[
  {
    "path": ".browserslistrc",
    "content": "> 1%\nlast 2 versions\nnot ie <= 10\n"
  },
  {
    "path": ".dockerignore",
    "content": "**/node_modules\n**/dist"
  },
  {
    "path": ".eslintignore",
    "content": "tests/__coverage__\nsrc/graphql\nnode_modules\nsrc/workers/auth.worker.js"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  root: true,\n  env: {\n    node: true\n  },\n  extends: [\n    'plugin:vue/essential',\n    'plugin:vue/recommended',\n    '@vue/prettier',\n    'eslint:recommended'\n  ],\n  plugins: ['vuetify'],\n  rules: {\n    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',\n    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',\n    'prettier/prettier': [\n      'warn',\n      {\n        singleQuote: true,\n        semi: false,\n        trailingComma: 'none',\n        printWidth: 80,\n        htmlWhitespaceSensitivity: 'strict'\n      }\n    ],\n    quotes: ['warn', 'single', { avoidEscape: true }],\n    semi: ['warn', 'never'],\n    'vuetify/grid-unknown-attributes': 'error',\n    'vuetify/no-deprecated-classes': 'error',\n    'vue/valid-v-slot': 'off'\n  },\n  parserOptions: {\n    parser: 'babel-eslint'\n  }\n}\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "# Lines starting with '#' are comments.\n# Each line is a file pattern followed by one or more owners.\n\n# These owners will be the default owners for everything in the repo.\n* @znicholasbrown @zhen0\n*.gql @cicdw @jlowin\n\n# Order is important. The last matching pattern has the most precedence.\n# So if a pull request only touches javascript files, only these owners\n# will be requested to review.\n# *.js    @octocat @github/js\n\n# You can also use email addresses if you prefer.\n# docs/*  docs@example.com\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug---.md",
    "content": "---\nname: \"Bug \\U0001F41B\"\nabout: Report an issue/bug with existing functionality.\ntitle: '1.0 BUG: '\nlabels: bug\nassignees: ''\n\n---\n***If your bug is related to Cloud 2.0 or Prefect 2.0, please submit your issue in the [Prefect Repo](https://github.com/PrefectHQ/prefect)***\n\n**Bug Description**\n<!--- Please write a clear description of the behavior you're seeing. Include screenshots in the *notes* section, if relevant. \n-->\n\n**Steps To Reproduce**\n<!--- \nConcisely describe steps we can take to reproduce this, using a numbered list \n-->\n1. \n\n**Browsers Tested:**\n* [ ] Chrome\n* [ ] Firefox\n* [ ] Safari\n* [ ] Edge\n* [ ] IE\n\n----------\n**Notes**\n<!--- \nProvide any additional context that might be helpful for the team to pick up the ticket, including screenshots. \n-->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/general---.md",
    "content": "---\nname: \"General \\U0001F680\"\nabout: Create a ticket for a general feature.\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n**Why**\n<!--\nDescribe this ticket: why it's important to users, the system, etc. This should be as non-technical as possible.\n-->\n\n**What**\n<!--\nCreate an actionable user story-style checklist that the team can use as the concrete steps towards completing this ticket\n-->\n* [ ] \n\n**Notes**\n<!-- Any additional context, resources, carbon copies, etc. -->\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "## Description\n<! -- What is it meant to do? -->\n\n\n## Linked Issues\n<! -- Use a key word (e.g. closes or resolves) to close related issues  -->\n\n\n## Tests and performance\n\n - [ ] Changes to any .js files are covered by existing tests or this PR adds new tests (if not please explain why below)\n - [ ] No new packages are added or package size and performance considerations are discussed below\n - [ ] PR Title fits our [changelog format](https://github.com/PrefectHQ/ui#readme)\n\n ## Releases/Changelog cuts only\n - [ ] Completed the [QA Checklist](https://www.notion.so/prefect/Cloud-UI-QA-Checklist-038a5a5d40a249d78232917ad1b923b9) in staging\n"
  },
  {
    "path": ".github/codeql-config.yml",
    "content": "paths-ignore:\n  - tests/**/test_*.py\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: [ dev, master ]\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' ]\n        # Learn more:\n        # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed\n\n    steps:\n    - name: Checkout repository\n      uses: actions/checkout@v2\n\n    # Initializes the CodeQL tools for scanning.\n    - name: Initialize CodeQL\n      uses: github/codeql-action/init@v1\n      with:\n        languages: ${{ matrix.language }}\n        config-file: ./.github/codeql-config.yml\n        queries: security-and-quality\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        # queries: ./path/to/local/query, your-org/your-repo/queries@main\n\n    # ℹ️ Command-line programs to run using the OS shell.\n    # 📚 https://git.io/JvXDl\n\n    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines\n    #    and modify them (or add more) to build your code if your project\n    #    uses a compiled language\n\n    #- run: |\n    #   make bootstrap\n    #   make release\n\n    - name: Perform CodeQL Analysis\n      uses: github/codeql-action/analyze@v1\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules\n/dist\ntests/__coverage__\n.firebase\n\n# Generated from integration tests\ntests/e2e/videos\ntests/e2e/screenshots\n\n\n# local env files\n.env.local\n.env.*.local\n\n# Log files\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n*.sw*\n\n# python\n.mypy_cache\n__pycache__/\n*.py[cod]\n*$py.class\n\n# external font/JS files downloaded during build\nsrc/styles/graphiql.css\npublic/fonts/*.ttf\npublic/fonts/*.otf\npublic/fonts/*.js\n"
  },
  {
    "path": ".nvmrc",
    "content": "v14.17.3"
  },
  {
    "path": ".prettierignore",
    "content": ""
  },
  {
    "path": ".prettierrc.js",
    "content": "const eslintrc = require('./.eslintrc')\n\nmodule.exports = eslintrc.rules['prettier/prettier'][1]\n"
  },
  {
    "path": ".salesforce_env_development",
    "content": "VUE_APP_SF_SFCID=00D7h0000009q6r\nVUE_APP_SF_TEAM=Chat_Service_Team\nVUE_APP_SF_URL1=https://prefect--partial.sandbox.my.salesforce.com\nVUE_APP_SF_URL2=https://prefect--partial.sandbox.my.site.com/partners\nVUE_APP_SF_BASE_LIVE_AGENT_CONTENT_URL=https://c.la3-c1cs-ia5.salesforceliveagent.com/content\nVUE_APP_SF_DEPLOYMENT_ID=5722E0000000dd5\nVUE_APP_SF_BUTTON_ID=5732E0000000eF1\nVUE_APP_SF_BASE_LIVE_AGENT_URL=https://d.la3-c1cs-ia5.salesforceliveagent.com/chat\nVUE_APP_SF_URL3=https://prefect--partial.sandbox.my.salesforce.com/embeddedservice/5.0/esw.min.js\n"
  },
  {
    "path": ".salesforce_env_production",
    "content": "VUE_APP_SF_SFCID=00D2E000000o3Ut\nVUE_APP_SF_TEAM=Chat_Service_Team\nVUE_APP_SF_URL1=https://prefect.my.salesforce.com\nVUE_APP_SF_URL2=https://prefect.force.com/partners\nVUE_APP_SF_BASE_LIVE_AGENT_CONTENT_URL=https://c.la1-c2-ia2.salesforceliveagent.com/content\nVUE_APP_SF_DEPLOYMENT_ID=5722E0000000dd5\nVUE_APP_SF_BUTTON_ID=5732E0000000eF1\nVUE_APP_SF_BASE_LIVE_AGENT_URL=https://d.la1-c2-ia2.salesforceliveagent.com/chat\nVUE_APP_SF_URL3=https://prefect.my.salesforce.com/embeddedservice/5.0/esw.min.js\n"
  },
  {
    "path": ".stylelintignore",
    "content": "src/styles/playground.scss\nsrc/styles/scss\nsrc/styles/graphiql.css\npublic/fonts.css\nsrc/workers"
  },
  {
    "path": "Changelog.md",
    "content": "# Changelog\n\n#### [2022-12-15](https://github.com/PrefectHQ/ui/compare/2022-10-03...2022-12-15)\n\n- BugFix: Remove skipped state from the change state mixin [`#1352`](https://github.com/PrefectHQ/ui/pull/1352)\n- Enhancement: Switch default to user from admin [`#1355`](https://github.com/PrefectHQ/ui/pull/1355)\n- Bump decode-uri-component from 0.2.0 to 0.2.2 [`#1351`](https://github.com/PrefectHQ/ui/pull/1351)\n- Bump qs from 6.5.2 to 6.5.3 [`#1353`](https://github.com/PrefectHQ/ui/pull/1353)\n- Bump express from 4.17.1 to 4.18.2 [`#1354`](https://github.com/PrefectHQ/ui/pull/1354)\n- Bump minimatch from 3.0.4 to 3.0.8 [`#1348`](https://github.com/PrefectHQ/ui/pull/1348)\n- Enhancement: Add explicit call to log out API route [`#1344`](https://github.com/PrefectHQ/ui/pull/1344)\n\n#### [2022-10-03](https://github.com/PrefectHQ/ui/compare/2022-09-14...2022-10-03)\n\n- Chore: Update Build image to use Circle2.0 image [`#1342`](https://github.com/PrefectHQ/ui/pull/1342)\n- Feature: adapts chatbot to match new SFDC changes [`#1338`](https://github.com/PrefectHQ/ui/pull/1338)\n- BugFix: Make z into Z [`#1336`](https://github.com/PrefectHQ/ui/pull/1336)\n- Chore: Remove font awesome conflict detection [`#1333`](https://github.com/PrefectHQ/ui/pull/1333)\n- Changelog for 2022-09-14 release [`#1332`](https://github.com/PrefectHQ/ui/pull/1332)\n\n#### [2022-09-14](https://github.com/PrefectHQ/ui/compare/2022-06-02...2022-09-14)\n\n- Security:  Update vue cli related packages [`#1328`](https://github.com/PrefectHQ/ui/pull/1328)\n- BugFix: Add version to graphiql css and re-update fully to node-fetch 2.6.7 [`#1327`](https://github.com/PrefectHQ/ui/pull/1327)\n- BugFix: Upgrade from Python 3.7 to 3.8 [`#1331`](https://github.com/PrefectHQ/ui/pull/1331)\n- Security: Force EJS update [`#1315`](https://github.com/PrefectHQ/ui/pull/1315)\n- Bump terser from 4.8.0 to 4.8.1 [`#1308`](https://github.com/PrefectHQ/ui/pull/1308)\n- Security: Remove Font Awesome Conflict Detection [`#1314`](https://github.com/PrefectHQ/ui/pull/1314)\n- Bump shell-quote from 1.7.2 to 1.7.3 [`#1292`](https://github.com/PrefectHQ/ui/pull/1292)\n- Bump parse-url from 6.0.0 to 6.0.2 [`#1294`](https://github.com/PrefectHQ/ui/pull/1294)\n- Bump eventsource from 1.1.0 to 1.1.1 [`#1288`](https://github.com/PrefectHQ/ui/pull/1288)\n- Bump dset from 3.1.1 to 3.1.2 [`#1284`](https://github.com/PrefectHQ/ui/pull/1284)\n- Bump async from 2.6.3 to 2.6.4 [`#1274`](https://github.com/PrefectHQ/ui/pull/1274)\n- Bugfix: Service account roles [`#1313`](https://github.com/PrefectHQ/ui/pull/1313)\n\n#### [2022-06-02](https://github.com/PrefectHQ/ui/compare/2022-05-17...2022-06-02)\n\n- Cut changelog ahead of 2022-06-02 release [`#1289`](https://github.com/PrefectHQ/ui/pull/1289)\n- Bugfix: Chat launcher icon added nav bar, previous launch button hidden [`#1287`](https://github.com/PrefectHQ/ui/pull/1287)\n- Bugfix: replaces env variables and CSP URLs related to Salesforce partial environment [`#1286`](https://github.com/PrefectHQ/ui/pull/1286)\n\n#### [2022-05-17](https://github.com/PrefectHQ/ui/compare/2022-04-21...2022-05-17)\n\n- 2022-05-17 [`#1283`](https://github.com/PrefectHQ/ui/pull/1283)\n- Enable sf chat plugin in Cloud production environments [`#1282`](https://github.com/PrefectHQ/ui/pull/1282)\n- Bugfix: adds new Salesforce URL to script-src Content Security Policy [`#1281`](https://github.com/PrefectHQ/ui/pull/1281)\n\n#### [2022-04-21](https://github.com/PrefectHQ/ui/compare/2022-02-17...2022-04-21)\n\n- Cut changelog ahead of 2022-04-21 release [`#1270`](https://github.com/PrefectHQ/ui/pull/1270)\n- Improve access-denied checks [`#1266`](https://github.com/PrefectHQ/ui/pull/1266)\n- Disable salesforce plugin in production environments [`#1267`](https://github.com/PrefectHQ/ui/pull/1267)\n- copies salesforce related URLS to script-src policy [`#1259`](https://github.com/PrefectHQ/ui/pull/1259)\n- add override [`#1258`](https://github.com/PrefectHQ/ui/pull/1258)\n- remove conflict detection [`#1257`](https://github.com/PrefectHQ/ui/pull/1257)\n- Audit fix [`#1256`](https://github.com/PrefectHQ/ui/pull/1256)\n- Bump minimist from 1.2.5 to 1.2.6 [`#1255`](https://github.com/PrefectHQ/ui/pull/1255)\n- Bump trim-newlines from 3.0.0 to 3.0.1 [`#1254`](https://github.com/PrefectHQ/ui/pull/1254)\n- Feature: Adds Salesforce Chat Bot [`#1250`](https://github.com/PrefectHQ/ui/pull/1250)\n- Bump url-parse from 1.5.7 to 1.5.10 [`#1246`](https://github.com/PrefectHQ/ui/pull/1246)\n- Cut changelog ahead of 2022-02-24 release [`#1245`](https://github.com/PrefectHQ/ui/pull/1245)\n- Bump url-parse from 1.5.1 to 1.5.7 [`#1240`](https://github.com/PrefectHQ/ui/pull/1240)\n- BugFix: Add error handling to the delete-service-account mutation [`#1243`](https://github.com/PrefectHQ/ui/pull/1243)\n- Feature: Expose discourse links [`#1244`](https://github.com/PrefectHQ/ui/pull/1244)\n- Changelog: Cut changelog ahead of 2022-02-17 release [`#1237`](https://github.com/PrefectHQ/ui/pull/1237)\n\n#### [2022-02-17](https://github.com/PrefectHQ/ui/compare/2022-02-04...2022-02-17)\n\n#### [2022-02-04](https://github.com/PrefectHQ/ui/compare/2022-01-14...2022-02-04)\n\n- Cut changelog ahead of 2022-02-24 release [`#1245`](https://github.com/PrefectHQ/ui/pull/1245)\n- Bump url-parse from 1.5.1 to 1.5.7 [`#1240`](https://github.com/PrefectHQ/ui/pull/1240)\n- BugFix: Add error handling to the delete-service-account mutation [`#1243`](https://github.com/PrefectHQ/ui/pull/1243)\n- Feature: Expose discourse links [`#1244`](https://github.com/PrefectHQ/ui/pull/1244)\n- Changelog: Cut changelog ahead of 2022-02-17 release [`#1237`](https://github.com/PrefectHQ/ui/pull/1237)\n- BugFix: Update placeholder text on task search [`#1234`](https://github.com/PrefectHQ/ui/pull/1234)\n- BugFix: Fix Skip on SetStateDialog [`#1235`](https://github.com/PrefectHQ/ui/pull/1235)\n- Feature: Enable deletion of agent configs in automations [`#1153`](https://github.com/PrefectHQ/ui/pull/1153)\n- BugFix: Update link to legal page on website [`#1219`](https://github.com/PrefectHQ/ui/pull/1219)\n- BugFix: Improve loading logic for automation tab on Flow Page [`#1223`](https://github.com/PrefectHQ/ui/pull/1223)\n- Admin: Remove new and beta badges [`#1230`](https://github.com/PrefectHQ/ui/pull/1230)\n- BugFix: Remove v-intersect as it was causing odd behavior [`#1224`](https://github.com/PrefectHQ/ui/pull/1224)\n- BugFix: Do not call unsubscribe agents if it is not a function [`#1225`](https://github.com/PrefectHQ/ui/pull/1225)\n- Bump follow-redirects from 1.14.7 to 1.14.8 [`#1228`](https://github.com/PrefectHQ/ui/pull/1228)\n- Bump node-sass from 5.0.0 to 7.0.0 [`#1226`](https://github.com/PrefectHQ/ui/pull/1226)\n- BugFix: Flow Concurrency and Task Concurrency browser refresh [`#1220`](https://github.com/PrefectHQ/ui/pull/1220)\n- Update: Change the wording on the teams page to redirect users based on their license [`#1210`](https://github.com/PrefectHQ/ui/pull/1210)\n- BugFix: Web hook URL validation [`#1212`](https://github.com/PrefectHQ/ui/pull/1212)\n- Bump follow-redirects from 1.14.0 to 1.14.7 [`#1211`](https://github.com/PrefectHQ/ui/pull/1211)\n- Bump nanoid from 3.1.23 to 3.2.0 [`#1214`](https://github.com/PrefectHQ/ui/pull/1214)\n- Bump markdown-it from 12.2.0 to 12.3.2 [`#1203`](https://github.com/PrefectHQ/ui/pull/1203)\n- Feature: Allow dates in the past to be used as parameter values when using date picker [`#1213`](https://github.com/PrefectHQ/ui/pull/1213)\n- BugFix: Remove \"user content\" from each heading in the tutorial menu [`#1209`](https://github.com/PrefectHQ/ui/pull/1209)\n- BugFix: Schematic node view issues [`#1204`](https://github.com/PrefectHQ/ui/pull/1204)\n- Changelog: Cut changelog ahead of 2022-01-14 release [`#1207`](https://github.com/PrefectHQ/ui/pull/1207)\n\n#### [2022-01-14](https://github.com/PrefectHQ/ui/compare/2021-12-22...2022-01-14)\n\n- BugFix: Enable editing in readme [`#1202`](https://github.com/PrefectHQ/ui/pull/1202)\n- BugFix: Remove confusing reference to RBAC on plans page [`#1192`](https://github.com/PrefectHQ/ui/pull/1192)\n- BugFix: Hide calendar schedule banner on Server [`#1200`](https://github.com/PrefectHQ/ui/pull/1200)\n- BugFix: Update Flow/Task Concurrency header values [`#1201`](https://github.com/PrefectHQ/ui/pull/1201)\n- Feature:  Add create_flow_run system action to automations [`#1152`](https://github.com/PrefectHQ/ui/pull/1152)\n- BugFix: Disable add service account and invite buttons until roles are loaded [`#1195`](https://github.com/PrefectHQ/ui/pull/1195)\n- BugFix: Remove automations tab from flow page on Server [`#1199`](https://github.com/PrefectHQ/ui/pull/1199)\n- Bugfix: Add loading state to the cloud hooks table  [`#1197`](https://github.com/PrefectHQ/ui/pull/1197)\n- Bugfix:  Go to Project button on dashboard  [`#1155`](https://github.com/PrefectHQ/ui/pull/1155)\n- Admin: Update PR template [`#1157`](https://github.com/PrefectHQ/ui/pull/1157)\n- BugFix: Improve error handling on restart button and refetch state after restart [`#1181`](https://github.com/PrefectHQ/ui/pull/1181)\n- BugFix: Ensure label warning updates  [`#1188`](https://github.com/PrefectHQ/ui/pull/1188)\n- Admin: Add input sanitizer as default for log rocket [`#1186`](https://github.com/PrefectHQ/ui/pull/1186)\n- BugFix: Add once to intersect on lastTenRuns [`#1187`](https://github.com/PrefectHQ/ui/pull/1187)\n- Admin: adopting auto-changelog [`#1171`](https://github.com/PrefectHQ/ui/pull/1171)\n\n#### [2021-12-22](https://github.com/PrefectHQ/ui/compare/2021-12-15...2021-12-22)\n\n- Changelog: Cut changelog ahead of 2021-12-22 release [`#1184`](https://github.com/PrefectHQ/ui/pull/1184)\n- Bugfix: Add log rocket prop [`#1183`](https://github.com/PrefectHQ/ui/pull/1183)\n- BugFix: removed unused onIntersect methods [`#1166`](https://github.com/PrefectHQ/ui/pull/1166)\n- added http-security-headers to apollo graphql network traffic [`#1173`](https://github.com/PrefectHQ/ui/pull/1173)\n- BugFix: Replacing link to docs in task run concurrency page [`#1176`](https://github.com/PrefectHQ/ui/pull/1176)\n- Cut Changelog ahead of 2021-12-15 release [`#1175`](https://github.com/PrefectHQ/ui/pull/1175)\n\n#### [2021-12-15](https://github.com/PrefectHQ/ui/compare/2021-12-14a...2021-12-15)\n\n- BugFix: added missing icon for help getting-started [`#1164`](https://github.com/PrefectHQ/ui/pull/1164)\n- Bugfix: Check tenant is in route params tenant before calling setCurrentTenant [`#1174`](https://github.com/PrefectHQ/ui/pull/1174)\n- Bugfix:  Send to sales for more users [`#1172`](https://github.com/PrefectHQ/ui/pull/1172)\n\n#### [2021-12-14a](https://github.com/PrefectHQ/ui/compare/2021-12-14...2021-12-14a)\n\n- Changelog: Cut hotifx changelog [`#1165`](https://github.com/PrefectHQ/ui/pull/1165)\n- HOTFIX: Remove intersection observers from Members, Invitations-Table, Members-Table components [`#1162`](https://github.com/PrefectHQ/ui/pull/1162)\n- HOTFIX: Remove intersection observer on notifications group component [`#1163`](https://github.com/PrefectHQ/ui/pull/1163)\n- rolling back watcher change [`#1158`](https://github.com/PrefectHQ/ui/pull/1158)\n\n#### [2021-12-14](https://github.com/PrefectHQ/ui/compare/2021-11-09...2021-12-14)\n\n- Changelog: Cut changelog ahead of 14-12-2021 release [`#1156`](https://github.com/PrefectHQ/ui/pull/1156)\n- Feature: Show project name in the run history flow run pop up box [`#1139`](https://github.com/PrefectHQ/ui/pull/1139)\n- Performance: More careful polling of graphql data [`#1125`](https://github.com/PrefectHQ/ui/pull/1125)\n- Dependabot: Bump tmpl from 1.0.4 to 1.0.5 [`#1055`](https://github.com/PrefectHQ/ui/pull/1055)\n- Feature: Elevate labels in the details tile  [`#1151`](https://github.com/PrefectHQ/ui/pull/1151)\n- Dependabot: Bump object-path from 0.11.5 to 0.11.8 [`#1054`](https://github.com/PrefectHQ/ui/pull/1054)\n- Bump axios from 0.21.1 to 0.21.4 [`#1052`](https://github.com/PrefectHQ/ui/pull/1052)\n- resolved high priority codeQL alerts [`#1150`](https://github.com/PrefectHQ/ui/pull/1150)\n- Bugfix: Check for skipped state in task run table to fix endless duration  [`#1134`](https://github.com/PrefectHQ/ui/pull/1134)\n- code review changes for 1120 [`#1148`](https://github.com/PrefectHQ/ui/pull/1148)\n- Performance: Add virtual-scroll to dashboard tiles and improve duration calculations [`#1120`](https://github.com/PrefectHQ/ui/pull/1120)\n- Performance: Removed watchers and/or increased watchers specificity [`#1143`](https://github.com/PrefectHQ/ui/pull/1143)\n- Feature: Add loading state to RestartDialog [`#1144`](https://github.com/PrefectHQ/ui/pull/1144)\n- Bugfix: Do not add 'allFlows' if a user has only one flow [`#1129`](https://github.com/PrefectHQ/ui/pull/1129)\n- Update free usage task runs count to 20,000 [`#1145`](https://github.com/PrefectHQ/ui/pull/1145)\n- Bugfix: Update artifact docs link in the 'beta' badge popover [`#1127`](https://github.com/PrefectHQ/ui/pull/1127)\n- Bugfix: Improve agent sorting [`#1137`](https://github.com/PrefectHQ/ui/pull/1137)\n- Bugfix: Set min-width in titlebars to account for shorter names [`#1136`](https://github.com/PrefectHQ/ui/pull/1136)\n- Performance: Update inputs in flow settings - parameters [`#1103`](https://github.com/PrefectHQ/ui/pull/1103)\n- 1095/schedules [`#1104`](https://github.com/PrefectHQ/ui/pull/1104)\n- 1095/team settings [`#1101`](https://github.com/PrefectHQ/ui/pull/1101)\n- Admin: Add Evan to code owners [`#1135`](https://github.com/PrefectHQ/ui/pull/1135)\n- Bugfix: Font-awesome-subsetting [`#1132`](https://github.com/PrefectHQ/ui/pull/1132)\n- 1095/automations [`#1102`](https://github.com/PrefectHQ/ui/pull/1102)\n- Bugfix: Checks for slashes in Cron regex to set interval schedule via Cron [`#1123`](https://github.com/PrefectHQ/ui/pull/1123)\n- Bugfix: Fix broken link to the account page  [`#1131`](https://github.com/PrefectHQ/ui/pull/1131)\n- Feature: Adjust column width in v-data-table to account for longer names [`#1121`](https://github.com/PrefectHQ/ui/pull/1121)\n- fixed incorrect syntax for flex-align [`#1128`](https://github.com/PrefectHQ/ui/pull/1128)\n- Bugfix: removed avoidable watchers when side-nav is not open [`#1124`](https://github.com/PrefectHQ/ui/pull/1124)\n- Bugfix: Performance - Remove global event listeners from App.vue [`#1119`](https://github.com/PrefectHQ/ui/pull/1119)\n- Feature: Expand space in the title bars to account for longer names [`#1098`](https://github.com/PrefectHQ/ui/pull/1098)\n- Feature: Enhancements to run page run-config inputs with new dict, json, yaml inputs [`#1095`](https://github.com/PrefectHQ/ui/pull/1095)\n- Bugfix: Artifacts docs link correction [`#1126`](https://github.com/PrefectHQ/ui/pull/1126)\n- Bugfix: Allow users to search for flows by both flow id and flow group id [`#1089`](https://github.com/PrefectHQ/ui/pull/1089)\n\n#### [2021-11-09](https://github.com/PrefectHQ/ui/compare/2021-11-01...2021-11-09)\n\n- Cut changelog ahead of 2021-11-09 release [`#1122`](https://github.com/PrefectHQ/ui/pull/1122)\n- Bump graphiql from 1.4.1 to 1.4.7 [`#1117`](https://github.com/PrefectHQ/ui/pull/1117)\n- Bump remark-html from 13.0.1 to 13.0.2 [`#1041`](https://github.com/PrefectHQ/ui/pull/1041)\n- performance: improved logic for displaying current time in user-menu [`#1099`](https://github.com/PrefectHQ/ui/pull/1099)\n- tree shaking moment dependency [`#1109`](https://github.com/PrefectHQ/ui/pull/1109)\n- tree shaking lodash dependency [`#1107`](https://github.com/PrefectHQ/ui/pull/1107)\n- tree shaking highlightjs dependency [`#1108`](https://github.com/PrefectHQ/ui/pull/1108)\n- when creating/editing schedule, make action button available across tabs [`#1096`](https://github.com/PrefectHQ/ui/pull/1096)\n\n#### [2021-11-01](https://github.com/PrefectHQ/ui/compare/2021-10-06...2021-11-01)\n\n- cut changelog ahead of  11/01/2021 release [`#1106`](https://github.com/PrefectHQ/ui/pull/1106)\n- fix ordering of submitted and running [`#1105`](https://github.com/PrefectHQ/ui/pull/1105)\n- Update plan definitions to reflect (soon to be) reality [`#1100`](https://github.com/PrefectHQ/ui/pull/1100)\n- User settings/teams - removeUser mutation error handling [`#1094`](https://github.com/PrefectHQ/ui/pull/1094)\n- Dont expose token to logrocket [`#1091`](https://github.com/PrefectHQ/ui/pull/1091)\n- Create codeql-config.yml [`#1037`](https://github.com/PrefectHQ/ui/pull/1037)\n- Fix tags in slack orb in CircleCI config [`#1053`](https://github.com/PrefectHQ/ui/pull/1053)\n- Warning that users will be locked out if not part of a team [`#1078`](https://github.com/PrefectHQ/ui/pull/1078)\n- Disable start run button for late flow runs  [`#1087`](https://github.com/PrefectHQ/ui/pull/1087)\n-  Filter by scheduled runs in the runs tab  [`#1079`](https://github.com/PrefectHQ/ui/pull/1079)\n- When editing a schedule, update the action button to \"Save\" [`#1083`](https://github.com/PrefectHQ/ui/pull/1083)\n- Fixed-tile-v-tabs [`#1081`](https://github.com/PrefectHQ/ui/pull/1081)\n- Pd update [`#1073`](https://github.com/PrefectHQ/ui/pull/1073)\n- Update the command on the connect an agent intro section [`#1076`](https://github.com/PrefectHQ/ui/pull/1076)\n\n#### [2021-10-06](https://github.com/PrefectHQ/ui/compare/2021-10-05...2021-10-06)\n\n- Add UniversalRun to possible run config options on flow details apge [`#1074`](https://github.com/PrefectHQ/ui/pull/1074)\n\n#### [2021-10-05](https://github.com/PrefectHQ/ui/compare/2021-09-20...2021-10-05)\n\n- update tabs on tiles [`#1064`](https://github.com/PrefectHQ/ui/pull/1064)\n- Remove requirement to add an API Secret for Pager Duty  [`#1065`](https://github.com/PrefectHQ/ui/pull/1065)\n- member invitation bug - invite a user on the free tier the first time the modal appears [`#1062`](https://github.com/PrefectHQ/ui/pull/1062)\n- added nvmrc for project that sets node version to 14-17-3 [`#1058`](https://github.com/PrefectHQ/ui/pull/1058)\n\n#### [2021-09-20](https://github.com/PrefectHQ/ui/compare/2021-09-07...2021-09-20)\n\n- pagerduty integration  [`#1038`](https://github.com/PrefectHQ/ui/pull/1038)\n- add run config tab in flow run details [`#1047`](https://github.com/PrefectHQ/ui/pull/1047)\n- update tutorial [`#1042`](https://github.com/PrefectHQ/ui/pull/1042)\n- fix text color in flow details tile [`#1044`](https://github.com/PrefectHQ/ui/pull/1044)\n\n#### [2021-09-07](https://github.com/PrefectHQ/ui/compare/2021-08-18...2021-09-07)\n\n- Cut changelog ahead of 2021-09-07 release [`#1039`](https://github.com/PrefectHQ/ui/pull/1039)\n- Add a copy method to task run result locations [`#1033`](https://github.com/PrefectHQ/ui/pull/1033)\n- Artifact title overlap fix [`#1032`](https://github.com/PrefectHQ/ui/pull/1032)\n- fix webhook url language and remove ref to secret [`#1036`](https://github.com/PrefectHQ/ui/pull/1036)\n- Update the dict component to ignore null k/v pairs [`#1029`](https://github.com/PrefectHQ/ui/pull/1029)\n- Increase default number of flows shown in the flow table [`#1027`](https://github.com/PrefectHQ/ui/pull/1027)\n- Remove global max width [`#1026`](https://github.com/PrefectHQ/ui/pull/1026)\n- Remove parent query [`#1025`](https://github.com/PrefectHQ/ui/pull/1025)\n- Skipped state duration and end time fix [`#1030`](https://github.com/PrefectHQ/ui/pull/1030)\n- Route to task run page on timeline click [`#1024`](https://github.com/PrefectHQ/ui/pull/1024)\n- Clean up remaining FA_TOKEN refs [`#1020`](https://github.com/PrefectHQ/ui/pull/1020)\n- Fix role reset [`#1019`](https://github.com/PrefectHQ/ui/pull/1019)\n- Remove references to certain task attributes [`#1011`](https://github.com/PrefectHQ/ui/pull/1011)\n- Remove reliance on private FA npm server [`#1013`](https://github.com/PrefectHQ/ui/pull/1013)\n\n#### [2021-08-18](https://github.com/PrefectHQ/ui/compare/2021-08-17...2021-08-18)\n\n- Cut changelog ahead of 2021-08-18 release [`#1007`](https://github.com/PrefectHQ/ui/pull/1007)\n- Check authorization token expiration on initial login flow [`#1006`](https://github.com/PrefectHQ/ui/pull/1006)\n- Cut changelog ahead of 2021-08-17 release [`#1003`](https://github.com/PrefectHQ/ui/pull/1003)\n\n#### [2021-08-17](https://github.com/PrefectHQ/ui/compare/2021-08-05...2021-08-17)\n\n- Expose retry for archived runs [`#1002`](https://github.com/PrefectHQ/ui/pull/1002)\n- Service account roles  [`#1001`](https://github.com/PrefectHQ/ui/pull/1001)\n- Add host config to the docker run config [`#988`](https://github.com/PrefectHQ/ui/pull/988)\n- Upgrade CircleCI/slack orb, rename variables [`#991`](https://github.com/PrefectHQ/ui/pull/991)\n- Auto-populate flow group schedules when editing [`#989`](https://github.com/PrefectHQ/ui/pull/989)\n- Separate primary and secondary Apollo client links [`#987`](https://github.com/PrefectHQ/ui/pull/987)\n- Update browser visibility handler to use new login logic [`#986`](https://github.com/PrefectHQ/ui/pull/986)\n- Add secret name and value routes to limit and offset exceptions [`#955`](https://github.com/PrefectHQ/ui/pull/955)\n\n#### [2021-08-05](https://github.com/PrefectHQ/ui/compare/2021-08-02...2021-08-05)\n\n- Cut changelog ahead of 2021-08-05 release [`#985`](https://github.com/PrefectHQ/ui/pull/985)\n- Update the data store retrieval patterns to handle more than 1000 flows [`#984`](https://github.com/PrefectHQ/ui/pull/984)\n- Fall back to in-memory token exchange if worker exchange fails or takes too long [`#982`](https://github.com/PrefectHQ/ui/pull/982)\n- Fix worker error handling [`#981`](https://github.com/PrefectHQ/ui/pull/981)\n- Move logrocket to first executed code [`#980`](https://github.com/PrefectHQ/ui/pull/980)\n\n#### [2021-08-02](https://github.com/PrefectHQ/ui/compare/2021-07-29...2021-08-02)\n\n- Fix start server settings [`#974`](https://github.com/PrefectHQ/ui/pull/974)\n\n#### [2021-07-29](https://github.com/PrefectHQ/ui/compare/2021-07-22...2021-07-29)\n\n- Cut changelog ahead of 2021-07-29 release [`#970`](https://github.com/PrefectHQ/ui/pull/970)\n- Allow hash characters in cron form validation [`#966`](https://github.com/PrefectHQ/ui/pull/966)\n- Add Automations tile to Flow page [`#941`](https://github.com/PrefectHQ/ui/pull/941)\n- Fix Bash syntax error in start_server.sh [`#964`](https://github.com/PrefectHQ/ui/pull/964)\n\n#### [2021-07-22](https://github.com/PrefectHQ/ui/compare/2021-07-21...2021-07-22)\n\n- Cut changelog ahead of 2021-07-22 release [`#961`](https://github.com/PrefectHQ/ui/pull/961)\n- Safari hotfix [`#960`](https://github.com/PrefectHQ/ui/pull/960)\n\n#### [2021-07-21](https://github.com/PrefectHQ/ui/compare/2021-07-13...2021-07-21)\n\n- Cut changelog ahead of 2021-07-21 release [`#959`](https://github.com/PrefectHQ/ui/pull/959)\n- Auth exceptions [`#957`](https://github.com/PrefectHQ/ui/pull/957)\n- remove jq [`#958`](https://github.com/PrefectHQ/ui/pull/958)\n- Setup nginx to run on rootless mode [`#946`](https://github.com/PrefectHQ/ui/pull/946)\n- add sort to healthy agents to prevent jumping [`#947`](https://github.com/PrefectHQ/ui/pull/947)\n\n#### [2021-07-13](https://github.com/PrefectHQ/ui/compare/2021-06-24...2021-07-13)\n\n- Cut changelog ahead of 2021-07-13 release [`#943`](https://github.com/PrefectHQ/ui/pull/943)\n- Parameters and context view legibility fix [`#939`](https://github.com/PrefectHQ/ui/pull/939)\n- Move logrocket initialization to its own plugin [`#940`](https://github.com/PrefectHQ/ui/pull/940)\n- Account page server fix [`#938`](https://github.com/PrefectHQ/ui/pull/938)\n- Improve type handling when passing parameters to create flow run mutation [`#936`](https://github.com/PrefectHQ/ui/pull/936)\n- Fix seconds on automation edit [`#937`](https://github.com/PrefectHQ/ui/pull/937)\n- Schedule timezone [`#922`](https://github.com/PrefectHQ/ui/pull/922)\n- Dark roles [`#925`](https://github.com/PrefectHQ/ui/pull/925)\n- Fix missing indentation in doc code snippet [`#932`](https://github.com/PrefectHQ/ui/pull/932)\n- Create codeql-analysis.yml [`#919`](https://github.com/PrefectHQ/ui/pull/919)\n- Add current tenant name to account header if no account_name is found [`#923`](https://github.com/PrefectHQ/ui/pull/923)\n- Cut changelog ahead of 2021-06-24 release [`#921`](https://github.com/PrefectHQ/ui/pull/921)\n\n#### [2021-06-24](https://github.com/PrefectHQ/ui/compare/2021-06-23a...2021-06-24)\n\n- More permissions [`#920`](https://github.com/PrefectHQ/ui/pull/920)\n- Use role id instead of name in members page invite mutation [`#918`](https://github.com/PrefectHQ/ui/pull/918)\n\n#### [2021-06-23a](https://github.com/PrefectHQ/ui/compare/2021-06-23...2021-06-23a)\n\n- Cut changelog ahead of 2021-06-23a release [`#917`](https://github.com/PrefectHQ/ui/pull/917)\n- schedule toggle  [`#916`](https://github.com/PrefectHQ/ui/pull/916)\n\n#### [2021-06-23](https://github.com/PrefectHQ/ui/compare/2021-06-17...2021-06-23)\n\n- Cut changelog ahead of 2021-06-23 release [`#915`](https://github.com/PrefectHQ/ui/pull/915)\n- Small fixes [`#914`](https://github.com/PrefectHQ/ui/pull/914)\n- Improved account management [`#909`](https://github.com/PrefectHQ/ui/pull/909)\n- other permission updates [`#910`](https://github.com/PrefectHQ/ui/pull/910)\n- Depressed prop on upgrade badge [`#913`](https://github.com/PrefectHQ/ui/pull/913)\n- members and service account permissions and formatting  [`#908`](https://github.com/PrefectHQ/ui/pull/908)\n- Add a check on all permissions that bypasses the license for Server [`#912`](https://github.com/PrefectHQ/ui/pull/912)\n- Roles [`#881`](https://github.com/PrefectHQ/ui/pull/881)\n- remove outdated migration date [`#902`](https://github.com/PrefectHQ/ui/pull/902)\n- Improve Agents on Server [`#901`](https://github.com/PrefectHQ/ui/pull/901)\n\n#### [2021-06-17](https://github.com/PrefectHQ/ui/compare/2021-06-02...2021-06-17)\n\n- Cut changelog ahead of 2021-06-17 release [`#900`](https://github.com/PrefectHQ/ui/pull/900)\n- remove setAgents from app.vue [`#898`](https://github.com/PrefectHQ/ui/pull/898)\n- Adds the netlify script to the csp [`#897`](https://github.com/PrefectHQ/ui/pull/897)\n- Improve expired auth and id token handling [`#896`](https://github.com/PrefectHQ/ui/pull/896)\n- Add agents [`#852`](https://github.com/PrefectHQ/ui/pull/852)\n- Add options to the survey on the name team page [`#895`](https://github.com/PrefectHQ/ui/pull/895)\n- Templating Task Name [`#863`](https://github.com/PrefectHQ/ui/pull/863)\n- Update interactive api allow list [`#891`](https://github.com/PrefectHQ/ui/pull/891)\n- Map index [`#890`](https://github.com/PrefectHQ/ui/pull/890)\n- KV Copy [`#887`](https://github.com/PrefectHQ/ui/pull/887)\n\n#### [2021-06-02](https://github.com/PrefectHQ/ui/compare/2021-06-01...2021-06-02)\n\n- Cut changelog ahead of 2021-06-02 release [`#880`](https://github.com/PrefectHQ/ui/pull/880)\n- KV Store Formatting inserts spacing into some values [`#879`](https://github.com/PrefectHQ/ui/pull/879)\n- KV Store  [`#804`](https://github.com/PrefectHQ/ui/pull/804)\n\n#### [2021-06-01](https://github.com/PrefectHQ/ui/compare/2021-05-25...2021-06-01)\n\n- Cut changelog ahead of 2021-06-01 release [`#875`](https://github.com/PrefectHQ/ui/pull/875)\n- Fix routing from invitation [`#862`](https://github.com/PrefectHQ/ui/pull/862)\n- Automations update [`#818`](https://github.com/PrefectHQ/ui/pull/818)\n\n#### [2021-05-25](https://github.com/PrefectHQ/ui/compare/2021-05-24...2021-05-25)\n\n- Cut changelog ahead of 2021-05-25 release [`#859`](https://github.com/PrefectHQ/ui/pull/859)\n- Remove fetchpolicy on tenant settings mutation [`#858`](https://github.com/PrefectHQ/ui/pull/858)\n\n#### [2021-05-24](https://github.com/PrefectHQ/ui/compare/2021-05-17...2021-05-24)\n\n- Cut changelog ahead of 2021-05-24 release [`#857`](https://github.com/PrefectHQ/ui/pull/857)\n- Improve usability of the quick run button [`#846`](https://github.com/PrefectHQ/ui/pull/846)\n- Allow configurable base url and relative public assets path [`#849`](https://github.com/PrefectHQ/ui/pull/849)\n- Fix broken api store core version ref [`#847`](https://github.com/PrefectHQ/ui/pull/847)\n- Remove options button for server [`#848`](https://github.com/PrefectHQ/ui/pull/848)\n- Fix issue with overlapping sidebar/application nav on small screens [`#850`](https://github.com/PrefectHQ/ui/pull/850)\n- Remove Server/Cloud switcher [`#844`](https://github.com/PrefectHQ/ui/pull/844)\n- Run page improvements/fixes [`#839`](https://github.com/PrefectHQ/ui/pull/839)\n- stop disable next for pager duty config [`#835`](https://github.com/PrefectHQ/ui/pull/835)\n- Add 3 new tenant-wide actions [`#825`](https://github.com/PrefectHQ/ui/pull/825)\n- Separate auth from the primary application [`#811`](https://github.com/PrefectHQ/ui/pull/811)\n\n#### [2021-05-17](https://github.com/PrefectHQ/ui/compare/2021-05-14...2021-05-17)\n\n- Cut changelog ahead of 2021-05-17 release [`#842`](https://github.com/PrefectHQ/ui/pull/842)\n- allowed users error [`#841`](https://github.com/PrefectHQ/ui/pull/841)\n- Stop json param value flicker [`#837`](https://github.com/PrefectHQ/ui/pull/837)\n\n#### [2021-05-14](https://github.com/PrefectHQ/ui/compare/2021-05-05...2021-05-14)\n\n- Cut changelog ahead of 2021-05-14 release [`#833`](https://github.com/PrefectHQ/ui/pull/833)\n- Fix issue setting default tenant in server and bypassing auth [`#828`](https://github.com/PrefectHQ/ui/pull/828)\n- Created by field service accounts [`#808`](https://github.com/PrefectHQ/ui/pull/808)\n- Show Maintenance Mode Warning [`#815`](https://github.com/PrefectHQ/ui/pull/815)\n- Members page doesn't load properly [`#824`](https://github.com/PrefectHQ/ui/pull/824)\n- licensing and permissions [`#763`](https://github.com/PrefectHQ/ui/pull/763)\n- Add Tooltip to flow run task table [`#814`](https://github.com/PrefectHQ/ui/pull/814)\n- Clarify Task Run usage tile [`#816`](https://github.com/PrefectHQ/ui/pull/816)\n- Switch token to key on getting started [`#820`](https://github.com/PrefectHQ/ui/pull/820)\n\n#### [2021-05-05](https://github.com/PrefectHQ/ui/compare/2021-05-04...2021-05-05)\n\n- Cut changelog ahead of 2021-05-05 release [`#812`](https://github.com/PrefectHQ/ui/pull/812)\n- don't disable context and environment key field [`#810`](https://github.com/PrefectHQ/ui/pull/810)\n- allow editing in json editor for checked params [`#787`](https://github.com/PrefectHQ/ui/pull/787)\n\n#### [2021-05-04](https://github.com/PrefectHQ/ui/compare/2021-04-23...2021-05-04)\n\n- Cut changelog ahead of 2021-05-04 release [`#809`](https://github.com/PrefectHQ/ui/pull/809)\n- update tutorials  [`#806`](https://github.com/PrefectHQ/ui/pull/806)\n- Add logging level to run config [`#769`](https://github.com/PrefectHQ/ui/pull/769)\n- Gracefully handle null default tenants [`#802`](https://github.com/PrefectHQ/ui/pull/802)\n- add animation hint for new automation card [`#784`](https://github.com/PrefectHQ/ui/pull/784)\n- take usage tile off dashboard and add to account page [`#782`](https://github.com/PrefectHQ/ui/pull/782)\n\n#### [2021-04-23](https://github.com/PrefectHQ/ui/compare/2021-04-22...2021-04-23)\n\n- More auth  [`#791`](https://github.com/PrefectHQ/ui/pull/791)\n\n#### [2021-04-22](https://github.com/PrefectHQ/ui/compare/2021-04-21...2021-04-22)\n\n- Fix issues with Server loading in the latest release. [`#788`](https://github.com/PrefectHQ/ui/pull/788)\n- add loading indicator for initial load [`#789`](https://github.com/PrefectHQ/ui/pull/789)\n\n#### [2021-04-21](https://github.com/PrefectHQ/ui/compare/2021-04-15...2021-04-21)\n\n- Cut changelog ahead of 2021-04-21 release [`#785`](https://github.com/PrefectHQ/ui/pull/785)\n- Fix auth loop [`#783`](https://github.com/PrefectHQ/ui/pull/783)\n- Fix some issues with checking auth when returning to the application [`#774`](https://github.com/PrefectHQ/ui/pull/774)\n\n#### [2021-04-15](https://github.com/PrefectHQ/ui/compare/2021-04-09a...2021-04-15)\n\n- Cut changelog ahead of 2021-04-15 release [`#779`](https://github.com/PrefectHQ/ui/pull/779)\n- default parameters  [`#773`](https://github.com/PrefectHQ/ui/pull/773)\n- update deploy tutorial for API keys [`#770`](https://github.com/PrefectHQ/ui/pull/770)\n- update user menu to mention keys instead of tokens [`#778`](https://github.com/PrefectHQ/ui/pull/778)\n- don't stringify strings [`#777`](https://github.com/PrefectHQ/ui/pull/777)\n- add breadcrumb to flow version, change flow name breadcrumb to overview [`#759`](https://github.com/PrefectHQ/ui/pull/759)\n- don't save backend in localstorage [`#772`](https://github.com/PrefectHQ/ui/pull/772)\n- Remove precommit hook [`#771`](https://github.com/PrefectHQ/ui/pull/771)\n- kinda hacky fix for weird rounding bug [`#768`](https://github.com/PrefectHQ/ui/pull/768)\n- make error message easier to read [`#767`](https://github.com/PrefectHQ/ui/pull/767)\n- Add loading state to sign out button [`#766`](https://github.com/PrefectHQ/ui/pull/766)\n\n#### [2021-04-09a](https://github.com/PrefectHQ/ui/compare/2021-04-09...2021-04-09a)\n\n- Cut changelog ahead of 2021-04-09a release [`#760`](https://github.com/PrefectHQ/ui/pull/760)\n- Add MS teams action [`#751`](https://github.com/PrefectHQ/ui/pull/751)\n\n#### [2021-04-09](https://github.com/PrefectHQ/ui/compare/2021-04-07...2021-04-09)\n\n- Cut changelog ahead of 2021-04-09 release [`#756`](https://github.com/PrefectHQ/ui/pull/756)\n- Improve onboarding license creation [`#754`](https://github.com/PrefectHQ/ui/pull/754)\n- include tenant when creating personal API keys [`#753`](https://github.com/PrefectHQ/ui/pull/753)\n- Display flow version in flow run  [`#736`](https://github.com/PrefectHQ/ui/pull/736)\n\n#### [2021-04-07](https://github.com/PrefectHQ/ui/compare/2021-04-06a...2021-04-07)\n\n- Cut changelog ahead of 2021-04-07 release [`#750`](https://github.com/PrefectHQ/ui/pull/750)\n- Update all slack invite links to redirect to the prefect.io slack link [`#747`](https://github.com/PrefectHQ/ui/pull/747)\n- fix legibility issues with /plans page in dark mode [`#748`](https://github.com/PrefectHQ/ui/pull/748)\n- check if flow version is archived for restart button state [`#714`](https://github.com/PrefectHQ/ui/pull/714)\n- Make \"current\" label more legible [`#737`](https://github.com/PrefectHQ/ui/pull/737)\n\n#### [2021-04-06a](https://github.com/PrefectHQ/ui/compare/2021-04-06...2021-04-06a)\n\n- Cut changelog ahead of 2021-04-06a release [`#744`](https://github.com/PrefectHQ/ui/pull/744)\n- Check rbac feature on permissions blob instead of plan names [`#743`](https://github.com/PrefectHQ/ui/pull/743)\n\n#### [2021-04-06](https://github.com/PrefectHQ/ui/compare/2021-04-05...2021-04-06)\n\n- Cut changelog ahead of 2021-04-06 release [`#742`](https://github.com/PrefectHQ/ui/pull/742)\n- Committed runs on license instead of tenant patch [`#741`](https://github.com/PrefectHQ/ui/pull/741)\n- Rbac patch [`#740`](https://github.com/PrefectHQ/ui/pull/740)\n\n#### [2021-04-05](https://github.com/PrefectHQ/ui/compare/2021-03-25...2021-04-05)\n\n- Cut changelog ahead of 2021-04-05 release [`#739`](https://github.com/PrefectHQ/ui/pull/739)\n- Fix gutters on pages using the tile layout [`#738`](https://github.com/PrefectHQ/ui/pull/738)\n- Add an agent config creation step to the automations agent SLA form [`#708`](https://github.com/PrefectHQ/ui/pull/708)\n- Add scheduling error message to toast [`#725`](https://github.com/PrefectHQ/ui/pull/725)\n- Usage timeline bugfixes [`#722`](https://github.com/PrefectHQ/ui/pull/722)\n- Add the proper permissions to role-based invitations [`#719`](https://github.com/PrefectHQ/ui/pull/719)\n- Add the proper permissions to flow and task concurrency pages [`#720`](https://github.com/PrefectHQ/ui/pull/720)\n- Small fixes to onboarding [`#721`](https://github.com/PrefectHQ/ui/pull/721)\n- Usage displays/updates [`#692`](https://github.com/PrefectHQ/ui/pull/692)\n- bugfix to show helpful error message on failed service account creation [`#716`](https://github.com/PrefectHQ/ui/pull/716)\n- Log URL  [`#712`](https://github.com/PrefectHQ/ui/pull/712)\n- Disable the automations tab [`#711`](https://github.com/PrefectHQ/ui/pull/711)\n- Fix tenant switching in Safari [`#710`](https://github.com/PrefectHQ/ui/pull/710)\n- Add remaining states to the state filter  [`#706`](https://github.com/PrefectHQ/ui/pull/706)\n- Package updates 2021-03-29 [`#707`](https://github.com/PrefectHQ/ui/pull/707)\n- Hooks (AKA Automations) [`#695`](https://github.com/PrefectHQ/ui/pull/695)\n- Token redesign [`#678`](https://github.com/PrefectHQ/ui/pull/678)\n- Make the duration header not sortable [`#699`](https://github.com/PrefectHQ/ui/pull/699)\n- fix artifact colors to be dark mode friendly [`#693`](https://github.com/PrefectHQ/ui/pull/693)\n- add loading state to quick run button [`#696`](https://github.com/PrefectHQ/ui/pull/696)\n- Add generic message notification type [`#674`](https://github.com/PrefectHQ/ui/pull/674)\n\n#### [2021-03-25](https://github.com/PrefectHQ/ui/compare/2021-03-16...2021-03-25)\n\n- Cut changelog ahead of 2021-03-25 release [`#694`](https://github.com/PrefectHQ/ui/pull/694)\n- Schedule default parameters  [`#683`](https://github.com/PrefectHQ/ui/pull/683)\n- Improve authorization expiration handling [`#690`](https://github.com/PrefectHQ/ui/pull/690)\n- delete entire flow group with new mutation [`#689`](https://github.com/PrefectHQ/ui/pull/689)\n- More flow run page improvements [`#688`](https://github.com/PrefectHQ/ui/pull/688)\n- Update readme with sections on testing, docker, and local development [`#691`](https://github.com/PrefectHQ/ui/pull/691)\n- Flow run page and general performance improvements [`#679`](https://github.com/PrefectHQ/ui/pull/679)\n- Named routes  [`#662`](https://github.com/PrefectHQ/ui/pull/662)\n- Randomize survey [`#677`](https://github.com/PrefectHQ/ui/pull/677)\n- Missing state in state filter  [`#675`](https://github.com/PrefectHQ/ui/pull/675)\n\n#### [2021-03-16](https://github.com/PrefectHQ/ui/compare/2021-03-15a...2021-03-16)\n\n- Cut changelog ahead of 2021-03-16 release [`#676`](https://github.com/PrefectHQ/ui/pull/676)\n- License creation/slug error  [`#672`](https://github.com/PrefectHQ/ui/pull/672)\n- Update links to new page [`#673`](https://github.com/PrefectHQ/ui/pull/673)\n- remove popover [`#665`](https://github.com/PrefectHQ/ui/pull/665)\n\n#### [2021-03-15a](https://github.com/PrefectHQ/ui/compare/2021-03-15...2021-03-15a)\n\n- Cut changelog ahead of 2021-03-15a release [`#671`](https://github.com/PrefectHQ/ui/pull/671)\n- Remove references to the detail blob from the task run table tile [`#670`](https://github.com/PrefectHQ/ui/pull/670)\n\n#### [2021-03-15](https://github.com/PrefectHQ/ui/compare/2021-03-09...2021-03-15)\n\n- Cut changelog ahead of 2021-03-15 release [`#668`](https://github.com/PrefectHQ/ui/pull/668)\n- Dark mode!! [`#656`](https://github.com/PrefectHQ/ui/pull/656)\n- Flow group created by  [`#657`](https://github.com/PrefectHQ/ui/pull/657)\n- Fix a couple bugs from color consolidation [`#652`](https://github.com/PrefectHQ/ui/pull/652)\n- Flow run state filter [`#645`](https://github.com/PrefectHQ/ui/pull/645)\n- Cancel late [`#653`](https://github.com/PrefectHQ/ui/pull/653)\n- Mapped case task runs [`#650`](https://github.com/PrefectHQ/ui/pull/650)\n\n#### [2021-03-09](https://github.com/PrefectHQ/ui/compare/2021-03-02...2021-03-09)\n\n- Cut changelog ahead of 2021-03-09 release [`#651`](https://github.com/PrefectHQ/ui/pull/651)\n- clean up agents with NaN secondsSinceLastQuery [`#646`](https://github.com/PrefectHQ/ui/pull/646)\n- Color cleanup: change hard-coded colors into variables throughout app [`#640`](https://github.com/PrefectHQ/ui/pull/640)\n- State table [`#633`](https://github.com/PrefectHQ/ui/pull/633)\n\n#### [2021-03-02](https://github.com/PrefectHQ/ui/compare/2021-02-23...2021-03-02)\n\n- Cut changelog ahead of 2021-03-02 release [`#638`](https://github.com/PrefectHQ/ui/pull/638)\n- Redirect links [`#631`](https://github.com/PrefectHQ/ui/pull/631)\n- Interactive api header [`#628`](https://github.com/PrefectHQ/ui/pull/628)\n- Fix agent controls z-index [`#617`](https://github.com/PrefectHQ/ui/pull/617)\n\n#### [2021-02-23](https://github.com/PrefectHQ/ui/compare/2021-02-12...2021-02-23)\n\n- Cut changelog ahead of 2021-02-23 release [`#627`](https://github.com/PrefectHQ/ui/pull/627)\n- make content a sibling of background so it'll scroll [`#616`](https://github.com/PrefectHQ/ui/pull/616)\n- Tenant and user headers [`#621`](https://github.com/PrefectHQ/ui/pull/621)\n- \"How did you hear about us\" dropdown  [`#615`](https://github.com/PrefectHQ/ui/pull/615)\n- add double check for flow id to avoid race condition between flow nav… [`#590`](https://github.com/PrefectHQ/ui/pull/590)\n- Clean up bug [`#591`](https://github.com/PrefectHQ/ui/pull/591)\n\n#### [2021-02-12](https://github.com/PrefectHQ/ui/compare/2021-02-11...2021-02-12)\n\n- VU Hotfix [`#611`](https://github.com/PrefectHQ/ui/pull/611)\n- HOTFIX: Runconfig [`#610`](https://github.com/PrefectHQ/ui/pull/610)\n\n#### [2021-02-11](https://github.com/PrefectHQ/ui/compare/2021-02-03...2021-02-11)\n\n- Cut changelog ahead of 2021-02-11 release [`#607`](https://github.com/PrefectHQ/ui/pull/607)\n- Runconfig pre release [`#606`](https://github.com/PrefectHQ/ui/pull/606)\n- unbreak netlify [`#605`](https://github.com/PrefectHQ/ui/pull/605)\n- lets get docker working [`#601`](https://github.com/PrefectHQ/ui/pull/601)\n- Run configs and run tab update [`#585`](https://github.com/PrefectHQ/ui/pull/585)\n- Add Flow Descriptions [`#563`](https://github.com/PrefectHQ/ui/pull/563)\n- dockerrrrrr [`#598`](https://github.com/PrefectHQ/ui/pull/598)\n- need to get creds into docker to build prod [`#597`](https://github.com/PrefectHQ/ui/pull/597)\n- Airgapping the UI [`#595`](https://github.com/PrefectHQ/ui/pull/595)\n- Show label warning on Server [`#593`](https://github.com/PrefectHQ/ui/pull/593)\n- don't show tutorial banner on server [`#592`](https://github.com/PrefectHQ/ui/pull/592)\n\n#### [2021-02-03](https://github.com/PrefectHQ/ui/compare/2021-01-28...2021-02-03)\n\n- Cut changelog ahead of 2021-02-03 release [`#589`](https://github.com/PrefectHQ/ui/pull/589)\n- Users [`#587`](https://github.com/PrefectHQ/ui/pull/587)\n- Update .env file with new auth variables [`#583`](https://github.com/PrefectHQ/ui/pull/583)\n- Use role_detail instead of role [`#577`](https://github.com/PrefectHQ/ui/pull/577)\n\n#### [2021-01-28](https://github.com/PrefectHQ/ui/compare/2021-01-25...2021-01-28)\n\n- Cut changelog ahead of 2021-01-28 release [`#580`](https://github.com/PrefectHQ/ui/pull/580)\n- Improve auth errors [`#576`](https://github.com/PrefectHQ/ui/pull/576)\n- Schedule TZ Details Tile [`#570`](https://github.com/PrefectHQ/ui/pull/570)\n- Refresh token improvements [`#574`](https://github.com/PrefectHQ/ui/pull/574)\n- Dev =&gt; Master [`#556`](https://github.com/PrefectHQ/ui/pull/556)\n\n#### [2021-01-25](https://github.com/PrefectHQ/ui/compare/2021-01-19...2021-01-25)\n\n- Wrap link artifacts in router links to allow relative navigation [`#559`](https://github.com/PrefectHQ/ui/pull/559)\n- Flow Group schedule timezones [`#532`](https://github.com/PrefectHQ/ui/pull/532)\n- 404 TLC [`#562`](https://github.com/PrefectHQ/ui/pull/562)\n- make sure we're on the correct tab when mounting page [`#561`](https://github.com/PrefectHQ/ui/pull/561)\n\n#### [2021-01-19](https://github.com/PrefectHQ/ui/compare/2021-01-07...2021-01-19)\n\n- Cut changelog ahead of 2021-01-19 release [`#560`](https://github.com/PrefectHQ/ui/pull/560)\n- Add new date method to prevent over-querying [`#558`](https://github.com/PrefectHQ/ui/pull/558)\n- don't show 'none' in details tile if flowgroup has a schedule [`#553`](https://github.com/PrefectHQ/ui/pull/553)\n- Update deploy jobs to distinguish between dev and staging [`#538`](https://github.com/PrefectHQ/ui/pull/538)\n\n#### [2021-01-07](https://github.com/PrefectHQ/ui/compare/2021-01-05...2021-01-07)\n\n- Cut changelog ahead of 2021-01-07 release [`#537`](https://github.com/PrefectHQ/ui/pull/537)\n- Iapi hotfix [`#533`](https://github.com/PrefectHQ/ui/pull/533)\n- Navbar slug fix [`#534`](https://github.com/PrefectHQ/ui/pull/534)\n- tutorial banner  [`#516`](https://github.com/PrefectHQ/ui/pull/516)\n- add support for url-encoded queries [`#529`](https://github.com/PrefectHQ/ui/pull/529)\n\n#### [2021-01-05](https://github.com/PrefectHQ/ui/compare/2020-12-18...2021-01-05)\n\n- Cut changelog ahead of 2021-01-05 release [`#531`](https://github.com/PrefectHQ/ui/pull/531)\n- Touchups [`#530`](https://github.com/PrefectHQ/ui/pull/530)\n-  simplify and improve calendar backend and tenant switch [`#524`](https://github.com/PrefectHQ/ui/pull/524)\n- Navigation update (top level flow visibility remix) [`#520`](https://github.com/PrefectHQ/ui/pull/520)\n- add beforeDestroy hook to fix blank page on reload [`#526`](https://github.com/PrefectHQ/ui/pull/526)\n- Add truncate/tooltip to notification tile [`#527`](https://github.com/PrefectHQ/ui/pull/527)\n- Simpler query [`#518`](https://github.com/PrefectHQ/ui/pull/518)\n- interactive API: graphiql [`#509`](https://github.com/PrefectHQ/ui/pull/509)\n- Calendar view [`#433`](https://github.com/PrefectHQ/ui/pull/433)\n\n#### [2020-12-18](https://github.com/PrefectHQ/ui/compare/2020-12-14...2020-12-18)\n\n- Cut changelog ahead of 2020-12-18 release [`#517`](https://github.com/PrefectHQ/ui/pull/517)\n- Remove decrossing from schematic calculations [`#515`](https://github.com/PrefectHQ/ui/pull/515)\n- Enable artifacts [`#512`](https://github.com/PrefectHQ/ui/pull/512)\n- Flow Run (& Task Run & Task) 404 [`#511`](https://github.com/PrefectHQ/ui/pull/511)\n- Assorted visual bugs [`#507`](https://github.com/PrefectHQ/ui/pull/507)\n\n#### [2020-12-14](https://github.com/PrefectHQ/ui/compare/2020-12-07...2020-12-14)\n\n- Cut changelog ahead of 2020-12-14 release [`#506`](https://github.com/PrefectHQ/ui/pull/506)\n- Stylesheet/CSS audit [`#495`](https://github.com/PrefectHQ/ui/pull/495)\n- Artifact link [`#498`](https://github.com/PrefectHQ/ui/pull/498)\n- Add task run name to global search [`#485`](https://github.com/PrefectHQ/ui/pull/485)\n\n#### [2020-12-07](https://github.com/PrefectHQ/ui/compare/2020-11-30...2020-12-07)\n\n- Update Changelog.md [`#493`](https://github.com/PrefectHQ/ui/pull/493)\n- Fix z-index on artifacts link [`#491`](https://github.com/PrefectHQ/ui/pull/491)\n- Flow run artifacts [`#484`](https://github.com/PrefectHQ/ui/pull/484)\n- Tokens [`#488`](https://github.com/PrefectHQ/ui/pull/488)\n- Update Universal Deploy tutorial [`#482`](https://github.com/PrefectHQ/ui/pull/482)\n- Set State Modal  [`#465`](https://github.com/PrefectHQ/ui/pull/465)\n- remove tutorial and update link in help text [`#480`](https://github.com/PrefectHQ/ui/pull/480)\n- Footer [`#451`](https://github.com/PrefectHQ/ui/pull/451)\n- add fixed height to subnav row to fix jumping bug [`#476`](https://github.com/PrefectHQ/ui/pull/476)\n- Table Rows [`#475`](https://github.com/PrefectHQ/ui/pull/475)\n\n#### [2020-11-30](https://github.com/PrefectHQ/ui/compare/2020-11-13...2020-11-30)\n\n- Cut changelog [`#474`](https://github.com/PrefectHQ/ui/pull/474)\n- [RELEASE-BLOCKING] - Fix positioning of agent controls [`#470`](https://github.com/PrefectHQ/ui/pull/470)\n- Team slug wording [`#471`](https://github.com/PrefectHQ/ui/pull/471)\n- Fix schematic node finished task run durations [`#468`](https://github.com/PrefectHQ/ui/pull/468)\n- Sub page nav [`#441`](https://github.com/PrefectHQ/ui/pull/441)\n- tutorials [`#434`](https://github.com/PrefectHQ/ui/pull/434)\n- Task run restart bugfix [`#452`](https://github.com/PrefectHQ/ui/pull/452)\n- Display the core version in the sidebar [`#431`](https://github.com/PrefectHQ/ui/pull/431)\n- Editable task run names [`#449`](https://github.com/PrefectHQ/ui/pull/449)\n- Editable flow run names [`#448`](https://github.com/PrefectHQ/ui/pull/448)\n- Truncated flow name [`#440`](https://github.com/PrefectHQ/ui/pull/440)\n\n#### [2020-11-13](https://github.com/PrefectHQ/ui/compare/2020-11-12...2020-11-13)\n\n- Update Changelog.md [`#436`](https://github.com/PrefectHQ/ui/pull/436)\n- Artifacts description [`#435`](https://github.com/PrefectHQ/ui/pull/435)\n\n#### [2020-11-12](https://github.com/PrefectHQ/ui/compare/2020-11-11...2020-11-12)\n\n- Update Changelog.md [`#432`](https://github.com/PrefectHQ/ui/pull/432)\n- Timeline [`#278`](https://github.com/PrefectHQ/ui/pull/278)\n- npm update [`#428`](https://github.com/PrefectHQ/ui/pull/428)\n\n#### [2020-11-11](https://github.com/PrefectHQ/ui/compare/2020-11-10...2020-11-11)\n\n- Update Changelog.md [`#429`](https://github.com/PrefectHQ/ui/pull/429)\n- Create a \"Your Teams\" page in the User prefs [`#403`](https://github.com/PrefectHQ/ui/pull/403)\n- md parser  [`#390`](https://github.com/PrefectHQ/ui/pull/390)\n- Allow querying agents from IAPI and bulk clearing agents [`#425`](https://github.com/PrefectHQ/ui/pull/425)\n- fetch task runs for mark as dialog [`#411`](https://github.com/PrefectHQ/ui/pull/411)\n- Accept invitation [`#417`](https://github.com/PrefectHQ/ui/pull/417)\n\n#### [2020-11-10](https://github.com/PrefectHQ/ui/compare/2020-10-29a...2020-11-10)\n\n- Update Changelog.md [`#416`](https://github.com/PrefectHQ/ui/pull/416)\n- Fix issue with notifications tile actions not being aligned to bottom [`#410`](https://github.com/PrefectHQ/ui/pull/410)\n- Parameters tab [`#401`](https://github.com/PrefectHQ/ui/pull/401)\n- Add more info to flow Run Config details section [`#400`](https://github.com/PrefectHQ/ui/pull/400)\n- Adjust state filter [`#402`](https://github.com/PrefectHQ/ui/pull/402)\n- Multiple email Cloud Hooks [`#372`](https://github.com/PrefectHQ/ui/pull/372)\n- Make agents and upcoming tiles refresh when switch backend [`#395`](https://github.com/PrefectHQ/ui/pull/395)\n- Refetch task run states after flow run finishes [`#398`](https://github.com/PrefectHQ/ui/pull/398)\n- Add icon for resource manager tasks  [`#396`](https://github.com/PrefectHQ/ui/pull/396)\n- Scrollbar bug [`#399`](https://github.com/PrefectHQ/ui/pull/399)\n\n#### [2020-10-29a](https://github.com/PrefectHQ/ui/compare/2020-10-29...2020-10-29a)\n\n- Update Changelog.md [`#391`](https://github.com/PrefectHQ/ui/pull/391)\n- Run state tab indicators [`#389`](https://github.com/PrefectHQ/ui/pull/389)\n- Secrets popover [`#377`](https://github.com/PrefectHQ/ui/pull/377)\n- update no agents warning  [`#382`](https://github.com/PrefectHQ/ui/pull/382)\n- add json and string type choices for secrets and validate json [`#370`](https://github.com/PrefectHQ/ui/pull/370)\n\n#### [2020-10-29](https://github.com/PrefectHQ/ui/compare/2020-10-23...2020-10-29)\n\n- Update Changelog.md [`#388`](https://github.com/PrefectHQ/ui/pull/388)\n- Fix authentication check for agents [`#387`](https://github.com/PrefectHQ/ui/pull/387)\n- Add more information to the name your tenant screen [`#368`](https://github.com/PrefectHQ/ui/pull/368)\n- Late count indicator [`#373`](https://github.com/PrefectHQ/ui/pull/373)\n\n#### [2020-10-23](https://github.com/PrefectHQ/ui/compare/2020-10-21...2020-10-23)\n\n- Update Changelog.md [`#375`](https://github.com/PrefectHQ/ui/pull/375)\n- Mapped children [`#364`](https://github.com/PrefectHQ/ui/pull/364)\n- Add page titles to major pages (dashboard, project, flow, runs) [`#367`](https://github.com/PrefectHQ/ui/pull/367)\n- Accept invitations [`#359`](https://github.com/PrefectHQ/ui/pull/359)\n- Cloud Hook Prefix [`#363`](https://github.com/PrefectHQ/ui/pull/363)\n- Remove flow join from the flow run history query [`#365`](https://github.com/PrefectHQ/ui/pull/365)\n\n#### [2020-10-21](https://github.com/PrefectHQ/ui/compare/2020-10-13...2020-10-21)\n\n- update changelog [`#362`](https://github.com/PrefectHQ/ui/pull/362)\n- Update the API connection menu to include helpful links for Server users [`#355`](https://github.com/PrefectHQ/ui/pull/355)\n- Server connection state bugfix [`#360`](https://github.com/PrefectHQ/ui/pull/360)\n- Whitescreen bugfix [`#354`](https://github.com/PrefectHQ/ui/pull/354)\n- \"what's new\" notifications marked as read  [`#344`](https://github.com/PrefectHQ/ui/pull/344)\n- Styling [`#330`](https://github.com/PrefectHQ/ui/pull/330)\n\n#### [2020-10-13](https://github.com/PrefectHQ/ui/compare/2020-10-09...2020-10-13)\n\n- Update Changelog.md [`#326`](https://github.com/PrefectHQ/ui/pull/326)\n- impose height in last ten runs div to keep row consistency [`#323`](https://github.com/PrefectHQ/ui/pull/323)\n- Loading hooks bug [`#321`](https://github.com/PrefectHQ/ui/pull/321)\n- BUGFIX: Prevent dashboard flickering on load, missing team slug [`#313`](https://github.com/PrefectHQ/ui/pull/313)\n- October package updates [`#317`](https://github.com/PrefectHQ/ui/pull/317)\n- Support labels in `flow.run_config` in label warning [`#312`](https://github.com/PrefectHQ/ui/pull/312)\n- authnavguard speed [`#303`](https://github.com/PrefectHQ/ui/pull/303)\n- Take labels from `flow.run_config` if present [`#309`](https://github.com/PrefectHQ/ui/pull/309)\n\n#### [2020-10-09](https://github.com/PrefectHQ/ui/compare/2020-10-05...2020-10-09)\n\n- Update Changelog.md [`#310`](https://github.com/PrefectHQ/ui/pull/310)\n- Invalid state hotfix [`#308`](https://github.com/PrefectHQ/ui/pull/308)\n- Add `Run Config` section to flow details [`#307`](https://github.com/PrefectHQ/ui/pull/307)\n- BUGFIX: Fix version display in flow page version dropdown [`#305`](https://github.com/PrefectHQ/ui/pull/305)\n- use membership id instead of route query for invitation id [`#306`](https://github.com/PrefectHQ/ui/pull/306)\n- Fix race condition with onboard/welcome flow [`#304`](https://github.com/PrefectHQ/ui/pull/304)\n- Flow run labels [`#300`](https://github.com/PrefectHQ/ui/pull/300)\n- add handler for task runs that don't have names [`#299`](https://github.com/PrefectHQ/ui/pull/299)\n- Display task run names on flow run page and task run page [`#302`](https://github.com/PrefectHQ/ui/pull/302)\n- Apollo url speed racer [`#295`](https://github.com/PrefectHQ/ui/pull/295)\n- Restart [`#285`](https://github.com/PrefectHQ/ui/pull/285)\n- Auth nav unit tests [`#266`](https://github.com/PrefectHQ/ui/pull/266)\n- Pluralization bug [`#298`](https://github.com/PrefectHQ/ui/pull/298)\n- Refactor circleCI to inlude a slack notification for prod approvals [`#294`](https://github.com/PrefectHQ/ui/pull/294)\n\n#### [2020-10-05](https://github.com/PrefectHQ/ui/compare/2020-10-01...2020-10-05)\n\n- Update Changelog.md [`#291`](https://github.com/PrefectHQ/ui/pull/291)\n- Expose agent persistence for server users [`#249`](https://github.com/PrefectHQ/ui/pull/249)\n- update url regex [`#277`](https://github.com/PrefectHQ/ui/pull/277)\n- Remove \"A nonexistant user\" from flow and flow run details for server instances [`#269`](https://github.com/PrefectHQ/ui/pull/269)\n\n#### [2020-10-01](https://github.com/PrefectHQ/ui/compare/2020-09-29...2020-10-01)\n\n- Cut changelog [`#279`](https://github.com/PrefectHQ/ui/pull/279)\n- To the dashboard [`#275`](https://github.com/PrefectHQ/ui/pull/275)\n- Invitations [`#274`](https://github.com/PrefectHQ/ui/pull/274)\n- Allow label editing on older versions of core and disable empty entries [`#273`](https://github.com/PrefectHQ/ui/pull/273)\n- Properly redirect to home when server instance has no tenants [`#270`](https://github.com/PrefectHQ/ui/pull/270)\n- Update UI connection info on home view [`#271`](https://github.com/PrefectHQ/ui/pull/271)\n\n#### [2020-09-29](https://github.com/PrefectHQ/ui/compare/2020-09-28a...2020-09-29)\n\n- Update Changelog.md [`#268`](https://github.com/PrefectHQ/ui/pull/268)\n- Task run table duration fix [`#267`](https://github.com/PrefectHQ/ui/pull/267)\n- add flow nav guard test [`#248`](https://github.com/PrefectHQ/ui/pull/248)\n- add isCloud to label warning until agent updates are made in core for… [`#264`](https://github.com/PrefectHQ/ui/pull/264)\n\n#### [2020-09-28a](https://github.com/PrefectHQ/ui/compare/2020-09-28...2020-09-28a)\n\n- Cut changelog [`#262`](https://github.com/PrefectHQ/ui/pull/262)\n- remove links to Cloud tutorials in server [`#255`](https://github.com/PrefectHQ/ui/pull/255)\n- BUGFIX: User invitations with unlimited accounts [`#260`](https://github.com/PrefectHQ/ui/pull/260)\n- User store tests [`#245`](https://github.com/PrefectHQ/ui/pull/245)\n\n#### [2020-09-28](https://github.com/PrefectHQ/ui/compare/2020-09-24...2020-09-28)\n\n- Cut changelog ahead of 2020-09-28 release [`#259`](https://github.com/PrefectHQ/ui/pull/259)\n- Show user notifications on the notifications tile [`#258`](https://github.com/PrefectHQ/ui/pull/258)\n\n#### [2020-09-24](https://github.com/PrefectHQ/ui/compare/2020-09-23...2020-09-24)\n\n- Cut changelog [`#254`](https://github.com/PrefectHQ/ui/pull/254)\n- Fix delete_agent mutation agentId type [`#253`](https://github.com/PrefectHQ/ui/pull/253)\n- Log times [`#247`](https://github.com/PrefectHQ/ui/pull/247)\n\n#### [2020-09-23](https://github.com/PrefectHQ/ui/compare/2020-09-17...2020-09-23)\n\n- Cut changelog [`#246`](https://github.com/PrefectHQ/ui/pull/246)\n- Apollo endpoint usability update [`#241`](https://github.com/PrefectHQ/ui/pull/241)\n- Show version group [`#236`](https://github.com/PrefectHQ/ui/pull/236)\n- Agent tab store [`#238`](https://github.com/PrefectHQ/ui/pull/238)\n- Labels with agent store [`#217`](https://github.com/PrefectHQ/ui/pull/217)\n- Use cache reset method instead of the manual store reset [`#237`](https://github.com/PrefectHQ/ui/pull/237)\n\n#### [2020-09-17](https://github.com/PrefectHQ/ui/compare/2020-09-15...2020-09-17)\n\n- BUGFIX: task concurrency query [`#235`](https://github.com/PrefectHQ/ui/pull/235)\n- Performance work (part...3?) [`#232`](https://github.com/PrefectHQ/ui/pull/232)\n- Cut changelog [`#233`](https://github.com/PrefectHQ/ui/pull/233)\n- BUGFIX: Flow concurrency usage [`#231`](https://github.com/PrefectHQ/ui/pull/231)\n- Unit tests store tenant [`#195`](https://github.com/PrefectHQ/ui/pull/195)\n- Clear late runs [`#227`](https://github.com/PrefectHQ/ui/pull/227)\n\n#### [2020-09-15](https://github.com/PrefectHQ/ui/compare/2020-09-08...2020-09-15)\n\n- Changelog cut ahead of 2020-09-15 release [`#228`](https://github.com/PrefectHQ/ui/pull/228)\n- Provide a way to modify the default server url. [`#219`](https://github.com/PrefectHQ/ui/pull/219)\n- Barchart bugfix VU [`#216`](https://github.com/PrefectHQ/ui/pull/216)\n- Notifications tile [`#220`](https://github.com/PrefectHQ/ui/pull/220)\n- Remove task runs from the upcoming runs query [`#218`](https://github.com/PrefectHQ/ui/pull/218)\n- Performance work part 2 [`#212`](https://github.com/PrefectHQ/ui/pull/212)\n\n#### [2020-09-08](https://github.com/PrefectHQ/ui/compare/2020-09-01...2020-09-08)\n\n- Cut changelog [`#209`](https://github.com/PrefectHQ/ui/pull/209)\n- Performance work [`#201`](https://github.com/PrefectHQ/ui/pull/201)\n- Show the token name on the agent card instead of the token id [`#200`](https://github.com/PrefectHQ/ui/pull/200)\n- Add flow concurrency page [`#199`](https://github.com/PrefectHQ/ui/pull/199)\n- Filtering scheduled flows from the heartbeattimeline [`#188`](https://github.com/PrefectHQ/ui/pull/188)\n- auth0 Vuex store unit tests [`#162`](https://github.com/PrefectHQ/ui/pull/162)\n- Some more GraphQL cleanup [`#193`](https://github.com/PrefectHQ/ui/pull/193)\n- improve approve button  [`#192`](https://github.com/PrefectHQ/ui/pull/192)\n- Membership management tweaks [`#190`](https://github.com/PrefectHQ/ui/pull/190)\n\n#### [2020-09-01](https://github.com/PrefectHQ/ui/compare/2020-08-31a...2020-09-01)\n\n- Cut changelog [`#189`](https://github.com/PrefectHQ/ui/pull/189)\n- Fix mapped children restart from failure bug [`#187`](https://github.com/PrefectHQ/ui/pull/187)\n- Make some of the flow run restart dialog code clearer [`#186`](https://github.com/PrefectHQ/ui/pull/186)\n- Unit tests store api [`#127`](https://github.com/PrefectHQ/ui/pull/127)\n- Rename Mark As -&gt; Set State everywhere [`#183`](https://github.com/PrefectHQ/ui/pull/183)\n- Add link to task run page from gantt chart [`#185`](https://github.com/PrefectHQ/ui/pull/185)\n- Unit tests store license [`#164`](https://github.com/PrefectHQ/ui/pull/164)\n- Order params [`#176`](https://github.com/PrefectHQ/ui/pull/176)\n\n#### [2020-08-31a](https://github.com/PrefectHQ/ui/compare/2020-08-31...2020-08-31a)\n\n- Cut changelog [`#181`](https://github.com/PrefectHQ/ui/pull/181)\n- August package updates [`#180`](https://github.com/PrefectHQ/ui/pull/180)\n- Display # of mapped children (when available) [`#179`](https://github.com/PrefectHQ/ui/pull/179)\n\n#### [2020-08-31](https://github.com/PrefectHQ/ui/compare/2020-08-28...2020-08-31)\n\n- Cut changelog [`#178`](https://github.com/PrefectHQ/ui/pull/178)\n- Scrollbars update [`#177`](https://github.com/PrefectHQ/ui/pull/177)\n- remove requirement that api token name is more than 2 characters [`#174`](https://github.com/PrefectHQ/ui/pull/174)\n\n#### [2020-08-28](https://github.com/PrefectHQ/ui/compare/2020-08-27...2020-08-28)\n\n- BUGFIX: Flow page details tile [`#171`](https://github.com/PrefectHQ/ui/pull/171)\n- Cut changelog [`#170`](https://github.com/PrefectHQ/ui/pull/170)\n- Durations [`#169`](https://github.com/PrefectHQ/ui/pull/169)\n- Unit tests store refresh [`#165`](https://github.com/PrefectHQ/ui/pull/165)\n- State manipulation improvements [`#163`](https://github.com/PrefectHQ/ui/pull/163)\n- Fix membership invitation toasts [`#166`](https://github.com/PrefectHQ/ui/pull/166)\n\n#### [2020-08-27](https://github.com/PrefectHQ/ui/compare/2020-08-26...2020-08-27)\n\n- Cut changelog [`#161`](https://github.com/PrefectHQ/ui/pull/161)\n- Don't show maintenance mode on load (unless it's true) [`#159`](https://github.com/PrefectHQ/ui/pull/159)\n- Remove run count [`#158`](https://github.com/PrefectHQ/ui/pull/158)\n\n#### [2020-08-26](https://github.com/PrefectHQ/ui/compare/2020-08-25...2020-08-26)\n\n- Cut changelog [`#156`](https://github.com/PrefectHQ/ui/pull/156)\n- Maintenance mode [`#155`](https://github.com/PrefectHQ/ui/pull/155)\n\n#### [2020-08-25](https://github.com/PrefectHQ/ui/compare/2020-08-24...2020-08-25)\n\n- Cut changelog ahead of release [`#143`](https://github.com/PrefectHQ/ui/pull/143)\n- Add Flow ID to the Flow Details tile [`#142`](https://github.com/PrefectHQ/ui/pull/142)\n- Include stripe [`#140`](https://github.com/PrefectHQ/ui/pull/140)\n\n#### [2020-08-24](https://github.com/PrefectHQ/ui/compare/2020-08-22...2020-08-24)\n\n- Cut changelog ahead of release [`#138`](https://github.com/PrefectHQ/ui/pull/138)\n- Add cancelling state [`#137`](https://github.com/PrefectHQ/ui/pull/137)\n\n#### [2020-08-22](https://github.com/PrefectHQ/ui/compare/2020-08-20...2020-08-22)\n\n- Logs refresh [`#128`](https://github.com/PrefectHQ/ui/pull/128)\n- Alert and agent store/vuex unit tests [`#124`](https://github.com/PrefectHQ/ui/pull/124)\n\n#### [2020-08-20](https://github.com/PrefectHQ/ui/compare/2020-08-19...2020-08-20)\n\n- Cut changelog ahead of release [`#125`](https://github.com/PrefectHQ/ui/pull/125)\n- Tenant switch [`#123`](https://github.com/PrefectHQ/ui/pull/123)\n\n#### [2020-08-19](https://github.com/PrefectHQ/ui/compare/2020-08-18...2020-08-19)\n\n- Fix inputs on task concurrency limiting mutation [`#122`](https://github.com/PrefectHQ/ui/pull/122)\n\n### 2020-08-18\n\n- Cut changelog [`#121`](https://github.com/PrefectHQ/ui/pull/121)\n- Update CircleCI to deploy prod artifacts on tag [`#120`](https://github.com/PrefectHQ/ui/pull/120)\n- Hopefully fix permissions for the deployment buckets [`#119`](https://github.com/PrefectHQ/ui/pull/119)\n- Update build script to export current timestamp [`#118`](https://github.com/PrefectHQ/ui/pull/118)\n- Add auto-deploy to staging job [`#117`](https://github.com/PrefectHQ/ui/pull/117)\n- Labels [`#106`](https://github.com/PrefectHQ/ui/pull/106)\n- Various Updates [`#116`](https://github.com/PrefectHQ/ui/pull/116)\n- Add Cloud alert [`#108`](https://github.com/PrefectHQ/ui/pull/108)\n- Update tenant CLI command in CreateTenant section [`#105`](https://github.com/PrefectHQ/ui/pull/105)\n- Update the schedule toggle component to use an optimistic response [`#104`](https://github.com/PrefectHQ/ui/pull/104)\n- Add Created On column to Flow Table [`#103`](https://github.com/PrefectHQ/ui/pull/103)\n- fix variable casing on restart button and name restart mutation [`#98`](https://github.com/PrefectHQ/ui/pull/98)\n- Flow run tutorial fix [`#96`](https://github.com/PrefectHQ/ui/pull/96)\n- Remove toasted [`#95`](https://github.com/PrefectHQ/ui/pull/95)\n- Flow Run Cancellation [`#92`](https://github.com/PrefectHQ/ui/pull/92)\n- Fix issue with task failures tile having wrong color [`#89`](https://github.com/PrefectHQ/ui/pull/89)\n- Fix admin settings references and Cloud Hooks form [`#86`](https://github.com/PrefectHQ/ui/pull/86)\n- Fix issue with updating tenant settings [`#84`](https://github.com/PrefectHQ/ui/pull/84)\n- Use template for versions query, add id to query to prevent invariant violations in the apollo cache [`#83`](https://github.com/PrefectHQ/ui/pull/83)\n- Add a netlify config [`#82`](https://github.com/PrefectHQ/ui/pull/82)\n- Update wording in the license section of the README [`#81`](https://github.com/PrefectHQ/ui/pull/81)\n- Schematics update [`#77`](https://github.com/PrefectHQ/ui/pull/77)\n- Extend late window by a little [`#76`](https://github.com/PrefectHQ/ui/pull/76)\n- Team settings fixes [`#75`](https://github.com/PrefectHQ/ui/pull/75)\n- Team fixes [`#72`](https://github.com/PrefectHQ/ui/pull/72)\n- Tag images with master instead of alpha [`#73`](https://github.com/PrefectHQ/ui/pull/73)\n- Delete fix [`#74`](https://github.com/PrefectHQ/ui/pull/74)\n- User profile fix [`#71`](https://github.com/PrefectHQ/ui/pull/71)\n- README.md [`#51`](https://github.com/PrefectHQ/ui/pull/51)\n- Universal deploy bugfix [`#70`](https://github.com/PrefectHQ/ui/pull/70)\n- Flow run tutorial bugfix [`#69`](https://github.com/PrefectHQ/ui/pull/69)\n- Typography fix [`#68`](https://github.com/PrefectHQ/ui/pull/68)\n- In Progress tile [`#67`](https://github.com/PrefectHQ/ui/pull/67)\n- Errors tile change [`#66`](https://github.com/PrefectHQ/ui/pull/66)\n- Heights and spacing [`#65`](https://github.com/PrefectHQ/ui/pull/65)\n- Use and display state timestamp on the failed flow tile [`#64`](https://github.com/PrefectHQ/ui/pull/64)\n- Gantt chart [`#59`](https://github.com/PrefectHQ/ui/pull/59)\n- Fix spacing on tenant creation section [`#62`](https://github.com/PrefectHQ/ui/pull/62)\n- Update frame-ancestors csp [`#61`](https://github.com/PrefectHQ/ui/pull/61)\n- Update padding and height [`#60`](https://github.com/PrefectHQ/ui/pull/60)\n- Updates, fixes, and performance improvements [`#58`](https://github.com/PrefectHQ/ui/pull/58)\n- Add redirects file to public folder to handle netlify redirects [`#46`](https://github.com/PrefectHQ/ui/pull/46)\n- Sidebar removal [`#42`](https://github.com/PrefectHQ/ui/pull/42)\n- dont install node in the deploy step [`#57`](https://github.com/PrefectHQ/ui/pull/57)\n- npm run build [`#55`](https://github.com/PrefectHQ/ui/pull/55)\n- upgrade node [`#56`](https://github.com/PrefectHQ/ui/pull/56)\n- deploy from master not dev [`#54`](https://github.com/PrefectHQ/ui/pull/54)\n- deploy to dev [`#48`](https://github.com/PrefectHQ/ui/pull/48)\n- Disable committing vscode editor settings to the repo [`#53`](https://github.com/PrefectHQ/ui/pull/53)\n- Speed up failures tile [`#44`](https://github.com/PrefectHQ/ui/pull/44)\n- Speed up task failures tile [`#45`](https://github.com/PrefectHQ/ui/pull/45)\n- Fix ordering for last 10 runs (and possible speedup?) [`#50`](https://github.com/PrefectHQ/ui/pull/50)\n- Speed up last task run query [`#49`](https://github.com/PrefectHQ/ui/pull/49)\n- Remove LogRocket from Server deployments [`#43`](https://github.com/PrefectHQ/ui/pull/43)\n- Add Docker related things [`#41`](https://github.com/PrefectHQ/ui/pull/41)\n- 9 tenant screen [`#30`](https://github.com/PrefectHQ/ui/pull/30)\n- Create LICENSE [`#39`](https://github.com/PrefectHQ/ui/pull/39)\n- Remove hasura aggregates from flow failure tile [`#29`](https://github.com/PrefectHQ/ui/pull/29)\n- Remove pnpm, update package-lock, fix eslintrc [`#28`](https://github.com/PrefectHQ/ui/pull/28)\n- Remove cypress from dependencies [`#27`](https://github.com/PrefectHQ/ui/pull/27)\n- Skip and then restart polling for global queries [`#20`](https://github.com/PrefectHQ/ui/pull/20)\n- Task error improvement [`#23`](https://github.com/PrefectHQ/ui/pull/23)\n- Default params [`#24`](https://github.com/PrefectHQ/ui/pull/24)\n- Adds concurrency info component [`#21`](https://github.com/PrefectHQ/ui/pull/21)\n- fix update membership mutation [`#25`](https://github.com/PrefectHQ/ui/pull/25)\n- Error message tile size [`#13`](https://github.com/PrefectHQ/ui/pull/13)\n- Add environment variables for stripe, auth0, and logrocket [`#16`](https://github.com/PrefectHQ/ui/pull/16)\n- Don't join to task table when querying for last task run [`#17`](https://github.com/PrefectHQ/ui/pull/17)\n- Don't join to flow table when querying for last flow run [`#18`](https://github.com/PrefectHQ/ui/pull/18)\n- Update 2 (to be merged after Update) [`#8`](https://github.com/PrefectHQ/ui/pull/8)\n- Failed Task Tile [`#6`](https://github.com/PrefectHQ/ui/pull/6)\n- Update [`#7`](https://github.com/PrefectHQ/ui/pull/7)\n- Allow switching between backends [`#5`](https://github.com/PrefectHQ/ui/pull/5)\n- 2 [`#4`](https://github.com/PrefectHQ/ui/pull/4)\n- 1 [`#3`](https://github.com/PrefectHQ/ui/pull/3)\n- Dev [`#2`](https://github.com/PrefectHQ/ui/pull/2)\n- Hello world! [`#1`](https://github.com/PrefectHQ/ui/pull/1)\n"
  },
  {
    "path": "Dockerfile",
    "content": "# syntax = docker/dockerfile:1.0-experimental\nFROM node:14.7.0 as ui\n\n# Set version args from CMD input\nARG PREFECT_VERSION=development\nENV PREFECT_VERSION=$PREFECT_VERSION\n\n# Write the arg into the .env file\nRUN echo \"VUE_APP_PREFECT_VERSION=${PREFECT_VERSION}\" >> .env\n\n# Move application files to the app directory\nCOPY ./ /app\nCOPY ./LICENSE LICENSE\n\n# Switch to the app directory\nWORKDIR /app\n\n# Install dependencies\nRUN npm ci\n\n# Build static files\nRUN npm run build\n\nFROM nginx:stable\n\n# Copy the previously built static files to the nginx container\nCOPY --from=ui /app/dist /var/www\n\n# Replace the default nginx config\n# with the one we've defined here\nCOPY ./nginx.conf /etc/nginx/conf.d/default.conf\n\n\n# Copy and allow all users to execute both the script to start the server\n# and the script that intercepts termination requests\nCOPY ./start_server.sh /start_server.sh\nRUN chmod a+x /start_server.sh\n\nCOPY ./intercept.sh /intercept.sh\nRUN chmod a+x /intercept.sh\n\n# Allow write access to www to ensure we can set the configuration file.\n# This is to enable rootless mode\nARG UID=101\nARG GID=101\n\nRUN sed -i 's,listen       80;,listen       8080;,' /etc/nginx/conf.d/default.conf \\\n    && sed -i '/user  nginx;/d' /etc/nginx/nginx.conf \\\n    && sed -i 's,/var/run/nginx.pid,/tmp/nginx.pid,' /etc/nginx/nginx.conf \\\n    && sed -i \"/^http {/a \\    proxy_temp_path /tmp/proxy_temp;\\n    client_body_temp_path /tmp/client_temp;\\n    fastcgi_temp_path /tmp/fastcgi_temp;\\n    uwsgi_temp_path /tmp/uwsgi_temp;\\n    scgi_temp_path /tmp/scgi_temp;\\n\" /etc/nginx/nginx.conf\n\nRUN chown -R $UID:0 /var/cache/nginx \\\n    && chmod -R g+w /var/cache/nginx \\\n    && chown -R $UID:0 /etc/nginx \\\n    && chmod -R g+w /etc/nginx \\\n    && chown -R $UID:0 /var/www \\\n    && chmod -R g+w /var/www\n\nUSER $UID\n\nSTOPSIGNAL SIGINT\n\nCMD [\"/intercept.sh\"]\n"
  },
  {
    "path": "LICENSE",
    "content": "                               Prefect Community License\n                                       Version 1.0\n\nA copy of this license may be found at\nhttps://www.prefect.io/legal/prefect-community-license\n\nThe Prefect Community License (this “Agreement”) sets forth the terms on which\nPrefect Technologies, Inc. (“Prefect”) makes available Prefect source code\nthrough one or more files each within a directory or containing a header stating\nthe contents are subject to Prefect copyright (the “Software”). BY INSTALLING,\nDOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE SOFTWARE, YOU AGREE TO\nTHE TERMS AND CONDITIONS OF THIS AGREEMENT.  IF YOU DO NOT AGREE TO SUCH TERMS\nAND CONDITIONS, YOU MUST NOT USE THE SOFTWARE.  IF YOU ARE RECEIVING THE\nSOFTWARE ON BEHALF OF A LEGAL ENTITY, YOU REPRESENT AND WARRANT THAT YOU HAVE\nTHE ACTUAL AUTHORITY TO AGREE TO THE TERMS AND CONDITIONS OF THIS AGREEMENT ON\nBEHALF OF SUCH ENTITY. “Licensee” as used herein means you, an individual, or\nthe entity on behalf of whom you are receiving the Software.\n\n1. LICENSE GRANT AND LIMITATIONS\n   \n   A. License.  Provided that Licensee remains in compliance with the terms and\n   conditions that are set forth in this Agreement, Prefect grants you the\n   following limited, revocable, non-exclusive, non-transferrable,\n   non-sublicensable, worldwide license during the term of this Agreement to (a)\n   only use the Software internally; (b) prepare modifications and derivative\n   works of the Software; (c) distribute the Software (including without\n   limitation in source code or object code form); and (d) reproduce copies of\n   the Software (the “License”). \n   \n   B. Limitations on License Grant.  In consideration of the rights granted\n   herein by this Agreement, Licensee’s distribution of the Software is subject\n   to the following conditions:\n      \n      i. Licensee is not granted the right to, and Licensee shall not, exercise\n      the License for an Excluded Purpose. For purposes of this Agreement,\n      “Excluded Purpose” includes, but is not limited to, using the Software, or\n      any derivative works thereof, to make available any software-as-a-service,\n      platform-as-a-service, infrastructure-as-a-service or other similar\n      service that competes with Prefect products or services.\n      \n      ii. Licensee must cause any Software modified by Licensee to carry\n      prominent notices stating that Licensee modified the Software; and\n      \n      iii. On any copy of the Software distributed by the Licensee, Licensee\n      shall reproduce and not remove or alter all Prefect or third-party\n      copyright or other notices contained in the Software, and Licensee must\n      provide the following notice with any copy:\n\n            “This software is made available by Prefect Technologies, Inc.,\n            under the terms of the Prefect Community License Agreement located\n            at https://www.prefect.io/legal/prefect-community-license . BY\n            INSTALLING, DOWNLOADING, ACCESSING, USING OR DISTRIBUTING ANY OF THE\n            SOFTWARE, YOU AGREE TO THE TERMS OF SUCH LICENSE AGREEMENT.”\n   \n   C. Modifications.  Licensee may add its own copyright notices to\n   modifications made by Licensee and may provide additional or different\n   license terms and conditions for use, reproduction, or distribution of\n   Licensee’s modifications. While redistributing the Software or modifications\n   thereof, Licensee may choose to offer, for a fee or free of charge, support,\n   warranty, indemnity, or other obligations.  Licensee, and not Prefect, will\n   be solely responsible for any such obligations.\n   \n   D. No Sublicense. The License does not include any right to sublicense the\n   Software. Each recipient to which Licensee provides the Software, however,\n   may exercise the License so long as such recipient agrees to the terms and\n   conditions of this Agreement.\n\n2. TERM AND TERMINATION\n   \n   A. Term.  This Agreement will continue unless and until earlier terminated as\n   set forth herein.\n   \n   B. Termination.  If Licensee breaches any of the conditions or obligations\n   set forth under this Agreement, this Agreement shall automatically terminate,\n   and the License rights granted therein shall be automatically and permanently\n   revoked.\n\n3. INTELLECTUAL PROPERTY\n\nAs between the parties, Prefect retains all right, title, and interest in the\nSoftware, and all intellectual property rights contained therein, regardless of\nwhether such intellectual property rights are registered or unregistered.\nPrefect hereby similarly reserves all rights in its trademarks and service\nmarks, and all goodwill developed therefrom shall inure to the benefit of\nPrefect; no licenses therein are granted by way of this Agreement.  Prefect\nhereby reserves all rights not expressly granted to Licensee by way of this\nAgreement.\n\n4. DISCLAIMER OF WARRANTIES\n\nEXCEPT AS SPECIFICALLY PROVIDED FOR HEREIN, THE SOFTWARE AND ANY MATERIALS ARE\nPROVIDED “AS IS”.  PREFECT AND ANY THIRD-PARTY PROVIDERS SPECIFICALLY DISCLAIM,\nWITHOUT LIMITATION, ALL WARRANTIES OF ANY KIND, WHETHER EXPRESS OR IMPLIED,\nINCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\nFITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT OR THOSE WARRANTIES ARISING\nFROM A COURSE OF PERFORMANCE, A COURSE OF DEALING OR TRADE USAGE.  EXCEPT AS\nEXPRESSLY PROVIDED HEREIN, PREFECT MAKES NO REPRESENTATION OR WARRANTY (I) AS TO\nTHE SOFTWARE; (II) AS TO THE RESULTS TO BE ATTAINED BY LICENSEE OR ANY THIRD\nPARTY FROM THE SOFTWARE; (III) AS TO THE LIFE OF ANY URL USED BY THE SOFTWARE;\nOR (IV) THAT ALL USES THAT CAN BE MADE OF THE SOFTWARE COMPLY WITH APPLICABLE\nLAW; RATHER, IT IS LICENSEE’S RESPONSIBILITY TO CONFORM ITS USE OF THE SOFTWARE\nWITH THE LAW.  LICENSEE ACKNOWLEDGES THAT CERTAIN SOFTWARE AND EQUIPMENT USED BY\nIT MAY NOT BE CAPABLE OF SUPPORTING CERTAIN FEATURES OF THE SOFTWARE. EACH PARTY\nHERETO HEREBY ACKNOWLEDGES THAT IT HAS NOT RELIED UPON ANY REPRESENTATIONS OR\nWARRANTIES MADE BY THE OTHER EXCEPT AS SPECIFICALLY SET FORTH IN THIS AGREEMENT.\n\n5. LIMITATIONS ON LIABILITY\n\nEXCEPT FOR A BREACH OF SECTION 6 AND REGARDLESS OF THE FORM OF ACTION, IN NO\nEVENT WILL EITHER PARTY (OR ITS OFFICERS, DIRECTORS, EMPLOYEES, MEMBERS,\nMANAGERS OR AGENTS) BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, PUNITIVE,\nEXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, LOST PROFITS,\nLOST DATA, BUSINESS INTERRUPTION, LOSS OF REPUTATION OR COSTS OF SUBSTITUTE\nSERVICES) THAT THE OTHER PARTY MAY INCUR OR EXPERIENCE ARISING OUT OF OR\nRELATING TO THE SOFTWARE, THIS AGREEMENT OR ITS TERMINATION, EVEN IF ADVISED OF\nTHE POSSIBILITY THEREOF. FURTHER, PREFECT SHALL NOT BE LIABLE (AND ITS OFFICERS,\nDIRECTORS, MEMBERS, MANAGERS, EMPLOYEES AND AGENTS, AND AFFILIATES THEREOF) TO\nLICENSEE FOR DAMAGES FOR ANY CAUSE WHATSOEVER NOTWITHSTANDING THE FORM OF SUCH\nCLAIMS (INCLUDING NEGLIGENCE).\n\n6. MISCELLANEOUS\n   \n   A. Governing law and venue. This Agreement shall be governed by and construed\n   in accordance with the laws of the State of Delaware applicable to contracts\n   to be performed entirely within Delaware. Any action or proceeding to enforce\n   or arising out of this Agreement shall be commenced in the state and federal\n   courts located in Delaware.  The parties hereto consent to the exclusive\n   jurisdiction of such courts, agree that venue will be proper in such courts\n   and waive any objections based upon forum non conveniens.  The choice of\n   forum set forth in this Section 7 will not be deemed to preclude the\n   enforcement of any judgment obtained in such forum or the taking of any\n   action under this Agreement to enforce such judgment in any other\n   jurisdiction.   \n   \n   B. Export Control Restrictions. Licensee warrants that its use of the\n   Software shall comply with all export control laws of the United States and\n   Licensee agrees to indemnify, defend and hold Prefect harmless from any\n   liability, claim, loss or expense suffered or incurred by Prefect as a result\n   of a breach of this warranty.\n   \n   C. Assignment. This Agreement shall be binding upon Licensee’s successors and\n   permitted assigns; neither this Agreement nor any right or obligation arising\n   under it may be assigned, licensed, sublicensed, sold, mortgaged, pledged or\n   otherwise disposed of (collectively, a “disposition”) by Licensee without the\n   prior written consent of Prefect, and any attempted disposition shall be null\n   and void.  Prefect may freely assign its rights under this Agreement to any\n   third party.\n   \n   D. Entire Agreement; Modifications; No Waiver.  This Agreement constitutes\n   the entire Agreement of the parties with respect to the subject matter\n   hereof, supersedes any and all existing agreements relating to the subject\n   matter hereof, and may not be modified or amended except by a written\n   instrument signed by both parties.  No failure or delay in exercising any\n   right, power or remedy under the Agreement shall operate as a waiver thereof,\n   nor shall any single or partial exercise of any right under this Agreement\n   preclude any other or further exercise thereof or the exercise of any other\n   right.  \n   \n   E. Severability.  If any provision of this Agreement shall be held to be\n   illegal, invalid or unenforceable, such illegality, invalidity or\n   unenforceability shall apply only to such provision and shall not in any\n   manner affect or render illegal, invalid or unenforceable any other provision\n   of this Agreement, and this Agreement shall be reformed, construed and\n   enforced to the fullest extent as if any such illegal, invalid or\n   unenforceable provision were not contained herein.\n   \n   F. Survival.  The obligations under Sections 3 and 6.B, as well as any other\n   provision that by its nature is intended to survive, shall survive the\n   termination or expiration of this Agreement.  \n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\" >\n   <img src=\"https://images.ctfassets.net/gm98wzqotmnx/3Ufcb7yYqcXBDlAhJ30gce/c237bb3254190795b30bf734f3cbc1d4/prefect-logo-full-gradient.svg\" width=\"500\" style=\"max-width: 500px;\" alt=\"Prefect Logo\">\n</p>\n\n<p align=\"center\">\n   <a href=\"https://app.netlify.com/sites/prefect-ui/deploys\">\n      <img src=\"https://api.netlify.com/api/v1/badges/effeac10-a905-46ee-8e93-b59454ecc8bb/deploy-status\" alt=\"Netlify Build Status\" alt=\"Netlify status badge\">\n   </a>\n\n   <a href=\"https://prefect.io/slack\">\n      <img src=\"https://prefect-slackin.herokuapp.com/badge.svg\" alt=\"Slack members status badge\">\n   </a>\n</p>\n<p align=\"center\">\n   <a href=\"https://prefect.io\">\n    <img src=\"https://images.ctfassets.net/gm98wzqotmnx/3mwImS57DEydMQXU1FCGG/6e36e2d49faf78cf4a166f123c2c43ca/image__5_.png\" height=\"27\" alt=\"Powered By Prefect\">\n    </a>\n</p>\n\n# Prefect UI\n\nNote: This repo is for Prefect UI development. To run the Prefect UI as part of [Prefect Server](https://github.com/PrefectHQ/server/), install [Prefect](https://github.com/prefecthq/prefect) and run `prefect server start`.\n\n### Installation\n\nPrefect UI requires [Node.js](https://nodejs.org/) v14 and [npm](https://www.npmjs.com/) v6 to run.\n\nYou'll also need an API token from a professional Font Awesome account to build the project locally; this token should be placed in a git-ignored `.env` file (e.g. `.env.development.local`) as it's referenced by `.npmrc` for accessing the private FA npm registry.\n\nBefore starting the development server, you'll need to install project dependencies:\n\n```sh\n$ git clone https://github.com/PrefectHQ/ui.git\n$ cd ui\n$ npm install\n```\n\nThen, you can start the Prefect UI development server:\n\n```sh\n$ npm run serve\n```\n\nThe Prefect UI should be available at [http://localhost:8080](http://localhost:8080); changes to the code in the `src/` directory will result in a hot reload of the application. For more information on hot-reloading or the development server, take a look at the [Webpack](https://webpack.js.org/) and [Vue CLI](https://cli.vuejs.org/) documentation.\n\n### Testing\n\nPrefect UI contains various unit tests for things like the Vuex store and Vue Router middleware; running theses tests locally requires [Jest](https://jestjs.io/). We recommend using a node package executor like [npx](https://www.npmjs.com/package/npx) for this dependency.\n\nRunning all unit tests:\n\n```\n$ npx jest\n```\n\nRunning specific tests:\n\n```\n$ npx jest auth\n# This will run tests found in middleware/authNavGuard.spec.js, store/auth.spec.js, and store/auth0.spec.js\n```\n\n### Development\n\nWe welcome contributions!\n\nPrefect UI is built on [Vue.js](https://vuejs.org/), a modern front-end JavaScript framework. We generally depend on Google's Material Design guidelines, drawing on and extending the [Vuetify](https://vuetifyjs.com/en/) component library.\n\n#### Building for production\n\nFor production builds:\n\n```sh\n$ npm run build\n```\n\nCompiled and minified code and assets are placed in the `dist/` folder; `dist/index.html` is the built application's entrypoint.\n\n### The Prefect UI Docker image\n\nThis repo comes with a Dockerfile for building a UI image; it's generally not recommended to build this yourself but to instead use one of the versioned images found in the [PrefectHQ Dockerhub registry](https://hub.docker.com/r/prefecthq/ui).\n\n#### Serving the built application\n\nThe Prefect UI requires a functional Prefect API to operate. For details on starting Prefect Server, visit the [docs](https://docs.prefect.io/api/latest/#ui-and-server).\n\n#### Submitting a PR\nPR Titles should include a prefix that sets out the purpose of the PR.  Most PRs will begin with the prefix Bugfix or Feature.  The title should describe the work and purpose of the PR clearly and succinctly and should be appropriate and safe for the Prefect community. \n\n###### Example\nFeature: Add create flow run method to automations\n\n## License\n\nPrefect UI is lovingly made by the team at [Prefect](https://www.prefect.io) and licensed under the [Prefect Community License](https://www.prefect.io/legal/prefect-community-license/). For information on how you can use, extend, and depend on Prefect UI to automate your data, take a look at our [license](https://github.com/PrefectHQ/ui/blob/master/LICENSE) or [contact us](https://www.prefect.io/pricing#contact).\n"
  },
  {
    "path": "babel.config.js",
    "content": "module.exports = {\n  presets: [['@vue/app', { useBuiltIns: 'entry' }]],\n  plugins: [\n    '@babel/plugin-proposal-nullish-coalescing-operator',\n    '@babel/plugin-proposal-optional-chaining'\n  ]\n}\n"
  },
  {
    "path": "changelog-template.hbs",
    "content": "# Changelog\n\n{{#each releases}}\n  {{#if href}}\n    ###{{#unless major}}#{{/unless}} [{{title}}]({{href}})\n  {{else}}\n    ### {{title}}\n  {{/if}}\n\n  {{#if summary}}\n    {{summary}}\n  {{/if}}\n\n  {{#each merges}}\n    - {{#if commit.breaking}}**Breaking change:** {{/if}}{{message}}{{#if href}} [`#{{id}}`]({{href}}){{/if}}\n  {{/each}}\n  {{#each fixes}}\n    - {{#if commit.breaking}}**Breaking change:** {{/if}}{{commit.subject}}{{#each fixes}}{{#if href}} [`#{{id}}`]({{href}}){{/if}}{{/each}}\n  {{/each}}\n  {{#each commits}}\n    - {{#if breaking}}**Breaking change:** {{/if}}{{subject}}{{#if href}} [`{{shorthash}}`]({{href}}){{/if}}\n  {{/each}}\n\n{{/each}}"
  },
  {
    "path": "export.sh",
    "content": "#!/bin/sh\n\ntouch .env\necho \"\" >> .env\n\ncat \".salesforce_env_${VUE_APP_ENVIRONMENT}\" | while read line; do\n    echo $line >> .env\ndone"
  },
  {
    "path": "file-downloader.js",
    "content": "const { https } = require('follow-redirects')\nconst fs = require('fs')\n\nconst downloads = [\n  {\n    filePath: './src/styles/graphiql.css',\n    url: 'https://unpkg.com/graphiql@1.4.7/graphiql.min.css'\n  },\n  {\n    filePath: './public/fonts/material-icons.ttf',\n    url:\n      'https://fonts.gstatic.com/s/materialicons/v76/flUhRq6tzZclQEJ-Vdg-IuiaDsNZ.ttf'\n  },\n  {\n    filePath: './public/fonts/material-icons-outlined.otf',\n    url:\n      'https://fonts.gstatic.com/s/materialiconsoutlined/v44/gok-H7zzDkdnRel8-DQ6KAXJ69wP1tGnf4ZGhUcd.otf'\n  },\n  {\n    filePath: './public/fonts/roboto-100.ttf',\n    url: 'https://fonts.gstatic.com/s/roboto/v20/KFOkCnqEu92Fr1MmgWxP.ttf'\n  },\n  {\n    filePath: './public/fonts/roboto-300.ttf',\n    url: 'https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmSU5vAw.ttf'\n  },\n  {\n    filePath: './public/fonts/roboto-400.ttf',\n    url: 'https://fonts.gstatic.com/s/roboto/v20/KFOmCnqEu92Fr1Me5Q.ttf'\n  },\n  {\n    filePath: './public/fonts/roboto-500.ttf',\n    url: 'https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmEU9vAw.ttf'\n  },\n  {\n    filePath: './public/fonts/roboto-700.ttf',\n    url: 'https://fonts.gstatic.com/s/roboto/v20/KFOlCnqEu92Fr1MmWUlvAw.ttf'\n  }\n]\n\ndownloads.forEach(loc => {\n  const file = fs.createWriteStream(loc.filePath)\n  https.get(loc.url, loc.options, function(res) {\n    res.pipe(file)\n    file.on('finish', function() {\n      file.close()\n    })\n  })\n})\n"
  },
  {
    "path": "intercept.sh",
    "content": "#!/usr/bin/env bash\n\nfunction _intercept {\n    kill -TERM $child\n    exit 0\n}\n\ntrap _intercept SIGTERM\ntrap _intercept SIGINT\ntrap _intercept SIGQUIT\ntrap _intercept EXIT\n\n/start_server.sh & tail -f /dev/null & child=$!\n\nwait \"$child\""
  },
  {
    "path": "jest.config.js",
    "content": "// Temporary workaround re: https://github.com/vuejs/vue-cli/issues/1879\nprocess.env.VUE_CLI_BABEL_TARGET_NODE = true\nprocess.env.VUE_CLI_BABEL_TRANSPILE_MODULES = true\nprocess.env.VUE_APP_GRAPHQL_HTTP = 'http://test.io'\n\nmodule.exports = {\n  automock: false,\n  timers: 'fake',\n  collectCoverageFrom: [\n    'src/**/*.{js,vue}',\n    '!**/node_modules/**',\n    '!**/dist/**',\n    '!src/main.js',\n    '!src/router.js'\n  ],\n  coverageDirectory: 'tests/__coverage__',\n  moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],\n  transform: {\n    '^.+\\\\.vue$': 'vue-jest',\n    '.+\\\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':\n      'jest-transform-stub',\n    '^.+\\\\.jsx?$': 'babel-jest'\n  },\n  moduleNameMapper: {\n    '\\\\.(css|scss|less)$': '<rootDir>/__mocks__/styleMock.js',\n    '^@/(.*)$': '<rootDir>/src/$1'\n  },\n  transformIgnorePatterns: ['<rootDir>/node_modules/'],\n  roots: ['src', 'tests'],\n  setupFiles: ['jest-localstorage-mock', 'jest-fetch-mock', 'jest-canvas-mock'],\n  setupFilesAfterEnv: ['<rootDir>/tests/jestSetup.js'],\n  snapshotSerializers: ['jest-serializer-vue'],\n  testMatch: [\n    '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'\n  ],\n  testURL: 'http://localhost/'\n}\n"
  },
  {
    "path": "netlify.toml",
    "content": "[[redirects]]\nfrom = \"/*\"\nto = \"/index.html\"\nstatus = 200\n\n\n[[headers]]\n# Define which paths this specific [[headers]] block will cover.\nfor = \"/*\"\n\n[headers.values]\n# X-Content-Type-Options controls whether browsers attempt to detect\n# the content type, rather than relyihng on the Content-Type header.\n# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options\nX-Content-Type-Options = \"nosniff\"\n\n# Strict-Transport-Security to require HTTPS connections in supported\n# browsers. These settings are required to be eligible for inclusion\n# in the HSTS Preload list; see: https://hstspreload.org/\nStrict-Transport-Security = \"\"\"\\\n      max-age=31536000; \\\n      includeSubDomains; \\\n      preload \\\n      \"\"\"\n\n# Content-Security-Policy to prevent XSS attacks.\n\nContent-Security-Policy = \"\"\" \\\n      default-src \\\n            * \\\n            ; \\\n\n      script-src \\\n            'self' \\\n            'unsafe-eval' \\\n            'unsafe-inline' \\\n            https://aleysian-prefect.cs29.force.com \\\n            https://c.la1-c1cs-ph2.salesforceliveagent.com \\\n            https://c.la1-c2-ia2.salesforceliveagent.com \\\n            https://cdn.lr-ingest.io \\\n            https://d.la1-c1cs-ph2.salesforceliveagent.com \\\n            https://d.la1-c2-ia2.salesforceliveagent.com \\\n            https://d.la1-c2-ph2.salesforceliveagent.com \\\n            https://d.la2-c1-ia5.salesforceliveagent.com \\\n            https://d.la3-c1cs-ia2.salesforceliveagent.com \n            https://d.la3-c1cs-ia5.salesforceliveagent.com \\\n            https://js.stripe.com \\\n            https://partial-prefect.cs1.force.com \\\n            https://prefect--aleysian.my.salesforce.com \\\n            https://prefect--partial.my.salesforce.com \\\n            https://prefect--partial.sandbox.my.salesforce.com \\\n            https://prefect--partial.sandbox.my.site.com \\\n            https://prefect.force.com \\\n            https://prefect.my.salesforce-site.com \\\n            https://prefect.my.salesforce.com \\\n            https://prefect.my.site.com \\\n            https://service.force.com \\\n            https://static.lightning.force.com \\\n            ; \\\n      \n      script-src-elem \\\n            'self' \\\n            'unsafe-eval' \\\n            'unsafe-inline' \\\n            https://aleysian-prefect.cs29.force.com \\\n            https://c.la1-c1cs-ph2.salesforceliveagent.com \\\n            https://c.la1-c2-ia2.salesforceliveagent.com \\\n            https://cdn.lr-ingest.io \\\n            https://d.la1-c1cs-ph2.salesforceliveagent.com \\\n            https://d.la1-c2-ia2.salesforceliveagent.com \\\n            https://d.la1-c2-ph2.salesforceliveagent.com \\\n            https://d.la2-c1-ia5.salesforceliveagent.com \\\n            https://d.la3-c1cs-ia2.salesforceliveagent.com \n            https://d.la3-c1cs-ia5.salesforceliveagent.com \\\n            https://js.stripe.com \\\n            https://partial-prefect.cs1.force.com \\\n            https://prefect--aleysian.my.salesforce.com \\\n            https://prefect--partial.my.salesforce.com \\\n            https://prefect--partial.sandbox.my.salesforce.com \\\n            https://prefect--partial.sandbox.my.site.com \\\n            https://prefect.force.com \\\n            https://prefect.my.salesforce-site.com \\\n            https://prefect.my.salesforce.com \\\n            https://prefect.my.site.com \\\n            https://service.force.com \\\n            https://static.lightning.force.com \\\n            ; \\\n\n      img-src \\\n            * \\\n            data: \\\n            ; \\\n\n      style-src \\\n            'self' \\\n            'unsafe-inline' \\\n            https://aleysian-prefect.cs29.force.com \\\n            https://c.la1-c1cs-ph2.salesforceliveagent.com \\\n            https://c.la1-c2-ia2.salesforceliveagent.com \\\n            https://cdn.lr-ingest.io \\\n            https://d.la1-c1cs-ph2.salesforceliveagent.com \\\n            https://d.la1-c2-ia2.salesforceliveagent.com \\\n            https://d.la1-c2-ph2.salesforceliveagent.com \\\n            https://d.la2-c1-ia5.salesforceliveagent.com \\\n            https://d.la3-c1cs-ia2.salesforceliveagent.com \n            https://d.la3-c1cs-ia5.salesforceliveagent.com \\\n            https://js.stripe.com \\\n            https://partial-prefect.cs1.force.com \\\n            https://prefect--aleysian.my.salesforce.com \\\n            https://prefect--partial.my.salesforce.com \\\n            https://prefect--partial.sandbox.my.salesforce.com \\\n            https://prefect--partial.sandbox.my.site.com \\\n            https://prefect.force.com \\\n            https://prefect.my.salesforce-site.com \\\n            https://prefect.my.salesforce.com \\\n            https://prefect.my.site.com \\\n            https://service.force.com \\\n            https://static.lightning.force.com \\\n            ; \\\n      \n      style-src-elem \\\n            'self' \\\n            'unsafe-inline' \\\n            https://aleysian-prefect.cs29.force.com \\\n            https://c.la1-c1cs-ph2.salesforceliveagent.com \\\n            https://c.la1-c2-ia2.salesforceliveagent.com \\\n            https://cdn.lr-ingest.io \\\n            https://d.la1-c1cs-ph2.salesforceliveagent.com \\\n            https://d.la1-c2-ia2.salesforceliveagent.com \\\n            https://d.la1-c2-ph2.salesforceliveagent.com \\\n            https://d.la2-c1-ia5.salesforceliveagent.com \\\n            https://d.la3-c1cs-ia2.salesforceliveagent.com \n            https://d.la3-c1cs-ia5.salesforceliveagent.com \\\n            https://js.stripe.com \\\n            https://partial-prefect.cs1.force.com \\\n            https://prefect--aleysian.my.salesforce.com \\\n            https://prefect--partial.my.salesforce.com \\\n            https://prefect--partial.sandbox.my.salesforce.com \\\n            https://prefect--partial.sandbox.my.site.com \\\n            https://prefect.force.com \\\n            https://prefect.my.salesforce-site.com \\\n            https://prefect.my.salesforce.com \\\n            https://prefect.my.site.com \\\n            https://service.force.com \\\n            https://static.lightning.force.com \\\n            ; \\\n\n      font-src \\\n            data: \\\n            'self' \\\n            ; \\\n\n      frame-ancestors \\\n            'self' \\\n            ; \\\n      \n      frame-src \\\n            'self' \\\n            https://*.okta.com \\\n            https://*.prefect.io \\\n            https://js.stripe.com \\\n            https://prefect--partial.my.salesforce.com \\\n            https://prefect--partial.sandbox.my.salesforce.com \\\n            https://prefect.auth0.com \\\n            https://prefect.my.salesforce.com \\\n            https://service.force.com \\\n            ; \\\n\n      child-src \\\n            data: \\\n            blob: \\\n            ; \\\n\n      worker-src \\\n            'self' \\\n            data: \\\n            blob: \\\n            ; \\\n      \"\"\"\n\n# Referrer-Policy controls the Referer header in requests.\n#\n# same-origin allows analytics tools to understand user journeys.\nReferrer-Policy = \"same-origin\"\n\n# X-Permitted-Cross-Domain-Policies controls whether this site can be\n# embedded into Flash applications or PDF documents.\nX-Permitted-Cross-Domain-Policies = \"none\"\n\n# Permissions-Policy controls the features that the site can request.\n#\n# https://developer.chrome.com/en/docs/privacy-sandbox/permissions-policy/\n# https://github.com/w3c/webappsec-permissions-policy/blob/main/features.md\n#\n# payment\n#   https://js.stripe.com - supports PaymentRequest\nPermissions-Policy = \"\"\"\\\n      accelerometer=(), \\\n      ambient-light-sensor=(), \\\n      autoplay=(), \\\n      battery=(), \\\n      camera=(), \\\n      cross-origin-isolated=(), \\\n      display-capture=(), \\\n      document-domain=(), \\\n      encrypted-media=(), \\\n      execution-while-not-rendered=(), \\\n      execution-while-out-of-viewport=(), \\\n      fullscreen=(), \\\n      geolocation=(), \\\n      gyroscope=(), \\\n      hid=(), \\\n      idle-detection=(), \\\n      magnetometer=(), \\\n      microphone=(), \\\n      midi=(), \\\n      navigation-override=(), \\\n      payment=(self \"https://js.stripe.com\"), \\\n      picture-in-picture=(), \\\n      publickey-credentials-get=(), \\\n      screen-wake-lock=(), \\\n      serial=(), \\\n      sync-xhr=(), \\\n      usb=(), \\\n      web-share=(), \\\n      xr-spatial-tracking=() \\\n      \"\"\"\n"
  },
  {
    "path": "nginx.conf",
    "content": "server {\n  # We'll want to make this dynamic at some point \n  listen 8080;\n\n  root /var/www;\n  index index.html;\n  \n  location / {\n    try_files $uri /index.html;\n  }\n}"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"prefect-ui\",\n  \"version\": \"0.12.4\",\n  \"private\": true,\n  \"scripts\": {\n    \"serve\": \"node file-downloader.js && export VUE_APP_RELEASE_TIMESTAMP=$(date -u +'%Y-%m-%dT%H:%M:%SZ') && vue-cli-service serve --port 8080\",\n    \"build\": \"node file-downloader.js && export VUE_APP_RELEASE_TIMESTAMP=$(date -u +'%Y-%m-%dT%H:%M:%SZ') && vue-cli-service build\",\n    \"lint\": \"vue-cli-service lint\",\n    \"lint:ci\": \"vue-cli-service lint --no-fix\",\n    \"preinstall\": \"npx npm-force-resolutions\",\n    \"test:e2e\": \"vue-cli-service test:e2e\",\n    \"test:integration\": \"vue-cli-service test:e2e --headless --mode development\",\n    \"test:snapshots\": \"vue-cli-service test:unit -u\",\n    \"test:unit\": \"vue-cli-service test:unit\",\n    \"test:coverage\": \"vue-cli-service test:unit --coverage\",\n    \"changelog\": \"auto-changelog --commit-limit 0 --template changelog-template.hbs --tag-pattern [0-9]{4}-[0-9]{2}-[0-9]{2}\"\n  },\n  \"dependencies\": {\n    \"@auth0/auth0-spa-js\": \"^1.14.0\",\n    \"@okta/okta-auth-js\": \"^5.2.2\",\n    \"apollo-link-batch-http\": \"^1.2.14\",\n    \"caniuse-lite\": \"^1.0.30001390\",\n    \"codemirror\": \"^5.60.0\",\n    \"cronstrue\": \"^1.110.0\",\n    \"d3\": \"^6.6.2\",\n    \"d3-dag\": \"0.3.5\",\n    \"d3-regression\": \"^1.3.8\",\n    \"d3-zoom\": \"^2.0.0\",\n    \"graphiql\": \"^1.4.7\",\n    \"graphql\": \"^15.5.0\",\n    \"highlight.js\": \"^10.7.2\",\n    \"js-beautify\": \"^1.13.5\",\n    \"jwt-decode\": \"^3.1.2\",\n    \"lodash\": \"^4.17.21\",\n    \"logrocket\": \"^1.0.14\",\n    \"logrocket-vuex\": \"0.0.3\",\n    \"moment\": \"^2.29.1\",\n    \"moment-duration-format\": \">=2.3.2\",\n    \"moment-timezone\": \"^0.5.37\",\n    \"nth-check\": \"2.0.1\",\n    \"react\": \"^17.0.2\",\n    \"react-dom\": \"^17.0.2\",\n    \"remark\": \"^13.0.0\",\n    \"remark-autolink-headings\": \"^6.0.1\",\n    \"remark-breaks\": \"^2.0.2\",\n    \"remark-gfm\": \"^1.0.0\",\n    \"remark-html\": \"^13.0.2\",\n    \"remark-slug\": \"^6.0.0\",\n    \"velocity-animate\": \">=1.5.2\",\n    \"vue\": \"^2.6.12\",\n    \"vue-apollo\": \"^3.0.7\",\n    \"vue-codemirror\": \">=4.0.6\",\n    \"vue-meta\": \"^2.4.0\",\n    \"vue-router\": \"^3.5.1\",\n    \"vue-router-multiguard\": \">=1.0.3\",\n    \"vue-scrollto\": \"^2.20.0\",\n    \"vuetify\": \"^2.4.8\",\n    \"vuex\": \"^3.6.2\",\n    \"yaml\": \"2.0.0-5\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.13.14\",\n    \"@babel/plugin-proposal-optional-chaining\": \"^7.13.12\",\n    \"@babel/plugin-transform-runtime\": \"^7.13.10\",\n    \"@babel/runtime\": \"^7.13.10\",\n    \"@vue/cli-plugin-babel\": \"4.5.14\",\n    \"@vue/cli-plugin-eslint\": \"4.5.14\",\n    \"@vue/cli-plugin-unit-jest\": \"4.5.14\",\n    \"@vue/cli-service\": \"4.5.14\",\n    \"@vue/eslint-config-prettier\": \">=6.0.0\",\n    \"@vue/test-utils\": \"^1.1.3\",\n    \"auto-changelog\": \"^2.3.0\",\n    \"autoprefixer\": \"^9.8.6\",\n    \"babel-eslint\": \">=10.0.3\",\n    \"babel-jest\": \"^26.6.3\",\n    \"babel-polyfill\": \"^6.26.0\",\n    \"eslint\": \"^7.23.0\",\n    \"eslint-plugin-prettier\": \"^3.3.1\",\n    \"eslint-plugin-vue\": \"^7.8.0\",\n    \"eslint-plugin-vuetify\": \"^1.0.0-beta.8\",\n    \"graphql-tag\": \">=2.10.2\",\n    \"html-loader\": \"^1.3.2\",\n    \"ignore-loader\": \">=0.1.2\",\n    \"jest-canvas-mock\": \"^2.3.1\",\n    \"jest-fetch-mock\": \">=3.0.1\",\n    \"jest-localstorage-mock\": \"^2.4.8\",\n    \"node-sass\": \"^7.0.0\",\n    \"postcss-scss\": \"^3.0.5\",\n    \"sass\": \"^1.32.8\",\n    \"sass-loader\": \"^10.1.1\",\n    \"sinon\": \"^9.2.4\",\n    \"start-server-and-test\": \"^1.12.1\",\n    \"style-loader\": \"^2.0.0\",\n    \"stylelint\": \"^13.12.0\",\n    \"stylelint-a11y\": \">=1.2.1\",\n    \"stylelint-config-recommended\": \"^4.0.0\",\n    \"stylelint-config-sass-guidelines\": \"^7.1.0\",\n    \"stylelint-order\": \">=4.1.0\",\n    \"stylelint-scss\": \"^3.19.0\",\n    \"vue-cli-plugin-apollo\": \"^0.22.2\",\n    \"vue-cli-plugin-vuetify\": \"^2.3.1\",\n    \"vue-cli-plugin-webpack-bundle-analyzer\": \"^2.0.0\",\n    \"vue-template-compiler\": \"^2.6.12\",\n    \"vuetify-loader\": \"^1.7.2\",\n    \"worker-plugin\": \"^5.0.0\",\n    \"workerize-loader\": \">=1.2.1\"\n  },\n  \"peerDependencies\": {\n    \"postcss\": \"^8.0.0\"\n  },\n  \"resolutions\": {\n    \"node-fetch\": \"2.6.7\",\n    \"ejs\": \"3.1.7\"\n  }\n}\n"
  },
  {
    "path": "postcss.config.js",
    "content": "module.exports = {\n  parser: 'postcss-scss',\n  syntax: 'postcss-scss',\n  plugins: {\n    autoprefixer: {}\n  }\n}\n"
  },
  {
    "path": "public/_redirects",
    "content": "/*    /index.html   200\n"
  },
  {
    "path": "public/browserconfig.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<browserconfig>\n    <msapplication>\n        <tile>\n            <square150x150logo src=\"/mstile-150x150.png\"/>\n            <TileColor>#2d89ef</TileColor>\n        </tile>\n    </msapplication>\n</browserconfig>\n"
  },
  {
    "path": "public/fonts/font-awesome/LICENSE.txt",
    "content": "Font Awesome Pro License\n------------------------\n\nFont Awesome Pro is commercial software that requires a paid license. Full\nFont Awesome Pro license: https://fontawesome.com/license.\n\n# Commercial License\nThe Font Awesome Pro commercial license allows you to pay for FA Pro once, own\nit, and use it just about everywhere you'd like.\n\n# Attribution\nAttribution is not required by the Font Awesome Pro commercial license.\n\n# Brand Icons\nAll brand icons are trademarks of their respective owners. The use of these\ntrademarks does not indicate endorsement of the trademark holder by Font\nAwesome, nor vice versa. **Please do not use brand logos for any purpose except\nto represent the company, product, or service to which they refer.**\n"
  },
  {
    "path": "public/fonts/font-awesome/README.md",
    "content": "# Font Awesome 5.15.4\n\nThanks for downloading Font Awesome! We're so excited you're here.\n\nOur documentation is available online. Just head here:\n\nhttps://fontawesome.com\n"
  },
  {
    "path": "public/fonts/font-awesome/css/all.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n.fa,\n.fas,\n.far,\n.fal,\n.fad,\n.fab {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  text-rendering: auto;\n  line-height: 1; }\n\n.fa-lg {\n  font-size: 1.33333em;\n  line-height: 0.75em;\n  vertical-align: -.0667em; }\n\n.fa-xs {\n  font-size: .75em; }\n\n.fa-sm {\n  font-size: .875em; }\n\n.fa-1x {\n  font-size: 1em; }\n\n.fa-2x {\n  font-size: 2em; }\n\n.fa-3x {\n  font-size: 3em; }\n\n.fa-4x {\n  font-size: 4em; }\n\n.fa-5x {\n  font-size: 5em; }\n\n.fa-6x {\n  font-size: 6em; }\n\n.fa-7x {\n  font-size: 7em; }\n\n.fa-8x {\n  font-size: 8em; }\n\n.fa-9x {\n  font-size: 9em; }\n\n.fa-10x {\n  font-size: 10em; }\n\n.fa-fw {\n  text-align: center;\n  width: 1.25em; }\n\n.fa-ul {\n  list-style-type: none;\n  margin-left: 2.5em;\n  padding-left: 0; }\n  .fa-ul > li {\n    position: relative; }\n\n.fa-li {\n  left: -2em;\n  position: absolute;\n  text-align: center;\n  width: 2em;\n  line-height: inherit; }\n\n.fa-border {\n  border: solid 0.08em #eee;\n  border-radius: .1em;\n  padding: .2em .25em .15em; }\n\n.fa-pull-left {\n  float: left; }\n\n.fa-pull-right {\n  float: right; }\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n  margin-right: .3em; }\n\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n  margin-left: .3em; }\n\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear; }\n\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8); }\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n.fa-rotate-90 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n  -webkit-transform: rotate(90deg);\n          transform: rotate(90deg); }\n\n.fa-rotate-180 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n  -webkit-transform: rotate(180deg);\n          transform: rotate(180deg); }\n\n.fa-rotate-270 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n  -webkit-transform: rotate(270deg);\n          transform: rotate(270deg); }\n\n.fa-flip-horizontal {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n  -webkit-transform: scale(-1, 1);\n          transform: scale(-1, 1); }\n\n.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(1, -1);\n          transform: scale(1, -1); }\n\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(-1, -1);\n          transform: scale(-1, -1); }\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical,\n:root .fa-flip-both {\n  -webkit-filter: none;\n          filter: none; }\n\n.fa-stack {\n  display: inline-block;\n  height: 2em;\n  line-height: 2em;\n  position: relative;\n  vertical-align: middle;\n  width: 2.5em; }\n\n.fa-stack-1x,\n.fa-stack-2x {\n  left: 0;\n  position: absolute;\n  text-align: center;\n  width: 100%; }\n\n.fa-stack-1x {\n  line-height: inherit; }\n\n.fa-stack-2x {\n  font-size: 2em; }\n\n.fa-inverse {\n  color: #fff; }\n\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\nreaders do not read off random characters that represent icons */\n.fa-abacus:before {\n  content: \"\\f640\"; }\n\n.fa-alarm-exclamation:before {\n  content: \"\\f843\"; }\n\n.fa-align-left:before {\n  content: \"\\f036\"; }\n\n.fa-align-slash:before {\n  content: \"\\f846\"; }\n\n.fa-atom-alt:before {\n  content: \"\\f5d3\"; }\n\n.fa-aws:before {\n  content: \"\\f375\"; }\n\n.fa-badge-check:before {\n  content: \"\\f336\"; }\n\n.fa-bell:before {\n  content: \"\\f0f3\"; }\n\n.fa-book-dead:before {\n  content: \"\\f6b7\"; }\n\n.fa-books:before {\n  content: \"\\f5db\"; }\n\n.fa-brackets-curly:before {\n  content: \"\\f7ea\"; }\n\n.fa-cc-amazon-pay:before {\n  content: \"\\f42d\"; }\n\n.fa-cc-amex:before {\n  content: \"\\f1f3\"; }\n\n.fa-cc-apple-pay:before {\n  content: \"\\f416\"; }\n\n.fa-cc-diners-club:before {\n  content: \"\\f24c\"; }\n\n.fa-cc-discover:before {\n  content: \"\\f1f2\"; }\n\n.fa-cc-jcb:before {\n  content: \"\\f24b\"; }\n\n.fa-cc-mastercard:before {\n  content: \"\\f1f1\"; }\n\n.fa-cc-paypal:before {\n  content: \"\\f1f4\"; }\n\n.fa-cc-stripe:before {\n  content: \"\\f1f5\"; }\n\n.fa-cc-visa:before {\n  content: \"\\f1f0\"; }\n\n.fa-chart-network:before {\n  content: \"\\f78a\"; }\n\n.fa-chart-scatter:before {\n  content: \"\\f7ee\"; }\n\n.fa-check:before {\n  content: \"\\f00c\"; }\n\n.fa-check-circle:before {\n  content: \"\\f058\"; }\n\n.fa-circle:before {\n  content: \"\\f111\"; }\n\n.fa-cloud:before {\n  content: \"\\f0c2\"; }\n\n.fa-clouds:before {\n  content: \"\\f744\"; }\n\n.fa-cogs:before {\n  content: \"\\f085\"; }\n\n.fa-comment-dots:before {\n  content: \"\\f4ad\"; }\n\n.fa-concierge-bell:before {\n  content: \"\\f562\"; }\n\n.fa-credit-card:before {\n  content: \"\\f09d\"; }\n\n.fa-desktop:before {\n  content: \"\\f108\"; }\n\n.fa-discourse:before {\n  content: \"\\f393\"; }\n\n.fa-docker:before {\n  content: \"\\f395\"; }\n\n.fa-dot-circle:before {\n  content: \"\\f192\"; }\n\n.fa-envelope:before {\n  content: \"\\f0e0\"; }\n\n.fa-exchange-alt:before {\n  content: \"\\f362\"; }\n\n.fa-eye:before {\n  content: \"\\f06e\"; }\n\n.fa-file-alt:before {\n  content: \"\\f15c\"; }\n\n.fa-file-code:before {\n  content: \"\\f1c9\"; }\n\n.fa-fingerprint:before {\n  content: \"\\f577\"; }\n\n.fa-github:before {\n  content: \"\\f09b\"; }\n\n.fa-globe:before {\n  content: \"\\f0ac\"; }\n\n.fa-globe-africa:before {\n  content: \"\\f57c\"; }\n\n.fa-globe-americas:before {\n  content: \"\\f57d\"; }\n\n.fa-globe-asia:before {\n  content: \"\\f57e\"; }\n\n.fa-globe-europe:before {\n  content: \"\\f7a2\"; }\n\n.fa-graduation-cap:before {\n  content: \"\\f19d\"; }\n\n.fa-history:before {\n  content: \"\\f1da\"; }\n\n.fa-home:before {\n  content: \"\\f015\"; }\n\n.fa-info:before {\n  content: \"\\f129\"; }\n\n.fa-info-circle:before {\n  content: \"\\f05a\"; }\n\n.fa-instagram:before {\n  content: \"\\f16d\"; }\n\n.fa-key:before {\n  content: \"\\f084\"; }\n\n.fa-key-skeleton:before {\n  content: \"\\f6f3\"; }\n\n.fa-laptop:before {\n  content: \"\\f109\"; }\n\n.fa-laptop-code:before {\n  content: \"\\f5fc\"; }\n\n.fa-laptop-house:before {\n  content: \"\\e066\"; }\n\n.fa-life-ring:before {\n  content: \"\\f1cd\"; }\n\n.fa-lightbulb:before {\n  content: \"\\f0eb\"; }\n\n.fa-list-alt:before {\n  content: \"\\f022\"; }\n\n.fa-list-ul:before {\n  content: \"\\f0ca\"; }\n\n.fa-lock-alt:before {\n  content: \"\\f30d\"; }\n\n.fa-map-marker-alt:before {\n  content: \"\\f3c5\"; }\n\n.fa-microsoft:before {\n  content: \"\\f3ca\"; }\n\n.fa-moon-stars:before {\n  content: \"\\f755\"; }\n\n.fa-network-wired:before {\n  content: \"\\f6ff\"; }\n\n.fa-planet-ringed:before {\n  content: \"\\e020\"; }\n\n.fa-plus:before {\n  content: \"\\f067\"; }\n\n.fa-question-circle:before {\n  content: \"\\f059\"; }\n\n.fa-quote-left:before {\n  content: \"\\f10d\"; }\n\n.fa-random:before {\n  content: \"\\f074\"; }\n\n.fa-rev:before {\n  content: \"\\f5b2\"; }\n\n.fa-robot:before {\n  content: \"\\f544\"; }\n\n.fa-rocket:before {\n  content: \"\\f135\"; }\n\n.fa-save:before {\n  content: \"\\f0c7\"; }\n\n.fa-search:before {\n  content: \"\\f002\"; }\n\n.fa-server:before {\n  content: \"\\f233\"; }\n\n.fa-sign-out:before {\n  content: \"\\f08b\"; }\n\n.fa-siren-on:before {\n  content: \"\\e02e\"; }\n\n.fa-slack:before {\n  content: \"\\f198\"; }\n\n.fa-slash:before {\n  content: \"\\f715\"; }\n\n.fa-smile:before {\n  content: \"\\f118\"; }\n\n.fa-snowman:before {\n  content: \"\\f7d0\"; }\n\n.fa-spinner-third:before {\n  content: \"\\f3f4\"; }\n\n.fa-square-full:before {\n  content: \"\\f45c\"; }\n\n.fa-sun:before {\n  content: \"\\f185\"; }\n\n.fa-tasks:before {\n  content: \"\\f0ae\"; }\n\n.fa-times:before {\n  content: \"\\f00d\"; }\n\n.fa-times-circle:before {\n  content: \"\\f057\"; }\n\n.fa-twitter:before {\n  content: \"\\f099\"; }\n\n.fa-undo:before {\n  content: \"\\f0e2\"; }\n\n.fa-undo-alt:before {\n  content: \"\\f2ea\"; }\n\n.fa-university:before {\n  content: \"\\f19c\"; }\n\n.fa-user:before {\n  content: \"\\f007\"; }\n\n.fa-user-friends:before {\n  content: \"\\f500\"; }\n\n.fa-user-hard-hat:before {\n  content: \"\\f82c\"; }\n\n.fa-user-shield:before {\n  content: \"\\f505\"; }\n\n.fa-users:before {\n  content: \"\\f0c0\"; }\n\n.sr-only {\n  border: 0;\n  clip: rect(0, 0, 0, 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px; }\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n  clip: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  position: static;\n  width: auto; }\n@font-face {\n  font-family: 'Font Awesome 5 Brands';\n  font-style: normal;\n  font-weight: 400;\n  font-display: block;\n  src: url(\"../webfonts/fa-brands-400.eot\");\n  src: url(\"../webfonts/fa-brands-400.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-brands-400.woff2\") format(\"woff2\"), url(\"../webfonts/fa-brands-400.woff\") format(\"woff\"), url(\"../webfonts/fa-brands-400.ttf\") format(\"truetype\"), url(\"../webfonts/fa-brands-400.svg#fontawesome\") format(\"svg\"); }\n\n.fab {\n  font-family: 'Font Awesome 5 Brands';\n  font-weight: 400; }\n@font-face {\n  font-family: 'Font Awesome 5 Duotone';\n  font-style: normal;\n  font-weight: 900;\n  font-display: block;\n  src: url(\"../webfonts/fa-duotone-900.eot\");\n  src: url(\"../webfonts/fa-duotone-900.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-duotone-900.woff2\") format(\"woff2\"), url(\"../webfonts/fa-duotone-900.woff\") format(\"woff\"), url(\"../webfonts/fa-duotone-900.ttf\") format(\"truetype\"), url(\"../webfonts/fa-duotone-900.svg#fontawesome\") format(\"svg\"); }\n\n.fad {\n  position: relative;\n  font-family: 'Font Awesome 5 Duotone';\n  font-weight: 900; }\n\n.fad:before {\n  position: absolute;\n  color: var(--fa-primary-color, inherit);\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.fad:after {\n  color: var(--fa-secondary-color, inherit);\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.fa-swap-opacity .fad:before,\n.fad.fa-swap-opacity:before {\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.fa-swap-opacity .fad:after,\n.fad.fa-swap-opacity:after {\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.fad.fa-inverse {\n  color: #fff; }\n\n.fad.fa-stack-1x, .fad.fa-stack-2x {\n  position: absolute; }\n\n.fad.fa-stack-1x:before,\n.fad.fa-stack-2x:before,\n.fad.fa-fw:before {\n  left: 50%;\n  -webkit-transform: translateX(-50%);\n          transform: translateX(-50%); }\n\n.fad.fa-abacus:after {\n  content: \"\\10f640\"; }\n\n.fad.fa-align-slash:after {\n  content: \"\\10f846\"; }\n\n.fad.fa-atom-alt:after {\n  content: \"\\10f5d3\"; }\n\n.fad.fa-badge-check:after {\n  content: \"\\10f336\"; }\n\n.fad.fa-bell:after {\n  content: \"\\10f0f3\"; }\n\n.fad.fa-books:after {\n  content: \"\\10f5db\"; }\n\n.fad.fa-brackets-curly:after {\n  content: \"\\10f7ea\"; }\n\n.fad.fa-chart-network:after {\n  content: \"\\10f78a\"; }\n\n.fad.fa-chart-scatter:after {\n  content: \"\\10f7ee\"; }\n\n.fad.fa-check:after {\n  content: \"\\10f00c\"; }\n\n.fad.fa-circle:after {\n  content: \"\\10f111\"; }\n\n.fad.fa-clouds:after {\n  content: \"\\10f744\"; }\n\n.fad.fa-cogs:after {\n  content: \"\\10f085\"; }\n\n.fad.fa-comment-dots:after {\n  content: \"\\10f4ad\"; }\n\n.fad.fa-concierge-bell:after {\n  content: \"\\10f562\"; }\n\n.fad.fa-dot-circle:after {\n  content: \"\\10f192\"; }\n\n.fad.fa-envelope:after {\n  content: \"\\10f0e0\"; }\n\n.fad.fa-exchange-alt:after {\n  content: \"\\10f362\"; }\n\n.fad.fa-file-alt:after {\n  content: \"\\10f15c\"; }\n\n.fad.fa-file-code:after {\n  content: \"\\10f1c9\"; }\n\n.fad.fa-globe:after {\n  content: \"\\10f0ac\"; }\n\n.fad.fa-globe-africa:after {\n  content: \"\\10f57c\"; }\n\n.fad.fa-globe-americas:after {\n  content: \"\\10f57d\"; }\n\n.fad.fa-globe-asia:after {\n  content: \"\\10f57e\"; }\n\n.fad.fa-globe-europe:after {\n  content: \"\\10f7a2\"; }\n\n.fad.fa-graduation-cap:after {\n  content: \"\\10f19d\"; }\n\n.fad.fa-history:after {\n  content: \"\\10f1da\"; }\n\n.fad.fa-key:after {\n  content: \"\\10f084\"; }\n\n.fad.fa-key-skeleton:after {\n  content: \"\\10f6f3\"; }\n\n.fad.fa-laptop:after {\n  content: \"\\10f109\"; }\n\n.fad.fa-laptop-code:after {\n  content: \"\\10f5fc\"; }\n\n.fad.fa-laptop-house:after {\n  content: \"\\10e066\"; }\n\n.fad.fa-life-ring:after {\n  content: \"\\10f1cd\"; }\n\n.fad.fa-lightbulb:after {\n  content: \"\\10f0eb\"; }\n\n.fad.fa-list-alt:after {\n  content: \"\\10f022\"; }\n\n.fad.fa-list-ul:after {\n  content: \"\\10f0ca\"; }\n\n.fad.fa-lock-alt:after {\n  content: \"\\10f30d\"; }\n\n.fad.fa-map-marker-alt:after {\n  content: \"\\10f3c5\"; }\n\n.fad.fa-moon-stars:after {\n  content: \"\\10f755\"; }\n\n.fad.fa-network-wired:after {\n  content: \"\\10f6ff\"; }\n\n.fad.fa-planet-ringed:after {\n  content: \"\\10e020\"; }\n\n.fad.fa-question-circle:after {\n  content: \"\\10f059\"; }\n\n.fad.fa-quote-left:after {\n  content: \"\\10f10d\"; }\n\n.fad.fa-random:after {\n  content: \"\\10f074\"; }\n\n.fad.fa-rocket:after {\n  content: \"\\10f135\"; }\n\n.fad.fa-search:after {\n  content: \"\\10f002\"; }\n\n.fad.fa-server:after {\n  content: \"\\10f233\"; }\n\n.fad.fa-sign-out:after {\n  content: \"\\10f08b\"; }\n\n.fad.fa-siren-on:after {\n  content: \"\\10e02e\"; }\n\n.fad.fa-smile:after {\n  content: \"\\10f118\"; }\n\n.fad.fa-snowman:after {\n  content: \"\\10f7d0\"; }\n\n.fad.fa-sun:after {\n  content: \"\\10f185\"; }\n\n.fad.fa-tasks:after {\n  content: \"\\10f0ae\"; }\n\n.fad.fa-university:after {\n  content: \"\\10f19c\"; }\n\n.fad.fa-user:after {\n  content: \"\\10f007\"; }\n\n.fad.fa-user-hard-hat:after {\n  content: \"\\10f82c\"; }\n\n.fad.fa-user-shield:after {\n  content: \"\\10f505\"; }\n\n.fad.fa-users:after {\n  content: \"\\10f0c0\"; }\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 400;\n  font-display: block;\n  src: url(\"../webfonts/fa-regular-400.eot\");\n  src: url(\"../webfonts/fa-regular-400.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-regular-400.woff2\") format(\"woff2\"), url(\"../webfonts/fa-regular-400.woff\") format(\"woff\"), url(\"../webfonts/fa-regular-400.ttf\") format(\"truetype\"), url(\"../webfonts/fa-regular-400.svg#fontawesome\") format(\"svg\"); }\n\n.far {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 400; }\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 900;\n  font-display: block;\n  src: url(\"../webfonts/fa-solid-900.eot\");\n  src: url(\"../webfonts/fa-solid-900.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-solid-900.woff2\") format(\"woff2\"), url(\"../webfonts/fa-solid-900.woff\") format(\"woff\"), url(\"../webfonts/fa-solid-900.ttf\") format(\"truetype\"), url(\"../webfonts/fa-solid-900.svg#fontawesome\") format(\"svg\"); }\n\n.fa,\n.fas {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 900; }\n"
  },
  {
    "path": "public/fonts/font-awesome/css/brands.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n@font-face {\n  font-family: 'Font Awesome 5 Brands';\n  font-style: normal;\n  font-weight: 400;\n  font-display: block;\n  src: url(\"../webfonts/fa-brands-400.eot\");\n  src: url(\"../webfonts/fa-brands-400.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-brands-400.woff2\") format(\"woff2\"), url(\"../webfonts/fa-brands-400.woff\") format(\"woff\"), url(\"../webfonts/fa-brands-400.ttf\") format(\"truetype\"), url(\"../webfonts/fa-brands-400.svg#fontawesome\") format(\"svg\"); }\n\n.fab {\n  font-family: 'Font Awesome 5 Brands';\n  font-weight: 400; }\n"
  },
  {
    "path": "public/fonts/font-awesome/css/duotone.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n@font-face {\n  font-family: 'Font Awesome 5 Duotone';\n  font-style: normal;\n  font-weight: 900;\n  font-display: block;\n  src: url(\"../webfonts/fa-duotone-900.eot\");\n  src: url(\"../webfonts/fa-duotone-900.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-duotone-900.woff2\") format(\"woff2\"), url(\"../webfonts/fa-duotone-900.woff\") format(\"woff\"), url(\"../webfonts/fa-duotone-900.ttf\") format(\"truetype\"), url(\"../webfonts/fa-duotone-900.svg#fontawesome\") format(\"svg\"); }\n\n.fad {\n  position: relative;\n  font-family: 'Font Awesome 5 Duotone';\n  font-weight: 900; }\n\n.fad:before {\n  position: absolute;\n  color: var(--fa-primary-color, inherit);\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.fad:after {\n  color: var(--fa-secondary-color, inherit);\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.fa-swap-opacity .fad:before,\n.fad.fa-swap-opacity:before {\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.fa-swap-opacity .fad:after,\n.fad.fa-swap-opacity:after {\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.fad.fa-inverse {\n  color: #fff; }\n\n.fad.fa-stack-1x, .fad.fa-stack-2x {\n  position: absolute; }\n\n.fad.fa-stack-1x:before,\n.fad.fa-stack-2x:before,\n.fad.fa-fw:before {\n  left: 50%;\n  -webkit-transform: translateX(-50%);\n          transform: translateX(-50%); }\n\n.fad.fa-abacus:after {\n  content: \"\\10f640\"; }\n\n.fad.fa-align-slash:after {\n  content: \"\\10f846\"; }\n\n.fad.fa-atom-alt:after {\n  content: \"\\10f5d3\"; }\n\n.fad.fa-badge-check:after {\n  content: \"\\10f336\"; }\n\n.fad.fa-bell:after {\n  content: \"\\10f0f3\"; }\n\n.fad.fa-books:after {\n  content: \"\\10f5db\"; }\n\n.fad.fa-brackets-curly:after {\n  content: \"\\10f7ea\"; }\n\n.fad.fa-chart-network:after {\n  content: \"\\10f78a\"; }\n\n.fad.fa-chart-scatter:after {\n  content: \"\\10f7ee\"; }\n\n.fad.fa-check:after {\n  content: \"\\10f00c\"; }\n\n.fad.fa-circle:after {\n  content: \"\\10f111\"; }\n\n.fad.fa-clouds:after {\n  content: \"\\10f744\"; }\n\n.fad.fa-cogs:after {\n  content: \"\\10f085\"; }\n\n.fad.fa-comment-dots:after {\n  content: \"\\10f4ad\"; }\n\n.fad.fa-concierge-bell:after {\n  content: \"\\10f562\"; }\n\n.fad.fa-dot-circle:after {\n  content: \"\\10f192\"; }\n\n.fad.fa-envelope:after {\n  content: \"\\10f0e0\"; }\n\n.fad.fa-exchange-alt:after {\n  content: \"\\10f362\"; }\n\n.fad.fa-file-alt:after {\n  content: \"\\10f15c\"; }\n\n.fad.fa-file-code:after {\n  content: \"\\10f1c9\"; }\n\n.fad.fa-globe:after {\n  content: \"\\10f0ac\"; }\n\n.fad.fa-globe-africa:after {\n  content: \"\\10f57c\"; }\n\n.fad.fa-globe-americas:after {\n  content: \"\\10f57d\"; }\n\n.fad.fa-globe-asia:after {\n  content: \"\\10f57e\"; }\n\n.fad.fa-globe-europe:after {\n  content: \"\\10f7a2\"; }\n\n.fad.fa-graduation-cap:after {\n  content: \"\\10f19d\"; }\n\n.fad.fa-history:after {\n  content: \"\\10f1da\"; }\n\n.fad.fa-key:after {\n  content: \"\\10f084\"; }\n\n.fad.fa-key-skeleton:after {\n  content: \"\\10f6f3\"; }\n\n.fad.fa-laptop:after {\n  content: \"\\10f109\"; }\n\n.fad.fa-laptop-code:after {\n  content: \"\\10f5fc\"; }\n\n.fad.fa-laptop-house:after {\n  content: \"\\10e066\"; }\n\n.fad.fa-life-ring:after {\n  content: \"\\10f1cd\"; }\n\n.fad.fa-lightbulb:after {\n  content: \"\\10f0eb\"; }\n\n.fad.fa-list-alt:after {\n  content: \"\\10f022\"; }\n\n.fad.fa-list-ul:after {\n  content: \"\\10f0ca\"; }\n\n.fad.fa-lock-alt:after {\n  content: \"\\10f30d\"; }\n\n.fad.fa-map-marker-alt:after {\n  content: \"\\10f3c5\"; }\n\n.fad.fa-moon-stars:after {\n  content: \"\\10f755\"; }\n\n.fad.fa-network-wired:after {\n  content: \"\\10f6ff\"; }\n\n.fad.fa-planet-ringed:after {\n  content: \"\\10e020\"; }\n\n.fad.fa-question-circle:after {\n  content: \"\\10f059\"; }\n\n.fad.fa-quote-left:after {\n  content: \"\\10f10d\"; }\n\n.fad.fa-random:after {\n  content: \"\\10f074\"; }\n\n.fad.fa-rocket:after {\n  content: \"\\10f135\"; }\n\n.fad.fa-search:after {\n  content: \"\\10f002\"; }\n\n.fad.fa-server:after {\n  content: \"\\10f233\"; }\n\n.fad.fa-sign-out:after {\n  content: \"\\10f08b\"; }\n\n.fad.fa-siren-on:after {\n  content: \"\\10e02e\"; }\n\n.fad.fa-smile:after {\n  content: \"\\10f118\"; }\n\n.fad.fa-snowman:after {\n  content: \"\\10f7d0\"; }\n\n.fad.fa-sun:after {\n  content: \"\\10f185\"; }\n\n.fad.fa-tasks:after {\n  content: \"\\10f0ae\"; }\n\n.fad.fa-university:after {\n  content: \"\\10f19c\"; }\n\n.fad.fa-user:after {\n  content: \"\\10f007\"; }\n\n.fad.fa-user-hard-hat:after {\n  content: \"\\10f82c\"; }\n\n.fad.fa-user-shield:after {\n  content: \"\\10f505\"; }\n\n.fad.fa-users:after {\n  content: \"\\10f0c0\"; }\n"
  },
  {
    "path": "public/fonts/font-awesome/css/fontawesome.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n.fa,\n.fas,\n.far,\n.fal,\n.fad,\n.fab {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  text-rendering: auto;\n  line-height: 1; }\n\n.fa-lg {\n  font-size: 1.33333em;\n  line-height: 0.75em;\n  vertical-align: -.0667em; }\n\n.fa-xs {\n  font-size: .75em; }\n\n.fa-sm {\n  font-size: .875em; }\n\n.fa-1x {\n  font-size: 1em; }\n\n.fa-2x {\n  font-size: 2em; }\n\n.fa-3x {\n  font-size: 3em; }\n\n.fa-4x {\n  font-size: 4em; }\n\n.fa-5x {\n  font-size: 5em; }\n\n.fa-6x {\n  font-size: 6em; }\n\n.fa-7x {\n  font-size: 7em; }\n\n.fa-8x {\n  font-size: 8em; }\n\n.fa-9x {\n  font-size: 9em; }\n\n.fa-10x {\n  font-size: 10em; }\n\n.fa-fw {\n  text-align: center;\n  width: 1.25em; }\n\n.fa-ul {\n  list-style-type: none;\n  margin-left: 2.5em;\n  padding-left: 0; }\n  .fa-ul > li {\n    position: relative; }\n\n.fa-li {\n  left: -2em;\n  position: absolute;\n  text-align: center;\n  width: 2em;\n  line-height: inherit; }\n\n.fa-border {\n  border: solid 0.08em #eee;\n  border-radius: .1em;\n  padding: .2em .25em .15em; }\n\n.fa-pull-left {\n  float: left; }\n\n.fa-pull-right {\n  float: right; }\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n  margin-right: .3em; }\n\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n  margin-left: .3em; }\n\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear; }\n\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8); }\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n.fa-rotate-90 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n  -webkit-transform: rotate(90deg);\n          transform: rotate(90deg); }\n\n.fa-rotate-180 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n  -webkit-transform: rotate(180deg);\n          transform: rotate(180deg); }\n\n.fa-rotate-270 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n  -webkit-transform: rotate(270deg);\n          transform: rotate(270deg); }\n\n.fa-flip-horizontal {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n  -webkit-transform: scale(-1, 1);\n          transform: scale(-1, 1); }\n\n.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(1, -1);\n          transform: scale(1, -1); }\n\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(-1, -1);\n          transform: scale(-1, -1); }\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical,\n:root .fa-flip-both {\n  -webkit-filter: none;\n          filter: none; }\n\n.fa-stack {\n  display: inline-block;\n  height: 2em;\n  line-height: 2em;\n  position: relative;\n  vertical-align: middle;\n  width: 2.5em; }\n\n.fa-stack-1x,\n.fa-stack-2x {\n  left: 0;\n  position: absolute;\n  text-align: center;\n  width: 100%; }\n\n.fa-stack-1x {\n  line-height: inherit; }\n\n.fa-stack-2x {\n  font-size: 2em; }\n\n.fa-inverse {\n  color: #fff; }\n\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\nreaders do not read off random characters that represent icons */\n.fa-abacus:before {\n  content: \"\\f640\"; }\n\n.fa-alarm-exclamation:before {\n  content: \"\\f843\"; }\n\n.fa-align-left:before {\n  content: \"\\f036\"; }\n\n.fa-align-slash:before {\n  content: \"\\f846\"; }\n\n.fa-atom-alt:before {\n  content: \"\\f5d3\"; }\n\n.fa-aws:before {\n  content: \"\\f375\"; }\n\n.fa-badge-check:before {\n  content: \"\\f336\"; }\n\n.fa-bell:before {\n  content: \"\\f0f3\"; }\n\n.fa-book-dead:before {\n  content: \"\\f6b7\"; }\n\n.fa-books:before {\n  content: \"\\f5db\"; }\n\n.fa-brackets-curly:before {\n  content: \"\\f7ea\"; }\n\n.fa-cc-amazon-pay:before {\n  content: \"\\f42d\"; }\n\n.fa-cc-amex:before {\n  content: \"\\f1f3\"; }\n\n.fa-cc-apple-pay:before {\n  content: \"\\f416\"; }\n\n.fa-cc-diners-club:before {\n  content: \"\\f24c\"; }\n\n.fa-cc-discover:before {\n  content: \"\\f1f2\"; }\n\n.fa-cc-jcb:before {\n  content: \"\\f24b\"; }\n\n.fa-cc-mastercard:before {\n  content: \"\\f1f1\"; }\n\n.fa-cc-paypal:before {\n  content: \"\\f1f4\"; }\n\n.fa-cc-stripe:before {\n  content: \"\\f1f5\"; }\n\n.fa-cc-visa:before {\n  content: \"\\f1f0\"; }\n\n.fa-chart-network:before {\n  content: \"\\f78a\"; }\n\n.fa-chart-scatter:before {\n  content: \"\\f7ee\"; }\n\n.fa-check:before {\n  content: \"\\f00c\"; }\n\n.fa-check-circle:before {\n  content: \"\\f058\"; }\n\n.fa-circle:before {\n  content: \"\\f111\"; }\n\n.fa-cloud:before {\n  content: \"\\f0c2\"; }\n\n.fa-clouds:before {\n  content: \"\\f744\"; }\n\n.fa-cogs:before {\n  content: \"\\f085\"; }\n\n.fa-comment-dots:before {\n  content: \"\\f4ad\"; }\n\n.fa-concierge-bell:before {\n  content: \"\\f562\"; }\n\n.fa-credit-card:before {\n  content: \"\\f09d\"; }\n\n.fa-desktop:before {\n  content: \"\\f108\"; }\n\n.fa-discourse:before {\n  content: \"\\f393\"; }\n\n.fa-docker:before {\n  content: \"\\f395\"; }\n\n.fa-dot-circle:before {\n  content: \"\\f192\"; }\n\n.fa-envelope:before {\n  content: \"\\f0e0\"; }\n\n.fa-exchange-alt:before {\n  content: \"\\f362\"; }\n\n.fa-eye:before {\n  content: \"\\f06e\"; }\n\n.fa-file-alt:before {\n  content: \"\\f15c\"; }\n\n.fa-file-code:before {\n  content: \"\\f1c9\"; }\n\n.fa-fingerprint:before {\n  content: \"\\f577\"; }\n\n.fa-github:before {\n  content: \"\\f09b\"; }\n\n.fa-globe:before {\n  content: \"\\f0ac\"; }\n\n.fa-globe-africa:before {\n  content: \"\\f57c\"; }\n\n.fa-globe-americas:before {\n  content: \"\\f57d\"; }\n\n.fa-globe-asia:before {\n  content: \"\\f57e\"; }\n\n.fa-globe-europe:before {\n  content: \"\\f7a2\"; }\n\n.fa-graduation-cap:before {\n  content: \"\\f19d\"; }\n\n.fa-history:before {\n  content: \"\\f1da\"; }\n\n.fa-home:before {\n  content: \"\\f015\"; }\n\n.fa-info:before {\n  content: \"\\f129\"; }\n\n.fa-info-circle:before {\n  content: \"\\f05a\"; }\n\n.fa-instagram:before {\n  content: \"\\f16d\"; }\n\n.fa-key:before {\n  content: \"\\f084\"; }\n\n.fa-key-skeleton:before {\n  content: \"\\f6f3\"; }\n\n.fa-laptop:before {\n  content: \"\\f109\"; }\n\n.fa-laptop-code:before {\n  content: \"\\f5fc\"; }\n\n.fa-laptop-house:before {\n  content: \"\\e066\"; }\n\n.fa-life-ring:before {\n  content: \"\\f1cd\"; }\n\n.fa-lightbulb:before {\n  content: \"\\f0eb\"; }\n\n.fa-list-alt:before {\n  content: \"\\f022\"; }\n\n.fa-list-ul:before {\n  content: \"\\f0ca\"; }\n\n.fa-lock-alt:before {\n  content: \"\\f30d\"; }\n\n.fa-map-marker-alt:before {\n  content: \"\\f3c5\"; }\n\n.fa-microsoft:before {\n  content: \"\\f3ca\"; }\n\n.fa-moon-stars:before {\n  content: \"\\f755\"; }\n\n.fa-network-wired:before {\n  content: \"\\f6ff\"; }\n\n.fa-planet-ringed:before {\n  content: \"\\e020\"; }\n\n.fa-plus:before {\n  content: \"\\f067\"; }\n\n.fa-question-circle:before {\n  content: \"\\f059\"; }\n\n.fa-quote-left:before {\n  content: \"\\f10d\"; }\n\n.fa-random:before {\n  content: \"\\f074\"; }\n\n.fa-rev:before {\n  content: \"\\f5b2\"; }\n\n.fa-robot:before {\n  content: \"\\f544\"; }\n\n.fa-rocket:before {\n  content: \"\\f135\"; }\n\n.fa-save:before {\n  content: \"\\f0c7\"; }\n\n.fa-search:before {\n  content: \"\\f002\"; }\n\n.fa-server:before {\n  content: \"\\f233\"; }\n\n.fa-sign-out:before {\n  content: \"\\f08b\"; }\n\n.fa-siren-on:before {\n  content: \"\\e02e\"; }\n\n.fa-slack:before {\n  content: \"\\f198\"; }\n\n.fa-slash:before {\n  content: \"\\f715\"; }\n\n.fa-smile:before {\n  content: \"\\f118\"; }\n\n.fa-snowman:before {\n  content: \"\\f7d0\"; }\n\n.fa-spinner-third:before {\n  content: \"\\f3f4\"; }\n\n.fa-square-full:before {\n  content: \"\\f45c\"; }\n\n.fa-sun:before {\n  content: \"\\f185\"; }\n\n.fa-tasks:before {\n  content: \"\\f0ae\"; }\n\n.fa-times:before {\n  content: \"\\f00d\"; }\n\n.fa-times-circle:before {\n  content: \"\\f057\"; }\n\n.fa-twitter:before {\n  content: \"\\f099\"; }\n\n.fa-undo:before {\n  content: \"\\f0e2\"; }\n\n.fa-undo-alt:before {\n  content: \"\\f2ea\"; }\n\n.fa-university:before {\n  content: \"\\f19c\"; }\n\n.fa-user:before {\n  content: \"\\f007\"; }\n\n.fa-user-friends:before {\n  content: \"\\f500\"; }\n\n.fa-user-hard-hat:before {\n  content: \"\\f82c\"; }\n\n.fa-user-shield:before {\n  content: \"\\f505\"; }\n\n.fa-users:before {\n  content: \"\\f0c0\"; }\n\n.sr-only {\n  border: 0;\n  clip: rect(0, 0, 0, 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px; }\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n  clip: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  position: static;\n  width: auto; }\n"
  },
  {
    "path": "public/fonts/font-awesome/css/regular.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 400;\n  font-display: block;\n  src: url(\"../webfonts/fa-regular-400.eot\");\n  src: url(\"../webfonts/fa-regular-400.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-regular-400.woff2\") format(\"woff2\"), url(\"../webfonts/fa-regular-400.woff\") format(\"woff\"), url(\"../webfonts/fa-regular-400.ttf\") format(\"truetype\"), url(\"../webfonts/fa-regular-400.svg#fontawesome\") format(\"svg\"); }\n\n.far {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 400; }\n"
  },
  {
    "path": "public/fonts/font-awesome/css/solid.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 900;\n  font-display: block;\n  src: url(\"../webfonts/fa-solid-900.eot\");\n  src: url(\"../webfonts/fa-solid-900.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-solid-900.woff2\") format(\"woff2\"), url(\"../webfonts/fa-solid-900.woff\") format(\"woff\"), url(\"../webfonts/fa-solid-900.ttf\") format(\"truetype\"), url(\"../webfonts/fa-solid-900.svg#fontawesome\") format(\"svg\"); }\n\n.fa,\n.fas {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 900; }\n"
  },
  {
    "path": "public/fonts/font-awesome/css/svg-with-js.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\nsvg:not(:root).svg-inline--fa {\n  overflow: visible; }\n\n.svg-inline--fa {\n  display: inline-block;\n  font-size: inherit;\n  height: 1em;\n  overflow: visible;\n  vertical-align: -.125em; }\n  .svg-inline--fa.fa-lg {\n    vertical-align: -.225em; }\n  .svg-inline--fa.fa-w-1 {\n    width: 0.0625em; }\n  .svg-inline--fa.fa-w-2 {\n    width: 0.125em; }\n  .svg-inline--fa.fa-w-3 {\n    width: 0.1875em; }\n  .svg-inline--fa.fa-w-4 {\n    width: 0.25em; }\n  .svg-inline--fa.fa-w-5 {\n    width: 0.3125em; }\n  .svg-inline--fa.fa-w-6 {\n    width: 0.375em; }\n  .svg-inline--fa.fa-w-7 {\n    width: 0.4375em; }\n  .svg-inline--fa.fa-w-8 {\n    width: 0.5em; }\n  .svg-inline--fa.fa-w-9 {\n    width: 0.5625em; }\n  .svg-inline--fa.fa-w-10 {\n    width: 0.625em; }\n  .svg-inline--fa.fa-w-11 {\n    width: 0.6875em; }\n  .svg-inline--fa.fa-w-12 {\n    width: 0.75em; }\n  .svg-inline--fa.fa-w-13 {\n    width: 0.8125em; }\n  .svg-inline--fa.fa-w-14 {\n    width: 0.875em; }\n  .svg-inline--fa.fa-w-15 {\n    width: 0.9375em; }\n  .svg-inline--fa.fa-w-16 {\n    width: 1em; }\n  .svg-inline--fa.fa-w-17 {\n    width: 1.0625em; }\n  .svg-inline--fa.fa-w-18 {\n    width: 1.125em; }\n  .svg-inline--fa.fa-w-19 {\n    width: 1.1875em; }\n  .svg-inline--fa.fa-w-20 {\n    width: 1.25em; }\n  .svg-inline--fa.fa-pull-left {\n    margin-right: .3em;\n    width: auto; }\n  .svg-inline--fa.fa-pull-right {\n    margin-left: .3em;\n    width: auto; }\n  .svg-inline--fa.fa-border {\n    height: 1.5em; }\n  .svg-inline--fa.fa-li {\n    width: 2em; }\n  .svg-inline--fa.fa-fw {\n    width: 1.25em; }\n\n.fa-layers svg.svg-inline--fa {\n  bottom: 0;\n  left: 0;\n  margin: auto;\n  position: absolute;\n  right: 0;\n  top: 0; }\n\n.fa-layers {\n  display: inline-block;\n  height: 1em;\n  position: relative;\n  text-align: center;\n  vertical-align: -.125em;\n  width: 1em; }\n  .fa-layers svg.svg-inline--fa {\n    -webkit-transform-origin: center center;\n            transform-origin: center center; }\n\n.fa-layers-text, .fa-layers-counter {\n  display: inline-block;\n  position: absolute;\n  text-align: center; }\n\n.fa-layers-text {\n  left: 50%;\n  top: 50%;\n  -webkit-transform: translate(-50%, -50%);\n          transform: translate(-50%, -50%);\n  -webkit-transform-origin: center center;\n          transform-origin: center center; }\n\n.fa-layers-counter {\n  background-color: #ff253a;\n  border-radius: 1em;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  color: #fff;\n  height: 1.5em;\n  line-height: 1;\n  max-width: 5em;\n  min-width: 1.5em;\n  overflow: hidden;\n  padding: .25em;\n  right: 0;\n  text-overflow: ellipsis;\n  top: 0;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: top right;\n          transform-origin: top right; }\n\n.fa-layers-bottom-right {\n  bottom: 0;\n  right: 0;\n  top: auto;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: bottom right;\n          transform-origin: bottom right; }\n\n.fa-layers-bottom-left {\n  bottom: 0;\n  left: 0;\n  right: auto;\n  top: auto;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: bottom left;\n          transform-origin: bottom left; }\n\n.fa-layers-top-right {\n  right: 0;\n  top: 0;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: top right;\n          transform-origin: top right; }\n\n.fa-layers-top-left {\n  left: 0;\n  right: auto;\n  top: 0;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: top left;\n          transform-origin: top left; }\n\n.fa-lg {\n  font-size: 1.33333em;\n  line-height: 0.75em;\n  vertical-align: -.0667em; }\n\n.fa-xs {\n  font-size: .75em; }\n\n.fa-sm {\n  font-size: .875em; }\n\n.fa-1x {\n  font-size: 1em; }\n\n.fa-2x {\n  font-size: 2em; }\n\n.fa-3x {\n  font-size: 3em; }\n\n.fa-4x {\n  font-size: 4em; }\n\n.fa-5x {\n  font-size: 5em; }\n\n.fa-6x {\n  font-size: 6em; }\n\n.fa-7x {\n  font-size: 7em; }\n\n.fa-8x {\n  font-size: 8em; }\n\n.fa-9x {\n  font-size: 9em; }\n\n.fa-10x {\n  font-size: 10em; }\n\n.fa-fw {\n  text-align: center;\n  width: 1.25em; }\n\n.fa-ul {\n  list-style-type: none;\n  margin-left: 2.5em;\n  padding-left: 0; }\n  .fa-ul > li {\n    position: relative; }\n\n.fa-li {\n  left: -2em;\n  position: absolute;\n  text-align: center;\n  width: 2em;\n  line-height: inherit; }\n\n.fa-border {\n  border: solid 0.08em #eee;\n  border-radius: .1em;\n  padding: .2em .25em .15em; }\n\n.fa-pull-left {\n  float: left; }\n\n.fa-pull-right {\n  float: right; }\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n  margin-right: .3em; }\n\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n  margin-left: .3em; }\n\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear; }\n\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8); }\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n.fa-rotate-90 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n  -webkit-transform: rotate(90deg);\n          transform: rotate(90deg); }\n\n.fa-rotate-180 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n  -webkit-transform: rotate(180deg);\n          transform: rotate(180deg); }\n\n.fa-rotate-270 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n  -webkit-transform: rotate(270deg);\n          transform: rotate(270deg); }\n\n.fa-flip-horizontal {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n  -webkit-transform: scale(-1, 1);\n          transform: scale(-1, 1); }\n\n.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(1, -1);\n          transform: scale(1, -1); }\n\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(-1, -1);\n          transform: scale(-1, -1); }\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical,\n:root .fa-flip-both {\n  -webkit-filter: none;\n          filter: none; }\n\n.fa-stack {\n  display: inline-block;\n  height: 2em;\n  position: relative;\n  width: 2.5em; }\n\n.fa-stack-1x,\n.fa-stack-2x {\n  bottom: 0;\n  left: 0;\n  margin: auto;\n  position: absolute;\n  right: 0;\n  top: 0; }\n\n.svg-inline--fa.fa-stack-1x {\n  height: 1em;\n  width: 1.25em; }\n\n.svg-inline--fa.fa-stack-2x {\n  height: 2em;\n  width: 2.5em; }\n\n.fa-inverse {\n  color: #fff; }\n\n.sr-only {\n  border: 0;\n  clip: rect(0, 0, 0, 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px; }\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n  clip: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  position: static;\n  width: auto; }\n\n.svg-inline--fa .fa-primary {\n  fill: var(--fa-primary-color, currentColor);\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.svg-inline--fa .fa-secondary {\n  fill: var(--fa-secondary-color, currentColor);\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.svg-inline--fa.fa-swap-opacity .fa-primary {\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.svg-inline--fa mask .fa-primary,\n.svg-inline--fa mask .fa-secondary {\n  fill: black; }\n\n.fad.fa-inverse {\n  color: #fff; }\n"
  },
  {
    "path": "public/fonts/font-awesome/current-ui.yaml",
    "content": "projectName: current-ui\nversion: 5.15.4\nicons:\n  - github:\n      - brands\n  - slack:\n      - brands\n  - twitter:\n      - brands\n  - instagram:\n      - brands\n  - times:\n      - solid\n      - regular\n  - times-circle:\n      - solid\n  - plus:\n      - regular\n      - solid\n  - undo-alt:\n      - regular\n      - solid\n  - info:\n      - regular\n  - user:\n      - solid\n      - duotone\n      - regular\n  - history:\n      - solid\n      - duotone\n  - check-circle:\n      - regular\n  - cloud:\n      - solid\n  - list-ul:\n      - duotone\n  - fingerprint:\n      - solid\n  - file-code:\n      - duotone\n      - regular\n  - search:\n      - duotone\n  - credit-card:\n      - solid\n  - server:\n      - duotone\n  - question-circle:\n      - duotone\n      - regular\n  - laptop:\n      - duotone\n  - file-alt:\n      - duotone\n  - books:\n      - duotone\n  - graduation-cap:\n      - duotone\n  - life-ring:\n      - duotone\n  - circle:\n      - duotone\n      - solid\n  - bell:\n      - duotone\n  - exchange-alt:\n      - duotone\n  - clouds:\n      - duotone\n  - random:\n      - duotone\n  - users:\n      - duotone\n      - solid\n      - regular\n  - key:\n      - duotone\n  - key-skeleton:\n      - duotone\n  - brackets-curly:\n      - duotone\n  - user-hard-hat:\n      - duotone\n  - abacus:\n      - duotone\n  - envelope:\n      - solid\n      - duotone\n  - cogs:\n      - duotone\n  - sun:\n      - duotone\n  - moon-stars:\n      - duotone\n  - sign-out:\n      - duotone\n  - smile:\n      - duotone\n  - map-marker-alt:\n      - duotone\n  - cc-amazon-pay:\n      - brands\n  - cc-amex:\n      - brands\n  - cc-apple-pay:\n      - brands\n  - cc-diners-club:\n      - brands\n  - cc-discover:\n      - brands\n  - cc-visa:\n      - brands\n  - cc-stripe:\n      - brands\n  - cc-paypal:\n      - brands\n  - cc-mastercard:\n      - brands\n  - cc-jcb:\n      - brands\n  - university:\n      - duotone\n  - lightbulb:\n      - duotone\n  - tasks:\n      - duotone\n  - check:\n      - duotone\n      - solid\n  - user-shield:\n      - duotone\n  - siren-on:\n      - duotone\n  - globe-africa:\n      - duotone\n  - globe-asia:\n      - duotone\n  - globe-americas:\n      - duotone\n  - globe-europe:\n      - duotone\n  - planet-ringed:\n      - duotone\n  - snowman:\n      - duotone\n  - globe:\n      - duotone\n  - laptop-house:\n      - duotone\n  - docker:\n      - brands\n  - aws:\n      - brands\n  - align-slash:\n      - duotone\n  - alarm-exclamation:\n      - solid\n  - slash:\n      - solid\n      - regular\n  - list-alt:\n      - duotone\n  - spinner-third:\n      - solid\n  - atom-alt:\n      - duotone\n  - network-wired:\n      - duotone\n  - chart-scatter:\n      - duotone\n  - chart-network:\n      - duotone\n  - lock-alt:\n      - duotone\n  - rocket:\n      - duotone\n      - solid\n      - regular\n  - home:\n      - solid\n  - quote-left:\n      - duotone\n  - desktop:\n      - solid\n      - regular\n  - save:\n      - solid\n      - regular\n  - eye:\n      - solid\n      - regular\n  - undo:\n      - solid\n      - regular\n  - book-dead:\n      - solid\n  - rev:\n      - brands\n  - robot:\n      - solid\n  - align-left:\n      - solid\n  - user-friends:\n      - regular\n  - microsoft:\n      - brands\n  - info-circle:\n      - regular\n  - square-full:\n      - solid\n  - concierge-bell:\n      - duotone\n  - badge-check:\n      - duotone\n  - dot-circle:\n      - duotone\n  - laptop-code:\n      - duotone\n  - discourse:\n      - brands\n  - comment-dots:\n      - duotone\n"
  },
  {
    "path": "public/fonts/font-awesome/js/all.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"aws\": [640, 512, [], \"f375\", \"M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z\"],\n    \"cc-amazon-pay\": [576, 512, [], \"f42d\", \"M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z\"],\n    \"cc-amex\": [576, 512, [], \"f1f3\", \"M325.1 167.8c0-16.4-14.1-18.4-27.4-18.4l-39.1-.3v69.3H275v-25.1h18c18.4 0 14.5 10.3 14.8 25.1h16.6v-13.5c0-9.2-1.5-15.1-11-18.4 7.4-3 11.8-10.7 11.7-18.7zm-29.4 11.3H275v-15.3h21c5.1 0 10.7 1 10.7 7.4 0 6.6-5.3 7.9-11 7.9zM279 268.6h-52.7l-21 22.8-20.5-22.8h-66.5l-.1 69.3h65.4l21.3-23 20.4 23h32.2l.1-23.3c18.9 0 49.3 4.6 49.3-23.3 0-17.3-12.3-22.7-27.9-22.7zm-103.8 54.7h-40.6v-13.8h36.3v-14.1h-36.3v-12.5h41.7l17.9 20.2zm65.8 8.2l-25.3-28.1L241 276zm37.8-31h-21.2v-17.6h21.5c5.6 0 10.2 2.3 10.2 8.4 0 6.4-4.6 9.2-10.5 9.2zm-31.6-136.7v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5zM576 255.4h-.2zm-194.6 31.9c0-16.4-14.1-18.7-27.1-18.7h-39.4l-.1 69.3h16.6l.1-25.3h17.6c11 0 14.8 2 14.8 13.8l-.1 11.5h16.6l.1-13.8c0-8.9-1.8-15.1-11-18.4 7.7-3.1 11.8-10.8 11.9-18.4zm-29.2 11.2h-20.7v-15.6h21c5.1 0 10.7 1 10.7 7.4 0 6.9-5.4 8.2-11 8.2zm-172.8-80v-69.3h-27.6l-19.7 47-21.7-47H83.3v65.7l-28.1-65.7H30.7L1 218.5h17.9l6.4-15.3h34.5l6.4 15.3H100v-54.2l24 54.2h14.6l24-54.2v54.2zM31.2 188.8l11.2-27.6 11.5 27.6zm477.4 158.9v-4.5c-10.8 5.6-3.9 4.5-156.7 4.5 0-25.2.1-23.9 0-25.2-1.7-.1-3.2-.1-9.4-.1 0 17.9-.1 6.8-.1 25.3h-39.6c0-12.1.1-15.3.1-29.2-10 6-22.8 6.4-34.3 6.2 0 14.7-.1 8.3-.1 23h-48.9c-5.1-5.7-2.7-3.1-15.4-17.4-3.2 3.5-12.8 13.9-16.1 17.4h-82v-92.3h83.1c5 5.6 2.8 3.1 15.5 17.2 3.2-3.5 12.2-13.4 15.7-17.2h58c9.8 0 18 1.9 24.3 5.6v-5.6c54.3 0 64.3-1.4 75.7 5.1v-5.1h78.2v5.2c11.4-6.9 19.6-5.2 64.9-5.2v5c10.3-5.9 16.6-5.2 54.3-5V80c0-26.5-21.5-48-48-48h-480c-26.5 0-48 21.5-48 48v109.8c9.4-21.9 19.7-46 23.1-53.9h39.7c4.3 10.1 1.6 3.7 9 21.1v-21.1h46c2.9 6.2 11.1 24 13.9 30 5.8-13.6 10.1-23.9 12.6-30h103c0-.1 11.5 0 11.6 0 43.7.2 53.6-.8 64.4 5.3v-5.3H363v9.3c7.6-6.1 17.9-9.3 30.7-9.3h27.6c0 .5 1.9.3 2.3.3H456c4.2 9.8 2.6 6 8.8 20.6v-20.6h43.3c4.9 8-1-1.8 11.2 18.4v-18.4h39.9v92h-41.6c-5.4-9-1.4-2.2-13.2-21.9v21.9h-52.8c-6.4-14.8-.1-.3-6.6-15.3h-19c-4.2 10-2.2 5.2-6.4 15.3h-26.8c-12.3 0-22.3-3-29.7-8.9v8.9h-66.5c-.3-13.9-.1-24.8-.1-24.8-1.8-.3-3.4-.2-9.8-.2v25.1H151.2v-11.4c-2.5 5.6-2.7 5.9-5.1 11.4h-29.5c-4-8.9-2.9-6.4-5.1-11.4v11.4H58.6c-4.2-10.1-2.2-5.3-6.4-15.3H33c-4.2 10-2.2 5.2-6.4 15.3H0V432c0 26.5 21.5 48 48 48h480.1c26.5 0 48-21.5 48-48v-90.4c-12.7 8.3-32.7 6.1-67.5 6.1zm36.3-64.5H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-57 39.8h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-42.2-40.1v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5zm-56.3-108.1c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm20.4-10.5h-.1zm-16.2-15.2c-23.5 0-34 12-34 35.3 0 22.2 10.2 34 33 34h19.2l6.4-15.3h34.3l6.6 15.3h33.7v-51.9l31.2 51.9h23.6v-69h-16.9v48.1l-29.1-48.1h-25.3v65.4l-27.9-65.4h-24.8l-23.5 54.5h-7.4c-13.3 0-16.1-8.1-16.1-19.9 0-23.8 15.7-20 33.1-19.7v-15.2zm42.1 12.1l11.2 27.6h-22.8zm-101.1-12v69.3h16.9v-69.3z\"],\n    \"cc-apple-pay\": [576, 512, [], \"f416\", \"M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z\"],\n    \"cc-diners-club\": [576, 512, [], \"f24c\", \"M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z\"],\n    \"cc-discover\": [576, 512, [], \"f1f2\", \"M520.4 196.1c0-7.9-5.5-12.1-15.6-12.1h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-44.1 138.9c22.6 0 52.9-4.1 52.9 24.4 0 12.6-6.6 20.7-18.7 23.2l25.8 34.4h-19.6l-22.2-32.8h-2.2v32.8h-16zm-55.9.1h45.3v14H444v18.2h28.3V217H444v22.2h29.3V253H428zm-68.7 0l21.9 55.2 22.2-55.2h17.5l-35.5 84.2h-8.6l-35-84.2zm-55.9-3c24.7 0 44.6 20 44.6 44.6 0 24.7-20 44.6-44.6 44.6-24.7 0-44.6-20-44.6-44.6 0-24.7 20-44.6 44.6-44.6zm-49.3 6.1v19c-20.1-20.1-46.8-4.7-46.8 19 0 25 27.5 38.5 46.8 19.2v19c-29.7 14.3-63.3-5.7-63.3-38.2 0-31.2 33.1-53 63.3-38zm-97.2 66.3c11.4 0 22.4-15.3-3.3-24.4-15-5.5-20.2-11.4-20.2-22.7 0-23.2 30.6-31.4 49.7-14.3l-8.4 10.8c-10.4-11.6-24.9-6.2-24.9 2.5 0 4.4 2.7 6.9 12.3 10.3 18.2 6.6 23.6 12.5 23.6 25.6 0 29.5-38.8 37.4-56.6 11.3l10.3-9.9c3.7 7.1 9.9 10.8 17.5 10.8zM55.4 253H32v-82h23.4c26.1 0 44.1 17 44.1 41.1 0 18.5-13.2 40.9-44.1 40.9zm67.5 0h-16v-82h16zM544 433c0 8.2-6.8 15-15 15H128c189.6-35.6 382.7-139.2 416-160zM74.1 191.6c-5.2-4.9-11.6-6.6-21.9-6.6H48v54.2h4.2c10.3 0 17-2 21.9-6.4 5.7-5.2 8.9-12.8 8.9-20.7s-3.2-15.5-8.9-20.5z\"],\n    \"cc-jcb\": [576, 512, [], \"f24b\", \"M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z\"],\n    \"cc-mastercard\": [576, 512, [], \"f1f1\", \"M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z\"],\n    \"cc-paypal\": [576, 512, [], \"f1f4\", \"M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z\"],\n    \"cc-stripe\": [576, 512, [], \"f1f5\", \"M492.4 220.8c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7zM375 223.4c-8.2 0-13.3 2.9-17 7l.2 52.8c3.5 3.7 8.5 6.7 16.8 6.7 13.1 0 21.9-14.3 21.9-33.4 0-18.6-9-33.2-21.9-33.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM122.2 281.1c0 25.6-20.3 40.1-49.9 40.3-12.2 0-25.6-2.4-38.8-8.1v-33.9c12 6.4 27.1 11.3 38.9 11.3 7.9 0 13.6-2.1 13.6-8.7 0-17-54-10.6-54-49.9 0-25.2 19.2-40.2 48-40.2 11.8 0 23.5 1.8 35.3 6.5v33.4c-10.8-5.8-24.5-9.1-35.3-9.1-7.5 0-12.1 2.2-12.1 7.7 0 16 54.3 8.4 54.3 50.7zm68.8-56.6h-27V275c0 20.9 22.5 14.4 27 12.6v28.9c-4.7 2.6-13.3 4.7-24.9 4.7-21.1 0-36.9-15.5-36.9-36.5l.2-113.9 34.7-7.4v30.8H191zm74 2.4c-4.5-1.5-18.7-3.6-27.1 7.4v84.4h-35.5V194.2h30.7l2.2 10.5c8.3-15.3 24.9-12.2 29.6-10.5h.1zm44.1 91.8h-35.7V194.2h35.7zm0-142.9l-35.7 7.6v-28.9l35.7-7.6zm74.1 145.5c-12.4 0-20-5.3-25.1-9l-.1 40.2-35.5 7.5V194.2h31.3l1.8 8.8c4.9-4.5 13.9-11.1 27.8-11.1 24.9 0 48.4 22.5 48.4 63.8 0 45.1-23.2 65.5-48.6 65.6zm160.4-51.5h-69.5c1.6 16.6 13.8 21.5 27.6 21.5 14.1 0 25.2-3 34.9-7.9V312c-9.7 5.3-22.4 9.2-39.4 9.2-34.6 0-58.8-21.7-58.8-64.5 0-36.2 20.5-64.9 54.3-64.9 33.7 0 51.3 28.7 51.3 65.1 0 3.5-.3 10.9-.4 12.9z\"],\n    \"cc-visa\": [576, 512, [], \"f1f0\", \"M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z\"],\n    \"discourse\": [448, 512, [], \"f393\", \"M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z\"],\n    \"docker\": [640, 512, [], \"f395\", \"M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z\"],\n    \"github\": [496, 512, [], \"f09b\", \"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\"],\n    \"instagram\": [448, 512, [], \"f16d\", \"M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z\"],\n    \"microsoft\": [448, 512, [], \"f3ca\", \"M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z\"],\n    \"rev\": [448, 512, [], \"f5b2\", \"M289.67 274.89a65.57 65.57 0 1 1-65.56-65.56 65.64 65.64 0 0 1 65.56 65.56zm139.55-5.05h-.13a204.69 204.69 0 0 0-74.32-153l-45.38 26.2a157.07 157.07 0 0 1 71.81 131.84C381.2 361.5 310.73 432 224.11 432S67 361.5 67 274.88c0-81.88 63-149.27 143-156.43v39.12l108.77-62.79L210 32v38.32c-106.7 7.25-191 96-191 204.57 0 111.59 89.12 202.29 200.06 205v.11h210.16V269.84z\"],\n    \"slack\": [448, 512, [], \"f198\", \"M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z\"],\n    \"twitter\": [512, 512, [], \"f099\", \"M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z\"]\n  };\n\n  bunker(function () {\n    defineIcons('fab', icons);\n  });\n\n}());\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"abacus\": [576, 512, [], \"f640\", [\"M192 440h-32v-48h32zM160 72v48h32V72zm96 160v48h32v-48zm-96 0v48h32v-48zm96 208h160v-48H256zm96-160h128v-48H352zM544 0a32 32 0 0 0-32 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32a32 32 0 0 0-32-32zM416 72H256v48h160zM32 0A32 32 0 0 0 0 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32A32 32 0 0 0 32 0z\", \"M144 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm-96 160h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm192 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm-96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zM464 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM144 352h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm224 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16z\"]],\n    \"align-slash\": [640, 512, [], \"f846\", [\"M528 352h-31.46l-82.81-64H528a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16zM96 304v32a16 16 0 0 0 16 16h175.21l-82.8-64H112a16 16 0 0 0-16 16zM528 96a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16H112a15.82 15.82 0 0 0-15 11.18L165.31 96zM112 416a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h340.83L370 416zm416-256H248.12l82.81 64H528a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M633.82 458.1L45.46 3.38A16 16 0 0 0 23 6.19L3.37 31.46a16 16 0 0 0 2.81 22.45l588.36 454.72a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45z\"]],\n    \"atom-alt\": [448, 512, [], \"f5d3\", [\"M424.37305,55.69141C408.294,39.61914,385.50879,32,358.58252,32,319.82764,32,272.43359,48.127,224,77.14453a493.86641,493.86641,0,0,0-58.042,41.03711C140.58252,138.875,114.57666,162.5918,85.75635,197.916a374.25237,374.25237,0,0,0,35.70263,58.082A505.23427,505.23427,0,0,1,224,153.65625a377.23937,377.23937,0,0,1,58.042-35.47266c70.01221-34.334,95.22461-19.07421,97.0625-17.23632,9.54248,9.543,7.67432,46.94531-16.86084,96.96875A492.27615,492.27615,0,0,1,403.06543,256C452.27637,173.91992,463.59277,94.90039,424.37305,55.69141ZM224,358.3418a377.44678,377.44678,0,0,1-58.042,35.47461c-70.01221,34.334-95.22461,19.07421-97.0625,17.23632-9.54248-9.543-7.67432-46.94335,16.86084-96.96875A492.27615,492.27615,0,0,1,44.93457,256C-4.27637,338.08008-15.59277,417.09961,23.627,456.30664,39.70605,472.38086,62.49121,480,89.41748,480c38.75488,0,86.14893-16.127,134.58252-45.14453a493.86641,493.86641,0,0,0,58.042-41.03711c25.38965-20.70508,51.42285-44.45606,80.20166-79.73438A373.962,373.962,0,0,0,326.541,256,505.23427,505.23427,0,0,1,224,358.3418Z\", \"M224,287.98828a31.99414,31.99414,0,1,0-32-31.99414A31.98908,31.98908,0,0,0,224,287.98828ZM121.46094,255.99805A374.13921,374.13921,0,0,1,85.7583,197.916c-24.53906-50.02344-26.40625-87.42579-16.86328-96.9668,1.83984-1.83789,27.05078-17.10156,97.062,17.23242A494.241,494.241,0,0,1,224,77.14453C175.5625,48.13086,128.16406,32,89.41846,32c-26.9336,0-49.707,7.61523-65.793,23.69141C-15.59326,94.90039-4.27686,173.91992,44.93408,256A492.0174,492.0174,0,0,0,85.7583,314.084c28.79639,35.30274,54.85889,59.07227,80.19873,79.73243A377.429,377.429,0,0,0,224,358.3418,505.131,505.131,0,0,1,121.46094,255.99805ZM403.06592,256a492.0174,492.0174,0,0,0-40.82422-58.084c-28.84326-35.35547-54.89795-59.10352-80.19873-79.73243A377.4073,377.4073,0,0,0,224,153.65625,505.20556,505.20556,0,0,1,326.53906,256a373.849,373.849,0,0,1,35.70264,58.084c24.53906,50.02149,26.40625,87.42383,16.86328,96.9668-1.83984,1.83789-27.05078,17.10156-97.062-17.23242A494.241,494.241,0,0,1,224,434.85547C272.4375,463.86914,319.83594,480,358.58154,480c26.9336,0,49.707-7.61523,65.793-23.69336C463.59326,417.09961,452.27686,338.08008,403.06592,256Z\"]],\n    \"badge-check\": [512, 512, [], \"f336\", [\"M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z\", \"M367.2 211.75l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.06 15.56z\"]],\n    \"bell\": [448, 512, [], \"f0f3\", [\"M448 384c-.1 16.4-13 32-32.1 32H32.08C13 416 .09 400.4 0 384a31.25 31.25 0 0 1 8.61-21.71c19.32-20.76 55.47-52 55.47-154.29 0-77.7 54.48-139.9 127.94-155.16V32a32 32 0 1 1 64 0v20.84C329.42 68.1 383.9 130.3 383.9 208c0 102.3 36.15 133.53 55.47 154.29A31.27 31.27 0 0 1 448 384z\", \"M160 448h128a64 64 0 0 1-128 0z\"]],\n    \"books\": [576, 512, [], \"f5db\", [\"M96 0H32A32 32 0 0 0 0 32v64h128V32A32 32 0 0 0 96 0zM0 384h128V128H0zm0 96a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H0zm513.62-17.78L401.08 42.71l-60.26 16.14 112.35 418.8c.11.39.2.79.29 1.18l60.29-16.15c-.04-.15-.09-.3-.13-.46zM160 480a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H160zM256 0h-64a32 32 0 0 0-32 32v64h124.79l-8-29.65a23.94 23.94 0 0 1 11.17-27V32A32 32 0 0 0 256 0zm-96 384h128V128H160z\", \"M0 416h128v-32H0zm0-288h128V96H0zm575.17 317.65L460.39 17.78a23.89 23.89 0 0 0-29.18-17h-.09L415.73 5a24 24 0 0 0-16.9 29.36l114.79 427.86a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.35zM160 416h128v-32H160zM338.39 49.78a23.89 23.89 0 0 0-29.18-17h-.09L293.73 37a24 24 0 0 0-16.9 29.36l8 29.65H160v32h128V108l103.62 386.22a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.33z\"]],\n    \"brackets-curly\": [576, 512, [], \"f7ea\", [\"M566.64 233.37a32 32 0 0 1 0 45.25l-45.25 45.25a32 32 0 0 0-9.39 22.64V384a96 96 0 0 1-96 96h-48a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h48a32 32 0 0 0 32-32v-37.48a96 96 0 0 1 28.13-67.89L498.76 256l-22.62-22.62A96 96 0 0 1 448 165.47V128a32 32 0 0 0-32-32h-48a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h48a96 96 0 0 1 96 96v37.48a32 32 0 0 0 9.38 22.65l45.25 45.24z\", \"M208 32h-48a96 96 0 0 0-96 96v37.48a32.12 32.12 0 0 1-9.38 22.65L9.38 233.37a32 32 0 0 0 0 45.25l45.25 45.25A32.05 32.05 0 0 1 64 346.51V384a96 96 0 0 0 96 96h48a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-48a32 32 0 0 1-32-32v-37.48a96 96 0 0 0-28.13-67.89L77.26 256l22.63-22.63A96 96 0 0 0 128 165.48V128a32 32 0 0 1 32-32h48a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]],\n    \"chart-network\": [640, 512, [], \"f78a\", [\"M64 240a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64zm88 80h48v-32h-48zm294.4-106.8l19.2 25.6 48-36-19.2-25.6zM576 64a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64z\", \"M576 384a63.84 63.84 0 0 0-38.3 13l-96-57.6a109.91 109.91 0 0 0 6.3-35.5 111.94 111.94 0 0 0-112-112 108.64 108.64 0 0 0-24.4 2.9l-40.8-87.4A63.84 63.84 0 1 0 224 128c1.1 0 2.1-.3 3.2-.3l41 87.8C241.5 235.9 224 267.8 224 304a111.71 111.71 0 0 0 193.2 76.7l95.8 57.5a63.87 63.87 0 1 0 63-54.2zm-240-32a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]],\n    \"chart-scatter\": [512, 512, [], \"f7ee\", [\"M512 400v32a16 16 0 0 1-16 16H32a32 32 0 0 1-32-32V80a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16v304h432a16 16 0 0 1 16 16z\", \"M160 256a32 32 0 1 0 32 32 32 32 0 0 0-32-32zM416 96a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-224 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm192 160a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-96-64a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]],\n    \"check\": [512, 512, [], \"f00c\", [\"M504.5 144.42L264.75 385.5 192 312.59l240.11-241a25.49 25.49 0 0 1 36.06-.14l.14.14L504.5 108a25.86 25.86 0 0 1 0 36.42z\", \"M264.67 385.59l-54.57 54.87a25.5 25.5 0 0 1-36.06.14l-.14-.14L7.5 273.1a25.84 25.84 0 0 1 0-36.41l36.2-36.41a25.49 25.49 0 0 1 36-.17l.16.17z\"]],\n    \"circle\": [512, 512, [], \"f111\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 424c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\", \"M256 432c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\"]],\n    \"clouds\": [640, 512, [], \"f744\", [\"M161.6 288H96a96 96 0 0 1 0-192c.6 0 1.1.2 1.6.2C105.3 41.9 151.6 0 208 0a111.61 111.61 0 0 1 104.5 72.7A95.07 95.07 0 0 1 352 64a96 96 0 0 1 96 96 93 93 0 0 1-7 34.7 110.5 110.5 0 0 0-31.6 11.8A142.54 142.54 0 0 0 304 160c-73.9 0-134.3 56.2-142.4 128z\", \"M640 416a96 96 0 0 1-96 96H224a96 96 0 0 1-96-96c0-42.5 27.8-78.2 66.1-90.8A113.72 113.72 0 0 1 192 304a111.94 111.94 0 0 1 112-112c43.2 0 80.4 24.9 99 60.8 14.7-17.5 36.4-28.8 61-28.8a80 80 0 0 1 80 80 78.09 78.09 0 0 1-1.6 16.2c.5 0 1-.2 1.6-.2a96 96 0 0 1 96 96z\"]],\n    \"cogs\": [640, 512, [], \"f085\", [\"M638.41 387a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4L602 335a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6 12.36 12.36 0 0 0-15.1 5.4l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 44.9c-29.6-38.5 14.3-82.4 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79zm136.8-343.8a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4l8.2-14.3a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6A12.36 12.36 0 0 0 552 7.19l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 45c-29.6-38.5 14.3-82.5 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79z\", \"M420 303.79L386.31 287a173.78 173.78 0 0 0 0-63.5l33.7-16.8c10.1-5.9 14-18.2 10-29.1-8.9-24.2-25.9-46.4-42.1-65.8a23.93 23.93 0 0 0-30.3-5.3l-29.1 16.8a173.66 173.66 0 0 0-54.9-31.7V58a24 24 0 0 0-20-23.6 228.06 228.06 0 0 0-76 .1A23.82 23.82 0 0 0 158 58v33.7a171.78 171.78 0 0 0-54.9 31.7L74 106.59a23.91 23.91 0 0 0-30.3 5.3c-16.2 19.4-33.3 41.6-42.2 65.8a23.84 23.84 0 0 0 10.5 29l33.3 16.9a173.24 173.24 0 0 0 0 63.4L12 303.79a24.13 24.13 0 0 0-10.5 29.1c8.9 24.1 26 46.3 42.2 65.7a23.93 23.93 0 0 0 30.3 5.3l29.1-16.7a173.66 173.66 0 0 0 54.9 31.7v33.6a24 24 0 0 0 20 23.6 224.88 224.88 0 0 0 75.9 0 23.93 23.93 0 0 0 19.7-23.6v-33.6a171.78 171.78 0 0 0 54.9-31.7l29.1 16.8a23.91 23.91 0 0 0 30.3-5.3c16.2-19.4 33.7-41.6 42.6-65.8a24 24 0 0 0-10.5-29.1zm-151.3 4.3c-77 59.2-164.9-28.7-105.7-105.7 77-59.2 164.91 28.7 105.71 105.7z\"]],\n    \"comment-dots\": [512, 512, [], \"f4ad\", [\"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5a8 8 0 0 0-1.5 8.7A7.83 7.83 0 0 0 8 480c66.3 0 116-31.8 140.6-51.4A305 305 0 0 0 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32z\", \"M128 208a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]],\n    \"concierge-bell\": [512, 512, [], \"f562\", [\"M512 400v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h480a16 16 0 0 1 16 16zM208 112h16v18.29a224.73 224.73 0 0 1 64 0V112h16a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16z\", \"M480 352H32c0-123.71 100.29-224 224-224s224 100.29 224 224z\"]],\n    \"dot-circle\": [512, 512, [], \"f192\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm124.45 372.45A176 176 0 1 1 432 256a174.85 174.85 0 0 1-51.55 124.45z\", \"M256 336a80 80 0 1 1 80-80 80.09 80.09 0 0 1-80 80z\"]],\n    \"envelope\": [512, 512, [], \"f0e0\", [\"M256.47 352h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V400a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V183.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52zM464 64H48a48 48 0 0 0-48 48v19a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4 23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131v-19a48 48 0 0 0-48-48z\", \"M512 131v52.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V131a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.69 12.12 49.75 41.4 72.93 41.4h.94c23.18 0 56.24-29.28 72.93-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131z\"]],\n    \"exchange-alt\": [512, 512, [], \"f362\", [\"M128 272v48h360a24 24 0 0 1 24 24v16a24 24 0 0 1-24 24H128v48c0 21.44-25.94 32-41 17L7 369a24 24 0 0 1 0-33.94l80-80c15.14-15.12 41-4.35 41 16.94z\", \"M505 143.05a24 24 0 0 1 0 33.95l-80 80c-15 15-41 4.49-41-17v-48H24a24 24 0 0 1-24-24v-16a24 24 0 0 1 24-24h360V80c0-21.36 25.9-32 41-17z\"]],\n    \"file-alt\": [384, 512, [], \"f15c\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zm-96 244a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM276 352H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12z\"]],\n    \"file-code\": [384, 512, [], \"f1c9\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zM141.79 379.54l-19.58 20.84a5.41 5.41 0 0 1-7.64.24l-64.86-60.69a5.37 5.37 0 0 1-.24-7.6l.25-.25 64.86-60.7a5.42 5.42 0 0 1 7.64.24l19.58 20.85a5.4 5.4 0 0 1-.25 7.62l-.13.12L100.65 336l40.76 35.8a5.4 5.4 0 0 1 .49 7.62zm31.71 71.25l-27.45-8a5.38 5.38 0 0 1-3.67-6.67l61.49-211.24a5.38 5.38 0 0 1 6.68-3.64l27.45 8a5.4 5.4 0 0 1 3.63 6.67l-61.45 211.2a5.4 5.4 0 0 1-6.68 3.68zm161-111.12l-.25.25-64.86 60.69a5.42 5.42 0 0 1-7.64-.23l-19.58-20.84a5.37 5.37 0 0 1 .26-7.6l.13-.12L283.35 336l-40.76-35.8a5.4 5.4 0 0 1-.49-7.62l.11-.12 19.58-20.85a5.42 5.42 0 0 1 7.64-.24l64.86 60.7a5.36 5.36 0 0 1 .25 7.6z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM141.41 371.8L100.65 336l40.76-35.8.13-.12a5.4 5.4 0 0 0 .25-7.62l-19.58-20.85a5.42 5.42 0 0 0-7.64-.24l-64.86 60.7-.25.25a5.37 5.37 0 0 0 .24 7.6l64.86 60.69a5.41 5.41 0 0 0 7.64-.24l19.58-20.84.11-.12a5.4 5.4 0 0 0-.48-7.61zm100.22-135.93a5.4 5.4 0 0 0-3.63-6.67l-27.45-8a5.38 5.38 0 0 0-6.68 3.64l-61.5 211.29a5.38 5.38 0 0 0 3.63 6.67l27.45 8a5.4 5.4 0 0 0 6.68-3.68l61.44-211.22zm92.66 96.2l-64.86-60.7a5.42 5.42 0 0 0-7.64.24l-19.58 20.85-.11.12a5.4 5.4 0 0 0 .49 7.62l40.76 35.8-40.76 35.8-.13.12a5.37 5.37 0 0 0-.26 7.6l19.58 20.84a5.42 5.42 0 0 0 7.64.23l64.86-60.69.25-.25a5.36 5.36 0 0 0-.25-7.6z\"]],\n    \"globe\": [496, 512, [], \"f0ac\", [\"M340.45,320H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256,575,575,0,0,1,340.45,320ZM160.2,160H335.8c-.41-2.31-.84-4.62-1.28-6.91-6-30.85-14.42-58.37-25.13-81.78C299.54,49.77,288,32.54,276.05,21.48,266.38,12.53,256.94,8,248,8s-18.38,4.53-28,13.48c-12,11.06-23.49,28.29-33.34,49.83C176,94.72,167.5,122.24,161.53,153.09,161,155.38,160.61,157.69,160.2,160ZM120,256a608,608,0,0,1,3.34-64H8.35a249.52,249.52,0,0,0,0,128h115A608,608,0,0,1,120,256Zm367.62-64h-115A608.06,608.06,0,0,1,376,256a608,608,0,0,1-3.34,64h115a249.52,249.52,0,0,0,0-128ZM476.7,160A248.62,248.62,0,0,0,315.58,17.32c24.13,33,42.89,83.15,52.75,142.68ZM315.58,494.68A248.59,248.59,0,0,0,476.71,352H368.33C358.47,411.53,339.71,461.68,315.58,494.68ZM335.8,352H160.2c.41,2.31.84,4.62,1.28,6.91,6,30.85,14.42,58.37,25.13,81.78,9.85,21.54,21.38,38.77,33.34,49.83,9.67,9,19.11,13.48,28.05,13.48s18.38-4.53,28.05-13.48c12-11.06,23.49-28.29,33.34-49.83,10.71-23.41,19.16-50.93,25.13-81.78C335,356.62,335.39,354.31,335.8,352ZM180.42,17.32A248.59,248.59,0,0,0,19.29,160H127.67C137.53,100.47,156.29,50.32,180.42,17.32ZM19.29,352A248.59,248.59,0,0,0,180.42,494.68c-24.13-33-42.89-83.15-52.75-142.68Z\", \"M376,256a608,608,0,0,0-3.34-64h115a245.72,245.72,0,0,0-10.92-32H368.33c-9.86-59.53-28.62-109.68-52.75-142.68A248.23,248.23,0,0,0,248,8c8.94,0,18.38,4.53,28.05,13.48,12,11.06,23.49,28.29,33.34,49.83,10.71,23.41,19.16,50.93,25.13,81.78.44,2.29.87,4.6,1.28,6.91H160.2c.41-2.31.84-4.62,1.28-6.91,6-30.85,14.42-58.37,25.13-81.78C196.46,49.77,208,32.54,220,21.48,229.62,12.53,239.06,8,248,8a248.23,248.23,0,0,0-67.58,9.32c-24.13,33-42.89,83.15-52.75,142.68H19.29A245.72,245.72,0,0,0,8.37,192h115a613.93,613.93,0,0,0,0,128H8.37a245.72,245.72,0,0,0,10.92,32H127.67c9.86,59.53,28.62,109.68,52.75,142.68A248.23,248.23,0,0,0,248,504c-8.94,0-18.38-4.53-28.05-13.48-12-11.06-23.49-28.29-33.34-49.83-10.71-23.41-19.16-50.93-25.13-81.78-.44-2.29-.87-4.6-1.28-6.91H335.8c-.41,2.31-.84,4.62-1.28,6.91-6,30.85-14.42,58.37-25.13,81.78-9.85,21.54-21.38,38.77-33.34,49.83-9.67,9-19.11,13.48-28.05,13.48a248.23,248.23,0,0,0,67.58-9.32c24.13-33,42.89-83.15,52.75-142.68H476.71a245.72,245.72,0,0,0,10.92-32h-115A605.37,605.37,0,0,0,376,256Zm-35.54,64H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256a575,575,0,0,1-3.55,64Z\"]],\n    \"globe-africa\": [496, 512, [], \"f57c\", [\"M491.33,208H423.5A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05A249.89,249.89,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256A249.51,249.51,0,0,0,491.33,208Z\", \"M423.5,208A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05C386,23.7,471,104.24,491.34,208Z\"]],\n    \"globe-americas\": [496, 512, [], \"f57d\", [\"M489.55,312.41C464,422.22,365.59,504,248,504,111,504,0,393,0,256A247,247,0,0,1,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311l-13.71-13.67A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A247,247,0,0,1,248,8C351.83,8,440.71,71.76,477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1Z\", \"M321.39,297.36A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A249,249,0,0,0,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311ZM477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1,55.64,29.22a249.21,249.21,0,0,0-11.88-150.14Z\"]],\n    \"globe-asia\": [496, 512, [], \"f57e\", [\"M312,16.35V50.73a28,28,0,0,1-11.12,22.35l-41.41,31.27a8,8,0,0,0,.86,13.81l10.83,5.41A16,16,0,0,1,280,137.88V216a8,8,0,0,1-8,8h-3.06a8,8,0,0,1-7.15-4.42,4.47,4.47,0,0,0-1.72-1.86,4.42,4.42,0,0,0-6.06,1.54h0l-17.34,29A16,16,0,0,1,222.94,256h-.31a16,16,0,0,0-11.32,4.69l-5.66,5.66a8,8,0,0,0,0,11.31l5.66,5.66A16,16,0,0,1,216,294.63V304a16,16,0,0,1-16,16h-6.1a16,16,0,0,1-14.28-8.85L157,265.92a8,8,0,0,0-10.72-3.6h0a8.14,8.14,0,0,0-2.11,1.53l-19.47,19.46A16,16,0,0,1,113.38,288H2.05C17.74,409.88,121.84,504,248,504c137,0,248-111,248-248C496,141.13,418,44.56,312,16.35Zm96,342.08a16,16,0,0,1-4.69,11.31l-9.57,9.57A16,16,0,0,1,382.43,384H367.27a16,16,0,0,1-11.36-4.74l-13-13a26.78,26.78,0,0,0-25.42-7l-21.27,5.32a15.86,15.86,0,0,1-3.88.48H282a16,16,0,0,1-11.24-4.69l-11.91-11.91a8,8,0,0,1-2.34-5.66V332.6a8,8,0,0,1,5-7.43l39.34-15.74a26.35,26.35,0,0,0,5.59-3.05l23.71-16.89a8,8,0,0,1,4.64-1.48h12.14a8,8,0,0,1,7.39,4.93l5.35,12.85a4,4,0,0,0,3.69,2.46h3.8a4,4,0,0,0,3.84-2.88l4.16-14.49A4,4,0,0,1,379,288h6.06a4,4,0,0,1,4,4v13a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,1,408,333.83Z\", \"M260.07,217.72a4.47,4.47,0,0,1,1.72,1.86,8,8,0,0,0,7.15,4.42H272a8,8,0,0,0,8-8V137.88a16,16,0,0,0-8.84-14.31l-10.83-5.41a8,8,0,0,1-.86-13.81l41.41-31.27A28,28,0,0,0,312,50.73V16.35A248.23,248.23,0,0,0,248,8C111,8,0,119,0,256a249.89,249.89,0,0,0,2.05,32H113.38a16,16,0,0,0,11.31-4.69l19.47-19.46A8,8,0,0,1,157,265.92l22.62,45.23A16,16,0,0,0,193.9,320H200a16,16,0,0,0,16-16v-9.37a16,16,0,0,0-4.69-11.31l-5.66-5.66a8,8,0,0,1,0-11.31l5.66-5.66A16,16,0,0,1,222.63,256h.31a16,16,0,0,0,13.72-7.77L254,219.28a4.42,4.42,0,0,1,6.05-1.57Zm143.24,104.8L391.4,310.61a8,8,0,0,1-2.34-5.66V292a4,4,0,0,0-4-4H379a4,4,0,0,0-3.84,2.88L371,305.37a4,4,0,0,1-3.84,2.88h-3.8a4,4,0,0,1-3.69-2.46l-5.35-12.85a8,8,0,0,0-7.39-4.93H334.79a8,8,0,0,0-4.64,1.48l-23.71,16.89a26.35,26.35,0,0,1-5.59,3.05l-39.34,15.74a8,8,0,0,0-5,7.43v10.2a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,0,282,365.06h10.34a15.86,15.86,0,0,0,3.88-.48l21.27-5.32a26.78,26.78,0,0,1,25.42,7l13,13A16,16,0,0,0,367.27,384h15.16a16,16,0,0,0,11.31-4.69l9.57-9.57A16,16,0,0,0,408,358.43v-24.6a16,16,0,0,0-4.69-11.31Z\"]],\n    \"globe-europe\": [496, 512, [], \"f7a2\", [\"M487.54,320.4H438.9a15.8,15.8,0,0,1-11.4-4.8l-32-32.6a11.92,11.92,0,0,1,.1-16.7l12.5-12.5v-8.7a11.37,11.37,0,0,0-3.3-8l-9.4-9.4a11.37,11.37,0,0,0-8-3.3h-16a11.31,11.31,0,0,1-8-19.3l9.4-9.4a11.37,11.37,0,0,1,8-3.3h32a11.35,11.35,0,0,0,11.3-11.3v-9.4a11.35,11.35,0,0,0-11.3-11.3H376.1a16,16,0,0,0-16,16v4.5a16,16,0,0,1-10.9,15.2l-31.6,10.5a8,8,0,0,0-5.5,7.6v2.2a8,8,0,0,1-8,8h-16a8,8,0,0,1-8-8,8,8,0,0,0-8-8H269a8.14,8.14,0,0,0-7.2,4.4l-9.4,18.7a15.94,15.94,0,0,1-14.3,8.8H216a16,16,0,0,1-16-16V199a16,16,0,0,1,4.7-11.3l20.1-20.1a24.77,24.77,0,0,0,7.2-17.5,8,8,0,0,1,5.5-7.6l40-13.3a11.66,11.66,0,0,0,4.4-2.7l26.8-26.8a11.31,11.31,0,0,0-8-19.3H280l-16,16v8a8,8,0,0,1-8,8H240a8,8,0,0,1-8-8v-20a8.05,8.05,0,0,1,3.2-6.4l82.42-60.08A247.79,247.79,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504a251.57,251.57,0,0,0,32.1-2.06V448.4a16,16,0,0,0-16-16H243.9c-10.8,0-26.7-5.3-35.4-11.8l-22.2-16.7a45.42,45.42,0,0,1-18.2-36.4V343.6a45.46,45.46,0,0,1,22.1-39l42.9-25.7a46.13,46.13,0,0,1,23.4-6.5h31.2a45.62,45.62,0,0,1,29.6,10.9l43.2,37.1h18.3a32,32,0,0,1,22.6,9.4l17.3,17.3.08.08C432,359.06,440,375.62,440,393.37V413A247.11,247.11,0,0,0,487.54,320.4ZM187.4,157.1a11.37,11.37,0,0,1-8,3.3h-16a11.31,11.31,0,0,1-8-19.3l25.4-25.4a11.31,11.31,0,0,1,19.3,8v16a11.37,11.37,0,0,1-3.3,8Z\", \"M187.4,157.1l9.4-9.4a11.37,11.37,0,0,0,3.3-8v-16a11.31,11.31,0,0,0-19.3-8l-25.4,25.4a11.31,11.31,0,0,0,8,19.3h16A11.37,11.37,0,0,0,187.4,157.1ZM418.78,347.18l-.08-.08-17.3-17.3a32,32,0,0,0-22.6-9.4H360.5l-43.2-37.1a45.62,45.62,0,0,0-29.6-10.9H256.5a46.13,46.13,0,0,0-23.4,6.5l-42.9,25.7a45.46,45.46,0,0,0-22.1,39v23.9a45.42,45.42,0,0,0,18.2,36.4l22.2,16.7c8.7,6.5,24.6,11.8,35.4,11.8h20.2a16,16,0,0,1,16,16v53.54A247.57,247.57,0,0,0,440,413V393.37C440,375.62,432,359.06,418.78,347.18ZM317.62,17.92,235.2,78a8.05,8.05,0,0,0-3.2,6.4v20a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-8l16-16h20.7a11.31,11.31,0,0,1,8,19.3l-26.8,26.8a11.66,11.66,0,0,1-4.4,2.7l-40,13.3a8,8,0,0,0-5.5,7.6,24.77,24.77,0,0,1-7.2,17.5l-20.1,20.1A16,16,0,0,0,200,199v25.3a16,16,0,0,0,16,16h22.1a15.94,15.94,0,0,0,14.3-8.8l9.4-18.7a8.14,8.14,0,0,1,7.2-4.4h3.1a8,8,0,0,1,8,8,8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-2.2a8,8,0,0,1,5.5-7.6l31.6-10.5a16,16,0,0,0,10.9-15.2v-4.5a16,16,0,0,1,16-16h36.7a11.35,11.35,0,0,1,11.3,11.3v9.4a11.35,11.35,0,0,1-11.3,11.3h-32a11.37,11.37,0,0,0-8,3.3l-9.4,9.4a11.31,11.31,0,0,0,8,19.3h16a11.37,11.37,0,0,1,8,3.3l9.4,9.4a11.37,11.37,0,0,1,3.3,8v8.7l-12.5,12.5a11.92,11.92,0,0,0-.1,16.7l32,32.6a15.8,15.8,0,0,0,11.4,4.8h48.64A248.29,248.29,0,0,0,496,256C496,143.18,420.71,48,317.62,17.92Z\"]],\n    \"graduation-cap\": [640, 512, [], \"f19d\", [\"M323.07 175.7L118.8 215.6a48.1 48.1 0 0 0-38.74 44.73 32 32 0 0 1 2.21 53.94l25.4 114.26A16 16 0 0 1 92 448H35.94a16 16 0 0 1-15.61-19.47l25.39-114.27a32 32 0 0 1 2.33-54 80.16 80.16 0 0 1 64.62-76.07l204.26-39.89a16 16 0 1 1 6.14 31.4z\", \"M622.33 198.8l-279 85.7a80 80 0 0 1-46.79 0L99.67 224a47.84 47.84 0 0 1 19.13-8.39l204.27-39.9a16 16 0 1 0-6.14-31.4l-204.26 39.88a79.87 79.87 0 0 0-47.57 29.18l-47.44-14.58c-23.54-7.23-23.54-38.36 0-45.59L296.6 67.5a79.92 79.92 0 0 1 46.8 0l278.93 85.7c23.55 7.24 23.55 38.36 0 45.6zM352.79 315.09a111.94 111.94 0 0 1-65.59 0l-145-44.55L128 384c0 35.35 86 64 192 64s192-28.65 192-64l-14.19-113.47z\"]],\n    \"history\": [512, 512, [], \"f1da\", [\"M141.68 400.23a184 184 0 1 0-11.75-278.3l50.76 50.76c10.08 10.08 2.94 27.31-11.32 27.31H24a16 16 0 0 1-16-16V38.63c0-14.26 17.23-21.4 27.31-11.32l49.38 49.38A247.14 247.14 0 0 1 256 8c136.81 0 247.75 110.78 248 247.53S392.82 503.9 256.18 504a247 247 0 0 1-155.82-54.91 24 24 0 0 1-1.84-35.61l11.27-11.27a24 24 0 0 1 31.89-1.98z\", \"M288 152v104.35L328.7 288a24 24 0 0 1 4.21 33.68l-9.82 12.62a24 24 0 0 1-33.68 4.21L224 287.65V152a24 24 0 0 1 24-24h16a24 24 0 0 1 24 24z\"]],\n    \"key\": [512, 512, [], \"f084\", [\"M303.06 348.91l.1.09-24 27a24 24 0 0 1-17.94 8H224v40a24 24 0 0 1-24 24h-40v40a24 24 0 0 1-24 24H24a24 24 0 0 1-24-24v-78a24 24 0 0 1 7-17l161.83-161.83-.11-.35a176.24 176.24 0 0 0 134.34 118.09z\", \"M336 0a176 176 0 1 0 176 176A176 176 0 0 0 336 0zm48 176a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]],\n    \"key-skeleton\": [512, 512, [], \"f6f3\", [\"M251.31 372.91a16 16 0 0 1 0 22.63l-15.77 15.77a16 16 0 0 1-22.62 0L176 374.4l-30.87 30.86 36.11 36.11a16 16 0 0 1 0 22.63l-43.16 43.17a16 16 0 0 1-22.62 0l-36.12-36.11-36.26 36.25a16 16 0 0 1-22.62 0L4.69 491.54a16 16 0 0 1 0-22.63l255.12-255.12a64.18 64.18 0 0 0 38.4 38.4L214.4 336l36.91 36.91z\", \"M448 0H320a64 64 0 0 0-64 64v128a64 64 0 0 0 64 64h128a64 64 0 0 0 64-64V64a64 64 0 0 0-64-64zm-73.37 182.63a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25zm64-64a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25z\"]],\n    \"laptop\": [640, 512, [], \"f109\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M512 64H128v256h384zm112 352H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16z\"]],\n    \"laptop-code\": [640, 512, [], \"f5fc\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16zM512 64H128v256h384zM289 250.34l-11.31 11.31a16 16 0 0 1-22.63 0l-58.35-58.34a16 16 0 0 1 0-22.63L255 122.34a16 16 0 0 1 22.63 0L289 133.65a16 16 0 0 1 0 22.63L253.25 192 289 227.71a16 16 0 0 1 0 22.63zm154.35-47L385 261.66a16 16 0 0 1-22.63 0L351 250.35a16 16 0 0 1 0-22.63L386.75 192 351 156.29a16 16 0 0 1 0-22.63l11.31-11.31a16 16 0 0 1 22.63 0l58.34 58.34a16 16 0 0 1 .04 22.63z\"]],\n    \"laptop-house\": [640, 512, [], \"e066\", [\"M272,416H96a32,32,0,0,1-32-32V219.88L42.34,239A16.51,16.51,0,0,1,33,242.48a16.22,16.22,0,0,1-10.63-4.78L3.55,216.42A16.4,16.4,0,0,1,0,207a16.15,16.15,0,0,1,4.78-10.61L216.58,8.92C222.12,4,232.64,0,240.05,0S258,4,263.5,8.92L352,87.3V48a16,16,0,0,1,16-16h32a16,16,0,0,1,16,16v96l59.24,52.42A16.31,16.31,0,0,1,480,207a16.51,16.51,0,0,1-3.58,9.44L469.74,224H332.8c-17.8,0-33.69,8.24-44.82,21.12V208a16,16,0,0,0-16-16H208a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16h64Z\", \"M629.33,448H592V288c0-17.67-12.89-32-28.8-32H332.8c-15.91,0-28.8,14.33-28.8,32V448H266.67A10.67,10.67,0,0,0,256,458.67v10.66A42.82,42.82,0,0,0,298.6,512H597.4A42.82,42.82,0,0,0,640,469.33V458.67A10.67,10.67,0,0,0,629.33,448ZM544,448H352V304H544Z\"]],\n    \"life-ring\": [512, 512, [], \"f1cd\", [\"M292.08 167l-.41-.17zm-66.62-2a96.5 96.5 0 0 1 61.08 0l112-112a248 248 0 0 0-285 0zm68.67 2.92l.52.22zm2.49 1.12l.46.21zM186.25 322l-.19-.21zm-5.51-6.36l.21.26zm1.65 2c.12.14.23.28.35.41-.12-.15-.23-.29-.35-.43zm1.74 2l.36.4zm135.51-135.51l.4.36zM177.51 311.29l-.1-.15zM304.18 173l.34.19zm11.42 7.78l.26.21zm6.36 5.51l-.21-.19zm-3.96-3.55l-.42-.35zm-11.6-8.43l.47.29zm4.68 3.09l.17.12zm-2-1.35l-.43-.29zm-9.71-5.68l-.1-.05zm-123.61 32.91c.1-.14.19-.28.28-.42-.04.14-.18.28-.28.42zm-1.45 2.28l.29-.46zm-1.31 2.25l.19-.32zm-2.6 4.77zm10.38-16.18l.21-.26zm2-2.43c-.12.13-.23.27-.35.41.08-.14.19-.28.31-.38zm-5.33 6.89l.1-.15zm-8.2 14.07c-.07.14-.13.29-.2.43.03-.14.09-.29.16-.43zm5.39 92l-.29-.46zm-4.27-7.53v.05zm2.82 5.14l-.19-.32zm2.61 4.21c.1.14.19.28.28.42-.08-.17-.22-.31-.32-.45zm-6.8-12.11c.07.14.13.29.2.43-.06-.14-.12-.29-.2-.43zm-2-76.7c0 .13-.1.25-.16.38.07-.13.16-.25.16-.38zm1.09-2.58c-.07.17-.15.34-.22.5.13-.16.13-.33.23-.5zm-.22 76.78c.07.16.15.33.22.5-.09-.17-.09-.34-.21-.5zm-1-2.46c.06.13.11.25.16.38-.03-.13-.12-.25-.18-.38zm172-84.19l.19.32zM327.51 320l.36-.4zm-1.57 1.71l-.19.21zM325.75 190l.19.21zm3.51 128c.12-.13.23-.27.35-.41-.12.17-.23.31-.35.41zm2-121.63l-.21-.26zm0 119.2l-.21.26zm-1.65-121.22c-.12-.14-.23-.28-.35-.41.12.16.23.3.35.44zm-1.74-2l-.36-.4zm6.62 8.35l.1.15zm.1 110.43l-.1.15zM398.49 53q2 1.41 4 2.85-2-1.43-4-2.85zM343.9 294.64c.07-.17.15-.34.22-.5-.07.16-.12.33-.22.5zm1.09-2.58c.05-.13.1-.25.16-.38-.06.13-.15.25-.15.38zm-3.35 7.36v-.05zm-5.4 9.3l-.28.42zm1.45-2.28l-.29.46zm1.35-2.25l-.19.32zm3.75-7.12c.07-.14.13-.29.2-.43-.07.14-.13.29-.2.43zM449 100.21q-1.41-1.75-2.85-3.46 1.39 1.71 2.85 3.46zM445.49 96c-1-1.18-2-2.35-3-3.51 1 1.19 2.01 2.36 3 3.51zm6.87 8.5q-1.36-1.74-2.76-3.5 1.4 1.76 2.76 3.53zm3.36 4.44c-.91-1.23-1.83-2.44-2.75-3.65.92 1.24 1.84 2.45 2.75 3.71zm-119.48 94.34l-.28-.42zm66.76-147q1.85 1.36 3.66 2.76-1.78-1.39-3.66-2.76zm12.23 9.62q-1.72-1.44-3.47-2.85 1.77 1.41 3.5 2.85zM411 62.4q-1.74-1.4-3.51-2.77Q409.24 61 411 62.4zm8.5 7.13q-1.74-1.53-3.51-3 1.75 1.47 3.49 3zm-75.38 148.33c-.07-.16-.15-.33-.22-.5.1.17.15.34.22.5zM184.49 192l-.36.4zM343 215.36c-.07-.14-.13-.29-.2-.43.06.14.12.29.2.43zm113.16-105.8c1 1.31 1.9 2.62 2.84 3.94-.95-1.32-1.89-2.63-2.85-3.94zM337.4 205.1l.29.46zm82.53-135.18a248.82 248.82 0 0 1 22.14 22.15 250.17 250.17 0 0 0-22.14-22.15zm-74.78 150.4a6.15 6.15 0 0 1-.16-.38c.01.13.1.25.16.38zM459 398.49a248 248 0 0 0 0-285L347 225.46a96.5 96.5 0 0 1 0 61.08zM341.67 212.63zM220.33 345.15l-.41-.17zm-2.46-1l-.52-.22zm-5.3-2.49l.1.05zM322 325.75l-.21.19zM309.14 336l-.43.29zm2-1.35l.17-.12zm4.48-3.34l.26-.21zm4-3.39l.4-.36zm-1.6 1.39l-.42.35zM215.38 343l-.46-.21zm-19-11.74l-.26-.21zm-4-3.39l-.4-.36zm-6.3-137.62l.19-.21zm4 135.5l.21.19zm15.52 11.94l-.47-.29zm2.26 1.35l-.34-.19zm78.72 8a96.5 96.5 0 0 1-61.08 0L113.51 459a248 248 0 0 0 285 0zM202.86 336l.43.29zm-2-1.35l-.17-.12zM416 445.49q1.77-1.49 3.51-3-1.77 1.51-3.51 3zm43-47c-.93 1.33-1.88 2.64-2.84 3.95.95-1.31 1.9-2.62 2.84-3.95zM411.79 449q1.74-1.41 3.47-2.85-1.72 1.39-3.47 2.85zm-4.32 3.42q1.77-1.38 3.51-2.77-1.74 1.35-3.51 2.72zM455.72 403q-1.37 1.85-2.76 3.66 1.4-1.78 2.76-3.66zm-10.23 13c-1 1.18-2 2.35-3 3.51 1-1.19 2.01-2.36 3-3.51zm3.46-4.18q-1.41 1.74-2.85 3.47 1.44-1.75 2.9-3.5zm.65-.81q1.39-1.74 2.77-3.51-1.37 1.74-2.77 3.5zm-150.17-69.38a.31.31 0 0 1-.1.05.31.31 0 0 0 .1-.05zm-5.3 2.49l.52-.22zm12.31-6.43l.47-.29zm-9.82 5.31l.46-.21zm7.56-4l.34-.19zm137.9 80.89a248.94 248.94 0 0 1-22.15 22.15 248.94 248.94 0 0 0 22.15-22.11zm-39.63 36.21q-2 1.44-4 2.85 2.04-1.37 4-2.81zM292.08 345l-.41.17zM403 455.72q1.85-1.37 3.66-2.76-1.78 1.4-3.66 2.76zM194 329.26l.42.35zM69.93 92.07a248.82 248.82 0 0 1 22.14-22.15 250.17 250.17 0 0 0-22.14 22.15zm30.28-29q-1.74 1.41-3.47 2.85 1.73-1.46 3.47-2.87zm90 123l-.21.19zm4.13-3.67l-.42.35zM109.55 55.86q2-1.44 4-2.85-2.03 1.41-4 2.85zM196.14 181l.26-.21zM104.53 59.63Q102.76 61 101 62.4q1.76-1.4 3.53-2.77zm.78-.59q1.81-1.4 3.66-2.76-1.84 1.37-3.66 2.72zm87.05 125.09l-.4.36zm22.56-14.92l.46-.21zm-2.25 1.11l-.1.05zm4.68-2.22l.52-.22zm2.57-1.08l.41-.17zm-17.06 9l.43-.29zm5-3.09l-.34.19zm-7.11 4.56l.17-.12zm4.38-2.92l.47-.29zM96.74 446.1q1.73 1.44 3.47 2.85-1.74-1.41-3.47-2.85zm-33.69-34.31q1.41 1.74 2.85 3.47-1.44-1.72-2.85-3.47zm3.46 4.21c1 1.18 2 2.35 3 3.51-1-1.19-2.01-2.36-3-3.51zm-10.23-13q1.36 1.85 2.76 3.66-1.39-1.78-2.76-3.66zm3.35 4.44q1.37 1.8 2.77 3.56-1.4-1.76-2.77-3.53zm32.89 35q1.74 1.53 3.51 3-1.77-1.44-3.51-2.97zM105.31 453q1.81 1.4 3.66 2.76-1.84-1.4-3.66-2.76zm8.2 6q-2-1.41-4-2.85 2.01 1.43 4 2.85zM101 449.6q1.74 1.39 3.51 2.77-1.75-1.37-3.51-2.77zm-45.15-47.16c-1-1.31-1.9-2.62-2.84-3.95.99 1.33 1.88 2.64 2.84 3.95zM65.9 96.75q-1.44 1.71-2.85 3.46 1.41-1.75 2.85-3.46zM56.29 109c.9-1.23 1.82-2.45 2.74-3.65-.92 1.17-1.84 2.39-2.74 3.65zm6.11-8q-1.4 1.74-2.76 3.51Q61 102.76 62.4 101zm7.12-8.5c-1 1.16-2 2.33-3 3.51.98-1.16 1.99-2.33 3-3.49zm23-23q1.74-1.53 3.51-3-1.77 1.5-3.51 3.03zm-.45 372.55a248.94 248.94 0 0 1-22.15-22.15 248.94 248.94 0 0 0 22.15 22.18zM165 286.54a96.5 96.5 0 0 1 0-61.08L53 113.51a248 248 0 0 0 0 285zm-109.11-177q-1.44 2-2.84 3.93 1.36-1.95 2.8-3.9z\", \"M347 225.46l112-111.95A249.4 249.4 0 0 0 398.49 53L286.54 165A96.26 96.26 0 0 1 347 225.46zm-182 61.08l-112 112a249.4 249.4 0 0 0 60.5 60.5L225.46 347A96.26 96.26 0 0 1 165 286.54zm-112-173l112 112a96.26 96.26 0 0 1 60.5-60.5L113.51 53A249.4 249.4 0 0 0 53 113.51zM286.54 347l112 112a249.4 249.4 0 0 0 60.5-60.5L347 286.54A96.26 96.26 0 0 1 286.54 347z\"]],\n    \"lightbulb\": [352, 512, [], \"f0eb\", [\"M175.45 0C73.44.31 0 83 0 176a175 175 0 0 0 43.56 115.78c16.52 18.85 42.36 58.22 52.21 91.45 0 .26.07.52.11.78h160.24c0-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45A175.9 175.9 0 0 0 175.45 0zm.55 96a80.09 80.09 0 0 0-80 80 16 16 0 0 1-32 0A112.12 112.12 0 0 1 176 64a16 16 0 0 1 0 32z\", \"M96.06 454.35L96 416h160v38.35a32 32 0 0 1-5.41 17.65l-17.09 25.73A32 32 0 0 1 206.86 512h-61.71a32 32 0 0 1-26.64-14.28L101.42 472a32 32 0 0 1-5.36-17.65z\"]],\n    \"list-alt\": [512, 512, [], \"f022\", [\"M464 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zM128 392a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm288 168a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12z\", \"M128 200a40 40 0 1 0-40-40 40 40 0 0 0 40 40zm0 16a40 40 0 1 0 40 40 40 40 0 0 0-40-40zm0 96a40 40 0 1 0 40 40 40 40 0 0 0-40-40z\"]],\n    \"list-ul\": [512, 512, [], \"f0ca\", [\"M496 384H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48z\"]],\n    \"lock-alt\": [448, 512, [], \"f30d\", [\"M152 225H72v-72C72 69.2 140.2 1 224 1s152 68.2 152 152v72h-80v-72a72 72 0 0 0-144 0z\", \"M400 225H48a48 48 0 0 0-48 48v192a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V273a48 48 0 0 0-48-48zM264 392a40 40 0 0 1-80 0v-48a40 40 0 0 1 80 0z\"]],\n    \"map-marker-alt\": [384, 512, [], \"f3c5\", [\"M192 0C86 0 0 86 0 192c0 77.41 27 99 172.27 309.67a24 24 0 0 0 39.46 0C357 291 384 269.41 384 192 384 86 298 0 192 0zm0 288a96 96 0 1 1 96-96 96 96 0 0 1-96 96z\", \"M192 256a64 64 0 1 1 64-64 64 64 0 0 1-64 64z\"]],\n    \"moon-stars\": [512, 512, [], \"f755\", [\"M320 32L304 0l-16 32-32 16 32 16 16 32 16-32 32-16zm138.7 149.3L432 128l-26.7 53.3L352 208l53.3 26.7L432 288l26.7-53.3L512 208z\", \"M332.2 426.4c8.1-1.6 13.9 8 8.6 14.5a191.18 191.18 0 0 1-149 71.1C85.8 512 0 426 0 320c0-120 108.7-210.6 227-188.8 8.2 1.6 10.1 12.6 2.8 16.7a150.3 150.3 0 0 0-76.1 130.8c0 94 85.4 165.4 178.5 147.7z\"]],\n    \"network-wired\": [640, 512, [], \"f6ff\", [\"M624 232H344v-40h-48v40H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h104v40h48v-40h304v40h48v-40h104a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z\", \"M224 192h192a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32H224a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32zm32-128h128v64H256zm320 256H416a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128h-96v-64h96zM224 320H64a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128H96v-64h96z\"]],\n    \"planet-ringed\": [512, 512, [], \"e020\", [\"M323.33815,323.33517C186.95939,459.71018,46.2602,540.11093,9.06777,502.9165c-23.48893-23.4909.01172-88.30917,54.81792-167.21379a206.56361,206.56361,0,0,0,25.02022,43.78446c-22.45765,34.20607-32.036,58.99194-23.71941,67.31053,18.59817,18.59624,119.10094-51.75539,224.47885-157.13342C395.04325,184.2882,465.39675,83.78336,446.79858,65.18712c-8.32054-8.3186-33.10638,1.26176-67.31045,23.71748a206.52984,206.52984,0,0,0-43.78245-25.0183C414.61019,9.082,479.42839-14.42259,502.91732,9.06832,540.10975,46.2608,459.70909,186.96211,323.33815,323.33517Z\", \"M448.0994,176.28016c-31.96573,46.02281-74.52549,96.81528-124.76125,147.055-50.24357,50.24168-101.034,92.79954-147.05874,124.76531,75.41614,31.25675,165.47721,16.29343,226.79531-45.02474S479.35807,251.69834,448.0994,176.28016Zm-25.02022-43.78251A208.22535,208.22535,0,0,0,403.07472,108.911c-81.2288-81.23281-212.93555-81.23281-294.16435,0-81.22881,81.23085-81.22881,212.93385,0,294.1647A208.25527,208.25527,0,0,0,132.497,423.08023c42.25117-27.73908,98.93242-75.1799,157.1684-133.41595C347.90133,231.43018,395.34013,174.75473,423.07918,132.49765Z\"]],\n    \"question-circle\": [512, 512, [], \"f059\", [\"M256 8C119 8 8 119.08 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 422a46 46 0 1 1 46-46 46.05 46.05 0 0 1-46 46zm40-131.33V300a12 12 0 0 1-12 12h-56a12 12 0 0 1-12-12v-4c0-41.06 31.13-57.47 54.65-70.66 20.17-11.31 32.54-19 32.54-34 0-19.82-25.27-33-45.7-33-27.19 0-39.44 13.14-57.3 35.79a12 12 0 0 1-16.67 2.13L148.82 170a12 12 0 0 1-2.71-16.26C173.4 113 208.16 90 262.66 90c56.34 0 116.53 44 116.53 102 0 77-83.19 78.21-83.19 106.67z\", \"M256 338a46 46 0 1 0 46 46 46 46 0 0 0-46-46zm6.66-248c-54.5 0-89.26 23-116.55 63.76a12 12 0 0 0 2.71 16.24l34.7 26.31a12 12 0 0 0 16.67-2.13c17.86-22.65 30.11-35.79 57.3-35.79 20.43 0 45.7 13.14 45.7 33 0 15-12.37 22.66-32.54 34C247.13 238.53 216 254.94 216 296v4a12 12 0 0 0 12 12h56a12 12 0 0 0 12-12v-1.33c0-28.46 83.19-29.67 83.19-106.67 0-58-60.19-102-116.53-102z\"]],\n    \"quote-left\": [512, 512, [], \"f10d\", [\"M464 256h-80v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H448a160 160 0 0 0-160 160v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\", \"M176 256H96v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H160A160 160 0 0 0 0 192v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\"]],\n    \"random\": [512, 512, [], \"f074\", [\"M505 359l-80-80c-15-15-41-4.47-41 17v40h-32l-52.78-56.55-53.33 57.14 70.55 75.6a12 12 0 0 0 8.77 3.81H384v40c0 21.46 26 32 41 17l80-80a24 24 0 0 0 0-34zM122.79 96H12a12 12 0 0 0-12 12v56a12 12 0 0 0 12 12h84l52.78 56.55 53.33-57.14-70.55-75.6a12 12 0 0 0-8.77-3.81z\", \"M505 119a24 24 0 0 1 0 34l-80 80c-15 15-41 4.48-41-17v-40h-32L131.56 412.19a12 12 0 0 1-8.77 3.81H12a12 12 0 0 1-12-12v-56a12 12 0 0 1 12-12h84L316.44 99.81a12 12 0 0 1 8.78-3.81H384V56c0-21.44 25.94-32 41-17z\"]],\n    \"rocket\": [512, 512, [], \"f135\", [\"M51.94117,154.48438,2.531,253.29688A28.125,28.125,0,0,0-.00023,264a24.00619,24.00619,0,0,0,24,24H117.4607c23.44141-47.41211,61.01172-123.373,77.89063-157.32812.51953-.91407,1-1.76758,1.52344-2.67188H94.82008C78.47633,128.01562,59.28883,139.875,51.94117,154.48438Zm172.0586,240.1621V488.209A24.12394,24.12394,0,0,0,247.9607,512a28.02965,28.02965,0,0,0,10.625-2.53125l98.72657-49.39063c14.625-7.3125,26.5-26.5,26.5-42.85937V315.70312c.0664-.041.125-.08789.1875-.1289v-.52734c-.90625.51953-1.7461,1.002-2.66407,1.52539C347.37477,333.58008,271.2732,371.252,223.99977,394.64648Z\", \"M505.15992,19.51562A16.73971,16.73971,0,0,0,492.62477,6.94531C460.22633,0,434.37477,0,409.48414,0,320.3357,0,252.80836,40.61523,196.97633,127.81836c-.5586.97852-1.07031,1.877-1.625,2.85352-19.59766,39.42578-67.20313,135.70312-88.04688,177.877a31.91421,31.91421,0,0,0,6.09766,36.76172L167.05445,398.709a31.88923,31.88923,0,0,0,36.64844,5.98047l14.17578-7.01367c46.57422-23.04883,128.06641-63.3789,163.457-81.10351.96094-.54883,1.832-1.04883,2.78907-1.59766,87.23437-56.06055,127.85937-123.51172,127.85937-212.27734C512.06227,77.60742,512.12867,52.08789,505.15992,19.51562ZM367.99977,192a48,48,0,1,1,48-48.00195A48.02156,48.02156,0,0,1,367.99977,192Z\"]],\n    \"search\": [512, 512, [], \"f002\", [\"M208 80a128 128 0 1 1-90.51 37.49A127.15 127.15 0 0 1 208 80m0-80C93.12 0 0 93.12 0 208s93.12 208 208 208 208-93.12 208-208S322.88 0 208 0z\", \"M504.9 476.7L476.6 505a23.9 23.9 0 0 1-33.9 0L343 405.3a24 24 0 0 1-7-17V372l36-36h16.3a24 24 0 0 1 17 7l99.7 99.7a24.11 24.11 0 0 1-.1 34z\"]],\n    \"server\": [512, 512, [], \"f233\", [\"M432 120a24 24 0 1 0-24-24 24 24 0 0 0 24 24zm0 272a24 24 0 1 0 24 24 24 24 0 0 0-24-24zm48-200H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\", \"M456 256a24 24 0 1 0-24 24 24 24 0 0 0 24-24zm24-224H32A32 32 0 0 0 0 64v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm48 232H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\"]],\n    \"sign-out\": [512, 512, [], \"f08b\", [\"M180 448H96a96 96 0 0 1-96-96V160a96 96 0 0 1 96-96h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12H96a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12z\", \"M353 88.3l151.9 150.6a24 24 0 0 1 0 34.1l-152 150.8a24.08 24.08 0 0 1-33.9-.1l-21.9-21.9a24.07 24.07 0 0 1 .8-34.7l77.6-71.1H184a23.94 23.94 0 0 1-24-24v-32a23.94 23.94 0 0 1 24-24h191.5l-77.6-71.1a24 24 0 0 1-.7-34.6l21.9-21.9a24 24 0 0 1 33.9-.1z\"]],\n    \"siren-on\": [640, 512, [], \"e02e\", [\"M224.21,134.94a8,8,0,0,1,9-6.87l15.86,2.13a8,8,0,0,1,6.87,9L231.82,320H496L471,120.06A64,64,0,0,0,407.5,64h-175A64,64,0,0,0,169,120.06L144,320h55.54Z\", \"M528,352H112a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16H528a16,16,0,0,0,16-16V368A16,16,0,0,0,528,352ZM112,192a24,24,0,0,0-24-24H24a24,24,0,0,0,0,48H88A24,24,0,0,0,112,192Zm504-24H552a24,24,0,0,0,0,48h64a24,24,0,0,0,0-48ZM90.69,76a24,24,0,1,0,26.62-39.92l-48-32A24,24,0,1,0,42.69,44ZM536,80a23.87,23.87,0,0,0,13.29-4l48-32A24,24,0,1,0,570.69,4.06l-48,32A24,24,0,0,0,536,80Z\"]],\n    \"smile\": [496, 512, [], \"f118\", [\"M248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256,385,8,248,8Zm80,168a32,32,0,1,1-32,32A32,32,0,0,1,328,176Zm-160,0a32,32,0,1,1-32,32A32,32,0,0,1,168,176ZM362.8,346.2a149.38,149.38,0,0,1-229.6,0c-13.6-16.3,11-36.7,24.6-20.5a117.5,117.5,0,0,0,180.4,0C351.6,309.5,376.3,329.9,362.8,346.2Z\", \"M328,176a32,32,0,1,0,32,32A32,32,0,0,0,328,176Zm-160,0a32,32,0,1,0,32,32A32,32,0,0,0,168,176Z\"]],\n    \"snowman\": [512, 512, [], \"f7d0\", [\"M363.76 268.8a108.77 108.77 0 0 0 4.2-28.7v-.1a112.68 112.68 0 0 0-.73-12.8c-.11-1-.24-2-.38-3-.29-2-.62-4-1-6-.2-1-.4-1.95-.62-2.92-.22-1-.45-1.93-.7-2.9-.24-1-.5-1.91-.77-2.85-.27-.95-.55-1.89-.84-2.83-.3-.94-.6-1.87-.92-2.8-.32-.93-.65-1.86-1-2.77-.34-.92-.69-1.83-1.06-2.74-.36-.9-.74-1.8-1.13-2.7-.39-.89-.79-1.78-1.19-2.66-.41-.88-.83-1.76-1.26-2.63q-1.31-2.62-2.73-5.16c-.48-.85-1-1.68-1.46-2.51a112.44 112.44 0 0 0-21.62-26.19 96 96 0 1 0-149.16 0 112.49 112.49 0 0 0-21.68 26.28q-.74 1.23-1.44 2.49c-.48.84-.94 1.69-1.39 2.54-.45.85-.89 1.7-1.32 2.57-.43.87-.85 1.74-1.25 2.62-.41.88-.8 1.76-1.19 2.66-.39.89-.76 1.79-1.12 2.69-.36.91-.71 1.82-1.05 2.74-.34.92-.67 1.84-1 2.76a111.63 111.63 0 0 0-5.22 23.28A113 113 0 0 0 144 240h.06v.1a110.27 110.27 0 0 0 4.2 28.9A151.18 151.18 0 0 0 104 376.1c0 54 28.4 100.9 70.8 127.8 9.3 5.9 20.3 8.2 31.3 8.2h99.2a65.1 65.1 0 0 0 37.2-11.7c46.5-32.3 74.4-89.4 62.9-152.6-5.54-30.2-20.54-57.6-41.64-79zM224 96.1a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm32 272a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm0-64a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm1.7-64.1a15.19 15.19 0 0 1-3.48 0 16 16 0 1 1 3.48 0zm-1.7-87.9s-16-23.2-16-32a16 16 0 1 1 32 0c0 8.8-16 32-16 32zm32-56a16 16 0 1 1 16-16 16 16 0 0 1-16 16z\", \"M510.86 152.4L505 137.9a16.15 16.15 0 0 0-20.8-8.7L456 140.7v-29a15.84 15.84 0 0 0-16-15.6h-16a15.84 15.84 0 0 0-16 15.6v46.9c0 .5.3 1 .3 1.5l-56.1 22.54a111.21 111.21 0 0 1 15.07 44.56L502 172.7a15.57 15.57 0 0 0 8.86-20.3zm-407.1 6.2v-46.9c.2-8.6-7-15.6-15.8-15.6H72a15.84 15.84 0 0 0-16 15.6v29l-28.1-11.5a16.15 16.15 0 0 0-20.8 8.7l-5.9 14.5a15.48 15.48 0 0 0 8.9 20.3l134.67 54.49a111.3 111.3 0 0 1 15-44.46l-56.31-22.63a8 8 0 0 0 .3-1.5zM256 336.1a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16z\"]],\n    \"sun\": [512, 512, [], \"f185\", [\"M502.42 240.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.41-94.8a17.31 17.31 0 0 0-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4a17.31 17.31 0 0 0 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.41-33.5 47.3 94.7a17.31 17.31 0 0 0 31 0l47.31-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3a17.33 17.33 0 0 0 .2-31.1zm-155.9 106c-49.91 49.9-131.11 49.9-181 0a128.13 128.13 0 0 1 0-181c49.9-49.9 131.1-49.9 181 0a128.13 128.13 0 0 1 0 181z\", \"M352 256a96 96 0 1 1-96-96 96.15 96.15 0 0 1 96 96z\"]],\n    \"tasks\": [512, 512, [], \"f0ae\", [\"M496 384H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M139.61 35.5a12 12 0 0 0-17 0L58.93 98.81l-22.7-22.12a12 12 0 0 0-17 0L3.53 92.41a12 12 0 0 0 0 17l47.59 47.4a12.78 12.78 0 0 0 17.61 0l15.59-15.62L156.52 69a12.09 12.09 0 0 0 .09-17zm0 159.19a12 12 0 0 0-17 0l-63.68 63.72-22.7-22.1a12 12 0 0 0-17 0L3.53 252a12 12 0 0 0 0 17L51 316.5a12.77 12.77 0 0 0 17.6 0l15.7-15.69 72.2-72.22a12 12 0 0 0 .09-16.9zM64 368c-26.49 0-48.59 21.5-48.59 48S37.53 464 64 464a48 48 0 0 0 0-96z\"]],\n    \"university\": [512, 512, [], \"f19c\", [\"M160,192V384h64V192h64V384h64V192h64V384h36a12,12,0,0,1,12,12v20H48V396a12,12,0,0,1,12-12H96V192Z\", \"M491.06,120.61l-232-88a8,8,0,0,0-6.12,0l-232,88A8,8,0,0,0,16,128v16a8,8,0,0,0,8,8H48v12a12,12,0,0,0,12,12H452a12,12,0,0,0,12-12V152h24a8,8,0,0,0,8-8V128A8,8,0,0,0,491.06,120.61ZM472,432H40a24,24,0,0,0-24,24v16a8,8,0,0,0,8,8H488a8,8,0,0,0,8-8V456A24,24,0,0,0,472,432Z\"]],\n    \"user\": [448, 512, [], \"f007\", [\"M352 128A128 128 0 1 1 224 0a128 128 0 0 1 128 128z\", \"M313.6 288h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48v-41.6A134.43 134.43 0 0 0 313.6 288z\"]],\n    \"user-hard-hat\": [448, 512, [], \"f82c\", [\"M97.61 208h252.78c-7.95 63.06-61.17 112-126.39 112S105.56 271.06 97.61 208z\", \"M313.6 352h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.4 134.4 0 0 0 0 486.4 25.6 25.6 0 0 0 25.6 512h396.8a25.6 25.6 0 0 0 25.6-25.6A134.4 134.4 0 0 0 313.6 352zM88 176h272a8 8 0 0 0 8-8v-32a8 8 0 0 0-8-8h-8a112 112 0 0 0-68.4-103.2L256 80V16a16 16 0 0 0-16-16h-32a16 16 0 0 0-16 16v64l-27.6-55.2A112 112 0 0 0 96 128h-8a8 8 0 0 0-8 8v32a8 8 0 0 0 8 8z\"]],\n    \"user-shield\": [640, 512, [], \"f505\", [\"M622.3 271.1l-115.2-45a31 31 0 0 0-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9a31 31 0 0 0 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8z\", \"M224 256A128 128 0 1 0 96 128a128 128 0 0 0 128 128zm96 40c0-2.5.8-4.8 1.1-7.2-2.5-.1-4.9-.8-7.5-.8h-16.7a174.08 174.08 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a49.22 49.22 0 0 0 19.2-4c-54-42.9-99.2-116.7-99.2-212z\"]],\n    \"users\": [640, 512, [], \"f0c0\", [\"M96 224a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64zm480 32h-64a63.81 63.81 0 0 0-45.1 18.6A146.27 146.27 0 0 1 542 384h66a32 32 0 0 0 32-32v-32a64.06 64.06 0 0 0-64-64zm-512 0a64.06 64.06 0 0 0-64 64v32a32 32 0 0 0 32 32h65.9a146.64 146.64 0 0 1 75.2-109.4A63.81 63.81 0 0 0 128 256zm480-32a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64z\", \"M396.8 288h-8.3a157.53 157.53 0 0 1-68.5 16c-24.6 0-47.6-6-68.5-16h-8.3A115.23 115.23 0 0 0 128 403.2V432a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48v-28.8A115.23 115.23 0 0 0 396.8 288zM320 256a112 112 0 1 0-112-112 111.94 111.94 0 0 0 112 112z\"]]\n  };\n\n  bunker(function () {\n    defineIcons('fad', icons);\n  });\n\n}());\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"check-circle\": [512, 512, [], \"f058\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z\"],\n    \"desktop\": [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v288c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V54c0-3.3 2.7-6 6-6h468c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-42 152c0 13.3-10.7 24-24 24H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h98.7l18.6-55.8c1.6-4.9 6.2-8.2 11.4-8.2h78.7c5.2 0 9.8 3.3 11.4 8.2l18.6 55.8H456c13.3 0 24 10.7 24 24z\"],\n    \"eye\": [576, 512, [], \"f06e\", \"M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z\"],\n    \"file-code\": [384, 512, [], \"f1c9\", \"M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z\"],\n    \"info\": [256, 512, [], \"f129\", \"M224 352.589V224c0-16.475-6.258-31.517-16.521-42.872C225.905 161.14 236 135.346 236 108 236 48.313 187.697 0 128 0 68.313 0 20 48.303 20 108c0 20.882 5.886 40.859 16.874 58.037C15.107 176.264 0 198.401 0 224v39.314c0 23.641 12.884 44.329 32 55.411v33.864C12.884 363.671 0 384.359 0 408v40c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-40c0-23.641-12.884-44.329-32-55.411zM128 48c33.137 0 60 26.863 60 60s-26.863 60-60 60-60-26.863-60-60 26.863-60 60-60zm80 400c0 8.836-7.164 16-16 16H64c-8.836 0-16-7.164-16-16v-40c0-8.836 7.164-16 16-16h16V279.314H64c-8.836 0-16-7.164-16-16V224c0-8.836 7.164-16 16-16h96c8.836 0 16 7.164 16 16v168h16c8.836 0 16 7.164 16 16v40z\"],\n    \"info-circle\": [512, 512, [], \"f05a\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm0-338c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"],\n    \"plus\": [384, 512, [], \"f067\", \"M368 224H224V80c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h144v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V288h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"],\n    \"question-circle\": [512, 512, [], \"f059\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z\"],\n    \"rocket\": [512, 512, [], \"f135\", \"M367.96813,103.99609a39.999,39.999,0,1,0,40.00384,40A40.02908,40.02908,0,0,0,367.96813,103.99609ZM505.07337,19.3418c-1.21875-5.60742-6.75-11.13868-12.34373-12.3418-32.62885-7-58.162-7-83.57017-7C305.39988,0,242.95858,55.0918,196.236,127.99609H94.82015c-16.34567.01563-35.53314,11.875-42.87883,26.48243L2.53125,253.28906A28.12512,28.12512,0,0,0,0,263.99219a24.00617,24.00617,0,0,0,24.00191,23.998h92.63266l-10.59373,21.42188c-9.33592,18.91016,4.27733,34.77344,6.15624,36.62305l53.75381,53.71875c15.56443,15.54492,33.81635,7.52929,36.6601,6.13867l21.34567-10.57617V488a24.00659,24.00659,0,0,0,24.00191,24,28.618,28.618,0,0,0,10.71873-2.51562l98.6971-49.4043c14.625-7.29688,26.50191-26.5,26.50191-42.85938V315.69336c72.72449-46.76367,128.10525-109.44922,128.10525-212.69727C512.07531,77.4668,512.07531,51.99805,505.07337,19.3418ZM358.53065,274.99023c-36.94135,18.48438-121.10527,60.14063-166.7966,82.73243l-37.50189-37.49805c22.59567-45.6875,64.25575-129.99609,82.72447-166.88672C284.33741,79.5293,335.96623,47.99805,409.15947,47.99805c18.00192,0,34.2851,0,52.56632,2.34375,2.375,18.71875,2.31249,35.27929,2.25,52.63867C463.97578,175.75977,432.41138,227.30469,358.53065,274.99023Z\"],\n    \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z\"],\n    \"slash\": [640, 512, [], \"f715\", \"M604 508.49L6.01 40.98c-6.9-5.52-8.02-15.59-2.49-22.49L13.51 6C19.03-.9 29.1-2.01 36 3.51l598 467.51c6.9 5.52 8.02 15.59 2.49 22.49l-10 12.49c-5.52 6.9-15.59 8.01-22.49 2.49z\"],\n    \"times\": [320, 512, [], \"f00d\", \"M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z\"],\n    \"undo\": [512, 512, [], \"f0e2\", \"M12 8h27.711c6.739 0 12.157 5.548 11.997 12.286l-2.347 98.568C93.925 51.834 170.212 7.73 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.835 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.322 0 196-87.662 196-196 0-108.322-87.662-196-196-196-79.545 0-147.941 47.282-178.675 115.302l126.389-3.009c6.737-.16 12.286 5.257 12.286 11.997V212c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V20C0 13.373 5.373 8 12 8z\"],\n    \"undo-alt\": [512, 512, [], \"f2ea\", \"M28.485 28.485L80.65 80.65C125.525 35.767 187.515 8 255.999 8 392.66 8 504.1 119.525 504 256.185 503.9 393.067 392.905 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.353-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.321 0 196-87.662 196-196 0-108.321-87.662-196-196-196-54.163 0-103.157 21.923-138.614 57.386l54.128 54.129c7.56 7.56 2.206 20.485-8.485 20.485H20c-6.627 0-12-5.373-12-12V36.971c0-10.691 12.926-16.045 20.485-8.486z\"],\n    \"user\": [448, 512, [], \"f007\", \"M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z\"],\n    \"user-friends\": [640, 512, [], \"f500\", \"M480 256c53 0 96-43 96-96s-43-96-96-96-96 43-96 96 43 96 96 96zm0-144c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM272.1 276c-11.9 0-23.9 1.7-35.5 5.3-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-11.6-3.5-23.6-5.3-35.5-5.3-36.3 0-71.6 16.2-92.3 46.9C7.2 341.3 0 363.4 0 387.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM336 432H48v-44.8c0-28.9 18.4-53.6 44.1-63.1 10.3-3.8 21.6-3.7 31.9 0 22.1 7.9 45 11.9 68 11.9s45.8-4 68.1-11.9c10.3-3.7 21.6-3.8 31.9 0 25.7 9.4 44.1 34.2 44.1 63.1V432zM192 256c61.9 0 112-50.1 112-112S253.9 32 192 32 80 82.1 80 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm431.7 237.1C606.4 291.5 577 278 546.8 278c-27.8 0-34.8 10-66.8 10s-39-10-66.8-10c-13.3 0-26.2 3-38.2 8.1 5.8 5.9 11.3 12 16 18.9 4.7 7 8.6 14.4 12 22 3.3-.7 6.7-1.1 10.2-1.1 17.2 0 29.6 10 66.8 10 37.4 0 49.5-10 66.8-10 15.7 0 29.5 6.7 37.1 17.9 5.3 7.9 8.1 17.1 8.1 26.7V400H416v32c0 5.5-.6 10.8-1.6 16H600c22.1 0 40-17.9 40-40v-37.3c0-19.9-6-38.3-16.3-53.6z\"],\n    \"users\": [640, 512, [], \"f0c0\", \"M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zm396.4 210.9c-27.5-40.8-80.7-56-127.8-41.7-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-47.1-14.3-100.3.8-127.8 41.7-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c.2-23.8-7-45.9-19.4-64.3zM464 432H176v-44.8c0-36.4 29.2-66.2 65.4-67.2 25.5 10.6 51.9 16 78.6 16 26.7 0 53.1-5.4 78.6-16 36.2 1 65.4 30.7 65.4 67.2V432zm92-176h-24c-17.3 0-33.4 5.3-46.8 14.3 13.4 10.1 25.2 22.2 34.4 36.2 3.9-1.4 8-2.5 12.3-2.5h24c19.8 0 36 16.2 36 36 0 13.2 10.8 24 24 24s24-10.8 24-24c.1-46.3-37.6-84-83.9-84zm-236 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM154.8 270.3c-13.4-9-29.5-14.3-46.8-14.3H84c-46.3 0-84 37.7-84 84 0 13.2 10.8 24 24 24s24-10.8 24-24c0-19.8 16.2-36 36-36h24c4.4 0 8.5 1.1 12.3 2.5 9.3-14 21.1-26.1 34.5-36.2z\"]\n  };\n\n  bunker(function () {\n    defineIcons('far', icons);\n  });\n\n}());\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"alarm-exclamation\": [512, 512, [], \"f843\", \"M96 0A96 96 0 0 0 0 96a94.81 94.81 0 0 0 15.3 51.26L161.2 25.68A95.63 95.63 0 0 0 96 0zm320 0a95.66 95.66 0 0 0-65.18 25.66l145.89 121.57A94.85 94.85 0 0 0 512 96a96 96 0 0 0-96-96zM256 64C132.3 64 32 164.29 32 288a222.7 222.7 0 0 0 44.79 134l-40.1 40.09a16 16 0 0 0 0 22.63l22.62 22.62a16 16 0 0 0 22.63 0L122 467.22a222.82 222.82 0 0 0 268 0l40.1 40.09a16 16 0 0 0 22.62 0l22.63-22.62a16 16 0 0 0 0-22.63L435.25 422A222.69 222.69 0 0 0 480 288c0-123.71-100.26-224-224-224zm0 352a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm25.4-110.4a16 16 0 0 1-15.9 14.4h-19a16 16 0 0 1-15.9-14.4l-12.8-128a16.06 16.06 0 0 1 15.9-17.6h44.6a16 16 0 0 1 15.9 17.6z\"],\n    \"align-left\": [448, 512, [], \"f036\", \"M12.83 352h262.34A12.82 12.82 0 0 0 288 339.17v-38.34A12.82 12.82 0 0 0 275.17 288H12.83A12.82 12.82 0 0 0 0 300.83v38.34A12.82 12.82 0 0 0 12.83 352zm0-256h262.34A12.82 12.82 0 0 0 288 83.17V44.83A12.82 12.82 0 0 0 275.17 32H12.83A12.82 12.82 0 0 0 0 44.83v38.34A12.82 12.82 0 0 0 12.83 96zM432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"],\n    \"book-dead\": [448, 512, [], \"f6b7\", \"M272 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm176 222.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM240 56c44.2 0 80 28.7 80 64 0 20.9-12.7 39.2-32 50.9V184c0 8.8-7.2 16-16 16h-64c-8.8 0-16-7.2-16-16v-13.1c-19.3-11.7-32-30-32-50.9 0-35.3 35.8-64 80-64zM124.8 223.3l6.3-14.7c1.7-4.1 6.4-5.9 10.5-4.2l98.3 42.1 98.4-42.1c4.1-1.7 8.8.1 10.5 4.2l6.3 14.7c1.7 4.1-.1 8.8-4.2 10.5L280.6 264l70.3 30.1c4.1 1.7 5.9 6.4 4.2 10.5l-6.3 14.7c-1.7 4.1-6.4 5.9-10.5 4.2L240 281.4l-98.3 42.2c-4.1 1.7-8.8-.1-10.5-4.2l-6.3-14.7c-1.7-4.1.1-8.8 4.2-10.5l70.4-30.1-70.5-30.3c-4.1-1.7-5.9-6.4-4.2-10.5zm256 224.7H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8zM208 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16z\"],\n    \"check\": [512, 512, [], \"f00c\", \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"],\n    \"circle\": [512, 512, [], \"f111\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"],\n    \"cloud\": [640, 512, [], \"f0c2\", \"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z\"],\n    \"credit-card\": [576, 512, [], \"f09d\", \"M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z\"],\n    \"desktop\": [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z\"],\n    \"envelope\": [512, 512, [], \"f0e0\", \"M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z\"],\n    \"eye\": [576, 512, [], \"f06e\", \"M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z\"],\n    \"fingerprint\": [512, 512, [], \"f577\", \"M256.12 245.96c-13.25 0-24 10.74-24 24 1.14 72.25-8.14 141.9-27.7 211.55-2.73 9.72 2.15 30.49 23.12 30.49 10.48 0 20.11-6.92 23.09-17.52 13.53-47.91 31.04-125.41 29.48-224.52.01-13.25-10.73-24-23.99-24zm-.86-81.73C194 164.16 151.25 211.3 152.1 265.32c.75 47.94-3.75 95.91-13.37 142.55-2.69 12.98 5.67 25.69 18.64 28.36 13.05 2.67 25.67-5.66 28.36-18.64 10.34-50.09 15.17-101.58 14.37-153.02-.41-25.95 19.92-52.49 54.45-52.34 31.31.47 57.15 25.34 57.62 55.47.77 48.05-2.81 96.33-10.61 143.55-2.17 13.06 6.69 25.42 19.76 27.58 19.97 3.33 26.81-15.1 27.58-19.77 8.28-50.03 12.06-101.21 11.27-152.11-.88-55.8-47.94-101.88-104.91-102.72zm-110.69-19.78c-10.3-8.34-25.37-6.8-33.76 3.48-25.62 31.5-39.39 71.28-38.75 112 .59 37.58-2.47 75.27-9.11 112.05-2.34 13.05 6.31 25.53 19.36 27.89 20.11 3.5 27.07-14.81 27.89-19.36 7.19-39.84 10.5-80.66 9.86-121.33-.47-29.88 9.2-57.88 28-80.97 8.35-10.28 6.79-25.39-3.49-33.76zm109.47-62.33c-15.41-.41-30.87 1.44-45.78 4.97-12.89 3.06-20.87 15.98-17.83 28.89 3.06 12.89 16 20.83 28.89 17.83 11.05-2.61 22.47-3.77 34-3.69 75.43 1.13 137.73 61.5 138.88 134.58.59 37.88-1.28 76.11-5.58 113.63-1.5 13.17 7.95 25.08 21.11 26.58 16.72 1.95 25.51-11.88 26.58-21.11a929.06 929.06 0 0 0 5.89-119.85c-1.56-98.75-85.07-180.33-186.16-181.83zm252.07 121.45c-2.86-12.92-15.51-21.2-28.61-18.27-12.94 2.86-21.12 15.66-18.26 28.61 4.71 21.41 4.91 37.41 4.7 61.6-.11 13.27 10.55 24.09 23.8 24.2h.2c13.17 0 23.89-10.61 24-23.8.18-22.18.4-44.11-5.83-72.34zm-40.12-90.72C417.29 43.46 337.6 1.29 252.81.02 183.02-.82 118.47 24.91 70.46 72.94 24.09 119.37-.9 181.04.14 246.65l-.12 21.47c-.39 13.25 10.03 24.31 23.28 24.69.23.02.48.02.72.02 12.92 0 23.59-10.3 23.97-23.3l.16-23.64c-.83-52.5 19.16-101.86 56.28-139 38.76-38.8 91.34-59.67 147.68-58.86 69.45 1.03 134.73 35.56 174.62 92.39 7.61 10.86 22.56 13.45 33.42 5.86 10.84-7.62 13.46-22.59 5.84-33.43z\"],\n    \"history\": [512, 512, [], \"f1da\", \"M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z\"],\n    \"home\": [576, 512, [], \"f015\", \"M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z\"],\n    \"plus\": [448, 512, [], \"f067\", \"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"],\n    \"robot\": [640, 512, [], \"f544\", \"M32,224H64V416H32A31.96166,31.96166,0,0,1,0,384V256A31.96166,31.96166,0,0,1,32,224Zm512-48V448a64.06328,64.06328,0,0,1-64,64H160a64.06328,64.06328,0,0,1-64-64V176a79.974,79.974,0,0,1,80-80H288V32a32,32,0,0,1,64,0V96H464A79.974,79.974,0,0,1,544,176ZM264,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,264,256Zm-8,128H192v32h64Zm96,0H288v32h64ZM456,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,456,256Zm-8,128H384v32h64ZM640,256V384a31.96166,31.96166,0,0,1-32,32H576V224h32A31.96166,31.96166,0,0,1,640,256Z\"],\n    \"rocket\": [512, 512, [], \"f135\", \"M505.12019,19.09375c-1.18945-5.53125-6.65819-11-12.207-12.1875C460.716,0,435.507,0,410.40747,0,307.17523,0,245.26909,55.20312,199.05238,128H94.83772c-16.34763.01562-35.55658,11.875-42.88664,26.48438L2.51562,253.29688A28.4,28.4,0,0,0,0,264a24.00867,24.00867,0,0,0,24.00582,24H127.81618l-22.47457,22.46875c-11.36521,11.36133-12.99607,32.25781,0,45.25L156.24582,406.625c11.15623,11.1875,32.15619,13.15625,45.27726,0l22.47457-22.46875V488a24.00867,24.00867,0,0,0,24.00581,24,28.55934,28.55934,0,0,0,10.707-2.51562l98.72834-49.39063c14.62888-7.29687,26.50776-26.5,26.50776-42.85937V312.79688c72.59753-46.3125,128.03493-108.40626,128.03493-211.09376C512.07526,76.5,512.07526,51.29688,505.12019,19.09375ZM384.04033,168A40,40,0,1,1,424.05,128,40.02322,40.02322,0,0,1,384.04033,168Z\"],\n    \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"],\n    \"slash\": [640, 512, [], \"f715\", \"M594.53 508.63L6.18 53.9c-6.97-5.42-8.23-15.47-2.81-22.45L23.01 6.18C28.43-.8 38.49-2.06 45.47 3.37L633.82 458.1c6.97 5.42 8.23 15.47 2.81 22.45l-19.64 25.27c-5.42 6.98-15.48 8.23-22.46 2.81z\"],\n    \"spinner-third\": [512, 512, [], \"f3f4\", \"M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z\"],\n    \"square-full\": [512, 512, [], \"f45c\", \"M512 512H0V0h512v512z\"],\n    \"times\": [352, 512, [], \"f00d\", \"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\"],\n    \"times-circle\": [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"],\n    \"undo\": [512, 512, [], \"f0e2\", \"M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z\"],\n    \"undo-alt\": [512, 512, [], \"f2ea\", \"M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z\"],\n    \"user\": [448, 512, [], \"f007\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"],\n    \"users\": [640, 512, [], \"f0c0\", \"M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z\"]\n  };\n\n  bunker(function () {\n    defineIcons('fas', icons);\n  });\n\n}());\n(function () {\n  'use strict';\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _typeof(obj) {\n    \"@babel/helpers - typeof\";\n\n    if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n      _typeof = function (obj) {\n        return typeof obj;\n      };\n    } else {\n      _typeof = function (obj) {\n        return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n      };\n    }\n\n    return _typeof(obj);\n  }\n\n  function _classCallCheck(instance, Constructor) {\n    if (!(instance instanceof Constructor)) {\n      throw new TypeError(\"Cannot call a class as a function\");\n    }\n  }\n\n  function _defineProperties(target, props) {\n    for (var i = 0; i < props.length; i++) {\n      var descriptor = props[i];\n      descriptor.enumerable = descriptor.enumerable || false;\n      descriptor.configurable = true;\n      if (\"value\" in descriptor) descriptor.writable = true;\n      Object.defineProperty(target, descriptor.key, descriptor);\n    }\n  }\n\n  function _createClass(Constructor, protoProps, staticProps) {\n    if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n    if (staticProps) _defineProperties(Constructor, staticProps);\n    return Constructor;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  function _slicedToArray(arr, i) {\n    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n  }\n\n  function _toConsumableArray(arr) {\n    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n  }\n\n  function _arrayWithoutHoles(arr) {\n    if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n  }\n\n  function _arrayWithHoles(arr) {\n    if (Array.isArray(arr)) return arr;\n  }\n\n  function _iterableToArray(iter) {\n    if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n  }\n\n  function _iterableToArrayLimit(arr, i) {\n    var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n    if (_i == null) return;\n    var _arr = [];\n    var _n = true;\n    var _d = false;\n\n    var _s, _e;\n\n    try {\n      for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n        _arr.push(_s.value);\n\n        if (i && _arr.length === i) break;\n      }\n    } catch (err) {\n      _d = true;\n      _e = err;\n    } finally {\n      try {\n        if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n      } finally {\n        if (_d) throw _e;\n      }\n    }\n\n    return _arr;\n  }\n\n  function _unsupportedIterableToArray(o, minLen) {\n    if (!o) return;\n    if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n    var n = Object.prototype.toString.call(o).slice(8, -1);\n    if (n === \"Object\" && o.constructor) n = o.constructor.name;\n    if (n === \"Map\" || n === \"Set\") return Array.from(o);\n    if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n  }\n\n  function _arrayLikeToArray(arr, len) {\n    if (len == null || len > arr.length) len = arr.length;\n\n    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n\n    return arr2;\n  }\n\n  function _nonIterableSpread() {\n    throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n\n  function _nonIterableRest() {\n    throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n\n  var noop = function noop() {};\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n  var _MUTATION_OBSERVER = null;\n  var _PERFORMANCE = {\n    mark: noop,\n    measure: noop\n  };\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n    if (typeof MutationObserver !== 'undefined') _MUTATION_OBSERVER = MutationObserver;\n    if (typeof performance !== 'undefined') _PERFORMANCE = performance;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var MUTATION_OBSERVER = _MUTATION_OBSERVER;\n  var PERFORMANCE = _PERFORMANCE;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var UNITS_IN_GRID = 16;\n  var DEFAULT_FAMILY_PREFIX = 'fa';\n  var DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa';\n  var DATA_FA_I2SVG = 'data-fa-i2svg';\n  var DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element';\n  var DATA_FA_PSEUDO_ELEMENT_PENDING = 'data-fa-pseudo-element-pending';\n  var DATA_PREFIX = 'data-prefix';\n  var DATA_ICON = 'data-icon';\n  var HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg';\n  var MUTATION_APPROACH_ASYNC = 'async';\n  var TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS = ['HTML', 'HEAD', 'STYLE', 'SCRIPT'];\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n  var PREFIX_TO_STYLE = {\n    'fas': 'solid',\n    'far': 'regular',\n    'fal': 'light',\n    'fad': 'duotone',\n    'fab': 'brands',\n    'fak': 'kit',\n    'fa': 'solid'\n  };\n  var STYLE_TO_PREFIX = {\n    'solid': 'fas',\n    'regular': 'far',\n    'light': 'fal',\n    'duotone': 'fad',\n    'brands': 'fab',\n    'kit': 'fak'\n  };\n  var LAYERS_TEXT_CLASSNAME = 'fa-layers-text';\n  var FONT_FAMILY_PATTERN = /Font Awesome ([5 ]*)(Solid|Regular|Light|Duotone|Brands|Free|Pro|Kit).*/i; // TODO: do we need to handle font-weight for kit SVG pseudo-elements?\n\n  var FONT_WEIGHT_TO_PREFIX = {\n    '900': 'fas',\n    '400': 'far',\n    'normal': 'far',\n    '300': 'fal'\n  };\n  var oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n  var oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);\n  var ATTRIBUTES_WATCHED_FOR_MUTATION = ['class', 'data-prefix', 'data-icon', 'data-fa-transform', 'data-fa-mask'];\n  var DUOTONE_CLASSES = {\n    GROUP: 'group',\n    SWAP_OPACITY: 'swap-opacity',\n    PRIMARY: 'primary',\n    SECONDARY: 'secondary'\n  };\n  var RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'flip-both', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter', DUOTONE_CLASSES.GROUP, DUOTONE_CLASSES.SWAP_OPACITY, DUOTONE_CLASSES.PRIMARY, DUOTONE_CLASSES.SECONDARY].concat(oneToTen.map(function (n) {\n    return \"\".concat(n, \"x\");\n  })).concat(oneToTwenty.map(function (n) {\n    return \"w-\".concat(n);\n  }));\n\n  var initial = WINDOW.FontAwesomeConfig || {};\n\n  function getAttrConfig(attr) {\n    var element = DOCUMENT.querySelector('script[' + attr + ']');\n\n    if (element) {\n      return element.getAttribute(attr);\n    }\n  }\n\n  function coerce(val) {\n    // Getting an empty string will occur if the attribute is set on the HTML tag but without a value\n    // We'll assume that this is an indication that it should be toggled to true\n    // For example <script data-search-pseudo-elements src=\"...\"></script>\n    if (val === '') return true;\n    if (val === 'false') return false;\n    if (val === 'true') return true;\n    return val;\n  }\n\n  if (DOCUMENT && typeof DOCUMENT.querySelector === 'function') {\n    var attrs = [['data-family-prefix', 'familyPrefix'], ['data-replacement-class', 'replacementClass'], ['data-auto-replace-svg', 'autoReplaceSvg'], ['data-auto-add-css', 'autoAddCss'], ['data-auto-a11y', 'autoA11y'], ['data-search-pseudo-elements', 'searchPseudoElements'], ['data-observe-mutations', 'observeMutations'], ['data-mutate-approach', 'mutateApproach'], ['data-keep-original-source', 'keepOriginalSource'], ['data-measure-performance', 'measurePerformance'], ['data-show-missing-icons', 'showMissingIcons']];\n    attrs.forEach(function (_ref) {\n      var _ref2 = _slicedToArray(_ref, 2),\n          attr = _ref2[0],\n          key = _ref2[1];\n\n      var val = coerce(getAttrConfig(attr));\n\n      if (val !== undefined && val !== null) {\n        initial[key] = val;\n      }\n    });\n  }\n\n  var _default = {\n    familyPrefix: DEFAULT_FAMILY_PREFIX,\n    replacementClass: DEFAULT_REPLACEMENT_CLASS,\n    autoReplaceSvg: true,\n    autoAddCss: true,\n    autoA11y: true,\n    searchPseudoElements: false,\n    observeMutations: true,\n    mutateApproach: 'async',\n    keepOriginalSource: true,\n    measurePerformance: false,\n    showMissingIcons: true\n  };\n\n  var _config = _objectSpread2(_objectSpread2({}, _default), initial);\n\n  if (!_config.autoReplaceSvg) _config.observeMutations = false;\n\n  var config = _objectSpread2({}, _config);\n\n  WINDOW.FontAwesomeConfig = config;\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  var functions = [];\n\n  var listener = function listener() {\n    DOCUMENT.removeEventListener('DOMContentLoaded', listener);\n    loaded = 1;\n    functions.map(function (fn) {\n      return fn();\n    });\n  };\n\n  var loaded = false;\n\n  if (IS_DOM) {\n    loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);\n    if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);\n  }\n\n  function domready (fn) {\n    if (!IS_DOM) return;\n    loaded ? setTimeout(fn, 0) : functions.push(fn);\n  }\n\n  var PENDING = 'pending';\n  var SETTLED = 'settled';\n  var FULFILLED = 'fulfilled';\n  var REJECTED = 'rejected';\n\n  var NOOP = function NOOP() {};\n\n  var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function';\n  var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate;\n  var asyncQueue = [];\n  var asyncTimer;\n\n  function asyncFlush() {\n    // run promise callbacks\n    for (var i = 0; i < asyncQueue.length; i++) {\n      asyncQueue[i][0](asyncQueue[i][1]);\n    } // reset async asyncQueue\n\n\n    asyncQueue = [];\n    asyncTimer = false;\n  }\n\n  function asyncCall(callback, arg) {\n    asyncQueue.push([callback, arg]);\n\n    if (!asyncTimer) {\n      asyncTimer = true;\n      asyncSetTimer(asyncFlush, 0);\n    }\n  }\n\n  function invokeResolver(resolver, promise) {\n    function resolvePromise(value) {\n      resolve(promise, value);\n    }\n\n    function rejectPromise(reason) {\n      reject(promise, reason);\n    }\n\n    try {\n      resolver(resolvePromise, rejectPromise);\n    } catch (e) {\n      rejectPromise(e);\n    }\n  }\n\n  function invokeCallback(subscriber) {\n    var owner = subscriber.owner;\n    var settled = owner._state;\n    var value = owner._data;\n    var callback = subscriber[settled];\n    var promise = subscriber.then;\n\n    if (typeof callback === 'function') {\n      settled = FULFILLED;\n\n      try {\n        value = callback(value);\n      } catch (e) {\n        reject(promise, e);\n      }\n    }\n\n    if (!handleThenable(promise, value)) {\n      if (settled === FULFILLED) {\n        resolve(promise, value);\n      }\n\n      if (settled === REJECTED) {\n        reject(promise, value);\n      }\n    }\n  }\n\n  function handleThenable(promise, value) {\n    var resolved;\n\n    try {\n      if (promise === value) {\n        throw new TypeError('A promises callback cannot return that same promise.');\n      }\n\n      if (value && (typeof value === 'function' || _typeof(value) === 'object')) {\n        // then should be retrieved only once\n        var then = value.then;\n\n        if (typeof then === 'function') {\n          then.call(value, function (val) {\n            if (!resolved) {\n              resolved = true;\n\n              if (value === val) {\n                fulfill(promise, val);\n              } else {\n                resolve(promise, val);\n              }\n            }\n          }, function (reason) {\n            if (!resolved) {\n              resolved = true;\n              reject(promise, reason);\n            }\n          });\n          return true;\n        }\n      }\n    } catch (e) {\n      if (!resolved) {\n        reject(promise, e);\n      }\n\n      return true;\n    }\n\n    return false;\n  }\n\n  function resolve(promise, value) {\n    if (promise === value || !handleThenable(promise, value)) {\n      fulfill(promise, value);\n    }\n  }\n\n  function fulfill(promise, value) {\n    if (promise._state === PENDING) {\n      promise._state = SETTLED;\n      promise._data = value;\n      asyncCall(publishFulfillment, promise);\n    }\n  }\n\n  function reject(promise, reason) {\n    if (promise._state === PENDING) {\n      promise._state = SETTLED;\n      promise._data = reason;\n      asyncCall(publishRejection, promise);\n    }\n  }\n\n  function publish(promise) {\n    promise._then = promise._then.forEach(invokeCallback);\n  }\n\n  function publishFulfillment(promise) {\n    promise._state = FULFILLED;\n    publish(promise);\n  }\n\n  function publishRejection(promise) {\n    promise._state = REJECTED;\n    publish(promise);\n\n    if (!promise._handled && isNode) {\n      global.process.emit('unhandledRejection', promise._data, promise);\n    }\n  }\n\n  function notifyRejectionHandled(promise) {\n    global.process.emit('rejectionHandled', promise);\n  }\n  /**\n   * @class\n   */\n\n\n  function P(resolver) {\n    if (typeof resolver !== 'function') {\n      throw new TypeError('Promise resolver ' + resolver + ' is not a function');\n    }\n\n    if (this instanceof P === false) {\n      throw new TypeError('Failed to construct \\'Promise\\': Please use the \\'new\\' operator, this object constructor cannot be called as a function.');\n    }\n\n    this._then = [];\n    invokeResolver(resolver, this);\n  }\n\n  P.prototype = {\n    constructor: P,\n    _state: PENDING,\n    _then: null,\n    _data: undefined,\n    _handled: false,\n    then: function then(onFulfillment, onRejection) {\n      var subscriber = {\n        owner: this,\n        then: new this.constructor(NOOP),\n        fulfilled: onFulfillment,\n        rejected: onRejection\n      };\n\n      if ((onRejection || onFulfillment) && !this._handled) {\n        this._handled = true;\n\n        if (this._state === REJECTED && isNode) {\n          asyncCall(notifyRejectionHandled, this);\n        }\n      }\n\n      if (this._state === FULFILLED || this._state === REJECTED) {\n        // already resolved, call callback async\n        asyncCall(invokeCallback, subscriber);\n      } else {\n        // subscribe\n        this._then.push(subscriber);\n      }\n\n      return subscriber.then;\n    },\n    catch: function _catch(onRejection) {\n      return this.then(null, onRejection);\n    }\n  };\n\n  P.all = function (promises) {\n    if (!Array.isArray(promises)) {\n      throw new TypeError('You must pass an array to Promise.all().');\n    }\n\n    return new P(function (resolve, reject) {\n      var results = [];\n      var remaining = 0;\n\n      function resolver(index) {\n        remaining++;\n        return function (value) {\n          results[index] = value;\n\n          if (! --remaining) {\n            resolve(results);\n          }\n        };\n      }\n\n      for (var i = 0, promise; i < promises.length; i++) {\n        promise = promises[i];\n\n        if (promise && typeof promise.then === 'function') {\n          promise.then(resolver(i), reject);\n        } else {\n          results[i] = promise;\n        }\n      }\n\n      if (!remaining) {\n        resolve(results);\n      }\n    });\n  };\n\n  P.race = function (promises) {\n    if (!Array.isArray(promises)) {\n      throw new TypeError('You must pass an array to Promise.race().');\n    }\n\n    return new P(function (resolve, reject) {\n      for (var i = 0, promise; i < promises.length; i++) {\n        promise = promises[i];\n\n        if (promise && typeof promise.then === 'function') {\n          promise.then(resolve, reject);\n        } else {\n          resolve(promise);\n        }\n      }\n    });\n  };\n\n  P.resolve = function (value) {\n    if (value && _typeof(value) === 'object' && value.constructor === P) {\n      return value;\n    }\n\n    return new P(function (resolve) {\n      resolve(value);\n    });\n  };\n\n  P.reject = function (reason) {\n    return new P(function (resolve, reject) {\n      reject(reason);\n    });\n  };\n\n  var picked = typeof Promise === 'function' ? Promise : P;\n\n  var d = UNITS_IN_GRID;\n  var meaninglessTransform = {\n    size: 16,\n    x: 0,\n    y: 0,\n    rotate: 0,\n    flipX: false,\n    flipY: false\n  };\n\n  function isReserved(name) {\n    return ~RESERVED_CLASSES.indexOf(name);\n  }\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n  function insertCss(css) {\n    if (!css || !IS_DOM) {\n      return;\n    }\n\n    var style = DOCUMENT.createElement('style');\n    style.setAttribute('type', 'text/css');\n    style.innerHTML = css;\n    var headChildren = DOCUMENT.head.childNodes;\n    var beforeChild = null;\n\n    for (var i = headChildren.length - 1; i > -1; i--) {\n      var child = headChildren[i];\n      var tagName = (child.tagName || '').toUpperCase();\n\n      if (['STYLE', 'LINK'].indexOf(tagName) > -1) {\n        beforeChild = child;\n      }\n    }\n\n    DOCUMENT.head.insertBefore(style, beforeChild);\n    return css;\n  }\n  var idPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n  function nextUniqueId() {\n    var size = 12;\n    var id = '';\n\n    while (size-- > 0) {\n      id += idPool[Math.random() * 62 | 0];\n    }\n\n    return id;\n  }\n  function toArray(obj) {\n    var array = [];\n\n    for (var i = (obj || []).length >>> 0; i--;) {\n      array[i] = obj[i];\n    }\n\n    return array;\n  }\n  function classArray(node) {\n    if (node.classList) {\n      return toArray(node.classList);\n    } else {\n      return (node.getAttribute('class') || '').split(' ').filter(function (i) {\n        return i;\n      });\n    }\n  }\n  function getIconName(familyPrefix, cls) {\n    var parts = cls.split('-');\n    var prefix = parts[0];\n    var iconName = parts.slice(1).join('-');\n\n    if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) {\n      return iconName;\n    } else {\n      return null;\n    }\n  }\n  function htmlEscape(str) {\n    return \"\".concat(str).replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n  }\n  function joinAttributes(attributes) {\n    return Object.keys(attributes || {}).reduce(function (acc, attributeName) {\n      return acc + \"\".concat(attributeName, \"=\\\"\").concat(htmlEscape(attributes[attributeName]), \"\\\" \");\n    }, '').trim();\n  }\n  function joinStyles(styles) {\n    return Object.keys(styles || {}).reduce(function (acc, styleName) {\n      return acc + \"\".concat(styleName, \": \").concat(styles[styleName], \";\");\n    }, '');\n  }\n  function transformIsMeaningful(transform) {\n    return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY;\n  }\n  function transformForSvg(_ref) {\n    var transform = _ref.transform,\n        containerWidth = _ref.containerWidth,\n        iconWidth = _ref.iconWidth;\n    var outer = {\n      transform: \"translate(\".concat(containerWidth / 2, \" 256)\")\n    };\n    var innerTranslate = \"translate(\".concat(transform.x * 32, \", \").concat(transform.y * 32, \") \");\n    var innerScale = \"scale(\".concat(transform.size / 16 * (transform.flipX ? -1 : 1), \", \").concat(transform.size / 16 * (transform.flipY ? -1 : 1), \") \");\n    var innerRotate = \"rotate(\".concat(transform.rotate, \" 0 0)\");\n    var inner = {\n      transform: \"\".concat(innerTranslate, \" \").concat(innerScale, \" \").concat(innerRotate)\n    };\n    var path = {\n      transform: \"translate(\".concat(iconWidth / 2 * -1, \" -256)\")\n    };\n    return {\n      outer: outer,\n      inner: inner,\n      path: path\n    };\n  }\n  function transformForCss(_ref2) {\n    var transform = _ref2.transform,\n        _ref2$width = _ref2.width,\n        width = _ref2$width === void 0 ? UNITS_IN_GRID : _ref2$width,\n        _ref2$height = _ref2.height,\n        height = _ref2$height === void 0 ? UNITS_IN_GRID : _ref2$height,\n        _ref2$startCentered = _ref2.startCentered,\n        startCentered = _ref2$startCentered === void 0 ? false : _ref2$startCentered;\n    var val = '';\n\n    if (startCentered && IS_IE) {\n      val += \"translate(\".concat(transform.x / d - width / 2, \"em, \").concat(transform.y / d - height / 2, \"em) \");\n    } else if (startCentered) {\n      val += \"translate(calc(-50% + \".concat(transform.x / d, \"em), calc(-50% + \").concat(transform.y / d, \"em)) \");\n    } else {\n      val += \"translate(\".concat(transform.x / d, \"em, \").concat(transform.y / d, \"em) \");\n    }\n\n    val += \"scale(\".concat(transform.size / d * (transform.flipX ? -1 : 1), \", \").concat(transform.size / d * (transform.flipY ? -1 : 1), \") \");\n    val += \"rotate(\".concat(transform.rotate, \"deg) \");\n    return val;\n  }\n\n  var ALL_SPACE = {\n    x: 0,\n    y: 0,\n    width: '100%',\n    height: '100%'\n  };\n\n  function fillBlack(abstract) {\n    var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n    if (abstract.attributes && (abstract.attributes.fill || force)) {\n      abstract.attributes.fill = 'black';\n    }\n\n    return abstract;\n  }\n\n  function deGroup(abstract) {\n    if (abstract.tag === 'g') {\n      return abstract.children;\n    } else {\n      return [abstract];\n    }\n  }\n\n  function makeIconMasking (_ref) {\n    var children = _ref.children,\n        attributes = _ref.attributes,\n        main = _ref.main,\n        mask = _ref.mask,\n        explicitMaskId = _ref.maskId,\n        transform = _ref.transform;\n    var mainWidth = main.width,\n        mainPath = main.icon;\n    var maskWidth = mask.width,\n        maskPath = mask.icon;\n    var trans = transformForSvg({\n      transform: transform,\n      containerWidth: maskWidth,\n      iconWidth: mainWidth\n    });\n    var maskRect = {\n      tag: 'rect',\n      attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n        fill: 'white'\n      })\n    };\n    var maskInnerGroupChildrenMixin = mainPath.children ? {\n      children: mainPath.children.map(fillBlack)\n    } : {};\n    var maskInnerGroup = {\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.inner),\n      children: [fillBlack(_objectSpread2({\n        tag: mainPath.tag,\n        attributes: _objectSpread2(_objectSpread2({}, mainPath.attributes), trans.path)\n      }, maskInnerGroupChildrenMixin))]\n    };\n    var maskOuterGroup = {\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.outer),\n      children: [maskInnerGroup]\n    };\n    var maskId = \"mask-\".concat(explicitMaskId || nextUniqueId());\n    var clipId = \"clip-\".concat(explicitMaskId || nextUniqueId());\n    var maskTag = {\n      tag: 'mask',\n      attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n        id: maskId,\n        maskUnits: 'userSpaceOnUse',\n        maskContentUnits: 'userSpaceOnUse'\n      }),\n      children: [maskRect, maskOuterGroup]\n    };\n    var defs = {\n      tag: 'defs',\n      children: [{\n        tag: 'clipPath',\n        attributes: {\n          id: clipId\n        },\n        children: deGroup(maskPath)\n      }, maskTag]\n    };\n    children.push(defs, {\n      tag: 'rect',\n      attributes: _objectSpread2({\n        fill: 'currentColor',\n        'clip-path': \"url(#\".concat(clipId, \")\"),\n        mask: \"url(#\".concat(maskId, \")\")\n      }, ALL_SPACE)\n    });\n    return {\n      children: children,\n      attributes: attributes\n    };\n  }\n\n  function makeIconStandard (_ref) {\n    var children = _ref.children,\n        attributes = _ref.attributes,\n        main = _ref.main,\n        transform = _ref.transform,\n        styles = _ref.styles;\n    var styleString = joinStyles(styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    if (transformIsMeaningful(transform)) {\n      var trans = transformForSvg({\n        transform: transform,\n        containerWidth: main.width,\n        iconWidth: main.width\n      });\n      children.push({\n        tag: 'g',\n        attributes: _objectSpread2({}, trans.outer),\n        children: [{\n          tag: 'g',\n          attributes: _objectSpread2({}, trans.inner),\n          children: [{\n            tag: main.icon.tag,\n            children: main.icon.children,\n            attributes: _objectSpread2(_objectSpread2({}, main.icon.attributes), trans.path)\n          }]\n        }]\n      });\n    } else {\n      children.push(main.icon);\n    }\n\n    return {\n      children: children,\n      attributes: attributes\n    };\n  }\n\n  function asIcon (_ref) {\n    var children = _ref.children,\n        main = _ref.main,\n        mask = _ref.mask,\n        attributes = _ref.attributes,\n        styles = _ref.styles,\n        transform = _ref.transform;\n\n    if (transformIsMeaningful(transform) && main.found && !mask.found) {\n      var width = main.width,\n          height = main.height;\n      var offset = {\n        x: width / height / 2,\n        y: 0.5\n      };\n      attributes['style'] = joinStyles(_objectSpread2(_objectSpread2({}, styles), {}, {\n        'transform-origin': \"\".concat(offset.x + transform.x / 16, \"em \").concat(offset.y + transform.y / 16, \"em\")\n      }));\n    }\n\n    return [{\n      tag: 'svg',\n      attributes: attributes,\n      children: children\n    }];\n  }\n\n  function asSymbol (_ref) {\n    var prefix = _ref.prefix,\n        iconName = _ref.iconName,\n        children = _ref.children,\n        attributes = _ref.attributes,\n        symbol = _ref.symbol;\n    var id = symbol === true ? \"\".concat(prefix, \"-\").concat(config.familyPrefix, \"-\").concat(iconName) : symbol;\n    return [{\n      tag: 'svg',\n      attributes: {\n        style: 'display: none;'\n      },\n      children: [{\n        tag: 'symbol',\n        attributes: _objectSpread2(_objectSpread2({}, attributes), {}, {\n          id: id\n        }),\n        children: children\n      }]\n    }];\n  }\n\n  function makeInlineSvgAbstract(params) {\n    var _params$icons = params.icons,\n        main = _params$icons.main,\n        mask = _params$icons.mask,\n        prefix = params.prefix,\n        iconName = params.iconName,\n        transform = params.transform,\n        symbol = params.symbol,\n        title = params.title,\n        maskId = params.maskId,\n        titleId = params.titleId,\n        extra = params.extra,\n        _params$watchable = params.watchable,\n        watchable = _params$watchable === void 0 ? false : _params$watchable;\n\n    var _ref = mask.found ? mask : main,\n        width = _ref.width,\n        height = _ref.height;\n\n    var isUploadedIcon = prefix === 'fak';\n    var widthClass = isUploadedIcon ? '' : \"fa-w-\".concat(Math.ceil(width / height * 16));\n    var attrClass = [config.replacementClass, iconName ? \"\".concat(config.familyPrefix, \"-\").concat(iconName) : '', widthClass].filter(function (c) {\n      return extra.classes.indexOf(c) === -1;\n    }).filter(function (c) {\n      return c !== '' || !!c;\n    }).concat(extra.classes).join(' ');\n    var content = {\n      children: [],\n      attributes: _objectSpread2(_objectSpread2({}, extra.attributes), {}, {\n        'data-prefix': prefix,\n        'data-icon': iconName,\n        'class': attrClass,\n        'role': extra.attributes.role || 'img',\n        'xmlns': 'http://www.w3.org/2000/svg',\n        'viewBox': \"0 0 \".concat(width, \" \").concat(height)\n      })\n    };\n    var uploadedIconWidthStyle = isUploadedIcon && !~extra.classes.indexOf('fa-fw') ? {\n      width: \"\".concat(width / height * 16 * 0.0625, \"em\")\n    } : {};\n\n    if (watchable) {\n      content.attributes[DATA_FA_I2SVG] = '';\n    }\n\n    if (title) content.children.push({\n      tag: 'title',\n      attributes: {\n        id: content.attributes['aria-labelledby'] || \"title-\".concat(titleId || nextUniqueId())\n      },\n      children: [title]\n    });\n\n    var args = _objectSpread2(_objectSpread2({}, content), {}, {\n      prefix: prefix,\n      iconName: iconName,\n      main: main,\n      mask: mask,\n      maskId: maskId,\n      transform: transform,\n      symbol: symbol,\n      styles: _objectSpread2(_objectSpread2({}, uploadedIconWidthStyle), extra.styles)\n    });\n\n    var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args),\n        children = _ref2.children,\n        attributes = _ref2.attributes;\n\n    args.children = children;\n    args.attributes = attributes;\n\n    if (symbol) {\n      return asSymbol(args);\n    } else {\n      return asIcon(args);\n    }\n  }\n  function makeLayersTextAbstract(params) {\n    var content = params.content,\n        width = params.width,\n        height = params.height,\n        transform = params.transform,\n        title = params.title,\n        extra = params.extra,\n        _params$watchable2 = params.watchable,\n        watchable = _params$watchable2 === void 0 ? false : _params$watchable2;\n\n    var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n      'title': title\n    } : {}), {}, {\n      'class': extra.classes.join(' ')\n    });\n\n    if (watchable) {\n      attributes[DATA_FA_I2SVG] = '';\n    }\n\n    var styles = _objectSpread2({}, extra.styles);\n\n    if (transformIsMeaningful(transform)) {\n      styles['transform'] = transformForCss({\n        transform: transform,\n        startCentered: true,\n        width: width,\n        height: height\n      });\n      styles['-webkit-transform'] = styles['transform'];\n    }\n\n    var styleString = joinStyles(styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    var val = [];\n    val.push({\n      tag: 'span',\n      attributes: attributes,\n      children: [content]\n    });\n\n    if (title) {\n      val.push({\n        tag: 'span',\n        attributes: {\n          class: 'sr-only'\n        },\n        children: [title]\n      });\n    }\n\n    return val;\n  }\n  function makeLayersCounterAbstract(params) {\n    var content = params.content,\n        title = params.title,\n        extra = params.extra;\n\n    var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n      'title': title\n    } : {}), {}, {\n      'class': extra.classes.join(' ')\n    });\n\n    var styleString = joinStyles(extra.styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    var val = [];\n    val.push({\n      tag: 'span',\n      attributes: attributes,\n      children: [content]\n    });\n\n    if (title) {\n      val.push({\n        tag: 'span',\n        attributes: {\n          class: 'sr-only'\n        },\n        children: [title]\n      });\n    }\n\n    return val;\n  }\n\n  var noop$1 = function noop() {};\n\n  var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : {\n    mark: noop$1,\n    measure: noop$1\n  };\n  var preamble = \"FA \\\"5.15.4\\\"\";\n\n  var begin = function begin(name) {\n    p.mark(\"\".concat(preamble, \" \").concat(name, \" begins\"));\n    return function () {\n      return end(name);\n    };\n  };\n\n  var end = function end(name) {\n    p.mark(\"\".concat(preamble, \" \").concat(name, \" ends\"));\n    p.measure(\"\".concat(preamble, \" \").concat(name), \"\".concat(preamble, \" \").concat(name, \" begins\"), \"\".concat(preamble, \" \").concat(name, \" ends\"));\n  };\n\n  var perf = {\n    begin: begin,\n    end: end\n  };\n\n  /**\n   * Internal helper to bind a function known to have 4 arguments\n   * to a given context.\n   */\n\n  var bindInternal4 = function bindInternal4(func, thisContext) {\n    return function (a, b, c, d) {\n      return func.call(thisContext, a, b, c, d);\n    };\n  };\n\n  /**\n   * # Reduce\n   *\n   * A fast object `.reduce()` implementation.\n   *\n   * @param  {Object}   subject      The object to reduce over.\n   * @param  {Function} fn           The reducer function.\n   * @param  {mixed}    initialValue The initial value for the reducer, defaults to subject[0].\n   * @param  {Object}   thisContext  The context for the reducer.\n   * @return {mixed}                 The final result.\n   */\n\n\n  var reduce = function fastReduceObject(subject, fn, initialValue, thisContext) {\n    var keys = Object.keys(subject),\n        length = keys.length,\n        iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn,\n        i,\n        key,\n        result;\n\n    if (initialValue === undefined) {\n      i = 1;\n      result = subject[keys[0]];\n    } else {\n      i = 0;\n      result = initialValue;\n    }\n\n    for (; i < length; i++) {\n      key = keys[i];\n      result = iterator(result, subject[key], key, subject);\n    }\n\n    return result;\n  };\n\n  function toHex(unicode) {\n    var result = '';\n\n    for (var i = 0; i < unicode.length; i++) {\n      var hex = unicode.charCodeAt(i).toString(16);\n      result += ('000' + hex).slice(-4);\n    }\n\n    return result;\n  }\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var styles = namespace.styles,\n      shims = namespace.shims;\n  var _byUnicode = {};\n  var _byLigature = {};\n  var _byOldName = {};\n  var build = function build() {\n    var lookup = function lookup(reducer) {\n      return reduce(styles, function (o, style, prefix) {\n        o[prefix] = reduce(style, reducer, {});\n        return o;\n      }, {});\n    };\n\n    _byUnicode = lookup(function (acc, icon, iconName) {\n      if (icon[3]) {\n        acc[icon[3]] = iconName;\n      }\n\n      return acc;\n    });\n    _byLigature = lookup(function (acc, icon, iconName) {\n      var ligatures = icon[2];\n      acc[iconName] = iconName;\n      ligatures.forEach(function (ligature) {\n        acc[ligature] = iconName;\n      });\n      return acc;\n    });\n    var hasRegular = ('far' in styles);\n    _byOldName = reduce(shims, function (acc, shim) {\n      var oldName = shim[0];\n      var prefix = shim[1];\n      var iconName = shim[2];\n\n      if (prefix === 'far' && !hasRegular) {\n        prefix = 'fas';\n      }\n\n      acc[oldName] = {\n        prefix: prefix,\n        iconName: iconName\n      };\n      return acc;\n    }, {});\n  };\n  build();\n  function byUnicode(prefix, unicode) {\n    return (_byUnicode[prefix] || {})[unicode];\n  }\n  function byLigature(prefix, ligature) {\n    return (_byLigature[prefix] || {})[ligature];\n  }\n  function byOldName(name) {\n    return _byOldName[name] || {\n      prefix: null,\n      iconName: null\n    };\n  }\n\n  var styles$1 = namespace.styles;\n  var emptyCanonicalIcon = function emptyCanonicalIcon() {\n    return {\n      prefix: null,\n      iconName: null,\n      rest: []\n    };\n  };\n  function getCanonicalIcon(values) {\n    return values.reduce(function (acc, cls) {\n      var iconName = getIconName(config.familyPrefix, cls);\n\n      if (styles$1[cls]) {\n        acc.prefix = cls;\n      } else if (config.autoFetchSvg && Object.keys(PREFIX_TO_STYLE).indexOf(cls) > -1) {\n        acc.prefix = cls;\n      } else if (iconName) {\n        var shim = acc.prefix === 'fa' ? byOldName(iconName) : {};\n        acc.iconName = shim.iconName || iconName;\n        acc.prefix = shim.prefix || acc.prefix;\n      } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) {\n        acc.rest.push(cls);\n      }\n\n      return acc;\n    }, emptyCanonicalIcon());\n  }\n  function iconFromMapping(mapping, prefix, iconName) {\n    if (mapping && mapping[prefix] && mapping[prefix][iconName]) {\n      return {\n        prefix: prefix,\n        iconName: iconName,\n        icon: mapping[prefix][iconName]\n      };\n    }\n  }\n\n  function toHtml(abstractNodes) {\n    var tag = abstractNodes.tag,\n        _abstractNodes$attrib = abstractNodes.attributes,\n        attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib,\n        _abstractNodes$childr = abstractNodes.children,\n        children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr;\n\n    if (typeof abstractNodes === 'string') {\n      return htmlEscape(abstractNodes);\n    } else {\n      return \"<\".concat(tag, \" \").concat(joinAttributes(attributes), \">\").concat(children.map(toHtml).join(''), \"</\").concat(tag, \">\");\n    }\n  }\n\n  var noop$2 = function noop() {};\n\n  function isWatched(node) {\n    var i2svg = node.getAttribute ? node.getAttribute(DATA_FA_I2SVG) : null;\n    return typeof i2svg === 'string';\n  }\n\n  function getMutator() {\n    if (config.autoReplaceSvg === true) {\n      return mutators.replace;\n    }\n\n    var mutator = mutators[config.autoReplaceSvg];\n    return mutator || mutators.replace;\n  }\n\n  var mutators = {\n    replace: function replace(mutation) {\n      var node = mutation[0];\n      var abstract = mutation[1];\n      var newOuterHTML = abstract.map(function (a) {\n        return toHtml(a);\n      }).join('\\n');\n\n      if (node.parentNode && node.outerHTML) {\n        node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? \"<!-- \".concat(node.outerHTML, \" Font Awesome fontawesome.com -->\") : '');\n      } else if (node.parentNode) {\n        var newNode = document.createElement('span');\n        node.parentNode.replaceChild(newNode, node);\n        newNode.outerHTML = newOuterHTML;\n      }\n    },\n    nest: function nest(mutation) {\n      var node = mutation[0];\n      var abstract = mutation[1]; // If we already have a replaced node we do not want to continue nesting within it.\n      // Short-circuit to the standard replacement\n\n      if (~classArray(node).indexOf(config.replacementClass)) {\n        return mutators.replace(mutation);\n      }\n\n      var forSvg = new RegExp(\"\".concat(config.familyPrefix, \"-.*\"));\n      delete abstract[0].attributes.style;\n      delete abstract[0].attributes.id;\n      var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) {\n        if (cls === config.replacementClass || cls.match(forSvg)) {\n          acc.toSvg.push(cls);\n        } else {\n          acc.toNode.push(cls);\n        }\n\n        return acc;\n      }, {\n        toNode: [],\n        toSvg: []\n      });\n      abstract[0].attributes.class = splitClasses.toSvg.join(' ');\n      var newInnerHTML = abstract.map(function (a) {\n        return toHtml(a);\n      }).join('\\n');\n      node.setAttribute('class', splitClasses.toNode.join(' '));\n      node.setAttribute(DATA_FA_I2SVG, '');\n      node.innerHTML = newInnerHTML;\n    }\n  };\n\n  function performOperationSync(op) {\n    op();\n  }\n\n  function perform(mutations, callback) {\n    var callbackFunction = typeof callback === 'function' ? callback : noop$2;\n\n    if (mutations.length === 0) {\n      callbackFunction();\n    } else {\n      var frame = performOperationSync;\n\n      if (config.mutateApproach === MUTATION_APPROACH_ASYNC) {\n        frame = WINDOW.requestAnimationFrame || performOperationSync;\n      }\n\n      frame(function () {\n        var mutator = getMutator();\n        var mark = perf.begin('mutate');\n        mutations.map(mutator);\n        mark();\n        callbackFunction();\n      });\n    }\n  }\n  var disabled = false;\n  function disableObservation() {\n    disabled = true;\n  }\n  function enableObservation() {\n    disabled = false;\n  }\n  var mo = null;\n  function observe(options) {\n    if (!MUTATION_OBSERVER) {\n      return;\n    }\n\n    if (!config.observeMutations) {\n      return;\n    }\n\n    var treeCallback = options.treeCallback,\n        nodeCallback = options.nodeCallback,\n        pseudoElementsCallback = options.pseudoElementsCallback,\n        _options$observeMutat = options.observeMutationsRoot,\n        observeMutationsRoot = _options$observeMutat === void 0 ? DOCUMENT : _options$observeMutat;\n    mo = new MUTATION_OBSERVER(function (objects) {\n      if (disabled) return;\n      toArray(objects).forEach(function (mutationRecord) {\n        if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isWatched(mutationRecord.addedNodes[0])) {\n          if (config.searchPseudoElements) {\n            pseudoElementsCallback(mutationRecord.target);\n          }\n\n          treeCallback(mutationRecord.target);\n        }\n\n        if (mutationRecord.type === 'attributes' && mutationRecord.target.parentNode && config.searchPseudoElements) {\n          pseudoElementsCallback(mutationRecord.target.parentNode);\n        }\n\n        if (mutationRecord.type === 'attributes' && isWatched(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) {\n          if (mutationRecord.attributeName === 'class') {\n            var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)),\n                prefix = _getCanonicalIcon.prefix,\n                iconName = _getCanonicalIcon.iconName;\n\n            if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix);\n            if (iconName) mutationRecord.target.setAttribute('data-icon', iconName);\n          } else {\n            nodeCallback(mutationRecord.target);\n          }\n        }\n      });\n    });\n    if (!IS_DOM) return;\n    mo.observe(observeMutationsRoot, {\n      childList: true,\n      attributes: true,\n      characterData: true,\n      subtree: true\n    });\n  }\n  function disconnect() {\n    if (!mo) return;\n    mo.disconnect();\n  }\n\n  function styleParser (node) {\n    var style = node.getAttribute('style');\n    var val = [];\n\n    if (style) {\n      val = style.split(';').reduce(function (acc, style) {\n        var styles = style.split(':');\n        var prop = styles[0];\n        var value = styles.slice(1);\n\n        if (prop && value.length > 0) {\n          acc[prop] = value.join(':').trim();\n        }\n\n        return acc;\n      }, {});\n    }\n\n    return val;\n  }\n\n  function classParser (node) {\n    var existingPrefix = node.getAttribute('data-prefix');\n    var existingIconName = node.getAttribute('data-icon');\n    var innerText = node.innerText !== undefined ? node.innerText.trim() : '';\n    var val = getCanonicalIcon(classArray(node));\n\n    if (existingPrefix && existingIconName) {\n      val.prefix = existingPrefix;\n      val.iconName = existingIconName;\n    }\n\n    if (val.prefix && innerText.length > 1) {\n      val.iconName = byLigature(val.prefix, node.innerText);\n    } else if (val.prefix && innerText.length === 1) {\n      val.iconName = byUnicode(val.prefix, toHex(node.innerText));\n    }\n\n    return val;\n  }\n\n  var parseTransformString = function parseTransformString(transformString) {\n    var transform = {\n      size: 16,\n      x: 0,\n      y: 0,\n      flipX: false,\n      flipY: false,\n      rotate: 0\n    };\n\n    if (!transformString) {\n      return transform;\n    } else {\n      return transformString.toLowerCase().split(' ').reduce(function (acc, n) {\n        var parts = n.toLowerCase().split('-');\n        var first = parts[0];\n        var rest = parts.slice(1).join('-');\n\n        if (first && rest === 'h') {\n          acc.flipX = true;\n          return acc;\n        }\n\n        if (first && rest === 'v') {\n          acc.flipY = true;\n          return acc;\n        }\n\n        rest = parseFloat(rest);\n\n        if (isNaN(rest)) {\n          return acc;\n        }\n\n        switch (first) {\n          case 'grow':\n            acc.size = acc.size + rest;\n            break;\n\n          case 'shrink':\n            acc.size = acc.size - rest;\n            break;\n\n          case 'left':\n            acc.x = acc.x - rest;\n            break;\n\n          case 'right':\n            acc.x = acc.x + rest;\n            break;\n\n          case 'up':\n            acc.y = acc.y - rest;\n            break;\n\n          case 'down':\n            acc.y = acc.y + rest;\n            break;\n\n          case 'rotate':\n            acc.rotate = acc.rotate + rest;\n            break;\n        }\n\n        return acc;\n      }, transform);\n    }\n  };\n  function transformParser (node) {\n    return parseTransformString(node.getAttribute('data-fa-transform'));\n  }\n\n  function symbolParser (node) {\n    var symbol = node.getAttribute('data-fa-symbol');\n    return symbol === null ? false : symbol === '' ? true : symbol;\n  }\n\n  function attributesParser (node) {\n    var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) {\n      if (acc.name !== 'class' && acc.name !== 'style') {\n        acc[attr.name] = attr.value;\n      }\n\n      return acc;\n    }, {});\n    var title = node.getAttribute('title');\n    var titleId = node.getAttribute('data-fa-title-id');\n\n    if (config.autoA11y) {\n      if (title) {\n        extraAttributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n      } else {\n        extraAttributes['aria-hidden'] = 'true';\n        extraAttributes['focusable'] = 'false';\n      }\n    }\n\n    return extraAttributes;\n  }\n\n  function maskParser (node) {\n    var mask = node.getAttribute('data-fa-mask');\n\n    if (!mask) {\n      return emptyCanonicalIcon();\n    } else {\n      return getCanonicalIcon(mask.split(' ').map(function (i) {\n        return i.trim();\n      }));\n    }\n  }\n\n  function blankMeta() {\n    return {\n      iconName: null,\n      title: null,\n      titleId: null,\n      prefix: null,\n      transform: meaninglessTransform,\n      symbol: false,\n      mask: null,\n      maskId: null,\n      extra: {\n        classes: [],\n        styles: {},\n        attributes: {}\n      }\n    };\n  }\n  function parseMeta(node) {\n    var _classParser = classParser(node),\n        iconName = _classParser.iconName,\n        prefix = _classParser.prefix,\n        extraClasses = _classParser.rest;\n\n    var extraStyles = styleParser(node);\n    var transform = transformParser(node);\n    var symbol = symbolParser(node);\n    var extraAttributes = attributesParser(node);\n    var mask = maskParser(node);\n    return {\n      iconName: iconName,\n      title: node.getAttribute('title'),\n      titleId: node.getAttribute('data-fa-title-id'),\n      prefix: prefix,\n      transform: transform,\n      symbol: symbol,\n      mask: mask,\n      maskId: node.getAttribute('data-fa-mask-id'),\n      extra: {\n        classes: extraClasses,\n        styles: extraStyles,\n        attributes: extraAttributes\n      }\n    };\n  }\n\n  function MissingIcon(error) {\n    this.name = 'MissingIcon';\n    this.message = error || 'Icon unavailable';\n    this.stack = new Error().stack;\n  }\n  MissingIcon.prototype = Object.create(Error.prototype);\n  MissingIcon.prototype.constructor = MissingIcon;\n\n  var FILL = {\n    fill: 'currentColor'\n  };\n  var ANIMATION_BASE = {\n    attributeType: 'XML',\n    repeatCount: 'indefinite',\n    dur: '2s'\n  };\n  var RING = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z'\n    })\n  };\n\n  var OPACITY_ANIMATE = _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n    attributeName: 'opacity'\n  });\n\n  var DOT = {\n    tag: 'circle',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      cx: '256',\n      cy: '364',\n      r: '28'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n        attributeName: 'r',\n        values: '28;14;28;28;14;28;'\n      })\n    }, {\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '1;0;1;1;0;1;'\n      })\n    }]\n  };\n  var QUESTION = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      opacity: '1',\n      d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '1;0;0;0;0;1;'\n      })\n    }]\n  };\n  var EXCLAMATION = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      opacity: '0',\n      d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '0;0;1;1;0;0;'\n      })\n    }]\n  };\n  var missing = {\n    tag: 'g',\n    children: [RING, DOT, QUESTION, EXCLAMATION]\n  };\n\n  var styles$2 = namespace.styles;\n  function asFoundIcon(icon) {\n    var width = icon[0];\n    var height = icon[1];\n\n    var _icon$slice = icon.slice(4),\n        _icon$slice2 = _slicedToArray(_icon$slice, 1),\n        vectorData = _icon$slice2[0];\n\n    var element = null;\n\n    if (Array.isArray(vectorData)) {\n      element = {\n        tag: 'g',\n        attributes: {\n          class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.GROUP)\n        },\n        children: [{\n          tag: 'path',\n          attributes: {\n            class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.SECONDARY),\n            fill: 'currentColor',\n            d: vectorData[0]\n          }\n        }, {\n          tag: 'path',\n          attributes: {\n            class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.PRIMARY),\n            fill: 'currentColor',\n            d: vectorData[1]\n          }\n        }]\n      };\n    } else {\n      element = {\n        tag: 'path',\n        attributes: {\n          fill: 'currentColor',\n          d: vectorData\n        }\n      };\n    }\n\n    return {\n      found: true,\n      width: width,\n      height: height,\n      icon: element\n    };\n  }\n  function findIcon(iconName, prefix) {\n    return new picked(function (resolve, reject) {\n      var val = {\n        found: false,\n        width: 512,\n        height: 512,\n        icon: missing\n      };\n\n      if (iconName && prefix && styles$2[prefix] && styles$2[prefix][iconName]) {\n        var icon = styles$2[prefix][iconName];\n        return resolve(asFoundIcon(icon));\n      }\n\n      if (iconName && prefix && !config.showMissingIcons) {\n        reject(new MissingIcon(\"Icon is missing for prefix \".concat(prefix, \" with icon name \").concat(iconName)));\n      } else {\n        resolve(val);\n      }\n    });\n  }\n\n  var styles$3 = namespace.styles;\n\n  function generateSvgReplacementMutation(node, nodeMeta) {\n    var iconName = nodeMeta.iconName,\n        title = nodeMeta.title,\n        titleId = nodeMeta.titleId,\n        prefix = nodeMeta.prefix,\n        transform = nodeMeta.transform,\n        symbol = nodeMeta.symbol,\n        mask = nodeMeta.mask,\n        maskId = nodeMeta.maskId,\n        extra = nodeMeta.extra;\n    return new picked(function (resolve, reject) {\n      picked.all([findIcon(iconName, prefix), findIcon(mask.iconName, mask.prefix)]).then(function (_ref) {\n        var _ref2 = _slicedToArray(_ref, 2),\n            main = _ref2[0],\n            mask = _ref2[1];\n\n        resolve([node, makeInlineSvgAbstract({\n          icons: {\n            main: main,\n            mask: mask\n          },\n          prefix: prefix,\n          iconName: iconName,\n          transform: transform,\n          symbol: symbol,\n          mask: mask,\n          maskId: maskId,\n          title: title,\n          titleId: titleId,\n          extra: extra,\n          watchable: true\n        })]);\n      });\n    });\n  }\n\n  function generateLayersText(node, nodeMeta) {\n    var title = nodeMeta.title,\n        transform = nodeMeta.transform,\n        extra = nodeMeta.extra;\n    var width = null;\n    var height = null;\n\n    if (IS_IE) {\n      var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10);\n      var boundingClientRect = node.getBoundingClientRect();\n      width = boundingClientRect.width / computedFontSize;\n      height = boundingClientRect.height / computedFontSize;\n    }\n\n    if (config.autoA11y && !title) {\n      extra.attributes['aria-hidden'] = 'true';\n    }\n\n    return picked.resolve([node, makeLayersTextAbstract({\n      content: node.innerHTML,\n      width: width,\n      height: height,\n      transform: transform,\n      title: title,\n      extra: extra,\n      watchable: true\n    })]);\n  }\n\n  function generateMutation(node) {\n    var nodeMeta = parseMeta(node);\n\n    if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) {\n      return generateLayersText(node, nodeMeta);\n    } else {\n      return generateSvgReplacementMutation(node, nodeMeta);\n    }\n  }\n\n  function onTree(root) {\n    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n    if (!IS_DOM) return;\n    var htmlClassList = DOCUMENT.documentElement.classList;\n\n    var hclAdd = function hclAdd(suffix) {\n      return htmlClassList.add(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n    };\n\n    var hclRemove = function hclRemove(suffix) {\n      return htmlClassList.remove(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n    };\n\n    var prefixes = config.autoFetchSvg ? Object.keys(PREFIX_TO_STYLE) : Object.keys(styles$3);\n    var prefixesDomQuery = [\".\".concat(LAYERS_TEXT_CLASSNAME, \":not([\").concat(DATA_FA_I2SVG, \"])\")].concat(prefixes.map(function (p) {\n      return \".\".concat(p, \":not([\").concat(DATA_FA_I2SVG, \"])\");\n    })).join(', ');\n\n    if (prefixesDomQuery.length === 0) {\n      return;\n    }\n\n    var candidates = [];\n\n    try {\n      candidates = toArray(root.querySelectorAll(prefixesDomQuery));\n    } catch (e) {// noop\n    }\n\n    if (candidates.length > 0) {\n      hclAdd('pending');\n      hclRemove('complete');\n    } else {\n      return;\n    }\n\n    var mark = perf.begin('onTree');\n    var mutations = candidates.reduce(function (acc, node) {\n      try {\n        var mutation = generateMutation(node);\n\n        if (mutation) {\n          acc.push(mutation);\n        }\n      } catch (e) {\n        if (!PRODUCTION) {\n          if (e instanceof MissingIcon) {\n            console.error(e);\n          }\n        }\n      }\n\n      return acc;\n    }, []);\n    return new picked(function (resolve, reject) {\n      picked.all(mutations).then(function (resolvedMutations) {\n        perform(resolvedMutations, function () {\n          hclAdd('active');\n          hclAdd('complete');\n          hclRemove('pending');\n          if (typeof callback === 'function') callback();\n          mark();\n          resolve();\n        });\n      }).catch(function () {\n        mark();\n        reject();\n      });\n    });\n  }\n  function onNode(node) {\n    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n    generateMutation(node).then(function (mutation) {\n      if (mutation) {\n        perform([mutation], callback);\n      }\n    });\n  }\n\n  function replaceForPosition(node, position) {\n    var pendingAttribute = \"\".concat(DATA_FA_PSEUDO_ELEMENT_PENDING).concat(position.replace(':', '-'));\n    return new picked(function (resolve, reject) {\n      if (node.getAttribute(pendingAttribute) !== null) {\n        // This node is already being processed\n        return resolve();\n      }\n\n      var children = toArray(node.children);\n      var alreadyProcessedPseudoElement = children.filter(function (c) {\n        return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === position;\n      })[0];\n      var styles = WINDOW.getComputedStyle(node, position);\n      var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN);\n      var fontWeight = styles.getPropertyValue('font-weight');\n      var content = styles.getPropertyValue('content');\n\n      if (alreadyProcessedPseudoElement && !fontFamily) {\n        // If we've already processed it but the current computed style does not result in a font-family,\n        // that probably means that a class name that was previously present to make the icon has been\n        // removed. So we now should delete the icon.\n        node.removeChild(alreadyProcessedPseudoElement);\n        return resolve();\n      } else if (fontFamily && content !== 'none' && content !== '') {\n        var _content = styles.getPropertyValue('content');\n\n        var prefix = ~['Solid', 'Regular', 'Light', 'Duotone', 'Brands', 'Kit'].indexOf(fontFamily[2]) ? STYLE_TO_PREFIX[fontFamily[2].toLowerCase()] : FONT_WEIGHT_TO_PREFIX[fontWeight];\n        var hexValue = toHex(_content.length === 3 ? _content.substr(1, 1) : _content);\n        var iconName = byUnicode(prefix, hexValue);\n        var iconIdentifier = iconName; // Only convert the pseudo element in this :before/:after position into an icon if we haven't\n        // already done so with the same prefix and iconName\n\n        if (iconName && (!alreadyProcessedPseudoElement || alreadyProcessedPseudoElement.getAttribute(DATA_PREFIX) !== prefix || alreadyProcessedPseudoElement.getAttribute(DATA_ICON) !== iconIdentifier)) {\n          node.setAttribute(pendingAttribute, iconIdentifier);\n\n          if (alreadyProcessedPseudoElement) {\n            // Delete the old one, since we're replacing it with a new one\n            node.removeChild(alreadyProcessedPseudoElement);\n          }\n\n          var meta = blankMeta();\n          var extra = meta.extra;\n          extra.attributes[DATA_FA_PSEUDO_ELEMENT] = position;\n          findIcon(iconName, prefix).then(function (main) {\n            var abstract = makeInlineSvgAbstract(_objectSpread2(_objectSpread2({}, meta), {}, {\n              icons: {\n                main: main,\n                mask: emptyCanonicalIcon()\n              },\n              prefix: prefix,\n              iconName: iconIdentifier,\n              extra: extra,\n              watchable: true\n            }));\n            var element = DOCUMENT.createElement('svg');\n\n            if (position === ':before') {\n              node.insertBefore(element, node.firstChild);\n            } else {\n              node.appendChild(element);\n            }\n\n            element.outerHTML = abstract.map(function (a) {\n              return toHtml(a);\n            }).join('\\n');\n            node.removeAttribute(pendingAttribute);\n            resolve();\n          }).catch(reject);\n        } else {\n          resolve();\n        }\n      } else {\n        resolve();\n      }\n    });\n  }\n\n  function replace(node) {\n    return picked.all([replaceForPosition(node, ':before'), replaceForPosition(node, ':after')]);\n  }\n\n  function processable(node) {\n    return node.parentNode !== document.head && !~TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS.indexOf(node.tagName.toUpperCase()) && !node.getAttribute(DATA_FA_PSEUDO_ELEMENT) && (!node.parentNode || node.parentNode.tagName !== 'svg');\n  }\n\n  function searchPseudoElements (root) {\n    if (!IS_DOM) return;\n    return new picked(function (resolve, reject) {\n      var operations = toArray(root.querySelectorAll('*')).filter(processable).map(replace);\n      var end = perf.begin('searchPseudoElements');\n      disableObservation();\n      picked.all(operations).then(function () {\n        end();\n        enableObservation();\n        resolve();\n      }).catch(function () {\n        end();\n        enableObservation();\n        reject();\n      });\n    });\n  }\n\n  var baseStyles = \"svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;-webkit-box-sizing:border-box;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor);opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.fad.fa-inverse{color:#fff}\";\n\n  function css () {\n    var dfp = DEFAULT_FAMILY_PREFIX;\n    var drc = DEFAULT_REPLACEMENT_CLASS;\n    var fp = config.familyPrefix;\n    var rc = config.replacementClass;\n    var s = baseStyles;\n\n    if (fp !== dfp || rc !== drc) {\n      var dPatt = new RegExp(\"\\\\.\".concat(dfp, \"\\\\-\"), 'g');\n      var customPropPatt = new RegExp(\"\\\\--\".concat(dfp, \"\\\\-\"), 'g');\n      var rPatt = new RegExp(\"\\\\.\".concat(drc), 'g');\n      s = s.replace(dPatt, \".\".concat(fp, \"-\")).replace(customPropPatt, \"--\".concat(fp, \"-\")).replace(rPatt, \".\".concat(rc));\n    }\n\n    return s;\n  }\n\n  var Library = /*#__PURE__*/function () {\n    function Library() {\n      _classCallCheck(this, Library);\n\n      this.definitions = {};\n    }\n\n    _createClass(Library, [{\n      key: \"add\",\n      value: function add() {\n        var _this = this;\n\n        for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) {\n          definitions[_key] = arguments[_key];\n        }\n\n        var additions = definitions.reduce(this._pullDefinitions, {});\n        Object.keys(additions).forEach(function (key) {\n          _this.definitions[key] = _objectSpread2(_objectSpread2({}, _this.definitions[key] || {}), additions[key]);\n          defineIcons(key, additions[key]);\n          build();\n        });\n      }\n    }, {\n      key: \"reset\",\n      value: function reset() {\n        this.definitions = {};\n      }\n    }, {\n      key: \"_pullDefinitions\",\n      value: function _pullDefinitions(additions, definition) {\n        var normalized = definition.prefix && definition.iconName && definition.icon ? {\n          0: definition\n        } : definition;\n        Object.keys(normalized).map(function (key) {\n          var _normalized$key = normalized[key],\n              prefix = _normalized$key.prefix,\n              iconName = _normalized$key.iconName,\n              icon = _normalized$key.icon;\n          if (!additions[prefix]) additions[prefix] = {};\n          additions[prefix][iconName] = icon;\n        });\n        return additions;\n      }\n    }]);\n\n    return Library;\n  }();\n\n  function ensureCss() {\n    if (config.autoAddCss && !_cssInserted) {\n      insertCss(css());\n\n      _cssInserted = true;\n    }\n  }\n\n  function apiObject(val, abstractCreator) {\n    Object.defineProperty(val, 'abstract', {\n      get: abstractCreator\n    });\n    Object.defineProperty(val, 'html', {\n      get: function get() {\n        return val.abstract.map(function (a) {\n          return toHtml(a);\n        });\n      }\n    });\n    Object.defineProperty(val, 'node', {\n      get: function get() {\n        if (!IS_DOM) return;\n        var container = DOCUMENT.createElement('div');\n        container.innerHTML = val.html;\n        return container.children;\n      }\n    });\n    return val;\n  }\n\n  function findIconDefinition(iconLookup) {\n    var _iconLookup$prefix = iconLookup.prefix,\n        prefix = _iconLookup$prefix === void 0 ? 'fa' : _iconLookup$prefix,\n        iconName = iconLookup.iconName;\n    if (!iconName) return;\n    return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName);\n  }\n\n  function resolveIcons(next) {\n    return function (maybeIconDefinition) {\n      var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n      var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {});\n      var mask = params.mask;\n\n      if (mask) {\n        mask = (mask || {}).icon ? mask : findIconDefinition(mask || {});\n      }\n\n      return next(iconDefinition, _objectSpread2(_objectSpread2({}, params), {}, {\n        mask: mask\n      }));\n    };\n  }\n\n  var library = new Library();\n  var noAuto = function noAuto() {\n    config.autoReplaceSvg = false;\n    config.observeMutations = false;\n    disconnect();\n  };\n  var _cssInserted = false;\n  var dom = {\n    i2svg: function i2svg() {\n      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n      if (IS_DOM) {\n        ensureCss();\n        var _params$node = params.node,\n            node = _params$node === void 0 ? DOCUMENT : _params$node,\n            _params$callback = params.callback,\n            callback = _params$callback === void 0 ? function () {} : _params$callback;\n\n        if (config.searchPseudoElements) {\n          searchPseudoElements(node);\n        }\n\n        return onTree(node, callback);\n      } else {\n        return picked.reject('Operation requires a DOM of some kind.');\n      }\n    },\n    css: css,\n    insertCss: function insertCss$$1() {\n      if (!_cssInserted) {\n        insertCss(css());\n\n        _cssInserted = true;\n      }\n    },\n    watch: function watch() {\n      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n      var autoReplaceSvgRoot = params.autoReplaceSvgRoot,\n          observeMutationsRoot = params.observeMutationsRoot;\n\n      if (config.autoReplaceSvg === false) {\n        config.autoReplaceSvg = true;\n      }\n\n      config.observeMutations = true;\n      domready(function () {\n        autoReplace({\n          autoReplaceSvgRoot: autoReplaceSvgRoot\n        });\n        observe({\n          treeCallback: onTree,\n          nodeCallback: onNode,\n          pseudoElementsCallback: searchPseudoElements,\n          observeMutationsRoot: observeMutationsRoot\n        });\n      });\n    }\n  };\n  var parse = {\n    transform: function transform(transformString) {\n      return parseTransformString(transformString);\n    }\n  };\n  var icon = resolveIcons(function (iconDefinition) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$transform = params.transform,\n        transform = _params$transform === void 0 ? meaninglessTransform : _params$transform,\n        _params$symbol = params.symbol,\n        symbol = _params$symbol === void 0 ? false : _params$symbol,\n        _params$mask = params.mask,\n        mask = _params$mask === void 0 ? null : _params$mask,\n        _params$maskId = params.maskId,\n        maskId = _params$maskId === void 0 ? null : _params$maskId,\n        _params$title = params.title,\n        title = _params$title === void 0 ? null : _params$title,\n        _params$titleId = params.titleId,\n        titleId = _params$titleId === void 0 ? null : _params$titleId,\n        _params$classes = params.classes,\n        classes = _params$classes === void 0 ? [] : _params$classes,\n        _params$attributes = params.attributes,\n        attributes = _params$attributes === void 0 ? {} : _params$attributes,\n        _params$styles = params.styles,\n        styles = _params$styles === void 0 ? {} : _params$styles;\n    if (!iconDefinition) return;\n    var prefix = iconDefinition.prefix,\n        iconName = iconDefinition.iconName,\n        icon = iconDefinition.icon;\n    return apiObject(_objectSpread2({\n      type: 'icon'\n    }, iconDefinition), function () {\n      ensureCss();\n\n      if (config.autoA11y) {\n        if (title) {\n          attributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n        } else {\n          attributes['aria-hidden'] = 'true';\n          attributes['focusable'] = 'false';\n        }\n      }\n\n      return makeInlineSvgAbstract({\n        icons: {\n          main: asFoundIcon(icon),\n          mask: mask ? asFoundIcon(mask.icon) : {\n            found: false,\n            width: null,\n            height: null,\n            icon: {}\n          }\n        },\n        prefix: prefix,\n        iconName: iconName,\n        transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n        symbol: symbol,\n        title: title,\n        maskId: maskId,\n        titleId: titleId,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: classes\n        }\n      });\n    });\n  });\n  var text = function text(content) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$transform2 = params.transform,\n        transform = _params$transform2 === void 0 ? meaninglessTransform : _params$transform2,\n        _params$title2 = params.title,\n        title = _params$title2 === void 0 ? null : _params$title2,\n        _params$classes2 = params.classes,\n        classes = _params$classes2 === void 0 ? [] : _params$classes2,\n        _params$attributes2 = params.attributes,\n        attributes = _params$attributes2 === void 0 ? {} : _params$attributes2,\n        _params$styles2 = params.styles,\n        styles = _params$styles2 === void 0 ? {} : _params$styles2;\n    return apiObject({\n      type: 'text',\n      content: content\n    }, function () {\n      ensureCss();\n      return makeLayersTextAbstract({\n        content: content,\n        transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n        title: title,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: [\"\".concat(config.familyPrefix, \"-layers-text\")].concat(_toConsumableArray(classes))\n        }\n      });\n    });\n  };\n  var counter = function counter(content) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$title3 = params.title,\n        title = _params$title3 === void 0 ? null : _params$title3,\n        _params$classes3 = params.classes,\n        classes = _params$classes3 === void 0 ? [] : _params$classes3,\n        _params$attributes3 = params.attributes,\n        attributes = _params$attributes3 === void 0 ? {} : _params$attributes3,\n        _params$styles3 = params.styles,\n        styles = _params$styles3 === void 0 ? {} : _params$styles3;\n    return apiObject({\n      type: 'counter',\n      content: content\n    }, function () {\n      ensureCss();\n      return makeLayersCounterAbstract({\n        content: content.toString(),\n        title: title,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: [\"\".concat(config.familyPrefix, \"-layers-counter\")].concat(_toConsumableArray(classes))\n        }\n      });\n    });\n  };\n  var layer = function layer(assembler) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$classes4 = params.classes,\n        classes = _params$classes4 === void 0 ? [] : _params$classes4;\n    return apiObject({\n      type: 'layer'\n    }, function () {\n      ensureCss();\n      var children = [];\n      assembler(function (args) {\n        Array.isArray(args) ? args.map(function (a) {\n          children = children.concat(a.abstract);\n        }) : children = children.concat(args.abstract);\n      });\n      return [{\n        tag: 'span',\n        attributes: {\n          class: [\"\".concat(config.familyPrefix, \"-layers\")].concat(_toConsumableArray(classes)).join(' ')\n        },\n        children: children\n      }];\n    });\n  };\n  var api = {\n    noAuto: noAuto,\n    config: config,\n    dom: dom,\n    library: library,\n    parse: parse,\n    findIconDefinition: findIconDefinition,\n    icon: icon,\n    text: text,\n    counter: counter,\n    layer: layer,\n    toHtml: toHtml\n  };\n\n  var autoReplace = function autoReplace() {\n    var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n    var _params$autoReplaceSv = params.autoReplaceSvgRoot,\n        autoReplaceSvgRoot = _params$autoReplaceSv === void 0 ? DOCUMENT : _params$autoReplaceSv;\n    if ((Object.keys(namespace.styles).length > 0 || config.autoFetchSvg) && IS_DOM && config.autoReplaceSvg) api.dom.i2svg({\n      node: autoReplaceSvgRoot\n    });\n  };\n\n  function bootstrap() {\n    if (IS_BROWSER) {\n      if (!WINDOW.FontAwesome) {\n        WINDOW.FontAwesome = api;\n      }\n\n      domready(function () {\n        autoReplace();\n        observe({\n          treeCallback: onTree,\n          nodeCallback: onNode,\n          pseudoElementsCallback: searchPseudoElements\n        });\n      });\n    }\n\n    namespace.hooks = _objectSpread2(_objectSpread2({}, namespace.hooks), {}, {\n      addPack: function addPack(prefix, icons) {\n        namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), icons);\n        build();\n        autoReplace();\n      },\n      addShims: function addShims(shims) {\n        var _namespace$shims;\n\n        (_namespace$shims = namespace.shims).push.apply(_namespace$shims, _toConsumableArray(shims));\n\n        build();\n        autoReplace();\n      }\n    });\n  }\n\n  bunker(bootstrap);\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js/brands.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"aws\": [640, 512, [], \"f375\", \"M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z\"],\n    \"cc-amazon-pay\": [576, 512, [], \"f42d\", \"M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z\"],\n    \"cc-amex\": [576, 512, [], \"f1f3\", \"M325.1 167.8c0-16.4-14.1-18.4-27.4-18.4l-39.1-.3v69.3H275v-25.1h18c18.4 0 14.5 10.3 14.8 25.1h16.6v-13.5c0-9.2-1.5-15.1-11-18.4 7.4-3 11.8-10.7 11.7-18.7zm-29.4 11.3H275v-15.3h21c5.1 0 10.7 1 10.7 7.4 0 6.6-5.3 7.9-11 7.9zM279 268.6h-52.7l-21 22.8-20.5-22.8h-66.5l-.1 69.3h65.4l21.3-23 20.4 23h32.2l.1-23.3c18.9 0 49.3 4.6 49.3-23.3 0-17.3-12.3-22.7-27.9-22.7zm-103.8 54.7h-40.6v-13.8h36.3v-14.1h-36.3v-12.5h41.7l17.9 20.2zm65.8 8.2l-25.3-28.1L241 276zm37.8-31h-21.2v-17.6h21.5c5.6 0 10.2 2.3 10.2 8.4 0 6.4-4.6 9.2-10.5 9.2zm-31.6-136.7v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5zM576 255.4h-.2zm-194.6 31.9c0-16.4-14.1-18.7-27.1-18.7h-39.4l-.1 69.3h16.6l.1-25.3h17.6c11 0 14.8 2 14.8 13.8l-.1 11.5h16.6l.1-13.8c0-8.9-1.8-15.1-11-18.4 7.7-3.1 11.8-10.8 11.9-18.4zm-29.2 11.2h-20.7v-15.6h21c5.1 0 10.7 1 10.7 7.4 0 6.9-5.4 8.2-11 8.2zm-172.8-80v-69.3h-27.6l-19.7 47-21.7-47H83.3v65.7l-28.1-65.7H30.7L1 218.5h17.9l6.4-15.3h34.5l6.4 15.3H100v-54.2l24 54.2h14.6l24-54.2v54.2zM31.2 188.8l11.2-27.6 11.5 27.6zm477.4 158.9v-4.5c-10.8 5.6-3.9 4.5-156.7 4.5 0-25.2.1-23.9 0-25.2-1.7-.1-3.2-.1-9.4-.1 0 17.9-.1 6.8-.1 25.3h-39.6c0-12.1.1-15.3.1-29.2-10 6-22.8 6.4-34.3 6.2 0 14.7-.1 8.3-.1 23h-48.9c-5.1-5.7-2.7-3.1-15.4-17.4-3.2 3.5-12.8 13.9-16.1 17.4h-82v-92.3h83.1c5 5.6 2.8 3.1 15.5 17.2 3.2-3.5 12.2-13.4 15.7-17.2h58c9.8 0 18 1.9 24.3 5.6v-5.6c54.3 0 64.3-1.4 75.7 5.1v-5.1h78.2v5.2c11.4-6.9 19.6-5.2 64.9-5.2v5c10.3-5.9 16.6-5.2 54.3-5V80c0-26.5-21.5-48-48-48h-480c-26.5 0-48 21.5-48 48v109.8c9.4-21.9 19.7-46 23.1-53.9h39.7c4.3 10.1 1.6 3.7 9 21.1v-21.1h46c2.9 6.2 11.1 24 13.9 30 5.8-13.6 10.1-23.9 12.6-30h103c0-.1 11.5 0 11.6 0 43.7.2 53.6-.8 64.4 5.3v-5.3H363v9.3c7.6-6.1 17.9-9.3 30.7-9.3h27.6c0 .5 1.9.3 2.3.3H456c4.2 9.8 2.6 6 8.8 20.6v-20.6h43.3c4.9 8-1-1.8 11.2 18.4v-18.4h39.9v92h-41.6c-5.4-9-1.4-2.2-13.2-21.9v21.9h-52.8c-6.4-14.8-.1-.3-6.6-15.3h-19c-4.2 10-2.2 5.2-6.4 15.3h-26.8c-12.3 0-22.3-3-29.7-8.9v8.9h-66.5c-.3-13.9-.1-24.8-.1-24.8-1.8-.3-3.4-.2-9.8-.2v25.1H151.2v-11.4c-2.5 5.6-2.7 5.9-5.1 11.4h-29.5c-4-8.9-2.9-6.4-5.1-11.4v11.4H58.6c-4.2-10.1-2.2-5.3-6.4-15.3H33c-4.2 10-2.2 5.2-6.4 15.3H0V432c0 26.5 21.5 48 48 48h480.1c26.5 0 48-21.5 48-48v-90.4c-12.7 8.3-32.7 6.1-67.5 6.1zm36.3-64.5H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-57 39.8h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-42.2-40.1v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5zm-56.3-108.1c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm20.4-10.5h-.1zm-16.2-15.2c-23.5 0-34 12-34 35.3 0 22.2 10.2 34 33 34h19.2l6.4-15.3h34.3l6.6 15.3h33.7v-51.9l31.2 51.9h23.6v-69h-16.9v48.1l-29.1-48.1h-25.3v65.4l-27.9-65.4h-24.8l-23.5 54.5h-7.4c-13.3 0-16.1-8.1-16.1-19.9 0-23.8 15.7-20 33.1-19.7v-15.2zm42.1 12.1l11.2 27.6h-22.8zm-101.1-12v69.3h16.9v-69.3z\"],\n    \"cc-apple-pay\": [576, 512, [], \"f416\", \"M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z\"],\n    \"cc-diners-club\": [576, 512, [], \"f24c\", \"M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z\"],\n    \"cc-discover\": [576, 512, [], \"f1f2\", \"M520.4 196.1c0-7.9-5.5-12.1-15.6-12.1h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-44.1 138.9c22.6 0 52.9-4.1 52.9 24.4 0 12.6-6.6 20.7-18.7 23.2l25.8 34.4h-19.6l-22.2-32.8h-2.2v32.8h-16zm-55.9.1h45.3v14H444v18.2h28.3V217H444v22.2h29.3V253H428zm-68.7 0l21.9 55.2 22.2-55.2h17.5l-35.5 84.2h-8.6l-35-84.2zm-55.9-3c24.7 0 44.6 20 44.6 44.6 0 24.7-20 44.6-44.6 44.6-24.7 0-44.6-20-44.6-44.6 0-24.7 20-44.6 44.6-44.6zm-49.3 6.1v19c-20.1-20.1-46.8-4.7-46.8 19 0 25 27.5 38.5 46.8 19.2v19c-29.7 14.3-63.3-5.7-63.3-38.2 0-31.2 33.1-53 63.3-38zm-97.2 66.3c11.4 0 22.4-15.3-3.3-24.4-15-5.5-20.2-11.4-20.2-22.7 0-23.2 30.6-31.4 49.7-14.3l-8.4 10.8c-10.4-11.6-24.9-6.2-24.9 2.5 0 4.4 2.7 6.9 12.3 10.3 18.2 6.6 23.6 12.5 23.6 25.6 0 29.5-38.8 37.4-56.6 11.3l10.3-9.9c3.7 7.1 9.9 10.8 17.5 10.8zM55.4 253H32v-82h23.4c26.1 0 44.1 17 44.1 41.1 0 18.5-13.2 40.9-44.1 40.9zm67.5 0h-16v-82h16zM544 433c0 8.2-6.8 15-15 15H128c189.6-35.6 382.7-139.2 416-160zM74.1 191.6c-5.2-4.9-11.6-6.6-21.9-6.6H48v54.2h4.2c10.3 0 17-2 21.9-6.4 5.7-5.2 8.9-12.8 8.9-20.7s-3.2-15.5-8.9-20.5z\"],\n    \"cc-jcb\": [576, 512, [], \"f24b\", \"M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z\"],\n    \"cc-mastercard\": [576, 512, [], \"f1f1\", \"M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z\"],\n    \"cc-paypal\": [576, 512, [], \"f1f4\", \"M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z\"],\n    \"cc-stripe\": [576, 512, [], \"f1f5\", \"M492.4 220.8c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7zM375 223.4c-8.2 0-13.3 2.9-17 7l.2 52.8c3.5 3.7 8.5 6.7 16.8 6.7 13.1 0 21.9-14.3 21.9-33.4 0-18.6-9-33.2-21.9-33.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM122.2 281.1c0 25.6-20.3 40.1-49.9 40.3-12.2 0-25.6-2.4-38.8-8.1v-33.9c12 6.4 27.1 11.3 38.9 11.3 7.9 0 13.6-2.1 13.6-8.7 0-17-54-10.6-54-49.9 0-25.2 19.2-40.2 48-40.2 11.8 0 23.5 1.8 35.3 6.5v33.4c-10.8-5.8-24.5-9.1-35.3-9.1-7.5 0-12.1 2.2-12.1 7.7 0 16 54.3 8.4 54.3 50.7zm68.8-56.6h-27V275c0 20.9 22.5 14.4 27 12.6v28.9c-4.7 2.6-13.3 4.7-24.9 4.7-21.1 0-36.9-15.5-36.9-36.5l.2-113.9 34.7-7.4v30.8H191zm74 2.4c-4.5-1.5-18.7-3.6-27.1 7.4v84.4h-35.5V194.2h30.7l2.2 10.5c8.3-15.3 24.9-12.2 29.6-10.5h.1zm44.1 91.8h-35.7V194.2h35.7zm0-142.9l-35.7 7.6v-28.9l35.7-7.6zm74.1 145.5c-12.4 0-20-5.3-25.1-9l-.1 40.2-35.5 7.5V194.2h31.3l1.8 8.8c4.9-4.5 13.9-11.1 27.8-11.1 24.9 0 48.4 22.5 48.4 63.8 0 45.1-23.2 65.5-48.6 65.6zm160.4-51.5h-69.5c1.6 16.6 13.8 21.5 27.6 21.5 14.1 0 25.2-3 34.9-7.9V312c-9.7 5.3-22.4 9.2-39.4 9.2-34.6 0-58.8-21.7-58.8-64.5 0-36.2 20.5-64.9 54.3-64.9 33.7 0 51.3 28.7 51.3 65.1 0 3.5-.3 10.9-.4 12.9z\"],\n    \"cc-visa\": [576, 512, [], \"f1f0\", \"M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z\"],\n    \"discourse\": [448, 512, [], \"f393\", \"M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z\"],\n    \"docker\": [640, 512, [], \"f395\", \"M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z\"],\n    \"github\": [496, 512, [], \"f09b\", \"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\"],\n    \"instagram\": [448, 512, [], \"f16d\", \"M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z\"],\n    \"microsoft\": [448, 512, [], \"f3ca\", \"M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z\"],\n    \"rev\": [448, 512, [], \"f5b2\", \"M289.67 274.89a65.57 65.57 0 1 1-65.56-65.56 65.64 65.64 0 0 1 65.56 65.56zm139.55-5.05h-.13a204.69 204.69 0 0 0-74.32-153l-45.38 26.2a157.07 157.07 0 0 1 71.81 131.84C381.2 361.5 310.73 432 224.11 432S67 361.5 67 274.88c0-81.88 63-149.27 143-156.43v39.12l108.77-62.79L210 32v38.32c-106.7 7.25-191 96-191 204.57 0 111.59 89.12 202.29 200.06 205v.11h210.16V269.84z\"],\n    \"slack\": [448, 512, [], \"f198\", \"M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z\"],\n    \"twitter\": [512, 512, [], \"f099\", \"M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z\"]\n  };\n\n  bunker(function () {\n    defineIcons('fab', icons);\n  });\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js/duotone.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"abacus\": [576, 512, [], \"f640\", [\"M192 440h-32v-48h32zM160 72v48h32V72zm96 160v48h32v-48zm-96 0v48h32v-48zm96 208h160v-48H256zm96-160h128v-48H352zM544 0a32 32 0 0 0-32 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32a32 32 0 0 0-32-32zM416 72H256v48h160zM32 0A32 32 0 0 0 0 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32A32 32 0 0 0 32 0z\", \"M144 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm-96 160h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm192 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm-96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zM464 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM144 352h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm224 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16z\"]],\n    \"align-slash\": [640, 512, [], \"f846\", [\"M528 352h-31.46l-82.81-64H528a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16zM96 304v32a16 16 0 0 0 16 16h175.21l-82.8-64H112a16 16 0 0 0-16 16zM528 96a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16H112a15.82 15.82 0 0 0-15 11.18L165.31 96zM112 416a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h340.83L370 416zm416-256H248.12l82.81 64H528a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M633.82 458.1L45.46 3.38A16 16 0 0 0 23 6.19L3.37 31.46a16 16 0 0 0 2.81 22.45l588.36 454.72a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45z\"]],\n    \"atom-alt\": [448, 512, [], \"f5d3\", [\"M424.37305,55.69141C408.294,39.61914,385.50879,32,358.58252,32,319.82764,32,272.43359,48.127,224,77.14453a493.86641,493.86641,0,0,0-58.042,41.03711C140.58252,138.875,114.57666,162.5918,85.75635,197.916a374.25237,374.25237,0,0,0,35.70263,58.082A505.23427,505.23427,0,0,1,224,153.65625a377.23937,377.23937,0,0,1,58.042-35.47266c70.01221-34.334,95.22461-19.07421,97.0625-17.23632,9.54248,9.543,7.67432,46.94531-16.86084,96.96875A492.27615,492.27615,0,0,1,403.06543,256C452.27637,173.91992,463.59277,94.90039,424.37305,55.69141ZM224,358.3418a377.44678,377.44678,0,0,1-58.042,35.47461c-70.01221,34.334-95.22461,19.07421-97.0625,17.23632-9.54248-9.543-7.67432-46.94335,16.86084-96.96875A492.27615,492.27615,0,0,1,44.93457,256C-4.27637,338.08008-15.59277,417.09961,23.627,456.30664,39.70605,472.38086,62.49121,480,89.41748,480c38.75488,0,86.14893-16.127,134.58252-45.14453a493.86641,493.86641,0,0,0,58.042-41.03711c25.38965-20.70508,51.42285-44.45606,80.20166-79.73438A373.962,373.962,0,0,0,326.541,256,505.23427,505.23427,0,0,1,224,358.3418Z\", \"M224,287.98828a31.99414,31.99414,0,1,0-32-31.99414A31.98908,31.98908,0,0,0,224,287.98828ZM121.46094,255.99805A374.13921,374.13921,0,0,1,85.7583,197.916c-24.53906-50.02344-26.40625-87.42579-16.86328-96.9668,1.83984-1.83789,27.05078-17.10156,97.062,17.23242A494.241,494.241,0,0,1,224,77.14453C175.5625,48.13086,128.16406,32,89.41846,32c-26.9336,0-49.707,7.61523-65.793,23.69141C-15.59326,94.90039-4.27686,173.91992,44.93408,256A492.0174,492.0174,0,0,0,85.7583,314.084c28.79639,35.30274,54.85889,59.07227,80.19873,79.73243A377.429,377.429,0,0,0,224,358.3418,505.131,505.131,0,0,1,121.46094,255.99805ZM403.06592,256a492.0174,492.0174,0,0,0-40.82422-58.084c-28.84326-35.35547-54.89795-59.10352-80.19873-79.73243A377.4073,377.4073,0,0,0,224,153.65625,505.20556,505.20556,0,0,1,326.53906,256a373.849,373.849,0,0,1,35.70264,58.084c24.53906,50.02149,26.40625,87.42383,16.86328,96.9668-1.83984,1.83789-27.05078,17.10156-97.062-17.23242A494.241,494.241,0,0,1,224,434.85547C272.4375,463.86914,319.83594,480,358.58154,480c26.9336,0,49.707-7.61523,65.793-23.69336C463.59326,417.09961,452.27686,338.08008,403.06592,256Z\"]],\n    \"badge-check\": [512, 512, [], \"f336\", [\"M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z\", \"M367.2 211.75l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.06 15.56z\"]],\n    \"bell\": [448, 512, [], \"f0f3\", [\"M448 384c-.1 16.4-13 32-32.1 32H32.08C13 416 .09 400.4 0 384a31.25 31.25 0 0 1 8.61-21.71c19.32-20.76 55.47-52 55.47-154.29 0-77.7 54.48-139.9 127.94-155.16V32a32 32 0 1 1 64 0v20.84C329.42 68.1 383.9 130.3 383.9 208c0 102.3 36.15 133.53 55.47 154.29A31.27 31.27 0 0 1 448 384z\", \"M160 448h128a64 64 0 0 1-128 0z\"]],\n    \"books\": [576, 512, [], \"f5db\", [\"M96 0H32A32 32 0 0 0 0 32v64h128V32A32 32 0 0 0 96 0zM0 384h128V128H0zm0 96a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H0zm513.62-17.78L401.08 42.71l-60.26 16.14 112.35 418.8c.11.39.2.79.29 1.18l60.29-16.15c-.04-.15-.09-.3-.13-.46zM160 480a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H160zM256 0h-64a32 32 0 0 0-32 32v64h124.79l-8-29.65a23.94 23.94 0 0 1 11.17-27V32A32 32 0 0 0 256 0zm-96 384h128V128H160z\", \"M0 416h128v-32H0zm0-288h128V96H0zm575.17 317.65L460.39 17.78a23.89 23.89 0 0 0-29.18-17h-.09L415.73 5a24 24 0 0 0-16.9 29.36l114.79 427.86a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.35zM160 416h128v-32H160zM338.39 49.78a23.89 23.89 0 0 0-29.18-17h-.09L293.73 37a24 24 0 0 0-16.9 29.36l8 29.65H160v32h128V108l103.62 386.22a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.33z\"]],\n    \"brackets-curly\": [576, 512, [], \"f7ea\", [\"M566.64 233.37a32 32 0 0 1 0 45.25l-45.25 45.25a32 32 0 0 0-9.39 22.64V384a96 96 0 0 1-96 96h-48a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h48a32 32 0 0 0 32-32v-37.48a96 96 0 0 1 28.13-67.89L498.76 256l-22.62-22.62A96 96 0 0 1 448 165.47V128a32 32 0 0 0-32-32h-48a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h48a96 96 0 0 1 96 96v37.48a32 32 0 0 0 9.38 22.65l45.25 45.24z\", \"M208 32h-48a96 96 0 0 0-96 96v37.48a32.12 32.12 0 0 1-9.38 22.65L9.38 233.37a32 32 0 0 0 0 45.25l45.25 45.25A32.05 32.05 0 0 1 64 346.51V384a96 96 0 0 0 96 96h48a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-48a32 32 0 0 1-32-32v-37.48a96 96 0 0 0-28.13-67.89L77.26 256l22.63-22.63A96 96 0 0 0 128 165.48V128a32 32 0 0 1 32-32h48a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]],\n    \"chart-network\": [640, 512, [], \"f78a\", [\"M64 240a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64zm88 80h48v-32h-48zm294.4-106.8l19.2 25.6 48-36-19.2-25.6zM576 64a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64z\", \"M576 384a63.84 63.84 0 0 0-38.3 13l-96-57.6a109.91 109.91 0 0 0 6.3-35.5 111.94 111.94 0 0 0-112-112 108.64 108.64 0 0 0-24.4 2.9l-40.8-87.4A63.84 63.84 0 1 0 224 128c1.1 0 2.1-.3 3.2-.3l41 87.8C241.5 235.9 224 267.8 224 304a111.71 111.71 0 0 0 193.2 76.7l95.8 57.5a63.87 63.87 0 1 0 63-54.2zm-240-32a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]],\n    \"chart-scatter\": [512, 512, [], \"f7ee\", [\"M512 400v32a16 16 0 0 1-16 16H32a32 32 0 0 1-32-32V80a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16v304h432a16 16 0 0 1 16 16z\", \"M160 256a32 32 0 1 0 32 32 32 32 0 0 0-32-32zM416 96a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-224 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm192 160a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-96-64a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]],\n    \"check\": [512, 512, [], \"f00c\", [\"M504.5 144.42L264.75 385.5 192 312.59l240.11-241a25.49 25.49 0 0 1 36.06-.14l.14.14L504.5 108a25.86 25.86 0 0 1 0 36.42z\", \"M264.67 385.59l-54.57 54.87a25.5 25.5 0 0 1-36.06.14l-.14-.14L7.5 273.1a25.84 25.84 0 0 1 0-36.41l36.2-36.41a25.49 25.49 0 0 1 36-.17l.16.17z\"]],\n    \"circle\": [512, 512, [], \"f111\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 424c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\", \"M256 432c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\"]],\n    \"clouds\": [640, 512, [], \"f744\", [\"M161.6 288H96a96 96 0 0 1 0-192c.6 0 1.1.2 1.6.2C105.3 41.9 151.6 0 208 0a111.61 111.61 0 0 1 104.5 72.7A95.07 95.07 0 0 1 352 64a96 96 0 0 1 96 96 93 93 0 0 1-7 34.7 110.5 110.5 0 0 0-31.6 11.8A142.54 142.54 0 0 0 304 160c-73.9 0-134.3 56.2-142.4 128z\", \"M640 416a96 96 0 0 1-96 96H224a96 96 0 0 1-96-96c0-42.5 27.8-78.2 66.1-90.8A113.72 113.72 0 0 1 192 304a111.94 111.94 0 0 1 112-112c43.2 0 80.4 24.9 99 60.8 14.7-17.5 36.4-28.8 61-28.8a80 80 0 0 1 80 80 78.09 78.09 0 0 1-1.6 16.2c.5 0 1-.2 1.6-.2a96 96 0 0 1 96 96z\"]],\n    \"cogs\": [640, 512, [], \"f085\", [\"M638.41 387a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4L602 335a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6 12.36 12.36 0 0 0-15.1 5.4l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 44.9c-29.6-38.5 14.3-82.4 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79zm136.8-343.8a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4l8.2-14.3a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6A12.36 12.36 0 0 0 552 7.19l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 45c-29.6-38.5 14.3-82.5 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79z\", \"M420 303.79L386.31 287a173.78 173.78 0 0 0 0-63.5l33.7-16.8c10.1-5.9 14-18.2 10-29.1-8.9-24.2-25.9-46.4-42.1-65.8a23.93 23.93 0 0 0-30.3-5.3l-29.1 16.8a173.66 173.66 0 0 0-54.9-31.7V58a24 24 0 0 0-20-23.6 228.06 228.06 0 0 0-76 .1A23.82 23.82 0 0 0 158 58v33.7a171.78 171.78 0 0 0-54.9 31.7L74 106.59a23.91 23.91 0 0 0-30.3 5.3c-16.2 19.4-33.3 41.6-42.2 65.8a23.84 23.84 0 0 0 10.5 29l33.3 16.9a173.24 173.24 0 0 0 0 63.4L12 303.79a24.13 24.13 0 0 0-10.5 29.1c8.9 24.1 26 46.3 42.2 65.7a23.93 23.93 0 0 0 30.3 5.3l29.1-16.7a173.66 173.66 0 0 0 54.9 31.7v33.6a24 24 0 0 0 20 23.6 224.88 224.88 0 0 0 75.9 0 23.93 23.93 0 0 0 19.7-23.6v-33.6a171.78 171.78 0 0 0 54.9-31.7l29.1 16.8a23.91 23.91 0 0 0 30.3-5.3c16.2-19.4 33.7-41.6 42.6-65.8a24 24 0 0 0-10.5-29.1zm-151.3 4.3c-77 59.2-164.9-28.7-105.7-105.7 77-59.2 164.91 28.7 105.71 105.7z\"]],\n    \"comment-dots\": [512, 512, [], \"f4ad\", [\"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5a8 8 0 0 0-1.5 8.7A7.83 7.83 0 0 0 8 480c66.3 0 116-31.8 140.6-51.4A305 305 0 0 0 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32z\", \"M128 208a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]],\n    \"concierge-bell\": [512, 512, [], \"f562\", [\"M512 400v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h480a16 16 0 0 1 16 16zM208 112h16v18.29a224.73 224.73 0 0 1 64 0V112h16a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16z\", \"M480 352H32c0-123.71 100.29-224 224-224s224 100.29 224 224z\"]],\n    \"dot-circle\": [512, 512, [], \"f192\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm124.45 372.45A176 176 0 1 1 432 256a174.85 174.85 0 0 1-51.55 124.45z\", \"M256 336a80 80 0 1 1 80-80 80.09 80.09 0 0 1-80 80z\"]],\n    \"envelope\": [512, 512, [], \"f0e0\", [\"M256.47 352h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V400a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V183.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52zM464 64H48a48 48 0 0 0-48 48v19a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4 23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131v-19a48 48 0 0 0-48-48z\", \"M512 131v52.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V131a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.69 12.12 49.75 41.4 72.93 41.4h.94c23.18 0 56.24-29.28 72.93-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131z\"]],\n    \"exchange-alt\": [512, 512, [], \"f362\", [\"M128 272v48h360a24 24 0 0 1 24 24v16a24 24 0 0 1-24 24H128v48c0 21.44-25.94 32-41 17L7 369a24 24 0 0 1 0-33.94l80-80c15.14-15.12 41-4.35 41 16.94z\", \"M505 143.05a24 24 0 0 1 0 33.95l-80 80c-15 15-41 4.49-41-17v-48H24a24 24 0 0 1-24-24v-16a24 24 0 0 1 24-24h360V80c0-21.36 25.9-32 41-17z\"]],\n    \"file-alt\": [384, 512, [], \"f15c\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zm-96 244a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM276 352H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12z\"]],\n    \"file-code\": [384, 512, [], \"f1c9\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zM141.79 379.54l-19.58 20.84a5.41 5.41 0 0 1-7.64.24l-64.86-60.69a5.37 5.37 0 0 1-.24-7.6l.25-.25 64.86-60.7a5.42 5.42 0 0 1 7.64.24l19.58 20.85a5.4 5.4 0 0 1-.25 7.62l-.13.12L100.65 336l40.76 35.8a5.4 5.4 0 0 1 .49 7.62zm31.71 71.25l-27.45-8a5.38 5.38 0 0 1-3.67-6.67l61.49-211.24a5.38 5.38 0 0 1 6.68-3.64l27.45 8a5.4 5.4 0 0 1 3.63 6.67l-61.45 211.2a5.4 5.4 0 0 1-6.68 3.68zm161-111.12l-.25.25-64.86 60.69a5.42 5.42 0 0 1-7.64-.23l-19.58-20.84a5.37 5.37 0 0 1 .26-7.6l.13-.12L283.35 336l-40.76-35.8a5.4 5.4 0 0 1-.49-7.62l.11-.12 19.58-20.85a5.42 5.42 0 0 1 7.64-.24l64.86 60.7a5.36 5.36 0 0 1 .25 7.6z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM141.41 371.8L100.65 336l40.76-35.8.13-.12a5.4 5.4 0 0 0 .25-7.62l-19.58-20.85a5.42 5.42 0 0 0-7.64-.24l-64.86 60.7-.25.25a5.37 5.37 0 0 0 .24 7.6l64.86 60.69a5.41 5.41 0 0 0 7.64-.24l19.58-20.84.11-.12a5.4 5.4 0 0 0-.48-7.61zm100.22-135.93a5.4 5.4 0 0 0-3.63-6.67l-27.45-8a5.38 5.38 0 0 0-6.68 3.64l-61.5 211.29a5.38 5.38 0 0 0 3.63 6.67l27.45 8a5.4 5.4 0 0 0 6.68-3.68l61.44-211.22zm92.66 96.2l-64.86-60.7a5.42 5.42 0 0 0-7.64.24l-19.58 20.85-.11.12a5.4 5.4 0 0 0 .49 7.62l40.76 35.8-40.76 35.8-.13.12a5.37 5.37 0 0 0-.26 7.6l19.58 20.84a5.42 5.42 0 0 0 7.64.23l64.86-60.69.25-.25a5.36 5.36 0 0 0-.25-7.6z\"]],\n    \"globe\": [496, 512, [], \"f0ac\", [\"M340.45,320H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256,575,575,0,0,1,340.45,320ZM160.2,160H335.8c-.41-2.31-.84-4.62-1.28-6.91-6-30.85-14.42-58.37-25.13-81.78C299.54,49.77,288,32.54,276.05,21.48,266.38,12.53,256.94,8,248,8s-18.38,4.53-28,13.48c-12,11.06-23.49,28.29-33.34,49.83C176,94.72,167.5,122.24,161.53,153.09,161,155.38,160.61,157.69,160.2,160ZM120,256a608,608,0,0,1,3.34-64H8.35a249.52,249.52,0,0,0,0,128h115A608,608,0,0,1,120,256Zm367.62-64h-115A608.06,608.06,0,0,1,376,256a608,608,0,0,1-3.34,64h115a249.52,249.52,0,0,0,0-128ZM476.7,160A248.62,248.62,0,0,0,315.58,17.32c24.13,33,42.89,83.15,52.75,142.68ZM315.58,494.68A248.59,248.59,0,0,0,476.71,352H368.33C358.47,411.53,339.71,461.68,315.58,494.68ZM335.8,352H160.2c.41,2.31.84,4.62,1.28,6.91,6,30.85,14.42,58.37,25.13,81.78,9.85,21.54,21.38,38.77,33.34,49.83,9.67,9,19.11,13.48,28.05,13.48s18.38-4.53,28.05-13.48c12-11.06,23.49-28.29,33.34-49.83,10.71-23.41,19.16-50.93,25.13-81.78C335,356.62,335.39,354.31,335.8,352ZM180.42,17.32A248.59,248.59,0,0,0,19.29,160H127.67C137.53,100.47,156.29,50.32,180.42,17.32ZM19.29,352A248.59,248.59,0,0,0,180.42,494.68c-24.13-33-42.89-83.15-52.75-142.68Z\", \"M376,256a608,608,0,0,0-3.34-64h115a245.72,245.72,0,0,0-10.92-32H368.33c-9.86-59.53-28.62-109.68-52.75-142.68A248.23,248.23,0,0,0,248,8c8.94,0,18.38,4.53,28.05,13.48,12,11.06,23.49,28.29,33.34,49.83,10.71,23.41,19.16,50.93,25.13,81.78.44,2.29.87,4.6,1.28,6.91H160.2c.41-2.31.84-4.62,1.28-6.91,6-30.85,14.42-58.37,25.13-81.78C196.46,49.77,208,32.54,220,21.48,229.62,12.53,239.06,8,248,8a248.23,248.23,0,0,0-67.58,9.32c-24.13,33-42.89,83.15-52.75,142.68H19.29A245.72,245.72,0,0,0,8.37,192h115a613.93,613.93,0,0,0,0,128H8.37a245.72,245.72,0,0,0,10.92,32H127.67c9.86,59.53,28.62,109.68,52.75,142.68A248.23,248.23,0,0,0,248,504c-8.94,0-18.38-4.53-28.05-13.48-12-11.06-23.49-28.29-33.34-49.83-10.71-23.41-19.16-50.93-25.13-81.78-.44-2.29-.87-4.6-1.28-6.91H335.8c-.41,2.31-.84,4.62-1.28,6.91-6,30.85-14.42,58.37-25.13,81.78-9.85,21.54-21.38,38.77-33.34,49.83-9.67,9-19.11,13.48-28.05,13.48a248.23,248.23,0,0,0,67.58-9.32c24.13-33,42.89-83.15,52.75-142.68H476.71a245.72,245.72,0,0,0,10.92-32h-115A605.37,605.37,0,0,0,376,256Zm-35.54,64H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256a575,575,0,0,1-3.55,64Z\"]],\n    \"globe-africa\": [496, 512, [], \"f57c\", [\"M491.33,208H423.5A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05A249.89,249.89,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256A249.51,249.51,0,0,0,491.33,208Z\", \"M423.5,208A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05C386,23.7,471,104.24,491.34,208Z\"]],\n    \"globe-americas\": [496, 512, [], \"f57d\", [\"M489.55,312.41C464,422.22,365.59,504,248,504,111,504,0,393,0,256A247,247,0,0,1,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311l-13.71-13.67A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A247,247,0,0,1,248,8C351.83,8,440.71,71.76,477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1Z\", \"M321.39,297.36A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A249,249,0,0,0,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311ZM477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1,55.64,29.22a249.21,249.21,0,0,0-11.88-150.14Z\"]],\n    \"globe-asia\": [496, 512, [], \"f57e\", [\"M312,16.35V50.73a28,28,0,0,1-11.12,22.35l-41.41,31.27a8,8,0,0,0,.86,13.81l10.83,5.41A16,16,0,0,1,280,137.88V216a8,8,0,0,1-8,8h-3.06a8,8,0,0,1-7.15-4.42,4.47,4.47,0,0,0-1.72-1.86,4.42,4.42,0,0,0-6.06,1.54h0l-17.34,29A16,16,0,0,1,222.94,256h-.31a16,16,0,0,0-11.32,4.69l-5.66,5.66a8,8,0,0,0,0,11.31l5.66,5.66A16,16,0,0,1,216,294.63V304a16,16,0,0,1-16,16h-6.1a16,16,0,0,1-14.28-8.85L157,265.92a8,8,0,0,0-10.72-3.6h0a8.14,8.14,0,0,0-2.11,1.53l-19.47,19.46A16,16,0,0,1,113.38,288H2.05C17.74,409.88,121.84,504,248,504c137,0,248-111,248-248C496,141.13,418,44.56,312,16.35Zm96,342.08a16,16,0,0,1-4.69,11.31l-9.57,9.57A16,16,0,0,1,382.43,384H367.27a16,16,0,0,1-11.36-4.74l-13-13a26.78,26.78,0,0,0-25.42-7l-21.27,5.32a15.86,15.86,0,0,1-3.88.48H282a16,16,0,0,1-11.24-4.69l-11.91-11.91a8,8,0,0,1-2.34-5.66V332.6a8,8,0,0,1,5-7.43l39.34-15.74a26.35,26.35,0,0,0,5.59-3.05l23.71-16.89a8,8,0,0,1,4.64-1.48h12.14a8,8,0,0,1,7.39,4.93l5.35,12.85a4,4,0,0,0,3.69,2.46h3.8a4,4,0,0,0,3.84-2.88l4.16-14.49A4,4,0,0,1,379,288h6.06a4,4,0,0,1,4,4v13a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,1,408,333.83Z\", \"M260.07,217.72a4.47,4.47,0,0,1,1.72,1.86,8,8,0,0,0,7.15,4.42H272a8,8,0,0,0,8-8V137.88a16,16,0,0,0-8.84-14.31l-10.83-5.41a8,8,0,0,1-.86-13.81l41.41-31.27A28,28,0,0,0,312,50.73V16.35A248.23,248.23,0,0,0,248,8C111,8,0,119,0,256a249.89,249.89,0,0,0,2.05,32H113.38a16,16,0,0,0,11.31-4.69l19.47-19.46A8,8,0,0,1,157,265.92l22.62,45.23A16,16,0,0,0,193.9,320H200a16,16,0,0,0,16-16v-9.37a16,16,0,0,0-4.69-11.31l-5.66-5.66a8,8,0,0,1,0-11.31l5.66-5.66A16,16,0,0,1,222.63,256h.31a16,16,0,0,0,13.72-7.77L254,219.28a4.42,4.42,0,0,1,6.05-1.57Zm143.24,104.8L391.4,310.61a8,8,0,0,1-2.34-5.66V292a4,4,0,0,0-4-4H379a4,4,0,0,0-3.84,2.88L371,305.37a4,4,0,0,1-3.84,2.88h-3.8a4,4,0,0,1-3.69-2.46l-5.35-12.85a8,8,0,0,0-7.39-4.93H334.79a8,8,0,0,0-4.64,1.48l-23.71,16.89a26.35,26.35,0,0,1-5.59,3.05l-39.34,15.74a8,8,0,0,0-5,7.43v10.2a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,0,282,365.06h10.34a15.86,15.86,0,0,0,3.88-.48l21.27-5.32a26.78,26.78,0,0,1,25.42,7l13,13A16,16,0,0,0,367.27,384h15.16a16,16,0,0,0,11.31-4.69l9.57-9.57A16,16,0,0,0,408,358.43v-24.6a16,16,0,0,0-4.69-11.31Z\"]],\n    \"globe-europe\": [496, 512, [], \"f7a2\", [\"M487.54,320.4H438.9a15.8,15.8,0,0,1-11.4-4.8l-32-32.6a11.92,11.92,0,0,1,.1-16.7l12.5-12.5v-8.7a11.37,11.37,0,0,0-3.3-8l-9.4-9.4a11.37,11.37,0,0,0-8-3.3h-16a11.31,11.31,0,0,1-8-19.3l9.4-9.4a11.37,11.37,0,0,1,8-3.3h32a11.35,11.35,0,0,0,11.3-11.3v-9.4a11.35,11.35,0,0,0-11.3-11.3H376.1a16,16,0,0,0-16,16v4.5a16,16,0,0,1-10.9,15.2l-31.6,10.5a8,8,0,0,0-5.5,7.6v2.2a8,8,0,0,1-8,8h-16a8,8,0,0,1-8-8,8,8,0,0,0-8-8H269a8.14,8.14,0,0,0-7.2,4.4l-9.4,18.7a15.94,15.94,0,0,1-14.3,8.8H216a16,16,0,0,1-16-16V199a16,16,0,0,1,4.7-11.3l20.1-20.1a24.77,24.77,0,0,0,7.2-17.5,8,8,0,0,1,5.5-7.6l40-13.3a11.66,11.66,0,0,0,4.4-2.7l26.8-26.8a11.31,11.31,0,0,0-8-19.3H280l-16,16v8a8,8,0,0,1-8,8H240a8,8,0,0,1-8-8v-20a8.05,8.05,0,0,1,3.2-6.4l82.42-60.08A247.79,247.79,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504a251.57,251.57,0,0,0,32.1-2.06V448.4a16,16,0,0,0-16-16H243.9c-10.8,0-26.7-5.3-35.4-11.8l-22.2-16.7a45.42,45.42,0,0,1-18.2-36.4V343.6a45.46,45.46,0,0,1,22.1-39l42.9-25.7a46.13,46.13,0,0,1,23.4-6.5h31.2a45.62,45.62,0,0,1,29.6,10.9l43.2,37.1h18.3a32,32,0,0,1,22.6,9.4l17.3,17.3.08.08C432,359.06,440,375.62,440,393.37V413A247.11,247.11,0,0,0,487.54,320.4ZM187.4,157.1a11.37,11.37,0,0,1-8,3.3h-16a11.31,11.31,0,0,1-8-19.3l25.4-25.4a11.31,11.31,0,0,1,19.3,8v16a11.37,11.37,0,0,1-3.3,8Z\", \"M187.4,157.1l9.4-9.4a11.37,11.37,0,0,0,3.3-8v-16a11.31,11.31,0,0,0-19.3-8l-25.4,25.4a11.31,11.31,0,0,0,8,19.3h16A11.37,11.37,0,0,0,187.4,157.1ZM418.78,347.18l-.08-.08-17.3-17.3a32,32,0,0,0-22.6-9.4H360.5l-43.2-37.1a45.62,45.62,0,0,0-29.6-10.9H256.5a46.13,46.13,0,0,0-23.4,6.5l-42.9,25.7a45.46,45.46,0,0,0-22.1,39v23.9a45.42,45.42,0,0,0,18.2,36.4l22.2,16.7c8.7,6.5,24.6,11.8,35.4,11.8h20.2a16,16,0,0,1,16,16v53.54A247.57,247.57,0,0,0,440,413V393.37C440,375.62,432,359.06,418.78,347.18ZM317.62,17.92,235.2,78a8.05,8.05,0,0,0-3.2,6.4v20a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-8l16-16h20.7a11.31,11.31,0,0,1,8,19.3l-26.8,26.8a11.66,11.66,0,0,1-4.4,2.7l-40,13.3a8,8,0,0,0-5.5,7.6,24.77,24.77,0,0,1-7.2,17.5l-20.1,20.1A16,16,0,0,0,200,199v25.3a16,16,0,0,0,16,16h22.1a15.94,15.94,0,0,0,14.3-8.8l9.4-18.7a8.14,8.14,0,0,1,7.2-4.4h3.1a8,8,0,0,1,8,8,8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-2.2a8,8,0,0,1,5.5-7.6l31.6-10.5a16,16,0,0,0,10.9-15.2v-4.5a16,16,0,0,1,16-16h36.7a11.35,11.35,0,0,1,11.3,11.3v9.4a11.35,11.35,0,0,1-11.3,11.3h-32a11.37,11.37,0,0,0-8,3.3l-9.4,9.4a11.31,11.31,0,0,0,8,19.3h16a11.37,11.37,0,0,1,8,3.3l9.4,9.4a11.37,11.37,0,0,1,3.3,8v8.7l-12.5,12.5a11.92,11.92,0,0,0-.1,16.7l32,32.6a15.8,15.8,0,0,0,11.4,4.8h48.64A248.29,248.29,0,0,0,496,256C496,143.18,420.71,48,317.62,17.92Z\"]],\n    \"graduation-cap\": [640, 512, [], \"f19d\", [\"M323.07 175.7L118.8 215.6a48.1 48.1 0 0 0-38.74 44.73 32 32 0 0 1 2.21 53.94l25.4 114.26A16 16 0 0 1 92 448H35.94a16 16 0 0 1-15.61-19.47l25.39-114.27a32 32 0 0 1 2.33-54 80.16 80.16 0 0 1 64.62-76.07l204.26-39.89a16 16 0 1 1 6.14 31.4z\", \"M622.33 198.8l-279 85.7a80 80 0 0 1-46.79 0L99.67 224a47.84 47.84 0 0 1 19.13-8.39l204.27-39.9a16 16 0 1 0-6.14-31.4l-204.26 39.88a79.87 79.87 0 0 0-47.57 29.18l-47.44-14.58c-23.54-7.23-23.54-38.36 0-45.59L296.6 67.5a79.92 79.92 0 0 1 46.8 0l278.93 85.7c23.55 7.24 23.55 38.36 0 45.6zM352.79 315.09a111.94 111.94 0 0 1-65.59 0l-145-44.55L128 384c0 35.35 86 64 192 64s192-28.65 192-64l-14.19-113.47z\"]],\n    \"history\": [512, 512, [], \"f1da\", [\"M141.68 400.23a184 184 0 1 0-11.75-278.3l50.76 50.76c10.08 10.08 2.94 27.31-11.32 27.31H24a16 16 0 0 1-16-16V38.63c0-14.26 17.23-21.4 27.31-11.32l49.38 49.38A247.14 247.14 0 0 1 256 8c136.81 0 247.75 110.78 248 247.53S392.82 503.9 256.18 504a247 247 0 0 1-155.82-54.91 24 24 0 0 1-1.84-35.61l11.27-11.27a24 24 0 0 1 31.89-1.98z\", \"M288 152v104.35L328.7 288a24 24 0 0 1 4.21 33.68l-9.82 12.62a24 24 0 0 1-33.68 4.21L224 287.65V152a24 24 0 0 1 24-24h16a24 24 0 0 1 24 24z\"]],\n    \"key\": [512, 512, [], \"f084\", [\"M303.06 348.91l.1.09-24 27a24 24 0 0 1-17.94 8H224v40a24 24 0 0 1-24 24h-40v40a24 24 0 0 1-24 24H24a24 24 0 0 1-24-24v-78a24 24 0 0 1 7-17l161.83-161.83-.11-.35a176.24 176.24 0 0 0 134.34 118.09z\", \"M336 0a176 176 0 1 0 176 176A176 176 0 0 0 336 0zm48 176a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]],\n    \"key-skeleton\": [512, 512, [], \"f6f3\", [\"M251.31 372.91a16 16 0 0 1 0 22.63l-15.77 15.77a16 16 0 0 1-22.62 0L176 374.4l-30.87 30.86 36.11 36.11a16 16 0 0 1 0 22.63l-43.16 43.17a16 16 0 0 1-22.62 0l-36.12-36.11-36.26 36.25a16 16 0 0 1-22.62 0L4.69 491.54a16 16 0 0 1 0-22.63l255.12-255.12a64.18 64.18 0 0 0 38.4 38.4L214.4 336l36.91 36.91z\", \"M448 0H320a64 64 0 0 0-64 64v128a64 64 0 0 0 64 64h128a64 64 0 0 0 64-64V64a64 64 0 0 0-64-64zm-73.37 182.63a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25zm64-64a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25z\"]],\n    \"laptop\": [640, 512, [], \"f109\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M512 64H128v256h384zm112 352H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16z\"]],\n    \"laptop-code\": [640, 512, [], \"f5fc\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16zM512 64H128v256h384zM289 250.34l-11.31 11.31a16 16 0 0 1-22.63 0l-58.35-58.34a16 16 0 0 1 0-22.63L255 122.34a16 16 0 0 1 22.63 0L289 133.65a16 16 0 0 1 0 22.63L253.25 192 289 227.71a16 16 0 0 1 0 22.63zm154.35-47L385 261.66a16 16 0 0 1-22.63 0L351 250.35a16 16 0 0 1 0-22.63L386.75 192 351 156.29a16 16 0 0 1 0-22.63l11.31-11.31a16 16 0 0 1 22.63 0l58.34 58.34a16 16 0 0 1 .04 22.63z\"]],\n    \"laptop-house\": [640, 512, [], \"e066\", [\"M272,416H96a32,32,0,0,1-32-32V219.88L42.34,239A16.51,16.51,0,0,1,33,242.48a16.22,16.22,0,0,1-10.63-4.78L3.55,216.42A16.4,16.4,0,0,1,0,207a16.15,16.15,0,0,1,4.78-10.61L216.58,8.92C222.12,4,232.64,0,240.05,0S258,4,263.5,8.92L352,87.3V48a16,16,0,0,1,16-16h32a16,16,0,0,1,16,16v96l59.24,52.42A16.31,16.31,0,0,1,480,207a16.51,16.51,0,0,1-3.58,9.44L469.74,224H332.8c-17.8,0-33.69,8.24-44.82,21.12V208a16,16,0,0,0-16-16H208a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16h64Z\", \"M629.33,448H592V288c0-17.67-12.89-32-28.8-32H332.8c-15.91,0-28.8,14.33-28.8,32V448H266.67A10.67,10.67,0,0,0,256,458.67v10.66A42.82,42.82,0,0,0,298.6,512H597.4A42.82,42.82,0,0,0,640,469.33V458.67A10.67,10.67,0,0,0,629.33,448ZM544,448H352V304H544Z\"]],\n    \"life-ring\": [512, 512, [], \"f1cd\", [\"M292.08 167l-.41-.17zm-66.62-2a96.5 96.5 0 0 1 61.08 0l112-112a248 248 0 0 0-285 0zm68.67 2.92l.52.22zm2.49 1.12l.46.21zM186.25 322l-.19-.21zm-5.51-6.36l.21.26zm1.65 2c.12.14.23.28.35.41-.12-.15-.23-.29-.35-.43zm1.74 2l.36.4zm135.51-135.51l.4.36zM177.51 311.29l-.1-.15zM304.18 173l.34.19zm11.42 7.78l.26.21zm6.36 5.51l-.21-.19zm-3.96-3.55l-.42-.35zm-11.6-8.43l.47.29zm4.68 3.09l.17.12zm-2-1.35l-.43-.29zm-9.71-5.68l-.1-.05zm-123.61 32.91c.1-.14.19-.28.28-.42-.04.14-.18.28-.28.42zm-1.45 2.28l.29-.46zm-1.31 2.25l.19-.32zm-2.6 4.77zm10.38-16.18l.21-.26zm2-2.43c-.12.13-.23.27-.35.41.08-.14.19-.28.31-.38zm-5.33 6.89l.1-.15zm-8.2 14.07c-.07.14-.13.29-.2.43.03-.14.09-.29.16-.43zm5.39 92l-.29-.46zm-4.27-7.53v.05zm2.82 5.14l-.19-.32zm2.61 4.21c.1.14.19.28.28.42-.08-.17-.22-.31-.32-.45zm-6.8-12.11c.07.14.13.29.2.43-.06-.14-.12-.29-.2-.43zm-2-76.7c0 .13-.1.25-.16.38.07-.13.16-.25.16-.38zm1.09-2.58c-.07.17-.15.34-.22.5.13-.16.13-.33.23-.5zm-.22 76.78c.07.16.15.33.22.5-.09-.17-.09-.34-.21-.5zm-1-2.46c.06.13.11.25.16.38-.03-.13-.12-.25-.18-.38zm172-84.19l.19.32zM327.51 320l.36-.4zm-1.57 1.71l-.19.21zM325.75 190l.19.21zm3.51 128c.12-.13.23-.27.35-.41-.12.17-.23.31-.35.41zm2-121.63l-.21-.26zm0 119.2l-.21.26zm-1.65-121.22c-.12-.14-.23-.28-.35-.41.12.16.23.3.35.44zm-1.74-2l-.36-.4zm6.62 8.35l.1.15zm.1 110.43l-.1.15zM398.49 53q2 1.41 4 2.85-2-1.43-4-2.85zM343.9 294.64c.07-.17.15-.34.22-.5-.07.16-.12.33-.22.5zm1.09-2.58c.05-.13.1-.25.16-.38-.06.13-.15.25-.15.38zm-3.35 7.36v-.05zm-5.4 9.3l-.28.42zm1.45-2.28l-.29.46zm1.35-2.25l-.19.32zm3.75-7.12c.07-.14.13-.29.2-.43-.07.14-.13.29-.2.43zM449 100.21q-1.41-1.75-2.85-3.46 1.39 1.71 2.85 3.46zM445.49 96c-1-1.18-2-2.35-3-3.51 1 1.19 2.01 2.36 3 3.51zm6.87 8.5q-1.36-1.74-2.76-3.5 1.4 1.76 2.76 3.53zm3.36 4.44c-.91-1.23-1.83-2.44-2.75-3.65.92 1.24 1.84 2.45 2.75 3.71zm-119.48 94.34l-.28-.42zm66.76-147q1.85 1.36 3.66 2.76-1.78-1.39-3.66-2.76zm12.23 9.62q-1.72-1.44-3.47-2.85 1.77 1.41 3.5 2.85zM411 62.4q-1.74-1.4-3.51-2.77Q409.24 61 411 62.4zm8.5 7.13q-1.74-1.53-3.51-3 1.75 1.47 3.49 3zm-75.38 148.33c-.07-.16-.15-.33-.22-.5.1.17.15.34.22.5zM184.49 192l-.36.4zM343 215.36c-.07-.14-.13-.29-.2-.43.06.14.12.29.2.43zm113.16-105.8c1 1.31 1.9 2.62 2.84 3.94-.95-1.32-1.89-2.63-2.85-3.94zM337.4 205.1l.29.46zm82.53-135.18a248.82 248.82 0 0 1 22.14 22.15 250.17 250.17 0 0 0-22.14-22.15zm-74.78 150.4a6.15 6.15 0 0 1-.16-.38c.01.13.1.25.16.38zM459 398.49a248 248 0 0 0 0-285L347 225.46a96.5 96.5 0 0 1 0 61.08zM341.67 212.63zM220.33 345.15l-.41-.17zm-2.46-1l-.52-.22zm-5.3-2.49l.1.05zM322 325.75l-.21.19zM309.14 336l-.43.29zm2-1.35l.17-.12zm4.48-3.34l.26-.21zm4-3.39l.4-.36zm-1.6 1.39l-.42.35zM215.38 343l-.46-.21zm-19-11.74l-.26-.21zm-4-3.39l-.4-.36zm-6.3-137.62l.19-.21zm4 135.5l.21.19zm15.52 11.94l-.47-.29zm2.26 1.35l-.34-.19zm78.72 8a96.5 96.5 0 0 1-61.08 0L113.51 459a248 248 0 0 0 285 0zM202.86 336l.43.29zm-2-1.35l-.17-.12zM416 445.49q1.77-1.49 3.51-3-1.77 1.51-3.51 3zm43-47c-.93 1.33-1.88 2.64-2.84 3.95.95-1.31 1.9-2.62 2.84-3.95zM411.79 449q1.74-1.41 3.47-2.85-1.72 1.39-3.47 2.85zm-4.32 3.42q1.77-1.38 3.51-2.77-1.74 1.35-3.51 2.72zM455.72 403q-1.37 1.85-2.76 3.66 1.4-1.78 2.76-3.66zm-10.23 13c-1 1.18-2 2.35-3 3.51 1-1.19 2.01-2.36 3-3.51zm3.46-4.18q-1.41 1.74-2.85 3.47 1.44-1.75 2.9-3.5zm.65-.81q1.39-1.74 2.77-3.51-1.37 1.74-2.77 3.5zm-150.17-69.38a.31.31 0 0 1-.1.05.31.31 0 0 0 .1-.05zm-5.3 2.49l.52-.22zm12.31-6.43l.47-.29zm-9.82 5.31l.46-.21zm7.56-4l.34-.19zm137.9 80.89a248.94 248.94 0 0 1-22.15 22.15 248.94 248.94 0 0 0 22.15-22.11zm-39.63 36.21q-2 1.44-4 2.85 2.04-1.37 4-2.81zM292.08 345l-.41.17zM403 455.72q1.85-1.37 3.66-2.76-1.78 1.4-3.66 2.76zM194 329.26l.42.35zM69.93 92.07a248.82 248.82 0 0 1 22.14-22.15 250.17 250.17 0 0 0-22.14 22.15zm30.28-29q-1.74 1.41-3.47 2.85 1.73-1.46 3.47-2.87zm90 123l-.21.19zm4.13-3.67l-.42.35zM109.55 55.86q2-1.44 4-2.85-2.03 1.41-4 2.85zM196.14 181l.26-.21zM104.53 59.63Q102.76 61 101 62.4q1.76-1.4 3.53-2.77zm.78-.59q1.81-1.4 3.66-2.76-1.84 1.37-3.66 2.72zm87.05 125.09l-.4.36zm22.56-14.92l.46-.21zm-2.25 1.11l-.1.05zm4.68-2.22l.52-.22zm2.57-1.08l.41-.17zm-17.06 9l.43-.29zm5-3.09l-.34.19zm-7.11 4.56l.17-.12zm4.38-2.92l.47-.29zM96.74 446.1q1.73 1.44 3.47 2.85-1.74-1.41-3.47-2.85zm-33.69-34.31q1.41 1.74 2.85 3.47-1.44-1.72-2.85-3.47zm3.46 4.21c1 1.18 2 2.35 3 3.51-1-1.19-2.01-2.36-3-3.51zm-10.23-13q1.36 1.85 2.76 3.66-1.39-1.78-2.76-3.66zm3.35 4.44q1.37 1.8 2.77 3.56-1.4-1.76-2.77-3.53zm32.89 35q1.74 1.53 3.51 3-1.77-1.44-3.51-2.97zM105.31 453q1.81 1.4 3.66 2.76-1.84-1.4-3.66-2.76zm8.2 6q-2-1.41-4-2.85 2.01 1.43 4 2.85zM101 449.6q1.74 1.39 3.51 2.77-1.75-1.37-3.51-2.77zm-45.15-47.16c-1-1.31-1.9-2.62-2.84-3.95.99 1.33 1.88 2.64 2.84 3.95zM65.9 96.75q-1.44 1.71-2.85 3.46 1.41-1.75 2.85-3.46zM56.29 109c.9-1.23 1.82-2.45 2.74-3.65-.92 1.17-1.84 2.39-2.74 3.65zm6.11-8q-1.4 1.74-2.76 3.51Q61 102.76 62.4 101zm7.12-8.5c-1 1.16-2 2.33-3 3.51.98-1.16 1.99-2.33 3-3.49zm23-23q1.74-1.53 3.51-3-1.77 1.5-3.51 3.03zm-.45 372.55a248.94 248.94 0 0 1-22.15-22.15 248.94 248.94 0 0 0 22.15 22.18zM165 286.54a96.5 96.5 0 0 1 0-61.08L53 113.51a248 248 0 0 0 0 285zm-109.11-177q-1.44 2-2.84 3.93 1.36-1.95 2.8-3.9z\", \"M347 225.46l112-111.95A249.4 249.4 0 0 0 398.49 53L286.54 165A96.26 96.26 0 0 1 347 225.46zm-182 61.08l-112 112a249.4 249.4 0 0 0 60.5 60.5L225.46 347A96.26 96.26 0 0 1 165 286.54zm-112-173l112 112a96.26 96.26 0 0 1 60.5-60.5L113.51 53A249.4 249.4 0 0 0 53 113.51zM286.54 347l112 112a249.4 249.4 0 0 0 60.5-60.5L347 286.54A96.26 96.26 0 0 1 286.54 347z\"]],\n    \"lightbulb\": [352, 512, [], \"f0eb\", [\"M175.45 0C73.44.31 0 83 0 176a175 175 0 0 0 43.56 115.78c16.52 18.85 42.36 58.22 52.21 91.45 0 .26.07.52.11.78h160.24c0-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45A175.9 175.9 0 0 0 175.45 0zm.55 96a80.09 80.09 0 0 0-80 80 16 16 0 0 1-32 0A112.12 112.12 0 0 1 176 64a16 16 0 0 1 0 32z\", \"M96.06 454.35L96 416h160v38.35a32 32 0 0 1-5.41 17.65l-17.09 25.73A32 32 0 0 1 206.86 512h-61.71a32 32 0 0 1-26.64-14.28L101.42 472a32 32 0 0 1-5.36-17.65z\"]],\n    \"list-alt\": [512, 512, [], \"f022\", [\"M464 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zM128 392a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm288 168a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12z\", \"M128 200a40 40 0 1 0-40-40 40 40 0 0 0 40 40zm0 16a40 40 0 1 0 40 40 40 40 0 0 0-40-40zm0 96a40 40 0 1 0 40 40 40 40 0 0 0-40-40z\"]],\n    \"list-ul\": [512, 512, [], \"f0ca\", [\"M496 384H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48z\"]],\n    \"lock-alt\": [448, 512, [], \"f30d\", [\"M152 225H72v-72C72 69.2 140.2 1 224 1s152 68.2 152 152v72h-80v-72a72 72 0 0 0-144 0z\", \"M400 225H48a48 48 0 0 0-48 48v192a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V273a48 48 0 0 0-48-48zM264 392a40 40 0 0 1-80 0v-48a40 40 0 0 1 80 0z\"]],\n    \"map-marker-alt\": [384, 512, [], \"f3c5\", [\"M192 0C86 0 0 86 0 192c0 77.41 27 99 172.27 309.67a24 24 0 0 0 39.46 0C357 291 384 269.41 384 192 384 86 298 0 192 0zm0 288a96 96 0 1 1 96-96 96 96 0 0 1-96 96z\", \"M192 256a64 64 0 1 1 64-64 64 64 0 0 1-64 64z\"]],\n    \"moon-stars\": [512, 512, [], \"f755\", [\"M320 32L304 0l-16 32-32 16 32 16 16 32 16-32 32-16zm138.7 149.3L432 128l-26.7 53.3L352 208l53.3 26.7L432 288l26.7-53.3L512 208z\", \"M332.2 426.4c8.1-1.6 13.9 8 8.6 14.5a191.18 191.18 0 0 1-149 71.1C85.8 512 0 426 0 320c0-120 108.7-210.6 227-188.8 8.2 1.6 10.1 12.6 2.8 16.7a150.3 150.3 0 0 0-76.1 130.8c0 94 85.4 165.4 178.5 147.7z\"]],\n    \"network-wired\": [640, 512, [], \"f6ff\", [\"M624 232H344v-40h-48v40H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h104v40h48v-40h304v40h48v-40h104a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z\", \"M224 192h192a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32H224a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32zm32-128h128v64H256zm320 256H416a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128h-96v-64h96zM224 320H64a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128H96v-64h96z\"]],\n    \"planet-ringed\": [512, 512, [], \"e020\", [\"M323.33815,323.33517C186.95939,459.71018,46.2602,540.11093,9.06777,502.9165c-23.48893-23.4909.01172-88.30917,54.81792-167.21379a206.56361,206.56361,0,0,0,25.02022,43.78446c-22.45765,34.20607-32.036,58.99194-23.71941,67.31053,18.59817,18.59624,119.10094-51.75539,224.47885-157.13342C395.04325,184.2882,465.39675,83.78336,446.79858,65.18712c-8.32054-8.3186-33.10638,1.26176-67.31045,23.71748a206.52984,206.52984,0,0,0-43.78245-25.0183C414.61019,9.082,479.42839-14.42259,502.91732,9.06832,540.10975,46.2608,459.70909,186.96211,323.33815,323.33517Z\", \"M448.0994,176.28016c-31.96573,46.02281-74.52549,96.81528-124.76125,147.055-50.24357,50.24168-101.034,92.79954-147.05874,124.76531,75.41614,31.25675,165.47721,16.29343,226.79531-45.02474S479.35807,251.69834,448.0994,176.28016Zm-25.02022-43.78251A208.22535,208.22535,0,0,0,403.07472,108.911c-81.2288-81.23281-212.93555-81.23281-294.16435,0-81.22881,81.23085-81.22881,212.93385,0,294.1647A208.25527,208.25527,0,0,0,132.497,423.08023c42.25117-27.73908,98.93242-75.1799,157.1684-133.41595C347.90133,231.43018,395.34013,174.75473,423.07918,132.49765Z\"]],\n    \"question-circle\": [512, 512, [], \"f059\", [\"M256 8C119 8 8 119.08 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 422a46 46 0 1 1 46-46 46.05 46.05 0 0 1-46 46zm40-131.33V300a12 12 0 0 1-12 12h-56a12 12 0 0 1-12-12v-4c0-41.06 31.13-57.47 54.65-70.66 20.17-11.31 32.54-19 32.54-34 0-19.82-25.27-33-45.7-33-27.19 0-39.44 13.14-57.3 35.79a12 12 0 0 1-16.67 2.13L148.82 170a12 12 0 0 1-2.71-16.26C173.4 113 208.16 90 262.66 90c56.34 0 116.53 44 116.53 102 0 77-83.19 78.21-83.19 106.67z\", \"M256 338a46 46 0 1 0 46 46 46 46 0 0 0-46-46zm6.66-248c-54.5 0-89.26 23-116.55 63.76a12 12 0 0 0 2.71 16.24l34.7 26.31a12 12 0 0 0 16.67-2.13c17.86-22.65 30.11-35.79 57.3-35.79 20.43 0 45.7 13.14 45.7 33 0 15-12.37 22.66-32.54 34C247.13 238.53 216 254.94 216 296v4a12 12 0 0 0 12 12h56a12 12 0 0 0 12-12v-1.33c0-28.46 83.19-29.67 83.19-106.67 0-58-60.19-102-116.53-102z\"]],\n    \"quote-left\": [512, 512, [], \"f10d\", [\"M464 256h-80v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H448a160 160 0 0 0-160 160v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\", \"M176 256H96v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H160A160 160 0 0 0 0 192v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\"]],\n    \"random\": [512, 512, [], \"f074\", [\"M505 359l-80-80c-15-15-41-4.47-41 17v40h-32l-52.78-56.55-53.33 57.14 70.55 75.6a12 12 0 0 0 8.77 3.81H384v40c0 21.46 26 32 41 17l80-80a24 24 0 0 0 0-34zM122.79 96H12a12 12 0 0 0-12 12v56a12 12 0 0 0 12 12h84l52.78 56.55 53.33-57.14-70.55-75.6a12 12 0 0 0-8.77-3.81z\", \"M505 119a24 24 0 0 1 0 34l-80 80c-15 15-41 4.48-41-17v-40h-32L131.56 412.19a12 12 0 0 1-8.77 3.81H12a12 12 0 0 1-12-12v-56a12 12 0 0 1 12-12h84L316.44 99.81a12 12 0 0 1 8.78-3.81H384V56c0-21.44 25.94-32 41-17z\"]],\n    \"rocket\": [512, 512, [], \"f135\", [\"M51.94117,154.48438,2.531,253.29688A28.125,28.125,0,0,0-.00023,264a24.00619,24.00619,0,0,0,24,24H117.4607c23.44141-47.41211,61.01172-123.373,77.89063-157.32812.51953-.91407,1-1.76758,1.52344-2.67188H94.82008C78.47633,128.01562,59.28883,139.875,51.94117,154.48438Zm172.0586,240.1621V488.209A24.12394,24.12394,0,0,0,247.9607,512a28.02965,28.02965,0,0,0,10.625-2.53125l98.72657-49.39063c14.625-7.3125,26.5-26.5,26.5-42.85937V315.70312c.0664-.041.125-.08789.1875-.1289v-.52734c-.90625.51953-1.7461,1.002-2.66407,1.52539C347.37477,333.58008,271.2732,371.252,223.99977,394.64648Z\", \"M505.15992,19.51562A16.73971,16.73971,0,0,0,492.62477,6.94531C460.22633,0,434.37477,0,409.48414,0,320.3357,0,252.80836,40.61523,196.97633,127.81836c-.5586.97852-1.07031,1.877-1.625,2.85352-19.59766,39.42578-67.20313,135.70312-88.04688,177.877a31.91421,31.91421,0,0,0,6.09766,36.76172L167.05445,398.709a31.88923,31.88923,0,0,0,36.64844,5.98047l14.17578-7.01367c46.57422-23.04883,128.06641-63.3789,163.457-81.10351.96094-.54883,1.832-1.04883,2.78907-1.59766,87.23437-56.06055,127.85937-123.51172,127.85937-212.27734C512.06227,77.60742,512.12867,52.08789,505.15992,19.51562ZM367.99977,192a48,48,0,1,1,48-48.00195A48.02156,48.02156,0,0,1,367.99977,192Z\"]],\n    \"search\": [512, 512, [], \"f002\", [\"M208 80a128 128 0 1 1-90.51 37.49A127.15 127.15 0 0 1 208 80m0-80C93.12 0 0 93.12 0 208s93.12 208 208 208 208-93.12 208-208S322.88 0 208 0z\", \"M504.9 476.7L476.6 505a23.9 23.9 0 0 1-33.9 0L343 405.3a24 24 0 0 1-7-17V372l36-36h16.3a24 24 0 0 1 17 7l99.7 99.7a24.11 24.11 0 0 1-.1 34z\"]],\n    \"server\": [512, 512, [], \"f233\", [\"M432 120a24 24 0 1 0-24-24 24 24 0 0 0 24 24zm0 272a24 24 0 1 0 24 24 24 24 0 0 0-24-24zm48-200H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\", \"M456 256a24 24 0 1 0-24 24 24 24 0 0 0 24-24zm24-224H32A32 32 0 0 0 0 64v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm48 232H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\"]],\n    \"sign-out\": [512, 512, [], \"f08b\", [\"M180 448H96a96 96 0 0 1-96-96V160a96 96 0 0 1 96-96h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12H96a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12z\", \"M353 88.3l151.9 150.6a24 24 0 0 1 0 34.1l-152 150.8a24.08 24.08 0 0 1-33.9-.1l-21.9-21.9a24.07 24.07 0 0 1 .8-34.7l77.6-71.1H184a23.94 23.94 0 0 1-24-24v-32a23.94 23.94 0 0 1 24-24h191.5l-77.6-71.1a24 24 0 0 1-.7-34.6l21.9-21.9a24 24 0 0 1 33.9-.1z\"]],\n    \"siren-on\": [640, 512, [], \"e02e\", [\"M224.21,134.94a8,8,0,0,1,9-6.87l15.86,2.13a8,8,0,0,1,6.87,9L231.82,320H496L471,120.06A64,64,0,0,0,407.5,64h-175A64,64,0,0,0,169,120.06L144,320h55.54Z\", \"M528,352H112a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16H528a16,16,0,0,0,16-16V368A16,16,0,0,0,528,352ZM112,192a24,24,0,0,0-24-24H24a24,24,0,0,0,0,48H88A24,24,0,0,0,112,192Zm504-24H552a24,24,0,0,0,0,48h64a24,24,0,0,0,0-48ZM90.69,76a24,24,0,1,0,26.62-39.92l-48-32A24,24,0,1,0,42.69,44ZM536,80a23.87,23.87,0,0,0,13.29-4l48-32A24,24,0,1,0,570.69,4.06l-48,32A24,24,0,0,0,536,80Z\"]],\n    \"smile\": [496, 512, [], \"f118\", [\"M248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256,385,8,248,8Zm80,168a32,32,0,1,1-32,32A32,32,0,0,1,328,176Zm-160,0a32,32,0,1,1-32,32A32,32,0,0,1,168,176ZM362.8,346.2a149.38,149.38,0,0,1-229.6,0c-13.6-16.3,11-36.7,24.6-20.5a117.5,117.5,0,0,0,180.4,0C351.6,309.5,376.3,329.9,362.8,346.2Z\", \"M328,176a32,32,0,1,0,32,32A32,32,0,0,0,328,176Zm-160,0a32,32,0,1,0,32,32A32,32,0,0,0,168,176Z\"]],\n    \"snowman\": [512, 512, [], \"f7d0\", [\"M363.76 268.8a108.77 108.77 0 0 0 4.2-28.7v-.1a112.68 112.68 0 0 0-.73-12.8c-.11-1-.24-2-.38-3-.29-2-.62-4-1-6-.2-1-.4-1.95-.62-2.92-.22-1-.45-1.93-.7-2.9-.24-1-.5-1.91-.77-2.85-.27-.95-.55-1.89-.84-2.83-.3-.94-.6-1.87-.92-2.8-.32-.93-.65-1.86-1-2.77-.34-.92-.69-1.83-1.06-2.74-.36-.9-.74-1.8-1.13-2.7-.39-.89-.79-1.78-1.19-2.66-.41-.88-.83-1.76-1.26-2.63q-1.31-2.62-2.73-5.16c-.48-.85-1-1.68-1.46-2.51a112.44 112.44 0 0 0-21.62-26.19 96 96 0 1 0-149.16 0 112.49 112.49 0 0 0-21.68 26.28q-.74 1.23-1.44 2.49c-.48.84-.94 1.69-1.39 2.54-.45.85-.89 1.7-1.32 2.57-.43.87-.85 1.74-1.25 2.62-.41.88-.8 1.76-1.19 2.66-.39.89-.76 1.79-1.12 2.69-.36.91-.71 1.82-1.05 2.74-.34.92-.67 1.84-1 2.76a111.63 111.63 0 0 0-5.22 23.28A113 113 0 0 0 144 240h.06v.1a110.27 110.27 0 0 0 4.2 28.9A151.18 151.18 0 0 0 104 376.1c0 54 28.4 100.9 70.8 127.8 9.3 5.9 20.3 8.2 31.3 8.2h99.2a65.1 65.1 0 0 0 37.2-11.7c46.5-32.3 74.4-89.4 62.9-152.6-5.54-30.2-20.54-57.6-41.64-79zM224 96.1a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm32 272a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm0-64a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm1.7-64.1a15.19 15.19 0 0 1-3.48 0 16 16 0 1 1 3.48 0zm-1.7-87.9s-16-23.2-16-32a16 16 0 1 1 32 0c0 8.8-16 32-16 32zm32-56a16 16 0 1 1 16-16 16 16 0 0 1-16 16z\", \"M510.86 152.4L505 137.9a16.15 16.15 0 0 0-20.8-8.7L456 140.7v-29a15.84 15.84 0 0 0-16-15.6h-16a15.84 15.84 0 0 0-16 15.6v46.9c0 .5.3 1 .3 1.5l-56.1 22.54a111.21 111.21 0 0 1 15.07 44.56L502 172.7a15.57 15.57 0 0 0 8.86-20.3zm-407.1 6.2v-46.9c.2-8.6-7-15.6-15.8-15.6H72a15.84 15.84 0 0 0-16 15.6v29l-28.1-11.5a16.15 16.15 0 0 0-20.8 8.7l-5.9 14.5a15.48 15.48 0 0 0 8.9 20.3l134.67 54.49a111.3 111.3 0 0 1 15-44.46l-56.31-22.63a8 8 0 0 0 .3-1.5zM256 336.1a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16z\"]],\n    \"sun\": [512, 512, [], \"f185\", [\"M502.42 240.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.41-94.8a17.31 17.31 0 0 0-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4a17.31 17.31 0 0 0 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.41-33.5 47.3 94.7a17.31 17.31 0 0 0 31 0l47.31-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3a17.33 17.33 0 0 0 .2-31.1zm-155.9 106c-49.91 49.9-131.11 49.9-181 0a128.13 128.13 0 0 1 0-181c49.9-49.9 131.1-49.9 181 0a128.13 128.13 0 0 1 0 181z\", \"M352 256a96 96 0 1 1-96-96 96.15 96.15 0 0 1 96 96z\"]],\n    \"tasks\": [512, 512, [], \"f0ae\", [\"M496 384H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M139.61 35.5a12 12 0 0 0-17 0L58.93 98.81l-22.7-22.12a12 12 0 0 0-17 0L3.53 92.41a12 12 0 0 0 0 17l47.59 47.4a12.78 12.78 0 0 0 17.61 0l15.59-15.62L156.52 69a12.09 12.09 0 0 0 .09-17zm0 159.19a12 12 0 0 0-17 0l-63.68 63.72-22.7-22.1a12 12 0 0 0-17 0L3.53 252a12 12 0 0 0 0 17L51 316.5a12.77 12.77 0 0 0 17.6 0l15.7-15.69 72.2-72.22a12 12 0 0 0 .09-16.9zM64 368c-26.49 0-48.59 21.5-48.59 48S37.53 464 64 464a48 48 0 0 0 0-96z\"]],\n    \"university\": [512, 512, [], \"f19c\", [\"M160,192V384h64V192h64V384h64V192h64V384h36a12,12,0,0,1,12,12v20H48V396a12,12,0,0,1,12-12H96V192Z\", \"M491.06,120.61l-232-88a8,8,0,0,0-6.12,0l-232,88A8,8,0,0,0,16,128v16a8,8,0,0,0,8,8H48v12a12,12,0,0,0,12,12H452a12,12,0,0,0,12-12V152h24a8,8,0,0,0,8-8V128A8,8,0,0,0,491.06,120.61ZM472,432H40a24,24,0,0,0-24,24v16a8,8,0,0,0,8,8H488a8,8,0,0,0,8-8V456A24,24,0,0,0,472,432Z\"]],\n    \"user\": [448, 512, [], \"f007\", [\"M352 128A128 128 0 1 1 224 0a128 128 0 0 1 128 128z\", \"M313.6 288h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48v-41.6A134.43 134.43 0 0 0 313.6 288z\"]],\n    \"user-hard-hat\": [448, 512, [], \"f82c\", [\"M97.61 208h252.78c-7.95 63.06-61.17 112-126.39 112S105.56 271.06 97.61 208z\", \"M313.6 352h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.4 134.4 0 0 0 0 486.4 25.6 25.6 0 0 0 25.6 512h396.8a25.6 25.6 0 0 0 25.6-25.6A134.4 134.4 0 0 0 313.6 352zM88 176h272a8 8 0 0 0 8-8v-32a8 8 0 0 0-8-8h-8a112 112 0 0 0-68.4-103.2L256 80V16a16 16 0 0 0-16-16h-32a16 16 0 0 0-16 16v64l-27.6-55.2A112 112 0 0 0 96 128h-8a8 8 0 0 0-8 8v32a8 8 0 0 0 8 8z\"]],\n    \"user-shield\": [640, 512, [], \"f505\", [\"M622.3 271.1l-115.2-45a31 31 0 0 0-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9a31 31 0 0 0 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8z\", \"M224 256A128 128 0 1 0 96 128a128 128 0 0 0 128 128zm96 40c0-2.5.8-4.8 1.1-7.2-2.5-.1-4.9-.8-7.5-.8h-16.7a174.08 174.08 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a49.22 49.22 0 0 0 19.2-4c-54-42.9-99.2-116.7-99.2-212z\"]],\n    \"users\": [640, 512, [], \"f0c0\", [\"M96 224a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64zm480 32h-64a63.81 63.81 0 0 0-45.1 18.6A146.27 146.27 0 0 1 542 384h66a32 32 0 0 0 32-32v-32a64.06 64.06 0 0 0-64-64zm-512 0a64.06 64.06 0 0 0-64 64v32a32 32 0 0 0 32 32h65.9a146.64 146.64 0 0 1 75.2-109.4A63.81 63.81 0 0 0 128 256zm480-32a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64z\", \"M396.8 288h-8.3a157.53 157.53 0 0 1-68.5 16c-24.6 0-47.6-6-68.5-16h-8.3A115.23 115.23 0 0 0 128 403.2V432a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48v-28.8A115.23 115.23 0 0 0 396.8 288zM320 256a112 112 0 1 0-112-112 111.94 111.94 0 0 0 112 112z\"]]\n  };\n\n  bunker(function () {\n    defineIcons('fad', icons);\n  });\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js/fontawesome.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _typeof(obj) {\n    \"@babel/helpers - typeof\";\n\n    if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n      _typeof = function (obj) {\n        return typeof obj;\n      };\n    } else {\n      _typeof = function (obj) {\n        return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n      };\n    }\n\n    return _typeof(obj);\n  }\n\n  function _classCallCheck(instance, Constructor) {\n    if (!(instance instanceof Constructor)) {\n      throw new TypeError(\"Cannot call a class as a function\");\n    }\n  }\n\n  function _defineProperties(target, props) {\n    for (var i = 0; i < props.length; i++) {\n      var descriptor = props[i];\n      descriptor.enumerable = descriptor.enumerable || false;\n      descriptor.configurable = true;\n      if (\"value\" in descriptor) descriptor.writable = true;\n      Object.defineProperty(target, descriptor.key, descriptor);\n    }\n  }\n\n  function _createClass(Constructor, protoProps, staticProps) {\n    if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n    if (staticProps) _defineProperties(Constructor, staticProps);\n    return Constructor;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  function _slicedToArray(arr, i) {\n    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n  }\n\n  function _toConsumableArray(arr) {\n    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n  }\n\n  function _arrayWithoutHoles(arr) {\n    if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n  }\n\n  function _arrayWithHoles(arr) {\n    if (Array.isArray(arr)) return arr;\n  }\n\n  function _iterableToArray(iter) {\n    if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n  }\n\n  function _iterableToArrayLimit(arr, i) {\n    var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n    if (_i == null) return;\n    var _arr = [];\n    var _n = true;\n    var _d = false;\n\n    var _s, _e;\n\n    try {\n      for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n        _arr.push(_s.value);\n\n        if (i && _arr.length === i) break;\n      }\n    } catch (err) {\n      _d = true;\n      _e = err;\n    } finally {\n      try {\n        if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n      } finally {\n        if (_d) throw _e;\n      }\n    }\n\n    return _arr;\n  }\n\n  function _unsupportedIterableToArray(o, minLen) {\n    if (!o) return;\n    if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n    var n = Object.prototype.toString.call(o).slice(8, -1);\n    if (n === \"Object\" && o.constructor) n = o.constructor.name;\n    if (n === \"Map\" || n === \"Set\") return Array.from(o);\n    if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n  }\n\n  function _arrayLikeToArray(arr, len) {\n    if (len == null || len > arr.length) len = arr.length;\n\n    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n\n    return arr2;\n  }\n\n  function _nonIterableSpread() {\n    throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n\n  function _nonIterableRest() {\n    throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n\n  var noop = function noop() {};\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n  var _MUTATION_OBSERVER = null;\n  var _PERFORMANCE = {\n    mark: noop,\n    measure: noop\n  };\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n    if (typeof MutationObserver !== 'undefined') _MUTATION_OBSERVER = MutationObserver;\n    if (typeof performance !== 'undefined') _PERFORMANCE = performance;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var MUTATION_OBSERVER = _MUTATION_OBSERVER;\n  var PERFORMANCE = _PERFORMANCE;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var UNITS_IN_GRID = 16;\n  var DEFAULT_FAMILY_PREFIX = 'fa';\n  var DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa';\n  var DATA_FA_I2SVG = 'data-fa-i2svg';\n  var DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element';\n  var DATA_FA_PSEUDO_ELEMENT_PENDING = 'data-fa-pseudo-element-pending';\n  var DATA_PREFIX = 'data-prefix';\n  var DATA_ICON = 'data-icon';\n  var HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg';\n  var MUTATION_APPROACH_ASYNC = 'async';\n  var TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS = ['HTML', 'HEAD', 'STYLE', 'SCRIPT'];\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n  var PREFIX_TO_STYLE = {\n    'fas': 'solid',\n    'far': 'regular',\n    'fal': 'light',\n    'fad': 'duotone',\n    'fab': 'brands',\n    'fak': 'kit',\n    'fa': 'solid'\n  };\n  var STYLE_TO_PREFIX = {\n    'solid': 'fas',\n    'regular': 'far',\n    'light': 'fal',\n    'duotone': 'fad',\n    'brands': 'fab',\n    'kit': 'fak'\n  };\n  var LAYERS_TEXT_CLASSNAME = 'fa-layers-text';\n  var FONT_FAMILY_PATTERN = /Font Awesome ([5 ]*)(Solid|Regular|Light|Duotone|Brands|Free|Pro|Kit).*/i; // TODO: do we need to handle font-weight for kit SVG pseudo-elements?\n\n  var FONT_WEIGHT_TO_PREFIX = {\n    '900': 'fas',\n    '400': 'far',\n    'normal': 'far',\n    '300': 'fal'\n  };\n  var oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n  var oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);\n  var ATTRIBUTES_WATCHED_FOR_MUTATION = ['class', 'data-prefix', 'data-icon', 'data-fa-transform', 'data-fa-mask'];\n  var DUOTONE_CLASSES = {\n    GROUP: 'group',\n    SWAP_OPACITY: 'swap-opacity',\n    PRIMARY: 'primary',\n    SECONDARY: 'secondary'\n  };\n  var RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'flip-both', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter', DUOTONE_CLASSES.GROUP, DUOTONE_CLASSES.SWAP_OPACITY, DUOTONE_CLASSES.PRIMARY, DUOTONE_CLASSES.SECONDARY].concat(oneToTen.map(function (n) {\n    return \"\".concat(n, \"x\");\n  })).concat(oneToTwenty.map(function (n) {\n    return \"w-\".concat(n);\n  }));\n\n  var initial = WINDOW.FontAwesomeConfig || {};\n\n  function getAttrConfig(attr) {\n    var element = DOCUMENT.querySelector('script[' + attr + ']');\n\n    if (element) {\n      return element.getAttribute(attr);\n    }\n  }\n\n  function coerce(val) {\n    // Getting an empty string will occur if the attribute is set on the HTML tag but without a value\n    // We'll assume that this is an indication that it should be toggled to true\n    // For example <script data-search-pseudo-elements src=\"...\"></script>\n    if (val === '') return true;\n    if (val === 'false') return false;\n    if (val === 'true') return true;\n    return val;\n  }\n\n  if (DOCUMENT && typeof DOCUMENT.querySelector === 'function') {\n    var attrs = [['data-family-prefix', 'familyPrefix'], ['data-replacement-class', 'replacementClass'], ['data-auto-replace-svg', 'autoReplaceSvg'], ['data-auto-add-css', 'autoAddCss'], ['data-auto-a11y', 'autoA11y'], ['data-search-pseudo-elements', 'searchPseudoElements'], ['data-observe-mutations', 'observeMutations'], ['data-mutate-approach', 'mutateApproach'], ['data-keep-original-source', 'keepOriginalSource'], ['data-measure-performance', 'measurePerformance'], ['data-show-missing-icons', 'showMissingIcons']];\n    attrs.forEach(function (_ref) {\n      var _ref2 = _slicedToArray(_ref, 2),\n          attr = _ref2[0],\n          key = _ref2[1];\n\n      var val = coerce(getAttrConfig(attr));\n\n      if (val !== undefined && val !== null) {\n        initial[key] = val;\n      }\n    });\n  }\n\n  var _default = {\n    familyPrefix: DEFAULT_FAMILY_PREFIX,\n    replacementClass: DEFAULT_REPLACEMENT_CLASS,\n    autoReplaceSvg: true,\n    autoAddCss: true,\n    autoA11y: true,\n    searchPseudoElements: false,\n    observeMutations: true,\n    mutateApproach: 'async',\n    keepOriginalSource: true,\n    measurePerformance: false,\n    showMissingIcons: true\n  };\n\n  var _config = _objectSpread2(_objectSpread2({}, _default), initial);\n\n  if (!_config.autoReplaceSvg) _config.observeMutations = false;\n\n  var config = _objectSpread2({}, _config);\n\n  WINDOW.FontAwesomeConfig = config;\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  var functions = [];\n\n  var listener = function listener() {\n    DOCUMENT.removeEventListener('DOMContentLoaded', listener);\n    loaded = 1;\n    functions.map(function (fn) {\n      return fn();\n    });\n  };\n\n  var loaded = false;\n\n  if (IS_DOM) {\n    loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);\n    if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);\n  }\n\n  function domready (fn) {\n    if (!IS_DOM) return;\n    loaded ? setTimeout(fn, 0) : functions.push(fn);\n  }\n\n  var PENDING = 'pending';\n  var SETTLED = 'settled';\n  var FULFILLED = 'fulfilled';\n  var REJECTED = 'rejected';\n\n  var NOOP = function NOOP() {};\n\n  var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function';\n  var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate;\n  var asyncQueue = [];\n  var asyncTimer;\n\n  function asyncFlush() {\n    // run promise callbacks\n    for (var i = 0; i < asyncQueue.length; i++) {\n      asyncQueue[i][0](asyncQueue[i][1]);\n    } // reset async asyncQueue\n\n\n    asyncQueue = [];\n    asyncTimer = false;\n  }\n\n  function asyncCall(callback, arg) {\n    asyncQueue.push([callback, arg]);\n\n    if (!asyncTimer) {\n      asyncTimer = true;\n      asyncSetTimer(asyncFlush, 0);\n    }\n  }\n\n  function invokeResolver(resolver, promise) {\n    function resolvePromise(value) {\n      resolve(promise, value);\n    }\n\n    function rejectPromise(reason) {\n      reject(promise, reason);\n    }\n\n    try {\n      resolver(resolvePromise, rejectPromise);\n    } catch (e) {\n      rejectPromise(e);\n    }\n  }\n\n  function invokeCallback(subscriber) {\n    var owner = subscriber.owner;\n    var settled = owner._state;\n    var value = owner._data;\n    var callback = subscriber[settled];\n    var promise = subscriber.then;\n\n    if (typeof callback === 'function') {\n      settled = FULFILLED;\n\n      try {\n        value = callback(value);\n      } catch (e) {\n        reject(promise, e);\n      }\n    }\n\n    if (!handleThenable(promise, value)) {\n      if (settled === FULFILLED) {\n        resolve(promise, value);\n      }\n\n      if (settled === REJECTED) {\n        reject(promise, value);\n      }\n    }\n  }\n\n  function handleThenable(promise, value) {\n    var resolved;\n\n    try {\n      if (promise === value) {\n        throw new TypeError('A promises callback cannot return that same promise.');\n      }\n\n      if (value && (typeof value === 'function' || _typeof(value) === 'object')) {\n        // then should be retrieved only once\n        var then = value.then;\n\n        if (typeof then === 'function') {\n          then.call(value, function (val) {\n            if (!resolved) {\n              resolved = true;\n\n              if (value === val) {\n                fulfill(promise, val);\n              } else {\n                resolve(promise, val);\n              }\n            }\n          }, function (reason) {\n            if (!resolved) {\n              resolved = true;\n              reject(promise, reason);\n            }\n          });\n          return true;\n        }\n      }\n    } catch (e) {\n      if (!resolved) {\n        reject(promise, e);\n      }\n\n      return true;\n    }\n\n    return false;\n  }\n\n  function resolve(promise, value) {\n    if (promise === value || !handleThenable(promise, value)) {\n      fulfill(promise, value);\n    }\n  }\n\n  function fulfill(promise, value) {\n    if (promise._state === PENDING) {\n      promise._state = SETTLED;\n      promise._data = value;\n      asyncCall(publishFulfillment, promise);\n    }\n  }\n\n  function reject(promise, reason) {\n    if (promise._state === PENDING) {\n      promise._state = SETTLED;\n      promise._data = reason;\n      asyncCall(publishRejection, promise);\n    }\n  }\n\n  function publish(promise) {\n    promise._then = promise._then.forEach(invokeCallback);\n  }\n\n  function publishFulfillment(promise) {\n    promise._state = FULFILLED;\n    publish(promise);\n  }\n\n  function publishRejection(promise) {\n    promise._state = REJECTED;\n    publish(promise);\n\n    if (!promise._handled && isNode) {\n      global.process.emit('unhandledRejection', promise._data, promise);\n    }\n  }\n\n  function notifyRejectionHandled(promise) {\n    global.process.emit('rejectionHandled', promise);\n  }\n  /**\n   * @class\n   */\n\n\n  function P(resolver) {\n    if (typeof resolver !== 'function') {\n      throw new TypeError('Promise resolver ' + resolver + ' is not a function');\n    }\n\n    if (this instanceof P === false) {\n      throw new TypeError('Failed to construct \\'Promise\\': Please use the \\'new\\' operator, this object constructor cannot be called as a function.');\n    }\n\n    this._then = [];\n    invokeResolver(resolver, this);\n  }\n\n  P.prototype = {\n    constructor: P,\n    _state: PENDING,\n    _then: null,\n    _data: undefined,\n    _handled: false,\n    then: function then(onFulfillment, onRejection) {\n      var subscriber = {\n        owner: this,\n        then: new this.constructor(NOOP),\n        fulfilled: onFulfillment,\n        rejected: onRejection\n      };\n\n      if ((onRejection || onFulfillment) && !this._handled) {\n        this._handled = true;\n\n        if (this._state === REJECTED && isNode) {\n          asyncCall(notifyRejectionHandled, this);\n        }\n      }\n\n      if (this._state === FULFILLED || this._state === REJECTED) {\n        // already resolved, call callback async\n        asyncCall(invokeCallback, subscriber);\n      } else {\n        // subscribe\n        this._then.push(subscriber);\n      }\n\n      return subscriber.then;\n    },\n    catch: function _catch(onRejection) {\n      return this.then(null, onRejection);\n    }\n  };\n\n  P.all = function (promises) {\n    if (!Array.isArray(promises)) {\n      throw new TypeError('You must pass an array to Promise.all().');\n    }\n\n    return new P(function (resolve, reject) {\n      var results = [];\n      var remaining = 0;\n\n      function resolver(index) {\n        remaining++;\n        return function (value) {\n          results[index] = value;\n\n          if (! --remaining) {\n            resolve(results);\n          }\n        };\n      }\n\n      for (var i = 0, promise; i < promises.length; i++) {\n        promise = promises[i];\n\n        if (promise && typeof promise.then === 'function') {\n          promise.then(resolver(i), reject);\n        } else {\n          results[i] = promise;\n        }\n      }\n\n      if (!remaining) {\n        resolve(results);\n      }\n    });\n  };\n\n  P.race = function (promises) {\n    if (!Array.isArray(promises)) {\n      throw new TypeError('You must pass an array to Promise.race().');\n    }\n\n    return new P(function (resolve, reject) {\n      for (var i = 0, promise; i < promises.length; i++) {\n        promise = promises[i];\n\n        if (promise && typeof promise.then === 'function') {\n          promise.then(resolve, reject);\n        } else {\n          resolve(promise);\n        }\n      }\n    });\n  };\n\n  P.resolve = function (value) {\n    if (value && _typeof(value) === 'object' && value.constructor === P) {\n      return value;\n    }\n\n    return new P(function (resolve) {\n      resolve(value);\n    });\n  };\n\n  P.reject = function (reason) {\n    return new P(function (resolve, reject) {\n      reject(reason);\n    });\n  };\n\n  var picked = typeof Promise === 'function' ? Promise : P;\n\n  var d = UNITS_IN_GRID;\n  var meaninglessTransform = {\n    size: 16,\n    x: 0,\n    y: 0,\n    rotate: 0,\n    flipX: false,\n    flipY: false\n  };\n\n  function isReserved(name) {\n    return ~RESERVED_CLASSES.indexOf(name);\n  }\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n  function insertCss(css) {\n    if (!css || !IS_DOM) {\n      return;\n    }\n\n    var style = DOCUMENT.createElement('style');\n    style.setAttribute('type', 'text/css');\n    style.innerHTML = css;\n    var headChildren = DOCUMENT.head.childNodes;\n    var beforeChild = null;\n\n    for (var i = headChildren.length - 1; i > -1; i--) {\n      var child = headChildren[i];\n      var tagName = (child.tagName || '').toUpperCase();\n\n      if (['STYLE', 'LINK'].indexOf(tagName) > -1) {\n        beforeChild = child;\n      }\n    }\n\n    DOCUMENT.head.insertBefore(style, beforeChild);\n    return css;\n  }\n  var idPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n  function nextUniqueId() {\n    var size = 12;\n    var id = '';\n\n    while (size-- > 0) {\n      id += idPool[Math.random() * 62 | 0];\n    }\n\n    return id;\n  }\n  function toArray(obj) {\n    var array = [];\n\n    for (var i = (obj || []).length >>> 0; i--;) {\n      array[i] = obj[i];\n    }\n\n    return array;\n  }\n  function classArray(node) {\n    if (node.classList) {\n      return toArray(node.classList);\n    } else {\n      return (node.getAttribute('class') || '').split(' ').filter(function (i) {\n        return i;\n      });\n    }\n  }\n  function getIconName(familyPrefix, cls) {\n    var parts = cls.split('-');\n    var prefix = parts[0];\n    var iconName = parts.slice(1).join('-');\n\n    if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) {\n      return iconName;\n    } else {\n      return null;\n    }\n  }\n  function htmlEscape(str) {\n    return \"\".concat(str).replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n  }\n  function joinAttributes(attributes) {\n    return Object.keys(attributes || {}).reduce(function (acc, attributeName) {\n      return acc + \"\".concat(attributeName, \"=\\\"\").concat(htmlEscape(attributes[attributeName]), \"\\\" \");\n    }, '').trim();\n  }\n  function joinStyles(styles) {\n    return Object.keys(styles || {}).reduce(function (acc, styleName) {\n      return acc + \"\".concat(styleName, \": \").concat(styles[styleName], \";\");\n    }, '');\n  }\n  function transformIsMeaningful(transform) {\n    return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY;\n  }\n  function transformForSvg(_ref) {\n    var transform = _ref.transform,\n        containerWidth = _ref.containerWidth,\n        iconWidth = _ref.iconWidth;\n    var outer = {\n      transform: \"translate(\".concat(containerWidth / 2, \" 256)\")\n    };\n    var innerTranslate = \"translate(\".concat(transform.x * 32, \", \").concat(transform.y * 32, \") \");\n    var innerScale = \"scale(\".concat(transform.size / 16 * (transform.flipX ? -1 : 1), \", \").concat(transform.size / 16 * (transform.flipY ? -1 : 1), \") \");\n    var innerRotate = \"rotate(\".concat(transform.rotate, \" 0 0)\");\n    var inner = {\n      transform: \"\".concat(innerTranslate, \" \").concat(innerScale, \" \").concat(innerRotate)\n    };\n    var path = {\n      transform: \"translate(\".concat(iconWidth / 2 * -1, \" -256)\")\n    };\n    return {\n      outer: outer,\n      inner: inner,\n      path: path\n    };\n  }\n  function transformForCss(_ref2) {\n    var transform = _ref2.transform,\n        _ref2$width = _ref2.width,\n        width = _ref2$width === void 0 ? UNITS_IN_GRID : _ref2$width,\n        _ref2$height = _ref2.height,\n        height = _ref2$height === void 0 ? UNITS_IN_GRID : _ref2$height,\n        _ref2$startCentered = _ref2.startCentered,\n        startCentered = _ref2$startCentered === void 0 ? false : _ref2$startCentered;\n    var val = '';\n\n    if (startCentered && IS_IE) {\n      val += \"translate(\".concat(transform.x / d - width / 2, \"em, \").concat(transform.y / d - height / 2, \"em) \");\n    } else if (startCentered) {\n      val += \"translate(calc(-50% + \".concat(transform.x / d, \"em), calc(-50% + \").concat(transform.y / d, \"em)) \");\n    } else {\n      val += \"translate(\".concat(transform.x / d, \"em, \").concat(transform.y / d, \"em) \");\n    }\n\n    val += \"scale(\".concat(transform.size / d * (transform.flipX ? -1 : 1), \", \").concat(transform.size / d * (transform.flipY ? -1 : 1), \") \");\n    val += \"rotate(\".concat(transform.rotate, \"deg) \");\n    return val;\n  }\n\n  var ALL_SPACE = {\n    x: 0,\n    y: 0,\n    width: '100%',\n    height: '100%'\n  };\n\n  function fillBlack(abstract) {\n    var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n    if (abstract.attributes && (abstract.attributes.fill || force)) {\n      abstract.attributes.fill = 'black';\n    }\n\n    return abstract;\n  }\n\n  function deGroup(abstract) {\n    if (abstract.tag === 'g') {\n      return abstract.children;\n    } else {\n      return [abstract];\n    }\n  }\n\n  function makeIconMasking (_ref) {\n    var children = _ref.children,\n        attributes = _ref.attributes,\n        main = _ref.main,\n        mask = _ref.mask,\n        explicitMaskId = _ref.maskId,\n        transform = _ref.transform;\n    var mainWidth = main.width,\n        mainPath = main.icon;\n    var maskWidth = mask.width,\n        maskPath = mask.icon;\n    var trans = transformForSvg({\n      transform: transform,\n      containerWidth: maskWidth,\n      iconWidth: mainWidth\n    });\n    var maskRect = {\n      tag: 'rect',\n      attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n        fill: 'white'\n      })\n    };\n    var maskInnerGroupChildrenMixin = mainPath.children ? {\n      children: mainPath.children.map(fillBlack)\n    } : {};\n    var maskInnerGroup = {\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.inner),\n      children: [fillBlack(_objectSpread2({\n        tag: mainPath.tag,\n        attributes: _objectSpread2(_objectSpread2({}, mainPath.attributes), trans.path)\n      }, maskInnerGroupChildrenMixin))]\n    };\n    var maskOuterGroup = {\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.outer),\n      children: [maskInnerGroup]\n    };\n    var maskId = \"mask-\".concat(explicitMaskId || nextUniqueId());\n    var clipId = \"clip-\".concat(explicitMaskId || nextUniqueId());\n    var maskTag = {\n      tag: 'mask',\n      attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n        id: maskId,\n        maskUnits: 'userSpaceOnUse',\n        maskContentUnits: 'userSpaceOnUse'\n      }),\n      children: [maskRect, maskOuterGroup]\n    };\n    var defs = {\n      tag: 'defs',\n      children: [{\n        tag: 'clipPath',\n        attributes: {\n          id: clipId\n        },\n        children: deGroup(maskPath)\n      }, maskTag]\n    };\n    children.push(defs, {\n      tag: 'rect',\n      attributes: _objectSpread2({\n        fill: 'currentColor',\n        'clip-path': \"url(#\".concat(clipId, \")\"),\n        mask: \"url(#\".concat(maskId, \")\")\n      }, ALL_SPACE)\n    });\n    return {\n      children: children,\n      attributes: attributes\n    };\n  }\n\n  function makeIconStandard (_ref) {\n    var children = _ref.children,\n        attributes = _ref.attributes,\n        main = _ref.main,\n        transform = _ref.transform,\n        styles = _ref.styles;\n    var styleString = joinStyles(styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    if (transformIsMeaningful(transform)) {\n      var trans = transformForSvg({\n        transform: transform,\n        containerWidth: main.width,\n        iconWidth: main.width\n      });\n      children.push({\n        tag: 'g',\n        attributes: _objectSpread2({}, trans.outer),\n        children: [{\n          tag: 'g',\n          attributes: _objectSpread2({}, trans.inner),\n          children: [{\n            tag: main.icon.tag,\n            children: main.icon.children,\n            attributes: _objectSpread2(_objectSpread2({}, main.icon.attributes), trans.path)\n          }]\n        }]\n      });\n    } else {\n      children.push(main.icon);\n    }\n\n    return {\n      children: children,\n      attributes: attributes\n    };\n  }\n\n  function asIcon (_ref) {\n    var children = _ref.children,\n        main = _ref.main,\n        mask = _ref.mask,\n        attributes = _ref.attributes,\n        styles = _ref.styles,\n        transform = _ref.transform;\n\n    if (transformIsMeaningful(transform) && main.found && !mask.found) {\n      var width = main.width,\n          height = main.height;\n      var offset = {\n        x: width / height / 2,\n        y: 0.5\n      };\n      attributes['style'] = joinStyles(_objectSpread2(_objectSpread2({}, styles), {}, {\n        'transform-origin': \"\".concat(offset.x + transform.x / 16, \"em \").concat(offset.y + transform.y / 16, \"em\")\n      }));\n    }\n\n    return [{\n      tag: 'svg',\n      attributes: attributes,\n      children: children\n    }];\n  }\n\n  function asSymbol (_ref) {\n    var prefix = _ref.prefix,\n        iconName = _ref.iconName,\n        children = _ref.children,\n        attributes = _ref.attributes,\n        symbol = _ref.symbol;\n    var id = symbol === true ? \"\".concat(prefix, \"-\").concat(config.familyPrefix, \"-\").concat(iconName) : symbol;\n    return [{\n      tag: 'svg',\n      attributes: {\n        style: 'display: none;'\n      },\n      children: [{\n        tag: 'symbol',\n        attributes: _objectSpread2(_objectSpread2({}, attributes), {}, {\n          id: id\n        }),\n        children: children\n      }]\n    }];\n  }\n\n  function makeInlineSvgAbstract(params) {\n    var _params$icons = params.icons,\n        main = _params$icons.main,\n        mask = _params$icons.mask,\n        prefix = params.prefix,\n        iconName = params.iconName,\n        transform = params.transform,\n        symbol = params.symbol,\n        title = params.title,\n        maskId = params.maskId,\n        titleId = params.titleId,\n        extra = params.extra,\n        _params$watchable = params.watchable,\n        watchable = _params$watchable === void 0 ? false : _params$watchable;\n\n    var _ref = mask.found ? mask : main,\n        width = _ref.width,\n        height = _ref.height;\n\n    var isUploadedIcon = prefix === 'fak';\n    var widthClass = isUploadedIcon ? '' : \"fa-w-\".concat(Math.ceil(width / height * 16));\n    var attrClass = [config.replacementClass, iconName ? \"\".concat(config.familyPrefix, \"-\").concat(iconName) : '', widthClass].filter(function (c) {\n      return extra.classes.indexOf(c) === -1;\n    }).filter(function (c) {\n      return c !== '' || !!c;\n    }).concat(extra.classes).join(' ');\n    var content = {\n      children: [],\n      attributes: _objectSpread2(_objectSpread2({}, extra.attributes), {}, {\n        'data-prefix': prefix,\n        'data-icon': iconName,\n        'class': attrClass,\n        'role': extra.attributes.role || 'img',\n        'xmlns': 'http://www.w3.org/2000/svg',\n        'viewBox': \"0 0 \".concat(width, \" \").concat(height)\n      })\n    };\n    var uploadedIconWidthStyle = isUploadedIcon && !~extra.classes.indexOf('fa-fw') ? {\n      width: \"\".concat(width / height * 16 * 0.0625, \"em\")\n    } : {};\n\n    if (watchable) {\n      content.attributes[DATA_FA_I2SVG] = '';\n    }\n\n    if (title) content.children.push({\n      tag: 'title',\n      attributes: {\n        id: content.attributes['aria-labelledby'] || \"title-\".concat(titleId || nextUniqueId())\n      },\n      children: [title]\n    });\n\n    var args = _objectSpread2(_objectSpread2({}, content), {}, {\n      prefix: prefix,\n      iconName: iconName,\n      main: main,\n      mask: mask,\n      maskId: maskId,\n      transform: transform,\n      symbol: symbol,\n      styles: _objectSpread2(_objectSpread2({}, uploadedIconWidthStyle), extra.styles)\n    });\n\n    var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args),\n        children = _ref2.children,\n        attributes = _ref2.attributes;\n\n    args.children = children;\n    args.attributes = attributes;\n\n    if (symbol) {\n      return asSymbol(args);\n    } else {\n      return asIcon(args);\n    }\n  }\n  function makeLayersTextAbstract(params) {\n    var content = params.content,\n        width = params.width,\n        height = params.height,\n        transform = params.transform,\n        title = params.title,\n        extra = params.extra,\n        _params$watchable2 = params.watchable,\n        watchable = _params$watchable2 === void 0 ? false : _params$watchable2;\n\n    var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n      'title': title\n    } : {}), {}, {\n      'class': extra.classes.join(' ')\n    });\n\n    if (watchable) {\n      attributes[DATA_FA_I2SVG] = '';\n    }\n\n    var styles = _objectSpread2({}, extra.styles);\n\n    if (transformIsMeaningful(transform)) {\n      styles['transform'] = transformForCss({\n        transform: transform,\n        startCentered: true,\n        width: width,\n        height: height\n      });\n      styles['-webkit-transform'] = styles['transform'];\n    }\n\n    var styleString = joinStyles(styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    var val = [];\n    val.push({\n      tag: 'span',\n      attributes: attributes,\n      children: [content]\n    });\n\n    if (title) {\n      val.push({\n        tag: 'span',\n        attributes: {\n          class: 'sr-only'\n        },\n        children: [title]\n      });\n    }\n\n    return val;\n  }\n  function makeLayersCounterAbstract(params) {\n    var content = params.content,\n        title = params.title,\n        extra = params.extra;\n\n    var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n      'title': title\n    } : {}), {}, {\n      'class': extra.classes.join(' ')\n    });\n\n    var styleString = joinStyles(extra.styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    var val = [];\n    val.push({\n      tag: 'span',\n      attributes: attributes,\n      children: [content]\n    });\n\n    if (title) {\n      val.push({\n        tag: 'span',\n        attributes: {\n          class: 'sr-only'\n        },\n        children: [title]\n      });\n    }\n\n    return val;\n  }\n\n  var noop$1 = function noop() {};\n\n  var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : {\n    mark: noop$1,\n    measure: noop$1\n  };\n  var preamble = \"FA \\\"5.15.4\\\"\";\n\n  var begin = function begin(name) {\n    p.mark(\"\".concat(preamble, \" \").concat(name, \" begins\"));\n    return function () {\n      return end(name);\n    };\n  };\n\n  var end = function end(name) {\n    p.mark(\"\".concat(preamble, \" \").concat(name, \" ends\"));\n    p.measure(\"\".concat(preamble, \" \").concat(name), \"\".concat(preamble, \" \").concat(name, \" begins\"), \"\".concat(preamble, \" \").concat(name, \" ends\"));\n  };\n\n  var perf = {\n    begin: begin,\n    end: end\n  };\n\n  /**\n   * Internal helper to bind a function known to have 4 arguments\n   * to a given context.\n   */\n\n  var bindInternal4 = function bindInternal4(func, thisContext) {\n    return function (a, b, c, d) {\n      return func.call(thisContext, a, b, c, d);\n    };\n  };\n\n  /**\n   * # Reduce\n   *\n   * A fast object `.reduce()` implementation.\n   *\n   * @param  {Object}   subject      The object to reduce over.\n   * @param  {Function} fn           The reducer function.\n   * @param  {mixed}    initialValue The initial value for the reducer, defaults to subject[0].\n   * @param  {Object}   thisContext  The context for the reducer.\n   * @return {mixed}                 The final result.\n   */\n\n\n  var reduce = function fastReduceObject(subject, fn, initialValue, thisContext) {\n    var keys = Object.keys(subject),\n        length = keys.length,\n        iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn,\n        i,\n        key,\n        result;\n\n    if (initialValue === undefined) {\n      i = 1;\n      result = subject[keys[0]];\n    } else {\n      i = 0;\n      result = initialValue;\n    }\n\n    for (; i < length; i++) {\n      key = keys[i];\n      result = iterator(result, subject[key], key, subject);\n    }\n\n    return result;\n  };\n\n  function toHex(unicode) {\n    var result = '';\n\n    for (var i = 0; i < unicode.length; i++) {\n      var hex = unicode.charCodeAt(i).toString(16);\n      result += ('000' + hex).slice(-4);\n    }\n\n    return result;\n  }\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var styles = namespace.styles,\n      shims = namespace.shims;\n  var _byUnicode = {};\n  var _byLigature = {};\n  var _byOldName = {};\n  var build = function build() {\n    var lookup = function lookup(reducer) {\n      return reduce(styles, function (o, style, prefix) {\n        o[prefix] = reduce(style, reducer, {});\n        return o;\n      }, {});\n    };\n\n    _byUnicode = lookup(function (acc, icon, iconName) {\n      if (icon[3]) {\n        acc[icon[3]] = iconName;\n      }\n\n      return acc;\n    });\n    _byLigature = lookup(function (acc, icon, iconName) {\n      var ligatures = icon[2];\n      acc[iconName] = iconName;\n      ligatures.forEach(function (ligature) {\n        acc[ligature] = iconName;\n      });\n      return acc;\n    });\n    var hasRegular = ('far' in styles);\n    _byOldName = reduce(shims, function (acc, shim) {\n      var oldName = shim[0];\n      var prefix = shim[1];\n      var iconName = shim[2];\n\n      if (prefix === 'far' && !hasRegular) {\n        prefix = 'fas';\n      }\n\n      acc[oldName] = {\n        prefix: prefix,\n        iconName: iconName\n      };\n      return acc;\n    }, {});\n  };\n  build();\n  function byUnicode(prefix, unicode) {\n    return (_byUnicode[prefix] || {})[unicode];\n  }\n  function byLigature(prefix, ligature) {\n    return (_byLigature[prefix] || {})[ligature];\n  }\n  function byOldName(name) {\n    return _byOldName[name] || {\n      prefix: null,\n      iconName: null\n    };\n  }\n\n  var styles$1 = namespace.styles;\n  var emptyCanonicalIcon = function emptyCanonicalIcon() {\n    return {\n      prefix: null,\n      iconName: null,\n      rest: []\n    };\n  };\n  function getCanonicalIcon(values) {\n    return values.reduce(function (acc, cls) {\n      var iconName = getIconName(config.familyPrefix, cls);\n\n      if (styles$1[cls]) {\n        acc.prefix = cls;\n      } else if (config.autoFetchSvg && Object.keys(PREFIX_TO_STYLE).indexOf(cls) > -1) {\n        acc.prefix = cls;\n      } else if (iconName) {\n        var shim = acc.prefix === 'fa' ? byOldName(iconName) : {};\n        acc.iconName = shim.iconName || iconName;\n        acc.prefix = shim.prefix || acc.prefix;\n      } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) {\n        acc.rest.push(cls);\n      }\n\n      return acc;\n    }, emptyCanonicalIcon());\n  }\n  function iconFromMapping(mapping, prefix, iconName) {\n    if (mapping && mapping[prefix] && mapping[prefix][iconName]) {\n      return {\n        prefix: prefix,\n        iconName: iconName,\n        icon: mapping[prefix][iconName]\n      };\n    }\n  }\n\n  function toHtml(abstractNodes) {\n    var tag = abstractNodes.tag,\n        _abstractNodes$attrib = abstractNodes.attributes,\n        attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib,\n        _abstractNodes$childr = abstractNodes.children,\n        children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr;\n\n    if (typeof abstractNodes === 'string') {\n      return htmlEscape(abstractNodes);\n    } else {\n      return \"<\".concat(tag, \" \").concat(joinAttributes(attributes), \">\").concat(children.map(toHtml).join(''), \"</\").concat(tag, \">\");\n    }\n  }\n\n  var noop$2 = function noop() {};\n\n  function isWatched(node) {\n    var i2svg = node.getAttribute ? node.getAttribute(DATA_FA_I2SVG) : null;\n    return typeof i2svg === 'string';\n  }\n\n  function getMutator() {\n    if (config.autoReplaceSvg === true) {\n      return mutators.replace;\n    }\n\n    var mutator = mutators[config.autoReplaceSvg];\n    return mutator || mutators.replace;\n  }\n\n  var mutators = {\n    replace: function replace(mutation) {\n      var node = mutation[0];\n      var abstract = mutation[1];\n      var newOuterHTML = abstract.map(function (a) {\n        return toHtml(a);\n      }).join('\\n');\n\n      if (node.parentNode && node.outerHTML) {\n        node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? \"<!-- \".concat(node.outerHTML, \" Font Awesome fontawesome.com -->\") : '');\n      } else if (node.parentNode) {\n        var newNode = document.createElement('span');\n        node.parentNode.replaceChild(newNode, node);\n        newNode.outerHTML = newOuterHTML;\n      }\n    },\n    nest: function nest(mutation) {\n      var node = mutation[0];\n      var abstract = mutation[1]; // If we already have a replaced node we do not want to continue nesting within it.\n      // Short-circuit to the standard replacement\n\n      if (~classArray(node).indexOf(config.replacementClass)) {\n        return mutators.replace(mutation);\n      }\n\n      var forSvg = new RegExp(\"\".concat(config.familyPrefix, \"-.*\"));\n      delete abstract[0].attributes.style;\n      delete abstract[0].attributes.id;\n      var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) {\n        if (cls === config.replacementClass || cls.match(forSvg)) {\n          acc.toSvg.push(cls);\n        } else {\n          acc.toNode.push(cls);\n        }\n\n        return acc;\n      }, {\n        toNode: [],\n        toSvg: []\n      });\n      abstract[0].attributes.class = splitClasses.toSvg.join(' ');\n      var newInnerHTML = abstract.map(function (a) {\n        return toHtml(a);\n      }).join('\\n');\n      node.setAttribute('class', splitClasses.toNode.join(' '));\n      node.setAttribute(DATA_FA_I2SVG, '');\n      node.innerHTML = newInnerHTML;\n    }\n  };\n\n  function performOperationSync(op) {\n    op();\n  }\n\n  function perform(mutations, callback) {\n    var callbackFunction = typeof callback === 'function' ? callback : noop$2;\n\n    if (mutations.length === 0) {\n      callbackFunction();\n    } else {\n      var frame = performOperationSync;\n\n      if (config.mutateApproach === MUTATION_APPROACH_ASYNC) {\n        frame = WINDOW.requestAnimationFrame || performOperationSync;\n      }\n\n      frame(function () {\n        var mutator = getMutator();\n        var mark = perf.begin('mutate');\n        mutations.map(mutator);\n        mark();\n        callbackFunction();\n      });\n    }\n  }\n  var disabled = false;\n  function disableObservation() {\n    disabled = true;\n  }\n  function enableObservation() {\n    disabled = false;\n  }\n  var mo = null;\n  function observe(options) {\n    if (!MUTATION_OBSERVER) {\n      return;\n    }\n\n    if (!config.observeMutations) {\n      return;\n    }\n\n    var treeCallback = options.treeCallback,\n        nodeCallback = options.nodeCallback,\n        pseudoElementsCallback = options.pseudoElementsCallback,\n        _options$observeMutat = options.observeMutationsRoot,\n        observeMutationsRoot = _options$observeMutat === void 0 ? DOCUMENT : _options$observeMutat;\n    mo = new MUTATION_OBSERVER(function (objects) {\n      if (disabled) return;\n      toArray(objects).forEach(function (mutationRecord) {\n        if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isWatched(mutationRecord.addedNodes[0])) {\n          if (config.searchPseudoElements) {\n            pseudoElementsCallback(mutationRecord.target);\n          }\n\n          treeCallback(mutationRecord.target);\n        }\n\n        if (mutationRecord.type === 'attributes' && mutationRecord.target.parentNode && config.searchPseudoElements) {\n          pseudoElementsCallback(mutationRecord.target.parentNode);\n        }\n\n        if (mutationRecord.type === 'attributes' && isWatched(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) {\n          if (mutationRecord.attributeName === 'class') {\n            var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)),\n                prefix = _getCanonicalIcon.prefix,\n                iconName = _getCanonicalIcon.iconName;\n\n            if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix);\n            if (iconName) mutationRecord.target.setAttribute('data-icon', iconName);\n          } else {\n            nodeCallback(mutationRecord.target);\n          }\n        }\n      });\n    });\n    if (!IS_DOM) return;\n    mo.observe(observeMutationsRoot, {\n      childList: true,\n      attributes: true,\n      characterData: true,\n      subtree: true\n    });\n  }\n  function disconnect() {\n    if (!mo) return;\n    mo.disconnect();\n  }\n\n  function styleParser (node) {\n    var style = node.getAttribute('style');\n    var val = [];\n\n    if (style) {\n      val = style.split(';').reduce(function (acc, style) {\n        var styles = style.split(':');\n        var prop = styles[0];\n        var value = styles.slice(1);\n\n        if (prop && value.length > 0) {\n          acc[prop] = value.join(':').trim();\n        }\n\n        return acc;\n      }, {});\n    }\n\n    return val;\n  }\n\n  function classParser (node) {\n    var existingPrefix = node.getAttribute('data-prefix');\n    var existingIconName = node.getAttribute('data-icon');\n    var innerText = node.innerText !== undefined ? node.innerText.trim() : '';\n    var val = getCanonicalIcon(classArray(node));\n\n    if (existingPrefix && existingIconName) {\n      val.prefix = existingPrefix;\n      val.iconName = existingIconName;\n    }\n\n    if (val.prefix && innerText.length > 1) {\n      val.iconName = byLigature(val.prefix, node.innerText);\n    } else if (val.prefix && innerText.length === 1) {\n      val.iconName = byUnicode(val.prefix, toHex(node.innerText));\n    }\n\n    return val;\n  }\n\n  var parseTransformString = function parseTransformString(transformString) {\n    var transform = {\n      size: 16,\n      x: 0,\n      y: 0,\n      flipX: false,\n      flipY: false,\n      rotate: 0\n    };\n\n    if (!transformString) {\n      return transform;\n    } else {\n      return transformString.toLowerCase().split(' ').reduce(function (acc, n) {\n        var parts = n.toLowerCase().split('-');\n        var first = parts[0];\n        var rest = parts.slice(1).join('-');\n\n        if (first && rest === 'h') {\n          acc.flipX = true;\n          return acc;\n        }\n\n        if (first && rest === 'v') {\n          acc.flipY = true;\n          return acc;\n        }\n\n        rest = parseFloat(rest);\n\n        if (isNaN(rest)) {\n          return acc;\n        }\n\n        switch (first) {\n          case 'grow':\n            acc.size = acc.size + rest;\n            break;\n\n          case 'shrink':\n            acc.size = acc.size - rest;\n            break;\n\n          case 'left':\n            acc.x = acc.x - rest;\n            break;\n\n          case 'right':\n            acc.x = acc.x + rest;\n            break;\n\n          case 'up':\n            acc.y = acc.y - rest;\n            break;\n\n          case 'down':\n            acc.y = acc.y + rest;\n            break;\n\n          case 'rotate':\n            acc.rotate = acc.rotate + rest;\n            break;\n        }\n\n        return acc;\n      }, transform);\n    }\n  };\n  function transformParser (node) {\n    return parseTransformString(node.getAttribute('data-fa-transform'));\n  }\n\n  function symbolParser (node) {\n    var symbol = node.getAttribute('data-fa-symbol');\n    return symbol === null ? false : symbol === '' ? true : symbol;\n  }\n\n  function attributesParser (node) {\n    var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) {\n      if (acc.name !== 'class' && acc.name !== 'style') {\n        acc[attr.name] = attr.value;\n      }\n\n      return acc;\n    }, {});\n    var title = node.getAttribute('title');\n    var titleId = node.getAttribute('data-fa-title-id');\n\n    if (config.autoA11y) {\n      if (title) {\n        extraAttributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n      } else {\n        extraAttributes['aria-hidden'] = 'true';\n        extraAttributes['focusable'] = 'false';\n      }\n    }\n\n    return extraAttributes;\n  }\n\n  function maskParser (node) {\n    var mask = node.getAttribute('data-fa-mask');\n\n    if (!mask) {\n      return emptyCanonicalIcon();\n    } else {\n      return getCanonicalIcon(mask.split(' ').map(function (i) {\n        return i.trim();\n      }));\n    }\n  }\n\n  function blankMeta() {\n    return {\n      iconName: null,\n      title: null,\n      titleId: null,\n      prefix: null,\n      transform: meaninglessTransform,\n      symbol: false,\n      mask: null,\n      maskId: null,\n      extra: {\n        classes: [],\n        styles: {},\n        attributes: {}\n      }\n    };\n  }\n  function parseMeta(node) {\n    var _classParser = classParser(node),\n        iconName = _classParser.iconName,\n        prefix = _classParser.prefix,\n        extraClasses = _classParser.rest;\n\n    var extraStyles = styleParser(node);\n    var transform = transformParser(node);\n    var symbol = symbolParser(node);\n    var extraAttributes = attributesParser(node);\n    var mask = maskParser(node);\n    return {\n      iconName: iconName,\n      title: node.getAttribute('title'),\n      titleId: node.getAttribute('data-fa-title-id'),\n      prefix: prefix,\n      transform: transform,\n      symbol: symbol,\n      mask: mask,\n      maskId: node.getAttribute('data-fa-mask-id'),\n      extra: {\n        classes: extraClasses,\n        styles: extraStyles,\n        attributes: extraAttributes\n      }\n    };\n  }\n\n  function MissingIcon(error) {\n    this.name = 'MissingIcon';\n    this.message = error || 'Icon unavailable';\n    this.stack = new Error().stack;\n  }\n  MissingIcon.prototype = Object.create(Error.prototype);\n  MissingIcon.prototype.constructor = MissingIcon;\n\n  var FILL = {\n    fill: 'currentColor'\n  };\n  var ANIMATION_BASE = {\n    attributeType: 'XML',\n    repeatCount: 'indefinite',\n    dur: '2s'\n  };\n  var RING = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z'\n    })\n  };\n\n  var OPACITY_ANIMATE = _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n    attributeName: 'opacity'\n  });\n\n  var DOT = {\n    tag: 'circle',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      cx: '256',\n      cy: '364',\n      r: '28'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n        attributeName: 'r',\n        values: '28;14;28;28;14;28;'\n      })\n    }, {\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '1;0;1;1;0;1;'\n      })\n    }]\n  };\n  var QUESTION = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      opacity: '1',\n      d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '1;0;0;0;0;1;'\n      })\n    }]\n  };\n  var EXCLAMATION = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      opacity: '0',\n      d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '0;0;1;1;0;0;'\n      })\n    }]\n  };\n  var missing = {\n    tag: 'g',\n    children: [RING, DOT, QUESTION, EXCLAMATION]\n  };\n\n  var styles$2 = namespace.styles;\n  function asFoundIcon(icon) {\n    var width = icon[0];\n    var height = icon[1];\n\n    var _icon$slice = icon.slice(4),\n        _icon$slice2 = _slicedToArray(_icon$slice, 1),\n        vectorData = _icon$slice2[0];\n\n    var element = null;\n\n    if (Array.isArray(vectorData)) {\n      element = {\n        tag: 'g',\n        attributes: {\n          class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.GROUP)\n        },\n        children: [{\n          tag: 'path',\n          attributes: {\n            class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.SECONDARY),\n            fill: 'currentColor',\n            d: vectorData[0]\n          }\n        }, {\n          tag: 'path',\n          attributes: {\n            class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.PRIMARY),\n            fill: 'currentColor',\n            d: vectorData[1]\n          }\n        }]\n      };\n    } else {\n      element = {\n        tag: 'path',\n        attributes: {\n          fill: 'currentColor',\n          d: vectorData\n        }\n      };\n    }\n\n    return {\n      found: true,\n      width: width,\n      height: height,\n      icon: element\n    };\n  }\n  function findIcon(iconName, prefix) {\n    return new picked(function (resolve, reject) {\n      var val = {\n        found: false,\n        width: 512,\n        height: 512,\n        icon: missing\n      };\n\n      if (iconName && prefix && styles$2[prefix] && styles$2[prefix][iconName]) {\n        var icon = styles$2[prefix][iconName];\n        return resolve(asFoundIcon(icon));\n      }\n\n      if (iconName && prefix && !config.showMissingIcons) {\n        reject(new MissingIcon(\"Icon is missing for prefix \".concat(prefix, \" with icon name \").concat(iconName)));\n      } else {\n        resolve(val);\n      }\n    });\n  }\n\n  var styles$3 = namespace.styles;\n\n  function generateSvgReplacementMutation(node, nodeMeta) {\n    var iconName = nodeMeta.iconName,\n        title = nodeMeta.title,\n        titleId = nodeMeta.titleId,\n        prefix = nodeMeta.prefix,\n        transform = nodeMeta.transform,\n        symbol = nodeMeta.symbol,\n        mask = nodeMeta.mask,\n        maskId = nodeMeta.maskId,\n        extra = nodeMeta.extra;\n    return new picked(function (resolve, reject) {\n      picked.all([findIcon(iconName, prefix), findIcon(mask.iconName, mask.prefix)]).then(function (_ref) {\n        var _ref2 = _slicedToArray(_ref, 2),\n            main = _ref2[0],\n            mask = _ref2[1];\n\n        resolve([node, makeInlineSvgAbstract({\n          icons: {\n            main: main,\n            mask: mask\n          },\n          prefix: prefix,\n          iconName: iconName,\n          transform: transform,\n          symbol: symbol,\n          mask: mask,\n          maskId: maskId,\n          title: title,\n          titleId: titleId,\n          extra: extra,\n          watchable: true\n        })]);\n      });\n    });\n  }\n\n  function generateLayersText(node, nodeMeta) {\n    var title = nodeMeta.title,\n        transform = nodeMeta.transform,\n        extra = nodeMeta.extra;\n    var width = null;\n    var height = null;\n\n    if (IS_IE) {\n      var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10);\n      var boundingClientRect = node.getBoundingClientRect();\n      width = boundingClientRect.width / computedFontSize;\n      height = boundingClientRect.height / computedFontSize;\n    }\n\n    if (config.autoA11y && !title) {\n      extra.attributes['aria-hidden'] = 'true';\n    }\n\n    return picked.resolve([node, makeLayersTextAbstract({\n      content: node.innerHTML,\n      width: width,\n      height: height,\n      transform: transform,\n      title: title,\n      extra: extra,\n      watchable: true\n    })]);\n  }\n\n  function generateMutation(node) {\n    var nodeMeta = parseMeta(node);\n\n    if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) {\n      return generateLayersText(node, nodeMeta);\n    } else {\n      return generateSvgReplacementMutation(node, nodeMeta);\n    }\n  }\n\n  function onTree(root) {\n    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n    if (!IS_DOM) return;\n    var htmlClassList = DOCUMENT.documentElement.classList;\n\n    var hclAdd = function hclAdd(suffix) {\n      return htmlClassList.add(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n    };\n\n    var hclRemove = function hclRemove(suffix) {\n      return htmlClassList.remove(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n    };\n\n    var prefixes = config.autoFetchSvg ? Object.keys(PREFIX_TO_STYLE) : Object.keys(styles$3);\n    var prefixesDomQuery = [\".\".concat(LAYERS_TEXT_CLASSNAME, \":not([\").concat(DATA_FA_I2SVG, \"])\")].concat(prefixes.map(function (p) {\n      return \".\".concat(p, \":not([\").concat(DATA_FA_I2SVG, \"])\");\n    })).join(', ');\n\n    if (prefixesDomQuery.length === 0) {\n      return;\n    }\n\n    var candidates = [];\n\n    try {\n      candidates = toArray(root.querySelectorAll(prefixesDomQuery));\n    } catch (e) {// noop\n    }\n\n    if (candidates.length > 0) {\n      hclAdd('pending');\n      hclRemove('complete');\n    } else {\n      return;\n    }\n\n    var mark = perf.begin('onTree');\n    var mutations = candidates.reduce(function (acc, node) {\n      try {\n        var mutation = generateMutation(node);\n\n        if (mutation) {\n          acc.push(mutation);\n        }\n      } catch (e) {\n        if (!PRODUCTION) {\n          if (e instanceof MissingIcon) {\n            console.error(e);\n          }\n        }\n      }\n\n      return acc;\n    }, []);\n    return new picked(function (resolve, reject) {\n      picked.all(mutations).then(function (resolvedMutations) {\n        perform(resolvedMutations, function () {\n          hclAdd('active');\n          hclAdd('complete');\n          hclRemove('pending');\n          if (typeof callback === 'function') callback();\n          mark();\n          resolve();\n        });\n      }).catch(function () {\n        mark();\n        reject();\n      });\n    });\n  }\n  function onNode(node) {\n    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n    generateMutation(node).then(function (mutation) {\n      if (mutation) {\n        perform([mutation], callback);\n      }\n    });\n  }\n\n  function replaceForPosition(node, position) {\n    var pendingAttribute = \"\".concat(DATA_FA_PSEUDO_ELEMENT_PENDING).concat(position.replace(':', '-'));\n    return new picked(function (resolve, reject) {\n      if (node.getAttribute(pendingAttribute) !== null) {\n        // This node is already being processed\n        return resolve();\n      }\n\n      var children = toArray(node.children);\n      var alreadyProcessedPseudoElement = children.filter(function (c) {\n        return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === position;\n      })[0];\n      var styles = WINDOW.getComputedStyle(node, position);\n      var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN);\n      var fontWeight = styles.getPropertyValue('font-weight');\n      var content = styles.getPropertyValue('content');\n\n      if (alreadyProcessedPseudoElement && !fontFamily) {\n        // If we've already processed it but the current computed style does not result in a font-family,\n        // that probably means that a class name that was previously present to make the icon has been\n        // removed. So we now should delete the icon.\n        node.removeChild(alreadyProcessedPseudoElement);\n        return resolve();\n      } else if (fontFamily && content !== 'none' && content !== '') {\n        var _content = styles.getPropertyValue('content');\n\n        var prefix = ~['Solid', 'Regular', 'Light', 'Duotone', 'Brands', 'Kit'].indexOf(fontFamily[2]) ? STYLE_TO_PREFIX[fontFamily[2].toLowerCase()] : FONT_WEIGHT_TO_PREFIX[fontWeight];\n        var hexValue = toHex(_content.length === 3 ? _content.substr(1, 1) : _content);\n        var iconName = byUnicode(prefix, hexValue);\n        var iconIdentifier = iconName; // Only convert the pseudo element in this :before/:after position into an icon if we haven't\n        // already done so with the same prefix and iconName\n\n        if (iconName && (!alreadyProcessedPseudoElement || alreadyProcessedPseudoElement.getAttribute(DATA_PREFIX) !== prefix || alreadyProcessedPseudoElement.getAttribute(DATA_ICON) !== iconIdentifier)) {\n          node.setAttribute(pendingAttribute, iconIdentifier);\n\n          if (alreadyProcessedPseudoElement) {\n            // Delete the old one, since we're replacing it with a new one\n            node.removeChild(alreadyProcessedPseudoElement);\n          }\n\n          var meta = blankMeta();\n          var extra = meta.extra;\n          extra.attributes[DATA_FA_PSEUDO_ELEMENT] = position;\n          findIcon(iconName, prefix).then(function (main) {\n            var abstract = makeInlineSvgAbstract(_objectSpread2(_objectSpread2({}, meta), {}, {\n              icons: {\n                main: main,\n                mask: emptyCanonicalIcon()\n              },\n              prefix: prefix,\n              iconName: iconIdentifier,\n              extra: extra,\n              watchable: true\n            }));\n            var element = DOCUMENT.createElement('svg');\n\n            if (position === ':before') {\n              node.insertBefore(element, node.firstChild);\n            } else {\n              node.appendChild(element);\n            }\n\n            element.outerHTML = abstract.map(function (a) {\n              return toHtml(a);\n            }).join('\\n');\n            node.removeAttribute(pendingAttribute);\n            resolve();\n          }).catch(reject);\n        } else {\n          resolve();\n        }\n      } else {\n        resolve();\n      }\n    });\n  }\n\n  function replace(node) {\n    return picked.all([replaceForPosition(node, ':before'), replaceForPosition(node, ':after')]);\n  }\n\n  function processable(node) {\n    return node.parentNode !== document.head && !~TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS.indexOf(node.tagName.toUpperCase()) && !node.getAttribute(DATA_FA_PSEUDO_ELEMENT) && (!node.parentNode || node.parentNode.tagName !== 'svg');\n  }\n\n  function searchPseudoElements (root) {\n    if (!IS_DOM) return;\n    return new picked(function (resolve, reject) {\n      var operations = toArray(root.querySelectorAll('*')).filter(processable).map(replace);\n      var end = perf.begin('searchPseudoElements');\n      disableObservation();\n      picked.all(operations).then(function () {\n        end();\n        enableObservation();\n        resolve();\n      }).catch(function () {\n        end();\n        enableObservation();\n        reject();\n      });\n    });\n  }\n\n  var baseStyles = \"svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;-webkit-box-sizing:border-box;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor);opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.fad.fa-inverse{color:#fff}\";\n\n  function css () {\n    var dfp = DEFAULT_FAMILY_PREFIX;\n    var drc = DEFAULT_REPLACEMENT_CLASS;\n    var fp = config.familyPrefix;\n    var rc = config.replacementClass;\n    var s = baseStyles;\n\n    if (fp !== dfp || rc !== drc) {\n      var dPatt = new RegExp(\"\\\\.\".concat(dfp, \"\\\\-\"), 'g');\n      var customPropPatt = new RegExp(\"\\\\--\".concat(dfp, \"\\\\-\"), 'g');\n      var rPatt = new RegExp(\"\\\\.\".concat(drc), 'g');\n      s = s.replace(dPatt, \".\".concat(fp, \"-\")).replace(customPropPatt, \"--\".concat(fp, \"-\")).replace(rPatt, \".\".concat(rc));\n    }\n\n    return s;\n  }\n\n  var Library = /*#__PURE__*/function () {\n    function Library() {\n      _classCallCheck(this, Library);\n\n      this.definitions = {};\n    }\n\n    _createClass(Library, [{\n      key: \"add\",\n      value: function add() {\n        var _this = this;\n\n        for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) {\n          definitions[_key] = arguments[_key];\n        }\n\n        var additions = definitions.reduce(this._pullDefinitions, {});\n        Object.keys(additions).forEach(function (key) {\n          _this.definitions[key] = _objectSpread2(_objectSpread2({}, _this.definitions[key] || {}), additions[key]);\n          defineIcons(key, additions[key]);\n          build();\n        });\n      }\n    }, {\n      key: \"reset\",\n      value: function reset() {\n        this.definitions = {};\n      }\n    }, {\n      key: \"_pullDefinitions\",\n      value: function _pullDefinitions(additions, definition) {\n        var normalized = definition.prefix && definition.iconName && definition.icon ? {\n          0: definition\n        } : definition;\n        Object.keys(normalized).map(function (key) {\n          var _normalized$key = normalized[key],\n              prefix = _normalized$key.prefix,\n              iconName = _normalized$key.iconName,\n              icon = _normalized$key.icon;\n          if (!additions[prefix]) additions[prefix] = {};\n          additions[prefix][iconName] = icon;\n        });\n        return additions;\n      }\n    }]);\n\n    return Library;\n  }();\n\n  function ensureCss() {\n    if (config.autoAddCss && !_cssInserted) {\n      insertCss(css());\n\n      _cssInserted = true;\n    }\n  }\n\n  function apiObject(val, abstractCreator) {\n    Object.defineProperty(val, 'abstract', {\n      get: abstractCreator\n    });\n    Object.defineProperty(val, 'html', {\n      get: function get() {\n        return val.abstract.map(function (a) {\n          return toHtml(a);\n        });\n      }\n    });\n    Object.defineProperty(val, 'node', {\n      get: function get() {\n        if (!IS_DOM) return;\n        var container = DOCUMENT.createElement('div');\n        container.innerHTML = val.html;\n        return container.children;\n      }\n    });\n    return val;\n  }\n\n  function findIconDefinition(iconLookup) {\n    var _iconLookup$prefix = iconLookup.prefix,\n        prefix = _iconLookup$prefix === void 0 ? 'fa' : _iconLookup$prefix,\n        iconName = iconLookup.iconName;\n    if (!iconName) return;\n    return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName);\n  }\n\n  function resolveIcons(next) {\n    return function (maybeIconDefinition) {\n      var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n      var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {});\n      var mask = params.mask;\n\n      if (mask) {\n        mask = (mask || {}).icon ? mask : findIconDefinition(mask || {});\n      }\n\n      return next(iconDefinition, _objectSpread2(_objectSpread2({}, params), {}, {\n        mask: mask\n      }));\n    };\n  }\n\n  var library = new Library();\n  var noAuto = function noAuto() {\n    config.autoReplaceSvg = false;\n    config.observeMutations = false;\n    disconnect();\n  };\n  var _cssInserted = false;\n  var dom = {\n    i2svg: function i2svg() {\n      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n      if (IS_DOM) {\n        ensureCss();\n        var _params$node = params.node,\n            node = _params$node === void 0 ? DOCUMENT : _params$node,\n            _params$callback = params.callback,\n            callback = _params$callback === void 0 ? function () {} : _params$callback;\n\n        if (config.searchPseudoElements) {\n          searchPseudoElements(node);\n        }\n\n        return onTree(node, callback);\n      } else {\n        return picked.reject('Operation requires a DOM of some kind.');\n      }\n    },\n    css: css,\n    insertCss: function insertCss$$1() {\n      if (!_cssInserted) {\n        insertCss(css());\n\n        _cssInserted = true;\n      }\n    },\n    watch: function watch() {\n      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n      var autoReplaceSvgRoot = params.autoReplaceSvgRoot,\n          observeMutationsRoot = params.observeMutationsRoot;\n\n      if (config.autoReplaceSvg === false) {\n        config.autoReplaceSvg = true;\n      }\n\n      config.observeMutations = true;\n      domready(function () {\n        autoReplace({\n          autoReplaceSvgRoot: autoReplaceSvgRoot\n        });\n        observe({\n          treeCallback: onTree,\n          nodeCallback: onNode,\n          pseudoElementsCallback: searchPseudoElements,\n          observeMutationsRoot: observeMutationsRoot\n        });\n      });\n    }\n  };\n  var parse = {\n    transform: function transform(transformString) {\n      return parseTransformString(transformString);\n    }\n  };\n  var icon = resolveIcons(function (iconDefinition) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$transform = params.transform,\n        transform = _params$transform === void 0 ? meaninglessTransform : _params$transform,\n        _params$symbol = params.symbol,\n        symbol = _params$symbol === void 0 ? false : _params$symbol,\n        _params$mask = params.mask,\n        mask = _params$mask === void 0 ? null : _params$mask,\n        _params$maskId = params.maskId,\n        maskId = _params$maskId === void 0 ? null : _params$maskId,\n        _params$title = params.title,\n        title = _params$title === void 0 ? null : _params$title,\n        _params$titleId = params.titleId,\n        titleId = _params$titleId === void 0 ? null : _params$titleId,\n        _params$classes = params.classes,\n        classes = _params$classes === void 0 ? [] : _params$classes,\n        _params$attributes = params.attributes,\n        attributes = _params$attributes === void 0 ? {} : _params$attributes,\n        _params$styles = params.styles,\n        styles = _params$styles === void 0 ? {} : _params$styles;\n    if (!iconDefinition) return;\n    var prefix = iconDefinition.prefix,\n        iconName = iconDefinition.iconName,\n        icon = iconDefinition.icon;\n    return apiObject(_objectSpread2({\n      type: 'icon'\n    }, iconDefinition), function () {\n      ensureCss();\n\n      if (config.autoA11y) {\n        if (title) {\n          attributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n        } else {\n          attributes['aria-hidden'] = 'true';\n          attributes['focusable'] = 'false';\n        }\n      }\n\n      return makeInlineSvgAbstract({\n        icons: {\n          main: asFoundIcon(icon),\n          mask: mask ? asFoundIcon(mask.icon) : {\n            found: false,\n            width: null,\n            height: null,\n            icon: {}\n          }\n        },\n        prefix: prefix,\n        iconName: iconName,\n        transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n        symbol: symbol,\n        title: title,\n        maskId: maskId,\n        titleId: titleId,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: classes\n        }\n      });\n    });\n  });\n  var text = function text(content) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$transform2 = params.transform,\n        transform = _params$transform2 === void 0 ? meaninglessTransform : _params$transform2,\n        _params$title2 = params.title,\n        title = _params$title2 === void 0 ? null : _params$title2,\n        _params$classes2 = params.classes,\n        classes = _params$classes2 === void 0 ? [] : _params$classes2,\n        _params$attributes2 = params.attributes,\n        attributes = _params$attributes2 === void 0 ? {} : _params$attributes2,\n        _params$styles2 = params.styles,\n        styles = _params$styles2 === void 0 ? {} : _params$styles2;\n    return apiObject({\n      type: 'text',\n      content: content\n    }, function () {\n      ensureCss();\n      return makeLayersTextAbstract({\n        content: content,\n        transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n        title: title,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: [\"\".concat(config.familyPrefix, \"-layers-text\")].concat(_toConsumableArray(classes))\n        }\n      });\n    });\n  };\n  var counter = function counter(content) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$title3 = params.title,\n        title = _params$title3 === void 0 ? null : _params$title3,\n        _params$classes3 = params.classes,\n        classes = _params$classes3 === void 0 ? [] : _params$classes3,\n        _params$attributes3 = params.attributes,\n        attributes = _params$attributes3 === void 0 ? {} : _params$attributes3,\n        _params$styles3 = params.styles,\n        styles = _params$styles3 === void 0 ? {} : _params$styles3;\n    return apiObject({\n      type: 'counter',\n      content: content\n    }, function () {\n      ensureCss();\n      return makeLayersCounterAbstract({\n        content: content.toString(),\n        title: title,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: [\"\".concat(config.familyPrefix, \"-layers-counter\")].concat(_toConsumableArray(classes))\n        }\n      });\n    });\n  };\n  var layer = function layer(assembler) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$classes4 = params.classes,\n        classes = _params$classes4 === void 0 ? [] : _params$classes4;\n    return apiObject({\n      type: 'layer'\n    }, function () {\n      ensureCss();\n      var children = [];\n      assembler(function (args) {\n        Array.isArray(args) ? args.map(function (a) {\n          children = children.concat(a.abstract);\n        }) : children = children.concat(args.abstract);\n      });\n      return [{\n        tag: 'span',\n        attributes: {\n          class: [\"\".concat(config.familyPrefix, \"-layers\")].concat(_toConsumableArray(classes)).join(' ')\n        },\n        children: children\n      }];\n    });\n  };\n  var api = {\n    noAuto: noAuto,\n    config: config,\n    dom: dom,\n    library: library,\n    parse: parse,\n    findIconDefinition: findIconDefinition,\n    icon: icon,\n    text: text,\n    counter: counter,\n    layer: layer,\n    toHtml: toHtml\n  };\n\n  var autoReplace = function autoReplace() {\n    var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n    var _params$autoReplaceSv = params.autoReplaceSvgRoot,\n        autoReplaceSvgRoot = _params$autoReplaceSv === void 0 ? DOCUMENT : _params$autoReplaceSv;\n    if ((Object.keys(namespace.styles).length > 0 || config.autoFetchSvg) && IS_DOM && config.autoReplaceSvg) api.dom.i2svg({\n      node: autoReplaceSvgRoot\n    });\n  };\n\n  function bootstrap() {\n    if (IS_BROWSER) {\n      if (!WINDOW.FontAwesome) {\n        WINDOW.FontAwesome = api;\n      }\n\n      domready(function () {\n        autoReplace();\n        observe({\n          treeCallback: onTree,\n          nodeCallback: onNode,\n          pseudoElementsCallback: searchPseudoElements\n        });\n      });\n    }\n\n    namespace.hooks = _objectSpread2(_objectSpread2({}, namespace.hooks), {}, {\n      addPack: function addPack(prefix, icons) {\n        namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), icons);\n        build();\n        autoReplace();\n      },\n      addShims: function addShims(shims) {\n        var _namespace$shims;\n\n        (_namespace$shims = namespace.shims).push.apply(_namespace$shims, _toConsumableArray(shims));\n\n        build();\n        autoReplace();\n      }\n    });\n  }\n\n  bunker(bootstrap);\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js/regular.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"check-circle\": [512, 512, [], \"f058\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z\"],\n    \"desktop\": [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v288c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V54c0-3.3 2.7-6 6-6h468c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-42 152c0 13.3-10.7 24-24 24H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h98.7l18.6-55.8c1.6-4.9 6.2-8.2 11.4-8.2h78.7c5.2 0 9.8 3.3 11.4 8.2l18.6 55.8H456c13.3 0 24 10.7 24 24z\"],\n    \"eye\": [576, 512, [], \"f06e\", \"M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z\"],\n    \"file-code\": [384, 512, [], \"f1c9\", \"M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z\"],\n    \"info\": [256, 512, [], \"f129\", \"M224 352.589V224c0-16.475-6.258-31.517-16.521-42.872C225.905 161.14 236 135.346 236 108 236 48.313 187.697 0 128 0 68.313 0 20 48.303 20 108c0 20.882 5.886 40.859 16.874 58.037C15.107 176.264 0 198.401 0 224v39.314c0 23.641 12.884 44.329 32 55.411v33.864C12.884 363.671 0 384.359 0 408v40c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-40c0-23.641-12.884-44.329-32-55.411zM128 48c33.137 0 60 26.863 60 60s-26.863 60-60 60-60-26.863-60-60 26.863-60 60-60zm80 400c0 8.836-7.164 16-16 16H64c-8.836 0-16-7.164-16-16v-40c0-8.836 7.164-16 16-16h16V279.314H64c-8.836 0-16-7.164-16-16V224c0-8.836 7.164-16 16-16h96c8.836 0 16 7.164 16 16v168h16c8.836 0 16 7.164 16 16v40z\"],\n    \"info-circle\": [512, 512, [], \"f05a\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm0-338c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"],\n    \"plus\": [384, 512, [], \"f067\", \"M368 224H224V80c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h144v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V288h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"],\n    \"question-circle\": [512, 512, [], \"f059\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z\"],\n    \"rocket\": [512, 512, [], \"f135\", \"M367.96813,103.99609a39.999,39.999,0,1,0,40.00384,40A40.02908,40.02908,0,0,0,367.96813,103.99609ZM505.07337,19.3418c-1.21875-5.60742-6.75-11.13868-12.34373-12.3418-32.62885-7-58.162-7-83.57017-7C305.39988,0,242.95858,55.0918,196.236,127.99609H94.82015c-16.34567.01563-35.53314,11.875-42.87883,26.48243L2.53125,253.28906A28.12512,28.12512,0,0,0,0,263.99219a24.00617,24.00617,0,0,0,24.00191,23.998h92.63266l-10.59373,21.42188c-9.33592,18.91016,4.27733,34.77344,6.15624,36.62305l53.75381,53.71875c15.56443,15.54492,33.81635,7.52929,36.6601,6.13867l21.34567-10.57617V488a24.00659,24.00659,0,0,0,24.00191,24,28.618,28.618,0,0,0,10.71873-2.51562l98.6971-49.4043c14.625-7.29688,26.50191-26.5,26.50191-42.85938V315.69336c72.72449-46.76367,128.10525-109.44922,128.10525-212.69727C512.07531,77.4668,512.07531,51.99805,505.07337,19.3418ZM358.53065,274.99023c-36.94135,18.48438-121.10527,60.14063-166.7966,82.73243l-37.50189-37.49805c22.59567-45.6875,64.25575-129.99609,82.72447-166.88672C284.33741,79.5293,335.96623,47.99805,409.15947,47.99805c18.00192,0,34.2851,0,52.56632,2.34375,2.375,18.71875,2.31249,35.27929,2.25,52.63867C463.97578,175.75977,432.41138,227.30469,358.53065,274.99023Z\"],\n    \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z\"],\n    \"slash\": [640, 512, [], \"f715\", \"M604 508.49L6.01 40.98c-6.9-5.52-8.02-15.59-2.49-22.49L13.51 6C19.03-.9 29.1-2.01 36 3.51l598 467.51c6.9 5.52 8.02 15.59 2.49 22.49l-10 12.49c-5.52 6.9-15.59 8.01-22.49 2.49z\"],\n    \"times\": [320, 512, [], \"f00d\", \"M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z\"],\n    \"undo\": [512, 512, [], \"f0e2\", \"M12 8h27.711c6.739 0 12.157 5.548 11.997 12.286l-2.347 98.568C93.925 51.834 170.212 7.73 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.835 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.322 0 196-87.662 196-196 0-108.322-87.662-196-196-196-79.545 0-147.941 47.282-178.675 115.302l126.389-3.009c6.737-.16 12.286 5.257 12.286 11.997V212c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V20C0 13.373 5.373 8 12 8z\"],\n    \"undo-alt\": [512, 512, [], \"f2ea\", \"M28.485 28.485L80.65 80.65C125.525 35.767 187.515 8 255.999 8 392.66 8 504.1 119.525 504 256.185 503.9 393.067 392.905 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.353-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.321 0 196-87.662 196-196 0-108.321-87.662-196-196-196-54.163 0-103.157 21.923-138.614 57.386l54.128 54.129c7.56 7.56 2.206 20.485-8.485 20.485H20c-6.627 0-12-5.373-12-12V36.971c0-10.691 12.926-16.045 20.485-8.486z\"],\n    \"user\": [448, 512, [], \"f007\", \"M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z\"],\n    \"user-friends\": [640, 512, [], \"f500\", \"M480 256c53 0 96-43 96-96s-43-96-96-96-96 43-96 96 43 96 96 96zm0-144c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM272.1 276c-11.9 0-23.9 1.7-35.5 5.3-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-11.6-3.5-23.6-5.3-35.5-5.3-36.3 0-71.6 16.2-92.3 46.9C7.2 341.3 0 363.4 0 387.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM336 432H48v-44.8c0-28.9 18.4-53.6 44.1-63.1 10.3-3.8 21.6-3.7 31.9 0 22.1 7.9 45 11.9 68 11.9s45.8-4 68.1-11.9c10.3-3.7 21.6-3.8 31.9 0 25.7 9.4 44.1 34.2 44.1 63.1V432zM192 256c61.9 0 112-50.1 112-112S253.9 32 192 32 80 82.1 80 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm431.7 237.1C606.4 291.5 577 278 546.8 278c-27.8 0-34.8 10-66.8 10s-39-10-66.8-10c-13.3 0-26.2 3-38.2 8.1 5.8 5.9 11.3 12 16 18.9 4.7 7 8.6 14.4 12 22 3.3-.7 6.7-1.1 10.2-1.1 17.2 0 29.6 10 66.8 10 37.4 0 49.5-10 66.8-10 15.7 0 29.5 6.7 37.1 17.9 5.3 7.9 8.1 17.1 8.1 26.7V400H416v32c0 5.5-.6 10.8-1.6 16H600c22.1 0 40-17.9 40-40v-37.3c0-19.9-6-38.3-16.3-53.6z\"],\n    \"users\": [640, 512, [], \"f0c0\", \"M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zm396.4 210.9c-27.5-40.8-80.7-56-127.8-41.7-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-47.1-14.3-100.3.8-127.8 41.7-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c.2-23.8-7-45.9-19.4-64.3zM464 432H176v-44.8c0-36.4 29.2-66.2 65.4-67.2 25.5 10.6 51.9 16 78.6 16 26.7 0 53.1-5.4 78.6-16 36.2 1 65.4 30.7 65.4 67.2V432zm92-176h-24c-17.3 0-33.4 5.3-46.8 14.3 13.4 10.1 25.2 22.2 34.4 36.2 3.9-1.4 8-2.5 12.3-2.5h24c19.8 0 36 16.2 36 36 0 13.2 10.8 24 24 24s24-10.8 24-24c.1-46.3-37.6-84-83.9-84zm-236 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM154.8 270.3c-13.4-9-29.5-14.3-46.8-14.3H84c-46.3 0-84 37.7-84 84 0 13.2 10.8 24 24 24s24-10.8 24-24c0-19.8 16.2-36 36-36h24c4.4 0 8.5 1.1 12.3 2.5 9.3-14 21.1-26.1 34.5-36.2z\"]\n  };\n\n  bunker(function () {\n    defineIcons('far', icons);\n  });\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js/solid.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"alarm-exclamation\": [512, 512, [], \"f843\", \"M96 0A96 96 0 0 0 0 96a94.81 94.81 0 0 0 15.3 51.26L161.2 25.68A95.63 95.63 0 0 0 96 0zm320 0a95.66 95.66 0 0 0-65.18 25.66l145.89 121.57A94.85 94.85 0 0 0 512 96a96 96 0 0 0-96-96zM256 64C132.3 64 32 164.29 32 288a222.7 222.7 0 0 0 44.79 134l-40.1 40.09a16 16 0 0 0 0 22.63l22.62 22.62a16 16 0 0 0 22.63 0L122 467.22a222.82 222.82 0 0 0 268 0l40.1 40.09a16 16 0 0 0 22.62 0l22.63-22.62a16 16 0 0 0 0-22.63L435.25 422A222.69 222.69 0 0 0 480 288c0-123.71-100.26-224-224-224zm0 352a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm25.4-110.4a16 16 0 0 1-15.9 14.4h-19a16 16 0 0 1-15.9-14.4l-12.8-128a16.06 16.06 0 0 1 15.9-17.6h44.6a16 16 0 0 1 15.9 17.6z\"],\n    \"align-left\": [448, 512, [], \"f036\", \"M12.83 352h262.34A12.82 12.82 0 0 0 288 339.17v-38.34A12.82 12.82 0 0 0 275.17 288H12.83A12.82 12.82 0 0 0 0 300.83v38.34A12.82 12.82 0 0 0 12.83 352zm0-256h262.34A12.82 12.82 0 0 0 288 83.17V44.83A12.82 12.82 0 0 0 275.17 32H12.83A12.82 12.82 0 0 0 0 44.83v38.34A12.82 12.82 0 0 0 12.83 96zM432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"],\n    \"book-dead\": [448, 512, [], \"f6b7\", \"M272 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm176 222.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM240 56c44.2 0 80 28.7 80 64 0 20.9-12.7 39.2-32 50.9V184c0 8.8-7.2 16-16 16h-64c-8.8 0-16-7.2-16-16v-13.1c-19.3-11.7-32-30-32-50.9 0-35.3 35.8-64 80-64zM124.8 223.3l6.3-14.7c1.7-4.1 6.4-5.9 10.5-4.2l98.3 42.1 98.4-42.1c4.1-1.7 8.8.1 10.5 4.2l6.3 14.7c1.7 4.1-.1 8.8-4.2 10.5L280.6 264l70.3 30.1c4.1 1.7 5.9 6.4 4.2 10.5l-6.3 14.7c-1.7 4.1-6.4 5.9-10.5 4.2L240 281.4l-98.3 42.2c-4.1 1.7-8.8-.1-10.5-4.2l-6.3-14.7c-1.7-4.1.1-8.8 4.2-10.5l70.4-30.1-70.5-30.3c-4.1-1.7-5.9-6.4-4.2-10.5zm256 224.7H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8zM208 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16z\"],\n    \"check\": [512, 512, [], \"f00c\", \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"],\n    \"circle\": [512, 512, [], \"f111\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"],\n    \"cloud\": [640, 512, [], \"f0c2\", \"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z\"],\n    \"credit-card\": [576, 512, [], \"f09d\", \"M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z\"],\n    \"desktop\": [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z\"],\n    \"envelope\": [512, 512, [], \"f0e0\", \"M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z\"],\n    \"eye\": [576, 512, [], \"f06e\", \"M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z\"],\n    \"fingerprint\": [512, 512, [], \"f577\", \"M256.12 245.96c-13.25 0-24 10.74-24 24 1.14 72.25-8.14 141.9-27.7 211.55-2.73 9.72 2.15 30.49 23.12 30.49 10.48 0 20.11-6.92 23.09-17.52 13.53-47.91 31.04-125.41 29.48-224.52.01-13.25-10.73-24-23.99-24zm-.86-81.73C194 164.16 151.25 211.3 152.1 265.32c.75 47.94-3.75 95.91-13.37 142.55-2.69 12.98 5.67 25.69 18.64 28.36 13.05 2.67 25.67-5.66 28.36-18.64 10.34-50.09 15.17-101.58 14.37-153.02-.41-25.95 19.92-52.49 54.45-52.34 31.31.47 57.15 25.34 57.62 55.47.77 48.05-2.81 96.33-10.61 143.55-2.17 13.06 6.69 25.42 19.76 27.58 19.97 3.33 26.81-15.1 27.58-19.77 8.28-50.03 12.06-101.21 11.27-152.11-.88-55.8-47.94-101.88-104.91-102.72zm-110.69-19.78c-10.3-8.34-25.37-6.8-33.76 3.48-25.62 31.5-39.39 71.28-38.75 112 .59 37.58-2.47 75.27-9.11 112.05-2.34 13.05 6.31 25.53 19.36 27.89 20.11 3.5 27.07-14.81 27.89-19.36 7.19-39.84 10.5-80.66 9.86-121.33-.47-29.88 9.2-57.88 28-80.97 8.35-10.28 6.79-25.39-3.49-33.76zm109.47-62.33c-15.41-.41-30.87 1.44-45.78 4.97-12.89 3.06-20.87 15.98-17.83 28.89 3.06 12.89 16 20.83 28.89 17.83 11.05-2.61 22.47-3.77 34-3.69 75.43 1.13 137.73 61.5 138.88 134.58.59 37.88-1.28 76.11-5.58 113.63-1.5 13.17 7.95 25.08 21.11 26.58 16.72 1.95 25.51-11.88 26.58-21.11a929.06 929.06 0 0 0 5.89-119.85c-1.56-98.75-85.07-180.33-186.16-181.83zm252.07 121.45c-2.86-12.92-15.51-21.2-28.61-18.27-12.94 2.86-21.12 15.66-18.26 28.61 4.71 21.41 4.91 37.41 4.7 61.6-.11 13.27 10.55 24.09 23.8 24.2h.2c13.17 0 23.89-10.61 24-23.8.18-22.18.4-44.11-5.83-72.34zm-40.12-90.72C417.29 43.46 337.6 1.29 252.81.02 183.02-.82 118.47 24.91 70.46 72.94 24.09 119.37-.9 181.04.14 246.65l-.12 21.47c-.39 13.25 10.03 24.31 23.28 24.69.23.02.48.02.72.02 12.92 0 23.59-10.3 23.97-23.3l.16-23.64c-.83-52.5 19.16-101.86 56.28-139 38.76-38.8 91.34-59.67 147.68-58.86 69.45 1.03 134.73 35.56 174.62 92.39 7.61 10.86 22.56 13.45 33.42 5.86 10.84-7.62 13.46-22.59 5.84-33.43z\"],\n    \"history\": [512, 512, [], \"f1da\", \"M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z\"],\n    \"home\": [576, 512, [], \"f015\", \"M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z\"],\n    \"plus\": [448, 512, [], \"f067\", \"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"],\n    \"robot\": [640, 512, [], \"f544\", \"M32,224H64V416H32A31.96166,31.96166,0,0,1,0,384V256A31.96166,31.96166,0,0,1,32,224Zm512-48V448a64.06328,64.06328,0,0,1-64,64H160a64.06328,64.06328,0,0,1-64-64V176a79.974,79.974,0,0,1,80-80H288V32a32,32,0,0,1,64,0V96H464A79.974,79.974,0,0,1,544,176ZM264,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,264,256Zm-8,128H192v32h64Zm96,0H288v32h64ZM456,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,456,256Zm-8,128H384v32h64ZM640,256V384a31.96166,31.96166,0,0,1-32,32H576V224h32A31.96166,31.96166,0,0,1,640,256Z\"],\n    \"rocket\": [512, 512, [], \"f135\", \"M505.12019,19.09375c-1.18945-5.53125-6.65819-11-12.207-12.1875C460.716,0,435.507,0,410.40747,0,307.17523,0,245.26909,55.20312,199.05238,128H94.83772c-16.34763.01562-35.55658,11.875-42.88664,26.48438L2.51562,253.29688A28.4,28.4,0,0,0,0,264a24.00867,24.00867,0,0,0,24.00582,24H127.81618l-22.47457,22.46875c-11.36521,11.36133-12.99607,32.25781,0,45.25L156.24582,406.625c11.15623,11.1875,32.15619,13.15625,45.27726,0l22.47457-22.46875V488a24.00867,24.00867,0,0,0,24.00581,24,28.55934,28.55934,0,0,0,10.707-2.51562l98.72834-49.39063c14.62888-7.29687,26.50776-26.5,26.50776-42.85937V312.79688c72.59753-46.3125,128.03493-108.40626,128.03493-211.09376C512.07526,76.5,512.07526,51.29688,505.12019,19.09375ZM384.04033,168A40,40,0,1,1,424.05,128,40.02322,40.02322,0,0,1,384.04033,168Z\"],\n    \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"],\n    \"slash\": [640, 512, [], \"f715\", \"M594.53 508.63L6.18 53.9c-6.97-5.42-8.23-15.47-2.81-22.45L23.01 6.18C28.43-.8 38.49-2.06 45.47 3.37L633.82 458.1c6.97 5.42 8.23 15.47 2.81 22.45l-19.64 25.27c-5.42 6.98-15.48 8.23-22.46 2.81z\"],\n    \"spinner-third\": [512, 512, [], \"f3f4\", \"M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z\"],\n    \"square-full\": [512, 512, [], \"f45c\", \"M512 512H0V0h512v512z\"],\n    \"times\": [352, 512, [], \"f00d\", \"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\"],\n    \"times-circle\": [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"],\n    \"undo\": [512, 512, [], \"f0e2\", \"M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z\"],\n    \"undo-alt\": [512, 512, [], \"f2ea\", \"M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z\"],\n    \"user\": [448, 512, [], \"f007\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"],\n    \"users\": [640, 512, [], \"f0c0\", \"M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z\"]\n  };\n\n  bunker(function () {\n    defineIcons('fas', icons);\n  });\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-common-types/LICENSE.txt",
    "content": "Font Awesome Free License\n-------------------------\n\nFont Awesome Free is free, open source, and GPL friendly. You can use it for\ncommercial projects, open source projects, or really almost whatever you want.\nFull Font Awesome Free license: https://fontawesome.com/license/free.\n\n# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)\nIn the Font Awesome Free download, the CC BY 4.0 license applies to all icons\npackaged as SVG and JS file types.\n\n# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL)\nIn the Font Awesome Free download, the SIL OFL license applies to all icons\npackaged as web and desktop font files.\n\n# Code: MIT License (https://opensource.org/licenses/MIT)\nIn the Font Awesome Free download, the MIT license applies to all non-font and\nnon-icon files.\n\n# Attribution\nAttribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font\nAwesome Free files already contain embedded comments with sufficient\nattribution, so you shouldn't need to do anything additional when using these\nfiles normally.\n\nWe've kept attribution comments terse, so we ask that you do not actively work\nto remove them from files, especially code. They're a great way for folks to\nlearn about Font Awesome.\n\n# Brand Icons\nAll brand icons are trademarks of their respective owners. The use of these\ntrademarks does not indicate endorsement of the trademark holder by Font\nAwesome, nor vice versa. **Please do not use brand logos for any purpose except\nto represent the company, product, or service to which they refer.**\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-common-types/README.md",
    "content": "# @fortawesome/fontawesome-common-types - SVG with JavaScript\n\n> \"I came here to chew bubblegum and install Font Awesome 5 - and I'm all out of bubblegum\"\n\n[![npm](https://img.shields.io/npm/v/@fortawesome/fontawesome-common-types.svg?style=flat-square)](https://www.npmjs.com/package/@fortawesome/fontawesome-common-types)\n\n## What is this package?\n\nFont Awesome 5 JavaScript packages support TypeScript. This package abstracts out some of the common definitions that those packages use.\n\n## Here be dragons\n\nIf you are trying to import types from this package we *highly* recommend you do the following instead as *all types in this package are re-exported to the main fontawesome package*.\n\nyour.ts\n\n```\nimport {\n  IconName\n} from `@fortawesome/fontawesome-svg-core`\n\nconst myIcon: IconName = \"...\"\n```\n\n## Issues and support\n\nStart with [GitHub issues](https://github.com/FortAwesome/Font-Awesome/issues) and ping us on [Twitter](https://twitter.com/fontawesome) if you need to.\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-common-types/attribution.js",
    "content": "console.log(`Font Awesome Free 0.2.36 by @fontawesome - https://fontawesome.com\nLicense - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)\n`)"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-common-types/index.d.ts",
    "content": "export type IconPrefix = \"fas\" | \"fab\" | \"far\" | \"fal\" | \"fad\";\nexport type IconPathData = string | string[]\n\nexport interface IconLookup {\n  prefix: IconPrefix;\n  // IconName is defined in the code that will be generated at build time and bundled with this file.\n  iconName: IconName;\n}\n\nexport interface IconDefinition extends IconLookup {\n  icon: [\n    number, // width\n    number, // height\n    string[], // ligatures\n    string, // unicode\n    IconPathData // svgPathData\n  ];\n}\n\nexport interface IconPack {\n  [key: string]: IconDefinition;\n}\n\nexport type IconName = 'aws' | \n  'cc-amazon-pay' | \n  'cc-amex' | \n  'cc-apple-pay' | \n  'cc-diners-club' | \n  'cc-discover' | \n  'cc-jcb' | \n  'cc-mastercard' | \n  'cc-paypal' | \n  'cc-stripe' | \n  'cc-visa' | \n  'discourse' | \n  'docker' | \n  'github' | \n  'instagram' | \n  'microsoft' | \n  'rev' | \n  'slack' | \n  'twitter' | \n  'abacus' | \n  'align-slash' | \n  'atom-alt' | \n  'badge-check' | \n  'bell' | \n  'books' | \n  'brackets-curly' | \n  'chart-network' | \n  'chart-scatter' | \n  'check' | \n  'circle' | \n  'clouds' | \n  'cogs' | \n  'comment-dots' | \n  'concierge-bell' | \n  'dot-circle' | \n  'envelope' | \n  'exchange-alt' | \n  'file-alt' | \n  'file-code' | \n  'globe' | \n  'globe-africa' | \n  'globe-americas' | \n  'globe-asia' | \n  'globe-europe' | \n  'graduation-cap' | \n  'history' | \n  'key' | \n  'key-skeleton' | \n  'laptop' | \n  'laptop-code' | \n  'laptop-house' | \n  'life-ring' | \n  'lightbulb' | \n  'list-alt' | \n  'list-ul' | \n  'lock-alt' | \n  'map-marker-alt' | \n  'moon-stars' | \n  'network-wired' | \n  'planet-ringed' | \n  'question-circle' | \n  'quote-left' | \n  'random' | \n  'rocket' | \n  'search' | \n  'server' | \n  'sign-out' | \n  'siren-on' | \n  'smile' | \n  'snowman' | \n  'sun' | \n  'tasks' | \n  'university' | \n  'user' | \n  'user-hard-hat' | \n  'user-shield' | \n  'users' | \n  'check-circle' | \n  'desktop' | \n  'eye' | \n  'file-code' | \n  'info' | \n  'info-circle' | \n  'plus' | \n  'question-circle' | \n  'rocket' | \n  'save' | \n  'slash' | \n  'times' | \n  'undo' | \n  'undo-alt' | \n  'user' | \n  'user-friends' | \n  'users' | \n  'alarm-exclamation' | \n  'align-left' | \n  'book-dead' | \n  'check' | \n  'circle' | \n  'cloud' | \n  'credit-card' | \n  'desktop' | \n  'envelope' | \n  'eye' | \n  'fingerprint' | \n  'history' | \n  'home' | \n  'plus' | \n  'robot' | \n  'rocket' | \n  'save' | \n  'slash' | \n  'spinner-third' | \n  'square-full' | \n  'times' | \n  'times-circle' | \n  'undo' | \n  'undo-alt' | \n  'user' | \n  'users';\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-common-types/package.json",
    "content": "{\n  \"description\": \"The iconic font, CSS, and SVG framework\",\n  \"keywords\": [\n    \"font\",\n    \"awesome\",\n    \"fontawesome\",\n    \"icon\",\n    \"svg\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://fontawesome.com\",\n  \"bugs\": {\n    \"url\": \"http://github.com/FortAwesome/Font-Awesome/issues\"\n  },\n  \"author\": {\n    \"name\": \"Dave Gandy\",\n    \"email\": \"dave@fontawesome.com\",\n    \"web\": \"http://twitter.com/davegandy\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Brian Talbot\",\n      \"web\": \"http://twitter.com/talbs\"\n    },\n    {\n      \"name\": \"Travis Chase\",\n      \"web\": \"http://twitter.com/supercodepoet\"\n    },\n    {\n      \"name\": \"Rob Madole\",\n      \"web\": \"http://twitter.com/robmadole\"\n    },\n    {\n      \"name\": \"Geremia Taglialatela\",\n      \"web\": \"http://twitter.com/gtagliala\"\n    },\n    {\n      \"name\": \"Mike Wilkerson\",\n      \"web\": \"http://twitter.com/mw77\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/FortAwesome/Font-Awesome\"\n  },\n  \"engines\": {\n    \"node\": \">=6\"\n  },\n  \"dependencies\": {},\n  \"version\": \"0.2.36\",\n  \"name\": \"@fortawesome/fontawesome-common-types\",\n  \"license\": \"MIT\",\n  \"types\": \"./index.d.ts\",\n  \"scripts\": {\n    \"postinstall\": \"node attribution.js\"\n  }\n}"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/LICENSE.txt",
    "content": "Font Awesome Pro License\n------------------------\n\nFont Awesome Pro is commercial software that requires a paid license. Full\nFont Awesome Pro license: https://fontawesome.com/license.\n\n# Commercial License\nThe Font Awesome Pro commercial license allows you to pay for FA Pro once, own\nit, and use it just about everywhere you'd like.\n\n# Attribution\nAttribution is not required by the Font Awesome Pro commercial license.\n\n# Brand Icons\nAll brand icons are trademarks of their respective owners. The use of these\ntrademarks does not indicate endorsement of the trademark holder by Font\nAwesome, nor vice versa. **Please do not use brand logos for any purpose except\nto represent the company, product, or service to which they refer.**\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/attribution.js",
    "content": "console.log(`Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\nLicense - https://fontawesome.com/license (Commercial License)\n`)"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/css/all.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n.fa,\n.fas,\n.far,\n.fal,\n.fad,\n.fab {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  text-rendering: auto;\n  line-height: 1; }\n\n.fa-lg {\n  font-size: 1.33333em;\n  line-height: 0.75em;\n  vertical-align: -.0667em; }\n\n.fa-xs {\n  font-size: .75em; }\n\n.fa-sm {\n  font-size: .875em; }\n\n.fa-1x {\n  font-size: 1em; }\n\n.fa-2x {\n  font-size: 2em; }\n\n.fa-3x {\n  font-size: 3em; }\n\n.fa-4x {\n  font-size: 4em; }\n\n.fa-5x {\n  font-size: 5em; }\n\n.fa-6x {\n  font-size: 6em; }\n\n.fa-7x {\n  font-size: 7em; }\n\n.fa-8x {\n  font-size: 8em; }\n\n.fa-9x {\n  font-size: 9em; }\n\n.fa-10x {\n  font-size: 10em; }\n\n.fa-fw {\n  text-align: center;\n  width: 1.25em; }\n\n.fa-ul {\n  list-style-type: none;\n  margin-left: 2.5em;\n  padding-left: 0; }\n  .fa-ul > li {\n    position: relative; }\n\n.fa-li {\n  left: -2em;\n  position: absolute;\n  text-align: center;\n  width: 2em;\n  line-height: inherit; }\n\n.fa-border {\n  border: solid 0.08em #eee;\n  border-radius: .1em;\n  padding: .2em .25em .15em; }\n\n.fa-pull-left {\n  float: left; }\n\n.fa-pull-right {\n  float: right; }\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n  margin-right: .3em; }\n\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n  margin-left: .3em; }\n\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear; }\n\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8); }\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n.fa-rotate-90 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n  -webkit-transform: rotate(90deg);\n          transform: rotate(90deg); }\n\n.fa-rotate-180 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n  -webkit-transform: rotate(180deg);\n          transform: rotate(180deg); }\n\n.fa-rotate-270 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n  -webkit-transform: rotate(270deg);\n          transform: rotate(270deg); }\n\n.fa-flip-horizontal {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n  -webkit-transform: scale(-1, 1);\n          transform: scale(-1, 1); }\n\n.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(1, -1);\n          transform: scale(1, -1); }\n\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(-1, -1);\n          transform: scale(-1, -1); }\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical,\n:root .fa-flip-both {\n  -webkit-filter: none;\n          filter: none; }\n\n.fa-stack {\n  display: inline-block;\n  height: 2em;\n  line-height: 2em;\n  position: relative;\n  vertical-align: middle;\n  width: 2.5em; }\n\n.fa-stack-1x,\n.fa-stack-2x {\n  left: 0;\n  position: absolute;\n  text-align: center;\n  width: 100%; }\n\n.fa-stack-1x {\n  line-height: inherit; }\n\n.fa-stack-2x {\n  font-size: 2em; }\n\n.fa-inverse {\n  color: #fff; }\n\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\nreaders do not read off random characters that represent icons */\n.fa-abacus:before {\n  content: \"\\f640\"; }\n\n.fa-alarm-exclamation:before {\n  content: \"\\f843\"; }\n\n.fa-align-left:before {\n  content: \"\\f036\"; }\n\n.fa-align-slash:before {\n  content: \"\\f846\"; }\n\n.fa-atom-alt:before {\n  content: \"\\f5d3\"; }\n\n.fa-aws:before {\n  content: \"\\f375\"; }\n\n.fa-badge-check:before {\n  content: \"\\f336\"; }\n\n.fa-bell:before {\n  content: \"\\f0f3\"; }\n\n.fa-book-dead:before {\n  content: \"\\f6b7\"; }\n\n.fa-books:before {\n  content: \"\\f5db\"; }\n\n.fa-brackets-curly:before {\n  content: \"\\f7ea\"; }\n\n.fa-cc-amazon-pay:before {\n  content: \"\\f42d\"; }\n\n.fa-cc-amex:before {\n  content: \"\\f1f3\"; }\n\n.fa-cc-apple-pay:before {\n  content: \"\\f416\"; }\n\n.fa-cc-diners-club:before {\n  content: \"\\f24c\"; }\n\n.fa-cc-discover:before {\n  content: \"\\f1f2\"; }\n\n.fa-cc-jcb:before {\n  content: \"\\f24b\"; }\n\n.fa-cc-mastercard:before {\n  content: \"\\f1f1\"; }\n\n.fa-cc-paypal:before {\n  content: \"\\f1f4\"; }\n\n.fa-cc-stripe:before {\n  content: \"\\f1f5\"; }\n\n.fa-cc-visa:before {\n  content: \"\\f1f0\"; }\n\n.fa-chart-network:before {\n  content: \"\\f78a\"; }\n\n.fa-chart-scatter:before {\n  content: \"\\f7ee\"; }\n\n.fa-check:before {\n  content: \"\\f00c\"; }\n\n.fa-check-circle:before {\n  content: \"\\f058\"; }\n\n.fa-circle:before {\n  content: \"\\f111\"; }\n\n.fa-cloud:before {\n  content: \"\\f0c2\"; }\n\n.fa-clouds:before {\n  content: \"\\f744\"; }\n\n.fa-cogs:before {\n  content: \"\\f085\"; }\n\n.fa-comment-dots:before {\n  content: \"\\f4ad\"; }\n\n.fa-concierge-bell:before {\n  content: \"\\f562\"; }\n\n.fa-credit-card:before {\n  content: \"\\f09d\"; }\n\n.fa-desktop:before {\n  content: \"\\f108\"; }\n\n.fa-discourse:before {\n  content: \"\\f393\"; }\n\n.fa-docker:before {\n  content: \"\\f395\"; }\n\n.fa-dot-circle:before {\n  content: \"\\f192\"; }\n\n.fa-envelope:before {\n  content: \"\\f0e0\"; }\n\n.fa-exchange-alt:before {\n  content: \"\\f362\"; }\n\n.fa-eye:before {\n  content: \"\\f06e\"; }\n\n.fa-file-alt:before {\n  content: \"\\f15c\"; }\n\n.fa-file-code:before {\n  content: \"\\f1c9\"; }\n\n.fa-fingerprint:before {\n  content: \"\\f577\"; }\n\n.fa-github:before {\n  content: \"\\f09b\"; }\n\n.fa-globe:before {\n  content: \"\\f0ac\"; }\n\n.fa-globe-africa:before {\n  content: \"\\f57c\"; }\n\n.fa-globe-americas:before {\n  content: \"\\f57d\"; }\n\n.fa-globe-asia:before {\n  content: \"\\f57e\"; }\n\n.fa-globe-europe:before {\n  content: \"\\f7a2\"; }\n\n.fa-graduation-cap:before {\n  content: \"\\f19d\"; }\n\n.fa-history:before {\n  content: \"\\f1da\"; }\n\n.fa-home:before {\n  content: \"\\f015\"; }\n\n.fa-info:before {\n  content: \"\\f129\"; }\n\n.fa-info-circle:before {\n  content: \"\\f05a\"; }\n\n.fa-instagram:before {\n  content: \"\\f16d\"; }\n\n.fa-key:before {\n  content: \"\\f084\"; }\n\n.fa-key-skeleton:before {\n  content: \"\\f6f3\"; }\n\n.fa-laptop:before {\n  content: \"\\f109\"; }\n\n.fa-laptop-code:before {\n  content: \"\\f5fc\"; }\n\n.fa-laptop-house:before {\n  content: \"\\e066\"; }\n\n.fa-life-ring:before {\n  content: \"\\f1cd\"; }\n\n.fa-lightbulb:before {\n  content: \"\\f0eb\"; }\n\n.fa-list-alt:before {\n  content: \"\\f022\"; }\n\n.fa-list-ul:before {\n  content: \"\\f0ca\"; }\n\n.fa-lock-alt:before {\n  content: \"\\f30d\"; }\n\n.fa-map-marker-alt:before {\n  content: \"\\f3c5\"; }\n\n.fa-microsoft:before {\n  content: \"\\f3ca\"; }\n\n.fa-moon-stars:before {\n  content: \"\\f755\"; }\n\n.fa-network-wired:before {\n  content: \"\\f6ff\"; }\n\n.fa-planet-ringed:before {\n  content: \"\\e020\"; }\n\n.fa-plus:before {\n  content: \"\\f067\"; }\n\n.fa-question-circle:before {\n  content: \"\\f059\"; }\n\n.fa-quote-left:before {\n  content: \"\\f10d\"; }\n\n.fa-random:before {\n  content: \"\\f074\"; }\n\n.fa-rev:before {\n  content: \"\\f5b2\"; }\n\n.fa-robot:before {\n  content: \"\\f544\"; }\n\n.fa-rocket:before {\n  content: \"\\f135\"; }\n\n.fa-save:before {\n  content: \"\\f0c7\"; }\n\n.fa-search:before {\n  content: \"\\f002\"; }\n\n.fa-server:before {\n  content: \"\\f233\"; }\n\n.fa-sign-out:before {\n  content: \"\\f08b\"; }\n\n.fa-siren-on:before {\n  content: \"\\e02e\"; }\n\n.fa-slack:before {\n  content: \"\\f198\"; }\n\n.fa-slash:before {\n  content: \"\\f715\"; }\n\n.fa-smile:before {\n  content: \"\\f118\"; }\n\n.fa-snowman:before {\n  content: \"\\f7d0\"; }\n\n.fa-spinner-third:before {\n  content: \"\\f3f4\"; }\n\n.fa-square-full:before {\n  content: \"\\f45c\"; }\n\n.fa-sun:before {\n  content: \"\\f185\"; }\n\n.fa-tasks:before {\n  content: \"\\f0ae\"; }\n\n.fa-times:before {\n  content: \"\\f00d\"; }\n\n.fa-times-circle:before {\n  content: \"\\f057\"; }\n\n.fa-twitter:before {\n  content: \"\\f099\"; }\n\n.fa-undo:before {\n  content: \"\\f0e2\"; }\n\n.fa-undo-alt:before {\n  content: \"\\f2ea\"; }\n\n.fa-university:before {\n  content: \"\\f19c\"; }\n\n.fa-user:before {\n  content: \"\\f007\"; }\n\n.fa-user-friends:before {\n  content: \"\\f500\"; }\n\n.fa-user-hard-hat:before {\n  content: \"\\f82c\"; }\n\n.fa-user-shield:before {\n  content: \"\\f505\"; }\n\n.fa-users:before {\n  content: \"\\f0c0\"; }\n\n.sr-only {\n  border: 0;\n  clip: rect(0, 0, 0, 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px; }\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n  clip: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  position: static;\n  width: auto; }\n@font-face {\n  font-family: 'Font Awesome 5 Brands';\n  font-style: normal;\n  font-weight: 400;\n  font-display: block;\n  src: url(\"../webfonts/fa-brands-400.eot\");\n  src: url(\"../webfonts/fa-brands-400.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-brands-400.woff2\") format(\"woff2\"), url(\"../webfonts/fa-brands-400.woff\") format(\"woff\"), url(\"../webfonts/fa-brands-400.ttf\") format(\"truetype\"), url(\"../webfonts/fa-brands-400.svg#fontawesome\") format(\"svg\"); }\n\n.fab {\n  font-family: 'Font Awesome 5 Brands';\n  font-weight: 400; }\n@font-face {\n  font-family: 'Font Awesome 5 Duotone';\n  font-style: normal;\n  font-weight: 900;\n  font-display: block;\n  src: url(\"../webfonts/fa-duotone-900.eot\");\n  src: url(\"../webfonts/fa-duotone-900.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-duotone-900.woff2\") format(\"woff2\"), url(\"../webfonts/fa-duotone-900.woff\") format(\"woff\"), url(\"../webfonts/fa-duotone-900.ttf\") format(\"truetype\"), url(\"../webfonts/fa-duotone-900.svg#fontawesome\") format(\"svg\"); }\n\n.fad {\n  position: relative;\n  font-family: 'Font Awesome 5 Duotone';\n  font-weight: 900; }\n\n.fad:before {\n  position: absolute;\n  color: var(--fa-primary-color, inherit);\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.fad:after {\n  color: var(--fa-secondary-color, inherit);\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.fa-swap-opacity .fad:before,\n.fad.fa-swap-opacity:before {\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.fa-swap-opacity .fad:after,\n.fad.fa-swap-opacity:after {\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.fad.fa-inverse {\n  color: #fff; }\n\n.fad.fa-stack-1x, .fad.fa-stack-2x {\n  position: absolute; }\n\n.fad.fa-stack-1x:before,\n.fad.fa-stack-2x:before,\n.fad.fa-fw:before {\n  left: 50%;\n  -webkit-transform: translateX(-50%);\n          transform: translateX(-50%); }\n\n.fad.fa-abacus:after {\n  content: \"\\10f640\"; }\n\n.fad.fa-align-slash:after {\n  content: \"\\10f846\"; }\n\n.fad.fa-atom-alt:after {\n  content: \"\\10f5d3\"; }\n\n.fad.fa-badge-check:after {\n  content: \"\\10f336\"; }\n\n.fad.fa-bell:after {\n  content: \"\\10f0f3\"; }\n\n.fad.fa-books:after {\n  content: \"\\10f5db\"; }\n\n.fad.fa-brackets-curly:after {\n  content: \"\\10f7ea\"; }\n\n.fad.fa-chart-network:after {\n  content: \"\\10f78a\"; }\n\n.fad.fa-chart-scatter:after {\n  content: \"\\10f7ee\"; }\n\n.fad.fa-check:after {\n  content: \"\\10f00c\"; }\n\n.fad.fa-circle:after {\n  content: \"\\10f111\"; }\n\n.fad.fa-clouds:after {\n  content: \"\\10f744\"; }\n\n.fad.fa-cogs:after {\n  content: \"\\10f085\"; }\n\n.fad.fa-comment-dots:after {\n  content: \"\\10f4ad\"; }\n\n.fad.fa-concierge-bell:after {\n  content: \"\\10f562\"; }\n\n.fad.fa-dot-circle:after {\n  content: \"\\10f192\"; }\n\n.fad.fa-envelope:after {\n  content: \"\\10f0e0\"; }\n\n.fad.fa-exchange-alt:after {\n  content: \"\\10f362\"; }\n\n.fad.fa-file-alt:after {\n  content: \"\\10f15c\"; }\n\n.fad.fa-file-code:after {\n  content: \"\\10f1c9\"; }\n\n.fad.fa-globe:after {\n  content: \"\\10f0ac\"; }\n\n.fad.fa-globe-africa:after {\n  content: \"\\10f57c\"; }\n\n.fad.fa-globe-americas:after {\n  content: \"\\10f57d\"; }\n\n.fad.fa-globe-asia:after {\n  content: \"\\10f57e\"; }\n\n.fad.fa-globe-europe:after {\n  content: \"\\10f7a2\"; }\n\n.fad.fa-graduation-cap:after {\n  content: \"\\10f19d\"; }\n\n.fad.fa-history:after {\n  content: \"\\10f1da\"; }\n\n.fad.fa-key:after {\n  content: \"\\10f084\"; }\n\n.fad.fa-key-skeleton:after {\n  content: \"\\10f6f3\"; }\n\n.fad.fa-laptop:after {\n  content: \"\\10f109\"; }\n\n.fad.fa-laptop-code:after {\n  content: \"\\10f5fc\"; }\n\n.fad.fa-laptop-house:after {\n  content: \"\\10e066\"; }\n\n.fad.fa-life-ring:after {\n  content: \"\\10f1cd\"; }\n\n.fad.fa-lightbulb:after {\n  content: \"\\10f0eb\"; }\n\n.fad.fa-list-alt:after {\n  content: \"\\10f022\"; }\n\n.fad.fa-list-ul:after {\n  content: \"\\10f0ca\"; }\n\n.fad.fa-lock-alt:after {\n  content: \"\\10f30d\"; }\n\n.fad.fa-map-marker-alt:after {\n  content: \"\\10f3c5\"; }\n\n.fad.fa-moon-stars:after {\n  content: \"\\10f755\"; }\n\n.fad.fa-network-wired:after {\n  content: \"\\10f6ff\"; }\n\n.fad.fa-planet-ringed:after {\n  content: \"\\10e020\"; }\n\n.fad.fa-question-circle:after {\n  content: \"\\10f059\"; }\n\n.fad.fa-quote-left:after {\n  content: \"\\10f10d\"; }\n\n.fad.fa-random:after {\n  content: \"\\10f074\"; }\n\n.fad.fa-rocket:after {\n  content: \"\\10f135\"; }\n\n.fad.fa-search:after {\n  content: \"\\10f002\"; }\n\n.fad.fa-server:after {\n  content: \"\\10f233\"; }\n\n.fad.fa-sign-out:after {\n  content: \"\\10f08b\"; }\n\n.fad.fa-siren-on:after {\n  content: \"\\10e02e\"; }\n\n.fad.fa-smile:after {\n  content: \"\\10f118\"; }\n\n.fad.fa-snowman:after {\n  content: \"\\10f7d0\"; }\n\n.fad.fa-sun:after {\n  content: \"\\10f185\"; }\n\n.fad.fa-tasks:after {\n  content: \"\\10f0ae\"; }\n\n.fad.fa-university:after {\n  content: \"\\10f19c\"; }\n\n.fad.fa-user:after {\n  content: \"\\10f007\"; }\n\n.fad.fa-user-hard-hat:after {\n  content: \"\\10f82c\"; }\n\n.fad.fa-user-shield:after {\n  content: \"\\10f505\"; }\n\n.fad.fa-users:after {\n  content: \"\\10f0c0\"; }\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 400;\n  font-display: block;\n  src: url(\"../webfonts/fa-regular-400.eot\");\n  src: url(\"../webfonts/fa-regular-400.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-regular-400.woff2\") format(\"woff2\"), url(\"../webfonts/fa-regular-400.woff\") format(\"woff\"), url(\"../webfonts/fa-regular-400.ttf\") format(\"truetype\"), url(\"../webfonts/fa-regular-400.svg#fontawesome\") format(\"svg\"); }\n\n.far {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 400; }\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 900;\n  font-display: block;\n  src: url(\"../webfonts/fa-solid-900.eot\");\n  src: url(\"../webfonts/fa-solid-900.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-solid-900.woff2\") format(\"woff2\"), url(\"../webfonts/fa-solid-900.woff\") format(\"woff\"), url(\"../webfonts/fa-solid-900.ttf\") format(\"truetype\"), url(\"../webfonts/fa-solid-900.svg#fontawesome\") format(\"svg\"); }\n\n.fa,\n.fas {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 900; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/css/brands.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n@font-face {\n  font-family: 'Font Awesome 5 Brands';\n  font-style: normal;\n  font-weight: 400;\n  font-display: block;\n  src: url(\"../webfonts/fa-brands-400.eot\");\n  src: url(\"../webfonts/fa-brands-400.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-brands-400.woff2\") format(\"woff2\"), url(\"../webfonts/fa-brands-400.woff\") format(\"woff\"), url(\"../webfonts/fa-brands-400.ttf\") format(\"truetype\"), url(\"../webfonts/fa-brands-400.svg#fontawesome\") format(\"svg\"); }\n\n.fab {\n  font-family: 'Font Awesome 5 Brands';\n  font-weight: 400; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/css/duotone.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n@font-face {\n  font-family: 'Font Awesome 5 Duotone';\n  font-style: normal;\n  font-weight: 900;\n  font-display: block;\n  src: url(\"../webfonts/fa-duotone-900.eot\");\n  src: url(\"../webfonts/fa-duotone-900.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-duotone-900.woff2\") format(\"woff2\"), url(\"../webfonts/fa-duotone-900.woff\") format(\"woff\"), url(\"../webfonts/fa-duotone-900.ttf\") format(\"truetype\"), url(\"../webfonts/fa-duotone-900.svg#fontawesome\") format(\"svg\"); }\n\n.fad {\n  position: relative;\n  font-family: 'Font Awesome 5 Duotone';\n  font-weight: 900; }\n\n.fad:before {\n  position: absolute;\n  color: var(--fa-primary-color, inherit);\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.fad:after {\n  color: var(--fa-secondary-color, inherit);\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.fa-swap-opacity .fad:before,\n.fad.fa-swap-opacity:before {\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.fa-swap-opacity .fad:after,\n.fad.fa-swap-opacity:after {\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.fad.fa-inverse {\n  color: #fff; }\n\n.fad.fa-stack-1x, .fad.fa-stack-2x {\n  position: absolute; }\n\n.fad.fa-stack-1x:before,\n.fad.fa-stack-2x:before,\n.fad.fa-fw:before {\n  left: 50%;\n  -webkit-transform: translateX(-50%);\n          transform: translateX(-50%); }\n\n.fad.fa-abacus:after {\n  content: \"\\10f640\"; }\n\n.fad.fa-align-slash:after {\n  content: \"\\10f846\"; }\n\n.fad.fa-atom-alt:after {\n  content: \"\\10f5d3\"; }\n\n.fad.fa-badge-check:after {\n  content: \"\\10f336\"; }\n\n.fad.fa-bell:after {\n  content: \"\\10f0f3\"; }\n\n.fad.fa-books:after {\n  content: \"\\10f5db\"; }\n\n.fad.fa-brackets-curly:after {\n  content: \"\\10f7ea\"; }\n\n.fad.fa-chart-network:after {\n  content: \"\\10f78a\"; }\n\n.fad.fa-chart-scatter:after {\n  content: \"\\10f7ee\"; }\n\n.fad.fa-check:after {\n  content: \"\\10f00c\"; }\n\n.fad.fa-circle:after {\n  content: \"\\10f111\"; }\n\n.fad.fa-clouds:after {\n  content: \"\\10f744\"; }\n\n.fad.fa-cogs:after {\n  content: \"\\10f085\"; }\n\n.fad.fa-comment-dots:after {\n  content: \"\\10f4ad\"; }\n\n.fad.fa-concierge-bell:after {\n  content: \"\\10f562\"; }\n\n.fad.fa-dot-circle:after {\n  content: \"\\10f192\"; }\n\n.fad.fa-envelope:after {\n  content: \"\\10f0e0\"; }\n\n.fad.fa-exchange-alt:after {\n  content: \"\\10f362\"; }\n\n.fad.fa-file-alt:after {\n  content: \"\\10f15c\"; }\n\n.fad.fa-file-code:after {\n  content: \"\\10f1c9\"; }\n\n.fad.fa-globe:after {\n  content: \"\\10f0ac\"; }\n\n.fad.fa-globe-africa:after {\n  content: \"\\10f57c\"; }\n\n.fad.fa-globe-americas:after {\n  content: \"\\10f57d\"; }\n\n.fad.fa-globe-asia:after {\n  content: \"\\10f57e\"; }\n\n.fad.fa-globe-europe:after {\n  content: \"\\10f7a2\"; }\n\n.fad.fa-graduation-cap:after {\n  content: \"\\10f19d\"; }\n\n.fad.fa-history:after {\n  content: \"\\10f1da\"; }\n\n.fad.fa-key:after {\n  content: \"\\10f084\"; }\n\n.fad.fa-key-skeleton:after {\n  content: \"\\10f6f3\"; }\n\n.fad.fa-laptop:after {\n  content: \"\\10f109\"; }\n\n.fad.fa-laptop-code:after {\n  content: \"\\10f5fc\"; }\n\n.fad.fa-laptop-house:after {\n  content: \"\\10e066\"; }\n\n.fad.fa-life-ring:after {\n  content: \"\\10f1cd\"; }\n\n.fad.fa-lightbulb:after {\n  content: \"\\10f0eb\"; }\n\n.fad.fa-list-alt:after {\n  content: \"\\10f022\"; }\n\n.fad.fa-list-ul:after {\n  content: \"\\10f0ca\"; }\n\n.fad.fa-lock-alt:after {\n  content: \"\\10f30d\"; }\n\n.fad.fa-map-marker-alt:after {\n  content: \"\\10f3c5\"; }\n\n.fad.fa-moon-stars:after {\n  content: \"\\10f755\"; }\n\n.fad.fa-network-wired:after {\n  content: \"\\10f6ff\"; }\n\n.fad.fa-planet-ringed:after {\n  content: \"\\10e020\"; }\n\n.fad.fa-question-circle:after {\n  content: \"\\10f059\"; }\n\n.fad.fa-quote-left:after {\n  content: \"\\10f10d\"; }\n\n.fad.fa-random:after {\n  content: \"\\10f074\"; }\n\n.fad.fa-rocket:after {\n  content: \"\\10f135\"; }\n\n.fad.fa-search:after {\n  content: \"\\10f002\"; }\n\n.fad.fa-server:after {\n  content: \"\\10f233\"; }\n\n.fad.fa-sign-out:after {\n  content: \"\\10f08b\"; }\n\n.fad.fa-siren-on:after {\n  content: \"\\10e02e\"; }\n\n.fad.fa-smile:after {\n  content: \"\\10f118\"; }\n\n.fad.fa-snowman:after {\n  content: \"\\10f7d0\"; }\n\n.fad.fa-sun:after {\n  content: \"\\10f185\"; }\n\n.fad.fa-tasks:after {\n  content: \"\\10f0ae\"; }\n\n.fad.fa-university:after {\n  content: \"\\10f19c\"; }\n\n.fad.fa-user:after {\n  content: \"\\10f007\"; }\n\n.fad.fa-user-hard-hat:after {\n  content: \"\\10f82c\"; }\n\n.fad.fa-user-shield:after {\n  content: \"\\10f505\"; }\n\n.fad.fa-users:after {\n  content: \"\\10f0c0\"; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/css/fontawesome.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n.fa,\n.fas,\n.far,\n.fal,\n.fad,\n.fab {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  text-rendering: auto;\n  line-height: 1; }\n\n.fa-lg {\n  font-size: 1.33333em;\n  line-height: 0.75em;\n  vertical-align: -.0667em; }\n\n.fa-xs {\n  font-size: .75em; }\n\n.fa-sm {\n  font-size: .875em; }\n\n.fa-1x {\n  font-size: 1em; }\n\n.fa-2x {\n  font-size: 2em; }\n\n.fa-3x {\n  font-size: 3em; }\n\n.fa-4x {\n  font-size: 4em; }\n\n.fa-5x {\n  font-size: 5em; }\n\n.fa-6x {\n  font-size: 6em; }\n\n.fa-7x {\n  font-size: 7em; }\n\n.fa-8x {\n  font-size: 8em; }\n\n.fa-9x {\n  font-size: 9em; }\n\n.fa-10x {\n  font-size: 10em; }\n\n.fa-fw {\n  text-align: center;\n  width: 1.25em; }\n\n.fa-ul {\n  list-style-type: none;\n  margin-left: 2.5em;\n  padding-left: 0; }\n  .fa-ul > li {\n    position: relative; }\n\n.fa-li {\n  left: -2em;\n  position: absolute;\n  text-align: center;\n  width: 2em;\n  line-height: inherit; }\n\n.fa-border {\n  border: solid 0.08em #eee;\n  border-radius: .1em;\n  padding: .2em .25em .15em; }\n\n.fa-pull-left {\n  float: left; }\n\n.fa-pull-right {\n  float: right; }\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n  margin-right: .3em; }\n\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n  margin-left: .3em; }\n\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear; }\n\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8); }\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n.fa-rotate-90 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n  -webkit-transform: rotate(90deg);\n          transform: rotate(90deg); }\n\n.fa-rotate-180 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n  -webkit-transform: rotate(180deg);\n          transform: rotate(180deg); }\n\n.fa-rotate-270 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n  -webkit-transform: rotate(270deg);\n          transform: rotate(270deg); }\n\n.fa-flip-horizontal {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n  -webkit-transform: scale(-1, 1);\n          transform: scale(-1, 1); }\n\n.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(1, -1);\n          transform: scale(1, -1); }\n\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(-1, -1);\n          transform: scale(-1, -1); }\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical,\n:root .fa-flip-both {\n  -webkit-filter: none;\n          filter: none; }\n\n.fa-stack {\n  display: inline-block;\n  height: 2em;\n  line-height: 2em;\n  position: relative;\n  vertical-align: middle;\n  width: 2.5em; }\n\n.fa-stack-1x,\n.fa-stack-2x {\n  left: 0;\n  position: absolute;\n  text-align: center;\n  width: 100%; }\n\n.fa-stack-1x {\n  line-height: inherit; }\n\n.fa-stack-2x {\n  font-size: 2em; }\n\n.fa-inverse {\n  color: #fff; }\n\n/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\nreaders do not read off random characters that represent icons */\n.fa-abacus:before {\n  content: \"\\f640\"; }\n\n.fa-alarm-exclamation:before {\n  content: \"\\f843\"; }\n\n.fa-align-left:before {\n  content: \"\\f036\"; }\n\n.fa-align-slash:before {\n  content: \"\\f846\"; }\n\n.fa-atom-alt:before {\n  content: \"\\f5d3\"; }\n\n.fa-aws:before {\n  content: \"\\f375\"; }\n\n.fa-badge-check:before {\n  content: \"\\f336\"; }\n\n.fa-bell:before {\n  content: \"\\f0f3\"; }\n\n.fa-book-dead:before {\n  content: \"\\f6b7\"; }\n\n.fa-books:before {\n  content: \"\\f5db\"; }\n\n.fa-brackets-curly:before {\n  content: \"\\f7ea\"; }\n\n.fa-cc-amazon-pay:before {\n  content: \"\\f42d\"; }\n\n.fa-cc-amex:before {\n  content: \"\\f1f3\"; }\n\n.fa-cc-apple-pay:before {\n  content: \"\\f416\"; }\n\n.fa-cc-diners-club:before {\n  content: \"\\f24c\"; }\n\n.fa-cc-discover:before {\n  content: \"\\f1f2\"; }\n\n.fa-cc-jcb:before {\n  content: \"\\f24b\"; }\n\n.fa-cc-mastercard:before {\n  content: \"\\f1f1\"; }\n\n.fa-cc-paypal:before {\n  content: \"\\f1f4\"; }\n\n.fa-cc-stripe:before {\n  content: \"\\f1f5\"; }\n\n.fa-cc-visa:before {\n  content: \"\\f1f0\"; }\n\n.fa-chart-network:before {\n  content: \"\\f78a\"; }\n\n.fa-chart-scatter:before {\n  content: \"\\f7ee\"; }\n\n.fa-check:before {\n  content: \"\\f00c\"; }\n\n.fa-check-circle:before {\n  content: \"\\f058\"; }\n\n.fa-circle:before {\n  content: \"\\f111\"; }\n\n.fa-cloud:before {\n  content: \"\\f0c2\"; }\n\n.fa-clouds:before {\n  content: \"\\f744\"; }\n\n.fa-cogs:before {\n  content: \"\\f085\"; }\n\n.fa-comment-dots:before {\n  content: \"\\f4ad\"; }\n\n.fa-concierge-bell:before {\n  content: \"\\f562\"; }\n\n.fa-credit-card:before {\n  content: \"\\f09d\"; }\n\n.fa-desktop:before {\n  content: \"\\f108\"; }\n\n.fa-discourse:before {\n  content: \"\\f393\"; }\n\n.fa-docker:before {\n  content: \"\\f395\"; }\n\n.fa-dot-circle:before {\n  content: \"\\f192\"; }\n\n.fa-envelope:before {\n  content: \"\\f0e0\"; }\n\n.fa-exchange-alt:before {\n  content: \"\\f362\"; }\n\n.fa-eye:before {\n  content: \"\\f06e\"; }\n\n.fa-file-alt:before {\n  content: \"\\f15c\"; }\n\n.fa-file-code:before {\n  content: \"\\f1c9\"; }\n\n.fa-fingerprint:before {\n  content: \"\\f577\"; }\n\n.fa-github:before {\n  content: \"\\f09b\"; }\n\n.fa-globe:before {\n  content: \"\\f0ac\"; }\n\n.fa-globe-africa:before {\n  content: \"\\f57c\"; }\n\n.fa-globe-americas:before {\n  content: \"\\f57d\"; }\n\n.fa-globe-asia:before {\n  content: \"\\f57e\"; }\n\n.fa-globe-europe:before {\n  content: \"\\f7a2\"; }\n\n.fa-graduation-cap:before {\n  content: \"\\f19d\"; }\n\n.fa-history:before {\n  content: \"\\f1da\"; }\n\n.fa-home:before {\n  content: \"\\f015\"; }\n\n.fa-info:before {\n  content: \"\\f129\"; }\n\n.fa-info-circle:before {\n  content: \"\\f05a\"; }\n\n.fa-instagram:before {\n  content: \"\\f16d\"; }\n\n.fa-key:before {\n  content: \"\\f084\"; }\n\n.fa-key-skeleton:before {\n  content: \"\\f6f3\"; }\n\n.fa-laptop:before {\n  content: \"\\f109\"; }\n\n.fa-laptop-code:before {\n  content: \"\\f5fc\"; }\n\n.fa-laptop-house:before {\n  content: \"\\e066\"; }\n\n.fa-life-ring:before {\n  content: \"\\f1cd\"; }\n\n.fa-lightbulb:before {\n  content: \"\\f0eb\"; }\n\n.fa-list-alt:before {\n  content: \"\\f022\"; }\n\n.fa-list-ul:before {\n  content: \"\\f0ca\"; }\n\n.fa-lock-alt:before {\n  content: \"\\f30d\"; }\n\n.fa-map-marker-alt:before {\n  content: \"\\f3c5\"; }\n\n.fa-microsoft:before {\n  content: \"\\f3ca\"; }\n\n.fa-moon-stars:before {\n  content: \"\\f755\"; }\n\n.fa-network-wired:before {\n  content: \"\\f6ff\"; }\n\n.fa-planet-ringed:before {\n  content: \"\\e020\"; }\n\n.fa-plus:before {\n  content: \"\\f067\"; }\n\n.fa-question-circle:before {\n  content: \"\\f059\"; }\n\n.fa-quote-left:before {\n  content: \"\\f10d\"; }\n\n.fa-random:before {\n  content: \"\\f074\"; }\n\n.fa-rev:before {\n  content: \"\\f5b2\"; }\n\n.fa-robot:before {\n  content: \"\\f544\"; }\n\n.fa-rocket:before {\n  content: \"\\f135\"; }\n\n.fa-save:before {\n  content: \"\\f0c7\"; }\n\n.fa-search:before {\n  content: \"\\f002\"; }\n\n.fa-server:before {\n  content: \"\\f233\"; }\n\n.fa-sign-out:before {\n  content: \"\\f08b\"; }\n\n.fa-siren-on:before {\n  content: \"\\e02e\"; }\n\n.fa-slack:before {\n  content: \"\\f198\"; }\n\n.fa-slash:before {\n  content: \"\\f715\"; }\n\n.fa-smile:before {\n  content: \"\\f118\"; }\n\n.fa-snowman:before {\n  content: \"\\f7d0\"; }\n\n.fa-spinner-third:before {\n  content: \"\\f3f4\"; }\n\n.fa-square-full:before {\n  content: \"\\f45c\"; }\n\n.fa-sun:before {\n  content: \"\\f185\"; }\n\n.fa-tasks:before {\n  content: \"\\f0ae\"; }\n\n.fa-times:before {\n  content: \"\\f00d\"; }\n\n.fa-times-circle:before {\n  content: \"\\f057\"; }\n\n.fa-twitter:before {\n  content: \"\\f099\"; }\n\n.fa-undo:before {\n  content: \"\\f0e2\"; }\n\n.fa-undo-alt:before {\n  content: \"\\f2ea\"; }\n\n.fa-university:before {\n  content: \"\\f19c\"; }\n\n.fa-user:before {\n  content: \"\\f007\"; }\n\n.fa-user-friends:before {\n  content: \"\\f500\"; }\n\n.fa-user-hard-hat:before {\n  content: \"\\f82c\"; }\n\n.fa-user-shield:before {\n  content: \"\\f505\"; }\n\n.fa-users:before {\n  content: \"\\f0c0\"; }\n\n.sr-only {\n  border: 0;\n  clip: rect(0, 0, 0, 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px; }\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n  clip: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  position: static;\n  width: auto; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/css/regular.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 400;\n  font-display: block;\n  src: url(\"../webfonts/fa-regular-400.eot\");\n  src: url(\"../webfonts/fa-regular-400.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-regular-400.woff2\") format(\"woff2\"), url(\"../webfonts/fa-regular-400.woff\") format(\"woff\"), url(\"../webfonts/fa-regular-400.ttf\") format(\"truetype\"), url(\"../webfonts/fa-regular-400.svg#fontawesome\") format(\"svg\"); }\n\n.far {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 400; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/css/solid.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 900;\n  font-display: block;\n  src: url(\"../webfonts/fa-solid-900.eot\");\n  src: url(\"../webfonts/fa-solid-900.eot?#iefix\") format(\"embedded-opentype\"), url(\"../webfonts/fa-solid-900.woff2\") format(\"woff2\"), url(\"../webfonts/fa-solid-900.woff\") format(\"woff\"), url(\"../webfonts/fa-solid-900.ttf\") format(\"truetype\"), url(\"../webfonts/fa-solid-900.svg#fontawesome\") format(\"svg\"); }\n\n.fa,\n.fas {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 900; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/css/svg-with-js.css",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\nsvg:not(:root).svg-inline--fa {\n  overflow: visible; }\n\n.svg-inline--fa {\n  display: inline-block;\n  font-size: inherit;\n  height: 1em;\n  overflow: visible;\n  vertical-align: -.125em; }\n  .svg-inline--fa.fa-lg {\n    vertical-align: -.225em; }\n  .svg-inline--fa.fa-w-1 {\n    width: 0.0625em; }\n  .svg-inline--fa.fa-w-2 {\n    width: 0.125em; }\n  .svg-inline--fa.fa-w-3 {\n    width: 0.1875em; }\n  .svg-inline--fa.fa-w-4 {\n    width: 0.25em; }\n  .svg-inline--fa.fa-w-5 {\n    width: 0.3125em; }\n  .svg-inline--fa.fa-w-6 {\n    width: 0.375em; }\n  .svg-inline--fa.fa-w-7 {\n    width: 0.4375em; }\n  .svg-inline--fa.fa-w-8 {\n    width: 0.5em; }\n  .svg-inline--fa.fa-w-9 {\n    width: 0.5625em; }\n  .svg-inline--fa.fa-w-10 {\n    width: 0.625em; }\n  .svg-inline--fa.fa-w-11 {\n    width: 0.6875em; }\n  .svg-inline--fa.fa-w-12 {\n    width: 0.75em; }\n  .svg-inline--fa.fa-w-13 {\n    width: 0.8125em; }\n  .svg-inline--fa.fa-w-14 {\n    width: 0.875em; }\n  .svg-inline--fa.fa-w-15 {\n    width: 0.9375em; }\n  .svg-inline--fa.fa-w-16 {\n    width: 1em; }\n  .svg-inline--fa.fa-w-17 {\n    width: 1.0625em; }\n  .svg-inline--fa.fa-w-18 {\n    width: 1.125em; }\n  .svg-inline--fa.fa-w-19 {\n    width: 1.1875em; }\n  .svg-inline--fa.fa-w-20 {\n    width: 1.25em; }\n  .svg-inline--fa.fa-pull-left {\n    margin-right: .3em;\n    width: auto; }\n  .svg-inline--fa.fa-pull-right {\n    margin-left: .3em;\n    width: auto; }\n  .svg-inline--fa.fa-border {\n    height: 1.5em; }\n  .svg-inline--fa.fa-li {\n    width: 2em; }\n  .svg-inline--fa.fa-fw {\n    width: 1.25em; }\n\n.fa-layers svg.svg-inline--fa {\n  bottom: 0;\n  left: 0;\n  margin: auto;\n  position: absolute;\n  right: 0;\n  top: 0; }\n\n.fa-layers {\n  display: inline-block;\n  height: 1em;\n  position: relative;\n  text-align: center;\n  vertical-align: -.125em;\n  width: 1em; }\n  .fa-layers svg.svg-inline--fa {\n    -webkit-transform-origin: center center;\n            transform-origin: center center; }\n\n.fa-layers-text, .fa-layers-counter {\n  display: inline-block;\n  position: absolute;\n  text-align: center; }\n\n.fa-layers-text {\n  left: 50%;\n  top: 50%;\n  -webkit-transform: translate(-50%, -50%);\n          transform: translate(-50%, -50%);\n  -webkit-transform-origin: center center;\n          transform-origin: center center; }\n\n.fa-layers-counter {\n  background-color: #ff253a;\n  border-radius: 1em;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  color: #fff;\n  height: 1.5em;\n  line-height: 1;\n  max-width: 5em;\n  min-width: 1.5em;\n  overflow: hidden;\n  padding: .25em;\n  right: 0;\n  text-overflow: ellipsis;\n  top: 0;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: top right;\n          transform-origin: top right; }\n\n.fa-layers-bottom-right {\n  bottom: 0;\n  right: 0;\n  top: auto;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: bottom right;\n          transform-origin: bottom right; }\n\n.fa-layers-bottom-left {\n  bottom: 0;\n  left: 0;\n  right: auto;\n  top: auto;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: bottom left;\n          transform-origin: bottom left; }\n\n.fa-layers-top-right {\n  right: 0;\n  top: 0;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: top right;\n          transform-origin: top right; }\n\n.fa-layers-top-left {\n  left: 0;\n  right: auto;\n  top: 0;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: top left;\n          transform-origin: top left; }\n\n.fa-lg {\n  font-size: 1.33333em;\n  line-height: 0.75em;\n  vertical-align: -.0667em; }\n\n.fa-xs {\n  font-size: .75em; }\n\n.fa-sm {\n  font-size: .875em; }\n\n.fa-1x {\n  font-size: 1em; }\n\n.fa-2x {\n  font-size: 2em; }\n\n.fa-3x {\n  font-size: 3em; }\n\n.fa-4x {\n  font-size: 4em; }\n\n.fa-5x {\n  font-size: 5em; }\n\n.fa-6x {\n  font-size: 6em; }\n\n.fa-7x {\n  font-size: 7em; }\n\n.fa-8x {\n  font-size: 8em; }\n\n.fa-9x {\n  font-size: 9em; }\n\n.fa-10x {\n  font-size: 10em; }\n\n.fa-fw {\n  text-align: center;\n  width: 1.25em; }\n\n.fa-ul {\n  list-style-type: none;\n  margin-left: 2.5em;\n  padding-left: 0; }\n  .fa-ul > li {\n    position: relative; }\n\n.fa-li {\n  left: -2em;\n  position: absolute;\n  text-align: center;\n  width: 2em;\n  line-height: inherit; }\n\n.fa-border {\n  border: solid 0.08em #eee;\n  border-radius: .1em;\n  padding: .2em .25em .15em; }\n\n.fa-pull-left {\n  float: left; }\n\n.fa-pull-right {\n  float: right; }\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n  margin-right: .3em; }\n\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n  margin-left: .3em; }\n\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear; }\n\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8); }\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n.fa-rotate-90 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n  -webkit-transform: rotate(90deg);\n          transform: rotate(90deg); }\n\n.fa-rotate-180 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n  -webkit-transform: rotate(180deg);\n          transform: rotate(180deg); }\n\n.fa-rotate-270 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n  -webkit-transform: rotate(270deg);\n          transform: rotate(270deg); }\n\n.fa-flip-horizontal {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n  -webkit-transform: scale(-1, 1);\n          transform: scale(-1, 1); }\n\n.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(1, -1);\n          transform: scale(1, -1); }\n\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(-1, -1);\n          transform: scale(-1, -1); }\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical,\n:root .fa-flip-both {\n  -webkit-filter: none;\n          filter: none; }\n\n.fa-stack {\n  display: inline-block;\n  height: 2em;\n  position: relative;\n  width: 2.5em; }\n\n.fa-stack-1x,\n.fa-stack-2x {\n  bottom: 0;\n  left: 0;\n  margin: auto;\n  position: absolute;\n  right: 0;\n  top: 0; }\n\n.svg-inline--fa.fa-stack-1x {\n  height: 1em;\n  width: 1.25em; }\n\n.svg-inline--fa.fa-stack-2x {\n  height: 2em;\n  width: 2.5em; }\n\n.fa-inverse {\n  color: #fff; }\n\n.sr-only {\n  border: 0;\n  clip: rect(0, 0, 0, 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px; }\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n  clip: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  position: static;\n  width: auto; }\n\n.svg-inline--fa .fa-primary {\n  fill: var(--fa-primary-color, currentColor);\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.svg-inline--fa .fa-secondary {\n  fill: var(--fa-secondary-color, currentColor);\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.svg-inline--fa.fa-swap-opacity .fa-primary {\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.svg-inline--fa mask .fa-primary,\n.svg-inline--fa mask .fa-secondary {\n  fill: black; }\n\n.fad.fa-inverse {\n  color: #fff; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/js/all.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"aws\": [640, 512, [], \"f375\", \"M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z\"],\n    \"cc-amazon-pay\": [576, 512, [], \"f42d\", \"M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z\"],\n    \"cc-amex\": [576, 512, [], \"f1f3\", \"M325.1 167.8c0-16.4-14.1-18.4-27.4-18.4l-39.1-.3v69.3H275v-25.1h18c18.4 0 14.5 10.3 14.8 25.1h16.6v-13.5c0-9.2-1.5-15.1-11-18.4 7.4-3 11.8-10.7 11.7-18.7zm-29.4 11.3H275v-15.3h21c5.1 0 10.7 1 10.7 7.4 0 6.6-5.3 7.9-11 7.9zM279 268.6h-52.7l-21 22.8-20.5-22.8h-66.5l-.1 69.3h65.4l21.3-23 20.4 23h32.2l.1-23.3c18.9 0 49.3 4.6 49.3-23.3 0-17.3-12.3-22.7-27.9-22.7zm-103.8 54.7h-40.6v-13.8h36.3v-14.1h-36.3v-12.5h41.7l17.9 20.2zm65.8 8.2l-25.3-28.1L241 276zm37.8-31h-21.2v-17.6h21.5c5.6 0 10.2 2.3 10.2 8.4 0 6.4-4.6 9.2-10.5 9.2zm-31.6-136.7v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5zM576 255.4h-.2zm-194.6 31.9c0-16.4-14.1-18.7-27.1-18.7h-39.4l-.1 69.3h16.6l.1-25.3h17.6c11 0 14.8 2 14.8 13.8l-.1 11.5h16.6l.1-13.8c0-8.9-1.8-15.1-11-18.4 7.7-3.1 11.8-10.8 11.9-18.4zm-29.2 11.2h-20.7v-15.6h21c5.1 0 10.7 1 10.7 7.4 0 6.9-5.4 8.2-11 8.2zm-172.8-80v-69.3h-27.6l-19.7 47-21.7-47H83.3v65.7l-28.1-65.7H30.7L1 218.5h17.9l6.4-15.3h34.5l6.4 15.3H100v-54.2l24 54.2h14.6l24-54.2v54.2zM31.2 188.8l11.2-27.6 11.5 27.6zm477.4 158.9v-4.5c-10.8 5.6-3.9 4.5-156.7 4.5 0-25.2.1-23.9 0-25.2-1.7-.1-3.2-.1-9.4-.1 0 17.9-.1 6.8-.1 25.3h-39.6c0-12.1.1-15.3.1-29.2-10 6-22.8 6.4-34.3 6.2 0 14.7-.1 8.3-.1 23h-48.9c-5.1-5.7-2.7-3.1-15.4-17.4-3.2 3.5-12.8 13.9-16.1 17.4h-82v-92.3h83.1c5 5.6 2.8 3.1 15.5 17.2 3.2-3.5 12.2-13.4 15.7-17.2h58c9.8 0 18 1.9 24.3 5.6v-5.6c54.3 0 64.3-1.4 75.7 5.1v-5.1h78.2v5.2c11.4-6.9 19.6-5.2 64.9-5.2v5c10.3-5.9 16.6-5.2 54.3-5V80c0-26.5-21.5-48-48-48h-480c-26.5 0-48 21.5-48 48v109.8c9.4-21.9 19.7-46 23.1-53.9h39.7c4.3 10.1 1.6 3.7 9 21.1v-21.1h46c2.9 6.2 11.1 24 13.9 30 5.8-13.6 10.1-23.9 12.6-30h103c0-.1 11.5 0 11.6 0 43.7.2 53.6-.8 64.4 5.3v-5.3H363v9.3c7.6-6.1 17.9-9.3 30.7-9.3h27.6c0 .5 1.9.3 2.3.3H456c4.2 9.8 2.6 6 8.8 20.6v-20.6h43.3c4.9 8-1-1.8 11.2 18.4v-18.4h39.9v92h-41.6c-5.4-9-1.4-2.2-13.2-21.9v21.9h-52.8c-6.4-14.8-.1-.3-6.6-15.3h-19c-4.2 10-2.2 5.2-6.4 15.3h-26.8c-12.3 0-22.3-3-29.7-8.9v8.9h-66.5c-.3-13.9-.1-24.8-.1-24.8-1.8-.3-3.4-.2-9.8-.2v25.1H151.2v-11.4c-2.5 5.6-2.7 5.9-5.1 11.4h-29.5c-4-8.9-2.9-6.4-5.1-11.4v11.4H58.6c-4.2-10.1-2.2-5.3-6.4-15.3H33c-4.2 10-2.2 5.2-6.4 15.3H0V432c0 26.5 21.5 48 48 48h480.1c26.5 0 48-21.5 48-48v-90.4c-12.7 8.3-32.7 6.1-67.5 6.1zm36.3-64.5H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-57 39.8h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-42.2-40.1v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5zm-56.3-108.1c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm20.4-10.5h-.1zm-16.2-15.2c-23.5 0-34 12-34 35.3 0 22.2 10.2 34 33 34h19.2l6.4-15.3h34.3l6.6 15.3h33.7v-51.9l31.2 51.9h23.6v-69h-16.9v48.1l-29.1-48.1h-25.3v65.4l-27.9-65.4h-24.8l-23.5 54.5h-7.4c-13.3 0-16.1-8.1-16.1-19.9 0-23.8 15.7-20 33.1-19.7v-15.2zm42.1 12.1l11.2 27.6h-22.8zm-101.1-12v69.3h16.9v-69.3z\"],\n    \"cc-apple-pay\": [576, 512, [], \"f416\", \"M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z\"],\n    \"cc-diners-club\": [576, 512, [], \"f24c\", \"M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z\"],\n    \"cc-discover\": [576, 512, [], \"f1f2\", \"M520.4 196.1c0-7.9-5.5-12.1-15.6-12.1h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-44.1 138.9c22.6 0 52.9-4.1 52.9 24.4 0 12.6-6.6 20.7-18.7 23.2l25.8 34.4h-19.6l-22.2-32.8h-2.2v32.8h-16zm-55.9.1h45.3v14H444v18.2h28.3V217H444v22.2h29.3V253H428zm-68.7 0l21.9 55.2 22.2-55.2h17.5l-35.5 84.2h-8.6l-35-84.2zm-55.9-3c24.7 0 44.6 20 44.6 44.6 0 24.7-20 44.6-44.6 44.6-24.7 0-44.6-20-44.6-44.6 0-24.7 20-44.6 44.6-44.6zm-49.3 6.1v19c-20.1-20.1-46.8-4.7-46.8 19 0 25 27.5 38.5 46.8 19.2v19c-29.7 14.3-63.3-5.7-63.3-38.2 0-31.2 33.1-53 63.3-38zm-97.2 66.3c11.4 0 22.4-15.3-3.3-24.4-15-5.5-20.2-11.4-20.2-22.7 0-23.2 30.6-31.4 49.7-14.3l-8.4 10.8c-10.4-11.6-24.9-6.2-24.9 2.5 0 4.4 2.7 6.9 12.3 10.3 18.2 6.6 23.6 12.5 23.6 25.6 0 29.5-38.8 37.4-56.6 11.3l10.3-9.9c3.7 7.1 9.9 10.8 17.5 10.8zM55.4 253H32v-82h23.4c26.1 0 44.1 17 44.1 41.1 0 18.5-13.2 40.9-44.1 40.9zm67.5 0h-16v-82h16zM544 433c0 8.2-6.8 15-15 15H128c189.6-35.6 382.7-139.2 416-160zM74.1 191.6c-5.2-4.9-11.6-6.6-21.9-6.6H48v54.2h4.2c10.3 0 17-2 21.9-6.4 5.7-5.2 8.9-12.8 8.9-20.7s-3.2-15.5-8.9-20.5z\"],\n    \"cc-jcb\": [576, 512, [], \"f24b\", \"M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z\"],\n    \"cc-mastercard\": [576, 512, [], \"f1f1\", \"M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z\"],\n    \"cc-paypal\": [576, 512, [], \"f1f4\", \"M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z\"],\n    \"cc-stripe\": [576, 512, [], \"f1f5\", \"M492.4 220.8c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7zM375 223.4c-8.2 0-13.3 2.9-17 7l.2 52.8c3.5 3.7 8.5 6.7 16.8 6.7 13.1 0 21.9-14.3 21.9-33.4 0-18.6-9-33.2-21.9-33.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM122.2 281.1c0 25.6-20.3 40.1-49.9 40.3-12.2 0-25.6-2.4-38.8-8.1v-33.9c12 6.4 27.1 11.3 38.9 11.3 7.9 0 13.6-2.1 13.6-8.7 0-17-54-10.6-54-49.9 0-25.2 19.2-40.2 48-40.2 11.8 0 23.5 1.8 35.3 6.5v33.4c-10.8-5.8-24.5-9.1-35.3-9.1-7.5 0-12.1 2.2-12.1 7.7 0 16 54.3 8.4 54.3 50.7zm68.8-56.6h-27V275c0 20.9 22.5 14.4 27 12.6v28.9c-4.7 2.6-13.3 4.7-24.9 4.7-21.1 0-36.9-15.5-36.9-36.5l.2-113.9 34.7-7.4v30.8H191zm74 2.4c-4.5-1.5-18.7-3.6-27.1 7.4v84.4h-35.5V194.2h30.7l2.2 10.5c8.3-15.3 24.9-12.2 29.6-10.5h.1zm44.1 91.8h-35.7V194.2h35.7zm0-142.9l-35.7 7.6v-28.9l35.7-7.6zm74.1 145.5c-12.4 0-20-5.3-25.1-9l-.1 40.2-35.5 7.5V194.2h31.3l1.8 8.8c4.9-4.5 13.9-11.1 27.8-11.1 24.9 0 48.4 22.5 48.4 63.8 0 45.1-23.2 65.5-48.6 65.6zm160.4-51.5h-69.5c1.6 16.6 13.8 21.5 27.6 21.5 14.1 0 25.2-3 34.9-7.9V312c-9.7 5.3-22.4 9.2-39.4 9.2-34.6 0-58.8-21.7-58.8-64.5 0-36.2 20.5-64.9 54.3-64.9 33.7 0 51.3 28.7 51.3 65.1 0 3.5-.3 10.9-.4 12.9z\"],\n    \"cc-visa\": [576, 512, [], \"f1f0\", \"M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z\"],\n    \"discourse\": [448, 512, [], \"f393\", \"M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z\"],\n    \"docker\": [640, 512, [], \"f395\", \"M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z\"],\n    \"github\": [496, 512, [], \"f09b\", \"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\"],\n    \"instagram\": [448, 512, [], \"f16d\", \"M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z\"],\n    \"microsoft\": [448, 512, [], \"f3ca\", \"M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z\"],\n    \"rev\": [448, 512, [], \"f5b2\", \"M289.67 274.89a65.57 65.57 0 1 1-65.56-65.56 65.64 65.64 0 0 1 65.56 65.56zm139.55-5.05h-.13a204.69 204.69 0 0 0-74.32-153l-45.38 26.2a157.07 157.07 0 0 1 71.81 131.84C381.2 361.5 310.73 432 224.11 432S67 361.5 67 274.88c0-81.88 63-149.27 143-156.43v39.12l108.77-62.79L210 32v38.32c-106.7 7.25-191 96-191 204.57 0 111.59 89.12 202.29 200.06 205v.11h210.16V269.84z\"],\n    \"slack\": [448, 512, [], \"f198\", \"M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z\"],\n    \"twitter\": [512, 512, [], \"f099\", \"M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z\"]\n  };\n\n  bunker(function () {\n    defineIcons('fab', icons);\n  });\n\n}());\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"abacus\": [576, 512, [], \"f640\", [\"M192 440h-32v-48h32zM160 72v48h32V72zm96 160v48h32v-48zm-96 0v48h32v-48zm96 208h160v-48H256zm96-160h128v-48H352zM544 0a32 32 0 0 0-32 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32a32 32 0 0 0-32-32zM416 72H256v48h160zM32 0A32 32 0 0 0 0 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32A32 32 0 0 0 32 0z\", \"M144 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm-96 160h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm192 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm-96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zM464 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM144 352h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm224 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16z\"]],\n    \"align-slash\": [640, 512, [], \"f846\", [\"M528 352h-31.46l-82.81-64H528a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16zM96 304v32a16 16 0 0 0 16 16h175.21l-82.8-64H112a16 16 0 0 0-16 16zM528 96a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16H112a15.82 15.82 0 0 0-15 11.18L165.31 96zM112 416a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h340.83L370 416zm416-256H248.12l82.81 64H528a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M633.82 458.1L45.46 3.38A16 16 0 0 0 23 6.19L3.37 31.46a16 16 0 0 0 2.81 22.45l588.36 454.72a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45z\"]],\n    \"atom-alt\": [448, 512, [], \"f5d3\", [\"M424.37305,55.69141C408.294,39.61914,385.50879,32,358.58252,32,319.82764,32,272.43359,48.127,224,77.14453a493.86641,493.86641,0,0,0-58.042,41.03711C140.58252,138.875,114.57666,162.5918,85.75635,197.916a374.25237,374.25237,0,0,0,35.70263,58.082A505.23427,505.23427,0,0,1,224,153.65625a377.23937,377.23937,0,0,1,58.042-35.47266c70.01221-34.334,95.22461-19.07421,97.0625-17.23632,9.54248,9.543,7.67432,46.94531-16.86084,96.96875A492.27615,492.27615,0,0,1,403.06543,256C452.27637,173.91992,463.59277,94.90039,424.37305,55.69141ZM224,358.3418a377.44678,377.44678,0,0,1-58.042,35.47461c-70.01221,34.334-95.22461,19.07421-97.0625,17.23632-9.54248-9.543-7.67432-46.94335,16.86084-96.96875A492.27615,492.27615,0,0,1,44.93457,256C-4.27637,338.08008-15.59277,417.09961,23.627,456.30664,39.70605,472.38086,62.49121,480,89.41748,480c38.75488,0,86.14893-16.127,134.58252-45.14453a493.86641,493.86641,0,0,0,58.042-41.03711c25.38965-20.70508,51.42285-44.45606,80.20166-79.73438A373.962,373.962,0,0,0,326.541,256,505.23427,505.23427,0,0,1,224,358.3418Z\", \"M224,287.98828a31.99414,31.99414,0,1,0-32-31.99414A31.98908,31.98908,0,0,0,224,287.98828ZM121.46094,255.99805A374.13921,374.13921,0,0,1,85.7583,197.916c-24.53906-50.02344-26.40625-87.42579-16.86328-96.9668,1.83984-1.83789,27.05078-17.10156,97.062,17.23242A494.241,494.241,0,0,1,224,77.14453C175.5625,48.13086,128.16406,32,89.41846,32c-26.9336,0-49.707,7.61523-65.793,23.69141C-15.59326,94.90039-4.27686,173.91992,44.93408,256A492.0174,492.0174,0,0,0,85.7583,314.084c28.79639,35.30274,54.85889,59.07227,80.19873,79.73243A377.429,377.429,0,0,0,224,358.3418,505.131,505.131,0,0,1,121.46094,255.99805ZM403.06592,256a492.0174,492.0174,0,0,0-40.82422-58.084c-28.84326-35.35547-54.89795-59.10352-80.19873-79.73243A377.4073,377.4073,0,0,0,224,153.65625,505.20556,505.20556,0,0,1,326.53906,256a373.849,373.849,0,0,1,35.70264,58.084c24.53906,50.02149,26.40625,87.42383,16.86328,96.9668-1.83984,1.83789-27.05078,17.10156-97.062-17.23242A494.241,494.241,0,0,1,224,434.85547C272.4375,463.86914,319.83594,480,358.58154,480c26.9336,0,49.707-7.61523,65.793-23.69336C463.59326,417.09961,452.27686,338.08008,403.06592,256Z\"]],\n    \"badge-check\": [512, 512, [], \"f336\", [\"M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z\", \"M367.2 211.75l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.06 15.56z\"]],\n    \"bell\": [448, 512, [], \"f0f3\", [\"M448 384c-.1 16.4-13 32-32.1 32H32.08C13 416 .09 400.4 0 384a31.25 31.25 0 0 1 8.61-21.71c19.32-20.76 55.47-52 55.47-154.29 0-77.7 54.48-139.9 127.94-155.16V32a32 32 0 1 1 64 0v20.84C329.42 68.1 383.9 130.3 383.9 208c0 102.3 36.15 133.53 55.47 154.29A31.27 31.27 0 0 1 448 384z\", \"M160 448h128a64 64 0 0 1-128 0z\"]],\n    \"books\": [576, 512, [], \"f5db\", [\"M96 0H32A32 32 0 0 0 0 32v64h128V32A32 32 0 0 0 96 0zM0 384h128V128H0zm0 96a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H0zm513.62-17.78L401.08 42.71l-60.26 16.14 112.35 418.8c.11.39.2.79.29 1.18l60.29-16.15c-.04-.15-.09-.3-.13-.46zM160 480a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H160zM256 0h-64a32 32 0 0 0-32 32v64h124.79l-8-29.65a23.94 23.94 0 0 1 11.17-27V32A32 32 0 0 0 256 0zm-96 384h128V128H160z\", \"M0 416h128v-32H0zm0-288h128V96H0zm575.17 317.65L460.39 17.78a23.89 23.89 0 0 0-29.18-17h-.09L415.73 5a24 24 0 0 0-16.9 29.36l114.79 427.86a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.35zM160 416h128v-32H160zM338.39 49.78a23.89 23.89 0 0 0-29.18-17h-.09L293.73 37a24 24 0 0 0-16.9 29.36l8 29.65H160v32h128V108l103.62 386.22a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.33z\"]],\n    \"brackets-curly\": [576, 512, [], \"f7ea\", [\"M566.64 233.37a32 32 0 0 1 0 45.25l-45.25 45.25a32 32 0 0 0-9.39 22.64V384a96 96 0 0 1-96 96h-48a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h48a32 32 0 0 0 32-32v-37.48a96 96 0 0 1 28.13-67.89L498.76 256l-22.62-22.62A96 96 0 0 1 448 165.47V128a32 32 0 0 0-32-32h-48a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h48a96 96 0 0 1 96 96v37.48a32 32 0 0 0 9.38 22.65l45.25 45.24z\", \"M208 32h-48a96 96 0 0 0-96 96v37.48a32.12 32.12 0 0 1-9.38 22.65L9.38 233.37a32 32 0 0 0 0 45.25l45.25 45.25A32.05 32.05 0 0 1 64 346.51V384a96 96 0 0 0 96 96h48a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-48a32 32 0 0 1-32-32v-37.48a96 96 0 0 0-28.13-67.89L77.26 256l22.63-22.63A96 96 0 0 0 128 165.48V128a32 32 0 0 1 32-32h48a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]],\n    \"chart-network\": [640, 512, [], \"f78a\", [\"M64 240a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64zm88 80h48v-32h-48zm294.4-106.8l19.2 25.6 48-36-19.2-25.6zM576 64a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64z\", \"M576 384a63.84 63.84 0 0 0-38.3 13l-96-57.6a109.91 109.91 0 0 0 6.3-35.5 111.94 111.94 0 0 0-112-112 108.64 108.64 0 0 0-24.4 2.9l-40.8-87.4A63.84 63.84 0 1 0 224 128c1.1 0 2.1-.3 3.2-.3l41 87.8C241.5 235.9 224 267.8 224 304a111.71 111.71 0 0 0 193.2 76.7l95.8 57.5a63.87 63.87 0 1 0 63-54.2zm-240-32a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]],\n    \"chart-scatter\": [512, 512, [], \"f7ee\", [\"M512 400v32a16 16 0 0 1-16 16H32a32 32 0 0 1-32-32V80a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16v304h432a16 16 0 0 1 16 16z\", \"M160 256a32 32 0 1 0 32 32 32 32 0 0 0-32-32zM416 96a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-224 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm192 160a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-96-64a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]],\n    \"check\": [512, 512, [], \"f00c\", [\"M504.5 144.42L264.75 385.5 192 312.59l240.11-241a25.49 25.49 0 0 1 36.06-.14l.14.14L504.5 108a25.86 25.86 0 0 1 0 36.42z\", \"M264.67 385.59l-54.57 54.87a25.5 25.5 0 0 1-36.06.14l-.14-.14L7.5 273.1a25.84 25.84 0 0 1 0-36.41l36.2-36.41a25.49 25.49 0 0 1 36-.17l.16.17z\"]],\n    \"circle\": [512, 512, [], \"f111\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 424c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\", \"M256 432c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\"]],\n    \"clouds\": [640, 512, [], \"f744\", [\"M161.6 288H96a96 96 0 0 1 0-192c.6 0 1.1.2 1.6.2C105.3 41.9 151.6 0 208 0a111.61 111.61 0 0 1 104.5 72.7A95.07 95.07 0 0 1 352 64a96 96 0 0 1 96 96 93 93 0 0 1-7 34.7 110.5 110.5 0 0 0-31.6 11.8A142.54 142.54 0 0 0 304 160c-73.9 0-134.3 56.2-142.4 128z\", \"M640 416a96 96 0 0 1-96 96H224a96 96 0 0 1-96-96c0-42.5 27.8-78.2 66.1-90.8A113.72 113.72 0 0 1 192 304a111.94 111.94 0 0 1 112-112c43.2 0 80.4 24.9 99 60.8 14.7-17.5 36.4-28.8 61-28.8a80 80 0 0 1 80 80 78.09 78.09 0 0 1-1.6 16.2c.5 0 1-.2 1.6-.2a96 96 0 0 1 96 96z\"]],\n    \"cogs\": [640, 512, [], \"f085\", [\"M638.41 387a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4L602 335a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6 12.36 12.36 0 0 0-15.1 5.4l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 44.9c-29.6-38.5 14.3-82.4 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79zm136.8-343.8a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4l8.2-14.3a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6A12.36 12.36 0 0 0 552 7.19l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 45c-29.6-38.5 14.3-82.5 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79z\", \"M420 303.79L386.31 287a173.78 173.78 0 0 0 0-63.5l33.7-16.8c10.1-5.9 14-18.2 10-29.1-8.9-24.2-25.9-46.4-42.1-65.8a23.93 23.93 0 0 0-30.3-5.3l-29.1 16.8a173.66 173.66 0 0 0-54.9-31.7V58a24 24 0 0 0-20-23.6 228.06 228.06 0 0 0-76 .1A23.82 23.82 0 0 0 158 58v33.7a171.78 171.78 0 0 0-54.9 31.7L74 106.59a23.91 23.91 0 0 0-30.3 5.3c-16.2 19.4-33.3 41.6-42.2 65.8a23.84 23.84 0 0 0 10.5 29l33.3 16.9a173.24 173.24 0 0 0 0 63.4L12 303.79a24.13 24.13 0 0 0-10.5 29.1c8.9 24.1 26 46.3 42.2 65.7a23.93 23.93 0 0 0 30.3 5.3l29.1-16.7a173.66 173.66 0 0 0 54.9 31.7v33.6a24 24 0 0 0 20 23.6 224.88 224.88 0 0 0 75.9 0 23.93 23.93 0 0 0 19.7-23.6v-33.6a171.78 171.78 0 0 0 54.9-31.7l29.1 16.8a23.91 23.91 0 0 0 30.3-5.3c16.2-19.4 33.7-41.6 42.6-65.8a24 24 0 0 0-10.5-29.1zm-151.3 4.3c-77 59.2-164.9-28.7-105.7-105.7 77-59.2 164.91 28.7 105.71 105.7z\"]],\n    \"comment-dots\": [512, 512, [], \"f4ad\", [\"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5a8 8 0 0 0-1.5 8.7A7.83 7.83 0 0 0 8 480c66.3 0 116-31.8 140.6-51.4A305 305 0 0 0 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32z\", \"M128 208a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]],\n    \"concierge-bell\": [512, 512, [], \"f562\", [\"M512 400v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h480a16 16 0 0 1 16 16zM208 112h16v18.29a224.73 224.73 0 0 1 64 0V112h16a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16z\", \"M480 352H32c0-123.71 100.29-224 224-224s224 100.29 224 224z\"]],\n    \"dot-circle\": [512, 512, [], \"f192\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm124.45 372.45A176 176 0 1 1 432 256a174.85 174.85 0 0 1-51.55 124.45z\", \"M256 336a80 80 0 1 1 80-80 80.09 80.09 0 0 1-80 80z\"]],\n    \"envelope\": [512, 512, [], \"f0e0\", [\"M256.47 352h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V400a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V183.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52zM464 64H48a48 48 0 0 0-48 48v19a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4 23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131v-19a48 48 0 0 0-48-48z\", \"M512 131v52.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V131a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.69 12.12 49.75 41.4 72.93 41.4h.94c23.18 0 56.24-29.28 72.93-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131z\"]],\n    \"exchange-alt\": [512, 512, [], \"f362\", [\"M128 272v48h360a24 24 0 0 1 24 24v16a24 24 0 0 1-24 24H128v48c0 21.44-25.94 32-41 17L7 369a24 24 0 0 1 0-33.94l80-80c15.14-15.12 41-4.35 41 16.94z\", \"M505 143.05a24 24 0 0 1 0 33.95l-80 80c-15 15-41 4.49-41-17v-48H24a24 24 0 0 1-24-24v-16a24 24 0 0 1 24-24h360V80c0-21.36 25.9-32 41-17z\"]],\n    \"file-alt\": [384, 512, [], \"f15c\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zm-96 244a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM276 352H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12z\"]],\n    \"file-code\": [384, 512, [], \"f1c9\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zM141.79 379.54l-19.58 20.84a5.41 5.41 0 0 1-7.64.24l-64.86-60.69a5.37 5.37 0 0 1-.24-7.6l.25-.25 64.86-60.7a5.42 5.42 0 0 1 7.64.24l19.58 20.85a5.4 5.4 0 0 1-.25 7.62l-.13.12L100.65 336l40.76 35.8a5.4 5.4 0 0 1 .49 7.62zm31.71 71.25l-27.45-8a5.38 5.38 0 0 1-3.67-6.67l61.49-211.24a5.38 5.38 0 0 1 6.68-3.64l27.45 8a5.4 5.4 0 0 1 3.63 6.67l-61.45 211.2a5.4 5.4 0 0 1-6.68 3.68zm161-111.12l-.25.25-64.86 60.69a5.42 5.42 0 0 1-7.64-.23l-19.58-20.84a5.37 5.37 0 0 1 .26-7.6l.13-.12L283.35 336l-40.76-35.8a5.4 5.4 0 0 1-.49-7.62l.11-.12 19.58-20.85a5.42 5.42 0 0 1 7.64-.24l64.86 60.7a5.36 5.36 0 0 1 .25 7.6z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM141.41 371.8L100.65 336l40.76-35.8.13-.12a5.4 5.4 0 0 0 .25-7.62l-19.58-20.85a5.42 5.42 0 0 0-7.64-.24l-64.86 60.7-.25.25a5.37 5.37 0 0 0 .24 7.6l64.86 60.69a5.41 5.41 0 0 0 7.64-.24l19.58-20.84.11-.12a5.4 5.4 0 0 0-.48-7.61zm100.22-135.93a5.4 5.4 0 0 0-3.63-6.67l-27.45-8a5.38 5.38 0 0 0-6.68 3.64l-61.5 211.29a5.38 5.38 0 0 0 3.63 6.67l27.45 8a5.4 5.4 0 0 0 6.68-3.68l61.44-211.22zm92.66 96.2l-64.86-60.7a5.42 5.42 0 0 0-7.64.24l-19.58 20.85-.11.12a5.4 5.4 0 0 0 .49 7.62l40.76 35.8-40.76 35.8-.13.12a5.37 5.37 0 0 0-.26 7.6l19.58 20.84a5.42 5.42 0 0 0 7.64.23l64.86-60.69.25-.25a5.36 5.36 0 0 0-.25-7.6z\"]],\n    \"globe\": [496, 512, [], \"f0ac\", [\"M340.45,320H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256,575,575,0,0,1,340.45,320ZM160.2,160H335.8c-.41-2.31-.84-4.62-1.28-6.91-6-30.85-14.42-58.37-25.13-81.78C299.54,49.77,288,32.54,276.05,21.48,266.38,12.53,256.94,8,248,8s-18.38,4.53-28,13.48c-12,11.06-23.49,28.29-33.34,49.83C176,94.72,167.5,122.24,161.53,153.09,161,155.38,160.61,157.69,160.2,160ZM120,256a608,608,0,0,1,3.34-64H8.35a249.52,249.52,0,0,0,0,128h115A608,608,0,0,1,120,256Zm367.62-64h-115A608.06,608.06,0,0,1,376,256a608,608,0,0,1-3.34,64h115a249.52,249.52,0,0,0,0-128ZM476.7,160A248.62,248.62,0,0,0,315.58,17.32c24.13,33,42.89,83.15,52.75,142.68ZM315.58,494.68A248.59,248.59,0,0,0,476.71,352H368.33C358.47,411.53,339.71,461.68,315.58,494.68ZM335.8,352H160.2c.41,2.31.84,4.62,1.28,6.91,6,30.85,14.42,58.37,25.13,81.78,9.85,21.54,21.38,38.77,33.34,49.83,9.67,9,19.11,13.48,28.05,13.48s18.38-4.53,28.05-13.48c12-11.06,23.49-28.29,33.34-49.83,10.71-23.41,19.16-50.93,25.13-81.78C335,356.62,335.39,354.31,335.8,352ZM180.42,17.32A248.59,248.59,0,0,0,19.29,160H127.67C137.53,100.47,156.29,50.32,180.42,17.32ZM19.29,352A248.59,248.59,0,0,0,180.42,494.68c-24.13-33-42.89-83.15-52.75-142.68Z\", \"M376,256a608,608,0,0,0-3.34-64h115a245.72,245.72,0,0,0-10.92-32H368.33c-9.86-59.53-28.62-109.68-52.75-142.68A248.23,248.23,0,0,0,248,8c8.94,0,18.38,4.53,28.05,13.48,12,11.06,23.49,28.29,33.34,49.83,10.71,23.41,19.16,50.93,25.13,81.78.44,2.29.87,4.6,1.28,6.91H160.2c.41-2.31.84-4.62,1.28-6.91,6-30.85,14.42-58.37,25.13-81.78C196.46,49.77,208,32.54,220,21.48,229.62,12.53,239.06,8,248,8a248.23,248.23,0,0,0-67.58,9.32c-24.13,33-42.89,83.15-52.75,142.68H19.29A245.72,245.72,0,0,0,8.37,192h115a613.93,613.93,0,0,0,0,128H8.37a245.72,245.72,0,0,0,10.92,32H127.67c9.86,59.53,28.62,109.68,52.75,142.68A248.23,248.23,0,0,0,248,504c-8.94,0-18.38-4.53-28.05-13.48-12-11.06-23.49-28.29-33.34-49.83-10.71-23.41-19.16-50.93-25.13-81.78-.44-2.29-.87-4.6-1.28-6.91H335.8c-.41,2.31-.84,4.62-1.28,6.91-6,30.85-14.42,58.37-25.13,81.78-9.85,21.54-21.38,38.77-33.34,49.83-9.67,9-19.11,13.48-28.05,13.48a248.23,248.23,0,0,0,67.58-9.32c24.13-33,42.89-83.15,52.75-142.68H476.71a245.72,245.72,0,0,0,10.92-32h-115A605.37,605.37,0,0,0,376,256Zm-35.54,64H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256a575,575,0,0,1-3.55,64Z\"]],\n    \"globe-africa\": [496, 512, [], \"f57c\", [\"M491.33,208H423.5A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05A249.89,249.89,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256A249.51,249.51,0,0,0,491.33,208Z\", \"M423.5,208A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05C386,23.7,471,104.24,491.34,208Z\"]],\n    \"globe-americas\": [496, 512, [], \"f57d\", [\"M489.55,312.41C464,422.22,365.59,504,248,504,111,504,0,393,0,256A247,247,0,0,1,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311l-13.71-13.67A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A247,247,0,0,1,248,8C351.83,8,440.71,71.76,477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1Z\", \"M321.39,297.36A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A249,249,0,0,0,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311ZM477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1,55.64,29.22a249.21,249.21,0,0,0-11.88-150.14Z\"]],\n    \"globe-asia\": [496, 512, [], \"f57e\", [\"M312,16.35V50.73a28,28,0,0,1-11.12,22.35l-41.41,31.27a8,8,0,0,0,.86,13.81l10.83,5.41A16,16,0,0,1,280,137.88V216a8,8,0,0,1-8,8h-3.06a8,8,0,0,1-7.15-4.42,4.47,4.47,0,0,0-1.72-1.86,4.42,4.42,0,0,0-6.06,1.54h0l-17.34,29A16,16,0,0,1,222.94,256h-.31a16,16,0,0,0-11.32,4.69l-5.66,5.66a8,8,0,0,0,0,11.31l5.66,5.66A16,16,0,0,1,216,294.63V304a16,16,0,0,1-16,16h-6.1a16,16,0,0,1-14.28-8.85L157,265.92a8,8,0,0,0-10.72-3.6h0a8.14,8.14,0,0,0-2.11,1.53l-19.47,19.46A16,16,0,0,1,113.38,288H2.05C17.74,409.88,121.84,504,248,504c137,0,248-111,248-248C496,141.13,418,44.56,312,16.35Zm96,342.08a16,16,0,0,1-4.69,11.31l-9.57,9.57A16,16,0,0,1,382.43,384H367.27a16,16,0,0,1-11.36-4.74l-13-13a26.78,26.78,0,0,0-25.42-7l-21.27,5.32a15.86,15.86,0,0,1-3.88.48H282a16,16,0,0,1-11.24-4.69l-11.91-11.91a8,8,0,0,1-2.34-5.66V332.6a8,8,0,0,1,5-7.43l39.34-15.74a26.35,26.35,0,0,0,5.59-3.05l23.71-16.89a8,8,0,0,1,4.64-1.48h12.14a8,8,0,0,1,7.39,4.93l5.35,12.85a4,4,0,0,0,3.69,2.46h3.8a4,4,0,0,0,3.84-2.88l4.16-14.49A4,4,0,0,1,379,288h6.06a4,4,0,0,1,4,4v13a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,1,408,333.83Z\", \"M260.07,217.72a4.47,4.47,0,0,1,1.72,1.86,8,8,0,0,0,7.15,4.42H272a8,8,0,0,0,8-8V137.88a16,16,0,0,0-8.84-14.31l-10.83-5.41a8,8,0,0,1-.86-13.81l41.41-31.27A28,28,0,0,0,312,50.73V16.35A248.23,248.23,0,0,0,248,8C111,8,0,119,0,256a249.89,249.89,0,0,0,2.05,32H113.38a16,16,0,0,0,11.31-4.69l19.47-19.46A8,8,0,0,1,157,265.92l22.62,45.23A16,16,0,0,0,193.9,320H200a16,16,0,0,0,16-16v-9.37a16,16,0,0,0-4.69-11.31l-5.66-5.66a8,8,0,0,1,0-11.31l5.66-5.66A16,16,0,0,1,222.63,256h.31a16,16,0,0,0,13.72-7.77L254,219.28a4.42,4.42,0,0,1,6.05-1.57Zm143.24,104.8L391.4,310.61a8,8,0,0,1-2.34-5.66V292a4,4,0,0,0-4-4H379a4,4,0,0,0-3.84,2.88L371,305.37a4,4,0,0,1-3.84,2.88h-3.8a4,4,0,0,1-3.69-2.46l-5.35-12.85a8,8,0,0,0-7.39-4.93H334.79a8,8,0,0,0-4.64,1.48l-23.71,16.89a26.35,26.35,0,0,1-5.59,3.05l-39.34,15.74a8,8,0,0,0-5,7.43v10.2a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,0,282,365.06h10.34a15.86,15.86,0,0,0,3.88-.48l21.27-5.32a26.78,26.78,0,0,1,25.42,7l13,13A16,16,0,0,0,367.27,384h15.16a16,16,0,0,0,11.31-4.69l9.57-9.57A16,16,0,0,0,408,358.43v-24.6a16,16,0,0,0-4.69-11.31Z\"]],\n    \"globe-europe\": [496, 512, [], \"f7a2\", [\"M487.54,320.4H438.9a15.8,15.8,0,0,1-11.4-4.8l-32-32.6a11.92,11.92,0,0,1,.1-16.7l12.5-12.5v-8.7a11.37,11.37,0,0,0-3.3-8l-9.4-9.4a11.37,11.37,0,0,0-8-3.3h-16a11.31,11.31,0,0,1-8-19.3l9.4-9.4a11.37,11.37,0,0,1,8-3.3h32a11.35,11.35,0,0,0,11.3-11.3v-9.4a11.35,11.35,0,0,0-11.3-11.3H376.1a16,16,0,0,0-16,16v4.5a16,16,0,0,1-10.9,15.2l-31.6,10.5a8,8,0,0,0-5.5,7.6v2.2a8,8,0,0,1-8,8h-16a8,8,0,0,1-8-8,8,8,0,0,0-8-8H269a8.14,8.14,0,0,0-7.2,4.4l-9.4,18.7a15.94,15.94,0,0,1-14.3,8.8H216a16,16,0,0,1-16-16V199a16,16,0,0,1,4.7-11.3l20.1-20.1a24.77,24.77,0,0,0,7.2-17.5,8,8,0,0,1,5.5-7.6l40-13.3a11.66,11.66,0,0,0,4.4-2.7l26.8-26.8a11.31,11.31,0,0,0-8-19.3H280l-16,16v8a8,8,0,0,1-8,8H240a8,8,0,0,1-8-8v-20a8.05,8.05,0,0,1,3.2-6.4l82.42-60.08A247.79,247.79,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504a251.57,251.57,0,0,0,32.1-2.06V448.4a16,16,0,0,0-16-16H243.9c-10.8,0-26.7-5.3-35.4-11.8l-22.2-16.7a45.42,45.42,0,0,1-18.2-36.4V343.6a45.46,45.46,0,0,1,22.1-39l42.9-25.7a46.13,46.13,0,0,1,23.4-6.5h31.2a45.62,45.62,0,0,1,29.6,10.9l43.2,37.1h18.3a32,32,0,0,1,22.6,9.4l17.3,17.3.08.08C432,359.06,440,375.62,440,393.37V413A247.11,247.11,0,0,0,487.54,320.4ZM187.4,157.1a11.37,11.37,0,0,1-8,3.3h-16a11.31,11.31,0,0,1-8-19.3l25.4-25.4a11.31,11.31,0,0,1,19.3,8v16a11.37,11.37,0,0,1-3.3,8Z\", \"M187.4,157.1l9.4-9.4a11.37,11.37,0,0,0,3.3-8v-16a11.31,11.31,0,0,0-19.3-8l-25.4,25.4a11.31,11.31,0,0,0,8,19.3h16A11.37,11.37,0,0,0,187.4,157.1ZM418.78,347.18l-.08-.08-17.3-17.3a32,32,0,0,0-22.6-9.4H360.5l-43.2-37.1a45.62,45.62,0,0,0-29.6-10.9H256.5a46.13,46.13,0,0,0-23.4,6.5l-42.9,25.7a45.46,45.46,0,0,0-22.1,39v23.9a45.42,45.42,0,0,0,18.2,36.4l22.2,16.7c8.7,6.5,24.6,11.8,35.4,11.8h20.2a16,16,0,0,1,16,16v53.54A247.57,247.57,0,0,0,440,413V393.37C440,375.62,432,359.06,418.78,347.18ZM317.62,17.92,235.2,78a8.05,8.05,0,0,0-3.2,6.4v20a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-8l16-16h20.7a11.31,11.31,0,0,1,8,19.3l-26.8,26.8a11.66,11.66,0,0,1-4.4,2.7l-40,13.3a8,8,0,0,0-5.5,7.6,24.77,24.77,0,0,1-7.2,17.5l-20.1,20.1A16,16,0,0,0,200,199v25.3a16,16,0,0,0,16,16h22.1a15.94,15.94,0,0,0,14.3-8.8l9.4-18.7a8.14,8.14,0,0,1,7.2-4.4h3.1a8,8,0,0,1,8,8,8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-2.2a8,8,0,0,1,5.5-7.6l31.6-10.5a16,16,0,0,0,10.9-15.2v-4.5a16,16,0,0,1,16-16h36.7a11.35,11.35,0,0,1,11.3,11.3v9.4a11.35,11.35,0,0,1-11.3,11.3h-32a11.37,11.37,0,0,0-8,3.3l-9.4,9.4a11.31,11.31,0,0,0,8,19.3h16a11.37,11.37,0,0,1,8,3.3l9.4,9.4a11.37,11.37,0,0,1,3.3,8v8.7l-12.5,12.5a11.92,11.92,0,0,0-.1,16.7l32,32.6a15.8,15.8,0,0,0,11.4,4.8h48.64A248.29,248.29,0,0,0,496,256C496,143.18,420.71,48,317.62,17.92Z\"]],\n    \"graduation-cap\": [640, 512, [], \"f19d\", [\"M323.07 175.7L118.8 215.6a48.1 48.1 0 0 0-38.74 44.73 32 32 0 0 1 2.21 53.94l25.4 114.26A16 16 0 0 1 92 448H35.94a16 16 0 0 1-15.61-19.47l25.39-114.27a32 32 0 0 1 2.33-54 80.16 80.16 0 0 1 64.62-76.07l204.26-39.89a16 16 0 1 1 6.14 31.4z\", \"M622.33 198.8l-279 85.7a80 80 0 0 1-46.79 0L99.67 224a47.84 47.84 0 0 1 19.13-8.39l204.27-39.9a16 16 0 1 0-6.14-31.4l-204.26 39.88a79.87 79.87 0 0 0-47.57 29.18l-47.44-14.58c-23.54-7.23-23.54-38.36 0-45.59L296.6 67.5a79.92 79.92 0 0 1 46.8 0l278.93 85.7c23.55 7.24 23.55 38.36 0 45.6zM352.79 315.09a111.94 111.94 0 0 1-65.59 0l-145-44.55L128 384c0 35.35 86 64 192 64s192-28.65 192-64l-14.19-113.47z\"]],\n    \"history\": [512, 512, [], \"f1da\", [\"M141.68 400.23a184 184 0 1 0-11.75-278.3l50.76 50.76c10.08 10.08 2.94 27.31-11.32 27.31H24a16 16 0 0 1-16-16V38.63c0-14.26 17.23-21.4 27.31-11.32l49.38 49.38A247.14 247.14 0 0 1 256 8c136.81 0 247.75 110.78 248 247.53S392.82 503.9 256.18 504a247 247 0 0 1-155.82-54.91 24 24 0 0 1-1.84-35.61l11.27-11.27a24 24 0 0 1 31.89-1.98z\", \"M288 152v104.35L328.7 288a24 24 0 0 1 4.21 33.68l-9.82 12.62a24 24 0 0 1-33.68 4.21L224 287.65V152a24 24 0 0 1 24-24h16a24 24 0 0 1 24 24z\"]],\n    \"key\": [512, 512, [], \"f084\", [\"M303.06 348.91l.1.09-24 27a24 24 0 0 1-17.94 8H224v40a24 24 0 0 1-24 24h-40v40a24 24 0 0 1-24 24H24a24 24 0 0 1-24-24v-78a24 24 0 0 1 7-17l161.83-161.83-.11-.35a176.24 176.24 0 0 0 134.34 118.09z\", \"M336 0a176 176 0 1 0 176 176A176 176 0 0 0 336 0zm48 176a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]],\n    \"key-skeleton\": [512, 512, [], \"f6f3\", [\"M251.31 372.91a16 16 0 0 1 0 22.63l-15.77 15.77a16 16 0 0 1-22.62 0L176 374.4l-30.87 30.86 36.11 36.11a16 16 0 0 1 0 22.63l-43.16 43.17a16 16 0 0 1-22.62 0l-36.12-36.11-36.26 36.25a16 16 0 0 1-22.62 0L4.69 491.54a16 16 0 0 1 0-22.63l255.12-255.12a64.18 64.18 0 0 0 38.4 38.4L214.4 336l36.91 36.91z\", \"M448 0H320a64 64 0 0 0-64 64v128a64 64 0 0 0 64 64h128a64 64 0 0 0 64-64V64a64 64 0 0 0-64-64zm-73.37 182.63a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25zm64-64a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25z\"]],\n    \"laptop\": [640, 512, [], \"f109\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M512 64H128v256h384zm112 352H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16z\"]],\n    \"laptop-code\": [640, 512, [], \"f5fc\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16zM512 64H128v256h384zM289 250.34l-11.31 11.31a16 16 0 0 1-22.63 0l-58.35-58.34a16 16 0 0 1 0-22.63L255 122.34a16 16 0 0 1 22.63 0L289 133.65a16 16 0 0 1 0 22.63L253.25 192 289 227.71a16 16 0 0 1 0 22.63zm154.35-47L385 261.66a16 16 0 0 1-22.63 0L351 250.35a16 16 0 0 1 0-22.63L386.75 192 351 156.29a16 16 0 0 1 0-22.63l11.31-11.31a16 16 0 0 1 22.63 0l58.34 58.34a16 16 0 0 1 .04 22.63z\"]],\n    \"laptop-house\": [640, 512, [], \"e066\", [\"M272,416H96a32,32,0,0,1-32-32V219.88L42.34,239A16.51,16.51,0,0,1,33,242.48a16.22,16.22,0,0,1-10.63-4.78L3.55,216.42A16.4,16.4,0,0,1,0,207a16.15,16.15,0,0,1,4.78-10.61L216.58,8.92C222.12,4,232.64,0,240.05,0S258,4,263.5,8.92L352,87.3V48a16,16,0,0,1,16-16h32a16,16,0,0,1,16,16v96l59.24,52.42A16.31,16.31,0,0,1,480,207a16.51,16.51,0,0,1-3.58,9.44L469.74,224H332.8c-17.8,0-33.69,8.24-44.82,21.12V208a16,16,0,0,0-16-16H208a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16h64Z\", \"M629.33,448H592V288c0-17.67-12.89-32-28.8-32H332.8c-15.91,0-28.8,14.33-28.8,32V448H266.67A10.67,10.67,0,0,0,256,458.67v10.66A42.82,42.82,0,0,0,298.6,512H597.4A42.82,42.82,0,0,0,640,469.33V458.67A10.67,10.67,0,0,0,629.33,448ZM544,448H352V304H544Z\"]],\n    \"life-ring\": [512, 512, [], \"f1cd\", [\"M292.08 167l-.41-.17zm-66.62-2a96.5 96.5 0 0 1 61.08 0l112-112a248 248 0 0 0-285 0zm68.67 2.92l.52.22zm2.49 1.12l.46.21zM186.25 322l-.19-.21zm-5.51-6.36l.21.26zm1.65 2c.12.14.23.28.35.41-.12-.15-.23-.29-.35-.43zm1.74 2l.36.4zm135.51-135.51l.4.36zM177.51 311.29l-.1-.15zM304.18 173l.34.19zm11.42 7.78l.26.21zm6.36 5.51l-.21-.19zm-3.96-3.55l-.42-.35zm-11.6-8.43l.47.29zm4.68 3.09l.17.12zm-2-1.35l-.43-.29zm-9.71-5.68l-.1-.05zm-123.61 32.91c.1-.14.19-.28.28-.42-.04.14-.18.28-.28.42zm-1.45 2.28l.29-.46zm-1.31 2.25l.19-.32zm-2.6 4.77zm10.38-16.18l.21-.26zm2-2.43c-.12.13-.23.27-.35.41.08-.14.19-.28.31-.38zm-5.33 6.89l.1-.15zm-8.2 14.07c-.07.14-.13.29-.2.43.03-.14.09-.29.16-.43zm5.39 92l-.29-.46zm-4.27-7.53v.05zm2.82 5.14l-.19-.32zm2.61 4.21c.1.14.19.28.28.42-.08-.17-.22-.31-.32-.45zm-6.8-12.11c.07.14.13.29.2.43-.06-.14-.12-.29-.2-.43zm-2-76.7c0 .13-.1.25-.16.38.07-.13.16-.25.16-.38zm1.09-2.58c-.07.17-.15.34-.22.5.13-.16.13-.33.23-.5zm-.22 76.78c.07.16.15.33.22.5-.09-.17-.09-.34-.21-.5zm-1-2.46c.06.13.11.25.16.38-.03-.13-.12-.25-.18-.38zm172-84.19l.19.32zM327.51 320l.36-.4zm-1.57 1.71l-.19.21zM325.75 190l.19.21zm3.51 128c.12-.13.23-.27.35-.41-.12.17-.23.31-.35.41zm2-121.63l-.21-.26zm0 119.2l-.21.26zm-1.65-121.22c-.12-.14-.23-.28-.35-.41.12.16.23.3.35.44zm-1.74-2l-.36-.4zm6.62 8.35l.1.15zm.1 110.43l-.1.15zM398.49 53q2 1.41 4 2.85-2-1.43-4-2.85zM343.9 294.64c.07-.17.15-.34.22-.5-.07.16-.12.33-.22.5zm1.09-2.58c.05-.13.1-.25.16-.38-.06.13-.15.25-.15.38zm-3.35 7.36v-.05zm-5.4 9.3l-.28.42zm1.45-2.28l-.29.46zm1.35-2.25l-.19.32zm3.75-7.12c.07-.14.13-.29.2-.43-.07.14-.13.29-.2.43zM449 100.21q-1.41-1.75-2.85-3.46 1.39 1.71 2.85 3.46zM445.49 96c-1-1.18-2-2.35-3-3.51 1 1.19 2.01 2.36 3 3.51zm6.87 8.5q-1.36-1.74-2.76-3.5 1.4 1.76 2.76 3.53zm3.36 4.44c-.91-1.23-1.83-2.44-2.75-3.65.92 1.24 1.84 2.45 2.75 3.71zm-119.48 94.34l-.28-.42zm66.76-147q1.85 1.36 3.66 2.76-1.78-1.39-3.66-2.76zm12.23 9.62q-1.72-1.44-3.47-2.85 1.77 1.41 3.5 2.85zM411 62.4q-1.74-1.4-3.51-2.77Q409.24 61 411 62.4zm8.5 7.13q-1.74-1.53-3.51-3 1.75 1.47 3.49 3zm-75.38 148.33c-.07-.16-.15-.33-.22-.5.1.17.15.34.22.5zM184.49 192l-.36.4zM343 215.36c-.07-.14-.13-.29-.2-.43.06.14.12.29.2.43zm113.16-105.8c1 1.31 1.9 2.62 2.84 3.94-.95-1.32-1.89-2.63-2.85-3.94zM337.4 205.1l.29.46zm82.53-135.18a248.82 248.82 0 0 1 22.14 22.15 250.17 250.17 0 0 0-22.14-22.15zm-74.78 150.4a6.15 6.15 0 0 1-.16-.38c.01.13.1.25.16.38zM459 398.49a248 248 0 0 0 0-285L347 225.46a96.5 96.5 0 0 1 0 61.08zM341.67 212.63zM220.33 345.15l-.41-.17zm-2.46-1l-.52-.22zm-5.3-2.49l.1.05zM322 325.75l-.21.19zM309.14 336l-.43.29zm2-1.35l.17-.12zm4.48-3.34l.26-.21zm4-3.39l.4-.36zm-1.6 1.39l-.42.35zM215.38 343l-.46-.21zm-19-11.74l-.26-.21zm-4-3.39l-.4-.36zm-6.3-137.62l.19-.21zm4 135.5l.21.19zm15.52 11.94l-.47-.29zm2.26 1.35l-.34-.19zm78.72 8a96.5 96.5 0 0 1-61.08 0L113.51 459a248 248 0 0 0 285 0zM202.86 336l.43.29zm-2-1.35l-.17-.12zM416 445.49q1.77-1.49 3.51-3-1.77 1.51-3.51 3zm43-47c-.93 1.33-1.88 2.64-2.84 3.95.95-1.31 1.9-2.62 2.84-3.95zM411.79 449q1.74-1.41 3.47-2.85-1.72 1.39-3.47 2.85zm-4.32 3.42q1.77-1.38 3.51-2.77-1.74 1.35-3.51 2.72zM455.72 403q-1.37 1.85-2.76 3.66 1.4-1.78 2.76-3.66zm-10.23 13c-1 1.18-2 2.35-3 3.51 1-1.19 2.01-2.36 3-3.51zm3.46-4.18q-1.41 1.74-2.85 3.47 1.44-1.75 2.9-3.5zm.65-.81q1.39-1.74 2.77-3.51-1.37 1.74-2.77 3.5zm-150.17-69.38a.31.31 0 0 1-.1.05.31.31 0 0 0 .1-.05zm-5.3 2.49l.52-.22zm12.31-6.43l.47-.29zm-9.82 5.31l.46-.21zm7.56-4l.34-.19zm137.9 80.89a248.94 248.94 0 0 1-22.15 22.15 248.94 248.94 0 0 0 22.15-22.11zm-39.63 36.21q-2 1.44-4 2.85 2.04-1.37 4-2.81zM292.08 345l-.41.17zM403 455.72q1.85-1.37 3.66-2.76-1.78 1.4-3.66 2.76zM194 329.26l.42.35zM69.93 92.07a248.82 248.82 0 0 1 22.14-22.15 250.17 250.17 0 0 0-22.14 22.15zm30.28-29q-1.74 1.41-3.47 2.85 1.73-1.46 3.47-2.87zm90 123l-.21.19zm4.13-3.67l-.42.35zM109.55 55.86q2-1.44 4-2.85-2.03 1.41-4 2.85zM196.14 181l.26-.21zM104.53 59.63Q102.76 61 101 62.4q1.76-1.4 3.53-2.77zm.78-.59q1.81-1.4 3.66-2.76-1.84 1.37-3.66 2.72zm87.05 125.09l-.4.36zm22.56-14.92l.46-.21zm-2.25 1.11l-.1.05zm4.68-2.22l.52-.22zm2.57-1.08l.41-.17zm-17.06 9l.43-.29zm5-3.09l-.34.19zm-7.11 4.56l.17-.12zm4.38-2.92l.47-.29zM96.74 446.1q1.73 1.44 3.47 2.85-1.74-1.41-3.47-2.85zm-33.69-34.31q1.41 1.74 2.85 3.47-1.44-1.72-2.85-3.47zm3.46 4.21c1 1.18 2 2.35 3 3.51-1-1.19-2.01-2.36-3-3.51zm-10.23-13q1.36 1.85 2.76 3.66-1.39-1.78-2.76-3.66zm3.35 4.44q1.37 1.8 2.77 3.56-1.4-1.76-2.77-3.53zm32.89 35q1.74 1.53 3.51 3-1.77-1.44-3.51-2.97zM105.31 453q1.81 1.4 3.66 2.76-1.84-1.4-3.66-2.76zm8.2 6q-2-1.41-4-2.85 2.01 1.43 4 2.85zM101 449.6q1.74 1.39 3.51 2.77-1.75-1.37-3.51-2.77zm-45.15-47.16c-1-1.31-1.9-2.62-2.84-3.95.99 1.33 1.88 2.64 2.84 3.95zM65.9 96.75q-1.44 1.71-2.85 3.46 1.41-1.75 2.85-3.46zM56.29 109c.9-1.23 1.82-2.45 2.74-3.65-.92 1.17-1.84 2.39-2.74 3.65zm6.11-8q-1.4 1.74-2.76 3.51Q61 102.76 62.4 101zm7.12-8.5c-1 1.16-2 2.33-3 3.51.98-1.16 1.99-2.33 3-3.49zm23-23q1.74-1.53 3.51-3-1.77 1.5-3.51 3.03zm-.45 372.55a248.94 248.94 0 0 1-22.15-22.15 248.94 248.94 0 0 0 22.15 22.18zM165 286.54a96.5 96.5 0 0 1 0-61.08L53 113.51a248 248 0 0 0 0 285zm-109.11-177q-1.44 2-2.84 3.93 1.36-1.95 2.8-3.9z\", \"M347 225.46l112-111.95A249.4 249.4 0 0 0 398.49 53L286.54 165A96.26 96.26 0 0 1 347 225.46zm-182 61.08l-112 112a249.4 249.4 0 0 0 60.5 60.5L225.46 347A96.26 96.26 0 0 1 165 286.54zm-112-173l112 112a96.26 96.26 0 0 1 60.5-60.5L113.51 53A249.4 249.4 0 0 0 53 113.51zM286.54 347l112 112a249.4 249.4 0 0 0 60.5-60.5L347 286.54A96.26 96.26 0 0 1 286.54 347z\"]],\n    \"lightbulb\": [352, 512, [], \"f0eb\", [\"M175.45 0C73.44.31 0 83 0 176a175 175 0 0 0 43.56 115.78c16.52 18.85 42.36 58.22 52.21 91.45 0 .26.07.52.11.78h160.24c0-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45A175.9 175.9 0 0 0 175.45 0zm.55 96a80.09 80.09 0 0 0-80 80 16 16 0 0 1-32 0A112.12 112.12 0 0 1 176 64a16 16 0 0 1 0 32z\", \"M96.06 454.35L96 416h160v38.35a32 32 0 0 1-5.41 17.65l-17.09 25.73A32 32 0 0 1 206.86 512h-61.71a32 32 0 0 1-26.64-14.28L101.42 472a32 32 0 0 1-5.36-17.65z\"]],\n    \"list-alt\": [512, 512, [], \"f022\", [\"M464 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zM128 392a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm288 168a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12z\", \"M128 200a40 40 0 1 0-40-40 40 40 0 0 0 40 40zm0 16a40 40 0 1 0 40 40 40 40 0 0 0-40-40zm0 96a40 40 0 1 0 40 40 40 40 0 0 0-40-40z\"]],\n    \"list-ul\": [512, 512, [], \"f0ca\", [\"M496 384H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48z\"]],\n    \"lock-alt\": [448, 512, [], \"f30d\", [\"M152 225H72v-72C72 69.2 140.2 1 224 1s152 68.2 152 152v72h-80v-72a72 72 0 0 0-144 0z\", \"M400 225H48a48 48 0 0 0-48 48v192a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V273a48 48 0 0 0-48-48zM264 392a40 40 0 0 1-80 0v-48a40 40 0 0 1 80 0z\"]],\n    \"map-marker-alt\": [384, 512, [], \"f3c5\", [\"M192 0C86 0 0 86 0 192c0 77.41 27 99 172.27 309.67a24 24 0 0 0 39.46 0C357 291 384 269.41 384 192 384 86 298 0 192 0zm0 288a96 96 0 1 1 96-96 96 96 0 0 1-96 96z\", \"M192 256a64 64 0 1 1 64-64 64 64 0 0 1-64 64z\"]],\n    \"moon-stars\": [512, 512, [], \"f755\", [\"M320 32L304 0l-16 32-32 16 32 16 16 32 16-32 32-16zm138.7 149.3L432 128l-26.7 53.3L352 208l53.3 26.7L432 288l26.7-53.3L512 208z\", \"M332.2 426.4c8.1-1.6 13.9 8 8.6 14.5a191.18 191.18 0 0 1-149 71.1C85.8 512 0 426 0 320c0-120 108.7-210.6 227-188.8 8.2 1.6 10.1 12.6 2.8 16.7a150.3 150.3 0 0 0-76.1 130.8c0 94 85.4 165.4 178.5 147.7z\"]],\n    \"network-wired\": [640, 512, [], \"f6ff\", [\"M624 232H344v-40h-48v40H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h104v40h48v-40h304v40h48v-40h104a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z\", \"M224 192h192a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32H224a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32zm32-128h128v64H256zm320 256H416a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128h-96v-64h96zM224 320H64a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128H96v-64h96z\"]],\n    \"planet-ringed\": [512, 512, [], \"e020\", [\"M323.33815,323.33517C186.95939,459.71018,46.2602,540.11093,9.06777,502.9165c-23.48893-23.4909.01172-88.30917,54.81792-167.21379a206.56361,206.56361,0,0,0,25.02022,43.78446c-22.45765,34.20607-32.036,58.99194-23.71941,67.31053,18.59817,18.59624,119.10094-51.75539,224.47885-157.13342C395.04325,184.2882,465.39675,83.78336,446.79858,65.18712c-8.32054-8.3186-33.10638,1.26176-67.31045,23.71748a206.52984,206.52984,0,0,0-43.78245-25.0183C414.61019,9.082,479.42839-14.42259,502.91732,9.06832,540.10975,46.2608,459.70909,186.96211,323.33815,323.33517Z\", \"M448.0994,176.28016c-31.96573,46.02281-74.52549,96.81528-124.76125,147.055-50.24357,50.24168-101.034,92.79954-147.05874,124.76531,75.41614,31.25675,165.47721,16.29343,226.79531-45.02474S479.35807,251.69834,448.0994,176.28016Zm-25.02022-43.78251A208.22535,208.22535,0,0,0,403.07472,108.911c-81.2288-81.23281-212.93555-81.23281-294.16435,0-81.22881,81.23085-81.22881,212.93385,0,294.1647A208.25527,208.25527,0,0,0,132.497,423.08023c42.25117-27.73908,98.93242-75.1799,157.1684-133.41595C347.90133,231.43018,395.34013,174.75473,423.07918,132.49765Z\"]],\n    \"question-circle\": [512, 512, [], \"f059\", [\"M256 8C119 8 8 119.08 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 422a46 46 0 1 1 46-46 46.05 46.05 0 0 1-46 46zm40-131.33V300a12 12 0 0 1-12 12h-56a12 12 0 0 1-12-12v-4c0-41.06 31.13-57.47 54.65-70.66 20.17-11.31 32.54-19 32.54-34 0-19.82-25.27-33-45.7-33-27.19 0-39.44 13.14-57.3 35.79a12 12 0 0 1-16.67 2.13L148.82 170a12 12 0 0 1-2.71-16.26C173.4 113 208.16 90 262.66 90c56.34 0 116.53 44 116.53 102 0 77-83.19 78.21-83.19 106.67z\", \"M256 338a46 46 0 1 0 46 46 46 46 0 0 0-46-46zm6.66-248c-54.5 0-89.26 23-116.55 63.76a12 12 0 0 0 2.71 16.24l34.7 26.31a12 12 0 0 0 16.67-2.13c17.86-22.65 30.11-35.79 57.3-35.79 20.43 0 45.7 13.14 45.7 33 0 15-12.37 22.66-32.54 34C247.13 238.53 216 254.94 216 296v4a12 12 0 0 0 12 12h56a12 12 0 0 0 12-12v-1.33c0-28.46 83.19-29.67 83.19-106.67 0-58-60.19-102-116.53-102z\"]],\n    \"quote-left\": [512, 512, [], \"f10d\", [\"M464 256h-80v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H448a160 160 0 0 0-160 160v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\", \"M176 256H96v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H160A160 160 0 0 0 0 192v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\"]],\n    \"random\": [512, 512, [], \"f074\", [\"M505 359l-80-80c-15-15-41-4.47-41 17v40h-32l-52.78-56.55-53.33 57.14 70.55 75.6a12 12 0 0 0 8.77 3.81H384v40c0 21.46 26 32 41 17l80-80a24 24 0 0 0 0-34zM122.79 96H12a12 12 0 0 0-12 12v56a12 12 0 0 0 12 12h84l52.78 56.55 53.33-57.14-70.55-75.6a12 12 0 0 0-8.77-3.81z\", \"M505 119a24 24 0 0 1 0 34l-80 80c-15 15-41 4.48-41-17v-40h-32L131.56 412.19a12 12 0 0 1-8.77 3.81H12a12 12 0 0 1-12-12v-56a12 12 0 0 1 12-12h84L316.44 99.81a12 12 0 0 1 8.78-3.81H384V56c0-21.44 25.94-32 41-17z\"]],\n    \"rocket\": [512, 512, [], \"f135\", [\"M51.94117,154.48438,2.531,253.29688A28.125,28.125,0,0,0-.00023,264a24.00619,24.00619,0,0,0,24,24H117.4607c23.44141-47.41211,61.01172-123.373,77.89063-157.32812.51953-.91407,1-1.76758,1.52344-2.67188H94.82008C78.47633,128.01562,59.28883,139.875,51.94117,154.48438Zm172.0586,240.1621V488.209A24.12394,24.12394,0,0,0,247.9607,512a28.02965,28.02965,0,0,0,10.625-2.53125l98.72657-49.39063c14.625-7.3125,26.5-26.5,26.5-42.85937V315.70312c.0664-.041.125-.08789.1875-.1289v-.52734c-.90625.51953-1.7461,1.002-2.66407,1.52539C347.37477,333.58008,271.2732,371.252,223.99977,394.64648Z\", \"M505.15992,19.51562A16.73971,16.73971,0,0,0,492.62477,6.94531C460.22633,0,434.37477,0,409.48414,0,320.3357,0,252.80836,40.61523,196.97633,127.81836c-.5586.97852-1.07031,1.877-1.625,2.85352-19.59766,39.42578-67.20313,135.70312-88.04688,177.877a31.91421,31.91421,0,0,0,6.09766,36.76172L167.05445,398.709a31.88923,31.88923,0,0,0,36.64844,5.98047l14.17578-7.01367c46.57422-23.04883,128.06641-63.3789,163.457-81.10351.96094-.54883,1.832-1.04883,2.78907-1.59766,87.23437-56.06055,127.85937-123.51172,127.85937-212.27734C512.06227,77.60742,512.12867,52.08789,505.15992,19.51562ZM367.99977,192a48,48,0,1,1,48-48.00195A48.02156,48.02156,0,0,1,367.99977,192Z\"]],\n    \"search\": [512, 512, [], \"f002\", [\"M208 80a128 128 0 1 1-90.51 37.49A127.15 127.15 0 0 1 208 80m0-80C93.12 0 0 93.12 0 208s93.12 208 208 208 208-93.12 208-208S322.88 0 208 0z\", \"M504.9 476.7L476.6 505a23.9 23.9 0 0 1-33.9 0L343 405.3a24 24 0 0 1-7-17V372l36-36h16.3a24 24 0 0 1 17 7l99.7 99.7a24.11 24.11 0 0 1-.1 34z\"]],\n    \"server\": [512, 512, [], \"f233\", [\"M432 120a24 24 0 1 0-24-24 24 24 0 0 0 24 24zm0 272a24 24 0 1 0 24 24 24 24 0 0 0-24-24zm48-200H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\", \"M456 256a24 24 0 1 0-24 24 24 24 0 0 0 24-24zm24-224H32A32 32 0 0 0 0 64v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm48 232H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\"]],\n    \"sign-out\": [512, 512, [], \"f08b\", [\"M180 448H96a96 96 0 0 1-96-96V160a96 96 0 0 1 96-96h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12H96a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12z\", \"M353 88.3l151.9 150.6a24 24 0 0 1 0 34.1l-152 150.8a24.08 24.08 0 0 1-33.9-.1l-21.9-21.9a24.07 24.07 0 0 1 .8-34.7l77.6-71.1H184a23.94 23.94 0 0 1-24-24v-32a23.94 23.94 0 0 1 24-24h191.5l-77.6-71.1a24 24 0 0 1-.7-34.6l21.9-21.9a24 24 0 0 1 33.9-.1z\"]],\n    \"siren-on\": [640, 512, [], \"e02e\", [\"M224.21,134.94a8,8,0,0,1,9-6.87l15.86,2.13a8,8,0,0,1,6.87,9L231.82,320H496L471,120.06A64,64,0,0,0,407.5,64h-175A64,64,0,0,0,169,120.06L144,320h55.54Z\", \"M528,352H112a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16H528a16,16,0,0,0,16-16V368A16,16,0,0,0,528,352ZM112,192a24,24,0,0,0-24-24H24a24,24,0,0,0,0,48H88A24,24,0,0,0,112,192Zm504-24H552a24,24,0,0,0,0,48h64a24,24,0,0,0,0-48ZM90.69,76a24,24,0,1,0,26.62-39.92l-48-32A24,24,0,1,0,42.69,44ZM536,80a23.87,23.87,0,0,0,13.29-4l48-32A24,24,0,1,0,570.69,4.06l-48,32A24,24,0,0,0,536,80Z\"]],\n    \"smile\": [496, 512, [], \"f118\", [\"M248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256,385,8,248,8Zm80,168a32,32,0,1,1-32,32A32,32,0,0,1,328,176Zm-160,0a32,32,0,1,1-32,32A32,32,0,0,1,168,176ZM362.8,346.2a149.38,149.38,0,0,1-229.6,0c-13.6-16.3,11-36.7,24.6-20.5a117.5,117.5,0,0,0,180.4,0C351.6,309.5,376.3,329.9,362.8,346.2Z\", \"M328,176a32,32,0,1,0,32,32A32,32,0,0,0,328,176Zm-160,0a32,32,0,1,0,32,32A32,32,0,0,0,168,176Z\"]],\n    \"snowman\": [512, 512, [], \"f7d0\", [\"M363.76 268.8a108.77 108.77 0 0 0 4.2-28.7v-.1a112.68 112.68 0 0 0-.73-12.8c-.11-1-.24-2-.38-3-.29-2-.62-4-1-6-.2-1-.4-1.95-.62-2.92-.22-1-.45-1.93-.7-2.9-.24-1-.5-1.91-.77-2.85-.27-.95-.55-1.89-.84-2.83-.3-.94-.6-1.87-.92-2.8-.32-.93-.65-1.86-1-2.77-.34-.92-.69-1.83-1.06-2.74-.36-.9-.74-1.8-1.13-2.7-.39-.89-.79-1.78-1.19-2.66-.41-.88-.83-1.76-1.26-2.63q-1.31-2.62-2.73-5.16c-.48-.85-1-1.68-1.46-2.51a112.44 112.44 0 0 0-21.62-26.19 96 96 0 1 0-149.16 0 112.49 112.49 0 0 0-21.68 26.28q-.74 1.23-1.44 2.49c-.48.84-.94 1.69-1.39 2.54-.45.85-.89 1.7-1.32 2.57-.43.87-.85 1.74-1.25 2.62-.41.88-.8 1.76-1.19 2.66-.39.89-.76 1.79-1.12 2.69-.36.91-.71 1.82-1.05 2.74-.34.92-.67 1.84-1 2.76a111.63 111.63 0 0 0-5.22 23.28A113 113 0 0 0 144 240h.06v.1a110.27 110.27 0 0 0 4.2 28.9A151.18 151.18 0 0 0 104 376.1c0 54 28.4 100.9 70.8 127.8 9.3 5.9 20.3 8.2 31.3 8.2h99.2a65.1 65.1 0 0 0 37.2-11.7c46.5-32.3 74.4-89.4 62.9-152.6-5.54-30.2-20.54-57.6-41.64-79zM224 96.1a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm32 272a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm0-64a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm1.7-64.1a15.19 15.19 0 0 1-3.48 0 16 16 0 1 1 3.48 0zm-1.7-87.9s-16-23.2-16-32a16 16 0 1 1 32 0c0 8.8-16 32-16 32zm32-56a16 16 0 1 1 16-16 16 16 0 0 1-16 16z\", \"M510.86 152.4L505 137.9a16.15 16.15 0 0 0-20.8-8.7L456 140.7v-29a15.84 15.84 0 0 0-16-15.6h-16a15.84 15.84 0 0 0-16 15.6v46.9c0 .5.3 1 .3 1.5l-56.1 22.54a111.21 111.21 0 0 1 15.07 44.56L502 172.7a15.57 15.57 0 0 0 8.86-20.3zm-407.1 6.2v-46.9c.2-8.6-7-15.6-15.8-15.6H72a15.84 15.84 0 0 0-16 15.6v29l-28.1-11.5a16.15 16.15 0 0 0-20.8 8.7l-5.9 14.5a15.48 15.48 0 0 0 8.9 20.3l134.67 54.49a111.3 111.3 0 0 1 15-44.46l-56.31-22.63a8 8 0 0 0 .3-1.5zM256 336.1a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16z\"]],\n    \"sun\": [512, 512, [], \"f185\", [\"M502.42 240.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.41-94.8a17.31 17.31 0 0 0-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4a17.31 17.31 0 0 0 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.41-33.5 47.3 94.7a17.31 17.31 0 0 0 31 0l47.31-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3a17.33 17.33 0 0 0 .2-31.1zm-155.9 106c-49.91 49.9-131.11 49.9-181 0a128.13 128.13 0 0 1 0-181c49.9-49.9 131.1-49.9 181 0a128.13 128.13 0 0 1 0 181z\", \"M352 256a96 96 0 1 1-96-96 96.15 96.15 0 0 1 96 96z\"]],\n    \"tasks\": [512, 512, [], \"f0ae\", [\"M496 384H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M139.61 35.5a12 12 0 0 0-17 0L58.93 98.81l-22.7-22.12a12 12 0 0 0-17 0L3.53 92.41a12 12 0 0 0 0 17l47.59 47.4a12.78 12.78 0 0 0 17.61 0l15.59-15.62L156.52 69a12.09 12.09 0 0 0 .09-17zm0 159.19a12 12 0 0 0-17 0l-63.68 63.72-22.7-22.1a12 12 0 0 0-17 0L3.53 252a12 12 0 0 0 0 17L51 316.5a12.77 12.77 0 0 0 17.6 0l15.7-15.69 72.2-72.22a12 12 0 0 0 .09-16.9zM64 368c-26.49 0-48.59 21.5-48.59 48S37.53 464 64 464a48 48 0 0 0 0-96z\"]],\n    \"university\": [512, 512, [], \"f19c\", [\"M160,192V384h64V192h64V384h64V192h64V384h36a12,12,0,0,1,12,12v20H48V396a12,12,0,0,1,12-12H96V192Z\", \"M491.06,120.61l-232-88a8,8,0,0,0-6.12,0l-232,88A8,8,0,0,0,16,128v16a8,8,0,0,0,8,8H48v12a12,12,0,0,0,12,12H452a12,12,0,0,0,12-12V152h24a8,8,0,0,0,8-8V128A8,8,0,0,0,491.06,120.61ZM472,432H40a24,24,0,0,0-24,24v16a8,8,0,0,0,8,8H488a8,8,0,0,0,8-8V456A24,24,0,0,0,472,432Z\"]],\n    \"user\": [448, 512, [], \"f007\", [\"M352 128A128 128 0 1 1 224 0a128 128 0 0 1 128 128z\", \"M313.6 288h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48v-41.6A134.43 134.43 0 0 0 313.6 288z\"]],\n    \"user-hard-hat\": [448, 512, [], \"f82c\", [\"M97.61 208h252.78c-7.95 63.06-61.17 112-126.39 112S105.56 271.06 97.61 208z\", \"M313.6 352h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.4 134.4 0 0 0 0 486.4 25.6 25.6 0 0 0 25.6 512h396.8a25.6 25.6 0 0 0 25.6-25.6A134.4 134.4 0 0 0 313.6 352zM88 176h272a8 8 0 0 0 8-8v-32a8 8 0 0 0-8-8h-8a112 112 0 0 0-68.4-103.2L256 80V16a16 16 0 0 0-16-16h-32a16 16 0 0 0-16 16v64l-27.6-55.2A112 112 0 0 0 96 128h-8a8 8 0 0 0-8 8v32a8 8 0 0 0 8 8z\"]],\n    \"user-shield\": [640, 512, [], \"f505\", [\"M622.3 271.1l-115.2-45a31 31 0 0 0-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9a31 31 0 0 0 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8z\", \"M224 256A128 128 0 1 0 96 128a128 128 0 0 0 128 128zm96 40c0-2.5.8-4.8 1.1-7.2-2.5-.1-4.9-.8-7.5-.8h-16.7a174.08 174.08 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a49.22 49.22 0 0 0 19.2-4c-54-42.9-99.2-116.7-99.2-212z\"]],\n    \"users\": [640, 512, [], \"f0c0\", [\"M96 224a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64zm480 32h-64a63.81 63.81 0 0 0-45.1 18.6A146.27 146.27 0 0 1 542 384h66a32 32 0 0 0 32-32v-32a64.06 64.06 0 0 0-64-64zm-512 0a64.06 64.06 0 0 0-64 64v32a32 32 0 0 0 32 32h65.9a146.64 146.64 0 0 1 75.2-109.4A63.81 63.81 0 0 0 128 256zm480-32a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64z\", \"M396.8 288h-8.3a157.53 157.53 0 0 1-68.5 16c-24.6 0-47.6-6-68.5-16h-8.3A115.23 115.23 0 0 0 128 403.2V432a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48v-28.8A115.23 115.23 0 0 0 396.8 288zM320 256a112 112 0 1 0-112-112 111.94 111.94 0 0 0 112 112z\"]]\n  };\n\n  bunker(function () {\n    defineIcons('fad', icons);\n  });\n\n}());\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"check-circle\": [512, 512, [], \"f058\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z\"],\n    \"desktop\": [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v288c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V54c0-3.3 2.7-6 6-6h468c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-42 152c0 13.3-10.7 24-24 24H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h98.7l18.6-55.8c1.6-4.9 6.2-8.2 11.4-8.2h78.7c5.2 0 9.8 3.3 11.4 8.2l18.6 55.8H456c13.3 0 24 10.7 24 24z\"],\n    \"eye\": [576, 512, [], \"f06e\", \"M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z\"],\n    \"file-code\": [384, 512, [], \"f1c9\", \"M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z\"],\n    \"info\": [256, 512, [], \"f129\", \"M224 352.589V224c0-16.475-6.258-31.517-16.521-42.872C225.905 161.14 236 135.346 236 108 236 48.313 187.697 0 128 0 68.313 0 20 48.303 20 108c0 20.882 5.886 40.859 16.874 58.037C15.107 176.264 0 198.401 0 224v39.314c0 23.641 12.884 44.329 32 55.411v33.864C12.884 363.671 0 384.359 0 408v40c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-40c0-23.641-12.884-44.329-32-55.411zM128 48c33.137 0 60 26.863 60 60s-26.863 60-60 60-60-26.863-60-60 26.863-60 60-60zm80 400c0 8.836-7.164 16-16 16H64c-8.836 0-16-7.164-16-16v-40c0-8.836 7.164-16 16-16h16V279.314H64c-8.836 0-16-7.164-16-16V224c0-8.836 7.164-16 16-16h96c8.836 0 16 7.164 16 16v168h16c8.836 0 16 7.164 16 16v40z\"],\n    \"info-circle\": [512, 512, [], \"f05a\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm0-338c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"],\n    \"plus\": [384, 512, [], \"f067\", \"M368 224H224V80c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h144v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V288h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"],\n    \"question-circle\": [512, 512, [], \"f059\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z\"],\n    \"rocket\": [512, 512, [], \"f135\", \"M367.96813,103.99609a39.999,39.999,0,1,0,40.00384,40A40.02908,40.02908,0,0,0,367.96813,103.99609ZM505.07337,19.3418c-1.21875-5.60742-6.75-11.13868-12.34373-12.3418-32.62885-7-58.162-7-83.57017-7C305.39988,0,242.95858,55.0918,196.236,127.99609H94.82015c-16.34567.01563-35.53314,11.875-42.87883,26.48243L2.53125,253.28906A28.12512,28.12512,0,0,0,0,263.99219a24.00617,24.00617,0,0,0,24.00191,23.998h92.63266l-10.59373,21.42188c-9.33592,18.91016,4.27733,34.77344,6.15624,36.62305l53.75381,53.71875c15.56443,15.54492,33.81635,7.52929,36.6601,6.13867l21.34567-10.57617V488a24.00659,24.00659,0,0,0,24.00191,24,28.618,28.618,0,0,0,10.71873-2.51562l98.6971-49.4043c14.625-7.29688,26.50191-26.5,26.50191-42.85938V315.69336c72.72449-46.76367,128.10525-109.44922,128.10525-212.69727C512.07531,77.4668,512.07531,51.99805,505.07337,19.3418ZM358.53065,274.99023c-36.94135,18.48438-121.10527,60.14063-166.7966,82.73243l-37.50189-37.49805c22.59567-45.6875,64.25575-129.99609,82.72447-166.88672C284.33741,79.5293,335.96623,47.99805,409.15947,47.99805c18.00192,0,34.2851,0,52.56632,2.34375,2.375,18.71875,2.31249,35.27929,2.25,52.63867C463.97578,175.75977,432.41138,227.30469,358.53065,274.99023Z\"],\n    \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z\"],\n    \"slash\": [640, 512, [], \"f715\", \"M604 508.49L6.01 40.98c-6.9-5.52-8.02-15.59-2.49-22.49L13.51 6C19.03-.9 29.1-2.01 36 3.51l598 467.51c6.9 5.52 8.02 15.59 2.49 22.49l-10 12.49c-5.52 6.9-15.59 8.01-22.49 2.49z\"],\n    \"times\": [320, 512, [], \"f00d\", \"M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z\"],\n    \"undo\": [512, 512, [], \"f0e2\", \"M12 8h27.711c6.739 0 12.157 5.548 11.997 12.286l-2.347 98.568C93.925 51.834 170.212 7.73 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.835 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.322 0 196-87.662 196-196 0-108.322-87.662-196-196-196-79.545 0-147.941 47.282-178.675 115.302l126.389-3.009c6.737-.16 12.286 5.257 12.286 11.997V212c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V20C0 13.373 5.373 8 12 8z\"],\n    \"undo-alt\": [512, 512, [], \"f2ea\", \"M28.485 28.485L80.65 80.65C125.525 35.767 187.515 8 255.999 8 392.66 8 504.1 119.525 504 256.185 503.9 393.067 392.905 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.353-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.321 0 196-87.662 196-196 0-108.321-87.662-196-196-196-54.163 0-103.157 21.923-138.614 57.386l54.128 54.129c7.56 7.56 2.206 20.485-8.485 20.485H20c-6.627 0-12-5.373-12-12V36.971c0-10.691 12.926-16.045 20.485-8.486z\"],\n    \"user\": [448, 512, [], \"f007\", \"M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z\"],\n    \"user-friends\": [640, 512, [], \"f500\", \"M480 256c53 0 96-43 96-96s-43-96-96-96-96 43-96 96 43 96 96 96zm0-144c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM272.1 276c-11.9 0-23.9 1.7-35.5 5.3-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-11.6-3.5-23.6-5.3-35.5-5.3-36.3 0-71.6 16.2-92.3 46.9C7.2 341.3 0 363.4 0 387.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM336 432H48v-44.8c0-28.9 18.4-53.6 44.1-63.1 10.3-3.8 21.6-3.7 31.9 0 22.1 7.9 45 11.9 68 11.9s45.8-4 68.1-11.9c10.3-3.7 21.6-3.8 31.9 0 25.7 9.4 44.1 34.2 44.1 63.1V432zM192 256c61.9 0 112-50.1 112-112S253.9 32 192 32 80 82.1 80 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm431.7 237.1C606.4 291.5 577 278 546.8 278c-27.8 0-34.8 10-66.8 10s-39-10-66.8-10c-13.3 0-26.2 3-38.2 8.1 5.8 5.9 11.3 12 16 18.9 4.7 7 8.6 14.4 12 22 3.3-.7 6.7-1.1 10.2-1.1 17.2 0 29.6 10 66.8 10 37.4 0 49.5-10 66.8-10 15.7 0 29.5 6.7 37.1 17.9 5.3 7.9 8.1 17.1 8.1 26.7V400H416v32c0 5.5-.6 10.8-1.6 16H600c22.1 0 40-17.9 40-40v-37.3c0-19.9-6-38.3-16.3-53.6z\"],\n    \"users\": [640, 512, [], \"f0c0\", \"M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zm396.4 210.9c-27.5-40.8-80.7-56-127.8-41.7-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-47.1-14.3-100.3.8-127.8 41.7-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c.2-23.8-7-45.9-19.4-64.3zM464 432H176v-44.8c0-36.4 29.2-66.2 65.4-67.2 25.5 10.6 51.9 16 78.6 16 26.7 0 53.1-5.4 78.6-16 36.2 1 65.4 30.7 65.4 67.2V432zm92-176h-24c-17.3 0-33.4 5.3-46.8 14.3 13.4 10.1 25.2 22.2 34.4 36.2 3.9-1.4 8-2.5 12.3-2.5h24c19.8 0 36 16.2 36 36 0 13.2 10.8 24 24 24s24-10.8 24-24c.1-46.3-37.6-84-83.9-84zm-236 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM154.8 270.3c-13.4-9-29.5-14.3-46.8-14.3H84c-46.3 0-84 37.7-84 84 0 13.2 10.8 24 24 24s24-10.8 24-24c0-19.8 16.2-36 36-36h24c4.4 0 8.5 1.1 12.3 2.5 9.3-14 21.1-26.1 34.5-36.2z\"]\n  };\n\n  bunker(function () {\n    defineIcons('far', icons);\n  });\n\n}());\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"alarm-exclamation\": [512, 512, [], \"f843\", \"M96 0A96 96 0 0 0 0 96a94.81 94.81 0 0 0 15.3 51.26L161.2 25.68A95.63 95.63 0 0 0 96 0zm320 0a95.66 95.66 0 0 0-65.18 25.66l145.89 121.57A94.85 94.85 0 0 0 512 96a96 96 0 0 0-96-96zM256 64C132.3 64 32 164.29 32 288a222.7 222.7 0 0 0 44.79 134l-40.1 40.09a16 16 0 0 0 0 22.63l22.62 22.62a16 16 0 0 0 22.63 0L122 467.22a222.82 222.82 0 0 0 268 0l40.1 40.09a16 16 0 0 0 22.62 0l22.63-22.62a16 16 0 0 0 0-22.63L435.25 422A222.69 222.69 0 0 0 480 288c0-123.71-100.26-224-224-224zm0 352a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm25.4-110.4a16 16 0 0 1-15.9 14.4h-19a16 16 0 0 1-15.9-14.4l-12.8-128a16.06 16.06 0 0 1 15.9-17.6h44.6a16 16 0 0 1 15.9 17.6z\"],\n    \"align-left\": [448, 512, [], \"f036\", \"M12.83 352h262.34A12.82 12.82 0 0 0 288 339.17v-38.34A12.82 12.82 0 0 0 275.17 288H12.83A12.82 12.82 0 0 0 0 300.83v38.34A12.82 12.82 0 0 0 12.83 352zm0-256h262.34A12.82 12.82 0 0 0 288 83.17V44.83A12.82 12.82 0 0 0 275.17 32H12.83A12.82 12.82 0 0 0 0 44.83v38.34A12.82 12.82 0 0 0 12.83 96zM432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"],\n    \"book-dead\": [448, 512, [], \"f6b7\", \"M272 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm176 222.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM240 56c44.2 0 80 28.7 80 64 0 20.9-12.7 39.2-32 50.9V184c0 8.8-7.2 16-16 16h-64c-8.8 0-16-7.2-16-16v-13.1c-19.3-11.7-32-30-32-50.9 0-35.3 35.8-64 80-64zM124.8 223.3l6.3-14.7c1.7-4.1 6.4-5.9 10.5-4.2l98.3 42.1 98.4-42.1c4.1-1.7 8.8.1 10.5 4.2l6.3 14.7c1.7 4.1-.1 8.8-4.2 10.5L280.6 264l70.3 30.1c4.1 1.7 5.9 6.4 4.2 10.5l-6.3 14.7c-1.7 4.1-6.4 5.9-10.5 4.2L240 281.4l-98.3 42.2c-4.1 1.7-8.8-.1-10.5-4.2l-6.3-14.7c-1.7-4.1.1-8.8 4.2-10.5l70.4-30.1-70.5-30.3c-4.1-1.7-5.9-6.4-4.2-10.5zm256 224.7H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8zM208 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16z\"],\n    \"check\": [512, 512, [], \"f00c\", \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"],\n    \"circle\": [512, 512, [], \"f111\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"],\n    \"cloud\": [640, 512, [], \"f0c2\", \"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z\"],\n    \"credit-card\": [576, 512, [], \"f09d\", \"M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z\"],\n    \"desktop\": [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z\"],\n    \"envelope\": [512, 512, [], \"f0e0\", \"M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z\"],\n    \"eye\": [576, 512, [], \"f06e\", \"M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z\"],\n    \"fingerprint\": [512, 512, [], \"f577\", \"M256.12 245.96c-13.25 0-24 10.74-24 24 1.14 72.25-8.14 141.9-27.7 211.55-2.73 9.72 2.15 30.49 23.12 30.49 10.48 0 20.11-6.92 23.09-17.52 13.53-47.91 31.04-125.41 29.48-224.52.01-13.25-10.73-24-23.99-24zm-.86-81.73C194 164.16 151.25 211.3 152.1 265.32c.75 47.94-3.75 95.91-13.37 142.55-2.69 12.98 5.67 25.69 18.64 28.36 13.05 2.67 25.67-5.66 28.36-18.64 10.34-50.09 15.17-101.58 14.37-153.02-.41-25.95 19.92-52.49 54.45-52.34 31.31.47 57.15 25.34 57.62 55.47.77 48.05-2.81 96.33-10.61 143.55-2.17 13.06 6.69 25.42 19.76 27.58 19.97 3.33 26.81-15.1 27.58-19.77 8.28-50.03 12.06-101.21 11.27-152.11-.88-55.8-47.94-101.88-104.91-102.72zm-110.69-19.78c-10.3-8.34-25.37-6.8-33.76 3.48-25.62 31.5-39.39 71.28-38.75 112 .59 37.58-2.47 75.27-9.11 112.05-2.34 13.05 6.31 25.53 19.36 27.89 20.11 3.5 27.07-14.81 27.89-19.36 7.19-39.84 10.5-80.66 9.86-121.33-.47-29.88 9.2-57.88 28-80.97 8.35-10.28 6.79-25.39-3.49-33.76zm109.47-62.33c-15.41-.41-30.87 1.44-45.78 4.97-12.89 3.06-20.87 15.98-17.83 28.89 3.06 12.89 16 20.83 28.89 17.83 11.05-2.61 22.47-3.77 34-3.69 75.43 1.13 137.73 61.5 138.88 134.58.59 37.88-1.28 76.11-5.58 113.63-1.5 13.17 7.95 25.08 21.11 26.58 16.72 1.95 25.51-11.88 26.58-21.11a929.06 929.06 0 0 0 5.89-119.85c-1.56-98.75-85.07-180.33-186.16-181.83zm252.07 121.45c-2.86-12.92-15.51-21.2-28.61-18.27-12.94 2.86-21.12 15.66-18.26 28.61 4.71 21.41 4.91 37.41 4.7 61.6-.11 13.27 10.55 24.09 23.8 24.2h.2c13.17 0 23.89-10.61 24-23.8.18-22.18.4-44.11-5.83-72.34zm-40.12-90.72C417.29 43.46 337.6 1.29 252.81.02 183.02-.82 118.47 24.91 70.46 72.94 24.09 119.37-.9 181.04.14 246.65l-.12 21.47c-.39 13.25 10.03 24.31 23.28 24.69.23.02.48.02.72.02 12.92 0 23.59-10.3 23.97-23.3l.16-23.64c-.83-52.5 19.16-101.86 56.28-139 38.76-38.8 91.34-59.67 147.68-58.86 69.45 1.03 134.73 35.56 174.62 92.39 7.61 10.86 22.56 13.45 33.42 5.86 10.84-7.62 13.46-22.59 5.84-33.43z\"],\n    \"history\": [512, 512, [], \"f1da\", \"M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z\"],\n    \"home\": [576, 512, [], \"f015\", \"M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z\"],\n    \"plus\": [448, 512, [], \"f067\", \"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"],\n    \"robot\": [640, 512, [], \"f544\", \"M32,224H64V416H32A31.96166,31.96166,0,0,1,0,384V256A31.96166,31.96166,0,0,1,32,224Zm512-48V448a64.06328,64.06328,0,0,1-64,64H160a64.06328,64.06328,0,0,1-64-64V176a79.974,79.974,0,0,1,80-80H288V32a32,32,0,0,1,64,0V96H464A79.974,79.974,0,0,1,544,176ZM264,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,264,256Zm-8,128H192v32h64Zm96,0H288v32h64ZM456,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,456,256Zm-8,128H384v32h64ZM640,256V384a31.96166,31.96166,0,0,1-32,32H576V224h32A31.96166,31.96166,0,0,1,640,256Z\"],\n    \"rocket\": [512, 512, [], \"f135\", \"M505.12019,19.09375c-1.18945-5.53125-6.65819-11-12.207-12.1875C460.716,0,435.507,0,410.40747,0,307.17523,0,245.26909,55.20312,199.05238,128H94.83772c-16.34763.01562-35.55658,11.875-42.88664,26.48438L2.51562,253.29688A28.4,28.4,0,0,0,0,264a24.00867,24.00867,0,0,0,24.00582,24H127.81618l-22.47457,22.46875c-11.36521,11.36133-12.99607,32.25781,0,45.25L156.24582,406.625c11.15623,11.1875,32.15619,13.15625,45.27726,0l22.47457-22.46875V488a24.00867,24.00867,0,0,0,24.00581,24,28.55934,28.55934,0,0,0,10.707-2.51562l98.72834-49.39063c14.62888-7.29687,26.50776-26.5,26.50776-42.85937V312.79688c72.59753-46.3125,128.03493-108.40626,128.03493-211.09376C512.07526,76.5,512.07526,51.29688,505.12019,19.09375ZM384.04033,168A40,40,0,1,1,424.05,128,40.02322,40.02322,0,0,1,384.04033,168Z\"],\n    \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"],\n    \"slash\": [640, 512, [], \"f715\", \"M594.53 508.63L6.18 53.9c-6.97-5.42-8.23-15.47-2.81-22.45L23.01 6.18C28.43-.8 38.49-2.06 45.47 3.37L633.82 458.1c6.97 5.42 8.23 15.47 2.81 22.45l-19.64 25.27c-5.42 6.98-15.48 8.23-22.46 2.81z\"],\n    \"spinner-third\": [512, 512, [], \"f3f4\", \"M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z\"],\n    \"square-full\": [512, 512, [], \"f45c\", \"M512 512H0V0h512v512z\"],\n    \"times\": [352, 512, [], \"f00d\", \"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\"],\n    \"times-circle\": [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"],\n    \"undo\": [512, 512, [], \"f0e2\", \"M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z\"],\n    \"undo-alt\": [512, 512, [], \"f2ea\", \"M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z\"],\n    \"user\": [448, 512, [], \"f007\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"],\n    \"users\": [640, 512, [], \"f0c0\", \"M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z\"]\n  };\n\n  bunker(function () {\n    defineIcons('fas', icons);\n  });\n\n}());\n(function () {\n  'use strict';\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _typeof(obj) {\n    \"@babel/helpers - typeof\";\n\n    if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n      _typeof = function (obj) {\n        return typeof obj;\n      };\n    } else {\n      _typeof = function (obj) {\n        return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n      };\n    }\n\n    return _typeof(obj);\n  }\n\n  function _classCallCheck(instance, Constructor) {\n    if (!(instance instanceof Constructor)) {\n      throw new TypeError(\"Cannot call a class as a function\");\n    }\n  }\n\n  function _defineProperties(target, props) {\n    for (var i = 0; i < props.length; i++) {\n      var descriptor = props[i];\n      descriptor.enumerable = descriptor.enumerable || false;\n      descriptor.configurable = true;\n      if (\"value\" in descriptor) descriptor.writable = true;\n      Object.defineProperty(target, descriptor.key, descriptor);\n    }\n  }\n\n  function _createClass(Constructor, protoProps, staticProps) {\n    if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n    if (staticProps) _defineProperties(Constructor, staticProps);\n    return Constructor;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  function _slicedToArray(arr, i) {\n    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n  }\n\n  function _toConsumableArray(arr) {\n    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n  }\n\n  function _arrayWithoutHoles(arr) {\n    if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n  }\n\n  function _arrayWithHoles(arr) {\n    if (Array.isArray(arr)) return arr;\n  }\n\n  function _iterableToArray(iter) {\n    if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n  }\n\n  function _iterableToArrayLimit(arr, i) {\n    var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n    if (_i == null) return;\n    var _arr = [];\n    var _n = true;\n    var _d = false;\n\n    var _s, _e;\n\n    try {\n      for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n        _arr.push(_s.value);\n\n        if (i && _arr.length === i) break;\n      }\n    } catch (err) {\n      _d = true;\n      _e = err;\n    } finally {\n      try {\n        if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n      } finally {\n        if (_d) throw _e;\n      }\n    }\n\n    return _arr;\n  }\n\n  function _unsupportedIterableToArray(o, minLen) {\n    if (!o) return;\n    if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n    var n = Object.prototype.toString.call(o).slice(8, -1);\n    if (n === \"Object\" && o.constructor) n = o.constructor.name;\n    if (n === \"Map\" || n === \"Set\") return Array.from(o);\n    if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n  }\n\n  function _arrayLikeToArray(arr, len) {\n    if (len == null || len > arr.length) len = arr.length;\n\n    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n\n    return arr2;\n  }\n\n  function _nonIterableSpread() {\n    throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n\n  function _nonIterableRest() {\n    throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n\n  var noop = function noop() {};\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n  var _MUTATION_OBSERVER = null;\n  var _PERFORMANCE = {\n    mark: noop,\n    measure: noop\n  };\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n    if (typeof MutationObserver !== 'undefined') _MUTATION_OBSERVER = MutationObserver;\n    if (typeof performance !== 'undefined') _PERFORMANCE = performance;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var MUTATION_OBSERVER = _MUTATION_OBSERVER;\n  var PERFORMANCE = _PERFORMANCE;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var UNITS_IN_GRID = 16;\n  var DEFAULT_FAMILY_PREFIX = 'fa';\n  var DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa';\n  var DATA_FA_I2SVG = 'data-fa-i2svg';\n  var DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element';\n  var DATA_FA_PSEUDO_ELEMENT_PENDING = 'data-fa-pseudo-element-pending';\n  var DATA_PREFIX = 'data-prefix';\n  var DATA_ICON = 'data-icon';\n  var HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg';\n  var MUTATION_APPROACH_ASYNC = 'async';\n  var TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS = ['HTML', 'HEAD', 'STYLE', 'SCRIPT'];\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n  var PREFIX_TO_STYLE = {\n    'fas': 'solid',\n    'far': 'regular',\n    'fal': 'light',\n    'fad': 'duotone',\n    'fab': 'brands',\n    'fak': 'kit',\n    'fa': 'solid'\n  };\n  var STYLE_TO_PREFIX = {\n    'solid': 'fas',\n    'regular': 'far',\n    'light': 'fal',\n    'duotone': 'fad',\n    'brands': 'fab',\n    'kit': 'fak'\n  };\n  var LAYERS_TEXT_CLASSNAME = 'fa-layers-text';\n  var FONT_FAMILY_PATTERN = /Font Awesome ([5 ]*)(Solid|Regular|Light|Duotone|Brands|Free|Pro|Kit).*/i; // TODO: do we need to handle font-weight for kit SVG pseudo-elements?\n\n  var FONT_WEIGHT_TO_PREFIX = {\n    '900': 'fas',\n    '400': 'far',\n    'normal': 'far',\n    '300': 'fal'\n  };\n  var oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n  var oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);\n  var ATTRIBUTES_WATCHED_FOR_MUTATION = ['class', 'data-prefix', 'data-icon', 'data-fa-transform', 'data-fa-mask'];\n  var DUOTONE_CLASSES = {\n    GROUP: 'group',\n    SWAP_OPACITY: 'swap-opacity',\n    PRIMARY: 'primary',\n    SECONDARY: 'secondary'\n  };\n  var RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'flip-both', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter', DUOTONE_CLASSES.GROUP, DUOTONE_CLASSES.SWAP_OPACITY, DUOTONE_CLASSES.PRIMARY, DUOTONE_CLASSES.SECONDARY].concat(oneToTen.map(function (n) {\n    return \"\".concat(n, \"x\");\n  })).concat(oneToTwenty.map(function (n) {\n    return \"w-\".concat(n);\n  }));\n\n  var initial = WINDOW.FontAwesomeConfig || {};\n\n  function getAttrConfig(attr) {\n    var element = DOCUMENT.querySelector('script[' + attr + ']');\n\n    if (element) {\n      return element.getAttribute(attr);\n    }\n  }\n\n  function coerce(val) {\n    // Getting an empty string will occur if the attribute is set on the HTML tag but without a value\n    // We'll assume that this is an indication that it should be toggled to true\n    // For example <script data-search-pseudo-elements src=\"...\"></script>\n    if (val === '') return true;\n    if (val === 'false') return false;\n    if (val === 'true') return true;\n    return val;\n  }\n\n  if (DOCUMENT && typeof DOCUMENT.querySelector === 'function') {\n    var attrs = [['data-family-prefix', 'familyPrefix'], ['data-replacement-class', 'replacementClass'], ['data-auto-replace-svg', 'autoReplaceSvg'], ['data-auto-add-css', 'autoAddCss'], ['data-auto-a11y', 'autoA11y'], ['data-search-pseudo-elements', 'searchPseudoElements'], ['data-observe-mutations', 'observeMutations'], ['data-mutate-approach', 'mutateApproach'], ['data-keep-original-source', 'keepOriginalSource'], ['data-measure-performance', 'measurePerformance'], ['data-show-missing-icons', 'showMissingIcons']];\n    attrs.forEach(function (_ref) {\n      var _ref2 = _slicedToArray(_ref, 2),\n          attr = _ref2[0],\n          key = _ref2[1];\n\n      var val = coerce(getAttrConfig(attr));\n\n      if (val !== undefined && val !== null) {\n        initial[key] = val;\n      }\n    });\n  }\n\n  var _default = {\n    familyPrefix: DEFAULT_FAMILY_PREFIX,\n    replacementClass: DEFAULT_REPLACEMENT_CLASS,\n    autoReplaceSvg: true,\n    autoAddCss: true,\n    autoA11y: true,\n    searchPseudoElements: false,\n    observeMutations: true,\n    mutateApproach: 'async',\n    keepOriginalSource: true,\n    measurePerformance: false,\n    showMissingIcons: true\n  };\n\n  var _config = _objectSpread2(_objectSpread2({}, _default), initial);\n\n  if (!_config.autoReplaceSvg) _config.observeMutations = false;\n\n  var config = _objectSpread2({}, _config);\n\n  WINDOW.FontAwesomeConfig = config;\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  var functions = [];\n\n  var listener = function listener() {\n    DOCUMENT.removeEventListener('DOMContentLoaded', listener);\n    loaded = 1;\n    functions.map(function (fn) {\n      return fn();\n    });\n  };\n\n  var loaded = false;\n\n  if (IS_DOM) {\n    loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);\n    if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);\n  }\n\n  function domready (fn) {\n    if (!IS_DOM) return;\n    loaded ? setTimeout(fn, 0) : functions.push(fn);\n  }\n\n  var PENDING = 'pending';\n  var SETTLED = 'settled';\n  var FULFILLED = 'fulfilled';\n  var REJECTED = 'rejected';\n\n  var NOOP = function NOOP() {};\n\n  var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function';\n  var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate;\n  var asyncQueue = [];\n  var asyncTimer;\n\n  function asyncFlush() {\n    // run promise callbacks\n    for (var i = 0; i < asyncQueue.length; i++) {\n      asyncQueue[i][0](asyncQueue[i][1]);\n    } // reset async asyncQueue\n\n\n    asyncQueue = [];\n    asyncTimer = false;\n  }\n\n  function asyncCall(callback, arg) {\n    asyncQueue.push([callback, arg]);\n\n    if (!asyncTimer) {\n      asyncTimer = true;\n      asyncSetTimer(asyncFlush, 0);\n    }\n  }\n\n  function invokeResolver(resolver, promise) {\n    function resolvePromise(value) {\n      resolve(promise, value);\n    }\n\n    function rejectPromise(reason) {\n      reject(promise, reason);\n    }\n\n    try {\n      resolver(resolvePromise, rejectPromise);\n    } catch (e) {\n      rejectPromise(e);\n    }\n  }\n\n  function invokeCallback(subscriber) {\n    var owner = subscriber.owner;\n    var settled = owner._state;\n    var value = owner._data;\n    var callback = subscriber[settled];\n    var promise = subscriber.then;\n\n    if (typeof callback === 'function') {\n      settled = FULFILLED;\n\n      try {\n        value = callback(value);\n      } catch (e) {\n        reject(promise, e);\n      }\n    }\n\n    if (!handleThenable(promise, value)) {\n      if (settled === FULFILLED) {\n        resolve(promise, value);\n      }\n\n      if (settled === REJECTED) {\n        reject(promise, value);\n      }\n    }\n  }\n\n  function handleThenable(promise, value) {\n    var resolved;\n\n    try {\n      if (promise === value) {\n        throw new TypeError('A promises callback cannot return that same promise.');\n      }\n\n      if (value && (typeof value === 'function' || _typeof(value) === 'object')) {\n        // then should be retrieved only once\n        var then = value.then;\n\n        if (typeof then === 'function') {\n          then.call(value, function (val) {\n            if (!resolved) {\n              resolved = true;\n\n              if (value === val) {\n                fulfill(promise, val);\n              } else {\n                resolve(promise, val);\n              }\n            }\n          }, function (reason) {\n            if (!resolved) {\n              resolved = true;\n              reject(promise, reason);\n            }\n          });\n          return true;\n        }\n      }\n    } catch (e) {\n      if (!resolved) {\n        reject(promise, e);\n      }\n\n      return true;\n    }\n\n    return false;\n  }\n\n  function resolve(promise, value) {\n    if (promise === value || !handleThenable(promise, value)) {\n      fulfill(promise, value);\n    }\n  }\n\n  function fulfill(promise, value) {\n    if (promise._state === PENDING) {\n      promise._state = SETTLED;\n      promise._data = value;\n      asyncCall(publishFulfillment, promise);\n    }\n  }\n\n  function reject(promise, reason) {\n    if (promise._state === PENDING) {\n      promise._state = SETTLED;\n      promise._data = reason;\n      asyncCall(publishRejection, promise);\n    }\n  }\n\n  function publish(promise) {\n    promise._then = promise._then.forEach(invokeCallback);\n  }\n\n  function publishFulfillment(promise) {\n    promise._state = FULFILLED;\n    publish(promise);\n  }\n\n  function publishRejection(promise) {\n    promise._state = REJECTED;\n    publish(promise);\n\n    if (!promise._handled && isNode) {\n      global.process.emit('unhandledRejection', promise._data, promise);\n    }\n  }\n\n  function notifyRejectionHandled(promise) {\n    global.process.emit('rejectionHandled', promise);\n  }\n  /**\n   * @class\n   */\n\n\n  function P(resolver) {\n    if (typeof resolver !== 'function') {\n      throw new TypeError('Promise resolver ' + resolver + ' is not a function');\n    }\n\n    if (this instanceof P === false) {\n      throw new TypeError('Failed to construct \\'Promise\\': Please use the \\'new\\' operator, this object constructor cannot be called as a function.');\n    }\n\n    this._then = [];\n    invokeResolver(resolver, this);\n  }\n\n  P.prototype = {\n    constructor: P,\n    _state: PENDING,\n    _then: null,\n    _data: undefined,\n    _handled: false,\n    then: function then(onFulfillment, onRejection) {\n      var subscriber = {\n        owner: this,\n        then: new this.constructor(NOOP),\n        fulfilled: onFulfillment,\n        rejected: onRejection\n      };\n\n      if ((onRejection || onFulfillment) && !this._handled) {\n        this._handled = true;\n\n        if (this._state === REJECTED && isNode) {\n          asyncCall(notifyRejectionHandled, this);\n        }\n      }\n\n      if (this._state === FULFILLED || this._state === REJECTED) {\n        // already resolved, call callback async\n        asyncCall(invokeCallback, subscriber);\n      } else {\n        // subscribe\n        this._then.push(subscriber);\n      }\n\n      return subscriber.then;\n    },\n    catch: function _catch(onRejection) {\n      return this.then(null, onRejection);\n    }\n  };\n\n  P.all = function (promises) {\n    if (!Array.isArray(promises)) {\n      throw new TypeError('You must pass an array to Promise.all().');\n    }\n\n    return new P(function (resolve, reject) {\n      var results = [];\n      var remaining = 0;\n\n      function resolver(index) {\n        remaining++;\n        return function (value) {\n          results[index] = value;\n\n          if (! --remaining) {\n            resolve(results);\n          }\n        };\n      }\n\n      for (var i = 0, promise; i < promises.length; i++) {\n        promise = promises[i];\n\n        if (promise && typeof promise.then === 'function') {\n          promise.then(resolver(i), reject);\n        } else {\n          results[i] = promise;\n        }\n      }\n\n      if (!remaining) {\n        resolve(results);\n      }\n    });\n  };\n\n  P.race = function (promises) {\n    if (!Array.isArray(promises)) {\n      throw new TypeError('You must pass an array to Promise.race().');\n    }\n\n    return new P(function (resolve, reject) {\n      for (var i = 0, promise; i < promises.length; i++) {\n        promise = promises[i];\n\n        if (promise && typeof promise.then === 'function') {\n          promise.then(resolve, reject);\n        } else {\n          resolve(promise);\n        }\n      }\n    });\n  };\n\n  P.resolve = function (value) {\n    if (value && _typeof(value) === 'object' && value.constructor === P) {\n      return value;\n    }\n\n    return new P(function (resolve) {\n      resolve(value);\n    });\n  };\n\n  P.reject = function (reason) {\n    return new P(function (resolve, reject) {\n      reject(reason);\n    });\n  };\n\n  var picked = typeof Promise === 'function' ? Promise : P;\n\n  var d = UNITS_IN_GRID;\n  var meaninglessTransform = {\n    size: 16,\n    x: 0,\n    y: 0,\n    rotate: 0,\n    flipX: false,\n    flipY: false\n  };\n\n  function isReserved(name) {\n    return ~RESERVED_CLASSES.indexOf(name);\n  }\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n  function insertCss(css) {\n    if (!css || !IS_DOM) {\n      return;\n    }\n\n    var style = DOCUMENT.createElement('style');\n    style.setAttribute('type', 'text/css');\n    style.innerHTML = css;\n    var headChildren = DOCUMENT.head.childNodes;\n    var beforeChild = null;\n\n    for (var i = headChildren.length - 1; i > -1; i--) {\n      var child = headChildren[i];\n      var tagName = (child.tagName || '').toUpperCase();\n\n      if (['STYLE', 'LINK'].indexOf(tagName) > -1) {\n        beforeChild = child;\n      }\n    }\n\n    DOCUMENT.head.insertBefore(style, beforeChild);\n    return css;\n  }\n  var idPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n  function nextUniqueId() {\n    var size = 12;\n    var id = '';\n\n    while (size-- > 0) {\n      id += idPool[Math.random() * 62 | 0];\n    }\n\n    return id;\n  }\n  function toArray(obj) {\n    var array = [];\n\n    for (var i = (obj || []).length >>> 0; i--;) {\n      array[i] = obj[i];\n    }\n\n    return array;\n  }\n  function classArray(node) {\n    if (node.classList) {\n      return toArray(node.classList);\n    } else {\n      return (node.getAttribute('class') || '').split(' ').filter(function (i) {\n        return i;\n      });\n    }\n  }\n  function getIconName(familyPrefix, cls) {\n    var parts = cls.split('-');\n    var prefix = parts[0];\n    var iconName = parts.slice(1).join('-');\n\n    if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) {\n      return iconName;\n    } else {\n      return null;\n    }\n  }\n  function htmlEscape(str) {\n    return \"\".concat(str).replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n  }\n  function joinAttributes(attributes) {\n    return Object.keys(attributes || {}).reduce(function (acc, attributeName) {\n      return acc + \"\".concat(attributeName, \"=\\\"\").concat(htmlEscape(attributes[attributeName]), \"\\\" \");\n    }, '').trim();\n  }\n  function joinStyles(styles) {\n    return Object.keys(styles || {}).reduce(function (acc, styleName) {\n      return acc + \"\".concat(styleName, \": \").concat(styles[styleName], \";\");\n    }, '');\n  }\n  function transformIsMeaningful(transform) {\n    return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY;\n  }\n  function transformForSvg(_ref) {\n    var transform = _ref.transform,\n        containerWidth = _ref.containerWidth,\n        iconWidth = _ref.iconWidth;\n    var outer = {\n      transform: \"translate(\".concat(containerWidth / 2, \" 256)\")\n    };\n    var innerTranslate = \"translate(\".concat(transform.x * 32, \", \").concat(transform.y * 32, \") \");\n    var innerScale = \"scale(\".concat(transform.size / 16 * (transform.flipX ? -1 : 1), \", \").concat(transform.size / 16 * (transform.flipY ? -1 : 1), \") \");\n    var innerRotate = \"rotate(\".concat(transform.rotate, \" 0 0)\");\n    var inner = {\n      transform: \"\".concat(innerTranslate, \" \").concat(innerScale, \" \").concat(innerRotate)\n    };\n    var path = {\n      transform: \"translate(\".concat(iconWidth / 2 * -1, \" -256)\")\n    };\n    return {\n      outer: outer,\n      inner: inner,\n      path: path\n    };\n  }\n  function transformForCss(_ref2) {\n    var transform = _ref2.transform,\n        _ref2$width = _ref2.width,\n        width = _ref2$width === void 0 ? UNITS_IN_GRID : _ref2$width,\n        _ref2$height = _ref2.height,\n        height = _ref2$height === void 0 ? UNITS_IN_GRID : _ref2$height,\n        _ref2$startCentered = _ref2.startCentered,\n        startCentered = _ref2$startCentered === void 0 ? false : _ref2$startCentered;\n    var val = '';\n\n    if (startCentered && IS_IE) {\n      val += \"translate(\".concat(transform.x / d - width / 2, \"em, \").concat(transform.y / d - height / 2, \"em) \");\n    } else if (startCentered) {\n      val += \"translate(calc(-50% + \".concat(transform.x / d, \"em), calc(-50% + \").concat(transform.y / d, \"em)) \");\n    } else {\n      val += \"translate(\".concat(transform.x / d, \"em, \").concat(transform.y / d, \"em) \");\n    }\n\n    val += \"scale(\".concat(transform.size / d * (transform.flipX ? -1 : 1), \", \").concat(transform.size / d * (transform.flipY ? -1 : 1), \") \");\n    val += \"rotate(\".concat(transform.rotate, \"deg) \");\n    return val;\n  }\n\n  var ALL_SPACE = {\n    x: 0,\n    y: 0,\n    width: '100%',\n    height: '100%'\n  };\n\n  function fillBlack(abstract) {\n    var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n    if (abstract.attributes && (abstract.attributes.fill || force)) {\n      abstract.attributes.fill = 'black';\n    }\n\n    return abstract;\n  }\n\n  function deGroup(abstract) {\n    if (abstract.tag === 'g') {\n      return abstract.children;\n    } else {\n      return [abstract];\n    }\n  }\n\n  function makeIconMasking (_ref) {\n    var children = _ref.children,\n        attributes = _ref.attributes,\n        main = _ref.main,\n        mask = _ref.mask,\n        explicitMaskId = _ref.maskId,\n        transform = _ref.transform;\n    var mainWidth = main.width,\n        mainPath = main.icon;\n    var maskWidth = mask.width,\n        maskPath = mask.icon;\n    var trans = transformForSvg({\n      transform: transform,\n      containerWidth: maskWidth,\n      iconWidth: mainWidth\n    });\n    var maskRect = {\n      tag: 'rect',\n      attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n        fill: 'white'\n      })\n    };\n    var maskInnerGroupChildrenMixin = mainPath.children ? {\n      children: mainPath.children.map(fillBlack)\n    } : {};\n    var maskInnerGroup = {\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.inner),\n      children: [fillBlack(_objectSpread2({\n        tag: mainPath.tag,\n        attributes: _objectSpread2(_objectSpread2({}, mainPath.attributes), trans.path)\n      }, maskInnerGroupChildrenMixin))]\n    };\n    var maskOuterGroup = {\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.outer),\n      children: [maskInnerGroup]\n    };\n    var maskId = \"mask-\".concat(explicitMaskId || nextUniqueId());\n    var clipId = \"clip-\".concat(explicitMaskId || nextUniqueId());\n    var maskTag = {\n      tag: 'mask',\n      attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n        id: maskId,\n        maskUnits: 'userSpaceOnUse',\n        maskContentUnits: 'userSpaceOnUse'\n      }),\n      children: [maskRect, maskOuterGroup]\n    };\n    var defs = {\n      tag: 'defs',\n      children: [{\n        tag: 'clipPath',\n        attributes: {\n          id: clipId\n        },\n        children: deGroup(maskPath)\n      }, maskTag]\n    };\n    children.push(defs, {\n      tag: 'rect',\n      attributes: _objectSpread2({\n        fill: 'currentColor',\n        'clip-path': \"url(#\".concat(clipId, \")\"),\n        mask: \"url(#\".concat(maskId, \")\")\n      }, ALL_SPACE)\n    });\n    return {\n      children: children,\n      attributes: attributes\n    };\n  }\n\n  function makeIconStandard (_ref) {\n    var children = _ref.children,\n        attributes = _ref.attributes,\n        main = _ref.main,\n        transform = _ref.transform,\n        styles = _ref.styles;\n    var styleString = joinStyles(styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    if (transformIsMeaningful(transform)) {\n      var trans = transformForSvg({\n        transform: transform,\n        containerWidth: main.width,\n        iconWidth: main.width\n      });\n      children.push({\n        tag: 'g',\n        attributes: _objectSpread2({}, trans.outer),\n        children: [{\n          tag: 'g',\n          attributes: _objectSpread2({}, trans.inner),\n          children: [{\n            tag: main.icon.tag,\n            children: main.icon.children,\n            attributes: _objectSpread2(_objectSpread2({}, main.icon.attributes), trans.path)\n          }]\n        }]\n      });\n    } else {\n      children.push(main.icon);\n    }\n\n    return {\n      children: children,\n      attributes: attributes\n    };\n  }\n\n  function asIcon (_ref) {\n    var children = _ref.children,\n        main = _ref.main,\n        mask = _ref.mask,\n        attributes = _ref.attributes,\n        styles = _ref.styles,\n        transform = _ref.transform;\n\n    if (transformIsMeaningful(transform) && main.found && !mask.found) {\n      var width = main.width,\n          height = main.height;\n      var offset = {\n        x: width / height / 2,\n        y: 0.5\n      };\n      attributes['style'] = joinStyles(_objectSpread2(_objectSpread2({}, styles), {}, {\n        'transform-origin': \"\".concat(offset.x + transform.x / 16, \"em \").concat(offset.y + transform.y / 16, \"em\")\n      }));\n    }\n\n    return [{\n      tag: 'svg',\n      attributes: attributes,\n      children: children\n    }];\n  }\n\n  function asSymbol (_ref) {\n    var prefix = _ref.prefix,\n        iconName = _ref.iconName,\n        children = _ref.children,\n        attributes = _ref.attributes,\n        symbol = _ref.symbol;\n    var id = symbol === true ? \"\".concat(prefix, \"-\").concat(config.familyPrefix, \"-\").concat(iconName) : symbol;\n    return [{\n      tag: 'svg',\n      attributes: {\n        style: 'display: none;'\n      },\n      children: [{\n        tag: 'symbol',\n        attributes: _objectSpread2(_objectSpread2({}, attributes), {}, {\n          id: id\n        }),\n        children: children\n      }]\n    }];\n  }\n\n  function makeInlineSvgAbstract(params) {\n    var _params$icons = params.icons,\n        main = _params$icons.main,\n        mask = _params$icons.mask,\n        prefix = params.prefix,\n        iconName = params.iconName,\n        transform = params.transform,\n        symbol = params.symbol,\n        title = params.title,\n        maskId = params.maskId,\n        titleId = params.titleId,\n        extra = params.extra,\n        _params$watchable = params.watchable,\n        watchable = _params$watchable === void 0 ? false : _params$watchable;\n\n    var _ref = mask.found ? mask : main,\n        width = _ref.width,\n        height = _ref.height;\n\n    var isUploadedIcon = prefix === 'fak';\n    var widthClass = isUploadedIcon ? '' : \"fa-w-\".concat(Math.ceil(width / height * 16));\n    var attrClass = [config.replacementClass, iconName ? \"\".concat(config.familyPrefix, \"-\").concat(iconName) : '', widthClass].filter(function (c) {\n      return extra.classes.indexOf(c) === -1;\n    }).filter(function (c) {\n      return c !== '' || !!c;\n    }).concat(extra.classes).join(' ');\n    var content = {\n      children: [],\n      attributes: _objectSpread2(_objectSpread2({}, extra.attributes), {}, {\n        'data-prefix': prefix,\n        'data-icon': iconName,\n        'class': attrClass,\n        'role': extra.attributes.role || 'img',\n        'xmlns': 'http://www.w3.org/2000/svg',\n        'viewBox': \"0 0 \".concat(width, \" \").concat(height)\n      })\n    };\n    var uploadedIconWidthStyle = isUploadedIcon && !~extra.classes.indexOf('fa-fw') ? {\n      width: \"\".concat(width / height * 16 * 0.0625, \"em\")\n    } : {};\n\n    if (watchable) {\n      content.attributes[DATA_FA_I2SVG] = '';\n    }\n\n    if (title) content.children.push({\n      tag: 'title',\n      attributes: {\n        id: content.attributes['aria-labelledby'] || \"title-\".concat(titleId || nextUniqueId())\n      },\n      children: [title]\n    });\n\n    var args = _objectSpread2(_objectSpread2({}, content), {}, {\n      prefix: prefix,\n      iconName: iconName,\n      main: main,\n      mask: mask,\n      maskId: maskId,\n      transform: transform,\n      symbol: symbol,\n      styles: _objectSpread2(_objectSpread2({}, uploadedIconWidthStyle), extra.styles)\n    });\n\n    var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args),\n        children = _ref2.children,\n        attributes = _ref2.attributes;\n\n    args.children = children;\n    args.attributes = attributes;\n\n    if (symbol) {\n      return asSymbol(args);\n    } else {\n      return asIcon(args);\n    }\n  }\n  function makeLayersTextAbstract(params) {\n    var content = params.content,\n        width = params.width,\n        height = params.height,\n        transform = params.transform,\n        title = params.title,\n        extra = params.extra,\n        _params$watchable2 = params.watchable,\n        watchable = _params$watchable2 === void 0 ? false : _params$watchable2;\n\n    var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n      'title': title\n    } : {}), {}, {\n      'class': extra.classes.join(' ')\n    });\n\n    if (watchable) {\n      attributes[DATA_FA_I2SVG] = '';\n    }\n\n    var styles = _objectSpread2({}, extra.styles);\n\n    if (transformIsMeaningful(transform)) {\n      styles['transform'] = transformForCss({\n        transform: transform,\n        startCentered: true,\n        width: width,\n        height: height\n      });\n      styles['-webkit-transform'] = styles['transform'];\n    }\n\n    var styleString = joinStyles(styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    var val = [];\n    val.push({\n      tag: 'span',\n      attributes: attributes,\n      children: [content]\n    });\n\n    if (title) {\n      val.push({\n        tag: 'span',\n        attributes: {\n          class: 'sr-only'\n        },\n        children: [title]\n      });\n    }\n\n    return val;\n  }\n  function makeLayersCounterAbstract(params) {\n    var content = params.content,\n        title = params.title,\n        extra = params.extra;\n\n    var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n      'title': title\n    } : {}), {}, {\n      'class': extra.classes.join(' ')\n    });\n\n    var styleString = joinStyles(extra.styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    var val = [];\n    val.push({\n      tag: 'span',\n      attributes: attributes,\n      children: [content]\n    });\n\n    if (title) {\n      val.push({\n        tag: 'span',\n        attributes: {\n          class: 'sr-only'\n        },\n        children: [title]\n      });\n    }\n\n    return val;\n  }\n\n  var noop$1 = function noop() {};\n\n  var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : {\n    mark: noop$1,\n    measure: noop$1\n  };\n  var preamble = \"FA \\\"5.15.4\\\"\";\n\n  var begin = function begin(name) {\n    p.mark(\"\".concat(preamble, \" \").concat(name, \" begins\"));\n    return function () {\n      return end(name);\n    };\n  };\n\n  var end = function end(name) {\n    p.mark(\"\".concat(preamble, \" \").concat(name, \" ends\"));\n    p.measure(\"\".concat(preamble, \" \").concat(name), \"\".concat(preamble, \" \").concat(name, \" begins\"), \"\".concat(preamble, \" \").concat(name, \" ends\"));\n  };\n\n  var perf = {\n    begin: begin,\n    end: end\n  };\n\n  /**\n   * Internal helper to bind a function known to have 4 arguments\n   * to a given context.\n   */\n\n  var bindInternal4 = function bindInternal4(func, thisContext) {\n    return function (a, b, c, d) {\n      return func.call(thisContext, a, b, c, d);\n    };\n  };\n\n  /**\n   * # Reduce\n   *\n   * A fast object `.reduce()` implementation.\n   *\n   * @param  {Object}   subject      The object to reduce over.\n   * @param  {Function} fn           The reducer function.\n   * @param  {mixed}    initialValue The initial value for the reducer, defaults to subject[0].\n   * @param  {Object}   thisContext  The context for the reducer.\n   * @return {mixed}                 The final result.\n   */\n\n\n  var reduce = function fastReduceObject(subject, fn, initialValue, thisContext) {\n    var keys = Object.keys(subject),\n        length = keys.length,\n        iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn,\n        i,\n        key,\n        result;\n\n    if (initialValue === undefined) {\n      i = 1;\n      result = subject[keys[0]];\n    } else {\n      i = 0;\n      result = initialValue;\n    }\n\n    for (; i < length; i++) {\n      key = keys[i];\n      result = iterator(result, subject[key], key, subject);\n    }\n\n    return result;\n  };\n\n  function toHex(unicode) {\n    var result = '';\n\n    for (var i = 0; i < unicode.length; i++) {\n      var hex = unicode.charCodeAt(i).toString(16);\n      result += ('000' + hex).slice(-4);\n    }\n\n    return result;\n  }\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var styles = namespace.styles,\n      shims = namespace.shims;\n  var _byUnicode = {};\n  var _byLigature = {};\n  var _byOldName = {};\n  var build = function build() {\n    var lookup = function lookup(reducer) {\n      return reduce(styles, function (o, style, prefix) {\n        o[prefix] = reduce(style, reducer, {});\n        return o;\n      }, {});\n    };\n\n    _byUnicode = lookup(function (acc, icon, iconName) {\n      if (icon[3]) {\n        acc[icon[3]] = iconName;\n      }\n\n      return acc;\n    });\n    _byLigature = lookup(function (acc, icon, iconName) {\n      var ligatures = icon[2];\n      acc[iconName] = iconName;\n      ligatures.forEach(function (ligature) {\n        acc[ligature] = iconName;\n      });\n      return acc;\n    });\n    var hasRegular = ('far' in styles);\n    _byOldName = reduce(shims, function (acc, shim) {\n      var oldName = shim[0];\n      var prefix = shim[1];\n      var iconName = shim[2];\n\n      if (prefix === 'far' && !hasRegular) {\n        prefix = 'fas';\n      }\n\n      acc[oldName] = {\n        prefix: prefix,\n        iconName: iconName\n      };\n      return acc;\n    }, {});\n  };\n  build();\n  function byUnicode(prefix, unicode) {\n    return (_byUnicode[prefix] || {})[unicode];\n  }\n  function byLigature(prefix, ligature) {\n    return (_byLigature[prefix] || {})[ligature];\n  }\n  function byOldName(name) {\n    return _byOldName[name] || {\n      prefix: null,\n      iconName: null\n    };\n  }\n\n  var styles$1 = namespace.styles;\n  var emptyCanonicalIcon = function emptyCanonicalIcon() {\n    return {\n      prefix: null,\n      iconName: null,\n      rest: []\n    };\n  };\n  function getCanonicalIcon(values) {\n    return values.reduce(function (acc, cls) {\n      var iconName = getIconName(config.familyPrefix, cls);\n\n      if (styles$1[cls]) {\n        acc.prefix = cls;\n      } else if (config.autoFetchSvg && Object.keys(PREFIX_TO_STYLE).indexOf(cls) > -1) {\n        acc.prefix = cls;\n      } else if (iconName) {\n        var shim = acc.prefix === 'fa' ? byOldName(iconName) : {};\n        acc.iconName = shim.iconName || iconName;\n        acc.prefix = shim.prefix || acc.prefix;\n      } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) {\n        acc.rest.push(cls);\n      }\n\n      return acc;\n    }, emptyCanonicalIcon());\n  }\n  function iconFromMapping(mapping, prefix, iconName) {\n    if (mapping && mapping[prefix] && mapping[prefix][iconName]) {\n      return {\n        prefix: prefix,\n        iconName: iconName,\n        icon: mapping[prefix][iconName]\n      };\n    }\n  }\n\n  function toHtml(abstractNodes) {\n    var tag = abstractNodes.tag,\n        _abstractNodes$attrib = abstractNodes.attributes,\n        attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib,\n        _abstractNodes$childr = abstractNodes.children,\n        children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr;\n\n    if (typeof abstractNodes === 'string') {\n      return htmlEscape(abstractNodes);\n    } else {\n      return \"<\".concat(tag, \" \").concat(joinAttributes(attributes), \">\").concat(children.map(toHtml).join(''), \"</\").concat(tag, \">\");\n    }\n  }\n\n  var noop$2 = function noop() {};\n\n  function isWatched(node) {\n    var i2svg = node.getAttribute ? node.getAttribute(DATA_FA_I2SVG) : null;\n    return typeof i2svg === 'string';\n  }\n\n  function getMutator() {\n    if (config.autoReplaceSvg === true) {\n      return mutators.replace;\n    }\n\n    var mutator = mutators[config.autoReplaceSvg];\n    return mutator || mutators.replace;\n  }\n\n  var mutators = {\n    replace: function replace(mutation) {\n      var node = mutation[0];\n      var abstract = mutation[1];\n      var newOuterHTML = abstract.map(function (a) {\n        return toHtml(a);\n      }).join('\\n');\n\n      if (node.parentNode && node.outerHTML) {\n        node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? \"<!-- \".concat(node.outerHTML, \" Font Awesome fontawesome.com -->\") : '');\n      } else if (node.parentNode) {\n        var newNode = document.createElement('span');\n        node.parentNode.replaceChild(newNode, node);\n        newNode.outerHTML = newOuterHTML;\n      }\n    },\n    nest: function nest(mutation) {\n      var node = mutation[0];\n      var abstract = mutation[1]; // If we already have a replaced node we do not want to continue nesting within it.\n      // Short-circuit to the standard replacement\n\n      if (~classArray(node).indexOf(config.replacementClass)) {\n        return mutators.replace(mutation);\n      }\n\n      var forSvg = new RegExp(\"\".concat(config.familyPrefix, \"-.*\"));\n      delete abstract[0].attributes.style;\n      delete abstract[0].attributes.id;\n      var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) {\n        if (cls === config.replacementClass || cls.match(forSvg)) {\n          acc.toSvg.push(cls);\n        } else {\n          acc.toNode.push(cls);\n        }\n\n        return acc;\n      }, {\n        toNode: [],\n        toSvg: []\n      });\n      abstract[0].attributes.class = splitClasses.toSvg.join(' ');\n      var newInnerHTML = abstract.map(function (a) {\n        return toHtml(a);\n      }).join('\\n');\n      node.setAttribute('class', splitClasses.toNode.join(' '));\n      node.setAttribute(DATA_FA_I2SVG, '');\n      node.innerHTML = newInnerHTML;\n    }\n  };\n\n  function performOperationSync(op) {\n    op();\n  }\n\n  function perform(mutations, callback) {\n    var callbackFunction = typeof callback === 'function' ? callback : noop$2;\n\n    if (mutations.length === 0) {\n      callbackFunction();\n    } else {\n      var frame = performOperationSync;\n\n      if (config.mutateApproach === MUTATION_APPROACH_ASYNC) {\n        frame = WINDOW.requestAnimationFrame || performOperationSync;\n      }\n\n      frame(function () {\n        var mutator = getMutator();\n        var mark = perf.begin('mutate');\n        mutations.map(mutator);\n        mark();\n        callbackFunction();\n      });\n    }\n  }\n  var disabled = false;\n  function disableObservation() {\n    disabled = true;\n  }\n  function enableObservation() {\n    disabled = false;\n  }\n  var mo = null;\n  function observe(options) {\n    if (!MUTATION_OBSERVER) {\n      return;\n    }\n\n    if (!config.observeMutations) {\n      return;\n    }\n\n    var treeCallback = options.treeCallback,\n        nodeCallback = options.nodeCallback,\n        pseudoElementsCallback = options.pseudoElementsCallback,\n        _options$observeMutat = options.observeMutationsRoot,\n        observeMutationsRoot = _options$observeMutat === void 0 ? DOCUMENT : _options$observeMutat;\n    mo = new MUTATION_OBSERVER(function (objects) {\n      if (disabled) return;\n      toArray(objects).forEach(function (mutationRecord) {\n        if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isWatched(mutationRecord.addedNodes[0])) {\n          if (config.searchPseudoElements) {\n            pseudoElementsCallback(mutationRecord.target);\n          }\n\n          treeCallback(mutationRecord.target);\n        }\n\n        if (mutationRecord.type === 'attributes' && mutationRecord.target.parentNode && config.searchPseudoElements) {\n          pseudoElementsCallback(mutationRecord.target.parentNode);\n        }\n\n        if (mutationRecord.type === 'attributes' && isWatched(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) {\n          if (mutationRecord.attributeName === 'class') {\n            var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)),\n                prefix = _getCanonicalIcon.prefix,\n                iconName = _getCanonicalIcon.iconName;\n\n            if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix);\n            if (iconName) mutationRecord.target.setAttribute('data-icon', iconName);\n          } else {\n            nodeCallback(mutationRecord.target);\n          }\n        }\n      });\n    });\n    if (!IS_DOM) return;\n    mo.observe(observeMutationsRoot, {\n      childList: true,\n      attributes: true,\n      characterData: true,\n      subtree: true\n    });\n  }\n  function disconnect() {\n    if (!mo) return;\n    mo.disconnect();\n  }\n\n  function styleParser (node) {\n    var style = node.getAttribute('style');\n    var val = [];\n\n    if (style) {\n      val = style.split(';').reduce(function (acc, style) {\n        var styles = style.split(':');\n        var prop = styles[0];\n        var value = styles.slice(1);\n\n        if (prop && value.length > 0) {\n          acc[prop] = value.join(':').trim();\n        }\n\n        return acc;\n      }, {});\n    }\n\n    return val;\n  }\n\n  function classParser (node) {\n    var existingPrefix = node.getAttribute('data-prefix');\n    var existingIconName = node.getAttribute('data-icon');\n    var innerText = node.innerText !== undefined ? node.innerText.trim() : '';\n    var val = getCanonicalIcon(classArray(node));\n\n    if (existingPrefix && existingIconName) {\n      val.prefix = existingPrefix;\n      val.iconName = existingIconName;\n    }\n\n    if (val.prefix && innerText.length > 1) {\n      val.iconName = byLigature(val.prefix, node.innerText);\n    } else if (val.prefix && innerText.length === 1) {\n      val.iconName = byUnicode(val.prefix, toHex(node.innerText));\n    }\n\n    return val;\n  }\n\n  var parseTransformString = function parseTransformString(transformString) {\n    var transform = {\n      size: 16,\n      x: 0,\n      y: 0,\n      flipX: false,\n      flipY: false,\n      rotate: 0\n    };\n\n    if (!transformString) {\n      return transform;\n    } else {\n      return transformString.toLowerCase().split(' ').reduce(function (acc, n) {\n        var parts = n.toLowerCase().split('-');\n        var first = parts[0];\n        var rest = parts.slice(1).join('-');\n\n        if (first && rest === 'h') {\n          acc.flipX = true;\n          return acc;\n        }\n\n        if (first && rest === 'v') {\n          acc.flipY = true;\n          return acc;\n        }\n\n        rest = parseFloat(rest);\n\n        if (isNaN(rest)) {\n          return acc;\n        }\n\n        switch (first) {\n          case 'grow':\n            acc.size = acc.size + rest;\n            break;\n\n          case 'shrink':\n            acc.size = acc.size - rest;\n            break;\n\n          case 'left':\n            acc.x = acc.x - rest;\n            break;\n\n          case 'right':\n            acc.x = acc.x + rest;\n            break;\n\n          case 'up':\n            acc.y = acc.y - rest;\n            break;\n\n          case 'down':\n            acc.y = acc.y + rest;\n            break;\n\n          case 'rotate':\n            acc.rotate = acc.rotate + rest;\n            break;\n        }\n\n        return acc;\n      }, transform);\n    }\n  };\n  function transformParser (node) {\n    return parseTransformString(node.getAttribute('data-fa-transform'));\n  }\n\n  function symbolParser (node) {\n    var symbol = node.getAttribute('data-fa-symbol');\n    return symbol === null ? false : symbol === '' ? true : symbol;\n  }\n\n  function attributesParser (node) {\n    var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) {\n      if (acc.name !== 'class' && acc.name !== 'style') {\n        acc[attr.name] = attr.value;\n      }\n\n      return acc;\n    }, {});\n    var title = node.getAttribute('title');\n    var titleId = node.getAttribute('data-fa-title-id');\n\n    if (config.autoA11y) {\n      if (title) {\n        extraAttributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n      } else {\n        extraAttributes['aria-hidden'] = 'true';\n        extraAttributes['focusable'] = 'false';\n      }\n    }\n\n    return extraAttributes;\n  }\n\n  function maskParser (node) {\n    var mask = node.getAttribute('data-fa-mask');\n\n    if (!mask) {\n      return emptyCanonicalIcon();\n    } else {\n      return getCanonicalIcon(mask.split(' ').map(function (i) {\n        return i.trim();\n      }));\n    }\n  }\n\n  function blankMeta() {\n    return {\n      iconName: null,\n      title: null,\n      titleId: null,\n      prefix: null,\n      transform: meaninglessTransform,\n      symbol: false,\n      mask: null,\n      maskId: null,\n      extra: {\n        classes: [],\n        styles: {},\n        attributes: {}\n      }\n    };\n  }\n  function parseMeta(node) {\n    var _classParser = classParser(node),\n        iconName = _classParser.iconName,\n        prefix = _classParser.prefix,\n        extraClasses = _classParser.rest;\n\n    var extraStyles = styleParser(node);\n    var transform = transformParser(node);\n    var symbol = symbolParser(node);\n    var extraAttributes = attributesParser(node);\n    var mask = maskParser(node);\n    return {\n      iconName: iconName,\n      title: node.getAttribute('title'),\n      titleId: node.getAttribute('data-fa-title-id'),\n      prefix: prefix,\n      transform: transform,\n      symbol: symbol,\n      mask: mask,\n      maskId: node.getAttribute('data-fa-mask-id'),\n      extra: {\n        classes: extraClasses,\n        styles: extraStyles,\n        attributes: extraAttributes\n      }\n    };\n  }\n\n  function MissingIcon(error) {\n    this.name = 'MissingIcon';\n    this.message = error || 'Icon unavailable';\n    this.stack = new Error().stack;\n  }\n  MissingIcon.prototype = Object.create(Error.prototype);\n  MissingIcon.prototype.constructor = MissingIcon;\n\n  var FILL = {\n    fill: 'currentColor'\n  };\n  var ANIMATION_BASE = {\n    attributeType: 'XML',\n    repeatCount: 'indefinite',\n    dur: '2s'\n  };\n  var RING = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z'\n    })\n  };\n\n  var OPACITY_ANIMATE = _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n    attributeName: 'opacity'\n  });\n\n  var DOT = {\n    tag: 'circle',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      cx: '256',\n      cy: '364',\n      r: '28'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n        attributeName: 'r',\n        values: '28;14;28;28;14;28;'\n      })\n    }, {\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '1;0;1;1;0;1;'\n      })\n    }]\n  };\n  var QUESTION = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      opacity: '1',\n      d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '1;0;0;0;0;1;'\n      })\n    }]\n  };\n  var EXCLAMATION = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      opacity: '0',\n      d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '0;0;1;1;0;0;'\n      })\n    }]\n  };\n  var missing = {\n    tag: 'g',\n    children: [RING, DOT, QUESTION, EXCLAMATION]\n  };\n\n  var styles$2 = namespace.styles;\n  function asFoundIcon(icon) {\n    var width = icon[0];\n    var height = icon[1];\n\n    var _icon$slice = icon.slice(4),\n        _icon$slice2 = _slicedToArray(_icon$slice, 1),\n        vectorData = _icon$slice2[0];\n\n    var element = null;\n\n    if (Array.isArray(vectorData)) {\n      element = {\n        tag: 'g',\n        attributes: {\n          class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.GROUP)\n        },\n        children: [{\n          tag: 'path',\n          attributes: {\n            class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.SECONDARY),\n            fill: 'currentColor',\n            d: vectorData[0]\n          }\n        }, {\n          tag: 'path',\n          attributes: {\n            class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.PRIMARY),\n            fill: 'currentColor',\n            d: vectorData[1]\n          }\n        }]\n      };\n    } else {\n      element = {\n        tag: 'path',\n        attributes: {\n          fill: 'currentColor',\n          d: vectorData\n        }\n      };\n    }\n\n    return {\n      found: true,\n      width: width,\n      height: height,\n      icon: element\n    };\n  }\n  function findIcon(iconName, prefix) {\n    return new picked(function (resolve, reject) {\n      var val = {\n        found: false,\n        width: 512,\n        height: 512,\n        icon: missing\n      };\n\n      if (iconName && prefix && styles$2[prefix] && styles$2[prefix][iconName]) {\n        var icon = styles$2[prefix][iconName];\n        return resolve(asFoundIcon(icon));\n      }\n\n      if (iconName && prefix && !config.showMissingIcons) {\n        reject(new MissingIcon(\"Icon is missing for prefix \".concat(prefix, \" with icon name \").concat(iconName)));\n      } else {\n        resolve(val);\n      }\n    });\n  }\n\n  var styles$3 = namespace.styles;\n\n  function generateSvgReplacementMutation(node, nodeMeta) {\n    var iconName = nodeMeta.iconName,\n        title = nodeMeta.title,\n        titleId = nodeMeta.titleId,\n        prefix = nodeMeta.prefix,\n        transform = nodeMeta.transform,\n        symbol = nodeMeta.symbol,\n        mask = nodeMeta.mask,\n        maskId = nodeMeta.maskId,\n        extra = nodeMeta.extra;\n    return new picked(function (resolve, reject) {\n      picked.all([findIcon(iconName, prefix), findIcon(mask.iconName, mask.prefix)]).then(function (_ref) {\n        var _ref2 = _slicedToArray(_ref, 2),\n            main = _ref2[0],\n            mask = _ref2[1];\n\n        resolve([node, makeInlineSvgAbstract({\n          icons: {\n            main: main,\n            mask: mask\n          },\n          prefix: prefix,\n          iconName: iconName,\n          transform: transform,\n          symbol: symbol,\n          mask: mask,\n          maskId: maskId,\n          title: title,\n          titleId: titleId,\n          extra: extra,\n          watchable: true\n        })]);\n      });\n    });\n  }\n\n  function generateLayersText(node, nodeMeta) {\n    var title = nodeMeta.title,\n        transform = nodeMeta.transform,\n        extra = nodeMeta.extra;\n    var width = null;\n    var height = null;\n\n    if (IS_IE) {\n      var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10);\n      var boundingClientRect = node.getBoundingClientRect();\n      width = boundingClientRect.width / computedFontSize;\n      height = boundingClientRect.height / computedFontSize;\n    }\n\n    if (config.autoA11y && !title) {\n      extra.attributes['aria-hidden'] = 'true';\n    }\n\n    return picked.resolve([node, makeLayersTextAbstract({\n      content: node.innerHTML,\n      width: width,\n      height: height,\n      transform: transform,\n      title: title,\n      extra: extra,\n      watchable: true\n    })]);\n  }\n\n  function generateMutation(node) {\n    var nodeMeta = parseMeta(node);\n\n    if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) {\n      return generateLayersText(node, nodeMeta);\n    } else {\n      return generateSvgReplacementMutation(node, nodeMeta);\n    }\n  }\n\n  function onTree(root) {\n    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n    if (!IS_DOM) return;\n    var htmlClassList = DOCUMENT.documentElement.classList;\n\n    var hclAdd = function hclAdd(suffix) {\n      return htmlClassList.add(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n    };\n\n    var hclRemove = function hclRemove(suffix) {\n      return htmlClassList.remove(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n    };\n\n    var prefixes = config.autoFetchSvg ? Object.keys(PREFIX_TO_STYLE) : Object.keys(styles$3);\n    var prefixesDomQuery = [\".\".concat(LAYERS_TEXT_CLASSNAME, \":not([\").concat(DATA_FA_I2SVG, \"])\")].concat(prefixes.map(function (p) {\n      return \".\".concat(p, \":not([\").concat(DATA_FA_I2SVG, \"])\");\n    })).join(', ');\n\n    if (prefixesDomQuery.length === 0) {\n      return;\n    }\n\n    var candidates = [];\n\n    try {\n      candidates = toArray(root.querySelectorAll(prefixesDomQuery));\n    } catch (e) {// noop\n    }\n\n    if (candidates.length > 0) {\n      hclAdd('pending');\n      hclRemove('complete');\n    } else {\n      return;\n    }\n\n    var mark = perf.begin('onTree');\n    var mutations = candidates.reduce(function (acc, node) {\n      try {\n        var mutation = generateMutation(node);\n\n        if (mutation) {\n          acc.push(mutation);\n        }\n      } catch (e) {\n        if (!PRODUCTION) {\n          if (e instanceof MissingIcon) {\n            console.error(e);\n          }\n        }\n      }\n\n      return acc;\n    }, []);\n    return new picked(function (resolve, reject) {\n      picked.all(mutations).then(function (resolvedMutations) {\n        perform(resolvedMutations, function () {\n          hclAdd('active');\n          hclAdd('complete');\n          hclRemove('pending');\n          if (typeof callback === 'function') callback();\n          mark();\n          resolve();\n        });\n      }).catch(function () {\n        mark();\n        reject();\n      });\n    });\n  }\n  function onNode(node) {\n    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n    generateMutation(node).then(function (mutation) {\n      if (mutation) {\n        perform([mutation], callback);\n      }\n    });\n  }\n\n  function replaceForPosition(node, position) {\n    var pendingAttribute = \"\".concat(DATA_FA_PSEUDO_ELEMENT_PENDING).concat(position.replace(':', '-'));\n    return new picked(function (resolve, reject) {\n      if (node.getAttribute(pendingAttribute) !== null) {\n        // This node is already being processed\n        return resolve();\n      }\n\n      var children = toArray(node.children);\n      var alreadyProcessedPseudoElement = children.filter(function (c) {\n        return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === position;\n      })[0];\n      var styles = WINDOW.getComputedStyle(node, position);\n      var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN);\n      var fontWeight = styles.getPropertyValue('font-weight');\n      var content = styles.getPropertyValue('content');\n\n      if (alreadyProcessedPseudoElement && !fontFamily) {\n        // If we've already processed it but the current computed style does not result in a font-family,\n        // that probably means that a class name that was previously present to make the icon has been\n        // removed. So we now should delete the icon.\n        node.removeChild(alreadyProcessedPseudoElement);\n        return resolve();\n      } else if (fontFamily && content !== 'none' && content !== '') {\n        var _content = styles.getPropertyValue('content');\n\n        var prefix = ~['Solid', 'Regular', 'Light', 'Duotone', 'Brands', 'Kit'].indexOf(fontFamily[2]) ? STYLE_TO_PREFIX[fontFamily[2].toLowerCase()] : FONT_WEIGHT_TO_PREFIX[fontWeight];\n        var hexValue = toHex(_content.length === 3 ? _content.substr(1, 1) : _content);\n        var iconName = byUnicode(prefix, hexValue);\n        var iconIdentifier = iconName; // Only convert the pseudo element in this :before/:after position into an icon if we haven't\n        // already done so with the same prefix and iconName\n\n        if (iconName && (!alreadyProcessedPseudoElement || alreadyProcessedPseudoElement.getAttribute(DATA_PREFIX) !== prefix || alreadyProcessedPseudoElement.getAttribute(DATA_ICON) !== iconIdentifier)) {\n          node.setAttribute(pendingAttribute, iconIdentifier);\n\n          if (alreadyProcessedPseudoElement) {\n            // Delete the old one, since we're replacing it with a new one\n            node.removeChild(alreadyProcessedPseudoElement);\n          }\n\n          var meta = blankMeta();\n          var extra = meta.extra;\n          extra.attributes[DATA_FA_PSEUDO_ELEMENT] = position;\n          findIcon(iconName, prefix).then(function (main) {\n            var abstract = makeInlineSvgAbstract(_objectSpread2(_objectSpread2({}, meta), {}, {\n              icons: {\n                main: main,\n                mask: emptyCanonicalIcon()\n              },\n              prefix: prefix,\n              iconName: iconIdentifier,\n              extra: extra,\n              watchable: true\n            }));\n            var element = DOCUMENT.createElement('svg');\n\n            if (position === ':before') {\n              node.insertBefore(element, node.firstChild);\n            } else {\n              node.appendChild(element);\n            }\n\n            element.outerHTML = abstract.map(function (a) {\n              return toHtml(a);\n            }).join('\\n');\n            node.removeAttribute(pendingAttribute);\n            resolve();\n          }).catch(reject);\n        } else {\n          resolve();\n        }\n      } else {\n        resolve();\n      }\n    });\n  }\n\n  function replace(node) {\n    return picked.all([replaceForPosition(node, ':before'), replaceForPosition(node, ':after')]);\n  }\n\n  function processable(node) {\n    return node.parentNode !== document.head && !~TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS.indexOf(node.tagName.toUpperCase()) && !node.getAttribute(DATA_FA_PSEUDO_ELEMENT) && (!node.parentNode || node.parentNode.tagName !== 'svg');\n  }\n\n  function searchPseudoElements (root) {\n    if (!IS_DOM) return;\n    return new picked(function (resolve, reject) {\n      var operations = toArray(root.querySelectorAll('*')).filter(processable).map(replace);\n      var end = perf.begin('searchPseudoElements');\n      disableObservation();\n      picked.all(operations).then(function () {\n        end();\n        enableObservation();\n        resolve();\n      }).catch(function () {\n        end();\n        enableObservation();\n        reject();\n      });\n    });\n  }\n\n  var baseStyles = \"svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;-webkit-box-sizing:border-box;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor);opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.fad.fa-inverse{color:#fff}\";\n\n  function css () {\n    var dfp = DEFAULT_FAMILY_PREFIX;\n    var drc = DEFAULT_REPLACEMENT_CLASS;\n    var fp = config.familyPrefix;\n    var rc = config.replacementClass;\n    var s = baseStyles;\n\n    if (fp !== dfp || rc !== drc) {\n      var dPatt = new RegExp(\"\\\\.\".concat(dfp, \"\\\\-\"), 'g');\n      var customPropPatt = new RegExp(\"\\\\--\".concat(dfp, \"\\\\-\"), 'g');\n      var rPatt = new RegExp(\"\\\\.\".concat(drc), 'g');\n      s = s.replace(dPatt, \".\".concat(fp, \"-\")).replace(customPropPatt, \"--\".concat(fp, \"-\")).replace(rPatt, \".\".concat(rc));\n    }\n\n    return s;\n  }\n\n  var Library = /*#__PURE__*/function () {\n    function Library() {\n      _classCallCheck(this, Library);\n\n      this.definitions = {};\n    }\n\n    _createClass(Library, [{\n      key: \"add\",\n      value: function add() {\n        var _this = this;\n\n        for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) {\n          definitions[_key] = arguments[_key];\n        }\n\n        var additions = definitions.reduce(this._pullDefinitions, {});\n        Object.keys(additions).forEach(function (key) {\n          _this.definitions[key] = _objectSpread2(_objectSpread2({}, _this.definitions[key] || {}), additions[key]);\n          defineIcons(key, additions[key]);\n          build();\n        });\n      }\n    }, {\n      key: \"reset\",\n      value: function reset() {\n        this.definitions = {};\n      }\n    }, {\n      key: \"_pullDefinitions\",\n      value: function _pullDefinitions(additions, definition) {\n        var normalized = definition.prefix && definition.iconName && definition.icon ? {\n          0: definition\n        } : definition;\n        Object.keys(normalized).map(function (key) {\n          var _normalized$key = normalized[key],\n              prefix = _normalized$key.prefix,\n              iconName = _normalized$key.iconName,\n              icon = _normalized$key.icon;\n          if (!additions[prefix]) additions[prefix] = {};\n          additions[prefix][iconName] = icon;\n        });\n        return additions;\n      }\n    }]);\n\n    return Library;\n  }();\n\n  function ensureCss() {\n    if (config.autoAddCss && !_cssInserted) {\n      insertCss(css());\n\n      _cssInserted = true;\n    }\n  }\n\n  function apiObject(val, abstractCreator) {\n    Object.defineProperty(val, 'abstract', {\n      get: abstractCreator\n    });\n    Object.defineProperty(val, 'html', {\n      get: function get() {\n        return val.abstract.map(function (a) {\n          return toHtml(a);\n        });\n      }\n    });\n    Object.defineProperty(val, 'node', {\n      get: function get() {\n        if (!IS_DOM) return;\n        var container = DOCUMENT.createElement('div');\n        container.innerHTML = val.html;\n        return container.children;\n      }\n    });\n    return val;\n  }\n\n  function findIconDefinition(iconLookup) {\n    var _iconLookup$prefix = iconLookup.prefix,\n        prefix = _iconLookup$prefix === void 0 ? 'fa' : _iconLookup$prefix,\n        iconName = iconLookup.iconName;\n    if (!iconName) return;\n    return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName);\n  }\n\n  function resolveIcons(next) {\n    return function (maybeIconDefinition) {\n      var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n      var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {});\n      var mask = params.mask;\n\n      if (mask) {\n        mask = (mask || {}).icon ? mask : findIconDefinition(mask || {});\n      }\n\n      return next(iconDefinition, _objectSpread2(_objectSpread2({}, params), {}, {\n        mask: mask\n      }));\n    };\n  }\n\n  var library = new Library();\n  var noAuto = function noAuto() {\n    config.autoReplaceSvg = false;\n    config.observeMutations = false;\n    disconnect();\n  };\n  var _cssInserted = false;\n  var dom = {\n    i2svg: function i2svg() {\n      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n      if (IS_DOM) {\n        ensureCss();\n        var _params$node = params.node,\n            node = _params$node === void 0 ? DOCUMENT : _params$node,\n            _params$callback = params.callback,\n            callback = _params$callback === void 0 ? function () {} : _params$callback;\n\n        if (config.searchPseudoElements) {\n          searchPseudoElements(node);\n        }\n\n        return onTree(node, callback);\n      } else {\n        return picked.reject('Operation requires a DOM of some kind.');\n      }\n    },\n    css: css,\n    insertCss: function insertCss$$1() {\n      if (!_cssInserted) {\n        insertCss(css());\n\n        _cssInserted = true;\n      }\n    },\n    watch: function watch() {\n      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n      var autoReplaceSvgRoot = params.autoReplaceSvgRoot,\n          observeMutationsRoot = params.observeMutationsRoot;\n\n      if (config.autoReplaceSvg === false) {\n        config.autoReplaceSvg = true;\n      }\n\n      config.observeMutations = true;\n      domready(function () {\n        autoReplace({\n          autoReplaceSvgRoot: autoReplaceSvgRoot\n        });\n        observe({\n          treeCallback: onTree,\n          nodeCallback: onNode,\n          pseudoElementsCallback: searchPseudoElements,\n          observeMutationsRoot: observeMutationsRoot\n        });\n      });\n    }\n  };\n  var parse = {\n    transform: function transform(transformString) {\n      return parseTransformString(transformString);\n    }\n  };\n  var icon = resolveIcons(function (iconDefinition) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$transform = params.transform,\n        transform = _params$transform === void 0 ? meaninglessTransform : _params$transform,\n        _params$symbol = params.symbol,\n        symbol = _params$symbol === void 0 ? false : _params$symbol,\n        _params$mask = params.mask,\n        mask = _params$mask === void 0 ? null : _params$mask,\n        _params$maskId = params.maskId,\n        maskId = _params$maskId === void 0 ? null : _params$maskId,\n        _params$title = params.title,\n        title = _params$title === void 0 ? null : _params$title,\n        _params$titleId = params.titleId,\n        titleId = _params$titleId === void 0 ? null : _params$titleId,\n        _params$classes = params.classes,\n        classes = _params$classes === void 0 ? [] : _params$classes,\n        _params$attributes = params.attributes,\n        attributes = _params$attributes === void 0 ? {} : _params$attributes,\n        _params$styles = params.styles,\n        styles = _params$styles === void 0 ? {} : _params$styles;\n    if (!iconDefinition) return;\n    var prefix = iconDefinition.prefix,\n        iconName = iconDefinition.iconName,\n        icon = iconDefinition.icon;\n    return apiObject(_objectSpread2({\n      type: 'icon'\n    }, iconDefinition), function () {\n      ensureCss();\n\n      if (config.autoA11y) {\n        if (title) {\n          attributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n        } else {\n          attributes['aria-hidden'] = 'true';\n          attributes['focusable'] = 'false';\n        }\n      }\n\n      return makeInlineSvgAbstract({\n        icons: {\n          main: asFoundIcon(icon),\n          mask: mask ? asFoundIcon(mask.icon) : {\n            found: false,\n            width: null,\n            height: null,\n            icon: {}\n          }\n        },\n        prefix: prefix,\n        iconName: iconName,\n        transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n        symbol: symbol,\n        title: title,\n        maskId: maskId,\n        titleId: titleId,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: classes\n        }\n      });\n    });\n  });\n  var text = function text(content) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$transform2 = params.transform,\n        transform = _params$transform2 === void 0 ? meaninglessTransform : _params$transform2,\n        _params$title2 = params.title,\n        title = _params$title2 === void 0 ? null : _params$title2,\n        _params$classes2 = params.classes,\n        classes = _params$classes2 === void 0 ? [] : _params$classes2,\n        _params$attributes2 = params.attributes,\n        attributes = _params$attributes2 === void 0 ? {} : _params$attributes2,\n        _params$styles2 = params.styles,\n        styles = _params$styles2 === void 0 ? {} : _params$styles2;\n    return apiObject({\n      type: 'text',\n      content: content\n    }, function () {\n      ensureCss();\n      return makeLayersTextAbstract({\n        content: content,\n        transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n        title: title,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: [\"\".concat(config.familyPrefix, \"-layers-text\")].concat(_toConsumableArray(classes))\n        }\n      });\n    });\n  };\n  var counter = function counter(content) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$title3 = params.title,\n        title = _params$title3 === void 0 ? null : _params$title3,\n        _params$classes3 = params.classes,\n        classes = _params$classes3 === void 0 ? [] : _params$classes3,\n        _params$attributes3 = params.attributes,\n        attributes = _params$attributes3 === void 0 ? {} : _params$attributes3,\n        _params$styles3 = params.styles,\n        styles = _params$styles3 === void 0 ? {} : _params$styles3;\n    return apiObject({\n      type: 'counter',\n      content: content\n    }, function () {\n      ensureCss();\n      return makeLayersCounterAbstract({\n        content: content.toString(),\n        title: title,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: [\"\".concat(config.familyPrefix, \"-layers-counter\")].concat(_toConsumableArray(classes))\n        }\n      });\n    });\n  };\n  var layer = function layer(assembler) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$classes4 = params.classes,\n        classes = _params$classes4 === void 0 ? [] : _params$classes4;\n    return apiObject({\n      type: 'layer'\n    }, function () {\n      ensureCss();\n      var children = [];\n      assembler(function (args) {\n        Array.isArray(args) ? args.map(function (a) {\n          children = children.concat(a.abstract);\n        }) : children = children.concat(args.abstract);\n      });\n      return [{\n        tag: 'span',\n        attributes: {\n          class: [\"\".concat(config.familyPrefix, \"-layers\")].concat(_toConsumableArray(classes)).join(' ')\n        },\n        children: children\n      }];\n    });\n  };\n  var api = {\n    noAuto: noAuto,\n    config: config,\n    dom: dom,\n    library: library,\n    parse: parse,\n    findIconDefinition: findIconDefinition,\n    icon: icon,\n    text: text,\n    counter: counter,\n    layer: layer,\n    toHtml: toHtml\n  };\n\n  var autoReplace = function autoReplace() {\n    var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n    var _params$autoReplaceSv = params.autoReplaceSvgRoot,\n        autoReplaceSvgRoot = _params$autoReplaceSv === void 0 ? DOCUMENT : _params$autoReplaceSv;\n    if ((Object.keys(namespace.styles).length > 0 || config.autoFetchSvg) && IS_DOM && config.autoReplaceSvg) api.dom.i2svg({\n      node: autoReplaceSvgRoot\n    });\n  };\n\n  function bootstrap() {\n    if (IS_BROWSER) {\n      if (!WINDOW.FontAwesome) {\n        WINDOW.FontAwesome = api;\n      }\n\n      domready(function () {\n        autoReplace();\n        observe({\n          treeCallback: onTree,\n          nodeCallback: onNode,\n          pseudoElementsCallback: searchPseudoElements\n        });\n      });\n    }\n\n    namespace.hooks = _objectSpread2(_objectSpread2({}, namespace.hooks), {}, {\n      addPack: function addPack(prefix, icons) {\n        namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), icons);\n        build();\n        autoReplace();\n      },\n      addShims: function addShims(shims) {\n        var _namespace$shims;\n\n        (_namespace$shims = namespace.shims).push.apply(_namespace$shims, _toConsumableArray(shims));\n\n        build();\n        autoReplace();\n      }\n    });\n  }\n\n  bunker(bootstrap);\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/js/brands.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"aws\": [640, 512, [], \"f375\", \"M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z\"],\n    \"cc-amazon-pay\": [576, 512, [], \"f42d\", \"M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z\"],\n    \"cc-amex\": [576, 512, [], \"f1f3\", \"M325.1 167.8c0-16.4-14.1-18.4-27.4-18.4l-39.1-.3v69.3H275v-25.1h18c18.4 0 14.5 10.3 14.8 25.1h16.6v-13.5c0-9.2-1.5-15.1-11-18.4 7.4-3 11.8-10.7 11.7-18.7zm-29.4 11.3H275v-15.3h21c5.1 0 10.7 1 10.7 7.4 0 6.6-5.3 7.9-11 7.9zM279 268.6h-52.7l-21 22.8-20.5-22.8h-66.5l-.1 69.3h65.4l21.3-23 20.4 23h32.2l.1-23.3c18.9 0 49.3 4.6 49.3-23.3 0-17.3-12.3-22.7-27.9-22.7zm-103.8 54.7h-40.6v-13.8h36.3v-14.1h-36.3v-12.5h41.7l17.9 20.2zm65.8 8.2l-25.3-28.1L241 276zm37.8-31h-21.2v-17.6h21.5c5.6 0 10.2 2.3 10.2 8.4 0 6.4-4.6 9.2-10.5 9.2zm-31.6-136.7v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5zM576 255.4h-.2zm-194.6 31.9c0-16.4-14.1-18.7-27.1-18.7h-39.4l-.1 69.3h16.6l.1-25.3h17.6c11 0 14.8 2 14.8 13.8l-.1 11.5h16.6l.1-13.8c0-8.9-1.8-15.1-11-18.4 7.7-3.1 11.8-10.8 11.9-18.4zm-29.2 11.2h-20.7v-15.6h21c5.1 0 10.7 1 10.7 7.4 0 6.9-5.4 8.2-11 8.2zm-172.8-80v-69.3h-27.6l-19.7 47-21.7-47H83.3v65.7l-28.1-65.7H30.7L1 218.5h17.9l6.4-15.3h34.5l6.4 15.3H100v-54.2l24 54.2h14.6l24-54.2v54.2zM31.2 188.8l11.2-27.6 11.5 27.6zm477.4 158.9v-4.5c-10.8 5.6-3.9 4.5-156.7 4.5 0-25.2.1-23.9 0-25.2-1.7-.1-3.2-.1-9.4-.1 0 17.9-.1 6.8-.1 25.3h-39.6c0-12.1.1-15.3.1-29.2-10 6-22.8 6.4-34.3 6.2 0 14.7-.1 8.3-.1 23h-48.9c-5.1-5.7-2.7-3.1-15.4-17.4-3.2 3.5-12.8 13.9-16.1 17.4h-82v-92.3h83.1c5 5.6 2.8 3.1 15.5 17.2 3.2-3.5 12.2-13.4 15.7-17.2h58c9.8 0 18 1.9 24.3 5.6v-5.6c54.3 0 64.3-1.4 75.7 5.1v-5.1h78.2v5.2c11.4-6.9 19.6-5.2 64.9-5.2v5c10.3-5.9 16.6-5.2 54.3-5V80c0-26.5-21.5-48-48-48h-480c-26.5 0-48 21.5-48 48v109.8c9.4-21.9 19.7-46 23.1-53.9h39.7c4.3 10.1 1.6 3.7 9 21.1v-21.1h46c2.9 6.2 11.1 24 13.9 30 5.8-13.6 10.1-23.9 12.6-30h103c0-.1 11.5 0 11.6 0 43.7.2 53.6-.8 64.4 5.3v-5.3H363v9.3c7.6-6.1 17.9-9.3 30.7-9.3h27.6c0 .5 1.9.3 2.3.3H456c4.2 9.8 2.6 6 8.8 20.6v-20.6h43.3c4.9 8-1-1.8 11.2 18.4v-18.4h39.9v92h-41.6c-5.4-9-1.4-2.2-13.2-21.9v21.9h-52.8c-6.4-14.8-.1-.3-6.6-15.3h-19c-4.2 10-2.2 5.2-6.4 15.3h-26.8c-12.3 0-22.3-3-29.7-8.9v8.9h-66.5c-.3-13.9-.1-24.8-.1-24.8-1.8-.3-3.4-.2-9.8-.2v25.1H151.2v-11.4c-2.5 5.6-2.7 5.9-5.1 11.4h-29.5c-4-8.9-2.9-6.4-5.1-11.4v11.4H58.6c-4.2-10.1-2.2-5.3-6.4-15.3H33c-4.2 10-2.2 5.2-6.4 15.3H0V432c0 26.5 21.5 48 48 48h480.1c26.5 0 48-21.5 48-48v-90.4c-12.7 8.3-32.7 6.1-67.5 6.1zm36.3-64.5H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-57 39.8h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-42.2-40.1v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5zm-56.3-108.1c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm20.4-10.5h-.1zm-16.2-15.2c-23.5 0-34 12-34 35.3 0 22.2 10.2 34 33 34h19.2l6.4-15.3h34.3l6.6 15.3h33.7v-51.9l31.2 51.9h23.6v-69h-16.9v48.1l-29.1-48.1h-25.3v65.4l-27.9-65.4h-24.8l-23.5 54.5h-7.4c-13.3 0-16.1-8.1-16.1-19.9 0-23.8 15.7-20 33.1-19.7v-15.2zm42.1 12.1l11.2 27.6h-22.8zm-101.1-12v69.3h16.9v-69.3z\"],\n    \"cc-apple-pay\": [576, 512, [], \"f416\", \"M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z\"],\n    \"cc-diners-club\": [576, 512, [], \"f24c\", \"M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z\"],\n    \"cc-discover\": [576, 512, [], \"f1f2\", \"M520.4 196.1c0-7.9-5.5-12.1-15.6-12.1h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-44.1 138.9c22.6 0 52.9-4.1 52.9 24.4 0 12.6-6.6 20.7-18.7 23.2l25.8 34.4h-19.6l-22.2-32.8h-2.2v32.8h-16zm-55.9.1h45.3v14H444v18.2h28.3V217H444v22.2h29.3V253H428zm-68.7 0l21.9 55.2 22.2-55.2h17.5l-35.5 84.2h-8.6l-35-84.2zm-55.9-3c24.7 0 44.6 20 44.6 44.6 0 24.7-20 44.6-44.6 44.6-24.7 0-44.6-20-44.6-44.6 0-24.7 20-44.6 44.6-44.6zm-49.3 6.1v19c-20.1-20.1-46.8-4.7-46.8 19 0 25 27.5 38.5 46.8 19.2v19c-29.7 14.3-63.3-5.7-63.3-38.2 0-31.2 33.1-53 63.3-38zm-97.2 66.3c11.4 0 22.4-15.3-3.3-24.4-15-5.5-20.2-11.4-20.2-22.7 0-23.2 30.6-31.4 49.7-14.3l-8.4 10.8c-10.4-11.6-24.9-6.2-24.9 2.5 0 4.4 2.7 6.9 12.3 10.3 18.2 6.6 23.6 12.5 23.6 25.6 0 29.5-38.8 37.4-56.6 11.3l10.3-9.9c3.7 7.1 9.9 10.8 17.5 10.8zM55.4 253H32v-82h23.4c26.1 0 44.1 17 44.1 41.1 0 18.5-13.2 40.9-44.1 40.9zm67.5 0h-16v-82h16zM544 433c0 8.2-6.8 15-15 15H128c189.6-35.6 382.7-139.2 416-160zM74.1 191.6c-5.2-4.9-11.6-6.6-21.9-6.6H48v54.2h4.2c10.3 0 17-2 21.9-6.4 5.7-5.2 8.9-12.8 8.9-20.7s-3.2-15.5-8.9-20.5z\"],\n    \"cc-jcb\": [576, 512, [], \"f24b\", \"M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z\"],\n    \"cc-mastercard\": [576, 512, [], \"f1f1\", \"M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z\"],\n    \"cc-paypal\": [576, 512, [], \"f1f4\", \"M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z\"],\n    \"cc-stripe\": [576, 512, [], \"f1f5\", \"M492.4 220.8c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7zM375 223.4c-8.2 0-13.3 2.9-17 7l.2 52.8c3.5 3.7 8.5 6.7 16.8 6.7 13.1 0 21.9-14.3 21.9-33.4 0-18.6-9-33.2-21.9-33.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM122.2 281.1c0 25.6-20.3 40.1-49.9 40.3-12.2 0-25.6-2.4-38.8-8.1v-33.9c12 6.4 27.1 11.3 38.9 11.3 7.9 0 13.6-2.1 13.6-8.7 0-17-54-10.6-54-49.9 0-25.2 19.2-40.2 48-40.2 11.8 0 23.5 1.8 35.3 6.5v33.4c-10.8-5.8-24.5-9.1-35.3-9.1-7.5 0-12.1 2.2-12.1 7.7 0 16 54.3 8.4 54.3 50.7zm68.8-56.6h-27V275c0 20.9 22.5 14.4 27 12.6v28.9c-4.7 2.6-13.3 4.7-24.9 4.7-21.1 0-36.9-15.5-36.9-36.5l.2-113.9 34.7-7.4v30.8H191zm74 2.4c-4.5-1.5-18.7-3.6-27.1 7.4v84.4h-35.5V194.2h30.7l2.2 10.5c8.3-15.3 24.9-12.2 29.6-10.5h.1zm44.1 91.8h-35.7V194.2h35.7zm0-142.9l-35.7 7.6v-28.9l35.7-7.6zm74.1 145.5c-12.4 0-20-5.3-25.1-9l-.1 40.2-35.5 7.5V194.2h31.3l1.8 8.8c4.9-4.5 13.9-11.1 27.8-11.1 24.9 0 48.4 22.5 48.4 63.8 0 45.1-23.2 65.5-48.6 65.6zm160.4-51.5h-69.5c1.6 16.6 13.8 21.5 27.6 21.5 14.1 0 25.2-3 34.9-7.9V312c-9.7 5.3-22.4 9.2-39.4 9.2-34.6 0-58.8-21.7-58.8-64.5 0-36.2 20.5-64.9 54.3-64.9 33.7 0 51.3 28.7 51.3 65.1 0 3.5-.3 10.9-.4 12.9z\"],\n    \"cc-visa\": [576, 512, [], \"f1f0\", \"M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z\"],\n    \"discourse\": [448, 512, [], \"f393\", \"M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z\"],\n    \"docker\": [640, 512, [], \"f395\", \"M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z\"],\n    \"github\": [496, 512, [], \"f09b\", \"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\"],\n    \"instagram\": [448, 512, [], \"f16d\", \"M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z\"],\n    \"microsoft\": [448, 512, [], \"f3ca\", \"M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z\"],\n    \"rev\": [448, 512, [], \"f5b2\", \"M289.67 274.89a65.57 65.57 0 1 1-65.56-65.56 65.64 65.64 0 0 1 65.56 65.56zm139.55-5.05h-.13a204.69 204.69 0 0 0-74.32-153l-45.38 26.2a157.07 157.07 0 0 1 71.81 131.84C381.2 361.5 310.73 432 224.11 432S67 361.5 67 274.88c0-81.88 63-149.27 143-156.43v39.12l108.77-62.79L210 32v38.32c-106.7 7.25-191 96-191 204.57 0 111.59 89.12 202.29 200.06 205v.11h210.16V269.84z\"],\n    \"slack\": [448, 512, [], \"f198\", \"M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z\"],\n    \"twitter\": [512, 512, [], \"f099\", \"M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z\"]\n  };\n\n  bunker(function () {\n    defineIcons('fab', icons);\n  });\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/js/duotone.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"abacus\": [576, 512, [], \"f640\", [\"M192 440h-32v-48h32zM160 72v48h32V72zm96 160v48h32v-48zm-96 0v48h32v-48zm96 208h160v-48H256zm96-160h128v-48H352zM544 0a32 32 0 0 0-32 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32a32 32 0 0 0-32-32zM416 72H256v48h160zM32 0A32 32 0 0 0 0 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32A32 32 0 0 0 32 0z\", \"M144 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm-96 160h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm192 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm-96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zM464 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM144 352h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm224 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16z\"]],\n    \"align-slash\": [640, 512, [], \"f846\", [\"M528 352h-31.46l-82.81-64H528a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16zM96 304v32a16 16 0 0 0 16 16h175.21l-82.8-64H112a16 16 0 0 0-16 16zM528 96a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16H112a15.82 15.82 0 0 0-15 11.18L165.31 96zM112 416a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h340.83L370 416zm416-256H248.12l82.81 64H528a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M633.82 458.1L45.46 3.38A16 16 0 0 0 23 6.19L3.37 31.46a16 16 0 0 0 2.81 22.45l588.36 454.72a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45z\"]],\n    \"atom-alt\": [448, 512, [], \"f5d3\", [\"M424.37305,55.69141C408.294,39.61914,385.50879,32,358.58252,32,319.82764,32,272.43359,48.127,224,77.14453a493.86641,493.86641,0,0,0-58.042,41.03711C140.58252,138.875,114.57666,162.5918,85.75635,197.916a374.25237,374.25237,0,0,0,35.70263,58.082A505.23427,505.23427,0,0,1,224,153.65625a377.23937,377.23937,0,0,1,58.042-35.47266c70.01221-34.334,95.22461-19.07421,97.0625-17.23632,9.54248,9.543,7.67432,46.94531-16.86084,96.96875A492.27615,492.27615,0,0,1,403.06543,256C452.27637,173.91992,463.59277,94.90039,424.37305,55.69141ZM224,358.3418a377.44678,377.44678,0,0,1-58.042,35.47461c-70.01221,34.334-95.22461,19.07421-97.0625,17.23632-9.54248-9.543-7.67432-46.94335,16.86084-96.96875A492.27615,492.27615,0,0,1,44.93457,256C-4.27637,338.08008-15.59277,417.09961,23.627,456.30664,39.70605,472.38086,62.49121,480,89.41748,480c38.75488,0,86.14893-16.127,134.58252-45.14453a493.86641,493.86641,0,0,0,58.042-41.03711c25.38965-20.70508,51.42285-44.45606,80.20166-79.73438A373.962,373.962,0,0,0,326.541,256,505.23427,505.23427,0,0,1,224,358.3418Z\", \"M224,287.98828a31.99414,31.99414,0,1,0-32-31.99414A31.98908,31.98908,0,0,0,224,287.98828ZM121.46094,255.99805A374.13921,374.13921,0,0,1,85.7583,197.916c-24.53906-50.02344-26.40625-87.42579-16.86328-96.9668,1.83984-1.83789,27.05078-17.10156,97.062,17.23242A494.241,494.241,0,0,1,224,77.14453C175.5625,48.13086,128.16406,32,89.41846,32c-26.9336,0-49.707,7.61523-65.793,23.69141C-15.59326,94.90039-4.27686,173.91992,44.93408,256A492.0174,492.0174,0,0,0,85.7583,314.084c28.79639,35.30274,54.85889,59.07227,80.19873,79.73243A377.429,377.429,0,0,0,224,358.3418,505.131,505.131,0,0,1,121.46094,255.99805ZM403.06592,256a492.0174,492.0174,0,0,0-40.82422-58.084c-28.84326-35.35547-54.89795-59.10352-80.19873-79.73243A377.4073,377.4073,0,0,0,224,153.65625,505.20556,505.20556,0,0,1,326.53906,256a373.849,373.849,0,0,1,35.70264,58.084c24.53906,50.02149,26.40625,87.42383,16.86328,96.9668-1.83984,1.83789-27.05078,17.10156-97.062-17.23242A494.241,494.241,0,0,1,224,434.85547C272.4375,463.86914,319.83594,480,358.58154,480c26.9336,0,49.707-7.61523,65.793-23.69336C463.59326,417.09961,452.27686,338.08008,403.06592,256Z\"]],\n    \"badge-check\": [512, 512, [], \"f336\", [\"M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z\", \"M367.2 211.75l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.06 15.56z\"]],\n    \"bell\": [448, 512, [], \"f0f3\", [\"M448 384c-.1 16.4-13 32-32.1 32H32.08C13 416 .09 400.4 0 384a31.25 31.25 0 0 1 8.61-21.71c19.32-20.76 55.47-52 55.47-154.29 0-77.7 54.48-139.9 127.94-155.16V32a32 32 0 1 1 64 0v20.84C329.42 68.1 383.9 130.3 383.9 208c0 102.3 36.15 133.53 55.47 154.29A31.27 31.27 0 0 1 448 384z\", \"M160 448h128a64 64 0 0 1-128 0z\"]],\n    \"books\": [576, 512, [], \"f5db\", [\"M96 0H32A32 32 0 0 0 0 32v64h128V32A32 32 0 0 0 96 0zM0 384h128V128H0zm0 96a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H0zm513.62-17.78L401.08 42.71l-60.26 16.14 112.35 418.8c.11.39.2.79.29 1.18l60.29-16.15c-.04-.15-.09-.3-.13-.46zM160 480a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H160zM256 0h-64a32 32 0 0 0-32 32v64h124.79l-8-29.65a23.94 23.94 0 0 1 11.17-27V32A32 32 0 0 0 256 0zm-96 384h128V128H160z\", \"M0 416h128v-32H0zm0-288h128V96H0zm575.17 317.65L460.39 17.78a23.89 23.89 0 0 0-29.18-17h-.09L415.73 5a24 24 0 0 0-16.9 29.36l114.79 427.86a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.35zM160 416h128v-32H160zM338.39 49.78a23.89 23.89 0 0 0-29.18-17h-.09L293.73 37a24 24 0 0 0-16.9 29.36l8 29.65H160v32h128V108l103.62 386.22a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.33z\"]],\n    \"brackets-curly\": [576, 512, [], \"f7ea\", [\"M566.64 233.37a32 32 0 0 1 0 45.25l-45.25 45.25a32 32 0 0 0-9.39 22.64V384a96 96 0 0 1-96 96h-48a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h48a32 32 0 0 0 32-32v-37.48a96 96 0 0 1 28.13-67.89L498.76 256l-22.62-22.62A96 96 0 0 1 448 165.47V128a32 32 0 0 0-32-32h-48a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h48a96 96 0 0 1 96 96v37.48a32 32 0 0 0 9.38 22.65l45.25 45.24z\", \"M208 32h-48a96 96 0 0 0-96 96v37.48a32.12 32.12 0 0 1-9.38 22.65L9.38 233.37a32 32 0 0 0 0 45.25l45.25 45.25A32.05 32.05 0 0 1 64 346.51V384a96 96 0 0 0 96 96h48a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-48a32 32 0 0 1-32-32v-37.48a96 96 0 0 0-28.13-67.89L77.26 256l22.63-22.63A96 96 0 0 0 128 165.48V128a32 32 0 0 1 32-32h48a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]],\n    \"chart-network\": [640, 512, [], \"f78a\", [\"M64 240a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64zm88 80h48v-32h-48zm294.4-106.8l19.2 25.6 48-36-19.2-25.6zM576 64a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64z\", \"M576 384a63.84 63.84 0 0 0-38.3 13l-96-57.6a109.91 109.91 0 0 0 6.3-35.5 111.94 111.94 0 0 0-112-112 108.64 108.64 0 0 0-24.4 2.9l-40.8-87.4A63.84 63.84 0 1 0 224 128c1.1 0 2.1-.3 3.2-.3l41 87.8C241.5 235.9 224 267.8 224 304a111.71 111.71 0 0 0 193.2 76.7l95.8 57.5a63.87 63.87 0 1 0 63-54.2zm-240-32a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]],\n    \"chart-scatter\": [512, 512, [], \"f7ee\", [\"M512 400v32a16 16 0 0 1-16 16H32a32 32 0 0 1-32-32V80a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16v304h432a16 16 0 0 1 16 16z\", \"M160 256a32 32 0 1 0 32 32 32 32 0 0 0-32-32zM416 96a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-224 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm192 160a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-96-64a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]],\n    \"check\": [512, 512, [], \"f00c\", [\"M504.5 144.42L264.75 385.5 192 312.59l240.11-241a25.49 25.49 0 0 1 36.06-.14l.14.14L504.5 108a25.86 25.86 0 0 1 0 36.42z\", \"M264.67 385.59l-54.57 54.87a25.5 25.5 0 0 1-36.06.14l-.14-.14L7.5 273.1a25.84 25.84 0 0 1 0-36.41l36.2-36.41a25.49 25.49 0 0 1 36-.17l.16.17z\"]],\n    \"circle\": [512, 512, [], \"f111\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 424c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\", \"M256 432c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\"]],\n    \"clouds\": [640, 512, [], \"f744\", [\"M161.6 288H96a96 96 0 0 1 0-192c.6 0 1.1.2 1.6.2C105.3 41.9 151.6 0 208 0a111.61 111.61 0 0 1 104.5 72.7A95.07 95.07 0 0 1 352 64a96 96 0 0 1 96 96 93 93 0 0 1-7 34.7 110.5 110.5 0 0 0-31.6 11.8A142.54 142.54 0 0 0 304 160c-73.9 0-134.3 56.2-142.4 128z\", \"M640 416a96 96 0 0 1-96 96H224a96 96 0 0 1-96-96c0-42.5 27.8-78.2 66.1-90.8A113.72 113.72 0 0 1 192 304a111.94 111.94 0 0 1 112-112c43.2 0 80.4 24.9 99 60.8 14.7-17.5 36.4-28.8 61-28.8a80 80 0 0 1 80 80 78.09 78.09 0 0 1-1.6 16.2c.5 0 1-.2 1.6-.2a96 96 0 0 1 96 96z\"]],\n    \"cogs\": [640, 512, [], \"f085\", [\"M638.41 387a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4L602 335a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6 12.36 12.36 0 0 0-15.1 5.4l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 44.9c-29.6-38.5 14.3-82.4 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79zm136.8-343.8a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4l8.2-14.3a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6A12.36 12.36 0 0 0 552 7.19l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 45c-29.6-38.5 14.3-82.5 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79z\", \"M420 303.79L386.31 287a173.78 173.78 0 0 0 0-63.5l33.7-16.8c10.1-5.9 14-18.2 10-29.1-8.9-24.2-25.9-46.4-42.1-65.8a23.93 23.93 0 0 0-30.3-5.3l-29.1 16.8a173.66 173.66 0 0 0-54.9-31.7V58a24 24 0 0 0-20-23.6 228.06 228.06 0 0 0-76 .1A23.82 23.82 0 0 0 158 58v33.7a171.78 171.78 0 0 0-54.9 31.7L74 106.59a23.91 23.91 0 0 0-30.3 5.3c-16.2 19.4-33.3 41.6-42.2 65.8a23.84 23.84 0 0 0 10.5 29l33.3 16.9a173.24 173.24 0 0 0 0 63.4L12 303.79a24.13 24.13 0 0 0-10.5 29.1c8.9 24.1 26 46.3 42.2 65.7a23.93 23.93 0 0 0 30.3 5.3l29.1-16.7a173.66 173.66 0 0 0 54.9 31.7v33.6a24 24 0 0 0 20 23.6 224.88 224.88 0 0 0 75.9 0 23.93 23.93 0 0 0 19.7-23.6v-33.6a171.78 171.78 0 0 0 54.9-31.7l29.1 16.8a23.91 23.91 0 0 0 30.3-5.3c16.2-19.4 33.7-41.6 42.6-65.8a24 24 0 0 0-10.5-29.1zm-151.3 4.3c-77 59.2-164.9-28.7-105.7-105.7 77-59.2 164.91 28.7 105.71 105.7z\"]],\n    \"comment-dots\": [512, 512, [], \"f4ad\", [\"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5a8 8 0 0 0-1.5 8.7A7.83 7.83 0 0 0 8 480c66.3 0 116-31.8 140.6-51.4A305 305 0 0 0 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32z\", \"M128 208a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]],\n    \"concierge-bell\": [512, 512, [], \"f562\", [\"M512 400v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h480a16 16 0 0 1 16 16zM208 112h16v18.29a224.73 224.73 0 0 1 64 0V112h16a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16z\", \"M480 352H32c0-123.71 100.29-224 224-224s224 100.29 224 224z\"]],\n    \"dot-circle\": [512, 512, [], \"f192\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm124.45 372.45A176 176 0 1 1 432 256a174.85 174.85 0 0 1-51.55 124.45z\", \"M256 336a80 80 0 1 1 80-80 80.09 80.09 0 0 1-80 80z\"]],\n    \"envelope\": [512, 512, [], \"f0e0\", [\"M256.47 352h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V400a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V183.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52zM464 64H48a48 48 0 0 0-48 48v19a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4 23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131v-19a48 48 0 0 0-48-48z\", \"M512 131v52.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V131a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.69 12.12 49.75 41.4 72.93 41.4h.94c23.18 0 56.24-29.28 72.93-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131z\"]],\n    \"exchange-alt\": [512, 512, [], \"f362\", [\"M128 272v48h360a24 24 0 0 1 24 24v16a24 24 0 0 1-24 24H128v48c0 21.44-25.94 32-41 17L7 369a24 24 0 0 1 0-33.94l80-80c15.14-15.12 41-4.35 41 16.94z\", \"M505 143.05a24 24 0 0 1 0 33.95l-80 80c-15 15-41 4.49-41-17v-48H24a24 24 0 0 1-24-24v-16a24 24 0 0 1 24-24h360V80c0-21.36 25.9-32 41-17z\"]],\n    \"file-alt\": [384, 512, [], \"f15c\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zm-96 244a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM276 352H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12z\"]],\n    \"file-code\": [384, 512, [], \"f1c9\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zM141.79 379.54l-19.58 20.84a5.41 5.41 0 0 1-7.64.24l-64.86-60.69a5.37 5.37 0 0 1-.24-7.6l.25-.25 64.86-60.7a5.42 5.42 0 0 1 7.64.24l19.58 20.85a5.4 5.4 0 0 1-.25 7.62l-.13.12L100.65 336l40.76 35.8a5.4 5.4 0 0 1 .49 7.62zm31.71 71.25l-27.45-8a5.38 5.38 0 0 1-3.67-6.67l61.49-211.24a5.38 5.38 0 0 1 6.68-3.64l27.45 8a5.4 5.4 0 0 1 3.63 6.67l-61.45 211.2a5.4 5.4 0 0 1-6.68 3.68zm161-111.12l-.25.25-64.86 60.69a5.42 5.42 0 0 1-7.64-.23l-19.58-20.84a5.37 5.37 0 0 1 .26-7.6l.13-.12L283.35 336l-40.76-35.8a5.4 5.4 0 0 1-.49-7.62l.11-.12 19.58-20.85a5.42 5.42 0 0 1 7.64-.24l64.86 60.7a5.36 5.36 0 0 1 .25 7.6z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM141.41 371.8L100.65 336l40.76-35.8.13-.12a5.4 5.4 0 0 0 .25-7.62l-19.58-20.85a5.42 5.42 0 0 0-7.64-.24l-64.86 60.7-.25.25a5.37 5.37 0 0 0 .24 7.6l64.86 60.69a5.41 5.41 0 0 0 7.64-.24l19.58-20.84.11-.12a5.4 5.4 0 0 0-.48-7.61zm100.22-135.93a5.4 5.4 0 0 0-3.63-6.67l-27.45-8a5.38 5.38 0 0 0-6.68 3.64l-61.5 211.29a5.38 5.38 0 0 0 3.63 6.67l27.45 8a5.4 5.4 0 0 0 6.68-3.68l61.44-211.22zm92.66 96.2l-64.86-60.7a5.42 5.42 0 0 0-7.64.24l-19.58 20.85-.11.12a5.4 5.4 0 0 0 .49 7.62l40.76 35.8-40.76 35.8-.13.12a5.37 5.37 0 0 0-.26 7.6l19.58 20.84a5.42 5.42 0 0 0 7.64.23l64.86-60.69.25-.25a5.36 5.36 0 0 0-.25-7.6z\"]],\n    \"globe\": [496, 512, [], \"f0ac\", [\"M340.45,320H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256,575,575,0,0,1,340.45,320ZM160.2,160H335.8c-.41-2.31-.84-4.62-1.28-6.91-6-30.85-14.42-58.37-25.13-81.78C299.54,49.77,288,32.54,276.05,21.48,266.38,12.53,256.94,8,248,8s-18.38,4.53-28,13.48c-12,11.06-23.49,28.29-33.34,49.83C176,94.72,167.5,122.24,161.53,153.09,161,155.38,160.61,157.69,160.2,160ZM120,256a608,608,0,0,1,3.34-64H8.35a249.52,249.52,0,0,0,0,128h115A608,608,0,0,1,120,256Zm367.62-64h-115A608.06,608.06,0,0,1,376,256a608,608,0,0,1-3.34,64h115a249.52,249.52,0,0,0,0-128ZM476.7,160A248.62,248.62,0,0,0,315.58,17.32c24.13,33,42.89,83.15,52.75,142.68ZM315.58,494.68A248.59,248.59,0,0,0,476.71,352H368.33C358.47,411.53,339.71,461.68,315.58,494.68ZM335.8,352H160.2c.41,2.31.84,4.62,1.28,6.91,6,30.85,14.42,58.37,25.13,81.78,9.85,21.54,21.38,38.77,33.34,49.83,9.67,9,19.11,13.48,28.05,13.48s18.38-4.53,28.05-13.48c12-11.06,23.49-28.29,33.34-49.83,10.71-23.41,19.16-50.93,25.13-81.78C335,356.62,335.39,354.31,335.8,352ZM180.42,17.32A248.59,248.59,0,0,0,19.29,160H127.67C137.53,100.47,156.29,50.32,180.42,17.32ZM19.29,352A248.59,248.59,0,0,0,180.42,494.68c-24.13-33-42.89-83.15-52.75-142.68Z\", \"M376,256a608,608,0,0,0-3.34-64h115a245.72,245.72,0,0,0-10.92-32H368.33c-9.86-59.53-28.62-109.68-52.75-142.68A248.23,248.23,0,0,0,248,8c8.94,0,18.38,4.53,28.05,13.48,12,11.06,23.49,28.29,33.34,49.83,10.71,23.41,19.16,50.93,25.13,81.78.44,2.29.87,4.6,1.28,6.91H160.2c.41-2.31.84-4.62,1.28-6.91,6-30.85,14.42-58.37,25.13-81.78C196.46,49.77,208,32.54,220,21.48,229.62,12.53,239.06,8,248,8a248.23,248.23,0,0,0-67.58,9.32c-24.13,33-42.89,83.15-52.75,142.68H19.29A245.72,245.72,0,0,0,8.37,192h115a613.93,613.93,0,0,0,0,128H8.37a245.72,245.72,0,0,0,10.92,32H127.67c9.86,59.53,28.62,109.68,52.75,142.68A248.23,248.23,0,0,0,248,504c-8.94,0-18.38-4.53-28.05-13.48-12-11.06-23.49-28.29-33.34-49.83-10.71-23.41-19.16-50.93-25.13-81.78-.44-2.29-.87-4.6-1.28-6.91H335.8c-.41,2.31-.84,4.62-1.28,6.91-6,30.85-14.42,58.37-25.13,81.78-9.85,21.54-21.38,38.77-33.34,49.83-9.67,9-19.11,13.48-28.05,13.48a248.23,248.23,0,0,0,67.58-9.32c24.13-33,42.89-83.15,52.75-142.68H476.71a245.72,245.72,0,0,0,10.92-32h-115A605.37,605.37,0,0,0,376,256Zm-35.54,64H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256a575,575,0,0,1-3.55,64Z\"]],\n    \"globe-africa\": [496, 512, [], \"f57c\", [\"M491.33,208H423.5A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05A249.89,249.89,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256A249.51,249.51,0,0,0,491.33,208Z\", \"M423.5,208A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05C386,23.7,471,104.24,491.34,208Z\"]],\n    \"globe-americas\": [496, 512, [], \"f57d\", [\"M489.55,312.41C464,422.22,365.59,504,248,504,111,504,0,393,0,256A247,247,0,0,1,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311l-13.71-13.67A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A247,247,0,0,1,248,8C351.83,8,440.71,71.76,477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1Z\", \"M321.39,297.36A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A249,249,0,0,0,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311ZM477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1,55.64,29.22a249.21,249.21,0,0,0-11.88-150.14Z\"]],\n    \"globe-asia\": [496, 512, [], \"f57e\", [\"M312,16.35V50.73a28,28,0,0,1-11.12,22.35l-41.41,31.27a8,8,0,0,0,.86,13.81l10.83,5.41A16,16,0,0,1,280,137.88V216a8,8,0,0,1-8,8h-3.06a8,8,0,0,1-7.15-4.42,4.47,4.47,0,0,0-1.72-1.86,4.42,4.42,0,0,0-6.06,1.54h0l-17.34,29A16,16,0,0,1,222.94,256h-.31a16,16,0,0,0-11.32,4.69l-5.66,5.66a8,8,0,0,0,0,11.31l5.66,5.66A16,16,0,0,1,216,294.63V304a16,16,0,0,1-16,16h-6.1a16,16,0,0,1-14.28-8.85L157,265.92a8,8,0,0,0-10.72-3.6h0a8.14,8.14,0,0,0-2.11,1.53l-19.47,19.46A16,16,0,0,1,113.38,288H2.05C17.74,409.88,121.84,504,248,504c137,0,248-111,248-248C496,141.13,418,44.56,312,16.35Zm96,342.08a16,16,0,0,1-4.69,11.31l-9.57,9.57A16,16,0,0,1,382.43,384H367.27a16,16,0,0,1-11.36-4.74l-13-13a26.78,26.78,0,0,0-25.42-7l-21.27,5.32a15.86,15.86,0,0,1-3.88.48H282a16,16,0,0,1-11.24-4.69l-11.91-11.91a8,8,0,0,1-2.34-5.66V332.6a8,8,0,0,1,5-7.43l39.34-15.74a26.35,26.35,0,0,0,5.59-3.05l23.71-16.89a8,8,0,0,1,4.64-1.48h12.14a8,8,0,0,1,7.39,4.93l5.35,12.85a4,4,0,0,0,3.69,2.46h3.8a4,4,0,0,0,3.84-2.88l4.16-14.49A4,4,0,0,1,379,288h6.06a4,4,0,0,1,4,4v13a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,1,408,333.83Z\", \"M260.07,217.72a4.47,4.47,0,0,1,1.72,1.86,8,8,0,0,0,7.15,4.42H272a8,8,0,0,0,8-8V137.88a16,16,0,0,0-8.84-14.31l-10.83-5.41a8,8,0,0,1-.86-13.81l41.41-31.27A28,28,0,0,0,312,50.73V16.35A248.23,248.23,0,0,0,248,8C111,8,0,119,0,256a249.89,249.89,0,0,0,2.05,32H113.38a16,16,0,0,0,11.31-4.69l19.47-19.46A8,8,0,0,1,157,265.92l22.62,45.23A16,16,0,0,0,193.9,320H200a16,16,0,0,0,16-16v-9.37a16,16,0,0,0-4.69-11.31l-5.66-5.66a8,8,0,0,1,0-11.31l5.66-5.66A16,16,0,0,1,222.63,256h.31a16,16,0,0,0,13.72-7.77L254,219.28a4.42,4.42,0,0,1,6.05-1.57Zm143.24,104.8L391.4,310.61a8,8,0,0,1-2.34-5.66V292a4,4,0,0,0-4-4H379a4,4,0,0,0-3.84,2.88L371,305.37a4,4,0,0,1-3.84,2.88h-3.8a4,4,0,0,1-3.69-2.46l-5.35-12.85a8,8,0,0,0-7.39-4.93H334.79a8,8,0,0,0-4.64,1.48l-23.71,16.89a26.35,26.35,0,0,1-5.59,3.05l-39.34,15.74a8,8,0,0,0-5,7.43v10.2a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,0,282,365.06h10.34a15.86,15.86,0,0,0,3.88-.48l21.27-5.32a26.78,26.78,0,0,1,25.42,7l13,13A16,16,0,0,0,367.27,384h15.16a16,16,0,0,0,11.31-4.69l9.57-9.57A16,16,0,0,0,408,358.43v-24.6a16,16,0,0,0-4.69-11.31Z\"]],\n    \"globe-europe\": [496, 512, [], \"f7a2\", [\"M487.54,320.4H438.9a15.8,15.8,0,0,1-11.4-4.8l-32-32.6a11.92,11.92,0,0,1,.1-16.7l12.5-12.5v-8.7a11.37,11.37,0,0,0-3.3-8l-9.4-9.4a11.37,11.37,0,0,0-8-3.3h-16a11.31,11.31,0,0,1-8-19.3l9.4-9.4a11.37,11.37,0,0,1,8-3.3h32a11.35,11.35,0,0,0,11.3-11.3v-9.4a11.35,11.35,0,0,0-11.3-11.3H376.1a16,16,0,0,0-16,16v4.5a16,16,0,0,1-10.9,15.2l-31.6,10.5a8,8,0,0,0-5.5,7.6v2.2a8,8,0,0,1-8,8h-16a8,8,0,0,1-8-8,8,8,0,0,0-8-8H269a8.14,8.14,0,0,0-7.2,4.4l-9.4,18.7a15.94,15.94,0,0,1-14.3,8.8H216a16,16,0,0,1-16-16V199a16,16,0,0,1,4.7-11.3l20.1-20.1a24.77,24.77,0,0,0,7.2-17.5,8,8,0,0,1,5.5-7.6l40-13.3a11.66,11.66,0,0,0,4.4-2.7l26.8-26.8a11.31,11.31,0,0,0-8-19.3H280l-16,16v8a8,8,0,0,1-8,8H240a8,8,0,0,1-8-8v-20a8.05,8.05,0,0,1,3.2-6.4l82.42-60.08A247.79,247.79,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504a251.57,251.57,0,0,0,32.1-2.06V448.4a16,16,0,0,0-16-16H243.9c-10.8,0-26.7-5.3-35.4-11.8l-22.2-16.7a45.42,45.42,0,0,1-18.2-36.4V343.6a45.46,45.46,0,0,1,22.1-39l42.9-25.7a46.13,46.13,0,0,1,23.4-6.5h31.2a45.62,45.62,0,0,1,29.6,10.9l43.2,37.1h18.3a32,32,0,0,1,22.6,9.4l17.3,17.3.08.08C432,359.06,440,375.62,440,393.37V413A247.11,247.11,0,0,0,487.54,320.4ZM187.4,157.1a11.37,11.37,0,0,1-8,3.3h-16a11.31,11.31,0,0,1-8-19.3l25.4-25.4a11.31,11.31,0,0,1,19.3,8v16a11.37,11.37,0,0,1-3.3,8Z\", \"M187.4,157.1l9.4-9.4a11.37,11.37,0,0,0,3.3-8v-16a11.31,11.31,0,0,0-19.3-8l-25.4,25.4a11.31,11.31,0,0,0,8,19.3h16A11.37,11.37,0,0,0,187.4,157.1ZM418.78,347.18l-.08-.08-17.3-17.3a32,32,0,0,0-22.6-9.4H360.5l-43.2-37.1a45.62,45.62,0,0,0-29.6-10.9H256.5a46.13,46.13,0,0,0-23.4,6.5l-42.9,25.7a45.46,45.46,0,0,0-22.1,39v23.9a45.42,45.42,0,0,0,18.2,36.4l22.2,16.7c8.7,6.5,24.6,11.8,35.4,11.8h20.2a16,16,0,0,1,16,16v53.54A247.57,247.57,0,0,0,440,413V393.37C440,375.62,432,359.06,418.78,347.18ZM317.62,17.92,235.2,78a8.05,8.05,0,0,0-3.2,6.4v20a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-8l16-16h20.7a11.31,11.31,0,0,1,8,19.3l-26.8,26.8a11.66,11.66,0,0,1-4.4,2.7l-40,13.3a8,8,0,0,0-5.5,7.6,24.77,24.77,0,0,1-7.2,17.5l-20.1,20.1A16,16,0,0,0,200,199v25.3a16,16,0,0,0,16,16h22.1a15.94,15.94,0,0,0,14.3-8.8l9.4-18.7a8.14,8.14,0,0,1,7.2-4.4h3.1a8,8,0,0,1,8,8,8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-2.2a8,8,0,0,1,5.5-7.6l31.6-10.5a16,16,0,0,0,10.9-15.2v-4.5a16,16,0,0,1,16-16h36.7a11.35,11.35,0,0,1,11.3,11.3v9.4a11.35,11.35,0,0,1-11.3,11.3h-32a11.37,11.37,0,0,0-8,3.3l-9.4,9.4a11.31,11.31,0,0,0,8,19.3h16a11.37,11.37,0,0,1,8,3.3l9.4,9.4a11.37,11.37,0,0,1,3.3,8v8.7l-12.5,12.5a11.92,11.92,0,0,0-.1,16.7l32,32.6a15.8,15.8,0,0,0,11.4,4.8h48.64A248.29,248.29,0,0,0,496,256C496,143.18,420.71,48,317.62,17.92Z\"]],\n    \"graduation-cap\": [640, 512, [], \"f19d\", [\"M323.07 175.7L118.8 215.6a48.1 48.1 0 0 0-38.74 44.73 32 32 0 0 1 2.21 53.94l25.4 114.26A16 16 0 0 1 92 448H35.94a16 16 0 0 1-15.61-19.47l25.39-114.27a32 32 0 0 1 2.33-54 80.16 80.16 0 0 1 64.62-76.07l204.26-39.89a16 16 0 1 1 6.14 31.4z\", \"M622.33 198.8l-279 85.7a80 80 0 0 1-46.79 0L99.67 224a47.84 47.84 0 0 1 19.13-8.39l204.27-39.9a16 16 0 1 0-6.14-31.4l-204.26 39.88a79.87 79.87 0 0 0-47.57 29.18l-47.44-14.58c-23.54-7.23-23.54-38.36 0-45.59L296.6 67.5a79.92 79.92 0 0 1 46.8 0l278.93 85.7c23.55 7.24 23.55 38.36 0 45.6zM352.79 315.09a111.94 111.94 0 0 1-65.59 0l-145-44.55L128 384c0 35.35 86 64 192 64s192-28.65 192-64l-14.19-113.47z\"]],\n    \"history\": [512, 512, [], \"f1da\", [\"M141.68 400.23a184 184 0 1 0-11.75-278.3l50.76 50.76c10.08 10.08 2.94 27.31-11.32 27.31H24a16 16 0 0 1-16-16V38.63c0-14.26 17.23-21.4 27.31-11.32l49.38 49.38A247.14 247.14 0 0 1 256 8c136.81 0 247.75 110.78 248 247.53S392.82 503.9 256.18 504a247 247 0 0 1-155.82-54.91 24 24 0 0 1-1.84-35.61l11.27-11.27a24 24 0 0 1 31.89-1.98z\", \"M288 152v104.35L328.7 288a24 24 0 0 1 4.21 33.68l-9.82 12.62a24 24 0 0 1-33.68 4.21L224 287.65V152a24 24 0 0 1 24-24h16a24 24 0 0 1 24 24z\"]],\n    \"key\": [512, 512, [], \"f084\", [\"M303.06 348.91l.1.09-24 27a24 24 0 0 1-17.94 8H224v40a24 24 0 0 1-24 24h-40v40a24 24 0 0 1-24 24H24a24 24 0 0 1-24-24v-78a24 24 0 0 1 7-17l161.83-161.83-.11-.35a176.24 176.24 0 0 0 134.34 118.09z\", \"M336 0a176 176 0 1 0 176 176A176 176 0 0 0 336 0zm48 176a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]],\n    \"key-skeleton\": [512, 512, [], \"f6f3\", [\"M251.31 372.91a16 16 0 0 1 0 22.63l-15.77 15.77a16 16 0 0 1-22.62 0L176 374.4l-30.87 30.86 36.11 36.11a16 16 0 0 1 0 22.63l-43.16 43.17a16 16 0 0 1-22.62 0l-36.12-36.11-36.26 36.25a16 16 0 0 1-22.62 0L4.69 491.54a16 16 0 0 1 0-22.63l255.12-255.12a64.18 64.18 0 0 0 38.4 38.4L214.4 336l36.91 36.91z\", \"M448 0H320a64 64 0 0 0-64 64v128a64 64 0 0 0 64 64h128a64 64 0 0 0 64-64V64a64 64 0 0 0-64-64zm-73.37 182.63a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25zm64-64a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25z\"]],\n    \"laptop\": [640, 512, [], \"f109\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M512 64H128v256h384zm112 352H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16z\"]],\n    \"laptop-code\": [640, 512, [], \"f5fc\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16zM512 64H128v256h384zM289 250.34l-11.31 11.31a16 16 0 0 1-22.63 0l-58.35-58.34a16 16 0 0 1 0-22.63L255 122.34a16 16 0 0 1 22.63 0L289 133.65a16 16 0 0 1 0 22.63L253.25 192 289 227.71a16 16 0 0 1 0 22.63zm154.35-47L385 261.66a16 16 0 0 1-22.63 0L351 250.35a16 16 0 0 1 0-22.63L386.75 192 351 156.29a16 16 0 0 1 0-22.63l11.31-11.31a16 16 0 0 1 22.63 0l58.34 58.34a16 16 0 0 1 .04 22.63z\"]],\n    \"laptop-house\": [640, 512, [], \"e066\", [\"M272,416H96a32,32,0,0,1-32-32V219.88L42.34,239A16.51,16.51,0,0,1,33,242.48a16.22,16.22,0,0,1-10.63-4.78L3.55,216.42A16.4,16.4,0,0,1,0,207a16.15,16.15,0,0,1,4.78-10.61L216.58,8.92C222.12,4,232.64,0,240.05,0S258,4,263.5,8.92L352,87.3V48a16,16,0,0,1,16-16h32a16,16,0,0,1,16,16v96l59.24,52.42A16.31,16.31,0,0,1,480,207a16.51,16.51,0,0,1-3.58,9.44L469.74,224H332.8c-17.8,0-33.69,8.24-44.82,21.12V208a16,16,0,0,0-16-16H208a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16h64Z\", \"M629.33,448H592V288c0-17.67-12.89-32-28.8-32H332.8c-15.91,0-28.8,14.33-28.8,32V448H266.67A10.67,10.67,0,0,0,256,458.67v10.66A42.82,42.82,0,0,0,298.6,512H597.4A42.82,42.82,0,0,0,640,469.33V458.67A10.67,10.67,0,0,0,629.33,448ZM544,448H352V304H544Z\"]],\n    \"life-ring\": [512, 512, [], \"f1cd\", [\"M292.08 167l-.41-.17zm-66.62-2a96.5 96.5 0 0 1 61.08 0l112-112a248 248 0 0 0-285 0zm68.67 2.92l.52.22zm2.49 1.12l.46.21zM186.25 322l-.19-.21zm-5.51-6.36l.21.26zm1.65 2c.12.14.23.28.35.41-.12-.15-.23-.29-.35-.43zm1.74 2l.36.4zm135.51-135.51l.4.36zM177.51 311.29l-.1-.15zM304.18 173l.34.19zm11.42 7.78l.26.21zm6.36 5.51l-.21-.19zm-3.96-3.55l-.42-.35zm-11.6-8.43l.47.29zm4.68 3.09l.17.12zm-2-1.35l-.43-.29zm-9.71-5.68l-.1-.05zm-123.61 32.91c.1-.14.19-.28.28-.42-.04.14-.18.28-.28.42zm-1.45 2.28l.29-.46zm-1.31 2.25l.19-.32zm-2.6 4.77zm10.38-16.18l.21-.26zm2-2.43c-.12.13-.23.27-.35.41.08-.14.19-.28.31-.38zm-5.33 6.89l.1-.15zm-8.2 14.07c-.07.14-.13.29-.2.43.03-.14.09-.29.16-.43zm5.39 92l-.29-.46zm-4.27-7.53v.05zm2.82 5.14l-.19-.32zm2.61 4.21c.1.14.19.28.28.42-.08-.17-.22-.31-.32-.45zm-6.8-12.11c.07.14.13.29.2.43-.06-.14-.12-.29-.2-.43zm-2-76.7c0 .13-.1.25-.16.38.07-.13.16-.25.16-.38zm1.09-2.58c-.07.17-.15.34-.22.5.13-.16.13-.33.23-.5zm-.22 76.78c.07.16.15.33.22.5-.09-.17-.09-.34-.21-.5zm-1-2.46c.06.13.11.25.16.38-.03-.13-.12-.25-.18-.38zm172-84.19l.19.32zM327.51 320l.36-.4zm-1.57 1.71l-.19.21zM325.75 190l.19.21zm3.51 128c.12-.13.23-.27.35-.41-.12.17-.23.31-.35.41zm2-121.63l-.21-.26zm0 119.2l-.21.26zm-1.65-121.22c-.12-.14-.23-.28-.35-.41.12.16.23.3.35.44zm-1.74-2l-.36-.4zm6.62 8.35l.1.15zm.1 110.43l-.1.15zM398.49 53q2 1.41 4 2.85-2-1.43-4-2.85zM343.9 294.64c.07-.17.15-.34.22-.5-.07.16-.12.33-.22.5zm1.09-2.58c.05-.13.1-.25.16-.38-.06.13-.15.25-.15.38zm-3.35 7.36v-.05zm-5.4 9.3l-.28.42zm1.45-2.28l-.29.46zm1.35-2.25l-.19.32zm3.75-7.12c.07-.14.13-.29.2-.43-.07.14-.13.29-.2.43zM449 100.21q-1.41-1.75-2.85-3.46 1.39 1.71 2.85 3.46zM445.49 96c-1-1.18-2-2.35-3-3.51 1 1.19 2.01 2.36 3 3.51zm6.87 8.5q-1.36-1.74-2.76-3.5 1.4 1.76 2.76 3.53zm3.36 4.44c-.91-1.23-1.83-2.44-2.75-3.65.92 1.24 1.84 2.45 2.75 3.71zm-119.48 94.34l-.28-.42zm66.76-147q1.85 1.36 3.66 2.76-1.78-1.39-3.66-2.76zm12.23 9.62q-1.72-1.44-3.47-2.85 1.77 1.41 3.5 2.85zM411 62.4q-1.74-1.4-3.51-2.77Q409.24 61 411 62.4zm8.5 7.13q-1.74-1.53-3.51-3 1.75 1.47 3.49 3zm-75.38 148.33c-.07-.16-.15-.33-.22-.5.1.17.15.34.22.5zM184.49 192l-.36.4zM343 215.36c-.07-.14-.13-.29-.2-.43.06.14.12.29.2.43zm113.16-105.8c1 1.31 1.9 2.62 2.84 3.94-.95-1.32-1.89-2.63-2.85-3.94zM337.4 205.1l.29.46zm82.53-135.18a248.82 248.82 0 0 1 22.14 22.15 250.17 250.17 0 0 0-22.14-22.15zm-74.78 150.4a6.15 6.15 0 0 1-.16-.38c.01.13.1.25.16.38zM459 398.49a248 248 0 0 0 0-285L347 225.46a96.5 96.5 0 0 1 0 61.08zM341.67 212.63zM220.33 345.15l-.41-.17zm-2.46-1l-.52-.22zm-5.3-2.49l.1.05zM322 325.75l-.21.19zM309.14 336l-.43.29zm2-1.35l.17-.12zm4.48-3.34l.26-.21zm4-3.39l.4-.36zm-1.6 1.39l-.42.35zM215.38 343l-.46-.21zm-19-11.74l-.26-.21zm-4-3.39l-.4-.36zm-6.3-137.62l.19-.21zm4 135.5l.21.19zm15.52 11.94l-.47-.29zm2.26 1.35l-.34-.19zm78.72 8a96.5 96.5 0 0 1-61.08 0L113.51 459a248 248 0 0 0 285 0zM202.86 336l.43.29zm-2-1.35l-.17-.12zM416 445.49q1.77-1.49 3.51-3-1.77 1.51-3.51 3zm43-47c-.93 1.33-1.88 2.64-2.84 3.95.95-1.31 1.9-2.62 2.84-3.95zM411.79 449q1.74-1.41 3.47-2.85-1.72 1.39-3.47 2.85zm-4.32 3.42q1.77-1.38 3.51-2.77-1.74 1.35-3.51 2.72zM455.72 403q-1.37 1.85-2.76 3.66 1.4-1.78 2.76-3.66zm-10.23 13c-1 1.18-2 2.35-3 3.51 1-1.19 2.01-2.36 3-3.51zm3.46-4.18q-1.41 1.74-2.85 3.47 1.44-1.75 2.9-3.5zm.65-.81q1.39-1.74 2.77-3.51-1.37 1.74-2.77 3.5zm-150.17-69.38a.31.31 0 0 1-.1.05.31.31 0 0 0 .1-.05zm-5.3 2.49l.52-.22zm12.31-6.43l.47-.29zm-9.82 5.31l.46-.21zm7.56-4l.34-.19zm137.9 80.89a248.94 248.94 0 0 1-22.15 22.15 248.94 248.94 0 0 0 22.15-22.11zm-39.63 36.21q-2 1.44-4 2.85 2.04-1.37 4-2.81zM292.08 345l-.41.17zM403 455.72q1.85-1.37 3.66-2.76-1.78 1.4-3.66 2.76zM194 329.26l.42.35zM69.93 92.07a248.82 248.82 0 0 1 22.14-22.15 250.17 250.17 0 0 0-22.14 22.15zm30.28-29q-1.74 1.41-3.47 2.85 1.73-1.46 3.47-2.87zm90 123l-.21.19zm4.13-3.67l-.42.35zM109.55 55.86q2-1.44 4-2.85-2.03 1.41-4 2.85zM196.14 181l.26-.21zM104.53 59.63Q102.76 61 101 62.4q1.76-1.4 3.53-2.77zm.78-.59q1.81-1.4 3.66-2.76-1.84 1.37-3.66 2.72zm87.05 125.09l-.4.36zm22.56-14.92l.46-.21zm-2.25 1.11l-.1.05zm4.68-2.22l.52-.22zm2.57-1.08l.41-.17zm-17.06 9l.43-.29zm5-3.09l-.34.19zm-7.11 4.56l.17-.12zm4.38-2.92l.47-.29zM96.74 446.1q1.73 1.44 3.47 2.85-1.74-1.41-3.47-2.85zm-33.69-34.31q1.41 1.74 2.85 3.47-1.44-1.72-2.85-3.47zm3.46 4.21c1 1.18 2 2.35 3 3.51-1-1.19-2.01-2.36-3-3.51zm-10.23-13q1.36 1.85 2.76 3.66-1.39-1.78-2.76-3.66zm3.35 4.44q1.37 1.8 2.77 3.56-1.4-1.76-2.77-3.53zm32.89 35q1.74 1.53 3.51 3-1.77-1.44-3.51-2.97zM105.31 453q1.81 1.4 3.66 2.76-1.84-1.4-3.66-2.76zm8.2 6q-2-1.41-4-2.85 2.01 1.43 4 2.85zM101 449.6q1.74 1.39 3.51 2.77-1.75-1.37-3.51-2.77zm-45.15-47.16c-1-1.31-1.9-2.62-2.84-3.95.99 1.33 1.88 2.64 2.84 3.95zM65.9 96.75q-1.44 1.71-2.85 3.46 1.41-1.75 2.85-3.46zM56.29 109c.9-1.23 1.82-2.45 2.74-3.65-.92 1.17-1.84 2.39-2.74 3.65zm6.11-8q-1.4 1.74-2.76 3.51Q61 102.76 62.4 101zm7.12-8.5c-1 1.16-2 2.33-3 3.51.98-1.16 1.99-2.33 3-3.49zm23-23q1.74-1.53 3.51-3-1.77 1.5-3.51 3.03zm-.45 372.55a248.94 248.94 0 0 1-22.15-22.15 248.94 248.94 0 0 0 22.15 22.18zM165 286.54a96.5 96.5 0 0 1 0-61.08L53 113.51a248 248 0 0 0 0 285zm-109.11-177q-1.44 2-2.84 3.93 1.36-1.95 2.8-3.9z\", \"M347 225.46l112-111.95A249.4 249.4 0 0 0 398.49 53L286.54 165A96.26 96.26 0 0 1 347 225.46zm-182 61.08l-112 112a249.4 249.4 0 0 0 60.5 60.5L225.46 347A96.26 96.26 0 0 1 165 286.54zm-112-173l112 112a96.26 96.26 0 0 1 60.5-60.5L113.51 53A249.4 249.4 0 0 0 53 113.51zM286.54 347l112 112a249.4 249.4 0 0 0 60.5-60.5L347 286.54A96.26 96.26 0 0 1 286.54 347z\"]],\n    \"lightbulb\": [352, 512, [], \"f0eb\", [\"M175.45 0C73.44.31 0 83 0 176a175 175 0 0 0 43.56 115.78c16.52 18.85 42.36 58.22 52.21 91.45 0 .26.07.52.11.78h160.24c0-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45A175.9 175.9 0 0 0 175.45 0zm.55 96a80.09 80.09 0 0 0-80 80 16 16 0 0 1-32 0A112.12 112.12 0 0 1 176 64a16 16 0 0 1 0 32z\", \"M96.06 454.35L96 416h160v38.35a32 32 0 0 1-5.41 17.65l-17.09 25.73A32 32 0 0 1 206.86 512h-61.71a32 32 0 0 1-26.64-14.28L101.42 472a32 32 0 0 1-5.36-17.65z\"]],\n    \"list-alt\": [512, 512, [], \"f022\", [\"M464 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zM128 392a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm288 168a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12z\", \"M128 200a40 40 0 1 0-40-40 40 40 0 0 0 40 40zm0 16a40 40 0 1 0 40 40 40 40 0 0 0-40-40zm0 96a40 40 0 1 0 40 40 40 40 0 0 0-40-40z\"]],\n    \"list-ul\": [512, 512, [], \"f0ca\", [\"M496 384H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48z\"]],\n    \"lock-alt\": [448, 512, [], \"f30d\", [\"M152 225H72v-72C72 69.2 140.2 1 224 1s152 68.2 152 152v72h-80v-72a72 72 0 0 0-144 0z\", \"M400 225H48a48 48 0 0 0-48 48v192a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V273a48 48 0 0 0-48-48zM264 392a40 40 0 0 1-80 0v-48a40 40 0 0 1 80 0z\"]],\n    \"map-marker-alt\": [384, 512, [], \"f3c5\", [\"M192 0C86 0 0 86 0 192c0 77.41 27 99 172.27 309.67a24 24 0 0 0 39.46 0C357 291 384 269.41 384 192 384 86 298 0 192 0zm0 288a96 96 0 1 1 96-96 96 96 0 0 1-96 96z\", \"M192 256a64 64 0 1 1 64-64 64 64 0 0 1-64 64z\"]],\n    \"moon-stars\": [512, 512, [], \"f755\", [\"M320 32L304 0l-16 32-32 16 32 16 16 32 16-32 32-16zm138.7 149.3L432 128l-26.7 53.3L352 208l53.3 26.7L432 288l26.7-53.3L512 208z\", \"M332.2 426.4c8.1-1.6 13.9 8 8.6 14.5a191.18 191.18 0 0 1-149 71.1C85.8 512 0 426 0 320c0-120 108.7-210.6 227-188.8 8.2 1.6 10.1 12.6 2.8 16.7a150.3 150.3 0 0 0-76.1 130.8c0 94 85.4 165.4 178.5 147.7z\"]],\n    \"network-wired\": [640, 512, [], \"f6ff\", [\"M624 232H344v-40h-48v40H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h104v40h48v-40h304v40h48v-40h104a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z\", \"M224 192h192a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32H224a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32zm32-128h128v64H256zm320 256H416a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128h-96v-64h96zM224 320H64a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128H96v-64h96z\"]],\n    \"planet-ringed\": [512, 512, [], \"e020\", [\"M323.33815,323.33517C186.95939,459.71018,46.2602,540.11093,9.06777,502.9165c-23.48893-23.4909.01172-88.30917,54.81792-167.21379a206.56361,206.56361,0,0,0,25.02022,43.78446c-22.45765,34.20607-32.036,58.99194-23.71941,67.31053,18.59817,18.59624,119.10094-51.75539,224.47885-157.13342C395.04325,184.2882,465.39675,83.78336,446.79858,65.18712c-8.32054-8.3186-33.10638,1.26176-67.31045,23.71748a206.52984,206.52984,0,0,0-43.78245-25.0183C414.61019,9.082,479.42839-14.42259,502.91732,9.06832,540.10975,46.2608,459.70909,186.96211,323.33815,323.33517Z\", \"M448.0994,176.28016c-31.96573,46.02281-74.52549,96.81528-124.76125,147.055-50.24357,50.24168-101.034,92.79954-147.05874,124.76531,75.41614,31.25675,165.47721,16.29343,226.79531-45.02474S479.35807,251.69834,448.0994,176.28016Zm-25.02022-43.78251A208.22535,208.22535,0,0,0,403.07472,108.911c-81.2288-81.23281-212.93555-81.23281-294.16435,0-81.22881,81.23085-81.22881,212.93385,0,294.1647A208.25527,208.25527,0,0,0,132.497,423.08023c42.25117-27.73908,98.93242-75.1799,157.1684-133.41595C347.90133,231.43018,395.34013,174.75473,423.07918,132.49765Z\"]],\n    \"question-circle\": [512, 512, [], \"f059\", [\"M256 8C119 8 8 119.08 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 422a46 46 0 1 1 46-46 46.05 46.05 0 0 1-46 46zm40-131.33V300a12 12 0 0 1-12 12h-56a12 12 0 0 1-12-12v-4c0-41.06 31.13-57.47 54.65-70.66 20.17-11.31 32.54-19 32.54-34 0-19.82-25.27-33-45.7-33-27.19 0-39.44 13.14-57.3 35.79a12 12 0 0 1-16.67 2.13L148.82 170a12 12 0 0 1-2.71-16.26C173.4 113 208.16 90 262.66 90c56.34 0 116.53 44 116.53 102 0 77-83.19 78.21-83.19 106.67z\", \"M256 338a46 46 0 1 0 46 46 46 46 0 0 0-46-46zm6.66-248c-54.5 0-89.26 23-116.55 63.76a12 12 0 0 0 2.71 16.24l34.7 26.31a12 12 0 0 0 16.67-2.13c17.86-22.65 30.11-35.79 57.3-35.79 20.43 0 45.7 13.14 45.7 33 0 15-12.37 22.66-32.54 34C247.13 238.53 216 254.94 216 296v4a12 12 0 0 0 12 12h56a12 12 0 0 0 12-12v-1.33c0-28.46 83.19-29.67 83.19-106.67 0-58-60.19-102-116.53-102z\"]],\n    \"quote-left\": [512, 512, [], \"f10d\", [\"M464 256h-80v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H448a160 160 0 0 0-160 160v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\", \"M176 256H96v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H160A160 160 0 0 0 0 192v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\"]],\n    \"random\": [512, 512, [], \"f074\", [\"M505 359l-80-80c-15-15-41-4.47-41 17v40h-32l-52.78-56.55-53.33 57.14 70.55 75.6a12 12 0 0 0 8.77 3.81H384v40c0 21.46 26 32 41 17l80-80a24 24 0 0 0 0-34zM122.79 96H12a12 12 0 0 0-12 12v56a12 12 0 0 0 12 12h84l52.78 56.55 53.33-57.14-70.55-75.6a12 12 0 0 0-8.77-3.81z\", \"M505 119a24 24 0 0 1 0 34l-80 80c-15 15-41 4.48-41-17v-40h-32L131.56 412.19a12 12 0 0 1-8.77 3.81H12a12 12 0 0 1-12-12v-56a12 12 0 0 1 12-12h84L316.44 99.81a12 12 0 0 1 8.78-3.81H384V56c0-21.44 25.94-32 41-17z\"]],\n    \"rocket\": [512, 512, [], \"f135\", [\"M51.94117,154.48438,2.531,253.29688A28.125,28.125,0,0,0-.00023,264a24.00619,24.00619,0,0,0,24,24H117.4607c23.44141-47.41211,61.01172-123.373,77.89063-157.32812.51953-.91407,1-1.76758,1.52344-2.67188H94.82008C78.47633,128.01562,59.28883,139.875,51.94117,154.48438Zm172.0586,240.1621V488.209A24.12394,24.12394,0,0,0,247.9607,512a28.02965,28.02965,0,0,0,10.625-2.53125l98.72657-49.39063c14.625-7.3125,26.5-26.5,26.5-42.85937V315.70312c.0664-.041.125-.08789.1875-.1289v-.52734c-.90625.51953-1.7461,1.002-2.66407,1.52539C347.37477,333.58008,271.2732,371.252,223.99977,394.64648Z\", \"M505.15992,19.51562A16.73971,16.73971,0,0,0,492.62477,6.94531C460.22633,0,434.37477,0,409.48414,0,320.3357,0,252.80836,40.61523,196.97633,127.81836c-.5586.97852-1.07031,1.877-1.625,2.85352-19.59766,39.42578-67.20313,135.70312-88.04688,177.877a31.91421,31.91421,0,0,0,6.09766,36.76172L167.05445,398.709a31.88923,31.88923,0,0,0,36.64844,5.98047l14.17578-7.01367c46.57422-23.04883,128.06641-63.3789,163.457-81.10351.96094-.54883,1.832-1.04883,2.78907-1.59766,87.23437-56.06055,127.85937-123.51172,127.85937-212.27734C512.06227,77.60742,512.12867,52.08789,505.15992,19.51562ZM367.99977,192a48,48,0,1,1,48-48.00195A48.02156,48.02156,0,0,1,367.99977,192Z\"]],\n    \"search\": [512, 512, [], \"f002\", [\"M208 80a128 128 0 1 1-90.51 37.49A127.15 127.15 0 0 1 208 80m0-80C93.12 0 0 93.12 0 208s93.12 208 208 208 208-93.12 208-208S322.88 0 208 0z\", \"M504.9 476.7L476.6 505a23.9 23.9 0 0 1-33.9 0L343 405.3a24 24 0 0 1-7-17V372l36-36h16.3a24 24 0 0 1 17 7l99.7 99.7a24.11 24.11 0 0 1-.1 34z\"]],\n    \"server\": [512, 512, [], \"f233\", [\"M432 120a24 24 0 1 0-24-24 24 24 0 0 0 24 24zm0 272a24 24 0 1 0 24 24 24 24 0 0 0-24-24zm48-200H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\", \"M456 256a24 24 0 1 0-24 24 24 24 0 0 0 24-24zm24-224H32A32 32 0 0 0 0 64v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm48 232H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\"]],\n    \"sign-out\": [512, 512, [], \"f08b\", [\"M180 448H96a96 96 0 0 1-96-96V160a96 96 0 0 1 96-96h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12H96a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12z\", \"M353 88.3l151.9 150.6a24 24 0 0 1 0 34.1l-152 150.8a24.08 24.08 0 0 1-33.9-.1l-21.9-21.9a24.07 24.07 0 0 1 .8-34.7l77.6-71.1H184a23.94 23.94 0 0 1-24-24v-32a23.94 23.94 0 0 1 24-24h191.5l-77.6-71.1a24 24 0 0 1-.7-34.6l21.9-21.9a24 24 0 0 1 33.9-.1z\"]],\n    \"siren-on\": [640, 512, [], \"e02e\", [\"M224.21,134.94a8,8,0,0,1,9-6.87l15.86,2.13a8,8,0,0,1,6.87,9L231.82,320H496L471,120.06A64,64,0,0,0,407.5,64h-175A64,64,0,0,0,169,120.06L144,320h55.54Z\", \"M528,352H112a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16H528a16,16,0,0,0,16-16V368A16,16,0,0,0,528,352ZM112,192a24,24,0,0,0-24-24H24a24,24,0,0,0,0,48H88A24,24,0,0,0,112,192Zm504-24H552a24,24,0,0,0,0,48h64a24,24,0,0,0,0-48ZM90.69,76a24,24,0,1,0,26.62-39.92l-48-32A24,24,0,1,0,42.69,44ZM536,80a23.87,23.87,0,0,0,13.29-4l48-32A24,24,0,1,0,570.69,4.06l-48,32A24,24,0,0,0,536,80Z\"]],\n    \"smile\": [496, 512, [], \"f118\", [\"M248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256,385,8,248,8Zm80,168a32,32,0,1,1-32,32A32,32,0,0,1,328,176Zm-160,0a32,32,0,1,1-32,32A32,32,0,0,1,168,176ZM362.8,346.2a149.38,149.38,0,0,1-229.6,0c-13.6-16.3,11-36.7,24.6-20.5a117.5,117.5,0,0,0,180.4,0C351.6,309.5,376.3,329.9,362.8,346.2Z\", \"M328,176a32,32,0,1,0,32,32A32,32,0,0,0,328,176Zm-160,0a32,32,0,1,0,32,32A32,32,0,0,0,168,176Z\"]],\n    \"snowman\": [512, 512, [], \"f7d0\", [\"M363.76 268.8a108.77 108.77 0 0 0 4.2-28.7v-.1a112.68 112.68 0 0 0-.73-12.8c-.11-1-.24-2-.38-3-.29-2-.62-4-1-6-.2-1-.4-1.95-.62-2.92-.22-1-.45-1.93-.7-2.9-.24-1-.5-1.91-.77-2.85-.27-.95-.55-1.89-.84-2.83-.3-.94-.6-1.87-.92-2.8-.32-.93-.65-1.86-1-2.77-.34-.92-.69-1.83-1.06-2.74-.36-.9-.74-1.8-1.13-2.7-.39-.89-.79-1.78-1.19-2.66-.41-.88-.83-1.76-1.26-2.63q-1.31-2.62-2.73-5.16c-.48-.85-1-1.68-1.46-2.51a112.44 112.44 0 0 0-21.62-26.19 96 96 0 1 0-149.16 0 112.49 112.49 0 0 0-21.68 26.28q-.74 1.23-1.44 2.49c-.48.84-.94 1.69-1.39 2.54-.45.85-.89 1.7-1.32 2.57-.43.87-.85 1.74-1.25 2.62-.41.88-.8 1.76-1.19 2.66-.39.89-.76 1.79-1.12 2.69-.36.91-.71 1.82-1.05 2.74-.34.92-.67 1.84-1 2.76a111.63 111.63 0 0 0-5.22 23.28A113 113 0 0 0 144 240h.06v.1a110.27 110.27 0 0 0 4.2 28.9A151.18 151.18 0 0 0 104 376.1c0 54 28.4 100.9 70.8 127.8 9.3 5.9 20.3 8.2 31.3 8.2h99.2a65.1 65.1 0 0 0 37.2-11.7c46.5-32.3 74.4-89.4 62.9-152.6-5.54-30.2-20.54-57.6-41.64-79zM224 96.1a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm32 272a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm0-64a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm1.7-64.1a15.19 15.19 0 0 1-3.48 0 16 16 0 1 1 3.48 0zm-1.7-87.9s-16-23.2-16-32a16 16 0 1 1 32 0c0 8.8-16 32-16 32zm32-56a16 16 0 1 1 16-16 16 16 0 0 1-16 16z\", \"M510.86 152.4L505 137.9a16.15 16.15 0 0 0-20.8-8.7L456 140.7v-29a15.84 15.84 0 0 0-16-15.6h-16a15.84 15.84 0 0 0-16 15.6v46.9c0 .5.3 1 .3 1.5l-56.1 22.54a111.21 111.21 0 0 1 15.07 44.56L502 172.7a15.57 15.57 0 0 0 8.86-20.3zm-407.1 6.2v-46.9c.2-8.6-7-15.6-15.8-15.6H72a15.84 15.84 0 0 0-16 15.6v29l-28.1-11.5a16.15 16.15 0 0 0-20.8 8.7l-5.9 14.5a15.48 15.48 0 0 0 8.9 20.3l134.67 54.49a111.3 111.3 0 0 1 15-44.46l-56.31-22.63a8 8 0 0 0 .3-1.5zM256 336.1a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16z\"]],\n    \"sun\": [512, 512, [], \"f185\", [\"M502.42 240.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.41-94.8a17.31 17.31 0 0 0-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4a17.31 17.31 0 0 0 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.41-33.5 47.3 94.7a17.31 17.31 0 0 0 31 0l47.31-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3a17.33 17.33 0 0 0 .2-31.1zm-155.9 106c-49.91 49.9-131.11 49.9-181 0a128.13 128.13 0 0 1 0-181c49.9-49.9 131.1-49.9 181 0a128.13 128.13 0 0 1 0 181z\", \"M352 256a96 96 0 1 1-96-96 96.15 96.15 0 0 1 96 96z\"]],\n    \"tasks\": [512, 512, [], \"f0ae\", [\"M496 384H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M139.61 35.5a12 12 0 0 0-17 0L58.93 98.81l-22.7-22.12a12 12 0 0 0-17 0L3.53 92.41a12 12 0 0 0 0 17l47.59 47.4a12.78 12.78 0 0 0 17.61 0l15.59-15.62L156.52 69a12.09 12.09 0 0 0 .09-17zm0 159.19a12 12 0 0 0-17 0l-63.68 63.72-22.7-22.1a12 12 0 0 0-17 0L3.53 252a12 12 0 0 0 0 17L51 316.5a12.77 12.77 0 0 0 17.6 0l15.7-15.69 72.2-72.22a12 12 0 0 0 .09-16.9zM64 368c-26.49 0-48.59 21.5-48.59 48S37.53 464 64 464a48 48 0 0 0 0-96z\"]],\n    \"university\": [512, 512, [], \"f19c\", [\"M160,192V384h64V192h64V384h64V192h64V384h36a12,12,0,0,1,12,12v20H48V396a12,12,0,0,1,12-12H96V192Z\", \"M491.06,120.61l-232-88a8,8,0,0,0-6.12,0l-232,88A8,8,0,0,0,16,128v16a8,8,0,0,0,8,8H48v12a12,12,0,0,0,12,12H452a12,12,0,0,0,12-12V152h24a8,8,0,0,0,8-8V128A8,8,0,0,0,491.06,120.61ZM472,432H40a24,24,0,0,0-24,24v16a8,8,0,0,0,8,8H488a8,8,0,0,0,8-8V456A24,24,0,0,0,472,432Z\"]],\n    \"user\": [448, 512, [], \"f007\", [\"M352 128A128 128 0 1 1 224 0a128 128 0 0 1 128 128z\", \"M313.6 288h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48v-41.6A134.43 134.43 0 0 0 313.6 288z\"]],\n    \"user-hard-hat\": [448, 512, [], \"f82c\", [\"M97.61 208h252.78c-7.95 63.06-61.17 112-126.39 112S105.56 271.06 97.61 208z\", \"M313.6 352h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.4 134.4 0 0 0 0 486.4 25.6 25.6 0 0 0 25.6 512h396.8a25.6 25.6 0 0 0 25.6-25.6A134.4 134.4 0 0 0 313.6 352zM88 176h272a8 8 0 0 0 8-8v-32a8 8 0 0 0-8-8h-8a112 112 0 0 0-68.4-103.2L256 80V16a16 16 0 0 0-16-16h-32a16 16 0 0 0-16 16v64l-27.6-55.2A112 112 0 0 0 96 128h-8a8 8 0 0 0-8 8v32a8 8 0 0 0 8 8z\"]],\n    \"user-shield\": [640, 512, [], \"f505\", [\"M622.3 271.1l-115.2-45a31 31 0 0 0-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9a31 31 0 0 0 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8z\", \"M224 256A128 128 0 1 0 96 128a128 128 0 0 0 128 128zm96 40c0-2.5.8-4.8 1.1-7.2-2.5-.1-4.9-.8-7.5-.8h-16.7a174.08 174.08 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a49.22 49.22 0 0 0 19.2-4c-54-42.9-99.2-116.7-99.2-212z\"]],\n    \"users\": [640, 512, [], \"f0c0\", [\"M96 224a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64zm480 32h-64a63.81 63.81 0 0 0-45.1 18.6A146.27 146.27 0 0 1 542 384h66a32 32 0 0 0 32-32v-32a64.06 64.06 0 0 0-64-64zm-512 0a64.06 64.06 0 0 0-64 64v32a32 32 0 0 0 32 32h65.9a146.64 146.64 0 0 1 75.2-109.4A63.81 63.81 0 0 0 128 256zm480-32a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64z\", \"M396.8 288h-8.3a157.53 157.53 0 0 1-68.5 16c-24.6 0-47.6-6-68.5-16h-8.3A115.23 115.23 0 0 0 128 403.2V432a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48v-28.8A115.23 115.23 0 0 0 396.8 288zM320 256a112 112 0 1 0-112-112 111.94 111.94 0 0 0 112 112z\"]]\n  };\n\n  bunker(function () {\n    defineIcons('fad', icons);\n  });\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/js/fontawesome.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _typeof(obj) {\n    \"@babel/helpers - typeof\";\n\n    if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n      _typeof = function (obj) {\n        return typeof obj;\n      };\n    } else {\n      _typeof = function (obj) {\n        return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n      };\n    }\n\n    return _typeof(obj);\n  }\n\n  function _classCallCheck(instance, Constructor) {\n    if (!(instance instanceof Constructor)) {\n      throw new TypeError(\"Cannot call a class as a function\");\n    }\n  }\n\n  function _defineProperties(target, props) {\n    for (var i = 0; i < props.length; i++) {\n      var descriptor = props[i];\n      descriptor.enumerable = descriptor.enumerable || false;\n      descriptor.configurable = true;\n      if (\"value\" in descriptor) descriptor.writable = true;\n      Object.defineProperty(target, descriptor.key, descriptor);\n    }\n  }\n\n  function _createClass(Constructor, protoProps, staticProps) {\n    if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n    if (staticProps) _defineProperties(Constructor, staticProps);\n    return Constructor;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  function _slicedToArray(arr, i) {\n    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n  }\n\n  function _toConsumableArray(arr) {\n    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n  }\n\n  function _arrayWithoutHoles(arr) {\n    if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n  }\n\n  function _arrayWithHoles(arr) {\n    if (Array.isArray(arr)) return arr;\n  }\n\n  function _iterableToArray(iter) {\n    if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n  }\n\n  function _iterableToArrayLimit(arr, i) {\n    var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n    if (_i == null) return;\n    var _arr = [];\n    var _n = true;\n    var _d = false;\n\n    var _s, _e;\n\n    try {\n      for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n        _arr.push(_s.value);\n\n        if (i && _arr.length === i) break;\n      }\n    } catch (err) {\n      _d = true;\n      _e = err;\n    } finally {\n      try {\n        if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n      } finally {\n        if (_d) throw _e;\n      }\n    }\n\n    return _arr;\n  }\n\n  function _unsupportedIterableToArray(o, minLen) {\n    if (!o) return;\n    if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n    var n = Object.prototype.toString.call(o).slice(8, -1);\n    if (n === \"Object\" && o.constructor) n = o.constructor.name;\n    if (n === \"Map\" || n === \"Set\") return Array.from(o);\n    if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n  }\n\n  function _arrayLikeToArray(arr, len) {\n    if (len == null || len > arr.length) len = arr.length;\n\n    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n\n    return arr2;\n  }\n\n  function _nonIterableSpread() {\n    throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n\n  function _nonIterableRest() {\n    throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n\n  var noop = function noop() {};\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n  var _MUTATION_OBSERVER = null;\n  var _PERFORMANCE = {\n    mark: noop,\n    measure: noop\n  };\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n    if (typeof MutationObserver !== 'undefined') _MUTATION_OBSERVER = MutationObserver;\n    if (typeof performance !== 'undefined') _PERFORMANCE = performance;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var MUTATION_OBSERVER = _MUTATION_OBSERVER;\n  var PERFORMANCE = _PERFORMANCE;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var UNITS_IN_GRID = 16;\n  var DEFAULT_FAMILY_PREFIX = 'fa';\n  var DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa';\n  var DATA_FA_I2SVG = 'data-fa-i2svg';\n  var DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element';\n  var DATA_FA_PSEUDO_ELEMENT_PENDING = 'data-fa-pseudo-element-pending';\n  var DATA_PREFIX = 'data-prefix';\n  var DATA_ICON = 'data-icon';\n  var HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg';\n  var MUTATION_APPROACH_ASYNC = 'async';\n  var TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS = ['HTML', 'HEAD', 'STYLE', 'SCRIPT'];\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n  var PREFIX_TO_STYLE = {\n    'fas': 'solid',\n    'far': 'regular',\n    'fal': 'light',\n    'fad': 'duotone',\n    'fab': 'brands',\n    'fak': 'kit',\n    'fa': 'solid'\n  };\n  var STYLE_TO_PREFIX = {\n    'solid': 'fas',\n    'regular': 'far',\n    'light': 'fal',\n    'duotone': 'fad',\n    'brands': 'fab',\n    'kit': 'fak'\n  };\n  var LAYERS_TEXT_CLASSNAME = 'fa-layers-text';\n  var FONT_FAMILY_PATTERN = /Font Awesome ([5 ]*)(Solid|Regular|Light|Duotone|Brands|Free|Pro|Kit).*/i; // TODO: do we need to handle font-weight for kit SVG pseudo-elements?\n\n  var FONT_WEIGHT_TO_PREFIX = {\n    '900': 'fas',\n    '400': 'far',\n    'normal': 'far',\n    '300': 'fal'\n  };\n  var oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n  var oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);\n  var ATTRIBUTES_WATCHED_FOR_MUTATION = ['class', 'data-prefix', 'data-icon', 'data-fa-transform', 'data-fa-mask'];\n  var DUOTONE_CLASSES = {\n    GROUP: 'group',\n    SWAP_OPACITY: 'swap-opacity',\n    PRIMARY: 'primary',\n    SECONDARY: 'secondary'\n  };\n  var RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'flip-both', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter', DUOTONE_CLASSES.GROUP, DUOTONE_CLASSES.SWAP_OPACITY, DUOTONE_CLASSES.PRIMARY, DUOTONE_CLASSES.SECONDARY].concat(oneToTen.map(function (n) {\n    return \"\".concat(n, \"x\");\n  })).concat(oneToTwenty.map(function (n) {\n    return \"w-\".concat(n);\n  }));\n\n  var initial = WINDOW.FontAwesomeConfig || {};\n\n  function getAttrConfig(attr) {\n    var element = DOCUMENT.querySelector('script[' + attr + ']');\n\n    if (element) {\n      return element.getAttribute(attr);\n    }\n  }\n\n  function coerce(val) {\n    // Getting an empty string will occur if the attribute is set on the HTML tag but without a value\n    // We'll assume that this is an indication that it should be toggled to true\n    // For example <script data-search-pseudo-elements src=\"...\"></script>\n    if (val === '') return true;\n    if (val === 'false') return false;\n    if (val === 'true') return true;\n    return val;\n  }\n\n  if (DOCUMENT && typeof DOCUMENT.querySelector === 'function') {\n    var attrs = [['data-family-prefix', 'familyPrefix'], ['data-replacement-class', 'replacementClass'], ['data-auto-replace-svg', 'autoReplaceSvg'], ['data-auto-add-css', 'autoAddCss'], ['data-auto-a11y', 'autoA11y'], ['data-search-pseudo-elements', 'searchPseudoElements'], ['data-observe-mutations', 'observeMutations'], ['data-mutate-approach', 'mutateApproach'], ['data-keep-original-source', 'keepOriginalSource'], ['data-measure-performance', 'measurePerformance'], ['data-show-missing-icons', 'showMissingIcons']];\n    attrs.forEach(function (_ref) {\n      var _ref2 = _slicedToArray(_ref, 2),\n          attr = _ref2[0],\n          key = _ref2[1];\n\n      var val = coerce(getAttrConfig(attr));\n\n      if (val !== undefined && val !== null) {\n        initial[key] = val;\n      }\n    });\n  }\n\n  var _default = {\n    familyPrefix: DEFAULT_FAMILY_PREFIX,\n    replacementClass: DEFAULT_REPLACEMENT_CLASS,\n    autoReplaceSvg: true,\n    autoAddCss: true,\n    autoA11y: true,\n    searchPseudoElements: false,\n    observeMutations: true,\n    mutateApproach: 'async',\n    keepOriginalSource: true,\n    measurePerformance: false,\n    showMissingIcons: true\n  };\n\n  var _config = _objectSpread2(_objectSpread2({}, _default), initial);\n\n  if (!_config.autoReplaceSvg) _config.observeMutations = false;\n\n  var config = _objectSpread2({}, _config);\n\n  WINDOW.FontAwesomeConfig = config;\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  var functions = [];\n\n  var listener = function listener() {\n    DOCUMENT.removeEventListener('DOMContentLoaded', listener);\n    loaded = 1;\n    functions.map(function (fn) {\n      return fn();\n    });\n  };\n\n  var loaded = false;\n\n  if (IS_DOM) {\n    loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);\n    if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);\n  }\n\n  function domready (fn) {\n    if (!IS_DOM) return;\n    loaded ? setTimeout(fn, 0) : functions.push(fn);\n  }\n\n  var PENDING = 'pending';\n  var SETTLED = 'settled';\n  var FULFILLED = 'fulfilled';\n  var REJECTED = 'rejected';\n\n  var NOOP = function NOOP() {};\n\n  var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function';\n  var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate;\n  var asyncQueue = [];\n  var asyncTimer;\n\n  function asyncFlush() {\n    // run promise callbacks\n    for (var i = 0; i < asyncQueue.length; i++) {\n      asyncQueue[i][0](asyncQueue[i][1]);\n    } // reset async asyncQueue\n\n\n    asyncQueue = [];\n    asyncTimer = false;\n  }\n\n  function asyncCall(callback, arg) {\n    asyncQueue.push([callback, arg]);\n\n    if (!asyncTimer) {\n      asyncTimer = true;\n      asyncSetTimer(asyncFlush, 0);\n    }\n  }\n\n  function invokeResolver(resolver, promise) {\n    function resolvePromise(value) {\n      resolve(promise, value);\n    }\n\n    function rejectPromise(reason) {\n      reject(promise, reason);\n    }\n\n    try {\n      resolver(resolvePromise, rejectPromise);\n    } catch (e) {\n      rejectPromise(e);\n    }\n  }\n\n  function invokeCallback(subscriber) {\n    var owner = subscriber.owner;\n    var settled = owner._state;\n    var value = owner._data;\n    var callback = subscriber[settled];\n    var promise = subscriber.then;\n\n    if (typeof callback === 'function') {\n      settled = FULFILLED;\n\n      try {\n        value = callback(value);\n      } catch (e) {\n        reject(promise, e);\n      }\n    }\n\n    if (!handleThenable(promise, value)) {\n      if (settled === FULFILLED) {\n        resolve(promise, value);\n      }\n\n      if (settled === REJECTED) {\n        reject(promise, value);\n      }\n    }\n  }\n\n  function handleThenable(promise, value) {\n    var resolved;\n\n    try {\n      if (promise === value) {\n        throw new TypeError('A promises callback cannot return that same promise.');\n      }\n\n      if (value && (typeof value === 'function' || _typeof(value) === 'object')) {\n        // then should be retrieved only once\n        var then = value.then;\n\n        if (typeof then === 'function') {\n          then.call(value, function (val) {\n            if (!resolved) {\n              resolved = true;\n\n              if (value === val) {\n                fulfill(promise, val);\n              } else {\n                resolve(promise, val);\n              }\n            }\n          }, function (reason) {\n            if (!resolved) {\n              resolved = true;\n              reject(promise, reason);\n            }\n          });\n          return true;\n        }\n      }\n    } catch (e) {\n      if (!resolved) {\n        reject(promise, e);\n      }\n\n      return true;\n    }\n\n    return false;\n  }\n\n  function resolve(promise, value) {\n    if (promise === value || !handleThenable(promise, value)) {\n      fulfill(promise, value);\n    }\n  }\n\n  function fulfill(promise, value) {\n    if (promise._state === PENDING) {\n      promise._state = SETTLED;\n      promise._data = value;\n      asyncCall(publishFulfillment, promise);\n    }\n  }\n\n  function reject(promise, reason) {\n    if (promise._state === PENDING) {\n      promise._state = SETTLED;\n      promise._data = reason;\n      asyncCall(publishRejection, promise);\n    }\n  }\n\n  function publish(promise) {\n    promise._then = promise._then.forEach(invokeCallback);\n  }\n\n  function publishFulfillment(promise) {\n    promise._state = FULFILLED;\n    publish(promise);\n  }\n\n  function publishRejection(promise) {\n    promise._state = REJECTED;\n    publish(promise);\n\n    if (!promise._handled && isNode) {\n      global.process.emit('unhandledRejection', promise._data, promise);\n    }\n  }\n\n  function notifyRejectionHandled(promise) {\n    global.process.emit('rejectionHandled', promise);\n  }\n  /**\n   * @class\n   */\n\n\n  function P(resolver) {\n    if (typeof resolver !== 'function') {\n      throw new TypeError('Promise resolver ' + resolver + ' is not a function');\n    }\n\n    if (this instanceof P === false) {\n      throw new TypeError('Failed to construct \\'Promise\\': Please use the \\'new\\' operator, this object constructor cannot be called as a function.');\n    }\n\n    this._then = [];\n    invokeResolver(resolver, this);\n  }\n\n  P.prototype = {\n    constructor: P,\n    _state: PENDING,\n    _then: null,\n    _data: undefined,\n    _handled: false,\n    then: function then(onFulfillment, onRejection) {\n      var subscriber = {\n        owner: this,\n        then: new this.constructor(NOOP),\n        fulfilled: onFulfillment,\n        rejected: onRejection\n      };\n\n      if ((onRejection || onFulfillment) && !this._handled) {\n        this._handled = true;\n\n        if (this._state === REJECTED && isNode) {\n          asyncCall(notifyRejectionHandled, this);\n        }\n      }\n\n      if (this._state === FULFILLED || this._state === REJECTED) {\n        // already resolved, call callback async\n        asyncCall(invokeCallback, subscriber);\n      } else {\n        // subscribe\n        this._then.push(subscriber);\n      }\n\n      return subscriber.then;\n    },\n    catch: function _catch(onRejection) {\n      return this.then(null, onRejection);\n    }\n  };\n\n  P.all = function (promises) {\n    if (!Array.isArray(promises)) {\n      throw new TypeError('You must pass an array to Promise.all().');\n    }\n\n    return new P(function (resolve, reject) {\n      var results = [];\n      var remaining = 0;\n\n      function resolver(index) {\n        remaining++;\n        return function (value) {\n          results[index] = value;\n\n          if (! --remaining) {\n            resolve(results);\n          }\n        };\n      }\n\n      for (var i = 0, promise; i < promises.length; i++) {\n        promise = promises[i];\n\n        if (promise && typeof promise.then === 'function') {\n          promise.then(resolver(i), reject);\n        } else {\n          results[i] = promise;\n        }\n      }\n\n      if (!remaining) {\n        resolve(results);\n      }\n    });\n  };\n\n  P.race = function (promises) {\n    if (!Array.isArray(promises)) {\n      throw new TypeError('You must pass an array to Promise.race().');\n    }\n\n    return new P(function (resolve, reject) {\n      for (var i = 0, promise; i < promises.length; i++) {\n        promise = promises[i];\n\n        if (promise && typeof promise.then === 'function') {\n          promise.then(resolve, reject);\n        } else {\n          resolve(promise);\n        }\n      }\n    });\n  };\n\n  P.resolve = function (value) {\n    if (value && _typeof(value) === 'object' && value.constructor === P) {\n      return value;\n    }\n\n    return new P(function (resolve) {\n      resolve(value);\n    });\n  };\n\n  P.reject = function (reason) {\n    return new P(function (resolve, reject) {\n      reject(reason);\n    });\n  };\n\n  var picked = typeof Promise === 'function' ? Promise : P;\n\n  var d = UNITS_IN_GRID;\n  var meaninglessTransform = {\n    size: 16,\n    x: 0,\n    y: 0,\n    rotate: 0,\n    flipX: false,\n    flipY: false\n  };\n\n  function isReserved(name) {\n    return ~RESERVED_CLASSES.indexOf(name);\n  }\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n  function insertCss(css) {\n    if (!css || !IS_DOM) {\n      return;\n    }\n\n    var style = DOCUMENT.createElement('style');\n    style.setAttribute('type', 'text/css');\n    style.innerHTML = css;\n    var headChildren = DOCUMENT.head.childNodes;\n    var beforeChild = null;\n\n    for (var i = headChildren.length - 1; i > -1; i--) {\n      var child = headChildren[i];\n      var tagName = (child.tagName || '').toUpperCase();\n\n      if (['STYLE', 'LINK'].indexOf(tagName) > -1) {\n        beforeChild = child;\n      }\n    }\n\n    DOCUMENT.head.insertBefore(style, beforeChild);\n    return css;\n  }\n  var idPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n  function nextUniqueId() {\n    var size = 12;\n    var id = '';\n\n    while (size-- > 0) {\n      id += idPool[Math.random() * 62 | 0];\n    }\n\n    return id;\n  }\n  function toArray(obj) {\n    var array = [];\n\n    for (var i = (obj || []).length >>> 0; i--;) {\n      array[i] = obj[i];\n    }\n\n    return array;\n  }\n  function classArray(node) {\n    if (node.classList) {\n      return toArray(node.classList);\n    } else {\n      return (node.getAttribute('class') || '').split(' ').filter(function (i) {\n        return i;\n      });\n    }\n  }\n  function getIconName(familyPrefix, cls) {\n    var parts = cls.split('-');\n    var prefix = parts[0];\n    var iconName = parts.slice(1).join('-');\n\n    if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) {\n      return iconName;\n    } else {\n      return null;\n    }\n  }\n  function htmlEscape(str) {\n    return \"\".concat(str).replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n  }\n  function joinAttributes(attributes) {\n    return Object.keys(attributes || {}).reduce(function (acc, attributeName) {\n      return acc + \"\".concat(attributeName, \"=\\\"\").concat(htmlEscape(attributes[attributeName]), \"\\\" \");\n    }, '').trim();\n  }\n  function joinStyles(styles) {\n    return Object.keys(styles || {}).reduce(function (acc, styleName) {\n      return acc + \"\".concat(styleName, \": \").concat(styles[styleName], \";\");\n    }, '');\n  }\n  function transformIsMeaningful(transform) {\n    return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY;\n  }\n  function transformForSvg(_ref) {\n    var transform = _ref.transform,\n        containerWidth = _ref.containerWidth,\n        iconWidth = _ref.iconWidth;\n    var outer = {\n      transform: \"translate(\".concat(containerWidth / 2, \" 256)\")\n    };\n    var innerTranslate = \"translate(\".concat(transform.x * 32, \", \").concat(transform.y * 32, \") \");\n    var innerScale = \"scale(\".concat(transform.size / 16 * (transform.flipX ? -1 : 1), \", \").concat(transform.size / 16 * (transform.flipY ? -1 : 1), \") \");\n    var innerRotate = \"rotate(\".concat(transform.rotate, \" 0 0)\");\n    var inner = {\n      transform: \"\".concat(innerTranslate, \" \").concat(innerScale, \" \").concat(innerRotate)\n    };\n    var path = {\n      transform: \"translate(\".concat(iconWidth / 2 * -1, \" -256)\")\n    };\n    return {\n      outer: outer,\n      inner: inner,\n      path: path\n    };\n  }\n  function transformForCss(_ref2) {\n    var transform = _ref2.transform,\n        _ref2$width = _ref2.width,\n        width = _ref2$width === void 0 ? UNITS_IN_GRID : _ref2$width,\n        _ref2$height = _ref2.height,\n        height = _ref2$height === void 0 ? UNITS_IN_GRID : _ref2$height,\n        _ref2$startCentered = _ref2.startCentered,\n        startCentered = _ref2$startCentered === void 0 ? false : _ref2$startCentered;\n    var val = '';\n\n    if (startCentered && IS_IE) {\n      val += \"translate(\".concat(transform.x / d - width / 2, \"em, \").concat(transform.y / d - height / 2, \"em) \");\n    } else if (startCentered) {\n      val += \"translate(calc(-50% + \".concat(transform.x / d, \"em), calc(-50% + \").concat(transform.y / d, \"em)) \");\n    } else {\n      val += \"translate(\".concat(transform.x / d, \"em, \").concat(transform.y / d, \"em) \");\n    }\n\n    val += \"scale(\".concat(transform.size / d * (transform.flipX ? -1 : 1), \", \").concat(transform.size / d * (transform.flipY ? -1 : 1), \") \");\n    val += \"rotate(\".concat(transform.rotate, \"deg) \");\n    return val;\n  }\n\n  var ALL_SPACE = {\n    x: 0,\n    y: 0,\n    width: '100%',\n    height: '100%'\n  };\n\n  function fillBlack(abstract) {\n    var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n    if (abstract.attributes && (abstract.attributes.fill || force)) {\n      abstract.attributes.fill = 'black';\n    }\n\n    return abstract;\n  }\n\n  function deGroup(abstract) {\n    if (abstract.tag === 'g') {\n      return abstract.children;\n    } else {\n      return [abstract];\n    }\n  }\n\n  function makeIconMasking (_ref) {\n    var children = _ref.children,\n        attributes = _ref.attributes,\n        main = _ref.main,\n        mask = _ref.mask,\n        explicitMaskId = _ref.maskId,\n        transform = _ref.transform;\n    var mainWidth = main.width,\n        mainPath = main.icon;\n    var maskWidth = mask.width,\n        maskPath = mask.icon;\n    var trans = transformForSvg({\n      transform: transform,\n      containerWidth: maskWidth,\n      iconWidth: mainWidth\n    });\n    var maskRect = {\n      tag: 'rect',\n      attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n        fill: 'white'\n      })\n    };\n    var maskInnerGroupChildrenMixin = mainPath.children ? {\n      children: mainPath.children.map(fillBlack)\n    } : {};\n    var maskInnerGroup = {\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.inner),\n      children: [fillBlack(_objectSpread2({\n        tag: mainPath.tag,\n        attributes: _objectSpread2(_objectSpread2({}, mainPath.attributes), trans.path)\n      }, maskInnerGroupChildrenMixin))]\n    };\n    var maskOuterGroup = {\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.outer),\n      children: [maskInnerGroup]\n    };\n    var maskId = \"mask-\".concat(explicitMaskId || nextUniqueId());\n    var clipId = \"clip-\".concat(explicitMaskId || nextUniqueId());\n    var maskTag = {\n      tag: 'mask',\n      attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n        id: maskId,\n        maskUnits: 'userSpaceOnUse',\n        maskContentUnits: 'userSpaceOnUse'\n      }),\n      children: [maskRect, maskOuterGroup]\n    };\n    var defs = {\n      tag: 'defs',\n      children: [{\n        tag: 'clipPath',\n        attributes: {\n          id: clipId\n        },\n        children: deGroup(maskPath)\n      }, maskTag]\n    };\n    children.push(defs, {\n      tag: 'rect',\n      attributes: _objectSpread2({\n        fill: 'currentColor',\n        'clip-path': \"url(#\".concat(clipId, \")\"),\n        mask: \"url(#\".concat(maskId, \")\")\n      }, ALL_SPACE)\n    });\n    return {\n      children: children,\n      attributes: attributes\n    };\n  }\n\n  function makeIconStandard (_ref) {\n    var children = _ref.children,\n        attributes = _ref.attributes,\n        main = _ref.main,\n        transform = _ref.transform,\n        styles = _ref.styles;\n    var styleString = joinStyles(styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    if (transformIsMeaningful(transform)) {\n      var trans = transformForSvg({\n        transform: transform,\n        containerWidth: main.width,\n        iconWidth: main.width\n      });\n      children.push({\n        tag: 'g',\n        attributes: _objectSpread2({}, trans.outer),\n        children: [{\n          tag: 'g',\n          attributes: _objectSpread2({}, trans.inner),\n          children: [{\n            tag: main.icon.tag,\n            children: main.icon.children,\n            attributes: _objectSpread2(_objectSpread2({}, main.icon.attributes), trans.path)\n          }]\n        }]\n      });\n    } else {\n      children.push(main.icon);\n    }\n\n    return {\n      children: children,\n      attributes: attributes\n    };\n  }\n\n  function asIcon (_ref) {\n    var children = _ref.children,\n        main = _ref.main,\n        mask = _ref.mask,\n        attributes = _ref.attributes,\n        styles = _ref.styles,\n        transform = _ref.transform;\n\n    if (transformIsMeaningful(transform) && main.found && !mask.found) {\n      var width = main.width,\n          height = main.height;\n      var offset = {\n        x: width / height / 2,\n        y: 0.5\n      };\n      attributes['style'] = joinStyles(_objectSpread2(_objectSpread2({}, styles), {}, {\n        'transform-origin': \"\".concat(offset.x + transform.x / 16, \"em \").concat(offset.y + transform.y / 16, \"em\")\n      }));\n    }\n\n    return [{\n      tag: 'svg',\n      attributes: attributes,\n      children: children\n    }];\n  }\n\n  function asSymbol (_ref) {\n    var prefix = _ref.prefix,\n        iconName = _ref.iconName,\n        children = _ref.children,\n        attributes = _ref.attributes,\n        symbol = _ref.symbol;\n    var id = symbol === true ? \"\".concat(prefix, \"-\").concat(config.familyPrefix, \"-\").concat(iconName) : symbol;\n    return [{\n      tag: 'svg',\n      attributes: {\n        style: 'display: none;'\n      },\n      children: [{\n        tag: 'symbol',\n        attributes: _objectSpread2(_objectSpread2({}, attributes), {}, {\n          id: id\n        }),\n        children: children\n      }]\n    }];\n  }\n\n  function makeInlineSvgAbstract(params) {\n    var _params$icons = params.icons,\n        main = _params$icons.main,\n        mask = _params$icons.mask,\n        prefix = params.prefix,\n        iconName = params.iconName,\n        transform = params.transform,\n        symbol = params.symbol,\n        title = params.title,\n        maskId = params.maskId,\n        titleId = params.titleId,\n        extra = params.extra,\n        _params$watchable = params.watchable,\n        watchable = _params$watchable === void 0 ? false : _params$watchable;\n\n    var _ref = mask.found ? mask : main,\n        width = _ref.width,\n        height = _ref.height;\n\n    var isUploadedIcon = prefix === 'fak';\n    var widthClass = isUploadedIcon ? '' : \"fa-w-\".concat(Math.ceil(width / height * 16));\n    var attrClass = [config.replacementClass, iconName ? \"\".concat(config.familyPrefix, \"-\").concat(iconName) : '', widthClass].filter(function (c) {\n      return extra.classes.indexOf(c) === -1;\n    }).filter(function (c) {\n      return c !== '' || !!c;\n    }).concat(extra.classes).join(' ');\n    var content = {\n      children: [],\n      attributes: _objectSpread2(_objectSpread2({}, extra.attributes), {}, {\n        'data-prefix': prefix,\n        'data-icon': iconName,\n        'class': attrClass,\n        'role': extra.attributes.role || 'img',\n        'xmlns': 'http://www.w3.org/2000/svg',\n        'viewBox': \"0 0 \".concat(width, \" \").concat(height)\n      })\n    };\n    var uploadedIconWidthStyle = isUploadedIcon && !~extra.classes.indexOf('fa-fw') ? {\n      width: \"\".concat(width / height * 16 * 0.0625, \"em\")\n    } : {};\n\n    if (watchable) {\n      content.attributes[DATA_FA_I2SVG] = '';\n    }\n\n    if (title) content.children.push({\n      tag: 'title',\n      attributes: {\n        id: content.attributes['aria-labelledby'] || \"title-\".concat(titleId || nextUniqueId())\n      },\n      children: [title]\n    });\n\n    var args = _objectSpread2(_objectSpread2({}, content), {}, {\n      prefix: prefix,\n      iconName: iconName,\n      main: main,\n      mask: mask,\n      maskId: maskId,\n      transform: transform,\n      symbol: symbol,\n      styles: _objectSpread2(_objectSpread2({}, uploadedIconWidthStyle), extra.styles)\n    });\n\n    var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args),\n        children = _ref2.children,\n        attributes = _ref2.attributes;\n\n    args.children = children;\n    args.attributes = attributes;\n\n    if (symbol) {\n      return asSymbol(args);\n    } else {\n      return asIcon(args);\n    }\n  }\n  function makeLayersTextAbstract(params) {\n    var content = params.content,\n        width = params.width,\n        height = params.height,\n        transform = params.transform,\n        title = params.title,\n        extra = params.extra,\n        _params$watchable2 = params.watchable,\n        watchable = _params$watchable2 === void 0 ? false : _params$watchable2;\n\n    var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n      'title': title\n    } : {}), {}, {\n      'class': extra.classes.join(' ')\n    });\n\n    if (watchable) {\n      attributes[DATA_FA_I2SVG] = '';\n    }\n\n    var styles = _objectSpread2({}, extra.styles);\n\n    if (transformIsMeaningful(transform)) {\n      styles['transform'] = transformForCss({\n        transform: transform,\n        startCentered: true,\n        width: width,\n        height: height\n      });\n      styles['-webkit-transform'] = styles['transform'];\n    }\n\n    var styleString = joinStyles(styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    var val = [];\n    val.push({\n      tag: 'span',\n      attributes: attributes,\n      children: [content]\n    });\n\n    if (title) {\n      val.push({\n        tag: 'span',\n        attributes: {\n          class: 'sr-only'\n        },\n        children: [title]\n      });\n    }\n\n    return val;\n  }\n  function makeLayersCounterAbstract(params) {\n    var content = params.content,\n        title = params.title,\n        extra = params.extra;\n\n    var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n      'title': title\n    } : {}), {}, {\n      'class': extra.classes.join(' ')\n    });\n\n    var styleString = joinStyles(extra.styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    var val = [];\n    val.push({\n      tag: 'span',\n      attributes: attributes,\n      children: [content]\n    });\n\n    if (title) {\n      val.push({\n        tag: 'span',\n        attributes: {\n          class: 'sr-only'\n        },\n        children: [title]\n      });\n    }\n\n    return val;\n  }\n\n  var noop$1 = function noop() {};\n\n  var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : {\n    mark: noop$1,\n    measure: noop$1\n  };\n  var preamble = \"FA \\\"5.15.4\\\"\";\n\n  var begin = function begin(name) {\n    p.mark(\"\".concat(preamble, \" \").concat(name, \" begins\"));\n    return function () {\n      return end(name);\n    };\n  };\n\n  var end = function end(name) {\n    p.mark(\"\".concat(preamble, \" \").concat(name, \" ends\"));\n    p.measure(\"\".concat(preamble, \" \").concat(name), \"\".concat(preamble, \" \").concat(name, \" begins\"), \"\".concat(preamble, \" \").concat(name, \" ends\"));\n  };\n\n  var perf = {\n    begin: begin,\n    end: end\n  };\n\n  /**\n   * Internal helper to bind a function known to have 4 arguments\n   * to a given context.\n   */\n\n  var bindInternal4 = function bindInternal4(func, thisContext) {\n    return function (a, b, c, d) {\n      return func.call(thisContext, a, b, c, d);\n    };\n  };\n\n  /**\n   * # Reduce\n   *\n   * A fast object `.reduce()` implementation.\n   *\n   * @param  {Object}   subject      The object to reduce over.\n   * @param  {Function} fn           The reducer function.\n   * @param  {mixed}    initialValue The initial value for the reducer, defaults to subject[0].\n   * @param  {Object}   thisContext  The context for the reducer.\n   * @return {mixed}                 The final result.\n   */\n\n\n  var reduce = function fastReduceObject(subject, fn, initialValue, thisContext) {\n    var keys = Object.keys(subject),\n        length = keys.length,\n        iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn,\n        i,\n        key,\n        result;\n\n    if (initialValue === undefined) {\n      i = 1;\n      result = subject[keys[0]];\n    } else {\n      i = 0;\n      result = initialValue;\n    }\n\n    for (; i < length; i++) {\n      key = keys[i];\n      result = iterator(result, subject[key], key, subject);\n    }\n\n    return result;\n  };\n\n  function toHex(unicode) {\n    var result = '';\n\n    for (var i = 0; i < unicode.length; i++) {\n      var hex = unicode.charCodeAt(i).toString(16);\n      result += ('000' + hex).slice(-4);\n    }\n\n    return result;\n  }\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var styles = namespace.styles,\n      shims = namespace.shims;\n  var _byUnicode = {};\n  var _byLigature = {};\n  var _byOldName = {};\n  var build = function build() {\n    var lookup = function lookup(reducer) {\n      return reduce(styles, function (o, style, prefix) {\n        o[prefix] = reduce(style, reducer, {});\n        return o;\n      }, {});\n    };\n\n    _byUnicode = lookup(function (acc, icon, iconName) {\n      if (icon[3]) {\n        acc[icon[3]] = iconName;\n      }\n\n      return acc;\n    });\n    _byLigature = lookup(function (acc, icon, iconName) {\n      var ligatures = icon[2];\n      acc[iconName] = iconName;\n      ligatures.forEach(function (ligature) {\n        acc[ligature] = iconName;\n      });\n      return acc;\n    });\n    var hasRegular = ('far' in styles);\n    _byOldName = reduce(shims, function (acc, shim) {\n      var oldName = shim[0];\n      var prefix = shim[1];\n      var iconName = shim[2];\n\n      if (prefix === 'far' && !hasRegular) {\n        prefix = 'fas';\n      }\n\n      acc[oldName] = {\n        prefix: prefix,\n        iconName: iconName\n      };\n      return acc;\n    }, {});\n  };\n  build();\n  function byUnicode(prefix, unicode) {\n    return (_byUnicode[prefix] || {})[unicode];\n  }\n  function byLigature(prefix, ligature) {\n    return (_byLigature[prefix] || {})[ligature];\n  }\n  function byOldName(name) {\n    return _byOldName[name] || {\n      prefix: null,\n      iconName: null\n    };\n  }\n\n  var styles$1 = namespace.styles;\n  var emptyCanonicalIcon = function emptyCanonicalIcon() {\n    return {\n      prefix: null,\n      iconName: null,\n      rest: []\n    };\n  };\n  function getCanonicalIcon(values) {\n    return values.reduce(function (acc, cls) {\n      var iconName = getIconName(config.familyPrefix, cls);\n\n      if (styles$1[cls]) {\n        acc.prefix = cls;\n      } else if (config.autoFetchSvg && Object.keys(PREFIX_TO_STYLE).indexOf(cls) > -1) {\n        acc.prefix = cls;\n      } else if (iconName) {\n        var shim = acc.prefix === 'fa' ? byOldName(iconName) : {};\n        acc.iconName = shim.iconName || iconName;\n        acc.prefix = shim.prefix || acc.prefix;\n      } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) {\n        acc.rest.push(cls);\n      }\n\n      return acc;\n    }, emptyCanonicalIcon());\n  }\n  function iconFromMapping(mapping, prefix, iconName) {\n    if (mapping && mapping[prefix] && mapping[prefix][iconName]) {\n      return {\n        prefix: prefix,\n        iconName: iconName,\n        icon: mapping[prefix][iconName]\n      };\n    }\n  }\n\n  function toHtml(abstractNodes) {\n    var tag = abstractNodes.tag,\n        _abstractNodes$attrib = abstractNodes.attributes,\n        attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib,\n        _abstractNodes$childr = abstractNodes.children,\n        children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr;\n\n    if (typeof abstractNodes === 'string') {\n      return htmlEscape(abstractNodes);\n    } else {\n      return \"<\".concat(tag, \" \").concat(joinAttributes(attributes), \">\").concat(children.map(toHtml).join(''), \"</\").concat(tag, \">\");\n    }\n  }\n\n  var noop$2 = function noop() {};\n\n  function isWatched(node) {\n    var i2svg = node.getAttribute ? node.getAttribute(DATA_FA_I2SVG) : null;\n    return typeof i2svg === 'string';\n  }\n\n  function getMutator() {\n    if (config.autoReplaceSvg === true) {\n      return mutators.replace;\n    }\n\n    var mutator = mutators[config.autoReplaceSvg];\n    return mutator || mutators.replace;\n  }\n\n  var mutators = {\n    replace: function replace(mutation) {\n      var node = mutation[0];\n      var abstract = mutation[1];\n      var newOuterHTML = abstract.map(function (a) {\n        return toHtml(a);\n      }).join('\\n');\n\n      if (node.parentNode && node.outerHTML) {\n        node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? \"<!-- \".concat(node.outerHTML, \" Font Awesome fontawesome.com -->\") : '');\n      } else if (node.parentNode) {\n        var newNode = document.createElement('span');\n        node.parentNode.replaceChild(newNode, node);\n        newNode.outerHTML = newOuterHTML;\n      }\n    },\n    nest: function nest(mutation) {\n      var node = mutation[0];\n      var abstract = mutation[1]; // If we already have a replaced node we do not want to continue nesting within it.\n      // Short-circuit to the standard replacement\n\n      if (~classArray(node).indexOf(config.replacementClass)) {\n        return mutators.replace(mutation);\n      }\n\n      var forSvg = new RegExp(\"\".concat(config.familyPrefix, \"-.*\"));\n      delete abstract[0].attributes.style;\n      delete abstract[0].attributes.id;\n      var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) {\n        if (cls === config.replacementClass || cls.match(forSvg)) {\n          acc.toSvg.push(cls);\n        } else {\n          acc.toNode.push(cls);\n        }\n\n        return acc;\n      }, {\n        toNode: [],\n        toSvg: []\n      });\n      abstract[0].attributes.class = splitClasses.toSvg.join(' ');\n      var newInnerHTML = abstract.map(function (a) {\n        return toHtml(a);\n      }).join('\\n');\n      node.setAttribute('class', splitClasses.toNode.join(' '));\n      node.setAttribute(DATA_FA_I2SVG, '');\n      node.innerHTML = newInnerHTML;\n    }\n  };\n\n  function performOperationSync(op) {\n    op();\n  }\n\n  function perform(mutations, callback) {\n    var callbackFunction = typeof callback === 'function' ? callback : noop$2;\n\n    if (mutations.length === 0) {\n      callbackFunction();\n    } else {\n      var frame = performOperationSync;\n\n      if (config.mutateApproach === MUTATION_APPROACH_ASYNC) {\n        frame = WINDOW.requestAnimationFrame || performOperationSync;\n      }\n\n      frame(function () {\n        var mutator = getMutator();\n        var mark = perf.begin('mutate');\n        mutations.map(mutator);\n        mark();\n        callbackFunction();\n      });\n    }\n  }\n  var disabled = false;\n  function disableObservation() {\n    disabled = true;\n  }\n  function enableObservation() {\n    disabled = false;\n  }\n  var mo = null;\n  function observe(options) {\n    if (!MUTATION_OBSERVER) {\n      return;\n    }\n\n    if (!config.observeMutations) {\n      return;\n    }\n\n    var treeCallback = options.treeCallback,\n        nodeCallback = options.nodeCallback,\n        pseudoElementsCallback = options.pseudoElementsCallback,\n        _options$observeMutat = options.observeMutationsRoot,\n        observeMutationsRoot = _options$observeMutat === void 0 ? DOCUMENT : _options$observeMutat;\n    mo = new MUTATION_OBSERVER(function (objects) {\n      if (disabled) return;\n      toArray(objects).forEach(function (mutationRecord) {\n        if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isWatched(mutationRecord.addedNodes[0])) {\n          if (config.searchPseudoElements) {\n            pseudoElementsCallback(mutationRecord.target);\n          }\n\n          treeCallback(mutationRecord.target);\n        }\n\n        if (mutationRecord.type === 'attributes' && mutationRecord.target.parentNode && config.searchPseudoElements) {\n          pseudoElementsCallback(mutationRecord.target.parentNode);\n        }\n\n        if (mutationRecord.type === 'attributes' && isWatched(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) {\n          if (mutationRecord.attributeName === 'class') {\n            var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)),\n                prefix = _getCanonicalIcon.prefix,\n                iconName = _getCanonicalIcon.iconName;\n\n            if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix);\n            if (iconName) mutationRecord.target.setAttribute('data-icon', iconName);\n          } else {\n            nodeCallback(mutationRecord.target);\n          }\n        }\n      });\n    });\n    if (!IS_DOM) return;\n    mo.observe(observeMutationsRoot, {\n      childList: true,\n      attributes: true,\n      characterData: true,\n      subtree: true\n    });\n  }\n  function disconnect() {\n    if (!mo) return;\n    mo.disconnect();\n  }\n\n  function styleParser (node) {\n    var style = node.getAttribute('style');\n    var val = [];\n\n    if (style) {\n      val = style.split(';').reduce(function (acc, style) {\n        var styles = style.split(':');\n        var prop = styles[0];\n        var value = styles.slice(1);\n\n        if (prop && value.length > 0) {\n          acc[prop] = value.join(':').trim();\n        }\n\n        return acc;\n      }, {});\n    }\n\n    return val;\n  }\n\n  function classParser (node) {\n    var existingPrefix = node.getAttribute('data-prefix');\n    var existingIconName = node.getAttribute('data-icon');\n    var innerText = node.innerText !== undefined ? node.innerText.trim() : '';\n    var val = getCanonicalIcon(classArray(node));\n\n    if (existingPrefix && existingIconName) {\n      val.prefix = existingPrefix;\n      val.iconName = existingIconName;\n    }\n\n    if (val.prefix && innerText.length > 1) {\n      val.iconName = byLigature(val.prefix, node.innerText);\n    } else if (val.prefix && innerText.length === 1) {\n      val.iconName = byUnicode(val.prefix, toHex(node.innerText));\n    }\n\n    return val;\n  }\n\n  var parseTransformString = function parseTransformString(transformString) {\n    var transform = {\n      size: 16,\n      x: 0,\n      y: 0,\n      flipX: false,\n      flipY: false,\n      rotate: 0\n    };\n\n    if (!transformString) {\n      return transform;\n    } else {\n      return transformString.toLowerCase().split(' ').reduce(function (acc, n) {\n        var parts = n.toLowerCase().split('-');\n        var first = parts[0];\n        var rest = parts.slice(1).join('-');\n\n        if (first && rest === 'h') {\n          acc.flipX = true;\n          return acc;\n        }\n\n        if (first && rest === 'v') {\n          acc.flipY = true;\n          return acc;\n        }\n\n        rest = parseFloat(rest);\n\n        if (isNaN(rest)) {\n          return acc;\n        }\n\n        switch (first) {\n          case 'grow':\n            acc.size = acc.size + rest;\n            break;\n\n          case 'shrink':\n            acc.size = acc.size - rest;\n            break;\n\n          case 'left':\n            acc.x = acc.x - rest;\n            break;\n\n          case 'right':\n            acc.x = acc.x + rest;\n            break;\n\n          case 'up':\n            acc.y = acc.y - rest;\n            break;\n\n          case 'down':\n            acc.y = acc.y + rest;\n            break;\n\n          case 'rotate':\n            acc.rotate = acc.rotate + rest;\n            break;\n        }\n\n        return acc;\n      }, transform);\n    }\n  };\n  function transformParser (node) {\n    return parseTransformString(node.getAttribute('data-fa-transform'));\n  }\n\n  function symbolParser (node) {\n    var symbol = node.getAttribute('data-fa-symbol');\n    return symbol === null ? false : symbol === '' ? true : symbol;\n  }\n\n  function attributesParser (node) {\n    var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) {\n      if (acc.name !== 'class' && acc.name !== 'style') {\n        acc[attr.name] = attr.value;\n      }\n\n      return acc;\n    }, {});\n    var title = node.getAttribute('title');\n    var titleId = node.getAttribute('data-fa-title-id');\n\n    if (config.autoA11y) {\n      if (title) {\n        extraAttributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n      } else {\n        extraAttributes['aria-hidden'] = 'true';\n        extraAttributes['focusable'] = 'false';\n      }\n    }\n\n    return extraAttributes;\n  }\n\n  function maskParser (node) {\n    var mask = node.getAttribute('data-fa-mask');\n\n    if (!mask) {\n      return emptyCanonicalIcon();\n    } else {\n      return getCanonicalIcon(mask.split(' ').map(function (i) {\n        return i.trim();\n      }));\n    }\n  }\n\n  function blankMeta() {\n    return {\n      iconName: null,\n      title: null,\n      titleId: null,\n      prefix: null,\n      transform: meaninglessTransform,\n      symbol: false,\n      mask: null,\n      maskId: null,\n      extra: {\n        classes: [],\n        styles: {},\n        attributes: {}\n      }\n    };\n  }\n  function parseMeta(node) {\n    var _classParser = classParser(node),\n        iconName = _classParser.iconName,\n        prefix = _classParser.prefix,\n        extraClasses = _classParser.rest;\n\n    var extraStyles = styleParser(node);\n    var transform = transformParser(node);\n    var symbol = symbolParser(node);\n    var extraAttributes = attributesParser(node);\n    var mask = maskParser(node);\n    return {\n      iconName: iconName,\n      title: node.getAttribute('title'),\n      titleId: node.getAttribute('data-fa-title-id'),\n      prefix: prefix,\n      transform: transform,\n      symbol: symbol,\n      mask: mask,\n      maskId: node.getAttribute('data-fa-mask-id'),\n      extra: {\n        classes: extraClasses,\n        styles: extraStyles,\n        attributes: extraAttributes\n      }\n    };\n  }\n\n  function MissingIcon(error) {\n    this.name = 'MissingIcon';\n    this.message = error || 'Icon unavailable';\n    this.stack = new Error().stack;\n  }\n  MissingIcon.prototype = Object.create(Error.prototype);\n  MissingIcon.prototype.constructor = MissingIcon;\n\n  var FILL = {\n    fill: 'currentColor'\n  };\n  var ANIMATION_BASE = {\n    attributeType: 'XML',\n    repeatCount: 'indefinite',\n    dur: '2s'\n  };\n  var RING = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z'\n    })\n  };\n\n  var OPACITY_ANIMATE = _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n    attributeName: 'opacity'\n  });\n\n  var DOT = {\n    tag: 'circle',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      cx: '256',\n      cy: '364',\n      r: '28'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n        attributeName: 'r',\n        values: '28;14;28;28;14;28;'\n      })\n    }, {\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '1;0;1;1;0;1;'\n      })\n    }]\n  };\n  var QUESTION = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      opacity: '1',\n      d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '1;0;0;0;0;1;'\n      })\n    }]\n  };\n  var EXCLAMATION = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      opacity: '0',\n      d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '0;0;1;1;0;0;'\n      })\n    }]\n  };\n  var missing = {\n    tag: 'g',\n    children: [RING, DOT, QUESTION, EXCLAMATION]\n  };\n\n  var styles$2 = namespace.styles;\n  function asFoundIcon(icon) {\n    var width = icon[0];\n    var height = icon[1];\n\n    var _icon$slice = icon.slice(4),\n        _icon$slice2 = _slicedToArray(_icon$slice, 1),\n        vectorData = _icon$slice2[0];\n\n    var element = null;\n\n    if (Array.isArray(vectorData)) {\n      element = {\n        tag: 'g',\n        attributes: {\n          class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.GROUP)\n        },\n        children: [{\n          tag: 'path',\n          attributes: {\n            class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.SECONDARY),\n            fill: 'currentColor',\n            d: vectorData[0]\n          }\n        }, {\n          tag: 'path',\n          attributes: {\n            class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.PRIMARY),\n            fill: 'currentColor',\n            d: vectorData[1]\n          }\n        }]\n      };\n    } else {\n      element = {\n        tag: 'path',\n        attributes: {\n          fill: 'currentColor',\n          d: vectorData\n        }\n      };\n    }\n\n    return {\n      found: true,\n      width: width,\n      height: height,\n      icon: element\n    };\n  }\n  function findIcon(iconName, prefix) {\n    return new picked(function (resolve, reject) {\n      var val = {\n        found: false,\n        width: 512,\n        height: 512,\n        icon: missing\n      };\n\n      if (iconName && prefix && styles$2[prefix] && styles$2[prefix][iconName]) {\n        var icon = styles$2[prefix][iconName];\n        return resolve(asFoundIcon(icon));\n      }\n\n      if (iconName && prefix && !config.showMissingIcons) {\n        reject(new MissingIcon(\"Icon is missing for prefix \".concat(prefix, \" with icon name \").concat(iconName)));\n      } else {\n        resolve(val);\n      }\n    });\n  }\n\n  var styles$3 = namespace.styles;\n\n  function generateSvgReplacementMutation(node, nodeMeta) {\n    var iconName = nodeMeta.iconName,\n        title = nodeMeta.title,\n        titleId = nodeMeta.titleId,\n        prefix = nodeMeta.prefix,\n        transform = nodeMeta.transform,\n        symbol = nodeMeta.symbol,\n        mask = nodeMeta.mask,\n        maskId = nodeMeta.maskId,\n        extra = nodeMeta.extra;\n    return new picked(function (resolve, reject) {\n      picked.all([findIcon(iconName, prefix), findIcon(mask.iconName, mask.prefix)]).then(function (_ref) {\n        var _ref2 = _slicedToArray(_ref, 2),\n            main = _ref2[0],\n            mask = _ref2[1];\n\n        resolve([node, makeInlineSvgAbstract({\n          icons: {\n            main: main,\n            mask: mask\n          },\n          prefix: prefix,\n          iconName: iconName,\n          transform: transform,\n          symbol: symbol,\n          mask: mask,\n          maskId: maskId,\n          title: title,\n          titleId: titleId,\n          extra: extra,\n          watchable: true\n        })]);\n      });\n    });\n  }\n\n  function generateLayersText(node, nodeMeta) {\n    var title = nodeMeta.title,\n        transform = nodeMeta.transform,\n        extra = nodeMeta.extra;\n    var width = null;\n    var height = null;\n\n    if (IS_IE) {\n      var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10);\n      var boundingClientRect = node.getBoundingClientRect();\n      width = boundingClientRect.width / computedFontSize;\n      height = boundingClientRect.height / computedFontSize;\n    }\n\n    if (config.autoA11y && !title) {\n      extra.attributes['aria-hidden'] = 'true';\n    }\n\n    return picked.resolve([node, makeLayersTextAbstract({\n      content: node.innerHTML,\n      width: width,\n      height: height,\n      transform: transform,\n      title: title,\n      extra: extra,\n      watchable: true\n    })]);\n  }\n\n  function generateMutation(node) {\n    var nodeMeta = parseMeta(node);\n\n    if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) {\n      return generateLayersText(node, nodeMeta);\n    } else {\n      return generateSvgReplacementMutation(node, nodeMeta);\n    }\n  }\n\n  function onTree(root) {\n    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n    if (!IS_DOM) return;\n    var htmlClassList = DOCUMENT.documentElement.classList;\n\n    var hclAdd = function hclAdd(suffix) {\n      return htmlClassList.add(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n    };\n\n    var hclRemove = function hclRemove(suffix) {\n      return htmlClassList.remove(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n    };\n\n    var prefixes = config.autoFetchSvg ? Object.keys(PREFIX_TO_STYLE) : Object.keys(styles$3);\n    var prefixesDomQuery = [\".\".concat(LAYERS_TEXT_CLASSNAME, \":not([\").concat(DATA_FA_I2SVG, \"])\")].concat(prefixes.map(function (p) {\n      return \".\".concat(p, \":not([\").concat(DATA_FA_I2SVG, \"])\");\n    })).join(', ');\n\n    if (prefixesDomQuery.length === 0) {\n      return;\n    }\n\n    var candidates = [];\n\n    try {\n      candidates = toArray(root.querySelectorAll(prefixesDomQuery));\n    } catch (e) {// noop\n    }\n\n    if (candidates.length > 0) {\n      hclAdd('pending');\n      hclRemove('complete');\n    } else {\n      return;\n    }\n\n    var mark = perf.begin('onTree');\n    var mutations = candidates.reduce(function (acc, node) {\n      try {\n        var mutation = generateMutation(node);\n\n        if (mutation) {\n          acc.push(mutation);\n        }\n      } catch (e) {\n        if (!PRODUCTION) {\n          if (e instanceof MissingIcon) {\n            console.error(e);\n          }\n        }\n      }\n\n      return acc;\n    }, []);\n    return new picked(function (resolve, reject) {\n      picked.all(mutations).then(function (resolvedMutations) {\n        perform(resolvedMutations, function () {\n          hclAdd('active');\n          hclAdd('complete');\n          hclRemove('pending');\n          if (typeof callback === 'function') callback();\n          mark();\n          resolve();\n        });\n      }).catch(function () {\n        mark();\n        reject();\n      });\n    });\n  }\n  function onNode(node) {\n    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n    generateMutation(node).then(function (mutation) {\n      if (mutation) {\n        perform([mutation], callback);\n      }\n    });\n  }\n\n  function replaceForPosition(node, position) {\n    var pendingAttribute = \"\".concat(DATA_FA_PSEUDO_ELEMENT_PENDING).concat(position.replace(':', '-'));\n    return new picked(function (resolve, reject) {\n      if (node.getAttribute(pendingAttribute) !== null) {\n        // This node is already being processed\n        return resolve();\n      }\n\n      var children = toArray(node.children);\n      var alreadyProcessedPseudoElement = children.filter(function (c) {\n        return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === position;\n      })[0];\n      var styles = WINDOW.getComputedStyle(node, position);\n      var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN);\n      var fontWeight = styles.getPropertyValue('font-weight');\n      var content = styles.getPropertyValue('content');\n\n      if (alreadyProcessedPseudoElement && !fontFamily) {\n        // If we've already processed it but the current computed style does not result in a font-family,\n        // that probably means that a class name that was previously present to make the icon has been\n        // removed. So we now should delete the icon.\n        node.removeChild(alreadyProcessedPseudoElement);\n        return resolve();\n      } else if (fontFamily && content !== 'none' && content !== '') {\n        var _content = styles.getPropertyValue('content');\n\n        var prefix = ~['Solid', 'Regular', 'Light', 'Duotone', 'Brands', 'Kit'].indexOf(fontFamily[2]) ? STYLE_TO_PREFIX[fontFamily[2].toLowerCase()] : FONT_WEIGHT_TO_PREFIX[fontWeight];\n        var hexValue = toHex(_content.length === 3 ? _content.substr(1, 1) : _content);\n        var iconName = byUnicode(prefix, hexValue);\n        var iconIdentifier = iconName; // Only convert the pseudo element in this :before/:after position into an icon if we haven't\n        // already done so with the same prefix and iconName\n\n        if (iconName && (!alreadyProcessedPseudoElement || alreadyProcessedPseudoElement.getAttribute(DATA_PREFIX) !== prefix || alreadyProcessedPseudoElement.getAttribute(DATA_ICON) !== iconIdentifier)) {\n          node.setAttribute(pendingAttribute, iconIdentifier);\n\n          if (alreadyProcessedPseudoElement) {\n            // Delete the old one, since we're replacing it with a new one\n            node.removeChild(alreadyProcessedPseudoElement);\n          }\n\n          var meta = blankMeta();\n          var extra = meta.extra;\n          extra.attributes[DATA_FA_PSEUDO_ELEMENT] = position;\n          findIcon(iconName, prefix).then(function (main) {\n            var abstract = makeInlineSvgAbstract(_objectSpread2(_objectSpread2({}, meta), {}, {\n              icons: {\n                main: main,\n                mask: emptyCanonicalIcon()\n              },\n              prefix: prefix,\n              iconName: iconIdentifier,\n              extra: extra,\n              watchable: true\n            }));\n            var element = DOCUMENT.createElement('svg');\n\n            if (position === ':before') {\n              node.insertBefore(element, node.firstChild);\n            } else {\n              node.appendChild(element);\n            }\n\n            element.outerHTML = abstract.map(function (a) {\n              return toHtml(a);\n            }).join('\\n');\n            node.removeAttribute(pendingAttribute);\n            resolve();\n          }).catch(reject);\n        } else {\n          resolve();\n        }\n      } else {\n        resolve();\n      }\n    });\n  }\n\n  function replace(node) {\n    return picked.all([replaceForPosition(node, ':before'), replaceForPosition(node, ':after')]);\n  }\n\n  function processable(node) {\n    return node.parentNode !== document.head && !~TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS.indexOf(node.tagName.toUpperCase()) && !node.getAttribute(DATA_FA_PSEUDO_ELEMENT) && (!node.parentNode || node.parentNode.tagName !== 'svg');\n  }\n\n  function searchPseudoElements (root) {\n    if (!IS_DOM) return;\n    return new picked(function (resolve, reject) {\n      var operations = toArray(root.querySelectorAll('*')).filter(processable).map(replace);\n      var end = perf.begin('searchPseudoElements');\n      disableObservation();\n      picked.all(operations).then(function () {\n        end();\n        enableObservation();\n        resolve();\n      }).catch(function () {\n        end();\n        enableObservation();\n        reject();\n      });\n    });\n  }\n\n  var baseStyles = \"svg:not(:root).svg-inline--fa{overflow:visible}.svg-inline--fa{display:inline-block;font-size:inherit;height:1em;overflow:visible;vertical-align:-.125em}.svg-inline--fa.fa-lg{vertical-align:-.225em}.svg-inline--fa.fa-w-1{width:.0625em}.svg-inline--fa.fa-w-2{width:.125em}.svg-inline--fa.fa-w-3{width:.1875em}.svg-inline--fa.fa-w-4{width:.25em}.svg-inline--fa.fa-w-5{width:.3125em}.svg-inline--fa.fa-w-6{width:.375em}.svg-inline--fa.fa-w-7{width:.4375em}.svg-inline--fa.fa-w-8{width:.5em}.svg-inline--fa.fa-w-9{width:.5625em}.svg-inline--fa.fa-w-10{width:.625em}.svg-inline--fa.fa-w-11{width:.6875em}.svg-inline--fa.fa-w-12{width:.75em}.svg-inline--fa.fa-w-13{width:.8125em}.svg-inline--fa.fa-w-14{width:.875em}.svg-inline--fa.fa-w-15{width:.9375em}.svg-inline--fa.fa-w-16{width:1em}.svg-inline--fa.fa-w-17{width:1.0625em}.svg-inline--fa.fa-w-18{width:1.125em}.svg-inline--fa.fa-w-19{width:1.1875em}.svg-inline--fa.fa-w-20{width:1.25em}.svg-inline--fa.fa-pull-left{margin-right:.3em;width:auto}.svg-inline--fa.fa-pull-right{margin-left:.3em;width:auto}.svg-inline--fa.fa-border{height:1.5em}.svg-inline--fa.fa-li{width:2em}.svg-inline--fa.fa-fw{width:1.25em}.fa-layers svg.svg-inline--fa{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.fa-layers{display:inline-block;height:1em;position:relative;text-align:center;vertical-align:-.125em;width:1em}.fa-layers svg.svg-inline--fa{-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter,.fa-layers-text{display:inline-block;position:absolute;text-align:center}.fa-layers-text{left:50%;top:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);-webkit-transform-origin:center center;transform-origin:center center}.fa-layers-counter{background-color:#ff253a;border-radius:1em;-webkit-box-sizing:border-box;box-sizing:border-box;color:#fff;height:1.5em;line-height:1;max-width:5em;min-width:1.5em;overflow:hidden;padding:.25em;right:0;text-overflow:ellipsis;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-bottom-right{bottom:0;right:0;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom right;transform-origin:bottom right}.fa-layers-bottom-left{bottom:0;left:0;right:auto;top:auto;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:bottom left;transform-origin:bottom left}.fa-layers-top-right{right:0;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top right;transform-origin:top right}.fa-layers-top-left{left:0;right:auto;top:0;-webkit-transform:scale(.25);transform:scale(.25);-webkit-transform-origin:top left;transform-origin:top left}.fa-lg{font-size:1.3333333333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:solid .08em #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.fa-rotate-90{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-webkit-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-webkit-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-webkit-transform:scale(1,-1);transform:scale(1,-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{-webkit-transform:scale(-1,-1);transform:scale(-1,-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-rotate-90{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;position:relative;width:2.5em}.fa-stack-1x,.fa-stack-2x{bottom:0;left:0;margin:auto;position:absolute;right:0;top:0}.svg-inline--fa.fa-stack-1x{height:1em;width:1.25em}.svg-inline--fa.fa-stack-2x{height:2em;width:2.5em}.fa-inverse{color:#fff}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.svg-inline--fa .fa-primary{fill:var(--fa-primary-color,currentColor);opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa .fa-secondary{fill:var(--fa-secondary-color,currentColor);opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-primary{opacity:.4;opacity:var(--fa-secondary-opacity,.4)}.svg-inline--fa.fa-swap-opacity .fa-secondary{opacity:1;opacity:var(--fa-primary-opacity,1)}.svg-inline--fa mask .fa-primary,.svg-inline--fa mask .fa-secondary{fill:#000}.fad.fa-inverse{color:#fff}\";\n\n  function css () {\n    var dfp = DEFAULT_FAMILY_PREFIX;\n    var drc = DEFAULT_REPLACEMENT_CLASS;\n    var fp = config.familyPrefix;\n    var rc = config.replacementClass;\n    var s = baseStyles;\n\n    if (fp !== dfp || rc !== drc) {\n      var dPatt = new RegExp(\"\\\\.\".concat(dfp, \"\\\\-\"), 'g');\n      var customPropPatt = new RegExp(\"\\\\--\".concat(dfp, \"\\\\-\"), 'g');\n      var rPatt = new RegExp(\"\\\\.\".concat(drc), 'g');\n      s = s.replace(dPatt, \".\".concat(fp, \"-\")).replace(customPropPatt, \"--\".concat(fp, \"-\")).replace(rPatt, \".\".concat(rc));\n    }\n\n    return s;\n  }\n\n  var Library = /*#__PURE__*/function () {\n    function Library() {\n      _classCallCheck(this, Library);\n\n      this.definitions = {};\n    }\n\n    _createClass(Library, [{\n      key: \"add\",\n      value: function add() {\n        var _this = this;\n\n        for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) {\n          definitions[_key] = arguments[_key];\n        }\n\n        var additions = definitions.reduce(this._pullDefinitions, {});\n        Object.keys(additions).forEach(function (key) {\n          _this.definitions[key] = _objectSpread2(_objectSpread2({}, _this.definitions[key] || {}), additions[key]);\n          defineIcons(key, additions[key]);\n          build();\n        });\n      }\n    }, {\n      key: \"reset\",\n      value: function reset() {\n        this.definitions = {};\n      }\n    }, {\n      key: \"_pullDefinitions\",\n      value: function _pullDefinitions(additions, definition) {\n        var normalized = definition.prefix && definition.iconName && definition.icon ? {\n          0: definition\n        } : definition;\n        Object.keys(normalized).map(function (key) {\n          var _normalized$key = normalized[key],\n              prefix = _normalized$key.prefix,\n              iconName = _normalized$key.iconName,\n              icon = _normalized$key.icon;\n          if (!additions[prefix]) additions[prefix] = {};\n          additions[prefix][iconName] = icon;\n        });\n        return additions;\n      }\n    }]);\n\n    return Library;\n  }();\n\n  function ensureCss() {\n    if (config.autoAddCss && !_cssInserted) {\n      insertCss(css());\n\n      _cssInserted = true;\n    }\n  }\n\n  function apiObject(val, abstractCreator) {\n    Object.defineProperty(val, 'abstract', {\n      get: abstractCreator\n    });\n    Object.defineProperty(val, 'html', {\n      get: function get() {\n        return val.abstract.map(function (a) {\n          return toHtml(a);\n        });\n      }\n    });\n    Object.defineProperty(val, 'node', {\n      get: function get() {\n        if (!IS_DOM) return;\n        var container = DOCUMENT.createElement('div');\n        container.innerHTML = val.html;\n        return container.children;\n      }\n    });\n    return val;\n  }\n\n  function findIconDefinition(iconLookup) {\n    var _iconLookup$prefix = iconLookup.prefix,\n        prefix = _iconLookup$prefix === void 0 ? 'fa' : _iconLookup$prefix,\n        iconName = iconLookup.iconName;\n    if (!iconName) return;\n    return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName);\n  }\n\n  function resolveIcons(next) {\n    return function (maybeIconDefinition) {\n      var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n      var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {});\n      var mask = params.mask;\n\n      if (mask) {\n        mask = (mask || {}).icon ? mask : findIconDefinition(mask || {});\n      }\n\n      return next(iconDefinition, _objectSpread2(_objectSpread2({}, params), {}, {\n        mask: mask\n      }));\n    };\n  }\n\n  var library = new Library();\n  var noAuto = function noAuto() {\n    config.autoReplaceSvg = false;\n    config.observeMutations = false;\n    disconnect();\n  };\n  var _cssInserted = false;\n  var dom = {\n    i2svg: function i2svg() {\n      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n      if (IS_DOM) {\n        ensureCss();\n        var _params$node = params.node,\n            node = _params$node === void 0 ? DOCUMENT : _params$node,\n            _params$callback = params.callback,\n            callback = _params$callback === void 0 ? function () {} : _params$callback;\n\n        if (config.searchPseudoElements) {\n          searchPseudoElements(node);\n        }\n\n        return onTree(node, callback);\n      } else {\n        return picked.reject('Operation requires a DOM of some kind.');\n      }\n    },\n    css: css,\n    insertCss: function insertCss$$1() {\n      if (!_cssInserted) {\n        insertCss(css());\n\n        _cssInserted = true;\n      }\n    },\n    watch: function watch() {\n      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n      var autoReplaceSvgRoot = params.autoReplaceSvgRoot,\n          observeMutationsRoot = params.observeMutationsRoot;\n\n      if (config.autoReplaceSvg === false) {\n        config.autoReplaceSvg = true;\n      }\n\n      config.observeMutations = true;\n      domready(function () {\n        autoReplace({\n          autoReplaceSvgRoot: autoReplaceSvgRoot\n        });\n        observe({\n          treeCallback: onTree,\n          nodeCallback: onNode,\n          pseudoElementsCallback: searchPseudoElements,\n          observeMutationsRoot: observeMutationsRoot\n        });\n      });\n    }\n  };\n  var parse = {\n    transform: function transform(transformString) {\n      return parseTransformString(transformString);\n    }\n  };\n  var icon = resolveIcons(function (iconDefinition) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$transform = params.transform,\n        transform = _params$transform === void 0 ? meaninglessTransform : _params$transform,\n        _params$symbol = params.symbol,\n        symbol = _params$symbol === void 0 ? false : _params$symbol,\n        _params$mask = params.mask,\n        mask = _params$mask === void 0 ? null : _params$mask,\n        _params$maskId = params.maskId,\n        maskId = _params$maskId === void 0 ? null : _params$maskId,\n        _params$title = params.title,\n        title = _params$title === void 0 ? null : _params$title,\n        _params$titleId = params.titleId,\n        titleId = _params$titleId === void 0 ? null : _params$titleId,\n        _params$classes = params.classes,\n        classes = _params$classes === void 0 ? [] : _params$classes,\n        _params$attributes = params.attributes,\n        attributes = _params$attributes === void 0 ? {} : _params$attributes,\n        _params$styles = params.styles,\n        styles = _params$styles === void 0 ? {} : _params$styles;\n    if (!iconDefinition) return;\n    var prefix = iconDefinition.prefix,\n        iconName = iconDefinition.iconName,\n        icon = iconDefinition.icon;\n    return apiObject(_objectSpread2({\n      type: 'icon'\n    }, iconDefinition), function () {\n      ensureCss();\n\n      if (config.autoA11y) {\n        if (title) {\n          attributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n        } else {\n          attributes['aria-hidden'] = 'true';\n          attributes['focusable'] = 'false';\n        }\n      }\n\n      return makeInlineSvgAbstract({\n        icons: {\n          main: asFoundIcon(icon),\n          mask: mask ? asFoundIcon(mask.icon) : {\n            found: false,\n            width: null,\n            height: null,\n            icon: {}\n          }\n        },\n        prefix: prefix,\n        iconName: iconName,\n        transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n        symbol: symbol,\n        title: title,\n        maskId: maskId,\n        titleId: titleId,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: classes\n        }\n      });\n    });\n  });\n  var text = function text(content) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$transform2 = params.transform,\n        transform = _params$transform2 === void 0 ? meaninglessTransform : _params$transform2,\n        _params$title2 = params.title,\n        title = _params$title2 === void 0 ? null : _params$title2,\n        _params$classes2 = params.classes,\n        classes = _params$classes2 === void 0 ? [] : _params$classes2,\n        _params$attributes2 = params.attributes,\n        attributes = _params$attributes2 === void 0 ? {} : _params$attributes2,\n        _params$styles2 = params.styles,\n        styles = _params$styles2 === void 0 ? {} : _params$styles2;\n    return apiObject({\n      type: 'text',\n      content: content\n    }, function () {\n      ensureCss();\n      return makeLayersTextAbstract({\n        content: content,\n        transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n        title: title,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: [\"\".concat(config.familyPrefix, \"-layers-text\")].concat(_toConsumableArray(classes))\n        }\n      });\n    });\n  };\n  var counter = function counter(content) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$title3 = params.title,\n        title = _params$title3 === void 0 ? null : _params$title3,\n        _params$classes3 = params.classes,\n        classes = _params$classes3 === void 0 ? [] : _params$classes3,\n        _params$attributes3 = params.attributes,\n        attributes = _params$attributes3 === void 0 ? {} : _params$attributes3,\n        _params$styles3 = params.styles,\n        styles = _params$styles3 === void 0 ? {} : _params$styles3;\n    return apiObject({\n      type: 'counter',\n      content: content\n    }, function () {\n      ensureCss();\n      return makeLayersCounterAbstract({\n        content: content.toString(),\n        title: title,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: [\"\".concat(config.familyPrefix, \"-layers-counter\")].concat(_toConsumableArray(classes))\n        }\n      });\n    });\n  };\n  var layer = function layer(assembler) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$classes4 = params.classes,\n        classes = _params$classes4 === void 0 ? [] : _params$classes4;\n    return apiObject({\n      type: 'layer'\n    }, function () {\n      ensureCss();\n      var children = [];\n      assembler(function (args) {\n        Array.isArray(args) ? args.map(function (a) {\n          children = children.concat(a.abstract);\n        }) : children = children.concat(args.abstract);\n      });\n      return [{\n        tag: 'span',\n        attributes: {\n          class: [\"\".concat(config.familyPrefix, \"-layers\")].concat(_toConsumableArray(classes)).join(' ')\n        },\n        children: children\n      }];\n    });\n  };\n  var api = {\n    noAuto: noAuto,\n    config: config,\n    dom: dom,\n    library: library,\n    parse: parse,\n    findIconDefinition: findIconDefinition,\n    icon: icon,\n    text: text,\n    counter: counter,\n    layer: layer,\n    toHtml: toHtml\n  };\n\n  var autoReplace = function autoReplace() {\n    var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n    var _params$autoReplaceSv = params.autoReplaceSvgRoot,\n        autoReplaceSvgRoot = _params$autoReplaceSv === void 0 ? DOCUMENT : _params$autoReplaceSv;\n    if ((Object.keys(namespace.styles).length > 0 || config.autoFetchSvg) && IS_DOM && config.autoReplaceSvg) api.dom.i2svg({\n      node: autoReplaceSvgRoot\n    });\n  };\n\n  function bootstrap() {\n    if (IS_BROWSER) {\n      if (!WINDOW.FontAwesome) {\n        WINDOW.FontAwesome = api;\n      }\n\n      domready(function () {\n        autoReplace();\n        observe({\n          treeCallback: onTree,\n          nodeCallback: onNode,\n          pseudoElementsCallback: searchPseudoElements\n        });\n      });\n    }\n\n    namespace.hooks = _objectSpread2(_objectSpread2({}, namespace.hooks), {}, {\n      addPack: function addPack(prefix, icons) {\n        namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), icons);\n        build();\n        autoReplace();\n      },\n      addShims: function addShims(shims) {\n        var _namespace$shims;\n\n        (_namespace$shims = namespace.shims).push.apply(_namespace$shims, _toConsumableArray(shims));\n\n        build();\n        autoReplace();\n      }\n    });\n  }\n\n  bunker(bootstrap);\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/js/regular.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"check-circle\": [512, 512, [], \"f058\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z\"],\n    \"desktop\": [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v288c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V54c0-3.3 2.7-6 6-6h468c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-42 152c0 13.3-10.7 24-24 24H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h98.7l18.6-55.8c1.6-4.9 6.2-8.2 11.4-8.2h78.7c5.2 0 9.8 3.3 11.4 8.2l18.6 55.8H456c13.3 0 24 10.7 24 24z\"],\n    \"eye\": [576, 512, [], \"f06e\", \"M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z\"],\n    \"file-code\": [384, 512, [], \"f1c9\", \"M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z\"],\n    \"info\": [256, 512, [], \"f129\", \"M224 352.589V224c0-16.475-6.258-31.517-16.521-42.872C225.905 161.14 236 135.346 236 108 236 48.313 187.697 0 128 0 68.313 0 20 48.303 20 108c0 20.882 5.886 40.859 16.874 58.037C15.107 176.264 0 198.401 0 224v39.314c0 23.641 12.884 44.329 32 55.411v33.864C12.884 363.671 0 384.359 0 408v40c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-40c0-23.641-12.884-44.329-32-55.411zM128 48c33.137 0 60 26.863 60 60s-26.863 60-60 60-60-26.863-60-60 26.863-60 60-60zm80 400c0 8.836-7.164 16-16 16H64c-8.836 0-16-7.164-16-16v-40c0-8.836 7.164-16 16-16h16V279.314H64c-8.836 0-16-7.164-16-16V224c0-8.836 7.164-16 16-16h96c8.836 0 16 7.164 16 16v168h16c8.836 0 16 7.164 16 16v40z\"],\n    \"info-circle\": [512, 512, [], \"f05a\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm0-338c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"],\n    \"plus\": [384, 512, [], \"f067\", \"M368 224H224V80c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h144v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V288h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"],\n    \"question-circle\": [512, 512, [], \"f059\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z\"],\n    \"rocket\": [512, 512, [], \"f135\", \"M367.96813,103.99609a39.999,39.999,0,1,0,40.00384,40A40.02908,40.02908,0,0,0,367.96813,103.99609ZM505.07337,19.3418c-1.21875-5.60742-6.75-11.13868-12.34373-12.3418-32.62885-7-58.162-7-83.57017-7C305.39988,0,242.95858,55.0918,196.236,127.99609H94.82015c-16.34567.01563-35.53314,11.875-42.87883,26.48243L2.53125,253.28906A28.12512,28.12512,0,0,0,0,263.99219a24.00617,24.00617,0,0,0,24.00191,23.998h92.63266l-10.59373,21.42188c-9.33592,18.91016,4.27733,34.77344,6.15624,36.62305l53.75381,53.71875c15.56443,15.54492,33.81635,7.52929,36.6601,6.13867l21.34567-10.57617V488a24.00659,24.00659,0,0,0,24.00191,24,28.618,28.618,0,0,0,10.71873-2.51562l98.6971-49.4043c14.625-7.29688,26.50191-26.5,26.50191-42.85938V315.69336c72.72449-46.76367,128.10525-109.44922,128.10525-212.69727C512.07531,77.4668,512.07531,51.99805,505.07337,19.3418ZM358.53065,274.99023c-36.94135,18.48438-121.10527,60.14063-166.7966,82.73243l-37.50189-37.49805c22.59567-45.6875,64.25575-129.99609,82.72447-166.88672C284.33741,79.5293,335.96623,47.99805,409.15947,47.99805c18.00192,0,34.2851,0,52.56632,2.34375,2.375,18.71875,2.31249,35.27929,2.25,52.63867C463.97578,175.75977,432.41138,227.30469,358.53065,274.99023Z\"],\n    \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z\"],\n    \"slash\": [640, 512, [], \"f715\", \"M604 508.49L6.01 40.98c-6.9-5.52-8.02-15.59-2.49-22.49L13.51 6C19.03-.9 29.1-2.01 36 3.51l598 467.51c6.9 5.52 8.02 15.59 2.49 22.49l-10 12.49c-5.52 6.9-15.59 8.01-22.49 2.49z\"],\n    \"times\": [320, 512, [], \"f00d\", \"M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z\"],\n    \"undo\": [512, 512, [], \"f0e2\", \"M12 8h27.711c6.739 0 12.157 5.548 11.997 12.286l-2.347 98.568C93.925 51.834 170.212 7.73 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.835 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.322 0 196-87.662 196-196 0-108.322-87.662-196-196-196-79.545 0-147.941 47.282-178.675 115.302l126.389-3.009c6.737-.16 12.286 5.257 12.286 11.997V212c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V20C0 13.373 5.373 8 12 8z\"],\n    \"undo-alt\": [512, 512, [], \"f2ea\", \"M28.485 28.485L80.65 80.65C125.525 35.767 187.515 8 255.999 8 392.66 8 504.1 119.525 504 256.185 503.9 393.067 392.905 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.353-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.321 0 196-87.662 196-196 0-108.321-87.662-196-196-196-54.163 0-103.157 21.923-138.614 57.386l54.128 54.129c7.56 7.56 2.206 20.485-8.485 20.485H20c-6.627 0-12-5.373-12-12V36.971c0-10.691 12.926-16.045 20.485-8.486z\"],\n    \"user\": [448, 512, [], \"f007\", \"M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z\"],\n    \"user-friends\": [640, 512, [], \"f500\", \"M480 256c53 0 96-43 96-96s-43-96-96-96-96 43-96 96 43 96 96 96zm0-144c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM272.1 276c-11.9 0-23.9 1.7-35.5 5.3-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-11.6-3.5-23.6-5.3-35.5-5.3-36.3 0-71.6 16.2-92.3 46.9C7.2 341.3 0 363.4 0 387.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM336 432H48v-44.8c0-28.9 18.4-53.6 44.1-63.1 10.3-3.8 21.6-3.7 31.9 0 22.1 7.9 45 11.9 68 11.9s45.8-4 68.1-11.9c10.3-3.7 21.6-3.8 31.9 0 25.7 9.4 44.1 34.2 44.1 63.1V432zM192 256c61.9 0 112-50.1 112-112S253.9 32 192 32 80 82.1 80 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm431.7 237.1C606.4 291.5 577 278 546.8 278c-27.8 0-34.8 10-66.8 10s-39-10-66.8-10c-13.3 0-26.2 3-38.2 8.1 5.8 5.9 11.3 12 16 18.9 4.7 7 8.6 14.4 12 22 3.3-.7 6.7-1.1 10.2-1.1 17.2 0 29.6 10 66.8 10 37.4 0 49.5-10 66.8-10 15.7 0 29.5 6.7 37.1 17.9 5.3 7.9 8.1 17.1 8.1 26.7V400H416v32c0 5.5-.6 10.8-1.6 16H600c22.1 0 40-17.9 40-40v-37.3c0-19.9-6-38.3-16.3-53.6z\"],\n    \"users\": [640, 512, [], \"f0c0\", \"M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zm396.4 210.9c-27.5-40.8-80.7-56-127.8-41.7-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-47.1-14.3-100.3.8-127.8 41.7-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c.2-23.8-7-45.9-19.4-64.3zM464 432H176v-44.8c0-36.4 29.2-66.2 65.4-67.2 25.5 10.6 51.9 16 78.6 16 26.7 0 53.1-5.4 78.6-16 36.2 1 65.4 30.7 65.4 67.2V432zm92-176h-24c-17.3 0-33.4 5.3-46.8 14.3 13.4 10.1 25.2 22.2 34.4 36.2 3.9-1.4 8-2.5 12.3-2.5h24c19.8 0 36 16.2 36 36 0 13.2 10.8 24 24 24s24-10.8 24-24c.1-46.3-37.6-84-83.9-84zm-236 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM154.8 270.3c-13.4-9-29.5-14.3-46.8-14.3H84c-46.3 0-84 37.7-84 84 0 13.2 10.8 24 24 24s24-10.8 24-24c0-19.8 16.2-36 36-36h24c4.4 0 8.5 1.1 12.3 2.5 9.3-14 21.1-26.1 34.5-36.2z\"]\n  };\n\n  bunker(function () {\n    defineIcons('far', icons);\n  });\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/js/solid.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function () {\n  'use strict';\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var PRODUCTION = function () {\n    try {\n      return \"production\" === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n\n  function bunker(fn) {\n    try {\n      fn();\n    } catch (e) {\n      if (!PRODUCTION) {\n        throw e;\n      }\n    }\n  }\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var icons = {\n    \"alarm-exclamation\": [512, 512, [], \"f843\", \"M96 0A96 96 0 0 0 0 96a94.81 94.81 0 0 0 15.3 51.26L161.2 25.68A95.63 95.63 0 0 0 96 0zm320 0a95.66 95.66 0 0 0-65.18 25.66l145.89 121.57A94.85 94.85 0 0 0 512 96a96 96 0 0 0-96-96zM256 64C132.3 64 32 164.29 32 288a222.7 222.7 0 0 0 44.79 134l-40.1 40.09a16 16 0 0 0 0 22.63l22.62 22.62a16 16 0 0 0 22.63 0L122 467.22a222.82 222.82 0 0 0 268 0l40.1 40.09a16 16 0 0 0 22.62 0l22.63-22.62a16 16 0 0 0 0-22.63L435.25 422A222.69 222.69 0 0 0 480 288c0-123.71-100.26-224-224-224zm0 352a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm25.4-110.4a16 16 0 0 1-15.9 14.4h-19a16 16 0 0 1-15.9-14.4l-12.8-128a16.06 16.06 0 0 1 15.9-17.6h44.6a16 16 0 0 1 15.9 17.6z\"],\n    \"align-left\": [448, 512, [], \"f036\", \"M12.83 352h262.34A12.82 12.82 0 0 0 288 339.17v-38.34A12.82 12.82 0 0 0 275.17 288H12.83A12.82 12.82 0 0 0 0 300.83v38.34A12.82 12.82 0 0 0 12.83 352zm0-256h262.34A12.82 12.82 0 0 0 288 83.17V44.83A12.82 12.82 0 0 0 275.17 32H12.83A12.82 12.82 0 0 0 0 44.83v38.34A12.82 12.82 0 0 0 12.83 96zM432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"],\n    \"book-dead\": [448, 512, [], \"f6b7\", \"M272 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm176 222.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM240 56c44.2 0 80 28.7 80 64 0 20.9-12.7 39.2-32 50.9V184c0 8.8-7.2 16-16 16h-64c-8.8 0-16-7.2-16-16v-13.1c-19.3-11.7-32-30-32-50.9 0-35.3 35.8-64 80-64zM124.8 223.3l6.3-14.7c1.7-4.1 6.4-5.9 10.5-4.2l98.3 42.1 98.4-42.1c4.1-1.7 8.8.1 10.5 4.2l6.3 14.7c1.7 4.1-.1 8.8-4.2 10.5L280.6 264l70.3 30.1c4.1 1.7 5.9 6.4 4.2 10.5l-6.3 14.7c-1.7 4.1-6.4 5.9-10.5 4.2L240 281.4l-98.3 42.2c-4.1 1.7-8.8-.1-10.5-4.2l-6.3-14.7c-1.7-4.1.1-8.8 4.2-10.5l70.4-30.1-70.5-30.3c-4.1-1.7-5.9-6.4-4.2-10.5zm256 224.7H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8zM208 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16z\"],\n    \"check\": [512, 512, [], \"f00c\", \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"],\n    \"circle\": [512, 512, [], \"f111\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"],\n    \"cloud\": [640, 512, [], \"f0c2\", \"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z\"],\n    \"credit-card\": [576, 512, [], \"f09d\", \"M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z\"],\n    \"desktop\": [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z\"],\n    \"envelope\": [512, 512, [], \"f0e0\", \"M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z\"],\n    \"eye\": [576, 512, [], \"f06e\", \"M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z\"],\n    \"fingerprint\": [512, 512, [], \"f577\", \"M256.12 245.96c-13.25 0-24 10.74-24 24 1.14 72.25-8.14 141.9-27.7 211.55-2.73 9.72 2.15 30.49 23.12 30.49 10.48 0 20.11-6.92 23.09-17.52 13.53-47.91 31.04-125.41 29.48-224.52.01-13.25-10.73-24-23.99-24zm-.86-81.73C194 164.16 151.25 211.3 152.1 265.32c.75 47.94-3.75 95.91-13.37 142.55-2.69 12.98 5.67 25.69 18.64 28.36 13.05 2.67 25.67-5.66 28.36-18.64 10.34-50.09 15.17-101.58 14.37-153.02-.41-25.95 19.92-52.49 54.45-52.34 31.31.47 57.15 25.34 57.62 55.47.77 48.05-2.81 96.33-10.61 143.55-2.17 13.06 6.69 25.42 19.76 27.58 19.97 3.33 26.81-15.1 27.58-19.77 8.28-50.03 12.06-101.21 11.27-152.11-.88-55.8-47.94-101.88-104.91-102.72zm-110.69-19.78c-10.3-8.34-25.37-6.8-33.76 3.48-25.62 31.5-39.39 71.28-38.75 112 .59 37.58-2.47 75.27-9.11 112.05-2.34 13.05 6.31 25.53 19.36 27.89 20.11 3.5 27.07-14.81 27.89-19.36 7.19-39.84 10.5-80.66 9.86-121.33-.47-29.88 9.2-57.88 28-80.97 8.35-10.28 6.79-25.39-3.49-33.76zm109.47-62.33c-15.41-.41-30.87 1.44-45.78 4.97-12.89 3.06-20.87 15.98-17.83 28.89 3.06 12.89 16 20.83 28.89 17.83 11.05-2.61 22.47-3.77 34-3.69 75.43 1.13 137.73 61.5 138.88 134.58.59 37.88-1.28 76.11-5.58 113.63-1.5 13.17 7.95 25.08 21.11 26.58 16.72 1.95 25.51-11.88 26.58-21.11a929.06 929.06 0 0 0 5.89-119.85c-1.56-98.75-85.07-180.33-186.16-181.83zm252.07 121.45c-2.86-12.92-15.51-21.2-28.61-18.27-12.94 2.86-21.12 15.66-18.26 28.61 4.71 21.41 4.91 37.41 4.7 61.6-.11 13.27 10.55 24.09 23.8 24.2h.2c13.17 0 23.89-10.61 24-23.8.18-22.18.4-44.11-5.83-72.34zm-40.12-90.72C417.29 43.46 337.6 1.29 252.81.02 183.02-.82 118.47 24.91 70.46 72.94 24.09 119.37-.9 181.04.14 246.65l-.12 21.47c-.39 13.25 10.03 24.31 23.28 24.69.23.02.48.02.72.02 12.92 0 23.59-10.3 23.97-23.3l.16-23.64c-.83-52.5 19.16-101.86 56.28-139 38.76-38.8 91.34-59.67 147.68-58.86 69.45 1.03 134.73 35.56 174.62 92.39 7.61 10.86 22.56 13.45 33.42 5.86 10.84-7.62 13.46-22.59 5.84-33.43z\"],\n    \"history\": [512, 512, [], \"f1da\", \"M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z\"],\n    \"home\": [576, 512, [], \"f015\", \"M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z\"],\n    \"plus\": [448, 512, [], \"f067\", \"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"],\n    \"robot\": [640, 512, [], \"f544\", \"M32,224H64V416H32A31.96166,31.96166,0,0,1,0,384V256A31.96166,31.96166,0,0,1,32,224Zm512-48V448a64.06328,64.06328,0,0,1-64,64H160a64.06328,64.06328,0,0,1-64-64V176a79.974,79.974,0,0,1,80-80H288V32a32,32,0,0,1,64,0V96H464A79.974,79.974,0,0,1,544,176ZM264,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,264,256Zm-8,128H192v32h64Zm96,0H288v32h64ZM456,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,456,256Zm-8,128H384v32h64ZM640,256V384a31.96166,31.96166,0,0,1-32,32H576V224h32A31.96166,31.96166,0,0,1,640,256Z\"],\n    \"rocket\": [512, 512, [], \"f135\", \"M505.12019,19.09375c-1.18945-5.53125-6.65819-11-12.207-12.1875C460.716,0,435.507,0,410.40747,0,307.17523,0,245.26909,55.20312,199.05238,128H94.83772c-16.34763.01562-35.55658,11.875-42.88664,26.48438L2.51562,253.29688A28.4,28.4,0,0,0,0,264a24.00867,24.00867,0,0,0,24.00582,24H127.81618l-22.47457,22.46875c-11.36521,11.36133-12.99607,32.25781,0,45.25L156.24582,406.625c11.15623,11.1875,32.15619,13.15625,45.27726,0l22.47457-22.46875V488a24.00867,24.00867,0,0,0,24.00581,24,28.55934,28.55934,0,0,0,10.707-2.51562l98.72834-49.39063c14.62888-7.29687,26.50776-26.5,26.50776-42.85937V312.79688c72.59753-46.3125,128.03493-108.40626,128.03493-211.09376C512.07526,76.5,512.07526,51.29688,505.12019,19.09375ZM384.04033,168A40,40,0,1,1,424.05,128,40.02322,40.02322,0,0,1,384.04033,168Z\"],\n    \"save\": [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"],\n    \"slash\": [640, 512, [], \"f715\", \"M594.53 508.63L6.18 53.9c-6.97-5.42-8.23-15.47-2.81-22.45L23.01 6.18C28.43-.8 38.49-2.06 45.47 3.37L633.82 458.1c6.97 5.42 8.23 15.47 2.81 22.45l-19.64 25.27c-5.42 6.98-15.48 8.23-22.46 2.81z\"],\n    \"spinner-third\": [512, 512, [], \"f3f4\", \"M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z\"],\n    \"square-full\": [512, 512, [], \"f45c\", \"M512 512H0V0h512v512z\"],\n    \"times\": [352, 512, [], \"f00d\", \"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\"],\n    \"times-circle\": [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"],\n    \"undo\": [512, 512, [], \"f0e2\", \"M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z\"],\n    \"undo-alt\": [512, 512, [], \"f2ea\", \"M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z\"],\n    \"user\": [448, 512, [], \"f007\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"],\n    \"users\": [640, 512, [], \"f0c0\", \"M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z\"]\n  };\n\n  bunker(function () {\n    defineIcons('fas', icons);\n  });\n\n}());\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_animated.less",
    "content": "// Animated Icons\n// --------------------------\n\n.@{fa-css-prefix}-spin {\n  animation: fa-spin 2s infinite linear;\n}\n\n.@{fa-css-prefix}-pulse {\n  animation: fa-spin 1s infinite steps(8);\n}\n\n@keyframes fa-spin {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(360deg);\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_bordered-pulled.less",
    "content": "// Bordered & Pulled\n// -------------------------\n\n.@{fa-css-prefix}-border {\n  border-radius: .1em;\n  border: solid .08em @fa-border-color;\n  padding: .2em .25em .15em;\n}\n\n.@{fa-css-prefix}-pull-left { float: left; }\n.@{fa-css-prefix}-pull-right { float: right; }\n\n.@{fa-css-prefix}, .fas, .far, .fal, .fab {\n  &.@{fa-css-prefix}-pull-left { margin-right: .3em; }\n  &.@{fa-css-prefix}-pull-right { margin-left: .3em; }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_core.less",
    "content": "// Base Class Definition\n// -------------------------\n\n.@{fa-css-prefix}, .fas, .far, .fal, .fad, .fab {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  text-rendering: auto;\n  line-height: 1;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_fixed-width.less",
    "content": "// Fixed Width Icons\n// -------------------------\n.@{fa-css-prefix}-fw {\n  text-align: center;\n  width: (20em / 16);\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_icons.less",
    "content": "/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n\n.@{fa-css-prefix}-abacus:before { content: @fa-var-abacus; }\n.@{fa-css-prefix}-alarm-exclamation:before { content: @fa-var-alarm-exclamation; }\n.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; }\n.@{fa-css-prefix}-align-slash:before { content: @fa-var-align-slash; }\n.@{fa-css-prefix}-atom-alt:before { content: @fa-var-atom-alt; }\n.@{fa-css-prefix}-aws:before { content: @fa-var-aws; }\n.@{fa-css-prefix}-badge-check:before { content: @fa-var-badge-check; }\n.@{fa-css-prefix}-bell:before { content: @fa-var-bell; }\n.@{fa-css-prefix}-book-dead:before { content: @fa-var-book-dead; }\n.@{fa-css-prefix}-books:before { content: @fa-var-books; }\n.@{fa-css-prefix}-brackets-curly:before { content: @fa-var-brackets-curly; }\n.@{fa-css-prefix}-cc-amazon-pay:before { content: @fa-var-cc-amazon-pay; }\n.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; }\n.@{fa-css-prefix}-cc-apple-pay:before { content: @fa-var-cc-apple-pay; }\n.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; }\n.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; }\n.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; }\n.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; }\n.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; }\n.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; }\n.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; }\n.@{fa-css-prefix}-chart-network:before { content: @fa-var-chart-network; }\n.@{fa-css-prefix}-chart-scatter:before { content: @fa-var-chart-scatter; }\n.@{fa-css-prefix}-check:before { content: @fa-var-check; }\n.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; }\n.@{fa-css-prefix}-circle:before { content: @fa-var-circle; }\n.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; }\n.@{fa-css-prefix}-clouds:before { content: @fa-var-clouds; }\n.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; }\n.@{fa-css-prefix}-comment-dots:before { content: @fa-var-comment-dots; }\n.@{fa-css-prefix}-concierge-bell:before { content: @fa-var-concierge-bell; }\n.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }\n.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; }\n.@{fa-css-prefix}-discourse:before { content: @fa-var-discourse; }\n.@{fa-css-prefix}-docker:before { content: @fa-var-docker; }\n.@{fa-css-prefix}-dot-circle:before { content: @fa-var-dot-circle; }\n.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; }\n.@{fa-css-prefix}-exchange-alt:before { content: @fa-var-exchange-alt; }\n.@{fa-css-prefix}-eye:before { content: @fa-var-eye; }\n.@{fa-css-prefix}-file-alt:before { content: @fa-var-file-alt; }\n.@{fa-css-prefix}-file-code:before { content: @fa-var-file-code; }\n.@{fa-css-prefix}-fingerprint:before { content: @fa-var-fingerprint; }\n.@{fa-css-prefix}-github:before { content: @fa-var-github; }\n.@{fa-css-prefix}-globe:before { content: @fa-var-globe; }\n.@{fa-css-prefix}-globe-africa:before { content: @fa-var-globe-africa; }\n.@{fa-css-prefix}-globe-americas:before { content: @fa-var-globe-americas; }\n.@{fa-css-prefix}-globe-asia:before { content: @fa-var-globe-asia; }\n.@{fa-css-prefix}-globe-europe:before { content: @fa-var-globe-europe; }\n.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; }\n.@{fa-css-prefix}-history:before { content: @fa-var-history; }\n.@{fa-css-prefix}-home:before { content: @fa-var-home; }\n.@{fa-css-prefix}-info:before { content: @fa-var-info; }\n.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; }\n.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; }\n.@{fa-css-prefix}-key:before { content: @fa-var-key; }\n.@{fa-css-prefix}-key-skeleton:before { content: @fa-var-key-skeleton; }\n.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; }\n.@{fa-css-prefix}-laptop-code:before { content: @fa-var-laptop-code; }\n.@{fa-css-prefix}-laptop-house:before { content: @fa-var-laptop-house; }\n.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }\n.@{fa-css-prefix}-lightbulb:before { content: @fa-var-lightbulb; }\n.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; }\n.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; }\n.@{fa-css-prefix}-lock-alt:before { content: @fa-var-lock-alt; }\n.@{fa-css-prefix}-map-marker-alt:before { content: @fa-var-map-marker-alt; }\n.@{fa-css-prefix}-microsoft:before { content: @fa-var-microsoft; }\n.@{fa-css-prefix}-moon-stars:before { content: @fa-var-moon-stars; }\n.@{fa-css-prefix}-network-wired:before { content: @fa-var-network-wired; }\n.@{fa-css-prefix}-planet-ringed:before { content: @fa-var-planet-ringed; }\n.@{fa-css-prefix}-plus:before { content: @fa-var-plus; }\n.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; }\n.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; }\n.@{fa-css-prefix}-random:before { content: @fa-var-random; }\n.@{fa-css-prefix}-rev:before { content: @fa-var-rev; }\n.@{fa-css-prefix}-robot:before { content: @fa-var-robot; }\n.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; }\n.@{fa-css-prefix}-save:before { content: @fa-var-save; }\n.@{fa-css-prefix}-search:before { content: @fa-var-search; }\n.@{fa-css-prefix}-server:before { content: @fa-var-server; }\n.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; }\n.@{fa-css-prefix}-siren-on:before { content: @fa-var-siren-on; }\n.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }\n.@{fa-css-prefix}-slash:before { content: @fa-var-slash; }\n.@{fa-css-prefix}-smile:before { content: @fa-var-smile; }\n.@{fa-css-prefix}-snowman:before { content: @fa-var-snowman; }\n.@{fa-css-prefix}-spinner-third:before { content: @fa-var-spinner-third; }\n.@{fa-css-prefix}-square-full:before { content: @fa-var-square-full; }\n.@{fa-css-prefix}-sun:before { content: @fa-var-sun; }\n.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; }\n.@{fa-css-prefix}-times:before { content: @fa-var-times; }\n.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; }\n.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }\n.@{fa-css-prefix}-undo:before { content: @fa-var-undo; }\n.@{fa-css-prefix}-undo-alt:before { content: @fa-var-undo-alt; }\n.@{fa-css-prefix}-university:before { content: @fa-var-university; }\n.@{fa-css-prefix}-user:before { content: @fa-var-user; }\n.@{fa-css-prefix}-user-friends:before { content: @fa-var-user-friends; }\n.@{fa-css-prefix}-user-hard-hat:before { content: @fa-var-user-hard-hat; }\n.@{fa-css-prefix}-user-shield:before { content: @fa-var-user-shield; }\n.@{fa-css-prefix}-users:before { content: @fa-var-users; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_larger.less",
    "content": "// Icon Sizes\n// -------------------------\n\n.larger(@factor) when (@factor > 0) {\n  .larger((@factor - 1));\n\n  .@{fa-css-prefix}-@{factor}x {\n    font-size: (@factor * 1em);\n  }\n}\n\n/* makes the font 33% larger relative to the icon container */\n.@{fa-css-prefix}-lg {\n  font-size: (4em / 3);\n  line-height: (3em / 4);\n  vertical-align: -.0667em;\n}\n\n.@{fa-css-prefix}-xs {\n  font-size: .75em;\n}\n\n.@{fa-css-prefix}-sm {\n  font-size: .875em;\n}\n\n.larger(10);\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_list.less",
    "content": "// List Icons\n// -------------------------\n\n.@{fa-css-prefix}-ul {\n  list-style-type: none;\n  margin-left: (@fa-li-width * 5/4);\n  padding-left: 0;\n\n  > li { position: relative; }\n}\n\n.@{fa-css-prefix}-li {\n  left: -@fa-li-width;\n  position: absolute;\n  text-align: center;\n  width: @fa-li-width;\n  line-height: inherit;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_mixins.less",
    "content": "// Mixins\n// --------------------------\n\n.fa-icon() {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  font-weight: normal;\n  line-height: 1;\n}\n\n.fa-icon-rotate(@degrees, @rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})\";\n  transform: rotate(@degrees);\n}\n\n.fa-icon-flip(@horiz, @vert, @rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)\";\n  transform: scale(@horiz, @vert);\n}\n\n\n// Only display content to screen readers. A la Bootstrap 4.\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only() {\n  border: 0;\n  clip: rect(0,0,0,0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable() {\n  &:active,\n  &:focus {\n    clip: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    position: static;\n    width: auto;\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_rotated-flipped.less",
    "content": "// Rotated & Flipped Icons\n// -------------------------\n\n.@{fa-css-prefix}-rotate-90  { .fa-icon-rotate(90deg, 1);  }\n.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }\n.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }\n\n.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }\n.@{fa-css-prefix}-flip-vertical   { .fa-icon-flip(1, -1, 2); }\n.@{fa-css-prefix}-flip-both, .@{fa-css-prefix}-flip-horizontal.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(-1, -1, 2); }\n\n// Hook for IE8-9\n// -------------------------\n\n:root {\n  .@{fa-css-prefix}-rotate-90,\n  .@{fa-css-prefix}-rotate-180,\n  .@{fa-css-prefix}-rotate-270,\n  .@{fa-css-prefix}-flip-horizontal,\n  .@{fa-css-prefix}-flip-vertical,\n  .@{fa-css-prefix}-flip-both {\n    filter: none;\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_screen-reader.less",
    "content": "// Screen Readers\n// -------------------------\n\n.sr-only { .sr-only(); }\n.sr-only-focusable { .sr-only-focusable(); }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_stacked.less",
    "content": "// Stacked Icons\n// -------------------------\n\n.@{fa-css-prefix}-stack {\n  display: inline-block;\n  height: 2em;\n  line-height: 2em;\n  position: relative;\n  vertical-align: middle;\n  width: 2em;\n}\n\n.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {\n  left: 0;\n  position: absolute;\n  text-align: center;\n  width: 100%;\n}\n\n.@{fa-css-prefix}-stack-1x { line-height: inherit; }\n.@{fa-css-prefix}-stack-2x { font-size: 2em; }\n.@{fa-css-prefix}-inverse { color: @fa-inverse; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/_variables.less",
    "content": "// Variables\n// --------------------------\n\n@fa-font-path:         \"../webfonts\";\n@fa-font-size-base:    16px;\n@fa-font-display:      block;\n@fa-line-height-base:  1;\n@fa-css-prefix:        fa;\n@fa-version:           \"5.15.4\";\n@fa-border-color:      #eee;\n@fa-inverse:           #fff;\n@fa-li-width:          2em;\n@fa-primary-opacity:   1;\n@fa-secondary-opacity: .4;\n\n@fa-var-abacus: \"\\f640\";\n@fa-var-alarm-exclamation: \"\\f843\";\n@fa-var-align-left: \"\\f036\";\n@fa-var-align-slash: \"\\f846\";\n@fa-var-atom-alt: \"\\f5d3\";\n@fa-var-aws: \"\\f375\";\n@fa-var-badge-check: \"\\f336\";\n@fa-var-bell: \"\\f0f3\";\n@fa-var-book-dead: \"\\f6b7\";\n@fa-var-books: \"\\f5db\";\n@fa-var-brackets-curly: \"\\f7ea\";\n@fa-var-cc-amazon-pay: \"\\f42d\";\n@fa-var-cc-amex: \"\\f1f3\";\n@fa-var-cc-apple-pay: \"\\f416\";\n@fa-var-cc-diners-club: \"\\f24c\";\n@fa-var-cc-discover: \"\\f1f2\";\n@fa-var-cc-jcb: \"\\f24b\";\n@fa-var-cc-mastercard: \"\\f1f1\";\n@fa-var-cc-paypal: \"\\f1f4\";\n@fa-var-cc-stripe: \"\\f1f5\";\n@fa-var-cc-visa: \"\\f1f0\";\n@fa-var-chart-network: \"\\f78a\";\n@fa-var-chart-scatter: \"\\f7ee\";\n@fa-var-check: \"\\f00c\";\n@fa-var-check-circle: \"\\f058\";\n@fa-var-circle: \"\\f111\";\n@fa-var-cloud: \"\\f0c2\";\n@fa-var-clouds: \"\\f744\";\n@fa-var-cogs: \"\\f085\";\n@fa-var-comment-dots: \"\\f4ad\";\n@fa-var-concierge-bell: \"\\f562\";\n@fa-var-credit-card: \"\\f09d\";\n@fa-var-desktop: \"\\f108\";\n@fa-var-discourse: \"\\f393\";\n@fa-var-docker: \"\\f395\";\n@fa-var-dot-circle: \"\\f192\";\n@fa-var-envelope: \"\\f0e0\";\n@fa-var-exchange-alt: \"\\f362\";\n@fa-var-eye: \"\\f06e\";\n@fa-var-file-alt: \"\\f15c\";\n@fa-var-file-code: \"\\f1c9\";\n@fa-var-fingerprint: \"\\f577\";\n@fa-var-github: \"\\f09b\";\n@fa-var-globe: \"\\f0ac\";\n@fa-var-globe-africa: \"\\f57c\";\n@fa-var-globe-americas: \"\\f57d\";\n@fa-var-globe-asia: \"\\f57e\";\n@fa-var-globe-europe: \"\\f7a2\";\n@fa-var-graduation-cap: \"\\f19d\";\n@fa-var-history: \"\\f1da\";\n@fa-var-home: \"\\f015\";\n@fa-var-info: \"\\f129\";\n@fa-var-info-circle: \"\\f05a\";\n@fa-var-instagram: \"\\f16d\";\n@fa-var-key: \"\\f084\";\n@fa-var-key-skeleton: \"\\f6f3\";\n@fa-var-laptop: \"\\f109\";\n@fa-var-laptop-code: \"\\f5fc\";\n@fa-var-laptop-house: \"\\e066\";\n@fa-var-life-ring: \"\\f1cd\";\n@fa-var-lightbulb: \"\\f0eb\";\n@fa-var-list-alt: \"\\f022\";\n@fa-var-list-ul: \"\\f0ca\";\n@fa-var-lock-alt: \"\\f30d\";\n@fa-var-map-marker-alt: \"\\f3c5\";\n@fa-var-microsoft: \"\\f3ca\";\n@fa-var-moon-stars: \"\\f755\";\n@fa-var-network-wired: \"\\f6ff\";\n@fa-var-planet-ringed: \"\\e020\";\n@fa-var-plus: \"\\f067\";\n@fa-var-question-circle: \"\\f059\";\n@fa-var-quote-left: \"\\f10d\";\n@fa-var-random: \"\\f074\";\n@fa-var-rev: \"\\f5b2\";\n@fa-var-robot: \"\\f544\";\n@fa-var-rocket: \"\\f135\";\n@fa-var-save: \"\\f0c7\";\n@fa-var-search: \"\\f002\";\n@fa-var-server: \"\\f233\";\n@fa-var-sign-out: \"\\f08b\";\n@fa-var-siren-on: \"\\e02e\";\n@fa-var-slack: \"\\f198\";\n@fa-var-slash: \"\\f715\";\n@fa-var-smile: \"\\f118\";\n@fa-var-snowman: \"\\f7d0\";\n@fa-var-spinner-third: \"\\f3f4\";\n@fa-var-square-full: \"\\f45c\";\n@fa-var-sun: \"\\f185\";\n@fa-var-tasks: \"\\f0ae\";\n@fa-var-times: \"\\f00d\";\n@fa-var-times-circle: \"\\f057\";\n@fa-var-twitter: \"\\f099\";\n@fa-var-undo: \"\\f0e2\";\n@fa-var-undo-alt: \"\\f2ea\";\n@fa-var-university: \"\\f19c\";\n@fa-var-user: \"\\f007\";\n@fa-var-user-friends: \"\\f500\";\n@fa-var-user-hard-hat: \"\\f82c\";\n@fa-var-user-shield: \"\\f505\";\n@fa-var-users: \"\\f0c0\";\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/brands.less",
    "content": "@import \"_variables.less\";\n\n@font-face {\n  font-family: 'Font Awesome 5 Brands';\n  font-style: normal;\n  font-weight: 400;\n  font-display: @fa-font-display;\n  src: url('@{fa-font-path}/fa-brands-400.eot');\n  src: url('@{fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'),\n    url('@{fa-font-path}/fa-brands-400.woff2') format('woff2'),\n    url('@{fa-font-path}/fa-brands-400.woff') format('woff'),\n    url('@{fa-font-path}/fa-brands-400.ttf') format('truetype'),\n    url('@{fa-font-path}/fa-brands-400.svg#fontawesome') format('svg');\n}\n\n.fab {\n  font-family: 'Font Awesome 5 Brands';\n  font-weight: 400;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/duotone.less",
    "content": "@import \"_variables.less\";\n\n@font-face {\n  font-family: 'Font Awesome 5 Duotone';\n  font-style: normal;\n  font-weight: 900;\n  font-display: @fa-font-display;\n  src: url('@{fa-font-path}/fa-duotone-900.eot');\n  src: url('@{fa-font-path}/fa-duotone-900.eot?#iefix') format('embedded-opentype'),\n    url('@{fa-font-path}/fa-duotone-900.woff2') format('woff2'),\n    url('@{fa-font-path}/fa-duotone-900.woff') format('woff'),\n    url('@{fa-font-path}/fa-duotone-900.ttf') format('truetype'),\n    url('@{fa-font-path}/fa-duotone-900.svg#fontawesome') format('svg');\n}\n\n.fad {\n  position: relative;\n  font-family: 'Font Awesome 5 Duotone';\n  font-weight: 900;\n}\n\n.fad:before {\n  position: absolute;\n  color: ~'var(--@{fa-css-prefix}-primary-color, inherit)';\n  opacity: @fa-primary-opacity;\n  opacity: ~'var(--@{fa-css-prefix}-primary-opacity, @{fa-primary-opacity})';\n}\n\n.fad:after {\n  color: ~'var(--@{fa-css-prefix}-secondary-color, inherit)';\n  opacity: @fa-secondary-opacity;\n  opacity: ~'var(--@{fa-css-prefix}-secondary-opacity, @{fa-secondary-opacity})';\n}\n\n.@{fa-css-prefix}-swap-opacity .fad:before,\n.fad.@{fa-css-prefix}-swap-opacity:before {\n  opacity: @fa-secondary-opacity;\n  opacity: ~'var(--@{fa-css-prefix}-secondary-opacity, @{fa-secondary-opacity})';\n}\n\n.@{fa-css-prefix}-swap-opacity .fad:after,\n.fad.@{fa-css-prefix}-swap-opacity:after {\n  opacity: @fa-primary-opacity;\n  opacity: ~'var(--@{fa-css-prefix}-primary-opacity, @{fa-primary-opacity})';\n}\n\n.fad.@{fa-css-prefix}-inverse {\n  color: @fa-inverse;\n}\n\n.fad.@{fa-css-prefix}-stack-1x, .fad.@{fa-css-prefix}-stack-2x {\n  position: absolute;\n}\n\n.fad.@{fa-css-prefix}-stack-1x:before,\n.fad.@{fa-css-prefix}-stack-2x:before,\n.fad.@{fa-css-prefix}-fw:before {\n  left: 50%;\n  transform: translateX(-50%);\n}\n\n.fad.@{fa-css-prefix}-abacus:after { content: \"\\10f640\"; }\n.fad.@{fa-css-prefix}-align-slash:after { content: \"\\10f846\"; }\n.fad.@{fa-css-prefix}-atom-alt:after { content: \"\\10f5d3\"; }\n.fad.@{fa-css-prefix}-badge-check:after { content: \"\\10f336\"; }\n.fad.@{fa-css-prefix}-bell:after { content: \"\\10f0f3\"; }\n.fad.@{fa-css-prefix}-books:after { content: \"\\10f5db\"; }\n.fad.@{fa-css-prefix}-brackets-curly:after { content: \"\\10f7ea\"; }\n.fad.@{fa-css-prefix}-chart-network:after { content: \"\\10f78a\"; }\n.fad.@{fa-css-prefix}-chart-scatter:after { content: \"\\10f7ee\"; }\n.fad.@{fa-css-prefix}-check:after { content: \"\\10f00c\"; }\n.fad.@{fa-css-prefix}-circle:after { content: \"\\10f111\"; }\n.fad.@{fa-css-prefix}-clouds:after { content: \"\\10f744\"; }\n.fad.@{fa-css-prefix}-cogs:after { content: \"\\10f085\"; }\n.fad.@{fa-css-prefix}-comment-dots:after { content: \"\\10f4ad\"; }\n.fad.@{fa-css-prefix}-concierge-bell:after { content: \"\\10f562\"; }\n.fad.@{fa-css-prefix}-dot-circle:after { content: \"\\10f192\"; }\n.fad.@{fa-css-prefix}-envelope:after { content: \"\\10f0e0\"; }\n.fad.@{fa-css-prefix}-exchange-alt:after { content: \"\\10f362\"; }\n.fad.@{fa-css-prefix}-file-alt:after { content: \"\\10f15c\"; }\n.fad.@{fa-css-prefix}-file-code:after { content: \"\\10f1c9\"; }\n.fad.@{fa-css-prefix}-globe:after { content: \"\\10f0ac\"; }\n.fad.@{fa-css-prefix}-globe-africa:after { content: \"\\10f57c\"; }\n.fad.@{fa-css-prefix}-globe-americas:after { content: \"\\10f57d\"; }\n.fad.@{fa-css-prefix}-globe-asia:after { content: \"\\10f57e\"; }\n.fad.@{fa-css-prefix}-globe-europe:after { content: \"\\10f7a2\"; }\n.fad.@{fa-css-prefix}-graduation-cap:after { content: \"\\10f19d\"; }\n.fad.@{fa-css-prefix}-history:after { content: \"\\10f1da\"; }\n.fad.@{fa-css-prefix}-key:after { content: \"\\10f084\"; }\n.fad.@{fa-css-prefix}-key-skeleton:after { content: \"\\10f6f3\"; }\n.fad.@{fa-css-prefix}-laptop:after { content: \"\\10f109\"; }\n.fad.@{fa-css-prefix}-laptop-code:after { content: \"\\10f5fc\"; }\n.fad.@{fa-css-prefix}-laptop-house:after { content: \"\\10e066\"; }\n.fad.@{fa-css-prefix}-life-ring:after { content: \"\\10f1cd\"; }\n.fad.@{fa-css-prefix}-lightbulb:after { content: \"\\10f0eb\"; }\n.fad.@{fa-css-prefix}-list-alt:after { content: \"\\10f022\"; }\n.fad.@{fa-css-prefix}-list-ul:after { content: \"\\10f0ca\"; }\n.fad.@{fa-css-prefix}-lock-alt:after { content: \"\\10f30d\"; }\n.fad.@{fa-css-prefix}-map-marker-alt:after { content: \"\\10f3c5\"; }\n.fad.@{fa-css-prefix}-moon-stars:after { content: \"\\10f755\"; }\n.fad.@{fa-css-prefix}-network-wired:after { content: \"\\10f6ff\"; }\n.fad.@{fa-css-prefix}-planet-ringed:after { content: \"\\10e020\"; }\n.fad.@{fa-css-prefix}-question-circle:after { content: \"\\10f059\"; }\n.fad.@{fa-css-prefix}-quote-left:after { content: \"\\10f10d\"; }\n.fad.@{fa-css-prefix}-random:after { content: \"\\10f074\"; }\n.fad.@{fa-css-prefix}-rocket:after { content: \"\\10f135\"; }\n.fad.@{fa-css-prefix}-search:after { content: \"\\10f002\"; }\n.fad.@{fa-css-prefix}-server:after { content: \"\\10f233\"; }\n.fad.@{fa-css-prefix}-sign-out:after { content: \"\\10f08b\"; }\n.fad.@{fa-css-prefix}-siren-on:after { content: \"\\10e02e\"; }\n.fad.@{fa-css-prefix}-smile:after { content: \"\\10f118\"; }\n.fad.@{fa-css-prefix}-snowman:after { content: \"\\10f7d0\"; }\n.fad.@{fa-css-prefix}-sun:after { content: \"\\10f185\"; }\n.fad.@{fa-css-prefix}-tasks:after { content: \"\\10f0ae\"; }\n.fad.@{fa-css-prefix}-university:after { content: \"\\10f19c\"; }\n.fad.@{fa-css-prefix}-user:after { content: \"\\10f007\"; }\n.fad.@{fa-css-prefix}-user-hard-hat:after { content: \"\\10f82c\"; }\n.fad.@{fa-css-prefix}-user-shield:after { content: \"\\10f505\"; }\n.fad.@{fa-css-prefix}-users:after { content: \"\\10f0c0\"; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/fontawesome.less",
    "content": "@import \"_variables.less\";\n@import \"_mixins.less\";\n@import \"_core.less\";\n@import \"_larger.less\";\n@import \"_fixed-width.less\";\n@import \"_list.less\";\n@import \"_bordered-pulled.less\";\n@import \"_animated.less\";\n@import \"_rotated-flipped.less\";\n@import \"_stacked.less\";\n@import \"_icons.less\";\n@import \"_screen-reader.less\";\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/regular.less",
    "content": "@import \"_variables.less\";\n\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 400;\n  font-display: @fa-font-display;\n  src: url('@{fa-font-path}/fa-regular-400.eot');\n  src: url('@{fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'),\n    url('@{fa-font-path}/fa-regular-400.woff2') format('woff2'),\n    url('@{fa-font-path}/fa-regular-400.woff') format('woff'),\n    url('@{fa-font-path}/fa-regular-400.ttf') format('truetype'),\n    url('@{fa-font-path}/fa-regular-400.svg#fontawesome') format('svg');\n}\n\n.far {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 400;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/less/solid.less",
    "content": "@import \"_variables.less\";\n\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 900;\n  font-display: @fa-font-display;\n  src: url('@{fa-font-path}/fa-solid-900.eot');\n  src: url('@{fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'),\n    url('@{fa-font-path}/fa-solid-900.woff2') format('woff2'),\n    url('@{fa-font-path}/fa-solid-900.woff') format('woff'),\n    url('@{fa-font-path}/fa-solid-900.ttf') format('truetype'),\n    url('@{fa-font-path}/fa-solid-900.svg#fontawesome') format('svg');\n}\n\n.fa,\n.fas {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 900;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/metadata/categories.yml",
    "content": "accessibility:\n  icons:\n    - question-circle\n  label: Accessibility\nalert:\n  icons:\n    - alarm-exclamation\n    - bell\n  label: Alert\nanimals:\n  icons: []\n  label: Animals\narrows:\n  icons:\n    - exchange-alt\n    - history\n    - random\n    - sign-out\n    - undo\n    - undo-alt\n  label: Arrows\naudio-video:\n  icons:\n    - circle\n    - random\n    - undo\n    - undo-alt\n  label: Audio & Video\nautomotive:\n  icons: []\n  label: Automotive\nautumn:\n  icons: []\n  label: Autumn\nbeverage:\n  icons: []\n  label: Beverage\nbuildings:\n  icons:\n    - home\n    - university\n  label: Buildings\nbusiness:\n  icons:\n    - badge-check\n    - chart-network\n    - chart-scatter\n    - envelope\n    - file-alt\n    - globe\n    - laptop-house\n    - save\n    - tasks\n  label: Business\ncamping:\n  icons: []\n  label: Camping\ncharity:\n  icons:\n    - globe\n  label: Charity\nchat:\n  icons:\n    - comment-dots\n    - quote-left\n    - smile\n  label: Chat\nchess:\n  icons:\n    - square-full\n  label: Chess\nchildhood:\n  icons:\n    - robot\n    - snowman\n  label: Childhood\nclothing:\n  icons:\n    - graduation-cap\n  label: Clothing\ncode:\n  icons:\n    - brackets-curly\n    - file-alt\n    - file-code\n    - laptop-code\n  label: Code\ncommunication:\n  icons:\n    - bell\n    - envelope\n  label: Communication\ncomputers:\n  icons:\n    - brackets-curly\n    - desktop\n    - laptop\n    - laptop-house\n    - save\n    - server\n  label: Computers\nconstruction:\n  icons:\n    - user-hard-hat\n  label: Construction\ncurrency:\n  icons: []\n  label: Currency\ndate-time:\n  icons:\n    - alarm-exclamation\n    - bell\n  label: Date & Time\ndesign:\n  icons:\n    - eye\n    - save\n  label: Design\neditors:\n  icons:\n    - align-left\n    - align-slash\n    - file-alt\n    - list-alt\n    - list-ul\n    - quote-left\n    - tasks\n    - undo\n    - undo-alt\n  label: Editors\neducation:\n  icons:\n    - atom-alt\n    - bell\n    - books\n    - graduation-cap\n    - laptop-code\n  label: Education\nemoji:\n  icons:\n    - smile\n  label: Emoji\nenergy:\n  icons:\n    - atom-alt\n    - lightbulb\n    - sun\n  label: Energy\nfiles:\n  icons:\n    - file-alt\n    - file-code\n    - save\n  label: Files\nfinance:\n  icons:\n    - credit-card\n  label: Finance\nfitness:\n  icons: []\n  label: Fitness\nfood:\n  icons: []\n  label: Food\nfruit-vegetable:\n  icons: []\n  label: Fruits & Vegetables\ngames:\n  icons: []\n  label: Games\ngaming-tabletop:\n  icons:\n    - book-dead\n  label: Tabletop Gaming\ngender:\n  icons: []\n  label: Genders\nhalloween:\n  icons:\n    - book-dead\n    - key-skeleton\n  label: Halloween\nhands:\n  icons: []\n  label: Hands\nhealth:\n  icons: []\n  label: Health\nholiday:\n  icons:\n    - snowman\n  label: Holiday\nhotel:\n  icons:\n    - concierge-bell\n    - key\n  label: Hotel\nhousehold:\n  icons:\n    - bell\n    - books\n    - laptop-house\n    - lightbulb\n    - siren-on\n  label: Household\nimages:\n  icons:\n    - eye\n  label: Images\ninterfaces:\n  icons:\n    - badge-check\n    - bell\n    - check\n    - check-circle\n    - circle\n    - cloud\n    - cogs\n    - dot-circle\n    - envelope\n    - eye\n    - file-alt\n    - fingerprint\n    - history\n    - home\n    - info\n    - info-circle\n    - plus\n    - question-circle\n    - quote-left\n    - save\n    - search\n    - sign-out\n    - smile\n    - times\n    - times-circle\n    - undo\n    - undo-alt\n    - user\n  label: Interfaces\nlogistics:\n  icons:\n    - user-hard-hat\n  label: Logistics\nmaps:\n  icons:\n    - bell\n    - eye\n    - globe\n    - graduation-cap\n    - home\n    - info\n    - info-circle\n    - key\n    - life-ring\n    - lightbulb\n    - map-marker-alt\n    - plus\n    - rocket\n    - search\n    - university\n  label: Maps\nmaritime:\n  icons: []\n  label: Maritime\nmarketing:\n  icons:\n    - badge-check\n    - lightbulb\n  label: Marketing\nmathematics:\n  icons:\n    - abacus\n    - plus\n    - times\n  label: Mathematics\nmedical:\n  icons:\n    - plus\n  label: Medical\nmoving:\n  icons: []\n  label: Moving\nmusic:\n  icons: []\n  label: Music\nobjects:\n  icons:\n    - bell\n    - book-dead\n    - cloud\n    - cogs\n    - envelope\n    - eye\n    - file-alt\n    - globe\n    - graduation-cap\n    - home\n    - key\n    - laptop\n    - life-ring\n    - lightbulb\n    - lock-alt\n    - map-marker-alt\n    - rocket\n    - save\n    - search\n    - sun\n    - university\n  label: Objects\npayments-shopping:\n  icons:\n    - badge-check\n    - bell\n    - cc-amazon-pay\n    - cc-amex\n    - cc-apple-pay\n    - cc-diners-club\n    - cc-discover\n    - cc-jcb\n    - cc-mastercard\n    - cc-paypal\n    - cc-stripe\n    - cc-visa\n    - credit-card\n    - key\n  label: Payments & Shopping\npharmacy:\n  icons:\n    - history\n  label: Pharmacy\npolitical:\n  icons: []\n  label: Political\nreligion:\n  icons: []\n  label: Religion\nscience:\n  icons:\n    - atom-alt\n    - chart-network\n    - chart-scatter\n    - key-skeleton\n  label: Science\nscience-fiction:\n  icons:\n    - atom-alt\n    - globe\n    - moon-stars\n    - planet-ringed\n    - robot\n    - rocket\n  label: Science Fiction\nsecurity:\n  icons:\n    - eye\n    - fingerprint\n    - key\n    - key-skeleton\n    - lock-alt\n    - siren-on\n    - user-shield\n  label: Security\nshapes:\n  icons:\n    - circle\n    - cloud\n  label: Shapes\nshopping:\n  icons:\n    - badge-check\n  label: Shopping\nsocial:\n  icons:\n    - bell\n    - envelope\n    - map-marker-alt\n    - user\n    - user-friends\n    - users\n  label: Social\nspinners:\n  icons:\n    - atom-alt\n    - life-ring\n    - slash\n    - spinner-third\n    - sun\n  label: Spinners\nsports:\n  icons: []\n  label: Sports\nspring:\n  icons: []\n  label: Spring\nstatus:\n  icons:\n    - badge-check\n    - bell\n    - eye\n    - file-alt\n    - info\n    - info-circle\n    - lightbulb\n    - lock-alt\n    - map-marker-alt\n    - plus\n    - question-circle\n    - sign-out\n    - user\n  label: Status\nsummer:\n  icons:\n    - sun\n  label: Summer\ntoggle:\n  icons:\n    - check-circle\n    - circle\n    - dot-circle\n  label: Toggle\ntravel:\n  icons:\n    - concierge-bell\n    - globe-africa\n    - globe-americas\n    - globe-asia\n    - globe-europe\n  label: Travel\nusers-people:\n  icons:\n    - smile\n    - user\n    - user-friends\n    - user-hard-hat\n    - user-shield\n    - users\n  label: Users & People\nvehicles:\n  icons:\n    - rocket\n  label: Vehicles\nweather:\n  icons:\n    - cloud\n    - clouds\n    - moon-stars\n    - sun\n  label: Weather\nwinter:\n  icons: []\n  label: Winter\nwriting:\n  icons:\n    - envelope\n    - file-alt\n    - quote-left\n  label: Writing\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/metadata/icons.yml",
    "content": "abacus:\n  changes:\n    - 5.3.0\n  label: Abacus\n  search:\n    terms:\n      - addition\n      - ancient\n      - arithmetic\n      - calculator\n      - counting\n      - hexadecimal\n      - math\n      - subtraction\n  styles:\n    - duotone\n  unicode: f640\n  voted: false\nalarm-exclamation:\n  changes:\n    - 5.9.0\n  label: Alarm Exclamation\n  search:\n    terms:\n      - alert\n      - date\n      - late\n      - reminder\n      - sleep\n      - snooze\n      - timer\n      - timestamp\n      - watch\n  styles:\n    - solid\n  unicode: f843\n  voted: false\nalign-left:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.9.0\n  label: align-left\n  search:\n    terms:\n      - format\n      - paragraph\n      - text\n  styles:\n    - solid\n  unicode: f036\n  voted: false\nalign-slash:\n  changes:\n    - 5.9.0\n  label: Align Slash\n  search:\n    terms:\n      - cancel\n      - format\n      - paragraph\n      - remove\n  styles:\n    - duotone\n  unicode: f846\n  voted: false\natom-alt:\n  changes:\n    - 5.2.0\n    - 5.12.0\n  label: Atom Alt\n  search:\n    terms:\n      - atheism\n      - chemistry\n      - electron\n      - ion\n      - isotope\n      - neutron\n      - nuclear\n      - proton\n      - science\n      - space\n  styles:\n    - duotone\n  unicode: f5d3\n  voted: false\naws:\n  changes:\n    - 5.0.0\n    - 5.1.0\n  label: Amazon Web Services (AWS)\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f375\n  voted: false\nbadge-check:\n  changes:\n    - 5.0.0\n  label: Check Badge\n  search:\n    terms:\n      - accept\n      - achievement\n      - agree\n      - award\n      - confirm\n      - correct\n      - done\n      - ok\n      - security\n      - select\n      - success\n      - verified\n      - verify\n      - winner\n      - 'yes'\n  styles:\n    - duotone\n  unicode: f336\n  voted: false\nbell:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.2.0\n    - 5.11.0\n  label: bell\n  search:\n    terms:\n      - alarm\n      - alert\n      - chime\n      - notification\n      - reminder\n  styles:\n    - duotone\n  unicode: f0f3\n  voted: false\nbook-dead:\n  changes:\n    - 5.4.0\n  label: Book of the Dead\n  search:\n    terms:\n      - Dungeons & Dragons\n      - crossbones\n      - d&d\n      - dark arts\n      - death\n      - dnd\n      - documentation\n      - evil\n      - fantasy\n      - halloween\n      - holiday\n      - necronomicon\n      - read\n      - skull\n      - spell\n  styles:\n    - solid\n  unicode: f6b7\n  voted: false\nbooks:\n  changes:\n    - 5.2.0\n    - 5.10.1\n  label: Books\n  search:\n    terms:\n      - diary\n      - documentation\n      - journal\n      - library\n      - read\n  styles:\n    - duotone\n  unicode: f5db\n  voted: false\nbrackets-curly:\n  changes:\n    - 5.7.0\n  label: Curly Brackets\n  search:\n    terms:\n      - code\n      - developer\n      - development\n      - parentheses\n  styles:\n    - duotone\n  unicode: f7ea\n  voted: true\ncc-amazon-pay:\n  changes:\n    - 5.0.2\n  label: Amazon Pay Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f42d\n  voted: false\ncc-amex:\n  changes:\n    - '4.2'\n    - 5.0.0\n    - 5.7.0\n  label: American Express Credit Card\n  search:\n    terms:\n      - amex\n  styles:\n    - brands\n  unicode: f1f3\n  voted: false\ncc-apple-pay:\n  changes:\n    - 5.0.0\n  label: Apple Pay Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f416\n  voted: false\ncc-diners-club:\n  changes:\n    - '4.4'\n    - 5.0.0\n  label: Diner's Club Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f24c\n  voted: false\ncc-discover:\n  changes:\n    - '4.2'\n    - 5.0.0\n  label: Discover Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f1f2\n  voted: false\ncc-jcb:\n  changes:\n    - '4.4'\n    - 5.0.0\n  label: JCB Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f24b\n  voted: false\ncc-mastercard:\n  changes:\n    - '4.2'\n    - 5.0.0\n  label: MasterCard Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f1f1\n  voted: false\ncc-paypal:\n  changes:\n    - '4.2'\n    - 5.0.0\n  label: Paypal Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f1f4\n  voted: false\ncc-stripe:\n  changes:\n    - '4.2'\n    - 5.0.0\n  label: Stripe Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f1f5\n  voted: false\ncc-visa:\n  changes:\n    - '4.2'\n    - 5.0.0\n  label: Visa Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f1f0\n  voted: false\nchart-network:\n  changes:\n    - 5.6.0\n  label: Network Chart\n  search:\n    terms:\n      - activity\n      - analytics\n      - association\n      - dashboard\n      - diagram\n      - distribution\n      - map\n      - network\n  styles:\n    - duotone\n  unicode: f78a\n  voted: true\nchart-scatter:\n  changes:\n    - 5.7.0\n  label: Scatter Chart\n  search:\n    terms:\n      - analytics\n      - chart\n      - diagram\n      - graph\n      - plot\n  styles:\n    - duotone\n  unicode: f7ee\n  voted: true\ncheck:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Check\n  search:\n    terms:\n      - accept\n      - agree\n      - checkmark\n      - confirm\n      - correct\n      - done\n      - notice\n      - notification\n      - notify\n      - ok\n      - select\n      - success\n      - tick\n      - todo\n      - 'yes'\n  styles:\n    - duotone\n    - solid\n  unicode: f00c\n  voted: false\ncheck-circle:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Check Circle\n  search:\n    terms:\n      - accept\n      - agree\n      - confirm\n      - correct\n      - done\n      - ok\n      - select\n      - success\n      - tick\n      - todo\n      - 'yes'\n  styles:\n    - regular\n  unicode: f058\n  voted: false\ncircle:\n  changes:\n    - '3'\n    - 5.0.0\n    - 5.10.1\n    - 5.10.2\n  label: Circle\n  search:\n    terms:\n      - circle-thin\n      - diameter\n      - dot\n      - ellipse\n      - notification\n      - round\n  styles:\n    - duotone\n    - solid\n  unicode: f111\n  voted: false\ncloud:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.0.11\n  label: Cloud\n  search:\n    terms:\n      - atmosphere\n      - fog\n      - overcast\n      - save\n      - upload\n      - weather\n  styles:\n    - solid\n  unicode: f0c2\n  voted: false\nclouds:\n  changes:\n    - 5.5.0\n  label: Clouds\n  search:\n    terms:\n      - cloudy\n      - fog\n      - haze\n      - overcast\n      - smoke\n      - storm\n      - weather\n  styles:\n    - duotone\n  unicode: f744\n  voted: false\ncogs:\n  changes:\n    - '1'\n    - 5.0.0\n  label: cogs\n  search:\n    terms:\n      - gears\n      - mechanical\n      - settings\n      - sprocket\n      - wheel\n  styles:\n    - duotone\n  unicode: f085\n  voted: false\ncomment-dots:\n  changes:\n    - 5.0.9\n  label: Comment Dots\n  search:\n    terms:\n      - bubble\n      - chat\n      - commenting\n      - conversation\n      - feedback\n      - message\n      - more\n      - note\n      - notification\n      - reply\n      - sms\n      - speech\n      - texting\n  styles:\n    - duotone\n  unicode: f4ad\n  voted: false\nconcierge-bell:\n  changes:\n    - 5.1.0\n  label: Concierge Bell\n  search:\n    terms:\n      - attention\n      - hotel\n      - receptionist\n      - service\n      - support\n  styles:\n    - duotone\n  unicode: f562\n  voted: false\ncredit-card:\n  changes:\n    - '2'\n    - 5.0.0\n  label: Credit Card\n  search:\n    terms:\n      - buy\n      - checkout\n      - credit-card-alt\n      - debit\n      - money\n      - payment\n      - purchase\n  styles:\n    - solid\n  unicode: f09d\n  voted: false\ndesktop:\n  changes:\n    - '3'\n    - 5.0.0\n  label: Desktop\n  search:\n    terms:\n      - computer\n      - cpu\n      - demo\n      - desktop\n      - device\n      - imac\n      - machine\n      - monitor\n      - pc\n      - screen\n  styles:\n    - solid\n    - regular\n  unicode: f108\n  voted: false\ndiscourse:\n  changes:\n    - 5.0.0\n    - 5.0.3\n  label: Discourse\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f393\n  voted: false\ndocker:\n  changes:\n    - 5.0.0\n  label: Docker\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f395\n  voted: false\ndot-circle:\n  changes:\n    - '4'\n    - 5.0.0\n  label: Dot Circle\n  search:\n    terms:\n      - bullseye\n      - notification\n      - target\n  styles:\n    - duotone\n  unicode: f192\n  voted: false\nenvelope:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.10.1\n    - 5.10.2\n  label: Envelope\n  search:\n    terms:\n      - e-mail\n      - email\n      - letter\n      - mail\n      - message\n      - notification\n      - support\n  styles:\n    - solid\n    - duotone\n  unicode: f0e0\n  voted: false\nexchange-alt:\n  changes:\n    - 5.0.0\n  label: Alternate Exchange\n  search:\n    terms:\n      - arrow\n      - arrows\n      - exchange\n      - reciprocate\n      - return\n      - swap\n      - transfer\n  styles:\n    - duotone\n  unicode: f362\n  voted: false\neye:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.7.0\n  label: Eye\n  search:\n    terms:\n      - look\n      - optic\n      - see\n      - seen\n      - show\n      - sight\n      - views\n      - visible\n  styles:\n    - solid\n    - regular\n  unicode: f06e\n  voted: false\nfile-alt:\n  changes:\n    - '3.2'\n    - 5.0.0\n    - 5.10.2\n  label: Alternate File\n  search:\n    terms:\n      - document\n      - file-text\n      - invoice\n      - new\n      - page\n      - pdf\n  styles:\n    - duotone\n  unicode: f15c\n  voted: false\nfile-code:\n  changes:\n    - '4.1'\n    - 5.0.0\n    - 5.10.2\n  label: Code File\n  search:\n    terms:\n      - css\n      - development\n      - document\n      - html\n  styles:\n    - duotone\n    - regular\n  unicode: f1c9\n  voted: false\nfingerprint:\n  changes:\n    - 5.1.0\n  label: Fingerprint\n  search:\n    terms:\n      - human\n      - id\n      - identification\n      - lock\n      - smudge\n      - touch\n      - unique\n      - unlock\n  styles:\n    - solid\n  unicode: f577\n  voted: true\ngithub:\n  changes:\n    - '2'\n    - 5.0.0\n  label: GitHub\n  search:\n    terms:\n      - octocat\n  styles:\n    - brands\n  unicode: f09b\n  voted: false\nglobe:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.0.9\n    - 5.11.0\n    - 5.11.1\n  label: Globe\n  search:\n    terms:\n      - all\n      - coordinates\n      - country\n      - earth\n      - global\n      - gps\n      - language\n      - localize\n      - location\n      - map\n      - online\n      - place\n      - planet\n      - translate\n      - travel\n      - world\n  styles:\n    - duotone\n  unicode: f0ac\n  voted: false\nglobe-africa:\n  changes:\n    - 5.1.0\n    - 5.11.0\n    - 5.11.1\n  label: Globe with Africa shown\n  search:\n    terms:\n      - all\n      - country\n      - earth\n      - global\n      - gps\n      - language\n      - localize\n      - location\n      - map\n      - online\n      - place\n      - planet\n      - translate\n      - travel\n      - world\n  styles:\n    - duotone\n  unicode: f57c\n  voted: false\nglobe-americas:\n  changes:\n    - 5.1.0\n    - 5.11.0\n    - 5.11.1\n  label: Globe with Americas shown\n  search:\n    terms:\n      - all\n      - country\n      - earth\n      - global\n      - gps\n      - language\n      - localize\n      - location\n      - map\n      - online\n      - place\n      - planet\n      - translate\n      - travel\n      - world\n  styles:\n    - duotone\n  unicode: f57d\n  voted: false\nglobe-asia:\n  changes:\n    - 5.1.0\n    - 5.11.0\n    - 5.11.1\n  label: Globe with Asia shown\n  search:\n    terms:\n      - all\n      - country\n      - earth\n      - global\n      - gps\n      - language\n      - localize\n      - location\n      - map\n      - online\n      - place\n      - planet\n      - translate\n      - travel\n      - world\n  styles:\n    - duotone\n  unicode: f57e\n  voted: false\nglobe-europe:\n  changes:\n    - 5.6.0\n    - 5.11.0\n    - 5.11.1\n  label: Globe with Europe shown\n  search:\n    terms:\n      - all\n      - country\n      - earth\n      - global\n      - gps\n      - language\n      - localize\n      - location\n      - map\n      - online\n      - place\n      - planet\n      - translate\n      - travel\n      - world\n  styles:\n    - duotone\n  unicode: f7a2\n  voted: true\ngraduation-cap:\n  changes:\n    - '4.1'\n    - 5.0.0\n    - 5.2.0\n    - 5.10.1\n  label: Graduation Cap\n  search:\n    terms:\n      - ceremony\n      - college\n      - graduate\n      - learning\n      - school\n      - student\n  styles:\n    - duotone\n  unicode: f19d\n  voted: false\nhistory:\n  changes:\n    - '4.1'\n    - 5.0.0\n  label: History\n  search:\n    terms:\n      - Rewind\n      - clock\n      - reverse\n      - time\n      - time machine\n  styles:\n    - solid\n    - duotone\n  unicode: f1da\n  voted: false\nhome:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.7.0\n  label: home\n  search:\n    terms:\n      - abode\n      - building\n      - house\n      - main\n  styles:\n    - solid\n  unicode: f015\n  voted: false\ninfo:\n  changes:\n    - '3.1'\n    - 5.0.0\n    - 5.10.1\n    - 5.10.2\n  label: Info\n  search:\n    terms:\n      - details\n      - help\n      - information\n      - more\n      - support\n  styles:\n    - regular\n  unicode: f129\n  voted: false\ninfo-circle:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Info Circle\n  search:\n    terms:\n      - details\n      - help\n      - information\n      - more\n      - support\n  styles:\n    - regular\n  unicode: f05a\n  voted: false\ninstagram:\n  changes:\n    - '4.6'\n    - 5.0.0\n  label: Instagram\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f16d\n  voted: false\nkey:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.10.1\n  label: key\n  search:\n    terms:\n      - lock\n      - password\n      - private\n      - secret\n      - unlock\n  styles:\n    - duotone\n  unicode: f084\n  voted: false\nkey-skeleton:\n  changes:\n    - 5.4.0\n  label: Key Skeleton\n  search:\n    terms:\n      - halloween\n      - lock\n      - password\n      - private\n      - secret\n      - unlock\n  styles:\n    - duotone\n  unicode: f6f3\n  voted: false\nlaptop:\n  changes:\n    - '3'\n    - 5.0.0\n    - 5.2.0\n  label: Laptop\n  search:\n    terms:\n      - computer\n      - cpu\n      - dell\n      - demo\n      - device\n      - mac\n      - macbook\n      - machine\n      - pc\n  styles:\n    - duotone\n  unicode: f109\n  voted: false\nlaptop-code:\n  changes:\n    - 5.2.0\n  label: Laptop Code\n  search:\n    terms:\n      - computer\n      - cpu\n      - dell\n      - demo\n      - develop\n      - device\n      - mac\n      - macbook\n      - machine\n      - pc\n  styles:\n    - duotone\n  unicode: f5fc\n  voted: false\nlaptop-house:\n  changes:\n    - 5.13.0\n    - 5.14.0\n  label: Laptop House\n  search:\n    terms:\n      - computer\n      - covid-19\n      - device\n      - office\n      - remote\n      - work from home\n  styles:\n    - duotone\n  unicode: e066\n  voted: false\nlife-ring:\n  changes:\n    - '4.1'\n    - 5.0.0\n  label: Life Ring\n  search:\n    terms:\n      - coast guard\n      - help\n      - overboard\n      - save\n      - support\n  styles:\n    - duotone\n  unicode: f1cd\n  voted: false\nlightbulb:\n  changes:\n    - '3'\n    - 5.0.0\n    - 5.3.0\n  label: Lightbulb\n  search:\n    terms:\n      - energy\n      - idea\n      - inspiration\n      - light\n  styles:\n    - duotone\n  unicode: f0eb\n  voted: false\nlist-alt:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Alternate List\n  search:\n    terms:\n      - checklist\n      - completed\n      - done\n      - finished\n      - ol\n      - todo\n      - ul\n  styles:\n    - duotone\n  unicode: f022\n  voted: false\nlist-ul:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.9.0\n  label: list-ul\n  search:\n    terms:\n      - checklist\n      - completed\n      - done\n      - finished\n      - ol\n      - todo\n      - ul\n  styles:\n    - duotone\n  unicode: f0ca\n  voted: false\nlock-alt:\n  changes:\n    - 5.0.0\n  label: Alternate Lock\n  search:\n    terms:\n      - admin\n      - lock\n      - open\n      - password\n      - private\n      - protect\n      - security\n  styles:\n    - duotone\n  unicode: f30d\n  voted: false\nmap-marker-alt:\n  changes:\n    - 5.0.0\n  label: Alternate Map Marker\n  search:\n    terms:\n      - address\n      - coordinates\n      - destination\n      - gps\n      - localize\n      - location\n      - map\n      - navigation\n      - paper\n      - pin\n      - place\n      - point of interest\n      - position\n      - route\n      - travel\n  styles:\n    - duotone\n  unicode: f3c5\n  voted: false\nmicrosoft:\n  changes:\n    - 5.0.0\n  label: Microsoft\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f3ca\n  voted: true\nmoon-stars:\n  changes:\n    - 5.5.0\n  label: Moon with Stars\n  search:\n    terms:\n      - clear\n      - crescent\n      - lunar\n      - space\n      - star\n  styles:\n    - duotone\n  unicode: f755\n  voted: false\nnetwork-wired:\n  changes:\n    - 5.4.0\n  label: Wired Network\n  search:\n    terms:\n      - computer\n      - connect\n      - ethernet\n      - internet\n      - intranet\n  styles:\n    - duotone\n  unicode: f6ff\n  voted: true\nplanet-ringed:\n  changes:\n    - 5.12.0\n    - 5.14.0\n  label: Ringed Planet\n  search:\n    terms:\n      - orbit\n      - saturn\n      - solar system\n      - space\n      - universe\n  styles:\n    - duotone\n  unicode: e020\n  voted: false\nplus:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.0.13\n  label: plus\n  search:\n    terms:\n      - add\n      - create\n      - expand\n      - new\n      - positive\n      - shape\n  styles:\n    - regular\n    - solid\n  unicode: f067\n  voted: false\nquestion-circle:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Question Circle\n  search:\n    terms:\n      - help\n      - information\n      - support\n      - unknown\n  styles:\n    - duotone\n    - regular\n  unicode: f059\n  voted: false\nquote-left:\n  changes:\n    - '3'\n    - 5.0.0\n    - 5.0.9\n  label: quote-left\n  search:\n    terms:\n      - mention\n      - note\n      - phrase\n      - text\n      - type\n  styles:\n    - duotone\n  unicode: f10d\n  voted: false\nrandom:\n  changes:\n    - '1'\n    - 5.0.0\n  label: random\n  search:\n    terms:\n      - arrows\n      - shuffle\n      - sort\n      - swap\n      - switch\n      - transfer\n  styles:\n    - duotone\n  unicode: f074\n  voted: false\nrev:\n  changes:\n    - 5.1.0\n    - 5.1.1\n    - 5.8.0\n  label: Rev.io\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f5b2\n  voted: false\nrobot:\n  changes:\n    - 5.0.13\n    - 5.12.0\n  label: Robot\n  search:\n    terms:\n      - android\n      - automate\n      - computer\n      - cyborg\n  styles:\n    - solid\n  unicode: f544\n  voted: true\nrocket:\n  changes:\n    - '3.1'\n    - 5.0.0\n    - 5.7.0\n    - 5.12.0\n  label: rocket\n  search:\n    terms:\n      - aircraft\n      - app\n      - jet\n      - launch\n      - nasa\n      - space\n  styles:\n    - duotone\n    - solid\n    - regular\n  unicode: f135\n  voted: false\nsave:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.10.2\n  label: Save\n  search:\n    terms:\n      - disk\n      - download\n      - floppy\n      - floppy-o\n  styles:\n    - solid\n    - regular\n  unicode: f0c7\n  voted: false\nsearch:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Search\n  search:\n    terms:\n      - bigger\n      - enlarge\n      - find\n      - magnify\n      - preview\n      - zoom\n  styles:\n    - duotone\n  unicode: f002\n  voted: false\nserver:\n  changes:\n    - '4.3'\n    - 5.0.0\n  label: Server\n  search:\n    terms:\n      - computer\n      - cpu\n      - database\n      - hardware\n      - network\n  styles:\n    - duotone\n  unicode: f233\n  voted: false\nsign-out:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Sign Out\n  search:\n    terms:\n      - arrow\n      - exit\n      - leave\n      - log out\n      - logout\n  styles:\n    - duotone\n  unicode: f08b\n  voted: false\nsiren-on:\n  changes:\n    - 5.12.0\n    - 5.14.0\n  label: Siren On\n  search:\n    terms:\n      - alarm\n      - alert\n      - ambulance\n      - loud\n      - police\n      - warning\n  styles:\n    - duotone\n  unicode: e02e\n  voted: false\nslack:\n  changes:\n    - '4.1'\n    - 5.0.0\n    - 5.7.0\n  label: Slack Logo\n  search:\n    terms:\n      - anchor\n      - hash\n      - hashtag\n  styles:\n    - brands\n  unicode: f198\n  voted: false\nslash:\n  changes:\n    - 5.4.0\n  label: Slash\n  search:\n    terms:\n      - cancel\n      - close\n      - mute\n      - 'off'\n      - stop\n      - x\n  styles:\n    - solid\n    - regular\n  unicode: f715\n  voted: true\nsmile:\n  changes:\n    - '3.1'\n    - 5.0.0\n    - 5.0.9\n    - 5.1.0\n    - 5.11.0\n    - 5.11.1\n  label: Smiling Face\n  search:\n    terms:\n      - approve\n      - emoticon\n      - face\n      - happy\n      - rating\n      - satisfied\n  styles:\n    - duotone\n  unicode: f118\n  voted: false\nsnowman:\n  changes:\n    - 5.6.0\n  label: Snowman\n  search:\n    terms:\n      - decoration\n      - frost\n      - frosty\n      - holiday\n  styles:\n    - duotone\n  unicode: f7d0\nspinner-third:\n  changes:\n    - 5.0.0\n    - 5.10.2\n  label: Spinner Third\n  search:\n    terms:\n      - circle\n      - loading\n      - progress\n  styles:\n    - solid\n  unicode: f3f4\n  voted: false\nsquare-full:\n  changes:\n    - 5.0.5\n    - 5.10.2\n  label: Square Full\n  search:\n    terms:\n      - block\n      - box\n      - shape\n  styles:\n    - solid\n  unicode: f45c\n  voted: false\nsun:\n  changes:\n    - '3.2'\n    - 5.0.0\n    - 5.5.0\n  label: Sun\n  search:\n    terms:\n      - brighten\n      - contrast\n      - day\n      - lighter\n      - sol\n      - solar\n      - star\n      - weather\n  styles:\n    - duotone\n  unicode: f185\n  voted: false\ntasks:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.9.0\n  label: Tasks\n  search:\n    terms:\n      - checklist\n      - downloading\n      - downloads\n      - loading\n      - progress\n      - project management\n      - settings\n      - to do\n  styles:\n    - duotone\n  unicode: f0ae\n  voted: false\ntimes:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.0.13\n    - 5.11.0\n    - 5.11.1\n  label: Times\n  search:\n    terms:\n      - close\n      - cross\n      - error\n      - exit\n      - incorrect\n      - notice\n      - notification\n      - notify\n      - problem\n      - wrong\n      - x\n  styles:\n    - solid\n    - regular\n  unicode: f00d\n  voted: false\ntimes-circle:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Times Circle\n  search:\n    terms:\n      - close\n      - cross\n      - exit\n      - incorrect\n      - notice\n      - notification\n      - notify\n      - problem\n      - wrong\n      - x\n  styles:\n    - solid\n  unicode: f057\n  voted: false\ntwitter:\n  changes:\n    - '2'\n    - 5.0.0\n  label: Twitter\n  search:\n    terms:\n      - social network\n      - tweet\n  styles:\n    - brands\n  unicode: f099\n  voted: false\nundo:\n  changes:\n    - '2'\n    - 5.0.0\n  label: Undo\n  search:\n    terms:\n      - back\n      - control z\n      - exchange\n      - oops\n      - return\n      - rotate\n      - swap\n  styles:\n    - solid\n    - regular\n  unicode: f0e2\n  voted: false\nundo-alt:\n  changes:\n    - 5.0.0\n  label: Alternate Undo\n  search:\n    terms:\n      - back\n      - control z\n      - exchange\n      - oops\n      - return\n      - swap\n  styles:\n    - regular\n    - solid\n  unicode: f2ea\n  voted: false\nuniversity:\n  changes:\n    - '4.1'\n    - 5.0.0\n    - 5.0.3\n    - 5.11.0\n    - 5.11.1\n  label: University\n  search:\n    terms:\n      - bank\n      - building\n      - college\n      - higher education - students\n      - institution\n  styles:\n    - duotone\n  unicode: f19c\n  voted: false\nuser:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.0.3\n    - 5.0.11\n  label: User\n  search:\n    terms:\n      - account\n      - avatar\n      - head\n      - human\n      - man\n      - person\n      - profile\n  styles:\n    - solid\n    - duotone\n    - regular\n  unicode: f007\n  voted: false\nuser-friends:\n  changes:\n    - 5.0.11\n  label: User Friends\n  search:\n    terms:\n      - group\n      - people\n      - person\n      - team\n      - users\n  styles:\n    - regular\n  unicode: f500\n  voted: false\nuser-hard-hat:\n  changes:\n    - 5.7.0\n  label: Construction Worker\n  search:\n    terms:\n      - construction\n      - hardhat\n      - helmet\n      - safety\n  styles:\n    - duotone\n  unicode: f82c\n  voted: false\nuser-shield:\n  changes:\n    - 5.0.11\n  label: User Shield\n  search:\n    terms:\n      - admin\n      - person\n      - private\n      - protect\n      - safe\n  styles:\n    - duotone\n  unicode: f505\n  voted: false\nusers:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.0.3\n    - 5.0.11\n  label: Users\n  search:\n    terms:\n      - friends\n      - group\n      - people\n      - persons\n      - profiles\n      - team\n  styles:\n    - duotone\n    - solid\n    - regular\n  unicode: f0c0\n  voted: false\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/metadata/sponsors.yml",
    "content": "amazon-web-services:\n  icons:\n    - aws\n  label: Amazon Web Services\n  url: 'https://aws.amazon.com'\ndiscourse:\n  icons:\n    - discourse\n  label: Discourse\n  url: 'https://discourse.org'\nharvard-medical-school:\n  icons:\n    - plus\n  label: Harvard Medical School\n  url: 'https://hms.harvard.edu'\nmylogin-info:\n  icons:\n    - user-shield\n  label: mylogin.info\n  url: 'https://www.mylogin.info'\nrev-io:\n  icons:\n    - rev\n  label: Rev.io\n  url: 'https://rev.io'\nrocket-chat:\n  icons:\n    - comment-dots\n    - quote-left\n    - smile\n  label: Rocket.Chat\n  url: 'https://rocket.chat'\nsupple:\n  icons:\n    - badge-check\n  label: Supple\n  url: 'https://supple.com.au'\nthe-us-sunnah-foundation:\n  icons:\n    - globe\n  label: The us-Sunnah Foundation\n  url: 'https://www.ussunnah.org'\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/package.json",
    "content": "{\n  \"description\": \"The iconic font, CSS, and SVG framework\",\n  \"keywords\": [\n    \"font\",\n    \"awesome\",\n    \"fontawesome\",\n    \"icon\",\n    \"svg\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://fontawesome.com\",\n  \"bugs\": {\n    \"url\": \"http://github.com/FortAwesome/Font-Awesome/issues\"\n  },\n  \"author\": {\n    \"name\": \"Dave Gandy\",\n    \"email\": \"dave@fontawesome.com\",\n    \"web\": \"http://twitter.com/davegandy\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Brian Talbot\",\n      \"web\": \"http://twitter.com/talbs\"\n    },\n    {\n      \"name\": \"Travis Chase\",\n      \"web\": \"http://twitter.com/supercodepoet\"\n    },\n    {\n      \"name\": \"Rob Madole\",\n      \"web\": \"http://twitter.com/robmadole\"\n    },\n    {\n      \"name\": \"Geremia Taglialatela\",\n      \"web\": \"http://twitter.com/gtagliala\"\n    },\n    {\n      \"name\": \"Mike Wilkerson\",\n      \"web\": \"http://twitter.com/mw77\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/FortAwesome/Font-Awesome\"\n  },\n  \"engines\": {\n    \"node\": \">=6\"\n  },\n  \"dependencies\": {},\n  \"version\": \"5.15.4\",\n  \"name\": \"@fortawesome/fontawesome-pro\",\n  \"main\": \"js/fontawesome.js\",\n  \"style\": \"css/fontawesome.css\",\n  \"license\": \"UNLICENSED\",\n  \"scripts\": {\n    \"postinstall\": \"node attribution.js\"\n  }\n}"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_animated.scss",
    "content": "// Animated Icons\n// --------------------------\n\n.#{$fa-css-prefix}-spin {\n  animation: fa-spin 2s infinite linear;\n}\n\n.#{$fa-css-prefix}-pulse {\n  animation: fa-spin 1s infinite steps(8);\n}\n\n@keyframes fa-spin {\n  0% {\n    transform: rotate(0deg);\n  }\n\n  100% {\n    transform: rotate(360deg);\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_bordered-pulled.scss",
    "content": "// Bordered & Pulled\n// -------------------------\n\n.#{$fa-css-prefix}-border {\n  border: solid .08em $fa-border-color;\n  border-radius: .1em;\n  padding: .2em .25em .15em;\n}\n\n.#{$fa-css-prefix}-pull-left { float: left; }\n.#{$fa-css-prefix}-pull-right { float: right; }\n\n.#{$fa-css-prefix},\n.fas,\n.far,\n.fal,\n.fab {\n  &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }\n  &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_core.scss",
    "content": "// Base Class Definition\n// -------------------------\n\n.#{$fa-css-prefix},\n.fas,\n.far,\n.fal,\n.fad,\n.fab {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  text-rendering: auto;\n  line-height: 1;\n}\n\n%fa-icon {\n  @include fa-icon;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_fixed-width.scss",
    "content": "// Fixed Width Icons\n// -------------------------\n.#{$fa-css-prefix}-fw {\n  text-align: center;\n  width: $fa-fw-width;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_icons.scss",
    "content": "/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\nreaders do not read off random characters that represent icons */\n\n.#{$fa-css-prefix}-abacus:before { content: fa-content($fa-var-abacus); }\n.#{$fa-css-prefix}-alarm-exclamation:before { content: fa-content($fa-var-alarm-exclamation); }\n.#{$fa-css-prefix}-align-left:before { content: fa-content($fa-var-align-left); }\n.#{$fa-css-prefix}-align-slash:before { content: fa-content($fa-var-align-slash); }\n.#{$fa-css-prefix}-atom-alt:before { content: fa-content($fa-var-atom-alt); }\n.#{$fa-css-prefix}-aws:before { content: fa-content($fa-var-aws); }\n.#{$fa-css-prefix}-badge-check:before { content: fa-content($fa-var-badge-check); }\n.#{$fa-css-prefix}-bell:before { content: fa-content($fa-var-bell); }\n.#{$fa-css-prefix}-book-dead:before { content: fa-content($fa-var-book-dead); }\n.#{$fa-css-prefix}-books:before { content: fa-content($fa-var-books); }\n.#{$fa-css-prefix}-brackets-curly:before { content: fa-content($fa-var-brackets-curly); }\n.#{$fa-css-prefix}-cc-amazon-pay:before { content: fa-content($fa-var-cc-amazon-pay); }\n.#{$fa-css-prefix}-cc-amex:before { content: fa-content($fa-var-cc-amex); }\n.#{$fa-css-prefix}-cc-apple-pay:before { content: fa-content($fa-var-cc-apple-pay); }\n.#{$fa-css-prefix}-cc-diners-club:before { content: fa-content($fa-var-cc-diners-club); }\n.#{$fa-css-prefix}-cc-discover:before { content: fa-content($fa-var-cc-discover); }\n.#{$fa-css-prefix}-cc-jcb:before { content: fa-content($fa-var-cc-jcb); }\n.#{$fa-css-prefix}-cc-mastercard:before { content: fa-content($fa-var-cc-mastercard); }\n.#{$fa-css-prefix}-cc-paypal:before { content: fa-content($fa-var-cc-paypal); }\n.#{$fa-css-prefix}-cc-stripe:before { content: fa-content($fa-var-cc-stripe); }\n.#{$fa-css-prefix}-cc-visa:before { content: fa-content($fa-var-cc-visa); }\n.#{$fa-css-prefix}-chart-network:before { content: fa-content($fa-var-chart-network); }\n.#{$fa-css-prefix}-chart-scatter:before { content: fa-content($fa-var-chart-scatter); }\n.#{$fa-css-prefix}-check:before { content: fa-content($fa-var-check); }\n.#{$fa-css-prefix}-check-circle:before { content: fa-content($fa-var-check-circle); }\n.#{$fa-css-prefix}-circle:before { content: fa-content($fa-var-circle); }\n.#{$fa-css-prefix}-cloud:before { content: fa-content($fa-var-cloud); }\n.#{$fa-css-prefix}-clouds:before { content: fa-content($fa-var-clouds); }\n.#{$fa-css-prefix}-cogs:before { content: fa-content($fa-var-cogs); }\n.#{$fa-css-prefix}-comment-dots:before { content: fa-content($fa-var-comment-dots); }\n.#{$fa-css-prefix}-concierge-bell:before { content: fa-content($fa-var-concierge-bell); }\n.#{$fa-css-prefix}-credit-card:before { content: fa-content($fa-var-credit-card); }\n.#{$fa-css-prefix}-desktop:before { content: fa-content($fa-var-desktop); }\n.#{$fa-css-prefix}-discourse:before { content: fa-content($fa-var-discourse); }\n.#{$fa-css-prefix}-docker:before { content: fa-content($fa-var-docker); }\n.#{$fa-css-prefix}-dot-circle:before { content: fa-content($fa-var-dot-circle); }\n.#{$fa-css-prefix}-envelope:before { content: fa-content($fa-var-envelope); }\n.#{$fa-css-prefix}-exchange-alt:before { content: fa-content($fa-var-exchange-alt); }\n.#{$fa-css-prefix}-eye:before { content: fa-content($fa-var-eye); }\n.#{$fa-css-prefix}-file-alt:before { content: fa-content($fa-var-file-alt); }\n.#{$fa-css-prefix}-file-code:before { content: fa-content($fa-var-file-code); }\n.#{$fa-css-prefix}-fingerprint:before { content: fa-content($fa-var-fingerprint); }\n.#{$fa-css-prefix}-github:before { content: fa-content($fa-var-github); }\n.#{$fa-css-prefix}-globe:before { content: fa-content($fa-var-globe); }\n.#{$fa-css-prefix}-globe-africa:before { content: fa-content($fa-var-globe-africa); }\n.#{$fa-css-prefix}-globe-americas:before { content: fa-content($fa-var-globe-americas); }\n.#{$fa-css-prefix}-globe-asia:before { content: fa-content($fa-var-globe-asia); }\n.#{$fa-css-prefix}-globe-europe:before { content: fa-content($fa-var-globe-europe); }\n.#{$fa-css-prefix}-graduation-cap:before { content: fa-content($fa-var-graduation-cap); }\n.#{$fa-css-prefix}-history:before { content: fa-content($fa-var-history); }\n.#{$fa-css-prefix}-home:before { content: fa-content($fa-var-home); }\n.#{$fa-css-prefix}-info:before { content: fa-content($fa-var-info); }\n.#{$fa-css-prefix}-info-circle:before { content: fa-content($fa-var-info-circle); }\n.#{$fa-css-prefix}-instagram:before { content: fa-content($fa-var-instagram); }\n.#{$fa-css-prefix}-key:before { content: fa-content($fa-var-key); }\n.#{$fa-css-prefix}-key-skeleton:before { content: fa-content($fa-var-key-skeleton); }\n.#{$fa-css-prefix}-laptop:before { content: fa-content($fa-var-laptop); }\n.#{$fa-css-prefix}-laptop-code:before { content: fa-content($fa-var-laptop-code); }\n.#{$fa-css-prefix}-laptop-house:before { content: fa-content($fa-var-laptop-house); }\n.#{$fa-css-prefix}-life-ring:before { content: fa-content($fa-var-life-ring); }\n.#{$fa-css-prefix}-lightbulb:before { content: fa-content($fa-var-lightbulb); }\n.#{$fa-css-prefix}-list-alt:before { content: fa-content($fa-var-list-alt); }\n.#{$fa-css-prefix}-list-ul:before { content: fa-content($fa-var-list-ul); }\n.#{$fa-css-prefix}-lock-alt:before { content: fa-content($fa-var-lock-alt); }\n.#{$fa-css-prefix}-map-marker-alt:before { content: fa-content($fa-var-map-marker-alt); }\n.#{$fa-css-prefix}-microsoft:before { content: fa-content($fa-var-microsoft); }\n.#{$fa-css-prefix}-moon-stars:before { content: fa-content($fa-var-moon-stars); }\n.#{$fa-css-prefix}-network-wired:before { content: fa-content($fa-var-network-wired); }\n.#{$fa-css-prefix}-planet-ringed:before { content: fa-content($fa-var-planet-ringed); }\n.#{$fa-css-prefix}-plus:before { content: fa-content($fa-var-plus); }\n.#{$fa-css-prefix}-question-circle:before { content: fa-content($fa-var-question-circle); }\n.#{$fa-css-prefix}-quote-left:before { content: fa-content($fa-var-quote-left); }\n.#{$fa-css-prefix}-random:before { content: fa-content($fa-var-random); }\n.#{$fa-css-prefix}-rev:before { content: fa-content($fa-var-rev); }\n.#{$fa-css-prefix}-robot:before { content: fa-content($fa-var-robot); }\n.#{$fa-css-prefix}-rocket:before { content: fa-content($fa-var-rocket); }\n.#{$fa-css-prefix}-save:before { content: fa-content($fa-var-save); }\n.#{$fa-css-prefix}-search:before { content: fa-content($fa-var-search); }\n.#{$fa-css-prefix}-server:before { content: fa-content($fa-var-server); }\n.#{$fa-css-prefix}-sign-out:before { content: fa-content($fa-var-sign-out); }\n.#{$fa-css-prefix}-siren-on:before { content: fa-content($fa-var-siren-on); }\n.#{$fa-css-prefix}-slack:before { content: fa-content($fa-var-slack); }\n.#{$fa-css-prefix}-slash:before { content: fa-content($fa-var-slash); }\n.#{$fa-css-prefix}-smile:before { content: fa-content($fa-var-smile); }\n.#{$fa-css-prefix}-snowman:before { content: fa-content($fa-var-snowman); }\n.#{$fa-css-prefix}-spinner-third:before { content: fa-content($fa-var-spinner-third); }\n.#{$fa-css-prefix}-square-full:before { content: fa-content($fa-var-square-full); }\n.#{$fa-css-prefix}-sun:before { content: fa-content($fa-var-sun); }\n.#{$fa-css-prefix}-tasks:before { content: fa-content($fa-var-tasks); }\n.#{$fa-css-prefix}-times:before { content: fa-content($fa-var-times); }\n.#{$fa-css-prefix}-times-circle:before { content: fa-content($fa-var-times-circle); }\n.#{$fa-css-prefix}-twitter:before { content: fa-content($fa-var-twitter); }\n.#{$fa-css-prefix}-undo:before { content: fa-content($fa-var-undo); }\n.#{$fa-css-prefix}-undo-alt:before { content: fa-content($fa-var-undo-alt); }\n.#{$fa-css-prefix}-university:before { content: fa-content($fa-var-university); }\n.#{$fa-css-prefix}-user:before { content: fa-content($fa-var-user); }\n.#{$fa-css-prefix}-user-friends:before { content: fa-content($fa-var-user-friends); }\n.#{$fa-css-prefix}-user-hard-hat:before { content: fa-content($fa-var-user-hard-hat); }\n.#{$fa-css-prefix}-user-shield:before { content: fa-content($fa-var-user-shield); }\n.#{$fa-css-prefix}-users:before { content: fa-content($fa-var-users); }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_larger.scss",
    "content": "// Icon Sizes\n// -------------------------\n\n// makes the font 33% larger relative to the icon container\n.#{$fa-css-prefix}-lg {\n  font-size: (4em / 3);\n  line-height: (3em / 4);\n  vertical-align: -.0667em;\n}\n\n.#{$fa-css-prefix}-xs {\n  font-size: .75em;\n}\n\n.#{$fa-css-prefix}-sm {\n  font-size: .875em;\n}\n\n@for $i from 1 through 10 {\n  .#{$fa-css-prefix}-#{$i}x {\n    font-size: $i * 1em;\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_list.scss",
    "content": "// List Icons\n// -------------------------\n\n.#{$fa-css-prefix}-ul {\n  list-style-type: none;\n  margin-left: $fa-li-width * 5/4;\n  padding-left: 0;\n\n  > li { position: relative; }\n}\n\n.#{$fa-css-prefix}-li {\n  left: -$fa-li-width;\n  position: absolute;\n  text-align: center;\n  width: $fa-li-width;\n  line-height: inherit;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_mixins.scss",
    "content": "// Mixins\n// --------------------------\n\n@mixin fa-icon {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  font-weight: normal;\n  line-height: 1;\n}\n\n@mixin fa-icon-rotate($degrees, $rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})\";\n  transform: rotate($degrees);\n}\n\n@mixin fa-icon-flip($horiz, $vert, $rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)\";\n  transform: scale($horiz, $vert);\n}\n\n\n// Only display content to screen readers. A la Bootstrap 4.\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n@mixin sr-only {\n  border: 0;\n  clip: rect(0, 0, 0, 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable {\n  &:active,\n  &:focus {\n    clip: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    position: static;\n    width: auto;\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_rotated-flipped.scss",
    "content": "// Rotated & Flipped Icons\n// -------------------------\n\n.#{$fa-css-prefix}-rotate-90  { @include fa-icon-rotate(90deg, 1);  }\n.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }\n.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }\n\n.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }\n.#{$fa-css-prefix}-flip-vertical   { @include fa-icon-flip(1, -1, 2); }\n.#{$fa-css-prefix}-flip-both, .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); }\n\n// Hook for IE8-9\n// -------------------------\n\n:root {\n  .#{$fa-css-prefix}-rotate-90,\n  .#{$fa-css-prefix}-rotate-180,\n  .#{$fa-css-prefix}-rotate-270,\n  .#{$fa-css-prefix}-flip-horizontal,\n  .#{$fa-css-prefix}-flip-vertical,\n  .#{$fa-css-prefix}-flip-both {\n    filter: none;\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_screen-reader.scss",
    "content": "// Screen Readers\n// -------------------------\n\n.sr-only { @include sr-only; }\n.sr-only-focusable { @include sr-only-focusable; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_stacked.scss",
    "content": "// Stacked Icons\n// -------------------------\n\n.#{$fa-css-prefix}-stack {\n  display: inline-block;\n  height: 2em;\n  line-height: 2em;\n  position: relative;\n  vertical-align: middle;\n  width: ($fa-fw-width*2);\n}\n\n.#{$fa-css-prefix}-stack-1x,\n.#{$fa-css-prefix}-stack-2x {\n  left: 0;\n  position: absolute;\n  text-align: center;\n  width: 100%;\n}\n\n.#{$fa-css-prefix}-stack-1x {\n  line-height: inherit;\n}\n\n.#{$fa-css-prefix}-stack-2x {\n  font-size: 2em;\n}\n\n.#{$fa-css-prefix}-inverse {\n  color: $fa-inverse;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/_variables.scss",
    "content": "// Variables\n// --------------------------\n\n$fa-font-path:         \"../webfonts\" !default;\n$fa-font-size-base:    16px !default;\n$fa-font-display:      block !default;\n$fa-css-prefix:        fa !default;\n$fa-version:           \"5.15.4\" !default;\n$fa-border-color:      #eee !default;\n$fa-inverse:           #fff !default;\n$fa-li-width:          2em !default;\n$fa-fw-width:          (20em / 16);\n$fa-primary-opacity:   1 !default;\n$fa-secondary-opacity: .4 !default;\n\n// Convenience function used to set content property\n@function fa-content($fa-var) {\n  @return unquote(\"\\\"#{ $fa-var }\\\"\");\n}\n\n$fa-var-abacus: \\f640;\n$fa-var-alarm-exclamation: \\f843;\n$fa-var-align-left: \\f036;\n$fa-var-align-slash: \\f846;\n$fa-var-atom-alt: \\f5d3;\n$fa-var-aws: \\f375;\n$fa-var-badge-check: \\f336;\n$fa-var-bell: \\f0f3;\n$fa-var-book-dead: \\f6b7;\n$fa-var-books: \\f5db;\n$fa-var-brackets-curly: \\f7ea;\n$fa-var-cc-amazon-pay: \\f42d;\n$fa-var-cc-amex: \\f1f3;\n$fa-var-cc-apple-pay: \\f416;\n$fa-var-cc-diners-club: \\f24c;\n$fa-var-cc-discover: \\f1f2;\n$fa-var-cc-jcb: \\f24b;\n$fa-var-cc-mastercard: \\f1f1;\n$fa-var-cc-paypal: \\f1f4;\n$fa-var-cc-stripe: \\f1f5;\n$fa-var-cc-visa: \\f1f0;\n$fa-var-chart-network: \\f78a;\n$fa-var-chart-scatter: \\f7ee;\n$fa-var-check: \\f00c;\n$fa-var-check-circle: \\f058;\n$fa-var-circle: \\f111;\n$fa-var-cloud: \\f0c2;\n$fa-var-clouds: \\f744;\n$fa-var-cogs: \\f085;\n$fa-var-comment-dots: \\f4ad;\n$fa-var-concierge-bell: \\f562;\n$fa-var-credit-card: \\f09d;\n$fa-var-desktop: \\f108;\n$fa-var-discourse: \\f393;\n$fa-var-docker: \\f395;\n$fa-var-dot-circle: \\f192;\n$fa-var-envelope: \\f0e0;\n$fa-var-exchange-alt: \\f362;\n$fa-var-eye: \\f06e;\n$fa-var-file-alt: \\f15c;\n$fa-var-file-code: \\f1c9;\n$fa-var-fingerprint: \\f577;\n$fa-var-github: \\f09b;\n$fa-var-globe: \\f0ac;\n$fa-var-globe-africa: \\f57c;\n$fa-var-globe-americas: \\f57d;\n$fa-var-globe-asia: \\f57e;\n$fa-var-globe-europe: \\f7a2;\n$fa-var-graduation-cap: \\f19d;\n$fa-var-history: \\f1da;\n$fa-var-home: \\f015;\n$fa-var-info: \\f129;\n$fa-var-info-circle: \\f05a;\n$fa-var-instagram: \\f16d;\n$fa-var-key: \\f084;\n$fa-var-key-skeleton: \\f6f3;\n$fa-var-laptop: \\f109;\n$fa-var-laptop-code: \\f5fc;\n$fa-var-laptop-house: \\e066;\n$fa-var-life-ring: \\f1cd;\n$fa-var-lightbulb: \\f0eb;\n$fa-var-list-alt: \\f022;\n$fa-var-list-ul: \\f0ca;\n$fa-var-lock-alt: \\f30d;\n$fa-var-map-marker-alt: \\f3c5;\n$fa-var-microsoft: \\f3ca;\n$fa-var-moon-stars: \\f755;\n$fa-var-network-wired: \\f6ff;\n$fa-var-planet-ringed: \\e020;\n$fa-var-plus: \\f067;\n$fa-var-question-circle: \\f059;\n$fa-var-quote-left: \\f10d;\n$fa-var-random: \\f074;\n$fa-var-rev: \\f5b2;\n$fa-var-robot: \\f544;\n$fa-var-rocket: \\f135;\n$fa-var-save: \\f0c7;\n$fa-var-search: \\f002;\n$fa-var-server: \\f233;\n$fa-var-sign-out: \\f08b;\n$fa-var-siren-on: \\e02e;\n$fa-var-slack: \\f198;\n$fa-var-slash: \\f715;\n$fa-var-smile: \\f118;\n$fa-var-snowman: \\f7d0;\n$fa-var-spinner-third: \\f3f4;\n$fa-var-square-full: \\f45c;\n$fa-var-sun: \\f185;\n$fa-var-tasks: \\f0ae;\n$fa-var-times: \\f00d;\n$fa-var-times-circle: \\f057;\n$fa-var-twitter: \\f099;\n$fa-var-undo: \\f0e2;\n$fa-var-undo-alt: \\f2ea;\n$fa-var-university: \\f19c;\n$fa-var-user: \\f007;\n$fa-var-user-friends: \\f500;\n$fa-var-user-hard-hat: \\f82c;\n$fa-var-user-shield: \\f505;\n$fa-var-users: \\f0c0;\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/brands.scss",
    "content": "@import 'variables';\n\n@font-face {\n  font-family: 'Font Awesome 5 Brands';\n  font-style: normal;\n  font-weight: 400;\n  font-display: $fa-font-display;\n  src: url('#{$fa-font-path}/fa-brands-400.eot');\n  src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'),\n  url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'),\n  url('#{$fa-font-path}/fa-brands-400.woff') format('woff'),\n  url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'),\n  url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg');\n}\n\n.fab {\n  font-family: 'Font Awesome 5 Brands';\n  font-weight: 400;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/duotone.scss",
    "content": "@import 'variables';\n\n@font-face {\n  font-family: 'Font Awesome 5 Duotone';\n  font-style: normal;\n  font-weight: 900;\n  font-display: $fa-font-display;\n  src: url('#{$fa-font-path}/fa-duotone-900.eot');\n  src: url('#{$fa-font-path}/fa-duotone-900.eot?#iefix') format('embedded-opentype'),\n  url('#{$fa-font-path}/fa-duotone-900.woff2') format('woff2'),\n  url('#{$fa-font-path}/fa-duotone-900.woff') format('woff'),\n  url('#{$fa-font-path}/fa-duotone-900.ttf') format('truetype'),\n  url('#{$fa-font-path}/fa-duotone-900.svg#fontawesome') format('svg');\n}\n\n.fad {\n  position: relative;\n  font-family: 'Font Awesome 5 Duotone';\n  font-weight: 900;\n}\n\n.fad:before {\n  position: absolute;\n  color: var(--#{$fa-css-prefix}-primary-color, inherit);\n  opacity: $fa-primary-opacity;\n  opacity: var(--#{$fa-css-prefix}-primary-opacity, #{$fa-primary-opacity});\n}\n\n.fad:after {\n  color: var(--#{$fa-css-prefix}-secondary-color, inherit);\n  opacity: $fa-secondary-opacity;\n  opacity: var(--#{$fa-css-prefix}-secondary-opacity, #{$fa-secondary-opacity});\n}\n\n.#{$fa-css-prefix}-swap-opacity .fad:before,\n.fad.#{$fa-css-prefix}-swap-opacity:before {\n  opacity: $fa-secondary-opacity;\n  opacity: var(--#{$fa-css-prefix}-secondary-opacity, #{$fa-secondary-opacity});\n}\n\n.#{$fa-css-prefix}-swap-opacity .fad:after,\n.fad.#{$fa-css-prefix}-swap-opacity:after {\n  opacity: $fa-primary-opacity;\n  opacity: var(--#{$fa-css-prefix}-primary-opacity, #{$fa-primary-opacity});\n}\n\n.fad.#{$fa-css-prefix}-inverse {\n  color: $fa-inverse;\n}\n\n.fad.#{$fa-css-prefix}-stack-1x, .fad.#{$fa-css-prefix}-stack-2x {\n  position: absolute;\n}\n\n.fad.#{$fa-css-prefix}-stack-1x:before,\n.fad.#{$fa-css-prefix}-stack-2x:before,\n.fad.#{$fa-css-prefix}-fw:before {\n  left: 50%;\n  transform: translateX(-50%);\n}\n\n.fad.#{$fa-css-prefix}-abacus:after { content: fa-content(\\10f640); }\n.fad.#{$fa-css-prefix}-align-slash:after { content: fa-content(\\10f846); }\n.fad.#{$fa-css-prefix}-atom-alt:after { content: fa-content(\\10f5d3); }\n.fad.#{$fa-css-prefix}-badge-check:after { content: fa-content(\\10f336); }\n.fad.#{$fa-css-prefix}-bell:after { content: fa-content(\\10f0f3); }\n.fad.#{$fa-css-prefix}-books:after { content: fa-content(\\10f5db); }\n.fad.#{$fa-css-prefix}-brackets-curly:after { content: fa-content(\\10f7ea); }\n.fad.#{$fa-css-prefix}-chart-network:after { content: fa-content(\\10f78a); }\n.fad.#{$fa-css-prefix}-chart-scatter:after { content: fa-content(\\10f7ee); }\n.fad.#{$fa-css-prefix}-check:after { content: fa-content(\\10f00c); }\n.fad.#{$fa-css-prefix}-circle:after { content: fa-content(\\10f111); }\n.fad.#{$fa-css-prefix}-clouds:after { content: fa-content(\\10f744); }\n.fad.#{$fa-css-prefix}-cogs:after { content: fa-content(\\10f085); }\n.fad.#{$fa-css-prefix}-comment-dots:after { content: fa-content(\\10f4ad); }\n.fad.#{$fa-css-prefix}-concierge-bell:after { content: fa-content(\\10f562); }\n.fad.#{$fa-css-prefix}-dot-circle:after { content: fa-content(\\10f192); }\n.fad.#{$fa-css-prefix}-envelope:after { content: fa-content(\\10f0e0); }\n.fad.#{$fa-css-prefix}-exchange-alt:after { content: fa-content(\\10f362); }\n.fad.#{$fa-css-prefix}-file-alt:after { content: fa-content(\\10f15c); }\n.fad.#{$fa-css-prefix}-file-code:after { content: fa-content(\\10f1c9); }\n.fad.#{$fa-css-prefix}-globe:after { content: fa-content(\\10f0ac); }\n.fad.#{$fa-css-prefix}-globe-africa:after { content: fa-content(\\10f57c); }\n.fad.#{$fa-css-prefix}-globe-americas:after { content: fa-content(\\10f57d); }\n.fad.#{$fa-css-prefix}-globe-asia:after { content: fa-content(\\10f57e); }\n.fad.#{$fa-css-prefix}-globe-europe:after { content: fa-content(\\10f7a2); }\n.fad.#{$fa-css-prefix}-graduation-cap:after { content: fa-content(\\10f19d); }\n.fad.#{$fa-css-prefix}-history:after { content: fa-content(\\10f1da); }\n.fad.#{$fa-css-prefix}-key:after { content: fa-content(\\10f084); }\n.fad.#{$fa-css-prefix}-key-skeleton:after { content: fa-content(\\10f6f3); }\n.fad.#{$fa-css-prefix}-laptop:after { content: fa-content(\\10f109); }\n.fad.#{$fa-css-prefix}-laptop-code:after { content: fa-content(\\10f5fc); }\n.fad.#{$fa-css-prefix}-laptop-house:after { content: fa-content(\\10e066); }\n.fad.#{$fa-css-prefix}-life-ring:after { content: fa-content(\\10f1cd); }\n.fad.#{$fa-css-prefix}-lightbulb:after { content: fa-content(\\10f0eb); }\n.fad.#{$fa-css-prefix}-list-alt:after { content: fa-content(\\10f022); }\n.fad.#{$fa-css-prefix}-list-ul:after { content: fa-content(\\10f0ca); }\n.fad.#{$fa-css-prefix}-lock-alt:after { content: fa-content(\\10f30d); }\n.fad.#{$fa-css-prefix}-map-marker-alt:after { content: fa-content(\\10f3c5); }\n.fad.#{$fa-css-prefix}-moon-stars:after { content: fa-content(\\10f755); }\n.fad.#{$fa-css-prefix}-network-wired:after { content: fa-content(\\10f6ff); }\n.fad.#{$fa-css-prefix}-planet-ringed:after { content: fa-content(\\10e020); }\n.fad.#{$fa-css-prefix}-question-circle:after { content: fa-content(\\10f059); }\n.fad.#{$fa-css-prefix}-quote-left:after { content: fa-content(\\10f10d); }\n.fad.#{$fa-css-prefix}-random:after { content: fa-content(\\10f074); }\n.fad.#{$fa-css-prefix}-rocket:after { content: fa-content(\\10f135); }\n.fad.#{$fa-css-prefix}-search:after { content: fa-content(\\10f002); }\n.fad.#{$fa-css-prefix}-server:after { content: fa-content(\\10f233); }\n.fad.#{$fa-css-prefix}-sign-out:after { content: fa-content(\\10f08b); }\n.fad.#{$fa-css-prefix}-siren-on:after { content: fa-content(\\10e02e); }\n.fad.#{$fa-css-prefix}-smile:after { content: fa-content(\\10f118); }\n.fad.#{$fa-css-prefix}-snowman:after { content: fa-content(\\10f7d0); }\n.fad.#{$fa-css-prefix}-sun:after { content: fa-content(\\10f185); }\n.fad.#{$fa-css-prefix}-tasks:after { content: fa-content(\\10f0ae); }\n.fad.#{$fa-css-prefix}-university:after { content: fa-content(\\10f19c); }\n.fad.#{$fa-css-prefix}-user:after { content: fa-content(\\10f007); }\n.fad.#{$fa-css-prefix}-user-hard-hat:after { content: fa-content(\\10f82c); }\n.fad.#{$fa-css-prefix}-user-shield:after { content: fa-content(\\10f505); }\n.fad.#{$fa-css-prefix}-users:after { content: fa-content(\\10f0c0); }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/fontawesome.scss",
    "content": "@import 'variables';\n@import 'mixins';\n@import 'core';\n@import 'larger';\n@import 'fixed-width';\n@import 'list';\n@import 'bordered-pulled';\n@import 'animated';\n@import 'rotated-flipped';\n@import 'stacked';\n@import 'icons';\n@import 'screen-reader';\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/regular.scss",
    "content": "@import 'variables';\n\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 400;\n  font-display: $fa-font-display;\n  src: url('#{$fa-font-path}/fa-regular-400.eot');\n  src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'),\n  url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'),\n  url('#{$fa-font-path}/fa-regular-400.woff') format('woff'),\n  url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'),\n  url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg');\n}\n\n.far {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 400;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-pro/scss/solid.scss",
    "content": "@import 'variables';\n\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 900;\n  font-display: $fa-font-display;\n  src: url('#{$fa-font-path}/fa-solid-900.eot');\n  src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'),\n  url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'),\n  url('#{$fa-font-path}/fa-solid-900.woff') format('woff'),\n  url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'),\n  url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg');\n}\n\n.fa,\n.fas {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 900;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-svg-core/LICENSE.txt",
    "content": "Font Awesome Free License\n-------------------------\n\nFont Awesome Free is free, open source, and GPL friendly. You can use it for\ncommercial projects, open source projects, or really almost whatever you want.\nFull Font Awesome Free license: https://fontawesome.com/license/free.\n\n# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/)\nIn the Font Awesome Free download, the CC BY 4.0 license applies to all icons\npackaged as SVG and JS file types.\n\n# Fonts: SIL OFL 1.1 License (https://scripts.sil.org/OFL)\nIn the Font Awesome Free download, the SIL OFL license applies to all icons\npackaged as web and desktop font files.\n\n# Code: MIT License (https://opensource.org/licenses/MIT)\nIn the Font Awesome Free download, the MIT license applies to all non-font and\nnon-icon files.\n\n# Attribution\nAttribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font\nAwesome Free files already contain embedded comments with sufficient\nattribution, so you shouldn't need to do anything additional when using these\nfiles normally.\n\nWe've kept attribution comments terse, so we ask that you do not actively work\nto remove them from files, especially code. They're a great way for folks to\nlearn about Font Awesome.\n\n# Brand Icons\nAll brand icons are trademarks of their respective owners. The use of these\ntrademarks does not indicate endorsement of the trademark holder by Font\nAwesome, nor vice versa. **Please do not use brand logos for any purpose except\nto represent the company, product, or service to which they refer.**\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-svg-core/README.md",
    "content": "# @fortawesome/fontawesome-svg-core - SVG with JavaScript version\n\n> \"I came here to chew bubblegum and install Font Awesome 5 - and I'm all out of bubblegum\"\n\n[![npm](https://img.shields.io/npm/v/@fortawesome/fontawesome-svg-core.svg?style=flat-square)](https://www.npmjs.com/package/@fortawesome/fontawesome-svg-core)\n\n## Installation\n\n```\n$ npm i --save @fortawesome/fontawesome-svg-core\n```\n\nOr\n\n```\n$ yarn add @fortawesome/fontawesome-svg-core\n```\n\n## Documentation\n\nGet started [here](https://fontawesome.com/how-to-use/on-the-web/setup/getting-started). Continue your journey [here](https://fontawesome.com/how-to-use/on-the-web/advanced).\n\nOr go straight to the [API documentation](https://fontawesome.com/how-to-use/with-the-api).\n\n## Issues and support\n\nStart with [GitHub issues](https://github.com/FortAwesome/Font-Awesome/issues) and ping us on [Twitter](https://twitter.com/fontawesome) if you need to.\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-svg-core/attribution.js",
    "content": "console.log(`Font Awesome Free 1.2.36 by @fontawesome - https://fontawesome.com\nLicense - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)\n`)"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-svg-core/index.d.ts",
    "content": "import {IconDefinition, IconLookup, IconName, IconPrefix, IconPathData, IconPack } from '@fortawesome/fontawesome-common-types';\nexport {IconDefinition, IconLookup, IconName, IconPrefix, IconPathData, IconPack } from '@fortawesome/fontawesome-common-types';\nexport const dom: DOM;\nexport const library: Library;\nexport const parse: { transform(transformString: string): Transform };\nexport const config: Config;\nexport function noAuto():void;\nexport function findIconDefinition(iconLookup: IconLookup): IconDefinition;\nexport function text(content: string, params?: TextParams): Text;\nexport function counter(content: string | number, params?: CounterParams): Counter;\nexport function toHtml(content: any): string;\nexport function toHtml(abstractNodes: AbstractElement): string;\nexport function layer(\n  assembler: (\n    addLayerCallback: (layerToAdd: IconOrText | IconOrText[]) => void\n  ) => void,\n  params?: LayerParams\n): Layer;\nexport function icon(icon: IconName | IconLookup, params?: IconParams): Icon;\nexport type IconProp = IconName | [IconPrefix, IconName] | IconLookup;\nexport type FlipProp = \"horizontal\" | \"vertical\" | \"both\";\nexport type SizeProp =\n  | \"xs\"\n  | \"lg\"\n  | \"sm\"\n  | \"1x\"\n  | \"2x\"\n  | \"3x\"\n  | \"4x\"\n  | \"5x\"\n  | \"6x\"\n  | \"7x\"\n  | \"8x\"\n  | \"9x\"\n  | \"10x\";\nexport type PullProp = \"left\" | \"right\";\nexport type RotateProp = 90 | 180 | 270;\nexport type FaSymbol = string | boolean;\nexport interface Config {\n  familyPrefix: IconPrefix;\n  replacementClass: string;\n  autoReplaceSvg: boolean | 'nest';\n  autoAddCss: boolean;\n  autoA11y: boolean;\n  searchPseudoElements: boolean;\n  observeMutations: boolean;\n  keepOriginalSource: boolean;\n  measurePerformance: boolean;\n  showMissingIcons: boolean;\n}\nexport interface AbstractElement {\n  tag: string;\n  attributes: any;\n  children?: AbstractElement[];\n}\nexport interface FontawesomeObject {\n  readonly abstract: AbstractElement[];\n  readonly html: string[];\n  readonly node: HTMLCollection;\n}\nexport interface Icon extends FontawesomeObject, IconDefinition {\n  readonly type: \"icon\";\n}\nexport interface Text extends FontawesomeObject {\n  readonly type: \"text\";\n}\nexport interface Counter extends FontawesomeObject {\n  readonly type: \"counter\";\n}\nexport interface Layer extends FontawesomeObject {\n  readonly type: \"layer\";\n}\ntype IconOrText = Icon | Text;\nexport interface Attributes {\n  [key: string]: number | string;\n}\nexport interface Styles {\n  [key: string]: string;\n}\nexport interface Transform {\n  size?: number;\n  x?: number;\n  y?: number;\n  rotate?: number;\n  flipX?: boolean;\n  flipY?: boolean;\n}\nexport interface Params {\n  title?: string;\n  titleId?: string;\n  classes?: string | string[];\n  attributes?: Attributes;\n  styles?: Styles;\n}\nexport interface CounterParams extends Params {\n}\nexport interface LayerParams {\n  classes?: string | string[];\n}\nexport interface TextParams extends Params {\n  transform?: Transform;\n}\nexport interface IconParams extends Params {\n  transform?: Transform;\n  symbol?: FaSymbol;\n  mask?: IconLookup;\n  maskId?: string;\n}\nexport interface DOM {\n  i2svg(params?: { node: Node; callback: () => void }): Promise<void>;\n  css(): string;\n  insertCss(): string;\n  watch(): void;\n}\ntype IconDefinitionOrPack = IconDefinition | IconPack;\nexport interface Library {\n  add(...definitions: IconDefinitionOrPack[]): void;\n  reset(): void;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-svg-core/index.es.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\nfunction ownKeys(object, enumerableOnly) {\n  var keys = Object.keys(object);\n\n  if (Object.getOwnPropertySymbols) {\n    var symbols = Object.getOwnPropertySymbols(object);\n\n    if (enumerableOnly) {\n      symbols = symbols.filter(function (sym) {\n        return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n      });\n    }\n\n    keys.push.apply(keys, symbols);\n  }\n\n  return keys;\n}\n\nfunction _objectSpread2(target) {\n  for (var i = 1; i < arguments.length; i++) {\n    var source = arguments[i] != null ? arguments[i] : {};\n\n    if (i % 2) {\n      ownKeys(Object(source), true).forEach(function (key) {\n        _defineProperty(target, key, source[key]);\n      });\n    } else if (Object.getOwnPropertyDescriptors) {\n      Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n    } else {\n      ownKeys(Object(source)).forEach(function (key) {\n        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n      });\n    }\n  }\n\n  return target;\n}\n\nfunction _typeof(obj) {\n  \"@babel/helpers - typeof\";\n\n  if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n    _typeof = function (obj) {\n      return typeof obj;\n    };\n  } else {\n    _typeof = function (obj) {\n      return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n    };\n  }\n\n  return _typeof(obj);\n}\n\nfunction _classCallCheck(instance, Constructor) {\n  if (!(instance instanceof Constructor)) {\n    throw new TypeError(\"Cannot call a class as a function\");\n  }\n}\n\nfunction _defineProperties(target, props) {\n  for (var i = 0; i < props.length; i++) {\n    var descriptor = props[i];\n    descriptor.enumerable = descriptor.enumerable || false;\n    descriptor.configurable = true;\n    if (\"value\" in descriptor) descriptor.writable = true;\n    Object.defineProperty(target, descriptor.key, descriptor);\n  }\n}\n\nfunction _createClass(Constructor, protoProps, staticProps) {\n  if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n  if (staticProps) _defineProperties(Constructor, staticProps);\n  return Constructor;\n}\n\nfunction _defineProperty(obj, key, value) {\n  if (key in obj) {\n    Object.defineProperty(obj, key, {\n      value: value,\n      enumerable: true,\n      configurable: true,\n      writable: true\n    });\n  } else {\n    obj[key] = value;\n  }\n\n  return obj;\n}\n\nfunction _slicedToArray(arr, i) {\n  return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n}\n\nfunction _toConsumableArray(arr) {\n  return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n}\n\nfunction _arrayWithoutHoles(arr) {\n  if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n}\n\nfunction _arrayWithHoles(arr) {\n  if (Array.isArray(arr)) return arr;\n}\n\nfunction _iterableToArray(iter) {\n  if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}\n\nfunction _iterableToArrayLimit(arr, i) {\n  var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n  if (_i == null) return;\n  var _arr = [];\n  var _n = true;\n  var _d = false;\n\n  var _s, _e;\n\n  try {\n    for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n      _arr.push(_s.value);\n\n      if (i && _arr.length === i) break;\n    }\n  } catch (err) {\n    _d = true;\n    _e = err;\n  } finally {\n    try {\n      if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n    } finally {\n      if (_d) throw _e;\n    }\n  }\n\n  return _arr;\n}\n\nfunction _unsupportedIterableToArray(o, minLen) {\n  if (!o) return;\n  if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n  var n = Object.prototype.toString.call(o).slice(8, -1);\n  if (n === \"Object\" && o.constructor) n = o.constructor.name;\n  if (n === \"Map\" || n === \"Set\") return Array.from(o);\n  if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n}\n\nfunction _arrayLikeToArray(arr, len) {\n  if (len == null || len > arr.length) len = arr.length;\n\n  for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n\n  return arr2;\n}\n\nfunction _nonIterableSpread() {\n  throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nfunction _nonIterableRest() {\n  throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\n\nvar noop = function noop() {};\n\nvar _WINDOW = {};\nvar _DOCUMENT = {};\nvar _MUTATION_OBSERVER = null;\nvar _PERFORMANCE = {\n  mark: noop,\n  measure: noop\n};\n\ntry {\n  if (typeof window !== 'undefined') _WINDOW = window;\n  if (typeof document !== 'undefined') _DOCUMENT = document;\n  if (typeof MutationObserver !== 'undefined') _MUTATION_OBSERVER = MutationObserver;\n  if (typeof performance !== 'undefined') _PERFORMANCE = performance;\n} catch (e) {}\n\nvar _ref = _WINDOW.navigator || {},\n    _ref$userAgent = _ref.userAgent,\n    userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\nvar WINDOW = _WINDOW;\nvar DOCUMENT = _DOCUMENT;\nvar MUTATION_OBSERVER = _MUTATION_OBSERVER;\nvar PERFORMANCE = _PERFORMANCE;\nvar IS_BROWSER = !!WINDOW.document;\nvar IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\nvar IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\nvar NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\nvar UNITS_IN_GRID = 16;\nvar DEFAULT_FAMILY_PREFIX = 'fa';\nvar DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa';\nvar DATA_FA_I2SVG = 'data-fa-i2svg';\nvar DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element';\nvar DATA_FA_PSEUDO_ELEMENT_PENDING = 'data-fa-pseudo-element-pending';\nvar DATA_PREFIX = 'data-prefix';\nvar DATA_ICON = 'data-icon';\nvar HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg';\nvar MUTATION_APPROACH_ASYNC = 'async';\nvar TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS = ['HTML', 'HEAD', 'STYLE', 'SCRIPT'];\nvar PRODUCTION = function () {\n  try {\n    return process.env.NODE_ENV === 'production';\n  } catch (e) {\n    return false;\n  }\n}();\nvar PREFIX_TO_STYLE = {\n  'fas': 'solid',\n  'far': 'regular',\n  'fal': 'light',\n  'fad': 'duotone',\n  'fab': 'brands',\n  'fak': 'kit',\n  'fa': 'solid'\n};\nvar STYLE_TO_PREFIX = {\n  'solid': 'fas',\n  'regular': 'far',\n  'light': 'fal',\n  'duotone': 'fad',\n  'brands': 'fab',\n  'kit': 'fak'\n};\nvar LAYERS_TEXT_CLASSNAME = 'fa-layers-text';\nvar FONT_FAMILY_PATTERN = /Font Awesome ([5 ]*)(Solid|Regular|Light|Duotone|Brands|Free|Pro|Kit).*/i; // TODO: do we need to handle font-weight for kit SVG pseudo-elements?\n\nvar FONT_WEIGHT_TO_PREFIX = {\n  '900': 'fas',\n  '400': 'far',\n  'normal': 'far',\n  '300': 'fal'\n};\nvar oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\nvar oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);\nvar ATTRIBUTES_WATCHED_FOR_MUTATION = ['class', 'data-prefix', 'data-icon', 'data-fa-transform', 'data-fa-mask'];\nvar DUOTONE_CLASSES = {\n  GROUP: 'group',\n  SWAP_OPACITY: 'swap-opacity',\n  PRIMARY: 'primary',\n  SECONDARY: 'secondary'\n};\nvar RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'flip-both', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter', DUOTONE_CLASSES.GROUP, DUOTONE_CLASSES.SWAP_OPACITY, DUOTONE_CLASSES.PRIMARY, DUOTONE_CLASSES.SECONDARY].concat(oneToTen.map(function (n) {\n  return \"\".concat(n, \"x\");\n})).concat(oneToTwenty.map(function (n) {\n  return \"w-\".concat(n);\n}));\n\nvar initial = WINDOW.FontAwesomeConfig || {};\n\nfunction getAttrConfig(attr) {\n  var element = DOCUMENT.querySelector('script[' + attr + ']');\n\n  if (element) {\n    return element.getAttribute(attr);\n  }\n}\n\nfunction coerce(val) {\n  // Getting an empty string will occur if the attribute is set on the HTML tag but without a value\n  // We'll assume that this is an indication that it should be toggled to true\n  // For example <script data-search-pseudo-elements src=\"...\"></script>\n  if (val === '') return true;\n  if (val === 'false') return false;\n  if (val === 'true') return true;\n  return val;\n}\n\nif (DOCUMENT && typeof DOCUMENT.querySelector === 'function') {\n  var attrs = [['data-family-prefix', 'familyPrefix'], ['data-replacement-class', 'replacementClass'], ['data-auto-replace-svg', 'autoReplaceSvg'], ['data-auto-add-css', 'autoAddCss'], ['data-auto-a11y', 'autoA11y'], ['data-search-pseudo-elements', 'searchPseudoElements'], ['data-observe-mutations', 'observeMutations'], ['data-mutate-approach', 'mutateApproach'], ['data-keep-original-source', 'keepOriginalSource'], ['data-measure-performance', 'measurePerformance'], ['data-show-missing-icons', 'showMissingIcons']];\n  attrs.forEach(function (_ref) {\n    var _ref2 = _slicedToArray(_ref, 2),\n        attr = _ref2[0],\n        key = _ref2[1];\n\n    var val = coerce(getAttrConfig(attr));\n\n    if (val !== undefined && val !== null) {\n      initial[key] = val;\n    }\n  });\n}\n\nvar _default = {\n  familyPrefix: DEFAULT_FAMILY_PREFIX,\n  replacementClass: DEFAULT_REPLACEMENT_CLASS,\n  autoReplaceSvg: true,\n  autoAddCss: true,\n  autoA11y: true,\n  searchPseudoElements: false,\n  observeMutations: true,\n  mutateApproach: 'async',\n  keepOriginalSource: true,\n  measurePerformance: false,\n  showMissingIcons: true\n};\n\nvar _config = _objectSpread2(_objectSpread2({}, _default), initial);\n\nif (!_config.autoReplaceSvg) _config.observeMutations = false;\n\nvar config = _objectSpread2({}, _config);\n\nWINDOW.FontAwesomeConfig = config;\n\nvar w = WINDOW || {};\nif (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\nif (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\nif (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\nif (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\nvar namespace = w[NAMESPACE_IDENTIFIER];\n\nvar functions = [];\n\nvar listener = function listener() {\n  DOCUMENT.removeEventListener('DOMContentLoaded', listener);\n  loaded = 1;\n  functions.map(function (fn) {\n    return fn();\n  });\n};\n\nvar loaded = false;\n\nif (IS_DOM) {\n  loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);\n  if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);\n}\n\nfunction domready (fn) {\n  if (!IS_DOM) return;\n  loaded ? setTimeout(fn, 0) : functions.push(fn);\n}\n\nvar PENDING = 'pending';\nvar SETTLED = 'settled';\nvar FULFILLED = 'fulfilled';\nvar REJECTED = 'rejected';\n\nvar NOOP = function NOOP() {};\n\nvar isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function';\nvar asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate;\nvar asyncQueue = [];\nvar asyncTimer;\n\nfunction asyncFlush() {\n  // run promise callbacks\n  for (var i = 0; i < asyncQueue.length; i++) {\n    asyncQueue[i][0](asyncQueue[i][1]);\n  } // reset async asyncQueue\n\n\n  asyncQueue = [];\n  asyncTimer = false;\n}\n\nfunction asyncCall(callback, arg) {\n  asyncQueue.push([callback, arg]);\n\n  if (!asyncTimer) {\n    asyncTimer = true;\n    asyncSetTimer(asyncFlush, 0);\n  }\n}\n\nfunction invokeResolver(resolver, promise) {\n  function resolvePromise(value) {\n    resolve(promise, value);\n  }\n\n  function rejectPromise(reason) {\n    reject(promise, reason);\n  }\n\n  try {\n    resolver(resolvePromise, rejectPromise);\n  } catch (e) {\n    rejectPromise(e);\n  }\n}\n\nfunction invokeCallback(subscriber) {\n  var owner = subscriber.owner;\n  var settled = owner._state;\n  var value = owner._data;\n  var callback = subscriber[settled];\n  var promise = subscriber.then;\n\n  if (typeof callback === 'function') {\n    settled = FULFILLED;\n\n    try {\n      value = callback(value);\n    } catch (e) {\n      reject(promise, e);\n    }\n  }\n\n  if (!handleThenable(promise, value)) {\n    if (settled === FULFILLED) {\n      resolve(promise, value);\n    }\n\n    if (settled === REJECTED) {\n      reject(promise, value);\n    }\n  }\n}\n\nfunction handleThenable(promise, value) {\n  var resolved;\n\n  try {\n    if (promise === value) {\n      throw new TypeError('A promises callback cannot return that same promise.');\n    }\n\n    if (value && (typeof value === 'function' || _typeof(value) === 'object')) {\n      // then should be retrieved only once\n      var then = value.then;\n\n      if (typeof then === 'function') {\n        then.call(value, function (val) {\n          if (!resolved) {\n            resolved = true;\n\n            if (value === val) {\n              fulfill(promise, val);\n            } else {\n              resolve(promise, val);\n            }\n          }\n        }, function (reason) {\n          if (!resolved) {\n            resolved = true;\n            reject(promise, reason);\n          }\n        });\n        return true;\n      }\n    }\n  } catch (e) {\n    if (!resolved) {\n      reject(promise, e);\n    }\n\n    return true;\n  }\n\n  return false;\n}\n\nfunction resolve(promise, value) {\n  if (promise === value || !handleThenable(promise, value)) {\n    fulfill(promise, value);\n  }\n}\n\nfunction fulfill(promise, value) {\n  if (promise._state === PENDING) {\n    promise._state = SETTLED;\n    promise._data = value;\n    asyncCall(publishFulfillment, promise);\n  }\n}\n\nfunction reject(promise, reason) {\n  if (promise._state === PENDING) {\n    promise._state = SETTLED;\n    promise._data = reason;\n    asyncCall(publishRejection, promise);\n  }\n}\n\nfunction publish(promise) {\n  promise._then = promise._then.forEach(invokeCallback);\n}\n\nfunction publishFulfillment(promise) {\n  promise._state = FULFILLED;\n  publish(promise);\n}\n\nfunction publishRejection(promise) {\n  promise._state = REJECTED;\n  publish(promise);\n\n  if (!promise._handled && isNode) {\n    global.process.emit('unhandledRejection', promise._data, promise);\n  }\n}\n\nfunction notifyRejectionHandled(promise) {\n  global.process.emit('rejectionHandled', promise);\n}\n/**\n * @class\n */\n\n\nfunction P(resolver) {\n  if (typeof resolver !== 'function') {\n    throw new TypeError('Promise resolver ' + resolver + ' is not a function');\n  }\n\n  if (this instanceof P === false) {\n    throw new TypeError('Failed to construct \\'Promise\\': Please use the \\'new\\' operator, this object constructor cannot be called as a function.');\n  }\n\n  this._then = [];\n  invokeResolver(resolver, this);\n}\n\nP.prototype = {\n  constructor: P,\n  _state: PENDING,\n  _then: null,\n  _data: undefined,\n  _handled: false,\n  then: function then(onFulfillment, onRejection) {\n    var subscriber = {\n      owner: this,\n      then: new this.constructor(NOOP),\n      fulfilled: onFulfillment,\n      rejected: onRejection\n    };\n\n    if ((onRejection || onFulfillment) && !this._handled) {\n      this._handled = true;\n\n      if (this._state === REJECTED && isNode) {\n        asyncCall(notifyRejectionHandled, this);\n      }\n    }\n\n    if (this._state === FULFILLED || this._state === REJECTED) {\n      // already resolved, call callback async\n      asyncCall(invokeCallback, subscriber);\n    } else {\n      // subscribe\n      this._then.push(subscriber);\n    }\n\n    return subscriber.then;\n  },\n  catch: function _catch(onRejection) {\n    return this.then(null, onRejection);\n  }\n};\n\nP.all = function (promises) {\n  if (!Array.isArray(promises)) {\n    throw new TypeError('You must pass an array to Promise.all().');\n  }\n\n  return new P(function (resolve, reject) {\n    var results = [];\n    var remaining = 0;\n\n    function resolver(index) {\n      remaining++;\n      return function (value) {\n        results[index] = value;\n\n        if (! --remaining) {\n          resolve(results);\n        }\n      };\n    }\n\n    for (var i = 0, promise; i < promises.length; i++) {\n      promise = promises[i];\n\n      if (promise && typeof promise.then === 'function') {\n        promise.then(resolver(i), reject);\n      } else {\n        results[i] = promise;\n      }\n    }\n\n    if (!remaining) {\n      resolve(results);\n    }\n  });\n};\n\nP.race = function (promises) {\n  if (!Array.isArray(promises)) {\n    throw new TypeError('You must pass an array to Promise.race().');\n  }\n\n  return new P(function (resolve, reject) {\n    for (var i = 0, promise; i < promises.length; i++) {\n      promise = promises[i];\n\n      if (promise && typeof promise.then === 'function') {\n        promise.then(resolve, reject);\n      } else {\n        resolve(promise);\n      }\n    }\n  });\n};\n\nP.resolve = function (value) {\n  if (value && _typeof(value) === 'object' && value.constructor === P) {\n    return value;\n  }\n\n  return new P(function (resolve) {\n    resolve(value);\n  });\n};\n\nP.reject = function (reason) {\n  return new P(function (resolve, reject) {\n    reject(reason);\n  });\n};\n\nvar picked = typeof Promise === 'function' ? Promise : P;\n\nvar d = UNITS_IN_GRID;\nvar meaninglessTransform = {\n  size: 16,\n  x: 0,\n  y: 0,\n  rotate: 0,\n  flipX: false,\n  flipY: false\n};\n\nfunction isReserved(name) {\n  return ~RESERVED_CLASSES.indexOf(name);\n}\nfunction insertCss(css) {\n  if (!css || !IS_DOM) {\n    return;\n  }\n\n  var style = DOCUMENT.createElement('style');\n  style.setAttribute('type', 'text/css');\n  style.innerHTML = css;\n  var headChildren = DOCUMENT.head.childNodes;\n  var beforeChild = null;\n\n  for (var i = headChildren.length - 1; i > -1; i--) {\n    var child = headChildren[i];\n    var tagName = (child.tagName || '').toUpperCase();\n\n    if (['STYLE', 'LINK'].indexOf(tagName) > -1) {\n      beforeChild = child;\n    }\n  }\n\n  DOCUMENT.head.insertBefore(style, beforeChild);\n  return css;\n}\nvar idPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\nfunction nextUniqueId() {\n  var size = 12;\n  var id = '';\n\n  while (size-- > 0) {\n    id += idPool[Math.random() * 62 | 0];\n  }\n\n  return id;\n}\nfunction toArray(obj) {\n  var array = [];\n\n  for (var i = (obj || []).length >>> 0; i--;) {\n    array[i] = obj[i];\n  }\n\n  return array;\n}\nfunction classArray(node) {\n  if (node.classList) {\n    return toArray(node.classList);\n  } else {\n    return (node.getAttribute('class') || '').split(' ').filter(function (i) {\n      return i;\n    });\n  }\n}\nfunction getIconName(familyPrefix, cls) {\n  var parts = cls.split('-');\n  var prefix = parts[0];\n  var iconName = parts.slice(1).join('-');\n\n  if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) {\n    return iconName;\n  } else {\n    return null;\n  }\n}\nfunction htmlEscape(str) {\n  return \"\".concat(str).replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n}\nfunction joinAttributes(attributes) {\n  return Object.keys(attributes || {}).reduce(function (acc, attributeName) {\n    return acc + \"\".concat(attributeName, \"=\\\"\").concat(htmlEscape(attributes[attributeName]), \"\\\" \");\n  }, '').trim();\n}\nfunction joinStyles(styles) {\n  return Object.keys(styles || {}).reduce(function (acc, styleName) {\n    return acc + \"\".concat(styleName, \": \").concat(styles[styleName], \";\");\n  }, '');\n}\nfunction transformIsMeaningful(transform) {\n  return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY;\n}\nfunction transformForSvg(_ref) {\n  var transform = _ref.transform,\n      containerWidth = _ref.containerWidth,\n      iconWidth = _ref.iconWidth;\n  var outer = {\n    transform: \"translate(\".concat(containerWidth / 2, \" 256)\")\n  };\n  var innerTranslate = \"translate(\".concat(transform.x * 32, \", \").concat(transform.y * 32, \") \");\n  var innerScale = \"scale(\".concat(transform.size / 16 * (transform.flipX ? -1 : 1), \", \").concat(transform.size / 16 * (transform.flipY ? -1 : 1), \") \");\n  var innerRotate = \"rotate(\".concat(transform.rotate, \" 0 0)\");\n  var inner = {\n    transform: \"\".concat(innerTranslate, \" \").concat(innerScale, \" \").concat(innerRotate)\n  };\n  var path = {\n    transform: \"translate(\".concat(iconWidth / 2 * -1, \" -256)\")\n  };\n  return {\n    outer: outer,\n    inner: inner,\n    path: path\n  };\n}\nfunction transformForCss(_ref2) {\n  var transform = _ref2.transform,\n      _ref2$width = _ref2.width,\n      width = _ref2$width === void 0 ? UNITS_IN_GRID : _ref2$width,\n      _ref2$height = _ref2.height,\n      height = _ref2$height === void 0 ? UNITS_IN_GRID : _ref2$height,\n      _ref2$startCentered = _ref2.startCentered,\n      startCentered = _ref2$startCentered === void 0 ? false : _ref2$startCentered;\n  var val = '';\n\n  if (startCentered && IS_IE) {\n    val += \"translate(\".concat(transform.x / d - width / 2, \"em, \").concat(transform.y / d - height / 2, \"em) \");\n  } else if (startCentered) {\n    val += \"translate(calc(-50% + \".concat(transform.x / d, \"em), calc(-50% + \").concat(transform.y / d, \"em)) \");\n  } else {\n    val += \"translate(\".concat(transform.x / d, \"em, \").concat(transform.y / d, \"em) \");\n  }\n\n  val += \"scale(\".concat(transform.size / d * (transform.flipX ? -1 : 1), \", \").concat(transform.size / d * (transform.flipY ? -1 : 1), \") \");\n  val += \"rotate(\".concat(transform.rotate, \"deg) \");\n  return val;\n}\n\nvar ALL_SPACE = {\n  x: 0,\n  y: 0,\n  width: '100%',\n  height: '100%'\n};\n\nfunction fillBlack(abstract) {\n  var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n  if (abstract.attributes && (abstract.attributes.fill || force)) {\n    abstract.attributes.fill = 'black';\n  }\n\n  return abstract;\n}\n\nfunction deGroup(abstract) {\n  if (abstract.tag === 'g') {\n    return abstract.children;\n  } else {\n    return [abstract];\n  }\n}\n\nfunction makeIconMasking (_ref) {\n  var children = _ref.children,\n      attributes = _ref.attributes,\n      main = _ref.main,\n      mask = _ref.mask,\n      explicitMaskId = _ref.maskId,\n      transform = _ref.transform;\n  var mainWidth = main.width,\n      mainPath = main.icon;\n  var maskWidth = mask.width,\n      maskPath = mask.icon;\n  var trans = transformForSvg({\n    transform: transform,\n    containerWidth: maskWidth,\n    iconWidth: mainWidth\n  });\n  var maskRect = {\n    tag: 'rect',\n    attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n      fill: 'white'\n    })\n  };\n  var maskInnerGroupChildrenMixin = mainPath.children ? {\n    children: mainPath.children.map(fillBlack)\n  } : {};\n  var maskInnerGroup = {\n    tag: 'g',\n    attributes: _objectSpread2({}, trans.inner),\n    children: [fillBlack(_objectSpread2({\n      tag: mainPath.tag,\n      attributes: _objectSpread2(_objectSpread2({}, mainPath.attributes), trans.path)\n    }, maskInnerGroupChildrenMixin))]\n  };\n  var maskOuterGroup = {\n    tag: 'g',\n    attributes: _objectSpread2({}, trans.outer),\n    children: [maskInnerGroup]\n  };\n  var maskId = \"mask-\".concat(explicitMaskId || nextUniqueId());\n  var clipId = \"clip-\".concat(explicitMaskId || nextUniqueId());\n  var maskTag = {\n    tag: 'mask',\n    attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n      id: maskId,\n      maskUnits: 'userSpaceOnUse',\n      maskContentUnits: 'userSpaceOnUse'\n    }),\n    children: [maskRect, maskOuterGroup]\n  };\n  var defs = {\n    tag: 'defs',\n    children: [{\n      tag: 'clipPath',\n      attributes: {\n        id: clipId\n      },\n      children: deGroup(maskPath)\n    }, maskTag]\n  };\n  children.push(defs, {\n    tag: 'rect',\n    attributes: _objectSpread2({\n      fill: 'currentColor',\n      'clip-path': \"url(#\".concat(clipId, \")\"),\n      mask: \"url(#\".concat(maskId, \")\")\n    }, ALL_SPACE)\n  });\n  return {\n    children: children,\n    attributes: attributes\n  };\n}\n\nfunction makeIconStandard (_ref) {\n  var children = _ref.children,\n      attributes = _ref.attributes,\n      main = _ref.main,\n      transform = _ref.transform,\n      styles = _ref.styles;\n  var styleString = joinStyles(styles);\n\n  if (styleString.length > 0) {\n    attributes['style'] = styleString;\n  }\n\n  if (transformIsMeaningful(transform)) {\n    var trans = transformForSvg({\n      transform: transform,\n      containerWidth: main.width,\n      iconWidth: main.width\n    });\n    children.push({\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.outer),\n      children: [{\n        tag: 'g',\n        attributes: _objectSpread2({}, trans.inner),\n        children: [{\n          tag: main.icon.tag,\n          children: main.icon.children,\n          attributes: _objectSpread2(_objectSpread2({}, main.icon.attributes), trans.path)\n        }]\n      }]\n    });\n  } else {\n    children.push(main.icon);\n  }\n\n  return {\n    children: children,\n    attributes: attributes\n  };\n}\n\nfunction asIcon (_ref) {\n  var children = _ref.children,\n      main = _ref.main,\n      mask = _ref.mask,\n      attributes = _ref.attributes,\n      styles = _ref.styles,\n      transform = _ref.transform;\n\n  if (transformIsMeaningful(transform) && main.found && !mask.found) {\n    var width = main.width,\n        height = main.height;\n    var offset = {\n      x: width / height / 2,\n      y: 0.5\n    };\n    attributes['style'] = joinStyles(_objectSpread2(_objectSpread2({}, styles), {}, {\n      'transform-origin': \"\".concat(offset.x + transform.x / 16, \"em \").concat(offset.y + transform.y / 16, \"em\")\n    }));\n  }\n\n  return [{\n    tag: 'svg',\n    attributes: attributes,\n    children: children\n  }];\n}\n\nfunction asSymbol (_ref) {\n  var prefix = _ref.prefix,\n      iconName = _ref.iconName,\n      children = _ref.children,\n      attributes = _ref.attributes,\n      symbol = _ref.symbol;\n  var id = symbol === true ? \"\".concat(prefix, \"-\").concat(config.familyPrefix, \"-\").concat(iconName) : symbol;\n  return [{\n    tag: 'svg',\n    attributes: {\n      style: 'display: none;'\n    },\n    children: [{\n      tag: 'symbol',\n      attributes: _objectSpread2(_objectSpread2({}, attributes), {}, {\n        id: id\n      }),\n      children: children\n    }]\n  }];\n}\n\nfunction makeInlineSvgAbstract(params) {\n  var _params$icons = params.icons,\n      main = _params$icons.main,\n      mask = _params$icons.mask,\n      prefix = params.prefix,\n      iconName = params.iconName,\n      transform = params.transform,\n      symbol = params.symbol,\n      title = params.title,\n      maskId = params.maskId,\n      titleId = params.titleId,\n      extra = params.extra,\n      _params$watchable = params.watchable,\n      watchable = _params$watchable === void 0 ? false : _params$watchable;\n\n  var _ref = mask.found ? mask : main,\n      width = _ref.width,\n      height = _ref.height;\n\n  var isUploadedIcon = prefix === 'fak';\n  var widthClass = isUploadedIcon ? '' : \"fa-w-\".concat(Math.ceil(width / height * 16));\n  var attrClass = [config.replacementClass, iconName ? \"\".concat(config.familyPrefix, \"-\").concat(iconName) : '', widthClass].filter(function (c) {\n    return extra.classes.indexOf(c) === -1;\n  }).filter(function (c) {\n    return c !== '' || !!c;\n  }).concat(extra.classes).join(' ');\n  var content = {\n    children: [],\n    attributes: _objectSpread2(_objectSpread2({}, extra.attributes), {}, {\n      'data-prefix': prefix,\n      'data-icon': iconName,\n      'class': attrClass,\n      'role': extra.attributes.role || 'img',\n      'xmlns': 'http://www.w3.org/2000/svg',\n      'viewBox': \"0 0 \".concat(width, \" \").concat(height)\n    })\n  };\n  var uploadedIconWidthStyle = isUploadedIcon && !~extra.classes.indexOf('fa-fw') ? {\n    width: \"\".concat(width / height * 16 * 0.0625, \"em\")\n  } : {};\n\n  if (watchable) {\n    content.attributes[DATA_FA_I2SVG] = '';\n  }\n\n  if (title) content.children.push({\n    tag: 'title',\n    attributes: {\n      id: content.attributes['aria-labelledby'] || \"title-\".concat(titleId || nextUniqueId())\n    },\n    children: [title]\n  });\n\n  var args = _objectSpread2(_objectSpread2({}, content), {}, {\n    prefix: prefix,\n    iconName: iconName,\n    main: main,\n    mask: mask,\n    maskId: maskId,\n    transform: transform,\n    symbol: symbol,\n    styles: _objectSpread2(_objectSpread2({}, uploadedIconWidthStyle), extra.styles)\n  });\n\n  var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args),\n      children = _ref2.children,\n      attributes = _ref2.attributes;\n\n  args.children = children;\n  args.attributes = attributes;\n\n  if (symbol) {\n    return asSymbol(args);\n  } else {\n    return asIcon(args);\n  }\n}\nfunction makeLayersTextAbstract(params) {\n  var content = params.content,\n      width = params.width,\n      height = params.height,\n      transform = params.transform,\n      title = params.title,\n      extra = params.extra,\n      _params$watchable2 = params.watchable,\n      watchable = _params$watchable2 === void 0 ? false : _params$watchable2;\n\n  var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n    'title': title\n  } : {}), {}, {\n    'class': extra.classes.join(' ')\n  });\n\n  if (watchable) {\n    attributes[DATA_FA_I2SVG] = '';\n  }\n\n  var styles = _objectSpread2({}, extra.styles);\n\n  if (transformIsMeaningful(transform)) {\n    styles['transform'] = transformForCss({\n      transform: transform,\n      startCentered: true,\n      width: width,\n      height: height\n    });\n    styles['-webkit-transform'] = styles['transform'];\n  }\n\n  var styleString = joinStyles(styles);\n\n  if (styleString.length > 0) {\n    attributes['style'] = styleString;\n  }\n\n  var val = [];\n  val.push({\n    tag: 'span',\n    attributes: attributes,\n    children: [content]\n  });\n\n  if (title) {\n    val.push({\n      tag: 'span',\n      attributes: {\n        class: 'sr-only'\n      },\n      children: [title]\n    });\n  }\n\n  return val;\n}\nfunction makeLayersCounterAbstract(params) {\n  var content = params.content,\n      title = params.title,\n      extra = params.extra;\n\n  var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n    'title': title\n  } : {}), {}, {\n    'class': extra.classes.join(' ')\n  });\n\n  var styleString = joinStyles(extra.styles);\n\n  if (styleString.length > 0) {\n    attributes['style'] = styleString;\n  }\n\n  var val = [];\n  val.push({\n    tag: 'span',\n    attributes: attributes,\n    children: [content]\n  });\n\n  if (title) {\n    val.push({\n      tag: 'span',\n      attributes: {\n        class: 'sr-only'\n      },\n      children: [title]\n    });\n  }\n\n  return val;\n}\n\nvar noop$1 = function noop() {};\n\nvar p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : {\n  mark: noop$1,\n  measure: noop$1\n};\nvar preamble = \"FA \\\"5.15.4\\\"\";\n\nvar begin = function begin(name) {\n  p.mark(\"\".concat(preamble, \" \").concat(name, \" begins\"));\n  return function () {\n    return end(name);\n  };\n};\n\nvar end = function end(name) {\n  p.mark(\"\".concat(preamble, \" \").concat(name, \" ends\"));\n  p.measure(\"\".concat(preamble, \" \").concat(name), \"\".concat(preamble, \" \").concat(name, \" begins\"), \"\".concat(preamble, \" \").concat(name, \" ends\"));\n};\n\nvar perf = {\n  begin: begin,\n  end: end\n};\n\n/**\n * Internal helper to bind a function known to have 4 arguments\n * to a given context.\n */\n\nvar bindInternal4 = function bindInternal4(func, thisContext) {\n  return function (a, b, c, d) {\n    return func.call(thisContext, a, b, c, d);\n  };\n};\n\n/**\n * # Reduce\n *\n * A fast object `.reduce()` implementation.\n *\n * @param  {Object}   subject      The object to reduce over.\n * @param  {Function} fn           The reducer function.\n * @param  {mixed}    initialValue The initial value for the reducer, defaults to subject[0].\n * @param  {Object}   thisContext  The context for the reducer.\n * @return {mixed}                 The final result.\n */\n\n\nvar reduce = function fastReduceObject(subject, fn, initialValue, thisContext) {\n  var keys = Object.keys(subject),\n      length = keys.length,\n      iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn,\n      i,\n      key,\n      result;\n\n  if (initialValue === undefined) {\n    i = 1;\n    result = subject[keys[0]];\n  } else {\n    i = 0;\n    result = initialValue;\n  }\n\n  for (; i < length; i++) {\n    key = keys[i];\n    result = iterator(result, subject[key], key, subject);\n  }\n\n  return result;\n};\n\nfunction toHex(unicode) {\n  var result = '';\n\n  for (var i = 0; i < unicode.length; i++) {\n    var hex = unicode.charCodeAt(i).toString(16);\n    result += ('000' + hex).slice(-4);\n  }\n\n  return result;\n}\n\nfunction defineIcons(prefix, icons) {\n  var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n  var _params$skipHooks = params.skipHooks,\n      skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n  var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n    var icon = icons[iconName];\n    var expanded = !!icon.icon;\n\n    if (expanded) {\n      acc[icon.iconName] = icon.icon;\n    } else {\n      acc[iconName] = icon;\n    }\n\n    return acc;\n  }, {});\n\n  if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n    namespace.hooks.addPack(prefix, normalized);\n  } else {\n    namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n  }\n  /**\n   * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n   * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n   * for `fas` so we'll easy the upgrade process for our users by automatically defining\n   * this as well.\n   */\n\n\n  if (prefix === 'fas') {\n    defineIcons('fa', icons);\n  }\n}\n\nvar styles = namespace.styles,\n    shims = namespace.shims;\nvar _byUnicode = {};\nvar _byLigature = {};\nvar _byOldName = {};\nvar build = function build() {\n  var lookup = function lookup(reducer) {\n    return reduce(styles, function (o, style, prefix) {\n      o[prefix] = reduce(style, reducer, {});\n      return o;\n    }, {});\n  };\n\n  _byUnicode = lookup(function (acc, icon, iconName) {\n    if (icon[3]) {\n      acc[icon[3]] = iconName;\n    }\n\n    return acc;\n  });\n  _byLigature = lookup(function (acc, icon, iconName) {\n    var ligatures = icon[2];\n    acc[iconName] = iconName;\n    ligatures.forEach(function (ligature) {\n      acc[ligature] = iconName;\n    });\n    return acc;\n  });\n  var hasRegular = ('far' in styles);\n  _byOldName = reduce(shims, function (acc, shim) {\n    var oldName = shim[0];\n    var prefix = shim[1];\n    var iconName = shim[2];\n\n    if (prefix === 'far' && !hasRegular) {\n      prefix = 'fas';\n    }\n\n    acc[oldName] = {\n      prefix: prefix,\n      iconName: iconName\n    };\n    return acc;\n  }, {});\n};\nbuild();\nfunction byUnicode(prefix, unicode) {\n  return (_byUnicode[prefix] || {})[unicode];\n}\nfunction byLigature(prefix, ligature) {\n  return (_byLigature[prefix] || {})[ligature];\n}\nfunction byOldName(name) {\n  return _byOldName[name] || {\n    prefix: null,\n    iconName: null\n  };\n}\n\nvar styles$1 = namespace.styles;\nvar emptyCanonicalIcon = function emptyCanonicalIcon() {\n  return {\n    prefix: null,\n    iconName: null,\n    rest: []\n  };\n};\nfunction getCanonicalIcon(values) {\n  return values.reduce(function (acc, cls) {\n    var iconName = getIconName(config.familyPrefix, cls);\n\n    if (styles$1[cls]) {\n      acc.prefix = cls;\n    } else if (config.autoFetchSvg && Object.keys(PREFIX_TO_STYLE).indexOf(cls) > -1) {\n      acc.prefix = cls;\n    } else if (iconName) {\n      var shim = acc.prefix === 'fa' ? byOldName(iconName) : {};\n      acc.iconName = shim.iconName || iconName;\n      acc.prefix = shim.prefix || acc.prefix;\n    } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) {\n      acc.rest.push(cls);\n    }\n\n    return acc;\n  }, emptyCanonicalIcon());\n}\nfunction iconFromMapping(mapping, prefix, iconName) {\n  if (mapping && mapping[prefix] && mapping[prefix][iconName]) {\n    return {\n      prefix: prefix,\n      iconName: iconName,\n      icon: mapping[prefix][iconName]\n    };\n  }\n}\n\nfunction toHtml(abstractNodes) {\n  var tag = abstractNodes.tag,\n      _abstractNodes$attrib = abstractNodes.attributes,\n      attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib,\n      _abstractNodes$childr = abstractNodes.children,\n      children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr;\n\n  if (typeof abstractNodes === 'string') {\n    return htmlEscape(abstractNodes);\n  } else {\n    return \"<\".concat(tag, \" \").concat(joinAttributes(attributes), \">\").concat(children.map(toHtml).join(''), \"</\").concat(tag, \">\");\n  }\n}\n\nvar noop$2 = function noop() {};\n\nfunction isWatched(node) {\n  var i2svg = node.getAttribute ? node.getAttribute(DATA_FA_I2SVG) : null;\n  return typeof i2svg === 'string';\n}\n\nfunction getMutator() {\n  if (config.autoReplaceSvg === true) {\n    return mutators.replace;\n  }\n\n  var mutator = mutators[config.autoReplaceSvg];\n  return mutator || mutators.replace;\n}\n\nvar mutators = {\n  replace: function replace(mutation) {\n    var node = mutation[0];\n    var abstract = mutation[1];\n    var newOuterHTML = abstract.map(function (a) {\n      return toHtml(a);\n    }).join('\\n');\n\n    if (node.parentNode && node.outerHTML) {\n      node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? \"<!-- \".concat(node.outerHTML, \" Font Awesome fontawesome.com -->\") : '');\n    } else if (node.parentNode) {\n      var newNode = document.createElement('span');\n      node.parentNode.replaceChild(newNode, node);\n      newNode.outerHTML = newOuterHTML;\n    }\n  },\n  nest: function nest(mutation) {\n    var node = mutation[0];\n    var abstract = mutation[1]; // If we already have a replaced node we do not want to continue nesting within it.\n    // Short-circuit to the standard replacement\n\n    if (~classArray(node).indexOf(config.replacementClass)) {\n      return mutators.replace(mutation);\n    }\n\n    var forSvg = new RegExp(\"\".concat(config.familyPrefix, \"-.*\"));\n    delete abstract[0].attributes.style;\n    delete abstract[0].attributes.id;\n    var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) {\n      if (cls === config.replacementClass || cls.match(forSvg)) {\n        acc.toSvg.push(cls);\n      } else {\n        acc.toNode.push(cls);\n      }\n\n      return acc;\n    }, {\n      toNode: [],\n      toSvg: []\n    });\n    abstract[0].attributes.class = splitClasses.toSvg.join(' ');\n    var newInnerHTML = abstract.map(function (a) {\n      return toHtml(a);\n    }).join('\\n');\n    node.setAttribute('class', splitClasses.toNode.join(' '));\n    node.setAttribute(DATA_FA_I2SVG, '');\n    node.innerHTML = newInnerHTML;\n  }\n};\n\nfunction performOperationSync(op) {\n  op();\n}\n\nfunction perform(mutations, callback) {\n  var callbackFunction = typeof callback === 'function' ? callback : noop$2;\n\n  if (mutations.length === 0) {\n    callbackFunction();\n  } else {\n    var frame = performOperationSync;\n\n    if (config.mutateApproach === MUTATION_APPROACH_ASYNC) {\n      frame = WINDOW.requestAnimationFrame || performOperationSync;\n    }\n\n    frame(function () {\n      var mutator = getMutator();\n      var mark = perf.begin('mutate');\n      mutations.map(mutator);\n      mark();\n      callbackFunction();\n    });\n  }\n}\nvar disabled = false;\nfunction disableObservation() {\n  disabled = true;\n}\nfunction enableObservation() {\n  disabled = false;\n}\nvar mo = null;\nfunction observe(options) {\n  if (!MUTATION_OBSERVER) {\n    return;\n  }\n\n  if (!config.observeMutations) {\n    return;\n  }\n\n  var treeCallback = options.treeCallback,\n      nodeCallback = options.nodeCallback,\n      pseudoElementsCallback = options.pseudoElementsCallback,\n      _options$observeMutat = options.observeMutationsRoot,\n      observeMutationsRoot = _options$observeMutat === void 0 ? DOCUMENT : _options$observeMutat;\n  mo = new MUTATION_OBSERVER(function (objects) {\n    if (disabled) return;\n    toArray(objects).forEach(function (mutationRecord) {\n      if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isWatched(mutationRecord.addedNodes[0])) {\n        if (config.searchPseudoElements) {\n          pseudoElementsCallback(mutationRecord.target);\n        }\n\n        treeCallback(mutationRecord.target);\n      }\n\n      if (mutationRecord.type === 'attributes' && mutationRecord.target.parentNode && config.searchPseudoElements) {\n        pseudoElementsCallback(mutationRecord.target.parentNode);\n      }\n\n      if (mutationRecord.type === 'attributes' && isWatched(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) {\n        if (mutationRecord.attributeName === 'class') {\n          var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)),\n              prefix = _getCanonicalIcon.prefix,\n              iconName = _getCanonicalIcon.iconName;\n\n          if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix);\n          if (iconName) mutationRecord.target.setAttribute('data-icon', iconName);\n        } else {\n          nodeCallback(mutationRecord.target);\n        }\n      }\n    });\n  });\n  if (!IS_DOM) return;\n  mo.observe(observeMutationsRoot, {\n    childList: true,\n    attributes: true,\n    characterData: true,\n    subtree: true\n  });\n}\nfunction disconnect() {\n  if (!mo) return;\n  mo.disconnect();\n}\n\nfunction styleParser (node) {\n  var style = node.getAttribute('style');\n  var val = [];\n\n  if (style) {\n    val = style.split(';').reduce(function (acc, style) {\n      var styles = style.split(':');\n      var prop = styles[0];\n      var value = styles.slice(1);\n\n      if (prop && value.length > 0) {\n        acc[prop] = value.join(':').trim();\n      }\n\n      return acc;\n    }, {});\n  }\n\n  return val;\n}\n\nfunction classParser (node) {\n  var existingPrefix = node.getAttribute('data-prefix');\n  var existingIconName = node.getAttribute('data-icon');\n  var innerText = node.innerText !== undefined ? node.innerText.trim() : '';\n  var val = getCanonicalIcon(classArray(node));\n\n  if (existingPrefix && existingIconName) {\n    val.prefix = existingPrefix;\n    val.iconName = existingIconName;\n  }\n\n  if (val.prefix && innerText.length > 1) {\n    val.iconName = byLigature(val.prefix, node.innerText);\n  } else if (val.prefix && innerText.length === 1) {\n    val.iconName = byUnicode(val.prefix, toHex(node.innerText));\n  }\n\n  return val;\n}\n\nvar parseTransformString = function parseTransformString(transformString) {\n  var transform = {\n    size: 16,\n    x: 0,\n    y: 0,\n    flipX: false,\n    flipY: false,\n    rotate: 0\n  };\n\n  if (!transformString) {\n    return transform;\n  } else {\n    return transformString.toLowerCase().split(' ').reduce(function (acc, n) {\n      var parts = n.toLowerCase().split('-');\n      var first = parts[0];\n      var rest = parts.slice(1).join('-');\n\n      if (first && rest === 'h') {\n        acc.flipX = true;\n        return acc;\n      }\n\n      if (first && rest === 'v') {\n        acc.flipY = true;\n        return acc;\n      }\n\n      rest = parseFloat(rest);\n\n      if (isNaN(rest)) {\n        return acc;\n      }\n\n      switch (first) {\n        case 'grow':\n          acc.size = acc.size + rest;\n          break;\n\n        case 'shrink':\n          acc.size = acc.size - rest;\n          break;\n\n        case 'left':\n          acc.x = acc.x - rest;\n          break;\n\n        case 'right':\n          acc.x = acc.x + rest;\n          break;\n\n        case 'up':\n          acc.y = acc.y - rest;\n          break;\n\n        case 'down':\n          acc.y = acc.y + rest;\n          break;\n\n        case 'rotate':\n          acc.rotate = acc.rotate + rest;\n          break;\n      }\n\n      return acc;\n    }, transform);\n  }\n};\nfunction transformParser (node) {\n  return parseTransformString(node.getAttribute('data-fa-transform'));\n}\n\nfunction symbolParser (node) {\n  var symbol = node.getAttribute('data-fa-symbol');\n  return symbol === null ? false : symbol === '' ? true : symbol;\n}\n\nfunction attributesParser (node) {\n  var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) {\n    if (acc.name !== 'class' && acc.name !== 'style') {\n      acc[attr.name] = attr.value;\n    }\n\n    return acc;\n  }, {});\n  var title = node.getAttribute('title');\n  var titleId = node.getAttribute('data-fa-title-id');\n\n  if (config.autoA11y) {\n    if (title) {\n      extraAttributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n    } else {\n      extraAttributes['aria-hidden'] = 'true';\n      extraAttributes['focusable'] = 'false';\n    }\n  }\n\n  return extraAttributes;\n}\n\nfunction maskParser (node) {\n  var mask = node.getAttribute('data-fa-mask');\n\n  if (!mask) {\n    return emptyCanonicalIcon();\n  } else {\n    return getCanonicalIcon(mask.split(' ').map(function (i) {\n      return i.trim();\n    }));\n  }\n}\n\nfunction blankMeta() {\n  return {\n    iconName: null,\n    title: null,\n    titleId: null,\n    prefix: null,\n    transform: meaninglessTransform,\n    symbol: false,\n    mask: null,\n    maskId: null,\n    extra: {\n      classes: [],\n      styles: {},\n      attributes: {}\n    }\n  };\n}\nfunction parseMeta(node) {\n  var _classParser = classParser(node),\n      iconName = _classParser.iconName,\n      prefix = _classParser.prefix,\n      extraClasses = _classParser.rest;\n\n  var extraStyles = styleParser(node);\n  var transform = transformParser(node);\n  var symbol = symbolParser(node);\n  var extraAttributes = attributesParser(node);\n  var mask = maskParser(node);\n  return {\n    iconName: iconName,\n    title: node.getAttribute('title'),\n    titleId: node.getAttribute('data-fa-title-id'),\n    prefix: prefix,\n    transform: transform,\n    symbol: symbol,\n    mask: mask,\n    maskId: node.getAttribute('data-fa-mask-id'),\n    extra: {\n      classes: extraClasses,\n      styles: extraStyles,\n      attributes: extraAttributes\n    }\n  };\n}\n\nfunction MissingIcon(error) {\n  this.name = 'MissingIcon';\n  this.message = error || 'Icon unavailable';\n  this.stack = new Error().stack;\n}\nMissingIcon.prototype = Object.create(Error.prototype);\nMissingIcon.prototype.constructor = MissingIcon;\n\nvar FILL = {\n  fill: 'currentColor'\n};\nvar ANIMATION_BASE = {\n  attributeType: 'XML',\n  repeatCount: 'indefinite',\n  dur: '2s'\n};\nvar RING = {\n  tag: 'path',\n  attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n    d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z'\n  })\n};\n\nvar OPACITY_ANIMATE = _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n  attributeName: 'opacity'\n});\n\nvar DOT = {\n  tag: 'circle',\n  attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n    cx: '256',\n    cy: '364',\n    r: '28'\n  }),\n  children: [{\n    tag: 'animate',\n    attributes: _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n      attributeName: 'r',\n      values: '28;14;28;28;14;28;'\n    })\n  }, {\n    tag: 'animate',\n    attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n      values: '1;0;1;1;0;1;'\n    })\n  }]\n};\nvar QUESTION = {\n  tag: 'path',\n  attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n    opacity: '1',\n    d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z'\n  }),\n  children: [{\n    tag: 'animate',\n    attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n      values: '1;0;0;0;0;1;'\n    })\n  }]\n};\nvar EXCLAMATION = {\n  tag: 'path',\n  attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n    opacity: '0',\n    d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z'\n  }),\n  children: [{\n    tag: 'animate',\n    attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n      values: '0;0;1;1;0;0;'\n    })\n  }]\n};\nvar missing = {\n  tag: 'g',\n  children: [RING, DOT, QUESTION, EXCLAMATION]\n};\n\nvar styles$2 = namespace.styles;\nfunction asFoundIcon(icon) {\n  var width = icon[0];\n  var height = icon[1];\n\n  var _icon$slice = icon.slice(4),\n      _icon$slice2 = _slicedToArray(_icon$slice, 1),\n      vectorData = _icon$slice2[0];\n\n  var element = null;\n\n  if (Array.isArray(vectorData)) {\n    element = {\n      tag: 'g',\n      attributes: {\n        class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.GROUP)\n      },\n      children: [{\n        tag: 'path',\n        attributes: {\n          class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.SECONDARY),\n          fill: 'currentColor',\n          d: vectorData[0]\n        }\n      }, {\n        tag: 'path',\n        attributes: {\n          class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.PRIMARY),\n          fill: 'currentColor',\n          d: vectorData[1]\n        }\n      }]\n    };\n  } else {\n    element = {\n      tag: 'path',\n      attributes: {\n        fill: 'currentColor',\n        d: vectorData\n      }\n    };\n  }\n\n  return {\n    found: true,\n    width: width,\n    height: height,\n    icon: element\n  };\n}\nfunction findIcon(iconName, prefix) {\n  return new picked(function (resolve, reject) {\n    var val = {\n      found: false,\n      width: 512,\n      height: 512,\n      icon: missing\n    };\n\n    if (iconName && prefix && styles$2[prefix] && styles$2[prefix][iconName]) {\n      var icon = styles$2[prefix][iconName];\n      return resolve(asFoundIcon(icon));\n    }\n\n    if (iconName && prefix && !config.showMissingIcons) {\n      reject(new MissingIcon(\"Icon is missing for prefix \".concat(prefix, \" with icon name \").concat(iconName)));\n    } else {\n      resolve(val);\n    }\n  });\n}\n\nvar styles$3 = namespace.styles;\n\nfunction generateSvgReplacementMutation(node, nodeMeta) {\n  var iconName = nodeMeta.iconName,\n      title = nodeMeta.title,\n      titleId = nodeMeta.titleId,\n      prefix = nodeMeta.prefix,\n      transform = nodeMeta.transform,\n      symbol = nodeMeta.symbol,\n      mask = nodeMeta.mask,\n      maskId = nodeMeta.maskId,\n      extra = nodeMeta.extra;\n  return new picked(function (resolve, reject) {\n    picked.all([findIcon(iconName, prefix), findIcon(mask.iconName, mask.prefix)]).then(function (_ref) {\n      var _ref2 = _slicedToArray(_ref, 2),\n          main = _ref2[0],\n          mask = _ref2[1];\n\n      resolve([node, makeInlineSvgAbstract({\n        icons: {\n          main: main,\n          mask: mask\n        },\n        prefix: prefix,\n        iconName: iconName,\n        transform: transform,\n        symbol: symbol,\n        mask: mask,\n        maskId: maskId,\n        title: title,\n        titleId: titleId,\n        extra: extra,\n        watchable: true\n      })]);\n    });\n  });\n}\n\nfunction generateLayersText(node, nodeMeta) {\n  var title = nodeMeta.title,\n      transform = nodeMeta.transform,\n      extra = nodeMeta.extra;\n  var width = null;\n  var height = null;\n\n  if (IS_IE) {\n    var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10);\n    var boundingClientRect = node.getBoundingClientRect();\n    width = boundingClientRect.width / computedFontSize;\n    height = boundingClientRect.height / computedFontSize;\n  }\n\n  if (config.autoA11y && !title) {\n    extra.attributes['aria-hidden'] = 'true';\n  }\n\n  return picked.resolve([node, makeLayersTextAbstract({\n    content: node.innerHTML,\n    width: width,\n    height: height,\n    transform: transform,\n    title: title,\n    extra: extra,\n    watchable: true\n  })]);\n}\n\nfunction generateMutation(node) {\n  var nodeMeta = parseMeta(node);\n\n  if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) {\n    return generateLayersText(node, nodeMeta);\n  } else {\n    return generateSvgReplacementMutation(node, nodeMeta);\n  }\n}\n\nfunction onTree(root) {\n  var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n  if (!IS_DOM) return;\n  var htmlClassList = DOCUMENT.documentElement.classList;\n\n  var hclAdd = function hclAdd(suffix) {\n    return htmlClassList.add(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n  };\n\n  var hclRemove = function hclRemove(suffix) {\n    return htmlClassList.remove(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n  };\n\n  var prefixes = config.autoFetchSvg ? Object.keys(PREFIX_TO_STYLE) : Object.keys(styles$3);\n  var prefixesDomQuery = [\".\".concat(LAYERS_TEXT_CLASSNAME, \":not([\").concat(DATA_FA_I2SVG, \"])\")].concat(prefixes.map(function (p) {\n    return \".\".concat(p, \":not([\").concat(DATA_FA_I2SVG, \"])\");\n  })).join(', ');\n\n  if (prefixesDomQuery.length === 0) {\n    return;\n  }\n\n  var candidates = [];\n\n  try {\n    candidates = toArray(root.querySelectorAll(prefixesDomQuery));\n  } catch (e) {// noop\n  }\n\n  if (candidates.length > 0) {\n    hclAdd('pending');\n    hclRemove('complete');\n  } else {\n    return;\n  }\n\n  var mark = perf.begin('onTree');\n  var mutations = candidates.reduce(function (acc, node) {\n    try {\n      var mutation = generateMutation(node);\n\n      if (mutation) {\n        acc.push(mutation);\n      }\n    } catch (e) {\n      if (!PRODUCTION) {\n        if (e instanceof MissingIcon) {\n          console.error(e);\n        }\n      }\n    }\n\n    return acc;\n  }, []);\n  return new picked(function (resolve, reject) {\n    picked.all(mutations).then(function (resolvedMutations) {\n      perform(resolvedMutations, function () {\n        hclAdd('active');\n        hclAdd('complete');\n        hclRemove('pending');\n        if (typeof callback === 'function') callback();\n        mark();\n        resolve();\n      });\n    }).catch(function () {\n      mark();\n      reject();\n    });\n  });\n}\nfunction onNode(node) {\n  var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n  generateMutation(node).then(function (mutation) {\n    if (mutation) {\n      perform([mutation], callback);\n    }\n  });\n}\n\nfunction replaceForPosition(node, position) {\n  var pendingAttribute = \"\".concat(DATA_FA_PSEUDO_ELEMENT_PENDING).concat(position.replace(':', '-'));\n  return new picked(function (resolve, reject) {\n    if (node.getAttribute(pendingAttribute) !== null) {\n      // This node is already being processed\n      return resolve();\n    }\n\n    var children = toArray(node.children);\n    var alreadyProcessedPseudoElement = children.filter(function (c) {\n      return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === position;\n    })[0];\n    var styles = WINDOW.getComputedStyle(node, position);\n    var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN);\n    var fontWeight = styles.getPropertyValue('font-weight');\n    var content = styles.getPropertyValue('content');\n\n    if (alreadyProcessedPseudoElement && !fontFamily) {\n      // If we've already processed it but the current computed style does not result in a font-family,\n      // that probably means that a class name that was previously present to make the icon has been\n      // removed. So we now should delete the icon.\n      node.removeChild(alreadyProcessedPseudoElement);\n      return resolve();\n    } else if (fontFamily && content !== 'none' && content !== '') {\n      var _content = styles.getPropertyValue('content');\n\n      var prefix = ~['Solid', 'Regular', 'Light', 'Duotone', 'Brands', 'Kit'].indexOf(fontFamily[2]) ? STYLE_TO_PREFIX[fontFamily[2].toLowerCase()] : FONT_WEIGHT_TO_PREFIX[fontWeight];\n      var hexValue = toHex(_content.length === 3 ? _content.substr(1, 1) : _content);\n      var iconName = byUnicode(prefix, hexValue);\n      var iconIdentifier = iconName; // Only convert the pseudo element in this :before/:after position into an icon if we haven't\n      // already done so with the same prefix and iconName\n\n      if (iconName && (!alreadyProcessedPseudoElement || alreadyProcessedPseudoElement.getAttribute(DATA_PREFIX) !== prefix || alreadyProcessedPseudoElement.getAttribute(DATA_ICON) !== iconIdentifier)) {\n        node.setAttribute(pendingAttribute, iconIdentifier);\n\n        if (alreadyProcessedPseudoElement) {\n          // Delete the old one, since we're replacing it with a new one\n          node.removeChild(alreadyProcessedPseudoElement);\n        }\n\n        var meta = blankMeta();\n        var extra = meta.extra;\n        extra.attributes[DATA_FA_PSEUDO_ELEMENT] = position;\n        findIcon(iconName, prefix).then(function (main) {\n          var abstract = makeInlineSvgAbstract(_objectSpread2(_objectSpread2({}, meta), {}, {\n            icons: {\n              main: main,\n              mask: emptyCanonicalIcon()\n            },\n            prefix: prefix,\n            iconName: iconIdentifier,\n            extra: extra,\n            watchable: true\n          }));\n          var element = DOCUMENT.createElement('svg');\n\n          if (position === ':before') {\n            node.insertBefore(element, node.firstChild);\n          } else {\n            node.appendChild(element);\n          }\n\n          element.outerHTML = abstract.map(function (a) {\n            return toHtml(a);\n          }).join('\\n');\n          node.removeAttribute(pendingAttribute);\n          resolve();\n        }).catch(reject);\n      } else {\n        resolve();\n      }\n    } else {\n      resolve();\n    }\n  });\n}\n\nfunction replace(node) {\n  return picked.all([replaceForPosition(node, ':before'), replaceForPosition(node, ':after')]);\n}\n\nfunction processable(node) {\n  return node.parentNode !== document.head && !~TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS.indexOf(node.tagName.toUpperCase()) && !node.getAttribute(DATA_FA_PSEUDO_ELEMENT) && (!node.parentNode || node.parentNode.tagName !== 'svg');\n}\n\nfunction searchPseudoElements (root) {\n  if (!IS_DOM) return;\n  return new picked(function (resolve, reject) {\n    var operations = toArray(root.querySelectorAll('*')).filter(processable).map(replace);\n    var end = perf.begin('searchPseudoElements');\n    disableObservation();\n    picked.all(operations).then(function () {\n      end();\n      enableObservation();\n      resolve();\n    }).catch(function () {\n      end();\n      enableObservation();\n      reject();\n    });\n  });\n}\n\nvar baseStyles = \"svg:not(:root).svg-inline--fa {\\n  overflow: visible;\\n}\\n\\n.svg-inline--fa {\\n  display: inline-block;\\n  font-size: inherit;\\n  height: 1em;\\n  overflow: visible;\\n  vertical-align: -0.125em;\\n}\\n.svg-inline--fa.fa-lg {\\n  vertical-align: -0.225em;\\n}\\n.svg-inline--fa.fa-w-1 {\\n  width: 0.0625em;\\n}\\n.svg-inline--fa.fa-w-2 {\\n  width: 0.125em;\\n}\\n.svg-inline--fa.fa-w-3 {\\n  width: 0.1875em;\\n}\\n.svg-inline--fa.fa-w-4 {\\n  width: 0.25em;\\n}\\n.svg-inline--fa.fa-w-5 {\\n  width: 0.3125em;\\n}\\n.svg-inline--fa.fa-w-6 {\\n  width: 0.375em;\\n}\\n.svg-inline--fa.fa-w-7 {\\n  width: 0.4375em;\\n}\\n.svg-inline--fa.fa-w-8 {\\n  width: 0.5em;\\n}\\n.svg-inline--fa.fa-w-9 {\\n  width: 0.5625em;\\n}\\n.svg-inline--fa.fa-w-10 {\\n  width: 0.625em;\\n}\\n.svg-inline--fa.fa-w-11 {\\n  width: 0.6875em;\\n}\\n.svg-inline--fa.fa-w-12 {\\n  width: 0.75em;\\n}\\n.svg-inline--fa.fa-w-13 {\\n  width: 0.8125em;\\n}\\n.svg-inline--fa.fa-w-14 {\\n  width: 0.875em;\\n}\\n.svg-inline--fa.fa-w-15 {\\n  width: 0.9375em;\\n}\\n.svg-inline--fa.fa-w-16 {\\n  width: 1em;\\n}\\n.svg-inline--fa.fa-w-17 {\\n  width: 1.0625em;\\n}\\n.svg-inline--fa.fa-w-18 {\\n  width: 1.125em;\\n}\\n.svg-inline--fa.fa-w-19 {\\n  width: 1.1875em;\\n}\\n.svg-inline--fa.fa-w-20 {\\n  width: 1.25em;\\n}\\n.svg-inline--fa.fa-pull-left {\\n  margin-right: 0.3em;\\n  width: auto;\\n}\\n.svg-inline--fa.fa-pull-right {\\n  margin-left: 0.3em;\\n  width: auto;\\n}\\n.svg-inline--fa.fa-border {\\n  height: 1.5em;\\n}\\n.svg-inline--fa.fa-li {\\n  width: 2em;\\n}\\n.svg-inline--fa.fa-fw {\\n  width: 1.25em;\\n}\\n\\n.fa-layers svg.svg-inline--fa {\\n  bottom: 0;\\n  left: 0;\\n  margin: auto;\\n  position: absolute;\\n  right: 0;\\n  top: 0;\\n}\\n\\n.fa-layers {\\n  display: inline-block;\\n  height: 1em;\\n  position: relative;\\n  text-align: center;\\n  vertical-align: -0.125em;\\n  width: 1em;\\n}\\n.fa-layers svg.svg-inline--fa {\\n  -webkit-transform-origin: center center;\\n          transform-origin: center center;\\n}\\n\\n.fa-layers-counter, .fa-layers-text {\\n  display: inline-block;\\n  position: absolute;\\n  text-align: center;\\n}\\n\\n.fa-layers-text {\\n  left: 50%;\\n  top: 50%;\\n  -webkit-transform: translate(-50%, -50%);\\n          transform: translate(-50%, -50%);\\n  -webkit-transform-origin: center center;\\n          transform-origin: center center;\\n}\\n\\n.fa-layers-counter {\\n  background-color: #ff253a;\\n  border-radius: 1em;\\n  -webkit-box-sizing: border-box;\\n          box-sizing: border-box;\\n  color: #fff;\\n  height: 1.5em;\\n  line-height: 1;\\n  max-width: 5em;\\n  min-width: 1.5em;\\n  overflow: hidden;\\n  padding: 0.25em;\\n  right: 0;\\n  text-overflow: ellipsis;\\n  top: 0;\\n  -webkit-transform: scale(0.25);\\n          transform: scale(0.25);\\n  -webkit-transform-origin: top right;\\n          transform-origin: top right;\\n}\\n\\n.fa-layers-bottom-right {\\n  bottom: 0;\\n  right: 0;\\n  top: auto;\\n  -webkit-transform: scale(0.25);\\n          transform: scale(0.25);\\n  -webkit-transform-origin: bottom right;\\n          transform-origin: bottom right;\\n}\\n\\n.fa-layers-bottom-left {\\n  bottom: 0;\\n  left: 0;\\n  right: auto;\\n  top: auto;\\n  -webkit-transform: scale(0.25);\\n          transform: scale(0.25);\\n  -webkit-transform-origin: bottom left;\\n          transform-origin: bottom left;\\n}\\n\\n.fa-layers-top-right {\\n  right: 0;\\n  top: 0;\\n  -webkit-transform: scale(0.25);\\n          transform: scale(0.25);\\n  -webkit-transform-origin: top right;\\n          transform-origin: top right;\\n}\\n\\n.fa-layers-top-left {\\n  left: 0;\\n  right: auto;\\n  top: 0;\\n  -webkit-transform: scale(0.25);\\n          transform: scale(0.25);\\n  -webkit-transform-origin: top left;\\n          transform-origin: top left;\\n}\\n\\n.fa-lg {\\n  font-size: 1.3333333333em;\\n  line-height: 0.75em;\\n  vertical-align: -0.0667em;\\n}\\n\\n.fa-xs {\\n  font-size: 0.75em;\\n}\\n\\n.fa-sm {\\n  font-size: 0.875em;\\n}\\n\\n.fa-1x {\\n  font-size: 1em;\\n}\\n\\n.fa-2x {\\n  font-size: 2em;\\n}\\n\\n.fa-3x {\\n  font-size: 3em;\\n}\\n\\n.fa-4x {\\n  font-size: 4em;\\n}\\n\\n.fa-5x {\\n  font-size: 5em;\\n}\\n\\n.fa-6x {\\n  font-size: 6em;\\n}\\n\\n.fa-7x {\\n  font-size: 7em;\\n}\\n\\n.fa-8x {\\n  font-size: 8em;\\n}\\n\\n.fa-9x {\\n  font-size: 9em;\\n}\\n\\n.fa-10x {\\n  font-size: 10em;\\n}\\n\\n.fa-fw {\\n  text-align: center;\\n  width: 1.25em;\\n}\\n\\n.fa-ul {\\n  list-style-type: none;\\n  margin-left: 2.5em;\\n  padding-left: 0;\\n}\\n.fa-ul > li {\\n  position: relative;\\n}\\n\\n.fa-li {\\n  left: -2em;\\n  position: absolute;\\n  text-align: center;\\n  width: 2em;\\n  line-height: inherit;\\n}\\n\\n.fa-border {\\n  border: solid 0.08em #eee;\\n  border-radius: 0.1em;\\n  padding: 0.2em 0.25em 0.15em;\\n}\\n\\n.fa-pull-left {\\n  float: left;\\n}\\n\\n.fa-pull-right {\\n  float: right;\\n}\\n\\n.fa.fa-pull-left,\\n.fas.fa-pull-left,\\n.far.fa-pull-left,\\n.fal.fa-pull-left,\\n.fab.fa-pull-left {\\n  margin-right: 0.3em;\\n}\\n.fa.fa-pull-right,\\n.fas.fa-pull-right,\\n.far.fa-pull-right,\\n.fal.fa-pull-right,\\n.fab.fa-pull-right {\\n  margin-left: 0.3em;\\n}\\n\\n.fa-spin {\\n  -webkit-animation: fa-spin 2s infinite linear;\\n          animation: fa-spin 2s infinite linear;\\n}\\n\\n.fa-pulse {\\n  -webkit-animation: fa-spin 1s infinite steps(8);\\n          animation: fa-spin 1s infinite steps(8);\\n}\\n\\n@-webkit-keyframes fa-spin {\\n  0% {\\n    -webkit-transform: rotate(0deg);\\n            transform: rotate(0deg);\\n  }\\n  100% {\\n    -webkit-transform: rotate(360deg);\\n            transform: rotate(360deg);\\n  }\\n}\\n\\n@keyframes fa-spin {\\n  0% {\\n    -webkit-transform: rotate(0deg);\\n            transform: rotate(0deg);\\n  }\\n  100% {\\n    -webkit-transform: rotate(360deg);\\n            transform: rotate(360deg);\\n  }\\n}\\n.fa-rotate-90 {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\\\";\\n  -webkit-transform: rotate(90deg);\\n          transform: rotate(90deg);\\n}\\n\\n.fa-rotate-180 {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\\\";\\n  -webkit-transform: rotate(180deg);\\n          transform: rotate(180deg);\\n}\\n\\n.fa-rotate-270 {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\\\";\\n  -webkit-transform: rotate(270deg);\\n          transform: rotate(270deg);\\n}\\n\\n.fa-flip-horizontal {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\\\";\\n  -webkit-transform: scale(-1, 1);\\n          transform: scale(-1, 1);\\n}\\n\\n.fa-flip-vertical {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\\\";\\n  -webkit-transform: scale(1, -1);\\n          transform: scale(1, -1);\\n}\\n\\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\\\";\\n  -webkit-transform: scale(-1, -1);\\n          transform: scale(-1, -1);\\n}\\n\\n:root .fa-rotate-90,\\n:root .fa-rotate-180,\\n:root .fa-rotate-270,\\n:root .fa-flip-horizontal,\\n:root .fa-flip-vertical,\\n:root .fa-flip-both {\\n  -webkit-filter: none;\\n          filter: none;\\n}\\n\\n.fa-stack {\\n  display: inline-block;\\n  height: 2em;\\n  position: relative;\\n  width: 2.5em;\\n}\\n\\n.fa-stack-1x,\\n.fa-stack-2x {\\n  bottom: 0;\\n  left: 0;\\n  margin: auto;\\n  position: absolute;\\n  right: 0;\\n  top: 0;\\n}\\n\\n.svg-inline--fa.fa-stack-1x {\\n  height: 1em;\\n  width: 1.25em;\\n}\\n.svg-inline--fa.fa-stack-2x {\\n  height: 2em;\\n  width: 2.5em;\\n}\\n\\n.fa-inverse {\\n  color: #fff;\\n}\\n\\n.sr-only {\\n  border: 0;\\n  clip: rect(0, 0, 0, 0);\\n  height: 1px;\\n  margin: -1px;\\n  overflow: hidden;\\n  padding: 0;\\n  position: absolute;\\n  width: 1px;\\n}\\n\\n.sr-only-focusable:active, .sr-only-focusable:focus {\\n  clip: auto;\\n  height: auto;\\n  margin: 0;\\n  overflow: visible;\\n  position: static;\\n  width: auto;\\n}\\n\\n.svg-inline--fa .fa-primary {\\n  fill: var(--fa-primary-color, currentColor);\\n  opacity: 1;\\n  opacity: var(--fa-primary-opacity, 1);\\n}\\n\\n.svg-inline--fa .fa-secondary {\\n  fill: var(--fa-secondary-color, currentColor);\\n  opacity: 0.4;\\n  opacity: var(--fa-secondary-opacity, 0.4);\\n}\\n\\n.svg-inline--fa.fa-swap-opacity .fa-primary {\\n  opacity: 0.4;\\n  opacity: var(--fa-secondary-opacity, 0.4);\\n}\\n\\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\\n  opacity: 1;\\n  opacity: var(--fa-primary-opacity, 1);\\n}\\n\\n.svg-inline--fa mask .fa-primary,\\n.svg-inline--fa mask .fa-secondary {\\n  fill: black;\\n}\\n\\n.fad.fa-inverse {\\n  color: #fff;\\n}\";\n\nfunction css () {\n  var dfp = DEFAULT_FAMILY_PREFIX;\n  var drc = DEFAULT_REPLACEMENT_CLASS;\n  var fp = config.familyPrefix;\n  var rc = config.replacementClass;\n  var s = baseStyles;\n\n  if (fp !== dfp || rc !== drc) {\n    var dPatt = new RegExp(\"\\\\.\".concat(dfp, \"\\\\-\"), 'g');\n    var customPropPatt = new RegExp(\"\\\\--\".concat(dfp, \"\\\\-\"), 'g');\n    var rPatt = new RegExp(\"\\\\.\".concat(drc), 'g');\n    s = s.replace(dPatt, \".\".concat(fp, \"-\")).replace(customPropPatt, \"--\".concat(fp, \"-\")).replace(rPatt, \".\".concat(rc));\n  }\n\n  return s;\n}\n\nvar Library = /*#__PURE__*/function () {\n  function Library() {\n    _classCallCheck(this, Library);\n\n    this.definitions = {};\n  }\n\n  _createClass(Library, [{\n    key: \"add\",\n    value: function add() {\n      var _this = this;\n\n      for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) {\n        definitions[_key] = arguments[_key];\n      }\n\n      var additions = definitions.reduce(this._pullDefinitions, {});\n      Object.keys(additions).forEach(function (key) {\n        _this.definitions[key] = _objectSpread2(_objectSpread2({}, _this.definitions[key] || {}), additions[key]);\n        defineIcons(key, additions[key]);\n        build();\n      });\n    }\n  }, {\n    key: \"reset\",\n    value: function reset() {\n      this.definitions = {};\n    }\n  }, {\n    key: \"_pullDefinitions\",\n    value: function _pullDefinitions(additions, definition) {\n      var normalized = definition.prefix && definition.iconName && definition.icon ? {\n        0: definition\n      } : definition;\n      Object.keys(normalized).map(function (key) {\n        var _normalized$key = normalized[key],\n            prefix = _normalized$key.prefix,\n            iconName = _normalized$key.iconName,\n            icon = _normalized$key.icon;\n        if (!additions[prefix]) additions[prefix] = {};\n        additions[prefix][iconName] = icon;\n      });\n      return additions;\n    }\n  }]);\n\n  return Library;\n}();\n\nfunction ensureCss() {\n  if (config.autoAddCss && !_cssInserted) {\n    insertCss(css());\n\n    _cssInserted = true;\n  }\n}\n\nfunction apiObject(val, abstractCreator) {\n  Object.defineProperty(val, 'abstract', {\n    get: abstractCreator\n  });\n  Object.defineProperty(val, 'html', {\n    get: function get() {\n      return val.abstract.map(function (a) {\n        return toHtml(a);\n      });\n    }\n  });\n  Object.defineProperty(val, 'node', {\n    get: function get() {\n      if (!IS_DOM) return;\n      var container = DOCUMENT.createElement('div');\n      container.innerHTML = val.html;\n      return container.children;\n    }\n  });\n  return val;\n}\n\nfunction findIconDefinition(iconLookup) {\n  var _iconLookup$prefix = iconLookup.prefix,\n      prefix = _iconLookup$prefix === void 0 ? 'fa' : _iconLookup$prefix,\n      iconName = iconLookup.iconName;\n  if (!iconName) return;\n  return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName);\n}\n\nfunction resolveIcons(next) {\n  return function (maybeIconDefinition) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {});\n    var mask = params.mask;\n\n    if (mask) {\n      mask = (mask || {}).icon ? mask : findIconDefinition(mask || {});\n    }\n\n    return next(iconDefinition, _objectSpread2(_objectSpread2({}, params), {}, {\n      mask: mask\n    }));\n  };\n}\n\nvar library = new Library();\nvar noAuto = function noAuto() {\n  config.autoReplaceSvg = false;\n  config.observeMutations = false;\n  disconnect();\n};\nvar _cssInserted = false;\nvar dom = {\n  i2svg: function i2svg() {\n    var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n    if (IS_DOM) {\n      ensureCss();\n      var _params$node = params.node,\n          node = _params$node === void 0 ? DOCUMENT : _params$node,\n          _params$callback = params.callback,\n          callback = _params$callback === void 0 ? function () {} : _params$callback;\n\n      if (config.searchPseudoElements) {\n        searchPseudoElements(node);\n      }\n\n      return onTree(node, callback);\n    } else {\n      return picked.reject('Operation requires a DOM of some kind.');\n    }\n  },\n  css: css,\n  insertCss: function insertCss$$1() {\n    if (!_cssInserted) {\n      insertCss(css());\n\n      _cssInserted = true;\n    }\n  },\n  watch: function watch() {\n    var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n    var autoReplaceSvgRoot = params.autoReplaceSvgRoot,\n        observeMutationsRoot = params.observeMutationsRoot;\n\n    if (config.autoReplaceSvg === false) {\n      config.autoReplaceSvg = true;\n    }\n\n    config.observeMutations = true;\n    domready(function () {\n      autoReplace({\n        autoReplaceSvgRoot: autoReplaceSvgRoot\n      });\n      observe({\n        treeCallback: onTree,\n        nodeCallback: onNode,\n        pseudoElementsCallback: searchPseudoElements,\n        observeMutationsRoot: observeMutationsRoot\n      });\n    });\n  }\n};\nvar parse = {\n  transform: function transform(transformString) {\n    return parseTransformString(transformString);\n  }\n};\nvar icon = resolveIcons(function (iconDefinition) {\n  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n  var _params$transform = params.transform,\n      transform = _params$transform === void 0 ? meaninglessTransform : _params$transform,\n      _params$symbol = params.symbol,\n      symbol = _params$symbol === void 0 ? false : _params$symbol,\n      _params$mask = params.mask,\n      mask = _params$mask === void 0 ? null : _params$mask,\n      _params$maskId = params.maskId,\n      maskId = _params$maskId === void 0 ? null : _params$maskId,\n      _params$title = params.title,\n      title = _params$title === void 0 ? null : _params$title,\n      _params$titleId = params.titleId,\n      titleId = _params$titleId === void 0 ? null : _params$titleId,\n      _params$classes = params.classes,\n      classes = _params$classes === void 0 ? [] : _params$classes,\n      _params$attributes = params.attributes,\n      attributes = _params$attributes === void 0 ? {} : _params$attributes,\n      _params$styles = params.styles,\n      styles = _params$styles === void 0 ? {} : _params$styles;\n  if (!iconDefinition) return;\n  var prefix = iconDefinition.prefix,\n      iconName = iconDefinition.iconName,\n      icon = iconDefinition.icon;\n  return apiObject(_objectSpread2({\n    type: 'icon'\n  }, iconDefinition), function () {\n    ensureCss();\n\n    if (config.autoA11y) {\n      if (title) {\n        attributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n      } else {\n        attributes['aria-hidden'] = 'true';\n        attributes['focusable'] = 'false';\n      }\n    }\n\n    return makeInlineSvgAbstract({\n      icons: {\n        main: asFoundIcon(icon),\n        mask: mask ? asFoundIcon(mask.icon) : {\n          found: false,\n          width: null,\n          height: null,\n          icon: {}\n        }\n      },\n      prefix: prefix,\n      iconName: iconName,\n      transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n      symbol: symbol,\n      title: title,\n      maskId: maskId,\n      titleId: titleId,\n      extra: {\n        attributes: attributes,\n        styles: styles,\n        classes: classes\n      }\n    });\n  });\n});\nvar text = function text(content) {\n  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n  var _params$transform2 = params.transform,\n      transform = _params$transform2 === void 0 ? meaninglessTransform : _params$transform2,\n      _params$title2 = params.title,\n      title = _params$title2 === void 0 ? null : _params$title2,\n      _params$classes2 = params.classes,\n      classes = _params$classes2 === void 0 ? [] : _params$classes2,\n      _params$attributes2 = params.attributes,\n      attributes = _params$attributes2 === void 0 ? {} : _params$attributes2,\n      _params$styles2 = params.styles,\n      styles = _params$styles2 === void 0 ? {} : _params$styles2;\n  return apiObject({\n    type: 'text',\n    content: content\n  }, function () {\n    ensureCss();\n    return makeLayersTextAbstract({\n      content: content,\n      transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n      title: title,\n      extra: {\n        attributes: attributes,\n        styles: styles,\n        classes: [\"\".concat(config.familyPrefix, \"-layers-text\")].concat(_toConsumableArray(classes))\n      }\n    });\n  });\n};\nvar counter = function counter(content) {\n  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n  var _params$title3 = params.title,\n      title = _params$title3 === void 0 ? null : _params$title3,\n      _params$classes3 = params.classes,\n      classes = _params$classes3 === void 0 ? [] : _params$classes3,\n      _params$attributes3 = params.attributes,\n      attributes = _params$attributes3 === void 0 ? {} : _params$attributes3,\n      _params$styles3 = params.styles,\n      styles = _params$styles3 === void 0 ? {} : _params$styles3;\n  return apiObject({\n    type: 'counter',\n    content: content\n  }, function () {\n    ensureCss();\n    return makeLayersCounterAbstract({\n      content: content.toString(),\n      title: title,\n      extra: {\n        attributes: attributes,\n        styles: styles,\n        classes: [\"\".concat(config.familyPrefix, \"-layers-counter\")].concat(_toConsumableArray(classes))\n      }\n    });\n  });\n};\nvar layer = function layer(assembler) {\n  var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n  var _params$classes4 = params.classes,\n      classes = _params$classes4 === void 0 ? [] : _params$classes4;\n  return apiObject({\n    type: 'layer'\n  }, function () {\n    ensureCss();\n    var children = [];\n    assembler(function (args) {\n      Array.isArray(args) ? args.map(function (a) {\n        children = children.concat(a.abstract);\n      }) : children = children.concat(args.abstract);\n    });\n    return [{\n      tag: 'span',\n      attributes: {\n        class: [\"\".concat(config.familyPrefix, \"-layers\")].concat(_toConsumableArray(classes)).join(' ')\n      },\n      children: children\n    }];\n  });\n};\nvar api = {\n  noAuto: noAuto,\n  config: config,\n  dom: dom,\n  library: library,\n  parse: parse,\n  findIconDefinition: findIconDefinition,\n  icon: icon,\n  text: text,\n  counter: counter,\n  layer: layer,\n  toHtml: toHtml\n};\n\nvar autoReplace = function autoReplace() {\n  var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n  var _params$autoReplaceSv = params.autoReplaceSvgRoot,\n      autoReplaceSvgRoot = _params$autoReplaceSv === void 0 ? DOCUMENT : _params$autoReplaceSv;\n  if ((Object.keys(namespace.styles).length > 0 || config.autoFetchSvg) && IS_DOM && config.autoReplaceSvg) api.dom.i2svg({\n    node: autoReplaceSvgRoot\n  });\n};\n\nexport { icon, noAuto, config, toHtml, layer, text, counter, library, dom, parse, findIconDefinition };\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-svg-core/index.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (factory((global['fontawesome-svg-core'] = {})));\n}(this, (function (exports) { 'use strict';\n\n  function ownKeys(object, enumerableOnly) {\n    var keys = Object.keys(object);\n\n    if (Object.getOwnPropertySymbols) {\n      var symbols = Object.getOwnPropertySymbols(object);\n\n      if (enumerableOnly) {\n        symbols = symbols.filter(function (sym) {\n          return Object.getOwnPropertyDescriptor(object, sym).enumerable;\n        });\n      }\n\n      keys.push.apply(keys, symbols);\n    }\n\n    return keys;\n  }\n\n  function _objectSpread2(target) {\n    for (var i = 1; i < arguments.length; i++) {\n      var source = arguments[i] != null ? arguments[i] : {};\n\n      if (i % 2) {\n        ownKeys(Object(source), true).forEach(function (key) {\n          _defineProperty(target, key, source[key]);\n        });\n      } else if (Object.getOwnPropertyDescriptors) {\n        Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));\n      } else {\n        ownKeys(Object(source)).forEach(function (key) {\n          Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));\n        });\n      }\n    }\n\n    return target;\n  }\n\n  function _typeof(obj) {\n    \"@babel/helpers - typeof\";\n\n    if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") {\n      _typeof = function (obj) {\n        return typeof obj;\n      };\n    } else {\n      _typeof = function (obj) {\n        return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n      };\n    }\n\n    return _typeof(obj);\n  }\n\n  function _classCallCheck(instance, Constructor) {\n    if (!(instance instanceof Constructor)) {\n      throw new TypeError(\"Cannot call a class as a function\");\n    }\n  }\n\n  function _defineProperties(target, props) {\n    for (var i = 0; i < props.length; i++) {\n      var descriptor = props[i];\n      descriptor.enumerable = descriptor.enumerable || false;\n      descriptor.configurable = true;\n      if (\"value\" in descriptor) descriptor.writable = true;\n      Object.defineProperty(target, descriptor.key, descriptor);\n    }\n  }\n\n  function _createClass(Constructor, protoProps, staticProps) {\n    if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n    if (staticProps) _defineProperties(Constructor, staticProps);\n    return Constructor;\n  }\n\n  function _defineProperty(obj, key, value) {\n    if (key in obj) {\n      Object.defineProperty(obj, key, {\n        value: value,\n        enumerable: true,\n        configurable: true,\n        writable: true\n      });\n    } else {\n      obj[key] = value;\n    }\n\n    return obj;\n  }\n\n  function _slicedToArray(arr, i) {\n    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n  }\n\n  function _toConsumableArray(arr) {\n    return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();\n  }\n\n  function _arrayWithoutHoles(arr) {\n    if (Array.isArray(arr)) return _arrayLikeToArray(arr);\n  }\n\n  function _arrayWithHoles(arr) {\n    if (Array.isArray(arr)) return arr;\n  }\n\n  function _iterableToArray(iter) {\n    if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n  }\n\n  function _iterableToArrayLimit(arr, i) {\n    var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n    if (_i == null) return;\n    var _arr = [];\n    var _n = true;\n    var _d = false;\n\n    var _s, _e;\n\n    try {\n      for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n        _arr.push(_s.value);\n\n        if (i && _arr.length === i) break;\n      }\n    } catch (err) {\n      _d = true;\n      _e = err;\n    } finally {\n      try {\n        if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n      } finally {\n        if (_d) throw _e;\n      }\n    }\n\n    return _arr;\n  }\n\n  function _unsupportedIterableToArray(o, minLen) {\n    if (!o) return;\n    if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n    var n = Object.prototype.toString.call(o).slice(8, -1);\n    if (n === \"Object\" && o.constructor) n = o.constructor.name;\n    if (n === \"Map\" || n === \"Set\") return Array.from(o);\n    if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n  }\n\n  function _arrayLikeToArray(arr, len) {\n    if (len == null || len > arr.length) len = arr.length;\n\n    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n\n    return arr2;\n  }\n\n  function _nonIterableSpread() {\n    throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n\n  function _nonIterableRest() {\n    throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n  }\n\n  var noop = function noop() {};\n\n  var _WINDOW = {};\n  var _DOCUMENT = {};\n  var _MUTATION_OBSERVER = null;\n  var _PERFORMANCE = {\n    mark: noop,\n    measure: noop\n  };\n\n  try {\n    if (typeof window !== 'undefined') _WINDOW = window;\n    if (typeof document !== 'undefined') _DOCUMENT = document;\n    if (typeof MutationObserver !== 'undefined') _MUTATION_OBSERVER = MutationObserver;\n    if (typeof performance !== 'undefined') _PERFORMANCE = performance;\n  } catch (e) {}\n\n  var _ref = _WINDOW.navigator || {},\n      _ref$userAgent = _ref.userAgent,\n      userAgent = _ref$userAgent === void 0 ? '' : _ref$userAgent;\n\n  var WINDOW = _WINDOW;\n  var DOCUMENT = _DOCUMENT;\n  var MUTATION_OBSERVER = _MUTATION_OBSERVER;\n  var PERFORMANCE = _PERFORMANCE;\n  var IS_BROWSER = !!WINDOW.document;\n  var IS_DOM = !!DOCUMENT.documentElement && !!DOCUMENT.head && typeof DOCUMENT.addEventListener === 'function' && typeof DOCUMENT.createElement === 'function';\n  var IS_IE = ~userAgent.indexOf('MSIE') || ~userAgent.indexOf('Trident/');\n\n  var NAMESPACE_IDENTIFIER = '___FONT_AWESOME___';\n  var UNITS_IN_GRID = 16;\n  var DEFAULT_FAMILY_PREFIX = 'fa';\n  var DEFAULT_REPLACEMENT_CLASS = 'svg-inline--fa';\n  var DATA_FA_I2SVG = 'data-fa-i2svg';\n  var DATA_FA_PSEUDO_ELEMENT = 'data-fa-pseudo-element';\n  var DATA_FA_PSEUDO_ELEMENT_PENDING = 'data-fa-pseudo-element-pending';\n  var DATA_PREFIX = 'data-prefix';\n  var DATA_ICON = 'data-icon';\n  var HTML_CLASS_I2SVG_BASE_CLASS = 'fontawesome-i2svg';\n  var MUTATION_APPROACH_ASYNC = 'async';\n  var TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS = ['HTML', 'HEAD', 'STYLE', 'SCRIPT'];\n  var PRODUCTION = function () {\n    try {\n      return process.env.NODE_ENV === 'production';\n    } catch (e) {\n      return false;\n    }\n  }();\n  var PREFIX_TO_STYLE = {\n    'fas': 'solid',\n    'far': 'regular',\n    'fal': 'light',\n    'fad': 'duotone',\n    'fab': 'brands',\n    'fak': 'kit',\n    'fa': 'solid'\n  };\n  var STYLE_TO_PREFIX = {\n    'solid': 'fas',\n    'regular': 'far',\n    'light': 'fal',\n    'duotone': 'fad',\n    'brands': 'fab',\n    'kit': 'fak'\n  };\n  var LAYERS_TEXT_CLASSNAME = 'fa-layers-text';\n  var FONT_FAMILY_PATTERN = /Font Awesome ([5 ]*)(Solid|Regular|Light|Duotone|Brands|Free|Pro|Kit).*/i; // TODO: do we need to handle font-weight for kit SVG pseudo-elements?\n\n  var FONT_WEIGHT_TO_PREFIX = {\n    '900': 'fas',\n    '400': 'far',\n    'normal': 'far',\n    '300': 'fal'\n  };\n  var oneToTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];\n  var oneToTwenty = oneToTen.concat([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);\n  var ATTRIBUTES_WATCHED_FOR_MUTATION = ['class', 'data-prefix', 'data-icon', 'data-fa-transform', 'data-fa-mask'];\n  var DUOTONE_CLASSES = {\n    GROUP: 'group',\n    SWAP_OPACITY: 'swap-opacity',\n    PRIMARY: 'primary',\n    SECONDARY: 'secondary'\n  };\n  var RESERVED_CLASSES = ['xs', 'sm', 'lg', 'fw', 'ul', 'li', 'border', 'pull-left', 'pull-right', 'spin', 'pulse', 'rotate-90', 'rotate-180', 'rotate-270', 'flip-horizontal', 'flip-vertical', 'flip-both', 'stack', 'stack-1x', 'stack-2x', 'inverse', 'layers', 'layers-text', 'layers-counter', DUOTONE_CLASSES.GROUP, DUOTONE_CLASSES.SWAP_OPACITY, DUOTONE_CLASSES.PRIMARY, DUOTONE_CLASSES.SECONDARY].concat(oneToTen.map(function (n) {\n    return \"\".concat(n, \"x\");\n  })).concat(oneToTwenty.map(function (n) {\n    return \"w-\".concat(n);\n  }));\n\n  var initial = WINDOW.FontAwesomeConfig || {};\n\n  function getAttrConfig(attr) {\n    var element = DOCUMENT.querySelector('script[' + attr + ']');\n\n    if (element) {\n      return element.getAttribute(attr);\n    }\n  }\n\n  function coerce(val) {\n    // Getting an empty string will occur if the attribute is set on the HTML tag but without a value\n    // We'll assume that this is an indication that it should be toggled to true\n    // For example <script data-search-pseudo-elements src=\"...\"></script>\n    if (val === '') return true;\n    if (val === 'false') return false;\n    if (val === 'true') return true;\n    return val;\n  }\n\n  if (DOCUMENT && typeof DOCUMENT.querySelector === 'function') {\n    var attrs = [['data-family-prefix', 'familyPrefix'], ['data-replacement-class', 'replacementClass'], ['data-auto-replace-svg', 'autoReplaceSvg'], ['data-auto-add-css', 'autoAddCss'], ['data-auto-a11y', 'autoA11y'], ['data-search-pseudo-elements', 'searchPseudoElements'], ['data-observe-mutations', 'observeMutations'], ['data-mutate-approach', 'mutateApproach'], ['data-keep-original-source', 'keepOriginalSource'], ['data-measure-performance', 'measurePerformance'], ['data-show-missing-icons', 'showMissingIcons']];\n    attrs.forEach(function (_ref) {\n      var _ref2 = _slicedToArray(_ref, 2),\n          attr = _ref2[0],\n          key = _ref2[1];\n\n      var val = coerce(getAttrConfig(attr));\n\n      if (val !== undefined && val !== null) {\n        initial[key] = val;\n      }\n    });\n  }\n\n  var _default = {\n    familyPrefix: DEFAULT_FAMILY_PREFIX,\n    replacementClass: DEFAULT_REPLACEMENT_CLASS,\n    autoReplaceSvg: true,\n    autoAddCss: true,\n    autoA11y: true,\n    searchPseudoElements: false,\n    observeMutations: true,\n    mutateApproach: 'async',\n    keepOriginalSource: true,\n    measurePerformance: false,\n    showMissingIcons: true\n  };\n\n  var _config = _objectSpread2(_objectSpread2({}, _default), initial);\n\n  if (!_config.autoReplaceSvg) _config.observeMutations = false;\n\n  var config = _objectSpread2({}, _config);\n\n  WINDOW.FontAwesomeConfig = config;\n\n  var w = WINDOW || {};\n  if (!w[NAMESPACE_IDENTIFIER]) w[NAMESPACE_IDENTIFIER] = {};\n  if (!w[NAMESPACE_IDENTIFIER].styles) w[NAMESPACE_IDENTIFIER].styles = {};\n  if (!w[NAMESPACE_IDENTIFIER].hooks) w[NAMESPACE_IDENTIFIER].hooks = {};\n  if (!w[NAMESPACE_IDENTIFIER].shims) w[NAMESPACE_IDENTIFIER].shims = [];\n  var namespace = w[NAMESPACE_IDENTIFIER];\n\n  var functions = [];\n\n  var listener = function listener() {\n    DOCUMENT.removeEventListener('DOMContentLoaded', listener);\n    loaded = 1;\n    functions.map(function (fn) {\n      return fn();\n    });\n  };\n\n  var loaded = false;\n\n  if (IS_DOM) {\n    loaded = (DOCUMENT.documentElement.doScroll ? /^loaded|^c/ : /^loaded|^i|^c/).test(DOCUMENT.readyState);\n    if (!loaded) DOCUMENT.addEventListener('DOMContentLoaded', listener);\n  }\n\n  function domready (fn) {\n    if (!IS_DOM) return;\n    loaded ? setTimeout(fn, 0) : functions.push(fn);\n  }\n\n  var PENDING = 'pending';\n  var SETTLED = 'settled';\n  var FULFILLED = 'fulfilled';\n  var REJECTED = 'rejected';\n\n  var NOOP = function NOOP() {};\n\n  var isNode = typeof global !== 'undefined' && typeof global.process !== 'undefined' && typeof global.process.emit === 'function';\n  var asyncSetTimer = typeof setImmediate === 'undefined' ? setTimeout : setImmediate;\n  var asyncQueue = [];\n  var asyncTimer;\n\n  function asyncFlush() {\n    // run promise callbacks\n    for (var i = 0; i < asyncQueue.length; i++) {\n      asyncQueue[i][0](asyncQueue[i][1]);\n    } // reset async asyncQueue\n\n\n    asyncQueue = [];\n    asyncTimer = false;\n  }\n\n  function asyncCall(callback, arg) {\n    asyncQueue.push([callback, arg]);\n\n    if (!asyncTimer) {\n      asyncTimer = true;\n      asyncSetTimer(asyncFlush, 0);\n    }\n  }\n\n  function invokeResolver(resolver, promise) {\n    function resolvePromise(value) {\n      resolve(promise, value);\n    }\n\n    function rejectPromise(reason) {\n      reject(promise, reason);\n    }\n\n    try {\n      resolver(resolvePromise, rejectPromise);\n    } catch (e) {\n      rejectPromise(e);\n    }\n  }\n\n  function invokeCallback(subscriber) {\n    var owner = subscriber.owner;\n    var settled = owner._state;\n    var value = owner._data;\n    var callback = subscriber[settled];\n    var promise = subscriber.then;\n\n    if (typeof callback === 'function') {\n      settled = FULFILLED;\n\n      try {\n        value = callback(value);\n      } catch (e) {\n        reject(promise, e);\n      }\n    }\n\n    if (!handleThenable(promise, value)) {\n      if (settled === FULFILLED) {\n        resolve(promise, value);\n      }\n\n      if (settled === REJECTED) {\n        reject(promise, value);\n      }\n    }\n  }\n\n  function handleThenable(promise, value) {\n    var resolved;\n\n    try {\n      if (promise === value) {\n        throw new TypeError('A promises callback cannot return that same promise.');\n      }\n\n      if (value && (typeof value === 'function' || _typeof(value) === 'object')) {\n        // then should be retrieved only once\n        var then = value.then;\n\n        if (typeof then === 'function') {\n          then.call(value, function (val) {\n            if (!resolved) {\n              resolved = true;\n\n              if (value === val) {\n                fulfill(promise, val);\n              } else {\n                resolve(promise, val);\n              }\n            }\n          }, function (reason) {\n            if (!resolved) {\n              resolved = true;\n              reject(promise, reason);\n            }\n          });\n          return true;\n        }\n      }\n    } catch (e) {\n      if (!resolved) {\n        reject(promise, e);\n      }\n\n      return true;\n    }\n\n    return false;\n  }\n\n  function resolve(promise, value) {\n    if (promise === value || !handleThenable(promise, value)) {\n      fulfill(promise, value);\n    }\n  }\n\n  function fulfill(promise, value) {\n    if (promise._state === PENDING) {\n      promise._state = SETTLED;\n      promise._data = value;\n      asyncCall(publishFulfillment, promise);\n    }\n  }\n\n  function reject(promise, reason) {\n    if (promise._state === PENDING) {\n      promise._state = SETTLED;\n      promise._data = reason;\n      asyncCall(publishRejection, promise);\n    }\n  }\n\n  function publish(promise) {\n    promise._then = promise._then.forEach(invokeCallback);\n  }\n\n  function publishFulfillment(promise) {\n    promise._state = FULFILLED;\n    publish(promise);\n  }\n\n  function publishRejection(promise) {\n    promise._state = REJECTED;\n    publish(promise);\n\n    if (!promise._handled && isNode) {\n      global.process.emit('unhandledRejection', promise._data, promise);\n    }\n  }\n\n  function notifyRejectionHandled(promise) {\n    global.process.emit('rejectionHandled', promise);\n  }\n  /**\n   * @class\n   */\n\n\n  function P(resolver) {\n    if (typeof resolver !== 'function') {\n      throw new TypeError('Promise resolver ' + resolver + ' is not a function');\n    }\n\n    if (this instanceof P === false) {\n      throw new TypeError('Failed to construct \\'Promise\\': Please use the \\'new\\' operator, this object constructor cannot be called as a function.');\n    }\n\n    this._then = [];\n    invokeResolver(resolver, this);\n  }\n\n  P.prototype = {\n    constructor: P,\n    _state: PENDING,\n    _then: null,\n    _data: undefined,\n    _handled: false,\n    then: function then(onFulfillment, onRejection) {\n      var subscriber = {\n        owner: this,\n        then: new this.constructor(NOOP),\n        fulfilled: onFulfillment,\n        rejected: onRejection\n      };\n\n      if ((onRejection || onFulfillment) && !this._handled) {\n        this._handled = true;\n\n        if (this._state === REJECTED && isNode) {\n          asyncCall(notifyRejectionHandled, this);\n        }\n      }\n\n      if (this._state === FULFILLED || this._state === REJECTED) {\n        // already resolved, call callback async\n        asyncCall(invokeCallback, subscriber);\n      } else {\n        // subscribe\n        this._then.push(subscriber);\n      }\n\n      return subscriber.then;\n    },\n    catch: function _catch(onRejection) {\n      return this.then(null, onRejection);\n    }\n  };\n\n  P.all = function (promises) {\n    if (!Array.isArray(promises)) {\n      throw new TypeError('You must pass an array to Promise.all().');\n    }\n\n    return new P(function (resolve, reject) {\n      var results = [];\n      var remaining = 0;\n\n      function resolver(index) {\n        remaining++;\n        return function (value) {\n          results[index] = value;\n\n          if (! --remaining) {\n            resolve(results);\n          }\n        };\n      }\n\n      for (var i = 0, promise; i < promises.length; i++) {\n        promise = promises[i];\n\n        if (promise && typeof promise.then === 'function') {\n          promise.then(resolver(i), reject);\n        } else {\n          results[i] = promise;\n        }\n      }\n\n      if (!remaining) {\n        resolve(results);\n      }\n    });\n  };\n\n  P.race = function (promises) {\n    if (!Array.isArray(promises)) {\n      throw new TypeError('You must pass an array to Promise.race().');\n    }\n\n    return new P(function (resolve, reject) {\n      for (var i = 0, promise; i < promises.length; i++) {\n        promise = promises[i];\n\n        if (promise && typeof promise.then === 'function') {\n          promise.then(resolve, reject);\n        } else {\n          resolve(promise);\n        }\n      }\n    });\n  };\n\n  P.resolve = function (value) {\n    if (value && _typeof(value) === 'object' && value.constructor === P) {\n      return value;\n    }\n\n    return new P(function (resolve) {\n      resolve(value);\n    });\n  };\n\n  P.reject = function (reason) {\n    return new P(function (resolve, reject) {\n      reject(reason);\n    });\n  };\n\n  var picked = typeof Promise === 'function' ? Promise : P;\n\n  var d = UNITS_IN_GRID;\n  var meaninglessTransform = {\n    size: 16,\n    x: 0,\n    y: 0,\n    rotate: 0,\n    flipX: false,\n    flipY: false\n  };\n\n  function isReserved(name) {\n    return ~RESERVED_CLASSES.indexOf(name);\n  }\n  function insertCss(css) {\n    if (!css || !IS_DOM) {\n      return;\n    }\n\n    var style = DOCUMENT.createElement('style');\n    style.setAttribute('type', 'text/css');\n    style.innerHTML = css;\n    var headChildren = DOCUMENT.head.childNodes;\n    var beforeChild = null;\n\n    for (var i = headChildren.length - 1; i > -1; i--) {\n      var child = headChildren[i];\n      var tagName = (child.tagName || '').toUpperCase();\n\n      if (['STYLE', 'LINK'].indexOf(tagName) > -1) {\n        beforeChild = child;\n      }\n    }\n\n    DOCUMENT.head.insertBefore(style, beforeChild);\n    return css;\n  }\n  var idPool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';\n  function nextUniqueId() {\n    var size = 12;\n    var id = '';\n\n    while (size-- > 0) {\n      id += idPool[Math.random() * 62 | 0];\n    }\n\n    return id;\n  }\n  function toArray(obj) {\n    var array = [];\n\n    for (var i = (obj || []).length >>> 0; i--;) {\n      array[i] = obj[i];\n    }\n\n    return array;\n  }\n  function classArray(node) {\n    if (node.classList) {\n      return toArray(node.classList);\n    } else {\n      return (node.getAttribute('class') || '').split(' ').filter(function (i) {\n        return i;\n      });\n    }\n  }\n  function getIconName(familyPrefix, cls) {\n    var parts = cls.split('-');\n    var prefix = parts[0];\n    var iconName = parts.slice(1).join('-');\n\n    if (prefix === familyPrefix && iconName !== '' && !isReserved(iconName)) {\n      return iconName;\n    } else {\n      return null;\n    }\n  }\n  function htmlEscape(str) {\n    return \"\".concat(str).replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n  }\n  function joinAttributes(attributes) {\n    return Object.keys(attributes || {}).reduce(function (acc, attributeName) {\n      return acc + \"\".concat(attributeName, \"=\\\"\").concat(htmlEscape(attributes[attributeName]), \"\\\" \");\n    }, '').trim();\n  }\n  function joinStyles(styles) {\n    return Object.keys(styles || {}).reduce(function (acc, styleName) {\n      return acc + \"\".concat(styleName, \": \").concat(styles[styleName], \";\");\n    }, '');\n  }\n  function transformIsMeaningful(transform) {\n    return transform.size !== meaninglessTransform.size || transform.x !== meaninglessTransform.x || transform.y !== meaninglessTransform.y || transform.rotate !== meaninglessTransform.rotate || transform.flipX || transform.flipY;\n  }\n  function transformForSvg(_ref) {\n    var transform = _ref.transform,\n        containerWidth = _ref.containerWidth,\n        iconWidth = _ref.iconWidth;\n    var outer = {\n      transform: \"translate(\".concat(containerWidth / 2, \" 256)\")\n    };\n    var innerTranslate = \"translate(\".concat(transform.x * 32, \", \").concat(transform.y * 32, \") \");\n    var innerScale = \"scale(\".concat(transform.size / 16 * (transform.flipX ? -1 : 1), \", \").concat(transform.size / 16 * (transform.flipY ? -1 : 1), \") \");\n    var innerRotate = \"rotate(\".concat(transform.rotate, \" 0 0)\");\n    var inner = {\n      transform: \"\".concat(innerTranslate, \" \").concat(innerScale, \" \").concat(innerRotate)\n    };\n    var path = {\n      transform: \"translate(\".concat(iconWidth / 2 * -1, \" -256)\")\n    };\n    return {\n      outer: outer,\n      inner: inner,\n      path: path\n    };\n  }\n  function transformForCss(_ref2) {\n    var transform = _ref2.transform,\n        _ref2$width = _ref2.width,\n        width = _ref2$width === void 0 ? UNITS_IN_GRID : _ref2$width,\n        _ref2$height = _ref2.height,\n        height = _ref2$height === void 0 ? UNITS_IN_GRID : _ref2$height,\n        _ref2$startCentered = _ref2.startCentered,\n        startCentered = _ref2$startCentered === void 0 ? false : _ref2$startCentered;\n    var val = '';\n\n    if (startCentered && IS_IE) {\n      val += \"translate(\".concat(transform.x / d - width / 2, \"em, \").concat(transform.y / d - height / 2, \"em) \");\n    } else if (startCentered) {\n      val += \"translate(calc(-50% + \".concat(transform.x / d, \"em), calc(-50% + \").concat(transform.y / d, \"em)) \");\n    } else {\n      val += \"translate(\".concat(transform.x / d, \"em, \").concat(transform.y / d, \"em) \");\n    }\n\n    val += \"scale(\".concat(transform.size / d * (transform.flipX ? -1 : 1), \", \").concat(transform.size / d * (transform.flipY ? -1 : 1), \") \");\n    val += \"rotate(\".concat(transform.rotate, \"deg) \");\n    return val;\n  }\n\n  var ALL_SPACE = {\n    x: 0,\n    y: 0,\n    width: '100%',\n    height: '100%'\n  };\n\n  function fillBlack(abstract) {\n    var force = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n\n    if (abstract.attributes && (abstract.attributes.fill || force)) {\n      abstract.attributes.fill = 'black';\n    }\n\n    return abstract;\n  }\n\n  function deGroup(abstract) {\n    if (abstract.tag === 'g') {\n      return abstract.children;\n    } else {\n      return [abstract];\n    }\n  }\n\n  function makeIconMasking (_ref) {\n    var children = _ref.children,\n        attributes = _ref.attributes,\n        main = _ref.main,\n        mask = _ref.mask,\n        explicitMaskId = _ref.maskId,\n        transform = _ref.transform;\n    var mainWidth = main.width,\n        mainPath = main.icon;\n    var maskWidth = mask.width,\n        maskPath = mask.icon;\n    var trans = transformForSvg({\n      transform: transform,\n      containerWidth: maskWidth,\n      iconWidth: mainWidth\n    });\n    var maskRect = {\n      tag: 'rect',\n      attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n        fill: 'white'\n      })\n    };\n    var maskInnerGroupChildrenMixin = mainPath.children ? {\n      children: mainPath.children.map(fillBlack)\n    } : {};\n    var maskInnerGroup = {\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.inner),\n      children: [fillBlack(_objectSpread2({\n        tag: mainPath.tag,\n        attributes: _objectSpread2(_objectSpread2({}, mainPath.attributes), trans.path)\n      }, maskInnerGroupChildrenMixin))]\n    };\n    var maskOuterGroup = {\n      tag: 'g',\n      attributes: _objectSpread2({}, trans.outer),\n      children: [maskInnerGroup]\n    };\n    var maskId = \"mask-\".concat(explicitMaskId || nextUniqueId());\n    var clipId = \"clip-\".concat(explicitMaskId || nextUniqueId());\n    var maskTag = {\n      tag: 'mask',\n      attributes: _objectSpread2(_objectSpread2({}, ALL_SPACE), {}, {\n        id: maskId,\n        maskUnits: 'userSpaceOnUse',\n        maskContentUnits: 'userSpaceOnUse'\n      }),\n      children: [maskRect, maskOuterGroup]\n    };\n    var defs = {\n      tag: 'defs',\n      children: [{\n        tag: 'clipPath',\n        attributes: {\n          id: clipId\n        },\n        children: deGroup(maskPath)\n      }, maskTag]\n    };\n    children.push(defs, {\n      tag: 'rect',\n      attributes: _objectSpread2({\n        fill: 'currentColor',\n        'clip-path': \"url(#\".concat(clipId, \")\"),\n        mask: \"url(#\".concat(maskId, \")\")\n      }, ALL_SPACE)\n    });\n    return {\n      children: children,\n      attributes: attributes\n    };\n  }\n\n  function makeIconStandard (_ref) {\n    var children = _ref.children,\n        attributes = _ref.attributes,\n        main = _ref.main,\n        transform = _ref.transform,\n        styles = _ref.styles;\n    var styleString = joinStyles(styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    if (transformIsMeaningful(transform)) {\n      var trans = transformForSvg({\n        transform: transform,\n        containerWidth: main.width,\n        iconWidth: main.width\n      });\n      children.push({\n        tag: 'g',\n        attributes: _objectSpread2({}, trans.outer),\n        children: [{\n          tag: 'g',\n          attributes: _objectSpread2({}, trans.inner),\n          children: [{\n            tag: main.icon.tag,\n            children: main.icon.children,\n            attributes: _objectSpread2(_objectSpread2({}, main.icon.attributes), trans.path)\n          }]\n        }]\n      });\n    } else {\n      children.push(main.icon);\n    }\n\n    return {\n      children: children,\n      attributes: attributes\n    };\n  }\n\n  function asIcon (_ref) {\n    var children = _ref.children,\n        main = _ref.main,\n        mask = _ref.mask,\n        attributes = _ref.attributes,\n        styles = _ref.styles,\n        transform = _ref.transform;\n\n    if (transformIsMeaningful(transform) && main.found && !mask.found) {\n      var width = main.width,\n          height = main.height;\n      var offset = {\n        x: width / height / 2,\n        y: 0.5\n      };\n      attributes['style'] = joinStyles(_objectSpread2(_objectSpread2({}, styles), {}, {\n        'transform-origin': \"\".concat(offset.x + transform.x / 16, \"em \").concat(offset.y + transform.y / 16, \"em\")\n      }));\n    }\n\n    return [{\n      tag: 'svg',\n      attributes: attributes,\n      children: children\n    }];\n  }\n\n  function asSymbol (_ref) {\n    var prefix = _ref.prefix,\n        iconName = _ref.iconName,\n        children = _ref.children,\n        attributes = _ref.attributes,\n        symbol = _ref.symbol;\n    var id = symbol === true ? \"\".concat(prefix, \"-\").concat(config.familyPrefix, \"-\").concat(iconName) : symbol;\n    return [{\n      tag: 'svg',\n      attributes: {\n        style: 'display: none;'\n      },\n      children: [{\n        tag: 'symbol',\n        attributes: _objectSpread2(_objectSpread2({}, attributes), {}, {\n          id: id\n        }),\n        children: children\n      }]\n    }];\n  }\n\n  function makeInlineSvgAbstract(params) {\n    var _params$icons = params.icons,\n        main = _params$icons.main,\n        mask = _params$icons.mask,\n        prefix = params.prefix,\n        iconName = params.iconName,\n        transform = params.transform,\n        symbol = params.symbol,\n        title = params.title,\n        maskId = params.maskId,\n        titleId = params.titleId,\n        extra = params.extra,\n        _params$watchable = params.watchable,\n        watchable = _params$watchable === void 0 ? false : _params$watchable;\n\n    var _ref = mask.found ? mask : main,\n        width = _ref.width,\n        height = _ref.height;\n\n    var isUploadedIcon = prefix === 'fak';\n    var widthClass = isUploadedIcon ? '' : \"fa-w-\".concat(Math.ceil(width / height * 16));\n    var attrClass = [config.replacementClass, iconName ? \"\".concat(config.familyPrefix, \"-\").concat(iconName) : '', widthClass].filter(function (c) {\n      return extra.classes.indexOf(c) === -1;\n    }).filter(function (c) {\n      return c !== '' || !!c;\n    }).concat(extra.classes).join(' ');\n    var content = {\n      children: [],\n      attributes: _objectSpread2(_objectSpread2({}, extra.attributes), {}, {\n        'data-prefix': prefix,\n        'data-icon': iconName,\n        'class': attrClass,\n        'role': extra.attributes.role || 'img',\n        'xmlns': 'http://www.w3.org/2000/svg',\n        'viewBox': \"0 0 \".concat(width, \" \").concat(height)\n      })\n    };\n    var uploadedIconWidthStyle = isUploadedIcon && !~extra.classes.indexOf('fa-fw') ? {\n      width: \"\".concat(width / height * 16 * 0.0625, \"em\")\n    } : {};\n\n    if (watchable) {\n      content.attributes[DATA_FA_I2SVG] = '';\n    }\n\n    if (title) content.children.push({\n      tag: 'title',\n      attributes: {\n        id: content.attributes['aria-labelledby'] || \"title-\".concat(titleId || nextUniqueId())\n      },\n      children: [title]\n    });\n\n    var args = _objectSpread2(_objectSpread2({}, content), {}, {\n      prefix: prefix,\n      iconName: iconName,\n      main: main,\n      mask: mask,\n      maskId: maskId,\n      transform: transform,\n      symbol: symbol,\n      styles: _objectSpread2(_objectSpread2({}, uploadedIconWidthStyle), extra.styles)\n    });\n\n    var _ref2 = mask.found && main.found ? makeIconMasking(args) : makeIconStandard(args),\n        children = _ref2.children,\n        attributes = _ref2.attributes;\n\n    args.children = children;\n    args.attributes = attributes;\n\n    if (symbol) {\n      return asSymbol(args);\n    } else {\n      return asIcon(args);\n    }\n  }\n  function makeLayersTextAbstract(params) {\n    var content = params.content,\n        width = params.width,\n        height = params.height,\n        transform = params.transform,\n        title = params.title,\n        extra = params.extra,\n        _params$watchable2 = params.watchable,\n        watchable = _params$watchable2 === void 0 ? false : _params$watchable2;\n\n    var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n      'title': title\n    } : {}), {}, {\n      'class': extra.classes.join(' ')\n    });\n\n    if (watchable) {\n      attributes[DATA_FA_I2SVG] = '';\n    }\n\n    var styles = _objectSpread2({}, extra.styles);\n\n    if (transformIsMeaningful(transform)) {\n      styles['transform'] = transformForCss({\n        transform: transform,\n        startCentered: true,\n        width: width,\n        height: height\n      });\n      styles['-webkit-transform'] = styles['transform'];\n    }\n\n    var styleString = joinStyles(styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    var val = [];\n    val.push({\n      tag: 'span',\n      attributes: attributes,\n      children: [content]\n    });\n\n    if (title) {\n      val.push({\n        tag: 'span',\n        attributes: {\n          class: 'sr-only'\n        },\n        children: [title]\n      });\n    }\n\n    return val;\n  }\n  function makeLayersCounterAbstract(params) {\n    var content = params.content,\n        title = params.title,\n        extra = params.extra;\n\n    var attributes = _objectSpread2(_objectSpread2(_objectSpread2({}, extra.attributes), title ? {\n      'title': title\n    } : {}), {}, {\n      'class': extra.classes.join(' ')\n    });\n\n    var styleString = joinStyles(extra.styles);\n\n    if (styleString.length > 0) {\n      attributes['style'] = styleString;\n    }\n\n    var val = [];\n    val.push({\n      tag: 'span',\n      attributes: attributes,\n      children: [content]\n    });\n\n    if (title) {\n      val.push({\n        tag: 'span',\n        attributes: {\n          class: 'sr-only'\n        },\n        children: [title]\n      });\n    }\n\n    return val;\n  }\n\n  var noop$1 = function noop() {};\n\n  var p = config.measurePerformance && PERFORMANCE && PERFORMANCE.mark && PERFORMANCE.measure ? PERFORMANCE : {\n    mark: noop$1,\n    measure: noop$1\n  };\n  var preamble = \"FA \\\"5.15.4\\\"\";\n\n  var begin = function begin(name) {\n    p.mark(\"\".concat(preamble, \" \").concat(name, \" begins\"));\n    return function () {\n      return end(name);\n    };\n  };\n\n  var end = function end(name) {\n    p.mark(\"\".concat(preamble, \" \").concat(name, \" ends\"));\n    p.measure(\"\".concat(preamble, \" \").concat(name), \"\".concat(preamble, \" \").concat(name, \" begins\"), \"\".concat(preamble, \" \").concat(name, \" ends\"));\n  };\n\n  var perf = {\n    begin: begin,\n    end: end\n  };\n\n  /**\n   * Internal helper to bind a function known to have 4 arguments\n   * to a given context.\n   */\n\n  var bindInternal4 = function bindInternal4(func, thisContext) {\n    return function (a, b, c, d) {\n      return func.call(thisContext, a, b, c, d);\n    };\n  };\n\n  /**\n   * # Reduce\n   *\n   * A fast object `.reduce()` implementation.\n   *\n   * @param  {Object}   subject      The object to reduce over.\n   * @param  {Function} fn           The reducer function.\n   * @param  {mixed}    initialValue The initial value for the reducer, defaults to subject[0].\n   * @param  {Object}   thisContext  The context for the reducer.\n   * @return {mixed}                 The final result.\n   */\n\n\n  var reduce = function fastReduceObject(subject, fn, initialValue, thisContext) {\n    var keys = Object.keys(subject),\n        length = keys.length,\n        iterator = thisContext !== undefined ? bindInternal4(fn, thisContext) : fn,\n        i,\n        key,\n        result;\n\n    if (initialValue === undefined) {\n      i = 1;\n      result = subject[keys[0]];\n    } else {\n      i = 0;\n      result = initialValue;\n    }\n\n    for (; i < length; i++) {\n      key = keys[i];\n      result = iterator(result, subject[key], key, subject);\n    }\n\n    return result;\n  };\n\n  function toHex(unicode) {\n    var result = '';\n\n    for (var i = 0; i < unicode.length; i++) {\n      var hex = unicode.charCodeAt(i).toString(16);\n      result += ('000' + hex).slice(-4);\n    }\n\n    return result;\n  }\n\n  function defineIcons(prefix, icons) {\n    var params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n    var _params$skipHooks = params.skipHooks,\n        skipHooks = _params$skipHooks === void 0 ? false : _params$skipHooks;\n    var normalized = Object.keys(icons).reduce(function (acc, iconName) {\n      var icon = icons[iconName];\n      var expanded = !!icon.icon;\n\n      if (expanded) {\n        acc[icon.iconName] = icon.icon;\n      } else {\n        acc[iconName] = icon;\n      }\n\n      return acc;\n    }, {});\n\n    if (typeof namespace.hooks.addPack === 'function' && !skipHooks) {\n      namespace.hooks.addPack(prefix, normalized);\n    } else {\n      namespace.styles[prefix] = _objectSpread2(_objectSpread2({}, namespace.styles[prefix] || {}), normalized);\n    }\n    /**\n     * Font Awesome 4 used the prefix of `fa` for all icons. With the introduction\n     * of new styles we needed to differentiate between them. Prefix `fa` is now an alias\n     * for `fas` so we'll easy the upgrade process for our users by automatically defining\n     * this as well.\n     */\n\n\n    if (prefix === 'fas') {\n      defineIcons('fa', icons);\n    }\n  }\n\n  var styles = namespace.styles,\n      shims = namespace.shims;\n  var _byUnicode = {};\n  var _byLigature = {};\n  var _byOldName = {};\n  var build = function build() {\n    var lookup = function lookup(reducer) {\n      return reduce(styles, function (o, style, prefix) {\n        o[prefix] = reduce(style, reducer, {});\n        return o;\n      }, {});\n    };\n\n    _byUnicode = lookup(function (acc, icon, iconName) {\n      if (icon[3]) {\n        acc[icon[3]] = iconName;\n      }\n\n      return acc;\n    });\n    _byLigature = lookup(function (acc, icon, iconName) {\n      var ligatures = icon[2];\n      acc[iconName] = iconName;\n      ligatures.forEach(function (ligature) {\n        acc[ligature] = iconName;\n      });\n      return acc;\n    });\n    var hasRegular = ('far' in styles);\n    _byOldName = reduce(shims, function (acc, shim) {\n      var oldName = shim[0];\n      var prefix = shim[1];\n      var iconName = shim[2];\n\n      if (prefix === 'far' && !hasRegular) {\n        prefix = 'fas';\n      }\n\n      acc[oldName] = {\n        prefix: prefix,\n        iconName: iconName\n      };\n      return acc;\n    }, {});\n  };\n  build();\n  function byUnicode(prefix, unicode) {\n    return (_byUnicode[prefix] || {})[unicode];\n  }\n  function byLigature(prefix, ligature) {\n    return (_byLigature[prefix] || {})[ligature];\n  }\n  function byOldName(name) {\n    return _byOldName[name] || {\n      prefix: null,\n      iconName: null\n    };\n  }\n\n  var styles$1 = namespace.styles;\n  var emptyCanonicalIcon = function emptyCanonicalIcon() {\n    return {\n      prefix: null,\n      iconName: null,\n      rest: []\n    };\n  };\n  function getCanonicalIcon(values) {\n    return values.reduce(function (acc, cls) {\n      var iconName = getIconName(config.familyPrefix, cls);\n\n      if (styles$1[cls]) {\n        acc.prefix = cls;\n      } else if (config.autoFetchSvg && Object.keys(PREFIX_TO_STYLE).indexOf(cls) > -1) {\n        acc.prefix = cls;\n      } else if (iconName) {\n        var shim = acc.prefix === 'fa' ? byOldName(iconName) : {};\n        acc.iconName = shim.iconName || iconName;\n        acc.prefix = shim.prefix || acc.prefix;\n      } else if (cls !== config.replacementClass && cls.indexOf('fa-w-') !== 0) {\n        acc.rest.push(cls);\n      }\n\n      return acc;\n    }, emptyCanonicalIcon());\n  }\n  function iconFromMapping(mapping, prefix, iconName) {\n    if (mapping && mapping[prefix] && mapping[prefix][iconName]) {\n      return {\n        prefix: prefix,\n        iconName: iconName,\n        icon: mapping[prefix][iconName]\n      };\n    }\n  }\n\n  function toHtml(abstractNodes) {\n    var tag = abstractNodes.tag,\n        _abstractNodes$attrib = abstractNodes.attributes,\n        attributes = _abstractNodes$attrib === void 0 ? {} : _abstractNodes$attrib,\n        _abstractNodes$childr = abstractNodes.children,\n        children = _abstractNodes$childr === void 0 ? [] : _abstractNodes$childr;\n\n    if (typeof abstractNodes === 'string') {\n      return htmlEscape(abstractNodes);\n    } else {\n      return \"<\".concat(tag, \" \").concat(joinAttributes(attributes), \">\").concat(children.map(toHtml).join(''), \"</\").concat(tag, \">\");\n    }\n  }\n\n  var noop$2 = function noop() {};\n\n  function isWatched(node) {\n    var i2svg = node.getAttribute ? node.getAttribute(DATA_FA_I2SVG) : null;\n    return typeof i2svg === 'string';\n  }\n\n  function getMutator() {\n    if (config.autoReplaceSvg === true) {\n      return mutators.replace;\n    }\n\n    var mutator = mutators[config.autoReplaceSvg];\n    return mutator || mutators.replace;\n  }\n\n  var mutators = {\n    replace: function replace(mutation) {\n      var node = mutation[0];\n      var abstract = mutation[1];\n      var newOuterHTML = abstract.map(function (a) {\n        return toHtml(a);\n      }).join('\\n');\n\n      if (node.parentNode && node.outerHTML) {\n        node.outerHTML = newOuterHTML + (config.keepOriginalSource && node.tagName.toLowerCase() !== 'svg' ? \"<!-- \".concat(node.outerHTML, \" Font Awesome fontawesome.com -->\") : '');\n      } else if (node.parentNode) {\n        var newNode = document.createElement('span');\n        node.parentNode.replaceChild(newNode, node);\n        newNode.outerHTML = newOuterHTML;\n      }\n    },\n    nest: function nest(mutation) {\n      var node = mutation[0];\n      var abstract = mutation[1]; // If we already have a replaced node we do not want to continue nesting within it.\n      // Short-circuit to the standard replacement\n\n      if (~classArray(node).indexOf(config.replacementClass)) {\n        return mutators.replace(mutation);\n      }\n\n      var forSvg = new RegExp(\"\".concat(config.familyPrefix, \"-.*\"));\n      delete abstract[0].attributes.style;\n      delete abstract[0].attributes.id;\n      var splitClasses = abstract[0].attributes.class.split(' ').reduce(function (acc, cls) {\n        if (cls === config.replacementClass || cls.match(forSvg)) {\n          acc.toSvg.push(cls);\n        } else {\n          acc.toNode.push(cls);\n        }\n\n        return acc;\n      }, {\n        toNode: [],\n        toSvg: []\n      });\n      abstract[0].attributes.class = splitClasses.toSvg.join(' ');\n      var newInnerHTML = abstract.map(function (a) {\n        return toHtml(a);\n      }).join('\\n');\n      node.setAttribute('class', splitClasses.toNode.join(' '));\n      node.setAttribute(DATA_FA_I2SVG, '');\n      node.innerHTML = newInnerHTML;\n    }\n  };\n\n  function performOperationSync(op) {\n    op();\n  }\n\n  function perform(mutations, callback) {\n    var callbackFunction = typeof callback === 'function' ? callback : noop$2;\n\n    if (mutations.length === 0) {\n      callbackFunction();\n    } else {\n      var frame = performOperationSync;\n\n      if (config.mutateApproach === MUTATION_APPROACH_ASYNC) {\n        frame = WINDOW.requestAnimationFrame || performOperationSync;\n      }\n\n      frame(function () {\n        var mutator = getMutator();\n        var mark = perf.begin('mutate');\n        mutations.map(mutator);\n        mark();\n        callbackFunction();\n      });\n    }\n  }\n  var disabled = false;\n  function disableObservation() {\n    disabled = true;\n  }\n  function enableObservation() {\n    disabled = false;\n  }\n  var mo = null;\n  function observe(options) {\n    if (!MUTATION_OBSERVER) {\n      return;\n    }\n\n    if (!config.observeMutations) {\n      return;\n    }\n\n    var treeCallback = options.treeCallback,\n        nodeCallback = options.nodeCallback,\n        pseudoElementsCallback = options.pseudoElementsCallback,\n        _options$observeMutat = options.observeMutationsRoot,\n        observeMutationsRoot = _options$observeMutat === void 0 ? DOCUMENT : _options$observeMutat;\n    mo = new MUTATION_OBSERVER(function (objects) {\n      if (disabled) return;\n      toArray(objects).forEach(function (mutationRecord) {\n        if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0 && !isWatched(mutationRecord.addedNodes[0])) {\n          if (config.searchPseudoElements) {\n            pseudoElementsCallback(mutationRecord.target);\n          }\n\n          treeCallback(mutationRecord.target);\n        }\n\n        if (mutationRecord.type === 'attributes' && mutationRecord.target.parentNode && config.searchPseudoElements) {\n          pseudoElementsCallback(mutationRecord.target.parentNode);\n        }\n\n        if (mutationRecord.type === 'attributes' && isWatched(mutationRecord.target) && ~ATTRIBUTES_WATCHED_FOR_MUTATION.indexOf(mutationRecord.attributeName)) {\n          if (mutationRecord.attributeName === 'class') {\n            var _getCanonicalIcon = getCanonicalIcon(classArray(mutationRecord.target)),\n                prefix = _getCanonicalIcon.prefix,\n                iconName = _getCanonicalIcon.iconName;\n\n            if (prefix) mutationRecord.target.setAttribute('data-prefix', prefix);\n            if (iconName) mutationRecord.target.setAttribute('data-icon', iconName);\n          } else {\n            nodeCallback(mutationRecord.target);\n          }\n        }\n      });\n    });\n    if (!IS_DOM) return;\n    mo.observe(observeMutationsRoot, {\n      childList: true,\n      attributes: true,\n      characterData: true,\n      subtree: true\n    });\n  }\n  function disconnect() {\n    if (!mo) return;\n    mo.disconnect();\n  }\n\n  function styleParser (node) {\n    var style = node.getAttribute('style');\n    var val = [];\n\n    if (style) {\n      val = style.split(';').reduce(function (acc, style) {\n        var styles = style.split(':');\n        var prop = styles[0];\n        var value = styles.slice(1);\n\n        if (prop && value.length > 0) {\n          acc[prop] = value.join(':').trim();\n        }\n\n        return acc;\n      }, {});\n    }\n\n    return val;\n  }\n\n  function classParser (node) {\n    var existingPrefix = node.getAttribute('data-prefix');\n    var existingIconName = node.getAttribute('data-icon');\n    var innerText = node.innerText !== undefined ? node.innerText.trim() : '';\n    var val = getCanonicalIcon(classArray(node));\n\n    if (existingPrefix && existingIconName) {\n      val.prefix = existingPrefix;\n      val.iconName = existingIconName;\n    }\n\n    if (val.prefix && innerText.length > 1) {\n      val.iconName = byLigature(val.prefix, node.innerText);\n    } else if (val.prefix && innerText.length === 1) {\n      val.iconName = byUnicode(val.prefix, toHex(node.innerText));\n    }\n\n    return val;\n  }\n\n  var parseTransformString = function parseTransformString(transformString) {\n    var transform = {\n      size: 16,\n      x: 0,\n      y: 0,\n      flipX: false,\n      flipY: false,\n      rotate: 0\n    };\n\n    if (!transformString) {\n      return transform;\n    } else {\n      return transformString.toLowerCase().split(' ').reduce(function (acc, n) {\n        var parts = n.toLowerCase().split('-');\n        var first = parts[0];\n        var rest = parts.slice(1).join('-');\n\n        if (first && rest === 'h') {\n          acc.flipX = true;\n          return acc;\n        }\n\n        if (first && rest === 'v') {\n          acc.flipY = true;\n          return acc;\n        }\n\n        rest = parseFloat(rest);\n\n        if (isNaN(rest)) {\n          return acc;\n        }\n\n        switch (first) {\n          case 'grow':\n            acc.size = acc.size + rest;\n            break;\n\n          case 'shrink':\n            acc.size = acc.size - rest;\n            break;\n\n          case 'left':\n            acc.x = acc.x - rest;\n            break;\n\n          case 'right':\n            acc.x = acc.x + rest;\n            break;\n\n          case 'up':\n            acc.y = acc.y - rest;\n            break;\n\n          case 'down':\n            acc.y = acc.y + rest;\n            break;\n\n          case 'rotate':\n            acc.rotate = acc.rotate + rest;\n            break;\n        }\n\n        return acc;\n      }, transform);\n    }\n  };\n  function transformParser (node) {\n    return parseTransformString(node.getAttribute('data-fa-transform'));\n  }\n\n  function symbolParser (node) {\n    var symbol = node.getAttribute('data-fa-symbol');\n    return symbol === null ? false : symbol === '' ? true : symbol;\n  }\n\n  function attributesParser (node) {\n    var extraAttributes = toArray(node.attributes).reduce(function (acc, attr) {\n      if (acc.name !== 'class' && acc.name !== 'style') {\n        acc[attr.name] = attr.value;\n      }\n\n      return acc;\n    }, {});\n    var title = node.getAttribute('title');\n    var titleId = node.getAttribute('data-fa-title-id');\n\n    if (config.autoA11y) {\n      if (title) {\n        extraAttributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n      } else {\n        extraAttributes['aria-hidden'] = 'true';\n        extraAttributes['focusable'] = 'false';\n      }\n    }\n\n    return extraAttributes;\n  }\n\n  function maskParser (node) {\n    var mask = node.getAttribute('data-fa-mask');\n\n    if (!mask) {\n      return emptyCanonicalIcon();\n    } else {\n      return getCanonicalIcon(mask.split(' ').map(function (i) {\n        return i.trim();\n      }));\n    }\n  }\n\n  function blankMeta() {\n    return {\n      iconName: null,\n      title: null,\n      titleId: null,\n      prefix: null,\n      transform: meaninglessTransform,\n      symbol: false,\n      mask: null,\n      maskId: null,\n      extra: {\n        classes: [],\n        styles: {},\n        attributes: {}\n      }\n    };\n  }\n  function parseMeta(node) {\n    var _classParser = classParser(node),\n        iconName = _classParser.iconName,\n        prefix = _classParser.prefix,\n        extraClasses = _classParser.rest;\n\n    var extraStyles = styleParser(node);\n    var transform = transformParser(node);\n    var symbol = symbolParser(node);\n    var extraAttributes = attributesParser(node);\n    var mask = maskParser(node);\n    return {\n      iconName: iconName,\n      title: node.getAttribute('title'),\n      titleId: node.getAttribute('data-fa-title-id'),\n      prefix: prefix,\n      transform: transform,\n      symbol: symbol,\n      mask: mask,\n      maskId: node.getAttribute('data-fa-mask-id'),\n      extra: {\n        classes: extraClasses,\n        styles: extraStyles,\n        attributes: extraAttributes\n      }\n    };\n  }\n\n  function MissingIcon(error) {\n    this.name = 'MissingIcon';\n    this.message = error || 'Icon unavailable';\n    this.stack = new Error().stack;\n  }\n  MissingIcon.prototype = Object.create(Error.prototype);\n  MissingIcon.prototype.constructor = MissingIcon;\n\n  var FILL = {\n    fill: 'currentColor'\n  };\n  var ANIMATION_BASE = {\n    attributeType: 'XML',\n    repeatCount: 'indefinite',\n    dur: '2s'\n  };\n  var RING = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      d: 'M156.5,447.7l-12.6,29.5c-18.7-9.5-35.9-21.2-51.5-34.9l22.7-22.7C127.6,430.5,141.5,440,156.5,447.7z M40.6,272H8.5 c1.4,21.2,5.4,41.7,11.7,61.1L50,321.2C45.1,305.5,41.8,289,40.6,272z M40.6,240c1.4-18.8,5.2-37,11.1-54.1l-29.5-12.6 C14.7,194.3,10,216.7,8.5,240H40.6z M64.3,156.5c7.8-14.9,17.2-28.8,28.1-41.5L69.7,92.3c-13.7,15.6-25.5,32.8-34.9,51.5 L64.3,156.5z M397,419.6c-13.9,12-29.4,22.3-46.1,30.4l11.9,29.8c20.7-9.9,39.8-22.6,56.9-37.6L397,419.6z M115,92.4 c13.9-12,29.4-22.3,46.1-30.4l-11.9-29.8c-20.7,9.9-39.8,22.6-56.8,37.6L115,92.4z M447.7,355.5c-7.8,14.9-17.2,28.8-28.1,41.5 l22.7,22.7c13.7-15.6,25.5-32.9,34.9-51.5L447.7,355.5z M471.4,272c-1.4,18.8-5.2,37-11.1,54.1l29.5,12.6 c7.5-21.1,12.2-43.5,13.6-66.8H471.4z M321.2,462c-15.7,5-32.2,8.2-49.2,9.4v32.1c21.2-1.4,41.7-5.4,61.1-11.7L321.2,462z M240,471.4c-18.8-1.4-37-5.2-54.1-11.1l-12.6,29.5c21.1,7.5,43.5,12.2,66.8,13.6V471.4z M462,190.8c5,15.7,8.2,32.2,9.4,49.2h32.1 c-1.4-21.2-5.4-41.7-11.7-61.1L462,190.8z M92.4,397c-12-13.9-22.3-29.4-30.4-46.1l-29.8,11.9c9.9,20.7,22.6,39.8,37.6,56.9 L92.4,397z M272,40.6c18.8,1.4,36.9,5.2,54.1,11.1l12.6-29.5C317.7,14.7,295.3,10,272,8.5V40.6z M190.8,50 c15.7-5,32.2-8.2,49.2-9.4V8.5c-21.2,1.4-41.7,5.4-61.1,11.7L190.8,50z M442.3,92.3L419.6,115c12,13.9,22.3,29.4,30.5,46.1 l29.8-11.9C470,128.5,457.3,109.4,442.3,92.3z M397,92.4l22.7-22.7c-15.6-13.7-32.8-25.5-51.5-34.9l-12.6,29.5 C370.4,72.1,384.4,81.5,397,92.4z'\n    })\n  };\n\n  var OPACITY_ANIMATE = _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n    attributeName: 'opacity'\n  });\n\n  var DOT = {\n    tag: 'circle',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      cx: '256',\n      cy: '364',\n      r: '28'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, ANIMATION_BASE), {}, {\n        attributeName: 'r',\n        values: '28;14;28;28;14;28;'\n      })\n    }, {\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '1;0;1;1;0;1;'\n      })\n    }]\n  };\n  var QUESTION = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      opacity: '1',\n      d: 'M263.7,312h-16c-6.6,0-12-5.4-12-12c0-71,77.4-63.9,77.4-107.8c0-20-17.8-40.2-57.4-40.2c-29.1,0-44.3,9.6-59.2,28.7 c-3.9,5-11.1,6-16.2,2.4l-13.1-9.2c-5.6-3.9-6.9-11.8-2.6-17.2c21.2-27.2,46.4-44.7,91.2-44.7c52.3,0,97.4,29.8,97.4,80.2 c0,67.6-77.4,63.5-77.4,107.8C275.7,306.6,270.3,312,263.7,312z'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '1;0;0;0;0;1;'\n      })\n    }]\n  };\n  var EXCLAMATION = {\n    tag: 'path',\n    attributes: _objectSpread2(_objectSpread2({}, FILL), {}, {\n      opacity: '0',\n      d: 'M232.5,134.5l7,168c0.3,6.4,5.6,11.5,12,11.5h9c6.4,0,11.7-5.1,12-11.5l7-168c0.3-6.8-5.2-12.5-12-12.5h-23 C237.7,122,232.2,127.7,232.5,134.5z'\n    }),\n    children: [{\n      tag: 'animate',\n      attributes: _objectSpread2(_objectSpread2({}, OPACITY_ANIMATE), {}, {\n        values: '0;0;1;1;0;0;'\n      })\n    }]\n  };\n  var missing = {\n    tag: 'g',\n    children: [RING, DOT, QUESTION, EXCLAMATION]\n  };\n\n  var styles$2 = namespace.styles;\n  function asFoundIcon(icon) {\n    var width = icon[0];\n    var height = icon[1];\n\n    var _icon$slice = icon.slice(4),\n        _icon$slice2 = _slicedToArray(_icon$slice, 1),\n        vectorData = _icon$slice2[0];\n\n    var element = null;\n\n    if (Array.isArray(vectorData)) {\n      element = {\n        tag: 'g',\n        attributes: {\n          class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.GROUP)\n        },\n        children: [{\n          tag: 'path',\n          attributes: {\n            class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.SECONDARY),\n            fill: 'currentColor',\n            d: vectorData[0]\n          }\n        }, {\n          tag: 'path',\n          attributes: {\n            class: \"\".concat(config.familyPrefix, \"-\").concat(DUOTONE_CLASSES.PRIMARY),\n            fill: 'currentColor',\n            d: vectorData[1]\n          }\n        }]\n      };\n    } else {\n      element = {\n        tag: 'path',\n        attributes: {\n          fill: 'currentColor',\n          d: vectorData\n        }\n      };\n    }\n\n    return {\n      found: true,\n      width: width,\n      height: height,\n      icon: element\n    };\n  }\n  function findIcon(iconName, prefix) {\n    return new picked(function (resolve, reject) {\n      var val = {\n        found: false,\n        width: 512,\n        height: 512,\n        icon: missing\n      };\n\n      if (iconName && prefix && styles$2[prefix] && styles$2[prefix][iconName]) {\n        var icon = styles$2[prefix][iconName];\n        return resolve(asFoundIcon(icon));\n      }\n\n      if (iconName && prefix && !config.showMissingIcons) {\n        reject(new MissingIcon(\"Icon is missing for prefix \".concat(prefix, \" with icon name \").concat(iconName)));\n      } else {\n        resolve(val);\n      }\n    });\n  }\n\n  var styles$3 = namespace.styles;\n\n  function generateSvgReplacementMutation(node, nodeMeta) {\n    var iconName = nodeMeta.iconName,\n        title = nodeMeta.title,\n        titleId = nodeMeta.titleId,\n        prefix = nodeMeta.prefix,\n        transform = nodeMeta.transform,\n        symbol = nodeMeta.symbol,\n        mask = nodeMeta.mask,\n        maskId = nodeMeta.maskId,\n        extra = nodeMeta.extra;\n    return new picked(function (resolve, reject) {\n      picked.all([findIcon(iconName, prefix), findIcon(mask.iconName, mask.prefix)]).then(function (_ref) {\n        var _ref2 = _slicedToArray(_ref, 2),\n            main = _ref2[0],\n            mask = _ref2[1];\n\n        resolve([node, makeInlineSvgAbstract({\n          icons: {\n            main: main,\n            mask: mask\n          },\n          prefix: prefix,\n          iconName: iconName,\n          transform: transform,\n          symbol: symbol,\n          mask: mask,\n          maskId: maskId,\n          title: title,\n          titleId: titleId,\n          extra: extra,\n          watchable: true\n        })]);\n      });\n    });\n  }\n\n  function generateLayersText(node, nodeMeta) {\n    var title = nodeMeta.title,\n        transform = nodeMeta.transform,\n        extra = nodeMeta.extra;\n    var width = null;\n    var height = null;\n\n    if (IS_IE) {\n      var computedFontSize = parseInt(getComputedStyle(node).fontSize, 10);\n      var boundingClientRect = node.getBoundingClientRect();\n      width = boundingClientRect.width / computedFontSize;\n      height = boundingClientRect.height / computedFontSize;\n    }\n\n    if (config.autoA11y && !title) {\n      extra.attributes['aria-hidden'] = 'true';\n    }\n\n    return picked.resolve([node, makeLayersTextAbstract({\n      content: node.innerHTML,\n      width: width,\n      height: height,\n      transform: transform,\n      title: title,\n      extra: extra,\n      watchable: true\n    })]);\n  }\n\n  function generateMutation(node) {\n    var nodeMeta = parseMeta(node);\n\n    if (~nodeMeta.extra.classes.indexOf(LAYERS_TEXT_CLASSNAME)) {\n      return generateLayersText(node, nodeMeta);\n    } else {\n      return generateSvgReplacementMutation(node, nodeMeta);\n    }\n  }\n\n  function onTree(root) {\n    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n    if (!IS_DOM) return;\n    var htmlClassList = DOCUMENT.documentElement.classList;\n\n    var hclAdd = function hclAdd(suffix) {\n      return htmlClassList.add(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n    };\n\n    var hclRemove = function hclRemove(suffix) {\n      return htmlClassList.remove(\"\".concat(HTML_CLASS_I2SVG_BASE_CLASS, \"-\").concat(suffix));\n    };\n\n    var prefixes = config.autoFetchSvg ? Object.keys(PREFIX_TO_STYLE) : Object.keys(styles$3);\n    var prefixesDomQuery = [\".\".concat(LAYERS_TEXT_CLASSNAME, \":not([\").concat(DATA_FA_I2SVG, \"])\")].concat(prefixes.map(function (p) {\n      return \".\".concat(p, \":not([\").concat(DATA_FA_I2SVG, \"])\");\n    })).join(', ');\n\n    if (prefixesDomQuery.length === 0) {\n      return;\n    }\n\n    var candidates = [];\n\n    try {\n      candidates = toArray(root.querySelectorAll(prefixesDomQuery));\n    } catch (e) {// noop\n    }\n\n    if (candidates.length > 0) {\n      hclAdd('pending');\n      hclRemove('complete');\n    } else {\n      return;\n    }\n\n    var mark = perf.begin('onTree');\n    var mutations = candidates.reduce(function (acc, node) {\n      try {\n        var mutation = generateMutation(node);\n\n        if (mutation) {\n          acc.push(mutation);\n        }\n      } catch (e) {\n        if (!PRODUCTION) {\n          if (e instanceof MissingIcon) {\n            console.error(e);\n          }\n        }\n      }\n\n      return acc;\n    }, []);\n    return new picked(function (resolve, reject) {\n      picked.all(mutations).then(function (resolvedMutations) {\n        perform(resolvedMutations, function () {\n          hclAdd('active');\n          hclAdd('complete');\n          hclRemove('pending');\n          if (typeof callback === 'function') callback();\n          mark();\n          resolve();\n        });\n      }).catch(function () {\n        mark();\n        reject();\n      });\n    });\n  }\n  function onNode(node) {\n    var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n    generateMutation(node).then(function (mutation) {\n      if (mutation) {\n        perform([mutation], callback);\n      }\n    });\n  }\n\n  function replaceForPosition(node, position) {\n    var pendingAttribute = \"\".concat(DATA_FA_PSEUDO_ELEMENT_PENDING).concat(position.replace(':', '-'));\n    return new picked(function (resolve, reject) {\n      if (node.getAttribute(pendingAttribute) !== null) {\n        // This node is already being processed\n        return resolve();\n      }\n\n      var children = toArray(node.children);\n      var alreadyProcessedPseudoElement = children.filter(function (c) {\n        return c.getAttribute(DATA_FA_PSEUDO_ELEMENT) === position;\n      })[0];\n      var styles = WINDOW.getComputedStyle(node, position);\n      var fontFamily = styles.getPropertyValue('font-family').match(FONT_FAMILY_PATTERN);\n      var fontWeight = styles.getPropertyValue('font-weight');\n      var content = styles.getPropertyValue('content');\n\n      if (alreadyProcessedPseudoElement && !fontFamily) {\n        // If we've already processed it but the current computed style does not result in a font-family,\n        // that probably means that a class name that was previously present to make the icon has been\n        // removed. So we now should delete the icon.\n        node.removeChild(alreadyProcessedPseudoElement);\n        return resolve();\n      } else if (fontFamily && content !== 'none' && content !== '') {\n        var _content = styles.getPropertyValue('content');\n\n        var prefix = ~['Solid', 'Regular', 'Light', 'Duotone', 'Brands', 'Kit'].indexOf(fontFamily[2]) ? STYLE_TO_PREFIX[fontFamily[2].toLowerCase()] : FONT_WEIGHT_TO_PREFIX[fontWeight];\n        var hexValue = toHex(_content.length === 3 ? _content.substr(1, 1) : _content);\n        var iconName = byUnicode(prefix, hexValue);\n        var iconIdentifier = iconName; // Only convert the pseudo element in this :before/:after position into an icon if we haven't\n        // already done so with the same prefix and iconName\n\n        if (iconName && (!alreadyProcessedPseudoElement || alreadyProcessedPseudoElement.getAttribute(DATA_PREFIX) !== prefix || alreadyProcessedPseudoElement.getAttribute(DATA_ICON) !== iconIdentifier)) {\n          node.setAttribute(pendingAttribute, iconIdentifier);\n\n          if (alreadyProcessedPseudoElement) {\n            // Delete the old one, since we're replacing it with a new one\n            node.removeChild(alreadyProcessedPseudoElement);\n          }\n\n          var meta = blankMeta();\n          var extra = meta.extra;\n          extra.attributes[DATA_FA_PSEUDO_ELEMENT] = position;\n          findIcon(iconName, prefix).then(function (main) {\n            var abstract = makeInlineSvgAbstract(_objectSpread2(_objectSpread2({}, meta), {}, {\n              icons: {\n                main: main,\n                mask: emptyCanonicalIcon()\n              },\n              prefix: prefix,\n              iconName: iconIdentifier,\n              extra: extra,\n              watchable: true\n            }));\n            var element = DOCUMENT.createElement('svg');\n\n            if (position === ':before') {\n              node.insertBefore(element, node.firstChild);\n            } else {\n              node.appendChild(element);\n            }\n\n            element.outerHTML = abstract.map(function (a) {\n              return toHtml(a);\n            }).join('\\n');\n            node.removeAttribute(pendingAttribute);\n            resolve();\n          }).catch(reject);\n        } else {\n          resolve();\n        }\n      } else {\n        resolve();\n      }\n    });\n  }\n\n  function replace(node) {\n    return picked.all([replaceForPosition(node, ':before'), replaceForPosition(node, ':after')]);\n  }\n\n  function processable(node) {\n    return node.parentNode !== document.head && !~TAGNAMES_TO_SKIP_FOR_PSEUDOELEMENTS.indexOf(node.tagName.toUpperCase()) && !node.getAttribute(DATA_FA_PSEUDO_ELEMENT) && (!node.parentNode || node.parentNode.tagName !== 'svg');\n  }\n\n  function searchPseudoElements (root) {\n    if (!IS_DOM) return;\n    return new picked(function (resolve, reject) {\n      var operations = toArray(root.querySelectorAll('*')).filter(processable).map(replace);\n      var end = perf.begin('searchPseudoElements');\n      disableObservation();\n      picked.all(operations).then(function () {\n        end();\n        enableObservation();\n        resolve();\n      }).catch(function () {\n        end();\n        enableObservation();\n        reject();\n      });\n    });\n  }\n\n  var baseStyles = \"svg:not(:root).svg-inline--fa {\\n  overflow: visible;\\n}\\n\\n.svg-inline--fa {\\n  display: inline-block;\\n  font-size: inherit;\\n  height: 1em;\\n  overflow: visible;\\n  vertical-align: -0.125em;\\n}\\n.svg-inline--fa.fa-lg {\\n  vertical-align: -0.225em;\\n}\\n.svg-inline--fa.fa-w-1 {\\n  width: 0.0625em;\\n}\\n.svg-inline--fa.fa-w-2 {\\n  width: 0.125em;\\n}\\n.svg-inline--fa.fa-w-3 {\\n  width: 0.1875em;\\n}\\n.svg-inline--fa.fa-w-4 {\\n  width: 0.25em;\\n}\\n.svg-inline--fa.fa-w-5 {\\n  width: 0.3125em;\\n}\\n.svg-inline--fa.fa-w-6 {\\n  width: 0.375em;\\n}\\n.svg-inline--fa.fa-w-7 {\\n  width: 0.4375em;\\n}\\n.svg-inline--fa.fa-w-8 {\\n  width: 0.5em;\\n}\\n.svg-inline--fa.fa-w-9 {\\n  width: 0.5625em;\\n}\\n.svg-inline--fa.fa-w-10 {\\n  width: 0.625em;\\n}\\n.svg-inline--fa.fa-w-11 {\\n  width: 0.6875em;\\n}\\n.svg-inline--fa.fa-w-12 {\\n  width: 0.75em;\\n}\\n.svg-inline--fa.fa-w-13 {\\n  width: 0.8125em;\\n}\\n.svg-inline--fa.fa-w-14 {\\n  width: 0.875em;\\n}\\n.svg-inline--fa.fa-w-15 {\\n  width: 0.9375em;\\n}\\n.svg-inline--fa.fa-w-16 {\\n  width: 1em;\\n}\\n.svg-inline--fa.fa-w-17 {\\n  width: 1.0625em;\\n}\\n.svg-inline--fa.fa-w-18 {\\n  width: 1.125em;\\n}\\n.svg-inline--fa.fa-w-19 {\\n  width: 1.1875em;\\n}\\n.svg-inline--fa.fa-w-20 {\\n  width: 1.25em;\\n}\\n.svg-inline--fa.fa-pull-left {\\n  margin-right: 0.3em;\\n  width: auto;\\n}\\n.svg-inline--fa.fa-pull-right {\\n  margin-left: 0.3em;\\n  width: auto;\\n}\\n.svg-inline--fa.fa-border {\\n  height: 1.5em;\\n}\\n.svg-inline--fa.fa-li {\\n  width: 2em;\\n}\\n.svg-inline--fa.fa-fw {\\n  width: 1.25em;\\n}\\n\\n.fa-layers svg.svg-inline--fa {\\n  bottom: 0;\\n  left: 0;\\n  margin: auto;\\n  position: absolute;\\n  right: 0;\\n  top: 0;\\n}\\n\\n.fa-layers {\\n  display: inline-block;\\n  height: 1em;\\n  position: relative;\\n  text-align: center;\\n  vertical-align: -0.125em;\\n  width: 1em;\\n}\\n.fa-layers svg.svg-inline--fa {\\n  -webkit-transform-origin: center center;\\n          transform-origin: center center;\\n}\\n\\n.fa-layers-counter, .fa-layers-text {\\n  display: inline-block;\\n  position: absolute;\\n  text-align: center;\\n}\\n\\n.fa-layers-text {\\n  left: 50%;\\n  top: 50%;\\n  -webkit-transform: translate(-50%, -50%);\\n          transform: translate(-50%, -50%);\\n  -webkit-transform-origin: center center;\\n          transform-origin: center center;\\n}\\n\\n.fa-layers-counter {\\n  background-color: #ff253a;\\n  border-radius: 1em;\\n  -webkit-box-sizing: border-box;\\n          box-sizing: border-box;\\n  color: #fff;\\n  height: 1.5em;\\n  line-height: 1;\\n  max-width: 5em;\\n  min-width: 1.5em;\\n  overflow: hidden;\\n  padding: 0.25em;\\n  right: 0;\\n  text-overflow: ellipsis;\\n  top: 0;\\n  -webkit-transform: scale(0.25);\\n          transform: scale(0.25);\\n  -webkit-transform-origin: top right;\\n          transform-origin: top right;\\n}\\n\\n.fa-layers-bottom-right {\\n  bottom: 0;\\n  right: 0;\\n  top: auto;\\n  -webkit-transform: scale(0.25);\\n          transform: scale(0.25);\\n  -webkit-transform-origin: bottom right;\\n          transform-origin: bottom right;\\n}\\n\\n.fa-layers-bottom-left {\\n  bottom: 0;\\n  left: 0;\\n  right: auto;\\n  top: auto;\\n  -webkit-transform: scale(0.25);\\n          transform: scale(0.25);\\n  -webkit-transform-origin: bottom left;\\n          transform-origin: bottom left;\\n}\\n\\n.fa-layers-top-right {\\n  right: 0;\\n  top: 0;\\n  -webkit-transform: scale(0.25);\\n          transform: scale(0.25);\\n  -webkit-transform-origin: top right;\\n          transform-origin: top right;\\n}\\n\\n.fa-layers-top-left {\\n  left: 0;\\n  right: auto;\\n  top: 0;\\n  -webkit-transform: scale(0.25);\\n          transform: scale(0.25);\\n  -webkit-transform-origin: top left;\\n          transform-origin: top left;\\n}\\n\\n.fa-lg {\\n  font-size: 1.3333333333em;\\n  line-height: 0.75em;\\n  vertical-align: -0.0667em;\\n}\\n\\n.fa-xs {\\n  font-size: 0.75em;\\n}\\n\\n.fa-sm {\\n  font-size: 0.875em;\\n}\\n\\n.fa-1x {\\n  font-size: 1em;\\n}\\n\\n.fa-2x {\\n  font-size: 2em;\\n}\\n\\n.fa-3x {\\n  font-size: 3em;\\n}\\n\\n.fa-4x {\\n  font-size: 4em;\\n}\\n\\n.fa-5x {\\n  font-size: 5em;\\n}\\n\\n.fa-6x {\\n  font-size: 6em;\\n}\\n\\n.fa-7x {\\n  font-size: 7em;\\n}\\n\\n.fa-8x {\\n  font-size: 8em;\\n}\\n\\n.fa-9x {\\n  font-size: 9em;\\n}\\n\\n.fa-10x {\\n  font-size: 10em;\\n}\\n\\n.fa-fw {\\n  text-align: center;\\n  width: 1.25em;\\n}\\n\\n.fa-ul {\\n  list-style-type: none;\\n  margin-left: 2.5em;\\n  padding-left: 0;\\n}\\n.fa-ul > li {\\n  position: relative;\\n}\\n\\n.fa-li {\\n  left: -2em;\\n  position: absolute;\\n  text-align: center;\\n  width: 2em;\\n  line-height: inherit;\\n}\\n\\n.fa-border {\\n  border: solid 0.08em #eee;\\n  border-radius: 0.1em;\\n  padding: 0.2em 0.25em 0.15em;\\n}\\n\\n.fa-pull-left {\\n  float: left;\\n}\\n\\n.fa-pull-right {\\n  float: right;\\n}\\n\\n.fa.fa-pull-left,\\n.fas.fa-pull-left,\\n.far.fa-pull-left,\\n.fal.fa-pull-left,\\n.fab.fa-pull-left {\\n  margin-right: 0.3em;\\n}\\n.fa.fa-pull-right,\\n.fas.fa-pull-right,\\n.far.fa-pull-right,\\n.fal.fa-pull-right,\\n.fab.fa-pull-right {\\n  margin-left: 0.3em;\\n}\\n\\n.fa-spin {\\n  -webkit-animation: fa-spin 2s infinite linear;\\n          animation: fa-spin 2s infinite linear;\\n}\\n\\n.fa-pulse {\\n  -webkit-animation: fa-spin 1s infinite steps(8);\\n          animation: fa-spin 1s infinite steps(8);\\n}\\n\\n@-webkit-keyframes fa-spin {\\n  0% {\\n    -webkit-transform: rotate(0deg);\\n            transform: rotate(0deg);\\n  }\\n  100% {\\n    -webkit-transform: rotate(360deg);\\n            transform: rotate(360deg);\\n  }\\n}\\n\\n@keyframes fa-spin {\\n  0% {\\n    -webkit-transform: rotate(0deg);\\n            transform: rotate(0deg);\\n  }\\n  100% {\\n    -webkit-transform: rotate(360deg);\\n            transform: rotate(360deg);\\n  }\\n}\\n.fa-rotate-90 {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\\\";\\n  -webkit-transform: rotate(90deg);\\n          transform: rotate(90deg);\\n}\\n\\n.fa-rotate-180 {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\\\";\\n  -webkit-transform: rotate(180deg);\\n          transform: rotate(180deg);\\n}\\n\\n.fa-rotate-270 {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\\\";\\n  -webkit-transform: rotate(270deg);\\n          transform: rotate(270deg);\\n}\\n\\n.fa-flip-horizontal {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\\\";\\n  -webkit-transform: scale(-1, 1);\\n          transform: scale(-1, 1);\\n}\\n\\n.fa-flip-vertical {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\\\";\\n  -webkit-transform: scale(1, -1);\\n          transform: scale(1, -1);\\n}\\n\\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\\n  -ms-filter: \\\"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\\\";\\n  -webkit-transform: scale(-1, -1);\\n          transform: scale(-1, -1);\\n}\\n\\n:root .fa-rotate-90,\\n:root .fa-rotate-180,\\n:root .fa-rotate-270,\\n:root .fa-flip-horizontal,\\n:root .fa-flip-vertical,\\n:root .fa-flip-both {\\n  -webkit-filter: none;\\n          filter: none;\\n}\\n\\n.fa-stack {\\n  display: inline-block;\\n  height: 2em;\\n  position: relative;\\n  width: 2.5em;\\n}\\n\\n.fa-stack-1x,\\n.fa-stack-2x {\\n  bottom: 0;\\n  left: 0;\\n  margin: auto;\\n  position: absolute;\\n  right: 0;\\n  top: 0;\\n}\\n\\n.svg-inline--fa.fa-stack-1x {\\n  height: 1em;\\n  width: 1.25em;\\n}\\n.svg-inline--fa.fa-stack-2x {\\n  height: 2em;\\n  width: 2.5em;\\n}\\n\\n.fa-inverse {\\n  color: #fff;\\n}\\n\\n.sr-only {\\n  border: 0;\\n  clip: rect(0, 0, 0, 0);\\n  height: 1px;\\n  margin: -1px;\\n  overflow: hidden;\\n  padding: 0;\\n  position: absolute;\\n  width: 1px;\\n}\\n\\n.sr-only-focusable:active, .sr-only-focusable:focus {\\n  clip: auto;\\n  height: auto;\\n  margin: 0;\\n  overflow: visible;\\n  position: static;\\n  width: auto;\\n}\\n\\n.svg-inline--fa .fa-primary {\\n  fill: var(--fa-primary-color, currentColor);\\n  opacity: 1;\\n  opacity: var(--fa-primary-opacity, 1);\\n}\\n\\n.svg-inline--fa .fa-secondary {\\n  fill: var(--fa-secondary-color, currentColor);\\n  opacity: 0.4;\\n  opacity: var(--fa-secondary-opacity, 0.4);\\n}\\n\\n.svg-inline--fa.fa-swap-opacity .fa-primary {\\n  opacity: 0.4;\\n  opacity: var(--fa-secondary-opacity, 0.4);\\n}\\n\\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\\n  opacity: 1;\\n  opacity: var(--fa-primary-opacity, 1);\\n}\\n\\n.svg-inline--fa mask .fa-primary,\\n.svg-inline--fa mask .fa-secondary {\\n  fill: black;\\n}\\n\\n.fad.fa-inverse {\\n  color: #fff;\\n}\";\n\n  function css () {\n    var dfp = DEFAULT_FAMILY_PREFIX;\n    var drc = DEFAULT_REPLACEMENT_CLASS;\n    var fp = config.familyPrefix;\n    var rc = config.replacementClass;\n    var s = baseStyles;\n\n    if (fp !== dfp || rc !== drc) {\n      var dPatt = new RegExp(\"\\\\.\".concat(dfp, \"\\\\-\"), 'g');\n      var customPropPatt = new RegExp(\"\\\\--\".concat(dfp, \"\\\\-\"), 'g');\n      var rPatt = new RegExp(\"\\\\.\".concat(drc), 'g');\n      s = s.replace(dPatt, \".\".concat(fp, \"-\")).replace(customPropPatt, \"--\".concat(fp, \"-\")).replace(rPatt, \".\".concat(rc));\n    }\n\n    return s;\n  }\n\n  var Library = /*#__PURE__*/function () {\n    function Library() {\n      _classCallCheck(this, Library);\n\n      this.definitions = {};\n    }\n\n    _createClass(Library, [{\n      key: \"add\",\n      value: function add() {\n        var _this = this;\n\n        for (var _len = arguments.length, definitions = new Array(_len), _key = 0; _key < _len; _key++) {\n          definitions[_key] = arguments[_key];\n        }\n\n        var additions = definitions.reduce(this._pullDefinitions, {});\n        Object.keys(additions).forEach(function (key) {\n          _this.definitions[key] = _objectSpread2(_objectSpread2({}, _this.definitions[key] || {}), additions[key]);\n          defineIcons(key, additions[key]);\n          build();\n        });\n      }\n    }, {\n      key: \"reset\",\n      value: function reset() {\n        this.definitions = {};\n      }\n    }, {\n      key: \"_pullDefinitions\",\n      value: function _pullDefinitions(additions, definition) {\n        var normalized = definition.prefix && definition.iconName && definition.icon ? {\n          0: definition\n        } : definition;\n        Object.keys(normalized).map(function (key) {\n          var _normalized$key = normalized[key],\n              prefix = _normalized$key.prefix,\n              iconName = _normalized$key.iconName,\n              icon = _normalized$key.icon;\n          if (!additions[prefix]) additions[prefix] = {};\n          additions[prefix][iconName] = icon;\n        });\n        return additions;\n      }\n    }]);\n\n    return Library;\n  }();\n\n  function ensureCss() {\n    if (config.autoAddCss && !_cssInserted) {\n      insertCss(css());\n\n      _cssInserted = true;\n    }\n  }\n\n  function apiObject(val, abstractCreator) {\n    Object.defineProperty(val, 'abstract', {\n      get: abstractCreator\n    });\n    Object.defineProperty(val, 'html', {\n      get: function get() {\n        return val.abstract.map(function (a) {\n          return toHtml(a);\n        });\n      }\n    });\n    Object.defineProperty(val, 'node', {\n      get: function get() {\n        if (!IS_DOM) return;\n        var container = DOCUMENT.createElement('div');\n        container.innerHTML = val.html;\n        return container.children;\n      }\n    });\n    return val;\n  }\n\n  function findIconDefinition(iconLookup) {\n    var _iconLookup$prefix = iconLookup.prefix,\n        prefix = _iconLookup$prefix === void 0 ? 'fa' : _iconLookup$prefix,\n        iconName = iconLookup.iconName;\n    if (!iconName) return;\n    return iconFromMapping(library.definitions, prefix, iconName) || iconFromMapping(namespace.styles, prefix, iconName);\n  }\n\n  function resolveIcons(next) {\n    return function (maybeIconDefinition) {\n      var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n      var iconDefinition = (maybeIconDefinition || {}).icon ? maybeIconDefinition : findIconDefinition(maybeIconDefinition || {});\n      var mask = params.mask;\n\n      if (mask) {\n        mask = (mask || {}).icon ? mask : findIconDefinition(mask || {});\n      }\n\n      return next(iconDefinition, _objectSpread2(_objectSpread2({}, params), {}, {\n        mask: mask\n      }));\n    };\n  }\n\n  var library = new Library();\n  var noAuto = function noAuto() {\n    config.autoReplaceSvg = false;\n    config.observeMutations = false;\n    disconnect();\n  };\n  var _cssInserted = false;\n  var dom = {\n    i2svg: function i2svg() {\n      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n      if (IS_DOM) {\n        ensureCss();\n        var _params$node = params.node,\n            node = _params$node === void 0 ? DOCUMENT : _params$node,\n            _params$callback = params.callback,\n            callback = _params$callback === void 0 ? function () {} : _params$callback;\n\n        if (config.searchPseudoElements) {\n          searchPseudoElements(node);\n        }\n\n        return onTree(node, callback);\n      } else {\n        return picked.reject('Operation requires a DOM of some kind.');\n      }\n    },\n    css: css,\n    insertCss: function insertCss$$1() {\n      if (!_cssInserted) {\n        insertCss(css());\n\n        _cssInserted = true;\n      }\n    },\n    watch: function watch() {\n      var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n      var autoReplaceSvgRoot = params.autoReplaceSvgRoot,\n          observeMutationsRoot = params.observeMutationsRoot;\n\n      if (config.autoReplaceSvg === false) {\n        config.autoReplaceSvg = true;\n      }\n\n      config.observeMutations = true;\n      domready(function () {\n        autoReplace({\n          autoReplaceSvgRoot: autoReplaceSvgRoot\n        });\n        observe({\n          treeCallback: onTree,\n          nodeCallback: onNode,\n          pseudoElementsCallback: searchPseudoElements,\n          observeMutationsRoot: observeMutationsRoot\n        });\n      });\n    }\n  };\n  var parse = {\n    transform: function transform(transformString) {\n      return parseTransformString(transformString);\n    }\n  };\n  var icon = resolveIcons(function (iconDefinition) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$transform = params.transform,\n        transform = _params$transform === void 0 ? meaninglessTransform : _params$transform,\n        _params$symbol = params.symbol,\n        symbol = _params$symbol === void 0 ? false : _params$symbol,\n        _params$mask = params.mask,\n        mask = _params$mask === void 0 ? null : _params$mask,\n        _params$maskId = params.maskId,\n        maskId = _params$maskId === void 0 ? null : _params$maskId,\n        _params$title = params.title,\n        title = _params$title === void 0 ? null : _params$title,\n        _params$titleId = params.titleId,\n        titleId = _params$titleId === void 0 ? null : _params$titleId,\n        _params$classes = params.classes,\n        classes = _params$classes === void 0 ? [] : _params$classes,\n        _params$attributes = params.attributes,\n        attributes = _params$attributes === void 0 ? {} : _params$attributes,\n        _params$styles = params.styles,\n        styles = _params$styles === void 0 ? {} : _params$styles;\n    if (!iconDefinition) return;\n    var prefix = iconDefinition.prefix,\n        iconName = iconDefinition.iconName,\n        icon = iconDefinition.icon;\n    return apiObject(_objectSpread2({\n      type: 'icon'\n    }, iconDefinition), function () {\n      ensureCss();\n\n      if (config.autoA11y) {\n        if (title) {\n          attributes['aria-labelledby'] = \"\".concat(config.replacementClass, \"-title-\").concat(titleId || nextUniqueId());\n        } else {\n          attributes['aria-hidden'] = 'true';\n          attributes['focusable'] = 'false';\n        }\n      }\n\n      return makeInlineSvgAbstract({\n        icons: {\n          main: asFoundIcon(icon),\n          mask: mask ? asFoundIcon(mask.icon) : {\n            found: false,\n            width: null,\n            height: null,\n            icon: {}\n          }\n        },\n        prefix: prefix,\n        iconName: iconName,\n        transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n        symbol: symbol,\n        title: title,\n        maskId: maskId,\n        titleId: titleId,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: classes\n        }\n      });\n    });\n  });\n  var text = function text(content) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$transform2 = params.transform,\n        transform = _params$transform2 === void 0 ? meaninglessTransform : _params$transform2,\n        _params$title2 = params.title,\n        title = _params$title2 === void 0 ? null : _params$title2,\n        _params$classes2 = params.classes,\n        classes = _params$classes2 === void 0 ? [] : _params$classes2,\n        _params$attributes2 = params.attributes,\n        attributes = _params$attributes2 === void 0 ? {} : _params$attributes2,\n        _params$styles2 = params.styles,\n        styles = _params$styles2 === void 0 ? {} : _params$styles2;\n    return apiObject({\n      type: 'text',\n      content: content\n    }, function () {\n      ensureCss();\n      return makeLayersTextAbstract({\n        content: content,\n        transform: _objectSpread2(_objectSpread2({}, meaninglessTransform), transform),\n        title: title,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: [\"\".concat(config.familyPrefix, \"-layers-text\")].concat(_toConsumableArray(classes))\n        }\n      });\n    });\n  };\n  var counter = function counter(content) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$title3 = params.title,\n        title = _params$title3 === void 0 ? null : _params$title3,\n        _params$classes3 = params.classes,\n        classes = _params$classes3 === void 0 ? [] : _params$classes3,\n        _params$attributes3 = params.attributes,\n        attributes = _params$attributes3 === void 0 ? {} : _params$attributes3,\n        _params$styles3 = params.styles,\n        styles = _params$styles3 === void 0 ? {} : _params$styles3;\n    return apiObject({\n      type: 'counter',\n      content: content\n    }, function () {\n      ensureCss();\n      return makeLayersCounterAbstract({\n        content: content.toString(),\n        title: title,\n        extra: {\n          attributes: attributes,\n          styles: styles,\n          classes: [\"\".concat(config.familyPrefix, \"-layers-counter\")].concat(_toConsumableArray(classes))\n        }\n      });\n    });\n  };\n  var layer = function layer(assembler) {\n    var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};\n    var _params$classes4 = params.classes,\n        classes = _params$classes4 === void 0 ? [] : _params$classes4;\n    return apiObject({\n      type: 'layer'\n    }, function () {\n      ensureCss();\n      var children = [];\n      assembler(function (args) {\n        Array.isArray(args) ? args.map(function (a) {\n          children = children.concat(a.abstract);\n        }) : children = children.concat(args.abstract);\n      });\n      return [{\n        tag: 'span',\n        attributes: {\n          class: [\"\".concat(config.familyPrefix, \"-layers\")].concat(_toConsumableArray(classes)).join(' ')\n        },\n        children: children\n      }];\n    });\n  };\n  var api = {\n    noAuto: noAuto,\n    config: config,\n    dom: dom,\n    library: library,\n    parse: parse,\n    findIconDefinition: findIconDefinition,\n    icon: icon,\n    text: text,\n    counter: counter,\n    layer: layer,\n    toHtml: toHtml\n  };\n\n  var autoReplace = function autoReplace() {\n    var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n    var _params$autoReplaceSv = params.autoReplaceSvgRoot,\n        autoReplaceSvgRoot = _params$autoReplaceSv === void 0 ? DOCUMENT : _params$autoReplaceSv;\n    if ((Object.keys(namespace.styles).length > 0 || config.autoFetchSvg) && IS_DOM && config.autoReplaceSvg) api.dom.i2svg({\n      node: autoReplaceSvgRoot\n    });\n  };\n\n  exports.icon = icon;\n  exports.noAuto = noAuto;\n  exports.config = config;\n  exports.toHtml = toHtml;\n  exports.layer = layer;\n  exports.text = text;\n  exports.counter = counter;\n  exports.library = library;\n  exports.dom = dom;\n  exports.parse = parse;\n  exports.findIconDefinition = findIconDefinition;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-svg-core/package.json",
    "content": "{\n  \"description\": \"The iconic font, CSS, and SVG framework\",\n  \"keywords\": [\n    \"font\",\n    \"awesome\",\n    \"fontawesome\",\n    \"icon\",\n    \"svg\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://fontawesome.com\",\n  \"bugs\": {\n    \"url\": \"http://github.com/FortAwesome/Font-Awesome/issues\"\n  },\n  \"author\": {\n    \"name\": \"Dave Gandy\",\n    \"email\": \"dave@fontawesome.com\",\n    \"web\": \"http://twitter.com/davegandy\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Brian Talbot\",\n      \"web\": \"http://twitter.com/talbs\"\n    },\n    {\n      \"name\": \"Travis Chase\",\n      \"web\": \"http://twitter.com/supercodepoet\"\n    },\n    {\n      \"name\": \"Rob Madole\",\n      \"web\": \"http://twitter.com/robmadole\"\n    },\n    {\n      \"name\": \"Geremia Taglialatela\",\n      \"web\": \"http://twitter.com/gtagliala\"\n    },\n    {\n      \"name\": \"Mike Wilkerson\",\n      \"web\": \"http://twitter.com/mw77\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/FortAwesome/Font-Awesome\"\n  },\n  \"engines\": {\n    \"node\": \">=6\"\n  },\n  \"dependencies\": {\n    \"@fortawesome/fontawesome-common-types\": \"^0.2.36\"\n  },\n  \"version\": \"1.2.36\",\n  \"name\": \"@fortawesome/fontawesome-svg-core\",\n  \"main\": \"index.js\",\n  \"module\": \"index.es.js\",\n  \"jsnext:main\": \"index.es.js\",\n  \"style\": \"styles.css\",\n  \"license\": \"MIT\",\n  \"types\": \"./index.d.ts\",\n  \"scripts\": {\n    \"postinstall\": \"node attribution.js\"\n  }\n}"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/fontawesome-svg-core/styles.css",
    "content": "svg:not(:root).svg-inline--fa {\n  overflow: visible; }\n\n.svg-inline--fa {\n  display: inline-block;\n  font-size: inherit;\n  height: 1em;\n  overflow: visible;\n  vertical-align: -.125em; }\n  .svg-inline--fa.fa-lg {\n    vertical-align: -.225em; }\n  .svg-inline--fa.fa-w-1 {\n    width: 0.0625em; }\n  .svg-inline--fa.fa-w-2 {\n    width: 0.125em; }\n  .svg-inline--fa.fa-w-3 {\n    width: 0.1875em; }\n  .svg-inline--fa.fa-w-4 {\n    width: 0.25em; }\n  .svg-inline--fa.fa-w-5 {\n    width: 0.3125em; }\n  .svg-inline--fa.fa-w-6 {\n    width: 0.375em; }\n  .svg-inline--fa.fa-w-7 {\n    width: 0.4375em; }\n  .svg-inline--fa.fa-w-8 {\n    width: 0.5em; }\n  .svg-inline--fa.fa-w-9 {\n    width: 0.5625em; }\n  .svg-inline--fa.fa-w-10 {\n    width: 0.625em; }\n  .svg-inline--fa.fa-w-11 {\n    width: 0.6875em; }\n  .svg-inline--fa.fa-w-12 {\n    width: 0.75em; }\n  .svg-inline--fa.fa-w-13 {\n    width: 0.8125em; }\n  .svg-inline--fa.fa-w-14 {\n    width: 0.875em; }\n  .svg-inline--fa.fa-w-15 {\n    width: 0.9375em; }\n  .svg-inline--fa.fa-w-16 {\n    width: 1em; }\n  .svg-inline--fa.fa-w-17 {\n    width: 1.0625em; }\n  .svg-inline--fa.fa-w-18 {\n    width: 1.125em; }\n  .svg-inline--fa.fa-w-19 {\n    width: 1.1875em; }\n  .svg-inline--fa.fa-w-20 {\n    width: 1.25em; }\n  .svg-inline--fa.fa-pull-left {\n    margin-right: .3em;\n    width: auto; }\n  .svg-inline--fa.fa-pull-right {\n    margin-left: .3em;\n    width: auto; }\n  .svg-inline--fa.fa-border {\n    height: 1.5em; }\n  .svg-inline--fa.fa-li {\n    width: 2em; }\n  .svg-inline--fa.fa-fw {\n    width: 1.25em; }\n\n.fa-layers svg.svg-inline--fa {\n  bottom: 0;\n  left: 0;\n  margin: auto;\n  position: absolute;\n  right: 0;\n  top: 0; }\n\n.fa-layers {\n  display: inline-block;\n  height: 1em;\n  position: relative;\n  text-align: center;\n  vertical-align: -.125em;\n  width: 1em; }\n  .fa-layers svg.svg-inline--fa {\n    -webkit-transform-origin: center center;\n            transform-origin: center center; }\n\n.fa-layers-text, .fa-layers-counter {\n  display: inline-block;\n  position: absolute;\n  text-align: center; }\n\n.fa-layers-text {\n  left: 50%;\n  top: 50%;\n  -webkit-transform: translate(-50%, -50%);\n          transform: translate(-50%, -50%);\n  -webkit-transform-origin: center center;\n          transform-origin: center center; }\n\n.fa-layers-counter {\n  background-color: #ff253a;\n  border-radius: 1em;\n  -webkit-box-sizing: border-box;\n          box-sizing: border-box;\n  color: #fff;\n  height: 1.5em;\n  line-height: 1;\n  max-width: 5em;\n  min-width: 1.5em;\n  overflow: hidden;\n  padding: .25em;\n  right: 0;\n  text-overflow: ellipsis;\n  top: 0;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: top right;\n          transform-origin: top right; }\n\n.fa-layers-bottom-right {\n  bottom: 0;\n  right: 0;\n  top: auto;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: bottom right;\n          transform-origin: bottom right; }\n\n.fa-layers-bottom-left {\n  bottom: 0;\n  left: 0;\n  right: auto;\n  top: auto;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: bottom left;\n          transform-origin: bottom left; }\n\n.fa-layers-top-right {\n  right: 0;\n  top: 0;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: top right;\n          transform-origin: top right; }\n\n.fa-layers-top-left {\n  left: 0;\n  right: auto;\n  top: 0;\n  -webkit-transform: scale(0.25);\n          transform: scale(0.25);\n  -webkit-transform-origin: top left;\n          transform-origin: top left; }\n\n.fa-lg {\n  font-size: 1.33333em;\n  line-height: 0.75em;\n  vertical-align: -.0667em; }\n\n.fa-xs {\n  font-size: .75em; }\n\n.fa-sm {\n  font-size: .875em; }\n\n.fa-1x {\n  font-size: 1em; }\n\n.fa-2x {\n  font-size: 2em; }\n\n.fa-3x {\n  font-size: 3em; }\n\n.fa-4x {\n  font-size: 4em; }\n\n.fa-5x {\n  font-size: 5em; }\n\n.fa-6x {\n  font-size: 6em; }\n\n.fa-7x {\n  font-size: 7em; }\n\n.fa-8x {\n  font-size: 8em; }\n\n.fa-9x {\n  font-size: 9em; }\n\n.fa-10x {\n  font-size: 10em; }\n\n.fa-fw {\n  text-align: center;\n  width: 1.25em; }\n\n.fa-ul {\n  list-style-type: none;\n  margin-left: 2.5em;\n  padding-left: 0; }\n  .fa-ul > li {\n    position: relative; }\n\n.fa-li {\n  left: -2em;\n  position: absolute;\n  text-align: center;\n  width: 2em;\n  line-height: inherit; }\n\n.fa-border {\n  border: solid 0.08em #eee;\n  border-radius: .1em;\n  padding: .2em .25em .15em; }\n\n.fa-pull-left {\n  float: left; }\n\n.fa-pull-right {\n  float: right; }\n\n.fa.fa-pull-left,\n.fas.fa-pull-left,\n.far.fa-pull-left,\n.fal.fa-pull-left,\n.fab.fa-pull-left {\n  margin-right: .3em; }\n\n.fa.fa-pull-right,\n.fas.fa-pull-right,\n.far.fa-pull-right,\n.fal.fa-pull-right,\n.fab.fa-pull-right {\n  margin-left: .3em; }\n\n.fa-spin {\n  -webkit-animation: fa-spin 2s infinite linear;\n          animation: fa-spin 2s infinite linear; }\n\n.fa-pulse {\n  -webkit-animation: fa-spin 1s infinite steps(8);\n          animation: fa-spin 1s infinite steps(8); }\n\n@-webkit-keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n@keyframes fa-spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n            transform: rotate(0deg); }\n  100% {\n    -webkit-transform: rotate(360deg);\n            transform: rotate(360deg); } }\n\n.fa-rotate-90 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)\";\n  -webkit-transform: rotate(90deg);\n          transform: rotate(90deg); }\n\n.fa-rotate-180 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)\";\n  -webkit-transform: rotate(180deg);\n          transform: rotate(180deg); }\n\n.fa-rotate-270 {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)\";\n  -webkit-transform: rotate(270deg);\n          transform: rotate(270deg); }\n\n.fa-flip-horizontal {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)\";\n  -webkit-transform: scale(-1, 1);\n          transform: scale(-1, 1); }\n\n.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(1, -1);\n          transform: scale(1, -1); }\n\n.fa-flip-both, .fa-flip-horizontal.fa-flip-vertical {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)\";\n  -webkit-transform: scale(-1, -1);\n          transform: scale(-1, -1); }\n\n:root .fa-rotate-90,\n:root .fa-rotate-180,\n:root .fa-rotate-270,\n:root .fa-flip-horizontal,\n:root .fa-flip-vertical,\n:root .fa-flip-both {\n  -webkit-filter: none;\n          filter: none; }\n\n.fa-stack {\n  display: inline-block;\n  height: 2em;\n  position: relative;\n  width: 2.5em; }\n\n.fa-stack-1x,\n.fa-stack-2x {\n  bottom: 0;\n  left: 0;\n  margin: auto;\n  position: absolute;\n  right: 0;\n  top: 0; }\n\n.svg-inline--fa.fa-stack-1x {\n  height: 1em;\n  width: 1.25em; }\n\n.svg-inline--fa.fa-stack-2x {\n  height: 2em;\n  width: 2.5em; }\n\n.fa-inverse {\n  color: #fff; }\n\n.sr-only {\n  border: 0;\n  clip: rect(0, 0, 0, 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px; }\n\n.sr-only-focusable:active, .sr-only-focusable:focus {\n  clip: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  position: static;\n  width: auto; }\n\n.svg-inline--fa .fa-primary {\n  fill: var(--fa-primary-color, currentColor);\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.svg-inline--fa .fa-secondary {\n  fill: var(--fa-secondary-color, currentColor);\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.svg-inline--fa.fa-swap-opacity .fa-primary {\n  opacity: 0.4;\n  opacity: var(--fa-secondary-opacity, 0.4); }\n\n.svg-inline--fa.fa-swap-opacity .fa-secondary {\n  opacity: 1;\n  opacity: var(--fa-primary-opacity, 1); }\n\n.svg-inline--fa mask .fa-primary,\n.svg-inline--fa mask .fa-secondary {\n  fill: black; }\n\n.fad.fa-inverse {\n  color: #fff; }\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/LICENSE.txt",
    "content": "Font Awesome Pro License\n------------------------\n\nFont Awesome Pro is commercial software that requires a paid license. Full\nFont Awesome Pro license: https://fontawesome.com/license.\n\n# Commercial License\nThe Font Awesome Pro commercial license allows you to pay for FA Pro once, own\nit, and use it just about everywhere you'd like.\n\n# Attribution\nAttribution is not required by the Font Awesome Pro commercial license.\n\n# Brand Icons\nAll brand icons are trademarks of their respective owners. The use of these\ntrademarks does not indicate endorsement of the trademark holder by Font\nAwesome, nor vice versa. **Please do not use brand logos for any purpose except\nto represent the company, product, or service to which they refer.**\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/attribution.js",
    "content": "console.log(`Font Awesome Pro undefined by @fontawesome - https://fontawesome.com\nLicense - https://fontawesome.com/license (Commercial License)\n`)"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faAws.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faAws: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faAws.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'aws';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f375';\nvar svgPathData = 'M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faAws = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcAmazonPay.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCcAmazonPay: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcAmazonPay.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'cc-amazon-pay';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f42d';\nvar svgPathData = 'M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCcAmazonPay = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcAmex.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCcAmex: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcAmex.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'cc-amex';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1f3';\nvar svgPathData = 'M325.1 167.8c0-16.4-14.1-18.4-27.4-18.4l-39.1-.3v69.3H275v-25.1h18c18.4 0 14.5 10.3 14.8 25.1h16.6v-13.5c0-9.2-1.5-15.1-11-18.4 7.4-3 11.8-10.7 11.7-18.7zm-29.4 11.3H275v-15.3h21c5.1 0 10.7 1 10.7 7.4 0 6.6-5.3 7.9-11 7.9zM279 268.6h-52.7l-21 22.8-20.5-22.8h-66.5l-.1 69.3h65.4l21.3-23 20.4 23h32.2l.1-23.3c18.9 0 49.3 4.6 49.3-23.3 0-17.3-12.3-22.7-27.9-22.7zm-103.8 54.7h-40.6v-13.8h36.3v-14.1h-36.3v-12.5h41.7l17.9 20.2zm65.8 8.2l-25.3-28.1L241 276zm37.8-31h-21.2v-17.6h21.5c5.6 0 10.2 2.3 10.2 8.4 0 6.4-4.6 9.2-10.5 9.2zm-31.6-136.7v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5zM576 255.4h-.2zm-194.6 31.9c0-16.4-14.1-18.7-27.1-18.7h-39.4l-.1 69.3h16.6l.1-25.3h17.6c11 0 14.8 2 14.8 13.8l-.1 11.5h16.6l.1-13.8c0-8.9-1.8-15.1-11-18.4 7.7-3.1 11.8-10.8 11.9-18.4zm-29.2 11.2h-20.7v-15.6h21c5.1 0 10.7 1 10.7 7.4 0 6.9-5.4 8.2-11 8.2zm-172.8-80v-69.3h-27.6l-19.7 47-21.7-47H83.3v65.7l-28.1-65.7H30.7L1 218.5h17.9l6.4-15.3h34.5l6.4 15.3H100v-54.2l24 54.2h14.6l24-54.2v54.2zM31.2 188.8l11.2-27.6 11.5 27.6zm477.4 158.9v-4.5c-10.8 5.6-3.9 4.5-156.7 4.5 0-25.2.1-23.9 0-25.2-1.7-.1-3.2-.1-9.4-.1 0 17.9-.1 6.8-.1 25.3h-39.6c0-12.1.1-15.3.1-29.2-10 6-22.8 6.4-34.3 6.2 0 14.7-.1 8.3-.1 23h-48.9c-5.1-5.7-2.7-3.1-15.4-17.4-3.2 3.5-12.8 13.9-16.1 17.4h-82v-92.3h83.1c5 5.6 2.8 3.1 15.5 17.2 3.2-3.5 12.2-13.4 15.7-17.2h58c9.8 0 18 1.9 24.3 5.6v-5.6c54.3 0 64.3-1.4 75.7 5.1v-5.1h78.2v5.2c11.4-6.9 19.6-5.2 64.9-5.2v5c10.3-5.9 16.6-5.2 54.3-5V80c0-26.5-21.5-48-48-48h-480c-26.5 0-48 21.5-48 48v109.8c9.4-21.9 19.7-46 23.1-53.9h39.7c4.3 10.1 1.6 3.7 9 21.1v-21.1h46c2.9 6.2 11.1 24 13.9 30 5.8-13.6 10.1-23.9 12.6-30h103c0-.1 11.5 0 11.6 0 43.7.2 53.6-.8 64.4 5.3v-5.3H363v9.3c7.6-6.1 17.9-9.3 30.7-9.3h27.6c0 .5 1.9.3 2.3.3H456c4.2 9.8 2.6 6 8.8 20.6v-20.6h43.3c4.9 8-1-1.8 11.2 18.4v-18.4h39.9v92h-41.6c-5.4-9-1.4-2.2-13.2-21.9v21.9h-52.8c-6.4-14.8-.1-.3-6.6-15.3h-19c-4.2 10-2.2 5.2-6.4 15.3h-26.8c-12.3 0-22.3-3-29.7-8.9v8.9h-66.5c-.3-13.9-.1-24.8-.1-24.8-1.8-.3-3.4-.2-9.8-.2v25.1H151.2v-11.4c-2.5 5.6-2.7 5.9-5.1 11.4h-29.5c-4-8.9-2.9-6.4-5.1-11.4v11.4H58.6c-4.2-10.1-2.2-5.3-6.4-15.3H33c-4.2 10-2.2 5.2-6.4 15.3H0V432c0 26.5 21.5 48 48 48h480.1c26.5 0 48-21.5 48-48v-90.4c-12.7 8.3-32.7 6.1-67.5 6.1zm36.3-64.5H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-57 39.8h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-42.2-40.1v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5zm-56.3-108.1c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm20.4-10.5h-.1zm-16.2-15.2c-23.5 0-34 12-34 35.3 0 22.2 10.2 34 33 34h19.2l6.4-15.3h34.3l6.6 15.3h33.7v-51.9l31.2 51.9h23.6v-69h-16.9v48.1l-29.1-48.1h-25.3v65.4l-27.9-65.4h-24.8l-23.5 54.5h-7.4c-13.3 0-16.1-8.1-16.1-19.9 0-23.8 15.7-20 33.1-19.7v-15.2zm42.1 12.1l11.2 27.6h-22.8zm-101.1-12v69.3h16.9v-69.3z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCcAmex = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcApplePay.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCcApplePay: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcApplePay.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'cc-apple-pay';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f416';\nvar svgPathData = 'M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCcApplePay = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcDinersClub.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCcDinersClub: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcDinersClub.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'cc-diners-club';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f24c';\nvar svgPathData = 'M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCcDinersClub = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcDiscover.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCcDiscover: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcDiscover.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'cc-discover';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1f2';\nvar svgPathData = 'M520.4 196.1c0-7.9-5.5-12.1-15.6-12.1h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-44.1 138.9c22.6 0 52.9-4.1 52.9 24.4 0 12.6-6.6 20.7-18.7 23.2l25.8 34.4h-19.6l-22.2-32.8h-2.2v32.8h-16zm-55.9.1h45.3v14H444v18.2h28.3V217H444v22.2h29.3V253H428zm-68.7 0l21.9 55.2 22.2-55.2h17.5l-35.5 84.2h-8.6l-35-84.2zm-55.9-3c24.7 0 44.6 20 44.6 44.6 0 24.7-20 44.6-44.6 44.6-24.7 0-44.6-20-44.6-44.6 0-24.7 20-44.6 44.6-44.6zm-49.3 6.1v19c-20.1-20.1-46.8-4.7-46.8 19 0 25 27.5 38.5 46.8 19.2v19c-29.7 14.3-63.3-5.7-63.3-38.2 0-31.2 33.1-53 63.3-38zm-97.2 66.3c11.4 0 22.4-15.3-3.3-24.4-15-5.5-20.2-11.4-20.2-22.7 0-23.2 30.6-31.4 49.7-14.3l-8.4 10.8c-10.4-11.6-24.9-6.2-24.9 2.5 0 4.4 2.7 6.9 12.3 10.3 18.2 6.6 23.6 12.5 23.6 25.6 0 29.5-38.8 37.4-56.6 11.3l10.3-9.9c3.7 7.1 9.9 10.8 17.5 10.8zM55.4 253H32v-82h23.4c26.1 0 44.1 17 44.1 41.1 0 18.5-13.2 40.9-44.1 40.9zm67.5 0h-16v-82h16zM544 433c0 8.2-6.8 15-15 15H128c189.6-35.6 382.7-139.2 416-160zM74.1 191.6c-5.2-4.9-11.6-6.6-21.9-6.6H48v54.2h4.2c10.3 0 17-2 21.9-6.4 5.7-5.2 8.9-12.8 8.9-20.7s-3.2-15.5-8.9-20.5z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCcDiscover = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcJcb.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCcJcb: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcJcb.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'cc-jcb';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f24b';\nvar svgPathData = 'M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCcJcb = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcMastercard.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCcMastercard: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcMastercard.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'cc-mastercard';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1f1';\nvar svgPathData = 'M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCcMastercard = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcPaypal.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCcPaypal: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcPaypal.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'cc-paypal';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1f4';\nvar svgPathData = 'M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCcPaypal = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcStripe.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCcStripe: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcStripe.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'cc-stripe';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1f5';\nvar svgPathData = 'M492.4 220.8c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7zM375 223.4c-8.2 0-13.3 2.9-17 7l.2 52.8c3.5 3.7 8.5 6.7 16.8 6.7 13.1 0 21.9-14.3 21.9-33.4 0-18.6-9-33.2-21.9-33.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM122.2 281.1c0 25.6-20.3 40.1-49.9 40.3-12.2 0-25.6-2.4-38.8-8.1v-33.9c12 6.4 27.1 11.3 38.9 11.3 7.9 0 13.6-2.1 13.6-8.7 0-17-54-10.6-54-49.9 0-25.2 19.2-40.2 48-40.2 11.8 0 23.5 1.8 35.3 6.5v33.4c-10.8-5.8-24.5-9.1-35.3-9.1-7.5 0-12.1 2.2-12.1 7.7 0 16 54.3 8.4 54.3 50.7zm68.8-56.6h-27V275c0 20.9 22.5 14.4 27 12.6v28.9c-4.7 2.6-13.3 4.7-24.9 4.7-21.1 0-36.9-15.5-36.9-36.5l.2-113.9 34.7-7.4v30.8H191zm74 2.4c-4.5-1.5-18.7-3.6-27.1 7.4v84.4h-35.5V194.2h30.7l2.2 10.5c8.3-15.3 24.9-12.2 29.6-10.5h.1zm44.1 91.8h-35.7V194.2h35.7zm0-142.9l-35.7 7.6v-28.9l35.7-7.6zm74.1 145.5c-12.4 0-20-5.3-25.1-9l-.1 40.2-35.5 7.5V194.2h31.3l1.8 8.8c4.9-4.5 13.9-11.1 27.8-11.1 24.9 0 48.4 22.5 48.4 63.8 0 45.1-23.2 65.5-48.6 65.6zm160.4-51.5h-69.5c1.6 16.6 13.8 21.5 27.6 21.5 14.1 0 25.2-3 34.9-7.9V312c-9.7 5.3-22.4 9.2-39.4 9.2-34.6 0-58.8-21.7-58.8-64.5 0-36.2 20.5-64.9 54.3-64.9 33.7 0 51.3 28.7 51.3 65.1 0 3.5-.3 10.9-.4 12.9z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCcStripe = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcVisa.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCcVisa: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faCcVisa.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'cc-visa';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1f0';\nvar svgPathData = 'M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCcVisa = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faDiscourse.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faDiscourse: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faDiscourse.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'discourse';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f393';\nvar svgPathData = 'M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faDiscourse = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faDocker.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faDocker: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faDocker.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'docker';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f395';\nvar svgPathData = 'M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faDocker = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faGithub.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faGithub: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faGithub.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'github';\nvar width = 496;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f09b';\nvar svgPathData = 'M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faGithub = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faInstagram.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faInstagram: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faInstagram.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'instagram';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f16d';\nvar svgPathData = 'M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faInstagram = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faMicrosoft.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faMicrosoft: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faMicrosoft.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'microsoft';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f3ca';\nvar svgPathData = 'M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faMicrosoft = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faRev.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faRev: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faRev.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'rev';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f5b2';\nvar svgPathData = 'M289.67 274.89a65.57 65.57 0 1 1-65.56-65.56 65.64 65.64 0 0 1 65.56 65.56zm139.55-5.05h-.13a204.69 204.69 0 0 0-74.32-153l-45.38 26.2a157.07 157.07 0 0 1 71.81 131.84C381.2 361.5 310.73 432 224.11 432S67 361.5 67 274.88c0-81.88 63-149.27 143-156.43v39.12l108.77-62.79L210 32v38.32c-106.7 7.25-191 96-191 204.57 0 111.59 89.12 202.29 200.06 205v.11h210.16V269.84z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faRev = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faSlack.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSlack: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faSlack.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'slack';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f198';\nvar svgPathData = 'M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSlack = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faTwitter.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faTwitter: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/faTwitter.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fab';\nvar iconName = 'twitter';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f099';\nvar svgPathData = 'M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faTwitter = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/index.d.ts",
    "content": "export const faAws: IconDefinition;\nexport const faCcAmazonPay: IconDefinition;\nexport const faCcAmex: IconDefinition;\nexport const faCcApplePay: IconDefinition;\nexport const faCcDinersClub: IconDefinition;\nexport const faCcDiscover: IconDefinition;\nexport const faCcJcb: IconDefinition;\nexport const faCcMastercard: IconDefinition;\nexport const faCcPaypal: IconDefinition;\nexport const faCcStripe: IconDefinition;\nexport const faCcVisa: IconDefinition;\nexport const faDiscourse: IconDefinition;\nexport const faDocker: IconDefinition;\nexport const faGithub: IconDefinition;\nexport const faInstagram: IconDefinition;\nexport const faMicrosoft: IconDefinition;\nexport const faRev: IconDefinition;\nexport const faSlack: IconDefinition;\nexport const faTwitter: IconDefinition;\nimport { IconDefinition, IconLookup, IconName, IconPrefix, IconPack } from '@fortawesome/fontawesome-common-types';\nexport { IconDefinition, IconLookup, IconName, IconPrefix, IconPack } from '@fortawesome/fontawesome-common-types';\nexport const prefix: IconPrefix;\nexport const fab: IconPack;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/index.es.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\nvar prefix = \"fab\";\nvar faAws = {\n  prefix: 'fab',\n  iconName: 'aws',\n  icon: [640, 512, [], \"f375\", \"M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z\"]\n};\nvar faCcAmazonPay = {\n  prefix: 'fab',\n  iconName: 'cc-amazon-pay',\n  icon: [576, 512, [], \"f42d\", \"M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z\"]\n};\nvar faCcAmex = {\n  prefix: 'fab',\n  iconName: 'cc-amex',\n  icon: [576, 512, [], \"f1f3\", \"M325.1 167.8c0-16.4-14.1-18.4-27.4-18.4l-39.1-.3v69.3H275v-25.1h18c18.4 0 14.5 10.3 14.8 25.1h16.6v-13.5c0-9.2-1.5-15.1-11-18.4 7.4-3 11.8-10.7 11.7-18.7zm-29.4 11.3H275v-15.3h21c5.1 0 10.7 1 10.7 7.4 0 6.6-5.3 7.9-11 7.9zM279 268.6h-52.7l-21 22.8-20.5-22.8h-66.5l-.1 69.3h65.4l21.3-23 20.4 23h32.2l.1-23.3c18.9 0 49.3 4.6 49.3-23.3 0-17.3-12.3-22.7-27.9-22.7zm-103.8 54.7h-40.6v-13.8h36.3v-14.1h-36.3v-12.5h41.7l17.9 20.2zm65.8 8.2l-25.3-28.1L241 276zm37.8-31h-21.2v-17.6h21.5c5.6 0 10.2 2.3 10.2 8.4 0 6.4-4.6 9.2-10.5 9.2zm-31.6-136.7v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5zM576 255.4h-.2zm-194.6 31.9c0-16.4-14.1-18.7-27.1-18.7h-39.4l-.1 69.3h16.6l.1-25.3h17.6c11 0 14.8 2 14.8 13.8l-.1 11.5h16.6l.1-13.8c0-8.9-1.8-15.1-11-18.4 7.7-3.1 11.8-10.8 11.9-18.4zm-29.2 11.2h-20.7v-15.6h21c5.1 0 10.7 1 10.7 7.4 0 6.9-5.4 8.2-11 8.2zm-172.8-80v-69.3h-27.6l-19.7 47-21.7-47H83.3v65.7l-28.1-65.7H30.7L1 218.5h17.9l6.4-15.3h34.5l6.4 15.3H100v-54.2l24 54.2h14.6l24-54.2v54.2zM31.2 188.8l11.2-27.6 11.5 27.6zm477.4 158.9v-4.5c-10.8 5.6-3.9 4.5-156.7 4.5 0-25.2.1-23.9 0-25.2-1.7-.1-3.2-.1-9.4-.1 0 17.9-.1 6.8-.1 25.3h-39.6c0-12.1.1-15.3.1-29.2-10 6-22.8 6.4-34.3 6.2 0 14.7-.1 8.3-.1 23h-48.9c-5.1-5.7-2.7-3.1-15.4-17.4-3.2 3.5-12.8 13.9-16.1 17.4h-82v-92.3h83.1c5 5.6 2.8 3.1 15.5 17.2 3.2-3.5 12.2-13.4 15.7-17.2h58c9.8 0 18 1.9 24.3 5.6v-5.6c54.3 0 64.3-1.4 75.7 5.1v-5.1h78.2v5.2c11.4-6.9 19.6-5.2 64.9-5.2v5c10.3-5.9 16.6-5.2 54.3-5V80c0-26.5-21.5-48-48-48h-480c-26.5 0-48 21.5-48 48v109.8c9.4-21.9 19.7-46 23.1-53.9h39.7c4.3 10.1 1.6 3.7 9 21.1v-21.1h46c2.9 6.2 11.1 24 13.9 30 5.8-13.6 10.1-23.9 12.6-30h103c0-.1 11.5 0 11.6 0 43.7.2 53.6-.8 64.4 5.3v-5.3H363v9.3c7.6-6.1 17.9-9.3 30.7-9.3h27.6c0 .5 1.9.3 2.3.3H456c4.2 9.8 2.6 6 8.8 20.6v-20.6h43.3c4.9 8-1-1.8 11.2 18.4v-18.4h39.9v92h-41.6c-5.4-9-1.4-2.2-13.2-21.9v21.9h-52.8c-6.4-14.8-.1-.3-6.6-15.3h-19c-4.2 10-2.2 5.2-6.4 15.3h-26.8c-12.3 0-22.3-3-29.7-8.9v8.9h-66.5c-.3-13.9-.1-24.8-.1-24.8-1.8-.3-3.4-.2-9.8-.2v25.1H151.2v-11.4c-2.5 5.6-2.7 5.9-5.1 11.4h-29.5c-4-8.9-2.9-6.4-5.1-11.4v11.4H58.6c-4.2-10.1-2.2-5.3-6.4-15.3H33c-4.2 10-2.2 5.2-6.4 15.3H0V432c0 26.5 21.5 48 48 48h480.1c26.5 0 48-21.5 48-48v-90.4c-12.7 8.3-32.7 6.1-67.5 6.1zm36.3-64.5H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-57 39.8h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-42.2-40.1v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5zm-56.3-108.1c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm20.4-10.5h-.1zm-16.2-15.2c-23.5 0-34 12-34 35.3 0 22.2 10.2 34 33 34h19.2l6.4-15.3h34.3l6.6 15.3h33.7v-51.9l31.2 51.9h23.6v-69h-16.9v48.1l-29.1-48.1h-25.3v65.4l-27.9-65.4h-24.8l-23.5 54.5h-7.4c-13.3 0-16.1-8.1-16.1-19.9 0-23.8 15.7-20 33.1-19.7v-15.2zm42.1 12.1l11.2 27.6h-22.8zm-101.1-12v69.3h16.9v-69.3z\"]\n};\nvar faCcApplePay = {\n  prefix: 'fab',\n  iconName: 'cc-apple-pay',\n  icon: [576, 512, [], \"f416\", \"M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z\"]\n};\nvar faCcDinersClub = {\n  prefix: 'fab',\n  iconName: 'cc-diners-club',\n  icon: [576, 512, [], \"f24c\", \"M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z\"]\n};\nvar faCcDiscover = {\n  prefix: 'fab',\n  iconName: 'cc-discover',\n  icon: [576, 512, [], \"f1f2\", \"M520.4 196.1c0-7.9-5.5-12.1-15.6-12.1h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-44.1 138.9c22.6 0 52.9-4.1 52.9 24.4 0 12.6-6.6 20.7-18.7 23.2l25.8 34.4h-19.6l-22.2-32.8h-2.2v32.8h-16zm-55.9.1h45.3v14H444v18.2h28.3V217H444v22.2h29.3V253H428zm-68.7 0l21.9 55.2 22.2-55.2h17.5l-35.5 84.2h-8.6l-35-84.2zm-55.9-3c24.7 0 44.6 20 44.6 44.6 0 24.7-20 44.6-44.6 44.6-24.7 0-44.6-20-44.6-44.6 0-24.7 20-44.6 44.6-44.6zm-49.3 6.1v19c-20.1-20.1-46.8-4.7-46.8 19 0 25 27.5 38.5 46.8 19.2v19c-29.7 14.3-63.3-5.7-63.3-38.2 0-31.2 33.1-53 63.3-38zm-97.2 66.3c11.4 0 22.4-15.3-3.3-24.4-15-5.5-20.2-11.4-20.2-22.7 0-23.2 30.6-31.4 49.7-14.3l-8.4 10.8c-10.4-11.6-24.9-6.2-24.9 2.5 0 4.4 2.7 6.9 12.3 10.3 18.2 6.6 23.6 12.5 23.6 25.6 0 29.5-38.8 37.4-56.6 11.3l10.3-9.9c3.7 7.1 9.9 10.8 17.5 10.8zM55.4 253H32v-82h23.4c26.1 0 44.1 17 44.1 41.1 0 18.5-13.2 40.9-44.1 40.9zm67.5 0h-16v-82h16zM544 433c0 8.2-6.8 15-15 15H128c189.6-35.6 382.7-139.2 416-160zM74.1 191.6c-5.2-4.9-11.6-6.6-21.9-6.6H48v54.2h4.2c10.3 0 17-2 21.9-6.4 5.7-5.2 8.9-12.8 8.9-20.7s-3.2-15.5-8.9-20.5z\"]\n};\nvar faCcJcb = {\n  prefix: 'fab',\n  iconName: 'cc-jcb',\n  icon: [576, 512, [], \"f24b\", \"M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z\"]\n};\nvar faCcMastercard = {\n  prefix: 'fab',\n  iconName: 'cc-mastercard',\n  icon: [576, 512, [], \"f1f1\", \"M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z\"]\n};\nvar faCcPaypal = {\n  prefix: 'fab',\n  iconName: 'cc-paypal',\n  icon: [576, 512, [], \"f1f4\", \"M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z\"]\n};\nvar faCcStripe = {\n  prefix: 'fab',\n  iconName: 'cc-stripe',\n  icon: [576, 512, [], \"f1f5\", \"M492.4 220.8c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7zM375 223.4c-8.2 0-13.3 2.9-17 7l.2 52.8c3.5 3.7 8.5 6.7 16.8 6.7 13.1 0 21.9-14.3 21.9-33.4 0-18.6-9-33.2-21.9-33.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM122.2 281.1c0 25.6-20.3 40.1-49.9 40.3-12.2 0-25.6-2.4-38.8-8.1v-33.9c12 6.4 27.1 11.3 38.9 11.3 7.9 0 13.6-2.1 13.6-8.7 0-17-54-10.6-54-49.9 0-25.2 19.2-40.2 48-40.2 11.8 0 23.5 1.8 35.3 6.5v33.4c-10.8-5.8-24.5-9.1-35.3-9.1-7.5 0-12.1 2.2-12.1 7.7 0 16 54.3 8.4 54.3 50.7zm68.8-56.6h-27V275c0 20.9 22.5 14.4 27 12.6v28.9c-4.7 2.6-13.3 4.7-24.9 4.7-21.1 0-36.9-15.5-36.9-36.5l.2-113.9 34.7-7.4v30.8H191zm74 2.4c-4.5-1.5-18.7-3.6-27.1 7.4v84.4h-35.5V194.2h30.7l2.2 10.5c8.3-15.3 24.9-12.2 29.6-10.5h.1zm44.1 91.8h-35.7V194.2h35.7zm0-142.9l-35.7 7.6v-28.9l35.7-7.6zm74.1 145.5c-12.4 0-20-5.3-25.1-9l-.1 40.2-35.5 7.5V194.2h31.3l1.8 8.8c4.9-4.5 13.9-11.1 27.8-11.1 24.9 0 48.4 22.5 48.4 63.8 0 45.1-23.2 65.5-48.6 65.6zm160.4-51.5h-69.5c1.6 16.6 13.8 21.5 27.6 21.5 14.1 0 25.2-3 34.9-7.9V312c-9.7 5.3-22.4 9.2-39.4 9.2-34.6 0-58.8-21.7-58.8-64.5 0-36.2 20.5-64.9 54.3-64.9 33.7 0 51.3 28.7 51.3 65.1 0 3.5-.3 10.9-.4 12.9z\"]\n};\nvar faCcVisa = {\n  prefix: 'fab',\n  iconName: 'cc-visa',\n  icon: [576, 512, [], \"f1f0\", \"M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z\"]\n};\nvar faDiscourse = {\n  prefix: 'fab',\n  iconName: 'discourse',\n  icon: [448, 512, [], \"f393\", \"M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z\"]\n};\nvar faDocker = {\n  prefix: 'fab',\n  iconName: 'docker',\n  icon: [640, 512, [], \"f395\", \"M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z\"]\n};\nvar faGithub = {\n  prefix: 'fab',\n  iconName: 'github',\n  icon: [496, 512, [], \"f09b\", \"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\"]\n};\nvar faInstagram = {\n  prefix: 'fab',\n  iconName: 'instagram',\n  icon: [448, 512, [], \"f16d\", \"M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z\"]\n};\nvar faMicrosoft = {\n  prefix: 'fab',\n  iconName: 'microsoft',\n  icon: [448, 512, [], \"f3ca\", \"M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z\"]\n};\nvar faRev = {\n  prefix: 'fab',\n  iconName: 'rev',\n  icon: [448, 512, [], \"f5b2\", \"M289.67 274.89a65.57 65.57 0 1 1-65.56-65.56 65.64 65.64 0 0 1 65.56 65.56zm139.55-5.05h-.13a204.69 204.69 0 0 0-74.32-153l-45.38 26.2a157.07 157.07 0 0 1 71.81 131.84C381.2 361.5 310.73 432 224.11 432S67 361.5 67 274.88c0-81.88 63-149.27 143-156.43v39.12l108.77-62.79L210 32v38.32c-106.7 7.25-191 96-191 204.57 0 111.59 89.12 202.29 200.06 205v.11h210.16V269.84z\"]\n};\nvar faSlack = {\n  prefix: 'fab',\n  iconName: 'slack',\n  icon: [448, 512, [], \"f198\", \"M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z\"]\n};\nvar faTwitter = {\n  prefix: 'fab',\n  iconName: 'twitter',\n  icon: [512, 512, [], \"f099\", \"M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z\"]\n};\nvar _iconsCache = {\n  faAws: faAws,\n  faCcAmazonPay: faCcAmazonPay,\n  faCcAmex: faCcAmex,\n  faCcApplePay: faCcApplePay,\n  faCcDinersClub: faCcDinersClub,\n  faCcDiscover: faCcDiscover,\n  faCcJcb: faCcJcb,\n  faCcMastercard: faCcMastercard,\n  faCcPaypal: faCcPaypal,\n  faCcStripe: faCcStripe,\n  faCcVisa: faCcVisa,\n  faDiscourse: faDiscourse,\n  faDocker: faDocker,\n  faGithub: faGithub,\n  faInstagram: faInstagram,\n  faMicrosoft: faMicrosoft,\n  faRev: faRev,\n  faSlack: faSlack,\n  faTwitter: faTwitter\n};\n\nexport { _iconsCache as fab, prefix, faAws, faCcAmazonPay, faCcAmex, faCcApplePay, faCcDinersClub, faCcDiscover, faCcJcb, faCcMastercard, faCcPaypal, faCcStripe, faCcVisa, faDiscourse, faDocker, faGithub, faInstagram, faMicrosoft, faRev, faSlack, faTwitter };\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/index.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (factory((global['pro-brands-svg-icons'] = {})));\n}(this, (function (exports) { 'use strict';\n\n  var prefix = \"fab\";\n  var faAws = {\n    prefix: 'fab',\n    iconName: 'aws',\n    icon: [640, 512, [], \"f375\", \"M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z\"]\n  };\n  var faCcAmazonPay = {\n    prefix: 'fab',\n    iconName: 'cc-amazon-pay',\n    icon: [576, 512, [], \"f42d\", \"M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z\"]\n  };\n  var faCcAmex = {\n    prefix: 'fab',\n    iconName: 'cc-amex',\n    icon: [576, 512, [], \"f1f3\", \"M325.1 167.8c0-16.4-14.1-18.4-27.4-18.4l-39.1-.3v69.3H275v-25.1h18c18.4 0 14.5 10.3 14.8 25.1h16.6v-13.5c0-9.2-1.5-15.1-11-18.4 7.4-3 11.8-10.7 11.7-18.7zm-29.4 11.3H275v-15.3h21c5.1 0 10.7 1 10.7 7.4 0 6.6-5.3 7.9-11 7.9zM279 268.6h-52.7l-21 22.8-20.5-22.8h-66.5l-.1 69.3h65.4l21.3-23 20.4 23h32.2l.1-23.3c18.9 0 49.3 4.6 49.3-23.3 0-17.3-12.3-22.7-27.9-22.7zm-103.8 54.7h-40.6v-13.8h36.3v-14.1h-36.3v-12.5h41.7l17.9 20.2zm65.8 8.2l-25.3-28.1L241 276zm37.8-31h-21.2v-17.6h21.5c5.6 0 10.2 2.3 10.2 8.4 0 6.4-4.6 9.2-10.5 9.2zm-31.6-136.7v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5zM576 255.4h-.2zm-194.6 31.9c0-16.4-14.1-18.7-27.1-18.7h-39.4l-.1 69.3h16.6l.1-25.3h17.6c11 0 14.8 2 14.8 13.8l-.1 11.5h16.6l.1-13.8c0-8.9-1.8-15.1-11-18.4 7.7-3.1 11.8-10.8 11.9-18.4zm-29.2 11.2h-20.7v-15.6h21c5.1 0 10.7 1 10.7 7.4 0 6.9-5.4 8.2-11 8.2zm-172.8-80v-69.3h-27.6l-19.7 47-21.7-47H83.3v65.7l-28.1-65.7H30.7L1 218.5h17.9l6.4-15.3h34.5l6.4 15.3H100v-54.2l24 54.2h14.6l24-54.2v54.2zM31.2 188.8l11.2-27.6 11.5 27.6zm477.4 158.9v-4.5c-10.8 5.6-3.9 4.5-156.7 4.5 0-25.2.1-23.9 0-25.2-1.7-.1-3.2-.1-9.4-.1 0 17.9-.1 6.8-.1 25.3h-39.6c0-12.1.1-15.3.1-29.2-10 6-22.8 6.4-34.3 6.2 0 14.7-.1 8.3-.1 23h-48.9c-5.1-5.7-2.7-3.1-15.4-17.4-3.2 3.5-12.8 13.9-16.1 17.4h-82v-92.3h83.1c5 5.6 2.8 3.1 15.5 17.2 3.2-3.5 12.2-13.4 15.7-17.2h58c9.8 0 18 1.9 24.3 5.6v-5.6c54.3 0 64.3-1.4 75.7 5.1v-5.1h78.2v5.2c11.4-6.9 19.6-5.2 64.9-5.2v5c10.3-5.9 16.6-5.2 54.3-5V80c0-26.5-21.5-48-48-48h-480c-26.5 0-48 21.5-48 48v109.8c9.4-21.9 19.7-46 23.1-53.9h39.7c4.3 10.1 1.6 3.7 9 21.1v-21.1h46c2.9 6.2 11.1 24 13.9 30 5.8-13.6 10.1-23.9 12.6-30h103c0-.1 11.5 0 11.6 0 43.7.2 53.6-.8 64.4 5.3v-5.3H363v9.3c7.6-6.1 17.9-9.3 30.7-9.3h27.6c0 .5 1.9.3 2.3.3H456c4.2 9.8 2.6 6 8.8 20.6v-20.6h43.3c4.9 8-1-1.8 11.2 18.4v-18.4h39.9v92h-41.6c-5.4-9-1.4-2.2-13.2-21.9v21.9h-52.8c-6.4-14.8-.1-.3-6.6-15.3h-19c-4.2 10-2.2 5.2-6.4 15.3h-26.8c-12.3 0-22.3-3-29.7-8.9v8.9h-66.5c-.3-13.9-.1-24.8-.1-24.8-1.8-.3-3.4-.2-9.8-.2v25.1H151.2v-11.4c-2.5 5.6-2.7 5.9-5.1 11.4h-29.5c-4-8.9-2.9-6.4-5.1-11.4v11.4H58.6c-4.2-10.1-2.2-5.3-6.4-15.3H33c-4.2 10-2.2 5.2-6.4 15.3H0V432c0 26.5 21.5 48 48 48h480.1c26.5 0 48-21.5 48-48v-90.4c-12.7 8.3-32.7 6.1-67.5 6.1zm36.3-64.5H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-57 39.8h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-42.2-40.1v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5zm-56.3-108.1c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm20.4-10.5h-.1zm-16.2-15.2c-23.5 0-34 12-34 35.3 0 22.2 10.2 34 33 34h19.2l6.4-15.3h34.3l6.6 15.3h33.7v-51.9l31.2 51.9h23.6v-69h-16.9v48.1l-29.1-48.1h-25.3v65.4l-27.9-65.4h-24.8l-23.5 54.5h-7.4c-13.3 0-16.1-8.1-16.1-19.9 0-23.8 15.7-20 33.1-19.7v-15.2zm42.1 12.1l11.2 27.6h-22.8zm-101.1-12v69.3h16.9v-69.3z\"]\n  };\n  var faCcApplePay = {\n    prefix: 'fab',\n    iconName: 'cc-apple-pay',\n    icon: [576, 512, [], \"f416\", \"M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z\"]\n  };\n  var faCcDinersClub = {\n    prefix: 'fab',\n    iconName: 'cc-diners-club',\n    icon: [576, 512, [], \"f24c\", \"M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z\"]\n  };\n  var faCcDiscover = {\n    prefix: 'fab',\n    iconName: 'cc-discover',\n    icon: [576, 512, [], \"f1f2\", \"M520.4 196.1c0-7.9-5.5-12.1-15.6-12.1h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-44.1 138.9c22.6 0 52.9-4.1 52.9 24.4 0 12.6-6.6 20.7-18.7 23.2l25.8 34.4h-19.6l-22.2-32.8h-2.2v32.8h-16zm-55.9.1h45.3v14H444v18.2h28.3V217H444v22.2h29.3V253H428zm-68.7 0l21.9 55.2 22.2-55.2h17.5l-35.5 84.2h-8.6l-35-84.2zm-55.9-3c24.7 0 44.6 20 44.6 44.6 0 24.7-20 44.6-44.6 44.6-24.7 0-44.6-20-44.6-44.6 0-24.7 20-44.6 44.6-44.6zm-49.3 6.1v19c-20.1-20.1-46.8-4.7-46.8 19 0 25 27.5 38.5 46.8 19.2v19c-29.7 14.3-63.3-5.7-63.3-38.2 0-31.2 33.1-53 63.3-38zm-97.2 66.3c11.4 0 22.4-15.3-3.3-24.4-15-5.5-20.2-11.4-20.2-22.7 0-23.2 30.6-31.4 49.7-14.3l-8.4 10.8c-10.4-11.6-24.9-6.2-24.9 2.5 0 4.4 2.7 6.9 12.3 10.3 18.2 6.6 23.6 12.5 23.6 25.6 0 29.5-38.8 37.4-56.6 11.3l10.3-9.9c3.7 7.1 9.9 10.8 17.5 10.8zM55.4 253H32v-82h23.4c26.1 0 44.1 17 44.1 41.1 0 18.5-13.2 40.9-44.1 40.9zm67.5 0h-16v-82h16zM544 433c0 8.2-6.8 15-15 15H128c189.6-35.6 382.7-139.2 416-160zM74.1 191.6c-5.2-4.9-11.6-6.6-21.9-6.6H48v54.2h4.2c10.3 0 17-2 21.9-6.4 5.7-5.2 8.9-12.8 8.9-20.7s-3.2-15.5-8.9-20.5z\"]\n  };\n  var faCcJcb = {\n    prefix: 'fab',\n    iconName: 'cc-jcb',\n    icon: [576, 512, [], \"f24b\", \"M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z\"]\n  };\n  var faCcMastercard = {\n    prefix: 'fab',\n    iconName: 'cc-mastercard',\n    icon: [576, 512, [], \"f1f1\", \"M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z\"]\n  };\n  var faCcPaypal = {\n    prefix: 'fab',\n    iconName: 'cc-paypal',\n    icon: [576, 512, [], \"f1f4\", \"M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z\"]\n  };\n  var faCcStripe = {\n    prefix: 'fab',\n    iconName: 'cc-stripe',\n    icon: [576, 512, [], \"f1f5\", \"M492.4 220.8c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7zM375 223.4c-8.2 0-13.3 2.9-17 7l.2 52.8c3.5 3.7 8.5 6.7 16.8 6.7 13.1 0 21.9-14.3 21.9-33.4 0-18.6-9-33.2-21.9-33.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM122.2 281.1c0 25.6-20.3 40.1-49.9 40.3-12.2 0-25.6-2.4-38.8-8.1v-33.9c12 6.4 27.1 11.3 38.9 11.3 7.9 0 13.6-2.1 13.6-8.7 0-17-54-10.6-54-49.9 0-25.2 19.2-40.2 48-40.2 11.8 0 23.5 1.8 35.3 6.5v33.4c-10.8-5.8-24.5-9.1-35.3-9.1-7.5 0-12.1 2.2-12.1 7.7 0 16 54.3 8.4 54.3 50.7zm68.8-56.6h-27V275c0 20.9 22.5 14.4 27 12.6v28.9c-4.7 2.6-13.3 4.7-24.9 4.7-21.1 0-36.9-15.5-36.9-36.5l.2-113.9 34.7-7.4v30.8H191zm74 2.4c-4.5-1.5-18.7-3.6-27.1 7.4v84.4h-35.5V194.2h30.7l2.2 10.5c8.3-15.3 24.9-12.2 29.6-10.5h.1zm44.1 91.8h-35.7V194.2h35.7zm0-142.9l-35.7 7.6v-28.9l35.7-7.6zm74.1 145.5c-12.4 0-20-5.3-25.1-9l-.1 40.2-35.5 7.5V194.2h31.3l1.8 8.8c4.9-4.5 13.9-11.1 27.8-11.1 24.9 0 48.4 22.5 48.4 63.8 0 45.1-23.2 65.5-48.6 65.6zm160.4-51.5h-69.5c1.6 16.6 13.8 21.5 27.6 21.5 14.1 0 25.2-3 34.9-7.9V312c-9.7 5.3-22.4 9.2-39.4 9.2-34.6 0-58.8-21.7-58.8-64.5 0-36.2 20.5-64.9 54.3-64.9 33.7 0 51.3 28.7 51.3 65.1 0 3.5-.3 10.9-.4 12.9z\"]\n  };\n  var faCcVisa = {\n    prefix: 'fab',\n    iconName: 'cc-visa',\n    icon: [576, 512, [], \"f1f0\", \"M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z\"]\n  };\n  var faDiscourse = {\n    prefix: 'fab',\n    iconName: 'discourse',\n    icon: [448, 512, [], \"f393\", \"M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z\"]\n  };\n  var faDocker = {\n    prefix: 'fab',\n    iconName: 'docker',\n    icon: [640, 512, [], \"f395\", \"M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z\"]\n  };\n  var faGithub = {\n    prefix: 'fab',\n    iconName: 'github',\n    icon: [496, 512, [], \"f09b\", \"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\"]\n  };\n  var faInstagram = {\n    prefix: 'fab',\n    iconName: 'instagram',\n    icon: [448, 512, [], \"f16d\", \"M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z\"]\n  };\n  var faMicrosoft = {\n    prefix: 'fab',\n    iconName: 'microsoft',\n    icon: [448, 512, [], \"f3ca\", \"M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z\"]\n  };\n  var faRev = {\n    prefix: 'fab',\n    iconName: 'rev',\n    icon: [448, 512, [], \"f5b2\", \"M289.67 274.89a65.57 65.57 0 1 1-65.56-65.56 65.64 65.64 0 0 1 65.56 65.56zm139.55-5.05h-.13a204.69 204.69 0 0 0-74.32-153l-45.38 26.2a157.07 157.07 0 0 1 71.81 131.84C381.2 361.5 310.73 432 224.11 432S67 361.5 67 274.88c0-81.88 63-149.27 143-156.43v39.12l108.77-62.79L210 32v38.32c-106.7 7.25-191 96-191 204.57 0 111.59 89.12 202.29 200.06 205v.11h210.16V269.84z\"]\n  };\n  var faSlack = {\n    prefix: 'fab',\n    iconName: 'slack',\n    icon: [448, 512, [], \"f198\", \"M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z\"]\n  };\n  var faTwitter = {\n    prefix: 'fab',\n    iconName: 'twitter',\n    icon: [512, 512, [], \"f099\", \"M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z\"]\n  };\n  var _iconsCache = {\n    faAws: faAws,\n    faCcAmazonPay: faCcAmazonPay,\n    faCcAmex: faCcAmex,\n    faCcApplePay: faCcApplePay,\n    faCcDinersClub: faCcDinersClub,\n    faCcDiscover: faCcDiscover,\n    faCcJcb: faCcJcb,\n    faCcMastercard: faCcMastercard,\n    faCcPaypal: faCcPaypal,\n    faCcStripe: faCcStripe,\n    faCcVisa: faCcVisa,\n    faDiscourse: faDiscourse,\n    faDocker: faDocker,\n    faGithub: faGithub,\n    faInstagram: faInstagram,\n    faMicrosoft: faMicrosoft,\n    faRev: faRev,\n    faSlack: faSlack,\n    faTwitter: faTwitter\n  };\n\n  exports.fab = _iconsCache;\n  exports.prefix = prefix;\n  exports.faAws = faAws;\n  exports.faCcAmazonPay = faCcAmazonPay;\n  exports.faCcAmex = faCcAmex;\n  exports.faCcApplePay = faCcApplePay;\n  exports.faCcDinersClub = faCcDinersClub;\n  exports.faCcDiscover = faCcDiscover;\n  exports.faCcJcb = faCcJcb;\n  exports.faCcMastercard = faCcMastercard;\n  exports.faCcPaypal = faCcPaypal;\n  exports.faCcStripe = faCcStripe;\n  exports.faCcVisa = faCcVisa;\n  exports.faDiscourse = faDiscourse;\n  exports.faDocker = faDocker;\n  exports.faGithub = faGithub;\n  exports.faInstagram = faInstagram;\n  exports.faMicrosoft = faMicrosoft;\n  exports.faRev = faRev;\n  exports.faSlack = faSlack;\n  exports.faTwitter = faTwitter;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-brands-svg-icons/package.json",
    "content": "{\n  \"description\": \"The iconic font, CSS, and SVG framework\",\n  \"keywords\": [\n    \"font\",\n    \"awesome\",\n    \"fontawesome\",\n    \"icon\",\n    \"svg\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://fontawesome.com\",\n  \"bugs\": {\n    \"url\": \"http://github.com/FortAwesome/Font-Awesome/issues\"\n  },\n  \"author\": {\n    \"name\": \"Dave Gandy\",\n    \"email\": \"dave@fontawesome.com\",\n    \"web\": \"http://twitter.com/davegandy\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Brian Talbot\",\n      \"web\": \"http://twitter.com/talbs\"\n    },\n    {\n      \"name\": \"Travis Chase\",\n      \"web\": \"http://twitter.com/supercodepoet\"\n    },\n    {\n      \"name\": \"Rob Madole\",\n      \"web\": \"http://twitter.com/robmadole\"\n    },\n    {\n      \"name\": \"Geremia Taglialatela\",\n      \"web\": \"http://twitter.com/gtagliala\"\n    },\n    {\n      \"name\": \"Mike Wilkerson\",\n      \"web\": \"http://twitter.com/mw77\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/FortAwesome/Font-Awesome\"\n  },\n  \"engines\": {\n    \"node\": \">=6\"\n  },\n  \"dependencies\": {\n    \"@fortawesome/fontawesome-common-types\": \"^0.2.36\"\n  },\n  \"name\": \"@fortawesome/pro-brands-svg-icons\",\n  \"main\": \"index.js\",\n  \"module\": \"index.es.js\",\n  \"jsnext:main\": \"index.es.js\",\n  \"license\": \"UNLICENSED\",\n  \"types\": \"./index.d.ts\",\n  \"sideEffects\": false,\n  \"scripts\": {\n    \"postinstall\": \"node attribution.js\"\n  }\n}"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/LICENSE.txt",
    "content": "Font Awesome Pro License\n------------------------\n\nFont Awesome Pro is commercial software that requires a paid license. Full\nFont Awesome Pro license: https://fontawesome.com/license.\n\n# Commercial License\nThe Font Awesome Pro commercial license allows you to pay for FA Pro once, own\nit, and use it just about everywhere you'd like.\n\n# Attribution\nAttribution is not required by the Font Awesome Pro commercial license.\n\n# Brand Icons\nAll brand icons are trademarks of their respective owners. The use of these\ntrademarks does not indicate endorsement of the trademark holder by Font\nAwesome, nor vice versa. **Please do not use brand logos for any purpose except\nto represent the company, product, or service to which they refer.**\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/README.md",
    "content": "# @fortawesome/free-duotone-svg-icons - SVG with JavaScript version\n\n> \"I came here to chew bubblegum and install Font Awesome 5 - and I'm all out of bubblegum\"\n\n[![npm](https://img.shields.io/npm/v/@fortawesome/free-duotone-svg-icons.svg?style=flat-square)](https://www.npmjs.com/package/@fortawesome/free-duotone-svg-icons)\n\n## Installation\n\n```\n$ npm i --save @fortawesome/free-duotone-svg-icons\n```\n\nOr\n\n```\n$ yarn add @fortawesome/free-duotone-svg-icons\n```\n\n## Documentation\n\nGet started [here](https://fontawesome.com/how-to-use/on-the-web/setup/getting-started). Continue your journey [here](https://fontawesome.com/how-to-use/on-the-web/advanced).\n\nOr go straight to the [API documentation](https://fontawesome.com/how-to-use/with-the-api).\n\n## Issues and support\n\nStart with [GitHub issues](https://github.com/FortAwesome/Font-Awesome/issues) and ping us on [Twitter](https://twitter.com/fontawesome) if you need to.\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/attribution.js",
    "content": "console.log(`Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\nLicense - https://fontawesome.com/license (Commercial License)\n`)"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faAbacus.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faAbacus: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faAbacus.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'abacus';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f640';\nvar svgPathData = ['M192 440h-32v-48h32zM160 72v48h32V72zm96 160v48h32v-48zm-96 0v48h32v-48zm96 208h160v-48H256zm96-160h128v-48H352zM544 0a32 32 0 0 0-32 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32a32 32 0 0 0-32-32zM416 72H256v48h160zM32 0A32 32 0 0 0 0 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32A32 32 0 0 0 32 0z', 'M144 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm-96 160h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm192 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm-96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zM464 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM144 352h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm224 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faAbacus = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faAlignSlash.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faAlignSlash: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faAlignSlash.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'align-slash';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f846';\nvar svgPathData = ['M528 352h-31.46l-82.81-64H528a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16zM96 304v32a16 16 0 0 0 16 16h175.21l-82.8-64H112a16 16 0 0 0-16 16zM528 96a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16H112a15.82 15.82 0 0 0-15 11.18L165.31 96zM112 416a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h340.83L370 416zm416-256H248.12l82.81 64H528a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z', 'M633.82 458.1L45.46 3.38A16 16 0 0 0 23 6.19L3.37 31.46a16 16 0 0 0 2.81 22.45l588.36 454.72a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faAlignSlash = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faAtomAlt.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faAtomAlt: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faAtomAlt.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'atom-alt';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f5d3';\nvar svgPathData = ['M424.37305,55.69141C408.294,39.61914,385.50879,32,358.58252,32,319.82764,32,272.43359,48.127,224,77.14453a493.86641,493.86641,0,0,0-58.042,41.03711C140.58252,138.875,114.57666,162.5918,85.75635,197.916a374.25237,374.25237,0,0,0,35.70263,58.082A505.23427,505.23427,0,0,1,224,153.65625a377.23937,377.23937,0,0,1,58.042-35.47266c70.01221-34.334,95.22461-19.07421,97.0625-17.23632,9.54248,9.543,7.67432,46.94531-16.86084,96.96875A492.27615,492.27615,0,0,1,403.06543,256C452.27637,173.91992,463.59277,94.90039,424.37305,55.69141ZM224,358.3418a377.44678,377.44678,0,0,1-58.042,35.47461c-70.01221,34.334-95.22461,19.07421-97.0625,17.23632-9.54248-9.543-7.67432-46.94335,16.86084-96.96875A492.27615,492.27615,0,0,1,44.93457,256C-4.27637,338.08008-15.59277,417.09961,23.627,456.30664,39.70605,472.38086,62.49121,480,89.41748,480c38.75488,0,86.14893-16.127,134.58252-45.14453a493.86641,493.86641,0,0,0,58.042-41.03711c25.38965-20.70508,51.42285-44.45606,80.20166-79.73438A373.962,373.962,0,0,0,326.541,256,505.23427,505.23427,0,0,1,224,358.3418Z', 'M224,287.98828a31.99414,31.99414,0,1,0-32-31.99414A31.98908,31.98908,0,0,0,224,287.98828ZM121.46094,255.99805A374.13921,374.13921,0,0,1,85.7583,197.916c-24.53906-50.02344-26.40625-87.42579-16.86328-96.9668,1.83984-1.83789,27.05078-17.10156,97.062,17.23242A494.241,494.241,0,0,1,224,77.14453C175.5625,48.13086,128.16406,32,89.41846,32c-26.9336,0-49.707,7.61523-65.793,23.69141C-15.59326,94.90039-4.27686,173.91992,44.93408,256A492.0174,492.0174,0,0,0,85.7583,314.084c28.79639,35.30274,54.85889,59.07227,80.19873,79.73243A377.429,377.429,0,0,0,224,358.3418,505.131,505.131,0,0,1,121.46094,255.99805ZM403.06592,256a492.0174,492.0174,0,0,0-40.82422-58.084c-28.84326-35.35547-54.89795-59.10352-80.19873-79.73243A377.4073,377.4073,0,0,0,224,153.65625,505.20556,505.20556,0,0,1,326.53906,256a373.849,373.849,0,0,1,35.70264,58.084c24.53906,50.02149,26.40625,87.42383,16.86328,96.9668-1.83984,1.83789-27.05078,17.10156-97.062-17.23242A494.241,494.241,0,0,1,224,434.85547C272.4375,463.86914,319.83594,480,358.58154,480c26.9336,0,49.707-7.61523,65.793-23.69336C463.59326,417.09961,452.27686,338.08008,403.06592,256Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faAtomAlt = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faBadgeCheck.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faBadgeCheck: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faBadgeCheck.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'badge-check';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f336';\nvar svgPathData = ['M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z', 'M367.2 211.75l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.06 15.56z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faBadgeCheck = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faBell.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faBell: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faBell.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'bell';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0f3';\nvar svgPathData = ['M448 384c-.1 16.4-13 32-32.1 32H32.08C13 416 .09 400.4 0 384a31.25 31.25 0 0 1 8.61-21.71c19.32-20.76 55.47-52 55.47-154.29 0-77.7 54.48-139.9 127.94-155.16V32a32 32 0 1 1 64 0v20.84C329.42 68.1 383.9 130.3 383.9 208c0 102.3 36.15 133.53 55.47 154.29A31.27 31.27 0 0 1 448 384z', 'M160 448h128a64 64 0 0 1-128 0z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faBell = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faBooks.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faBooks: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faBooks.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'books';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f5db';\nvar svgPathData = ['M96 0H32A32 32 0 0 0 0 32v64h128V32A32 32 0 0 0 96 0zM0 384h128V128H0zm0 96a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H0zm513.62-17.78L401.08 42.71l-60.26 16.14 112.35 418.8c.11.39.2.79.29 1.18l60.29-16.15c-.04-.15-.09-.3-.13-.46zM160 480a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H160zM256 0h-64a32 32 0 0 0-32 32v64h124.79l-8-29.65a23.94 23.94 0 0 1 11.17-27V32A32 32 0 0 0 256 0zm-96 384h128V128H160z', 'M0 416h128v-32H0zm0-288h128V96H0zm575.17 317.65L460.39 17.78a23.89 23.89 0 0 0-29.18-17h-.09L415.73 5a24 24 0 0 0-16.9 29.36l114.79 427.86a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.35zM160 416h128v-32H160zM338.39 49.78a23.89 23.89 0 0 0-29.18-17h-.09L293.73 37a24 24 0 0 0-16.9 29.36l8 29.65H160v32h128V108l103.62 386.22a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.33z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faBooks = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faBracketsCurly.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faBracketsCurly: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faBracketsCurly.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'brackets-curly';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f7ea';\nvar svgPathData = ['M566.64 233.37a32 32 0 0 1 0 45.25l-45.25 45.25a32 32 0 0 0-9.39 22.64V384a96 96 0 0 1-96 96h-48a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h48a32 32 0 0 0 32-32v-37.48a96 96 0 0 1 28.13-67.89L498.76 256l-22.62-22.62A96 96 0 0 1 448 165.47V128a32 32 0 0 0-32-32h-48a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h48a96 96 0 0 1 96 96v37.48a32 32 0 0 0 9.38 22.65l45.25 45.24z', 'M208 32h-48a96 96 0 0 0-96 96v37.48a32.12 32.12 0 0 1-9.38 22.65L9.38 233.37a32 32 0 0 0 0 45.25l45.25 45.25A32.05 32.05 0 0 1 64 346.51V384a96 96 0 0 0 96 96h48a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-48a32 32 0 0 1-32-32v-37.48a96 96 0 0 0-28.13-67.89L77.26 256l22.63-22.63A96 96 0 0 0 128 165.48V128a32 32 0 0 1 32-32h48a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faBracketsCurly = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faChartNetwork.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faChartNetwork: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faChartNetwork.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'chart-network';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f78a';\nvar svgPathData = ['M64 240a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64zm88 80h48v-32h-48zm294.4-106.8l19.2 25.6 48-36-19.2-25.6zM576 64a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64z', 'M576 384a63.84 63.84 0 0 0-38.3 13l-96-57.6a109.91 109.91 0 0 0 6.3-35.5 111.94 111.94 0 0 0-112-112 108.64 108.64 0 0 0-24.4 2.9l-40.8-87.4A63.84 63.84 0 1 0 224 128c1.1 0 2.1-.3 3.2-.3l41 87.8C241.5 235.9 224 267.8 224 304a111.71 111.71 0 0 0 193.2 76.7l95.8 57.5a63.87 63.87 0 1 0 63-54.2zm-240-32a48 48 0 1 1 48-48 48 48 0 0 1-48 48z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faChartNetwork = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faChartScatter.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faChartScatter: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faChartScatter.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'chart-scatter';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f7ee';\nvar svgPathData = ['M512 400v32a16 16 0 0 1-16 16H32a32 32 0 0 1-32-32V80a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16v304h432a16 16 0 0 1 16 16z', 'M160 256a32 32 0 1 0 32 32 32 32 0 0 0-32-32zM416 96a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-224 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm192 160a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-96-64a32 32 0 1 0 32 32 32 32 0 0 0-32-32z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faChartScatter = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faCheck.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCheck: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faCheck.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'check';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f00c';\nvar svgPathData = ['M504.5 144.42L264.75 385.5 192 312.59l240.11-241a25.49 25.49 0 0 1 36.06-.14l.14.14L504.5 108a25.86 25.86 0 0 1 0 36.42z', 'M264.67 385.59l-54.57 54.87a25.5 25.5 0 0 1-36.06.14l-.14-.14L7.5 273.1a25.84 25.84 0 0 1 0-36.41l36.2-36.41a25.49 25.49 0 0 1 36-.17l.16.17z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCheck = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faCircle.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCircle: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faCircle.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'circle';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f111';\nvar svgPathData = ['M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 424c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z', 'M256 432c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCircle = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faClouds.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faClouds: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faClouds.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'clouds';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f744';\nvar svgPathData = ['M161.6 288H96a96 96 0 0 1 0-192c.6 0 1.1.2 1.6.2C105.3 41.9 151.6 0 208 0a111.61 111.61 0 0 1 104.5 72.7A95.07 95.07 0 0 1 352 64a96 96 0 0 1 96 96 93 93 0 0 1-7 34.7 110.5 110.5 0 0 0-31.6 11.8A142.54 142.54 0 0 0 304 160c-73.9 0-134.3 56.2-142.4 128z', 'M640 416a96 96 0 0 1-96 96H224a96 96 0 0 1-96-96c0-42.5 27.8-78.2 66.1-90.8A113.72 113.72 0 0 1 192 304a111.94 111.94 0 0 1 112-112c43.2 0 80.4 24.9 99 60.8 14.7-17.5 36.4-28.8 61-28.8a80 80 0 0 1 80 80 78.09 78.09 0 0 1-1.6 16.2c.5 0 1-.2 1.6-.2a96 96 0 0 1 96 96z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faClouds = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faCogs.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCogs: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faCogs.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'cogs';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f085';\nvar svgPathData = ['M638.41 387a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4L602 335a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6 12.36 12.36 0 0 0-15.1 5.4l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 44.9c-29.6-38.5 14.3-82.4 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79zm136.8-343.8a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4l8.2-14.3a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6A12.36 12.36 0 0 0 552 7.19l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 45c-29.6-38.5 14.3-82.5 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79z', 'M420 303.79L386.31 287a173.78 173.78 0 0 0 0-63.5l33.7-16.8c10.1-5.9 14-18.2 10-29.1-8.9-24.2-25.9-46.4-42.1-65.8a23.93 23.93 0 0 0-30.3-5.3l-29.1 16.8a173.66 173.66 0 0 0-54.9-31.7V58a24 24 0 0 0-20-23.6 228.06 228.06 0 0 0-76 .1A23.82 23.82 0 0 0 158 58v33.7a171.78 171.78 0 0 0-54.9 31.7L74 106.59a23.91 23.91 0 0 0-30.3 5.3c-16.2 19.4-33.3 41.6-42.2 65.8a23.84 23.84 0 0 0 10.5 29l33.3 16.9a173.24 173.24 0 0 0 0 63.4L12 303.79a24.13 24.13 0 0 0-10.5 29.1c8.9 24.1 26 46.3 42.2 65.7a23.93 23.93 0 0 0 30.3 5.3l29.1-16.7a173.66 173.66 0 0 0 54.9 31.7v33.6a24 24 0 0 0 20 23.6 224.88 224.88 0 0 0 75.9 0 23.93 23.93 0 0 0 19.7-23.6v-33.6a171.78 171.78 0 0 0 54.9-31.7l29.1 16.8a23.91 23.91 0 0 0 30.3-5.3c16.2-19.4 33.7-41.6 42.6-65.8a24 24 0 0 0-10.5-29.1zm-151.3 4.3c-77 59.2-164.9-28.7-105.7-105.7 77-59.2 164.91 28.7 105.71 105.7z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCogs = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faCommentDots.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCommentDots: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faCommentDots.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'comment-dots';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f4ad';\nvar svgPathData = ['M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5a8 8 0 0 0-1.5 8.7A7.83 7.83 0 0 0 8 480c66.3 0 116-31.8 140.6-51.4A305 305 0 0 0 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32z', 'M128 208a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCommentDots = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faConciergeBell.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faConciergeBell: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faConciergeBell.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'concierge-bell';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f562';\nvar svgPathData = ['M512 400v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h480a16 16 0 0 1 16 16zM208 112h16v18.29a224.73 224.73 0 0 1 64 0V112h16a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16z', 'M480 352H32c0-123.71 100.29-224 224-224s224 100.29 224 224z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faConciergeBell = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faDotCircle.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faDotCircle: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faDotCircle.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'dot-circle';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f192';\nvar svgPathData = ['M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm124.45 372.45A176 176 0 1 1 432 256a174.85 174.85 0 0 1-51.55 124.45z', 'M256 336a80 80 0 1 1 80-80 80.09 80.09 0 0 1-80 80z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faDotCircle = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faEnvelope.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faEnvelope: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faEnvelope.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'envelope';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0e0';\nvar svgPathData = ['M256.47 352h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V400a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V183.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52zM464 64H48a48 48 0 0 0-48 48v19a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4 23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131v-19a48 48 0 0 0-48-48z', 'M512 131v52.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V131a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.69 12.12 49.75 41.4 72.93 41.4h.94c23.18 0 56.24-29.28 72.93-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faEnvelope = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faExchangeAlt.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faExchangeAlt: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faExchangeAlt.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'exchange-alt';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f362';\nvar svgPathData = ['M128 272v48h360a24 24 0 0 1 24 24v16a24 24 0 0 1-24 24H128v48c0 21.44-25.94 32-41 17L7 369a24 24 0 0 1 0-33.94l80-80c15.14-15.12 41-4.35 41 16.94z', 'M505 143.05a24 24 0 0 1 0 33.95l-80 80c-15 15-41 4.49-41-17v-48H24a24 24 0 0 1-24-24v-16a24 24 0 0 1 24-24h360V80c0-21.36 25.9-32 41-17z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faExchangeAlt = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faFileAlt.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faFileAlt: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faFileAlt.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'file-alt';\nvar width = 384;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f15c';\nvar svgPathData = ['M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zm-96 244a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12z', 'M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM276 352H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faFileAlt = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faFileCode.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faFileCode: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faFileCode.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'file-code';\nvar width = 384;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1c9';\nvar svgPathData = ['M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zM141.79 379.54l-19.58 20.84a5.41 5.41 0 0 1-7.64.24l-64.86-60.69a5.37 5.37 0 0 1-.24-7.6l.25-.25 64.86-60.7a5.42 5.42 0 0 1 7.64.24l19.58 20.85a5.4 5.4 0 0 1-.25 7.62l-.13.12L100.65 336l40.76 35.8a5.4 5.4 0 0 1 .49 7.62zm31.71 71.25l-27.45-8a5.38 5.38 0 0 1-3.67-6.67l61.49-211.24a5.38 5.38 0 0 1 6.68-3.64l27.45 8a5.4 5.4 0 0 1 3.63 6.67l-61.45 211.2a5.4 5.4 0 0 1-6.68 3.68zm161-111.12l-.25.25-64.86 60.69a5.42 5.42 0 0 1-7.64-.23l-19.58-20.84a5.37 5.37 0 0 1 .26-7.6l.13-.12L283.35 336l-40.76-35.8a5.4 5.4 0 0 1-.49-7.62l.11-.12 19.58-20.85a5.42 5.42 0 0 1 7.64-.24l64.86 60.7a5.36 5.36 0 0 1 .25 7.6z', 'M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM141.41 371.8L100.65 336l40.76-35.8.13-.12a5.4 5.4 0 0 0 .25-7.62l-19.58-20.85a5.42 5.42 0 0 0-7.64-.24l-64.86 60.7-.25.25a5.37 5.37 0 0 0 .24 7.6l64.86 60.69a5.41 5.41 0 0 0 7.64-.24l19.58-20.84.11-.12a5.4 5.4 0 0 0-.48-7.61zm100.22-135.93a5.4 5.4 0 0 0-3.63-6.67l-27.45-8a5.38 5.38 0 0 0-6.68 3.64l-61.5 211.29a5.38 5.38 0 0 0 3.63 6.67l27.45 8a5.4 5.4 0 0 0 6.68-3.68l61.44-211.22zm92.66 96.2l-64.86-60.7a5.42 5.42 0 0 0-7.64.24l-19.58 20.85-.11.12a5.4 5.4 0 0 0 .49 7.62l40.76 35.8-40.76 35.8-.13.12a5.37 5.37 0 0 0-.26 7.6l19.58 20.84a5.42 5.42 0 0 0 7.64.23l64.86-60.69.25-.25a5.36 5.36 0 0 0-.25-7.6z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faFileCode = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGlobe.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faGlobe: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGlobe.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'globe';\nvar width = 496;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0ac';\nvar svgPathData = ['M340.45,320H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256,575,575,0,0,1,340.45,320ZM160.2,160H335.8c-.41-2.31-.84-4.62-1.28-6.91-6-30.85-14.42-58.37-25.13-81.78C299.54,49.77,288,32.54,276.05,21.48,266.38,12.53,256.94,8,248,8s-18.38,4.53-28,13.48c-12,11.06-23.49,28.29-33.34,49.83C176,94.72,167.5,122.24,161.53,153.09,161,155.38,160.61,157.69,160.2,160ZM120,256a608,608,0,0,1,3.34-64H8.35a249.52,249.52,0,0,0,0,128h115A608,608,0,0,1,120,256Zm367.62-64h-115A608.06,608.06,0,0,1,376,256a608,608,0,0,1-3.34,64h115a249.52,249.52,0,0,0,0-128ZM476.7,160A248.62,248.62,0,0,0,315.58,17.32c24.13,33,42.89,83.15,52.75,142.68ZM315.58,494.68A248.59,248.59,0,0,0,476.71,352H368.33C358.47,411.53,339.71,461.68,315.58,494.68ZM335.8,352H160.2c.41,2.31.84,4.62,1.28,6.91,6,30.85,14.42,58.37,25.13,81.78,9.85,21.54,21.38,38.77,33.34,49.83,9.67,9,19.11,13.48,28.05,13.48s18.38-4.53,28.05-13.48c12-11.06,23.49-28.29,33.34-49.83,10.71-23.41,19.16-50.93,25.13-81.78C335,356.62,335.39,354.31,335.8,352ZM180.42,17.32A248.59,248.59,0,0,0,19.29,160H127.67C137.53,100.47,156.29,50.32,180.42,17.32ZM19.29,352A248.59,248.59,0,0,0,180.42,494.68c-24.13-33-42.89-83.15-52.75-142.68Z', 'M376,256a608,608,0,0,0-3.34-64h115a245.72,245.72,0,0,0-10.92-32H368.33c-9.86-59.53-28.62-109.68-52.75-142.68A248.23,248.23,0,0,0,248,8c8.94,0,18.38,4.53,28.05,13.48,12,11.06,23.49,28.29,33.34,49.83,10.71,23.41,19.16,50.93,25.13,81.78.44,2.29.87,4.6,1.28,6.91H160.2c.41-2.31.84-4.62,1.28-6.91,6-30.85,14.42-58.37,25.13-81.78C196.46,49.77,208,32.54,220,21.48,229.62,12.53,239.06,8,248,8a248.23,248.23,0,0,0-67.58,9.32c-24.13,33-42.89,83.15-52.75,142.68H19.29A245.72,245.72,0,0,0,8.37,192h115a613.93,613.93,0,0,0,0,128H8.37a245.72,245.72,0,0,0,10.92,32H127.67c9.86,59.53,28.62,109.68,52.75,142.68A248.23,248.23,0,0,0,248,504c-8.94,0-18.38-4.53-28.05-13.48-12-11.06-23.49-28.29-33.34-49.83-10.71-23.41-19.16-50.93-25.13-81.78-.44-2.29-.87-4.6-1.28-6.91H335.8c-.41,2.31-.84,4.62-1.28,6.91-6,30.85-14.42,58.37-25.13,81.78-9.85,21.54-21.38,38.77-33.34,49.83-9.67,9-19.11,13.48-28.05,13.48a248.23,248.23,0,0,0,67.58-9.32c24.13-33,42.89-83.15,52.75-142.68H476.71a245.72,245.72,0,0,0,10.92-32h-115A605.37,605.37,0,0,0,376,256Zm-35.54,64H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256a575,575,0,0,1-3.55,64Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faGlobe = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGlobeAfrica.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faGlobeAfrica: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGlobeAfrica.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'globe-africa';\nvar width = 496;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f57c';\nvar svgPathData = ['M491.33,208H423.5A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05A249.89,249.89,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256A249.51,249.51,0,0,0,491.33,208Z', 'M423.5,208A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05C386,23.7,471,104.24,491.34,208Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faGlobeAfrica = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGlobeAmericas.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faGlobeAmericas: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGlobeAmericas.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'globe-americas';\nvar width = 496;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f57d';\nvar svgPathData = ['M489.55,312.41C464,422.22,365.59,504,248,504,111,504,0,393,0,256A247,247,0,0,1,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311l-13.71-13.67A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A247,247,0,0,1,248,8C351.83,8,440.71,71.76,477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1Z', 'M321.39,297.36A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A249,249,0,0,0,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311ZM477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1,55.64,29.22a249.21,249.21,0,0,0-11.88-150.14Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faGlobeAmericas = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGlobeAsia.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faGlobeAsia: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGlobeAsia.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'globe-asia';\nvar width = 496;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f57e';\nvar svgPathData = ['M312,16.35V50.73a28,28,0,0,1-11.12,22.35l-41.41,31.27a8,8,0,0,0,.86,13.81l10.83,5.41A16,16,0,0,1,280,137.88V216a8,8,0,0,1-8,8h-3.06a8,8,0,0,1-7.15-4.42,4.47,4.47,0,0,0-1.72-1.86,4.42,4.42,0,0,0-6.06,1.54h0l-17.34,29A16,16,0,0,1,222.94,256h-.31a16,16,0,0,0-11.32,4.69l-5.66,5.66a8,8,0,0,0,0,11.31l5.66,5.66A16,16,0,0,1,216,294.63V304a16,16,0,0,1-16,16h-6.1a16,16,0,0,1-14.28-8.85L157,265.92a8,8,0,0,0-10.72-3.6h0a8.14,8.14,0,0,0-2.11,1.53l-19.47,19.46A16,16,0,0,1,113.38,288H2.05C17.74,409.88,121.84,504,248,504c137,0,248-111,248-248C496,141.13,418,44.56,312,16.35Zm96,342.08a16,16,0,0,1-4.69,11.31l-9.57,9.57A16,16,0,0,1,382.43,384H367.27a16,16,0,0,1-11.36-4.74l-13-13a26.78,26.78,0,0,0-25.42-7l-21.27,5.32a15.86,15.86,0,0,1-3.88.48H282a16,16,0,0,1-11.24-4.69l-11.91-11.91a8,8,0,0,1-2.34-5.66V332.6a8,8,0,0,1,5-7.43l39.34-15.74a26.35,26.35,0,0,0,5.59-3.05l23.71-16.89a8,8,0,0,1,4.64-1.48h12.14a8,8,0,0,1,7.39,4.93l5.35,12.85a4,4,0,0,0,3.69,2.46h3.8a4,4,0,0,0,3.84-2.88l4.16-14.49A4,4,0,0,1,379,288h6.06a4,4,0,0,1,4,4v13a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,1,408,333.83Z', 'M260.07,217.72a4.47,4.47,0,0,1,1.72,1.86,8,8,0,0,0,7.15,4.42H272a8,8,0,0,0,8-8V137.88a16,16,0,0,0-8.84-14.31l-10.83-5.41a8,8,0,0,1-.86-13.81l41.41-31.27A28,28,0,0,0,312,50.73V16.35A248.23,248.23,0,0,0,248,8C111,8,0,119,0,256a249.89,249.89,0,0,0,2.05,32H113.38a16,16,0,0,0,11.31-4.69l19.47-19.46A8,8,0,0,1,157,265.92l22.62,45.23A16,16,0,0,0,193.9,320H200a16,16,0,0,0,16-16v-9.37a16,16,0,0,0-4.69-11.31l-5.66-5.66a8,8,0,0,1,0-11.31l5.66-5.66A16,16,0,0,1,222.63,256h.31a16,16,0,0,0,13.72-7.77L254,219.28a4.42,4.42,0,0,1,6.05-1.57Zm143.24,104.8L391.4,310.61a8,8,0,0,1-2.34-5.66V292a4,4,0,0,0-4-4H379a4,4,0,0,0-3.84,2.88L371,305.37a4,4,0,0,1-3.84,2.88h-3.8a4,4,0,0,1-3.69-2.46l-5.35-12.85a8,8,0,0,0-7.39-4.93H334.79a8,8,0,0,0-4.64,1.48l-23.71,16.89a26.35,26.35,0,0,1-5.59,3.05l-39.34,15.74a8,8,0,0,0-5,7.43v10.2a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,0,282,365.06h10.34a15.86,15.86,0,0,0,3.88-.48l21.27-5.32a26.78,26.78,0,0,1,25.42,7l13,13A16,16,0,0,0,367.27,384h15.16a16,16,0,0,0,11.31-4.69l9.57-9.57A16,16,0,0,0,408,358.43v-24.6a16,16,0,0,0-4.69-11.31Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faGlobeAsia = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGlobeEurope.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faGlobeEurope: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGlobeEurope.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'globe-europe';\nvar width = 496;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f7a2';\nvar svgPathData = ['M487.54,320.4H438.9a15.8,15.8,0,0,1-11.4-4.8l-32-32.6a11.92,11.92,0,0,1,.1-16.7l12.5-12.5v-8.7a11.37,11.37,0,0,0-3.3-8l-9.4-9.4a11.37,11.37,0,0,0-8-3.3h-16a11.31,11.31,0,0,1-8-19.3l9.4-9.4a11.37,11.37,0,0,1,8-3.3h32a11.35,11.35,0,0,0,11.3-11.3v-9.4a11.35,11.35,0,0,0-11.3-11.3H376.1a16,16,0,0,0-16,16v4.5a16,16,0,0,1-10.9,15.2l-31.6,10.5a8,8,0,0,0-5.5,7.6v2.2a8,8,0,0,1-8,8h-16a8,8,0,0,1-8-8,8,8,0,0,0-8-8H269a8.14,8.14,0,0,0-7.2,4.4l-9.4,18.7a15.94,15.94,0,0,1-14.3,8.8H216a16,16,0,0,1-16-16V199a16,16,0,0,1,4.7-11.3l20.1-20.1a24.77,24.77,0,0,0,7.2-17.5,8,8,0,0,1,5.5-7.6l40-13.3a11.66,11.66,0,0,0,4.4-2.7l26.8-26.8a11.31,11.31,0,0,0-8-19.3H280l-16,16v8a8,8,0,0,1-8,8H240a8,8,0,0,1-8-8v-20a8.05,8.05,0,0,1,3.2-6.4l82.42-60.08A247.79,247.79,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504a251.57,251.57,0,0,0,32.1-2.06V448.4a16,16,0,0,0-16-16H243.9c-10.8,0-26.7-5.3-35.4-11.8l-22.2-16.7a45.42,45.42,0,0,1-18.2-36.4V343.6a45.46,45.46,0,0,1,22.1-39l42.9-25.7a46.13,46.13,0,0,1,23.4-6.5h31.2a45.62,45.62,0,0,1,29.6,10.9l43.2,37.1h18.3a32,32,0,0,1,22.6,9.4l17.3,17.3.08.08C432,359.06,440,375.62,440,393.37V413A247.11,247.11,0,0,0,487.54,320.4ZM187.4,157.1a11.37,11.37,0,0,1-8,3.3h-16a11.31,11.31,0,0,1-8-19.3l25.4-25.4a11.31,11.31,0,0,1,19.3,8v16a11.37,11.37,0,0,1-3.3,8Z', 'M187.4,157.1l9.4-9.4a11.37,11.37,0,0,0,3.3-8v-16a11.31,11.31,0,0,0-19.3-8l-25.4,25.4a11.31,11.31,0,0,0,8,19.3h16A11.37,11.37,0,0,0,187.4,157.1ZM418.78,347.18l-.08-.08-17.3-17.3a32,32,0,0,0-22.6-9.4H360.5l-43.2-37.1a45.62,45.62,0,0,0-29.6-10.9H256.5a46.13,46.13,0,0,0-23.4,6.5l-42.9,25.7a45.46,45.46,0,0,0-22.1,39v23.9a45.42,45.42,0,0,0,18.2,36.4l22.2,16.7c8.7,6.5,24.6,11.8,35.4,11.8h20.2a16,16,0,0,1,16,16v53.54A247.57,247.57,0,0,0,440,413V393.37C440,375.62,432,359.06,418.78,347.18ZM317.62,17.92,235.2,78a8.05,8.05,0,0,0-3.2,6.4v20a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-8l16-16h20.7a11.31,11.31,0,0,1,8,19.3l-26.8,26.8a11.66,11.66,0,0,1-4.4,2.7l-40,13.3a8,8,0,0,0-5.5,7.6,24.77,24.77,0,0,1-7.2,17.5l-20.1,20.1A16,16,0,0,0,200,199v25.3a16,16,0,0,0,16,16h22.1a15.94,15.94,0,0,0,14.3-8.8l9.4-18.7a8.14,8.14,0,0,1,7.2-4.4h3.1a8,8,0,0,1,8,8,8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-2.2a8,8,0,0,1,5.5-7.6l31.6-10.5a16,16,0,0,0,10.9-15.2v-4.5a16,16,0,0,1,16-16h36.7a11.35,11.35,0,0,1,11.3,11.3v9.4a11.35,11.35,0,0,1-11.3,11.3h-32a11.37,11.37,0,0,0-8,3.3l-9.4,9.4a11.31,11.31,0,0,0,8,19.3h16a11.37,11.37,0,0,1,8,3.3l9.4,9.4a11.37,11.37,0,0,1,3.3,8v8.7l-12.5,12.5a11.92,11.92,0,0,0-.1,16.7l32,32.6a15.8,15.8,0,0,0,11.4,4.8h48.64A248.29,248.29,0,0,0,496,256C496,143.18,420.71,48,317.62,17.92Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faGlobeEurope = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGraduationCap.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faGraduationCap: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faGraduationCap.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'graduation-cap';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f19d';\nvar svgPathData = ['M323.07 175.7L118.8 215.6a48.1 48.1 0 0 0-38.74 44.73 32 32 0 0 1 2.21 53.94l25.4 114.26A16 16 0 0 1 92 448H35.94a16 16 0 0 1-15.61-19.47l25.39-114.27a32 32 0 0 1 2.33-54 80.16 80.16 0 0 1 64.62-76.07l204.26-39.89a16 16 0 1 1 6.14 31.4z', 'M622.33 198.8l-279 85.7a80 80 0 0 1-46.79 0L99.67 224a47.84 47.84 0 0 1 19.13-8.39l204.27-39.9a16 16 0 1 0-6.14-31.4l-204.26 39.88a79.87 79.87 0 0 0-47.57 29.18l-47.44-14.58c-23.54-7.23-23.54-38.36 0-45.59L296.6 67.5a79.92 79.92 0 0 1 46.8 0l278.93 85.7c23.55 7.24 23.55 38.36 0 45.6zM352.79 315.09a111.94 111.94 0 0 1-65.59 0l-145-44.55L128 384c0 35.35 86 64 192 64s192-28.65 192-64l-14.19-113.47z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faGraduationCap = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faHistory.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faHistory: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faHistory.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'history';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1da';\nvar svgPathData = ['M141.68 400.23a184 184 0 1 0-11.75-278.3l50.76 50.76c10.08 10.08 2.94 27.31-11.32 27.31H24a16 16 0 0 1-16-16V38.63c0-14.26 17.23-21.4 27.31-11.32l49.38 49.38A247.14 247.14 0 0 1 256 8c136.81 0 247.75 110.78 248 247.53S392.82 503.9 256.18 504a247 247 0 0 1-155.82-54.91 24 24 0 0 1-1.84-35.61l11.27-11.27a24 24 0 0 1 31.89-1.98z', 'M288 152v104.35L328.7 288a24 24 0 0 1 4.21 33.68l-9.82 12.62a24 24 0 0 1-33.68 4.21L224 287.65V152a24 24 0 0 1 24-24h16a24 24 0 0 1 24 24z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faHistory = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faKey.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faKey: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faKey.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'key';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f084';\nvar svgPathData = ['M303.06 348.91l.1.09-24 27a24 24 0 0 1-17.94 8H224v40a24 24 0 0 1-24 24h-40v40a24 24 0 0 1-24 24H24a24 24 0 0 1-24-24v-78a24 24 0 0 1 7-17l161.83-161.83-.11-.35a176.24 176.24 0 0 0 134.34 118.09z', 'M336 0a176 176 0 1 0 176 176A176 176 0 0 0 336 0zm48 176a48 48 0 1 1 48-48 48 48 0 0 1-48 48z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faKey = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faKeySkeleton.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faKeySkeleton: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faKeySkeleton.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'key-skeleton';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f6f3';\nvar svgPathData = ['M251.31 372.91a16 16 0 0 1 0 22.63l-15.77 15.77a16 16 0 0 1-22.62 0L176 374.4l-30.87 30.86 36.11 36.11a16 16 0 0 1 0 22.63l-43.16 43.17a16 16 0 0 1-22.62 0l-36.12-36.11-36.26 36.25a16 16 0 0 1-22.62 0L4.69 491.54a16 16 0 0 1 0-22.63l255.12-255.12a64.18 64.18 0 0 0 38.4 38.4L214.4 336l36.91 36.91z', 'M448 0H320a64 64 0 0 0-64 64v128a64 64 0 0 0 64 64h128a64 64 0 0 0 64-64V64a64 64 0 0 0-64-64zm-73.37 182.63a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25zm64-64a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faKeySkeleton = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLaptop.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faLaptop: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLaptop.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'laptop';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f109';\nvar svgPathData = ['M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z', 'M512 64H128v256h384zm112 352H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faLaptop = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLaptopCode.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faLaptopCode: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLaptopCode.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'laptop-code';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f5fc';\nvar svgPathData = ['M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z', 'M624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16zM512 64H128v256h384zM289 250.34l-11.31 11.31a16 16 0 0 1-22.63 0l-58.35-58.34a16 16 0 0 1 0-22.63L255 122.34a16 16 0 0 1 22.63 0L289 133.65a16 16 0 0 1 0 22.63L253.25 192 289 227.71a16 16 0 0 1 0 22.63zm154.35-47L385 261.66a16 16 0 0 1-22.63 0L351 250.35a16 16 0 0 1 0-22.63L386.75 192 351 156.29a16 16 0 0 1 0-22.63l11.31-11.31a16 16 0 0 1 22.63 0l58.34 58.34a16 16 0 0 1 .04 22.63z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faLaptopCode = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLaptopHouse.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faLaptopHouse: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLaptopHouse.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'laptop-house';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'e066';\nvar svgPathData = ['M272,416H96a32,32,0,0,1-32-32V219.88L42.34,239A16.51,16.51,0,0,1,33,242.48a16.22,16.22,0,0,1-10.63-4.78L3.55,216.42A16.4,16.4,0,0,1,0,207a16.15,16.15,0,0,1,4.78-10.61L216.58,8.92C222.12,4,232.64,0,240.05,0S258,4,263.5,8.92L352,87.3V48a16,16,0,0,1,16-16h32a16,16,0,0,1,16,16v96l59.24,52.42A16.31,16.31,0,0,1,480,207a16.51,16.51,0,0,1-3.58,9.44L469.74,224H332.8c-17.8,0-33.69,8.24-44.82,21.12V208a16,16,0,0,0-16-16H208a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16h64Z', 'M629.33,448H592V288c0-17.67-12.89-32-28.8-32H332.8c-15.91,0-28.8,14.33-28.8,32V448H266.67A10.67,10.67,0,0,0,256,458.67v10.66A42.82,42.82,0,0,0,298.6,512H597.4A42.82,42.82,0,0,0,640,469.33V458.67A10.67,10.67,0,0,0,629.33,448ZM544,448H352V304H544Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faLaptopHouse = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLifeRing.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faLifeRing: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLifeRing.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'life-ring';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1cd';\nvar svgPathData = ['M292.08 167l-.41-.17zm-66.62-2a96.5 96.5 0 0 1 61.08 0l112-112a248 248 0 0 0-285 0zm68.67 2.92l.52.22zm2.49 1.12l.46.21zM186.25 322l-.19-.21zm-5.51-6.36l.21.26zm1.65 2c.12.14.23.28.35.41-.12-.15-.23-.29-.35-.43zm1.74 2l.36.4zm135.51-135.51l.4.36zM177.51 311.29l-.1-.15zM304.18 173l.34.19zm11.42 7.78l.26.21zm6.36 5.51l-.21-.19zm-3.96-3.55l-.42-.35zm-11.6-8.43l.47.29zm4.68 3.09l.17.12zm-2-1.35l-.43-.29zm-9.71-5.68l-.1-.05zm-123.61 32.91c.1-.14.19-.28.28-.42-.04.14-.18.28-.28.42zm-1.45 2.28l.29-.46zm-1.31 2.25l.19-.32zm-2.6 4.77zm10.38-16.18l.21-.26zm2-2.43c-.12.13-.23.27-.35.41.08-.14.19-.28.31-.38zm-5.33 6.89l.1-.15zm-8.2 14.07c-.07.14-.13.29-.2.43.03-.14.09-.29.16-.43zm5.39 92l-.29-.46zm-4.27-7.53v.05zm2.82 5.14l-.19-.32zm2.61 4.21c.1.14.19.28.28.42-.08-.17-.22-.31-.32-.45zm-6.8-12.11c.07.14.13.29.2.43-.06-.14-.12-.29-.2-.43zm-2-76.7c0 .13-.1.25-.16.38.07-.13.16-.25.16-.38zm1.09-2.58c-.07.17-.15.34-.22.5.13-.16.13-.33.23-.5zm-.22 76.78c.07.16.15.33.22.5-.09-.17-.09-.34-.21-.5zm-1-2.46c.06.13.11.25.16.38-.03-.13-.12-.25-.18-.38zm172-84.19l.19.32zM327.51 320l.36-.4zm-1.57 1.71l-.19.21zM325.75 190l.19.21zm3.51 128c.12-.13.23-.27.35-.41-.12.17-.23.31-.35.41zm2-121.63l-.21-.26zm0 119.2l-.21.26zm-1.65-121.22c-.12-.14-.23-.28-.35-.41.12.16.23.3.35.44zm-1.74-2l-.36-.4zm6.62 8.35l.1.15zm.1 110.43l-.1.15zM398.49 53q2 1.41 4 2.85-2-1.43-4-2.85zM343.9 294.64c.07-.17.15-.34.22-.5-.07.16-.12.33-.22.5zm1.09-2.58c.05-.13.1-.25.16-.38-.06.13-.15.25-.15.38zm-3.35 7.36v-.05zm-5.4 9.3l-.28.42zm1.45-2.28l-.29.46zm1.35-2.25l-.19.32zm3.75-7.12c.07-.14.13-.29.2-.43-.07.14-.13.29-.2.43zM449 100.21q-1.41-1.75-2.85-3.46 1.39 1.71 2.85 3.46zM445.49 96c-1-1.18-2-2.35-3-3.51 1 1.19 2.01 2.36 3 3.51zm6.87 8.5q-1.36-1.74-2.76-3.5 1.4 1.76 2.76 3.53zm3.36 4.44c-.91-1.23-1.83-2.44-2.75-3.65.92 1.24 1.84 2.45 2.75 3.71zm-119.48 94.34l-.28-.42zm66.76-147q1.85 1.36 3.66 2.76-1.78-1.39-3.66-2.76zm12.23 9.62q-1.72-1.44-3.47-2.85 1.77 1.41 3.5 2.85zM411 62.4q-1.74-1.4-3.51-2.77Q409.24 61 411 62.4zm8.5 7.13q-1.74-1.53-3.51-3 1.75 1.47 3.49 3zm-75.38 148.33c-.07-.16-.15-.33-.22-.5.1.17.15.34.22.5zM184.49 192l-.36.4zM343 215.36c-.07-.14-.13-.29-.2-.43.06.14.12.29.2.43zm113.16-105.8c1 1.31 1.9 2.62 2.84 3.94-.95-1.32-1.89-2.63-2.85-3.94zM337.4 205.1l.29.46zm82.53-135.18a248.82 248.82 0 0 1 22.14 22.15 250.17 250.17 0 0 0-22.14-22.15zm-74.78 150.4a6.15 6.15 0 0 1-.16-.38c.01.13.1.25.16.38zM459 398.49a248 248 0 0 0 0-285L347 225.46a96.5 96.5 0 0 1 0 61.08zM341.67 212.63zM220.33 345.15l-.41-.17zm-2.46-1l-.52-.22zm-5.3-2.49l.1.05zM322 325.75l-.21.19zM309.14 336l-.43.29zm2-1.35l.17-.12zm4.48-3.34l.26-.21zm4-3.39l.4-.36zm-1.6 1.39l-.42.35zM215.38 343l-.46-.21zm-19-11.74l-.26-.21zm-4-3.39l-.4-.36zm-6.3-137.62l.19-.21zm4 135.5l.21.19zm15.52 11.94l-.47-.29zm2.26 1.35l-.34-.19zm78.72 8a96.5 96.5 0 0 1-61.08 0L113.51 459a248 248 0 0 0 285 0zM202.86 336l.43.29zm-2-1.35l-.17-.12zM416 445.49q1.77-1.49 3.51-3-1.77 1.51-3.51 3zm43-47c-.93 1.33-1.88 2.64-2.84 3.95.95-1.31 1.9-2.62 2.84-3.95zM411.79 449q1.74-1.41 3.47-2.85-1.72 1.39-3.47 2.85zm-4.32 3.42q1.77-1.38 3.51-2.77-1.74 1.35-3.51 2.72zM455.72 403q-1.37 1.85-2.76 3.66 1.4-1.78 2.76-3.66zm-10.23 13c-1 1.18-2 2.35-3 3.51 1-1.19 2.01-2.36 3-3.51zm3.46-4.18q-1.41 1.74-2.85 3.47 1.44-1.75 2.9-3.5zm.65-.81q1.39-1.74 2.77-3.51-1.37 1.74-2.77 3.5zm-150.17-69.38a.31.31 0 0 1-.1.05.31.31 0 0 0 .1-.05zm-5.3 2.49l.52-.22zm12.31-6.43l.47-.29zm-9.82 5.31l.46-.21zm7.56-4l.34-.19zm137.9 80.89a248.94 248.94 0 0 1-22.15 22.15 248.94 248.94 0 0 0 22.15-22.11zm-39.63 36.21q-2 1.44-4 2.85 2.04-1.37 4-2.81zM292.08 345l-.41.17zM403 455.72q1.85-1.37 3.66-2.76-1.78 1.4-3.66 2.76zM194 329.26l.42.35zM69.93 92.07a248.82 248.82 0 0 1 22.14-22.15 250.17 250.17 0 0 0-22.14 22.15zm30.28-29q-1.74 1.41-3.47 2.85 1.73-1.46 3.47-2.87zm90 123l-.21.19zm4.13-3.67l-.42.35zM109.55 55.86q2-1.44 4-2.85-2.03 1.41-4 2.85zM196.14 181l.26-.21zM104.53 59.63Q102.76 61 101 62.4q1.76-1.4 3.53-2.77zm.78-.59q1.81-1.4 3.66-2.76-1.84 1.37-3.66 2.72zm87.05 125.09l-.4.36zm22.56-14.92l.46-.21zm-2.25 1.11l-.1.05zm4.68-2.22l.52-.22zm2.57-1.08l.41-.17zm-17.06 9l.43-.29zm5-3.09l-.34.19zm-7.11 4.56l.17-.12zm4.38-2.92l.47-.29zM96.74 446.1q1.73 1.44 3.47 2.85-1.74-1.41-3.47-2.85zm-33.69-34.31q1.41 1.74 2.85 3.47-1.44-1.72-2.85-3.47zm3.46 4.21c1 1.18 2 2.35 3 3.51-1-1.19-2.01-2.36-3-3.51zm-10.23-13q1.36 1.85 2.76 3.66-1.39-1.78-2.76-3.66zm3.35 4.44q1.37 1.8 2.77 3.56-1.4-1.76-2.77-3.53zm32.89 35q1.74 1.53 3.51 3-1.77-1.44-3.51-2.97zM105.31 453q1.81 1.4 3.66 2.76-1.84-1.4-3.66-2.76zm8.2 6q-2-1.41-4-2.85 2.01 1.43 4 2.85zM101 449.6q1.74 1.39 3.51 2.77-1.75-1.37-3.51-2.77zm-45.15-47.16c-1-1.31-1.9-2.62-2.84-3.95.99 1.33 1.88 2.64 2.84 3.95zM65.9 96.75q-1.44 1.71-2.85 3.46 1.41-1.75 2.85-3.46zM56.29 109c.9-1.23 1.82-2.45 2.74-3.65-.92 1.17-1.84 2.39-2.74 3.65zm6.11-8q-1.4 1.74-2.76 3.51Q61 102.76 62.4 101zm7.12-8.5c-1 1.16-2 2.33-3 3.51.98-1.16 1.99-2.33 3-3.49zm23-23q1.74-1.53 3.51-3-1.77 1.5-3.51 3.03zm-.45 372.55a248.94 248.94 0 0 1-22.15-22.15 248.94 248.94 0 0 0 22.15 22.18zM165 286.54a96.5 96.5 0 0 1 0-61.08L53 113.51a248 248 0 0 0 0 285zm-109.11-177q-1.44 2-2.84 3.93 1.36-1.95 2.8-3.9z', 'M347 225.46l112-111.95A249.4 249.4 0 0 0 398.49 53L286.54 165A96.26 96.26 0 0 1 347 225.46zm-182 61.08l-112 112a249.4 249.4 0 0 0 60.5 60.5L225.46 347A96.26 96.26 0 0 1 165 286.54zm-112-173l112 112a96.26 96.26 0 0 1 60.5-60.5L113.51 53A249.4 249.4 0 0 0 53 113.51zM286.54 347l112 112a249.4 249.4 0 0 0 60.5-60.5L347 286.54A96.26 96.26 0 0 1 286.54 347z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faLifeRing = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLightbulb.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faLightbulb: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLightbulb.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'lightbulb';\nvar width = 352;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0eb';\nvar svgPathData = ['M175.45 0C73.44.31 0 83 0 176a175 175 0 0 0 43.56 115.78c16.52 18.85 42.36 58.22 52.21 91.45 0 .26.07.52.11.78h160.24c0-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45A175.9 175.9 0 0 0 175.45 0zm.55 96a80.09 80.09 0 0 0-80 80 16 16 0 0 1-32 0A112.12 112.12 0 0 1 176 64a16 16 0 0 1 0 32z', 'M96.06 454.35L96 416h160v38.35a32 32 0 0 1-5.41 17.65l-17.09 25.73A32 32 0 0 1 206.86 512h-61.71a32 32 0 0 1-26.64-14.28L101.42 472a32 32 0 0 1-5.36-17.65z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faLightbulb = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faListAlt.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faListAlt: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faListAlt.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'list-alt';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f022';\nvar svgPathData = ['M464 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zM128 392a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm288 168a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12z', 'M128 200a40 40 0 1 0-40-40 40 40 0 0 0 40 40zm0 16a40 40 0 1 0 40 40 40 40 0 0 0-40-40zm0 96a40 40 0 1 0 40 40 40 40 0 0 0-40-40z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faListAlt = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faListUl.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faListUl: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faListUl.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'list-ul';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0ca';\nvar svgPathData = ['M496 384H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z', 'M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faListUl = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLockAlt.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faLockAlt: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faLockAlt.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'lock-alt';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f30d';\nvar svgPathData = ['M152 225H72v-72C72 69.2 140.2 1 224 1s152 68.2 152 152v72h-80v-72a72 72 0 0 0-144 0z', 'M400 225H48a48 48 0 0 0-48 48v192a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V273a48 48 0 0 0-48-48zM264 392a40 40 0 0 1-80 0v-48a40 40 0 0 1 80 0z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faLockAlt = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faMapMarkerAlt.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faMapMarkerAlt: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faMapMarkerAlt.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'map-marker-alt';\nvar width = 384;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f3c5';\nvar svgPathData = ['M192 0C86 0 0 86 0 192c0 77.41 27 99 172.27 309.67a24 24 0 0 0 39.46 0C357 291 384 269.41 384 192 384 86 298 0 192 0zm0 288a96 96 0 1 1 96-96 96 96 0 0 1-96 96z', 'M192 256a64 64 0 1 1 64-64 64 64 0 0 1-64 64z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faMapMarkerAlt = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faMoonStars.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faMoonStars: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faMoonStars.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'moon-stars';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f755';\nvar svgPathData = ['M320 32L304 0l-16 32-32 16 32 16 16 32 16-32 32-16zm138.7 149.3L432 128l-26.7 53.3L352 208l53.3 26.7L432 288l26.7-53.3L512 208z', 'M332.2 426.4c8.1-1.6 13.9 8 8.6 14.5a191.18 191.18 0 0 1-149 71.1C85.8 512 0 426 0 320c0-120 108.7-210.6 227-188.8 8.2 1.6 10.1 12.6 2.8 16.7a150.3 150.3 0 0 0-76.1 130.8c0 94 85.4 165.4 178.5 147.7z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faMoonStars = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faNetworkWired.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faNetworkWired: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faNetworkWired.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'network-wired';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f6ff';\nvar svgPathData = ['M624 232H344v-40h-48v40H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h104v40h48v-40h304v40h48v-40h104a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z', 'M224 192h192a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32H224a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32zm32-128h128v64H256zm320 256H416a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128h-96v-64h96zM224 320H64a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128H96v-64h96z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faNetworkWired = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faPlanetRinged.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faPlanetRinged: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faPlanetRinged.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'planet-ringed';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'e020';\nvar svgPathData = ['M323.33815,323.33517C186.95939,459.71018,46.2602,540.11093,9.06777,502.9165c-23.48893-23.4909.01172-88.30917,54.81792-167.21379a206.56361,206.56361,0,0,0,25.02022,43.78446c-22.45765,34.20607-32.036,58.99194-23.71941,67.31053,18.59817,18.59624,119.10094-51.75539,224.47885-157.13342C395.04325,184.2882,465.39675,83.78336,446.79858,65.18712c-8.32054-8.3186-33.10638,1.26176-67.31045,23.71748a206.52984,206.52984,0,0,0-43.78245-25.0183C414.61019,9.082,479.42839-14.42259,502.91732,9.06832,540.10975,46.2608,459.70909,186.96211,323.33815,323.33517Z', 'M448.0994,176.28016c-31.96573,46.02281-74.52549,96.81528-124.76125,147.055-50.24357,50.24168-101.034,92.79954-147.05874,124.76531,75.41614,31.25675,165.47721,16.29343,226.79531-45.02474S479.35807,251.69834,448.0994,176.28016Zm-25.02022-43.78251A208.22535,208.22535,0,0,0,403.07472,108.911c-81.2288-81.23281-212.93555-81.23281-294.16435,0-81.22881,81.23085-81.22881,212.93385,0,294.1647A208.25527,208.25527,0,0,0,132.497,423.08023c42.25117-27.73908,98.93242-75.1799,157.1684-133.41595C347.90133,231.43018,395.34013,174.75473,423.07918,132.49765Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faPlanetRinged = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faQuestionCircle.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faQuestionCircle: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faQuestionCircle.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'question-circle';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f059';\nvar svgPathData = ['M256 8C119 8 8 119.08 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 422a46 46 0 1 1 46-46 46.05 46.05 0 0 1-46 46zm40-131.33V300a12 12 0 0 1-12 12h-56a12 12 0 0 1-12-12v-4c0-41.06 31.13-57.47 54.65-70.66 20.17-11.31 32.54-19 32.54-34 0-19.82-25.27-33-45.7-33-27.19 0-39.44 13.14-57.3 35.79a12 12 0 0 1-16.67 2.13L148.82 170a12 12 0 0 1-2.71-16.26C173.4 113 208.16 90 262.66 90c56.34 0 116.53 44 116.53 102 0 77-83.19 78.21-83.19 106.67z', 'M256 338a46 46 0 1 0 46 46 46 46 0 0 0-46-46zm6.66-248c-54.5 0-89.26 23-116.55 63.76a12 12 0 0 0 2.71 16.24l34.7 26.31a12 12 0 0 0 16.67-2.13c17.86-22.65 30.11-35.79 57.3-35.79 20.43 0 45.7 13.14 45.7 33 0 15-12.37 22.66-32.54 34C247.13 238.53 216 254.94 216 296v4a12 12 0 0 0 12 12h56a12 12 0 0 0 12-12v-1.33c0-28.46 83.19-29.67 83.19-106.67 0-58-60.19-102-116.53-102z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faQuestionCircle = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faQuoteLeft.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faQuoteLeft: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faQuoteLeft.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'quote-left';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f10d';\nvar svgPathData = ['M464 256h-80v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H448a160 160 0 0 0-160 160v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z', 'M176 256H96v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H160A160 160 0 0 0 0 192v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faQuoteLeft = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faRandom.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faRandom: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faRandom.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'random';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f074';\nvar svgPathData = ['M505 359l-80-80c-15-15-41-4.47-41 17v40h-32l-52.78-56.55-53.33 57.14 70.55 75.6a12 12 0 0 0 8.77 3.81H384v40c0 21.46 26 32 41 17l80-80a24 24 0 0 0 0-34zM122.79 96H12a12 12 0 0 0-12 12v56a12 12 0 0 0 12 12h84l52.78 56.55 53.33-57.14-70.55-75.6a12 12 0 0 0-8.77-3.81z', 'M505 119a24 24 0 0 1 0 34l-80 80c-15 15-41 4.48-41-17v-40h-32L131.56 412.19a12 12 0 0 1-8.77 3.81H12a12 12 0 0 1-12-12v-56a12 12 0 0 1 12-12h84L316.44 99.81a12 12 0 0 1 8.78-3.81H384V56c0-21.44 25.94-32 41-17z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faRandom = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faRocket.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faRocket: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faRocket.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'rocket';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f135';\nvar svgPathData = ['M51.94117,154.48438,2.531,253.29688A28.125,28.125,0,0,0-.00023,264a24.00619,24.00619,0,0,0,24,24H117.4607c23.44141-47.41211,61.01172-123.373,77.89063-157.32812.51953-.91407,1-1.76758,1.52344-2.67188H94.82008C78.47633,128.01562,59.28883,139.875,51.94117,154.48438Zm172.0586,240.1621V488.209A24.12394,24.12394,0,0,0,247.9607,512a28.02965,28.02965,0,0,0,10.625-2.53125l98.72657-49.39063c14.625-7.3125,26.5-26.5,26.5-42.85937V315.70312c.0664-.041.125-.08789.1875-.1289v-.52734c-.90625.51953-1.7461,1.002-2.66407,1.52539C347.37477,333.58008,271.2732,371.252,223.99977,394.64648Z', 'M505.15992,19.51562A16.73971,16.73971,0,0,0,492.62477,6.94531C460.22633,0,434.37477,0,409.48414,0,320.3357,0,252.80836,40.61523,196.97633,127.81836c-.5586.97852-1.07031,1.877-1.625,2.85352-19.59766,39.42578-67.20313,135.70312-88.04688,177.877a31.91421,31.91421,0,0,0,6.09766,36.76172L167.05445,398.709a31.88923,31.88923,0,0,0,36.64844,5.98047l14.17578-7.01367c46.57422-23.04883,128.06641-63.3789,163.457-81.10351.96094-.54883,1.832-1.04883,2.78907-1.59766,87.23437-56.06055,127.85937-123.51172,127.85937-212.27734C512.06227,77.60742,512.12867,52.08789,505.15992,19.51562ZM367.99977,192a48,48,0,1,1,48-48.00195A48.02156,48.02156,0,0,1,367.99977,192Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faRocket = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSearch.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSearch: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSearch.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'search';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f002';\nvar svgPathData = ['M208 80a128 128 0 1 1-90.51 37.49A127.15 127.15 0 0 1 208 80m0-80C93.12 0 0 93.12 0 208s93.12 208 208 208 208-93.12 208-208S322.88 0 208 0z', 'M504.9 476.7L476.6 505a23.9 23.9 0 0 1-33.9 0L343 405.3a24 24 0 0 1-7-17V372l36-36h16.3a24 24 0 0 1 17 7l99.7 99.7a24.11 24.11 0 0 1-.1 34z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSearch = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faServer.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faServer: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faServer.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'server';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f233';\nvar svgPathData = ['M432 120a24 24 0 1 0-24-24 24 24 0 0 0 24 24zm0 272a24 24 0 1 0 24 24 24 24 0 0 0-24-24zm48-200H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z', 'M456 256a24 24 0 1 0-24 24 24 24 0 0 0 24-24zm24-224H32A32 32 0 0 0 0 64v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm48 232H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faServer = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSignOut.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSignOut: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSignOut.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'sign-out';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f08b';\nvar svgPathData = ['M180 448H96a96 96 0 0 1-96-96V160a96 96 0 0 1 96-96h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12H96a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12z', 'M353 88.3l151.9 150.6a24 24 0 0 1 0 34.1l-152 150.8a24.08 24.08 0 0 1-33.9-.1l-21.9-21.9a24.07 24.07 0 0 1 .8-34.7l77.6-71.1H184a23.94 23.94 0 0 1-24-24v-32a23.94 23.94 0 0 1 24-24h191.5l-77.6-71.1a24 24 0 0 1-.7-34.6l21.9-21.9a24 24 0 0 1 33.9-.1z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSignOut = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSirenOn.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSirenOn: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSirenOn.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'siren-on';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'e02e';\nvar svgPathData = ['M224.21,134.94a8,8,0,0,1,9-6.87l15.86,2.13a8,8,0,0,1,6.87,9L231.82,320H496L471,120.06A64,64,0,0,0,407.5,64h-175A64,64,0,0,0,169,120.06L144,320h55.54Z', 'M528,352H112a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16H528a16,16,0,0,0,16-16V368A16,16,0,0,0,528,352ZM112,192a24,24,0,0,0-24-24H24a24,24,0,0,0,0,48H88A24,24,0,0,0,112,192Zm504-24H552a24,24,0,0,0,0,48h64a24,24,0,0,0,0-48ZM90.69,76a24,24,0,1,0,26.62-39.92l-48-32A24,24,0,1,0,42.69,44ZM536,80a23.87,23.87,0,0,0,13.29-4l48-32A24,24,0,1,0,570.69,4.06l-48,32A24,24,0,0,0,536,80Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSirenOn = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSmile.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSmile: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSmile.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'smile';\nvar width = 496;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f118';\nvar svgPathData = ['M248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256,385,8,248,8Zm80,168a32,32,0,1,1-32,32A32,32,0,0,1,328,176Zm-160,0a32,32,0,1,1-32,32A32,32,0,0,1,168,176ZM362.8,346.2a149.38,149.38,0,0,1-229.6,0c-13.6-16.3,11-36.7,24.6-20.5a117.5,117.5,0,0,0,180.4,0C351.6,309.5,376.3,329.9,362.8,346.2Z', 'M328,176a32,32,0,1,0,32,32A32,32,0,0,0,328,176Zm-160,0a32,32,0,1,0,32,32A32,32,0,0,0,168,176Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSmile = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSnowman.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSnowman: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSnowman.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'snowman';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f7d0';\nvar svgPathData = ['M363.76 268.8a108.77 108.77 0 0 0 4.2-28.7v-.1a112.68 112.68 0 0 0-.73-12.8c-.11-1-.24-2-.38-3-.29-2-.62-4-1-6-.2-1-.4-1.95-.62-2.92-.22-1-.45-1.93-.7-2.9-.24-1-.5-1.91-.77-2.85-.27-.95-.55-1.89-.84-2.83-.3-.94-.6-1.87-.92-2.8-.32-.93-.65-1.86-1-2.77-.34-.92-.69-1.83-1.06-2.74-.36-.9-.74-1.8-1.13-2.7-.39-.89-.79-1.78-1.19-2.66-.41-.88-.83-1.76-1.26-2.63q-1.31-2.62-2.73-5.16c-.48-.85-1-1.68-1.46-2.51a112.44 112.44 0 0 0-21.62-26.19 96 96 0 1 0-149.16 0 112.49 112.49 0 0 0-21.68 26.28q-.74 1.23-1.44 2.49c-.48.84-.94 1.69-1.39 2.54-.45.85-.89 1.7-1.32 2.57-.43.87-.85 1.74-1.25 2.62-.41.88-.8 1.76-1.19 2.66-.39.89-.76 1.79-1.12 2.69-.36.91-.71 1.82-1.05 2.74-.34.92-.67 1.84-1 2.76a111.63 111.63 0 0 0-5.22 23.28A113 113 0 0 0 144 240h.06v.1a110.27 110.27 0 0 0 4.2 28.9A151.18 151.18 0 0 0 104 376.1c0 54 28.4 100.9 70.8 127.8 9.3 5.9 20.3 8.2 31.3 8.2h99.2a65.1 65.1 0 0 0 37.2-11.7c46.5-32.3 74.4-89.4 62.9-152.6-5.54-30.2-20.54-57.6-41.64-79zM224 96.1a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm32 272a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm0-64a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm1.7-64.1a15.19 15.19 0 0 1-3.48 0 16 16 0 1 1 3.48 0zm-1.7-87.9s-16-23.2-16-32a16 16 0 1 1 32 0c0 8.8-16 32-16 32zm32-56a16 16 0 1 1 16-16 16 16 0 0 1-16 16z', 'M510.86 152.4L505 137.9a16.15 16.15 0 0 0-20.8-8.7L456 140.7v-29a15.84 15.84 0 0 0-16-15.6h-16a15.84 15.84 0 0 0-16 15.6v46.9c0 .5.3 1 .3 1.5l-56.1 22.54a111.21 111.21 0 0 1 15.07 44.56L502 172.7a15.57 15.57 0 0 0 8.86-20.3zm-407.1 6.2v-46.9c.2-8.6-7-15.6-15.8-15.6H72a15.84 15.84 0 0 0-16 15.6v29l-28.1-11.5a16.15 16.15 0 0 0-20.8 8.7l-5.9 14.5a15.48 15.48 0 0 0 8.9 20.3l134.67 54.49a111.3 111.3 0 0 1 15-44.46l-56.31-22.63a8 8 0 0 0 .3-1.5zM256 336.1a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSnowman = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSun.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSun: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faSun.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'sun';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f185';\nvar svgPathData = ['M502.42 240.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.41-94.8a17.31 17.31 0 0 0-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4a17.31 17.31 0 0 0 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.41-33.5 47.3 94.7a17.31 17.31 0 0 0 31 0l47.31-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3a17.33 17.33 0 0 0 .2-31.1zm-155.9 106c-49.91 49.9-131.11 49.9-181 0a128.13 128.13 0 0 1 0-181c49.9-49.9 131.1-49.9 181 0a128.13 128.13 0 0 1 0 181z', 'M352 256a96 96 0 1 1-96-96 96.15 96.15 0 0 1 96 96z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSun = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faTasks.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faTasks: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faTasks.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'tasks';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0ae';\nvar svgPathData = ['M496 384H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z', 'M139.61 35.5a12 12 0 0 0-17 0L58.93 98.81l-22.7-22.12a12 12 0 0 0-17 0L3.53 92.41a12 12 0 0 0 0 17l47.59 47.4a12.78 12.78 0 0 0 17.61 0l15.59-15.62L156.52 69a12.09 12.09 0 0 0 .09-17zm0 159.19a12 12 0 0 0-17 0l-63.68 63.72-22.7-22.1a12 12 0 0 0-17 0L3.53 252a12 12 0 0 0 0 17L51 316.5a12.77 12.77 0 0 0 17.6 0l15.7-15.69 72.2-72.22a12 12 0 0 0 .09-16.9zM64 368c-26.49 0-48.59 21.5-48.59 48S37.53 464 64 464a48 48 0 0 0 0-96z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faTasks = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faUniversity.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUniversity: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faUniversity.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'university';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f19c';\nvar svgPathData = ['M160,192V384h64V192h64V384h64V192h64V384h36a12,12,0,0,1,12,12v20H48V396a12,12,0,0,1,12-12H96V192Z', 'M491.06,120.61l-232-88a8,8,0,0,0-6.12,0l-232,88A8,8,0,0,0,16,128v16a8,8,0,0,0,8,8H48v12a12,12,0,0,0,12,12H452a12,12,0,0,0,12-12V152h24a8,8,0,0,0,8-8V128A8,8,0,0,0,491.06,120.61ZM472,432H40a24,24,0,0,0-24,24v16a8,8,0,0,0,8,8H488a8,8,0,0,0,8-8V456A24,24,0,0,0,472,432Z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUniversity = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faUser.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUser: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faUser.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'user';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f007';\nvar svgPathData = ['M352 128A128 128 0 1 1 224 0a128 128 0 0 1 128 128z', 'M313.6 288h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48v-41.6A134.43 134.43 0 0 0 313.6 288z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUser = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faUserHardHat.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUserHardHat: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faUserHardHat.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'user-hard-hat';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f82c';\nvar svgPathData = ['M97.61 208h252.78c-7.95 63.06-61.17 112-126.39 112S105.56 271.06 97.61 208z', 'M313.6 352h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.4 134.4 0 0 0 0 486.4 25.6 25.6 0 0 0 25.6 512h396.8a25.6 25.6 0 0 0 25.6-25.6A134.4 134.4 0 0 0 313.6 352zM88 176h272a8 8 0 0 0 8-8v-32a8 8 0 0 0-8-8h-8a112 112 0 0 0-68.4-103.2L256 80V16a16 16 0 0 0-16-16h-32a16 16 0 0 0-16 16v64l-27.6-55.2A112 112 0 0 0 96 128h-8a8 8 0 0 0-8 8v32a8 8 0 0 0 8 8z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUserHardHat = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faUserShield.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUserShield: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faUserShield.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'user-shield';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f505';\nvar svgPathData = ['M622.3 271.1l-115.2-45a31 31 0 0 0-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9a31 31 0 0 0 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8z', 'M224 256A128 128 0 1 0 96 128a128 128 0 0 0 128 128zm96 40c0-2.5.8-4.8 1.1-7.2-2.5-.1-4.9-.8-7.5-.8h-16.7a174.08 174.08 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a49.22 49.22 0 0 0 19.2-4c-54-42.9-99.2-116.7-99.2-212z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUserShield = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faUsers.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUsers: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string[];"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/faUsers.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fad';\nvar iconName = 'users';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0c0';\nvar svgPathData = ['M96 224a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64zm480 32h-64a63.81 63.81 0 0 0-45.1 18.6A146.27 146.27 0 0 1 542 384h66a32 32 0 0 0 32-32v-32a64.06 64.06 0 0 0-64-64zm-512 0a64.06 64.06 0 0 0-64 64v32a32 32 0 0 0 32 32h65.9a146.64 146.64 0 0 1 75.2-109.4A63.81 63.81 0 0 0 128 256zm480-32a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64z', 'M396.8 288h-8.3a157.53 157.53 0 0 1-68.5 16c-24.6 0-47.6-6-68.5-16h-8.3A115.23 115.23 0 0 0 128 403.2V432a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48v-28.8A115.23 115.23 0 0 0 396.8 288zM320 256a112 112 0 1 0-112-112 111.94 111.94 0 0 0 112 112z'];\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUsers = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/index.d.ts",
    "content": "export const faAbacus: IconDefinition;\nexport const faAlignSlash: IconDefinition;\nexport const faAtomAlt: IconDefinition;\nexport const faBadgeCheck: IconDefinition;\nexport const faBell: IconDefinition;\nexport const faBooks: IconDefinition;\nexport const faBracketsCurly: IconDefinition;\nexport const faChartNetwork: IconDefinition;\nexport const faChartScatter: IconDefinition;\nexport const faCheck: IconDefinition;\nexport const faCircle: IconDefinition;\nexport const faClouds: IconDefinition;\nexport const faCogs: IconDefinition;\nexport const faCommentDots: IconDefinition;\nexport const faConciergeBell: IconDefinition;\nexport const faDotCircle: IconDefinition;\nexport const faEnvelope: IconDefinition;\nexport const faExchangeAlt: IconDefinition;\nexport const faFileAlt: IconDefinition;\nexport const faFileCode: IconDefinition;\nexport const faGlobe: IconDefinition;\nexport const faGlobeAfrica: IconDefinition;\nexport const faGlobeAmericas: IconDefinition;\nexport const faGlobeAsia: IconDefinition;\nexport const faGlobeEurope: IconDefinition;\nexport const faGraduationCap: IconDefinition;\nexport const faHistory: IconDefinition;\nexport const faKey: IconDefinition;\nexport const faKeySkeleton: IconDefinition;\nexport const faLaptop: IconDefinition;\nexport const faLaptopCode: IconDefinition;\nexport const faLaptopHouse: IconDefinition;\nexport const faLifeRing: IconDefinition;\nexport const faLightbulb: IconDefinition;\nexport const faListAlt: IconDefinition;\nexport const faListUl: IconDefinition;\nexport const faLockAlt: IconDefinition;\nexport const faMapMarkerAlt: IconDefinition;\nexport const faMoonStars: IconDefinition;\nexport const faNetworkWired: IconDefinition;\nexport const faPlanetRinged: IconDefinition;\nexport const faQuestionCircle: IconDefinition;\nexport const faQuoteLeft: IconDefinition;\nexport const faRandom: IconDefinition;\nexport const faRocket: IconDefinition;\nexport const faSearch: IconDefinition;\nexport const faServer: IconDefinition;\nexport const faSignOut: IconDefinition;\nexport const faSirenOn: IconDefinition;\nexport const faSmile: IconDefinition;\nexport const faSnowman: IconDefinition;\nexport const faSun: IconDefinition;\nexport const faTasks: IconDefinition;\nexport const faUniversity: IconDefinition;\nexport const faUser: IconDefinition;\nexport const faUserHardHat: IconDefinition;\nexport const faUserShield: IconDefinition;\nexport const faUsers: IconDefinition;\nimport { IconDefinition, IconLookup, IconName, IconPrefix, IconPack } from '@fortawesome/fontawesome-common-types';\nexport { IconDefinition, IconLookup, IconName, IconPrefix, IconPack } from '@fortawesome/fontawesome-common-types';\nexport const prefix: IconPrefix;\nexport const fad: IconPack;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/index.es.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\nvar prefix = \"fad\";\nvar faAbacus = {\n  prefix: 'fad',\n  iconName: 'abacus',\n  icon: [576, 512, [], \"f640\", [\"M192 440h-32v-48h32zM160 72v48h32V72zm96 160v48h32v-48zm-96 0v48h32v-48zm96 208h160v-48H256zm96-160h128v-48H352zM544 0a32 32 0 0 0-32 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32a32 32 0 0 0-32-32zM416 72H256v48h160zM32 0A32 32 0 0 0 0 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32A32 32 0 0 0 32 0z\", \"M144 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm-96 160h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm192 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm-96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zM464 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM144 352h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm224 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16z\"]]\n};\nvar faAlignSlash = {\n  prefix: 'fad',\n  iconName: 'align-slash',\n  icon: [640, 512, [], \"f846\", [\"M528 352h-31.46l-82.81-64H528a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16zM96 304v32a16 16 0 0 0 16 16h175.21l-82.8-64H112a16 16 0 0 0-16 16zM528 96a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16H112a15.82 15.82 0 0 0-15 11.18L165.31 96zM112 416a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h340.83L370 416zm416-256H248.12l82.81 64H528a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M633.82 458.1L45.46 3.38A16 16 0 0 0 23 6.19L3.37 31.46a16 16 0 0 0 2.81 22.45l588.36 454.72a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45z\"]]\n};\nvar faAtomAlt = {\n  prefix: 'fad',\n  iconName: 'atom-alt',\n  icon: [448, 512, [], \"f5d3\", [\"M424.37305,55.69141C408.294,39.61914,385.50879,32,358.58252,32,319.82764,32,272.43359,48.127,224,77.14453a493.86641,493.86641,0,0,0-58.042,41.03711C140.58252,138.875,114.57666,162.5918,85.75635,197.916a374.25237,374.25237,0,0,0,35.70263,58.082A505.23427,505.23427,0,0,1,224,153.65625a377.23937,377.23937,0,0,1,58.042-35.47266c70.01221-34.334,95.22461-19.07421,97.0625-17.23632,9.54248,9.543,7.67432,46.94531-16.86084,96.96875A492.27615,492.27615,0,0,1,403.06543,256C452.27637,173.91992,463.59277,94.90039,424.37305,55.69141ZM224,358.3418a377.44678,377.44678,0,0,1-58.042,35.47461c-70.01221,34.334-95.22461,19.07421-97.0625,17.23632-9.54248-9.543-7.67432-46.94335,16.86084-96.96875A492.27615,492.27615,0,0,1,44.93457,256C-4.27637,338.08008-15.59277,417.09961,23.627,456.30664,39.70605,472.38086,62.49121,480,89.41748,480c38.75488,0,86.14893-16.127,134.58252-45.14453a493.86641,493.86641,0,0,0,58.042-41.03711c25.38965-20.70508,51.42285-44.45606,80.20166-79.73438A373.962,373.962,0,0,0,326.541,256,505.23427,505.23427,0,0,1,224,358.3418Z\", \"M224,287.98828a31.99414,31.99414,0,1,0-32-31.99414A31.98908,31.98908,0,0,0,224,287.98828ZM121.46094,255.99805A374.13921,374.13921,0,0,1,85.7583,197.916c-24.53906-50.02344-26.40625-87.42579-16.86328-96.9668,1.83984-1.83789,27.05078-17.10156,97.062,17.23242A494.241,494.241,0,0,1,224,77.14453C175.5625,48.13086,128.16406,32,89.41846,32c-26.9336,0-49.707,7.61523-65.793,23.69141C-15.59326,94.90039-4.27686,173.91992,44.93408,256A492.0174,492.0174,0,0,0,85.7583,314.084c28.79639,35.30274,54.85889,59.07227,80.19873,79.73243A377.429,377.429,0,0,0,224,358.3418,505.131,505.131,0,0,1,121.46094,255.99805ZM403.06592,256a492.0174,492.0174,0,0,0-40.82422-58.084c-28.84326-35.35547-54.89795-59.10352-80.19873-79.73243A377.4073,377.4073,0,0,0,224,153.65625,505.20556,505.20556,0,0,1,326.53906,256a373.849,373.849,0,0,1,35.70264,58.084c24.53906,50.02149,26.40625,87.42383,16.86328,96.9668-1.83984,1.83789-27.05078,17.10156-97.062-17.23242A494.241,494.241,0,0,1,224,434.85547C272.4375,463.86914,319.83594,480,358.58154,480c26.9336,0,49.707-7.61523,65.793-23.69336C463.59326,417.09961,452.27686,338.08008,403.06592,256Z\"]]\n};\nvar faBadgeCheck = {\n  prefix: 'fad',\n  iconName: 'badge-check',\n  icon: [512, 512, [], \"f336\", [\"M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z\", \"M367.2 211.75l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.06 15.56z\"]]\n};\nvar faBell = {\n  prefix: 'fad',\n  iconName: 'bell',\n  icon: [448, 512, [], \"f0f3\", [\"M448 384c-.1 16.4-13 32-32.1 32H32.08C13 416 .09 400.4 0 384a31.25 31.25 0 0 1 8.61-21.71c19.32-20.76 55.47-52 55.47-154.29 0-77.7 54.48-139.9 127.94-155.16V32a32 32 0 1 1 64 0v20.84C329.42 68.1 383.9 130.3 383.9 208c0 102.3 36.15 133.53 55.47 154.29A31.27 31.27 0 0 1 448 384z\", \"M160 448h128a64 64 0 0 1-128 0z\"]]\n};\nvar faBooks = {\n  prefix: 'fad',\n  iconName: 'books',\n  icon: [576, 512, [], \"f5db\", [\"M96 0H32A32 32 0 0 0 0 32v64h128V32A32 32 0 0 0 96 0zM0 384h128V128H0zm0 96a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H0zm513.62-17.78L401.08 42.71l-60.26 16.14 112.35 418.8c.11.39.2.79.29 1.18l60.29-16.15c-.04-.15-.09-.3-.13-.46zM160 480a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H160zM256 0h-64a32 32 0 0 0-32 32v64h124.79l-8-29.65a23.94 23.94 0 0 1 11.17-27V32A32 32 0 0 0 256 0zm-96 384h128V128H160z\", \"M0 416h128v-32H0zm0-288h128V96H0zm575.17 317.65L460.39 17.78a23.89 23.89 0 0 0-29.18-17h-.09L415.73 5a24 24 0 0 0-16.9 29.36l114.79 427.86a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.35zM160 416h128v-32H160zM338.39 49.78a23.89 23.89 0 0 0-29.18-17h-.09L293.73 37a24 24 0 0 0-16.9 29.36l8 29.65H160v32h128V108l103.62 386.22a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.33z\"]]\n};\nvar faBracketsCurly = {\n  prefix: 'fad',\n  iconName: 'brackets-curly',\n  icon: [576, 512, [], \"f7ea\", [\"M566.64 233.37a32 32 0 0 1 0 45.25l-45.25 45.25a32 32 0 0 0-9.39 22.64V384a96 96 0 0 1-96 96h-48a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h48a32 32 0 0 0 32-32v-37.48a96 96 0 0 1 28.13-67.89L498.76 256l-22.62-22.62A96 96 0 0 1 448 165.47V128a32 32 0 0 0-32-32h-48a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h48a96 96 0 0 1 96 96v37.48a32 32 0 0 0 9.38 22.65l45.25 45.24z\", \"M208 32h-48a96 96 0 0 0-96 96v37.48a32.12 32.12 0 0 1-9.38 22.65L9.38 233.37a32 32 0 0 0 0 45.25l45.25 45.25A32.05 32.05 0 0 1 64 346.51V384a96 96 0 0 0 96 96h48a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-48a32 32 0 0 1-32-32v-37.48a96 96 0 0 0-28.13-67.89L77.26 256l22.63-22.63A96 96 0 0 0 128 165.48V128a32 32 0 0 1 32-32h48a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]]\n};\nvar faChartNetwork = {\n  prefix: 'fad',\n  iconName: 'chart-network',\n  icon: [640, 512, [], \"f78a\", [\"M64 240a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64zm88 80h48v-32h-48zm294.4-106.8l19.2 25.6 48-36-19.2-25.6zM576 64a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64z\", \"M576 384a63.84 63.84 0 0 0-38.3 13l-96-57.6a109.91 109.91 0 0 0 6.3-35.5 111.94 111.94 0 0 0-112-112 108.64 108.64 0 0 0-24.4 2.9l-40.8-87.4A63.84 63.84 0 1 0 224 128c1.1 0 2.1-.3 3.2-.3l41 87.8C241.5 235.9 224 267.8 224 304a111.71 111.71 0 0 0 193.2 76.7l95.8 57.5a63.87 63.87 0 1 0 63-54.2zm-240-32a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]]\n};\nvar faChartScatter = {\n  prefix: 'fad',\n  iconName: 'chart-scatter',\n  icon: [512, 512, [], \"f7ee\", [\"M512 400v32a16 16 0 0 1-16 16H32a32 32 0 0 1-32-32V80a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16v304h432a16 16 0 0 1 16 16z\", \"M160 256a32 32 0 1 0 32 32 32 32 0 0 0-32-32zM416 96a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-224 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm192 160a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-96-64a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]]\n};\nvar faCheck = {\n  prefix: 'fad',\n  iconName: 'check',\n  icon: [512, 512, [], \"f00c\", [\"M504.5 144.42L264.75 385.5 192 312.59l240.11-241a25.49 25.49 0 0 1 36.06-.14l.14.14L504.5 108a25.86 25.86 0 0 1 0 36.42z\", \"M264.67 385.59l-54.57 54.87a25.5 25.5 0 0 1-36.06.14l-.14-.14L7.5 273.1a25.84 25.84 0 0 1 0-36.41l36.2-36.41a25.49 25.49 0 0 1 36-.17l.16.17z\"]]\n};\nvar faCircle = {\n  prefix: 'fad',\n  iconName: 'circle',\n  icon: [512, 512, [], \"f111\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 424c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\", \"M256 432c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\"]]\n};\nvar faClouds = {\n  prefix: 'fad',\n  iconName: 'clouds',\n  icon: [640, 512, [], \"f744\", [\"M161.6 288H96a96 96 0 0 1 0-192c.6 0 1.1.2 1.6.2C105.3 41.9 151.6 0 208 0a111.61 111.61 0 0 1 104.5 72.7A95.07 95.07 0 0 1 352 64a96 96 0 0 1 96 96 93 93 0 0 1-7 34.7 110.5 110.5 0 0 0-31.6 11.8A142.54 142.54 0 0 0 304 160c-73.9 0-134.3 56.2-142.4 128z\", \"M640 416a96 96 0 0 1-96 96H224a96 96 0 0 1-96-96c0-42.5 27.8-78.2 66.1-90.8A113.72 113.72 0 0 1 192 304a111.94 111.94 0 0 1 112-112c43.2 0 80.4 24.9 99 60.8 14.7-17.5 36.4-28.8 61-28.8a80 80 0 0 1 80 80 78.09 78.09 0 0 1-1.6 16.2c.5 0 1-.2 1.6-.2a96 96 0 0 1 96 96z\"]]\n};\nvar faCogs = {\n  prefix: 'fad',\n  iconName: 'cogs',\n  icon: [640, 512, [], \"f085\", [\"M638.41 387a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4L602 335a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6 12.36 12.36 0 0 0-15.1 5.4l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 44.9c-29.6-38.5 14.3-82.4 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79zm136.8-343.8a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4l8.2-14.3a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6A12.36 12.36 0 0 0 552 7.19l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 45c-29.6-38.5 14.3-82.5 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79z\", \"M420 303.79L386.31 287a173.78 173.78 0 0 0 0-63.5l33.7-16.8c10.1-5.9 14-18.2 10-29.1-8.9-24.2-25.9-46.4-42.1-65.8a23.93 23.93 0 0 0-30.3-5.3l-29.1 16.8a173.66 173.66 0 0 0-54.9-31.7V58a24 24 0 0 0-20-23.6 228.06 228.06 0 0 0-76 .1A23.82 23.82 0 0 0 158 58v33.7a171.78 171.78 0 0 0-54.9 31.7L74 106.59a23.91 23.91 0 0 0-30.3 5.3c-16.2 19.4-33.3 41.6-42.2 65.8a23.84 23.84 0 0 0 10.5 29l33.3 16.9a173.24 173.24 0 0 0 0 63.4L12 303.79a24.13 24.13 0 0 0-10.5 29.1c8.9 24.1 26 46.3 42.2 65.7a23.93 23.93 0 0 0 30.3 5.3l29.1-16.7a173.66 173.66 0 0 0 54.9 31.7v33.6a24 24 0 0 0 20 23.6 224.88 224.88 0 0 0 75.9 0 23.93 23.93 0 0 0 19.7-23.6v-33.6a171.78 171.78 0 0 0 54.9-31.7l29.1 16.8a23.91 23.91 0 0 0 30.3-5.3c16.2-19.4 33.7-41.6 42.6-65.8a24 24 0 0 0-10.5-29.1zm-151.3 4.3c-77 59.2-164.9-28.7-105.7-105.7 77-59.2 164.91 28.7 105.71 105.7z\"]]\n};\nvar faCommentDots = {\n  prefix: 'fad',\n  iconName: 'comment-dots',\n  icon: [512, 512, [], \"f4ad\", [\"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5a8 8 0 0 0-1.5 8.7A7.83 7.83 0 0 0 8 480c66.3 0 116-31.8 140.6-51.4A305 305 0 0 0 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32z\", \"M128 208a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]]\n};\nvar faConciergeBell = {\n  prefix: 'fad',\n  iconName: 'concierge-bell',\n  icon: [512, 512, [], \"f562\", [\"M512 400v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h480a16 16 0 0 1 16 16zM208 112h16v18.29a224.73 224.73 0 0 1 64 0V112h16a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16z\", \"M480 352H32c0-123.71 100.29-224 224-224s224 100.29 224 224z\"]]\n};\nvar faDotCircle = {\n  prefix: 'fad',\n  iconName: 'dot-circle',\n  icon: [512, 512, [], \"f192\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm124.45 372.45A176 176 0 1 1 432 256a174.85 174.85 0 0 1-51.55 124.45z\", \"M256 336a80 80 0 1 1 80-80 80.09 80.09 0 0 1-80 80z\"]]\n};\nvar faEnvelope = {\n  prefix: 'fad',\n  iconName: 'envelope',\n  icon: [512, 512, [], \"f0e0\", [\"M256.47 352h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V400a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V183.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52zM464 64H48a48 48 0 0 0-48 48v19a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4 23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131v-19a48 48 0 0 0-48-48z\", \"M512 131v52.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V131a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.69 12.12 49.75 41.4 72.93 41.4h.94c23.18 0 56.24-29.28 72.93-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131z\"]]\n};\nvar faExchangeAlt = {\n  prefix: 'fad',\n  iconName: 'exchange-alt',\n  icon: [512, 512, [], \"f362\", [\"M128 272v48h360a24 24 0 0 1 24 24v16a24 24 0 0 1-24 24H128v48c0 21.44-25.94 32-41 17L7 369a24 24 0 0 1 0-33.94l80-80c15.14-15.12 41-4.35 41 16.94z\", \"M505 143.05a24 24 0 0 1 0 33.95l-80 80c-15 15-41 4.49-41-17v-48H24a24 24 0 0 1-24-24v-16a24 24 0 0 1 24-24h360V80c0-21.36 25.9-32 41-17z\"]]\n};\nvar faFileAlt = {\n  prefix: 'fad',\n  iconName: 'file-alt',\n  icon: [384, 512, [], \"f15c\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zm-96 244a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM276 352H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12z\"]]\n};\nvar faFileCode = {\n  prefix: 'fad',\n  iconName: 'file-code',\n  icon: [384, 512, [], \"f1c9\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zM141.79 379.54l-19.58 20.84a5.41 5.41 0 0 1-7.64.24l-64.86-60.69a5.37 5.37 0 0 1-.24-7.6l.25-.25 64.86-60.7a5.42 5.42 0 0 1 7.64.24l19.58 20.85a5.4 5.4 0 0 1-.25 7.62l-.13.12L100.65 336l40.76 35.8a5.4 5.4 0 0 1 .49 7.62zm31.71 71.25l-27.45-8a5.38 5.38 0 0 1-3.67-6.67l61.49-211.24a5.38 5.38 0 0 1 6.68-3.64l27.45 8a5.4 5.4 0 0 1 3.63 6.67l-61.45 211.2a5.4 5.4 0 0 1-6.68 3.68zm161-111.12l-.25.25-64.86 60.69a5.42 5.42 0 0 1-7.64-.23l-19.58-20.84a5.37 5.37 0 0 1 .26-7.6l.13-.12L283.35 336l-40.76-35.8a5.4 5.4 0 0 1-.49-7.62l.11-.12 19.58-20.85a5.42 5.42 0 0 1 7.64-.24l64.86 60.7a5.36 5.36 0 0 1 .25 7.6z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM141.41 371.8L100.65 336l40.76-35.8.13-.12a5.4 5.4 0 0 0 .25-7.62l-19.58-20.85a5.42 5.42 0 0 0-7.64-.24l-64.86 60.7-.25.25a5.37 5.37 0 0 0 .24 7.6l64.86 60.69a5.41 5.41 0 0 0 7.64-.24l19.58-20.84.11-.12a5.4 5.4 0 0 0-.48-7.61zm100.22-135.93a5.4 5.4 0 0 0-3.63-6.67l-27.45-8a5.38 5.38 0 0 0-6.68 3.64l-61.5 211.29a5.38 5.38 0 0 0 3.63 6.67l27.45 8a5.4 5.4 0 0 0 6.68-3.68l61.44-211.22zm92.66 96.2l-64.86-60.7a5.42 5.42 0 0 0-7.64.24l-19.58 20.85-.11.12a5.4 5.4 0 0 0 .49 7.62l40.76 35.8-40.76 35.8-.13.12a5.37 5.37 0 0 0-.26 7.6l19.58 20.84a5.42 5.42 0 0 0 7.64.23l64.86-60.69.25-.25a5.36 5.36 0 0 0-.25-7.6z\"]]\n};\nvar faGlobe = {\n  prefix: 'fad',\n  iconName: 'globe',\n  icon: [496, 512, [], \"f0ac\", [\"M340.45,320H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256,575,575,0,0,1,340.45,320ZM160.2,160H335.8c-.41-2.31-.84-4.62-1.28-6.91-6-30.85-14.42-58.37-25.13-81.78C299.54,49.77,288,32.54,276.05,21.48,266.38,12.53,256.94,8,248,8s-18.38,4.53-28,13.48c-12,11.06-23.49,28.29-33.34,49.83C176,94.72,167.5,122.24,161.53,153.09,161,155.38,160.61,157.69,160.2,160ZM120,256a608,608,0,0,1,3.34-64H8.35a249.52,249.52,0,0,0,0,128h115A608,608,0,0,1,120,256Zm367.62-64h-115A608.06,608.06,0,0,1,376,256a608,608,0,0,1-3.34,64h115a249.52,249.52,0,0,0,0-128ZM476.7,160A248.62,248.62,0,0,0,315.58,17.32c24.13,33,42.89,83.15,52.75,142.68ZM315.58,494.68A248.59,248.59,0,0,0,476.71,352H368.33C358.47,411.53,339.71,461.68,315.58,494.68ZM335.8,352H160.2c.41,2.31.84,4.62,1.28,6.91,6,30.85,14.42,58.37,25.13,81.78,9.85,21.54,21.38,38.77,33.34,49.83,9.67,9,19.11,13.48,28.05,13.48s18.38-4.53,28.05-13.48c12-11.06,23.49-28.29,33.34-49.83,10.71-23.41,19.16-50.93,25.13-81.78C335,356.62,335.39,354.31,335.8,352ZM180.42,17.32A248.59,248.59,0,0,0,19.29,160H127.67C137.53,100.47,156.29,50.32,180.42,17.32ZM19.29,352A248.59,248.59,0,0,0,180.42,494.68c-24.13-33-42.89-83.15-52.75-142.68Z\", \"M376,256a608,608,0,0,0-3.34-64h115a245.72,245.72,0,0,0-10.92-32H368.33c-9.86-59.53-28.62-109.68-52.75-142.68A248.23,248.23,0,0,0,248,8c8.94,0,18.38,4.53,28.05,13.48,12,11.06,23.49,28.29,33.34,49.83,10.71,23.41,19.16,50.93,25.13,81.78.44,2.29.87,4.6,1.28,6.91H160.2c.41-2.31.84-4.62,1.28-6.91,6-30.85,14.42-58.37,25.13-81.78C196.46,49.77,208,32.54,220,21.48,229.62,12.53,239.06,8,248,8a248.23,248.23,0,0,0-67.58,9.32c-24.13,33-42.89,83.15-52.75,142.68H19.29A245.72,245.72,0,0,0,8.37,192h115a613.93,613.93,0,0,0,0,128H8.37a245.72,245.72,0,0,0,10.92,32H127.67c9.86,59.53,28.62,109.68,52.75,142.68A248.23,248.23,0,0,0,248,504c-8.94,0-18.38-4.53-28.05-13.48-12-11.06-23.49-28.29-33.34-49.83-10.71-23.41-19.16-50.93-25.13-81.78-.44-2.29-.87-4.6-1.28-6.91H335.8c-.41,2.31-.84,4.62-1.28,6.91-6,30.85-14.42,58.37-25.13,81.78-9.85,21.54-21.38,38.77-33.34,49.83-9.67,9-19.11,13.48-28.05,13.48a248.23,248.23,0,0,0,67.58-9.32c24.13-33,42.89-83.15,52.75-142.68H476.71a245.72,245.72,0,0,0,10.92-32h-115A605.37,605.37,0,0,0,376,256Zm-35.54,64H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256a575,575,0,0,1-3.55,64Z\"]]\n};\nvar faGlobeAfrica = {\n  prefix: 'fad',\n  iconName: 'globe-africa',\n  icon: [496, 512, [], \"f57c\", [\"M491.33,208H423.5A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05A249.89,249.89,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256A249.51,249.51,0,0,0,491.33,208Z\", \"M423.5,208A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05C386,23.7,471,104.24,491.34,208Z\"]]\n};\nvar faGlobeAmericas = {\n  prefix: 'fad',\n  iconName: 'globe-americas',\n  icon: [496, 512, [], \"f57d\", [\"M489.55,312.41C464,422.22,365.59,504,248,504,111,504,0,393,0,256A247,247,0,0,1,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311l-13.71-13.67A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A247,247,0,0,1,248,8C351.83,8,440.71,71.76,477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1Z\", \"M321.39,297.36A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A249,249,0,0,0,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311ZM477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1,55.64,29.22a249.21,249.21,0,0,0-11.88-150.14Z\"]]\n};\nvar faGlobeAsia = {\n  prefix: 'fad',\n  iconName: 'globe-asia',\n  icon: [496, 512, [], \"f57e\", [\"M312,16.35V50.73a28,28,0,0,1-11.12,22.35l-41.41,31.27a8,8,0,0,0,.86,13.81l10.83,5.41A16,16,0,0,1,280,137.88V216a8,8,0,0,1-8,8h-3.06a8,8,0,0,1-7.15-4.42,4.47,4.47,0,0,0-1.72-1.86,4.42,4.42,0,0,0-6.06,1.54h0l-17.34,29A16,16,0,0,1,222.94,256h-.31a16,16,0,0,0-11.32,4.69l-5.66,5.66a8,8,0,0,0,0,11.31l5.66,5.66A16,16,0,0,1,216,294.63V304a16,16,0,0,1-16,16h-6.1a16,16,0,0,1-14.28-8.85L157,265.92a8,8,0,0,0-10.72-3.6h0a8.14,8.14,0,0,0-2.11,1.53l-19.47,19.46A16,16,0,0,1,113.38,288H2.05C17.74,409.88,121.84,504,248,504c137,0,248-111,248-248C496,141.13,418,44.56,312,16.35Zm96,342.08a16,16,0,0,1-4.69,11.31l-9.57,9.57A16,16,0,0,1,382.43,384H367.27a16,16,0,0,1-11.36-4.74l-13-13a26.78,26.78,0,0,0-25.42-7l-21.27,5.32a15.86,15.86,0,0,1-3.88.48H282a16,16,0,0,1-11.24-4.69l-11.91-11.91a8,8,0,0,1-2.34-5.66V332.6a8,8,0,0,1,5-7.43l39.34-15.74a26.35,26.35,0,0,0,5.59-3.05l23.71-16.89a8,8,0,0,1,4.64-1.48h12.14a8,8,0,0,1,7.39,4.93l5.35,12.85a4,4,0,0,0,3.69,2.46h3.8a4,4,0,0,0,3.84-2.88l4.16-14.49A4,4,0,0,1,379,288h6.06a4,4,0,0,1,4,4v13a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,1,408,333.83Z\", \"M260.07,217.72a4.47,4.47,0,0,1,1.72,1.86,8,8,0,0,0,7.15,4.42H272a8,8,0,0,0,8-8V137.88a16,16,0,0,0-8.84-14.31l-10.83-5.41a8,8,0,0,1-.86-13.81l41.41-31.27A28,28,0,0,0,312,50.73V16.35A248.23,248.23,0,0,0,248,8C111,8,0,119,0,256a249.89,249.89,0,0,0,2.05,32H113.38a16,16,0,0,0,11.31-4.69l19.47-19.46A8,8,0,0,1,157,265.92l22.62,45.23A16,16,0,0,0,193.9,320H200a16,16,0,0,0,16-16v-9.37a16,16,0,0,0-4.69-11.31l-5.66-5.66a8,8,0,0,1,0-11.31l5.66-5.66A16,16,0,0,1,222.63,256h.31a16,16,0,0,0,13.72-7.77L254,219.28a4.42,4.42,0,0,1,6.05-1.57Zm143.24,104.8L391.4,310.61a8,8,0,0,1-2.34-5.66V292a4,4,0,0,0-4-4H379a4,4,0,0,0-3.84,2.88L371,305.37a4,4,0,0,1-3.84,2.88h-3.8a4,4,0,0,1-3.69-2.46l-5.35-12.85a8,8,0,0,0-7.39-4.93H334.79a8,8,0,0,0-4.64,1.48l-23.71,16.89a26.35,26.35,0,0,1-5.59,3.05l-39.34,15.74a8,8,0,0,0-5,7.43v10.2a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,0,282,365.06h10.34a15.86,15.86,0,0,0,3.88-.48l21.27-5.32a26.78,26.78,0,0,1,25.42,7l13,13A16,16,0,0,0,367.27,384h15.16a16,16,0,0,0,11.31-4.69l9.57-9.57A16,16,0,0,0,408,358.43v-24.6a16,16,0,0,0-4.69-11.31Z\"]]\n};\nvar faGlobeEurope = {\n  prefix: 'fad',\n  iconName: 'globe-europe',\n  icon: [496, 512, [], \"f7a2\", [\"M487.54,320.4H438.9a15.8,15.8,0,0,1-11.4-4.8l-32-32.6a11.92,11.92,0,0,1,.1-16.7l12.5-12.5v-8.7a11.37,11.37,0,0,0-3.3-8l-9.4-9.4a11.37,11.37,0,0,0-8-3.3h-16a11.31,11.31,0,0,1-8-19.3l9.4-9.4a11.37,11.37,0,0,1,8-3.3h32a11.35,11.35,0,0,0,11.3-11.3v-9.4a11.35,11.35,0,0,0-11.3-11.3H376.1a16,16,0,0,0-16,16v4.5a16,16,0,0,1-10.9,15.2l-31.6,10.5a8,8,0,0,0-5.5,7.6v2.2a8,8,0,0,1-8,8h-16a8,8,0,0,1-8-8,8,8,0,0,0-8-8H269a8.14,8.14,0,0,0-7.2,4.4l-9.4,18.7a15.94,15.94,0,0,1-14.3,8.8H216a16,16,0,0,1-16-16V199a16,16,0,0,1,4.7-11.3l20.1-20.1a24.77,24.77,0,0,0,7.2-17.5,8,8,0,0,1,5.5-7.6l40-13.3a11.66,11.66,0,0,0,4.4-2.7l26.8-26.8a11.31,11.31,0,0,0-8-19.3H280l-16,16v8a8,8,0,0,1-8,8H240a8,8,0,0,1-8-8v-20a8.05,8.05,0,0,1,3.2-6.4l82.42-60.08A247.79,247.79,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504a251.57,251.57,0,0,0,32.1-2.06V448.4a16,16,0,0,0-16-16H243.9c-10.8,0-26.7-5.3-35.4-11.8l-22.2-16.7a45.42,45.42,0,0,1-18.2-36.4V343.6a45.46,45.46,0,0,1,22.1-39l42.9-25.7a46.13,46.13,0,0,1,23.4-6.5h31.2a45.62,45.62,0,0,1,29.6,10.9l43.2,37.1h18.3a32,32,0,0,1,22.6,9.4l17.3,17.3.08.08C432,359.06,440,375.62,440,393.37V413A247.11,247.11,0,0,0,487.54,320.4ZM187.4,157.1a11.37,11.37,0,0,1-8,3.3h-16a11.31,11.31,0,0,1-8-19.3l25.4-25.4a11.31,11.31,0,0,1,19.3,8v16a11.37,11.37,0,0,1-3.3,8Z\", \"M187.4,157.1l9.4-9.4a11.37,11.37,0,0,0,3.3-8v-16a11.31,11.31,0,0,0-19.3-8l-25.4,25.4a11.31,11.31,0,0,0,8,19.3h16A11.37,11.37,0,0,0,187.4,157.1ZM418.78,347.18l-.08-.08-17.3-17.3a32,32,0,0,0-22.6-9.4H360.5l-43.2-37.1a45.62,45.62,0,0,0-29.6-10.9H256.5a46.13,46.13,0,0,0-23.4,6.5l-42.9,25.7a45.46,45.46,0,0,0-22.1,39v23.9a45.42,45.42,0,0,0,18.2,36.4l22.2,16.7c8.7,6.5,24.6,11.8,35.4,11.8h20.2a16,16,0,0,1,16,16v53.54A247.57,247.57,0,0,0,440,413V393.37C440,375.62,432,359.06,418.78,347.18ZM317.62,17.92,235.2,78a8.05,8.05,0,0,0-3.2,6.4v20a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-8l16-16h20.7a11.31,11.31,0,0,1,8,19.3l-26.8,26.8a11.66,11.66,0,0,1-4.4,2.7l-40,13.3a8,8,0,0,0-5.5,7.6,24.77,24.77,0,0,1-7.2,17.5l-20.1,20.1A16,16,0,0,0,200,199v25.3a16,16,0,0,0,16,16h22.1a15.94,15.94,0,0,0,14.3-8.8l9.4-18.7a8.14,8.14,0,0,1,7.2-4.4h3.1a8,8,0,0,1,8,8,8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-2.2a8,8,0,0,1,5.5-7.6l31.6-10.5a16,16,0,0,0,10.9-15.2v-4.5a16,16,0,0,1,16-16h36.7a11.35,11.35,0,0,1,11.3,11.3v9.4a11.35,11.35,0,0,1-11.3,11.3h-32a11.37,11.37,0,0,0-8,3.3l-9.4,9.4a11.31,11.31,0,0,0,8,19.3h16a11.37,11.37,0,0,1,8,3.3l9.4,9.4a11.37,11.37,0,0,1,3.3,8v8.7l-12.5,12.5a11.92,11.92,0,0,0-.1,16.7l32,32.6a15.8,15.8,0,0,0,11.4,4.8h48.64A248.29,248.29,0,0,0,496,256C496,143.18,420.71,48,317.62,17.92Z\"]]\n};\nvar faGraduationCap = {\n  prefix: 'fad',\n  iconName: 'graduation-cap',\n  icon: [640, 512, [], \"f19d\", [\"M323.07 175.7L118.8 215.6a48.1 48.1 0 0 0-38.74 44.73 32 32 0 0 1 2.21 53.94l25.4 114.26A16 16 0 0 1 92 448H35.94a16 16 0 0 1-15.61-19.47l25.39-114.27a32 32 0 0 1 2.33-54 80.16 80.16 0 0 1 64.62-76.07l204.26-39.89a16 16 0 1 1 6.14 31.4z\", \"M622.33 198.8l-279 85.7a80 80 0 0 1-46.79 0L99.67 224a47.84 47.84 0 0 1 19.13-8.39l204.27-39.9a16 16 0 1 0-6.14-31.4l-204.26 39.88a79.87 79.87 0 0 0-47.57 29.18l-47.44-14.58c-23.54-7.23-23.54-38.36 0-45.59L296.6 67.5a79.92 79.92 0 0 1 46.8 0l278.93 85.7c23.55 7.24 23.55 38.36 0 45.6zM352.79 315.09a111.94 111.94 0 0 1-65.59 0l-145-44.55L128 384c0 35.35 86 64 192 64s192-28.65 192-64l-14.19-113.47z\"]]\n};\nvar faHistory = {\n  prefix: 'fad',\n  iconName: 'history',\n  icon: [512, 512, [], \"f1da\", [\"M141.68 400.23a184 184 0 1 0-11.75-278.3l50.76 50.76c10.08 10.08 2.94 27.31-11.32 27.31H24a16 16 0 0 1-16-16V38.63c0-14.26 17.23-21.4 27.31-11.32l49.38 49.38A247.14 247.14 0 0 1 256 8c136.81 0 247.75 110.78 248 247.53S392.82 503.9 256.18 504a247 247 0 0 1-155.82-54.91 24 24 0 0 1-1.84-35.61l11.27-11.27a24 24 0 0 1 31.89-1.98z\", \"M288 152v104.35L328.7 288a24 24 0 0 1 4.21 33.68l-9.82 12.62a24 24 0 0 1-33.68 4.21L224 287.65V152a24 24 0 0 1 24-24h16a24 24 0 0 1 24 24z\"]]\n};\nvar faKey = {\n  prefix: 'fad',\n  iconName: 'key',\n  icon: [512, 512, [], \"f084\", [\"M303.06 348.91l.1.09-24 27a24 24 0 0 1-17.94 8H224v40a24 24 0 0 1-24 24h-40v40a24 24 0 0 1-24 24H24a24 24 0 0 1-24-24v-78a24 24 0 0 1 7-17l161.83-161.83-.11-.35a176.24 176.24 0 0 0 134.34 118.09z\", \"M336 0a176 176 0 1 0 176 176A176 176 0 0 0 336 0zm48 176a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]]\n};\nvar faKeySkeleton = {\n  prefix: 'fad',\n  iconName: 'key-skeleton',\n  icon: [512, 512, [], \"f6f3\", [\"M251.31 372.91a16 16 0 0 1 0 22.63l-15.77 15.77a16 16 0 0 1-22.62 0L176 374.4l-30.87 30.86 36.11 36.11a16 16 0 0 1 0 22.63l-43.16 43.17a16 16 0 0 1-22.62 0l-36.12-36.11-36.26 36.25a16 16 0 0 1-22.62 0L4.69 491.54a16 16 0 0 1 0-22.63l255.12-255.12a64.18 64.18 0 0 0 38.4 38.4L214.4 336l36.91 36.91z\", \"M448 0H320a64 64 0 0 0-64 64v128a64 64 0 0 0 64 64h128a64 64 0 0 0 64-64V64a64 64 0 0 0-64-64zm-73.37 182.63a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25zm64-64a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25z\"]]\n};\nvar faLaptop = {\n  prefix: 'fad',\n  iconName: 'laptop',\n  icon: [640, 512, [], \"f109\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M512 64H128v256h384zm112 352H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16z\"]]\n};\nvar faLaptopCode = {\n  prefix: 'fad',\n  iconName: 'laptop-code',\n  icon: [640, 512, [], \"f5fc\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16zM512 64H128v256h384zM289 250.34l-11.31 11.31a16 16 0 0 1-22.63 0l-58.35-58.34a16 16 0 0 1 0-22.63L255 122.34a16 16 0 0 1 22.63 0L289 133.65a16 16 0 0 1 0 22.63L253.25 192 289 227.71a16 16 0 0 1 0 22.63zm154.35-47L385 261.66a16 16 0 0 1-22.63 0L351 250.35a16 16 0 0 1 0-22.63L386.75 192 351 156.29a16 16 0 0 1 0-22.63l11.31-11.31a16 16 0 0 1 22.63 0l58.34 58.34a16 16 0 0 1 .04 22.63z\"]]\n};\nvar faLaptopHouse = {\n  prefix: 'fad',\n  iconName: 'laptop-house',\n  icon: [640, 512, [], \"e066\", [\"M272,416H96a32,32,0,0,1-32-32V219.88L42.34,239A16.51,16.51,0,0,1,33,242.48a16.22,16.22,0,0,1-10.63-4.78L3.55,216.42A16.4,16.4,0,0,1,0,207a16.15,16.15,0,0,1,4.78-10.61L216.58,8.92C222.12,4,232.64,0,240.05,0S258,4,263.5,8.92L352,87.3V48a16,16,0,0,1,16-16h32a16,16,0,0,1,16,16v96l59.24,52.42A16.31,16.31,0,0,1,480,207a16.51,16.51,0,0,1-3.58,9.44L469.74,224H332.8c-17.8,0-33.69,8.24-44.82,21.12V208a16,16,0,0,0-16-16H208a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16h64Z\", \"M629.33,448H592V288c0-17.67-12.89-32-28.8-32H332.8c-15.91,0-28.8,14.33-28.8,32V448H266.67A10.67,10.67,0,0,0,256,458.67v10.66A42.82,42.82,0,0,0,298.6,512H597.4A42.82,42.82,0,0,0,640,469.33V458.67A10.67,10.67,0,0,0,629.33,448ZM544,448H352V304H544Z\"]]\n};\nvar faLifeRing = {\n  prefix: 'fad',\n  iconName: 'life-ring',\n  icon: [512, 512, [], \"f1cd\", [\"M292.08 167l-.41-.17zm-66.62-2a96.5 96.5 0 0 1 61.08 0l112-112a248 248 0 0 0-285 0zm68.67 2.92l.52.22zm2.49 1.12l.46.21zM186.25 322l-.19-.21zm-5.51-6.36l.21.26zm1.65 2c.12.14.23.28.35.41-.12-.15-.23-.29-.35-.43zm1.74 2l.36.4zm135.51-135.51l.4.36zM177.51 311.29l-.1-.15zM304.18 173l.34.19zm11.42 7.78l.26.21zm6.36 5.51l-.21-.19zm-3.96-3.55l-.42-.35zm-11.6-8.43l.47.29zm4.68 3.09l.17.12zm-2-1.35l-.43-.29zm-9.71-5.68l-.1-.05zm-123.61 32.91c.1-.14.19-.28.28-.42-.04.14-.18.28-.28.42zm-1.45 2.28l.29-.46zm-1.31 2.25l.19-.32zm-2.6 4.77zm10.38-16.18l.21-.26zm2-2.43c-.12.13-.23.27-.35.41.08-.14.19-.28.31-.38zm-5.33 6.89l.1-.15zm-8.2 14.07c-.07.14-.13.29-.2.43.03-.14.09-.29.16-.43zm5.39 92l-.29-.46zm-4.27-7.53v.05zm2.82 5.14l-.19-.32zm2.61 4.21c.1.14.19.28.28.42-.08-.17-.22-.31-.32-.45zm-6.8-12.11c.07.14.13.29.2.43-.06-.14-.12-.29-.2-.43zm-2-76.7c0 .13-.1.25-.16.38.07-.13.16-.25.16-.38zm1.09-2.58c-.07.17-.15.34-.22.5.13-.16.13-.33.23-.5zm-.22 76.78c.07.16.15.33.22.5-.09-.17-.09-.34-.21-.5zm-1-2.46c.06.13.11.25.16.38-.03-.13-.12-.25-.18-.38zm172-84.19l.19.32zM327.51 320l.36-.4zm-1.57 1.71l-.19.21zM325.75 190l.19.21zm3.51 128c.12-.13.23-.27.35-.41-.12.17-.23.31-.35.41zm2-121.63l-.21-.26zm0 119.2l-.21.26zm-1.65-121.22c-.12-.14-.23-.28-.35-.41.12.16.23.3.35.44zm-1.74-2l-.36-.4zm6.62 8.35l.1.15zm.1 110.43l-.1.15zM398.49 53q2 1.41 4 2.85-2-1.43-4-2.85zM343.9 294.64c.07-.17.15-.34.22-.5-.07.16-.12.33-.22.5zm1.09-2.58c.05-.13.1-.25.16-.38-.06.13-.15.25-.15.38zm-3.35 7.36v-.05zm-5.4 9.3l-.28.42zm1.45-2.28l-.29.46zm1.35-2.25l-.19.32zm3.75-7.12c.07-.14.13-.29.2-.43-.07.14-.13.29-.2.43zM449 100.21q-1.41-1.75-2.85-3.46 1.39 1.71 2.85 3.46zM445.49 96c-1-1.18-2-2.35-3-3.51 1 1.19 2.01 2.36 3 3.51zm6.87 8.5q-1.36-1.74-2.76-3.5 1.4 1.76 2.76 3.53zm3.36 4.44c-.91-1.23-1.83-2.44-2.75-3.65.92 1.24 1.84 2.45 2.75 3.71zm-119.48 94.34l-.28-.42zm66.76-147q1.85 1.36 3.66 2.76-1.78-1.39-3.66-2.76zm12.23 9.62q-1.72-1.44-3.47-2.85 1.77 1.41 3.5 2.85zM411 62.4q-1.74-1.4-3.51-2.77Q409.24 61 411 62.4zm8.5 7.13q-1.74-1.53-3.51-3 1.75 1.47 3.49 3zm-75.38 148.33c-.07-.16-.15-.33-.22-.5.1.17.15.34.22.5zM184.49 192l-.36.4zM343 215.36c-.07-.14-.13-.29-.2-.43.06.14.12.29.2.43zm113.16-105.8c1 1.31 1.9 2.62 2.84 3.94-.95-1.32-1.89-2.63-2.85-3.94zM337.4 205.1l.29.46zm82.53-135.18a248.82 248.82 0 0 1 22.14 22.15 250.17 250.17 0 0 0-22.14-22.15zm-74.78 150.4a6.15 6.15 0 0 1-.16-.38c.01.13.1.25.16.38zM459 398.49a248 248 0 0 0 0-285L347 225.46a96.5 96.5 0 0 1 0 61.08zM341.67 212.63zM220.33 345.15l-.41-.17zm-2.46-1l-.52-.22zm-5.3-2.49l.1.05zM322 325.75l-.21.19zM309.14 336l-.43.29zm2-1.35l.17-.12zm4.48-3.34l.26-.21zm4-3.39l.4-.36zm-1.6 1.39l-.42.35zM215.38 343l-.46-.21zm-19-11.74l-.26-.21zm-4-3.39l-.4-.36zm-6.3-137.62l.19-.21zm4 135.5l.21.19zm15.52 11.94l-.47-.29zm2.26 1.35l-.34-.19zm78.72 8a96.5 96.5 0 0 1-61.08 0L113.51 459a248 248 0 0 0 285 0zM202.86 336l.43.29zm-2-1.35l-.17-.12zM416 445.49q1.77-1.49 3.51-3-1.77 1.51-3.51 3zm43-47c-.93 1.33-1.88 2.64-2.84 3.95.95-1.31 1.9-2.62 2.84-3.95zM411.79 449q1.74-1.41 3.47-2.85-1.72 1.39-3.47 2.85zm-4.32 3.42q1.77-1.38 3.51-2.77-1.74 1.35-3.51 2.72zM455.72 403q-1.37 1.85-2.76 3.66 1.4-1.78 2.76-3.66zm-10.23 13c-1 1.18-2 2.35-3 3.51 1-1.19 2.01-2.36 3-3.51zm3.46-4.18q-1.41 1.74-2.85 3.47 1.44-1.75 2.9-3.5zm.65-.81q1.39-1.74 2.77-3.51-1.37 1.74-2.77 3.5zm-150.17-69.38a.31.31 0 0 1-.1.05.31.31 0 0 0 .1-.05zm-5.3 2.49l.52-.22zm12.31-6.43l.47-.29zm-9.82 5.31l.46-.21zm7.56-4l.34-.19zm137.9 80.89a248.94 248.94 0 0 1-22.15 22.15 248.94 248.94 0 0 0 22.15-22.11zm-39.63 36.21q-2 1.44-4 2.85 2.04-1.37 4-2.81zM292.08 345l-.41.17zM403 455.72q1.85-1.37 3.66-2.76-1.78 1.4-3.66 2.76zM194 329.26l.42.35zM69.93 92.07a248.82 248.82 0 0 1 22.14-22.15 250.17 250.17 0 0 0-22.14 22.15zm30.28-29q-1.74 1.41-3.47 2.85 1.73-1.46 3.47-2.87zm90 123l-.21.19zm4.13-3.67l-.42.35zM109.55 55.86q2-1.44 4-2.85-2.03 1.41-4 2.85zM196.14 181l.26-.21zM104.53 59.63Q102.76 61 101 62.4q1.76-1.4 3.53-2.77zm.78-.59q1.81-1.4 3.66-2.76-1.84 1.37-3.66 2.72zm87.05 125.09l-.4.36zm22.56-14.92l.46-.21zm-2.25 1.11l-.1.05zm4.68-2.22l.52-.22zm2.57-1.08l.41-.17zm-17.06 9l.43-.29zm5-3.09l-.34.19zm-7.11 4.56l.17-.12zm4.38-2.92l.47-.29zM96.74 446.1q1.73 1.44 3.47 2.85-1.74-1.41-3.47-2.85zm-33.69-34.31q1.41 1.74 2.85 3.47-1.44-1.72-2.85-3.47zm3.46 4.21c1 1.18 2 2.35 3 3.51-1-1.19-2.01-2.36-3-3.51zm-10.23-13q1.36 1.85 2.76 3.66-1.39-1.78-2.76-3.66zm3.35 4.44q1.37 1.8 2.77 3.56-1.4-1.76-2.77-3.53zm32.89 35q1.74 1.53 3.51 3-1.77-1.44-3.51-2.97zM105.31 453q1.81 1.4 3.66 2.76-1.84-1.4-3.66-2.76zm8.2 6q-2-1.41-4-2.85 2.01 1.43 4 2.85zM101 449.6q1.74 1.39 3.51 2.77-1.75-1.37-3.51-2.77zm-45.15-47.16c-1-1.31-1.9-2.62-2.84-3.95.99 1.33 1.88 2.64 2.84 3.95zM65.9 96.75q-1.44 1.71-2.85 3.46 1.41-1.75 2.85-3.46zM56.29 109c.9-1.23 1.82-2.45 2.74-3.65-.92 1.17-1.84 2.39-2.74 3.65zm6.11-8q-1.4 1.74-2.76 3.51Q61 102.76 62.4 101zm7.12-8.5c-1 1.16-2 2.33-3 3.51.98-1.16 1.99-2.33 3-3.49zm23-23q1.74-1.53 3.51-3-1.77 1.5-3.51 3.03zm-.45 372.55a248.94 248.94 0 0 1-22.15-22.15 248.94 248.94 0 0 0 22.15 22.18zM165 286.54a96.5 96.5 0 0 1 0-61.08L53 113.51a248 248 0 0 0 0 285zm-109.11-177q-1.44 2-2.84 3.93 1.36-1.95 2.8-3.9z\", \"M347 225.46l112-111.95A249.4 249.4 0 0 0 398.49 53L286.54 165A96.26 96.26 0 0 1 347 225.46zm-182 61.08l-112 112a249.4 249.4 0 0 0 60.5 60.5L225.46 347A96.26 96.26 0 0 1 165 286.54zm-112-173l112 112a96.26 96.26 0 0 1 60.5-60.5L113.51 53A249.4 249.4 0 0 0 53 113.51zM286.54 347l112 112a249.4 249.4 0 0 0 60.5-60.5L347 286.54A96.26 96.26 0 0 1 286.54 347z\"]]\n};\nvar faLightbulb = {\n  prefix: 'fad',\n  iconName: 'lightbulb',\n  icon: [352, 512, [], \"f0eb\", [\"M175.45 0C73.44.31 0 83 0 176a175 175 0 0 0 43.56 115.78c16.52 18.85 42.36 58.22 52.21 91.45 0 .26.07.52.11.78h160.24c0-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45A175.9 175.9 0 0 0 175.45 0zm.55 96a80.09 80.09 0 0 0-80 80 16 16 0 0 1-32 0A112.12 112.12 0 0 1 176 64a16 16 0 0 1 0 32z\", \"M96.06 454.35L96 416h160v38.35a32 32 0 0 1-5.41 17.65l-17.09 25.73A32 32 0 0 1 206.86 512h-61.71a32 32 0 0 1-26.64-14.28L101.42 472a32 32 0 0 1-5.36-17.65z\"]]\n};\nvar faListAlt = {\n  prefix: 'fad',\n  iconName: 'list-alt',\n  icon: [512, 512, [], \"f022\", [\"M464 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zM128 392a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm288 168a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12z\", \"M128 200a40 40 0 1 0-40-40 40 40 0 0 0 40 40zm0 16a40 40 0 1 0 40 40 40 40 0 0 0-40-40zm0 96a40 40 0 1 0 40 40 40 40 0 0 0-40-40z\"]]\n};\nvar faListUl = {\n  prefix: 'fad',\n  iconName: 'list-ul',\n  icon: [512, 512, [], \"f0ca\", [\"M496 384H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48z\"]]\n};\nvar faLockAlt = {\n  prefix: 'fad',\n  iconName: 'lock-alt',\n  icon: [448, 512, [], \"f30d\", [\"M152 225H72v-72C72 69.2 140.2 1 224 1s152 68.2 152 152v72h-80v-72a72 72 0 0 0-144 0z\", \"M400 225H48a48 48 0 0 0-48 48v192a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V273a48 48 0 0 0-48-48zM264 392a40 40 0 0 1-80 0v-48a40 40 0 0 1 80 0z\"]]\n};\nvar faMapMarkerAlt = {\n  prefix: 'fad',\n  iconName: 'map-marker-alt',\n  icon: [384, 512, [], \"f3c5\", [\"M192 0C86 0 0 86 0 192c0 77.41 27 99 172.27 309.67a24 24 0 0 0 39.46 0C357 291 384 269.41 384 192 384 86 298 0 192 0zm0 288a96 96 0 1 1 96-96 96 96 0 0 1-96 96z\", \"M192 256a64 64 0 1 1 64-64 64 64 0 0 1-64 64z\"]]\n};\nvar faMoonStars = {\n  prefix: 'fad',\n  iconName: 'moon-stars',\n  icon: [512, 512, [], \"f755\", [\"M320 32L304 0l-16 32-32 16 32 16 16 32 16-32 32-16zm138.7 149.3L432 128l-26.7 53.3L352 208l53.3 26.7L432 288l26.7-53.3L512 208z\", \"M332.2 426.4c8.1-1.6 13.9 8 8.6 14.5a191.18 191.18 0 0 1-149 71.1C85.8 512 0 426 0 320c0-120 108.7-210.6 227-188.8 8.2 1.6 10.1 12.6 2.8 16.7a150.3 150.3 0 0 0-76.1 130.8c0 94 85.4 165.4 178.5 147.7z\"]]\n};\nvar faNetworkWired = {\n  prefix: 'fad',\n  iconName: 'network-wired',\n  icon: [640, 512, [], \"f6ff\", [\"M624 232H344v-40h-48v40H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h104v40h48v-40h304v40h48v-40h104a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z\", \"M224 192h192a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32H224a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32zm32-128h128v64H256zm320 256H416a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128h-96v-64h96zM224 320H64a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128H96v-64h96z\"]]\n};\nvar faPlanetRinged = {\n  prefix: 'fad',\n  iconName: 'planet-ringed',\n  icon: [512, 512, [], \"e020\", [\"M323.33815,323.33517C186.95939,459.71018,46.2602,540.11093,9.06777,502.9165c-23.48893-23.4909.01172-88.30917,54.81792-167.21379a206.56361,206.56361,0,0,0,25.02022,43.78446c-22.45765,34.20607-32.036,58.99194-23.71941,67.31053,18.59817,18.59624,119.10094-51.75539,224.47885-157.13342C395.04325,184.2882,465.39675,83.78336,446.79858,65.18712c-8.32054-8.3186-33.10638,1.26176-67.31045,23.71748a206.52984,206.52984,0,0,0-43.78245-25.0183C414.61019,9.082,479.42839-14.42259,502.91732,9.06832,540.10975,46.2608,459.70909,186.96211,323.33815,323.33517Z\", \"M448.0994,176.28016c-31.96573,46.02281-74.52549,96.81528-124.76125,147.055-50.24357,50.24168-101.034,92.79954-147.05874,124.76531,75.41614,31.25675,165.47721,16.29343,226.79531-45.02474S479.35807,251.69834,448.0994,176.28016Zm-25.02022-43.78251A208.22535,208.22535,0,0,0,403.07472,108.911c-81.2288-81.23281-212.93555-81.23281-294.16435,0-81.22881,81.23085-81.22881,212.93385,0,294.1647A208.25527,208.25527,0,0,0,132.497,423.08023c42.25117-27.73908,98.93242-75.1799,157.1684-133.41595C347.90133,231.43018,395.34013,174.75473,423.07918,132.49765Z\"]]\n};\nvar faQuestionCircle = {\n  prefix: 'fad',\n  iconName: 'question-circle',\n  icon: [512, 512, [], \"f059\", [\"M256 8C119 8 8 119.08 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 422a46 46 0 1 1 46-46 46.05 46.05 0 0 1-46 46zm40-131.33V300a12 12 0 0 1-12 12h-56a12 12 0 0 1-12-12v-4c0-41.06 31.13-57.47 54.65-70.66 20.17-11.31 32.54-19 32.54-34 0-19.82-25.27-33-45.7-33-27.19 0-39.44 13.14-57.3 35.79a12 12 0 0 1-16.67 2.13L148.82 170a12 12 0 0 1-2.71-16.26C173.4 113 208.16 90 262.66 90c56.34 0 116.53 44 116.53 102 0 77-83.19 78.21-83.19 106.67z\", \"M256 338a46 46 0 1 0 46 46 46 46 0 0 0-46-46zm6.66-248c-54.5 0-89.26 23-116.55 63.76a12 12 0 0 0 2.71 16.24l34.7 26.31a12 12 0 0 0 16.67-2.13c17.86-22.65 30.11-35.79 57.3-35.79 20.43 0 45.7 13.14 45.7 33 0 15-12.37 22.66-32.54 34C247.13 238.53 216 254.94 216 296v4a12 12 0 0 0 12 12h56a12 12 0 0 0 12-12v-1.33c0-28.46 83.19-29.67 83.19-106.67 0-58-60.19-102-116.53-102z\"]]\n};\nvar faQuoteLeft = {\n  prefix: 'fad',\n  iconName: 'quote-left',\n  icon: [512, 512, [], \"f10d\", [\"M464 256h-80v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H448a160 160 0 0 0-160 160v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\", \"M176 256H96v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H160A160 160 0 0 0 0 192v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\"]]\n};\nvar faRandom = {\n  prefix: 'fad',\n  iconName: 'random',\n  icon: [512, 512, [], \"f074\", [\"M505 359l-80-80c-15-15-41-4.47-41 17v40h-32l-52.78-56.55-53.33 57.14 70.55 75.6a12 12 0 0 0 8.77 3.81H384v40c0 21.46 26 32 41 17l80-80a24 24 0 0 0 0-34zM122.79 96H12a12 12 0 0 0-12 12v56a12 12 0 0 0 12 12h84l52.78 56.55 53.33-57.14-70.55-75.6a12 12 0 0 0-8.77-3.81z\", \"M505 119a24 24 0 0 1 0 34l-80 80c-15 15-41 4.48-41-17v-40h-32L131.56 412.19a12 12 0 0 1-8.77 3.81H12a12 12 0 0 1-12-12v-56a12 12 0 0 1 12-12h84L316.44 99.81a12 12 0 0 1 8.78-3.81H384V56c0-21.44 25.94-32 41-17z\"]]\n};\nvar faRocket = {\n  prefix: 'fad',\n  iconName: 'rocket',\n  icon: [512, 512, [], \"f135\", [\"M51.94117,154.48438,2.531,253.29688A28.125,28.125,0,0,0-.00023,264a24.00619,24.00619,0,0,0,24,24H117.4607c23.44141-47.41211,61.01172-123.373,77.89063-157.32812.51953-.91407,1-1.76758,1.52344-2.67188H94.82008C78.47633,128.01562,59.28883,139.875,51.94117,154.48438Zm172.0586,240.1621V488.209A24.12394,24.12394,0,0,0,247.9607,512a28.02965,28.02965,0,0,0,10.625-2.53125l98.72657-49.39063c14.625-7.3125,26.5-26.5,26.5-42.85937V315.70312c.0664-.041.125-.08789.1875-.1289v-.52734c-.90625.51953-1.7461,1.002-2.66407,1.52539C347.37477,333.58008,271.2732,371.252,223.99977,394.64648Z\", \"M505.15992,19.51562A16.73971,16.73971,0,0,0,492.62477,6.94531C460.22633,0,434.37477,0,409.48414,0,320.3357,0,252.80836,40.61523,196.97633,127.81836c-.5586.97852-1.07031,1.877-1.625,2.85352-19.59766,39.42578-67.20313,135.70312-88.04688,177.877a31.91421,31.91421,0,0,0,6.09766,36.76172L167.05445,398.709a31.88923,31.88923,0,0,0,36.64844,5.98047l14.17578-7.01367c46.57422-23.04883,128.06641-63.3789,163.457-81.10351.96094-.54883,1.832-1.04883,2.78907-1.59766,87.23437-56.06055,127.85937-123.51172,127.85937-212.27734C512.06227,77.60742,512.12867,52.08789,505.15992,19.51562ZM367.99977,192a48,48,0,1,1,48-48.00195A48.02156,48.02156,0,0,1,367.99977,192Z\"]]\n};\nvar faSearch = {\n  prefix: 'fad',\n  iconName: 'search',\n  icon: [512, 512, [], \"f002\", [\"M208 80a128 128 0 1 1-90.51 37.49A127.15 127.15 0 0 1 208 80m0-80C93.12 0 0 93.12 0 208s93.12 208 208 208 208-93.12 208-208S322.88 0 208 0z\", \"M504.9 476.7L476.6 505a23.9 23.9 0 0 1-33.9 0L343 405.3a24 24 0 0 1-7-17V372l36-36h16.3a24 24 0 0 1 17 7l99.7 99.7a24.11 24.11 0 0 1-.1 34z\"]]\n};\nvar faServer = {\n  prefix: 'fad',\n  iconName: 'server',\n  icon: [512, 512, [], \"f233\", [\"M432 120a24 24 0 1 0-24-24 24 24 0 0 0 24 24zm0 272a24 24 0 1 0 24 24 24 24 0 0 0-24-24zm48-200H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\", \"M456 256a24 24 0 1 0-24 24 24 24 0 0 0 24-24zm24-224H32A32 32 0 0 0 0 64v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm48 232H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\"]]\n};\nvar faSignOut = {\n  prefix: 'fad',\n  iconName: 'sign-out',\n  icon: [512, 512, [], \"f08b\", [\"M180 448H96a96 96 0 0 1-96-96V160a96 96 0 0 1 96-96h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12H96a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12z\", \"M353 88.3l151.9 150.6a24 24 0 0 1 0 34.1l-152 150.8a24.08 24.08 0 0 1-33.9-.1l-21.9-21.9a24.07 24.07 0 0 1 .8-34.7l77.6-71.1H184a23.94 23.94 0 0 1-24-24v-32a23.94 23.94 0 0 1 24-24h191.5l-77.6-71.1a24 24 0 0 1-.7-34.6l21.9-21.9a24 24 0 0 1 33.9-.1z\"]]\n};\nvar faSirenOn = {\n  prefix: 'fad',\n  iconName: 'siren-on',\n  icon: [640, 512, [], \"e02e\", [\"M224.21,134.94a8,8,0,0,1,9-6.87l15.86,2.13a8,8,0,0,1,6.87,9L231.82,320H496L471,120.06A64,64,0,0,0,407.5,64h-175A64,64,0,0,0,169,120.06L144,320h55.54Z\", \"M528,352H112a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16H528a16,16,0,0,0,16-16V368A16,16,0,0,0,528,352ZM112,192a24,24,0,0,0-24-24H24a24,24,0,0,0,0,48H88A24,24,0,0,0,112,192Zm504-24H552a24,24,0,0,0,0,48h64a24,24,0,0,0,0-48ZM90.69,76a24,24,0,1,0,26.62-39.92l-48-32A24,24,0,1,0,42.69,44ZM536,80a23.87,23.87,0,0,0,13.29-4l48-32A24,24,0,1,0,570.69,4.06l-48,32A24,24,0,0,0,536,80Z\"]]\n};\nvar faSmile = {\n  prefix: 'fad',\n  iconName: 'smile',\n  icon: [496, 512, [], \"f118\", [\"M248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256,385,8,248,8Zm80,168a32,32,0,1,1-32,32A32,32,0,0,1,328,176Zm-160,0a32,32,0,1,1-32,32A32,32,0,0,1,168,176ZM362.8,346.2a149.38,149.38,0,0,1-229.6,0c-13.6-16.3,11-36.7,24.6-20.5a117.5,117.5,0,0,0,180.4,0C351.6,309.5,376.3,329.9,362.8,346.2Z\", \"M328,176a32,32,0,1,0,32,32A32,32,0,0,0,328,176Zm-160,0a32,32,0,1,0,32,32A32,32,0,0,0,168,176Z\"]]\n};\nvar faSnowman = {\n  prefix: 'fad',\n  iconName: 'snowman',\n  icon: [512, 512, [], \"f7d0\", [\"M363.76 268.8a108.77 108.77 0 0 0 4.2-28.7v-.1a112.68 112.68 0 0 0-.73-12.8c-.11-1-.24-2-.38-3-.29-2-.62-4-1-6-.2-1-.4-1.95-.62-2.92-.22-1-.45-1.93-.7-2.9-.24-1-.5-1.91-.77-2.85-.27-.95-.55-1.89-.84-2.83-.3-.94-.6-1.87-.92-2.8-.32-.93-.65-1.86-1-2.77-.34-.92-.69-1.83-1.06-2.74-.36-.9-.74-1.8-1.13-2.7-.39-.89-.79-1.78-1.19-2.66-.41-.88-.83-1.76-1.26-2.63q-1.31-2.62-2.73-5.16c-.48-.85-1-1.68-1.46-2.51a112.44 112.44 0 0 0-21.62-26.19 96 96 0 1 0-149.16 0 112.49 112.49 0 0 0-21.68 26.28q-.74 1.23-1.44 2.49c-.48.84-.94 1.69-1.39 2.54-.45.85-.89 1.7-1.32 2.57-.43.87-.85 1.74-1.25 2.62-.41.88-.8 1.76-1.19 2.66-.39.89-.76 1.79-1.12 2.69-.36.91-.71 1.82-1.05 2.74-.34.92-.67 1.84-1 2.76a111.63 111.63 0 0 0-5.22 23.28A113 113 0 0 0 144 240h.06v.1a110.27 110.27 0 0 0 4.2 28.9A151.18 151.18 0 0 0 104 376.1c0 54 28.4 100.9 70.8 127.8 9.3 5.9 20.3 8.2 31.3 8.2h99.2a65.1 65.1 0 0 0 37.2-11.7c46.5-32.3 74.4-89.4 62.9-152.6-5.54-30.2-20.54-57.6-41.64-79zM224 96.1a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm32 272a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm0-64a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm1.7-64.1a15.19 15.19 0 0 1-3.48 0 16 16 0 1 1 3.48 0zm-1.7-87.9s-16-23.2-16-32a16 16 0 1 1 32 0c0 8.8-16 32-16 32zm32-56a16 16 0 1 1 16-16 16 16 0 0 1-16 16z\", \"M510.86 152.4L505 137.9a16.15 16.15 0 0 0-20.8-8.7L456 140.7v-29a15.84 15.84 0 0 0-16-15.6h-16a15.84 15.84 0 0 0-16 15.6v46.9c0 .5.3 1 .3 1.5l-56.1 22.54a111.21 111.21 0 0 1 15.07 44.56L502 172.7a15.57 15.57 0 0 0 8.86-20.3zm-407.1 6.2v-46.9c.2-8.6-7-15.6-15.8-15.6H72a15.84 15.84 0 0 0-16 15.6v29l-28.1-11.5a16.15 16.15 0 0 0-20.8 8.7l-5.9 14.5a15.48 15.48 0 0 0 8.9 20.3l134.67 54.49a111.3 111.3 0 0 1 15-44.46l-56.31-22.63a8 8 0 0 0 .3-1.5zM256 336.1a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16z\"]]\n};\nvar faSun = {\n  prefix: 'fad',\n  iconName: 'sun',\n  icon: [512, 512, [], \"f185\", [\"M502.42 240.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.41-94.8a17.31 17.31 0 0 0-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4a17.31 17.31 0 0 0 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.41-33.5 47.3 94.7a17.31 17.31 0 0 0 31 0l47.31-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3a17.33 17.33 0 0 0 .2-31.1zm-155.9 106c-49.91 49.9-131.11 49.9-181 0a128.13 128.13 0 0 1 0-181c49.9-49.9 131.1-49.9 181 0a128.13 128.13 0 0 1 0 181z\", \"M352 256a96 96 0 1 1-96-96 96.15 96.15 0 0 1 96 96z\"]]\n};\nvar faTasks = {\n  prefix: 'fad',\n  iconName: 'tasks',\n  icon: [512, 512, [], \"f0ae\", [\"M496 384H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M139.61 35.5a12 12 0 0 0-17 0L58.93 98.81l-22.7-22.12a12 12 0 0 0-17 0L3.53 92.41a12 12 0 0 0 0 17l47.59 47.4a12.78 12.78 0 0 0 17.61 0l15.59-15.62L156.52 69a12.09 12.09 0 0 0 .09-17zm0 159.19a12 12 0 0 0-17 0l-63.68 63.72-22.7-22.1a12 12 0 0 0-17 0L3.53 252a12 12 0 0 0 0 17L51 316.5a12.77 12.77 0 0 0 17.6 0l15.7-15.69 72.2-72.22a12 12 0 0 0 .09-16.9zM64 368c-26.49 0-48.59 21.5-48.59 48S37.53 464 64 464a48 48 0 0 0 0-96z\"]]\n};\nvar faUniversity = {\n  prefix: 'fad',\n  iconName: 'university',\n  icon: [512, 512, [], \"f19c\", [\"M160,192V384h64V192h64V384h64V192h64V384h36a12,12,0,0,1,12,12v20H48V396a12,12,0,0,1,12-12H96V192Z\", \"M491.06,120.61l-232-88a8,8,0,0,0-6.12,0l-232,88A8,8,0,0,0,16,128v16a8,8,0,0,0,8,8H48v12a12,12,0,0,0,12,12H452a12,12,0,0,0,12-12V152h24a8,8,0,0,0,8-8V128A8,8,0,0,0,491.06,120.61ZM472,432H40a24,24,0,0,0-24,24v16a8,8,0,0,0,8,8H488a8,8,0,0,0,8-8V456A24,24,0,0,0,472,432Z\"]]\n};\nvar faUser = {\n  prefix: 'fad',\n  iconName: 'user',\n  icon: [448, 512, [], \"f007\", [\"M352 128A128 128 0 1 1 224 0a128 128 0 0 1 128 128z\", \"M313.6 288h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48v-41.6A134.43 134.43 0 0 0 313.6 288z\"]]\n};\nvar faUserHardHat = {\n  prefix: 'fad',\n  iconName: 'user-hard-hat',\n  icon: [448, 512, [], \"f82c\", [\"M97.61 208h252.78c-7.95 63.06-61.17 112-126.39 112S105.56 271.06 97.61 208z\", \"M313.6 352h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.4 134.4 0 0 0 0 486.4 25.6 25.6 0 0 0 25.6 512h396.8a25.6 25.6 0 0 0 25.6-25.6A134.4 134.4 0 0 0 313.6 352zM88 176h272a8 8 0 0 0 8-8v-32a8 8 0 0 0-8-8h-8a112 112 0 0 0-68.4-103.2L256 80V16a16 16 0 0 0-16-16h-32a16 16 0 0 0-16 16v64l-27.6-55.2A112 112 0 0 0 96 128h-8a8 8 0 0 0-8 8v32a8 8 0 0 0 8 8z\"]]\n};\nvar faUserShield = {\n  prefix: 'fad',\n  iconName: 'user-shield',\n  icon: [640, 512, [], \"f505\", [\"M622.3 271.1l-115.2-45a31 31 0 0 0-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9a31 31 0 0 0 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8z\", \"M224 256A128 128 0 1 0 96 128a128 128 0 0 0 128 128zm96 40c0-2.5.8-4.8 1.1-7.2-2.5-.1-4.9-.8-7.5-.8h-16.7a174.08 174.08 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a49.22 49.22 0 0 0 19.2-4c-54-42.9-99.2-116.7-99.2-212z\"]]\n};\nvar faUsers = {\n  prefix: 'fad',\n  iconName: 'users',\n  icon: [640, 512, [], \"f0c0\", [\"M96 224a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64zm480 32h-64a63.81 63.81 0 0 0-45.1 18.6A146.27 146.27 0 0 1 542 384h66a32 32 0 0 0 32-32v-32a64.06 64.06 0 0 0-64-64zm-512 0a64.06 64.06 0 0 0-64 64v32a32 32 0 0 0 32 32h65.9a146.64 146.64 0 0 1 75.2-109.4A63.81 63.81 0 0 0 128 256zm480-32a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64z\", \"M396.8 288h-8.3a157.53 157.53 0 0 1-68.5 16c-24.6 0-47.6-6-68.5-16h-8.3A115.23 115.23 0 0 0 128 403.2V432a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48v-28.8A115.23 115.23 0 0 0 396.8 288zM320 256a112 112 0 1 0-112-112 111.94 111.94 0 0 0 112 112z\"]]\n};\nvar _iconsCache = {\n  faAbacus: faAbacus,\n  faAlignSlash: faAlignSlash,\n  faAtomAlt: faAtomAlt,\n  faBadgeCheck: faBadgeCheck,\n  faBell: faBell,\n  faBooks: faBooks,\n  faBracketsCurly: faBracketsCurly,\n  faChartNetwork: faChartNetwork,\n  faChartScatter: faChartScatter,\n  faCheck: faCheck,\n  faCircle: faCircle,\n  faClouds: faClouds,\n  faCogs: faCogs,\n  faCommentDots: faCommentDots,\n  faConciergeBell: faConciergeBell,\n  faDotCircle: faDotCircle,\n  faEnvelope: faEnvelope,\n  faExchangeAlt: faExchangeAlt,\n  faFileAlt: faFileAlt,\n  faFileCode: faFileCode,\n  faGlobe: faGlobe,\n  faGlobeAfrica: faGlobeAfrica,\n  faGlobeAmericas: faGlobeAmericas,\n  faGlobeAsia: faGlobeAsia,\n  faGlobeEurope: faGlobeEurope,\n  faGraduationCap: faGraduationCap,\n  faHistory: faHistory,\n  faKey: faKey,\n  faKeySkeleton: faKeySkeleton,\n  faLaptop: faLaptop,\n  faLaptopCode: faLaptopCode,\n  faLaptopHouse: faLaptopHouse,\n  faLifeRing: faLifeRing,\n  faLightbulb: faLightbulb,\n  faListAlt: faListAlt,\n  faListUl: faListUl,\n  faLockAlt: faLockAlt,\n  faMapMarkerAlt: faMapMarkerAlt,\n  faMoonStars: faMoonStars,\n  faNetworkWired: faNetworkWired,\n  faPlanetRinged: faPlanetRinged,\n  faQuestionCircle: faQuestionCircle,\n  faQuoteLeft: faQuoteLeft,\n  faRandom: faRandom,\n  faRocket: faRocket,\n  faSearch: faSearch,\n  faServer: faServer,\n  faSignOut: faSignOut,\n  faSirenOn: faSirenOn,\n  faSmile: faSmile,\n  faSnowman: faSnowman,\n  faSun: faSun,\n  faTasks: faTasks,\n  faUniversity: faUniversity,\n  faUser: faUser,\n  faUserHardHat: faUserHardHat,\n  faUserShield: faUserShield,\n  faUsers: faUsers\n};\n\nexport { _iconsCache as fad, prefix, faAbacus, faAlignSlash, faAtomAlt, faBadgeCheck, faBell, faBooks, faBracketsCurly, faChartNetwork, faChartScatter, faCheck, faCircle, faClouds, faCogs, faCommentDots, faConciergeBell, faDotCircle, faEnvelope, faExchangeAlt, faFileAlt, faFileCode, faGlobe, faGlobeAfrica, faGlobeAmericas, faGlobeAsia, faGlobeEurope, faGraduationCap, faHistory, faKey, faKeySkeleton, faLaptop, faLaptopCode, faLaptopHouse, faLifeRing, faLightbulb, faListAlt, faListUl, faLockAlt, faMapMarkerAlt, faMoonStars, faNetworkWired, faPlanetRinged, faQuestionCircle, faQuoteLeft, faRandom, faRocket, faSearch, faServer, faSignOut, faSirenOn, faSmile, faSnowman, faSun, faTasks, faUniversity, faUser, faUserHardHat, faUserShield, faUsers };\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/index.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (factory((global['pro-duotone-svg-icons'] = {})));\n}(this, (function (exports) { 'use strict';\n\n  var prefix = \"fad\";\n  var faAbacus = {\n    prefix: 'fad',\n    iconName: 'abacus',\n    icon: [576, 512, [], \"f640\", [\"M192 440h-32v-48h32zM160 72v48h32V72zm96 160v48h32v-48zm-96 0v48h32v-48zm96 208h160v-48H256zm96-160h128v-48H352zM544 0a32 32 0 0 0-32 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32a32 32 0 0 0-32-32zM416 72H256v48h160zM32 0A32 32 0 0 0 0 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32A32 32 0 0 0 32 0z\", \"M144 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm-96 160h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm192 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm-96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zM464 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM144 352h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm224 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16z\"]]\n  };\n  var faAlignSlash = {\n    prefix: 'fad',\n    iconName: 'align-slash',\n    icon: [640, 512, [], \"f846\", [\"M528 352h-31.46l-82.81-64H528a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16zM96 304v32a16 16 0 0 0 16 16h175.21l-82.8-64H112a16 16 0 0 0-16 16zM528 96a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16H112a15.82 15.82 0 0 0-15 11.18L165.31 96zM112 416a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h340.83L370 416zm416-256H248.12l82.81 64H528a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M633.82 458.1L45.46 3.38A16 16 0 0 0 23 6.19L3.37 31.46a16 16 0 0 0 2.81 22.45l588.36 454.72a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45z\"]]\n  };\n  var faAtomAlt = {\n    prefix: 'fad',\n    iconName: 'atom-alt',\n    icon: [448, 512, [], \"f5d3\", [\"M424.37305,55.69141C408.294,39.61914,385.50879,32,358.58252,32,319.82764,32,272.43359,48.127,224,77.14453a493.86641,493.86641,0,0,0-58.042,41.03711C140.58252,138.875,114.57666,162.5918,85.75635,197.916a374.25237,374.25237,0,0,0,35.70263,58.082A505.23427,505.23427,0,0,1,224,153.65625a377.23937,377.23937,0,0,1,58.042-35.47266c70.01221-34.334,95.22461-19.07421,97.0625-17.23632,9.54248,9.543,7.67432,46.94531-16.86084,96.96875A492.27615,492.27615,0,0,1,403.06543,256C452.27637,173.91992,463.59277,94.90039,424.37305,55.69141ZM224,358.3418a377.44678,377.44678,0,0,1-58.042,35.47461c-70.01221,34.334-95.22461,19.07421-97.0625,17.23632-9.54248-9.543-7.67432-46.94335,16.86084-96.96875A492.27615,492.27615,0,0,1,44.93457,256C-4.27637,338.08008-15.59277,417.09961,23.627,456.30664,39.70605,472.38086,62.49121,480,89.41748,480c38.75488,0,86.14893-16.127,134.58252-45.14453a493.86641,493.86641,0,0,0,58.042-41.03711c25.38965-20.70508,51.42285-44.45606,80.20166-79.73438A373.962,373.962,0,0,0,326.541,256,505.23427,505.23427,0,0,1,224,358.3418Z\", \"M224,287.98828a31.99414,31.99414,0,1,0-32-31.99414A31.98908,31.98908,0,0,0,224,287.98828ZM121.46094,255.99805A374.13921,374.13921,0,0,1,85.7583,197.916c-24.53906-50.02344-26.40625-87.42579-16.86328-96.9668,1.83984-1.83789,27.05078-17.10156,97.062,17.23242A494.241,494.241,0,0,1,224,77.14453C175.5625,48.13086,128.16406,32,89.41846,32c-26.9336,0-49.707,7.61523-65.793,23.69141C-15.59326,94.90039-4.27686,173.91992,44.93408,256A492.0174,492.0174,0,0,0,85.7583,314.084c28.79639,35.30274,54.85889,59.07227,80.19873,79.73243A377.429,377.429,0,0,0,224,358.3418,505.131,505.131,0,0,1,121.46094,255.99805ZM403.06592,256a492.0174,492.0174,0,0,0-40.82422-58.084c-28.84326-35.35547-54.89795-59.10352-80.19873-79.73243A377.4073,377.4073,0,0,0,224,153.65625,505.20556,505.20556,0,0,1,326.53906,256a373.849,373.849,0,0,1,35.70264,58.084c24.53906,50.02149,26.40625,87.42383,16.86328,96.9668-1.83984,1.83789-27.05078,17.10156-97.062-17.23242A494.241,494.241,0,0,1,224,434.85547C272.4375,463.86914,319.83594,480,358.58154,480c26.9336,0,49.707-7.61523,65.793-23.69336C463.59326,417.09961,452.27686,338.08008,403.06592,256Z\"]]\n  };\n  var faBadgeCheck = {\n    prefix: 'fad',\n    iconName: 'badge-check',\n    icon: [512, 512, [], \"f336\", [\"M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z\", \"M367.2 211.75l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.06 15.56z\"]]\n  };\n  var faBell = {\n    prefix: 'fad',\n    iconName: 'bell',\n    icon: [448, 512, [], \"f0f3\", [\"M448 384c-.1 16.4-13 32-32.1 32H32.08C13 416 .09 400.4 0 384a31.25 31.25 0 0 1 8.61-21.71c19.32-20.76 55.47-52 55.47-154.29 0-77.7 54.48-139.9 127.94-155.16V32a32 32 0 1 1 64 0v20.84C329.42 68.1 383.9 130.3 383.9 208c0 102.3 36.15 133.53 55.47 154.29A31.27 31.27 0 0 1 448 384z\", \"M160 448h128a64 64 0 0 1-128 0z\"]]\n  };\n  var faBooks = {\n    prefix: 'fad',\n    iconName: 'books',\n    icon: [576, 512, [], \"f5db\", [\"M96 0H32A32 32 0 0 0 0 32v64h128V32A32 32 0 0 0 96 0zM0 384h128V128H0zm0 96a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H0zm513.62-17.78L401.08 42.71l-60.26 16.14 112.35 418.8c.11.39.2.79.29 1.18l60.29-16.15c-.04-.15-.09-.3-.13-.46zM160 480a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H160zM256 0h-64a32 32 0 0 0-32 32v64h124.79l-8-29.65a23.94 23.94 0 0 1 11.17-27V32A32 32 0 0 0 256 0zm-96 384h128V128H160z\", \"M0 416h128v-32H0zm0-288h128V96H0zm575.17 317.65L460.39 17.78a23.89 23.89 0 0 0-29.18-17h-.09L415.73 5a24 24 0 0 0-16.9 29.36l114.79 427.86a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.35zM160 416h128v-32H160zM338.39 49.78a23.89 23.89 0 0 0-29.18-17h-.09L293.73 37a24 24 0 0 0-16.9 29.36l8 29.65H160v32h128V108l103.62 386.22a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.33z\"]]\n  };\n  var faBracketsCurly = {\n    prefix: 'fad',\n    iconName: 'brackets-curly',\n    icon: [576, 512, [], \"f7ea\", [\"M566.64 233.37a32 32 0 0 1 0 45.25l-45.25 45.25a32 32 0 0 0-9.39 22.64V384a96 96 0 0 1-96 96h-48a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h48a32 32 0 0 0 32-32v-37.48a96 96 0 0 1 28.13-67.89L498.76 256l-22.62-22.62A96 96 0 0 1 448 165.47V128a32 32 0 0 0-32-32h-48a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h48a96 96 0 0 1 96 96v37.48a32 32 0 0 0 9.38 22.65l45.25 45.24z\", \"M208 32h-48a96 96 0 0 0-96 96v37.48a32.12 32.12 0 0 1-9.38 22.65L9.38 233.37a32 32 0 0 0 0 45.25l45.25 45.25A32.05 32.05 0 0 1 64 346.51V384a96 96 0 0 0 96 96h48a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-48a32 32 0 0 1-32-32v-37.48a96 96 0 0 0-28.13-67.89L77.26 256l22.63-22.63A96 96 0 0 0 128 165.48V128a32 32 0 0 1 32-32h48a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"]]\n  };\n  var faChartNetwork = {\n    prefix: 'fad',\n    iconName: 'chart-network',\n    icon: [640, 512, [], \"f78a\", [\"M64 240a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64zm88 80h48v-32h-48zm294.4-106.8l19.2 25.6 48-36-19.2-25.6zM576 64a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64z\", \"M576 384a63.84 63.84 0 0 0-38.3 13l-96-57.6a109.91 109.91 0 0 0 6.3-35.5 111.94 111.94 0 0 0-112-112 108.64 108.64 0 0 0-24.4 2.9l-40.8-87.4A63.84 63.84 0 1 0 224 128c1.1 0 2.1-.3 3.2-.3l41 87.8C241.5 235.9 224 267.8 224 304a111.71 111.71 0 0 0 193.2 76.7l95.8 57.5a63.87 63.87 0 1 0 63-54.2zm-240-32a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]]\n  };\n  var faChartScatter = {\n    prefix: 'fad',\n    iconName: 'chart-scatter',\n    icon: [512, 512, [], \"f7ee\", [\"M512 400v32a16 16 0 0 1-16 16H32a32 32 0 0 1-32-32V80a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16v304h432a16 16 0 0 1 16 16z\", \"M160 256a32 32 0 1 0 32 32 32 32 0 0 0-32-32zM416 96a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-224 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm192 160a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-96-64a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]]\n  };\n  var faCheck = {\n    prefix: 'fad',\n    iconName: 'check',\n    icon: [512, 512, [], \"f00c\", [\"M504.5 144.42L264.75 385.5 192 312.59l240.11-241a25.49 25.49 0 0 1 36.06-.14l.14.14L504.5 108a25.86 25.86 0 0 1 0 36.42z\", \"M264.67 385.59l-54.57 54.87a25.5 25.5 0 0 1-36.06.14l-.14-.14L7.5 273.1a25.84 25.84 0 0 1 0-36.41l36.2-36.41a25.49 25.49 0 0 1 36-.17l.16.17z\"]]\n  };\n  var faCircle = {\n    prefix: 'fad',\n    iconName: 'circle',\n    icon: [512, 512, [], \"f111\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 424c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\", \"M256 432c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\"]]\n  };\n  var faClouds = {\n    prefix: 'fad',\n    iconName: 'clouds',\n    icon: [640, 512, [], \"f744\", [\"M161.6 288H96a96 96 0 0 1 0-192c.6 0 1.1.2 1.6.2C105.3 41.9 151.6 0 208 0a111.61 111.61 0 0 1 104.5 72.7A95.07 95.07 0 0 1 352 64a96 96 0 0 1 96 96 93 93 0 0 1-7 34.7 110.5 110.5 0 0 0-31.6 11.8A142.54 142.54 0 0 0 304 160c-73.9 0-134.3 56.2-142.4 128z\", \"M640 416a96 96 0 0 1-96 96H224a96 96 0 0 1-96-96c0-42.5 27.8-78.2 66.1-90.8A113.72 113.72 0 0 1 192 304a111.94 111.94 0 0 1 112-112c43.2 0 80.4 24.9 99 60.8 14.7-17.5 36.4-28.8 61-28.8a80 80 0 0 1 80 80 78.09 78.09 0 0 1-1.6 16.2c.5 0 1-.2 1.6-.2a96 96 0 0 1 96 96z\"]]\n  };\n  var faCogs = {\n    prefix: 'fad',\n    iconName: 'cogs',\n    icon: [640, 512, [], \"f085\", [\"M638.41 387a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4L602 335a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6 12.36 12.36 0 0 0-15.1 5.4l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 44.9c-29.6-38.5 14.3-82.4 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79zm136.8-343.8a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4l8.2-14.3a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6A12.36 12.36 0 0 0 552 7.19l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 45c-29.6-38.5 14.3-82.5 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79z\", \"M420 303.79L386.31 287a173.78 173.78 0 0 0 0-63.5l33.7-16.8c10.1-5.9 14-18.2 10-29.1-8.9-24.2-25.9-46.4-42.1-65.8a23.93 23.93 0 0 0-30.3-5.3l-29.1 16.8a173.66 173.66 0 0 0-54.9-31.7V58a24 24 0 0 0-20-23.6 228.06 228.06 0 0 0-76 .1A23.82 23.82 0 0 0 158 58v33.7a171.78 171.78 0 0 0-54.9 31.7L74 106.59a23.91 23.91 0 0 0-30.3 5.3c-16.2 19.4-33.3 41.6-42.2 65.8a23.84 23.84 0 0 0 10.5 29l33.3 16.9a173.24 173.24 0 0 0 0 63.4L12 303.79a24.13 24.13 0 0 0-10.5 29.1c8.9 24.1 26 46.3 42.2 65.7a23.93 23.93 0 0 0 30.3 5.3l29.1-16.7a173.66 173.66 0 0 0 54.9 31.7v33.6a24 24 0 0 0 20 23.6 224.88 224.88 0 0 0 75.9 0 23.93 23.93 0 0 0 19.7-23.6v-33.6a171.78 171.78 0 0 0 54.9-31.7l29.1 16.8a23.91 23.91 0 0 0 30.3-5.3c16.2-19.4 33.7-41.6 42.6-65.8a24 24 0 0 0-10.5-29.1zm-151.3 4.3c-77 59.2-164.9-28.7-105.7-105.7 77-59.2 164.91 28.7 105.71 105.7z\"]]\n  };\n  var faCommentDots = {\n    prefix: 'fad',\n    iconName: 'comment-dots',\n    icon: [512, 512, [], \"f4ad\", [\"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5a8 8 0 0 0-1.5 8.7A7.83 7.83 0 0 0 8 480c66.3 0 116-31.8 140.6-51.4A305 305 0 0 0 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32z\", \"M128 208a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"]]\n  };\n  var faConciergeBell = {\n    prefix: 'fad',\n    iconName: 'concierge-bell',\n    icon: [512, 512, [], \"f562\", [\"M512 400v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h480a16 16 0 0 1 16 16zM208 112h16v18.29a224.73 224.73 0 0 1 64 0V112h16a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16z\", \"M480 352H32c0-123.71 100.29-224 224-224s224 100.29 224 224z\"]]\n  };\n  var faDotCircle = {\n    prefix: 'fad',\n    iconName: 'dot-circle',\n    icon: [512, 512, [], \"f192\", [\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm124.45 372.45A176 176 0 1 1 432 256a174.85 174.85 0 0 1-51.55 124.45z\", \"M256 336a80 80 0 1 1 80-80 80.09 80.09 0 0 1-80 80z\"]]\n  };\n  var faEnvelope = {\n    prefix: 'fad',\n    iconName: 'envelope',\n    icon: [512, 512, [], \"f0e0\", [\"M256.47 352h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V400a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V183.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52zM464 64H48a48 48 0 0 0-48 48v19a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4 23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131v-19a48 48 0 0 0-48-48z\", \"M512 131v52.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V131a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.69 12.12 49.75 41.4 72.93 41.4h.94c23.18 0 56.24-29.28 72.93-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131z\"]]\n  };\n  var faExchangeAlt = {\n    prefix: 'fad',\n    iconName: 'exchange-alt',\n    icon: [512, 512, [], \"f362\", [\"M128 272v48h360a24 24 0 0 1 24 24v16a24 24 0 0 1-24 24H128v48c0 21.44-25.94 32-41 17L7 369a24 24 0 0 1 0-33.94l80-80c15.14-15.12 41-4.35 41 16.94z\", \"M505 143.05a24 24 0 0 1 0 33.95l-80 80c-15 15-41 4.49-41-17v-48H24a24 24 0 0 1-24-24v-16a24 24 0 0 1 24-24h360V80c0-21.36 25.9-32 41-17z\"]]\n  };\n  var faFileAlt = {\n    prefix: 'fad',\n    iconName: 'file-alt',\n    icon: [384, 512, [], \"f15c\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zm-96 244a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM276 352H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12z\"]]\n  };\n  var faFileCode = {\n    prefix: 'fad',\n    iconName: 'file-code',\n    icon: [384, 512, [], \"f1c9\", [\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zM141.79 379.54l-19.58 20.84a5.41 5.41 0 0 1-7.64.24l-64.86-60.69a5.37 5.37 0 0 1-.24-7.6l.25-.25 64.86-60.7a5.42 5.42 0 0 1 7.64.24l19.58 20.85a5.4 5.4 0 0 1-.25 7.62l-.13.12L100.65 336l40.76 35.8a5.4 5.4 0 0 1 .49 7.62zm31.71 71.25l-27.45-8a5.38 5.38 0 0 1-3.67-6.67l61.49-211.24a5.38 5.38 0 0 1 6.68-3.64l27.45 8a5.4 5.4 0 0 1 3.63 6.67l-61.45 211.2a5.4 5.4 0 0 1-6.68 3.68zm161-111.12l-.25.25-64.86 60.69a5.42 5.42 0 0 1-7.64-.23l-19.58-20.84a5.37 5.37 0 0 1 .26-7.6l.13-.12L283.35 336l-40.76-35.8a5.4 5.4 0 0 1-.49-7.62l.11-.12 19.58-20.85a5.42 5.42 0 0 1 7.64-.24l64.86 60.7a5.36 5.36 0 0 1 .25 7.6z\", \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM141.41 371.8L100.65 336l40.76-35.8.13-.12a5.4 5.4 0 0 0 .25-7.62l-19.58-20.85a5.42 5.42 0 0 0-7.64-.24l-64.86 60.7-.25.25a5.37 5.37 0 0 0 .24 7.6l64.86 60.69a5.41 5.41 0 0 0 7.64-.24l19.58-20.84.11-.12a5.4 5.4 0 0 0-.48-7.61zm100.22-135.93a5.4 5.4 0 0 0-3.63-6.67l-27.45-8a5.38 5.38 0 0 0-6.68 3.64l-61.5 211.29a5.38 5.38 0 0 0 3.63 6.67l27.45 8a5.4 5.4 0 0 0 6.68-3.68l61.44-211.22zm92.66 96.2l-64.86-60.7a5.42 5.42 0 0 0-7.64.24l-19.58 20.85-.11.12a5.4 5.4 0 0 0 .49 7.62l40.76 35.8-40.76 35.8-.13.12a5.37 5.37 0 0 0-.26 7.6l19.58 20.84a5.42 5.42 0 0 0 7.64.23l64.86-60.69.25-.25a5.36 5.36 0 0 0-.25-7.6z\"]]\n  };\n  var faGlobe = {\n    prefix: 'fad',\n    iconName: 'globe',\n    icon: [496, 512, [], \"f0ac\", [\"M340.45,320H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256,575,575,0,0,1,340.45,320ZM160.2,160H335.8c-.41-2.31-.84-4.62-1.28-6.91-6-30.85-14.42-58.37-25.13-81.78C299.54,49.77,288,32.54,276.05,21.48,266.38,12.53,256.94,8,248,8s-18.38,4.53-28,13.48c-12,11.06-23.49,28.29-33.34,49.83C176,94.72,167.5,122.24,161.53,153.09,161,155.38,160.61,157.69,160.2,160ZM120,256a608,608,0,0,1,3.34-64H8.35a249.52,249.52,0,0,0,0,128h115A608,608,0,0,1,120,256Zm367.62-64h-115A608.06,608.06,0,0,1,376,256a608,608,0,0,1-3.34,64h115a249.52,249.52,0,0,0,0-128ZM476.7,160A248.62,248.62,0,0,0,315.58,17.32c24.13,33,42.89,83.15,52.75,142.68ZM315.58,494.68A248.59,248.59,0,0,0,476.71,352H368.33C358.47,411.53,339.71,461.68,315.58,494.68ZM335.8,352H160.2c.41,2.31.84,4.62,1.28,6.91,6,30.85,14.42,58.37,25.13,81.78,9.85,21.54,21.38,38.77,33.34,49.83,9.67,9,19.11,13.48,28.05,13.48s18.38-4.53,28.05-13.48c12-11.06,23.49-28.29,33.34-49.83,10.71-23.41,19.16-50.93,25.13-81.78C335,356.62,335.39,354.31,335.8,352ZM180.42,17.32A248.59,248.59,0,0,0,19.29,160H127.67C137.53,100.47,156.29,50.32,180.42,17.32ZM19.29,352A248.59,248.59,0,0,0,180.42,494.68c-24.13-33-42.89-83.15-52.75-142.68Z\", \"M376,256a608,608,0,0,0-3.34-64h115a245.72,245.72,0,0,0-10.92-32H368.33c-9.86-59.53-28.62-109.68-52.75-142.68A248.23,248.23,0,0,0,248,8c8.94,0,18.38,4.53,28.05,13.48,12,11.06,23.49,28.29,33.34,49.83,10.71,23.41,19.16,50.93,25.13,81.78.44,2.29.87,4.6,1.28,6.91H160.2c.41-2.31.84-4.62,1.28-6.91,6-30.85,14.42-58.37,25.13-81.78C196.46,49.77,208,32.54,220,21.48,229.62,12.53,239.06,8,248,8a248.23,248.23,0,0,0-67.58,9.32c-24.13,33-42.89,83.15-52.75,142.68H19.29A245.72,245.72,0,0,0,8.37,192h115a613.93,613.93,0,0,0,0,128H8.37a245.72,245.72,0,0,0,10.92,32H127.67c9.86,59.53,28.62,109.68,52.75,142.68A248.23,248.23,0,0,0,248,504c-8.94,0-18.38-4.53-28.05-13.48-12-11.06-23.49-28.29-33.34-49.83-10.71-23.41-19.16-50.93-25.13-81.78-.44-2.29-.87-4.6-1.28-6.91H335.8c-.41,2.31-.84,4.62-1.28,6.91-6,30.85-14.42,58.37-25.13,81.78-9.85,21.54-21.38,38.77-33.34,49.83-9.67,9-19.11,13.48-28.05,13.48a248.23,248.23,0,0,0,67.58-9.32c24.13-33,42.89-83.15,52.75-142.68H476.71a245.72,245.72,0,0,0,10.92-32h-115A605.37,605.37,0,0,0,376,256Zm-35.54,64H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256a575,575,0,0,1-3.55,64Z\"]]\n  };\n  var faGlobeAfrica = {\n    prefix: 'fad',\n    iconName: 'globe-africa',\n    icon: [496, 512, [], \"f57c\", [\"M491.33,208H423.5A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05A249.89,249.89,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256A249.51,249.51,0,0,0,491.33,208Z\", \"M423.5,208A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05C386,23.7,471,104.24,491.34,208Z\"]]\n  };\n  var faGlobeAmericas = {\n    prefix: 'fad',\n    iconName: 'globe-americas',\n    icon: [496, 512, [], \"f57d\", [\"M489.55,312.41C464,422.22,365.59,504,248,504,111,504,0,393,0,256A247,247,0,0,1,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311l-13.71-13.67A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A247,247,0,0,1,248,8C351.83,8,440.71,71.76,477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1Z\", \"M321.39,297.36A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A249,249,0,0,0,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311ZM477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1,55.64,29.22a249.21,249.21,0,0,0-11.88-150.14Z\"]]\n  };\n  var faGlobeAsia = {\n    prefix: 'fad',\n    iconName: 'globe-asia',\n    icon: [496, 512, [], \"f57e\", [\"M312,16.35V50.73a28,28,0,0,1-11.12,22.35l-41.41,31.27a8,8,0,0,0,.86,13.81l10.83,5.41A16,16,0,0,1,280,137.88V216a8,8,0,0,1-8,8h-3.06a8,8,0,0,1-7.15-4.42,4.47,4.47,0,0,0-1.72-1.86,4.42,4.42,0,0,0-6.06,1.54h0l-17.34,29A16,16,0,0,1,222.94,256h-.31a16,16,0,0,0-11.32,4.69l-5.66,5.66a8,8,0,0,0,0,11.31l5.66,5.66A16,16,0,0,1,216,294.63V304a16,16,0,0,1-16,16h-6.1a16,16,0,0,1-14.28-8.85L157,265.92a8,8,0,0,0-10.72-3.6h0a8.14,8.14,0,0,0-2.11,1.53l-19.47,19.46A16,16,0,0,1,113.38,288H2.05C17.74,409.88,121.84,504,248,504c137,0,248-111,248-248C496,141.13,418,44.56,312,16.35Zm96,342.08a16,16,0,0,1-4.69,11.31l-9.57,9.57A16,16,0,0,1,382.43,384H367.27a16,16,0,0,1-11.36-4.74l-13-13a26.78,26.78,0,0,0-25.42-7l-21.27,5.32a15.86,15.86,0,0,1-3.88.48H282a16,16,0,0,1-11.24-4.69l-11.91-11.91a8,8,0,0,1-2.34-5.66V332.6a8,8,0,0,1,5-7.43l39.34-15.74a26.35,26.35,0,0,0,5.59-3.05l23.71-16.89a8,8,0,0,1,4.64-1.48h12.14a8,8,0,0,1,7.39,4.93l5.35,12.85a4,4,0,0,0,3.69,2.46h3.8a4,4,0,0,0,3.84-2.88l4.16-14.49A4,4,0,0,1,379,288h6.06a4,4,0,0,1,4,4v13a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,1,408,333.83Z\", \"M260.07,217.72a4.47,4.47,0,0,1,1.72,1.86,8,8,0,0,0,7.15,4.42H272a8,8,0,0,0,8-8V137.88a16,16,0,0,0-8.84-14.31l-10.83-5.41a8,8,0,0,1-.86-13.81l41.41-31.27A28,28,0,0,0,312,50.73V16.35A248.23,248.23,0,0,0,248,8C111,8,0,119,0,256a249.89,249.89,0,0,0,2.05,32H113.38a16,16,0,0,0,11.31-4.69l19.47-19.46A8,8,0,0,1,157,265.92l22.62,45.23A16,16,0,0,0,193.9,320H200a16,16,0,0,0,16-16v-9.37a16,16,0,0,0-4.69-11.31l-5.66-5.66a8,8,0,0,1,0-11.31l5.66-5.66A16,16,0,0,1,222.63,256h.31a16,16,0,0,0,13.72-7.77L254,219.28a4.42,4.42,0,0,1,6.05-1.57Zm143.24,104.8L391.4,310.61a8,8,0,0,1-2.34-5.66V292a4,4,0,0,0-4-4H379a4,4,0,0,0-3.84,2.88L371,305.37a4,4,0,0,1-3.84,2.88h-3.8a4,4,0,0,1-3.69-2.46l-5.35-12.85a8,8,0,0,0-7.39-4.93H334.79a8,8,0,0,0-4.64,1.48l-23.71,16.89a26.35,26.35,0,0,1-5.59,3.05l-39.34,15.74a8,8,0,0,0-5,7.43v10.2a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,0,282,365.06h10.34a15.86,15.86,0,0,0,3.88-.48l21.27-5.32a26.78,26.78,0,0,1,25.42,7l13,13A16,16,0,0,0,367.27,384h15.16a16,16,0,0,0,11.31-4.69l9.57-9.57A16,16,0,0,0,408,358.43v-24.6a16,16,0,0,0-4.69-11.31Z\"]]\n  };\n  var faGlobeEurope = {\n    prefix: 'fad',\n    iconName: 'globe-europe',\n    icon: [496, 512, [], \"f7a2\", [\"M487.54,320.4H438.9a15.8,15.8,0,0,1-11.4-4.8l-32-32.6a11.92,11.92,0,0,1,.1-16.7l12.5-12.5v-8.7a11.37,11.37,0,0,0-3.3-8l-9.4-9.4a11.37,11.37,0,0,0-8-3.3h-16a11.31,11.31,0,0,1-8-19.3l9.4-9.4a11.37,11.37,0,0,1,8-3.3h32a11.35,11.35,0,0,0,11.3-11.3v-9.4a11.35,11.35,0,0,0-11.3-11.3H376.1a16,16,0,0,0-16,16v4.5a16,16,0,0,1-10.9,15.2l-31.6,10.5a8,8,0,0,0-5.5,7.6v2.2a8,8,0,0,1-8,8h-16a8,8,0,0,1-8-8,8,8,0,0,0-8-8H269a8.14,8.14,0,0,0-7.2,4.4l-9.4,18.7a15.94,15.94,0,0,1-14.3,8.8H216a16,16,0,0,1-16-16V199a16,16,0,0,1,4.7-11.3l20.1-20.1a24.77,24.77,0,0,0,7.2-17.5,8,8,0,0,1,5.5-7.6l40-13.3a11.66,11.66,0,0,0,4.4-2.7l26.8-26.8a11.31,11.31,0,0,0-8-19.3H280l-16,16v8a8,8,0,0,1-8,8H240a8,8,0,0,1-8-8v-20a8.05,8.05,0,0,1,3.2-6.4l82.42-60.08A247.79,247.79,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504a251.57,251.57,0,0,0,32.1-2.06V448.4a16,16,0,0,0-16-16H243.9c-10.8,0-26.7-5.3-35.4-11.8l-22.2-16.7a45.42,45.42,0,0,1-18.2-36.4V343.6a45.46,45.46,0,0,1,22.1-39l42.9-25.7a46.13,46.13,0,0,1,23.4-6.5h31.2a45.62,45.62,0,0,1,29.6,10.9l43.2,37.1h18.3a32,32,0,0,1,22.6,9.4l17.3,17.3.08.08C432,359.06,440,375.62,440,393.37V413A247.11,247.11,0,0,0,487.54,320.4ZM187.4,157.1a11.37,11.37,0,0,1-8,3.3h-16a11.31,11.31,0,0,1-8-19.3l25.4-25.4a11.31,11.31,0,0,1,19.3,8v16a11.37,11.37,0,0,1-3.3,8Z\", \"M187.4,157.1l9.4-9.4a11.37,11.37,0,0,0,3.3-8v-16a11.31,11.31,0,0,0-19.3-8l-25.4,25.4a11.31,11.31,0,0,0,8,19.3h16A11.37,11.37,0,0,0,187.4,157.1ZM418.78,347.18l-.08-.08-17.3-17.3a32,32,0,0,0-22.6-9.4H360.5l-43.2-37.1a45.62,45.62,0,0,0-29.6-10.9H256.5a46.13,46.13,0,0,0-23.4,6.5l-42.9,25.7a45.46,45.46,0,0,0-22.1,39v23.9a45.42,45.42,0,0,0,18.2,36.4l22.2,16.7c8.7,6.5,24.6,11.8,35.4,11.8h20.2a16,16,0,0,1,16,16v53.54A247.57,247.57,0,0,0,440,413V393.37C440,375.62,432,359.06,418.78,347.18ZM317.62,17.92,235.2,78a8.05,8.05,0,0,0-3.2,6.4v20a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-8l16-16h20.7a11.31,11.31,0,0,1,8,19.3l-26.8,26.8a11.66,11.66,0,0,1-4.4,2.7l-40,13.3a8,8,0,0,0-5.5,7.6,24.77,24.77,0,0,1-7.2,17.5l-20.1,20.1A16,16,0,0,0,200,199v25.3a16,16,0,0,0,16,16h22.1a15.94,15.94,0,0,0,14.3-8.8l9.4-18.7a8.14,8.14,0,0,1,7.2-4.4h3.1a8,8,0,0,1,8,8,8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-2.2a8,8,0,0,1,5.5-7.6l31.6-10.5a16,16,0,0,0,10.9-15.2v-4.5a16,16,0,0,1,16-16h36.7a11.35,11.35,0,0,1,11.3,11.3v9.4a11.35,11.35,0,0,1-11.3,11.3h-32a11.37,11.37,0,0,0-8,3.3l-9.4,9.4a11.31,11.31,0,0,0,8,19.3h16a11.37,11.37,0,0,1,8,3.3l9.4,9.4a11.37,11.37,0,0,1,3.3,8v8.7l-12.5,12.5a11.92,11.92,0,0,0-.1,16.7l32,32.6a15.8,15.8,0,0,0,11.4,4.8h48.64A248.29,248.29,0,0,0,496,256C496,143.18,420.71,48,317.62,17.92Z\"]]\n  };\n  var faGraduationCap = {\n    prefix: 'fad',\n    iconName: 'graduation-cap',\n    icon: [640, 512, [], \"f19d\", [\"M323.07 175.7L118.8 215.6a48.1 48.1 0 0 0-38.74 44.73 32 32 0 0 1 2.21 53.94l25.4 114.26A16 16 0 0 1 92 448H35.94a16 16 0 0 1-15.61-19.47l25.39-114.27a32 32 0 0 1 2.33-54 80.16 80.16 0 0 1 64.62-76.07l204.26-39.89a16 16 0 1 1 6.14 31.4z\", \"M622.33 198.8l-279 85.7a80 80 0 0 1-46.79 0L99.67 224a47.84 47.84 0 0 1 19.13-8.39l204.27-39.9a16 16 0 1 0-6.14-31.4l-204.26 39.88a79.87 79.87 0 0 0-47.57 29.18l-47.44-14.58c-23.54-7.23-23.54-38.36 0-45.59L296.6 67.5a79.92 79.92 0 0 1 46.8 0l278.93 85.7c23.55 7.24 23.55 38.36 0 45.6zM352.79 315.09a111.94 111.94 0 0 1-65.59 0l-145-44.55L128 384c0 35.35 86 64 192 64s192-28.65 192-64l-14.19-113.47z\"]]\n  };\n  var faHistory = {\n    prefix: 'fad',\n    iconName: 'history',\n    icon: [512, 512, [], \"f1da\", [\"M141.68 400.23a184 184 0 1 0-11.75-278.3l50.76 50.76c10.08 10.08 2.94 27.31-11.32 27.31H24a16 16 0 0 1-16-16V38.63c0-14.26 17.23-21.4 27.31-11.32l49.38 49.38A247.14 247.14 0 0 1 256 8c136.81 0 247.75 110.78 248 247.53S392.82 503.9 256.18 504a247 247 0 0 1-155.82-54.91 24 24 0 0 1-1.84-35.61l11.27-11.27a24 24 0 0 1 31.89-1.98z\", \"M288 152v104.35L328.7 288a24 24 0 0 1 4.21 33.68l-9.82 12.62a24 24 0 0 1-33.68 4.21L224 287.65V152a24 24 0 0 1 24-24h16a24 24 0 0 1 24 24z\"]]\n  };\n  var faKey = {\n    prefix: 'fad',\n    iconName: 'key',\n    icon: [512, 512, [], \"f084\", [\"M303.06 348.91l.1.09-24 27a24 24 0 0 1-17.94 8H224v40a24 24 0 0 1-24 24h-40v40a24 24 0 0 1-24 24H24a24 24 0 0 1-24-24v-78a24 24 0 0 1 7-17l161.83-161.83-.11-.35a176.24 176.24 0 0 0 134.34 118.09z\", \"M336 0a176 176 0 1 0 176 176A176 176 0 0 0 336 0zm48 176a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"]]\n  };\n  var faKeySkeleton = {\n    prefix: 'fad',\n    iconName: 'key-skeleton',\n    icon: [512, 512, [], \"f6f3\", [\"M251.31 372.91a16 16 0 0 1 0 22.63l-15.77 15.77a16 16 0 0 1-22.62 0L176 374.4l-30.87 30.86 36.11 36.11a16 16 0 0 1 0 22.63l-43.16 43.17a16 16 0 0 1-22.62 0l-36.12-36.11-36.26 36.25a16 16 0 0 1-22.62 0L4.69 491.54a16 16 0 0 1 0-22.63l255.12-255.12a64.18 64.18 0 0 0 38.4 38.4L214.4 336l36.91 36.91z\", \"M448 0H320a64 64 0 0 0-64 64v128a64 64 0 0 0 64 64h128a64 64 0 0 0 64-64V64a64 64 0 0 0-64-64zm-73.37 182.63a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25zm64-64a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25z\"]]\n  };\n  var faLaptop = {\n    prefix: 'fad',\n    iconName: 'laptop',\n    icon: [640, 512, [], \"f109\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M512 64H128v256h384zm112 352H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16z\"]]\n  };\n  var faLaptopCode = {\n    prefix: 'fad',\n    iconName: 'laptop-code',\n    icon: [640, 512, [], \"f5fc\", [\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\", \"M624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16zM512 64H128v256h384zM289 250.34l-11.31 11.31a16 16 0 0 1-22.63 0l-58.35-58.34a16 16 0 0 1 0-22.63L255 122.34a16 16 0 0 1 22.63 0L289 133.65a16 16 0 0 1 0 22.63L253.25 192 289 227.71a16 16 0 0 1 0 22.63zm154.35-47L385 261.66a16 16 0 0 1-22.63 0L351 250.35a16 16 0 0 1 0-22.63L386.75 192 351 156.29a16 16 0 0 1 0-22.63l11.31-11.31a16 16 0 0 1 22.63 0l58.34 58.34a16 16 0 0 1 .04 22.63z\"]]\n  };\n  var faLaptopHouse = {\n    prefix: 'fad',\n    iconName: 'laptop-house',\n    icon: [640, 512, [], \"e066\", [\"M272,416H96a32,32,0,0,1-32-32V219.88L42.34,239A16.51,16.51,0,0,1,33,242.48a16.22,16.22,0,0,1-10.63-4.78L3.55,216.42A16.4,16.4,0,0,1,0,207a16.15,16.15,0,0,1,4.78-10.61L216.58,8.92C222.12,4,232.64,0,240.05,0S258,4,263.5,8.92L352,87.3V48a16,16,0,0,1,16-16h32a16,16,0,0,1,16,16v96l59.24,52.42A16.31,16.31,0,0,1,480,207a16.51,16.51,0,0,1-3.58,9.44L469.74,224H332.8c-17.8,0-33.69,8.24-44.82,21.12V208a16,16,0,0,0-16-16H208a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16h64Z\", \"M629.33,448H592V288c0-17.67-12.89-32-28.8-32H332.8c-15.91,0-28.8,14.33-28.8,32V448H266.67A10.67,10.67,0,0,0,256,458.67v10.66A42.82,42.82,0,0,0,298.6,512H597.4A42.82,42.82,0,0,0,640,469.33V458.67A10.67,10.67,0,0,0,629.33,448ZM544,448H352V304H544Z\"]]\n  };\n  var faLifeRing = {\n    prefix: 'fad',\n    iconName: 'life-ring',\n    icon: [512, 512, [], \"f1cd\", [\"M292.08 167l-.41-.17zm-66.62-2a96.5 96.5 0 0 1 61.08 0l112-112a248 248 0 0 0-285 0zm68.67 2.92l.52.22zm2.49 1.12l.46.21zM186.25 322l-.19-.21zm-5.51-6.36l.21.26zm1.65 2c.12.14.23.28.35.41-.12-.15-.23-.29-.35-.43zm1.74 2l.36.4zm135.51-135.51l.4.36zM177.51 311.29l-.1-.15zM304.18 173l.34.19zm11.42 7.78l.26.21zm6.36 5.51l-.21-.19zm-3.96-3.55l-.42-.35zm-11.6-8.43l.47.29zm4.68 3.09l.17.12zm-2-1.35l-.43-.29zm-9.71-5.68l-.1-.05zm-123.61 32.91c.1-.14.19-.28.28-.42-.04.14-.18.28-.28.42zm-1.45 2.28l.29-.46zm-1.31 2.25l.19-.32zm-2.6 4.77zm10.38-16.18l.21-.26zm2-2.43c-.12.13-.23.27-.35.41.08-.14.19-.28.31-.38zm-5.33 6.89l.1-.15zm-8.2 14.07c-.07.14-.13.29-.2.43.03-.14.09-.29.16-.43zm5.39 92l-.29-.46zm-4.27-7.53v.05zm2.82 5.14l-.19-.32zm2.61 4.21c.1.14.19.28.28.42-.08-.17-.22-.31-.32-.45zm-6.8-12.11c.07.14.13.29.2.43-.06-.14-.12-.29-.2-.43zm-2-76.7c0 .13-.1.25-.16.38.07-.13.16-.25.16-.38zm1.09-2.58c-.07.17-.15.34-.22.5.13-.16.13-.33.23-.5zm-.22 76.78c.07.16.15.33.22.5-.09-.17-.09-.34-.21-.5zm-1-2.46c.06.13.11.25.16.38-.03-.13-.12-.25-.18-.38zm172-84.19l.19.32zM327.51 320l.36-.4zm-1.57 1.71l-.19.21zM325.75 190l.19.21zm3.51 128c.12-.13.23-.27.35-.41-.12.17-.23.31-.35.41zm2-121.63l-.21-.26zm0 119.2l-.21.26zm-1.65-121.22c-.12-.14-.23-.28-.35-.41.12.16.23.3.35.44zm-1.74-2l-.36-.4zm6.62 8.35l.1.15zm.1 110.43l-.1.15zM398.49 53q2 1.41 4 2.85-2-1.43-4-2.85zM343.9 294.64c.07-.17.15-.34.22-.5-.07.16-.12.33-.22.5zm1.09-2.58c.05-.13.1-.25.16-.38-.06.13-.15.25-.15.38zm-3.35 7.36v-.05zm-5.4 9.3l-.28.42zm1.45-2.28l-.29.46zm1.35-2.25l-.19.32zm3.75-7.12c.07-.14.13-.29.2-.43-.07.14-.13.29-.2.43zM449 100.21q-1.41-1.75-2.85-3.46 1.39 1.71 2.85 3.46zM445.49 96c-1-1.18-2-2.35-3-3.51 1 1.19 2.01 2.36 3 3.51zm6.87 8.5q-1.36-1.74-2.76-3.5 1.4 1.76 2.76 3.53zm3.36 4.44c-.91-1.23-1.83-2.44-2.75-3.65.92 1.24 1.84 2.45 2.75 3.71zm-119.48 94.34l-.28-.42zm66.76-147q1.85 1.36 3.66 2.76-1.78-1.39-3.66-2.76zm12.23 9.62q-1.72-1.44-3.47-2.85 1.77 1.41 3.5 2.85zM411 62.4q-1.74-1.4-3.51-2.77Q409.24 61 411 62.4zm8.5 7.13q-1.74-1.53-3.51-3 1.75 1.47 3.49 3zm-75.38 148.33c-.07-.16-.15-.33-.22-.5.1.17.15.34.22.5zM184.49 192l-.36.4zM343 215.36c-.07-.14-.13-.29-.2-.43.06.14.12.29.2.43zm113.16-105.8c1 1.31 1.9 2.62 2.84 3.94-.95-1.32-1.89-2.63-2.85-3.94zM337.4 205.1l.29.46zm82.53-135.18a248.82 248.82 0 0 1 22.14 22.15 250.17 250.17 0 0 0-22.14-22.15zm-74.78 150.4a6.15 6.15 0 0 1-.16-.38c.01.13.1.25.16.38zM459 398.49a248 248 0 0 0 0-285L347 225.46a96.5 96.5 0 0 1 0 61.08zM341.67 212.63zM220.33 345.15l-.41-.17zm-2.46-1l-.52-.22zm-5.3-2.49l.1.05zM322 325.75l-.21.19zM309.14 336l-.43.29zm2-1.35l.17-.12zm4.48-3.34l.26-.21zm4-3.39l.4-.36zm-1.6 1.39l-.42.35zM215.38 343l-.46-.21zm-19-11.74l-.26-.21zm-4-3.39l-.4-.36zm-6.3-137.62l.19-.21zm4 135.5l.21.19zm15.52 11.94l-.47-.29zm2.26 1.35l-.34-.19zm78.72 8a96.5 96.5 0 0 1-61.08 0L113.51 459a248 248 0 0 0 285 0zM202.86 336l.43.29zm-2-1.35l-.17-.12zM416 445.49q1.77-1.49 3.51-3-1.77 1.51-3.51 3zm43-47c-.93 1.33-1.88 2.64-2.84 3.95.95-1.31 1.9-2.62 2.84-3.95zM411.79 449q1.74-1.41 3.47-2.85-1.72 1.39-3.47 2.85zm-4.32 3.42q1.77-1.38 3.51-2.77-1.74 1.35-3.51 2.72zM455.72 403q-1.37 1.85-2.76 3.66 1.4-1.78 2.76-3.66zm-10.23 13c-1 1.18-2 2.35-3 3.51 1-1.19 2.01-2.36 3-3.51zm3.46-4.18q-1.41 1.74-2.85 3.47 1.44-1.75 2.9-3.5zm.65-.81q1.39-1.74 2.77-3.51-1.37 1.74-2.77 3.5zm-150.17-69.38a.31.31 0 0 1-.1.05.31.31 0 0 0 .1-.05zm-5.3 2.49l.52-.22zm12.31-6.43l.47-.29zm-9.82 5.31l.46-.21zm7.56-4l.34-.19zm137.9 80.89a248.94 248.94 0 0 1-22.15 22.15 248.94 248.94 0 0 0 22.15-22.11zm-39.63 36.21q-2 1.44-4 2.85 2.04-1.37 4-2.81zM292.08 345l-.41.17zM403 455.72q1.85-1.37 3.66-2.76-1.78 1.4-3.66 2.76zM194 329.26l.42.35zM69.93 92.07a248.82 248.82 0 0 1 22.14-22.15 250.17 250.17 0 0 0-22.14 22.15zm30.28-29q-1.74 1.41-3.47 2.85 1.73-1.46 3.47-2.87zm90 123l-.21.19zm4.13-3.67l-.42.35zM109.55 55.86q2-1.44 4-2.85-2.03 1.41-4 2.85zM196.14 181l.26-.21zM104.53 59.63Q102.76 61 101 62.4q1.76-1.4 3.53-2.77zm.78-.59q1.81-1.4 3.66-2.76-1.84 1.37-3.66 2.72zm87.05 125.09l-.4.36zm22.56-14.92l.46-.21zm-2.25 1.11l-.1.05zm4.68-2.22l.52-.22zm2.57-1.08l.41-.17zm-17.06 9l.43-.29zm5-3.09l-.34.19zm-7.11 4.56l.17-.12zm4.38-2.92l.47-.29zM96.74 446.1q1.73 1.44 3.47 2.85-1.74-1.41-3.47-2.85zm-33.69-34.31q1.41 1.74 2.85 3.47-1.44-1.72-2.85-3.47zm3.46 4.21c1 1.18 2 2.35 3 3.51-1-1.19-2.01-2.36-3-3.51zm-10.23-13q1.36 1.85 2.76 3.66-1.39-1.78-2.76-3.66zm3.35 4.44q1.37 1.8 2.77 3.56-1.4-1.76-2.77-3.53zm32.89 35q1.74 1.53 3.51 3-1.77-1.44-3.51-2.97zM105.31 453q1.81 1.4 3.66 2.76-1.84-1.4-3.66-2.76zm8.2 6q-2-1.41-4-2.85 2.01 1.43 4 2.85zM101 449.6q1.74 1.39 3.51 2.77-1.75-1.37-3.51-2.77zm-45.15-47.16c-1-1.31-1.9-2.62-2.84-3.95.99 1.33 1.88 2.64 2.84 3.95zM65.9 96.75q-1.44 1.71-2.85 3.46 1.41-1.75 2.85-3.46zM56.29 109c.9-1.23 1.82-2.45 2.74-3.65-.92 1.17-1.84 2.39-2.74 3.65zm6.11-8q-1.4 1.74-2.76 3.51Q61 102.76 62.4 101zm7.12-8.5c-1 1.16-2 2.33-3 3.51.98-1.16 1.99-2.33 3-3.49zm23-23q1.74-1.53 3.51-3-1.77 1.5-3.51 3.03zm-.45 372.55a248.94 248.94 0 0 1-22.15-22.15 248.94 248.94 0 0 0 22.15 22.18zM165 286.54a96.5 96.5 0 0 1 0-61.08L53 113.51a248 248 0 0 0 0 285zm-109.11-177q-1.44 2-2.84 3.93 1.36-1.95 2.8-3.9z\", \"M347 225.46l112-111.95A249.4 249.4 0 0 0 398.49 53L286.54 165A96.26 96.26 0 0 1 347 225.46zm-182 61.08l-112 112a249.4 249.4 0 0 0 60.5 60.5L225.46 347A96.26 96.26 0 0 1 165 286.54zm-112-173l112 112a96.26 96.26 0 0 1 60.5-60.5L113.51 53A249.4 249.4 0 0 0 53 113.51zM286.54 347l112 112a249.4 249.4 0 0 0 60.5-60.5L347 286.54A96.26 96.26 0 0 1 286.54 347z\"]]\n  };\n  var faLightbulb = {\n    prefix: 'fad',\n    iconName: 'lightbulb',\n    icon: [352, 512, [], \"f0eb\", [\"M175.45 0C73.44.31 0 83 0 176a175 175 0 0 0 43.56 115.78c16.52 18.85 42.36 58.22 52.21 91.45 0 .26.07.52.11.78h160.24c0-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45A175.9 175.9 0 0 0 175.45 0zm.55 96a80.09 80.09 0 0 0-80 80 16 16 0 0 1-32 0A112.12 112.12 0 0 1 176 64a16 16 0 0 1 0 32z\", \"M96.06 454.35L96 416h160v38.35a32 32 0 0 1-5.41 17.65l-17.09 25.73A32 32 0 0 1 206.86 512h-61.71a32 32 0 0 1-26.64-14.28L101.42 472a32 32 0 0 1-5.36-17.65z\"]]\n  };\n  var faListAlt = {\n    prefix: 'fad',\n    iconName: 'list-alt',\n    icon: [512, 512, [], \"f022\", [\"M464 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zM128 392a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm288 168a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12z\", \"M128 200a40 40 0 1 0-40-40 40 40 0 0 0 40 40zm0 16a40 40 0 1 0 40 40 40 40 0 0 0-40-40zm0 96a40 40 0 1 0 40 40 40 40 0 0 0-40-40z\"]]\n  };\n  var faListUl = {\n    prefix: 'fad',\n    iconName: 'list-ul',\n    icon: [512, 512, [], \"f0ca\", [\"M496 384H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48z\"]]\n  };\n  var faLockAlt = {\n    prefix: 'fad',\n    iconName: 'lock-alt',\n    icon: [448, 512, [], \"f30d\", [\"M152 225H72v-72C72 69.2 140.2 1 224 1s152 68.2 152 152v72h-80v-72a72 72 0 0 0-144 0z\", \"M400 225H48a48 48 0 0 0-48 48v192a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V273a48 48 0 0 0-48-48zM264 392a40 40 0 0 1-80 0v-48a40 40 0 0 1 80 0z\"]]\n  };\n  var faMapMarkerAlt = {\n    prefix: 'fad',\n    iconName: 'map-marker-alt',\n    icon: [384, 512, [], \"f3c5\", [\"M192 0C86 0 0 86 0 192c0 77.41 27 99 172.27 309.67a24 24 0 0 0 39.46 0C357 291 384 269.41 384 192 384 86 298 0 192 0zm0 288a96 96 0 1 1 96-96 96 96 0 0 1-96 96z\", \"M192 256a64 64 0 1 1 64-64 64 64 0 0 1-64 64z\"]]\n  };\n  var faMoonStars = {\n    prefix: 'fad',\n    iconName: 'moon-stars',\n    icon: [512, 512, [], \"f755\", [\"M320 32L304 0l-16 32-32 16 32 16 16 32 16-32 32-16zm138.7 149.3L432 128l-26.7 53.3L352 208l53.3 26.7L432 288l26.7-53.3L512 208z\", \"M332.2 426.4c8.1-1.6 13.9 8 8.6 14.5a191.18 191.18 0 0 1-149 71.1C85.8 512 0 426 0 320c0-120 108.7-210.6 227-188.8 8.2 1.6 10.1 12.6 2.8 16.7a150.3 150.3 0 0 0-76.1 130.8c0 94 85.4 165.4 178.5 147.7z\"]]\n  };\n  var faNetworkWired = {\n    prefix: 'fad',\n    iconName: 'network-wired',\n    icon: [640, 512, [], \"f6ff\", [\"M624 232H344v-40h-48v40H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h104v40h48v-40h304v40h48v-40h104a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z\", \"M224 192h192a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32H224a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32zm32-128h128v64H256zm320 256H416a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128h-96v-64h96zM224 320H64a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128H96v-64h96z\"]]\n  };\n  var faPlanetRinged = {\n    prefix: 'fad',\n    iconName: 'planet-ringed',\n    icon: [512, 512, [], \"e020\", [\"M323.33815,323.33517C186.95939,459.71018,46.2602,540.11093,9.06777,502.9165c-23.48893-23.4909.01172-88.30917,54.81792-167.21379a206.56361,206.56361,0,0,0,25.02022,43.78446c-22.45765,34.20607-32.036,58.99194-23.71941,67.31053,18.59817,18.59624,119.10094-51.75539,224.47885-157.13342C395.04325,184.2882,465.39675,83.78336,446.79858,65.18712c-8.32054-8.3186-33.10638,1.26176-67.31045,23.71748a206.52984,206.52984,0,0,0-43.78245-25.0183C414.61019,9.082,479.42839-14.42259,502.91732,9.06832,540.10975,46.2608,459.70909,186.96211,323.33815,323.33517Z\", \"M448.0994,176.28016c-31.96573,46.02281-74.52549,96.81528-124.76125,147.055-50.24357,50.24168-101.034,92.79954-147.05874,124.76531,75.41614,31.25675,165.47721,16.29343,226.79531-45.02474S479.35807,251.69834,448.0994,176.28016Zm-25.02022-43.78251A208.22535,208.22535,0,0,0,403.07472,108.911c-81.2288-81.23281-212.93555-81.23281-294.16435,0-81.22881,81.23085-81.22881,212.93385,0,294.1647A208.25527,208.25527,0,0,0,132.497,423.08023c42.25117-27.73908,98.93242-75.1799,157.1684-133.41595C347.90133,231.43018,395.34013,174.75473,423.07918,132.49765Z\"]]\n  };\n  var faQuestionCircle = {\n    prefix: 'fad',\n    iconName: 'question-circle',\n    icon: [512, 512, [], \"f059\", [\"M256 8C119 8 8 119.08 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 422a46 46 0 1 1 46-46 46.05 46.05 0 0 1-46 46zm40-131.33V300a12 12 0 0 1-12 12h-56a12 12 0 0 1-12-12v-4c0-41.06 31.13-57.47 54.65-70.66 20.17-11.31 32.54-19 32.54-34 0-19.82-25.27-33-45.7-33-27.19 0-39.44 13.14-57.3 35.79a12 12 0 0 1-16.67 2.13L148.82 170a12 12 0 0 1-2.71-16.26C173.4 113 208.16 90 262.66 90c56.34 0 116.53 44 116.53 102 0 77-83.19 78.21-83.19 106.67z\", \"M256 338a46 46 0 1 0 46 46 46 46 0 0 0-46-46zm6.66-248c-54.5 0-89.26 23-116.55 63.76a12 12 0 0 0 2.71 16.24l34.7 26.31a12 12 0 0 0 16.67-2.13c17.86-22.65 30.11-35.79 57.3-35.79 20.43 0 45.7 13.14 45.7 33 0 15-12.37 22.66-32.54 34C247.13 238.53 216 254.94 216 296v4a12 12 0 0 0 12 12h56a12 12 0 0 0 12-12v-1.33c0-28.46 83.19-29.67 83.19-106.67 0-58-60.19-102-116.53-102z\"]]\n  };\n  var faQuoteLeft = {\n    prefix: 'fad',\n    iconName: 'quote-left',\n    icon: [512, 512, [], \"f10d\", [\"M464 256h-80v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H448a160 160 0 0 0-160 160v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\", \"M176 256H96v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H160A160 160 0 0 0 0 192v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\"]]\n  };\n  var faRandom = {\n    prefix: 'fad',\n    iconName: 'random',\n    icon: [512, 512, [], \"f074\", [\"M505 359l-80-80c-15-15-41-4.47-41 17v40h-32l-52.78-56.55-53.33 57.14 70.55 75.6a12 12 0 0 0 8.77 3.81H384v40c0 21.46 26 32 41 17l80-80a24 24 0 0 0 0-34zM122.79 96H12a12 12 0 0 0-12 12v56a12 12 0 0 0 12 12h84l52.78 56.55 53.33-57.14-70.55-75.6a12 12 0 0 0-8.77-3.81z\", \"M505 119a24 24 0 0 1 0 34l-80 80c-15 15-41 4.48-41-17v-40h-32L131.56 412.19a12 12 0 0 1-8.77 3.81H12a12 12 0 0 1-12-12v-56a12 12 0 0 1 12-12h84L316.44 99.81a12 12 0 0 1 8.78-3.81H384V56c0-21.44 25.94-32 41-17z\"]]\n  };\n  var faRocket = {\n    prefix: 'fad',\n    iconName: 'rocket',\n    icon: [512, 512, [], \"f135\", [\"M51.94117,154.48438,2.531,253.29688A28.125,28.125,0,0,0-.00023,264a24.00619,24.00619,0,0,0,24,24H117.4607c23.44141-47.41211,61.01172-123.373,77.89063-157.32812.51953-.91407,1-1.76758,1.52344-2.67188H94.82008C78.47633,128.01562,59.28883,139.875,51.94117,154.48438Zm172.0586,240.1621V488.209A24.12394,24.12394,0,0,0,247.9607,512a28.02965,28.02965,0,0,0,10.625-2.53125l98.72657-49.39063c14.625-7.3125,26.5-26.5,26.5-42.85937V315.70312c.0664-.041.125-.08789.1875-.1289v-.52734c-.90625.51953-1.7461,1.002-2.66407,1.52539C347.37477,333.58008,271.2732,371.252,223.99977,394.64648Z\", \"M505.15992,19.51562A16.73971,16.73971,0,0,0,492.62477,6.94531C460.22633,0,434.37477,0,409.48414,0,320.3357,0,252.80836,40.61523,196.97633,127.81836c-.5586.97852-1.07031,1.877-1.625,2.85352-19.59766,39.42578-67.20313,135.70312-88.04688,177.877a31.91421,31.91421,0,0,0,6.09766,36.76172L167.05445,398.709a31.88923,31.88923,0,0,0,36.64844,5.98047l14.17578-7.01367c46.57422-23.04883,128.06641-63.3789,163.457-81.10351.96094-.54883,1.832-1.04883,2.78907-1.59766,87.23437-56.06055,127.85937-123.51172,127.85937-212.27734C512.06227,77.60742,512.12867,52.08789,505.15992,19.51562ZM367.99977,192a48,48,0,1,1,48-48.00195A48.02156,48.02156,0,0,1,367.99977,192Z\"]]\n  };\n  var faSearch = {\n    prefix: 'fad',\n    iconName: 'search',\n    icon: [512, 512, [], \"f002\", [\"M208 80a128 128 0 1 1-90.51 37.49A127.15 127.15 0 0 1 208 80m0-80C93.12 0 0 93.12 0 208s93.12 208 208 208 208-93.12 208-208S322.88 0 208 0z\", \"M504.9 476.7L476.6 505a23.9 23.9 0 0 1-33.9 0L343 405.3a24 24 0 0 1-7-17V372l36-36h16.3a24 24 0 0 1 17 7l99.7 99.7a24.11 24.11 0 0 1-.1 34z\"]]\n  };\n  var faServer = {\n    prefix: 'fad',\n    iconName: 'server',\n    icon: [512, 512, [], \"f233\", [\"M432 120a24 24 0 1 0-24-24 24 24 0 0 0 24 24zm0 272a24 24 0 1 0 24 24 24 24 0 0 0-24-24zm48-200H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\", \"M456 256a24 24 0 1 0-24 24 24 24 0 0 0 24-24zm24-224H32A32 32 0 0 0 0 64v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm48 232H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\"]]\n  };\n  var faSignOut = {\n    prefix: 'fad',\n    iconName: 'sign-out',\n    icon: [512, 512, [], \"f08b\", [\"M180 448H96a96 96 0 0 1-96-96V160a96 96 0 0 1 96-96h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12H96a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12z\", \"M353 88.3l151.9 150.6a24 24 0 0 1 0 34.1l-152 150.8a24.08 24.08 0 0 1-33.9-.1l-21.9-21.9a24.07 24.07 0 0 1 .8-34.7l77.6-71.1H184a23.94 23.94 0 0 1-24-24v-32a23.94 23.94 0 0 1 24-24h191.5l-77.6-71.1a24 24 0 0 1-.7-34.6l21.9-21.9a24 24 0 0 1 33.9-.1z\"]]\n  };\n  var faSirenOn = {\n    prefix: 'fad',\n    iconName: 'siren-on',\n    icon: [640, 512, [], \"e02e\", [\"M224.21,134.94a8,8,0,0,1,9-6.87l15.86,2.13a8,8,0,0,1,6.87,9L231.82,320H496L471,120.06A64,64,0,0,0,407.5,64h-175A64,64,0,0,0,169,120.06L144,320h55.54Z\", \"M528,352H112a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16H528a16,16,0,0,0,16-16V368A16,16,0,0,0,528,352ZM112,192a24,24,0,0,0-24-24H24a24,24,0,0,0,0,48H88A24,24,0,0,0,112,192Zm504-24H552a24,24,0,0,0,0,48h64a24,24,0,0,0,0-48ZM90.69,76a24,24,0,1,0,26.62-39.92l-48-32A24,24,0,1,0,42.69,44ZM536,80a23.87,23.87,0,0,0,13.29-4l48-32A24,24,0,1,0,570.69,4.06l-48,32A24,24,0,0,0,536,80Z\"]]\n  };\n  var faSmile = {\n    prefix: 'fad',\n    iconName: 'smile',\n    icon: [496, 512, [], \"f118\", [\"M248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256,385,8,248,8Zm80,168a32,32,0,1,1-32,32A32,32,0,0,1,328,176Zm-160,0a32,32,0,1,1-32,32A32,32,0,0,1,168,176ZM362.8,346.2a149.38,149.38,0,0,1-229.6,0c-13.6-16.3,11-36.7,24.6-20.5a117.5,117.5,0,0,0,180.4,0C351.6,309.5,376.3,329.9,362.8,346.2Z\", \"M328,176a32,32,0,1,0,32,32A32,32,0,0,0,328,176Zm-160,0a32,32,0,1,0,32,32A32,32,0,0,0,168,176Z\"]]\n  };\n  var faSnowman = {\n    prefix: 'fad',\n    iconName: 'snowman',\n    icon: [512, 512, [], \"f7d0\", [\"M363.76 268.8a108.77 108.77 0 0 0 4.2-28.7v-.1a112.68 112.68 0 0 0-.73-12.8c-.11-1-.24-2-.38-3-.29-2-.62-4-1-6-.2-1-.4-1.95-.62-2.92-.22-1-.45-1.93-.7-2.9-.24-1-.5-1.91-.77-2.85-.27-.95-.55-1.89-.84-2.83-.3-.94-.6-1.87-.92-2.8-.32-.93-.65-1.86-1-2.77-.34-.92-.69-1.83-1.06-2.74-.36-.9-.74-1.8-1.13-2.7-.39-.89-.79-1.78-1.19-2.66-.41-.88-.83-1.76-1.26-2.63q-1.31-2.62-2.73-5.16c-.48-.85-1-1.68-1.46-2.51a112.44 112.44 0 0 0-21.62-26.19 96 96 0 1 0-149.16 0 112.49 112.49 0 0 0-21.68 26.28q-.74 1.23-1.44 2.49c-.48.84-.94 1.69-1.39 2.54-.45.85-.89 1.7-1.32 2.57-.43.87-.85 1.74-1.25 2.62-.41.88-.8 1.76-1.19 2.66-.39.89-.76 1.79-1.12 2.69-.36.91-.71 1.82-1.05 2.74-.34.92-.67 1.84-1 2.76a111.63 111.63 0 0 0-5.22 23.28A113 113 0 0 0 144 240h.06v.1a110.27 110.27 0 0 0 4.2 28.9A151.18 151.18 0 0 0 104 376.1c0 54 28.4 100.9 70.8 127.8 9.3 5.9 20.3 8.2 31.3 8.2h99.2a65.1 65.1 0 0 0 37.2-11.7c46.5-32.3 74.4-89.4 62.9-152.6-5.54-30.2-20.54-57.6-41.64-79zM224 96.1a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm32 272a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm0-64a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm1.7-64.1a15.19 15.19 0 0 1-3.48 0 16 16 0 1 1 3.48 0zm-1.7-87.9s-16-23.2-16-32a16 16 0 1 1 32 0c0 8.8-16 32-16 32zm32-56a16 16 0 1 1 16-16 16 16 0 0 1-16 16z\", \"M510.86 152.4L505 137.9a16.15 16.15 0 0 0-20.8-8.7L456 140.7v-29a15.84 15.84 0 0 0-16-15.6h-16a15.84 15.84 0 0 0-16 15.6v46.9c0 .5.3 1 .3 1.5l-56.1 22.54a111.21 111.21 0 0 1 15.07 44.56L502 172.7a15.57 15.57 0 0 0 8.86-20.3zm-407.1 6.2v-46.9c.2-8.6-7-15.6-15.8-15.6H72a15.84 15.84 0 0 0-16 15.6v29l-28.1-11.5a16.15 16.15 0 0 0-20.8 8.7l-5.9 14.5a15.48 15.48 0 0 0 8.9 20.3l134.67 54.49a111.3 111.3 0 0 1 15-44.46l-56.31-22.63a8 8 0 0 0 .3-1.5zM256 336.1a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16z\"]]\n  };\n  var faSun = {\n    prefix: 'fad',\n    iconName: 'sun',\n    icon: [512, 512, [], \"f185\", [\"M502.42 240.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.41-94.8a17.31 17.31 0 0 0-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4a17.31 17.31 0 0 0 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.41-33.5 47.3 94.7a17.31 17.31 0 0 0 31 0l47.31-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3a17.33 17.33 0 0 0 .2-31.1zm-155.9 106c-49.91 49.9-131.11 49.9-181 0a128.13 128.13 0 0 1 0-181c49.9-49.9 131.1-49.9 181 0a128.13 128.13 0 0 1 0 181z\", \"M352 256a96 96 0 1 1-96-96 96.15 96.15 0 0 1 96 96z\"]]\n  };\n  var faTasks = {\n    prefix: 'fad',\n    iconName: 'tasks',\n    icon: [512, 512, [], \"f0ae\", [\"M496 384H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\", \"M139.61 35.5a12 12 0 0 0-17 0L58.93 98.81l-22.7-22.12a12 12 0 0 0-17 0L3.53 92.41a12 12 0 0 0 0 17l47.59 47.4a12.78 12.78 0 0 0 17.61 0l15.59-15.62L156.52 69a12.09 12.09 0 0 0 .09-17zm0 159.19a12 12 0 0 0-17 0l-63.68 63.72-22.7-22.1a12 12 0 0 0-17 0L3.53 252a12 12 0 0 0 0 17L51 316.5a12.77 12.77 0 0 0 17.6 0l15.7-15.69 72.2-72.22a12 12 0 0 0 .09-16.9zM64 368c-26.49 0-48.59 21.5-48.59 48S37.53 464 64 464a48 48 0 0 0 0-96z\"]]\n  };\n  var faUniversity = {\n    prefix: 'fad',\n    iconName: 'university',\n    icon: [512, 512, [], \"f19c\", [\"M160,192V384h64V192h64V384h64V192h64V384h36a12,12,0,0,1,12,12v20H48V396a12,12,0,0,1,12-12H96V192Z\", \"M491.06,120.61l-232-88a8,8,0,0,0-6.12,0l-232,88A8,8,0,0,0,16,128v16a8,8,0,0,0,8,8H48v12a12,12,0,0,0,12,12H452a12,12,0,0,0,12-12V152h24a8,8,0,0,0,8-8V128A8,8,0,0,0,491.06,120.61ZM472,432H40a24,24,0,0,0-24,24v16a8,8,0,0,0,8,8H488a8,8,0,0,0,8-8V456A24,24,0,0,0,472,432Z\"]]\n  };\n  var faUser = {\n    prefix: 'fad',\n    iconName: 'user',\n    icon: [448, 512, [], \"f007\", [\"M352 128A128 128 0 1 1 224 0a128 128 0 0 1 128 128z\", \"M313.6 288h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48v-41.6A134.43 134.43 0 0 0 313.6 288z\"]]\n  };\n  var faUserHardHat = {\n    prefix: 'fad',\n    iconName: 'user-hard-hat',\n    icon: [448, 512, [], \"f82c\", [\"M97.61 208h252.78c-7.95 63.06-61.17 112-126.39 112S105.56 271.06 97.61 208z\", \"M313.6 352h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.4 134.4 0 0 0 0 486.4 25.6 25.6 0 0 0 25.6 512h396.8a25.6 25.6 0 0 0 25.6-25.6A134.4 134.4 0 0 0 313.6 352zM88 176h272a8 8 0 0 0 8-8v-32a8 8 0 0 0-8-8h-8a112 112 0 0 0-68.4-103.2L256 80V16a16 16 0 0 0-16-16h-32a16 16 0 0 0-16 16v64l-27.6-55.2A112 112 0 0 0 96 128h-8a8 8 0 0 0-8 8v32a8 8 0 0 0 8 8z\"]]\n  };\n  var faUserShield = {\n    prefix: 'fad',\n    iconName: 'user-shield',\n    icon: [640, 512, [], \"f505\", [\"M622.3 271.1l-115.2-45a31 31 0 0 0-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9a31 31 0 0 0 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8z\", \"M224 256A128 128 0 1 0 96 128a128 128 0 0 0 128 128zm96 40c0-2.5.8-4.8 1.1-7.2-2.5-.1-4.9-.8-7.5-.8h-16.7a174.08 174.08 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a49.22 49.22 0 0 0 19.2-4c-54-42.9-99.2-116.7-99.2-212z\"]]\n  };\n  var faUsers = {\n    prefix: 'fad',\n    iconName: 'users',\n    icon: [640, 512, [], \"f0c0\", [\"M96 224a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64zm480 32h-64a63.81 63.81 0 0 0-45.1 18.6A146.27 146.27 0 0 1 542 384h66a32 32 0 0 0 32-32v-32a64.06 64.06 0 0 0-64-64zm-512 0a64.06 64.06 0 0 0-64 64v32a32 32 0 0 0 32 32h65.9a146.64 146.64 0 0 1 75.2-109.4A63.81 63.81 0 0 0 128 256zm480-32a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64z\", \"M396.8 288h-8.3a157.53 157.53 0 0 1-68.5 16c-24.6 0-47.6-6-68.5-16h-8.3A115.23 115.23 0 0 0 128 403.2V432a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48v-28.8A115.23 115.23 0 0 0 396.8 288zM320 256a112 112 0 1 0-112-112 111.94 111.94 0 0 0 112 112z\"]]\n  };\n  var _iconsCache = {\n    faAbacus: faAbacus,\n    faAlignSlash: faAlignSlash,\n    faAtomAlt: faAtomAlt,\n    faBadgeCheck: faBadgeCheck,\n    faBell: faBell,\n    faBooks: faBooks,\n    faBracketsCurly: faBracketsCurly,\n    faChartNetwork: faChartNetwork,\n    faChartScatter: faChartScatter,\n    faCheck: faCheck,\n    faCircle: faCircle,\n    faClouds: faClouds,\n    faCogs: faCogs,\n    faCommentDots: faCommentDots,\n    faConciergeBell: faConciergeBell,\n    faDotCircle: faDotCircle,\n    faEnvelope: faEnvelope,\n    faExchangeAlt: faExchangeAlt,\n    faFileAlt: faFileAlt,\n    faFileCode: faFileCode,\n    faGlobe: faGlobe,\n    faGlobeAfrica: faGlobeAfrica,\n    faGlobeAmericas: faGlobeAmericas,\n    faGlobeAsia: faGlobeAsia,\n    faGlobeEurope: faGlobeEurope,\n    faGraduationCap: faGraduationCap,\n    faHistory: faHistory,\n    faKey: faKey,\n    faKeySkeleton: faKeySkeleton,\n    faLaptop: faLaptop,\n    faLaptopCode: faLaptopCode,\n    faLaptopHouse: faLaptopHouse,\n    faLifeRing: faLifeRing,\n    faLightbulb: faLightbulb,\n    faListAlt: faListAlt,\n    faListUl: faListUl,\n    faLockAlt: faLockAlt,\n    faMapMarkerAlt: faMapMarkerAlt,\n    faMoonStars: faMoonStars,\n    faNetworkWired: faNetworkWired,\n    faPlanetRinged: faPlanetRinged,\n    faQuestionCircle: faQuestionCircle,\n    faQuoteLeft: faQuoteLeft,\n    faRandom: faRandom,\n    faRocket: faRocket,\n    faSearch: faSearch,\n    faServer: faServer,\n    faSignOut: faSignOut,\n    faSirenOn: faSirenOn,\n    faSmile: faSmile,\n    faSnowman: faSnowman,\n    faSun: faSun,\n    faTasks: faTasks,\n    faUniversity: faUniversity,\n    faUser: faUser,\n    faUserHardHat: faUserHardHat,\n    faUserShield: faUserShield,\n    faUsers: faUsers\n  };\n\n  exports.fad = _iconsCache;\n  exports.prefix = prefix;\n  exports.faAbacus = faAbacus;\n  exports.faAlignSlash = faAlignSlash;\n  exports.faAtomAlt = faAtomAlt;\n  exports.faBadgeCheck = faBadgeCheck;\n  exports.faBell = faBell;\n  exports.faBooks = faBooks;\n  exports.faBracketsCurly = faBracketsCurly;\n  exports.faChartNetwork = faChartNetwork;\n  exports.faChartScatter = faChartScatter;\n  exports.faCheck = faCheck;\n  exports.faCircle = faCircle;\n  exports.faClouds = faClouds;\n  exports.faCogs = faCogs;\n  exports.faCommentDots = faCommentDots;\n  exports.faConciergeBell = faConciergeBell;\n  exports.faDotCircle = faDotCircle;\n  exports.faEnvelope = faEnvelope;\n  exports.faExchangeAlt = faExchangeAlt;\n  exports.faFileAlt = faFileAlt;\n  exports.faFileCode = faFileCode;\n  exports.faGlobe = faGlobe;\n  exports.faGlobeAfrica = faGlobeAfrica;\n  exports.faGlobeAmericas = faGlobeAmericas;\n  exports.faGlobeAsia = faGlobeAsia;\n  exports.faGlobeEurope = faGlobeEurope;\n  exports.faGraduationCap = faGraduationCap;\n  exports.faHistory = faHistory;\n  exports.faKey = faKey;\n  exports.faKeySkeleton = faKeySkeleton;\n  exports.faLaptop = faLaptop;\n  exports.faLaptopCode = faLaptopCode;\n  exports.faLaptopHouse = faLaptopHouse;\n  exports.faLifeRing = faLifeRing;\n  exports.faLightbulb = faLightbulb;\n  exports.faListAlt = faListAlt;\n  exports.faListUl = faListUl;\n  exports.faLockAlt = faLockAlt;\n  exports.faMapMarkerAlt = faMapMarkerAlt;\n  exports.faMoonStars = faMoonStars;\n  exports.faNetworkWired = faNetworkWired;\n  exports.faPlanetRinged = faPlanetRinged;\n  exports.faQuestionCircle = faQuestionCircle;\n  exports.faQuoteLeft = faQuoteLeft;\n  exports.faRandom = faRandom;\n  exports.faRocket = faRocket;\n  exports.faSearch = faSearch;\n  exports.faServer = faServer;\n  exports.faSignOut = faSignOut;\n  exports.faSirenOn = faSirenOn;\n  exports.faSmile = faSmile;\n  exports.faSnowman = faSnowman;\n  exports.faSun = faSun;\n  exports.faTasks = faTasks;\n  exports.faUniversity = faUniversity;\n  exports.faUser = faUser;\n  exports.faUserHardHat = faUserHardHat;\n  exports.faUserShield = faUserShield;\n  exports.faUsers = faUsers;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-duotone-svg-icons/package.json",
    "content": "{\n  \"description\": \"The iconic font, CSS, and SVG framework\",\n  \"keywords\": [\n    \"font\",\n    \"awesome\",\n    \"fontawesome\",\n    \"icon\",\n    \"svg\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://fontawesome.com\",\n  \"bugs\": {\n    \"url\": \"http://github.com/FortAwesome/Font-Awesome/issues\"\n  },\n  \"author\": {\n    \"name\": \"Dave Gandy\",\n    \"email\": \"dave@fontawesome.com\",\n    \"web\": \"http://twitter.com/davegandy\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Brian Talbot\",\n      \"web\": \"http://twitter.com/talbs\"\n    },\n    {\n      \"name\": \"Travis Chase\",\n      \"web\": \"http://twitter.com/supercodepoet\"\n    },\n    {\n      \"name\": \"Rob Madole\",\n      \"web\": \"http://twitter.com/robmadole\"\n    },\n    {\n      \"name\": \"Geremia Taglialatela\",\n      \"web\": \"http://twitter.com/gtagliala\"\n    },\n    {\n      \"name\": \"Mike Wilkerson\",\n      \"web\": \"http://twitter.com/mw77\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/FortAwesome/Font-Awesome\"\n  },\n  \"engines\": {\n    \"node\": \">=6\"\n  },\n  \"dependencies\": {\n    \"@fortawesome/fontawesome-common-types\": \"^0.2.36\"\n  },\n  \"version\": \"5.15.4\",\n  \"name\": \"@fortawesome/pro-duotone-svg-icons\",\n  \"main\": \"index.js\",\n  \"module\": \"index.es.js\",\n  \"jsnext:main\": \"index.es.js\",\n  \"license\": \"UNLICENSED\",\n  \"types\": \"./index.d.ts\",\n  \"sideEffects\": false,\n  \"scripts\": {\n    \"postinstall\": \"node attribution.js\"\n  }\n}"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/LICENSE.txt",
    "content": "Font Awesome Pro License\n------------------------\n\nFont Awesome Pro is commercial software that requires a paid license. Full\nFont Awesome Pro license: https://fontawesome.com/license.\n\n# Commercial License\nThe Font Awesome Pro commercial license allows you to pay for FA Pro once, own\nit, and use it just about everywhere you'd like.\n\n# Attribution\nAttribution is not required by the Font Awesome Pro commercial license.\n\n# Brand Icons\nAll brand icons are trademarks of their respective owners. The use of these\ntrademarks does not indicate endorsement of the trademark holder by Font\nAwesome, nor vice versa. **Please do not use brand logos for any purpose except\nto represent the company, product, or service to which they refer.**\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/README.md",
    "content": "# @fortawesome/pro-regular-svg-icons - SVG with JavaScript version\n\n> \"I came here to chew bubblegum and install Font Awesome 5 - and I'm all out of bubblegum\"\n\n[![npm](https://img.shields.io/npm/v/@fortawesome/pro-regular-svg-icons.svg?style=flat-square)](https://www.npmjs.com/package/@fortawesome/pro-regular-svg-icons)\n\n## Installation\n\n```\n$ npm i --save @fortawesome/pro-regular-svg-icons\n```\n\nOr\n\n```\n$ yarn add @fortawesome/pro-regular-svg-icons\n```\n\n## Documentation\n\nGet started [here](https://fontawesome.com/how-to-use/on-the-web/setup/getting-started). Continue your journey [here](https://fontawesome.com/how-to-use/on-the-web/advanced).\n\nOr go straight to the [API documentation](https://fontawesome.com/how-to-use/with-the-api).\n\n## Issues and support\n\nStart with [GitHub issues](https://github.com/FortAwesome/Font-Awesome/issues) and ping us on [Twitter](https://twitter.com/fontawesome) if you need to.\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/attribution.js",
    "content": "console.log(`Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\nLicense - https://fontawesome.com/license (Commercial License)\n`)"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faCheckCircle.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCheckCircle: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faCheckCircle.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'check-circle';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f058';\nvar svgPathData = 'M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCheckCircle = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faDesktop.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faDesktop: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faDesktop.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'desktop';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f108';\nvar svgPathData = 'M528 0H48C21.5 0 0 21.5 0 48v288c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V54c0-3.3 2.7-6 6-6h468c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-42 152c0 13.3-10.7 24-24 24H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h98.7l18.6-55.8c1.6-4.9 6.2-8.2 11.4-8.2h78.7c5.2 0 9.8 3.3 11.4 8.2l18.6 55.8H456c13.3 0 24 10.7 24 24z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faDesktop = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faEye.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faEye: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faEye.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'eye';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f06e';\nvar svgPathData = 'M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faEye = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faFileCode.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faFileCode: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faFileCode.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'file-code';\nvar width = 384;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1c9';\nvar svgPathData = 'M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faFileCode = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faInfo.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faInfo: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faInfo.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'info';\nvar width = 256;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f129';\nvar svgPathData = 'M224 352.589V224c0-16.475-6.258-31.517-16.521-42.872C225.905 161.14 236 135.346 236 108 236 48.313 187.697 0 128 0 68.313 0 20 48.303 20 108c0 20.882 5.886 40.859 16.874 58.037C15.107 176.264 0 198.401 0 224v39.314c0 23.641 12.884 44.329 32 55.411v33.864C12.884 363.671 0 384.359 0 408v40c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-40c0-23.641-12.884-44.329-32-55.411zM128 48c33.137 0 60 26.863 60 60s-26.863 60-60 60-60-26.863-60-60 26.863-60 60-60zm80 400c0 8.836-7.164 16-16 16H64c-8.836 0-16-7.164-16-16v-40c0-8.836 7.164-16 16-16h16V279.314H64c-8.836 0-16-7.164-16-16V224c0-8.836 7.164-16 16-16h96c8.836 0 16 7.164 16 16v168h16c8.836 0 16 7.164 16 16v40z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faInfo = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faInfoCircle.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faInfoCircle: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faInfoCircle.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'info-circle';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f05a';\nvar svgPathData = 'M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm0-338c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faInfoCircle = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faPlus.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faPlus: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faPlus.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'plus';\nvar width = 384;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f067';\nvar svgPathData = 'M368 224H224V80c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h144v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V288h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faPlus = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faQuestionCircle.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faQuestionCircle: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faQuestionCircle.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'question-circle';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f059';\nvar svgPathData = 'M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faQuestionCircle = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faRocket.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faRocket: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faRocket.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'rocket';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f135';\nvar svgPathData = 'M367.96813,103.99609a39.999,39.999,0,1,0,40.00384,40A40.02908,40.02908,0,0,0,367.96813,103.99609ZM505.07337,19.3418c-1.21875-5.60742-6.75-11.13868-12.34373-12.3418-32.62885-7-58.162-7-83.57017-7C305.39988,0,242.95858,55.0918,196.236,127.99609H94.82015c-16.34567.01563-35.53314,11.875-42.87883,26.48243L2.53125,253.28906A28.12512,28.12512,0,0,0,0,263.99219a24.00617,24.00617,0,0,0,24.00191,23.998h92.63266l-10.59373,21.42188c-9.33592,18.91016,4.27733,34.77344,6.15624,36.62305l53.75381,53.71875c15.56443,15.54492,33.81635,7.52929,36.6601,6.13867l21.34567-10.57617V488a24.00659,24.00659,0,0,0,24.00191,24,28.618,28.618,0,0,0,10.71873-2.51562l98.6971-49.4043c14.625-7.29688,26.50191-26.5,26.50191-42.85938V315.69336c72.72449-46.76367,128.10525-109.44922,128.10525-212.69727C512.07531,77.4668,512.07531,51.99805,505.07337,19.3418ZM358.53065,274.99023c-36.94135,18.48438-121.10527,60.14063-166.7966,82.73243l-37.50189-37.49805c22.59567-45.6875,64.25575-129.99609,82.72447-166.88672C284.33741,79.5293,335.96623,47.99805,409.15947,47.99805c18.00192,0,34.2851,0,52.56632,2.34375,2.375,18.71875,2.31249,35.27929,2.25,52.63867C463.97578,175.75977,432.41138,227.30469,358.53065,274.99023Z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faRocket = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faSave.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSave: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faSave.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'save';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0c7';\nvar svgPathData = 'M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSave = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faSlash.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSlash: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faSlash.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'slash';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f715';\nvar svgPathData = 'M604 508.49L6.01 40.98c-6.9-5.52-8.02-15.59-2.49-22.49L13.51 6C19.03-.9 29.1-2.01 36 3.51l598 467.51c6.9 5.52 8.02 15.59 2.49 22.49l-10 12.49c-5.52 6.9-15.59 8.01-22.49 2.49z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSlash = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faTimes.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faTimes: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faTimes.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'times';\nvar width = 320;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f00d';\nvar svgPathData = 'M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faTimes = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faUndo.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUndo: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faUndo.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'undo';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0e2';\nvar svgPathData = 'M12 8h27.711c6.739 0 12.157 5.548 11.997 12.286l-2.347 98.568C93.925 51.834 170.212 7.73 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.835 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.322 0 196-87.662 196-196 0-108.322-87.662-196-196-196-79.545 0-147.941 47.282-178.675 115.302l126.389-3.009c6.737-.16 12.286 5.257 12.286 11.997V212c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V20C0 13.373 5.373 8 12 8z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUndo = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faUndoAlt.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUndoAlt: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faUndoAlt.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'undo-alt';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f2ea';\nvar svgPathData = 'M28.485 28.485L80.65 80.65C125.525 35.767 187.515 8 255.999 8 392.66 8 504.1 119.525 504 256.185 503.9 393.067 392.905 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.353-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.321 0 196-87.662 196-196 0-108.321-87.662-196-196-196-54.163 0-103.157 21.923-138.614 57.386l54.128 54.129c7.56 7.56 2.206 20.485-8.485 20.485H20c-6.627 0-12-5.373-12-12V36.971c0-10.691 12.926-16.045 20.485-8.486z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUndoAlt = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faUser.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUser: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faUser.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'user';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f007';\nvar svgPathData = 'M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUser = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faUserFriends.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUserFriends: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faUserFriends.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'user-friends';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f500';\nvar svgPathData = 'M480 256c53 0 96-43 96-96s-43-96-96-96-96 43-96 96 43 96 96 96zm0-144c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM272.1 276c-11.9 0-23.9 1.7-35.5 5.3-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-11.6-3.5-23.6-5.3-35.5-5.3-36.3 0-71.6 16.2-92.3 46.9C7.2 341.3 0 363.4 0 387.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM336 432H48v-44.8c0-28.9 18.4-53.6 44.1-63.1 10.3-3.8 21.6-3.7 31.9 0 22.1 7.9 45 11.9 68 11.9s45.8-4 68.1-11.9c10.3-3.7 21.6-3.8 31.9 0 25.7 9.4 44.1 34.2 44.1 63.1V432zM192 256c61.9 0 112-50.1 112-112S253.9 32 192 32 80 82.1 80 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm431.7 237.1C606.4 291.5 577 278 546.8 278c-27.8 0-34.8 10-66.8 10s-39-10-66.8-10c-13.3 0-26.2 3-38.2 8.1 5.8 5.9 11.3 12 16 18.9 4.7 7 8.6 14.4 12 22 3.3-.7 6.7-1.1 10.2-1.1 17.2 0 29.6 10 66.8 10 37.4 0 49.5-10 66.8-10 15.7 0 29.5 6.7 37.1 17.9 5.3 7.9 8.1 17.1 8.1 26.7V400H416v32c0 5.5-.6 10.8-1.6 16H600c22.1 0 40-17.9 40-40v-37.3c0-19.9-6-38.3-16.3-53.6z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUserFriends = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faUsers.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUsers: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/faUsers.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'far';\nvar iconName = 'users';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0c0';\nvar svgPathData = 'M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zm396.4 210.9c-27.5-40.8-80.7-56-127.8-41.7-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-47.1-14.3-100.3.8-127.8 41.7-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c.2-23.8-7-45.9-19.4-64.3zM464 432H176v-44.8c0-36.4 29.2-66.2 65.4-67.2 25.5 10.6 51.9 16 78.6 16 26.7 0 53.1-5.4 78.6-16 36.2 1 65.4 30.7 65.4 67.2V432zm92-176h-24c-17.3 0-33.4 5.3-46.8 14.3 13.4 10.1 25.2 22.2 34.4 36.2 3.9-1.4 8-2.5 12.3-2.5h24c19.8 0 36 16.2 36 36 0 13.2 10.8 24 24 24s24-10.8 24-24c.1-46.3-37.6-84-83.9-84zm-236 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM154.8 270.3c-13.4-9-29.5-14.3-46.8-14.3H84c-46.3 0-84 37.7-84 84 0 13.2 10.8 24 24 24s24-10.8 24-24c0-19.8 16.2-36 36-36h24c4.4 0 8.5 1.1 12.3 2.5 9.3-14 21.1-26.1 34.5-36.2z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUsers = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/index.d.ts",
    "content": "export const faCheckCircle: IconDefinition;\nexport const faDesktop: IconDefinition;\nexport const faEye: IconDefinition;\nexport const faFileCode: IconDefinition;\nexport const faInfo: IconDefinition;\nexport const faInfoCircle: IconDefinition;\nexport const faPlus: IconDefinition;\nexport const faQuestionCircle: IconDefinition;\nexport const faRocket: IconDefinition;\nexport const faSave: IconDefinition;\nexport const faSlash: IconDefinition;\nexport const faTimes: IconDefinition;\nexport const faUndo: IconDefinition;\nexport const faUndoAlt: IconDefinition;\nexport const faUser: IconDefinition;\nexport const faUserFriends: IconDefinition;\nexport const faUsers: IconDefinition;\nimport { IconDefinition, IconLookup, IconName, IconPrefix, IconPack } from '@fortawesome/fontawesome-common-types';\nexport { IconDefinition, IconLookup, IconName, IconPrefix, IconPack } from '@fortawesome/fontawesome-common-types';\nexport const prefix: IconPrefix;\nexport const far: IconPack;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/index.es.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\nvar prefix = \"far\";\nvar faCheckCircle = {\n  prefix: 'far',\n  iconName: 'check-circle',\n  icon: [512, 512, [], \"f058\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z\"]\n};\nvar faDesktop = {\n  prefix: 'far',\n  iconName: 'desktop',\n  icon: [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v288c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V54c0-3.3 2.7-6 6-6h468c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-42 152c0 13.3-10.7 24-24 24H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h98.7l18.6-55.8c1.6-4.9 6.2-8.2 11.4-8.2h78.7c5.2 0 9.8 3.3 11.4 8.2l18.6 55.8H456c13.3 0 24 10.7 24 24z\"]\n};\nvar faEye = {\n  prefix: 'far',\n  iconName: 'eye',\n  icon: [576, 512, [], \"f06e\", \"M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z\"]\n};\nvar faFileCode = {\n  prefix: 'far',\n  iconName: 'file-code',\n  icon: [384, 512, [], \"f1c9\", \"M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z\"]\n};\nvar faInfo = {\n  prefix: 'far',\n  iconName: 'info',\n  icon: [256, 512, [], \"f129\", \"M224 352.589V224c0-16.475-6.258-31.517-16.521-42.872C225.905 161.14 236 135.346 236 108 236 48.313 187.697 0 128 0 68.313 0 20 48.303 20 108c0 20.882 5.886 40.859 16.874 58.037C15.107 176.264 0 198.401 0 224v39.314c0 23.641 12.884 44.329 32 55.411v33.864C12.884 363.671 0 384.359 0 408v40c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-40c0-23.641-12.884-44.329-32-55.411zM128 48c33.137 0 60 26.863 60 60s-26.863 60-60 60-60-26.863-60-60 26.863-60 60-60zm80 400c0 8.836-7.164 16-16 16H64c-8.836 0-16-7.164-16-16v-40c0-8.836 7.164-16 16-16h16V279.314H64c-8.836 0-16-7.164-16-16V224c0-8.836 7.164-16 16-16h96c8.836 0 16 7.164 16 16v168h16c8.836 0 16 7.164 16 16v40z\"]\n};\nvar faInfoCircle = {\n  prefix: 'far',\n  iconName: 'info-circle',\n  icon: [512, 512, [], \"f05a\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm0-338c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"]\n};\nvar faPlus = {\n  prefix: 'far',\n  iconName: 'plus',\n  icon: [384, 512, [], \"f067\", \"M368 224H224V80c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h144v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V288h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"]\n};\nvar faQuestionCircle = {\n  prefix: 'far',\n  iconName: 'question-circle',\n  icon: [512, 512, [], \"f059\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z\"]\n};\nvar faRocket = {\n  prefix: 'far',\n  iconName: 'rocket',\n  icon: [512, 512, [], \"f135\", \"M367.96813,103.99609a39.999,39.999,0,1,0,40.00384,40A40.02908,40.02908,0,0,0,367.96813,103.99609ZM505.07337,19.3418c-1.21875-5.60742-6.75-11.13868-12.34373-12.3418-32.62885-7-58.162-7-83.57017-7C305.39988,0,242.95858,55.0918,196.236,127.99609H94.82015c-16.34567.01563-35.53314,11.875-42.87883,26.48243L2.53125,253.28906A28.12512,28.12512,0,0,0,0,263.99219a24.00617,24.00617,0,0,0,24.00191,23.998h92.63266l-10.59373,21.42188c-9.33592,18.91016,4.27733,34.77344,6.15624,36.62305l53.75381,53.71875c15.56443,15.54492,33.81635,7.52929,36.6601,6.13867l21.34567-10.57617V488a24.00659,24.00659,0,0,0,24.00191,24,28.618,28.618,0,0,0,10.71873-2.51562l98.6971-49.4043c14.625-7.29688,26.50191-26.5,26.50191-42.85938V315.69336c72.72449-46.76367,128.10525-109.44922,128.10525-212.69727C512.07531,77.4668,512.07531,51.99805,505.07337,19.3418ZM358.53065,274.99023c-36.94135,18.48438-121.10527,60.14063-166.7966,82.73243l-37.50189-37.49805c22.59567-45.6875,64.25575-129.99609,82.72447-166.88672C284.33741,79.5293,335.96623,47.99805,409.15947,47.99805c18.00192,0,34.2851,0,52.56632,2.34375,2.375,18.71875,2.31249,35.27929,2.25,52.63867C463.97578,175.75977,432.41138,227.30469,358.53065,274.99023Z\"]\n};\nvar faSave = {\n  prefix: 'far',\n  iconName: 'save',\n  icon: [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z\"]\n};\nvar faSlash = {\n  prefix: 'far',\n  iconName: 'slash',\n  icon: [640, 512, [], \"f715\", \"M604 508.49L6.01 40.98c-6.9-5.52-8.02-15.59-2.49-22.49L13.51 6C19.03-.9 29.1-2.01 36 3.51l598 467.51c6.9 5.52 8.02 15.59 2.49 22.49l-10 12.49c-5.52 6.9-15.59 8.01-22.49 2.49z\"]\n};\nvar faTimes = {\n  prefix: 'far',\n  iconName: 'times',\n  icon: [320, 512, [], \"f00d\", \"M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z\"]\n};\nvar faUndo = {\n  prefix: 'far',\n  iconName: 'undo',\n  icon: [512, 512, [], \"f0e2\", \"M12 8h27.711c6.739 0 12.157 5.548 11.997 12.286l-2.347 98.568C93.925 51.834 170.212 7.73 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.835 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.322 0 196-87.662 196-196 0-108.322-87.662-196-196-196-79.545 0-147.941 47.282-178.675 115.302l126.389-3.009c6.737-.16 12.286 5.257 12.286 11.997V212c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V20C0 13.373 5.373 8 12 8z\"]\n};\nvar faUndoAlt = {\n  prefix: 'far',\n  iconName: 'undo-alt',\n  icon: [512, 512, [], \"f2ea\", \"M28.485 28.485L80.65 80.65C125.525 35.767 187.515 8 255.999 8 392.66 8 504.1 119.525 504 256.185 503.9 393.067 392.905 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.353-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.321 0 196-87.662 196-196 0-108.321-87.662-196-196-196-54.163 0-103.157 21.923-138.614 57.386l54.128 54.129c7.56 7.56 2.206 20.485-8.485 20.485H20c-6.627 0-12-5.373-12-12V36.971c0-10.691 12.926-16.045 20.485-8.486z\"]\n};\nvar faUser = {\n  prefix: 'far',\n  iconName: 'user',\n  icon: [448, 512, [], \"f007\", \"M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z\"]\n};\nvar faUserFriends = {\n  prefix: 'far',\n  iconName: 'user-friends',\n  icon: [640, 512, [], \"f500\", \"M480 256c53 0 96-43 96-96s-43-96-96-96-96 43-96 96 43 96 96 96zm0-144c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM272.1 276c-11.9 0-23.9 1.7-35.5 5.3-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-11.6-3.5-23.6-5.3-35.5-5.3-36.3 0-71.6 16.2-92.3 46.9C7.2 341.3 0 363.4 0 387.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM336 432H48v-44.8c0-28.9 18.4-53.6 44.1-63.1 10.3-3.8 21.6-3.7 31.9 0 22.1 7.9 45 11.9 68 11.9s45.8-4 68.1-11.9c10.3-3.7 21.6-3.8 31.9 0 25.7 9.4 44.1 34.2 44.1 63.1V432zM192 256c61.9 0 112-50.1 112-112S253.9 32 192 32 80 82.1 80 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm431.7 237.1C606.4 291.5 577 278 546.8 278c-27.8 0-34.8 10-66.8 10s-39-10-66.8-10c-13.3 0-26.2 3-38.2 8.1 5.8 5.9 11.3 12 16 18.9 4.7 7 8.6 14.4 12 22 3.3-.7 6.7-1.1 10.2-1.1 17.2 0 29.6 10 66.8 10 37.4 0 49.5-10 66.8-10 15.7 0 29.5 6.7 37.1 17.9 5.3 7.9 8.1 17.1 8.1 26.7V400H416v32c0 5.5-.6 10.8-1.6 16H600c22.1 0 40-17.9 40-40v-37.3c0-19.9-6-38.3-16.3-53.6z\"]\n};\nvar faUsers = {\n  prefix: 'far',\n  iconName: 'users',\n  icon: [640, 512, [], \"f0c0\", \"M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zm396.4 210.9c-27.5-40.8-80.7-56-127.8-41.7-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-47.1-14.3-100.3.8-127.8 41.7-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c.2-23.8-7-45.9-19.4-64.3zM464 432H176v-44.8c0-36.4 29.2-66.2 65.4-67.2 25.5 10.6 51.9 16 78.6 16 26.7 0 53.1-5.4 78.6-16 36.2 1 65.4 30.7 65.4 67.2V432zm92-176h-24c-17.3 0-33.4 5.3-46.8 14.3 13.4 10.1 25.2 22.2 34.4 36.2 3.9-1.4 8-2.5 12.3-2.5h24c19.8 0 36 16.2 36 36 0 13.2 10.8 24 24 24s24-10.8 24-24c.1-46.3-37.6-84-83.9-84zm-236 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM154.8 270.3c-13.4-9-29.5-14.3-46.8-14.3H84c-46.3 0-84 37.7-84 84 0 13.2 10.8 24 24 24s24-10.8 24-24c0-19.8 16.2-36 36-36h24c4.4 0 8.5 1.1 12.3 2.5 9.3-14 21.1-26.1 34.5-36.2z\"]\n};\nvar _iconsCache = {\n  faCheckCircle: faCheckCircle,\n  faDesktop: faDesktop,\n  faEye: faEye,\n  faFileCode: faFileCode,\n  faInfo: faInfo,\n  faInfoCircle: faInfoCircle,\n  faPlus: faPlus,\n  faQuestionCircle: faQuestionCircle,\n  faRocket: faRocket,\n  faSave: faSave,\n  faSlash: faSlash,\n  faTimes: faTimes,\n  faUndo: faUndo,\n  faUndoAlt: faUndoAlt,\n  faUser: faUser,\n  faUserFriends: faUserFriends,\n  faUsers: faUsers\n};\n\nexport { _iconsCache as far, prefix, faCheckCircle, faDesktop, faEye, faFileCode, faInfo, faInfoCircle, faPlus, faQuestionCircle, faRocket, faSave, faSlash, faTimes, faUndo, faUndoAlt, faUser, faUserFriends, faUsers };\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/index.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (factory((global['pro-regular-svg-icons'] = {})));\n}(this, (function (exports) { 'use strict';\n\n  var prefix = \"far\";\n  var faCheckCircle = {\n    prefix: 'far',\n    iconName: 'check-circle',\n    icon: [512, 512, [], \"f058\", \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z\"]\n  };\n  var faDesktop = {\n    prefix: 'far',\n    iconName: 'desktop',\n    icon: [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v288c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V54c0-3.3 2.7-6 6-6h468c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-42 152c0 13.3-10.7 24-24 24H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h98.7l18.6-55.8c1.6-4.9 6.2-8.2 11.4-8.2h78.7c5.2 0 9.8 3.3 11.4 8.2l18.6 55.8H456c13.3 0 24 10.7 24 24z\"]\n  };\n  var faEye = {\n    prefix: 'far',\n    iconName: 'eye',\n    icon: [576, 512, [], \"f06e\", \"M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z\"]\n  };\n  var faFileCode = {\n    prefix: 'far',\n    iconName: 'file-code',\n    icon: [384, 512, [], \"f1c9\", \"M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z\"]\n  };\n  var faInfo = {\n    prefix: 'far',\n    iconName: 'info',\n    icon: [256, 512, [], \"f129\", \"M224 352.589V224c0-16.475-6.258-31.517-16.521-42.872C225.905 161.14 236 135.346 236 108 236 48.313 187.697 0 128 0 68.313 0 20 48.303 20 108c0 20.882 5.886 40.859 16.874 58.037C15.107 176.264 0 198.401 0 224v39.314c0 23.641 12.884 44.329 32 55.411v33.864C12.884 363.671 0 384.359 0 408v40c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-40c0-23.641-12.884-44.329-32-55.411zM128 48c33.137 0 60 26.863 60 60s-26.863 60-60 60-60-26.863-60-60 26.863-60 60-60zm80 400c0 8.836-7.164 16-16 16H64c-8.836 0-16-7.164-16-16v-40c0-8.836 7.164-16 16-16h16V279.314H64c-8.836 0-16-7.164-16-16V224c0-8.836 7.164-16 16-16h96c8.836 0 16 7.164 16 16v168h16c8.836 0 16 7.164 16 16v40z\"]\n  };\n  var faInfoCircle = {\n    prefix: 'far',\n    iconName: 'info-circle',\n    icon: [512, 512, [], \"f05a\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm0-338c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"]\n  };\n  var faPlus = {\n    prefix: 'far',\n    iconName: 'plus',\n    icon: [384, 512, [], \"f067\", \"M368 224H224V80c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h144v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V288h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"]\n  };\n  var faQuestionCircle = {\n    prefix: 'far',\n    iconName: 'question-circle',\n    icon: [512, 512, [], \"f059\", \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z\"]\n  };\n  var faRocket = {\n    prefix: 'far',\n    iconName: 'rocket',\n    icon: [512, 512, [], \"f135\", \"M367.96813,103.99609a39.999,39.999,0,1,0,40.00384,40A40.02908,40.02908,0,0,0,367.96813,103.99609ZM505.07337,19.3418c-1.21875-5.60742-6.75-11.13868-12.34373-12.3418-32.62885-7-58.162-7-83.57017-7C305.39988,0,242.95858,55.0918,196.236,127.99609H94.82015c-16.34567.01563-35.53314,11.875-42.87883,26.48243L2.53125,253.28906A28.12512,28.12512,0,0,0,0,263.99219a24.00617,24.00617,0,0,0,24.00191,23.998h92.63266l-10.59373,21.42188c-9.33592,18.91016,4.27733,34.77344,6.15624,36.62305l53.75381,53.71875c15.56443,15.54492,33.81635,7.52929,36.6601,6.13867l21.34567-10.57617V488a24.00659,24.00659,0,0,0,24.00191,24,28.618,28.618,0,0,0,10.71873-2.51562l98.6971-49.4043c14.625-7.29688,26.50191-26.5,26.50191-42.85938V315.69336c72.72449-46.76367,128.10525-109.44922,128.10525-212.69727C512.07531,77.4668,512.07531,51.99805,505.07337,19.3418ZM358.53065,274.99023c-36.94135,18.48438-121.10527,60.14063-166.7966,82.73243l-37.50189-37.49805c22.59567-45.6875,64.25575-129.99609,82.72447-166.88672C284.33741,79.5293,335.96623,47.99805,409.15947,47.99805c18.00192,0,34.2851,0,52.56632,2.34375,2.375,18.71875,2.31249,35.27929,2.25,52.63867C463.97578,175.75977,432.41138,227.30469,358.53065,274.99023Z\"]\n  };\n  var faSave = {\n    prefix: 'far',\n    iconName: 'save',\n    icon: [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z\"]\n  };\n  var faSlash = {\n    prefix: 'far',\n    iconName: 'slash',\n    icon: [640, 512, [], \"f715\", \"M604 508.49L6.01 40.98c-6.9-5.52-8.02-15.59-2.49-22.49L13.51 6C19.03-.9 29.1-2.01 36 3.51l598 467.51c6.9 5.52 8.02 15.59 2.49 22.49l-10 12.49c-5.52 6.9-15.59 8.01-22.49 2.49z\"]\n  };\n  var faTimes = {\n    prefix: 'far',\n    iconName: 'times',\n    icon: [320, 512, [], \"f00d\", \"M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z\"]\n  };\n  var faUndo = {\n    prefix: 'far',\n    iconName: 'undo',\n    icon: [512, 512, [], \"f0e2\", \"M12 8h27.711c6.739 0 12.157 5.548 11.997 12.286l-2.347 98.568C93.925 51.834 170.212 7.73 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.835 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.322 0 196-87.662 196-196 0-108.322-87.662-196-196-196-79.545 0-147.941 47.282-178.675 115.302l126.389-3.009c6.737-.16 12.286 5.257 12.286 11.997V212c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V20C0 13.373 5.373 8 12 8z\"]\n  };\n  var faUndoAlt = {\n    prefix: 'far',\n    iconName: 'undo-alt',\n    icon: [512, 512, [], \"f2ea\", \"M28.485 28.485L80.65 80.65C125.525 35.767 187.515 8 255.999 8 392.66 8 504.1 119.525 504 256.185 503.9 393.067 392.905 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.353-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.321 0 196-87.662 196-196 0-108.321-87.662-196-196-196-54.163 0-103.157 21.923-138.614 57.386l54.128 54.129c7.56 7.56 2.206 20.485-8.485 20.485H20c-6.627 0-12-5.373-12-12V36.971c0-10.691 12.926-16.045 20.485-8.486z\"]\n  };\n  var faUser = {\n    prefix: 'far',\n    iconName: 'user',\n    icon: [448, 512, [], \"f007\", \"M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z\"]\n  };\n  var faUserFriends = {\n    prefix: 'far',\n    iconName: 'user-friends',\n    icon: [640, 512, [], \"f500\", \"M480 256c53 0 96-43 96-96s-43-96-96-96-96 43-96 96 43 96 96 96zm0-144c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM272.1 276c-11.9 0-23.9 1.7-35.5 5.3-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-11.6-3.5-23.6-5.3-35.5-5.3-36.3 0-71.6 16.2-92.3 46.9C7.2 341.3 0 363.4 0 387.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM336 432H48v-44.8c0-28.9 18.4-53.6 44.1-63.1 10.3-3.8 21.6-3.7 31.9 0 22.1 7.9 45 11.9 68 11.9s45.8-4 68.1-11.9c10.3-3.7 21.6-3.8 31.9 0 25.7 9.4 44.1 34.2 44.1 63.1V432zM192 256c61.9 0 112-50.1 112-112S253.9 32 192 32 80 82.1 80 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm431.7 237.1C606.4 291.5 577 278 546.8 278c-27.8 0-34.8 10-66.8 10s-39-10-66.8-10c-13.3 0-26.2 3-38.2 8.1 5.8 5.9 11.3 12 16 18.9 4.7 7 8.6 14.4 12 22 3.3-.7 6.7-1.1 10.2-1.1 17.2 0 29.6 10 66.8 10 37.4 0 49.5-10 66.8-10 15.7 0 29.5 6.7 37.1 17.9 5.3 7.9 8.1 17.1 8.1 26.7V400H416v32c0 5.5-.6 10.8-1.6 16H600c22.1 0 40-17.9 40-40v-37.3c0-19.9-6-38.3-16.3-53.6z\"]\n  };\n  var faUsers = {\n    prefix: 'far',\n    iconName: 'users',\n    icon: [640, 512, [], \"f0c0\", \"M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zm396.4 210.9c-27.5-40.8-80.7-56-127.8-41.7-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-47.1-14.3-100.3.8-127.8 41.7-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c.2-23.8-7-45.9-19.4-64.3zM464 432H176v-44.8c0-36.4 29.2-66.2 65.4-67.2 25.5 10.6 51.9 16 78.6 16 26.7 0 53.1-5.4 78.6-16 36.2 1 65.4 30.7 65.4 67.2V432zm92-176h-24c-17.3 0-33.4 5.3-46.8 14.3 13.4 10.1 25.2 22.2 34.4 36.2 3.9-1.4 8-2.5 12.3-2.5h24c19.8 0 36 16.2 36 36 0 13.2 10.8 24 24 24s24-10.8 24-24c.1-46.3-37.6-84-83.9-84zm-236 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM154.8 270.3c-13.4-9-29.5-14.3-46.8-14.3H84c-46.3 0-84 37.7-84 84 0 13.2 10.8 24 24 24s24-10.8 24-24c0-19.8 16.2-36 36-36h24c4.4 0 8.5 1.1 12.3 2.5 9.3-14 21.1-26.1 34.5-36.2z\"]\n  };\n  var _iconsCache = {\n    faCheckCircle: faCheckCircle,\n    faDesktop: faDesktop,\n    faEye: faEye,\n    faFileCode: faFileCode,\n    faInfo: faInfo,\n    faInfoCircle: faInfoCircle,\n    faPlus: faPlus,\n    faQuestionCircle: faQuestionCircle,\n    faRocket: faRocket,\n    faSave: faSave,\n    faSlash: faSlash,\n    faTimes: faTimes,\n    faUndo: faUndo,\n    faUndoAlt: faUndoAlt,\n    faUser: faUser,\n    faUserFriends: faUserFriends,\n    faUsers: faUsers\n  };\n\n  exports.far = _iconsCache;\n  exports.prefix = prefix;\n  exports.faCheckCircle = faCheckCircle;\n  exports.faDesktop = faDesktop;\n  exports.faEye = faEye;\n  exports.faFileCode = faFileCode;\n  exports.faInfo = faInfo;\n  exports.faInfoCircle = faInfoCircle;\n  exports.faPlus = faPlus;\n  exports.faQuestionCircle = faQuestionCircle;\n  exports.faRocket = faRocket;\n  exports.faSave = faSave;\n  exports.faSlash = faSlash;\n  exports.faTimes = faTimes;\n  exports.faUndo = faUndo;\n  exports.faUndoAlt = faUndoAlt;\n  exports.faUser = faUser;\n  exports.faUserFriends = faUserFriends;\n  exports.faUsers = faUsers;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-regular-svg-icons/package.json",
    "content": "{\n  \"description\": \"The iconic font, CSS, and SVG framework\",\n  \"keywords\": [\n    \"font\",\n    \"awesome\",\n    \"fontawesome\",\n    \"icon\",\n    \"svg\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://fontawesome.com\",\n  \"bugs\": {\n    \"url\": \"http://github.com/FortAwesome/Font-Awesome/issues\"\n  },\n  \"author\": {\n    \"name\": \"Dave Gandy\",\n    \"email\": \"dave@fontawesome.com\",\n    \"web\": \"http://twitter.com/davegandy\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Brian Talbot\",\n      \"web\": \"http://twitter.com/talbs\"\n    },\n    {\n      \"name\": \"Travis Chase\",\n      \"web\": \"http://twitter.com/supercodepoet\"\n    },\n    {\n      \"name\": \"Rob Madole\",\n      \"web\": \"http://twitter.com/robmadole\"\n    },\n    {\n      \"name\": \"Geremia Taglialatela\",\n      \"web\": \"http://twitter.com/gtagliala\"\n    },\n    {\n      \"name\": \"Mike Wilkerson\",\n      \"web\": \"http://twitter.com/mw77\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/FortAwesome/Font-Awesome\"\n  },\n  \"engines\": {\n    \"node\": \">=6\"\n  },\n  \"dependencies\": {\n    \"@fortawesome/fontawesome-common-types\": \"^0.2.36\"\n  },\n  \"version\": \"5.15.4\",\n  \"name\": \"@fortawesome/pro-regular-svg-icons\",\n  \"main\": \"index.js\",\n  \"module\": \"index.es.js\",\n  \"jsnext:main\": \"index.es.js\",\n  \"license\": \"UNLICENSED\",\n  \"types\": \"./index.d.ts\",\n  \"sideEffects\": false,\n  \"scripts\": {\n    \"postinstall\": \"node attribution.js\"\n  }\n}"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/LICENSE.txt",
    "content": "Font Awesome Pro License\n------------------------\n\nFont Awesome Pro is commercial software that requires a paid license. Full\nFont Awesome Pro license: https://fontawesome.com/license.\n\n# Commercial License\nThe Font Awesome Pro commercial license allows you to pay for FA Pro once, own\nit, and use it just about everywhere you'd like.\n\n# Attribution\nAttribution is not required by the Font Awesome Pro commercial license.\n\n# Brand Icons\nAll brand icons are trademarks of their respective owners. The use of these\ntrademarks does not indicate endorsement of the trademark holder by Font\nAwesome, nor vice versa. **Please do not use brand logos for any purpose except\nto represent the company, product, or service to which they refer.**\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/README.md",
    "content": "# @fortawesome/pro-solid-svg-icons - SVG with JavaScript version\n\n> \"I came here to chew bubblegum and install Font Awesome 5 - and I'm all out of bubblegum\"\n\n[![npm](https://img.shields.io/npm/v/@fortawesome/pro-solid-svg-icons.svg?style=flat-square)](https://www.npmjs.com/package/@fortawesome/pro-solid-svg-icons)\n\n## Installation\n\n```\n$ npm i --save @fortawesome/pro-solid-svg-icons\n```\n\nOr\n\n```\n$ yarn add @fortawesome/pro-solid-svg-icons\n```\n\n## Documentation\n\nGet started [here](https://fontawesome.com/how-to-use/on-the-web/setup/getting-started). Continue your journey [here](https://fontawesome.com/how-to-use/on-the-web/advanced).\n\nOr go straight to the [API documentation](https://fontawesome.com/how-to-use/with-the-api).\n\n## Issues and support\n\nStart with [GitHub issues](https://github.com/FortAwesome/Font-Awesome/issues) and ping us on [Twitter](https://twitter.com/fontawesome) if you need to.\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/attribution.js",
    "content": "console.log(`Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\nLicense - https://fontawesome.com/license (Commercial License)\n`)"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faAlarmExclamation.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faAlarmExclamation: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faAlarmExclamation.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'alarm-exclamation';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f843';\nvar svgPathData = 'M96 0A96 96 0 0 0 0 96a94.81 94.81 0 0 0 15.3 51.26L161.2 25.68A95.63 95.63 0 0 0 96 0zm320 0a95.66 95.66 0 0 0-65.18 25.66l145.89 121.57A94.85 94.85 0 0 0 512 96a96 96 0 0 0-96-96zM256 64C132.3 64 32 164.29 32 288a222.7 222.7 0 0 0 44.79 134l-40.1 40.09a16 16 0 0 0 0 22.63l22.62 22.62a16 16 0 0 0 22.63 0L122 467.22a222.82 222.82 0 0 0 268 0l40.1 40.09a16 16 0 0 0 22.62 0l22.63-22.62a16 16 0 0 0 0-22.63L435.25 422A222.69 222.69 0 0 0 480 288c0-123.71-100.26-224-224-224zm0 352a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm25.4-110.4a16 16 0 0 1-15.9 14.4h-19a16 16 0 0 1-15.9-14.4l-12.8-128a16.06 16.06 0 0 1 15.9-17.6h44.6a16 16 0 0 1 15.9 17.6z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faAlarmExclamation = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faAlignLeft.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faAlignLeft: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faAlignLeft.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'align-left';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f036';\nvar svgPathData = 'M12.83 352h262.34A12.82 12.82 0 0 0 288 339.17v-38.34A12.82 12.82 0 0 0 275.17 288H12.83A12.82 12.82 0 0 0 0 300.83v38.34A12.82 12.82 0 0 0 12.83 352zm0-256h262.34A12.82 12.82 0 0 0 288 83.17V44.83A12.82 12.82 0 0 0 275.17 32H12.83A12.82 12.82 0 0 0 0 44.83v38.34A12.82 12.82 0 0 0 12.83 96zM432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faAlignLeft = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faBookDead.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faBookDead: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faBookDead.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'book-dead';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f6b7';\nvar svgPathData = 'M272 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm176 222.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM240 56c44.2 0 80 28.7 80 64 0 20.9-12.7 39.2-32 50.9V184c0 8.8-7.2 16-16 16h-64c-8.8 0-16-7.2-16-16v-13.1c-19.3-11.7-32-30-32-50.9 0-35.3 35.8-64 80-64zM124.8 223.3l6.3-14.7c1.7-4.1 6.4-5.9 10.5-4.2l98.3 42.1 98.4-42.1c4.1-1.7 8.8.1 10.5 4.2l6.3 14.7c1.7 4.1-.1 8.8-4.2 10.5L280.6 264l70.3 30.1c4.1 1.7 5.9 6.4 4.2 10.5l-6.3 14.7c-1.7 4.1-6.4 5.9-10.5 4.2L240 281.4l-98.3 42.2c-4.1 1.7-8.8-.1-10.5-4.2l-6.3-14.7c-1.7-4.1.1-8.8 4.2-10.5l70.4-30.1-70.5-30.3c-4.1-1.7-5.9-6.4-4.2-10.5zm256 224.7H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8zM208 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faBookDead = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faCheck.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCheck: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faCheck.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'check';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f00c';\nvar svgPathData = 'M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCheck = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faCircle.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCircle: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faCircle.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'circle';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f111';\nvar svgPathData = 'M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCircle = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faCloud.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCloud: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faCloud.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'cloud';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0c2';\nvar svgPathData = 'M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCloud = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faCreditCard.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faCreditCard: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faCreditCard.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'credit-card';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f09d';\nvar svgPathData = 'M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faCreditCard = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faDesktop.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faDesktop: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faDesktop.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'desktop';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f108';\nvar svgPathData = 'M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faDesktop = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faEnvelope.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faEnvelope: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faEnvelope.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'envelope';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0e0';\nvar svgPathData = 'M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faEnvelope = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faEye.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faEye: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faEye.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'eye';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f06e';\nvar svgPathData = 'M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faEye = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faFingerprint.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faFingerprint: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faFingerprint.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'fingerprint';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f577';\nvar svgPathData = 'M256.12 245.96c-13.25 0-24 10.74-24 24 1.14 72.25-8.14 141.9-27.7 211.55-2.73 9.72 2.15 30.49 23.12 30.49 10.48 0 20.11-6.92 23.09-17.52 13.53-47.91 31.04-125.41 29.48-224.52.01-13.25-10.73-24-23.99-24zm-.86-81.73C194 164.16 151.25 211.3 152.1 265.32c.75 47.94-3.75 95.91-13.37 142.55-2.69 12.98 5.67 25.69 18.64 28.36 13.05 2.67 25.67-5.66 28.36-18.64 10.34-50.09 15.17-101.58 14.37-153.02-.41-25.95 19.92-52.49 54.45-52.34 31.31.47 57.15 25.34 57.62 55.47.77 48.05-2.81 96.33-10.61 143.55-2.17 13.06 6.69 25.42 19.76 27.58 19.97 3.33 26.81-15.1 27.58-19.77 8.28-50.03 12.06-101.21 11.27-152.11-.88-55.8-47.94-101.88-104.91-102.72zm-110.69-19.78c-10.3-8.34-25.37-6.8-33.76 3.48-25.62 31.5-39.39 71.28-38.75 112 .59 37.58-2.47 75.27-9.11 112.05-2.34 13.05 6.31 25.53 19.36 27.89 20.11 3.5 27.07-14.81 27.89-19.36 7.19-39.84 10.5-80.66 9.86-121.33-.47-29.88 9.2-57.88 28-80.97 8.35-10.28 6.79-25.39-3.49-33.76zm109.47-62.33c-15.41-.41-30.87 1.44-45.78 4.97-12.89 3.06-20.87 15.98-17.83 28.89 3.06 12.89 16 20.83 28.89 17.83 11.05-2.61 22.47-3.77 34-3.69 75.43 1.13 137.73 61.5 138.88 134.58.59 37.88-1.28 76.11-5.58 113.63-1.5 13.17 7.95 25.08 21.11 26.58 16.72 1.95 25.51-11.88 26.58-21.11a929.06 929.06 0 0 0 5.89-119.85c-1.56-98.75-85.07-180.33-186.16-181.83zm252.07 121.45c-2.86-12.92-15.51-21.2-28.61-18.27-12.94 2.86-21.12 15.66-18.26 28.61 4.71 21.41 4.91 37.41 4.7 61.6-.11 13.27 10.55 24.09 23.8 24.2h.2c13.17 0 23.89-10.61 24-23.8.18-22.18.4-44.11-5.83-72.34zm-40.12-90.72C417.29 43.46 337.6 1.29 252.81.02 183.02-.82 118.47 24.91 70.46 72.94 24.09 119.37-.9 181.04.14 246.65l-.12 21.47c-.39 13.25 10.03 24.31 23.28 24.69.23.02.48.02.72.02 12.92 0 23.59-10.3 23.97-23.3l.16-23.64c-.83-52.5 19.16-101.86 56.28-139 38.76-38.8 91.34-59.67 147.68-58.86 69.45 1.03 134.73 35.56 174.62 92.39 7.61 10.86 22.56 13.45 33.42 5.86 10.84-7.62 13.46-22.59 5.84-33.43z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faFingerprint = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faHistory.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faHistory: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faHistory.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'history';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f1da';\nvar svgPathData = 'M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faHistory = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faHome.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faHome: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faHome.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'home';\nvar width = 576;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f015';\nvar svgPathData = 'M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faHome = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faPlus.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faPlus: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faPlus.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'plus';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f067';\nvar svgPathData = 'M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faPlus = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faRobot.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faRobot: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faRobot.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'robot';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f544';\nvar svgPathData = 'M32,224H64V416H32A31.96166,31.96166,0,0,1,0,384V256A31.96166,31.96166,0,0,1,32,224Zm512-48V448a64.06328,64.06328,0,0,1-64,64H160a64.06328,64.06328,0,0,1-64-64V176a79.974,79.974,0,0,1,80-80H288V32a32,32,0,0,1,64,0V96H464A79.974,79.974,0,0,1,544,176ZM264,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,264,256Zm-8,128H192v32h64Zm96,0H288v32h64ZM456,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,456,256Zm-8,128H384v32h64ZM640,256V384a31.96166,31.96166,0,0,1-32,32H576V224h32A31.96166,31.96166,0,0,1,640,256Z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faRobot = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faRocket.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faRocket: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faRocket.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'rocket';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f135';\nvar svgPathData = 'M505.12019,19.09375c-1.18945-5.53125-6.65819-11-12.207-12.1875C460.716,0,435.507,0,410.40747,0,307.17523,0,245.26909,55.20312,199.05238,128H94.83772c-16.34763.01562-35.55658,11.875-42.88664,26.48438L2.51562,253.29688A28.4,28.4,0,0,0,0,264a24.00867,24.00867,0,0,0,24.00582,24H127.81618l-22.47457,22.46875c-11.36521,11.36133-12.99607,32.25781,0,45.25L156.24582,406.625c11.15623,11.1875,32.15619,13.15625,45.27726,0l22.47457-22.46875V488a24.00867,24.00867,0,0,0,24.00581,24,28.55934,28.55934,0,0,0,10.707-2.51562l98.72834-49.39063c14.62888-7.29687,26.50776-26.5,26.50776-42.85937V312.79688c72.59753-46.3125,128.03493-108.40626,128.03493-211.09376C512.07526,76.5,512.07526,51.29688,505.12019,19.09375ZM384.04033,168A40,40,0,1,1,424.05,128,40.02322,40.02322,0,0,1,384.04033,168Z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faRocket = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faSave.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSave: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faSave.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'save';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0c7';\nvar svgPathData = 'M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSave = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faSlash.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSlash: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faSlash.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'slash';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f715';\nvar svgPathData = 'M594.53 508.63L6.18 53.9c-6.97-5.42-8.23-15.47-2.81-22.45L23.01 6.18C28.43-.8 38.49-2.06 45.47 3.37L633.82 458.1c6.97 5.42 8.23 15.47 2.81 22.45l-19.64 25.27c-5.42 6.98-15.48 8.23-22.46 2.81z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSlash = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faSpinnerThird.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSpinnerThird: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faSpinnerThird.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'spinner-third';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f3f4';\nvar svgPathData = 'M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSpinnerThird = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faSquareFull.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faSquareFull: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faSquareFull.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'square-full';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f45c';\nvar svgPathData = 'M512 512H0V0h512v512z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faSquareFull = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faTimes.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faTimes: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faTimes.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'times';\nvar width = 352;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f00d';\nvar svgPathData = 'M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faTimes = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faTimesCircle.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faTimesCircle: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faTimesCircle.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'times-circle';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f057';\nvar svgPathData = 'M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faTimesCircle = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faUndo.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUndo: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faUndo.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'undo';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0e2';\nvar svgPathData = 'M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUndo = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faUndoAlt.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUndoAlt: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faUndoAlt.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'undo-alt';\nvar width = 512;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f2ea';\nvar svgPathData = 'M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUndoAlt = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faUser.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUser: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faUser.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'user';\nvar width = 448;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f007';\nvar svgPathData = 'M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUser = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faUsers.d.ts",
    "content": "import { IconDefinition, IconPrefix, IconName } from \"@fortawesome/fontawesome-common-types\";\nexport const definition: IconDefinition;\nexport const faUsers: IconDefinition;\nexport const prefix: IconPrefix;\nexport const iconName: IconName;\nexport const width: number;\nexport const height: number;\nexport const ligatures: string[];\nexport const unicode: string;\nexport const svgPathData: string;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/faUsers.js",
    "content": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nvar prefix = 'fas';\nvar iconName = 'users';\nvar width = 640;\nvar height = 512;\nvar ligatures = [];\nvar unicode = 'f0c0';\nvar svgPathData = 'M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z';\n\nexports.definition = {\n  prefix: prefix,\n  iconName: iconName,\n  icon: [\n    width,\n    height,\n    ligatures,\n    unicode,\n    svgPathData\n  ]};\n\nexports.faUsers = exports.definition;\nexports.prefix = prefix;\nexports.iconName = iconName;\nexports.width = width;\nexports.height = height;\nexports.ligatures = ligatures;\nexports.unicode = unicode;\nexports.svgPathData = svgPathData;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/index.d.ts",
    "content": "export const faAlarmExclamation: IconDefinition;\nexport const faAlignLeft: IconDefinition;\nexport const faBookDead: IconDefinition;\nexport const faCheck: IconDefinition;\nexport const faCircle: IconDefinition;\nexport const faCloud: IconDefinition;\nexport const faCreditCard: IconDefinition;\nexport const faDesktop: IconDefinition;\nexport const faEnvelope: IconDefinition;\nexport const faEye: IconDefinition;\nexport const faFingerprint: IconDefinition;\nexport const faHistory: IconDefinition;\nexport const faHome: IconDefinition;\nexport const faPlus: IconDefinition;\nexport const faRobot: IconDefinition;\nexport const faRocket: IconDefinition;\nexport const faSave: IconDefinition;\nexport const faSlash: IconDefinition;\nexport const faSpinnerThird: IconDefinition;\nexport const faSquareFull: IconDefinition;\nexport const faTimes: IconDefinition;\nexport const faTimesCircle: IconDefinition;\nexport const faUndo: IconDefinition;\nexport const faUndoAlt: IconDefinition;\nexport const faUser: IconDefinition;\nexport const faUsers: IconDefinition;\nimport { IconDefinition, IconLookup, IconName, IconPrefix, IconPack } from '@fortawesome/fontawesome-common-types';\nexport { IconDefinition, IconLookup, IconName, IconPrefix, IconPack } from '@fortawesome/fontawesome-common-types';\nexport const prefix: IconPrefix;\nexport const fas: IconPack;"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/index.es.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\nvar prefix = \"fas\";\nvar faAlarmExclamation = {\n  prefix: 'fas',\n  iconName: 'alarm-exclamation',\n  icon: [512, 512, [], \"f843\", \"M96 0A96 96 0 0 0 0 96a94.81 94.81 0 0 0 15.3 51.26L161.2 25.68A95.63 95.63 0 0 0 96 0zm320 0a95.66 95.66 0 0 0-65.18 25.66l145.89 121.57A94.85 94.85 0 0 0 512 96a96 96 0 0 0-96-96zM256 64C132.3 64 32 164.29 32 288a222.7 222.7 0 0 0 44.79 134l-40.1 40.09a16 16 0 0 0 0 22.63l22.62 22.62a16 16 0 0 0 22.63 0L122 467.22a222.82 222.82 0 0 0 268 0l40.1 40.09a16 16 0 0 0 22.62 0l22.63-22.62a16 16 0 0 0 0-22.63L435.25 422A222.69 222.69 0 0 0 480 288c0-123.71-100.26-224-224-224zm0 352a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm25.4-110.4a16 16 0 0 1-15.9 14.4h-19a16 16 0 0 1-15.9-14.4l-12.8-128a16.06 16.06 0 0 1 15.9-17.6h44.6a16 16 0 0 1 15.9 17.6z\"]\n};\nvar faAlignLeft = {\n  prefix: 'fas',\n  iconName: 'align-left',\n  icon: [448, 512, [], \"f036\", \"M12.83 352h262.34A12.82 12.82 0 0 0 288 339.17v-38.34A12.82 12.82 0 0 0 275.17 288H12.83A12.82 12.82 0 0 0 0 300.83v38.34A12.82 12.82 0 0 0 12.83 352zm0-256h262.34A12.82 12.82 0 0 0 288 83.17V44.83A12.82 12.82 0 0 0 275.17 32H12.83A12.82 12.82 0 0 0 0 44.83v38.34A12.82 12.82 0 0 0 12.83 96zM432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n};\nvar faBookDead = {\n  prefix: 'fas',\n  iconName: 'book-dead',\n  icon: [448, 512, [], \"f6b7\", \"M272 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm176 222.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM240 56c44.2 0 80 28.7 80 64 0 20.9-12.7 39.2-32 50.9V184c0 8.8-7.2 16-16 16h-64c-8.8 0-16-7.2-16-16v-13.1c-19.3-11.7-32-30-32-50.9 0-35.3 35.8-64 80-64zM124.8 223.3l6.3-14.7c1.7-4.1 6.4-5.9 10.5-4.2l98.3 42.1 98.4-42.1c4.1-1.7 8.8.1 10.5 4.2l6.3 14.7c1.7 4.1-.1 8.8-4.2 10.5L280.6 264l70.3 30.1c4.1 1.7 5.9 6.4 4.2 10.5l-6.3 14.7c-1.7 4.1-6.4 5.9-10.5 4.2L240 281.4l-98.3 42.2c-4.1 1.7-8.8-.1-10.5-4.2l-6.3-14.7c-1.7-4.1.1-8.8 4.2-10.5l70.4-30.1-70.5-30.3c-4.1-1.7-5.9-6.4-4.2-10.5zm256 224.7H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8zM208 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16z\"]\n};\nvar faCheck = {\n  prefix: 'fas',\n  iconName: 'check',\n  icon: [512, 512, [], \"f00c\", \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"]\n};\nvar faCircle = {\n  prefix: 'fas',\n  iconName: 'circle',\n  icon: [512, 512, [], \"f111\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"]\n};\nvar faCloud = {\n  prefix: 'fas',\n  iconName: 'cloud',\n  icon: [640, 512, [], \"f0c2\", \"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z\"]\n};\nvar faCreditCard = {\n  prefix: 'fas',\n  iconName: 'credit-card',\n  icon: [576, 512, [], \"f09d\", \"M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z\"]\n};\nvar faDesktop = {\n  prefix: 'fas',\n  iconName: 'desktop',\n  icon: [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z\"]\n};\nvar faEnvelope = {\n  prefix: 'fas',\n  iconName: 'envelope',\n  icon: [512, 512, [], \"f0e0\", \"M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z\"]\n};\nvar faEye = {\n  prefix: 'fas',\n  iconName: 'eye',\n  icon: [576, 512, [], \"f06e\", \"M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z\"]\n};\nvar faFingerprint = {\n  prefix: 'fas',\n  iconName: 'fingerprint',\n  icon: [512, 512, [], \"f577\", \"M256.12 245.96c-13.25 0-24 10.74-24 24 1.14 72.25-8.14 141.9-27.7 211.55-2.73 9.72 2.15 30.49 23.12 30.49 10.48 0 20.11-6.92 23.09-17.52 13.53-47.91 31.04-125.41 29.48-224.52.01-13.25-10.73-24-23.99-24zm-.86-81.73C194 164.16 151.25 211.3 152.1 265.32c.75 47.94-3.75 95.91-13.37 142.55-2.69 12.98 5.67 25.69 18.64 28.36 13.05 2.67 25.67-5.66 28.36-18.64 10.34-50.09 15.17-101.58 14.37-153.02-.41-25.95 19.92-52.49 54.45-52.34 31.31.47 57.15 25.34 57.62 55.47.77 48.05-2.81 96.33-10.61 143.55-2.17 13.06 6.69 25.42 19.76 27.58 19.97 3.33 26.81-15.1 27.58-19.77 8.28-50.03 12.06-101.21 11.27-152.11-.88-55.8-47.94-101.88-104.91-102.72zm-110.69-19.78c-10.3-8.34-25.37-6.8-33.76 3.48-25.62 31.5-39.39 71.28-38.75 112 .59 37.58-2.47 75.27-9.11 112.05-2.34 13.05 6.31 25.53 19.36 27.89 20.11 3.5 27.07-14.81 27.89-19.36 7.19-39.84 10.5-80.66 9.86-121.33-.47-29.88 9.2-57.88 28-80.97 8.35-10.28 6.79-25.39-3.49-33.76zm109.47-62.33c-15.41-.41-30.87 1.44-45.78 4.97-12.89 3.06-20.87 15.98-17.83 28.89 3.06 12.89 16 20.83 28.89 17.83 11.05-2.61 22.47-3.77 34-3.69 75.43 1.13 137.73 61.5 138.88 134.58.59 37.88-1.28 76.11-5.58 113.63-1.5 13.17 7.95 25.08 21.11 26.58 16.72 1.95 25.51-11.88 26.58-21.11a929.06 929.06 0 0 0 5.89-119.85c-1.56-98.75-85.07-180.33-186.16-181.83zm252.07 121.45c-2.86-12.92-15.51-21.2-28.61-18.27-12.94 2.86-21.12 15.66-18.26 28.61 4.71 21.41 4.91 37.41 4.7 61.6-.11 13.27 10.55 24.09 23.8 24.2h.2c13.17 0 23.89-10.61 24-23.8.18-22.18.4-44.11-5.83-72.34zm-40.12-90.72C417.29 43.46 337.6 1.29 252.81.02 183.02-.82 118.47 24.91 70.46 72.94 24.09 119.37-.9 181.04.14 246.65l-.12 21.47c-.39 13.25 10.03 24.31 23.28 24.69.23.02.48.02.72.02 12.92 0 23.59-10.3 23.97-23.3l.16-23.64c-.83-52.5 19.16-101.86 56.28-139 38.76-38.8 91.34-59.67 147.68-58.86 69.45 1.03 134.73 35.56 174.62 92.39 7.61 10.86 22.56 13.45 33.42 5.86 10.84-7.62 13.46-22.59 5.84-33.43z\"]\n};\nvar faHistory = {\n  prefix: 'fas',\n  iconName: 'history',\n  icon: [512, 512, [], \"f1da\", \"M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z\"]\n};\nvar faHome = {\n  prefix: 'fas',\n  iconName: 'home',\n  icon: [576, 512, [], \"f015\", \"M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z\"]\n};\nvar faPlus = {\n  prefix: 'fas',\n  iconName: 'plus',\n  icon: [448, 512, [], \"f067\", \"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"]\n};\nvar faRobot = {\n  prefix: 'fas',\n  iconName: 'robot',\n  icon: [640, 512, [], \"f544\", \"M32,224H64V416H32A31.96166,31.96166,0,0,1,0,384V256A31.96166,31.96166,0,0,1,32,224Zm512-48V448a64.06328,64.06328,0,0,1-64,64H160a64.06328,64.06328,0,0,1-64-64V176a79.974,79.974,0,0,1,80-80H288V32a32,32,0,0,1,64,0V96H464A79.974,79.974,0,0,1,544,176ZM264,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,264,256Zm-8,128H192v32h64Zm96,0H288v32h64ZM456,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,456,256Zm-8,128H384v32h64ZM640,256V384a31.96166,31.96166,0,0,1-32,32H576V224h32A31.96166,31.96166,0,0,1,640,256Z\"]\n};\nvar faRocket = {\n  prefix: 'fas',\n  iconName: 'rocket',\n  icon: [512, 512, [], \"f135\", \"M505.12019,19.09375c-1.18945-5.53125-6.65819-11-12.207-12.1875C460.716,0,435.507,0,410.40747,0,307.17523,0,245.26909,55.20312,199.05238,128H94.83772c-16.34763.01562-35.55658,11.875-42.88664,26.48438L2.51562,253.29688A28.4,28.4,0,0,0,0,264a24.00867,24.00867,0,0,0,24.00582,24H127.81618l-22.47457,22.46875c-11.36521,11.36133-12.99607,32.25781,0,45.25L156.24582,406.625c11.15623,11.1875,32.15619,13.15625,45.27726,0l22.47457-22.46875V488a24.00867,24.00867,0,0,0,24.00581,24,28.55934,28.55934,0,0,0,10.707-2.51562l98.72834-49.39063c14.62888-7.29687,26.50776-26.5,26.50776-42.85937V312.79688c72.59753-46.3125,128.03493-108.40626,128.03493-211.09376C512.07526,76.5,512.07526,51.29688,505.12019,19.09375ZM384.04033,168A40,40,0,1,1,424.05,128,40.02322,40.02322,0,0,1,384.04033,168Z\"]\n};\nvar faSave = {\n  prefix: 'fas',\n  iconName: 'save',\n  icon: [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"]\n};\nvar faSlash = {\n  prefix: 'fas',\n  iconName: 'slash',\n  icon: [640, 512, [], \"f715\", \"M594.53 508.63L6.18 53.9c-6.97-5.42-8.23-15.47-2.81-22.45L23.01 6.18C28.43-.8 38.49-2.06 45.47 3.37L633.82 458.1c6.97 5.42 8.23 15.47 2.81 22.45l-19.64 25.27c-5.42 6.98-15.48 8.23-22.46 2.81z\"]\n};\nvar faSpinnerThird = {\n  prefix: 'fas',\n  iconName: 'spinner-third',\n  icon: [512, 512, [], \"f3f4\", \"M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z\"]\n};\nvar faSquareFull = {\n  prefix: 'fas',\n  iconName: 'square-full',\n  icon: [512, 512, [], \"f45c\", \"M512 512H0V0h512v512z\"]\n};\nvar faTimes = {\n  prefix: 'fas',\n  iconName: 'times',\n  icon: [352, 512, [], \"f00d\", \"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\"]\n};\nvar faTimesCircle = {\n  prefix: 'fas',\n  iconName: 'times-circle',\n  icon: [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"]\n};\nvar faUndo = {\n  prefix: 'fas',\n  iconName: 'undo',\n  icon: [512, 512, [], \"f0e2\", \"M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z\"]\n};\nvar faUndoAlt = {\n  prefix: 'fas',\n  iconName: 'undo-alt',\n  icon: [512, 512, [], \"f2ea\", \"M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z\"]\n};\nvar faUser = {\n  prefix: 'fas',\n  iconName: 'user',\n  icon: [448, 512, [], \"f007\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"]\n};\nvar faUsers = {\n  prefix: 'fas',\n  iconName: 'users',\n  icon: [640, 512, [], \"f0c0\", \"M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z\"]\n};\nvar _iconsCache = {\n  faAlarmExclamation: faAlarmExclamation,\n  faAlignLeft: faAlignLeft,\n  faBookDead: faBookDead,\n  faCheck: faCheck,\n  faCircle: faCircle,\n  faCloud: faCloud,\n  faCreditCard: faCreditCard,\n  faDesktop: faDesktop,\n  faEnvelope: faEnvelope,\n  faEye: faEye,\n  faFingerprint: faFingerprint,\n  faHistory: faHistory,\n  faHome: faHome,\n  faPlus: faPlus,\n  faRobot: faRobot,\n  faRocket: faRocket,\n  faSave: faSave,\n  faSlash: faSlash,\n  faSpinnerThird: faSpinnerThird,\n  faSquareFull: faSquareFull,\n  faTimes: faTimes,\n  faTimesCircle: faTimesCircle,\n  faUndo: faUndo,\n  faUndoAlt: faUndoAlt,\n  faUser: faUser,\n  faUsers: faUsers\n};\n\nexport { _iconsCache as fas, prefix, faAlarmExclamation, faAlignLeft, faBookDead, faCheck, faCircle, faCloud, faCreditCard, faDesktop, faEnvelope, faEye, faFingerprint, faHistory, faHome, faPlus, faRobot, faRocket, faSave, faSlash, faSpinnerThird, faSquareFull, faTimes, faTimesCircle, faUndo, faUndoAlt, faUser, faUsers };\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/index.js",
    "content": "/*!\n * Font Awesome Pro 5.15.4 by @fontawesome - https://fontawesome.com\n * License - https://fontawesome.com/license (Commercial License)\n */\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n  typeof define === 'function' && define.amd ? define(['exports'], factory) :\n  (factory((global['pro-solid-svg-icons'] = {})));\n}(this, (function (exports) { 'use strict';\n\n  var prefix = \"fas\";\n  var faAlarmExclamation = {\n    prefix: 'fas',\n    iconName: 'alarm-exclamation',\n    icon: [512, 512, [], \"f843\", \"M96 0A96 96 0 0 0 0 96a94.81 94.81 0 0 0 15.3 51.26L161.2 25.68A95.63 95.63 0 0 0 96 0zm320 0a95.66 95.66 0 0 0-65.18 25.66l145.89 121.57A94.85 94.85 0 0 0 512 96a96 96 0 0 0-96-96zM256 64C132.3 64 32 164.29 32 288a222.7 222.7 0 0 0 44.79 134l-40.1 40.09a16 16 0 0 0 0 22.63l22.62 22.62a16 16 0 0 0 22.63 0L122 467.22a222.82 222.82 0 0 0 268 0l40.1 40.09a16 16 0 0 0 22.62 0l22.63-22.62a16 16 0 0 0 0-22.63L435.25 422A222.69 222.69 0 0 0 480 288c0-123.71-100.26-224-224-224zm0 352a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm25.4-110.4a16 16 0 0 1-15.9 14.4h-19a16 16 0 0 1-15.9-14.4l-12.8-128a16.06 16.06 0 0 1 15.9-17.6h44.6a16 16 0 0 1 15.9 17.6z\"]\n  };\n  var faAlignLeft = {\n    prefix: 'fas',\n    iconName: 'align-left',\n    icon: [448, 512, [], \"f036\", \"M12.83 352h262.34A12.82 12.82 0 0 0 288 339.17v-38.34A12.82 12.82 0 0 0 275.17 288H12.83A12.82 12.82 0 0 0 0 300.83v38.34A12.82 12.82 0 0 0 12.83 352zm0-256h262.34A12.82 12.82 0 0 0 288 83.17V44.83A12.82 12.82 0 0 0 275.17 32H12.83A12.82 12.82 0 0 0 0 44.83v38.34A12.82 12.82 0 0 0 12.83 96zM432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"]\n  };\n  var faBookDead = {\n    prefix: 'fas',\n    iconName: 'book-dead',\n    icon: [448, 512, [], \"f6b7\", \"M272 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm176 222.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM240 56c44.2 0 80 28.7 80 64 0 20.9-12.7 39.2-32 50.9V184c0 8.8-7.2 16-16 16h-64c-8.8 0-16-7.2-16-16v-13.1c-19.3-11.7-32-30-32-50.9 0-35.3 35.8-64 80-64zM124.8 223.3l6.3-14.7c1.7-4.1 6.4-5.9 10.5-4.2l98.3 42.1 98.4-42.1c4.1-1.7 8.8.1 10.5 4.2l6.3 14.7c1.7 4.1-.1 8.8-4.2 10.5L280.6 264l70.3 30.1c4.1 1.7 5.9 6.4 4.2 10.5l-6.3 14.7c-1.7 4.1-6.4 5.9-10.5 4.2L240 281.4l-98.3 42.2c-4.1 1.7-8.8-.1-10.5-4.2l-6.3-14.7c-1.7-4.1.1-8.8 4.2-10.5l70.4-30.1-70.5-30.3c-4.1-1.7-5.9-6.4-4.2-10.5zm256 224.7H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8zM208 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16z\"]\n  };\n  var faCheck = {\n    prefix: 'fas',\n    iconName: 'check',\n    icon: [512, 512, [], \"f00c\", \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"]\n  };\n  var faCircle = {\n    prefix: 'fas',\n    iconName: 'circle',\n    icon: [512, 512, [], \"f111\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"]\n  };\n  var faCloud = {\n    prefix: 'fas',\n    iconName: 'cloud',\n    icon: [640, 512, [], \"f0c2\", \"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z\"]\n  };\n  var faCreditCard = {\n    prefix: 'fas',\n    iconName: 'credit-card',\n    icon: [576, 512, [], \"f09d\", \"M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z\"]\n  };\n  var faDesktop = {\n    prefix: 'fas',\n    iconName: 'desktop',\n    icon: [576, 512, [], \"f108\", \"M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z\"]\n  };\n  var faEnvelope = {\n    prefix: 'fas',\n    iconName: 'envelope',\n    icon: [512, 512, [], \"f0e0\", \"M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z\"]\n  };\n  var faEye = {\n    prefix: 'fas',\n    iconName: 'eye',\n    icon: [576, 512, [], \"f06e\", \"M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z\"]\n  };\n  var faFingerprint = {\n    prefix: 'fas',\n    iconName: 'fingerprint',\n    icon: [512, 512, [], \"f577\", \"M256.12 245.96c-13.25 0-24 10.74-24 24 1.14 72.25-8.14 141.9-27.7 211.55-2.73 9.72 2.15 30.49 23.12 30.49 10.48 0 20.11-6.92 23.09-17.52 13.53-47.91 31.04-125.41 29.48-224.52.01-13.25-10.73-24-23.99-24zm-.86-81.73C194 164.16 151.25 211.3 152.1 265.32c.75 47.94-3.75 95.91-13.37 142.55-2.69 12.98 5.67 25.69 18.64 28.36 13.05 2.67 25.67-5.66 28.36-18.64 10.34-50.09 15.17-101.58 14.37-153.02-.41-25.95 19.92-52.49 54.45-52.34 31.31.47 57.15 25.34 57.62 55.47.77 48.05-2.81 96.33-10.61 143.55-2.17 13.06 6.69 25.42 19.76 27.58 19.97 3.33 26.81-15.1 27.58-19.77 8.28-50.03 12.06-101.21 11.27-152.11-.88-55.8-47.94-101.88-104.91-102.72zm-110.69-19.78c-10.3-8.34-25.37-6.8-33.76 3.48-25.62 31.5-39.39 71.28-38.75 112 .59 37.58-2.47 75.27-9.11 112.05-2.34 13.05 6.31 25.53 19.36 27.89 20.11 3.5 27.07-14.81 27.89-19.36 7.19-39.84 10.5-80.66 9.86-121.33-.47-29.88 9.2-57.88 28-80.97 8.35-10.28 6.79-25.39-3.49-33.76zm109.47-62.33c-15.41-.41-30.87 1.44-45.78 4.97-12.89 3.06-20.87 15.98-17.83 28.89 3.06 12.89 16 20.83 28.89 17.83 11.05-2.61 22.47-3.77 34-3.69 75.43 1.13 137.73 61.5 138.88 134.58.59 37.88-1.28 76.11-5.58 113.63-1.5 13.17 7.95 25.08 21.11 26.58 16.72 1.95 25.51-11.88 26.58-21.11a929.06 929.06 0 0 0 5.89-119.85c-1.56-98.75-85.07-180.33-186.16-181.83zm252.07 121.45c-2.86-12.92-15.51-21.2-28.61-18.27-12.94 2.86-21.12 15.66-18.26 28.61 4.71 21.41 4.91 37.41 4.7 61.6-.11 13.27 10.55 24.09 23.8 24.2h.2c13.17 0 23.89-10.61 24-23.8.18-22.18.4-44.11-5.83-72.34zm-40.12-90.72C417.29 43.46 337.6 1.29 252.81.02 183.02-.82 118.47 24.91 70.46 72.94 24.09 119.37-.9 181.04.14 246.65l-.12 21.47c-.39 13.25 10.03 24.31 23.28 24.69.23.02.48.02.72.02 12.92 0 23.59-10.3 23.97-23.3l.16-23.64c-.83-52.5 19.16-101.86 56.28-139 38.76-38.8 91.34-59.67 147.68-58.86 69.45 1.03 134.73 35.56 174.62 92.39 7.61 10.86 22.56 13.45 33.42 5.86 10.84-7.62 13.46-22.59 5.84-33.43z\"]\n  };\n  var faHistory = {\n    prefix: 'fas',\n    iconName: 'history',\n    icon: [512, 512, [], \"f1da\", \"M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z\"]\n  };\n  var faHome = {\n    prefix: 'fas',\n    iconName: 'home',\n    icon: [576, 512, [], \"f015\", \"M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z\"]\n  };\n  var faPlus = {\n    prefix: 'fas',\n    iconName: 'plus',\n    icon: [448, 512, [], \"f067\", \"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"]\n  };\n  var faRobot = {\n    prefix: 'fas',\n    iconName: 'robot',\n    icon: [640, 512, [], \"f544\", \"M32,224H64V416H32A31.96166,31.96166,0,0,1,0,384V256A31.96166,31.96166,0,0,1,32,224Zm512-48V448a64.06328,64.06328,0,0,1-64,64H160a64.06328,64.06328,0,0,1-64-64V176a79.974,79.974,0,0,1,80-80H288V32a32,32,0,0,1,64,0V96H464A79.974,79.974,0,0,1,544,176ZM264,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,264,256Zm-8,128H192v32h64Zm96,0H288v32h64ZM456,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,456,256Zm-8,128H384v32h64ZM640,256V384a31.96166,31.96166,0,0,1-32,32H576V224h32A31.96166,31.96166,0,0,1,640,256Z\"]\n  };\n  var faRocket = {\n    prefix: 'fas',\n    iconName: 'rocket',\n    icon: [512, 512, [], \"f135\", \"M505.12019,19.09375c-1.18945-5.53125-6.65819-11-12.207-12.1875C460.716,0,435.507,0,410.40747,0,307.17523,0,245.26909,55.20312,199.05238,128H94.83772c-16.34763.01562-35.55658,11.875-42.88664,26.48438L2.51562,253.29688A28.4,28.4,0,0,0,0,264a24.00867,24.00867,0,0,0,24.00582,24H127.81618l-22.47457,22.46875c-11.36521,11.36133-12.99607,32.25781,0,45.25L156.24582,406.625c11.15623,11.1875,32.15619,13.15625,45.27726,0l22.47457-22.46875V488a24.00867,24.00867,0,0,0,24.00581,24,28.55934,28.55934,0,0,0,10.707-2.51562l98.72834-49.39063c14.62888-7.29687,26.50776-26.5,26.50776-42.85937V312.79688c72.59753-46.3125,128.03493-108.40626,128.03493-211.09376C512.07526,76.5,512.07526,51.29688,505.12019,19.09375ZM384.04033,168A40,40,0,1,1,424.05,128,40.02322,40.02322,0,0,1,384.04033,168Z\"]\n  };\n  var faSave = {\n    prefix: 'fas',\n    iconName: 'save',\n    icon: [448, 512, [], \"f0c7\", \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"]\n  };\n  var faSlash = {\n    prefix: 'fas',\n    iconName: 'slash',\n    icon: [640, 512, [], \"f715\", \"M594.53 508.63L6.18 53.9c-6.97-5.42-8.23-15.47-2.81-22.45L23.01 6.18C28.43-.8 38.49-2.06 45.47 3.37L633.82 458.1c6.97 5.42 8.23 15.47 2.81 22.45l-19.64 25.27c-5.42 6.98-15.48 8.23-22.46 2.81z\"]\n  };\n  var faSpinnerThird = {\n    prefix: 'fas',\n    iconName: 'spinner-third',\n    icon: [512, 512, [], \"f3f4\", \"M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z\"]\n  };\n  var faSquareFull = {\n    prefix: 'fas',\n    iconName: 'square-full',\n    icon: [512, 512, [], \"f45c\", \"M512 512H0V0h512v512z\"]\n  };\n  var faTimes = {\n    prefix: 'fas',\n    iconName: 'times',\n    icon: [352, 512, [], \"f00d\", \"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\"]\n  };\n  var faTimesCircle = {\n    prefix: 'fas',\n    iconName: 'times-circle',\n    icon: [512, 512, [], \"f057\", \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"]\n  };\n  var faUndo = {\n    prefix: 'fas',\n    iconName: 'undo',\n    icon: [512, 512, [], \"f0e2\", \"M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z\"]\n  };\n  var faUndoAlt = {\n    prefix: 'fas',\n    iconName: 'undo-alt',\n    icon: [512, 512, [], \"f2ea\", \"M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z\"]\n  };\n  var faUser = {\n    prefix: 'fas',\n    iconName: 'user',\n    icon: [448, 512, [], \"f007\", \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"]\n  };\n  var faUsers = {\n    prefix: 'fas',\n    iconName: 'users',\n    icon: [640, 512, [], \"f0c0\", \"M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z\"]\n  };\n  var _iconsCache = {\n    faAlarmExclamation: faAlarmExclamation,\n    faAlignLeft: faAlignLeft,\n    faBookDead: faBookDead,\n    faCheck: faCheck,\n    faCircle: faCircle,\n    faCloud: faCloud,\n    faCreditCard: faCreditCard,\n    faDesktop: faDesktop,\n    faEnvelope: faEnvelope,\n    faEye: faEye,\n    faFingerprint: faFingerprint,\n    faHistory: faHistory,\n    faHome: faHome,\n    faPlus: faPlus,\n    faRobot: faRobot,\n    faRocket: faRocket,\n    faSave: faSave,\n    faSlash: faSlash,\n    faSpinnerThird: faSpinnerThird,\n    faSquareFull: faSquareFull,\n    faTimes: faTimes,\n    faTimesCircle: faTimesCircle,\n    faUndo: faUndo,\n    faUndoAlt: faUndoAlt,\n    faUser: faUser,\n    faUsers: faUsers\n  };\n\n  exports.fas = _iconsCache;\n  exports.prefix = prefix;\n  exports.faAlarmExclamation = faAlarmExclamation;\n  exports.faAlignLeft = faAlignLeft;\n  exports.faBookDead = faBookDead;\n  exports.faCheck = faCheck;\n  exports.faCircle = faCircle;\n  exports.faCloud = faCloud;\n  exports.faCreditCard = faCreditCard;\n  exports.faDesktop = faDesktop;\n  exports.faEnvelope = faEnvelope;\n  exports.faEye = faEye;\n  exports.faFingerprint = faFingerprint;\n  exports.faHistory = faHistory;\n  exports.faHome = faHome;\n  exports.faPlus = faPlus;\n  exports.faRobot = faRobot;\n  exports.faRocket = faRocket;\n  exports.faSave = faSave;\n  exports.faSlash = faSlash;\n  exports.faSpinnerThird = faSpinnerThird;\n  exports.faSquareFull = faSquareFull;\n  exports.faTimes = faTimes;\n  exports.faTimesCircle = faTimesCircle;\n  exports.faUndo = faUndo;\n  exports.faUndoAlt = faUndoAlt;\n  exports.faUser = faUser;\n  exports.faUsers = faUsers;\n\n  Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n"
  },
  {
    "path": "public/fonts/font-awesome/js-packages/@fortawesome/pro-solid-svg-icons/package.json",
    "content": "{\n  \"description\": \"The iconic font, CSS, and SVG framework\",\n  \"keywords\": [\n    \"font\",\n    \"awesome\",\n    \"fontawesome\",\n    \"icon\",\n    \"svg\",\n    \"bootstrap\"\n  ],\n  \"homepage\": \"https://fontawesome.com\",\n  \"bugs\": {\n    \"url\": \"http://github.com/FortAwesome/Font-Awesome/issues\"\n  },\n  \"author\": {\n    \"name\": \"Dave Gandy\",\n    \"email\": \"dave@fontawesome.com\",\n    \"web\": \"http://twitter.com/davegandy\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Brian Talbot\",\n      \"web\": \"http://twitter.com/talbs\"\n    },\n    {\n      \"name\": \"Travis Chase\",\n      \"web\": \"http://twitter.com/supercodepoet\"\n    },\n    {\n      \"name\": \"Rob Madole\",\n      \"web\": \"http://twitter.com/robmadole\"\n    },\n    {\n      \"name\": \"Geremia Taglialatela\",\n      \"web\": \"http://twitter.com/gtagliala\"\n    },\n    {\n      \"name\": \"Mike Wilkerson\",\n      \"web\": \"http://twitter.com/mw77\"\n    }\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/FortAwesome/Font-Awesome\"\n  },\n  \"engines\": {\n    \"node\": \">=6\"\n  },\n  \"dependencies\": {\n    \"@fortawesome/fontawesome-common-types\": \"^0.2.36\"\n  },\n  \"version\": \"5.15.4\",\n  \"name\": \"@fortawesome/pro-solid-svg-icons\",\n  \"main\": \"index.js\",\n  \"module\": \"index.es.js\",\n  \"jsnext:main\": \"index.es.js\",\n  \"license\": \"UNLICENSED\",\n  \"types\": \"./index.d.ts\",\n  \"sideEffects\": false,\n  \"scripts\": {\n    \"postinstall\": \"node attribution.js\"\n  }\n}"
  },
  {
    "path": "public/fonts/font-awesome/less/_animated.less",
    "content": "// Animated Icons\n// --------------------------\n\n.@{fa-css-prefix}-spin {\n  animation: fa-spin 2s infinite linear;\n}\n\n.@{fa-css-prefix}-pulse {\n  animation: fa-spin 1s infinite steps(8);\n}\n\n@keyframes fa-spin {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(360deg);\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_bordered-pulled.less",
    "content": "// Bordered & Pulled\n// -------------------------\n\n.@{fa-css-prefix}-border {\n  border-radius: .1em;\n  border: solid .08em @fa-border-color;\n  padding: .2em .25em .15em;\n}\n\n.@{fa-css-prefix}-pull-left { float: left; }\n.@{fa-css-prefix}-pull-right { float: right; }\n\n.@{fa-css-prefix}, .fas, .far, .fal, .fab {\n  &.@{fa-css-prefix}-pull-left { margin-right: .3em; }\n  &.@{fa-css-prefix}-pull-right { margin-left: .3em; }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_core.less",
    "content": "// Base Class Definition\n// -------------------------\n\n.@{fa-css-prefix}, .fas, .far, .fal, .fad, .fab {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  text-rendering: auto;\n  line-height: 1;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_fixed-width.less",
    "content": "// Fixed Width Icons\n// -------------------------\n.@{fa-css-prefix}-fw {\n  text-align: center;\n  width: (20em / 16);\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_icons.less",
    "content": "/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\n   readers do not read off random characters that represent icons */\n\n.@{fa-css-prefix}-abacus:before { content: @fa-var-abacus; }\n.@{fa-css-prefix}-alarm-exclamation:before { content: @fa-var-alarm-exclamation; }\n.@{fa-css-prefix}-align-left:before { content: @fa-var-align-left; }\n.@{fa-css-prefix}-align-slash:before { content: @fa-var-align-slash; }\n.@{fa-css-prefix}-atom-alt:before { content: @fa-var-atom-alt; }\n.@{fa-css-prefix}-aws:before { content: @fa-var-aws; }\n.@{fa-css-prefix}-badge-check:before { content: @fa-var-badge-check; }\n.@{fa-css-prefix}-bell:before { content: @fa-var-bell; }\n.@{fa-css-prefix}-book-dead:before { content: @fa-var-book-dead; }\n.@{fa-css-prefix}-books:before { content: @fa-var-books; }\n.@{fa-css-prefix}-brackets-curly:before { content: @fa-var-brackets-curly; }\n.@{fa-css-prefix}-cc-amazon-pay:before { content: @fa-var-cc-amazon-pay; }\n.@{fa-css-prefix}-cc-amex:before { content: @fa-var-cc-amex; }\n.@{fa-css-prefix}-cc-apple-pay:before { content: @fa-var-cc-apple-pay; }\n.@{fa-css-prefix}-cc-diners-club:before { content: @fa-var-cc-diners-club; }\n.@{fa-css-prefix}-cc-discover:before { content: @fa-var-cc-discover; }\n.@{fa-css-prefix}-cc-jcb:before { content: @fa-var-cc-jcb; }\n.@{fa-css-prefix}-cc-mastercard:before { content: @fa-var-cc-mastercard; }\n.@{fa-css-prefix}-cc-paypal:before { content: @fa-var-cc-paypal; }\n.@{fa-css-prefix}-cc-stripe:before { content: @fa-var-cc-stripe; }\n.@{fa-css-prefix}-cc-visa:before { content: @fa-var-cc-visa; }\n.@{fa-css-prefix}-chart-network:before { content: @fa-var-chart-network; }\n.@{fa-css-prefix}-chart-scatter:before { content: @fa-var-chart-scatter; }\n.@{fa-css-prefix}-check:before { content: @fa-var-check; }\n.@{fa-css-prefix}-check-circle:before { content: @fa-var-check-circle; }\n.@{fa-css-prefix}-circle:before { content: @fa-var-circle; }\n.@{fa-css-prefix}-cloud:before { content: @fa-var-cloud; }\n.@{fa-css-prefix}-clouds:before { content: @fa-var-clouds; }\n.@{fa-css-prefix}-cogs:before { content: @fa-var-cogs; }\n.@{fa-css-prefix}-comment-dots:before { content: @fa-var-comment-dots; }\n.@{fa-css-prefix}-concierge-bell:before { content: @fa-var-concierge-bell; }\n.@{fa-css-prefix}-credit-card:before { content: @fa-var-credit-card; }\n.@{fa-css-prefix}-desktop:before { content: @fa-var-desktop; }\n.@{fa-css-prefix}-discourse:before { content: @fa-var-discourse; }\n.@{fa-css-prefix}-docker:before { content: @fa-var-docker; }\n.@{fa-css-prefix}-dot-circle:before { content: @fa-var-dot-circle; }\n.@{fa-css-prefix}-envelope:before { content: @fa-var-envelope; }\n.@{fa-css-prefix}-exchange-alt:before { content: @fa-var-exchange-alt; }\n.@{fa-css-prefix}-eye:before { content: @fa-var-eye; }\n.@{fa-css-prefix}-file-alt:before { content: @fa-var-file-alt; }\n.@{fa-css-prefix}-file-code:before { content: @fa-var-file-code; }\n.@{fa-css-prefix}-fingerprint:before { content: @fa-var-fingerprint; }\n.@{fa-css-prefix}-github:before { content: @fa-var-github; }\n.@{fa-css-prefix}-globe:before { content: @fa-var-globe; }\n.@{fa-css-prefix}-globe-africa:before { content: @fa-var-globe-africa; }\n.@{fa-css-prefix}-globe-americas:before { content: @fa-var-globe-americas; }\n.@{fa-css-prefix}-globe-asia:before { content: @fa-var-globe-asia; }\n.@{fa-css-prefix}-globe-europe:before { content: @fa-var-globe-europe; }\n.@{fa-css-prefix}-graduation-cap:before { content: @fa-var-graduation-cap; }\n.@{fa-css-prefix}-history:before { content: @fa-var-history; }\n.@{fa-css-prefix}-home:before { content: @fa-var-home; }\n.@{fa-css-prefix}-info:before { content: @fa-var-info; }\n.@{fa-css-prefix}-info-circle:before { content: @fa-var-info-circle; }\n.@{fa-css-prefix}-instagram:before { content: @fa-var-instagram; }\n.@{fa-css-prefix}-key:before { content: @fa-var-key; }\n.@{fa-css-prefix}-key-skeleton:before { content: @fa-var-key-skeleton; }\n.@{fa-css-prefix}-laptop:before { content: @fa-var-laptop; }\n.@{fa-css-prefix}-laptop-code:before { content: @fa-var-laptop-code; }\n.@{fa-css-prefix}-laptop-house:before { content: @fa-var-laptop-house; }\n.@{fa-css-prefix}-life-ring:before { content: @fa-var-life-ring; }\n.@{fa-css-prefix}-lightbulb:before { content: @fa-var-lightbulb; }\n.@{fa-css-prefix}-list-alt:before { content: @fa-var-list-alt; }\n.@{fa-css-prefix}-list-ul:before { content: @fa-var-list-ul; }\n.@{fa-css-prefix}-lock-alt:before { content: @fa-var-lock-alt; }\n.@{fa-css-prefix}-map-marker-alt:before { content: @fa-var-map-marker-alt; }\n.@{fa-css-prefix}-microsoft:before { content: @fa-var-microsoft; }\n.@{fa-css-prefix}-moon-stars:before { content: @fa-var-moon-stars; }\n.@{fa-css-prefix}-network-wired:before { content: @fa-var-network-wired; }\n.@{fa-css-prefix}-planet-ringed:before { content: @fa-var-planet-ringed; }\n.@{fa-css-prefix}-plus:before { content: @fa-var-plus; }\n.@{fa-css-prefix}-question-circle:before { content: @fa-var-question-circle; }\n.@{fa-css-prefix}-quote-left:before { content: @fa-var-quote-left; }\n.@{fa-css-prefix}-random:before { content: @fa-var-random; }\n.@{fa-css-prefix}-rev:before { content: @fa-var-rev; }\n.@{fa-css-prefix}-robot:before { content: @fa-var-robot; }\n.@{fa-css-prefix}-rocket:before { content: @fa-var-rocket; }\n.@{fa-css-prefix}-save:before { content: @fa-var-save; }\n.@{fa-css-prefix}-search:before { content: @fa-var-search; }\n.@{fa-css-prefix}-server:before { content: @fa-var-server; }\n.@{fa-css-prefix}-sign-out:before { content: @fa-var-sign-out; }\n.@{fa-css-prefix}-siren-on:before { content: @fa-var-siren-on; }\n.@{fa-css-prefix}-slack:before { content: @fa-var-slack; }\n.@{fa-css-prefix}-slash:before { content: @fa-var-slash; }\n.@{fa-css-prefix}-smile:before { content: @fa-var-smile; }\n.@{fa-css-prefix}-snowman:before { content: @fa-var-snowman; }\n.@{fa-css-prefix}-spinner-third:before { content: @fa-var-spinner-third; }\n.@{fa-css-prefix}-square-full:before { content: @fa-var-square-full; }\n.@{fa-css-prefix}-sun:before { content: @fa-var-sun; }\n.@{fa-css-prefix}-tasks:before { content: @fa-var-tasks; }\n.@{fa-css-prefix}-times:before { content: @fa-var-times; }\n.@{fa-css-prefix}-times-circle:before { content: @fa-var-times-circle; }\n.@{fa-css-prefix}-twitter:before { content: @fa-var-twitter; }\n.@{fa-css-prefix}-undo:before { content: @fa-var-undo; }\n.@{fa-css-prefix}-undo-alt:before { content: @fa-var-undo-alt; }\n.@{fa-css-prefix}-university:before { content: @fa-var-university; }\n.@{fa-css-prefix}-user:before { content: @fa-var-user; }\n.@{fa-css-prefix}-user-friends:before { content: @fa-var-user-friends; }\n.@{fa-css-prefix}-user-hard-hat:before { content: @fa-var-user-hard-hat; }\n.@{fa-css-prefix}-user-shield:before { content: @fa-var-user-shield; }\n.@{fa-css-prefix}-users:before { content: @fa-var-users; }\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_larger.less",
    "content": "// Icon Sizes\n// -------------------------\n\n.larger(@factor) when (@factor > 0) {\n  .larger((@factor - 1));\n\n  .@{fa-css-prefix}-@{factor}x {\n    font-size: (@factor * 1em);\n  }\n}\n\n/* makes the font 33% larger relative to the icon container */\n.@{fa-css-prefix}-lg {\n  font-size: (4em / 3);\n  line-height: (3em / 4);\n  vertical-align: -.0667em;\n}\n\n.@{fa-css-prefix}-xs {\n  font-size: .75em;\n}\n\n.@{fa-css-prefix}-sm {\n  font-size: .875em;\n}\n\n.larger(10);\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_list.less",
    "content": "// List Icons\n// -------------------------\n\n.@{fa-css-prefix}-ul {\n  list-style-type: none;\n  margin-left: (@fa-li-width * 5/4);\n  padding-left: 0;\n\n  > li { position: relative; }\n}\n\n.@{fa-css-prefix}-li {\n  left: -@fa-li-width;\n  position: absolute;\n  text-align: center;\n  width: @fa-li-width;\n  line-height: inherit;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_mixins.less",
    "content": "// Mixins\n// --------------------------\n\n.fa-icon() {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  font-weight: normal;\n  line-height: 1;\n}\n\n.fa-icon-rotate(@degrees, @rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})\";\n  transform: rotate(@degrees);\n}\n\n.fa-icon-flip(@horiz, @vert, @rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)\";\n  transform: scale(@horiz, @vert);\n}\n\n\n// Only display content to screen readers. A la Bootstrap 4.\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only() {\n  border: 0;\n  clip: rect(0,0,0,0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable() {\n  &:active,\n  &:focus {\n    clip: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    position: static;\n    width: auto;\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_rotated-flipped.less",
    "content": "// Rotated & Flipped Icons\n// -------------------------\n\n.@{fa-css-prefix}-rotate-90  { .fa-icon-rotate(90deg, 1);  }\n.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }\n.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }\n\n.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }\n.@{fa-css-prefix}-flip-vertical   { .fa-icon-flip(1, -1, 2); }\n.@{fa-css-prefix}-flip-both, .@{fa-css-prefix}-flip-horizontal.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(-1, -1, 2); }\n\n// Hook for IE8-9\n// -------------------------\n\n:root {\n  .@{fa-css-prefix}-rotate-90,\n  .@{fa-css-prefix}-rotate-180,\n  .@{fa-css-prefix}-rotate-270,\n  .@{fa-css-prefix}-flip-horizontal,\n  .@{fa-css-prefix}-flip-vertical,\n  .@{fa-css-prefix}-flip-both {\n    filter: none;\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_screen-reader.less",
    "content": "// Screen Readers\n// -------------------------\n\n.sr-only { .sr-only(); }\n.sr-only-focusable { .sr-only-focusable(); }\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_stacked.less",
    "content": "// Stacked Icons\n// -------------------------\n\n.@{fa-css-prefix}-stack {\n  display: inline-block;\n  height: 2em;\n  line-height: 2em;\n  position: relative;\n  vertical-align: middle;\n  width: 2em;\n}\n\n.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {\n  left: 0;\n  position: absolute;\n  text-align: center;\n  width: 100%;\n}\n\n.@{fa-css-prefix}-stack-1x { line-height: inherit; }\n.@{fa-css-prefix}-stack-2x { font-size: 2em; }\n.@{fa-css-prefix}-inverse { color: @fa-inverse; }\n"
  },
  {
    "path": "public/fonts/font-awesome/less/_variables.less",
    "content": "// Variables\n// --------------------------\n\n@fa-font-path:         \"../webfonts\";\n@fa-font-size-base:    16px;\n@fa-font-display:      block;\n@fa-line-height-base:  1;\n@fa-css-prefix:        fa;\n@fa-version:           \"5.15.4\";\n@fa-border-color:      #eee;\n@fa-inverse:           #fff;\n@fa-li-width:          2em;\n@fa-primary-opacity:   1;\n@fa-secondary-opacity: .4;\n\n@fa-var-abacus: \"\\f640\";\n@fa-var-alarm-exclamation: \"\\f843\";\n@fa-var-align-left: \"\\f036\";\n@fa-var-align-slash: \"\\f846\";\n@fa-var-atom-alt: \"\\f5d3\";\n@fa-var-aws: \"\\f375\";\n@fa-var-badge-check: \"\\f336\";\n@fa-var-bell: \"\\f0f3\";\n@fa-var-book-dead: \"\\f6b7\";\n@fa-var-books: \"\\f5db\";\n@fa-var-brackets-curly: \"\\f7ea\";\n@fa-var-cc-amazon-pay: \"\\f42d\";\n@fa-var-cc-amex: \"\\f1f3\";\n@fa-var-cc-apple-pay: \"\\f416\";\n@fa-var-cc-diners-club: \"\\f24c\";\n@fa-var-cc-discover: \"\\f1f2\";\n@fa-var-cc-jcb: \"\\f24b\";\n@fa-var-cc-mastercard: \"\\f1f1\";\n@fa-var-cc-paypal: \"\\f1f4\";\n@fa-var-cc-stripe: \"\\f1f5\";\n@fa-var-cc-visa: \"\\f1f0\";\n@fa-var-chart-network: \"\\f78a\";\n@fa-var-chart-scatter: \"\\f7ee\";\n@fa-var-check: \"\\f00c\";\n@fa-var-check-circle: \"\\f058\";\n@fa-var-circle: \"\\f111\";\n@fa-var-cloud: \"\\f0c2\";\n@fa-var-clouds: \"\\f744\";\n@fa-var-cogs: \"\\f085\";\n@fa-var-comment-dots: \"\\f4ad\";\n@fa-var-concierge-bell: \"\\f562\";\n@fa-var-credit-card: \"\\f09d\";\n@fa-var-desktop: \"\\f108\";\n@fa-var-discourse: \"\\f393\";\n@fa-var-docker: \"\\f395\";\n@fa-var-dot-circle: \"\\f192\";\n@fa-var-envelope: \"\\f0e0\";\n@fa-var-exchange-alt: \"\\f362\";\n@fa-var-eye: \"\\f06e\";\n@fa-var-file-alt: \"\\f15c\";\n@fa-var-file-code: \"\\f1c9\";\n@fa-var-fingerprint: \"\\f577\";\n@fa-var-github: \"\\f09b\";\n@fa-var-globe: \"\\f0ac\";\n@fa-var-globe-africa: \"\\f57c\";\n@fa-var-globe-americas: \"\\f57d\";\n@fa-var-globe-asia: \"\\f57e\";\n@fa-var-globe-europe: \"\\f7a2\";\n@fa-var-graduation-cap: \"\\f19d\";\n@fa-var-history: \"\\f1da\";\n@fa-var-home: \"\\f015\";\n@fa-var-info: \"\\f129\";\n@fa-var-info-circle: \"\\f05a\";\n@fa-var-instagram: \"\\f16d\";\n@fa-var-key: \"\\f084\";\n@fa-var-key-skeleton: \"\\f6f3\";\n@fa-var-laptop: \"\\f109\";\n@fa-var-laptop-code: \"\\f5fc\";\n@fa-var-laptop-house: \"\\e066\";\n@fa-var-life-ring: \"\\f1cd\";\n@fa-var-lightbulb: \"\\f0eb\";\n@fa-var-list-alt: \"\\f022\";\n@fa-var-list-ul: \"\\f0ca\";\n@fa-var-lock-alt: \"\\f30d\";\n@fa-var-map-marker-alt: \"\\f3c5\";\n@fa-var-microsoft: \"\\f3ca\";\n@fa-var-moon-stars: \"\\f755\";\n@fa-var-network-wired: \"\\f6ff\";\n@fa-var-planet-ringed: \"\\e020\";\n@fa-var-plus: \"\\f067\";\n@fa-var-question-circle: \"\\f059\";\n@fa-var-quote-left: \"\\f10d\";\n@fa-var-random: \"\\f074\";\n@fa-var-rev: \"\\f5b2\";\n@fa-var-robot: \"\\f544\";\n@fa-var-rocket: \"\\f135\";\n@fa-var-save: \"\\f0c7\";\n@fa-var-search: \"\\f002\";\n@fa-var-server: \"\\f233\";\n@fa-var-sign-out: \"\\f08b\";\n@fa-var-siren-on: \"\\e02e\";\n@fa-var-slack: \"\\f198\";\n@fa-var-slash: \"\\f715\";\n@fa-var-smile: \"\\f118\";\n@fa-var-snowman: \"\\f7d0\";\n@fa-var-spinner-third: \"\\f3f4\";\n@fa-var-square-full: \"\\f45c\";\n@fa-var-sun: \"\\f185\";\n@fa-var-tasks: \"\\f0ae\";\n@fa-var-times: \"\\f00d\";\n@fa-var-times-circle: \"\\f057\";\n@fa-var-twitter: \"\\f099\";\n@fa-var-undo: \"\\f0e2\";\n@fa-var-undo-alt: \"\\f2ea\";\n@fa-var-university: \"\\f19c\";\n@fa-var-user: \"\\f007\";\n@fa-var-user-friends: \"\\f500\";\n@fa-var-user-hard-hat: \"\\f82c\";\n@fa-var-user-shield: \"\\f505\";\n@fa-var-users: \"\\f0c0\";\n"
  },
  {
    "path": "public/fonts/font-awesome/less/brands.less",
    "content": "@import \"_variables.less\";\n\n@font-face {\n  font-family: 'Font Awesome 5 Brands';\n  font-style: normal;\n  font-weight: 400;\n  font-display: @fa-font-display;\n  src: url('@{fa-font-path}/fa-brands-400.eot');\n  src: url('@{fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'),\n    url('@{fa-font-path}/fa-brands-400.woff2') format('woff2'),\n    url('@{fa-font-path}/fa-brands-400.woff') format('woff'),\n    url('@{fa-font-path}/fa-brands-400.ttf') format('truetype'),\n    url('@{fa-font-path}/fa-brands-400.svg#fontawesome') format('svg');\n}\n\n.fab {\n  font-family: 'Font Awesome 5 Brands';\n  font-weight: 400;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/less/duotone.less",
    "content": "@import \"_variables.less\";\n\n@font-face {\n  font-family: 'Font Awesome 5 Duotone';\n  font-style: normal;\n  font-weight: 900;\n  font-display: @fa-font-display;\n  src: url('@{fa-font-path}/fa-duotone-900.eot');\n  src: url('@{fa-font-path}/fa-duotone-900.eot?#iefix') format('embedded-opentype'),\n    url('@{fa-font-path}/fa-duotone-900.woff2') format('woff2'),\n    url('@{fa-font-path}/fa-duotone-900.woff') format('woff'),\n    url('@{fa-font-path}/fa-duotone-900.ttf') format('truetype'),\n    url('@{fa-font-path}/fa-duotone-900.svg#fontawesome') format('svg');\n}\n\n.fad {\n  position: relative;\n  font-family: 'Font Awesome 5 Duotone';\n  font-weight: 900;\n}\n\n.fad:before {\n  position: absolute;\n  color: ~'var(--@{fa-css-prefix}-primary-color, inherit)';\n  opacity: @fa-primary-opacity;\n  opacity: ~'var(--@{fa-css-prefix}-primary-opacity, @{fa-primary-opacity})';\n}\n\n.fad:after {\n  color: ~'var(--@{fa-css-prefix}-secondary-color, inherit)';\n  opacity: @fa-secondary-opacity;\n  opacity: ~'var(--@{fa-css-prefix}-secondary-opacity, @{fa-secondary-opacity})';\n}\n\n.@{fa-css-prefix}-swap-opacity .fad:before,\n.fad.@{fa-css-prefix}-swap-opacity:before {\n  opacity: @fa-secondary-opacity;\n  opacity: ~'var(--@{fa-css-prefix}-secondary-opacity, @{fa-secondary-opacity})';\n}\n\n.@{fa-css-prefix}-swap-opacity .fad:after,\n.fad.@{fa-css-prefix}-swap-opacity:after {\n  opacity: @fa-primary-opacity;\n  opacity: ~'var(--@{fa-css-prefix}-primary-opacity, @{fa-primary-opacity})';\n}\n\n.fad.@{fa-css-prefix}-inverse {\n  color: @fa-inverse;\n}\n\n.fad.@{fa-css-prefix}-stack-1x, .fad.@{fa-css-prefix}-stack-2x {\n  position: absolute;\n}\n\n.fad.@{fa-css-prefix}-stack-1x:before,\n.fad.@{fa-css-prefix}-stack-2x:before,\n.fad.@{fa-css-prefix}-fw:before {\n  left: 50%;\n  transform: translateX(-50%);\n}\n\n.fad.@{fa-css-prefix}-abacus:after { content: \"\\10f640\"; }\n.fad.@{fa-css-prefix}-align-slash:after { content: \"\\10f846\"; }\n.fad.@{fa-css-prefix}-atom-alt:after { content: \"\\10f5d3\"; }\n.fad.@{fa-css-prefix}-badge-check:after { content: \"\\10f336\"; }\n.fad.@{fa-css-prefix}-bell:after { content: \"\\10f0f3\"; }\n.fad.@{fa-css-prefix}-books:after { content: \"\\10f5db\"; }\n.fad.@{fa-css-prefix}-brackets-curly:after { content: \"\\10f7ea\"; }\n.fad.@{fa-css-prefix}-chart-network:after { content: \"\\10f78a\"; }\n.fad.@{fa-css-prefix}-chart-scatter:after { content: \"\\10f7ee\"; }\n.fad.@{fa-css-prefix}-check:after { content: \"\\10f00c\"; }\n.fad.@{fa-css-prefix}-circle:after { content: \"\\10f111\"; }\n.fad.@{fa-css-prefix}-clouds:after { content: \"\\10f744\"; }\n.fad.@{fa-css-prefix}-cogs:after { content: \"\\10f085\"; }\n.fad.@{fa-css-prefix}-comment-dots:after { content: \"\\10f4ad\"; }\n.fad.@{fa-css-prefix}-concierge-bell:after { content: \"\\10f562\"; }\n.fad.@{fa-css-prefix}-dot-circle:after { content: \"\\10f192\"; }\n.fad.@{fa-css-prefix}-envelope:after { content: \"\\10f0e0\"; }\n.fad.@{fa-css-prefix}-exchange-alt:after { content: \"\\10f362\"; }\n.fad.@{fa-css-prefix}-file-alt:after { content: \"\\10f15c\"; }\n.fad.@{fa-css-prefix}-file-code:after { content: \"\\10f1c9\"; }\n.fad.@{fa-css-prefix}-globe:after { content: \"\\10f0ac\"; }\n.fad.@{fa-css-prefix}-globe-africa:after { content: \"\\10f57c\"; }\n.fad.@{fa-css-prefix}-globe-americas:after { content: \"\\10f57d\"; }\n.fad.@{fa-css-prefix}-globe-asia:after { content: \"\\10f57e\"; }\n.fad.@{fa-css-prefix}-globe-europe:after { content: \"\\10f7a2\"; }\n.fad.@{fa-css-prefix}-graduation-cap:after { content: \"\\10f19d\"; }\n.fad.@{fa-css-prefix}-history:after { content: \"\\10f1da\"; }\n.fad.@{fa-css-prefix}-key:after { content: \"\\10f084\"; }\n.fad.@{fa-css-prefix}-key-skeleton:after { content: \"\\10f6f3\"; }\n.fad.@{fa-css-prefix}-laptop:after { content: \"\\10f109\"; }\n.fad.@{fa-css-prefix}-laptop-code:after { content: \"\\10f5fc\"; }\n.fad.@{fa-css-prefix}-laptop-house:after { content: \"\\10e066\"; }\n.fad.@{fa-css-prefix}-life-ring:after { content: \"\\10f1cd\"; }\n.fad.@{fa-css-prefix}-lightbulb:after { content: \"\\10f0eb\"; }\n.fad.@{fa-css-prefix}-list-alt:after { content: \"\\10f022\"; }\n.fad.@{fa-css-prefix}-list-ul:after { content: \"\\10f0ca\"; }\n.fad.@{fa-css-prefix}-lock-alt:after { content: \"\\10f30d\"; }\n.fad.@{fa-css-prefix}-map-marker-alt:after { content: \"\\10f3c5\"; }\n.fad.@{fa-css-prefix}-moon-stars:after { content: \"\\10f755\"; }\n.fad.@{fa-css-prefix}-network-wired:after { content: \"\\10f6ff\"; }\n.fad.@{fa-css-prefix}-planet-ringed:after { content: \"\\10e020\"; }\n.fad.@{fa-css-prefix}-question-circle:after { content: \"\\10f059\"; }\n.fad.@{fa-css-prefix}-quote-left:after { content: \"\\10f10d\"; }\n.fad.@{fa-css-prefix}-random:after { content: \"\\10f074\"; }\n.fad.@{fa-css-prefix}-rocket:after { content: \"\\10f135\"; }\n.fad.@{fa-css-prefix}-search:after { content: \"\\10f002\"; }\n.fad.@{fa-css-prefix}-server:after { content: \"\\10f233\"; }\n.fad.@{fa-css-prefix}-sign-out:after { content: \"\\10f08b\"; }\n.fad.@{fa-css-prefix}-siren-on:after { content: \"\\10e02e\"; }\n.fad.@{fa-css-prefix}-smile:after { content: \"\\10f118\"; }\n.fad.@{fa-css-prefix}-snowman:after { content: \"\\10f7d0\"; }\n.fad.@{fa-css-prefix}-sun:after { content: \"\\10f185\"; }\n.fad.@{fa-css-prefix}-tasks:after { content: \"\\10f0ae\"; }\n.fad.@{fa-css-prefix}-university:after { content: \"\\10f19c\"; }\n.fad.@{fa-css-prefix}-user:after { content: \"\\10f007\"; }\n.fad.@{fa-css-prefix}-user-hard-hat:after { content: \"\\10f82c\"; }\n.fad.@{fa-css-prefix}-user-shield:after { content: \"\\10f505\"; }\n.fad.@{fa-css-prefix}-users:after { content: \"\\10f0c0\"; }\n"
  },
  {
    "path": "public/fonts/font-awesome/less/fontawesome.less",
    "content": "@import \"_variables.less\";\n@import \"_mixins.less\";\n@import \"_core.less\";\n@import \"_larger.less\";\n@import \"_fixed-width.less\";\n@import \"_list.less\";\n@import \"_bordered-pulled.less\";\n@import \"_animated.less\";\n@import \"_rotated-flipped.less\";\n@import \"_stacked.less\";\n@import \"_icons.less\";\n@import \"_screen-reader.less\";\n"
  },
  {
    "path": "public/fonts/font-awesome/less/regular.less",
    "content": "@import \"_variables.less\";\n\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 400;\n  font-display: @fa-font-display;\n  src: url('@{fa-font-path}/fa-regular-400.eot');\n  src: url('@{fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'),\n    url('@{fa-font-path}/fa-regular-400.woff2') format('woff2'),\n    url('@{fa-font-path}/fa-regular-400.woff') format('woff'),\n    url('@{fa-font-path}/fa-regular-400.ttf') format('truetype'),\n    url('@{fa-font-path}/fa-regular-400.svg#fontawesome') format('svg');\n}\n\n.far {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 400;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/less/solid.less",
    "content": "@import \"_variables.less\";\n\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 900;\n  font-display: @fa-font-display;\n  src: url('@{fa-font-path}/fa-solid-900.eot');\n  src: url('@{fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'),\n    url('@{fa-font-path}/fa-solid-900.woff2') format('woff2'),\n    url('@{fa-font-path}/fa-solid-900.woff') format('woff'),\n    url('@{fa-font-path}/fa-solid-900.ttf') format('truetype'),\n    url('@{fa-font-path}/fa-solid-900.svg#fontawesome') format('svg');\n}\n\n.fa,\n.fas {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 900;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/metadata/categories.yml",
    "content": "accessibility:\n  icons:\n    - question-circle\n  label: Accessibility\nalert:\n  icons:\n    - alarm-exclamation\n    - bell\n  label: Alert\nanimals:\n  icons: []\n  label: Animals\narrows:\n  icons:\n    - exchange-alt\n    - history\n    - random\n    - sign-out\n    - undo\n    - undo-alt\n  label: Arrows\naudio-video:\n  icons:\n    - circle\n    - random\n    - undo\n    - undo-alt\n  label: Audio & Video\nautomotive:\n  icons: []\n  label: Automotive\nautumn:\n  icons: []\n  label: Autumn\nbeverage:\n  icons: []\n  label: Beverage\nbuildings:\n  icons:\n    - home\n    - university\n  label: Buildings\nbusiness:\n  icons:\n    - badge-check\n    - chart-network\n    - chart-scatter\n    - envelope\n    - file-alt\n    - globe\n    - laptop-house\n    - save\n    - tasks\n  label: Business\ncamping:\n  icons: []\n  label: Camping\ncharity:\n  icons:\n    - globe\n  label: Charity\nchat:\n  icons:\n    - comment-dots\n    - quote-left\n    - smile\n  label: Chat\nchess:\n  icons:\n    - square-full\n  label: Chess\nchildhood:\n  icons:\n    - robot\n    - snowman\n  label: Childhood\nclothing:\n  icons:\n    - graduation-cap\n  label: Clothing\ncode:\n  icons:\n    - brackets-curly\n    - file-alt\n    - file-code\n    - laptop-code\n  label: Code\ncommunication:\n  icons:\n    - bell\n    - envelope\n  label: Communication\ncomputers:\n  icons:\n    - brackets-curly\n    - desktop\n    - laptop\n    - laptop-house\n    - save\n    - server\n  label: Computers\nconstruction:\n  icons:\n    - user-hard-hat\n  label: Construction\ncurrency:\n  icons: []\n  label: Currency\ndate-time:\n  icons:\n    - alarm-exclamation\n    - bell\n  label: Date & Time\ndesign:\n  icons:\n    - eye\n    - save\n  label: Design\neditors:\n  icons:\n    - align-left\n    - align-slash\n    - file-alt\n    - list-alt\n    - list-ul\n    - quote-left\n    - tasks\n    - undo\n    - undo-alt\n  label: Editors\neducation:\n  icons:\n    - atom-alt\n    - bell\n    - books\n    - graduation-cap\n    - laptop-code\n  label: Education\nemoji:\n  icons:\n    - smile\n  label: Emoji\nenergy:\n  icons:\n    - atom-alt\n    - lightbulb\n    - sun\n  label: Energy\nfiles:\n  icons:\n    - file-alt\n    - file-code\n    - save\n  label: Files\nfinance:\n  icons:\n    - credit-card\n  label: Finance\nfitness:\n  icons: []\n  label: Fitness\nfood:\n  icons: []\n  label: Food\nfruit-vegetable:\n  icons: []\n  label: Fruits & Vegetables\ngames:\n  icons: []\n  label: Games\ngaming-tabletop:\n  icons:\n    - book-dead\n  label: Tabletop Gaming\ngender:\n  icons: []\n  label: Genders\nhalloween:\n  icons:\n    - book-dead\n    - key-skeleton\n  label: Halloween\nhands:\n  icons: []\n  label: Hands\nhealth:\n  icons: []\n  label: Health\nholiday:\n  icons:\n    - snowman\n  label: Holiday\nhotel:\n  icons:\n    - concierge-bell\n    - key\n  label: Hotel\nhousehold:\n  icons:\n    - bell\n    - books\n    - laptop-house\n    - lightbulb\n    - siren-on\n  label: Household\nimages:\n  icons:\n    - eye\n  label: Images\ninterfaces:\n  icons:\n    - badge-check\n    - bell\n    - check\n    - check-circle\n    - circle\n    - cloud\n    - cogs\n    - dot-circle\n    - envelope\n    - eye\n    - file-alt\n    - fingerprint\n    - history\n    - home\n    - info\n    - info-circle\n    - plus\n    - question-circle\n    - quote-left\n    - save\n    - search\n    - sign-out\n    - smile\n    - times\n    - times-circle\n    - undo\n    - undo-alt\n    - user\n  label: Interfaces\nlogistics:\n  icons:\n    - user-hard-hat\n  label: Logistics\nmaps:\n  icons:\n    - bell\n    - eye\n    - globe\n    - graduation-cap\n    - home\n    - info\n    - info-circle\n    - key\n    - life-ring\n    - lightbulb\n    - map-marker-alt\n    - plus\n    - rocket\n    - search\n    - university\n  label: Maps\nmaritime:\n  icons: []\n  label: Maritime\nmarketing:\n  icons:\n    - badge-check\n    - lightbulb\n  label: Marketing\nmathematics:\n  icons:\n    - abacus\n    - plus\n    - times\n  label: Mathematics\nmedical:\n  icons:\n    - plus\n  label: Medical\nmoving:\n  icons: []\n  label: Moving\nmusic:\n  icons: []\n  label: Music\nobjects:\n  icons:\n    - bell\n    - book-dead\n    - cloud\n    - cogs\n    - envelope\n    - eye\n    - file-alt\n    - globe\n    - graduation-cap\n    - home\n    - key\n    - laptop\n    - life-ring\n    - lightbulb\n    - lock-alt\n    - map-marker-alt\n    - rocket\n    - save\n    - search\n    - sun\n    - university\n  label: Objects\npayments-shopping:\n  icons:\n    - badge-check\n    - bell\n    - cc-amazon-pay\n    - cc-amex\n    - cc-apple-pay\n    - cc-diners-club\n    - cc-discover\n    - cc-jcb\n    - cc-mastercard\n    - cc-paypal\n    - cc-stripe\n    - cc-visa\n    - credit-card\n    - key\n  label: Payments & Shopping\npharmacy:\n  icons:\n    - history\n  label: Pharmacy\npolitical:\n  icons: []\n  label: Political\nreligion:\n  icons: []\n  label: Religion\nscience:\n  icons:\n    - atom-alt\n    - chart-network\n    - chart-scatter\n    - key-skeleton\n  label: Science\nscience-fiction:\n  icons:\n    - atom-alt\n    - globe\n    - moon-stars\n    - planet-ringed\n    - robot\n    - rocket\n  label: Science Fiction\nsecurity:\n  icons:\n    - eye\n    - fingerprint\n    - key\n    - key-skeleton\n    - lock-alt\n    - siren-on\n    - user-shield\n  label: Security\nshapes:\n  icons:\n    - circle\n    - cloud\n  label: Shapes\nshopping:\n  icons:\n    - badge-check\n  label: Shopping\nsocial:\n  icons:\n    - bell\n    - envelope\n    - map-marker-alt\n    - user\n    - user-friends\n    - users\n  label: Social\nspinners:\n  icons:\n    - atom-alt\n    - life-ring\n    - slash\n    - spinner-third\n    - sun\n  label: Spinners\nsports:\n  icons: []\n  label: Sports\nspring:\n  icons: []\n  label: Spring\nstatus:\n  icons:\n    - badge-check\n    - bell\n    - eye\n    - file-alt\n    - info\n    - info-circle\n    - lightbulb\n    - lock-alt\n    - map-marker-alt\n    - plus\n    - question-circle\n    - sign-out\n    - user\n  label: Status\nsummer:\n  icons:\n    - sun\n  label: Summer\ntoggle:\n  icons:\n    - check-circle\n    - circle\n    - dot-circle\n  label: Toggle\ntravel:\n  icons:\n    - concierge-bell\n    - globe-africa\n    - globe-americas\n    - globe-asia\n    - globe-europe\n  label: Travel\nusers-people:\n  icons:\n    - smile\n    - user\n    - user-friends\n    - user-hard-hat\n    - user-shield\n    - users\n  label: Users & People\nvehicles:\n  icons:\n    - rocket\n  label: Vehicles\nweather:\n  icons:\n    - cloud\n    - clouds\n    - moon-stars\n    - sun\n  label: Weather\nwinter:\n  icons: []\n  label: Winter\nwriting:\n  icons:\n    - envelope\n    - file-alt\n    - quote-left\n  label: Writing\n"
  },
  {
    "path": "public/fonts/font-awesome/metadata/icons.json",
    "content": "{\n  \"abacus\": {\n    \"changes\": [\n      \"5.3.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"addition\",\n        \"ancient\",\n        \"arithmetic\",\n        \"calculator\",\n        \"counting\",\n        \"hexadecimal\",\n        \"math\",\n        \"subtraction\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f640\",\n    \"label\": \"Abacus\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M192 440h-32v-48h32zM160 72v48h32V72zm96 160v48h32v-48zm-96 0v48h32v-48zm96 208h160v-48H256zm96-160h128v-48H352zM544 0a32 32 0 0 0-32 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32a32 32 0 0 0-32-32zM416 72H256v48h160zM32 0A32 32 0 0 0 0 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32A32 32 0 0 0 32 0z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M144 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm-96 160h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm192 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm-96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zM464 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM144 352h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm224 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": [\n          \"M192 440h-32v-48h32zM160 72v48h32V72zm96 160v48h32v-48zm-96 0v48h32v-48zm96 208h160v-48H256zm96-160h128v-48H352zM544 0a32 32 0 0 0-32 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32a32 32 0 0 0-32-32zM416 72H256v48h160zM32 0A32 32 0 0 0 0 32v464a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V32A32 32 0 0 0 32 0z\",\n          \"M144 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zm-96 160h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm192 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm-96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zM464 32h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16zM144 352h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm96 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16zm224 0h-32a16 16 0 0 0-16 16v96a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16v-96a16 16 0 0 0-16-16z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"alarm-exclamation\": {\n    \"changes\": [\n      \"5.9.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"alert\",\n        \"date\",\n        \"late\",\n        \"reminder\",\n        \"sleep\",\n        \"snooze\",\n        \"timer\",\n        \"timestamp\",\n        \"watch\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f843\",\n    \"label\": \"Alarm Exclamation\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M96 0A96 96 0 0 0 0 96a94.81 94.81 0 0 0 15.3 51.26L161.2 25.68A95.63 95.63 0 0 0 96 0zm320 0a95.66 95.66 0 0 0-65.18 25.66l145.89 121.57A94.85 94.85 0 0 0 512 96a96 96 0 0 0-96-96zM256 64C132.3 64 32 164.29 32 288a222.7 222.7 0 0 0 44.79 134l-40.1 40.09a16 16 0 0 0 0 22.63l22.62 22.62a16 16 0 0 0 22.63 0L122 467.22a222.82 222.82 0 0 0 268 0l40.1 40.09a16 16 0 0 0 22.62 0l22.63-22.62a16 16 0 0 0 0-22.63L435.25 422A222.69 222.69 0 0 0 480 288c0-123.71-100.26-224-224-224zm0 352a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm25.4-110.4a16 16 0 0 1-15.9 14.4h-19a16 16 0 0 1-15.9-14.4l-12.8-128a16.06 16.06 0 0 1 15.9-17.6h44.6a16 16 0 0 1 15.9 17.6z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M96 0A96 96 0 0 0 0 96a94.81 94.81 0 0 0 15.3 51.26L161.2 25.68A95.63 95.63 0 0 0 96 0zm320 0a95.66 95.66 0 0 0-65.18 25.66l145.89 121.57A94.85 94.85 0 0 0 512 96a96 96 0 0 0-96-96zM256 64C132.3 64 32 164.29 32 288a222.7 222.7 0 0 0 44.79 134l-40.1 40.09a16 16 0 0 0 0 22.63l22.62 22.62a16 16 0 0 0 22.63 0L122 467.22a222.82 222.82 0 0 0 268 0l40.1 40.09a16 16 0 0 0 22.62 0l22.63-22.62a16 16 0 0 0 0-22.63L435.25 422A222.69 222.69 0 0 0 480 288c0-123.71-100.26-224-224-224zm0 352a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm25.4-110.4a16 16 0 0 1-15.9 14.4h-19a16 16 0 0 1-15.9-14.4l-12.8-128a16.06 16.06 0 0 1 15.9-17.6h44.6a16 16 0 0 1 15.9 17.6z\"\n      }\n    },\n    \"free\": []\n  },\n  \"align-left\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\",\n      \"5.9.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"format\",\n        \"paragraph\",\n        \"text\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f036\",\n    \"label\": \"align-left\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M12.83 352h262.34A12.82 12.82 0 0 0 288 339.17v-38.34A12.82 12.82 0 0 0 275.17 288H12.83A12.82 12.82 0 0 0 0 300.83v38.34A12.82 12.82 0 0 0 12.83 352zm0-256h262.34A12.82 12.82 0 0 0 288 83.17V44.83A12.82 12.82 0 0 0 275.17 32H12.83A12.82 12.82 0 0 0 0 44.83v38.34A12.82 12.82 0 0 0 12.83 96zM432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M12.83 352h262.34A12.82 12.82 0 0 0 288 339.17v-38.34A12.82 12.82 0 0 0 275.17 288H12.83A12.82 12.82 0 0 0 0 300.83v38.34A12.82 12.82 0 0 0 12.83 352zm0-256h262.34A12.82 12.82 0 0 0 288 83.17V44.83A12.82 12.82 0 0 0 275.17 32H12.83A12.82 12.82 0 0 0 0 44.83v38.34A12.82 12.82 0 0 0 12.83 96zM432 160H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0 256H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h416a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"align-slash\": {\n    \"changes\": [\n      \"5.9.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"cancel\",\n        \"format\",\n        \"paragraph\",\n        \"remove\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f846\",\n    \"label\": \"Align Slash\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M528 352h-31.46l-82.81-64H528a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16zM96 304v32a16 16 0 0 0 16 16h175.21l-82.8-64H112a16 16 0 0 0-16 16zM528 96a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16H112a15.82 15.82 0 0 0-15 11.18L165.31 96zM112 416a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h340.83L370 416zm416-256H248.12l82.81 64H528a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M633.82 458.1L45.46 3.38A16 16 0 0 0 23 6.19L3.37 31.46a16 16 0 0 0 2.81 22.45l588.36 454.72a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M528 352h-31.46l-82.81-64H528a16 16 0 0 1 16 16v32a16 16 0 0 1-16 16zM96 304v32a16 16 0 0 0 16 16h175.21l-82.8-64H112a16 16 0 0 0-16 16zM528 96a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16H112a15.82 15.82 0 0 0-15 11.18L165.31 96zM112 416a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h340.83L370 416zm416-256H248.12l82.81 64H528a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\",\n          \"M633.82 458.1L45.46 3.38A16 16 0 0 0 23 6.19L3.37 31.46a16 16 0 0 0 2.81 22.45l588.36 454.72a16 16 0 0 0 22.46-2.81l19.64-25.27a16 16 0 0 0-2.82-22.45z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"atom-alt\": {\n    \"changes\": [\n      \"5.2.0\",\n      \"5.12.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"atheism\",\n        \"chemistry\",\n        \"electron\",\n        \"ion\",\n        \"isotope\",\n        \"neutron\",\n        \"nuclear\",\n        \"proton\",\n        \"science\",\n        \"space\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f5d3\",\n    \"label\": \"Atom Alt\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M424.37305,55.69141C408.294,39.61914,385.50879,32,358.58252,32,319.82764,32,272.43359,48.127,224,77.14453a493.86641,493.86641,0,0,0-58.042,41.03711C140.58252,138.875,114.57666,162.5918,85.75635,197.916a374.25237,374.25237,0,0,0,35.70263,58.082A505.23427,505.23427,0,0,1,224,153.65625a377.23937,377.23937,0,0,1,58.042-35.47266c70.01221-34.334,95.22461-19.07421,97.0625-17.23632,9.54248,9.543,7.67432,46.94531-16.86084,96.96875A492.27615,492.27615,0,0,1,403.06543,256C452.27637,173.91992,463.59277,94.90039,424.37305,55.69141ZM224,358.3418a377.44678,377.44678,0,0,1-58.042,35.47461c-70.01221,34.334-95.22461,19.07421-97.0625,17.23632-9.54248-9.543-7.67432-46.94335,16.86084-96.96875A492.27615,492.27615,0,0,1,44.93457,256C-4.27637,338.08008-15.59277,417.09961,23.627,456.30664,39.70605,472.38086,62.49121,480,89.41748,480c38.75488,0,86.14893-16.127,134.58252-45.14453a493.86641,493.86641,0,0,0,58.042-41.03711c25.38965-20.70508,51.42285-44.45606,80.20166-79.73438A373.962,373.962,0,0,0,326.541,256,505.23427,505.23427,0,0,1,224,358.3418Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M224,287.98828a31.99414,31.99414,0,1,0-32-31.99414A31.98908,31.98908,0,0,0,224,287.98828ZM121.46094,255.99805A374.13921,374.13921,0,0,1,85.7583,197.916c-24.53906-50.02344-26.40625-87.42579-16.86328-96.9668,1.83984-1.83789,27.05078-17.10156,97.062,17.23242A494.241,494.241,0,0,1,224,77.14453C175.5625,48.13086,128.16406,32,89.41846,32c-26.9336,0-49.707,7.61523-65.793,23.69141C-15.59326,94.90039-4.27686,173.91992,44.93408,256A492.0174,492.0174,0,0,0,85.7583,314.084c28.79639,35.30274,54.85889,59.07227,80.19873,79.73243A377.429,377.429,0,0,0,224,358.3418,505.131,505.131,0,0,1,121.46094,255.99805ZM403.06592,256a492.0174,492.0174,0,0,0-40.82422-58.084c-28.84326-35.35547-54.89795-59.10352-80.19873-79.73243A377.4073,377.4073,0,0,0,224,153.65625,505.20556,505.20556,0,0,1,326.53906,256a373.849,373.849,0,0,1,35.70264,58.084c24.53906,50.02149,26.40625,87.42383,16.86328,96.9668-1.83984,1.83789-27.05078,17.10156-97.062-17.23242A494.241,494.241,0,0,1,224,434.85547C272.4375,463.86914,319.83594,480,358.58154,480c26.9336,0,49.707-7.61523,65.793-23.69336C463.59326,417.09961,452.27686,338.08008,403.06592,256Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": [\n          \"M424.37305,55.69141C408.294,39.61914,385.50879,32,358.58252,32,319.82764,32,272.43359,48.127,224,77.14453a493.86641,493.86641,0,0,0-58.042,41.03711C140.58252,138.875,114.57666,162.5918,85.75635,197.916a374.25237,374.25237,0,0,0,35.70263,58.082A505.23427,505.23427,0,0,1,224,153.65625a377.23937,377.23937,0,0,1,58.042-35.47266c70.01221-34.334,95.22461-19.07421,97.0625-17.23632,9.54248,9.543,7.67432,46.94531-16.86084,96.96875A492.27615,492.27615,0,0,1,403.06543,256C452.27637,173.91992,463.59277,94.90039,424.37305,55.69141ZM224,358.3418a377.44678,377.44678,0,0,1-58.042,35.47461c-70.01221,34.334-95.22461,19.07421-97.0625,17.23632-9.54248-9.543-7.67432-46.94335,16.86084-96.96875A492.27615,492.27615,0,0,1,44.93457,256C-4.27637,338.08008-15.59277,417.09961,23.627,456.30664,39.70605,472.38086,62.49121,480,89.41748,480c38.75488,0,86.14893-16.127,134.58252-45.14453a493.86641,493.86641,0,0,0,58.042-41.03711c25.38965-20.70508,51.42285-44.45606,80.20166-79.73438A373.962,373.962,0,0,0,326.541,256,505.23427,505.23427,0,0,1,224,358.3418Z\",\n          \"M224,287.98828a31.99414,31.99414,0,1,0-32-31.99414A31.98908,31.98908,0,0,0,224,287.98828ZM121.46094,255.99805A374.13921,374.13921,0,0,1,85.7583,197.916c-24.53906-50.02344-26.40625-87.42579-16.86328-96.9668,1.83984-1.83789,27.05078-17.10156,97.062,17.23242A494.241,494.241,0,0,1,224,77.14453C175.5625,48.13086,128.16406,32,89.41846,32c-26.9336,0-49.707,7.61523-65.793,23.69141C-15.59326,94.90039-4.27686,173.91992,44.93408,256A492.0174,492.0174,0,0,0,85.7583,314.084c28.79639,35.30274,54.85889,59.07227,80.19873,79.73243A377.429,377.429,0,0,0,224,358.3418,505.131,505.131,0,0,1,121.46094,255.99805ZM403.06592,256a492.0174,492.0174,0,0,0-40.82422-58.084c-28.84326-35.35547-54.89795-59.10352-80.19873-79.73243A377.4073,377.4073,0,0,0,224,153.65625,505.20556,505.20556,0,0,1,326.53906,256a373.849,373.849,0,0,1,35.70264,58.084c24.53906,50.02149,26.40625,87.42383,16.86328,96.9668-1.83984,1.83789-27.05078,17.10156-97.062-17.23242A494.241,494.241,0,0,1,224,434.85547C272.4375,463.86914,319.83594,480,358.58154,480c26.9336,0,49.707-7.61523,65.793-23.69336C463.59326,417.09961,452.27686,338.08008,403.06592,256Z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"aws\": {\n    \"changes\": [\n      \"5.0.0\",\n      \"5.1.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f375\",\n    \"label\": \"Amazon Web Services (AWS)\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><path d=\\\"M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": \"M180.41 203.01c-.72 22.65 10.6 32.68 10.88 39.05a8.164 8.164 0 0 1-4.1 6.27l-12.8 8.96a10.66 10.66 0 0 1-5.63 1.92c-.43-.02-8.19 1.83-20.48-25.61a78.608 78.608 0 0 1-62.61 29.45c-16.28.89-60.4-9.24-58.13-56.21-1.59-38.28 34.06-62.06 70.93-60.05 7.1.02 21.6.37 46.99 6.27v-15.62c2.69-26.46-14.7-46.99-44.81-43.91-2.4.01-19.4-.5-45.84 10.11-7.36 3.38-8.3 2.82-10.75 2.82-7.41 0-4.36-21.48-2.94-24.2 5.21-6.4 35.86-18.35 65.94-18.18a76.857 76.857 0 0 1 55.69 17.28 70.285 70.285 0 0 1 17.67 52.36l-.01 69.29zM93.99 235.4c32.43-.47 46.16-19.97 49.29-30.47 2.46-10.05 2.05-16.41 2.05-27.4-9.67-2.32-23.59-4.85-39.56-4.87-15.15-1.14-42.82 5.63-41.74 32.26-1.24 16.79 11.12 31.4 29.96 30.48zm170.92 23.05c-7.86.72-11.52-4.86-12.68-10.37l-49.8-164.65c-.97-2.78-1.61-5.65-1.92-8.58a4.61 4.61 0 0 1 3.86-5.25c.24-.04-2.13 0 22.25 0 8.78-.88 11.64 6.03 12.55 10.37l35.72 140.83 33.16-140.83c.53-3.22 2.94-11.07 12.8-10.24h17.16c2.17-.18 11.11-.5 12.68 10.37l33.42 142.63L420.98 80.1c.48-2.18 2.72-11.37 12.68-10.37h19.72c.85-.13 6.15-.81 5.25 8.58-.43 1.85 3.41-10.66-52.75 169.9-1.15 5.51-4.82 11.09-12.68 10.37h-18.69c-10.94 1.15-12.51-9.66-12.68-10.75L328.67 110.7l-32.78 136.99c-.16 1.09-1.73 11.9-12.68 10.75h-18.3zm273.48 5.63c-5.88.01-33.92-.3-57.36-12.29a12.802 12.802 0 0 1-7.81-11.91v-10.75c0-8.45 6.2-6.9 8.83-5.89 10.04 4.06 16.48 7.14 28.81 9.6 36.65 7.53 52.77-2.3 56.72-4.48 13.15-7.81 14.19-25.68 5.25-34.95-10.48-8.79-15.48-9.12-53.13-21-4.64-1.29-43.7-13.61-43.79-52.36-.61-28.24 25.05-56.18 69.52-55.95 12.67-.01 46.43 4.13 55.57 15.62 1.35 2.09 2.02 4.55 1.92 7.04v10.11c0 4.44-1.62 6.66-4.87 6.66-7.71-.86-21.39-11.17-49.16-10.75-6.89-.36-39.89.91-38.41 24.97-.43 18.96 26.61 26.07 29.7 26.89 36.46 10.97 48.65 12.79 63.12 29.58 17.14 22.25 7.9 48.3 4.35 55.44-19.08 37.49-68.42 34.44-69.26 34.42zm40.2 104.86c-70.03 51.72-171.69 79.25-258.49 79.25A469.127 469.127 0 0 1 2.83 327.46c-6.53-5.89-.77-13.96 7.17-9.47a637.37 637.37 0 0 0 316.88 84.12 630.22 630.22 0 0 0 241.59-49.55c11.78-5 21.77 7.8 10.12 16.38zm29.19-33.29c-8.96-11.52-59.28-5.38-81.81-2.69-6.79.77-7.94-5.12-1.79-9.47 40.07-28.17 105.88-20.1 113.44-10.63 7.55 9.47-2.05 75.41-39.56 106.91-5.76 4.87-11.27 2.3-8.71-4.1 8.44-21.25 27.39-68.49 18.43-80.02z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"badge-check\": {\n    \"changes\": [\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"accept\",\n        \"achievement\",\n        \"agree\",\n        \"award\",\n        \"confirm\",\n        \"correct\",\n        \"done\",\n        \"ok\",\n        \"security\",\n        \"select\",\n        \"success\",\n        \"verified\",\n        \"verify\",\n        \"winner\",\n        \"yes\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f336\",\n    \"label\": \"Check Badge\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M367.2 211.75l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.06 15.56z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M512 256a88 88 0 0 0-57.1-82.4A88 88 0 0 0 338.4 57.1a88 88 0 0 0-164.8 0A88 88 0 0 0 57.1 173.6a88 88 0 0 0 0 164.8 88 88 0 0 0 116.5 116.5 88 88 0 0 0 164.8 0 88 88 0 0 0 116.5-116.5A88 88 0 0 0 512 256zm-144.8-44.25l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.08 15.56z\",\n          \"M367.2 211.75l-131 130a11 11 0 0 1-15.55-.06l-75.72-76.33a11 11 0 0 1 .06-15.56L171 224a11 11 0 0 1 15.56.06l42.15 42.49 97.2-96.42a11 11 0 0 1 15.55.06l25.82 26a11 11 0 0 1-.06 15.56z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"bell\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\",\n      \"5.2.0\",\n      \"5.11.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"alarm\",\n        \"alert\",\n        \"chime\",\n        \"notification\",\n        \"reminder\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f0f3\",\n    \"label\": \"bell\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M448 384c-.1 16.4-13 32-32.1 32H32.08C13 416 .09 400.4 0 384a31.25 31.25 0 0 1 8.61-21.71c19.32-20.76 55.47-52 55.47-154.29 0-77.7 54.48-139.9 127.94-155.16V32a32 32 0 1 1 64 0v20.84C329.42 68.1 383.9 130.3 383.9 208c0 102.3 36.15 133.53 55.47 154.29A31.27 31.27 0 0 1 448 384z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M160 448h128a64 64 0 0 1-128 0z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": [\n          \"M448 384c-.1 16.4-13 32-32.1 32H32.08C13 416 .09 400.4 0 384a31.25 31.25 0 0 1 8.61-21.71c19.32-20.76 55.47-52 55.47-154.29 0-77.7 54.48-139.9 127.94-155.16V32a32 32 0 1 1 64 0v20.84C329.42 68.1 383.9 130.3 383.9 208c0 102.3 36.15 133.53 55.47 154.29A31.27 31.27 0 0 1 448 384z\",\n          \"M160 448h128a64 64 0 0 1-128 0z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"book-dead\": {\n    \"changes\": [\n      \"5.4.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"Dungeons & Dragons\",\n        \"crossbones\",\n        \"d&d\",\n        \"dark arts\",\n        \"death\",\n        \"dnd\",\n        \"documentation\",\n        \"evil\",\n        \"fantasy\",\n        \"halloween\",\n        \"holiday\",\n        \"necronomicon\",\n        \"read\",\n        \"skull\",\n        \"spell\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f6b7\",\n    \"label\": \"Book of the Dead\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M272 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm176 222.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM240 56c44.2 0 80 28.7 80 64 0 20.9-12.7 39.2-32 50.9V184c0 8.8-7.2 16-16 16h-64c-8.8 0-16-7.2-16-16v-13.1c-19.3-11.7-32-30-32-50.9 0-35.3 35.8-64 80-64zM124.8 223.3l6.3-14.7c1.7-4.1 6.4-5.9 10.5-4.2l98.3 42.1 98.4-42.1c4.1-1.7 8.8.1 10.5 4.2l6.3 14.7c1.7 4.1-.1 8.8-4.2 10.5L280.6 264l70.3 30.1c4.1 1.7 5.9 6.4 4.2 10.5l-6.3 14.7c-1.7 4.1-6.4 5.9-10.5 4.2L240 281.4l-98.3 42.2c-4.1 1.7-8.8-.1-10.5-4.2l-6.3-14.7c-1.7-4.1.1-8.8 4.2-10.5l70.4-30.1-70.5-30.3c-4.1-1.7-5.9-6.4-4.2-10.5zm256 224.7H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8zM208 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M272 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16zm176 222.4V25.6c0-16-9.6-25.6-25.6-25.6H96C41.6 0 0 41.6 0 96v320c0 54.4 41.6 96 96 96h326.4c12.8 0 25.6-9.6 25.6-25.6v-16c0-6.4-3.2-12.8-9.6-19.2-3.2-16-3.2-60.8 0-73.6 6.4-3.2 9.6-9.6 9.6-19.2zM240 56c44.2 0 80 28.7 80 64 0 20.9-12.7 39.2-32 50.9V184c0 8.8-7.2 16-16 16h-64c-8.8 0-16-7.2-16-16v-13.1c-19.3-11.7-32-30-32-50.9 0-35.3 35.8-64 80-64zM124.8 223.3l6.3-14.7c1.7-4.1 6.4-5.9 10.5-4.2l98.3 42.1 98.4-42.1c4.1-1.7 8.8.1 10.5 4.2l6.3 14.7c1.7 4.1-.1 8.8-4.2 10.5L280.6 264l70.3 30.1c4.1 1.7 5.9 6.4 4.2 10.5l-6.3 14.7c-1.7 4.1-6.4 5.9-10.5 4.2L240 281.4l-98.3 42.2c-4.1 1.7-8.8-.1-10.5-4.2l-6.3-14.7c-1.7-4.1.1-8.8 4.2-10.5l70.4-30.1-70.5-30.3c-4.1-1.7-5.9-6.4-4.2-10.5zm256 224.7H96c-19.2 0-32-12.8-32-32s16-32 32-32h284.8zM208 136c8.8 0 16-7.2 16-16s-7.2-16-16-16-16 7.2-16 16 7.2 16 16 16z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"books\": {\n    \"changes\": [\n      \"5.2.0\",\n      \"5.10.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"diary\",\n        \"documentation\",\n        \"journal\",\n        \"library\",\n        \"read\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f5db\",\n    \"label\": \"Books\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M96 0H32A32 32 0 0 0 0 32v64h128V32A32 32 0 0 0 96 0zM0 384h128V128H0zm0 96a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H0zm513.62-17.78L401.08 42.71l-60.26 16.14 112.35 418.8c.11.39.2.79.29 1.18l60.29-16.15c-.04-.15-.09-.3-.13-.46zM160 480a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H160zM256 0h-64a32 32 0 0 0-32 32v64h124.79l-8-29.65a23.94 23.94 0 0 1 11.17-27V32A32 32 0 0 0 256 0zm-96 384h128V128H160z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M0 416h128v-32H0zm0-288h128V96H0zm575.17 317.65L460.39 17.78a23.89 23.89 0 0 0-29.18-17h-.09L415.73 5a24 24 0 0 0-16.9 29.36l114.79 427.86a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.35zM160 416h128v-32H160zM338.39 49.78a23.89 23.89 0 0 0-29.18-17h-.09L293.73 37a24 24 0 0 0-16.9 29.36l8 29.65H160v32h128V108l103.62 386.22a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.33z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": [\n          \"M96 0H32A32 32 0 0 0 0 32v64h128V32A32 32 0 0 0 96 0zM0 384h128V128H0zm0 96a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H0zm513.62-17.78L401.08 42.71l-60.26 16.14 112.35 418.8c.11.39.2.79.29 1.18l60.29-16.15c-.04-.15-.09-.3-.13-.46zM160 480a32 32 0 0 0 32 32h64a32 32 0 0 0 32-32v-64H160zM256 0h-64a32 32 0 0 0-32 32v64h124.79l-8-29.65a23.94 23.94 0 0 1 11.17-27V32A32 32 0 0 0 256 0zm-96 384h128V128H160z\",\n          \"M0 416h128v-32H0zm0-288h128V96H0zm575.17 317.65L460.39 17.78a23.89 23.89 0 0 0-29.18-17h-.09L415.73 5a24 24 0 0 0-16.9 29.36l114.79 427.86a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.35zM160 416h128v-32H160zM338.39 49.78a23.89 23.89 0 0 0-29.18-17h-.09L293.73 37a24 24 0 0 0-16.9 29.36l8 29.65H160v32h128V108l103.62 386.22a23.89 23.89 0 0 0 29.18 17h.09l15.38-4.22a24 24 0 0 0 16.9-29.33z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"brackets-curly\": {\n    \"changes\": [\n      \"5.7.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"code\",\n        \"developer\",\n        \"development\",\n        \"parentheses\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f7ea\",\n    \"label\": \"Curly Brackets\",\n    \"voted\": true,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M566.64 233.37a32 32 0 0 1 0 45.25l-45.25 45.25a32 32 0 0 0-9.39 22.64V384a96 96 0 0 1-96 96h-48a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h48a32 32 0 0 0 32-32v-37.48a96 96 0 0 1 28.13-67.89L498.76 256l-22.62-22.62A96 96 0 0 1 448 165.47V128a32 32 0 0 0-32-32h-48a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h48a96 96 0 0 1 96 96v37.48a32 32 0 0 0 9.38 22.65l45.25 45.24z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M208 32h-48a96 96 0 0 0-96 96v37.48a32.12 32.12 0 0 1-9.38 22.65L9.38 233.37a32 32 0 0 0 0 45.25l45.25 45.25A32.05 32.05 0 0 1 64 346.51V384a96 96 0 0 0 96 96h48a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-48a32 32 0 0 1-32-32v-37.48a96 96 0 0 0-28.13-67.89L77.26 256l22.63-22.63A96 96 0 0 0 128 165.48V128a32 32 0 0 1 32-32h48a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": [\n          \"M566.64 233.37a32 32 0 0 1 0 45.25l-45.25 45.25a32 32 0 0 0-9.39 22.64V384a96 96 0 0 1-96 96h-48a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h48a32 32 0 0 0 32-32v-37.48a96 96 0 0 1 28.13-67.89L498.76 256l-22.62-22.62A96 96 0 0 1 448 165.47V128a32 32 0 0 0-32-32h-48a16 16 0 0 1-16-16V48a16 16 0 0 1 16-16h48a96 96 0 0 1 96 96v37.48a32 32 0 0 0 9.38 22.65l45.25 45.24z\",\n          \"M208 32h-48a96 96 0 0 0-96 96v37.48a32.12 32.12 0 0 1-9.38 22.65L9.38 233.37a32 32 0 0 0 0 45.25l45.25 45.25A32.05 32.05 0 0 1 64 346.51V384a96 96 0 0 0 96 96h48a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16h-48a32 32 0 0 1-32-32v-37.48a96 96 0 0 0-28.13-67.89L77.26 256l22.63-22.63A96 96 0 0 0 128 165.48V128a32 32 0 0 1 32-32h48a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"cc-amazon-pay\": {\n    \"changes\": [\n      \"5.0.2\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f42d\",\n    \"label\": \"Amazon Pay Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M124.7 201.8c.1-11.8 0-23.5 0-35.3v-35.3c0-1.3.4-2 1.4-2.7 11.5-8 24.1-12.1 38.2-11.1 12.5.9 22.7 7 28.1 21.7 3.3 8.9 4.1 18.2 4.1 27.7 0 8.7-.7 17.3-3.4 25.6-5.7 17.8-18.7 24.7-35.7 23.9-11.7-.5-21.9-5-31.4-11.7-.9-.8-1.4-1.6-1.3-2.8zm154.9 14.6c4.6 1.8 9.3 2 14.1 1.5 11.6-1.2 21.9-5.7 31.3-12.5.9-.6 1.3-1.3 1.3-2.5-.1-3.9 0-7.9 0-11.8 0-4-.1-8 0-12 0-1.4-.4-2-1.8-2.2-7-.9-13.9-2.2-20.9-2.9-7-.6-14-.3-20.8 1.9-6.7 2.2-11.7 6.2-13.7 13.1-1.6 5.4-1.6 10.8.1 16.2 1.6 5.5 5.2 9.2 10.4 11.2zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zm-207.5 23.9c.4 1.7.9 3.4 1.6 5.1 16.5 40.6 32.9 81.3 49.5 121.9 1.4 3.5 1.7 6.4.2 9.9-2.8 6.2-4.9 12.6-7.8 18.7-2.6 5.5-6.7 9.5-12.7 11.2-4.2 1.1-8.5 1.3-12.9.9-2.1-.2-4.2-.7-6.3-.8-2.8-.2-4.2 1.1-4.3 4-.1 2.8-.1 5.6 0 8.3.1 4.6 1.6 6.7 6.2 7.5 4.7.8 9.4 1.6 14.2 1.7 14.3.3 25.7-5.4 33.1-17.9 2.9-4.9 5.6-10.1 7.7-15.4 19.8-50.1 39.5-100.3 59.2-150.5.6-1.5 1.1-3 1.3-4.6.4-2.4-.7-3.6-3.1-3.7-5.6-.1-11.1 0-16.7 0-3.1 0-5.3 1.4-6.4 4.3-.4 1.1-.9 2.3-1.3 3.4l-29.1 83.7c-2.1 6.1-4.2 12.1-6.5 18.6-.4-.9-.6-1.4-.8-1.9-10.8-29.9-21.6-59.9-32.4-89.8-1.7-4.7-3.5-9.5-5.3-14.2-.9-2.5-2.7-4-5.4-4-6.4-.1-12.8-.2-19.2-.1-2.2 0-3.3 1.6-2.8 3.7zM242.4 206c1.7 11.7 7.6 20.8 18 26.6 9.9 5.5 20.7 6.2 31.7 4.6 12.7-1.9 23.9-7.3 33.8-15.5.4-.3.8-.6 1.4-1 .5 3.2.9 6.2 1.5 9.2.5 2.6 2.1 4.3 4.5 4.4 4.6.1 9.1.1 13.7 0 2.3-.1 3.8-1.6 4-3.9.1-.8.1-1.6.1-2.3v-88.8c0-3.6-.2-7.2-.7-10.8-1.6-10.8-6.2-19.7-15.9-25.4-5.6-3.3-11.8-5-18.2-5.9-3-.4-6-.7-9.1-1.1h-10c-.8.1-1.6.3-2.5.3-8.2.4-16.3 1.4-24.2 3.5-5.1 1.3-10 3.2-15 4.9-3 1-4.5 3.2-4.4 6.5.1 2.8-.1 5.6 0 8.3.1 4.1 1.8 5.2 5.7 4.1 6.5-1.7 13.1-3.5 19.7-4.8 10.3-1.9 20.7-2.7 31.1-1.2 5.4.8 10.5 2.4 14.1 7 3.1 4 4.2 8.8 4.4 13.7.3 6.9.2 13.9.3 20.8 0 .4-.1.7-.2 1.2-.4 0-.8 0-1.1-.1-8.8-2.1-17.7-3.6-26.8-4.1-9.5-.5-18.9.1-27.9 3.2-10.8 3.8-19.5 10.3-24.6 20.8-4.1 8.3-4.6 17-3.4 25.8zM98.7 106.9v175.3c0 .8 0 1.7.1 2.5.2 2.5 1.7 4.1 4.1 4.2 5.9.1 11.8.1 17.7 0 2.5 0 4-1.7 4.1-4.1.1-.8.1-1.7.1-2.5v-60.7c.9.7 1.4 1.2 1.9 1.6 15 12.5 32.2 16.6 51.1 12.9 17.1-3.4 28.9-13.9 36.7-29.2 5.8-11.6 8.3-24.1 8.7-37 .5-14.3-1-28.4-6.8-41.7-7.1-16.4-18.9-27.3-36.7-30.9-2.7-.6-5.5-.8-8.2-1.2h-7c-1.2.2-2.4.3-3.6.5-11.7 1.4-22.3 5.8-31.8 12.7-2 1.4-3.9 3-5.9 4.5-.1-.5-.3-.8-.4-1.2-.4-2.3-.7-4.6-1.1-6.9-.6-3.9-2.5-5.5-6.4-5.6h-9.7c-5.9-.1-6.9 1-6.9 6.8zM493.6 339c-2.7-.7-5.1 0-7.6 1-43.9 18.4-89.5 30.2-136.8 35.8-14.5 1.7-29.1 2.8-43.7 3.2-26.6.7-53.2-.8-79.6-4.3-17.8-2.4-35.5-5.7-53-9.9-37-8.9-72.7-21.7-106.7-38.8-8.8-4.4-17.4-9.3-26.1-14-3.8-2.1-6.2-1.5-8.2 2.1v1.7c1.2 1.6 2.2 3.4 3.7 4.8 36 32.2 76.6 56.5 122 72.9 21.9 7.9 44.4 13.7 67.3 17.5 14 2.3 28 3.8 42.2 4.5 3 .1 6 .2 9 .4.7 0 1.4.2 2.1.3h17.7c.7-.1 1.4-.3 2.1-.3 14.9-.4 29.8-1.8 44.6-4 21.4-3.2 42.4-8.1 62.9-14.7 29.6-9.6 57.7-22.4 83.4-40.1 2.8-1.9 5.7-3.8 8-6.2 4.3-4.4 2.3-10.4-3.3-11.9zm50.4-27.7c-.8-4.2-4-5.8-7.6-7-5.7-1.9-11.6-2.8-17.6-3.3-11-.9-22-.4-32.8 1.6-12 2.2-23.4 6.1-33.5 13.1-1.2.8-2.4 1.8-3.1 3-.6.9-.7 2.3-.5 3.4.3 1.3 1.7 1.6 3 1.5.6 0 1.2 0 1.8-.1l19.5-2.1c9.6-.9 19.2-1.5 28.8-.8 4.1.3 8.1 1.2 12 2.2 4.3 1.1 6.2 4.4 6.4 8.7.3 6.7-1.2 13.1-2.9 19.5-3.5 12.9-8.3 25.4-13.3 37.8-.3.8-.7 1.7-.8 2.5-.4 2.5 1 4 3.4 3.5 1.4-.3 3-1.1 4-2.1 3.7-3.6 7.5-7.2 10.6-11.2 10.7-13.8 17-29.6 20.7-46.6.7-3 1.2-6.1 1.7-9.1.2-4.7.2-9.6.2-14.5z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"cc-amex\": {\n    \"changes\": [\n      \"4.2\",\n      \"5.0.0\",\n      \"5.7.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"amex\"\n      ]\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f1f3\",\n    \"label\": \"American Express Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1548364699000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M325.1 167.8c0-16.4-14.1-18.4-27.4-18.4l-39.1-.3v69.3H275v-25.1h18c18.4 0 14.5 10.3 14.8 25.1h16.6v-13.5c0-9.2-1.5-15.1-11-18.4 7.4-3 11.8-10.7 11.7-18.7zm-29.4 11.3H275v-15.3h21c5.1 0 10.7 1 10.7 7.4 0 6.6-5.3 7.9-11 7.9zM279 268.6h-52.7l-21 22.8-20.5-22.8h-66.5l-.1 69.3h65.4l21.3-23 20.4 23h32.2l.1-23.3c18.9 0 49.3 4.6 49.3-23.3 0-17.3-12.3-22.7-27.9-22.7zm-103.8 54.7h-40.6v-13.8h36.3v-14.1h-36.3v-12.5h41.7l17.9 20.2zm65.8 8.2l-25.3-28.1L241 276zm37.8-31h-21.2v-17.6h21.5c5.6 0 10.2 2.3 10.2 8.4 0 6.4-4.6 9.2-10.5 9.2zm-31.6-136.7v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5zM576 255.4h-.2zm-194.6 31.9c0-16.4-14.1-18.7-27.1-18.7h-39.4l-.1 69.3h16.6l.1-25.3h17.6c11 0 14.8 2 14.8 13.8l-.1 11.5h16.6l.1-13.8c0-8.9-1.8-15.1-11-18.4 7.7-3.1 11.8-10.8 11.9-18.4zm-29.2 11.2h-20.7v-15.6h21c5.1 0 10.7 1 10.7 7.4 0 6.9-5.4 8.2-11 8.2zm-172.8-80v-69.3h-27.6l-19.7 47-21.7-47H83.3v65.7l-28.1-65.7H30.7L1 218.5h17.9l6.4-15.3h34.5l6.4 15.3H100v-54.2l24 54.2h14.6l24-54.2v54.2zM31.2 188.8l11.2-27.6 11.5 27.6zm477.4 158.9v-4.5c-10.8 5.6-3.9 4.5-156.7 4.5 0-25.2.1-23.9 0-25.2-1.7-.1-3.2-.1-9.4-.1 0 17.9-.1 6.8-.1 25.3h-39.6c0-12.1.1-15.3.1-29.2-10 6-22.8 6.4-34.3 6.2 0 14.7-.1 8.3-.1 23h-48.9c-5.1-5.7-2.7-3.1-15.4-17.4-3.2 3.5-12.8 13.9-16.1 17.4h-82v-92.3h83.1c5 5.6 2.8 3.1 15.5 17.2 3.2-3.5 12.2-13.4 15.7-17.2h58c9.8 0 18 1.9 24.3 5.6v-5.6c54.3 0 64.3-1.4 75.7 5.1v-5.1h78.2v5.2c11.4-6.9 19.6-5.2 64.9-5.2v5c10.3-5.9 16.6-5.2 54.3-5V80c0-26.5-21.5-48-48-48h-480c-26.5 0-48 21.5-48 48v109.8c9.4-21.9 19.7-46 23.1-53.9h39.7c4.3 10.1 1.6 3.7 9 21.1v-21.1h46c2.9 6.2 11.1 24 13.9 30 5.8-13.6 10.1-23.9 12.6-30h103c0-.1 11.5 0 11.6 0 43.7.2 53.6-.8 64.4 5.3v-5.3H363v9.3c7.6-6.1 17.9-9.3 30.7-9.3h27.6c0 .5 1.9.3 2.3.3H456c4.2 9.8 2.6 6 8.8 20.6v-20.6h43.3c4.9 8-1-1.8 11.2 18.4v-18.4h39.9v92h-41.6c-5.4-9-1.4-2.2-13.2-21.9v21.9h-52.8c-6.4-14.8-.1-.3-6.6-15.3h-19c-4.2 10-2.2 5.2-6.4 15.3h-26.8c-12.3 0-22.3-3-29.7-8.9v8.9h-66.5c-.3-13.9-.1-24.8-.1-24.8-1.8-.3-3.4-.2-9.8-.2v25.1H151.2v-11.4c-2.5 5.6-2.7 5.9-5.1 11.4h-29.5c-4-8.9-2.9-6.4-5.1-11.4v11.4H58.6c-4.2-10.1-2.2-5.3-6.4-15.3H33c-4.2 10-2.2 5.2-6.4 15.3H0V432c0 26.5 21.5 48 48 48h480.1c26.5 0 48-21.5 48-48v-90.4c-12.7 8.3-32.7 6.1-67.5 6.1zm36.3-64.5H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-57 39.8h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-42.2-40.1v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5zm-56.3-108.1c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm20.4-10.5h-.1zm-16.2-15.2c-23.5 0-34 12-34 35.3 0 22.2 10.2 34 33 34h19.2l6.4-15.3h34.3l6.6 15.3h33.7v-51.9l31.2 51.9h23.6v-69h-16.9v48.1l-29.1-48.1h-25.3v65.4l-27.9-65.4h-24.8l-23.5 54.5h-7.4c-13.3 0-16.1-8.1-16.1-19.9 0-23.8 15.7-20 33.1-19.7v-15.2zm42.1 12.1l11.2 27.6h-22.8zm-101.1-12v69.3h16.9v-69.3z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M325.1 167.8c0-16.4-14.1-18.4-27.4-18.4l-39.1-.3v69.3H275v-25.1h18c18.4 0 14.5 10.3 14.8 25.1h16.6v-13.5c0-9.2-1.5-15.1-11-18.4 7.4-3 11.8-10.7 11.7-18.7zm-29.4 11.3H275v-15.3h21c5.1 0 10.7 1 10.7 7.4 0 6.6-5.3 7.9-11 7.9zM279 268.6h-52.7l-21 22.8-20.5-22.8h-66.5l-.1 69.3h65.4l21.3-23 20.4 23h32.2l.1-23.3c18.9 0 49.3 4.6 49.3-23.3 0-17.3-12.3-22.7-27.9-22.7zm-103.8 54.7h-40.6v-13.8h36.3v-14.1h-36.3v-12.5h41.7l17.9 20.2zm65.8 8.2l-25.3-28.1L241 276zm37.8-31h-21.2v-17.6h21.5c5.6 0 10.2 2.3 10.2 8.4 0 6.4-4.6 9.2-10.5 9.2zm-31.6-136.7v-14.6h-55.5v69.3h55.5v-14.3h-38.9v-13.8h37.8v-14.1h-37.8v-12.5zM576 255.4h-.2zm-194.6 31.9c0-16.4-14.1-18.7-27.1-18.7h-39.4l-.1 69.3h16.6l.1-25.3h17.6c11 0 14.8 2 14.8 13.8l-.1 11.5h16.6l.1-13.8c0-8.9-1.8-15.1-11-18.4 7.7-3.1 11.8-10.8 11.9-18.4zm-29.2 11.2h-20.7v-15.6h21c5.1 0 10.7 1 10.7 7.4 0 6.9-5.4 8.2-11 8.2zm-172.8-80v-69.3h-27.6l-19.7 47-21.7-47H83.3v65.7l-28.1-65.7H30.7L1 218.5h17.9l6.4-15.3h34.5l6.4 15.3H100v-54.2l24 54.2h14.6l24-54.2v54.2zM31.2 188.8l11.2-27.6 11.5 27.6zm477.4 158.9v-4.5c-10.8 5.6-3.9 4.5-156.7 4.5 0-25.2.1-23.9 0-25.2-1.7-.1-3.2-.1-9.4-.1 0 17.9-.1 6.8-.1 25.3h-39.6c0-12.1.1-15.3.1-29.2-10 6-22.8 6.4-34.3 6.2 0 14.7-.1 8.3-.1 23h-48.9c-5.1-5.7-2.7-3.1-15.4-17.4-3.2 3.5-12.8 13.9-16.1 17.4h-82v-92.3h83.1c5 5.6 2.8 3.1 15.5 17.2 3.2-3.5 12.2-13.4 15.7-17.2h58c9.8 0 18 1.9 24.3 5.6v-5.6c54.3 0 64.3-1.4 75.7 5.1v-5.1h78.2v5.2c11.4-6.9 19.6-5.2 64.9-5.2v5c10.3-5.9 16.6-5.2 54.3-5V80c0-26.5-21.5-48-48-48h-480c-26.5 0-48 21.5-48 48v109.8c9.4-21.9 19.7-46 23.1-53.9h39.7c4.3 10.1 1.6 3.7 9 21.1v-21.1h46c2.9 6.2 11.1 24 13.9 30 5.8-13.6 10.1-23.9 12.6-30h103c0-.1 11.5 0 11.6 0 43.7.2 53.6-.8 64.4 5.3v-5.3H363v9.3c7.6-6.1 17.9-9.3 30.7-9.3h27.6c0 .5 1.9.3 2.3.3H456c4.2 9.8 2.6 6 8.8 20.6v-20.6h43.3c4.9 8-1-1.8 11.2 18.4v-18.4h39.9v92h-41.6c-5.4-9-1.4-2.2-13.2-21.9v21.9h-52.8c-6.4-14.8-.1-.3-6.6-15.3h-19c-4.2 10-2.2 5.2-6.4 15.3h-26.8c-12.3 0-22.3-3-29.7-8.9v8.9h-66.5c-.3-13.9-.1-24.8-.1-24.8-1.8-.3-3.4-.2-9.8-.2v25.1H151.2v-11.4c-2.5 5.6-2.7 5.9-5.1 11.4h-29.5c-4-8.9-2.9-6.4-5.1-11.4v11.4H58.6c-4.2-10.1-2.2-5.3-6.4-15.3H33c-4.2 10-2.2 5.2-6.4 15.3H0V432c0 26.5 21.5 48 48 48h480.1c26.5 0 48-21.5 48-48v-90.4c-12.7 8.3-32.7 6.1-67.5 6.1zm36.3-64.5H575v-14.6h-32.9c-12.8 0-23.8 6.6-23.8 20.7 0 33 42.7 12.8 42.7 27.4 0 5.1-4.3 6.4-8.4 6.4h-32l-.1 14.8h32c8.4 0 17.6-1.8 22.5-8.9v-25.8c-10.5-13.8-39.3-1.3-39.3-13.5 0-5.8 4.6-6.5 9.2-6.5zm-57 39.8h-32.2l-.1 14.8h32.2c14.8 0 26.2-5.6 26.2-22 0-33.2-42.9-11.2-42.9-26.3 0-5.6 4.9-6.4 9.2-6.4h30.4v-14.6h-33.2c-12.8 0-23.5 6.6-23.5 20.7 0 33 42.7 12.5 42.7 27.4-.1 5.4-4.7 6.4-8.8 6.4zm-42.2-40.1v-14.3h-55.2l-.1 69.3h55.2l.1-14.3-38.6-.3v-13.8H445v-14.1h-37.8v-12.5zm-56.3-108.1c-.3.2-1.4 2.2-1.4 7.6 0 6 .9 7.7 1.1 7.9.2.1 1.1.5 3.4.5l7.3-16.9c-1.1 0-2.1-.1-3.1-.1-5.6 0-7 .7-7.3 1zm20.4-10.5h-.1zm-16.2-15.2c-23.5 0-34 12-34 35.3 0 22.2 10.2 34 33 34h19.2l6.4-15.3h34.3l6.6 15.3h33.7v-51.9l31.2 51.9h23.6v-69h-16.9v48.1l-29.1-48.1h-25.3v65.4l-27.9-65.4h-24.8l-23.5 54.5h-7.4c-13.3 0-16.1-8.1-16.1-19.9 0-23.8 15.7-20 33.1-19.7v-15.2zm42.1 12.1l11.2 27.6h-22.8zm-101.1-12v69.3h16.9v-69.3z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"cc-apple-pay\": {\n    \"changes\": [\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f416\",\n    \"label\": \"Apple Pay Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M302.2 218.4c0 17.2-10.5 27.1-29 27.1h-24.3v-54.2h24.4c18.4 0 28.9 9.8 28.9 27.1zm47.5 62.6c0 8.3 7.2 13.7 18.5 13.7 14.4 0 25.2-9.1 25.2-21.9v-7.7l-23.5 1.5c-13.3.9-20.2 5.8-20.2 14.4zM576 79v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM127.8 197.2c8.4.7 16.8-4.2 22.1-10.4 5.2-6.4 8.6-15 7.7-23.7-7.4.3-16.6 4.9-21.9 11.3-4.8 5.5-8.9 14.4-7.9 22.8zm60.6 74.5c-.2-.2-19.6-7.6-19.8-30-.2-18.7 15.3-27.7 16-28.2-8.8-13-22.4-14.4-27.1-14.7-12.2-.7-22.6 6.9-28.4 6.9-5.9 0-14.7-6.6-24.3-6.4-12.5.2-24.2 7.3-30.5 18.6-13.1 22.6-3.4 56 9.3 74.4 6.2 9.1 13.7 19.1 23.5 18.7 9.3-.4 13-6 24.2-6 11.3 0 14.5 6 24.3 5.9 10.2-.2 16.5-9.1 22.8-18.2 6.9-10.4 9.8-20.4 10-21zm135.4-53.4c0-26.6-18.5-44.8-44.9-44.8h-51.2v136.4h21.2v-46.6h29.3c26.8 0 45.6-18.4 45.6-45zm90 23.7c0-19.7-15.8-32.4-40-32.4-22.5 0-39.1 12.9-39.7 30.5h19.1c1.6-8.4 9.4-13.9 20-13.9 13 0 20.2 6 20.2 17.2v7.5l-26.4 1.6c-24.6 1.5-37.9 11.6-37.9 29.1 0 17.7 13.7 29.4 33.4 29.4 13.3 0 25.6-6.7 31.2-17.4h.4V310h19.6v-68zM516 210.9h-21.5l-24.9 80.6h-.4l-24.9-80.6H422l35.9 99.3-1.9 6c-3.2 10.2-8.5 14.2-17.9 14.2-1.7 0-4.9-.2-6.2-.3v16.4c1.2.4 6.5.5 8.1.5 20.7 0 30.4-7.9 38.9-31.8L516 210.9z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"cc-diners-club\": {\n    \"changes\": [\n      \"4.4\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f24c\",\n    \"label\": \"Diner's Club Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M239.7 79.9c-96.9 0-175.8 78.6-175.8 175.8 0 96.9 78.9 175.8 175.8 175.8 97.2 0 175.8-78.9 175.8-175.8 0-97.2-78.6-175.8-175.8-175.8zm-39.9 279.6c-41.7-15.9-71.4-56.4-71.4-103.8s29.7-87.9 71.4-104.1v207.9zm79.8.3V151.6c41.7 16.2 71.4 56.7 71.4 104.1s-29.7 87.9-71.4 104.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM329.7 448h-90.3c-106.2 0-193.8-85.5-193.8-190.2C45.6 143.2 133.2 64 239.4 64h90.3c105 0 200.7 79.2 200.7 193.8 0 104.7-95.7 190.2-200.7 190.2z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"cc-discover\": {\n    \"changes\": [\n      \"4.2\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f1f2\",\n    \"label\": \"Discover Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1548363722000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M520.4 196.1c0-7.9-5.5-12.1-15.6-12.1h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-44.1 138.9c22.6 0 52.9-4.1 52.9 24.4 0 12.6-6.6 20.7-18.7 23.2l25.8 34.4h-19.6l-22.2-32.8h-2.2v32.8h-16zm-55.9.1h45.3v14H444v18.2h28.3V217H444v22.2h29.3V253H428zm-68.7 0l21.9 55.2 22.2-55.2h17.5l-35.5 84.2h-8.6l-35-84.2zm-55.9-3c24.7 0 44.6 20 44.6 44.6 0 24.7-20 44.6-44.6 44.6-24.7 0-44.6-20-44.6-44.6 0-24.7 20-44.6 44.6-44.6zm-49.3 6.1v19c-20.1-20.1-46.8-4.7-46.8 19 0 25 27.5 38.5 46.8 19.2v19c-29.7 14.3-63.3-5.7-63.3-38.2 0-31.2 33.1-53 63.3-38zm-97.2 66.3c11.4 0 22.4-15.3-3.3-24.4-15-5.5-20.2-11.4-20.2-22.7 0-23.2 30.6-31.4 49.7-14.3l-8.4 10.8c-10.4-11.6-24.9-6.2-24.9 2.5 0 4.4 2.7 6.9 12.3 10.3 18.2 6.6 23.6 12.5 23.6 25.6 0 29.5-38.8 37.4-56.6 11.3l10.3-9.9c3.7 7.1 9.9 10.8 17.5 10.8zM55.4 253H32v-82h23.4c26.1 0 44.1 17 44.1 41.1 0 18.5-13.2 40.9-44.1 40.9zm67.5 0h-16v-82h16zM544 433c0 8.2-6.8 15-15 15H128c189.6-35.6 382.7-139.2 416-160zM74.1 191.6c-5.2-4.9-11.6-6.6-21.9-6.6H48v54.2h4.2c10.3 0 17-2 21.9-6.4 5.7-5.2 8.9-12.8 8.9-20.7s-3.2-15.5-8.9-20.5z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M520.4 196.1c0-7.9-5.5-12.1-15.6-12.1h-4.9v24.9h4.7c10.3 0 15.8-4.4 15.8-12.8zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-44.1 138.9c22.6 0 52.9-4.1 52.9 24.4 0 12.6-6.6 20.7-18.7 23.2l25.8 34.4h-19.6l-22.2-32.8h-2.2v32.8h-16zm-55.9.1h45.3v14H444v18.2h28.3V217H444v22.2h29.3V253H428zm-68.7 0l21.9 55.2 22.2-55.2h17.5l-35.5 84.2h-8.6l-35-84.2zm-55.9-3c24.7 0 44.6 20 44.6 44.6 0 24.7-20 44.6-44.6 44.6-24.7 0-44.6-20-44.6-44.6 0-24.7 20-44.6 44.6-44.6zm-49.3 6.1v19c-20.1-20.1-46.8-4.7-46.8 19 0 25 27.5 38.5 46.8 19.2v19c-29.7 14.3-63.3-5.7-63.3-38.2 0-31.2 33.1-53 63.3-38zm-97.2 66.3c11.4 0 22.4-15.3-3.3-24.4-15-5.5-20.2-11.4-20.2-22.7 0-23.2 30.6-31.4 49.7-14.3l-8.4 10.8c-10.4-11.6-24.9-6.2-24.9 2.5 0 4.4 2.7 6.9 12.3 10.3 18.2 6.6 23.6 12.5 23.6 25.6 0 29.5-38.8 37.4-56.6 11.3l10.3-9.9c3.7 7.1 9.9 10.8 17.5 10.8zM55.4 253H32v-82h23.4c26.1 0 44.1 17 44.1 41.1 0 18.5-13.2 40.9-44.1 40.9zm67.5 0h-16v-82h16zM544 433c0 8.2-6.8 15-15 15H128c189.6-35.6 382.7-139.2 416-160zM74.1 191.6c-5.2-4.9-11.6-6.6-21.9-6.6H48v54.2h4.2c10.3 0 17-2 21.9-6.4 5.7-5.2 8.9-12.8 8.9-20.7s-3.2-15.5-8.9-20.5z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"cc-jcb\": {\n    \"changes\": [\n      \"4.4\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f24b\",\n    \"label\": \"JCB Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M431.5 244.3V212c41.2 0 38.5.2 38.5.2 7.3 1.3 13.3 7.3 13.3 16 0 8.8-6 14.5-13.3 15.8-1.2.4-3.3.3-38.5.3zm42.8 20.2c-2.8-.7-3.3-.5-42.8-.5v35c39.6 0 40 .2 42.8-.5 7.5-1.5 13.5-8 13.5-17 0-8.7-6-15.5-13.5-17zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM182 192.3h-57c0 67.1 10.7 109.7-35.8 109.7-19.5 0-38.8-5.7-57.2-14.8v28c30 8.3 68 8.3 68 8.3 97.9 0 82-47.7 82-131.2zm178.5 4.5c-63.4-16-165-14.9-165 59.3 0 77.1 108.2 73.6 165 59.2V287C312.9 311.7 253 309 253 256s59.8-55.6 107.5-31.2v-28zM544 286.5c0-18.5-16.5-30.5-38-32v-.8c19.5-2.7 30.3-15.5 30.3-30.2 0-19-15.7-30-37-31 0 0 6.3-.3-120.3-.3v127.5h122.7c24.3.1 42.3-12.9 42.3-33.2z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"cc-mastercard\": {\n    \"changes\": [\n      \"4.2\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f1f1\",\n    \"label\": \"MasterCard Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M482.9 410.3c0 6.8-4.6 11.7-11.2 11.7-6.8 0-11.2-5.2-11.2-11.7 0-6.5 4.4-11.7 11.2-11.7 6.6 0 11.2 5.2 11.2 11.7zm-310.8-11.7c-7.1 0-11.2 5.2-11.2 11.7 0 6.5 4.1 11.7 11.2 11.7 6.5 0 10.9-4.9 10.9-11.7-.1-6.5-4.4-11.7-10.9-11.7zm117.5-.3c-5.4 0-8.7 3.5-9.5 8.7h19.1c-.9-5.7-4.4-8.7-9.6-8.7zm107.8.3c-6.8 0-10.9 5.2-10.9 11.7 0 6.5 4.1 11.7 10.9 11.7 6.8 0 11.2-4.9 11.2-11.7 0-6.5-4.4-11.7-11.2-11.7zm105.9 26.1c0 .3.3.5.3 1.1 0 .3-.3.5-.3 1.1-.3.3-.3.5-.5.8-.3.3-.5.5-1.1.5-.3.3-.5.3-1.1.3-.3 0-.5 0-1.1-.3-.3 0-.5-.3-.8-.5-.3-.3-.5-.5-.5-.8-.3-.5-.3-.8-.3-1.1 0-.5 0-.8.3-1.1 0-.5.3-.8.5-1.1.3-.3.5-.3.8-.5.5-.3.8-.3 1.1-.3.5 0 .8 0 1.1.3.5.3.8.3 1.1.5s.2.6.5 1.1zm-2.2 1.4c.5 0 .5-.3.8-.3.3-.3.3-.5.3-.8 0-.3 0-.5-.3-.8-.3 0-.5-.3-1.1-.3h-1.6v3.5h.8V426h.3l1.1 1.4h.8l-1.1-1.3zM576 81v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V81c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM64 220.6c0 76.5 62.1 138.5 138.5 138.5 27.2 0 53.9-8.2 76.5-23.1-72.9-59.3-72.4-171.2 0-230.5-22.6-15-49.3-23.1-76.5-23.1-76.4-.1-138.5 62-138.5 138.2zm224 108.8c70.5-55 70.2-162.2 0-217.5-70.2 55.3-70.5 162.6 0 217.5zm-142.3 76.3c0-8.7-5.7-14.4-14.7-14.7-4.6 0-9.5 1.4-12.8 6.5-2.4-4.1-6.5-6.5-12.2-6.5-3.8 0-7.6 1.4-10.6 5.4V392h-8.2v36.7h8.2c0-18.9-2.5-30.2 9-30.2 10.2 0 8.2 10.2 8.2 30.2h7.9c0-18.3-2.5-30.2 9-30.2 10.2 0 8.2 10 8.2 30.2h8.2v-23zm44.9-13.7h-7.9v4.4c-2.7-3.3-6.5-5.4-11.7-5.4-10.3 0-18.2 8.2-18.2 19.3 0 11.2 7.9 19.3 18.2 19.3 5.2 0 9-1.9 11.7-5.4v4.6h7.9V392zm40.5 25.6c0-15-22.9-8.2-22.9-15.2 0-5.7 11.9-4.8 18.5-1.1l3.3-6.5c-9.4-6.1-30.2-6-30.2 8.2 0 14.3 22.9 8.3 22.9 15 0 6.3-13.5 5.8-20.7.8l-3.5 6.3c11.2 7.6 32.6 6 32.6-7.5zm35.4 9.3l-2.2-6.8c-3.8 2.1-12.2 4.4-12.2-4.1v-16.6h13.1V392h-13.1v-11.2h-8.2V392h-7.6v7.3h7.6V416c0 17.6 17.3 14.4 22.6 10.9zm13.3-13.4h27.5c0-16.2-7.4-22.6-17.4-22.6-10.6 0-18.2 7.9-18.2 19.3 0 20.5 22.6 23.9 33.8 14.2l-3.8-6c-7.8 6.4-19.6 5.8-21.9-4.9zm59.1-21.5c-4.6-2-11.6-1.8-15.2 4.4V392h-8.2v36.7h8.2V408c0-11.6 9.5-10.1 12.8-8.4l2.4-7.6zm10.6 18.3c0-11.4 11.6-15.1 20.7-8.4l3.8-6.5c-11.6-9.1-32.7-4.1-32.7 15 0 19.8 22.4 23.8 32.7 15l-3.8-6.5c-9.2 6.5-20.7 2.6-20.7-8.6zm66.7-18.3H408v4.4c-8.3-11-29.9-4.8-29.9 13.9 0 19.2 22.4 24.7 29.9 13.9v4.6h8.2V392zm33.7 0c-2.4-1.2-11-2.9-15.2 4.4V392h-7.9v36.7h7.9V408c0-11 9-10.3 12.8-8.4l2.4-7.6zm40.3-14.9h-7.9v19.3c-8.2-10.9-29.9-5.1-29.9 13.9 0 19.4 22.5 24.6 29.9 13.9v4.6h7.9v-51.7zm7.6-75.1v4.6h.8V302h1.9v-.8h-4.6v.8h1.9zm6.6 123.8c0-.5 0-1.1-.3-1.6-.3-.3-.5-.8-.8-1.1-.3-.3-.8-.5-1.1-.8-.5 0-1.1-.3-1.6-.3-.3 0-.8.3-1.4.3-.5.3-.8.5-1.1.8-.5.3-.8.8-.8 1.1-.3.5-.3 1.1-.3 1.6 0 .3 0 .8.3 1.4 0 .3.3.8.8 1.1.3.3.5.5 1.1.8.5.3 1.1.3 1.4.3.5 0 1.1 0 1.6-.3.3-.3.8-.5 1.1-.8.3-.3.5-.8.8-1.1.3-.6.3-1.1.3-1.4zm3.2-124.7h-1.4l-1.6 3.5-1.6-3.5h-1.4v5.4h.8v-4.1l1.6 3.5h1.1l1.4-3.5v4.1h1.1v-5.4zm4.4-80.5c0-76.2-62.1-138.3-138.5-138.3-27.2 0-53.9 8.2-76.5 23.1 72.1 59.3 73.2 171.5 0 230.5 22.6 15 49.5 23.1 76.5 23.1 76.4.1 138.5-61.9 138.5-138.4z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"cc-paypal\": {\n    \"changes\": [\n      \"4.2\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f1f4\",\n    \"label\": \"Paypal Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M186.3 258.2c0 12.2-9.7 21.5-22 21.5-9.2 0-16-5.2-16-15 0-12.2 9.5-22 21.7-22 9.3 0 16.3 5.7 16.3 15.5zM80.5 209.7h-4.7c-1.5 0-3 1-3.2 2.7l-4.3 26.7 8.2-.3c11 0 19.5-1.5 21.5-14.2 2.3-13.4-6.2-14.9-17.5-14.9zm284 0H360c-1.8 0-3 1-3.2 2.7l-4.2 26.7 8-.3c13 0 22-3 22-18-.1-10.6-9.6-11.1-18.1-11.1zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM128.3 215.4c0-21-16.2-28-34.7-28h-40c-2.5 0-5 2-5.2 4.7L32 294.2c-.3 2 1.2 4 3.2 4h19c2.7 0 5.2-2.9 5.5-5.7l4.5-26.6c1-7.2 13.2-4.7 18-4.7 28.6 0 46.1-17 46.1-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.2 8.2-5.8-8.5-14.2-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9 0 20.2-4.9 26.5-11.9-.5 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H200c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm40.5 97.9l63.7-92.6c.5-.5.5-1 .5-1.7 0-1.7-1.5-3.5-3.2-3.5h-19.2c-1.7 0-3.5 1-4.5 2.5l-26.5 39-11-37.5c-.8-2.2-3-4-5.5-4h-18.7c-1.7 0-3.2 1.8-3.2 3.5 0 1.2 19.5 56.8 21.2 62.1-2.7 3.8-20.5 28.6-20.5 31.6 0 1.8 1.5 3.2 3.2 3.2h19.2c1.8-.1 3.5-1.1 4.5-2.6zm159.3-106.7c0-21-16.2-28-34.7-28h-39.7c-2.7 0-5.2 2-5.5 4.7l-16.2 102c-.2 2 1.3 4 3.2 4h20.5c2 0 3.5-1.5 4-3.2l4.5-29c1-7.2 13.2-4.7 18-4.7 28.4 0 45.9-17 45.9-45.8zm84.2 8.8h-19c-3.8 0-4 5.5-4.3 8.2-5.5-8.5-14-10-23.7-10-24.5 0-43.2 21.5-43.2 45.2 0 19.5 12.2 32.2 31.7 32.2 9.3 0 20.5-4.9 26.5-11.9-.3 1.5-1 4.7-1 6.2 0 2.3 1 4 3.2 4H484c2.7 0 5-2.9 5.5-5.7l10.2-64.3c.3-1.9-1.2-3.9-3.2-3.9zm47.5-33.3c0-2-1.5-3.5-3.2-3.5h-18.5c-1.5 0-3 1.2-3.2 2.7l-16.2 104-.3.5c0 1.8 1.5 3.5 3.5 3.5h16.5c2.5 0 5-2.9 5.2-5.7L544 191.2v-.3zm-90 51.8c-12.2 0-21.7 9.7-21.7 22 0 9.7 7 15 16.2 15 12 0 21.7-9.2 21.7-21.5.1-9.8-6.9-15.5-16.2-15.5z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"cc-stripe\": {\n    \"changes\": [\n      \"4.2\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f1f5\",\n    \"label\": \"Stripe Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1548363722000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M492.4 220.8c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7zM375 223.4c-8.2 0-13.3 2.9-17 7l.2 52.8c3.5 3.7 8.5 6.7 16.8 6.7 13.1 0 21.9-14.3 21.9-33.4 0-18.6-9-33.2-21.9-33.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM122.2 281.1c0 25.6-20.3 40.1-49.9 40.3-12.2 0-25.6-2.4-38.8-8.1v-33.9c12 6.4 27.1 11.3 38.9 11.3 7.9 0 13.6-2.1 13.6-8.7 0-17-54-10.6-54-49.9 0-25.2 19.2-40.2 48-40.2 11.8 0 23.5 1.8 35.3 6.5v33.4c-10.8-5.8-24.5-9.1-35.3-9.1-7.5 0-12.1 2.2-12.1 7.7 0 16 54.3 8.4 54.3 50.7zm68.8-56.6h-27V275c0 20.9 22.5 14.4 27 12.6v28.9c-4.7 2.6-13.3 4.7-24.9 4.7-21.1 0-36.9-15.5-36.9-36.5l.2-113.9 34.7-7.4v30.8H191zm74 2.4c-4.5-1.5-18.7-3.6-27.1 7.4v84.4h-35.5V194.2h30.7l2.2 10.5c8.3-15.3 24.9-12.2 29.6-10.5h.1zm44.1 91.8h-35.7V194.2h35.7zm0-142.9l-35.7 7.6v-28.9l35.7-7.6zm74.1 145.5c-12.4 0-20-5.3-25.1-9l-.1 40.2-35.5 7.5V194.2h31.3l1.8 8.8c4.9-4.5 13.9-11.1 27.8-11.1 24.9 0 48.4 22.5 48.4 63.8 0 45.1-23.2 65.5-48.6 65.6zm160.4-51.5h-69.5c1.6 16.6 13.8 21.5 27.6 21.5 14.1 0 25.2-3 34.9-7.9V312c-9.7 5.3-22.4 9.2-39.4 9.2-34.6 0-58.8-21.7-58.8-64.5 0-36.2 20.5-64.9 54.3-64.9 33.7 0 51.3 28.7 51.3 65.1 0 3.5-.3 10.9-.4 12.9z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M492.4 220.8c-8.9 0-18.7 6.7-18.7 22.7h36.7c0-16-9.3-22.7-18-22.7zM375 223.4c-8.2 0-13.3 2.9-17 7l.2 52.8c3.5 3.7 8.5 6.7 16.8 6.7 13.1 0 21.9-14.3 21.9-33.4 0-18.6-9-33.2-21.9-33.1zM528 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM122.2 281.1c0 25.6-20.3 40.1-49.9 40.3-12.2 0-25.6-2.4-38.8-8.1v-33.9c12 6.4 27.1 11.3 38.9 11.3 7.9 0 13.6-2.1 13.6-8.7 0-17-54-10.6-54-49.9 0-25.2 19.2-40.2 48-40.2 11.8 0 23.5 1.8 35.3 6.5v33.4c-10.8-5.8-24.5-9.1-35.3-9.1-7.5 0-12.1 2.2-12.1 7.7 0 16 54.3 8.4 54.3 50.7zm68.8-56.6h-27V275c0 20.9 22.5 14.4 27 12.6v28.9c-4.7 2.6-13.3 4.7-24.9 4.7-21.1 0-36.9-15.5-36.9-36.5l.2-113.9 34.7-7.4v30.8H191zm74 2.4c-4.5-1.5-18.7-3.6-27.1 7.4v84.4h-35.5V194.2h30.7l2.2 10.5c8.3-15.3 24.9-12.2 29.6-10.5h.1zm44.1 91.8h-35.7V194.2h35.7zm0-142.9l-35.7 7.6v-28.9l35.7-7.6zm74.1 145.5c-12.4 0-20-5.3-25.1-9l-.1 40.2-35.5 7.5V194.2h31.3l1.8 8.8c4.9-4.5 13.9-11.1 27.8-11.1 24.9 0 48.4 22.5 48.4 63.8 0 45.1-23.2 65.5-48.6 65.6zm160.4-51.5h-69.5c1.6 16.6 13.8 21.5 27.6 21.5 14.1 0 25.2-3 34.9-7.9V312c-9.7 5.3-22.4 9.2-39.4 9.2-34.6 0-58.8-21.7-58.8-64.5 0-36.2 20.5-64.9 54.3-64.9 33.7 0 51.3 28.7 51.3 65.1 0 3.5-.3 10.9-.4 12.9z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"cc-visa\": {\n    \"changes\": [\n      \"4.2\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f1f0\",\n    \"label\": \"Visa Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M470.1 231.3s7.6 37.2 9.3 45H446c3.3-8.9 16-43.5 16-43.5-.2.3 3.3-9.1 5.3-14.9l2.8 13.4zM576 80v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48zM152.5 331.2L215.7 176h-42.5l-39.3 106-4.3-21.5-14-71.4c-2.3-9.9-9.4-12.7-18.2-13.1H32.7l-.7 3.1c15.8 4 29.9 9.8 42.2 17.1l35.8 135h42.5zm94.4.2L272.1 176h-40.2l-25.1 155.4h40.1zm139.9-50.8c.2-17.7-10.6-31.2-33.7-42.3-14.1-7.1-22.7-11.9-22.7-19.2.2-6.6 7.3-13.4 23.1-13.4 13.1-.3 22.7 2.8 29.9 5.9l3.6 1.7 5.5-33.6c-7.9-3.1-20.5-6.6-36-6.6-39.7 0-67.6 21.2-67.8 51.4-.3 22.3 20 34.7 35.2 42.2 15.5 7.6 20.8 12.6 20.8 19.3-.2 10.4-12.6 15.2-24.1 15.2-16 0-24.6-2.5-37.7-8.3l-5.3-2.5-5.6 34.9c9.4 4.3 26.8 8.1 44.8 8.3 42.2.1 69.7-20.8 70-53zM528 331.4L495.6 176h-31.1c-9.6 0-16.9 2.8-21 12.9l-59.7 142.5H426s6.9-19.2 8.4-23.3H486c1.2 5.5 4.8 23.3 4.8 23.3H528z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"chart-network\": {\n    \"changes\": [\n      \"5.6.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"activity\",\n        \"analytics\",\n        \"association\",\n        \"dashboard\",\n        \"diagram\",\n        \"distribution\",\n        \"map\",\n        \"network\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f78a\",\n    \"label\": \"Network Chart\",\n    \"voted\": true,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M64 240a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64zm88 80h48v-32h-48zm294.4-106.8l19.2 25.6 48-36-19.2-25.6zM576 64a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M576 384a63.84 63.84 0 0 0-38.3 13l-96-57.6a109.91 109.91 0 0 0 6.3-35.5 111.94 111.94 0 0 0-112-112 108.64 108.64 0 0 0-24.4 2.9l-40.8-87.4A63.84 63.84 0 1 0 224 128c1.1 0 2.1-.3 3.2-.3l41 87.8C241.5 235.9 224 267.8 224 304a111.71 111.71 0 0 0 193.2 76.7l95.8 57.5a63.87 63.87 0 1 0 63-54.2zm-240-32a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M64 240a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64zm88 80h48v-32h-48zm294.4-106.8l19.2 25.6 48-36-19.2-25.6zM576 64a64 64 0 1 0 64 64 64.06 64.06 0 0 0-64-64z\",\n          \"M576 384a63.84 63.84 0 0 0-38.3 13l-96-57.6a109.91 109.91 0 0 0 6.3-35.5 111.94 111.94 0 0 0-112-112 108.64 108.64 0 0 0-24.4 2.9l-40.8-87.4A63.84 63.84 0 1 0 224 128c1.1 0 2.1-.3 3.2-.3l41 87.8C241.5 235.9 224 267.8 224 304a111.71 111.71 0 0 0 193.2 76.7l95.8 57.5a63.87 63.87 0 1 0 63-54.2zm-240-32a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"chart-scatter\": {\n    \"changes\": [\n      \"5.7.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"analytics\",\n        \"chart\",\n        \"diagram\",\n        \"graph\",\n        \"plot\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f7ee\",\n    \"label\": \"Scatter Chart\",\n    \"voted\": true,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M512 400v32a16 16 0 0 1-16 16H32a32 32 0 0 1-32-32V80a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16v304h432a16 16 0 0 1 16 16z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M160 256a32 32 0 1 0 32 32 32 32 0 0 0-32-32zM416 96a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-224 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm192 160a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-96-64a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M512 400v32a16 16 0 0 1-16 16H32a32 32 0 0 1-32-32V80a16 16 0 0 1 16-16h32a16 16 0 0 1 16 16v304h432a16 16 0 0 1 16 16z\",\n          \"M160 256a32 32 0 1 0 32 32 32 32 0 0 0-32-32zM416 96a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-224 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm192 160a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm-96-64a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"check\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"accept\",\n        \"agree\",\n        \"checkmark\",\n        \"confirm\",\n        \"correct\",\n        \"done\",\n        \"notice\",\n        \"notification\",\n        \"notify\",\n        \"ok\",\n        \"select\",\n        \"success\",\n        \"tick\",\n        \"todo\",\n        \"yes\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\",\n      \"solid\"\n    ],\n    \"unicode\": \"f00c\",\n    \"label\": \"Check\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M504.5 144.42L264.75 385.5 192 312.59l240.11-241a25.49 25.49 0 0 1 36.06-.14l.14.14L504.5 108a25.86 25.86 0 0 1 0 36.42z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M264.67 385.59l-54.57 54.87a25.5 25.5 0 0 1-36.06.14l-.14-.14L7.5 273.1a25.84 25.84 0 0 1 0-36.41l36.2-36.41a25.49 25.49 0 0 1 36-.17l.16.17z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M504.5 144.42L264.75 385.5 192 312.59l240.11-241a25.49 25.49 0 0 1 36.06-.14l.14.14L504.5 108a25.86 25.86 0 0 1 0 36.42z\",\n          \"M264.67 385.59l-54.57 54.87a25.5 25.5 0 0 1-36.06.14l-.14-.14L7.5 273.1a25.84 25.84 0 0 1 0-36.41l36.2-36.41a25.49 25.49 0 0 1 36-.17l.16.17z\"\n        ]\n      },\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"check-circle\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"accept\",\n        \"agree\",\n        \"confirm\",\n        \"correct\",\n        \"done\",\n        \"ok\",\n        \"select\",\n        \"success\",\n        \"tick\",\n        \"todo\",\n        \"yes\"\n      ]\n    },\n    \"styles\": [\n      \"regular\"\n    ],\n    \"unicode\": \"f058\",\n    \"label\": \"Check Circle\",\n    \"voted\": false,\n    \"svg\": {\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M256 8C119.033 8 8 119.033 8 256s111.033 248 248 248 248-111.033 248-248S392.967 8 256 8zm0 48c110.532 0 200 89.451 200 200 0 110.532-89.451 200-200 200-110.532 0-200-89.451-200-200 0-110.532 89.451-200 200-200m140.204 130.267l-22.536-22.718c-4.667-4.705-12.265-4.736-16.97-.068L215.346 303.697l-59.792-60.277c-4.667-4.705-12.265-4.736-16.97-.069l-22.719 22.536c-4.705 4.667-4.736 12.265-.068 16.971l90.781 91.516c4.667 4.705 12.265 4.736 16.97.068l172.589-171.204c4.704-4.668 4.734-12.266.067-16.971z\"\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"circle\": {\n    \"changes\": [\n      \"3\",\n      \"5.0.0\",\n      \"5.10.1\",\n      \"5.10.2\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"circle-thin\",\n        \"diameter\",\n        \"dot\",\n        \"ellipse\",\n        \"notification\",\n        \"round\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\",\n      \"solid\"\n    ],\n    \"unicode\": \"f111\",\n    \"label\": \"Circle\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 424c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M256 432c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 424c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\",\n          \"M256 432c-97.06 0-176-79-176-176S158.94 80 256 80s176 79 176 176-78.94 176-176 176z\"\n        ]\n      },\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8z\"\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"cloud\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\",\n      \"5.0.11\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"atmosphere\",\n        \"fog\",\n        \"overcast\",\n        \"save\",\n        \"upload\",\n        \"weather\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f0c2\",\n    \"label\": \"Cloud\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><path d=\\\"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": \"M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"clouds\": {\n    \"changes\": [\n      \"5.5.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"cloudy\",\n        \"fog\",\n        \"haze\",\n        \"overcast\",\n        \"smoke\",\n        \"storm\",\n        \"weather\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f744\",\n    \"label\": \"Clouds\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M161.6 288H96a96 96 0 0 1 0-192c.6 0 1.1.2 1.6.2C105.3 41.9 151.6 0 208 0a111.61 111.61 0 0 1 104.5 72.7A95.07 95.07 0 0 1 352 64a96 96 0 0 1 96 96 93 93 0 0 1-7 34.7 110.5 110.5 0 0 0-31.6 11.8A142.54 142.54 0 0 0 304 160c-73.9 0-134.3 56.2-142.4 128z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M640 416a96 96 0 0 1-96 96H224a96 96 0 0 1-96-96c0-42.5 27.8-78.2 66.1-90.8A113.72 113.72 0 0 1 192 304a111.94 111.94 0 0 1 112-112c43.2 0 80.4 24.9 99 60.8 14.7-17.5 36.4-28.8 61-28.8a80 80 0 0 1 80 80 78.09 78.09 0 0 1-1.6 16.2c.5 0 1-.2 1.6-.2a96 96 0 0 1 96 96z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M161.6 288H96a96 96 0 0 1 0-192c.6 0 1.1.2 1.6.2C105.3 41.9 151.6 0 208 0a111.61 111.61 0 0 1 104.5 72.7A95.07 95.07 0 0 1 352 64a96 96 0 0 1 96 96 93 93 0 0 1-7 34.7 110.5 110.5 0 0 0-31.6 11.8A142.54 142.54 0 0 0 304 160c-73.9 0-134.3 56.2-142.4 128z\",\n          \"M640 416a96 96 0 0 1-96 96H224a96 96 0 0 1-96-96c0-42.5 27.8-78.2 66.1-90.8A113.72 113.72 0 0 1 192 304a111.94 111.94 0 0 1 112-112c43.2 0 80.4 24.9 99 60.8 14.7-17.5 36.4-28.8 61-28.8a80 80 0 0 1 80 80 78.09 78.09 0 0 1-1.6 16.2c.5 0 1-.2 1.6-.2a96 96 0 0 1 96 96z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"cogs\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"gears\",\n        \"mechanical\",\n        \"settings\",\n        \"sprocket\",\n        \"wheel\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f085\",\n    \"label\": \"cogs\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M638.41 387a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4L602 335a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6 12.36 12.36 0 0 0-15.1 5.4l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 44.9c-29.6-38.5 14.3-82.4 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79zm136.8-343.8a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4l8.2-14.3a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6A12.36 12.36 0 0 0 552 7.19l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 45c-29.6-38.5 14.3-82.5 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M420 303.79L386.31 287a173.78 173.78 0 0 0 0-63.5l33.7-16.8c10.1-5.9 14-18.2 10-29.1-8.9-24.2-25.9-46.4-42.1-65.8a23.93 23.93 0 0 0-30.3-5.3l-29.1 16.8a173.66 173.66 0 0 0-54.9-31.7V58a24 24 0 0 0-20-23.6 228.06 228.06 0 0 0-76 .1A23.82 23.82 0 0 0 158 58v33.7a171.78 171.78 0 0 0-54.9 31.7L74 106.59a23.91 23.91 0 0 0-30.3 5.3c-16.2 19.4-33.3 41.6-42.2 65.8a23.84 23.84 0 0 0 10.5 29l33.3 16.9a173.24 173.24 0 0 0 0 63.4L12 303.79a24.13 24.13 0 0 0-10.5 29.1c8.9 24.1 26 46.3 42.2 65.7a23.93 23.93 0 0 0 30.3 5.3l29.1-16.7a173.66 173.66 0 0 0 54.9 31.7v33.6a24 24 0 0 0 20 23.6 224.88 224.88 0 0 0 75.9 0 23.93 23.93 0 0 0 19.7-23.6v-33.6a171.78 171.78 0 0 0 54.9-31.7l29.1 16.8a23.91 23.91 0 0 0 30.3-5.3c16.2-19.4 33.7-41.6 42.6-65.8a24 24 0 0 0-10.5-29.1zm-151.3 4.3c-77 59.2-164.9-28.7-105.7-105.7 77-59.2 164.91 28.7 105.71 105.7z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M638.41 387a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4L602 335a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6 12.36 12.36 0 0 0-15.1 5.4l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 44.9c-29.6-38.5 14.3-82.4 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79zm136.8-343.8a12.34 12.34 0 0 0-12.2-10.3h-16.5a86.33 86.33 0 0 0-15.9-27.4l8.2-14.3a12.42 12.42 0 0 0-2.8-15.7 110.5 110.5 0 0 0-32.1-18.6A12.36 12.36 0 0 0 552 7.19l-8.2 14.3a88.86 88.86 0 0 0-31.7 0l-8.2-14.3a12.36 12.36 0 0 0-15.1-5.4 111.83 111.83 0 0 0-32.1 18.6 12.3 12.3 0 0 0-2.8 15.7l8.2 14.3a86.33 86.33 0 0 0-15.9 27.4h-16.5a12.43 12.43 0 0 0-12.2 10.4 112.66 112.66 0 0 0 0 37.1 12.34 12.34 0 0 0 12.2 10.3h16.5a86.33 86.33 0 0 0 15.9 27.4l-8.2 14.3a12.42 12.42 0 0 0 2.8 15.7 110.5 110.5 0 0 0 32.1 18.6 12.36 12.36 0 0 0 15.1-5.4l8.2-14.3a88.86 88.86 0 0 0 31.7 0l8.2 14.3a12.36 12.36 0 0 0 15.1 5.4 111.83 111.83 0 0 0 32.1-18.6 12.3 12.3 0 0 0 2.8-15.7l-8.2-14.3a86.33 86.33 0 0 0 15.9-27.4h16.5a12.43 12.43 0 0 0 12.2-10.4 112.66 112.66 0 0 0 .01-37.1zm-136.8 45c-29.6-38.5 14.3-82.5 52.8-52.8 29.59 38.49-14.3 82.39-52.8 52.79z\",\n          \"M420 303.79L386.31 287a173.78 173.78 0 0 0 0-63.5l33.7-16.8c10.1-5.9 14-18.2 10-29.1-8.9-24.2-25.9-46.4-42.1-65.8a23.93 23.93 0 0 0-30.3-5.3l-29.1 16.8a173.66 173.66 0 0 0-54.9-31.7V58a24 24 0 0 0-20-23.6 228.06 228.06 0 0 0-76 .1A23.82 23.82 0 0 0 158 58v33.7a171.78 171.78 0 0 0-54.9 31.7L74 106.59a23.91 23.91 0 0 0-30.3 5.3c-16.2 19.4-33.3 41.6-42.2 65.8a23.84 23.84 0 0 0 10.5 29l33.3 16.9a173.24 173.24 0 0 0 0 63.4L12 303.79a24.13 24.13 0 0 0-10.5 29.1c8.9 24.1 26 46.3 42.2 65.7a23.93 23.93 0 0 0 30.3 5.3l29.1-16.7a173.66 173.66 0 0 0 54.9 31.7v33.6a24 24 0 0 0 20 23.6 224.88 224.88 0 0 0 75.9 0 23.93 23.93 0 0 0 19.7-23.6v-33.6a171.78 171.78 0 0 0 54.9-31.7l29.1 16.8a23.91 23.91 0 0 0 30.3-5.3c16.2-19.4 33.7-41.6 42.6-65.8a24 24 0 0 0-10.5-29.1zm-151.3 4.3c-77 59.2-164.9-28.7-105.7-105.7 77-59.2 164.91 28.7 105.71 105.7z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"comment-dots\": {\n    \"changes\": [\n      \"5.0.9\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"bubble\",\n        \"chat\",\n        \"commenting\",\n        \"conversation\",\n        \"feedback\",\n        \"message\",\n        \"more\",\n        \"note\",\n        \"notification\",\n        \"reply\",\n        \"sms\",\n        \"speech\",\n        \"texting\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f4ad\",\n    \"label\": \"Comment Dots\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5a8 8 0 0 0-1.5 8.7A7.83 7.83 0 0 0 8 480c66.3 0 116-31.8 140.6-51.4A305 305 0 0 0 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M128 208a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M256 32C114.6 32 0 125.1 0 240c0 49.6 21.4 95 57 130.7C44.5 421.1 2.7 466 2.2 466.5a8 8 0 0 0-1.5 8.7A7.83 7.83 0 0 0 8 480c66.3 0 116-31.8 140.6-51.4A305 305 0 0 0 256 448c141.4 0 256-93.1 256-208S397.4 32 256 32zM128 272a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm128 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32z\",\n          \"M128 208a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32zm128 0a32 32 0 1 0 32 32 32 32 0 0 0-32-32z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"concierge-bell\": {\n    \"changes\": [\n      \"5.1.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"attention\",\n        \"hotel\",\n        \"receptionist\",\n        \"service\",\n        \"support\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f562\",\n    \"label\": \"Concierge Bell\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M512 400v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h480a16 16 0 0 1 16 16zM208 112h16v18.29a224.73 224.73 0 0 1 64 0V112h16a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M480 352H32c0-123.71 100.29-224 224-224s224 100.29 224 224z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M512 400v32a16 16 0 0 1-16 16H16a16 16 0 0 1-16-16v-32a16 16 0 0 1 16-16h480a16 16 0 0 1 16 16zM208 112h16v18.29a224.73 224.73 0 0 1 64 0V112h16a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16h-96a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16z\",\n          \"M480 352H32c0-123.71 100.29-224 224-224s224 100.29 224 224z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"credit-card\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"buy\",\n        \"checkout\",\n        \"credit-card-alt\",\n        \"debit\",\n        \"money\",\n        \"payment\",\n        \"purchase\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f09d\",\n    \"label\": \"Credit Card\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M0 432c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V256H0v176zm192-68c0-6.6 5.4-12 12-12h136c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H204c-6.6 0-12-5.4-12-12v-40zm-128 0c0-6.6 5.4-12 12-12h72c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12v-40zM576 80v48H0V80c0-26.5 21.5-48 48-48h480c26.5 0 48 21.5 48 48z\"\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"desktop\": {\n    \"changes\": [\n      \"3\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"computer\",\n        \"cpu\",\n        \"demo\",\n        \"desktop\",\n        \"device\",\n        \"imac\",\n        \"machine\",\n        \"monitor\",\n        \"pc\",\n        \"screen\"\n      ]\n    },\n    \"styles\": [\n      \"solid\",\n      \"regular\"\n    ],\n    \"unicode\": \"f108\",\n    \"label\": \"Desktop\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M528 0H48C21.5 0 0 21.5 0 48v320c0 26.5 21.5 48 48 48h192l-16 48h-72c-13.3 0-24 10.7-24 24s10.7 24 24 24h272c13.3 0 24-10.7 24-24s-10.7-24-24-24h-72l-16-48h192c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-16 352H64V64h448v288z\"\n      },\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M528 0H48C21.5 0 0 21.5 0 48v288c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V54c0-3.3 2.7-6 6-6h468c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-42 152c0 13.3-10.7 24-24 24H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h98.7l18.6-55.8c1.6-4.9 6.2-8.2 11.4-8.2h78.7c5.2 0 9.8 3.3 11.4 8.2l18.6 55.8H456c13.3 0 24 10.7 24 24z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M528 0H48C21.5 0 0 21.5 0 48v288c0 26.5 21.5 48 48 48h480c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48zm-6 336H54c-3.3 0-6-2.7-6-6V54c0-3.3 2.7-6 6-6h468c3.3 0 6 2.7 6 6v276c0 3.3-2.7 6-6 6zm-42 152c0 13.3-10.7 24-24 24H120c-13.3 0-24-10.7-24-24s10.7-24 24-24h98.7l18.6-55.8c1.6-4.9 6.2-8.2 11.4-8.2h78.7c5.2 0 9.8 3.3 11.4 8.2l18.6 55.8H456c13.3 0 24 10.7 24 24z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"discourse\": {\n    \"changes\": [\n      \"5.0.0\",\n      \"5.0.3\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f393\",\n    \"label\": \"Discourse\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M225.9 32C103.3 32 0 130.5 0 252.1 0 256 .1 480 .1 480l225.8-.2c122.7 0 222.1-102.3 222.1-223.9C448 134.3 348.6 32 225.9 32zM224 384c-19.4 0-37.9-4.3-54.4-12.1L88.5 392l22.9-75c-9.8-18.1-15.4-38.9-15.4-61 0-70.7 57.3-128 128-128s128 57.3 128 128-57.3 128-128 128z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"docker\": {\n    \"changes\": [\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f395\",\n    \"label\": \"Docker\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><path d=\\\"M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": \"M349.9 236.3h-66.1v-59.4h66.1v59.4zm0-204.3h-66.1v60.7h66.1V32zm78.2 144.8H362v59.4h66.1v-59.4zm-156.3-72.1h-66.1v60.1h66.1v-60.1zm78.1 0h-66.1v60.1h66.1v-60.1zm276.8 100c-14.4-9.7-47.6-13.2-73.1-8.4-3.3-24-16.7-44.9-41.1-63.7l-14-9.3-9.3 14c-18.4 27.8-23.4 73.6-3.7 103.8-8.7 4.7-25.8 11.1-48.4 10.7H2.4c-8.7 50.8 5.8 116.8 44 162.1 37.1 43.9 92.7 66.2 165.4 66.2 157.4 0 273.9-72.5 328.4-204.2 21.4.4 67.6.1 91.3-45.2 1.5-2.5 6.6-13.2 8.5-17.1l-13.3-8.9zm-511.1-27.9h-66v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm78.1 0h-66.1v59.4h66.1v-59.4zm-78.1-72.1h-66.1v60.1h66.1v-60.1z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"dot-circle\": {\n    \"changes\": [\n      \"4\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"bullseye\",\n        \"notification\",\n        \"target\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f192\",\n    \"label\": \"Dot Circle\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm124.45 372.45A176 176 0 1 1 432 256a174.85 174.85 0 0 1-51.55 124.45z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M256 336a80 80 0 1 1 80-80 80.09 80.09 0 0 1-80 80z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm124.45 372.45A176 176 0 1 1 432 256a174.85 174.85 0 0 1-51.55 124.45z\",\n          \"M256 336a80 80 0 1 1 80-80 80.09 80.09 0 0 1-80 80z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"envelope\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\",\n      \"5.10.1\",\n      \"5.10.2\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"e-mail\",\n        \"email\",\n        \"letter\",\n        \"mail\",\n        \"message\",\n        \"notification\",\n        \"support\"\n      ]\n    },\n    \"styles\": [\n      \"solid\",\n      \"duotone\"\n    ],\n    \"unicode\": \"f0e0\",\n    \"label\": \"Envelope\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M502.3 190.8c3.9-3.1 9.7-.2 9.7 4.7V400c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V195.6c0-5 5.7-7.8 9.7-4.7 22.4 17.4 52.1 39.5 154.1 113.6 21.1 15.4 56.7 47.8 92.2 47.6 35.7.3 72-32.8 92.3-47.6 102-74.1 131.6-96.3 154-113.7zM256 320c23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7 5.8-4.5 9.2-11.5 9.2-18.9v-19c0-26.5-21.5-48-48-48H48C21.5 64 0 85.5 0 112v19c0 7.4 3.4 14.3 9.2 18.9 30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4z\"\n      },\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M256.47 352h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V400a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V183.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52zM464 64H48a48 48 0 0 0-48 48v19a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4 23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131v-19a48 48 0 0 0-48-48z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M512 131v52.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V131a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.69 12.12 49.75 41.4 72.93 41.4h.94c23.18 0 56.24-29.28 72.93-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M256.47 352h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V400a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V183.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52zM464 64H48a48 48 0 0 0-48 48v19a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.8 12.2 50.2 41.8 73.4 41.4 23.2.4 56.6-29.2 73.4-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131v-19a48 48 0 0 0-48-48z\",\n          \"M512 131v52.36c-24.46 19.17-169.4 125.34-173 128.12-22.12 17.1-52.43 40.52-82.53 40.52h-.94c-30.1 0-60.41-23.42-82.54-40.52C169.39 308.7 24.77 202.7 0 183.33V131a24.08 24.08 0 0 0 9.2 18.9c30.6 23.9 40.7 32.4 173.4 128.7 16.69 12.12 49.75 41.4 72.93 41.4h.94c23.18 0 56.24-29.28 72.93-41.4 132.7-96.3 142.8-104.7 173.4-128.7A23.93 23.93 0 0 0 512 131z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"exchange-alt\": {\n    \"changes\": [\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"arrow\",\n        \"arrows\",\n        \"exchange\",\n        \"reciprocate\",\n        \"return\",\n        \"swap\",\n        \"transfer\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f362\",\n    \"label\": \"Alternate Exchange\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M128 272v48h360a24 24 0 0 1 24 24v16a24 24 0 0 1-24 24H128v48c0 21.44-25.94 32-41 17L7 369a24 24 0 0 1 0-33.94l80-80c15.14-15.12 41-4.35 41 16.94z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M505 143.05a24 24 0 0 1 0 33.95l-80 80c-15 15-41 4.49-41-17v-48H24a24 24 0 0 1-24-24v-16a24 24 0 0 1 24-24h360V80c0-21.36 25.9-32 41-17z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M128 272v48h360a24 24 0 0 1 24 24v16a24 24 0 0 1-24 24H128v48c0 21.44-25.94 32-41 17L7 369a24 24 0 0 1 0-33.94l80-80c15.14-15.12 41-4.35 41 16.94z\",\n          \"M505 143.05a24 24 0 0 1 0 33.95l-80 80c-15 15-41 4.49-41-17v-48H24a24 24 0 0 1-24-24v-16a24 24 0 0 1 24-24h360V80c0-21.36 25.9-32 41-17z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"eye\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\",\n      \"5.7.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"look\",\n        \"optic\",\n        \"see\",\n        \"seen\",\n        \"show\",\n        \"sight\",\n        \"views\",\n        \"visible\"\n      ]\n    },\n    \"styles\": [\n      \"solid\",\n      \"regular\"\n    ],\n    \"unicode\": \"f06e\",\n    \"label\": \"Eye\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M572.52 241.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400a144 144 0 1 1 144-144 143.93 143.93 0 0 1-144 144zm0-240a95.31 95.31 0 0 0-25.31 3.79 47.85 47.85 0 0 1-66.9 66.9A95.78 95.78 0 1 0 288 160z\"\n      },\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M288 144a110.94 110.94 0 0 0-31.24 5 55.4 55.4 0 0 1 7.24 27 56 56 0 0 1-56 56 55.4 55.4 0 0 1-27-7.24A111.71 111.71 0 1 0 288 144zm284.52 97.4C518.29 135.59 410.93 64 288 64S57.68 135.64 3.48 241.41a32.35 32.35 0 0 0 0 29.19C57.71 376.41 165.07 448 288 448s230.32-71.64 284.52-177.41a32.35 32.35 0 0 0 0-29.19zM288 400c-98.65 0-189.09-55-237.93-144C98.91 167 189.34 112 288 112s189.09 55 237.93 144C477.1 345 386.66 400 288 400z\"\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"file-alt\": {\n    \"changes\": [\n      \"3.2\",\n      \"5.0.0\",\n      \"5.10.2\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"document\",\n        \"file-text\",\n        \"invoice\",\n        \"new\",\n        \"page\",\n        \"pdf\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f15c\",\n    \"label\": \"Alternate File\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 384 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zm-96 244a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM276 352H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"384\",\n          \"512\"\n        ],\n        \"width\": 384,\n        \"height\": 512,\n        \"path\": [\n          \"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zm-96 244a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12zm0-64a12 12 0 0 1-12 12H108a12 12 0 0 1-12-12v-8a12 12 0 0 1 12-12h168a12 12 0 0 1 12 12z\",\n          \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM276 352H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12zm0-64H108a12 12 0 0 0-12 12v8a12 12 0 0 0 12 12h168a12 12 0 0 0 12-12v-8a12 12 0 0 0-12-12z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"file-code\": {\n    \"changes\": [\n      \"4.1\",\n      \"5.0.0\",\n      \"5.10.2\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"css\",\n        \"development\",\n        \"document\",\n        \"html\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\",\n      \"regular\"\n    ],\n    \"unicode\": \"f1c9\",\n    \"label\": \"Code File\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 384 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zM141.79 379.54l-19.58 20.84a5.41 5.41 0 0 1-7.64.24l-64.86-60.69a5.37 5.37 0 0 1-.24-7.6l.25-.25 64.86-60.7a5.42 5.42 0 0 1 7.64.24l19.58 20.85a5.4 5.4 0 0 1-.25 7.62l-.13.12L100.65 336l40.76 35.8a5.4 5.4 0 0 1 .49 7.62zm31.71 71.25l-27.45-8a5.38 5.38 0 0 1-3.67-6.67l61.49-211.24a5.38 5.38 0 0 1 6.68-3.64l27.45 8a5.4 5.4 0 0 1 3.63 6.67l-61.45 211.2a5.4 5.4 0 0 1-6.68 3.68zm161-111.12l-.25.25-64.86 60.69a5.42 5.42 0 0 1-7.64-.23l-19.58-20.84a5.37 5.37 0 0 1 .26-7.6l.13-.12L283.35 336l-40.76-35.8a5.4 5.4 0 0 1-.49-7.62l.11-.12 19.58-20.85a5.42 5.42 0 0 1 7.64-.24l64.86 60.7a5.36 5.36 0 0 1 .25 7.6z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM141.41 371.8L100.65 336l40.76-35.8.13-.12a5.4 5.4 0 0 0 .25-7.62l-19.58-20.85a5.42 5.42 0 0 0-7.64-.24l-64.86 60.7-.25.25a5.37 5.37 0 0 0 .24 7.6l64.86 60.69a5.41 5.41 0 0 0 7.64-.24l19.58-20.84.11-.12a5.4 5.4 0 0 0-.48-7.61zm100.22-135.93a5.4 5.4 0 0 0-3.63-6.67l-27.45-8a5.38 5.38 0 0 0-6.68 3.64l-61.5 211.29a5.38 5.38 0 0 0 3.63 6.67l27.45 8a5.4 5.4 0 0 0 6.68-3.68l61.44-211.22zm92.66 96.2l-64.86-60.7a5.42 5.42 0 0 0-7.64.24l-19.58 20.85-.11.12a5.4 5.4 0 0 0 .49 7.62l40.76 35.8-40.76 35.8-.13.12a5.37 5.37 0 0 0-.26 7.6l19.58 20.84a5.42 5.42 0 0 0 7.64.23l64.86-60.69.25-.25a5.36 5.36 0 0 0-.25-7.6z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"384\",\n          \"512\"\n        ],\n        \"width\": 384,\n        \"height\": 512,\n        \"path\": [\n          \"M384 128H272a16 16 0 0 1-16-16V0H24A23.94 23.94 0 0 0 0 23.88V488a23.94 23.94 0 0 0 23.88 24H360a23.94 23.94 0 0 0 24-23.88V128zM141.79 379.54l-19.58 20.84a5.41 5.41 0 0 1-7.64.24l-64.86-60.69a5.37 5.37 0 0 1-.24-7.6l.25-.25 64.86-60.7a5.42 5.42 0 0 1 7.64.24l19.58 20.85a5.4 5.4 0 0 1-.25 7.62l-.13.12L100.65 336l40.76 35.8a5.4 5.4 0 0 1 .49 7.62zm31.71 71.25l-27.45-8a5.38 5.38 0 0 1-3.67-6.67l61.49-211.24a5.38 5.38 0 0 1 6.68-3.64l27.45 8a5.4 5.4 0 0 1 3.63 6.67l-61.45 211.2a5.4 5.4 0 0 1-6.68 3.68zm161-111.12l-.25.25-64.86 60.69a5.42 5.42 0 0 1-7.64-.23l-19.58-20.84a5.37 5.37 0 0 1 .26-7.6l.13-.12L283.35 336l-40.76-35.8a5.4 5.4 0 0 1-.49-7.62l.11-.12 19.58-20.85a5.42 5.42 0 0 1 7.64-.24l64.86 60.7a5.36 5.36 0 0 1 .25 7.6z\",\n          \"M377 105L279.1 7a24 24 0 0 0-17-7H256v112a16 16 0 0 0 16 16h112v-6.1a23.9 23.9 0 0 0-7-16.9zM141.41 371.8L100.65 336l40.76-35.8.13-.12a5.4 5.4 0 0 0 .25-7.62l-19.58-20.85a5.42 5.42 0 0 0-7.64-.24l-64.86 60.7-.25.25a5.37 5.37 0 0 0 .24 7.6l64.86 60.69a5.41 5.41 0 0 0 7.64-.24l19.58-20.84.11-.12a5.4 5.4 0 0 0-.48-7.61zm100.22-135.93a5.4 5.4 0 0 0-3.63-6.67l-27.45-8a5.38 5.38 0 0 0-6.68 3.64l-61.5 211.29a5.38 5.38 0 0 0 3.63 6.67l27.45 8a5.4 5.4 0 0 0 6.68-3.68l61.44-211.22zm92.66 96.2l-64.86-60.7a5.42 5.42 0 0 0-7.64.24l-19.58 20.85-.11.12a5.4 5.4 0 0 0 .49 7.62l40.76 35.8-40.76 35.8-.13.12a5.37 5.37 0 0 0-.26 7.6l19.58 20.84a5.42 5.42 0 0 0 7.64.23l64.86-60.69.25-.25a5.36 5.36 0 0 0-.25-7.6z\"\n        ]\n      },\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 384 512\\\"><path d=\\\"M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"384\",\n          \"512\"\n        ],\n        \"width\": 384,\n        \"height\": 512,\n        \"path\": \"M149.9 349.1l-.2-.2-32.8-28.9 32.8-28.9c3.6-3.2 4-8.8.8-12.4l-.2-.2-17.4-18.6c-3.4-3.6-9-3.7-12.4-.4l-57.7 54.1c-3.7 3.5-3.7 9.4 0 12.8l57.7 54.1c1.6 1.5 3.8 2.4 6 2.4 2.4 0 4.8-1 6.4-2.8l17.4-18.6c3.3-3.5 3.1-9.1-.4-12.4zm220-251.2L286 14C277 5 264.8-.1 252.1-.1H48C21.5 0 0 21.5 0 48v416c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V131.9c0-12.7-5.1-25-14.1-34zM256 51.9l76.1 76.1H256zM336 464H48V48h160v104c0 13.3 10.7 24 24 24h104zM209.6 214c-4.7-1.4-9.5 1.3-10.9 6L144 408.1c-1.4 4.7 1.3 9.6 6 10.9l24.4 7.1c4.7 1.4 9.6-1.4 10.9-6L240 231.9c1.4-4.7-1.3-9.6-6-10.9zm24.5 76.9l.2.2 32.8 28.9-32.8 28.9c-3.6 3.2-4 8.8-.8 12.4l.2.2 17.4 18.6c3.3 3.5 8.9 3.7 12.4.4l57.7-54.1c3.7-3.5 3.7-9.4 0-12.8l-57.7-54.1c-3.5-3.3-9.1-3.2-12.4.4l-17.4 18.6c-3.3 3.5-3.1 9.1.4 12.4z\"\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"fingerprint\": {\n    \"changes\": [\n      \"5.1.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"human\",\n        \"id\",\n        \"identification\",\n        \"lock\",\n        \"smudge\",\n        \"touch\",\n        \"unique\",\n        \"unlock\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f577\",\n    \"label\": \"Fingerprint\",\n    \"voted\": true,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M256.12 245.96c-13.25 0-24 10.74-24 24 1.14 72.25-8.14 141.9-27.7 211.55-2.73 9.72 2.15 30.49 23.12 30.49 10.48 0 20.11-6.92 23.09-17.52 13.53-47.91 31.04-125.41 29.48-224.52.01-13.25-10.73-24-23.99-24zm-.86-81.73C194 164.16 151.25 211.3 152.1 265.32c.75 47.94-3.75 95.91-13.37 142.55-2.69 12.98 5.67 25.69 18.64 28.36 13.05 2.67 25.67-5.66 28.36-18.64 10.34-50.09 15.17-101.58 14.37-153.02-.41-25.95 19.92-52.49 54.45-52.34 31.31.47 57.15 25.34 57.62 55.47.77 48.05-2.81 96.33-10.61 143.55-2.17 13.06 6.69 25.42 19.76 27.58 19.97 3.33 26.81-15.1 27.58-19.77 8.28-50.03 12.06-101.21 11.27-152.11-.88-55.8-47.94-101.88-104.91-102.72zm-110.69-19.78c-10.3-8.34-25.37-6.8-33.76 3.48-25.62 31.5-39.39 71.28-38.75 112 .59 37.58-2.47 75.27-9.11 112.05-2.34 13.05 6.31 25.53 19.36 27.89 20.11 3.5 27.07-14.81 27.89-19.36 7.19-39.84 10.5-80.66 9.86-121.33-.47-29.88 9.2-57.88 28-80.97 8.35-10.28 6.79-25.39-3.49-33.76zm109.47-62.33c-15.41-.41-30.87 1.44-45.78 4.97-12.89 3.06-20.87 15.98-17.83 28.89 3.06 12.89 16 20.83 28.89 17.83 11.05-2.61 22.47-3.77 34-3.69 75.43 1.13 137.73 61.5 138.88 134.58.59 37.88-1.28 76.11-5.58 113.63-1.5 13.17 7.95 25.08 21.11 26.58 16.72 1.95 25.51-11.88 26.58-21.11a929.06 929.06 0 0 0 5.89-119.85c-1.56-98.75-85.07-180.33-186.16-181.83zm252.07 121.45c-2.86-12.92-15.51-21.2-28.61-18.27-12.94 2.86-21.12 15.66-18.26 28.61 4.71 21.41 4.91 37.41 4.7 61.6-.11 13.27 10.55 24.09 23.8 24.2h.2c13.17 0 23.89-10.61 24-23.8.18-22.18.4-44.11-5.83-72.34zm-40.12-90.72C417.29 43.46 337.6 1.29 252.81.02 183.02-.82 118.47 24.91 70.46 72.94 24.09 119.37-.9 181.04.14 246.65l-.12 21.47c-.39 13.25 10.03 24.31 23.28 24.69.23.02.48.02.72.02 12.92 0 23.59-10.3 23.97-23.3l.16-23.64c-.83-52.5 19.16-101.86 56.28-139 38.76-38.8 91.34-59.67 147.68-58.86 69.45 1.03 134.73 35.56 174.62 92.39 7.61 10.86 22.56 13.45 33.42 5.86 10.84-7.62 13.46-22.59 5.84-33.43z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M256.12 245.96c-13.25 0-24 10.74-24 24 1.14 72.25-8.14 141.9-27.7 211.55-2.73 9.72 2.15 30.49 23.12 30.49 10.48 0 20.11-6.92 23.09-17.52 13.53-47.91 31.04-125.41 29.48-224.52.01-13.25-10.73-24-23.99-24zm-.86-81.73C194 164.16 151.25 211.3 152.1 265.32c.75 47.94-3.75 95.91-13.37 142.55-2.69 12.98 5.67 25.69 18.64 28.36 13.05 2.67 25.67-5.66 28.36-18.64 10.34-50.09 15.17-101.58 14.37-153.02-.41-25.95 19.92-52.49 54.45-52.34 31.31.47 57.15 25.34 57.62 55.47.77 48.05-2.81 96.33-10.61 143.55-2.17 13.06 6.69 25.42 19.76 27.58 19.97 3.33 26.81-15.1 27.58-19.77 8.28-50.03 12.06-101.21 11.27-152.11-.88-55.8-47.94-101.88-104.91-102.72zm-110.69-19.78c-10.3-8.34-25.37-6.8-33.76 3.48-25.62 31.5-39.39 71.28-38.75 112 .59 37.58-2.47 75.27-9.11 112.05-2.34 13.05 6.31 25.53 19.36 27.89 20.11 3.5 27.07-14.81 27.89-19.36 7.19-39.84 10.5-80.66 9.86-121.33-.47-29.88 9.2-57.88 28-80.97 8.35-10.28 6.79-25.39-3.49-33.76zm109.47-62.33c-15.41-.41-30.87 1.44-45.78 4.97-12.89 3.06-20.87 15.98-17.83 28.89 3.06 12.89 16 20.83 28.89 17.83 11.05-2.61 22.47-3.77 34-3.69 75.43 1.13 137.73 61.5 138.88 134.58.59 37.88-1.28 76.11-5.58 113.63-1.5 13.17 7.95 25.08 21.11 26.58 16.72 1.95 25.51-11.88 26.58-21.11a929.06 929.06 0 0 0 5.89-119.85c-1.56-98.75-85.07-180.33-186.16-181.83zm252.07 121.45c-2.86-12.92-15.51-21.2-28.61-18.27-12.94 2.86-21.12 15.66-18.26 28.61 4.71 21.41 4.91 37.41 4.7 61.6-.11 13.27 10.55 24.09 23.8 24.2h.2c13.17 0 23.89-10.61 24-23.8.18-22.18.4-44.11-5.83-72.34zm-40.12-90.72C417.29 43.46 337.6 1.29 252.81.02 183.02-.82 118.47 24.91 70.46 72.94 24.09 119.37-.9 181.04.14 246.65l-.12 21.47c-.39 13.25 10.03 24.31 23.28 24.69.23.02.48.02.72.02 12.92 0 23.59-10.3 23.97-23.3l.16-23.64c-.83-52.5 19.16-101.86 56.28-139 38.76-38.8 91.34-59.67 147.68-58.86 69.45 1.03 134.73 35.56 174.62 92.39 7.61 10.86 22.56 13.45 33.42 5.86 10.84-7.62 13.46-22.59 5.84-33.43z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"github\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"octocat\"\n      ]\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f09b\",\n    \"label\": \"GitHub\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 496 512\\\"><path d=\\\"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"496\",\n          \"512\"\n        ],\n        \"width\": 496,\n        \"height\": 512,\n        \"path\": \"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"globe\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\",\n      \"5.0.9\",\n      \"5.11.0\",\n      \"5.11.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"all\",\n        \"coordinates\",\n        \"country\",\n        \"earth\",\n        \"global\",\n        \"gps\",\n        \"language\",\n        \"localize\",\n        \"location\",\n        \"map\",\n        \"online\",\n        \"place\",\n        \"planet\",\n        \"translate\",\n        \"travel\",\n        \"world\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f0ac\",\n    \"label\": \"Globe\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 496 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M340.45,320H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256,575,575,0,0,1,340.45,320ZM160.2,160H335.8c-.41-2.31-.84-4.62-1.28-6.91-6-30.85-14.42-58.37-25.13-81.78C299.54,49.77,288,32.54,276.05,21.48,266.38,12.53,256.94,8,248,8s-18.38,4.53-28,13.48c-12,11.06-23.49,28.29-33.34,49.83C176,94.72,167.5,122.24,161.53,153.09,161,155.38,160.61,157.69,160.2,160ZM120,256a608,608,0,0,1,3.34-64H8.35a249.52,249.52,0,0,0,0,128h115A608,608,0,0,1,120,256Zm367.62-64h-115A608.06,608.06,0,0,1,376,256a608,608,0,0,1-3.34,64h115a249.52,249.52,0,0,0,0-128ZM476.7,160A248.62,248.62,0,0,0,315.58,17.32c24.13,33,42.89,83.15,52.75,142.68ZM315.58,494.68A248.59,248.59,0,0,0,476.71,352H368.33C358.47,411.53,339.71,461.68,315.58,494.68ZM335.8,352H160.2c.41,2.31.84,4.62,1.28,6.91,6,30.85,14.42,58.37,25.13,81.78,9.85,21.54,21.38,38.77,33.34,49.83,9.67,9,19.11,13.48,28.05,13.48s18.38-4.53,28.05-13.48c12-11.06,23.49-28.29,33.34-49.83,10.71-23.41,19.16-50.93,25.13-81.78C335,356.62,335.39,354.31,335.8,352ZM180.42,17.32A248.59,248.59,0,0,0,19.29,160H127.67C137.53,100.47,156.29,50.32,180.42,17.32ZM19.29,352A248.59,248.59,0,0,0,180.42,494.68c-24.13-33-42.89-83.15-52.75-142.68Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M376,256a608,608,0,0,0-3.34-64h115a245.72,245.72,0,0,0-10.92-32H368.33c-9.86-59.53-28.62-109.68-52.75-142.68A248.23,248.23,0,0,0,248,8c8.94,0,18.38,4.53,28.05,13.48,12,11.06,23.49,28.29,33.34,49.83,10.71,23.41,19.16,50.93,25.13,81.78.44,2.29.87,4.6,1.28,6.91H160.2c.41-2.31.84-4.62,1.28-6.91,6-30.85,14.42-58.37,25.13-81.78C196.46,49.77,208,32.54,220,21.48,229.62,12.53,239.06,8,248,8a248.23,248.23,0,0,0-67.58,9.32c-24.13,33-42.89,83.15-52.75,142.68H19.29A245.72,245.72,0,0,0,8.37,192h115a613.93,613.93,0,0,0,0,128H8.37a245.72,245.72,0,0,0,10.92,32H127.67c9.86,59.53,28.62,109.68,52.75,142.68A248.23,248.23,0,0,0,248,504c-8.94,0-18.38-4.53-28.05-13.48-12-11.06-23.49-28.29-33.34-49.83-10.71-23.41-19.16-50.93-25.13-81.78-.44-2.29-.87-4.6-1.28-6.91H335.8c-.41,2.31-.84,4.62-1.28,6.91-6,30.85-14.42,58.37-25.13,81.78-9.85,21.54-21.38,38.77-33.34,49.83-9.67,9-19.11,13.48-28.05,13.48a248.23,248.23,0,0,0,67.58-9.32c24.13-33,42.89-83.15,52.75-142.68H476.71a245.72,245.72,0,0,0,10.92-32h-115A605.37,605.37,0,0,0,376,256Zm-35.54,64H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256a575,575,0,0,1-3.55,64Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"496\",\n          \"512\"\n        ],\n        \"width\": 496,\n        \"height\": 512,\n        \"path\": [\n          \"M340.45,320H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256,575,575,0,0,1,340.45,320ZM160.2,160H335.8c-.41-2.31-.84-4.62-1.28-6.91-6-30.85-14.42-58.37-25.13-81.78C299.54,49.77,288,32.54,276.05,21.48,266.38,12.53,256.94,8,248,8s-18.38,4.53-28,13.48c-12,11.06-23.49,28.29-33.34,49.83C176,94.72,167.5,122.24,161.53,153.09,161,155.38,160.61,157.69,160.2,160ZM120,256a608,608,0,0,1,3.34-64H8.35a249.52,249.52,0,0,0,0,128h115A608,608,0,0,1,120,256Zm367.62-64h-115A608.06,608.06,0,0,1,376,256a608,608,0,0,1-3.34,64h115a249.52,249.52,0,0,0,0-128ZM476.7,160A248.62,248.62,0,0,0,315.58,17.32c24.13,33,42.89,83.15,52.75,142.68ZM315.58,494.68A248.59,248.59,0,0,0,476.71,352H368.33C358.47,411.53,339.71,461.68,315.58,494.68ZM335.8,352H160.2c.41,2.31.84,4.62,1.28,6.91,6,30.85,14.42,58.37,25.13,81.78,9.85,21.54,21.38,38.77,33.34,49.83,9.67,9,19.11,13.48,28.05,13.48s18.38-4.53,28.05-13.48c12-11.06,23.49-28.29,33.34-49.83,10.71-23.41,19.16-50.93,25.13-81.78C335,356.62,335.39,354.31,335.8,352ZM180.42,17.32A248.59,248.59,0,0,0,19.29,160H127.67C137.53,100.47,156.29,50.32,180.42,17.32ZM19.29,352A248.59,248.59,0,0,0,180.42,494.68c-24.13-33-42.89-83.15-52.75-142.68Z\",\n          \"M376,256a608,608,0,0,0-3.34-64h115a245.72,245.72,0,0,0-10.92-32H368.33c-9.86-59.53-28.62-109.68-52.75-142.68A248.23,248.23,0,0,0,248,8c8.94,0,18.38,4.53,28.05,13.48,12,11.06,23.49,28.29,33.34,49.83,10.71,23.41,19.16,50.93,25.13,81.78.44,2.29.87,4.6,1.28,6.91H160.2c.41-2.31.84-4.62,1.28-6.91,6-30.85,14.42-58.37,25.13-81.78C196.46,49.77,208,32.54,220,21.48,229.62,12.53,239.06,8,248,8a248.23,248.23,0,0,0-67.58,9.32c-24.13,33-42.89,83.15-52.75,142.68H19.29A245.72,245.72,0,0,0,8.37,192h115a613.93,613.93,0,0,0,0,128H8.37a245.72,245.72,0,0,0,10.92,32H127.67c9.86,59.53,28.62,109.68,52.75,142.68A248.23,248.23,0,0,0,248,504c-8.94,0-18.38-4.53-28.05-13.48-12-11.06-23.49-28.29-33.34-49.83-10.71-23.41-19.16-50.93-25.13-81.78-.44-2.29-.87-4.6-1.28-6.91H335.8c-.41,2.31-.84,4.62-1.28,6.91-6,30.85-14.42,58.37-25.13,81.78-9.85,21.54-21.38,38.77-33.34,49.83-9.67,9-19.11,13.48-28.05,13.48a248.23,248.23,0,0,0,67.58-9.32c24.13-33,42.89-83.15,52.75-142.68H476.71a245.72,245.72,0,0,0,10.92-32h-115A605.37,605.37,0,0,0,376,256Zm-35.54,64H155.55a579.08,579.08,0,0,1,0-128h184.9A575,575,0,0,1,344,256a575,575,0,0,1-3.55,64Z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"globe-africa\": {\n    \"changes\": [\n      \"5.1.0\",\n      \"5.11.0\",\n      \"5.11.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"all\",\n        \"country\",\n        \"earth\",\n        \"global\",\n        \"gps\",\n        \"language\",\n        \"localize\",\n        \"location\",\n        \"map\",\n        \"online\",\n        \"place\",\n        \"planet\",\n        \"translate\",\n        \"travel\",\n        \"world\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f57c\",\n    \"label\": \"Globe with Africa shown\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 496 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M491.33,208H423.5A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05A249.89,249.89,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256A249.51,249.51,0,0,0,491.33,208Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M423.5,208A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05C386,23.7,471,104.24,491.34,208Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"496\",\n          \"512\"\n        ],\n        \"width\": 496,\n        \"height\": 512,\n        \"path\": [\n          \"M491.33,208H423.5A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05A249.89,249.89,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256A249.51,249.51,0,0,0,491.33,208Z\",\n          \"M423.5,208A15.5,15.5,0,0,0,408,223.5h0v6.93a15.49,15.49,0,0,1-8.57,13.86L384,252a15.49,15.49,0,0,1-15.53-1L350.3,238.88a15.52,15.52,0,0,0-13.5-1.81l-2.65.88a15.47,15.47,0,0,0-9.83,19.56,15.83,15.83,0,0,0,1.83,3.74l13.24,19.86a15.49,15.49,0,0,0,12.89,6.9h8.21a15.5,15.5,0,0,1,15.5,15.5v11.34a15.52,15.52,0,0,1-3.1,9.3l-18.74,25a15.57,15.57,0,0,0-2.83,6.43L347,378.39a15.53,15.53,0,0,1-4.76,8.56,159.61,159.61,0,0,0-25,29.16l-13,19.55a27.77,27.77,0,0,1-47.91-3A78.82,78.82,0,0,1,248,397.39V367.5A15.5,15.5,0,0,0,232.5,352H206.62A54.63,54.63,0,0,1,152,297.37V283.31a54.65,54.65,0,0,1,21.85-43.7l27.58-20.69A54.6,54.6,0,0,1,234.2,208h.89a54.52,54.52,0,0,1,24.43,5.77l14.72,7.36a15.49,15.49,0,0,0,11.83.84l47.31-15.77a15.5,15.5,0,0,0-4.9-30.2H318.39a15.5,15.5,0,0,1-11-4.54l-6.92-6.92a15.5,15.5,0,0,0-11-4.54h-90A15.5,15.5,0,0,1,184,144.5v-4.4a15.52,15.52,0,0,1,11.74-15l14.45-3.61a15.53,15.53,0,0,0,9.14-6.44l8.08-12.11A15.47,15.47,0,0,1,240.3,96h24.21A15.5,15.5,0,0,0,280,80.49V10.05C386,23.7,471,104.24,491.34,208Z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"globe-americas\": {\n    \"changes\": [\n      \"5.1.0\",\n      \"5.11.0\",\n      \"5.11.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"all\",\n        \"country\",\n        \"earth\",\n        \"global\",\n        \"gps\",\n        \"language\",\n        \"localize\",\n        \"location\",\n        \"map\",\n        \"online\",\n        \"place\",\n        \"planet\",\n        \"translate\",\n        \"travel\",\n        \"world\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f57d\",\n    \"label\": \"Globe with Americas shown\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 496 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M489.55,312.41C464,422.22,365.59,504,248,504,111,504,0,393,0,256A247,247,0,0,1,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311l-13.71-13.67A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A247,247,0,0,1,248,8C351.83,8,440.71,71.76,477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M321.39,297.36A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A249,249,0,0,0,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311ZM477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1,55.64,29.22a249.21,249.21,0,0,0-11.88-150.14Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"496\",\n          \"512\"\n        ],\n        \"width\": 496,\n        \"height\": 512,\n        \"path\": [\n          \"M489.55,312.41C464,422.22,365.59,504,248,504,111,504,0,393,0,256A247,247,0,0,1,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311l-13.71-13.67A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A247,247,0,0,1,248,8C351.83,8,440.71,71.76,477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1Z\",\n          \"M321.39,297.36A32,32,0,0,0,298.76,288H232c-9.41-4.71-21.48-32-32-32a67.72,67.72,0,0,1-30.31-7.16l-11.08-5.54a12,12,0,0,1,1.56-22l31.17-10.39A16,16,0,0,1,206.9,214l9.28,8.06a8,8,0,0,0,5.24,2h5.64a8,8,0,0,0,7.15-11.58l-15.59-31.19A8,8,0,0,1,220.2,172l9.92-9.65A8,8,0,0,1,235.7,160h9a8,8,0,0,0,5.66-2.34l8-8a8,8,0,0,0,0-11.31l-4.69-4.69a8,8,0,0,1,0-11.31L264,112l4.69-4.68a16,16,0,0,0,0-22.63h0l-24.4-24.4a12.38,12.38,0,0,0-9.55-3.61c-2.53.17-5.05.38-7.58.65A12.41,12.41,0,0,0,216,69.66a16.35,16.35,0,0,1-11.59,15.83,16,16,0,0,1-11.57-1.07,66.09,66.09,0,0,1-16-11.24L136.26,34.54A249,249,0,0,0,56,99v45.71a50,50,0,0,0,8.55,27.95c11.72,17.39,28.38,42.07,35.67,52.77a114.79,114.79,0,0,0,18.06,20.74l.8.72a144.26,144.26,0,0,0,31.65,21.75c14,7.05,34.44,18.16,48.81,26.11a31.9,31.9,0,0,1,16.46,28v32a32,32,0,0,0,9.37,22.63c15,15,24.32,38.63,22.63,51.25V457.7a21,21,0,0,0,23.49,20.85c1.75-.21,3.49-.44,5.23-.7a20.91,20.91,0,0,0,17.17-15.76L308,404.46c2-5.49,3.26-11.21,4.77-16.87A23.9,23.9,0,0,1,319,376.88c3.32-3.33,7.41-7.4,11.31-11.28a46.46,46.46,0,0,0,13.72-33A30.49,30.49,0,0,0,335.1,311ZM477.67,162.27l-36.51,3.15a76.22,76.22,0,0,0-27.48,7.74,24.05,24.05,0,0,0-9.24,8.15l-19.59,29.38a24,24,0,0,0,0,26.62l18,27a24,24,0,0,0,10.54,8.78l20.52,10.1,55.64,29.22a249.21,249.21,0,0,0-11.88-150.14Z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"globe-asia\": {\n    \"changes\": [\n      \"5.1.0\",\n      \"5.11.0\",\n      \"5.11.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"all\",\n        \"country\",\n        \"earth\",\n        \"global\",\n        \"gps\",\n        \"language\",\n        \"localize\",\n        \"location\",\n        \"map\",\n        \"online\",\n        \"place\",\n        \"planet\",\n        \"translate\",\n        \"travel\",\n        \"world\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f57e\",\n    \"label\": \"Globe with Asia shown\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 496 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M312,16.35V50.73a28,28,0,0,1-11.12,22.35l-41.41,31.27a8,8,0,0,0,.86,13.81l10.83,5.41A16,16,0,0,1,280,137.88V216a8,8,0,0,1-8,8h-3.06a8,8,0,0,1-7.15-4.42,4.47,4.47,0,0,0-1.72-1.86,4.42,4.42,0,0,0-6.06,1.54h0l-17.34,29A16,16,0,0,1,222.94,256h-.31a16,16,0,0,0-11.32,4.69l-5.66,5.66a8,8,0,0,0,0,11.31l5.66,5.66A16,16,0,0,1,216,294.63V304a16,16,0,0,1-16,16h-6.1a16,16,0,0,1-14.28-8.85L157,265.92a8,8,0,0,0-10.72-3.6h0a8.14,8.14,0,0,0-2.11,1.53l-19.47,19.46A16,16,0,0,1,113.38,288H2.05C17.74,409.88,121.84,504,248,504c137,0,248-111,248-248C496,141.13,418,44.56,312,16.35Zm96,342.08a16,16,0,0,1-4.69,11.31l-9.57,9.57A16,16,0,0,1,382.43,384H367.27a16,16,0,0,1-11.36-4.74l-13-13a26.78,26.78,0,0,0-25.42-7l-21.27,5.32a15.86,15.86,0,0,1-3.88.48H282a16,16,0,0,1-11.24-4.69l-11.91-11.91a8,8,0,0,1-2.34-5.66V332.6a8,8,0,0,1,5-7.43l39.34-15.74a26.35,26.35,0,0,0,5.59-3.05l23.71-16.89a8,8,0,0,1,4.64-1.48h12.14a8,8,0,0,1,7.39,4.93l5.35,12.85a4,4,0,0,0,3.69,2.46h3.8a4,4,0,0,0,3.84-2.88l4.16-14.49A4,4,0,0,1,379,288h6.06a4,4,0,0,1,4,4v13a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,1,408,333.83Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M260.07,217.72a4.47,4.47,0,0,1,1.72,1.86,8,8,0,0,0,7.15,4.42H272a8,8,0,0,0,8-8V137.88a16,16,0,0,0-8.84-14.31l-10.83-5.41a8,8,0,0,1-.86-13.81l41.41-31.27A28,28,0,0,0,312,50.73V16.35A248.23,248.23,0,0,0,248,8C111,8,0,119,0,256a249.89,249.89,0,0,0,2.05,32H113.38a16,16,0,0,0,11.31-4.69l19.47-19.46A8,8,0,0,1,157,265.92l22.62,45.23A16,16,0,0,0,193.9,320H200a16,16,0,0,0,16-16v-9.37a16,16,0,0,0-4.69-11.31l-5.66-5.66a8,8,0,0,1,0-11.31l5.66-5.66A16,16,0,0,1,222.63,256h.31a16,16,0,0,0,13.72-7.77L254,219.28a4.42,4.42,0,0,1,6.05-1.57Zm143.24,104.8L391.4,310.61a8,8,0,0,1-2.34-5.66V292a4,4,0,0,0-4-4H379a4,4,0,0,0-3.84,2.88L371,305.37a4,4,0,0,1-3.84,2.88h-3.8a4,4,0,0,1-3.69-2.46l-5.35-12.85a8,8,0,0,0-7.39-4.93H334.79a8,8,0,0,0-4.64,1.48l-23.71,16.89a26.35,26.35,0,0,1-5.59,3.05l-39.34,15.74a8,8,0,0,0-5,7.43v10.2a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,0,282,365.06h10.34a15.86,15.86,0,0,0,3.88-.48l21.27-5.32a26.78,26.78,0,0,1,25.42,7l13,13A16,16,0,0,0,367.27,384h15.16a16,16,0,0,0,11.31-4.69l9.57-9.57A16,16,0,0,0,408,358.43v-24.6a16,16,0,0,0-4.69-11.31Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"496\",\n          \"512\"\n        ],\n        \"width\": 496,\n        \"height\": 512,\n        \"path\": [\n          \"M312,16.35V50.73a28,28,0,0,1-11.12,22.35l-41.41,31.27a8,8,0,0,0,.86,13.81l10.83,5.41A16,16,0,0,1,280,137.88V216a8,8,0,0,1-8,8h-3.06a8,8,0,0,1-7.15-4.42,4.47,4.47,0,0,0-1.72-1.86,4.42,4.42,0,0,0-6.06,1.54h0l-17.34,29A16,16,0,0,1,222.94,256h-.31a16,16,0,0,0-11.32,4.69l-5.66,5.66a8,8,0,0,0,0,11.31l5.66,5.66A16,16,0,0,1,216,294.63V304a16,16,0,0,1-16,16h-6.1a16,16,0,0,1-14.28-8.85L157,265.92a8,8,0,0,0-10.72-3.6h0a8.14,8.14,0,0,0-2.11,1.53l-19.47,19.46A16,16,0,0,1,113.38,288H2.05C17.74,409.88,121.84,504,248,504c137,0,248-111,248-248C496,141.13,418,44.56,312,16.35Zm96,342.08a16,16,0,0,1-4.69,11.31l-9.57,9.57A16,16,0,0,1,382.43,384H367.27a16,16,0,0,1-11.36-4.74l-13-13a26.78,26.78,0,0,0-25.42-7l-21.27,5.32a15.86,15.86,0,0,1-3.88.48H282a16,16,0,0,1-11.24-4.69l-11.91-11.91a8,8,0,0,1-2.34-5.66V332.6a8,8,0,0,1,5-7.43l39.34-15.74a26.35,26.35,0,0,0,5.59-3.05l23.71-16.89a8,8,0,0,1,4.64-1.48h12.14a8,8,0,0,1,7.39,4.93l5.35,12.85a4,4,0,0,0,3.69,2.46h3.8a4,4,0,0,0,3.84-2.88l4.16-14.49A4,4,0,0,1,379,288h6.06a4,4,0,0,1,4,4v13a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,1,408,333.83Z\",\n          \"M260.07,217.72a4.47,4.47,0,0,1,1.72,1.86,8,8,0,0,0,7.15,4.42H272a8,8,0,0,0,8-8V137.88a16,16,0,0,0-8.84-14.31l-10.83-5.41a8,8,0,0,1-.86-13.81l41.41-31.27A28,28,0,0,0,312,50.73V16.35A248.23,248.23,0,0,0,248,8C111,8,0,119,0,256a249.89,249.89,0,0,0,2.05,32H113.38a16,16,0,0,0,11.31-4.69l19.47-19.46A8,8,0,0,1,157,265.92l22.62,45.23A16,16,0,0,0,193.9,320H200a16,16,0,0,0,16-16v-9.37a16,16,0,0,0-4.69-11.31l-5.66-5.66a8,8,0,0,1,0-11.31l5.66-5.66A16,16,0,0,1,222.63,256h.31a16,16,0,0,0,13.72-7.77L254,219.28a4.42,4.42,0,0,1,6.05-1.57Zm143.24,104.8L391.4,310.61a8,8,0,0,1-2.34-5.66V292a4,4,0,0,0-4-4H379a4,4,0,0,0-3.84,2.88L371,305.37a4,4,0,0,1-3.84,2.88h-3.8a4,4,0,0,1-3.69-2.46l-5.35-12.85a8,8,0,0,0-7.39-4.93H334.79a8,8,0,0,0-4.64,1.48l-23.71,16.89a26.35,26.35,0,0,1-5.59,3.05l-39.34,15.74a8,8,0,0,0-5,7.43v10.2a8,8,0,0,0,2.34,5.66l11.91,11.91A16,16,0,0,0,282,365.06h10.34a15.86,15.86,0,0,0,3.88-.48l21.27-5.32a26.78,26.78,0,0,1,25.42,7l13,13A16,16,0,0,0,367.27,384h15.16a16,16,0,0,0,11.31-4.69l9.57-9.57A16,16,0,0,0,408,358.43v-24.6a16,16,0,0,0-4.69-11.31Z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"globe-europe\": {\n    \"changes\": [\n      \"5.6.0\",\n      \"5.11.0\",\n      \"5.11.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"all\",\n        \"country\",\n        \"earth\",\n        \"global\",\n        \"gps\",\n        \"language\",\n        \"localize\",\n        \"location\",\n        \"map\",\n        \"online\",\n        \"place\",\n        \"planet\",\n        \"translate\",\n        \"travel\",\n        \"world\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f7a2\",\n    \"label\": \"Globe with Europe shown\",\n    \"voted\": true,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 496 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M487.54,320.4H438.9a15.8,15.8,0,0,1-11.4-4.8l-32-32.6a11.92,11.92,0,0,1,.1-16.7l12.5-12.5v-8.7a11.37,11.37,0,0,0-3.3-8l-9.4-9.4a11.37,11.37,0,0,0-8-3.3h-16a11.31,11.31,0,0,1-8-19.3l9.4-9.4a11.37,11.37,0,0,1,8-3.3h32a11.35,11.35,0,0,0,11.3-11.3v-9.4a11.35,11.35,0,0,0-11.3-11.3H376.1a16,16,0,0,0-16,16v4.5a16,16,0,0,1-10.9,15.2l-31.6,10.5a8,8,0,0,0-5.5,7.6v2.2a8,8,0,0,1-8,8h-16a8,8,0,0,1-8-8,8,8,0,0,0-8-8H269a8.14,8.14,0,0,0-7.2,4.4l-9.4,18.7a15.94,15.94,0,0,1-14.3,8.8H216a16,16,0,0,1-16-16V199a16,16,0,0,1,4.7-11.3l20.1-20.1a24.77,24.77,0,0,0,7.2-17.5,8,8,0,0,1,5.5-7.6l40-13.3a11.66,11.66,0,0,0,4.4-2.7l26.8-26.8a11.31,11.31,0,0,0-8-19.3H280l-16,16v8a8,8,0,0,1-8,8H240a8,8,0,0,1-8-8v-20a8.05,8.05,0,0,1,3.2-6.4l82.42-60.08A247.79,247.79,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504a251.57,251.57,0,0,0,32.1-2.06V448.4a16,16,0,0,0-16-16H243.9c-10.8,0-26.7-5.3-35.4-11.8l-22.2-16.7a45.42,45.42,0,0,1-18.2-36.4V343.6a45.46,45.46,0,0,1,22.1-39l42.9-25.7a46.13,46.13,0,0,1,23.4-6.5h31.2a45.62,45.62,0,0,1,29.6,10.9l43.2,37.1h18.3a32,32,0,0,1,22.6,9.4l17.3,17.3.08.08C432,359.06,440,375.62,440,393.37V413A247.11,247.11,0,0,0,487.54,320.4ZM187.4,157.1a11.37,11.37,0,0,1-8,3.3h-16a11.31,11.31,0,0,1-8-19.3l25.4-25.4a11.31,11.31,0,0,1,19.3,8v16a11.37,11.37,0,0,1-3.3,8Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M187.4,157.1l9.4-9.4a11.37,11.37,0,0,0,3.3-8v-16a11.31,11.31,0,0,0-19.3-8l-25.4,25.4a11.31,11.31,0,0,0,8,19.3h16A11.37,11.37,0,0,0,187.4,157.1ZM418.78,347.18l-.08-.08-17.3-17.3a32,32,0,0,0-22.6-9.4H360.5l-43.2-37.1a45.62,45.62,0,0,0-29.6-10.9H256.5a46.13,46.13,0,0,0-23.4,6.5l-42.9,25.7a45.46,45.46,0,0,0-22.1,39v23.9a45.42,45.42,0,0,0,18.2,36.4l22.2,16.7c8.7,6.5,24.6,11.8,35.4,11.8h20.2a16,16,0,0,1,16,16v53.54A247.57,247.57,0,0,0,440,413V393.37C440,375.62,432,359.06,418.78,347.18ZM317.62,17.92,235.2,78a8.05,8.05,0,0,0-3.2,6.4v20a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-8l16-16h20.7a11.31,11.31,0,0,1,8,19.3l-26.8,26.8a11.66,11.66,0,0,1-4.4,2.7l-40,13.3a8,8,0,0,0-5.5,7.6,24.77,24.77,0,0,1-7.2,17.5l-20.1,20.1A16,16,0,0,0,200,199v25.3a16,16,0,0,0,16,16h22.1a15.94,15.94,0,0,0,14.3-8.8l9.4-18.7a8.14,8.14,0,0,1,7.2-4.4h3.1a8,8,0,0,1,8,8,8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-2.2a8,8,0,0,1,5.5-7.6l31.6-10.5a16,16,0,0,0,10.9-15.2v-4.5a16,16,0,0,1,16-16h36.7a11.35,11.35,0,0,1,11.3,11.3v9.4a11.35,11.35,0,0,1-11.3,11.3h-32a11.37,11.37,0,0,0-8,3.3l-9.4,9.4a11.31,11.31,0,0,0,8,19.3h16a11.37,11.37,0,0,1,8,3.3l9.4,9.4a11.37,11.37,0,0,1,3.3,8v8.7l-12.5,12.5a11.92,11.92,0,0,0-.1,16.7l32,32.6a15.8,15.8,0,0,0,11.4,4.8h48.64A248.29,248.29,0,0,0,496,256C496,143.18,420.71,48,317.62,17.92Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"496\",\n          \"512\"\n        ],\n        \"width\": 496,\n        \"height\": 512,\n        \"path\": [\n          \"M487.54,320.4H438.9a15.8,15.8,0,0,1-11.4-4.8l-32-32.6a11.92,11.92,0,0,1,.1-16.7l12.5-12.5v-8.7a11.37,11.37,0,0,0-3.3-8l-9.4-9.4a11.37,11.37,0,0,0-8-3.3h-16a11.31,11.31,0,0,1-8-19.3l9.4-9.4a11.37,11.37,0,0,1,8-3.3h32a11.35,11.35,0,0,0,11.3-11.3v-9.4a11.35,11.35,0,0,0-11.3-11.3H376.1a16,16,0,0,0-16,16v4.5a16,16,0,0,1-10.9,15.2l-31.6,10.5a8,8,0,0,0-5.5,7.6v2.2a8,8,0,0,1-8,8h-16a8,8,0,0,1-8-8,8,8,0,0,0-8-8H269a8.14,8.14,0,0,0-7.2,4.4l-9.4,18.7a15.94,15.94,0,0,1-14.3,8.8H216a16,16,0,0,1-16-16V199a16,16,0,0,1,4.7-11.3l20.1-20.1a24.77,24.77,0,0,0,7.2-17.5,8,8,0,0,1,5.5-7.6l40-13.3a11.66,11.66,0,0,0,4.4-2.7l26.8-26.8a11.31,11.31,0,0,0-8-19.3H280l-16,16v8a8,8,0,0,1-8,8H240a8,8,0,0,1-8-8v-20a8.05,8.05,0,0,1,3.2-6.4l82.42-60.08A247.79,247.79,0,0,0,248,8C111,8,0,119,0,256S111,504,248,504a251.57,251.57,0,0,0,32.1-2.06V448.4a16,16,0,0,0-16-16H243.9c-10.8,0-26.7-5.3-35.4-11.8l-22.2-16.7a45.42,45.42,0,0,1-18.2-36.4V343.6a45.46,45.46,0,0,1,22.1-39l42.9-25.7a46.13,46.13,0,0,1,23.4-6.5h31.2a45.62,45.62,0,0,1,29.6,10.9l43.2,37.1h18.3a32,32,0,0,1,22.6,9.4l17.3,17.3.08.08C432,359.06,440,375.62,440,393.37V413A247.11,247.11,0,0,0,487.54,320.4ZM187.4,157.1a11.37,11.37,0,0,1-8,3.3h-16a11.31,11.31,0,0,1-8-19.3l25.4-25.4a11.31,11.31,0,0,1,19.3,8v16a11.37,11.37,0,0,1-3.3,8Z\",\n          \"M187.4,157.1l9.4-9.4a11.37,11.37,0,0,0,3.3-8v-16a11.31,11.31,0,0,0-19.3-8l-25.4,25.4a11.31,11.31,0,0,0,8,19.3h16A11.37,11.37,0,0,0,187.4,157.1ZM418.78,347.18l-.08-.08-17.3-17.3a32,32,0,0,0-22.6-9.4H360.5l-43.2-37.1a45.62,45.62,0,0,0-29.6-10.9H256.5a46.13,46.13,0,0,0-23.4,6.5l-42.9,25.7a45.46,45.46,0,0,0-22.1,39v23.9a45.42,45.42,0,0,0,18.2,36.4l22.2,16.7c8.7,6.5,24.6,11.8,35.4,11.8h20.2a16,16,0,0,1,16,16v53.54A247.57,247.57,0,0,0,440,413V393.37C440,375.62,432,359.06,418.78,347.18ZM317.62,17.92,235.2,78a8.05,8.05,0,0,0-3.2,6.4v20a8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-8l16-16h20.7a11.31,11.31,0,0,1,8,19.3l-26.8,26.8a11.66,11.66,0,0,1-4.4,2.7l-40,13.3a8,8,0,0,0-5.5,7.6,24.77,24.77,0,0,1-7.2,17.5l-20.1,20.1A16,16,0,0,0,200,199v25.3a16,16,0,0,0,16,16h22.1a15.94,15.94,0,0,0,14.3-8.8l9.4-18.7a8.14,8.14,0,0,1,7.2-4.4h3.1a8,8,0,0,1,8,8,8,8,0,0,0,8,8h16a8,8,0,0,0,8-8v-2.2a8,8,0,0,1,5.5-7.6l31.6-10.5a16,16,0,0,0,10.9-15.2v-4.5a16,16,0,0,1,16-16h36.7a11.35,11.35,0,0,1,11.3,11.3v9.4a11.35,11.35,0,0,1-11.3,11.3h-32a11.37,11.37,0,0,0-8,3.3l-9.4,9.4a11.31,11.31,0,0,0,8,19.3h16a11.37,11.37,0,0,1,8,3.3l9.4,9.4a11.37,11.37,0,0,1,3.3,8v8.7l-12.5,12.5a11.92,11.92,0,0,0-.1,16.7l32,32.6a15.8,15.8,0,0,0,11.4,4.8h48.64A248.29,248.29,0,0,0,496,256C496,143.18,420.71,48,317.62,17.92Z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"graduation-cap\": {\n    \"changes\": [\n      \"4.1\",\n      \"5.0.0\",\n      \"5.2.0\",\n      \"5.10.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"ceremony\",\n        \"college\",\n        \"graduate\",\n        \"learning\",\n        \"school\",\n        \"student\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f19d\",\n    \"label\": \"Graduation Cap\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M323.07 175.7L118.8 215.6a48.1 48.1 0 0 0-38.74 44.73 32 32 0 0 1 2.21 53.94l25.4 114.26A16 16 0 0 1 92 448H35.94a16 16 0 0 1-15.61-19.47l25.39-114.27a32 32 0 0 1 2.33-54 80.16 80.16 0 0 1 64.62-76.07l204.26-39.89a16 16 0 1 1 6.14 31.4z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M622.33 198.8l-279 85.7a80 80 0 0 1-46.79 0L99.67 224a47.84 47.84 0 0 1 19.13-8.39l204.27-39.9a16 16 0 1 0-6.14-31.4l-204.26 39.88a79.87 79.87 0 0 0-47.57 29.18l-47.44-14.58c-23.54-7.23-23.54-38.36 0-45.59L296.6 67.5a79.92 79.92 0 0 1 46.8 0l278.93 85.7c23.55 7.24 23.55 38.36 0 45.6zM352.79 315.09a111.94 111.94 0 0 1-65.59 0l-145-44.55L128 384c0 35.35 86 64 192 64s192-28.65 192-64l-14.19-113.47z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M323.07 175.7L118.8 215.6a48.1 48.1 0 0 0-38.74 44.73 32 32 0 0 1 2.21 53.94l25.4 114.26A16 16 0 0 1 92 448H35.94a16 16 0 0 1-15.61-19.47l25.39-114.27a32 32 0 0 1 2.33-54 80.16 80.16 0 0 1 64.62-76.07l204.26-39.89a16 16 0 1 1 6.14 31.4z\",\n          \"M622.33 198.8l-279 85.7a80 80 0 0 1-46.79 0L99.67 224a47.84 47.84 0 0 1 19.13-8.39l204.27-39.9a16 16 0 1 0-6.14-31.4l-204.26 39.88a79.87 79.87 0 0 0-47.57 29.18l-47.44-14.58c-23.54-7.23-23.54-38.36 0-45.59L296.6 67.5a79.92 79.92 0 0 1 46.8 0l278.93 85.7c23.55 7.24 23.55 38.36 0 45.6zM352.79 315.09a111.94 111.94 0 0 1-65.59 0l-145-44.55L128 384c0 35.35 86 64 192 64s192-28.65 192-64l-14.19-113.47z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"history\": {\n    \"changes\": [\n      \"4.1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"Rewind\",\n        \"clock\",\n        \"reverse\",\n        \"time\",\n        \"time machine\"\n      ]\n    },\n    \"styles\": [\n      \"solid\",\n      \"duotone\"\n    ],\n    \"unicode\": \"f1da\",\n    \"label\": \"History\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M504 255.531c.253 136.64-111.18 248.372-247.82 248.468-59.015.042-113.223-20.53-155.822-54.911-11.077-8.94-11.905-25.541-1.839-35.607l11.267-11.267c8.609-8.609 22.353-9.551 31.891-1.984C173.062 425.135 212.781 440 256 440c101.705 0 184-82.311 184-184 0-101.705-82.311-184-184-184-48.814 0-93.149 18.969-126.068 49.932l50.754 50.754c10.08 10.08 2.941 27.314-11.313 27.314H24c-8.837 0-16-7.163-16-16V38.627c0-14.254 17.234-21.393 27.314-11.314l49.372 49.372C129.209 34.136 189.552 8 256 8c136.81 0 247.747 110.78 248 247.531zm-180.912 78.784l9.823-12.63c8.138-10.463 6.253-25.542-4.21-33.679L288 256.349V152c0-13.255-10.745-24-24-24h-16c-13.255 0-24 10.745-24 24v135.651l65.409 50.874c10.463 8.137 25.541 6.253 33.679-4.21z\"\n      },\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M141.68 400.23a184 184 0 1 0-11.75-278.3l50.76 50.76c10.08 10.08 2.94 27.31-11.32 27.31H24a16 16 0 0 1-16-16V38.63c0-14.26 17.23-21.4 27.31-11.32l49.38 49.38A247.14 247.14 0 0 1 256 8c136.81 0 247.75 110.78 248 247.53S392.82 503.9 256.18 504a247 247 0 0 1-155.82-54.91 24 24 0 0 1-1.84-35.61l11.27-11.27a24 24 0 0 1 31.89-1.98z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M288 152v104.35L328.7 288a24 24 0 0 1 4.21 33.68l-9.82 12.62a24 24 0 0 1-33.68 4.21L224 287.65V152a24 24 0 0 1 24-24h16a24 24 0 0 1 24 24z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M141.68 400.23a184 184 0 1 0-11.75-278.3l50.76 50.76c10.08 10.08 2.94 27.31-11.32 27.31H24a16 16 0 0 1-16-16V38.63c0-14.26 17.23-21.4 27.31-11.32l49.38 49.38A247.14 247.14 0 0 1 256 8c136.81 0 247.75 110.78 248 247.53S392.82 503.9 256.18 504a247 247 0 0 1-155.82-54.91 24 24 0 0 1-1.84-35.61l11.27-11.27a24 24 0 0 1 31.89-1.98z\",\n          \"M288 152v104.35L328.7 288a24 24 0 0 1 4.21 33.68l-9.82 12.62a24 24 0 0 1-33.68 4.21L224 287.65V152a24 24 0 0 1 24-24h16a24 24 0 0 1 24 24z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"home\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\",\n      \"5.7.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"abode\",\n        \"building\",\n        \"house\",\n        \"main\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f015\",\n    \"label\": \"home\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 576 512\\\"><path d=\\\"M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"576\",\n          \"512\"\n        ],\n        \"width\": 576,\n        \"height\": 512,\n        \"path\": \"M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"info\": {\n    \"changes\": [\n      \"3.1\",\n      \"5.0.0\",\n      \"5.10.1\",\n      \"5.10.2\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"details\",\n        \"help\",\n        \"information\",\n        \"more\",\n        \"support\"\n      ]\n    },\n    \"styles\": [\n      \"regular\"\n    ],\n    \"unicode\": \"f129\",\n    \"label\": \"Info\",\n    \"voted\": false,\n    \"svg\": {\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 256 512\\\"><path d=\\\"M224 352.589V224c0-16.475-6.258-31.517-16.521-42.872C225.905 161.14 236 135.346 236 108 236 48.313 187.697 0 128 0 68.313 0 20 48.303 20 108c0 20.882 5.886 40.859 16.874 58.037C15.107 176.264 0 198.401 0 224v39.314c0 23.641 12.884 44.329 32 55.411v33.864C12.884 363.671 0 384.359 0 408v40c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-40c0-23.641-12.884-44.329-32-55.411zM128 48c33.137 0 60 26.863 60 60s-26.863 60-60 60-60-26.863-60-60 26.863-60 60-60zm80 400c0 8.836-7.164 16-16 16H64c-8.836 0-16-7.164-16-16v-40c0-8.836 7.164-16 16-16h16V279.314H64c-8.836 0-16-7.164-16-16V224c0-8.836 7.164-16 16-16h96c8.836 0 16 7.164 16 16v168h16c8.836 0 16 7.164 16 16v40z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"256\",\n          \"512\"\n        ],\n        \"width\": 256,\n        \"height\": 512,\n        \"path\": \"M224 352.589V224c0-16.475-6.258-31.517-16.521-42.872C225.905 161.14 236 135.346 236 108 236 48.313 187.697 0 128 0 68.313 0 20 48.303 20 108c0 20.882 5.886 40.859 16.874 58.037C15.107 176.264 0 198.401 0 224v39.314c0 23.641 12.884 44.329 32 55.411v33.864C12.884 363.671 0 384.359 0 408v40c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-40c0-23.641-12.884-44.329-32-55.411zM128 48c33.137 0 60 26.863 60 60s-26.863 60-60 60-60-26.863-60-60 26.863-60 60-60zm80 400c0 8.836-7.164 16-16 16H64c-8.836 0-16-7.164-16-16v-40c0-8.836 7.164-16 16-16h16V279.314H64c-8.836 0-16-7.164-16-16V224c0-8.836 7.164-16 16-16h96c8.836 0 16 7.164 16 16v168h16c8.836 0 16 7.164 16 16v40z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"info-circle\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"details\",\n        \"help\",\n        \"information\",\n        \"more\",\n        \"support\"\n      ]\n    },\n    \"styles\": [\n      \"regular\"\n    ],\n    \"unicode\": \"f05a\",\n    \"label\": \"Info Circle\",\n    \"voted\": false,\n    \"svg\": {\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm0-338c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm0-338c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"instagram\": {\n    \"changes\": [\n      \"4.6\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f16d\",\n    \"label\": \"Instagram\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440860000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"key\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\",\n      \"5.10.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"lock\",\n        \"password\",\n        \"private\",\n        \"secret\",\n        \"unlock\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f084\",\n    \"label\": \"key\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M303.06 348.91l.1.09-24 27a24 24 0 0 1-17.94 8H224v40a24 24 0 0 1-24 24h-40v40a24 24 0 0 1-24 24H24a24 24 0 0 1-24-24v-78a24 24 0 0 1 7-17l161.83-161.83-.11-.35a176.24 176.24 0 0 0 134.34 118.09z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M336 0a176 176 0 1 0 176 176A176 176 0 0 0 336 0zm48 176a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M303.06 348.91l.1.09-24 27a24 24 0 0 1-17.94 8H224v40a24 24 0 0 1-24 24h-40v40a24 24 0 0 1-24 24H24a24 24 0 0 1-24-24v-78a24 24 0 0 1 7-17l161.83-161.83-.11-.35a176.24 176.24 0 0 0 134.34 118.09z\",\n          \"M336 0a176 176 0 1 0 176 176A176 176 0 0 0 336 0zm48 176a48 48 0 1 1 48-48 48 48 0 0 1-48 48z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"key-skeleton\": {\n    \"changes\": [\n      \"5.4.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"halloween\",\n        \"lock\",\n        \"password\",\n        \"private\",\n        \"secret\",\n        \"unlock\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f6f3\",\n    \"label\": \"Key Skeleton\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M251.31 372.91a16 16 0 0 1 0 22.63l-15.77 15.77a16 16 0 0 1-22.62 0L176 374.4l-30.87 30.86 36.11 36.11a16 16 0 0 1 0 22.63l-43.16 43.17a16 16 0 0 1-22.62 0l-36.12-36.11-36.26 36.25a16 16 0 0 1-22.62 0L4.69 491.54a16 16 0 0 1 0-22.63l255.12-255.12a64.18 64.18 0 0 0 38.4 38.4L214.4 336l36.91 36.91z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M448 0H320a64 64 0 0 0-64 64v128a64 64 0 0 0 64 64h128a64 64 0 0 0 64-64V64a64 64 0 0 0-64-64zm-73.37 182.63a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25zm64-64a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M251.31 372.91a16 16 0 0 1 0 22.63l-15.77 15.77a16 16 0 0 1-22.62 0L176 374.4l-30.87 30.86 36.11 36.11a16 16 0 0 1 0 22.63l-43.16 43.17a16 16 0 0 1-22.62 0l-36.12-36.11-36.26 36.25a16 16 0 0 1-22.62 0L4.69 491.54a16 16 0 0 1 0-22.63l255.12-255.12a64.18 64.18 0 0 0 38.4 38.4L214.4 336l36.91 36.91z\",\n          \"M448 0H320a64 64 0 0 0-64 64v128a64 64 0 0 0 64 64h128a64 64 0 0 0 64-64V64a64 64 0 0 0-64-64zm-73.37 182.63a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25zm64-64a32 32 0 1 1 0-45.25 32 32 0 0 1 0 45.25z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"laptop\": {\n    \"changes\": [\n      \"3\",\n      \"5.0.0\",\n      \"5.2.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"computer\",\n        \"cpu\",\n        \"dell\",\n        \"demo\",\n        \"device\",\n        \"mac\",\n        \"macbook\",\n        \"machine\",\n        \"pc\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f109\",\n    \"label\": \"Laptop\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M512 64H128v256h384zm112 352H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\",\n          \"M512 64H128v256h384zm112 352H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"laptop-code\": {\n    \"changes\": [\n      \"5.2.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"computer\",\n        \"cpu\",\n        \"dell\",\n        \"demo\",\n        \"develop\",\n        \"device\",\n        \"mac\",\n        \"macbook\",\n        \"machine\",\n        \"pc\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f5fc\",\n    \"label\": \"Laptop Code\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16zM512 64H128v256h384zM289 250.34l-11.31 11.31a16 16 0 0 1-22.63 0l-58.35-58.34a16 16 0 0 1 0-22.63L255 122.34a16 16 0 0 1 22.63 0L289 133.65a16 16 0 0 1 0 22.63L253.25 192 289 227.71a16 16 0 0 1 0 22.63zm154.35-47L385 261.66a16 16 0 0 1-22.63 0L351 250.35a16 16 0 0 1 0-22.63L386.75 192 351 156.29a16 16 0 0 1 0-22.63l11.31-11.31a16 16 0 0 1 22.63 0l58.34 58.34a16 16 0 0 1 .04 22.63z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M528 0H112a48.14 48.14 0 0 0-48 48v336h512V48a48.14 48.14 0 0 0-48-48zm-16 320H128V64h384z\",\n          \"M624 416H381.54c-.74 19.81-14.71 32-32.74 32H288c-18.69 0-33-17.47-32.77-32H16a16 16 0 0 0-16 16v16a64.19 64.19 0 0 0 64 64h512a64.19 64.19 0 0 0 64-64v-16a16 16 0 0 0-16-16zM512 64H128v256h384zM289 250.34l-11.31 11.31a16 16 0 0 1-22.63 0l-58.35-58.34a16 16 0 0 1 0-22.63L255 122.34a16 16 0 0 1 22.63 0L289 133.65a16 16 0 0 1 0 22.63L253.25 192 289 227.71a16 16 0 0 1 0 22.63zm154.35-47L385 261.66a16 16 0 0 1-22.63 0L351 250.35a16 16 0 0 1 0-22.63L386.75 192 351 156.29a16 16 0 0 1 0-22.63l11.31-11.31a16 16 0 0 1 22.63 0l58.34 58.34a16 16 0 0 1 .04 22.63z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"laptop-house\": {\n    \"changes\": [\n      \"5.13.0\",\n      \"5.14.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"computer\",\n        \"covid-19\",\n        \"device\",\n        \"office\",\n        \"remote\",\n        \"work from home\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"e066\",\n    \"label\": \"Laptop House\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M272,416H96a32,32,0,0,1-32-32V219.88L42.34,239A16.51,16.51,0,0,1,33,242.48a16.22,16.22,0,0,1-10.63-4.78L3.55,216.42A16.4,16.4,0,0,1,0,207a16.15,16.15,0,0,1,4.78-10.61L216.58,8.92C222.12,4,232.64,0,240.05,0S258,4,263.5,8.92L352,87.3V48a16,16,0,0,1,16-16h32a16,16,0,0,1,16,16v96l59.24,52.42A16.31,16.31,0,0,1,480,207a16.51,16.51,0,0,1-3.58,9.44L469.74,224H332.8c-17.8,0-33.69,8.24-44.82,21.12V208a16,16,0,0,0-16-16H208a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16h64Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M629.33,448H592V288c0-17.67-12.89-32-28.8-32H332.8c-15.91,0-28.8,14.33-28.8,32V448H266.67A10.67,10.67,0,0,0,256,458.67v10.66A42.82,42.82,0,0,0,298.6,512H597.4A42.82,42.82,0,0,0,640,469.33V458.67A10.67,10.67,0,0,0,629.33,448ZM544,448H352V304H544Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M272,416H96a32,32,0,0,1-32-32V219.88L42.34,239A16.51,16.51,0,0,1,33,242.48a16.22,16.22,0,0,1-10.63-4.78L3.55,216.42A16.4,16.4,0,0,1,0,207a16.15,16.15,0,0,1,4.78-10.61L216.58,8.92C222.12,4,232.64,0,240.05,0S258,4,263.5,8.92L352,87.3V48a16,16,0,0,1,16-16h32a16,16,0,0,1,16,16v96l59.24,52.42A16.31,16.31,0,0,1,480,207a16.51,16.51,0,0,1-3.58,9.44L469.74,224H332.8c-17.8,0-33.69,8.24-44.82,21.12V208a16,16,0,0,0-16-16H208a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16h64Z\",\n          \"M629.33,448H592V288c0-17.67-12.89-32-28.8-32H332.8c-15.91,0-28.8,14.33-28.8,32V448H266.67A10.67,10.67,0,0,0,256,458.67v10.66A42.82,42.82,0,0,0,298.6,512H597.4A42.82,42.82,0,0,0,640,469.33V458.67A10.67,10.67,0,0,0,629.33,448ZM544,448H352V304H544Z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"life-ring\": {\n    \"changes\": [\n      \"4.1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"coast guard\",\n        \"help\",\n        \"overboard\",\n        \"save\",\n        \"support\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f1cd\",\n    \"label\": \"Life Ring\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M292.08 167l-.41-.17zm-66.62-2a96.5 96.5 0 0 1 61.08 0l112-112a248 248 0 0 0-285 0zm68.67 2.92l.52.22zm2.49 1.12l.46.21zM186.25 322l-.19-.21zm-5.51-6.36l.21.26zm1.65 2c.12.14.23.28.35.41-.12-.15-.23-.29-.35-.43zm1.74 2l.36.4zm135.51-135.51l.4.36zM177.51 311.29l-.1-.15zM304.18 173l.34.19zm11.42 7.78l.26.21zm6.36 5.51l-.21-.19zm-3.96-3.55l-.42-.35zm-11.6-8.43l.47.29zm4.68 3.09l.17.12zm-2-1.35l-.43-.29zm-9.71-5.68l-.1-.05zm-123.61 32.91c.1-.14.19-.28.28-.42-.04.14-.18.28-.28.42zm-1.45 2.28l.29-.46zm-1.31 2.25l.19-.32zm-2.6 4.77zm10.38-16.18l.21-.26zm2-2.43c-.12.13-.23.27-.35.41.08-.14.19-.28.31-.38zm-5.33 6.89l.1-.15zm-8.2 14.07c-.07.14-.13.29-.2.43.03-.14.09-.29.16-.43zm5.39 92l-.29-.46zm-4.27-7.53v.05zm2.82 5.14l-.19-.32zm2.61 4.21c.1.14.19.28.28.42-.08-.17-.22-.31-.32-.45zm-6.8-12.11c.07.14.13.29.2.43-.06-.14-.12-.29-.2-.43zm-2-76.7c0 .13-.1.25-.16.38.07-.13.16-.25.16-.38zm1.09-2.58c-.07.17-.15.34-.22.5.13-.16.13-.33.23-.5zm-.22 76.78c.07.16.15.33.22.5-.09-.17-.09-.34-.21-.5zm-1-2.46c.06.13.11.25.16.38-.03-.13-.12-.25-.18-.38zm172-84.19l.19.32zM327.51 320l.36-.4zm-1.57 1.71l-.19.21zM325.75 190l.19.21zm3.51 128c.12-.13.23-.27.35-.41-.12.17-.23.31-.35.41zm2-121.63l-.21-.26zm0 119.2l-.21.26zm-1.65-121.22c-.12-.14-.23-.28-.35-.41.12.16.23.3.35.44zm-1.74-2l-.36-.4zm6.62 8.35l.1.15zm.1 110.43l-.1.15zM398.49 53q2 1.41 4 2.85-2-1.43-4-2.85zM343.9 294.64c.07-.17.15-.34.22-.5-.07.16-.12.33-.22.5zm1.09-2.58c.05-.13.1-.25.16-.38-.06.13-.15.25-.15.38zm-3.35 7.36v-.05zm-5.4 9.3l-.28.42zm1.45-2.28l-.29.46zm1.35-2.25l-.19.32zm3.75-7.12c.07-.14.13-.29.2-.43-.07.14-.13.29-.2.43zM449 100.21q-1.41-1.75-2.85-3.46 1.39 1.71 2.85 3.46zM445.49 96c-1-1.18-2-2.35-3-3.51 1 1.19 2.01 2.36 3 3.51zm6.87 8.5q-1.36-1.74-2.76-3.5 1.4 1.76 2.76 3.53zm3.36 4.44c-.91-1.23-1.83-2.44-2.75-3.65.92 1.24 1.84 2.45 2.75 3.71zm-119.48 94.34l-.28-.42zm66.76-147q1.85 1.36 3.66 2.76-1.78-1.39-3.66-2.76zm12.23 9.62q-1.72-1.44-3.47-2.85 1.77 1.41 3.5 2.85zM411 62.4q-1.74-1.4-3.51-2.77Q409.24 61 411 62.4zm8.5 7.13q-1.74-1.53-3.51-3 1.75 1.47 3.49 3zm-75.38 148.33c-.07-.16-.15-.33-.22-.5.1.17.15.34.22.5zM184.49 192l-.36.4zM343 215.36c-.07-.14-.13-.29-.2-.43.06.14.12.29.2.43zm113.16-105.8c1 1.31 1.9 2.62 2.84 3.94-.95-1.32-1.89-2.63-2.85-3.94zM337.4 205.1l.29.46zm82.53-135.18a248.82 248.82 0 0 1 22.14 22.15 250.17 250.17 0 0 0-22.14-22.15zm-74.78 150.4a6.15 6.15 0 0 1-.16-.38c.01.13.1.25.16.38zM459 398.49a248 248 0 0 0 0-285L347 225.46a96.5 96.5 0 0 1 0 61.08zM341.67 212.63zM220.33 345.15l-.41-.17zm-2.46-1l-.52-.22zm-5.3-2.49l.1.05zM322 325.75l-.21.19zM309.14 336l-.43.29zm2-1.35l.17-.12zm4.48-3.34l.26-.21zm4-3.39l.4-.36zm-1.6 1.39l-.42.35zM215.38 343l-.46-.21zm-19-11.74l-.26-.21zm-4-3.39l-.4-.36zm-6.3-137.62l.19-.21zm4 135.5l.21.19zm15.52 11.94l-.47-.29zm2.26 1.35l-.34-.19zm78.72 8a96.5 96.5 0 0 1-61.08 0L113.51 459a248 248 0 0 0 285 0zM202.86 336l.43.29zm-2-1.35l-.17-.12zM416 445.49q1.77-1.49 3.51-3-1.77 1.51-3.51 3zm43-47c-.93 1.33-1.88 2.64-2.84 3.95.95-1.31 1.9-2.62 2.84-3.95zM411.79 449q1.74-1.41 3.47-2.85-1.72 1.39-3.47 2.85zm-4.32 3.42q1.77-1.38 3.51-2.77-1.74 1.35-3.51 2.72zM455.72 403q-1.37 1.85-2.76 3.66 1.4-1.78 2.76-3.66zm-10.23 13c-1 1.18-2 2.35-3 3.51 1-1.19 2.01-2.36 3-3.51zm3.46-4.18q-1.41 1.74-2.85 3.47 1.44-1.75 2.9-3.5zm.65-.81q1.39-1.74 2.77-3.51-1.37 1.74-2.77 3.5zm-150.17-69.38a.31.31 0 0 1-.1.05.31.31 0 0 0 .1-.05zm-5.3 2.49l.52-.22zm12.31-6.43l.47-.29zm-9.82 5.31l.46-.21zm7.56-4l.34-.19zm137.9 80.89a248.94 248.94 0 0 1-22.15 22.15 248.94 248.94 0 0 0 22.15-22.11zm-39.63 36.21q-2 1.44-4 2.85 2.04-1.37 4-2.81zM292.08 345l-.41.17zM403 455.72q1.85-1.37 3.66-2.76-1.78 1.4-3.66 2.76zM194 329.26l.42.35zM69.93 92.07a248.82 248.82 0 0 1 22.14-22.15 250.17 250.17 0 0 0-22.14 22.15zm30.28-29q-1.74 1.41-3.47 2.85 1.73-1.46 3.47-2.87zm90 123l-.21.19zm4.13-3.67l-.42.35zM109.55 55.86q2-1.44 4-2.85-2.03 1.41-4 2.85zM196.14 181l.26-.21zM104.53 59.63Q102.76 61 101 62.4q1.76-1.4 3.53-2.77zm.78-.59q1.81-1.4 3.66-2.76-1.84 1.37-3.66 2.72zm87.05 125.09l-.4.36zm22.56-14.92l.46-.21zm-2.25 1.11l-.1.05zm4.68-2.22l.52-.22zm2.57-1.08l.41-.17zm-17.06 9l.43-.29zm5-3.09l-.34.19zm-7.11 4.56l.17-.12zm4.38-2.92l.47-.29zM96.74 446.1q1.73 1.44 3.47 2.85-1.74-1.41-3.47-2.85zm-33.69-34.31q1.41 1.74 2.85 3.47-1.44-1.72-2.85-3.47zm3.46 4.21c1 1.18 2 2.35 3 3.51-1-1.19-2.01-2.36-3-3.51zm-10.23-13q1.36 1.85 2.76 3.66-1.39-1.78-2.76-3.66zm3.35 4.44q1.37 1.8 2.77 3.56-1.4-1.76-2.77-3.53zm32.89 35q1.74 1.53 3.51 3-1.77-1.44-3.51-2.97zM105.31 453q1.81 1.4 3.66 2.76-1.84-1.4-3.66-2.76zm8.2 6q-2-1.41-4-2.85 2.01 1.43 4 2.85zM101 449.6q1.74 1.39 3.51 2.77-1.75-1.37-3.51-2.77zm-45.15-47.16c-1-1.31-1.9-2.62-2.84-3.95.99 1.33 1.88 2.64 2.84 3.95zM65.9 96.75q-1.44 1.71-2.85 3.46 1.41-1.75 2.85-3.46zM56.29 109c.9-1.23 1.82-2.45 2.74-3.65-.92 1.17-1.84 2.39-2.74 3.65zm6.11-8q-1.4 1.74-2.76 3.51Q61 102.76 62.4 101zm7.12-8.5c-1 1.16-2 2.33-3 3.51.98-1.16 1.99-2.33 3-3.49zm23-23q1.74-1.53 3.51-3-1.77 1.5-3.51 3.03zm-.45 372.55a248.94 248.94 0 0 1-22.15-22.15 248.94 248.94 0 0 0 22.15 22.18zM165 286.54a96.5 96.5 0 0 1 0-61.08L53 113.51a248 248 0 0 0 0 285zm-109.11-177q-1.44 2-2.84 3.93 1.36-1.95 2.8-3.9z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M347 225.46l112-111.95A249.4 249.4 0 0 0 398.49 53L286.54 165A96.26 96.26 0 0 1 347 225.46zm-182 61.08l-112 112a249.4 249.4 0 0 0 60.5 60.5L225.46 347A96.26 96.26 0 0 1 165 286.54zm-112-173l112 112a96.26 96.26 0 0 1 60.5-60.5L113.51 53A249.4 249.4 0 0 0 53 113.51zM286.54 347l112 112a249.4 249.4 0 0 0 60.5-60.5L347 286.54A96.26 96.26 0 0 1 286.54 347z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M292.08 167l-.41-.17zm-66.62-2a96.5 96.5 0 0 1 61.08 0l112-112a248 248 0 0 0-285 0zm68.67 2.92l.52.22zm2.49 1.12l.46.21zM186.25 322l-.19-.21zm-5.51-6.36l.21.26zm1.65 2c.12.14.23.28.35.41-.12-.15-.23-.29-.35-.43zm1.74 2l.36.4zm135.51-135.51l.4.36zM177.51 311.29l-.1-.15zM304.18 173l.34.19zm11.42 7.78l.26.21zm6.36 5.51l-.21-.19zm-3.96-3.55l-.42-.35zm-11.6-8.43l.47.29zm4.68 3.09l.17.12zm-2-1.35l-.43-.29zm-9.71-5.68l-.1-.05zm-123.61 32.91c.1-.14.19-.28.28-.42-.04.14-.18.28-.28.42zm-1.45 2.28l.29-.46zm-1.31 2.25l.19-.32zm-2.6 4.77zm10.38-16.18l.21-.26zm2-2.43c-.12.13-.23.27-.35.41.08-.14.19-.28.31-.38zm-5.33 6.89l.1-.15zm-8.2 14.07c-.07.14-.13.29-.2.43.03-.14.09-.29.16-.43zm5.39 92l-.29-.46zm-4.27-7.53v.05zm2.82 5.14l-.19-.32zm2.61 4.21c.1.14.19.28.28.42-.08-.17-.22-.31-.32-.45zm-6.8-12.11c.07.14.13.29.2.43-.06-.14-.12-.29-.2-.43zm-2-76.7c0 .13-.1.25-.16.38.07-.13.16-.25.16-.38zm1.09-2.58c-.07.17-.15.34-.22.5.13-.16.13-.33.23-.5zm-.22 76.78c.07.16.15.33.22.5-.09-.17-.09-.34-.21-.5zm-1-2.46c.06.13.11.25.16.38-.03-.13-.12-.25-.18-.38zm172-84.19l.19.32zM327.51 320l.36-.4zm-1.57 1.71l-.19.21zM325.75 190l.19.21zm3.51 128c.12-.13.23-.27.35-.41-.12.17-.23.31-.35.41zm2-121.63l-.21-.26zm0 119.2l-.21.26zm-1.65-121.22c-.12-.14-.23-.28-.35-.41.12.16.23.3.35.44zm-1.74-2l-.36-.4zm6.62 8.35l.1.15zm.1 110.43l-.1.15zM398.49 53q2 1.41 4 2.85-2-1.43-4-2.85zM343.9 294.64c.07-.17.15-.34.22-.5-.07.16-.12.33-.22.5zm1.09-2.58c.05-.13.1-.25.16-.38-.06.13-.15.25-.15.38zm-3.35 7.36v-.05zm-5.4 9.3l-.28.42zm1.45-2.28l-.29.46zm1.35-2.25l-.19.32zm3.75-7.12c.07-.14.13-.29.2-.43-.07.14-.13.29-.2.43zM449 100.21q-1.41-1.75-2.85-3.46 1.39 1.71 2.85 3.46zM445.49 96c-1-1.18-2-2.35-3-3.51 1 1.19 2.01 2.36 3 3.51zm6.87 8.5q-1.36-1.74-2.76-3.5 1.4 1.76 2.76 3.53zm3.36 4.44c-.91-1.23-1.83-2.44-2.75-3.65.92 1.24 1.84 2.45 2.75 3.71zm-119.48 94.34l-.28-.42zm66.76-147q1.85 1.36 3.66 2.76-1.78-1.39-3.66-2.76zm12.23 9.62q-1.72-1.44-3.47-2.85 1.77 1.41 3.5 2.85zM411 62.4q-1.74-1.4-3.51-2.77Q409.24 61 411 62.4zm8.5 7.13q-1.74-1.53-3.51-3 1.75 1.47 3.49 3zm-75.38 148.33c-.07-.16-.15-.33-.22-.5.1.17.15.34.22.5zM184.49 192l-.36.4zM343 215.36c-.07-.14-.13-.29-.2-.43.06.14.12.29.2.43zm113.16-105.8c1 1.31 1.9 2.62 2.84 3.94-.95-1.32-1.89-2.63-2.85-3.94zM337.4 205.1l.29.46zm82.53-135.18a248.82 248.82 0 0 1 22.14 22.15 250.17 250.17 0 0 0-22.14-22.15zm-74.78 150.4a6.15 6.15 0 0 1-.16-.38c.01.13.1.25.16.38zM459 398.49a248 248 0 0 0 0-285L347 225.46a96.5 96.5 0 0 1 0 61.08zM341.67 212.63zM220.33 345.15l-.41-.17zm-2.46-1l-.52-.22zm-5.3-2.49l.1.05zM322 325.75l-.21.19zM309.14 336l-.43.29zm2-1.35l.17-.12zm4.48-3.34l.26-.21zm4-3.39l.4-.36zm-1.6 1.39l-.42.35zM215.38 343l-.46-.21zm-19-11.74l-.26-.21zm-4-3.39l-.4-.36zm-6.3-137.62l.19-.21zm4 135.5l.21.19zm15.52 11.94l-.47-.29zm2.26 1.35l-.34-.19zm78.72 8a96.5 96.5 0 0 1-61.08 0L113.51 459a248 248 0 0 0 285 0zM202.86 336l.43.29zm-2-1.35l-.17-.12zM416 445.49q1.77-1.49 3.51-3-1.77 1.51-3.51 3zm43-47c-.93 1.33-1.88 2.64-2.84 3.95.95-1.31 1.9-2.62 2.84-3.95zM411.79 449q1.74-1.41 3.47-2.85-1.72 1.39-3.47 2.85zm-4.32 3.42q1.77-1.38 3.51-2.77-1.74 1.35-3.51 2.72zM455.72 403q-1.37 1.85-2.76 3.66 1.4-1.78 2.76-3.66zm-10.23 13c-1 1.18-2 2.35-3 3.51 1-1.19 2.01-2.36 3-3.51zm3.46-4.18q-1.41 1.74-2.85 3.47 1.44-1.75 2.9-3.5zm.65-.81q1.39-1.74 2.77-3.51-1.37 1.74-2.77 3.5zm-150.17-69.38a.31.31 0 0 1-.1.05.31.31 0 0 0 .1-.05zm-5.3 2.49l.52-.22zm12.31-6.43l.47-.29zm-9.82 5.31l.46-.21zm7.56-4l.34-.19zm137.9 80.89a248.94 248.94 0 0 1-22.15 22.15 248.94 248.94 0 0 0 22.15-22.11zm-39.63 36.21q-2 1.44-4 2.85 2.04-1.37 4-2.81zM292.08 345l-.41.17zM403 455.72q1.85-1.37 3.66-2.76-1.78 1.4-3.66 2.76zM194 329.26l.42.35zM69.93 92.07a248.82 248.82 0 0 1 22.14-22.15 250.17 250.17 0 0 0-22.14 22.15zm30.28-29q-1.74 1.41-3.47 2.85 1.73-1.46 3.47-2.87zm90 123l-.21.19zm4.13-3.67l-.42.35zM109.55 55.86q2-1.44 4-2.85-2.03 1.41-4 2.85zM196.14 181l.26-.21zM104.53 59.63Q102.76 61 101 62.4q1.76-1.4 3.53-2.77zm.78-.59q1.81-1.4 3.66-2.76-1.84 1.37-3.66 2.72zm87.05 125.09l-.4.36zm22.56-14.92l.46-.21zm-2.25 1.11l-.1.05zm4.68-2.22l.52-.22zm2.57-1.08l.41-.17zm-17.06 9l.43-.29zm5-3.09l-.34.19zm-7.11 4.56l.17-.12zm4.38-2.92l.47-.29zM96.74 446.1q1.73 1.44 3.47 2.85-1.74-1.41-3.47-2.85zm-33.69-34.31q1.41 1.74 2.85 3.47-1.44-1.72-2.85-3.47zm3.46 4.21c1 1.18 2 2.35 3 3.51-1-1.19-2.01-2.36-3-3.51zm-10.23-13q1.36 1.85 2.76 3.66-1.39-1.78-2.76-3.66zm3.35 4.44q1.37 1.8 2.77 3.56-1.4-1.76-2.77-3.53zm32.89 35q1.74 1.53 3.51 3-1.77-1.44-3.51-2.97zM105.31 453q1.81 1.4 3.66 2.76-1.84-1.4-3.66-2.76zm8.2 6q-2-1.41-4-2.85 2.01 1.43 4 2.85zM101 449.6q1.74 1.39 3.51 2.77-1.75-1.37-3.51-2.77zm-45.15-47.16c-1-1.31-1.9-2.62-2.84-3.95.99 1.33 1.88 2.64 2.84 3.95zM65.9 96.75q-1.44 1.71-2.85 3.46 1.41-1.75 2.85-3.46zM56.29 109c.9-1.23 1.82-2.45 2.74-3.65-.92 1.17-1.84 2.39-2.74 3.65zm6.11-8q-1.4 1.74-2.76 3.51Q61 102.76 62.4 101zm7.12-8.5c-1 1.16-2 2.33-3 3.51.98-1.16 1.99-2.33 3-3.49zm23-23q1.74-1.53 3.51-3-1.77 1.5-3.51 3.03zm-.45 372.55a248.94 248.94 0 0 1-22.15-22.15 248.94 248.94 0 0 0 22.15 22.18zM165 286.54a96.5 96.5 0 0 1 0-61.08L53 113.51a248 248 0 0 0 0 285zm-109.11-177q-1.44 2-2.84 3.93 1.36-1.95 2.8-3.9z\",\n          \"M347 225.46l112-111.95A249.4 249.4 0 0 0 398.49 53L286.54 165A96.26 96.26 0 0 1 347 225.46zm-182 61.08l-112 112a249.4 249.4 0 0 0 60.5 60.5L225.46 347A96.26 96.26 0 0 1 165 286.54zm-112-173l112 112a96.26 96.26 0 0 1 60.5-60.5L113.51 53A249.4 249.4 0 0 0 53 113.51zM286.54 347l112 112a249.4 249.4 0 0 0 60.5-60.5L347 286.54A96.26 96.26 0 0 1 286.54 347z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"lightbulb\": {\n    \"changes\": [\n      \"3\",\n      \"5.0.0\",\n      \"5.3.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"energy\",\n        \"idea\",\n        \"inspiration\",\n        \"light\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f0eb\",\n    \"label\": \"Lightbulb\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 352 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M175.45 0C73.44.31 0 83 0 176a175 175 0 0 0 43.56 115.78c16.52 18.85 42.36 58.22 52.21 91.45 0 .26.07.52.11.78h160.24c0-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45A175.9 175.9 0 0 0 175.45 0zm.55 96a80.09 80.09 0 0 0-80 80 16 16 0 0 1-32 0A112.12 112.12 0 0 1 176 64a16 16 0 0 1 0 32z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M96.06 454.35L96 416h160v38.35a32 32 0 0 1-5.41 17.65l-17.09 25.73A32 32 0 0 1 206.86 512h-61.71a32 32 0 0 1-26.64-14.28L101.42 472a32 32 0 0 1-5.36-17.65z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"352\",\n          \"512\"\n        ],\n        \"width\": 352,\n        \"height\": 512,\n        \"path\": [\n          \"M175.45 0C73.44.31 0 83 0 176a175 175 0 0 0 43.56 115.78c16.52 18.85 42.36 58.22 52.21 91.45 0 .26.07.52.11.78h160.24c0-.26.07-.51.11-.78 9.85-33.22 35.69-72.6 52.21-91.45A175.9 175.9 0 0 0 175.45 0zm.55 96a80.09 80.09 0 0 0-80 80 16 16 0 0 1-32 0A112.12 112.12 0 0 1 176 64a16 16 0 0 1 0 32z\",\n          \"M96.06 454.35L96 416h160v38.35a32 32 0 0 1-5.41 17.65l-17.09 25.73A32 32 0 0 1 206.86 512h-61.71a32 32 0 0 1-26.64-14.28L101.42 472a32 32 0 0 1-5.36-17.65z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"list-alt\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"checklist\",\n        \"completed\",\n        \"done\",\n        \"finished\",\n        \"ol\",\n        \"todo\",\n        \"ul\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f022\",\n    \"label\": \"Alternate List\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M464 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zM128 392a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm288 168a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M128 200a40 40 0 1 0-40-40 40 40 0 0 0 40 40zm0 16a40 40 0 1 0 40 40 40 40 0 0 0-40-40zm0 96a40 40 0 1 0 40 40 40 40 0 0 0-40-40z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M464 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h416a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zM128 392a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm0-96a40 40 0 1 1 40-40 40 40 0 0 1-40 40zm288 168a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12zm0-96a12 12 0 0 1-12 12H204a12 12 0 0 1-12-12v-32a12 12 0 0 1 12-12h200a12 12 0 0 1 12 12z\",\n          \"M128 200a40 40 0 1 0-40-40 40 40 0 0 0 40 40zm0 16a40 40 0 1 0 40 40 40 40 0 0 0-40-40zm0 96a40 40 0 1 0 40 40 40 40 0 0 0-40-40z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"list-ul\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\",\n      \"5.9.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"checklist\",\n        \"completed\",\n        \"done\",\n        \"finished\",\n        \"ol\",\n        \"todo\",\n        \"ul\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f0ca\",\n    \"label\": \"list-ul\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M496 384H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M496 384H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H176a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h320a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\",\n          \"M48 48a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48zm0 160a48 48 0 1 0 48 48 48 48 0 0 0-48-48z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"lock-alt\": {\n    \"changes\": [\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"admin\",\n        \"lock\",\n        \"open\",\n        \"password\",\n        \"private\",\n        \"protect\",\n        \"security\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f30d\",\n    \"label\": \"Alternate Lock\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M152 225H72v-72C72 69.2 140.2 1 224 1s152 68.2 152 152v72h-80v-72a72 72 0 0 0-144 0z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M400 225H48a48 48 0 0 0-48 48v192a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V273a48 48 0 0 0-48-48zM264 392a40 40 0 0 1-80 0v-48a40 40 0 0 1 80 0z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": [\n          \"M152 225H72v-72C72 69.2 140.2 1 224 1s152 68.2 152 152v72h-80v-72a72 72 0 0 0-144 0z\",\n          \"M400 225H48a48 48 0 0 0-48 48v192a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V273a48 48 0 0 0-48-48zM264 392a40 40 0 0 1-80 0v-48a40 40 0 0 1 80 0z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"map-marker-alt\": {\n    \"changes\": [\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"address\",\n        \"coordinates\",\n        \"destination\",\n        \"gps\",\n        \"localize\",\n        \"location\",\n        \"map\",\n        \"navigation\",\n        \"paper\",\n        \"pin\",\n        \"place\",\n        \"point of interest\",\n        \"position\",\n        \"route\",\n        \"travel\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f3c5\",\n    \"label\": \"Alternate Map Marker\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 384 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M192 0C86 0 0 86 0 192c0 77.41 27 99 172.27 309.67a24 24 0 0 0 39.46 0C357 291 384 269.41 384 192 384 86 298 0 192 0zm0 288a96 96 0 1 1 96-96 96 96 0 0 1-96 96z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M192 256a64 64 0 1 1 64-64 64 64 0 0 1-64 64z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"384\",\n          \"512\"\n        ],\n        \"width\": 384,\n        \"height\": 512,\n        \"path\": [\n          \"M192 0C86 0 0 86 0 192c0 77.41 27 99 172.27 309.67a24 24 0 0 0 39.46 0C357 291 384 269.41 384 192 384 86 298 0 192 0zm0 288a96 96 0 1 1 96-96 96 96 0 0 1-96 96z\",\n          \"M192 256a64 64 0 1 1 64-64 64 64 0 0 1-64 64z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"microsoft\": {\n    \"changes\": [\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f3ca\",\n    \"label\": \"Microsoft\",\n    \"voted\": true,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440861000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M0 32h214.6v214.6H0V32zm233.4 0H448v214.6H233.4V32zM0 265.4h214.6V480H0V265.4zm233.4 0H448V480H233.4V265.4z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"moon-stars\": {\n    \"changes\": [\n      \"5.5.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"clear\",\n        \"crescent\",\n        \"lunar\",\n        \"space\",\n        \"star\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f755\",\n    \"label\": \"Moon with Stars\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M320 32L304 0l-16 32-32 16 32 16 16 32 16-32 32-16zm138.7 149.3L432 128l-26.7 53.3L352 208l53.3 26.7L432 288l26.7-53.3L512 208z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M332.2 426.4c8.1-1.6 13.9 8 8.6 14.5a191.18 191.18 0 0 1-149 71.1C85.8 512 0 426 0 320c0-120 108.7-210.6 227-188.8 8.2 1.6 10.1 12.6 2.8 16.7a150.3 150.3 0 0 0-76.1 130.8c0 94 85.4 165.4 178.5 147.7z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M320 32L304 0l-16 32-32 16 32 16 16 32 16-32 32-16zm138.7 149.3L432 128l-26.7 53.3L352 208l53.3 26.7L432 288l26.7-53.3L512 208z\",\n          \"M332.2 426.4c8.1-1.6 13.9 8 8.6 14.5a191.18 191.18 0 0 1-149 71.1C85.8 512 0 426 0 320c0-120 108.7-210.6 227-188.8 8.2 1.6 10.1 12.6 2.8 16.7a150.3 150.3 0 0 0-76.1 130.8c0 94 85.4 165.4 178.5 147.7z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"network-wired\": {\n    \"changes\": [\n      \"5.4.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"computer\",\n        \"connect\",\n        \"ethernet\",\n        \"internet\",\n        \"intranet\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f6ff\",\n    \"label\": \"Wired Network\",\n    \"voted\": true,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M624 232H344v-40h-48v40H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h104v40h48v-40h304v40h48v-40h104a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M224 192h192a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32H224a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32zm32-128h128v64H256zm320 256H416a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128h-96v-64h96zM224 320H64a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128H96v-64h96z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M624 232H344v-40h-48v40H16a16 16 0 0 0-16 16v16a16 16 0 0 0 16 16h104v40h48v-40h304v40h48v-40h104a16 16 0 0 0 16-16v-16a16 16 0 0 0-16-16z\",\n          \"M224 192h192a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32H224a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32zm32-128h128v64H256zm320 256H416a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128h-96v-64h96zM224 320H64a32 32 0 0 0-32 32v128a32 32 0 0 0 32 32h160a32 32 0 0 0 32-32V352a32 32 0 0 0-32-32zm-32 128H96v-64h96z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"planet-ringed\": {\n    \"changes\": [\n      \"5.12.0\",\n      \"5.14.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"orbit\",\n        \"saturn\",\n        \"solar system\",\n        \"space\",\n        \"universe\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"e020\",\n    \"label\": \"Ringed Planet\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M323.33815,323.33517C186.95939,459.71018,46.2602,540.11093,9.06777,502.9165c-23.48893-23.4909.01172-88.30917,54.81792-167.21379a206.56361,206.56361,0,0,0,25.02022,43.78446c-22.45765,34.20607-32.036,58.99194-23.71941,67.31053,18.59817,18.59624,119.10094-51.75539,224.47885-157.13342C395.04325,184.2882,465.39675,83.78336,446.79858,65.18712c-8.32054-8.3186-33.10638,1.26176-67.31045,23.71748a206.52984,206.52984,0,0,0-43.78245-25.0183C414.61019,9.082,479.42839-14.42259,502.91732,9.06832,540.10975,46.2608,459.70909,186.96211,323.33815,323.33517Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M448.0994,176.28016c-31.96573,46.02281-74.52549,96.81528-124.76125,147.055-50.24357,50.24168-101.034,92.79954-147.05874,124.76531,75.41614,31.25675,165.47721,16.29343,226.79531-45.02474S479.35807,251.69834,448.0994,176.28016Zm-25.02022-43.78251A208.22535,208.22535,0,0,0,403.07472,108.911c-81.2288-81.23281-212.93555-81.23281-294.16435,0-81.22881,81.23085-81.22881,212.93385,0,294.1647A208.25527,208.25527,0,0,0,132.497,423.08023c42.25117-27.73908,98.93242-75.1799,157.1684-133.41595C347.90133,231.43018,395.34013,174.75473,423.07918,132.49765Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M323.33815,323.33517C186.95939,459.71018,46.2602,540.11093,9.06777,502.9165c-23.48893-23.4909.01172-88.30917,54.81792-167.21379a206.56361,206.56361,0,0,0,25.02022,43.78446c-22.45765,34.20607-32.036,58.99194-23.71941,67.31053,18.59817,18.59624,119.10094-51.75539,224.47885-157.13342C395.04325,184.2882,465.39675,83.78336,446.79858,65.18712c-8.32054-8.3186-33.10638,1.26176-67.31045,23.71748a206.52984,206.52984,0,0,0-43.78245-25.0183C414.61019,9.082,479.42839-14.42259,502.91732,9.06832,540.10975,46.2608,459.70909,186.96211,323.33815,323.33517Z\",\n          \"M448.0994,176.28016c-31.96573,46.02281-74.52549,96.81528-124.76125,147.055-50.24357,50.24168-101.034,92.79954-147.05874,124.76531,75.41614,31.25675,165.47721,16.29343,226.79531-45.02474S479.35807,251.69834,448.0994,176.28016Zm-25.02022-43.78251A208.22535,208.22535,0,0,0,403.07472,108.911c-81.2288-81.23281-212.93555-81.23281-294.16435,0-81.22881,81.23085-81.22881,212.93385,0,294.1647A208.25527,208.25527,0,0,0,132.497,423.08023c42.25117-27.73908,98.93242-75.1799,157.1684-133.41595C347.90133,231.43018,395.34013,174.75473,423.07918,132.49765Z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"plus\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\",\n      \"5.0.13\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"add\",\n        \"create\",\n        \"expand\",\n        \"new\",\n        \"positive\",\n        \"shape\"\n      ]\n    },\n    \"styles\": [\n      \"regular\",\n      \"solid\"\n    ],\n    \"unicode\": \"f067\",\n    \"label\": \"plus\",\n    \"voted\": false,\n    \"svg\": {\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 384 512\\\"><path d=\\\"M368 224H224V80c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h144v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V288h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"384\",\n          \"512\"\n        ],\n        \"width\": 384,\n        \"height\": 512,\n        \"path\": \"M368 224H224V80c0-8.84-7.16-16-16-16h-32c-8.84 0-16 7.16-16 16v144H16c-8.84 0-16 7.16-16 16v32c0 8.84 7.16 16 16 16h144v144c0 8.84 7.16 16 16 16h32c8.84 0 16-7.16 16-16V288h144c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16z\"\n      },\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M416 208H272V64c0-17.67-14.33-32-32-32h-32c-17.67 0-32 14.33-32 32v144H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h144v144c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32V304h144c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"question-circle\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"help\",\n        \"information\",\n        \"support\",\n        \"unknown\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\",\n      \"regular\"\n    ],\n    \"unicode\": \"f059\",\n    \"label\": \"Question Circle\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M256 8C119 8 8 119.08 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 422a46 46 0 1 1 46-46 46.05 46.05 0 0 1-46 46zm40-131.33V300a12 12 0 0 1-12 12h-56a12 12 0 0 1-12-12v-4c0-41.06 31.13-57.47 54.65-70.66 20.17-11.31 32.54-19 32.54-34 0-19.82-25.27-33-45.7-33-27.19 0-39.44 13.14-57.3 35.79a12 12 0 0 1-16.67 2.13L148.82 170a12 12 0 0 1-2.71-16.26C173.4 113 208.16 90 262.66 90c56.34 0 116.53 44 116.53 102 0 77-83.19 78.21-83.19 106.67z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M256 338a46 46 0 1 0 46 46 46 46 0 0 0-46-46zm6.66-248c-54.5 0-89.26 23-116.55 63.76a12 12 0 0 0 2.71 16.24l34.7 26.31a12 12 0 0 0 16.67-2.13c17.86-22.65 30.11-35.79 57.3-35.79 20.43 0 45.7 13.14 45.7 33 0 15-12.37 22.66-32.54 34C247.13 238.53 216 254.94 216 296v4a12 12 0 0 0 12 12h56a12 12 0 0 0 12-12v-1.33c0-28.46 83.19-29.67 83.19-106.67 0-58-60.19-102-116.53-102z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M256 8C119 8 8 119.08 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 422a46 46 0 1 1 46-46 46.05 46.05 0 0 1-46 46zm40-131.33V300a12 12 0 0 1-12 12h-56a12 12 0 0 1-12-12v-4c0-41.06 31.13-57.47 54.65-70.66 20.17-11.31 32.54-19 32.54-34 0-19.82-25.27-33-45.7-33-27.19 0-39.44 13.14-57.3 35.79a12 12 0 0 1-16.67 2.13L148.82 170a12 12 0 0 1-2.71-16.26C173.4 113 208.16 90 262.66 90c56.34 0 116.53 44 116.53 102 0 77-83.19 78.21-83.19 106.67z\",\n          \"M256 338a46 46 0 1 0 46 46 46 46 0 0 0-46-46zm6.66-248c-54.5 0-89.26 23-116.55 63.76a12 12 0 0 0 2.71 16.24l34.7 26.31a12 12 0 0 0 16.67-2.13c17.86-22.65 30.11-35.79 57.3-35.79 20.43 0 45.7 13.14 45.7 33 0 15-12.37 22.66-32.54 34C247.13 238.53 216 254.94 216 296v4a12 12 0 0 0 12 12h56a12 12 0 0 0 12-12v-1.33c0-28.46 83.19-29.67 83.19-106.67 0-58-60.19-102-116.53-102z\"\n        ]\n      },\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 448c-110.532 0-200-89.431-200-200 0-110.495 89.472-200 200-200 110.491 0 200 89.471 200 200 0 110.53-89.431 200-200 200zm107.244-255.2c0 67.052-72.421 68.084-72.421 92.863V300c0 6.627-5.373 12-12 12h-45.647c-6.627 0-12-5.373-12-12v-8.659c0-35.745 27.1-50.034 47.579-61.516 17.561-9.845 28.324-16.541 28.324-29.579 0-17.246-21.999-28.693-39.784-28.693-23.189 0-33.894 10.977-48.942 29.969-4.057 5.12-11.46 6.071-16.666 2.124l-27.824-21.098c-5.107-3.872-6.251-11.066-2.644-16.363C184.846 131.491 214.94 112 261.794 112c49.071 0 101.45 38.304 101.45 88.8zM298 368c0 23.159-18.841 42-42 42s-42-18.841-42-42 18.841-42 42-42 42 18.841 42 42z\"\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"quote-left\": {\n    \"changes\": [\n      \"3\",\n      \"5.0.0\",\n      \"5.0.9\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"mention\",\n        \"note\",\n        \"phrase\",\n        \"text\",\n        \"type\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f10d\",\n    \"label\": \"quote-left\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M464 256h-80v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H448a160 160 0 0 0-160 160v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M176 256H96v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H160A160 160 0 0 0 0 192v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M464 256h-80v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H448a160 160 0 0 0-160 160v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\",\n          \"M176 256H96v-64a64.06 64.06 0 0 1 64-64h8a23.94 23.94 0 0 0 24-23.88V56a23.94 23.94 0 0 0-23.88-24H160A160 160 0 0 0 0 192v240a48 48 0 0 0 48 48h128a48 48 0 0 0 48-48V304a48 48 0 0 0-48-48z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"random\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"arrows\",\n        \"shuffle\",\n        \"sort\",\n        \"swap\",\n        \"switch\",\n        \"transfer\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f074\",\n    \"label\": \"random\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M505 359l-80-80c-15-15-41-4.47-41 17v40h-32l-52.78-56.55-53.33 57.14 70.55 75.6a12 12 0 0 0 8.77 3.81H384v40c0 21.46 26 32 41 17l80-80a24 24 0 0 0 0-34zM122.79 96H12a12 12 0 0 0-12 12v56a12 12 0 0 0 12 12h84l52.78 56.55 53.33-57.14-70.55-75.6a12 12 0 0 0-8.77-3.81z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M505 119a24 24 0 0 1 0 34l-80 80c-15 15-41 4.48-41-17v-40h-32L131.56 412.19a12 12 0 0 1-8.77 3.81H12a12 12 0 0 1-12-12v-56a12 12 0 0 1 12-12h84L316.44 99.81a12 12 0 0 1 8.78-3.81H384V56c0-21.44 25.94-32 41-17z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M505 359l-80-80c-15-15-41-4.47-41 17v40h-32l-52.78-56.55-53.33 57.14 70.55 75.6a12 12 0 0 0 8.77 3.81H384v40c0 21.46 26 32 41 17l80-80a24 24 0 0 0 0-34zM122.79 96H12a12 12 0 0 0-12 12v56a12 12 0 0 0 12 12h84l52.78 56.55 53.33-57.14-70.55-75.6a12 12 0 0 0-8.77-3.81z\",\n          \"M505 119a24 24 0 0 1 0 34l-80 80c-15 15-41 4.48-41-17v-40h-32L131.56 412.19a12 12 0 0 1-8.77 3.81H12a12 12 0 0 1-12-12v-56a12 12 0 0 1 12-12h84L316.44 99.81a12 12 0 0 1 8.78-3.81H384V56c0-21.44 25.94-32 41-17z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"rev\": {\n    \"changes\": [\n      \"5.1.0\",\n      \"5.1.1\",\n      \"5.8.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": []\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f5b2\",\n    \"label\": \"Rev.io\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1558987775000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M289.67 274.89a65.57 65.57 0 1 1-65.56-65.56 65.64 65.64 0 0 1 65.56 65.56zm139.55-5.05h-.13a204.69 204.69 0 0 0-74.32-153l-45.38 26.2a157.07 157.07 0 0 1 71.81 131.84C381.2 361.5 310.73 432 224.11 432S67 361.5 67 274.88c0-81.88 63-149.27 143-156.43v39.12l108.77-62.79L210 32v38.32c-106.7 7.25-191 96-191 204.57 0 111.59 89.12 202.29 200.06 205v.11h210.16V269.84z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M289.67 274.89a65.57 65.57 0 1 1-65.56-65.56 65.64 65.64 0 0 1 65.56 65.56zm139.55-5.05h-.13a204.69 204.69 0 0 0-74.32-153l-45.38 26.2a157.07 157.07 0 0 1 71.81 131.84C381.2 361.5 310.73 432 224.11 432S67 361.5 67 274.88c0-81.88 63-149.27 143-156.43v39.12l108.77-62.79L210 32v38.32c-106.7 7.25-191 96-191 204.57 0 111.59 89.12 202.29 200.06 205v.11h210.16V269.84z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"robot\": {\n    \"changes\": [\n      \"5.0.13\",\n      \"5.12.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"android\",\n        \"automate\",\n        \"computer\",\n        \"cyborg\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f544\",\n    \"label\": \"Robot\",\n    \"voted\": true,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><path d=\\\"M32,224H64V416H32A31.96166,31.96166,0,0,1,0,384V256A31.96166,31.96166,0,0,1,32,224Zm512-48V448a64.06328,64.06328,0,0,1-64,64H160a64.06328,64.06328,0,0,1-64-64V176a79.974,79.974,0,0,1,80-80H288V32a32,32,0,0,1,64,0V96H464A79.974,79.974,0,0,1,544,176ZM264,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,264,256Zm-8,128H192v32h64Zm96,0H288v32h64ZM456,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,456,256Zm-8,128H384v32h64ZM640,256V384a31.96166,31.96166,0,0,1-32,32H576V224h32A31.96166,31.96166,0,0,1,640,256Z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": \"M32,224H64V416H32A31.96166,31.96166,0,0,1,0,384V256A31.96166,31.96166,0,0,1,32,224Zm512-48V448a64.06328,64.06328,0,0,1-64,64H160a64.06328,64.06328,0,0,1-64-64V176a79.974,79.974,0,0,1,80-80H288V32a32,32,0,0,1,64,0V96H464A79.974,79.974,0,0,1,544,176ZM264,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,264,256Zm-8,128H192v32h64Zm96,0H288v32h64ZM456,256a40,40,0,1,0-40,40A39.997,39.997,0,0,0,456,256Zm-8,128H384v32h64ZM640,256V384a31.96166,31.96166,0,0,1-32,32H576V224h32A31.96166,31.96166,0,0,1,640,256Z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"rocket\": {\n    \"changes\": [\n      \"3.1\",\n      \"5.0.0\",\n      \"5.7.0\",\n      \"5.12.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"aircraft\",\n        \"app\",\n        \"jet\",\n        \"launch\",\n        \"nasa\",\n        \"space\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\",\n      \"solid\",\n      \"regular\"\n    ],\n    \"unicode\": \"f135\",\n    \"label\": \"rocket\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M51.94117,154.48438,2.531,253.29688A28.125,28.125,0,0,0-.00023,264a24.00619,24.00619,0,0,0,24,24H117.4607c23.44141-47.41211,61.01172-123.373,77.89063-157.32812.51953-.91407,1-1.76758,1.52344-2.67188H94.82008C78.47633,128.01562,59.28883,139.875,51.94117,154.48438Zm172.0586,240.1621V488.209A24.12394,24.12394,0,0,0,247.9607,512a28.02965,28.02965,0,0,0,10.625-2.53125l98.72657-49.39063c14.625-7.3125,26.5-26.5,26.5-42.85937V315.70312c.0664-.041.125-.08789.1875-.1289v-.52734c-.90625.51953-1.7461,1.002-2.66407,1.52539C347.37477,333.58008,271.2732,371.252,223.99977,394.64648Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M505.15992,19.51562A16.73971,16.73971,0,0,0,492.62477,6.94531C460.22633,0,434.37477,0,409.48414,0,320.3357,0,252.80836,40.61523,196.97633,127.81836c-.5586.97852-1.07031,1.877-1.625,2.85352-19.59766,39.42578-67.20313,135.70312-88.04688,177.877a31.91421,31.91421,0,0,0,6.09766,36.76172L167.05445,398.709a31.88923,31.88923,0,0,0,36.64844,5.98047l14.17578-7.01367c46.57422-23.04883,128.06641-63.3789,163.457-81.10351.96094-.54883,1.832-1.04883,2.78907-1.59766,87.23437-56.06055,127.85937-123.51172,127.85937-212.27734C512.06227,77.60742,512.12867,52.08789,505.15992,19.51562ZM367.99977,192a48,48,0,1,1,48-48.00195A48.02156,48.02156,0,0,1,367.99977,192Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M51.94117,154.48438,2.531,253.29688A28.125,28.125,0,0,0-.00023,264a24.00619,24.00619,0,0,0,24,24H117.4607c23.44141-47.41211,61.01172-123.373,77.89063-157.32812.51953-.91407,1-1.76758,1.52344-2.67188H94.82008C78.47633,128.01562,59.28883,139.875,51.94117,154.48438Zm172.0586,240.1621V488.209A24.12394,24.12394,0,0,0,247.9607,512a28.02965,28.02965,0,0,0,10.625-2.53125l98.72657-49.39063c14.625-7.3125,26.5-26.5,26.5-42.85937V315.70312c.0664-.041.125-.08789.1875-.1289v-.52734c-.90625.51953-1.7461,1.002-2.66407,1.52539C347.37477,333.58008,271.2732,371.252,223.99977,394.64648Z\",\n          \"M505.15992,19.51562A16.73971,16.73971,0,0,0,492.62477,6.94531C460.22633,0,434.37477,0,409.48414,0,320.3357,0,252.80836,40.61523,196.97633,127.81836c-.5586.97852-1.07031,1.877-1.625,2.85352-19.59766,39.42578-67.20313,135.70312-88.04688,177.877a31.91421,31.91421,0,0,0,6.09766,36.76172L167.05445,398.709a31.88923,31.88923,0,0,0,36.64844,5.98047l14.17578-7.01367c46.57422-23.04883,128.06641-63.3789,163.457-81.10351.96094-.54883,1.832-1.04883,2.78907-1.59766,87.23437-56.06055,127.85937-123.51172,127.85937-212.27734C512.06227,77.60742,512.12867,52.08789,505.15992,19.51562ZM367.99977,192a48,48,0,1,1,48-48.00195A48.02156,48.02156,0,0,1,367.99977,192Z\"\n        ]\n      },\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M505.12019,19.09375c-1.18945-5.53125-6.65819-11-12.207-12.1875C460.716,0,435.507,0,410.40747,0,307.17523,0,245.26909,55.20312,199.05238,128H94.83772c-16.34763.01562-35.55658,11.875-42.88664,26.48438L2.51562,253.29688A28.4,28.4,0,0,0,0,264a24.00867,24.00867,0,0,0,24.00582,24H127.81618l-22.47457,22.46875c-11.36521,11.36133-12.99607,32.25781,0,45.25L156.24582,406.625c11.15623,11.1875,32.15619,13.15625,45.27726,0l22.47457-22.46875V488a24.00867,24.00867,0,0,0,24.00581,24,28.55934,28.55934,0,0,0,10.707-2.51562l98.72834-49.39063c14.62888-7.29687,26.50776-26.5,26.50776-42.85937V312.79688c72.59753-46.3125,128.03493-108.40626,128.03493-211.09376C512.07526,76.5,512.07526,51.29688,505.12019,19.09375ZM384.04033,168A40,40,0,1,1,424.05,128,40.02322,40.02322,0,0,1,384.04033,168Z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M505.12019,19.09375c-1.18945-5.53125-6.65819-11-12.207-12.1875C460.716,0,435.507,0,410.40747,0,307.17523,0,245.26909,55.20312,199.05238,128H94.83772c-16.34763.01562-35.55658,11.875-42.88664,26.48438L2.51562,253.29688A28.4,28.4,0,0,0,0,264a24.00867,24.00867,0,0,0,24.00582,24H127.81618l-22.47457,22.46875c-11.36521,11.36133-12.99607,32.25781,0,45.25L156.24582,406.625c11.15623,11.1875,32.15619,13.15625,45.27726,0l22.47457-22.46875V488a24.00867,24.00867,0,0,0,24.00581,24,28.55934,28.55934,0,0,0,10.707-2.51562l98.72834-49.39063c14.62888-7.29687,26.50776-26.5,26.50776-42.85937V312.79688c72.59753-46.3125,128.03493-108.40626,128.03493-211.09376C512.07526,76.5,512.07526,51.29688,505.12019,19.09375ZM384.04033,168A40,40,0,1,1,424.05,128,40.02322,40.02322,0,0,1,384.04033,168Z\"\n      },\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M367.96813,103.99609a39.999,39.999,0,1,0,40.00384,40A40.02908,40.02908,0,0,0,367.96813,103.99609ZM505.07337,19.3418c-1.21875-5.60742-6.75-11.13868-12.34373-12.3418-32.62885-7-58.162-7-83.57017-7C305.39988,0,242.95858,55.0918,196.236,127.99609H94.82015c-16.34567.01563-35.53314,11.875-42.87883,26.48243L2.53125,253.28906A28.12512,28.12512,0,0,0,0,263.99219a24.00617,24.00617,0,0,0,24.00191,23.998h92.63266l-10.59373,21.42188c-9.33592,18.91016,4.27733,34.77344,6.15624,36.62305l53.75381,53.71875c15.56443,15.54492,33.81635,7.52929,36.6601,6.13867l21.34567-10.57617V488a24.00659,24.00659,0,0,0,24.00191,24,28.618,28.618,0,0,0,10.71873-2.51562l98.6971-49.4043c14.625-7.29688,26.50191-26.5,26.50191-42.85938V315.69336c72.72449-46.76367,128.10525-109.44922,128.10525-212.69727C512.07531,77.4668,512.07531,51.99805,505.07337,19.3418ZM358.53065,274.99023c-36.94135,18.48438-121.10527,60.14063-166.7966,82.73243l-37.50189-37.49805c22.59567-45.6875,64.25575-129.99609,82.72447-166.88672C284.33741,79.5293,335.96623,47.99805,409.15947,47.99805c18.00192,0,34.2851,0,52.56632,2.34375,2.375,18.71875,2.31249,35.27929,2.25,52.63867C463.97578,175.75977,432.41138,227.30469,358.53065,274.99023Z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M367.96813,103.99609a39.999,39.999,0,1,0,40.00384,40A40.02908,40.02908,0,0,0,367.96813,103.99609ZM505.07337,19.3418c-1.21875-5.60742-6.75-11.13868-12.34373-12.3418-32.62885-7-58.162-7-83.57017-7C305.39988,0,242.95858,55.0918,196.236,127.99609H94.82015c-16.34567.01563-35.53314,11.875-42.87883,26.48243L2.53125,253.28906A28.12512,28.12512,0,0,0,0,263.99219a24.00617,24.00617,0,0,0,24.00191,23.998h92.63266l-10.59373,21.42188c-9.33592,18.91016,4.27733,34.77344,6.15624,36.62305l53.75381,53.71875c15.56443,15.54492,33.81635,7.52929,36.6601,6.13867l21.34567-10.57617V488a24.00659,24.00659,0,0,0,24.00191,24,28.618,28.618,0,0,0,10.71873-2.51562l98.6971-49.4043c14.625-7.29688,26.50191-26.5,26.50191-42.85938V315.69336c72.72449-46.76367,128.10525-109.44922,128.10525-212.69727C512.07531,77.4668,512.07531,51.99805,505.07337,19.3418ZM358.53065,274.99023c-36.94135,18.48438-121.10527,60.14063-166.7966,82.73243l-37.50189-37.49805c22.59567-45.6875,64.25575-129.99609,82.72447-166.88672C284.33741,79.5293,335.96623,47.99805,409.15947,47.99805c18.00192,0,34.2851,0,52.56632,2.34375,2.375,18.71875,2.31249,35.27929,2.25,52.63867C463.97578,175.75977,432.41138,227.30469,358.53065,274.99023Z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"save\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\",\n      \"5.10.2\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"disk\",\n        \"download\",\n        \"floppy\",\n        \"floppy-o\"\n      ]\n    },\n    \"styles\": [\n      \"solid\",\n      \"regular\"\n    ],\n    \"unicode\": \"f0c7\",\n    \"label\": \"Save\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM224 416c-35.346 0-64-28.654-64-64 0-35.346 28.654-64 64-64s64 28.654 64 64c0 35.346-28.654 64-64 64zm96-304.52V212c0 6.627-5.373 12-12 12H76c-6.627 0-12-5.373-12-12V108c0-6.627 5.373-12 12-12h228.52c3.183 0 6.235 1.264 8.485 3.515l3.48 3.48A11.996 11.996 0 0 1 320 111.48z\"\n      },\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z\"\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"search\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"bigger\",\n        \"enlarge\",\n        \"find\",\n        \"magnify\",\n        \"preview\",\n        \"zoom\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f002\",\n    \"label\": \"Search\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M208 80a128 128 0 1 1-90.51 37.49A127.15 127.15 0 0 1 208 80m0-80C93.12 0 0 93.12 0 208s93.12 208 208 208 208-93.12 208-208S322.88 0 208 0z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M504.9 476.7L476.6 505a23.9 23.9 0 0 1-33.9 0L343 405.3a24 24 0 0 1-7-17V372l36-36h16.3a24 24 0 0 1 17 7l99.7 99.7a24.11 24.11 0 0 1-.1 34z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M208 80a128 128 0 1 1-90.51 37.49A127.15 127.15 0 0 1 208 80m0-80C93.12 0 0 93.12 0 208s93.12 208 208 208 208-93.12 208-208S322.88 0 208 0z\",\n          \"M504.9 476.7L476.6 505a23.9 23.9 0 0 1-33.9 0L343 405.3a24 24 0 0 1-7-17V372l36-36h16.3a24 24 0 0 1 17 7l99.7 99.7a24.11 24.11 0 0 1-.1 34z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"server\": {\n    \"changes\": [\n      \"4.3\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"computer\",\n        \"cpu\",\n        \"database\",\n        \"hardware\",\n        \"network\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f233\",\n    \"label\": \"Server\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M432 120a24 24 0 1 0-24-24 24 24 0 0 0 24 24zm0 272a24 24 0 1 0 24 24 24 24 0 0 0-24-24zm48-200H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M456 256a24 24 0 1 0-24 24 24 24 0 0 0 24-24zm24-224H32A32 32 0 0 0 0 64v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm48 232H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M432 120a24 24 0 1 0-24-24 24 24 0 0 0 24 24zm0 272a24 24 0 1 0 24 24 24 24 0 0 0-24-24zm48-200H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\",\n          \"M456 256a24 24 0 1 0-24 24 24 24 0 0 0 24-24zm24-224H32A32 32 0 0 0 0 64v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm48 232H32a32 32 0 0 0-32 32v64a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32v-64a32 32 0 0 0-32-32zm-112 88a24 24 0 1 1 24-24 24 24 0 0 1-24 24zm64 0a24 24 0 1 1 24-24 24 24 0 0 1-24 24z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"sign-out\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"arrow\",\n        \"exit\",\n        \"leave\",\n        \"log out\",\n        \"logout\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f08b\",\n    \"label\": \"Sign Out\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M180 448H96a96 96 0 0 1-96-96V160a96 96 0 0 1 96-96h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12H96a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M353 88.3l151.9 150.6a24 24 0 0 1 0 34.1l-152 150.8a24.08 24.08 0 0 1-33.9-.1l-21.9-21.9a24.07 24.07 0 0 1 .8-34.7l77.6-71.1H184a23.94 23.94 0 0 1-24-24v-32a23.94 23.94 0 0 1 24-24h191.5l-77.6-71.1a24 24 0 0 1-.7-34.6l21.9-21.9a24 24 0 0 1 33.9-.1z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M180 448H96a96 96 0 0 1-96-96V160a96 96 0 0 1 96-96h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12H96a32 32 0 0 0-32 32v192a32 32 0 0 0 32 32h84a12 12 0 0 1 12 12v40a12 12 0 0 1-12 12z\",\n          \"M353 88.3l151.9 150.6a24 24 0 0 1 0 34.1l-152 150.8a24.08 24.08 0 0 1-33.9-.1l-21.9-21.9a24.07 24.07 0 0 1 .8-34.7l77.6-71.1H184a23.94 23.94 0 0 1-24-24v-32a23.94 23.94 0 0 1 24-24h191.5l-77.6-71.1a24 24 0 0 1-.7-34.6l21.9-21.9a24 24 0 0 1 33.9-.1z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"siren-on\": {\n    \"changes\": [\n      \"5.12.0\",\n      \"5.14.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"alarm\",\n        \"alert\",\n        \"ambulance\",\n        \"loud\",\n        \"police\",\n        \"warning\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"e02e\",\n    \"label\": \"Siren On\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M224.21,134.94a8,8,0,0,1,9-6.87l15.86,2.13a8,8,0,0,1,6.87,9L231.82,320H496L471,120.06A64,64,0,0,0,407.5,64h-175A64,64,0,0,0,169,120.06L144,320h55.54Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M528,352H112a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16H528a16,16,0,0,0,16-16V368A16,16,0,0,0,528,352ZM112,192a24,24,0,0,0-24-24H24a24,24,0,0,0,0,48H88A24,24,0,0,0,112,192Zm504-24H552a24,24,0,0,0,0,48h64a24,24,0,0,0,0-48ZM90.69,76a24,24,0,1,0,26.62-39.92l-48-32A24,24,0,1,0,42.69,44ZM536,80a23.87,23.87,0,0,0,13.29-4l48-32A24,24,0,1,0,570.69,4.06l-48,32A24,24,0,0,0,536,80Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M224.21,134.94a8,8,0,0,1,9-6.87l15.86,2.13a8,8,0,0,1,6.87,9L231.82,320H496L471,120.06A64,64,0,0,0,407.5,64h-175A64,64,0,0,0,169,120.06L144,320h55.54Z\",\n          \"M528,352H112a16,16,0,0,0-16,16v64a16,16,0,0,0,16,16H528a16,16,0,0,0,16-16V368A16,16,0,0,0,528,352ZM112,192a24,24,0,0,0-24-24H24a24,24,0,0,0,0,48H88A24,24,0,0,0,112,192Zm504-24H552a24,24,0,0,0,0,48h64a24,24,0,0,0,0-48ZM90.69,76a24,24,0,1,0,26.62-39.92l-48-32A24,24,0,1,0,42.69,44ZM536,80a23.87,23.87,0,0,0,13.29-4l48-32A24,24,0,1,0,570.69,4.06l-48,32A24,24,0,0,0,536,80Z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"slack\": {\n    \"changes\": [\n      \"4.1\",\n      \"5.0.0\",\n      \"5.7.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"anchor\",\n        \"hash\",\n        \"hashtag\"\n      ]\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f198\",\n    \"label\": \"Slack Logo\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1548363722000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M94.12 315.1c0 25.9-21.16 47.06-47.06 47.06S0 341 0 315.1c0-25.9 21.16-47.06 47.06-47.06h47.06v47.06zm23.72 0c0-25.9 21.16-47.06 47.06-47.06s47.06 21.16 47.06 47.06v117.84c0 25.9-21.16 47.06-47.06 47.06s-47.06-21.16-47.06-47.06V315.1zm47.06-188.98c-25.9 0-47.06-21.16-47.06-47.06S139 32 164.9 32s47.06 21.16 47.06 47.06v47.06H164.9zm0 23.72c25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06H47.06C21.16 243.96 0 222.8 0 196.9s21.16-47.06 47.06-47.06H164.9zm188.98 47.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06s-21.16 47.06-47.06 47.06h-47.06V196.9zm-23.72 0c0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06V79.06c0-25.9 21.16-47.06 47.06-47.06 25.9 0 47.06 21.16 47.06 47.06V196.9zM283.1 385.88c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06-25.9 0-47.06-21.16-47.06-47.06v-47.06h47.06zm0-23.72c-25.9 0-47.06-21.16-47.06-47.06 0-25.9 21.16-47.06 47.06-47.06h117.84c25.9 0 47.06 21.16 47.06 47.06 0 25.9-21.16 47.06-47.06 47.06H283.1z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"slash\": {\n    \"changes\": [\n      \"5.4.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"cancel\",\n        \"close\",\n        \"mute\",\n        \"off\",\n        \"stop\",\n        \"x\"\n      ]\n    },\n    \"styles\": [\n      \"solid\",\n      \"regular\"\n    ],\n    \"unicode\": \"f715\",\n    \"label\": \"Slash\",\n    \"voted\": true,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><path d=\\\"M594.53 508.63L6.18 53.9c-6.97-5.42-8.23-15.47-2.81-22.45L23.01 6.18C28.43-.8 38.49-2.06 45.47 3.37L633.82 458.1c6.97 5.42 8.23 15.47 2.81 22.45l-19.64 25.27c-5.42 6.98-15.48 8.23-22.46 2.81z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": \"M594.53 508.63L6.18 53.9c-6.97-5.42-8.23-15.47-2.81-22.45L23.01 6.18C28.43-.8 38.49-2.06 45.47 3.37L633.82 458.1c6.97 5.42 8.23 15.47 2.81 22.45l-19.64 25.27c-5.42 6.98-15.48 8.23-22.46 2.81z\"\n      },\n      \"regular\": {\n        \"last_modified\": 1628277665000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><path d=\\\"M604 508.49L6.01 40.98c-6.9-5.52-8.02-15.59-2.49-22.49L13.51 6C19.03-.9 29.1-2.01 36 3.51l598 467.51c6.9 5.52 8.02 15.59 2.49 22.49l-10 12.49c-5.52 6.9-15.59 8.01-22.49 2.49z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": \"M604 508.49L6.01 40.98c-6.9-5.52-8.02-15.59-2.49-22.49L13.51 6C19.03-.9 29.1-2.01 36 3.51l598 467.51c6.9 5.52 8.02 15.59 2.49 22.49l-10 12.49c-5.52 6.9-15.59 8.01-22.49 2.49z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"smile\": {\n    \"changes\": [\n      \"3.1\",\n      \"5.0.0\",\n      \"5.0.9\",\n      \"5.1.0\",\n      \"5.11.0\",\n      \"5.11.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"approve\",\n        \"emoticon\",\n        \"face\",\n        \"happy\",\n        \"rating\",\n        \"satisfied\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f118\",\n    \"label\": \"Smiling Face\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 496 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256,385,8,248,8Zm80,168a32,32,0,1,1-32,32A32,32,0,0,1,328,176Zm-160,0a32,32,0,1,1-32,32A32,32,0,0,1,168,176ZM362.8,346.2a149.38,149.38,0,0,1-229.6,0c-13.6-16.3,11-36.7,24.6-20.5a117.5,117.5,0,0,0,180.4,0C351.6,309.5,376.3,329.9,362.8,346.2Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M328,176a32,32,0,1,0,32,32A32,32,0,0,0,328,176Zm-160,0a32,32,0,1,0,32,32A32,32,0,0,0,168,176Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"496\",\n          \"512\"\n        ],\n        \"width\": 496,\n        \"height\": 512,\n        \"path\": [\n          \"M248,8C111,8,0,119,0,256S111,504,248,504,496,393,496,256,385,8,248,8Zm80,168a32,32,0,1,1-32,32A32,32,0,0,1,328,176Zm-160,0a32,32,0,1,1-32,32A32,32,0,0,1,168,176ZM362.8,346.2a149.38,149.38,0,0,1-229.6,0c-13.6-16.3,11-36.7,24.6-20.5a117.5,117.5,0,0,0,180.4,0C351.6,309.5,376.3,329.9,362.8,346.2Z\",\n          \"M328,176a32,32,0,1,0,32,32A32,32,0,0,0,328,176Zm-160,0a32,32,0,1,0,32,32A32,32,0,0,0,168,176Z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"snowman\": {\n    \"changes\": [\n      \"5.6.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"decoration\",\n        \"frost\",\n        \"frosty\",\n        \"holiday\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f7d0\",\n    \"label\": \"Snowman\",\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M363.76 268.8a108.77 108.77 0 0 0 4.2-28.7v-.1a112.68 112.68 0 0 0-.73-12.8c-.11-1-.24-2-.38-3-.29-2-.62-4-1-6-.2-1-.4-1.95-.62-2.92-.22-1-.45-1.93-.7-2.9-.24-1-.5-1.91-.77-2.85-.27-.95-.55-1.89-.84-2.83-.3-.94-.6-1.87-.92-2.8-.32-.93-.65-1.86-1-2.77-.34-.92-.69-1.83-1.06-2.74-.36-.9-.74-1.8-1.13-2.7-.39-.89-.79-1.78-1.19-2.66-.41-.88-.83-1.76-1.26-2.63q-1.31-2.62-2.73-5.16c-.48-.85-1-1.68-1.46-2.51a112.44 112.44 0 0 0-21.62-26.19 96 96 0 1 0-149.16 0 112.49 112.49 0 0 0-21.68 26.28q-.74 1.23-1.44 2.49c-.48.84-.94 1.69-1.39 2.54-.45.85-.89 1.7-1.32 2.57-.43.87-.85 1.74-1.25 2.62-.41.88-.8 1.76-1.19 2.66-.39.89-.76 1.79-1.12 2.69-.36.91-.71 1.82-1.05 2.74-.34.92-.67 1.84-1 2.76a111.63 111.63 0 0 0-5.22 23.28A113 113 0 0 0 144 240h.06v.1a110.27 110.27 0 0 0 4.2 28.9A151.18 151.18 0 0 0 104 376.1c0 54 28.4 100.9 70.8 127.8 9.3 5.9 20.3 8.2 31.3 8.2h99.2a65.1 65.1 0 0 0 37.2-11.7c46.5-32.3 74.4-89.4 62.9-152.6-5.54-30.2-20.54-57.6-41.64-79zM224 96.1a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm32 272a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm0-64a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm1.7-64.1a15.19 15.19 0 0 1-3.48 0 16 16 0 1 1 3.48 0zm-1.7-87.9s-16-23.2-16-32a16 16 0 1 1 32 0c0 8.8-16 32-16 32zm32-56a16 16 0 1 1 16-16 16 16 0 0 1-16 16z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M510.86 152.4L505 137.9a16.15 16.15 0 0 0-20.8-8.7L456 140.7v-29a15.84 15.84 0 0 0-16-15.6h-16a15.84 15.84 0 0 0-16 15.6v46.9c0 .5.3 1 .3 1.5l-56.1 22.54a111.21 111.21 0 0 1 15.07 44.56L502 172.7a15.57 15.57 0 0 0 8.86-20.3zm-407.1 6.2v-46.9c.2-8.6-7-15.6-15.8-15.6H72a15.84 15.84 0 0 0-16 15.6v29l-28.1-11.5a16.15 16.15 0 0 0-20.8 8.7l-5.9 14.5a15.48 15.48 0 0 0 8.9 20.3l134.67 54.49a111.3 111.3 0 0 1 15-44.46l-56.31-22.63a8 8 0 0 0 .3-1.5zM256 336.1a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M363.76 268.8a108.77 108.77 0 0 0 4.2-28.7v-.1a112.68 112.68 0 0 0-.73-12.8c-.11-1-.24-2-.38-3-.29-2-.62-4-1-6-.2-1-.4-1.95-.62-2.92-.22-1-.45-1.93-.7-2.9-.24-1-.5-1.91-.77-2.85-.27-.95-.55-1.89-.84-2.83-.3-.94-.6-1.87-.92-2.8-.32-.93-.65-1.86-1-2.77-.34-.92-.69-1.83-1.06-2.74-.36-.9-.74-1.8-1.13-2.7-.39-.89-.79-1.78-1.19-2.66-.41-.88-.83-1.76-1.26-2.63q-1.31-2.62-2.73-5.16c-.48-.85-1-1.68-1.46-2.51a112.44 112.44 0 0 0-21.62-26.19 96 96 0 1 0-149.16 0 112.49 112.49 0 0 0-21.68 26.28q-.74 1.23-1.44 2.49c-.48.84-.94 1.69-1.39 2.54-.45.85-.89 1.7-1.32 2.57-.43.87-.85 1.74-1.25 2.62-.41.88-.8 1.76-1.19 2.66-.39.89-.76 1.79-1.12 2.69-.36.91-.71 1.82-1.05 2.74-.34.92-.67 1.84-1 2.76a111.63 111.63 0 0 0-5.22 23.28A113 113 0 0 0 144 240h.06v.1a110.27 110.27 0 0 0 4.2 28.9A151.18 151.18 0 0 0 104 376.1c0 54 28.4 100.9 70.8 127.8 9.3 5.9 20.3 8.2 31.3 8.2h99.2a65.1 65.1 0 0 0 37.2-11.7c46.5-32.3 74.4-89.4 62.9-152.6-5.54-30.2-20.54-57.6-41.64-79zM224 96.1a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm32 272a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm0-64a16 16 0 1 1 16-16 16 16 0 0 1-16 16zm1.7-64.1a15.19 15.19 0 0 1-3.48 0 16 16 0 1 1 3.48 0zm-1.7-87.9s-16-23.2-16-32a16 16 0 1 1 32 0c0 8.8-16 32-16 32zm32-56a16 16 0 1 1 16-16 16 16 0 0 1-16 16z\",\n          \"M510.86 152.4L505 137.9a16.15 16.15 0 0 0-20.8-8.7L456 140.7v-29a15.84 15.84 0 0 0-16-15.6h-16a15.84 15.84 0 0 0-16 15.6v46.9c0 .5.3 1 .3 1.5l-56.1 22.54a111.21 111.21 0 0 1 15.07 44.56L502 172.7a15.57 15.57 0 0 0 8.86-20.3zm-407.1 6.2v-46.9c.2-8.6-7-15.6-15.8-15.6H72a15.84 15.84 0 0 0-16 15.6v29l-28.1-11.5a16.15 16.15 0 0 0-20.8 8.7l-5.9 14.5a15.48 15.48 0 0 0 8.9 20.3l134.67 54.49a111.3 111.3 0 0 1 15-44.46l-56.31-22.63a8 8 0 0 0 .3-1.5zM256 336.1a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16zm0-64a16 16 0 1 0 16 16 16 16 0 0 0-16-16z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"spinner-third\": {\n    \"changes\": [\n      \"5.0.0\",\n      \"5.10.2\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"circle\",\n        \"loading\",\n        \"progress\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f3f4\",\n    \"label\": \"Spinner Third\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M456.433 371.72l-27.79-16.045c-7.192-4.152-10.052-13.136-6.487-20.636 25.82-54.328 23.566-118.602-6.768-171.03-30.265-52.529-84.802-86.621-144.76-91.424C262.35 71.922 256 64.953 256 56.649V24.56c0-9.31 7.916-16.609 17.204-15.96 81.795 5.717 156.412 51.902 197.611 123.408 41.301 71.385 43.99 159.096 8.042 232.792-4.082 8.369-14.361 11.575-22.424 6.92z\"\n      }\n    },\n    \"free\": []\n  },\n  \"square-full\": {\n    \"changes\": [\n      \"5.0.5\",\n      \"5.10.2\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"block\",\n        \"box\",\n        \"shape\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f45c\",\n    \"label\": \"Square Full\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M512 512H0V0h512v512z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M512 512H0V0h512v512z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"sun\": {\n    \"changes\": [\n      \"3.2\",\n      \"5.0.0\",\n      \"5.5.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"brighten\",\n        \"contrast\",\n        \"day\",\n        \"lighter\",\n        \"sol\",\n        \"solar\",\n        \"star\",\n        \"weather\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f185\",\n    \"label\": \"Sun\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M502.42 240.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.41-94.8a17.31 17.31 0 0 0-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4a17.31 17.31 0 0 0 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.41-33.5 47.3 94.7a17.31 17.31 0 0 0 31 0l47.31-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3a17.33 17.33 0 0 0 .2-31.1zm-155.9 106c-49.91 49.9-131.11 49.9-181 0a128.13 128.13 0 0 1 0-181c49.9-49.9 131.1-49.9 181 0a128.13 128.13 0 0 1 0 181z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M352 256a96 96 0 1 1-96-96 96.15 96.15 0 0 1 96 96z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M502.42 240.5l-94.7-47.3 33.5-100.4c4.5-13.6-8.4-26.5-21.9-21.9l-100.4 33.5-47.41-94.8a17.31 17.31 0 0 0-31 0l-47.3 94.7L92.7 70.8c-13.6-4.5-26.5 8.4-21.9 21.9l33.5 100.4-94.7 47.4a17.31 17.31 0 0 0 0 31l94.7 47.3-33.5 100.5c-4.5 13.6 8.4 26.5 21.9 21.9l100.41-33.5 47.3 94.7a17.31 17.31 0 0 0 31 0l47.31-94.7 100.4 33.5c13.6 4.5 26.5-8.4 21.9-21.9l-33.5-100.4 94.7-47.3a17.33 17.33 0 0 0 .2-31.1zm-155.9 106c-49.91 49.9-131.11 49.9-181 0a128.13 128.13 0 0 1 0-181c49.9-49.9 131.1-49.9 181 0a128.13 128.13 0 0 1 0 181z\",\n          \"M352 256a96 96 0 1 1-96-96 96.15 96.15 0 0 1 96 96z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"tasks\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\",\n      \"5.9.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"checklist\",\n        \"downloading\",\n        \"downloads\",\n        \"loading\",\n        \"progress\",\n        \"project management\",\n        \"settings\",\n        \"to do\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f0ae\",\n    \"label\": \"Tasks\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M496 384H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M139.61 35.5a12 12 0 0 0-17 0L58.93 98.81l-22.7-22.12a12 12 0 0 0-17 0L3.53 92.41a12 12 0 0 0 0 17l47.59 47.4a12.78 12.78 0 0 0 17.61 0l15.59-15.62L156.52 69a12.09 12.09 0 0 0 .09-17zm0 159.19a12 12 0 0 0-17 0l-63.68 63.72-22.7-22.1a12 12 0 0 0-17 0L3.53 252a12 12 0 0 0 0 17L51 316.5a12.77 12.77 0 0 0 17.6 0l15.7-15.69 72.2-72.22a12 12 0 0 0 .09-16.9zM64 368c-26.49 0-48.59 21.5-48.59 48S37.53 464 64 464a48 48 0 0 0 0-96z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M496 384H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm0-320H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16zm0 160H208a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h288a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16z\",\n          \"M139.61 35.5a12 12 0 0 0-17 0L58.93 98.81l-22.7-22.12a12 12 0 0 0-17 0L3.53 92.41a12 12 0 0 0 0 17l47.59 47.4a12.78 12.78 0 0 0 17.61 0l15.59-15.62L156.52 69a12.09 12.09 0 0 0 .09-17zm0 159.19a12 12 0 0 0-17 0l-63.68 63.72-22.7-22.1a12 12 0 0 0-17 0L3.53 252a12 12 0 0 0 0 17L51 316.5a12.77 12.77 0 0 0 17.6 0l15.7-15.69 72.2-72.22a12 12 0 0 0 .09-16.9zM64 368c-26.49 0-48.59 21.5-48.59 48S37.53 464 64 464a48 48 0 0 0 0-96z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"times\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\",\n      \"5.0.13\",\n      \"5.11.0\",\n      \"5.11.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"close\",\n        \"cross\",\n        \"error\",\n        \"exit\",\n        \"incorrect\",\n        \"notice\",\n        \"notification\",\n        \"notify\",\n        \"problem\",\n        \"wrong\",\n        \"x\"\n      ]\n    },\n    \"styles\": [\n      \"solid\",\n      \"regular\"\n    ],\n    \"unicode\": \"f00d\",\n    \"label\": \"Times\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 352 512\\\"><path d=\\\"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"352\",\n          \"512\"\n        ],\n        \"width\": 352,\n        \"height\": 512,\n        \"path\": \"M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z\"\n      },\n      \"regular\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 320 512\\\"><path d=\\\"M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"320\",\n          \"512\"\n        ],\n        \"width\": 320,\n        \"height\": 512,\n        \"path\": \"M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"times-circle\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"close\",\n        \"cross\",\n        \"exit\",\n        \"incorrect\",\n        \"notice\",\n        \"notification\",\n        \"notify\",\n        \"problem\",\n        \"wrong\",\n        \"x\"\n      ]\n    },\n    \"styles\": [\n      \"solid\"\n    ],\n    \"unicode\": \"f057\",\n    \"label\": \"Times Circle\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z\"\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"twitter\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"social network\",\n        \"tweet\"\n      ]\n    },\n    \"styles\": [\n      \"brands\"\n    ],\n    \"unicode\": \"f099\",\n    \"label\": \"Twitter\",\n    \"voted\": false,\n    \"svg\": {\n      \"brands\": {\n        \"last_modified\": 1546440861000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z\"\n      }\n    },\n    \"free\": [\n      \"brands\"\n    ]\n  },\n  \"undo\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"back\",\n        \"control z\",\n        \"exchange\",\n        \"oops\",\n        \"return\",\n        \"rotate\",\n        \"swap\"\n      ]\n    },\n    \"styles\": [\n      \"solid\",\n      \"regular\"\n    ],\n    \"unicode\": \"f0e2\",\n    \"label\": \"Undo\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z\"\n      },\n      \"regular\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M12 8h27.711c6.739 0 12.157 5.548 11.997 12.286l-2.347 98.568C93.925 51.834 170.212 7.73 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.835 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.322 0 196-87.662 196-196 0-108.322-87.662-196-196-196-79.545 0-147.941 47.282-178.675 115.302l126.389-3.009c6.737-.16 12.286 5.257 12.286 11.997V212c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V20C0 13.373 5.373 8 12 8z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M12 8h27.711c6.739 0 12.157 5.548 11.997 12.286l-2.347 98.568C93.925 51.834 170.212 7.73 256.793 8.001 393.18 8.428 504.213 120.009 504 256.396 503.786 393.181 392.835 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.354-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.322 0 196-87.662 196-196 0-108.322-87.662-196-196-196-79.545 0-147.941 47.282-178.675 115.302l126.389-3.009c6.737-.16 12.286 5.257 12.286 11.997V212c0 6.627-5.373 12-12 12H12c-6.627 0-12-5.373-12-12V20C0 13.373 5.373 8 12 8z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"undo-alt\": {\n    \"changes\": [\n      \"5.0.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"back\",\n        \"control z\",\n        \"exchange\",\n        \"oops\",\n        \"return\",\n        \"swap\"\n      ]\n    },\n    \"styles\": [\n      \"regular\",\n      \"solid\"\n    ],\n    \"unicode\": \"f2ea\",\n    \"label\": \"Alternate Undo\",\n    \"voted\": false,\n    \"svg\": {\n      \"regular\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M28.485 28.485L80.65 80.65C125.525 35.767 187.515 8 255.999 8 392.66 8 504.1 119.525 504 256.185 503.9 393.067 392.905 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.353-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.321 0 196-87.662 196-196 0-108.321-87.662-196-196-196-54.163 0-103.157 21.923-138.614 57.386l54.128 54.129c7.56 7.56 2.206 20.485-8.485 20.485H20c-6.627 0-12-5.373-12-12V36.971c0-10.691 12.926-16.045 20.485-8.486z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M28.485 28.485L80.65 80.65C125.525 35.767 187.515 8 255.999 8 392.66 8 504.1 119.525 504 256.185 503.9 393.067 392.905 504 256 504c-63.926 0-122.202-24.187-166.178-63.908-5.113-4.618-5.353-12.561-.482-17.433l19.738-19.738c4.498-4.498 11.753-4.785 16.501-.552C160.213 433.246 205.895 452 256 452c108.321 0 196-87.662 196-196 0-108.321-87.662-196-196-196-54.163 0-103.157 21.923-138.614 57.386l54.128 54.129c7.56 7.56 2.206 20.485-8.485 20.485H20c-6.627 0-12-5.373-12-12V36.971c0-10.691 12.926-16.045 20.485-8.486z\"\n      },\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><path d=\\\"M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": \"M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"university\": {\n    \"changes\": [\n      \"4.1\",\n      \"5.0.0\",\n      \"5.0.3\",\n      \"5.11.0\",\n      \"5.11.1\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"bank\",\n        \"building\",\n        \"college\",\n        \"higher education - students\",\n        \"institution\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f19c\",\n    \"label\": \"University\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 512 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M160,192V384h64V192h64V384h64V192h64V384h36a12,12,0,0,1,12,12v20H48V396a12,12,0,0,1,12-12H96V192Z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M491.06,120.61l-232-88a8,8,0,0,0-6.12,0l-232,88A8,8,0,0,0,16,128v16a8,8,0,0,0,8,8H48v12a12,12,0,0,0,12,12H452a12,12,0,0,0,12-12V152h24a8,8,0,0,0,8-8V128A8,8,0,0,0,491.06,120.61ZM472,432H40a24,24,0,0,0-24,24v16a8,8,0,0,0,8,8H488a8,8,0,0,0,8-8V456A24,24,0,0,0,472,432Z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"512\",\n          \"512\"\n        ],\n        \"width\": 512,\n        \"height\": 512,\n        \"path\": [\n          \"M160,192V384h64V192h64V384h64V192h64V384h36a12,12,0,0,1,12,12v20H48V396a12,12,0,0,1,12-12H96V192Z\",\n          \"M491.06,120.61l-232-88a8,8,0,0,0-6.12,0l-232,88A8,8,0,0,0,16,128v16a8,8,0,0,0,8,8H48v12a12,12,0,0,0,12,12H452a12,12,0,0,0,12-12V152h24a8,8,0,0,0,8-8V128A8,8,0,0,0,491.06,120.61ZM472,432H40a24,24,0,0,0-24,24v16a8,8,0,0,0,8,8H488a8,8,0,0,0,8-8V456A24,24,0,0,0,472,432Z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"user\": {\n    \"changes\": [\n      \"1\",\n      \"5.0.0\",\n      \"5.0.3\",\n      \"5.0.11\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"account\",\n        \"avatar\",\n        \"head\",\n        \"human\",\n        \"man\",\n        \"person\",\n        \"profile\"\n      ]\n    },\n    \"styles\": [\n      \"solid\",\n      \"duotone\",\n      \"regular\"\n    ],\n    \"unicode\": \"f007\",\n    \"label\": \"User\",\n    \"voted\": false,\n    \"svg\": {\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z\"\n      },\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M352 128A128 128 0 1 1 224 0a128 128 0 0 1 128 128z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M313.6 288h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48v-41.6A134.43 134.43 0 0 0 313.6 288z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": [\n          \"M352 128A128 128 0 1 1 224 0a128 128 0 0 1 128 128z\",\n          \"M313.6 288h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48v-41.6A134.43 134.43 0 0 0 313.6 288z\"\n        ]\n      },\n      \"regular\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><path d=\\\"M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": \"M313.6 304c-28.7 0-42.5 16-89.6 16-47.1 0-60.8-16-89.6-16C60.2 304 0 364.2 0 438.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-25.6c0-74.2-60.2-134.4-134.4-134.4zM400 464H48v-25.6c0-47.6 38.8-86.4 86.4-86.4 14.6 0 38.3 16 89.6 16 51.7 0 74.9-16 89.6-16 47.6 0 86.4 38.8 86.4 86.4V464zM224 288c79.5 0 144-64.5 144-144S303.5 0 224 0 80 64.5 80 144s64.5 144 144 144zm0-240c52.9 0 96 43.1 96 96s-43.1 96-96 96-96-43.1-96-96 43.1-96 96-96z\"\n      }\n    },\n    \"free\": [\n      \"solid\",\n      \"regular\"\n    ]\n  },\n  \"user-friends\": {\n    \"changes\": [\n      \"5.0.11\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"group\",\n        \"people\",\n        \"person\",\n        \"team\",\n        \"users\"\n      ]\n    },\n    \"styles\": [\n      \"regular\"\n    ],\n    \"unicode\": \"f500\",\n    \"label\": \"User Friends\",\n    \"voted\": false,\n    \"svg\": {\n      \"regular\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><path d=\\\"M480 256c53 0 96-43 96-96s-43-96-96-96-96 43-96 96 43 96 96 96zm0-144c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM272.1 276c-11.9 0-23.9 1.7-35.5 5.3-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-11.6-3.5-23.6-5.3-35.5-5.3-36.3 0-71.6 16.2-92.3 46.9C7.2 341.3 0 363.4 0 387.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM336 432H48v-44.8c0-28.9 18.4-53.6 44.1-63.1 10.3-3.8 21.6-3.7 31.9 0 22.1 7.9 45 11.9 68 11.9s45.8-4 68.1-11.9c10.3-3.7 21.6-3.8 31.9 0 25.7 9.4 44.1 34.2 44.1 63.1V432zM192 256c61.9 0 112-50.1 112-112S253.9 32 192 32 80 82.1 80 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm431.7 237.1C606.4 291.5 577 278 546.8 278c-27.8 0-34.8 10-66.8 10s-39-10-66.8-10c-13.3 0-26.2 3-38.2 8.1 5.8 5.9 11.3 12 16 18.9 4.7 7 8.6 14.4 12 22 3.3-.7 6.7-1.1 10.2-1.1 17.2 0 29.6 10 66.8 10 37.4 0 49.5-10 66.8-10 15.7 0 29.5 6.7 37.1 17.9 5.3 7.9 8.1 17.1 8.1 26.7V400H416v32c0 5.5-.6 10.8-1.6 16H600c22.1 0 40-17.9 40-40v-37.3c0-19.9-6-38.3-16.3-53.6z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": \"M480 256c53 0 96-43 96-96s-43-96-96-96-96 43-96 96 43 96 96 96zm0-144c26.5 0 48 21.5 48 48s-21.5 48-48 48-48-21.5-48-48 21.5-48 48-48zM272.1 276c-11.9 0-23.9 1.7-35.5 5.3-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-11.6-3.5-23.6-5.3-35.5-5.3-36.3 0-71.6 16.2-92.3 46.9C7.2 341.3 0 363.4 0 387.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c0-23.8-7.2-45.9-19.6-64.3-20.7-30.7-56-46.9-92.3-46.9zM336 432H48v-44.8c0-28.9 18.4-53.6 44.1-63.1 10.3-3.8 21.6-3.7 31.9 0 22.1 7.9 45 11.9 68 11.9s45.8-4 68.1-11.9c10.3-3.7 21.6-3.8 31.9 0 25.7 9.4 44.1 34.2 44.1 63.1V432zM192 256c61.9 0 112-50.1 112-112S253.9 32 192 32 80 82.1 80 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm431.7 237.1C606.4 291.5 577 278 546.8 278c-27.8 0-34.8 10-66.8 10s-39-10-66.8-10c-13.3 0-26.2 3-38.2 8.1 5.8 5.9 11.3 12 16 18.9 4.7 7 8.6 14.4 12 22 3.3-.7 6.7-1.1 10.2-1.1 17.2 0 29.6 10 66.8 10 37.4 0 49.5-10 66.8-10 15.7 0 29.5 6.7 37.1 17.9 5.3 7.9 8.1 17.1 8.1 26.7V400H416v32c0 5.5-.6 10.8-1.6 16H600c22.1 0 40-17.9 40-40v-37.3c0-19.9-6-38.3-16.3-53.6z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"user-hard-hat\": {\n    \"changes\": [\n      \"5.7.0\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"construction\",\n        \"hardhat\",\n        \"helmet\",\n        \"safety\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f82c\",\n    \"label\": \"Construction Worker\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 448 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M97.61 208h252.78c-7.95 63.06-61.17 112-126.39 112S105.56 271.06 97.61 208z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M313.6 352h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.4 134.4 0 0 0 0 486.4 25.6 25.6 0 0 0 25.6 512h396.8a25.6 25.6 0 0 0 25.6-25.6A134.4 134.4 0 0 0 313.6 352zM88 176h272a8 8 0 0 0 8-8v-32a8 8 0 0 0-8-8h-8a112 112 0 0 0-68.4-103.2L256 80V16a16 16 0 0 0-16-16h-32a16 16 0 0 0-16 16v64l-27.6-55.2A112 112 0 0 0 96 128h-8a8 8 0 0 0-8 8v32a8 8 0 0 0 8 8z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"448\",\n          \"512\"\n        ],\n        \"width\": 448,\n        \"height\": 512,\n        \"path\": [\n          \"M97.61 208h252.78c-7.95 63.06-61.17 112-126.39 112S105.56 271.06 97.61 208z\",\n          \"M313.6 352h-16.7a174.1 174.1 0 0 1-145.8 0h-16.7A134.4 134.4 0 0 0 0 486.4 25.6 25.6 0 0 0 25.6 512h396.8a25.6 25.6 0 0 0 25.6-25.6A134.4 134.4 0 0 0 313.6 352zM88 176h272a8 8 0 0 0 8-8v-32a8 8 0 0 0-8-8h-8a112 112 0 0 0-68.4-103.2L256 80V16a16 16 0 0 0-16-16h-32a16 16 0 0 0-16 16v64l-27.6-55.2A112 112 0 0 0 96 128h-8a8 8 0 0 0-8 8v32a8 8 0 0 0 8 8z\"\n        ]\n      }\n    },\n    \"free\": []\n  },\n  \"user-shield\": {\n    \"changes\": [\n      \"5.0.11\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"admin\",\n        \"person\",\n        \"private\",\n        \"protect\",\n        \"safe\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\"\n    ],\n    \"unicode\": \"f505\",\n    \"label\": \"User Shield\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M622.3 271.1l-115.2-45a31 31 0 0 0-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9a31 31 0 0 0 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M224 256A128 128 0 1 0 96 128a128 128 0 0 0 128 128zm96 40c0-2.5.8-4.8 1.1-7.2-2.5-.1-4.9-.8-7.5-.8h-16.7a174.08 174.08 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a49.22 49.22 0 0 0 19.2-4c-54-42.9-99.2-116.7-99.2-212z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M622.3 271.1l-115.2-45a31 31 0 0 0-22.2 0l-115.2 45c-10.7 4.2-17.7 14-17.7 24.9 0 111.6 68.7 188.8 132.9 213.9a31 31 0 0 0 22.2 0C558.4 489.9 640 420.5 640 296c0-10.9-7-20.7-17.7-24.9zM496 462.4V273.3l95.5 37.3c-5.6 87.1-60.9 135.4-95.5 151.8z\",\n          \"M224 256A128 128 0 1 0 96 128a128 128 0 0 0 128 128zm96 40c0-2.5.8-4.8 1.1-7.2-2.5-.1-4.9-.8-7.5-.8h-16.7a174.08 174.08 0 0 1-145.8 0h-16.7A134.43 134.43 0 0 0 0 422.4V464a48 48 0 0 0 48 48h352a49.22 49.22 0 0 0 19.2-4c-54-42.9-99.2-116.7-99.2-212z\"\n        ]\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  },\n  \"users\": {\n    \"changes\": [\n      \"2\",\n      \"5.0.0\",\n      \"5.0.3\",\n      \"5.0.11\"\n    ],\n    \"ligatures\": [],\n    \"search\": {\n      \"terms\": [\n        \"friends\",\n        \"group\",\n        \"people\",\n        \"persons\",\n        \"profiles\",\n        \"team\"\n      ]\n    },\n    \"styles\": [\n      \"duotone\",\n      \"solid\",\n      \"regular\"\n    ],\n    \"unicode\": \"f0c0\",\n    \"label\": \"Users\",\n    \"voted\": false,\n    \"svg\": {\n      \"duotone\": {\n        \"last_modified\": 1628277664000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><defs><style>.fa-secondary{opacity:.4}</style></defs><path d=\\\"M96 224a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64zm480 32h-64a63.81 63.81 0 0 0-45.1 18.6A146.27 146.27 0 0 1 542 384h66a32 32 0 0 0 32-32v-32a64.06 64.06 0 0 0-64-64zm-512 0a64.06 64.06 0 0 0-64 64v32a32 32 0 0 0 32 32h65.9a146.64 146.64 0 0 1 75.2-109.4A63.81 63.81 0 0 0 128 256zm480-32a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64z\\\" class=\\\"fa-secondary\\\"/><path d=\\\"M396.8 288h-8.3a157.53 157.53 0 0 1-68.5 16c-24.6 0-47.6-6-68.5-16h-8.3A115.23 115.23 0 0 0 128 403.2V432a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48v-28.8A115.23 115.23 0 0 0 396.8 288zM320 256a112 112 0 1 0-112-112 111.94 111.94 0 0 0 112 112z\\\" class=\\\"fa-primary\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": [\n          \"M96 224a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64zm480 32h-64a63.81 63.81 0 0 0-45.1 18.6A146.27 146.27 0 0 1 542 384h66a32 32 0 0 0 32-32v-32a64.06 64.06 0 0 0-64-64zm-512 0a64.06 64.06 0 0 0-64 64v32a32 32 0 0 0 32 32h65.9a146.64 146.64 0 0 1 75.2-109.4A63.81 63.81 0 0 0 128 256zm480-32a64 64 0 1 0-64-64 64.06 64.06 0 0 0 64 64z\",\n          \"M396.8 288h-8.3a157.53 157.53 0 0 1-68.5 16c-24.6 0-47.6-6-68.5-16h-8.3A115.23 115.23 0 0 0 128 403.2V432a48 48 0 0 0 48 48h288a48 48 0 0 0 48-48v-28.8A115.23 115.23 0 0 0 396.8 288zM320 256a112 112 0 1 0-112-112 111.94 111.94 0 0 0 112 112z\"\n        ]\n      },\n      \"solid\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><path d=\\\"M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": \"M96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3C179.6 288 128 339.6 128 403.2V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4C161.5 263.1 145.6 256 128 256H64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z\"\n      },\n      \"regular\": {\n        \"last_modified\": 1628277666000,\n        \"raw\": \"<svg xmlns=\\\"http://www.w3.org/2000/svg\\\" viewBox=\\\"0 0 640 512\\\"><path d=\\\"M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zm396.4 210.9c-27.5-40.8-80.7-56-127.8-41.7-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-47.1-14.3-100.3.8-127.8 41.7-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c.2-23.8-7-45.9-19.4-64.3zM464 432H176v-44.8c0-36.4 29.2-66.2 65.4-67.2 25.5 10.6 51.9 16 78.6 16 26.7 0 53.1-5.4 78.6-16 36.2 1 65.4 30.7 65.4 67.2V432zm92-176h-24c-17.3 0-33.4 5.3-46.8 14.3 13.4 10.1 25.2 22.2 34.4 36.2 3.9-1.4 8-2.5 12.3-2.5h24c19.8 0 36 16.2 36 36 0 13.2 10.8 24 24 24s24-10.8 24-24c.1-46.3-37.6-84-83.9-84zm-236 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM154.8 270.3c-13.4-9-29.5-14.3-46.8-14.3H84c-46.3 0-84 37.7-84 84 0 13.2 10.8 24 24 24s24-10.8 24-24c0-19.8 16.2-36 36-36h24c4.4 0 8.5 1.1 12.3 2.5 9.3-14 21.1-26.1 34.5-36.2z\\\"/></svg>\",\n        \"viewBox\": [\n          \"0\",\n          \"0\",\n          \"640\",\n          \"512\"\n        ],\n        \"width\": 640,\n        \"height\": 512,\n        \"path\": \"M544 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zM96 224c44.2 0 80-35.8 80-80s-35.8-80-80-80-80 35.8-80 80 35.8 80 80 80zm0-112c17.6 0 32 14.4 32 32s-14.4 32-32 32-32-14.4-32-32 14.4-32 32-32zm396.4 210.9c-27.5-40.8-80.7-56-127.8-41.7-14.2 4.3-29.1 6.7-44.7 6.7s-30.5-2.4-44.7-6.7c-47.1-14.3-100.3.8-127.8 41.7-12.4 18.4-19.6 40.5-19.6 64.3V432c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-44.8c.2-23.8-7-45.9-19.4-64.3zM464 432H176v-44.8c0-36.4 29.2-66.2 65.4-67.2 25.5 10.6 51.9 16 78.6 16 26.7 0 53.1-5.4 78.6-16 36.2 1 65.4 30.7 65.4 67.2V432zm92-176h-24c-17.3 0-33.4 5.3-46.8 14.3 13.4 10.1 25.2 22.2 34.4 36.2 3.9-1.4 8-2.5 12.3-2.5h24c19.8 0 36 16.2 36 36 0 13.2 10.8 24 24 24s24-10.8 24-24c.1-46.3-37.6-84-83.9-84zm-236 0c61.9 0 112-50.1 112-112S381.9 32 320 32 208 82.1 208 144s50.1 112 112 112zm0-176c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zM154.8 270.3c-13.4-9-29.5-14.3-46.8-14.3H84c-46.3 0-84 37.7-84 84 0 13.2 10.8 24 24 24s24-10.8 24-24c0-19.8 16.2-36 36-36h24c4.4 0 8.5 1.1 12.3 2.5 9.3-14 21.1-26.1 34.5-36.2z\"\n      }\n    },\n    \"free\": [\n      \"solid\"\n    ]\n  }\n}"
  },
  {
    "path": "public/fonts/font-awesome/metadata/icons.yml",
    "content": "abacus:\n  changes:\n    - 5.3.0\n  label: Abacus\n  search:\n    terms:\n      - addition\n      - ancient\n      - arithmetic\n      - calculator\n      - counting\n      - hexadecimal\n      - math\n      - subtraction\n  styles:\n    - duotone\n  unicode: f640\n  voted: false\nalarm-exclamation:\n  changes:\n    - 5.9.0\n  label: Alarm Exclamation\n  search:\n    terms:\n      - alert\n      - date\n      - late\n      - reminder\n      - sleep\n      - snooze\n      - timer\n      - timestamp\n      - watch\n  styles:\n    - solid\n  unicode: f843\n  voted: false\nalign-left:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.9.0\n  label: align-left\n  search:\n    terms:\n      - format\n      - paragraph\n      - text\n  styles:\n    - solid\n  unicode: f036\n  voted: false\nalign-slash:\n  changes:\n    - 5.9.0\n  label: Align Slash\n  search:\n    terms:\n      - cancel\n      - format\n      - paragraph\n      - remove\n  styles:\n    - duotone\n  unicode: f846\n  voted: false\natom-alt:\n  changes:\n    - 5.2.0\n    - 5.12.0\n  label: Atom Alt\n  search:\n    terms:\n      - atheism\n      - chemistry\n      - electron\n      - ion\n      - isotope\n      - neutron\n      - nuclear\n      - proton\n      - science\n      - space\n  styles:\n    - duotone\n  unicode: f5d3\n  voted: false\naws:\n  changes:\n    - 5.0.0\n    - 5.1.0\n  label: Amazon Web Services (AWS)\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f375\n  voted: false\nbadge-check:\n  changes:\n    - 5.0.0\n  label: Check Badge\n  search:\n    terms:\n      - accept\n      - achievement\n      - agree\n      - award\n      - confirm\n      - correct\n      - done\n      - ok\n      - security\n      - select\n      - success\n      - verified\n      - verify\n      - winner\n      - 'yes'\n  styles:\n    - duotone\n  unicode: f336\n  voted: false\nbell:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.2.0\n    - 5.11.0\n  label: bell\n  search:\n    terms:\n      - alarm\n      - alert\n      - chime\n      - notification\n      - reminder\n  styles:\n    - duotone\n  unicode: f0f3\n  voted: false\nbook-dead:\n  changes:\n    - 5.4.0\n  label: Book of the Dead\n  search:\n    terms:\n      - Dungeons & Dragons\n      - crossbones\n      - d&d\n      - dark arts\n      - death\n      - dnd\n      - documentation\n      - evil\n      - fantasy\n      - halloween\n      - holiday\n      - necronomicon\n      - read\n      - skull\n      - spell\n  styles:\n    - solid\n  unicode: f6b7\n  voted: false\nbooks:\n  changes:\n    - 5.2.0\n    - 5.10.1\n  label: Books\n  search:\n    terms:\n      - diary\n      - documentation\n      - journal\n      - library\n      - read\n  styles:\n    - duotone\n  unicode: f5db\n  voted: false\nbrackets-curly:\n  changes:\n    - 5.7.0\n  label: Curly Brackets\n  search:\n    terms:\n      - code\n      - developer\n      - development\n      - parentheses\n  styles:\n    - duotone\n  unicode: f7ea\n  voted: true\ncc-amazon-pay:\n  changes:\n    - 5.0.2\n  label: Amazon Pay Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f42d\n  voted: false\ncc-amex:\n  changes:\n    - '4.2'\n    - 5.0.0\n    - 5.7.0\n  label: American Express Credit Card\n  search:\n    terms:\n      - amex\n  styles:\n    - brands\n  unicode: f1f3\n  voted: false\ncc-apple-pay:\n  changes:\n    - 5.0.0\n  label: Apple Pay Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f416\n  voted: false\ncc-diners-club:\n  changes:\n    - '4.4'\n    - 5.0.0\n  label: Diner's Club Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f24c\n  voted: false\ncc-discover:\n  changes:\n    - '4.2'\n    - 5.0.0\n  label: Discover Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f1f2\n  voted: false\ncc-jcb:\n  changes:\n    - '4.4'\n    - 5.0.0\n  label: JCB Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f24b\n  voted: false\ncc-mastercard:\n  changes:\n    - '4.2'\n    - 5.0.0\n  label: MasterCard Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f1f1\n  voted: false\ncc-paypal:\n  changes:\n    - '4.2'\n    - 5.0.0\n  label: Paypal Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f1f4\n  voted: false\ncc-stripe:\n  changes:\n    - '4.2'\n    - 5.0.0\n  label: Stripe Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f1f5\n  voted: false\ncc-visa:\n  changes:\n    - '4.2'\n    - 5.0.0\n  label: Visa Credit Card\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f1f0\n  voted: false\nchart-network:\n  changes:\n    - 5.6.0\n  label: Network Chart\n  search:\n    terms:\n      - activity\n      - analytics\n      - association\n      - dashboard\n      - diagram\n      - distribution\n      - map\n      - network\n  styles:\n    - duotone\n  unicode: f78a\n  voted: true\nchart-scatter:\n  changes:\n    - 5.7.0\n  label: Scatter Chart\n  search:\n    terms:\n      - analytics\n      - chart\n      - diagram\n      - graph\n      - plot\n  styles:\n    - duotone\n  unicode: f7ee\n  voted: true\ncheck:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Check\n  search:\n    terms:\n      - accept\n      - agree\n      - checkmark\n      - confirm\n      - correct\n      - done\n      - notice\n      - notification\n      - notify\n      - ok\n      - select\n      - success\n      - tick\n      - todo\n      - 'yes'\n  styles:\n    - duotone\n    - solid\n  unicode: f00c\n  voted: false\ncheck-circle:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Check Circle\n  search:\n    terms:\n      - accept\n      - agree\n      - confirm\n      - correct\n      - done\n      - ok\n      - select\n      - success\n      - tick\n      - todo\n      - 'yes'\n  styles:\n    - regular\n  unicode: f058\n  voted: false\ncircle:\n  changes:\n    - '3'\n    - 5.0.0\n    - 5.10.1\n    - 5.10.2\n  label: Circle\n  search:\n    terms:\n      - circle-thin\n      - diameter\n      - dot\n      - ellipse\n      - notification\n      - round\n  styles:\n    - duotone\n    - solid\n  unicode: f111\n  voted: false\ncloud:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.0.11\n  label: Cloud\n  search:\n    terms:\n      - atmosphere\n      - fog\n      - overcast\n      - save\n      - upload\n      - weather\n  styles:\n    - solid\n  unicode: f0c2\n  voted: false\nclouds:\n  changes:\n    - 5.5.0\n  label: Clouds\n  search:\n    terms:\n      - cloudy\n      - fog\n      - haze\n      - overcast\n      - smoke\n      - storm\n      - weather\n  styles:\n    - duotone\n  unicode: f744\n  voted: false\ncogs:\n  changes:\n    - '1'\n    - 5.0.0\n  label: cogs\n  search:\n    terms:\n      - gears\n      - mechanical\n      - settings\n      - sprocket\n      - wheel\n  styles:\n    - duotone\n  unicode: f085\n  voted: false\ncomment-dots:\n  changes:\n    - 5.0.9\n  label: Comment Dots\n  search:\n    terms:\n      - bubble\n      - chat\n      - commenting\n      - conversation\n      - feedback\n      - message\n      - more\n      - note\n      - notification\n      - reply\n      - sms\n      - speech\n      - texting\n  styles:\n    - duotone\n  unicode: f4ad\n  voted: false\nconcierge-bell:\n  changes:\n    - 5.1.0\n  label: Concierge Bell\n  search:\n    terms:\n      - attention\n      - hotel\n      - receptionist\n      - service\n      - support\n  styles:\n    - duotone\n  unicode: f562\n  voted: false\ncredit-card:\n  changes:\n    - '2'\n    - 5.0.0\n  label: Credit Card\n  search:\n    terms:\n      - buy\n      - checkout\n      - credit-card-alt\n      - debit\n      - money\n      - payment\n      - purchase\n  styles:\n    - solid\n  unicode: f09d\n  voted: false\ndesktop:\n  changes:\n    - '3'\n    - 5.0.0\n  label: Desktop\n  search:\n    terms:\n      - computer\n      - cpu\n      - demo\n      - desktop\n      - device\n      - imac\n      - machine\n      - monitor\n      - pc\n      - screen\n  styles:\n    - solid\n    - regular\n  unicode: f108\n  voted: false\ndiscourse:\n  changes:\n    - 5.0.0\n    - 5.0.3\n  label: Discourse\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f393\n  voted: false\ndocker:\n  changes:\n    - 5.0.0\n  label: Docker\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f395\n  voted: false\ndot-circle:\n  changes:\n    - '4'\n    - 5.0.0\n  label: Dot Circle\n  search:\n    terms:\n      - bullseye\n      - notification\n      - target\n  styles:\n    - duotone\n  unicode: f192\n  voted: false\nenvelope:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.10.1\n    - 5.10.2\n  label: Envelope\n  search:\n    terms:\n      - e-mail\n      - email\n      - letter\n      - mail\n      - message\n      - notification\n      - support\n  styles:\n    - solid\n    - duotone\n  unicode: f0e0\n  voted: false\nexchange-alt:\n  changes:\n    - 5.0.0\n  label: Alternate Exchange\n  search:\n    terms:\n      - arrow\n      - arrows\n      - exchange\n      - reciprocate\n      - return\n      - swap\n      - transfer\n  styles:\n    - duotone\n  unicode: f362\n  voted: false\neye:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.7.0\n  label: Eye\n  search:\n    terms:\n      - look\n      - optic\n      - see\n      - seen\n      - show\n      - sight\n      - views\n      - visible\n  styles:\n    - solid\n    - regular\n  unicode: f06e\n  voted: false\nfile-alt:\n  changes:\n    - '3.2'\n    - 5.0.0\n    - 5.10.2\n  label: Alternate File\n  search:\n    terms:\n      - document\n      - file-text\n      - invoice\n      - new\n      - page\n      - pdf\n  styles:\n    - duotone\n  unicode: f15c\n  voted: false\nfile-code:\n  changes:\n    - '4.1'\n    - 5.0.0\n    - 5.10.2\n  label: Code File\n  search:\n    terms:\n      - css\n      - development\n      - document\n      - html\n  styles:\n    - duotone\n    - regular\n  unicode: f1c9\n  voted: false\nfingerprint:\n  changes:\n    - 5.1.0\n  label: Fingerprint\n  search:\n    terms:\n      - human\n      - id\n      - identification\n      - lock\n      - smudge\n      - touch\n      - unique\n      - unlock\n  styles:\n    - solid\n  unicode: f577\n  voted: true\ngithub:\n  changes:\n    - '2'\n    - 5.0.0\n  label: GitHub\n  search:\n    terms:\n      - octocat\n  styles:\n    - brands\n  unicode: f09b\n  voted: false\nglobe:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.0.9\n    - 5.11.0\n    - 5.11.1\n  label: Globe\n  search:\n    terms:\n      - all\n      - coordinates\n      - country\n      - earth\n      - global\n      - gps\n      - language\n      - localize\n      - location\n      - map\n      - online\n      - place\n      - planet\n      - translate\n      - travel\n      - world\n  styles:\n    - duotone\n  unicode: f0ac\n  voted: false\nglobe-africa:\n  changes:\n    - 5.1.0\n    - 5.11.0\n    - 5.11.1\n  label: Globe with Africa shown\n  search:\n    terms:\n      - all\n      - country\n      - earth\n      - global\n      - gps\n      - language\n      - localize\n      - location\n      - map\n      - online\n      - place\n      - planet\n      - translate\n      - travel\n      - world\n  styles:\n    - duotone\n  unicode: f57c\n  voted: false\nglobe-americas:\n  changes:\n    - 5.1.0\n    - 5.11.0\n    - 5.11.1\n  label: Globe with Americas shown\n  search:\n    terms:\n      - all\n      - country\n      - earth\n      - global\n      - gps\n      - language\n      - localize\n      - location\n      - map\n      - online\n      - place\n      - planet\n      - translate\n      - travel\n      - world\n  styles:\n    - duotone\n  unicode: f57d\n  voted: false\nglobe-asia:\n  changes:\n    - 5.1.0\n    - 5.11.0\n    - 5.11.1\n  label: Globe with Asia shown\n  search:\n    terms:\n      - all\n      - country\n      - earth\n      - global\n      - gps\n      - language\n      - localize\n      - location\n      - map\n      - online\n      - place\n      - planet\n      - translate\n      - travel\n      - world\n  styles:\n    - duotone\n  unicode: f57e\n  voted: false\nglobe-europe:\n  changes:\n    - 5.6.0\n    - 5.11.0\n    - 5.11.1\n  label: Globe with Europe shown\n  search:\n    terms:\n      - all\n      - country\n      - earth\n      - global\n      - gps\n      - language\n      - localize\n      - location\n      - map\n      - online\n      - place\n      - planet\n      - translate\n      - travel\n      - world\n  styles:\n    - duotone\n  unicode: f7a2\n  voted: true\ngraduation-cap:\n  changes:\n    - '4.1'\n    - 5.0.0\n    - 5.2.0\n    - 5.10.1\n  label: Graduation Cap\n  search:\n    terms:\n      - ceremony\n      - college\n      - graduate\n      - learning\n      - school\n      - student\n  styles:\n    - duotone\n  unicode: f19d\n  voted: false\nhistory:\n  changes:\n    - '4.1'\n    - 5.0.0\n  label: History\n  search:\n    terms:\n      - Rewind\n      - clock\n      - reverse\n      - time\n      - time machine\n  styles:\n    - solid\n    - duotone\n  unicode: f1da\n  voted: false\nhome:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.7.0\n  label: home\n  search:\n    terms:\n      - abode\n      - building\n      - house\n      - main\n  styles:\n    - solid\n  unicode: f015\n  voted: false\ninfo:\n  changes:\n    - '3.1'\n    - 5.0.0\n    - 5.10.1\n    - 5.10.2\n  label: Info\n  search:\n    terms:\n      - details\n      - help\n      - information\n      - more\n      - support\n  styles:\n    - regular\n  unicode: f129\n  voted: false\ninfo-circle:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Info Circle\n  search:\n    terms:\n      - details\n      - help\n      - information\n      - more\n      - support\n  styles:\n    - regular\n  unicode: f05a\n  voted: false\ninstagram:\n  changes:\n    - '4.6'\n    - 5.0.0\n  label: Instagram\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f16d\n  voted: false\nkey:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.10.1\n  label: key\n  search:\n    terms:\n      - lock\n      - password\n      - private\n      - secret\n      - unlock\n  styles:\n    - duotone\n  unicode: f084\n  voted: false\nkey-skeleton:\n  changes:\n    - 5.4.0\n  label: Key Skeleton\n  search:\n    terms:\n      - halloween\n      - lock\n      - password\n      - private\n      - secret\n      - unlock\n  styles:\n    - duotone\n  unicode: f6f3\n  voted: false\nlaptop:\n  changes:\n    - '3'\n    - 5.0.0\n    - 5.2.0\n  label: Laptop\n  search:\n    terms:\n      - computer\n      - cpu\n      - dell\n      - demo\n      - device\n      - mac\n      - macbook\n      - machine\n      - pc\n  styles:\n    - duotone\n  unicode: f109\n  voted: false\nlaptop-code:\n  changes:\n    - 5.2.0\n  label: Laptop Code\n  search:\n    terms:\n      - computer\n      - cpu\n      - dell\n      - demo\n      - develop\n      - device\n      - mac\n      - macbook\n      - machine\n      - pc\n  styles:\n    - duotone\n  unicode: f5fc\n  voted: false\nlaptop-house:\n  changes:\n    - 5.13.0\n    - 5.14.0\n  label: Laptop House\n  search:\n    terms:\n      - computer\n      - covid-19\n      - device\n      - office\n      - remote\n      - work from home\n  styles:\n    - duotone\n  unicode: e066\n  voted: false\nlife-ring:\n  changes:\n    - '4.1'\n    - 5.0.0\n  label: Life Ring\n  search:\n    terms:\n      - coast guard\n      - help\n      - overboard\n      - save\n      - support\n  styles:\n    - duotone\n  unicode: f1cd\n  voted: false\nlightbulb:\n  changes:\n    - '3'\n    - 5.0.0\n    - 5.3.0\n  label: Lightbulb\n  search:\n    terms:\n      - energy\n      - idea\n      - inspiration\n      - light\n  styles:\n    - duotone\n  unicode: f0eb\n  voted: false\nlist-alt:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Alternate List\n  search:\n    terms:\n      - checklist\n      - completed\n      - done\n      - finished\n      - ol\n      - todo\n      - ul\n  styles:\n    - duotone\n  unicode: f022\n  voted: false\nlist-ul:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.9.0\n  label: list-ul\n  search:\n    terms:\n      - checklist\n      - completed\n      - done\n      - finished\n      - ol\n      - todo\n      - ul\n  styles:\n    - duotone\n  unicode: f0ca\n  voted: false\nlock-alt:\n  changes:\n    - 5.0.0\n  label: Alternate Lock\n  search:\n    terms:\n      - admin\n      - lock\n      - open\n      - password\n      - private\n      - protect\n      - security\n  styles:\n    - duotone\n  unicode: f30d\n  voted: false\nmap-marker-alt:\n  changes:\n    - 5.0.0\n  label: Alternate Map Marker\n  search:\n    terms:\n      - address\n      - coordinates\n      - destination\n      - gps\n      - localize\n      - location\n      - map\n      - navigation\n      - paper\n      - pin\n      - place\n      - point of interest\n      - position\n      - route\n      - travel\n  styles:\n    - duotone\n  unicode: f3c5\n  voted: false\nmicrosoft:\n  changes:\n    - 5.0.0\n  label: Microsoft\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f3ca\n  voted: true\nmoon-stars:\n  changes:\n    - 5.5.0\n  label: Moon with Stars\n  search:\n    terms:\n      - clear\n      - crescent\n      - lunar\n      - space\n      - star\n  styles:\n    - duotone\n  unicode: f755\n  voted: false\nnetwork-wired:\n  changes:\n    - 5.4.0\n  label: Wired Network\n  search:\n    terms:\n      - computer\n      - connect\n      - ethernet\n      - internet\n      - intranet\n  styles:\n    - duotone\n  unicode: f6ff\n  voted: true\nplanet-ringed:\n  changes:\n    - 5.12.0\n    - 5.14.0\n  label: Ringed Planet\n  search:\n    terms:\n      - orbit\n      - saturn\n      - solar system\n      - space\n      - universe\n  styles:\n    - duotone\n  unicode: e020\n  voted: false\nplus:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.0.13\n  label: plus\n  search:\n    terms:\n      - add\n      - create\n      - expand\n      - new\n      - positive\n      - shape\n  styles:\n    - regular\n    - solid\n  unicode: f067\n  voted: false\nquestion-circle:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Question Circle\n  search:\n    terms:\n      - help\n      - information\n      - support\n      - unknown\n  styles:\n    - duotone\n    - regular\n  unicode: f059\n  voted: false\nquote-left:\n  changes:\n    - '3'\n    - 5.0.0\n    - 5.0.9\n  label: quote-left\n  search:\n    terms:\n      - mention\n      - note\n      - phrase\n      - text\n      - type\n  styles:\n    - duotone\n  unicode: f10d\n  voted: false\nrandom:\n  changes:\n    - '1'\n    - 5.0.0\n  label: random\n  search:\n    terms:\n      - arrows\n      - shuffle\n      - sort\n      - swap\n      - switch\n      - transfer\n  styles:\n    - duotone\n  unicode: f074\n  voted: false\nrev:\n  changes:\n    - 5.1.0\n    - 5.1.1\n    - 5.8.0\n  label: Rev.io\n  search:\n    terms: []\n  styles:\n    - brands\n  unicode: f5b2\n  voted: false\nrobot:\n  changes:\n    - 5.0.13\n    - 5.12.0\n  label: Robot\n  search:\n    terms:\n      - android\n      - automate\n      - computer\n      - cyborg\n  styles:\n    - solid\n  unicode: f544\n  voted: true\nrocket:\n  changes:\n    - '3.1'\n    - 5.0.0\n    - 5.7.0\n    - 5.12.0\n  label: rocket\n  search:\n    terms:\n      - aircraft\n      - app\n      - jet\n      - launch\n      - nasa\n      - space\n  styles:\n    - duotone\n    - solid\n    - regular\n  unicode: f135\n  voted: false\nsave:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.10.2\n  label: Save\n  search:\n    terms:\n      - disk\n      - download\n      - floppy\n      - floppy-o\n  styles:\n    - solid\n    - regular\n  unicode: f0c7\n  voted: false\nsearch:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Search\n  search:\n    terms:\n      - bigger\n      - enlarge\n      - find\n      - magnify\n      - preview\n      - zoom\n  styles:\n    - duotone\n  unicode: f002\n  voted: false\nserver:\n  changes:\n    - '4.3'\n    - 5.0.0\n  label: Server\n  search:\n    terms:\n      - computer\n      - cpu\n      - database\n      - hardware\n      - network\n  styles:\n    - duotone\n  unicode: f233\n  voted: false\nsign-out:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Sign Out\n  search:\n    terms:\n      - arrow\n      - exit\n      - leave\n      - log out\n      - logout\n  styles:\n    - duotone\n  unicode: f08b\n  voted: false\nsiren-on:\n  changes:\n    - 5.12.0\n    - 5.14.0\n  label: Siren On\n  search:\n    terms:\n      - alarm\n      - alert\n      - ambulance\n      - loud\n      - police\n      - warning\n  styles:\n    - duotone\n  unicode: e02e\n  voted: false\nslack:\n  changes:\n    - '4.1'\n    - 5.0.0\n    - 5.7.0\n  label: Slack Logo\n  search:\n    terms:\n      - anchor\n      - hash\n      - hashtag\n  styles:\n    - brands\n  unicode: f198\n  voted: false\nslash:\n  changes:\n    - 5.4.0\n  label: Slash\n  search:\n    terms:\n      - cancel\n      - close\n      - mute\n      - 'off'\n      - stop\n      - x\n  styles:\n    - solid\n    - regular\n  unicode: f715\n  voted: true\nsmile:\n  changes:\n    - '3.1'\n    - 5.0.0\n    - 5.0.9\n    - 5.1.0\n    - 5.11.0\n    - 5.11.1\n  label: Smiling Face\n  search:\n    terms:\n      - approve\n      - emoticon\n      - face\n      - happy\n      - rating\n      - satisfied\n  styles:\n    - duotone\n  unicode: f118\n  voted: false\nsnowman:\n  changes:\n    - 5.6.0\n  label: Snowman\n  search:\n    terms:\n      - decoration\n      - frost\n      - frosty\n      - holiday\n  styles:\n    - duotone\n  unicode: f7d0\nspinner-third:\n  changes:\n    - 5.0.0\n    - 5.10.2\n  label: Spinner Third\n  search:\n    terms:\n      - circle\n      - loading\n      - progress\n  styles:\n    - solid\n  unicode: f3f4\n  voted: false\nsquare-full:\n  changes:\n    - 5.0.5\n    - 5.10.2\n  label: Square Full\n  search:\n    terms:\n      - block\n      - box\n      - shape\n  styles:\n    - solid\n  unicode: f45c\n  voted: false\nsun:\n  changes:\n    - '3.2'\n    - 5.0.0\n    - 5.5.0\n  label: Sun\n  search:\n    terms:\n      - brighten\n      - contrast\n      - day\n      - lighter\n      - sol\n      - solar\n      - star\n      - weather\n  styles:\n    - duotone\n  unicode: f185\n  voted: false\ntasks:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.9.0\n  label: Tasks\n  search:\n    terms:\n      - checklist\n      - downloading\n      - downloads\n      - loading\n      - progress\n      - project management\n      - settings\n      - to do\n  styles:\n    - duotone\n  unicode: f0ae\n  voted: false\ntimes:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.0.13\n    - 5.11.0\n    - 5.11.1\n  label: Times\n  search:\n    terms:\n      - close\n      - cross\n      - error\n      - exit\n      - incorrect\n      - notice\n      - notification\n      - notify\n      - problem\n      - wrong\n      - x\n  styles:\n    - solid\n    - regular\n  unicode: f00d\n  voted: false\ntimes-circle:\n  changes:\n    - '1'\n    - 5.0.0\n  label: Times Circle\n  search:\n    terms:\n      - close\n      - cross\n      - exit\n      - incorrect\n      - notice\n      - notification\n      - notify\n      - problem\n      - wrong\n      - x\n  styles:\n    - solid\n  unicode: f057\n  voted: false\ntwitter:\n  changes:\n    - '2'\n    - 5.0.0\n  label: Twitter\n  search:\n    terms:\n      - social network\n      - tweet\n  styles:\n    - brands\n  unicode: f099\n  voted: false\nundo:\n  changes:\n    - '2'\n    - 5.0.0\n  label: Undo\n  search:\n    terms:\n      - back\n      - control z\n      - exchange\n      - oops\n      - return\n      - rotate\n      - swap\n  styles:\n    - solid\n    - regular\n  unicode: f0e2\n  voted: false\nundo-alt:\n  changes:\n    - 5.0.0\n  label: Alternate Undo\n  search:\n    terms:\n      - back\n      - control z\n      - exchange\n      - oops\n      - return\n      - swap\n  styles:\n    - regular\n    - solid\n  unicode: f2ea\n  voted: false\nuniversity:\n  changes:\n    - '4.1'\n    - 5.0.0\n    - 5.0.3\n    - 5.11.0\n    - 5.11.1\n  label: University\n  search:\n    terms:\n      - bank\n      - building\n      - college\n      - higher education - students\n      - institution\n  styles:\n    - duotone\n  unicode: f19c\n  voted: false\nuser:\n  changes:\n    - '1'\n    - 5.0.0\n    - 5.0.3\n    - 5.0.11\n  label: User\n  search:\n    terms:\n      - account\n      - avatar\n      - head\n      - human\n      - man\n      - person\n      - profile\n  styles:\n    - solid\n    - duotone\n    - regular\n  unicode: f007\n  voted: false\nuser-friends:\n  changes:\n    - 5.0.11\n  label: User Friends\n  search:\n    terms:\n      - group\n      - people\n      - person\n      - team\n      - users\n  styles:\n    - regular\n  unicode: f500\n  voted: false\nuser-hard-hat:\n  changes:\n    - 5.7.0\n  label: Construction Worker\n  search:\n    terms:\n      - construction\n      - hardhat\n      - helmet\n      - safety\n  styles:\n    - duotone\n  unicode: f82c\n  voted: false\nuser-shield:\n  changes:\n    - 5.0.11\n  label: User Shield\n  search:\n    terms:\n      - admin\n      - person\n      - private\n      - protect\n      - safe\n  styles:\n    - duotone\n  unicode: f505\n  voted: false\nusers:\n  changes:\n    - '2'\n    - 5.0.0\n    - 5.0.3\n    - 5.0.11\n  label: Users\n  search:\n    terms:\n      - friends\n      - group\n      - people\n      - persons\n      - profiles\n      - team\n  styles:\n    - duotone\n    - solid\n    - regular\n  unicode: f0c0\n  voted: false\n"
  },
  {
    "path": "public/fonts/font-awesome/metadata/sponsors.yml",
    "content": "amazon-web-services:\n  icons:\n    - aws\n  label: Amazon Web Services\n  url: 'https://aws.amazon.com'\ndiscourse:\n  icons:\n    - discourse\n  label: Discourse\n  url: 'https://discourse.org'\nharvard-medical-school:\n  icons:\n    - plus\n  label: Harvard Medical School\n  url: 'https://hms.harvard.edu'\nmylogin-info:\n  icons:\n    - user-shield\n  label: mylogin.info\n  url: 'https://www.mylogin.info'\nrev-io:\n  icons:\n    - rev\n  label: Rev.io\n  url: 'https://rev.io'\nrocket-chat:\n  icons:\n    - comment-dots\n    - quote-left\n    - smile\n  label: Rocket.Chat\n  url: 'https://rocket.chat'\nsupple:\n  icons:\n    - badge-check\n  label: Supple\n  url: 'https://supple.com.au'\nthe-us-sunnah-foundation:\n  icons:\n    - globe\n  label: The us-Sunnah Foundation\n  url: 'https://www.ussunnah.org'\n"
  },
  {
    "path": "public/fonts/font-awesome/otfs/README.md",
    "content": "A HEADS UP ABOUT DUOTONE ICONS ON THE DESKTOP\n---------------------------------------------\n\nDuotone icons are a bit different to use than other Font Awesome icons at the moment.\n\n* We currently recommend using the Duotone-specific optimized .svg vector\n  files. These can be found in the /svgs/duotone folder of this download.\n\n* Using Ligatures with Duotone Icons is NOT currently recommended - while we've\n  included a Duotone ligature-based font file in our Pro desktop download, we\n  can't recommend it as a way to use our icons on the desktop. Read the special\n  instructions for using duotones with ligatures here -\n  https://fontawesome.com/how-to-use/on-the-desktop/referencing-icons/duotone-icons#using-ligatures.\n\nYou can read the nitty gritty on the current limitations desktop apps have that\nmade our Duotone ligature implementation diferent there as well. And our full\nDuotone Desktop docs are available at:\n\nhttps://fontawesome.com/how-to-use/on-the-desktop/referencing-icons/duotone-icons.\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_animated.scss",
    "content": "// Animated Icons\n// --------------------------\n\n.#{$fa-css-prefix}-spin {\n  animation: fa-spin 2s infinite linear;\n}\n\n.#{$fa-css-prefix}-pulse {\n  animation: fa-spin 1s infinite steps(8);\n}\n\n@keyframes fa-spin {\n  0% {\n    transform: rotate(0deg);\n  }\n\n  100% {\n    transform: rotate(360deg);\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_bordered-pulled.scss",
    "content": "// Bordered & Pulled\n// -------------------------\n\n.#{$fa-css-prefix}-border {\n  border: solid .08em $fa-border-color;\n  border-radius: .1em;\n  padding: .2em .25em .15em;\n}\n\n.#{$fa-css-prefix}-pull-left { float: left; }\n.#{$fa-css-prefix}-pull-right { float: right; }\n\n.#{$fa-css-prefix},\n.fas,\n.far,\n.fal,\n.fab {\n  &.#{$fa-css-prefix}-pull-left { margin-right: .3em; }\n  &.#{$fa-css-prefix}-pull-right { margin-left: .3em; }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_core.scss",
    "content": "// Base Class Definition\n// -------------------------\n\n.#{$fa-css-prefix},\n.fas,\n.far,\n.fal,\n.fad,\n.fab {\n  -moz-osx-font-smoothing: grayscale;\n  -webkit-font-smoothing: antialiased;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  text-rendering: auto;\n  line-height: 1;\n}\n\n%fa-icon {\n  @include fa-icon;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_fixed-width.scss",
    "content": "// Fixed Width Icons\n// -------------------------\n.#{$fa-css-prefix}-fw {\n  text-align: center;\n  width: $fa-fw-width;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_icons.scss",
    "content": "/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen\nreaders do not read off random characters that represent icons */\n\n.#{$fa-css-prefix}-abacus:before { content: fa-content($fa-var-abacus); }\n.#{$fa-css-prefix}-alarm-exclamation:before { content: fa-content($fa-var-alarm-exclamation); }\n.#{$fa-css-prefix}-align-left:before { content: fa-content($fa-var-align-left); }\n.#{$fa-css-prefix}-align-slash:before { content: fa-content($fa-var-align-slash); }\n.#{$fa-css-prefix}-atom-alt:before { content: fa-content($fa-var-atom-alt); }\n.#{$fa-css-prefix}-aws:before { content: fa-content($fa-var-aws); }\n.#{$fa-css-prefix}-badge-check:before { content: fa-content($fa-var-badge-check); }\n.#{$fa-css-prefix}-bell:before { content: fa-content($fa-var-bell); }\n.#{$fa-css-prefix}-book-dead:before { content: fa-content($fa-var-book-dead); }\n.#{$fa-css-prefix}-books:before { content: fa-content($fa-var-books); }\n.#{$fa-css-prefix}-brackets-curly:before { content: fa-content($fa-var-brackets-curly); }\n.#{$fa-css-prefix}-cc-amazon-pay:before { content: fa-content($fa-var-cc-amazon-pay); }\n.#{$fa-css-prefix}-cc-amex:before { content: fa-content($fa-var-cc-amex); }\n.#{$fa-css-prefix}-cc-apple-pay:before { content: fa-content($fa-var-cc-apple-pay); }\n.#{$fa-css-prefix}-cc-diners-club:before { content: fa-content($fa-var-cc-diners-club); }\n.#{$fa-css-prefix}-cc-discover:before { content: fa-content($fa-var-cc-discover); }\n.#{$fa-css-prefix}-cc-jcb:before { content: fa-content($fa-var-cc-jcb); }\n.#{$fa-css-prefix}-cc-mastercard:before { content: fa-content($fa-var-cc-mastercard); }\n.#{$fa-css-prefix}-cc-paypal:before { content: fa-content($fa-var-cc-paypal); }\n.#{$fa-css-prefix}-cc-stripe:before { content: fa-content($fa-var-cc-stripe); }\n.#{$fa-css-prefix}-cc-visa:before { content: fa-content($fa-var-cc-visa); }\n.#{$fa-css-prefix}-chart-network:before { content: fa-content($fa-var-chart-network); }\n.#{$fa-css-prefix}-chart-scatter:before { content: fa-content($fa-var-chart-scatter); }\n.#{$fa-css-prefix}-check:before { content: fa-content($fa-var-check); }\n.#{$fa-css-prefix}-check-circle:before { content: fa-content($fa-var-check-circle); }\n.#{$fa-css-prefix}-circle:before { content: fa-content($fa-var-circle); }\n.#{$fa-css-prefix}-cloud:before { content: fa-content($fa-var-cloud); }\n.#{$fa-css-prefix}-clouds:before { content: fa-content($fa-var-clouds); }\n.#{$fa-css-prefix}-cogs:before { content: fa-content($fa-var-cogs); }\n.#{$fa-css-prefix}-comment-dots:before { content: fa-content($fa-var-comment-dots); }\n.#{$fa-css-prefix}-concierge-bell:before { content: fa-content($fa-var-concierge-bell); }\n.#{$fa-css-prefix}-credit-card:before { content: fa-content($fa-var-credit-card); }\n.#{$fa-css-prefix}-desktop:before { content: fa-content($fa-var-desktop); }\n.#{$fa-css-prefix}-discourse:before { content: fa-content($fa-var-discourse); }\n.#{$fa-css-prefix}-docker:before { content: fa-content($fa-var-docker); }\n.#{$fa-css-prefix}-dot-circle:before { content: fa-content($fa-var-dot-circle); }\n.#{$fa-css-prefix}-envelope:before { content: fa-content($fa-var-envelope); }\n.#{$fa-css-prefix}-exchange-alt:before { content: fa-content($fa-var-exchange-alt); }\n.#{$fa-css-prefix}-eye:before { content: fa-content($fa-var-eye); }\n.#{$fa-css-prefix}-file-alt:before { content: fa-content($fa-var-file-alt); }\n.#{$fa-css-prefix}-file-code:before { content: fa-content($fa-var-file-code); }\n.#{$fa-css-prefix}-fingerprint:before { content: fa-content($fa-var-fingerprint); }\n.#{$fa-css-prefix}-github:before { content: fa-content($fa-var-github); }\n.#{$fa-css-prefix}-globe:before { content: fa-content($fa-var-globe); }\n.#{$fa-css-prefix}-globe-africa:before { content: fa-content($fa-var-globe-africa); }\n.#{$fa-css-prefix}-globe-americas:before { content: fa-content($fa-var-globe-americas); }\n.#{$fa-css-prefix}-globe-asia:before { content: fa-content($fa-var-globe-asia); }\n.#{$fa-css-prefix}-globe-europe:before { content: fa-content($fa-var-globe-europe); }\n.#{$fa-css-prefix}-graduation-cap:before { content: fa-content($fa-var-graduation-cap); }\n.#{$fa-css-prefix}-history:before { content: fa-content($fa-var-history); }\n.#{$fa-css-prefix}-home:before { content: fa-content($fa-var-home); }\n.#{$fa-css-prefix}-info:before { content: fa-content($fa-var-info); }\n.#{$fa-css-prefix}-info-circle:before { content: fa-content($fa-var-info-circle); }\n.#{$fa-css-prefix}-instagram:before { content: fa-content($fa-var-instagram); }\n.#{$fa-css-prefix}-key:before { content: fa-content($fa-var-key); }\n.#{$fa-css-prefix}-key-skeleton:before { content: fa-content($fa-var-key-skeleton); }\n.#{$fa-css-prefix}-laptop:before { content: fa-content($fa-var-laptop); }\n.#{$fa-css-prefix}-laptop-code:before { content: fa-content($fa-var-laptop-code); }\n.#{$fa-css-prefix}-laptop-house:before { content: fa-content($fa-var-laptop-house); }\n.#{$fa-css-prefix}-life-ring:before { content: fa-content($fa-var-life-ring); }\n.#{$fa-css-prefix}-lightbulb:before { content: fa-content($fa-var-lightbulb); }\n.#{$fa-css-prefix}-list-alt:before { content: fa-content($fa-var-list-alt); }\n.#{$fa-css-prefix}-list-ul:before { content: fa-content($fa-var-list-ul); }\n.#{$fa-css-prefix}-lock-alt:before { content: fa-content($fa-var-lock-alt); }\n.#{$fa-css-prefix}-map-marker-alt:before { content: fa-content($fa-var-map-marker-alt); }\n.#{$fa-css-prefix}-microsoft:before { content: fa-content($fa-var-microsoft); }\n.#{$fa-css-prefix}-moon-stars:before { content: fa-content($fa-var-moon-stars); }\n.#{$fa-css-prefix}-network-wired:before { content: fa-content($fa-var-network-wired); }\n.#{$fa-css-prefix}-planet-ringed:before { content: fa-content($fa-var-planet-ringed); }\n.#{$fa-css-prefix}-plus:before { content: fa-content($fa-var-plus); }\n.#{$fa-css-prefix}-question-circle:before { content: fa-content($fa-var-question-circle); }\n.#{$fa-css-prefix}-quote-left:before { content: fa-content($fa-var-quote-left); }\n.#{$fa-css-prefix}-random:before { content: fa-content($fa-var-random); }\n.#{$fa-css-prefix}-rev:before { content: fa-content($fa-var-rev); }\n.#{$fa-css-prefix}-robot:before { content: fa-content($fa-var-robot); }\n.#{$fa-css-prefix}-rocket:before { content: fa-content($fa-var-rocket); }\n.#{$fa-css-prefix}-save:before { content: fa-content($fa-var-save); }\n.#{$fa-css-prefix}-search:before { content: fa-content($fa-var-search); }\n.#{$fa-css-prefix}-server:before { content: fa-content($fa-var-server); }\n.#{$fa-css-prefix}-sign-out:before { content: fa-content($fa-var-sign-out); }\n.#{$fa-css-prefix}-siren-on:before { content: fa-content($fa-var-siren-on); }\n.#{$fa-css-prefix}-slack:before { content: fa-content($fa-var-slack); }\n.#{$fa-css-prefix}-slash:before { content: fa-content($fa-var-slash); }\n.#{$fa-css-prefix}-smile:before { content: fa-content($fa-var-smile); }\n.#{$fa-css-prefix}-snowman:before { content: fa-content($fa-var-snowman); }\n.#{$fa-css-prefix}-spinner-third:before { content: fa-content($fa-var-spinner-third); }\n.#{$fa-css-prefix}-square-full:before { content: fa-content($fa-var-square-full); }\n.#{$fa-css-prefix}-sun:before { content: fa-content($fa-var-sun); }\n.#{$fa-css-prefix}-tasks:before { content: fa-content($fa-var-tasks); }\n.#{$fa-css-prefix}-times:before { content: fa-content($fa-var-times); }\n.#{$fa-css-prefix}-times-circle:before { content: fa-content($fa-var-times-circle); }\n.#{$fa-css-prefix}-twitter:before { content: fa-content($fa-var-twitter); }\n.#{$fa-css-prefix}-undo:before { content: fa-content($fa-var-undo); }\n.#{$fa-css-prefix}-undo-alt:before { content: fa-content($fa-var-undo-alt); }\n.#{$fa-css-prefix}-university:before { content: fa-content($fa-var-university); }\n.#{$fa-css-prefix}-user:before { content: fa-content($fa-var-user); }\n.#{$fa-css-prefix}-user-friends:before { content: fa-content($fa-var-user-friends); }\n.#{$fa-css-prefix}-user-hard-hat:before { content: fa-content($fa-var-user-hard-hat); }\n.#{$fa-css-prefix}-user-shield:before { content: fa-content($fa-var-user-shield); }\n.#{$fa-css-prefix}-users:before { content: fa-content($fa-var-users); }\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_larger.scss",
    "content": "// Icon Sizes\n// -------------------------\n\n// makes the font 33% larger relative to the icon container\n.#{$fa-css-prefix}-lg {\n  font-size: (4em / 3);\n  line-height: (3em / 4);\n  vertical-align: -.0667em;\n}\n\n.#{$fa-css-prefix}-xs {\n  font-size: .75em;\n}\n\n.#{$fa-css-prefix}-sm {\n  font-size: .875em;\n}\n\n@for $i from 1 through 10 {\n  .#{$fa-css-prefix}-#{$i}x {\n    font-size: $i * 1em;\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_list.scss",
    "content": "// List Icons\n// -------------------------\n\n.#{$fa-css-prefix}-ul {\n  list-style-type: none;\n  margin-left: $fa-li-width * 5/4;\n  padding-left: 0;\n\n  > li { position: relative; }\n}\n\n.#{$fa-css-prefix}-li {\n  left: -$fa-li-width;\n  position: absolute;\n  text-align: center;\n  width: $fa-li-width;\n  line-height: inherit;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_mixins.scss",
    "content": "// Mixins\n// --------------------------\n\n@mixin fa-icon {\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n  display: inline-block;\n  font-style: normal;\n  font-variant: normal;\n  font-weight: normal;\n  line-height: 1;\n}\n\n@mixin fa-icon-rotate($degrees, $rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})\";\n  transform: rotate($degrees);\n}\n\n@mixin fa-icon-flip($horiz, $vert, $rotation) {\n  -ms-filter: \"progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)\";\n  transform: scale($horiz, $vert);\n}\n\n\n// Only display content to screen readers. A la Bootstrap 4.\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n@mixin sr-only {\n  border: 0;\n  clip: rect(0, 0, 0, 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n//\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n//\n// Credit: HTML5 Boilerplate\n\n@mixin sr-only-focusable {\n  &:active,\n  &:focus {\n    clip: auto;\n    height: auto;\n    margin: 0;\n    overflow: visible;\n    position: static;\n    width: auto;\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_rotated-flipped.scss",
    "content": "// Rotated & Flipped Icons\n// -------------------------\n\n.#{$fa-css-prefix}-rotate-90  { @include fa-icon-rotate(90deg, 1);  }\n.#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); }\n.#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); }\n\n.#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); }\n.#{$fa-css-prefix}-flip-vertical   { @include fa-icon-flip(1, -1, 2); }\n.#{$fa-css-prefix}-flip-both, .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(-1, -1, 2); }\n\n// Hook for IE8-9\n// -------------------------\n\n:root {\n  .#{$fa-css-prefix}-rotate-90,\n  .#{$fa-css-prefix}-rotate-180,\n  .#{$fa-css-prefix}-rotate-270,\n  .#{$fa-css-prefix}-flip-horizontal,\n  .#{$fa-css-prefix}-flip-vertical,\n  .#{$fa-css-prefix}-flip-both {\n    filter: none;\n  }\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_screen-reader.scss",
    "content": "// Screen Readers\n// -------------------------\n\n.sr-only { @include sr-only; }\n.sr-only-focusable { @include sr-only-focusable; }\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_stacked.scss",
    "content": "// Stacked Icons\n// -------------------------\n\n.#{$fa-css-prefix}-stack {\n  display: inline-block;\n  height: 2em;\n  line-height: 2em;\n  position: relative;\n  vertical-align: middle;\n  width: ($fa-fw-width*2);\n}\n\n.#{$fa-css-prefix}-stack-1x,\n.#{$fa-css-prefix}-stack-2x {\n  left: 0;\n  position: absolute;\n  text-align: center;\n  width: 100%;\n}\n\n.#{$fa-css-prefix}-stack-1x {\n  line-height: inherit;\n}\n\n.#{$fa-css-prefix}-stack-2x {\n  font-size: 2em;\n}\n\n.#{$fa-css-prefix}-inverse {\n  color: $fa-inverse;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/_variables.scss",
    "content": "// Variables\n// --------------------------\n\n$fa-font-path:         \"../webfonts\" !default;\n$fa-font-size-base:    16px !default;\n$fa-font-display:      block !default;\n$fa-css-prefix:        fa !default;\n$fa-version:           \"5.15.4\" !default;\n$fa-border-color:      #eee !default;\n$fa-inverse:           #fff !default;\n$fa-li-width:          2em !default;\n$fa-fw-width:          (20em / 16);\n$fa-primary-opacity:   1 !default;\n$fa-secondary-opacity: .4 !default;\n\n// Convenience function used to set content property\n@function fa-content($fa-var) {\n  @return unquote(\"\\\"#{ $fa-var }\\\"\");\n}\n\n$fa-var-abacus: \\f640;\n$fa-var-alarm-exclamation: \\f843;\n$fa-var-align-left: \\f036;\n$fa-var-align-slash: \\f846;\n$fa-var-atom-alt: \\f5d3;\n$fa-var-aws: \\f375;\n$fa-var-badge-check: \\f336;\n$fa-var-bell: \\f0f3;\n$fa-var-book-dead: \\f6b7;\n$fa-var-books: \\f5db;\n$fa-var-brackets-curly: \\f7ea;\n$fa-var-cc-amazon-pay: \\f42d;\n$fa-var-cc-amex: \\f1f3;\n$fa-var-cc-apple-pay: \\f416;\n$fa-var-cc-diners-club: \\f24c;\n$fa-var-cc-discover: \\f1f2;\n$fa-var-cc-jcb: \\f24b;\n$fa-var-cc-mastercard: \\f1f1;\n$fa-var-cc-paypal: \\f1f4;\n$fa-var-cc-stripe: \\f1f5;\n$fa-var-cc-visa: \\f1f0;\n$fa-var-chart-network: \\f78a;\n$fa-var-chart-scatter: \\f7ee;\n$fa-var-check: \\f00c;\n$fa-var-check-circle: \\f058;\n$fa-var-circle: \\f111;\n$fa-var-cloud: \\f0c2;\n$fa-var-clouds: \\f744;\n$fa-var-cogs: \\f085;\n$fa-var-comment-dots: \\f4ad;\n$fa-var-concierge-bell: \\f562;\n$fa-var-credit-card: \\f09d;\n$fa-var-desktop: \\f108;\n$fa-var-discourse: \\f393;\n$fa-var-docker: \\f395;\n$fa-var-dot-circle: \\f192;\n$fa-var-envelope: \\f0e0;\n$fa-var-exchange-alt: \\f362;\n$fa-var-eye: \\f06e;\n$fa-var-file-alt: \\f15c;\n$fa-var-file-code: \\f1c9;\n$fa-var-fingerprint: \\f577;\n$fa-var-github: \\f09b;\n$fa-var-globe: \\f0ac;\n$fa-var-globe-africa: \\f57c;\n$fa-var-globe-americas: \\f57d;\n$fa-var-globe-asia: \\f57e;\n$fa-var-globe-europe: \\f7a2;\n$fa-var-graduation-cap: \\f19d;\n$fa-var-history: \\f1da;\n$fa-var-home: \\f015;\n$fa-var-info: \\f129;\n$fa-var-info-circle: \\f05a;\n$fa-var-instagram: \\f16d;\n$fa-var-key: \\f084;\n$fa-var-key-skeleton: \\f6f3;\n$fa-var-laptop: \\f109;\n$fa-var-laptop-code: \\f5fc;\n$fa-var-laptop-house: \\e066;\n$fa-var-life-ring: \\f1cd;\n$fa-var-lightbulb: \\f0eb;\n$fa-var-list-alt: \\f022;\n$fa-var-list-ul: \\f0ca;\n$fa-var-lock-alt: \\f30d;\n$fa-var-map-marker-alt: \\f3c5;\n$fa-var-microsoft: \\f3ca;\n$fa-var-moon-stars: \\f755;\n$fa-var-network-wired: \\f6ff;\n$fa-var-planet-ringed: \\e020;\n$fa-var-plus: \\f067;\n$fa-var-question-circle: \\f059;\n$fa-var-quote-left: \\f10d;\n$fa-var-random: \\f074;\n$fa-var-rev: \\f5b2;\n$fa-var-robot: \\f544;\n$fa-var-rocket: \\f135;\n$fa-var-save: \\f0c7;\n$fa-var-search: \\f002;\n$fa-var-server: \\f233;\n$fa-var-sign-out: \\f08b;\n$fa-var-siren-on: \\e02e;\n$fa-var-slack: \\f198;\n$fa-var-slash: \\f715;\n$fa-var-smile: \\f118;\n$fa-var-snowman: \\f7d0;\n$fa-var-spinner-third: \\f3f4;\n$fa-var-square-full: \\f45c;\n$fa-var-sun: \\f185;\n$fa-var-tasks: \\f0ae;\n$fa-var-times: \\f00d;\n$fa-var-times-circle: \\f057;\n$fa-var-twitter: \\f099;\n$fa-var-undo: \\f0e2;\n$fa-var-undo-alt: \\f2ea;\n$fa-var-university: \\f19c;\n$fa-var-user: \\f007;\n$fa-var-user-friends: \\f500;\n$fa-var-user-hard-hat: \\f82c;\n$fa-var-user-shield: \\f505;\n$fa-var-users: \\f0c0;\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/brands.scss",
    "content": "@import 'variables';\n\n@font-face {\n  font-family: 'Font Awesome 5 Brands';\n  font-style: normal;\n  font-weight: 400;\n  font-display: $fa-font-display;\n  src: url('#{$fa-font-path}/fa-brands-400.eot');\n  src: url('#{$fa-font-path}/fa-brands-400.eot?#iefix') format('embedded-opentype'),\n  url('#{$fa-font-path}/fa-brands-400.woff2') format('woff2'),\n  url('#{$fa-font-path}/fa-brands-400.woff') format('woff'),\n  url('#{$fa-font-path}/fa-brands-400.ttf') format('truetype'),\n  url('#{$fa-font-path}/fa-brands-400.svg#fontawesome') format('svg');\n}\n\n.fab {\n  font-family: 'Font Awesome 5 Brands';\n  font-weight: 400;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/duotone.scss",
    "content": "@import 'variables';\n\n@font-face {\n  font-family: 'Font Awesome 5 Duotone';\n  font-style: normal;\n  font-weight: 900;\n  font-display: $fa-font-display;\n  src: url('#{$fa-font-path}/fa-duotone-900.eot');\n  src: url('#{$fa-font-path}/fa-duotone-900.eot?#iefix') format('embedded-opentype'),\n  url('#{$fa-font-path}/fa-duotone-900.woff2') format('woff2'),\n  url('#{$fa-font-path}/fa-duotone-900.woff') format('woff'),\n  url('#{$fa-font-path}/fa-duotone-900.ttf') format('truetype'),\n  url('#{$fa-font-path}/fa-duotone-900.svg#fontawesome') format('svg');\n}\n\n.fad {\n  position: relative;\n  font-family: 'Font Awesome 5 Duotone';\n  font-weight: 900;\n}\n\n.fad:before {\n  position: absolute;\n  color: var(--#{$fa-css-prefix}-primary-color, inherit);\n  opacity: $fa-primary-opacity;\n  opacity: var(--#{$fa-css-prefix}-primary-opacity, #{$fa-primary-opacity});\n}\n\n.fad:after {\n  color: var(--#{$fa-css-prefix}-secondary-color, inherit);\n  opacity: $fa-secondary-opacity;\n  opacity: var(--#{$fa-css-prefix}-secondary-opacity, #{$fa-secondary-opacity});\n}\n\n.#{$fa-css-prefix}-swap-opacity .fad:before,\n.fad.#{$fa-css-prefix}-swap-opacity:before {\n  opacity: $fa-secondary-opacity;\n  opacity: var(--#{$fa-css-prefix}-secondary-opacity, #{$fa-secondary-opacity});\n}\n\n.#{$fa-css-prefix}-swap-opacity .fad:after,\n.fad.#{$fa-css-prefix}-swap-opacity:after {\n  opacity: $fa-primary-opacity;\n  opacity: var(--#{$fa-css-prefix}-primary-opacity, #{$fa-primary-opacity});\n}\n\n.fad.#{$fa-css-prefix}-inverse {\n  color: $fa-inverse;\n}\n\n.fad.#{$fa-css-prefix}-stack-1x, .fad.#{$fa-css-prefix}-stack-2x {\n  position: absolute;\n}\n\n.fad.#{$fa-css-prefix}-stack-1x:before,\n.fad.#{$fa-css-prefix}-stack-2x:before,\n.fad.#{$fa-css-prefix}-fw:before {\n  left: 50%;\n  transform: translateX(-50%);\n}\n\n.fad.#{$fa-css-prefix}-abacus:after { content: fa-content(\\10f640); }\n.fad.#{$fa-css-prefix}-align-slash:after { content: fa-content(\\10f846); }\n.fad.#{$fa-css-prefix}-atom-alt:after { content: fa-content(\\10f5d3); }\n.fad.#{$fa-css-prefix}-badge-check:after { content: fa-content(\\10f336); }\n.fad.#{$fa-css-prefix}-bell:after { content: fa-content(\\10f0f3); }\n.fad.#{$fa-css-prefix}-books:after { content: fa-content(\\10f5db); }\n.fad.#{$fa-css-prefix}-brackets-curly:after { content: fa-content(\\10f7ea); }\n.fad.#{$fa-css-prefix}-chart-network:after { content: fa-content(\\10f78a); }\n.fad.#{$fa-css-prefix}-chart-scatter:after { content: fa-content(\\10f7ee); }\n.fad.#{$fa-css-prefix}-check:after { content: fa-content(\\10f00c); }\n.fad.#{$fa-css-prefix}-circle:after { content: fa-content(\\10f111); }\n.fad.#{$fa-css-prefix}-clouds:after { content: fa-content(\\10f744); }\n.fad.#{$fa-css-prefix}-cogs:after { content: fa-content(\\10f085); }\n.fad.#{$fa-css-prefix}-comment-dots:after { content: fa-content(\\10f4ad); }\n.fad.#{$fa-css-prefix}-concierge-bell:after { content: fa-content(\\10f562); }\n.fad.#{$fa-css-prefix}-dot-circle:after { content: fa-content(\\10f192); }\n.fad.#{$fa-css-prefix}-envelope:after { content: fa-content(\\10f0e0); }\n.fad.#{$fa-css-prefix}-exchange-alt:after { content: fa-content(\\10f362); }\n.fad.#{$fa-css-prefix}-file-alt:after { content: fa-content(\\10f15c); }\n.fad.#{$fa-css-prefix}-file-code:after { content: fa-content(\\10f1c9); }\n.fad.#{$fa-css-prefix}-globe:after { content: fa-content(\\10f0ac); }\n.fad.#{$fa-css-prefix}-globe-africa:after { content: fa-content(\\10f57c); }\n.fad.#{$fa-css-prefix}-globe-americas:after { content: fa-content(\\10f57d); }\n.fad.#{$fa-css-prefix}-globe-asia:after { content: fa-content(\\10f57e); }\n.fad.#{$fa-css-prefix}-globe-europe:after { content: fa-content(\\10f7a2); }\n.fad.#{$fa-css-prefix}-graduation-cap:after { content: fa-content(\\10f19d); }\n.fad.#{$fa-css-prefix}-history:after { content: fa-content(\\10f1da); }\n.fad.#{$fa-css-prefix}-key:after { content: fa-content(\\10f084); }\n.fad.#{$fa-css-prefix}-key-skeleton:after { content: fa-content(\\10f6f3); }\n.fad.#{$fa-css-prefix}-laptop:after { content: fa-content(\\10f109); }\n.fad.#{$fa-css-prefix}-laptop-code:after { content: fa-content(\\10f5fc); }\n.fad.#{$fa-css-prefix}-laptop-house:after { content: fa-content(\\10e066); }\n.fad.#{$fa-css-prefix}-life-ring:after { content: fa-content(\\10f1cd); }\n.fad.#{$fa-css-prefix}-lightbulb:after { content: fa-content(\\10f0eb); }\n.fad.#{$fa-css-prefix}-list-alt:after { content: fa-content(\\10f022); }\n.fad.#{$fa-css-prefix}-list-ul:after { content: fa-content(\\10f0ca); }\n.fad.#{$fa-css-prefix}-lock-alt:after { content: fa-content(\\10f30d); }\n.fad.#{$fa-css-prefix}-map-marker-alt:after { content: fa-content(\\10f3c5); }\n.fad.#{$fa-css-prefix}-moon-stars:after { content: fa-content(\\10f755); }\n.fad.#{$fa-css-prefix}-network-wired:after { content: fa-content(\\10f6ff); }\n.fad.#{$fa-css-prefix}-planet-ringed:after { content: fa-content(\\10e020); }\n.fad.#{$fa-css-prefix}-question-circle:after { content: fa-content(\\10f059); }\n.fad.#{$fa-css-prefix}-quote-left:after { content: fa-content(\\10f10d); }\n.fad.#{$fa-css-prefix}-random:after { content: fa-content(\\10f074); }\n.fad.#{$fa-css-prefix}-rocket:after { content: fa-content(\\10f135); }\n.fad.#{$fa-css-prefix}-search:after { content: fa-content(\\10f002); }\n.fad.#{$fa-css-prefix}-server:after { content: fa-content(\\10f233); }\n.fad.#{$fa-css-prefix}-sign-out:after { content: fa-content(\\10f08b); }\n.fad.#{$fa-css-prefix}-siren-on:after { content: fa-content(\\10e02e); }\n.fad.#{$fa-css-prefix}-smile:after { content: fa-content(\\10f118); }\n.fad.#{$fa-css-prefix}-snowman:after { content: fa-content(\\10f7d0); }\n.fad.#{$fa-css-prefix}-sun:after { content: fa-content(\\10f185); }\n.fad.#{$fa-css-prefix}-tasks:after { content: fa-content(\\10f0ae); }\n.fad.#{$fa-css-prefix}-university:after { content: fa-content(\\10f19c); }\n.fad.#{$fa-css-prefix}-user:after { content: fa-content(\\10f007); }\n.fad.#{$fa-css-prefix}-user-hard-hat:after { content: fa-content(\\10f82c); }\n.fad.#{$fa-css-prefix}-user-shield:after { content: fa-content(\\10f505); }\n.fad.#{$fa-css-prefix}-users:after { content: fa-content(\\10f0c0); }\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/fontawesome.scss",
    "content": "@import 'variables';\n@import 'mixins';\n@import 'core';\n@import 'larger';\n@import 'fixed-width';\n@import 'list';\n@import 'bordered-pulled';\n@import 'animated';\n@import 'rotated-flipped';\n@import 'stacked';\n@import 'icons';\n@import 'screen-reader';\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/regular.scss",
    "content": "@import 'variables';\n\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 400;\n  font-display: $fa-font-display;\n  src: url('#{$fa-font-path}/fa-regular-400.eot');\n  src: url('#{$fa-font-path}/fa-regular-400.eot?#iefix') format('embedded-opentype'),\n  url('#{$fa-font-path}/fa-regular-400.woff2') format('woff2'),\n  url('#{$fa-font-path}/fa-regular-400.woff') format('woff'),\n  url('#{$fa-font-path}/fa-regular-400.ttf') format('truetype'),\n  url('#{$fa-font-path}/fa-regular-400.svg#fontawesome') format('svg');\n}\n\n.far {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 400;\n}\n"
  },
  {
    "path": "public/fonts/font-awesome/scss/solid.scss",
    "content": "@import 'variables';\n\n@font-face {\n  font-family: 'Font Awesome 5 Pro';\n  font-style: normal;\n  font-weight: 900;\n  font-display: $fa-font-display;\n  src: url('#{$fa-font-path}/fa-solid-900.eot');\n  src: url('#{$fa-font-path}/fa-solid-900.eot?#iefix') format('embedded-opentype'),\n  url('#{$fa-font-path}/fa-solid-900.woff2') format('woff2'),\n  url('#{$fa-font-path}/fa-solid-900.woff') format('woff'),\n  url('#{$fa-font-path}/fa-solid-900.ttf') format('truetype'),\n  url('#{$fa-font-path}/fa-solid-900.svg#fontawesome') format('svg');\n}\n\n.fa,\n.fas {\n  font-family: 'Font Awesome 5 Pro';\n  font-weight: 900;\n}\n"
  },
  {
    "path": "public/fonts/fonts.css",
    "content": "@font-face {\n  font-family: 'Material Icons';\n  font-style: normal;\n  font-weight: 400;\n  src: url('./material-icons.ttf') format('truetype');\n}\n@font-face {\n  font-family: 'Material Icons Outlined';\n  font-style: normal;\n  font-weight: 400;\n  src: url('./material-icons-outlined.otf') format('opentype');\n}\n@font-face {\n  font-family: 'Roboto';\n  font-style: normal;\n  font-weight: 100;\n  src: url('./roboto-100.ttf') format('truetype');\n}\n@font-face {\n  font-family: 'Roboto';\n  font-style: normal;\n  font-weight: 300;\n  src: url('./roboto-300.ttf') format('truetype');\n}\n@font-face {\n  font-family: 'Roboto';\n  font-style: normal;\n  font-weight: 400;\n  src: url('./roboto-400.ttf') format('truetype');\n}\n@font-face {\n  font-family: 'Roboto';\n  font-style: normal;\n  font-weight: 500;\n  src: url('./roboto-500.ttf') format('truetype');\n}\n@font-face {\n  font-family: 'Roboto';\n  font-style: normal;\n  font-weight: 700;\n  src: url('./roboto-700.ttf') format('truetype');\n}\n\n.material-icons {\n  font-family: 'Material Icons';\n  font-weight: normal;\n  font-style: normal;\n  font-size: 24px;\n  line-height: 1;\n  letter-spacing: normal;\n  text-transform: none;\n  display: inline-block;\n  white-space: nowrap;\n  word-wrap: normal;\n  direction: ltr;\n}\n\n.material-icons-outlined {\n  font-family: 'Material Icons Outlined';\n  font-weight: normal;\n  font-style: normal;\n  font-size: 24px;\n  line-height: 1;\n  letter-spacing: normal;\n  text-transform: none;\n  display: inline-block;\n  white-space: nowrap;\n  word-wrap: normal;\n  direction: ltr;\n}\n"
  },
  {
    "path": "public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n  <meta charset=\"utf-8\" />\n  <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\" />\n\n  <link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"/apple-touch-icon.png\" />\n  <link rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/favicon-32x32.png\" />\n  <link rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/favicon-16x16.png\" />\n  <link rel=\"manifest\" href=\"/site.webmanifest\" />\n  <link rel=\"mask-icon\" href=\"/safari-pinned-tab.svg\" color=\"#5bbad5\" />\n  <meta name=\"msapplication-TileColor\" content=\"#2d89ef\" />\n  <meta name=\"theme-color\" content=\"#ffffff\" />\n\n  <title>Prefect</title>\n  <link rel=\"stylesheet\" href=\"/fonts/fonts.css\" />\n  <script defer src=\"/fonts/font-awesome/js/all.js\"></script>\n  <script src=\"https://js.stripe.com/v3/\" async></script>\n</head>\n\n<body>\n  <noscript>\n    <strong>\n      We're sorry but the Prefect UI doesn't work properly without JavaScript\n      enabled. Please enable it to continue.\n    </strong>\n  </noscript>\n  <div id=\"app\"></div>\n  <div id=\"app-loader\" class=\"loading\">\n    <span></span>\n    <span></span>\n    <span></span>\n    <span></span>\n    <span></span>\n    <span></span>\n    <span></span>\n  </div>\n  <!-- built files will be auto injected -->\n  <script type=\"text/javascript\" src=\"https://service.force.com/embeddedservice/5.0/esw.min.js\"></script>\n</body>\n\n</html>\n\n<style>\n  #app-loader.loading {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n  }\n\n  #app-loader.loading span {\n    display: inline-block;\n    vertical-align: middle;\n    width: 0.6em;\n    height: 0.6em;\n    margin: 0.19em;\n    border-radius: 0.6em;\n    animation: loading 1s infinite alternate;\n  }\n\n  #app-loader.loading span:nth-of-type(2) {\n    background: #0082cb;\n    animation-delay: 0.2s;\n  }\n\n  #app-loader.loading span:nth-of-type(3) {\n    background: #27b1ff;\n    animation-delay: 0.4s;\n  }\n\n  #app-loader.loading span:nth-of-type(4) {\n    background: #0082cb;\n    animation-delay: 0.6s;\n  }\n\n  #app-loader.loading span:nth-of-type(5) {\n    background: #73e3ff;\n    animation-delay: 0.8s;\n  }\n\n  #app-loader.loading span:nth-of-type(6) {\n    background: #0082cb;\n    animation-delay: 1s;\n  }\n\n  #app-loader.loading span:nth-of-type(7) {\n    background: #27b1ff;\n    animation-delay: 1.2s;\n  }\n\n  @keyframes loading {\n    0% {\n      opacity: 0;\n    }\n\n    100% {\n      opacity: 1;\n    }\n  }\n</style>"
  },
  {
    "path": "public/settings.json",
    "content": "{\n    \"server_url\": \"PREFECT_SERVER__APOLLO_URL\",\n    \"base_url\": \"PREFECT_SERVER__BASE_URL\"\n}"
  },
  {
    "path": "public/site.webmanifest",
    "content": "{\n    \"name\": \"Prefect\",\n    \"short_name\": \"Prefect\",\n    \"icons\": [\n        {\n            \"src\": \"/android-chrome-192x192.png\",\n            \"sizes\": \"192x192\",\n            \"type\": \"image/png\"\n        },\n        {\n            \"src\": \"/android-chrome-512x512.png\",\n            \"sizes\": \"512x512\",\n            \"type\": \"image/png\"\n        }\n    ],\n    \"theme_color\": \"#ffffff\",\n    \"background_color\": \"#ffffff\",\n    \"display\": \"standalone\"\n}\n"
  },
  {
    "path": "requirements.txt",
    "content": "prefect == 0.12.4"
  },
  {
    "path": "runtime.txt",
    "content": "3.8\n"
  },
  {
    "path": "src/App.vue",
    "content": "<script>\nimport Alert from '@/components/Alert'\nimport Footer from '@/components/Footer'\nimport { mapActions, mapGetters, mapMutations } from 'vuex'\nimport { clearCache } from '@/vue-apollo'\nimport moment from 'moment'\n// import { authMixin } from '@/mixins/authMixin'\nimport ApplicationNavBar from '@/components/Nav/ApplicationNav'\nimport GlobalSearch from '@/components/GlobalSearchBar/GlobalSearch'\nimport TeamSideNav from '@/components/Nav/TeamSideNav'\nimport WorkQueueBanner from '@/components/WorkQueueBanner'\nimport { eventsMixin } from '@/mixins/eventsMixin'\nimport VSnackbars from '@/components/Snackbars/Snackbars'\n\nconst SERVER_KEY = `${process.env.VUE_APP_RELEASE_TIMESTAMP}_server_url`\n\nconst fullPageRoutes = [\n  'api',\n  '404',\n  'calendar',\n  'not-found',\n  'access-denied',\n  'team-switched',\n  'logout',\n  'welcome',\n  'roles'\n]\n\nconst onboardRoutes = ['welcome', 'name-team', 'onboard-resources', 'accept']\n\nexport default {\n  metaInfo() {\n    return {\n      title: `Prefect ${this.backend == 'CLOUD' ? 'Cloud' : 'Server'}`,\n      link: [\n        {\n          rel: 'icon',\n          href: null,\n          vmid: 'favicon'\n        }\n      ]\n    }\n  },\n  components: {\n    Alert,\n    ApplicationNavBar,\n    Footer,\n    GlobalSearch,\n    TeamSideNav,\n    VSnackbars,\n    WorkQueueBanner\n  },\n  mixins: [eventsMixin],\n  data() {\n    return {\n      error: null,\n      loadedComponents: 0,\n      loadingKey: 0,\n      numberOfComponents: 1,\n      refreshTimeout: null,\n      reset: false,\n      shown: true,\n      startupHasRun: false,\n      wholeAppShown: true\n    }\n  },\n  computed: {\n    ...mapGetters('api', [\n      'backend',\n      'version',\n      'url',\n      'connected',\n      'connecting',\n      'isServer',\n      'isCloud'\n    ]),\n    ...mapGetters('alert', ['getAlert']),\n    ...mapGetters('data', ['projects', 'flows']),\n    ...mapGetters('auth', ['isAuthenticated', 'isAuthorized']),\n    ...mapGetters('tenant', [\n      'tenant',\n      'tenants',\n      'defaultTenant',\n      'tenantIsSet',\n      'isLoadingTenant'\n    ]),\n    ...mapGetters('user', [\n      'isDark',\n      'memberships',\n      'userIsSet',\n      'user',\n      'plan'\n    ]),\n    ...mapGetters('polling', [\n      'shouldPollTenants',\n      'shouldPollAgents',\n      'shouldPollProjects',\n      'shouldPollFlows'\n    ]),\n    notFoundPage() {\n      return this.$route.name === 'not-found'\n    },\n    fullPageRoute() {\n      return fullPageRoutes.includes(this.$route.name)\n    },\n    loading() {\n      return this.isAuthenticated && (this.connecting || this.isLoadingTenant)\n    },\n    showNav() {\n      if (\n        this.$route.name == 'plans' ||\n        this.$route.name == 'not-found' ||\n        this.$route.name == 'team-switched' ||\n        this.$route.name == 'logout' ||\n        onboardRoutes.includes(this.$route.name)\n      )\n        return false\n      return (\n        ((this.isCloud && this.isAuthenticated) || this.isServer) &&\n        this.loadedComponents > 0\n      )\n    },\n    isCloud() {\n      return this.backend == 'CLOUD'\n    },\n    isWelcome() {\n      return (\n        this.$route.name === 'welcome' ||\n        this.$route.name === 'onboard-resources' ||\n        this.$route.name === 'name-team' ||\n        this.$route.name === 'accept'\n      )\n    },\n    paused() {\n      return this.tenant?.settings?.work_queue_paused\n    }\n  },\n  watch: {\n    isDark(val) {\n      this.$vuetify.theme.dark = val\n    },\n    backend() {\n      this.loadedComponents = 0\n      clearCache()\n      this.resetData()\n\n      this.refreshTimeout = setTimeout(() => {\n        this.resetData()\n        this.unsetInvitations()\n        this.unsetTenants()\n        this.unsetUser()\n        this.refresh()\n        clearTimeout(this.refreshTimeout)\n      }, 1000)\n      this.setSortedAgents(null)\n    },\n    async connected(val) {\n      if (val) {\n        clearCache()\n      }\n    },\n    tenant(val, oldVal) {\n      if (val?.id !== oldVal?.id) {\n        if (localStorage.getItem('haltTenantRouting')) {\n          localStorage.removeItem('haltTenantRouting')\n          return\n        }\n\n        if (this.isCloud && !this.tenant.settings.teamNamed) {\n          this.$router.push({\n            name: 'welcome',\n            params: {\n              tenant: this.tenant.slug\n            }\n          })\n        }\n\n        clearTimeout(this.refreshTimeout)\n        this.refresh()\n        this.resetData()\n        this.$apollo.queries.agents.refresh()\n        this.$apollo.queries.projects.refresh()\n        this.$apollo.queries.flows.refresh()\n      }\n    },\n    '$route.params.tenant'(value, previous) {\n      if (value && value !== previous && value !== this.tenant?.slug) {\n        this.setCurrentTenant(value)\n      }\n    },\n    isAuthorized(value) {\n      if (value) {\n        this.getApi()\n        this.getTenants()\n      }\n    }\n  },\n  beforeDestroy() {\n    window.removeEventListener('offline', this.handleOffline)\n    window.removeEventListener('online', this.handleOnline)\n\n    // this.oktaClient?.remove()\n\n    // document.removeEventListener(\n    //   'visibilitychange',\n    //   this.handleVisibilityChange\n    // )\n    // window.removeEventListener('blur', this.handleVisibilityChange)\n    // window.removeEventListener('focus', this.handleVisibilityChange)\n  },\n  async mounted() {\n    if (!localStorage.getItem(SERVER_KEY)) {\n      localStorage.setItem(\n        SERVER_KEY,\n        window.prefect_ui_settings?.server_url || process.env.VUE_APP_SERVER_URL\n      )\n\n      this.setServerUrl(localStorage.getItem(SERVER_KEY))\n    }\n\n    this.refresh()\n\n    if (this.isAuthorized || this.isServer) {\n      await this.getApi()\n\n      if (!this.connected && this.isServer) {\n        this.$router.push({ name: 'getting-started' })\n      }\n    }\n\n    this.$globalApolloQueries['tenants'] = this.$apollo.addSmartQuery(\n      'tenants',\n      {\n        query: require('@/graphql/Tenant/tenants.js').default(this.isCloud),\n        skip() {\n          return (\n            (this.isCloud && !this.isAuthorized) ||\n            !this.connected ||\n            !this.shouldPollTenants\n          )\n        },\n        fetchPolicy: 'no-cache',\n        pollInterval: 60000,\n        update(data) {\n          if (!data?.tenant) return []\n          this.setTenants(data.tenant)\n          return data.tenant\n        }\n      }\n    )\n\n    this.$globalApolloQueries['agents'] = this.$apollo.addSmartQuery('agents', {\n      query() {\n        return require('@/graphql/Agent/agents.js').default(this.isCloud)\n      },\n      skip() {\n        return (\n          (this.isCloud && !this.isAuthorized) ||\n          !this.connected ||\n          !this.shouldPollAgents\n        )\n      },\n      pollInterval: 1000,\n      // Without this, server UI with no actual server shows results\n      fetchPolicy: 'no-cache',\n      update(data) {\n        if (!data?.agent || this.isLoadingTenant) return null\n        this.setSortedAgents(data.agent)\n        return data.agent\n      }\n    })\n\n    this.$globalApolloQueries['projects'] = this.$apollo.addSmartQuery(\n      'projects',\n      {\n        query() {\n          return require('@/graphql/Nav/projects.gql')\n        },\n        skip() {\n          return (\n            (this.isCloud && !this.isAuthorized) ||\n            !this.connected ||\n            !this.shouldPollProjects\n          )\n        },\n        pollInterval: 10000,\n        update(data) {\n          if (!data?.project || this.isLoadingTenant) return []\n          this.setProjects(data.project)\n          return data.project\n        }\n      }\n    )\n\n    this.$globalApolloQueries['flows'] = this.$apollo.addSmartQuery('flows', {\n      query() {\n        return require('@/graphql/Nav/flows.gql')\n      },\n      skip() {\n        return (\n          (this.isCloud && !this.isAuthorized) ||\n          !this.connected ||\n          !this.shouldPollFlows\n        )\n      },\n      pollInterval: 10000,\n      update(data) {\n        if (!data?.flow || this.isLoadingTenant) return []\n        // Dedupes incoming flows\n        const flows =\n          this.flows?.filter(f => !data.flow.find(_f => _f.id == f.id)) || []\n        this.setFlows([...flows, ...data.flow])\n        return data.flow\n      }\n    })\n\n    this.$globalApolloQueries['memberships'] = this.$apollo.addSmartQuery(\n      'memberships',\n      {\n        query: require('@/graphql/User/user.gql'),\n        skip() {\n          return (\n            !this.isCloud ||\n            !this.isAuthorized ||\n            !this.memberships ||\n            !this.user ||\n            !this.user.email ||\n            !this.tenantIsSet\n          )\n        },\n        fetchPolicy: 'no-cache',\n        pollInterval: 60000,\n        update(data) {\n          if (!data?.user?.[0]) return []\n          this.setUser(data.user[0])\n\n          return data.user[0]\n        }\n      }\n    )\n\n    this.$globalApolloQueries[\n      'membershipInvitations'\n    ] = this.$apollo.addSmartQuery('membershipInvitations', {\n      query: require('@/graphql/Tenant/pending-invitations-by-email.gql'),\n      variables() {\n        return {\n          email: this.user.email\n        }\n      },\n      skip() {\n        return (\n          !this.isCloud ||\n          !this.isAuthorized ||\n          !this.memberships ||\n          !this.user ||\n          !this.user.email ||\n          !this.tenantIsSet\n        )\n      },\n      fetchPolicy: 'network-only',\n      pollInterval: 10000,\n      update(data) {\n        if (!data?.pendingInvitations || this.isLoadingTenant) return []\n        this.setInvitations(data.pendingInvitations)\n        return data.pendingInvitations\n      }\n    })\n  },\n  async beforeMount() {\n    window.addEventListener('offline', this.handleOffline)\n    window.addEventListener('online', this.handleOnline)\n    const dark = localStorage.getItem('dark_mode') === 'true' || this.isDark\n    if (dark) {\n      this.$vuetify.theme.dark = true\n    } else {\n      this.$vuetify.theme.dark = false\n    }\n\n    if (this.isCloud) {\n      if (\n        window.location.pathname?.includes('logout') ||\n        window.location.pathname?.includes('access-denied')\n      )\n        return\n\n      // If the application has loaded but the user isn't authenticated, authorized, or has no tenant\n      // redirect them to the help screen\n      if (!this.isAuthorized || !this.isAuthenticated || !this.tenant?.id) {\n        this.$router.push({\n          name: 'access-denied',\n          params: {\n            tenant: this.tenant.slug\n          }\n        })\n\n        // otherwise, if they haven't gone through onboarding, route them there\n      } else if (!this.tenant.settings.teamNamed) {\n        this.$router.push({\n          name: 'welcome',\n          params: {\n            tenant: this.tenant.slug\n          }\n        })\n      }\n    }\n\n    // document.addEventListener(\n    //   'visibilitychange',\n    //   this.handleVisibilityChange,\n    //   false\n    // )\n    // window.addEventListener('blur', this.handleVisibilityChange, false)\n    // window.addEventListener('focus', this.handleVisibilityChange, false)\n  },\n  methods: {\n    ...mapMutations('agent', ['setSortedAgents']),\n    ...mapActions('api', ['getApi', 'monitorConnection', 'setServerUrl']),\n    ...mapActions('auth', ['authenticate', 'authorize']),\n    ...mapActions('data', ['resetData']),\n    ...mapMutations('data', ['setFlows', 'setProjects']),\n    ...mapActions('tenant', ['getTenants', 'setCurrentTenant']),\n    ...mapMutations('tenant', [\n      'setDefaultTenant',\n      'unsetTenants',\n      'setTenants'\n    ]),\n    ...mapActions('user', ['getUser']),\n    ...mapMutations('user', [\n      'setInvitations',\n      'unsetInvitations',\n      'unsetUser'\n    ]),\n    ...mapMutations({ setUser: 'user/user' }),\n    handleOffline() {\n      // if the page isn't visible don't display a message\n      if (document.hidden || document.msHidden || document.webkitHidden) return\n    },\n    handleOnline() {\n      // if the page isn't visible don't display a message\n      if (document.hidden || document.msHidden || document.webkitHidden) return\n    },\n    handleVisibilityChange() {\n      this.currentInteraction = moment()\n\n      if (this.currentInteraction.diff(this.lastInteraction) >= 600000) {\n        this.wholeAppShown = false\n        setTimeout(() => {\n          this.wholeAppShown = true\n        }, 0)\n      } else if (this.currentInteraction.diff(this.lastInteraction) >= 300000) {\n        this.shown = false\n        setTimeout(() => {\n          this.shown = true\n        }, 0)\n      }\n\n      this.lastInteraction = this.currentInteraction\n    },\n    refresh() {\n      let start\n\n      const animationDuration = 150\n\n      const loadTiles = time => {\n        if (!start) start = time\n\n        const elapsed = time - start\n\n        if (elapsed > this.loadedComponents * animationDuration + 500) {\n          this.loadedComponents++\n        }\n\n        if (this.loadedComponents <= this.numberOfComponents) {\n          requestAnimationFrame(loadTiles)\n        }\n      }\n\n      requestAnimationFrame(loadTiles)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-app class=\"app\">\n    <v-main :class=\"{ 'pt-0': isWelcome }\">\n      <v-progress-linear absolute :active=\"loading\" indeterminate height=\"5\" />\n\n      <WorkQueueBanner />\n\n      <v-slide-y-transition>\n        <ApplicationNavBar v-if=\"showNav\" />\n      </v-slide-y-transition>\n\n      <TeamSideNav\n        v-if=\"\n          ((isCloud && isAuthenticated) || isServer) &&\n            loadedComponents > 0 &&\n            !isWelcome &&\n            $route.name !== 'team-switched'\n        \"\n      />\n\n      <v-fade-transition mode=\"out-in\">\n        <router-view\n          class=\"router-view\"\n          :class=\"{\n            'full-page': fullPageRoute,\n            'sm-and-down-bottom-padding': $vuetify.breakpoint.smAndDown\n          }\"\n        />\n      </v-fade-transition>\n\n      <v-container v-if=\"error\" class=\"fill-height\" fluid justify-center>\n        <v-card class=\"error--login\">\n          <v-card-text>{{ error }}</v-card-text>\n        </v-card>\n      </v-container>\n\n      <GlobalSearch v-if=\"$vuetify.breakpoint.xsOnly && showNav\" />\n\n      <v-slide-y-reverse-transition>\n        <Footer v-if=\"!fullPageRoute && !isWelcome\" />\n      </v-slide-y-reverse-transition>\n    </v-main>\n\n    <Alert\n      v-if=\"getAlert.alertShow\"\n      v-model=\"getAlert.alertShow\"\n      :type=\"getAlert.alertType\"\n      :message=\"getAlert.alertMessage\"\n      :alert-link=\"getAlert.alertLink\"\n      :link-text=\"getAlert.linkText\"\n      :nudge-bottom=\"paused\"\n      :timeout=\"12000\"\n      :alert-copy=\"getAlert.alertCopy\"\n    />\n\n    <VSnackbars />\n  </v-app>\n</template>\n\n<style lang=\"scss\">\n@font-face {\n  font-family: “Source Code Pro”;\n  src: url('assets/fonts/SourceCodePro-Regular.otf.woff2') format('woff2');\n}\n\nhtml {\n  background-color: var(--v-appBackground-base) !important;\n  font-size: 0.9rem !important;\n  overflow-y: auto;\n}\n\n.app {\n  background-color: var(--v-appBackground-base) !important;\n}\n\n.theme--light.v-app-bar {\n  &.primary {\n    background-image: linear-gradient(\n      165deg,\n      var(--v-primary-base),\n      var(--v-prefect-base)\n    );\n  }\n\n  &.secondary {\n    background-image: linear-gradient(\n      165deg,\n      var(--v-secondary-base),\n      var(--v-secondaryGray-base)\n    );\n  }\n}\n\n.link {\n  text-decoration: none;\n\n  &:hover,\n  &:active,\n  &:focus {\n    text-decoration: underline;\n  }\n}\n\n.router-view {\n  height: auto;\n  margin-bottom: 123px;\n  max-width: 100% !important;\n  min-height: calc(100vh - 64px - 123px);\n  padding-bottom: 18px;\n  transition: height none, opacity 250ms !important;\n\n  &.full-page {\n    margin-bottom: 0 !important;\n  }\n\n  &.sm-and-down-bottom-padding {\n    // margin-bottom: 180px;\n  }\n}\n\n.tab-full-height {\n  min-height: 100%;\n}\n\n.v-overlay.v-overlay--active {\n  backdrop-filter: blur(10px);\n}\n</style>\n"
  },
  {
    "path": "src/__mocks__/apollo.js",
    "content": "/* global jest */\n\nexport const query = jest.fn()\nexport const mutate = jest.fn()\n\nexport const Client = jest.fn(() => {\n  return {\n    query: query,\n    mutate: mutate\n  }\n})\n\nexport default Client\n"
  },
  {
    "path": "src/apollo.js",
    "content": "import { ApolloClient } from '@apollo/client/core'\nimport { HttpLink, from } from '@apollo/client'\nimport { onError } from 'apollo-link-error'\nimport { InMemoryCache } from 'apollo-cache-inmemory'\n\nconst cache = new InMemoryCache()\n\nconst errorAfterware = onError(\n  ({ response, operation, graphQLErrors, networkError, forward }) => {\n    if (process.env.NODE_ENV !== 'production') {\n      /* eslint-disable no-console */\n      console.groupCollapsed(\n        `%c${operation.operationName || 'Unnamed Query'} error`,\n        'color: #D64292; font-weight:bold;'\n      )\n      console.log('Operation: ', operation)\n\n      if (graphQLErrors?.length > 0) {\n        console.group('%cGraphQL Errors', 'color: #CA9800; font-weight:bold;')\n        graphQLErrors?.forEach(error => {\n          console.group(\n            `%c${error.extensions?.code || 'ERROR'}`,\n            'color: #B11A04; font-weight:bold;'\n          )\n          console.log(`Message: ${error.message}`)\n          console.log('Full log: ', error)\n          console.groupEnd()\n        })\n        console.groupEnd()\n      }\n\n      if (networkError) {\n        console.group('%cNetwork Error', 'color: #CA9800; font-weight:bold;')\n        console.log(networkError)\n        console.log(response)\n        console.log(graphQLErrors)\n        console.groupEnd()\n      }\n      console.groupEnd()\n      /* eslint-enable no-console */\n    }\n\n    if (response) {\n      response.errors = null\n    }\n\n    // Can return Observable.of returned from error link to supress errors\n    //  otherwise return forward(operation)\n    // for a single retry of the failure\n    // if (process.env.NODE_ENV !== 'production') return Observable.of()\n    return forward(operation)\n  }\n)\n\nconst link = from([\n  errorAfterware,\n  new HttpLink({ uri: process.env.VUE_APP_CLOUD_URL })\n])\n\nconst options = {\n  cache: cache,\n  link: link,\n  queryDeduplication: false,\n  defaultOptions: {\n    mutate: {\n      errorPolicy: 'all'\n    }\n  }\n}\n\n// // Create apollo client\nexport const Client = name =>\n  new ApolloClient({\n    name: name,\n    version: '1.3',\n    ...options\n  })\n"
  },
  {
    "path": "src/app.js",
    "content": "// Base imports\nimport Vue from 'vue'\nimport vuetify from '@/plugins/vuetify'\n\nimport Router from 'vue-router'\nimport App from '@/App.vue'\n\n// Plugins\nimport store from '@/store'\nimport { defaultApolloProvider } from '@/vue-apollo'\n\n// eslint-disable-next-line\n// import okta from '@/plugins/okta'\n\nimport { createRouter } from '@/router'\nimport VueMeta from 'vue-meta'\n\nimport LogRocket from 'logrocket'\n\n// Filters\nimport duration from '@/filters/duration'\nimport {\n  roundWhole,\n  roundTenths,\n  roundHundredths,\n  roundThousandths,\n  roundTens,\n  roundHundreds,\n  roundThousands\n} from '@/filters/round'\nimport shorten from '@/filters/shorten'\nimport filterOnePercent from '@/filters/filterOnePercent'\nimport { insertedActions, updatedActions } from '@/directives/disable-read-only'\n\n// Functional Components\nimport TransitionHeight from '@/components/Functional/Transition-Height'\nimport TruncatedSpan from '@/components/Functional/TruncatedSpan'\nimport GetCloud from '@/components/GetCloud'\n\nimport '@/styles/atelier-sulphurpool-light.scss'\n\n// Prefect icon font\nimport '@/assets/fonts/prefect-icons/style.scss'\n\n// Global and functional styles\nimport '@/styles/global.scss'\n\nVue.config.productionTip = false\nVue.config.devtools = true\nVue.config.performance = true\nif (\n  process.env.VUE_APP_ENVIRONMENT == 'staging' ||\n  process.env.VUE_APP_ENVIRONMENT == 'dev'\n) {\n  Vue.config.devtools = true\n  Vue.config.performance = true\n}\n\nVue.directive('disable-read-only-user', {\n  inserted: (el, binding) => insertedActions(el, binding),\n  update: (el, binding) => updatedActions(el, binding)\n})\n\n// Router\nVue.use(Router)\n\n// Meta data plugin\nVue.use(VueMeta, {\n  refreshOnceOnNavigation: true,\n  debounceWait: 500\n})\n\nVue.prototype.$globalApolloQueries = {}\n\n// Vue Global Error Handler\nVue.config.errorHandler = function(error, vm, trace) {\n  if (error?.message?.includes(\"'_observe'\")) return\n  if (process.env.NODE_ENV === 'development')\n    // eslint-disable-next-line no-console\n    console.log('Vue Global Error Handler', { error, vm, trace })\n  LogRocket.captureException(error)\n  LogRocket.log('Related to error', vm, error)\n}\n\nVue.config.warnHandler = function(error, vm, trace) {\n  if (error?.message?.includes(\"'_observe'\")) return\n  if (process.env.NODE_ENV === 'development')\n    // eslint-disable-next-line no-console\n    console.log('Vue Global Warn Handler', { error, vm, trace })\n}\n\n// Catch the rest\nwindow.onerror = function(error) {\n  if (process.env.NODE_ENV === 'development')\n    // eslint-disable-next-line no-console\n    console.log('Window Error Handler', error)\n  LogRocket.captureException(error)\n}\n\n// Add Filters\nVue.filter('duration', duration)\nVue.filter('shorten', shorten)\nVue.filter('filterOnePercent', filterOnePercent)\n\nVue.filter('roundWhole', roundWhole)\nVue.filter('roundTenths', roundTenths)\nVue.filter('roundHundredths', roundHundredths)\nVue.filter('roundThousandths', roundThousandths)\nVue.filter('roundTens', roundTens)\nVue.filter('roundHundreds', roundHundreds)\nVue.filter('roundThousands', roundThousands)\n\nVue.component('HeightTransition', TransitionHeight)\nVue.component('Truncate', TruncatedSpan)\nVue.component('GetCloud', GetCloud)\n\n// This is a global mixin used to clean up any\n// references a component may have after it's destroyed.\n// It's a pretty heavy-handed approach to what we're trying\n// to accomplish but Vue doesn't seem to be removing all references\n// itself, which is leading to large memory leaks on data-heavy pages\n// as Apollo polls and when navigating between pages.\n// This could be more elegant and may be fixed by upgrading to Vue 3.\nconst blockedProps = [\n  '$data',\n  '$listeners',\n  'theme',\n  '$attrs',\n  '$props',\n  'timeline',\n  'windowGroup',\n  'expansionPanel',\n  'expansionPanels',\n  'tabsBar',\n  'listItemGroup',\n  'btnToggle'\n]\n\nVue.mixin({\n  destroyed() {\n    const prepForGC = () => {\n      try {\n        this.$el?.remove()\n        this.elm = null\n        this.$el = null\n        this.parent = null\n        this.$parent = null\n        this.data = null\n        // this.$data = null // Unsetting this throws internal Vue errors\n        // this.options = null // Unsetting this throws internal Vue errors\n        this.$options = null\n        this.$vnode = null\n        this.listeners = null\n        // this.$listeners = null // Unsetting this throws internal Vue errors\n        this._vnode = null\n        this._watcher = null\n        this._watchers = null\n        this._computedWatchers = null\n        this.$slots = null\n        this.slots = null\n        this.$scopedSlots = null\n        this.scopedSlots = null\n        this.$children = null\n        this.children = null\n        this.store = null\n        this.$store = null\n\n        // $apollo has no setter so we clear props instead\n        if (this.$apollo) {\n          this.$apollo.vm = null\n        }\n\n        Object.keys(this).forEach(key => {\n          try {\n            !blockedProps.includes(key) &&\n              !(key in this[key]?.$props) &&\n              (this[key] = null)\n          } catch {\n            /* */\n          }\n        })\n      } catch (e) {\n        if (\n          process.env.VUE_APP_ENVIRONMENT == 'staging' ||\n          process.env.VUE_APP_ENVIRONMENT == 'dev'\n        ) {\n          // eslint-disable-next-line no-console\n          console.error('Error in destroyed garbage collector mixin', e)\n        }\n      }\n    }\n\n    // If the element has already been removed from the DOM\n    // we run the GC prep method immediately\n    if (!document.body.contains(this.$el)) {\n      prepForGC()\n      return\n    }\n\n    // Otherwise we can assume there's some sort of transition\n    // on the component and we wait for it to complete\n    // Note: this is obviously rough but Observer methods\n    // were performing poorly.\n    setTimeout(prepForGC, 1500)\n  }\n})\n\ntry {\n  if (navigator?.platform !== 'MacIntel') {\n    document.body.classList.add('not-mac')\n  }\n} catch {\n  // eslint-disable-next-line no-console\n  console.info('Unable to apply platform-specific scrollbar styles.')\n}\n\n// eslint-disable-next-line no-unused-vars\nlet PrefectUI\nexport const CreatePrefectUI = () => {\n  try {\n    if (\n      process.env.VUE_APP_LOG_ROCKET_PUBLIC_ID &&\n      process.env.VUE_APP_BACKEND === 'CLOUD' &&\n      store.getters['auth/user']\n    ) {\n      LogRocket.identify(store.getters['auth/user'].sub, {\n        name: store.getters['auth/user'].user.fullName,\n        email: store.getters['auth/user'].email\n      })\n    }\n  } catch (e) {\n    // eslint-disable-next-line no-console\n    console.log(e)\n  }\n\n  const loader = document.querySelector('div.loading')\n  loader.style.display = 'none'\n\n  // eslint-disable-next-line no-unused-vars\n  PrefectUI = new Vue({\n    vuetify,\n    router: createRouter(),\n    store,\n    publicPath: './',\n    apolloProvider: defaultApolloProvider,\n    render: h => h(App)\n  }).$mount('#app')\n}\n"
  },
  {
    "path": "src/assets/demo-flow/demo-flow.json",
    "content": "{\n  \"name\": \"Welcome Flow\",\n  \"type\": \"prefect.core.flow.Flow\",\n  \"schedule\": null,\n  \"parameters\": [],\n  \"tasks\": [\n    {\n      \"name\": \"Welcome\",\n      \"retry_delay\": null,\n      \"type\": \"prefect.tasks.core.function.FunctionTask\",\n      \"inputs\": {},\n      \"max_retries\": 0,\n      \"skip_on_upstream_skip\": true,\n      \"outputs\": \"typing.Any\",\n      \"trigger\": {\n        \"fn\": \"prefect.triggers.all_successful\",\n        \"kwargs\": {}\n      },\n      \"cache_key\": null,\n      \"slug\": \"welcome-task\",\n      \"tags\": [],\n      \"auto_generated\": false,\n      \"cache_for\": null,\n      \"cache_validator\": {\n        \"fn\": \"prefect.engine.cache_validators.never_use\",\n        \"kwargs\": {}\n      },\n      \"timeout\": null,\n      \"__version__\": \"0.6.1+310.gc1dc5c0a\"\n    }\n  ],\n  \"edges\": [],\n  \"reference_tasks\": [],\n  \"environment\": {\n    \"executor\": \"prefect.engine.executors.LocalExecutor\",\n    \"executor_kwargs\": {},\n    \"__version__\": \"0.6.1+310.gc1dc5c0a\",\n    \"type\": \"RemoteEnvironment\"\n  },\n  \"__version__\": \"0.6.1+310.gc1dc5c0a\",\n  \"storage\": {\n    \"prefect_version\": \"master\",\n    \"image_name\": \"flows\",\n    \"registry_url\": \"prefecthq\",\n    \"image_tag\": \"welcome-flow\",\n    \"flows\": {\n      \"Welcome Flow\": \"/root/.prefect/welcome-flow.prefect\"\n    },\n    \"__version__\": \"0.6.1+310.gc1dc5c0a\",\n    \"type\": \"Docker\"\n  }\n}\n"
  },
  {
    "path": "src/assets/fonts/prefect-icons/style.scss",
    "content": "@import 'variables';\n\n@font-face {\n  font-display: block;\n  font-family: '#{$prefect-font-family}';\n  font-style: normal;\n  font-weight: normal;\n\n  // stylelint-disable\n  src: url('#{$prefect-font-path}/#{$prefect-font-family}.eot?higzvn');\n  src: url('#{$prefect-font-path}/#{$prefect-font-family}.eot?higzvn#iefix')\n      format('embedded-opentype'),\n    url('#{$prefect-font-path}/#{$prefect-font-family}.ttf?higzvn')\n      format('truetype'),\n    url('#{$prefect-font-path}/#{$prefect-font-family}.woff?higzvn')\n      format('woff'),\n    url('#{$prefect-font-path}/#{$prefect-font-family}.svg?higzvn##{$prefect-font-family}')\n      format('svg');\n  // stylelint-enable\n}\n\n[class^='pi-'],\n[class*=' pi-'] {\n  /* use !important to prevent issues with browser extensions that change fonts */\n  font-family: '#{$prefect-font-family}' !important;\n  font-size: 24px;\n\n  /* Better Font Rendering =========== */\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n\n  font-style: normal;\n  font-variant: normal;\n  font-weight: normal;\n  line-height: 1rem;\n  text-transform: none;\n}\n\n// stylelint-disable a11y/content-property-no-static-value\n.pi-agent {\n  &::before {\n    content: $pi-agent;\n  }\n}\n\n.pi-flow-run {\n  &::before {\n    content: $pi-flow-run;\n  }\n}\n\n.pi-flow {\n  &::before {\n    content: $pi-flow;\n  }\n}\n\n.pi-gantt {\n  &::before {\n    content: $pi-gantt;\n  }\n}\n\n.pi-project {\n  &::before {\n    content: $pi-project;\n  }\n}\n\n.pi-kubernetes {\n  &::before {\n    content: $pi-kubernetes;\n  }\n}\n\n.pi-schematic {\n  &::before {\n    content: $pi-schematic;\n  }\n}\n\n.pi-task-run {\n  &::before {\n    content: $pi-task-run;\n  }\n}\n\n.pi-task {\n  &::before {\n    content: $pi-task;\n  }\n}\n\n.pi-lg {\n  font-size: 1.33333em !important;\n  line-height: 0.75em;\n  vertical-align: -0.0667em;\n}\n\n.pi-xs {\n  font-size: 0.75em !important;\n}\n\n.pi-sm {\n  font-size: 0.875em !important;\n}\n\n.pi-1x {\n  font-size: 1em !important;\n}\n\n.pi-2x {\n  font-size: 2em !important;\n}\n\n.pi-3x {\n  font-size: 3em !important;\n}\n\n.pi-4x {\n  font-size: 4em !important;\n}\n\n.pi-5x {\n  font-size: 5em !important;\n}\n\n.pi-6x {\n  font-size: 6em !important;\n}\n\n.pi-7x {\n  font-size: 7em !important;\n}\n\n.pi-8x {\n  font-size: 8em !important;\n}\n\n.pi-9x {\n  font-size: 9em;\n}\n\n.pi-10x {\n  font-size: 10em !important;\n}\n\n.pi-fw {\n  display: inline-block;\n  height: 1em;\n  text-align: center;\n  vertical-align: -0.25em;\n  width: 1.25em;\n}\n"
  },
  {
    "path": "src/assets/fonts/prefect-icons/variables.scss",
    "content": "$prefect-font-family: 'prefect-icons' !default;\n$prefect-font-path: 'fonts' !default;\n\n$pi-agent: '\\e900';\n$pi-flow-run: '\\e901';\n$pi-flow: '\\e902';\n$pi-gantt: '\\e903';\n$pi-kubernetes: '\\e908';\n$pi-project: '\\e904';\n$pi-schematic: '\\e905';\n$pi-task-run: '\\e906';\n$pi-task: '\\e907';\n"
  },
  {
    "path": "src/auth/authentication.js",
    "content": "import { OktaAuth } from '@okta/okta-auth-js'\n\nconst {\n  VUE_APP_PUBLIC_CLIENT_ID,\n  VUE_APP_PUBLIC_ISSUER,\n  VUE_APP_ENVIRONMENT\n} = process.env\n\nconst storageTypes = ['memory', 'sessionStorage', 'cookie', 'localStorage']\n\nexport const authClient = new OktaAuth({\n  clientId: VUE_APP_PUBLIC_CLIENT_ID,\n  issuer: VUE_APP_PUBLIC_ISSUER,\n  redirectUri: window.location.origin,\n  postLogoutRedirectUri: window.location.origin + '/logout',\n  scopes: ['openid', 'profile', 'email'],\n  testing: {\n    disableHttpsCheck: VUE_APP_ENVIRONMENT !== 'production'\n  },\n  tokenManager: {\n    autoRenew: true\n  },\n  pkce: OktaAuth.features.isPKCESupported(),\n  storageManager: {\n    token: {\n      storageType: 'memory',\n      storageTypes: storageTypes,\n      useMultipleCookies: true\n    },\n    cache: {\n      storageType: 'memory',\n      storageTypes: storageTypes\n    },\n    transaction: {\n      storageType: 'sessionStorage',\n      storageTypes: storageTypes\n    }\n  }\n})\n\nauthClient.start()\n\nexport const authenticate = async () => {\n  const isLoginRedirect = await authClient.isLoginRedirect()\n  const redirectRoute = sessionStorage.getItem('redirectRoute')\n  if (isLoginRedirect) {\n    const { tokens } = await authClient.token.parseFromUrl()\n\n    authClient.tokenManager.setTokens(tokens)\n    if (redirectRoute) {\n      history.replaceState(null, null, redirectRoute)\n      sessionStorage.removeItem('redirectRoute')\n    }\n\n    return tokens\n  } else {\n    if (window.location?.pathname && !redirectRoute) {\n      sessionStorage.setItem(\n        'redirectRoute',\n        window.location.pathname + window.location.search\n      )\n    }\n  }\n\n  const tokens = await authClient.tokenManager.getTokens()\n\n  if (tokens?.idToken) {\n    if (authClient.tokenManager.hasExpired(tokens.idToken)) {\n      try {\n        const idToken = await authClient.tokenManager.renew('idToken')\n        tokens.idToken = idToken\n      } catch {\n        return await authClient.token.getWithRedirect({\n          responseType: ['token', 'id_token']\n        })\n      }\n    }\n\n    return tokens\n  }\n\n  await authClient.token.getWithRedirect({\n    responseType: ['token', 'id_token']\n  })\n}\n"
  },
  {
    "path": "src/auth/authorization.js",
    "content": "import { Client } from '@/apollo.js'\n\nconst client = Client('authorization')\n\nconst headers = {\n  'X-PREFECT-UI': true,\n  'X-Backend': 'cloud'\n}\n\nexport const authorize = async idToken => {\n  if (!idToken) {\n    throw new Error('No ID token passed to authorize')\n  }\n\n  const res = await client.mutate({\n    mutation: require('@/graphql/log-in.gql'),\n    variables: {\n      input: { id_token: idToken }\n    },\n    context: {\n      headers: headers\n    },\n    errorPolicy: 'all',\n    fetchPolicy: 'no-cache'\n  })\n\n  return res?.data?.log_in\n}\n\nexport const refreshTokens = async (accessToken, refreshToken) => {\n  if (!accessToken || !refreshToken) {\n    throw new Error('No access or refresh token passed to refreshTokens')\n  }\n\n  const res = await client.mutate({\n    mutation: require('@/graphql/refresh-token.gql'),\n    variables: {\n      input: { access_token: accessToken }\n    },\n    context: {\n      headers: {\n        ...headers,\n        authorization: `Bearer ${refreshToken}`\n      }\n    },\n    fetchPolicy: 'no-cache'\n  })\n\n  return res?.data?.refresh_token\n}\n\nexport const authorizeTenant = async (accessToken, tenantId) => {\n  if (!accessToken || !tenantId) {\n    throw new Error('No access token or no tenant id passed to authorizeTenant')\n  }\n\n  const res = await client.mutate({\n    mutation: require('@/graphql/Tenant/tenant-token.gql'),\n    variables: {\n      tenantId: tenantId\n    },\n    context: {\n      headers: {\n        ...headers,\n        authorization: `Bearer ${accessToken}`\n      }\n    },\n    fetchPolicy: 'no-cache'\n  })\n\n  return res?.data?.switch_tenant\n}\n\nexport const revokeTokens = async (accessToken, refreshToken) => {\n  if (!accessToken) {\n    throw new Error('No access token passed to revokeToken')\n  }\n\n  const res = await client.mutate({\n    mutation: require('@/graphql/log-out.gql'),\n    variables: {\n      input: { access_token: accessToken }\n    },\n    context: {\n      headers: {\n        ...headers,\n        authorization: `Bearer ${refreshToken}`\n      }\n    },\n    errorPolicy: 'all',\n    fetchPolicy: 'no-cache'\n  })\n\n  return res?.data?.success\n}\n"
  },
  {
    "path": "src/auth/index.js",
    "content": "import { promiseChannel } from '@/workers/util/worker-interface.js'\nimport { authenticate, authClient } from '@/auth/authentication.js'\nimport {\n  authorize,\n  authorizeTenant,\n  refreshTokens,\n  revokeTokens\n} from '@/auth/authorization.js'\n\nimport store from '@/store'\nimport LogRocket from 'logrocket'\n\nimport jwt_decode from 'jwt-decode'\n\nlet TokenWorker\nif (typeof window.SharedWorker !== 'undefined') {\n  // // Initializes the shared service worker that handles token refresh\n  TokenWorker = new SharedWorker('@/workers/auth.worker.js', {\n    type: 'module'\n  })\n} else {\n  // eslint-disable-next-line no-console\n  console.log(\n    \"Shared service worker couldn't be registered, falling back to legacy auth pattern.\"\n  )\n  // workers aren't supported; we'll fall back to the legacy auth pattern\n}\n\nif (TokenWorker?.port) {\n  TokenWorker.port.onmessage = async e => {\n    const type = e.data?.type\n    const payload = e.data?.payload\n\n    // console.log(type, payload)\n\n    switch (type) {\n      case 'idToken':\n        commitTokens({ idToken: payload })\n        break\n      case 'authorizationToken':\n        commitTokens({ authorizationTokens: payload })\n        break\n      case 'clear':\n        authClient.tokenManager.clear()\n        unsetTokens()\n        authClient.signOut()\n        break\n      case 'logout':\n        authClient.signOut()\n        unsetTokens()\n        break\n      case 'switch-tenant':\n        if (\n          store.getters['tenant/tenant']?.id !== payload.tenantId &&\n          !store.getters['tenant/isLoadingTenant'] &&\n          !window.location.pathname?.includes('team-switched')\n        ) {\n          window.location.href = '/team-switched'\n        } else {\n          if (process.env.VUE_APP_BACKEND === 'CLOUD') {\n            store.dispatch('license/getLicense')\n          }\n        }\n        break\n      case 'accessDenied':\n        await authClient.signOut({\n          clientId: process.env.VUE_APP_PUBLIC_CLIENT_ID,\n          idToken: payload,\n          postLogoutRedirectUri:\n            window.location.origin + '/access-denied?reason=invalid_sso'\n        })\n        break\n      case 'console':\n        // This should only be used for debugging\n        // eslint-disable-next-line no-console\n        // console.log('TokenWorker console', payload)\n        LogRocket.track('TokenWorker console', payload)\n        break\n      case 'error':\n        // eslint-disable-next-line no-console\n        console.log('TokenWorker error', payload)\n        LogRocket.captureException(payload)\n        break\n      default:\n        // This should only be used for debugging\n        // eslint-disable-next-line no-console\n        // console.log('default', payload)\n        LogRocket.track('TokenWorker Message', payload)\n        break\n    }\n  }\n\n  TokenWorker.onerror = e => {\n    // eslint-disable-next-line no-console\n    console.log('Error message received from Token Worker', e)\n    LogRocket.captureException(e)\n  }\n\n  TokenWorker.port.start()\n}\n\nexport { TokenWorker }\n\nexport const commitTokens = tokens => {\n  if (!tokens) return\n\n  if (tokens.idToken) {\n    const idToken = tokens.idToken\n\n    store.commit('auth/idToken', idToken.idToken)\n    store.commit('auth/idTokenExpiry', idToken.expiresAt * 1000)\n    store.commit('auth/user', idToken.claims)\n    store.commit('user/setOktaUser', idToken.claims)\n  }\n\n  if (tokens.authorizationTokens) {\n    const authToken = tokens.authorizationTokens.access_token\n    const expiry = new Date(tokens.authorizationTokens.expires_at).getTime()\n    const refreshToken = tokens.authorizationTokens.refresh_token\n\n    store.commit('auth/authorizationToken', authToken)\n    store.commit('auth/refreshToken', refreshToken)\n\n    store.commit('auth/authorizationTokenExpiry', expiry)\n    store.commit('auth/refreshTokenExpiry', jwt_decode(refreshToken).exp * 1000)\n  }\n}\n\nexport const unsetTokens = () => {\n  store.commit('auth/unsetIdToken')\n  store.commit('auth/unsetIdTokenExpiry')\n  store.commit('auth/unsetUser')\n  store.commit('auth/unsetAuthorizationToken')\n  store.commit('auth/unsetAuthorizationTokenExpiry')\n  store.commit('auth/unsetRefreshToken')\n  store.commit('auth/unsetRefreshTokenExpiry')\n}\n\nlet refreshTimeout\nconst refresh = tokens => {\n  clearTimeout(refreshTimeout)\n  const expiration = new Date(tokens.expires_at)\n  const timeout = ((expiration - Date.now()) * 3) / 4\n  refreshTimeout = setTimeout(async () => {\n    const refreshedTokens = await refreshTokens(\n      tokens.access_token,\n      tokens.refresh_token\n    )\n    commitTokens({ authorizationTokens: refreshedTokens })\n    refresh(refreshedTokens)\n  }, timeout || 15000)\n}\n\nauthClient.tokenManager.on('renewed', (key, idToken) => {\n  if (key === 'idToken' && idToken) {\n    commitTokens({ idToken: idToken })\n\n    if (TokenWorker) {\n      TokenWorker.port.postMessage({\n        type: 'idToken',\n        payload: idToken\n      })\n    }\n  }\n})\n\nexport const login = async (fallback = false) => {\n  // try getting a token from the service worker\n  // if we have a service worker, ping that for a token\n  // otherwise we go through the okta login process directly\n  let idToken, authorizationTokens, source\n  try {\n    if (TokenWorker && !fallback) {\n      idToken = await promiseChannel(TokenWorker, 'login')\n      source = 'TokenWorker'\n\n      if (!idToken || idToken.expiresAt * 1000 < Date.now()) {\n        const loginResponse = await authenticate()\n\n        idToken = loginResponse?.idToken\n        source = 'AuthClient <> TokenWorker'\n\n        TokenWorker.port.postMessage({\n          type: 'idToken',\n          payload: idToken\n        })\n      }\n\n      if (idToken && (idToken.idToken || idToken.value)) {\n        authorizationTokens = await promiseChannel(\n          TokenWorker,\n          'authorize',\n          idToken.idToken || idToken.value\n        )\n      }\n    } else {\n      const loginResponse = await authenticate()\n\n      source = 'AuthClient <> InMemory'\n      idToken = loginResponse?.idToken\n\n      if (idToken && (idToken.idToken || idToken.value)) {\n        authorizationTokens = await authorize(idToken.idToken || idToken.value)\n        refresh(authorizationTokens)\n      }\n    }\n  } catch (e) {\n    // eslint-disable-next-line no-console\n    console.error('Login error', e)\n    LogRocket.captureException(e)\n  }\n\n  if (idToken && authorizationTokens) {\n    return {\n      idToken: idToken,\n      authorizationTokens: authorizationTokens,\n      source: source\n    }\n  } else {\n    // If this session fails to get idTokens, we call the clear method\n    // to post messages to all other sessions that they need to sign out\n    // This also clears all stored tokens for these sessions\n    if (TokenWorker) {\n      TokenWorker.port.postMessage({\n        type: 'clear'\n      })\n    }\n  }\n}\n\nexport const switchTenant = async tenantId => {\n  let authorizationTokens\n\n  if (TokenWorker) {\n    authorizationTokens = await promiseChannel(\n      TokenWorker,\n      'switch-tenant',\n      tenantId\n    )\n  } else {\n    authorizationTokens = await authorizeTenant(\n      store.getters['auth/authorizationToken'],\n      tenantId\n    )\n  }\n\n  return {\n    authorizationTokens: authorizationTokens\n  }\n}\n\nexport const logout = async () => {\n  await revokeTokens(\n    store.getters['auth/authorizationToken'],\n    store.getters['auth/refreshToken']\n  )\n\n  if (TokenWorker) {\n    TokenWorker.port.postMessage({\n      type: 'logout'\n    })\n  } else {\n    try {\n      await authClient.signOut()\n      unsetTokens()\n    } catch (e) {\n      // eslint-disable-next-line no-console\n      console.log(e)\n      LogRocket.captureException(e)\n    }\n  }\n}\n"
  },
  {
    "path": "src/components/AcceptConfirmInputRow.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nexport default {\n  props: {\n    label: {\n      type: String,\n      default: ''\n    },\n    loading: {\n      type: Boolean,\n      default: false\n    },\n    tooltips: {\n      type: Boolean,\n      default: false\n    }\n  },\n  data() {\n    return {\n      confirm: false\n    }\n  },\n  methods: {\n    accept() {\n      this.$emit('accept')\n    },\n    decline() {\n      this.$emit('decline')\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div v-if=\"!confirm\" class=\"d-flex align-center justify-space-between\">\n      <div class=\"text-truncate\" v-html=\"label\"></div>\n      <div class=\"text-right\">\n        <v-tooltip :disabled=\"!tooltips\" bottom\n          ><template #activator=\"{on}\"\n            ><v-btn\n              color=\"primary\"\n              data-cy=\"choose-tenant\"\n              text\n              v-on=\"on\"\n              @click=\"confirm = 'accept'\"\n            >\n              <v-icon>\n                check\n              </v-icon>\n            </v-btn></template\n          >Accept team invite</v-tooltip\n        >\n\n        <v-tooltip :disabled=\"!tooltips\" bottom\n          ><template #activator=\"{on}\"\n            ><v-btn color=\"error\" text v-on=\"on\" @click=\"confirm = 'decline'\">\n              <v-icon>\n                close\n              </v-icon>\n            </v-btn></template\n          >Decline team invite</v-tooltip\n        >\n      </div>\n    </div>\n\n    <div v-else>\n      <v-row no-gutters>\n        <v-col cols=\"9\">\n          <v-btn\n            v-if=\"confirm == 'accept'\"\n            data-cy=\"accept-invitation\"\n            color=\"primary\"\n            block\n            text\n            :loading=\"loading\"\n            outlined\n            @click=\"accept\"\n          >\n            Accept\n          </v-btn>\n          <v-btn\n            v-if=\"confirm == 'decline'\"\n            color=\"error\"\n            block\n            :loading=\"loading\"\n            text\n            outlined\n            @click=\"decline\"\n          >\n            Decline\n          </v-btn>\n        </v-col>\n        <v-col cols=\"3\" class=\"px-1\">\n          <v-btn v-if=\"!!confirm\" block text @click=\"confirm = false\">\n            <v-icon small>close</v-icon>\n          </v-btn>\n        </v-col>\n      </v-row>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.cancel-button {\n  position: absolute;\n  right: 0;\n  top: 0;\n}\n</style>\n"
  },
  {
    "path": "src/components/Alert.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nimport { mapMutations } from 'vuex'\n\nexport default {\n  props: {\n    // Position the alert at the bottom of the screen.\n    bottom: {\n      type: Boolean,\n      required: false,\n      default: () => true\n    },\n    // Set dark theme\n    dark: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    // Set light theme\n    light: {\n      type: Boolean,\n      required: false,\n      default: () => true\n    },\n    // Specify the message to display on the alert.\n    message: {\n      type: String,\n      required: true\n    },\n    alertLink: {\n      type: Object,\n      required: false,\n      default: null\n    },\n    nudgeBottom: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    linkText: {\n      type: String,\n      required: false,\n      default: 'See Details'\n    },\n    alertCopy: {\n      type: String,\n      required: false,\n      default: ''\n    },\n    // Move snackbar in the X direction by updating left/right margins.\n    offsetX: {\n      type: Number,\n      required: false,\n      default: () => 0\n    },\n    // Set the alert to disappear after a specified number of milliseconds.\n    // Set this to 0 to render indefinitely (until the alert is closed by the user).\n    timeout: {\n      type: Number,\n      required: false,\n      default: () => 6000\n    },\n    // Position the alert at the top of the screen.\n    top: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    // Position the alert at the right of the screen.\n    right: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    // Position the alert at the left of the screen.\n    left: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    // Specify the type of alert (error, info, success, etc.)\n    type: {\n      type: String,\n      required: false,\n      default: () => 'info'\n    },\n    // Prop that allows users to set v-model on the alert.\n    value: {\n      type: Boolean,\n      required: true\n    }\n  },\n  data() {\n    return {\n      internalValue: this.value,\n      timeoutId: null\n    }\n  },\n  watch: {\n    value(val) {\n      // Keep the internal state of the alert on par with the value prop.\n      this.internalValue = val\n      // If the alert is being displayed and a timeout is specified,\n      // make the alert disappear after this.timeout milliseconds.\n      if (this.internalValue && this.timeout) {\n        if (this.timeoutId) clearTimeout(this.timeoutId)\n        this.timeoutId = setTimeout(this.handleDismiss, this.timeout)\n      }\n    }\n  },\n  methods: {\n    ...mapMutations('alert', ['setEmpty']),\n    emitInternalValue() {\n      this.$emit('input', this.internalValue)\n    },\n    handleDismiss() {\n      this.setEmpty()\n      this.internalValue = false\n      this.emitInternalValue()\n    },\n    // Propagate the internal notification value to the component's parent.\n    // This method is what allows us to set v-model on this component.\n    handleInput() {\n      this.emitInternalValue()\n    },\n    copyText(value) {\n      this.copiedText = {}\n      this.copiedText[value] = true\n      navigator.clipboard.writeText(value)\n\n      setTimeout(() => {\n        this.copiedText = {}\n        this.copiedText[value] = false\n      }, 600)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-snackbar\n    :top=\"top\"\n    :bottom=\"bottom\"\n    :right=\"right\"\n    :left=\"left\"\n    :value=\"internalValue\"\n    :timeout=\"-1\"\n    color=\"appBackground\"\n    :style=\"{\n      'margin-left': offsetX > 0 ? `${offsetX}px` : '0',\n      'margin-right': offsetX < 0 ? `${Math.abs(offsetX)}px` : '0',\n      'margin-bottom': nudgeBottom ? '64px' : '0'\n    }\"\n    @input=\"handleInput\"\n  >\n    <v-icon v-if=\"type == 'error'\" class=\"mr-4\" color=\"red\">warning</v-icon>\n\n    <span class=\"text-subtitle-1 utilGrayDark--text\" v-html=\"message\"> </span>\n\n    <template #action>\n      <v-btn v-if=\"alertLink\" color=\"pink\" text :to=\"alertLink\">\n        <span>{{ linkText }}</span>\n      </v-btn>\n      <v-btn v-if=\"alertCopy\" color=\"pink\" text @click=\"copyText(alertCopy)\">\n        Copy\n      </v-btn>\n      <v-btn :color=\"type\" text @click=\"handleDismiss\">\n        Dismiss\n      </v-btn>\n    </template>\n  </v-snackbar>\n</template>\n"
  },
  {
    "path": "src/components/Artifacts/Artifact-NodeTree.vue",
    "content": "<script>\nexport default {\n  props: {\n    depth: {\n      type: Number,\n      required: false,\n      default: () => 0\n    },\n    id: {\n      type: String,\n      required: true\n    },\n    label: {\n      type: String,\n      required: false,\n      default: null\n    },\n    nodes: {\n      type: Array,\n      required: false,\n      default: () => []\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div>\n      {{ label }}\n    </div>\n    <ArtifactNodeTree\n      v-for=\"node in nodes\"\n      :id=\"node.id\"\n      :key=\"node.id\"\n      :depth=\"depth + 1\"\n      :label=\"node.label\"\n      :nodes=\"nodes.nodes\"\n    />\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/Artifacts/Artifact.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nimport ExternalLink from '@/components/ExternalLink'\nimport { artifact_parser } from '@/utils/markdownParser'\nimport '@/styles/atelier-sulphurpool-light.scss'\n\nconst httpRegex = /^(http|https)/\n\nexport default {\n  components: { ExternalLink },\n  props: {\n    artifact: {\n      type: Object,\n      required: true\n    }\n  },\n  computed: {\n    isRelativeLink() {\n      return !httpRegex.test(this.artifact.data?.link)\n    }\n  },\n  methods: {\n    mdParser(md) {\n      return artifact_parser(md)\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    v-if=\"artifact.kind == 'md' || artifact.kind == 'markdown'\"\n    class=\"artifact md utilGrayDark--text mx-4\"\n    v-html=\"mdParser(artifact.data.markdown)\"\n  >\n  </div>\n  <div v-else-if=\"artifact.kind == 'link'\">\n    <router-link v-if=\"isRelativeLink\" :to=\"{ path: artifact.data.link }\">\n      {{ artifact.data.link }}\n    </router-link>\n    <ExternalLink v-else :href=\"artifact.data.link\">\n      {{ artifact.data.link }}\n    </ExternalLink>\n  </div>\n  <div v-else>\n    {{ artifact }}\n  </div>\n</template>\n\n<style lang=\"scss\">\n.artifact {\n  margin-top: 0;\n\n  .table-wrapper {\n    max-height: 400px;\n  }\n\n  table {\n    border: 1px solid rgb(176, 190, 197) !important;\n    border-collapse: collapse;\n    border-color: rgb(176, 190, 197) !important;\n  }\n\n  td {\n    padding: 4px 8px;\n  }\n\n  thead {\n    th:not(:empty) {\n      border-bottom: thin solid rgba(0, 0, 0, 0.12);\n      border-top: 1px solid rgb(176, 190, 197);\n      font-size: 1rem;\n      padding: 4px 8px;\n      position: sticky;\n      text-align: left;\n      top: 0;\n      z-index: 1;\n    }\n\n    th:first-of-type {\n      border-left: thin solid rgb(176, 190, 197);\n    }\n\n    th:last-of-type {\n      border-right: thin solid rgb(176, 190, 197);\n    }\n  }\n\n  tbody {\n    tr:not(:empty) {\n      border: 1px solid rgb(176, 190, 197);\n      border-bottom: thin solid rgba(0, 0, 0, 0.12);\n      transition: background-color 50ms ease-in-out;\n\n      &:focus,\n      &:hover {\n        background-color: rgba(0, 0, 0, 0.05);\n      }\n    }\n\n    tr:last-of-type:not(:empty) {\n      border-bottom: 1px solid rgb(176, 190, 197);\n    }\n  }\n\n  h1:first-of-type {\n    margin-top: 0 !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Artifacts/Artifacts.vue",
    "content": "<script>\nimport Artifact from '@/components/Artifacts/Artifact'\n\nexport default {\n  components: {\n    Artifact\n  },\n  props: {\n    flowRunId: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    taskRunIds: {\n      type: Array,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      artifact: null,\n      expanded: [],\n      loadingKey: 0\n    }\n  },\n  computed: {\n    loading() {\n      return !this.artifacts && this.loadingKey > 0\n    },\n    taskRunIds_() {\n      return this.taskRunIds || this.ids\n    }\n  },\n  methods: {\n    decrement() {\n      this.artifact--\n    },\n    increment() {\n      this.artifact++\n    }\n  },\n  apollo: {\n    artifacts: {\n      query: require('@/graphql/Artifacts/task-run-artifacts.gql'),\n      variables() {\n        return {\n          taskRunIds: this.taskRunIds_\n        }\n      },\n      skip() {\n        return !this.taskRunIds_\n      },\n      loadingKey: 'loadingKey',\n      pollInterval: 10000,\n      update: data =>\n        [...(data.task_run_artifact || [])].sort(\n          (a, b) => new Date(a.created) - new Date(b.created)\n        )\n    },\n    ids: {\n      query: require('@/graphql/Artifacts/task-run-ids.gql'),\n      variables() {\n        return {\n          where: {\n            flow_run_id: { _eq: this.flowRunId }\n          },\n          limit: null, // We'll introduce limits and offsets later when we begin server-side pagination for artifacts\n          offset: null\n        }\n      },\n      skip() {\n        return this.taskRunIds\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.task_run?.map(t => t.id) || null\n    }\n  }\n}\n</script>\n\n<template>\n  <v-row no-gutters>\n    <v-col>\n      <div\n        v-if=\"artifacts && artifacts.length > 0\"\n        class=\"d-flex align-center justify-center\"\n      >\n        <v-btn icon :disabled=\"artifact == 0\" @click=\"decrement\">\n          <v-icon large>arrow_left</v-icon>\n        </v-btn>\n        <v-item-group v-model=\"artifact\" class=\"text-center my-2\" mandatory>\n          <v-item\n            v-for=\"a in artifacts\"\n            :key=\"a.id\"\n            v-slot=\"{ active, toggle }\"\n          >\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn :input-value=\"active\" icon @click=\"toggle\" v-on=\"on\">\n                  <v-icon :x-large=\"active\" color=\"primary\">\n                    fiber_manual_record\n                  </v-icon>\n                  <v-scale-transition>\n                    <v-icon\n                      v-if=\"active\"\n                      color=\"white\"\n                      class=\"position-absolute center-absolute\"\n                    >\n                      fingerprint\n                    </v-icon>\n                  </v-scale-transition>\n                </v-btn>\n              </template>\n              <div>\n                <div class=\"text-h6\">\n                  {{ a.task_run.task.name }}\n                </div>\n                <div v-if=\"a.task_run.name\" class=\"text-subtitle-1\">\n                  {{ a.task_run.name }}\n                </div>\n              </div>\n            </v-tooltip>\n          </v-item>\n        </v-item-group>\n        <v-btn\n          icon\n          :disabled=\"!artifacts || artifact == artifacts.length - 1\"\n          @click=\"increment\"\n        >\n          <v-icon large>arrow_right</v-icon>\n        </v-btn>\n      </div>\n      <div v-else-if=\"loading\" class=\"position-absolute center-absolute\">\n        <v-progress-circular\n          v-if=\"loading\"\n          color=\"primary\"\n          indeterminate\n          size=\"150\"\n          width=\"10\"\n        />\n      </div>\n      <div\n        v-else\n        class=\"text-center position-absolute center-absolute text-h5 utilGrayDark--text\"\n        style=\"z-index: 1;\"\n      >\n        This run has no\n        <span class=\"font-weight-medium\">\n          <v-icon x-small color=\"primary\" class=\"ml-1\">\n            fas fa-fingerprint\n          </v-icon>\n          Artifacts</span\n        >! You can learn how to generate artifacts from your flow/task in the\n        <a\n          href=\"https://docs.prefect.io/api/latest/backend/artifacts.html\"\n          target=\"_blank\"\n        >\n          Artifacts API Docs</a\n        >.\n      </div>\n\n      <v-window v-model=\"artifact\" class=\"artifact-container\">\n        <v-window-item\n          v-for=\"a in artifacts\"\n          :key=\"a.id\"\n          class=\"h-100\"\n          transition=\"quick-fade\"\n          reverse-transition=\"quick-fade\"\n        >\n          <v-card class=\"artifact-card pa-0\" flat outlined>\n            <v-card-title class=\"artifact-card-title\">\n              <div class=\"position-relative\">\n                <v-icon x-large color=\"primary\">fiber_manual_record</v-icon>\n                <v-icon\n                  class=\"position-absolute center-absolute\"\n                  small\n                  color=\"white\"\n                >\n                  fas fa-fingerprint\n                </v-icon>\n              </div>\n              <div>\n                <div\n                  class=\"text-overline utilGrayMid--text\"\n                  style=\"line-height: 1rem;\"\n                >\n                  Artifact\n                </div>\n                <div class=\"text-h4\">\n                  {{ a.task_run.name ? a.task_run.name : a.task_run.task.name }}\n                </div>\n              </div>\n            </v-card-title>\n            <v-card-text class=\"pt-10\">\n              <v-fade-transition mode=\"out-in\">\n                <Artifact :artifact=\"a\" />\n              </v-fade-transition>\n            </v-card-text>\n          </v-card>\n        </v-window-item>\n      </v-window>\n    </v-col>\n  </v-row>\n</template>\n\n<style lang=\"scss\" scoped>\n.artifact-container {\n  height: calc(100vh - 400px);\n  min-height: 400px;\n}\n\n.artifact-card {\n  height: auto;\n  max-height: 100%;\n  overflow: scroll;\n  position: relative;\n  transition: height 250ms ease-in-out;\n\n  .artifact-card-title {\n    background-color: var(--v-appForeground-base);\n    position: sticky;\n    top: 0;\n    z-index: 2;\n    box-shadow: 0 2px 4px -1px rgb(0 0 0 / 20%), 0 4px 5px 0 rgb(0 0 0 / 14%),\n      0 1px 10px 0 rgb(0 0 0 / 12%) !important;\n  }\n}\n\n.artifact-selector {\n  max-height: calc(100%);\n}\n\n.h-100 {\n  height: 100%;\n}\n\n.center-absolute {\n  left: 50%;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n</style>\n"
  },
  {
    "path": "src/components/BreadCrumbs.vue",
    "content": "<script>\nexport default {\n  props: {\n    crumbs: {\n      type: Array,\n      required: true\n    }\n  }\n}\n</script>\n\n<template>\n  <span>\n    <span v-for=\"crumb in crumbs\" :key=\"crumb.text\">\n      <RouterLink\n        class=\"link\"\n        :to=\"crumb.route\"\n        :data-cy=\"'breadcrum-link|' + crumb.text\"\n      >\n        {{ crumb.text }}\n      </RouterLink>\n      <v-icon small class=\"arrow-position\">\n        chevron_right\n      </v-icon>\n    </span>\n  </span>\n</template>\n\n<style lang=\"scss\" scoped>\n.arrow-position {\n  bottom: 1px;\n  position: relative;\n}\n</style>\n"
  },
  {
    "path": "src/components/CancelButton.vue",
    "content": "<script>\nimport { changeStateMixin } from '@/mixins/changeStateMixin'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  mixins: [changeStateMixin],\n  computed: {\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return !this.hasPermission('update', 'run')\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-if=\"dialogType == 'flow run'\">\n    <v-tooltip bottom>\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <v-btn\n            color=\"red darken-3\"\n            class=\"vertical-button white--text\"\n            :style=\"{ height: '46px' }\"\n            :disabled=\"!checkVersion || permissionsCheck || isFinishing\"\n            text\n            small\n            depressed\n            :loading=\"cancelLoad\"\n            @click=\"cancelFlowRun\"\n          >\n            <v-icon>not_interested</v-icon>\n            Cancel\n          </v-btn>\n        </div>\n      </template>\n      <span v-if=\"permissionsCheck\">\n        You don't have permission to modify runs.\n      </span>\n      <span v-else-if=\"!checkVersion\">\n        Your Flow was registered with version {{ flowRun.flow.core_version }} of\n        Prefect Core; please upgrade to version 0.13.0 or higher and re-register\n        your Flow to enable cancellation.\n      </span>\n      <span v-else-if=\"isFinishing\"\n        >This flow run has concluded so it can't be cancelled.</span\n      >\n      <span v-else>Cancel this flow run.</span>\n    </v-tooltip>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/Card-Title.vue",
    "content": "<script>\nexport default {\n  props: {\n    icon: {\n      type: String,\n      required: false,\n      default: () => ''\n    },\n    params: {\n      type: Object,\n      required: false,\n      default: () => {}\n    },\n    iconClass: {\n      type: String,\n      required: false,\n      default: () => ''\n    },\n    iconColor: {\n      type: String,\n      required: false,\n      default: () => ''\n    },\n    loading: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    subtitle: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    title: {\n      type: String,\n      required: false,\n      default: () => ''\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-list-item dense class=\"px-0\" :to=\"params\">\n      <v-list-item-avatar class=\"mr-2\" tile>\n        <div v-if=\"$slots['icon']\">\n          <slot name=\"icon\" />\n        </div>\n        <v-icon v-else :color=\"iconColor\" :class=\"iconClass\">\n          {{ icon }}\n        </v-icon>\n      </v-list-item-avatar>\n      <v-list-item-content class=\"position: relative;\">\n        <v-list-item-title class=\"text-h6 pb-1 \" style=\"max-width: 23vw;\">\n          <div v-if=\"$slots['title']\" class=\"text-truncate\">\n            <slot name=\"title\" />\n          </div>\n          <div v-else>\n            <div v-if=\"!loading\" class=\"text-truncate\">\n              {{ title }}\n            </div>\n            <v-skeleton-loader v-else type=\"heading\" tile></v-skeleton-loader>\n          </div>\n          <div class=\"action-slot d-flex align-center justify-end\">\n            <slot name=\"state-filter\" />\n            <slot name=\"action\" />\n          </div>\n        </v-list-item-title>\n        <div\n          v-if=\"$slots['subtitle'] || subtitle\"\n          class=\"text-subtitle-2 utilGrayDark--text text-caption position-absolute font-weight-medium\"\n          style=\"bottom: 2px;\"\n        >\n          <slot v-if=\"$slots['subtitle']\" name=\"subtitle\" />\n          <div v-else>{{ subtitle }}</div>\n        </div>\n\n        <v-list-item-subtitle v-if=\"$slots['badge']\">\n          <slot name=\"badge\" />\n        </v-list-item-subtitle>\n      </v-list-item-content>\n    </v-list-item>\n\n    <v-divider class=\"ml-12 mr-2\"></v-divider>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.action-slot {\n  height: 100%;\n  position: absolute;\n  right: 0;\n  top: 0;\n}\n</style>\n"
  },
  {
    "path": "src/components/ChartCard/ChartCard.vue",
    "content": "<script>\nimport RingChartHeader from '@/components/ChartCard/ChartCardHeader-Ring'\nimport SimpleChartHeader from '@/components/ChartCard/ChartCardHeader-Simple'\n\nexport default {\n  components: {\n    RingChartHeader,\n    SimpleChartHeader\n  },\n  props: {\n    accentColor: {\n      type: String,\n      default: () => 'rgb(39, 177, 255)'\n    },\n    title: { type: String, default: () => '' },\n    subtitle: { type: String, default: () => '' },\n    body: { type: String, default: () => '' },\n    chartType: { type: String, default: () => null },\n    chartOverlayMain: { type: String, default: () => null },\n    chartOverlayUnits: { type: String, default: () => null },\n    chartOverlayOverline: { type: String, default: () => null },\n    chartOverlaySub: { type: String, default: () => null },\n    chartOverlayCenter: { type: String, default: () => 'check' },\n    chartOverlayCenterTwo: { type: String, default: () => '' },\n    chartOverlayCenterType: { type: String, default: () => 'icon' },\n    chartData: { type: Array, default: () => [] },\n    extra: { type: Boolean, default: true },\n    colors: { type: Array, default: () => null }\n  },\n  computed: {\n    chartStyle() {\n      return {\n        'background-color': this.accentColor,\n        color: '#fff'\n      }\n    },\n    mainContainer() {\n      return this.extra ? 'main-container' : 'no-extra-container'\n    },\n    overlayStyle() {\n      return {\n        left: this.$vuetify.breakpoint.mdAndUp ? '25px' : '0',\n        top: this.$vuetify.breakpoint.mdAndUp ? '25px' : '0',\n        width: this.$vuetify.breakpoint.mdAndUp ? '25%' : '20%',\n        'text-align': this.$vuetify.breakpoint.smAndDown ? 'center' : 'right'\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container ref=\"mainContainer\" :class=\"mainContainer\" class=\"relative\">\n    <RingChartHeader\n      v-if=\"chartType == 'ring'\"\n      :chart-data=\"chartData\"\n      :chart-overlay-main=\"chartOverlayMain\"\n      :chart-overlay-units=\"chartOverlayUnits\"\n      :chart-overlay-overline=\"chartOverlayOverline\"\n      :chart-overlay-sub=\"chartOverlaySub\"\n      :chart-overlay-center=\"chartOverlayCenter\"\n      :chart-overlay-center-two=\"chartOverlayCenterTwo\"\n      :chart-overlay-center-type=\"chartOverlayCenterType\"\n      :accent-color=\"accentColor\"\n      :colors=\"colors\"\n    />\n\n    <SimpleChartHeader\n      v-if=\"chartType == 'simple'\"\n      :chart-overlay-main=\"chartOverlayMain\"\n      :chart-overlay-overline=\"chartOverlayOverline\"\n      :chart-overlay-sub=\"chartOverlaySub\"\n      :chart-overlay-center=\"chartOverlayCenter\"\n      :accent-color=\"accentColor\"\n    />\n\n    <v-container\n      v-if=\"extra\"\n      class=\"absolute box text-box d-flex flex-column pa-8\"\n    >\n      <v-row no-gutters align=\"end\" justify=\"start\">\n        <v-col cols=\"12\">\n          <div class=\"text-overline grey--text\">\n            {{ subtitle }}\n          </div>\n\n          <div\n            class=\"text-h4\"\n            :class=\"$vuetify.breakpoint.mdAndUp ? 'text-h4' : 'text-h5'\"\n          >\n            {{ title }}\n          </div>\n          <div v-if=\"!!body\" class=\"text-body-2\">\n            {{ body }}\n          </div>\n          <div v-else-if=\"title === 'Users'\" class=\"text-body-2\">\n            Invited users and actual members count towards your users total. You\n            can add and remove members and invitations in the\n            <router-link :to=\"'/team/members'\">\n              team-members\n            </router-link>\n            page.\n          </div>\n          <div v-else-if=\"title === 'Flows'\" class=\"text-body-2\">\n            Different versions all count as one flow. You can view and manage\n            the flows that count towards your total on the\n            <router-link :to=\"{ name: 'flow-version-groups' }\">\n              flow version groups\n            </router-link>\n            page.\n          </div>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.relative {\n  position: relative;\n}\n\n.absolute {\n  position: absolute;\n}\n\n.main-container {\n  min-height: 400px;\n  text-align: left;\n  width: 100%;\n}\n\n.no-extra-container {\n  min-height: 250px;\n  text-align: left;\n  width: 100%;\n}\n\n.container {\n  .box {\n    border-radius: 4px;\n\n    &.chart-box {\n      left: 50%;\n      top: 0;\n      transform: translate(-50%);\n      width: 87.5%;\n      z-index: 2;\n\n      .overlay {\n        color: #fff;\n        text-align: right;\n      }\n\n      .overlay-center {\n        left: 50%;\n        text-align: center;\n        top: 50%;\n        transform: translate(-50%, -50%);\n        width: 25%;\n      }\n\n      .v-icon {\n        color: rgba(255, 255, 255, 0.4);\n        font-size: 6em !important;\n      }\n    }\n\n    &.text-box {\n      background-color: #fff;\n      bottom: 0;\n      height: 67.5%;\n      left: 50%;\n      top: 25px;\n      transform: translate(-50%, 50%);\n      width: 90%;\n      z-index: 1;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/ChartCard/ChartCardHeader-Ring.vue",
    "content": "<script>\nimport RingChart from '@/components/Visualizations/RingChart'\n\nexport default {\n  components: {\n    RingChart\n  },\n  props: {\n    accentColor: {\n      type: String,\n      default: () => 'rgb(39, 177, 255)'\n    },\n    chartOverlayMain: { type: String, default: () => null },\n    chartOverlayUnits: { type: String, default: () => null },\n    chartOverlayOverline: { type: String, default: () => null },\n    chartOverlaySub: { type: String, default: () => null },\n    chartOverlayCenter: { type: String, default: () => 'check' },\n    chartOverlayCenterTwo: { type: String, default: () => '' },\n    chartOverlayCenterType: { type: String, default: () => 'icon' },\n    chartData: { type: Array, default: () => [] },\n    colors: { type: Array, default: () => null }\n  },\n  computed: {\n    notMobile() {\n      if (this.$vuetify.breakpoint.xs) return false\n      return true\n    },\n    chartStyle() {\n      return {\n        'background-color': this.accentColor,\n        color: '#fff'\n      }\n    },\n    overlayStyle() {\n      return {\n        left: 0,\n        width: this.$vuetify.breakpoint.lgAndUp ? '25%' : '20%',\n        'text-align': this.$vuetify.breakpoint.mdAndDown ? 'left' : 'right'\n      }\n    },\n    mainClasses() {\n      return {\n        'text-h3': this.$vuetify.breakpoint.lgAndUp,\n        'text-h4': !this.$vuetify.breakpoint.lgAndUp,\n        'justify-end': this.$vuetify.breakpoint.lgAndUp\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container\n    v-if=\"notMobile\"\n    :style=\"chartStyle\"\n    class=\"absolute box chart-box d-flex justify-center\"\n  >\n    <v-container\n      v-if=\"chartOverlayMain\"\n      class=\"absolute overlay\"\n      :style=\"overlayStyle\"\n    >\n      <div class=\"text-overline\">\n        {{ chartOverlayOverline }}\n      </div>\n\n      <div\n        class=\"text-h3 font-weight-bold d-flex align-start\"\n        :class=\"mainClasses\"\n      >\n        {{ chartOverlayMain\n        }}<span class=\"text-h6 font-weight-black\">{{ chartOverlayUnits }}</span>\n      </div>\n      <div\n        class=\"font-weight-light\"\n        style=\"color: rgba(255, 255, 255, 0.8);\"\n        :class=\"$vuetify.breakpoint.sm ? 'text-subtitle-2' : 'text-h6'\"\n      >\n        {{ chartOverlaySub }}\n      </div>\n    </v-container>\n\n    <v-container class=\"absolute overlay-center\">\n      <v-icon v-if=\"chartOverlayCenterType === 'icon'\">{{\n        chartOverlayCenter\n      }}</v-icon>\n      <div v-else class=\"grey--text text--darken-2\">\n        <div>{{ chartOverlayCenter }}</div>\n        <div>{{ chartOverlayCenterTwo }}</div>\n      </div>\n    </v-container>\n\n    <RingChart\n      :segments=\"chartData\"\n      :width=\"250\"\n      :height=\"250\"\n      :colors=\"colors\"\n    />\n  </v-container>\n  <v-container\n    v-else\n    :style=\"chartStyle\"\n    class=\"absolute box chart-box d-flex justify-center\"\n  >\n    <v-container\n      v-if=\"chartOverlayMain\"\n      class=\"absolute overlay\"\n      style=\"\n      text-align: 'right';\n      width: 50%;\"\n    >\n      <div class=\"text-overline\">\n        {{ chartOverlayOverline }}\n      </div>\n\n      <div class=\"text-h3 font-weight-bold d-flex align-start justify-end\">\n        {{ chartOverlayMain\n        }}<span class=\"text-h6 font-weight-black\">{{ chartOverlayUnits }}</span>\n      </div>\n      <div\n        class=\"font-weight-light\"\n        style=\"color: rgba(255, 255, 255, 0.8);\"\n        :class=\"$vuetify.breakpoint.smAndDown ? 'text-subtitle-2' : 'text-h6'\"\n      >\n        {{ chartOverlaySub }}\n      </div>\n    </v-container>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.absolute {\n  position: absolute;\n}\n\n.box {\n  border-radius: 4px;\n\n  &.chart-box {\n    left: 50%;\n    top: 0;\n    transform: translate(-50%);\n    width: 87.5%;\n    z-index: 2;\n\n    .overlay {\n      color: #fff;\n      text-align: right;\n      top: 50%;\n      transform: translate(0, -50%);\n    }\n\n    .overlay-center {\n      left: 50%;\n      text-align: center;\n      top: 50%;\n      transform: translate(-50%, -50%);\n    }\n\n    .v-icon {\n      color: rgba(255, 255, 255, 0.4);\n      font-size: 6em !important;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/ChartCard/ChartCardHeader-Simple.vue",
    "content": "<script>\nexport default {\n  props: {\n    accentColor: {\n      type: String,\n      default: () => 'rgb(39, 177, 255)'\n    },\n    chartOverlayMain: { type: String, default: () => null },\n    chartOverlayOverline: { type: String, default: () => null },\n    chartOverlaySub: { type: String, default: () => null },\n    chartOverlayCenter: { type: String, default: () => 'check' }\n  },\n  computed: {\n    chartStyle() {\n      return {\n        'background-color': this.accentColor,\n        color: '#fff'\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container\n    :style=\"chartStyle\"\n    class=\"absolute box chart-box elevation-4 d-flex justify-center\"\n  >\n    <v-container class=\"absolute overlay\">\n      <div class=\"text-overline\">\n        {{ chartOverlayOverline }}\n      </div>\n      <div class=\"text-h2 font-weight-bold\">\n        {{ chartOverlayMain }}\n      </div>\n      <div class=\"font-weight-light text-h5\">\n        {{ chartOverlaySub }}\n      </div>\n    </v-container>\n\n    <v-container class=\"absolute overlay-center\">\n      <v-icon>{{ chartOverlayCenter }}</v-icon>\n    </v-container>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.absolute {\n  position: absolute;\n}\n\n.box {\n  border-radius: 4px;\n\n  &.chart-box {\n    height: 70%;\n    left: 50%;\n    top: 0;\n    transform: translate(-50%);\n    width: 87.5%;\n    z-index: 2;\n\n    .overlay {\n      color: #fff;\n      left: 50%;\n      text-align: center;\n      top: 50%;\n      transform: translate(-50%, -50%);\n      width: 50%;\n    }\n\n    .overlay-center {\n      left: 50%;\n      text-align: center;\n      top: 50%;\n      transform: translate(-50%, -50%);\n    }\n\n    .v-icon {\n      color: rgba(255, 255, 255, 0.4);\n      font-size: 6em !important;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/CloudHookForm.vue",
    "content": "<script>\nimport LogRocket from 'logrocket'\nimport { mapActions, mapGetters } from 'vuex'\nimport {\n  GROUP_COLORS,\n  STATES,\n  openCloudHookTypes,\n  featureFlaggedCloudHookTypes\n} from '@/utils/cloudHooks'\n\nconst PROVIDE_CONFIG_ERROR =\n  'You must provide a configuration for the Cloud Hook'\n\nconst obfuscatedFields = [\n  'account_sid',\n  'auth_token',\n  'messaging_service_sid',\n  'api_token',\n  'routing_key'\n]\n\nconst cloudHookLabels = {\n  account_sid: 'Account SID',\n  auth_token: 'Auth Token',\n  email: 'Email',\n  messaging_service_sid: 'Messaging Service SID',\n  to: 'To',\n  url: 'URL',\n  routing_key: 'Integration Key',\n  api_token: 'API Token',\n  severity: 'Severity'\n}\n\nconst newCloudHookTemplate = () => {\n  return {\n    name: 'Cloud Hook',\n    states: STATES['All'],\n    config: { url: null },\n    type: 'WEBHOOK'\n  }\n}\n\nexport default {\n  filters: {\n    obfuscate: function(val) {\n      if (!val || val == 'None') return val\n      return `••••••••••••••••${val.substring(val.length - 4)}`\n    },\n    capitalize: function(value) {\n      if (!value) return ''\n      value = value.toString()\n      return value.charAt(0).toUpperCase() + value.slice(1)\n    }\n  },\n  props: {\n    editable: {\n      default: () => true,\n      required: false,\n      type: Boolean\n    },\n    editOnRender: {\n      default: () => false,\n      required: false,\n      type: Boolean\n    },\n    hook: {\n      default: () => newCloudHookTemplate(),\n      required: false,\n      type: Object\n    },\n    showControls: {\n      default: () => false,\n      required: false,\n      type: Boolean\n    },\n    versionGroupIdProp: {\n      required: false,\n      type: String,\n      default: ''\n    }\n  },\n  data() {\n    return {\n      canEdit: this.editOnRender,\n      tempConfig: this.hook?.config ? this.hook.config : { url: null },\n      severityLevels: [\n        { text: 'Info', value: 'info' },\n        { text: 'Warning', value: 'warning' },\n        { text: 'Error', value: 'error' },\n        { text: 'Critical', value: 'critical' }\n      ],\n      versionGroupIdSelect: '',\n      configError: false,\n      error: null,\n      valid: false,\n      loading: false,\n      tempName: this.hook.name,\n      rules: {\n        email: val => {\n          const pattern = /^(([^<>()[\\]\\\\.,;:\\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          return (\n            val.split(',').every(email => pattern.test(email.trim())) ||\n            'Invalid e-mail.'\n          )\n        },\n        required: val => !!val || 'Required.',\n        requiredCombo: val =>\n          (!!val && val.length > 0) || 'At least one number is required',\n        url: val => {\n          const pattern = /[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,}\\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/\n          return pattern.test(val) || 'Invalid URL.'\n        }\n      },\n      tempStates: this.hook.states,\n      tempType: this.hook ? this.hook.type : 'WEBHOOK',\n      testCloudHookLoading: false,\n      flowError: ''\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('api', ['isCloud']),\n    stateGroupAll() {\n      return this.cloudHookStateGroup('All')\n    },\n    versionGroupId() {\n      if (this.versionGroupIdProp) return this.versionGroupIdProp\n      return this.versionGroupIdSelect\n    },\n    stateGroupCustom() {\n      return (\n        !this.stateGroupAll &&\n        !this.stateGroupFailed &&\n        !this.stateGroupFinished &&\n        !this.stateGroupSuccess\n      )\n    },\n    stateGroupFailed() {\n      return this.cloudHookStateGroup('Failed')\n    },\n    stateGroupFinished() {\n      return this.cloudHookStateGroup('Finished')\n    },\n    stateGroupSuccess() {\n      return this.cloudHookStateGroup('Success')\n    },\n    states() {\n      return this.canEdit && this.editable\n        ? STATES['All']\n        : STATES['All'].filter(s =>\n            this.hook?.states?.includes(s.toUpperCase())\n          )\n    },\n    cloudHookTypes() {\n      let allHooks\n      if (\n        this.canEdit &&\n        this.editable &&\n        this.tenant.prefectAdminSettings?.notifications\n      ) {\n        allHooks = featureFlaggedCloudHookTypes\n      } else {\n        allHooks =\n          this.canEdit && this.editable\n            ? openCloudHookTypes\n            : openCloudHookTypes.filter(t => t.type == this.hook.type)\n      }\n      return allHooks.filter(\n        t => (t.requiresCloud && this.isCloud) || !t.requiresCloud\n      )\n    }\n  },\n  watch: {\n    loading(val) {\n      this.$emit('update:loading', val)\n    },\n    tempConfig() {\n      this.configError = false\n      this.error = ''\n    },\n    versionGroupId(val) {\n      if (val) {\n        this.flowError = ''\n      }\n    },\n    tempType(val) {\n      this.tempConfig = this.cloudHookTypes.find(t => t.type == val).config\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    _handleCancel() {\n      this.$emit('close')\n      this.flowError = ''\n      this.canEdit = false\n    },\n    async _handleSaveCloudHook() {\n      if (this.hook.id) await this.deleteCloudHook()\n      await this.createCloudHook()\n    },\n    _handleCloudHookStatesAll() {\n      this.tempStates = STATES.All\n    },\n    _handleCloudHookStatesCustom() {\n      this.tempStates = []\n    },\n    _handleCloudHookStatesFailed() {\n      this.tempStates = STATES.Failed\n    },\n    _handleCloudHookStatesFinished() {\n      this.tempStates = STATES.Finished\n    },\n    _handleCloudHookStatesSuccess() {\n      this.tempStates = STATES.Success\n    },\n    async createCloudHook() {\n      if (!this.tempConfig) {\n        this.configError = true\n        this.error = PROVIDE_CONFIG_ERROR\n        return\n      }\n\n      if (!this.versionGroupId) {\n        this.flowError =\n          'You have not selected a flow to attach your Cloud Hook to'\n        return\n      }\n\n      this.configError = false\n      this.error = null\n\n      this.loading = true\n      try {\n        let input = {\n          version_group_id: this.versionGroupId,\n          name: this.tempName,\n          states: this.tempStates,\n          config: this.tempConfig,\n          type: this.tempType,\n          tenant_id: this.tenant.id\n        }\n\n        const createCloudHookResult = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-cloud-hook.gql'),\n          variables: {\n            input: input\n          },\n          errorPolicy: 'all'\n        })\n\n        setTimeout(() => {\n          if (createCloudHookResult?.data?.create_cloud_hook?.id) {\n            this.$emit('update')\n            this.loading = false\n            this.$emit('close')\n            this.canEdit = false\n          } else {\n            this.error = createCloudHookResult.errors[0].message\n            this.loading = false\n          }\n        }, 1000)\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Settings',\n            stage: 'Create State Hook'\n          }\n        })\n        this.loading = false\n        this.error = e\n      }\n    },\n    async deleteCloudHook() {\n      this.loading = true\n      try {\n        let input = {\n          cloud_hook_id: this.hook.id\n        }\n\n        const deleteCloudHookResult = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/delete-cloud-hook.gql'),\n          variables: {\n            input: input\n          },\n          errorPolicy: 'all'\n        })\n\n        setTimeout(() => {\n          if (deleteCloudHookResult?.data?.delete_cloud_hook?.success) {\n            this.$emit('update')\n            this.loading = false\n            this.$emit('delete')\n            this.canEdit = false\n          } else {\n            this.error = deleteCloudHookResult.errors[0].message\n            this.loading = false\n          }\n        }, 1000)\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Settings',\n            stage: 'Delete Cloud Hook'\n          }\n        })\n        this.loading = false\n        this.error = e\n      }\n    },\n    async testCloudHook() {\n      this.testCloudHookLoading = true\n\n      try {\n        let input = {\n          cloud_hook_id: this.hook.id,\n          state_type: 'SUCCESS'\n        }\n\n        const testCloudHookResult = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/test-cloud-hook.gql'),\n          variables: {\n            input: input\n          },\n          errorPolicy: 'all'\n        })\n        setTimeout(() => {\n          if (testCloudHookResult?.data?.test_cloud_hook?.success) {\n            this.testCloudHookLoading = false\n            this.setAlert(\n              {\n                alertShow: true,\n                alertMessage: 'Cloud Hook test dispatched.',\n                alertType: 'success'\n              },\n              3000\n            )\n            this.$emit('test')\n          } else {\n            this.setAlert(\n              {\n                alertShow: true,\n                alertMessage: `Cloud Hook test failed with the following message: <strong>${testCloudHookResult?.data?.test_cloud_hook?.error}</strong>`,\n                alertType: 'error'\n              },\n              3000\n            )\n            this.testCloudHookLoading = false\n          }\n        }, 1000)\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Settings',\n            stage: 'Test Cloud Hook'\n          }\n        })\n        this.testCloudHookLoading = false\n        this.error = e\n      }\n    },\n    cloudHookKeyLabel(key) {\n      return cloudHookLabels[key]\n    },\n    cloudHookStateGroup(group) {\n      return (\n        STATES[group] &&\n        STATES[group].every(state => this.tempStates?.includes(state)) &&\n        STATES[group].length == this.tempStates.length\n      )\n    },\n    shouldObfuscate(key) {\n      return obfuscatedFields?.includes(key)\n    },\n    stateGroupColor(group) {\n      return GROUP_COLORS[group]\n    },\n    projectNamePrefix() {\n      return item => `${item.name} (${item.project.name})`\n    }\n  },\n  apollo: {\n    flows: {\n      query: require('@/graphql/TeamSettings/flows.gql'),\n      result({ data }) {\n        if (!data) return\n        this.flowsLoaded = true\n      },\n      error() {\n        this.handleError(\n          'Something went wrong while trying to fetch your flows.'\n        )\n      },\n      update(data) {\n        return data.flow\n      },\n      fetchPolicy: 'no-cache'\n    }\n  }\n}\n</script>\n\n<template>\n  <v-form v-model=\"valid\">\n    <v-card flat>\n      <v-card-text class=\"pa-0\">\n        <v-row>\n          <v-col cols=\"12\">\n            <v-row>\n              <v-col cols=\"12\" md=\"8\" class=\"pb-0\">\n                <v-autocomplete\n                  data-public\n                  v-if=\"canEdit && !versionGroupIdProp\"\n                  id=\"item\"\n                  v-model=\"versionGroupIdSelect\"\n                  data-cy=\"flow-list\"\n                  item-value=\"version_group_id\"\n                  :item-text=\"projectNamePrefix()\"\n                  label=\"Flow (Version Group)\"\n                  class=\"text-h5 overflow\"\n                  :items=\"flows\"\n                >\n                  <template #item=\"{ item }\">\n                    <v-list-item-content>\n                      <v-list-item-title>{{ item.name }}</v-list-item-title>\n                      <v-list-item-subtitle\n                        >({{ item.project.name }})</v-list-item-subtitle\n                      >\n                    </v-list-item-content>\n                  </template>\n                </v-autocomplete>\n                <v-text-field\n                  v-if=\"canEdit\"\n                  v-model=\"tempName\"\n                  data-cy=\"hook-name\"\n                  label=\"Name\"\n                  class=\"text-h5\"\n                  hide-details\n                />\n                <div v-else>\n                  <div class=\"text-caption\">Name</div>\n                  <div class=\"text-h5 black--text\">{{ tempName }}</div>\n                </div>\n                <div class=\"text-subtitle-1 pt-2\">\n                  This is a non-unique shorthand identifier for your Cloud Hook.\n                </div>\n              </v-col>\n\n              <v-col\n                v-if=\"showControls\"\n                class=\"d-flex justify-end\"\n                cols=\"12\"\n                md=\"4\"\n                order-sm=\"1\"\n              >\n                <v-tooltip v-if=\"!canEdit && editable\" top>\n                  <template #activator=\"{ on }\">\n                    <div style=\"display: inline-block;\" v-on=\"on\">\n                      <v-btn\n                        :loading=\"testCloudHookLoading\"\n                        class=\"mr-4\"\n                        color=\"warning\"\n                        small\n                        depressed\n                        @click=\"testCloudHook\"\n                      >\n                        <v-icon>bug_report</v-icon>\n                        Test\n                      </v-btn>\n                    </div>\n                  </template>\n                  <span v-if=\"!editable\">\n                    Read-only users cannot modify Cloud Hooks\n                  </span>\n                  <span v-else>\n                    Test this Cloud Hook (will send a test call to your\n                    endpoint)\n                  </span>\n                </v-tooltip>\n\n                <v-tooltip v-if=\"!canEdit && editable\" top>\n                  <template #activator=\"{ on }\">\n                    <div style=\"display: inline-block;\" v-on=\"on\">\n                      <v-btn icon @click=\"canEdit = true\">\n                        <v-icon color=\"primary lighten-1\">edit</v-icon>\n                      </v-btn>\n                    </div>\n                  </template>\n                  <span v-if=\"!editable\">\n                    Read-only users cannot modify Cloud Hooks\n                  </span>\n                  <span v-else>\n                    Modify this Cloud Hook\n                  </span>\n                </v-tooltip>\n\n                <!-- <v-btn\n                  v-if=\"canEdit\"\n                  color=\"primary\"\n                  depressed\n                  :loading=\"loading\"\n                  :disabled=\"loading || !!error || !valid\"\n                  @click=\"_handleSaveCloudHook\"\n                >\n                  Save\n                </v-btn> -->\n\n                <v-tooltip v-if=\"editable && !canEdit\" top>\n                  <template #activator=\"{ on }\">\n                    <div style=\"display: inline-block;\" v-on=\"on\">\n                      <v-btn\n                        icon\n                        :loading=\"loading\"\n                        :disabled=\"loading\"\n                        @click=\"deleteCloudHook\"\n                      >\n                        <v-icon color=\"red darken-1\">delete</v-icon>\n                      </v-btn>\n                    </div>\n                  </template>\n                  <span v-if=\"!editable\">\n                    Read-only users cannot delete Cloud Hooks\n                  </span>\n                  <span v-else>\n                    Delete this Cloud Hook\n                  </span>\n                </v-tooltip>\n              </v-col>\n            </v-row>\n\n            <v-row class=\"mt-2\">\n              <v-col cols=\"12\" class=\"pt-2\">\n                <div class=\"text-h5 primary--text\">\n                  Type\n                </div>\n              </v-col>\n              <v-col cols=\"12\" class=\"pt-0\">\n                <v-chip-group\n                  v-if=\"canEdit\"\n                  v-model=\"tempType\"\n                  column\n                  mandatory\n                >\n                  <v-chip\n                    v-for=\"type in cloudHookTypes\"\n                    :key=\"type.title\"\n                    :data-cy=\"type.type\"\n                    active-class=\"primary\"\n                    class=\"px-6\"\n                    label\n                    :value=\"type.type\"\n                    large\n                  >\n                    <v-icon left class=\"mr-2\">\n                      {{ type.icon }}\n                    </v-icon>\n                    {{ type.title }}\n                  </v-chip>\n                </v-chip-group>\n\n                <div v-else>\n                  <v-chip\n                    v-for=\"type in cloudHookTypes\"\n                    :key=\"type.title\"\n                    color=\"primary\"\n                    class=\"px-6\"\n                    label\n                    :value=\"type.type\"\n                    large\n                  >\n                    <v-icon left class=\"mr-2\">\n                      {{ type.icon }}\n                    </v-icon>\n                    {{ type.title }}\n                  </v-chip>\n                </div>\n              </v-col>\n            </v-row>\n\n            <v-row\n              class=\"mt-2\"\n              :style=\"{\n                'border-left': configError\n                  ? '2px solid var(--v-Failed-base) !important'\n                  : ''\n              }\"\n            >\n              <v-col cols=\"12\" class=\"pt-2\">\n                <div\n                  v-if=\"tempType !== 'PREFECT_MESSAGE'\"\n                  class=\"text-h5 primary--text\"\n                >\n                  Configuration\n                </div>\n                <div class=\"subtitle pt-2\">\n                  <span v-if=\"tempType == 'EMAIL'\">\n                    Input emails separated by commas; Prefect Cloud will send an\n                    email to these addresses when your flow's State changes.\n                  </span>\n                  <span v-else-if=\"tempType == 'SLACK_WEBHOOK'\">\n                    Prefect Cloud will send a notification via Slack Webhook to\n                    this endpoint when your flow's State changes. To read more\n                    about Slack Webhooks, you can visit the\n                    <a\n                      href=\"https://api.slack.com/messaging/webhooks\"\n                      target=\"_blank\"\n                      >Slack API Docs</a\n                    >.\n                  </span>\n                  <span v-else-if=\"tempType == 'TWILIO'\">\n                    Prefect Cloud will send a message via the\n                    <a href=\"https://www.twilio.com/docs\" target=\"_blank\">\n                      Twilio SMS API\n                    </a>\n                    on your behalf when your flow's State changes. You can\n                    retrieve the <code class=\"my-1 mx-1\">ACCOUNT SID</code> and\n                    <code class=\"my-1 mx-1\">AUTH TOKEN</code> from the dashboard\n                    of your Twilio account. You'll need to configure a\n                    <a\n                      href=\"https://www.twilio.com/docs/sms/services/api#messaging-services-resource\"\n                      target=\"_blank\"\n                    >\n                      Messaging Service\n                    </a>\n                    to recieve messages.\n                  </span>\n                  <span v-else-if=\"tempType == 'WEBHOOK'\">\n                    Prefect Cloud will send a JSON payload to this endpoint when\n                    your flow's State changes.\n                  </span>\n                  <span v-else-if=\"tempType == 'PAGERDUTY'\">\n                    Prefect Cloud will send a PagerDuty notification when your\n                    flow's State changes. Create your\n                    <a\n                      href=\"https://support.pagerduty.com/docs/generating-api-keys\"\n                      target=\"_blank\"\n                      >Pager Duty API token</a\n                    >\n                    in the Pager Duty app by visiting Configuration > API\n                    Access. You'll also need an Integration Key, which can be\n                    created by visiting the Integrations tab of the Service\n                    Details page and setting up an\n                    <a\n                      href=\"https://support.pagerduty.com/docs/services-and-integrations\"\n                      target=\"_blank\"\n                      >Events API v2</a\n                    >\n                    integration.\n                  </span>\n                </div>\n              </v-col>\n              <v-col v-if=\"editable && canEdit\" cols=\"12\" class=\"pt-0 pr-8\">\n                <v-text-field\n                  v-if=\"tempType == 'EMAIL'\"\n                  v-model=\"tempConfig.to\"\n                  :rules=\"[rules.required, rules.email]\"\n                  type=\"email\"\n                  label=\"To\"\n                  dense\n                />\n                <v-text-field\n                  v-if=\"tempType == 'SLACK_WEBHOOK'\"\n                  v-model=\"tempConfig.url\"\n                  :rules=\"[rules.required, rules.url]\"\n                  label=\"Slack URL\"\n                  dense\n                />\n\n                <v-combobox\n                  v-if=\"tempType == 'TWILIO'\"\n                  v-model=\"tempConfig.to\"\n                  :items=\"tempConfig.to\"\n                  :rules=\"[rules.requiredCombo]\"\n                  label=\"To\"\n                  multiple\n                  chips\n                  dense\n                  hint=\"To add a number to the list, type the number and press enter.\"\n                  persistent-hint\n                >\n                  <template #no-data>\n                    <v-list-item>\n                      <v-list-item-content>\n                        <v-list-item-title>\n                          To add a new number, type the number and press enter.\n                        </v-list-item-title>\n                      </v-list-item-content>\n                    </v-list-item>\n                  </template>\n                </v-combobox>\n\n                <v-text-field\n                  v-if=\"tempType == 'TWILIO'\"\n                  v-model=\"tempConfig.auth_token\"\n                  class=\"my-8\"\n                  :rules=\"[rules.required]\"\n                  label=\"Auth Token\"\n                  dense\n                />\n\n                <v-text-field\n                  v-if=\"tempType == 'TWILIO'\"\n                  v-model=\"tempConfig.account_sid\"\n                  :rules=\"[rules.required]\"\n                  label=\"Account SID\"\n                  class=\"mb-8\"\n                  dense\n                />\n\n                <v-text-field\n                  v-if=\"tempType == 'TWILIO'\"\n                  v-model=\"tempConfig.messaging_service_sid\"\n                  :rules=\"[rules.required]\"\n                  label=\"Messaging service SID\"\n                  dense\n                />\n\n                <v-text-field\n                  v-if=\"tempType == 'WEBHOOK'\"\n                  v-model=\"tempConfig.url\"\n                  :rules=\"[rules.required, rules.url]\"\n                  label=\"URL\"\n                  dense\n                />\n                <v-text-field\n                  v-if=\"tempType == 'PAGERDUTY'\"\n                  v-model=\"tempConfig.api_token\"\n                  :rules=\"[rules.required]\"\n                  label=\"API Token\"\n                  class=\"my-8\"\n                  dense\n                />\n                <v-text-field\n                  v-if=\"tempType == 'PAGERDUTY'\"\n                  v-model=\"tempConfig.routing_key\"\n                  :rules=\"[rules.required]\"\n                  label=\"Integration key\"\n                  dense\n                  class=\"mb-8\"\n                />\n                <v-select\n                  v-if=\"tempType == 'PAGERDUTY'\"\n                  v-model=\"tempConfig.severity\"\n                  :items=\"severityLevels\"\n                  label=\"Severity\"\n                  dense\n                />\n\n                <div v-if=\"error && configError\" class=\"error--text\">\n                  {{ error }}\n                </div>\n              </v-col>\n\n              <v-col v-else cols=\"12\" md=\"6\" class=\"pt-0\">\n                <div\n                  v-for=\"key in Object.keys(hook.config)\"\n                  :key=\"key\"\n                  class=\"my-4\"\n                >\n                  <div class=\"text-caption\">\n                    {{ cloudHookKeyLabel(key) }}\n                  </div>\n                  <div class=\"text-h6\">\n                    <span v-if=\"shouldObfuscate(key)\">\n                      {{ hook.config[key] || 'None' | obfuscate }}\n                    </span>\n                    <span v-else-if=\"typeof hook.config[key] == 'object'\">\n                      <v-chip v-for=\"item in hook.config[key]\" :key=\"item\">\n                        {{ item }}\n                      </v-chip>\n                    </span>\n                    <span v-else-if=\"hook.config && hook.config.severity\">\n                      {{ hook.config.severity | capitalize }}\n                    </span>\n                    <span v-else>\n                      {{ hook.config[key] || 'None' }}\n                    </span>\n                  </div>\n                </div>\n              </v-col>\n            </v-row>\n\n            <v-row class=\"mt-2\">\n              <v-col cols=\"12\" class=\"pt-2\">\n                <div class=\"text-h5 primary--text\">\n                  States\n                </div>\n                <div class=\"text-subtitle-1\">\n                  Prefect Cloud will send information to your Cloud Hook when\n                  your flow transitions to any of these states.\n                  <div v-if=\"editable && canEdit\" class=\"mt-2\">\n                    You can use state group presets or set custom notifiers.\n                  </div>\n                </div>\n              </v-col>\n              <v-col\n                v-if=\"editable && canEdit\"\n                cols=\"12\"\n                class=\"pt-0 d-flex flex-space-around align-center\"\n              >\n                <v-btn\n                  class=\"ma-auto\"\n                  :color=\"stateGroupAll ? stateGroupColor('All') : ''\"\n                  depressed\n                  :dark=\"stateGroupAll\"\n                  :disabled=\"!canEdit\"\n                  @click=\"_handleCloudHookStatesAll\"\n                >\n                  All\n                </v-btn>\n\n                <v-btn\n                  class=\"ma-auto\"\n                  :color=\"stateGroupFinished ? stateGroupColor('Finished') : ''\"\n                  depressed\n                  :dark=\"stateGroupFinished\"\n                  :disabled=\"!canEdit\"\n                  @click=\"_handleCloudHookStatesFinished\"\n                >\n                  Finished\n                </v-btn>\n\n                <v-btn\n                  class=\"ma-auto\"\n                  :color=\"stateGroupSuccess ? stateGroupColor('Success') : ''\"\n                  depressed\n                  :dark=\"stateGroupSuccess\"\n                  :disabled=\"!canEdit\"\n                  @click=\"_handleCloudHookStatesSuccess\"\n                >\n                  Success\n                </v-btn>\n\n                <v-btn\n                  class=\"ma-auto\"\n                  :color=\"stateGroupFailed ? stateGroupColor('Failed') : ''\"\n                  depressed\n                  :dark=\"stateGroupFailed\"\n                  :disabled=\"!canEdit\"\n                  @click=\"_handleCloudHookStatesFailed\"\n                >\n                  Failed\n                </v-btn>\n\n                <v-btn\n                  class=\"ma-auto\"\n                  :color=\"stateGroupCustom ? stateGroupColor('Custom') : ''\"\n                  depressed\n                  :dark=\"stateGroupCustom\"\n                  :disabled=\"!canEdit\"\n                  @click=\"_handleCloudHookStatesCustom\"\n                >\n                  Custom\n                </v-btn>\n              </v-col>\n\n              <v-col cols=\"12\" class=\"mt-1 pt-0\">\n                <v-divider />\n\n                <v-chip-group\n                  v-if=\"canEdit\"\n                  v-model=\"tempStates\"\n                  column\n                  multiple\n                >\n                  <v-chip\n                    v-for=\"state in states\"\n                    :key=\"state\"\n                    active-class=\"primary\"\n                    class=\"capitalize\"\n                    label\n                    :value=\"state\"\n                    :disabled=\"!canEdit\"\n                  >\n                    {{ state.toLowerCase() }}\n                  </v-chip>\n                </v-chip-group>\n                <v-chip-group v-else column>\n                  <v-chip\n                    v-for=\"state in states\"\n                    :key=\"state\"\n                    color=\"primary\"\n                    class=\"capitalize\"\n                    label\n                    :value=\"state\"\n                  >\n                    {{ state.toLowerCase() }}\n                  </v-chip>\n                </v-chip-group>\n\n                <div v-if=\"states.length == 0 && !canEdit\">\n                  This Cloud Hook doesn't have any states configured.\n                  <a @click=\"canEdit = true\">Configure</a>\n                </div>\n              </v-col>\n            </v-row>\n          </v-col>\n        </v-row>\n        <div v-if=\"error && !configError\" class=\"error--text\">\n          {{ error }}\n        </div>\n        <div v-if=\"flowError\" class=\"error--text\">\n          {{ flowError }}\n        </div>\n      </v-card-text>\n\n      <v-divider class=\"mt-2\"></v-divider>\n\n      <v-card-actions v-if=\"canEdit\">\n        <v-spacer></v-spacer>\n        <v-btn\n          color=\"primary\"\n          depressed\n          data-cy=\"save-hook\"\n          :loading=\"loading\"\n          :disabled=\"loading || configError || !valid\"\n          @click=\"_handleSaveCloudHook\"\n        >\n          Save\n        </v-btn>\n        <v-btn depressed @click=\"_handleCancel\">\n          Cancel\n        </v-btn>\n      </v-card-actions>\n    </v-card>\n  </v-form>\n</template>\n\n<style>\n.capitalize {\n  text-transform: capitalize !important;\n}\n/* stylelint-disable */\n.v-autocomplete__content.v-menu__content .v-select-list {\n  border-radius: 0 0 4px 4px;\n  max-width: 400px;\n}\n/* stylelint-enable */\n</style>\n"
  },
  {
    "path": "src/components/ConcurrencyInfo.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nexport default {\n  data() {\n    return {\n      menu: false\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license']),\n    flowConcurrency() {\n      return this.license?.terms?.flow_concurrency\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.concurrentRuns.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    concurrentRuns: {\n      query: require('@/graphql/concurrent-runs.gql'),\n      loadingKey: 'loading',\n      pollInterval: 3000,\n      update({ flow_run }) {\n        if (!flow_run) return []\n        return flow_run\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-if=\"concurrentRuns && license\" v-intersect=\"{ handler: onIntersect }\">\n    {{ concurrentRuns.length\n    }}{{ flowConcurrency ? `/${flowConcurrency}` : '' }} slot{{\n      concurrentRuns.length === 1 || flowConcurrency === 1 ? '' : 's'\n    }}\n    used\n\n    <v-menu\n      v-model=\"menu\"\n      :close-on-content-click=\"false\"\n      offset-y\n      transition=\"slide-y-transition\"\n    >\n      <template #activator=\"{ on }\">\n        <v-btn text icon x-small v-on=\"on\">\n          <v-icon>\n            info\n          </v-icon>\n        </v-btn>\n      </template>\n      <v-card tile class=\"pa-0\" max-width=\"320\">\n        <v-card-text class=\"pb-0\">\n          <div class=\"text-h6 mb-4\">\n            <span class=\"primary--text\">{{ concurrentRuns.length }}</span>\n            concurrency slots used\n          </div>\n          <p v-if=\"!flowConcurrency\">\n            Your team has\n            <span class=\"font-weight-bold\">unlimited</span> flow concurrency, so\n            you can run as many concurrent flows as you'd like!\n          </p>\n          <p v-else>\n            Your team has\n            <span class=\"font-weight-bold\">{{ flowConcurrency }}</span>\n            flow concurrency slot{{ flowConcurrency === 1 ? '' : 's' }}. Flow\n            runs in\n            <v-chip\n              x-small\n              label\n              dark\n              color=\"Running\"\n              class=\"px-1 font-weight-bold\"\n            >\n              Running </v-chip\n            >,\n            <v-chip\n              x-small\n              label\n              color=\"Cancelling\"\n              class=\"px-1 font-weight-bold\"\n            >\n              Cancelling\n            </v-chip>\n            or\n            <v-chip\n              x-small\n              label\n              color=\"Submitted\"\n              class=\"px-1 font-weight-bold\"\n            >\n              Submitted\n            </v-chip>\n            states take up concurrency slots; flow runs will remain in\n            <v-chip\n              x-small\n              label\n              dark\n              color=\"Scheduled\"\n              class=\"px-1 font-weight-bold\"\n            >\n              Scheduled\n            </v-chip>\n            until a concurrency slot becomes available.\n          </p>\n          <p v-if=\"flowConcurrency\">\n            <a href=\"https://www.prefect.io/pricing#contact\" target=\"_blank\">\n              Contact us</a\n            >\n            to add concurrency slots and to get access to lots of other cool\n            features!\n          </p>\n        </v-card-text>\n        <v-card-actions class=\"pt-0\">\n          <v-spacer></v-spacer>\n          <v-btn small text @click=\"menu = false\">\n            Close\n          </v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-menu>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/ConfirmDialog.vue",
    "content": "<script>\nexport default {\n  props: {\n    // Text displayed on the cancel button\n    cancelText: {\n      type: String,\n      required: false,\n      default: () => 'Cancel'\n    },\n    // Props to pass to cancel button\n    cancelProps: {\n      type: Object,\n      required: false,\n      default: () => ({})\n    },\n    // Props to pass to confirm button\n    confirmProps: {\n      type: Object,\n      required: false,\n      default: () => ({})\n    },\n    // Text displayed on the confirmation button\n    confirmText: {\n      type: String,\n      required: false,\n      default: () => 'Confirm'\n    },\n    // Props to pass to v-dialog component\n    dialogProps: {\n      type: Object,\n      required: false,\n      default: () => ({})\n    },\n    // Disable confirmation button\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    // Any error messages associated with the dialog\n    error: {\n      type: String,\n      required: false,\n      default: () => ''\n    },\n    // Display loader on confirmation button\n    loading: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    // Title on dialog card\n    title: {\n      type: String,\n      required: false,\n      default: () => ''\n    },\n    // Specify the type of alert\n    // - \"primary\", the default, is typically used for save actions\n    // - \"error\" is typically used for destructive actions\n    type: {\n      type: String,\n      required: false,\n      default: () => 'primary'\n    },\n    // Prop that allows users to set v-model on the dialog\n    value: {\n      type: Boolean,\n      required: true\n    },\n    width: {\n      type: String,\n      required: false,\n      default: ''\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  },\n  methods: {\n    emitInternalValue() {\n      this.$emit('input', this.internalValue)\n    },\n    handleCancel() {\n      this.internalValue = false\n      this.$emit('cancel')\n    },\n    handleConfirm() {\n      this.$emit('confirm')\n    }\n  }\n}\n</script>\n\n<template>\n  <v-dialog\n    :value=\"internalValue\"\n    v-bind=\"dialogProps\"\n    :width=\"width\"\n    @click:outside=\"handleCancel\"\n    @keydown.esc=\"handleCancel\"\n  >\n    <v-card flat>\n      <v-card-title class=\"text-h5 word-break-normal mb-3\" primary-title>\n        <slot v-if=\"$slots['title']\" name=\"title\" />\n        <div v-else>{{ title }}</div>\n      </v-card-title>\n\n      <v-card-text class=\"pb-0\">\n        <slot></slot>\n      </v-card-text>\n\n      <v-card-actions class=\"pb-4 px-6\">\n        <div class=\"error--text text-body-2\t\">{{ error }}</div>\n        <v-spacer></v-spacer>\n        <v-btn\n          text\n          :data-cy=\"cancelProps['data-cy'] || 'cancel'\"\n          v-bind=\"cancelProps\"\n          @click=\"handleCancel\"\n        >\n          {{ cancelText }}\n        </v-btn>\n        <v-btn\n          depressed\n          :color=\"type\"\n          :data-cy=\"confirmProps['data-cy'] || 'confirm'\"\n          :loading=\"loading\"\n          :disabled=\"disabled\"\n          v-bind=\"confirmProps\"\n          @click=\"handleConfirm\"\n        >\n          {{ confirmText }}\n        </v-btn>\n      </v-card-actions>\n    </v-card>\n  </v-dialog>\n</template>\n"
  },
  {
    "path": "src/components/CustomInputs/BaseCodeTextarea.vue",
    "content": "<template>\n  <div class=\"base-code-textarea\">\n    <v-textarea\n      v-model=\"internalValue\"\n      class=\"base-code-textarea__textarea\"\n      spellcheck=\"false\"\n      :error-messages=\"errors\"\n      :disabled=\"readonly\"\n      :placeholder=\"placeholder\"\n      auto-grow\n      outlined\n      @input=\"validate\"\n      @blur=\"handleBlur\"\n    >\n      <template #append>\n        <highlight\n          :language=\"language\"\n          :code=\"internalValue\"\n          class=\"base-code-textarea__preview\"\n        />\n        <span\n          class=\"base-code-textarea__language\"\n          :class=\"`base-code-textarea__language-${language}`\"\n          >{{ language }}</span\n        >\n      </template>\n      <template #message=\"{message}\">\n        <p style=\"white-space: pre-line\">\n          {{ message }}\n        </p>\n      </template>\n    </v-textarea>\n  </div>\n</template>\n\n<script>\nimport Highlight from '@/components/CustomInputs/Highlight'\n\nexport default {\n  name: 'BaseCodeTextarea',\n  components: {\n    Highlight\n  },\n  props: {\n    value: {\n      type: String,\n      required: false,\n      default: null\n    },\n    readonly: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    language: {\n      type: String,\n      required: true,\n      validator: value => ['json', 'yaml'].includes(value)\n    },\n    placeholder: {\n      type: String,\n      required: false,\n      default: null\n    },\n    getErrors: {\n      type: Function,\n      required: true\n    },\n    parse: {\n      type: Function,\n      required: true\n    },\n    format: {\n      type: Function,\n      required: true\n    }\n  },\n  data() {\n    return {\n      errors: []\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  },\n  created() {\n    if (this.internalValue) {\n      this.validate(this.internalValue)\n    }\n  },\n  methods: {\n    handleBlur() {\n      const objectValue = this.parse(this.internalValue)\n      const formatted = this.format(objectValue)\n\n      if (formatted != null) {\n        this.internalValue = formatted\n      }\n    },\n    validate(value) {\n      this.errors = this.getErrors(value)\n\n      return this.errors.length === 0\n    }\n  }\n}\n</script>\n\n<style lang=\"scss\">\n.base-code-textarea {\n  .v-input__append-inner {\n    position: absolute;\n    margin: 0;\n    padding: 0;\n    width: 50%;\n    right: 2px;\n    top: 2px;\n    bottom: 2px;\n  }\n\n  .v-input__control {\n    padding: 0;\n  }\n\n  .base-code-textarea__textarea .v-text-field__slot {\n    width: 50%;\n    margin-bottom: 4px;\n    flex-grow: 0 !important;\n  }\n\n  .base-code-textarea__preview {\n    color: #666666;\n    width: 100%;\n    word-wrap: break-word;\n    white-space: pre-wrap;\n\n    code {\n      position: absolute;\n      top: 0;\n      left: 0;\n      right: 0;\n      bottom: 0;\n      padding-top: 10px;\n      padding-bottom: 8px;\n      font-family: monospace, monospace;\n      font-size: 13px;\n      line-height: 13px;\n    }\n  }\n\n  .base-code-textarea__language {\n    position: absolute;\n    bottom: 5px;\n    right: 5px;\n    text-transform: uppercase;\n  }\n\n  .base-code-textarea__language-json {\n    color: rgba(76, 175, 80, 0.35);\n  }\n\n  .base-code-textarea__language-yaml {\n    color: rgba(255, 152, 0, 0.35);\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/BaseDictInput.vue",
    "content": "<template>\n  <div class=\"base-dict-input\">\n    <div\n      v-for=\"(entry, index) in entries\"\n      :key=\"index\"\n      class=\"base-dict-input__row\"\n    >\n      <slot name=\"before-existing\" :entry=\"entry\" />\n      <key-value-input\n        ref=\"existingPropertyForms\"\n        :value=\"entry\"\n        :readonly-key=\"readonlyKey\"\n        :readonly-type=\"readonlyType\"\n        :readonly-value=\"readonlyValue\"\n        :show-types=\"showTypes\"\n        :types=\"types\"\n        @input=\"$emit('update', [$event, entry])\"\n      />\n      <slot name=\"after-existing\" :entry=\"entry\" />\n      <v-btn\n        v-if=\"!disableRemove\"\n        class=\"base-dict-input__action\"\n        icon\n        @click=\"$emit('remove', entry)\"\n      >\n        <v-icon color=\"red\">remove_circle</v-icon>\n      </v-btn>\n    </div>\n    <div\n      v-if=\"!disableAdd\"\n      ref=\"newPropertyContainer\"\n      class=\"base-dict-input__row base-dict-input__row-last\"\n    >\n      <slot name=\"before-new\" :entry=\"newProperty\" />\n      <key-value-input\n        ref=\"newPropertyForm\"\n        v-model=\"newProperty\"\n        :show-types=\"showTypes\"\n        :types=\"types\"\n        @focusout.native=\"handleFocusout\"\n      />\n      <slot name=\"after-new\" :entry=\"newProperty\">\n        <v-btn class=\"base-dict-input__action\" icon @click=\"tryAddNewProperty\">\n          <v-icon color=\"green\">add_circle</v-icon>\n        </v-btn>\n      </slot>\n    </div>\n  </div>\n</template>\n\n<script>\nimport KeyValueInput from '@/components/CustomInputs/KeyValueInput'\nimport readonlyProps from '@/components/CustomInputs/readonlyProps'\nimport { types, isValidType } from '@/utils/types'\n\nexport default {\n  name: 'BaseDictInput',\n  components: {\n    KeyValueInput\n  },\n  props: {\n    entries: {\n      type: Array,\n      required: false,\n      default: null\n    },\n    showTypes: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    types: {\n      type: Array,\n      required: false,\n      default: () => types,\n      validator: value => value.every(isValidType)\n    },\n    ...readonlyProps\n  },\n  data() {\n    return {\n      newProperty: { key: null, value: null }\n    }\n  },\n  methods: {\n    handleFocusout(event) {\n      const target = event.relatedTarget\n\n      if (\n        !this.$refs.newPropertyContainer.contains(target) &&\n        this.newProperty.key != null\n      ) {\n        this.tryAddNewProperty()\n      }\n    },\n    tryAddNewProperty() {\n      if (!this.$refs.newPropertyForm.validate()) {\n        return false\n      }\n\n      this.$emit('add', this.newProperty)\n      this.$refs.newPropertyForm.reset()\n      return true\n    },\n    validate() {\n      if (!this.$refs.existingPropertyForms) {\n        return true\n      }\n\n      return this.$refs.existingPropertyForms.every(form => form.validate())\n    }\n  }\n}\n</script>\n\n<style lang=\"scss\">\n.base-dict-input__row {\n  display: flex;\n}\n\n.base-dict-input__row-last:not(:focus-within) {\n  opacity: 0.5;\n}\n\n.key-value-input {\n  flex-grow: 1;\n}\n\n.base-dict-input__action {\n  flex-grow: 0;\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/CheckboxDictInput.vue",
    "content": "<template>\n  <base-dict-input\n    ref=\"editor\"\n    :entries=\"internalValue\"\n    :readonly-key=\"readonlyKey\"\n    :readonly-type=\"readonlyType\"\n    :readonly-value=\"readonlyValue\"\n    :disable-add=\"disableAdd\"\n    :disable-remove=\"disableRemove\"\n    :show-types=\"showTypes\"\n    :types=\"types\"\n    class=\"checkbox-dict-input\"\n    @add=\"handleAdd\"\n    @update=\"handleUpdate\"\n    @remove=\"handleRemove\"\n  >\n    <template #before-existing=\"{entry, index}\">\n      <v-checkbox\n        :input-value=\"checked.includes(entry.key)\"\n        class=\"checkbox-dict-input__checkbox\"\n        @change=\"handleCheck($event, entry, index)\"\n      />\n    </template>\n    <template #before-new>\n      <v-checkbox\n        class=\"checkbox-dict-input__checkbox\"\n        :input-value=\"true\"\n        disabled\n      />\n    </template>\n  </base-dict-input>\n</template>\n\n<script>\nimport BaseDictInput from '@/components/CustomInputs/BaseDictInput'\nimport readonlyProps from '@/components/CustomInputs/readonlyProps'\nimport { isValidJson, tryParseJson, tryFormatJson } from '@/utils/json'\nimport { types, isValidType } from '@/utils/types'\n\nexport default {\n  name: 'CheckboxDictInput',\n  components: {\n    BaseDictInput\n  },\n  props: {\n    value: {\n      type: String,\n      required: false,\n      default: null\n    },\n    checked: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    showTypes: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    types: {\n      type: Array,\n      required: false,\n      default: () => types,\n      validator: value => value.every(isValidType)\n    },\n    ...readonlyProps\n  },\n  computed: {\n    internalValue() {\n      return this.convertValueToArray(this.value)\n    }\n  },\n  methods: {\n    isArray(value) {\n      return typeof value === 'object' && Array.isArray(value)\n    },\n    isArrayString(value) {\n      return isValidJson(value) && this.isArray(tryParseJson(value))\n    },\n    emitValue(value) {\n      const jsonValue = this.isArrayString(this.value)\n        ? tryFormatJson(value)\n        : tryFormatJson(this.convertArrayToObject(value))\n\n      this.$emit('input', jsonValue)\n    },\n    check(key) {\n      this.$emit('update:checked', [...this.checked.filter(x => x != key), key])\n    },\n    uncheck(key) {\n      this.$emit('update:checked', [...this.checked.filter(x => x != key)])\n    },\n    convertValueToArray(value) {\n      if (value == null || !isValidJson(value)) {\n        return []\n      }\n\n      if (this.isArray(value)) {\n        return value\n      }\n\n      const objectValue = tryParseJson(value)\n\n      if (this.isArray(objectValue)) {\n        return objectValue\n      }\n\n      const objectEntries = Object.entries(objectValue)\n\n      return objectEntries.map(([key, value]) => ({ key, value }))\n    },\n    convertArrayToObject(array) {\n      return array.reduce((value, entry) => {\n        value[entry.key] = entry.value\n\n        return value\n      }, {})\n    },\n    entryIsUnchecked({ key }) {\n      return this.internalValue.every(x => x.key != key)\n    },\n    addEntry(entry) {\n      this.emitValue([...this.internalValue, entry])\n      this.check(entry.key)\n    },\n    updateEntry(key, entry) {\n      this.emitValue([\n        ...this.internalValue.map(x => (x.key == key ? entry : x))\n      ])\n      this.check(entry.key)\n    },\n    removeEntry({ key }) {\n      this.emitValue([...this.internalValue.filter(x => x.key != key)])\n      this.uncheck(key)\n    },\n    addToValue(entry) {\n      this.emitValue([...this.internalValue, entry])\n    },\n    removeFromValue({ key }) {\n      this.emitValue([...this.internalValue.filter(x => x.key != key)])\n    },\n    handleCheck(checked, { key }) {\n      if (checked) {\n        this.check(key)\n      } else {\n        this.uncheck(key)\n      }\n    },\n    handleAdd(entry) {\n      this.addEntry(entry)\n    },\n    handleUpdate([entry, previous]) {\n      this.updateEntry(previous.key, entry)\n    },\n    handleRemove(entry) {\n      this.removeEntry(entry)\n    },\n    validate() {\n      return this.$refs.editor.validate()\n    }\n  }\n}\n</script>\n\n<style lang=\"scss\">\n.checkbox-dict-input__checkbox {\n  margin-top: 4px;\n\n  .v-input__slot {\n    margin: 0;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/CodeInput.vue",
    "content": "<template>\n  <div class=\"code-input\">\n    <v-btn-toggle\n      v-if=\"editors.length > 1\"\n      class=\"code-input__toggle\"\n      :value=\"internalMode\"\n      mandatory\n      @change=\"setMode\"\n    >\n      <v-btn\n        v-for=\"editor in editors\"\n        :key=\"editor\"\n        :value=\"editor\"\n        class=\"code-input__language-btn\"\n        x-small\n      >\n        {{ editor }}\n      </v-btn>\n    </v-btn-toggle>\n    <component\n      :is=\"editorComponents[internalMode]\"\n      ref=\"editor\"\n      v-model=\"internalValue\"\n      v-bind=\"editorProps[internalMode]\"\n      @update:checked=\"$emit('update:checked', $event)\"\n    />\n  </div>\n</template>\n\n<script>\nimport JsonInput2 from '@/components/CustomInputs/JsonInput2'\nimport YamlInput2 from '@/components/CustomInputs/YamlInput2'\nimport DictInput2 from '@/components/CustomInputs/DictInput2'\nimport CheckboxDictInput from '@/components/CustomInputs/CheckboxDictInput'\nimport readonlyProps from '@/components/CustomInputs/readonlyProps'\nimport Textarea from 'vuetify/lib/components/VTextarea'\nimport { tryParseJson, tryFormatJson } from '@/utils/json'\nimport { tryParseYaml, formatYaml } from '@/utils/yaml'\nimport { types, isValidType } from '@/utils/types'\n\nexport default {\n  name: 'CodeInput',\n  props: {\n    value: {\n      type: String,\n      required: false,\n      default: null\n    },\n    editors: {\n      type: Array,\n      required: false,\n      default: () => ['dict', 'json'],\n      validator: value =>\n        value.length > 0 &&\n        value.every(lang => ['json', 'yaml', 'dict', 'text'].includes(lang))\n    },\n    mode: {\n      type: String,\n      required: false,\n      default: null,\n      validator: value => ['json', 'yaml', 'dict', 'text'].includes(value)\n    },\n    showTypes: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    showCheckboxes: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    placeholder: {\n      type: String,\n      required: false,\n      default: null\n    },\n    types: {\n      type: Array,\n      required: false,\n      default: () => types,\n      validator: value => value.every(isValidType)\n    },\n    checked: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    ...readonlyProps\n  },\n  data() {\n    return {\n      localMode: null\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    },\n    internalMode: {\n      get() {\n        return this.mode ?? this.localMode\n      },\n      set(value) {\n        this.$emit('update:mode', value)\n        this.localMode = value\n      }\n    },\n    editorComponents() {\n      return {\n        json: JsonInput2,\n        yaml: YamlInput2,\n        dict: this.showCheckboxes ? CheckboxDictInput : DictInput2,\n        text: Textarea\n      }\n    },\n    editorProps() {\n      return {\n        json: {\n          placeholder: this.placeholder,\n          disabled: this.readonlyValue\n        },\n        yaml: {\n          placeholder: this.placeholder,\n          disabled: this.readonlyValue\n        },\n        text: {\n          placeholder: this.placeholder,\n          disabled: this.readonlyValue,\n          outlined: true,\n          autoGrow: true\n        },\n        dict: {\n          readonlyKey: this.readonlyKey,\n          readonlyType: this.readonlyType,\n          readonlyValue: this.readonlyValue,\n          disableAdd: this.disableAdd,\n          disableRemove: this.disableRemove,\n          showTypes: this.showTypes,\n          types: this.types,\n          checked: this.checked\n        }\n      }\n    }\n  },\n  created() {\n    if (this.internalMode == null) {\n      this.setMode(this.editors[0])\n    }\n  },\n  methods: {\n    setMode(mode) {\n      if (this.internalValue != null) {\n        const value = this.tryGetValueObject(this.internalValue)\n\n        if (value != null) {\n          this.internalValue = this.formatValueToString(mode, value)\n        }\n      }\n\n      this.internalMode = mode\n    },\n    formatValueToString(mode, value) {\n      switch (mode) {\n        case 'yaml':\n          return formatYaml(value)\n        case 'json':\n          return tryFormatJson(value)\n        case 'dict':\n          return tryFormatJson(value)\n        case 'text':\n          return tryFormatJson(value)\n      }\n    },\n    tryGetValueObject(value) {\n      return tryParseYaml(value) ?? tryParseJson(value)\n    },\n    validate() {\n      if (this.internalMode == 'text') {\n        return true\n      }\n\n      return this.$refs.editor.validate()\n    }\n  }\n}\n</script>\n<style lang=\"scss\">\n.code-input {\n  display: flex;\n  flex-direction: column;\n\n  textarea {\n    font-family: monospace, monospace;\n    font-size: 13px;\n    line-height: 13px !important;\n    min-height: 56px;\n    overflow-y: auto;\n    resize: vertical;\n  }\n}\n\n.code-input__toggle {\n  align-self: flex-end;\n  margin-bottom: 8px;\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/DictInput.vue",
    "content": "<script>\nimport JsonInput from '@/components/CustomInputs/JsonInput'\nimport jsBeautify from 'js-beautify'\n\nexport default {\n  components: {\n    JsonInput\n  },\n  props: {\n    includeCheckbox: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    addLabel: {\n      type: String,\n      requird: false,\n      default: 'Add key / value'\n    },\n    allowReset: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    dict: {\n      type: [Object, Array],\n      required: false,\n      default: () => {\n        return null\n      }\n    },\n    disableEdit: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    keyLabel: {\n      type: String,\n      requird: false,\n      default: 'Key'\n    },\n    valueLabel: {\n      type: String,\n      requird: false,\n      default: 'Value'\n    },\n    defaultCheckedKeys: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    return {\n      disabledKeys: [],\n      json: false,\n      jsonInput: '{}',\n      keys: [],\n      values: [],\n      includedKeys: this.defaultCheckedKeys\n    }\n  },\n  computed: {\n    inputIsArray() {\n      return Array.isArray(this.dict)\n    },\n    pairs() {\n      return this.keys.map((p, i) => i)\n    },\n    value() {\n      const dict = {}\n      this.keys.forEach((k, i) => {\n        // Ignore null key/val pairs\n        if (k == null && this.values[i] == null) return\n        if (\n          !this.includeCheckbox ||\n          (this.json && Object.keys(JSON.parse(this.jsonInput)).includes(k)) ||\n          (!this.json && this.includedKeys.includes(k))\n        ) {\n          try {\n            dict[k] =\n              typeof this.values[i] == 'string'\n                ? JSON.parse(this.values[i])\n                : this.values[i]\n          } catch {\n            dict[k] = this.values[i]\n          }\n        }\n      })\n      return dict\n    }\n  },\n\n  watch: {\n    // Allows swapping between json input and key value pairs\n    json(val) {\n      if (val) {\n        this.jsonInput = jsBeautify(this.jsonInput, {\n          indent_size: 4,\n          space_in_empty_paren: true,\n          preserve_newlines: true,\n          indent_empty_lines: true\n        })\n\n        // Use next tick to make sure the json input element exists\n        this.$nextTick(() => {\n          this.$refs['json-input'].validateJson()\n        })\n      } else {\n        try {\n          this.includedKeys = Object.keys(JSON.parse(this.jsonInput))\n        } catch {\n          this.includedKeys = Object.keys(this.value)\n        }\n      }\n\n      this.$emit('toggle-json-editor', val)\n    },\n    includedKeys(val) {\n      this.jsonInput = val.length > 0 ? JSON.stringify(this.value) : '{}'\n      this.$emit('input', { ...this.value })\n    }\n  },\n  mounted() {\n    this.reset()\n  },\n  methods: {\n    _handleJsonInput() {\n      // Allows swapping between json input and key value pairs\n      try {\n        const json = JSON.parse(this.jsonInput)\n\n        if (this.includeCheckbox) {\n          Object.keys(json).forEach(k => {\n            let i = this.keys.indexOf(k)\n\n            if (i > -1) {\n              this.values[i] =\n                typeof json[k] === 'string' ? json[k] : JSON.stringify(json[k])\n            } else {\n              this.keys.push(k)\n              this.values.push(\n                typeof json[k] === 'string' ? json[k] : JSON.stringify(json[k])\n              )\n            }\n          })\n        } else {\n          this.keys = Object.keys(json)\n          this.values = Object.values(json).map(value =>\n            typeof value === 'string' ? value : JSON.stringify(value)\n          )\n        }\n        this.$emit('input', { ...this.value })\n      } catch {\n        this.$refs['json-input'].validateJson()\n      }\n    },\n    _handleKeypress() {\n      this.jsonInput = this.keys.length > 0 ? JSON.stringify(this.value) : '{}'\n      this.$emit('input', { ...this.value })\n    },\n    addKeyValuePair() {\n      this.keys.push(null)\n      this.values.push(null)\n    },\n    removeKeyValuePair(i) {\n      this.keys.splice(i, 1)\n      this.values.splice(i, 1)\n\n      if (this.keys.length === 0) {\n        this.keys = [null]\n        this.values = [null]\n      }\n\n      this.$emit('input', { ...this.value })\n    },\n    reset() {\n      this.disabledKeys = this.inputIsArray\n        ? this.dict\n            .filter(entry => entry.disabled == true)\n            .map(entry => entry.key)\n        : []\n      if (this.includeCheckbox && this.includedKeys.length === 0) {\n        this.jsonInput = '{}'\n      } else if (\n        this.includeCheckbox &&\n        this.includedKeys.length > 0 &&\n        this.inputIsArray\n      ) {\n        const v = this.dict.filter(i => this.includedKeys.includes(i.key))\n\n        this.jsonInput = JSON.stringify(\n          Object.fromEntries(v.map(entry => [entry.key, entry.value]))\n        )\n      } else {\n        this.jsonInput = this.inputIsArray\n          ? JSON.stringify(\n              Object.fromEntries(\n                this.dict.map(entry => [entry.key, entry.value])\n              )\n            )\n          : this.dict\n          ? JSON.stringify(this.dict)\n          : `\n        {\n\n        }\n              `\n      }\n\n      this.keys = this.inputIsArray\n        ? this.dict.map(entry => entry.key)\n        : this.dict\n        ? Object.keys(this.dict)\n        : [null]\n\n      this.values = this.inputIsArray\n        ? this.dict.map(entry =>\n            typeof entry.value == 'string'\n              ? entry.value\n              : JSON.stringify(entry.value)\n          )\n        : this.dict\n        ? Object.values(this.dict).map(value => JSON.stringify(value))\n        : [null]\n\n      this.$emit('input', { ...this.value })\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"position-relative\">\n    <div class=\"d-flex justify-end align-end mb-1\" style=\"width: 100%;\">\n      <v-btn\n        v-if=\"allowReset\"\n        x-small\n        class=\"text-normal mr-2\"\n        depressed\n        color=\"utilGrayLight\"\n        title=\"Reset\"\n        @click=\"reset\"\n      >\n        Reset\n        <v-icon small>refresh</v-icon>\n      </v-btn>\n\n      <v-switch\n        v-if=\"!disabled\"\n        v-model=\"json\"\n        inset\n        label=\"JSON\"\n        class=\"mt-0 small-switch v-input--reverse\"\n        hide-details\n      ></v-switch>\n    </div>\n\n    <div v-if=\"json\">\n      <JsonInput\n        ref=\"json-input\"\n        v-model=\"jsonInput\"\n        prepend-icon=\"fad fa-file-code\"\n        prepend-icon-label=\"JSON\"\n        selected-type=\"json\"\n        @input=\"_handleJsonInput\"\n      />\n    </div>\n\n    <div v-else>\n      <transition-group name=\"fade\" mode=\"out-in\">\n        <v-row\n          v-for=\"(pair, i) in pairs\"\n          :key=\"pair\"\n          no-gutters\n          align=\"center\"\n          class=\"my-4 position-relative\"\n          :class=\"{ 'pr-8': !disableEdit }\"\n        >\n          <v-col v-if=\"includeCheckbox\" cols=\"1\">\n            <v-checkbox\n              v-model=\"includedKeys\"\n              multiple\n              :value=\"keys[i]\"\n            ></v-checkbox>\n          </v-col>\n          <v-col :cols=\"includeCheckbox ? 3 : 4\" class=\"pr-3\">\n            <v-text-field\n              v-model=\"keys[i]\"\n              class=\"text-body-1\"\n              hide-details\n              outlined\n              :disabled=\"disabled\"\n              dense\n              :placeholder=\"keyLabel\"\n              :readonly=\"disabledKeys.includes(keys[i])\"\n              @keyup=\"_handleKeypress\"\n            />\n          </v-col>\n          <v-col cols=\"8\" class=\"pl-3\">\n            <v-text-field\n              v-model=\"values[i]\"\n              class=\"text-body-1\"\n              hide-details\n              :disabled=\"disabled\"\n              outlined\n              dense\n              :placeholder=\"\n                inputIsArray && dict[i] && dict[i].value\n                  ? dict[i].value.toString()\n                  : valueLabel\n              \"\n              :readonly=\"\n                includeCheckbox ? !includedKeys.includes(keys[i]) : false\n              \"\n              @keyup=\"_handleKeypress\"\n            />\n          </v-col>\n\n          <v-btn\n            v-if=\"\n              !disableEdit &&\n                (i !== 0 || keys[i] !== null || values[i] !== null)\n            \"\n            class=\"remove-button\"\n            depressed\n            icon\n            fab\n            x-small\n            @click=\"removeKeyValuePair(i)\"\n          >\n            <v-icon color=\"red\">remove_circle</v-icon>\n          </v-btn>\n        </v-row>\n      </transition-group>\n\n      <div v-if=\"!disableEdit\" class=\"text-center\">\n        <v-btn\n          class=\"mx-auto px-8 text-none\"\n          depressed\n          text\n          color=\"primary\"\n          @click=\"addKeyValuePair\"\n        >\n          {{ addLabel }}\n          <v-icon right>\n            add\n          </v-icon>\n        </v-btn>\n      </div>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.remove-button {\n  position: absolute;\n  right: 0;\n}\n\n.v-input--is-readonly {\n  background-color: rgba(0, 0, 0, 0.03) !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/DictInput2.vue",
    "content": "<template>\n  <base-dict-input\n    ref=\"editor\"\n    :entries=\"internalValue\"\n    :readonly-key=\"readonlyKey\"\n    :readonly-type=\"readonlyType\"\n    :readonly-value=\"readonlyValue\"\n    :disable-add=\"disableAdd\"\n    :disable-remove=\"disableRemove\"\n    :show-types=\"showTypes\"\n    :types=\"types\"\n    @add=\"handleAdd\"\n    @update=\"handleUpdate\"\n    @remove=\"handleRemove\"\n  />\n</template>\n\n<script>\nimport BaseDictInput from '@/components/CustomInputs/BaseDictInput'\nimport readonlyProps from '@/components/CustomInputs/readonlyProps'\nimport { isValidJson, tryParseJson, tryFormatJson } from '@/utils/json'\nimport { types, isValidType } from '@/utils/types'\n\nexport default {\n  name: 'DictInput',\n  components: {\n    BaseDictInput\n  },\n  props: {\n    value: {\n      type: String,\n      required: false,\n      default: null\n    },\n    showTypes: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    types: {\n      type: Array,\n      required: false,\n      default: () => types,\n      validator: value => value.every(isValidType)\n    },\n    ...readonlyProps\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.convertValueToArray(this.value)\n      },\n      set(value) {\n        if (this.isArrayString(this.value)) {\n          this.$emit('input', tryFormatJson(value))\n        }\n\n        this.$emit('input', tryFormatJson(this.convertArrayToObject(value)))\n      }\n    }\n  },\n  methods: {\n    isArray(value) {\n      return typeof value === 'object' && Array.isArray(value)\n    },\n    isArrayString(value) {\n      return isValidJson(value) && this.isArray(tryParseJson(value))\n    },\n    convertValueToArray(value) {\n      if (value == null || !isValidJson(value)) {\n        return []\n      }\n\n      if (this.isArray(value)) {\n        return value\n      }\n\n      const objectValue = tryParseJson(value)\n\n      if (this.isArray(objectValue)) {\n        return objectValue\n      }\n\n      const objectEntries = Object.entries(objectValue)\n\n      return objectEntries.map(([key, value]) => ({ key, value }))\n    },\n    convertArrayToObject(array) {\n      return array.reduce((value, entry) => {\n        value[entry.key] = entry.value\n\n        return value\n      }, {})\n    },\n    handleAdd(entry) {\n      this.internalValue = [...this.internalValue, entry]\n    },\n    handleUpdate([entry, previous]) {\n      this.internalValue = [\n        ...this.internalValue.map(x => (x.key == previous.key ? entry : x))\n      ]\n    },\n    handleRemove({ key }) {\n      this.internalValue = [...this.internalValue.filter(x => x.key != key)]\n    },\n    validate() {\n      return this.$refs.editor.validate()\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/Highlight.vue",
    "content": "<template>\n  <pre>\n    <!-- eslint-disable vue/no-v-html -->\n    <code :class=\"classes.code\" v-html=\"html\" />\n  </pre>\n</template>\n\n<script>\nimport hljs from 'highlight.js/lib/core.js'\nimport json from 'highlight.js/lib/languages/json'\nimport yaml from 'highlight.js/lib/languages/yaml'\nimport { escapeHTML } from '@/utils/html'\n\nexport default {\n  props: {\n    language: {\n      type: String,\n      required: false,\n      default: null,\n      validator: value => [null, 'json', 'yaml'].includes(value)\n    },\n    code: {\n      type: String,\n      required: false,\n      default: null\n    },\n    autodetect: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    ignoreIllegals: {\n      type: Boolean,\n      default: true\n    }\n  },\n  data() {\n    return {\n      detectedLanguage: ''\n    }\n  },\n  computed: {\n    classes() {\n      return {\n        code: 'hljs ' + this.detectedLanguage\n      }\n    },\n    html() {\n      if (!this.code) {\n        return ''\n      }\n\n      if (this.autoDetect || this.language == null) {\n        this.tryDetectingLanguage()\n      }\n\n      if (this.languageNotSupported) {\n        return escapeHTML(this.code)\n      }\n\n      const { value } = hljs.highlight(this.code, {\n        language: this.language,\n        ignoreIllegals: this.ignoreIllegals\n      })\n\n      return value\n    },\n    languageNotSupported() {\n      return !hljs.getLanguage(this.language)\n    }\n  },\n  created() {\n    hljs.registerLanguage('json', json)\n    hljs.registerLanguage('yaml', yaml)\n  },\n  methods: {\n    tryDetectingLanguage() {\n      const { language } = hljs.highlightAuto(this.code)\n\n      this.detectedLanguage = language\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/JsonInput.vue",
    "content": "<script>\nimport jsBeautify from 'js-beautify'\nimport { codemirror } from 'vue-codemirror'\nimport debounce from 'lodash/debounce'\n\nimport 'codemirror/addon/edit/matchbrackets'\nimport 'codemirror/addon/edit/closebrackets'\nimport 'codemirror/mode/javascript/javascript.js'\nimport 'codemirror/lib/codemirror.css'\nimport 'codemirror/addon/display/placeholder'\nimport '@/styles/json-input-style.scss'\n\nexport default {\n  components: {\n    CodeMirror: codemirror\n  },\n  props: {\n    backgroundColor: {\n      type: String,\n      default: () => 'transparent'\n    },\n    disabled: {\n      type: Boolean,\n      default: () => false\n    },\n    prependIcon: {\n      type: String,\n      required: false,\n      default: ''\n    },\n    prependIconLabel: {\n      type: String,\n      required: false,\n      default: null\n    },\n    selectedType: {\n      type: String,\n      default: null,\n      required: false\n    },\n    // If true, editor height updates based on content.\n    heightAuto: {\n      type: Boolean,\n      default: () => false,\n      required: false\n    },\n    value: {\n      type: String,\n      default: () => '',\n      required: false\n    },\n    newParameterInput: {\n      type: String,\n      default: '',\n      required: false\n    },\n    placeholderText: {\n      type: String,\n      default: '',\n      required: false\n    },\n    skipRequired: {\n      type: Boolean,\n      default: false,\n      required: false\n    },\n    addCorners: {\n      type: Boolean,\n      default: false,\n      required: false\n    }\n  },\n  data() {\n    return {\n      // Line of JSON that contains a syntax error\n      errorLine: null,\n      // The JSON may need to be modified for formatting.\n      // Store the JSON prop's value internally as data so the JSON can be modified.\n      internalValue: this.value,\n      jsonError: '',\n      focussed: false\n    }\n  },\n  computed: {\n    cmInstance() {\n      return this.$refs.cmRef && this.$refs.cmRef.codemirror\n    },\n    updateBorder() {\n      if (this.prependIcon) return true\n      if (this.addCorners) return true\n      return false\n    },\n    iconColor() {\n      if (this.jsonError) return 'error'\n      if (this.focussed) return 'primary'\n      return 'grey'\n    },\n    editorOptions() {\n      return {\n        autoCloseBrackets: true,\n        matchBrackets: true,\n        mode: 'application/json',\n        theme: this.selectedType == 'json' ? 'json-input' : 'light',\n        readOnly: this.disabled,\n        smartIndent: true,\n        lineWrapping: true,\n        placeholder: this.placeholderText,\n        tabSize: 4\n      }\n    }\n  },\n  watch: {\n    // Keep value prop in sync with value saved as data\n    value() {\n      this.internalValue = this.value\n    }\n  },\n  methods: {\n    formatJson() {\n      this.internalValue = jsBeautify(this.internalValue, {\n        indent_size: 4,\n        space_in_empty_paren: true,\n        preserve_newlines: false\n      })\n    },\n    handleJsonInput(event) {\n      this.removeJsonErrors()\n      this.$emit('input', event)\n      if (this.selectedType === 'json') this.validateJson(event)\n    },\n    markJsonErrors(syntaxError) {\n      const errorIndex = syntaxError?.message?.split(' ').pop()\n      const errorPosition = this.cmInstance.doc.posFromIndex(errorIndex)\n      this.errorLine = errorPosition.line\n      this.cmInstance.doc.addLineClass(\n        this.errorLine,\n        'text',\n        'json-input-error-text'\n      )\n    },\n    removeJsonErrors() {\n      this.jsonError = ''\n      if (this.errorLine == null) return\n      this.cmInstance.doc.removeLineClass(\n        this.errorLine,\n        'text',\n        'json-input-error-text'\n      )\n\n      this.errorLine = null\n    },\n    // JSON validation is only used within this component for secrets.\n    // Parent components are responsible for imperatively validating JSON using a ref to this component.\n    validateJson: debounce(function(event) {\n      if (this.newParameterInput) this.internalValue = this.newParameterInput\n      const input = event || this.internalValue\n      try {\n        // Treat empty or null inputs as valid\n        if (!input || (input && input.trim() === '')) {\n          if (this.skipRequired) return\n          this.jsonError = 'Please enter a value.'\n          this.$emit('invalid-secret', true)\n          return 'MissingError'\n        }\n        // Attempt to parse JSON and catch syntax errors\n        JSON.parse(input)\n        this.removeJsonErrors()\n        this.$emit('invalid-secret', false)\n        return true\n      } catch (err) {\n        if (err instanceof SyntaxError) {\n          this.markJsonErrors(err)\n          this.$emit('invalid-secret', true)\n          this.jsonError = `\n          There is a syntax error in your JSON.\n        `\n          return 'SyntaxError'\n        } else {\n          throw err\n        }\n      }\n    }, 300)\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"position-relative json-input-empty-text\"\n    :class=\"{\n      'json-input-height-auto': heightAuto\n    }\"\n  >\n    <div\n      class=\"position-absolute text-center\"\n      :style=\"{\n        top: '12px',\n        left: '12px',\n        'z-index': 3\n      }\"\n    >\n      <v-icon :color=\"iconColor\">\n        {{ prependIcon }}\n      </v-icon>\n      <div class=\"text-caption o-20\">\n        {{ prependIconLabel }}\n      </div>\n    </div>\n    <CodeMirror\n      ref=\"cmRef\"\n      data-cy=\"code-mirror-input\"\n      :value=\"internalValue\"\n      class=\"pt-2 cm-style json-input\"\n      :class=\"{\n        'pl-9': prependIcon,\n        'pl-4': addCorners,\n        'pl-12': prependIconLabel,\n        'blue-border': updateBorder && focussed && !jsonError,\n        'red-border': updateBorder && jsonError,\n        'plain-border': updateBorder && !focussed && !jsonError,\n        'original-border': !updateBorder,\n        [backgroundColor]: true\n      }\"\n      :options=\"editorOptions\"\n      @input=\"handleJsonInput($event)\"\n      @focus=\"focussed = true\"\n      @blur=\"focussed = false\"\n    ></CodeMirror>\n\n    <slot></slot>\n    <v-btn\n      class=\"position-absolute\"\n      :style=\"{\n        bottom: '25px',\n        right: '10px',\n        'z-index': 3\n      }\"\n      text\n      small\n      color=\"accent\"\n      @click=\"formatJson\"\n    >\n      Format\n    </v-btn>\n\n    <div class=\"text-caption red--text min-height pl-4\">{{ jsonError }}</div>\n  </div>\n</template>\n\n<style lang=\"scss\">\n/*\n  IMPORTANT: These styles must be globally scoped.\n\n  There is CodeMirror code in <script /> that sets the .json-input-error-text class on any\n  lines in the JSON editor with JSON syntax issues.\n\n  Due to low CSS specificity, the styles in the .json-input-error-text class will not set\n  if the component is locally scoped.\n\n  For the same reason, the .json-input-error-text styles must also be marked as !important.\n\n  To mitigate the effect of these global styles, each style will be prepended\n  with json-input-, for \"Run Flow Page\".\n*/\n\n/* stylelint-disable selector-class-pattern */\n.json-input {\n  .CodeMirror {\n    cursor: text !important;\n    font-family: inherit !important;\n    height: 300px;\n  }\n\n  .CodeMirror-placeholder {\n    color: var(--v-utilGrayMid-base) !important;\n  }\n\n  .CodeMirror-scroll {\n    padding-bottom: 0px;\n  }\n  .json-input-height-auto {\n    .CodeMirror {\n      height: auto;\n      min-height: 108px;\n    }\n  }\n\n  .json-input-empty-text {\n    .CodeMirror-empty {\n      color: var(--v-utilGrayMid-base);\n    }\n\n    .CodeMirror-cursor {\n      height: auto !important;\n    }\n  }\n\n  /* stylelint-enable selector-class-pattern */\n\n  .json-input-error-text {\n    text-decoration: var(--v-error-base) wavy underline !important;\n  }\n}\n</style>\n\n<style lang=\"scss\" scoped>\n.min-height {\n  height: 15px;\n}\n\n.cm-style {\n  color: rgba(0, 0, 0, 0.38);\n  font-size: inherit !important;\n  height: auto;\n  position: relative;\n\n  &:hover,\n  &:focus {\n    color: rgba(0, 0, 0, 0.86);\n  }\n\n  &::after {\n    background: transparent;\n    content: '';\n    height: 100%;\n    left: 0;\n    pointer-events: none;\n    position: absolute;\n    top: 0;\n    transition: all 50ms;\n    width: 100%;\n  }\n\n  &.red-border::after {\n    border: 2px solid var(--v-error-base);\n    border-radius: 4px;\n  }\n\n  &.blue-border::after {\n    border: 2px solid var(--v-primary-base);\n    border-radius: 4px;\n  }\n\n  &.plain-border::after {\n    border: 1px solid currentColor;\n    border-radius: 4px;\n  }\n\n  &.original-border::after {\n    border: 1px solid currentColor;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/JsonInput2.vue",
    "content": "<template>\n  <base-code-textarea\n    ref=\"editor\"\n    v-model=\"internalValue\"\n    :readonly=\"readonly\"\n    :placeholder=\"placeholder\"\n    :get-errors=\"getJsonErrors\"\n    :format=\"tryFormatJson\"\n    :parse=\"tryParseJson\"\n    language=\"json\"\n  />\n</template>\n\n<script>\nimport BaseCodeTextarea from '@/components/CustomInputs/BaseCodeTextarea'\nimport { tryParseJson, parseJson, tryFormatJson } from '@/utils/json'\n\nexport default {\n  name: 'JsonInput',\n  components: {\n    BaseCodeTextarea\n  },\n  props: {\n    value: {\n      type: String,\n      required: false,\n      default: null\n    },\n    readonly: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    placeholder: {\n      type: String,\n      required: false,\n      default: null\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  },\n  methods: {\n    validate() {\n      return this.$refs.editor.validate(this.internalValue)\n    },\n    getJsonErrors(value) {\n      if (value == '') {\n        return []\n      }\n\n      try {\n        parseJson(value)\n        return []\n      } catch (e) {\n        return [e.toString()]\n      }\n    },\n    tryParseJson,\n    tryFormatJson\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/KeyValueInput.vue",
    "content": "<template>\n  <fieldset class=\"key-value-input\">\n    <v-text-field\n      v-model=\"internalKey\"\n      label=\"Key\"\n      class=\"key-value-input__key-input\"\n      :error-messages=\"keyErrors\"\n      :disabled=\"readonlyKey\"\n      outlined\n      dense\n      @input=\"validateKey\"\n    />\n    <template v-if=\"showTypes && hasTypes\">\n      <v-select\n        data-public\n        v-model=\"selectedType\"\n        :items=\"[emptyTypeOption, ...types]\"\n        label=\"Type\"\n        class=\"key-value-input__type-input\"\n        :disabled=\"singleTypeMode || readonlyType\"\n        outlined\n        dense\n        @input=\"handleTypeInput\"\n      />\n    </template>\n    <component\n      :is=\"valueComponent\"\n      ref=\"valueInput\"\n      v-model=\"internalValue\"\n      class=\"key-value-input__value-input\"\n      v-bind=\"valueProps\"\n      @input=\"handleValueInput\"\n    />\n  </fieldset>\n</template>\n\n<script>\nimport InputTypes from '@/components/CustomInputs/KeyValueTypeInputs'\nimport readonlyProps from '@/components/CustomInputs/readonlyProps'\nimport { isIsoDateString } from '@/utils/dateTime'\nimport { types, isValidType } from '@/utils/types'\n\nexport default {\n  name: 'KeyValueInput',\n  props: {\n    value: {\n      type: Object,\n      required: false,\n      default: null\n    },\n    showTypes: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    types: {\n      type: Array,\n      required: false,\n      default: () => types,\n      validator: value => value.every(isValidType)\n    },\n    ...readonlyProps\n  },\n  data() {\n    return {\n      selectedType: null,\n      emptyTypeOption: { text: 'Auto', value: null },\n      typeIsInferred: true,\n      valueComponent: InputTypes.JsonParsingInput,\n      keyErrors: []\n    }\n  },\n  computed: {\n    internalKey: {\n      get() {\n        return this.value?.key\n      },\n      set(value) {\n        this.$emit('input', { ...this.value, key: value })\n      }\n    },\n    internalValue: {\n      get() {\n        return this.value?.value\n      },\n      set(value) {\n        this.$emit('input', { ...this.value, value: value })\n      }\n    },\n    valueProps() {\n      const props = { disabled: this.readonlyValue }\n\n      if (this.valueComponent == InputTypes.JsonParsingInput) {\n        props.types = this.types\n      }\n\n      return props\n    },\n    valueCanBeEmpty() {\n      return this.isTypeAcceptable('None') || this.isTypeAcceptable('String')\n    },\n    showingTypes() {\n      return this.showTypes && !this.singleTypeMode\n    },\n    hasTypes() {\n      return this.types?.length > 0\n    },\n    singleTypeMode() {\n      return this.types?.length === 1\n    }\n  },\n  watch: {\n    value: {\n      deep: true,\n      handler({ value }) {\n        if (this.hasFocus()) {\n          return\n        }\n\n        if (this.showingTypes) {\n          this.trySettingType(value)\n          this.trySettingValueComponent(this.selectedType)\n        }\n      }\n    }\n  },\n  created() {\n    this.checkSingleTypeMode()\n\n    if (this.showingTypes) {\n      this.trySettingType(this.internalValue)\n      this.trySettingValueComponent(this.selectedType)\n    }\n\n    if (this.selectedType != null) {\n      this.typeIsInferred = false\n    }\n  },\n  methods: {\n    checkSingleTypeMode() {\n      if (this.singleTypeMode) {\n        this.selectedType = this.types[0]\n        this.valueComponent = this.getValueComponentForType(this.types[0])\n      }\n    },\n    trySettingType(value) {\n      const type = this.discoverType(value)\n\n      this.selectedType = this.isTypeAcceptable(type) ? type : null\n    },\n    handleTypeInput(type) {\n      this.typeIsInferred = type === null\n      this.valueComponent = this.getValueComponentForType(type)\n    },\n    handleValueInput(value) {\n      if (this.showingTypes && this.typeIsInferred) {\n        this.trySettingType(value)\n      }\n    },\n    trySettingValueComponent(type) {\n      if (type != null) {\n        this.valueComponent = this.getValueComponentForType(type)\n      }\n    },\n    getValueComponentForType(type) {\n      switch (type) {\n        case null:\n          return InputTypes.JsonParsingInput\n        case 'Boolean':\n          return InputTypes.BooleanInput\n        case 'Integer':\n          return InputTypes.NumberInput\n        case 'List':\n          return InputTypes.ArrayInput\n        case 'Date':\n          return InputTypes.DateInput\n        case 'Dictionary':\n          return InputTypes.ObjectInput\n        case 'None':\n          return InputTypes.NullInput\n        case 'String':\n        default:\n          return InputTypes.StringInput\n      }\n    },\n    isTypeAcceptable(type) {\n      if (type == 'None' && this.internalKey == null) {\n        return false\n      }\n\n      return this.types == null || this.types.includes(type)\n    },\n    discoverType(value) {\n      const type = typeof value\n\n      switch (type) {\n        case 'object':\n          return this.discoverObjectType(value)\n        case 'string':\n          return this.discoverStringType(value)\n        case 'number':\n        case 'bigint':\n          return 'Integer'\n        case 'boolean':\n          return 'Boolean'\n      }\n\n      return null\n    },\n    discoverStringType(value) {\n      if (isIsoDateString(value)) {\n        return 'Date'\n      }\n\n      return 'String'\n    },\n    discoverObjectType(value) {\n      if (value === null) {\n        return 'None'\n      }\n\n      if (value instanceof Array) {\n        return 'List'\n      }\n\n      if (value instanceof Date) {\n        return 'Date'\n      }\n\n      return 'Dictionary'\n    },\n    hasFocus() {\n      return this.$el.contains(document.activeElement)\n    },\n    getKeyErrors(value) {\n      if (value == null || value.length == 0) {\n        return ['Key is required']\n      }\n\n      return []\n    },\n    validateKey(value) {\n      this.keyErrors = this.getKeyErrors(value)\n\n      return this.keyErrors.length == 0\n    },\n    validateValue(value) {\n      return this.$refs.valueInput.validate(value)\n    },\n    validate() {\n      return (\n        this.validateKey(this.internalKey) &&\n        this.validateValue(this.internalValue)\n      )\n    },\n    reset() {\n      this.selectedType = null\n      this.handleTypeInput(null)\n      this.checkSingleTypeMode()\n      this.$emit('input', { value: null, key: null })\n    }\n  }\n}\n</script>\n\n<style lang=\"scss\">\n.key-value-input {\n  display: flex;\n  gap: 24px;\n  border: none;\n}\n\n.key-value-input__key-input {\n  flex-basis: 0;\n}\n\n.key-value-input__type-input {\n  width: 134px;\n  flex-grow: 0;\n}\n\n.key-value-input__value-input {\n  flex-basis: 0 !important;\n  flex-grow: 2 !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/KeyValueTypeInputs/ArrayInput.vue",
    "content": "<template>\n  <v-text-field\n    v-model=\"internalValue\"\n    :error-messages=\"errors\"\n    :disabled=\"disabled\"\n    label=\"Value\"\n    outlined\n    dense\n    @input=\"validate\"\n  />\n</template>\n\n<script>\nimport {\n  isValidJson,\n  tryParseJson,\n  tryFormatSingleLineJson\n} from '@/utils/json'\n\nexport default {\n  name: 'ArrayInput',\n  props: {\n    value: {\n      type: [String, Number, Boolean, Object, Array],\n      required: false,\n      default: null\n    },\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    return {\n      errors: []\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return tryFormatSingleLineJson(this.value)\n      },\n      set(value) {\n        this.$emit('input', tryParseJson(value) ?? value)\n      }\n    }\n  },\n  mounted() {\n    if (this.isArray(this.value)) {\n      return\n    }\n\n    if (this.isArrayString(this.value)) {\n      this.internalValue = this.value\n    } else {\n      this.internalValue = '[]'\n    }\n  },\n  methods: {\n    isArray(value) {\n      return typeof value === 'object' && Array.isArray(value)\n    },\n    isArrayString(value) {\n      return isValidJson(value) && this.isArray(tryParseJson(value))\n    },\n    isArrayOrArrayString(value) {\n      return this.isArray(value) || this.isArrayString(value)\n    },\n    validate(value) {\n      this.errors = this.getErrors(value)\n\n      return this.errors.length == 0\n    },\n    getErrors(value) {\n      if (value == null) {\n        return ['Value is required']\n      }\n\n      if (!this.isArrayOrArrayString(value)) {\n        return ['Value is expected to be a List']\n      }\n\n      return []\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/KeyValueTypeInputs/BooleanInput.vue",
    "content": "<template>\n  <v-radio-group\n    v-model=\"internalValue\"\n    :error-messages=\"errors\"\n    :disabled=\"disabled\"\n    outlined\n    dense\n    mandatory\n    row\n    @input=\"validate\"\n  >\n    <v-radio label=\"true\" :value=\"1\" />\n    <v-radio label=\"false\" :value=\"0\" />\n  </v-radio-group>\n</template>\n\n<script>\nexport default {\n  name: 'BooleanInput',\n  props: {\n    value: {\n      type: [String, Number, Boolean, Object, Array],\n      required: false,\n      default: null\n    },\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    return {\n      errors: []\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value ? 1 : 0\n      },\n      set(value) {\n        this.$emit('input', !!value)\n      }\n    }\n  },\n  mounted() {\n    if (typeof this.value != 'boolean') {\n      this.internalValue =\n        this.value === 1 || this.value === 'true' || this.value === '1'\n    }\n  },\n  methods: {\n    validate(value) {\n      this.errors = this.getErrors(value)\n\n      return this.errors.length == 0\n    },\n    getErrors(value) {\n      if (value == null) {\n        return ['Value is required']\n      }\n\n      return []\n    }\n  }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.v-input--selection-controls {\n  margin-top: 4px;\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/KeyValueTypeInputs/DateInput.vue",
    "content": "<template>\n  <date-time\n    v-model=\"internalValue\"\n    allow-past-date\n    :disabled=\"disabled\"\n    :text-field-props=\"{\n      label: 'Value',\n      outlined: true,\n      dense: true,\n      errorMessages: errors\n    }\"\n    @input=\"validate\"\n  />\n</template>\n\n<script>\nimport DateTime from '@/components/DateTime'\nimport { isIsoDateString } from '@/utils/dateTime'\n\nexport default {\n  name: 'DateInput',\n  components: {\n    DateTime\n  },\n  props: {\n    value: {\n      type: [String, Number, Boolean, Object, Array],\n      required: false,\n      default: null\n    },\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    return {\n      errors: []\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        if (typeof this.value != 'string' || !isIsoDateString(this.value)) {\n          return null\n        }\n\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  },\n  mounted() {\n    if (typeof this.value != 'string' || !isIsoDateString(this.value)) {\n      this.internalValue = new Date().toISOString()\n    }\n  },\n  methods: {\n    validate(value) {\n      this.errors = this.getErrors(value)\n\n      return this.errors.length == 0\n    },\n    getErrors(value) {\n      if (value == null) {\n        return ['Value is required']\n      }\n\n      if (!isIsoDateString(value)) {\n        return ['Value is expected to be an ISO Date string']\n      }\n\n      return []\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/KeyValueTypeInputs/JsonParsingInput.vue",
    "content": "<template>\n  <v-text-field\n    v-model=\"internalValue\"\n    :error-messages=\"errors\"\n    :disabled=\"disabled\"\n    label=\"Value\"\n    outlined\n    dense\n    @input=\"validate\"\n  />\n</template>\n\n<script>\nimport { isValidJson, tryParseJson, formatSingleLineJson } from '@/utils/json'\nimport { types, isValidType } from '@/utils/types'\n\nexport default {\n  name: 'JsonParsingInput',\n  props: {\n    value: {\n      type: [String, Number, Boolean, Object, Array],\n      required: false,\n      default: null\n    },\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    types: {\n      type: Array,\n      required: false,\n      default: () => types,\n      validator: value => value.every(isValidType)\n    }\n  },\n  data() {\n    return {\n      errors: []\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return typeof this.value === 'object'\n          ? formatSingleLineJson(this.value)\n          : this.value\n      },\n      set(value) {\n        const converted = this.tryParsingFromString(value)\n\n        this.$emit('input', converted)\n      }\n    }\n  },\n  methods: {\n    tryParsingFromString(value) {\n      return isValidJson(value) ? tryParseJson(value) : value\n    },\n    validate(value) {\n      this.errors = this.getErrors(value)\n\n      return this.errors.length == 0\n    },\n    getErrors(value) {\n      if (value === null) {\n        return ['Value is required']\n      }\n\n      return []\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/KeyValueTypeInputs/NullInput.vue",
    "content": "<template>\n  <v-text-field\n    value=\"null\"\n    :error-messages=\"errors\"\n    disabled\n    label=\"Value\"\n    outlined\n    dense\n    @input=\"validate\"\n  />\n</template>\n\n<script>\nexport default {\n  name: 'NullInput',\n  props: {\n    value: {\n      type: [String, Number, Boolean, Object, Array],\n      required: false,\n      default: null\n    }\n  },\n  data() {\n    return {\n      errors: []\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  },\n  mounted() {\n    if (this.value != null) {\n      this.internalValue = null\n    }\n  },\n  methods: {\n    validate(value) {\n      this.errors = this.getErrors(value)\n\n      return this.errors.length == 0\n    },\n    getErrors(value) {\n      if (value !== null) {\n        return ['Value is expected to be None']\n      }\n\n      return []\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/KeyValueTypeInputs/NumberInput.vue",
    "content": "<template>\n  <v-text-field\n    v-model.number=\"internalValue\"\n    :error-messages=\"errors\"\n    :disabled=\"disabled\"\n    type=\"number\"\n    label=\"Value\"\n    outlined\n    dense\n    @input=\"validate\"\n  />\n</template>\n\n<script>\nexport default {\n  name: 'NumberInput',\n  props: {\n    value: {\n      type: [String, Number, Boolean, Object, Array],\n      required: false,\n      default: null\n    },\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    return {\n      errors: []\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  },\n  mounted() {\n    if (typeof this.value != 'number') {\n      const parsed = Number(this.value)\n\n      this.internalValue = isNaN(parsed) ? 0 : parsed\n    }\n  },\n  methods: {\n    validate(value) {\n      this.errors = this.getErrors(value)\n\n      return this.errors.length == 0\n    },\n    getErrors(value) {\n      if (value == null) {\n        return ['Value is required']\n      }\n\n      if (isNaN(value)) {\n        return ['Value is expected to be an Integer']\n      }\n\n      return []\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/KeyValueTypeInputs/ObjectInput.vue",
    "content": "<template>\n  <v-text-field\n    v-model=\"internalValue\"\n    :error-messages=\"errors\"\n    :disabled=\"disabled\"\n    label=\"Value\"\n    outlined\n    dense\n    @input=\"validate\"\n  />\n</template>\n\n<script>\nimport {\n  isValidJson,\n  tryParseJson,\n  tryFormatSingleLineJson\n} from '@/utils/json'\n\nexport default {\n  name: 'ObjectInput',\n  props: {\n    value: {\n      type: [String, Number, Boolean, Object, Array],\n      required: false,\n      default: null\n    },\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    return {\n      errors: []\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return tryFormatSingleLineJson(this.value)\n      },\n      set(value) {\n        this.$emit('input', tryParseJson(value) ?? value)\n      }\n    }\n  },\n  mounted() {\n    if (this.isObject(this.value)) {\n      return\n    }\n\n    if (\n      this.isObjectString(this.value) &&\n      !this.isArrayOrArrayString(this.value)\n    ) {\n      this.internalValue = this.value\n    } else {\n      this.internalValue = '{}'\n    }\n  },\n  methods: {\n    isObject(value) {\n      return typeof value === 'object'\n    },\n    isObjectString(value) {\n      return isValidJson(value) && typeof tryParseJson(value) == 'object'\n    },\n    isObjectOrObjectString(value) {\n      return this.isObject(value) || this.isObjectString(value)\n    },\n    isArrayOrArrayString(value) {\n      return Array.isArray(value) || Array.isArray(tryParseJson(value))\n    },\n    validate(value) {\n      this.errors = this.getErrors(value)\n\n      return this.errors.length == 0\n    },\n    getErrors(value) {\n      if (value === null) {\n        return ['Value is required']\n      }\n\n      if (\n        !this.isObjectOrObjectString(value) ||\n        this.isArrayOrArrayString(value)\n      ) {\n        return ['Value is not valid Dictionary']\n      }\n\n      return []\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/KeyValueTypeInputs/StringInput.vue",
    "content": "<template>\n  <v-text-field\n    v-model=\"internalValue\"\n    :error-messages=\"errors\"\n    :disabled=\"disabled\"\n    label=\"Value\"\n    outlined\n    dense\n    @input=\"validate\"\n  />\n</template>\n\n<script>\nimport { tryFormatJson } from '@/utils/json'\n\nexport default {\n  name: 'StringInput',\n  props: {\n    value: {\n      type: [String, Number, Boolean, Object, Array],\n      required: false,\n      default: null\n    },\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    return {\n      errors: []\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  },\n  mounted() {\n    if (typeof this.value == 'object') {\n      this.internalValue = tryFormatJson(this.value) ?? ''\n    } else if (typeof this.value != 'string') {\n      this.internalValue = this.tryCallingToString(this.value) ?? ''\n    }\n  },\n  methods: {\n    tryCallingToString(value) {\n      if (value != null && typeof this.value.toString === 'function') {\n        return value.toString()\n      }\n\n      return null\n    },\n    validate(value) {\n      this.errors = this.getErrors(value)\n\n      return this.errors.length == 0\n    },\n    getErrors(value) {\n      if (value === null) {\n        return ['Value is required']\n      }\n\n      return []\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/KeyValueTypeInputs/index.js",
    "content": "import NullInput from '@/components/CustomInputs/KeyValueTypeInputs/NullInput'\nimport JsonParsingInput from '@/components/CustomInputs/KeyValueTypeInputs/JsonParsingInput'\nimport BooleanInput from '@/components/CustomInputs/KeyValueTypeInputs/BooleanInput'\nimport NumberInput from '@/components/CustomInputs/KeyValueTypeInputs/NumberInput'\nimport StringInput from '@/components/CustomInputs/KeyValueTypeInputs/StringInput'\nimport ObjectInput from '@/components/CustomInputs/KeyValueTypeInputs/ObjectInput'\nimport ArrayInput from '@/components/CustomInputs/KeyValueTypeInputs/ArrayInput'\nimport DateInput from '@/components/CustomInputs/KeyValueTypeInputs/DateInput'\n\nexport default {\n  NullInput,\n  JsonParsingInput,\n  BooleanInput,\n  NumberInput,\n  StringInput,\n  ObjectInput,\n  ArrayInput,\n  DateInput\n}\n"
  },
  {
    "path": "src/components/CustomInputs/ListInput.vue",
    "content": "<script>\nexport default {\n  props: {\n    value: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    label: {\n      type: String,\n      required: false,\n      default: null\n    },\n    items: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    showClear: {\n      type: Boolean,\n      required: false,\n      default: true\n    },\n    showClose: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    showReset: {\n      type: Boolean,\n      required: false,\n      default: true\n    },\n    outline: {\n      type: Boolean,\n      required: false,\n      default: true\n    },\n    rules: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    hide: {\n      type: Boolean,\n      required: false,\n      default: true\n    }\n  },\n  data() {\n    return {\n      initialValue: []\n    }\n  },\n  computed: {\n    clearDisabled() {\n      return this.internalValue.length === 0\n    },\n    resetDisabled() {\n      return (\n        this.initialValue.every(val => this.internalValue.includes(val)) &&\n        this.initialValue.length === this.internalValue.length\n      )\n    },\n    internalValue: {\n      get() {\n        return this.value ?? []\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  },\n  created() {\n    this.initialValue = [...this.internalValue]\n  },\n  methods: {\n    clear() {\n      this.internalValue = []\n    },\n    reset() {\n      this.internalValue = this.initialValue\n    },\n    close() {\n      this.$emit('next')\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"list-input\">\n    <div\n      v-if=\"showClear || showReset || showClose\"\n      class=\"d-flex align-center justify-end mb-2\"\n    >\n      <v-btn\n        v-if=\"showReset\"\n        x-small\n        class=\"text-normal\"\n        depressed\n        color=\"utilGrayLight\"\n        title=\"Reset\"\n        :disabled=\"resetDisabled\"\n        @click=\"reset\"\n      >\n        Reset\n        <v-icon small>refresh</v-icon>\n      </v-btn>\n      <v-btn\n        v-if=\"showClose\"\n        :disabled=\"clearDisabled\"\n        x-small\n        class=\"text-normal\"\n        depressed\n        color=\"primary\"\n        title=\"Next\"\n        @click=\"close\"\n      >\n        Next\n        <v-icon small>call_made</v-icon>\n      </v-btn>\n\n      <v-btn\n        v-if=\"showClear\"\n        x-small\n        class=\"text-normal ml-2\"\n        depressed\n        color=\"primary\"\n        title=\"Clear\"\n        :disabled=\"clearDisabled\"\n        @click=\"clear\"\n      >\n        Clear\n        <v-icon small>clear</v-icon>\n      </v-btn>\n    </div>\n    <v-combobox\n      v-model=\"internalValue\"\n      hide-selected\n      :label=\"label\"\n      :items=\"items\"\n      :append-icon=\"items.length > 0 ? '$dropdown' : null\"\n      multiple\n      small-chips\n      :rules=\"rules\"\n      :hide-details=\"hide\"\n      :outlined=\"outline\"\n    >\n      <template #selection=\"{ item, parent }\">\n        <v-chip label small color=\"primary\">\n          <span class=\"pr-2\">\n            {{ item }}\n          </span>\n\n          <v-icon small @click=\"parent.selectItem(item)\">\n            close\n          </v-icon>\n        </v-chip>\n      </template>\n    </v-combobox>\n    <div v-if=\"!rules.length\" class=\"mt-1 text-caption\">\n      Hint: add to the list after typing by pressing the Enter key\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/CustomInputs/MultiLineInput.vue",
    "content": "<script>\nimport JsonInput from '@/components/CustomInputs/JsonInput'\nimport YamlInput from '@/components/CustomInputs/YamlInput'\nimport jsBeautify from 'js-beautify'\n\nimport { parse, stringify } from 'yaml'\n\nexport default {\n  components: {\n    JsonInput,\n    YamlInput\n  },\n  props: {\n    value: {\n      type: [Object, String],\n      required: false,\n      default: () => {\n        return ''\n      }\n    }\n  },\n  data() {\n    return {\n      mode: 'json',\n      jsonInput: '{}',\n      yamlInput: ''\n    }\n  },\n  computed: {\n    internalValue() {\n      if (this.mode == 'yaml') return this.yamlInput\n      if (this.mode == 'json') {\n        try {\n          return JSON.parse(this.jsonInput)\n        } catch {\n          return this.jsonInput\n        }\n      }\n      return null\n    }\n  },\n  watch: {\n    // Allows swapping between json input and yaml inputs\n    mode(val) {\n      if (val == 'json') {\n        let jsonInput\n\n        try {\n          jsonInput = JSON.stringify(parse(this.yamlInput))\n        } catch {\n          jsonInput = this.yamlInput\n        }\n\n        this.jsonInput = jsBeautify(jsonInput || {}, {\n          indent_size: 4,\n          space_in_empty_paren: true,\n          preserve_newlines: false\n        })\n\n        // Use next tick to make sure the json input element exists\n        this.$nextTick(() => {\n          this.$refs['json-input'].validateJson()\n        })\n      } else {\n        if (this.jsonInput === '{}') {\n          this.yamlInput = ''\n        } else {\n          let yamlInput\n\n          try {\n            yamlInput = stringify(JSON.parse(this.jsonInput))\n          } catch {\n            yamlInput = this.jsonInput\n          }\n          this.yamlInput = yamlInput\n        }\n      }\n\n      this.$emit('input', this.internalValue)\n    }\n  },\n  mounted() {\n    if (this.value && typeof this.value == 'object') {\n      this.mode = 'json'\n\n      const val = JSON.stringify(this.value)\n\n      this.jsonInput = jsBeautify(val, {\n        indent_size: 4,\n        space_in_empty_paren: true,\n        preserve_newlines: false\n      })\n\n      this.yamlInput = stringify(this.value)\n    } else if (this.value) {\n      this.mode = 'yaml'\n      this.yamlInput = stringify(this.value)\n    }\n  },\n  methods: {\n    _handleJsonInput() {\n      // Allows swapping between json input and key value pairs\n      try {\n        const json = JSON.parse(this.jsonInput)\n\n        this.keys = Object.keys(json)\n        this.values = Object.values(json)\n      } catch {\n        this.$refs['json-input'].validateJson()\n      }\n    },\n    _handleKeypress() {\n      this.$emit('input', this.internalValue)\n    },\n    _handleYamlInput() {},\n    switchMode() {\n      this.mode = this.mode == 'yaml' ? 'json' : 'yaml'\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"multiline-input position-relative\">\n    <div class=\"d-flex justify-end align-center mb-1\" style=\"width: 100%;\">\n      <span\n        class=\"d-flex justify-end align-center cursor-pointer\"\n        @click=\"switchMode\"\n      >\n        <span\n          class=\"text-body-2\"\n          :class=\"{ 'font-weight-bold': mode == 'json' }\"\n        >\n          JSON\n        </span>\n        <v-switch\n          inset\n          color=\"orange\"\n          class=\"mt-0 small-switch v-input--reverse multi-color-switch\"\n          :class=\"{\n            'green--text': mode == 'json',\n            'orange--text': mode == 'yaml'\n          }\"\n          hide-details\n          :value=\"mode == 'yaml'\"\n          @click.stop=\"switchMode\"\n        ></v-switch>\n        <span\n          class=\"text-body-2\"\n          :class=\"{ 'font-weight-bold': mode == 'yaml' }\"\n        >\n          YAML\n        </span>\n      </span>\n    </div>\n\n    <div v-if=\"mode == 'json'\">\n      <JsonInput\n        ref=\"json-input\"\n        v-model=\"jsonInput\"\n        background-color=\"white\"\n        selected-type=\"json\"\n        prepend-icon=\"fad fa-file-code\"\n        prepend-icon-label=\"JSON\"\n        @input=\"_handleKeypress\"\n      />\n    </div>\n\n    <div v-else-if=\"mode == 'yaml'\">\n      <YamlInput\n        ref=\"yaml-input\"\n        v-model=\"yamlInput\"\n        background-color=\"white\"\n        prepend-icon=\"fad fa-file-alt\"\n        prepend-icon-label=\"YAML\"\n        @input=\"_handleKeypress\"\n      />\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.remove-button {\n  position: absolute;\n  right: 0;\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/ResettableWrapper.vue",
    "content": "<template>\n  <div class=\"resettable-wrapper\">\n    <div class=\"resettable-wrapper__button-container\">\n      <v-btn\n        class=\"text-normal\"\n        color=\"utilGrayLight\"\n        title=\"Reset\"\n        :disabled=\"initialValue == value\"\n        x-small\n        depressed\n        @click=\"reset\"\n      >\n        Reset\n        <v-icon small>refresh</v-icon>\n      </v-btn>\n    </div>\n    <div class=\"resettable-wrapper__slot-container\">\n      <slot />\n    </div>\n  </div>\n</template>\n\n<script>\nimport { tryParseJson, tryFormatJson } from '@/utils/json'\n\nexport default {\n  name: 'ResettableWrapper',\n  props: {\n    value: {\n      type: [String, Boolean, Number, Array, Object],\n      required: false,\n      default: null\n    }\n  },\n  data() {\n    return {\n      initialValue: null\n    }\n  },\n  created() {\n    if (typeof this.value === 'object') {\n      const json = tryFormatJson(this.value)\n\n      this.initialValue = tryParseJson(json)\n    } else {\n      this.initialValue = this.value\n    }\n  },\n  methods: {\n    reset() {\n      this.$emit('input', this.initialValue)\n    }\n  }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.resettable-wrapper__button-container {\n  display: flex;\n  justify-content: flex-end;\n  margin-bottom: 8px;\n}\n\n.resettable-dictionary-json {\n  position: relative;\n\n  .resettable-wrapper__button-container {\n    position: absolute;\n    right: 110px;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/YamlInput.vue",
    "content": "<script>\nimport { codemirror } from 'vue-codemirror'\nimport 'codemirror/mode/yaml/yaml.js'\nimport 'codemirror/lib/codemirror.css'\nimport 'codemirror/addon/display/placeholder'\nimport '@/styles/yaml-input-style.scss'\n\nexport default {\n  components: {\n    CodeMirror: codemirror\n  },\n  props: {\n    backgroundColor: {\n      type: String,\n      default: () => 'transparent'\n    },\n    disabled: {\n      type: Boolean,\n      default: () => false\n    },\n    prependIcon: {\n      type: String,\n      required: false,\n      default: ''\n    },\n    prependIconLabel: {\n      type: String,\n      required: false,\n      default: null\n    },\n    selectedType: {\n      type: String,\n      default: 'yaml',\n      required: false\n    },\n    // If true, editor height updates based on content.\n    heightAuto: {\n      type: Boolean,\n      default: () => false,\n      required: false\n    },\n    value: {\n      type: String,\n      default: () => '',\n      required: false\n    },\n    newParameterInput: {\n      type: String,\n      default: '',\n      required: false\n    },\n    placeholderText: {\n      type: String,\n      default: '',\n      required: false\n    }\n  },\n  data() {\n    return {\n      // Line that contains a syntax error\n      errorLine: null,\n      // The value may need to be modified for formatting.\n      // Store the value prop's value internally as data so it can be modified.\n      internalValue: this.value,\n      error: null,\n      focussed: false\n    }\n  },\n  computed: {\n    cmInstance() {\n      return this.$refs.cmRef && this.$refs.cmRef.codemirror\n    },\n    iconColor() {\n      if (this.error) return 'error'\n      if (this.focussed) return 'primary'\n      return 'grey'\n    },\n    editorOptions() {\n      return {\n        mode: 'text/x-yaml',\n        theme: 'yaml-input',\n        readOnly: this.disabled,\n        lint: true,\n        smartIndent: true,\n        lineWrapping: true,\n        placeholder: this.placeholderText,\n        tabSize: 4\n      }\n    }\n  },\n  watch: {\n    // Keep value prop in sync with value saved as data\n    value() {\n      this.internalValue = this.value\n    }\n  },\n  methods: {\n    _handleInput(event) {\n      this.removeErrors()\n      this.$emit('input', event)\n    },\n    markErrors(syntaxError) {\n      const errorIndex = syntaxError?.message?.split(' ').pop()\n      const errorPosition = this.cmInstance.doc.posFromIndex(errorIndex)\n      this.errorLine = errorPosition.line\n      this.cmInstance.doc.addLineClass(\n        this.errorLine,\n        'text',\n        'input-error-text'\n      )\n    },\n    removeErrors() {\n      this.error = null\n      if (this.errorLine == null) return\n      this.cmInstance.doc.removeLineClass(\n        this.errorLine,\n        'text',\n        'input-error-text'\n      )\n\n      this.errorLine = null\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"position-relative input-empty-text\"\n    :class=\"{ 'input-height-auto': heightAuto }\"\n  >\n    <div\n      class=\"position-absolute text-center\"\n      :style=\"{\n        top: '12px',\n        left: '12px',\n        'z-index': 3\n      }\"\n    >\n      <v-icon :color=\"iconColor\">\n        {{ prependIcon }}\n      </v-icon>\n      <div class=\"text-caption o-20\">\n        {{ prependIconLabel }}\n      </div>\n    </div>\n    <CodeMirror\n      ref=\"cmRef\"\n      data-cy=\"code-mirror-input\"\n      :value=\"internalValue\"\n      class=\"pt-2 cm-style yaml-input\"\n      :class=\"{\n        'pl-9': prependIcon,\n        'pl-12': prependIconLabel,\n        'blue-border': prependIcon && focussed && !error,\n        'red-border': prependIcon && error,\n        'plain-border': prependIcon && !focussed && !error,\n        'original-border': !prependIcon,\n        [backgroundColor]: true\n      }\"\n      :options=\"editorOptions\"\n      @input=\"_handleInput($event)\"\n      @focus=\"focussed = true\"\n      @blur=\"focussed = false\"\n    ></CodeMirror>\n\n    <slot></slot>\n    <div class=\"text-caption red--text min-height pl-4\">{{ error }}</div>\n  </div>\n</template>\n\n<style lang=\"scss\">\n/* stylelint-disable selector-class-pattern */\n.yaml-input {\n  .CodeMirror.CodeMirror-wrap {\n    font-family: inherit !important;\n    height: 300px;\n    resize: vertical;\n  }\n\n  .input-height-auto {\n    .CodeMirror {\n      height: auto;\n      min-height: 108px;\n    }\n  }\n\n  .input-empty-text {\n    .CodeMirror-empty {\n      color: var(--v-utilGrayMid-base);\n    }\n\n    .CodeMirror-cursor {\n      height: auto !important;\n    }\n  }\n}\n</style>\n\n<style lang=\"scss\" scoped>\n.min-height {\n  height: 15px;\n}\n\n.cm-style {\n  color: rgba(0, 0, 0, 0.38);\n  cursor: text !important;\n  font-size: inherit !important;\n  height: auto;\n  position: relative;\n\n  &:hover,\n  &:focus {\n    color: rgba(0, 0, 0, 0.86);\n  }\n\n  &::after {\n    background: transparent;\n    content: '';\n    height: 100%;\n    left: 0;\n    pointer-events: none;\n    position: absolute;\n    top: 0;\n    transition: all 50ms;\n    width: 100%;\n  }\n\n  &.red-border::after {\n    border: 2px solid var(--v-error-base);\n    border-radius: 4px;\n  }\n\n  &.blue-border::after {\n    border: 2px solid var(--v-primary-base);\n    border-radius: 4px;\n  }\n\n  &.plain-border::after {\n    border: 1px solid currentColor;\n    border-radius: 4px;\n  }\n\n  &.original-border::after {\n    border: 1px solid currentColor;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/CustomInputs/YamlInput2.vue",
    "content": "<template>\n  <base-code-textarea\n    ref=\"editor\"\n    v-model=\"internalValue\"\n    :readonly=\"readonly\"\n    :placeholder=\"placeholder\"\n    :get-errors=\"getYamlErrors\"\n    :format=\"formatYaml\"\n    :parse=\"tryParseYaml\"\n    language=\"yaml\"\n  />\n</template>\n\n<script>\nimport BaseCodeTextarea from '@/components/CustomInputs/BaseCodeTextarea'\nimport { tryParseYaml, parseYaml, formatYaml } from '@/utils/yaml'\n\nexport default {\n  name: 'YamlInput',\n  components: {\n    BaseCodeTextarea\n  },\n  props: {\n    value: {\n      type: String,\n      required: false,\n      default: null\n    },\n    readonly: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    placeholder: {\n      type: String,\n      required: false,\n      default: null\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  },\n  methods: {\n    validate() {\n      return this.$refs.editor.validate(this.internalValue)\n    },\n    getYamlErrors(value) {\n      if (value == null || value == '') {\n        return []\n      }\n\n      try {\n        parseYaml(value)\n        return []\n      } catch (e) {\n        return [e.toString()]\n      }\n    },\n    tryParseYaml,\n    formatYaml\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/CustomInputs/readonlyProps.js",
    "content": "const readonlyProps = {\n  readonlyKey: {\n    type: Boolean,\n    required: false,\n    default: false\n  },\n  readonlyType: {\n    type: Boolean,\n    required: false,\n    default: false\n  },\n  readonlyValue: {\n    type: Boolean,\n    required: false,\n    default: false\n  },\n  disableAdd: {\n    type: Boolean,\n    required: false,\n    default: false\n  },\n  disableRemove: {\n    type: Boolean,\n    required: false,\n    default: false\n  }\n}\n\nexport default readonlyProps\n"
  },
  {
    "path": "src/components/DateTime.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport moment from 'moment-timezone'\nimport range from 'lodash/range'\n\nexport default {\n  props: {\n    // Specify a warning to display if the selected time is in the past.\n    warning: {\n      type: String,\n      required: false,\n      default: () => 'This time is in the past.'\n    },\n    // Custom props for the read-only text field displaying the selected date and time.\n    textFieldProps: {\n      type: Object,\n      required: false,\n      default: () => ({})\n    },\n    // Two-way-bound date & time.\n    // Format: ISO 8601, e.g. 2020-03-18T15:30:32-05:00\n    // This prop is required for use of v-model on this component.\n    value: {\n      type: String,\n      required: false,\n      default: () => ''\n    },\n    allowPastDate: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    }\n  },\n  data() {\n    return {\n      // Date & time inputs\n      date: null,\n      timeHr: '12',\n      timeMin: '00',\n      timeAmPm: 'AM',\n\n      // Tab control\n      tab: 'date',\n\n      // Menu control\n      showMenu: false,\n\n      // Current date & time\n      currentDateTimeMoment: null\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone']),\n    // The current date in YYYY-MM-DD format\n    currentDate() {\n      if (!this.currentDateTimeMoment || this.allowPastDate) return null\n      return this.currentDateTimeMoment.format('YYYY-MM-DD')\n    },\n    // Selected date and time value, as derived from date & time inputs.\n    // Format: ISO 8601, e.g. 2020-03-18T15:30:32-05:00\n    internalValue() {\n      if (!this.date) return null\n\n      const selectedDateTime = moment(\n        `${this.date} ${this.timeHr}:${this.timeMin} ${this.timeAmPm}`,\n        'YYYY-MM-DD hh:mm A'\n      )\n      // If user's timezone is not set, format to ISO 8601 and return.\n      if (!this.timezone) return selectedDateTime.format()\n\n      // Determine the user's timezone (-05:00, Z, etc)\n      const tz = moment()\n        .tz(this.timezone)\n        .format('Z')\n\n      // If user's timezone is set...\n      return (\n        selectedDateTime\n          // format to ISO 8601,\n          .format()\n          // Remove timezone identifier (-05:00, Z, etc),\n          .replace(/([+|-]\\d{2}:\\d{2})|Z$/g, '')\n          // Append new timezone identifier based on user's timezone.\n          .concat(tz)\n      )\n    },\n    // Format the selected date & time to be more human-readable.\n    formattedValue() {\n      if (!this.internalValue) return null\n\n      const formattedDateTime = this.momentWithTimezone(\n        this.internalValue\n      ).format('MMMM D YYYY [at] h:mm A')\n\n      const formattedTimezone = this.timezone\n        ? moment()\n            .tz(\n              this.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone\n            )\n            .zoneAbbr()\n        : ''\n\n      return `${formattedDateTime} ${formattedTimezone}`\n    },\n    timeInPast() {\n      if (!this.internalValue) return false\n      return moment(this.internalValue) < this.currentDateTimeMoment\n    }\n  },\n  watch: {\n    // Whenever internalValue changes, it should be emitted to the parent.\n    // This input emitter is what makes v-model work on the DateTime component.\n    internalValue(val) {\n      this.$emit('input', val)\n    },\n    // Keep the constituent parts of DateTime in sync with the user-provided value prop.\n    value: {\n      immediate: true,\n      handler(val) {\n        if (val) {\n          const valueMoment = this.momentWithTimezone(val)\n          this.date = valueMoment.format('YYYY-MM-DD')\n          this.timeHr = valueMoment.format('hh')\n          this.timeMin = valueMoment.format('mm')\n          this.timeAmPm = valueMoment.format('A')\n        } else {\n          this.handleDateTimeClear()\n        }\n      }\n    }\n  },\n  created() {\n    this.currentDateTimeMoment = this.timezone\n      ? moment().tz(this.timezone)\n      : moment()\n\n    setInterval(() => {\n      this.currentDateTimeMoment = this.timezone\n        ? moment().tz(this.timezone)\n        : moment()\n    }, 5000)\n  },\n  methods: {\n    handleDateChange(input) {\n      this.date = input\n      this.tab = 'time'\n\n      let currentDateTime = this.momentWithTimezone()\n\n      currentDateTime.add(1, 'minute')\n\n      if (this.date === currentDateTime.format('YYYY-MM-DD')) {\n        // If selected date is current day,\n        // set time input values as the current time + 1 minute.\n        this.timeHr = currentDateTime.format('hh')\n        this.timeMin = currentDateTime.format('mm')\n        this.timeAmPm = currentDateTime.format('A')\n      } else {\n        // If selected day is in the future,\n        // initialize start time as midnight.\n        this.timeHr = '12'\n        this.timeMin = '00'\n        this.timeAmPm = 'AM'\n      }\n    },\n    handleDateTimeClear() {\n      this.tab = 'date'\n\n      this.date = null\n      this.timeHr = '12'\n      this.timeMin = '00'\n      this.timeAmPm = 'AM'\n    },\n    // Given the date & time as a string,\n    // provide a moment object that accounts for timezone.\n    // Leave argument blank if you want to use the current time.\n    momentWithTimezone(dateTime) {\n      return this.timezone\n        ? moment(dateTime).tz(this.timezone)\n        : moment(dateTime)\n    },\n    timeRange(min, max) {\n      return range(min, max).map(val => {\n        if (val < 10) return `0${val}`\n        return val.toString()\n      })\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-menu\n      v-model=\"showMenu\"\n      max-width=\"290\"\n      offset-y\n      :close-on-content-click=\"false\"\n    >\n      <template #activator=\"{ on }\">\n        <v-text-field\n          :value=\"formattedValue\"\n          clearable\n          readonly\n          v-bind=\"textFieldProps\"\n          v-on=\"on\"\n          @click:clear=\"handleDateTimeClear\"\n        ></v-text-field>\n      </template>\n      <v-tabs v-model=\"tab\" grow class=\"tab-height-custom\">\n        <v-tab key=\"date\" href=\"#date\">Date</v-tab>\n        <v-tab key=\"time\" href=\"#time\" :disabled=\"!date\">\n          Time\n        </v-tab>\n\n        <v-tab-item value=\"date\">\n          <v-date-picker\n            v-model=\"date\"\n            no-title\n            :min=\"currentDate\"\n            label=\"Hour\"\n            @change=\"handleDateChange\"\n          ></v-date-picker>\n        </v-tab-item>\n\n        <v-tab-item value=\"time\">\n          <v-card tile>\n            <v-card-text>\n              <v-row>\n                <v-col cols=\"4\">\n                  <v-autocomplete\n                    data-public\n                    v-model=\"timeHr\"\n                    hide-details\n                    label=\"Hour\"\n                    :items=\"timeRange(1, 13)\"\n                    :append-icon=\"null\"\n                    hide-no-data\n                  ></v-autocomplete>\n                </v-col>\n                <v-col cols=\"4\">\n                  <v-autocomplete\n                    data-public\n                    v-model=\"timeMin\"\n                    hide-details\n                    label=\"Minute\"\n                    :items=\"timeRange(0, 60)\"\n                    :append-icon=\"null\"\n                    hide-no-data\n                  ></v-autocomplete>\n                </v-col>\n                <v-col cols=\"4\">\n                  <v-autocomplete\n                    data-public\n                    v-model=\"timeAmPm\"\n                    hide-details\n                    label=\"AM/PM\"\n                    :items=\"['AM', 'PM']\"\n                    :append-icon=\"null\"\n                    hide-no-data\n                  ></v-autocomplete>\n                </v-col>\n              </v-row>\n              <v-row>\n                <v-col cols=\"12\">\n                  <p>Timezone: {{ timezone || 'Local' }}</p>\n                  <p class=\"mb-0\">\n                    You can change your system's timezone from your user\n                    profile.\n                    <router-link :to=\"'/user/profile'\">\n                      Update timezone\n                    </router-link>\n                    .\n                  </p>\n                </v-col>\n              </v-row>\n              <v-row>\n                <v-col cols=\"12\" class=\"py-0\">\n                  <v-scroll-x-transition>\n                    <v-alert\n                      v-if=\"!allowPastDate && timeInPast\"\n                      border=\"left\"\n                      colored-border\n                      elevation=\"2\"\n                      type=\"warning\"\n                      dense\n                      class=\"mt-4 mb-0\"\n                    >\n                      <span class=\"text-body-2 ma-0\">\n                        {{ warning }}\n                      </span>\n                    </v-alert>\n                  </v-scroll-x-transition>\n                </v-col>\n              </v-row>\n            </v-card-text>\n            <v-card-actions class=\"pa-0\">\n              <v-spacer></v-spacer>\n              <v-btn text color=\"primary\" @click=\"showMenu = false\">\n                Confirm\n              </v-btn>\n            </v-card-actions>\n          </v-card>\n        </v-tab-item>\n      </v-tabs>\n    </v-menu>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/DeleteFlowButton.vue",
    "content": "<script>\nimport { mapGetters, mapActions } from 'vuex'\n\nimport gql from 'graphql-tag'\n\nexport default {\n  components: {},\n  props: {\n    flow: {\n      type: Object,\n      default: null\n    },\n    flowGroup: {\n      type: Object,\n      default: null\n    },\n    type: {\n      type: String,\n      default: null\n    }\n  },\n  data() {\n    return {\n      deleting: false,\n      errorMessage: '',\n      allFlows: false,\n      deleteDialog: false,\n      // Alert data\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n      alertLink: null\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['role']),\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return !this.hasPermission('delete', 'flow')\n    },\n    all() {\n      if (this.allFlows) return true\n      if (this.type === 'group') return true\n      return false\n    },\n    mutationString() {\n      if (!this.all) {\n        return gql`\n          mutation($flowId: UUID!) {\n            delete_flow(input: { flow_id: $flowId }) {\n              success\n            }\n          }\n        `\n      } else {\n        return gql`\n          mutation($flowGroupId: UUID!) {\n            delete_flow_group(input: { flow_group_id: $flowGroupId }) {\n              success\n            }\n          }\n        `\n      }\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    async deleteFlow() {\n      try {\n        this.deleting = true\n        const variables = this.allFlows\n          ? { flowGroupId: this.flowGroup.id }\n          : { flowId: this.flow.id }\n        const { data } = await this.$apollo.mutate({\n          mutation: this.mutationString,\n          variables: variables\n        })\n\n        if (this.all && data?.delete_flow_group?.success) {\n          this.deleting = false\n          this.reset()\n          this.$router.push({ name: 'dashboard' })\n          this.setAlert({\n            alertShow: true,\n            alertMessage: `${this.flow.name} Deleted`,\n            alertType: 'info'\n          })\n        } else if (!this.all && data?.delete_flow?.success) {\n          this.deleting = false\n          this.reset()\n          this.$router.push({\n            name: 'flow',\n            params: { id: this.flowGroup.id },\n            query: null\n          })\n          this.setAlert({\n            alertShow: true,\n            alertMessage: `Version ${this.flow.version} of ${this.flow.name} Deleted`,\n            alertType: 'info'\n          })\n        } else {\n          throw new Error('Something went wrong deleting a flow', data)\n        }\n      } catch (error) {\n        this.deleting = false\n        this.errorMessage =\n          'We could not delete your flow.  Please try again.  If this problem continues, contact help@prefect.io'\n      }\n    },\n    reset() {\n      this.dialog = false\n      this.deleting = false\n      this.errorMessage = ''\n      this.allFlows = false\n      this.deleteDialog = false\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-if=\"!permissionsCheck\" class=\"text-center\">\n    <v-dialog v-model=\"deleteDialog\" width=\"500\" @click:outside=\"reset\">\n      <template #activator=\"{ on: dialog }\">\n        <v-tooltip bottom>\n          <template #activator=\"{ on: tooltip }\">\n            <div v-on=\"{ ...tooltip, ...dialog }\">\n              <v-btn\n                class=\"vertical-button\"\n                data-cy=\"delete-button\"\n                text\n                tile\n                small\n                color=\"red accent-2\"\n                aria-label=\"delete\"\n              >\n                <v-icon>delete</v-icon>\n                <div>Delete</div>\n              </v-btn>\n            </div>\n          </template>\n          <span v-if=\"type === 'flow'\">Delete this flow</span>\n          <span v-if=\"type === 'group'\">Delete this flow group</span>\n        </v-tooltip>\n      </template>\n\n      <!-- <template #activator=\"{ on }\">\n        <v-btn\n          class=\"vertical-button\"\n          text\n          tile\n          small\n          color=\"red accent-2\"\n          aria-label=\"delete\"\n          @click=\"dialog = true\"\n        >\n          <v-icon>delete</v-icon>\n          <div v-if=\"type === 'flow'\">Delete</div>\n        </v-btn>\n      </template> -->\n\n      <v-card :loading=\"deleting\">\n        <v-card-title v-if=\"!errorMessage && type === 'flow'\">\n          Delete flow \"{{ flow.name }}\" version {{ flow.version }}?\n        </v-card-title>\n        <v-card-title v-if=\"!errorMessage && type === 'group'\">\n          Delete all versions of this flow?\n        </v-card-title>\n        <v-card-text class=\"fix-height\">\n          <v-checkbox\n            v-if=\"!errorMessage && type === 'flow'\"\n            v-model=\"allFlows\"\n            color=\"red accent-2\"\n            :label=\"`Delete all versions of this flow.`\"\n          ></v-checkbox>\n          <div\n            v-if=\"!errorMessage && !all && flow.archived === false\"\n            class=\"font-weight-bold\"\n          >\n            This is an active version of your flow. Only archived versions will\n            remain.\n          </div>\n          <div v-if=\"!errorMessage && all\">\n            This will delete <span class=\"font-weight-black\">all </span>versions\n            of your flow and cannot be undone.\n          </div>\n          <div class=\"red--text pt-5\">\n            {{ errorMessage }}\n          </div>\n        </v-card-text>\n        <v-card-actions>\n          <v-spacer></v-spacer>\n          <v-btn\n            v-if=\"!errorMessage\"\n            color=\"red accent-2\"\n            class=\"white--text\"\n            :loading=\"deleting\"\n            @click=\"deleteFlow\"\n          >\n            Delete\n          </v-btn>\n          <v-btn text @click=\"reset()\">Cancel</v-btn>\n        </v-card-actions></v-card\n      >\n    </v-dialog>\n  </div>\n  <div v-else-if=\"permissionsCheck\">\n    <v-tooltip top>\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <v-btn class=\"vertical-button\" text disabled tile small>\n            <v-icon>delete</v-icon>\n            <div>Delete</div>\n          </v-btn>\n        </div>\n      </template>\n      <span>\n        You don't have permission to delete flows.\n      </span>\n    </v-tooltip>\n  </div>\n</template>\n\n<style scoped lang=\"scss\">\n.fix-height {\n  height: 110px;\n}\n</style>\n"
  },
  {
    "path": "src/components/DurationSpan.vue",
    "content": "<script>\nimport {\n  MS_PER_SECOND,\n  MS_PER_MINUTE,\n  MS_PER_HOUR,\n  durationDifference,\n  toDurationDifferenceString,\n  getMillisecondsUntilNextSecond,\n  getMillisecondsUntilNextMinute,\n  getMillisecondsUntilNextHour\n} from '@/utils/dateTime'\n\nexport default {\n  props: {\n    startTime: {\n      type: String,\n      required: true\n    },\n    endTime: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      duration: null,\n      interval: null,\n      intervalBlocks: {\n        second: {\n          msInBlock: MS_PER_SECOND,\n          msUntilNextBlock: getMillisecondsUntilNextSecond\n        },\n        minute: {\n          msInBlock: MS_PER_MINUTE,\n          msUntilNextBlock: getMillisecondsUntilNextMinute\n        },\n        hour: {\n          msInBlock: MS_PER_HOUR,\n          msUntilNextBlock: getMillisecondsUntilNextHour\n        }\n      }\n    }\n  },\n  computed: {\n    durationDifferenceString() {\n      return toDurationDifferenceString(this.duration ?? {})\n    },\n    smallestBlock() {\n      const blocks = Object.keys(this.duration ?? {})\n        .map(key => this.intervalBlocks[key])\n        .sort((a, b) => a.msInBlock - b.msInBlock)\n\n      return blocks.length ? blocks[0] : null\n    }\n  },\n  watch: {\n    endTime() {\n      this.startIntervalAtNextBlock()\n    }\n  },\n  mounted() {\n    this.startIntervalAtNextBlock()\n  },\n  beforeDestroy() {\n    clearInterval(this.interval)\n  },\n  methods: {\n    updateDuration() {\n      this.duration = durationDifference(\n        new Date(this.startTime),\n        this.endTime ? new Date(this.endTime) : new Date()\n      )\n    },\n    startIntervalAtNextBlock() {\n      clearInterval(this.interval)\n      this.updateDuration()\n\n      if (this.endTime) {\n        return\n      }\n\n      this.interval = setTimeout(\n        this.startInterval,\n        this.smallestBlock.msUntilNextBlock()\n      )\n    },\n    startInterval() {\n      this.updateDuration()\n\n      this.interval = setInterval(\n        this.updateDuration,\n        this.smallestBlock.msInBlock\n      )\n    }\n  }\n}\n</script>\n\n<template>\n  <span class=\"duration-span\">\n    <slot :duration=\"durationDifferenceString\">{{\n      durationDifferenceString\n    }}</slot>\n  </span>\n</template>\n"
  },
  {
    "path": "src/components/EditableTextField.vue",
    "content": "<script>\nexport default {\n  props: {\n    content: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    label: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    loading: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    required: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    return {\n      error: false,\n      focused: false,\n      rules: {\n        required: val => !!val || 'Required.',\n        length: val => val?.length > 0 || 'At least one number is required'\n      },\n      value: this.content\n    }\n  },\n  methods: {\n    discard() {\n      this.focused = false\n      this.$refs['edit-input']?.blur()\n\n      this.value = this.content\n    },\n    edit() {\n      if (this.loading) return\n\n      this.focused = true\n\n      this.$refs['edit-input']?.focus()\n    },\n    save() {\n      this.error = this.value?.length === 0\n      if (this.loading || this.value?.length === 0) return\n\n      this.focused = false\n      this.$refs['edit-input']?.blur()\n\n      this.$emit('change', this.value)\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    v-click-outside=\"discard\"\n    class=\"inherited-text-field\"\n    :class=\"{ focused: focused, 'cursor-pointer': !focused }\"\n    @click=\"edit\"\n  >\n    <v-icon v-if=\"!loading\" small class=\"prepend-input edit-icon\">edit</v-icon>\n    <v-progress-circular\n      v-else\n      indeterminate\n      class=\"prepend-input\"\n      color=\"primary\"\n      size=\"16\"\n      width=\"2\"\n    />\n\n    <v-menu\n      :value=\"focused && required && (!value || value.length === 0) && error\"\n      :close-on-click=\"false\"\n      :open-on-click=\"false\"\n      :close-on-content-click=\"false\"\n      offset-y\n      max-width=\"320\"\n      nudge-bottom=\"5\"\n    >\n      <template #activator=\"{on}\">\n        <v-input\n          class=\"input-container\"\n          :class=\"{\n            'error-border': required && (!value || value.length === 0),\n            disabled: loading\n          }\"\n          hide-details\n          :error=\"required && (!value || value.length === 0)\"\n          v-on=\"on\"\n          @disabled=\"loading\"\n        >\n          <input\n            ref=\"edit-input\"\n            v-model=\"value\"\n            class=\"text-truncate\"\n            :class=\"{\n              'cursor-pointer': !focused\n            }\"\n            :placeholder=\"`${label} (press enter to save)`\"\n            @disabled=\"loading\"\n            @keyup.enter=\"save\"\n            @keyup.esc=\"discard\"\n            @focus=\"focused = !loading && true\"\n          />\n        </v-input>\n      </template>\n\n      <v-alert border=\"left\" colored-border type=\"error\" class=\"ma-0\">\n        {{ label }} can't be empty\n      </v-alert>\n    </v-menu>\n\n    <!-- Not sure if we need to show these buttons since enter is a pretty natural interaction -->\n    <!-- <div v-if=\"focused\" class=\"button-container text-center\">\n      <v-btn block depressed color=\"primary\" x-small @click=\"save\">\n        Save\n      </v-btn>\n      <v-btn\n        block\n        depressed\n        x-small\n        class=\"mr-1\"\n        color=\"transparent\"\n        @click=\"discard\"\n      >\n        Cancel\n      </v-btn>\n    </div> -->\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.button-container {\n  position: absolute;\n  right: -60px;\n  top: 50%;\n  transform: translate(0, -50%);\n  width: 60px;\n}\n\n.prepend-input {\n  display: inline-block;\n  position: relative;\n}\n\n.edit-icon {\n  opacity: 0;\n  transition: all 150ms;\n  width: 0;\n}\n\n.inherited-text-field {\n  box-sizing: border-box;\n  color: inherit !important;\n  font-size: inherit !important;\n  height: 28px;\n  max-width: 100%;\n  padding-bottom: 2px;\n  position: relative;\n  width: 100%;\n\n  .v-input {\n    color: inherit !important;\n    font-size: inherit !important;\n  }\n\n  .input-container {\n    display: inline-block;\n    width: calc(100% - 20px);\n\n    input,\n    input:active {\n      color: inherit !important;\n      outline: none;\n      transition: all 100ms;\n      width: 100%;\n    }\n\n    &.disabled {\n      color: var(--v-utilGrayMid-base) !important;\n      cursor: progress;\n\n      input {\n        pointer-events: none;\n      }\n    }\n\n    &::after {\n      background-color: var(--v-primary-base);\n      bottom: 0;\n      content: '';\n      height: 2px;\n      left: 50%;\n      position: absolute;\n      transition: all 100ms;\n      transition-delay: 10ms;\n      width: 0%;\n    }\n\n    &.error-border::after {\n      background-color: var(--v-error-base);\n      transition-delay: 0;\n    }\n  }\n\n  &.focused {\n    .input-container {\n      border-bottom: 1px solid var(--v-utilGrayLight-base);\n      height: 100%;\n    }\n\n    .input-container::after {\n      left: 20px;\n      width: calc(100% - 20px);\n    }\n\n    .edit-icon {\n      margin-right: 4px;\n      opacity: 1;\n      width: 16px;\n    }\n  }\n\n  &:focus,\n  &:hover {\n    .edit-icon {\n      margin-right: 4px;\n      opacity: 1;\n      width: 16px;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/EmphasizedIcon.vue",
    "content": "<script>\nimport { THEME_COLORS } from '@/plugins/vuetify'\n\nexport default {\n  props: {\n    color: {\n      type: String,\n      validator: color => THEME_COLORS[color],\n      default: 'secondary'\n    }\n  },\n  computed: {\n    style() {\n      return { 'background-color': THEME_COLORS[this.color] }\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"emphasized-icon\" :style=\"style\">\n    <slot />\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.emphasized-icon {\n  align-content: center;\n  border-radius: 50%;\n  display: flex;\n  justify-content: center;\n  padding: 0.25rem;\n}\n</style>\n"
  },
  {
    "path": "src/components/EndOfLifeBanner.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport ExternalLink from '@/components/ExternalLink'\n\nexport default {\n  components: { ExternalLink },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('license', ['planType']),\n    free() {\n      return this.planType('FREE')\n    },\n    frozen() {\n      return this.license?.terms?.frozen\n    }\n  }\n}\n</script>\n\n<template>\n  <v-banner>\n    <template #default>\n      <div class=\"d-flex align-center\">\n        <v-avatar slot=\"icon\" rounded color=\"primary\" size=\"40\">\n          <v-icon color=\"white\"> warning </v-icon>\n        </v-avatar>\n        <div v-if=\"frozen\" class=\"ml-4\">\n          This legacy Prefect Cloud account has been frozen.\n          <ExternalLink\n            href=\"https://www.prefect.io/guide/blog/freezing-legacy-prefect-cloud-1-accounts-on-starter-and-standard-plans/\"\n            >Click here</ExternalLink\n          >\n          for more information.\n        </div>\n        <div v-else class=\"ml-4\">\n          This legacy Prefect Cloud account will be frozen on October 25th, 2023.\n          <ExternalLink\n            href=\"https://www.prefect.io/guide/blog/freezing-legacy-prefect-cloud-1-accounts-on-starter-and-standard-plans/\"\n            >Click here</ExternalLink\n          >\n          to learn more or to start your migration to\n          <ExternalLink\n            href=\"https://www.prefect.io/guide/blog/introducing-prefect-cloud-2-0/\"\n            >Prefect Cloud 2</ExternalLink\n          >.\n        </div>\n      </div>\n    </template>\n  </v-banner>\n</template>\n"
  },
  {
    "path": "src/components/ExternalLink.vue",
    "content": "<script>\nexport default {\n  props: {\n    href: {\n      type: String,\n      required: true\n    }\n  }\n}\n</script>\n\n<template>\n  <span>\n    <a :href=\"href\" target=\"_blank\" rel=\"noopener noreferrer\">\n      <slot></slot>\n    </a>\n    <sup>\n      <v-icon x-small>\n        open_in_new\n      </v-icon>\n    </sup>\n  </span>\n</template>\n\n<style lang=\"scss\" scoped>\na {\n  text-decoration: none !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/Feedback.vue",
    "content": "<script>\nimport LogRocket from 'logrocket'\n\nexport default {\n  data() {\n    return {\n      feedback: '',\n      error: false,\n      submitting: false,\n      success: false\n    }\n  },\n  methods: {\n    async sendFeedback() {\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/support/send-feedback.gql'),\n          variables: {\n            type: 'Cloud Feedback',\n            message: this.feedback\n          }\n        })\n        if (data?.send_feedback?.success) {\n          this.success = true\n          this.feedback = ''\n          setTimeout(() => {\n            this.$emit('close')\n          }, 2000)\n        } else {\n          this.error = true\n        }\n      } catch (error) {\n        LogRocket.captureException(error)\n        this.error = true\n        throw new Error(error)\n      }\n    },\n    async submit() {\n      if (!this.feedback) {\n        this.error = true\n        return\n      }\n\n      this.submitting = true\n      await this.sendFeedback()\n      this.submitting = false\n    },\n    reset() {\n      this.error = false\n      this.success = false\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card tile>\n    <v-card-title class=\"pb-1\">\n      We would love your feedback!\n    </v-card-title>\n    <v-card-subtitle class=\"mt-0 mb-4\">\n      Let us know how we can make Prefect Cloud a better experience for you.\n    </v-card-subtitle>\n    <v-card-text>\n      <v-scroll-x-transition mode=\"out-in\">\n        <div\n          v-if=\"success\"\n          key=\"message\"\n          class=\"text-body-2\"\n          style=\"height: 157px;\"\n        >\n          <v-icon small color=\"green\">\n            check\n          </v-icon>\n          Your feedback has been submitted. Thank you!\n        </div>\n        <v-textarea\n          v-else\n          key=\"input\"\n          v-model=\"feedback\"\n          label=\"How can we help?\"\n          outlined\n          dense\n          required\n          @input=\"reset\"\n        />\n      </v-scroll-x-transition>\n      <div\n        :style=\"{\n          height: '20px',\n          position: 'relative',\n          top: '-12px'\n        }\"\n      >\n        <v-scroll-x-transition>\n          <div v-if=\"error\" class=\"text-body-2\">\n            <v-icon small color=\"error\">\n              error\n            </v-icon>\n            Something went wrong while submitting your feedback. Please try\n            again.\n          </div>\n        </v-scroll-x-transition>\n      </div>\n    </v-card-text>\n    <v-card-actions>\n      <v-spacer></v-spacer>\n      <v-btn text @click=\"$emit('close')\">\n        Cancel\n      </v-btn>\n      <v-btn\n        :disabled=\"!feedback\"\n        color=\"primary\"\n        :loading=\"submitting\"\n        @click=\"submit\"\n      >\n        Submit\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.message-height {\n  height: 30px;\n}\n</style>\n"
  },
  {
    "path": "src/components/Footer.vue",
    "content": "<script>\nconst socialIcons = [\n  {\n    alt: 'GitHub',\n    link: 'https://github.com/PrefectHQ',\n    icon: 'fab fa-github'\n  },\n  {\n    alt: 'Slack',\n    link: 'https://prefect-community.slack.com',\n    icon: 'fab fa-slack'\n  },\n  {\n    alt: 'Twitter',\n    link: 'https://twitter.com/PrefectIO',\n    icon: 'fab fa-twitter'\n  },\n  {\n    alt: 'Discourse',\n    link: 'https://discourse.prefect.io',\n    icon: 'fab fa-discourse'\n  }\n]\nconst links = [\n  {\n    text: 'Docs',\n    link: 'https://docs.prefect.io/'\n  },\n  {\n    text: 'Legal',\n    link:\n      'https://www.prefect.io/legal/prefect-cloud-software-as-a-service-saas-agreement'\n  },\n  {\n    text: 'Community',\n    link: 'https://www.prefect.io/community/updates'\n  },\n  {\n    text: 'Blog',\n    link: 'https://medium.com/the-prefect-blog'\n  },\n  {\n    text: 'Careers',\n    link: 'https://www.prefect.io/about/company#careers'\n  },\n  {\n    text: 'Discourse',\n    link: 'https://discourse.prefect.io'\n  }\n]\n\nconst insetRoutes = ['user', 'tutorials']\n\nexport default {\n  data() {\n    return {\n      visible: false\n    }\n  },\n  computed: {\n    inset() {\n      return insetRoutes.includes(this.$route.path.split('/')[1])\n    },\n    linksLeft() {\n      return links.slice(0, Math.ceil(links.length / 2))\n    },\n    linksRight() {\n      return links.slice(Math.ceil(links.length / 2))\n    },\n    socialIconsLeft() {\n      return socialIcons.slice(0, Math.ceil(socialIcons.length / 2))\n    },\n    socialIconsRight() {\n      return socialIcons.slice(Math.ceil(socialIcons.length / 2))\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.visible = entry.isIntersecting\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-intersect=\"onIntersect\">\n    <v-slide-y-reverse-transition>\n      <v-footer\n        v-if=\"visible\"\n        color=\"transparent\"\n        padless\n        absolute\n        :inset=\"inset\"\n        :class=\"{\n          'sm-and-down-left-padding': inset && $vuetify.breakpoint.smAndDown,\n          'sm-and-up-left-padding': inset && $vuetify.breakpoint.smAndUp,\n          'sm-and-down-bottom-padding': $vuetify.breakpoint.smAndDown\n        }\"\n      >\n        <v-card flat tile width=\"100%\" class=\"transparent\">\n          <v-divider class=\"mx-auto\" style=\"max-width: 1440px;\"></v-divider>\n\n          <v-card-text class=\"d-flex align-center justify-center\">\n            <div class=\"block d-flex flex-column align-end justify-start\">\n              <div>\n                <v-btn\n                  v-for=\"(icon, i) in socialIconsLeft\"\n                  :key=\"i\"\n                  :href=\"icon.link\"\n                  target=\"_blank\"\n                  depressed\n                  icon\n                  :class=\"inset ? 'ml-2' : 'ml-4'\"\n                >\n                  <v-icon>{{ icon.icon }}</v-icon>\n                </v-btn>\n              </div>\n\n              <div\n                class=\"mr-1 mt-4 d-flex w-100 flex-wrap\"\n                :class=\"{\n                  'justify-space-between': $vuetify.breakpoint.smAndUp,\n                  'justify-end': $vuetify.breakpoint.xsOnly,\n                  'text-right': $vuetify.breakpoint.xsOnly\n                }\"\n              >\n                <div\n                  v-for=\"(link, i) in linksLeft\"\n                  :key=\"i\"\n                  style=\"min-width: 66px;\"\n                >\n                  <a class=\"link\" :href=\"link.link\">\n                    {{ link.text }}\n                  </a>\n                </div>\n              </div>\n            </div>\n\n            <div\n              class=\"text-center\"\n              :class=\"{\n                'mx-16': $vuetify.breakpoint.mdAndUp,\n                'mx-2': $vuetify.breakpoint.smAndDown\n              }\"\n            >\n              <div class=\"text-overline\">Made with ♡ in DC</div>\n\n              <a href=\"https://prefect.io\" target=\"_blank\">\n                <img\n                  class=\"logo mt-2\"\n                  src=\"@/assets/logos/logomark-cerulean.svg\"\n                  alt=\"The Prefect Logo\"\n                />\n              </a>\n            </div>\n\n            <div class=\"block d-flex flex-column align-start justify-start\">\n              <div>\n                <v-btn\n                  v-for=\"(icon, i) in socialIconsRight\"\n                  :key=\"i\"\n                  :href=\"icon.link\"\n                  target=\"_blank\"\n                  depressed\n                  icon\n                  :class=\"inset ? 'mr-2' : 'mr-4'\"\n                >\n                  <v-icon>{{ icon.icon }}</v-icon>\n                </v-btn>\n              </div>\n\n              <div class=\"ml-1 mt-4 d-flex w-100 flex-wrap\">\n                <div\n                  v-for=\"(link, i) in linksRight\"\n                  :key=\"i\"\n                  :class=\"{\n                    'justify-space-between': $vuetify.breakpoint.smAndUp,\n                    'justify-start': $vuetify.breakpoint.xsOnly,\n                    'text-left': $vuetify.breakpoint.xsOnly\n                  }\"\n                  style=\"min-width: 66px;\"\n                >\n                  <a class=\"link\" :href=\"link.link\">\n                    {{ link.text }}\n                  </a>\n                </div>\n              </div>\n            </div>\n          </v-card-text>\n        </v-card>\n      </v-footer>\n    </v-slide-y-reverse-transition>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.logo {\n  filter: grayscale(1);\n  height: 50px;\n  width: auto;\n}\n\n.block {\n  width: 200px;\n}\n\n.w-100 {\n  width: 100%;\n}\n\n.sm-and-up-left-padding {\n  // Match left padding with sidebar widths\n  padding-left: 256px;\n}\n\n.sm-and-down-left-padding {\n  // Match left padding with collapsed sidebar widths\n  padding-left: 56px;\n}\n\n.sm-and-down-bottom-padding {\n  // padding-bottom: 56px;\n}\n</style>\n"
  },
  {
    "path": "src/components/FullPagination.vue",
    "content": "<script>\nexport default {\n  props: {\n    countOptions: {\n      type: Array,\n      default: () => [10, 20, 50],\n      validator: countOptions => {\n        // expecting an array of integers with a length > 0\n        return countOptions.length > 0\n      }\n    },\n    page: {\n      required: true,\n      type: Number,\n      validator: page => page > 0\n    },\n    totalItems: {\n      required: true,\n      type: Number,\n      validator: totalItems => totalItems > 0\n    }\n  },\n  data() {\n    return {\n      selected: this.countOptions[0]\n    }\n  },\n  computed: {\n    disableDecrementPage() {\n      return this.page === 1\n    },\n    disableIncrementPage() {\n      return this.endingNumber >= this.totalItems\n    },\n    endingNumber() {\n      const product = this.selected * this.page\n      if (product <= this.totalItems) return product\n\n      return this.totalItems\n    },\n    startingNumber() {\n      if (this.page === 1) {\n        return 1\n      }\n      return (this.page - 1) * this.selected + 1\n    },\n    style() {\n      return { width: `${this.selected.toString().length * 25}px` }\n    }\n  },\n  methods: {\n    handleChange(newCount) {\n      this.$emit('change-page', 1)\n      this.$emit('change-count-option', newCount)\n    },\n    handleDecrementPage() {\n      if (this.page > 1) {\n        this.$emit('change-page', this.page - 1)\n      }\n    },\n    handleIncrementPage() {\n      if (this.page * this.selected <= this.totalItems) {\n        this.$emit('change-page', this.page + 1)\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"d-flex justify-end align-center\">\n    <div class=\"d-flex align-baseline justify-end\">\n      <div class=\"mr-2 text-caption black--text\">\n        Items per page:\n      </div>\n      <div :style=\"style\">\n        <v-select\n          v-model=\"selected\"\n          class=\"text-caption\"\n          hide-details\n          :items=\"countOptions\"\n          @change=\"handleChange\"\n        />\n      </div>\n      <div class=\"text-caption mx-5 black--text\">\n        {{ startingNumber }}-{{ endingNumber }} of {{ totalItems }}\n      </div>\n      <div>\n        <v-btn\n          icon\n          :disabled=\"disableDecrementPage\"\n          @click=\"handleDecrementPage\"\n        >\n          <v-icon>chevron_left</v-icon>\n        </v-btn>\n        <v-btn\n          icon\n          :disabled=\"disableIncrementPage\"\n          @click=\"handleIncrementPage\"\n        >\n          <v-icon>chevron_right</v-icon>\n        </v-btn>\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/Functional/CronClock.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nimport cronstrue from 'cronstrue'\nimport moment from 'moment-timezone'\nimport { PARSED_SCHEDULE_REGEX } from '@/utils/regEx'\n\nexport default {\n  props: {\n    cron: {\n      type: String,\n      required: true\n    },\n    verbose: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    timezone: {\n      type: String,\n      required: false,\n      default: null\n    }\n  },\n  computed: {\n    parsedCron() {\n      return cronstrue.toString(this.cron, { verbose: this.verbose })\n    },\n    timezoneAbbr() {\n      return moment()\n        .tz(this.timezone)\n        .zoneAbbr()\n    },\n    highlightedText() {\n      if (!this.parsedCron) return ''\n      if (this.timezone) {\n        return this.parsedCron\n          .replace(PARSED_SCHEDULE_REGEX, match => {\n            return `<span class=\"primary--text\">${match}</span>`\n          })\n          .concat(`<span class=\"primary--text\"> (${this.timezoneAbbr})</span>`)\n      } else {\n        return this.parsedCron.replace(PARSED_SCHEDULE_REGEX, match => {\n          return `<span class=\"primary--text\">${match}</span>`\n        })\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <span v-html=\"highlightedText\"></span>\n</template>\n"
  },
  {
    "path": "src/components/Functional/IntervalClock.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nimport { intervalToEnglish } from '@/utils/dateTime'\nimport { PARSED_SCHEDULE_REGEX } from '@/utils/regEx'\n\nexport default {\n  props: {\n    interval: {\n      type: [String, Number],\n      required: true\n    }\n  },\n  computed: {\n    parsedInterval() {\n      return intervalToEnglish(Number(this.interval) * 0.001)\n    }\n  },\n  methods: {\n    generateHighlightedText(string) {\n      return string.replace(PARSED_SCHEDULE_REGEX, match => {\n        return `<span class=\"primary--text\">${match}</span>`\n      })\n    }\n  }\n}\n</script>\n\n<template>\n  <span v-html=\"`${generateHighlightedText(parsedInterval)}`\"></span>\n</template>\n"
  },
  {
    "path": "src/components/Functional/Transition-Height.js",
    "content": "import Velocity from 'velocity-animate'\n\nexport default {\n  functional: true,\n  render: function(createElement, context) {\n    const data = {\n      props: {\n        name: 'HeightTransition',\n        mode: 'out-in'\n      },\n      on: {\n        beforeEnter: function(el) {\n          el.style['max-height'] = 0\n          el.style.opacity = 0\n        },\n        enter: function(el, done) {\n          // This will try to find a parent component\n          // whose height isn't set to auto, up to 2 levels\n          // above the transitioning components\n          let parent =\n            getComputedStyle(el.parentElement)?.height == 'auto'\n              ? el.parentElement.parentElement\n              : el.parentElement\n\n          let elHeight = getComputedStyle(el).height\n\n          let height =\n            parseFloat(getComputedStyle(parent).height) +\n            parseFloat(elHeight) +\n            'px'\n          Velocity(parent, { 'max-height': height }, { complete: done })\n          Velocity(\n            el,\n            { opacity: 1, 'max-height': elHeight },\n            { complete: done }\n          )\n        },\n        leave: function(el, done) {\n          let delay = el.dataset.index * 150\n          let parent =\n            getComputedStyle(el.parentElement)?.height == 'auto'\n              ? el.parentElement.parentElement\n              : el.parentElement\n\n          let height =\n            parseFloat(getComputedStyle(parent).height) -\n            parseFloat(getComputedStyle(el).height) +\n            'px'\n\n          Velocity(el, { opacity: 0, 'max-height': 0 }, { complete: done })\n          setTimeout(function() {\n            Velocity(parent, { 'max-height': height }, { complete: done })\n          }, delay)\n        }\n      }\n    }\n    return createElement('transition-group', data, context.children)\n  }\n}\n"
  },
  {
    "path": "src/components/Functional/TruncatedSpan.vue",
    "content": "<script>\nimport { VTooltip } from 'vuetify/lib'\n\nexport default {\n  components: {\n    VTooltip\n  },\n  props: {\n    content: {\n      type: [Number, String],\n      required: false,\n      default: null\n    }\n  }\n}\n</script>\n\n<template functional>\n  <component :is=\"$options.components.VTooltip\" top>\n    <template #activator=\"{ on }\">\n      <div\n        class=\"text-truncate\"\n        style=\"\n          width: auto;\n        \"\n        v-on=\"on\"\n      >\n        <slot>\n          {{ props.content }}\n        </slot>\n      </div>\n    </template>\n    <span>{{ props.content }}</span>\n  </component>\n</template>\n"
  },
  {
    "path": "src/components/GetCloud.vue",
    "content": "<template>\n  <a\n    title=\"Get Cloud!\"\n    href=\"https://www.prefect.io/get-prefect#pricing\"\n    target=\"_blank\"\n  >\n    <v-icon v-if=\"!isCloud\" dense class=\"mr-2\">\n      cloud\n    </v-icon>\n    Get Cloud\n  </a>\n</template>\n\n<script>\nimport { mapGetters } from 'vuex'\nexport default {\n  computed: {\n    ...mapGetters('api', ['isCloud'])\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/GlobalSearchBar/GlobalSearch.vue",
    "content": "<script>\nimport globalNameSearchQuery from '@/graphql/GlobalSearch/search-by-name.gql'\nimport globalIDSearchQuery from '@/graphql/GlobalSearch/search-by-id.gql'\nimport GlobalSearchIcon from '@/components/GlobalSearchBar/GlobalSearchIcon'\nimport GlobalSearchResult from '@/components/GlobalSearchBar/GlobalSearchResult'\nimport MResult from '@/components/GlobalSearchBar/MResult'\nimport { mapGetters } from 'vuex'\nimport HavingTrouble from '@/components/HavingTrouble'\n\nexport default {\n  components: { HavingTrouble, GlobalSearchIcon, GlobalSearchResult, MResult },\n  data() {\n    return {\n      activateTimeout: null,\n      active: false,\n      input: null,\n      model: null,\n      search: null,\n      results: [],\n      isLoading: false,\n      mResult: false\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['connected']),\n    ...mapGetters('tenant', ['tenant']),\n    id() {\n      if (!this.input) return ''\n\n      // Call .trim() to get rid of whitespace on the ends of the\n      // string before making the query\n      return `${this.input.trim()}`\n    },\n    isSearchForID() {\n      const UUIDRegex = /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/\n\n      // Call .trim() to get rid of whitespace on the ends of the\n      // string before making the query\n      return UUIDRegex.test(this.input.trim())\n    },\n    name() {\n      if (!this.input) return ''\n      // Call .trim() to get rid of whitespace on the ends of the\n      // string before making the query\n      return `%${this.input.trim()}%`\n    },\n    entries() {\n      const resultsWithNames = this.results.map(result => {\n        result.name = result.name || result.id\n        return result\n      })\n      return resultsWithNames\n    }\n  },\n  watch: {\n    search(val) {\n      this.handleSearch(val)\n    },\n    model(val) {\n      this.handleResultSelected(val)\n    }\n  },\n  mounted() {\n    // Adds the event listener for the / search shortcut\n    window.addEventListener('keyup', this.handleKeyboardShortcut)\n  },\n  beforeDestroy() {\n    // Removes the / search shortcut event listener when\n    // the component is destroyed\n    window.removeEventListener('keyup', this.handleKeyboardShortcut)\n  },\n  methods: {\n    _activate() {\n      clearTimeout(this.activateTimeout)\n      this.active = true\n\n      // Wait till the animation has finished\n      this.activateTimeout = setTimeout(() => {\n        // We can no longer use the onClick method because\n        // it requires a click event to work properly\n        this.$refs['global-search'].activateMenu()\n        this.$refs['global-search'].focus()\n      }, 250)\n    },\n    _deactivate() {\n      clearTimeout(this.activateTimeout)\n      this.$refs['global-search'].reset()\n\n      this.input = null\n      this.model = null\n      this.search = null\n      this.results = []\n\n      this.activateTimeout = setTimeout(() => {\n        this.active = false\n      }, 100)\n    },\n    handleKeyboardShortcut(e) {\n      if (\n        e.key &&\n        e.key === '/' &&\n        e.srcElement.tagName !== 'INPUT' &&\n        e.srcElement.tagName !== 'TEXTAREA'\n      ) {\n        this._activate()\n      }\n    },\n    handleSearch(input) {\n      // We set the input prop to null if the input\n      // string is empty, to bring back up the searchbox hint\n      this.input = input == '' ? null : input\n\n      // If there's no input or apollo has been told to\n      // pause all queries elsewhere (the skipAll prop),\n      // we pause the individual queries and\n      // remove all results. This will show the typing hint\n      // again if the user has focused the global search focus\n      if (!input || this.$apollo.skipAll) {\n        this.$apollo.queries.nameQuery.skip = true\n        this.$apollo.queries.idQuery.skip = true\n        this.results = []\n        return\n      }\n      this.mResult = input == 'about:Prefect' ? true : false\n\n      // Once we've confirmed that we have input and\n      // we aren't pausing all queries, we check that\n      // the input matches a UUID regex which is stored as\n      // a computed prop called isSearchForID\n      // If that's the case, we start an id query and\n      // pause the name query.\n      if (this.isSearchForID) {\n        this.startQuery('id')\n        this.$apollo.queries.nameQuery.skip = true\n      }\n      // Otherwise, we start a name query and pause\n      // the id query.\n      else {\n        this.startQuery('name')\n        this.$apollo.queries.idQuery.skip = true\n      }\n    },\n    async handleResultSelected(searchResultName) {\n      // If this is called with no argument\n      // we return immediately\n      if (!searchResultName) return\n\n      // The search result that we use is found in the\n      // entries on name, since the VAutocomplete\n      // component will always pass the name prop to this\n      // method regardless of the query used (id or name)\n      let searchResult = this.entries.find(\n        result => result.name == searchResultName\n      )\n\n      // Pause all queries\n      this.$apollo.skipAll = true\n\n      const routeToNavigateTo = this.routeName(searchResult.__typename)\n\n      // Navigate to the URL based on the search result\n      await this.$router.push({\n        name: routeToNavigateTo,\n        params: { id: searchResult.id, tenant: this.tenant.slug }\n      })\n\n      this._deactivate()\n    },\n    routeName(name) {\n      switch (name) {\n        case 'flow':\n          return 'flow'\n        // Since no actual routes exist for projects\n        // we just return the dashboard route\n        // when a project is selected.\n        case 'project':\n          return 'project'\n        case 'task':\n          return 'task'\n        case 'flow_run':\n          return 'flow-run'\n        case 'task_run':\n          return 'task-run'\n        default:\n          throw new Error('Unable to resolve route, GlobalSearchResult')\n      }\n    },\n    startQuery(ref) {\n      this.isLoading = true\n      // We make sure to unpause this query before\n      // we try to refetch the data\n      this.$apollo.queries[`${ref}Query`].skip = false\n      this.$apollo.queries[`${ref}Query`].refetch()\n    },\n    processResult(data, loading) {\n      this.isLoading = loading\n      // Returning if GraphQL is loading the query still\n      // leads to a better UX since the search results\n      // don't flicker between loading states\n      // i.e. we maintain is loading until GraphQL\n      // has determined loading is finished NOT\n      // when we've received some data\n      if (this.isLoading) return\n\n      this.results = data\n        ? Object.entries(data)\n            .map(e => e[1].map(e1 => (e1 ? { ...e1 } : [])))\n            .flat()\n        : []\n    },\n    searchFilter(item, queryText) {\n      // This is the filter we use to determine what the VAutocomplete\n      // method is showing. We transform all queries to lowercase\n      // for comparison for a better UX\n      return (\n        item['id']?.toLowerCase().includes(queryText.toLowerCase()) ||\n        item['name']?.toLowerCase().includes(queryText.toLowerCase()) ||\n        item['flow_id']?.toLowerCase().includes(queryText.toLowerCase())\n      )\n    }\n  },\n  apollo: {\n    idQuery: {\n      query: globalIDSearchQuery,\n      manual: true,\n      debounce: 300,\n      fetchPolicy: 'no-cache',\n      variables() {\n        return { id: this.id }\n      },\n      result({ data, loading }) {\n        this.processResult(data, loading)\n      },\n      skip: true\n    },\n    nameQuery: {\n      query: globalNameSearchQuery,\n      manual: true,\n      debounce: 300,\n      fetchPolicy: 'no-cache',\n      variables() {\n        return { name: this.name }\n      },\n      result({ data, loading }) {\n        this.processResult(data, loading)\n      },\n      skip: true\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"d-flex align-center justify-end global-search-container\"\n    :class=\"{ 'justify-center': active }\"\n  >\n    <v-btn\n      class=\"mx-1 global-search-activator cursor-pointer\"\n      :icon=\"$vuetify.breakpoint.smAndUp\"\n      :class=\"{\n        active: active,\n        'navbar-icon': $vuetify.breakpoint.smAndUp,\n        fixed: $vuetify.breakpoint.xsOnly\n      }\"\n      title=\"Search your team for projects, flows, and runs\"\n      :absolute=\"$vuetify.breakpoint.xsOnly\"\n      :fab=\"$vuetify.breakpoint.xsOnly\"\n      :elevation=\"$vuetify.breakpoint.xsOnly ? 2 : null\"\n      @click.native=\"_activate\"\n    >\n      <i class=\"fad fa-search fa-2x nav-bar-duotone-icon\" />\n    </v-btn>\n\n    <div\n      class=\"global-search\"\n      :class=\"{ active: active, fixed: $vuetify.breakpoint.xsOnly }\"\n    >\n      <v-autocomplete\n        data-public\n        v-if=\"active\"\n        ref=\"global-search\"\n        v-model=\"model\"\n        single-line\n        dense\n        outlined\n        multiple\n        :dark=\"$vuetify.breakpoint.smAndUp\"\n        clearable\n        :menu-props=\"{\n          closeOnContentClick: false,\n          closeOnClick: false\n        }\"\n        :items=\"entries\"\n        :loading=\"isLoading ? 'green accent-3' : false\"\n        :search-input.sync=\"search\"\n        :filter=\"searchFilter\"\n        label=\"Search\"\n        placeholder=\"Search\"\n        item-text=\"name\"\n        hide-details\n        clear-icon=\"close\"\n        open-on-clear\n        @blur=\"_deactivate\"\n        @clear=\"results = []\"\n        @focus=\"\n          results = []\n          handleSearch(input)\n        \"\n      >\n        <template #no-data>\n          <div\n            v-if=\"!connected\"\n            class=\"text-subtitle-1 pa-4\"\n            style=\"width: 500px;\"\n          >\n            <div class=\"font-weight-light\">\n              You aren't connected, so you won't be able to search for\n              anything...\n            </div>\n\n            <v-divider class=\"my-6 mx-6\" />\n\n            <HavingTrouble />\n          </div>\n\n          <v-list-item v-else-if=\"input == null\">\n            <v-list-item-title class=\"text-subtitle-1 font-weight-light\">\n              Type to search for a <strong>Project</strong>,\n              <strong>Flow</strong>, <strong>Task</strong>, or\n              <strong>Run</strong>\n            </v-list-item-title>\n          </v-list-item>\n\n          <v-list-item v-else-if=\"isLoading\">\n            <v-list-item-title>\n              Searching...\n            </v-list-item-title>\n          </v-list-item>\n\n          <MResult v-else-if=\"mResult\" />\n          <v-list-item v-else>\n            <v-list-item-title>\n              No results matched your search.\n            </v-list-item-title>\n          </v-list-item>\n        </template>\n\n        <template #item=\"data\">\n          <GlobalSearchIcon v-if=\"data\" :type=\"data.item.__typename\" />\n          <GlobalSearchResult\n            v-if=\"data\"\n            ref=\"result\"\n            :search-result=\"data.item\"\n            :parent-prop=\"data.parent\"\n          />\n        </template>\n      </v-autocomplete>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.global-search-container {\n  height: 100%;\n  max-width: 500px;\n  transition: all 250ms;\n}\n\n.global-search-activator {\n  &.fixed {\n    background-color: var(--v-primary-base);\n    position: fixed;\n    right: 10px;\n    top: 114px;\n    transition: all 250ms;\n    z-index: 4;\n\n    &.active {\n      right: calc(100% - 74px);\n    }\n  }\n}\n\n.global-search {\n  background-color: rgba(255, 255, 255, 0.1);\n  font-size: 1rem;\n  max-width: 500px;\n  transition: all 250ms;\n  width: 0;\n\n  &.active {\n    width: 100%;\n  }\n\n  &.fixed {\n    background-color: rgba(255, 255, 255, 1);\n    left: 74px;\n    max-width: calc(100% - 84px);\n    position: fixed;\n    top: 120px;\n    // right: 10px;\n    z-index: 4;\n  }\n}\n\n.v-select-list {\n  max-width: 500px !important;\n  width: 100% !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/GlobalSearchBar/GlobalSearchIcon.vue",
    "content": "<script>\nexport default {\n  props: {\n    type: {\n      required: true,\n      type: String,\n      validator: label => {\n        return typeof label == 'string'\n      }\n    }\n  },\n  computed: {\n    resultIcon() {\n      switch (this.type) {\n        case 'flow':\n          return 'pi-flow'\n        case 'flow_run':\n          return 'pi-flow-run'\n        case 'task':\n          return 'pi-task'\n        case 'task_run':\n          return 'pi-task-run'\n        case 'project':\n          return 'pi-project'\n        default:\n          return ''\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-list-item-avatar>\n    <v-icon>{{ resultIcon }}</v-icon>\n  </v-list-item-avatar>\n</template>\n"
  },
  {
    "path": "src/components/GlobalSearchBar/GlobalSearchResult.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\n// Added this line to disable to the v-html\n// console warning since we know we can trust the\n// data coming from the GraphQL server\nexport default {\n  props: {\n    searchResult: {\n      required: true,\n      type: Object,\n      validator: result => {\n        return (\n          result.id &&\n          result.name &&\n          ['flow', 'flow_run', 'project', 'task', 'task_run'].includes(\n            result.__typename\n          )\n        )\n      }\n    },\n    // This is a reference to the parent passed in by the VAutoComplete\n    // component. It contains important search highlighting methods\n    // but we don't use it for much else. It's typed as an Object\n    // and we're making sure the .genFilteredText() method exists on the\n    // passed prop.\n    parentProp: {\n      type: Object,\n      required: true,\n      validator: parent => {\n        return parent.genFilteredText\n      }\n    }\n  },\n  data() {\n    return {\n      parent: { ...this.parentProp }\n    }\n  },\n  computed: {\n    // Here we're just translating the\n    // __typename reference to a human-readable format.\n    // We could do this with a regex if we wanted.\n    typeName() {\n      switch (this.searchResult.__typename) {\n        case 'flow':\n          return 'Flow'\n        case 'flow_run':\n          return 'Flow Run'\n        case 'task':\n          return 'Task'\n        case 'task_run':\n          return 'Task Run'\n        case 'project':\n          return 'Project'\n        default:\n          return ''\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"search-result\">\n    <v-list-item-content>\n      <v-list-item-subtitle>{{ typeName }}</v-list-item-subtitle>\n      <!-- the .genFilteredText() method calls a number of downstream methods\n       on the parent component. This allows us to show where the user input\n      matches the results we're returning to them.\n      Since it returns HTML, we need to use the Vue HTML injector, otherwise\n      it'll be inserted as plaintext. -->\n      <v-list-item-title\n        v-html=\"`${parent.genFilteredText(searchResult.name)}`\"\n      />\n      <v-list-item-subtitle class=\"id-subtitle\">\n        {{ searchResult.name !== searchResult.id ? searchResult.id : '' }}\n      </v-list-item-subtitle>\n    </v-list-item-content>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.search-result {\n  cursor: pointer;\n  min-width: 15rem;\n}\n\n.id-subtitle {\n  font-size: 0.6rem !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/GlobalSearchBar/MResult.vue",
    "content": "<script>\nexport default {\n  data() {\n    return {\n      quotes: [\n        \"It's the people you meet in this job that really get you down.\",\n        \"It's the people you meet in this job that really get you down.\",\n        'This will all end in tears, I just know it.',\n        \"Life? Don't talk to me about life.\",\n        \"Life. Loathe it or ignore it, you can't like it.\",\n        'Incredible. It’s even worse than I thought it would be.',\n        'Don’t pretend you want to talk to me, I know you hate me.',\n        'Here I am, brain the size of a planet, and they ask me to talk to you.',\n        \"Don't feel you have to take any notice of me, please.\",\n        'I’d give you advice, but you wouldn’t listen. No one ever does.'\n      ]\n    }\n  },\n  computed: {\n    quote() {\n      return this.quotes[Math.floor(Math.random() * this.quotes.length)]\n    }\n  }\n}\n</script>\n\n<template>\n  <v-list-item>\n    <v-list-item-icon>\n      <v-icon color=\"black\">{{ '$mr' }}</v-icon>\n    </v-list-item-icon>\n    <v-list-item-content>\n      <v-list-item-title>Marvin says.....</v-list-item-title>\n      <v-list-item-subtitle class=\"id-subtitle\">\n        {{ quote }}\n      </v-list-item-subtitle>\n    </v-list-item-content>\n  </v-list-item>\n</template>\n\n<style lang=\"scss\" scoped>\n.id-subtitle {\n  font-size: 0.8rem !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/HavingTrouble.vue",
    "content": "<script>\nimport ExternalLink from '@/components/ExternalLink'\nexport default { components: { ExternalLink } }\n</script>\n\n<template>\n  <div style=\"max-width: 100%;\">\n    <div>\n      Having trouble?\n      <span class=\"font-weight-medium\">Don't panic! </span>\n    </div>\n    <div class=\"mt-4\">\n      The <v-icon x-small>fab fa-slack</v-icon>&nbsp;\n      <ExternalLink href=\"https://prefect.io/slack\"\n        >Prefect Slack community</ExternalLink\n      >\n      is a great place to ask questions, provide feedback, or just to chat!\n      Check out the\n      <ExternalLink\n        href=\"https://docs.prefect.io/orchestration/server/overview.html#what-is-prefect-server\"\n        >Prefect documentation</ExternalLink\n      >\n\n      for tips on setting up Prefect Server, idioms for writing flows, and so\n      much more. Looking for more in-depth discussion? Our\n      <ExternalLink href=\"https://github.com/PrefectHQ/prefect/discussions/new\"\n        >GitHub Discussion board</ExternalLink\n      >\n      is a great place to present long-form ideas, technical challenges, or to\n      show off your Prefect tasks and flows!\n\n      <div class=\"mt-4\"\n        >Did you know that\n\n        <ExternalLink href=\"https://www.prefect.io/cloud\"\n          >Prefect Cloud</ExternalLink\n        >\n        offers a feature-rich and fully-managed orchestration layer for your\n        flows? Oh and it's also <em>free</em>.\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/components/HeartbeatTimeline.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  mixins: [formatTime],\n  props: {\n    items: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    loading: {\n      type: Number,\n      required: false,\n      default: () => 0\n    },\n    type: {\n      type: String,\n      required: true\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone'])\n  },\n  methods: {\n    icon(item) {\n      let icon\n\n      switch (item.__typename) {\n        case 'flow_run':\n          icon = 'pi-flow-run'\n          break\n        case 'task_run_state':\n          icon = 'compare_arrows'\n          break\n        case 'task_run':\n          icon = 'pi-task-run'\n          break\n      }\n      return icon\n    },\n    routeTo(item) {\n      let routeName\n      switch (this.type) {\n        case 'project':\n          routeName = 'flow'\n          break\n        case 'flow':\n        case 'flow_run':\n          routeName = 'flow-run'\n          break\n        case 'task':\n        case 'task_run':\n          routeName = 'task-run'\n          break\n        default:\n          routeName = '/'\n          break\n      }\n\n      return {\n        name: routeName,\n        params: { id: this.type == 'project' ? item.flow?.id : item.id }\n      }\n    },\n    timelineItemTitle(item) {\n      let name\n      switch (this.type) {\n        case 'project':\n          name = item.flow?.name\n          break\n        case 'flow':\n          name = item.name\n          break\n        case 'flow_run':\n          name = item.name\n          break\n        case 'task_run':\n          name = item.name || item.task.name\n          break\n        case 'task_run_state':\n          name = item.message\n          break\n        default:\n          name = ''\n          break\n      }\n\n      return name\n    }\n  }\n}\n</script>\n\n<template>\n  <v-expansion-panels accordion hover>\n    <v-progress-linear\n      :active=\"loading > 0\"\n      indeterminate\n      color=\"primary\"\n      absolute\n    />\n\n    <v-timeline\n      class=\"heartbeat-timeline timeline-flat\"\n      dense\n      reverse\n      style=\"width: 100%;\"\n    >\n      <v-slide-x-transition group mode=\"out-in\" leave-absolute>\n        <v-timeline-item\n          v-if=\"items.length === 0 && loading > 0\"\n          key=\"skeleton\"\n          small\n          color=\"grey\"\n        >\n          <v-row class=\"align-center\">\n            <v-col cols=\"2\">\n              <v-skeleton-loader type=\"text\"></v-skeleton-loader>\n            </v-col>\n            <v-col cols=\"7\">\n              <v-skeleton-loader type=\"text\"></v-skeleton-loader>\n              <v-skeleton-loader type=\"text\"></v-skeleton-loader>\n            </v-col>\n            <v-col cols=\"3\">\n              <v-divider class=\"small-divider\" />\n            </v-col>\n          </v-row>\n        </v-timeline-item>\n\n        <v-timeline-item\n          v-else-if=\"items.length === 0 && loading === 0\"\n          key=\"no-data\"\n          color=\"grey\"\n        >\n          <v-list-item>\n            <v-list-item-content class=\"my-0 py-0\">\n              <v-list-item-title>\n                No activity\n              </v-list-item-title>\n            </v-list-item-content>\n            <v-divider class=\"small-divider\" />\n          </v-list-item>\n        </v-timeline-item>\n\n        <v-timeline-item\n          v-for=\"item in items\"\n          :key=\"item.id\"\n          small\n          :color=\"item.state\"\n          fill-dot\n          :icon=\"item.map_index > -1 ? 'dynamic_feed' : ''\"\n          class=\"pb-2\"\n        >\n          <v-expansion-panel\n            :key=\"item.id\"\n            class=\"position-relative pl-2 pr-14\"\n            style=\"background-color: transparent;\"\n            active-class=\"highlight-icon\"\n          >\n            <v-expansion-panel-header hide-actions class=\"pl-2 py-0 pr-8\">\n              <div class=\"d-flex\" style=\"max-width: 100%;\">\n                <v-icon class=\"flex-grow-0 flex-shrink-0\" left small>\n                  {{ icon(item) }}\n                </v-icon>\n\n                <div\n                  class=\"text-body-2 utilGrayMid--text flex-grow-1 flex-shrink-0 py-2\"\n                  style=\"max-width: 100%;\"\n                >\n                  <div class=\"text-caption\">\n                    {{ item.state }}\n                    {{\n                      item.state == 'Scheduled'\n                        ? `for ${formatDateTime(item.scheduled_start_time)}`\n                        : ''\n                    }}\n                  </div>\n\n                  <div\n                    class=\"text-subtitle-1 utilGrayDark--text mt-n1 text-truncate\"\n                  >\n                    {{ timelineItemTitle(item) }}\n                    <v-icon v-if=\"item.map_index > -1\" x-small class=\"mx-1\"\n                      >dynamic_feed</v-icon\n                    >\n                    <span\n                      v-if=\"item.map_index > -1 && !item.name\"\n                      class=\"text-body-2\"\n                      >{{ item.map_index }}</span\n                    >\n                  </div>\n\n                  <div\n                    v-if=\"item.state_message\"\n                    class=\"text-caption text-truncate\"\n                  >\n                    {{ item.state_message }}\n                  </div>\n\n                  <div v-else-if=\"item.name\" class=\"text-caption text-truncate\">\n                    {{ item.name }}\n                  </div>\n                </div>\n              </div>\n            </v-expansion-panel-header>\n            <v-expansion-panel-content\n              class=\"ml-2 pl-0 highlighted-border\"\n              :style=\"{\n                'border-left': `3px solid var(--v-${item.state}-base)`\n              }\"\n            >\n              <div v-if=\"type !== 'task_run_state'\" class=\"text-body-1\">\n                <router-link class=\"link\" :to=\"routeTo(item)\">\n                  {{ timelineItemTitle(item) }}\n                  <span\n                    v-if=\"item.map_index > -1 && !item.name\"\n                    class=\"text-caption mb-2\"\n                  >\n                    (Mapped Child {{ item.map_index }})\n                  </span>\n                </router-link>\n              </div>\n\n              <div v-if=\"type == 'project'\" class=\"text-subtitle-2\">\n                <router-link\n                  class=\"link\"\n                  :to=\"{ name: 'flow-run', params: { id: item.id } }\"\n                >\n                  {{ item.name }}\n                </router-link>\n              </div>\n\n              <div v-if=\"type == 'task'\">\n                <router-link\n                  class=\"link\"\n                  :to=\"{ name: 'task-run', params: { id: item.id } }\"\n                >\n                  Task Run\n                </router-link>\n              </div>\n\n              <div class=\"mb-1 text-caption\">\n                {{ formatTime(item.state_timestamp || item.timestamp) }}\n              </div>\n\n              <div v-if=\"item.message\">\n                <div class=\"font-weight-medium\">Message: </div>\n                {{ item.message }}\n              </div>\n              <div v-else-if=\"item.state_message\" class=\"mt-2\">\n                <div class=\"font-weight-medium\">State Message: </div>\n                {{ item.state_message }}\n              </div>\n              <div v-else-if=\"item.result\" class=\"mt-2\">\n                <div class=\"font-weight-medium\">Result: </div>\n                {{ item.result }}\n              </div>\n\n              <v-divider />\n            </v-expansion-panel-content>\n\n            <div\n              class=\"text-caption d-flex justify-end align-center position-absolute timeline-timestamp\"\n            >\n              <v-tooltip top>\n                <template #activator=\"{ on }\">\n                  <span v-on=\"on\">\n                    {{ shortTime(item.state_timestamp || item.timestamp) }}\n                  </span>\n                </template>\n                <span>\n                  {{ formatTime(item.state_timestamp || item.timestamp) }}\n                </span>\n              </v-tooltip>\n\n              <div class=\"small-divider ml-1\">\n                <v-divider class=\"small-divider\" />\n              </div>\n            </div>\n          </v-expansion-panel>\n        </v-timeline-item>\n      </v-slide-x-transition>\n    </v-timeline>\n  </v-expansion-panels>\n</template>\n\n<style lang=\"scss\">\n// stylelint-disable\n.heartbeat-timeline {\n  overflow: hidden;\n\n  &::before {\n    right: calc(23px - 1px) !important;\n  }\n\n  .small-divider {\n    width: 15px;\n  }\n\n  .v-timeline-item__divider {\n    min-width: 46px !important;\n  }\n\n  .v-timeline-item__body {\n    max-width: calc(100% - 46px) !important;\n  }\n\n  .timeline-timestamp {\n    right: 0;\n    top: 50%;\n    transform: translate(0, -50%);\n    transition: all 150ms;\n  }\n\n  .highlight-icon {\n    i {\n      color: var(--v-primary-base) !important;\n    }\n  }\n}\n// stylelint-enable\n\n.timeline-flat {\n  .v-expansion-panel {\n    &::before {\n      box-shadow: 0 0 0 0 rgba(0, 0, 0, 0.2), 0 0 0 0 rgba(0, 0, 0, 0.14),\n        0 0 0 0 rgba(0, 0, 0, 0.12) !important;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Icons/Hashicorp.vue",
    "content": "<template>\n  <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 106.86 113.14\">\n    <title>iAsset 1</title>\n    <g id=\"Layer_2\" data-name=\"Layer 2\">\n      <g id=\"Logo\">\n        <polygon\n          points=\"44.54 0 0 25.69 0 25.71 0 87.41 16.73 97.07 16.73 35.35 44.54 19.3 44.54 0\"\n        />\n        <polygon\n          points=\"62.32 0 62.32 49.15 44.54 49.15 44.54 30.81 27.8 40.47 27.8 103.44 44.54 113.12 44.54 64.11 62.32 64.11 62.32 82.33 79.05 72.67 79.05 9.66 62.32 0\"\n        />\n        <polygon\n          points=\"62.32 113.14 106.86 87.45 106.86 87.43 106.86 25.73 90.12 16.07 90.12 77.79 62.32 93.84 62.32 113.14\"\n        />\n      </g>\n    </g>\n  </svg>\n</template>\n"
  },
  {
    "path": "src/components/Icons/Nomad.vue",
    "content": "<template>\n  <svg\n    id=\"Layer_1\"\n    version=\"1.1\"\n    xmlns=\"http://www.w3.org/2000/svg\"\n    xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n    x=\"0px\"\n    y=\"0px\"\n    viewBox=\"0 0 192 192\"\n    style=\"enable-background: new 0 0 192 192;\"\n    xml:space=\"preserve\"\n    class=\"icon\"\n  >\n    <g>\n      <path\n        class=\"st0\"\n        style=\"\n        clip-rule: evenodd;\n        fill-rule: evenodd;\"\n        d=\"M96,20.6L30.8,58.3v75.4L96,171.4l65.2-37.7V58.3L96,20.6z M126.8,103.1l-18.4,10.4L84.7,99.8v27.1l-19.7,11.8\n\t\tV89.1l19.7-10.9L106,90.7V64.9l20.6-12v50.1H126.8z\"\n      />\n    </g>\n  </svg>\n</template>\n\n<style lang=\"scss\" scoped>\n.icon {\n  fill: currentColor;\n}\n</style>\n"
  },
  {
    "path": "src/components/Icons/PagerDuty.vue",
    "content": "<template>\n  <svg\n    version=\"1.1\"\n    id=\"Layer_1\"\n    xmlns=\"http://www.w3.org/2000/svg\"\n    xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n    x=\"0px\"\n    y=\"0px\"\n    viewBox=\"0 0 120.6 175\"\n    style=\"enable-background:new 0 0 120.6 175;\"\n    xml:space=\"preserve\"\n  >\n    <g>\n      <rect y=\"128.4\" class=\"pd\" width=\"25.7\" height=\"46.6\" />\n      <path\n        class=\"pd\"\n        d=\"M96.5,8.6C82.8,1.2,73.2,0,50.7,0H0v106.1h25.7H29h21.5c20,0,35-1.2,48.2-10c14.4-9.5,21.9-25.4,21.9-43.8\n\t\tC120.6,32.5,111.4,16.6,96.5,8.6z M56.4,83.9H25.7V22.7l29-0.2c26.4-0.2,39.6,9,39.6,30.1C94.3,75.3,77.9,83.9,56.4,83.9z\"\n      />\n    </g>\n  </svg>\n</template>\n\n<style type=\"text/css\">\n.pd {\n  fill: currentColor;\n}\n</style>\n"
  },
  {
    "path": "src/components/Icons/Prefect.vue",
    "content": "<script>\nexport default {\n  props: {\n    white: {\n      type: String,\n      required: false,\n      default: 'grey'\n    }\n  }\n}\n</script>\n\n<template>\n  <svg\n    width=\"464px\"\n    height=\"745px\"\n    viewBox=\"0 0 464 745\"\n    version=\"1.1\"\n    xmlns=\"http://www.w3.org/2000/svg\"\n    xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n    class=\"icon\"\n  >\n    <!-- Generator: Sketch 52.5 (67469) - http://www.bohemiancoding.com/sketch -->\n    <title>logomark/primary-dark</title>\n    <desc>Created with Sketch.</desc>\n    <defs>\n      <linearGradient id=\"linearGradient-1\" x1=\"85%\" y1=\"85%\" x2=\"14%\" y2=\"13%\">\n        <stop class=\"icon\" offset=\"0%\"></stop>\n        <stop class=\"icon\" offset=\"97%\"></stop>\n      </linearGradient>\n      <polygon id=\"path-2\" points=\"232 115 0.5 0 0.5 235\"></polygon>\n      <linearGradient id=\"linearGradient-4\" x1=\"9%\" y1=\"10%\" x2=\"139%\" y2=\"37%\">\n        <stop class=\"icon\" offset=\"0%\"></stop>\n        <stop class=\"icon\" offset=\"100%\"></stop>\n      </linearGradient>\n      <linearGradient id=\"linearGradient-5\" x1=\"9%\" y1=\"10%\" x2=\"65%\" y2=\"109%\">\n        <stop class=\"icon\" offset=\"0%\"></stop>\n        <stop class=\"icon\" offset=\"100%\"></stop>\n      </linearGradient>\n    </defs>\n    <g\n      id=\"logomark/primary-dark\"\n      stroke=\"none\"\n      stroke-width=\"1\"\n      fill-rule=\"evenodd\"\n    >\n      <g id=\"Dark\">\n        <g id=\"middle-triangle\" transform=\"translate(231.000000, 231.000000)\">\n          <mask id=\"mask-3\" fill=\"white\">\n            <use xlink:href=\"#path-2\"></use>\n          </mask>\n          <use id=\"triangle\" xlink:href=\"#path-2\"></use>\n          <polygon\n            id=\"left-shadow\"\n            fill-opacity=\"0.2\"\n            mask=\"url(#mask-3)\"\n            points=\"30 220 0.5 45 0.5 235\"\n          ></polygon>\n          <polygon\n            id=\"right-shadow\"\n            fill-opacity=\"0.2\"\n            mask=\"url(#mask-3)\"\n            points=\"202.5 101 0.5 0 0.5 25\"\n          ></polygon>\n        </g>\n        <path\n          id=\"leg\"\n          d=\"M14,742 C14.5,742 226,639 227,639 C229,637 231,636 231,631 C231,631 231,231 231,231 C141,276 15,339 4,345 C0.5,346 0,348 0,351 L0,732 C0,740 0.5,749 14,742 Z\"\n        ></path>\n        <path\n          id=\"top\"\n          d=\"M463,119 L463,346 C463,346 31,130 16,122 C6,117 6,112 16,107.166 C25,102 200,14 227,1 C231,-0 232,-0 235,0 L458,112 C462,114 463,116 463,119 Z\"\n          f\n        ></path>\n      </g>\n    </g>\n  </svg>\n</template>\n\n<style lang=\"scss\" scoped>\n.icon {\n  fill: currentColor;\n  stop-color: currentColor;\n}\n</style>\n"
  },
  {
    "path": "src/components/Icons/mr.vue",
    "content": "<template>\n  <svg\n    version=\"1.0\"\n    xmlns=\"http://www.w3.org/2000/svg\"\n    width=\"206.000000pt\"\n    height=\"216.000000pt\"\n    viewBox=\"0 0 206.000000 216.000000\"\n    preserveAspectRatio=\"xMidYMid meet\"\n    class=\"icon\"\n  >\n    <g\n      transform=\"translate(0.000000,216.000000) scale(0.050000,-0.050000)\"\n      stroke=\"none\"\n    >\n      <path\n        d=\"M1646 4030 c-9 -22 -34 -42 -56 -45 -108 -15 -132 -21 -144 -32 -7 -7 -23 -3 -37 8 -17 14 -34 11 -55 -10 -17 -17 -41 -31 -53 -31 -11 0 -21 -9 -21 -20 0 -11 -22 -20 -50 -20 -27 0 -50 -7 -50 -15 -1 -8 -46 -42 -100 -74 -55 -33 -100 -66 -100 -75 0 -9 -7 -14 -16 -11 -35 11 -304 -227 -304 -268 0 -11 -9 -14 -20 -7 -11 7 -29 -11 -40 -39 -11 -29 -38 -72 -60 -96 -23 -24 -47 -65 -53 -89 -6 -25 -19 -41 -29 -35 -10 6 -18 -1 -18 -17 0 -16 -19 -52 -41 -81 -23 -29 -32 -53 -19 -53 14 0 11 -12 -8 -31 -17 -16 -25 -43 -19 -60 6 -16 2 -29 -8 -29 -62 0 -98 -817 -42 -952 13 -32 22 -65 20 -73 -2 -8 6 -15 17 -15 11 0 20 -28 20 -61 0 -41 8 -57 23 -47 16 10 20 1 12 -29 -6 -24 -3 -48 7 -54 10 -7 13 -22 5 -33 -8 -13 -4 -16 10 -8 13 8 23 5 23 -7 0 -39 6 -51 34 -71 30 -22 66 -80 116 -185 17 -36 37 -65 45 -65 8 0 56 -38 105 -85 142 -134 264 -226 340 -257 83 -33 79 -33 225 -36 92 -2 115 -9 115 -34 0 -27 -5 -28 -30 -8 -25 21 -30 18 -30 -18 0 -37 -6 -40 -40 -22 -32 17 -40 15 -40 -9 0 -17 -14 -31 -31 -31 -39 0 -25 -25 86 -150 102 -114 95 -118 138 81 19 87 43 165 55 173 11 7 -7 20 -39 28 -863 214 -1339 1265 -941 2078 608 1245 2479 1121 2919 -194 232 -692 -173 -1555 -853 -1819 -43 -16 -76 -36 -74 -43 1 -7 36 -86 77 -176 l75 -162 74 107 c80 116 91 148 44 130 -18 -7 -30 0 -30 18 0 25 -8 26 -42 8 -38 -20 -40 -18 -28 22 12 36 8 43 -18 33 -17 -7 -32 -5 -32 5 0 21 77 39 195 45 64 3 99 18 139 60 29 31 65 56 78 56 14 0 56 36 93 80 38 44 79 80 91 80 12 0 36 29 53 65 17 36 56 92 87 125 67 72 224 391 224 456 0 17 9 34 20 37 36 12 71 628 36 649 -9 6 -12 19 -5 29 14 23 -34 259 -53 259 -7 0 -20 20 -28 45 -19 58 -16 52 -59 145 -21 44 -38 87 -39 95 -1 8 -39 62 -84 120 -45 58 -93 125 -106 150 -13 25 -34 46 -48 46 -13 1 -55 41 -94 89 -38 48 -80 88 -92 89 -20 1 -127 75 -209 145 -17 14 -48 29 -70 32 -21 4 -48 17 -59 30 -38 43 -105 72 -145 61 -25 -6 -44 2 -52 22 -9 23 -26 28 -63 19 -28 -7 -62 -4 -75 7 -32 26 -153 46 -300 51 -63 2 -115 11 -115 20 0 9 -9 11 -19 5 -45 -28 -267 -34 -283 -8 -12 20 -20 16 -32 -13z\"\n      ></path>\n      <path\n        d=\"M1905 2191 c-609 -53 -1325 -243 -1325 -351 0 -31 19 -25 167 50 175 89 168 90 293 -41 58 -62 112 -105 120 -95 8 9 65 85 126 170 92 125 125 156 178 165 192 34 626 73 926 84 l340 13 147 -155 c80 -85 148 -151 151 -148 2 4 40 64 83 133 87 140 64 133 299 92 132 -22 53 34 -94 67 -179 41 -1020 50 -1411 16z m1190 -56 c-12 -38 -144 -43 -174 -6 -23 27 -14 31 78 31 75 0 102 -7 96 -25z m-1896 -143 c-28 -27 -76 -39 -138 -34 -54 4 46 61 108 61 52 1 56 -3 30 -27z\"\n      ></path>\n      <path\n        d=\"M2333 910 c-163 -45 -378 -56 -563 -30 -200 28 -211 25 -119 -38 184 -126 436 -144 637 -44 219 107 242 166 45 112z\"\n      ></path>\n      <path\n        d=\"M2890 812 c-45 -32 -18 -167 62 -310 l49 -88 -61 -52 c-66 -57 -75 -93 -52 -213 21 -106 115 -170 174 -118 81 74 65 196 -36 282 l-50 42 58 35 c89 52 116 105 77 149 -17 19 -26 39 -21 45 6 6 -3 22 -20 36 -16 14 -30 40 -30 57 -1 67 -110 165 -150 135z\"\n      ></path>\n      <path\n        d=\"M1071 706 c-29 -27 -45 -59 -38 -76 6 -17 2 -30 -9 -30 -81 0 -27 -243 62 -276 l62 -24 -65 -67 c-105 -108 -88 -221 35 -229 105 -8 121 11 122 141 0 95 -9 111 -106 180 -34 25 -34 30 7 122 103 233 63 382 -70 259z\"\n      ></path>\n      <path\n        d=\"M2469 551 c-8 -51 -9 -97 -4 -103 6 -5 16 32 24 83 8 51 10 97 4 103 -5 5 -16 -32 -24 -83z\"\n      ></path>\n      <path\n        d=\"M1584 498 c1 -37 16 -81 32 -97 27 -27 28 -21 16 50 -20 103 -50 134 -48 47z\"\n      ></path>\n      <path\n        d=\"M1860 268 c-168 -29 -171 -30 -290 -149 l-120 -121 160 4 c107 3 176 15 209 36 76 49 593 47 630 -3 20 -28 56 -35 182 -35 l156 0 -49 52 c-26 28 -108 96 -180 150 l-133 98 -197 -2 c-109 -1 -274 -15 -368 -30z\"\n      ></path>\n    </g>\n  </svg>\n</template>\n\n<style lang=\"scss\" scoped>\n.icon {\n  fill: currentColor;\n}\n</style>\n"
  },
  {
    "path": "src/components/Icons/newPagerDuty.vue",
    "content": "<template>\n  <svg\n    version=\"1.1\"\n    id=\"Layer_1\"\n    xmlns=\"http://www.w3.org/2000/svg\"\n    xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n    x=\"0px\"\n    y=\"0px\"\n    viewBox=\"0 0 974.8 200\"\n    style=\"enable-background:new 0 0 974.8 200;\"\n    xml:space=\"preserve\"\n  >\n    <g>\n      <path\n        class=\"st0\"\n        d=\"M950.5,41.9l-22,62.4c-4,11.2-6,17.6-9.7,28.4h-0.4c-2.9-9.3-5.5-16.8-9.3-27.8l-21.4-63.1h-25.6l44.3,115.8\n\t\tc-1,2.5-2,5.1-3.1,7.8c-3.7,9-12.5,14.9-22.2,14.9l-11,0V200h11.3c18.3,0,34.8-11.1,41.6-28.2c14.1-35.3,38.1-95.4,51.8-129.9\n\t\tH950.5z\"\n      />\n      <path\n        class=\"st0\"\n        d=\"M336.2,135.4c0,41.9-19.2,64.6-58,64.6c-28.9,0-46.3-15.2-52.5-38.1h23.4c4,10.6,12.3,20.1,29.5,20.1\n\t\tc26.5,0,35.9-16.5,35.9-47.9c-0.2,0-0.2-0.2-0.4-0.2c-5.7,9.9-18.5,18.7-38.8,18.7c-32.6,0-53.4-23.6-53.4-56.7\n\t\tc0-34.4,22.5-57.6,53.6-57.6c20.1,0,32.2,8.6,38.8,18.1c-0.2-2.4-0.2-4.9-0.2-7.3v-7.3h22.1V135.4z M246.2,95.7\n\t\tc0,22.5,12.6,38.6,34.2,38.6c19.4,0,34.4-13.7,34.4-39.3c0-22.7-13.2-37.9-34.4-37.9S246.2,72.3,246.2,95.7z\"\n      />\n      <path\n        class=\"st0\"\n        d=\"M372.7,105.6c0.9,20.3,13.9,36.4,36.4,36.4c15.9,0,23.6-7.5,29.5-17.4h22.3c-6.6,20.9-24.9,35.9-52.7,35.9\n\t\tc-35.7,0-58-24-58-60.2c0-36.2,23.2-61.7,58-61.7c37.7,0,55.1,28.7,55.1,59.8v7.3H372.7z M440.1,88c-2-18.3-13.5-31.3-32.4-31.3\n\t\tc-18.1,0-32,11.9-34.2,31.3H440.1z\"\n      />\n      <path\n        class=\"st0\"\n        d=\"M499,41.9v14.8c3.7-10.8,15-17.6,28-17.6c2.9,0,4.2,0.2,5.7,0.4v20.3c-2-0.4-5.3-0.7-7.7-0.7\n\t\tc-20.9,0-24.9,15.4-24.9,38.6v60h-22.3v-95c0-7.3,0-13.7-0.2-20.7H499z\"\n      />\n      <path\n        class=\"st0\"\n        d=\"M761.7,141.1c-6,9.9-17.2,19.4-36.8,19.4c-26.9,0-40.1-16.5-40.1-46.5V41.9H707v63.7\n\t\tc0,22.7,7.5,36.4,25.6,36.4c23.8,0,28-21.6,28-47V41.9h22.3v98.3c0,6,0,11.7,0.2,17.4h-21.4V141.1z\"\n      />\n      <path\n        class=\"st0\"\n        d=\"M833,41.9h21.6v17.2H833v69.5c0,11,5.5,14.3,14.1,14.3c1.5,0,4.2-0.2,5.5-0.4V159c-3.3,0.4-5.7,0.9-8.6,0.9\n\t\tc-20.5,0-33.5-6.8-33.5-30V59.1h-17.4V41.9h17.4V10.6H833V41.9z\"\n      />\n      <g>\n        <rect y=\"115.6\" class=\"st0\" width=\"23.1\" height=\"42\" />\n        <path\n          class=\"st0\"\n          d=\"M87,7.7C74.6,1.1,66,0,45.7,0H0v95.6h23.1h3h19.4c18.1,0,31.6-1.1,43.5-9c13-8.6,19.7-22.9,19.7-39.4\n\t\t\tC108.7,29.3,100.4,15,87,7.7z M50.8,75.6H23.1V20.5l26.1-0.2C73,20,84.9,28.4,84.9,47.4C84.9,67.8,70.2,75.6,50.8,75.6z\"\n        />\n      </g>\n      <path\n        class=\"st0\"\n        d=\"M546.3,0h38.6c57.8,0.4,85.6,28.6,85.8,79.2c0.2,43.1-22.1,77.9-82,78.5l-42.3,0V0z M569.7,138l13.5,0\n\t\tc41.9,0,63.8-16,63.8-58.9c-0.1-37.7-21.8-59.3-61.6-59.3c-7.7,0-15.7,0.2-15.7,0.2V138z\"\n      />\n      <path\n        class=\"st0\"\n        d=\"M189.7,157.7c-0.7-4.6-0.7-7.5-1.1-15.9c-8.8,12.6-20.5,18.1-39,18.1c-24.3,0-41.9-11.9-41.9-33.5\n\t\tc0-24.9,23.8-33.1,54.7-37.3c7.7-1.1,16.3-2,23.8-2.6c0-22.9-12.7-29.8-26-29.8s-23,9.3-23,21.5h-21.6c0-23.5,18.5-39.3,45.1-39.3\n\t\ts47.1,11,47.1,53.4v22.5c0,18.7,0.9,32.4,2.9,43H189.7z M131.7,126.1c0,10.8,8.8,17.6,22.9,17.6c20.7,0,31.8-12.6,31.8-35.1\n\t\tc0-2.9,0-4.9,0.2-6.2C148.9,106.3,131.7,110,131.7,126.1z\"\n      />\n    </g>\n  </svg>\n</template>\n\n<style lang=\"scss\" scoped>\n.icon {\n  fill: currentColor;\n}\n\n.st0 {\n  fill: #06ac38;\n}\n</style>\n"
  },
  {
    "path": "src/components/Icons/twilio.vue",
    "content": "<template>\n  <svg class=\"icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 30 30\">\n    <path\n      d=\"M15 0C6.7 0 0 6.7 0 15s6.7 15 15 15 15-6.7 15-15S23.3 0 15 0zm0 26C8.9 26 4 21.1 4 15S8.9 4 15 4s11 4.9 11 11-4.9 11-11 11zm6.8-14.7c0 1.7-1.4 3.1-3.1 3.1s-3.1-1.4-3.1-3.1 1.4-3.1 3.1-3.1 3.1 1.4 3.1 3.1zm0 7.4c0 1.7-1.4 3.1-3.1 3.1s-3.1-1.4-3.1-3.1c0-1.7 1.4-3.1 3.1-3.1s3.1 1.4 3.1 3.1zm-7.4 0c0 1.7-1.4 3.1-3.1 3.1s-3.1-1.4-3.1-3.1c0-1.7 1.4-3.1 3.1-3.1s3.1 1.4 3.1 3.1zm0-7.4c0 1.7-1.4 3.1-3.1 3.1S8.2 13 8.2 11.3s1.4-3.1 3.1-3.1 3.1 1.4 3.1 3.1z\"\n    />\n  </svg>\n</template>\n\n<style lang=\"scss\" scoped>\n.icon {\n  fill: currentColor;\n}\n</style>\n"
  },
  {
    "path": "src/components/KeyValueTable.vue",
    "content": "<script>\nexport default {\n  props: {\n    jsonBlob: {\n      type: Object,\n      required: true\n    }\n  },\n  methods: {\n    checkValue(value) {\n      if (value === null) {\n        return 'null'\n      } else {\n        return value\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <table>\n    <tr v-for=\"(value, key) in jsonBlob\" :key=\"key\">\n      <!-- we remove __version__ from display because this corresponds to the\n      version of Prefect Core running in Cloud, which is irrelevant and\n      confusing for users to see -->\n      <td v-if=\"key != '__version__'\" class=\"text-left text-body-1\">\n        {{ key }}\n      </td>\n      <td\n        v-if=\"key != '__version__'\"\n        id=\"value\"\n        class=\"text-right text-body-1 force-wrap\"\n      >\n        {{ checkValue(value) }}\n      </td>\n    </tr>\n  </table>\n</template>\n\n<style lang=\"scss\" scoped>\n.force-wrap {\n  word-break: break-all;\n  word-wrap: break-word;\n}\n</style>\n"
  },
  {
    "path": "src/components/Label.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nexport default {\n  props: {\n    disabled: {\n      type: Boolean,\n      default: false,\n      required: false\n    },\n    closable: {\n      type: Boolean,\n      default: false,\n      required: false\n    },\n    duplicate: {\n      type: Boolean,\n      default: false,\n      required: false\n    },\n    outlined: {\n      type: Boolean,\n      default: true,\n      required: false\n    },\n    loading: {\n      type: Boolean,\n      default: false,\n      required: false\n    },\n    size: {\n      type: String,\n      default: 'small',\n      required: false\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['hasPermission']),\n    duplicatedColor() {\n      return this.duplicate ? 'error' : 'primary'\n    }\n  },\n  methods: {\n    handleClick() {\n      if (this.closable) return\n      this.$emit('click', this.$slots.default[0].text)\n    },\n    handleRemove() {\n      this.$emit('remove', this.$slots.default[0].text)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-chip\n    :disabled=\"disabled\"\n    :color=\"duplicatedColor\"\n    :class=\"closable ? 'pr-0 overflow' : 'overflow'\"\n    :outlined=\"outlined\"\n    :x-large=\"size === 'x-large'\"\n    :large=\"size === 'large'\"\n    :small=\"size === 'small'\"\n    :x-small=\"size === 'x-small'\"\n    style=\"user-select: auto;\"\n    @click=\"handleClick\"\n  >\n    <slot></slot>\n    <v-tooltip v-if=\"closable && hasPermission('update', 'run')\" bottom>\n      <template #activator=\"{ on }\">\n        <v-btn\n          :disabled=\"disabled && !loading\"\n          :color=\"duplicatedColor\"\n          :loading=\"loading\"\n          icon\n          small\n          @click=\"handleRemove\"\n        >\n          <span v-on=\"on\">\n            <i class=\"fas fa-times-circle fa-lg\" />\n          </span>\n        </v-btn>\n      </template>\n      Remove this label\n    </v-tooltip>\n  </v-chip>\n</template>\n\n<style lang=\"scss\" scoped>\n.v-chip--disabled {\n  opacity: 1;\n}\n\n.overflow {\n  max-width: 800px !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/LabelEdit.vue",
    "content": "<script>\nimport Label from '@/components/Label'\nimport LabelWarning from '@/components/LabelWarning'\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    Label,\n    LabelWarning\n  },\n  props: {\n    flow: {\n      type: Object,\n      default: () => {}\n    },\n    flowGroup: {\n      type: Object,\n      default: () => {}\n    },\n    flowRun: {\n      type: Object,\n      default: () => {}\n    },\n    type: {\n      type: String,\n      default: ''\n    }\n  },\n  data() {\n    return {\n      //labels\n      newLabel: '',\n      labelMenuOpen: false,\n      labelEditOpen: false,\n      labelSearchInput: '',\n      removingLabel: null,\n      newLabels: null,\n      disableRemove: false,\n      disableAdd: false,\n      valid: false,\n      errorMessage: '',\n      duplicateLabel: '',\n      rules: {\n        labelCheck: value => this.checkLabelInput(value) || this.errorMessage\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['role']),\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return !this.hasPermission('update', 'run')\n    },\n    labels() {\n      const labels =\n        this.newLabels ||\n        this.flowRun?.labels ||\n        this.flowGroup?.labels ||\n        this.flow?.run_config?.labels ||\n        this.flow?.environment?.labels ||\n        []\n      return labels?.slice().sort()\n    },\n    flowOrFlowRun() {\n      return this.flowRun ? 'Flow Run' : 'Flow'\n    },\n    labelResetDisabled() {\n      const labels = this.newLabels || this.labels\n      const defaultLabels =\n        this.flow?.run_config?.labels || this.flow?.environment?.labels\n      return (\n        Array.isArray(labels) &&\n        Array.isArray(defaultLabels) &&\n        labels.length === defaultLabels.length &&\n        labels.every((val, index) => val === defaultLabels[index])\n      )\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    checkLabelInput(val) {\n      const labels = this.newLabels || this.labels\n      if (labels.includes(val) && !this.disableAdd) {\n        this.errorMessage = 'Duplicate label'\n        this.duplicateLabel = val\n        this.valid = false\n        return false\n      }\n      this.duplicateLabel = ''\n      this.valid = true\n      return true\n    },\n    removeLabel(labelToRemove) {\n      this.removingLabel = labelToRemove\n      this.disableRemove = true\n      const labels = this.newLabels || this.labels\n      const updatedArray = labels.filter(label => {\n        return labelToRemove != label\n      })\n      this.editLabels(updatedArray)\n    },\n    addLabel() {\n      if (!this.valid) return\n      if (!this.newLabel) return\n      this.disableAdd = true\n      const labelArray = this.newLabels || this.labels.slice()\n      labelArray.push(this.newLabel)\n      this.editLabels(labelArray)\n    },\n    async editLabels(newLabels) {\n      try {\n        let result\n        if (this.type !== 'flowRun') {\n          result = await this.$apollo.mutate({\n            mutation: require('@/graphql/Mutations/set-labels.gql'),\n            variables: {\n              flowGroupId: this.flowGroup.id,\n              labelArray: newLabels\n            }\n          })\n        } else {\n          result = await this.$apollo.mutate({\n            mutation: require('@/graphql/Mutations/set-flow-run-labels.gql'),\n            variables: {\n              flowRunId: this.flowRun.id,\n              labelArray: newLabels\n            }\n          })\n          this.$emit('refetch')\n        }\n        if (result.data) {\n          this.newLabels =\n            newLabels ||\n            this.flowRun?.labels ||\n            this.flow?.run_config?.labels ||\n            this.flow?.environment?.labels ||\n            []\n          this.resetLabelSettings()\n        } else {\n          this.labelsError()\n          this.resetLabelSettings()\n        }\n      } catch (e) {\n        this.labelsError(e)\n        this.resetLabelSettings()\n      }\n    },\n    labelReset() {\n      this.editLabels(null)\n    },\n    resetLabelSettings() {\n      this.removingLabel = false\n      this.disableAdd = false\n      this.newLabel = ''\n      this.disableRemove = false\n    },\n    labelsError(e) {\n      const message = e\n        ? `There was a problem: ${e}`\n        : 'There was a problem updating your labels.  Please try again.'\n      this.setAlert({\n        alertShow: true,\n        alertMessage: message,\n        alertType: 'error'\n      })\n    }\n  }\n}\n</script>\n\n<template>\n  <v-list-item dense>\n    <v-list-item-content width=\"800px\" style=\"overflow-x: auto;\">\n      <v-list-item-subtitle class=\"text-caption\">\n        Labels\n        <v-menu :close-on-content-click=\"false\" offset-y open-on-hover>\n          <template #activator=\"{ on }\">\n            <v-btn text icon x-small class=\"mr-2\" v-on=\"on\">\n              <v-icon>\n                info\n              </v-icon>\n            </v-btn>\n          </template>\n          <v-card tile class=\"pa-0\" max-width=\"320\">\n            <v-card-title class=\"subtitle pb-1\"\n              >{{ flowOrFlowRun }} Labels\n            </v-card-title>\n\n            <v-card-text class=\"pt-0\">\n              Flows, flow runs and agents have optional labels which allow you\n              to determine where your flow runs are executed. For more\n              information see\n              <a\n                href=\"https://docs.prefect.io/orchestration/execution/overview.html#labels\"\n                target=\"_blank\"\n                >the docs on labels</a\n              >.\n            </v-card-text>\n          </v-card>\n        </v-menu>\n\n        <LabelWarning\n          :flow=\"type === 'flowRun' ? flowRun.flow : flow\"\n          :flow-group=\"flowGroup\"\n          :flow-run=\"flowRun\"\n          icon-size=\"x-large\"\n          location=\"flowPageDetails\"\n        />\n        <span v-if=\"$vuetify.breakpoint.sm\" class=\"ml-8\">\n          <v-menu\n            v-model=\"labelEditOpen\"\n            :close-on-content-click=\"false\"\n            offset-y\n          >\n            <template #activator=\"{ on: menu, attrs }\">\n              <v-tooltip bottom>\n                <template #activator=\"{ on: tooltip }\">\n                  <div v-on=\"tooltip\">\n                    <v-btn\n                      small\n                      icon\n                      :disabled=\"permissionsCheck\"\n                      aria-label=\"Add label\"\n                      color=\"primary\"\n                      v-bind=\"attrs\"\n                      v-on=\"menu\"\n                    >\n                      <i class=\"far fa-plus fa-2x\" />\n                    </v-btn>\n                  </div>\n                </template>\n                <span v-if=\"permissionsCheck\">\n                  You don't have permission to edit labels</span\n                >\n                <span v-else>Add a label</span>\n              </v-tooltip>\n            </template>\n            <v-card width=\"800px\" class=\"py-0\">\n              <v-card-title class=\"subtitle pr-2 pt-2 pb-0\"\n                >{{ flowOrFlowRun }} labels</v-card-title\n              >\n\n              <v-card-text class=\"py-0 width=1500px\">\n                <div class=\"width=800px\">\n                  Flows, flow runs and agents have optional labels which allow\n                  you to determine where your flow runs are executed. For more\n                  information see\n                  <a\n                    href=\"https://docs.prefect.io/orchestration/execution/overview.html#labels\"\n                    target=\"_blank\"\n                    >the docs on labels</a\n                  >.\n                </div>\n                <v-text-field\n                  v-model=\"newLabel\"\n                  :rules=\"[rules.labelCheck]\"\n                  color=\"primary\"\n                  clearable\n                  class=\"mr-2 width=2000px\"\n                  :disabled=\"disableAdd\"\n                  @keyup.enter=\"addLabel\"\n                >\n                  <template #prepend-inner>\n                    <Label\n                      v-for=\"(label, i) in newLabels || labels\"\n                      :key=\"i\"\n                      closable\n                      :duplicate=\"duplicateLabel === label\"\n                      :loading=\"removingLabel === label\"\n                      :disabled=\"disableRemove\"\n                      class=\"mr-1 mb-1\"\n                      @remove=\"removeLabel\"\n                      >{{ label }}</Label\n                    >\n                  </template>\n                </v-text-field>\n              </v-card-text>\n            </v-card>\n          </v-menu>\n          <v-tooltip v-if=\"type !== 'flowRun'\" top>\n            <template #activator=\"{ on }\">\n              <v-btn\n                class=\"mt-0\"\n                icon\n                :disabled=\"labelResetDisabled\"\n                color=\"codePink\"\n                small\n                @click=\"labelReset\"\n                v-on=\"on\"\n              >\n                <i class=\"far fa-undo-alt fa-2x\" />\n              </v-btn>\n            </template>\n            <span>Reset to labels from flow registration</span>\n          </v-tooltip>\n        </span>\n      </v-list-item-subtitle>\n      <div\n        v-if=\"\n          (newLabels && newLabels.length > 0) || (labels && labels.length > 0)\n        \"\n      >\n        <Label\n          v-for=\"(label, i) in newLabels || labels\"\n          :key=\"i\"\n          closable\n          :duplicate=\"duplicateLabel === label\"\n          :loading=\"removingLabel === label\"\n          :disabled=\"disableRemove\"\n          class=\"mr-1 mb-1\"\n          @remove=\"removeLabel\"\n          >{{ label }}</Label\n        >\n      </div>\n      <div v-else class=\"text-subtitle-2\">\n        None\n      </div>\n    </v-list-item-content>\n    <v-list-item-action v-if=\"!$vuetify.breakpoint.sm\" class=\"ma-0\">\n      <v-tooltip v-if=\"type !== 'flowRun'\" top>\n        <template #activator=\"{ on }\">\n          <v-btn\n            class=\"mt-0\"\n            icon\n            :disabled=\"labelResetDisabled\"\n            color=\"codePink\"\n            small\n            @click=\"labelReset\"\n            v-on=\"on\"\n          >\n            <i class=\"far fa-undo-alt fa-2x\" />\n          </v-btn>\n        </template>\n        <span>Reset to labels from flow registration</span>\n      </v-tooltip>\n      <v-menu v-model=\"labelEditOpen\" :close-on-content-click=\"false\" offset-y>\n        <template #activator=\"{ on: menu, attrs }\">\n          <v-tooltip top>\n            <template #activator=\"{ on: tooltip }\">\n              <div v-on=\"tooltip\">\n                <v-btn\n                  small\n                  icon\n                  :disabled=\"permissionsCheck\"\n                  aria-label=\"Add label\"\n                  color=\"primary\"\n                  v-bind=\"attrs\"\n                  v-on=\"menu\"\n                >\n                  <i class=\"far fa-plus fa-2x\" />\n                </v-btn>\n              </div>\n            </template>\n            <span v-if=\"permissionsCheck\">\n              You don't have permission to edit labels\n            </span>\n            <span v-else>Add a label</span>\n          </v-tooltip>\n        </template>\n        <v-card width=\"800px\" class=\"py-0\">\n          <v-card-title class=\"subtitle pr-2 pt-2 pb-0\"\n            >{{ flowOrFlowRun }} labels</v-card-title\n          >\n\n          <v-card-text class=\"py-0 width=1500px\">\n            <div class=\"width=800px\">\n              Flows, flow runs and agents have optional labels which allow you\n              to determine where your flow runs are executed. For more\n              information see\n              <a\n                href=\"https://docs.prefect.io/orchestration/execution/overview.html#labels\"\n                target=\"_blank\"\n                >the docs on labels</a\n              >.\n            </div>\n            <v-text-field\n              v-model=\"newLabel\"\n              :rules=\"[rules.labelCheck]\"\n              color=\"primary\"\n              clearable\n              class=\"mr-2 width=2000px\"\n              :disabled=\"disableAdd\"\n              @keyup.enter=\"addLabel\"\n            >\n              <template #prepend-inner>\n                <Label\n                  v-for=\"(label, i) in newLabels || labels\"\n                  :key=\"i\"\n                  closable\n                  :duplicate=\"duplicateLabel === label\"\n                  :loading=\"removingLabel === label\"\n                  :disabled=\"disableRemove\"\n                  class=\"mr-1 mb-1\"\n                  @remove=\"removeLabel\"\n                  >{{ label }}</Label\n                >\n              </template>\n            </v-text-field>\n          </v-card-text>\n        </v-card>\n      </v-menu>\n    </v-list-item-action>\n  </v-list-item>\n</template>\n\n<style lang=\"scss\" scoped>\n/* stylelint-disable */\n.v-list-item__action--stack {\n  align-items: flex-start;\n  flex-direction: row;\n}\n</style>\n"
  },
  {
    "path": "src/components/LabelWarning.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nexport default {\n  props: {\n    flow: {\n      type: Object,\n      default: () => {}\n    },\n    flowGroup: {\n      type: Object,\n      default: () => {}\n    },\n    flowRun: {\n      type: Object,\n      default: () => {}\n    },\n    iconSize: {\n      type: String,\n      required: false,\n      default: null\n    },\n    location: {\n      type: String,\n      default: ''\n    }\n  },\n  data() {\n    return {\n      infoMessage: '',\n      noLabelInfo: false,\n      unsubscribeAgents: null,\n      show: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('agent', ['agents']),\n    agentOrLabel() {\n      if (!this.agents || !this.agents.length) return 'Agent Problem'\n      if (!this.labelsAlign) return 'Label Problem'\n      return 'Flow and Agent Labels'\n    },\n    agentLabels() {\n      return this.agents?.reduce((accumulator, agent) => {\n        accumulator.push(agent.labels)\n        return accumulator\n      }, [])\n    },\n    flowOrFlowRun() {\n      return this.flowRun ? 'Flow Run' : 'Flow'\n    },\n    flowLabels() {\n      return (\n        this.flowRun?.labels ||\n        this.flowGroup?.labels ||\n        this.flow?.run_config?.labels ||\n        this.flow?.environment?.labels\n      )\n    },\n    docsName() {\n      if (!this.agents?.length) return 'agents'\n      return 'Labels and Flow Affinity'\n    },\n    docsLink() {\n      if (!this.agents?.length)\n        return 'https://docs.prefect.io/orchestration/agents/overview.html'\n      return 'https://docs.prefect.io/orchestration/agents/overview.html#flow-affinity-labels'\n    },\n    labelsAlign() {\n      if (!this.agents?.length) {\n        this.labelMessage(\n          'You have no live Agents - scheduled flow runs will not be submitted for execution and might display as \"Late\".'\n        )\n        return false\n      }\n      if (\n        !this.flowLabels?.length &&\n        this.agentLabels.every(arrayOfLabels => arrayOfLabels.length > 0)\n      ) {\n        this.labelMessage(\n          `You have no currently running Agents configured to pick up flow runs without labels; you may need to add labels to your ${this.flowOrFlowRun}.`\n        )\n        return false\n      } else {\n        let matchingLabels = 0\n        if (this.agentLabels) {\n          this.agentLabels.forEach(array => {\n            if (this.flowLabels.every(label => array.includes(label)))\n              matchingLabels++\n          })\n        }\n        if (matchingLabels > 0) {\n          this.labelMessage('Your flow and agent labels look good.')\n          return true\n        } else {\n          this.labelMessage(\n            `It looks like no currently running Agent has this ${this.flowOrFlowRun}'s full set of labels. To allow an Agent to run this ${this.flowOrFlowRun}, you need to have at least one Agent whose labels include all of those on the ${this.flowOrFlowRun}.`\n          )\n          return false\n        }\n      }\n    }\n  },\n  methods: {\n    labelMessage(message) {\n      this.infoMessage = message\n    },\n    async onIntersect([entry]) {\n      if (entry.isIntersecting) {\n        this.unsubscribeAgents = await this.$store.dispatch(\n          'polling/subscribe',\n          'agents'\n        )\n      } else {\n        if (this.unsubscribeAgents) this.unsubscribeAgents()\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <span v-intersect=\"onIntersect\">\n    <v-menu\n      v-if=\"!labelsAlign\"\n      v-model=\"show\"\n      :close-on-content-click=\"false\"\n      offset-y\n      open-on-hover\n    >\n      <template #activator=\"{ on }\">\n        <div text class=\"super-imposed-icon-set cursor-pointer\" v-on=\"on\">\n          <v-icon v-ripple color=\"red\">label</v-icon>\n          <v-icon\n            x-small\n            color=\"white\"\n            class=\"nudge-icon-left\"\n            style=\"pointer-events: none;\"\n          >\n            not_interested\n          </v-icon>\n        </div>\n      </template>\n      <v-card tile class=\"pa-0\" max-width=\"320\">\n        <v-card-title class=\"subtitle pb-1\">{{ agentOrLabel }} </v-card-title>\n\n        <v-card-text class=\"pt-0\">\n          <div class=\"font-weight-bold pb-4\"> {{ infoMessage }}</div>\n          <div\n            >You can see your agent labels in the\n            <router-link\n              target=\"_blank\"\n              :to=\"{\n                name: 'dashboard',\n                params: { tenant: tenant.slug },\n                query: { agents: '' }\n              }\"\n            >\n              <span>agents tab</span></router-link\n            >.</div\n          >\n          <div>\n            You can see and edit your\n            {{ flowOrFlowRun }} labels in the\n            <router-link\n              v-if=\"location !== 'flowPageDetails'\"\n              :to=\"{\n                name: 'flow-run',\n                params: { id: flowRun.id, tenant: tenant.slug }\n              }\"\n              >flow run details tile</router-link\n            ><span v-else>{{ flowOrFlowRun }} details tile</span>.</div\n          >\n          <div v-if=\"flow && flow.is_schedule_active\" class=\"mt-4\">\n            If you need to edit labels on many scheduled flow runs, you can\n            pause the schedule and update the flow labels on the\n            <router-link\n              v-if=\"location !== 'flowPageDetails'\"\n              :to=\"{\n                name: 'flow',\n                params: { id: flow.id, tenant: tenant.slug }\n              }\"\n              >flow details tile</router-link\n            >\n            and then turn your schedule back on.\n          </div>\n          <div class=\"mt-4\">\n            For more information check out the docs on\n            <a :href=\"docsLink\" target=\"_blank\">{{ docsName }}</a>\n            .</div\n          >\n        </v-card-text>\n      </v-card>\n    </v-menu>\n  </span>\n</template>\n\n<style lang=\"scss\" scoped>\n.lefty {\n  justify-content: left;\n}\n\n.super-imposed-icon-set {\n  display: inline-block;\n  position: relative;\n\n  i {\n    z-index: 0;\n  }\n\n  i:last-child {\n    left: 50%;\n    position: absolute;\n    top: 50%;\n    transform: translate(-50%, -50%);\n    z-index: 1;\n  }\n\n  .nudge-icon-left {\n    left: 45% !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/LastTenRuns.vue",
    "content": "<script>\nimport BarChart from '@/components/Visualizations/BarChart.vue'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport moment from 'moment'\nimport TimelineTooltip from '@/components/TimelineTooltip'\n\nexport default {\n  components: {\n    BarChart,\n    TimelineTooltip\n  },\n  mixins: [formatTime],\n  props: {\n    archived: {\n      required: false,\n      type: Boolean,\n      default: () => false\n    },\n    flowId: {\n      required: false,\n      type: String,\n      default: null\n    },\n    agentId: {\n      required: false,\n      type: String,\n      default: null\n    },\n    disableView: {\n      required: false,\n      type: Boolean,\n      default: false\n    },\n    runs: {\n      required: false,\n      type: Array,\n      default: null\n    }\n  },\n  data() {\n    return {\n      loadingKey: 0,\n      tooltip: null\n    }\n  },\n  computed: {\n    pollInterval() {\n      return this.archived ? 0 : 60000\n    },\n    preppedFlowRuns() {\n      if (!this.flowRuns && !this.runs) return []\n\n      const computedStyle = getComputedStyle(document.documentElement)\n      const runs = this.runs || this.flowRuns\n      const prepped = runs\n        .filter(\n          run => run.flow_id == this.flowId || run.agent_id === this.agentId\n        )\n\n        .reverse()\n        .map(d => {\n          if (d.start_time && d.end_time) {\n            let end = new moment(d.end_time),\n              start = new moment(d.start_time)\n            d.duration = moment.duration(end.diff(start))\n          } else {\n            let now = new moment(),\n              start = new moment(d.start_time)\n            d.duration = moment.duration(now.diff(start))\n          }\n\n          d.color = computedStyle.getPropertyValue(`--v-${d.state}-base`)\n          d.opacity = 1\n          d.warningOpacity = 0\n          return d\n        })\n      return prepped\n    }\n  },\n  mounted() {\n    if (this.pollInterval > 0) {\n      this.$apollo.queries.flowRuns.startPolling(this.pollInterval)\n    }\n  },\n  methods: {\n    _barMouseout() {\n      this.tooltip = null\n    },\n    async _barMouseover(d) {\n      if (this.runs) {\n        try {\n          const { data } = await this.$apollo.query({\n            query: require('@/graphql/Dashboard/timeline-flow.gql'),\n            variables: {\n              flowId: d.data?.flow_id\n            }\n          })\n\n          d.data.flow = data.flow_by_pk\n        } catch (e) {\n          throw new Error(e)\n        }\n      }\n      if (d.data.end_time) {\n        d.data.display_end_time = this.formatTime(d.data.end_time)\n      }\n\n      if (d.data.start_time) {\n        d.data.display_start_time = this.formatTime(d.data.start_time)\n      }\n\n      if (d.data.scheduled_start_time) {\n        d.data.display_scheduled_start_time = this.formatTime(\n          d.data.scheduled_start_time\n        )\n      }\n      d.limited_view = !!this.runs\n      d.status_style = this.statusStyle(d.data.state)\n\n      this.tooltip = d\n    },\n    _barClick(d) {\n      this.$router.push({\n        name: 'flow-run',\n        params: {\n          id: d.id\n        }\n      })\n    },\n    formatTime(timestamp) {\n      if (!timestamp) throw new Error('Did not recieve a timestamp')\n\n      let t = moment(timestamp).tz(this.timezone),\n        shortenedTz = moment()\n          .tz(this.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone)\n          .zoneAbbr()\n\n      let timeObj = t ? t : moment(timestamp)\n\n      let formatted = timeObj.calendar(null, {\n        sameDay: 'h:mma',\n        sameElse: 'MMMM D, YYYY [at] h:mma'\n      })\n      return `${formatted} ${shortenedTz}`\n    },\n    statusStyle(state) {\n      return {\n        'border-radius': '50%',\n        display: 'inline-block',\n        'background-color': `var(--v-${state}-base)`,\n        height: '1rem',\n        width: '1rem'\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRuns.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRuns: {\n      query: require('@/graphql/Dashboard/last-flow-runs.gql'),\n      variables() {\n        return {\n          flowId: this.flowId || null\n        }\n      },\n      skip() {\n        return !!this.runs\n      },\n      loadingKey: 'loadingKey',\n      update: data => data?.flow_run\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <BarChart\n      v-intersect.once=\"onIntersect\"\n      :items=\"preppedFlowRuns\"\n      :loading=\"loadingKey > 0\"\n      :height=\"50\"\n      :min-bands=\"10\"\n      normalize\n      :padding=\"0\"\n      y-field=\"duration\"\n      @bar-click=\"_barClick\"\n      @bar-mouseout=\"_barMouseout\"\n      @bar-mouseover=\"_barMouseover\"\n    />\n\n    <div v-if=\"tooltip\" class=\"barchart-tooltip v-tooltip__content text-left\">\n      <TimelineTooltip :tooltip=\"tooltip\" />\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.barchart-tooltip {\n  left: 50%;\n  pointer-events: none;\n  position: absolute;\n  text-overflow: initial;\n  transform: translate(-50%);\n  user-select: none;\n  width: fit-content !important;\n  z-index: 10;\n}\n</style>\n"
  },
  {
    "path": "src/components/License/ChangePlanDialog.vue",
    "content": "<script>\nimport { mapGetters, mapActions, mapMutations } from 'vuex'\nimport Billing from '@/pages/TeamSettings/Account/Billing'\n\nexport default {\n  components: {\n    Billing\n  },\n  props: {\n    plan: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    return {\n      loading: false,\n      changePlanDialog: false,\n      alertMessage: '',\n      tempPlanName: null\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['license', 'hasPermission']),\n    existingCard() {\n      return this.tenant?.stripe_customer?.sources?.data[0]?.card\n    },\n    permissionsCheck() {\n      return this.hasPermission('create', 'license')\n    },\n    isSelfServe() {\n      return (\n        this.license?.terms?.plan === 'SELF_SERVE' ||\n        this.license?.terms?.is_self_serve\n      )\n    },\n    planName() {\n      return this.plan?.name\n    },\n    planCost() {\n      return this.plan?.price\n    },\n    additionalCost() {\n      return this.plan?.additionalCost\n    },\n    limit() {\n      return this.plan.taskRuns\n    },\n    disableChangePlan() {\n      const type = this.tempPlanName || this.license?.terms?.plan\n      const planName = type === 'STARTER_2021' ? 'FREE_2021' : type\n      return (\n        !this.permissionsCheck ||\n        !this.isSelfServe ||\n        this.plan.value === planName\n      )\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    ...mapActions('license', ['getLicense']),\n    ...mapMutations('license', ['setTempLicenseType']),\n    async changePlan() {\n      const planvalue =\n        this.plan.value === 'FREE_2021' && this.existingCard\n          ? 'STARTER_2021'\n          : this.plan.value\n      this.loading = true\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/License/create-usage-based-license.gql'),\n          variables: {\n            input: {\n              tenant_id: this.tenant.id,\n              plan_name: planvalue\n            }\n          }\n        })\n        if (data.create_usage_license.id) {\n          this.alertMessage = {\n            alertShow: true,\n            alertMessage: `You are now on the Prefect ${this.planName} plan`,\n            alertType: 'success'\n          }\n          this.setTempLicenseType(planvalue)\n          this.$emit('update', this.plan.value)\n          this.tempPlanName = planvalue\n        }\n      } catch (e) {\n        this.alertMessage = {\n          alertShow: true,\n          alertMessage:\n            'There was a problem updating your license.  Please try again or contact help@prefect.io',\n          alertType: 'error'\n        }\n      } finally {\n        this.setAlert(this.alertMessage)\n        this.loading = false\n        this.changePlanDialog = false\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-dialog v-model=\"changePlanDialog\" max-width=\"600\" min-height=\"500px\">\n    <template #activator=\"{ on: dialog }\">\n      <v-btn color=\"primary\" :disabled=\"disableChangePlan\" v-on=\"{ ...dialog }\">\n        Change Plan\n      </v-btn>\n    </template>\n\n    <v-card :loading=\"loading\">\n      <v-card-title class=\"grey--text text--darken-2\">\n        Change to the\n        <span class=\"primary--text px-1\"> Prefect {{ planName }}</span> Plan\n      </v-card-title>\n      <v-card-text>\n        <v-alert\n          v-if=\"!permissionsCheck & !loading\"\n          class=\"mx-auto mb-12\"\n          border=\"left\"\n          colored-border\n          elevation=\"2\"\n          type=\"warning\"\n          tile\n          icon=\"lock\"\n          max-width=\"540\"\n          >Only your team's administrators can modify these settings.\n        </v-alert>\n        <v-alert\n          v-else-if=\"!isSelfServe & !loading\"\n          class=\"mx-auto mb-12\"\n          border=\"left\"\n          colored-border\n          elevation=\"2\"\n          type=\"info\"\n          tile\n          icon=\"lock\"\n          max-width=\"540\"\n        >\n          To change your license terms, please\n          <a href=\"https://www.prefect.io/pricing#contact\" target=\"_blank\"\n            >contact our sales team</a\n          >\n        </v-alert>\n        <div v-else-if=\"existingCard && planCost\">\n          <i class=\"fas fa-credit-card\" />\n          Your card ending in\n          <span class=\"font-weight-bold\"> {{ existingCard.last4 }}</span>\n\n          will be charged\n          <span class=\"font-weight-bold \">${{ planCost }} </span> on a monthly\n          basis.\n        </div>\n        <div v-else-if=\"planCost && !existingCard\"> <Billing page=\"plan\"/></div>\n        <div v-if=\"!planCost && isSelfServe\">\n          This plan is free. If you want to run more than {{ limit }} task\n          runs/month you will need to add a credit card in the Team Account\n          page.\n        </div>\n      </v-card-text>\n      <v-card-actions class=\"py-4\">\n        <v-spacer />\n        <v-btn\n          v-if=\"isSelfServe && permissionsCheck\"\n          text\n          @click=\"changePlanDialog = false\"\n        >\n          Cancel\n        </v-btn>\n        <v-btn\n          v-if=\"isSelfServe && permissionsCheck\"\n          :loading=\"loading\"\n          color=\"primary\"\n          @click=\"changePlan\"\n        >\n          Confirm\n        </v-btn>\n      </v-card-actions>\n    </v-card>\n  </v-dialog>\n</template>\n\n<style>\n.theme--light.v-subheader {\n  color: #000;\n  font-weight: bold !important;\n}\n\n.checkbox-container {\n  margin-left: 30px;\n  margin-top: -20px;\n}\n/* stylelint-disable */\n.set-state .v-btn__loader {\n  color: #fff;\n}\n\n.card-title {\n  margin-left: -12px;\n  margin-top: -10px;\n  margin-bottom: 10px;\n}\n</style>\n"
  },
  {
    "path": "src/components/License/UpgradeAlert.vue",
    "content": "<script>\nimport ExternalLink from '@/components/ExternalLink'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    ExternalLink\n  },\n  computed: {\n    ...mapGetters('license', ['license']),\n    isSelfServe() {\n      return this.license?.terms?.is_self_serve\n    },\n    isUsageBased() {\n      return this.license?.terms?.is_usage_based\n    }\n  }\n}\n</script>\n\n<template>\n  <v-alert\n    class=\"mx-auto mt-4 alert\"\n    border=\"left\"\n    colored-border\n    elevation=\"2\"\n    type=\"info\"\n    tile\n    color=\"codePink\"\n    icon=\"auto_awesome\"\n  >\n    <v-row>\n      <v-col v-if=\"!isUsageBased\" cols=\"12\">\n        Pssst! We noticed you have a legacy license type. Prefect now has new\n        licenses that include\n        <span class=\"font-weight-bold\">more users</span> and\n        <span class=\"font-weight-bold\">fewer limits.</span>\n        <span v-if=\"!isSelfServe\" class=\"pl-2\"\n          ><ExternalLink\n            href=\"https://www.prefect.io/pricing#contact\"\n            target=\"_blank\"\n            >Contact us </ExternalLink\n          >to find out more!</span\n        >\n      </v-col>\n      <v-col v-else>\n        <span v-if=\"!isSelfServe\"\n          >If you'd like to change your plan or get access to cool new features\n          please\n          <a href=\"https://www.prefect.io/pricing#contact\" target=\"_blank\">\n            contact us!</a\n          >\n        </span>\n        <span v-else>\n          Upgrade your license to get access to cool new features!</span\n        >\n      </v-col>\n\n      <v-col v-if=\"isSelfServe\" cols=\"12\" lg=\"4\">\n        <router-link\n          :to=\"{ name: 'plan-comparison' }\"\n          style=\"text-decoration: none;\"\n        >\n          <v-btn outlined color=\"codePink\">\n            Find Out More\n          </v-btn>\n        </router-link>\n      </v-col>\n    </v-row>\n  </v-alert>\n</template>\n\n<style>\n/* stylelint-disable */\n.alert .v-alert__icon.v-icon {\n  padding-top: 24px;\n}\n</style>\n"
  },
  {
    "path": "src/components/LogsCard/DownloadMenu.vue",
    "content": "<script>\nimport jsBeautify from 'js-beautify'\n\nexport default {\n  props: {\n    logs: {\n      required: true,\n      type: Array\n    }\n  },\n  data() {\n    return {\n      downloadMenuOpen: false,\n      downloadType: null\n    }\n  },\n  methods: {\n    // Generate a CSV string based on the currently-rendered logs\n    createCsvFromLogs() {\n      return this.logs\n        .map(log => {\n          const dateTime = `${log.date},${log.time}`\n          return `${dateTime},${log.name},${log.level},\"${log.message}\"\\n`\n        })\n        .join('')\n    },\n    // Generate a JSON string based on the currently-rendered logs\n    createJsonFromLogs() {\n      return jsBeautify(\n        JSON.stringify(\n          this.logs.map(log => ({\n            date: log.date,\n            time: log.time,\n            level: log.level,\n            name: log.name,\n            message: log.message\n          }))\n        )\n      )\n    },\n    // Generate a plain old string based on the currently-rendered logs\n    // Used to create .txt files\n    createTextFromLogs() {\n      return this.logs\n        .map(log => {\n          const dateTime = `${log.date},${log.time}`\n          return `${dateTime}\\t${log.name}\\t${log.level}\\t${log.message}\\n`\n        })\n        .join('')\n    },\n    // Create a blob and initiate a logs download for the user, based on their download menu settings\n    downloadLogs() {\n      let logsContent, mimeType, fileExtension\n\n      switch (this.downloadType) {\n        case 'CSV':\n          logsContent = this.createCsvFromLogs()\n          mimeType = 'text/csv'\n          fileExtension = 'csv'\n          break\n        case 'JSON':\n          logsContent = this.createJsonFromLogs()\n          mimeType = 'application/json'\n          fileExtension = 'json'\n          break\n        case 'Text':\n          logsContent = this.createTextFromLogs()\n          mimeType = 'text/plain'\n          fileExtension = 'txt'\n          break\n        default:\n          throw new Error('Unexpected file type found when downloading logs')\n      }\n\n      const blob = new Blob([logsContent], { type: mimeType })\n      const link = document.createElement('a')\n      link.href = window.URL.createObjectURL(blob)\n      link.setAttribute('download', `logs.${fileExtension}`)\n      link.click()\n\n      this.downloadMenuOpen = false\n    }\n  }\n}\n</script>\n\n<template>\n  <v-menu\n    v-model=\"downloadMenuOpen\"\n    :close-on-content-click=\"false\"\n    bottom\n    left\n    offset-y\n    transition=\"slide-y-transition\"\n  >\n    <template #activator=\"{ on }\">\n      <v-btn color=\"utilGrayMid\" text small v-on=\"on\">\n        <v-icon>\n          cloud_download\n        </v-icon>\n      </v-btn>\n    </template>\n    <v-card class=\"download-menu-card\">\n      <v-card-subtitle>\n        Download the logs that are currently rendered on the page.\n      </v-card-subtitle>\n\n      <div class=\"px-4 pt-2\">\n        <v-form>\n          <v-select\n            v-model=\"downloadType\"\n            :items=\"['Text', 'CSV', 'JSON']\"\n            :menu-props=\"{\n              'offset-y': true,\n              transition: 'slide-y-transition'\n            }\"\n            outlined\n            dense\n            label=\"File type\"\n            required\n          ></v-select>\n        </v-form>\n      </div>\n\n      <v-card-actions>\n        <v-spacer></v-spacer>\n        <v-btn text @click=\"downloadMenuOpen = false\">Cancel</v-btn>\n        <v-btn\n          text\n          color=\"primary\"\n          :disabled=\"!downloadType\"\n          @click=\"downloadLogs\"\n        >\n          Download\n        </v-btn>\n      </v-card-actions>\n    </v-card>\n  </v-menu>\n</template>\n\n<style lang=\"scss\" scoped>\n.download-menu-card {\n  max-width: 300px;\n}\n</style>\n"
  },
  {
    "path": "src/components/LogsCard/FilterMenu.vue",
    "content": "<script>\nimport moment from 'moment-timezone'\nimport range from 'lodash/range'\n\n// A RegEx for checking 12-hour time formats\n// e.g. 1:14:18am, 11:23:34 PM\nconst TIME_FORMAT = /^((?:0?[1-9]|1[0-2]):[0-5]\\d:[0-5]\\d\\s*(a|A|p|P)(m|M)\\s*$)$/\n\nexport default {\n  props: {\n    menuOpen: {\n      required: true,\n      type: Boolean\n    },\n    logLevels: {\n      required: true,\n      type: Array\n    }\n  },\n  data() {\n    return {\n      open: this.menuOpen,\n      filterFormDatetimeError: null,\n      searchInput: '',\n      logLevelFilterInput: this.logLevels,\n\n      dateFromInput: null,\n      dateFromMenu: false,\n      timeFromInputAmPm: 'AM',\n      timeFromInputHr: '12',\n      timeFromInputMin: '00',\n      timeFromInputSec: '00',\n      timeFromMenu: false,\n      timeFromValid: true,\n\n      dateToInput: null,\n      dateToMenu: false,\n      timeToInputAmPm: moment().format('A'),\n      timeToInputHr: moment().format('hh'),\n      timeToInputMin: moment().format('mm'),\n      timeToInputSec: moment().format('ss'),\n      timeToMenu: false,\n      timeToValid: true\n    }\n  },\n  computed: {\n    timeFromInput() {\n      return (\n        `${this.timeFromInputHr}:` +\n        `${this.timeFromInputMin}:` +\n        `${this.timeFromInputSec} ${this.timeFromInputAmPm}`\n      )\n    },\n    timeToInput() {\n      return (\n        `${this.timeToInputHr}:` +\n        `${this.timeToInputMin}:` +\n        `${this.timeToInputSec} ${this.timeToInputAmPm}`\n      )\n    }\n  },\n  watch: {\n    menuOpen() {\n      this.open = this.menuOpen\n    },\n    open() {\n      if (this.open) {\n        this.$emit('open')\n      } else {\n        this.$emit('close')\n      }\n    }\n  },\n  methods: {\n    endDatePlaceholder() {\n      return moment().format('YYYY-MM-DD')\n    },\n    handleDateChange(fromOrTo) {\n      this.filterFormDatetimeError = null\n\n      if (fromOrTo === 'from') {\n        this.dateFromMenu = false\n      }\n\n      if (fromOrTo === 'to') {\n        this.dateToMenu = false\n      }\n    },\n    handleDateClear(fromOrTo) {\n      this.filterFormDatetimeError = null\n\n      if (fromOrTo === 'from') {\n        this.dateFromInput = null\n        this.timeFromInputHr = '12'\n        this.timeFromInputMin = '00'\n        this.timeFromInputSec = '00'\n        this.timeFromInputAmPm = 'AM'\n      }\n\n      if (fromOrTo === 'to') {\n        this.dateToInput = null\n        this.timeToInputHr = moment().format('hh')\n        this.timeToInputMin = moment().format('mm')\n        this.timeToInputSec = moment().format('ss')\n        this.timeToInputAmPm = moment().format('A')\n      }\n    },\n    handleFilter() {\n      this.filterFormDatetimeError = null\n\n      let startDateTime\n      let endDateTime\n\n      if (this.dateFromInput) {\n        let newTimeFrom = this.dateFromInput\n        if (this.timeFromInput && this.timeInputValid(this.timeFromInput)) {\n          newTimeFrom = `${newTimeFrom} ${this.timeFromInput}`\n        }\n        startDateTime = moment(newTimeFrom)\n      }\n\n      if (this.dateToInput) {\n        let newTimeTo = this.dateToInput\n        if (this.timeToInput && this.timeInputValid(this.timeToInput)) {\n          newTimeTo = `${newTimeTo} ${this.timeToInput}`\n        }\n        endDateTime = moment(newTimeTo)\n      }\n\n      if (startDateTime && endDateTime && startDateTime > endDateTime) {\n        this.filterFormDatetimeError = [\n          'Invalid date and time range. Please try again.'\n        ]\n        return\n      }\n\n      this.$emit('filter', {\n        searchInput: this.searchInput,\n        logLevelFilterInput: this.logLevelFilterInput,\n        startDateTime,\n        endDateTime\n      })\n\n      this.open = false\n    },\n    resetFilter() {\n      this.searchInput = ''\n      this.logLevelFilterInput = this.logLevels\n      this.handleDateClear('from')\n      this.handleDateClear('to')\n      this.handleFilter()\n    },\n    timeInputValid(time) {\n      return TIME_FORMAT.test(time)\n    },\n    // Create a array of consecutive numbers\n    // Add paddings to any single-digit numbers, so 1 becomes \"01\"\n    // Keep double-digit numbers as-is\n    timeRange(min, max) {\n      return range(min, max).map(val => {\n        if (val < 10) return `0${val}`\n        return val.toString()\n      })\n    }\n  }\n}\n</script>\n\n<template>\n  <v-menu\n    v-model=\"open\"\n    :close-on-content-click=\"false\"\n    bottom\n    left\n    offset-y\n    transition=\"slide-y-transition\"\n  >\n    <template #activator=\"{ on }\">\n      <v-btn color=\"utilGrayMid\" text small v-on=\"on\">\n        <v-icon>\n          filter_list\n        </v-icon>\n      </v-btn>\n    </template>\n    <v-card class=\"px-5 pt-3 filter-menu-card\">\n      <v-form>\n        <v-row dense>\n          <v-col cols=\"12\">\n            <v-text-field\n              v-model=\"searchInput\"\n              dense\n              outlined\n              label=\"Search logs by text\"\n              clearable\n            ></v-text-field>\n          </v-col>\n          <v-col cols=\"12\">\n            <v-select\n              v-model=\"logLevelFilterInput\"\n              :items=\"logLevels\"\n              :menu-props=\"{\n                'min-width': 200,\n                'offset-y': true,\n                transition: 'slide-y-transition'\n              }\"\n              multiple\n              chips\n              deletable-chips\n              small-chips\n              dense\n              outlined\n              label=\"Log level\"\n            ></v-select>\n          </v-col>\n          <v-col cols=\"12\" md=\"6\">\n            <v-menu\n              v-model=\"dateFromMenu\"\n              :close-on-content-click=\"false\"\n              max-width=\"290\"\n              offset-y\n            >\n              <template #activator=\"{ on }\">\n                <v-text-field\n                  :value=\"dateFromInput\"\n                  :error-messages=\"filterFormDatetimeError\"\n                  clearable\n                  label=\"Starting date\"\n                  readonly\n                  dense\n                  outlined\n                  placeholder=\"2017-03-23\"\n                  v-on=\"on\"\n                  @click:clear=\"handleDateClear('from')\"\n                ></v-text-field>\n              </template>\n              <v-date-picker\n                v-model=\"dateFromInput\"\n                no-title\n                @change=\"handleDateChange('from')\"\n              ></v-date-picker>\n            </v-menu>\n          </v-col>\n          <v-col cols=\"12\" md=\"6\" class=\"pt-0\">\n            <v-row v-if=\"dateFromInput\" dense>\n              <v-col cols=\"3\">\n                <v-autocomplete\n                  data-public\n                  v-model=\"timeFromInputHr\"\n                  class=\"ma-0\"\n                  dense\n                  outlined\n                  :append-icon=\"null\"\n                  hide-no-data\n                  hide-details\n                  label=\"Hour\"\n                  :items=\"timeRange(1, 13)\"\n                  :error=\"!!filterFormDatetimeError\"\n                ></v-autocomplete>\n              </v-col>\n              <v-col cols=\"3\">\n                <v-autocomplete\n                  data-public\n                  v-model=\"timeFromInputMin\"\n                  class=\"ma-0\"\n                  dense\n                  outlined\n                  :append-icon=\"null\"\n                  hide-no-data\n                  hide-details\n                  label=\"Minutes\"\n                  :items=\"timeRange(0, 60)\"\n                  :error=\"!!filterFormDatetimeError\"\n                ></v-autocomplete>\n              </v-col>\n              <v-col cols=\"3\">\n                <v-autocomplete\n                  data-public\n                  v-model=\"timeFromInputSec\"\n                  class=\"ma-0\"\n                  dense\n                  outlined\n                  :append-icon=\"null\"\n                  hide-no-data\n                  hide-details\n                  label=\"Seconds\"\n                  :items=\"timeRange(0, 60)\"\n                  :error=\"!!filterFormDatetimeError\"\n                ></v-autocomplete>\n              </v-col>\n              <v-col cols=\"3\">\n                <v-autocomplete\n                  data-public\n                  v-model=\"timeFromInputAmPm\"\n                  class=\"ma-0\"\n                  dense\n                  outlined\n                  :append-icon=\"null\"\n                  hide-no-data\n                  hide-details\n                  label=\"AM/PM\"\n                  :items=\"['AM', 'PM']\"\n                  :error=\"!!filterFormDatetimeError\"\n                ></v-autocomplete>\n              </v-col>\n            </v-row>\n          </v-col>\n          <v-col cols=\"12\" md=\"6\">\n            <v-menu\n              v-model=\"dateToMenu\"\n              :close-on-content-click=\"false\"\n              max-width=\"290\"\n              offset-y\n            >\n              <template #activator=\"{ on }\">\n                <v-text-field\n                  :error-messages=\"filterFormDatetimeError\"\n                  :placeholder=\"endDatePlaceholder()\"\n                  :value=\"dateToInput\"\n                  clearable\n                  label=\"Ending date\"\n                  readonly\n                  dense\n                  outlined\n                  v-on=\"on\"\n                  @click:clear=\"handleDateClear('to')\"\n                ></v-text-field>\n              </template>\n              <v-date-picker\n                v-model=\"dateToInput\"\n                no-title\n                @change=\"handleDateChange('to')\"\n              ></v-date-picker>\n            </v-menu>\n          </v-col>\n          <v-col cols=\"12\" md=\"6\" class=\"pt-0\">\n            <v-row v-if=\"dateToInput\" dense>\n              <v-col cols=\"3\">\n                <v-autocomplete\n                  data-public\n                  v-model=\"timeToInputHr\"\n                  class=\"ma-0\"\n                  dense\n                  outlined\n                  :append-icon=\"null\"\n                  hide-no-data\n                  hide-details\n                  label=\"Hour\"\n                  :items=\"timeRange(1, 13)\"\n                  :error=\"!!filterFormDatetimeError\"\n                ></v-autocomplete>\n              </v-col>\n              <v-col cols=\"3\">\n                <v-autocomplete\n                  data-public\n                  v-model=\"timeToInputMin\"\n                  class=\"ma-0\"\n                  dense\n                  outlined\n                  :append-icon=\"null\"\n                  hide-no-data\n                  hide-details\n                  label=\"Minutes\"\n                  :items=\"timeRange(0, 60)\"\n                  :error=\"!!filterFormDatetimeError\"\n                ></v-autocomplete>\n              </v-col>\n              <v-col cols=\"3\">\n                <v-autocomplete\n                  data-public\n                  v-model=\"timeToInputSec\"\n                  class=\"ma-0\"\n                  dense\n                  outlined\n                  :append-icon=\"null\"\n                  hide-no-data\n                  hide-details\n                  label=\"Seconds\"\n                  :items=\"timeRange(0, 60)\"\n                  :error=\"!!filterFormDatetimeError\"\n                ></v-autocomplete>\n              </v-col>\n              <v-col cols=\"3\">\n                <v-autocomplete\n                  data-public\n                  v-model=\"timeToInputAmPm\"\n                  class=\"ma-0\"\n                  dense\n                  outlined\n                  :append-icon=\"null\"\n                  hide-no-data\n                  hide-details\n                  label=\"AM/PM\"\n                  :items=\"['AM', 'PM']\"\n                  :error=\"!!filterFormDatetimeError\"\n                ></v-autocomplete>\n              </v-col>\n            </v-row>\n          </v-col>\n        </v-row>\n      </v-form>\n\n      <v-card-actions>\n        <v-spacer></v-spacer>\n        <v-btn text @click=\"open = false\">Close</v-btn>\n        <v-btn text @click=\"resetFilter\">\n          Reset\n        </v-btn>\n        <v-btn text color=\"primary\" @click=\"handleFilter\">\n          Apply\n        </v-btn>\n      </v-card-actions>\n    </v-card>\n  </v-menu>\n</template>\n\n<style scoped lang=\"scss\">\n.filter-menu-card {\n  max-width: 768px;\n  min-width: 300px;\n}\n</style>\n\n<style lang=\"scss\">\n.filter-menu-card {\n  .v-label.v-label--active {\n    background-color: var(--v-appForeground-base);\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/LogsCard/LogRow.vue",
    "content": "<script>\nimport { formatTime } from '@/mixins/formatTimeMixin'\nexport default {\n  mixins: [formatTime],\n  props: {\n    index: {\n      type: Number,\n      required: true\n    },\n    log: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    return {\n      linkCopied: false\n    }\n  },\n  computed: {\n    logLevelColorMapper() {\n      const vuetifyThemeColors = this.$vuetify.theme.themes.light\n\n      return {\n        CRITICAL: vuetifyThemeColors.error,\n        DEBUG: vuetifyThemeColors.secondaryGray,\n        ERROR: vuetifyThemeColors.error,\n        INFO: vuetifyThemeColors.info,\n        WARNING: vuetifyThemeColors.warning\n      }\n    },\n    source() {\n      return this.log?.name?.replace('prefect.', '')\n    }\n  },\n  mounted() {\n    this.emitRender()\n  },\n  updated() {\n    this.emitRender()\n  },\n  methods: {\n    copyLogLink() {\n      setTimeout(() => {\n        this.linkCopied = true\n        navigator.clipboard.writeText(\n          `${window.location.origin}${this.$route.path}?logs=&logId=${this.log.id}`\n        )\n\n        setTimeout(() => {\n          this.linkCopied = false\n        }, 3000)\n      }, 100) // Should match log-copy transition duration\n    },\n    // Let parent know if the rendered log's ID is equal to the log ID query param\n    emitRender() {\n      if (this.isQueriedLog()) {\n        this.$emit('query-log-rendered')\n      }\n    },\n    // Determine whether log's ID is equal to the log ID provided via query param\n    isQueriedLog() {\n      return this.log.id === this.$route.query.logId\n    },\n    // Determine the log-level color based on the passed-in log level (\"DEBUG\", \"ERROR\", etc)\n    logLevelColor(logLevel) {\n      return (\n        this.logLevelColorMapper[logLevel] ||\n        this.$vuetify.theme.themes.light.secondaryGray\n      )\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"log-row d-flex pr-12 justify-start align-center\"\n    :class=\"{\n      'log-row-color-1': !isQueriedLog() && index % 2 === 0,\n      'log-row-color-2': !isQueriedLog() && index % 2 !== 0,\n      'log-row-color-queried': isQueriedLog()\n    }\"\n    tabindex=\"0\"\n  >\n    <div class=\"log-actions\">\n      <div class=\"log-link\">\n        <v-tooltip right>\n          <template #activator=\"{ on }\">\n            <v-btn\n              color=\"blue-grey lighten-1\"\n              text\n              x-small\n              @click=\"copyLogLink\"\n              v-on=\"on\"\n            >\n              <transition name=\"log-copy\" mode=\"out-in\">\n                <v-icon v-if=\"linkCopied\" key=\"copied\">check</v-icon>\n                <v-icon v-else key=\"not-copied\">link</v-icon>\n              </transition>\n            </v-btn>\n          </template>\n          <span>\n            {{ linkCopied ? 'Copied!' : 'Copy log URL to clipboard' }}\n          </span>\n        </v-tooltip>\n      </div>\n    </div>\n\n    <div class=\"log-info text-caption py-2 text-left\">\n      <v-tooltip top>\n        <template #activator=\"{ on }\">\n          <div class=\"log-datetime utilGrayMid--text\" v-on=\"on\">\n            {{ logTime(log.timestamp) }}\n          </div>\n        </template>\n        <span>{{ logDate(log.timestamp) }}</span>\n      </v-tooltip>\n      <div class=\"log-level d-flex align-center justify-start\">\n        <v-icon :color=\"logLevelColor(log.level)\" x-small>lens</v-icon>\n        <span class=\"text-truncate ml-1 text-small-caps\">{{ log.level }}</span>\n      </div>\n      <div class=\"log-name text-caption font-weight-light\">\n        <span class=\"text-truncate\">{{ source }}</span>\n      </div>\n    </div>\n\n    <div class=\"ml-10 py-1\">\n      <span class=\"log-message\">{{ log.message }}</span>\n    </div>\n\n    <div v-if=\"log.task_run_id\" class=\"justify-self-end log-router-link\">\n      <v-tooltip top>\n        <template #activator=\"{ on }\">\n          <v-btn\n            class=\"log-router-button vertical-button\"\n            color=\"blue-grey lighten-1\"\n            small\n            text\n            tile\n            :to=\"{\n              name: 'task-run',\n              params: {\n                id: log.task_run_id\n              }\n            }\"\n            v-on=\"on\"\n          >\n            <v-icon>chevron_right</v-icon>\n            To Task Run\n          </v-btn>\n        </template>\n        <span>\n          Navigate to the task run associated with this log\n        </span>\n      </v-tooltip>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.log-copy-enter-active,\n.log-copy-leave-active {\n  transition: opacity 100ms;\n}\n\n.log-copy-enter,\n.log-copy-leave-to {\n  opacity: 0;\n}\n\n.log-router-link {\n  height: 100%;\n  position: absolute;\n  right: 0;\n\n  a {\n    height: 100% !important;\n  }\n}\n\n.log-link,\n.log-router-link {\n  opacity: 0;\n\n  &:focus,\n  &:hover {\n    opacity: 1;\n  }\n}\n\n.log-row {\n  position: relative;\n\n  /* stylelint-disable a11y/selector-pseudo-class-focus */\n  &:hover {\n    .log-link,\n    .log-router-link {\n      opacity: 1;\n    }\n  }\n\n  &:focus {\n    z-index: 10;\n  }\n  /* stylelint-enable a11y/selector-pseudo-class-focus */\n}\n\n.log-info {\n  display: block;\n  width: 100px;\n}\n\n.log-row-color-1 {\n  background-color: var(--v-appForeground-base);\n}\n\n.log-row-color-2 {\n  background-color: var(--v-appBackground-base);\n}\n\n.log-row-color-queried {\n  background-color: var(--v-primaryLight-base);\n}\n\n.log-message {\n  font-family: 'Source Code Pro', monospace;\n  white-space: pre-wrap; // Needed to format log messages properly\n}\n</style>\n"
  },
  {
    "path": "src/components/LogsCard/LogsCard.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\n\nimport { mapGetters } from 'vuex'\nimport moment from 'moment-timezone'\nimport vueScrollTo from 'vue-scrollto'\n\nimport store from '@/store'\nimport { STATE_TYPES } from '@/utils/states'\nimport DownloadMenu from './DownloadMenu'\nimport FilterMenu from './FilterMenu'\nimport LogRow from './LogRow'\n\nconst DEFAULT_LIMIT = 100\nconst LOG_LEVELS = ['CRITICAL', 'DEBUG', 'ERROR', 'INFO', 'WARNING']\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i\n\nexport default {\n  components: {\n    DownloadMenu,\n    FilterMenu,\n    LogRow\n  },\n  props: {\n    // Set whether the logs are for a flow or a task\n    entity: {\n      default: 'flow',\n      required: false,\n      type: String,\n      validator: value => ['flow', 'task'].includes(value)\n    },\n    // The GraphQL query that will be used to fetch the logs\n    // Use the schema at \"src/graphql/Logs/flow-run-logs.gql\" as a reference\n    query: {\n      required: true,\n      type: Object\n    },\n    // A special GraphQL query that's used to fetch the logs *around* a given log\n    // Use the schema at \"src/graphql/Logs/flow-run-logs-scoping.gql\" as a reference\n    queryForScoping: {\n      required: false,\n      type: Object,\n      default: null\n    },\n    // The key that should be access in GraphQL data results to extract logs\n    queryKey: {\n      required: false,\n      type: String,\n      default: 'flow_run_by_pk'\n    },\n    // Determine whether or not to show filter descriptions at the top of the logs card\n    showFilterDescription: {\n      default: true,\n      required: false,\n      type: Boolean\n    },\n    // Any variables that should be passed into the logs GraphQL query\n    variables: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      // Stored GraphQL query results\n      // Logs to render on the page\n      logsQueryResults: null,\n      // Older & newer logs used for pagiation purposes\n      logsQueryResultsOlder: null,\n      logsQueryResultsNewer: null,\n      // Information about a specific log whose ID is provided via the logId query param\n      logsQueryResultsTarget: null,\n      // Specialized query to get a certain amount of logs *around* a target log\n      logsQueryResultsScoping: null,\n\n      // GraphQL query variables\n      // Any updates to these values will automatically update logsQueryResults, logsQueryResultsOlder, and logsQueryResultsNewer\n      limit: DEFAULT_LIMIT,\n      logLevelFilter: LOG_LEVELS,\n      offset: 0,\n      searchText: '',\n      timestampFrom: null,\n      timestampTo: null,\n\n      // All possible log levels\n      logLevels: LOG_LEVELS,\n\n      // Filtering\n      filterMenuOpen: false,\n\n      // Show loader when logs are being fetched\n      loadingOnStart: true,\n\n      // User-set value that determines whether or not logs should be tailed during a run\n      isTailingLogs: true,\n\n      // Initiate scroll to a specific log, provided that a log ID is provided as a query param\n      scrolledToQueryLog: false,\n\n      // Archived logs props\n      failedToRetrieveArchivedLogs: false,\n      retrievingArchivedLogs: false\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    // Derive the state of the flow or task\n    entityState() {\n      if (!this.logsQueryResults) return 'Fetching logs'\n      return this.logsQueryResults.state\n    },\n    // Derive whether or not the flow/task is in a non-finished state\n    entityIsRunning() {\n      return (\n        this.entityState === 'Fetching logs' ||\n        STATE_TYPES[this.entityState] !== 'Finished'\n      )\n    },\n    // Determine whether user has filtered logs\n    isFiltered() {\n      return (\n        this.searchText ||\n        this.timestampFrom ||\n        this.timestampTo ||\n        this.logLevelFilter.length < this.logLevels.length\n      )\n    },\n    // The number of logs rendered on the page\n    logCount() {\n      if (!this.logsQueryResults) return\n\n      return this.logsQueryResults.logs.length\n    },\n    // Derive the list of logs from the GraphQL query\n    logs() {\n      if (!this.logsQueryResults) return\n      return this.logsQueryResults.logs\n        .slice()\n        .reverse()\n        .map(log => ({\n          ...log,\n          date: this.logDate(log.timestamp),\n          time: this.logTime(log.timestamp),\n          timestamp: moment(log.timestamp).format()\n        }))\n    },\n    // Filter description text that tells the user what filters are currently applied to their logs\n    // Example: \"Showing 3 logs for all log levels from the beginning of time to now.\"\n    logsFilterDescription() {\n      let logLevelsMessage\n\n      if (this.logLevelFilter.length === 5) {\n        logLevelsMessage = 'for <b>all log levels</b>'\n      } else if (this.logLevelFilter.length === 0) {\n        logLevelsMessage = 'for <b>no log levels</b>'\n      } else {\n        logLevelsMessage = `for <b>log levels ${this.sententifyLogLevels()}</b>`\n      }\n\n      const searchText = this.searchText\n        ? ` with text <b>\"${this.searchText}\"</b>`\n        : ''\n\n      const timestampFrom = this.timestampFrom\n        ? `${this.logDate(this.timestampFrom)} ${this.logTime(\n            this.timestampFrom\n          )}`\n        : 'the beginning of time'\n\n      const timestampTo = this.timestampTo\n        ? `${this.logDate(this.timestampTo)} ${this.logTime(this.timestampTo)}`\n        : 'now'\n\n      return `\n        Showing logs ${searchText} ${logLevelsMessage}\n        from <b>${timestampFrom}</b> to <b>${timestampTo}</b>.\n      `\n    }\n  },\n  watch: {\n    logsQueryResults() {\n      if (!this.logsQueryResults) return\n\n      // Set the loading state to false once Apollo fetches log data\n      this.loadingOnStart = false\n\n      if (this.scrolledToQueryLog || !this.logsQueryResultsTarget) return\n\n      this.scopeLogs()\n    },\n    logsQueryResultsTarget() {\n      if (!this.logsQueryResultsTarget || !this.logsQueryResults) return\n\n      this.scopeLogs()\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.logsQueryResults.skip = !entry.isIntersecting\n      this.$apollo.queries.logsQueryResultsOlder.skip = !entry.isIntersecting\n      this.$apollo.queries.logsQueryResultsNewer.skip = !entry.isIntersecting\n    }\n  },\n  created() {\n    this.$apollo.addSmartQuery('logsQueryResults', {\n      query: this.query,\n      variables() {\n        return {\n          ...this.variables,\n          limit: this.limit,\n          offset: this.offset,\n          levels: this.logLevelFilter,\n          searchText: this.searchText ? `%${this.searchText}%` : null,\n          timestampFrom: this.timestampFrom,\n          timestampTo: this.timestampTo\n        }\n      },\n      pollInterval: 5000,\n      update(data) {\n        if (\n          this.retrievingArchivedLogs &&\n          data[this.queryKey]?.logs?.length > 0\n        ) {\n          this.retrievingArchivedLogs = false\n        }\n        return data[this.queryKey]\n      }\n    })\n\n    this.$apollo.addSmartQuery('logsQueryResultsOlder', {\n      query: this.query,\n      variables() {\n        return {\n          ...this.variables,\n          limit: this.limit,\n          offset: this.offset + this.limit,\n          levels: this.logLevelFilter,\n          searchText: this.searchText ? `%${this.searchText}%` : null,\n          timestampFrom: this.timestampFrom,\n          timestampTo: this.timestampTo\n        }\n      },\n      pollInterval: 5000,\n      update(data) {\n        if (\n          this.retrievingArchivedLogs &&\n          data[this.queryKey]?.logs?.length > 0\n        ) {\n          this.retrievingArchivedLogs = false\n        }\n        return data[this.queryKey]\n      }\n    })\n\n    this.$apollo.addSmartQuery('logsQueryResultsNewer', {\n      query: this.query,\n      variables() {\n        return {\n          ...this.variables,\n          limit: this.limit,\n          offset:\n            this.offset - this.limit < 0\n              ? this.offset\n              : this.offset - this.limit,\n          levels: this.logLevelFilter,\n          searchText: this.searchText ? `%${this.searchText}%` : null,\n          timestampFrom: this.timestampFrom,\n          timestampTo: this.timestampTo\n        }\n      },\n      pollInterval: 5000,\n      update(data) {\n        if (\n          this.retrievingArchivedLogs &&\n          data[this.queryKey]?.logs?.length > 0\n        ) {\n          this.retrievingArchivedLogs = false\n        }\n        return data[this.queryKey]\n      }\n    })\n\n    if (!this.$route.query.logId) return\n    if (!UUID_REGEX.test(this.$route.query.logId)) return\n\n    this.$apollo.addSmartQuery('logsQueryResultsTarget', {\n      query: this.query,\n      variables() {\n        return {\n          ...this.variables,\n          logId: this.$route.query.logId\n        }\n      },\n      update(data) {\n        if (\n          this.retrievingArchivedLogs &&\n          data[this.queryKey]?.logs?.length > 0\n        ) {\n          this.retrievingArchivedLogs = false\n        }\n        return data[this.queryKey]\n      }\n    })\n  },\n  updated() {\n    // Tail logs\n    if (this.entityIsRunning && this.isTailingLogs) {\n      this.scrollToEnd()\n    }\n  },\n  methods: {\n    // Remove the logId query param\n    clearLogIdQuery() {\n      this.$router.replace({\n        query: { logId: undefined }\n      })\n    },\n    async retrieveArchivedLogs() {\n      this.failedToRetrieveArchivedLogs = false\n      this.retrievingArchivedLogs = true\n      let flowRunId =\n        this.entity == 'task'\n          ? this.logsQueryResults.flow_run_id\n          : this.logsQueryResults.id\n      let dates = [\n        this.logsQueryResults.start_time,\n        moment(this.logsQueryResults.start_time).add(1, 'days')\n      ]\n      dates.forEach(async archiveDate => {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Logs/retrieve-archived-logs.gql'),\n          variables: {\n            flowRunId: flowRunId,\n            timestamp: archiveDate\n          },\n          errorPolicy: 'all'\n        })\n      })\n\n      await this.$apollo.queries.logsQueryResults?.refetch()\n      await this.$apollo.queries.logsQueryResultsOlder?.refetch()\n      await this.$apollo.queries.logsQueryResultsNewer?.refetch()\n      await this.$apollo.queries.logsQueryResultsTarget?.refetch()\n\n      setTimeout(() => {\n        // If we still haven't found any logs after 30 seconds\n        // we display a message about that\n        if (this.retrievingArchivedLogs) {\n          this.retrievingArchivedLogs = false\n          this.failedToRetrieveArchivedLogs = true\n        }\n      }, 30000)\n    },\n    // Apply any filters that the user sets\n    handleFilter(filterResult) {\n      this.limit = DEFAULT_LIMIT\n      this.offset = 0\n      this.searchText = filterResult.searchInput\n      this.logLevelFilter = filterResult.logLevelFilterInput\n      this.timestampFrom = filterResult.startDateTime\n      this.timestampTo = filterResult.endDateTime\n\n      this.filterMenuOpen = false\n    },\n    handleQueryLogScroll() {\n      if (!this.shouldScrollToLog()) return\n\n      this.scrolledToQueryLog = true\n      setTimeout(() => {\n        this.scrollToLog(this.$route.query.logId)\n      }, 1500)\n    },\n    // Fetch a batch of newer logs\n    // For pagaination\n    loadNewerLogs() {\n      if (this.offset - DEFAULT_LIMIT < 0) {\n        this.limit = this.logCount - (this.logCount - this.offset)\n        this.offset = 0\n      } else {\n        this.offset -= DEFAULT_LIMIT\n      }\n    },\n    // Fetch a batch of older logs\n    // For pagination\n    loadOlderLogs() {\n      this.offset += this.limit\n\n      if (this.limit < DEFAULT_LIMIT) {\n        this.limit = DEFAULT_LIMIT\n      }\n    },\n\n    // Format the log entry's date based on the datetime timestamp\n    logDate(datetime) {\n      let dt = moment(datetime)\n\n      if (store.getters['user/timezone']) {\n        dt = dt.tz(store.getters['user/timezone'])\n      }\n\n      return dt.format('D MMMM YYYY')\n    },\n    // Format a log entry's time based on the datetime timestamp\n    logTime(datetime) {\n      let dt = moment(datetime)\n\n      if (store.getters['user/timezone']) {\n        dt = dt.tz(store.getters['user/timezone'])\n      }\n\n      return dt.format('hh:mm:ss z')\n    },\n    // Reset GraphQL query variables to their defaults\n    resetQueryVars() {\n      this.limit = DEFAULT_LIMIT\n      this.logLevelFilter = LOG_LEVELS\n      this.offset = 0\n      this.searchText = ''\n      this.timestampFrom = null\n      this.timestampTo = null\n\n      // Initiate reset on FilterMenu child\n      if (this.$refs.filterMenu) {\n        this.$refs.filterMenu.resetFilter()\n      }\n    },\n    // Scroll to the bottom of the logs, for tailing purposes\n    scrollToEnd() {\n      const scrollEndElement = document.getElementById('scroll-end')\n      if (!scrollEndElement) return\n\n      vueScrollTo.scrollTo(scrollEndElement, 750, {\n        container: '.logs-list',\n        easing: 'ease-in',\n        force: false,\n        offset: -90\n      })\n    },\n    // Scroll to a specific log entry\n    scrollToLog(logId) {\n      const logElement = this.$refs[`log-${logId}`]\n      if (!logElement) return\n\n      vueScrollTo.scrollTo(logElement[0].$el, 750, {\n        container: '.logs-list',\n        easing: 'ease-in',\n        force: false,\n        offset: -90,\n        onDone: function(el) {\n          el.focus()\n        }\n      })\n    },\n    // Create a phrase from the currently-set log levels\n    // e.g. CRITICAL, DEBUG, and INFO\n    sententifyLogLevels() {\n      const words = this.logLevelFilter.slice()\n\n      if (words.length === 1) {\n        return words[0]\n      } else if (words.length === 2) {\n        return `${words[0]} and ${words[1]}`\n      } else {\n        words[words.length - 1] = `and ${words[words.length - 1]}`\n        return words.join(', ')\n      }\n    },\n    // Determine whether or not to scroll to a specific log\n    shouldScrollToLog() {\n      // Scroll to a specific log if...\n      return (\n        // the scroll hasn't happened yet,\n        !this.scrolledToQueryLog &&\n        // and an ID for the target log was provided as a query parameter,\n        this.$route.query.logId\n      )\n    },\n    // Show the logs surrounding a log whose ID was provided via query param\n    scopeLogs() {\n      if (!this.queryForScoping) return\n      if (this.logs.length < DEFAULT_LIMIT) return\n\n      const logTime = moment(\n        this.logsQueryResultsTarget.logs[0].timestamp\n      ).format()\n\n      this.$apollo.addSmartQuery('logsQueryResultsScoping', {\n        query: this.queryForScoping,\n        variables() {\n          return {\n            ...this.variables,\n            limit: DEFAULT_LIMIT / 2,\n            timestamp: logTime\n          }\n        },\n        result(res) {\n          if (\n            res.errors ||\n            !this.$route.query.logId ||\n            !res.data?.flow_run_by_pk\n          )\n            return\n\n          const logsAfter = res.data.flow_run_by_pk.logs_after\n          const logsBefore = res.data.flow_run_by_pk.logs_before\n\n          if (logsAfter && logsAfter.length > 0) {\n            this.timestampTo = logsAfter[logsAfter.length - 1].timestamp\n          }\n\n          if (logsBefore && logsBefore.length > 0) {\n            this.timestampFrom = logsBefore[logsBefore.length - 1].timestamp\n          }\n        },\n        update: data => data[this.queryKey]\n      })\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-intersect=\"{ handler: onIntersect }\" data-private>\n    <v-card class=\"logs-card\" tile>\n      <v-system-bar :color=\"entityState\" :height=\"5\" absolute>\n        <!-- We should include a state icon here when we've got those -->\n        <!-- <v-icon>{{ flow.flow_runs[0].state }}</v-icon> -->\n      </v-system-bar>\n\n      <v-toolbar class=\"mb-0 logs-card-title\" elevation=\"4\">\n        <div v-if=\"showFilterDescription\" v-html=\"logsFilterDescription\"> </div>\n\n        <v-spacer></v-spacer>\n        <v-toolbar-items>\n          <span v-if=\"$route.query.logId\" class=\"toolbar-text\">\n            <a href=\"#\" @click.prevent=\"clearLogIdQuery\">\n              Clear log query\n            </a>\n          </span>\n          <span v-if=\"isFiltered\" class=\"toolbar-text ml-4\">\n            <a href=\"#\" @click.prevent=\"resetQueryVars\">\n              Clear filters\n            </a>\n          </span>\n          <span class=\"state-indicator px-4\">\n            <span>\n              <v-tooltip v-if=\"entityState\" bottom>\n                <template #activator=\"{ on }\">\n                  <v-icon\n                    class=\"state-indicator-icon\"\n                    :class=\"{ 'fade-in-out': entityIsRunning }\"\n                    :color=\"entityState\"\n                    v-on=\"on\"\n                  >\n                    brightness_1\n                  </v-icon>\n                </template>\n                <span>\n                  {{ entity.toUpperCase() }} RUN STATE:\n                  {{ entityState.toUpperCase(0) }}</span\n                >\n              </v-tooltip>\n            </span>\n          </span>\n\n          <DownloadMenu v-if=\"logs\" :logs=\"logs\"></DownloadMenu>\n\n          <FilterMenu\n            ref=\"filterMenu\"\n            :menu-open=\"filterMenuOpen\"\n            :log-levels=\"logLevels\"\n            @filter=\"handleFilter\"\n            @open=\"filterMenuOpen = true\"\n            @close=\"filterMenuOpen = false\"\n          ></FilterMenu>\n        </v-toolbar-items>\n      </v-toolbar>\n\n      <v-card-text v-if=\"loadingOnStart\" class=\"bg-white loading-logs-progress\">\n        <v-progress-circular\n          indeterminate\n          color=\"primary\"\n        ></v-progress-circular>\n      </v-card-text>\n\n      <v-card-text\n        v-else-if=\"logs && logs.length > 0\"\n        class=\"logs-list px-0 pt-0 pb-3\"\n        tabindex=\"0\"\n      >\n        <v-btn\n          v-if=\"logsQueryResultsOlder && logsQueryResultsOlder.logs.length > 0\"\n          x-small\n          text\n          class=\"ma-0 pa-0 load-logs-pagination load-logs-border-bottom\"\n          @click=\"loadOlderLogs\"\n        >\n          Load older logs\n        </v-btn>\n        <LogRow\n          v-for=\"(log, index) in logs\"\n          :key=\"index\"\n          :ref=\"`log-${log.id}`\"\n          :index=\"index\"\n          :log=\"log\"\n          @query-log-rendered=\"handleQueryLogScroll\"\n        >\n        </LogRow>\n        <v-btn\n          v-if=\"offset > 0\"\n          x-small\n          text\n          class=\"ma-0 pa-0 load-logs-pagination load-logs-border-top\"\n          @click=\"loadNewerLogs\"\n        >\n          Load newer logs\n        </v-btn>\n        <div\n          v-else-if=\"entityIsRunning\"\n          class=\"pa-3 running-indicator bg-white\"\n        >\n          <v-progress-linear indeterminate color=\"primary\"></v-progress-linear>\n        </div>\n        <div id=\"scroll-end\"></div>\n      </v-card-text>\n\n      <v-card-text\n        v-else-if=\"entityIsRunning || retrievingArchivedLogs\"\n        class=\"bg-white\"\n      >\n        <div class=\"mb-3\">\n          {{\n            retrievingArchivedLogs\n              ? 'Retrieving archived logs from glacial storage...'\n              : entityState\n          }}...\n        </div>\n        <v-progress-linear indeterminate color=\"primary\"></v-progress-linear>\n      </v-card-text>\n\n      <v-card-text v-else class=\"bg-white no-logs-found\">\n        {{\n          failedToRetrieveArchivedLogs\n            ? \"Sorry, we couldn't get the logs from glacial storage...\"\n            : entityIsRunning\n            ? `${entityState}...`\n            : 'No logs found.'\n        }}\n        <span\n          v-if=\"logCount === 0 && !failedToRetrieveArchivedLogs\"\n          class=\"ma-0\"\n        >\n          Try\n          <a href=\"#\" @click.prevent=\"filterMenuOpen = true\">expanding</a>\n          or\n          <a href=\"#\" @click.prevent=\"resetQueryVars\">resetting</a> your search.\n        </span>\n        <span v-if=\"failedToRetrieveArchivedLogs\">\n          <a @click=\"retrieveArchivedLogs\"><u>Retry?</u></a>\n        </span>\n        <span v-else-if=\"logCount === 0 && isCloud\" class=\"ma-0\">\n          <br />\n          <br />\n          <a @click=\"retrieveArchivedLogs\"><u>Click here</u></a> to retrieve\n          archived logs - please allow up to 30 seconds for the retrieval to\n          take effect.\n        </span>\n      </v-card-text>\n\n      <v-tooltip\n        v-if=\"entityIsRunning && logs && logs.length > 0\"\n        left\n        open-delay=\"400\"\n        transition=\"fade-transition\"\n      >\n        <template #activator=\"{ on }\">\n          <v-btn\n            :color=\"isTailingLogs ? 'primary' : 'secondaryGrayLight'\"\n            :class=\"{ 'white--text': isTailingLogs }\"\n            class=\"tail-logs-button\"\n            small\n            @click=\"isTailingLogs = !isTailingLogs\"\n            v-on=\"on\"\n          >\n            <v-icon class=\"mr-2\">offline_bolt</v-icon>\n            Live\n          </v-btn>\n        </template>\n        <span>\n          Show the most recent logs while the {{ entity }} is running.\n        </span>\n      </v-tooltip>\n\n      <div\n        v-if=\"!entityIsRunning && logs && logs.length > 0\"\n        class=\"pa-0 logs-footer\"\n      ></div>\n    </v-card>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.bg-white {\n  background-color: var(--v-appForeground-base);\n}\n\n.date-picker {\n  box-shadow: none;\n}\n\n.fade-in-out {\n  animation: fade-oscillate 0.8s infinite alternate;\n}\n\n.toolbar-text {\n  font-size: 0.9em;\n\n  @media only screen and (min-width: 960px) {\n    line-height: 64px;\n  }\n\n  @media only screen and (max-width: 959px) {\n    line-height: 54px;\n  }\n}\n\n.load-logs-border-bottom {\n  border-bottom: 1px solid var(--v-secondaryGrayLight-base);\n}\n\n.load-logs-border-top {\n  border-top: 1px solid var(--v-secondaryGrayLight-base);\n}\n\n.load-logs-pagination {\n  background-color: var(--v-appForeground-base);\n  border-radius: 0;\n  height: 100%;\n  width: 100%;\n}\n\n.loading-logs-progress {\n  display: flex;\n  flex-flow: row wrap;\n  justify-content: center;\n}\n\n.logs-card {\n  background-color: transparent;\n  position: relative;\n}\n\n.logs-card-title {\n  position: relative;\n  z-index: 1;\n}\n\n.logs-footer {\n  background-image: linear-gradient(\n    transparent,\n    60%,\n    var(--v-utilGrayLight-base)\n  );\n  height: 12px !important;\n  position: relative;\n  top: -12px;\n}\n\n.logs-list {\n  max-height: 62vh;\n  overflow: auto;\n  position: relative;\n}\n\n.no-logs-found {\n  font-family: 'Source Code Pro', monospace;\n}\n\n.running-indicator {\n  font-family: 'Source Code Pro', monospace;\n}\n\n.state-indicator {\n  font-size: 0.9em;\n\n  @media only screen and (min-width: 960px) {\n    line-height: 64px;\n  }\n\n  @media only screen and (max-width: 959px) {\n    line-height: 54px;\n  }\n}\n\n.state-indicator-icon {\n  border: 1px solid var(--v-secondaryGray-base);\n  border-radius: 50%;\n}\n\n.tail-logs-button {\n  bottom: 8px;\n  position: absolute;\n  right: 8px;\n  z-index: 10;\n}\n\n@keyframes fade-oscillate {\n  from {\n    opacity: 0;\n  }\n\n  to {\n    opacity: 100%;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/MenuTooltip.vue",
    "content": "<script>\nexport default {\n  props: {\n    content: {\n      type: String,\n      required: false,\n      default: null\n    },\n    hideClose: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    icon: {\n      type: String,\n      required: false,\n      default: 'far fa-info-circle'\n    },\n    iconClass: {\n      type: [String, Object, Array],\n      required: false,\n      default: null\n    },\n    iconColor: {\n      type: String,\n      required: false,\n      default: null\n    },\n    maxWidth: {\n      type: [String, Number],\n      required: false,\n      default: '320px'\n    },\n    nudgeBottom: {\n      type: String,\n      required: false,\n      default: null\n    },\n    nudgeLeft: {\n      type: String,\n      required: false,\n      default: null\n    },\n    nudgeRight: {\n      type: String,\n      required: false,\n      default: null\n    },\n    nudgeTop: {\n      type: String,\n      required: false,\n      default: null\n    },\n    offsetX: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    offsetY: {\n      type: Boolean,\n      required: false,\n      default: true\n    },\n    top: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    transition: {\n      type: String,\n      required: false,\n      default: null\n    }\n  },\n  data() {\n    return {\n      open: false\n    }\n  }\n}\n</script>\n\n<template>\n  <v-menu\n    v-model=\"open\"\n    :offset-y=\"offsetY\"\n    :offset-x=\"offsetX\"\n    :close-on-content-click=\"false\"\n    :top=\"top\"\n    :nudge-bottom=\"nudgeBottom\"\n    :nudge-top=\"nudgeTop\"\n    :nudge-left=\"nudgeLeft\"\n    :nudge-right=\"nudgeRight\"\n    :max-width=\"maxWidth\"\n    open-on-hover\n    tile\n    :transition=\"transition\"\n    class=\"elevation-1\"\n  >\n    <template #activator=\"{ on }\">\n      <span v-on=\"on\">\n        <slot name=\"activator\">\n          <div class=\"d-inline-flex align-start\" :class=\"iconClass\">\n            <v-icon :color=\"iconColor\" x-small @focus=\"open = true\">\n              {{ icon }}\n            </v-icon>\n          </div>\n        </slot>\n      </span>\n    </template>\n    <v-card tile class=\"pa-0\">\n      <v-card-text class=\"pa-4 text-body-2\">\n        <slot>\n          {{ content }}\n        </slot>\n      </v-card-text>\n      <v-card-actions\n        v-if=\"!hideClose\"\n        class=\"pa-2 flex-row-reverse justify-space-between\"\n      >\n        <v-btn\n          class=\"text-none\"\n          color=\"primary\"\n          small\n          text\n          @click=\"open = false\"\n          >Close</v-btn\n        >\n        <slot name=\"actions\" />\n      </v-card-actions>\n    </v-card>\n  </v-menu>\n</template>\n"
  },
  {
    "path": "src/components/Nav/ApplicationNav.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport ConnectionMenu from '@/components/Nav/ConnectionMenu'\nimport GlobalSearch from '@/components/GlobalSearchBar/GlobalSearch'\nimport HelpMenu from '@/components/Nav/HelpMenu'\nimport NotificationMenu from '@/components/Nav/NotificationMenu'\nimport Links from '@/components/Nav/Links'\nimport TeamSideNavButton from '@/components/Nav/TeamSideNavButton'\nimport UserMenu from '@/components/Nav/UserMenu'\nimport ChatLauncher from '@/components/Nav/ChatLauncher'\n\nexport default {\n  components: {\n    ConnectionMenu,\n    GlobalSearch,\n    HelpMenu,\n    Links,\n    NotificationMenu,\n    TeamSideNavButton,\n    UserMenu,\n    ChatLauncher\n  },\n  data() {\n    return {\n      active: false,\n      menu: false\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud', 'isServer']),\n    ...mapGetters('auth', ['isAuthenticated', 'isAuthorized']),\n    ...mapGetters('tenant', ['tenant']),\n    isTransparent() {\n      return this.$route.name === 'not-found'\n    },\n    isWelcome() {\n      return (\n        this.$route.name === 'welcome' ||\n        this.$route.name === 'onboard-resources' ||\n        this.$route.name === 'name-team' ||\n        this.$route.name === 'accept'\n      )\n    },\n    navBarColor() {\n      return this.isTransparent\n        ? 'transparent'\n        : this.isCloud\n        ? 'primary'\n        : 'secondary'\n    },\n    slug() {\n      return this.tenant?.slug\n    }\n  }\n}\n</script>\n\n<template>\n  <v-app-bar app elevate-on-scroll fixed :color=\"navBarColor\">\n    <router-link\n      :to=\"\n        isServer || isAuthorized\n          ? {\n              name: 'dashboard',\n              params: {\n                tenant: slug\n              }\n            }\n          : {\n              name: 'access-denied'\n            }\n      \"\n      exact\n    >\n      <v-btn\n        icon\n        :x-large=\"$vuetify.breakpoint.smAndUp\"\n        :large=\"$vuetify.breakpoint.xsOnly\"\n      >\n        <img\n          class=\"logo\"\n          src=\"@/assets/logos/logomark-white.svg\"\n          alt=\"The Prefect Logo\"\n        />\n      </v-btn>\n    </router-link>\n\n    <TeamSideNavButton v-if=\"isServer || isAuthorized\" />\n\n    <v-divider vertical class=\"white vertical-divider my-auto mx-2\" />\n\n    <!-- We can't use a v-if-else chain here; -->\n    <!-- For some reason the default slot never renders if we do. -->\n    <!-- (likely a Vuetify bug) -->\n    <template v-if=\"$vuetify.breakpoint.mdAndDown\" #extension>\n      <Links\n        v-if=\"$vuetify.breakpoint.mdAndDown && (isServer || isAuthorized)\"\n      />\n    </template>\n\n    <Links\n      v-if=\"!$vuetify.breakpoint.mdAndDown && (isServer || isAuthorized)\"\n    />\n\n    <v-spacer></v-spacer>\n\n    <GlobalSearch\n      v-if=\"$vuetify.breakpoint.smAndUp && (isServer || isAuthorized)\"\n    />\n\n    <HelpMenu />\n\n    <ChatLauncher v-if=\"isCloud\" />\n\n    <NotificationMenu v-if=\"isServer || isAuthorized\" />\n\n    <ConnectionMenu />\n\n    <UserMenu v-if=\"isCloud\" />\n  </v-app-bar>\n</template>\n\n<style lang=\"scss\" scoped>\n.vertical-divider {\n  height: 50%;\n  min-height: 0;\n  opacity: 0.5;\n}\n\n.logo {\n  height: 100%;\n}\n</style>\n\n<style lang=\"scss\">\n.v-app-bar {\n  @media screen and (max-width: 600px) {\n    /* stylelint-disable-next-line */\n    .v-toolbar__content {\n      padding: 0 !important;\n    }\n  }\n\n  z-index: 8 !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/Nav/ChatLauncher.vue",
    "content": "<script>\nexport default {\n  methods: {\n    launchChat() {\n      window.embedded_svc?.bootstrapEmbeddedService()\n    }\n  }\n}\n</script>\n\n<template>\n  <v-btn\n    class=\"navbar-icon mx-1\"\n    icon\n    title=\"Launch support chat\"\n    @click=\"launchChat()\"\n  >\n    <i class=\"fad fa-comment-dots nav-bar-duotone-icon fa-2x\"></i>\n  </v-btn>\n</template>\n"
  },
  {
    "path": "src/components/Nav/ConnectionMenu.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport ExternalLink from '@/components/ExternalLink'\nimport HavingTrouble from '@/components/HavingTrouble'\nimport { clearCache } from '@/vue-apollo'\n\nexport default {\n  components: { ExternalLink, HavingTrouble },\n  data() {\n    return {\n      backendTimeout: null,\n      loading: false,\n      model: false,\n      value: this.backend\n    }\n  },\n  computed: {\n    ...mapGetters('api', [\n      'backend',\n      'isServer',\n      'isCloud',\n      'url',\n      'apiMode',\n      'connected',\n      'connecting',\n      'retries'\n    ]),\n    ...mapGetters('tenant', ['tenant']),\n    iconClass() {\n      if (this.apiMode == 'maintenance') return ['maintenance']\n      if (this.connected) return ['connected']\n      if (this.connecting) return ['connecting', 'connecting-animate']\n      return ['disconnected']\n    },\n    statusColor() {\n      if (this.apiMode == 'maintenance') return 'var(--v-warning-base)'\n      if (this.connected) return 'var(--v-accentGreen-base)'\n      if (this.connecting) return 'var(--v-warning-base)'\n      return 'var(--v-Failed-base)'\n    }\n  },\n  beforeDestroy() {\n    clearTimeout(this.backendTimeout)\n  },\n  methods: {\n    ...mapActions('api', ['switchBackend']),\n    async _switchBackend(val) {\n      if (val == this.backend) return\n\n      clearTimeout(this.backendTimeout)\n      this.loading = true\n\n      this.backendTimeout = setTimeout(async () => {\n        this.loading = false\n\n        if (!this.isCloud) {\n          await this.switchBackend('CLOUD')\n        } else {\n          await this.switchBackend('SERVER')\n        }\n\n        clearCache()\n        this.handlePostTokenRouting()\n      }, 2000)\n    },\n    handlePostTokenRouting() {\n      if (this.isCloud && !this.tenant.settings.teamNamed) {\n        this.$router.push({\n          name: 'welcome',\n          params: {\n            tenant: this.tenant?.slug\n          }\n        })\n\n        return\n      } else {\n        this.$router.push({\n          name: 'dashboard',\n          params: { tenant: this.tenant?.slug }\n        })\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-menu\n    v-model=\"model\"\n    :close-on-content-click=\"false\"\n    offset-y\n    offset-x\n    :nudge-left=\"500\"\n    transition=\"slide-y-transition\"\n    nudge-bottom=\"20\"\n  >\n    <template #activator=\"{ on }\">\n      <v-btn\n        class=\"navbar-icon mx-1\"\n        :class=\"iconClass\"\n        icon\n        title=\"Open the connection menu\"\n        v-on=\"on\"\n      >\n        <i class=\"fad fa-server fa-2x nav-bar-duotone-icon\" />\n      </v-btn>\n    </template>\n\n    <v-sheet width=\"500\" class=\"white\">\n      <v-alert\n        border=\"left\"\n        colored-border\n        tile\n        :color=\"statusColor\"\n        class=\"text-body-1 mb-0\"\n      >\n        <template slot=\"prepend\">\n          <div class=\"align-self-start\" style=\"height: 100%;\">\n            <div\n              class=\"navbar-icon mr-2 grey lighten-2 rounded-circle d-flex align-center justify-center\"\n              :class=\"iconClass\"\n              icon\n            >\n              <i class=\"fad fa-server fa-2x nav-bar-duotone-icon\" />\n            </div>\n          </div>\n        </template>\n\n        <div\n          v-if=\"false\"\n          class=\"mb-4 text-h5 d-flex align-bottom justify-start\"\n        >\n          <v-btn\n            color=\"primary lighten-1\"\n            class=\"px-3 white--text font-weight-bold text-subtitle-1\"\n            depressed\n            tile\n            :outlined=\"isServer\"\n            :disabled=\"loading\"\n            style=\"width: 50%;\"\n            @click=\"_switchBackend('CLOUD')\"\n          >\n            <img\n              class=\"logo mr-2\"\n              style=\"opacity: 0.5;\"\n              src=\"@/assets/logos/cloud-logo-no-text.svg\"\n              :style=\"isCloud && 'filter: brightness(0) invert(1); opacity: 1;'\"\n            />\n            Cloud\n          </v-btn>\n\n          <v-btn\n            class=\"px-3 font-weight-bold text-subtitle-1\"\n            depressed\n            tile\n            :color=\"isServer ? 'primary' : 'utilGrayDark'\"\n            :outlined=\"isCloud\"\n            :disabled=\"loading\"\n            style=\"width: 50%;\"\n            @click=\"_switchBackend('SERVER')\"\n          >\n            Server\n            <img\n              class=\"logo ml-2\"\n              src=\"@/assets/logos/core-logo-no-text.svg\"\n              style=\"opacity: 0.5;\"\n              :style=\"\n                (isServer || $vuetify.theme.dark) &&\n                  'filter: brightness(0) invert(1); opacity: 1;'\n              \"\n            />\n          </v-btn>\n        </div>\n\n        <div class=\"text-h6 font-weight-light\">\n          <span v-if=\"connected\">Connected</span>\n          <span v-else-if=\"connecting\">Connecting</span>\n          <span v-else>Couldn't connect</span>\n          to\n          <span class=\"font-weight-bold\">\n            <span v-if=\"isCloud\" class=\"primary--text\">Prefect Cloud </span>\n            <span v-else class=\"utilGrayDark--text\">Prefect Server</span>\n          </span>\n          <span v-if=\"isServer\">\n            at\n            <span class=\"font-weight-bold\">{{ url }}</span>\n          </span>\n        </div>\n\n        <v-divider class=\"grey lighten-3 my-3\" style=\"width: 50%;\" />\n\n        <!-- If the user is having trouble connecting to Server -->\n        <div v-if=\"isServer && (!connected || connecting)\">\n          <HavingTrouble />\n        </div>\n\n        <!-- If the API is in maintenance mode -->\n        <div v-if=\"apiMode == 'maintenance'\">\n          Prefect Cloud is undergoing routine maintenance; during this time no\n          new runs will be released to your Agents and state updates may be\n          delayed.\n        </div>\n\n        <div v-else-if=\"isCloud\">\n          Having trouble? Check out the\n          <ExternalLink href=\"https://prefect-legacy.status.io/\"\n            >Prefect Cloud status page</ExternalLink\n          >\n          for information about upcoming maintenance windows and the current\n          uptime of Prefect Cloud services.\n        </div>\n      </v-alert>\n    </v-sheet>\n  </v-menu>\n</template>\n\n<style lang=\"scss\" scoped>\n$primary-base: #fff; /* true in light and dark */\n$secondary-base: var(--v-secondaryGrayLight-base);\n\n$statuses: (\n  'connected': var(--v-accentGreen-base),\n  'connecting': var(--v-warning-base),\n  'maintenance': var(--v-warning-base),\n  'disconnected': var(--v-Failed-base)\n);\n\n@mixin duotone-colors($primary, $secondary) {\n  --fa-primary-color: #{$primary};\n  --fa-secondary-color: #{$secondary};\n  --fa-primary-opacity: 1;\n  --fa-secondary-opacity: 1;\n}\n\n@mixin keyframes($animation-name) {\n  @keyframes #{$animation-name} {\n    @content;\n  }\n}\n\n@each $selector, $color in $statuses {\n  @include keyframes(#{$selector}-swap) {\n    from {\n      @include duotone-colors($color, $primary-base);\n    }\n\n    to {\n      @include duotone-colors($primary-base, $color);\n    }\n  }\n\n  .#{$selector} {\n    .svg-inline--fa {\n      @include duotone-colors($primary-base, $color);\n      transition: all 500ms;\n    }\n\n    &:hover,\n    &:focus {\n      .svg-inline--fa {\n        @include duotone-colors($color, $primary-base);\n        animation: unset !important;\n      }\n    }\n  }\n\n  .#{$selector}-animate {\n    .svg-inline--fa {\n      animation: #{$selector}-swap 2000ms linear infinite;\n    }\n  }\n}\n\n.logo {\n  height: 24px;\n  width: 24px;\n}\n</style>\n"
  },
  {
    "path": "src/components/Nav/CurrentTime.vue",
    "content": "<template>\n  <div class=\"current-time\">\n    <span class=\"current-time__hour\">{{ time.hour }}</span>\n    <span class=\"current-time__separator\">:</span>\n    <span class=\"current-time__minute\">{{ time.minute }}</span>\n    <span class=\"current-time__meridian\">{{ time.meridian }}</span>\n    <v-tooltip top>\n      <template #activator=\"{ on }\">\n        <v-icon class=\"material-icons-outlined\" x-small v-on=\"on\">\n          info\n        </v-icon>\n      </template>\n      System time according to your set Timezone; you can change this from your\n      Account Settings.\n    </v-tooltip>\n  </div>\n</template>\n\n<script>\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { getMillisecondsUntilNextMinute } from '@/utils/dateTime'\n\nexport default {\n  mixins: [formatTime],\n  data() {\n    return {\n      clockTimeout: null,\n      clockInterval: null,\n      time: null\n    }\n  },\n  created() {\n    this.setTime()\n    this.triggerSetTimeIntervalAtNextMinute()\n  },\n  destroyed() {\n    clearInterval(this.clockInterval)\n  },\n  methods: {\n    setTime() {\n      this.time = this.dateParts(Date.now())\n    },\n    triggerSetTimeIntervalAtNextMinute() {\n      const millisecondsUntilNextMinute = getMillisecondsUntilNextMinute()\n\n      this.clockInterval = setTimeout(\n        this.setTimeOnMinuteInterval,\n        millisecondsUntilNextMinute\n      )\n    },\n    setTimeOnMinuteInterval() {\n      this.setTime()\n      this.clockInterval = setInterval(this.setTime, 60000)\n    }\n  }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.current-time__separator {\n  color: var(--v-utilGrayDark-base);\n}\n\n.current-time__meridian {\n  color: var(--v-utilGrayDark-base);\n  font-size: 0.75rem;\n  line-height: 2rem;\n  font-weight: 500;\n  letter-spacing: 0.16em;\n  text-transform: uppercase;\n  padding-left: 8px;\n  padding-right: 4px;\n}\n</style>\n"
  },
  {
    "path": "src/components/Nav/HelpMenu.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nexport default {\n  data() {\n    return {\n      model: false\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud'])\n  }\n}\n</script>\n\n<template>\n  <v-menu\n    v-model=\"model\"\n    offset-y\n    offset-x\n    :nudge-left=\"350\"\n    transition=\"slide-y-transition\"\n    nudge-bottom=\"20\"\n  >\n    <template #activator=\"{ on }\">\n      <v-btn\n        class=\"navbar-icon mx-1\"\n        :input-value=\"$route.path.includes('/help')\"\n        icon\n        title=\"Open the help menu\"\n        v-on=\"on\"\n      >\n        <i\n          class=\"fad fa-question-circle nav-bar-duotone-icon fa-2x white--text\"\n        />\n      </v-btn>\n    </template>\n\n    <v-sheet width=\"350\" class=\"pt-4\">\n      <div class=\"text-h6 font-weight-light px-4\">\n        Stuck? We can help!\n      </div>\n\n      <v-list class=\"text-left\">\n        <v-list-item :to=\"'/getting-started'\">\n          <v-list-item-avatar tile class=\"d-flex justify-center align-center\">\n            <i class=\"o-100 fad fa-laptop-code fa-2x\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Getting started\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Installing Prefect, starting your first agent and more\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item href=\"https://docs.prefect.io\" target=\"_blank\">\n          <v-list-item-avatar tile class=\"d-flex justify-center align-center\">\n            <i class=\"o-100 fad fa-books fa-2x fa-flip-horizontal\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Docs\n              <sup>\n                <v-icon x-small>\n                  open_in_new\n                </v-icon>\n              </sup>\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Explore Prefect through our docs\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item href=\"https://discourse.prefect.io\" target=\"_blank\">\n          <v-list-item-avatar tile class=\"d-flex justify-center align-center\">\n            <i class=\"o-100 fab fa-discourse fa-2x primaryDark--text\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Have a question?\n              <sup>\n                <v-icon x-small>\n                  open_in_new\n                </v-icon>\n              </sup>\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Start a discussion on our Discourse!\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :to=\"'/tutorial'\">\n          <v-list-item-avatar tile class=\"d-flex justify-center align-center\">\n            <i class=\"o-100 fad fa-graduation-cap fa-2x fa-flip-horizontal\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Tutorials\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Learn more about Prefect, right from the UI\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          href=\"https://github.com/PrefectHQ/ui/issues/new/choose\"\n          target=\"_blank\"\n        >\n          <v-list-item-avatar tile class=\"d-flex justify-center align-center\">\n            <i class=\"o-100 fab fa-github fa-2x primaryDark--text\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Found a bug?\n              <sup>\n                <v-icon x-small>\n                  open_in_new\n                </v-icon>\n              </sup>\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Open a ticket for us on GitHub!\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item href=\"https://prefect.io/slack\" target=\"_blank\">\n          <v-list-item-avatar tile class=\"d-flex justify-center align-center\">\n            <img src=\"@/assets/icon-illustrations/slack-community.svg\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Join our Slack!\n              <sup>\n                <v-icon x-small>\n                  open_in_new\n                </v-icon>\n              </sup>\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Chat with us, ask questions, and share tips\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item v-if=\"isCloud\" :to=\"'/help'\">\n          <v-list-item-avatar tile class=\"d-flex justify-center align-center\">\n            <i class=\"o-100 fad fa-life-ring fa-2x\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Feedback & Support\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Having trouble or have a question for us?\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n      </v-list>\n    </v-sheet>\n  </v-menu>\n</template>\n\n<style lang=\"scss\" scoped>\n$dark-grey-icon: var(--v-utilGrayMid-base);\n$dark-blue-icon: var(--v-primaryDark-base);\n\n.o-100 {\n  &.svg-inline--fa {\n    --fa-primary-opacity: 0.8;\n    --fa-secondary-opacity: 0.8;\n  }\n}\n\n.fa-life-ring {\n  --fa-secondary-color: #{$dark-grey-icon};\n  --fa-primary-color: #{$dark-blue-icon};\n}\n\n.fa-books {\n  --fa-primary-color: #{$dark-grey-icon};\n  --fa-secondary-color: #{$dark-blue-icon};\n}\n\n.fa-graduation-cap {\n  --fa-secondary-color: #{$dark-blue-icon};\n  --fa-primary-color: #{$dark-grey-icon};\n}\n\n.fa-laptop-code {\n  --fa-secondary-color: #{$dark-blue-icon};\n  --fa-primary-color: #{$dark-grey-icon};\n}\n</style>\n"
  },
  {
    "path": "src/components/Nav/Links.vue",
    "content": "<script>\nimport TeamMenu from '@/components/Nav/TeamMenu'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    TeamMenu\n  },\n  data() {\n    return {\n      active: false,\n      menu: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    slug() {\n      return this.tenant?.slug\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"links-container\">\n    <v-btn\n      :to=\"{\n        name: 'dashboard',\n        params: {\n          tenant: slug\n        }\n      }\"\n      class=\"text-subtitle-1 text-capitalize mx-1 font-weight-medium\"\n      dark\n      small\n      depressed\n      color=\"transparent\"\n      :input-value=\"$route.name == 'dashboard' || $route.name == 'project'\"\n      title=\"Visit your Dashboard\"\n      exact\n    >\n      Dashboard\n    </v-btn>\n\n    <v-btn\n      :to=\"{\n        name: 'agents',\n        params: { tenant: slug }\n      }\"\n      class=\"text-subtitle-1 text-capitalize mx-1 font-weight-medium\"\n      dark\n      small\n      depressed\n      color=\"transparent\"\n      title=\"Manage your team's agents\"\n    >\n      Agents\n    </v-btn>\n\n    <v-btn\n      :to=\"{\n        name: 'api',\n        params: { tenant: slug }\n      }\"\n      class=\"text-subtitle-1 text-capitalize mx-1 font-weight-medium\"\n      dark\n      small\n      depressed\n      color=\"transparent\"\n      title=\"Experiment with GraphQL queries using the Interactive API\"\n    >\n      Interactive API\n    </v-btn>\n\n    <v-btn\n      :to=\"{\n        name: 'account',\n        params: { tenant: slug }\n      }\"\n      class=\"text-subtitle-1 text-capitalize mx-1 font-weight-medium\"\n      dark\n      small\n      depressed\n      color=\"transparent\"\n      title=\"Manage your account, usage, and data\"\n    >\n      Account\n    </v-btn>\n\n    <TeamMenu />\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.links-container {\n  max-width: 100%;\n  overflow-x: auto;\n  scrollbar-width: none;\n  white-space: nowrap;\n\n  // stylelint-disable\n  &::-webkit-scrollbar {\n    display: none;\n  }\n  // stylelint-enable\n}\n</style>\n"
  },
  {
    "path": "src/components/Nav/MenuLink.vue",
    "content": "<script>\nimport {\n  VListItem,\n  VListItemContent,\n  VListItemSubtitle,\n  VListItemTitle\n} from 'vuetify/lib'\n\nexport default {\n  components: {\n    VListItem,\n    VListItemContent,\n    VListItemSubtitle,\n    VListItemTitle\n  },\n  props: {\n    primary: {\n      type: String,\n      default: () => null,\n      required: false\n    },\n    secondary: {\n      type: String,\n      default: () => null,\n      required: false\n    },\n    route: {\n      type: Object,\n      default: () => null,\n      required: false\n    }\n  }\n}\n</script>\n\n<template functional>\n  <component :is=\"$options.components.VListItem\" class=\"py-2\" :to=\"props.route\">\n    <component :is=\"$options.components.VListItemContent\">\n      <component\n        :is=\"$options.components.VListItemTitle\"\n        class=\"text-body-1 text--primary\"\n      >\n        {{ props.primary }}\n      </component>\n      <component\n        :is=\"$options.components.VListItemSubtitle\"\n        class=\"text-caption text--secondary text-truncate\"\n      >\n        {{ props.secondary }}\n      </component>\n    </component>\n  </component>\n</template>\n"
  },
  {
    "path": "src/components/Nav/NotificationMenu.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nexport default {\n  computed: {\n    ...mapGetters('api', ['connected']),\n    ...mapGetters('auth', ['isAuthorized']),\n    ...mapGetters('tenant', ['tenant', 'tenantIsSet']),\n    active() {\n      return this.notificationsCount\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.notificationsCount.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    notificationsCount: {\n      query: require('@/graphql/Notifications/notifications-count-unread.gql'),\n      loadingKey: 'loading',\n      update: data => data?.message_aggregate?.aggregate?.count,\n      fetchPolicy: 'no-cache',\n      skip() {\n        return !this.connected || !this.tenantIsSet || !this.isAuthorized\n      },\n      pollInterval: 10000\n    }\n  }\n}\n</script>\n\n<template>\n  <v-btn\n    v-intersect=\"{ handler: onIntersect }\"\n    :to=\"'/notifications'\"\n    class=\"navbar-icon mx-1\"\n    icon\n    title=\"Navigation to your notifications page\"\n  >\n    <span class=\"fa-stack\" :class=\"{ active: active }\">\n      <i\n        class=\"fad fa-circle nav-bar-duotone-icon fa-stack-1x fa-xs overflow-hidden\"\n      ></i>\n      <i class=\"fad fa-bell nav-bar-duotone-icon fa-stack-2x\"></i>\n    </span>\n  </v-btn>\n</template>\n"
  },
  {
    "path": "src/components/Nav/TeamMenu.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport UpgradeBadge from '@/components/UpgradeBadge'\n\nexport default {\n  components: {\n    UpgradeBadge\n  },\n  data() {\n    return {\n      model: false\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('license', ['hasPermission'])\n  }\n}\n</script>\n\n<template>\n  <v-menu\n    v-model=\"model\"\n    offset-y\n    transition=\"slide-y-transition\"\n    nudge-bottom=\"25\"\n  >\n    <template #activator=\"{on}\">\n      <v-btn\n        :input-value=\"$route.path.includes('/team/')\"\n        class=\"text-subtitle-1 text-capitalize mx-1 font-weight-medium\"\n        dark\n        small\n        depressed\n        color=\"transparent\"\n        title=\"Open the team menu\"\n        v-on=\"on\"\n      >\n        Team\n      </v-btn>\n    </template>\n\n    <v-sheet width=\"400\" class=\"white\">\n      <v-list>\n        <v-list-item :disabled=\"!isCloud\" :to=\"'/team/tokens'\">\n          <v-list-item-avatar tile>\n            <i class=\"o-100 fad fa-exchange-alt fa-2x\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              API Tokens\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Manage your team's API tokens\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :disabled=\"!isCloud\" :to=\"'/team/actions'\">\n          <v-list-item-avatar>\n            <span class=\"auto-icon\">\n              <i class=\"fad fa-random\" style=\"width: 24px; height: 24px;\"></i>\n            </span>\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title>Automation Actions</v-list-item-title>\n            <v-list-item-subtitle>\n              View and manage automation actions\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :to=\"'/team/cloud-hooks'\">\n          <v-list-item-avatar tile>\n            <i class=\"o-100 fad fa-clouds fa-2x\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Cloud Hooks\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Create and modify team-wide Cloud Hooks\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :disabled=\"!isCloud\" :to=\"'/team/flow-concurrency'\">\n          <v-list-item-avatar tile>\n            <v-icon large color=\"navIcons\">\n              pi-flow-run\n            </v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Flow Concurrency\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Manage flow concurrency\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :to=\"'/team/flow-groups'\">\n          <v-list-item-avatar tile>\n            <v-icon large color=\"navIcons\">\n              pi-flow\n            </v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Flow Groups\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              View all your team's flows\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :disabled=\"!isCloud\" :to=\"'/team/kv'\">\n          <v-list-item-avatar tile>\n            <span style=\"color: Dodgerblue;\">\n              <i class=\"fad fa-brackets-curly fa-2x\"></i>\n            </span>\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              KV Store\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Manage your team's key/value store\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :disabled=\"!isCloud\" :to=\"'/team/members'\">\n          <v-list-item-avatar tile>\n            <i class=\"o-100 fad fa-users fa-2x\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Members\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Invite people to your team and manage permissions\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :to=\"'/team/projects'\">\n          <v-list-item-avatar tile>\n            <v-icon large color=\"navIcons\">\n              pi-project\n            </v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Projects\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Create and modify your team's projects\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :disabled=\"!isCloud || !hasPermission('feature', 'custom-role')\"\n          :to=\"'/team/roles'\"\n        >\n          <v-list-item-avatar tile>\n            <v-icon large color=\"navIcons\">face</v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\"\n              >Roles\n              <UpgradeBadge\n                v-if=\"isCloud && !hasPermission('feature', 'custom-role')\"\n                depressed\n                inline\n              >\n                <span class=\"font-weight-medium\">Custom Roles</span> are only\n                available on Enterprise plans.\n              </UpgradeBadge></v-list-item-title\n            >\n            <v-list-item-subtitle>\n              Manage Team Roles\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :disabled=\"!isCloud\" :to=\"'/team/secrets'\">\n          <v-list-item-avatar tile>\n            <i class=\"o-100 fad fa-key-skeleton fa-2x\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Secrets\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Create and manage team-wide Secrets used by your flows\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :disabled=\"!isCloud\" :to=\"'/team/service-accounts'\">\n          <v-list-item-avatar tile>\n            <i class=\"o-100 fad fa-user-hard-hat fa-2x\" />\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Service Accounts\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Manage Service Accounts and API Keys\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item :disabled=\"!isCloud\" :to=\"'/team/task-concurrency'\">\n          <v-list-item-avatar tile>\n            <v-icon large color=\"primaryDark\">\n              pi-task-run\n            </v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-subtitle-1\">\n              Task Concurrency\n            </v-list-item-title>\n            <v-list-item-subtitle>\n              Manage task run concurrency\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n      </v-list>\n    </v-sheet>\n  </v-menu>\n</template>\n\n<style lang=\"scss\" scoped>\n$dark-grey-icon: var(--v-navIcons-base);\n$dark-blue-icon: var(--v-primaryDark-base);\n\n.o-100 {\n  &.svg-inline--fa {\n    --fa-primary-opacity: 0.8;\n    --fa-secondary-opacity: 0.8;\n  }\n}\n\n.fa-abacus {\n  --fa-primary-color: #{$dark-grey-icon};\n  --fa-secondary-color: #{$dark-blue-icon};\n}\n\n.fa-random {\n  --fa-primary-color: #{$dark-grey-icon};\n  --fa-secondary-color: #{$dark-blue-icon};\n}\n\n.fa-key-skeleton {\n  --fa-primary-color: #{$dark-blue-icon};\n  --fa-secondary-color: #{$dark-grey-icon};\n}\n\n.fa-users {\n  --fa-primary-color: #{$dark-blue-icon};\n  --fa-secondary-color: #{$dark-grey-icon};\n}\n\n.fa-user-hard-hat {\n  --fa-primary-color: #{$dark-blue-icon};\n  --fa-secondary-color: #{$dark-grey-icon};\n}\n\n.fa-clouds {\n  --fa-primary-color: #{$dark-blue-icon};\n  --fa-secondary-color: #{$dark-grey-icon};\n}\n\n.fa-exchange-alt {\n  --fa-primary-color: #{$dark-blue-icon};\n  --fa-secondary-color: #{$dark-grey-icon};\n}\n\n/* stylelint-disable-next-line */\n.v-list-item--disabled {\n  /* stylelint-disable-next-line */\n  .v-list-item__avatar {\n    opacity: 0.25 !important;\n  }\n\n  /* stylelint-disable-next-line */\n  .v-list-item__subtitle {\n    opacity: 0.4 !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Nav/TeamSideNav.vue",
    "content": "<script>\nimport debounce from 'lodash/throttle'\nimport moment from 'moment-timezone'\nimport { mapGetters, mapMutations } from 'vuex'\nimport NewProjectDialog from '@/pages/Dashboard/NewProject-Dialog'\nimport TeamSwitcher from '@/components/Nav/TeamSwitcher'\nimport Tree from '@/components/Tree/Tree'\n\nconst UI_DEPLOY_TIMESTAMP = process.env.VUE_APP_RELEASE_TIMESTAMP\n\nexport default {\n  components: {\n    NewProjectDialog,\n    TeamSwitcher,\n    Tree\n  },\n  data() {\n    return {\n      items: [],\n      newProjectDialog: false,\n      types: {\n        project: 'folder',\n        projectActive: 'pi-project',\n        flow: 'pi-flow',\n        task: 'pi-task'\n      },\n      unwatchFlows: null,\n      unwatchProjects: null,\n      unsubscribeData: null\n    }\n  },\n\n  computed: {\n    ...mapGetters('api', [\n      'isServer',\n      'isCloud',\n      'version',\n      'releaseTimestamp',\n      'coreVersion'\n    ]),\n    ...mapGetters('sideNav', ['isOpen']),\n    ...mapGetters('data', [\n      'flows',\n      'activeFlowId',\n      'projects',\n      'activeProjectId',\n      'tasks',\n      'activeTaskId'\n    ]),\n    ...mapGetters('tenant', ['tenant', 'isLoadingTenant']),\n    activeIds() {\n      return [\n        this.activeFlowId,\n        this.activeProjectId,\n        this.activeTaskId\n      ].filter(id => !!id)\n    },\n    model: {\n      get() {\n        return this.isOpen\n      },\n      set(value) {\n        if (value === false) {\n          this.close()\n        }\n      }\n    },\n    lastDeployment_Cloud() {\n      return this.releaseTimestamp\n        ? moment(this.releaseTimestamp).format('MMM D [•] h:mmA')\n        : 'Unknown'\n    },\n    lastDeployment_UI() {\n      return moment(UI_DEPLOY_TIMESTAMP).format('MMM D [•] h:mmA')\n    },\n    logoAlt() {\n      return require(`@/assets/logos/${\n        this.isCloud ? 'cloud' : 'core'\n      }-logo-no-text.svg`)\n    }\n  },\n  watch: {\n    async isOpen(val) {\n      if (val) {\n        this.updateItems()\n\n        this.unwatchFlows = this.$watch('flows', this.updateItems)\n        this.unwatchProjects = this.$watch('projects', this.updateItems)\n        this.unsubscribeData = await this.$store.dispatch('polling/subscribe', [\n          'flows',\n          'projects'\n        ])\n      } else {\n        this.unwatchFlows()\n        this.unwatchProjects()\n        this.unsubscribeData()\n      }\n    }\n  },\n  mounted() {\n    // Adds the event listener for the t search shortcut\n    window.addEventListener('keyup', this.handleKeyboardShortcut)\n\n    this.updateItems()\n  },\n  beforeDestroy() {\n    // Removes the t search shortcut event listener when\n    // the component is destroyed\n    window.removeEventListener('keyup', this.handleKeyboardShortcut)\n  },\n  methods: {\n    ...mapMutations('sideNav', ['close', 'open']),\n    ...mapMutations('data', ['addTasks']),\n    onIntersect([entry]) {\n      if (entry.isIntersecting) {\n        entry.target.focus()\n      }\n    },\n    closeAll() {\n      this.$refs['tree'].close()\n    },\n    handleKeyboardShortcut(e) {\n      if (e?.key === 'Escape' && this.isOpen) {\n        this.close()\n      }\n\n      if (\n        e?.key === 't' &&\n        e?.srcElement?.tagName !== 'INPUT' &&\n        e?.srcElement?.tagName !== 'TEXTAREA'\n      ) {\n        this.isOpen ? this.close() : this.open()\n      }\n    },\n    handleSelect: debounce(\n      function() {\n        // We can do something when an item is selected\n        // but routing is handled with the link attribute\n        // requestAnimationFrame(() => {\n        //   let id = val.id\n        //   if (val.type == 'flow') {\n        //     id = this.flows.find(f => f.id == val.id).flow_group_id\n        //   }\n        //   this.$router.push({\n        //     name: val.type,\n        //     params: {\n        //       id: id,\n        //       tenant: this.tenant.slug\n        //     }\n        //   })\n        // })\n      },\n      1500,\n      { leading: true, trailing: true }\n    ),\n    async loadTasks(item) {\n      const { data } = await this.$apollo.query({\n        query: require('@/graphql/Nav/tasks.gql'),\n        variables: {\n          flowId: item.id\n        }\n      })\n\n      this.addTasks(data.task)\n\n      const sortedTasks = data.task\n        .map(t => {\n          return {\n            id: t.id,\n            idToMatch: t.id,\n            link: {\n              name: 'task',\n              params: { id: t.id, tenant: this.tenant.slug }\n            },\n            name: t.name,\n            icon: this.types['task'],\n            type: 'task'\n          }\n        })\n        .sort((a, b) =>\n          a.name.localeCompare(b.name, undefined, {\n            ignorePunctuation: true\n          })\n        )\n      return sortedTasks\n    },\n    updateItems() {\n      this.items = [\n        ...(this.projects ?? [])\n          .filter(p => p.tenant_id == this.tenant.id)\n          .map(project => {\n            const val = {\n              id: project.id,\n              idToMatch: project.id,\n              icon: this.types['project'],\n              iconActive: this.types['projectActive'],\n              link: {\n                name: 'project',\n                params: { id: project.id, tenant: this.tenant.slug }\n              },\n              name: project.name,\n              type: 'project',\n              children: [\n                ...(this.flows ?? [])\n                  ?.filter(f => f.project_id == project.id)\n                  .map(f => {\n                    return {\n                      id: f.id,\n                      idToMatch: f.flow_group_id,\n                      children: this.loadTasks, // These are loaded async\n                      link: {\n                        name: 'flow',\n                        params: {\n                          id: f.flow_group_id,\n                          tenant: this.tenant.slug\n                        }\n                      },\n                      name: f.name,\n                      icon: this.types['flow'],\n                      type: 'flow'\n                    }\n                  })\n                  .sort((a, b) =>\n                    a.name.localeCompare(b.name, undefined, {\n                      ignorePunctuation: true\n                    })\n                  )\n              ]\n            }\n            return val\n          })\n          .sort((a, b) =>\n            a.name.localeCompare(b.name, undefined, { ignorePunctuation: true })\n          )\n      ]\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-navigation-drawer\n      v-model=\"model\"\n      temporary\n      hide-overlay\n      fixed\n      disable-route-watcher\n      width=\"375\"\n      class=\"drawer pb-1\"\n    >\n      <div\n        v-if=\"model\"\n        class=\"d-flex flex-column\"\n        style=\"\n        height: 100%;\n        width: 100%;\"\n      >\n        <TeamSwitcher />\n\n        <div class=\"mt-4 mb-2\">\n          <v-divider class=\"mx-10 mb-5\" />\n\n          <div v-if=\"projects\" class=\"mx-4 d-flex justify-space-between\">\n            <div class=\"text-h5\">Projects</div>\n\n            <div\n              v-if=\"projects.length > 0\"\n              v-ripple\n              class=\"cursor-pointer px-2 py-2 text-caption font-weight-normal collapse-button rounded utilGrayMid--text\"\n              @click=\"closeAll\"\n            >\n              Collapse All\n            </div>\n          </div>\n        </div>\n\n        <div\n          v-intersect=\"{ handler: onIntersect }\"\n          class=\"focusable tree-view flex-grow-1 flex-shrink-1\"\n          tabindex=\"-1\"\n        >\n          <div class=\"pa-0 mx-4\">\n            <tree\n              v-if=\"!isLoadingTenant && projects && projects.length > 0\"\n              ref=\"tree\"\n              class=\"px-4\"\n              :active-ids=\"activeIds\"\n              :items=\"items\"\n              :options=\"{\n                noData: { 0: 'no projects', 1: 'no flows', 2: 'no tasks' },\n                activateButton: { 0: 'Visit', 1: 'Visit', 2: false }\n              }\"\n              @select=\"handleSelect\"\n            />\n\n            <div\n              v-else-if=\"!isLoadingTenant && projects && projects.length === 0\"\n            >\n              <div class=\"text-subtitle-1\">You have no projects</div>\n\n              <v-btn\n                depressed\n                color=\"primaryDark\"\n                class=\"my-4\"\n                block\n                dark\n                @click=\"newProjectDialog = true\"\n              >\n                <v-icon class=\"mr-2\">folder</v-icon>\n                New project\n              </v-btn>\n            </div>\n\n            <v-progress-circular\n              v-else\n              indeterminate\n              size=\"70\"\n              color=\"primaryDark\"\n              class=\"position-absolute\"\n              style=\"\n                left: 50%;\n                top: 50%;\n                transform: translate(-50%, -50%);\n              \"\n            />\n          </div>\n        </div>\n\n        <div class=\"flex-grow-0 flex-shrink-0 mt-6 pb-6\">\n          <v-divider class=\"mx-10 mb-4\" />\n\n          <div class=\"text-caption d-flex align-end justify-space-between mx-8\">\n            <div\n              v-if=\"lastDeployment_UI\"\n              class=\"text-right\"\n              style=\"width: 35%;\"\n            >\n              <div class=\"utilGrayMid--text font-weight-light\">\n                UI Release\n              </div>\n              <div>{{ lastDeployment_UI }}</div>\n            </div>\n            <div class=\"flex-grow-1\">\n              <div v-show=\"coreVersion && isServer\" class=\"text-center mb-2\">\n                <div class=\"utilGrayMid--text font-weight-light\">\n                  Core Version\n                </div>\n                <div>{{ coreVersion }}</div>\n              </div>\n              <v-img\n                max-height=\"100\"\n                width=\"40px\"\n                contain\n                position=\"center center\"\n                class=\"mx-auto\"\n                :src=\"logoAlt\"\n                alt=\"Prefect Logo\"\n              />\n            </div>\n            <div v-if=\"lastDeployment_Cloud\" style=\"width: 35%;\">\n              <div class=\"utilGrayMid--text font-weight-light\">\n                API Release\n              </div>\n              <div>{{ lastDeployment_Cloud }}</div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </v-navigation-drawer>\n\n    <NewProjectDialog :show.sync=\"newProjectDialog\" />\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.drawer {\n  height: calc(100vh - 64px) !important;\n  overflow: auto;\n  top: 64px !important;\n\n  @media screen and (max-width: 1264px) {\n    height: calc(100vh - 104px) !important;\n    top: 104px !important;\n  }\n\n  /* stylelint-disable */\n  .focusable {\n    &:focus {\n      // This allows us to auto-focus the nav drawer but not show the outline\n      outline: none;\n    }\n  }\n  /* stylelint-enable */\n\n  .tree-view {\n    overflow: scroll;\n  }\n}\n\n.collapse-button {\n  letter-spacing: 1px !important;\n\n  &:focus,\n  &:hover {\n    background-color: rgba(0, 0, 0, 0.03);\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Nav/TeamSideNavButton.vue",
    "content": "<script>\nimport { mapGetters, mapMutations } from 'vuex'\n\nexport default {\n  data() {\n    return {}\n  },\n  computed: {\n    ...mapGetters('sideNav', ['isOpen']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['invitations']),\n    size() {\n      return this.$vuetify.breakpoint.mdAndUp ? (this.isOpen ? 325 : 225) : 175\n    }\n  },\n  methods: {\n    ...mapMutations('sideNav', ['toggle'])\n  }\n}\n</script>\n\n<template>\n  <v-btn\n    class=\"text-subtitle-1 text-capitalize mx-1 font-weight-medium d-flex justify-space-between px-3\"\n    dark\n    large\n    depressed\n    :width=\"size\"\n    style=\"\n      background-color: rgba(255, 255, 255, 0.1);\n      transition: width 200ms;\"\n    title=\"Open the sidebar\"\n    @click.stop=\"toggle\"\n  >\n    <div\n      style=\"font-size: 1.05rem;\"\n      class=\"d-flex align-center justify-start\"\n      :style=\"{ width: size - 45 + 'px' }\"\n    >\n      <div class=\"text-truncate\">\n        {{ tenant.name }}\n      </div>\n      <v-badge\n        inline\n        :value=\"invitations && invitations.length\"\n        :content=\"invitations && invitations.length\"\n        color=\"accentPink\"\n      />\n    </div>\n    <v-icon class=\"flex-shrink-0\">\n      {{ isOpen ? 'chevron_left' : 'chevron_right' }}\n    </v-icon>\n  </v-btn>\n</template>\n"
  },
  {
    "path": "src/components/Nav/TeamSwitcher.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport { handleMembershipInvitations } from '@/mixins/membershipInvitationMixin'\nimport { pollsTenantsMixin } from '@/mixins/polling/pollsTenantsMixin'\nimport AcceptConfirmInputRow from '@/components/AcceptConfirmInputRow'\nimport { clearCache } from '@/vue-apollo'\n\nconst backendProtectedRoutes = [\n  'team',\n  'account',\n  'task-concurrency',\n  'members',\n  'secrets',\n  'tokens',\n  'user',\n  'profile',\n  'user-tokens',\n  'welcome',\n  'name-team',\n  'onboard-resources'\n]\n\nconst tenantProtectedRoutes = [\n  'project',\n  'flow',\n  'flow-run',\n  'task',\n  'task-run',\n  'flow-run-logs',\n  'select-plan',\n  'billing',\n  'welcome',\n  'current-plan',\n  'payment',\n  'api',\n  'name-team'\n]\n\nexport default {\n  components: { AcceptConfirmInputRow },\n  mixins: [handleMembershipInvitations, pollsTenantsMixin],\n  data() {\n    return {\n      loading: false,\n      model: false\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant', 'tenants']),\n    ...mapGetters('user', ['invitations', 'memberships']),\n    role() {\n      if (!this.tenant) return\n\n      let role\n      switch (this.tenant.role) {\n        case 'USER':\n          role = 'User'\n          break\n        case 'READ_ONLY_USER':\n          role = 'Restricted User'\n          break\n        case 'TENANT_ADMIN':\n          role = 'Administrator'\n          break\n        default:\n          role = ''\n          break\n      }\n      return role\n    },\n    teams() {\n      return this.isCloud\n        ? this.memberships?.map(m => {\n            return { ...m, ...m.tenant }\n          })\n        : this.tenants\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['addNotification', 'updateNotification']),\n    ...mapActions('data', ['resetData']),\n    ...mapActions('tenant', ['setCurrentTenant']),\n    ...mapActions('user', ['getUser']),\n    async handleAcceptPendingInvitation(id, name, slug) {\n      this.loading = true\n      const notificationId = await this.addNotification({\n        color: 'primaryLight',\n        loading: true,\n        text: `Joining ${name}...`,\n        dismissable: false\n      })\n\n      let success, error\n      try {\n        await this.acceptMembershipInvitation(id)\n        success = true\n      } catch (e) {\n        success = false\n        error = e\n      } finally {\n        await this.$globalApolloQueries['membershipInvitations']?.refetch()\n        await this.getUser()\n        await this.$globalApolloQueries['tenants']?.refetch()\n\n        await this.updateNotification({\n          id: notificationId,\n          notification: {\n            color: success ? 'accentGreen' : 'error',\n            loading: false,\n            linkText: success ? 'Visit' : null,\n            to: success\n              ? {\n                  name: 'dashboard',\n                  params: {\n                    tenant: slug\n                  }\n                }\n              : null,\n            text: success\n              ? `You've joined ${name}!`\n              : `Something went wrong trying to accept your invitation to ${name}... please wait a few moments and try again.`,\n            subtext: error,\n            dismissable: true,\n            timeout: 10000\n          }\n        })\n\n        this.loading = false\n      }\n    },\n    async handleDeclinePendingInvitation(id, name) {\n      this.loading = true\n      let success, error\n      try {\n        await this.declineMembershipInvitation(id)\n        success = true\n      } catch (e) {\n        success = false\n        error = e\n      } finally {\n        await this.$globalApolloQueries['membershipInvitations']?.refetch()\n        await this.getUser()\n        await this.$globalApolloQueries['tenants']?.refetch()\n\n        await this.addNotification({\n          color: success ? 'accentGreen' : 'error',\n          text: success\n            ? `Invitation to join ${name} removed.`\n            : `Something went wrong trying to decline your invitation to ${name}... please wait a few moments and try again.`,\n          subtext: error,\n          dismissable: true,\n          timeout: 10000\n        })\n\n        this.loading = false\n      }\n    },\n    async handleSwitchTenant(tenant) {\n      if (tenant.slug == this.tenant.slug) return\n\n      this.loading = true\n\n      this.resetData()\n\n      await this.setCurrentTenant(tenant.slug)\n\n      clearCache()\n      this.handlePostTokenRouting()\n    },\n    async handlePostTokenRouting() {\n      try {\n        if (this.isCloud && !this.tenant.settings.teamNamed) {\n          await this.$router.push({\n            name: 'welcome',\n            params: {\n              tenant: this.tenant.slug\n            }\n          })\n\n          return\n        }\n\n        if (\n          tenantProtectedRoutes.includes(this.$route.name) ||\n          (this.isServer && backendProtectedRoutes.includes(this.$route.name))\n        ) {\n          await this.$router.push({\n            name: 'dashboard',\n            params: { tenant: this.tenant.slug }\n          })\n        } else {\n          await this.$router.push({\n            name: this.$route.name,\n            params: { ...this.$route.params, tenant: this.tenant.slug }\n          })\n        }\n      } catch {\n        /* */\n      } finally {\n        this.model = false\n        this.loading = false\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container class=\"pa-0\" fluid>\n    <v-progress-linear\n      absolute\n      :active=\"loading\"\n      :indeterminate=\"loading\"\n      color=\"accentPink\"\n    />\n\n    <div class=\"pt-6 px-4 text-center\">\n      <div>\n        <div class=\"text-h4\">\n          {{\n            tenant && tenant.name\n              ? tenant.name\n              : loading\n              ? '...'\n              : 'No team selected'\n          }}\n        </div>\n\n        <div class=\"text-body-1 utilGrayMid--text\">{{ role }}</div>\n      </div>\n    </div>\n    <v-menu\n      v-model=\"model\"\n      offset-x\n      :close-on-content-click=\"false\"\n      max-height=\"60vh\"\n    >\n      <template #activator=\"{ on }\">\n        <v-list-item\n          class=\"py-0\"\n          :disabled=\"!tenants || tenants.length === 0\"\n          v-on=\"on\"\n        >\n          <v-list-item-avatar tile class=\"mr-2\">\n            <v-badge\n              v-if=\"invitations && invitations.length > 0\"\n              :value=\"invitations && invitations.length\"\n              :content=\"invitations && invitations.length\"\n              color=\"accentPink\"\n              inline\n              class=\"ml-1 white--text\"\n            />\n            <v-icon\n              v-else\n              :color=\"model ? 'primaryDark' : 'grey darken-1'\"\n              small\n            >\n              sync_alt\n            </v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-body-1 text-none\">\n              Switch team\n            </v-list-item-title>\n          </v-list-item-content>\n          <v-list-item-action>\n            <v-icon :color=\"model ? 'primaryDark' : 'grey darken-1'\">\n              arrow_right\n            </v-icon>\n          </v-list-item-action>\n        </v-list-item>\n      </template>\n\n      <v-card class=\"team-switcher-list elevation-4 text-truncate\">\n        <v-list :disabled=\"loading\">\n          <v-subheader>\n            <v-icon x-small class=\"mr-2\">\n              fas fa-users\n            </v-icon>\n            <div>Teams</div>\n            <v-divider class=\"ml-4\" />\n          </v-subheader>\n          <v-list-item\n            v-for=\"team in teams\"\n            :key=\"team.id\"\n            class=\"pl-4 py-2\"\n            :input-value=\"tenant.id == team.id\"\n            active-class=\"active\"\n            @click=\"handleSwitchTenant(team)\"\n          >\n            <v-list-item-content>\n              <v-list-item-title>\n                {{ team.name }}\n              </v-list-item-title>\n              <v-list-item-subtitle\n                v-if=\"tenant.id == team.id\"\n                class=\"utilGrayMid--text\"\n              >\n                Current\n              </v-list-item-subtitle>\n            </v-list-item-content>\n          </v-list-item>\n        </v-list>\n\n        <v-list\n          v-if=\"invitations && invitations.length > 0\"\n          :disabled=\"loading\"\n        >\n          <v-subheader>\n            <v-icon x-small class=\"mr-2\">\n              fas fa-envelope\n            </v-icon>\n            <div>Invitations</div>\n            <v-divider class=\"ml-4\" />\n          </v-subheader>\n          <v-list-item\n            v-for=\"invitation in invitations\"\n            :key=\"invitation.id\"\n            class=\"pl-4 py-2 disabled-list-item\"\n            :ripple=\"false\"\n          >\n            <v-list-item-content>\n              <AcceptConfirmInputRow\n                :label=\"invitation.tenant.name\"\n                :loading=\"loading\"\n                @accept=\"\n                  handleAcceptPendingInvitation(\n                    invitation.id,\n                    invitation.tenant.name,\n                    invitation.tenant.slug\n                  )\n                \"\n                @decline=\"\n                  handleDeclinePendingInvitation(\n                    invitation.id,\n                    invitation.tenant.name\n                  )\n                \"\n              />\n            </v-list-item-content>\n          </v-list-item>\n        </v-list>\n      </v-card>\n    </v-menu>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n/* stylelint-disable-next-line */\n.v-list-item--active::before {\n  opacity: 0 !important;\n}\n\n.team-switcher-list {\n  overflow: scroll;\n\n  .v-list {\n    padding: 0;\n  }\n\n  .v-list-item {\n    border-left: 10px solid rgba(0, 0, 0, 0.05);\n    cursor: pointer;\n\n    &.active {\n      background-color: var(--v-primaryLight-base) !important;\n      border-left: 10px solid var(--v-primaryDark-base);\n\n      /* stylelint-disable-next-line */\n      .v-list-item__title {\n        color: var(--v-primaryDark-base) !important;\n      }\n    }\n\n    &:hover:not(.disabled-list-item),\n    &:focus:not(.disabled-list-item) {\n      background-color: rgba(0, 0, 0, 0.05) !important;\n    }\n\n    &.disabled-list-item {\n      border-left: 10px solid var(--v-accentPink-base);\n      cursor: auto;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Nav/UserMenu.vue",
    "content": "<script>\nimport { mapGetters, mapMutations } from 'vuex'\nimport CurrentTime from '@/components/Nav/CurrentTime'\nimport { logout } from '@/auth/index.js'\n\nexport default {\n  components: {\n    CurrentTime\n  },\n  data() {\n    return {\n      loading: false,\n      model: false,\n      routes: [\n        {\n          title: 'Profile',\n          subtitle: 'Some details about what profile is',\n          route: {\n            name: 'profile'\n          }\n        },\n        {\n          title: 'Tokens',\n          subtitle: 'Some details about what user tokens are',\n          route: {\n            name: 'user-tokens'\n          }\n        }\n      ]\n    }\n  },\n  computed: {\n    ...mapGetters('auth', ['isAuthorized']),\n    ...mapGetters('user', ['user', 'oktaUser', 'isDark'])\n  },\n  methods: {\n    ...mapMutations('user', ['setUserSettings']),\n    async wipeClientAndLogout() {\n      this.loading = true\n\n      try {\n        await logout() // Pass true here to propagate this to all clients\n        document.querySelector('.router-view').style.opacity = 0\n      } catch {\n        this.loading = false\n      }\n    },\n    async toggleDarkMode() {\n      this.$vuetify.theme.dark = !this.$vuetify.theme.dark\n      localStorage.setItem('dark_mode', this.$vuetify.theme.dark.toString())\n      let settings = { isDark: this.$vuetify.theme.dark }\n      settings = { ...this.user.settings, ...settings }\n      this.setUserSettings(settings)\n\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/User/update-user-settings.gql'),\n          variables: {\n            input: settings\n          }\n        })\n        return true\n      } catch (error) {\n        this.handleAlert('error', 'Sorry, something went wrong!')\n        return false\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-menu\n    v-model=\"model\"\n    offset-y\n    data-cy=\"nav-bar-menu\"\n    transition=\"slide-y-transition\"\n    :close-on-content-click=\"false\"\n    nudge-bottom=\"15\"\n  >\n    <template #activator=\"{ on }\">\n      <v-scale-transition>\n        <v-btn\n          class=\"white ml-3 mr-1\"\n          large\n          icon\n          title=\"Open the user menu\"\n          v-on=\"on\"\n        >\n          <v-icon large color=\"grey\">\n            face\n          </v-icon>\n        </v-btn>\n      </v-scale-transition>\n    </template>\n\n    <v-sheet v-if=\"model\" width=\"300\" class=\"pt-6 text-center\">\n      <div class=\"text-center\">\n        <v-avatar size=\"64\" :tile=\"!oktaUser.picture\">\n          <img\n            :src=\"\n              oktaUser.picture ||\n                require('@/assets/logos/logomark-cerulean.svg')\n            \"\n            :alt=\"oktaUser.name\"\n          />\n        </v-avatar>\n\n        <div class=\"mt-2 text-h6\">\n          {{ user.first_name }} {{ user.last_name }}\n        </div>\n        <div class=\"text-caption\"> {{ user.email }} </div>\n      </div>\n\n      <div\n        v-ripple\n        class=\"mx-auto my-4 py-2 px-6 text-center rounded-lg d-inline-block cursor-pointer\"\n        style=\"border: 2px solid var(--v-secondaryGrayLight-base);\"\n        @click=\"$router.push({ name: 'profile' })\"\n      >\n        <div>\n          <v-icon x-small class=\"utilGrayDark--text\">\n            fad fa-cogs\n          </v-icon>\n          Account Settings\n        </div>\n        <div class=\"text-caption text--secondary text-truncate\">\n          Manage profile, API keys, and teams\n        </div>\n      </div>\n\n      <div class=\"text-caption mb-n2\">Theme (experimental)</div>\n      <div class=\"d-flex flex-row align-center justify-center\">\n        <span class=\"mx-3 sun cursor-pointer\" @click=\"toggleDarkMode()\"\n          ><v-icon size=\"36px\">fad fa-sun</v-icon></span\n        >\n        <v-switch v-model=\"isDark\" @change=\"toggleDarkMode()\"> </v-switch>\n        <span class=\"mx-3 moon cursor-pointer\" @click=\"toggleDarkMode()\"\n          ><v-icon size=\"36px\">fad fa-moon-stars</v-icon></span\n        >\n      </div>\n\n      <v-divider class=\"grey lighten-3 mx-auto my-2\" style=\"width: 50%;\" />\n\n      <current-time class=\"my-4 text-h4 text-center primary--text\" />\n      <!-- <v-divider class=\"grey lighten-3 mx-auto my-2\" style=\"width: 50%;\" /> -->\n\n      <div>\n        <!-- <MenuLink\n          v-for=\"r in routes\"\n          :key=\"r.title\"\n          :primary=\"r.title\"\n          :secondary=\"r.subtitle\"\n          :route=\"r.route\"\n        /> -->\n\n        <v-btn\n          class=\"appBackground text-capitalize py-6\"\n          depressed\n          block\n          :loading=\"loading\"\n          @click=\"wipeClientAndLogout\"\n        >\n          <span class=\"mr-2\">Sign out</span>\n          <i class=\"fad fa-sign-out\" />\n        </v-btn>\n      </div>\n    </v-sheet>\n  </v-menu>\n</template>\n\n<style lang=\"scss\" scoped>\n.sun .v-icon {\n  color: #ffd932;\n}\n\n.moon {\n  margin-top: -12px;\n\n  .v-icon {\n    color: #93c1e9;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/NavTabBar.vue",
    "content": "<script>\nimport ExternalLink from '@/components/ExternalLink'\n\nexport default {\n  components: {\n    ExternalLink\n  },\n  props: {\n    tabs: {\n      type: Array,\n      required: true\n    },\n    page: {\n      type: String,\n      required: false,\n      default: ''\n    },\n    paths: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    return {\n      pageScrolled: false\n    }\n  },\n  computed: {\n    mainTabs() {\n      return this.tabs.filter(tab => !tab.hidden && tab.align != 'right')\n    },\n    secondaryTabs() {\n      return this.tabs.filter(tab => !tab.hidden && tab.align === 'right')\n    },\n    tab: {\n      get() {\n        const route = this.tabs.find(\n          t => t.to?.path == this.$route.path || t.to?.name == this.$route.name\n        )\n\n        if (Object.keys(this.$route.query).length != 0) {\n          return Object.keys(this.$route.query)[0]\n        } else if (route) {\n          return route.to.path || route.to.name\n        }\n\n        return 'overview'\n      },\n      set(value) {\n        if (this.paths) return\n\n        const query = { [value]: null }\n\n        if (value && this.$route.query.version) {\n          query.version = this.$route.query.version\n        }\n\n        this.$router.replace({ query }).catch()\n      }\n    }\n  },\n  methods: {\n    scrolled() {\n      this.pageScrolled = window.scrollY > 30\n    }\n  }\n}\n</script>\n\n<template>\n  <v-tabs\n    v-model=\"tab\"\n    v-scroll=\"scrolled\"\n    class=\"mx-auto tabs-border-bottom tabs-border-top\"\n    :class=\"[\n      $vuetify.breakpoint.smAndDown ? 'tabs-hidden' : '',\n      pageScrolled ? 'elevation-4' : ''\n    ]\"\n  >\n    <v-tabs-slider color=\"blue\"></v-tabs-slider>\n    <template v-for=\"tb in mainTabs\">\n      <v-menu\n        v-if=\"tb.cardText\"\n        :key=\"tb.target || (tb.to && (tb.to.name || tb.to.path))\"\n        open-on-hover\n        :close-on-click=\"false\"\n        :open-on-click=\"false\"\n        :close-on-content-click=\"false\"\n        offset-y\n      >\n        <template #activator=\"{on}\">\n          <div\n            :style=\"tb.cardText && 'cursor: default; pointer-events: auto;'\"\n            v-on=\"on\"\n            @click.stop\n          >\n            <v-tab\n              :data-cy=\"`${page}-${tb.target}-tab`\"\n              :href=\"tb.target ? `#${tb.target}` : null\"\n              :to=\"tb.to ? tb.to : null\"\n              :class=\"{\n                'tabs-hidden': $vuetify.breakpoint.smAndDown,\n                'pr-2': tb.badgeText\n              }\"\n              style=\"height: 100%;\"\n              :disabled=\"tb.disabled\"\n              :hidden=\"tb.hidden\"\n            >\n              <v-icon left :size=\"tb.iconSize || 'medium'\">\n                {{ tb.icon }}\n              </v-icon>\n              {{ tb.name }}\n              <v-badge\n                v-if=\"tb.badgeText\"\n                color=\"codePink\"\n                class=\"text-none\"\n                :content=\"tb.badgeText\"\n                bottom\n                inline\n              ></v-badge>\n            </v-tab>\n          </div>\n        </template>\n        <v-card v-if=\"tb.cardText\" tile class=\"pa-0\" max-width=\"320\">\n          <v-card-title>\n            <v-badge\n              color=\"codePink\"\n              :content=\"tb.badgeText\"\n              bottom\n              bordered\n              inline\n            >\n              <v-icon left>{{ tb.icon }}</v-icon>\n              {{ tb.name }}\n            </v-badge>\n          </v-card-title>\n          <v-card-text>\n            <div>\n              {{ tb.cardText }}\n              <ExternalLink :href=\"tb.cardLink\">{{\n                tb.cardLinkText\n              }}</ExternalLink\n              >!\n            </div></v-card-text\n          >\n        </v-card>\n      </v-menu>\n      <v-tab\n        v-else\n        :key=\"tb.target || (tb.to && (tb.to.name || tb.to.path))\"\n        :data-cy=\"`${page}-${tb.target}-tab`\"\n        :href=\"tb.target ? `#${tb.target}` : null\"\n        :to=\"tb.to ? tb.to : null\"\n        :class=\"{\n          'tabs-hidden': $vuetify.breakpoint.smAndDown,\n          'pr-2': tb.badgeText\n        }\"\n        :disabled=\"tb.disabled\"\n      >\n        <v-icon left :size=\"tb.iconSize || 'medium'\">{{ tb.icon }}</v-icon>\n        {{ tb.name }}\n        <v-badge\n          v-if=\"tb.badgeText\"\n          :color=\"tb.badgeColor || 'accentPink'\"\n          class=\"text-none\"\n          :class=\"{ disabled: tb.disabled }\"\n          :content=\"tb.badgeText\"\n          bottom\n          inline\n        ></v-badge>\n      </v-tab>\n    </template>\n\n    <v-spacer />\n    <v-tab\n      v-for=\"tb in secondaryTabs\"\n      :key=\"tb.target\"\n      :data-cy=\"`${page}-${tb.target}-tab`\"\n      :href=\"`#${tb.target}`\"\n      :class=\"$vuetify.breakpoint.smAndDown ? 'tabs-hidden' : ''\"\n      :disabled=\"tb.disabled\"\n      :hidden=\"tb.hidden\"\n    >\n      <v-icon left :size=\"tb.iconSize || 'medium'\">{{ tb.icon }}</v-icon>\n      {{ tb.name }}\n    </v-tab>\n  </v-tabs>\n</template>\n"
  },
  {
    "path": "src/components/Parameters.vue",
    "content": "<script>\nimport jsBeautify from 'js-beautify'\n\nexport default {\n  props: {\n    hideTitle: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    missing: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    parameters: {\n      type: Array,\n      required: false,\n      default: () => []\n    }\n  },\n  computed: {},\n  methods: {\n    formatDefaultParamValue(defaultParamValue) {\n      return jsBeautify(JSON.stringify(defaultParamValue), {\n        indent_size: 2,\n        space_in_empty_paren: true,\n        preserve_newlines: false\n      })\n    },\n    paramIsArray(param) {\n      return Array.isArray(param)\n    },\n    paramIsObject(param) {\n      return (\n        typeof param === 'object' && param != null && !this.paramIsArray(param)\n      )\n    }\n  }\n}\n</script>\n\n<template>\n  <v-list class=\"pa-0 border-left border-radius-0\">\n    <v-list-item\n      v-for=\"param in parameters\"\n      :key=\"param.name\"\n      class=\"px-3\"\n      :two-line=\"param.required\"\n    >\n      <v-list-item-content>\n        <v-list-item-title v-if=\"!hideTitle\">\n          {{ param.name }}\n          <v-fade-transition>\n            <v-icon\n              v-if=\"param.required && missing.includes(param.name)\"\n              color=\"error\"\n              small\n            >\n              error\n            </v-icon>\n          </v-fade-transition>\n        </v-list-item-title>\n        <v-list-item-subtitle v-if=\"param.required\">\n          Required\n        </v-list-item-subtitle>\n        <v-list-item-subtitle>\n          Default:\n          {{\n            paramIsArray(param.default) || paramIsObject(param.default)\n              ? ''\n              : JSON.stringify(param.default)\n          }}\n        </v-list-item-subtitle>\n        <code\n          v-if=\"paramIsArray(param.default) || paramIsObject(param.default)\"\n          class=\"mt-3 pa-3 no-before-after-content code-custom\"\n          >{{ formatDefaultParamValue(param.default) }}</code\n        >\n      </v-list-item-content>\n    </v-list-item>\n  </v-list>\n</template>\n\n<style lang=\"scss\" scoped>\n.border-left {\n  border-left: 2px solid (var(--v-secondaryGrayLight-base));\n}\n\n.border-radius-0 {\n  border-radius: 0;\n}\n\n.code-custom {\n  background-color: var(--v-appBackground-base);\n  box-shadow: none;\n  color: var(--v-codeBlue-base);\n  font-size: 0.9em;\n}\n\n.no-before-after-content {\n  &::before,\n  &::after {\n    content: '' !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/ParametersForm.vue",
    "content": "<script>\nimport { parametersMixin } from '@/mixins/parametersMixin.js'\n\nexport default {\n  mixins: [parametersMixin],\n  props: {\n    parameter: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    return {\n      valid: false,\n      loading: false,\n      newType: '',\n      rules: {\n        typeCheck: value => this.checkInput(value) || this.errorMessage\n      },\n      errorMessage: ''\n    }\n  },\n  computed: {\n    defaultType: {\n      get() {\n        const param = this.parameter.defaultVal\n        if (Array.isArray(param)) return 'Array'\n        return typeof param\n      },\n      set(x) {\n        this.newType = x\n      }\n    },\n    inputVal: {\n      get() {\n        if (!this.parameter.defaultVal) return ''\n        // Prevents [Object object] or JSON as default entry for objects and stringified arrays\n        if (\n          typeof this.parameter.defaultVal == 'object' &&\n          !Array.isArray(this.parameter.defaultVal)\n        ) {\n          let stringObj = '{'\n          for (const [key, value] of Object.entries(\n            this.parameter.defaultVal\n          )) {\n            stringObj += key + ':' + value\n          }\n          stringObj += '}'\n          return stringObj\n        }\n        return this.parameter.defaultVal\n      },\n      set(x) {\n        this.newInputVal = x\n      }\n    }\n  },\n  methods: {\n    reset() {\n      this.$emit('cancel')\n    },\n    checkInput(val) {\n      if (val === this.inputVal) {\n        return false\n      }\n      const type = this.newType || this.defaultType\n      if (type === 'boolean') {\n        if (val?.toLowerCase() === 'true') {\n          this.valid = true\n          this.errorMessage = ''\n          return true\n        } else if (val?.toLowerCase() === 'false') {\n          this.valid = true\n          this.errorMessage = ''\n          return true\n        } else {\n          this.errorMessage = 'Invalid boolean'\n          this.valid = false\n          return false\n        }\n      }\n      if (type === 'object') {\n        if (val && val[0] !== '{') {\n          this.errorMessage = 'Invalid dictionary'\n          this.valid = false\n          return false\n        }\n        this.valid = true\n        this.errorMessage = ''\n        return true\n      }\n      this.valid = true\n      this.errorMessage = ''\n      return true\n    },\n    async setIndividualParam() {\n      const type = this.newType || this.defaultType\n      if (type === 'number') this.newInputVal = Number(this.newInputVal)\n      if (type === 'Array') {\n        if (!this.newInputVal) {\n          this.newInputVal = []\n        } else {\n          this.newInputVal = this.newInputVal\n            .replace('[', '')\n            .replace(']', '')\n            .split(',')\n          this.newInputVal = this.newInputVal.map(x =>\n            isNaN(x) ? x : Number(x)\n          )\n        }\n      }\n      if (type === 'boolean') {\n        if (this.newInputVal.toLowerCase() === 'true') {\n          this.newInputVal = true\n        } else if (this.newInputVal.toLowerCase() === 'false') {\n          this.newInputVal = false\n        } else {\n          this.setAlert({\n            alertShow: true,\n            alertMessage: 'Invalid boolean',\n            alertType: 'error'\n          })\n          return\n        }\n      }\n      if (type === 'object') {\n        if (!this.newInputVal || this.newInputVal == '{}') {\n          this.inputVal = {}\n        } else {\n          if (this.newInputVal[0] !== '{') {\n            this.setAlert({\n              alertShow: true,\n              alertMessage: 'Invalid dictionary',\n              alertType: 'error'\n            })\n            return\n          }\n          if (this.newInputVal[1] !== \"'\") {\n            const regex = /{|}/gi\n            const regex2 = /,/gi\n            const regex3 = /'/gi\n\n            const split = this.newInputVal\n              .replace(regex, '')\n              .replace(regex2, ':')\n              .replace(regex3, '')\n              .split(':')\n\n            const keys = {}\n            let key = ''\n            split.forEach((input, index) => {\n              if (index % 2 === 0) {\n                key = `${input}`.trim()\n                keys[key] = null\n              } else {\n                const value = isNaN(input) ? input : Number(input)\n                keys[key] = value\n              }\n            })\n            this.newInputVal = JSON.stringify(keys)\n            const test = this.validateJson()\n            if (test !== true) return\n            this.newInputVal = JSON.parse(this.newInputVal)\n          }\n        }\n      }\n      const parameterInputObj = JSON.parse(this.parameterInput)\n      const paramKey = this.parameter.name\n      const paramVal = this.newInputVal\n      parameterInputObj[paramKey] = paramVal\n      this.parameterInput = JSON.stringify(parameterInputObj)\n      await this.setDefaultParams()\n      this.reset()\n    },\n    validateJson() {\n      try {\n        // Treat empty or null inputs as valid\n        const testVal = Array.isArray(this.inputVal)\n          ? this.newInputVal[0]\n          : this.newInputVal\n        if (!testVal || (testVal && testVal.trim() === '')) {\n          return 'MissingError'\n        }\n        // Attempt to parse JSON and catch syntax errors\n        JSON.parse(testVal)\n        return true\n      } catch (err) {\n        if (err instanceof SyntaxError) {\n          // this.markJsonErrors(err)\n          return 'SyntaxError'\n        } else {\n          throw err\n        }\n      }\n    },\n    resetValidation() {\n      this.$refs.form.resetValidation()\n    }\n  }\n}\n</script>\n\n<template>\n  <v-col cols=\"12\">\n    <v-row align-end>\n      <v-text-field\n        ref=\"form\"\n        v-model=\"inputVal\"\n        class=\"mx-4\"\n        :type=\"newType || defaultType\"\n        :rules=\"[rules.typeCheck]\"\n      ></v-text-field>\n      <v-tooltip bottom>\n        <template #activator=\"{ on }\">\n          <div v-on=\"on\">\n            <v-select\n              data-public\n              v-model=\"defaultType\"\n              class=\"select mx-4\"\n              :items=\"[\n                { value: 'Array', text: 'List' },\n                { value: 'string', text: 'String' },\n                { value: 'object', text: 'Dictionary' },\n                { value: 'number', text: 'Integer' },\n                { value: 'boolean', text: 'Boolean' }\n              ]\"\n              @change=\"resetValidation()\"\n            />\n          </div>\n        </template>\n        <span\n          >Select the type that this parameter should be set to. (Defaults to\n          current parameter type).</span\n        >\n      </v-tooltip>\n      <v-btn depressed class=\"mr-4 mt-4\" @click=\"reset\">\n        Cancel\n      </v-btn>\n      <v-btn\n        color=\"primary\"\n        class=\"mt-4\"\n        :loading=\"loading\"\n        :disabled=\"!valid\"\n        @click=\"setIndividualParam(parameter)\"\n      >\n        Update\n      </v-btn>\n    </v-row>\n  </v-col>\n</template>\n\n<style scoped>\n.select {\n  width: 150px;\n}\n</style>\n"
  },
  {
    "path": "src/components/PaymentCard.vue",
    "content": "<script>\n// eslint-disable-next-line\nconst stripe = Stripe(process.env.VUE_APP_STRIPE_PUBLIC_TOKEN)\nlet elements = stripe.elements()\nlet card = undefined\nconst computedStyle = getComputedStyle(document.body)\nlet style = {\n  iconStyle: 'Solid',\n  base: {\n    outlineStyle: 'solid',\n    fontFamily: '\"Helvetica Neue\", Helvetica, sans-serif',\n    fontSmoothing: 'antialiased',\n    fontSize: '16px',\n    iconColor: computedStyle.getPropertyValue('--v-utilGrayMid-base'),\n    '::placeholder': {\n      color: computedStyle.getPropertyValue('--v-utilGrayMid-base')\n    }\n  },\n  invalid: {\n    color: computedStyle.getPropertyValue('--v-accentOrange-base'),\n    iconColor: computedStyle.getPropertyValue('--v-accentOrange-base')\n  },\n  focus: {\n    iconColor: computedStyle.getPropertyValue('--v-primary-base'),\n    borderColor: computedStyle.getPropertyValue('--v-primary-base')\n  }\n}\n\nconst elementClasses = {\n  focus: 'focused',\n  empty: 'empty',\n  invalid: 'invalid'\n}\n\nimport { teamProfileMixin } from '@/mixins/teamProfileMixin.js'\nimport { paymentMixin } from '@/mixins/paymentMixin.js'\nimport LogRocket from 'logrocket'\nimport { mapGetters, mapActions } from 'vuex'\n\nexport default {\n  components: {},\n  mixins: [teamProfileMixin, paymentMixin],\n  props: {\n    desiredUsers: {\n      type: Number,\n      required: false,\n      default: 0\n    },\n    diff: {\n      type: Number,\n      required: false,\n      default: 0\n    },\n    updateCard: {\n      type: Boolean,\n      required: true\n    },\n    updateUsers: {\n      type: Boolean,\n      required: true\n    }\n  },\n  data() {\n    return {\n      nameRules: [\n        v => !!v || 'Name is required',\n        v => v.length <= 20 || 'Name must be less than 20 characters'\n      ],\n      emailRules: [\n        v => !!v || 'E-mail is required',\n        v => /.+@.+/.test(v) || 'E-mail must be valid'\n      ],\n      valid: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['license', 'planType']),\n    ...mapGetters('user', ['user']),\n    disableButton() {\n      if (this.updateUsers)\n        return this.diff === 0 || (this.showPayment && !this.valid)\n      return !this.valid\n    },\n    showPayment() {\n      if (!this.existingCard || this.updateCard) return true\n      return false\n    }\n  },\n  mounted() {\n    if (!card) {\n      card = elements.create('card', {\n        iconStyle: 'solid',\n        style: style,\n        classes: elementClasses\n      })\n      if (this.updateCard) card.mount(this.$refs.card)\n      this.card = card\n    }\n  },\n  beforeDestroy() {\n    if (card) card.unmount()\n  },\n  updated() {\n    if (card && this.updateCard) card.mount(this.$refs.card)\n  },\n  methods: {\n    ...mapActions('license', ['getLicense']),\n    ...mapActions('alert', ['setAlert']),\n    ...mapActions('tenant', ['getTenants']),\n    ...mapActions('user', ['getUser']),\n    async checkForm() {\n      const options = {\n        owner: {\n          address: {\n            line1: this.updatedAddress ? this.updatedAddress : this.address\n          }\n        },\n        usage: 'reusable'\n      }\n      const result = await stripe.createSource(card, options)\n      if (result.error) {\n        // Inform the user if there was an error\n        this.cardError = result.error.message\n        this.loading = false\n        return\n      } else {\n        this.source = result.source\n        return true\n      }\n    },\n    async confirmAdd() {\n      this.loading = true\n      try {\n        const continueAdding = await this.checkForm()\n        if (continueAdding) {\n          const customer = await this.$apollo.mutate({\n            mutation: require('@/graphql/License/update-customer.gql'),\n            variables: {\n              email: this.updatedEmail ? this.updatedEmail : this.email,\n              name: this.updatedName ? this.updatedName : this.username,\n              source: this.source ? this.source.id : null\n            },\n            errorPolicy: 'all'\n          })\n          if (customer.data.update_stripe_customer.id) {\n            if (this.planType('FREE')) {\n              await this.$apollo.mutate({\n                mutation: require('@/graphql/License/create-usage-based-license.gql'),\n                variables: {\n                  input: {\n                    tenant_id: this.tenant.id,\n                    plan_name: 'STARTER_2021'\n                  }\n                }\n              })\n            }\n            this.setAlert({\n              alertShow: true,\n              alertMessage: 'Payment details updated.',\n              alertType: 'Success'\n            })\n            this.reset()\n          } else {\n            this.loading = false\n            this.cardError = customer.errors[0].message\n          }\n        }\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'payment card',\n            stage: 'update stripe customer'\n          }\n        })\n        this.loading = false\n        this.cardError = 'There was a problem adding your card information.'\n      }\n    },\n    async reset() {\n      this.$emit('close')\n      this.email = null\n      this.address = null\n      this.cardError = null\n      this.username = null\n\n      await this.getUser()\n\n      const tenantSlug = this.user.memberships.filter(\n        membership => membership.tenant.id === this.tenant.id\n      )?.tenant?.slug\n\n      if (tenantSlug) {\n        await this.setCurrentTenant(tenantSlug)\n      }\n      this.loading = false\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-card-text>\n      <v-form v-if=\"showPayment\" v-model=\"valid\">\n        <v-text-field\n          v-model=\"username\"\n          data-cy=\"full-name\"\n          outlined\n          :rules=\"nameRules\"\n          class=\"mt-3\"\n          prepend-inner-icon=\"face\"\n          label=\"Full Name\"\n          type=\"text\"\n          required\n        ></v-text-field>\n        <v-text-field\n          v-model=\"email\"\n          outlined\n          :rules=\"emailRules\"\n          prepend-inner-icon=\"email\"\n          label=\"Email\"\n          type=\"email\"\n          default=\"this.user.email\"\n          required\n        ></v-text-field>\n        <v-text-field\n          v-model=\"address\"\n          data-cy=\"address\"\n          outlined\n          prepend-inner-icon=\"home\"\n          label=\"Address\"\n          type=\"text\"\n          required\n        ></v-text-field>\n\n        <div ref=\"card\"> </div>\n\n        <div class=\"red--text\">\n          {{ cardError }}\n        </div>\n      </v-form>\n    </v-card-text>\n    <v-card-actions v-if=\"isTenantAdmin\">\n      <v-spacer></v-spacer>\n      <v-btn text @click=\"reset\">Cancel</v-btn>\n      <v-btn\n        v-if=\"updateUsers\"\n        color=\"primary\"\n        :disabled=\"disableButton\"\n        :loading=\"loading\"\n        @click=\"confirmAdd\"\n        >{{ upgradeOrDowngrade }}</v-btn\n      >\n      <v-btn\n        v-else\n        color=\"primary\"\n        :disabled=\"disableButton\"\n        :loading=\"loading\"\n        data-cy=\"save-payment\"\n        @click=\"confirmAdd\"\n        >Update</v-btn\n      >\n    </v-card-actions>\n  </div>\n</template>\n\n<style scoped>\n/*stylelint-disable */\n.StripeElement {\n  border: 1px solid;\n  border-radius: 4px;\n  height: 56px;\n\n  padding: 15px;\n}\n\n.StripeElement.focused {\n  border-color: var(--v-primary-base);\n  border-width: 2px;\n}\n\n.StripeElement.invalid {\n  border-color: var(--v-accentOrange-base);\n}\n\n.StripeElement.webkit-autofill {\n  background-color: var(--v-Queued-base) !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/PlanCard.vue",
    "content": "<script>\nimport { PLANS_2021 } from '@/utils/plans'\n\nexport default {\n  props: {\n    plan: {\n      required: true,\n      type: String\n    },\n    selected: {\n      required: false,\n      type: Boolean,\n      default: false\n    }\n  },\n  data() {\n    return {\n      plans: PLANS_2021\n    }\n  },\n  computed: {\n    activePlan() {\n      return this.plans[this.plan]\n    },\n    monthlyCost() {\n      if (this.activePlan.price == 'contact') {\n        return 'Contact Us'\n      }\n      return `$${this.activePlan.price}/month`\n    }\n  }\n}\n</script>\n<template>\n  <v-card class=\"pa-0\">\n    <div class=\"font-weight-light\">\n      {{ activePlan.name }}\n    </div>\n    <v-divider />\n    <!-- <h2>{{ activePlan.name }}</h2>\n    <v-list>\n      <v-list-item two-line>\n        <v-list-item-icon style=\"margin-left: 0;\"\n          ><v-icon\n            class=\"pi-flow-run\"\n            style=\"color: var(--v-primary-base);\"\n          ></v-icon\n        ></v-list-item-icon>\n        <span\n          style=\"flex-direction: column;\n        text-align: left;\"\n        >\n          <v-list-item-title\n            >{{ activePlan.taskRuns }} runs per month</v-list-item-title\n          >\n          <v-list-item-subtitle\n            >Additional runs start at ${{\n              activePlan.additionalCost\n            }}</v-list-item-subtitle\n          >\n        </span>\n      </v-list-item>\n      <v-list-item>\n        <v-list-item-icon\n          ><v-icon\n            class=\"fas fa-user\"\n            style=\"color: var(--v-primary-base);\"\n          ></v-icon></v-list-item-icon\n        >{{ activePlan.users }} users</v-list-item\n      >\n      <v-list-item>\n        <v-list-item-icon\n          ><v-icon\n            class=\"fas fa-history\"\n            style=\"color: var(--v-primary-base);\"\n          ></v-icon></v-list-item-icon\n        >1 {{ activePlan.history }} result history</v-list-item\n      >\n    </v-list>\n    <div class=\"text-h4 text-center\">{{ monthlyCost }}</div> -->\n  </v-card>\n</template>\n"
  },
  {
    "path": "src/components/Plans/CardDetails.vue",
    "content": "<script>\n// eslint-disable-next-line\nconst stripe = Stripe(process.env.VUE_APP_STRIPE_PUBLIC_TOKEN)\nlet elements = stripe.elements()\nlet card = undefined\nlet style = {\n  iconStyle: 'solid',\n  base: {\n    outlineStyle: 'solid',\n    fontFamily: '\"Helvetica Neue\", Helvetica, sans-serif',\n    fontSmoothing: 'antialiased',\n    fontSize: '16px',\n    iconColor: '#aaa',\n    '::placeholder': {\n      color: '#767676'\n    }\n  },\n  invalid: {\n    color: '#fa755a',\n    iconColor: '#fa755a'\n  }\n}\n\nconst elementClasses = {\n  focus: 'focused',\n  empty: 'empty',\n  invalid: 'invalid'\n}\n\nimport LogRocket from 'logrocket'\nimport { mapGetters, mapActions } from 'vuex'\n\nexport default {\n  components: {},\n  data() {\n    return {\n      cardError: '',\n      address: this.tenant?.stripe_customer?.sources?.data[0]?.owner?.address\n        ?.line1,\n      email: this.tenant?.stripe_customer?.email,\n      name: this.tenant?.stripe_customer?.name,\n      loading: false,\n      nameRules: [\n        v => !!v || 'Name is required',\n        v => v?.length <= 80 || 'Name must be less than 80 characters'\n      ],\n      emailRules: [\n        v => !!v || 'E-mail is required',\n        v => /.+@.+/.test(v) || 'E-mail must be valid'\n      ],\n      addressRules: [v => !!v || 'Address is required'],\n      valid: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['license']),\n    ...mapGetters('user', ['user']),\n    disabled() {\n      return !this.valid\n    }\n  },\n  mounted() {\n    if (!card) {\n      card = elements.create('card', {\n        style: style,\n        classes: elementClasses\n      })\n      card.mount(this.$refs.card)\n      this.card = card\n    }\n\n    this.email = this.tenant.stripe_customer?.email\n    this.name = this.tenant.stripe_customer?.name\n\n    this.address = this.tenant?.stripe_customer?.sources?.data[0]?.owner?.address?.line1\n\n    this.$nextTick(() => {\n      this.$refs['form']?.validate()\n    })\n  },\n  destroyed() {\n    // if (card) card.unmount()\n  },\n  updated() {\n    if (card) card.mount(this.$refs.card)\n  },\n  methods: {\n    ...mapActions('license', ['getLicense']),\n    ...mapActions('alert', ['setAlert']),\n    ...mapActions('tenant', ['getTenants']),\n    ...mapActions('user', ['getUser']),\n    async checkForm() {\n      const options = {\n        owner: {\n          name: this.name,\n          email: this.email,\n          address: {\n            line1: this.address\n          }\n        },\n        usage: 'reusable'\n      }\n\n      const result = await stripe.createSource(card, options)\n      if (result.error) {\n        // Inform the user if there was an error\n        this.cardError = result.error.message\n        this.loading = false\n        return\n      } else {\n        this.source = result.source\n        return true\n      }\n    },\n    async confirm() {\n      this.loading = true\n      try {\n        const continueAdding = await this.checkForm()\n        if (continueAdding) {\n          const customer = await this.$apollo.mutate({\n            mutation: require('@/graphql/License/update-customer.gql'),\n            variables: {\n              email: this.email,\n              name: this.name,\n              source: this.source ? this.source.id : null\n            },\n            errorPolicy: 'all'\n          })\n          if (!customer.data.update_stripe_customer.id) {\n            this.loading = false\n            this.cardError = customer.errors[0].message\n          }\n\n          this.$emit('confirm', this.source.id)\n        }\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'payment card',\n            stage: 'update stripe customer'\n          }\n        })\n        this.loading = false\n        this.cardError = 'There was a problem adding your card information.'\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"card-form d-flex align-center justify-center flex-column\">\n    <v-form ref=\"form\" v-model=\"valid\" class=\"my-auto\">\n      <v-text-field\n        v-model=\"name\"\n        data-cy=\"full-name\"\n        outlined\n        :rules=\"nameRules\"\n        class=\"mt-3\"\n        label=\"Name\"\n        type=\"text\"\n        :value=\"name\"\n        required\n        validate-on-blur\n      >\n        <template #prepend-inner>\n          <span>\n            <v-icon>\n              fad fa-smile fa-fw\n            </v-icon>\n          </span>\n        </template>\n      </v-text-field>\n      <v-text-field\n        v-model=\"email\"\n        outlined\n        :rules=\"emailRules\"\n        label=\"Email\"\n        type=\"email\"\n        required\n        validate-on-blur\n      >\n        <template #prepend-inner>\n          <span>\n            <v-icon>\n              fad fa-envelope fa-fw\n            </v-icon>\n          </span>\n        </template>\n      </v-text-field>\n\n      <v-text-field\n        v-model=\"address\"\n        data-cy=\"address\"\n        outlined\n        :rules=\"addressRules\"\n        label=\"Address\"\n        type=\"text\"\n        required\n        validate-on-blur\n      >\n        <template #prepend-inner>\n          <span>\n            <v-icon>\n              fad fa-map-marker-alt fa-fw\n            </v-icon>\n          </span>\n        </template>\n      </v-text-field>\n\n      <div ref=\"card\"> </div>\n\n      <div class=\"red--text\">\n        {{ cardError }}\n      </div>\n    </v-form>\n\n    <v-btn\n      color=\"prefect\"\n      class=\"mt-auto white--text\"\n      :disabled=\"loading || !valid\"\n      :loading=\"loading\"\n      data-cy=\"save-payment\"\n      @click=\"confirm\"\n    >\n      {{ loading ? 'Submitting' : 'Confirm' }}\n    </v-btn>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.card-form {\n  height: 100% !important;\n\n  form,\n  button {\n    width: 100%;\n  }\n}\n\n/*stylelint-disable */\n.StripeElement {\n  background-color: white;\n\n  height: 56px;\n  padding: 15px;\n  position: relative;\n  transition: box-shadow 150ms ease;\n\n  &:before {\n    border: 1px solid rgba(0, 0, 0, 0.42);\n    border-radius: 4px;\n    content: '';\n    height: 100%;\n    left: 0;\n    position: absolute;\n    top: 0;\n    transition: all 50ms;\n    user-select: none;\n    width: 100%;\n  }\n\n  &:hover {\n    &:before {\n      border-color: #000;\n    }\n  }\n}\n\n.StripeElement--focus {\n  box-shadow: 0 1px 3px 0 #cfd7df;\n}\n\n.StripeElement--invalid {\n  border-color: #fa755a;\n}\n\n.StripeElement--webkit-autofill {\n  background-color: #fefde5 !important;\n}\n\n.focused {\n  &:before {\n    border: 2px solid var(--v-primary-base) !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Plans/Enterprise.vue",
    "content": "<template>\n  <div class=\"plan-card blue-grey darken-3 white--text rounded elevation-3\">\n    <div class=\"font-weight-regular text-center py-8 plan-title\">\n      Enterprise\n    </div>\n\n    <v-divider class=\"divider-light\" />\n    <div\n      class=\"text-h6 text-md-subtitle-1 text-lg-h6 font-weight-regular text-center\"\n    >\n      <div class=\"px-4\">\n        <div class=\"mt-4\">\n          Built for your business\n\n          <div class=\"mt-2 font-weight-light\">\n            Get in touch to build your Prefect Cloud\n          </div>\n        </div>\n\n        <div\n          class=\"my-12 my-md-8 my-lg-12 d-flex align-center justify-center flex-column\"\n        >\n          <div class=\"plan-table\">\n            <div class=\"py-2 px-3\">100+ users</div>\n            <div class=\"py-2 px-3\">Audit trail</div>\n            <div class=\"py-2 px-3\">Custom RBAC / SSO</div>\n            <div class=\"py-2 px-3\">6+ months history</div>\n          </div>\n        </div>\n      </div>\n      <a\n        class=\"plan-cta plan-cta-dark py-7 mt-12 mt-md-8 mt-lg-12 d-flex align-center justify-center\"\n        href=\"https://www.prefect.io/pricing#contact\"\n        target=\"_blank\"\n      >\n        Contact Us\n        <v-icon class=\"mb-1\" color=\"grey lighten-2\">arrow_right</v-icon>\n      </a>\n    </div>\n  </div>\n</template>\n\n<script>\nexport default {}\n</script>\n\n<style lang=\"scss\" scoped>\n.plan-card {\n  height: min-content;\n  overflow: hidden;\n  transition: all 150ms;\n  width: 425px;\n\n  .plan-title {\n    font-size: 1.15rem;\n    letter-spacing: 0.15rem;\n    text-transform: uppercase;\n  }\n\n  .divider-dark {\n    border-color: #eee;\n  }\n\n  .divider-light {\n    border-color: #3f515a;\n  }\n\n  .plan-body {\n    font-weight: 400 !important;\n    margin: auto;\n    max-width: 350px;\n    width: max-content;\n  }\n\n  .plan-feature-icon {\n    align-items: center;\n    display: inline-flex;\n    height: 20px;\n    justify-content: center;\n    width: 20px;\n  }\n\n  .plan-cent {\n    font-size: 3rem !important;\n    vertical-align: middle;\n  }\n\n  .plan-table {\n    column-gap: 2px;\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    row-gap: 2px;\n\n    div {\n      background-color: #455a64;\n    }\n  }\n\n  .plan-cta {\n    background-color: #f7fcfd;\n    color: inherit !important;\n    cursor: pointer;\n    display: block;\n    font-size: 1rem;\n    letter-spacing: 0.15rem;\n    text-decoration: none;\n    text-transform: uppercase;\n    transition: all 50ms;\n\n    &.plan-cta-dark {\n      background-color: #546e7a;\n\n      &:focus,\n      &:hover {\n        background-color: #5a7581 !important;\n        color: #fff;\n      }\n    }\n\n    &:focus,\n    &:hover {\n      background-color: #e9f7fc !important;\n      font-weight: 500 !important;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Plans/PlanSelectionForm.vue",
    "content": "<script>\nimport LogRocket from 'logrocket'\nimport { mapGetters, mapActions } from 'vuex'\nimport CardDetails from '@/components/Plans/CardDetails'\nimport ExternalLink from '@/components/ExternalLink'\n\nimport { PLANS_2021 } from '@/utils/plans'\n\nexport default {\n  components: {\n    CardDetails,\n    ExternalLink\n  },\n  props: {\n    planReference: {\n      type: String,\n      required: true\n    }\n  },\n  data() {\n    return {\n      paymentSource: null,\n      loading: false,\n      step: 'select-card'\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license']),\n    ...mapGetters('tenant', ['tenant']),\n    plan() {\n      return PLANS_2021[this.planReference]\n    },\n    payments() {\n      return this.tenant?.stripe_customer?.sources?.data\n    },\n    title() {\n      let title\n      switch (this.step) {\n        case 'select-card':\n          title = 'Confirm your payment details'\n          break\n        case 'add-card':\n          title = 'Add a new payment method'\n          break\n        case 'confirm':\n          title = 'Summary'\n          break\n        case 'complete':\n          title = ''\n          break\n        case 'error':\n        default:\n          title = 'Oops'\n          break\n      }\n      return title\n    }\n  },\n  mounted() {\n    this.getTenants()\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    ...mapActions('license', ['getLicense']),\n    ...mapActions('tenant', ['getTenants']),\n    async updatePlan() {\n      this.loading = true\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/License/create-usage-based-license.gql'),\n          variables: {\n            input: {\n              tenant_id: this.tenant.id,\n              plan_name: this.plan.value\n            }\n          }\n        })\n        if (data.create_self_serve_usage_license.id) {\n          await this.getLicense()\n          await this.getTenants()\n        }\n      } catch (e) {\n        this.error = true\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Plan selection',\n            stage: 'Create usage based license'\n          }\n        })\n      } finally {\n        this.loading = false\n      }\n    },\n    handleConfirm(sourceId) {\n      this.paymentSource = sourceId\n      this.setStep('confirm')\n    },\n    handleNext() {\n      if (this.paymentSource == 'new') {\n        this.setStep('add-card')\n      } else {\n        this.setStep('confirm')\n      }\n    },\n    selectPayment(id) {\n      this.paymentSource = id\n    },\n    setStep(step) {\n      this.step = step\n\n      if (step == 'select-card') {\n        this.getTenants()\n      }\n    },\n    async handleSubmit() {\n      await this.updatePlan()\n      if (!this.error) {\n        this.$emit('complete')\n        this.setStep('complete')\n      } else {\n        this.setStep('error')\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"form-container blue-grey--text text--darken-2 white rounded elevation-8 pa-8\"\n  >\n    <div class=\"text-h4 font-weight-light\">\n      {{ title }}\n    </div>\n\n    <div key=\"card-form-container\" class=\"card-container\">\n      <v-fade-transition mode=\"out-in\">\n        <div\n          v-if=\"step == 'add-card'\"\n          key=\"add-card\"\n          class=\"card-entry-container\"\n        >\n          <div\n            class=\"d-inline-block text-subtitle-1 font-weight-light mx-auto cursor-pointer mt-4 h-auto\"\n            @click=\"setStep('select-card')\"\n          >\n            <v-icon color=\"blue-grey\">chevron_left</v-icon>\n            Choose an existing method instead\n          </div>\n\n          <div style=\"height: 559px;\">\n            <CardDetails @confirm=\"handleConfirm\" />\n          </div>\n        </div>\n\n        <div\n          v-else-if=\"step == 'select-card'\"\n          key=\"select-card\"\n          class=\"card-selection d-flex align-center justify-center flex-column\"\n        >\n          <div\n            class=\"card-display mt-auto\"\n            :class=\"{ active: paymentSource == 'new' }\"\n            @click.stop=\"selectPayment('new')\"\n          >\n            <div class=\"text-h6 font-weight-light\">\n              Add new card\n            </div>\n          </div>\n\n          <div\n            v-if=\"payments && payments.length\"\n            class=\"card-or text-center my-8\"\n          >\n            <div class=\"d-inline-block position-relative white py-2 px-8\">\n              OR\n            </div>\n          </div>\n\n          <div\n            v-for=\"payment in payments\"\n            :key=\"payment.id\"\n            :class=\"{ active: paymentSource == payment.id }\"\n            class=\"card-display mb-auto d-flex align-center justify--start\"\n            @click=\"selectPayment(payment.id)\"\n          >\n            <div v-if=\"payment.type == 'card'\">\n              <div class=\"mb-auto d-flex align-center justify--start\">\n                <div>\n                  <div v-if=\"payment.owner\" class=\"text-h5 font-weight-light\">\n                    {{ payment.owner.name }}\n                  </div>\n                  <div v-if=\"payment.card\" class=\"mt-1\">\n                    <div class=\"text-subtitle-1\">\n                      {{ payment.brand || payment.card.brand }}\n                    </div>\n\n                    <div class=\"mt-n2\">\n                      <span class=\"text-h6 font-weight-regular\">\n                        •••• •••• •••• {{ payment.last4 || payment.card.last4 }}\n                      </span>\n                      <span\n                        v-if=\"payment.exp_month || payment.card\"\n                        class=\"ml-1 text-subtitle-1 font-weight-light\"\n                      >\n                        {{ payment.exp_month || payment.card.exp_month }}/{{\n                          payment.exp_year || payment.card.exp_year\n                        }}\n                      </span>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n\n            <div v-else-if=\"payment.type == 'ach_credit_transfer'\">\n              <div class=\"mb-auto d-flex align-center justify--start\">\n                <div>\n                  <div v-if=\"payment.owner\" class=\"text-h5 font-weight-light\">\n                    {{ payment.owner.name }}\n                  </div>\n                  <div class=\"mt-1\">\n                    <div class=\"text-subtitle-1\">\n                      {{ payment.ach_credit_transfer.bank_name }}\n                    </div>\n\n                    <div class=\"mt-n2\">\n                      <div class=\"text-h6 font-weight-regular\">\n                        ••••••••••••\n                        {{\n                          payment.ach_credit_transfer.account_number &&\n                            payment.ach_credit_transfer.account_number.substring(\n                              payment.ach_credit_transfer.account_number\n                                .length - 4\n                            )\n                        }}\n                      </div>\n                      <div class=\"text-subtitle-1 font-weight-light\">\n                        ••••••••••••\n                        {{\n                          payment.ach_credit_transfer.routing_number &&\n                            payment.ach_credit_transfer.routing_number.substring(\n                              payment.ach_credit_transfer.routing_number\n                                .length - 4\n                            )\n                        }}\n                      </div>\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n\n            <div v-else-if=\"payment.type == 'ach_debit'\">\n              <div class=\"mb-auto d-flex align-center justify--start\">\n                <div v-if=\"payment.owner\" class=\"text-h5 font-weight-light\">\n                  {{ payment.owner.name }}\n                </div>\n\n                <div class=\"mt-1\">\n                  <div class=\"text-subtitle-1\">\n                    {{ payment.ach_debit.bank_name }}\n                  </div>\n\n                  <div class=\"mt-n2\">\n                    <div\n                      v-if=\"payment.ach_debit.account_number\"\n                      class=\"text-h6 font-weight-regular\"\n                    >\n                      ••••••••••••\n                      {{\n                        payment.ach_debit.account_number.substring(\n                          payment.ach_debit.account_number.length - 4\n                        )\n                      }}\n                    </div>\n                    <div\n                      v-if=\"payment.ach_debit.routing_number\"\n                      class=\"text-subtitle-1 font-weight-light\"\n                    >\n                      ••••••••••••\n                      {{\n                        payment.ach_debit.routing_number.substring(\n                          payment.ach_debit.routing_number.length - 4\n                        )\n                      }}\n                    </div>\n                  </div>\n                </div>\n              </div>\n            </div>\n\n            <div v-if=\"payment.type == 'card' && payment.card\" class=\"ml-auto\">\n              <v-icon large>\n                fab fa-cc-{{ payment.card.brand.toLowerCase() }}\n              </v-icon>\n            </div>\n\n            <div\n              v-else-if=\"\n                payment.type == 'ach_debit' ||\n                  payment.type == 'ach_credit_transfer'\n              \"\n              class=\"ml-auto\"\n            >\n              <v-icon large>\n                fad fa-university\n              </v-icon>\n            </div>\n          </div>\n\n          <v-btn\n            color=\"prefect\"\n            class=\"mt-auto white--text\"\n            :disabled=\"loading || !paymentSource\"\n            :loading=\"loading\"\n            style=\"width: 100%;\"\n            data-cy=\"next\"\n            @click=\"handleNext\"\n          >\n            Next\n          </v-btn>\n        </div>\n\n        <div\n          v-else-if=\"step == 'confirm'\"\n          key=\"confirm\"\n          class=\"confirm-container d-flex align-start justify-center flex-column\"\n        >\n          <div\n            class=\"d-inline-block text-subtitle-1 font-weight-light cursor-pointer mt-4 h-auto\"\n            @click=\"setStep('select-card')\"\n          >\n            <v-icon color=\"blue-grey\">chevron_left</v-icon>\n            Change payment method\n          </div>\n\n          <div class=\"text-left mt-auto w-100\">\n            <div\n              class=\"text-h4 font-weight-light d-flex align-end justify-start\"\n            >\n              <span>Plan</span>\n              <span class=\"flex-grow-1 dotted-line mx-2 mb-1\" />\n              <span class=\"text-subtitle-1 ml-auto white--text plan-title\">\n                {{ plan.name }}\n              </span>\n            </div>\n            <div class=\"mt-4 text-h6 font-weight-light\">\n              <div class=\"mt-4 d-flex align-end justify-start\">\n                <span>Users</span>\n                <span class=\"flex-grow-1 dotted-line mx-2 mb-1\" />\n                <span class=\"mr-3 font-weight-regular\">\n                  {{ plan.users }}\n                </span>\n                <span class=\"plans-feature-icon align-self-center\">\n                  <v-icon small>\n                    fad fa-users fa-fw\n                  </v-icon>\n                </span>\n              </div>\n\n              <div class=\"mt-6 d-flex align-end justify-start\">\n                <span>Run history</span>\n                <span class=\"flex-grow-1 dotted-line mx-2 mb-1\" />\n                <span class=\"mr-3 font-weight-regular\">\n                  1 {{ plan.history }}\n                </span>\n                <span class=\"plans-feature-icon align-self-center\">\n                  <v-icon small>\n                    fad fa-history fa-fw\n                  </v-icon>\n                </span>\n              </div>\n\n              <div\n                v-if=\"plan.taskRuns\"\n                class=\"mt-6 d-flex align-end justify-start\"\n              >\n                <span>Free runs</span>\n                <span class=\"flex-grow-1 dotted-line mx-2 mb-1\" />\n                <span class=\"mr-3 font-weight-regular text-right mb-n2\">\n                  <span>\n                    {{ plan.taskRuns.toLocaleString() }}\n                    <div class=\"text-caption mt-n2\">\n                      / month\n                    </div>\n                  </span>\n                </span>\n\n                <span class=\"plans-feature-icon align-self-center\">\n                  <v-icon small>\n                    fad fa-lightbulb fa-fw\n                  </v-icon>\n                </span>\n              </div>\n\n              <div\n                v-if=\"plan.price\"\n                class=\"mt-6 d-flex align-end justify-start\"\n              >\n                <span>Price per additional run</span>\n                <span class=\"flex-grow-1 dotted-line mx-2 mb-1\" />\n                <span class=\"mr-3 font-weight-regular text-right mb-n2\">\n                  <span>\n                    ${{ plan.price }}\n                    <div class=\"text-caption mt-n2\">\n                      / successful task run\n                    </div>\n                  </span>\n                </span>\n\n                <span class=\"plans-feature-icon align-self-center\">\n                  <v-icon small>\n                    fad fa-tasks fa-fw\n                  </v-icon>\n                </span>\n              </div>\n\n              <div\n                class=\"mt-6 font-weight-light d-flex align-end justify-start\"\n              >\n                <span>Volume discounts</span>\n                <span class=\"flex-grow-1 mx-2 mb-1 dotted-line\" />\n                <span class=\"mr-3 font-weight-regular mb-n2\"\n                  >Automatic\n                  <div class=\"text-caption mt-n2\">\n                    applied monthly\n                  </div>\n                </span>\n                <span\n                  class=\"plans-feature-icon feature-green align-self-center\"\n                >\n                  <v-icon small>\n                    fad fa-check fa-fw\n                  </v-icon>\n                </span>\n              </div>\n            </div>\n          </div>\n\n          <div class=\"mt-8 text-h5 font-weight-light text-right w-100\">\n            Due today:\n            <span class=\"font-weight-medium\"\n              >${{ plan.additionalCost ? plan.additionalCost : '0.00' }}</span\n            >\n          </div>\n\n          <v-btn\n            color=\"prefect\"\n            class=\"mt-auto white--text w-100\"\n            :disabled=\"loading || !paymentSource\"\n            :loading=\"loading\"\n            data-cy=\"finish\"\n            @click=\"handleSubmit\"\n          >\n            Finish\n          </v-btn>\n\n          <div class=\"text-caption mb-n4 mt-2 mx-auto\">\n            By clicking finish, you assert that you have read & agree to the\n            <ExternalLink\n              href=\"https://www.prefect.io/legal/terms-and-conditions\"\n              >Terms & Conditions</ExternalLink\n            >\n          </div>\n        </div>\n\n        <div\n          v-else-if=\"step == 'complete'\"\n          key=\"complete\"\n          class=\"complete-container d-flex align-start justify-center flex-column\"\n        >\n          <div class=\"mt-auto text-h4 font-weight-light w-100 text-center\">\n            You're all set - happy engineering!\n            <img\n              class=\"mt-8 mx-auto\"\n              src=\"@/assets/backgrounds/your-flow-runs.svg\"\n              alt=\"You're all set image\"\n            />\n          </div>\n\n          <v-btn\n            color=\"prefect\"\n            class=\"mt-auto white--text w-100\"\n            :href=\"`/${tenant.slug}`\"\n          >\n            Go to the dashboard\n          </v-btn>\n        </div>\n\n        <div v-else key=\"error\" class=\"error-container\">\n          Something went wrong...\n        </div>\n      </v-fade-transition>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.form-container {\n  height: min-content;\n  max-width: 600px;\n  overflow: hidden;\n  transition: max-height 150ms;\n  width: 600px;\n}\n\n.form-actions {\n  min-height: 36px;\n}\n\n.h-auto {\n  height: auto !important;\n}\n\n.card-container {\n  position: relative;\n  transition: all 150ms;\n\n  .card-selection {\n    min-height: 600px;\n  }\n\n  .card-display {\n    border: 2px solid #efefef;\n    border-radius: 4px;\n    box-sizing: content-box;\n    cursor: pointer;\n    height: auto;\n    padding: 24px 24px 24px 48px;\n    position: relative;\n    text-align: left;\n    transition: all 50ms;\n    user-select: none;\n    width: 400px;\n\n    &.active {\n      border: 2px solid var(--v-primary-base);\n\n      &::before {\n        border-color: var(--v-primary-base);\n      }\n\n      &::after {\n        background-color: var(--v-primary-base);\n        border-radius: 50%;\n        height: 10px;\n        left: 17px;\n        width: 10px;\n      }\n    }\n\n    &::after,\n    &::before {\n      box-sizing: border-box;\n      content: '';\n      position: absolute;\n      top: 50%;\n      transform: translate(0, -50%);\n      transition: all 150ms;\n    }\n\n    &::after {\n      border-radius: 0;\n      height: 0;\n      left: 22px;\n      width: 0;\n    }\n\n    &::before {\n      border: 2px solid #eee;\n      border-radius: 50%;\n      height: 20px;\n      left: 12px;\n      width: 20px;\n    }\n  }\n\n  .card-or {\n    position: relative;\n    width: 100%;\n\n    &::before {\n      background-color: #eee;\n      content: '';\n      height: 1px;\n      left: 0;\n      position: absolute;\n      top: 50%;\n      transform: translate(0, -50%);\n      width: 100%;\n    }\n  }\n}\n\n.confirm-container,\n.complete-container,\n.error-container,\n.card-entry-container {\n  min-height: 600px;\n}\n\n.dotted-line {\n  border-top: 2px dotted #eee;\n}\n\n.h-100 {\n  height: 100%;\n}\n\n.w-100 {\n  width: 100%;\n}\n\n.theme--light.v-subheader {\n  color: #000;\n  font-weight: bold !important;\n}\n\n.checkbox-container {\n  margin-left: 30px;\n  margin-top: -20px;\n}\n/* stylelint-disable */\n.set-state .v-btn__loader {\n  color: #fff;\n}\n\n.card-title {\n  margin-left: -12px;\n  margin-top: -10px;\n  margin-bottom: 10px;\n}\n\n.plan-title {\n  background-color: var(--v-primary-base);\n  border-radius: 6px;\n  letter-spacing: 0.15rem;\n  padding: 0 8px;\n  text-transform: uppercase;\n}\n</style>\n"
  },
  {
    "path": "src/components/Plans/Standard.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport MenuTooltip from '@/components/MenuTooltip'\n\nexport default {\n  components: {\n    MenuTooltip\n  },\n  props: {\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    hideDetails: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    }\n  },\n  data() {\n    return {\n      volumeDiscounts: [\n        { runs: '20,000', price: 'Free' },\n        { runs: '100,000', price: '$0.0050' },\n        { runs: '1,000,000', price: '$0.0025' },\n        { runs: '10,000,000', price: '$0.00125' },\n        { runs: '100,000,000', price: '$0.000625' },\n        { runs: '...and up', price: '', final: true }\n      ]\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license', 'planType'])\n  },\n  methods: {\n    select() {\n      if (this.planType('STANDARD') || this.disabled) return\n      this.$emit('click')\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"plan-card white rounded elevation-7\">\n    <div\n      class=\"font-weight-regular secondaryGrayDark--text text-center py-8 plan-title\"\n    >\n      Standard\n      <div v-if=\"!hideDetails\" class=\"text-body-1 prefect--text text-none\">\n        Recommended\n      </div>\n    </div>\n    <v-divider class=\"divider-dark\" />\n    <div\n      class=\"text-h6 text-md-subtitle-1 text-lg-h6 font-weight-regular text-center\"\n    >\n      <div class=\"px-4\">\n        <MenuTooltip hide-close>\n          <template #activator>\n            <div\n              class=\"mt-12 ml-10 text-h2 font-weight-regular blue-grey--text text--darken-3 plan-task-run-price d-flex align-center justify-center\"\n            >\n              <span class=\"mr-2 font-weight-light d-inline-block plan-cent\">\n                $ </span\n              >0.0050\n\n              <span class=\"mx-1 font-weight-light text-h5 align-self-end mr-n1\"\n                >/\n              </span>\n              <div\n                class=\"ml-2 font-weight-light text-body-2 align-self-end text-left\"\n              >\n                <div>successful</div>\n                <div style=\"margin-top: -6px;\">\n                  <span>\n                    task run\n                  </span>\n                </div>\n              </div>\n            </div>\n\n            <div class=\"font-weight-regular\">\n              +\n\n              <a class=\"accentPink--text volume-link\"\n                >automatic volume discounts</a\n              >\n            </div></template\n          >\n          <div>\n            <div class=\"text-h6 font-weight-regular\">\n              Only pay for successful runs.\n            </div>\n            <div class=\"mt-4 text-subtitle-1 font-weight-light\">\n              There's no charge for retries, failures, or any task that runs in\n              less than one second.\n            </div>\n            <div class=\"mt-4 text-subtitle-1 font-weight-light\">\n              As usage increases each month, the price per run automatically\n              drops:\n            </div>\n            <div class=\"mt-4 text-subtitle-1 font-weight-light\">\n              <v-simple-table dense>\n                <thead>\n                  <tr>\n                    <th class=\"text-left font-weight-light text-subtitle-1\">\n                      Monthly run tier\n                    </th>\n                    <th class=\"text-left font-weight-light text-subtitle-1\">\n                      Price per run\n                    </th>\n                  </tr>\n                </thead>\n                <tbody>\n                  <tr v-for=\"(item, i) in volumeDiscounts\" :key=\"item.runs\">\n                    <td class=\"font-weight-light\">\n                      <span v-if=\"i == 0\" class=\"text-subtitle-1\"\n                        >0 <span class=\"text-caption\">to </span></span\n                      >\n\n                      <span\n                        v-if=\"i !== 0 && i !== volumeDiscounts.length - 1\"\n                        class=\"text-caption\"\n                        >then to\n                      </span>\n\n                      <span class=\"text-subtitle-1\">{{ item.runs }}</span>\n                    </td>\n                    <td class=\"text-subtitle-1 font-weight-light\">{{\n                      item.price\n                    }}</td>\n                  </tr>\n                </tbody>\n              </v-simple-table>\n            </div>\n          </div>\n        </MenuTooltip>\n\n        <div\n          class=\"my-12 my-md-8 my-lg-12 text-left plan-body d-flex align-start justify-center flex-column secondaryGrayDark--text\"\n        >\n          <div class=\"d-flex align-center justify-center\">\n            <span class=\"rounded-circle plans-feature-icon\">\n              <v-icon small>\n                fad fa-tasks\n              </v-icon>\n            </span>\n            <span class=\"ml-2\">\n              20,000 free runs every month\n            </span>\n          </div>\n\n          <div class=\"mt-3 d-flex align-center justify-center\">\n            <span class=\"rounded-circle plans-feature-icon\">\n              <v-icon small>\n                fad fa-users\n              </v-icon>\n            </span>\n            <span class=\"ml-2\">\n              Up to 3 users\n            </span>\n          </div>\n\n          <div class=\"mt-3 d-flex align-center justify-center\">\n            <span class=\"rounded-circle plans-feature-icon\">\n              <v-icon small>\n                fad fa-history\n              </v-icon>\n            </span>\n            <span class=\"ml-2\">\n              2 weeks of run history\n            </span>\n          </div>\n\n          <div class=\"mt-3 d-flex align-center justify-center\">\n            <span class=\"rounded-circle plans-feature-icon\">\n              <v-icon small>\n                fad fa-siren-on\n              </v-icon>\n            </span>\n            <span class=\"ml-2\">Workflow and infrastructure SLAs</span>\n          </div>\n\n          <div class=\"mt-3 d-flex align-center justify-center\">\n            <span class=\"rounded-circle plans-feature-icon\">\n              <v-icon small>\n                fad fa-random\n              </v-icon>\n            </span>\n            <span class=\"ml-2\">Automation suite</span>\n          </div>\n        </div>\n      </div>\n      <div v-if=\"hideDetails\" class=\"py-7 mt-8 mt-md-6 mt-lg-8 o-0\">\n        {{\n          planType('STANDARD')\n            ? 'Current'\n            : disabled\n            ? 'Contact your team admin to upgrade'\n            : 'Start free'\n        }}\n      </div>\n\n      <div\n        v-else\n        class=\"plan-cta py-7 mt-8 mt-md-6 mt-lg-8\"\n        :class=\"{ 'cursor-pointer': !planType('STANDARD') }\"\n        @click=\"select\"\n      >\n        {{\n          planType('STANDARD')\n            ? 'Current'\n            : disabled\n            ? 'Contact your team admin to upgrade'\n            : 'Start free'\n        }}\n      </div>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.plan-card {\n  height: min-content;\n  overflow: hidden;\n  transition: all 150ms;\n  width: 450px;\n\n  .plan-title {\n    font-size: 1.25rem;\n    letter-spacing: 0.2rem;\n    text-transform: uppercase;\n  }\n\n  .divider-dark {\n    border-color: #eee;\n  }\n\n  .divider-light {\n    border-color: #3f515a;\n  }\n\n  .plan-body {\n    // font-size: 1.2rem !important;\n    font-weight: 300 !important;\n    margin: auto;\n    max-width: 375px;\n    width: max-content;\n  }\n\n  .plan-feature-icon {\n    align-items: center;\n    display: inline-flex;\n    height: 20px;\n    justify-content: center;\n    width: 20px;\n  }\n\n  .plan-task-run-price {\n    font-size: 4.5rem !important;\n  }\n\n  .volume-link {\n    // text-decoration: dotted;\n    border-bottom: dotted 1.75px;\n  }\n\n  .plan-cent {\n    font-size: 3rem !important;\n    vertical-align: middle;\n  }\n\n  .plan-table {\n    column-gap: 2px;\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    row-gap: 2px;\n\n    div {\n      background-color: #455a64;\n    }\n  }\n\n  .plan-cta {\n    background-color: #f7fcfd;\n    color: var(--v-secondaryGrayDark-base);\n    display: block;\n    font-size: 1rem;\n    letter-spacing: 0.15rem;\n    text-decoration: none;\n    text-transform: uppercase;\n    transition: all 50ms;\n\n    &.plan-cta-dark {\n      background-color: #546e7a;\n\n      &:focus,\n      &:hover {\n        background-color: #5a7581 !important;\n        color: #fff;\n      }\n    }\n\n    &:focus,\n    &:hover {\n      background-color: #e9f7fc !important;\n      font-weight: 500 !important;\n    }\n  }\n}\n\n.feature-divider {\n  border-color: #cfd8dc;\n  margin: auto;\n  width: 30%;\n}\n</style>\n"
  },
  {
    "path": "src/components/Plans/Starter.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport MenuTooltip from '@/components/MenuTooltip'\n\nexport default {\n  components: {\n    MenuTooltip\n  },\n  props: {\n    disabled: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    hideDetails: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    }\n  },\n  data() {\n    return {\n      volumeDiscounts: [\n        { runs: '20,000', price: 'Free' },\n        { runs: '100,000', price: '$0.0025' },\n        { runs: '1,000,000', price: '$0.00125' },\n        { runs: '10,000,000', price: '$0.000625' },\n        { runs: '100,000,000', price: '$0.0003125' },\n        { runs: '...and up', price: '' }\n      ]\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license', 'planType'])\n  },\n  methods: {\n    select() {\n      if (this.planType('STARTER') || this.disabled) return\n      this.$emit('click')\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"plan-card blue-grey darken-2 white--text mt-8 rounded elevation-4\"\n  >\n    <div class=\"font-weight-regular text-center py-8 plan-title\">\n      Starter\n    </div>\n    <v-divider class=\"divider-light\" />\n    <div\n      class=\"text-h6 text-md-subtitle-1 text-lg-h6 font-weight-regular text-center grey--text text--lighten-3\"\n    >\n      <div class=\"px-4\">\n        <MenuTooltip hide-close>\n          <template #activator>\n            <div\n              class=\"mt-12 ml-4 text-h2 font-weight-regular white--text plan-task-run-price d-flex align-center justify-center\"\n            >\n              <span class=\"mr-2 font-weight-light d-inline-block plan-cent\">\n                $ </span\n              >0.0025\n\n              <span class=\"mx-1 font-weight-light text-h5 align-self-end mr-n1\"\n                >/\n              </span>\n              <div\n                class=\"ml-2 font-weight-light text-body-2 align-self-end text-left\"\n              >\n                <div>successful</div>\n                <div style=\"margin-top: -6px;\">\n                  <span>\n                    task run\n                  </span>\n                </div>\n              </div>\n            </div>\n\n            <div class=\"font-weight-regular\">\n              +\n\n              <a class=\"primary--text text--lighten-1 volume-link\"\n                >automatic volume discounts</a\n              >\n            </div></template\n          >\n          <div>\n            <div class=\"text-h6 font-weight-regular\">\n              Only pay for successful runs.\n            </div>\n            <div class=\"mt-4 text-subtitle-1 font-weight-light\">\n              There's no charge for retries, failures, or any task that runs in\n              less than one second.\n            </div>\n            <div class=\"mt-4 text-subtitle-1 font-weight-light\">\n              As usage increases each month, the price per run automatically\n              drops:\n            </div>\n            <div class=\"mt-4 text-subtitle-1 font-weight-light\">\n              <v-simple-table dense>\n                <thead>\n                  <tr>\n                    <th class=\"text-left font-weight-light text-subtitle-1\">\n                      Monthly run tier\n                    </th>\n                    <th class=\"text-left font-weight-light text-subtitle-1\">\n                      Price per run\n                    </th>\n                  </tr>\n                </thead>\n                <tbody>\n                  <tr v-for=\"(item, i) in volumeDiscounts\" :key=\"item.runs\">\n                    <td class=\"font-weight-light\">\n                      <span v-if=\"i == 0\" class=\"text-subtitle-1\"\n                        >0 <span class=\"text-caption\">to </span></span\n                      >\n\n                      <span\n                        v-if=\"i !== 0 && i !== volumeDiscounts.length - 1\"\n                        class=\"text-caption\"\n                        >then to\n                      </span>\n\n                      <span class=\"text-subtitle-1\">{{ item.runs }}</span>\n                    </td>\n                    <td class=\"text-subtitle-1 font-weight-light\">{{\n                      item.price\n                    }}</td>\n                  </tr>\n                </tbody>\n              </v-simple-table>\n            </div>\n          </div>\n        </MenuTooltip>\n\n        <div\n          class=\"my-12 my-md-8 my-lg-12 text-left plan-body d-flex align-start justify-center flex-column\"\n        >\n          <div class=\"d-flex align-center justify-center\">\n            <span class=\"rounded-circle plans-feature-icon\">\n              <v-icon small>\n                fad fa-tasks\n              </v-icon>\n            </span>\n            <span class=\"ml-2\">\n              20,000 free runs every month\n            </span>\n          </div>\n\n          <div class=\"mt-3 d-flex align-center justify-center\">\n            <span\n              class=\"rounded-circle plans-feature-icon plans-feature-icon-light\"\n            >\n              <v-icon small>\n                fad fa-users\n              </v-icon>\n            </span>\n            <span class=\"ml-2\">Up to 1 user</span>\n          </div>\n\n          <div class=\"mt-3 d-flex align-center justify-center\">\n            <span\n              class=\"rounded-circle plans-feature-icon plans-feature-icon-light\"\n            >\n              <v-icon small>\n                fad fa-history\n              </v-icon>\n            </span>\n            <span class=\"ml-2\">1 week of run history</span>\n          </div>\n        </div>\n      </div>\n\n      <div v-if=\"hideDetails\" class=\"py-7 mt-8 mt-md-6 mt-lg-8 o-0\">\n        {{\n          planType('STARTER')\n            ? 'Current'\n            : disabled\n            ? 'Contact your team admin to upgrade'\n            : 'Start for free'\n        }}\n      </div>\n\n      <div\n        v-else\n        class=\"plan-cta plan-cta-dark py-7 mt-8 mt-md-6 mt-lg-8\"\n        :class=\"{ 'cursor-pointer': !planType('STARTER') }\"\n        @click=\"select\"\n      >\n        {{\n          planType('STARTER')\n            ? 'Current'\n            : disabled\n            ? 'Contact your team admin to upgrade'\n            : 'Start for free'\n        }}\n      </div>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.plan-card {\n  height: min-content;\n  overflow: hidden;\n  transition: all 150ms;\n  width: 425px;\n\n  .plan-title {\n    font-size: 1.15rem;\n    letter-spacing: 0.15rem;\n    text-transform: uppercase;\n  }\n\n  .divider-dark {\n    border-color: #eee;\n  }\n\n  .divider-light {\n    border-color: #3f515a;\n  }\n\n  .plan-body {\n    font-weight: 300 !important;\n    margin: auto;\n    max-width: 375px;\n    width: max-content;\n  }\n\n  .plan-feature-icon {\n    align-items: center;\n    display: inline-flex;\n    height: 20px;\n    justify-content: center;\n    width: 20px;\n  }\n\n  .plan-task-run-price {\n    font-size: 4.5rem !important;\n  }\n\n  .volume-link {\n    // text-decoration: dotted;\n    border-bottom: dotted 1.75px;\n  }\n\n  .plan-cent {\n    font-size: 3rem !important;\n    vertical-align: middle;\n  }\n\n  .plan-table {\n    column-gap: 2px;\n    display: grid;\n    grid-template-columns: 1fr 1fr;\n    row-gap: 2px;\n\n    div {\n      background-color: #455a64;\n    }\n  }\n\n  .plan-cta {\n    background-color: #f7fcfd;\n    color: inherit !important;\n    display: block;\n    font-size: 1rem;\n    letter-spacing: 0.15rem;\n    text-decoration: none;\n    text-transform: uppercase;\n    transition: all 50ms;\n\n    &.plan-cta-dark {\n      background-color: #546e7a;\n\n      &:focus,\n      &:hover {\n        background-color: #5a7581 !important;\n        color: #fff;\n      }\n    }\n\n    &:focus,\n    &:hover {\n      background-color: #e9f7fc !important;\n      font-weight: 500 !important;\n    }\n  }\n}\n\n.feature-divider {\n  border-color: #cfd8dc;\n  margin: auto;\n  width: 30%;\n}\n</style>\n"
  },
  {
    "path": "src/components/PrefectSchedule.vue",
    "content": "<script>\nimport { intervalToEnglish } from '@/utils/dateTime'\nimport cronstrue from 'cronstrue'\nimport moment from 'moment-timezone'\n// TODO add button that opens a sidebar to show multiple schedules (#307)\n\nexport default {\n  props: {\n    schedule: {\n      required: true,\n      type: Object,\n      validator: schedule => schedule.type\n    }\n  },\n  computed: {\n    displaySchedule() {\n      if (this.schedule.clocks[0].type === 'CronClock') {\n        // If there's a start date and a timezone, add a space and show it\n        const timezone =\n          (this.schedule.clocks[0]?.start_date?.tz &&\n            ` (${moment()\n              .tz(this.schedule.clocks[0]?.start_date?.tz)\n              .zoneAbbr()})`) ||\n          ' (UTC)'\n        return `${cronstrue.toString(this.schedule.clocks[0].cron)}${timezone}`\n      } else if (this.schedule.clocks[0].type === 'IntervalClock') {\n        const microsecondsString = this.schedule.clocks[0].interval\n        const numberOfMilliseconds = Number(microsecondsString) * 0.001\n\n        return intervalToEnglish(numberOfMilliseconds)\n      }\n      return null\n    }\n  }\n}\n</script>\n\n<template>\n  <span v-if=\"schedule.clocks ? schedule.clocks.length == 1 : false\">\n    {{ displaySchedule }}\n  </span>\n  <span v-else>\n    <v-btn disabled small>{{\n      schedule.type === 'UnionSchedule' ? 'union schedule' : 'custom schedule'\n    }}</v-btn>\n  </span>\n</template>\n"
  },
  {
    "path": "src/components/ResumeButton.vue",
    "content": "<script>\nimport { changeStateMixin } from '@/mixins/changeStateMixin'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  mixins: [changeStateMixin],\n  props: {\n    includeText: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return !this.hasPermission('update', 'run')\n    },\n    loading() {\n      if (this.resumeLoad == this.taskRun.id) return true\n      if (this.taskRunApproved && this.taskRun.state === 'Paused') return true\n      return false\n    }\n  }\n}\n</script>\n\n<template>\n  <v-tooltip bottom>\n    <template #activator=\"{ on: tooltip }\">\n      <div v-on=\"{ ...tooltip }\">\n        <v-btn\n          class=\"vertical-button mr-2\"\n          :style=\"{ height: '46px' }\"\n          data-cy=\"resume\"\n          text\n          depressed\n          small\n          :disabled=\"permissionsCheck\"\n          color=\"accentOrange\"\n          :loading=\"loading\"\n          @click=\"resumeRun\"\n        >\n          <v-icon>far fa-check-circle</v-icon>\n          <span v-if=\"includeText\"> Approve </span>\n        </v-btn>\n      </div>\n    </template>\n    <span>Approve task run (allows the task run to resume)</span>\n  </v-tooltip>\n</template>\n"
  },
  {
    "path": "src/components/RunConfig/ArgumentHeading.vue",
    "content": "<template>\n  <div class=\"argument-heading\">\n    <div class=\"argument-heading__title\">\n      {{ title }}\n      <span v-if=\"argument.length\" class=\"argument-heading__tag\">\n        {{ argument }}\n      </span>\n    </div>\n\n    <div class=\"argument-heading__description\">\n      <slot />\n    </div>\n  </div>\n</template>\n\n<script lang=\"js\">\nexport default {\n  props: {\n    argument: {\n      type: String,\n      required: false,\n      default: ''\n    },\n    title: {\n      type: String,\n      required: true\n    }\n  }\n}\n</script>\n\n<style lang=\"scss\">\n.argument-heading__tag {\n  background-color: #fafafa !important;\n  border: 1px solid var(--v-utilGrayLight-base);\n  border-radius: 2px;\n  color: #455a64 !important;\n  caret-color: #455a64 !important;\n  padding: 0 4px;\n  font-size: 0.75rem !important;\n  font-weight: 400;\n  line-height: 1.25rem;\n  letter-spacing: 0.0333333333em !important;\n}\n\n.argument-heading__title {\n  font-size: 1.25rem !important;\n  font-weight: 500;\n  line-height: 2rem;\n  letter-spacing: 0.0125em !important;\n}\n\n.argument-heading__description {\n  font-size: 0.875rem !important;\n  font-weight: 400;\n  line-height: 1.25rem;\n  letter-spacing: 0.0178571429em !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/RunConfig/ArgumentInput.vue",
    "content": "<template>\n  <v-row class=\"run-config-form__row\">\n    <v-col cols=\"12\" md=\"6\">\n      <argument-heading :argument=\"argument\" :title=\"title\">\n        <slot name=\"description\">\n          {{ description }}\n        </slot>\n      </argument-heading>\n    </v-col>\n    <v-col cols=\"12\" md=\"6\" class=\"run-config-form__input\">\n      <slot>\n        <resettable-wrapper v-model=\"internalValue\">\n          <v-text-field\n            v-model=\"internalValue\"\n            placeholder=\"Default\"\n            :label=\"title\"\n            hide-details\n            outlined\n            dense\n          />\n        </resettable-wrapper>\n      </slot>\n    </v-col>\n  </v-row>\n</template>\n\n<script>\nimport ArgumentHeading from '@/components/RunConfig/ArgumentHeading'\nimport ResettableWrapper from '@/components/CustomInputs/ResettableWrapper'\n\nexport default {\n  components: {\n    ArgumentHeading,\n    ResettableWrapper\n  },\n  props: {\n    argument: {\n      type: String,\n      required: false,\n      default: ''\n    },\n    title: {\n      type: String,\n      required: true\n    },\n    description: {\n      type: String,\n      required: false,\n      default: ''\n    },\n    value: {\n      type: String,\n      required: false,\n      default: ''\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/RunConfig/ArgumentReference.vue",
    "content": "<template>\n  <span>\n    <a :href=\"href\" target=\"_blank\">\n      {{ title }}\n    </a>\n    <sup>\n      <i\n        class=\"v-icon notranslate material-icons theme--light\"\n        style=\"font-size: 12px !important;\"\n      >\n        open_in_new\n      </i>\n    </sup>\n  </span>\n</template>\n\n<script>\nexport default {\n  props: {\n    title: {\n      type: String,\n      required: true\n    },\n    href: {\n      type: String,\n      required: true\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/RunConfig/DateTimeSelector.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport moment from 'moment-timezone'\n\nconst timezones = [...moment.tz.names()].map(tz => {\n  return { text: tz.replace(/_/g, ' '), value: tz }\n})\n\nexport default {\n  props: {\n    disablePast: {\n      type: Boolean,\n      required: false,\n      default: () => true\n    },\n    // Two-way-bound date & time.\n    // Format: ISO 8601, e.g. 2020-03-18T15:30:32-05:00\n    // This prop is required for use of v-model on this component.\n    value: {\n      type: String,\n      required: false,\n      default: () => ''\n    }\n  },\n  data() {\n    return {\n      // Date & time inputs\n      dateTime: this.momentWithTimezone(),\n      dateInterval: null,\n\n      // Get either the user-set timezone or the resolved local timezone\n      timezone_:\n        this.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone,\n      timezones: timezones,\n\n      previousDay: null,\n\n      // These are set to true if a user has edited the date/time fields\n      // so that the counter doesn't continue to increment values\n      dateChanged: false,\n      timeChanged: false\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone']),\n    internalValue() {\n      if (!this.dateTime) return\n\n      // format to ISO 8601,\n      return this.dateTime.format()\n    },\n    displayDay() {\n      return this.dateTime?.format('D')\n    },\n    displayMonth() {\n      return this.dateTime?.format('MMMM')\n    },\n    displayYear() {\n      return this.dateTime?.format('YYYY')\n    },\n    displayTimezone() {\n      return this.dateTime?.zoneAbbr()\n    },\n    timezoneIcon() {\n      const region = this.timezone_?.split('/')?.[0]?.toLowerCase()\n      let icon\n      switch (region) {\n        case 'africa':\n        case 'egypt':\n        case 'zulu':\n        case 'iran':\n        case 'israel':\n        case 'libya':\n          icon = 'fad fa-globe-africa'\n          break\n\n        case 'asia':\n        case 'australia':\n        case 'pacific':\n        case 'kwajalein':\n        case 'hongkong':\n        case 'indian':\n        case 'japan':\n        case 'rok':\n        case 'roc':\n        case 'singapore':\n          icon = 'fad fa-globe-asia'\n          break\n\n        case 'america':\n        case 'canada':\n        case 'us':\n        case 'atlantic':\n        case 'brazil':\n        case 'cuba':\n        case 'mexico':\n        case 'jamaica':\n        case 'navajo':\n        case 'mst':\n          icon = 'fad fa-globe-americas'\n          break\n\n        case 'europe':\n        case 'gb':\n        case 'gb-eire':\n        case 'gmt':\n        case 'greenwich':\n        case 'hst':\n        case 'iceland':\n        case 'poland':\n        case 'portugal':\n        case 'turkey':\n        case 'met':\n          icon = 'fad fa-globe-europe'\n          break\n\n        case 'universal':\n          icon = 'fad fa-planet-ringed'\n          break\n\n        case 'antarctica':\n          icon = 'fad fa-snowman'\n          break\n\n        case 'etc':\n        default:\n          icon = 'fad fa-globe'\n          break\n      }\n      return icon\n    },\n    hour: {\n      get() {\n        return this.dateTime?.format('h')\n      },\n      set(val) {\n        const hour =\n          this.meridian == 'pm' && val < 12 ? parseInt(val) + 12 : parseInt(val)\n\n        const dateTime = moment(this.dateTime).set({\n          hour: hour\n        })\n        this.dateTime = this.momentWithTimezone(dateTime)\n      }\n    },\n    minute: {\n      get() {\n        return this.dateTime?.format('mm')\n      },\n      set(val) {\n        const dateTime = moment(this.dateTime).set({\n          minute: val\n        })\n        this.dateTime = this.momentWithTimezone(dateTime)\n      }\n    },\n    meridian: {\n      get() {\n        return this.dateTime?.format('a')\n      },\n      set(val) {\n        const currentHour = this.dateTime.get('hour')\n        // If the meridian is already correct, we can stop here\n        if (\n          (currentHour > 12 && val == 'pm') ||\n          (currentHour < 12 && val == 'am')\n        )\n          return\n\n        let operation\n\n        switch (val) {\n          case 'am':\n            operation = 'subtract'\n            break\n          case 'pm':\n            operation = 'add'\n            break\n        }\n\n        const dateTime = moment(this.dateTime)[operation](12, 'hours')\n        this.dateTime = this.momentWithTimezone(dateTime)\n      }\n    },\n    date: {\n      get() {\n        return this.dateTime?.format('YYYY-MM-DD')\n      },\n      set(val) {\n        const split = val.split('-').map(v => parseInt(v))\n        // Subtract 1 from the month since the datepicker is indexed to 1\n        const dateTime = moment(this.dateTime).set({\n          year: split[0],\n          month: split[1] - 1,\n          date: split[2]\n        })\n\n        this.dateTime = this.momentWithTimezone(dateTime)\n      }\n    }\n  },\n  watch: {\n    internalValue(val) {\n      this.$emit('input', val)\n    },\n    timezone_(val) {\n      this.dateTime = this.momentWithTimezone(this.dateTime)\n      this.$emit('update:timezone', val)\n    }\n  },\n  mounted() {\n    this.dateTime = this.momentWithTimezone()\n    this.previousDay = new moment().startOf('day').format('YYYY-MM-DD')\n\n    this.$emit('update:timezone', this.timezone_)\n\n    const updateCurrentDateTime = () => {\n      // If both date and time have been changed, exit immediately\n\n      if (this.dateChanged && this.timeChanged) return\n      const dateTime = this.momentWithTimezone()\n\n      if (!this.dateChanged) {\n        this.date = dateTime.format('YYYY-MM-DD')\n      }\n\n      if (!this.timeChanged) {\n        this.hour = dateTime.format('hh')\n        this.minute = dateTime.format('mm')\n        this.meridian = dateTime.format('a')\n      }\n    }\n\n    this.dateInterval = setInterval(updateCurrentDateTime, 5000)\n  },\n  updated() {\n    this.previousDay = new moment().startOf('day').format('YYYY-MM-DD')\n  },\n  destroyed() {\n    clearInterval(this.dateInterval)\n    this.dateInterval = null\n  },\n  methods: {\n    handleChangeDate() {\n      this.dateChanged = true\n    },\n    handleChangeTime() {\n      this.timeChanged = true\n    },\n    momentWithTimezone(dateTime) {\n      return (dateTime ? moment(dateTime) : new moment()).tz(this.timezone_)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container class=\"pa-0 ma-0\" fluid>\n    <v-row no-gutters>\n      <v-col\n        cols=\"12\"\n        md=\"4\"\n        class=\"d-flex align-center justify-start text-right\"\n      >\n        <div\n          class=\"pb-16 text-h5\"\n          :class=\"{\n            'mx-auto': $vuetify.breakpoint.smAndDown,\n            'text-center': $vuetify.breakpoint.smAndDown\n          }\"\n        >\n          <div>\n            {{ displayMonth }}\n            <span class=\"primary--text\"> {{ displayDay }}</span\n            >,\n            {{ displayYear }}\n          </div>\n\n          <div class=\"text-h4\">\n            <span class=\"primary--text\">{{ hour }}</span\n            >:<span class=\"primary--text\">{{ minute }} {{ meridian }} </span>\n            <span class=\"text-h5\" style=\"line-height: 0.9rem;\"\n              >({{ displayTimezone }})</span\n            >\n          </div>\n        </div>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"1\" class=\"text-center\">\n        <v-divider :vertical=\"$vuetify.breakpoint.mdAndUp\" />\n      </v-col>\n\n      <v-col cols=\"12\" md=\"7\">\n        <v-date-picker\n          v-model=\"date\"\n          no-title\n          color=\"primary\"\n          class=\"transparent blue-grey--text text--darken-2\"\n          width=\"100%\"\n          :min=\"previousDay\"\n          :value=\"date\"\n          @change=\"handleChangeDate\"\n        />\n\n        <v-row style=\"max-width: 290px;\" class=\"mx-auto\" no-gutters>\n          <v-col cols=\"12\" class=\"d-flex align-center justify-space-between\">\n            <v-text-field\n              v-model=\"hour\"\n              type=\"number\"\n              class=\"mx-2\"\n              label=\"hour\"\n              hide-details\n              outlined\n              dense\n              min=\"1\"\n              max=\"12\"\n              style=\"width: 20%;\"\n              @input=\"handleChangeTime\"\n            />\n            <span class=\"text-h4\">:</span>\n            <v-text-field\n              v-model=\"minute\"\n              type=\"number\"\n              class=\"mx-2\"\n              label=\"minute\"\n              hide-details\n              outlined\n              dense\n              min=\"0\"\n              max=\"59\"\n              style=\"width: 20%;\"\n              @input=\"handleChangeTime\"\n            />\n            <v-select\n              v-model=\"meridian\"\n              class=\"mx-2\"\n              hide-details\n              outlined\n              dense\n              label=\"am/pm\"\n              :items=\"['am', 'pm']\"\n              :append-icon=\"null\"\n              hide-no-data\n              menu-props=\"offset-y\"\n              style=\"width: 20%;\"\n              @input=\"handleChangeTime\"\n            />\n          </v-col>\n\n          <v-col cols=\"12\" class=\"mt-4 d-flex align-center\">\n            <div class=\"icon-placeholder mx-2\">\n              <v-fade-transition mode=\"out-in\">\n                <span :key=\"timezoneIcon\">\n                  <v-icon>{{ timezoneIcon }}</v-icon>\n                </span>\n              </v-fade-transition>\n            </div>\n            <v-autocomplete\n              data-public\n              v-model=\"timezone_\"\n              :items=\"timezones\"\n              outlined\n              dense\n              class=\"mx-2\"\n              hide-details\n              label=\"Time Zone\"\n              :menu-props=\"{ contentClass: 'tz' }\"\n            />\n          </v-col>\n        </v-row>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.icon-placeholder {\n  height: 26px;\n  width: 26px;\n}\n</style>\n\n<style lang=\"scss\">\n/* stylelint-disable */\n.tz.v-menu__content .v-select-list {\n  max-width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/components/RunConfig/DockerRunForm.vue",
    "content": "<template>\n  <div class=\"run-config-form\">\n    <argument-input\n      v-model=\"internalValue.image\"\n      argument=\"image\"\n      title=\"Image\"\n      description=\"The image to use.\"\n    />\n    <argument-input\n      argument=\"env\"\n      title=\"Environment Variables\"\n      description=\"Additional environment variables to set in the container.\"\n    >\n      <resettable-wrapper v-model=\"envValue\" class=\"resettable-dictionary-json\">\n        <code-input ref=\"envInput\" v-model=\"envValue\" show-types />\n      </resettable-wrapper>\n    </argument-input>\n    <argument-input\n      argument=\"host_config\"\n      title=\"Host Config\"\n      description=\"Runtime arguments to pass to the Docker Agent.\"\n    >\n      <resettable-wrapper\n        v-model=\"hostConfigValue\"\n        class=\"resettable-dictionary-json\"\n      >\n        <code-input\n          ref=\"hostConfigInput\"\n          v-model=\"hostConfigValue\"\n          show-types\n        />\n      </resettable-wrapper>\n    </argument-input>\n  </div>\n</template>\n\n<script>\nimport ArgumentInput from '@/components/RunConfig/ArgumentInput'\nimport CodeInput from '@/components/CustomInputs/CodeInput'\nimport ResettableWrapper from '@/components/CustomInputs/ResettableWrapper'\nimport { tryFormatJson } from '@/utils/json'\n\nexport default {\n  components: {\n    ArgumentInput,\n    ResettableWrapper,\n    CodeInput\n  },\n  props: {\n    value: {\n      type: Object,\n      required: true\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    },\n    envValue: {\n      get() {\n        return tryFormatJson(this.internalValue.env)\n      },\n      set(value) {\n        this.internalValue = { ...this.internalValue, env: value }\n      }\n    },\n    hostConfigValue: {\n      get() {\n        return tryFormatJson(this.internalValue.host_config)\n      },\n      set(value) {\n        this.internalValue = { ...this.internalValue, host_config: value }\n      }\n    }\n  },\n  methods: {\n    validate() {\n      return (\n        this.$refs.envInput.validate() && this.$refs.hostConfigInput.validate()\n      )\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/RunConfig/EcsRunForm.vue",
    "content": "<template>\n  <div class=\"run-config-form\">\n    <argument-input\n      title=\"Task Definition\"\n      description=\"The source of the task definition to use. If default is selected, the task will use the definition specified by your agent.\"\n    >\n      <v-radio-group v-model=\"selectedTaskDefinition\" mandatory row>\n        <v-radio label=\"Default\" :value=\"taskDefinitions.default\" />\n        <v-radio label=\"Template path\" :value=\"taskDefinitions.path\" />\n        <v-radio label=\"Template\" :value=\"taskDefinitions.template\" />\n        <v-radio label=\"ARN\" :value=\"taskDefinitions.arn\" />\n      </v-radio-group>\n    </argument-input>\n    <template v-if=\"selectedTaskDefinition == taskDefinitions.path\">\n      <argument-input\n        v-model=\"internalValue.task_definition_path\"\n        argument=\"task_definition_path\"\n        title=\"Template path\"\n        description=\"Specify a path to a task definition to use. If this is a local path, the definition will be loaded on initialization and stored on the ECSRun object as the task_definition field. Otherwise the definition will be loaded at runtime by the agent; supported runtime file schemes include s3, gcs, and agent.\"\n      />\n    </template>\n    <template v-if=\"selectedTaskDefinition == taskDefinitions.template\">\n      <argument-input argument=\"task_definition\" title=\"Template\">\n        <template slot=\"description\">\n          Specify an in-memory task definition spec to use; see the\n          <argument-reference\n            title=\"ECS docs\"\n            href=\"https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.run_task\"\n          />\n          for more information on task definitions.\n        </template>\n        <resettable-wrapper\n          v-model=\"taskDefinitionValue\"\n          class=\"resettable-dictionary-json\"\n        >\n          <code-input\n            ref=\"taskDefinitionInput\"\n            v-model=\"taskDefinitionValue\"\n            :editors=\"['json', 'yaml']\"\n          />\n        </resettable-wrapper>\n      </argument-input>\n    </template>\n    <template v-if=\"selectedTaskDefinition == taskDefinitions.arn\">\n      <argument-input\n        v-model=\"internalValue.task_definition_arn\"\n        argument=\"task_definition_arn\"\n        title=\"ARN\"\n      >\n        <template slot=\"description\">\n          Specify a pre-registered task definition ARN to use (either\n          <code>family</code>, <code>family:version</code>, or a full task\n          definition ARN).\n        </template>\n      </argument-input>\n    </template>\n    <argument\n      v-model=\"internalValue.image\"\n      argument=\"image\"\n      title=\"Image\"\n      description=\"The image to use; if not provided, the image will be inferred from either the flow's storage or the default image configured on the agent.\"\n    />\n    <argument-input\n      argument=\"env\"\n      title=\"Environment Variables\"\n      description=\"Additional environment variables to set on the task.\"\n    >\n      <resettable-wrapper v-model=\"envValue\" class=\"resettable-dictionary-json\">\n        <code-input ref=\"envInput\" v-model=\"envValue\" show-types />\n      </resettable-wrapper>\n    </argument-input>\n    <argument-input v-model=\"internalValue.cpu\" argument=\"cpu\" title=\"CPU\">\n      <template slot=\"description\">\n        The CPU made available to the task; see the\n        <argument-reference\n          title=\"ECS docs\"\n          href=\"https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-cpu-memory-error.html\"\n        />\n        for available values.\n      </template>\n    </argument-input>\n    <argument-input\n      v-model=\"internalValue.memory\"\n      argument=\"memory\"\n      title=\"Memory\"\n    >\n      <template slot=\"description\">\n        The memory made available to the task; see the\n        <argument-reference\n          title=\"ECS docs\"\n          href=\"https://docs.aws.amazon.com/AmazonECS/latest/userguide/task-cpu-memory-error.html\"\n        />\n        for available values.\n      </template>\n    </argument-input>\n    <argument\n      v-model=\"internalValue.task_role_arn\"\n      argument=\"task_role_arn\"\n      title=\"Task role ARN\"\n      description=\"The name or full ARN for the IAM role to use for this task. If not provided, the default on the agent will be used (if configured).\"\n    />\n    <argument\n      v-model=\"internalValue.execution_role_arn\"\n      argument=\"execution_role_arn\"\n      title=\"Execution role ARN\"\n      description=\"The execution role ARN to use when registering a task definition for this task. If not provided, the default on the agent will be used (if configured).\"\n    />\n    <argument-input argument=\"run_task_kwargs\" title=\"Run task arguments\">\n      <template slot=\"description\">\n        Additional key word arguments to pass to <code>run_task</code> when\n        starting this task; see the\n        <argument-reference\n          title=\"ECS docs\"\n          href=\"https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.register_task_definition\"\n        />\n        for more information.\n      </template>\n      <resettable-wrapper\n        v-model=\"runTaskKwargsValue\"\n        class=\"resettable-dictionary-json\"\n      >\n        <code-input\n          ref=\"runTaskKwargsInput\"\n          v-model=\"runTaskKwargsValue\"\n          show-types\n        />\n      </resettable-wrapper>\n    </argument-input>\n  </div>\n</template>\n\n<script>\nimport ArgumentInput from '@/components/RunConfig/ArgumentInput'\nimport ArgumentReference from '@/components/RunConfig/ArgumentReference'\nimport CodeInput from '@/components/CustomInputs/CodeInput'\nimport ResettableWrapper from '@/components/CustomInputs/ResettableWrapper'\nimport { tryFormatJson } from '@/utils/json'\n\nexport default {\n  components: {\n    ArgumentInput,\n    ArgumentReference,\n    ResettableWrapper,\n    CodeInput\n  },\n  props: {\n    value: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    const taskDefinitions = {\n      default: 'default',\n      path: 'path',\n      template: 'template',\n      arn: 'arn'\n    }\n\n    return {\n      selectedTaskDefinition: taskDefinitions.default,\n      taskDefinitions\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    },\n    envValue: {\n      get() {\n        return tryFormatJson(this.internalValue.env)\n      },\n      set(value) {\n        this.internalValue = { ...this.internalValue, env: value }\n      }\n    },\n    taskDefinitionValue: {\n      get() {\n        return tryFormatJson(this.internalValue.task_definition)\n      },\n      set(value) {\n        this.internalValue = { ...this.internalValue, task_definition: value }\n      }\n    },\n    runTaskKwargsValue: {\n      get() {\n        return tryFormatJson(this.internalValue.run_task_kwargs)\n      },\n      set(value) {\n        this.internalValue = { ...this.internalValue, run_task_kwargs: value }\n      }\n    }\n  },\n  methods: {\n    validate() {\n      const envValid = this.$refs.envInput.validate()\n      const taskDefinitionValid =\n        !this.$refs.taskDefinitionInput ||\n        this.$refs.taskDefinitionInput.validate()\n      const runTaskKwargsValid =\n        !this.$refs.runTaskKwargsInput ||\n        this.$refs.runTaskKwargsInput.validate()\n\n      return envValid && taskDefinitionValid && runTaskKwargsValid\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/RunConfig/KubernetesRunForm.vue",
    "content": "<template>\n  <div class=\"run-config-form\">\n    <argument-input\n      title=\"Job template\"\n      description=\"The source of the job template to use. If default is selected, the job will use the template specified by your agent.\"\n    >\n      <v-radio-group v-model=\"selectedJobTemplate\" mandatory row>\n        <v-radio label=\"Default\" :value=\"jobTemplates.default\" />\n        <v-radio label=\"Template path\" :value=\"jobTemplates.path\" />\n        <v-radio label=\"Template\" :value=\"jobTemplates.template\" />\n      </v-radio-group>\n    </argument-input>\n    <argument-input\n      v-if=\"selectedJobTemplate == jobTemplates.path\"\n      v-model=\"internalValue.job_template_path\"\n      argument=\"job_template_path\"\n      title=\"Template path\"\n      description=\"Specify a path to a job template to use. If this is a local path, the job template will be loaded on initialization and stored on the KubernetesRun object as the job template field. Otherwise the job template will be loaded at runtime by the agent; supported runtime file schemes include s3, gcs, and agent.\"\n    />\n    <argument-input\n      v-if=\"selectedJobTemplate == jobTemplates.template\"\n      argument=\"job_template\"\n      title=\"Template\"\n      description=\"Specify an in-memory job template to use.\"\n    >\n      <resettable-wrapper\n        v-model=\"jobTemplateValue\"\n        class=\"resettable-dictionary-json\"\n      >\n        <code-input\n          ref=\"jobTemplateInput\"\n          v-model=\"jobTemplateValue\"\n          :editors=\"['json', 'yaml']\"\n        />\n      </resettable-wrapper>\n    </argument-input>\n    <argument-input\n      v-model=\"internalValue.image\"\n      argument=\"image\"\n      title=\"Image\"\n      description=\"The image to use.\"\n    />\n    <argument-input\n      argument=\"env\"\n      title=\"Environment Variables\"\n      description=\"Additional environment variables to set on the job.\"\n    >\n      <resettable-wrapper v-model=\"envValue\" class=\"resettable-dictionary-json\">\n        <code-input ref=\"envInput\" v-model=\"envValue\" show-types />\n      </resettable-wrapper>\n    </argument-input>\n    <argument-input\n      v-model=\"internalValue.cpu_limit\"\n      argument=\"cpu_limit\"\n      title=\"CPU limit\"\n    >\n      <template slot=\"description\">\n        The CPU limit for the job; when this is specified, the kubelet does not\n        allow the container to use more than this amount of CPU. See the\n        <argument-reference\n          title=\"Kubernetes docs\"\n          href=\"https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\"\n        />\n        for more information.\n      </template>\n    </argument-input>\n    <argument-input\n      v-model=\"internalValue.cpu_request\"\n      argument=\"cpu_request\"\n      title=\"CPU Request\"\n    >\n      <template slot=\"description\">\n        The CPU request for the job; when this is specified, the kubelet\n        reserves at least this amount of CPU for the container to use. See the\n        <argument-reference\n          title=\"Kubernetes docs\"\n          href=\"https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\"\n        />\n        for more information.\n      </template>\n    </argument-input>\n    <argument-input\n      v-model=\"internalValue.memory_limit\"\n      argument=\"memory_limit\"\n      title=\"Memory limit\"\n    >\n      <template slot=\"description\">\n        The memory limit for the job; when this is specified, the kubelet does\n        not allow the container to use more than this amount of memory. See the\n        <argument-reference\n          title=\"Kubernetes docs\"\n          href=\"https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\"\n        />\n        for more information.\n      </template>\n    </argument-input>\n    <argument-input\n      v-model=\"internalValue.memory_request\"\n      argument=\"memory_request\"\n      title=\"Memory request\"\n    >\n      <template slot=\"description\">\n        The memory request to use for the job; when this is specified, the\n        kubelet reserves at least this amount of memory for the container to\n        use. See the\n        <argument-reference\n          title=\"Kubernetes docs\"\n          href=\"https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/\"\n        />\n        for more information.\n      </template>\n    </argument-input>\n    <argument-input\n      v-model=\"internalValue.service_account_name\"\n      argument=\"service_account_name\"\n      title=\"Service account name\"\n      description=\"A service account name to use for this job. Note: if\n          present, this overrides any service account configured on the agent or in\n          the job template.\"\n    />\n    <argument-input\n      argument=\"image_pull_secrets\"\n      title=\"Image\"\n      description=\"A list of image pull secrets to use for this job.\n          Note: if present, these override any image pull secrets configured on the\n          agent or in the job template.\"\n    >\n      <list-input\n        v-model=\"internalValue.image_pull_secrets\"\n        label=\"Image pull secrets\"\n      />\n    </argument-input>\n  </div>\n</template>\n\n<script>\nimport ArgumentInput from '@/components/RunConfig/ArgumentInput'\nimport ArgumentReference from '@/components/RunConfig/ArgumentReference'\nimport CodeInput from '@/components/CustomInputs/CodeInput'\nimport ListInput from '@/components/CustomInputs/ListInput'\nimport ResettableWrapper from '@/components/CustomInputs/ResettableWrapper'\nimport { tryFormatJson } from '@/utils/json'\n\nexport default {\n  components: {\n    ArgumentInput,\n    ArgumentReference,\n    ResettableWrapper,\n    CodeInput,\n    ListInput\n  },\n  props: {\n    value: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    const jobTemplates = {\n      default: 'default',\n      path: 'path',\n      template: 'template'\n    }\n\n    return {\n      selectedJobTemplate: jobTemplates.default,\n      jobTemplates\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    },\n    envValue: {\n      get() {\n        return tryFormatJson(this.internalValue.env)\n      },\n      set(value) {\n        this.internalValue = { ...this.internalValue, env: value }\n      }\n    },\n    jobTemplateValue: {\n      get() {\n        return tryFormatJson(this.internalValue.job_template)\n      },\n      set(value) {\n        this.internalValue = { ...this.internalValue, job_template: value }\n      }\n    }\n  },\n  methods: {\n    validate() {\n      const envValid = this.$refs.envInput.validate()\n      const jobTemplateValid =\n        !this.$refs.jobTemplateInput || this.$refs.jobTemplateInput.validate()\n\n      return envValid && jobTemplateValid\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/RunConfig/LocalRunForm.vue",
    "content": "<template>\n  <div class=\"run-config-form\">\n    <argument-input\n      argument=\"env\"\n      title=\"Environment Variables\"\n      description=\"Additional environment variables to set for the process.\"\n    >\n      <resettable-wrapper v-model=\"envValue\" class=\"resettable-dictionary-json\">\n        <code-input ref=\"envInput\" v-model=\"envValue\" show-types />\n      </resettable-wrapper>\n    </argument-input>\n    <argument-input\n      v-model=\"internalValue.working_dir\"\n      argument=\"working_dir\"\n      title=\"Working directory\"\n      description=\"The working directory in which to start the process; the directory must already exist. If not provided, will be run in the same directory as the agent was started.\"\n    />\n  </div>\n</template>\n\n<script>\nimport ArgumentInput from '@/components/RunConfig/ArgumentInput'\nimport CodeInput from '@/components/CustomInputs/CodeInput'\nimport ResettableWrapper from '@/components/CustomInputs/ResettableWrapper'\nimport { tryFormatJson } from '@/utils/json'\n\nexport default {\n  components: {\n    ArgumentInput,\n    ResettableWrapper,\n    CodeInput\n  },\n  props: {\n    value: {\n      type: Object,\n      required: true\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    },\n    envValue: {\n      get() {\n        return tryFormatJson(this.internalValue.env)\n      },\n      set(value) {\n        this.internalValue = { ...this.internalValue, env: value }\n      }\n    }\n  },\n  methods: {\n    validate() {\n      return this.$refs.envInput.validate()\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/RunConfig/RunConfig.vue",
    "content": "<script>\nimport RunConfigTypeSelect from '@/components/RunConfig/RunConfigTypeSelect'\nimport UniversalRunForm from '@/components/RunConfig/UniversalRunForm'\nimport LocalRunForm from '@/components/RunConfig/LocalRunForm'\nimport DockerRunForm from '@/components/RunConfig/DockerRunForm'\nimport KubernetesRunForm from '@/components/RunConfig/KubernetesRunForm'\nimport EcsRunForm from '@/components/RunConfig/EcsRunForm'\n\nexport default {\n  components: {\n    RunConfigTypeSelect\n  },\n  props: {\n    value: {\n      type: Object,\n      required: true\n    }\n  },\n  computed: {\n    formComponent() {\n      switch (this.value.type) {\n        case 'LocalRun':\n          return LocalRunForm\n        case 'DockerRun':\n          return DockerRunForm\n        case 'KubernetesRun':\n          return KubernetesRunForm\n        case 'ECSRun':\n          return EcsRunForm\n        case 'UniversalRun':\n        default:\n          return UniversalRunForm\n      }\n    },\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  },\n  methods: {\n    validate() {\n      return this.$refs.runConfigForm.validate()\n    }\n  }\n}\n</script>\n\n<template>\n  <div style=\"min-width: 100%\">\n    <run-config-type-select v-model=\"internalValue.type\" class=\"pb-8\" />\n    <component\n      :is=\"formComponent\"\n      ref=\"runConfigForm\"\n      v-model=\"internalValue\"\n    />\n  </div>\n</template>\n\n<style lang=\"scss\">\n.run-config-form__row {\n  max-width: var(--v-lg);\n  margin: 0;\n}\n\n@media (min-width: 960px) {\n  .run-config-form__input > .v-input {\n    margin-top: 26px;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/RunConfig/RunConfigTypeButton.vue",
    "content": "<template>\n  <div v-ripple role=\"button\" tabindex=\"0\" @click=\"$emit('select')\">\n    <div class=\"text-center\" style=\"width: 50px;\">\n      <i :class=\"icon\" class=\"fa-2x pi-2x\"> </i>\n    </div>\n\n    <div class=\"w-100 ml-2\">\n      <span class=\"text-h6 mr-2\"> {{ label }}</span>\n\n      <menu-tooltip v-if=\"$vuetify.breakpoint.mdAndUp\">\n        <div class=\"text-body-1 grey--text text--darken-1\">\n          {{ description }}\n        </div>\n      </menu-tooltip>\n    </div>\n  </div>\n</template>\n\n<script>\nimport MenuTooltip from '@/components/MenuTooltip'\n\nexport default {\n  components: {\n    MenuTooltip\n  },\n  props: {\n    label: {\n      type: String,\n      required: true\n    },\n    description: {\n      type: String,\n      required: true\n    },\n    icon: {\n      type: String,\n      required: true\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/RunConfig/RunConfigTypeSelect.vue",
    "content": "<template>\n  <div class=\"run-config-type-select\">\n    <run-config-type-button\n      label=\"Local\"\n      icon=\"fad fa-laptop-house\"\n      class=\"run-config-type-select__option\"\n      :class=\"{ active: internalValue == 'LocalRun' }\"\n      description=\"Run the flow in a local process on a local agent\"\n      @select=\"internalValue = 'LocalRun'\"\n    />\n    <run-config-type-button\n      label=\"Universal\"\n      icon=\"fad fa-globe\"\n      class=\"run-config-type-select__option\"\n      :class=\"{ active: internalValue == 'UniversalRun' }\"\n      description=\"Run the flow on any agent with matching labels\"\n      @select=\"internalValue = 'UniversalRun'\"\n    />\n    <run-config-type-button\n      label=\"Docker\"\n      icon=\"fab fa-docker\"\n      class=\"run-config-type-select__option\"\n      :class=\"{ active: internalValue == 'DockerRun' }\"\n      description=\"Run the flow as a container on a Docker agent\"\n      @select=\"internalValue = 'DockerRun'\"\n    />\n    <run-config-type-button\n      label=\"Kubernetes\"\n      icon=\"pi-kubernetes\"\n      class=\"run-config-type-select__option\"\n      :class=\"{ active: internalValue == 'KubernetesRun' }\"\n      description=\"Run the flow as a job on a Kubernetes agent\"\n      @select=\"internalValue = 'KubernetesRun'\"\n    />\n    <run-config-type-button\n      label=\"ECS\"\n      icon=\"fab fa-aws\"\n      class=\"run-config-type-select__option\"\n      :class=\"{ active: internalValue == 'ECSRun' }\"\n      description=\"Run the flow as a task on an ECS agent\"\n      @select=\"internalValue = 'ECSRun'\"\n    />\n  </div>\n</template>\n\n<script>\nimport RunConfigTypeButton from '@/components/RunConfig/RunConfigTypeButton'\n\nexport default {\n  components: {\n    RunConfigTypeButton\n  },\n  props: {\n    value: {\n      type: String,\n      required: true\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    }\n  }\n}\n</script>\n\n<style lang=\"scss\">\n.run-config-type-select {\n  display: grid;\n  grid-column-gap: 20px;\n  grid-template-columns: repeat(auto-fit, minmax(150px, 195px));\n}\n\n.run-config-type-select__option {\n  display: flex;\n  justify-content: flex-start;\n  align-items: center;\n  padding: 8px 16px;\n  margin: 8px 0;\n  border: 2px solid;\n  border-color: var(--v-utilGrayLight-base) !important;\n  transition: all 50ms;\n  height: 80px;\n  width: 100%;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n\n  &.active {\n    border-color: var(--v-primary-base) !important;\n\n    .svg-inline--fa path {\n      fill: var(--v-primary-base) !important;\n    }\n\n    .pi-kubernetes::before {\n      color: var(--v-primary-base) !important;\n    }\n  }\n\n  &:hover,\n  &:focus {\n    background-color: rgba(0, 0, 0, 0.05);\n  }\n}\n\n.theme--dark {\n  .run-config-type-select__option {\n    &:hover,\n    &:focus {\n      background-color: rgba(255, 255, 255, 0.12);\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/RunConfig/UniversalRunForm.vue",
    "content": "<template>\n  <div class=\"run-config-form\">\n    <argument-input\n      argument=\"env\"\n      title=\"Environment Variables\"\n      description=\"Additional environment variables to set in the container.\"\n    >\n      <resettable-wrapper v-model=\"envValue\" class=\"resettable-dictionary-json\">\n        <code-input ref=\"envInput\" v-model=\"envValue\" show-types />\n      </resettable-wrapper>\n    </argument-input>\n  </div>\n</template>\n\n<script>\nimport ArgumentInput from '@/components/RunConfig/ArgumentInput'\nimport CodeInput from '@/components/CustomInputs/CodeInput'\nimport ResettableWrapper from '@/components/CustomInputs/ResettableWrapper'\nimport { tryFormatJson } from '@/utils/json'\n\nexport default {\n  components: {\n    ArgumentInput,\n    ResettableWrapper,\n    CodeInput\n  },\n  props: {\n    value: {\n      type: Object,\n      required: true\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    },\n    envValue: {\n      get() {\n        return tryFormatJson(this.internalValue.env)\n      },\n      set(value) {\n        this.internalValue = { ...this.internalValue, env: value }\n      }\n    }\n  },\n  methods: {\n    validate() {\n      return this.$refs.envInput.validate()\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/components/RunConfig/adjectives.js",
    "content": "// Adapted from the coolname Python project: https://github.com/alexanderlukanin13/coolname\n\nexport const adjectives = [\n  'acrid',\n  'ambrosial',\n  'amorphous',\n  'armored',\n  'aromatic',\n  'bald',\n  'blazing',\n  'boisterous',\n  'bouncy',\n  'brawny',\n  'bulky',\n  'camouflaged',\n  'caped',\n  'elastic',\n  'ethereal',\n  'feathered',\n  'fiery',\n  'fluffy',\n  'foamy',\n  'fragrant',\n  'furry',\n  'fuzzy',\n  'glaring',\n  'hairy',\n  'heavy',\n  'hissing',\n  'horned',\n  'icy',\n  'imaginary',\n  'invisible',\n  'lean',\n  'loud',\n  'loutish',\n  'lumpy',\n  'lush',\n  'masked',\n  'meaty',\n  'messy',\n  'misty',\n  'nebulous',\n  'noisy',\n  'nondescript',\n  'organic',\n  'purring',\n  'quiet',\n  'quirky',\n  'radiant',\n  'roaring',\n  'ruddy',\n  'rustling',\n  'screeching',\n  'shaggy',\n  'shapeless',\n  'shiny',\n  'silent',\n  'silky',\n  'singing',\n  'skinny',\n  'smooth',\n  'soft',\n  'spicy',\n  'spiked',\n  'statuesque',\n  'sticky',\n  'tacky',\n  'tall',\n  'tangible',\n  'tentacled',\n  'thundering',\n  'venomous',\n  'warm',\n  'weightless',\n  'whispering',\n  'winged',\n  'wooden',\n  'adorable',\n  'affable',\n  'amazing',\n  'amiable',\n  'attractive',\n  'beautiful',\n  'calm',\n  'charming',\n  'cherubic',\n  'classic',\n  'classy',\n  'convivial',\n  'cordial',\n  'cuddly',\n  'curly',\n  'cute',\n  'debonair',\n  'elegant',\n  'famous',\n  'fresh',\n  'friendly',\n  'funny',\n  'gorgeous',\n  'graceful',\n  'gregarious',\n  'grinning',\n  'handsome',\n  'hilarious',\n  'hot',\n  'interesting',\n  'kind',\n  'laughing',\n  'lovely',\n  'meek',\n  'mellow',\n  'merciful',\n  'neat',\n  'nifty',\n  'notorious',\n  'poetic',\n  'pretty',\n  'refined',\n  'refreshing',\n  'smiling',\n  'sociable',\n  'spiffy',\n  'stylish',\n  'sweet',\n  'tactful',\n  'whimsical',\n  'abiding',\n  'accurate',\n  'adamant',\n  'adaptable',\n  'adventurous',\n  'alluring',\n  'aloof',\n  'ambitious',\n  'amusing',\n  'annoying',\n  'arrogant',\n  'aspiring',\n  'belligerent',\n  'benign',\n  'berserk',\n  'benevolent',\n  'bold',\n  'brave',\n  'cheerful',\n  'chirpy',\n  'cocky',\n  'congenial',\n  'courageous',\n  'cryptic',\n  'curious',\n  'daft',\n  'dainty',\n  'daring',\n  'defiant',\n  'delicate',\n  'delightful',\n  'determined',\n  'devout',\n  'didactic',\n  'diligent',\n  'discreet',\n  'dramatic',\n  'dynamic',\n  'eager',\n  'eccentric',\n  'elated',\n  'encouraging',\n  'enigmatic',\n  'enthusiastic',\n  'evasive',\n  'faithful',\n  'fair',\n  'fanatic',\n  'fearless',\n  'fervent',\n  'festive',\n  'fierce',\n  'fine',\n  'free',\n  'gabby',\n  'garrulous',\n  'gentle',\n  'glistening',\n  'greedy',\n  'grumpy',\n  'happy',\n  'honest',\n  'hopeful',\n  'hospitable',\n  'impetuous',\n  'independent',\n  'industrious',\n  'innocent',\n  'intrepid',\n  'jolly',\n  'jovial',\n  'just',\n  'lively',\n  'loose',\n  'loyal',\n  'merry',\n  'modest',\n  'mysterious',\n  'nice',\n  'obedient',\n  'optimistic',\n  'orthodox',\n  'outgoing',\n  'outrageous',\n  'overjoyed',\n  'passionate',\n  'perky',\n  'placid',\n  'polite',\n  'positive',\n  'proud',\n  'prudent',\n  'puzzling',\n  'quixotic',\n  'quizzical',\n  'rebel',\n  'resolute',\n  'rampant',\n  'righteous',\n  'romantic',\n  'rough',\n  'rousing',\n  'sassy',\n  'satisfied',\n  'sly',\n  'sincere',\n  'snobbish',\n  'spirited',\n  'spry',\n  'stalwart',\n  'stirring',\n  'swinging',\n  'tasteful',\n  'thankful',\n  'tidy',\n  'tremendous',\n  'truthful',\n  'unselfish',\n  'upbeat',\n  'uppish',\n  'valiant',\n  'vehement',\n  'vengeful',\n  'vigorous',\n  'vivacious',\n  'zealous',\n  'zippy',\n  'able',\n  'adept',\n  'analytic',\n  'astute',\n  'attentive',\n  'brainy',\n  'busy',\n  'calculating',\n  'capable',\n  'careful',\n  'cautious',\n  'certain',\n  'clever',\n  'competent',\n  'conscious',\n  'cooperative',\n  'crafty',\n  'crazy',\n  'cunning',\n  'daffy',\n  'devious',\n  'discerning',\n  'efficient',\n  'expert',\n  'functional',\n  'gifted',\n  'helpful',\n  'enlightened',\n  'idealistic',\n  'impartial',\n  'industrious',\n  'ingenious',\n  'inquisitive',\n  'intelligent',\n  'inventive',\n  'judicious',\n  'keen',\n  'knowing',\n  'literate',\n  'logical',\n  'masterful',\n  'mindful',\n  'nonchalant',\n  'observant',\n  'omniscient',\n  'poised',\n  'practical',\n  'pragmatic',\n  'proficient',\n  'provocative',\n  'qualified',\n  'radical',\n  'rational',\n  'realistic',\n  'resourceful',\n  'savvy',\n  'skeptical',\n  'sensible',\n  'serious',\n  'shrewd',\n  'skilled',\n  'slick',\n  'slim',\n  'smart',\n  'sophisticated',\n  'stoic',\n  'succinct',\n  'talented',\n  'thoughtful',\n  'tricky',\n  'unbiased',\n  'uptight',\n  'versatile',\n  'versed',\n  'visionary',\n  'wise',\n  'witty',\n  'accelerated',\n  'active',\n  'agile',\n  'athletic',\n  'dashing',\n  'deft',\n  'dexterous',\n  'energetic',\n  'fast',\n  'frisky',\n  'hasty',\n  'hypersonic',\n  'meteoric',\n  'mighty',\n  'muscular',\n  'nimble',\n  'powerful',\n  'prompt',\n  'quick',\n  'rapid',\n  'resilient',\n  'robust',\n  'rugged',\n  'solid',\n  'speedy',\n  'steadfast',\n  'steady',\n  'strong',\n  'sturdy',\n  'tireless',\n  'tough',\n  'unyielding',\n  'rich',\n  'wealthy',\n  'meticulous',\n  'precise',\n  'rigorous',\n  'scrupulous',\n  'strict',\n  'airborne',\n  'burrowing',\n  'crouching',\n  'flying',\n  'hidden',\n  'hopping',\n  'jumping',\n  'lurking',\n  'tunneling',\n  'warping',\n  'aboriginal',\n  'amphibian',\n  'aquatic',\n  'arboreal',\n  'polar',\n  'terrestrial',\n  'urban',\n  'accomplished',\n  'astonishing',\n  'authentic',\n  'awesome',\n  'delectable',\n  'excellent',\n  'exotic',\n  'exuberant',\n  'fabulous',\n  'fantastic',\n  'fascinating',\n  'flawless',\n  'fortunate',\n  'glorious',\n  'groovy',\n  'honored',\n  'illustrious',\n  'imposing',\n  'important',\n  'impressive',\n  'incredible',\n  'invaluable',\n  'majestic',\n  'magnificent',\n  'marvellous',\n  'monumental',\n  'perfect',\n  'phenomenal',\n  'pompous',\n  'precious',\n  'premium',\n  'private',\n  'remarkable',\n  'spectacular',\n  'splendid',\n  'successful',\n  'wonderful',\n  'wondrous',\n  'offbeat',\n  'original',\n  'outstanding',\n  'quaint',\n  'unique',\n  'ancient',\n  'antique',\n  'prehistoric',\n  'primitive',\n  'abstract',\n  'acoustic',\n  'angelic',\n  'arcane',\n  'archetypal',\n  'augmented',\n  'auspicious',\n  'axiomatic',\n  'beneficial',\n  'bipedal',\n  'bizarre',\n  'complex',\n  'dancing',\n  'dangerous',\n  'divergent',\n  'economic',\n  'electric',\n  'elite',\n  'eminent',\n  'enchanted',\n  'esoteric',\n  'finicky',\n  'fractal',\n  'futuristic',\n  'gainful',\n  'hallowed',\n  'heavenly',\n  'holistic',\n  'hungry',\n  'hypnotic',\n  'hysterical',\n  'illegal',\n  'imperial',\n  'imported',\n  'impossible',\n  'inescapable',\n  'liberal',\n  'ludicrous',\n  'lyrical',\n  'magnetic',\n  'manipulative',\n  'mature',\n  'military',\n  'macho',\n  'married',\n  'melodic',\n  'natural',\n  'naughty',\n  'nocturnal',\n  'nostalgic',\n  'optimal',\n  'pastoral',\n  'peculiar',\n  'piquant',\n  'pristine',\n  'prophetic',\n  'psychedelic',\n  'quantum',\n  'rare',\n  'real',\n  'secret',\n  'simple',\n  'spectral',\n  'spiritual',\n  'stereotyped',\n  'stimulating',\n  'straight',\n  'strange',\n  'tested',\n  'therapeutic',\n  'true',\n  'ubiquitous',\n  'uncovered',\n  'unnatural',\n  'utopian',\n  'vagabond',\n  'vague',\n  'vegan',\n  'victorious',\n  'vigilant',\n  'voracious',\n  'wakeful',\n  'wandering',\n  'watchful',\n  'wild',\n  'bright',\n  'brilliant',\n  'colorful',\n  'crystal',\n  'dark',\n  'dazzling',\n  'fluorescent',\n  'glittering',\n  'glossy',\n  'gleaming',\n  'light',\n  'mottled',\n  'neon',\n  'opalescent',\n  'pastel',\n  'smoky',\n  'sparkling',\n  'spotted',\n  'striped',\n  'translucent',\n  'transparent',\n  'vivid'\n]\n"
  },
  {
    "path": "src/components/RunConfig/animals.js",
    "content": "// Adapted from the coolname Python project: https://github.com/alexanderlukanin13/coolname\n\nexport const animals = [\n  'earthworm',\n  'leech',\n  'worm',\n  'scorpion',\n  'spider',\n  'tarantula',\n  'barnacle',\n  'crab',\n  'crayfish',\n  'lobster',\n  'pillbug',\n  'prawn',\n  'shrimp',\n  'ant',\n  'bee',\n  'beetle',\n  'bug',\n  'bumblebee',\n  'butterfly',\n  'caterpillar',\n  'cicada',\n  'cricket',\n  'dragonfly',\n  'earwig',\n  'firefly',\n  'grasshopper',\n  'honeybee',\n  'hornet',\n  'inchworm',\n  'ladybug',\n  'locust',\n  'mantis',\n  'mayfly',\n  'mosquito',\n  'moth',\n  'sawfly',\n  'silkworm',\n  'termite',\n  'wasp',\n  'woodlouse',\n  'centipede',\n  'millipede',\n  'pronghorn',\n  'antelope',\n  'bison',\n  'buffalo',\n  'bull',\n  'chamois',\n  'cow',\n  'gazelle',\n  'gaur',\n  'goat',\n  'ibex',\n  'impala',\n  'kudu',\n  'markhor',\n  'mouflon',\n  'muskox',\n  'nyala',\n  'sheep',\n  'wildebeest',\n  'yak',\n  'zebu',\n  'alpaca',\n  'camel',\n  'llama',\n  'vicugna',\n  'caribou',\n  'chital',\n  'deer',\n  'elk',\n  'moose',\n  'pudu',\n  'reindeer',\n  'sambar',\n  'wapiti',\n  'beluga',\n  'dolphin',\n  'narwhal',\n  'orca',\n  'porpoise',\n  'whale',\n  'donkey',\n  'horse',\n  'stallion',\n  'zebra',\n  'giraffe',\n  'okapi',\n  'hippo',\n  'rhino',\n  'boar',\n  'hog',\n  'pig',\n  'swine',\n  'warthog',\n  'peccary',\n  'buzzard',\n  'eagle',\n  'goshawk',\n  'harrier',\n  'hawk',\n  'vulture',\n  'duck',\n  'goose',\n  'swan',\n  'teal',\n  'bird',\n  'hummingbird',\n  'swift',\n  'kiwi',\n  'potoo',\n  'seriema',\n  'cassowary',\n  'emu',\n  'condor',\n  'auk',\n  'avocet',\n  'guillemot',\n  'kittiwake',\n  'puffin',\n  'seagull',\n  'skua',\n  'stork',\n  'dodo',\n  'dove',\n  'pigeon',\n  'kingfisher',\n  'tody',\n  'bustard',\n  'coua',\n  'coucal',\n  'cuckoo',\n  'koel',\n  'malkoha',\n  'roadrunner',\n  'kagu',\n  'caracara',\n  'falcon',\n  'kestrel',\n  'chachalaca',\n  'chicken',\n  'curassow',\n  'grouse',\n  'guan',\n  'junglefowl',\n  'partridge',\n  'peacock',\n  'pheasant',\n  'quail',\n  'rooster',\n  'turkey',\n  'loon',\n  'coot',\n  'crane',\n  'turaco',\n  'hoatzin',\n  'bullfinch',\n  'crow',\n  'jackdaw',\n  'jaybird',\n  'finch',\n  'lyrebird',\n  'magpie',\n  'myna',\n  'nightingale',\n  'nuthatch',\n  'oriole',\n  'oxpecker',\n  'raven',\n  'robin',\n  'rook',\n  'skylark',\n  'sparrow',\n  'starling',\n  'swallow',\n  'waxbill',\n  'wren',\n  'heron',\n  'ibis',\n  'jacamar',\n  'piculet',\n  'toucan',\n  'toucanet',\n  'woodpecker',\n  'flamingo',\n  'grebe',\n  'albatross',\n  'fulmar',\n  'petrel',\n  'spoonbill',\n  'ara',\n  'cockatoo',\n  'kakapo',\n  'lorikeet',\n  'macaw',\n  'parakeet',\n  'parrot',\n  'penguin',\n  'ostrich',\n  'boobook',\n  'owl',\n  'cormorant',\n  'frigatebird',\n  'pelican',\n  'quetzal',\n  'trogon',\n  'axolotl',\n  'bullfrog',\n  'frog',\n  'newt',\n  'salamander',\n  'toad',\n  'angelfish',\n  'barracuda',\n  'carp',\n  'catfish',\n  'dogfish',\n  'goldfish',\n  'guppy',\n  'eel',\n  'flounder',\n  'herring',\n  'lionfish',\n  'mackerel',\n  'oarfish',\n  'perch',\n  'salmon',\n  'seahorse',\n  'sturgeon',\n  'sunfish',\n  'tench',\n  'trout',\n  'tuna',\n  'wrasse',\n  'sawfish',\n  'shark',\n  'stingray',\n  'jellyfish',\n  'alligator',\n  'caiman',\n  'crocodile',\n  'gharial',\n  'starfish',\n  'urchin',\n  'hedgehog',\n  'coyote',\n  'dingo',\n  'dog',\n  'fennec',\n  'fox',\n  'hound',\n  'jackal',\n  'tanuki',\n  'wolf',\n  'bobcat',\n  'caracal',\n  'cat',\n  'cougar',\n  'jaguar',\n  'jaguarundi',\n  'leopard',\n  'lion',\n  'lynx',\n  'manul',\n  'ocelot',\n  'panther',\n  'puma',\n  'serval',\n  'smilodon',\n  'tiger',\n  'wildcat',\n  'aardwolf',\n  'binturong',\n  'cheetah',\n  'civet',\n  'fossa',\n  'hyena',\n  'meerkat',\n  'mongoose',\n  'badger',\n  'coati',\n  'ermine',\n  'ferret',\n  'marten',\n  'mink',\n  'otter',\n  'polecat',\n  'skunk',\n  'stoat',\n  'weasel',\n  'wolverine',\n  'seal',\n  'walrus',\n  'raccoon',\n  'ringtail',\n  'bear',\n  'panda',\n  'bat',\n  'armadillo',\n  'elephant',\n  'mammoth',\n  'mastodon',\n  'mole',\n  'hyrax',\n  'bandicoot',\n  'bettong',\n  'cuscus',\n  'kangaroo',\n  'koala',\n  'numbat',\n  'quokka',\n  'quoll',\n  'wallaby',\n  'wombat',\n  'echidna',\n  'platypus',\n  'tapir',\n  'anteater',\n  'sloth',\n  'agouti',\n  'capybara',\n  'chinchilla',\n  'chipmunk',\n  'degu',\n  'dormouse',\n  'gerbil',\n  'gopher',\n  'groundhog',\n  'jackrabbit',\n  'jerboa',\n  'hamster',\n  'hare',\n  'lemming',\n  'marmot',\n  'mouse',\n  'muskrat',\n  'porcupine',\n  'rabbit',\n  'rat',\n  'squirrel',\n  'vole',\n  'ape',\n  'baboon',\n  'bonobo',\n  'capuchin',\n  'chimpanzee',\n  'galago',\n  'gibbon',\n  'gorilla',\n  'lemur',\n  'lori',\n  'macaque',\n  'mandrill',\n  'marmoset',\n  'monkey',\n  'orangutan',\n  'tamarin',\n  'tarsier',\n  'uakari',\n  'dugong',\n  'manatee',\n  'shrew',\n  'aardwark',\n  'clam',\n  'cockle',\n  'mussel',\n  'oyster',\n  'scallop',\n  'shellfish',\n  'ammonite',\n  'cuttlefish',\n  'nautilus',\n  'octopus',\n  'squid',\n  'limpet',\n  'slug',\n  'snail',\n  'sponge',\n  'tuatara',\n  'agama',\n  'chameleon',\n  'dragon',\n  'gecko',\n  'iguana',\n  'lizard',\n  'pogona',\n  'skink',\n  'adder',\n  'anaconda',\n  'asp',\n  'boa',\n  'cobra',\n  'copperhead',\n  'mamba',\n  'python',\n  'rattlesnake',\n  'sidewinder',\n  'snake',\n  'taipan',\n  'viper',\n  'tortoise',\n  'turtle',\n  'dinosaur',\n  'raptor',\n  'mushroom'\n]\n"
  },
  {
    "path": "src/components/RunStateTooltip.vue",
    "content": "<script>\nexport default {\n  props: {\n    states: { type: Array, required: true }\n  }\n}\n</script>\n\n<template functional>\n  <div class=\"v-tooltip__content tooltip\">\n    <div v-for=\"(state, i) in props.states\" :key=\"i\">\n      <div class=\"text-body-1 \">\n        <span class=\"font-weight-medium\" :style=\"{ color: state.color }\">\n          {{ state.label }}\n        </span>\n        at\n        {{ state.formattedTime }}\n      </div>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.tooltip {\n  height: auto;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/components/ScheduleToggle.vue",
    "content": "<script>\nimport { mapGetters, mapActions } from 'vuex'\n\nexport default {\n  props: {\n    flow: {\n      required: true,\n      type: Object\n    },\n    flowGroup: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      loading: false,\n      optimisticIsScheduled: this.flow.is_schedule_active\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('license', ['hasPermission']),\n    archived() {\n      return this.flow.archived\n    },\n    disableToggle() {\n      const c = !this.hasPermission('create', 'run')\n      const d = !this.hasPermission('delete', 'run')\n      const scheduled = this.isScheduled\n\n      return (c && d) || (!scheduled && c) || (scheduled && d)\n    },\n\n    isScheduled() {\n      if (this.archived) return false\n      return this.optimisticIsScheduled\n    },\n    schedule() {\n      return (\n        this.flow.schedule?.clocks?.[0] || this.flowGroup.schedule?.clocks?.[0]\n      )\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    async scheduleFlow() {\n      try {\n        this.loading = true\n        let response\n        if (this.isScheduled) {\n          response = await this.$apollo.mutate({\n            mutation: require('@/graphql/Mutations/set-schedule-inactive.gql'),\n            variables: {\n              id: this.flow.id\n            }\n          })\n          if (response.data.set_schedule_inactive.success) {\n            this.alertShow = true\n            this.alertMessage = 'Schedule paused'\n            this.alertType = 'info'\n            this.optimisticIsScheduled = false\n          } else {\n            this.alertShow = true\n            this.alertMessage =\n              '\"Something went wrong. Please wait a few moments and try again.\"'\n            this.alertType = 'error'\n          }\n        } else if (!this.isScheduled) {\n          response = await this.$apollo.mutate({\n            mutation: require('@/graphql/Mutations/set-schedule-active.gql'),\n            variables: {\n              id: this.flow.id\n            }\n          })\n          if (response.data.set_schedule_active.success) {\n            this.alertShow = true\n            this.alertMessage = 'Schedule activated'\n            this.alertType = 'info'\n            this.optimisticIsScheduled = true\n          } else {\n            this.alertShow = true\n            this.alertMessage =\n              '\"Something went wrong. Please wait a few moments and try again.\"'\n            this.alertType = 'error'\n          }\n        }\n      } catch (error) {\n        this.alertShow = true\n        this.alertMessage =\n          '\"Something went wrong. Please wait a few moments and try again.\"'\n        this.alertType = 'error'\n        throw error\n      } finally {\n        this.loading = false\n        this.setAlert({\n          alertShow: this.alertShow,\n          alertMessage: this.alertMessage,\n          alertType: this.alertType,\n          alertLink: this.alertLink\n        })\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"position-relative\">\n    <v-tooltip bottom>\n      <template #activator=\"{ on }\">\n        <div class=\"schedule-toggle\" v-on=\"on\">\n          <v-badge\n            :value=\"schedule == null && isScheduled\"\n            color=\"warning\"\n            icon=\"priority_high\"\n            overlap\n            top\n            left\n          >\n            <v-switch\n              v-model=\"isScheduled\"\n              data-cy=\"schedule-toggle\"\n              class=\"small-switch\"\n              color=\"primary\"\n              :loading=\"loading\"\n              :disabled=\"disableToggle || archived\"\n              inset\n              dense\n              hide-details\n              @change=\"scheduleFlow\"\n            >\n            </v-switch>\n          </v-badge>\n        </div>\n      </template>\n      <span v-if=\"!hasPermission('create', 'run')\">\n        You don't have permission to schedule flows.\n      </span>\n      <span v-else-if=\"schedule == null && isScheduled\">\n        This flow is trying to schedule runs but has no schedules! Visit this\n        flow's\n        <span class=\"font-weight-bold\">Settings > Schedules</span> to set a new\n        schedule.\n      </span>\n      <span v-else-if=\"archived\">\n        Archived flows cannot be scheduled.\n      </span>\n      <span v-else>\n        Turn {{ isScheduled ? 'off' : 'on' }} this flow's schedule\n      </span>\n    </v-tooltip>\n  </div>\n</template>\n\n<style lang=\"scss\">\n.schedule-toggle {\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n</style>\n"
  },
  {
    "path": "src/components/Schematics/Legend.vue",
    "content": "<script>\nexport default {\n  props: {\n    tasks: { type: Array, required: true }\n  },\n  computed: {\n    states() {\n      // Reduce to just states\n      // create a set (dedupe) from the states array\n      return [...new Set(this.tasks?.map(t => t.state).sort())]\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card tile min-width=\"200\" max-width=\"200\">\n    <v-card-text class=\"pa-0\" style=\"overflow: hidden;\">\n      <height-transition>\n        <v-list-item v-for=\"state in states\" :key=\"state\">\n          <v-list-item-avatar class=\"my-0\" tile>\n            <v-icon :color=\"state\">fas fa-square-full</v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <v-list-item-title class=\"text-body-2\">\n              {{ state }}\n            </v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n      </height-transition>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\">\n//\n//\n</style>\n"
  },
  {
    "path": "src/components/Schematics/Preview-Dynamic.vue",
    "content": "<script>\n// import moment from '@/utils/moment'\nimport { STATE_COLORS } from '@/utils/states'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  filters: {\n    typeClass: val => val.split('.').pop(),\n    shortenString: str => (str.length > 20 ? str.substring(0, 20) + '...' : str)\n  },\n  mixins: [formatTime],\n  props: {\n    task: {\n      type: Object,\n      required: true\n    },\n    runs: {\n      type: Array,\n      required: false,\n      default: () => []\n    }\n  },\n  data() {\n    return { expanded: true }\n  },\n  computed: {\n    resultExists() {\n      return this.task?.serialized_state?._result\n    },\n    expectedRuns() {\n      return (\n        this.task?.serialized_state?.n_map_states || 'Unknown'\n      ).toLocaleString()\n    }\n  },\n  methods: {\n    runStyle(state) {\n      return {\n        'border-left': state\n          ? `0.5rem solid ${\n              this.disabled\n                ? this.hex2RGBA(STATE_COLORS[state])\n                : STATE_COLORS[state]\n            } !important`\n          : ''\n      }\n    },\n    stateClass(state) {\n      const lightStates = [\n        'Submitted',\n        'Cancelled',\n        'Cancelling',\n        'Queued',\n        'Pending'\n      ]\n\n      const textColor = lightStates.includes(state)\n        ? ['grey--text', 'text--darken-4']\n        : ['white--text']\n\n      return [state, ...textColor]\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.mappedChildren.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    mappedChildren: {\n      query: require('@/graphql/MappedTasks/mapped-children.gql'),\n      variables() {\n        return {\n          taskRunId: this.task.id\n        }\n      },\n      skip() {\n        return this.task.state !== 'Mapped' || !this.task.id\n      },\n      pollInterval: 3000,\n      update: data => data.mapped_children\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card-text\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"full-height position-relative pa-0 text-caption\"\n  >\n    <v-list-item\n      class=\"py-2 pr-2 pl-3\"\n      dense\n      :to=\"{ name: 'task-run', params: { id: task.id } }\"\n      :style=\"runStyle(task.state)\"\n    >\n      <v-list-item-content class=\"my-0 py-0\">\n        <v-list-item-subtitle class=\"text-caption mb-0\">\n          Task Run\n        </v-list-item-subtitle>\n        <v-list-item-title>\n          <span>\n            {{ task.flow_run_name }} -\n            {{ task.name ? task.name : task.task.name }}\n          </span>\n        </v-list-item-title>\n        <v-list-item-subtitle class=\"text-caption\">\n          <v-tooltip top>\n            <template #activator=\"{ on }\">\n              <span v-on=\"on\">\n                <span :class=\"`${task.state}--text`\">\n                  {{ task.state }}\n                </span>\n                - {{ formDate(task.state_timestamp) }}\n              </span>\n            </template>\n            <span>\n              {{ formatTime(task.state_timestamp) }}\n            </span>\n          </v-tooltip>\n        </v-list-item-subtitle>\n      </v-list-item-content>\n      <v-list-item-avatar class=\"text-body-2\">\n        <v-icon class=\"utilGrayMid--text\">\n          arrow_right\n        </v-icon>\n      </v-list-item-avatar>\n    </v-list-item>\n\n    <v-list-item\n      dense\n      class=\"py-2 pr-2 pl-5\"\n      :to=\"{ name: 'task', params: { id: task.task.id } }\"\n    >\n      <v-list-item-content class=\"my-0 py-0\">\n        <v-list-item-subtitle class=\"text-caption mb-0\">\n          Task\n        </v-list-item-subtitle>\n        <v-list-item-title>\n          {{ task.task.name }}\n        </v-list-item-title>\n      </v-list-item-content>\n\n      <v-list-item-avatar class=\"text-body-2\">\n        <v-icon class=\"utilGrayMid--text\">\n          arrow_right\n        </v-icon>\n      </v-list-item-avatar>\n    </v-list-item>\n\n    <v-divider></v-divider>\n\n    <v-card-text class=\"pb-0 pl-3 pr-2 text-caption\">\n      <v-row>\n        <v-col cols=\"12\" class=\"pb-0 pt-0\">\n          <span class=\"utilGrayDark--text\">Task Run State Message:</span>\n        </v-col>\n        <v-col cols=\"12\" class=\"pt-0\">\n          {{ task.state_message }}\n        </v-col>\n      </v-row>\n\n      <v-row>\n        <v-col cols=\"6\" class=\"pt-0\">\n          <span class=\"utilGrayDark--text\">Max retries:</span>\n        </v-col>\n        <v-col cols=\"6\" class=\"text-right pt-0\">\n          {{ task.task.max_retries }}\n        </v-col>\n      </v-row>\n\n      <v-row v-if=\"task.task.max_retries > 0\">\n        <v-col cols=\"6\" class=\"pt-0\">\n          <span class=\"utilGrayDark--text\">Retry delay:</span>\n        </v-col>\n        <v-col cols=\"6\" class=\"text-right pt-0\">\n          {{ task.task.retry_delay }}\n        </v-col>\n      </v-row>\n\n      <v-row v-if=\"task.state == 'Mapped'\">\n        <v-col cols=\"6\" class=\"pt-0\">\n          <span class=\"utilGrayDark--text\">Expected Runs:</span>\n        </v-col>\n        <v-col cols=\"6\" class=\"text-right pt-0\">\n          <v-tooltip max-width=\"300px\" top>\n            <template #activator=\"{ on }\">\n              <span v-on=\"on\">\n                {{ expectedRuns }}\n              </span>\n            </template>\n            <span v-if=\"!task.serialized_state.n_map_states\">\n              This data is only available on Flows registered with Prefect Core\n              0.13.5+\n            </span>\n            <span v-else>\n              The number of mapped children expected to run. Note that the\n              number of active mapped runs may be less than this if some have\n              not yet entered a <code>Pending</code> state.\n            </span>\n          </v-tooltip>\n        </v-col>\n      </v-row>\n\n      <v-row v-if=\"resultExists\">\n        <v-col cols=\"6\" class=\"pt-0\">\n          <span class=\"utilGrayDark--text\">Result Type:</span>\n        </v-col>\n        <v-col cols=\"6\" class=\"text-right pt-0\">\n          {{ task.serialized_state._result.type | typeClass }}\n        </v-col>\n      </v-row>\n\n      <v-row v-if=\"resultExists\">\n        <v-col cols=\"6\" class=\"pt-0\">\n          <span class=\"utilGrayDark--text\">Result Location:</span>\n        </v-col>\n        <v-col cols=\"6\" class=\"text-right pt-0\">\n          <v-tooltip top>\n            <template #activator=\"{ on }\">\n              <span v-on=\"on\">\n                {{\n                  task.serialized_state._result.location ||\n                    'None' | shortenString\n                }}\n              </span>\n            </template>\n            <div>\n              {{ task.serialized_state._result.location || 'None' }}\n            </div>\n          </v-tooltip>\n        </v-col>\n      </v-row>\n    </v-card-text>\n\n    <v-card-actions v-if=\"mappedChildren\" class=\"pl-3\">\n      <div>\n        <div class=\"text-body-1 utilGrayDark--text\">Mapped Runs</div>\n\n        <v-chip-group column>\n          <v-chip\n            v-for=\"state in Object.keys(mappedChildren.state_counts)\"\n            :key=\"state\"\n            class=\"px-4 font-weight-bold\"\n            :class=\"stateClass(state)\"\n            label\n            small\n          >\n            {{ state }}\n            <span class=\"font-weight-medium ml-1\">\n              ({{ mappedChildren.state_counts[state].toLocaleString() }})\n            </span>\n          </v-chip>\n        </v-chip-group>\n      </div>\n    </v-card-actions>\n\n    <v-card-actions v-if=\"runs && runs.length > 0\" class=\"px-0 py-0\">\n      <v-list dense style=\"width: 100%;\" class=\"py-0\">\n        <v-list-group v-model=\"expanded\" no-action dense value=\"true\">\n          <template #activator>\n            <v-list-item-content class=\"pa-0\">\n              <v-list-item-title class=\"text-body-2 d-flex align-end\">\n                <v-icon class=\"utilGrayDark--text mr-6\" small\n                  >trending_up</v-icon\n                >\n                <span class=\"font-weight-black mr-1\">\n                  {{ runs.length }}\n                </span>\n                Mapped Run{{ runs.length > 1 ? 's' : '' }}\n              </v-list-item-title>\n            </v-list-item-content>\n          </template>\n\n          <template #appendIcon>\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon>arrow_drop_down</v-icon>\n            </v-list-item-avatar>\n          </template>\n\n          <v-divider></v-divider>\n\n          <v-list-item-group class=\"mapped-tasks-container\">\n            <v-lazy\n              v-for=\"run in runs\"\n              :key=\"run.id\"\n              :options=\"{\n                threshold: 0.75\n              }\"\n              min-height=\"40px\"\n              transition=\"fade\"\n            >\n              <v-list-item\n                dense\n                two-line\n                class=\"px-2 py-1\"\n                :to=\"{ name: 'task-run', params: { id: run.id } }\"\n                :style=\"runStyle(run.state)\"\n              >\n                <v-tooltip bottom>\n                  <template #activator=\"{ on }\">\n                    <v-list-item-content v-on=\"on\">\n                      <v-list-item-title>\n                        {{ run.state }}\n                      </v-list-item-title>\n                      <v-list-item-subtitle class=\"text-caption\">\n                        {{ run.state_message }}\n                      </v-list-item-subtitle>\n                    </v-list-item-content>\n                  </template>\n                  <span>\n                    {{ run.state_message }}\n                  </span>\n                </v-tooltip>\n                <v-list-item-avatar\n                  class=\"text-caption\"\n                  style=\"\n                  border-radius: unset !important;\n                  min-width: 85px;\"\n                >\n                  {{ formatTime(run.state_timestamp) }}\n                </v-list-item-avatar>\n              </v-list-item>\n            </v-lazy>\n          </v-list-item-group>\n        </v-list-group>\n      </v-list>\n    </v-card-actions>\n  </v-card-text>\n</template>\n\n<style lang=\"scss\" scoped>\n.mapped-tasks-container {\n  max-height: 20vh;\n  overflow: scroll;\n}\n</style>\n"
  },
  {
    "path": "src/components/Schematics/Preview-SearchResult.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\n// Added this line to disable to the v-html\n// console warning since we've hard-coded the data\nexport default {\n  props: {\n    searchResult: {\n      required: true,\n      type: Object,\n      validator: result => {\n        return result.id && result.name\n      }\n    },\n    // This is a reference to the parent passed in by the VAutoComplete\n    // component. It contains important search highlighting methods\n    // but we don't use it for much else. It's typed as an Object\n    // and we're making sure the .genFilteredText() method exists on the\n    // passed prop.\n    parent: {\n      type: Object,\n      required: true,\n      validator: parent => {\n        return parent.genFilteredText\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"search-result\">\n    <v-list-item-content>\n      <!-- the .genFilteredText() method calls a number of downstream methods\n       on the parent component. This allows us to show where the user input\n      matches the results we're returning to them.\n      Since it returns HTML, we need to use the Vue HTML injector, otherwise\n      it'll be inserted as plaintext. -->\n      <v-list-item-title\n        v-html=\"`${parent.genFilteredText(searchResult.name)}`\"\n      />\n      <v-list-item-subtitle class=\"id-subtitle\">\n        {{ searchResult.id }}\n      </v-list-item-subtitle>\n    </v-list-item-content>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.search-result {\n  cursor: pointer;\n  min-width: 15rem;\n}\n\n.id-subtitle {\n  font-size: 0.6rem !important;\n}\n</style>\n"
  },
  {
    "path": "src/components/Schematics/Preview-Static.vue",
    "content": "<script>\nexport default {\n  filters: {\n    typeClass: val => val.split('.').pop()\n  },\n  props: {\n    task: {\n      type: Object,\n      required: true\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card-text class=\"pa-0 text-caption\">\n    <v-list-item\n      dense\n      class=\"py-2 pr-2 pl-5\"\n      :to=\"{ name: 'task', params: { id: task.id } }\"\n    >\n      <v-list-item-content class=\"my-0 py-0\">\n        <v-list-item-subtitle class=\"text-caption mb-0\">\n          Task\n        </v-list-item-subtitle>\n        <v-list-item-title>\n          {{ task.name }}\n        </v-list-item-title>\n      </v-list-item-content>\n\n      <v-list-item-avatar class=\"text-body-2\">\n        <v-icon class=\"grey--text text--darken-2\">\n          arrow_right\n        </v-icon>\n      </v-list-item-avatar>\n    </v-list-item>\n\n    <v-divider></v-divider>\n\n    <v-card-text class=\"pb-0 pl-3 pr-2 text-caption\">\n      <v-row>\n        <v-col cols=\"6\" class=\"pt-0\">\n          <span class=\"utilGrayDark--text\">Max retries:</span>\n        </v-col>\n        <v-col cols=\"6\" class=\"text-right pt-0\">\n          {{ task.max_retries }}\n        </v-col>\n      </v-row>\n\n      <v-row v-if=\"task.max_retries > 0\">\n        <v-col cols=\"6\" class=\"pt-0\">\n          <span class=\"utilGrayDark--text\">Retry delay:</span>\n        </v-col>\n        <v-col cols=\"6\" class=\"text-right pt-0\">\n          {{ task.retry_delay }}\n        </v-col>\n      </v-row>\n\n      <v-row>\n        <v-col cols=\"6\" class=\"pt-0\">\n          <span class=\"utilGrayDark--text\">Class:</span>\n        </v-col>\n        <v-col cols=\"6\" class=\"text-right pt-0\">\n          {{ task.type | typeClass }}\n        </v-col>\n      </v-row>\n\n      <v-row>\n        <v-col cols=\"6\" class=\"pt-0\">\n          <span class=\"utilGrayDark--text\">Trigger:</span>\n        </v-col>\n        <v-col cols=\"6\" class=\"text-right pt-0\">\n          {{ task.trigger | typeClass }}\n        </v-col>\n      </v-row>\n    </v-card-text>\n  </v-card-text>\n</template>\n"
  },
  {
    "path": "src/components/Schematics/Preview-Tile.vue",
    "content": "<script>\nimport SearchResult from '@/components/Schematics/Preview-SearchResult'\n\n// Type content\nimport StaticPreview from '@/components/Schematics/Preview-Static'\nimport DynamicPreview from '@/components/Schematics/Preview-Dynamic'\n\nexport default {\n  components: {\n    SearchResult,\n    DynamicPreview,\n    StaticPreview\n  },\n  props: {\n    options: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    tasks: {\n      type: Array,\n      required: true\n    }\n  },\n  data() {\n    return {\n      runs: null,\n      search: null,\n      searchInput: null,\n      showDetails: true,\n      task: null\n    }\n  },\n  computed: {\n    isRun() {\n      return this.tasks?.[0].__typename == 'task_run'\n    }\n  },\n  watch: {\n    '$route.query.schematic'(val) {\n      if (!val) {\n        this.task = null\n        this.searchInput = null\n      } else {\n        this.updatePreview()\n      }\n    },\n    searchInput(val) {\n      let selected = this.options.find(opt => opt.name == val)\n      if (selected) this.handleSelect(selected)\n    },\n    tasks() {\n      if (!this.$route.query.schematic) {\n        this.task = null\n      } else {\n        this.updatePreview()\n      }\n    }\n  },\n  mounted() {\n    if (!this.$route.query.schematic) return\n    this.updatePreview()\n  },\n  methods: {\n    handleBlur() {\n      this.showDetails = true\n    },\n    handleClear() {\n      this.$emit('clear-task')\n    },\n    handleFocus() {\n      this.showDetails = false\n    },\n    handleSelect(task) {\n      this.$emit('select-task', task)\n    },\n    searchFilter(item, queryText) {\n      // This is the filter we use to determine what the VAutocomplete\n      // method is showing. We transform all queries to lowercase\n      // for comparison for a better UX\n      return (\n        item['id'].toLowerCase().includes(queryText.toLowerCase()) ||\n        item['name'].toLowerCase().includes(queryText.toLowerCase())\n      )\n    },\n    updatePreview() {\n      if (!this.isRun) {\n        this.task = this.tasks.find(\n          task => task.id == this.$route.query.schematic\n        )\n        return\n      }\n\n      let runs = this.tasks.filter(\n        task => task.task.id == this.$route.query.schematic\n      )\n\n      let index =\n        runs.length > 1 ? runs.findIndex(task => task.state == 'Mapped') : 0\n\n      this.task = runs.splice(index, 1)[0]\n      this.runs = runs\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"preview-tile\" tile>\n    <v-autocomplete\n      data-public\n      v-model=\"searchInput\"\n      autocomplete=\"new-password\"\n      class=\"mx-0 py-0\"\n      auto-select-first\n      background-color=\"appForeground\"\n      hide-details\n      single-line\n      flat\n      solo\n      dense\n      clearable\n      :items=\"options\"\n      :search-input.sync=\"search\"\n      :filter=\"searchFilter\"\n      placeholder=\"Search for a task\"\n      prepend-inner-icon=\"search\"\n      item-text=\"name\"\n      disable-lookup\n      @blur=\"handleBlur\"\n      @change=\"handleBlur\"\n      @click:clear=\"handleClear\"\n      @focus=\"handleFocus\"\n    >\n      <template v-if=\"search == null\" #no-data>\n        <v-list-item>\n          <v-list-item-title>\n            Type to search for a <strong>Task</strong> by\n            <strong>name</strong> or <strong>id</strong>\n          </v-list-item-title>\n        </v-list-item>\n      </template>\n      <template v-else #no-data>\n        <v-list-item>\n          <v-list-item-title>\n            No results matched your search.\n          </v-list-item-title>\n        </v-list-item>\n      </template>\n      <template #item=\"data\">\n        <v-lazy\n          :options=\"{\n            threshold: 0.75\n          }\"\n          min-height=\"40px\"\n          transition=\"fade\"\n        >\n          <SearchResult\n            v-if=\"data\"\n            :search-result=\"data.item\"\n            :parent=\"data.parent\"\n          />\n        </v-lazy>\n      </template>\n    </v-autocomplete>\n\n    <DynamicPreview\n      v-if=\"task && isRun && showDetails\"\n      :runs=\"runs\"\n      :task=\"task\"\n    />\n    <StaticPreview v-else-if=\"task && showDetails\" :task=\"task\" />\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n$width: 25rem;\n\n.preview-tile {\n  width: 100%;\n}\n\n.search-input {\n  font-size: 1rem;\n  height: 2rem;\n  max-width: $width;\n}\n\n.v-select-list {\n  max-width: $width;\n}\n</style>\n"
  },
  {
    "path": "src/components/Schematics/Schematic-Flow.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport * as d3_base from 'd3'\nimport { zoom } from 'd3-zoom'\nimport uniqueId from 'lodash/uniqueId'\nimport throttle from 'lodash/throttle'\nimport Legend from '@/components/Schematics/Legend'\nimport LogRocket from 'logrocket'\nimport SchematicNode from '@/components/Schematics/Schematic-Node'\nimport PreviewTile from '@/components/Schematics/Preview-Tile'\nimport Tooltip from '@/components/Schematics/Tooltip'\nimport {\n  curveMetro,\n  makeQuadraticBezierPoints,\n  isDiagonal\n} from '@/utils/curveMetro'\nimport { STATE_COLORS } from '@/utils/states'\n// TODO: Remove the workerize-loader package and adjust this worker to\n// a more classic pub/sub style\nimport SchematicWorker from 'workerize-loader?inline!@/workers/schematic'\n\n// Add our custom curve to d3 base\n// and then merges the libraries together into one\n// access point\nconst d3 = Object.assign({}, d3_base, { curveMetro: curveMetro })\n\nexport default {\n  components: {\n    Legend,\n    SchematicNode,\n    PreviewTile,\n    Tooltip\n  },\n  props: {\n    hideControls: { type: Boolean, required: false, default: () => false },\n    schematicId: { type: String, required: false, default: '' },\n    showCards: { type: Boolean, required: false, default: () => true },\n    showLegend: { type: Boolean, required: false, defaul: () => false },\n    tasks: { type: Array, required: true }\n  },\n  data() {\n    return {\n      id: uniqueId('schematic'),\n      canvas: null,\n      offscreenCanvas: null,\n      canvasAdjustment: { h: 0, w: 0 },\n      canvasFocus: false,\n      collapsed: true,\n      context: null,\n      offscreenContext: null,\n      curve: 'curveMetro',\n      custom: null,\n      dag: null,\n      debug: false,\n      defaultEdgeColor: { r: 132, g: 132, b: 132, a: 1 },\n      defaultArrowColor: { r: 132, g: 132, b: 132, a: 1 },\n      defaultNodeColor: { r: 0, g: 118, b: 255, a: 1 },\n      edgeColorUpstream: { r: 255, g: 238, b: 88, a: 0.7 },\n      edgeColorDownstream: { r: 249, g: 168, b: 37, a: 0.7 },\n      edgeColor: null,\n      error: false,\n      errorReportLoading: false,\n      errorSubmitted: false,\n      fadedNodeColor: { r: 189, g: 189, b: 189, a: 1 },\n      fadedEdgeColor: { r: 220, g: 220, b: 220, a: 1 },\n      flow: null,\n      globalGroup: null,\n      hasFit: false,\n      height: 1250,\n      labels: null,\n      layout: null,\n      layoutPlan: 'sugiyama',\n      line: null,\n      links: null,\n      loadingKey: 0,\n      mappedTasks: {},\n      nodes: null,\n      nodeColor: null,\n      nodeData: null,\n      painting: false,\n      path: null,\n      previousSchematicId: null,\n      scaledZoom: null,\n      searchOptions: [],\n      selectedTaskId: this.$route.query.schematic\n        ? this.$route.query.schematic\n        : null,\n      showCanvas: false,\n      showEdgeColorSwatch: false,\n      showNodeColorSwatch: false,\n      showLabels: false,\n      showTooltip: true,\n      size: 0,\n      timer: null,\n      tooltipData: null,\n      transitionDuration: 250,\n      transform: null,\n      transformEventK: 1,\n      transformEventX: 0,\n      transformEventY: 0,\n      tree: null,\n      width: 1250,\n      worker: null\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    canvasStyle() {\n      return {\n        opacity: this.loading || !this.showCanvas ? 0 : 1\n      }\n    },\n    color: {\n      get() {\n        return this.showNodeColorSwatch\n          ? this.nodeColor\n            ? this.nodeColor\n            : this.defaultNodeColor\n          : this.edgeColor\n          ? this.edgeColor\n          : this.defaultEdgeColor\n      },\n      set(val) {\n        this[this.showNodeColorSwatch ? 'nodeColor' : 'edgeColor'] = val\n      }\n    },\n    loading() {\n      return this.loadingKey > 0\n    },\n    nodeDataGroupTranslate() {\n      return {\n        opacity: this.loading || !this.showCanvas ? 0 : 1\n      }\n    },\n    // Should expand this to show certain details at different levels later\n    showDetails() {\n      return {\n        level1: this.transform?.k / this.size > 0.05,\n        level2: this.transform?.k / this.size > 0.15\n      }\n    },\n    animateCanvas: function() {\n      return throttle(this.rawAnimateCanvas, 16)\n    },\n    visibleNodes() {\n      if (!this.transform) return []\n      const buf = 100 // buffer\n      return this.nodeData.filter(node => {\n        let [x, y] = this.transform.apply([node.x, node.y])\n        return (\n          x >= -buf &&\n          y >= -buf &&\n          x <= this.width + buf &&\n          y <= this.height + buf\n        )\n      })\n    }\n  },\n  watch: {\n    tasks(val) {\n      if (!this.canvas) this.createCanvas()\n      if (this.nodeData && this.previousSchematicId == this.schematicId) {\n        this.updateData(val)\n      } else {\n        this.previousSchematicId = this.schematicId\n        this.createDag(val)\n      }\n    },\n    showCards() {\n      this.animateCanvas()\n    }\n  },\n  mounted() {\n    this.layout = null\n    this.worker = SchematicWorker({ type: 'module' })\n    this.createCanvas()\n\n    if (this.tasks?.length > 0) {\n      this.createDag(this.tasks)\n    }\n  },\n  beforeDestroy() {\n    cancelAnimationFrame(this.drawCanvas)\n    this.id = null\n    this.hasFit = null\n    this.nodeData = null\n    this.worker = null\n    this.custom = null\n    this.timer.stop()\n    this.timer = null\n  },\n  methods: {\n    _zoomed(event) {\n      // Disabling for now to prevent flickering when throttling\n      // drawing the canvas\n      // this.context.clearRect(0, 0, this.width, this.height)\n\n      if (event && event.sourceEvent && event.sourceEvent.ctrlKey) {\n        if (event.sourceEvent.deltaY > 0) {\n          event.transform.k = event.transform.k - event.transform.k * 0.03\n        } else if (event && event.sourceEvent.deltaY < 0) {\n          event.transform.k = event.transform.k + event.transform.k * 0.03\n        }\n      }\n      this.transform = event.transform\n      this.transformEventK = event.transform.k\n      this.transformEventX = event.transform.x\n      this.transformEventY = event.transform.y\n      requestAnimationFrame(this.drawCanvas)\n    },\n    _zoomIn() {\n      if (this.transform.k < 0.01) return\n      this.canvas\n        .transition()\n        .duration(500)\n        .call(this.scaledZoom.scaleBy, 2)\n    },\n    _zoomOut() {\n      if (this.transform.k > 10) return\n      this.canvas\n        .transition()\n        .duration(500)\n        .call(this.scaledZoom.scaleBy, 0.5)\n    },\n    createCanvas() {\n      this.loadingKey++\n      this.canvas = d3.select(`#${this.id}`)\n\n      let parent = this.canvas.select(function() {\n        return this.parentNode\n      })\n\n      let computedStyle = window.getComputedStyle(parent._groups[0][0], null)\n\n      let paddingLeft = parseFloat(\n          computedStyle.getPropertyValue('padding-left')\n        ),\n        paddingRight = parseFloat(\n          computedStyle.getPropertyValue('padding-right')\n        ),\n        paddingTop = parseFloat(computedStyle.getPropertyValue('padding-top')),\n        paddingBottom = parseFloat(\n          computedStyle.getPropertyValue('padding-left')\n        )\n      this.height =\n        parent._groups[0][0].clientHeight - paddingTop - paddingBottom\n\n      this.width = parent._groups[0][0].clientWidth - paddingLeft - paddingRight\n\n      this.canvas.attr('width', this.width).attr('height', this.height)\n      this.context = this.canvas.node().getContext('2d')\n      this.customBase = document.createElement('custom')\n      this.custom = d3.select(this.customBase)\n\n      // Have to add this because the normal d3 wheel event\n      // isn't being captured for some reason\n      const filter = () => {\n        return event.isTrusted\n      }\n\n      this.scaledZoom = zoom()\n        .on('zoom', this._zoomed)\n        .scaleExtent([0.45, Infinity])\n        .filter(filter)\n\n      this.canvas.call(this.scaledZoom).on('dblclick.zoom', null)\n      this.loadingKey--\n    },\n    async createDag(tasks) {\n      if (tasks.length === 0 || this.loading) return\n      this.loadingKey += 2\n      this.mappedTasks = {}\n\n      this.painting = true\n\n      // eslint-disable-next-line\n      if (this.debug) console.time('Pre-stratify')\n\n      let preStratify = tasks\n        .sort((a, b) => {\n          let _a = a.task ? a.task : a\n          let _b = b.task ? b.task : b\n\n          let diff = _b.upstream_edges.length - _a.upstream_edges.length\n\n          if (diff !== 0) return diff\n\n          return _a.name.localeCompare(_b.name)\n        })\n        .map(task => {\n          let parsedTask = task.task ? task.task : task\n\n          let child = {\n            ...task,\n            ...parsedTask\n          }\n\n          if (parsedTask.upstream_edges.length) {\n            child.parentIds = parsedTask.upstream_edges.map(\n              edge => edge.upstream_task.id\n            )\n          } else {\n            child.parentIds = []\n          }\n          this.searchOptions.push({ id: parsedTask.id, name: parsedTask.name })\n          return child\n        })\n      // eslint-disable-next-line\n      if (this.debug) console.timeEnd('Pre-stratify')\n\n      // If it takes more than 60 seconds to calculate the\n      // dag layout, we'll stop the calculation,\n      // terminate the worker, and show an error message\n      let timeout = setTimeout(() => {\n        this.error = true\n        this.worker.terminate()\n        this.loadingKey = 0\n\n        let message = `\n            There was an issue loading a flow schematic... this is an automated feedback message\\n\n                Tenant: ${this.tenant.name}\\n\n                Tenant ID: ${this.tenant.id}\\n\n                Path: ${this.$route.path}\\n\n            `\n        LogRocket.warn(message, {\n          extra: {\n            pageName: 'Flow Schematics',\n            stage: 'Worker Termination'\n          }\n        })\n        return\n      }, 60000)\n\n      this.loadingKey++\n      this.dag = await this.worker.Stratify(preStratify)\n      this.loadingKey--\n\n      this.loadingKey++\n      this.tree = await this.worker.GenerateTree(this.dag)\n      this.loadingKey--\n\n      this.size = Math.max(this.tree.height, this.tree.width)\n\n      const {\n        canvasAdjustment,\n        descendants,\n        links\n      } = await this.worker.GenerateLayout({\n        tree: this.tree,\n        height: this.height,\n        layoutPlan: this.layoutPlan,\n        width: this.width,\n        dag: this.dag\n      })\n      this.loadingKey--\n\n      clearTimeout(timeout)\n\n      this.canvasAdjustment = canvasAdjustment\n      this.nodeData = descendants\n      this.links = links\n\n      if (!this.error) this.redraw()\n      this.loadingKey--\n    },\n    async updateData(tasks) {\n      if (tasks.length === 0) return\n      this.mappedTasks = {}\n\n      let taskMap = Object.assign(\n        {},\n        ...tasks.map(t => ({ [t.task?.id || t.id]: t }))\n      )\n\n      this.nodeData.forEach(node => {\n        let task = taskMap[node.id]\n        // This ensures the id isn't incorrectly overwritten\n        let parsedTask = task.task ? { ...task, ...task.task } : task\n        parsedTask.name = task?.name ? task.name : parsedTask.name\n\n        node.data = parsedTask\n      })\n\n      this.links.forEach(link => {\n        let _t = taskMap[link.source.id] // Source task\n        let t_ = taskMap[link.target.id] // Target task\n\n        let _tP = _t.task ? { ..._t, ..._t.task } : _t // Parsed source task\n        let tP_ = t_.task ? { ...t_, ...t_.task } : t_ // Parsed target task\n        link.source.data = _tP\n        link.target.data = tP_\n      })\n\n      this.redraw()\n    },\n    fitViz() {\n      this.canvas.call(\n        this.scaledZoom.transform,\n        d3.zoomIdentity\n          .translate(this.canvasAdjustment.w / 2, this.canvasAdjustment.h / 2)\n          .scale(1)\n      )\n    },\n    rawAnimateCanvas() {\n      cancelAnimationFrame(this.drawCanvas)\n\n      this.timer?.stop()\n      this.timer = d3.timer(elapsed => {\n        this.canvas.call(\n          this.scaledZoom.transform,\n          d3.zoomIdentity\n            .translate(this.transformEventX, this.transformEventY)\n            .scale(this.transformEventK)\n        )\n\n        if (elapsed > this.transitionDuration + 100) {\n          setTimeout(() => {\n            // Final fit\n            this.painting = false\n\n            // Fit after the first drawing\n            if (!this.hasFit) {\n              this.hasFit = true\n              this.fitViz()\n              setTimeout(() => {\n                this.showCanvas = true\n              }, 600)\n            }\n          }, 500)\n\n          this.timer.stop()\n        }\n      })\n    },\n    drawCanvas() {\n      // If the custom ref has been destroyed we don't want to continue trying\n      // to draw the canvas (this can happen if this has been queued)\n      if (!this.custom) return\n\n      this.context.clearRect(0, 0, this.width, this.height)\n\n      const transform = this.transform\n      const context = this.context\n      const showNodes = !this.showCards\n      const showDetails = this.showDetails\n      const size = this.size\n\n      const scaledLine = (75 / this.size) * transform.k\n      const scaledArrow = (100 / this.size) * transform.k\n      const scaledNode = (150 / this.size) * transform.k\n\n      const lineWidth =\n        scaledLine > 3 ? 3 : scaledLine < 1.85 ? 1.85 : scaledLine\n      const arrowSize =\n        scaledArrow > 10 ? 10 : scaledArrow < 5 ? 5 : scaledArrow\n      const nodeSize =\n        scaledNode + Math.min(scaledNode, scaledNode * (size / scaledNode))\n\n      if (!this.custom) return\n\n      let edges = this.custom.selectAll('path')\n\n      edges.each(function() {\n        context.beginPath()\n\n        let edge = d3.select(this)\n        context.strokeStyle = edge.attr('stroke')\n        context.lineCap = edge.attr('stroke-linecap')\n        context.lineWidth = lineWidth\n\n        // We only use alpha if the size is relatively small\n        // because there's a significant rendering overhead\n        context.globalAlpha = this.size < 100 ? edge.attr('stroke-opacity') : 1\n\n        edge.each(d => {\n          let _p\n          let _context\n          d.data.points.forEach((p, i) => {\n            let point = transform.apply([p.x, p.y])\n            switch (i) {\n              case 0:\n                _p = point\n                context.moveTo(...point)\n                break\n              default:\n                _p = point\n                if (isDiagonal(_context[0], _context[1], point[0], point[1])) {\n                  let to = makeQuadraticBezierPoints(\n                    _context[0],\n                    _context[1],\n                    point[0],\n                    point[1]\n                  )\n                  context.lineTo(...to[0])\n                  context.lineTo(...to[1])\n                }\n\n                context.lineTo(point[0], point[1])\n                break\n            }\n            _context = point\n          })\n\n          context.stroke()\n          if (showDetails.level2) {\n            context.fillStyle = edge.attr('arrow-color')\n            context.beginPath()\n\n            context.moveTo(_p[0], _p[1] - nodeSize)\n            context.lineTo(_p[0] - arrowSize, _p[1] - nodeSize - arrowSize)\n            context.lineTo(_p[0] + arrowSize, _p[1] - nodeSize - arrowSize)\n            context.lineTo(_p[0], _p[1] - nodeSize)\n            context.fill()\n          }\n        })\n      })\n\n      if (!showNodes && showDetails?.level1) return\n\n      let nodes = this.custom.selectAll('circle')\n\n      if (!nodes) return\n\n      // Resets the alpha before we draw nodes,\n      // which we always want to be opaque\n      context.globalAlpha = 1\n\n      nodes.each(function() {\n        let node = d3.select(this)\n        let point = transform.apply([node.attr('cx'), node.attr('cy')])\n\n        context.beginPath()\n        context.fillStyle = node.attr('fill')\n        context.arc(point[0], point[1], nodeSize, 0, 2 * Math.PI)\n        context.fill()\n\n        context.fillStyle = 'transparent'\n        this.path2D = new Path2D()\n        this.path2D.arc(\n          point[0],\n          point[1],\n          nodeSize + Math.min(nodeSize, nodeSize * (size / nodeSize)),\n          0,\n          2 * Math.PI\n        )\n        context.fill(this.path2D)\n      })\n    },\n    labelNodes() {\n      this.canvas.selectAll('text').remove()\n\n      this.labels = this.globalGroup\n        .append('g')\n        .attr('id', 'labelGroup')\n        .selectAll('text')\n        .data(this.nodeData)\n        .enter()\n        .append('text')\n        .text(d => d.data.name)\n        .attr('text-anchor', 'middle')\n        .attr('alignment-baseline', 'middle')\n        .style('font-size', '0.55rem')\n        .attr('display', this.showLabels ? 'block' : 'none')\n        .attr('x', d => (d.x ? d.x : d.x1) + 10)\n        .attr('y', d => (d.y ? d.y : d.y1) - 10)\n    },\n    redraw() {\n      this.updateEdges()\n      this.updateNodes()\n      this.animateCanvas()\n    },\n    updateNodes() {\n      // Preserves references to this for event handlers\n      const size = 96 / this.size\n\n      this.custom\n        .selectAll('circle')\n        .data(this.nodeData)\n        .join(\n          enter =>\n            enter\n              .append('circle')\n              .attr('fill', this.calcNodeColor)\n              .attr('id', data => data.id)\n              .attr('opacity', 0)\n              .attr('cursor', 'pointer')\n              .attr('cy', data =>\n                typeof data.y == 'number'\n                  ? data.y\n                  : data.y0 + (data.y1 - data.y0) / 2\n              )\n              .call(enter =>\n                enter\n                  .transition()\n                  .duration(this.transitionDuration)\n                  .delay((d, i) => i * 10)\n                  .attr('r', d =>\n                    d.id == this.selectedTaskId ? size : size * 0.9\n                  )\n                  .attr('opacity', 1)\n                  .attr('cx', data =>\n                    typeof data.x == 'number'\n                      ? data.x\n                      : data.x0 + (data.x1 - data.x0) / 2\n                  )\n              ),\n          update =>\n            update\n              .attr('fill', this.calcNodeColor)\n              .attr('r', d => (d.id == this.selectedTaskId ? size : size * 0.9))\n              .attr('opacity', 1)\n              .attr('cy', data =>\n                typeof data.y == 'number'\n                  ? data.y\n                  : data.y0 + (data.y1 - data.y0) / 2\n              )\n              .attr('cx', data =>\n                typeof data.x == 'number'\n                  ? data.x\n                  : data.x0 + (data.x1 - data.x0) / 2\n              ),\n          exit =>\n            exit.call(exit =>\n              exit\n                .transition()\n                .duration(this.transitionDuration)\n                .remove()\n            )\n        )\n    },\n    updateEdges() {\n      // We don't use this right now\n      // since the shape of the line\n      // is determined in the canvas\n      // context method\n      // this.line = d3\n      //   .line()\n      //   .curve(d3[this.curve])\n      //   .x(d => d.x)\n      //   .y(d => d.y)\n\n      this.custom\n        .selectAll('path')\n        .data(this.links)\n        .join(\n          enter =>\n            enter\n              .append('path')\n              .attr('stroke-linecap', 'round')\n              .attr('fill', 'none')\n              .attr('class', 'path')\n              .attr('arrow-color', () => this.calcColor(this.defaultArrowColor))\n              .attr('stroke-width', 4)\n              .attr('stroke', this.calcStrokeColor)\n              .call(enter => {\n                enter\n                  .transition()\n                  .duration(this.transitionDuration)\n                  .delay((d, i) => i * 10)\n                  .attr('stroke-opacity', d => {\n                    let opacity\n                    if (this.selectedTaskId) {\n                      if (\n                        d.source.id == this.selectedTaskId ||\n                        d.target.id == this.selectedTaskId\n                      ) {\n                        opacity = 1\n                      } else {\n                        opacity = 0.2\n                      }\n                    } else {\n                      opacity = 1\n                    }\n                    return opacity\n                  })\n              }),\n          update =>\n            update.attr('stroke', this.calcStrokeColor).call(update => {\n              update\n                .transition()\n                .duration(this.transitionDuration)\n                .delay((d, i) => i * 10)\n                .attr('stroke-opacity', d => {\n                  let opacity\n                  if (this.selectedTaskId) {\n                    if (\n                      d.source.id == this.selectedTaskId ||\n                      d.target.id == this.selectedTaskId\n                    ) {\n                      opacity = 1\n                    } else {\n                      opacity = 0.2\n                    }\n                  } else {\n                    opacity = 1\n                  }\n                  return opacity\n                })\n            }),\n          exit =>\n            exit.call(exit =>\n              exit\n                .transition()\n                .duration(this.transitionDuration)\n                .remove()\n            )\n        )\n    },\n    handleCanvasClick(e) {\n      if (!this.canvasFocus) return (this.canvasFocus = true)\n      if (!this.showCards || !this.showDetails.level1) {\n        const context = this.context\n        const handleSelect = this.handleSelect\n        let found = false\n        this.custom.selectAll('circle').each(function() {\n          try {\n            if (context?.isPointInPath(this.path2D, e.offsetX, e.offsetY)) {\n              found = true\n              handleSelect({ id: this.id })\n            }\n          } catch {\n            // do nothing\n          }\n        })\n        if (!found && this.selectedTaskId)\n          this.handleSelect({ id: this.selectedTaskId })\n      } else {\n        if (!this.selectedTaskId) return\n        this.handleSelect({ id: this.selectedTaskId })\n      }\n    },\n    handleCanvasMove(e) {\n      if (this.showDetails.level1 && this.showCards) return\n      const context = this.context\n      const canvas = this.canvas\n      const nodeData = this.nodeData\n      const updateTooltip = this.updateTooltip\n      let found = false\n      this.custom.selectAll('circle').each(function() {\n        try {\n          if (found) return\n          if (context?.isPointInPath(this.path2D, e.offsetX, e.offsetY)) {\n            canvas._groups[0][0].style.cursor = 'pointer'\n            found = true\n            updateTooltip(nodeData.find(node => node.id == this.id))\n          } else {\n            canvas._groups[0][0].style.cursor = null\n          }\n        } catch {\n          // do nothing\n        }\n      })\n      if (!found) updateTooltip(null)\n    },\n    handleSelect(task) {\n      this.$emit('node-click', task)\n\n      let taskId = task.id\n\n      if (taskId !== this.selectedTaskId) {\n        this.selectedTaskId = taskId\n\n        this.fadeAllNodes()\n        this.highlightNode(taskId)\n\n        this.fadeAllEdges()\n        this.highlightUpstreamEdges(taskId)\n        this.highlightDownstreamEdges(taskId)\n\n        this.$router.replace({\n          query: { ...this.$route.query, schematic: taskId }\n        })\n      } else {\n        this.selectedTaskId = null\n\n        this.showAllNodes()\n        this.showAllEdges()\n\n        this.$router.replace({\n          query: { ...this.$route.query, schematic: '' }\n        })\n      }\n\n      this.animateCanvas()\n    },\n    showAllNodes() {\n      this.custom\n        .selectAll('circle')\n        .transition()\n        .duration(this.transitionDuration)\n        .attr('fill', this.calcNodeColor)\n    },\n    showAllEdges() {\n      this.custom\n        .selectAll('path')\n        .transition()\n        .duration(this.transitionDuration)\n        .attr('stroke', this.calcStrokeColor)\n        .attr('stroke-opacity', 1)\n    },\n    fadeAllNodes() {\n      this.custom\n        .selectAll('circle')\n        .transition()\n        .duration(this.transitionDuration)\n        .attr('fill', this.calcColor(this.fadedNodeColor))\n    },\n    fadeAllEdges() {\n      this.custom\n        .selectAll('path')\n        .transition()\n        .duration(this.transitionDuration)\n        .attr('stroke', this.calcColor(this.fadedEdgeColor))\n        // We only use alpha if the size is relatively small\n        // because there's a significant rendering overhead\n        .attr('stroke-opacity', this.size < 100 ? 0.2 : 1)\n    },\n    highlightNode(id) {\n      this.custom\n        .selectAll('circle')\n        .filter(({ data }) => data.id == id)\n        .transition()\n        .duration(this.transitionDuration)\n        .attr('fill', this.calcNodeColor)\n    },\n    highlightUpstreamEdges(id) {\n      // Upstream edges\n      this.custom\n        .selectAll('path')\n        .filter(({ source }) => source.id == id)\n        .transition()\n        .duration(this.transitionDuration)\n        .attr('stroke', this.calcStrokeColor)\n        .attr('stroke-opacity', 1)\n    },\n    highlightDownstreamEdges(id) {\n      // Downstream edges\n      this.custom\n        .selectAll('path')\n        .filter(({ target }) => target.id == id)\n        .transition()\n        .duration(this.transitionDuration)\n        .attr('stroke', this.calcStrokeColor)\n        .attr('stroke-opacity', 1)\n    },\n    calcStrokeColor(d) {\n      if (d?.source?.data?.state) {\n        return STATE_COLORS[d.source.data.state]\n      }\n      return this.calcEdgeColor()\n    },\n    calcNodeColor(d) {\n      if (d?.data?.state) {\n        return STATE_COLORS[d.data.state]\n      }\n      let c = this.defaultNodeColor || this.nodeColor\n      return `rgba(${c.r}, ${c.g}, ${c.b}, ${c.a})`\n    },\n    calcEdgeColor() {\n      let c = this.edgeColor || this.defaultEdgeColor\n      return `rgba(${c.r}, ${c.g}, ${c.b}, ${c.a})`\n    },\n    calcColor(c) {\n      return `rgba(${c.r}, ${c.g}, ${c.b}, ${c.a})`\n    },\n    rgba2hex(orig) {\n      let a,\n        rgb = orig\n          .replace(/\\s/g, '')\n          .match(/^rgba?\\((\\d+),(\\d+),(\\d+),?([^,\\s)]+)?/i),\n        alpha = ((rgb && rgb[4]) || '').trim(),\n        hex = rgb\n          ? (rgb[1] | (1 << 8)).toString(16).slice(1) +\n            (rgb[2] | (1 << 8)).toString(16).slice(1) +\n            (rgb[3] | (1 << 8)).toString(16).slice(1)\n          : orig\n\n      if (alpha !== '') {\n        a = alpha\n      } else {\n        a = 1\n      }\n      // multiply before convert to HEX\n      a = ((a * 255) | (1 << 8)).toString(16).slice(1)\n      hex = hex + a\n\n      return hex\n    },\n    async submitReport() {\n      this.errorReportLoading = true\n      let message = `\n            There was an issue loading a flow schematic... this is an automated feedback message\\n\n                Tenant: ${this.tenant.name}\\n\n                Tenant ID: ${this.tenant.id}\\n\n                Path: ${this.$route.path}\\n\n            `\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/support/send-feedback.gql'),\n          variables: {\n            type: 'Schematics',\n            message: message\n          }\n        })\n        setTimeout(() => {\n          this.errorSubmitted = true\n        }, 1500)\n      } catch (e) {\n        this.error = true\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Schematics',\n            stage: 'Automated Feedback Submission'\n          }\n        })\n      }\n      setTimeout(() => {\n        this.errorReportLoading = false\n      }, 1500)\n\n      LogRocket.warn(message, {\n        extra: {\n          pageName: 'Flow Schematics',\n          stage: 'Automated Feedback Submission'\n        }\n      })\n    },\n    tooltipStyle(data) {\n      let t = this.transform?.apply([data?.x, data?.y])\n      return {\n        left: `${t[0]}px`,\n        top: `${t[1] + 10}px`,\n        position: 'absolute'\n      }\n    },\n    updateTooltip(data) {\n      if (!data) {\n        this.showTooltip = false\n        this.tooltipData = null\n      }\n      this.tooltipData = data\n      this.showTooltip = true\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    ref=\"container\"\n    class=\"position-relative full-height ma-0 pa-0\"\n    style=\"overflow: hidden;\"\n  >\n    <v-progress-circular\n      v-if=\"loading\"\n      color=\"primary\"\n      class=\"position-absolute center\"\n      indeterminate\n      size=\"150\"\n      width=\"10\"\n    />\n\n    <div\n      v-if=\"tasks && !error && hasFit\"\n      class=\"position-absolute task-preview-tile\"\n      @click=\"canvasFocus = false\"\n      @mouseover=\"canvasFocus = false\"\n      @focus=\"canvasFocus = false\"\n    >\n      <PreviewTile\n        :options=\"searchOptions\"\n        :tasks=\"tasks\"\n        @clear-task=\"handleSelect({ id: selectedTaskId })\"\n        @select-task=\"handleSelect\"\n      />\n    </div>\n\n    <canvas\n      v-if=\"!error\"\n      :id=\"id\"\n      :style=\"canvasStyle\"\n      @click=\"handleCanvasClick\"\n      @mousemove=\"handleCanvasMove\"\n    />\n\n    <div\n      v-if=\"showCards && transform && showDetails.level1 && !error\"\n      class=\"node-data-group position-absolute\"\n      :style=\"nodeDataGroupTranslate\"\n    >\n      <SchematicNode\n        v-for=\"data in visibleNodes\"\n        :key=\"data.id\"\n        :disabled=\"selectedTaskId && selectedTaskId !== data.id\"\n        :multiplier=\"size\"\n        :node-data=\"data\"\n        :show-details=\"showDetails.level2\"\n        :size=\"size\"\n        :transform=\"transform\"\n        @mouseover=\"\n          updateTooltip()\n          canvasFocus = true\n        \"\n        @mouseout=\"updateTooltip\"\n        @node-click=\"handleSelect\"\n      ></SchematicNode>\n    </div>\n\n    <!-- eslint-disable -->\n    <Tooltip\n      v-if=\"tooltipData && showTooltip && transform\"\n      :data=\"tooltipData.data\"\n      :style=\"tooltipStyle(tooltipData)\"\n    />\n\n    <v-toolbar\n      v-if=\"!hideControls && !error && hasFit\"\n      dense\n      class=\"toolbar px-0 mx-0\"\n      elevation=\"2\"\n    >\n      <v-tooltip top>\n        <template #activator=\"{ on }\">\n          <v-btn icon tile v-on=\"on\" @click=\"fitViz\">\n            <v-icon>center_focus_strong</v-icon>\n          </v-btn>\n        </template>\n        <span>\n          Reset Viewport\n        </span>\n      </v-tooltip>\n\n      <v-tooltip top>\n        <template #activator=\"{ on }\">\n          <v-btn icon tile v-on=\"on\" @click=\"_zoomIn\">\n            <v-icon>zoom_in</v-icon>\n          </v-btn>\n        </template>\n        <span>\n          Zoom In\n        </span>\n      </v-tooltip>\n\n      <v-tooltip top>\n        <template #activator=\"{ on }\">\n          <v-btn icon tile v-on=\"on\" @click=\"_zoomOut\">\n            <v-icon>zoom_out</v-icon>\n          </v-btn>\n        </template>\n        <span>\n          Zoom Out\n        </span>\n      </v-tooltip>\n    </v-toolbar>\n\n    <Legend\n      v-if=\"showLegend && !error\"\n      class=\"position-absolute legend\"\n      :tasks=\"tasks\"\n    />\n\n    <v-card v-if=\"error\" class=\"position-absolute center\" tile>\n      <v-card-text class=\"text-center\">\n        <transition name=\"fade-expand\" mode=\"out-in\">\n          <div v-if=\"!errorSubmitted && !errorReportLoading\" key=\"step1\">\n            <div class=\"text-h4\">\n              Sorry, we're unable to load this schematic.\n            </div>\n            <div class=\"mt-2\">Help us improve by submitting a report.</div>\n          </div>\n          <div v-else-if=\"errorReportLoading\" key=\"step2\" class=\"text-h4\">\n            Submitting report...\n          </div>\n          <div v-else key=\"step2\">\n            <div class=\"text-h4 mb-2\">\n              Thanks! We'll get our team on it immediately.\n            </div>\n            By the way, you can\n            <a target=\"_blank\" href=\"https://prefect.io/slack\"\n              >join our Slack</a\n            >\n            to ask questions, provide feedback, or just to chat! You can also\n            check out our\n            <a target=\"_blank\" href=\"https://docs.prefect.io\">docs</a>, which\n            are filled with lots of helpful tutorials, explanations, and useful\n            information.\n          </div>\n        </transition>\n      </v-card-text>\n      <v-card-actions>\n        <v-btn\n          v-if=\"!errorSubmitted\"\n          depressed\n          color=\"warning\"\n          class=\"ma-auto\"\n          :loading=\"errorReportLoading\"\n          @click=\"submitReport\"\n        >\n          Submit Report\n        </v-btn>\n        <v-btn v-else color=\"success\" :ripple=\"false\" depressed class=\"ma-auto\">\n          <v-icon class=\"mr-2\">check</v-icon>\n          Report submitted\n        </v-btn>\n      </v-card-actions>\n    </v-card>\n  </div>\n</template>\n\n<style lang=\"scss\">\n// This block is has no style scoping,\n// which allows us to use css\n// to style dynamically attached svg elements\n// .path {\n// animation: dash 120s reverse linear;\n// animation-iteration-count: infinite;\n// stroke-dasharray: 5 7;\n// }\n\n@keyframes dash {\n  to {\n    stroke-dashoffset: 500;\n  }\n}\n</style>\n\n<style lang=\"scss\" scoped>\ncanvas {\n  cursor: grab;\n  min-height: 800px;\n  transition: opacity 500ms linear;\n  user-select: none;\n\n  &:active {\n    cursor: grabbing;\n  }\n}\n\n.legend {\n  bottom: 0.2rem;\n  right: 0.15rem;\n}\n\n.center {\n  left: 50%;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n\n.node-data-group {\n  height: 100%;\n  left: 0;\n  pointer-events: none;\n  top: 0;\n  transform-origin: 0 0;\n  transition: opacity 500ms linear;\n  width: 100%;\n}\n\n.task-preview-tile {\n  min-width: 250px;\n  right: 0.15rem;\n  top: 0.15rem;\n  width: 25%;\n  z-index: 2;\n}\n\n.toolbar {\n  border-bottom-right-radius: 0 !important;\n  bottom: 0.2rem;\n  left: 0.15rem;\n  position: absolute;\n}\n</style>\n\n<style lang=\"scss\" scoped>\n.h-100 {\n  height: calc(100% - 64px) !important;\n  min-height: calc(100% - 64px) !important;\n}\n\n.toolbox {\n  bottom: 1rem;\n  height: 350px;\n  overflow: hidden;\n  position: absolute;\n  right: calc(200px + 2rem);\n  transform-origin: right;\n  transition: all 500ms;\n  width: 350px;\n  z-index: 1;\n\n  &.swatch-open {\n    width: 700px;\n  }\n\n  &.collapsed {\n    height: 50px;\n    width: 50px;\n  }\n}\n\n.no-flows {\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n\n.color-picker {\n  cursor: pointer;\n  font-size: 1rem;\n  line-height: 1rem;\n  user-select: none;\n\n  &.selected {\n    background-color: rgba(0, 0, 0, 0.2);\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Schematics/Schematic-Node.vue",
    "content": "<script>\nimport { duration } from '@/utils/moment'\nimport DurationSpan from '@/components/DurationSpan'\nimport StackedLineChart from '@/components/Visualizations/StackedLineChart'\nimport { STATE_COLORS } from '@/utils/states'\nimport { FINISHED_STATES } from '@/utils/states'\n\nexport default {\n  filters: {\n    duration: function(v) {\n      if (!v) return ''\n\n      const runTime = duration(v)\n\n      if (runTime >= duration(1, 'week')) {\n        return runTime.format('w[w], d[d], h[h]')\n      } else if (runTime >= duration(1, 'day')) {\n        return runTime.format('d d], h[h], m[m]')\n      } else if (runTime >= duration(1, 'hour')) {\n        return runTime.format('h[h], m[m], s[s]')\n      } else if (runTime >= duration(1, 'minute')) {\n        return runTime.format('m[m], s[s]')\n      } else if (runTime >= duration(1, 's')) {\n        return runTime.format('s[s]')\n      } else if (runTime < duration(1, 'second')) {\n        return '<1s'\n      }\n      return runTime.humanize()\n    }\n  },\n  components: { StackedLineChart, DurationSpan },\n  props: {\n    // /** @typedef {import('d3').Node} Node */\n    // This doesn't pass webpack compilation so disabling for now...\n    // we can reinstate with TS\n    disabled: { type: Boolean, required: false, default: () => false },\n    multiplier: { type: Number, required: true },\n    nodeData: { type: null, required: true },\n    showDetails: { type: Boolean, required: false, default: () => true },\n    size: { type: null, required: true },\n    transform: { type: null, required: true }\n  },\n  data() {\n    return {\n      scale: false\n    }\n  },\n  computed: {\n    mappedStates() {\n      return this.nodeData?.data?.serialized_state?.n_map_states ?? false\n    },\n    appliedTransform() {\n      return this.transform.apply([this.nodeData.x, this.nodeData.y])\n    },\n    colors() {\n      return STATE_COLORS\n    },\n    cardStyle() {\n      let transform = `translate(${this.appliedTransform[0]}px, ${\n        this.appliedTransform[1]\n      }px) scale(${this.transform.k / this.size})`\n\n      return {\n        'border-color': 'none !important',\n        'border-left': this.nodeData.data.state\n          ? `6rem solid ${\n              this.disabled\n                ? this.hex2RGBA(STATE_COLORS[this.nodeData.data.state])\n                : STATE_COLORS[this.nodeData.data.state]\n            } !important`\n          : '',\n        transform: transform\n      }\n    },\n    durationStyle() {\n      let size = 45 * (1 / this.transform.k)\n      size = size < 45 ? 45 : size > 64 ? 64 : size\n      return {\n        color: this.disabled ? 'var(--v-utilGrayLight-base)' : '',\n        'font-size': `${size}px !important`,\n        'line-height': `${size}px !important`\n      }\n    },\n    isParameter() {\n      return this.nodeData?.data?.type?.split('.').pop() == 'Parameter'\n    },\n    isResource() {\n      return (\n        this.nodeData?.data?.type?.split('.').pop() == 'ResourceCleanupTask' ||\n        this.nodeData?.data?.type?.split('.').pop() == 'ResourceSetupTask'\n      )\n    },\n    segments() {\n      if (!this.mappedChildren) return []\n      return Object.keys(this.mappedChildren.state_counts).map(state => {\n        return {\n          label: state,\n          value: this.mappedChildren.state_counts[state]\n        }\n      })\n    },\n    finishedStates() {\n      return this.segments\n        .filter(s => FINISHED_STATES.includes(s.label))\n        .reduce((accum, item) => accum + item.value, 0)\n    },\n    subtitleStyle() {\n      let size = 64 * (1 / this.transform.k)\n      size = size < 64 ? 64 : size > 84 ? 84 : size\n      return {\n        color: this.disabled\n          ? 'var(--v-navIcons-base)'\n          : 'var(--v-utilGrayDark-base)',\n        'font-size': `${size}px !important`,\n        'line-height': `${size}px !important`\n      }\n    },\n    titleStyle() {\n      let size = 84 * (1 / this.transform.k)\n      size = size < 84 ? 84 : size > 96 ? 96 : size\n      return {\n        color: this.disabled\n          ? 'var(--v-navIcons-base)'\n          : 'var(--v-utilGrayDark-base)',\n        'font-size': `${size}px !important`,\n        'line-height': `${size + 10}px !important`\n      }\n    }\n  },\n  methods: {\n    _mouseOut() {\n      this.scale = false\n      this.$emit('mouseout', null)\n    },\n    _mouseOver() {\n      this.scale = true\n      this.$emit('mouseover', this.nodeData)\n    },\n    wheelEvent(e) {\n      if (!e) return\n      e.preventDefault()\n\n      // We can emit this later if we want to figure out\n      // how best to implement zooming from the node\n      // this.$emit('wheel-event', {\n      //   e: e\n      // })\n    },\n    nodeClick() {\n      this.$emit('node-click', this.nodeData.data)\n    },\n    hex2RGBA(hex) {\n      // Doesn't support 3 char hex values\n      let red = hex.substr(1, 2),\n        green = hex.substr(3, 2),\n        blue = hex.substr(5, 4)\n      let red10 = parseInt(red, 16),\n        green10 = parseInt(green, 16),\n        blue10 = parseInt(blue, 16)\n      return `rgba(${red10}, ${green10}, ${blue10}, 0.6)`\n    },\n    isFinished(state) {\n      return FINISHED_STATES.includes(state)\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.mappedChildren.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    mappedChildren: {\n      query: require('@/graphql/MappedTasks/mapped-children.gql'),\n      variables() {\n        return {\n          taskRunId: this.nodeData?.data?.task_run_id\n        }\n      },\n      skip() {\n        return (\n          this.nodeData?.data?.state !== 'Mapped' ||\n          !this.nodeData?.data?.task_run_id\n        )\n      },\n      pollInterval: 3000,\n      update: data => data.mapped_children\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    v-intersect=\"{ handler: onIntersect }\"\n    v-ripple\n    class=\"utilGrayLight d-flex align-center node ripple\"\n    :class=\"showDetails ? 'elevation-3' : ''\"\n    :style=\"cardStyle\"\n    tile\n    style=\"cursor: pointer;\"\n    @click=\"nodeClick\"\n    @mouseover=\"_mouseOver\"\n    @mouseout=\"_mouseOut\"\n    @mousewheel=\"wheelEvent\"\n  >\n    <div class=\"ml-12 node-content\" style=\"width: calc(100% - 6rem);\">\n      <div\n        v-if=\"nodeData.data.task && !nodeData.data.mapped\"\n        class=\"text-subtitle-2 text-truncate font-weight-light\"\n        :style=\"subtitleStyle\"\n      >\n        {{ nodeData.data.task.name }}\n      </div>\n      <div class=\"text-h6 text-truncate font-weight-bold\" :style=\"titleStyle\">\n        <v-avatar\n          v-if=\"isResource || isParameter\"\n          color=\"accentOrange\"\n          size=\"0.75em\"\n        >\n          <span v-if=\"isParameter\" class=\"text-h2 white--text font-weight-black\"\n            >P</span\n          >\n          <span v-if=\"isResource\" class=\"text-h2 white--text font-weight-black\"\n            >R</span\n          >\n        </v-avatar>\n        {{ nodeData.data.name }}\n      </div>\n\n      <div v-if=\"mappedChildren\" :style=\"durationStyle\">\n        <div v-if=\"mappedStates\" style=\"padding-bottom: 40px;\">\n          <div v-if=\"showDetails\">\n            {{ finishedStates }}/{{\n              nodeData.data.serialized_state.n_map_states\n            }}\n            {{\n              nodeData.data.serialized_state.n_map_states > 1 ? 'runs' : 'run'\n            }}\n            complete\n          </div>\n\n          <div v-else class=\"mt-2\">\n            {{ finishedStates }}/{{\n              nodeData.data.serialized_state.n_map_states\n            }}\n          </div>\n        </div>\n      </div>\n\n      <div\n        v-if=\"showDetails && nodeData.data.start_time\"\n        :style=\"durationStyle\"\n      >\n        <DurationSpan\n          :start-time=\"nodeData.data.start_time\"\n          :end-time=\"\n            nodeData.data.end_time\n              ? nodeData.data.end_time\n              : isFinished(nodeData.data.state)\n              ? nodeData.data.start_time\n              : null\n          \"\n        >\n          <template #default=\"{duration}\">\n            <div v-show=\"duration.length > 0\"> Duration: {{ duration }} </div>\n          </template>\n        </DurationSpan>\n      </div>\n    </div>\n    <div\n      v-if=\"mappedChildren && showDetails\"\n      class=\"line-chart\"\n      :class=\"disabled ? 'disabled' : ''\"\n    >\n      <StackedLineChart :segments=\"segments\" :colors=\"colors\" :height=\"50\" />\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.node {\n  height: 300px;\n  left: -425px;\n  pointer-events: auto;\n  position: absolute;\n  top: -150px;\n  width: 850px;\n\n  .node-content {\n    pointer-events: none;\n    user-select: none;\n  }\n}\n\n.h-100 {\n  height: 100%;\n}\n\n.line-chart {\n  bottom: 0;\n  height: 50px;\n  left: 0;\n  position: absolute !important;\n  width: calc(850px - 6rem);\n\n  &.disabled {\n    opacity: 0.6;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Schematics/Tooltip.vue",
    "content": "<script>\nimport DurationSpan from '@/components/DurationSpan'\nexport default {\n  components: { DurationSpan },\n  props: {\n    data: { type: Object, required: true }\n  },\n  computed: {\n    isParameter() {\n      return this.data?.type?.split('.').pop() == 'Parameter'\n    }\n  }\n}\n</script>\n\n<template>\n  <transition name=\"tooltip-fade\" mode=\"in-out\">\n    <span class=\"schematic-tooltip v-tooltip__content\">\n      <div>\n        <span class=\"accentOrange--text\">\n          {{ isParameter ? '[Parameter]' : '' }}\n        </span>\n        <span class=\"font-weight-bold\">{{ data.name }}</span>\n\n        <div v-if=\"data.start_time\" class=\"subtitle\">\n          Duration:\n          <DurationSpan\n            :start-time=\"data.start_time\"\n            :end-time=\"data.end_time\"\n          />\n        </div>\n      </div>\n    </span>\n  </transition>\n</template>\n\n<style lang=\"scss\" scoped>\n.schematic-tooltip {\n  pointer-events: none;\n  position: absolute;\n  text-overflow: initial;\n  transform-origin: bottom;\n  user-select: none;\n  width: fit-content !important;\n  z-index: 1;\n}\n</style>\n"
  },
  {
    "path": "src/components/SetStateDialog.vue",
    "content": "<script>\nimport { changeStateMixin } from '@/mixins/changeStateMixin'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  mixins: [changeStateMixin],\n  data() {\n    return {\n      childTasks: false\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return !this.hasPermission('update', 'run')\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.taskRunIds.skip =\n        !this.flowRun || !entry.isIntersecting\n    }\n  },\n  apollo: {\n    taskRunIds: {\n      query: require('@/graphql/FlowRun/task-run-ids.gql'),\n      variables() {\n        return {\n          flowRunId: this.flowRun.id,\n          parentMapIndex: -1,\n          childMapIndex: null\n        }\n      },\n      pollInterval: 10000,\n      update: data => data.task_run\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-if=\"activeButton\" v-intersect=\"{ handler: onIntersect }\">\n    <v-dialog v-model=\"setStateDialog\" max-width=\"600\" @click:outside=\"reset\">\n      <template #activator=\"{ on: dialog }\">\n        <v-tooltip bottom>\n          <template #activator=\"{ on: tooltip }\">\n            <div v-on=\"{ ...tooltip, ...dialog }\">\n              <v-btn\n                class=\"vertical-button\"\n                :style=\"{ height: '46px' }\"\n                text\n                small\n                depressed\n                :disabled=\"permissionsCheck\"\n                color=\"utilGrayMid\"\n              >\n                <v-icon>label_important</v-icon>\n                <div>Set State</div>\n              </v-btn>\n            </div>\n          </template>\n          <span>Change the state of this {{ dialogType }}</span>\n        </v-tooltip>\n      </template>\n\n      <v-card flat :loading=\"markAsLoading\">\n        <div style=\"padding: 20px;\">\n          <v-card-title class=\"text-h5 word-break-normal card-title\">\n            <span v-if=\"taskRun && taskRun.name\">\n              Change the state of\n              <span class=\"font-weight-medium\">{{ taskRun.name }}</span>\n            </span>\n            <span v-else-if=\"taskRun\">\n              Change the state of this run of\n              <span class=\"font-weight-medium\">{{ taskRun.task.name }}</span>\n            </span>\n            <span v-else\n              >Change the state of\n              <span class=\"font-weight-medium\">{{ flowRun.name }}</span></span\n            >\n          </v-card-title>\n          <v-select\n            data-public\n            v-model=\"selectedState\"\n            outlined\n            :menu-props=\"{ offsetY: true }\"\n            label=\"State\"\n            prepend-icon=\"assessment\"\n            :items=\"filteredStates\"\n          >\n          </v-select>\n\n          <v-text-field\n            v-model=\"reason\"\n            class=\"mb-3\"\n            label=\"Optional - Why are you changing state?\"\n            prepend-icon=\"live_help\"\n            autocomplete=\"new-password\"\n            outlined\n          />\n\n          <div class=\"checkbox-container\">\n            <v-checkbox\n              v-if=\"flowRun\"\n              v-model=\"allTasks\"\n              label=\"Include non-mapped task runs\"\n              style=\"margin-bottom: -30px;\"\n            ></v-checkbox>\n            <v-checkbox\n              v-if=\"flowRun\"\n              v-model=\"childTasks\"\n              :disabled=\"!allTasks\"\n              label=\"Include mapped task runs - this may take some time\"\n            ></v-checkbox>\n          </div>\n\n          <v-card-actions>\n            <v-spacer></v-spacer>\n            <v-tooltip top>\n              <template #activator=\"{ on, attrs }\">\n                <v-btn\n                  v-show=\"childTasks || dialogType === 'task run'\"\n                  v-disable-read-only-user=\"!selectedState\"\n                  :loading=\"markAsLoading\"\n                  color=\"primary\"\n                  v-bind=\"attrs\"\n                  class=\"set-state\"\n                  v-on=\"on\"\n                  @click=\"changeState\"\n                >\n                  Confirm\n                </v-btn>\n              </template>\n\n              <span v-if=\"childTasks\" class=\"pt-1\">\n                If you have a lot of child mapped tasks, the state change may\n                continue in the background.\n                <br />\n              </span>\n\n              <span v-if=\"dialogType === 'task run'\">\n                This may have an effect on downstream tasks.\n                <br />\n              </span>\n            </v-tooltip>\n            <v-btn\n              v-show=\"!taskRun && (!childTasks || !dialogType === 'task run')\"\n              v-disable-read-only-user=\"!selectedState\"\n              :loading=\"markAsLoading\"\n              color=\"primary\"\n              class=\"set-state\"\n              @click=\"changeState\"\n            >\n              Confirm\n            </v-btn>\n            <v-btn text @click=\"reset\">\n              Cancel\n            </v-btn>\n          </v-card-actions>\n        </div>\n      </v-card>\n    </v-dialog>\n  </div>\n  <div v-else-if=\"permissionsCheck && dialogType == 'flow run'\">\n    <v-tooltip bottom>\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <v-btn\n            text\n            disabled\n            class=\"vertical-button\"\n            :style=\"{ height: '46px' }\"\n            small\n            depressed\n            color=\"grey darken-2\"\n          >\n            <v-icon>label_important</v-icon>\n            Set State\n          </v-btn>\n        </div>\n      </template>\n      <span>\n        You don't have permission to change flow run states\n      </span>\n    </v-tooltip>\n  </div>\n  <div v-else-if=\"dialogType == 'task run'\">\n    <v-tooltip bottom>\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <v-btn\n            text\n            disabled\n            class=\"vertical-button\"\n            :style=\"{ height: '46px' }\"\n            small\n            depressed\n            color=\"grey darken-2\"\n          >\n            <v-icon>label_important</v-icon>\n            Set State\n          </v-btn>\n        </div>\n      </template>\n      <span v-if=\"permissionsCheck\">\n        You don't have permission to change states\n      </span>\n      <span v-else>\n        You can only change the marked state of a finished task-run\n      </span>\n    </v-tooltip>\n  </div>\n</template>\n\n<style>\n.theme--light.v-subheader {\n  color: var(--v-secondaryGray-dark);\n  font-weight: bold !important;\n}\n\n.checkbox-container {\n  margin-left: 30px;\n  margin-top: -20px;\n}\n/* stylelint-disable */\n.set-state .v-btn__loader {\n  color: var(--v-appForeground-base);\n}\n\n.card-title {\n  margin-left: -12px;\n  margin-top: -10px;\n  margin-bottom: 10px;\n}\n</style>\n"
  },
  {
    "path": "src/components/Snackbars/Snackbars.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nimport { mapGetters, mapActions } from 'vuex'\nexport default {\n  computed: {\n    ...mapGetters('alert', ['notifications']),\n    list() {\n      return this.notifications\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['dismissNotification']),\n    resolveColor(color) {\n      if (!color) return\n      if (color[0] === '#' || color.includes('var(')) return color\n      return `var(--v-${color}-base)`\n    }\n  }\n}\n</script>\n\n<template>\n  <transition-group\n    class=\"snackbars-wrapper justify-end d-flex flex-column align-end\"\n    name=\"snackbars-wrapper\"\n    tag=\"div\"\n  >\n    <template v-for=\"item in list\">\n      <v-card\n        :key=\"item.id\"\n        class=\"snackbars-snack rounded-sm elevation-4 mr-4 mb-4 py-2 pr-1\"\n        max-width=\"500px\"\n        :min-width=\"$vuetify.breakpoint.xsOnly ? '80%' : '350px'\"\n        :style=\"{ 'border-left': `6px solid ${resolveColor(item.color)}` }\"\n      >\n        <v-card-actions class=\"pl-4 pr-1\">\n          <div class=\"utilGrayDark--text\">\n            <transition name=\"quick-fade\" mode=\"out-in\" tag=\"div\">\n              <div\n                :key=\"item.supertext\"\n                class=\"text-caption mb-n1 font-weight-thin\"\n              >\n                {{ item.supertext }}\n              </div>\n            </transition>\n\n            <transition name=\"quick-fade\" mode=\"out-in\" tag=\"div\">\n              <div :key=\"item.text\" class=\"text-body-1\" v-html=\"item.text\" />\n            </transition>\n\n            <transition name=\"quick-fade\" mode=\"out-in\" tag=\"div\">\n              <div\n                :key=\"item.subtext\"\n                class=\"text-caption text--secondary mt-n1\"\n              >\n                {{ item.subtext }}\n              </div>\n            </transition>\n          </div>\n          <v-spacer />\n\n          <transition name=\"fade\" mode=\"out-in\" tag=\"div\">\n            <v-btn\n              v-if=\"item.to\"\n              :color=\"item.color\"\n              class=\"ml-2\"\n              :to=\"item.to\"\n              small\n              depressed\n              @click=\"dismissNotification(item)\"\n            >\n              {{ item.linkText || 'Details' }}\n            </v-btn>\n          </transition>\n\n          <transition name=\"fade\" mode=\"out-in\" tag=\"div\">\n            <v-btn\n              v-if=\"item.dismissable\"\n              color=\"grey lighten-1\"\n              class=\"ml-2\"\n              icon\n              small\n              @click=\"dismissNotification(item)\"\n            >\n              <v-icon>close</v-icon>\n            </v-btn>\n          </transition>\n\n          <v-progress-circular\n            v-if=\"item.loading\"\n            :color=\"item.color\"\n            size=\"31\"\n            indeterminate\n          />\n        </v-card-actions>\n      </v-card>\n    </template>\n  </transition-group>\n</template>\n\n<style lang=\"scss\" scoped>\n.snackbars-wrapper {\n  height: 100vh;\n  pointer-events: none;\n  position: fixed;\n  width: 100%;\n  z-index: 1000;\n\n  .snackbars-snack {\n    pointer-events: auto;\n    transition: all 0.5s;\n  }\n\n  &-enter,\n  &-leave-to,\n  &-leave-active {\n    opacity: 0;\n    transform: translateY(30px);\n  }\n\n  &-leave-active {\n    position: absolute;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/SupportBanner.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport ExternalLink from '@/components/ExternalLink'\nexport default {\n  components: { ExternalLink },\n  data() {\n    return {\n      dismissed: false\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud'])\n  },\n  methods: {\n    handleDismiss() {\n      this.dismissed = true\n      localStorage.setItem('dismissedSupportBanner', true)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-banner :value=\"!dismissed\">\n    <template #default>\n      <div class=\"d-flex align-center\">\n        <v-avatar slot=\"icon\" rounded color=\"primary\" size=\"40\">\n          <i class=\"o-100 fad fa-life-ring fa-2x\" />\n        </v-avatar>\n        <div class=\"ml-4\">\n          Prefect now offers Standard support for self-serve users on Prefect\n          Cloud 2. To purchase, reach out to help@prefect.io or\n          <ExternalLink\n            href=\"https://calendly.com/prefect-experts/prefect-product-advocates-support?utm_source=cloud1\">\n            set up time\n          </ExternalLink>\n          with our team.\n        </div>\n        <v-btn\n          class=\"ml-auto\"\n          width=\"40\"\n          height=\"40\"\n          icon\n          text\n          dark\n          @click=\"handleDismiss\"\n        >\n          <v-icon>close</v-icon>\n        </v-btn>\n      </div>\n    </template>\n  </v-banner>\n</template>\n\n<style lang=\"scss\" scoped>\n$dark-grey-icon: var(--v-utilGrayMid-base);\n$dark-blue-icon: var(--v-primaryDark-base);\n\n.o-100 {\n  &.svg-inline--fa {\n    --fa-primary-opacity: 0.8;\n    --fa-secondary-opacity: 0.8;\n  }\n}\n\n.fa-life-ring {\n  --fa-secondary-color: #fff;\n  --fa-primary-color: #{$dark-blue-icon};\n}\n</style>\n"
  },
  {
    "path": "src/components/SystemActions/CancelAll.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  props: {\n    flowRuns: {\n      type: Array,\n      required: false,\n      default: () => []\n    }\n  },\n  data() {\n    return {\n      finished: false,\n      errors: 0,\n      loaded: 0,\n      loadingKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    loading() {\n      return this.loadingKey > 0\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    async cancelAll() {\n      if (!this.flowRuns?.length) return\n\n      try {\n        const mutation = require('@/graphql/Mutations/cancel-flow-run.gql')\n\n        this.loaded = 0\n\n        const promises = []\n        const animationTime = Math.min(10000, this.flowRuns.length * 750)\n\n        this.flowRuns.map(async (run, i) => {\n          this.loadingKey++\n          const promise = new Promise((res, rej) => {\n            this.$apollo\n              .mutate({\n                mutation: mutation,\n                variables: {\n                  flowRunId: run.id\n                }\n              })\n              .then(() => {\n                setTimeout(() => {\n                  this.loaded++\n                  res()\n                }, animationTime / (750 * (i + 1)))\n              })\n              .catch(() => {\n                this.errors++\n                rej()\n              })\n          })\n          promises.push(promise)\n        })\n\n        await Promise.allSettled(promises)\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: e,\n          alertType: 'error'\n        })\n      } finally {\n        this.finished = true\n        setTimeout(() => {\n          this.$emit('finish')\n        }, 1500)\n        setTimeout(() => {\n          this.loadingKey = 0\n          this.finished = false\n        }, 5000)\n\n        if (this.errors > 0) {\n          this.setAlert({\n            alertShow: true,\n            alertMessage: `${this.errors} could not be stopped.`,\n            alertType: 'error'\n          })\n\n          this.errors = 0\n        }\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <button\n    class=\"rounded-lg action-container d-flex flex-column align-center justify-center\"\n    :disabled=\"loading || !flowRuns || flowRuns.length === 0\"\n    @click=\"cancelAll\"\n  >\n    <div class=\"system-icon mx-auto\" :class=\"{ active: !loading }\">\n      <i class=\"fad fa-align-slash\" />\n    </div>\n\n    <div class=\"text-h6 white--text mt-2 \">\n      <v-fade-transition mode=\"out-in\">\n        <div v-if=\"finished\" style=\"transition-delay: 1.5s\">Complete!</div>\n        <div v-else-if=\"loading\" style=\"transition-delay: 1.5s\"\n          >Stopping...</div\n        >\n        <div v-else style=\"transition-delay: 1.5s\">Stop all runs</div>\n      </v-fade-transition>\n    </div>\n\n    <v-scroll-y-transition mode=\"out-in\">\n      <div v-if=\"loading\" class=\"action-text\">\n        <v-progress-linear\n          :active=\"loading\"\n          height=\"25\"\n          rounded\n          color=\"error\"\n          :value=\"(loaded / loadingKey) * 100\"\n        >\n          {{ loaded }} / {{ loadingKey }}\n        </v-progress-linear>\n      </div>\n      <div v-else class=\"action-text mb-2\">\n        <span v-if=\"flowRuns && flowRuns.length > 0\">\n          {{ flowRuns.length }} run{{ flowRuns.length == 1 ? '' : 's' }} can be\n          stopped</span\n        >\n        <span v-else>No runs to stop</span>\n      </div>\n    </v-scroll-y-transition>\n  </button>\n</template>\n\n<style lang=\"scss\" scoped>\n.action-container {\n  background-color: #455a64;\n  height: 100%;\n  margin: auto;\n  padding: 36px 36px 52px 36px;\n  position: relative;\n  transition: transform 150ms ease-in-out;\n  width: 180px;\n\n  &:focus {\n    outline: none;\n  }\n\n  &:active {\n    outline: none;\n    transform: scale(0.97);\n  }\n\n  &:disabled {\n    background-color: #90a4ae;\n    color: #eee;\n    cursor: not-allowed;\n  }\n}\n\n.action-text {\n  bottom: 20px;\n  left: 10%;\n  position: absolute;\n  width: 80%;\n}\n</style>\n"
  },
  {
    "path": "src/components/SystemActions/ClearLate.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  props: {\n    flowRuns: {\n      type: Array,\n      required: false,\n      default: () => []\n    }\n  },\n  data() {\n    return {\n      finished: false,\n      errors: 0,\n      loaded: 0,\n      loadingKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    loading() {\n      return this.loadingKey > 0\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    async clearLate() {\n      if (!this.flowRuns?.length) return\n\n      try {\n        const mutation = require('@/graphql/Mutations/delete-flow-run.gql')\n\n        this.loaded = 0\n\n        const promises = []\n        const animationTime = Math.min(10000, this.flowRuns.length * 750)\n\n        this.flowRuns.map(async (run, i) => {\n          this.loadingKey++\n          const promise = new Promise((res, rej) => {\n            this.$apollo\n              .mutate({\n                mutation: mutation,\n                variables: {\n                  id: run.id\n                }\n              })\n              .then(() => {\n                setTimeout(() => {\n                  this.loaded++\n                  res()\n                }, animationTime / (750 * (i + 1)))\n              })\n              .catch(() => {\n                this.errors++\n                rej()\n              })\n          })\n          promises.push(promise)\n        })\n\n        await Promise.allSettled(promises)\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: e,\n          alertType: 'error'\n        })\n      } finally {\n        this.finished = true\n        setTimeout(() => {\n          this.$emit('finish')\n        }, 2000)\n\n        setTimeout(() => {\n          this.loadingKey = 0\n          this.finished = false\n        }, 5000)\n\n        if (this.errors > 0) {\n          this.setAlert({\n            alertShow: true,\n            alertMessage: `${this.errors} run could not be removed.`,\n            alertType: 'error'\n          })\n\n          this.errors = 0\n        }\n      }\n    },\n    getTimeOverdue(time) {\n      return new Date() - new Date(time)\n    }\n  }\n}\n</script>\n\n<template>\n  <button\n    class=\"rounded-lg action-container d-flex flex-column align-center justify-center\"\n    :disabled=\"loading || !flowRuns || flowRuns.length === 0\"\n    @click=\"clearLate\"\n  >\n    <div class=\"mx-auto fa-stack system-icon\" :class=\"{ active: !loading }\">\n      <i class=\"fas fa-alarm-exclamation fa-stack-2x\"></i>\n      <i class=\"fas fa-slash fa-4x fa-stack-1x\" />\n    </div>\n\n    <div class=\"text-h6 white--text mt-2\">\n      <v-fade-transition mode=\"out-in\">\n        <div v-if=\"finished\" style=\"transition-delay: 1.5s\">Complete!</div>\n        <div v-else-if=\"loading\" style=\"transition-delay: 1.5s\"\n          >Clearing...</div\n        >\n        <div v-else style=\"transition-delay: 1.5s\">Clear late runs</div>\n      </v-fade-transition>\n    </div>\n\n    <v-scroll-y-transition mode=\"out-in\">\n      <div v-if=\"loading\" class=\"action-text\">\n        <v-progress-linear\n          :active=\"loading\"\n          height=\"25\"\n          rounded\n          color=\"error\"\n          :value=\"(loaded / loadingKey) * 100\"\n        >\n          {{ loaded }} / {{ loadingKey }}\n        </v-progress-linear>\n      </div>\n      <div v-else class=\"action-text mb-2\">\n        <span v-if=\"flowRuns && flowRuns.length > 0\">\n          {{ flowRuns.length.toLocaleString() }} late run{{\n            flowRuns.length == 1 ? '' : 's'\n          }}\n        </span>\n        <span v-else>No late runs</span>\n      </div>\n    </v-scroll-y-transition>\n  </button>\n</template>\n\n<style lang=\"scss\" scoped>\n.action-container {\n  background-color: #455a64;\n  height: 100%;\n  margin: auto;\n  padding: 36px 36px 52px 36px;\n  position: relative;\n  transition: transform 150ms ease-in-out;\n  width: 200px;\n\n  &:focus {\n    outline: none;\n  }\n\n  &:active {\n    outline: none;\n    transform: scale(0.97);\n  }\n\n  &:disabled {\n    background-color: #90a4ae;\n    color: #eee;\n    cursor: not-allowed;\n  }\n}\n\n.action-text {\n  bottom: 20px;\n  left: 10%;\n  position: absolute;\n  width: 80%;\n}\n</style>\n"
  },
  {
    "path": "src/components/SystemActions/WorkQueue.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  data() {\n    return {\n      loading: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    paused() {\n      return this.tenant?.settings?.work_queue_paused\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    ...mapActions('tenant', ['getTenants']),\n    async haltWork() {\n      this.loading = true\n      const value = this.paused ? 'resume' : 'pause'\n\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require(`@/graphql/Mutations/${value}-tenant-work-queue.gql`),\n          variables: {\n            tenantId: this.tenant.id\n          }\n        })\n\n        if (data?.tenant_work_queue_result?.success) {\n          this.getTenants()\n        }\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: e,\n          alertType: 'error'\n        })\n      } finally {\n        this.loading = false\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <button\n    class=\"rounded-lg action-container d-flex flex-column align-center justify-center\"\n    :disabled=\"loading\"\n    @click=\"haltWork\"\n  >\n    <div class=\"system-icon mx-auto\" :class=\"{ active: !paused }\">\n      <i class=\"fad fa-list-alt\" />\n    </div>\n\n    <div class=\"text-h6 white--text mt-2 mb-2\">\n      Work queue\n    </div>\n\n    <div>\n      <input\n        ref=\"checkbox\"\n        class=\"large-switch work-queue\"\n        :class=\"{ loading: loading, active: !paused }\"\n        :disabled=\"loading\"\n        type=\"checkbox\"\n      />\n    </div>\n  </button>\n</template>\n\n<style lang=\"scss\" scoped>\n@keyframes spin {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(360deg);\n  }\n}\n\n.large-switch {\n  appearance: none;\n  background-color: rgba(254, 81, 150, 0.15);\n  border: none;\n  border-radius: 50px;\n  cursor: pointer;\n  display: inline-block;\n  height: 48px;\n  outline: none;\n  overflow: hidden;\n  position: relative;\n  transition: background-color ease 0.3s;\n  width: 124px;\n\n  &:disabled {\n    cursor: not-allowed;\n  }\n\n  &::before {\n    background: rgba(255, 193, 7, 1);\n    border-radius: 50%;\n    color: #fff;\n    content: 'Active Paused';\n    display: block;\n    font: 14px/44px 'Roboto', sans-serif;\n    font-weight: bold;\n    height: 44px;\n    left: 2px;\n    position: absolute;\n    text-indent: -56px;\n    text-transform: uppercase;\n    top: 2px;\n    transition: all cubic-bezier(0.3, 1.5, 0.7, 1) 0.3s;\n    white-space: nowrap;\n    width: 44px;\n    word-spacing: 58px;\n    z-index: 2;\n  }\n\n  &::after {\n    animation: spin 2s cubic-bezier(0, 0.87, 0.92, 0.91) 0.3s infinite;\n    background-color: transparent;\n    border: 6px solid transparent;\n    border-radius: 50%;\n    border-right: 6px solid #fff;\n    content: '';\n    display: block;\n    height: 44px;\n    left: 2px;\n    opacity: 0;\n    position: absolute;\n    top: 2px;\n    transition: opacity 50ms;\n    width: 44px;\n    z-index: 3;\n  }\n\n  &:not(.active) {\n    background-color: rgba(0, 0, 0, 0.35);\n  }\n\n  &.active {\n    background-color: rgba(59, 141, 255, 0.45);\n\n    &::before {\n      background: var(--v-primary-base);\n    }\n\n    &::after,\n    &::before {\n      left: 78px;\n    }\n  }\n\n  &.loading {\n    &::after {\n      opacity: 1;\n    }\n  }\n\n  &.loading.active {\n    background-color: rgba(59, 141, 255, 0.15);\n\n    &::before,\n    &::after {\n      left: 78px !important;\n    }\n  }\n\n  &.loading:not(.active) {\n    background-color: rgba(255, 193, 7, 0.15);\n\n    &.active {\n      &::before,\n      &::after {\n        left: 2px !important;\n      }\n    }\n  }\n}\n\n.action-container {\n  background-color: #455a64;\n  height: 100%;\n  margin: auto;\n  padding: 36px;\n  position: relative;\n  transition: transform 150ms ease-in-out;\n  width: 220px;\n\n  &:focus {\n    outline: none;\n  }\n\n  &:active {\n    outline: none;\n    transform: scale(0.97);\n  }\n\n  &:disabled {\n    background-color: #90a4ae;\n    color: #eee;\n    cursor: not-allowed;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/TaskRunMenu.vue",
    "content": "<script>\nimport DurationSpan from '@/components/DurationSpan'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nexport default {\n  components: {\n    DurationSpan\n  },\n  mixins: [formatTime],\n  props: {\n    taskRun: { type: Object, required: true }\n  },\n  methods: {\n    statusStyle(state) {\n      return {\n        'border-radius': '50%',\n        display: 'inline-block',\n        'background-color': `var(--v-${state}-base)`,\n        height: '1rem',\n        width: '1rem'\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card tile>\n    <v-card-title class=\"text-subtitle-1\">\n      <router-link :to=\"{ name: 'task-run', params: { id: taskRun.id } }\">\n        {{ taskRun.name ? taskRun.name : taskRun.task_name }}\n        {{ taskRun.map_index > -1 ? `(${taskRun.map_index})` : '' }}\n      </router-link>\n    </v-card-title>\n    <v-card-text>\n      <div>\n        State:\n        <span :style=\"statusStyle(taskRun.state)\"></span>\n        <span class=\"font-weight-bold\"> {{ taskRun.state }}</span>\n      </div>\n      <div\n        v-if=\"taskRun.start_time\"\n        class=\"subtitle d-flex align-end justify-space-between\"\n      >\n        Duration:\n        <DurationSpan\n          class=\"font-weight-bold\"\n          :start-time=\"taskRun.start_time\"\n          :end-time=\"taskRun.end_time\"\n        />\n      </div>\n      <div\n        v-if=\"taskRun.start_time\"\n        class=\"subtitle d-flex align-end justify-space-between\"\n      >\n        Start:\n        <span class=\"font-weight-bold\">\n          {{ formatTime(taskRun.start_time) }}\n        </span>\n      </div>\n      <div\n        v-if=\"taskRun.end_time\"\n        class=\"subtitle d-flex align-end justify-space-between\"\n      >\n        End:\n        <span class=\"font-weight-bold\">\n          {{ formatTime(taskRun.end_time) }}\n        </span>\n      </div>\n      <div\n        v-if=\"taskRun.state_timestamp\"\n        class=\"subtitle d-flex align-end justify-space-between\"\n      >\n        Updated:\n        <span class=\"font-weight-bold\">\n          {{ formatTime(taskRun.state_timestamp) }}\n        </span>\n      </div>\n      <div class=\"subtitle d-flex align-end justify-space-between\">\n        Max Retries:\n        <span class=\"font-weight-bold\">\n          {{ taskRun.max_retries || 0 }}\n        </span>\n      </div>\n      <div class=\"subtitle d-flex align-end justify-space-between\">\n        Retry delay:\n        <span class=\"font-weight-bold\">\n          {{ taskRun.retry_delay || 0 }}\n        </span>\n      </div>\n      <v-divider class=\"my-2\" />\n      <div class=\"text-subtitle-1\">\n        <div>Message:</div>\n        <div class=\"font-weight-bold\">\n          {{ taskRun.state_message || 'No message' }}\n        </div>\n      </div>\n      <v-divider class=\"my-2\" />\n      <div class=\"text-subtitle-1\">\n        <div>Result:</div>\n        <div class=\"font-weight-bold\">\n          {{ taskRun.state_result || 'No result' }}\n        </div>\n      </div>\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "src/components/TaskRunTooltip.vue",
    "content": "<script>\nimport DurationSpan from '@/components/DurationSpan'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    DurationSpan\n  },\n  mixins: [formatTime],\n  props: {\n    taskRuns: { type: Array, required: true }\n  },\n  computed: {\n    displayedTaskRuns() {\n      return this.taskRuns.slice(0, 5)\n    },\n    hiddenTaskRuns() {\n      return this.taskRuns.slice(5)\n    }\n  },\n  methods: {\n    expectedRuns(taskRun) {\n      return (\n        taskRun.data?.serialized_state?.n_map_states || 'Unknown'\n      ).toLocaleString()\n    },\n    stateClass(state) {\n      const lightStates = [\n        'Submitted',\n        'Cancelled',\n        'Cancelling',\n        'Queued',\n        'Pending'\n      ]\n\n      const textColor = lightStates.includes(state)\n        ? ['grey--text', 'text--darken-4']\n        : ['white--text']\n\n      return [state, ...textColor]\n    },\n    statusStyle(state) {\n      return {\n        'border-radius': '50%',\n        display: 'inline-block',\n        'background-color': `var(--v-${state}-base)`,\n        height: '1rem',\n        width: '1rem'\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"v-tooltip__content tooltip py-2\">\n    <div v-for=\"(taskRun, i) in displayedTaskRuns\" :key=\"i\">\n      <div class=\"text-h6\">{{ taskRun.data.task_name }}</div>\n\n      <div class=\"d-flex align-center justify-start\">\n        <div :style=\"statusStyle(taskRun.data.state)\"></div>\n        <div class=\"ml-2\">{{ taskRun.data.state }}</div>\n      </div>\n\n      <div v-if=\"taskRun.state == 'Scheduled'\" class=\"text-subtitle-1\">\n        Scheduled for:\n        <span class=\"font-weight-black\">\n          {{ logTimeExtended(taskRun.data.scheduled_start_time) }}\n        </span>\n      </div>\n\n      <div v-if=\"taskRun.start_time\" class=\"text-subtitle-1\">\n        Started:\n        <span class=\"font-weight-black\">\n          {{ logTimeExtended(taskRun.start_time) }}\n        </span>\n      </div>\n\n      <div v-if=\"taskRun.end_time\" class=\"text-subtitle-1\">\n        Ended:\n        <span class=\"font-weight-black\">\n          {{ logTimeExtended(taskRun.end_time) }}\n        </span>\n      </div>\n\n      <div v-if=\"taskRun.start_time\" class=\"text-subtitle-1\">\n        Duration:\n        <DurationSpan\n          class=\"font-weight-bold\"\n          :start-time=\"taskRun.start_time\"\n          :end-time=\"taskRun.end_time\"\n        />\n      </div>\n\n      <div\n        v-if=\"taskRun.data.serialized_state.n_map_states\"\n        class=\"divider\"\n      ></div>\n\n      <div v-if=\"taskRun.data.state == 'Mapped'\" class=\"text-subtitle-1\">\n        Expected Runs:\n        <span class=\"font-weight-black\">\n          {{ expectedRuns(taskRun) }}\n        </span>\n      </div>\n\n      <div v-if=\"taskRun.data.mappedChildren\">\n        <div>\n          <div class=\"text-subtitle-1\">Mapped Runs</div>\n\n          <v-chip\n            v-for=\"state in Object.keys(\n              taskRun.data.mappedChildren.state_counts\n            )\"\n            :key=\"state\"\n            class=\"px-4 font-weight-medium mr-1\"\n            :class=\"stateClass(state)\"\n            label\n            small\n          >\n            {{ state }}\n            <span class=\"font-weight-normal ml-1\">\n              ({{\n                taskRun.data.mappedChildren.state_counts[\n                  state\n                ].toLocaleString()\n              }})\n            </span>\n          </v-chip>\n        </div>\n      </div>\n\n      <div\n        v-if=\"\n          displayedTaskRuns.length > 1 && i !== displayedTaskRuns.length - 1\n        \"\n        class=\"divider\"\n      ></div>\n    </div>\n\n    <div\n      v-if=\"hiddenTaskRuns.length\"\n      class=\"pt-4 text-caption font-weight-medium text-right\"\n    >\n      +{{ hiddenTaskRuns.length }} more\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.divider {\n  border: 1px solid;\n  margin: 8px 0;\n}\n\n.tooltip {\n  height: auto;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/components/TeamListItem.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nexport default {\n  props: {\n    team: {\n      required: true,\n      type: Object\n    },\n    loading: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    users: {\n      type: Array,\n      required: false,\n      default: () => []\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['license']),\n    selected() {\n      return this.team.id == this.tenant.id\n    },\n    isRoot() {\n      return !!this.team.stripe_customer\n    }\n  },\n  methods: {}\n}\n</script>\n\n<template>\n  <div\n    class=\"utilGrayDark--text team-card d-flex align-center justify-start px-6 rounded\"\n    :class=\"{ selected: selected, disabled: loading, root: isRoot }\"\n    flat\n    outlined\n    :disabled=\"loading\"\n  >\n    <div\n      class=\"pr-8\"\n      style=\"border-right: thin solid #eee; max-width: 350px; width: 100%;\"\n    >\n      <div class=\"text-truncate font-weight-light text-h5\">\n        {{ team.name }}\n      </div>\n\n      <div v-show=\"isRoot\" class=\"text-overline mt-n2\">Root</div>\n    </div>\n\n    <router-link\n      class=\"ml-8 d-flex align-center justify-start text-decoration-none\"\n      :to=\"{ name: 'members', params: { tenant: team.slug } }\"\n    >\n      <v-avatar\n        v-for=\"u in users.slice(0, 3)\"\n        :key=\"u.id\"\n        :color=\"u.avatar_color\"\n        size=\"32\"\n        class=\"white--text rounded-circle text-uppercase ml-n3 user-select-none\"\n        style=\"border: thin solid #fff;\"\n      >\n        <truncate :content=\"u.username\">\n          {{\n            u.first_name && u.last_name\n              ? u.first_name[0] + u.last_name[1]\n              : u.username[0] + u.username[1]\n          }}\n        </truncate>\n      </v-avatar>\n\n      <v-avatar\n        v-if=\"users.length > 3\"\n        color=\"grey lighten-3\"\n        :size=\"users.length - 3 > 100 ? '42' : '32'\"\n        class=\"rounded-circle text-uppercase ml-n3 user-select-none utilGrayDark--text\"\n        style=\"border: thin solid #fff;\"\n      >\n        +{{ users.length - 3 }}\n      </v-avatar>\n    </router-link>\n\n    <v-spacer />\n\n    <div class=\"actions d-flex align-center justify-center\">\n      <truncate\n        :content=\"selected ? 'You\\'re logged in to this team' : 'Switch team'\"\n      >\n        <v-btn\n          icon\n          :disabled=\"selected || loading\"\n          title=\"Switch team\"\n          @click.stop=\"$emit('click')\"\n        >\n          <v-icon>sync_alt</v-icon>\n        </v-btn>\n      </truncate>\n\n      <truncate\n        :content=\"\n          isRoot\n            ? 'The root team can\\'t be deleted'\n            : selected\n            ? 'You can\\'t remove the team you\\'re logged into. Switch to another team to remove.'\n            : 'Remove team'\n        \"\n      >\n        <v-btn\n          icon\n          :disabled=\"selected || isRoot || loading\"\n          :title=\"isRoot ? 'The root team can\\'t be deleted' : 'Remove team'\"\n          @click.stop=\"$emit('remove')\"\n        >\n          <v-icon>delete</v-icon>\n        </v-btn>\n      </truncate>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.team-card {\n  background-color: var(--v-appForeground-base);\n  border: thin solid rgba(0, 0, 0, 0.12);\n  box-sizing: border-box;\n  height: 78px;\n  transition: all 150ms;\n  width: 100%;\n\n  &.selected {\n    border-left: 6px solid var(--v-primary-base);\n  }\n\n  &.disabled {\n    backdrop-filter: blur(10px);\n  }\n\n  .actions {\n    opacity: 0;\n  }\n\n  &:hover {\n    .actions {\n      opacity: 1;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/TimelineTooltip.vue",
    "content": "<script>\nimport DurationSpan from '@/components/DurationSpan'\n\nexport default {\n  components: {\n    DurationSpan\n  },\n  props: {\n    tooltip: { type: Object, required: true },\n    loading: { type: Boolean, required: false, default: false },\n    showProjectName: { type: Boolean, required: false, default: false }\n  }\n}\n</script>\n\n<template functional>\n  <div>\n    <div v-if=\"props.tooltip.data.flow\" class=\"text-h6 text-truncate\">\n      {{ props.tooltip.data.flow.name }}\n    </div>\n    <div v-else-if=\"props.loading\">\n      ...\n    </div>\n    <div\n      class=\"text-truncate\"\n      :class=\"\n        props.tooltip.data.flow || props.loading ? 'text-caption' : 'text-h6'\n      \"\n    >\n      {{ props.tooltip.data.name }}\n    </div>\n\n    <div class=\"d-flex align-center justify-start\">\n      <div :style=\"props.tooltip.status_style\"></div>\n      <div class=\"ml-2\">{{ props.tooltip.data.state }}</div>\n    </div>\n\n    <div class=\"divider\"></div>\n    <div\n      v-if=\"\n        props.showProjectName &&\n          !props.loading &&\n          props.tooltip.data.flow.project.name\n      \"\n      class=\"text-subtitle-1\"\n    >\n      Project:\n      <span class=\"font-weight-black\">\n        {{ props.tooltip.data.flow.project.name }}\n      </span>\n    </div>\n\n    <div v-if=\"!props.tooltip.limited_view\">\n      <div\n        v-if=\"props.tooltip.data.state == 'Scheduled'\"\n        class=\"text-subtitle-1\"\n      >\n        Scheduled for:\n        <span class=\"font-weight-black\">\n          {{ props.tooltip.data.display_scheduled_start_time }}\n        </span>\n      </div>\n\n      <div v-if=\"props.tooltip.data.start_time\" class=\"text-subtitle-1\">\n        Started:\n        <span class=\"font-weight-black\">\n          {{ props.tooltip.data.display_start_time }}\n        </span>\n      </div>\n\n      <div v-if=\"props.tooltip.data.end_time\" class=\"text-subtitle-1\">\n        Ended:\n        <span class=\"font-weight-black\">\n          {{ props.tooltip.data.display_end_time }}\n        </span>\n      </div>\n\n      <div\n        v-if=\"\n          props.tooltip.data.start_time &&\n            (props.tooltip.data.end_time || !props.tooltip.data.finished)\n        \"\n        class=\"text-subtitle-1\"\n      >\n        Duration:\n        <component\n          :is=\"$options.components.DurationSpan\"\n          class=\"font-weight-bold\"\n          :start-time=\"props.tooltip.data.start_time\"\n          :end-time=\"props.tooltip.data.end_time\"\n        />\n      </div>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.divider {\n  border: 1px solid;\n  margin: 8px 0;\n}\n</style>\n"
  },
  {
    "path": "src/components/Tree/Tree.vue",
    "content": "<script>\nimport isFunction from 'lodash/isFunction'\n\nexport default {\n  name: 'Tree',\n  props: {\n    activeIds: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n\n    depth: {\n      type: Number,\n      required: false,\n      default: () => 0\n    },\n    icon: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    iconActive: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    id: {\n      type: [String, Number],\n      required: false,\n      default: () => 0\n    },\n    idToMatch: {\n      type: [String, Number],\n      required: false,\n      default: () => 0\n    },\n    items: {\n      type: [Array, Function],\n      required: false,\n      default: () => null\n    },\n    link: {\n      type: [Object, String],\n      required: false,\n      default: () => null\n    },\n    options: {\n      type: Object,\n      required: false,\n      default: () => {\n        return {}\n      }\n    },\n    name: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    type: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      // These _ data props allow us to manipulate local component state without throwing warnings\n      active_: null,\n      icon_: null,\n      iconActive_: null,\n      name_: null,\n      children_: null,\n      childrenCallback: null,\n\n      loading: false,\n      open: false\n    }\n  },\n  computed: {\n    activeRoute() {\n      return this.$route.params?.id == this.idToMatch\n    },\n    canExpand() {\n      return this.items || this.children_?.length\n    }\n  },\n  watch: {\n    active_(val) {\n      if (val && !this.open) {\n        this.toggle()\n      }\n    },\n    activeIds: {\n      deep: true,\n      handler: function() {\n        this.active_ = this.activeIds.includes(this.id)\n      }\n    },\n\n    items(val) {\n      this.children_ = val\n    },\n    icon(val) {\n      this.icon_ = val\n    },\n    iconActive(val) {\n      this.iconActive_ = val\n    },\n    name(val) {\n      this.name_ = val\n    }\n  },\n  mounted() {\n    this.active_ = this.activeIds.includes(this.id)\n\n    this.icon_ = this.icon\n    this.iconActive_ = this.iconActive\n    this.name_ = this.name\n\n    if (isFunction(this.items)) {\n      this.childrenCallback = this.items\n    } else {\n      this.children_ = [...(this.items ?? [])]\n    }\n  },\n  methods: {\n    clickHandler() {\n      if (this.canExpand) return this.toggle()\n      const data = { id: this.id, type: this.type }\n      return this.select(data)\n    },\n    close() {\n      this.open = false\n\n      let i = 0\n\n      while (this.$refs[`leaf_${i}`]?.[0]) {\n        this.$refs[`leaf_${i}`]?.[0]?.close()\n        ++i\n      }\n    },\n    async select(data) {\n      this.$emit('select', data)\n    },\n    async toggle() {\n      // if this item is being closed,\n      // we can skip the rest\n      if (this.open) return (this.open = false)\n\n      if (isFunction(this.items)) {\n        this.loading = true\n        const data = await this.items({ id: this.id, name: this.name })\n\n        this.children_ = data\n        this.loading = false\n      }\n\n      this.open = true\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <component\n      :is=\"canExpand ? 'div' : 'router-link'\"\n      v-if=\"icon || name_\"\n      :class=\"['pl-' + (depth - 1) * 4, { 'leaf-active': active_ }]\"\n      class=\"cursor-pointer d-flex justify-start align-center py-1 leaf\"\n      :to=\"canExpand ? null : link\"\n      tabindex=\"0\"\n      @click.stop=\"clickHandler\"\n      @keyup.enter=\"clickHandler\"\n    >\n      <div class=\"icon-block flex-shrink-0\">\n        <span v-if=\"loading\" key=\"loading-spinner\">\n          <i class=\"fas fa-spinner-third fa-spin fa-sm\" />\n        </span>\n\n        <v-icon\n          v-else-if=\"canExpand\"\n          class=\"drop-arrow\"\n          :class=\"open && 'open'\"\n          small\n        >\n          keyboard_arrow_right\n        </v-icon>\n      </div>\n\n      <div class=\"icon-block flex-shrink-0\">\n        <v-icon :color=\"open ? 'primaryDark' : 'grey'\" size=\"20\" class=\"mr-2\">\n          {{ open && iconActive_ ? iconActive_ : icon_ }}\n        </v-icon>\n      </div>\n\n      <div\n        class=\"text-subtitle-1 text-truncate flex-grow-1\"\n        :class=\"{ 'font-weight-medium': active_ }\"\n      >\n        {{ name_ }}\n      </div>\n\n      <router-link\n        v-if=\"!activeRoute\"\n        class=\"mr-2 text-caption px-1 d-flex align-center justify-space-between view-button\"\n        :to=\"link\"\n        @click.native.stop=\"select({ id: id, type: type })\"\n      >\n        <div>View</div>\n        <v-icon small>\n          arrow_right\n        </v-icon>\n      </router-link>\n\n      <div v-else class=\"mr-2 text-caption px-1 grey--text\">\n        Current\n      </div>\n    </component>\n\n    <div v-if=\"depth == 0 || (open && children_ && children_.length > 0)\">\n      <tree\n        v-for=\"(child, i) in children_\"\n        :id=\"child.id\"\n        :ref=\"`leaf_${i}`\"\n        :key=\"child.id\"\n        :id-to-match=\"child.idToMatch\"\n        :depth=\"depth + 1\"\n        :icon=\"child.icon\"\n        :icon-active=\"child.iconActive\"\n        :link=\"child.link\"\n        :name=\"child.name\"\n        :items=\"child.children\"\n        :type=\"child.type\"\n        :active-ids=\"activeIds\"\n        :options=\"options\"\n        @select=\"select\"\n      />\n    </div>\n\n    <div\n      v-else-if=\"\n        open &&\n          children_ &&\n          children_.length === 0 &&\n          options.noData &&\n          options.noData[depth]\n      \"\n      class=\"font-italic text-body-2 grey--text text--darken-1\"\n      :class=\"'pl-' + depth * 8\"\n    >\n      ({{ options.noData[depth] }})\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.drop-arrow {\n  transform: rotate(0);\n  transition: 50ms transform linear;\n\n  &.open {\n    transform: rotate(90deg);\n  }\n}\n\n.icon-block {\n  height: 24px;\n  width: 24px;\n}\n\n/* stylelint-disable */\n\n.leaf {\n  color: unset;\n  text-decoration: inherit;\n  user-select: none;\n\n  .view-button {\n    color: unset;\n    opacity: 0;\n    text-decoration: inherit;\n  }\n\n  &:focus,\n  &:hover,\n  &:focus-within {\n    background-color: rgba(0, 0, 0, 0.03);\n    outline: none;\n\n    .view-button {\n      color: var(--v-secondary-base) !important;\n      opacity: 0.5;\n\n      &:focus,\n      &:hover {\n        background-color: rgba(0, 0, 0, 0.05);\n        opacity: 1;\n        outline: none;\n      }\n    }\n  }\n\n  &.leaf-active {\n    color: var(--v-primaryDark-base);\n  }\n}\n\n/* stylelint-enable */\n</style>\n"
  },
  {
    "path": "src/components/TutorialBanner.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport ExternalLink from '@/components/ExternalLink'\nexport default {\n  components: { ExternalLink },\n  props: {\n    pageScroll: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    }\n  },\n  data() {\n    return {\n      dismissed: false\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud'])\n  }\n}\n</script>\n\n<template>\n  <v-banner :value=\"!dismissed\">\n    <template #default>\n      <div class=\"d-flex align-center\">\n        <v-avatar slot=\"icon\" color=\"primary\" size=\"40\">\n          <v-icon icon=\"mdi-lock\" color=\"white\">\n            school\n          </v-icon>\n        </v-avatar>\n        <div class=\"ml-4\">\n          Pst! It looks like you don't have any flows yet;\n          <span v-if=\"isCloud\">\n            check out the\n            <router-link :to=\"'/tutorial'\"> tutorials</router-link>\n            for walkthroughs on writing and registering flows with Prefect and\n            the for more in-depth looks at the Prefect APIs\n          </span>\n          <span v-else>\n            check out our\n            <ExternalLink href=\"https://docs.prefect.io/\">\n              documentation\n            </ExternalLink>\n            for help on getting started.\n          </span>\n        </div>\n        <v-btn\n          class=\"ml-auto\"\n          width=\"40\"\n          height=\"40\"\n          icon\n          text\n          dark\n          color=\"error\"\n          @click=\"dismissed = !dismissed\"\n        >\n          <v-icon>\n            close\n          </v-icon>\n        </v-btn>\n      </div>\n    </template>\n  </v-banner>\n</template>\n"
  },
  {
    "path": "src/components/UpgradeBadge.vue",
    "content": "<script>\nimport MenuTooltip from '@/components/MenuTooltip'\nexport default {\n  components: {\n    MenuTooltip\n  },\n  props: {\n    inline: {\n      type: Boolean,\n      default: false,\n      required: false\n    },\n    depressed: {\n      type: Boolean,\n      default: false,\n      required: false\n    }\n  }\n}\n</script>\n\n<template>\n  <MenuTooltip\n    hide-close\n    :nudge-top=\"inline ? '-4px' : '16px'\"\n    :nudge-left=\"inline ? '-4px' : null\"\n    transition=\"slide-x-transition\"\n  >\n    <template #activator>\n      <router-link :to=\"'/plans'\">\n        <v-badge\n          color=\"accentPink\"\n          offset-y=\"-12\"\n          origin=\"center\"\n          :inline=\"inline\"\n          class=\"pa-0 upgrade-badge\"\n          :class=\"{ elevate: !depressed }\"\n        >\n          <template #badge>\n            <div class=\"white--text d-flex align-center justify-center px-1\">\n              <div class=\"appearable text-none font-weight-medium\">\n                Upgrade\n              </div>\n              <v-icon>fa-fw fa-sm fa-cloud</v-icon>\n            </div>\n          </template>\n        </v-badge>\n      </router-link>\n    </template>\n\n    <div class=\"utilGrayMid--text text-h6 font-weight-light\">\n      <slot />\n\n      <br />\n      <br />\n      <div>\n        <router-link :to=\"'/plans'\">Upgrade now</router-link> to get access!\n      </div>\n    </div>\n  </MenuTooltip>\n</template>\n\n<style lang=\"scss\">\n.upgrade-badge {\n  &.elevate {\n    .v-badge__badge {\n      box-shadow: 0px 2px 4px -1px rgb(0 0 0 / 20%),\n        0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%) !important;\n    }\n  }\n\n  /* stylelint-disable */\n  .v-badge__badge {\n    left: unset;\n    max-width: 31px;\n    right: 0;\n    transition: 250ms ease-in-out;\n    z-index: 4;\n  }\n  /* stylelint-enable */\n\n  .appearable {\n    margin-right: 0;\n    overflow: hidden;\n    transition: width 250ms ease-in-out, margin-right 250ms ease-in-out;\n    width: 0;\n  }\n\n  &:hover,\n  &:focus {\n    /* stylelint-disable */\n    .v-badge__badge {\n      max-width: 83px;\n    }\n    /* stylelint-enable */\n\n    .appearable {\n      margin-right: 6px;\n      width: 100%;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Visualizations/BarChart.vue",
    "content": "<script>\nimport * as d3 from 'd3'\nimport { mapGetters } from 'vuex'\nimport uniqueId from 'lodash/uniqueId'\nimport throttle from 'lodash/throttle'\nimport debounce from 'lodash/debounce'\n\nexport default {\n  props: {\n    // Breaklines should be a list of objects with the following format:\n    // { label: String, value: UUID }\n    // where the UUID corresponds to an item passed\n    breaklines: { type: Array, default: () => [] },\n    height: { type: Number, default: () => null },\n    items: { type: Array, default: () => [] },\n    loading: { type: Boolean, default: () => false },\n    minBands: { type: Number, default: () => null },\n    normalize: { type: Boolean, default: () => true },\n    padding: { type: Number, default: () => 2 },\n    showControls: { type: Boolean, default: () => false },\n    visible: { type: Boolean, default: () => true },\n    width: { type: Number, default: () => null },\n    yField: { type: String, default: () => null }\n  },\n  data() {\n    return {\n      id: uniqueId('barChart'),\n      animationTimer: null,\n      bars: [],\n      boundingClientRect: null,\n      canvas: null,\n      chartHeight: null,\n      chart: null,\n      easing: 'easeCubic',\n      groupBreaklines: null,\n      groupClickArea: null,\n      groupRect: null,\n      groupText: null,\n      hovered: null,\n      hoveredId: null,\n      breaklineUnwatch: null,\n      itemUnwatch: null,\n      visibleUnwatch: null,\n      loadingInterval: null,\n      loadingItems: [],\n      nowLine: null,\n      pattern: null,\n      previousItems: null,\n      restrictOutliers: this.normalize,\n      sum: 0,\n      timer: null,\n      visibilityListenerAdded: false,\n      wasLoading: false,\n      x: null,\n      xShift: 0,\n      y: null,\n      yShift: 0\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone']),\n    computedStyle() {\n      return getComputedStyle(document.body)\n    },\n    computedItems() {\n      return this.loading ? this.loadingItems : this.items\n    },\n    computedMouseout: function() {\n      return debounce(this.rawMouseout, 0, { trailing: true, leading: false })\n    },\n    computedYField() {\n      return this.loading ? 'value' : this.yField\n    },\n    animationDuration() {\n      return this.loading ? 500 : 500\n    },\n    barStart() {\n      return this.chartHeight - this.chartHeight * 0.1\n    },\n    animateCanvas: function() {\n      return throttle(this.rawAnimateCanvas, 16)\n    },\n    resizeChart: function() {\n      return debounce(() => {\n        requestAnimationFrame(this.rawResizeChart)\n      }, 300)\n    },\n    min() {\n      return this.chartHeight * 0.15\n    },\n    tooltipStyle() {\n      if (!this.hovered) return\n      let p = this.boundingClientRect\n      let overRight = this.hovered.x + 150 - p.width > 0\n      let overLeft = this.hovered.x - 150 < 0\n      return {\n        left: `${\n          overRight ? p.width - 150 : overLeft ? 150 : this.hovered.x\n        }px`,\n        top: `${this.hovered.y}px`\n      }\n    }\n  },\n  watch: {\n    normalize() {\n      this.updateChart()\n    },\n    restrictOutliers() {\n      this.updateChart()\n    }\n  },\n  mounted() {\n    this.createScheduledCanvas()\n    this.createChart()\n\n    this.loadingItems = Array.from({ length: this.minBands }, (d, i) => {\n      return {\n        id: i,\n        value: Math.floor(Math.random() * 100)\n      }\n    })\n\n    this.boundingClientRect = this.$refs['parent']?.getBoundingClientRect()\n\n    this.breaklineUnwatch = this.$watch(\n      'breaklines',\n      debounce(function() {\n        if (!this.chart) this.createChart()\n        if (this.loading || !this.visible) return\n        this.updateBreaklines()\n      }, 500)\n    )\n    this.itemUnwatch = this.$watch(\n      'items',\n      debounce(function() {\n        this.updateChart()\n      }, 500),\n      { deep: true }\n    )\n\n    this.visibleUnwatch = this.$watch('visible', val => {\n      if (val) {\n        this.resizeChart()\n      }\n    })\n  },\n  updated() {\n    if (!this.chart) this.createChart()\n  },\n  beforeDestroy() {\n    clearTimeout(this.loadingInterval)\n\n    window.removeEventListener('resize', this.resizeChart)\n    window.removeEventListener('visibilitychange', this.handleVisibilityChange)\n\n    this.itemUnwatch()\n    this.breaklineUnwatch()\n    this.visibleUnwatch()\n  },\n  methods: {\n    calcHeight(d) {\n      if (d.ignore) return this.barStart / 3\n      let height = this.y(0) - this.y(d[this.computedYField])\n      return height > this.min ? height : this.min\n    },\n    calcY(d) {\n      if (d.ignore) return this.barStart / 1.5\n      let _y = this.y(d[this.computedYField])\n      return _y < this.barStart - this.min ? _y : this.barStart - this.min\n    },\n    click({ currentTarget }) {\n      // Turn this on for debugging bars more easily\n      // console.log(\n      //   d,\n      //   this.bars.find(b => b.id == d.id)\n      // )\n      this.$emit('bar-click', currentTarget?.__data__)\n    },\n    mouseover({ currentTarget }) {\n      const d = currentTarget?.__data__\n\n      this.computedMouseout.cancel()\n      this.hovered = {\n        data: d,\n        x: this.x(d.id),\n        y: this.chartHeight,\n        width: this.x.bandwidth(),\n        height: this.calcHeight(d)\n      }\n      this.$emit('bar-mouseover', this.hovered)\n\n      this.hoveredId = d.id\n\n      this.animateCanvas()\n    },\n    rawMouseout() {\n      this.$emit('bar-mouseout', this.hovered)\n      this.hovered = null\n      this.hoveredId = null\n\n      this.animateCanvas()\n    },\n    createChart() {\n      this.chart = d3.select(`#${this.id}`)\n      this.canvas = d3.select(`#${this.id}-canvas`)\n\n      this.groupClickArea = this.chart\n        .append('g')\n        .attr('class', 'click-area-rect-group')\n      this.groupRect = this.chart.append('g').attr('class', 'rect-group')\n      this.groupText = this.chart.append('g').attr('class', 'text-group')\n      this.groupBreaklines = this.chart\n        .append('g')\n        .attr('class', 'breaklines-group')\n\n      window.addEventListener('resize', this.resizeChart)\n\n      requestAnimationFrame(this.resizeChart)\n    },\n    rawAnimateCanvas() {\n      cancelAnimationFrame(this.drawCanvas)\n\n      const barWidth = this.x.bandwidth()\n\n      // Check our current data against existing bars\n      this.computedItems.forEach((item, i) => {\n        const barIndex = this.bars.findIndex(b => b.id == item.id)\n\n        const height1 = this.calcHeight(item)\n        const x1 = this.x(item.id || i)\n        const y1 = this.calcY(item)\n        const opacity = item.opacity ? item.opacity : 1\n\n        // If the item isn't present in the bar array\n        // we instantiate a new bar...\n        if (barIndex < 0) {\n          this.bars.push({\n            ...item,\n            height0: 0,\n            height1: height1,\n            height: 0,\n            width: barWidth,\n            x0: x1,\n            x1: x1,\n            x: x1,\n            y0: this.barStart,\n            y1: y1,\n            y: this.barStart,\n            opacity: opacity\n          })\n        } else {\n          // ...otherwise we update the existing bar with\n          // new values\n          const bar = this.bars[barIndex]\n          const bar1 = {\n            height0: bar.height,\n            height1: height1,\n            width: barWidth,\n            x0: bar.x || 0,\n            x1: x1,\n            y0: bar.y || this.barStart,\n            y1: y1,\n            opacity: opacity\n          }\n\n          this.bars[barIndex] = { ...bar, ...bar1, ...item }\n        }\n      })\n\n      // Check our existing bars against current data\n      this.bars.forEach((bar, i) => {\n        const itemExists = this.computedItems.find(item => item.id == bar.id)\n\n        // If this is a valid bar, do nothing since its data was already\n        // updated in the loop above...\n        if (itemExists) return\n\n        // ...otherwise we'll start the exit animation\n        const bar1 = {\n          height0: bar.height,\n          height1: 0,\n          width: barWidth,\n          y0: bar.y,\n          y1: this.barStart,\n          leaving: true\n        }\n\n        this.bars[i] = { ...bar, ...bar1 }\n      })\n\n      requestAnimationFrame(this.drawCanvas)\n\n      const timingCallback = elapsed => {\n        const t = Math.min(1, d3[this.easing](elapsed / this.animationDuration))\n\n        this.bars.forEach(bar => {\n          bar.alpha = this.hoveredId\n            ? bar.id == this.hoveredId\n              ? 1\n              : 0.5\n            : bar.opacity\n          bar.x = bar.x0 * (1 - t) + bar.x1 * t\n          bar.y = bar.y0 * (1 - t) + bar.y1 * t\n          bar.height = bar.height0 * (1 - t) + bar.height1 * t\n        })\n\n        try {\n          requestAnimationFrame(this.drawCanvas)\n        } catch {\n          this.timer.stop()\n        }\n\n        if (t === 1 || document.hidden) {\n          this.timer.stop()\n          this.bars = this.bars.filter(b => !b.leaving)\n        }\n      }\n\n      if (this.timer) {\n        this.timer.restart(timingCallback)\n      } else {\n        this.timer = d3.timer(timingCallback)\n      }\n    },\n    createScheduledCanvas() {\n      this.pattern = document.createElement('canvas')\n      const context = this.pattern.getContext('2d')\n\n      const x = 32\n      this.pattern.width = x\n      this.pattern.height = x / 2\n\n      const x0 = 36\n      const x1 = -4\n      const y0 = -2\n      const y1 = 18\n      const offset = 32\n\n      context.fillStyle = this.computedStyle?.getPropertyValue(\n        '--v-ScheduledAlt-base'\n      )\n      context.fillRect(0, 0, x, x)\n\n      context.strokeStyle = this.computedStyle?.getPropertyValue(\n        '--v-Scheduled-base'\n      )\n      context.lineWidth = 6\n      context.beginPath()\n      context.moveTo(x0, y0)\n      context.lineTo(x1, y1)\n      context.moveTo(x0 - offset, y0)\n      context.lineTo(x1 - offset, y1)\n      context.moveTo(x0 + offset, y0)\n      context.lineTo(x1 + offset, y1)\n      context.stroke()\n    },\n    drawCanvas() {\n      const context = this.canvas.node().getContext('2d')\n\n      context.save()\n      context.lineWidth = 2\n      try {\n        context.strokeStyle = this.computedStyle.getPropertyValue(\n          '--v-appBackground-base'\n        )\n      } catch (e) {\n        // eslint-disable-next-line no-console\n        console.log(e)\n        cancelAnimationFrame(this.drawCanvas)\n        this.timer.stop()\n        this.bars = []\n      }\n\n      context.clearRect(0, 0, this.chartWidth, this.chartHeight)\n\n      let len = this.bars?.length\n      for (let i = 0; i < len; ++i) {\n        const bar = this.bars[i]\n\n        context.beginPath()\n        context.globalAlpha = bar.alpha\n        context.fillStyle = bar.usePattern\n          ? context.createPattern(this.pattern, 'repeat')\n          : bar.color ||\n            this.computedStyle?.getPropertyValue('--v-secondaryGrayLight-base')\n\n        context.rect(bar.x, bar.y, bar.width, bar.height)\n        context.fill()\n        context.stroke()\n      }\n\n      context.restore()\n    },\n    rawResizeChart() {\n      let parent = this.chart.select(function() {\n        return this.parentNode\n      })\n\n      let computedStyle = window.getComputedStyle(parent._groups[0][0], null)\n\n      let paddingLeft = parseFloat(\n          computedStyle?.getPropertyValue('padding-left')\n        ),\n        paddingRight = parseFloat(\n          computedStyle?.getPropertyValue('padding-right')\n        ),\n        paddingTop = parseFloat(computedStyle?.getPropertyValue('padding-top')),\n        paddingBottom = parseFloat(\n          computedStyle?.getPropertyValue('padding-bottom')\n        )\n\n      this.boundingClientRect = this.$refs['parent']?.getBoundingClientRect()\n\n      const width =\n        this.width ||\n        parent._groups[0][0].clientWidth - paddingLeft - paddingRight\n\n      const height =\n        this.height ||\n        parent._groups[0][0].clientHeight - paddingTop - paddingBottom\n\n      if (!height || !width || height <= 0 || width <= 0) {\n        return\n      }\n\n      this.chartWidth = width\n      this.chartHeight = height\n\n      this.chart\n        .attr('viewbox', `0 0 ${this.chartWidth} ${this.chartHeight}`)\n        .attr('width', this.chartWidth)\n        .attr('height', this.chartHeight)\n\n      this.canvas\n        .attr('width', this.chartWidth)\n        .attr('height', this.chartHeight)\n        .style('width', this.chartWidth)\n        .style('height', this.chartHeight)\n\n      this.updateChart()\n    },\n    updateBreaklines() {\n      if (!this.x) return\n\n      this.groupBreaklines\n        .selectAll('.breaklines-group')\n        .data(this.loading ? [] : this.breaklines)\n        .join(\n          enter => {\n            const g = enter\n              .append('g')\n              .attr('transform', 'translate(0)')\n              .attr('class', 'breaklines-group')\n\n            g.append('path')\n              .attr(\n                'stroke',\n                this.computedStyle?.getPropertyValue('--v-utilGrayMid-base')\n              )\n              .attr('stroke-width', 1)\n              .attr('stroke-dasharray', 5)\n              .attr('d', `M0,10L0,${this.chartHeight}`)\n              .style('pointer-events', 'none')\n\n            g.append('text')\n              .style('font-size', '8px')\n              .style('pointer-events', 'none')\n              .attr(\n                'fill',\n                this.computedStyle?.getPropertyValue('--v-utilGrayMid-base')\n              )\n              .attr('text-anchor', d => d.anchor || 'middle')\n              .text(d => d.label)\n              .attr('y', 6)\n              .style('opacity', 0)\n              .transition()\n              .delay(this.animationDuration)\n              .duration(150)\n              .style('opacity', 1)\n\n            return g.call(enter =>\n              enter\n                .transition('enter')\n                .duration(500)\n                .attr(\n                  'transform',\n                  d =>\n                    `translate(${\n                      d.value && this.x(d.value)\n                        ? this.x(d.value) + (d.after ? this.x.bandwidth() : 0)\n                        : -20\n                    })`\n                )\n            )\n          },\n          update =>\n            update.call(update => {\n              update\n                .select('text')\n                .attr('text-anchor', d => d.anchor || 'middle')\n                .text(d => d.label)\n                .transition()\n                .delay(this.animationDuration)\n                .duration(150)\n                .style('opacity', 1)\n\n              return update.call(update =>\n                update\n                  .transition('update')\n                  .duration(this.animationDuration)\n                  .attr(\n                    'transform',\n                    d =>\n                      `translate(${\n                        d.value\n                          ? this.x(d.value) + (d.after ? this.x.bandwidth() : 0)\n                          : -20\n                      })`\n                  )\n              )\n            }),\n          exit => {\n            exit\n              .selectAll('text')\n              .transition('exit')\n              .duration(150)\n              .style('opacity', 0)\n\n            return exit.call(exit =>\n              exit\n                .transition('exit')\n                .duration(this.animationDuration)\n                .attr('transform', 'translate(0)')\n                .remove()\n            )\n          }\n        )\n    },\n    handleVisibilityChange() {\n      if (document.visibilityState === 'visible') {\n        if (this.$el) {\n          requestAnimationFrame(this.updateChart)\n        }\n\n        window.removeEventListener(\n          'visibilitychange',\n          this.handleVisibilityChange\n        )\n        this.visibilityListenerAdded = false\n      }\n    },\n    updateChart() {\n      if (document.hidden) {\n        if (this.visibilityListenerAdded || !this.$el) return\n        window.addEventListener('visibilitychange', this.handleVisibilityChange)\n        this.visibilityListenerAdded = true\n        return\n      }\n\n      if (!this.visible) return\n      if (!this.computedItems) return\n      if (!this.loading) clearTimeout(this.loadingInterval)\n\n      let domainItems = this.computedItems.map((d, i) => (d.id ? d.id : i))\n\n      let domain = this.minBands\n        ? domainItems?.length > this.minBands\n          ? domainItems\n          : [\n              ...domainItems,\n              ...Array.from(\n                { length: this.minBands - domainItems?.length },\n                (d, i) => i\n              )\n            ]\n        : domainItems\n\n      const x = d3\n        .scaleBand()\n        .domain(domain)\n        .range([0, this.chartWidth])\n        .paddingOuter([this.padding])\n\n      this.x = x\n\n      let yMax = d3.max(this.computedItems, d => d[this.computedYField])\n\n      let y\n\n      if (this.restrictOutliers) {\n        y = d3.scalePow().exponent([0.4])\n      } else {\n        y = d3.scaleLinear()\n      }\n\n      y.range([this.barStart, this.chartHeight * 0.2]).domain([\n        0,\n        this.loading ? 100 : yMax > 0 ? yMax : 100\n      ])\n\n      this.y = y\n\n      this.groupClickArea\n        .selectAll('.click-area-rect')\n        .data(this.loading ? [] : this.computedItems)\n        .join(\n          enter =>\n            enter\n              .append('rect')\n              .attr('stroke-width', 0)\n              .style('cursor', 'pointer')\n              .attr('class', 'click-area-rect')\n              .attr('id', d => `click-area-${d.id}`)\n              .style('fill', 'transparent')\n              .attr('height', this.barStart)\n              .attr('width', x.bandwidth() || 0)\n              .attr('y', 0)\n              .attr('x', (d, i) => x(d.id ? d.id : i) || 0)\n              .call(enter =>\n                enter\n                  .on('click', this.click)\n                  .on('mouseout', this.computedMouseout)\n                  .on('mouseover', this.mouseover)\n              ),\n          update =>\n            update\n              .attr('id', d => `click-area-${d.id}`)\n              .attr('height', this.barStart)\n              .attr('width', x.bandwidth() || 0)\n              .attr('y', 0)\n              .attr('x', (d, i) => x(d.id ? d.id : i) || 0)\n              .call(update =>\n                update\n                  .on('click', this.click)\n                  .on('mouseout', this.computedMouseout)\n                  .on('mouseover', this.mouseover)\n              ),\n          exit =>\n            exit.call(exit =>\n              exit\n                .on('click', null)\n                .on('mouseout', null)\n                .on('mouseover', null)\n                .transition('exit')\n                .duration(this.animationDuration)\n                .remove()\n            )\n        )\n\n      // We don't use filter on this so we can maintain\n      // the correct index for the x scale\n      this.groupText\n        .selectAll('.warning-text')\n        .data(this.loading ? [] : this.computedItems)\n        .join(\n          enter =>\n            enter\n              .append('text')\n              .attr('class', 'warning-text')\n              .style('font-family', 'Material Icons')\n              .style('pointer-events', 'none')\n              .style('font-size', '12px')\n              .attr('fill', 'var(--v-deepRed-base)')\n              .attr('id', d => d.id + 'warning')\n              .style('opacity', 0)\n              .attr('text-anchor', 'middle')\n              .text('timelapse')\n              .attr('y', this.barStart / 1.5 - 3)\n              .attr('x', d => x(d.id) + x.bandwidth() / 2 || 0)\n              .call(enter =>\n                enter\n                  .transition('enter')\n                  .delay((d, i) => i * 10)\n                  .duration(this.animationDuration)\n                  .style('opacity', d =>\n                    'warningOpacity' in d ? d.warningOpacity : 0\n                  )\n              ),\n          update =>\n            update.call(update =>\n              update\n                .transition('update')\n                .duration(this.animationDuration)\n                .attr('x', d => x(d.id) + x.bandwidth() / 2)\n                .style('opacity', d =>\n                  'warningOpacity' in d ? d.warningOpacity : 0\n                )\n            ),\n          exit =>\n            exit.call(exit =>\n              exit\n                .transition('exit')\n                .duration(this.animationDuration)\n                .style('opacity', 0)\n                .remove()\n            )\n        )\n\n      this.chart\n        .selectAll('.x-axis')\n        .data([x])\n        .join(enter =>\n          enter\n            .append('path')\n            .attr('class', 'x-axis')\n            .attr('stroke', 'rgba(0, 0, 0, 0.12)')\n            .attr('stroke-width', 1)\n            .attr('d', `M0,${this.barStart || 0}L0,${this.barStart || 0}`)\n            .call(enter =>\n              enter\n                .transition('enter')\n                .duration(this.animationDuration)\n                .attr(\n                  'd',\n                  `M0,${this.barStart}L${this.chartWidth},${this.barStart}`\n                )\n            )\n        )\n\n      this.updateBreaklines()\n      this.animateCanvas()\n\n      if (this.loading && !this.loadingInterval) {\n        this.loadingInterval = setInterval(() => {\n          this.loadingItems.forEach(\n            d => (d.value = Math.floor(Math.random() * 125 - 25))\n          )\n          this.updateChart()\n        }, this.animationDuration)\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div ref=\"parent\" class=\"barchart position-relative\">\n    <svg :id=\"id\" preserveAspectRatio=\"xMinYMin meet\">\n      <pattern\n        id=\"future-run\"\n        width=\"8\"\n        height=\"8\"\n        patternTransform=\"rotate(45 0 0)\"\n        patternUnits=\"userSpaceOnUse\"\n      >\n        <g>\n          <line\n            x1=\"0\"\n            y1=\"0\"\n            x2=\"0\"\n            y2=\"8\"\n            style=\"\n          opacity: 1;\n          stroke: var(--v-Scheduled-base);\n          stroke-width: 8;\"\n          />\n\n          <line\n            x1=\"8\"\n            y1=\"0\"\n            x2=\"8\"\n            y2=\"8\"\n            style=\"\n          opacity: 0.2;\n          stroke: var(--v-Scheduled-base);\n          stroke-width: 8;\"\n          />\n        </g>\n      </pattern>\n    </svg>\n\n    <canvas :id=\"id + '-canvas'\" class=\"canvas\" />\n\n    <transition name=\"tooltip-fade\" mode=\"in-out\">\n      <div\n        v-if=\"$slots['tooltip']\"\n        class=\"v-tooltip__content barchart-tooltip\"\n        :style=\"tooltipStyle\"\n      >\n        <slot name=\"tooltip\" />\n      </div>\n    </transition>\n\n    <v-menu v-if=\"showControls\" bottom left :close-on-content-click=\"false\">\n      <template #activator=\"{ on }\">\n        <v-btn icon small class=\"input-menu\" v-on=\"on\">\n          <v-icon>more_vert</v-icon>\n        </v-btn>\n      </template>\n\n      <v-list dense tile>\n        <v-list-item>\n          <v-checkbox\n            v-model=\"restrictOutliers\"\n            label=\"Normalize\"\n            hide-details\n            class=\"v-input--reverse input-menu-item ma-0\"\n          ></v-checkbox>\n        </v-list-item>\n      </v-list>\n    </v-menu>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.barchart-tooltip {\n  background-color: var(--v-utilGrayMid-darken2);\n  pointer-events: none;\n  position: absolute;\n  text-overflow: initial;\n  transform: translate(-50%);\n  transition: all 150ms;\n  user-select: none;\n  width: 375px !important;\n  z-index: 4;\n}\n\n.input-menu {\n  opacity: 0.35;\n  position: absolute;\n  right: 0;\n  top: -14px;\n}\n\n.input-menu-item {\n  transform: scale(0.9);\n}\n\n.barchart {\n  &:focus,\n  &:hover {\n    .input-menu {\n      opacity: 1;\n    }\n  }\n}\n\n.canvas {\n  left: 0;\n  pointer-events: none;\n  position: absolute;\n  top: 0;\n}\n</style>\n"
  },
  {
    "path": "src/components/Visualizations/RingChart.vue",
    "content": "<script>\nimport * as d3 from 'd3'\nimport uniqueId from 'lodash/uniqueId'\n\nexport default {\n  props: {\n    colors: { type: Array, default: () => null },\n    segments: { type: Array, default: () => [] },\n    width: { type: Number, default: () => 200 },\n    height: { type: Number, default: () => 200 },\n    outerRadius: { type: Number, default: () => null },\n    innerRadius: { type: Number, default: () => null }\n  },\n  data() {\n    return {\n      id: uniqueId('ring'),\n      pie: null,\n      chart: null,\n      arc: null,\n      radius: null,\n      total: 0\n    }\n  },\n  watch: {\n    segments: function() {\n      this.refreshChart()\n    }\n  },\n  mounted() {\n    this.$nextTick(() => {\n      this.createRingChart()\n    })\n  },\n  methods: {\n    refreshChart() {\n      this.clearChart()\n      this.createRingChart()\n    },\n    clearChart() {\n      d3.select(`#${this.id}`)\n        .selectAll('*')\n        .remove()\n    },\n    createRingChart() {\n      this.radius = Math.min(this.width, this.height) / 2\n\n      this.color = d3\n        .scaleOrdinal()\n        .range(this.colors || ['#fff', 'transparent'])\n\n      this.arc = d3\n        .arc()\n        .outerRadius(this.outerRadius || this.radius * 0.95)\n        .innerRadius(this.innerRadius || this.radius * 0.65)\n\n      let totalArc = d3\n        .arc()\n        .outerRadius(this.outerRadius || this.radius * 0.95)\n        .innerRadius(this.innerRadius || this.radius * 0.65)\n        .startAngle(0)\n        .endAngle(6.28319)\n\n      this.pie = d3\n        .pie()\n        .sort(null)\n        .value(d => {\n          return d.value\n        })\n\n      this.chart = d3\n        .select(`#${this.id}`)\n        .attr('width', this.width)\n        .attr('height', this.height)\n        .append('g')\n        .attr('transform', `translate(${this.width / 2}, ${this.height / 2})`)\n\n      let total = this.chart.append('g').attr('class', 'arc-container')\n\n      total\n        .append('path')\n        .attr('stroke', 'white')\n        .attr('stroke-width', 0)\n        .attr('class', 'arc-total')\n        .attr('d', totalArc)\n        .style('fill', 'rgba(255, 255, 255, 0.4)')\n\n      this.updateRingChart()\n    },\n    updateRingChart() {\n      this.chart.selectAll('.arc').exit()\n\n      let category = this.chart\n        .selectAll('.arc')\n        .data(this.pie(this.segments))\n        .enter()\n        .append('g')\n        .attr('class', 'arc-container')\n\n      category\n        .append('path')\n        .attr('stroke', 'white')\n        .attr('stroke-width', 0)\n        .attr('class', 'arc')\n        .style('fill', d => {\n          return this.color(d.data.label)\n        })\n\n      category\n        .select('.arc')\n        .transition()\n        .delay((d, i) => {\n          return 1250 * i\n        })\n        .duration((d, i) => {\n          // Multiplying i by 0\n          // as a placeholder so that we keep the\n          // total duration the same\n          // Perhaps we can add this as a prop?\n          return 2000 + i * 0\n        })\n        .attrTween('d', d => {\n          let i = d3.interpolate(d.startAngle, d.endAngle)\n          return t => {\n            d.endAngle = i(t)\n            return this.arc(d)\n          }\n        })\n    }\n  }\n}\n</script>\n\n<template>\n  <svg :id=\"id\" />\n</template>\n"
  },
  {
    "path": "src/components/Visualizations/StackedLineChart.vue",
    "content": "<script>\nimport * as d3 from 'd3'\nimport uniqueId from 'lodash/uniqueId'\n\nexport default {\n  props: {\n    colors: { type: Object, default: () => {} },\n    height: { type: Number, default: () => null },\n    segments: { type: Array, default: () => [] },\n    vertical: { type: Boolean, default: () => false },\n    width: { type: Number, default: () => null }\n  },\n  data() {\n    return {\n      id: uniqueId('stackedLine'),\n      chart: null,\n      sum: 0,\n      xShift: 0,\n      yShift: 0\n    }\n  },\n  computed: {\n    paddingBottom() {\n      return 100 * (this.height / this.width) + '%'\n    },\n    filteredSegments() {\n      return this.segments.filter(s => s.value > 0)\n    }\n  },\n  watch: {\n    segments: {\n      deep: true,\n      handler() {\n        if (!this.chart) this.createChart()\n        setTimeout(() => {\n          this.updateChart()\n        }, 50)\n      }\n    }\n  },\n  mounted() {\n    this.createChart()\n    setTimeout(() => {\n      this.updateChart()\n    }, 50)\n  },\n  updated() {\n    if (!this.chart) this.createChart()\n    setTimeout(() => {\n      this.updateChart()\n    }, 50)\n  },\n  beforeDestroy() {\n    window.onresize = null\n    window.removeEventListener('resize', this.updateChart)\n  },\n  methods: {\n    calcHeight(d, i) {\n      if (!this.vertical || (this.sum === 0 && i === 0)) return this.chartHeight\n      if (this.sum === 0) return 0\n      return this.scale(d.value)\n    },\n    calcWidth(d, i) {\n      if (this.vertical || (this.sum === 0 && i === 0)) return this.chartWidth\n      if (this.sum === 0) return 0\n      return this.scale(d.value)\n    },\n    calcX(d) {\n      if (this.vertical) return 0\n      let x = this.xShift\n      this.xShift += this.scale(d.value)\n      return x\n    },\n    calcY(d) {\n      if (!this.vertical) return 0\n      let y = this.yShift\n      this.yShift += this.scale(d.value)\n      return y\n    },\n    createChart() {\n      this.chart = d3.select(`#${this.id}`)\n      window.addEventListener('resize', this.updateChart)\n    },\n    statusStyle(state) {\n      return {\n        'border-radius': '50%',\n        display: 'inline-block',\n        'background-color': this.colors[state],\n        height: '1rem',\n        width: '1rem'\n      }\n    },\n    updateChart() {\n      let parent = this.chart.select(function() {\n        return this.parentNode\n      })\n\n      if (!parent || !parent._groups[0][0]) return\n\n      let computedStyle = window.getComputedStyle(parent._groups[0][0], null)\n\n      let paddingLeft = parseFloat(\n          computedStyle.getPropertyValue('padding-left')\n        ),\n        paddingRight = parseFloat(\n          computedStyle.getPropertyValue('padding-right')\n        ),\n        paddingTop = parseFloat(computedStyle.getPropertyValue('padding-top')),\n        paddingBottom = parseFloat(\n          computedStyle.getPropertyValue('padding-bottom')\n        )\n\n      this.chartWidth = this.vertical\n        ? this.width\n        : parent._groups[0][0].clientWidth - paddingLeft - paddingRight\n\n      this.chartHeight = this.vertical\n        ? parent._groups[0][0].clientHeight - paddingTop - paddingBottom\n        : this.height\n\n      if (\n        !this.chartHeight ||\n        !this.chartWidth ||\n        this.chartHeight < 0 ||\n        this.chartWidth < 0\n      ) {\n        return\n      }\n\n      this.chart\n        .attr('viewbox', `0 0 ${this.chartWidth} ${this.chartHeight}`)\n        .attr('width', this.chartWidth)\n        .attr('height', this.chartHeight)\n\n      this.sum = d3.sum(this.segments, d => +d.value)\n\n      this.scale = d3\n        .scaleLinear()\n        .range([0, this.vertical ? this.chartHeight : this.chartWidth])\n        .domain([0, this.sum])\n\n      this.xShift = 0\n      this.yShift = 0\n\n      this.chart\n        .selectAll('.rect')\n        .data(this.segments)\n        .join(\n          enter =>\n            enter\n              .append('rect')\n              .attr('stroke', 'white')\n              .attr('stroke-width', this.filteredSegments > 1 ? 1 : 0)\n              .attr('class', 'rect')\n              .attr('id', d => d.label)\n              .style('fill', (d, i) => {\n                if (this.sum === 0 && i === 0)\n                  return 'var(--v-secondaryGrayLight-base)'\n                if (this.sum === 0) return 'transparent'\n                return this.colors[d.label]\n              })\n              .attr('height', (d, i) =>\n                this.vertical ? 0 : this.calcHeight(d, i)\n              )\n              .attr('width', (d, i) =>\n                !this.vertical ? 0 : this.calcWidth(d, i)\n              )\n              .attr('y', () =>\n                this.vertical ? this.chartHeight - this.yShift : null\n              )\n              .call(enter =>\n                enter\n                  .transition()\n                  .duration(500)\n                  .attr('height', (d, i) => this.calcHeight(d, i))\n                  .attr('width', (d, i) => this.calcWidth(d, i))\n                  .attr('x', d => this.calcX(d))\n                  .attr('y', d => this.calcY(d))\n              ),\n          update =>\n            update.call(update =>\n              update\n                .transition()\n                .duration(500)\n                .style('fill', (d, i) => {\n                  if (this.sum === 0 && i === 0)\n                    return 'var(--v-secondaryGrayLight-base)'\n                  if (this.sum === 0) return 'transparent'\n                  return this.colors[d.label]\n                })\n                .attr('height', (d, i) => this.calcHeight(d, i))\n                .attr('width', (d, i) => this.calcWidth(d, i))\n                .attr('x', d => this.calcX(d))\n                .attr('y', d => this.calcY(d))\n            ),\n          exit =>\n            exit.call(exit =>\n              exit\n                .transition()\n                .duration(500)\n                .remove()\n            )\n        )\n    }\n  }\n}\n</script>\n\n<template>\n  <v-tooltip :bottom=\"!vertical\" :right=\"vertical\">\n    <template #activator=\"{ on }\">\n      <svg :id=\"id\" preserveAspectRatio=\"xMinYMin meet\" v-on=\"on\" />\n    </template>\n    <div v-if=\"filteredSegments.length > 0\">\n      <div\n        v-for=\"segment in filteredSegments\"\n        :key=\"segment.label\"\n        class=\"svg-tooltip\"\n      >\n        <span :style=\"statusStyle(segment.label)\"></span>\n        <span>{{ segment.label }}: {{ segment.value.toLocaleString() }}</span>\n      </div>\n    </div>\n    <div v-else>\n      No data.\n    </div>\n  </v-tooltip>\n</template>\n\n<style lang=\"scss\" scoped>\n.svg-tooltip {\n  align-items: center;\n  display: flex;\n\n  span {\n    margin: 0 5px;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/components/Visualizations/Timeline/Bar.js",
    "content": ""
  },
  {
    "path": "src/components/Visualizations/Timeline.vue",
    "content": "<script>\nimport * as d3 from 'd3'\nimport uniqueId from 'lodash/uniqueId'\nimport throttle from 'lodash/throttle'\nimport debounce from 'lodash/debounce'\nimport moment from '@/utils/moment'\n\n// TODO: Remove the workerize-loader package and adjust this worker to\n// a more classic pub/sub style\nimport TimelineWorker from 'workerize-loader?inline!@/workers/timeline'\n\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { mapGetters } from 'vuex'\n\nconst xAxisHeight = 20\nconst minBarRadius = 10\nconst maxBarRadius = 25\nconst breakpointTooltipWidth = 185\nconst itemTooltipWidth = 375\nconst condensed = true\n\nlet hidden, visibilityChange\nif (window) {\n  if (typeof document.hidden !== 'undefined') {\n    // Opera 12.10 and Firefox 18 and later\n    hidden = 'hidden'\n    visibilityChange = 'visibilitychange'\n  } else if (typeof document.msHidden !== 'undefined') {\n    hidden = 'msHidden'\n    visibilityChange = 'msvisibilitychange'\n  } else if (typeof document.webkitHidden !== 'undefined') {\n    hidden = 'webkitHidden'\n    visibilityChange = 'webkitvisibilitychange'\n  }\n}\n\nexport default {\n  mixins: [formatTime],\n  props: {\n    barRadius: {\n      type: Number,\n      required: false,\n      default: 15\n    },\n    breakpoints: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    loading: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    items: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    live: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n\n    // Bookends for the chart\n    endTime: {\n      type: [Number, String],\n      required: false,\n      default: null\n    },\n    startTime: {\n      type: [Number, String],\n      required: false,\n      default: null\n    }\n  },\n  data() {\n    return {\n      animationDuration: 500,\n      drawTimeout: null,\n      easing: 'easePolyInOut',\n      firstRenderComplete: false,\n      id: uniqueId('timeline'),\n      hoveredBreakpoint: null,\n      hoveredBreakpoints: null,\n      hovered: null,\n      hoveredItemIds: [],\n      now: new Date(),\n      showControls: true,\n      showDebugControls: false, // These are useful for debugging\n      showLabels: true,\n      showTimestampAtCursor: false,\n      updateXTimeout: null,\n      worker: null,\n      zoom: d3.zoom(),\n\n      breakpointsUnwatch: null,\n      endTimeUnwatch: null,\n      itemUnwatch: null,\n      liveUnwatch: null,\n      pauseUpdatesUnwatch: null,\n      startTimeUnwatch: null,\n\n      followEdge: true,\n\n      // DOM refs\n      canvas: null,\n      breakpointsNode: null,\n      svg: null,\n      xAxisNode: null,\n\n      // Bars\n      bars: [],\n      barPadding: 0.2,\n\n      domainStart: null,\n      domainEnd: null,\n\n      // Viewport extent\n      viewportLeft: 0,\n      viewportRight: 1,\n\n      // Dimensions\n      height_: null,\n      width_: null,\n      height: null,\n      width: null,\n\n      padding: {\n        bottom: xAxisHeight,\n        left: 5,\n        right: 5,\n        top: 20,\n        x: 10,\n        y: 25\n      },\n\n      interval: null,\n      iterations: 0,\n      live_: this.live,\n      pauseUpdates: document[hidden],\n      scaleExtent: [1, 10],\n      translateExtent: [\n        [-Infinity, -Infinity],\n        [Infinity, Infinity]\n      ],\n      transform: d3.zoomIdentity,\n\n      rowMap: {},\n      rows: 1,\n\n      // Scales\n      x: d3.scaleTime(),\n      y: d3.scaleBand(),\n      xAxis: null\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['user', 'timezone']),\n    calcRows: function() {\n      return debounce(() => {\n        this.rawCalcRows()\n      }, 300)\n    },\n    resizeChart: function() {\n      return debounce(() => {\n        requestAnimationFrame(this.rawResizeChart)\n      }, 500)\n    },\n    resizeCanvas: function() {\n      return debounce(() => {\n        requestAnimationFrame(this.rawResizeCanvas)\n      }, 300)\n    },\n    setChartDimensions: function() {\n      return debounce(() => {\n        requestAnimationFrame(this.rawSetChartDimensions)\n      }, 300)\n    },\n    start() {\n      if (!this.startTime) return this.now\n      return new Date(this.startTime)\n    },\n    end() {\n      if (!this.endTime) return null\n      return new Date(this.endTime)\n    },\n    breakpoints_() {\n      const breakpoints = [...this.breakpoints]\n\n      if (this.live_) {\n        breakpoints.push({\n          label: '(now)',\n          time: this.now,\n          color: 'var(--v-utilGrayMid-base)'\n        })\n      }\n\n      if (this.hoveredBreakpoint) {\n        breakpoints.push({\n          label: this.hoveredBreakpoint.label,\n          time: this.hoveredBreakpoint.time,\n          color: 'var(--v-utilGrayMid-base)'\n        })\n      }\n\n      return breakpoints.sort((a, b) => new Date(a.time) - new Date(b.time))\n    },\n    breakpointTooltipStyle() {\n      if (!this.hovered) return\n      let half = breakpointTooltipWidth / 2\n      let p = this.boundingClientRect\n      let overRight = this.hovered.x + half - p.width > 0\n      let overLeft = this.hovered.x - half < 0\n      return {\n        left: `${\n          overRight ? p.width - half : overLeft ? half : this.hovered.x\n        }px`,\n        top: `${this.hovered.y}px`,\n        width: `${breakpointTooltipWidth}px`\n      }\n    },\n    itemTooltipStyle() {\n      if (!this.hovered) return\n      let half = itemTooltipWidth / 2\n      let p = this.boundingClientRect\n      let overRight = this.hovered.x + half - p.width > 0\n      let overLeft = this.hovered.x - half < 0\n      return {\n        left: `${\n          overRight ? p.width - half : overLeft ? half : this.hovered.x\n        }px`,\n        top: `${this.hovered.y}px`,\n        width: `${itemTooltipWidth}px`\n      }\n    },\n    updateBars: function() {\n      return throttle(\n        () => {\n          this.rawUpdateBars()\n        },\n        this.firstRenderComplete ? 32 : this.animationDuration\n      )\n    }\n  },\n  mounted() {\n    this.worker = TimelineWorker({ type: 'module' })\n    this.timer?.stop()\n\n    this.canvas = d3.select(`#${this.id}-canvas`)\n    this.svg = d3.select(`#${this.id}-svg`)\n\n    this.xAxisNode = this.svg.append('g')\n    this.breakpointsNode = this.svg.append('g')\n\n    this.resizeChart()\n\n    if (!this.loading) {\n      this.calcRows()\n    }\n\n    window.addEventListener('resize', this.resizeChart)\n    window.addEventListener(\n      visibilityChange,\n      this.handleVisibilityChange,\n      false\n    )\n\n    this.setChartDimensions()\n\n    this.canvas.on('click', this.click)\n    this.canvas.on('mousemove', this.mousemove)\n    this.canvas.on('mouseout', this.mouseout)\n\n    this.live_ = this.live\n\n    this.breakpointsUnwatch = this.$watch(\n      'breakpoints',\n      debounce(function() {\n        if (this.pauseUpdates) return\n        this.updateBreakpoints(true)\n      }, 500)\n    )\n    this.itemUnwatch = this.$watch(\n      'items',\n      debounce(function() {\n        if (this.pauseUpdates) return\n        this.calcRows()\n        this.updateBars()\n      }, 500),\n      { deep: true }\n    )\n\n    this.endTimeUnwatch = this.$watch('endTime', () => {\n      if (this.pauseUpdates) return\n      this.updateScales()\n    })\n\n    this.liveUnwatch = this.$watch('live', val => {\n      this.live_ = val\n    })\n\n    this.startTimeUnwatch = this.$watch('startTime', () => {\n      if (this.pauseUpdates) return\n      this.updateScales()\n    })\n\n    this.pauseUpdatesUnwatch = this.$watch('pauseUpdates', val => {\n      if (!val && !this.live_) {\n        this.updateScales()\n      }\n    })\n  },\n  beforeDestroy() {\n    this.worker?.terminate()\n    this.worker = null\n    this.timer?.stop()\n    this.interval?.stop()\n    window.removeEventListener('resize', this.resizeChart)\n    window.removeEventListener(visibilityChange, this.handleVisibilityChange)\n\n    this.canvas.on('.zoom', null)\n    this.canvas.on('click', null)\n    this.canvas.on('mousemove', null)\n    this.canvas.on('mouseout', null)\n    this.xAxisNode.on('end', null)\n\n    this.itemUnwatch()\n    this.breakpointsUnwatch()\n    this.endTimeUnwatch()\n    this.liveUnwatch()\n    this.startTimeUnwatch()\n    this.pauseUpdatesUnwatch()\n  },\n  methods: {\n    async rawCalcRows() {\n      const prevRows = this.rows\n      const { rowMap, rows } = await this.worker.GenerateRows(this.items)\n\n      this.rows = rows\n      this.rowMap = rowMap\n      if (this.rows !== prevRows) this.updateScales()\n    },\n    click(e) {\n      const context = this.canvas.node().getContext('2d')\n      let hoveredId,\n        hovered = {\n          data: [],\n          x: e.offsetX,\n          y: this.height\n        }\n      let x = (e.offsetX - this.transform.x) * (1 / this.transform.k)\n      let y = e.offsetY * (1 / this.transform.k)\n\n      for (let i = 0; i < this.bars.length; ++i) {\n        const bar = this.bars[i]\n        if (context.isPointInPath(bar.path2D, x, y)) {\n          hoveredId = bar.id\n          hovered.data.push(bar)\n\n          this.canvas._groups[0][0].style.cursor = 'pointer'\n          break\n        }\n      }\n\n      if (!hoveredId || hoveredId !== this.hoveredItemId) {\n        this.updateBars()\n      }\n\n      this.hoveredItemId = hoveredId\n      this.$emit('click', { id: hoveredId, ...hovered })\n    },\n    breaklineMouseout() {\n      this.hoveredBreakpoints = null\n      this.hovered = null\n      this.$emit('breakpoint-hover', null)\n    },\n    breaklineMouseover(e) {\n      this.hoveredBreakpoints = e.currentTarget?.__data__.breakpoints\n      this.hovered = {\n        x: e.offsetX,\n        y: this.height\n      }\n      this.$emit('breakpoint-hover', e.currentTarget?.__data__)\n    },\n    mousemove(e) {\n      if (this.showTimestampAtCursor) {\n        this.hoveredBreakpoint = {\n          time: this.x.invert(\n            (e.offsetX - this.transform.x) * (1 / this.transform.k)\n          ),\n          label: this.logTimeExtended(\n            new Date(\n              this.x.invert(\n                (e.offsetX - this.transform.x) * (1 / this.transform.k)\n              )\n            )\n          )\n        }\n        this.updateBreakpoints()\n      }\n\n      const context = this.canvas.node().getContext('2d')\n      let hoveredIds = []\n      let hovered = {\n        data: [],\n        x: e.offsetX,\n        y: this.height\n      }\n      let x = (e.offsetX - this.transform.x) * (1 / this.transform.k)\n      let y = e.offsetY * (1 / this.transform.k)\n\n      for (let i = 0; i < this.bars.length; ++i) {\n        const bar = this.bars[i]\n        if (context.isPointInPath(bar.path2D, x, y)) {\n          hoveredIds.push(bar.id)\n          hovered.data.push(bar)\n\n          this.canvas._groups[0][0].style.cursor = 'pointer'\n        }\n      }\n\n      if (\n        (!hoveredIds.length && this.hoveredItemIds.length) ||\n        hoveredIds.some(h => !this.hoveredItemIds.includes(h)) ||\n        hoveredIds.length !== this.hoveredItemIds.length\n      ) {\n        if (!hoveredIds.length) this.canvas._groups[0][0].style.cursor = null\n\n        this.$emit('hover', { ids: hoveredIds, ...hovered })\n        this.updateBars()\n      }\n\n      this.hoveredItemIds = hoveredIds\n      this.hovered = hovered\n    },\n    mouseout() {\n      this.hoveredBreakpoint = null\n      this.updateBreakpoints()\n\n      // if we don't have a hovered item already\n      // we don't need to do anything\n      if (!this.hoveredItemIds.length) return\n      this.hoveredItemIds = []\n      this.hovered = null\n\n      this.canvas._groups[0][0].style.cursor = null\n      this.updateBars()\n      this.$emit('hover', null)\n    },\n    newXAxis(x) {\n      let day\n      let meridiem\n\n      return d3\n        .axisBottom(x)\n        .ticks(7)\n        .tickSizeOuter(0)\n        .tickFormat(d => {\n          const t = moment(d).tz(this.timezone)\n          const dateObj = t ? t : moment(d)\n          const dayWeek = dateObj.day()\n          const hours = dateObj.hour() < 12 ? 'am' : 'pm'\n\n          const shortened =\n            day && dayWeek === day && meridiem && hours === meridiem\n\n          if (!shortened) {\n            day = dayWeek\n            meridiem = hours\n          }\n\n          const formatted = dateObj.calendar(null, {\n            sameDay: `h:mm${shortened ? '' : 'a'}`,\n            nextDay: 'D MMM h:mm',\n            nextWeek: 'D MMM h:mm',\n            lastDay: `${shortened ? '' : '[Yesterday at]'} h:mm${\n              shortened ? '' : 'a'\n            }`,\n            lastWeek: `${shortened ? '' : 'D MMM [at] '}h:mm${\n              shortened ? '' : 'a'\n            }`,\n            sameElse: `${shortened ? '' : 'D MMM [at] '}h:mm${\n              shortened ? '' : 'a'\n            }`\n          })\n\n          return `${formatted}`\n        })\n    },\n    render(elapsed) {\n      const t = Math.min(\n        1,\n        elapsed /\n          (this.live_ && this.firstRenderComplete ? 1 : this.animationDuration)\n      )\n\n      const context = this.canvas.node().getContext('2d')\n      context.save()\n      context.clearRect(0, 0, this.width_, this.height_)\n      context.translate(this.transform.x, 1)\n      context.scale(this.transform.k, this.transform.k)\n\n      let len = this.bars.length\n\n      for (let i = 0; i < len; ++i) {\n        context.beginPath()\n        const bar = this.bars[i]\n\n        const isHovered = this.hoveredItemIds.includes(bar.id)\n\n        bar.alpha = isHovered\n          ? 1\n          : this.hoveredItemIds.length\n          ? 0.5\n          : bar.alpha || 1\n        bar.x = bar.x0 * (1 - t) + bar.x1 * t\n        bar.y = bar.y0 * (1 - t) + bar.y1 * t\n        bar.height = bar.height0 * (1 - t) + bar.height1 * t\n\n        bar.width = bar.width0 * (1 - t) + bar.width1 * t\n        bar.shadow = bar.shadow0 * (1 - t) + bar.shadow1 * t\n\n        this.bars[i].path2D = new Path2D()\n\n        const radius = (bar.height / 2) * (1 / this.transform.k)\n        const x = bar.x + radius / 2\n        const y = bar.y * (1 / this.transform.k)\n\n        let offset = 0\n        context.globalAlpha = bar.alpha || 1\n\n        // Create outline of the bar\n        if (bar.shadow && (!this.hoveredItemIds.length || isHovered)) {\n          context.beginPath()\n          // context.lineWidth = 1 * (1 / this.transform.k)\n          // context.strokeStyle = colors[0]\n          context.fillStyle = 'var(--v-utilGrayLight-base)'\n          context.shadowColor = 'var(--v-utilGrayMid-base)'\n          context.shadowBlur = bar.shadow\n          const compress = 2 * (1 / this.transform.k)\n          const x = bar.x + radius / 2 + compress / 2\n          const width = bar.width - radius * 2 - compress\n\n          context.arc(\n            x,\n            y + radius,\n            radius - compress / 2,\n            -(90 * Math.PI) / 180,\n            -(270 * Math.PI) / 180,\n            true\n          )\n\n          context.arc(\n            x + width,\n            y + radius,\n            radius - compress / 2,\n            (90 * Math.PI) / 180,\n            (270 * Math.PI) / 180,\n            true\n          )\n          context.closePath()\n          context.fill()\n          // End create outline of the bar\n        }\n\n        context.shadowBlur = 0\n        context.strokeStyle = getComputedStyle(document.body).getPropertyValue(\n          '--v-appForeground-base'\n        )\n        context.lineWidth = 2 / this.transform.k\n\n        bar.colors.forEach((color, j) => {\n          context.beginPath()\n\n          context.fillStyle = color.color || 'var(--v-utilGrayLight-base)'\n\n          const capLeft = new Path2D(),\n            capRight = new Path2D(),\n            rect = new Path2D()\n\n          const calcWidth = (bar.width - radius * 2) * color.value\n          const width = calcWidth < 0 ? 0 : calcWidth\n\n          rect.rect(\n            x + offset,\n            y + (width <= 0 ? context.lineWidth : 0),\n            width,\n            radius * 2 - (width <= 0 ? context.lineWidth : 0)\n          )\n\n          if (j === 0) {\n            capLeft.arc(\n              x,\n              y + radius,\n              radius,\n              -(90 * Math.PI) / 180,\n              -(270 * Math.PI) / 180,\n              true\n            )\n\n            rect.addPath(capLeft)\n            context.stroke(capLeft)\n          }\n\n          if (j === bar.colors.length - 1) {\n            capRight.arc(\n              x + width + offset,\n              y + radius,\n              radius,\n              (90 * Math.PI) / 180,\n              (270 * Math.PI) / 180,\n              true\n            )\n\n            rect.addPath(capRight)\n\n            context.stroke(capRight)\n          }\n\n          if (width <= 0) {\n            capLeft.addPath(capRight)\n            context.fill(capLeft)\n          } else {\n            context.fill(rect)\n          }\n\n          // Fill the shape but add the shape to the reference\n          // path, so we can calculation intersections\n          this.bars[i].path2D.addPath(rect)\n          this.bars[i].path2D.addPath(capLeft)\n          this.bars[i].path2D.addPath(capRight)\n          offset += width\n        })\n\n        // These are pretty fuzzy right now\n        // so we'll probably want to move them to the svg layer\n        if (bar.label && !condensed) {\n          const savedStrokeStyle = context.fillStyle\n          const fontSize = 10 * (1 / this.transform.k)\n          const textY = (9 + bar.y + bar.height) * (1 / this.transform.k)\n\n          const tX = bar.x + this.transform.x / this.transform.k\n          const x1 = bar.width + bar.x\n          const overLeft = tX < 0\n          // const overRight = transformedX > this.width_ / this.transform.k\n\n          const leftEdge = -(this.transform.x / this.transform.k)\n          const textX = overLeft\n            ? leftEdge > x1\n              ? bar.width + bar.x\n              : leftEdge\n            : bar.x\n\n          context.font = `${fontSize}px Roboto`\n          // context.textAlign = overLeft && leftEdge > tX1 ? 'end' : 'start'\n          context.textAlign = 'start'\n          context.fillStyle = 'var(--v-utilGrayMid-base)'\n          context.fillText(bar.label, textX, textY)\n          context.fillStyle = savedStrokeStyle\n        }\n      }\n\n      context.restore()\n\n      if (t === 1) {\n        this.timer.stop()\n        this.bars = this.bars.filter(b => !b.leaving)\n        this.firstRenderComplete = true\n      }\n    },\n    rawUpdateBars() {\n      const height =\n        (this.y.bandwidth() > maxBarRadius\n          ? maxBarRadius\n          : this.y.bandwidth()) ?? 0\n\n      const calcBar = item => {\n        if (this.pauseUpdates) return\n\n        const x =\n          (item.start_time\n            ? this.x(new Date(item.start_time))\n            : this.x(this.now) + 20) ?? 0\n\n        const width = item.end_time\n          ? this.x(new Date(item.end_time)) - x\n          : item.start_time\n          ? this.x(this.now) - x\n          : 0\n\n        const y =\n          (this.y(this.rowMap[item.id]) ?? 0) + (this.y.bandwidth() - height)\n\n        const alpha = 1\n\n        const barIndex = this.bars.findIndex(b => b.id == item.id)\n\n        const label = item.label\n\n        // If the item isn't present in the bar array\n        // we instantiate a new bar...\n        if (barIndex === -1) {\n          this.bars.push({\n            ...item,\n            alpha: alpha,\n            height0: height,\n            height1: height,\n            height: height,\n            label: label,\n            row: this.rowMap[item.id],\n            shadow: 0,\n            shadow0: 0,\n            shadow1: item.shadow ? 5 : 0,\n            width0: 0,\n            width1: width,\n            width: 0,\n            x0: x || 0,\n            x1: x,\n            x: x || 0,\n            y0: y,\n            y1: y,\n            y: y\n          })\n        } else {\n          // ...otherwise we update the existing bar with\n          // new values\n          const bar = this.bars[barIndex]\n\n          const bar1 = {\n            ...item,\n            alpha: alpha,\n            height0: bar.height,\n            height1: height,\n            height: bar.height,\n            row: this.rowMap[item.id],\n            shadow: bar.shadow,\n            shadow0: bar.shadow,\n            shadow1: item.shadow ? 5 : 0,\n            width0: bar.width,\n            width1: width,\n            width: bar.width,\n            x0: bar.x,\n            x1: x,\n            x: bar.x,\n            y0: bar.y,\n            y1: y,\n            y: bar.y\n          }\n\n          this.bars[barIndex] = { ...bar, ...bar1, ...item }\n        }\n      }\n\n      this.items.forEach(calcBar)\n\n      // Check our existing bars against current data\n      this.bars\n        // If this is a valid bar, do nothing since its data was already\n        // updated\n        .filter(bar => !this.items.find(item => item.id == bar.id))\n        // ...otherwise we'll start the exit animation\n        .forEach((bar, i) => {\n          const bar1 = {\n            height0: bar.height,\n            height1: height,\n            height: bar.height,\n            width0: bar.width,\n            width1: 0,\n            width: bar.width,\n            x0: bar.x,\n            x1: bar.x,\n            x: bar.x,\n            y0: bar.y,\n            y1: bar.y,\n            y: bar.y,\n            leaving: true\n          }\n\n          this.bars[i] = { ...bar, ...bar1 }\n        })\n\n      if (this.timer) {\n        this.timer.restart(this.render)\n      } else {\n        this.timer = d3.timer(this.render)\n      }\n    },\n    play() {\n      this.pauseUpdates = false\n      this.updateX()\n    },\n    playOrPause() {\n      this.pauseUpdates ? this.play() : this.pause()\n    },\n    pause() {\n      this.pauseUpdates = true\n    },\n    rawResizeChart() {\n      let parent = this.canvas.select(function() {\n        return this.parentNode\n      })?._groups?.[0]?.[0]\n\n      let computedStyle = window.getComputedStyle(parent, null)\n\n      // This is the padding that the parent element has\n      // NOT the internal padding\n      let padding = {\n        left: parseFloat(computedStyle.getPropertyValue('padding-left')),\n        right: parseFloat(computedStyle.getPropertyValue('padding-right')),\n        top: parseFloat(computedStyle.getPropertyValue('padding-top')),\n        bottom: parseFloat(computedStyle.getPropertyValue('padding-bottom'))\n      }\n\n      this.boundingClientRect = this.$refs['parent']?.getBoundingClientRect()\n\n      this.width = Math.floor(parent.clientWidth - padding.left - padding.right)\n\n      // If a height is specified in the component\n      // we use that, otherwise we assume infinite height and\n      // let the component expand based on the min\n      // bar radius\n      this.height = Math.floor(\n        parent.clientHeight - padding.top - padding.bottom\n      )\n\n      if (!this.width_ || (this.width && this.width_ !== this.width)) {\n        this.setChartDimensions()\n      }\n    },\n    rawSetChartDimensions() {\n      this.pause()\n      clearTimeout(this.drawTimeout)\n\n      if (!this.height || this.height <= 0) {\n        return\n      }\n\n      this.svg\n        .attr('viewbox', `0 0 ${this.width} ${this.height}`)\n        .attr('width', this.width)\n        .attr('height', this.height)\n\n      this.width_ = this.width\n\n      this.xAxisNode\n        .attr('class', 'x-axis-group')\n        .style(\n          'transform',\n          `translate(0, ${this.height - this.padding.bottom}px)`\n        )\n\n      this.resizeCanvas()\n      this.updateScales()\n\n      const filter = () => {\n        return event.isTrusted\n      }\n\n      // We use a timeout to account for the transition\n      // period when redrawing the canvas and svg nodes\n      this.drawTimeout = setTimeout(() => {\n        this.play()\n\n        this.zoom\n          .scaleExtent(this.scaleExtent)\n          .translateExtent(this.translateExtent)\n          .on('zoom', this.zoomed)\n          .filter(filter)\n\n        // Sets the initial transform\n        // and updates the scales and breakpoints\n        this.zoomed({ transform: d3.zoomIdentity })\n\n        // Adds the zoom entity\n        // to the canvas element\n        this.canvas.call(this.zoom)\n      }, this.animationDuration)\n    },\n    rawResizeCanvas() {\n      const fullHeight =\n        this.rows * minBarRadius +\n        this.rows * minBarRadius * this.barPadding * 2\n\n      this.height_ =\n        (condensed\n          ? this.height - this.padding.y\n          : Math.max(fullHeight, this.height) - this.padding.y) -\n        this.padding.bottom\n\n      this.canvas\n        .style('width', `${this.width_}px`)\n        .style('height', `${this.height_}px`)\n        .attr('width', this.width_)\n        .attr('height', this.height_)\n        .style('transform', `translate(0, ${this.padding.y * 0.75}px)`)\n\n      this.updateScales()\n    },\n    updateBreakpoints(shouldTransition) {\n      this.breakpointsNode.attr(\n        'transform',\n        () => `translate(${this.transform.x} 5) scale(${this.transform.k})`\n      )\n\n      const breakpoints = this.breakpoints_\n      const breakpointGroups = []\n\n      for (let i = 0; i < this.breakpoints_.length; ++i) {\n        const d = breakpoints[i]\n        const x = d.time ? this.x(new Date(d.time)) : -20\n        const intersectionIndex = breakpointGroups.findIndex(\n          g =>\n            x <= g.x + 40 * (1 / this.transform.k) &&\n            x >= g.x - 40 * (1 / this.transform.k)\n        )\n\n        if (intersectionIndex > -1) {\n          breakpointGroups[intersectionIndex].breakpoints.push({\n            id: i,\n            x: x,\n            ...d\n          })\n\n          // This section is used to aggregate breakpoints at the median\n          // instead of at the mean.\n          // breakpointGroups[intersectionIndex].breakpoints.sort(\n          //   (a, b) => a.x - b.x\n          // )\n          // const median = Math.ceil(\n          //   breakpointGroups[intersectionIndex].breakpoints.length / 2\n          // )\n          // breakpointGroups[intersectionIndex].x =\n          //   breakpointGroups[intersectionIndex].breakpoints[median].x\n\n          breakpointGroups[intersectionIndex].x =\n            breakpointGroups[intersectionIndex].breakpoints.reduce(\n              (acc, b) => acc + b.x,\n              0\n            ) / breakpointGroups[intersectionIndex].breakpoints.length\n\n          breakpoints[i].group_ref = intersectionIndex\n          breakpoints[i].x = x\n        } else {\n          breakpoints[i].group_ref = breakpointGroups.push({\n            breakpoints: [{ id: i, x: x, ...d }],\n            x: x\n          })\n\n          breakpoints[i].x = x\n        }\n      }\n\n      const breakpointsGroup = this.breakpointsNode\n        .selectAll('.breakpoints-group')\n        .data(breakpointGroups)\n\n      breakpointsGroup.join(\n        enter => {\n          const g = enter\n            .append('g')\n            .attr('class', 'breakpoints-group')\n            .style('opacity', 1)\n            .attr(\n              'transform',\n              d => `translate(${d.x}) scale(${1 / this.transform.k})`\n            )\n\n          g.append('path')\n            .attr('stroke', 'var(--v-utilGrayMid-base)')\n            .attr('stroke-width', 1.5)\n            .attr('stroke-dasharray', 5)\n            .attr('d', `M0,${this.height - 25}L0,10`)\n            .style('pointer-events', 'none')\n            .style('opacity', this.firstRenderComplete ? 1 : 0)\n            .transition()\n            .delay((d, i) => i * 50)\n            .duration(this.animationDuration)\n            .style('opacity', 1)\n\n          g.append('text')\n            .style('font-size', '8px')\n            .style('pointer-events', 'none')\n            .attr('fill', 'var(--v-utilGrayMid-base)')\n            .attr('alignment-baseline', 'hanging')\n            .attr('text-anchor', d => d.anchor || 'middle')\n            .style('user-select', 'none')\n            .text(d => {\n              if (d.breakpoints.length === 1) {\n                let breakpoint = d.breakpoints[0]\n                return this.showLabels\n                  ? breakpoint.label\n                  : this.logTimeExtended(new Date(breakpoint.time))\n              } else {\n                return `${d.breakpoints.length}+ states`\n              }\n            })\n            .attr('y', 1)\n            .attr('x', 0)\n            .style('opacity', this.firstRenderComplete ? 1 : 0)\n            .transition()\n            .delay((d, i) => i * 50)\n            .duration(50)\n            .style('opacity', 1)\n\n          return g\n            .on('mouseover', this.breaklineMouseover)\n            .on('mouseout', this.breaklineMouseout)\n            .call(enter =>\n              enter\n                .transition('enter')\n                .duration(16)\n                .style('opacity', 1)\n            )\n        },\n        update =>\n          update.call(update => {\n            update\n              .select('path')\n              .transition('update')\n              .duration(this.animationDuration)\n              .attr('stroke', 'var(--v-utilGrayMid-base)')\n\n            update\n              .select('text')\n              .attr('text-anchor', d => d.anchor || 'middle')\n              .text(d => {\n                if (d.breakpoints.length === 1) {\n                  let breakpoint = d.breakpoints[0]\n                  return this.showLabels\n                    ? breakpoint.label\n                    : this.logTimeExtended(new Date(breakpoint.time))\n                } else {\n                  return `${d.breakpoints.length}+ states`\n                }\n              })\n              .transition()\n              .delay(50)\n              .duration(50)\n              .style('opacity', 1)\n\n            return update.call(update =>\n              update\n                .transition('update')\n                .duration(shouldTransition ? 16 : 0)\n                .attr(\n                  'transform',\n                  d => `translate(${d.x}) scale(${1 / this.transform.k})`\n                )\n            )\n          }),\n        exit => {\n          return exit\n            .on('mouseover', null)\n            .on('mouseout', null)\n            .call(exit =>\n              exit\n                .transition('exit')\n                .duration(50)\n                .style('opacity', 0)\n                .remove()\n            )\n        }\n      )\n\n      const radius = 5\n\n      breakpointsGroup\n        .selectAll('.breakline-circle')\n        .data(d => d.breakpoints)\n        .join(\n          enter => {\n            const g = enter\n              .append('circle')\n              .attr('class', 'breakline-circle')\n              .style('cursor', 'pointer')\n              .attr('id', d => `circle-${d.id}`)\n              .style('opacity', 1)\n\n            g.attr('cy', this.height - 25)\n              .attr('cx', (d, i, arr) => {\n                let median = Math.ceil(arr.length / 2) - 1\n                return (\n                  (i - median) * 5 - (arr.length % 2 === 0 ? radius / 2 : 0)\n                )\n              })\n              .attr('r', radius)\n              .attr('stroke-width', 0.5)\n              .attr('stroke', 'var(--v-appForeground-base)')\n              .attr('fill', d => d.color)\n\n            return g\n          },\n          update => {\n            return update\n              .attr('fill', d => d.color)\n              .style('opacity', 1)\n              .call(update =>\n                update\n                  .transition('update')\n                  .duration(50)\n                  .attr('cx', (d, i, arr) => {\n                    let median = Math.ceil(arr.length / 2) - 1\n                    return (\n                      (i - median) * 5 - (arr.length % 2 === 0 ? radius / 2 : 0)\n                    )\n                  })\n              )\n          },\n          exit => {\n            return exit.call(exit =>\n              exit\n                .transition('exit')\n                .duration(50)\n                .style('opacity', 0)\n                .remove()\n            )\n          }\n        )\n    },\n    updateX(shouldTransition) {\n      clearTimeout(this.updateXTimeout)\n      // Passing true to this method\n      // removes the duration from the axis transitions\n      // meaning we can keep the scales in sync with user actions\n      // like zooming and panning\n      const x = this.transform.rescaleX(this.x)\n      const xAxis = this.newXAxis(x)\n      this.now = new Date()\n\n      this.updateBars()\n      this.updateBreakpoints(shouldTransition)\n\n      if (this.live_ && !this.pauseUpdates) {\n        this.updateXTimeout = setTimeout(() => {\n          this.updateScales()\n        }, this.animationDuration)\n      }\n\n      // We only need this section if we want to draw the x-axis\n      this.xAxisNode\n        .transition()\n        .duration(shouldTransition ? 64 : 0)\n        .call(xAxis)\n        .on('end', () => {\n          this.xAxisNode.on('end', null)\n          this.updateBars()\n          this.updateBreakpoints(shouldTransition)\n\n          if (this.live_ && !this.pauseUpdates) {\n            this.updateScales()\n            ++this.iterations\n          }\n        })\n    },\n    updateScales() {\n      if (!this.height_ || !this.width_) return\n\n      const prevDomainEnd = this.domainEnd\n\n      this.now = new Date()\n      const startMs = this.start?.getTime() ?? 0\n      const endMs = (this.end ?? this.now).getTime()\n      const domainPadding = (endMs - startMs) * 0.025\n      this.domainStart = new Date(startMs - domainPadding)\n      this.domainEnd = new Date(endMs + domainPadding)\n\n      this.x.range([this.padding.left, this.width_ - this.padding.right])\n      this.x.domain([this.domainStart, this.domainEnd])\n      this.y.domain([...Array(this.rows).keys()])\n      this.y.paddingInner(this.barPadding)\n      this.y.paddingOuter(this.barPadding * 2)\n      this.y.range([0, this.height_])\n\n      // This is the the smallest period represented by the full graph\n      // i.e. if zoomed in to the max extent the length of time the\n      // graph will show.\n      // Duration of entire run / smallest period (ms)\n      // We default to 5 seconds right now.\n      const scaleExtentUpper = (endMs - startMs) / 5000\n      this.scaleExtent = [1, scaleExtentUpper < 2 ? 2 : scaleExtentUpper]\n\n      this.translateExtent = [\n        [0, 0],\n        [this.width_, 0]\n      ]\n\n      if (prevDomainEnd && this.transform.k !== 1) {\n        const translateBy = this.x(prevDomainEnd) - this.x(this.domainEnd)\n\n        this.transform.x += translateBy\n\n        this.canvas.call(this.zoom, this.transform)\n      } else {\n        this.canvas.call(this.zoom)\n      }\n\n      this.updateX(true)\n    },\n    statusStyle(state) {\n      return {\n        'border-radius': '50%',\n        display: 'inline-block',\n        'background-color': `var(--v-${state}-base)`,\n        height: '1rem',\n        width: '1rem'\n      }\n    },\n    zoomed({ transform }) {\n      this.transform = transform\n      this.updateX()\n    },\n    collapse() {\n      this.resizeCanvas()\n    },\n    handleVisibilityChange() {\n      this.pauseUpdates = document[hidden]\n    },\n    panLeft() {\n      this.canvas\n        .transition()\n        .duration(500)\n        .call(this.zoom.translateBy, 200, 0)\n    },\n    panRight() {\n      this.canvas\n        .transition()\n        .duration(500)\n        .call(this.zoom.translateBy, -200, 0)\n    },\n    redraw() {\n      const context = this.canvas.node().getContext('2d')\n      context.clearRect(0, 0, this.width_, this.height_)\n      this.bars = []\n      this.firstRenderComplete = false\n      this.resizeChart()\n      this.setChartDimensions()\n    },\n    zoomIn() {\n      this.canvas\n        .transition()\n        .duration(500)\n        .call(this.zoom.scaleBy, 2)\n    },\n    zoomOut() {\n      this.canvas\n        .transition()\n        .duration(500)\n        .call(this.zoom.scaleBy, 0.5)\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    ref=\"parent\"\n    class=\"position-relative timeline-container\"\n    style=\"height: 100%;\"\n  >\n    <div\n      v-if=\"showControls\"\n      class=\"controls-overlay d-flex flex-column align-center\"\n      multiple\n    >\n      <v-btn\n        small\n        depressed\n        icon\n        tile\n        color=\"utilGrayMid\"\n        :disabled=\"transform.k == scaleExtent[1]\"\n        @click=\"zoomIn\"\n      >\n        <v-icon>add</v-icon>\n      </v-btn>\n\n      <div class=\"d-flex\">\n        <v-btn\n          small\n          icon\n          depressed\n          tile\n          color=\"utilGrayMid\"\n          :disabled=\"transform.k === 1 || transform.x == translateExtent[0][0]\"\n          @click=\"panLeft\"\n        >\n          <v-icon>arrow_left</v-icon>\n        </v-btn>\n        <v-btn\n          small\n          icon\n          depressed\n          tile\n          color=\"utilGrayMid\"\n          :disabled=\"\n            transform.k === 1 ||\n              transform.k * translateExtent[1][0] + transform.x <=\n                translateExtent[1][0]\n          \"\n          @click=\"panRight\"\n        >\n          <v-icon>arrow_right</v-icon>\n        </v-btn>\n      </div>\n\n      <v-btn\n        small\n        depressed\n        icon\n        tile\n        color=\"utilGrayMid\"\n        :disabled=\"transform.k == scaleExtent[0]\"\n        @click=\"zoomOut\"\n      >\n        <v-icon>remove</v-icon>\n      </v-btn>\n    </div>\n\n    <v-menu bottom left :close-on-content-click=\"false\">\n      <template #activator=\"{ on }\">\n        <v-btn icon small class=\"input-menu\" v-on=\"on\">\n          <v-icon>more_vert</v-icon>\n        </v-btn>\n      </template>\n\n      <v-list dense tile class=\"d-flex justify-middle align-end flex-column\">\n        <v-list-item v-if=\"showDebugControls\" class=\"d-flex  my-4\">\n          <v-btn\n            small\n            :disabled=\"transform.k == scaleExtent[1]\"\n            @click=\"zoomIn\"\n          >\n            +\n          </v-btn>\n          <v-btn\n            small\n            class=\"ml-2\"\n            :disabled=\"transform.k == scaleExtent[0]\"\n            @click=\"zoomOut\"\n          >\n            -\n          </v-btn>\n\n          <v-btn\n            small\n            class=\"ml-12\"\n            :disabled=\"\n              transform.k === 1 || transform.x == translateExtent[0][0]\n            \"\n            @click=\"panLeft\"\n          >\n            ←\n          </v-btn>\n          <v-btn\n            small\n            class=\"ml-2\"\n            :disabled=\"\n              transform.k === 1 ||\n                transform.k * translateExtent[1][0] + transform.x <=\n                  translateExtent[1][0]\n            \"\n            @click=\"panRight\"\n          >\n            →\n          </v-btn>\n        </v-list-item>\n\n        <v-list-item\n          v-if=\"showDebugControls\"\n          class=\"text-caption text-right d-flex flex-column justify-space-around\"\n        >\n          <span>\n            Scale:\n            <span class=\"font-weight-medium\">\n              {{ Math.round(transform.k * 100) / 100 }}\n            </span>\n          </span>\n          <span>\n            Transform\n            <span class=\"font-weight-medium\">\n              {{ Math.round(transform.x * 100) / 100 }},\n              {{ Math.round(transform.y * 100) / 100 }}\n            </span>\n          </span>\n          <span>\n            Translate Extent\n            <span class=\"font-weight-medium\"> {{ translateExtent }}, </span>\n          </span>\n        </v-list-item>\n\n        <v-list-item>\n          <v-checkbox\n            v-model=\"showControls\"\n            label=\"Show Controls\"\n            hide-details\n            class=\"v-input--reverse input-menu-item ma-0\"\n          ></v-checkbox>\n        </v-list-item>\n\n        <v-list-item>\n          <v-checkbox\n            v-model=\"showLabels\"\n            label=\"Breakpoint Labels\"\n            hide-details\n            class=\"v-input--reverse input-menu-item ma-0\"\n            @change=\"updateBreakpoints\"\n          ></v-checkbox>\n        </v-list-item>\n\n        <v-list-item>\n          <v-checkbox\n            v-model=\"showTimestampAtCursor\"\n            label=\"Cursor Timestamp\"\n            hide-details\n            class=\"v-input--reverse input-menu-item ma-0\"\n            @change=\"updateBreakpoints\"\n          ></v-checkbox>\n        </v-list-item>\n\n        <v-list-item v-if=\"showDebugControls\" @click=\"playOrPause\">\n          {{ pauseUpdates ? 'Play' : 'Pause' }}\n        </v-list-item>\n\n        <v-list-item v-if=\"showDebugControls\" @click=\"collapse\">\n          {{ condensed_ ? 'Expand' : 'Collapse' }}\n        </v-list-item>\n\n        <v-list-item v-if=\"showDebugControls\" @click=\"redraw\">\n          Redraw\n        </v-list-item>\n      </v-list>\n    </v-menu>\n\n    <canvas :id=\"`${id}-canvas`\" class=\"canvas mx-auto\" />\n    <svg :id=\"`${id}-svg`\" class=\"svg\" />\n\n    <div\n      v-if=\"hoveredItemIds.length && $slots['item-tooltip']\"\n      class=\"timeline-tooltip\"\n      :style=\"itemTooltipStyle\"\n    >\n      <slot name=\"item-tooltip\" />\n    </div>\n\n    <div\n      v-if=\"hoveredBreakpoints && $slots['breakpoint-tooltip']\"\n      class=\"timeline-tooltip\"\n      :style=\"breakpointTooltipStyle\"\n    >\n      <slot name=\"breakpoint-tooltip\" />\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.input-menu {\n  opacity: 0.35;\n  position: absolute;\n  right: 0;\n  top: -20px;\n  z-index: 2;\n}\n\n.timeline-container {\n  position: relative;\n\n  .controls-overlay {\n    background-color: var(--v-appForeground-base);\n    box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),\n      1px 2px 2px 0 rgba(0, 0, 0, 0.14), 3px 1px 5px 0 rgba(0, 0, 0, 0.12) !important;\n    position: absolute;\n    right: -50px;\n    top: 50%;\n    transform: translate(0, -60%);\n    transition: all 250ms;\n    z-index: 2;\n\n    > .v-btn {\n      width: 100%;\n    }\n\n    &:focus,\n    &:hover {\n      opacity: 1;\n    }\n\n    @media only screen and (max-width: 1440px) {\n      box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),\n        -1px 2px 2px 0 rgba(0, 0, 0, 0.14),\n        -5px 1px 5px -4px rgba(0, 0, 0, 0.12) !important;\n      margin-right: -12px;\n      opacity: 0.85;\n      right: 0;\n    }\n  }\n}\n\n.svg {\n  box-sizing: border-box;\n  z-index: 0;\n}\n\n.canvas {\n  box-sizing: border-box;\n  cursor: grab;\n  position: absolute;\n  z-index: 1;\n}\n\n.timeline-tooltip {\n  pointer-events: none;\n  position: absolute;\n  text-overflow: initial;\n  transform: translate(-50%);\n  transition: all 150ms;\n  user-select: none;\n  z-index: 4;\n}\n</style>\n\n<style lang=\"scss\">\n// We use unscoped css here\n// so that we don't need to do a post-selection\n// on the axis\n.x-axis-group {\n  color: var(--v-utilGrayLight-base) !important;\n  font: 10px Roboto, sans-serif;\n  opacity: 0.8;\n  user-select: none;\n\n  .domain {\n    stroke: rgba(0, 0, 0, 0.12);\n    stroke-width: 1.65px;\n  }\n\n  .tick line {\n    stroke: rgba(0, 0, 0, 0.12);\n    stroke-width: 1.65px;\n  }\n\n  .tick {\n    transition: all 50ms;\n  }\n\n  .tick:first-of-type {\n    text-anchor: start;\n  }\n\n  .tick:last-of-type {\n    text-anchor: end;\n  }\n}\n\n.breakpoints-group {\n  opacity: 1;\n}\n</style>\n"
  },
  {
    "path": "src/components/WorkQueueBanner.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nexport default {\n  data() {\n    return {\n      loading: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    paused() {\n      return this.tenant?.settings?.work_queue_paused\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    ...mapActions('tenant', ['getTenants']),\n    async resumeWork() {\n      this.loading = true\n\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/resume-tenant-work-queue.gql'),\n          variables: {\n            tenantId: this.tenant.id\n          }\n        })\n\n        if (data?.tenant_work_queue_result?.success) {\n          this.getTenants()\n        }\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: e,\n          alertType: 'error'\n        })\n      } finally {\n        this.loading = false\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-snackbar\n    color=\"amber lighten-5\"\n    :value=\"paused\"\n    app\n    rounded\n    bottom\n    content-class=\"py-1\"\n    elevation=\"24\"\n    :timeout=\"-1\"\n  >\n    <div class=\"d-flex align-center justify-start\">\n      <v-avatar rounded>\n        <div class=\"banner-icon\">\n          <i class=\"fad fa-list-ul\" />\n        </div>\n      </v-avatar>\n\n      <span class=\"utilGrayDark--text text-body-1 ml-3\">\n        Work is paused - no runs will be released to your agents.\n      </span>\n\n      <v-spacer />\n\n      <v-btn\n        class=\"ml-4\"\n        text\n        depressed\n        color=\"primary\"\n        :loading=\"loading\"\n        @click=\"resumeWork\"\n      >\n        Resume work\n      </v-btn>\n    </div>\n  </v-snackbar>\n</template>\n\n<style lang=\"scss\">\n.v-avatar {\n  border-radius: 0 !important;\n}\n</style>\n"
  },
  {
    "path": "src/directives/disable-read-only.js",
    "content": "import store from '@/store'\n\nexport const insertedActions = (el, binding) => {\n  //checks again after all data loads (for component level disabling)\n  const readOnly = store.getters['tenant/role'] === 'READ_ONLY_USER'\n  if (readOnly || binding.value) {\n    if (el.classList.contains('blue')) {\n      el.classList.remove('blue')\n      el.classList.remove('white--text')\n      el.classList.add('needBlue')\n    }\n    if (el.classList.contains('primary')) {\n      el.classList.remove('primary')\n      el.classList.add('needPrimary')\n    }\n    if (el.style.color === 'primary') {\n      el.classList.add('needPrimary')\n    }\n    el.disabled = true\n    el.style.color = 'grey'\n    el.style.backgroundColor = 'lightgrey'\n    el.style.boxShadow = 'none'\n  }\n}\n\nexport const updatedActions = (el, binding) => {\n  //checks again after all data loads (for component level disabling)\n  const readOnly = store.getters['tenant/role'] === 'READ_ONLY_USER'\n  if (readOnly || binding.value) {\n    if (el.classList.contains('blue')) {\n      el.classList.remove('blue')\n      el.classList.remove('white--text')\n      el.classList.add('needBlue')\n    }\n    if (el.classList.contains('primary')) {\n      el.classList.remove('primary')\n      el.classList.add('needPrimary')\n    }\n    if (el.style.color === 'primary') {\n      el.classList.add('needPrimary')\n    }\n    el.disabled = true\n    el.style.color = 'grey'\n  } else {\n    //set back if new data (in component) means button should not be disabled\n    el.disabled = false\n    if (el.classList.contains('needBlue')) {\n      el.classList.remove('needBlue')\n      el.classList.add('blue')\n      el.classList.add('white--text')\n    } else if (el.classList.contains('needPrimary' || 'primary')) {\n      el.classList.remove('needPrimary')\n      el.classList.add('primary')\n      el.classList.add('white--text')\n    } else {\n      el.style.color = 'black'\n    }\n  }\n}\n"
  },
  {
    "path": "src/filters/duration.js",
    "content": "import { durationToEnglish } from '@/utils/dateTime'\n\nexport default function(duration) {\n  return durationToEnglish(duration)\n}\n"
  },
  {
    "path": "src/filters/filterOnePercent.js",
    "content": "export default function(x) {\n  return x < 1 ? '< 1' : x\n}\n"
  },
  {
    "path": "src/filters/round.js",
    "content": "import round from 'lodash/round'\n\nexport function roundWhole(x) {\n  if (!x || typeof x !== 'number') {\n    // eslint-disable-next-line no-console\n    console.warn(\n      `Value ${x} is a ${typeof x}, roundWhole filter requires a number instead.`\n    )\n    return x\n  }\n\n  return round(x)\n}\n\nexport function roundTenths(x) {\n  if (!x || typeof x !== 'number') {\n    // eslint-disable-next-line no-console\n    console.warn(\n      `Value ${x} is a ${typeof x}, roundTenths filter requires a number instead.`\n    )\n    return x\n  }\n\n  return round(x, 1)\n}\n\nexport function roundHundredths(x) {\n  if (!x || typeof x !== 'number') {\n    // eslint-disable-next-line no-console\n    console.warn(\n      `Value ${x} is a ${typeof x}, roundHundredths filter requires a number instead.`\n    )\n    return x\n  }\n\n  return round(x, 2)\n}\n\nexport function roundThousandths(x) {\n  if (!x || typeof x !== 'number') {\n    // eslint-disable-next-line no-console\n    console.warn(\n      `Value ${x} is a ${typeof x}, roundThousandths filter requires a number instead.`\n    )\n    return x\n  }\n\n  return round(x, 3)\n}\n\nexport function roundTens(x) {\n  if (!x || typeof x !== 'number') {\n    // eslint-disable-next-line no-console\n    console.warn(\n      `Value ${x} is a ${typeof x}, roundTens filter requires a number instead.`\n    )\n    return x\n  }\n\n  return round(x, -1)\n}\n\nexport function roundHundreds(x) {\n  if (!x || typeof x !== 'number') {\n    // eslint-disable-next-line no-console\n    console.warn(\n      `Value ${x} is a ${typeof x}, roundHundreds filter requires a number instead.`\n    )\n    return x\n  }\n\n  return round(x, -2)\n}\n\nexport function roundThousands(x) {\n  if (!x || typeof x !== 'number') {\n    // eslint-disable-next-line no-console\n    console.warn(\n      `Value ${x} is a ${typeof x}, roundThousands filter requires a number instead.`\n    )\n    return x\n  }\n\n  return round(x, 3)\n}\n"
  },
  {
    "path": "src/filters/shorten.js",
    "content": "export default function(string, numberOfCharacters = 8, startingIndex = 0) {\n  if (!(typeof string === 'string') || !string) {\n    return ''\n  }\n  return string.substring(startingIndex, startingIndex + numberOfCharacters)\n}\n"
  },
  {
    "path": "src/graphql/Account/invitations.gql",
    "content": "query AccountMembershipInvitations {\n  membership_invitation {\n    id\n    created\n    email\n    role\n  }\n}\n"
  },
  {
    "path": "src/graphql/Account/license-users.gql",
    "content": "query LicenseUsers {\n  license_users {\n    id\n    first_name\n    last_name\n    username\n    email\n\n    memberships {\n      tenant_id\n      membership_id\n      role_id\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Agent/FlowRuns.gql",
    "content": "query AgentSubmittableRuns {\n    flow_run (where: {state: {_eq: \"Scheduled\"}}) {\n        id\n        name\n        state\n        labels\n        scheduled_start_time\n        version\n        flow_id\n        flow {\n            id\n            name\n        }\n    }\n}"
  },
  {
    "path": "src/graphql/Agent/agent-hooks.gql",
    "content": "query AgentHooks{\n  hook (where: {event_type: {_eq: \"AgentSLAFailedEvent\"}}){\n    event_tags \n      action {\n        id\n        name\n        action_type\n      }\n    event_type\n    \n  }\n}"
  },
  {
    "path": "src/graphql/Agent/agents.js",
    "content": "import gql from 'graphql-tag'\n\nexport default function(isCloud) {\n  return gql`\n  query Agents {\n    agent {\n      id\n      agent_config_id\n      core_version\n      created\n      name\n      labels\n      last_queried\n      type\n      ${\n          isCloud\n            ? `\n            token_name\n            token_id`\n            : ''\n        }\n    }\n  }`\n}\n"
  },
  {
    "path": "src/graphql/Agent/delete-agent.gql",
    "content": "mutation DeleteAgent($agentId: UUID!) {\n  delete_agent(input: { agent_id: $agentId }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Agent/in-progress-flow-runs.gql",
    "content": "query InProgressFlowRuns($agentId: uuid) {\n  flow_run(\n    where: {\n      agent_id: { _eq: $agentId },\n      state: { _in: [\"Running\", \"Submitted\", \"Cancelling\"] }\n    }\n    order_by: { start_time: desc }\n  ) {\n    id\n    name\n    start_time\n    state\n    state_timestamp\n\n    flow {\n      id\n      name\n\n      flow_group_id\n    }\n\n    updated\n  }\n}\n"
  },
  {
    "path": "src/graphql/Agent/recent-runs.gql",
    "content": "query RecentRuns($agentId: uuid, $day: timestamptz) {\n  flow_run(\n     where: { \n      _and: [\n    {state: { _neq: \"Scheduled\" }},\n    {agent_id: { _eq: $agentId}},\n      ],\n      _or:[\n    {scheduled_start_time:{ _gt: $day}},   \n    {start_time: { _gt: $day}}\n      ]\n    }\n    order_by: { start_time: desc_nulls_last }\n    limit: 10\n  ) {\n    id\n    name\n    end_time\n    flow_id\n    start_time\n    state\n    agent_id\n  }\n}"
  },
  {
    "path": "src/graphql/Agent/table-flow-runs-count.gql",
    "content": "query TableFlowRunsCount(\n \n  $agent_id: uuid\n  $name: String\n  $state: [String!]\n) {\n  flow_run_aggregate(\n    where: {\n      agent_id: {_eq: $agent_id}\n      name: { _ilike: $name }\n      state: { _in: $state, _neq: \"Scheduled\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Agent/table-flow-runs.gql",
    "content": "query TableFlowRuns(\n  $name: String\n  $limit: Int\n  $offset: Int\n  $orderBy: [flow_run_order_by!]\n  $agent_id: uuid\n  $state: [String!]\n) {\n  flow_run(\n    where: {\n      agent_id: {_eq: $agent_id}\n      name: { _ilike: $name }\n      state: { _in: $state, _neq: \"Scheduled\" }\n    }\n    order_by: $orderBy\n    limit: $limit\n    offset: $offset\n  ) {\n    id\n    name\n    end_time\n    scheduled_start_time\n    start_time\n    state\n    flow {\n      name\n      id\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Agent/timeline-flow-runs.gql",
    "content": "query AgentTimelineFlowRuns($agent_id: uuid) {\n  flow_run(\n    where: {\n       agent_id: { _eq: $agent_id } \n    }\n    limit: 100\n    order_by: { scheduled_start_time: desc }\n  ) {\n    id\n    name\n    flow_id\n    end_time\n    start_time\n    scheduled_start_time\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/Artifacts/task-run-artifacts-aggregate.gql",
    "content": "query TaskRunArtifacts($taskRunIds: [uuid!]) {\n  task_run_artifact_aggregate(where: { task_run_id: { _in: $taskRunIds } }) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Artifacts/task-run-artifacts.gql",
    "content": "query TaskRunArtifacts($taskRunIds: [uuid!]) {\n  task_run_artifact(where: { task_run_id: { _in: $taskRunIds } }) {\n    id\n    created\n    data\n    kind\n\n    task_run {\n      id\n      name\n      state\n\n      task {\n        id\n        name\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Artifacts/task-run-ids.gql",
    "content": "query TaskRunIds($where: task_run_bool_exp!, $limit: Int, $offset: Int) {\n  task_run(where: $where, limit: $limit, offset: $offset) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Automations/actions.gql",
    "content": "query Actions \n {action {\n  id\n  name\n  action_type\n  action_config\n}}"
  },
  {
    "path": "src/graphql/Automations/agent-config-by-pk.gql",
    "content": "query AgentConfig($agentConfigId: uuid!) {\n  agent_config_by_pk(id: $agentConfigId) {\n    id\n    name\n\n    agents {\n      id\n      type\n      name\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Automations/agent-config.gql",
    "content": "query AgentConfig {\n  agent_config {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/Automations/delete-agent-config.gql",
    "content": "mutation deleteAgentConfig($agentConfigInput: delete_agent_config_input!){\n  delete_agent_config(\n    input: $agentConfigInput\n  ) {\n    error\n    success\n  }\n}"
  },
  {
    "path": "src/graphql/Automations/flow-config-by-pk.gql",
    "content": "query FlowSLAConfig($flowSLAConfigId: uuid!) {\n  flow_sla_config_by_pk(id: $flowSLAConfigId) {\n    flow_groups {\n      id\n      flow_group_id\n    }\n    kind\n    duration_seconds\n  }\n}\n"
  },
  {
    "path": "src/graphql/Automations/flow-only-hooks.gql",
    "content": "query Actions {\n  hook(where: { event_type: { _neq: \"AgentSLAFailedEvent\" } }) {\n    id\n    event_tags\n    created\n    event_type\n    __typename\n    action {\n      name\n      id\n      action_config\n      action_type\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Automations/flows.gql",
    "content": "query ActionFlows ($project: uuid, $flowGroupIds: [uuid!]) {\n  flow(distinct_on: flow_group_id, where: {_and: [{project_id: {_eq: $project}, archived: {_eq: false}, flow_group_id: {_in: $flowGroupIds}}]}) {\n    id\n    archived\n    name\n    flow_group_id\n    version_group_id\n    project {\n      name\n      id\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Automations/hooks.gql",
    "content": "query Actions {\n  hook{\n    id\n    event_tags\n    created\n    event_type\n    __typename\n    action {\n      name\n      id\n      action_config\n      action_type\n    }\n  }\n}"
  },
  {
    "path": "src/graphql/Calendar/calendar-day-flow-runs.gql",
    "content": "query CalendarDayFlowRuns($startTime: timestamptz, $endTime: timestamptz, $flowId: uuid!) {\n  flow_run (\n    where: { \n      _and: [\n    {flow_id: { _eq: $flowId}},\n    {start_time: { _gt: $startTime}}, \n    {start_time: { _lt: $endTime}}\n      ]\n    }\n  ) \n  {\n    id\n    flow_id\n    name\n    end_time\n    start_time\n    scheduled_start_time\n    state\n    state_message\n  }\n}"
  },
  {
    "path": "src/graphql/Calendar/calendar-day-ongoing-flow-runs.gql",
    "content": "query CalendarDayOngoingFlowRuns($flowId: uuid!, $startTime:timestamptz, $endTime: timestamptz) {\n  flow_run (\n    where: { \n      _and: [\n    {flow_id: { _eq: $flowId}},\n    {start_time: {_lt: $startTime}}\n    {end_time: {_gt: $endTime}}\n      ]\n    }\n  ) \n  {\n    id\n    flow_id\n    name\n    end_time\n    start_time\n    scheduled_start_time\n    state\n    state_message\n  }\n}"
  },
  {
    "path": "src/graphql/Calendar/calendar-day-running-flow-runs.gql",
    "content": "query CalendarDayRunningFlowRuns($flowId: uuid!, $startTime:timestamptz) {\n  flow_run (\n    where: { \n      _and: [\n    {flow_id: { _eq: $flowId}},\n    {state: { _eq: \"Running\"}},\n    {start_time: {_lt: $startTime}}\n      ]\n    }\n  ) \n  {\n    id\n    flow_id\n    name\n    end_time\n    start_time\n    scheduled_start_time\n    state\n    state_message\n  }\n}"
  },
  {
    "path": "src/graphql/Calendar/calendar-day-scheduled-flow-runs.gql",
    "content": "query CalendarDayScheduledFlowRuns($startTime: timestamptz, $endTime: timestamptz, $flowId: uuid!) {\n  flow_run (\n    where: { \n      _and: [\n    {scheduled_start_time: { _gt: $startTime}}, \n    {scheduled_start_time: { _lt: $endTime}},\n    {start_time: {_is_null: true}},\n    {flow_id: { _eq: $flowId}}\n    ]\n    }\n  ) \n  {\n    id\n    flow_id\n    name\n    end_time\n    start_time\n    scheduled_start_time\n    state\n    state_message\n  }\n}"
  },
  {
    "path": "src/graphql/Calendar/calendar-flow-groups.gql",
    "content": "query flowGroups {\n    flow_group {\n        id\n        name\n        flows (where: {archived: {_eq: false}}) {\n            name\n            id\n            version\n        }\n    }\n}"
  },
  {
    "path": "src/graphql/Calendar/calendar-flow-runs.gql",
    "content": "query CalendarFlowRuns($startTime: timestamptz, $endTime: timestamptz) {\n  flow_run (\n    where: { \n      _and: [\n    {start_time: { _gt: $startTime}}, \n    {start_time: { _lt: $endTime}}\n      ]\n    }\n  ) \n  {\n    id\n    flow_id\n  }\n}"
  },
  {
    "path": "src/graphql/Calendar/calendar-flows.gql",
    "content": "query CalendarFlow( $id: uuid!) {\n  flow_by_pk(id: $id) \n    {\n    id\n    name\n    is_schedule_active\n  }\n}\n"
  },
  {
    "path": "src/graphql/Calendar/calendar-ongoing-flow-runs.gql",
    "content": "query CalendarOngoingFlowRuns($startTime:timestamptz, $endTime: timestamptz) {\n  flow_run (\n    where: { \n      _and: [\n    {start_time: {_lt: $startTime}}\n    {end_time: {_gte: $endTime}}\n      ]\n    }\n    distinct_on: flow_id\n    limit: 1\n  ) \n  {\n    id\n    flow_id\n  }\n}"
  },
  {
    "path": "src/graphql/Calendar/calendar-running-flow-runs.gql",
    "content": "query CalendarRunningFlowRuns($startTime:timestamptz) {\n  flow_run (\n    where: { \n      _and: [\n    {state: { _eq: \"Running\"}},\n    {start_time: {_lt: $startTime}}\n      ]\n    }\n    limit: 1\n    distinct_on: flow_id\n  ) \n  {\n    id\n    flow_id\n  }\n}"
  },
  {
    "path": "src/graphql/Calendar/calendar-scheduled-flow-runs.gql",
    "content": "query CalendarScheduledFlowRuns($startTime: timestamptz, $endTime: timestamptz) {\n  flow_run (\n    where: { \n      _and: [\n    {scheduled_start_time: { _gt: $startTime}}, \n    {scheduled_start_time: { _lt: $endTime}},\n    {start_time: {_is_null: true}},\n    ]\n    }\n  ) \n  {\n    id\n    flow_id\n  }\n}"
  },
  {
    "path": "src/graphql/Dashboard/committed-usage.gql",
    "content": "query Usage($license_id: uuid) {\n  usage: billing_usage(where: { license_id: { _eq: $license_id } }) {\n    id\n    kind\n    runs\n    tenant_id\n    timestamp\n    usage_last_updated\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/failures-count.gql",
    "content": "query FailureCount($heartbeat: timestamptz, $projectId: uuid) {\n  flow_aggregate(\n    where: {\n      flow_runs: { state: { _eq: \"Failed\" }, updated: { _gte: $heartbeat } }\n      project_id: { _eq: $projectId }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/failures-drawer.gql",
    "content": "query FailDetails($heartbeat: timestamptz, $projectIds: [uuid!]) {\n  flow_run(\n    where: {\n      state: { _eq: \"Failed\" }\n      updated: { _gte: $heartbeat }\n      flow: { project_id: { _in: $projectIds } }\n    }\n    distinct_on: flow_id\n    order_by: [{ flow_id: asc }, { updated: desc }]\n  ) {\n    id\n    name\n    scheduled_start_time\n    start_time\n    end_time\n    flow {\n      id\n      name\n      failed_runs_count: flow_runs_aggregate(\n        where: { state: { _eq: \"Failed\" }, updated: { _gte: $heartbeat } }\n      ) {\n        aggregate {\n          count\n        }\n      }\n      runs_count: flow_runs_aggregate(\n        where: { updated: { _gte: $heartbeat } }\n      ) {\n        aggregate {\n          count\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/flow-count.gql",
    "content": "query FlowCount($searchParams: flow_bool_exp) {\n  flowCount: flow_aggregate(where: $searchParams) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/flow-failures.gql",
    "content": "query FlowFailures($projectId: uuid, $heartbeat: timestamptz, $tenantId: uuid) {\n  flow_run(\n    where: {\n      tenant_id: { _eq: $tenantId }\n      flow: { project_id: { _eq: $projectId } }\n      state: { _eq: \"Failed\" }\n      scheduled_start_time: { _gte: $heartbeat }\n    }\n    distinct_on: flow_id\n    order_by: { flow_id: asc, scheduled_start_time: desc }\n  ) {\n    flow_id\n    state_timestamp\n\n    flow {\n      id\n      name\n      flow_group_id\n    }\n\n    scheduled_start_time\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/flow-run-drawer.gql",
    "content": "query FlowRun($id: uuid!) {\n  flow_run_by_pk(id: $id) {\n    id\n    name\n    state\n    context\n    auto_scheduled\n    state_message\n    created_by {\n      username\n    }\n    start_time\n    end_time\n    flow {\n      id\n      name\n      version\n    }\n    parameters\n    scheduled_start_time\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/flow-runs-count.gql",
    "content": "query FlowRunsCount($projectIds: [uuid!], $heartbeat: timestamptz) {\n  flow_run_aggregate(\n    where: {\n      flow: { project_id: { _in: $projectIds } }\n      updated: { _gte: $heartbeat }\n      state: { _neq: \"Scheduled\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/flow-runs.gql",
    "content": "query FlowRuns($projectId: uuid, $heartbeat: timestamptz) {\n  Success: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Success\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Running: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Running\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Pending: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Pending\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Failed: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Failed\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  ClientFailed: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"ClientFailed\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Submitted: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Submitted\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Queued: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Queued\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Resume: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Resume\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Retrying: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Retrying\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Looped: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Looped\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Cached: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Cached\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Mapped: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Mapped\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  TimedOut: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"TimedOut\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  TriggerFailed: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"TriggerFailed\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Skipped: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Skipped\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Finished: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Finished\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Cancelled: flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      scheduled_start_time: { _gte: $heartbeat }\n      state: { _eq: \"Cancelled\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/flows.js",
    "content": "import gql from 'graphql-tag'\n\nexport default function(isCloud) {\n  return gql`\n    query Flows(\n      $limit: Int\n      $offset: Int\n      $orderBy: [flow_order_by!]\n      $searchParams: flow_bool_exp\n    ) {\n    flow(\n        where: $searchParams\n        limit: $limit\n        offset: $offset\n        order_by: $orderBy\n      ) {\n\n      id\n      flow_group_id\n      archived\n      core_version\n      created\n\n      ${\n        isCloud\n          ? `\n          created_by {\n            id\n            username\n          }`\n          : ''\n      }\n\n      description\n      environment\n\n      flow_group {\n        id\n        created\n        name\n        schedule\n      }\n\n      is_schedule_active\n\n      name\n      parameters\n\n      project {\n        id\n        name\n      }\n\n      schedule\n\n      storage\n\n      updated\n      version\n      version_group_id\n      }\n    }\n`\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/heartbeat.gql",
    "content": "query Heartbeat($projectId: uuid, $timestamp: timestamptz, $state: String, $filterOutStates: [String!]) {\n  flow_run(\n    limit: 10\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      state_timestamp: { _gte: $timestamp }\n      state: { _eq: $state, _nin: $filterOutStates }\n    }\n    order_by: { updated: desc_nulls_last }\n  ) {\n    id\n    name\n    scheduled_start_time\n    state\n    state_timestamp\n    flow {\n      id\n      name\n    }\n    __typename\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/in-progress-flow-runs.gql",
    "content": "query InProgressFlowRuns($projectId: uuid) {\n  flow_run(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      state: { _in: [\"Running\", \"Submitted\", \"Cancelling\"] }\n    }\n    order_by: { start_time: desc }\n  ) {\n    id\n    name\n    start_time\n    state\n    state_timestamp\n\n    flow {\n      id\n      name\n\n      flow_group_id\n    }\n\n    updated\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/invoice.gql",
    "content": "query Invoice($licenseId: UUID!) {\n  preview_invoice(license_id: $licenseId)\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/last-flow-runs.gql",
    "content": "query LastFlowRuns($flowId: uuid) {\n  flow_run(\n    where: { flow_id: { _eq: $flowId }, state: { _neq: \"Scheduled\" } }\n    order_by: { start_time: desc_nulls_last }\n    limit: 10\n  ) {\n    id\n    end_time\n    flow_id\n    start_time\n    state\n   \n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/project-name.gql",
    "content": "query Project($id: uuid!) {\n  project: project_by_pk(id: $id) {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/project.gql",
    "content": "query Project($id: uuid!) {\n  project: project_by_pk(id: $id) {\n    id\n    name\n    description\n    created\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/projects.gql",
    "content": "query Projects {\n  project {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/task-failures.gql",
    "content": "query FailedTasks($heartbeat: timestamptz) {\n  task_run(\n    where: { state: { _eq: \"Failed\" }, updated: { _gte: $heartbeat } }\n    distinct_on: task_id\n  ) {\n    id\n    updated\n    task {\n      id\n      name\n      flow {\n        name\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/timeline-flow-runs.gql",
    "content": "query TimelineFlowRuns($limit: Int, $project_id: uuid, $date: timestamptz) {\n  flow_run(\n    where: {\n      flow: { project_id: { _eq: $project_id } }\n      state: { _neq: \"Scheduled\" }\n      scheduled_start_time: { _gte: $date }\n    }\n    limit: $limit\n    order_by: { scheduled_start_time: desc }\n  ) {\n    id\n    flow_id\n    name\n    end_time\n    start_time\n    scheduled_start_time\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/timeline-flow.gql",
    "content": "query TimelineFlow($flowId: uuid!) {\n  flow_by_pk(id: $flowId) {\n    id\n    name\n    project {\n      name\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/timeline-scheduled-flow-runs.gql",
    "content": "query TimelineFlowRuns($project_id: uuid) {\n  flow_run(\n    where: {\n      flow: { project_id: { _eq: $project_id } }\n      state: { _eq: \"Scheduled\" }\n    }\n    limit: 10\n    order_by: { scheduled_start_time: asc_nulls_last }\n  ) {\n    id\n    flow_id\n    name\n    end_time\n    start_time\n    scheduled_start_time\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/upcoming-flow-runs-count.gql",
    "content": "query UpcomingFlowRunsCount($projectId: uuid) {\n  flow_run_aggregate(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      state: { _eq: \"Scheduled\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/upcoming-flow-runs.gql",
    "content": "query UpcomingFlowRuns($projectId: uuid) {\n  flow_run(\n    where: {\n      flow: { project_id: { _eq: $projectId } }\n      state: { _eq: \"Scheduled\" }\n    }\n    order_by: [{ scheduled_start_time: asc }, { flow: { name: asc } }]\n  ) {\n    id\n    name\n    state\n    labels\n    scheduled_start_time\n    version\n    flow {\n      id\n      name\n      schedule\n      environment\n      is_schedule_active\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Dashboard/usage.gql",
    "content": "query Usage($from: timestamptz, $to: timestamptz, $license_id: uuid) {\n  usage: billing_usage(\n    where: {\n      timestamp: { _gte: $from, _lte: $to }\n      license_id: { _eq: $license_id }\n    }\n  ) {\n    id\n    kind\n    runs\n    license_id\n    timestamp\n    usage_last_updated\n  }\n}\n"
  },
  {
    "path": "src/graphql/FirstRunWorkflow/flow-run.gql",
    "content": "query FlowRun(\n  $id: uuid!\n  $logId: uuid\n  $levels: [String!]\n  $limit: Int = 100\n  $offset: Int = 0\n  $searchText: String\n  $timestampFrom: timestamptz\n  $timestampTo: timestamptz\n) {\n  flow_run_by_pk(id: $id) {\n    id\n    end_time\n    name\n    scheduled_start_time\n    state\n    start_time\n    logs(\n      limit: $limit\n      offset: $offset\n      order_by: { timestamp: desc }\n      where: {\n        id: { _eq: $logId }\n        level: { _in: $levels }\n        message: { _ilike: $searchText }\n        timestamp: { _gte: $timestampFrom, _lte: $timestampTo }\n      }\n    ) {\n      id\n      level\n      message\n      name\n      timestamp\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/FirstRunWorkflow/project-names.gql",
    "content": "query {\n  project {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/cloud-hooks.gql",
    "content": "query CloudHooks($id: String) {\n  cloud_hook(where: { version_group_id: { _eq: $id } }) {\n    id\n    active\n    config\n    created\n    name\n    states\n    type\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/errors.gql",
    "content": "query Errors(\n  $updated: timestamptz_comparison_exp\n  $flow_group_id: uuid\n  $flow_id: uuid\n) {\n  flow_run(\n    where: {\n      updated: $updated\n      flow: { id: { _eq: $flow_id }, flow_group_id: { _eq: $flow_group_id } }\n    }\n    limit: 50\n    order_by: [{ updated: desc }]\n  ) {\n    id\n    name\n    task_runs(where: { state: { _eq: \"Failed\" } }){\n        task{\n            id\n            name\n        }\n        id\n        state_message\n        state_timestamp\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/flow-by-pk.gql",
    "content": "query FlowByPk($flowId: uuid!) {\n  flow_by_pk(id: $flowId) {\n    id\n    name\n    version\n    schedule\n    flow_group_id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/flow-drawer.gql",
    "content": "query Flow($id: uuid!) {\n  flow_by_pk(id: $id) {\n    id\n    name\n    description\n    created\n    created_by {\n      username\n    }\n    archived\n    storage\n    environment\n    parameters\n    version\n    schedules {\n      id\n      active\n      schedule\n      schedule_start\n      schedule_end\n    }\n    project {\n      id\n      name\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/flow-run-by-pk.gql",
    "content": "query FlowRunByPK($id: uuid!) {\n  flow_run_by_pk(id: $id) {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/flow-runs.gql",
    "content": "query FlowRuns($flow_group_id: uuid, $flow_id: uuid, $heartbeat: timestamptz) {\n  Success: flow_run_aggregate(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n      updated: { _gte: $heartbeat }\n      state: { _eq: \"Success\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Failed: flow_run_aggregate(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n      updated: { _gte: $heartbeat }\n      state: { _eq: \"Failed\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Submitted: flow_run_aggregate(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n      updated: { _gte: $heartbeat }\n      state: { _eq: \"Submitted\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Paused: flow_run_aggregate(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n      updated: { _gte: $heartbeat }\n      state: { _eq: \"Paused\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Resume: flow_run_aggregate(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n      updated: { _gte: $heartbeat }\n      state: { _eq: \"Resume\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Running: flow_run_aggregate(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n      updated: { _gte: $heartbeat }\n      state: { _eq: \"Running\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Cancelled: flow_run_aggregate(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n      updated: { _gte: $heartbeat }\n      state: { _eq: \"Cancelled\" }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/flow-versions-count.gql",
    "content": "query VersionsCount($flow_group_id: uuid!, $search: Int) {\n  flow_group_by_pk(id: $flow_group_id) {\n    id\n\n    flows_aggregate(where: { version: { _eq: $search } }) {\n      aggregate {\n        count\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/flow-versions-runs.gql",
    "content": "query VersionsRuns($flow_ids: [uuid!]) {\n  flow(where: { id: { _in: $flow_ids } }) {\n    id\n    name\n    version\n\n    flow_runs(\n      where: {\n        _and: [{ state: { _neq: \"Scheduled\" } }, { state: { _neq: \"Running\" } }]\n      }\n      order_by: { updated: desc }\n      limit: 10\n    ) {\n      id\n      name\n      start_time\n      end_time\n      state\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/flow-versions.js",
    "content": "import gql from 'graphql-tag'\n\nexport default function(isCloud) {\n  return gql`\n    query Versions(\n      $limit: Int\n      $offset: Int\n      $order_by: [flow_order_by!]\n      $flow_group_id: uuid!\n      $search: Int\n    ) {\n      flow_group_by_pk(id: $flow_group_id) {\n        id\n\n        flows(\n          order_by: $order_by\n          where: { version: { _eq: $search } }\n          limit: $limit\n          offset: $offset\n        ) {\n          id\n\n          archived\n          created\n          ${\n            isCloud\n              ? `\n                  created_by {\n            id\n            username\n          }\n          `\n              : ''\n          }\n\n\n\n          name\n          version\n        }\n      }\n    }\n   \n  `\n}\n"
  },
  {
    "path": "src/graphql/Flow/flow.js",
    "content": "import gql from 'graphql-tag'\n\nexport default function(isCloud) {\n  return gql`\n    query Flow($id: uuid!) {\n      flow_group_by_pk(id: $id) {\n        id\n        labels\n        created\n        description\n        name\n        default_parameters\n        schedule\n        \n        flows {\n          id\n\n          archived\n          core_version\n          created\n\n          ${\n            isCloud\n              ? `\n              created_by {\n                id\n                username\n              }`\n              : ''\n          }\n\n          description\n          run_config\n          environment\n          flow_group_id\n          is_schedule_active\n\n          name\n          parameters\n\n          project {\n            id\n            name\n          }\n\n          schedule\n\n          storage\n\n          updated\n          version\n          version_group_id\n        }\n\n        settings\n        updated\n      }\n    }\n`\n}\n"
  },
  {
    "path": "src/graphql/Flow/heartbeat.gql",
    "content": "query Heartbeat($flow_group_id: uuid, $flow_id: uuid, $state: String, $filterOutStates: [String!]) {\n  flow_run(\n    limit: 10\n    where: {\n      flow: { id: { _eq: $flow_id }, flow_group_id: { _eq: $flow_group_id } }\n      state: { _eq: $state, _nin: $filterOutStates }\n    }\n    order_by: { updated: desc_nulls_last }\n  ) {\n    id\n    name\n    scheduled_start_time\n    state\n    state_message\n    state_timestamp\n    __typename\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/last-flow-run.gql",
    "content": "query LastFlowRun($id: uuid!) {\n  flow_run(\n    where: { flow_id: { _eq: $id }, state: { _neq: \"Scheduled\" } }\n    order_by: { scheduled_start_time: desc }\n    limit: 1\n  ) {\n    id\n    name\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/past-flow-runs.gql",
    "content": "query PastFlowRuns($id: uuid!, $heartbeat: timestamptz) {\n  flow_run(\n    where: {\n      flow_id: { _eq: $id }\n      updated: { _gte: $heartbeat }\n      state: { _neq: \"Scheduled\" }\n    }\n    order_by: { scheduled_start_time: desc }\n  ) {\n    id\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/project-names.gql",
    "content": "query {\n  project {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/table-flow-runs-count.gql",
    "content": "query TableFlowRunsCount(\n  $flow_group_id: uuid\n  $flow_id: uuid\n  $name: String\n  $state: [String!]\n) {\n  flow_run_aggregate(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n      name: { _ilike: $name }\n      state: { _in: $state }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/table-flow-runs.gql",
    "content": "query TableFlowRuns(\n  $name: String\n  $limit: Int\n  $offset: Int\n  $orderBy: [flow_run_order_by!]\n  $flow_group_id: uuid\n  $flow_id: uuid\n  $state: [String!]\n) {\n  flow_run(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n      name: { _ilike: $name }\n      state: { _in: $state }\n    }\n    order_by: $orderBy\n    limit: $limit\n    offset: $offset\n  ) {\n    id\n    name\n    end_time\n    scheduled_start_time\n    start_time\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/table-tasks-count.gql",
    "content": "query TableTasks(\n  $flowId: uuid\n  $name: String\n  $limit: Int\n  $offset: Int\n  $orderBy: [task_order_by!]\n) {\n  task_aggregate(\n    where: { flow_id: { _eq: $flowId }, name: { _ilike: $name } }\n    order_by: $orderBy\n    limit: $limit\n    offset: $offset\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/table-tasks.gql",
    "content": "query TableTasks(\n  $flowId: uuid\n  $name: String\n  $limit: Int\n  $offset: Int\n  $orderBy: [task_order_by!]\n) {\n  task(\n    where: { flow_id: { _eq: $flowId }, name: { _ilike: $name } }\n    order_by: $orderBy\n    limit: $limit\n    offset: $offset\n  ) {\n    id\n    name\n    max_retries\n    retry_delay\n    type\n    trigger\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/timeline-flow-runs.gql",
    "content": "query TimelineFlowRuns($flow_group_id: uuid, $flow_id: uuid) {\n  flow_run(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n    }\n    limit: 100\n    order_by: { scheduled_start_time: desc }\n  ) {\n    id\n    name\n    end_time\n    start_time\n    scheduled_start_time\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/upcoming-flow-runs.gql",
    "content": "query UpcomingFlowRuns($flow_group_id: uuid, $flow_id: uuid) {\n  flow_run(\n    where: {\n      flow: { flow_group_id: { _eq: $flow_group_id }, id: { _eq: $flow_id } }\n      state: { _eq: \"Scheduled\" }\n    }\n    order_by: { scheduled_start_time: asc }\n  ) {\n    id\n    labels\n    name\n    version\n    scheduled_start_time\n  }\n}\n"
  },
  {
    "path": "src/graphql/Flow/version-group.gql",
    "content": "query FlowsByVersionGroup($versionGroupId: String) {\n  flow(where: { version_group_id: { _eq: $versionGroupId } }) {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowLabelLimit/delete-flow-concurrency-limit.gql",
    "content": "mutation DeleteFlowConcurrencyLimit($limitId: UUID!) {\n  delete_flow_concurrency_limit(input: { limit_id: $limitId }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowLabelLimit/flow-label-limit.gql",
    "content": "query FlowLabelLimit {\n  flow_concurrency_limit {\n    id\n    limit\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowLabelLimit/update-flow-concurrency-limit.gql",
    "content": "mutation UpdateFlowConcurrencyLimit($label: String!, $limit: Int!) {\n  update_flow_concurrency_limit(input: { label: $label, limit: $limit }) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowLabelUsage/flow-label-usage.gql",
    "content": "query FlowLabelUsage($labels: [String!]) {\n  flow_concurrency(labels: $labels) {\n    label\n    usage\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/cancel-flow-run.gql",
    "content": "mutation CancelFlowRun($flowRunId: UUID!) {\n  cancel_flow_run(input: { flow_run_id: $flowRunId }) {\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/failed-task-runs.gql",
    "content": "query FailedTaskRuns($flowRunId: uuid, $failedStates: [String!]) {\n  task_run(\n    where: {\n      flow_run_id: { _eq: $flowRunId }\n      state: { _in: $failedStates }\n    }\n  ) {\n    id\n    task_id\n    version\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/flow-run.js",
    "content": "import gql from 'graphql-tag'\n\nexport default function(isCloud) {\n  return gql`\n    query FlowRun(\n      $id: uuid!\n    ) {\n      flow_run_by_pk(id: $id) {\n        id\n        name\n        version\n        labels\n        auto_scheduled\n\n        ${\n          isCloud\n            ? `\n            created_by {\n              id\n              username\n            }\n          `\n            : ''\n        }\n\n        auto_scheduled\n        context\n        end_time\n        flow_id\n        name\n        parameters\n        scheduled_start_time\n        start_time\n        state\n        state_message\n        state_timestamp\n        parameters\n        context\n        run_config\n        agent_id\n\n        states {\n          id\n          state\n          timestamp\n          start_time\n        }\n\n        flow {\n          id\n          name\n          version\n          version_group_id\n          core_version\n          parameters\n          archived\n          flow_group_id\n          project {\n            id\n            name\n          }\n        }\n      }\n    }\n  `\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/gantt-task-runs.gql",
    "content": "query GanttChart(\n  $id: uuid!\n  $taskRunStates: [String!]\n  $taskName: String\n  $sort: order_by\n  $limit: Int\n  $offset: Int\n) {\n  flow_run_by_pk(id: $id) {\n    id\n    name\n    version\n    labels\n    auto_scheduled\n\n    scheduled_start_time\n    start_time\n    end_time\n    state\n    state_message\n    state_timestamp\n    parameters\n    context\n    agent_id\n    task_run_states: task_runs(distinct_on: state) {\n      state\n    }\n    task_runs_aggregate(\n      where: {\n        state: { _in: $taskRunStates }\n        task: { name: { _ilike: $taskName }, auto_generated: { _eq: false } }\n      }\n    ) {\n      aggregate {\n        count\n      }\n    }\n    task_runs(\n      order_by: { start_time: $sort }\n      where: {\n        state: { _in: $taskRunStates }\n        task: { name: { _ilike: $taskName }, auto_generated: { _eq: false } }\n      }\n      limit: $limit\n      offset: $offset\n    ) {\n      id\n      state\n      state_message\n      state_result\n      state_timestamp\n      start_time\n      end_time\n      map_index\n      version\n      task {\n        id\n        name\n        auto_generated\n        max_retries\n        retry_delay\n      }\n      name\n    }\n    flow {\n      id\n      name\n      version\n      version_group_id\n      core_version\n      project {\n        id\n        name\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/heartbeat.gql",
    "content": "query Heartbeat($flowRunId: uuid!, $timestamp: timestamptz, $state: String) {\n  task_run(\n    limit: 10\n    where: {\n      flow_run_id: { _eq: $flowRunId }\n      state_timestamp: { _gte: $timestamp }\n      state: { _eq: $state }\n    }\n    order_by: { state_timestamp: desc_nulls_last }\n  ) {\n    id\n    map_index\n    state\n    state_message\n    state_timestamp\n    task {\n      id\n      name\n      max_retries\n    }\n    __typename\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/states-aggregate.gql",
    "content": "query FlowRunStatesAggregate($where: flow_run_state_bool_exp) {\n  flow_run_state_aggregate(where: $where) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/states.gql",
    "content": "query FlowRunStates(\n  $where: flow_run_state_bool_exp\n  $limit: Int!\n  $offset: Int!\n  $orderBy: [flow_run_state_order_by!]\n) {\n  flow_run_state(\n    where: $where\n    limit: $limit\n    order_by: $orderBy\n    offset: $offset\n  ) {\n    id\n    state\n    start_time\n    timestamp\n    result\n    message\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/table-task-runs-count.gql",
    "content": "query TableTaskRunsCount(\n  $flowRunId: uuid\n  $name: String\n  $state: [String!]\n  $heartbeat: timestamptz\n) {\n  task_run_aggregate(\n    where: {\n      flow_run_id: { _eq: $flowRunId }\n      _or: [{ task: { name: { _ilike: $name } }, state: { _in: $state } }]\n      updated: { _gte: $heartbeat }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/table-task-runs.gql",
    "content": "query TableTaskRuns(\n  $flowRunId: uuid\n  $name: String\n  $state: [String!]\n  $limit: Int\n  $offset: Int\n  $orderBy: [task_run_order_by!]\n) {\n  flow_run(where: { id: { _eq: $flowRunId } }) {\n    id\n    name\n    task_runs(\n      where: { task: { name: { _ilike: $name } }, state: { _in: $state } }\n      order_by: $orderBy\n      limit: $limit\n      offset: $offset\n    ) {\n      map_index\n      state\n      id\n      version\n      start_time\n      end_time\n\n      task {\n        id\n        name\n      }\n      name\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/task-run-drawer.gql",
    "content": "query TaskRun($id: uuid!) {\n  task_run_by_pk(id: $id) {\n    id\n    created\n    end_time\n    flow_run {\n      id\n      name\n    }\n    updated\n    map_index\n    start_time\n    state\n    state_message\n    state_result\n    task {\n      id\n      name\n      description\n      max_retries\n      retry_delay\n    }\n    version\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/task-run-ids.gql",
    "content": "query taskRunIds($flowRunId: uuid!, $parentMapIndex: Int, $childMapIndex: Int) {\n  task_run(\n    where: {\n      _and: [\n        { flow_run_id: { _eq: $flowRunId } }\n        { map_index: { _eq: $parentMapIndex } }\n        { map_index: { _gte: $childMapIndex } }\n      ]\n    }\n  ) {\n    version\n    id\n    map_index\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/task-runs-aggregate.gql",
    "content": "query TaskRunsCount($where: task_run_bool_exp) {\n  task_run_aggregate(where: $where) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/task-runs.gql",
    "content": "query TaskRuns(\n  $limit: Int!\n  $offset: Int!\n  $orderBy: [task_run_order_by!]\n  $where: task_run_bool_exp\n) {\n  task_run(where: $where, order_by: $orderBy, limit: $limit, offset: $offset) {\n    id\n    map_index\n    state\n    start_time\n    end_time\n    task {\n      id\n      name\n    }\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/timeline-chart-task-runs.gql",
    "content": "query TaskRuns($flowRunId: uuid!) {\n  task_run(\n    where: { flow_run_id: { _eq: $flowRunId }, map_index: { _eq: -1 } }\n  ) {\n    id\n    start_time\n    end_time\n    name\n    serialized_state\n    state\n    state_timestamp\n\n    states {\n      id\n      message\n      state\n      timestamp\n      start_time\n    }\n\n    task_id\n    version\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRun/timeline-chart-tasks.gql",
    "content": "query Tasks($flowId: uuid!) {\n  task(where: { flow_id: { _eq: $flowId } }) {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/FlowRunLogs/flow-run-metadata.gql",
    "content": "query FlowRunMetadata($id: uuid!) {\n  flow_run_by_pk(id: $id) {\n    id\n    name\n    flow {\n      id\n      name\n      project {\n        id\n        name\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/GlobalSearch/search-by-id.gql",
    "content": "query GlobalSearchByID($id: uuid!) {\n  flow(where:{ _or: [{ id: { _eq: $id } }, {flow_group_id: {_eq: $id}}]}) {\n    id: flow_group_id\n    flow_id: id\n    name\n    project {\n      id\n      name\n    }\n  }\n  flow_run(where: { id: { _eq: $id } }) {\n    id\n    name\n    flow {\n      id\n      name\n      project {\n        id\n        name\n      }\n    }\n  }\n  project(where: { id: { _eq: $id } }) {\n    id\n    name\n  }\n  task(where: { id: { _eq: $id } }) {\n    id\n    name\n    flow {\n      id\n      name\n      project {\n        id\n        name\n      }\n    }\n  }\n  task_run(where: { id: { _eq: $id } }) {\n    id\n    name\n    task {\n      id\n      name\n      flow {\n        id\n        name\n        project {\n          id\n          name\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/GlobalSearch/search-by-name.gql",
    "content": "query GlobalSearchByName($name: String) {\n  flow(where: { name: { _ilike: $name }, archived: { _eq: false } }, limit: 5) {\n    id: flow_group_id\n    name\n    project {\n      id\n      name\n    }\n    __typename\n  }\n  flow_run(\n    where: { name: { _ilike: $name }, flow: { archived: { _eq: false } } }\n    limit: 5\n  ) {\n    id\n    name\n    flow {\n      id\n      name\n      project {\n        id\n        name\n      }\n    }\n    __typename\n  }\n  project(where: { name: { _ilike: $name } }, limit: 5) {\n    id\n    name\n  }\n  task(\n    where: { name: { _ilike: $name }, flow: { archived: { _eq: false } } }\n    limit: 5\n  ) {\n    id\n    name\n    flow {\n      id\n      name\n      project {\n        id\n        name\n      }\n    }\n    __typename\n  }\n  task_run(\n    where: { name: { _ilike: $name } }\n    limit: 5\n  ) {\n    id\n    name\n    __typename\n  }\n}\n"
  },
  {
    "path": "src/graphql/Integrations/PagerDutyActions.gql",
    "content": "query pagerdutyactions ($includeIds: [uuid!]) {\n   actions: action (where: {id: {_in: $includeIds}}) {\n    action_type\n    action_config\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/KV/delete-key-value.gql",
    "content": "mutation DeleteKV($id: UUID!) {\n  delete_key_value(input: { key_value_id: $id }) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/KV/get-key-value.gql",
    "content": "query {\n  key_value {\n    key\n    value\n    updated\n    created\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/KV/set-key-value.gql",
    "content": "mutation SetKV($key: String!, $value: JSON!) {\n  set_key_value(input: { key: $key, value: $value }) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/License/create-self-serve-license.gql",
    "content": "mutation CreateSelfServeLicense(\n  $input: create_self_serve_cloud_license_input!\n) {\n  create_self_serve_cloud_license(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/License/create-usage-based-license.gql",
    "content": "mutation CreateUsageBasedLicense(\n  $input: create_self_serve_usage_license_input!\n) {\n  create_self_serve_usage_license(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/License/license.gql",
    "content": "query License {\n  auth_info {\n    license\n    permissions\n    role_id\n  }\n}\n"
  },
  {
    "path": "src/graphql/License/update-customer.gql",
    "content": "mutation updateCustomer($email: String!, $source: String, $name: String) {\n  update_stripe_customer(input: { email: $email, source: $source, name: $name}) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/License/update-self-serve-cloud-license.gql",
    "content": "mutation updateLicense ($license_id: String!, $confirm: Boolean!, $users: Int  ) {\n  update_self_serve_cloud_license(input: {license_id: $license_id, confirm: $confirm, users: $users}){\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/License/update-stripe-customer.gql",
    "content": "mutation UpdateStripeCustomer($input: update_stripe_customer_input!) {\n  update_stripe_customer(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Logs/flow-run-logs-scoping.gql",
    "content": "query FlowRunLogsScoping(\n  $id: uuid!\n  $limit: Int = 50\n  $timestamp: timestamptz\n) {\n  flow_run_by_pk(id: $id) {\n    id\n    logs_after: logs(\n      where: { timestamp: { _gte: $timestamp } }\n      order_by: { timestamp: asc }\n      limit: $limit\n    ) {\n      timestamp\n    }\n    logs_before: logs(\n      where: { timestamp: { _lte: $timestamp } }\n      order_by: { timestamp: desc }\n      limit: $limit\n    ) {\n      timestamp\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Logs/flow-run-logs.gql",
    "content": "query FlowRunLogs(\n  $id: uuid!\n  $logId: uuid\n  $levels: [String!]\n  $limit: Int = 100\n  $offset: Int = 0\n  $searchText: String\n  $timestampFrom: timestamptz\n  $timestampTo: timestamptz\n) {\n  flow_run_by_pk(id: $id) {\n    id\n    state\n    start_time\n    logs(\n      limit: $limit\n      offset: $offset\n      order_by: { timestamp: desc }\n      where: {\n        id: { _eq: $logId }\n        level: { _in: $levels }\n        message: { _ilike: $searchText }\n        timestamp: { _gte: $timestampFrom, _lte: $timestampTo }\n      }\n    ) {\n      id\n      flow_run_id\n      level\n      message\n      name\n      task_run_id\n      timestamp\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Logs/retrieve-archived-logs.gql",
    "content": "mutation ArchivedFlowRunLogs($flowRunId: UUID!, $timestamp: DateTime!) {\n  retrieve_archived_flow_run_logs(\n    input: { flow_run_id: $flowRunId, timestamp: $timestamp }\n  ) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Logs/task-run-logs-scoping.gql",
    "content": "query TaskRunLogsScoping(\n  $id: uuid!\n  $limit: Int = 50\n  $timestamp: timestamptz\n) {\n  task_run_by_pk(id: $id) {\n    id\n    logs_after: logs(\n      where: { timestamp: { _gte: $timestamp } }\n      order_by: { timestamp: asc }\n      limit: $limit\n    ) {\n      timestamp\n    }\n    logs_before: logs(\n      where: { timestamp: { _lte: $timestamp } }\n      order_by: { timestamp: desc }\n      limit: $limit\n    ) {\n      timestamp\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Logs/task-run-logs.gql",
    "content": "query TaskRunLogs(\n  $id: uuid!\n  $logId: uuid\n  $levels: [String!]\n  $limit: Int = 100\n  $offset: Int = 0\n  $searchText: String\n  $timestampFrom: timestamptz\n  $timestampTo: timestamptz\n) {\n  task_run_by_pk(id: $id) {\n    id\n    flow_run_id\n    start_time\n    state\n    logs(\n      limit: $limit\n      offset: $offset\n      order_by: { timestamp: desc }\n      where: {\n        id: { _eq: $logId }\n        level: { _in: $levels }\n        message: { _ilike: $searchText }\n        timestamp: { _gte: $timestampFrom, _lte: $timestampTo }\n      }\n    ) {\n      id\n      level\n      message\n      name\n      timestamp\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/MappedTasks/mapped-children.gql",
    "content": "query MappedChildren($taskRunId: UUID!) {\n  mapped_children(task_run_id: $taskRunId) {\n    max_end_time\n    min_start_time\n    state_counts\n  }\n}\n"
  },
  {
    "path": "src/graphql/Middleware/flow-group.gql",
    "content": "query Flow($id: uuid!) {\n  flow_group_by_pk(id: $id) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Middleware/flow.gql",
    "content": "query Flow($id: uuid!) {\n  flow_by_pk(id: $id) {\n    id\n    version\n    flow_group_id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/add-config-to-flow.gql",
    "content": "mutation CreateFlowGroupSLA($input: create_flow_group_sla_input!) {\n  create_flow_group_sla(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/cancel-flow-run.gql",
    "content": "mutation CancelFlowRun($flowRunId: UUID!) {\n  cancel_flow_run(input: { flow_run_id: $flowRunId }) {\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-action.gql",
    "content": "mutation CreateAction($input: create_action_input!) {\n  create_action(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-agent-config.gql",
    "content": "mutation CreateAgentConfig($input: create_agent_config_input!) {\n  create_agent_config(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-agent-sla-failed-hook.gql",
    "content": "mutation CreateAgentSLAFailedHook($input: create_agent_sla_failed_hook_input!) {\n  create_agent_sla_failed_hook(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-cloud-hook.gql",
    "content": "mutation CreateCloudHook($input: create_cloud_hook_input!) {\n  create_cloud_hook(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-custom-role.gql",
    "content": "mutation CreateCustomRole ($input: create_custom_role_input!){\n    create_custom_role (input: $input) {\n        id\n    }\n}"
  },
  {
    "path": "src/graphql/Mutations/create-flow-run-state-changed-hook.gql",
    "content": "mutation CreateFlowRunStateChangedHook(\n  $input: create_flow_run_state_changed_hook_input!\n) {\n  create_flow_run_state_changed_hook(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-flow-run.gql",
    "content": "mutation CreateFlowRun(\n  $context: JSON\n  $id: UUID!\n  $flowRunName: String\n  $parameters: JSON\n  $scheduledStartTime: DateTime\n  $runConfig: JSON\n  $labels: [String!]\n) {\n  create_flow_run(\n    input: {\n      context: $context\n      flow_id: $id\n      flow_run_name: $flowRunName\n      parameters: $parameters\n      scheduled_start_time: $scheduledStartTime\n      run_config: $runConfig\n      labels: $labels\n    }\n  ) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-flow-sla-failed-hook.gql",
    "content": "mutation CreateFlowSLAFailedHook($input: create_flow_sla_failed_hook_input!) {\n  create_flow_sla_failed_hook(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-flow-sla.gql",
    "content": "mutation CreateFlowSLAConfig($input: create_flow_sla_config_input!) {\n  create_flow_sla_config(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-project.gql",
    "content": "mutation CreateProject($name: String!, $description: String, $tenantId: UUID!) {\n  create_project(\n    input: { name: $name, description: $description, tenant_id: $tenantId }\n  ) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-runner-token.gql",
    "content": "mutation CreateRunnerToken($name: String!) {\n  create_api_token(input: { name: $name, scope: RUNNER }) {\n    id\n    token\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-tenant.gql",
    "content": "mutation CreateTenant($input: create_tenant_input!) {\n  create_tenant(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/create-tutorial-flow-run.gql",
    "content": "mutation CreateFlowRun($flowId: UUID) {\n  create_flow_run(input: { flow_id: $flowId }) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/delete-cloud-hook.gql",
    "content": "mutation DeleteCloudHook($input: delete_cloud_hook_input!) {\n  delete_cloud_hook(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/delete-flow-group-schedule.gql",
    "content": "mutation DeleteFlowGroupSchedule($input: delete_flow_group_schedule_input!) {\n  delete_flow_group_schedule(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/delete-flow-run.gql",
    "content": "mutation DeleteFlowRun($id: UUID!) {\n  delete_flow_run(input: { flow_run_id: $id }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/delete-hook.gql",
    "content": "mutation deleteHook ($hookId: UUID!) {\n  delete_hook (input: {hook_id: $hookId}) {\n    success\n  }\n}"
  },
  {
    "path": "src/graphql/Mutations/delete_action.gql",
    "content": "mutation deleteAction ($id: UUID!) {\n  delete_action (input: {action_id: $id}) {\n    success\n    error\n  }\n}"
  },
  {
    "path": "src/graphql/Mutations/delete_custom-role.gql",
    "content": "mutation DeleteCustomRole ($input: delete_custom_role_input!){\n    delete_custom_role (input: $input) {\n        success\n    }\n}"
  },
  {
    "path": "src/graphql/Mutations/deploy-flow.gql",
    "content": "mutation CreateFlow($projectId: UUID!, $serializedFlow: JSON!) {\n  create_flow(\n    input: { project_id: $projectId, serialized_flow: $serializedFlow }\n  ) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/disable-flow-heartbeat.gql",
    "content": "mutation DisableFlowHeartbeat($input: disable_flow_heartbeat_input!) {\n  disable_flow_heartbeat(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/disable-flow-lazarus-process.gql",
    "content": "mutation DisableFlowLazarusProcess(\n  $input: disable_flow_lazarus_process_input!\n) {\n  disable_flow_lazarus_process(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/disable-flow-version-lock.gql",
    "content": "mutation DisableFlowVersionLock($input: disable_flow_version_lock_input!) {\n  disable_flow_version_lock(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/enable-flow-heartbeat.gql",
    "content": "mutation EnableFlowHeartbeat($input: enable_flow_heartbeat_input!) {\n  enable_flow_heartbeat(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/enable-flow-lazarus-process.gql",
    "content": "mutation EnableFlowLazarusProcess($input: enable_flow_lazarus_process_input!) {\n  enable_flow_lazarus_process(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/enable-flow-version-lock.gql",
    "content": "mutation EnableFlowVersionLock($input: enable_flow_version_lock_input!) {\n  enable_flow_version_lock(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/mark-as-read.gql",
    "content": "mutation MarkMessageAsRead($input: mark_message_as_read_input!) {\n  mark_message_as_read(input: $input) {\n    success\n    error\n    }\n  }\n"
  },
  {
    "path": "src/graphql/Mutations/pause-tenant-work-queue.gql",
    "content": "mutation PauseTenantWorkQueue($tenantId: UUID!) {\n  tenant_work_queue_result: pause_tenant_work_queue(\n    input: { tenant_id: $tenantId }\n  ) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/resume-tenant-work-queue.gql",
    "content": "mutation ResumeTenantWorkQueue($tenantId: UUID!) {\n  tenant_work_queue_result: resume_tenant_work_queue(\n    input: { tenant_id: $tenantId }\n  ) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/set-cloud-hook-active.gql",
    "content": "mutation SetCloudHookActive($input: set_cloud_hook_active_input!) {\n  set_cloud_hook_active(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/set-cloud-hook-inactive.gql",
    "content": "mutation SetCloudHookInactive($input: set_cloud_hook_inactive_input!) {\n  set_cloud_hook_inactive(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/set-default-params.gql",
    "content": "mutation SetDefaultParams($input: set_flow_group_default_parameters_input!){\n  set_flow_group_default_parameters(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/set-flow-description.gql",
    "content": "mutation setFlowGroupDescription ($description: String!, $flowGroupId: UUID!) {\n  set_flow_group_description (input: {description: $description, flow_group_id: $flowGroupId}) {\n    success\n  }\n}"
  },
  {
    "path": "src/graphql/Mutations/set-flow-group-schedule.gql",
    "content": "mutation SetFlowGroupSchedule($input: set_flow_group_schedule_input!) {\n  set_flow_group_schedule(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/set-flow-run-labels.gql",
    "content": "mutation SetFlowRunLabel ($flowRunId: UUID!, $labelArray: [String!]!) {\n  set_flow_run_labels(input: {flow_run_id: $flowRunId, labels: $labelArray}) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/set-flow-run-name.gql",
    "content": "mutation SetFlowRunName($input: set_flow_run_name_input!) {\n  set_flow_run_name(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/set-labels.gql",
    "content": "mutation SetFlowGroupLabel ($flowGroupId: UUID!, $labelArray: [String!]) {\n  set_flow_group_labels(input: {flow_group_id: $flowGroupId, labels: $labelArray}) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/set-schedule-active.gql",
    "content": "mutation SetScheduleActive($id: UUID!) {\n  set_schedule_active(input: { flow_id: $id }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/set-schedule-inactive.gql",
    "content": "mutation SetScheduleInactive($id: UUID!) {\n  set_schedule_inactive(input: { flow_id: $id }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/set-task-run-name.gql",
    "content": "mutation SetTaskRunName($input: set_task_run_name_input!) {\n  set_task_run_name(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/test-cloud-hook.gql",
    "content": "mutation TestCloudHook($input: test_cloud_hook_input!) {\n  test_cloud_hook(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/update-custom-role.gql",
    "content": "mutation UpdateCustomRole ($input: update_custom_role_permissions_input!){\n    update_custom_role_permissions (input: $input) {\n        success\n    }\n}"
  },
  {
    "path": "src/graphql/Mutations/update-flow-project.gql",
    "content": "mutation UpdateFlowProject($input: update_flow_project_input!) {\n  update_flow_project(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Mutations/update-tenant-settings.gql",
    "content": "mutation UpdateTenantSettings($settings: JSON!) {\n  update_tenant_settings(input: { settings: $settings }) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Nav/flow-runs.gql",
    "content": "query FlowRuns($tenantId: uuid!, $states: [String!]) {\n  flow_run(where: { state: { _in: $states }, tenant_id: { _eq: $tenantId } }) {\n    id\n    scheduled_start_time\n  }\n}\n"
  },
  {
    "path": "src/graphql/Nav/flow.gql",
    "content": "query Flow($id: uuid) {\n  flow(\n    where: { _or: [{ id: { _eq: $id } }, { flow_group_id: { _eq: $id } }] }\n  ) {\n    id\n    flow_group_id\n    name\n    project_id\n    is_schedule_active\n  }\n}\n"
  },
  {
    "path": "src/graphql/Nav/flows.gql",
    "content": "query Flows {\n  flow(where: { archived: { _eq: false } }) {\n    id\n    flow_group_id\n    name\n    project_id\n    is_schedule_active\n  }\n}\n"
  },
  {
    "path": "src/graphql/Nav/projects.gql",
    "content": "query Projects {\n  project {\n    id\n    name\n    tenant_id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Nav/task.gql",
    "content": "query Task($taskId: uuid!) {\n  task(where: { id: { _eq: $taskId } }) {\n    id\n    flow_id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/Nav/tasks.gql",
    "content": "query Tasks($flowId: uuid!) {\n  task(where: { flow_id: { _eq: $flowId } }) {\n    id\n    flow_id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/Notifications/all-notifications.gql",
    "content": "query Notifications($where: message_bool_exp) {\n  notifications: message(where: $where) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Notifications/membership-invitation.gql",
    "content": "query MembershipInvitation($id: uuid!) {\n  membership_invitation_by_pk(id: $id) {\n    id\n    role_detail {\n      id\n      name\n    }\n    email\n    created\n    tenant {\n      id\n      name\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Notifications/notifications-count-unread.gql",
    "content": "query NotificationsCountUnread {\n  message_aggregate(where: { read: { _eq: false } }) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Notifications/notifications-count.gql",
    "content": "query NotificationsCount($where: message_bool_exp) {\n  message_aggregate(where: $where) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Notifications/notifications.js",
    "content": "import gql from 'graphql-tag'\n\nexport default function(isCloud) {\n  return gql`\n\n  query Notifications(\n  $limit: Int\n  $offset: Int\n  $orderBy: [message_order_by!]\n  $where: message_bool_exp\n) {\n  notifications: message(\n    where: $where\n    limit: $limit\n    offset: $offset\n    order_by: $orderBy\n  ) {\n    id\n    content\n    created\n    read\n    content\n    tenant_id\n    text\n    type\n    updated\n\n    ${\n      isCloud\n        ? `\n        user {\n          id\n          username\n        }\n\n        user_id\n      `\n        : ''\n    }\n\n  }\n}\n   \n  `\n}\n"
  },
  {
    "path": "src/graphql/Notifications/teams.gql",
    "content": "query Teams {\n  teams: tenant(order_by: { name: asc }) {\n    id\n    name\n    slug\n  }\n}\n"
  },
  {
    "path": "src/graphql/Playground/schema.gql",
    "content": "query IntrospectionQuery {\n  __schema {\n    queryType {\n      name\n    }\n    mutationType {\n      name\n    }\n    subscriptionType {\n      name\n    }\n    types {\n      ...FullType\n    }\n    directives {\n      name\n      description\n      locations\n      args {\n        ...InputValue\n      }\n    }\n  }\n}\n\nfragment FullType on __Type {\n  kind\n  name\n  description\n  fields {\n    name\n    description\n    args {\n      ...InputValue\n    }\n    type {\n      ...TypeRef\n    }\n    isDeprecated\n    deprecationReason\n  }\n  inputFields {\n    ...InputValue\n  }\n  interfaces {\n    ...TypeRef\n  }\n  enumValues {\n    name\n    description\n    isDeprecated\n    deprecationReason\n  }\n  possibleTypes {\n    ...TypeRef\n  }\n}\n\nfragment InputValue on __InputValue {\n  name\n  description\n  type {\n    ...TypeRef\n  }\n  defaultValue\n}\n\nfragment TypeRef on __Type {\n  kind\n  name\n  ofType {\n    kind\n    name\n    ofType {\n      kind\n      name\n      ofType {\n        kind\n        name\n        ofType {\n          kind\n          name\n          ofType {\n            kind\n            name\n            ofType {\n              kind\n              name\n              ofType {\n                kind\n                name\n              }\n            }\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Project/flow-ids.gql",
    "content": "query ProjectFlowIds($projectId: uuid!) {\n  project_by_pk(id: $projectId) {\n    flows {\n      id\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Project/flows-aggregate.gql",
    "content": "query FlowAggregate($where: flow_bool_exp) {\n  flow_aggregate(where: $where) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Project/flows.gql",
    "content": "query ProjectFlows(\n  $limit: Int!\n  $offset: Int!\n  $orderBy: [flow_order_by!]\n  $where: flow_bool_exp\n) {\n  flow(where: $where, limit: $limit, offset: $offset, order_by: $orderBy) {\n    id\n    name\n    version\n    flow_runs(\n      where: { start_time: { _is_null: false } }\n      order_by: { start_time: desc }\n      limit: 1\n    ) {\n      id\n      state\n      start_time\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Project/project.gql",
    "content": "query Project($id: uuid!) {\n  project_by_pk(id: $id) {\n    id\n    name\n    created\n  }\n}\n"
  },
  {
    "path": "src/graphql/Projects/projects-aggregate.gql",
    "content": "query ProjectsAggregate {\n  project_aggregate {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Projects/projects.gql",
    "content": "query Projects(\n  $limit: Int!\n  $offset: Int!\n  $orderBy: [project_order_by!]\n) {\n  project(limit: $limit, offset: $offset, order_by: $orderBy) {\n    id\n    name\n    flows_aggregate(where: { archived: { _eq: false } }) {\n      aggregate {\n        count\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Schematics/flow-list.gql",
    "content": "query Flows {\n  flow(\n    order_by: { created: desc }\n    where: { archived: { _eq: false }, name: { _neq: \"Welcome Flow\" } }\n  ) {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/Schematics/flow-run.gql",
    "content": "query FlowRun($id: uuid!) {\n  flow_run_by_pk(id: $id) {\n    id\n    name\n    state\n    start_time\n    end_time\n\n    task_runs(where: { map_index: { _eq: -1 } }) {\n      id\n      serialized_state\n      state\n      state_message\n      state_timestamp\n      start_time\n      end_time\n      map_index\n      name\n\n      task {\n        id\n        name\n        max_retries\n        retry_delay\n        trigger\n        type\n\n        upstream_edges {\n          upstream_task {\n            id\n            name\n          }\n          downstream_task {\n            id\n            name\n          }\n        }\n        downstream_edges {\n          upstream_task {\n            id\n            name\n          }\n          downstream_task {\n            id\n            name\n          }\n        }\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n}\n"
  },
  {
    "path": "src/graphql/Schematics/flow.gql",
    "content": "query Flow($id: uuid!) {\n  flow_by_pk(id: $id) {\n    id\n    name\n    tasks_aggregate {\n      aggregate {\n        count\n      }\n    }\n    tasks {\n      id\n      name\n      max_retries\n      retry_delay\n      trigger\n      type\n\n      upstream_edges {\n        upstream_task {\n          id\n          name\n        }\n        downstream_task {\n          id\n          name\n        }\n      }\n      downstream_edges {\n        upstream_task {\n          id\n          name\n        }\n        downstream_task {\n          id\n          name\n        }\n      }\n      __typename\n    }\n    __typename\n  }\n}\n"
  },
  {
    "path": "src/graphql/Schematics/task-run.gql",
    "content": "query TaskRun($id: uuid!) {\n  task_run_by_pk(id: $id) {\n      \n  }\n  flow_run_by_pk(id: $id) {\n    id\n    name\n    state\n    start_time\n    end_time\n\n    task_runs(where: { map_index: { _eq: -1 } }) {\n      id\n      serialized_state\n      state\n      state_message\n      state_timestamp\n      start_time\n      end_time\n      map_index\n\n      task {\n        id\n        name\n        max_retries\n        retry_delay\n        trigger\n        type\n\n        upstream_edges {\n          upstream_task {\n            id\n            name\n          }\n          downstream_task {\n            id\n            name\n          }\n        }\n        downstream_edges {\n          upstream_task {\n            id\n            name\n          }\n          downstream_task {\n            id\n            name\n          }\n        }\n        __typename\n      }\n      __typename\n    }\n    __typename\n  }\n}\n"
  },
  {
    "path": "src/graphql/Schematics/task.gql",
    "content": "query Task($id: uuid!) {\n  task(where: { id: { _eq: $id } }) {\n    id\n    name\n    downstream_edges {\n      id\n      downstream_task_id\n    }\n    upstream_edges {\n      id\n      upstream_task_id\n    }\n    slug\n    tags\n    type\n    trigger\n    description\n    auto_generated\n    __typename\n  }\n}\n"
  },
  {
    "path": "src/graphql/Secrets/delete-secret.gql",
    "content": "mutation DeleteSecret($name: String!) {\n  delete_secret(input: { name: $name }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Secrets/set-secret.gql",
    "content": "mutation SetSecret($name: String!, $value: JSON!) {\n  set_secret(input: { name: $name, value: $value }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/activity.gql",
    "content": "query Activity(\n  $limit: Int\n  $taskId: uuid!\n  $states: [String!]\n  $timestamp: timestamptz\n) {\n  task_run_state(\n    where: {\n      task_run: { task: { id: { _eq: $taskId } } }\n      timestamp: { _gte: $timestamp }\n      state: { _in: $states }\n    }\n    limit: $limit\n    order_by: { timestamp: desc }\n  ) {\n    id\n    state\n    message\n    result\n    timestamp\n    task_run {\n      id\n      state\n      start_time\n      end_time\n      task {\n        id\n        name\n        max_retries\n      }\n      flow_run {\n        id\n      }\n      name\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/heartbeat.gql",
    "content": "query Heartbeat($taskId: uuid!, $timestamp: timestamptz, $state: String) {\n  task_run(\n    limit: 10\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $timestamp }\n      state: { _eq: $state }\n    }\n    order_by: { updated: desc_nulls_last }\n  ) {\n    id\n    state\n    state_message\n    state_timestamp\n    start_time\n    end_time\n    task {\n      id\n      name\n      max_retries\n    }\n    __typename\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/last-task-run.gql",
    "content": "query LastTaskRun($id: uuid!) {\n  task_run(\n    where: {\n      task_id: { _eq: $id }\n      state: { _neq: \"Scheduled\" }\n      start_time: { _is_null: false }\n    }\n    order_by: { updated: desc }\n    limit: 1\n  ) {\n    id\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/table-task-runs-count.gql",
    "content": "query TableTaskRuns($taskId: uuid, $heartbeat: timestamptz) {\n  task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/table-task-runs.gql",
    "content": "query Task(\n  $taskId: uuid!\n  $limit: Int\n  $offset: Int\n  $orderBy: [task_run_order_by!]\n  $heartbeat: timestamptz\n) {\n  task_by_pk(id: $taskId) {\n    id\n    name\n    task_runs(\n      where: {\n        flow_run: { state: { _neq: \"Scheduled\" } }\n        updated: { _gte: $heartbeat }\n      }\n      order_by: $orderBy\n      limit: $limit\n      offset: $offset\n    ) {\n      id\n      map_index\n      end_time\n      start_time\n      state\n      flow_run {\n        name\n        id\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/task-drawer.gql",
    "content": "query Task($id: uuid!) {\n  task_by_pk(id: $id) {\n    id\n    name\n    created\n    description\n    slug\n    max_retries\n    retry_delay\n    trigger\n    type\n    flow {\n      id\n      name\n      project {\n        id\n        name\n      }\n    }\n    task_runs(\n      where: { flow_run: { state: { _neq: \"Scheduled\" } } }\n      order_by: { flow_run: { scheduled_start_time: desc } }\n      limit: 1\n    ) {\n      id\n      state\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/task-runs-count.gql",
    "content": "query TaskRunsCount($where: task_run_bool_exp) {\n  task_run_aggregate(where: $where) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/task-runs-drawer-count.gql",
    "content": "query FlowRunsCount($taskId: uuid, $heartbeat: timestamptz, $state: String) {\n  task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: $state }\n    }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/task-runs-drawer.gql",
    "content": "query FlowRuns(\n  $taskId: uuid\n  $heartbeat: timestamptz\n  $state: String\n  $limit: Int\n  $offset: Int\n) {\n  task_run(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: $state }\n    }\n    limit: $limit\n    offset: $offset\n  ) {\n    id\n    end_time\n    start_time\n    state\n    task {\n      id\n      name\n    }\n    flow_run {\n      id\n      name\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/task-runs.gql",
    "content": "query TaskRuns($taskId: uuid!, $heartbeat: timestamptz) {\n  Success: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Success\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Running: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Running\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Pending: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Pending\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Paused: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Paused\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  ClientFailed: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"ClientFailed\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Submitted: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Submitted\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Queued: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Queued\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Resume: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Resume\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Retrying: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Retrying\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Looped: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Looped\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Cached: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Cached\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Mapped: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Mapped\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Failed: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Failed\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  TimedOut: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"TimedOut\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  TriggerFailed: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"TriggerFailed\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Skipped: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Skipped\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n  Finished: task_run_aggregate(\n    where: {\n      task_id: { _eq: $taskId }\n      updated: { _gte: $heartbeat }\n      flow_run: { state: { _neq: \"Scheduled\" } }\n      state: { _eq: \"Finished\" }\n    }\n    order_by: { id: desc }\n  ) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Task/task.gql",
    "content": "query Task($id: uuid!) {\n  task_by_pk(id: $id) {\n    id\n    name\n    description\n    created\n    retry_delay\n    max_retries\n    trigger\n    type\n\n    upstream_edges {\n      id\n      upstream_task {\n        id\n        name\n        retry_delay\n        max_retries\n        trigger\n        type\n      }\n    }\n    downstream_edges {\n      id\n      downstream_task {\n        id\n        name\n        retry_delay\n        max_retries\n        trigger\n        type\n      }\n    }\n\n    flow {\n      id\n      flow_group_id\n      name\n      version\n      project {\n        id\n        name\n      }\n      parameters\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/activity.gql",
    "content": "query Activity(\n  $limit: Int\n  $taskRunId: uuid!\n  $states: [String!]\n  $timestamp: timestamptz\n) {\n  task_run_state(\n    where: {\n      task_run: { id: { _eq: $taskRunId } }\n      timestamp: { _gte: $timestamp }\n      state: { _in: $states }\n    }\n    limit: $limit\n    order_by: { timestamp: desc }\n  ) {\n    id\n    state\n    message\n    result\n    timestamp\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/dependencies.gql",
    "content": "query Dependencies($taskRunId: uuid!, $flowRunId: uuid!) {\n  task_run_by_pk(id: $taskRunId) {\n    id\n    state\n    task {\n      id\n      name\n      upstream_edges {\n        id\n        upstream_task {\n          id\n          name\n          task_runs(where: { flow_run_id: { _eq: $flowRunId } }) {\n            id\n            state\n          }\n        }\n      }\n      downstream_edges {\n        id\n        downstream_task {\n          id\n          name\n          task_runs(where: { flow_run_id: { _eq: $flowRunId } }) {\n            id\n            state\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/heartbeat.gql",
    "content": "query Heartbeat(\n  $taskRunId: uuid!\n  $timestamp: timestamptz\n  $state: String\n  $limit: Int\n) {\n  task_run(where: { id: { _eq: $taskRunId } }) {\n    id\n    states_aggregate {\n      aggregate {\n        count\n      }\n    }\n    states(\n      limit: $limit\n      where: { timestamp: { _gte: $timestamp }, state: { _eq: $state } }\n      order_by: { timestamp: desc_nulls_last }\n    ) {\n      id: timestamp\n      state\n      message\n      timestamp\n      result\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/set-flow-run-states.gql",
    "content": "mutation SetFlowRunStates($flowRunId: UUID!, $version: Int!, $state: JSON!) {\n  set_flow_run_states(\n    input: {\n      states: [{ flow_run_id: $flowRunId, state: $state, version: $version }]\n    }\n  ) {\n    states {\n      id\n      status\n      message\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/set-task-run-states.gql",
    "content": "mutation setTaskRunStates($input: [set_task_run_state_input!]!) {\n  set_task_run_states(input: { states: $input }) {\n    states {\n      id\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/table-mapped-task-runs-count.gql",
    "content": "query TableMappedTaskRunsCount($where: task_run_bool_exp!) {\n  task_run_aggregate(where: $where) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/table-mapped-task-runs.gql",
    "content": "query TableMappedTaskRuns(\n  $where: task_run_bool_exp!\n  $limit: Int\n  $offset: Int\n  $orderBy: [task_run_order_by!]\n) {\n  task_run(where: $where, order_by: $orderBy, limit: $limit, offset: $offset) {\n    id\n    name\n    map_index\n    end_time\n    start_time\n    state\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/task-run-states-count.gql",
    "content": "query TaskRunStatesCount($where: task_run_state_bool_exp) {\n  task_run_state_aggregate(where: $where) {\n    aggregate {\n      count\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/task-run-states.gql",
    "content": "query TaskRunStates(\n  $where: task_run_state_bool_exp\n  $limit: Int!\n  $offset: Int!\n  $orderBy: [task_run_state_order_by!]\n) {\n  task_run_state(\n    where: $where\n    limit: $limit\n    order_by: $orderBy\n    offset: $offset\n  ) {\n    id\n    state\n    start_time\n    timestamp\n    result\n    message\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/task-run.gql",
    "content": "query TaskRun($id: uuid!) {\n  task_run_by_pk(id: $id) {\n    id\n    version\n    state\n    state_message\n    state_timestamp\n    updated\n    start_time\n    end_time\n    map_index\n    serialized_state\n    name\n\n    task {\n      id\n      name\n      retry_delay\n      max_retries\n      trigger\n      type\n\n      upstream_edges {\n        upstream_task {\n          id\n          name\n        }\n        downstream_task {\n          id\n          name\n        }\n      }\n      downstream_edges {\n        upstream_task {\n          id\n          name\n        }\n        downstream_task {\n          id\n          name\n        }\n      }\n    }\n\n    flow_run {\n      id\n      name\n      state\n      flow {\n        id\n        flow_group_id\n        name\n        project {\n          id\n          name\n        }\n      }\n      parameters\n      version\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskRun/utility_downstream_tasks.gql",
    "content": "query taskRunUtilityDownstreamTasks($flowRunId: uuid, $taskIds: _uuid) {\n  utility_downstream_tasks(args: { start_task_ids: $taskIds }) {\n    depth\n    task {\n      task_runs(where: { flow_run_id: { _eq: $flowRunId } }) {\n        id\n        map_index\n        version\n      }\n    }\n    task_id\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskTagLimit/delete-task-concurrency-limit.gql",
    "content": "mutation DeleteTaskConcurrencyLimit($limitId: UUID!) {\n  delete_task_concurrency_limit(input: { limit_id: $limitId }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskTagLimit/task-tag-limit.gql",
    "content": "query TaskTagLimit {\n  task_concurrency_limit {\n    id\n    limit\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskTagLimit/update-task-concurrency-limit.gql",
    "content": "mutation UpdateTaskConcurrencyLimit($name: String!, $limit: Int!) {\n  update_task_concurrency_limit(input: { name: $name, limit: $limit }) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/TaskTagUsage/task-tag-usage.gql",
    "content": "query TaskTagUsage($tags: [String!]) {\n  task_concurrency(names: $tags) {\n    name\n    usage\n  }\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/actions.gql",
    "content": "query actions {\n   actions: action {\n    action_type\n    action_config\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/cloud-hooks.gql",
    "content": "query CloudHooks($searchParams: [cloud_hook_bool_exp!]) {\n  cloud_hook(where: { _or: $searchParams }) {\n    id\n    active\n    config\n    created\n    name\n    states\n    tenant_id\n    type\n    updated\n    version_group_id\n  }\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/data-to-clear.js",
    "content": "import gql from 'graphql-tag'\n\nexport default function(isCloud) {\n  return gql`\n    query DataToClear {\n      project {\n        id\n      }\n\n      flow(distinct_on: version_group_id, where: { archived: { _eq: false } }) {\n        id\n      }\n\n      \n      ${\n        isCloud\n          ? `\n          secret_names\n\n          memberships: user_view_same_tenant {\n            id\n            account_type\n\n            memberships {\n                id\n              }\n          }\n\n          membershipInvitations: membership_invitation {\n            id\n          }\n\n          api_token {\n            id\n          }\n\n          `\n          : ''\n      }\n\n    }\n`\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/delete-action.gql",
    "content": "mutation DeleteAction ($actionId: UUID!) {\n  delete_action (input: {action_id: $actionId}) {\n    success\n  }\n}"
  },
  {
    "path": "src/graphql/TeamSettings/delete-project.gql",
    "content": "mutation DeleteProject($projectId: UUID!) {\n  delete_project(input: { project_id: $projectId }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/flow-version-groups.js",
    "content": "import gql from 'graphql-tag'\n\nexport default function(isCloud) {\n  return gql`\nquery FlowVersionGroups {\n    versionGroup: flow(distinct_on: [version_group_id]) {\n    version_group_id\n    id\n    name\n    project {\n      id\n      name\n    }\n\n              ${\n            isCloud\n              ? `\n              created_by {\n                id\n                username\n              }`\n              : ''\n          }\n  }\n}\n`\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/flows.gql",
    "content": "query Flows ($project: uuid) {\n  flow(distinct_on: version_group_id, where: {_and: [{project_id: {_eq: $project}, archived: {_eq: false}}]}) {\n    id\n    archived\n    name\n    flow_group_id\n    version_group_id\n    project {\n      id\n      name\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/membership-invitation-roles.gql",
    "content": "query MembershipInvitationRoles {\n    membership_invitation {\n        role_id\n    }\n}"
  },
  {
    "path": "src/graphql/TeamSettings/membership-roles.gql",
    "content": "query RolesInUse {\n    membership {\n        id\n        role_id\n    }\n}"
  },
  {
    "path": "src/graphql/TeamSettings/memberships.gql",
    "content": "query Memberships {\n  memberships: user_view_same_tenant {\n    id\n    account_type\n\n    memberships {\n      id\n    }\n  }\n\n  membershipInvitations: membership_invitation {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/modify-project.gql",
    "content": "mutation ModifyProject(\n  $projectId: UUID!\n  $projectName: String!\n  $projectDescription: String\n) {\n  set_project_name(input: { project_id: $projectId, name: $projectName }) {\n    id\n  }\n\n  set_project_description(\n    input: { project_id: $projectId, description: $projectDescription }\n  ) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/permissions.gql",
    "content": "query Permissions {\n  permissions_info {\n      user_permissions_filtered_by_license_features\n      all_permissions_filtered_by_license_features\n    }\n  }\n"
  },
  {
    "path": "src/graphql/TeamSettings/project.gql",
    "content": "query Project($projectName: String!) {\n  project(where: { name: { _eq: $projectName } }) {\n    id\n    name\n  }\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/projects.gql",
    "content": "query Projects {\n  projects: project {\n    id\n    name\n    description\n    created\n    active_flow_count: flows_aggregate(where: { archived: { _eq: false } }) {\n      aggregate {\n        count\n      }\n    }\n    archived_flow_count: flows_aggregate(where: { archived: { _eq: true } }) {\n      aggregate {\n        count\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/roles.gql",
    "content": "query AuthRoles {\n  auth_role {\n    name\n    permissions\n    created\n    updated\n    tenant_id\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/TeamSettings/test-action.gql",
    "content": "mutation TestAction ($actionId: UUID!) {\n  test_action (input: {action_id: $actionId}) {\n    success\n  }\n}"
  },
  {
    "path": "src/graphql/TeamSettings/usage.gql",
    "content": "query Usage($from: timestamptz, $to: timestamptz, $tenant_id: uuid) {\n  usage: billing_usage(\n    where: {\n      timestamp: { _gte: $from, _lte: $to }\n      tenant_id: { _eq: $tenant_id }\n    }\n  ) {\n    id\n    kind\n    runs\n    tenant_id\n    timestamp\n    usage_last_updated\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/accept-membership-invitation.gql",
    "content": "mutation AcceptMembershipInvitation($membershipInvitationId: UUID!) {\n  accept_membership_invitation(\n    input: { invitation_id: $membershipInvitationId }\n  ) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/create-enterprise-tenant.gql",
    "content": "mutation CreateEnterpriseTenant($input: create_enterprise_tenant_input!) {\n  create_enterprise_tenant(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/create-membership-invitation.gql",
    "content": "mutation CreateMembershipInvitation(\n  $input: create_membership_invitation_input!\n) {\n  create_membership_invitation(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/delete-enterprise-tenant.gql",
    "content": "mutation DeleteEnterpriseTenant($input: delete_enterprise_tenant_input!) {\n  delete_enterprise_tenant(input: $input) {\n    success\n    error\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/delete-membership-invitation.gql",
    "content": "mutation DeleteMembershipInvitation($membershipInvitationId: UUID!) {\n  delete_membership_invitation(\n    input: { invitation_id: $membershipInvitationId }\n  ) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/delete-membership.gql",
    "content": "mutation DeleteMembership($membershipId: UUID!) {\n  delete_membership(input: { membership_id: $membershipId }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/delete-tenant.gql",
    "content": "mutation DeleteTenant($input: delete_tenant_input!) {\n  delete_tenant(input: $input) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/membership-invitation.gql",
    "content": "query Memberships($id: uuid!) {\n  membership_invitation_by_pk(id: $id ) {\n    id\n    created\n    email\n    role_detail {\n      id\n      name\n    }\n    tenant {\n      id\n      name\n      slug\n    }\n    user {\n      id\n      username\n      email\n    }\n    tenant_id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/membership.gql",
    "content": "query Membership($membershipId: uuid!) {\n  membership(where: { id: { _eq: $membershipId } }) {\n    id\n    role_detail {\n      id\n      name\n    }\n    tenant {\n      id\n      name\n      slug\n      settings\n      stripe_customer\n      prefectAdminSettings: prefect_admin_settings\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/pending-invitations-by-email.gql",
    "content": "query PendingInvitations($email: String!) {\n  pendingInvitations: membership_invitation(\n    where: { email: { _eq: $email } }\n  ) {\n    id\n    role_detail {\n      id\n      name\n    }\n    email\n    created\n    tenant {\n      id\n      name\n      slug\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/pending-invitations.gql",
    "content": "query PendingInvitations {\n  pendingInvitations: membership_invitation {\n    id\n    created\n    email\n    role_detail {\n      id\n      name\n    }\n    tenant {\n      id\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/set-membership-role.gql",
    "content": "mutation SetMembershipRole($input: set_membership_role_input!) {\n  set_membership_role(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/tenant-by-pk.gql",
    "content": "query Tenant($id: uuid!) {\n  tenant_by_pk(id: $id) {\n    id\n    name\n    info\n    settings\n    slug\n    created\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/tenant-by-slug.gql",
    "content": "query CheckTenantSlug($slug: String!) {\n  tenant(where: { slug: { _eq: $slug } }) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/tenant-id-by-membership-id.gql",
    "content": "query Membership($membershipId: uuid!) {\n  membership(where: { id: { _eq: $membershipId } }) {\n    id\n    tenant {\n      id\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/tenant-secret-names.gql",
    "content": "query TenantSecretNames {\n  secret_names\n}\n"
  },
  {
    "path": "src/graphql/Tenant/tenant-token.gql",
    "content": "mutation SwitchTenant($tenantId: UUID!) {\n  switch_tenant(input: { tenant_id: $tenantId }) {\n    access_token\n    expires_at\n    refresh_token\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/tenant-users.gql",
    "content": "query TenantUsers {\n  tenantUsers: user_view_same_tenant {\n    id\n    username\n    email\n    first_name\n    last_name\n    account_type\n    memberships {\n      id\n      tenant_id\n      role_detail {\n        id\n        name\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tenant/tenants.js",
    "content": "import gql from 'graphql-tag'\n\nexport default function(isCloud) {\n  return gql`\n    query Tenants {\n      tenant {\n        id\n        created\n        name\n        info\n        settings\n        \n        ${\n          isCloud\n            ? `\n              prefectAdminSettings: prefect_admin_settings\n              stripe_customer\n              license_id\n            `\n            : ''\n        }\n        slug\n      }\n    }\n`\n}\n"
  },
  {
    "path": "src/graphql/Tenant/update-tenant.gql",
    "content": "mutation UpdateTenant($name: String!, $slug: String!) {\n  update_tenant_name(input: { name: $name }) {\n    id\n  }\n  update_tenant_slug(input: { slug: $slug }) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tokens/api-keys.gql",
    "content": "query APIKeys {\n  auth_api_key(order_by: { created: desc }) {\n    id\n    name\n    created\n    expires_at\n    default_tenant_id\n    user_id\n    updated\n\n    created_by {\n      id\n      username\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tokens/api-tokens.gql",
    "content": "query APITokens {\n  api_token(\n    order_by: { created: desc }\n    where: { scope: { _in: [\"TENANT\", \"RUNNER\"] } }\n  ) {\n    id\n    name\n    created_by {\n      id\n      username\n    }\n    created\n    expires_at\n    last_used\n    tenant_id\n    user_id\n    scope\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tokens/create-api-key.gql",
    "content": "mutation CreateAPIKey(\n  $user_id: UUID!\n  $name: String!\n  $expires_at: DateTime\n  $tenant_id: UUID\n) {\n  create_api_key(\n    input: {\n      user_id: $user_id\n      name: $name\n      expires_at: $expires_at\n      default_tenant_id: $tenant_id\n    }\n  ) {\n    id\n    key\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tokens/create-api-token.gql",
    "content": "mutation CreateAPIToken(\n  $name: String!\n  $scope: api_token_scope\n  $expires_at: DateTime\n) {\n  create_api_token(\n    input: { name: $name, scope: $scope, expires_at: $expires_at }\n  ) {\n    id\n    token\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tokens/delete-api-key.gql",
    "content": "mutation DeleteAPIKey($id: UUID!) {\n  delete_api_key(input: { key_id: $id }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tokens/delete-token.gql",
    "content": "mutation DeleteAPIToken($id: UUID!) {\n  delete_api_token(input: { token_id: $id }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/Tokens/user-tokens.gql",
    "content": "query APITokens {\n  api_token(order_by: { created: desc }, where: { scope: { _eq: \"USER\" } }) {\n    id\n    name\n    created\n    expires_at\n    last_used\n  }\n}\n"
  },
  {
    "path": "src/graphql/Update/write-run-logs.gql",
    "content": "mutation WriteRunLogs(\n  $flowRunId: UUID!\n  $taskRunId: UUID\n  $message: String\n  $name: String\n) {\n  write_run_logs(\n    input: {\n      logs: [\n        {\n          flow_run_id: $flowRunId\n          task_run_id: $taskRunId\n          name: $name\n          message: $message\n        }\n      ]\n    }\n  ) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/User/create-service-account.gql",
    "content": "mutation CreateServiceAccount($input: create_service_account_input!) {\n  create_service_account(input: $input) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/User/delete-service-account.gql",
    "content": "mutation DeleteServiceAccount($id: UUID!) {\n  delete_service_account(input: { user_id: $id }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/User/update-user-details.gql",
    "content": "mutation UpdateUserDetails($firstName: String, $lastName: String) {\n  update_user_details(input: { first_name: $firstName, last_name: $lastName }) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/User/update-user-settings.gql",
    "content": "mutation UpdateUserSettings($input: JSON) {\n  update_user_settings(input: { settings: $input }) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/User/user.gql",
    "content": "query User {\n  user {\n    id\n    username\n    email\n    settings\n    default_membership_id\n    first_name\n    last_name\n    memberships {\n      id\n      tenant {\n        id\n        name\n        slug\n      }\n      role_detail {\n        id\n        name\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/graphql/api.gql",
    "content": "query Api {\n  api {\n    backend\n    mode\n    version\n    core_version\n    release_timestamp\n  }\n}\n"
  },
  {
    "path": "src/graphql/concurrent-runs.gql",
    "content": "query ConcurrentRuns {\n  flow_run(where: { state: { _in: [\"Running\", \"Submitted\", \"Cancelling\"] } }) {\n    id\n  }\n}\n"
  },
  {
    "path": "src/graphql/hello.gql",
    "content": "query Hello {\n  hello\n}\n"
  },
  {
    "path": "src/graphql/log-in.gql",
    "content": "mutation LogIn($input: log_in_input!) {\n  log_in(input: $input) {\n    access_token\n    expires_at\n    refresh_token\n  }\n}\n"
  },
  {
    "path": "src/graphql/log-out.gql",
    "content": "mutation LogOut($input: log_out_input!) {\n  log_out(input: $input) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/graphql/refresh-token.gql",
    "content": "mutation RefreshToken($input: refresh_token_input!) {\n  refresh_token(input: $input) {\n    access_token\n    expires_at\n    refresh_token\n  }\n}\n"
  },
  {
    "path": "src/graphql/support/send-feedback.gql",
    "content": "mutation($type: String!, $message: String!) {\n  send_feedback(input: { type: $type, message: $message }) {\n    success\n  }\n}\n"
  },
  {
    "path": "src/layouts/AgentLayout.vue",
    "content": "<script>\nexport default {\n  computed: {\n    extendedSlots() {\n      return Object.keys(this.$slots).filter(key => key.includes('extended'))\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container fluid class=\"mx-auto pt-0 px-3 pb-12\">\n    <v-row v-if=\"$slots['row-0']\" no-gutters>\n      <v-col class=\"pa-0\">\n        <slot name=\"row-0\" />\n      </v-col>\n    </v-row>\n\n    <v-row\n      v-if=\"\n        $slots['row-1-col-1-tile-1'] ||\n          $slots['row-1-col-2-tile-1'] ||\n          $slots['row-1-col-3-tile-1'] ||\n          $slots['row-1-col-4-tile-1']\n      \"\n      no-gutters\n      class=\"justify-start\"\n    >\n      <v-col\n        :class=\"{\n          'pb-0':\n            $slots['row-2-col-1-row-1-tile-1'] ||\n            $slots['row-2-col-1-row-2-tile-1'] ||\n            $slots['row-2-col-1-row-3-tile-1'] ||\n            $slots['row-2-col-1-row-4-tile-1'],\n          'pt-0': $slots['row-0']\n        }\"\n      >\n        <v-row class=\"mt-0\">\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            :class=\"{\n              'pt-2': $slots['row-0']\n            }\"\n          >\n            <slot name=\"row-1-col-1-tile-1\" />\n          </v-col>\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            sm=\"6\"\n            :class=\"{\n              'pt-2': $slots['row-0']\n            }\"\n          >\n            <slot name=\"row-1-col-2-tile-1\" />\n          </v-col>\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            sm=\"6\"\n            :class=\"{\n              'pt-2': $slots['row-0']\n            }\"\n          >\n            <slot name=\"row-1-col-3-tile-1\" />\n          </v-col>\n        </v-row>\n      </v-col>\n      <v-row v-if=\"$slots['row-2-col-1-row-2-tile-a']\" class=\"pt-2 mt-0\">\n        <v-col cols=\"12\">\n          <slot name=\"row-2-col-1-row-2-tile-a\" />\n        </v-col>\n      </v-row>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "src/layouts/DashboardLargeActivityLayout.vue",
    "content": "<template>\n  <v-container class=\"fill-height\" fluid justify-center>\n    <v-layout align-content-start fill-height wrap style=\"max-width: 1440px;\">\n      <v-flex xs12>\n        <slot name=\"first-row\" />\n      </v-flex>\n      <v-flex sm12 md8>\n        <v-layout wrap>\n          <v-flex xs12 sm6>\n            <slot name=\"tile1\" />\n          </v-flex>\n          <v-flex xs12 sm6>\n            <slot name=\"tile2\" />\n          </v-flex>\n          <v-flex xs12 sm12>\n            <slot name=\"table\" />\n          </v-flex>\n        </v-layout>\n      </v-flex>\n      <v-flex sm12 md4>\n        <slot name=\"activityBar\" />\n      </v-flex>\n    </v-layout>\n  </v-container>\n</template>\n"
  },
  {
    "path": "src/layouts/DashboardLargeChartLayout.vue",
    "content": "<template>\n  <v-container class=\"fill-height\" fluid justify-center>\n    <v-layout align-content-start fill-height wrap style=\"max-width: 1440px;\">\n      <v-flex xs12>\n        <slot name=\"firstRow\" />\n      </v-flex>\n      <v-flex sm12 md4>\n        <v-layout column>\n          <v-flex xs12>\n            <slot name=\"tile1\" />\n          </v-flex>\n          <v-flex xs12>\n            <slot name=\"activityBar\" />\n          </v-flex>\n        </v-layout>\n      </v-flex>\n      <v-flex sm12 md8 class=\"pa-2\">\n        <slot name=\"chart\" />\n      </v-flex>\n    </v-layout>\n  </v-container>\n</template>\n"
  },
  {
    "path": "src/layouts/DashboardLayout.vue",
    "content": "<template>\n  <v-container class=\"fill-height\" fluid justify-center>\n    <v-layout align-content-start fill-height wrap style=\"max-width: 1440px;\">\n      <v-flex class=\"w-100\" xs-12>\n        <slot name=\"first-row\" />\n      </v-flex>\n      <v-flex sm6 md4>\n        <slot name=\"tile1\" />\n      </v-flex>\n      <v-flex sm6 md4>\n        <slot name=\"tile2\" />\n      </v-flex>\n      <v-flex sm12 md4>\n        <slot name=\"tile3\" />\n      </v-flex>\n      <v-flex sm12 md8>\n        <slot name=\"table\" />\n      </v-flex>\n      <v-flex sm12 md4>\n        <slot name=\"activityBar\" />\n      </v-flex>\n    </v-layout>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.w-100 {\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/layouts/FullPageLayout.vue",
    "content": "<template>\n  <v-container fluid style=\"max-width: 1440px;\" class=\"mx-auto pt-0 px-3 pb-12\">\n    <v-row no-gutters>\n      <v-col class=\"pa-0\">\n        <slot />\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "src/layouts/ManagementLayout.vue",
    "content": "<script>\nexport default {\n  props: {\n    // Gain direct control over the render of this layout.\n    // This is particularly useful when you want to load data before rendering the layout & its contents.\n    controlShow: {\n      type: Boolean,\n      default: false,\n      required: false\n    },\n    // Determine whether or not to render the layout.\n    // Do nothing if controlShow is false.\n    show: {\n      type: Boolean,\n      default: false,\n      required: false\n    }\n  },\n  data() {\n    return {\n      showPage: this.show || false\n    }\n  },\n  watch: {\n    show(val) {\n      this.showPage = val\n    }\n  },\n  mounted() {\n    // Do nothing if the user wants programmatic control over the layout render.\n    if (this.controlShow) return\n\n    // Otherwise, fade-in the layout.\n    setTimeout(() => {\n      this.showPage = true\n    }, 0)\n  },\n  beforeDestroy() {\n    // Do nothing if the user wants programmatic control over the layout render.\n    if (this.controlShow) return\n\n    // Otherwise, fade out.\n    this.showPage = false\n  }\n}\n</script>\n\n<template>\n  <transition name=\"ml-fade\">\n    <v-container\n      v-show=\"showPage\"\n      fluid\n      justify-center\n      :style=\"{ 'max-width': `${$vuetify.breakpoint.thresholds.lg}px` }\"\n    >\n      <v-row>\n        <v-col cols=\"12\" class=\"text-center pb-2 \">\n          <slot name=\"alert\"></slot>\n          <h1 class=\"text-h4\"><slot name=\"title\"></slot></h1>\n        </v-col>\n      </v-row>\n      <v-row v-if=\"$slots.subtitle\">\n        <v-col cols=\"12\" class=\"text-center py-0\">\n          <div class=\"text-subtitle-1\">\n            <slot name=\"subtitle\"></slot>\n          </div>\n        </v-col>\n      </v-row>\n      <v-row v-if=\"$slots.cta\">\n        <v-col cols=\"12\" class=\"text-center mt-1 mb-2\">\n          <slot name=\"cta\"></slot>\n        </v-col>\n      </v-row>\n      <v-row v-if=\"$slots.cta1\">\n        <v-col cols=\"1\" md=\"3\" xl=\"5\" class=\"text-center mt-1 mb-2 xs\" />\n\n        <v-col cols=\"5\" md=\"3\" xl=\"1\" class=\"text-right mt-1 mb-2\">\n          <slot name=\"cta1\"></slot>\n        </v-col>\n        <v-col cols=\"5\" md=\"3\" xl=\"1\" class=\"text-left mt-1 mb-2\">\n          <slot name=\"cta2\"></slot>\n        </v-col>\n        <v-col cols=\"1\" md=\"3\" xl=\"5\" class=\"text-center mt-1 mb-2\" />\n      </v-row>\n      <v-row v-if=\"$slots.alerts\">\n        <v-col cols=\"12\">\n          <slot name=\"alerts\"></slot>\n        </v-col>\n      </v-row>\n      <v-row>\n        <v-col cols=\"12\">\n          <slot></slot>\n        </v-col>\n      </v-row>\n    </v-container>\n  </transition>\n</template>\n\n<style lang=\"scss\">\n.ml-fade-enter-active,\n.ml-fade-leave-active {\n  transition: opacity 400ms;\n}\n\n.ml-fade-enter,\n.ml-fade-leave-to {\n  opacity: 0;\n}\n</style>\n"
  },
  {
    "path": "src/layouts/NotificationsLayout.vue",
    "content": "<template>\n  <v-container\n    style=\"\n      max-width: 1440px;\n      padding-top: 60px;\n    \"\n    class=\"pb-12\"\n  >\n    <v-row class=\"mt-0\">\n      <v-col v-if=\"$slots['col-1']\" cols=\"12\" sm=\"4\" md=\"3\">\n        <slot name=\"col-1\" />\n      </v-col>\n\n      <v-col cols=\"12\" sm=\"8\" md=\"9\">\n        <slot />\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "src/layouts/SubPageNav.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport SupportBanner from '@/components/SupportBanner'\nimport EndOfLifeBanner from '@/components/EndOfLifeBanner'\n\nexport default {\n  components: { EndOfLifeBanner, SupportBanner },\n  props: {\n    hideBanners: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    icon: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    pageType: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      pageScrolled: false,\n      unsubscribeFlows: null,\n      unwatchFlows: null\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license', 'planType']),\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('data', ['flows']),\n    ...mapGetters('tenant', ['tenant']),\n    canShowBanners() {\n      return (\n        !this.hideBanners &&\n        !this.$vuetify.breakpoint.smAndDown &&\n        !this.pageScrolled\n      )\n    },\n    shouldShowSupportBanner() {\n      return (\n        !localStorage.getItem('dismissedSupportBanner') &&\n        this.shouldShowEndOfLifeBanner\n      )\n    },\n    shouldShowEndOfLifeBanner() {\n      return this.canShowBanners && this.isCloud && this.license?.terms?.frozen\n    }\n  },\n  async created() {\n    this.unsubscribeFlows = await this.$store.dispatch(\n      'polling/subscribe',\n      'flows'\n    )\n    this.unwatchFlows = this.$watch('flows', this.flowsChanged)\n  },\n  beforeDestroy() {\n    this.unsubscribeFlows()\n  },\n  methods: {\n    scrolled() {\n      this.pageScrolled = window.scrollY > 30\n    },\n    flowsChanged(flows) {\n      if (flows.length > 0) {\n        this.unsubscribeFlows()\n        this.unwatchFlows()\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <EndOfLifeBanner v-if=\"shouldShowEndOfLifeBanner\" />\n    <SupportBanner v-if=\"shouldShowSupportBanner\" />\n    <v-toolbar\n      v-scroll=\"scrolled\"\n      :elevation=\"\n        pageScrolled && (!$slots.tabs || $vuetify.breakpoint.smAndDown)\n          ? '4'\n          : '0'\n      \"\n      height=\"auto\"\n      color=\"appBackground\"\n      class=\"pb-3\"\n      style=\"position: fixed; width: 100%; z-index: 6\"\n    >\n      <v-row\n        no-gutters\n        class=\"d-flex align-center mx-auto\"\n        :class=\"{\n          'justify-center': $vuetify.breakpoint.smAndDown\n        }\"\n        style=\"height: 64px\"\n      >\n        <v-col :sm=\"$slots['page-actions'] ? 6 : 12\" class=\"d-flex align-end\">\n          <div class=\"mr-2\">\n            <v-icon x-large color=\"blue-grey lighten-4\">{{ icon }}</v-icon>\n          </div>\n          <div>\n            <div>\n              <span v-if=\"$slots.breadcrumbs\" style=\"font-size: 0.875rem\">\n                <slot name=\"breadcrumbs\"></slot>\n              </span>\n              <slot v-if=\"$slots['page-type']\" name=\"page-type\"></slot>\n              <span v-else class=\"text-overline\">{{ pageType }}</span>\n            </div>\n            <div class=\"text-h5 mt-n1\">\n              <slot name=\"page-title\"></slot>\n            </div>\n          </div>\n        </v-col>\n        <v-col\n          v-if=\"$slots['page-actions'] && $vuetify.breakpoint.smAndUp\"\n          cols=\"12\"\n          sm=\"6\"\n          class=\"align-self-end text-right\"\n          :class=\"{\n            'text-center': $vuetify.breakpoint.smAndDown\n          }\"\n        >\n          <slot name=\"page-actions\"></slot>\n        </v-col>\n      </v-row>\n      <template\n        v-if=\"$slots.tabs && $vuetify.breakpoint.mdAndUp\"\n        slot=\"extension\"\n        ><slot name=\"tabs\"></slot\n      ></template>\n      <template\n        v-if=\"$slots['page-actions'] && $vuetify.breakpoint.xsOnly\"\n        slot=\"extension\"\n        ><slot name=\"page-actions\"></slot\n      ></template>\n    </v-toolbar>\n  </div>\n</template>\n"
  },
  {
    "path": "src/layouts/TileLayout-Alternate.vue",
    "content": "<template>\n  <v-sheet fluid color=\"transparent\" class=\"mx-auto pt-0 px-3 pb-12\">\n    <v-row no-gutters>\n      <v-col cols=\"12\" md=\"4\" class=\"py-0\">\n        <v-row v-if=\"$slots['col-1-tile-1']\" class=\"justify-start\">\n          <v-col class=\"pb-0\">\n            <v-row>\n              <v-col>\n                <slot name=\"col-1-tile-1\" />\n              </v-col>\n            </v-row>\n          </v-col>\n        </v-row>\n\n        <v-row v-if=\"$slots['col-1-tile-2']\" class=\"justify-start\">\n          <v-col class=\"pt-0\">\n            <v-row>\n              <v-col>\n                <slot name=\"col-1-tile-2\" />\n              </v-col>\n            </v-row>\n          </v-col>\n        </v-row>\n      </v-col>\n\n      <v-col cols=\"12\" md=\"8\" class=\"py-0\">\n        <v-row v-if=\"$slots['actions-row']\" class=\"justify-start\">\n          <v-col\n            :class=\"\n              $slots['row-1-tile-1'] || $slots['row-1-tile-2'] ? 'pb-0' : ''\n            \"\n          >\n            <v-row>\n              <v-col>\n                <slot name=\"actions-row\" />\n              </v-col>\n            </v-row>\n          </v-col>\n        </v-row>\n\n        <v-row\n          v-if=\"$slots['row-1-tile-1'] || $slots['row-1-tile-2']\"\n          class=\"justify-start\"\n          no-gutters\n        >\n          <v-col\n            :class=\"\n              $slots['row-2-tile-1'] || $slots['row-2-tile-2']\n                ? $slots['actions-row']\n                  ? 'py-0'\n                  : 'pb-0'\n                : $slots['actions-row']\n                ? 'pt-0'\n                : ''\n            \"\n          >\n            <v-row style=\"height: 351px;\">\n              <v-col>\n                <slot name=\"row-1-tile-1\" />\n              </v-col>\n              <v-col>\n                <slot name=\"row-1-tile-2\" />\n              </v-col>\n            </v-row>\n          </v-col>\n        </v-row>\n\n        <v-row\n          v-if=\"$slots['row-2-tile-1'] || $slots['row-2-tile-2']\"\n          class=\"justify-start\"\n          no-gutters\n        >\n          <v-col\n            :class=\"\n              $slots['row-1-tile-1'] || $slots['row-1-tile-2'] ? 'pt-0' : ''\n            \"\n          >\n            <v-row>\n              <v-col v-if=\"$slots['row-2-tile-1']\">\n                <slot name=\"row-2-tile-1\" />\n              </v-col>\n              <v-col v-if=\"$slots['row-2-tile-2']\">\n                <slot name=\"row-2-tile-2\" />\n              </v-col>\n            </v-row>\n          </v-col>\n        </v-row>\n      </v-col>\n    </v-row>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "src/layouts/TileLayout-Full.vue",
    "content": "<template>\n  <v-sheet color=\"transparent\" class=\"pt-0 pb-12\">\n    <v-row v-if=\"$slots['row-1-tile']\" no-gutters>\n      <v-col cols=\"12\" class=\"pb-0\">\n        <v-row>\n          <v-col class=\"pb-0\">\n            <slot name=\"row-1-tile\" />\n          </v-col>\n        </v-row>\n      </v-col>\n    </v-row>\n    <v-row no-gutters>\n      <v-col cols=\"12\" class=\"py-0 px-4\">\n        <v-row>\n          <v-col class=\"pa-0\" cols=\"12\">\n            <slot name=\"row-2-tile\" />\n          </v-col>\n          <v-col>\n            <slot name=\"row-2a-tile\" cols=\"12\" />\n          </v-col>\n        </v-row>\n      </v-col>\n    </v-row>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "src/layouts/TileLayout.vue",
    "content": "<script>\nexport default {\n  computed: {\n    extendedSlots() {\n      return Object.keys(this.$slots).filter(key => key.includes('extended'))\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container fluid class=\"mx-auto pt-0 px-3 pb-12\">\n    <v-row v-if=\"$slots['row-0']\" no-gutters>\n      <v-col class=\"pa-0\">\n        <slot name=\"row-0\" />\n      </v-col>\n    </v-row>\n\n    <v-row\n      v-if=\"\n        $slots['row-1-col-1-tile-1'] ||\n          $slots['row-1-col-2-tile-1'] ||\n          $slots['row-1-col-3-tile-1'] ||\n          $slots['row-1-col-4-tile-1']\n      \"\n      no-gutters\n      class=\"justify-start\"\n    >\n      <v-col\n        :class=\"{\n          'pb-0':\n            $slots['row-2-col-1-row-1-tile-1'] ||\n            $slots['row-2-col-1-row-2-tile-1'] ||\n            $slots['row-2-col-1-row-3-tile-1'] ||\n            $slots['row-2-col-1-row-4-tile-1'],\n          'pt-0': $slots['row-0']\n        }\"\n      >\n        <v-row\n          class=\"mt-0\"\n          :style=\"{ height: $vuetify.breakpoint.mdAndUp ? '350px' : '' }\"\n        >\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            :class=\"{\n              'pt-1': $slots['row-0']\n            }\"\n          >\n            <slot name=\"row-1-col-1-tile-1\" />\n          </v-col>\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            sm=\"6\"\n            :class=\"{\n              'pt-1': $slots['row-0']\n            }\"\n          >\n            <slot name=\"row-1-col-2-tile-1\" />\n          </v-col>\n          <v-col\n            cols=\"12\"\n            md=\"4\"\n            sm=\"6\"\n            :class=\"{\n              'pt-1': $slots['row-0']\n            }\"\n          >\n            <slot name=\"row-1-col-3-tile-1\" />\n          </v-col>\n\n          <!-- This col is just used to push col-4 to the right -->\n          <v-col v-if=\"$vuetify.breakpoint.mdAndUp\" cols=\"4\"> </v-col>\n\n          <v-col cols=\"12\" md=\"8\">\n            <slot name=\"row-1-col-4-tile-1\" />\n          </v-col>\n        </v-row>\n      </v-col>\n    </v-row>\n\n    <v-row class=\"justify-start mt-4\">\n      <v-col\n        v-if=\"\n          $slots['row-2-col-1-row-1-tile-1'] ||\n            $slots['row-2-col-1-row-2-tile-1'] ||\n            $slots['row-2-col-1-row-3-tile-1'] ||\n            $slots['row-2-col-1-row-4-tile-1']\n        \"\n        cols=\"12\"\n        md=\"4\"\n        :class=\"\n          $slots['row-1-col-1-tile-1'] ||\n          $slots['row-1-col-2-tile-1'] ||\n          $slots['row-1-col-3-tile-1'] ||\n          $slots['row-1-col-4-tile-1']\n            ? 'pt-0'\n            : ''\n        \"\n      >\n        <v-row v-if=\"$slots['row-2-col-1-row-1-tile-1']\">\n          <v-col>\n            <slot name=\"row-2-col-1-row-1-tile-1\" />\n          </v-col>\n        </v-row>\n\n        <v-row v-if=\"$slots['row-2-col-1-row-2-tile-1']\">\n          <v-col>\n            <slot name=\"row-2-col-1-row-2-tile-1\" />\n          </v-col>\n        </v-row>\n\n        <v-row v-if=\"$slots['row-2-col-1-row-3-tile-1']\">\n          <v-col>\n            <slot name=\"row-2-col-1-row-3-tile-1\" />\n          </v-col>\n        </v-row>\n\n        <v-row v-if=\"$slots['row-2-col-1-row-4-tile-1']\">\n          <v-col\n            :class=\"{\n              'pt-1': $slots['row-0']\n            }\"\n          >\n            <slot name=\"row-2-col-1-row-4-tile-1\" />\n          </v-col>\n        </v-row>\n      </v-col>\n\n      <v-col\n        v-if=\"\n          $slots['row-2-col-2-row-1-tile-1'] ||\n            $slots['row-2-col-2-row-2-tile-1'] ||\n            $slots['row-2-col-2-row-2-tile-2'] ||\n            $slots['row-2-col-2-row-3-tile-1']\n        \"\n        cols=\"12\"\n        md=\"8\"\n        :class=\"\n          $slots['row-1-col-1-tile-1'] ||\n          $slots['row-1-col-2-tile-1'] ||\n          $slots['row-1-col-3-tile-1']\n            ? 'pt-0'\n            : ''\n        \"\n      >\n        <v-row v-if=\"$slots['row-2-col-2-row-1-tile-1']\" no-gutters>\n          <v-col>\n            <slot name=\"row-2-col-2-row-1-tile-1\" />\n          </v-col>\n        </v-row>\n\n        <v-row\n          v-if=\"\n            $slots['row-2-col-2-row-2-tile-1'] ||\n              $slots['row-2-col-2-row-2-tile-2']\n          \"\n        >\n          <v-col cols=\"12\" md=\"6\">\n            <slot name=\"row-2-col-2-row-2-tile-1\" />\n          </v-col>\n\n          <v-col cols=\"12\" md=\"6\">\n            <slot name=\"row-2-col-2-row-2-tile-2\" />\n          </v-col>\n        </v-row>\n\n        <v-row v-if=\"$slots['row-2-col-2-row-3-tile-1']\">\n          <v-col>\n            <slot name=\"row-2-col-2-row-3-tile-1\" />\n          </v-col>\n        </v-row>\n\n        <v-row>\n          <v-col v-for=\"slot in extendedSlots\" :key=\"slot\">\n            <slot :name=\"slot\" />\n          </v-col>\n        </v-row>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n"
  },
  {
    "path": "src/layouts/TutorialLayout.vue",
    "content": "<script>\nimport range from 'lodash/range'\n\nexport default {\n  props: {\n    stepCount: {\n      type: Number,\n      required: true\n    },\n    stepNumber: {\n      type: Number,\n      required: true\n    }\n  },\n  data() {\n    return {\n      furthestStep: 1\n    }\n  },\n  computed: {\n    stepRange() {\n      return range(1, this.stepCount + 1)\n    }\n  },\n  watch: {\n    stepNumber() {\n      if (this.stepNumber > this.furthestStep) {\n        this.furthestStep = this.stepNumber\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container class=\"fill-height mt-6\" fluid justify-center>\n    <v-layout align-content-start fill-height wrap style=\"max-width: 1440px;\">\n      <v-flex xs12>\n        <div class=\"text-h5 full-width mb-3\">\n          <slot name=\"title\"></slot>\n        </div>\n      </v-flex>\n\n      <v-flex xs12>\n        <p class=\"mb-3\">\n          <slot name=\"description\"></slot>\n        </p>\n      </v-flex>\n\n      <v-flex v-if=\"$slots.alert\" xs12>\n        <blockquote\n          class=\"blockquote blockquote-border-left mb-3 text-body-2 px-4 py-2\"\n        >\n          <slot name=\"alert\"></slot>\n        </blockquote>\n      </v-flex>\n\n      <v-flex xs12>\n        <v-container>\n          <v-row>\n            <v-stepper :value=\"stepNumber\" vertical class=\"full-width\">\n              <template v-for=\"step in stepRange\">\n                <v-stepper-step\n                  :key=\"`title-${step}`\"\n                  :complete=\"stepNumber > step\"\n                  :step=\"step\"\n                  :class=\"{ 'clickable-step': step <= furthestStep }\"\n                  class=\"text-h6 font-weight-light\"\n                  @click=\"$emit('step-click', step, furthestStep)\"\n                >\n                  <slot :name=\"`tutorial-step-${step}-title`\"></slot>\n                </v-stepper-step>\n\n                <v-stepper-content :key=\"`content-${step}`\" :step=\"step\">\n                  <v-card flat class=\"mb-6\">\n                    <v-card-text class=\"pa-0 text-body-1 black--text\">\n                      <slot :name=\"`tutorial-step-${step}-content`\"></slot>\n                    </v-card-text>\n                  </v-card>\n                </v-stepper-content>\n              </template>\n            </v-stepper>\n          </v-row>\n        </v-container>\n      </v-flex>\n    </v-layout>\n  </v-container>\n</template>\n\n<style lang=\"scss\">\n.blockquote-border-left {\n  border-left: 3px solid var(--v-primary-base);\n}\n\n.clickable-step {\n  cursor: pointer;\n\n  &:focus,\n  &:hover {\n    background-color: var(--v-secondaryGrayLight-base);\n  }\n\n  /* stylelint-disable selector-class-pattern */\n  .v-stepper__step__step {\n    background-color: var(--v-primary-base) !important;\n  }\n\n  .v-stepper__label {\n    color: var(--v-secondaryGrayDark-base) !important;\n    text-shadow: none !important;\n  }\n  /* stylelint-enable selector-class-pattern */\n}\n\n.full-width {\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/main.js",
    "content": "import '@/plugins/logrocket.js'\nimport { login, switchTenant, commitTokens, logout } from '@/auth/index.js'\nimport { CreatePrefectUI } from '@/app.js'\nimport store from '@/store'\nimport jwt_decode from 'jwt-decode'\nimport LogRocket from 'logrocket'\n\nexport const setStartupTenant = async () => {\n  const path = window.location.pathname\n  const split = path.split('/')\n  const slug = split?.[1]\n  const tenants = store.getters['tenant/tenants']\n  const slugTenant = tenants.find(t => t.slug == slug)\n\n  let tenant\n  if (process.env.VUE_APP_BACKEND === 'SERVER') {\n    if (slugTenant) tenant = slugTenant\n    else tenant = tenants[0]\n  } else {\n    const tokenTenantId = jwt_decode(store.getters['auth/authorizationToken'])\n      .tenant_id\n    const tokenTenant = tenants.find(t => t.id == tokenTenantId)\n    let needNewTokens = false\n\n    // If there's no slug in the URL or the token\n    // tenant matches the intended tenant, we can set the current tenant\n    // to the token tenant; if the token tenant is undefined,\n    // we fallback to the user's first tenant. If all of these fail,\n    // we redirect to a help screen cause the user can't create a tenant\n    // with this token atm\n    if (slugTenant) {\n      if (tokenTenant?.slug !== slug) needNewTokens = true\n      tenant = slugTenant\n    } else if (tokenTenant) {\n      tenant = tokenTenant\n    } else if (tenants?.[0]) {\n      tenant = tenants?.[0]\n      needNewTokens = true\n    } else {\n      // redirect to help screen\n      window.location.href = '/access-denied'\n    }\n\n    // We want to make sure the URL slug matches\n    // the tenant slug\n    if (slug && slug !== tenant.slug && slugTenant) {\n      window.history.pushState('', '', tenant.slug)\n    }\n\n    if (needNewTokens) {\n      const tokens = await switchTenant(tenant.id)\n      commitTokens(tokens)\n    }\n  }\n\n  tenant.role =\n    process.env.VUE_APP_BACKEND === 'CLOUD'\n      ? store.getters['user/memberships'].find(\n          membership => membership.tenant.id == tenant.id\n        )?.role_detail?.name\n      : 'TENANT_ADMIN'\n\n  store.commit('tenant/setTenant', tenant)\n\n  if (process.env.VUE_APP_BACKEND === 'CLOUD') {\n    await store.dispatch('license/getLicense')\n  }\n}\n\nconst timeout = async (main, fallback, fallbackargs, time) =>\n  Promise.race([main, new Promise((_r, rej) => setTimeout(rej, time))]).catch(\n    () => {\n      localStorage.setItem('prefect_fallback_auth', Date.now())\n      return fallback(...fallbackargs)\n    }\n  )\n\nlet loading = false\nexport const start = async () => {\n  if (\n    window.location.pathname?.includes('logout') ||\n    window.location.pathname?.includes('access-denied')\n  ) {\n    CreatePrefectUI()\n    return\n  }\n\n  const start0 = performance.now()\n  if (process.env.VUE_APP_BACKEND === 'CLOUD') {\n    // we run this when the application starts or a user returns to the page after some time away\n    // this logs into the default tenant so that we can fetch information we need\n    // if the user is requesting a different tenant (indicated by the URL),\n    // we swap out these tokens later\n    loading = true\n\n    let tokens\n\n    // We check local storage for a fallback token and compare it against\n    // the curent timestamp - 1 minute. If it falls outside that window\n    // we attempt the normal flow\n    const fallbackTimestamp = localStorage.getItem('prefect_fallback_auth')\n\n    // We coerce the timestamp because localstorage stores it as a string\n    if (fallbackTimestamp && +fallbackTimestamp > Date.now() - 60000) {\n      tokens = await login(true)\n    } else {\n      tokens = await timeout(login(), login, [true], 10000)\n    }\n\n    if (tokens) {\n      try {\n        LogRocket.track('Tokens', {\n          source: tokens.source || 'No source',\n          idTokenExpiration:\n            new Date(tokens.idToken?.expiresAt)?.toString() || 'No id token',\n          authorizationTokenExpiration:\n            tokens.authorizationTokens?.expires_at || 'No authorization token'\n        })\n      } catch (e) {\n        LogRocket.captureException(e)\n      }\n    } else return\n\n    commitTokens(tokens)\n\n    loading = false\n  } else {\n    // If we're on Server we fetch settings\n    window.prefect_ui_settings = await fetch('/settings.json')\n      .then(response => response.json())\n      .then(data => data)\n      .catch(e => e)\n  }\n\n  try {\n    // This is a good place to implement browser-side InnoDB or other caching\n    await Promise.all([\n      store.dispatch('user/getUser'),\n      store.dispatch('tenant/getTenants')\n    ])\n\n    await setStartupTenant()\n  } catch (e) {\n    // eslint-disable-next-line no-console\n    console.log(e)\n  }\n\n  const start1 = performance.now()\n\n  // eslint-disable-next-line no-console\n  console.log('Start total: ', start1 - start0)\n  LogRocket.track('Start', { timeToStart: start1 - start0 })\n  CreatePrefectUI()\n}\n\nstart()\n\n// ******************************************************************************************\n// Browser visibility API handler for auth\n// ******************************************************************************************\n\n// Visibility change properties vary between browsers\nlet hidden, visibilityChange\n\nconst handleVisibilityChange = async () => {\n  if (store.getters['api/isServer'] || loading) return\n\n  loading = true\n\n  if (!document[hidden]) {\n    if (\n      (!store.getters['auth/isAuthenticated'] ||\n        !store.getters['auth/isAuthorized']) &&\n      !window.location.pathname?.includes('logout') &&\n      !window.location.pathname?.includes('access-denied')\n    ) {\n      let tokens\n\n      // We check local storage for a fallback token and compare it against\n      // the curent timestamp - 1 minute. If it falls outside that window\n      // we attempt the normal flow\n      const fallbackTimestamp = localStorage.getItem('prefect_fallback_auth')\n\n      // We coerce the timestamp because localstorage stores it as a string\n      if (fallbackTimestamp && +fallbackTimestamp > Date.now() - 60000) {\n        tokens = await login(true)\n      } else {\n        tokens = await timeout(login(), login, [true], 10000)\n      }\n\n      if (tokens) commitTokens(tokens)\n      else logout()\n    }\n  }\n\n  loading = false\n}\n\nif (window) {\n  if (typeof document.hidden !== 'undefined') {\n    // Opera 12.10 and Firefox 18 and later\n    hidden = 'hidden'\n    visibilityChange = 'visibilitychange'\n  } else if (typeof document.msHidden !== 'undefined') {\n    hidden = 'msHidden'\n    visibilityChange = 'msvisibilitychange'\n  } else if (typeof document.webkitHidden !== 'undefined') {\n    hidden = 'webkitHidden'\n    visibilityChange = 'webkitvisibilitychange'\n  }\n  window.addEventListener(visibilityChange, handleVisibilityChange, false)\n}\n"
  },
  {
    "path": "src/middleware/flowNavGuard.js",
    "content": "import { fallbackApolloClient } from '@/vue-apollo'\nimport store from '@/store/index'\n\nconst flowNavGuard = async (to, from, next) => {\n  const id = to.params?.id\n  const flows = store.getters['data/flows']\n\n  const group = flows?.find(flow => flow.flow_group_id == id)\n\n  if (group) return next()\n\n  let version\n  try {\n    version = await fallbackApolloClient.query({\n      query: require('@/graphql/Middleware/flow.gql'),\n      variables: {\n        id: id\n      }\n    })\n  } catch {\n    return next({\n      name: 'not-found'\n    })\n  }\n\n  if (version?.data?.flow_by_pk?.flow_group_id) {\n    return next({\n      name: to.name,\n      params: { id: version.data.flow_by_pk.flow_group_id },\n      query: {\n        version: version.data.flow_by_pk.version,\n        ...to.query\n      }\n    })\n  }\n\n  try {\n    await store.dispatch('data/activateFlow', id)\n    const renewedFlows = store.getters['data/flows']\n    const renewedGroup = renewedFlows?.find(flow => flow.flow_group_id == id)\n    if (renewedGroup) return next()\n  } catch {\n    return next({\n      name: 'not-found'\n    })\n  }\n\n  return next({\n    name: 'not-found'\n  })\n}\n\nexport default flowNavGuard\n"
  },
  {
    "path": "src/middleware/prefectAuth.js",
    "content": "import { fallbackApolloClient } from '@/vue-apollo'\n\nconst prefectAuth = async idToken => {\n  try {\n    const result = await fallbackApolloClient.mutate({\n      mutation: require('@/graphql/log-in.gql'),\n      variables: {\n        input: { id_token: idToken }\n      },\n      errorPolicy: 'all'\n    })\n\n    if (result?.data?.log_in) {\n      return result.data.log_in\n    } else if (result?.errors) {\n      if (\n        result.errors[0].message ===\n        \"We get it, you're reeaally interested. Unfortunately, the timing isn't quite Prefect yet.\"\n      ) {\n        return null\n      } else {\n        throw new Error(result.errors[0].message)\n      }\n    }\n  } catch (error) {\n    throw new Error('Error authorizing prefectAuth', error)\n  }\n}\n\nconst prefectRefresh = async accessToken => {\n  try {\n    const result = await fallbackApolloClient.mutate({\n      mutation: require('@/graphql/refresh-token.gql'),\n      variables: {\n        input: { access_token: accessToken }\n      }\n    })\n\n    if (result?.data?.refresh_token) {\n      return result.data.refresh_token\n    } else if (result.error) {\n      throw new Error(result.error)\n    } else {\n      throw new Error('No token returned')\n    }\n  } catch (error) {\n    throw new Error('Error refreshing token in prefectRefresh', error)\n  }\n}\n\nconst prefectUser = async () => {\n  try {\n    const user = await fallbackApolloClient.query({\n      query: require('@/graphql/User/user.gql'),\n      fetchPolicy: 'no-cache'\n    })\n    return user.data.user[0]\n  } catch (error) {\n    throw new Error('Error retrieving user in prefectUser', error)\n  }\n}\n\nconst prefectTenants = async isCloud => {\n  const result = await fallbackApolloClient.query({\n    query: require('@/graphql/Tenant/tenants.js').default(isCloud),\n    fetchPolicy: 'no-cache'\n  })\n  return result.data.tenant\n}\n\nexport { prefectAuth, prefectRefresh, prefectUser, prefectTenants }\n"
  },
  {
    "path": "src/mixins/authMixin.js",
    "content": "import { OktaAuth } from '@okta/okta-auth-js'\nimport { mapActions } from 'vuex'\nconst { VUE_APP_PUBLIC_CLIENT_ID, VUE_APP_PUBLIC_ISSUER } = process.env\n\nconst authClient = new OktaAuth({\n  clientId: VUE_APP_PUBLIC_CLIENT_ID,\n  issuer: VUE_APP_PUBLIC_ISSUER,\n  redirectUri: window.location.origin,\n  scopes: ['openid', 'profile', 'email'],\n  responseType: 'token',\n  testing: {\n    disableHttpsCheck: true\n  }\n})\n\nexport const authMixin = {\n  data() {\n    return {\n      email: null,\n      error: null,\n      password: null\n    }\n  },\n  methods: {\n    ...mapActions('auth', ['authenticate']),\n    async checkSession() {\n      // const session = await authClient.session.exists()\n    },\n    async getSession() {\n      const sessionExists = await authClient.session.exists()\n\n      if (sessionExists) {\n        await this.getTokens()\n      }\n    },\n    async getTokens(sessionToken) {\n      const { tokens } = await authClient.token.getWithoutPrompt({\n        responseType: 'id_token',\n        sessionToken: sessionToken // this is optional depending on session cookies\n      })\n\n      this.authenticate(tokens)\n    },\n    async login() {\n      const { sessionToken } = await authClient.signInWithCredentials({\n        username: this.email,\n        password: this.password\n      })\n\n      await this.getTokens(sessionToken)\n\n      this.$router.push({ name: 'dashboard' })\n    },\n    loginWithGitHub() {},\n    loginWithGoogle() {}\n  }\n}\n"
  },
  {
    "path": "src/mixins/cancelLateRunsMixin.js",
    "content": "import gql from 'graphql-tag'\nimport { mapActions } from 'vuex'\n\nexport const cancelLateRunsMixin = {\n  data() {\n    return {\n      // Clearing late runs\n      clearLateRunsError: false,\n      isClearingLateRuns: false,\n      showClearLateRunsDialog: false,\n      individualRuns: [],\n      scheduledRunIds: []\n    }\n  },\n  watch: {\n    lateRuns() {\n      if (this.lateRuns?.length === 0 && this.isClearingLateRuns) {\n        this.isClearingLateRuns = false\n      }\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    handleOpenDialog() {\n      this.IdCheck()\n      this.showClearLateRunsDialog = true\n    },\n    IdCheck() {\n      return this.lateRuns?.map(run => {\n        if (run.flow?.is_schedule_active) {\n          this.scheduledRunIds.push(run.flow?.id)\n        } else {\n          this.individualRuns.push(run)\n        }\n      })\n    },\n    async runMutation(mutationType) {\n      const mutation = gql`\n          mutation CancelLateRuns {\n            ${mutationType}\n          }`\n\n      await this.$apollo.mutate({ mutation })\n    },\n    async clearLateRuns() {\n      try {\n        this.showClearLateRunsDialog = false\n        this.isClearingLateRuns = true\n        if (this.scheduledRunIds.length > 1) {\n          const uniqueIds = [...new Set(this.scheduledRunIds)]\n          const clearMutation = uniqueIds.map(\n            (id, ind) => `\n            set_schedule_inactive${ind}: set_schedule_inactive(input: { flow_id: \"${id}\" }) {\n              success,\n              error\n            }`\n          )\n          await this.runMutation(clearMutation)\n\n          const resetMutation = uniqueIds.map(\n            (id, ind) => `\n            set_schedule_active${ind}: set_schedule_active(input: { flow_id: \"${id}\" }) {\n              success,\n              error\n            }`\n          )\n\n          await this.runMutation(resetMutation)\n          // Cancel flow runs & task runs\n        }\n\n        // There's probably a better way to handle the JSON stringy conversion here.\n        if (this.individualRuns?.length > 0) {\n          const statesMutation = `\n            set_flow_run_states(\n              input: {\n                states: [${this.individualRuns.map(r => {\n                  return `{\n                    flow_run_id: \"${r.id}\",\n                    state: ${JSON.stringify(\n                      '{\"type\": \"Cancelled\",\"message\": \"This run was late and so was cancelled from the UI.\"}'\n                    )},\n                    version: ${r.version}\n                  }`\n                })}]\n              }\n            ) {\n              states {\n                status\n              }\n            }\n          `\n\n          // Build mutation to delete late flow runs.\n          await this.runMutation(statesMutation)\n        }\n\n        // Refetch upcoming flows\n        await this.$apollo.queries.upcoming.refetch()\n      } catch (error) {\n        this.clearLateRunsError = true\n        this.setAlert({\n          alertShow: true,\n          alertMessage:\n            'Something went wrong while trying to clear your late flow runs. Please try again later.',\n          alertType: 'error'\n        })\n        throw error\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/mixins/changeStateMixin.js",
    "content": "import { mapActions, mapGetters } from 'vuex'\n\nimport { FINISHED_STATES } from '@/utils/states'\n\nexport const changeStateMixin = {\n  props: {\n    taskRun: {\n      default: null,\n      type: Object\n    },\n    flowRun: {\n      default: null,\n      type: Object\n    },\n    dialogType: {\n      required: true,\n      type: String\n    }\n  },\n  data() {\n    return {\n      setStateDialog: false,\n      markAsLoading: false,\n      resumeLoad: '',\n      reason: '',\n      e1: 1,\n      formError: false,\n      name: 'PrefectUIRunMarkAsButton',\n      setStateError: false,\n      selectedState: '',\n      allTasks: false,\n      cancelLoad: false,\n      setStateSuccessA: false,\n      setStateSuccessB: false,\n      taskRunApproved: false,\n      alertMessage: 'We hit a problem.  Please try marking the state again.',\n      taskStates: [\n        { header: 'Finished States' },\n        { divider: '...' },\n        'Failed',\n        'Success',\n        'Cancelled',\n        'Finished',\n        'TimedOut',\n        { header: 'Scheduled States - To Re-run Task Run' },\n        { divider: '...' },\n        'Scheduled',\n        'Resume',\n        { header: 'Pending - to clear the state' },\n        { divider: '...' },\n        'Pending'\n      ],\n      flowStates: [\n        { header: 'Finished States' },\n        { divider: '...' },\n        'Failed',\n        'Success',\n        'Cancelled',\n        'Finished',\n        { header: 'Scheduled - To Re-run Flow Run' },\n        { divider: '...' },\n        'Scheduled'\n      ]\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['user']),\n    ...mapGetters('license', ['hasPermission']),\n    activeButton() {\n      return this.hasPermission('update', 'run')\n    },\n    isFinished() {\n      return FINISHED_STATES.includes(this.flowRun.state)\n    },\n    isFinishing() {\n      return (\n        this.flowRun.state == 'Cancelling' ||\n        FINISHED_STATES.includes(this.flowRun.state)\n      )\n    },\n    filteredStates() {\n      if (this.dialogType === 'task run') {\n        return this.taskStates.filter(state => state !== this.taskRun.state)\n      } else {\n        return this.flowStates.filter(state => state !== this.flowRun.state)\n      }\n    },\n    checkVersion() {\n      let split = this.flowRun?.flow?.core_version.split('.')\n\n      let major = parseInt(split[0]),\n        minor = parseInt(split[1]),\n        patch = parseInt(split[2])\n\n      return major >= 1 || (minor >= 13 && patch >= 0)\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    runLogMessage() {\n      if (this.dialogType == 'resume') {\n        return `Task ${this.taskRun.task.name} approved by ${this.user.username}`\n      } else if (this.reason) {\n        return `${this.user.username || 'User'} marked ${this.dialogType} as ${\n          this.selectedState\n        } because \"${this.reason}\"`\n      } else {\n        return `${this.user.username || 'User'} marked ${this.dialogType} \n        as ${this.selectedState}`\n      }\n    },\n    async writeLogs() {\n      const { data } = await this.$apollo.mutate({\n        mutation: require('@/graphql/Update/write-run-logs.gql'),\n        variables: {\n          flowRunId: this.taskRun ? this.taskRun.flow_run?.id : this.flowRun.id,\n          taskRunId: this.taskRun ? this.taskRun.id : null,\n          name: this.name,\n          message: this.runLogMessage()\n        }\n      })\n      return data?.write_run_logs?.success\n    },\n    resumeRun() {\n      this.resumeLoad = this.taskRun.id\n      this.selectedState = 'Resume'\n      this.alertMessage =\n        'An error occurred when approving this task run. Please try again.'\n      this.changeState()\n    },\n    async cancelFlowRun() {\n      this.cancelLoad = true\n      this.selectedState = 'Cancelled'\n      this.allTasks = true\n\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/FlowRun/cancel-flow-run.gql'),\n          variables: {\n            flowRunId: this.flowRun.id\n          }\n        })\n\n        this.setAlert({\n          alertShow: true,\n          alertMessage:\n            'Your flow run will be cancelled; please allow some time for this to take effect.',\n          alertType: 'success'\n        })\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage:\n            'Something went wrong when trying to cancel this flow run, please try again.',\n          alertType: 'error'\n        })\n      }\n\n      this.$emit('update')\n\n      this.cancelLoad = false\n    },\n    async changeState() {\n      try {\n        //make sure we get the lastest version of each task run\n        this.markAsLoading = true\n        if (this.allTasks) await this.$apollo.queries.taskRunIds.refetch()\n        const logSuccess = this.writeLogs()\n        if (logSuccess) {\n          if (\n            this.dialogType === 'task run' ||\n            this.dialogType == 'resume' ||\n            (this.allTasks && this.taskRunIds?.length)\n          ) {\n            let taskState\n            if (this.dialogType === 'task run' || this.dialogType == 'resume') {\n              taskState = {\n                task_run_id: this.taskRun.id,\n                version: this.taskRun.version,\n                state: {\n                  type: this.selectedState,\n                  message: this.runLogMessage()\n                }\n              }\n            } else {\n              taskState = this.taskRunIds.map(taskRun => {\n                return {\n                  version: taskRun.version,\n                  task_run_id: taskRun.id,\n                  state: {\n                    type: this.selectedState,\n                    message: this.runLogMessage()\n                  }\n                }\n              })\n            }\n            const result = await this.$apollo.mutate({\n              mutation: require('@/graphql/TaskRun/set-task-run-states.gql'),\n              variables: {\n                input: taskState\n              }\n            })\n            this.setStateSuccessA =\n              result?.data?.set_task_run_states?.states?.length\n            if (!this.setStateSuccessA) {\n              this.setStateError = true\n            }\n            if (this.setStateSuccessA && this.dialogType == 'resume') {\n              this.taskRunApproved = true\n            }\n          }\n          if (this.dialogType === 'flow run') {\n            const result = await this.$apollo.mutate({\n              mutation: require('@/graphql/TaskRun/set-flow-run-states.gql'),\n              variables: {\n                flowRunId: this.flowRun.id,\n                version: this.flowRun.version,\n                state: {\n                  type: this.selectedState,\n                  message: this.runLogMessage()\n                }\n              }\n            })\n            this.setStateSuccessB =\n              result?.data?.set_flow_run_states?.states?.length\n            if (!this.setStateSuccessB) {\n              this.setStateError = true\n            }\n          }\n        } else {\n          this.setStateError = true\n        }\n      } catch (error) {\n        this.setStateError = true\n      }\n      if (this.setStateError) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: this.alertMessage,\n          alertType: 'error'\n        })\n      }\n      if (\n        this.setStateSuccessA &&\n        this.setStateSuccessB &&\n        this.cancelLoad &&\n        !this.setStateError\n      ) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage:\n            'Your flow run will be cancelled; please allow some time for this to take effect.',\n          alertType: 'success'\n        })\n      }\n      if (this.setStateSuccessA && this.childTasks) {\n        this.setAllTaskRuns(this.selectedState)\n      }\n      setTimeout(() => this.reset(), 500)\n      this.$emit('update')\n    },\n    async setAllTaskRuns(type) {\n      try {\n        const { data } = await this.$apollo.query({\n          query: require('@/graphql/FlowRun/task-run-ids.gql'),\n          variables: {\n            flowRunId: this.flowRun.id,\n            parentMapIndex: null,\n            childMapIndex: -1\n          }\n        })\n        const taskState = data.task_run.map(taskRun => {\n          return {\n            version: taskRun.version,\n            task_run_id: taskRun.id,\n            state: {\n              type: type,\n              message: this.runLogMessage()\n            }\n          }\n        })\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/TaskRun/set-task-run-states.gql'),\n          variables: {\n            input: taskState\n          }\n        })\n        this.childTasks = false\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage:\n            'An error occured setting the state of mapped task runs',\n          alertType: 'error'\n        })\n      }\n      this.$emit('update')\n    },\n    checkContinue() {\n      if (this.selectedState) {\n        this.e1 = 2\n      }\n    },\n    reset() {\n      this.setStateDialog = false\n      this.markAsLoading = false\n      this.reason = ''\n      this.form = false\n      this.setStateError = false\n      this.e1 = 1\n      this.selectedState = ''\n      this.allTasks = false\n      this.cancelLoad = false\n      this.alertMessage =\n        'We hit a problem. Please try marking the state again.'\n\n      this.setStateSuccessA = false\n      this.setStateSuccessB = false\n      this.cancelLoad = false\n      this.resumeLoad = ''\n    }\n  }\n}\n"
  },
  {
    "path": "src/mixins/cloudHookMixin.js",
    "content": "import {\n  openCloudHookTypes,\n  featureFlaggedCloudHookTypes,\n  GROUP_COLORS,\n  STATES\n} from '@/utils/cloudHooks'\nimport LogRocket from 'logrocket'\nimport { mapGetters } from 'vuex'\n\nexport const cloudHookMixin = {\n  data() {\n    return {\n      createNewCloudHook: false,\n      error: {\n        createCloudHook: null\n      },\n      loading: {\n        createCloudHook: false\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    cloudHookTypes() {\n      if (this.tenant.prefectAdminSettings?.notifications)\n        return featureFlaggedCloudHookTypes\n      return openCloudHookTypes\n    }\n  },\n  methods: {\n    async _handleSetCloudHookStatusChange(val, item) {\n      item.loading = true\n\n      try {\n        const updateCloudHookStatus = !val\n          ? await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/set-cloud-hook-inactive.gql'),\n              variables: {\n                input: {\n                  cloud_hook_id: item.id\n                }\n              },\n              errorPolicy: 'all'\n            })\n          : await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/set-cloud-hook-active.gql'),\n              variables: {\n                input: {\n                  cloud_hook_id: item.id\n                }\n              },\n              errorPolicy: 'all'\n            })\n\n        setTimeout(() => {\n          let status = updateCloudHookStatus.data\n            ? updateCloudHookStatus.data.setCloudHookActive ||\n              updateCloudHookStatus.data.setCloudHookInactive ||\n              updateCloudHookStatus.data.set_cloud_hook_active ||\n              updateCloudHookStatus.data.set_cloud_hook_inactive\n            : false\n\n          if (!status || !status.success) {\n            item.loading = false\n          } else {\n            this.$apollo.queries.cloudHooks.refetch()\n            item.loading = false\n          }\n        }, 500)\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Settings',\n            stage: 'Cloud Hook Status Update'\n          }\n        })\n\n        item.loading = false\n      }\n    },\n    stateGroup(states) {\n      if (this.stateGroupAll(states)) return 'All'\n      if (this.stateGroupFailed(states)) return 'Failed'\n      if (this.stateGroupFinished(states)) return 'Finished'\n      if (this.stateGroupSuccess(states)) return 'Success'\n      return 'Custom'\n    },\n    stateGroupAll(states) {\n      return this.cloudHookStateGroup('All', states)\n    },\n    stateGroupFailed(states) {\n      return this.cloudHookStateGroup('Failed', states)\n    },\n    stateGroupFinished(states) {\n      return this.cloudHookStateGroup('Finished', states)\n    },\n    stateGroupSuccess(states) {\n      return this.cloudHookStateGroup('Success', states)\n    },\n    stateGroupColor(group) {\n      return GROUP_COLORS[group]\n    },\n    typeIcon(type) {\n      const hook = this.cloudHookTypes.find(t => t.type == type)\n      if (hook) return hook.icon\n      return ''\n    },\n    typeTitle(type) {\n      const hook = this.cloudHookTypes.find(t => t.type == type)\n      if (hook) return hook.title\n      return type.toLowerCase()\n    },\n    cloudHookStateGroup(group, states) {\n      return (\n        STATES[group] &&\n        STATES[group].every(state => states?.includes(state)) &&\n        STATES[group].length == states.length\n      )\n    }\n  }\n}\n"
  },
  {
    "path": "src/mixins/eventsMixin.js",
    "content": "const expectedEvent = [\n  'ArrowUp',\n  'ArrowUp',\n  'ArrowDown',\n  'ArrowDown',\n  'ArrowLeft',\n  'ArrowRight',\n  'ArrowLeft',\n  'ArrowRight',\n  'b',\n  'a'\n]\n\nexport const eventsMixin = {\n  data() {\n    return {\n      sequence: []\n    }\n  },\n  created() {\n    document.addEventListener('keydown', this.handleEvent)\n  },\n  beforeDestroy() {\n    document.removeEventListener('keydown', this.handleEvent)\n  },\n  methods: {\n    checkSequence() {\n      for (let i = 0; i < this.sequence.length; ++i) {\n        let key = this.sequence[i]\n        if (key !== expectedEvent[i]) {\n          this.sequence = []\n          break\n        }\n\n        if (i == expectedEvent.length - 1) {\n          this.sequence = []\n          this.handleSequenceSuccess()\n        }\n      }\n    },\n    handleEvent(e) {\n      this.sequence.push(e?.key)\n      this.checkSequence()\n    },\n    handleSequenceSuccess() {\n      const app = document.getElementById('app')\n\n      app.classList.add('roll')\n\n      setTimeout(() => {\n        app.classList.remove('roll')\n      }, 5000)\n    }\n  }\n}\n"
  },
  {
    "path": "src/mixins/flowRunHistoryMixin.js",
    "content": "import { mapGetters } from 'vuex'\nimport moment from 'moment'\n\nexport const flowRunHistoryMixin = {\n  data() {\n    return {\n      flowRuns: [],\n      scheduledFlowRuns: [],\n      tooltip: null,\n      tooltipLoading: false,\n      unwatchFlowRuns: null\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone']),\n    ...mapGetters('tenant', ['tenant']),\n    breaklines() {\n      if (this.reversedRuns.length <= 0) return []\n      let breaklines = []\n\n      let cutoff = null,\n        index = 0\n      this.reversedRuns.forEach((d, i) => {\n        let future =\n          d.state == 'Scheduled'\n            ? this.getTimeDiff(d.scheduled_start_time)._milliseconds <= 0\n            : null\n\n        if (future && !cutoff) {\n          cutoff = d.id\n          index = i\n        }\n      })\n      let anchor =\n        index > 4 && index < 98 ? 'middle' : index < 98 ? 'start' : 'end'\n\n      if (cutoff)\n        breaklines.push({\n          label: '(now)',\n          value: cutoff,\n          anchor: anchor\n        })\n\n      if (!cutoff) {\n        let lastIndex = this.reversedRuns.length - 1\n        breaklines.push({\n          label: this.getTimeFrom(\n            this.reversedRuns[lastIndex].start_time ||\n              this.reversedRuns[lastIndex].scheduled_start_time\n          ),\n          value: this.reversedRuns[lastIndex].id,\n          after: true,\n          anchor: lastIndex > 98 ? 'end' : 'middle'\n        })\n\n        if (this.reversedRuns.length > 4) {\n          breaklines.push({\n            label: this.getTimeFrom(\n              this.reversedRuns[0].start_time ||\n                this.reversedRuns[0].scheduled_start_time\n            ),\n            value: this.reversedRuns[0].id,\n            anchor: 'start'\n          })\n        }\n      } else if (this.reversedRuns.length > 4) {\n        breaklines.push({\n          label: this.getTimeFrom(\n            this.reversedRuns[0].start_time ||\n              this.reversedRuns[0].scheduled_start_time\n          ),\n          value: this.reversedRuns[0].id,\n          anchor: 'start'\n        })\n      }\n\n      return breaklines\n    },\n    canShowTooltip() {\n      return (\n        this.tooltip &&\n        this.reversedRuns.find(f => f.id == this.tooltip.data.id)\n      )\n    },\n    reversedRuns() {\n      let runs = [...this.scheduledFlowRuns, ...this.flowRuns]\n\n      const computedStyle = getComputedStyle(document.documentElement)\n\n      const notPastRunStates = [\n        'Running',\n        'Scheduled',\n        'Queued',\n        'Paused',\n        'Submitted'\n      ]\n\n      runs.forEach(d => {\n        let future = this.getTimeDiff(d.scheduled_start_time)._milliseconds\n\n        if (d.start_time && d.end_time) {\n          let end = new Date(d.end_time),\n            start = new Date(d.start_time)\n          d.duration = end - start\n        } else if (d.start_time && notPastRunStates.includes(d.state)) {\n          let now = new Date(),\n            start = new Date(d.start_time)\n          d.duration = now - start\n        }\n\n        // We add a filler end_time for instances where a finished\n        // state has been set but the PG trigger to populate end_time\n        // hasn't run yet\n        if (\n          !d.end_time &&\n          d.start_time &&\n          !notPastRunStates.includes(d.state) &&\n          d.state !== 'Skipped'\n        ) {\n          d.end_time = new Date()\n        }\n\n        d.finished = !notPastRunStates.includes(d.state)\n\n        // We do the same for running flows without start_time\n        if (!d.start_time && d.state == 'Running') {\n          d.start_time = new Date()\n        }\n\n        d.ignore = d.state == 'Scheduled'\n\n        d.color = computedStyle?.getPropertyValue(`--v-${d.state}-base`)\n\n        d.usePattern = d.state == 'Scheduled' && future <= 0\n\n        d.warningOpacity =\n          d.state !== 'Scheduled' || d.start_time || future <= 10000 ? 0 : 1\n      })\n\n      const pastRuns = runs\n        .filter(r => !notPastRunStates.includes(r.state))\n        .sort(this.sortTime('end_time', 'scheduled_start_time'))\n\n      const currentRuns = runs\n        .filter(r => r.state == 'Running' || r.state == 'Paused')\n        .sort(this.sortTime('start_time'))\n\n      const futureRuns = runs\n        .filter(r => r.state == 'Scheduled')\n        .sort(this.sortTime('scheduled_start_time'))\n\n      const queuedRuns = runs\n        .filter(r => r.state == 'Queued' || r.state == 'Submitted')\n        .sort(this.sortTime('scheduled_start_time'))\n\n      // We have to sort again because the server-side sorting\n      // is unstable\n      const toReturn = [\n        ...pastRuns,\n        ...currentRuns,\n        ...queuedRuns,\n        ...futureRuns\n      ]\n\n      return toReturn\n    }\n  },\n  methods: {\n    _barMouseout() {\n      this.setTooltip(null)\n      this.tooltipLoading = false\n    },\n    async _barMouseover(tooltipData) {\n      this.setTooltip(tooltipData)\n      this.checkFormatTime(tooltipData, 'end_time')\n      this.checkFormatTime(tooltipData, 'start_time')\n      this.checkFormatTime(tooltipData, 'scheduled_start_time')\n\n      tooltipData.status_style = this.statusStyle(tooltipData.data.state)\n\n      const flowId = tooltipData.data.flow_id\n      if (!flowId) {\n        this.setTooltip(tooltipData)\n        return\n      }\n\n      try {\n        this.tooltipLoading = true\n\n        const { data } = await this.$apollo.query({\n          query: require('@/graphql/Dashboard/timeline-flow.gql'),\n          variables: { flowId }\n        })\n\n        tooltipData.data.flow = data.flow_by_pk\n      } finally {\n        this.tooltipLoading = false\n\n        // We check this to make sure we're not showing the tooltip\n        // when _barMouseout has already run or a different\n        // bar has been hovered\n        if (this.tooltip && this.tooltip.data.flow_id == flowId)\n          this.setTooltip(tooltipData)\n      }\n    },\n    _barClick(d) {\n      this.$router.push({\n        name: 'flow-run',\n        params: {\n          id: d.id,\n          tenant: this.tenant?.slug\n        }\n      })\n    },\n    formatTime(timestamp) {\n      if (!timestamp) throw new Error('Did not receive a timestamp')\n\n      let t = moment(timestamp).tz(this.timezone),\n        shortenedTz = moment()\n          .tz(this.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone)\n          .zoneAbbr()\n\n      let timeObj = t ? t : moment(timestamp)\n\n      let formatted = timeObj.calendar(null, {\n        sameDay: 'h:mma',\n        sameElse: 'MMMM D, YYYY [at] h:mma'\n      })\n      return `${formatted} ${shortenedTz}`\n    },\n    getTimeDiff(time) {\n      let now, start\n      if (this.timezone) {\n        now = new moment().tz(this.timezone)\n        start = moment(time).tz(this.timezone)\n      } else {\n        now = new moment()\n        start = moment(time)\n      }\n      let diff = moment.duration(now.diff(start))\n\n      return diff\n    },\n    getTimeFrom(time) {\n      let now, _time\n      if (this.timezone) {\n        now = new moment().tz(this.timezone)\n        _time = moment(time).tz(this.timezone)\n      } else {\n        now = new moment()\n        _time = moment(time)\n      }\n\n      return _time.from(now)\n    },\n    sortTime(ref, secondaryRef) {\n      return function(a, b) {\n        return (\n          new Date(a[ref] || a[secondaryRef]) -\n          new Date(b[ref] || b[secondaryRef])\n        )\n      }\n    },\n    statusStyle(state) {\n      return {\n        'border-radius': '50%',\n        display: 'inline-block',\n        'background-color': `var(--v-${state}-base)`,\n        height: '1rem',\n        width: '1rem'\n      }\n    },\n    setTooltip(tooltip) {\n      if (this.unwatchFlowRuns) {\n        this.unwatchFlowRuns()\n      }\n\n      if (tooltip) {\n        this.unwatchFlowRuns = this.$watch(\n          'flowRuns',\n          this.validateTooltipIdStillPresent\n        )\n      }\n\n      this.tooltip = tooltip\n    },\n    validateTooltipIdStillPresent() {\n      const exists = this.flowRuns.some(f => f.id == this.tooltip.data.id)\n\n      if (!exists) {\n        this.setTooltip(null)\n      }\n    },\n    checkFormatTime(tooltipData, property) {\n      if (tooltipData.data[property]) {\n        const formatted = this.formatTime(tooltipData.data[property])\n\n        tooltipData.data[`display_${property}`] = formatted\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/mixins/formatTimeMixin.js",
    "content": "import moment from '@/utils/moment'\nimport { mapGetters } from 'vuex'\n\nexport const formatTime = {\n  data() {\n    return {\n      dateFilters: [\n        { name: '1 Hour', value: 'hour' },\n        { name: '24 Hours', value: 'day' },\n        { name: '7 Days', value: 'week' },\n        { name: '30 Days', value: 'month' }\n      ],\n      // querying failures for over 24 hours either goes into endless loading or returns a 504 so shortening for now\n      shortDateFilters: [\n        { name: '1 Hour', value: 'hour' },\n        { name: '24 Hours', value: 'day' },\n        { name: '7 Days', value: 'week' }\n      ],\n      selectedDateFilter: 'day'\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['user', 'timezone'])\n  },\n  methods: {\n    dateDiff(date1, date2) {\n      const a = moment(date1)\n      const b = moment(date2)\n      return b.diff(a, 'days')\n    },\n    datePartHour(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${timeObj ? timeObj.format('h') : moment(timestamp).format('h')}`\n    },\n    datePartMinute(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${\n        timeObj ? timeObj.format('mm') : moment(timestamp).format('mm')\n      }`\n    },\n    datePartMeridian(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${timeObj ? timeObj.format('a') : moment(timestamp).format('a')}`\n    },\n    dateParts(timestamp) {\n      if (!timestamp) {\n        return\n      }\n\n      const timeObj = moment(timestamp).tz(this.timezone) ?? moment(timestamp)\n\n      return {\n        hour: timeObj.format('h'),\n        minute: timeObj.format('mm'),\n        meridian: timeObj.format('a')\n      }\n    },\n    formatTimeRelative(timestamp) {\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return timeObj ? timeObj.fromNow() : moment(timestamp).fromNow()\n    },\n    formatDate(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${\n        timeObj\n          ? timeObj.format('DD/MM/YY')\n          : moment(timestamp).format('DD/MM/YY')\n      }`\n    },\n    formatCalendarDate(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      const date = `${\n        timeObj\n          ? timeObj.format('YYYY-MM-DD')\n          : moment(timestamp).format('YYYY-MM-DD')\n      }`\n      return date\n    },\n    getHour(timestamp) {\n      let timeObj = moment(timestamp).tz(this.timezone) || moment(timestamp)\n      return timeObj.format('HH')\n    },\n    formatCalendarTime(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone) || moment(timestamp)\n      //Bit of a hack here to make sure that we have timezone but also get the time in milliseconds\n      const updated = timeObj.format('YYYY-MM-DD HH:mm:ss')\n      return moment(updated).valueOf()\n    },\n    convertCalendarStartTime(timestamp) {\n      const startTime = moment(timestamp).tz(this.timezone) || moment(timestamp)\n      const start = startTime.startOf('day').toISOString()\n      return start\n    },\n    addTime(timestamp, amount, unit) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone) || moment(timestamp)\n      return timeObj.add(amount, unit).format('YYYY-MM-DD HH:mm:ss')\n    },\n    addTimeNoTz(timestamp, amount, unit) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp)\n      return timeObj.add(amount, unit).format('YYYY-MM-DD HH:mm:ss')\n    },\n    getMonth(timestamp) {\n      return moment(timestamp).format('MMMM YYYY')\n    },\n    addDay(timestamp, amount) {\n      if (!timestamp) return\n      const timeObj = moment(timestamp).tz(this.timezone) || moment(timestamp)\n      return timeObj\n        .add(amount, 'days')\n        .startOf('day')\n        .toISOString()\n    },\n    subtractDay(timestamp, amount) {\n      if (!timestamp) return\n      const timeObj = moment(timestamp).tz(this.timezone) || moment(timestamp)\n      const day = timeObj\n        .subtract(amount, 'days')\n        .startOf('day')\n        .toISOString()\n      return day\n    },\n    shortTime(timestamp) {\n      if (!timestamp) return\n      let t = moment(timestamp).tz(this.timezone)\n\n      let timeObj = t ? t : moment(timestamp)\n\n      let formatted = timeObj.calendar(null, {\n        sameDay: 'h:mma',\n        nextDay: 'D MMM ',\n        nextWeek: 'D MMM ',\n        lastDay: 'D MMM ',\n        lastWeek: 'D MMM ',\n        sameElse: 'D MMM '\n      })\n      return `${formatted}`\n    },\n    formDate(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${\n        timeObj\n          ? timeObj.format('D MMM YYYY h:mma')\n          : moment(timestamp).format('D MMM YYYY h:mma')\n      }`\n    },\n    formTimeNoTimeZone(timestamp) {\n      if (!timestamp) return\n      return moment(timestamp).format('hh:mma')\n    },\n    formTime(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${\n        timeObj ? timeObj.format('hh:mma') : moment(timestamp).format('hh:mma')\n      }`\n    },\n    tzOffset(date) {\n      const zone = moment.tz.zone(this.timezone)\n      const offset =\n        zone?.parse(Date.UTC(date)) || new Date().getTimezoneOffset()\n      return offset\n    },\n    calEventTime(timestamp, date) {\n      if (!timestamp) return\n      let t = moment(timestamp).tz(this.timezone)\n\n      let timeObj = t ? t : moment(timestamp)\n\n      let formatted = timeObj.calendar(date, {\n        sameDay: 'h:mma',\n        nextDay: 'D MMM h:mma',\n        nextWeek: 'D MMM',\n        lastDay: 'D MMM h: mma',\n        lastWeek: 'D MMM ',\n        sameElse: 'D MMM '\n      })\n      return `${formatted}`\n    },\n    logTime(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${\n        timeObj\n          ? timeObj.format('HH:mm:ss')\n          : moment(timestamp).format('HH:mm:ss')\n      }`\n    },\n    logTimeExtended(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${\n        timeObj\n          ? timeObj.format('HH:mm:ss:SS')\n          : moment(timestamp).format('HH:mm:ss:SS')\n      }`\n    },\n    logDate(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${\n        timeObj\n          ? timeObj.format('D MMMM YYYY h:mma')\n          : moment(timestamp).format('D MMMM YYYY h:mma')\n      }`\n    },\n    formatTime(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${\n        timeObj\n          ? timeObj.format('D MMMM YYYY h:mma')\n          : moment(timestamp).format('D MMMM YYYY h:mma')\n      }`\n    },\n    formatTimeGranular(timestamp) {\n      if (!timestamp) return\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return `${\n        timeObj\n          ? timeObj.format('h:mm:ss A')\n          : moment(timestamp).format('h:mm:ss A')\n      }`\n    },\n    formatDateTime(timestamp) {\n      if (!timestamp) return\n\n      let t = moment(timestamp).tz(this.timezone),\n        shortenedTz = moment()\n          .tz(this.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone)\n          .zoneAbbr()\n\n      let timeObj = t ? t : moment(timestamp)\n\n      let formatted = timeObj.calendar(null, {\n        sameDay: 'h:mma',\n        sameElse: 'MMMM D, YYYY [at] h:mma'\n      })\n      return `${formatted} ${shortenedTz}`\n    },\n    formatLongDate(timestamp) {\n      if (!timestamp) return\n\n      let t = moment(timestamp).tz(this.timezone)\n      let timeObj = t ? t : moment(timestamp)\n\n      let formatted = timeObj.calendar(null, {\n        sameDay: '[today]',\n        sameElse: 'MMMM D, YYYY'\n      })\n      return formatted\n    },\n    formatDateTimeFromUTC(timestamp, timezone) {\n      if (!timestamp) return\n\n      let timeObj = moment.tz(timestamp, timezone)\n\n      let formatted = timeObj.calendar(null, {\n        sameDay: 'h:mma z',\n        sameElse: 'MMMM D, YYYY [at] h:mma z'\n      })\n      return formatted\n    }\n  }\n}\n"
  },
  {
    "path": "src/mixins/heartbeatMixin.js",
    "content": "import { STATE_NAMES } from '@/utils/states.js'\n\nexport const heartbeatMixin = {\n  data() {\n    return { state: 'All', stateNames: STATE_NAMES, stateList: [] }\n  },\n  computed: {\n    checkedState() {\n      if (this.state === 'All') return null\n      if (!this.state) return null\n      return this.state\n    },\n    states() {\n      return this.stateNames.filter(name => name !== 'Scheduled').sort()\n    }\n  },\n  methods: {}\n}\n"
  },
  {
    "path": "src/mixins/membershipInvitationMixin.js",
    "content": "export const handleMembershipInvitations = {\n  methods: {\n    async acceptMembershipInvitation(id) {\n      const { data } = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tenant/accept-membership-invitation.gql'),\n        variables: {\n          membershipInvitationId: id\n        }\n      })\n      return data\n    },\n    async declineMembershipInvitation(id) {\n      const { data } = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tenant/delete-membership-invitation.gql'),\n        variables: {\n          membershipInvitationId: id\n        }\n      })\n      return data\n    }\n  }\n}\n"
  },
  {
    "path": "src/mixins/parametersMixin.js",
    "content": "import { mapGetters, mapActions } from 'vuex'\nimport { formatJson } from '@/utils/json'\nimport difference from 'lodash/difference'\n\nexport const parametersMixin = {\n  props: {\n    flowGroup: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      loading: false,\n      flowParameters: [],\n      newParameterInput: null,\n      extraParameters: [],\n      missingRequiredParameters: []\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['hasPermission']),\n    parameterInput: {\n      get() {\n        return this.newParameterInput\n      },\n      set(val) {\n        this.newParameterInput = val\n      }\n    },\n    requiredParameters() {\n      return this.selectedFlow.parameters.reduce((accum, currentParam) => {\n        if (currentParam.required) accum.push(currentParam.name)\n        return accum\n      }, [])\n    },\n    permissionsCheck() {\n      return !this.hasPermission('update', 'run')\n    },\n    selectedFlow() {\n      return this.flow || this.flowGroup.flows.find(flow => !flow.archived)\n    },\n    flowGroupParameters() {\n      const fgParamObjArray = []\n      for (const [key, value] of Object.entries(\n        this.flowGroup?.default_parameters\n      )) {\n        fgParamObjArray.push({ name: key, default: value })\n      }\n      return fgParamObjArray\n    },\n    selectedFlowParameters() {\n      return this.selectedFlow.parameters.reduce((accum, currentParam) => {\n        accum[currentParam.name] = currentParam.default\n        return accum\n      }, {})\n    },\n    diffBetweenFlowGroupAndFlow() {\n      const fgParams = this.flowGroup?.default_parameters\n      const selectedFlowParams = this.selectedFlowParameters\n      const diff = difference(\n        Object.keys(selectedFlowParams),\n        Object.keys(fgParams)\n      )\n      return diff\n    },\n    defaultParameters() {\n      const fgParams = this.flowGroup?.default_parameters\n      const selectedFlowParams = this.selectedFlowParameters\n      this.diffBetweenFlowGroupAndFlow.forEach(\n        differentKey =>\n          (fgParams[differentKey] = selectedFlowParams[differentKey])\n      )\n      const paramifiedArray = []\n      for (const [key, value] of Object.entries(fgParams)) {\n        const required =\n          this.selectedFlow?.parameters.filter(\n            paramObj => paramObj.name == key && paramObj.required\n          ).length > 0\n        paramifiedArray.push({\n          name: key,\n          default: value,\n          required: required\n        })\n      }\n      const sorted = paramifiedArray.sort((a, b) => {\n        return a.name > b.name ? 1 : -1\n      })\n      return sorted\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    setParameterInput() {\n      this.parameterInput = formatJson(this.flowGroup.default_parameters)\n    },\n    validateParameters() {\n      this.extraParameters = []\n      this.missingRequiredParameters = []\n      if (!this.$refs.parameterRef) {\n        return true\n      }\n      // Check JSON using the JsonInput component's validation\n      const jsonValidationResult = Array.isArray(this.$refs.parameterRef)\n        ? this.$refs.parameterRef[0].validateJson()\n        : this.$refs.parameterRef.validateJson()\n      if (jsonValidationResult === 'SyntaxError') {\n        this.errorInParameterInput = true\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `There is a syntax error in your flow parameters JSON.\n          Please correct the error and try again.`,\n          alertType: 'error'\n        })\n\n        return false\n      }\n      if (jsonValidationResult === 'MissingError') {\n        this.errorInParameterInput = true\n        this.setAlert({\n          alertShow: true,\n          alertMessage: 'Please enter your flow parameters as a JSON object.',\n          alertType: 'error'\n        })\n        return false\n      }\n\n      const parameters = JSON.parse(\n        this.newParameterInput || this.parameterInput\n      )\n      // Collect any missing required parameters\n      this.missingRequiredParameters = difference(\n        this.requiredParameters,\n        Object.keys(parameters)\n      )\n      // Collect any extra parameters.\n      this.extraParameters = difference(\n        Object.keys(parameters),\n        this.selectedFlow.parameters.map(param => param.name)\n      )\n      if (\n        this.missingRequiredParameters.length === 0 &&\n        this.extraParameters.length === 0\n      ) {\n        return true\n      }\n      this.errorInParameterInput = true\n      if (this.missingRequiredParameters.length > 0) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `There are required flow parameters missing in the JSON payload.\n          Please specify values for the missing parameters.`,\n          alertType: 'error'\n        })\n      } else {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `You have parameters which were not part of your original flow: ${this.extraParameters}. Please remove them to continue.`,\n          alertType: 'error'\n        })\n      }\n      return false\n    },\n    async saveDefaultParams() {\n      try {\n        const { data, errors } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/set-default-params.gql'),\n          variables: {\n            input: {\n              flow_group_id: this.flowGroup.id,\n              parameters:\n                this.parameterInput && this.parameterInput.trim() !== ''\n                  ? JSON.parse(this.parameterInput)\n                  : null\n            }\n          },\n          errorPolicy: 'all'\n        })\n        if (data) {\n          await this.showAlert(\n            'Your flow group parameters have been updated.',\n            'success'\n          )\n          this.$emit('updated', this.parameterInput)\n        }\n        if (errors) {\n          await this.showAlert(errors[0].message, 'error')\n        }\n      } catch (err) {\n        await this.showAlert(\n          'There was a problem setting your parameters.  Please check the input.',\n          'error'\n        )\n      }\n    },\n    async setDefaultParams() {\n      this.loading = true\n\n      if (!this.validateParameters()) {\n        this.loading = false\n        return\n      }\n\n      await this.saveDefaultParams()\n\n      this.loading = false\n    },\n    async showAlert(alertMessage, alertType) {\n      await this.setAlert({\n        alertShow: true,\n        alertMessage,\n        alertType\n      })\n    }\n  }\n}\n"
  },
  {
    "path": "src/mixins/paymentMixin.js",
    "content": "import { mapGetters } from 'vuex'\n\nexport const paymentMixin = {\n  props: {},\n  data() {\n    return {\n      cardError: '',\n      updatedEmail: null,\n      updatedAddress: null,\n      updatedName: null,\n      loading: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['license']),\n    ...mapGetters('user', ['user']),\n    email: {\n      get() {\n        return this.tenant.stripe_customer?.email\n      },\n      set(x) {\n        this.updatedEmail = x\n      }\n    },\n    address: {\n      get() {\n        return this.tenant?.stripe_customer?.sources?.data[0]?.owner?.address\n          ?.line1\n      },\n      set(x) {\n        this.updatedAddress = x\n      }\n    },\n    username: {\n      get() {\n        //stripe_customer returns empty customer name as string 'nullnull' so need to explicitly check for that\n        if (this.tenant?.stripe_customer?.name == 'nullnull') return ''\n        return this.tenant?.stripe_customer?.name\n          ? this.tenant?.stripe_customer?.name\n          : ''\n      },\n      set(x) {\n        this.updatedName = x\n      }\n    }\n  },\n  methods: {}\n}\n"
  },
  {
    "path": "src/mixins/polling/pollsAgentsMixin.js",
    "content": "export const pollsAgentsMixin = {\n  data() {\n    return {\n      unsubscribe: null\n    }\n  },\n  async created() {\n    this.unsubscribe = await this.$store.dispatch('polling/subscribe', 'agents')\n  },\n  beforeDestroy() {\n    this.unsubscribe()\n  }\n}\n"
  },
  {
    "path": "src/mixins/polling/pollsFlowsMixin.js",
    "content": "export const pollsFlowsMixin = {\n  data() {\n    return {\n      unsubscribe: null\n    }\n  },\n  async created() {\n    this.unsubscribe = await this.$store.dispatch('polling/subscribe', 'flows')\n  },\n  beforeDestroy() {\n    this.unsubscribe()\n  }\n}\n"
  },
  {
    "path": "src/mixins/polling/pollsProjectsMixin.js",
    "content": "export const pollsProjectsMixin = {\n  data() {\n    return {\n      unsubscribe: null\n    }\n  },\n  async created() {\n    this.unsubscribe = await this.$store.dispatch(\n      'polling/subscribe',\n      'projects'\n    )\n  },\n  beforeDestroy() {\n    this.unsubscribe()\n  }\n}\n"
  },
  {
    "path": "src/mixins/polling/pollsTenantsMixin.js",
    "content": "export const pollsTenantsMixin = {\n  data() {\n    return {\n      unsubscribe: null\n    }\n  },\n  async created() {\n    this.unsubscribe = await this.$store.dispatch(\n      'polling/subscribe',\n      'tenants'\n    )\n  },\n  beforeDestroy() {\n    this.unsubscribe()\n  }\n}\n"
  },
  {
    "path": "src/mixins/runFlowNow.js",
    "content": "export const runFlowNowMixin = {\n  data() {\n    return {\n      // Alert\n      showAlert: false,\n      alertMessage: '',\n      alertLink: {},\n      alertType: 'info',\n      setToRun: []\n    }\n  },\n  methods: {\n    async runFlowNow(flowRunId, version, name) {\n      this.setToRun.push(flowRunId)\n      try {\n        // Set the flow in a Scheduled state (even if it's already Scheduled).\n        // This causes the flow run to execute immediately.\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/TaskRun/set-flow-run-states.gql'),\n          variables: {\n            flowRunId: flowRunId,\n            version: version,\n            state: {\n              type: 'Scheduled'\n            }\n          }\n        })\n        this.alertMessage = `Your flow run ${name} has been scheduled to start immediately.`\n        this.alertLink = { name: 'flow-run', params: { id: flowRunId } }\n        this.alertType = 'success'\n        this.showAlert = true\n      } catch (error) {\n        this.alertMessage =\n          'Something went wrong while trying to run this flow. Please try again later.'\n        this.alertType = 'error'\n        this.showAlert = true\n        this.isRunningNow = false\n        this.setToRun.pop(flowRunId)\n\n        throw error\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/mixins/teamProfileMixin.js",
    "content": "import { mapGetters, mapActions } from 'vuex'\n\nexport const teamProfileMixin = {\n  data() {\n    return {\n      // User inputs\n      tenantChanges: {\n        name: '',\n        slug: ''\n      },\n\n      // Regexes to check if a slug is invalid\n      slugCharRegex: /^[a-z0-9|-]*$/,\n      dashPositionRegex: /^(-)|-{2,}|(-)$/,\n\n      // Flags that are set to true during async vaidation checks\n      isCheckingName: false,\n      isCheckingSlug: false,\n\n      // Flag input icons so that they are only revealed during submission & validation\n      showNameIcon: false,\n      showSlugIcon: false,\n\n      // Input errors\n      nameErrors: [],\n      slugErrors: [],\n\n      // Form is submitted & tenant is updating\n      isUpdatingTenant: false,\n\n      // Tenant update returns a server error\n      updateServerError: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return this.hasPermission('update', 'tenant')\n    },\n    isUpdatable() {\n      // Tenant cannot be updated during any kind of load state\n      if (this.isUpdatingTenant) return false\n      if (this.isCheckingSlug) return false\n\n      // Tenant cannot be updated if any errors exist\n      if (\n        this.updateServerError ||\n        this.nameErrors.length > 0 ||\n        this.slugErrors.length > 0\n      ) {\n        return false\n      }\n\n      return (\n        this.tenantChanges.name !== this.tenant.name ||\n        this.tenantChanges.slug !== this.tenant.slug\n      )\n    },\n    slug: {\n      get() {\n        return this.tenantChanges.slug\n      },\n      set(val) {\n        this.tenantChanges.slug = val.replace(' ', '-')\n      }\n    },\n    name: {\n      get() {\n        return this.tenantChanges.name\n      },\n      set(val) {\n        this.tenantChanges.name = val\n      }\n    },\n    showNameCheck() {\n      return (\n        this.showNameIcon &&\n        this.nameErrors.length === 0 &&\n        !this.updateServerError\n      )\n    },\n    showNameClear() {\n      return (\n        this.showNameIcon &&\n        (this.nameErrors.length > 0 || this.updateServerError)\n      )\n    },\n    showSlugCheck() {\n      return (\n        this.showSlugIcon &&\n        this.slugErrors.length === 0 &&\n        !this.updateServerError\n      )\n    },\n    showSlugClear() {\n      return (\n        this.showSlugIcon &&\n        (this.slugErrors.length > 0 || this.updateServerError)\n      )\n    }\n  },\n  watch: {\n    tenant(val) {\n      this.tenantChanges.name = val.name || ''\n      this.tenantChanges.slug = val.slug || ''\n    }\n  },\n  created() {\n    this.tenantChanges.name = this.tenant.name || ''\n    this.tenantChanges.slug = this.tenant.slug || ''\n  },\n  methods: {\n    ...mapActions('tenant', [\n      'setCurrentTenant',\n      'updateTenantSettings',\n      'getTenants'\n    ]),\n    ...mapActions('alert', ['setAlert']),\n    // Synchronous name check that occur on input blur\n    checkName(name) {\n      this.nameErrors = []\n\n      // If name is not provided, reset to original value\n      //\n      // Make this field required if there is no original value\n      if (name === '') {\n        if (!this.tenant.name) {\n          this.nameErrors = ['A team name is required.']\n        } else {\n          this.tenantChanges.name = this.tenant.name\n        }\n        return\n      }\n\n      if (name.length < 3) {\n        this.nameErrors = ['Team names must contain a minimum of 3 characters.']\n        return\n      }\n    },\n    // Synchronous slug input check that occurs on input blur\n    checkSlug(slug) {\n      this.slugErrors = []\n\n      // If slug is not provided, reset to original value\n      //\n      // Make this field required if there is no original value\n      if (slug === '') {\n        if (!this.tenant.slug) {\n          this.slugErrors = ['A URL slug for your team is required.']\n        } else {\n          this.tenantChanges.slug = this.tenant.slug\n        }\n        return\n      }\n\n      if (slug.length < 3) {\n        this.slugErrors = ['URL slug must contain a minimum of 3 characters.']\n        return\n      }\n\n      if (!this.slugCharRegex.test(slug)) {\n        this.slugErrors = [\n          'URL slugs can only contain lowercase letters, numbers, and dashes.'\n        ]\n        return\n      }\n\n      if (this.dashPositionRegex.test(slug)) {\n        this.slugErrors = [\n          'URL slugs cannot begin, end, or contain more than 1 dash in a row.'\n        ]\n      }\n    },\n    // Asynchronous name input \"check\" that occurs when user attempts to submit the form\n    //\n    // Quotes around \"check\" because a check doesn't actually occur\n    //\n    // Instead, a timeout is returned purely to surface a loader on the UI to keep it\n    // inline with the slug async check\n    checkNameAsync() {\n      // Stop immediately if the input never changed\n      if (this.showNameIcon) return\n\n      this.isCheckingName = true\n\n      return new Promise(resolve => {\n        setTimeout(() => {\n          this.showNameIcon = true\n          this.isCheckingName = false\n          resolve()\n        }, 750)\n      })\n    },\n    // Asynchronous slug input check that occurs when user attempts to submit the form\n    //\n    // Currently checks only for slug uniqueness\n    checkSlugAsync() {\n      // Stop immediately if the input never changed\n      if (this.showSlugIcon) return\n\n      this.isCheckingSlug = true\n\n      return new Promise(resolve => [\n        setTimeout(async () => {\n          // Check slug uniqueness\n          try {\n            const checkSlug = await this.$apollo.query({\n              query: require('@/graphql/Tenant/tenant-by-slug.gql'),\n              variables: {\n                slug: this.slug\n              }\n            })\n            if (\n              checkSlug?.data?.tenant?.length !== 0 &&\n              this.slug != this.tenant.slug\n            ) {\n              this.slugErrors = ['Sorry, that URL slug is already in use.']\n            }\n          } catch {\n            this.updateServerError = true\n          }\n\n          this.showSlugIcon = true\n          this.isCheckingSlug = false\n          resolve()\n        }, 750)\n      ])\n    },\n    resetNameMetadata() {\n      this.showNameIcon = false\n      this.nameErrors = []\n      this.updateServerError = false\n    },\n    resetSlugMetadata() {\n      this.showSlugIcon = false\n      this.slugErrors = []\n      this.updateServerError = false\n    },\n    handleError(alert) {\n      this.setAlert({\n        alertMessage:\n          alert ||\n          'Something went wrong while trying to update your team profile settings. Please try again later.',\n        alertType: 'error',\n        alertShow: true\n      })\n    },\n    handleSuccess() {\n      this.setAlert({\n        alertMessage:\n          \"Your team's profile settings have been successfully updated.\",\n        alertType: 'success',\n        alertShow: true\n      })\n      setTimeout(() => {\n        this.resetNameMetadata()\n        this.resetSlugMetadata()\n      }, 3000)\n    },\n    async updateTenant() {\n      if (this.nameErrors.length > 0 || this.slugErrors.length > 0) {\n        return\n      }\n      this.updateServerError = false\n      this.isUpdatingTenant = true\n\n      // Async tenant checks\n      await this.checkNameAsync()\n      await this.checkSlugAsync()\n\n      if (\n        this.tenantChanges.slug == this.tenant.slug &&\n        this.tenantChanges.name == this.tenant.name\n      ) {\n        await this.updateTenantSettings({\n          teamNamed: true\n        })\n\n        this.handleSuccess()\n        this.isUpdatingTenant = false\n        return\n      }\n\n      let newTenant\n\n      try {\n        newTenant = await this.$apollo.mutate({\n          mutation: require('@/graphql/Tenant/update-tenant.gql'),\n          variables: {\n            name: this.tenantChanges.name || this.tenant.name,\n            slug: this.tenantChanges.slug || this.tenant.slug\n          }\n        })\n      } catch (error) {\n        // Otherwise, surface the global error alert.\n        const e = error.toString()\n        const alert = e.includes('Uniqueness violation')\n          ? 'Sorry, that URL slug is already in use. Please try another URL Slug.'\n          : null\n        this.handleError(alert)\n        this.updateServerError = true\n        this.isUpdatingTenant = false\n        return\n      }\n      if (\n        !newTenant?.data?.update_tenant_name ||\n        !newTenant?.data?.update_tenant_slug\n      ) {\n        this.handleError()\n        this.updateServerError = true\n        return\n      }\n\n      await this.getTenants()\n      await this.setCurrentTenant(this.tenantChanges.slug)\n\n      this.$router.replace({\n        name: 'account',\n        params: { tenant: this.tenantChanges.slug }\n      })\n\n      this.handleSuccess()\n      this.isUpdatingTenant = false\n    }\n  }\n}\n"
  },
  {
    "path": "src/pages/AccessDenied.vue",
    "content": "<script>\nimport { mapActions } from 'vuex'\nimport { logout } from '@/auth/index.js'\n\nexport default {\n  data() {\n    return {\n      origin: window.location.origin\n    }\n  },\n  computed: {\n    invalidSSOMethod() {\n      return this.$route.query?.reason == 'invalid_sso'\n    }\n  },\n  methods: {\n    ...mapActions('auth', ['login']),\n    async logOut() {\n      await logout()\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"access-denied\"\n    :class=\"{\n      small: $vuetify.breakpoint.sm,\n      med: $vuetify.breakpoint.mdAndUp,\n      mobile: $vuetify.breakpoint.xs\n    }\"\n  >\n    <div class=\"text py-16 px-8 rounded\">\n      <h1>Oops!</h1>\n\n      <div v-if=\"invalidSSOMethod\">\n        <p>\n          It looks like you're attempting to sign in with a method unsupported\n          by your organization.\n        </p>\n\n        <v-btn color=\"white\" class=\"primary--text\" depressed @click=\"logOut\">\n          <v-icon>arrow_back_ios</v-icon>\n          Back to sign in\n        </v-btn>\n      </div>\n\n      <div v-else>\n        <p>\n          It looks like you don't have access to this application. If you\n          believe this is an error, contact us at help@prefect.io\n        </p>\n\n        <v-btn\n          v-if=\"origin !== 'cloud.prefect.io'\"\n          color=\"white\"\n          class=\"primary--text\"\n          depressed\n          href=\"https://cloud.prefect.io\"\n        >\n          <v-icon class=\"mr-4\">cloud</v-icon>\n          Take me to Prefect Cloud\n        </v-btn>\n\n        <v-btn\n          v-else\n          color=\"white\"\n          class=\"primary--text\"\n          depressed\n          @click=\"logOut\"\n        >\n          <v-icon>arrow_back_ios</v-icon>\n          Sign out\n        </v-btn>\n      </div>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\ni {\n  text-decoration: none;\n}\n\n.access-denied {\n  background-color: var(--v-primary-base) !important;\n  background-image: url('../assets/backgrounds/not-found.svg') !important;\n  background-position: left !important;\n  background-repeat: no-repeat !important;\n  background-size: cover !important;\n  color: var(--v-cloudUIPrimaryLight-base);\n  height: 100vh;\n\n  .text {\n    background-color: rgba(0, 0, 0, 0.2);\n    position: fixed;\n    top: 15%;\n  }\n\n  &.small {\n    .text {\n      left: 25%;\n    }\n  }\n\n  &.med {\n    .text {\n      left: 20%;\n    }\n  }\n\n  &.mobile {\n    .text {\n      left: 5%;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Account/Account.vue",
    "content": "<script>\nimport { mapGetters, mapActions } from 'vuex'\nimport { teamProfileMixin } from '@/mixins/teamProfileMixin.js'\nimport Profile from '@/pages/Admin/Account/Profile'\nimport License from '@/pages/Admin/Account/License'\nimport Billing from '@/pages/Admin/Account/Billing'\nimport ClearDataDialog from '@/pages/Admin/Account/ClearDataDialog'\nimport UsageToday from '@/pages/Admin/Account/Usage/UsageToday'\nimport CurrentUsers from '@/pages/Admin/Account/Usage/CurrentUsers'\nimport UsageCycle from '@/pages/Admin/Account/Usage/UsageCycle'\nimport UsageTimeline from '@/pages/Admin/Account/Usage/UsageTimeline'\nimport UpgradeUsageTile from '@/pages/Dashboard/UsageTiles/UpgradeUsage-Tile'\nimport CommittedUsageTile from '@/pages/Dashboard/UsageTiles/CommittedUsage-Tile'\nimport CycleUsageTile from '@/pages/Dashboard/UsageTiles/CycleUsage-Tile'\n\nexport default {\n  components: {\n    Profile,\n    ClearDataDialog,\n    License,\n    Billing,\n    UsageTimeline,\n    CurrentUsers,\n    UsageCycle,\n    UsageToday,\n    CommittedUsageTile,\n    CycleUsageTile,\n    UpgradeUsageTile\n  },\n  mixins: [teamProfileMixin],\n  data() {\n    return {\n      //profile\n      changeProfile: false,\n      // Clear data\n      clearDataDialog: false,\n\n      loadedTiles: 0,\n      numberOfTiles: 9,\n      refreshTimeout: null\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('license', ['license', 'planType']),\n    isUsageBased() {\n      return this.license?.terms?.is_usage_based\n    },\n    usageTile() {\n      if (!this.isCloud) return null\n      if (!this.license) return 'loading'\n      const isSelfServe = this.license.terms.is_self_serve\n      const isUsageBased = this.license.terms.is_usage_based\n\n      // Legacy license, not self-serve (so no upgrade)\n      if (!isSelfServe && !isUsageBased) return null\n\n      // Legacy license, self-serve (so can upgrade)\n      if (isSelfServe && !isUsageBased) return 'UpgradeUsageTile'\n\n      // Usage license, not self-serve (show committed runs)\n      if (!isSelfServe && isUsageBased) return 'CommittedUsageTile'\n\n      // Usage license && self-serve\n      return 'CycleUsageTile'\n    }\n  },\n  watch: {\n    tenant(val, oldVal) {\n      if (val?.id !== oldVal?.id) {\n        this.loadedTiles = 0\n        clearTimeout(this.refreshTimeout)\n        this.refresh()\n      }\n    }\n  },\n  mounted() {\n    this.refresh()\n  },\n  methods: {\n    ...mapActions('license', ['getLicense']),\n    refresh() {\n      let start\n\n      const animationDuration = 150\n\n      const loadTiles = time => {\n        if (!start) start = time\n\n        const elapsed = time - start\n\n        if (elapsed > this.loadedTiles * animationDuration + 500) {\n          this.loadedTiles++\n        }\n\n        if (this.loadedTiles <= this.numberOfTiles) {\n          requestAnimationFrame(loadTiles)\n        }\n      }\n\n      requestAnimationFrame(loadTiles)\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-container v-if=\"isCloud\" fluid>\n      <v-row class=\"usage-row\">\n        <v-col cols=\"12\" class=\"usage-grid\">\n          <v-skeleton-loader\n            :loading=\"loadedTiles < 3\"\n            type=\"image\"\n            height=\"476\"\n            class=\"usage\"\n            transition=\"quick-fade\"\n            tile\n          >\n            <UsageTimeline />\n          </v-skeleton-loader>\n\n          <v-skeleton-loader\n            :loading=\"loadedTiles < 2\"\n            type=\"image\"\n            height=\"230\"\n            min-height=\"230\"\n            class=\"runs\"\n            transition=\"quick-fade\"\n            tile\n          >\n            <UsageToday />\n          </v-skeleton-loader>\n\n          <v-skeleton-loader\n            :loading=\"loadedTiles < 1\"\n            type=\"image\"\n            height=\"230\"\n            transition=\"quick-fade\"\n            class=\"users\"\n            tile\n          >\n            <CurrentUsers />\n          </v-skeleton-loader>\n        </v-col>\n      </v-row>\n\n      <v-row>\n        <v-col cols=\"12\" md=\"6\">\n          <v-row>\n            <v-col cols=\"12\">\n              <v-skeleton-loader\n                :loading=\"loadedTiles < 5\"\n                type=\"image\"\n                height=\"339\"\n                class=\"usage\"\n                transition=\"quick-fade\"\n                tile\n              >\n                <Profile />\n              </v-skeleton-loader>\n            </v-col>\n            <v-col cols=\"12\">\n              <v-skeleton-loader\n                :loading=\"loadedTiles < 7\"\n                type=\"image\"\n                height=\"282\"\n                class=\"usage\"\n                transition=\"quick-fade\"\n                tile\n              >\n                <ClearDataDialog />\n              </v-skeleton-loader>\n            </v-col>\n          </v-row>\n        </v-col>\n        <v-col cols=\"12\" md=\"6\">\n          <v-row>\n            <v-col\n              v-if=\"isUsageBased && license && !planType('FREE')\"\n              cols=\"12\"\n            >\n              <v-skeleton-loader\n                :loading=\"loadedTiles < 6\"\n                type=\"image\"\n                height=\"168\"\n                class=\"usage\"\n                transition=\"quick-fade\"\n                tile\n              >\n                <UsageCycle />\n              </v-skeleton-loader>\n            </v-col>\n            <v-col v-if=\"usageTile\" cols=\"12\">\n              <v-skeleton-loader\n                v-if=\"usageTile\"\n                :loading=\"loadedTiles < 6 || usageTile == 'loading'\"\n                type=\"image\"\n                height=\"100%\"\n                transition=\"quick-fade\"\n                class=\"tile-container span-row-1\"\n                tile\n              >\n                <component :is=\"usageTile\" />\n              </v-skeleton-loader>\n            </v-col>\n            <v-col cols=\"12\">\n              <v-skeleton-loader\n                :loading=\"loadedTiles < 6\"\n                type=\"image\"\n                height=\"168\"\n                class=\"usage\"\n                transition=\"quick-fade\"\n                tile\n              >\n                <Billing />\n              </v-skeleton-loader>\n            </v-col>\n            <v-col cols=\"12\">\n              <v-skeleton-loader\n                :loading=\"loadedTiles < 4\"\n                type=\"image\"\n                height=\"463\"\n                class=\"usage\"\n                transition=\"quick-fade\"\n                tile\n              >\n                <License />\n              </v-skeleton-loader>\n            </v-col>\n          </v-row>\n        </v-col>\n      </v-row>\n    </v-container>\n\n    <v-container v-else>\n      <v-row>\n        <v-col cols=\"12\">\n          <Profile />\n        </v-col>\n        <v-col cols=\"12\">\n          <ClearDataDialog />\n        </v-col>\n      </v-row>\n    </v-container>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.v-sheet.v-alert:not(.v-sheet--outlined) {\n  padding-left: 25px;\n}\n\n.account-container {\n  margin: auto;\n  max-width: 1600px;\n}\n\n.usage-row {\n  position: relative;\n\n  .usage-grid {\n    column-gap: 16px;\n    display: grid;\n    grid-template-areas:\n      'usage runs'\n      'usage users';\n    grid-template-columns: 4fr 1fr;\n    height: 500px;\n    row-gap: 16px;\n  }\n\n  @media screen and (max-width: 960px) {\n    .usage-grid {\n      grid-template-areas:\n        'usage usage'\n        'runs users';\n      grid-template-columns: auto;\n      grid-template-rows: 4fr 1fr;\n      height: 800px;\n    }\n  }\n\n  .usage {\n    grid-area: usage;\n  }\n\n  .runs {\n    grid-area: runs;\n  }\n\n  .users {\n    grid-area: users;\n  }\n}\n\n.h-100 {\n  height: 100%;\n}\n\n.h-50 {\n  height: 50%;\n}\n</style>\n\n<style lang=\"scss\">\n// stylelint-disable\n.v-skeleton-loader__image {\n  height: inherit !important;\n}\n// stylelint-enable\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Account/Billing.vue",
    "content": "<script>\nimport CardDetails from '@/components/Plans/CardDetails'\nimport { mapActions, mapGetters } from 'vuex'\nimport { pollsTenantsMixin } from '@/mixins/polling/pollsTenantsMixin'\n\nexport default {\n  components: { CardDetails },\n  mixins: [pollsTenantsMixin],\n  props: {\n    page: {\n      type: String,\n      required: false,\n      default: ''\n    }\n  },\n  data() {\n    return {\n      editCardDetails: false,\n      loading: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'tenants']),\n    ...mapGetters('user', ['user']),\n    ...mapGetters('license', ['license', 'hasPermission']),\n    isBank() {\n      return (\n        this.payment?.type == 'ach_credit_transfer' ||\n        this.payment?.type == 'ach_debit'\n      )\n    },\n    isCard() {\n      return this.payment?.type == 'card'\n    },\n    updateOrAdd() {\n      if (this.payment) return 'Update'\n      return 'Add'\n    },\n    isSelfServe() {\n      return this.license?.terms?.is_self_serve\n    },\n    permissionsCheck() {\n      return this.hasPermission('update', 'license')\n    },\n    payment() {\n      return this.tenant?.stripe_customer?.sources?.data?.find(\n        d =>\n          d.status == 'chargeable' &&\n          d.id == this.tenant?.stripe_customer?.default_source\n      )\n    }\n  },\n  methods: {\n    ...mapActions('tenant', ['getTenants']),\n    async confirmCard() {\n      this.loading = true\n      await this.getTenants()\n      this.loading = false\n      this.editCardDetails = false\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    data-cy=\"billing-card\"\n    :class=\"{\n      'warning-border': !payment,\n      'success-border': payment,\n      'prefect-border': editCardDetails\n    }\"\n    tile\n    :loading=\"loading\"\n  >\n    <v-card-title class=\"text-h4 font-weight-light\">\n      <div>\n        Payment\n      </div>\n      <v-spacer />\n      <v-btn\n        v-if=\"!editCardDetails && isSelfServe && permissionsCheck\"\n        data-cy=\"add-payment-card\"\n        color=\"primary\"\n        depressed\n        small\n        @click=\"editCardDetails = true\"\n      >\n        {{ updateOrAdd }} payment\n      </v-btn>\n    </v-card-title>\n\n    <v-card-text style=\"min-height: 100px;\">\n      <transition name=\"fade-expand\" mode=\"out-in\">\n        <div v-if=\"!isSelfServe && !loading\" class=\"text-subtitle-1\">\n          To update your payment details, please\n          <a href=\"https://www.prefect.io/pricing#contact\" target=\"_blank\">\n            contact our sales team\n          </a>\n        </div>\n\n        <div\n          v-else-if=\"!payment && !editCardDetails\"\n          class=\"text-subtitle-1 utilGrayMid--text\"\n        >\n          You haven't added a payment method\n        </div>\n\n        <div v-else-if=\"editCardDetails\" key=\"card-details\">\n          <div style=\"height: 500px;\">\n            <CardDetails @confirm=\"confirmCard\" />\n          </div>\n\n          <v-btn\n            v-if=\"editCardDetails\"\n            class=\"text-none mt-4\"\n            depressed\n            block\n            text\n            @click=\"editCardDetails = false\"\n          >\n            Cancel\n          </v-btn>\n        </div>\n\n        <div v-else-if=\"isCard\" key=\"card-display\">\n          <div class=\"mb-auto d-flex align-center justify--start\">\n            <div>\n              <div v-if=\"payment.owner\" class=\"text-h5 font-weight-light\">\n                {{ payment.owner.name }}\n              </div>\n              <div v-if=\"payment.card\" class=\"mt-1\">\n                <div class=\"text-subtitle-1\">\n                  {{ payment.brand || payment.card.brand }}\n                </div>\n\n                <div class=\"mt-n2\">\n                  <span class=\"text-h6 font-weight-regular utilGrayMid--text\">\n                    •••• •••• •••• {{ payment.last4 || payment.card.last4 }}\n                  </span>\n                  <span\n                    v-if=\"payment.exp_month || payment.card\"\n                    class=\"ml-1 text-subtitle-1 font-weight-light\"\n                  >\n                    {{ payment.exp_month || payment.card.exp_month }}/{{\n                      payment.exp_year || payment.card.exp_year\n                    }}\n                  </span>\n                </div>\n              </div>\n            </div>\n\n            <div v-if=\"payment.card\" class=\"ml-auto\">\n              <v-icon large>\n                fab fa-cc-{{ payment.card.brand.toLowerCase() }}\n              </v-icon>\n            </div>\n          </div>\n        </div>\n\n        <div v-else-if=\"isBank\" key=\"bank-display\">\n          <div class=\"mb-auto d-flex align-center justify--start\">\n            <div>\n              <div v-if=\"payment.owner\" class=\"text-h5 font-weight-light\">\n                {{ payment.owner.name }}\n              </div>\n              <div v-if=\"payment.ach_credit_transfer\" class=\"mt-1\">\n                <div class=\"text-subtitle-1\">\n                  {{ payment.ach_credit_transfer.bank_name }}\n                </div>\n\n                <div class=\"mt-n2\">\n                  <div class=\"text-h6 font-weight-regular\">\n                    ••••••••••••\n                    {{\n                      payment.ach_credit_transfer.account_number &&\n                        payment.ach_credit_transfer.account_number.substring(\n                          payment.ach_credit_transfer.account_number.length - 4\n                        )\n                    }}\n                  </div>\n                  <div class=\"text-subtitle-1 font-weight-light\">\n                    ••••••••••••\n                    {{\n                      payment.ach_credit_transfer.routing_number &&\n                        payment.ach_credit_transfer.routing_number.substring(\n                          payment.ach_credit_transfer.routing_number.length - 4\n                        )\n                    }}\n                  </div>\n                </div>\n              </div>\n\n              <div v-else-if=\"payment.ach_debit\" class=\"mt-1\">\n                <div class=\"text-subtitle-1\">\n                  {{ payment.ach_debit.bank_name }}\n                </div>\n\n                <div class=\"mt-n2\">\n                  <div\n                    v-if=\"payment.ach_debit.account_number\"\n                    class=\"text-h6 font-weight-regular\"\n                  >\n                    ••••••••••••\n                    {{\n                      payment.ach_debit.account_number.substring(\n                        payment.ach_debit.account_number.length - 4\n                      )\n                    }}\n                  </div>\n                  <div\n                    v-if=\"payment.ach_debit.routing_number\"\n                    class=\"text-subtitle-1 font-weight-light\"\n                  >\n                    ••••••••••••\n                    {{\n                      payment.ach_debit.routing_number.substring(\n                        payment.ach_debit.routing_number.length - 4\n                      )\n                    }}\n                  </div>\n                </div>\n              </div>\n            </div>\n\n            <div class=\"ml-auto\">\n              <v-icon large>\n                fad fa-university\n              </v-icon>\n            </div>\n          </div>\n        </div>\n\n        <div v-else class=\"text-subtitle-1\">\n          Sorry, we're having trouble displaying your payment method. For\n          questions, please contact us via email at\n          <span class=\"primary--text\">support@prefect.io</span> or on our\n          <router-link :to=\"'/help'\">support page</router-link>\n        </div>\n      </transition>\n    </v-card-text>\n\n    <!-- <v-card-actions v-if=\"permissionsCheck\" class=\"mt-auto px-4\"> </v-card-actions> -->\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.warning-border {\n  border-left: 6px solid var(--v-warning-base);\n  transition: border-left 100ms;\n}\n\n.success-border {\n  border-left: 6px solid var(--v-Success-base);\n  transition: border-left 100ms;\n}\n\n.prefect-border {\n  border-left: 6px solid var(--v-prefect-base);\n  transition: border-left 100ms;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Account/ClearDataDialog.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport gql from 'graphql-tag'\n\nconst loadingMessages = [\n  'Extracting flow data',\n  'Halting schematic processes',\n  'Untangling task dependencies',\n  'Severing terminal nodes',\n  'Flushing connections',\n  'Cleaning up'\n]\n\nexport default {\n  data() {\n    return {\n      confirmInput: null,\n      dataLoading: false,\n      error: null,\n      formValid: false,\n      loading: false,\n      loadingMessage: loadingMessages[0],\n      loadingMessageInterval: null,\n      success: false,\n      timeout: null,\n      show: false,\n\n      // Data to clear - populated on show\n      flows: [],\n      memberships: [],\n      membershipInvitations: [],\n      projects: [],\n      secrets: [],\n      tokens: [],\n      dataMapping: {},\n\n      // Form rules\n      rules: {\n        confirm: value => value == this.tenant.slug || 'Input is incorrect.',\n        required: value => !!value || 'This field is is required.'\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('user', ['user']),\n    ...mapGetters('license', ['hasPermission']),\n    activeClearScreen() {\n      if (this.success) return 'success'\n      if (this.loading) return 'loading'\n      if (this.error) return 'error'\n      return 'form'\n    },\n    permissionsCheck() {\n      return (\n        this.hasPermission('delete', 'project') &&\n        this.hasPermission('delete', 'membership') &&\n        this.hasPermission('delete', 'membership-invitation') &&\n        this.hasPermission('delete', 'api-key') &&\n        this.hasPermission('delete', 'secret')\n      )\n    },\n    confirmDisabled() {\n      return (\n        !this.formValid ||\n        this.dataLoading ||\n        this.confirmInput !== this.tenant.slug\n      )\n    },\n    noDataToClear() {\n      return (\n        this.memberships &&\n        this.membershipInvitations &&\n        this.projects &&\n        this.flows &&\n        this.secrets &&\n        this.tokens &&\n        this.memberships?.length == 0 &&\n        this.membershipInvitations?.length == 0 &&\n        this.projects?.length == 0 &&\n        this.flows?.length == 0 &&\n        this.secrets?.length == 0 &&\n        this.tokens?.length == 0\n      )\n    }\n  },\n  watch: {\n    tenant() {\n      this.$apollo.queries.data.refetch()\n    },\n    async show(val) {\n      clearTimeout(this.timeout)\n      this.confirmInput = null\n      if (!val) return\n\n      this.dataLoading = true\n\n      const { data } = await this.$apollo.query({\n        query: require('@/graphql/TeamSettings/data-to-clear.js').default(\n          this.isCloud\n        ),\n        fetchPolicy: 'no-cache'\n      })\n      this.timeout = setTimeout(() => {\n        if (\n          data?.memberships &&\n          data?.membershipInvitations &&\n          data?.project &&\n          data?.flow &&\n          data?.secret_names &&\n          data?.api_token\n        ) {\n          this.memberships = data.memberships.filter(m => m.id !== this.user.id)\n          this.membershipInvitations = data.membershipInvitations\n          this.projects = data.project\n          this.flows = data.flow\n          this.secrets = data.secret_names\n          this.tokens = data.api_token\n          this.dataMapping.memberships.count = this.memberships.length\n          this.dataMapping.projects.count = this.projects.length\n          this.dataMapping.flows.count = this.flows.length\n        }\n\n        this.dataLoading = false\n      }, 1500)\n    }\n  },\n  mounted() {\n    const projects = {\n      label: 'Project',\n      count: null,\n      icon: 'pi-project'\n    }\n    const flows = {\n      label: 'Flow',\n      count: null,\n      icon: 'pi-flow'\n    }\n    const memberships = {\n      label: 'User',\n      count: null,\n      icon: 'people'\n    }\n    if (this.isCloud) {\n      this.dataMapping = { projects, flows, memberships }\n    } else {\n      this.dataMapping = { projects, flows }\n    }\n  },\n  methods: {\n    _close() {\n      this.show = false\n      this.$apollo.queries.data.refetch()\n      setTimeout(() => {\n        this.teamName = false\n        this.loading = false\n        this.error = false\n        this.success = false\n        this.confirmInput = null\n        this.flows = []\n        this.memberships = []\n        this.membershipInvitations = []\n        this.projects = []\n      }, 500)\n\n      clearTimeout(this.timeout)\n    },\n    clearMutation() {\n      let mutation = ''\n\n      this.memberships?.map((membership, i) => {\n        mutation += `\n          delete_membership_${i}: delete_membership(input: { membership_id: \"${membership.memberships[0]?.id}\" }) {\n            success\n          }\n        `\n      })\n\n      this.membershipInvitations?.map((invitation, i) => {\n        mutation += `\n          delete_membership_invitation_${i}: delete_membership_invitation(input: { invitation_id: \"${invitation.id}\" }) {\n            success\n          }\n        `\n      })\n\n      this.projects.map((project, i) => {\n        mutation += `\n          delete_project_${i}: delete_project(input: { project_id: \"${project.id}\" }) {\n            success\n          }\n        `\n      })\n\n      this.tokens?.map((token, i) => {\n        mutation += `\n          delete_api_token_${i}: delete_api_token(input: { token_id: \"${token.id}\" }) {\n            success\n          }\n        `\n      })\n\n      this.secrets?.map((secret, i) => {\n        mutation += `\n          delete_secret_${i}: delete_secret(input: { name: \"${secret}\" }) {\n            success\n          }\n        `\n      })\n\n      return gql`\n        mutation ClearData {\n          ${mutation}\n        }\n      `\n    },\n\n    async clearData() {\n      clearTimeout(this.timeout)\n      this.loading = true\n\n      if (!this.noDataToClear) {\n        this.updateLoadingMessage(0, 2500)\n\n        const { data } = await this.$apollo.mutate({\n          mutation: this.clearMutation()\n        })\n\n        if (\n          data?.delete_membership_0?.success ||\n          data?.delete_membership_invitation_0?.success ||\n          data?.delete_project_0?.success ||\n          data?.delete_api_token_0?.success ||\n          data?.delete_secret_0?.success\n        ) {\n          this.timeout = setTimeout(() => {\n            this.loading = false\n            this.success = true\n            this.loadingMessage = loadingMessages[0]\n            this.$emit('cleared')\n            clearTimeout(this.timeout)\n          }, 10000)\n        } else {\n          this.timeout = setTimeout(() => {\n            this.loading = false\n            this.error = true\n            this.loadingMessage = loadingMessages[0]\n            clearTimeout(this.timeout)\n          }, 2000)\n        }\n      }\n    },\n    updateLoadingMessage(i, max) {\n      if (i && i >= loadingMessages.length) return\n      this.loadingMessageInterval = setTimeout(() => {\n        this.loadingMessage = loadingMessages[i]\n        this.updateLoadingMessage(i + 1, max)\n      }, Math.floor(Math.random() * max) + 1000)\n    }\n  },\n  apollo: {\n    data: {\n      query() {\n        return require('@/graphql/TeamSettings/data-to-clear.js').default(\n          this.isCloud\n        )\n      },\n      result({ data }) {\n        if (!data) return\n      },\n      update(data) {\n        this.memberships = data?.memberships?.filter(m => m.id !== this.user.id)\n        this.membershipInvitations = data?.membershipInvitations\n        this.projects = data?.project\n        this.flows = data?.flow\n        this.secrets = data?.secret_names\n        this.tokens = data?.api_token\n\n        if (this.memberships) {\n          this.dataMapping.memberships.count =\n            this.memberships?.filter(m => m.account_type !== 'SERVICE').length +\n            1\n        }\n\n        this.dataMapping.projects.count = this.projects?.length\n        this.dataMapping.flows.count = this.flows?.length\n      },\n      fetchPolicy: 'no-cache'\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card data-cy=\"data-card\" tile class=\"h-100 d-flex flex-column\">\n    <v-card-title class=\"mb-2 text-h4 font-weight-light\">\n      Your data\n    </v-card-title>\n\n    <v-card-subtitle>\n      See and clear the data in your account such as projects, flows, members\n      and secrets\n    </v-card-subtitle>\n    <v-card-text>\n      <v-alert\n        v-if=\"!permissionsCheck\"\n        class=\"mx-auto mb-12\"\n        border=\"left\"\n        colored-border\n        elevation=\"2\"\n        type=\"warning\"\n        tile\n        icon=\"lock\"\n        max-width=\"540\"\n      >\n        Only your team's administrators can modify these settings.\n      </v-alert>\n      <transition name=\"fade-expand\" mode=\"out-in\">\n        <div v-show=\"activeClearScreen == 'form'\" class=\" pa-6\">\n          <v-row>\n            <v-col\n              v-for=\"data in dataMapping\"\n              :key=\"data.title\"\n              class=\"d-flex flex-column justify-center align-center\"\n              cols=\"4\"\n            >\n              <div>\n                <v-icon>{{ data.icon }}</v-icon>\n              </div>\n              <div class=\"my-1 text-center\" style=\"width: 100%;\">\n                <v-skeleton-loader\n                  v-if=\"dataLoading || data.count === null\"\n                  type=\"heading\"\n                  tile\n                  class=\"mx-auto text-center mt-1\"\n                ></v-skeleton-loader>\n                <span v-else class=\"font-weight-bold text-h5\">\n                  {{ data.count.toLocaleString() }}\n                </span>\n              </div>\n\n              <div>\n                {{\n                  data.label +\n                    ((data.count && data.count > 1) || data.count == 0\n                      ? 's'\n                      : '')\n                }}\n              </div>\n            </v-col>\n          </v-row>\n        </div>\n      </transition>\n      <transition name=\"fade-expand\" mode=\"out-in\">\n        <v-alert\n          v-if=\"show\"\n          v-show=\"activeClearScreen == 'form'\"\n          class=\"mx-auto\"\n          border=\"left\"\n          colored-border\n          :color=\"dataLoading ? 'primary' : null\"\n          :type=\"!dataLoading && !noDataToClear ? 'warning' : 'success'\"\n          elevation=\"0\"\n          tile\n          max-width=\"400\"\n          transition=\"fade\"\n        >\n          <template v-if=\"dataLoading\" #prepend>\n            <v-progress-circular\n              :size=\"28\"\n              :width=\"4\"\n              color=\"primary\"\n              class=\"mr-4\"\n              indeterminate\n            ></v-progress-circular>\n          </template>\n\n          <v-fade-transition mode=\"out-in\">\n            <div v-if=\"dataLoading\" class=\"text-h5\">\n              Analyzing...\n            </div>\n\n            <div v-else-if=\"!dataLoading && !noDataToClear\">\n              <div class=\"text-h5\">\n                <span class=\"font-weight-bold\">WARNING:</span> This can't be\n                undone.\n              </div>\n              <div>\n                This will remove all of your team's projects, members, flows,\n                tasks, schematics, secrets, API tokens, runs, and logs.\n              </div>\n            </div>\n\n            <div v-else>\n              <div class=\"text-h5\">\n                You have no data to remove!\n              </div>\n            </div>\n          </v-fade-transition>\n        </v-alert>\n      </transition>\n\n      <transition name=\"fade-expand\" mode=\"out-in\">\n        <div\n          v-show=\"activeClearScreen == 'form' && !noDataToClear\"\n          v-if=\"show\"\n          class=\"mt-10 px-12\"\n        >\n          <div>\n            To confirm, type\n            <span class=\"font-weight-bold\"> your tenant URL slug </span>\n            below:\n          </div>\n          <v-form v-model=\"formValid\">\n            <v-text-field\n              v-if=\"permissionsCheck\"\n              v-model=\"confirmInput\"\n              autocomplete=\"off\"\n              class=\"my-1\"\n              placeholder=\"Type your tenant URL slug\"\n              single-line\n              outlined\n              :rules=\"[rules.required, rules.confirm]\"\n              color=\"primary\"\n              :loading=\"loading\"\n            >\n            </v-text-field>\n          </v-form>\n        </div>\n      </transition>\n\n      <transition name=\"fade-expand\" mode=\"out-in\">\n        <div\n          v-show=\"activeClearScreen == 'form'\"\n          v-if=\"show\"\n          class=\"text-right px-6\"\n        >\n          <v-spacer></v-spacer>\n\n          <v-btn text @click=\"_close\">\n            Close\n          </v-btn>\n          <v-btn\n            v-if=\"!noDataToClear\"\n            color=\"red\"\n            class=\"white--text\"\n            depressed\n            :disabled=\"confirmDisabled\"\n            :loading=\"loading\"\n            @click=\"clearData\"\n          >\n            Clear all data?\n          </v-btn>\n        </div>\n      </transition>\n\n      <transition name=\"fade-expand\" mode=\"out-in\">\n        <v-alert\n          v-if=\"show\"\n          v-show=\"activeClearScreen == 'error'\"\n          class=\"mx-auto mb-0 py-10\"\n          border=\"left\"\n          colored-border\n          elevation=\"0\"\n          type=\"error\"\n          tile\n          transition=\"fade\"\n        >\n          <div class=\"text-h6\">\n            <span class=\"font-weight-bold\">Error:</span> We're sorry, something\n            went wrong.\n          </div>\n          <div>\n            If the issue persists, please contact us via email at\n            <span class=\"primary--text\">support@prefect.io</span> or on our\n            <router-link :to=\"'/help'\">Support page</router-link>\n          </div>\n\n          <template #close>\n            <div class=\"text-right\">\n              <v-btn v-if=\"show\" depressed color=\"primary\" @click=\"_close\">\n                Close\n              </v-btn>\n            </div>\n          </template>\n        </v-alert>\n      </transition>\n\n      <transition name=\"fade-expand\" mode=\"out-in\">\n        <div\n          v-if=\"show\"\n          v-show=\"\n            activeClearScreen == 'success' || activeClearScreen == 'loading'\n          \"\n          class=\"pa-6 text-center\"\n        >\n          <div class=\"text-h5 word-break-normal mb-3 black--text\">\n            {{\n              loading ? loadingMessage + '...' : 'All data has been removed.'\n            }}\n          </div>\n\n          <div class=\"loading-container ma-auto my-10\">\n            <div :class=\"loading ? '' : 'solid'\" class=\"circle\"></div>\n            <div v-if=\"!loading\" class=\"check\"></div>\n          </div>\n\n          <div v-if=\"!loading\" class=\"text-right\">\n            <v-btn depressed color=\"primary\" @click=\"_close\">\n              Close\n            </v-btn>\n          </div>\n        </div>\n      </transition>\n    </v-card-text>\n    <v-card-actions>\n      <v-spacer />\n      <v-btn\n        v-if=\"!show && permissionsCheck\"\n        color=\"primary\"\n        :disabled=\"noDataToClear\"\n        depressed\n        small\n        @click=\"show = true\"\n        >Clear Data\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\">\n.text-center {\n  // stylelint-disable\n  .v-skeleton-loader__heading {\n    margin: auto !important;\n  }\n  // stylelint-enable\n}\n</style>\n\n<style lang=\"scss\" scoped>\n$container-size: 10em;\n$circle-stroke: 10px;\n$check-stroke: 10px;\n$circle-size: $container-size;\n$check-height: $circle-size/2;\n$check-width: $check-height/2.5;\n$check-left: ($container-size/6 + $container-size/8);\n$color: var(--v-prefect-base);\n$color-success: var(--v-prefect-base);\n\n.h-100 {\n  height: 100%;\n}\n\n.loading-container {\n  height: $container-size;\n  position: relative;\n  vertical-align: top;\n  width: $container-size;\n\n  .circle {\n    animation: circle-indeterminate 1.2s infinite linear;\n    border: $circle-stroke solid var(--v-secondaryGrayLight-base);\n    border-left-color: $color;\n    border-radius: 50%;\n    height: $circle-size;\n    width: $circle-size;\n\n    &.solid {\n      border-color: $color-success;\n    }\n  }\n\n  .check {\n    &::after {\n      animation: draw-check 0.75s ease;\n      border-color: $color-success;\n      border-style: solid;\n      border-width: $check-stroke $check-stroke 0 0;\n      content: '';\n      height: $check-height;\n      left: $check-left;\n      opacity: 1;\n      position: absolute;\n      top: $check-height/0.85;\n      transform: scaleX(-1) rotate(135deg);\n      transform-origin: left top;\n      width: $check-width;\n    }\n  }\n\n  @keyframes circle-indeterminate {\n    0% {\n      transform: rotate(0deg);\n    }\n\n    100% {\n      transform: rotate(360deg);\n    }\n  }\n\n  @keyframes draw-check {\n    0% {\n      height: 0;\n      width: 0;\n    }\n\n    20% {\n      height: 0;\n      width: $check-width;\n    }\n\n    40% {\n      height: $check-height;\n      width: $check-width;\n    }\n\n    100% {\n      height: $check-height;\n      width: $check-width;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Account/License.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport { featureTypes } from '@/utils/features'\nimport { PLANS_2021 } from '@/utils/plans'\n\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ExternalLink from '@/components/ExternalLink'\n\nexport default {\n  components: { ConfirmDialog, ExternalLink },\n  data() {\n    return {\n      allFeatures: featureTypes,\n      cancelPlanDialog: false,\n      cancelPlanError: false,\n      cancelPlanloading: false,\n      loading: false,\n      loadingKey: 0,\n      plans: Object.values(PLANS_2021),\n      usersCount: null\n    }\n  },\n  computed: {\n    ...mapGetters('license', [\n      'license',\n      'planType',\n      'allowedUsers',\n      'hasPermission'\n    ]),\n    ...mapGetters('tenant', ['tenant']),\n    isSelfServe() {\n      return this.license?.terms?.is_self_serve\n    },\n    isLegacy() {\n      return !this.license?.terms?.is_usage_based\n    },\n    freeUsersCount() {\n      return PLANS_2021['free'].users\n    },\n    plan() {\n      return this.plans.find(planType => planType.value === this.planType())\n    },\n    planName() {\n      if (this.isLegacy)\n        return `${\n          this.isSelfServe\n            ? 'Developer'\n            : this.planType()\n            ? this.planType().toLowerCase()\n            : ''\n        }`\n      return this.plan.name\n    },\n    runCost() {\n      return this.plan?.price\n    },\n    planColor() {\n      return 'primary'\n    },\n    readNum() {\n      return this.allowedUsers('read').toLocaleString()\n    },\n    userNum() {\n      return this.allowedUsers().toLocaleString()\n    },\n    readOnlyUserOrUsers() {\n      return !this.license?.terms?.read_only_users\n        ? 'users'\n        : this.license?.terms?.read_only_users > 1\n        ? 'users'\n        : 'user'\n    },\n    userOrUsers() {\n      return !this.allowedUsers()\n        ? 'users'\n        : this.allowedUsers() > 1\n        ? 'users'\n        : 'user'\n    },\n    historyRetention() {\n      return this.license?.terms?.history_retention_days?.toLocaleString()\n    },\n    flowConcurrency() {\n      return this.license?.terms?.flow_concurrency\n    },\n    memberOrMembers() {\n      return this.allowedUsers() > 1 ? 'members' : 'member'\n    },\n    flowOrFlows() {\n      return !this.license?.terms?.flow_concurrency\n        ? 'flows'\n        : this.license?.terms?.flow_concurrency > 1\n        ? 'flows'\n        : 'flow'\n    },\n    features() {\n      const featuresArray = this.license?.terms?.permissions?.filter(\n        permission => permission.includes('feature')\n      )\n      const featuresObjArray = featuresArray?.map(feature => {\n        let featureText = feature.split(':')[1]\n        return { type: featureText }\n      })\n      return featuresObjArray?.length > 0 ? featuresObjArray : null\n    },\n    taskRuns() {\n      return this.license?.terms?.task_runs_usage_limit || this.plan?.taskRuns\n    }\n  },\n  methods: {\n    ...mapActions('license', ['getLicense']),\n    ...mapActions('tenant', ['getTenants']),\n    ...mapActions('alert', ['setAlert']),\n    colorType(type) {\n      const feature = featureTypes.find(f => f.type == type)\n      if (feature) return feature.color\n      return 'primary'\n    },\n    iconType(type) {\n      const feature = featureTypes.find(f => f.type == type)\n      if (feature) return feature.icon\n      return 'grade'\n    },\n    titleType(type) {\n      const feature = featureTypes.find(f => f.type == type)\n      if (feature) return feature.title\n      return type\n    },\n    textType(type) {\n      const feature = featureTypes.find(f => f.type == type)\n      if (feature) return feature.text\n      return ''\n    },\n    linkType(type) {\n      const feature = featureTypes.find(f => f.type == type)\n      if (feature) return feature.link\n      return ''\n    },\n    async cancelPlan() {\n      this.cancelPlanloading = true\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/License/create-usage-based-license.gql'),\n          variables: {\n            input: {\n              tenant_id: this.tenant.id,\n              plan_name: PLANS_2021['free'].value\n            }\n          }\n        })\n        if (data.create_self_serve_usage_license.id) {\n          await this.getLicense()\n          await this.getTenants()\n\n          this.cancelPlanDialog = false\n\n          this.setAlert(\n            {\n              alertShow: true,\n              alertMessage: 'Your account has been downgraded.',\n              alertType: 'success'\n            },\n            3000\n          )\n        }\n      } catch (e) {\n        this.cancelPlanError = true\n      } finally {\n        this.cancelPlanloading = false\n      }\n    }\n  },\n  apollo: {\n    memberships: {\n      query: require('@/graphql/TeamSettings/memberships.gql'),\n      loadingKey: 'loadingKey',\n      result({ data }) {\n        if (!data) return\n        this.usersCount =\n          data.memberships.length + data.membershipInvitations.length\n      },\n      fetchPolicy: 'no-cache'\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-card tile data-cy=\"license-card\" :loading=\"loading\">\n      <v-card-title class=\"mb-2 text-h4 font-weight-light\">\n        Your plan\n        <v-spacer />\n\n        <v-btn\n          v-if=\"\n            isSelfServe &&\n              !planType('FREE') &&\n              hasPermission('create', 'license') &&\n              hasPermission('delete', 'license')\n          \"\n          class=\"mr-1 blue-grey--text\"\n          text\n          small\n          @click=\"cancelPlanDialog = true\"\n        >\n          Cancel plan\n        </v-btn>\n\n        <v-btn\n          v-if=\"isSelfServe\"\n          color=\"accentPink\"\n          depressed\n          dark\n          small\n          :to=\"'/plans'\"\n        >\n          Upgrade\n        </v-btn>\n      </v-card-title>\n\n      <v-card-subtitle class=\"pb-0\">\n        You're on\n        {{ !isLegacy ? 'the' : 'a' }}\n        <v-icon :color=\"planColor\" class=\"mr-1 pb-1\" x-small>\n          cloud\n        </v-icon>\n        <span :class=\"`${planColor}--text`\" class=\"text-capitalize\"\n          >{{ planName\n          }}<span v-if=\"isLegacy\" class=\"text-none\"> (legacy)</span></span\n        >\n        plan<span v-if=\"isLegacy && isSelfServe\"\n          >. <router-link :to=\"'/plans'\">Upgrade now</router-link> to get access\n          to usage-based pricing and new features!\n        </span>\n        <br />\n      </v-card-subtitle>\n      <v-card-text>\n        <div class=\"d-flex flex-wrap mt-4\">\n          <div\n            class=\"d-flex justify-start align-start py-4 px-8 my-2\"\n            style=\"width: 50%;\"\n          >\n            <div class=\"mr-4\">\n              <i class=\"primary--text fad fa-clouds fa-fw fa-3x\" />\n            </div>\n            <div>\n              <div\n                class=\"text-h6 font-weight-regular text-capitalize utilGrayMid--text\"\n              >\n                {{ planName\n                }}<span class=\"text-none\">\n                  {{ isLegacy ? '(legacy)' : '' }} plan\n                </span>\n              </div>\n              <div class=\"text-body-1\">\n                Visit the\n                <ExternalLink href=\"https://prefect.io/pricing\" target=\"_blank\"\n                  >pricing page</ExternalLink\n                >\n                for more details\n              </div>\n            </div>\n          </div>\n\n          <div\n            v-if=\"\n              planType('FREE') || planType('STARTER') || planType('STANDARD')\n            \"\n            class=\"d-flex justify-start align-start py-4 px-8 my-2\"\n            style=\"width: 50%;\"\n          >\n            <div class=\"mr-4\">\n              <i class=\"primary--text fad fa-tasks fa-fw fa-3x\" />\n            </div>\n            <div>\n              <div class=\"text-h6 font-weight-regular utilGrayMid--text\">\n                20,000 free runs / month\n              </div>\n              <div v-if=\"!planType('FREE')\" class=\"text-body-1\">\n                Your first 20,000 successful runs per month are on us!\n              </div>\n              <div v-else class=\"text-body-1\">\n                20,000 successful runs each month!\n              </div>\n            </div>\n          </div>\n\n          <div\n            class=\"d-flex justify-start align-start py-4 px-8 my-2\"\n            style=\"width: 50%;\"\n          >\n            <div class=\"mr-4\">\n              <i\n                :class=\"\n                  `primary--text fad fa-user${\n                    userNum > 1 ? 's' : ''\n                  } fa-fw fa-3x`\n                \"\n              />\n            </div>\n            <div>\n              <div class=\"text-h6 font-weight-regular utilGrayMid--text\">\n                {{ userNum ? userNum : 'Unlimited' }} {{ userOrUsers }}\n              </div>\n              <div v-if=\"userNum\" class=\"text-body-1\">\n                You can invite up to {{ userNum }} {{ userOrUsers }}\n              </div>\n              <div v-else class=\"text-body-1\">\n                You have unlimited users!\n              </div>\n            </div>\n          </div>\n\n          <div\n            v-if=\"flowConcurrency\"\n            class=\"d-flex justify-start align-start py-4 px-8 my-2\"\n            style=\"width: 50%;\"\n          >\n            <div class=\"mr-4\">\n              <i class=\"primary--text pi-flow pi-3x pi-fw\" />\n            </div>\n            <div>\n              <div class=\"text-h6 font-weight-regular utilGrayMid--text\">\n                {{ `${flowConcurrency} concurrent ${flowOrFlows}` }}\n              </div>\n              <div class=\"text-body-1\">\n                You can have {{ flowConcurrency }} {{ flowOrFlows }} running at\n                a time\n              </div>\n            </div>\n          </div>\n\n          <div\n            class=\"d-flex justify-start align-start py-4 px-8 my-2\"\n            style=\"width: 50%;\"\n          >\n            <div class=\"mr-4\">\n              <i class=\"primary--text fad fa-history fa-fw fa-3x\" />\n            </div>\n            <div>\n              <div class=\"text-h6 font-weight-regular utilGrayMid--text\">\n                {{\n                  historyRetention\n                    ? historyRetention + ' days of '\n                    : 'Unlimited'\n                }}\n                history\n              </div>\n              <div v-if=\"historyRetention\" class=\"text-body-1\">\n                Flow and task run history is retained for\n                {{ historyRetention }} days\n              </div>\n              <div v-else class=\"text-body-1\">\n                You can view run history forever!\n              </div>\n            </div>\n          </div>\n        </div>\n      </v-card-text>\n    </v-card>\n\n    <ConfirmDialog\n      v-model=\"cancelPlanDialog\"\n      type=\"error\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      :disabled=\"cancelPlanloading || usersCount > freeUsersCount\"\n      :loading=\"cancelPlanloading\"\n      @confirm=\"cancelPlan\"\n    >\n      <template slot=\"title\">\n        <div class=\"text-h5 font-weight-light\">\n          {{ cancelPlanError ? 'Oops' : 'Are you sure?' }}\n        </div>\n      </template>\n\n      <div class=\"text-subtitle-1\">\n        <span v-if=\"cancelPlanError\"\n          >Something went wrong trying to cancel your plan. If this error\n          persists, please contact help@prefect.io.</span\n        >\n        <span v-else\n          >This will cancel your current plan and put you on the Free plan. Any\n          outstanding balance will be billed immediately.</span\n        >\n\n        <v-alert\n          v-if=\"!cancelPlanError && usersCount > freeUsersCount\"\n          color=\"warning\"\n          colored-border\n          type=\"warning\"\n          border=\"left\"\n          tile\n          class=\"mt-4\"\n        >\n          You have more users than the Free plan allows (1). You'll need to\n          <router-link :to=\"'/team/members'\"\n            >remove users and pending invitations</router-link\n          >\n          from your team before proceeding.\n        </v-alert>\n      </div>\n    </ConfirmDialog>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/Admin/Account/Profile.vue",
    "content": "<script>\nimport { teamProfileMixin } from '@/mixins/teamProfileMixin.js'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {},\n  mixins: [teamProfileMixin],\n  computed: {\n    ...mapGetters('license', ['hasPermission'])\n  }\n}\n</script>\n\n<template>\n  <v-card tile data-cy=\"profile-card\" class=\"h-100 d-flex flex-column\">\n    <v-card-title class=\"mb-2 text-h4 font-weight-light\">\n      Profile\n    </v-card-title>\n\n    <v-card-subtitle> See and edit your team profile.</v-card-subtitle>\n    <v-card-text class=\"align-self-stretch\">\n      <v-alert\n        v-if=\"!hasPermission('update', 'tenant')\"\n        class=\"mx-auto mb-12\"\n        border=\"left\"\n        colored-border\n        elevation=\"2\"\n        type=\"warning\"\n        tile\n        icon=\"lock\"\n        max-width=\"540\"\n      >\n        Only your team's administrators can modify these profile settings.\n      </v-alert>\n      <v-text-field\n        v-model=\"name\"\n        data-cy=\"update-profile-name\"\n        label=\"Team Name\"\n        outlined\n        class=\"mb-3\"\n        counter\n        maxlength=\"80\"\n        :disabled=\"isUpdatingTenant\"\n        :loading=\"isCheckingName\"\n        prepend-inner-icon=\"supervised_user_circle\"\n        :readonly=\"!hasPermission('update', 'tenant')\"\n        @blur=\"checkName(name)\"\n        @input=\"resetNameMetadata\"\n      >\n        <v-icon v-if=\"showNameCheck\" slot=\"append\" class=\"green--text\">\n          check\n        </v-icon>\n        <v-icon v-if=\"showNameClear\" slot=\"append\" class=\"red--text\">\n          clear\n        </v-icon>\n      </v-text-field>\n\n      <v-text-field\n        v-model=\"slug\"\n        data-cy=\"update-profile-slug\"\n        label=\"URL Slug\"\n        outlined\n        counter\n        maxlength=\"80\"\n        :disabled=\"isUpdatingTenant\"\n        :error-messages=\"slugErrors\"\n        :loading=\"isCheckingSlug\"\n        prepend-inner-icon=\"language\"\n        :readonly=\"!hasPermission('update', 'tenant')\"\n        @blur=\"checkSlug(slug)\"\n        @input=\"resetSlugMetadata\"\n      >\n        <v-icon v-if=\"showSlugCheck\" slot=\"append\" class=\"green--text\">\n          check\n        </v-icon>\n        <v-icon v-if=\"showSlugClear\" slot=\"append\" class=\"red--text\">\n          clear\n        </v-icon>\n      </v-text-field>\n    </v-card-text>\n\n    <v-spacer />\n\n    <v-card-actions v-if=\"hasPermission('update', 'tenant')\" class=\"mt-auto\">\n      <v-spacer></v-spacer>\n      <v-btn\n        :disabled=\"!isUpdatable\"\n        data-cy=\"update-profile\"\n        color=\"primary\"\n        depressed\n        small\n        @click=\"updateTenant\"\n        >Update Profile</v-btn\n      >\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.h-100 {\n  height: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Account/Usage/CurrentUsers.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nexport default {\n  data() {\n    return {\n      count: null,\n      loadingKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license', 'hasPermission']),\n    loading() {\n      return this.loadingKey > 0 || (!this.count && this.count !== 0)\n    }\n  },\n  apollo: {\n    memberships: {\n      query() {\n        return this.hasPermission('license', 'admin') && this.license\n          ? require('@/graphql/Account/license-users.gql')\n          : require('@/graphql/TeamSettings/memberships.gql')\n      },\n      loadingKey: 'loadingKey',\n      update(data) {\n        if (!data) return\n        if (this.hasPermission('license', 'admin') && this.license) {\n          this.count = data.license_users?.length\n        } else {\n          this.count =\n            data.memberships.filter(m => m.account_type !== 'SERVICE').length +\n            data.membershipInvitations.length\n        }\n      },\n      fetchPolicy: 'no-cache'\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card tile class=\"f-wh py-8 d-flex flex-column align-center justify-center\">\n    <div class=\"rounded pa-3 primary\">\n      <v-icon x-large color=\"white\">\n        fad fa-users\n      </v-icon>\n    </div>\n\n    <div class=\"text-center\">\n      <div class=\"text-subtitle-1 text--disabled\">Users</div>\n\n      <v-skeleton-loader\n        :loading=\"loading\"\n        type=\"image\"\n        transition=\"quick-fade\"\n        height=\"36\"\n        tile\n      >\n        <div class=\"text-h4\">\n          {{ count }}\n        </div>\n      </v-skeleton-loader>\n    </div>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.f-wh {\n  height: 100%;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Account/Usage/Usage.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport { PLANS_2021 } from '@/utils/plans'\nimport ChartCard from '@/components/ChartCard/ChartCard'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    ChartCard\n  },\n  filters: {\n    numFormat(value) {\n      if (!value) return ''\n      return new Intl.NumberFormat().format(value)\n    }\n  },\n  mixins: [formatTime],\n  data() {\n    return {\n      loading: false,\n      plans: Object.values(PLANS_2021)\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['user']),\n    ...mapGetters('license', ['license', 'tempLicenseType', 'planType']),\n    ...mapGetters('user', ['timezone']),\n    plan() {\n      const type = this.tempLicenseType || this.license?.terms?.plan\n      const name = type === 'STARTER_2021' ? 'FREE_2021' : type\n      const plan = this.plans.filter(planType => planType.value === name)\n      return plan[0]\n    },\n    smallScreen() {\n      return this.$vuetify.breakpoint.xs ? '' : 'pt-16'\n    },\n    usedTaskRuns() {\n      return 221000\n    },\n    subscriptionPeriodEnd() {\n      const dtFormat = new Intl.DateTimeFormat('en-US', {\n        dateStyle: 'medium'\n      })\n      return dtFormat.format(\n        new Date(this.license.stripe_subscription.current_period_end * 1e3)\n      )\n    },\n    subscriptionPeriodBegun() {\n      const dtFormat = new Intl.DateTimeFormat('en-US', {\n        dateStyle: 'medium'\n      })\n      return dtFormat.format(\n        new Date(this.license.stripe_subscription.current_period_start * 1e3)\n      )\n    },\n    taskRunsLeft() {\n      return this.planTaskRuns - this.usedTaskRuns\n    },\n    planTaskRuns() {\n      return this.license?.terms?.task_runs_usage_limit || this.plan.taskRuns\n    },\n    chargeableRuns() {\n      return this.usedTaskRuns - this.planTaskRuns\n    },\n    costSoFar() {\n      return new Intl.NumberFormat('en-US', {\n        style: 'currency',\n        currency: 'USD'\n      }).format(this.chargeableRuns * this.plan.additionalCost)\n    },\n    noExtra() {\n      return (\n        this.usedTaskRuns < this.planTaskRuns && this.plan.value === 'FREE_2021'\n      )\n    },\n    taskRunsPerDay() {\n      return new Intl.NumberFormat().format(\n        Math.round(this.usedTaskRuns / this.daysFromInvoice())\n      )\n    }\n  },\n  watch: {\n    tenant(val) {\n      this.loading = true\n      if (val) {\n        setTimeout(() => {\n          this.loading = false\n        }, 1000)\n      }\n    }\n  },\n  methods: {\n    daysUntilInvoice() {\n      const today = new Date()\n      return this.dateDiff(today, this.subscriptionPeriodEnd) - 1\n    },\n    daysFromInvoice() {\n      const today = new Date()\n      return this.dateDiff(this.subscriptionPeriodBegun, today) + 1\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card tile max-width=\"720\" class=\"mx-auto my-4\" :loading=\"loading\">\n    <v-card-title> Usage</v-card-title>\n    <v-card-subtitle class=\"pb-0\"> Check your task run usage.</v-card-subtitle>\n    <v-card-text>\n      <v-row>\n        <v-col v-if=\"!$vuetify.breakpoint.xs\" cols=\"0\" sm=\"7\">\n          <ChartCard\n            v-if=\"plan.value === 'FREE_2021'\"\n            :chart-data=\"[\n              { label: 'used', value: usedTaskRuns, color: '#ff8cc6' },\n              { name: 'Plan Runs', value: taskRunsLeft, color: '#de369d' }\n            ]\"\n            :extra=\"false\"\n            chart-type=\"ring\"\n            :colors=\"['#27b1ff', '#f9f9f9']\"\n            accent-color=\"#fff\"\n            chart-overlay-center-type=\"text\"\n            :chart-overlay-center=\"`${usedTaskRuns}/${planTaskRuns}`\"\n            chart-overlay-center-two=\"Task Runs Used\"\n          />\n          <ChartCard\n            v-else\n            :chart-data=\"[\n              {\n                label: 'daysPassed',\n                value: daysFromInvoice(),\n                color: '#ff8cc6'\n              },\n              { name: 'daysLeft', value: daysUntilInvoice(), color: '#de369d' }\n            ]\"\n            :extra=\"false\"\n            chart-type=\"ring\"\n            :colors=\"['#27b1ff', '#f9f9f9']\"\n            accent-color=\"#fff\"\n            chart-overlay-center-type=\"text\"\n            :chart-overlay-center=\"`${taskRunsPerDay}`\"\n            chart-overlay-center-two=\"Task Runs/Day\"\n          />\n        </v-col>\n        <v-col v-if=\"noExtra\" cols=\"12\" sm=\"5\"\n          ><ul>\n            <li :class=\"smallScreen\"\n              >You are on the Prefect {{ plan.name }} Plan. </li\n            ><li> You have used {{ usedTaskRuns | numFormat }} task runs</li>\n            <li>\n              You have {{ taskRunsLeft | numFormat }} task runs left until\n              {{ subscriptionPeriodEnd }}.\n              <span v-if=\"planType('STARTER')\">\n                You will then be charged ${{ plan.additionalCost }}/task\n                run.</span\n              >\n            </li>\n          </ul>\n        </v-col>\n        <v-col v-else cols=\"12\" sm=\"5\"\n          ><ul\n            ><li :class=\"smallScreen\"\n              >You are on the Prefect {{ plan.name }} Plan. </li\n            ><li\n              >Your billing period started on {{ subscriptionPeriodBegun }} and\n              will end on {{ subscriptionPeriodEnd }}.\n            </li>\n            <li v-if=\"planTaskRuns\">\n              You have {{ planTaskRuns | numFormat }} task runs in your plan and\n              have used {{ chargeableRuns | numFormat }} extra runs at ${{\n                plan.additionalCost\n              }}/run.</li\n            >\n            <li v-else>\n              You have used {{ chargeableRuns | numFormat }} task runs at ${{\n                plan.additionalCost\n              }}/run.</li\n            >\n            <li> Your total so far is {{ costSoFar }}.</li>\n            <!-- <li>We predict your final monthly cost will be.... </li> -->\n          </ul>\n        </v-col>\n      </v-row>\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "src/pages/Admin/Account/Usage/UsageCycle.vue",
    "content": "<script>\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  mixins: [formatTime],\n  data() {\n    return {\n      invoiceLoadingKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license']),\n    ...mapGetters('tenant', ['tenant']),\n    projectedCostDollars() {\n      if (!this.invoice) return 0\n      return Math.floor(this.invoice.total / 100)\n    },\n    projectedCostCents() {\n      if (!this.invoice) return 0\n      const cents = ((this.invoice.total / 100) % 1).toFixed(2) * 100\n      return cents == 0 ? '00' : cents\n    },\n    nextPaymentDate() {\n      if (!this.invoice) return null\n      const nextPayment = this.invoice.next_payment_attempt * 1000\n      return this.formatLongDate(nextPayment)\n    },\n    periodStart() {\n      if (!this.invoice) return null\n      return new Date(this.invoice.period_start * 1000)\n    },\n    invoiceLoading() {\n      return this.invoiceLoadingKey > 0\n    }\n  },\n  apollo: {\n    invoice: {\n      query: require('@/graphql/Dashboard/invoice.gql'),\n      variables() {\n        return {\n          licenseId: this.license.id\n        }\n      },\n      loadingKey: 'invoiceLoadingKey',\n      skip() {\n        return !this.license?.id\n      },\n      update: data => data?.preview_invoice\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    class=\"position-relative d-flex flex-column justify-space-between\"\n    style=\"height: 100%;\"\n    tile\n  >\n    <v-card-title class=\"text-h4 font-weight-light\">\n      Current balance\n    </v-card-title>\n\n    <v-card-text\n      class=\"pt-0 pa-3 d-flex align-start justify-center flex-column mb-auto\"\n    >\n      <div class=\"text-h3\"\n        ><span class=\"text-h5\" style=\"vertical-align: top;\">$</span>\n        <v-skeleton-loader\n          :loading=\"invoiceLoading\"\n          type=\"image\"\n          transition=\"quick-fade\"\n          height=\"45\"\n          width=\"75\"\n          tile\n          class=\"d-inline-block\"\n        >\n          <span>\n            {{ projectedCostDollars\n            }}<span class=\"text--disabled text-subtitle-1\"\n              >.{{ projectedCostCents }}</span\n            >\n          </span>\n        </v-skeleton-loader>\n      </div>\n      <div class=\"text-subtitle-2 font-weight-light\"\n        >due\n        <v-skeleton-loader\n          :loading=\"invoiceLoading\"\n          type=\"image\"\n          transition=\"quick-fade\"\n          height=\"12\"\n          width=\"100\"\n          tile\n          class=\"d-inline-block\"\n          style=\"vertical-align: baseline;\"\n        >\n          <span>\n            <span v-if=\"nextPaymentDate !== 'today'\">on </span\n            >{{ nextPaymentDate }}\n          </span>\n        </v-skeleton-loader>\n      </div>\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "src/pages/Admin/Account/Usage/UsageTimeline.vue",
    "content": "<script>\nimport * as d3_base from 'd3'\nimport * as d3_regression from 'd3-regression'\n\nimport uniqueId from 'lodash/uniqueId'\nimport debounce from 'lodash/debounce'\nimport throttle from 'lodash/throttle'\nimport { mapGetters } from 'vuex'\nimport { pollsTenantsMixin } from '@/mixins/polling/pollsTenantsMixin'\n\nconst d3 = Object.assign({}, d3_base, d3_regression)\n\nconst xAxisHeight = 40\n\nconst startDate = new Date('2018-01-17T00:00:00+00:00')\n\nexport default {\n  mixins: [pollsTenantsMixin],\n  props: {\n    baseline: {\n      type: Number,\n      required: false,\n      default: () => 10000\n    }\n  },\n  data() {\n    return {\n      id: uniqueId('usage'),\n      selectedTeam: null,\n      format: null,\n      ticks: null,\n      period: 'Year',\n      hoverGroup: null,\n      interactionGroup: null,\n      mainGroup: null,\n      chart: null,\n      offset: 0,\n      xAxisGroup: null,\n      yAxisGroup: null,\n      height: null,\n      width: null,\n\n      padding: {\n        bottom: xAxisHeight,\n        left: 80,\n        right: 20,\n        top: 10,\n        x: 100,\n        y: xAxisHeight + 10\n      },\n\n      hovered: null,\n      showPath: false,\n      showBars: true,\n      showText: false,\n\n      items: [],\n      line: null,\n      previousLine: null,\n      predict: null,\n      regression: null,\n\n      // Domain\n      // from: null, // we use a computed prop for this based on the period\n      // to: null, // we use a computed prop for this based on the period\n\n      // Scales\n      previousX: null,\n      previousY: null,\n      x: null,\n      y: null\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'tenants']),\n    ...mapGetters('license', ['license']),\n    teams() {\n      return [\n        { id: null, name: 'All' },\n        ...this.tenants?.filter(t => t.license_id == this.license?.id)\n      ]\n    },\n    multitenancy() {\n      return this.license?.terms?.tenants > 1\n    },\n    predictedItems() {\n      if (!this.usage || !this.predict) return []\n      const from = new Date(this.from)\n      from.setMonth(this.from.getMonth() - 1)\n\n      const to = new Date(this.to)\n      to.setMonth(this.to.getMonth() + 1)\n\n      const months = d3.timeMonth.range(from, to)\n\n      const pastPrediction = Math.floor(this.predict(this.x(months[0])))\n      const past = {\n        timestamp: months[0],\n        runs: pastPrediction < 0 ? 0 : pastPrediction\n      }\n\n      const futurePrediction = Math.floor(\n        this.predict(this.x(months[months.length - 1]))\n      )\n      const future = {\n        timestamp: months[months.length - 1],\n        runs: futurePrediction < 0 ? 0 : futurePrediction\n      }\n\n      return [\n        past,\n        this.items[0],\n        this.items[1],\n        { timestamp: this.items[1].timestamp, runs: undefined },\n        this.items[this.items.length - 2],\n        this.items[this.items.length - 1],\n        future\n      ]\n    },\n    // regressionItems() {\n    //   // We do this to prevent modification of the original items array\n    //   const items = Array.from(this.items, d => Object.assign({}, d))\n\n    //   const lastIndex = items.length - 1\n    //   const lastItem = items[lastIndex]\n    //   const timestamp = new Date()\n    //   const interpolatedRuns = Math.ceil(\n    //     (lastItem.runs *\n    //       daysInMonth(timestamp.getFullYear(), timestamp.getMonth())) /\n    //       timestamp.getDate()\n    //   )\n\n    //   items[items.length - 1].runs = interpolatedRuns\n    //   return items\n    // },\n    resizeChart: function() {\n      return debounce(() => {\n        requestAnimationFrame(this.rawResizeChart)\n      }, 300)\n    },\n    tooltipStyle() {\n      if (!this.hovered) return\n      return {\n        left: `${this.hovered.x + this.hovered.bandwidth / 4}px`,\n        top: `${this.hovered.y + this.padding.top + 35}px`\n      }\n    },\n    updateChart: function() {\n      return debounce(() => {\n        requestAnimationFrame(this.rawUpdateChart)\n      }, 50)\n    },\n    updateItems: function() {\n      return debounce(() => {\n        requestAnimationFrame(this.rawUpdateItems)\n      }, 50)\n    },\n    updateScales: function() {\n      return debounce(() => {\n        requestAnimationFrame(this.rawUpdateScales)\n      }, 50)\n    },\n    updateHovered: function() {\n      return throttle(\n        e => {\n          requestAnimationFrame(() => {\n            this.rawUpdateHovered(e)\n          })\n        },\n        16,\n        { leading: true, trailing: true }\n      )\n    },\n    fromDisplay() {\n      let format\n      switch (this.period) {\n        case 'Year':\n          format = '%b %Y'\n          break\n        case 'Month':\n          format = '%e %b %Y'\n          break\n        case 'Week':\n          format = '%e %b'\n          break\n        default:\n          break\n      }\n      return d3.timeFormat(format)(this.from)\n    },\n    toDisplay() {\n      let format\n      switch (this.period) {\n        case 'Year':\n          format = '%b %Y'\n          break\n        case 'Month':\n          format = '%e %b %Y'\n          break\n        case 'Week':\n          format = '%e %b'\n          break\n        default:\n          break\n      }\n      return d3.timeFormat(format)(this.to)\n    },\n    from() {\n      const from = new Date()\n\n      if (this.period == 'Year') {\n        const year = new Date().getFullYear()\n        from.setFullYear(year - 1 + this.offset)\n        from.setDate(0)\n      } else if (this.period == 'Month') {\n        from.setDate(1)\n        from.setMonth(from.getMonth() + this.offset)\n      } else if (this.period == 'Week') {\n        const day = from.getDay()\n        const diff = from.getDate() + this.offset - ((day + 6) % 7)\n        from.setDate(diff)\n      }\n\n      from.setMilliseconds(0)\n      from.setSeconds(0)\n      from.setMinutes(0)\n      from.setHours(0)\n      return from\n    },\n    to() {\n      const to = new Date()\n      to.setHours(23)\n      to.setSeconds(59)\n      if (this.period == 'Year') {\n        const year = new Date().getFullYear()\n        to.setFullYear(year + this.offset)\n        to.setMonth(to.getMonth() + 1)\n        to.setDate(0)\n        to.setMinutes(59)\n      } else if (this.period == 'Month') {\n        to.setMonth(to.getMonth() + 1 + this.offset)\n        to.setDate(0)\n        to.setMinutes(59)\n      } else if (this.period == 'Week') {\n        const day = to.getDay()\n        const diff = to.getDate() + this.offset + (7 - day)\n        to.setDate(diff)\n      }\n\n      to.setMilliseconds(999)\n      to.setSeconds(59)\n      to.setMinutes(59)\n      to.setHours(23)\n      return to\n    },\n    decrementOffsetDisabled() {\n      return this.from <= startDate\n    }\n  },\n  watch: {\n    items() {\n      // if (!this.chart) this.createChart()\n      this.updateChart()\n    },\n    usage(val) {\n      if (!val) return\n      this.$apollo.queries['usage'].stop()\n      this.updateItems()\n      this.updateScales()\n    },\n    period() {\n      this.offset = 0\n      this.updateItems()\n      this.updateScales()\n    },\n    offset() {\n      this.updateItems()\n      this.updateScales()\n    },\n    selectedTeam() {\n      this.$apollo.queries['usage'].refresh()\n    }\n  },\n  mounted() {\n    setTimeout(() => {\n      this.createChart()\n    }, 1000)\n\n    this.$apollo.queries['usage'].refetch()\n  },\n  updated() {\n    if (!this.chart) this.createChart()\n  },\n  beforeDestroy() {\n    window.removeEventListener('resize', this.resizeChart)\n\n    this.interactionGroup.on('mouseout', null)\n  },\n  methods: {\n    barMouseover(e) {\n      this.hovered = e.currentTarget?.__data__\n    },\n    barMouseout() {\n      this.hovered = null\n    },\n    createChart() {\n      this.chart = d3.select(`#${this.id}-svg`)\n      this.mainGroup = this.chart.append('g').attr('class', 'main-group')\n      this.hoverGroup = this.chart.append('g').attr('class', 'hover-group')\n      this.predictionGroup = this.chart\n        .append('g')\n        .attr('class', 'prediction-group')\n      this.xAxisGroup = this.chart\n        .append('g')\n        .attr('class', 'usage-x-axis-group')\n      this.yAxisGroup = this.chart\n        .append('g')\n        .attr('class', 'usage-y-axis-group')\n\n      this.interactionGroup = this.chart\n        .append('g')\n        .attr('class', 'interaction-group')\n\n      window.addEventListener('resize', this.resizeChart)\n\n      this.rawResizeChart()\n    },\n    createX() {\n      const x = d3.scaleTime()\n      x.domain([this.from, this.to])\n      x.range([this.padding.left * 2, this.width - this.padding.right * 2])\n\n      return x\n    },\n    createY() {\n      const y = d3.scaleLinear()\n      y.domain([d3.max(this.items.map(d => d.runs)) || 10000, 0])\n      y.range([this.padding.top, this.height - this.padding.y])\n\n      return y\n    },\n    rawResizeChart() {\n      if (!this.chart) return\n\n      let parent = this.chart.select(function() {\n        return this.parentNode\n      })?._groups?.[0]?.[0]\n\n      let computedStyle = window.getComputedStyle(parent, null)\n\n      // This is the padding that the parent element has\n      // NOT the internal padding\n      let padding = {\n        left: parseFloat(computedStyle.getPropertyValue('padding-left')),\n        right: parseFloat(computedStyle.getPropertyValue('padding-right')),\n        top: parseFloat(computedStyle.getPropertyValue('padding-top')),\n        bottom: parseFloat(computedStyle.getPropertyValue('padding-bottom'))\n      }\n\n      this.boundingClientRect = this.$refs['parent']?.getBoundingClientRect()\n\n      this.width = parent.clientWidth - padding.left - padding.right\n\n      this.height = parent.clientHeight - padding.top - padding.bottom\n\n      this.chart.attr('viewbox', `0 0 ${this.width} ${this.height}`)\n\n      if (!this.items.length) return\n\n      this.updateScales()\n      this.updateChart()\n    },\n    rawUpdateHovered(e) {\n      const hoverline = e ? [e] : []\n\n      const path = d =>\n        `M0,${d.y + this.padding.top}L0,${this.height -\n          this.padding.top -\n          xAxisHeight / 2}`\n\n      const cy = d => d.y + this.padding.top\n\n      this.hoverGroup\n        .selectAll('.hover-group')\n        .data(hoverline, d => d.x)\n        .join(\n          enter => {\n            const g = enter\n              .append('g')\n              .attr('class', 'hover-group')\n              .attr('transform', d => `translate(${d.x})`)\n\n            g.append('path')\n              .attr('stroke', 'var(--v-primary-base')\n              .attr('stroke-width', 2)\n              .attr('stroke-dasharray', 2.5)\n              .attr('d', path)\n              .style('pointer-events', 'none')\n              .style('opacity', 0.3)\n\n            g.append('circle')\n              .attr('cy', cy)\n              .attr('r', 5)\n              .attr('fill', 'var(--v-accentPink-base)')\n            return g\n          },\n          update => {\n            update.attr('transform', d => `translate(${d.x})`)\n\n            // update.select('path').attr('d', path)\n\n            update.select('circle').attr('cy', cy)\n\n            update\n              .select('text')\n              .attr('y', cy)\n              .text(d => (d.runs ? d.runs.toLocaleString() : 0))\n\n            return update\n          },\n          exit => exit.remove()\n        )\n\n      this.xAxisGroup\n        .selectAll('.tick')\n        .select('text')\n        .attr('fill', '#9e9e9e')\n\n      if (e) {\n        this.xAxisGroup\n          .selectAll('.tick')\n          .filter(function() {\n            const selection = d3.select(this)\n            const transform = Math.floor(\n              selection.attr('transform').replace(/[^\\d.]/g, '')\n            )\n            const x = Math.floor(e.x)\n            return transform - x <= 5 && transform - x >= -5\n          })\n          .select('text')\n          .attr('fill', 'var(--v-primary-base')\n      }\n    },\n    rawUpdateChart() {\n      if (!this.chart) return\n      const yOffset = this.height - this.padding.y\n\n      const maxBandwidth =\n        ((this.width - this.padding.left * 2 - this.padding.right * 2) /\n          this.ticks) *\n        0.8\n\n      const bandwidth = maxBandwidth < 75 ? maxBandwidth : 75\n      const bandwidthNoPadding =\n        (this.width - this.padding.left * 2 - this.padding.right * 2) /\n        this.ticks\n\n      const xAxis = d3\n        .axisBottom(this.x)\n        .ticks(this.ticks)\n        .tickSizeOuter(0)\n        .tickFormat(date => {\n          let formatted = d3.timeFormat(this.format)(date)\n\n          if (this.period === 'Week') {\n            formatted = formatted[0]\n          }\n          return formatted\n        })\n\n      const yAxis = d3\n        .axisLeft(this.y)\n        .tickSizeOuter(0)\n        .tickSize(this.width - this.padding.x)\n\n      this.xAxisGroup\n        .style(\n          'transform',\n          `translate(0, ${this.height -\n            this.padding.bottom +\n            this.padding.bottom -\n            25}px)`\n        )\n        .transition()\n        .duration(1000)\n        .ease(d3.easeQuad)\n        .call(xAxis)\n\n      this.yAxisGroup\n        .transition()\n        .duration(1000)\n        .ease(d3.easeQuad)\n        .style(\n          'transform',\n          `translate(${this.width - this.padding.left}px, ${\n            this.padding.top\n          }px)`\n        )\n        .call(yAxis)\n\n      this.interactionGroup\n        .selectAll('rect')\n        .data(this.items, d => d.id)\n        .join(\n          enter =>\n            enter\n              .append('rect')\n              .attr('width', bandwidthNoPadding < 0 ? 0 : bandwidthNoPadding)\n              .attr('height', this.height)\n              .attr(\n                'x',\n                d => this.x(new Date(d.timestamp)) - bandwidthNoPadding / 2\n              )\n              .attr('fill', 'transparent')\n              .style('cursor', 'pointer')\n              .on('mousemove', (e, d) => {\n                if (!isNaN(d.runs)) {\n                  const x = this.x(new Date(d.timestamp))\n                  const y = this.y(d.runs)\n                  const runs = d.runs ? d.runs.toLocaleString() : 0\n\n                  this.hovered = {\n                    x: x,\n                    y: y,\n                    runs: runs,\n                    bandwidth: bandwidth\n                  }\n\n                  this.updateHovered(this.hovered)\n                }\n              }),\n          update => {\n            update\n              .select('rect')\n              .attr('width', bandwidthNoPadding < 0 ? 0 : bandwidthNoPadding)\n              .attr(\n                'x',\n                d => this.x(new Date(d.timestamp)) - bandwidthNoPadding / 2\n              )\n              .on('mousemove', (e, d) => {\n                if (!isNaN(d.runs)) {\n                  const x = this.x(new Date(d.timestamp))\n                  const y = this.y(d.runs)\n                  const runs = d.runs ? d.runs.toLocaleString() : 0\n\n                  this.hovered = {\n                    x: x,\n                    y: y,\n                    runs: runs,\n                    bandwidth: bandwidth\n                  }\n\n                  this.updateHovered(this.hovered)\n                }\n              })\n          },\n          exit =>\n            exit\n              .on('mouseout', null)\n              .on('mouseover', null)\n              .transition('exit')\n              .remove()\n        )\n\n      this.interactionGroup.on('mouseout', () => {\n        this.hovered = null\n        this.updateHovered()\n      })\n\n      this.mainGroup\n        .selectAll('path')\n        .data([{ id: this.period, items: this.items }], d => d.id)\n        .join(\n          enter =>\n            enter\n              .append('path')\n              .attr('stroke-width', 4.5)\n              .attr(\n                'stroke',\n                this.showPath ? 'var(--v-primary-base)' : 'transparent'\n              )\n              .attr('fill', 'none')\n              .call(enter =>\n                enter\n                  .transition()\n                  .delay(1000)\n                  .attr('d', d =>\n                    this.line(\n                      Array.from(d.items, d_ => {\n                        return { ...d_, runs: !isNaN(d_.runs) ? 0 : undefined }\n                      })\n                    )\n                  )\n                  .transition()\n                  .duration(1000)\n                  .ease(d3.easeQuad)\n                  .attr('d', d => this.line(d.items))\n              ),\n          update =>\n            update.call(update =>\n              update\n                .transition()\n                .duration(1000)\n                .ease(d3.easeQuad)\n                .attr(\n                  'stroke',\n                  this.showPath ? 'var(--v-primary-base)' : 'transparent'\n                )\n                .attr('d', d => this.line(d.items))\n            ),\n          exit =>\n            exit.call(exit =>\n              exit\n                .transition()\n                .duration(1000)\n                .ease(d3.easeQuad)\n                .attr('d', d =>\n                  this.previousLine(\n                    Array.from(d.items, d_ => {\n                      return { ...d_, runs: !isNaN(d_.runs) ? 0 : undefined }\n                    })\n                  )\n                )\n                .transition()\n                .duration(1000)\n                .style('opacity', 0)\n                .remove()\n            )\n        )\n\n      // Prediction pathing\n      // this.predictionGroup\n      //   .selectAll('path')\n      //   .data([this.predictedItems])\n      //   .join(\n      //     enter =>\n      //       enter\n      //         .append('path')\n      //         .attr('stroke-width', 1)\n      //         .attr('stroke', '#FF5733')\n      //         .attr('fill', 'none')\n      //         .attr('d', d =>\n      //           this.line(\n      //             Array.from(d, d_ => {\n      //               return { ...d_, runs: 0 }\n      //             })\n      //           )\n      //         )\n      //         .call(enter =>\n      //           enter\n      //             .transition()\n      //             .duration(1000)\n      //             .ease(d3.easeQuad)\n      //             .attr('d', this.line)\n      //         ),\n      //     update =>\n      //       update.call(update =>\n      //         update\n      //           .transition()\n      //           .duration(1000)\n      //           .ease(d3.easeQuad)\n      //           .attr('d', this.line)\n      //       )\n      //   )\n      const start = this.padding.left * 2\n      const xPosition = (d, i) =>\n        start + (bandwidthNoPadding * i - bandwidth / 2)\n      const yPosition = d => (d.runs ? this.y(d.runs) : yOffset)\n      const height = d => {\n        const h = d.runs ? yOffset - this.y(d.runs) : 0\n        return h >= 0 ? h : 0\n      }\n\n      // These are used for the text labels on the bars\n      // which are unused at the moment\n      // const transform = `translate(${bandwidth / 2 ?? 0}px)`\n      // const textContent = d =>\n      //   d.runs\n      //     ? d.runs?.toLocaleString() +\n      //       ' - ' +\n      //       new Date(d.timestamp).toLocaleString('en-US', {\n      //         dateStyle: 'short',\n      //         timeStyle: undefined\n      //       })\n      //     : null\n\n      this.mainGroup.style('transform', `translate(0, ${this.padding.top}px)`)\n\n      // Bars\n      this.mainGroup\n        .selectAll('.bar-group')\n        .data(this.items, d => d.id)\n        .join(\n          enter => {\n            const g = enter\n              .append('g')\n              .attr('id', d => `bar-${d.id}-${this.period}`)\n              .attr('class', 'bar-group')\n              .attr('opacity', this.showBars ? 1 : 0)\n              .on('mouseover', this.barMouseover)\n              .on('mouseout', this.barMouseout)\n\n            g.append('rect')\n              .attr('class', 'bar')\n              .attr('height', 0)\n              .attr('width', bandwidth)\n              .attr('fill', (d, i) =>\n                i === 0 && this.ticks < this.items.length\n                  ? 'url(#grad)'\n                  : 'var(--v-primary-base)'\n              )\n              .attr('x', xPosition)\n              .attr('y', yOffset)\n\n            // g.append('text')\n            //   .attr('x', xPosition)\n            //   .attr('y', yOffset - 5)\n            //   .style('text-anchor', 'middle')\n            //   .style('user-select', 'none')\n            //   .style('transform', transform)\n            //   .style('font', '10px Roboto, sans-serif')\n            //   .attr('fill', 'transparent')\n            //   .text(textContent)\n\n            return g.call(enter => {\n              enter\n                .select('rect')\n                .transition('enter')\n                .duration(1000)\n                .delay(250)\n                .ease(d3.easeQuad)\n                .attr('height', height)\n                .attr('y', yPosition)\n\n              // enter\n              //   .select('text')\n              //   .transition('enter')\n              //   .duration(1000)\n              //   .delay(250)\n              //   .ease(d3.easeQuad)\n              //   .attr('y', d =>\n              //     d.runs ? yPosition(d) - 5 : yOffset + this.padding.y\n              //   )\n              //   .style('font', '10px Roboto, sans-serif')\n              //   .attr('fill', this.showText ? '#546E7A' : 'transparent')\n\n              return enter\n            })\n          },\n          update => {\n            return update.call(update => {\n              update\n                .transition('update')\n                .duration(1000)\n                .ease(d3.easeQuad)\n                .attr('opacity', this.showBars ? 1 : 0)\n\n              update\n                .select('rect')\n                .transition('update')\n                .duration(1000)\n                .ease(d3.easeQuad)\n                .attr('height', height)\n                .attr('y', yPosition)\n                .attr('width', bandwidth)\n                .attr('x', xPosition)\n\n              // update\n              //   .select('text')\n              //   .transition('update')\n              //   .duration(1000)\n              //   .delay(500)\n              //   .ease(d3.easeQuad)\n              //   .attr('fill', this.showText ? '#546E7A' : 'transparent')\n              //   .attr('y', d =>\n              //     d.runs ? yPosition(d) - 5 : yOffset + this.padding.y\n              //   )\n              //   .attr('x', xPosition)\n            })\n          },\n          exit =>\n            exit.call(exit => {\n              exit\n                .select('rect')\n                .transition('exit')\n                .duration(250)\n                .ease(d3.easeQuad)\n                .attr('height', 0)\n                .attr('y', yOffset)\n\n              exit\n                .select('text')\n                .transition('exit')\n                .duration(250)\n                .ease(d3.easeQuad)\n                .attr('y', yOffset - 5)\n\n              return exit.call(exit =>\n                exit\n                  .on('click', null)\n                  .on('mouseout', null)\n                  .on('mouseover', null)\n                  .transition('exit')\n                  // .delay(250)\n                  .remove()\n              )\n            })\n        )\n    },\n    rawUpdateItems() {\n      const now = new Date()\n      now.setMinutes(59)\n      now.setHours(23)\n\n      let range,\n        setDate = true,\n        setHours = true,\n        setMinutes = true\n\n      switch (this.period) {\n        case 'Year':\n          range = d3.timeMonth\n          break\n        case 'Month':\n          range = d3.timeDay\n          setDate = false\n          break\n        case 'Week':\n          range = d3.timeDay\n          setDate = false\n          break\n        case 'Day':\n        default:\n          range = d3.timeHour\n          setDate = false\n          setHours = false\n          setMinutes = false\n          break\n      }\n\n      this.items = this.usage\n        .filter(d => {\n          if (d.kind !== 'USAGE') return\n\n          const date = new Date(d.timestamp)\n          return date >= this.from && date <= this.to\n        })\n        .reduce(\n          (arr, d) => {\n            const date = new Date(d.timestamp)\n            date.setMilliseconds(0)\n            date.setSeconds(0)\n\n            if (setMinutes) {\n              date.setMinutes(0)\n            }\n\n            if (setHours) {\n              date.setHours(0)\n            }\n\n            if (setDate) {\n              date.setDate(1)\n            }\n\n            const index = arr.findIndex(\n              d_ => d_.timestamp == date.toISOString()\n            )\n\n            if (index > -1) {\n              arr[index].runs += d.runs * -1\n            } else {\n              arr.push({\n                timestamp: date.toISOString(),\n                runs: d.runs * -1\n              })\n            }\n\n            return arr\n          },\n          range.range(this.from, this.to).map(d => {\n            const date = new Date(d)\n            return {\n              id: date.toISOString() + '-' + this.period,\n              timestamp: date.toISOString(),\n              runs: date > now ? undefined : 0\n            }\n          })\n        )\n        .sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp))\n    },\n    rawUpdateScales() {\n      const x = this.createX()\n      this.previousX = this.x\n      this.x = x\n\n      const y = this.createY()\n      this.previousY = this.y\n      this.y = y\n\n      this.line = d3\n        .line()\n        .curve(d3.curveMonotoneX)\n        .defined(d => !isNaN(d.runs)) // Use this to create gaps in data\n        .x(d => this.x(new Date(d.timestamp)) ?? 0)\n        .y(\n          d => this.height - this.padding.y + (this.y(d.runs) - this.y(0)) || 0\n        )\n\n      this.previousLine = d3\n        .line()\n        .curve(d3.curveMonotoneX)\n        .defined(d => !isNaN(d.runs)) // Use this to create gaps in data\n        .x(d => this.previousX(new Date(d.timestamp)) ?? 0)\n        .y(\n          d =>\n            this.height -\n              this.padding.y +\n              (this.previousY(d.runs) - this.previousY(0)) || 0\n        )\n\n      // this.regression = d3\n      //   .regressionLinear()\n      //   .x(d => this.x(new Date(d.timestamp)))\n      //   .y(d => d.runs)(this.regressionItems)\n\n      // this.predict = this.regression.predict\n\n      switch (this.period) {\n        case 'Year':\n          this.ticks = 13\n          this.format = '%b'\n          break\n        case 'Month':\n          this.ticks = 31\n          this.format = '%e'\n          break\n        case 'Week':\n          this.ticks = 7\n          this.format = '%a'\n          break\n        default:\n          break\n      }\n    },\n    decrementOffset() {\n      switch (this.period) {\n        case 'Year':\n        case 'Month':\n          this.offset -= 1\n          break\n        case 'Week':\n          this.offset -= 7\n          break\n        default:\n          break\n      }\n    },\n    incrementOffset() {\n      switch (this.period) {\n        case 'Year':\n        case 'Month':\n          this.offset += 1\n          break\n        case 'Week':\n          this.offset += 7\n          break\n        default:\n          break\n      }\n    }\n  },\n  apollo: {\n    usage: {\n      query: require('@/graphql/TeamSettings/usage.gql'),\n      variables() {\n        return { from: startDate, to: this.to, tenant_id: this.selectedTeam }\n      },\n      skip() {\n        return !this.from || !this.to\n      },\n      update: data => data?.usage\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"position-relative py-2 h-100\" tile fluid>\n    <div\n      class=\"d-flex align-center justify-space-between py-2 ml-n2 px-5 card-title\"\n    >\n      <div class=\"d-flex\">\n        <div class=\"text-h4 font-weight-light\">\n          Usage\n        </div>\n\n        <div>\n          <v-select\n            v-if=\"multitenancy\"\n            v-model=\"selectedTeam\"\n            dense\n            hide-details\n            outlined\n            style=\"width: 200px;\"\n            class=\"ml-6\"\n            single-line\n            :items=\"teams\"\n            item-value=\"id\"\n          >\n            <template #item=\"{ item }\">\n              <div class=\"text-subtitle-2 font-weight-light\">\n                {{ item.name }}\n              </div>\n            </template>\n            <template #selection=\"{ item }\">\n              <div class=\"text-subtitle-2 font-weight-light text-truncate\">\n                {{ item.name }}\n              </div>\n            </template>\n          </v-select>\n        </div>\n      </div>\n\n      <div\n        v-if=\"$vuetify.breakpoint.smAndUp\"\n        class=\"font-weight-light d-flex align-center justify-center\"\n        :class=\"{ 'text-caption': $vuetify.breakpoint.smOnly }\"\n      >\n        <v-btn\n          :disabled=\"decrementOffsetDisabled\"\n          icon\n          depressed\n          small\n          @click=\"decrementOffset\"\n        >\n          <v-icon>chevron_left</v-icon>\n        </v-btn>\n\n        <span class=\"mx-2\"> {{ fromDisplay }} - {{ toDisplay }} </span>\n\n        <v-btn\n          :disabled=\"offset === 0\"\n          icon\n          depressed\n          small\n          @click=\"incrementOffset\"\n        >\n          <v-icon>chevron_right</v-icon>\n        </v-btn>\n\n        <v-btn\n          :disabled=\"offset === 0\"\n          icon\n          depressed\n          small\n          @click=\"offset = 0\"\n        >\n          <v-icon>last_page</v-icon>\n        </v-btn>\n      </div>\n\n      <div>\n        <span\n          class=\"cursor-pointer px-4 text-title d-inline-flex align-center justify-center\"\n          :class=\"\n            period == 'Week'\n              ? 'blue-grey--text'\n              : 'blue-grey--text text--lighten-4'\n          \"\n          @click=\"period = 'Week'\"\n        >\n          <v-icon\n            x-small\n            class=\"mr-2\"\n            :color=\"period == 'Week' ? 'primary' : 'grey lighten-2'\"\n          >\n            fiber_manual_record\n          </v-icon>\n          Week\n        </span>\n        <span\n          class=\"cursor-pointer px-4 text-title d-inline-flex align-center justify-center\"\n          :class=\"\n            period == 'Month'\n              ? 'blue-grey--text'\n              : 'blue-grey--text text--lighten-4'\n          \"\n          @click=\"period = 'Month'\"\n        >\n          <v-icon\n            x-small\n            class=\"mr-2\"\n            :color=\"period == 'Month' ? 'primary' : 'grey lighten-2'\"\n          >\n            fiber_manual_record\n          </v-icon>\n          Month\n        </span>\n        <span\n          class=\"cursor-pointer px-4 text-title d-inline-flex align-center justify-center\"\n          :class=\"\n            period == 'Year'\n              ? 'blue-grey--text'\n              : 'blue-grey--text text--lighten-4'\n          \"\n          @click=\"period = 'Year'\"\n        >\n          <v-icon\n            x-small\n            class=\"mr-2\"\n            :color=\"period == 'Year' ? 'primary' : 'grey lighten-2'\"\n          >\n            fiber_manual_record\n          </v-icon>\n          Year\n        </span>\n      </div>\n    </div>\n\n    <v-card-text ref=\"parent\" class=\"chart-container pt-16 pr-8\">\n      <svg :id=\"`${id}-svg`\" class=\"svg\">\n        <defs>\n          <linearGradient id=\"grad\" x1=\"0%\" y1=\"50%\" x2=\"100%\" y2=\"50%\">\n            <stop\n              offset=\"0%\"\n              style=\"\n                stop-color: rgb(39, 177, 255);\n                stop-opacity: 0;\n              \"\n            />\n            <stop\n              offset=\"100%\"\n              style=\"\n                stop-color: rgb(39, 177, 255);\n                stop-opacity: 0.25;\n              \"\n            />\n          </linearGradient>\n        </defs>\n      </svg>\n    </v-card-text>\n\n    <div\n      v-if=\"hovered\"\n      class=\"tooltip v-tooltip__content rounded\"\n      :style=\"tooltipStyle\"\n    >\n      {{ hovered.runs }} runs\n    </div>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.h-100 {\n  height: 100%;\n}\n\n.chart-container {\n  height: 100%;\n  position: relative;\n  width: 100%;\n}\n\nsvg {\n  height: 100%;\n  margin: auto;\n  width: 100%;\n}\n\n.card-title {\n  position: absolute;\n  width: 100%;\n  z-index: 1;\n}\n\n.tooltip {\n  pointer-events: none;\n  position: absolute;\n  text-overflow: initial;\n  transform: translate(-50%);\n  transition: all 50ms;\n  user-select: none;\n  z-index: 4;\n}\n</style>\n\n<style lang=\"scss\">\n// We use unscoped css here\n// so that we don't need to do a post-selection\n// on the axis\n.usage-x-axis-group {\n  color: #9e9e9e !important;\n  font: 16px Roboto, sans-serif;\n  opacity: 0.8;\n  user-select: none;\n\n  @media screen and (max-width: 1440px) {\n    font: 12px Roboto, sans-serif;\n  }\n\n  @media screen and (max-width: 1200px) {\n    font: 10px Roboto, sans-serif;\n  }\n\n  @media screen and (max-width: 800px) {\n    font: 8px Roboto, sans-serif;\n  }\n\n  .domain {\n    opacity: 0;\n    stroke: rgba(0, 0, 0, 0.12);\n    stroke-width: 1.65px;\n  }\n\n  .tick line {\n    opacity: 0;\n  }\n}\n\n.usage-y-axis-group {\n  color: #9e9e9e !important;\n  font: 12px Roboto, sans-serif;\n  opacity: 0.8;\n  text-anchor: start;\n  user-select: none;\n\n  .domain {\n    opacity: 0;\n  }\n\n  .tick:nth-child(odd) {\n    opacity: 0;\n  }\n\n  .tick line {\n    stroke: rgba(0, 0, 0, 0.05);\n    stroke-dasharray: 10, 10;\n    stroke-width: 1.65px;\n    transform: translate(50px);\n  }\n\n  .tick:last-of-type line {\n    opacity: 0;\n  }\n}\n\n.theme--dark .usage-y-axis-group {\n  /* stylelint-disable-next-line */\n  .tick line {\n    stroke: rgba(255, 255, 255, 0.05);\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Account/Usage/UsageToday.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nexport default {\n  data() {\n    return {\n      loadingKey: 0,\n      // Domain\n      from: null,\n      to: null\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    loading() {\n      return this.loadingKey > 0\n    }\n  },\n  mounted() {\n    this.from = new Date()\n    this.from.setMinutes(0)\n    this.from.setHours(0)\n\n    this.to = new Date()\n    this.to.setMinutes(59)\n    this.to.setHours(23)\n\n    this.$apollo.queries['usage'].refetch()\n  },\n  apollo: {\n    usage: {\n      query: require('@/graphql/TeamSettings/usage.gql'),\n      variables() {\n        return {\n          from: this.from,\n          to: this.to,\n          tenant_id: this.tenant.id\n        }\n      },\n      skip() {\n        return !this.from || !this.to\n      },\n      loadingKey: 'loadingKey',\n      update: data =>\n        data?.usage\n          .filter(u => u.kind == 'USAGE')\n          .reduce((prev, val) => (prev += Math.abs(val.runs)), 0)\n          ?.toLocaleString()\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card tile class=\"f-wh py-8 d-flex flex-column align-center justify-center\">\n    <div class=\"rounded pa-3 primary\">\n      <v-icon x-large color=\"white\">\n        fad fa-tasks\n      </v-icon>\n    </div>\n\n    <div class=\"text-center\">\n      <div class=\"text-subtitle-1 text--disabled\">Task runs today</div>\n\n      <v-skeleton-loader\n        :loading=\"loading\"\n        type=\"image\"\n        transition=\"quick-fade\"\n        height=\"36\"\n        tile\n      >\n        <div class=\"text-h4\">\n          {{ usage }}\n        </div>\n      </v-skeleton-loader>\n    </div>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.f-wh {\n  height: 100%;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Account/Users.vue",
    "content": "<script>\nimport { teamProfileMixin } from '@/mixins/teamProfileMixin.js'\nimport UpgradeAlert from '@/components/License/UpgradeAlert'\n// import { paymentMixin } from '@/mixins/paymentMixin.js'\nimport { mapGetters, mapActions } from 'vuex'\nimport LogRocket from 'logrocket'\n\nexport default {\n  components: { UpgradeAlert },\n  mixins: [teamProfileMixin],\n  data() {\n    return {\n      desiredUsers: null,\n      show: false,\n      diff: 0,\n      userCost: 100,\n      cardError: '',\n      loading: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['license']),\n    ...mapGetters('user', ['user']),\n    users: {\n      get() {\n        return this.license?.terms?.users - 1\n      },\n      set(x) {\n        return x\n      }\n    },\n    upgradeOrDowngrade() {\n      if (this.diff >= 0) return 'Upgrade'\n      return 'Downgrade'\n    },\n    memberMembers() {\n      return this.diff > 1 ? 'members' : 'member'\n    },\n    existingCard() {\n      return this.tenant?.stripe_customer?.sources?.data[0]?.card\n    },\n    isSelfServe() {\n      return (\n        this.license?.terms?.plan === 'SELF_SERVE' ||\n        this.license?.terms?.is_self_serve\n      )\n    },\n    max() {\n      return 4\n    },\n    numArr() {\n      let numArr = []\n      for (let i = 1; i < this.license?.terms?.users + this.max + 1; i += 1) {\n        numArr.push(i)\n      }\n      return numArr\n    },\n    showPay() {\n      return (\n        this.show && this.isSelfServe && this.isTenantAdmin && !this.loading\n      )\n    },\n    disableButton() {\n      return !this.existingCard || this.diff == 0 || this.errors > 0\n    },\n    addOrRemove() {\n      if (this.diff >= 0) return 'add'\n      return 'remove'\n    },\n    userOrUsers() {\n      return Math.abs(this.diff) === 1 ? 'user' : 'users'\n    },\n    desiredUserOrUsers() {\n      return this.desiredUsers > 1 ? 'users' : 'user'\n    },\n    totalCost() {\n      return (this.desiredUsers - 1) * this.userCost\n    },\n    planType() {\n      if (this.license?.terms?.plan == 'SELF_SERVE') return 'Cloud Developer'\n      if (this.license?.terms?.plan == 'PLATFORM') return 'Cloud Enterprise'\n      return 'Custom'\n    }\n  },\n  watch: {\n    diff(val) {\n      if (val === 0) {\n        this.show = false\n      }\n    }\n  },\n  methods: {\n    ...mapActions('license', ['getLicense']),\n    ...mapActions('alert', ['setAlert']),\n    ...mapActions('tenant', ['getTenants', 'setCurrentTenant']),\n    ...mapActions('user', ['getUser']),\n    handleInput(ev) {\n      this.diff = ev - this.license?.terms?.users + 1\n      if (this.diff != 0) this.show = true\n    },\n    handleChange(ev) {\n      this.diff = ev - this.license?.terms?.users + 1\n      if (this.diff != 0) this.show = true\n      this.desiredUsers = ev + 1\n    },\n    async updateLicense() {\n      this.loading = true\n      try {\n        const license = await this.$apollo.mutate({\n          mutation: require('@/graphql/License/update-self-serve-cloud-license.gql'),\n          variables: {\n            license_id: this.license.id,\n            users: this.desiredUsers,\n            confirm: true\n          },\n          errorPolicy: 'all'\n        })\n        if (\n          license.data &&\n          license.data.update_self_serve_cloud_license?.success\n        ) {\n          await this.getLicense()\n          this.setAlert({\n            alertShow: true,\n            alertMessage: 'Users updated.',\n            alertType: 'Success',\n            alertLink: { name: 'members' },\n            linkText: this.diff > 0 ? `Invite ${this.memberMembers}` : ''\n          })\n          this.reset()\n        } else {\n          this.cardError = license.errors[0].message\n          this.loading = false\n        }\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'users',\n            stage: 'update license'\n          }\n        })\n        this.loading = false\n        this.cardError = 'There was a problem updating your license'\n      }\n    },\n    async reset() {\n      this.show = false\n      this.users = this.license.terms.users - 1\n      this.diff = 0\n\n      await this.getUser()\n      const tenantSlug = this.user.memberships.filter(\n        membership => membership.tenant.id === this.tenant.id\n      )?.tenant?.slug\n\n      if (tenantSlug) {\n        this.setCurrentTenant(tenantSlug)\n      }\n      this.loading = false\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card data-cy=\"users-card\" tile class=\"mx-auto\" :loading=\"loading\">\n    <v-card-title class=\"mb-2 text-h4 font-weight-light\">\n      Add users\n    </v-card-title>\n\n    <v-card-subtitle>\n      Check and update the number of users in your account. To see active\n      membership information visit the\n      <router-link :to=\"'/team/members'\">\n        members page\n      </router-link>\n      .\n    </v-card-subtitle>\n    <v-card-text>\n      <v-alert\n        v-if=\"!isTenantAdmin & !loading\"\n        class=\"mx-auto mb-12\"\n        border=\"left\"\n        colored-border\n        elevation=\"2\"\n        type=\"warning\"\n        tile\n        icon=\"lock\"\n        max-width=\"540\"\n        >Only your team's administrators can modify these settings.\n      </v-alert>\n      <v-alert\n        v-else-if=\"!isSelfServe & !loading\"\n        class=\"mx-auto mb-12\"\n        border=\"left\"\n        colored-border\n        elevation=\"2\"\n        type=\"info\"\n        tile\n        icon=\"lock\"\n        max-width=\"540\"\n      >\n        You are on a {{ planType }} license. To change your license terms,\n        please\n        <a href=\"https://www.prefect.io/pricing#contact\" target=\"_blank\"\n          >contact our sales team</a\n        >\n      </v-alert>\n\n      <v-slider\n        v-if=\"isSelfServe\"\n        data-cy=\"user-slider\"\n        :value=\"users\"\n        :readonly=\"!isTenantAdmin\"\n        :max=\"max\"\n        :tick-size=\"5\"\n        :tick-labels=\"numArr\"\n        ticks=\"always\"\n        @input=\"handleInput($event)\"\n        @change=\"handleChange($event)\"\n      >\n      </v-slider>\n    </v-card-text>\n    <div v-if=\"showPay\" clas=\"mt-12\">\n      <v-card-text>\n        <UpgradeAlert :license=\"license\" />\n      </v-card-text>\n      <v-card-title>\n        {{ upgradeOrDowngrade }} to {{ desiredUsers }} {{ desiredUserOrUsers }}\n      </v-card-title>\n      <v-list hide-details>\n        <v-list-item\n          ><v-icon small class=\"pr-4\">star_rate</v-icon> You'll\n          {{ addOrRemove }}\n          <span class=\"font-weight-bold mx-1\">{{ Math.abs(diff) }}</span>\n          {{ userOrUsers }} at\n          <span class=\"font-weight-bold mx-1\">${{ userCost }}</span> /user/month\n          (<span class=\"font-weight-bold mr-1\"\n            >${{ Math.abs(diff) * userCost }}</span\n          >\n          total)\n        </v-list-item>\n        <v-list-item\n          ><v-icon small class=\"pr-4\">star_rate</v-icon> Your card\n          <span v-if=\"existingCard\" class=\"mx-1\">\n            ending in\n            <span class=\"font-weight-bold\"> {{ existingCard.last4 }}</span>\n          </span>\n          will now be charged\n          <span class=\"font-weight-bold mx-1\">${{ totalCost }} </span> on a\n          monthly basis</v-list-item\n        >\n\n        <v-list-item\n          ><div class=\"red--text\">\n            {{ cardError }}\n          </div>\n        </v-list-item>\n      </v-list>\n    </div>\n    <v-alert\n      v-if=\"!existingCard && isSelfServe && isTenantAdmin && !loading\"\n      class=\"mx-auto mb-12\"\n      border=\"left\"\n      colored-border\n      elevation=\"2\"\n      type=\"warning\"\n      tile\n      icon=\"lock\"\n      max-width=\"540\"\n      >Please enter payment details before adding users\n    </v-alert>\n\n    <v-card-actions v-if=\"isTenantAdmin && isSelfServe\">\n      <v-spacer></v-spacer>\n\n      <v-btn\n        v-if=\"showPay\"\n        color=\"primary\"\n        data-cy=\"add-user-button\"\n        :loading=\"loading\"\n        :disabled=\"disableButton\"\n        @click=\"updateLicense\"\n        >{{ addOrRemove }} {{ userOrUsers }}\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style>\n.v-slider--horizontal {\n  cursor: pointer !important;\n}\n\n/* stylelint-disable */\n.v-slider__tick-label {\n  bottom: 0;\n  left: 0;\n  right: 0;\n  top: 8px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Admin.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nimport { mapGetters } from 'vuex'\nimport { pollsTenantsMixin } from '@/mixins/polling/pollsTenantsMixin'\nimport BreadCrumbs from '@/components/BreadCrumbs'\nimport NavTabBar from '@/components/NavTabBar'\nimport SubPageNav from '@/layouts/SubPageNav'\n\nexport default {\n  metaInfo() {\n    return {\n      titleTemplate: `%s - Admin | ${this.pageTitle}`\n    }\n  },\n  components: {\n    BreadCrumbs,\n    NavTabBar,\n    SubPageNav\n  },\n  mixins: [pollsTenantsMixin],\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'tenants']),\n    ...mapGetters('license', ['planType', 'license']),\n    pageTitle() {\n      const pageTitles = {\n        '/admin/teams/new': 'New team',\n        '/admin/account':\n          this.license?.account_name || this.tenant?.name || 'Account',\n        '/admin/teams': `${\n          this.license?.account_name ? this.license.account_name + ' ' : ''\n        }Teams <span class=\"font-weight-light text-h6\">(${\n          this.teams.length\n        })</span>`\n      }\n\n      return pageTitles[this.$route.path]\n    },\n    pageType() {\n      return this.$route.path == '/admin/teams/new' ? 'New team' : 'Account'\n    },\n    crumbs() {\n      return this.$route.path == '/admin/teams/new'\n        ? [\n            {\n              text: 'Teams',\n              route: { path: '/admin/teams' }\n            }\n          ]\n        : []\n    },\n    tabs() {\n      return [\n        {\n          name: 'Account',\n          to: { path: '/admin/account' },\n          icon: 'fad fa-abacus'\n        },\n        {\n          name: 'Teams',\n          to: { path: '/admin/teams' },\n          icon: 'groups',\n          disabled: !this.multitenancy,\n          badgeText: this.multitenancy ? null : 'Upgrade',\n          cardText: this.multitenancy\n            ? null\n            : 'Multi-team accounts are an enterprise feature; for more information',\n          cardLink: 'https://www.prefect.io/pricing#contact',\n          cardLinkText: this.multitenancy ? null : 'contact sales'\n        }\n      ]\n    },\n    teams() {\n      return [...this.tenants?.filter(t => t.license_id == this.license?.id)]\n    },\n    multitenancy() {\n      return this.license?.terms.tenants > 1\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet color=\"appBackground\" class=\"position-relative\">\n    <SubPageNav icon=\"groups\" :page-type=\"pageType\" hide-banners>\n      <span\n        slot=\"breadcrumbs\"\n        :style=\"\n          $vuetify.breakpoint.smAndDown && {\n            display: 'inline',\n            'font-size': '0.875rem'\n          }\n        \"\n      >\n        <BreadCrumbs :crumbs=\"crumbs\" />\n      </span>\n\n      <span slot=\"page-title\" v-html=\"pageTitle\" />\n\n      <span slot=\"tabs\" style=\"width: 100%;\">\n        <NavTabBar :tabs=\"tabs\" page=\"Account\" paths />\n      </span>\n    </SubPageNav>\n\n    <div\n      class=\"container-body mx-auto\"\n      :style=\"{\n        'padding-top': $vuetify.breakpoint.smOnly ? '73px' : '123px'\n      }\"\n    >\n      <transition name=\"quick-fade\" mode=\"out-in\">\n        <router-view />\n      </transition>\n    </div>\n  </v-sheet>\n</template>\n\n<style lang=\"scss\" scoped>\n.container-body {\n  max-width: 1440px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Teams/InviteUsers.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport { EMAIL_REGEX } from '@/utils/regEx'\n\nconst defaultRoles = {\n  USER: 'User',\n  READ_ONLY_USER: 'Read only',\n  TENANT_ADMIN: 'Administrator',\n  ENTERPRISE_LICENSE_ADMIN: 'License Administrator',\n  RUNNER: 'Runner'\n}\n\nexport default {\n  data() {\n    return {\n      invitation: {\n        email: null,\n        role: null\n      },\n\n      invitations: [],\n      roles: [],\n      users: [],\n\n      // Input rules\n      rules: {\n        email: value =>\n          EMAIL_REGEX.test(value) || 'Please enter a valid email address.',\n        required: value => !!value || 'This field is is required.'\n      },\n      loadingKey: 0,\n      loading: false,\n      disabled: false,\n      addedUsers: [],\n      removedInvitations: []\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['hasPermission', 'permissions']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['user']),\n    filteredUsers() {\n      if (!this.users) return []\n      return this.users.filter(\n        u =>\n          !this.invitations.find(i => i.email == u.email) &&\n          this.user.email !== u.email\n      )\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['addNotification', 'updateNotification']),\n    async inviteUser(user) {\n      this.loading = true\n      let error\n\n      this.addedUsers.push(user.id)\n\n      const notificationId = await this.addNotification({\n        color: 'primaryLight',\n        loading: true,\n        text: `Inviting <span class=\"font-weight-medium\">${user.email}</span>`,\n        dismissable: false\n      })\n\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Tenant/create-membership-invitation.gql'),\n          variables: {\n            input: {\n              email: user.email,\n              role_id: user.role\n            }\n          }\n        })\n\n        await this.$apollo.queries['invitationsQuery']?.refetch()\n      } catch (e) {\n        switch (e?.toString()) {\n          case 'This tenant already has the maximum number of users.':\n            error = 'Your license already has the maximum number of users.'\n            break\n\n          case `Error: GraphQL error: A user with email \"${user.email}\" already has a membership in tenant ${this.tenant.id}.`:\n          case `A user with email \"${user.email}\" has already been invited.`:\n            error = `<span class=\"font-weight-medium\">${user.email}</span> has already been invited.`\n            break\n          default:\n            error = e?.toString()\n            break\n        }\n\n        this.addedUsers = []\n      } finally {\n        this.loading = false\n        await this.updateNotification({\n          id: notificationId,\n          notification: {\n            color: error ? 'error' : 'primary',\n            text: error\n              ? error\n              : `<span class=\"font-weight-medium\">${user.email}</span> invited.`,\n            loading: false,\n            dismissable: true,\n            timeout: 10000\n          }\n        })\n\n        if (!error) this.invitation.email = null\n      }\n    },\n    async uninviteUser(invitation) {\n      let error\n\n      this.removedInvitations.push(invitation.id)\n\n      const notificationId = await this.addNotification({\n        color: 'primaryLight',\n        loading: true,\n        text: `Removing invitation for <span class=\"font-weight-medium\">${invitation.email}</span>`,\n        dismissable: false\n      })\n\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Tenant/delete-membership-invitation.gql'),\n          variables: {\n            membershipInvitationId: invitation.id\n          }\n        })\n\n        await this.$apollo.queries['invitationsQuery']?.refetch()\n      } catch (e) {\n        error = e?.toString()\n        this.removedInvitations = []\n      } finally {\n        this.loading = false\n        await this.updateNotification({\n          id: notificationId,\n          notification: {\n            color: error ? 'error' : 'primary',\n            text: error\n              ? error\n              : `Invitation for <span class=\"font-weight-medium\">${invitation.email}</span> removed.`,\n            loading: false,\n            dismissable: true,\n            timeout: 10000\n          }\n        })\n      }\n    }\n  },\n  apollo: {\n    invitationsQuery: {\n      query: require('@/graphql/Account/invitations.gql'),\n      loadingKey: 'loadingKey',\n      update(data) {\n        if (!data) return []\n        this.invitations = data.membership_invitation.sort(\n          (a, b) => new Date(b.created) - new Date(a.created)\n        )\n\n        this.addedUsers = []\n        this.removedInvitations = []\n        return data.membership_invitation\n      }\n    },\n    usersQuery: {\n      query: require('@/graphql/Account/license-users.gql'),\n      loadingKey: 'loadingKey',\n      skip() {\n        return (\n          !this.hasPermission('license', 'admin') || this.roles.length === 0\n        )\n      },\n      update(data) {\n        if (!data) return\n        const users = data.license_users.map(u => {\n          return {\n            ...u,\n            role: this.roles.find(r => r.name == 'USER').id\n          }\n        })\n        this.users = users\n        this.addedUsers = []\n        this.removedInvitations = []\n        return users\n      },\n      fetchPolicy: 'no-cache'\n    },\n    rolesQuery: {\n      query: require('@/graphql/TeamSettings/roles.gql'),\n      loadingKey: 'loadingKey',\n      update(data) {\n        if (!data) return\n        const roles = data.auth_role?.map(r => {\n          return { ...r, label: defaultRoles[r.name] || r.name }\n        })\n        this.roles = roles\n        this.invitation.role = data.auth_role?.find(r => r.name == 'USER').id\n        return roles\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-card class=\"containing-card utilGrayDark--text mx-4\" flat outlined>\n      <v-card-title class=\"text-h4 font-weight-light\">\n        Add users to your team\n      </v-card-title>\n\n      <v-card-text class=\"mt-4\">\n        <v-row>\n          <v-col cols=\"12\" md=\"6\" class=\"pr-8\">\n            <div class=\"d-flex flex-column align-end justify-center\">\n              <v-text-field\n                v-model=\"invitation.email\"\n                class=\"mb-3 align-self-stretch\"\n                dense\n                label=\"Email\"\n                data-cy=\"invite-email\"\n                prepend-icon=\"alternate_email\"\n                outlined\n                autocomplete=\"new-password\"\n                :rules=\"[rules.email]\"\n                validate-on-blur\n                full-width\n                :disabled=\"loading\"\n              />\n\n              <v-autocomplete\n                data-public\n                v-model=\"invitation.role\"\n                outlined\n                dense\n                :allow-overflow=\"false\"\n                auto-select-first\n                label=\"Role\"\n                class=\"align-self-stretch\"\n                data-cy=\"invite-role\"\n                prepend-icon=\"supervised_user_circle\"\n                :items=\"roles\"\n                :rules=\"[rules.required]\"\n                item-text=\"label\"\n                item-value=\"id\"\n                :disabled=\"loading\"\n              >\n              </v-autocomplete>\n\n              <v-btn\n                class=\"justify-self-end\"\n                depressed\n                color=\"primary\"\n                width=\"200\"\n                :disabled=\"\n                  disabled || !invitation.email || !invitation.role || loading\n                \"\n                @click.stop=\"inviteUser(invitation)\"\n              >\n                Invite\n              </v-btn>\n            </div>\n          </v-col>\n          <v-col\n            cols=\"12\"\n            md=\"6\"\n            class=\"pl-8\"\n            :style=\"{\n              'border-left': $vuetify.breakpoint.smAndDown\n                ? null\n                : 'thin solid #eee'\n            }\"\n          >\n            <div class=\"text-h5 font-weight-light\">\n              Invitations\n            </div>\n\n            <div v-if=\"invitations.length > 0\" class=\"mt-2 invitations-section\">\n              <transition-group name=\"user-wrapper\" mode=\"out-in\" tag=\"div\">\n                <div\n                  v-for=\"inv in invitations\"\n                  :key=\"inv.id\"\n                  class=\"invitation d-inline-flex align-center justify-space-between\"\n                  :class=\"{ disabled: removedInvitations.includes(inv.id) }\"\n                >\n                  <div class=\"text-truncate text-body-1 font-weight-light\">\n                    {{ inv.email }}\n                  </div>\n\n                  <v-btn\n                    class=\"actions\"\n                    icon\n                    x-small\n                    depressed\n                    :disabled=\"loading\"\n                    @click=\"uninviteUser(inv)\"\n                  >\n                    <v-icon color=\"error\">delete</v-icon>\n                  </v-btn>\n                </div>\n              </transition-group>\n            </div>\n\n            <div v-else class=\"font-weight-light\">None</div>\n          </v-col>\n        </v-row>\n\n        <v-divider class=\"my-8\" />\n\n        <transition name=\"fade\" mode=\"out-in\">\n          <div v-if=\"filteredUsers.length > 0\">\n            <div class=\"text-h5 font-weight-light\">\n              Suggested\n            </div>\n\n            <div v-if=\"filteredUsers.length > 0\" class=\"mt-4\">\n              <transition-group name=\"user-wrapper\" mode=\"out-in\">\n                <div\n                  v-for=\"u in filteredUsers\"\n                  :key=\"u.id\"\n                  class=\"utilGrayDark--text user-card d-inline-flex align-center justify-space-between px-3 mr-4 my-2 text-body-1\"\n                  :class=\"{\n                    disabled: addedUsers.includes(u.id)\n                  }\"\n                >\n                  <div class=\"text-truncate\">\n                    {{\n                      u.first_name || u.last_name\n                        ? u.first_name + ' ' + u.last_name\n                        : u.username\n                    }}\n                  </div>\n\n                  <div class=\"actions d-flex align-center justify-end ml-auto\">\n                    <v-autocomplete\n                      data-public\n                      v-model=\"u.role\"\n                      outlined\n                      dense\n                      class=\"actions-role\"\n                      hide-details\n                      :allow-overflow=\"false\"\n                      auto-select-first\n                      single-line\n                      label=\"Role\"\n                      :items=\"roles\"\n                      item-text=\"label\"\n                      item-value=\"id\"\n                      :disabled=\"addedUsers.includes(u.id)\"\n                      style=\"width: 200px;\"\n                    >\n                    </v-autocomplete>\n                    <v-btn\n                      small\n                      depressed\n                      color=\"primary\"\n                      @click=\"inviteUser(u)\"\n                    >\n                      Invite\n                    </v-btn>\n                  </div>\n                </div>\n              </transition-group>\n            </div>\n          </div>\n        </transition>\n      </v-card-text>\n\n      <v-card-actions class=\"d-flex align-center justify-center mt-8\">\n        <v-btn\n          :to=\"'/admin/teams'\"\n          depressed\n          color=\"primary\"\n          style=\"width: 300px;\"\n        >\n          Close\n        </v-btn>\n      </v-card-actions>\n    </v-card>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.containing-card {\n  transition: height 150ms;\n}\n\n.user-card {\n  background-color: var(--v-appForeground-base);\n  border-left: thin solid rgba(0, 0, 0, 0.12);\n  height: 48px;\n  max-width: 500px;\n  transition: all 150ms;\n  width: 100%;\n\n  .actions {\n    .actions-role {\n      transform: scale(0.8);\n    }\n  }\n}\n\n.disabled {\n  cursor: progress;\n  opacity: 0.4;\n  user-select: none;\n}\n\n.user-wrapper {\n  &-enter,\n  &-leave-to,\n  &-leave-active {\n    opacity: 0;\n    transform: translateY(30px);\n  }\n\n  &-leave-active {\n    position: absolute;\n  }\n}\n\n.invitations-section {\n  max-height: 175px;\n  overflow: scroll;\n\n  .invitation {\n    border-left: 2px solid var(--v-primary-base);\n    max-width: 300px;\n    padding: 4px 16px 4px 12px;\n    margin-bottom: 6px;\n    width: 50%;\n\n    .actions {\n      opacity: 0;\n      transition: opacity 10ms;\n    }\n\n    &:hover {\n      .actions {\n        opacity: 1;\n      }\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Teams/NewTeam.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nimport InviteUsers from '@/pages/Admin/Teams/InviteUsers'\nimport TeamForm from '@/pages/Admin/Teams/TeamForm'\n\nexport default {\n  components: { TeamForm, InviteUsers },\n  data() {\n    return {\n      step: 1\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['permissions', 'license', 'planType']),\n    multitenancy() {\n      return this.license?.terms?.tenants > 1\n    }\n  }\n}\n</script>\n\n<template>\n  <div style=\"min-height: 400px;\">\n    <v-container\n      v-if=\"!multitenancy\"\n      class=\"text-h5 text-center blue-grey--text d-flex align-center justify-center\"\n      style=\"height: 400px;\"\n      fluid\n    >\n      <div>\n        <i class=\"fad fa-lock-alt fa-3x\" />\n        <div class=\"mt-6\">\n          <span v-if=\"planType('ENTERPRISE')\">\n            Your plan doesn't include multi-tenancy;\n          </span>\n          <span v-else\n            >Multi-tenancy is only available on Enterprise plans;</span\n          >\n          <br />contact\n          <a class=\"font-weight-medium\" href=\"sales@prefect.io\"\n            >sales@prefect.io</a\n          >\n          to learn more.\n        </div>\n      </div>\n    </v-container>\n\n    <v-container v-else fluid>\n      <v-btn\n        class=\"text-capitalize text-h6 font-weight-light ml-4\"\n        :to=\"'/admin/teams'\"\n        text\n        color=\"transparent\"\n      >\n        <v-icon color=\"blue-grey lighten-3\" left>chevron_left</v-icon>\n        <span class=\"blue-grey--text\">Back</span>\n      </v-btn>\n\n      <div\n        class=\"d-flex justify-center align-center mx-auto mb-4\"\n        style=\"max-width: 400px;\"\n      >\n        <div\n          class=\"rounded-circle d-flex align-center justify-center step text-h5\"\n          :class=\"{ active: step == 1 }\"\n        >\n          <v-icon>people_alt</v-icon>\n        </div>\n        <v-divider\n          style=\"border-width: 1px;\"\n          :style=\"{\n            'border-color': step == 2 ? 'var(--v-primary-base)' : null\n          }\"\n        />\n        <div\n          class=\"rounded-circle d-flex align-center justify-center step text-h5\"\n          :class=\"{ active: step == 2 }\"\n        >\n          <v-icon>person_add_alt_1</v-icon>\n        </div>\n      </div>\n\n      <transition name=\"quick-fade\" mode=\"out-in\">\n        <TeamForm v-if=\"step === 1\" :key=\"1\" @team-created=\"step = 2\" />\n        <InviteUsers v-else-if=\"step === 2\" :key=\"2\" />\n      </transition>\n    </v-container>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.step {\n  border: 2px solid rgba(0, 0, 0, 0.12);\n  height: 34px;\n  transition: all 200ms;\n  width: 34px;\n\n  &.active {\n    border-color: var(--v-primary-base);\n    border-width: 3px;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Teams/TeamForm.vue",
    "content": "<script>\nimport LogRocket from 'logrocket'\nimport { mapActions, mapGetters } from 'vuex'\nimport { pollsTenantsMixin } from '@/mixins/polling/pollsTenantsMixin'\nimport { clearCache } from '@/vue-apollo'\n\nimport { adjectives } from '@/components/RunConfig/adjectives'\nimport { animals } from '@/components/RunConfig/animals'\n\nconst adjectivesLength = adjectives.length\nconst animalsLength = animals.length\n\nexport default {\n  mixins: [pollsTenantsMixin],\n  data() {\n    return {\n      currentTeam: null,\n      loading: false,\n      teamName: this.generateRandomName(),\n      teamSlug: null,\n      slugErrors: [],\n\n      // Regexes to check if a slug is invalid\n      slugCharRegex: /^[a-z0-9|-]*$/,\n      dashPositionRegex: /^(-)|-{2,}|(-)$/\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'tenants'])\n  },\n  watch: {\n    teamName(val) {\n      try {\n        this.teamSlug = this.slugifyString(val)\n      } catch {\n        /* */\n      }\n    }\n  },\n  mounted() {\n    this.teamSlug = this.slugifyString(this.teamName)\n    this.currentTeam = this.tenant.slug\n  },\n  methods: {\n    ...mapActions('alert', ['addNotification', 'updateNotification']),\n    ...mapActions('data', ['resetData']),\n    ...mapActions('tenant', ['setCurrentTenant', 'updateTenantSettings']),\n    ...mapActions('user', ['getUser']),\n    generateRandomName() {\n      const adjective = adjectives[Math.floor(Math.random() * adjectivesLength)]\n      const animal = animals[Math.floor(Math.random() * animalsLength)]\n      return (\n        adjective.charAt(0).toUpperCase() +\n        adjective.slice(1) +\n        ' ' +\n        animal.charAt(0).toUpperCase() +\n        animal.slice(1) +\n        's'\n      )\n    },\n    slugifyString(str) {\n      return encodeURI(\n        str\n          .replace(' ', '-')\n          .replace(/[^a-zA-Z0-9-_]/g, '')\n          .toLowerCase()\n      )\n    },\n    checkSlug(slug) {\n      this.slugErrors = []\n\n      // If slug is not provided, reset to original value\n      //\n      // Make this field required if there is no original value\n      if (slug === '') {\n        if (!this.tenant.slug) {\n          this.slugErrors = ['A URL slug for your team is required.']\n        } else {\n          this.tenantChanges.slug = this.tenant.slug\n        }\n        return\n      }\n\n      if (slug.length < 3) {\n        this.slugErrors = ['URL slug must contain a minimum of 3 characters.']\n        return\n      }\n\n      if (!this.slugCharRegex.test(slug)) {\n        this.slugErrors = [\n          'URL slugs can only contain lowercase letters, numbers, and dashes.'\n        ]\n        return\n      }\n\n      if (this.dashPositionRegex.test(slug)) {\n        this.slugErrors = [\n          'URL slugs cannot begin or end with a dash or contain more than 1 dash in a row.'\n        ]\n      }\n    },\n    async createTenant() {\n      let error\n      this.loading = true\n\n      const notificationId = await this.addNotification({\n        color: 'primaryLight',\n        loading: true,\n        text: 'Creating team...',\n        dismissable: false\n      })\n\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Tenant/create-enterprise-tenant.gql'),\n          variables: {\n            input: {\n              name: this.teamName,\n              slug: this.teamSlug\n            }\n          }\n        })\n\n        await this.getUser()\n        await this.$globalApolloQueries['tenants']?.refetch()\n\n        // This makes sure we don't route to the welcome screen\n        // after switching to the tenant\n        localStorage.setItem('haltTenantRouting', true)\n        await this.setCurrentTenant(this.teamSlug)\n\n        await this.updateTenantSettings({\n          teamNamed: true\n        })\n\n        this.$emit('team-created')\n\n        this.resetData()\n\n        clearCache()\n\n        await this.updateNotification({\n          id: notificationId,\n          notification: {\n            color: 'primary',\n            text: 'Team created!',\n            loading: false,\n            subtext: this.teamName,\n            dismissable: true,\n            timeout: 10000\n          }\n        })\n      } catch (e) {\n        error = e\n\n        if (e?.toString().includes('Uniqueness violation')) {\n          this.slugErrors = ['Sorry, that URL slug is already in use.']\n        } else {\n          LogRocket.captureException(e)\n        }\n        // eslint-disable-next-line no-console\n        console.error(e)\n      } finally {\n        this.loading = false\n        await this.updateNotification({\n          id: notificationId,\n          notification: {\n            color: error ? 'error' : 'primary',\n            text: error\n              ? 'There was a problem creating your team. If the issue persists, contact help@prefect.io.'\n              : 'Team created!',\n            loading: false,\n            subtext: error ? error : this.teamName,\n            dismissable: true,\n            timeout: 10000\n          }\n        })\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"utilGrayDark--text mx-4 \" flat outlined>\n    <v-card-text>\n      <v-container fluid>\n        <v-row class=\"my-2 pb-8\" no-gutters>\n          <v-col cols=\"12\">\n            <div class=\"py-0\" :class=\"{ 'pr-24': $vuetify.breakpoint.mdAndUp }\">\n              <div class=\"text-h4 font-weight-light\">\n                Create your team\n              </div>\n            </div>\n          </v-col>\n        </v-row>\n\n        <v-row class=\"my-2 pb-8\" no-gutters>\n          <v-col cols=\"12\" md=\"3\">\n            <div class=\"py-0\" :class=\"{ 'pr-24': $vuetify.breakpoint.mdAndUp }\">\n              <div class=\"text-h5\">\n                Name\n              </div>\n            </div>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"9\">\n            <div class=\" mt-4 mt-md-0 d-flex align-center\">\n              <v-btn\n                color=\"primary\"\n                fab\n                depressed\n                x-small\n                title=\"Randomize team name\"\n                @click=\"teamName = generateRandomName()\"\n              >\n                <v-icon>fad fa-random</v-icon>\n              </v-btn>\n\n              <v-text-field\n                v-model=\"teamName\"\n                placeholder=\"Team name\"\n                class=\"ml-2 text-h5\"\n                hide-details\n                outlined\n                dense\n                :disabled=\"loading\"\n              />\n            </div>\n          </v-col>\n        </v-row>\n\n        <v-row class=\"my-2 pb-8\" no-gutters>\n          <v-col cols=\"12\" md=\"3\">\n            <div class=\"py-0\" :class=\"{ 'pr-24': $vuetify.breakpoint.mdAndUp }\">\n              <div class=\"text-h5\">\n                Slug\n              </div>\n            </div>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"9\">\n            <div class=\" mt-4 mt-md-0 d-flex align-center\">\n              <v-text-field\n                v-model=\"teamSlug\"\n                placeholder=\"URL slug\"\n                class=\"ml-2 text-h5\"\n                outlined\n                :error-messages=\"slugErrors\"\n                dense\n                :disabled=\"loading\"\n                @change=\"checkSlug\"\n              />\n            </div>\n          </v-col>\n        </v-row>\n      </v-container>\n    </v-card-text>\n\n    <v-card-actions class=\"create-tenant-actions px-4 d-flex align-center\">\n      <v-spacer></v-spacer>\n\n      <v-btn\n        class=\"text-none text-h5 px-4\"\n        color=\"primary\"\n        depressed\n        x-large\n        :loading=\"loading\"\n        :disabled=\"teamName && teamSlug && slugErrors.length > 0\"\n        @click=\"createTenant\"\n      >\n        Create\n        <!-- <i class=\"fad fa-rocket ml-2\" /> -->\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.create-tenant-actions {\n  background-color: var(--v-appForeground-base);\n  border-top: 1px solid var(--v-utilGrayLight-base);\n  height: 86px;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Teams/Teams.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nexport default {\n  computed: {\n    ...mapGetters('license', ['permissions', 'license', 'planType']),\n    multitenancy() {\n      return this.license?.terms?.tenants > 1\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-container\n      v-if=\"!multitenancy\"\n      class=\"text-h5 text-center blue-grey--text d-flex align-center justify-center\"\n      style=\"height: 400px;\"\n      fluid\n    >\n      <div>\n        <i class=\"fad fa-lock-alt fa-3x\" />\n        <div class=\"mt-6\">\n          <span v-if=\"planType('ENTERPRISE')\">\n            Your plan doesn't include multi-tenancy;\n          </span>\n          <span v-else\n            >Multi-tenancy is only available on Enterprise plans;</span\n          >\n          <br />contact\n          <a class=\"font-weight-medium\" href=\"sales@prefect.io\"\n            >sales@prefect.io</a\n          >\n          to learn more.\n        </div>\n      </div>\n    </v-container>\n\n    <transition v-else name=\"quick-fade\" mode=\"out-in\">\n      <router-view />\n    </transition>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.teams-wrapper {\n  height: 100vh;\n  pointer-events: none;\n  position: fixed;\n  width: 100%;\n  z-index: 1000;\n\n  .snackbars-snack {\n    pointer-events: auto;\n    transition: all 0.5s;\n  }\n\n  &-enter,\n  &-leave-to,\n  &-leave-active {\n    opacity: 0;\n    transform: translateY(30px);\n  }\n\n  &-leave-active {\n    position: absolute;\n  }\n}\n\n.new-team-button {\n  border-style: dotted;\n  border-width: 2px;\n  max-width: 400px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Admin/Teams/TeamsOverview.vue",
    "content": "<script>\nimport ConfirmDialog from '@/components/ConfirmDialog'\n\nimport TeamListItem from '@/components/TeamListItem'\nimport { mapActions, mapGetters } from 'vuex'\nimport { pollsTenantsMixin } from '@/mixins/polling/pollsTenantsMixin'\nimport { clearCache } from '@/vue-apollo'\n\nexport default {\n  components: {\n    ConfirmDialog,\n    TeamListItem\n  },\n  mixins: [pollsTenantsMixin],\n  data() {\n    return {\n      confirmDeleteDialog: false,\n      loading: false,\n      loadingKey: 0,\n      teamToDelete: null\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'tenants']),\n    ...mapGetters('license', [\n      'hasPermission',\n      'permissions',\n      'license',\n      'planType'\n    ]),\n    atTeamLimit() {\n      return this.license?.terms?.tenants <= this.teams.length\n    },\n    multitenancy() {\n      return this.license?.terms?.tenants > 1\n    },\n    teams() {\n      return [\n        ...this.tenants?.filter(t => t.license_id == this.license?.id)\n      ].sort((a, b) =>\n        a.stripe_customer\n          ? -1\n          : b.stripe_customer\n          ? 1\n          : new Date(a.created) - new Date(b.created)\n      )\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['addNotification', 'updateNotification']),\n    ...mapActions('data', ['resetData']),\n    ...mapActions('tenant', ['setCurrentTenant']),\n    ...mapActions('user', ['getUser']),\n    async handleSwitchTenant(tenant) {\n      if (tenant.slug == this.tenant.slug) return\n\n      this.loading = true\n\n      this.resetData()\n\n      await this.setCurrentTenant(tenant.slug)\n\n      clearCache()\n      this.loading = false\n    },\n    handleShowDeleteDialog(tenant) {\n      this.teamToDelete = tenant\n      this.confirmDeleteDialog = true\n    },\n    async handleRemoveTenant() {\n      const tenant = this.teamToDelete\n      this.loading = true\n\n      const notificationId = await this.addNotification({\n        color: 'primaryLight',\n        loading: true,\n        text: `Deleting <span class=\"font-weight-medium\">${tenant.name}</span>...`,\n        dismissable: false\n      })\n\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Tenant/delete-enterprise-tenant.gql'),\n          variables: {\n            input: {\n              tenant_id: tenant.id,\n              confirm: true\n            }\n          }\n        })\n\n        await this.refetch()\n\n        await this.updateNotification({\n          id: notificationId,\n          notification: {\n            color: 'primary',\n            text: `<span class=\"font-weight-medium\">${tenant.name}</span> deleted.`,\n            loading: false,\n            dismissable: true,\n            timeout: 10000\n          }\n        })\n      } catch (e) {\n        await this.updateNotification({\n          id: notificationId,\n          notification: {\n            color: 'error',\n            loading: false,\n            text:\n              'There was a problem deleting your team. If the issue persists, contact help@prefect.io.',\n            subtext: e.toString(),\n            dismissable: true,\n            timeout: 10000\n          }\n        })\n      } finally {\n        this.loading = false\n        this.teamToDelete = null\n        this.confirmDeleteDialog = false\n      }\n    },\n    refetch() {\n      this.resetData()\n      clearCache()\n\n      this.getUser()\n      this.$globalApolloQueries['tenants']?.refetch()\n    },\n    randomColor() {\n      const letters = '0123456789ABCDEF'.split('')\n      let color = '#'\n      for (let i = 0; i < 6; i++) {\n        color += letters[Math.round(Math.random() * 15)]\n      }\n      return color\n    }\n  },\n  apollo: {\n    users: {\n      query: require('@/graphql/Account/license-users.gql'),\n      loadingKey: 'loadingKey',\n      skip() {\n        return !this.hasPermission('license', 'admin')\n      },\n      update(data) {\n        if (!data) return\n        return data.license_users.map(u => {\n          return { ...u, avatar_color: this.randomColor() }\n        })\n      },\n      fetchPolicy: 'no-cache'\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-container\n      v-if=\"!hasPermission('license', 'admin')\"\n      class=\"text-h5 text-center blue-grey--text d-flex align-center justify-center\"\n      style=\"height: 400px;\"\n      fluid\n    >\n      <div>\n        <i class=\"fad fa-lock-alt fa-3x\" />\n        <div class=\"mt-6\">\n          <span v-if=\"planType('ENTERPRISE')\">\n            You don't have permission to view license teams; contact your\n            license administrator to get access.\n          </span>\n          <span v-else>\n            Multi-tenancy is only available on Enterprise plans.\n          </span>\n        </div>\n      </div>\n    </v-container>\n\n    <v-container v-else fluid>\n      <div class=\"mx-4 mb-4 d-flex align-center justify-end\">\n        <div class=\"mr-auto text-h5 font-weight-light\" @click=\"refetch\">\n          {{ teams.length }}/{{ license.terms.tenants }} team slots used\n        </div>\n\n        <v-btn\n          :to=\"{ path: '/admin/teams/new' }\"\n          color=\"primary\"\n          depressed\n          :disabled=\"atTeamLimit\"\n        >\n          <v-icon class=\"mr-2\" small>add</v-icon>New\n        </v-btn>\n      </div>\n\n      <transition-group name=\"teams-wrapper\" mode=\"out-in\">\n        <TeamListItem\n          v-for=\"team in teams\"\n          :key=\"team.id\"\n          :team=\"team\"\n          :loading=\"loading\"\n          :users=\"\n            users\n              ? users.filter(\n                  u => u.memberships.findIndex(m => m.tenant_id == team.id) > -1\n                )\n              : []\n          \"\n          class=\"mb-4\"\n          @click=\"handleSwitchTenant(team)\"\n          @refetch=\"refetch\"\n          @remove=\"handleShowDeleteDialog(team)\"\n        />\n      </transition-group>\n    </v-container>\n\n    <ConfirmDialog\n      v-model=\"confirmDeleteDialog\"\n      type=\"error\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      confirm-text=\"I understand\"\n      :loading=\"loading\"\n      @confirm=\"handleRemoveTenant\"\n    >\n      <template slot=\"title\">\n        <div class=\"text-h5 font-weight-light\">\n          Are you sure?\n        </div>\n      </template>\n\n      <div class=\"text-subtitle-1\">\n        This will delete your team and all associated flows, tasks, logs, and\n        runs.\n      </div>\n    </ConfirmDialog>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.teams-wrapper {\n  height: 100vh;\n  pointer-events: none;\n  position: fixed;\n  width: 100%;\n  z-index: 1000;\n\n  &-enter,\n  &-leave-to,\n  &-leave-active {\n    opacity: 0;\n    transform: translateY(30px);\n  }\n\n  &-leave-active {\n    position: absolute;\n  }\n}\n\n.new-team-button {\n  border-style: dotted;\n  border-width: 2px;\n  max-width: 400px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Agents/AgentFlowRunHistory.vue",
    "content": "<script>\nimport BarChart from '@/components/Visualizations/BarChart.vue'\nimport { flowRunHistoryMixin } from '@/mixins/flowRunHistoryMixin'\nimport TimelineTooltip from '@/components/TimelineTooltip'\n\nexport default {\n  components: {\n    BarChart,\n    TimelineTooltip\n  },\n  mixins: [flowRunHistoryMixin],\n  props: {\n    agent: {\n      type: Object,\n      required: true\n    },\n    visible: { type: Boolean, default: () => true }\n  },\n  data() {\n    return {\n      loadingKey: 0\n    }\n  },\n  computed: {\n    loading() {\n      return this.loadingKey > 0\n    },\n    pollInterval() {\n      return 5000\n    }\n  },\n  mounted() {\n    if (this.pollInterval > 0) {\n      this.$apollo.queries.flowRuns.startPolling(this.pollInterval)\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRuns.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRuns: {\n      query: require('@/graphql/Agent/timeline-flow-runs.gql'),\n      variables() {\n        let variables = { heartbeat: null, agent_id: this.agent.id }\n\n        return variables\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.flow_run || []\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"pa-0 pt-7 mb-4 appBackground\"\n    style=\"max-height: 114px;\"\n    tile\n    flat\n  >\n    <div class=\"text-caption text-left grey--text timeline-title\">\n      <v-icon x-small>pi-flow-run</v-icon><span class=\"ml-1\">Run History</span>\n    </div>\n\n    <div\n      v-if=\"!loading && reversedRuns.length === 0\"\n      class=\"text-caption text-center grey--text timeline-no-runs\"\n    >\n      No run history\n    </div>\n    <BarChart\n      :loading=\"loading\"\n      :items=\"reversedRuns\"\n      :breaklines=\"breaklines\"\n      :height=\"100\"\n      :min-bands=\"100\"\n      show-controls\n      :visible=\"visible\"\n      y-field=\"duration\"\n      @bar-click=\"_barClick\"\n      @bar-mouseout=\"_barMouseout\"\n      @bar-mouseover=\"_barMouseover\"\n    >\n      <TimelineTooltip\n        v-if=\"tooltip\"\n        slot=\"tooltip\"\n        :tooltip=\"tooltip\"\n        :loading=\"tooltipLoading\"\n      />\n    </BarChart>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.timeline-title {\n  left: 0;\n  position: absolute;\n  top: 8px;\n}\n\n.timeline-no-runs {\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n</style>\n"
  },
  {
    "path": "src/pages/Agents/AgentFlowRunTable-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport DurationSpan from '@/components/DurationSpan'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { STATE_NAMES } from '@/utils/states'\nexport default {\n  components: { CardTitle, DurationSpan },\n  mixins: [formatTime],\n  props: {\n    agent: {\n      required: false,\n      type: Object,\n      default: () => {}\n    },\n    agentRuns: {\n      required: false,\n      type: Boolean,\n      default: true\n    }\n  },\n  data() {\n    return {\n      flowRuns: null,\n      flowRunsCount: null,\n      headers: [\n        {\n          text: 'Name',\n          value: 'name',\n          width: '20%'\n        },\n        {\n          text: 'Flow',\n          value: 'flow.name',\n          width: '20%'\n        },\n        {\n          text: 'Scheduled Start',\n          value: 'scheduled_start_time',\n          align: 'start',\n          width: '18%'\n        },\n        {\n          text: 'Start Time',\n          value: 'start_time',\n          align: 'start',\n          width: '18%'\n        },\n        { text: 'End Time', value: 'end_time', align: 'start', width: '18%' },\n        {\n          text: 'Duration',\n          value: 'duration',\n          align: 'end',\n          width: '15%',\n          sortable: false\n        },\n        { text: 'State', value: 'state', align: 'end', width: '10%' }\n      ],\n      itemsPerPage: 15,\n      page: 1,\n      searchTerm: null,\n      sortBy: 'scheduled_start_time',\n      sortDesc: true,\n      state: [],\n      states: STATE_NAMES.slice(1).sort()\n    }\n  },\n  computed: {\n    offset() {\n      return this.itemsPerPage * (this.page - 1)\n    },\n    searchFormatted() {\n      if (!this.searchTerm) return null\n      return `%${this.searchTerm}%`\n    },\n    pollInterval() {\n      return 5000\n    }\n  },\n  mounted() {\n    if (this.agentRuns) {\n      this.$apollo.queries.agentFlowRuns.startPolling(this.pollInterval)\n      this.$apollo.queries.agentFlowRunsCount.startPolling(this.pollInterval)\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.agentFlowRuns.skip = !entry.isIntersecting\n      this.$apollo.queries.agentFlowRunsCount.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    agentFlowRuns: {\n      query: require('@/graphql/Agent/table-flow-runs.gql'),\n      variables() {\n        const orderBy = {}\n        orderBy[`${this.sortBy}`] = this.sortDesc ? 'desc' : 'asc'\n\n        let variables = {\n          limit: this.itemsPerPage,\n          name: this.searchFormatted,\n          offset: this.offset,\n          state: this.state.length === 0 ? null : this.state,\n          orderBy\n        }\n\n        variables.agent_id = this.agent.id\n\n        return variables\n      },\n      skip() {\n        return !this.agentRuns\n      },\n      update: data => data.flow_run\n    },\n    agentFlowRunsCount: {\n      query: require('@/graphql/Agent/table-flow-runs-count.gql'),\n      variables() {\n        let variables = {\n          name: this.searchFormatted,\n          state: this.state.length === 0 ? null : this.state\n        }\n\n        variables.agent_id = this.agent.id\n\n        return variables\n      },\n      skip() {\n        return !this.agentRuns\n      },\n      update: data =>\n        data && data.flow_run_aggregate\n          ? data.flow_run_aggregate.aggregate.count\n          : null\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" tile>\n    <CardTitle icon=\"pi-task-run\">\n      <div :slot=\"$vuetify.breakpoint.lgAndUp && 'title'\">\n        Flow Runs\n      </div>\n\n      <div\n        :slot=\"$vuetify.breakpoint.mdAndDown ? 'title' : 'state-filter'\"\n        :class=\"{ 'd-flex': $vuetify.breakpoint.mdAndUp }\"\n      >\n        <v-select\n          data-public\n          v-model=\"state\"\n          outlined\n          class=\"state-filter\"\n          :style=\"[\n            $vuetify.breakpoint.mdAndUp ? { width: '280px' } : { width: '100%' }\n          ]\"\n          dense\n          flat\n          solo\n          hide-details\n          :menu-props=\"{ bottom: true, offsetY: true }\"\n          clearable\n          :items=\"states\"\n          label=\"Filter by state\"\n          multiple\n        >\n          <template #selection=\"{ item, index }\">\n            <v-chip\n              v-if=\"index === 0 || index === 1\"\n              :color=\"item\"\n              label\n              small\n              text-color=\"white\"\n            >\n              {{ item }}\n            </v-chip>\n            <span v-if=\"index === 2\" class=\"grey--text text-caption\">\n              (+{{ state.length - 2 }})\n            </span>\n          </template>\n        </v-select>\n        <v-text-field\n          slot=\"action\"\n          v-model=\"searchTerm\"\n          class=\"search\"\n          dense\n          solo\n          prepend-inner-icon=\"search\"\n          hide-details\n          placeholder=\"Search for a Flow Run\"\n          flat\n          style=\"min-width: 200px;\"\n        >\n        </v-text-field>\n      </div>\n    </CardTitle>\n\n    <v-card-text>\n      <v-data-table\n        :footer-props=\"{\n          showFirstLastPage: true,\n          itemsPerPageOptions: [10, 15, 25, 50],\n          firstIcon: 'first_page',\n          lastIcon: 'last_page',\n          prevIcon: 'keyboard_arrow_left',\n          nextIcon: 'keyboard_arrow_right'\n        }\"\n        class=\"truncate-table\"\n        :headers=\"headers\"\n        :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n        :items=\"agentFlowRuns || []\"\n        :items-per-page.sync=\"itemsPerPage\"\n        :loading=\"$apollo.queries.agentFlowRuns.loading\"\n        must-sort\n        :page.sync=\"page\"\n        :server-items-length=\"agentFlowRunsCount\"\n        :sort-by.sync=\"sortBy\"\n        :sort-desc.sync=\"sortDesc\"\n        :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n        calculate-widths\n      >\n        <template #item.name=\"{ item }\">\n          <truncate :content=\"item.name\">\n            <router-link\n              class=\"link text-truncate\"\n              :to=\"{ name: 'flow-run', params: { id: item.id } }\"\n            >\n              {{ item.name }}\n            </router-link>\n          </truncate>\n        </template>\n\n        <template #item.flow.name=\"{ item }\">\n          <truncate :content=\"item.flow.name\">\n            <router-link\n              class=\"link text-truncate\"\n              :to=\"{ name: 'flow', params: { id: item.flow.id } }\"\n            >\n              {{ item.flow.name }}\n            </router-link>\n          </truncate>\n        </template>\n\n        <template #item.scheduled_start_time=\"{ item }\">\n          <truncate :content=\"formatTime(item.scheduled_start_time)\">\n            {{ formDate(item.scheduled_start_time) }}\n          </truncate>\n        </template>\n\n        <template #item.start_time=\"{ item }\">\n          <truncate :content=\"formatTime(item.start_time)\">\n            {{ formDate(item.start_time) }}\n          </truncate>\n        </template>\n\n        <template #item.end_time=\"{ item }\">\n          <truncate :content=\"formatTime(item.end_time)\">\n            {{ formDate(item.end_time) }}\n          </truncate>\n        </template>\n\n        <template #item.duration=\"{ item }\">\n          <DurationSpan\n            v-if=\"item.start_time\"\n            :start-time=\"item.start_time\"\n            :end-time=\"item.end_time\"\n          />\n        </template>\n\n        <template #item.state=\"{ item }\">\n          <truncate :content=\"item.state\">\n            <v-icon class=\"mr-1 pointer\" small :color=\"item.state\">\n              brightness_1\n            </v-icon>\n          </truncate>\n        </template>\n      </v-data-table>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\">\n.search {\n  border-radius: 0 !important;\n  font-size: 0.85rem;\n\n  .v-icon {\n    font-size: 20px !important;\n  }\n}\n\n.state-filter {\n  .v-label {\n    font-size: 0.85rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Agents/AgentPage.vue",
    "content": "<script>\nimport SubPageNav from '@/layouts/SubPageNav'\nimport BreadCrumbs from '@/components/BreadCrumbs'\nimport TileLayout from '@/layouts/AgentLayout'\nimport AgentTile from '@/pages/Agents/AgentTile'\nimport AgentFlowRunHistory from '@/pages/Agents/AgentFlowRunHistory'\nimport AgentRunsInProgress from '@/pages/Dashboard/InProgress-Tile.vue'\nimport SubmittableRuns from '@/pages/Agents/SubmittableRuns'\nimport FlowRunTableTile from '@/pages/Agents/AgentFlowRunTable-Tile'\nimport { pollsAgentsMixin } from '@/mixins/polling/pollsAgentsMixin'\n\nimport { mapGetters, mapMutations, mapActions } from 'vuex'\n\nexport default {\n  components: {\n    SubPageNav,\n    BreadCrumbs,\n    TileLayout,\n    AgentTile,\n    AgentFlowRunHistory,\n    AgentRunsInProgress,\n    SubmittableRuns,\n    FlowRunTableTile\n  },\n  mixins: [pollsAgentsMixin],\n  data() {\n    return {\n      tab: 'overview',\n      tabs: [{ name: 'overview', target: 'overview' }],\n      loading: false,\n      showConfirmDialog: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('agent', ['sorting', 'sortedAgent']),\n    agentId() {\n      return this.$route.params.id\n    },\n    agentDetails() {\n      const agent = this.sortedAgent(this.agentId)\n      return agent\n    },\n    agentName() {\n      return this.agentDetails?.name != 'agent'\n        ? this.agentDetails?.name\n        : this.agentDetails?.type\n    }\n  },\n  watch: {\n    tenant() {\n      this.loading = true\n      setTimeout(() => {\n        this.$router.push({ name: 'agents' })\n        this.loading = false\n      }, 5000)\n    }\n  },\n  mounted() {\n    if (!this.agentDetails) {\n      this.$router.push({ name: 'agents' })\n    }\n  },\n  methods: {\n    ...mapMutations('agent', ['setAgents']),\n    ...mapActions('alert', ['setAlert']),\n    async deleteAgent() {\n      try {\n        this.showConfirmDialog = false\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Agent/delete-agent.gql'),\n          variables: {\n            agentId: this.agentDetails.id\n          }\n        })\n        this.setRefetch(true)\n        if (data.delete_agent?.success) this.$router.push({ name: 'agents' })\n      } catch (error) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `${error}`,\n          alertType: 'error'\n        })\n      }\n    }\n  }\n}\n</script>\n<template>\n  <v-sheet v-if=\"sorting || loading\" color=\"appBackground\">\n    <v-progress-linear indeterminate color=\"primary\"></v-progress-linear>\n  </v-sheet>\n  <v-sheet v-else color=\"appBackground\">\n    <SubPageNav icon=\"pi-agent\" page-type=\"Agent\" m>\n      <span slot=\"page-title\">\n        <span>\n          {{ agentName }}\n        </span>\n      </span>\n      <span\n        slot=\"breadcrumbs\"\n        :style=\"\n          $vuetify.breakpoint.smAndDown && {\n            display: 'inline',\n            'font-size': '0.875rem'\n          }\n        \"\n      >\n        <BreadCrumbs\n          :crumbs=\"[\n            {\n              route: {\n                name: 'agents'\n              },\n              text: 'Agents'\n            }\n          ]\"\n        />\n      </span>\n      <span\n        slot=\"page-actions\"\n        :class=\"{ 'mx-auto': $vuetify.breakpoint.xsOnly }\"\n      >\n        <v-btn\n          v-if=\"agentDetails.status === 'unhealthy'\"\n          text\n          tile\n          small\n          color=\"error\"\n          class=\"vertical-button py-1\"\n          :title=\"'Remove agent'\"\n          @click=\"showConfirmDialog = true\"\n        >\n          <v-icon>\n            delete\n          </v-icon>\n          <div class=\"mb-1\">Remove</div>\n        </v-btn>\n\n        <v-dialog v-model=\"showConfirmDialog\" max-width=\"480\">\n          <v-card>\n            <v-card-title class=\"word-break-normal\">\n              Are you sure you want to stop displaying this agent?\n            </v-card-title>\n\n            <v-card-text class=\"my-4 text-body-2\">\n              <strong>\n                This action will not stop the agent process if it is still\n                running in your infrastructure.</strong\n              >\n              It will only stop displaying the agent in Cloud.\n            </v-card-text>\n\n            <v-card-actions>\n              <v-spacer></v-spacer>\n\n              <v-btn text @click=\"showConfirmDialog = false\">\n                Cancel\n              </v-btn>\n\n              <v-btn color=\"error lighten-1\" text @click=\"deleteAgent\">\n                Confirm\n              </v-btn>\n            </v-card-actions>\n          </v-card>\n        </v-dialog>\n      </span>\n    </SubPageNav>\n\n    <v-tabs-items\n      v-model=\"tab\"\n      class=\"px-6 mx-auto tabs-border-bottom tab-full-height\"\n      :style=\"{\n        'padding-top': $vuetify.breakpoint.smOnly ? '30px' : '80px'\n      }\"\n    >\n      <v-tab-item\n        class=\"pa-0\"\n        value=\"overview\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayout>\n          <AgentFlowRunHistory slot=\"row-0\" :agent=\"agentDetails\" />\n          <AgentTile\n            slot=\"row-1-col-1-tile-1\"\n            show-all\n            :raw-agent=\"agentDetails\"\n          />\n          <SubmittableRuns\n            slot=\"row-1-col-2-tile-1\"\n            :raw-agent=\"agentDetails\"\n          />\n          <AgentRunsInProgress\n            slot=\"row-1-col-3-tile-1\"\n            :agent-id=\"agentDetails.id\"\n            agent-runs\n          />\n          <FlowRunTableTile\n            slot=\"row-2-col-1-row-2-tile-a\"\n            agent-runs\n            :agent=\"agentDetails\"\n          />\n        </TileLayout>\n      </v-tab-item>\n    </v-tabs-items>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "src/pages/Agents/AgentTile.vue",
    "content": "<script>\nimport { mapGetters, mapActions } from 'vuex'\n\nimport Label from '@/components/Label'\nimport moment from '@/utils/moment'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport LastTenRuns from '@/components/LastTenRuns'\nimport CardTitle from '@/components/Card-Title'\nimport DurationSpan from '@/components/DurationSpan'\n\nconst AGENT_TYPES = [\n  { type: 'DockerAgent', icon: 'fab fa-docker pa-1', name: 'Docker' },\n  { type: 'ECSAgent', icon: 'fab fa-aws pa-1', name: 'ECS' },\n  { type: 'FargateAgent', icon: 'fab fa-aws pa-1', name: 'Fargate' },\n  { type: 'KubernetesAgent', icon: 'pi-kubernetes', name: 'Kubernetes' },\n  { type: 'LocalAgent', icon: 'fas fa-home', name: 'Local' },\n  { type: 'NomadAgent', icon: '$nomad', name: 'Nomad' }\n]\n\nexport default {\n  components: {\n    LastTenRuns,\n    Label,\n    CardTitle,\n    DurationSpan\n  },\n  mixins: [formatTime],\n  props: {\n    rawAgent: {\n      type: Object,\n      required: true\n    },\n    labelRenderLimit: {\n      type: Number,\n      required: false,\n      default: 3\n    },\n    selectedLabels: {\n      type: Array,\n      required: false,\n      default: () => []\n    },\n    showAll: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    const tabs = {\n      overview: 0,\n      config: 1\n    }\n\n    return {\n      copiedText: {},\n      labelMenuOpen: false,\n      isDeleting: false,\n      showConfirmDialog: false,\n      loading: 0,\n      showIcon: true,\n      tab: tabs.overview,\n      tabs\n    }\n  },\n  computed: {\n    ...mapGetters('agent', ['staleThreshold', 'unhealthyThreshold']),\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant']),\n    agent() {\n      const agent = { ...this.rawAgent }\n      const getTimeOverdue = time => new Date() - new Date(time)\n      agent.submittableRuns = []\n      agent.lateRuns = []\n\n      if (!agent.labels?.length) {\n        const noLabels = this.flowRuns?.filter(flowRun => {\n          return !flowRun?.labels?.length\n        })\n        agent.submittableRuns = noLabels?.filter(\n          flowRun => getTimeOverdue(flowRun.scheduled_start_time) <= 20000\n        )\n        agent.lateRuns = noLabels?.filter(\n          flowRun => getTimeOverdue(flowRun.scheduled_start_time) > 20000\n        )\n      } else {\n        const match = this.flowRuns?.filter(\n          flowRun =>\n            flowRun?.labels?.length &&\n            flowRun.labels.every(label => agent?.labels?.includes(label))\n        )\n        agent.submittableRuns = match?.filter(\n          flowRun => getTimeOverdue(flowRun.scheduled_start_time) <= 20000\n        )\n        agent.lateRuns = match?.filter(\n          flowRun => getTimeOverdue(flowRun.scheduled_start_time) > 20000\n        )\n      }\n      return agent\n    },\n    dayAgo() {\n      const today = this.formatCalendarDate(new Date())\n      const day = this.subtractDay(today, 2)\n      return day\n    },\n    labelHeight() {\n      return this.showAll ? '60px' : '40px'\n    },\n    hasLateRuns() {\n      return !!this.lateRuns?.length\n    },\n    name() {\n      return this.agent?.name && this.agent.name !== 'agent'\n        ? this.agent.name\n        : AGENT_TYPES.find(a => a.type == this.agent?.type)?.name || 'Agent'\n    },\n    secondsSinceLastQuery() {\n      return this.agent.secondsSinceLastQuery\n    },\n    status() {\n      return this.agent?.lateRuns?.length ? 'late' : this.agent.status\n    },\n    statusColor() {\n      const color =\n        {\n          unhealthy: 'utilGrayLight',\n          late: 'deepRed',\n          healthy: 'green',\n          stale: 'warning'\n        }[this.status] || 'secondaryGray'\n      return color\n    },\n    iconClass() {\n      const color =\n        {\n          unhealthy: 'unhealthy',\n          late: 'late',\n          healthy: 'healthy',\n          stale: 'stale'\n        }[this.status] || 'plain'\n      return color\n    },\n    queryColor() {\n      if (this.agent.secondsSinceLastQuery < 60 * this.staleThreshold)\n        return 'success'\n      if (this.agent.secondsSinceLastQuery < 60 * this.unhealthyThreshold)\n        return 'warning'\n      return 'error'\n    },\n    timer() {\n      if (!this.agent?.last_queried) return null\n      return moment(this.agent.last_queried).fromNow()\n    },\n    type() {\n      return this.agent?.type ? this.agent.type : 'Agent type unknown'\n    },\n    submittableRuns() {\n      return this.agent.submittableRuns\n    },\n    lateRuns() {\n      return this.agent.lateRuns\n    },\n    failedRuns() {\n      const badRuns = this.recentRuns?.filter(run =>\n        ['Failed', 'TriggerFailed'].includes(run.state)\n      )\n      return !!badRuns?.length\n    },\n    agentIcon() {\n      return (\n        AGENT_TYPES.find(a => a.type == this.agent?.type)?.icon ||\n        'fad fa-globe'\n      )\n    },\n    agentHook() {\n      const hook = this.agentHooks\n        ?.filter(\n          hook =>\n            hook.event_tags?.agent_config_id?.filter(id => {\n              return id === this.agent?.agent_config_id\n            }).length > 0\n        )\n        .map(hook => hook.action)\n      return hook\n    },\n    getDateTime() {\n      if (this.agent?.created) {\n        const time = this.formatDateTime(this.agent.created)\n        const formattedTime = time.charAt(0).toLowerCase() + time.slice(1)\n        return `Created ${formattedTime}`\n      }\n      return 'No creation time recorded'\n    }\n  },\n  mounted() {\n    this.$globalApolloQueries['agents'].refetch()\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    anyLabelsSelected(labels) {\n      return labels.reduce((result, label) => this.labelSelected(label), false)\n    },\n    copyTextToClipboard(text) {\n      if (!text) return\n\n      this.copiedText = {}\n      this.copiedText[text] = true\n      navigator.clipboard.writeText(text)\n\n      setTimeout(() => {\n        this.copiedText = {}\n        this.copiedText[text] = false\n      }, 1000)\n    },\n    async deleteAgent() {\n      try {\n        this.showConfirmDialog = false\n        this.isDeleting = true\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Agent/delete-agent.gql'),\n          variables: {\n            agentId: this.agent.id\n          }\n        })\n        this.$globalApolloQueries['agents'].refetch()\n        setTimeout(() => {\n          this.isDeleting = false\n        }, 10000)\n      } catch (error) {\n        this.isDeleting = false\n        this.setAlert({\n          alertShow: true,\n          alertMessage:\n            'We had a problem removing your Agent. Please try again.',\n          alertType: 'error'\n        })\n      }\n    },\n    labelSelected(label) {\n      return this.selectedLabels.includes(label)\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRuns.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    recentRuns: {\n      query: require('@/graphql/Agent/recent-runs.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {\n          agentId: this.rawAgent?.id,\n          day: this.dayAgo\n        }\n      },\n      update: data => {\n        return data.flow_run\n      }\n    },\n    agentHooks: {\n      query: require('@/graphql/Agent/agent-hooks.gql'),\n      loadingKey: 'loading',\n      skip() {\n        return !this.isCloud\n      },\n      update: data => {\n        return data.hook\n      }\n    },\n    flowRuns: {\n      query: require('@/graphql/Agent/FlowRuns.gql'),\n      pollInterval: 1000,\n      fetchPolicy: 'no-cache',\n      update(data) {\n        return data.flow_run\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    :disabled=\"agent.isDeleting || isDeleting\"\n    class=\"agent-card py-2\"\n    :tile=\"showAll\"\n    :height=\"showAll ? '380px' : '350px'\"\n  >\n    <v-system-bar :color=\"statusColor\" :height=\"5\" absolute> </v-system-bar>\n    <CardTitle :title=\"name\">\n      <div slot=\"icon\" :class=\"iconClass\" class=\"ml-2\" icon>\n        <i class=\"fa-2x pi-2x nav-bar-duotone-icon\" :class=\"agentIcon\" />\n      </div>\n    </CardTitle>\n\n    <v-dialog v-model=\"showConfirmDialog\" max-width=\"480\">\n      <v-card>\n        <v-card-title class=\"word-break-normal\">\n          Are you sure you want to stop displaying this agent?\n        </v-card-title>\n\n        <v-card-text class=\"my-4 text-body-2\">\n          <strong>\n            This action will not stop the agent process if it is still running\n            in your infrastructure.</strong\n          >\n          It will only stop displaying the agent in Cloud.\n        </v-card-text>\n\n        <v-card-actions>\n          <v-spacer></v-spacer>\n\n          <v-btn text @click=\"showConfirmDialog = false\">\n            Cancel\n          </v-btn>\n\n          <v-btn color=\"error lighten-1\" text @click=\"deleteAgent\">\n            Confirm\n          </v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-dialog>\n\n    <v-tabs\n      v-if=\"showAll && isCloud\"\n      v-model=\"tab\"\n      tabs-border-bottom\n      color=\"primary\"\n      class=\"flex-grow-0\"\n    >\n      <v-tab :key=\"tabs.overview\" data-cy=\"details-tile-overview\">\n        Overview\n      </v-tab>\n      <v-tab :key=\"tabs.config\" data-cy=\"details-tile-config\">\n        Config\n      </v-tab>\n    </v-tabs>\n\n    <v-card-text\n      v-if=\"tab == tabs.overview || !showAll\"\n      class=\"py-2 card-content\"\n      :style=\"showAll ? '' : { height: '250px' }\"\n    >\n      <div v-if=\"!showAll\" class=\"my-2 text-subtitle-1 font-weight-light \">\n        <v-icon small class=\"mr-1\" :color=\"hasLateRuns ? 'deepRed' : 'success'\">\n          adjust\n        </v-icon>\n        <span v-if=\"hasLateRuns\">\n          {{ hasLateRuns ? lateRuns.length : 0 }}\n        </span>\n        <span v-else>\n          {{ submittableRuns ? submittableRuns.length : 0 }}\n        </span>\n        {{ hasLateRuns ? 'Late submittable' : 'submittable' }}\n        runs\n      </div>\n\n      <div v-if=\"!showAll\" class=\"my-2 text-subtitle-1 font-weight-light \">\n        <v-icon small class=\"mr-1\" :color=\"queryColor\">adjust</v-icon>\n        <v-tooltip v-if=\"agent.last_queried\" top>\n          <template #activator=\"{ on }\">\n            <span v-on=\"on\">\n              Last queried\n              <span v-if=\"secondsSinceLastQuery < 60\">\n                <DurationSpan :start-time=\"agent.last_queried\" /> ago\n              </span>\n              <span v-else>{{ timer }}</span>\n            </span>\n          </template>\n          <span>{{ formatDateTime(agent.last_queried) }}</span>\n        </v-tooltip>\n        <span v-else> No recent queries</span>\n      </div>\n      <div v-else class=\"my-2 text-subtitle-1\">\n        <v-row no-gutters>\n          <v-col cols=\"4\">\n            Last queried\n          </v-col>\n          <v-col cols=\"8\" class=\"text-right font-weight-bold\">\n            <v-tooltip v-if=\"agent.last_queried\" top>\n              <template #activator=\"{ on }\">\n                <span v-on=\"on\">\n                  <span v-if=\"secondsSinceLastQuery < 60\">\n                    <DurationSpan :start-time=\"agent.last_queried\" /> ago\n                  </span>\n                  <span v-else>{{ timer }}</span>\n                </span>\n              </template>\n              <span>{{ formatDateTime(agent.last_queried) }}</span>\n            </v-tooltip>\n            <span v-else> No recent queries</span>\n          </v-col>\n        </v-row>\n      </div>\n\n      <div v-if=\"showAll\" class=\"my-2 text-subtitle-1\">\n        <v-row no-gutters>\n          <v-col cols=\"4\">\n            Core Version\n          </v-col>\n          <v-col cols=\"8\" class=\"text-right font-weight-bold\">\n            {{ agent.core_version || 'Unknown' }}\n          </v-col>\n        </v-row>\n      </div>\n\n      <div v-if=\"!showAll\" :style=\"{ height: '70px' }\">\n        <div class=\"mt-2 text-subtitle-1\">\n          Recent runs\n        </div>\n        <div v-if=\"loading < 1 && (!recentRuns || !recentRuns.length)\">\n          <div class=\"text-xs-subtitle-1 grey--text timeline-no-runs\"\n            >No run history\n          </div>\n        </div>\n        <LastTenRuns\n          :runs=\"recentRuns\"\n          :agent-id=\"agent.id\"\n          :disable-view=\"hasLateRuns\"\n        />\n      </div>\n      <div v-if=\"showAll\" class=\"my-2 text-subtitle-1\">\n        <v-row no-gutters>\n          <v-col cols=\"4\">\n            Created At\n          </v-col>\n          <v-col cols=\"8\" class=\"text-right font-weight-bold\">\n            {{ formatTime(agent.created) }}\n          </v-col>\n        </v-row>\n      </div>\n      <div v-if=\"showAll && isCloud\" class=\"my-2 text-subtitle-1\">\n        <v-row no-gutters>\n          <v-col :cols=\"agent.token_name ? 4 : 2\">\n            Token {{ agent.token_name ? 'Name' : 'ID' }}\n          </v-col>\n          <v-col\n            :cols=\"agent.token_name ? 8 : 10\"\n            class=\"text-right font-weight-bold\"\n          >\n            <div class=\"text-truncate show-icon\">\n              <span class=\"cursor\" @click=\"copyTextToClipboard(agent.token_id)\">\n                <v-icon x-small class=\"mb-2px hidden-icon mr-1\">\n                  {{ copiedText[agent.token_id] ? 'check' : 'file_copy' }}\n                </v-icon>\n                <span>{{ agent.token_name || agent.token_id }}</span>\n              </span>\n            </div>\n          </v-col>\n        </v-row>\n      </div>\n\n      <div v-if=\"showAll\" class=\"my-2 text-subtitle-1\">\n        <v-row no-gutters>\n          <v-col cols=\"3\">\n            Agent ID\n          </v-col>\n          <v-col cols=\"9\" class=\"text-right font-weight-bold\">\n            <div class=\"text-truncate show-icon\">\n              <span class=\"cursor\" @click=\"copyTextToClipboard(agent.id)\">\n                <v-icon x-small class=\"mb-2px hidden-icon mr-1\">\n                  {{ copiedText[agent.id] ? 'check' : 'file_copy' }}\n                </v-icon>\n                <span>{{ agent.id || 'Unknown' }}</span>\n              </span>\n            </div>\n          </v-col>\n        </v-row>\n      </div>\n      <div>\n        <div class=\"my-2 \" :class=\"showAll ? 'subtitle-1' : 'text-subtitle-1'\">\n          Labels\n        </div>\n        <v-sheet\n          v-if=\"agent.labels && agent.labels.length\"\n          :height=\"showAll ? '60px' : '40px'\"\n          :style=\"{ overflow: 'auto' }\"\n        >\n          <Label\n            v-for=\"label in agent.labels\"\n            :key=\"label\"\n            class=\"mr-1 mt-1\"\n            :outlined=\"!labelSelected(label)\"\n            size=\"x-small\"\n            @click=\"$emit('label-click', $event)\"\n          >\n            {{ label }}\n          </Label>\n          <!-- <span v-if=\"!agentModified.labels.length\">\n                None\n              </span> -->\n        </v-sheet>\n        <div\n          v-else\n          class=\"text--disabled my-2\"\n          :class=\"showAll ? 'subtitle-1' : 'text-subtitle-1'\"\n          :style=\"{ height: labelHeight }\"\n        >\n          None\n        </div>\n      </div>\n    </v-card-text>\n    <v-card-text v-else\n      ><div\n        v-if=\"!agentHook || !agentHook.length\"\n        class=\"my-2 text-subtitle-1 font-weight-light text-center\"\n      >\n        No config</div\n      >\n      <div v-else class=\"my-2 text-subtitle-1 font-weight-dark\">\n        <truncate :content=\"agent.id\">\n          Agent Config Id: {{ agent.agent_config_id || unknown }}</truncate\n        >\n        <div v-for=\"(action, index) in agentHook\" :key=\"index\">\n          <div class=\"my-2 text-subtitle-1 font-weight-light\">\n            Action Name{{\n              agentHook && agentHook.length > 1 ? ` ${index}` : ''\n            }}:\n            {{ action.name }}\n          </div>\n          <div class=\"my-2 text-subtitle-1 font-weight-light \">\n            Action Type{{\n              agentHook && agentHook.length > 1 ? ` ${index}` : ''\n            }}:\n            {{ action.action_type }}\n          </div>\n        </div>\n      </div>\n    </v-card-text>\n\n    <v-card-actions v-if=\"!showAll\" class=\"pt-0\">\n      <v-btn\n        small\n        text\n        color=\"primary\"\n        class=\"mx-1\"\n        :to=\"{\n          name: 'agent',\n          params: { tenant: tenant.slug, id: agent.id }\n        }\"\n      >\n        More\n      </v-btn>\n      <v-spacer />\n      <v-btn\n        v-show=\"agent && agent.status != 'healthy'\"\n        small\n        color=\"primary\"\n        text\n        class=\"mx-1\"\n        :loading=\"agent.isDeleting || isDeleting\"\n        @click=\"showConfirmDialog = true\"\n      >\n        Remove\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.late {\n  color: var(--v-deepRed-base);\n  --fa-primary-color: var(--v-deepRed-base);\n}\n.healthy {\n  color: var(--v-success-base);\n  --fa-primary-color: var(--v-success-base);\n}\n.stale {\n  color: var(--v-warning-base);\n  --fa-primary-color: var(--v-warning-base);\n}\n.unhealthy {\n  color: var(--v-utilGrayLight-base);\n  --fa-primary-color: var(--v-utilGrayLight-base);\n}\n\n.card-content {\n  max-height: calc(310px - var(--v-tabs-height));\n  overflow-y: auto;\n}\n\n.timeline-no-runs {\n  left: 50%;\n  position: absolute;\n  top: 52%;\n  transform: translate(-50%, -50%);\n}\n\n.hidden-icon {\n  display: none;\n}\n\n.show-icon:hover .hidden-icon {\n  display: inline;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Agents/Agents.vue",
    "content": "<script>\nimport uniq from 'lodash/uniq'\nimport { mapGetters, mapActions, mapMutations } from 'vuex'\nimport { pollsAgentsMixin } from '@/mixins/polling/pollsAgentsMixin'\nimport LogRocket from 'logrocket'\nimport SubPageNav from '@/layouts/SubPageNav'\nimport { formatTime } from '@/mixins/formatTimeMixin.js'\nimport difference from 'lodash/difference'\n\nimport AgentTile from '@/pages/Agents/AgentTile'\n\nconst STATUSES = ['healthy', 'stale', 'unhealthy', 'late']\n\nexport default {\n  components: {\n    AgentTile,\n    SubPageNav\n  },\n  mixins: [formatTime, pollsAgentsMixin],\n  data() {\n    return {\n      cleanUpDialog: false,\n      filterMenuOpen: false,\n      queryFailed: false,\n      loading: 0,\n      labelInput: [],\n      showUnlabeledAgentsOnly: false,\n      statusInput: STATUSES,\n      clearingAgents: false,\n      clearingError: false,\n      tab: 'overview'\n    }\n  },\n  computed: {\n    ...mapGetters('agent', [\n      'staleThreshold',\n      'unhealthyThreshold',\n      'agents',\n      'sortedAgents',\n      'sorting'\n    ]),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('api', ['isCloud']),\n\n    oldAgents() {\n      return !!this.filteredAgents?.find(agent => agent.status === 'unhealthy')\n    },\n    allLabels() {\n      if (!this.agents) return []\n      return this.agents.reduce(\n        (accumLabels, currentAgent) => accumLabels.concat(currentAgent.labels),\n        []\n      )\n    },\n    isLoading() {\n      return this.loading > 0 || this.sorting\n    },\n    filteredAgents() {\n      return this.sortedAgents?.filter(agent => {\n        if (this.showUnlabeledAgentsOnly) {\n          return agent.labels.length === 0\n        }\n        if (!this.statusInput.includes(agent.status)) return false\n        return difference(this.labelInput, agent.labels).length === 0\n      })\n    },\n    filtersApplied() {\n      return (\n        this.labelInput.length > 0 ||\n        this.statusInput.length < STATUSES.length ||\n        this.showUnlabeledAgentsOnly\n      )\n    }\n  },\n  watch: {\n    tenant(val) {\n      this.labelInput = []\n      this.queryFailed = false\n      this.showUnlabeledAgentsOnly = false\n      if (!val) return\n      this.loading = 1\n      setTimeout(() => {\n        this.loading = 0\n      }, 5000)\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    ...mapMutations('agent', ['setAgents', 'setSortedAgents']),\n    async clearUnhealthyAgents() {\n      try {\n        this.clearingAgents = true\n        const unhealthyAgents = this.filteredAgents.filter(\n          agent => agent.status === 'unhealthy'\n        )\n        if (unhealthyAgents?.length === 0) {\n          LogRocket.captureMessage('Clean Up button open but no agents found')\n          this.setAlert({\n            alertShow: true,\n            alertMessage: 'Error clearing agents',\n            alertType: 'error'\n          })\n        }\n        await unhealthyAgents.forEach(agent => {\n          agent.isDeleting = true\n          this.$apollo\n            .mutate({\n              mutation: require('@/graphql/Agent/delete-agent.gql'),\n              variables: {\n                agentId: agent.id\n              }\n            })\n            .then(() => {\n              this.cleanUpDialog = false\n              setTimeout(() => {\n                agent.isDeleting = false\n              }, 5000)\n            })\n            .catch(e => {\n              LogRocket.captureException(e)\n              this.clearingError = true\n              agent.isDeleting = false\n            })\n        })\n      } catch (e) {\n        LogRocket.captureException(e)\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `${e}`,\n          alertType: 'error'\n        })\n      } finally {\n        this.$globalApolloQueries['agents'].refetch()\n        setTimeout(() => {\n          this.clearingAgents = false\n        }, 500)\n        setTimeout(() => {\n          this.cleanUpDialog = false\n          if (this.clearingError) {\n            this.setAlert({\n              alertShow: true,\n              alertMessage: 'Error clearing agents',\n              alertType: 'error'\n            })\n            this.clearingError = false\n          }\n        }, 800)\n      }\n    },\n    handleLabelClick(lbl) {\n      let label = lbl.trim()\n\n      if (this.labelInput.includes(label)) {\n        this.labelInput.splice(this.labelInput.indexOf(label), 1)\n      } else {\n        this.labelInput.push(label.trim())\n        this.labelInput = uniq(this.labelInput)\n      }\n    },\n    menuArrow() {\n      const productSortSelect = this.$refs.agents\n      if (productSortSelect.isMenuActive) {\n        this.$refs.agents.isMenuActive = false\n        productSortSelect.blur()\n      } else {\n        this.$refs.agents.isMenuActive = true\n        productSortSelect.focus()\n      }\n    },\n    resetFilter() {\n      this.filterMenuOpen = false\n      this.labelInput = []\n      this.statusInput = STATUSES\n      this.showUnlabeledAgentsOnly = false\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet v-if=\"isLoading\" color=\"appBackground\">\n    <v-progress-linear indeterminate color=\"primary\"></v-progress-linear>\n  </v-sheet>\n\n  <v-sheet\n    v-else-if=\"!sortedAgents && queryFailed\"\n    class=\"text-subtitle-1 font-weight-light\"\n  >\n    <v-alert\n      border=\"left\"\n      colored-border\n      elevation=\"2\"\n      type=\"error\"\n      max-width=\"600\"\n    >\n      <p>\n        Something went wrong while trying to fetch agents.\n      </p>\n\n      <p class=\"mb-0\">\n        Please try refreshing your page. If this error persists, return to this\n        page after a few minutes.\n      </p>\n    </v-alert>\n  </v-sheet>\n\n  <v-sheet v-else color=\"appBackground\">\n    <SubPageNav icon=\"pi-agent\" page-type=\"Agents\">\n      <span\n        slot=\"page-title\"\n        :style=\"\n          loading > 0\n            ? {\n                display: 'block',\n                height: '28px',\n                overflow: 'hidden'\n              }\n            : $vuetify.breakpoint.smAndDown && {\n                display: 'inline'\n              }\n        \"\n      >\n        <span v-if=\"loading === 0\">\n          {{ tenant.name }}\n        </span>\n        <span v-else>\n          <v-skeleton-loader type=\"heading\" tile></v-skeleton-loader>\n        </span>\n      </span>\n\n      <span\n        slot=\"page-actions\"\n        :class=\"{ 'mx-auto': $vuetify.breakpoint.xsOnly }\"\n      >\n        <v-dialog v-model=\"cleanUpDialog\" width=\"25%\">\n          <template #activator=\"{ on }\">\n            <v-btn\n              v-if=\"oldAgents\"\n              class=\"vertical-button py-1 \"\n              color=\"red\"\n              text\n              tile\n              small\n              v-on=\"on\"\n            >\n              <v-icon>\n                delete_sweep\n              </v-icon>\n              <div class=\"mb-1\">Clean Up</div>\n            </v-btn>\n          </template>\n\n          <v-card flat>\n            <v-card-title class=\"text-h6 word-break-normal\">\n              Clean up unhealthy agents?\n            </v-card-title>\n\n            <v-card-text>\n              <p>\n                This will remove any agents that haven't queried\n                <span v-if=\"isCloud\" class=\"primary--text\">Prefect Cloud</span>\n                <span v-else class=\"secondaryGray--text\">Prefect Server</span>\n                in the last {{ unhealthyThreshold / 60 }} hours.\n              </p>\n              <p>\n                Note: These agents will appear again if they become healthy by\n                querying the server.\n              </p>\n            </v-card-text>\n\n            <v-card-actions>\n              <v-spacer></v-spacer>\n              <v-btn text tile @click=\"cleanUpDialog = false\">\n                Cancel\n              </v-btn>\n              <v-btn\n                :loading=\"clearingAgents\"\n                dark\n                color=\"red\"\n                depressed\n                @click=\"clearUnhealthyAgents\"\n              >\n                Confirm\n              </v-btn>\n            </v-card-actions>\n          </v-card>\n        </v-dialog>\n\n        <v-menu\n          v-if=\"sortedAgents && sortedAgents.length\"\n          v-model=\"filterMenuOpen\"\n          :close-on-content-click=\"false\"\n          bottom\n          left\n          offset-y\n          transition=\"slide-y-transition\"\n        >\n          <template #activator=\"{ on }\">\n            <v-btn class=\"vertical-button py-1\" text tile small v-on=\"on\">\n              <v-icon>\n                filter_list\n              </v-icon>\n              <div class=\"mb-1\">Filter</div>\n            </v-btn>\n          </template>\n          <v-card width=\"320\">\n            <v-card-text class=\"pb-6\">\n              <v-autocomplete\n                data-public\n                ref=\"agents\"\n                v-model=\"labelInput\"\n                :items=\"allLabels\"\n                label=\"Filter agents by label\"\n                outlined\n                multiple\n                chips\n                small-chips\n                :disabled=\"showUnlabeledAgentsOnly || allLabels.length === 0\"\n                deletable-chips\n                hide-no-data\n                :menu-props=\"{\n                  closeOnContentClick: true,\n                  maxHeight: 300,\n                  transition: 'slide-y-transition'\n                }\"\n                @click:append=\"menuArrow\"\n              ></v-autocomplete>\n              <v-switch\n                v-model=\"showUnlabeledAgentsOnly\"\n                class=\"ma-0 mt-1 label-switch-position\"\n                label=\"Only show agents with no labels\"\n                hide-details\n              ></v-switch>\n              <v-checkbox\n                v-model=\"statusInput\"\n                hide-details\n                label=\"Show healthy agents\"\n                value=\"healthy\"\n                color=\"success\"\n              ></v-checkbox>\n              <v-checkbox\n                v-model=\"statusInput\"\n                label=\"Show stale agents\"\n                :hint=\"\n                  `Stale agents have not queried for flows in the last ${\n                    staleThreshold === 1\n                      ? 'minute'\n                      : `${staleThreshold} minutes`\n                  }.`\n                \"\n                persistent-hint\n                value=\"stale\"\n                color=\"warning\"\n              ></v-checkbox>\n              <v-checkbox\n                v-model=\"statusInput\"\n                label=\"Show unhealthy agents\"\n                :hint=\"\n                  `Unhealthy agents have not queried for flows in the last ${\n                    unhealthyThreshold === 1\n                      ? 'minute'\n                      : `${unhealthyThreshold / 60} hours`\n                  }.`\n                \"\n                persistent-hint\n                value=\"unhealthy\"\n                color=\"utilGrayLight\"\n              ></v-checkbox>\n            </v-card-text>\n\n            <v-card-actions>\n              <v-spacer></v-spacer>\n              <v-btn text color=\"primary\" @click=\"resetFilter\">\n                Reset\n              </v-btn>\n              <v-btn text @click=\"filterMenuOpen = false\">\n                Close\n              </v-btn>\n            </v-card-actions>\n          </v-card>\n        </v-menu>\n      </span>\n    </SubPageNav>\n\n    <v-scroll-x-reverse-transition>\n      <v-alert\n        v-if=\"filtersApplied && !filterMenuOpen\"\n        class=\"filter-alert-position\"\n        border=\"left\"\n        colored-border\n        dense\n        elevation=\"2\"\n        type=\"info\"\n      >\n        <span>\n          Filters applied.\n        </span>\n        <v-btn\n          tile\n          text\n          small\n          color=\"info\"\n          class=\"ml-3 mr-0 my-0 pa-0\"\n          @click=\"filterMenuOpen = true\"\n          >View Filters</v-btn\n        >\n      </v-alert>\n    </v-scroll-x-reverse-transition>\n\n    <v-tabs-items\n      v-model=\"tab\"\n      tag=\"div\"\n      class=\"px-6 mx-auto tabs-border-bottom tab-full-height\"\n      style=\"max-width: 1440px;\"\n      :style=\"{\n        'padding-top': $vuetify.breakpoint.smOnly ? '80px' : '100px'\n      }\"\n    >\n      <v-tab-item\n        class=\"pa-0\"\n        value=\"overview\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <v-row\n          v-if=\"filteredAgents && filteredAgents.length > 0\"\n          :style=\"{\n            'padding-top': $vuetify.breakpoint.smOnly ? '10px' : '1px',\n            'padding-bottom': $vuetify.breakpoint.smOnly ? '10px' : '10px'\n          }\"\n        >\n          <v-col\n            v-for=\"agent in filteredAgents\"\n            :key=\"agent.id\"\n            cols=\"12\"\n            sm=\"6\"\n            md=\"4\"\n            lg=\"3\"\n          >\n            <AgentTile\n              :raw-agent=\"agent\"\n              :selected-labels=\"labelInput\"\n              @label-click=\"handleLabelClick\"\n            ></AgentTile>\n          </v-col>\n        </v-row>\n        <v-row v-else-if=\"filtersApplied\" class=\"ma-8\">\n          <v-col cols=\"12\">\n            <div\n              class=\"text-center position-absolute center-absolute text-h5 utilGrayDark--text\"\n              style=\"z-index: 1;\"\n            >\n              No agents found. Try removing a filter.\n            </div>\n          </v-col>\n        </v-row>\n        <v-row v-else class=\"ma-8\">\n          <v-col cols=\"12\">\n            <div\n              class=\"text-center position-absolute center-absolute text-h5 utilGrayDark--text\"\n              style=\"z-index: 1;\"\n            >\n              You have no agents querying for runs. For help setting up an\n              agent, check out the agent\n              <a\n                href=\"https://docs.prefect.io/orchestration/agents/overview.html\"\n                target=\"_blank\"\n                rel=\"noopener noreferrer\"\n                >docs</a\n              >\n              or\n              <router-link class=\"link\" :to=\"'/tutorial/Universal-Deploy'\">\n                <u>tutorial</u> </router-link\n              >.\n            </div>\n          </v-col>\n        </v-row>\n      </v-tab-item>\n    </v-tabs-items>\n  </v-sheet>\n</template>\n\n<style lang=\"scss\" scoped>\n.agents-list-move {\n  transition: transform 300ms;\n}\n\n.agents-list-enter-active,\n.agents-list-leave-active {\n  transition: all 300ms;\n}\n\n.agents-list-leave-active {\n  position: absolute;\n}\n\n.agents-list-enter,\n.agents-list-leave-to {\n  opacity: 0;\n}\n\n.agent-controls {\n  left: 50%;\n  position: fixed;\n  transform: translate(570px);\n  z-index: 6;\n\n  &.sm-and-down {\n    top: 156px;\n  }\n\n  &.md {\n    top: 184px;\n  }\n\n  &.lg-and-up {\n    top: 136px;\n  }\n\n  @media screen and (max-width: 1440px) {\n    left: unset;\n    right: 12px;\n    transform: unset;\n  }\n\n  @media screen and (max-width: 960px) {\n    background-color: var(--v-appBackground-base);\n\n    left: 50%;\n    right: unset;\n    transform: translate(-50%);\n  }\n\n  @media screen and (max-width: 600px) {\n    left: unset;\n    right: 12px;\n    top: 64px !important;\n    transform: unset;\n  }\n}\n\n.filter-alert-position {\n  position: absolute;\n  right: 16px;\n  top: 80px;\n  z-index: 10;\n}\n\n.font-size-custom {\n  font-size: 1.35em;\n}\n\n.label-switch-position {\n  position: relative;\n  top: -16px;\n}\n\n.center-absolute {\n  left: 50%;\n  top: 80%;\n  transform: translate(-50%, -50%);\n}\n</style>\n"
  },
  {
    "path": "src/pages/Agents/SubmittableRuns.vue",
    "content": "<script>\nimport { mapGetters, mapMutations } from 'vuex'\nimport CardTitle from '@/components/Card-Title'\nimport DurationSpan from '@/components/DurationSpan'\nimport { cancelLateRunsMixin } from '@/mixins/cancelLateRunsMixin'\nimport { runFlowNowMixin } from '@/mixins/runFlowNow'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport Alert from '@/components/Alert'\nimport ClearLate from '@/components/SystemActions/ClearLate'\nimport WorkQueue from '@/components/SystemActions/WorkQueue'\n\nexport default {\n  components: {\n    CardTitle,\n    DurationSpan,\n    Alert,\n    ClearLate,\n    WorkQueue\n  },\n  mixins: [cancelLateRunsMixin, runFlowNowMixin, formatTime],\n  props: {\n    rawAgent: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    const tabs = {\n      submittable: 0,\n      late: 1\n    }\n\n    return {\n      tab: tabs.submittable,\n      tabs,\n      overlay: null,\n      userSetTab: false,\n      loadingKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('agent', [\n      'staleThreshold',\n      'unhealthyThreshold',\n      'sortedAgents'\n    ]),\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['timezone']),\n    agent() {\n      const agent = { ...this.rawAgent }\n      const getTimeOverdue = time => new Date() - new Date(time)\n      agent.submittableRuns = []\n      agent.lateRuns = []\n\n      if (!agent.labels?.length) {\n        const noLabels = this.flowRuns?.filter(flowRun => {\n          return !flowRun?.labels?.length\n        })\n        agent.submittableRuns = noLabels?.filter(\n          flowRun => getTimeOverdue(flowRun.scheduled_start_time) <= 20000\n        )\n        agent.lateRuns = noLabels?.filter(\n          flowRun => getTimeOverdue(flowRun.scheduled_start_time) > 20000\n        )\n      } else {\n        const match = this.flowRuns?.filter(\n          flowRun =>\n            flowRun?.labels?.length &&\n            flowRun.labels.every(label => agent?.labels?.includes(label))\n        )\n        agent.submittableRuns = match?.filter(\n          flowRun => getTimeOverdue(flowRun.scheduled_start_time) <= 20000\n        )\n        agent.lateRuns = match?.filter(\n          flowRun => getTimeOverdue(flowRun.scheduled_start_time) > 20000\n        )\n      }\n      return agent\n    },\n    paused() {\n      return this.tenant?.settings?.work_queue_paused\n    },\n    lateRuns() {\n      if (!this.agent.lateRuns) return []\n      return [...this.agent.lateRuns].sort(\n        (a, b) =>\n          new Date(a.scheduled_start_time) - new Date(b.scheduled_start_time)\n      )\n    },\n    loading() {\n      return this.loadingKey > 0\n    },\n    submittableRuns() {\n      if (!this.agent.submittableRuns) return []\n      return [...this.agent?.submittableRuns].sort(\n        (a, b) =>\n          new Date(a.scheduled_start_time) - new Date(b.scheduled_start_time)\n      )\n    },\n    title() {\n      return this.tabProperties[this.tab].title\n    },\n    titleIcon() {\n      return this.tabProperties[this.tab].icon\n    },\n    titleIconColor() {\n      if (this.loading) return 'grey'\n\n      return this.tabProperties[this.tab].icon_color\n    },\n    systemBarColor() {\n      if (this.loading) return 'secondaryGray'\n\n      return this.lateRuns?.length > 0 ? 'deepRed' : 'Success'\n    },\n    tabProperties() {\n      const submittableCount = this.submittableRuns?.length || 0\n      const lateCount = this.lateRuns?.length || 0\n\n      return {\n        [this.tabs.submittable]: {\n          title: `${this.getFriendlyCount(submittableCount)} submittable runs`,\n          icon: 'access_time',\n          icon_color: 'primary'\n        },\n        [this.tabs.late]: {\n          title: `${this.getFriendlyCount(lateCount)} late runs`,\n          icon: 'timelapse',\n          icon_color: lateCount > 0 ? 'deepRed' : 'Success'\n        }\n      }\n    },\n    submittableTabTitle() {\n      const submittableCount = this.submittableRuns?.length || 0\n\n      if (this.tab == this.tabs.submittable || submittableCount == 0) {\n        return 'Submittable'\n      }\n\n      return `(${this.getFriendlyCount(submittableCount)}) Submittable`\n    },\n    lateTabTitle() {\n      const lateCount = this.lateRuns?.length || 0\n\n      if (this.tab == this.tabs.late || lateCount == 0) {\n        return 'Late'\n      }\n\n      return `(${this.getFriendlyCount(lateCount)}) Late`\n    }\n  },\n  watch: {\n    agent(val) {\n      if (!val || this.userSetTab) return\n\n      if (this.tab == this.tabs.submittable && this.lateRuns?.length > 0) {\n        this.tab = this.tabs.late\n      } else if (this.tab == this.tabs.late && this.lateRuns?.length == 0) {\n        this.tab = this.tabs.submittable\n      }\n    },\n    ['tenant.settings.work_queue_paused'](val) {\n      if (!val) {\n        setTimeout(() => {\n          this.hideOverlay()\n        }, 1500)\n      }\n    }\n  },\n  mounted() {\n    if (this.agent?.lateRuns?.length) this.tab = this.tabs.late\n  },\n  methods: {\n    ...mapMutations('agent', ['setRefetch']),\n    flowName(flowRun) {\n      return flowRun?.flow?.name\n    },\n    flowRunName(flowRun) {\n      return flowRun?.name\n    },\n    showOverlay(kind) {\n      this.overlay = kind\n    },\n    hideOverlay() {\n      this.overlay = null\n    },\n    refetch() {\n      this.setRefetch(true)\n      this.overlay = null\n    },\n    getFriendlyCount(count) {\n      return count > 999 ? '1,000+' : count\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRuns.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRuns: {\n      query: require('@/graphql/Agent/FlowRuns.gql'),\n      pollInterval: 1000,\n      loadingKey: 'loadingKey',\n      update(data) {\n        return data.flow_run\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"py-2\"\n    tile\n    height=\"380px\"\n  >\n    <v-system-bar :color=\"systemBarColor\" :height=\"5\" absolute />\n\n    <CardTitle :title=\"title\" :icon=\"titleIcon\" :icon-color=\"titleIconColor\">\n      <v-row slot=\"title\" no-gutters class=\"d-flex align-center\">\n        <v-col cols=\"10\">\n          <div>\n            <div\n              v-if=\"loading || (tab === tabs.late && isClearingLateRuns)\"\n              style=\"\n                display: inline-block;\n                height: 20px;\n                overflow: hidden;\n                width: 20px;\"\n            >\n              <v-skeleton-loader type=\"avatar\" tile />\n            </div>\n            {{ title }}\n          </div>\n        </v-col>\n      </v-row>\n    </CardTitle>\n\n    <v-tabs\n      v-model=\"tab\"\n      tabs-border-bottom\n      :color=\"titleIconColor\"\n      class=\"flex-grow-0\"\n      @change=\"userSetTab = true\"\n    >\n      <v-tab :key=\"tabs.submittable\" data-cy=\"submittable-runs-submittable\">\n        {{ submittableTabTitle }}\n      </v-tab>\n      <v-tab :key=\"tabs.late\" data-cy=\"submittable-runs-late\">\n        <v-icon v-if=\"lateRuns && lateRuns.length > 0\" small color=\"deepRed\">\n          warning\n        </v-icon>\n        {{ lateTabTitle }}\n      </v-tab>\n    </v-tabs>\n\n    <v-card-text v-show=\"overlay\" class=\"pa-0\">\n      <v-overlay v-show=\"overlay == 'late'\" absolute z-index=\"1\">\n        <ClearLate :flow-runs=\"lateRuns\" @finish=\"refetch\" />\n      </v-overlay>\n      <v-overlay v-show=\"overlay == 'queue'\" absolute z-index=\"1\">\n        <WorkQueue />\n      </v-overlay>\n    </v-card-text>\n\n    <v-card-text\n      class=\"px-0 py-2\"\n      :class=\"\n        lateRuns && lateRuns.length ? 'late-card-content' : 'card-content'\n      \"\n    >\n      <v-tabs-items v-model=\"tab\">\n        <v-tab-item>\n          <v-skeleton-loader v-if=\"loading\" type=\"list-item-three-line\" />\n\n          <v-list-item\n            v-else-if=\"submittableRuns && submittableRuns.length === 0\"\n            dense\n          >\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon class=\"green--text\">check</v-icon>\n            </v-list-item-avatar>\n            <v-list-item-content class=\"my-0 py-0\">\n              <div\n                class=\"text-subtitle-1 font-weight-light\"\n                style=\"line-height: 1.25rem;\"\n              >\n                No submittable runs.\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-virtual-scroll\n            v-else\n            :items=\"submittableRuns\"\n            height=\"232px\"\n            item-height=\"50px\"\n          >\n            <template #default=\"{item}\">\n              <v-list-item\n                :key=\"item.id\"\n                :disabled=\"setToRun.includes(item.id)\"\n                dense\n              >\n                <v-list-item-content>\n                  <v-list-item-subtitle class=\"text-body-1 font-weight-regular\">\n                    <router-link\n                      :to=\"{ name: 'flow', params: { id: item.flow_id } }\"\n                    >\n                      {{ flowName(item) }}\n                    </router-link>\n                    <span class=\"font-weight-bold\">\n                      <v-icon style=\"font-size: 12px;\">\n                        chevron_right\n                      </v-icon>\n                    </span>\n                    <router-link\n                      :to=\"{ name: 'flow-run', params: { id: item.id } }\"\n                    >\n                      {{ item.name }}\n                    </router-link>\n                  </v-list-item-subtitle>\n\n                  <span class=\"text-caption mb-0 ml-n1 d-flex align-center\">\n                    <span class=\"ml-1\">\n                      Scheduled for\n                      {{ formatDateTime(item.scheduled_start_time) }}\n                    </span>\n                  </span>\n                </v-list-item-content>\n\n                <v-list-item-action tile min-width=\"5\" class=\"text-body-2\">\n                  <v-tooltip top>\n                    <template #activator=\"{ on }\">\n                      <v-btn\n                        text\n                        x-small\n                        aria-label=\"Run Now\"\n                        :disabled=\"setToRun.includes(item.id)\"\n                        color=\"primary\"\n                        class=\"vertical-button\"\n                        v-on=\"on\"\n                        @click=\"runFlowNow(item.id, item.version, item.name)\"\n                      >\n                        <v-icon small dense color=\"primary\"> fa-rocket</v-icon>\n                      </v-btn>\n                    </template>\n                    <span> Run {{ item.name }} now </span>\n                  </v-tooltip>\n                </v-list-item-action>\n              </v-list-item>\n            </template>\n          </v-virtual-scroll>\n\n          <Alert\n            v-model=\"showAlert\"\n            :type=\"alertType\"\n            :message=\"alertMessage\"\n            :alert-link=\"alertLink\"\n            :timeout=\"12000\"\n          >\n          </Alert>\n        </v-tab-item>\n\n        <v-tab-item>\n          <v-skeleton-loader\n            v-if=\"loading || isClearingLateRuns\"\n            type=\"list-item-three-line\"\n          />\n\n          <v-list-item v-else-if=\"lateRuns && lateRuns.length === 0\" dense>\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon class=\"green--text\">check</v-icon>\n            </v-list-item-avatar>\n            <v-list-item-content class=\"my-0 py-0\">\n              <div\n                class=\"text-subtitle-1 font-weight-light\"\n                style=\"line-height: 1.25rem;\"\n              >\n                Everything is running on schedule!\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-virtual-scroll\n            v-else\n            :items=\"lateRuns\"\n            height=\"232px\"\n            item-height=\"76px\"\n          >\n            <template #default=\"{item}\">\n              <v-list-item :key=\"item.id\" dense three-line>\n                <v-list-item-content>\n                  <v-list-item-subtitle class=\"text-body-1 font-weight-regular\">\n                    <router-link\n                      :to=\"{ name: 'flow', params: { id: item.flow_id } }\"\n                    >\n                      {{ flowName(item) }}\n                    </router-link>\n                    <span class=\"font-weight-bold\">\n                      <v-icon style=\"font-size: 12px;\">\n                        chevron_right\n                      </v-icon>\n                    </span>\n                    <router-link\n                      :to=\"{ name: 'flow-run', params: { id: item.id } }\"\n                    >\n                      {{ item.name }}\n                    </router-link>\n                  </v-list-item-subtitle>\n\n                  <span class=\"text-caption mb-0 ml-n1 d-flex align-center\">\n                    <span class=\"ml-1\">\n                      Scheduled for\n                      {{ formatDateTime(item.scheduled_start_time) }}\n                    </span>\n                  </span>\n\n                  <v-list-item-subtitle class=\"text-caption\">\n                    <DurationSpan :start-time=\"item.scheduled_start_time\" />\n                    behind schedule\n                  </v-list-item-subtitle>\n                </v-list-item-content>\n              </v-list-item>\n            </template>\n          </v-virtual-scroll>\n        </v-tab-item>\n      </v-tabs-items>\n    </v-card-text>\n\n    <v-card-actions class=\"py-0\">\n      <v-spacer />\n      <v-btn\n        v-if=\"!overlay && lateRuns && lateRuns.length > 0\"\n        small\n        depressed\n        color=\"primary\"\n        text\n        style=\"z-index: 2;\"\n        @click=\"showOverlay('late')\"\n      >\n        Clear late\n      </v-btn>\n\n      <v-btn\n        v-if=\"overlay && !paused\"\n        small\n        depressed\n        plain\n        color=\"white\"\n        width=\"74\"\n        text\n        style=\"z-index: 2;\"\n        @click=\"hideOverlay\"\n      >\n        Close\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\na {\n  text-decoration: none !important;\n}\n\n.button-transition {\n  transition: border-right 150ms linear;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.late-card-content {\n  height: 100%;\n  max-height: calc(280px - var(--v-tabs-height));\n  overflow-y: auto;\n  position: relative;\n}\n\n.card-content {\n  height: 100%;\n  max-height: calc(300px - var(--v-tabs-height));\n  overflow-y: auto;\n  position: relative;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Auth/Auth.vue",
    "content": "<script>\nexport default {\n  data() {\n    return {\n      previousHeight: 0\n    }\n  },\n  methods: {\n    afterEnter(element) {\n      element.style.height = 'auto'\n    },\n    beforeLeave(element) {\n      this.previousHeight = getComputedStyle(element).height\n    },\n    enter(element) {\n      const { height } = getComputedStyle(element)\n      element.style.height = this.previousHeight\n\n      setTimeout(() => {\n        element.style.height = height\n      })\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container class=\"transition-container\">\n    <v-card tile class=\"mx-auto transition-height universal-card\" width=\"500\">\n      <div ref=\"universal-card\" class=\"pa-12\">\n        <div class=\"arboria text-center\">\n          <img src=\"@/assets/logos/cloud-logo.svg\" />\n        </div>\n\n        <transition\n          name=\"fade\"\n          mode=\"out-in\"\n          @beforeLeave=\"beforeLeave\"\n          @enter=\"enter\"\n          @afterEnter=\"afterEnter\"\n        >\n          <router-view />\n        </transition>\n      </div>\n    </v-card>\n  </v-container>\n</template>\n\n<style lang=\"scss\">\n/* stylelint-disable */\ninput:-webkit-autofill {\n  box-shadow: 0 0 0 50px var(--v-appForeground-base) inset !important;\n  -webkit-box-shadow: 0 0 0 50px var(--v-appForeground-base) inset !important;\n  -webkit-text-fill-color: var(--v-utilGrayDark-base) !important;\n}\n\ninput:-webkit-autofill:focus {\n  box-shadow: 0 0 0 50px var(--v-appForeground-base) inset !important;\n  -webkit-box-shadow: 0 0 0 50px var(--v-appForeground-base) inset !important;\n  -webkit-text-fill-color: var(--v-utilGrayDark-base) !important;\n}\n/* stylelint-enable */\n\n.logo {\n  width: 75px;\n}\n\n.position-relative {\n  position: relative;\n}\n\n.universal-card {\n  position: relative;\n}\n\n.transition-container {\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n\n.transition-height {\n  transition: max-height 250ms linear !important;\n}\n\n/*\n  This is the fade transition css class overrides\n*/\n.fade-enter-active,\n.fade-leave-active {\n  overflow: hidden;\n  transition: all 250ms ease-in-out;\n}\n\n.fade-enter,\n.fade-leave-active {\n  opacity: 0;\n}\n\n@keyframes fade {\n  0% {\n    opacity: 0;\n  }\n\n  50% {\n    opacity: 0;\n  }\n\n  100% {\n    opacity: 1;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Auth/ForgotPassword.vue",
    "content": "<script>\nimport { authMixin } from '@/mixins/authMixin.js'\n\nexport default {\n  mixins: [authMixin],\n  data() {\n    return {\n      email: null,\n      error: null,\n      success: false\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container fluid>\n    <div\n      class=\"text-subtitle-1 my-4 font-weight-bold text-center grey--text text--darken-2\"\n    >\n      Recover Password\n    </div>\n\n    <v-form\n      class=\"text-center\"\n      :class=\"error ? 'mb-5' : 'mb-12'\"\n      @submit.prevent=\"resetPassword\"\n      @keyup.enter=\"resetPassword\"\n    >\n      <div\n        v-if=\"!success && !error\"\n        class=\"my-2 mb-10 arboria text-center text-body-2 mx-auto\"\n      >\n        <div class=\"primary--text font-weight-bold text-body-1\"\n          >Don't panic!</div\n        >\n        We’ll email you instructions to reset your password.\n      </div>\n\n      <transition-group name=\"fade\" mode=\"out-in\">\n        <div v-if=\"!success && !error\" key=\"field\" class=\"my-4\">\n          <v-text-field\n            v-model=\"email\"\n            class=\"arboria\"\n            outlined\n            type=\"email\"\n            label=\"Your email\"\n            hide-details\n            prepend-inner-icon=\"email\"\n          />\n        </div>\n\n        <div v-else-if=\"success\" key=\"success\" class=\"my-4 primary--text\">\n          <v-icon x-large class=\"mx-auto mb-4\" color=\"primary\">\n            mail_outline\n          </v-icon>\n          <div>\n            Please check the email address\n            <span class=\"font-weight-bold\">{{ email }}</span> for instructions\n            on resetting your password.\n          </div>\n        </div>\n\n        <div v-else key=\"error\" class=\"my-4\">\n          <div v-if=\"error\" class=\"error--text arboria text-center\">\n            {{ error }}\n          </div>\n        </div>\n      </transition-group>\n\n      <v-btn\n        v-if=\"!success && !error\"\n        color=\"primary\"\n        class=\"btn btn-primary btn-block mt-10\"\n        height=\"45\"\n        type=\"submit\"\n        block\n        depressed\n      >\n        Send me a recovery link\n      </v-btn>\n    </v-form>\n\n    <div\n      class=\"text-caption mt-12 text-center d-flex align-center justify-center\"\n    >\n      <router-link :to=\"'/login'\">\n        <div class=\"d-flex align-center justify-center\">\n          <v-icon>keyboard_arrow_left</v-icon>Back to sign in\n        </div>\n      </router-link>\n    </div>\n  </v-container>\n</template>\n\n<style>\n/* // */\n</style>\n"
  },
  {
    "path": "src/pages/Auth/Logout.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nconst quotes = [\n  '\"The first ten million years were the worst,\" said Marvin, \"and the second ten million years, they were the worst too. The third ten million years I didn\\'t enjoy at all. After that I went into a bit of a decline.\"',\n  '\"It\\'s part of the shape of the Universe. I only have to talk to somebody and they begin to hate me.\"',\n  '\"Don\\'t blame you,\" said Marvin and counted five hundred and ninety-seven thousand million sheep before falling asleep again a second later.',\n  'Having solved all the major mathematical, physical, chemical, biological, sociological, philosophical, etymological, meteorological and psychological problems of the Universe except for his own, three times over, [Marvin] was severely stuck for something to do, and had taken up composing short dolorous ditties of no tone, or indeed tune. The latest one was a lullaby. Marvin droned, \"Now the world has gone to bed, Darkness won\\'t engulf my head, I can see in infrared, How I hate the night. He paused to gather the artistic and emotional strength to tackle the next verse. Now I lay me down to sleep, Try to count electric sheep, Sweet dream wishes you can keep, How I hate the night.\"'\n]\n\nexport default {\n  data() {\n    return {\n      redirecting: false,\n      quote: quotes[Math.floor(Math.random() * quotes.length)]\n    }\n  },\n  computed: {\n    ...mapGetters('auth', ['isAuthenticated'])\n  },\n  watch: {\n    isAuthenticated(val, oldVal) {\n      if (val && oldVal !== val) {\n        this.$router.push({ name: 'dashboard' })\n      }\n    }\n  },\n  mounted() {\n    if (this.isAuthenticated) {\n      this.$router.push({ name: 'dashboard' })\n    }\n  },\n  methods: {\n    redirectToLogin() {\n      this.redirecting = true\n      setTimeout(() => {\n        window.location.href = '/'\n      }, 1500)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container\n    class=\"d-flex flex-column align-center justify-center text-h4 h-100\"\n  >\n    <div>\n      You're now signed out.\n    </div>\n    <div class=\"d-flex align-center justify-center\">\n      <i class=\"fad fa-quote-left\" />\n      <v-avatar class=\"ml-4\" size=\"80\">\n        <img src=\"@/assets/logos/marvin.jpg\" alt=\"Marvin Avatar\" />\n      </v-avatar>\n      <blockquote class=\"blockquote text-body-1 text--secondary\">\n        {{ quote }}\n      </blockquote>\n    </div>\n    <v-btn\n      color=\"prefect\"\n      dark\n      class=\"mt-8\"\n      large\n      :loading=\"redirecting\"\n      @click=\"redirectToLogin\"\n    >\n      Sign In\n    </v-btn>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.h-100 {\n  height: 100vh;\n}\n\n.blockquote {\n  max-width: 600px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Auth/SignIn.vue",
    "content": "<script>\nimport { authMixin } from '@/mixins/authMixin.js'\n\nexport default {\n  mixins: [authMixin],\n  data() {\n    return {\n      autofilled: false,\n      form: null,\n      showSignup: true || window.location.hostname === 'login.prefect.io'\n    }\n  },\n  mounted() {\n    this.$refs.email.$el\n      .querySelector('input')\n      .addEventListener('animationstart', this.focus)\n    this.$refs.password.$el\n      .querySelector('input')\n      .addEventListener('animationstart', this.focus)\n  },\n  methods: {\n    focus(e) {\n      switch (e.animationName) {\n        case 'onAutoFillStart':\n          this.autofilled = true\n          this.$refs.email.focus()\n          break\n        case 'onAutoFillCancel':\n          this.autofilled = false\n          break\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container fluid>\n    <div\n      class=\"text-subtitle-1 my-4 font-weight-bold text-center grey--text text--darken-2\"\n    >\n      Sign in\n    </div>\n\n    <v-form\n      v-model=\"form\"\n      class=\"text-center\"\n      :class=\"!showSignup ? '' : error ? 'mb-5' : 'mb-8'\"\n      @submit.prevent=\"login\"\n      @keyup.enter=\"login\"\n    >\n      <div class=\"my-4\">\n        <v-text-field\n          ref=\"email\"\n          v-model=\"email\"\n          class=\"arboria autofillable-input\"\n          outlined\n          type=\"email\"\n          label=\"Email\"\n          :placeholder=\"autofilled ? ' ' : null\"\n          hide-details\n          autocomplete=\"email\"\n          prepend-inner-icon=\"email\"\n        />\n      </div>\n      <div class=\"mt-4 mb-2\">\n        <v-text-field\n          ref=\"password\"\n          v-model=\"password\"\n          class=\"arboria mb-0 autofillable-input\"\n          outlined\n          type=\"password\"\n          label=\"Password\"\n          :placeholder=\"autofilled ? ' ' : null\"\n          hide-details\n          autocomplete=\"current-password\"\n          prepend-inner-icon=\"lock\"\n        />\n      </div>\n\n      <div class=\"text-caption text-left\">\n        <router-link :to=\"'/login/forgot-password'\">\n          Forgot password?\n        </router-link>\n      </div>\n\n      <v-btn\n        block\n        depressed\n        color=\"primary\"\n        class=\"btn btn-primary btn-block mt-6 pa-3\"\n        height=\"45\"\n        type=\"submit\"\n      >\n        Continue\n      </v-btn>\n    </v-form>\n\n    <div v-if=\"error\" class=\"mt-2 alert error--text arboria text-center\">\n      {{ error }}\n    </div>\n\n    <div v-if=\"showSignup\">\n      <v-divider class=\"my-5\" />\n\n      <div class=\"py-2 text-center\">\n        <v-btn\n          color=\"white\"\n          block\n          height=\"auto\"\n          class=\"google-button mx-auto pa-3\"\n          @click=\"loginWithGoogle\"\n        >\n          <v-avatar size=\"25\" left>\n            <v-img src=\"@/assets/companies/google.png\" />\n          </v-avatar>\n\n          <span class=\"ml-4 grey--text text--darken-2\">\n            Continue with Google\n          </span>\n        </v-btn>\n      </div>\n\n      <div class=\"py-2 text-center\">\n        <v-btn\n          color=\"white\"\n          block\n          height=\"auto\"\n          class=\"google-button mx-auto pa-3\"\n          @click=\"loginWithGitHub\"\n        >\n          <v-avatar size=\"25\" left>\n            <v-img src=\"@/assets/companies/github.png\" />\n          </v-avatar>\n\n          <span class=\"ml-4 grey--text text--darken-2\">\n            Continue with GitHub\n          </span>\n        </v-btn>\n      </div>\n\n      <v-divider class=\"my-5\" />\n\n      <div\n        class=\"text-caption mt-12 text-center d-flex align-center justify-center\"\n      >\n        New to Prefect Cloud?\n        <router-link :to=\"'/login/sign-up'\">\n          <div class=\"ml-1\">\n            Create an account\n          </div>\n        </router-link>\n        .\n      </div>\n    </div>\n  </v-container>\n</template>\n\n<style lang=\"scss\">\n// This method was developed by the Klarna UI team to\n// \"hack\" the autofill bug in Chromium...\n// I've adapted it to Vue and made some modifications for\n// Vuetify.\n.autofillable-input {\n  input:-webkit-autofill {\n    // Expose a hook for JavaScript when auto fill is shown.\n    // JavaScript can capture 'animationstart' events\n    animation-name: onAutoFillStart;\n\n    // Make the backgound color become yellow _really slowly_\n    transition: background-color 50000s ease-in-out 0s;\n  }\n\n  input:not(:-webkit-autofill) {\n    // Expose a hook for JS onAutoFillCancel\n    // JavaScript can capture 'animationstart' events\n    animation-name: onAutoFillCancel;\n  }\n}\n\n// stylelint-disable\n@keyframes onAutoFillStart {\n  from {\n    /**/\n  }\n  to {\n    /**/\n  }\n}\n\n@keyframes onAutoFillCancel {\n  from {\n    /**/\n  }\n  to {\n    /**/\n  }\n}\n// stylelint-enable\n</style>\n"
  },
  {
    "path": "src/pages/Auth/SignUp.vue",
    "content": "<script>\nimport { authMixin } from '@/mixins/authMixin.js'\n\nconst lowercase = /(?=.*[a-z])/g\n\nconst uppercase = /(?=.*[A-Z])/g\n\nconst numbers = /(?=.*[0-9])/g\n\nconst special = /(?=.*[!@#$%^&*(),.?\":{}|<>])/g\n\nexport default {\n  mixins: [authMixin],\n  data() {\n    return {\n      email: null,\n      error: null,\n      password: null,\n      passwordConfirm: null,\n      passwordHintIsShown: true,\n      passwordIsFocused: false,\n      rules: {\n        email: val => {\n          const pattern = /^(([^<>()[\\]\\\\.,;:\\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          return pattern.test(val) || 'Invalid e-mail'\n        },\n        required: val => !!val || 'Required',\n        match: val => val === this.password || 'Passwords do not match'\n      },\n      validation: {\n        length: null,\n        lowercase: null,\n        uppercase: null,\n        numbers: null,\n        special: null\n      }\n    }\n  },\n  computed: {\n    passwordMeets3SubCriteria() {\n      return (\n        [\n          this.validation.lowercase,\n          this.validation.uppercase,\n          this.validation.numbers,\n          this.validation.special\n        ].filter(i => i)?.length >= 3\n      )\n    },\n    passwordMeetsCriteria() {\n      return this.validation.length && this.passwordMeets3SubCriteria\n    }\n  },\n  watch: {\n    passwordMeetsCriteria(val) {\n      if (val) {\n        setTimeout(() => {\n          this.passwordHintIsShown = false\n        }, 500)\n      } else {\n        this.passwordHintIsShown = true\n      }\n    },\n    password() {\n      this.error = null\n    },\n    email() {\n      this.error = null\n    },\n    passwordConfirm() {\n      this.error = null\n    }\n  },\n  methods: {\n    blur() {\n      this.passwordIsFocused = false\n    },\n    focus() {\n      this.passwordIsFocused = true\n    },\n    validate() {\n      this.validation.length = this.password?.length >= 10\n\n      this.validation.lowercase = lowercase.test(this.password)\n      this.validation.uppercase = uppercase.test(this.password)\n      this.validation.numbers = numbers.test(this.password)\n      this.validation.special = special.test(this.password)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container fluid>\n    <div\n      class=\"text-subtitle-1 my-4 font-weight-bold text-center grey--text text--darken-2\"\n    >\n      Create Account\n    </div>\n\n    <v-form\n      class=\"text-center\"\n      :class=\"error ? 'mb-5' : 'mb-8'\"\n      @submit.prevent=\"signup\"\n      @keyup.enter=\"signup\"\n    >\n      <div class=\"mb-3\">\n        <v-text-field\n          v-model=\"email\"\n          class=\"arboria\"\n          outlined\n          type=\"email\"\n          label=\"Email\"\n          prepend-inner-icon=\"email\"\n          :rules=\"[rules.required, rules.email]\"\n        />\n      </div>\n      <div class=\"position-relative mb-3\">\n        <v-text-field\n          v-model=\"password\"\n          class=\"arboria\"\n          outlined\n          type=\"password\"\n          autocomplete=\"off\"\n          label=\"Password\"\n          prepend-inner-icon=\"lock\"\n          :rules=\"[rules.required]\"\n          @focus=\"focus\"\n          @blur=\"blur\"\n          @keyup=\"validate\"\n        />\n\n        <transition name=\"hint\">\n          <div\n            v-if=\"passwordIsFocused && passwordHintIsShown\"\n            class=\"password-hint-container\"\n          >\n            <v-card\n              class=\"text-caption pa-4 text-left password-hint\"\n              tile\n              elevation=\"4\"\n            >\n              <v-card-text class=\"pa-0\">\n                <div :class=\"passwordMeetsCriteria ? 'success--text' : ''\">\n                  Your password must contain:\n                </div>\n                <div\n                  class=\"ml-4\"\n                  :class=\"validation.length ? 'success--text' : ''\"\n                >\n                  At least 10 characters\n                </div>\n                <div\n                  class=\"ml-4\"\n                  :class=\"passwordMeets3SubCriteria ? 'success--text' : ''\"\n                >\n                  At least 3 of the following:\n                </div>\n                <div\n                  class=\"ml-8\"\n                  :class=\"validation.lowercase ? 'success--text' : ''\"\n                >\n                  Lower case letters (a-z)\n                </div>\n                <div\n                  class=\"ml-8\"\n                  :class=\"validation.uppercase ? 'success--text' : ''\"\n                >\n                  Upper case letters (A-Z)\n                </div>\n                <div\n                  class=\"ml-8\"\n                  :class=\"validation.numbers ? 'success--text' : ''\"\n                >\n                  Numbers (0-9)\n                </div>\n                <div\n                  class=\"ml-8\"\n                  :class=\"validation.special ? 'success--text' : ''\"\n                >\n                  Special characters (ex. !@#)\n                </div>\n              </v-card-text>\n            </v-card>\n          </div>\n        </transition>\n      </div>\n\n      <div class=\"position-relative\">\n        <v-text-field\n          v-model=\"passwordConfirm\"\n          class=\"arboria\"\n          outlined\n          type=\"password\"\n          autocomplete=\"off\"\n          label=\"Confirm Password\"\n          prepend-inner-icon=\"verified_user\"\n          :rules=\"[rules.required, rules.match]\"\n          @keyup=\"validate\"\n        />\n      </div>\n\n      <v-btn\n        color=\"primary\"\n        class=\"btn btn-primary btn-block mt-1\"\n        height=\"45\"\n        type=\"submit\"\n        block\n        depressed\n      >\n        Create Account\n      </v-btn>\n    </v-form>\n\n    <div v-if=\"error\" class=\"mt-2 alert error--text arboria text-center\">\n      {{ error }}\n    </div>\n\n    <v-divider class=\"my-5\" />\n\n    <div class=\"py-2 text-center\">\n      <v-btn\n        color=\"white\"\n        block\n        height=\"auto\"\n        class=\"google-button mx-auto pa-3\"\n        @click=\"loginWithGoogle\"\n      >\n        <v-avatar size=\"25\" left>\n          <v-img src=\"@/assets/companies/google.png\" />\n        </v-avatar>\n\n        <span class=\"ml-4 grey--text text--darken-2\">\n          Sign up with Google\n        </span>\n      </v-btn>\n    </div>\n\n    <div class=\"py-2 text-center\">\n      <v-btn\n        color=\"white\"\n        block\n        height=\"auto\"\n        class=\"google-button mx-auto pa-3\"\n        @click=\"loginWithGitHub\"\n      >\n        <v-avatar size=\"25\" left>\n          <v-img src=\"@/assets/companies/github.png\" />\n        </v-avatar>\n\n        <span class=\"ml-4 grey--text text--darken-2\">\n          Sign up with GitHub\n        </span>\n      </v-btn>\n    </div>\n\n    <v-divider class=\"my-5\" />\n\n    <div\n      class=\"text-caption mt-12 text-center d-flex align-center justify-center\"\n    >\n      Already have an account?\n      <router-link :to=\"'/login'\">\n        <div class=\"ml-1\">\n          Sign in\n        </div>\n      </router-link>\n      .\n    </div>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.password-hint-container {\n  left: 50%;\n  position: absolute;\n  top: 75px;\n  transform: translate(-50%);\n  z-index: 1;\n\n  .password-hint {\n    position: relative;\n    width: 250px;\n\n    &::before {\n      background-color: var(--v-appForeground-base);\n      box-shadow: 0 0 2px -2px rgba(0, 0, 0, 0.2), 0 0 2px 0 rgba(0, 0, 0, 0.14),\n        0 -1px 5px 0 rgba(0, 0, 0, 0.12);\n      content: '';\n      height: 36px;\n      left: 50%;\n      position: absolute;\n      top: -18px;\n      transform: translate(-50%) rotate(45deg);\n      width: 36px;\n      z-index: -1;\n    }\n\n    // stylelint-disable\n    &::after {\n      // stylelint-enable\n      border: solid transparent;\n      border-color: var(--v-appForeground-base);\n      border-top-color: rgba(255, 255, 255, 0);\n      border-width: 20px;\n      bottom: 100%;\n      content: ' ';\n      height: 0;\n      left: 50%;\n      pointer-events: none;\n      position: absolute;\n      top: -1px;\n      transform: translate(-50%);\n      width: 51px;\n      z-index: -1;\n    }\n  }\n}\n\n/*\n  This is the fade transition css class overrides\n*/\n.hint-enter-active {\n  animation: fade 150ms;\n}\n\n.hint-leave-active {\n  animation: fade 150ms reverse;\n}\n\n@keyframes fade {\n  0% {\n    opacity: 0;\n  }\n\n  100% {\n    opacity: 1;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Calendar/Calendar-Day.vue",
    "content": "<script>\nimport FlowRunMenu from '@/pages/Calendar/RunMenu'\nimport { mapGetters } from 'vuex'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport ExternalLink from '@/components/ExternalLink'\n\nexport default {\n  components: {\n    FlowRunMenu,\n    ExternalLink\n  },\n  filters: {},\n  mixins: [formatTime],\n  props: {\n    calendarInterval: {\n      required: true,\n      type: Number\n    },\n    date: {\n      required: true,\n      type: String\n    },\n    flowId: {\n      required: true,\n      type: String\n    },\n    type: {\n      required: true,\n      type: String\n    }\n  },\n  data() {\n    return {\n      skip: false,\n      loadingKey: 0,\n      flowRunEvents: [],\n      selectedEvent: null,\n      selectedOpen: false,\n      selectedElement: null,\n      upcoming: null,\n      scheduleBanner: false,\n      closeBanner: false,\n      timeout: null\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['connected', 'isCloud']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['timezone']),\n    intervalCount() {\n      return (60 / this.calendarInterval) * 24\n    },\n    intervalHeight() {\n      return this.type === 'day'\n        ? this.flowRunEvents.length < 100\n          ? 100\n          : this.flowRunEvents.length > 1500\n          ? this.flowRunEvents.length / 2\n          : this.flowRunEvents.length\n        : 100\n    },\n    start() {\n      let days = 1\n      const start =\n        this.tzOffset(this.date) < 0\n          ? this.subtractDay(this.date, days)\n          : this.date\n      return start\n    },\n    end() {\n      let days = 1\n      switch (this.type) {\n        case '4day':\n          days = this.tzOffset(this.date) > 0 ? 5 : 4\n          break\n        case 'day':\n          days = this.tzOffset(this.date) > 0 ? 2 : 1\n          break\n      }\n      return this.addDay(this.date, days)\n    }\n  },\n  watch: {\n    async tenant() {\n      this.selectedEvent = null\n      this.flowRunEvents = []\n      await this.flowRunEventsList()\n    },\n    async backend() {\n      this.selectedEvent = null\n      this.flowRunEvents = []\n      await this.flowRunEventsList()\n    },\n    async date() {\n      this.selectedEvent = null\n      this.flowRunEvents = []\n      await this.flowRunEventsList()\n    },\n    async flowId() {\n      this.selectedEvent = null\n      this.flowRunEvents = []\n      await this.flowRunEventsList()\n    }\n  },\n  async created() {\n    await this.flowRunEventsList()\n    this.scrollToElement()\n  },\n  methods: {\n    async flowRunEventsList() {\n      this.$emit('loading', true)\n      const queryVariables = {\n        startTime: this.start,\n        endTime: this.end,\n        flowId: this.flowId\n      }\n      Promise.all([\n        this.$apollo.query({\n          query: require('@/graphql/Calendar/calendar-day-scheduled-flow-runs.gql'),\n          variables: queryVariables,\n          loadingKey: 'loadingKey'\n        }),\n        this.$apollo.query({\n          query: require('@/graphql/Calendar/calendar-day-flow-runs.gql'),\n          variables: queryVariables,\n          loadingKey: 'loadingKey'\n        }),\n        this.$apollo.query({\n          query: require('@/graphql/Calendar/calendar-day-running-flow-runs.gql'),\n          variables: queryVariables,\n          loadingKey: 'loadingKey'\n        }),\n        this.$apollo.query({\n          query: require('@/graphql/Calendar/calendar-day-ongoing-flow-runs.gql'),\n          variables: {\n            startTime: this.start,\n            endTime: this.date,\n            flowId: this.flowId\n          },\n          loadingKey: 'loadingKey'\n        })\n      ]).then(runs => {\n        this.upcoming = runs[0]?.data?.flow_run?.length\n        const allRuns = [\n          ...(runs[0]?.data?.flow_run || []),\n          ...(runs[1]?.data?.flow_run || []),\n          ...(runs[2]?.data?.flow_run || []),\n          ...(runs[3]?.data?.flow_run || [])\n        ]\n        const uniqueRuns = [...new Set(allRuns)]\n        const updatedRuns = uniqueRuns.map(flowRun => {\n          const diff = new Date(flowRun.end_time) - new Date(flowRun.start_time)\n          const addedTime = this.addTime(flowRun.start_time, 3, 'm')\n\n          flowRun.start = !flowRun.start_time\n            ? this.formatCalendarTime(flowRun.scheduled_start_time)\n            : this.formatCalendarTime(flowRun.start_time)\n\n          flowRun.end =\n            flowRun.start_time && !flowRun.end_time\n              ? this.formatCalendarTime(new Date())\n              : diff < 60000\n              ? addedTime\n              : flowRun.start_time < this.date &&\n                flowRun.end_time?.split('T')[0] > this.date\n              ? this.formatCalendarTime(new Date())\n              : this.formatCalendarTime(flowRun.end_time)\n\n          flowRun.timed =\n            flowRun.start_time < this.date\n              ? !flowRun.end_time\n                ? false\n                : flowRun.end_time.split('T')[0] > this.date\n                ? false\n                : true\n              : true\n\n          flowRun.category = flowRun.flow_id\n          return flowRun\n        })\n        this.flowRunEvents = updatedRuns\n        this.$emit('loading', false)\n        this.showScheduleBanner()\n      })\n    },\n    showScheduleBanner() {\n      if (this.closeBanner || !this.isCloud) {\n        this.scheduleBanner = false\n      } else if (this.flow?.is_schedule_active && this.upcoming > 8) {\n        this.scheduleBanner = true\n      } else {\n        this.scheduleBanner = new Date(this.date) > new Date()\n      }\n    },\n    eventColor(event) {\n      return event.state ? event.state : 'primary'\n    },\n    striped(event) {\n      return event.state === 'Scheduled'\n        ? 'striped'\n        : event.state === 'Submitted'\n        ? 'darker'\n        : ''\n    },\n    handleEventClick(item, event) {\n      clearTimeout(this.timeout)\n      const open = () => {\n        this.selectedEvent = item\n        this.selectedElement = event.target\n        this.selectedOpen = true\n      }\n      if (this.selectedOpen) {\n        this.selectedOpen = false\n        this.timeout = setTimeout(open, 10)\n      } else {\n        open()\n      }\n    },\n    handleScheduleBanner() {\n      this.scheduleBanner = false\n      this.closeBanner = true\n    },\n    timeNow(time) {\n      return time.split(':')[0] == this.getHour(new Date()) - 2\n        ? 'scroll-here'\n        : null\n    },\n    scrollToElement() {\n      const el = this.$el.getElementsByClassName('scroll-here')[0]\n      if (el) {\n        el.scrollIntoView()\n      }\n    }\n  },\n  apollo: {\n    flow: {\n      query: require('@/graphql/Calendar/calendar-flows.gql'),\n      variables() {\n        return {\n          id: this.flowId\n        }\n      },\n      skip() {\n        return this.skip\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.flow_by_pk\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet v-if=\"connected\" height=\"100vh\" class=\"sheet-tweaks\">\n    <v-snackbar\n      v-model=\"scheduleBanner\"\n      top\n      app\n      :icon=\"$vuetify.breakpoint.lgAndUp ? 'announcement' : null\"\n      custom-class=\"pt-8\"\n      color=\"amber\"\n      transition=\"slide-y-transition\"\n    >\n      <span :style=\"{ color: 'utilGrayDark' }\">\n        Reminder!\n        <ExternalLink\n          href=\"https://docs.prefect.io/orchestration/concepts/services.html#scheduler\"\n        >\n          The Prefect Scheduler\n        </ExternalLink>\n        will only schedule 10 runs in advance.</span\n      >\n      <template #action=\"{ attrs }\">\n        <v-btn v-bind=\"attrs\" text color=\"white\" @click=\"handleScheduleBanner\"\n          >Close</v-btn\n        >\n      </template>\n    </v-snackbar>\n    <v-calendar\n      ref=\"calendar\"\n      :now=\"date\"\n      :value=\"date\"\n      event-overlap-mode=\"stack\"\n      :events=\"flowRunEvents\"\n      :event-color=\"eventColor\"\n      :interval-height=\"intervalHeight\"\n      :interval-minutes=\"calendarInterval\"\n      :interval-count=\"intervalCount\"\n      :type=\"type\"\n      class=\"calendar-tweaks\"\n    >\n      <template #event=\"{event}\">\n        <div\n          :id=\"event.name\"\n          class=\"text-caption pl-2 event\"\n          :class=\"striped(event)\"\n          @click.self=\"handleEventClick(event, $event)\"\n        >\n          {{ event.name }} {{ calEventTime(event.start_time, date) }}\n          -\n          {{ calEventTime(event.end_time, date) }}\n        </div>\n      </template>\n      <template #interval=\"{time}\">\n        <div :class=\"timeNow(time)\" />\n      </template>\n    </v-calendar>\n\n    <v-menu\n      :value=\"selectedOpen\"\n      content-class=\"menu-tweaks\"\n      :attach=\"selectedElement\"\n      offset-x\n      max-width=\"50vW\"\n      :close-on-content-click=\"false\"\n    >\n      <FlowRunMenu\n        v-if=\"selectedEvent\"\n        :run=\"selectedEvent\"\n        :active=\"flow.is_schedule_active\"\n        type=\"flow-run\"\n      />\n    </v-menu>\n  </v-sheet>\n</template>\n\n<style lang=\"scss\">\n.event {\n  height: 100%;\n}\n\n.striped {\n  background: repeating-linear-gradient(\n    135deg,\n    var(--v-ScheduledAlt-base),\n    var(--v-ScheduledAlt-base) 5px,\n    var(--v-Scheduled-base) 5px,\n    var(--v-Scheduled-base) 10px\n  );\n  color: #333; //true for light and dark\n}\n\n.darker {\n  color: var(--v-utilGrayDark-base);\n}\n\n.limit-width {\n  max-width: 20%;\n}\n\n/* stylelint-disable */\n\n.sheet-tweaks {\n  .theme--light {\n    background-color: var(--v-appBackground-base) !important;\n  }\n}\n.skeleton-tweak {\n  .theme--light {\n    background-color: var(--v-appBackground-base) !important;\n  }\n}\n.calendar-tweaks {\n  overflow: auto;\n\n  .theme--light {\n    background-color: var(--v-appBackground-base) !important;\n  }\n  .v-calendar-daily__intervals-body {\n    max-width: 45px !important;\n  }\n  .v-btn--fab.v-size--default {\n    height: 35px;\n    width: 30px;\n  }\n  .v-calendar-daily_head-weekday {\n    padding: 3px 0px 0px 0px;\n    font-size: 8px;\n    text-align: center;\n    text-transform: uppercase;\n  }\n\n  .v-calendar-daily__intervals-head {\n    max-width: 45px !important;\n  }\n}\n\n//Make the popover menu visible\n\n.menu-tweaks {\n  cursor: default;\n  // pointer-events: none !important;\n}\n.v-calendar .v-event {\n  overflow: visible;\n  z-index: auto;\n}\n\n.v-calendar .v-event-timed {\n  overflow: visible;\n  z-index: auto;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Calendar/Calendar-FlowFilter.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport FlowName from '@/pages/Calendar/FlowName'\n\nexport default {\n  components: {\n    FlowName\n  },\n  mixins: [formatTime],\n  props: {\n    day: {\n      type: String,\n      required: true\n    }\n  },\n  data() {\n    return {\n      filters: [{ name: 'Flows' }],\n      skip: false,\n      show: true,\n      loadingKey: 0,\n      Ids: null,\n      flowGroupIds: [],\n      timeout: null,\n      selectedFlow: 0\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['connected']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['timezone']),\n    ...mapGetters('api', ['backend']),\n    start() {\n      let days = 1\n      const start =\n        this.tzOffset(this.day) < 0\n          ? this.subtractDay(this.day, days)\n          : this.day\n      return start\n    },\n    end() {\n      let days = 1\n      switch (this.type) {\n        case '4day':\n          days = this.tzOffset(this.day) > 0 ? 5 : 4\n          break\n        case 'day':\n          days = this.tzOffset(this.day) > 0 ? 2 : 1\n          break\n      }\n      return this.addDay(this.day, days)\n    },\n    queryVariables() {\n      return {\n        startTime: this.start,\n        endTime: this.end\n      }\n    },\n    allIds() {\n      const allRuns =\n        new Date(this.day) < new Date()\n          ? [\n              ...(this.flowRuns || []),\n              ...(this.scheduledFlowRuns || []),\n              ...(this.runningFlowRuns || []),\n              ...(this.ongoingFlowRuns || []),\n              ...(this.allFlows || [])\n            ]\n          : [\n              ...(this.flowRuns || []),\n              ...(this.scheduledFlowRuns || []),\n              ...(this.allFlows || [])\n            ]\n      const runs = allRuns.reduce((accum, run) => {\n        if (!run.flow_id && !run.flows) {\n          return accum\n        }\n        if (run.flow_id) {\n          if (this.selectFlow && this.selectFlow[0] === run.flow_id)\n            return accum\n          if (!accum[run.flow_id]) {\n            accum[run.flow_id] = {\n              active: true,\n              id: run.flow_id\n            }\n          }\n        }\n        if (run.flows && run.flows[0]) {\n          let flow = run.flows[0]\n          let flowId = run.flows[0]?.id\n          if (this.selectFlow && this.selectFlow[0] === flowId) return accum\n          if (!accum[flowId]) {\n            accum[flowId] = {\n              name: flow.name,\n              active: false,\n              id: flowId,\n              version: flow.version,\n              fgId: run.id\n            }\n          } else {\n            accum[flowId].name = flow.name\n            accum[flowId].version = flow.version\n            accum[flowId].fgId = run.id\n          }\n        }\n        return accum\n      }, {})\n      let entries = Object.entries(runs)\n      const ordered = entries.sort((a, b) =>\n        a[1].active\n          ? -1\n          : b[1].active\n          ? 1\n          : a[1].name > b[1].name\n          ? 1\n          : b[1].name > a[1].name\n          ? -1\n          : 0\n      )\n      if (this.selectFlow) ordered.unshift(this.selectFlow)\n      return ordered\n    }\n  },\n  watch: {\n    allIds(val) {\n      if (val[0] && !this.selectFlow) this.$emit('update', this.allIds[0][0])\n    },\n    day() {\n      this.flowGroupIds = []\n      this.selectedFlow = 0\n    }\n  },\n  created() {\n    //creates a non-reactive property that isn't tracked by Vue - so that allIds does not reset\n    this.selectFlow = null\n    this.$emit('update', this.allIds[0])\n  },\n  methods: {\n    handleSelectedFlow(flow, index) {\n      this.selectedFlow = index\n      this.selectFlow = flow\n      this.$emit('update', flow[0])\n    },\n    updateFlowGroupList(flowGroupId) {\n      this.flowGroupIds.push(flowGroupId)\n    }\n  },\n  apollo: {\n    flowRuns: {\n      query: require('@/graphql/Calendar/calendar-flow-runs.gql'),\n      variables() {\n        return {\n          startTime: this.start,\n          endTime: this.end\n        }\n      },\n      skip() {\n        return this.skip\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.flow_run\n    },\n    scheduledFlowRuns: {\n      query: require('@/graphql/Calendar/calendar-scheduled-flow-runs.gql'),\n      variables() {\n        return this.queryVariables\n      },\n      skip() {\n        return this.skip\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.flow_run || []\n    },\n    runningFlowRuns: {\n      query: require('@/graphql/Calendar/calendar-running-flow-runs.gql'),\n      variables() {\n        return this.queryVariables\n      },\n      skip() {\n        return new Date(this.day) > new Date()\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.flow_run || []\n    },\n    ongoingFlowRuns: {\n      query: require('@/graphql/Calendar/calendar-ongoing-flow-runs.gql'),\n      variables() {\n        return {\n          startTime: this.start,\n          endTime: this.day\n        }\n      },\n      skip() {\n        return new Date(this.day) > new Date()\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.flow_run || []\n    },\n    allFlows: {\n      query: require('@/graphql/Calendar/calendar-flow-groups.gql'),\n      skip() {\n        return this.skip\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.flow_group\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-if=\"connected\" class=\"expansion text-center\">\n    <v-expansion-panels class=\"expansion\" flat :value=\"0\">\n      <v-expansion-panel v-for=\"(filter, index) in filters\" :key=\"index\">\n        <v-expansion-panel-header class=\" py-0\">\n          {{ filter.name }}\n        </v-expansion-panel-header>\n        <v-expansion-panel-content>\n          <v-list height=\"60vh\" class=\"pt-0\">\n            <v-progress-linear\n              :indeterminate=\"loadingKey > 0\"\n            ></v-progress-linear>\n            <v-list-item-group :value=\"selectedFlow\" color=\"primary\" mandatory>\n              <v-list-item\n                v-for=\"(item, inde) in allIds\"\n                :key=\"inde\"\n                dense\n                class=\"pl-2\"\n              >\n                <v-list-item-content\n                  class=\" pa-0\"\n                  @click=\"handleSelectedFlow(item, inde)\"\n                >\n                  <v-list-item-subtitle class=\"font-weight-light \">\n                    <FlowName\n                      v-if=\"item\"\n                      :id=\"item[0]\"\n                      :name=\"item[1].name\"\n                      :version=\"item[1].version\"\n                      left\n                      :active=\"item[1].active\"\n                      @fg=\"updateFlowGroupList\"\n                    />\n                  </v-list-item-subtitle>\n                </v-list-item-content>\n              </v-list-item>\n            </v-list-item-group>\n          </v-list>\n        </v-expansion-panel-content>\n      </v-expansion-panel>\n    </v-expansion-panels>\n  </div>\n</template>\n\n<style lang=\"scss\">\n/* stylelint-disable */\n\n.expansion > div {\n  overflow: auto;\n  background-color: var(--v-appBackground-base) !important;\n\n  .theme--light > div {\n    background-color: var(--v-appBackground-base) !important;\n  }\n\n  .theme--light.v-list {\n    background-color: var(--v-appBackground-base) !important;\n  }\n\n  .v-expansion-panel-header {\n    min-height: 20px;\n  }\n}\n\n.circular {\n  padding-top: 100px !important;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Calendar/Calendar-View.vue",
    "content": "<script>\nimport CalendarDay from '@/pages/Calendar/Calendar-Day'\nimport CalendarFlows from '@/pages/Calendar/Calendar-FlowFilter'\nimport { mapGetters } from 'vuex'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    CalendarDay,\n    CalendarFlows\n  },\n  mixins: [formatTime],\n  data() {\n    return {\n      calendarInterval: 60,\n      date: this.formatCalendarDate(new Date()),\n      loading: false,\n      refetching: false,\n      type: 'day',\n      flowId: null,\n      typeToLabel: {\n        day: 'Day',\n        '4day': '4 Days'\n      },\n      refresh: false,\n      timeout: null\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['timezone']),\n    ...mapGetters('api', ['backend', 'connected']),\n    calTitle() {\n      return this.getMonth(this.date)\n    }\n  },\n  watch: {\n    async tenant() {\n      clearTimeout(this.timeout)\n      this.refresh = true\n      this.timeout = setTimeout(() => {\n        this.refresh = false\n      }, 2000)\n      this.flowId = null\n    },\n    async backend() {\n      clearTimeout(this.timeout)\n      this.refresh = true\n      this.timeout = setTimeout(() => {\n        this.refresh = false\n      }, 3000)\n      this.flowId = null\n    }\n  },\n  methods: {\n    setToday() {\n      this.date = this.formatCalendarDate(new Date())\n    },\n    handleSelectedFlow(flow) {\n      this.flowId = flow\n    },\n    handleLoad(bool) {\n      this.loading = bool\n    },\n    prev() {\n      const day = this.subtractDay(this.date, 1)\n      this.date = this.formatCalendarDate(day)\n    },\n    next() {\n      const day = this.addDay(this.date, 1)\n      this.date = this.formatCalendarDate(day)\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-if=\"!refresh\" class=\"mt-6 ma-2 pl-0 pt-0\">\n    <v-row>\n      <v-col class=\"pa-0\" cols=\"12\" md=\"3\" lg=\"2\">\n        <v-date-picker\n          v-model=\"date\"\n          no-title\n          class=\"small-picker pl-0\"\n          flat\n          width=\"100%\"\n          height=\"200px\"\n        ></v-date-picker>\n        <CalendarFlows :day=\"date\" @update=\"handleSelectedFlow\" />\n      </v-col>\n      <v-col class=\"pa-0\" cols=\"12\" md=\"9\" lg=\"10\">\n        <v-toolbar flat color=\"appBackground\" class=\"pa-0 tbar\">\n          <v-row>\n            <v-col cols=\"12\" sm=\"4\">\n              <v-btn\n                outlined\n                class=\"mx-4\"\n                color=\"utilGrayMid\"\n                @click=\"setToday\"\n              >\n                Today\n              </v-btn>\n              <v-btn\n                v-if=\"$vuetify.breakpoint.smAndUp\"\n                fab\n                text\n                small\n                color=\"utilGrayMid\"\n                @click=\"prev\"\n              >\n                <v-icon>\n                  chevron_left\n                </v-icon>\n              </v-btn>\n              <v-btn\n                v-if=\"$vuetify.breakpoint.smAndUp\"\n                fab\n                text\n                small\n                color=\"utilGrayMid\"\n                @click=\"next\"\n              >\n                <v-icon>\n                  chevron_right\n                </v-icon>\n              </v-btn>\n            </v-col>\n            <v-col\n              v-if=\"$vuetify.breakpoint.smAndUp\"\n              cols=\"4\"\n              class=\"text-center mt-2\"\n            >\n              <v-toolbar-title>\n                {{ calTitle }}\n              </v-toolbar-title>\n            </v-col>\n            <v-col cols=\"6\" sm=\"4\" class=\"text-right\">\n              <v-menu bottom right>\n                <template #activator=\"{ on, attrs }\">\n                  <v-btn\n                    outlined\n                    color=\"utilGrayMid\"\n                    class=\"mr-4\"\n                    v-bind=\"attrs\"\n                    v-on=\"on\"\n                  >\n                    <span>{{ typeToLabel[type] }}</span>\n                    <v-icon right>\n                      expand_more\n                    </v-icon>\n                  </v-btn>\n                </template>\n                <v-list>\n                  <v-list-item @click=\"type = 'day'\">\n                    <v-list-item-title>Day</v-list-item-title>\n                  </v-list-item>\n                  <v-list-item @click=\"type = '4day'\">\n                    <v-list-item-title>4 Days</v-list-item-title>\n                  </v-list-item>\n                </v-list>\n              </v-menu>\n            </v-col>\n            <v-progress-linear\n              absolute\n              bottom\n              :active=\"loading\"\n              :indeterminate=\"loading\"\n              color=\"primary\"\n            ></v-progress-linear>\n          </v-row>\n        </v-toolbar>\n\n        <CalendarDay\n          v-if=\"flowId\"\n          :date=\"date\"\n          :type=\"type\"\n          :flow-id=\"flowId\"\n          :calendar-interval=\"calendarInterval\"\n          @loading=\"handleLoad\"\n        />\n      </v-col>\n    </v-row>\n  </div>\n</template>\n\n<style lang=\"scss\">\n/* stylelint-disable */\n.tbar {\n  max-height: 50px;\n  .v-toolbar__content {\n    max-height: 50px;\n  }\n}\n\n.small-picker {\n  .v-date-picker-table--date .v-btn {\n    height: 25px;\n    width: 25px;\n  }\n\n  .v-date-picker-years {\n    width: 250px;\n  }\n\n  .v-date-picker-table {\n    max-height: 200px;\n  }\n\n  .v-date-picker-header__value button {\n    padding: 0;\n  }\n\n  .v-btn:not(.v-btn--flat):not(.v-btn--text):not(.v-btn--outlined) {\n    background-color: none !important;\n  }\n\n  .v-btn:before {\n    background-color: var(--v-appBackground-base);\n  }\n\n  .theme--light {\n    background: var(--v-appBackground-base);\n  }\n\n  .v-date-picker-table--month td {\n    height: 30px;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Calendar/FlowName.vue",
    "content": "<script>\nexport default {\n  props: {\n    id: {\n      type: String,\n      required: true\n    },\n    left: {\n      type: Boolean\n    },\n    active: {\n      type: Boolean,\n      required: false,\n      default: false\n    },\n    truncate: {\n      type: Boolean,\n      required: false,\n      default: true\n    },\n    name: {\n      type: String,\n      required: false,\n      default: null\n    },\n    version: {\n      type: Number,\n      required: false,\n      default: null\n    }\n  },\n  data() {\n    return {\n      loadingKey: 0\n    }\n  },\n  computed: {\n    includeVersion() {\n      return !this.name ? `(Version ${this.version || this.flow?.version})` : ''\n    },\n    flowDetails() {\n      const name = this.name ? `${this.name}` : `${this.flow?.name}`\n      const active = this.active ? '' : '- no current runs'\n      return `${name} ${this.includeVersion} ${active}`\n    },\n    flowNameText() {\n      const name = this.name ? `${this.name}` : `${this.flow?.name}`\n      return `${name} ${this.includeVersion}`\n    },\n    textAlign() {\n      if (this.left) return 'text-left'\n      return 'text-center'\n    }\n  },\n  methods: {\n    addDot(state) {\n      if (this.active) {\n        return {\n          'border-radius': '50%',\n          display: 'inline-block',\n          'background-color': `var(--v-${state}-base)`,\n          height: '5px',\n          width: '5px',\n          'margin-right': '3px'\n        }\n      } else {\n        return {\n          'margin-right': '8px'\n        }\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flow.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flow: {\n      query: require('@/graphql/Flow/flow-by-pk.gql'),\n      variables() {\n        return {\n          flowId: this.id\n        }\n      },\n      skip() {\n        return this.name\n      },\n      loadingKey: 'loadingKey',\n      pollInterval: 500000,\n      update: data => data.flow_by_pk\n    }\n  }\n}\n</script>\n\n<template>\n  <span\n    v-if=\"loadingKey < 1\"\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"text-caption max-width\"\n    :class=\"[textAlign]\"\n  >\n    <truncate v-if=\"truncate\" :content=\"flowDetails\">\n      <span :style=\"addDot('primary')\"></span>\n      {{ flowNameText }}\n    </truncate>\n    <span v-else> {{ flowNameText }} </span>\n  </span>\n</template>\n\n<style lang=\"scss\" scoped>\ndiv >>> div {\n  background-color: var(--v-appBackground-base);\n}\n</style>\n"
  },
  {
    "path": "src/pages/Calendar/RunMenu.vue",
    "content": "<script>\nimport DurationSpan from '@/components/DurationSpan'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport FlowName from '@/pages/Calendar/FlowName'\nimport ExternalLink from '@/components/ExternalLink'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    DurationSpan,\n    FlowName,\n    ExternalLink\n  },\n  mixins: [formatTime],\n  props: {\n    run: { type: Object, required: false, default: () => {} },\n    type: { type: String, required: false, default: 'task-run' },\n    active: { type: Boolean, required: true }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    showScheduleBanner() {\n      return this.run.state === 'Scheduled' && this.active && this.isCloud\n    }\n  },\n  methods: {\n    statusStyle(state) {\n      return {\n        'border-radius': '50%',\n        display: 'inline-block',\n        'background-color': `var(--v-${state}-base)`,\n        height: '1rem',\n        width: '1rem'\n      }\n    }\n  },\n  apollo: {}\n}\n</script>\n\n<template>\n  <v-card tile class=\"pointer\">\n    <v-alert\n      v-if=\"showScheduleBanner\"\n      class=\"mx-2 mt-2 mb-0 text-caption radius\"\n      type=\"warning\"\n      icon=\"announcement\"\n      dense\n    >\n      Reminder!\n      <ExternalLink\n        href=\"https://docs.prefect.io/orchestration/concepts/services.html#scheduler\"\n      >\n        The Prefect Scheduler\n      </ExternalLink>\n      will only schedule 10 runs in advance.\n    </v-alert>\n    <v-card-title class=\"text-subtitle-1 pt-2\">\n      <router-link :to=\"{ name: type, params: { id: run.id } }\" target=\"_blank\">\n        {{ run.name ? run.name : run.task_name }}\n        {{ run.map_index > -1 ? `(${run.map_index})` : '' }}\n      </router-link>\n      <v-icon x-small>\n        open_in_new\n      </v-icon>\n    </v-card-title>\n    <v-card-subtitle v-if=\"type === 'flow-run'\">\n      <FlowName :id=\"run.flow_id\" left :truncate=\"false\" />\n    </v-card-subtitle>\n    <v-card-text>\n      <div>\n        State:\n        <span :style=\"statusStyle(run.state)\"></span>\n        <span class=\"font-weight-bold\"> {{ run.state }}</span>\n      </div>\n      <div v-if=\"run.start_time\" class=\"subtitle\">\n        Duration:\n        <DurationSpan\n          class=\"font-weight-bold\"\n          :start-time=\"run.start_time\"\n          :end-time=\"run.end_time\"\n        />\n      </div>\n      <div v-if=\"run.start_time\" class=\"subtitle\">\n        Start:\n        <span class=\"font-weight-bold\">\n          {{ formatTime(run.start_time) }}\n        </span>\n      </div>\n      <div v-if=\"run.end_time\" class=\"subtitle \">\n        End:\n        <span class=\"font-weight-bold\">\n          {{ formatTime(run.end_time) }}\n        </span>\n      </div>\n      <div v-if=\"run.state_timestamp\" class=\"subtitle\">\n        Updated:\n        <span class=\"font-weight-bold\">\n          {{ formatTime(run.state_timestamp) }}\n        </span>\n      </div>\n\n      <div v-if=\"run.max_retries\" class=\"subtitle\">\n        Max Retries:\n        <span class=\"font-weight-bold\">\n          {{ run.max_retries || 0 }}\n        </span>\n      </div>\n      <div v-if=\"run.retry_delay\" class=\"subtitle\">\n        Retry delay:\n        <span class=\"font-weight-bold\">\n          {{ run.retry_delay || 0 }}\n        </span>\n      </div>\n      <v-divider v-if=\"run.state_message\" class=\"my-2\" />\n      <div v-if=\"run.state_message\">\n        <div class=\"text-subtitle\">Message:</div>\n        <div class=\"font-weight-bold\">\n          {{ run.state_message || 'No message' }}\n        </div>\n      </div>\n      <v-divider v-if=\"run.state_result\" class=\"my-2\" />\n      <div v-if=\"run.state_result\" class=\"text-subtitle-1\">\n        <div>Result:</div>\n        <div class=\"font-weight-bold\">\n          {{ run.state_result || 'No result' }}\n        </div>\n      </div>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style scoped>\n.pointer {\n  cursor: default;\n}\n\n.v-card > .radius {\n  border-radius: 4px !important;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/Agents-Tile.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nimport CardTitle from '@/components/Card-Title'\nimport moment from '@/utils/moment'\nimport ExternalLink from '@/components/ExternalLink'\n\nexport default {\n  components: {\n    CardTitle,\n    ExternalLink\n  },\n  data() {\n    return {\n      unsubscribeAgents: () => {}\n    }\n  },\n  computed: {\n    ...mapGetters('agent', ['staleThreshold', 'unhealthyThreshold', 'agents']),\n    ...mapGetters('api', ['isCloud']),\n    agentTracker() {\n      return this.agents?.reduce(\n        (tracker, agent) => {\n          const secondsSinceLastQuery = moment().diff(\n            moment(agent.last_queried),\n            'seconds'\n          )\n\n          if (secondsSinceLastQuery < 60 * this.staleThreshold) {\n            tracker.healthy++\n          } else if (secondsSinceLastQuery < 60 * this.unhealthyThreshold) {\n            tracker.stale++\n          } else {\n            tracker.unhealthy++\n          }\n\n          return tracker\n        },\n        {\n          healthy: 0,\n          stale: 0,\n          unhealthy: 0\n        }\n      )\n    },\n    cardTitle() {\n      if (!this.agents) return\n      if (this.agents && this.agents.length === 0) return '0 agents'\n\n      return `${this.agents?.length} ${\n        this.agents?.length === 1 ? 'agent' : 'agents'\n      }`\n    },\n    statusColor() {\n      if (!this.agents) return 'secondaryGray'\n      if (\n        this.agents?.length === 0 ||\n        (this.agentTracker?.healthy === 0 &&\n          this.agentTracker?.stale === 0 &&\n          this.agentTracker?.unhealthy > 0)\n      )\n        return 'error'\n\n      if (this.agentTracker?.stale > 0 || this.agentTracker?.unhealthy > 0) {\n        return 'warning'\n      }\n\n      return 'success'\n    }\n  },\n  beforeDestroy() {\n    this.unsubscribeAgents()\n  },\n  methods: {\n    async onIntersect([entry]) {\n      if (entry.isIntersecting) {\n        this.unsubscribeAgents = await this.$store.dispatch(\n          'polling/subscribe',\n          'agents'\n        )\n      } else {\n        this.unsubscribeAgents()\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"py-2 position-relative d-flex flex-column\"\n    style=\"height: 100%;\"\n    tile\n  >\n    <v-system-bar :color=\"statusColor\" :height=\"5\" absolute>\n      <!-- We should include a state icon here when we've got those -->\n      <!-- <v-icon>{{ flow.flow_runs[0].state }}</v-icon> -->\n    </v-system-bar>\n\n    <CardTitle\n      :title=\"cardTitle\"\n      icon=\"pi-agent\"\n      :icon-color=\"statusColor\"\n      icon-class=\"mb-1\"\n      :loading=\"!agents\"\n      :data-cy=\"\n        'agents-tile-healthy-count|' + (agentTracker ? agentTracker.healthy : 0)\n      \"\n    />\n\n    <v-list class=\"card-content\">\n      <v-slide-y-reverse-transition v-if=\"!agents\" leave-absolute group>\n        <v-skeleton-loader key=\"loading\" type=\"list-item-avatar\">\n        </v-skeleton-loader>\n      </v-slide-y-reverse-transition>\n\n      <v-slide-y-reverse-transition v-else leave-absolute group>\n        <v-list-item\n          v-if=\"agents && agents.length === 0\"\n          key=\"no-agents\"\n          color=\"grey\"\n        >\n          <v-list-item-avatar class=\"mr-0\">\n            <v-icon class=\"error--text mb-1\">\n              error\n            </v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content class=\"my-0 py-3\">\n            <div\n              class=\" text-subtitle-1 font-weight-light\"\n              style=\"line-height: 1.25rem;\"\n            >\n              You do not have any agents querying for flow runs. Without an\n              agent, your flow runs will not be picked up.</div\n            >\n            <div\n              class=\" text-subtitle-1 font-weight-light pt-4\"\n              style=\"line-height: 1.25rem;\"\n              >See\n              <ExternalLink\n                href=\"https://docs.prefect.io/orchestration/agents/overview.html\"\n                >the Prefect docs</ExternalLink\n              >\n              for more information on agents.</div\n            >\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          v-if=\"agentTracker && agentTracker.healthy > 0\"\n          key=\"healthy-agents\"\n          color=\"grey\"\n        >\n          <v-list-item-avatar class=\"mr-0\">\n            <v-icon class=\"green--text\">\n              check\n            </v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content class=\"my-0 py-3\">\n            <div\n              class=\" text-subtitle-1 font-weight-light\"\n              style=\"line-height: 1.25rem;\"\n            >\n              <span class=\"font-weight-medium\">{{ agentTracker.healthy }}</span>\n              agent{{ agentTracker.healthy === 1 ? '' : 's' }}\n              {{ agentTracker.healthy === 1 ? 'is' : 'are' }} querying for flow\n              runs\n            </div>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          v-if=\"agentTracker && agentTracker.stale > 0\"\n          key=\"stale-agents\"\n          color=\"grey\"\n        >\n          <v-list-item-avatar class=\"mr-0\">\n            <v-icon class=\"warning--text mb-1\">\n              warning\n            </v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content class=\"my-0 py-3\">\n            <div\n              class=\"text-subtitle-1 font-weight-light\"\n              style=\"line-height: 1.25rem;\"\n            >\n              <span class=\"font-weight-medium\">{{ agentTracker.stale }}</span>\n              agent{{ agentTracker.stale === 1 ? '' : 's' }}\n              {{ agentTracker.stale === 1 ? 'has' : 'have' }}\n              not queried for flow runs in the last\n              {{\n                staleThreshold === 1 ? 'minute' : `${staleThreshold} minutes`\n              }}.\n            </div>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          v-if=\"agentTracker && agentTracker.unhealthy > 0\"\n          key=\"unhealthy-agents\"\n          color=\"grey\"\n        >\n          <v-list-item-avatar class=\"mr-0\">\n            <v-icon class=\"error--text mb-1\">\n              error\n            </v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content class=\"my-0 py-3\">\n            <div\n              class=\"text-subtitle-1 font-weight-light\"\n              style=\"line-height: 1.25rem;\"\n            >\n              <span>\n                <span class=\"font-weight-medium\">\n                  {{ agentTracker.unhealthy }}\n                </span>\n                agent{{ agentTracker.unhealthy === 1 ? '' : 's' }}\n                {{ agentTracker.unhealthy === 1 ? 'has' : 'have' }}\n                not queried for flow runs in the last\n                {{\n                  unhealthyThreshold === 1\n                    ? 'minute'\n                    : `${unhealthyThreshold / 60} hours`\n                }}.\n              </span>\n            </div>\n            <div\n              v-if=\"agentTracker && agentTracker.healthy < 1\"\n              class=\" text-subtitle-1 font-weight-light pt-4\"\n              style=\"line-height: 1.25rem;\"\n              >See\n              <ExternalLink\n                href=\"https://docs.prefect.io/orchestration/agents/overview.html\"\n                >the Prefect docs</ExternalLink\n              >\n              for more information on agents.</div\n            >\n          </v-list-item-content>\n        </v-list-item>\n      </v-slide-y-reverse-transition>\n    </v-list>\n\n    <v-spacer />\n\n    <v-card-actions class=\"py-0\">\n      <v-spacer />\n      <v-btn small color=\"primary\" text @click=\"$emit('view-details-clicked')\">\n        View details\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.bottom-right {\n  bottom: 0;\n  right: 0;\n}\n\n.card-content {\n  height: 100%;\n  max-height: 210px;\n  overflow-y: auto;\n}\n\n.time-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n\na {\n  text-decoration: none !important;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/ApiHealthCheck-Tile.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport CardTitle from '@/components/Card-Title'\n\nexport default {\n  components: {\n    CardTitle\n  },\n  data() {\n    return {}\n  },\n  computed: {\n    ...mapGetters('api', [\n      'connected',\n      'connecting',\n      'backend',\n      'connectionMessage',\n      'url'\n    ]),\n    cardColor() {\n      if (this.connected) return 'Success'\n      if (this.connecting) return 'grey'\n      return 'Failed'\n    },\n    cardIcon() {\n      if (this.connected) return 'signal_cellular_4_bar'\n      if (this.connecting) return 'signal_cellular_connected_no_internet_4_bar'\n      return 'signal_cellular_off'\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card tile class=\"py-2 position-relative\">\n    <v-system-bar :height=\"5\" absolute :color=\"cardColor\" />\n    <CardTitle :loading=\"connecting\" :icon=\"cardIcon\" :icon-color=\"cardColor\">\n      <v-row slot=\"title\" no-gutters class=\"d-flex align-center justify-start\">\n        <div>API Status</div>\n        <a\n          v-if=\"!connected\"\n          class=\"ml-3\"\n          href=\"https://docs.prefect.io/core/concepts/configuration.html#environment-variables\"\n          target=\"_blank\"\n        >\n          <v-tooltip top>\n            <template #activator=\"{ on }\">\n              <v-icon color=\"grey darken-1\" v-on=\"on\">info</v-icon>\n            </template>\n            <span>\n              <div>This is the most recent message:</div>\n              <div class=\"my-4 font-italic font-weight-medium\">\n                {{ connectionMessage }}\n              </div>\n              <div>\n                Did you set the\n                <span class=\"font-weight-bold\">graphql_url</span> variable in\n                <span class=\"font-weight-bold\">~/.prefect/config.toml</span>\n                correctly before starting Prefect Server?\n              </div>\n              <div>\n                Click this icon to read more about configuring Prefect.\n              </div>\n            </span>\n          </v-tooltip>\n        </a>\n      </v-row>\n    </CardTitle>\n    <v-list dense>\n      <v-list-item>\n        <v-list-item-avatar class=\"mr-0\">\n          <v-progress-circular\n            v-if=\"connecting\"\n            indeterminate\n            :size=\"15\"\n            :width=\"2\"\n            color=\"primary\"\n          />\n          <v-icon v-else-if=\"!connected\" class=\"Failed--text\">\n            priority_high\n          </v-icon>\n          <v-icon v-else class=\"Success--text\">\n            check\n          </v-icon>\n        </v-list-item-avatar>\n        <v-list-item-content>\n          <div\n            class=\"text-subtitle-1 font-weight-light\"\n            style=\"line-height: 1.25rem;\"\n          >\n            <span v-if=\"connected\">Connected</span>\n            <span v-else-if=\"connecting\">Attempting to connect...</span>\n            <span v-else>Couldn't connect</span>\n          </div>\n          <div class=\"font-weight-medium\">\n            {{ url }}\n          </div>\n        </v-list-item-content>\n      </v-list-item>\n    </v-list>\n  </v-card>\n</template>\n"
  },
  {
    "path": "src/pages/Dashboard/Automations/AddAction.vue",
    "content": "<script>\nimport { actionTypes, jsonPlacehold } from '@/utils/automations'\nimport { mapGetters } from 'vuex'\nimport ListInput from '@/components/CustomInputs/ListInput'\nimport JsonInput from '@/components/CustomInputs/JsonInput2'\nimport { formatJson, isValidJson } from '@/utils/json'\n\nexport default {\n  components: {\n    ListInput,\n    JsonInput\n  },\n  props: {\n    eventType: {\n      type: String,\n      required: false,\n      default: ''\n    }\n  },\n  data() {\n    return {\n      jsonPlacehold: jsonPlacehold.jsonBlob,\n      steps: {\n        selectActionType: { name: 'selectActionType', complete: false },\n        openMessageText: { name: 'openMessageText', complete: false },\n        openToConfig: { name: 'openToConfig', complete: false },\n        addTwilioConfig: { name: 'addTwilioConfig', complete: false },\n        addMSTeamsConfig: { name: 'addMSTeamsConfig', complete: false },\n        addName: { name: 'addName', complete: false }\n      },\n      saving: false,\n      enableSave: false,\n      actionType: { title: 'Send' },\n      step: null,\n      actionConfig: null,\n      actionConfigArray: [],\n      messageName: 'message',\n      secretName: '',\n      messageText: '',\n      openTwilioConfig: false,\n      newSaveAs: '',\n      authToken: '',\n      accountSid: '',\n      apiToken: '',\n      jsonPayload: null,\n      routingKey: '',\n      webhookURLString: null,\n      severity: '',\n      severityLevels: [\n        { text: 'Info', value: 'info' },\n        { text: 'Warning', value: 'warning' },\n        { text: 'Error', value: 'error' },\n        { text: 'Critical', value: 'critical' }\n      ],\n      messagingService: '',\n      menu: false,\n      errorMessage: '',\n      rules: {\n        SLACK_WEBHOOK: () => true,\n        PAGERDUTY: () => true,\n        MS_TEAMS: () => true,\n        WEBHOOK: () => true,\n        EMAIL: val => {\n          const pattern = /^(([^<>()[\\]\\\\.,;:\\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          if (!val) return 'Email is required.'\n          if (!Array.isArray(val))\n            return pattern.test(val.trim()) || 'Invalid e-mail.'\n          return (\n            val.every(email => pattern.test(email.trim())) || 'Invalid e-mail.'\n          )\n        },\n        TWILIO: val => {\n          const pattern = /^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$/\n          if (!val) return 'Phone number is required.'\n          else if (!Array.isArray(val)) {\n            return (\n              pattern.text(val.trim()) || 'Entries must be a valid phone number'\n            )\n          } else {\n            const check =\n              val.every(item => pattern.test(item.trim())) ||\n              'Entries must be a valid phone number'\n            return check\n          }\n        },\n        required: val => !!val || 'Required',\n        requiredCombo: val =>\n          (!!val && val.length > 0) || 'At least one number is required',\n        url: val => {\n          const pattern = /[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/\n          return pattern.test(val) || 'Invalid URL.'\n        }\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('user', ['user']),\n    messageConfigLabel() {\n      return this.actionType?.type === 'EMAIL'\n        ? 'Email address(es)'\n        : this.actionType?.type === 'WEBHOOK'\n        ? 'Web address'\n        : this.actionType?.type === 'TWILIO'\n        ? 'Twilio Phone Numbers'\n        : this.actionType?.type === 'SLACK_WEBHOOK'\n        ? 'Slack Webhook Secret Name'\n        : 'config details'\n    },\n    messagePlaceholder() {\n      let messageText\n      switch (this.eventType) {\n        case 'CHANGES_STATE':\n          messageText =\n            'Run {flow_run_name} of flow {flow_name} entered state {state} with message {state_message}. See {flow_run_link} for more details.'\n          break\n        case 'SCHEDULED_NOT_STARTED':\n          messageText =\n            'Run {flow_run_name} ({flow_run_id}) of flow {flow_name} failed {kind} SLA {flow_sla_config_id} after {duration_seconds} seconds. See {flow_run_link} for more details.'\n          break\n        case 'STARTED_NOT_FINISHED':\n          messageText =\n            'Run {flow_run_name} ({flow_run_id}) of flow {flow_name} failed {kind} SLA {flow_sla_config_id} after {duration_seconds} seconds. See {flow_run_link} for more details.'\n          break\n        case 'AGENT':\n          messageText =\n            'Agents sharing the config {agent_config_id} have failed the minimum healthy count of {sla_min_healthy}. The following agents are unhealthy: {agent_ids}'\n          break\n        default:\n          'You have a notification from Prefect Cloud'\n      }\n      return messageText\n    },\n    messageConfigRules() {\n      return []\n    },\n    disableNext() {\n      if (this.step.name === 'openToConfig') {\n        if (this.isPagerDuty && this.routingKey && this.severity) return false\n        if (!this.actionConfigArray.length) return true\n        else return false\n      } else {\n        if (this.jsonPayload && !this.validJson) return true\n        if (this.step.name === 'addTwilioConfig') {\n          if (!!this.authToken && !!this.messagingService && !!this.accountSid)\n            return false\n          return true\n        }\n        return false\n      }\n    },\n    allowSave() {\n      const type = this.actionType.type\n      const allow = this.isPagerDuty\n        ? !!this.actionType && !!this.routingKey && !!this.severity\n        : this.isTwilio\n        ? !!this.actionConfigArray &&\n          !!this.authToken &&\n          !!this.messagingService &&\n          this.accountSid\n        : this.isMSTeams\n        ? !!this.webhookURLString\n        : this.isWebhook\n        ? !!this.webhookURLString\n        : !!this.actionType &&\n          (!!this.secretName ||\n            (!!this.actionConfigArray.length &&\n              this.actionConfigArray.filter(\n                item => this.rules[type](item) !== true\n              ).length < 1))\n      return allow && this.step.name === 'addName'\n    },\n    saveAs: {\n      get() {\n        const whoTo = this.actionConfigArray.length\n          ? this.actionConfigArray\n          : this.secretName || this.webhookURLString || this.apiToken\n        return `${this.actionType.verb} ${whoTo}`\n      },\n      set(x) {\n        this.newSaveAs = x\n      }\n    },\n    to() {\n      const configTo =\n        this.actionConfigArray.length > 0\n          ? `to ${this.actionConfigArray.toString()}`\n          : this.secretName\n          ? `to ${this.secretName}`\n          : ''\n      const config =\n        !this.isTwilio && this.actionType?.config?.to\n          ? `to ${this.actionType?.config?.to}`\n          : this.isTwilio && this.actionType?.config?.to.length\n          ? this.actionType?.config?.to.toString()\n          : false\n      return this.actionType?.type === 'EMAIL'\n        ? configTo || config || 'to this email address.'\n        : this.actionType.type === 'WEBHOOK'\n        ? config || 'to this web address.'\n        : this.actionType?.type === 'TWILIO'\n        ? configTo || config || 'to this phone number'\n        : this.actionType?.type === 'SLACK_WEBHOOK'\n        ? configTo || config || 'here.'\n        : this.actionType.type === 'PAGERDUTY'\n        ? 'using this config.'\n        : this.actionType.type === 'MS_TEAMS'\n        ? 'using this config.'\n        : 'to who?'\n    },\n    isTwilio() {\n      return this.actionType.type === 'TWILIO'\n    },\n    isPagerDuty() {\n      return this.actionType.type === 'PAGERDUTY'\n    },\n    isWebhook() {\n      return this.actionType.type === 'WEBHOOK'\n    },\n    isMSTeams() {\n      return this.actionType.type === 'MS_TEAMS'\n    },\n    validJson() {\n      return isValidJson(this.jsonPayload)\n    }\n    // needsNext() {\n    //   if (\n    //     this.step === 'openToConfig' &&\n    //     this.actionType.type === 'SLACK_WEBHOOK'\n    //   )\n    //     return false\n    //   switch (this.step) {\n    //     case 'openMessageText':\n    //     case 'addTwilioConfig':\n    //     case 'openToConfig':\n    //       return true\n    //     default:\n    //       return false\n    //   }\n    // }\n  },\n  created() {\n    this.step = this.steps['selectActionType']\n  },\n  methods: {\n    jsonPlaceholder() {\n      this.jsonPlacehold.message = this.messagePlaceholder\n      return formatJson(this.jsonPlacehold)\n    },\n    buttonColor(selectedStep) {\n      return this.step.name === selectedStep ? 'codePink' : 'utilGrayDark'\n    },\n    format(selectedStep, otherStep) {\n      const stepComplete = this.steps[selectedStep]\n      const otherComplete = this.steps[otherStep]\n      return this.step.name === selectedStep || this.step.name === otherStep\n        ? 'font-weight-dark'\n        : stepComplete?.complete || otherComplete?.complete\n        ? 'font-weight-light'\n        : ''\n    },\n    switchStep(selectedStep) {\n      if (this.step.name === 'openMessageText')\n        this.steps['openMessageText'].complete = true\n      this.step = this.steps[selectedStep]\n    },\n    handleNext() {\n      if (this.step.name === 'openMessageText') {\n        this.steps['openMessageText'].complete = true\n        this.switchStep('openToConfig')\n      } else if (this.step.name === 'openToConfig') {\n        if (this.actionType.type === 'TWILIO') {\n          if (this.actionConfigArray.length)\n            this.steps['openToConfig'].complete = true\n          this.switchStep('addTwilioConfig')\n        } else {\n          if (this.actionType.type === 'EMAIL' && this.actionConfigArray.length)\n            this.steps['openToConfig'].complete = true\n          else if (this.isPagerDuty && this.routingKey && this.severity) {\n            this.steps['openToConfig'].complete = true\n          }\n          this.switchStep('addName')\n        }\n      } else {\n        this.switchStep('addName')\n      }\n    },\n    selectActionType(type) {\n      this.actionType = type\n      this.actionConfigArray = []\n      this.steps = {\n        selectActionType: { name: 'selectActionType', complete: false },\n        openMessageText: { name: 'openMessageText', complete: false },\n        openToConfig: { name: 'openToConfig', complete: false },\n        addTwilioConfig: { name: 'addTwilioConfig', complete: false },\n        addName: { name: 'addName', complete: false }\n      }\n      this.steps.selectActionType.complete = true\n      this.switchStep('openMessageText')\n    },\n    handleClose() {\n      this.$emit('close-action')\n    },\n    handleListInput(val) {\n      this.actionConfigArray = val\n      this.steps['openToConfig'].complete = true\n    },\n    handleWebhookURLInput(val) {\n      this.actionConfigArray = val\n      this.steps['openToConfig'].complete = true\n    },\n    saveConfig() {\n      const type = this.actionType.type\n      const checked =\n        type != 'EMAIL'\n          ? this.rules[type](this.actionConfigArray)\n          : this.actionConfigArray.filter(\n              email => this.rules['EMAIL'](email) !== true\n            ).length < 1\n      if (checked === true) {\n        if (this.actionConfigArray) {\n          switch (this.actionType.type) {\n            case 'SLACK_WEBHOOK':\n              {\n                this.actionConfig = {\n                  webhook_url_secret: this.secretName\n                }\n                if (this.messageText) {\n                  this.actionConfig.message = this.messageText\n                }\n              }\n              break\n            case 'EMAIL':\n              {\n                this.actionConfig = { to_emails: this.actionConfigArray }\n                if (this.messageText) {\n                  this.actionConfig.body = this.messageText\n                }\n              }\n              break\n            case 'TWILIO':\n              {\n                this.actionConfig = {\n                  phone_numbers: this.actionConfigArray,\n                  auth_token_secret: this.authToken,\n                  account_sid: this.accountSid,\n                  messaging_service_sid: this.messagingService\n                }\n                if (this.messageText) {\n                  this.actionConfig.message = this.messageText\n                }\n              }\n              break\n            case 'PAGERDUTY':\n              {\n                this.actionConfig = {\n                  api_token_secret: this.apiToken || null,\n                  routing_key: this.routingKey,\n                  severity: this.severity\n                }\n                if (this.messageText) {\n                  this.actionConfig.message = this.messageText\n                }\n              }\n              break\n            case 'MS_TEAMS':\n              {\n                this.actionConfig = {\n                  webhook_url_secret: this.webhookURLString\n                }\n                if (this.messageText) {\n                  this.actionConfig.message = this.messageText\n                }\n              }\n              break\n            case 'WEBHOOK': {\n              this.actionConfig = {\n                url: this.webhookURLString\n              }\n              if (this.jsonPayload) {\n                this.actionConfig.payload = JSON.parse(this.jsonPayload)\n              }\n            }\n          }\n        }\n      } else {\n        this.errorMessage = checked\n      }\n    },\n    selectSecret(secretName) {\n      this.secretName = secretName\n      this.steps['openToConfig'].complete = true\n      this.switchStep('addName')\n    },\n    // openTwilioConfigSection() {\n    //   this.openTwilioConfig = !this.openTwilioConfig\n    // },\n    saveMessage() {\n      this.steps['openMessageText'].complete = true\n      this.switchStep('openToConfig')\n    },\n    actionTypes() {\n      let allHooks\n      allHooks = actionTypes\n      return allHooks.filter(\n        t => (t.requiresCloud && this.isCloud) || !t.requiresCloud\n      )\n    },\n    createAction() {\n      this.saving = true\n      this.saveConfig()\n      let config\n      switch (this.actionType.type) {\n        case 'SLACK_WEBHOOK':\n          config = {\n            slack_notification: this.actionConfig\n          }\n          break\n        case 'EMAIL':\n          config = {\n            email_notification: this.actionConfig\n          }\n          break\n        case 'TWILIO':\n          config = {\n            twilio_notification: this.actionConfig\n          }\n          break\n        case 'PAGERDUTY':\n          config = {\n            pagerduty_notification: this.actionConfig\n          }\n          break\n        case 'MS_TEAMS':\n          config = {\n            teams_webhook_notification: this.actionConfig\n          }\n          break\n        case 'WEBHOOK':\n          config = {\n            webhook: this.actionConfig\n          }\n          break\n        default:\n          config = {}\n      }\n      const name = this.newSaveAs || this.saveAs\n      const input = { name: name, config }\n      this.$emit('new-action', input)\n    }\n  },\n  apollo: {\n    secretNames: {\n      query: require('@/graphql/Tenant/tenant-secret-names.gql'),\n      update: data => data.secret_names\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card elevation=\"0\">\n    <v-card-text class=\"text-h6 font-weight-light\">\n      <v-row>\n        <v-col cols=\"9\" lg=\"10\">\n          <span v-if=\"actionType.sendText\" class=\"mr-1\">{{\n            actionType.sendText\n          }}</span>\n          <v-btn\n            :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n            :color=\"buttonColor('selectActionType')\"\n            :class=\"format('selectActionType')\"\n            class=\"px-0 pb-1 text-h6\"\n            text\n            @click=\"switchStep('selectActionType')\"\n            ><span>{{ actionType.title }}</span></v-btn\n          >\n          {{ ' ' }}\n          <span>\n            <v-btn\n              v-if=\"!messageText\"\n              :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n              class=\"px-0 pb-1 text-h6 d-inline-block text-truncate\"\n              max-width=\"300px\"\n              text\n              :disabled=\"!actionType.type\"\n              :color=\"buttonColor('openMessageText')\"\n              :class=\"format('openMessageText')\"\n              @click=\"switchStep('openMessageText')\"\n            >\n              <span v-if=\"isWebhook\" class=\"mr-1\"> JSON </span> message</v-btn\n            >\n            <v-tooltip v-else top>\n              <template #activator=\"{ on, attrs }\">\n                <v-btn\n                  :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n                  class=\"px-0 pb-1 text-h6 d-inline-block text-truncate\"\n                  max-width=\"300px\"\n                  text\n                  :disabled=\"!actionType.type\"\n                  :color=\"buttonColor('openMessageText')\"\n                  :class=\"format('openMessageText')\"\n                  v-bind=\"attrs\"\n                  @click=\"switchStep('openMessageText')\"\n                  v-on=\"on\"\n                >\n                  message</v-btn\n                ></template\n              >{{ messageText }}</v-tooltip\n            >\n          </span>\n          <span>\n            <v-btn\n              :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n              class=\"pb-1 px-0 ml-1 text-h6\"\n              text\n              :disabled=\"!actionType.type\"\n              :color=\"buttonColor('openToConfig')\"\n              :class=\"format('openToConfig')\"\n              @click=\"switchStep('openToConfig')\"\n              >{{ to }}</v-btn\n            >\n            <span v-if=\"isTwilio\">\n              using this\n              <v-btn\n                :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n                class=\"px-0 pb-1 text-h6\"\n                text\n                :color=\"buttonColor('addTwilioConfig')\"\n                :class=\"format('openToConfig')\"\n                @click=\"switchStep('addTwilioConfig')\"\n              >\n                config.</v-btn\n              ></span\n            ></span\n          ></v-col\n        >\n        <v-col cols=\"3\" lg=\"2\" class=\"text-right\">\n          <v-btn\n            text\n            color=\"utilGrayMid\"\n            class=\"light-weight-text mr-1 px-2\"\n            @click=\"handleClose\"\n          >\n            <span style=\"text-transform: none;\">Cancel</span></v-btn\n          ><v-btn\n            color=\"primary\"\n            elevation=\"0\"\n            :loading=\"saving\"\n            :disabled=\"!allowSave\"\n            @click=\"createAction\"\n            ><span style=\"text-transform: none;\">Save</span></v-btn\n          ></v-col\n        >\n      </v-row>\n    </v-card-text>\n\n    <v-card-text v-if=\"step.name === 'selectActionType'\">\n      <v-row>\n        <v-col\n          v-for=\"type in actionTypes()\"\n          :key=\"type.title\"\n          cols=\"12\"\n          sm=\"6\"\n          md=\"4\"\n          lg=\"2\"\n        >\n          <div\n            v-ripple\n            class=\"chip-bigger d-flex align-center justify-start pa-2 cursor-pointer text-body-1\"\n            :class=\"{ active: actionType === type }\"\n            @click=\"selectActionType(type)\"\n            ><v-icon left class=\"mx-4\">\n              {{ type.icon }}\n            </v-icon>\n            {{ type.title }}</div\n          ></v-col\n        ></v-row\n      >\n    </v-card-text>\n    <v-card-text v-else-if=\"step.name === 'openMessageText'\" class=\"pt-0\">\n      <div>\n        <span v-if=\"!isWebhook\" class=\"primary--text\"\n          >Type your message here or leave blank to send a default message.\n        </span>\n        <span v-else class=\"primary--text\"\n          >Enter custom JSON payload to send as part of your webhook or leave\n          blank to send data from the event that triggers the\n          notification.</span\n        ><v-menu\n          v-model=\"menu\"\n          :close-on-content-click=\"false\"\n          :open-on-hover=\"true\"\n        >\n          <template #activator=\"{ on, attrs }\">\n            <v-btn icon small v-bind=\"attrs\" v-on=\"on\">\n              <v-icon color=\"primary\" small>info</v-icon>\n            </v-btn>\n          </template>\n\n          <v-card width=\"30vW\">\n            <v-card-text\n              ><div class=\"mb-2\"\n                >The default message varies depending on what type of event you\n                attach the action to. You can also send a custom message.\n\n                <div class=\"mt-2\">\n                  Attributes you can include in a custom message include:\n                  <ul\n                    ><li>event_id</li>\n                    <li>flow_name</li\n                    ><li> flow_run_name</li>\n                    <li>flow_run_id</li>\n                    <li>agent_ids</li>\n                    <li>state</li>\n                    <li>state_message</li>\n                    <li>flow_run_link</li>\n                  </ul>\n                </div>\n                <div v-if=\"!isWebhook\" class=\"mt-2\">\n                  For example:\n                  <div>{{\n                    `\"Run {flow_run_name} from flow {flow_name} needs\n                your attention! See: {flow_run_link}\"`\n                  }}</div>\n                </div>\n                <div v-else class=\"mt-2\">\n                  For example:\n                  <div\n                    >{{ `{` }}\n                    <div class=\"ml-3\">{{ `\"flow\": \"{flow_name}\"` }}</div>\n                    <div>{{ `}` }}</div>\n                  </div>\n                </div>\n              </div>\n            </v-card-text>\n          </v-card>\n        </v-menu>\n        <v-textarea\n          v-if=\"!isWebhook\"\n          v-model=\"messageText\"\n          class=\"pt-0\"\n          outlined\n          :placeholder=\"messagePlaceholder\"\n          @keydown.enter=\"saveMessage\"\n        />\n\n        <json-input\n          v-else\n          v-model=\"jsonPayload\"\n          :placeholder=\"jsonPlaceholder()\"\n        />\n      </div>\n    </v-card-text>\n    <v-card-text v-else-if=\"step.name === 'openToConfig'\">\n      <v-row v-if=\"actionType.type === 'SLACK_WEBHOOK'\" class=\"py-3 px-1\">\n        <div v-if=\"!secretNames || !secretNames.length\" class=\"mx-2\">\n          To set up a slack webhook, you'll need to create a\n          <router-link :to=\"{ name: 'secrets' }\">secret</router-link> with your\n          slack webhook url.\n        </div>\n        <div v-else class=\"mx-2\">\n          Select the name of the\n          <router-link :to=\"{ name: 'secrets' }\">secret</router-link> for your\n          Slack webhook url.\n        </div>\n      </v-row>\n      <v-row v-if=\"actionType.type === 'SLACK_WEBHOOK'\" class=\"px-1\">\n        <div\n          v-for=\"name in secretNames\"\n          :key=\"name\"\n          v-ripple\n          class=\"chip-small px-2 pb-2 pt-1 ma-2 cursor-pointer text-body-1\"\n          :class=\"{ active: secretName === name }\"\n          @click=\"selectSecret(name)\"\n          ><div class=\"text-truncate\">\n            {{ name }}\n          </div></div\n        >\n      </v-row>\n\n      <div v-else-if=\"isPagerDuty\">\n        <span>\n          Prefect Cloud will send a PagerDuty notification. Create your\n          Integration Key by visiting the Integrations tab of the Service\n          Details page and setting up an\n          <a\n            href=\"https://support.pagerduty.com/docs/services-and-integrations\"\n            target=\"_blank\"\n            >Events API v2</a\n          >\n          integration. Providing a PagerDuty API token is optional.\n        </span>\n        <v-row class=\"mt-2\">\n          <v-col cols=\"12\" md=\"4\">\n            <v-select\n              data-public\n              v-model=\"apiToken\"\n              :items=\"secretNames\"\n              outlined\n              label=\"PagerDuty API Token Secret (optional)\"\n              no-data-text=\"You will need to create a secret with your PagerDuty API Token\"\n            />\n          </v-col>\n          <v-col cols=\"12\" md=\"4\">\n            <v-select\n              data-public\n              v-model=\"severity\"\n              :items=\"severityLevels\"\n              outlined\n              label=\"Severity\"\n            />\n          </v-col>\n          <v-col cols=\"12\" md=\"4\">\n            <v-text-field\n              v-model=\"routingKey\"\n              :rules=\"[rules.required]\"\n              label=\"Integration key\"\n              outlined\n              class=\"mb-8\"\n            />\n          </v-col>\n        </v-row>\n      </div>\n      <div\n        v-else-if=\"actionType.type === 'EMAIL' || actionType.type === 'TWILIO'\"\n      >\n        <div class=\"mb-1 text-caption\">\n          Hint: add to the list after typing by pressing the Enter key\n        </div>\n        <ListInput\n          :label=\"messageConfigLabel\"\n          :value=\"actionConfigArray\"\n          :rules=\"[rules[actionType.type]]\"\n          :hide=\"false\"\n          :show-reset=\"false\"\n          :show-clear=\"false\"\n          @input=\"handleListInput\"\n        ></ListInput>\n      </div>\n\n      <div\n        v-else-if=\"\n          actionType.type === 'MS_TEAMS' || actionType.type === 'WEBHOOK'\n        \"\n      >\n        <div v-if=\"actionType.type === 'WEBHOOK'\">\n          <span>\n            Prefect Cloud will send a payload to the URL you provide.\n          </span>\n        </div>\n        <div v-else-if=\"actionType.type === 'MS_TEAMS'\">\n          <span>\n            Prefect Cloud will send a message via the\n            <a\n              href=\"https://docs.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/connectors-using#setting-up-a-custom-incoming-webhook\"\n              target=\"_blank\"\n            >\n              MS Teams API</a\n            >; you'll need to set up a Teams Incoming Webhook Connector and\n            retreive the webhook URL. To securely store your webhook URL, create\n            a\n            <router-link :to=\"{ name: 'secrets' }\"> Prefect secret</router-link\n            >.\n          </span>\n        </div>\n\n        <v-row class=\"mt-2\">\n          <v-col cols=\"12\" md=\"8\">\n            <v-text-field\n              v-model=\"webhookURLString\"\n              :rules=\"[rules.required]\"\n              label=\"Webhook URL\"\n              outlined\n              class=\"mb-8\"\n              @input=\"handleWebhookURLInput\"\n            />\n          </v-col>\n        </v-row>\n      </div>\n    </v-card-text>\n\n    <v-card-text v-else-if=\"step.name === 'addTwilioConfig'\">\n      <div>\n        <span>\n          Prefect Cloud will send a message via the\n          <a href=\"https://www.twilio.com/docs\" target=\"_blank\">\n            Twilio SMS API</a\n          >. You can retrieve the <code class=\"my-1 mx-1\">ACCOUNT SID</code> and\n          <code class=\"my-1 mx-1\">AUTH TOKEN</code> from the dashboard of your\n          Twilio account. To securely store your auth token, create a\n          <router-link :to=\"{ name: 'secrets' }\"> Prefect secret</router-link>.\n          You'll also need to configure a\n          <a\n            href=\"https://www.twilio.com/docs/sms/services/api#messaging-services-resource\"\n            target=\"_blank\"\n          >\n            Messaging Service</a\n          >\n          to recieve messages.\n        </span>\n      </div>\n\n      <v-row class=\"mt-4\">\n        <v-col cols=\"12\" md=\"4\">\n          <v-select\n            data-public\n            v-model=\"authToken\"\n            outlined\n            :items=\"secretNames\"\n            label=\"Name of Auth token Secret\"\n            no-data-text=\"You will need to create a secret with your PagerDuty API Token\"\n          />\n        </v-col>\n        <v-col cols=\"12\" md=\"4\">\n          <v-text-field\n            v-model=\"accountSid\"\n            outlined\n            :rules=\"[rules.required]\"\n            label=\"Account SID\"\n          />\n        </v-col>\n        <v-col cols=\"12\" md=\"4\">\n          <v-text-field\n            v-model=\"messagingService\"\n            outlined\n            :rules=\"[rules.required]\"\n            label=\"Messaging service SID\"\n          />\n        </v-col>\n      </v-row>\n    </v-card-text>\n\n    <v-card-text v-else-if=\"step.name === 'addName'\" class=\"pr-4\">\n      <div class=\"pb-2\"\n        >Give your action a name so you can find and re-use it with more\n        automations.</div\n      >\n      <v-text-field\n        v-model=\"saveAs\"\n        outlined\n        class=\"pr-4\"\n        label=\"Save As\"\n      ></v-text-field>\n    </v-card-text>\n    <v-card-actions v-if=\"step.name !== 'addName'\">\n      <v-spacer></v-spacer>\n      <v-btn\n        class=\"text-normal mr-1 mb-1\"\n        depressed\n        :disabled=\"disableNext\"\n        color=\"primary\"\n        title=\"Next\"\n        @click=\"handleNext\"\n        ><span style=\"text-transform: none;\"> Next</span>\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style scoped>\n.no-top {\n  margin-top: 1px;\n}\n</style>\n\n<style lang=\"scss\" scoped>\n.chip-bigger {\n  border: 1px solid;\n  border-color: var(--v-utilGrayLight-base) !important;\n  border-radius: 5px;\n  height: 60px;\n  transition: all 50ms;\n  width: 100%;\n\n  &.active {\n    border-color: var(--v-codePink-base) !important;\n  }\n\n  &:hover,\n  &:focus {\n    background-color: rgba(0, 0, 0, 0.05);\n  }\n}\n\n.chip-small {\n  border: 1px solid;\n  border-color: var(--v-utilGrayLight-base) !important;\n  border-radius: 5px;\n  height: 35px;\n  max-width: fit-content;\n  transition: all 50ms;\n  width: 100%;\n\n  &.active {\n    border-color: var(--v-codePink-base) !important;\n  }\n\n  &:hover,\n  &:focus {\n    background-color: rgba(0, 0, 0, 0.05);\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/Automations/AddAutomationCard.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport { pollsProjectsMixin } from '@/mixins/polling/pollsProjectsMixin'\nimport AddAction from '@/pages/Dashboard/Automations/AddAction'\nimport CreateAgentConfigForm from '@/pages/Dashboard/Automations/CreateAgentConfigForm'\nimport {\n  AUTOMATIONSTATES,\n  flowEventTypes,\n  actionTypes\n} from '@/utils/automations'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport UpgradeBadge from '@/components/UpgradeBadge'\nimport DeleteAgentConfig from './DeleteAgentConfig.vue'\n\nconst systemActions = [\n  'CancelFlowRunAction',\n  'PauseScheduleAction',\n  'CreateFlowRunAction'\n]\n\nexport default {\n  components: {\n    AddAction,\n    CreateAgentConfigForm,\n    ConfirmDialog,\n    UpgradeBadge,\n    DeleteAgentConfig\n  },\n  mixins: [pollsProjectsMixin],\n  props: {\n    hookDetail: {\n      type: Object,\n      required: false,\n      default: null\n    }\n  },\n  data() {\n    return {\n      steps: {\n        openAgentOrFlow: { name: 'openAgentOrFlow', complete: false },\n        chooseAgentConfig: { name: 'chooseAgentConfig', complete: false },\n        selectFlow: { name: 'selectFlow', complete: false },\n        selectEventType: { name: 'selectEventType', complete: false },\n        selectState: { name: 'selectState', complete: false },\n        openDuration: { name: 'openDuration', complete: false },\n        selectDoThis: { name: 'selectDoThis', complete: false }\n      },\n      hookTypes: [\n        { type: 'flow', label: 'flow run', permission: null },\n        { type: 'agent', label: 'agent', permission: 'feature:agent-sla' }\n      ],\n      selectAll: false,\n      deleting: false,\n      saving: false,\n      searchEntry: null,\n      selectedAgentConfig: this.hookDetail?.agentConfig,\n      selectedFlows: this.hookDetail?.flowName || [],\n      showAgentConfigForm: false,\n      step: null,\n      removeDoThisDialog: false,\n      flowNamesList: this.hookDetail?.flowNameList || [],\n      hookDetails: this.hookDetail,\n      project: null,\n      stateGroups: Object.keys(AUTOMATIONSTATES),\n      states: AUTOMATIONSTATES,\n      stateName: '',\n      agentFlowOrSomethingElse: null,\n      chosenStates:\n        this.hookDetail?.hook?.event_tags?.state || AUTOMATIONSTATES['All'],\n      disableClick: false,\n      chosenAction: this.hookDetail?.hook?.action || null,\n      seconds: this.hookDetail?.flowConfig?.duration_seconds || 60,\n      addAction: false,\n      flowEventType: null,\n      flowEventTypes: flowEventTypes,\n      notAll: !!this.hookDetail?.flowName || false,\n      previousStep: null,\n      isActive: false,\n      rules: {\n        required: val => !!val || 'Required',\n        notNull: val => val > 0 || 'Duration must be greater than 0 seconds'\n      },\n      animated: false,\n      agentConfigId: ''\n    }\n  },\n  computed: {\n    ...mapGetters('data', ['projects']),\n    ...mapGetters('license', ['permissions']),\n    //We can not update agent for now - config id needs to be added at agent creation\n    // ...mapGetters('agent', ['agents']),\n    // projectsList() {\n    //   return [...this.projects, { name: 'All', id: null }].sort((a, b) =>\n    //     a.name > b.name ? 1 : -1\n    //   )\n    // },\n    allFlows() {\n      return (\n        this.selectedFlows?.length === this.flows?.length &&\n        this.flows?.length > 1\n      )\n    },\n    formHeight() {\n      return this.$vuetuify?.breakpoint?.smAndUp ? '35vh' : '25vh'\n    },\n    agentOrFlow() {\n      if (this.agentFlowOrSomethingElse) return this.agentFlowOrSomethingElse\n      if (this.hookDetails?.hook?.event_type === 'AgentSLAFailedEvent')\n        return 'agent'\n      if (this.hookDetails) return 'flow'\n      return 'this'\n    },\n    disableStep() {\n      return this.agentOrFlow === 'agent' || this.selectedFlows.length > 1\n    },\n    disableDoThis() {\n      if (this.agentOrFlow === 'this' && !this.hookDetail) return true\n      if (this.agentOrFlow === 'flow' && this.selectedFlows.length < 1)\n        return true\n      return false\n    },\n    isSLA() {\n      return (\n        this.flowEventType?.enum === 'STARTED_NOT_FINISHED' ||\n        this.flowEventType?.enum === 'SCHEDULED_NOT_STARTED'\n      )\n    },\n    haveOrHas() {\n      if (this.selectedFlows?.length > 1 && !this.allFlows) return 'have'\n      return 'has'\n    },\n    editedActions() {\n      // Most actions are independent and can be used across flows but PauseScheduleAction and CreateScheduleAction can take a flow group id so need to filter here\n      const actions = this.actions.filter(\n        action =>\n          (action.action_type !== 'PauseScheduleAction' ||\n            action?.action_config?.flow_group_id ===\n              this.selectedFlows[0]?.flow_group_id) &&\n          (action.action_type !== 'CreateFlowRunAction' ||\n            action?.action_config?.flow_group_id ===\n              this.selectedFlows[0]?.flow_group_id)\n      )\n\n      if (actions) {\n        if (this.agentOrFlow === 'agent') {\n          return actions.filter(\n            action => !systemActions.includes(action.action_type)\n          )\n        }\n        if (\n          !actions.find(action => action.action_type === 'CancelFlowRunAction')\n        ) {\n          actions.push({\n            name: 'cancel run',\n            value: 'CANCEL_RUN',\n            action_type: 'CancelFlowRunAction'\n          })\n        }\n        if (\n          !actions.find(\n            action =>\n              action.action_type === 'PauseScheduleAction' &&\n              action.action_config.flow_group_id ===\n                this.selectedFlows[0].flow_group_id\n          )\n        ) {\n          actions.push({\n            name: 'pause schedule',\n            value: 'PAUSE_SCHEDULE',\n            id: 2,\n            action_type: 'PauseScheduleAction'\n          })\n        }\n        if (\n          !actions.find(action => action.action_type === 'CreateFlowRunAction')\n        ) {\n          actions.push({\n            name: 'start a new run',\n            value: 'START_RUN',\n            id: 3,\n            action_type: 'CreateFlowRunAction'\n          })\n        }\n        return actions\n      }\n      return [\n        {\n          name: 'cancel run',\n          value: 'CANCEL_RUN',\n          id: 1,\n          action_type: 'CancelFlowRunAction'\n        },\n        {\n          name: 'pause schedule',\n          value: 'PAUSE_SCHEDULE',\n          id: 2,\n          action_type: 'PauseScheduleAction'\n        },\n        {\n          name: 'start new run',\n          value: 'START_RUN',\n          id: 3,\n          action_type: 'CreateFlowRunAction'\n        }\n      ]\n    },\n    customActions() {\n      return this.editedActions.filter(\n        a => !systemActions.includes(a.action_type)\n      )\n    },\n    systemActions() {\n      if (this.selectedFlows?.length > 1) return []\n      return this.editedActions.filter(a =>\n        systemActions.includes(a.action_type)\n      )\n    },\n    includeTo() {\n      this.hookDetail\n      return this.flowEventType?.enum == 'CHANGES_STATE'\n    },\n    durationSeconds() {\n      return this.seconds || this.hookDetails?.flowConfig?.duration_seconds\n    },\n    flowNames() {\n      const agentName =\n        this.hookDetail?.agentConfig?.agents?.length == 1\n          ? this.HookDetail?.agentConfig?.agents[0]?.name === 'agent'\n            ? this.HookDetail?.agentConfig?.agents[0]?.type\n            : this.hookDetail?.agentConfig?.agents[0]?.name\n          : this.hookDetail?.agentConfig?.agents\n              .map((agent, index) => {\n                if (index === 0) {\n                  return agent.name === 'agent' ? agent.type : agent.name\n                } else {\n                  return agent.name === 'agent'\n                    ? `or ${agent.type}`\n                    : `or ${agent.name}`\n                }\n              })\n              .toString()\n      return this.agentOrFlow === 'agent'\n        ? agentName || 'agent'\n        : this.flowNamesList?.length > 1\n        ? this.flowNamesList?.length === this.flows?.length\n          ? 'any flow'\n          : 'any of these flows'\n        : this.flowNamesList.toString() || this.agentOrFlow\n    },\n    hookStates() {\n      return this.chosenStates?.length === this.states['All'].length\n        ? 'any state'\n        : this.stateName && this.stateName != 'Custom'\n        ? this.stateName\n        : this.chosenStates.length != 1\n        ? 'selected states'\n        : this.chosenStates.toString().toLowerCase()\n    },\n    hookAction() {\n      return (\n        this.chosenAction?.name || this.chosenAction?.action_type || 'do this'\n      )\n    },\n    completeAction() {\n      if (this.agentOrFlow === 'agent') return !!this.chosenAction\n      if (!this.includeTo)\n        return !!this.selectedFlows?.length && !!this.chosenAction\n      return (\n        !!this.chosenAction &&\n        !!this.chosenStates?.length &&\n        !!this.selectedFlows?.length\n      )\n    },\n    placeholderMessage() {\n      return 'Search by Flow, or Project'\n    },\n    searchFormatted() {\n      if (!this.searchEntry) return null\n      return `%${this.searchEntry}%`\n    },\n    stateGroupAll() {\n      return this.stateGroup('All')\n    },\n    stateGroupCustom() {\n      return (\n        !this.stateGroupAll &&\n        !this.stateGroupFailed &&\n        !this.stateGroupFinished &&\n        !this.stateGroupSuccess\n      )\n    },\n    stateGroupFailed() {\n      return this.stateGroup('Failed')\n    },\n    stateGroupFinished() {\n      return this.stateGroup('Finished')\n    },\n    stateGroupSuccess() {\n      return this.stateGroup('Success')\n    },\n    validUUID() {\n      if (!this.searchEntry) return false\n\n      const UUIDRegex = /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/\n      // Call .trim() to get rid of whitespace on the ends of the\n      // string before making the query\n      return UUIDRegex.test(this.searchEntry.trim())\n    },\n    filteredFlowEventTypes() {\n      if (this.selectedFlows?.length > 1)\n        return this.flowEventTypes.filter(item => item.enum != 'CHANGES_STATE')\n      return this.flowEventTypes\n    }\n  },\n  watch: {\n    selectAll(val) {\n      this.notAll = false\n      if (val) {\n        this.selectedFlows = this.flows\n        this.flowNamesList = ['any flow']\n\n        this.flowEventType = {\n          name: 'changes state',\n          enum: 'CHANGES_STATE'\n        }\n      } else {\n        this.selectedFlows = []\n        this.flowNamesList = []\n      }\n    }\n  },\n  created() {\n    this.step = this.steps['openAgentOrFlow']\n    this.flowEventType = this.hookDetail?.flowConfig?.kind\n      ? this.flowEventTypes.find(\n          type => type.enum === this.hookDetail?.flowConfig?.kind\n        )\n      : this.hookDetail?.hook?.event_type === 'FlowRunStateChangedEvent'\n      ? {\n          name: 'changes state',\n          enum: 'CHANGES_STATE'\n        }\n      : this.hookDetail?.agentConfig\n      ? { name: 'are unhealthy' }\n      : {\n          name: 'does this'\n        }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    actionIcon(type) {\n      return actionTypes.find(a => a.actionType == type)?.icon\n    },\n    addHint() {\n      clearTimeout(this.animationTimeout)\n      this.animated = true\n\n      this.animationTimeout = setTimeout(() => {\n        this.animated = false\n      }, 1500)\n    },\n    buttonColor(selectedStep, otherStep) {\n      // const stepComplete = this.steps[selectedStep]\n      // const otherComplete = this.steps[otherStep]\n      return this.step.name === selectedStep || this.step.name === otherStep\n        ? 'accentPink'\n        : 'utilGrayDark'\n    },\n    createAgentConfig() {},\n    format(selectedStep, otherStep) {\n      const stepComplete = this.steps[selectedStep].complete\n      return this.step.name === selectedStep || this.step.name === otherStep\n        ? 'font-weight-dark'\n        : stepComplete\n        ? 'font-weight-light text-decoration-dotted-underline'\n        : 'font-weight-light'\n    },\n    closeCard() {\n      if (this.hookDetail) this.$emit('close')\n      else {\n        this.$emit('refresh')\n      }\n    },\n    stateGroup(group) {\n      return (\n        AUTOMATIONSTATES[group] &&\n        AUTOMATIONSTATES[group].every(state =>\n          this.chosenStates?.includes(state)\n        ) &&\n        AUTOMATIONSTATES[group].length == this.chosenStates.length\n      )\n    },\n    dynamicStateGroup(group) {\n      return this[`stateGroup${group}`]\n    },\n    switchStep(selectedStep) {\n      if (this.step.name == selectedStep) {\n        this.addHint()\n      } else {\n        clearTimeout(this.animationTimeout)\n      }\n\n      this.previousStep = this.step.name\n\n      if (this.step.name === 'openDuration')\n        this.steps['openDuration'].complete = true\n      this.step = this.steps[selectedStep]\n    },\n    selectAgentOrFlow(choice) {\n      this.agentFlowOrSomethingElse = choice\n      if (choice === 'flow') {\n        this.flowEventType =\n          this.hookDetail?.hook?.event_type === 'FlowSLAFailedEvent'\n            ? this.flowEventTypes.find(\n                type => type.enum === this.hookDetail?.flowConfig?.kind\n              )\n            : this.hookDetail?.hook?.event_type === 'FlowRunStateChangedEvent'\n            ? {\n                name: 'changes state',\n                enum: 'CHANGES_STATE'\n              }\n            : {\n                name: 'does this'\n              }\n        this.switchStep('selectFlow')\n      }\n      if (choice === 'agent') {\n        this.flowEventType = { name: 'are unhealthy' }\n        this.flowNamesList = []\n        this.selectedFlows = []\n\n        this.switchStep('chooseAgentConfig')\n      }\n      this.steps['openAgentOrFlow'].complete = true\n    },\n    selectFlow(flow) {\n      if (\n        flow &&\n        this.selectedFlows?.find(\n          item => item.flow_group_id === flow.flow_group_id\n        )\n      ) {\n        this.selectedFlows = this.selectedFlows?.filter(\n          item => item.flow_group_id != flow.flow_group_id\n        )\n      } else {\n        if (flow) this.selectedFlows.push(flow)\n      }\n      this.notAll = true\n      this.flowNamesList = this.selectedFlows?.map(flow => flow.name)\n      this.steps['openAgentOrFlow'].complete = true\n      this.steps['selectFlow'].complete = true\n    },\n    handleFlowNext() {\n      if (this.selectedFlows.length || this.allFlows)\n        this.steps['openAgentOrFlow'].complete = true\n      if (this.selectedFlows?.length > 1) {\n        this.flowEventType = {\n          name: 'changes state',\n          enum: 'CHANGES_STATE'\n        }\n        this.switchStep('selectState')\n      } else {\n        this.switchStep('selectEventType')\n      }\n    },\n    hasPermission(permission) {\n      return permission ? this.permissions?.includes(permission) : true\n    },\n    selectFlowEventType(type) {\n      this.steps['selectEventType'].complete = true\n      if (type) this.flowEventType = type\n      this.isSLA\n        ? this.switchStep('openDuration')\n        : this.includeTo\n        ? this.switchStep('selectState')\n        : this.switchStep('selectDoThis')\n    },\n    selectStateGroup(group) {\n      this.stateName = group\n      this.chosenStates = [...this.states[group]]\n      this.steps['selectState'].complete = this.chosenStates.length > 0\n    },\n    selectStates(state) {\n      this.stateName = 'Custom'\n      this.chosenStates.find(\n        item => item === state || item.toUpperCase() == state\n      )\n        ? (this.chosenStates = this.chosenStates.filter(\n            item => item != state && item.toUpperCase() != state\n          ))\n        : this.chosenStates.push(state)\n      this.steps['selectState'].complete = this.chosenStates.length > 0\n    },\n    async handleSaveAgentConfig(config) {\n      this.agentConfigId = config.id\n      this.$apollo.queries.agentConfigs.refetch()\n      this.showAgentConfigForm = false\n    },\n    selectAgentConfig(config) {\n      this.steps['chooseAgentConfig'].complete = true\n      this.agentConfigId = config.id\n      this.selectedAgentConfig = config\n    },\n    selectAction(action) {\n      this.steps['selectDoThis'].complete = true\n      this.chosenAction = action\n    },\n    closeStates() {\n      this.switchStep('selectDoThis')\n    },\n    closeSeconds() {\n      this.steps['openDuration'].complete = true\n      this.switchStep('selectDoThis')\n    },\n    addNewAction() {\n      this.addAction = true\n      // this.openActions = false\n    },\n    disableChip(item) {\n      return (\n        (item.enum != 'CHANGES_STATE' && this.selectedFlows?.length > 1) ||\n        this.agentOrFlow === 'agent'\n      )\n    },\n    includesFlow(flow) {\n      return (\n        this.selectedFlows.filter(\n          item => item.flow_group_id === flow.flow_group_id\n        )?.length > 0\n      )\n    },\n    async createAction(input) {\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-action.gql'),\n          variables: {\n            input: { config: input.config, name: input.name }\n          }\n        })\n        await this.$apollo.queries.actions.refetch()\n        this.addAction = false\n        const newAction = {\n          id: data.create_action.id,\n          name: input.name\n        }\n        this.selectAction(newAction)\n        return data?.create_action\n      } catch (error) {\n        const errString = `${error}`\n        this.setAlert({\n          alertShow: true,\n          alertMessage: errString,\n          alertType: 'error'\n        })\n      }\n    },\n    handleRemoveClick(toDo) {\n      this.removeToDoId = toDo.id\n      this.removeDoThisDialog = true\n    },\n    async removeDoThis() {\n      this.deleting = true\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/delete_action.gql'),\n          variables: {\n            id: this.removeToDoId\n          }\n        })\n        data.delete_action?.success\n          ? await this.$apollo.queries.actions.refresh()\n          : this.setAlert({\n              alertShow: true,\n              alertMessage: data.delete_action.error,\n              alertType: 'error'\n            })\n      } catch (error) {\n        const errString = `${error}`\n        this.setAlert({\n          alertShow: true,\n          alertMessage: errString,\n          alertType: 'error'\n        })\n      } finally {\n        this.removeDoThisDialog = false\n        this.deleting = false\n      }\n    },\n    async createHook() {\n      this.saving = true\n\n      let data\n      try {\n        const flow = this.selectedFlows[0]?.flow_group_id\n        let action = this.chosenAction || this.hookDetails?.hook?.action\n        if (action?.value === 'CANCEL_RUN') {\n          const cancelConfig = { cancel_flow_run: {} }\n          action = await this.createAction({\n            config: cancelConfig,\n            name: 'cancel that run'\n          })\n        }\n        if (action?.value === 'PAUSE_SCHEDULE') {\n          const pauseConfig = { pause_schedule: {} }\n          action = await this.createAction({\n            config: pauseConfig,\n            name: 'pause the schedule'\n          })\n        }\n        if (action?.value === 'START_RUN') {\n          const startConfig = {\n            create_flow_run: {\n              flow_group_id: this.selectedFlows[0].flow_group_id\n            }\n          }\n          action = await this.createAction({\n            config: startConfig,\n            name: 'start a new run'\n          })\n        }\n        if (flow) {\n          if (this.includeTo) {\n            const flowGroupIds = this.selectedFlows?.map(\n              flow => flow.flow_group_id\n            )\n            const inputObject = this.allFlows\n              ? {\n                  action_id: action.id,\n                  states: this.chosenStates\n                }\n              : {\n                  flow_group_ids: flowGroupIds,\n                  action_id: action.id,\n                  states: this.chosenStates\n                }\n            const flowRunStateChangedSuccess = await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/create-flow-run-state-changed-hook.gql'),\n              variables: {\n                input: inputObject\n              }\n            })\n            data = flowRunStateChangedSuccess.data\n          }\n          if (this.isSLA) {\n            const kind = this.flowEventType?.enum\n            const configId = await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/create-flow-sla.gql'),\n              variables: {\n                input: {\n                  kind: kind,\n                  duration_seconds: Number(this.durationSeconds)\n                }\n              }\n            })\n            await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/add-config-to-flow.gql'),\n              variables: {\n                input: {\n                  flow_sla_config_id: configId.data.create_flow_sla_config.id,\n                  flow_group_id: flow\n                }\n              }\n            })\n\n            const flowSLAEventSuccess = await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/create-flow-sla-failed-hook.gql'),\n              variables: {\n                input: {\n                  action_id: action.id,\n                  sla_config_ids: [configId.data.create_flow_sla_config.id]\n                }\n              }\n            })\n            data = flowSLAEventSuccess.data\n          }\n        } else if (this.agentOrFlow === 'agent') {\n          let agentConfig\n          if (this.hookDetails?.agentConfig) {\n            this.agentConfigId = this.hookDetails?.agentConfig?.id\n          } else if (!this.agentConfigId) {\n            const { data } = await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/create-agent-config.gql'),\n              variables: {\n                input: {}\n              }\n            })\n            agentConfig = data?.create_agent_config\n            this.agentConfigId = agentConfig.id\n          }\n          const agentHook = await this.$apollo.mutate({\n            mutation: require('@/graphql/Mutations/create-agent-sla-failed-hook.gql'),\n            variables: {\n              input: {\n                action_id: action.id,\n                agent_config_ids: [this.agentConfigId]\n              }\n            }\n          })\n          data = agentHook.data\n        }\n        if (data && this.hookDetails) {\n          await this.$apollo.mutate({\n            mutation: require('@/graphql/Mutations/delete-hook.gql'),\n            variables: {\n              hookId: this.hookDetails.hook.id\n            }\n          })\n        }\n      } catch (error) {\n        const errString = `${error}`\n        this.setAlert({\n          alertShow: true,\n          alertMessage: errString,\n          alertType: 'error'\n        })\n        this.saving = false\n      } finally {\n        const updated = !!this.hookDetails\n        this.hookDetails = null\n        this.$emit('refetch')\n        if (data) {\n          const agentConfigString = `Your agent config ID is ${this.agentConfigId}.  You can find this in the info button on your automation`\n          this.setAlert({\n            alertShow: true,\n            alertMessage: this.agentConfigId\n              ? agentConfigString\n              : updated\n              ? 'Automation updated'\n              : 'Automation created',\n            alertType: 'success',\n            alertCopy: this.agentConfigId\n          })\n          this.saving = false\n          this.closeCard()\n        }\n      }\n    },\n    handleDeletedAgentConfig(event) {\n      this.$apollo.queries.agentConfigs.refetch()\n      if (this.selectedAgentConfig.id === event) {\n        this.selectedAgentConfig = null\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flows.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flows: {\n      query() {\n        return require('@/graphql/Dashboard/flows.js').default(this.isCloud)\n      },\n      variables() {\n        let searchParams = [{ archived: { _eq: false } }]\n\n        let orParams = [\n          {\n            name: { _ilike: this.searchFormatted }\n          },\n          { project: { name: { _ilike: this.searchFormatted } } }\n        ]\n\n        if (this.validUUID) {\n          orParams.push({ id: { _eq: this.search } })\n        }\n\n        if (this.isCloud) {\n          orParams.push({\n            created_by: { username: { _ilike: this.searchFormatted } }\n          })\n        }\n\n        return {\n          searchParams: {\n            _and: [...searchParams, { _or: [...orParams] }]\n          }\n        }\n      },\n      loadingKey: 'loading',\n      pollInterval: 60000,\n      update: data => data?.flow || []\n    },\n    actions: {\n      query: require('@/graphql/Automations/actions.gql'),\n      update: data => data?.action\n    },\n    agentConfigs: {\n      query: require('@/graphql/Automations/agent-config.gql'),\n      update: data => data.agent_config\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"pb-4 px-4\"\n    elevation=\"4\"\n  >\n    <v-card-text class=\"text-h5 font-weight-light pb-0 pt-4 px-0\">\n      <v-row no-gutters>\n        <v-col cols=\"9\" lg=\"10\">\n          When<v-btn\n            v-if=\"agentOrFlow === 'flow'\"\n            :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n            :color=\"buttonColor('openAgentOrFlow')\"\n            :class=\"format('openAgentOrFlow')\"\n            class=\"px-0 pb-1 ml-1 text-h5 d-inline-block\"\n            text\n            :disabled=\"addAction\"\n            max-width=\"500px\"\n            @click=\"switchStep('openAgentOrFlow')\"\n          >\n            <span>\n              any run\n            </span>\n          </v-btn>\n          <span v-if=\"agentOrFlow === 'flow'\"> from</span>\n          <span v-else-if=\"agentOrFlow === 'agent'\"> all</span>\n\n          <v-btn\n            v-if=\"agentOrFlow === 'flow'\"\n            :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n            :color=\"buttonColor('selectFlow')\"\n            :class=\"format('selectFlow')\"\n            class=\"px-0 pb-1 ml-1 text-h5 d-inline-block text-truncate\"\n            text\n            :disabled=\"addAction\"\n            max-width=\"500px\"\n            @click=\"\n              switchStep(\n                agentOrFlow === 'flow' ? 'selectFlow' : 'openAgentOrFlow'\n              )\n            \"\n          >\n            <span v-if=\"agentOrFlow === 'agent'\">{{ flowNames }}s</span>\n            <truncate\n              v-else-if=\"flowNamesList && flowNamesList.length\"\n              :content=\"flowNamesList.join(', ')\"\n            >\n              <span>{{ flowNames }}</span>\n            </truncate>\n            <span v-else>{{ flowNames }}</span>\n          </v-btn>\n\n          <v-btn\n            v-else-if=\"agentOrFlow === 'this'\"\n            :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n            color=\"accentPink\"\n            class=\"px-0 pb-1 ml-1 text-h5 d-inline-block text-truncate\"\n            text\n            :disabled=\"addAction\"\n            max-width=\"500px\"\n            @click=\"addHint\"\n          >\n            <span>this</span>\n          </v-btn>\n\n          <v-btn\n            v-else\n            :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n            :color=\"buttonColor('openAgentOrFlow')\"\n            :class=\"format('openAgentOrFlow')\"\n            class=\"px-0 pb-1 ml-1 text-h5 d-inline-block text-truncate\"\n            text\n            :disabled=\"addAction\"\n            max-width=\"500px\"\n            @click=\"switchStep('openAgentOrFlow')\"\n          >\n            <span v-if=\"agentOrFlow === 'agent'\">{{ flowNames }}s</span>\n            <truncate\n              v-else-if=\"flowNamesList && flowNamesList.length\"\n              :content=\"flowNamesList.join(', ')\"\n            >\n              <span>{{ flowNames }}</span>\n            </truncate>\n            <span v-else>{{ flowNames }}</span>\n          </v-btn>\n\n          <span v-if=\"agentOrFlow === 'agent'\">\n            with<v-btn\n              :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n              :color=\"buttonColor('chooseAgentConfig')\"\n              :class=\"format('chooseAgentConfig')\"\n              class=\"px-0 pb-1 ml-1 text-h5 d-inline-block text-truncate\"\n              text\n              :disabled=\"addAction\"\n              max-width=\"500px\"\n              @click=\"switchStep('chooseAgentConfig')\"\n            >\n              <span>\n                {{\n                  selectedAgentConfig && selectedAgentConfig.name\n                    ? selectedAgentConfig.name + ' config'\n                    : 'this config'\n                }}\n              </span>\n            </v-btn>\n          </span>\n\n          <v-btn\n            v-if=\"!disableStep\"\n            :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n            class=\"px-0 pb-1 ml-1 text-h5\"\n            text\n            :disabled=\"addAction || !selectedFlows.length\"\n            :color=\"buttonColor('selectEventType')\"\n            :class=\"format('selectEventType')\"\n            @click=\"switchStep('selectEventType')\"\n          >\n            <span>\n              {{ flowEventType.name }}\n            </span>\n          </v-btn>\n          <span v-else class=\"pl-1\">{{ flowEventType.name }}</span>\n          <span v-if=\"isSLA\">\n            after\n\n            <v-btn\n              :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n              class=\"px-0 pb-1 text-h5\"\n              text\n              :disabled=\"addAction\"\n              :color=\"buttonColor('openDuration')\"\n              :class=\"format('openDuration')\"\n              @click=\"switchStep('openDuration')\"\n            >\n              <span>{{ seconds }}</span>\n            </v-btn>\n            seconds</span\n          ><span v-if=\"includeTo\">\n            to<v-btn\n              :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n              class=\"ml-1 px-0 pb-1 text-h5\"\n              :class=\"format('selectState')\"\n              text\n              :disabled=\"addAction\"\n              :color=\"buttonColor('selectState')\"\n              @click=\"switchStep('selectState')\"\n            >\n              <span>{{ hookStates }}</span>\n            </v-btn></span\n          >, then<v-btn\n            :style=\"{\n              'text-transform': 'none',\n              'min-width': '0px'\n            }\"\n            class=\"px-0 pb-1 ml-1 text-h5 d-inline-block text-truncate\"\n            text\n            :disabled=\"disableDoThis\"\n            :color=\"buttonColor('selectDoThis')\"\n            :class=\"format('selectDoThis')\"\n            @click=\"switchStep('selectDoThis')\"\n            ><span>{{ addAction ? 'do this' : hookAction }}</span></v-btn\n          >.\n        </v-col>\n        <v-col v-if=\"!addAction\" cols=\"3\" lg=\"2\" class=\"text-right\">\n          <v-btn\n            v-if=\"step.name != 'openAgentOrFlow' || hookDetail\"\n            text\n            color=\"utilGrayMid\"\n            class=\"light-weight-text mr-1 px-2\"\n            @click=\"closeCard\"\n          >\n            <span class=\"text-none\">Cancel</span></v-btn\n          ><v-btn\n            color=\"primary\"\n            elevation=\"0\"\n            :loading=\"saving\"\n            :disabled=\"!completeAction\"\n            @click=\"createHook\"\n          >\n            <span class=\"text-none\">Save</span>\n          </v-btn>\n        </v-col>\n      </v-row>\n    </v-card-text>\n\n    <v-divider class=\"my-4 \" />\n\n    <transition name=\"quick-fade\" mode=\"out-in\">\n      <!-- OPEN AGENT OR FLOW -->\n      <div v-if=\"step.name === 'openAgentOrFlow'\" key=\"openAgentOrFlow\">\n        <div>\n          <div class=\"mb-2 text-subtitle-1 accentPink--text font-weight-light\">\n            Choose an automation:\n          </div>\n          <v-row>\n            <v-col cols=\"12\">\n              <v-btn\n                v-for=\"item in hookTypes\"\n                :key=\"item.type\"\n                outlined\n                depressed\n                :color=\"\n                  agentOrFlow === item.type ? 'accentPink' : 'utilGrayMid'\n                \"\n                class=\"mr-4 cursor-pointer text-h6 font-weight-light remove--disabled\"\n                :class=\"{ flash: animated }\"\n                :disabled=\"!hasPermission(item.permission)\"\n                :input-value=\"agentOrFlow === item.type\"\n                @click=\"selectAgentOrFlow(item.type)\"\n              >\n                <v-icon class=\"mr-3\">\n                  {{ item.type === 'flow' ? 'pi-flow' : 'pi-agent' }}\n                </v-icon>\n                <span class=\"text-lowercase\">{{ item.label }}</span>\n\n                <UpgradeBadge v-if=\"!hasPermission(item.permission)\">\n                  <span class=\"font-weight-medium\"\n                    ><span class=\"text-capitalize\">{{ item.label }}</span>\n                    automations</span\n                  >\n                  are only available on Standard and Enterprise plans.\n                </UpgradeBadge>\n              </v-btn>\n            </v-col>\n          </v-row>\n        </div>\n        <v-card-actions v-if=\"agentOrFlow !== 'this'\">\n          <v-spacer></v-spacer>\n          <v-btn\n            color=\"primary\"\n            elevation=\"0\"\n            title=\"Next\"\n            @click=\"\n              agentOrFlow === 'agent'\n                ? switchStep('selectDoThis')\n                : switchStep('selectFlow')\n            \"\n            ><span class=\"text-none\">Next</span>\n          </v-btn>\n        </v-card-actions>\n      </div>\n      <!-- END OPEN AGENT OR FLOW -->\n\n      <!-- CHOOSE AGENT CONFIG -->\n      <div\n        v-else-if=\"step.name === 'chooseAgentConfig'\"\n        key=\"chooseAgentConfig\"\n      >\n        <div class=\"pt-0 pb-8\">\n          <div class=\"mb-2 text-subtitle-1 font-weight-light\">\n            {{\n              !showAgentConfigForm\n                ? 'Choose an agent config:'\n                : 'Name your agent config:'\n            }}\n          </div>\n          <v-row v-if=\"!showAgentConfigForm\" no-gutters>\n            <v-col cols=\"12\">\n              <v-btn\n                small\n                elevation=\"0\"\n                color=\"primary\"\n                :class=\"{ flash: animated }\"\n                @click=\"showAgentConfigForm = true\"\n              >\n                <v-icon small class=\"mr-2\">fa-plus</v-icon>\n                <span class=\"text-none\">Create agent config</span>\n              </v-btn>\n\n              <div v-if=\"agentConfigs && agentConfigs.length\" class=\"mt-4\">\n                <div\n                  v-for=\"config in agentConfigs\"\n                  :key=\"config.id\"\n                  v-ripple\n                  class=\"d-inline-block agent-chip pa-2 my-2 mr-4 cursor-pointer text-body-1\"\n                  :class=\"{\n                    active:\n                      selectedAgentConfig &&\n                      selectedAgentConfig.id === config.id\n                  }\"\n                  @click=\"selectAgentConfig(config)\"\n                >\n                  <span>\n                    <span v-if=\"config.name\">{{ config.name }}</span>\n                    <span v-else>{{ config.id }}</span>\n                  </span>\n                  <span>\n                    <DeleteAgentConfig\n                      :config=\"config\"\n                      @refetch=\"handleDeletedAgentConfig\"\n                    />\n                  </span>\n                </div>\n              </div>\n            </v-col>\n            <v-col cols=\"12\" class=\"mt-2\">\n              <span class=\"text-subtitle-1 font-weight-light\"\n                >To set up an agent automation you need to add the\n                agent-config-id flag at agent registration. If you attach the\n                same id to multiple agents,</span\n              ><span class=\"mb-2 text-subtitle-1 font-weight-medium\">\n                Prefect will only notify you if all agents are unhealthy.</span\n              >\n            </v-col>\n          </v-row>\n\n          <div v-else>\n            <CreateAgentConfigForm\n              @close=\"showAgentConfigForm = false\"\n              @save=\"handleSaveAgentConfig\"\n            />\n          </div>\n        </div>\n\n        <v-card-actions v-if=\"!showAgentConfigForm\" class=\"px-0\">\n          <v-spacer></v-spacer>\n          <v-btn\n            text\n            title=\"Previous\"\n            class=\"mr-1\"\n            color=\"utilGrayMid\"\n            @click=\"switchStep('openAgentOrFlow')\"\n            ><span class=\"text-none\">Previous</span>\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            elevation=\"0\"\n            :disabled=\"!selectedAgentConfig\"\n            title=\"Next\"\n            @click=\"switchStep('selectDoThis')\"\n          >\n            <span class=\"text-none\">Next</span>\n          </v-btn>\n        </v-card-actions>\n      </div>\n      <!-- END CHOOSE AGENT CONFIG -->\n\n      <!-- SELECT FLOW -->\n      <div v-else-if=\"step.name === 'selectFlow'\" key=\"selectFlow\">\n        <div class=\"mb-2 text-subtitle-1 font-weight-light\">\n          Choose a flow:\n        </div>\n\n        <v-row>\n          <v-col cols=\"12\" class=\"pb-0\">\n            <!-- //need to fix v-model AND flow box color/style -->\n            <v-text-field\n              v-model=\"searchEntry\"\n              hide-details\n              single-line\n              solo\n              dense\n              flat\n              :placeholder=\"placeholderMessage\"\n              prepend-inner-icon=\"search\"\n              autocomplete=\"new-password\"\n              class=\"ml-n3\"\n            />\n            <v-checkbox\n              v-model=\"selectAll\"\n              class=\"mt-2 d-inline-block\"\n              dense\n              hide-details\n              label=\"Select All\"\n              :indeterminate=\"notAll\"\n            ></v-checkbox>\n          </v-col>\n        </v-row>\n        <v-row>\n          <v-col cols=\"12\">\n            <v-sheet\n              :height=\"formHeight\"\n              :style=\"{ 'overflow-y': 'auto', 'overflow-x': 'hidden' }\"\n            >\n              <v-row class=\"py-2\">\n                <v-col\n                  v-for=\"item in flows\"\n                  :key=\"item.id\"\n                  cols=\"6\"\n                  sm=\"3\"\n                  lg=\"2\"\n                >\n                  <div\n                    v-ripple\n                    class=\"chip-bigger d-flex align-center justify-start pa-2 cursor-pointer\"\n                    :class=\"{ active: includesFlow(item), flash: animated }\"\n                    @click=\"selectFlow(item)\"\n                  >\n                    <div style=\"width: auto;\" class=\"text-body-1 text-truncate\">\n                      <div class=\"text-caption\">{{ item.project.name }}</div>\n                      <div>\n                        <div style=\"width: 100%;\" class=\"text-truncate\">\n                          {{ item.name }}\n                        </div>\n                      </div>\n                    </div>\n                  </div>\n                </v-col>\n              </v-row>\n            </v-sheet>\n          </v-col>\n        </v-row>\n        <v-card-actions class=\"px-0\">\n          <v-spacer></v-spacer>\n          <v-btn\n            text\n            title=\"Previous\"\n            color=\"utilGrayMid\"\n            class=\"mr-1\"\n            @click=\"switchStep('openAgentOrFlow')\"\n            ><span class=\"text-none\">Previous</span>\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            elevation=\"0\"\n            :disabled=\"!selectedFlows.length\"\n            title=\"Next\"\n            @click=\"handleFlowNext\"\n            ><span class=\"text-none\">Next</span>\n          </v-btn>\n        </v-card-actions>\n      </div>\n      <!-- END SELECT FLOW -->\n\n      <!-- SELECT EVENT TYPE -->\n      <div v-else-if=\"step.name === 'selectEventType'\" key=\"selectEventType\">\n        <div class=\"mb-2 text-subtitle-1 font-weight-light\">\n          Choose an event:\n        </div>\n        <div>\n          <v-row>\n            <v-col cols=\"12\">\n              <v-btn\n                v-for=\"item in filteredFlowEventTypes\"\n                :key=\"item.enum\"\n                outlined\n                depressed\n                :color=\"\n                  flowEventType.name === item.name\n                    ? 'accentPink'\n                    : 'utilGrayMid'\n                \"\n                :class=\"{ flash: animated }\"\n                class=\"mr-4 cursor-pointer text-h6 font-weight-light remove--disabled\"\n                :input-value=\"flowEventType.name === item.name\"\n                :disabled=\"!hasPermission(item.permission)\"\n                @click=\"selectFlowEventType(item)\"\n                ><div class=\"text-center text-body-1 text-none\">\n                  {{ item.name }}\n                </div>\n\n                <UpgradeBadge v-if=\"!hasPermission(item.permission)\">\n                  <span class=\"font-weight-medium\">Flow SLA automations</span>\n                  are only available on Standard and Enterprise plans.\n                </UpgradeBadge>\n              </v-btn>\n            </v-col>\n          </v-row>\n        </div>\n        <v-card-actions>\n          <v-spacer></v-spacer>\n          <v-btn\n            text\n            title=\"Previous\"\n            color=\"utilGrayMid\"\n            class=\"mr-1\"\n            @click=\"switchStep('selectFlow')\"\n            ><span class=\"text-none\">Previous</span>\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            elevation=\"0\"\n            title=\"Next\"\n            :disabled=\"!flowEventType.enum\"\n            @click=\"selectFlowEventType()\"\n          >\n            <span class=\"text-none\">Next</span>\n          </v-btn>\n        </v-card-actions>\n      </div>\n      <!-- END SELECT EVENT TYPE -->\n\n      <!-- OPEN DURATION -->\n      <div v-else-if=\"step.name === 'openDuration'\" key=\"openDuration\">\n        <div class=\"mb-2 text-subtitle-1 font-weight-light\">\n          Choose SLA duration:\n        </div>\n        <div>\n          <v-col class=\"pa-0\" cols=\"12\" sm=\"6\" lg=\"3\">\n            <v-text-field\n              v-model=\"seconds\"\n              type=\"number\"\n              :rules=\"[rules.required, rules.notNull]\"\n              :class=\"{ flash: animated }\"\n              persistent-hint\n              outlined\n              hide-details\n              @keydown.enter=\"closeSeconds\"\n            ></v-text-field>\n          </v-col>\n        </div>\n        <v-card-actions>\n          <v-spacer></v-spacer>\n          <v-btn\n            text\n            title=\"Previous\"\n            class=\"mr-1\"\n            color=\"utilGrayMid\"\n            @click=\"switchStep('selectEventType')\"\n            ><span class=\"text-none\">Previous</span>\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            elevation=\"0\"\n            title=\"Next\"\n            @click=\"closeSeconds\"\n          >\n            <span class=\"text-none\">Next</span>\n          </v-btn>\n        </v-card-actions>\n      </div>\n      <!-- END OPEN DURATION -->\n\n      <!-- SELECT STATE -->\n      <div v-else-if=\"step.name === 'selectState'\" key=\"selectState\">\n        <div class=\"mb-2 text-subtitle-1 font-weight-light\">\n          Choose the states that trigger this automation:\n        </div>\n\n        <v-btn\n          v-for=\"item in stateGroups\"\n          :key=\"item.id\"\n          :color=\"dynamicStateGroup(item) ? 'accentPink' : null\"\n          depressed\n          max-width=\"300px\"\n          :title=\"\n            item == 'All'\n              ? `Select all states`\n              : `Select ${item} and all connected states`\n          \"\n          class=\"mr-2\"\n          :class=\"{ 'white--text': dynamicStateGroup(item), flash: animated }\"\n          @click=\"selectStateGroup(item)\"\n        >\n          {{ item }}\n        </v-btn>\n\n        <div v-if=\"dynamicStateGroup('Custom')\" class=\"mt-4\">\n          <div\n            v-for=\"item in states['All']\"\n            :key=\"item\"\n            v-ripple\n            class=\"d-inline-block chip-small pa-2 mr-4 my-2 cursor-pointer text-body-1\"\n            :class=\"{ active: chosenStates.includes(item), flash: animated }\"\n            @click=\"selectStates(item)\"\n          >\n            {{ item }}\n          </div>\n        </div>\n\n        <v-card-actions>\n          <v-spacer></v-spacer>\n          <v-btn\n            text\n            title=\"Previous\"\n            class=\"mr-1\"\n            color=\"utilGrayMid\"\n            @click=\"switchStep('selectEventType')\"\n            ><span class=\"text-none\">Previous</span>\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            elevation=\"0\"\n            title=\"Next\"\n            :disabled=\"chosenStates.length < 1\"\n            @click=\"\n              steps['selectState'].complete = true\n              switchStep('selectDoThis')\n            \"\n            ><span class=\"text-none\">Next</span>\n          </v-btn>\n        </v-card-actions>\n      </div>\n      <!-- END SELECT STATE -->\n\n      <!-- SELECT ACTION -->\n      <div v-else-if=\"step.name === 'selectDoThis'\" key=\"selectDoThis\">\n        <div class=\"mb-2 text-subtitle-1 font-weight-light\">\n          Choose an action:\n        </div>\n\n        <v-row v-if=\"!addAction\">\n          <v-col>\n            <v-btn small elevation=\"0\" color=\"primary\" @click=\"addNewAction\">\n              <v-icon small class=\"mr-2\">fa-plus fa-sm</v-icon>\n              <span class=\"text-none\">New</span>\n            </v-btn>\n          </v-col>\n        </v-row>\n\n        <v-row v-if=\"!addAction\" class=\"mt-8\" no-gutters>\n          <v-col cols=\"12\">\n            <div class=\"text-overline\">\n              System actions\n\n              <UpgradeBadge\n                v-if=\"\n                  systemActions.length && !hasPermission('feature:api-action')\n                \"\n                inline\n              >\n                <span class=\"font-weight-medium\">System actions</span> are only\n                available on Standard and Enterprise plans.\n              </UpgradeBadge>\n            </div>\n\n            <div\n              v-if=\"!systemActions.length\"\n              class=\"utilGrayMid--text text-body-2 font-weight-light\"\n            >\n              There are no system actions for this automation.\n            </div>\n\n            <div\n              v-for=\"item in systemActions\"\n              v-else\n              :key=\"item.id\"\n              v-ripple\n              class=\"chip-small pa-2 mr-4 my-2 cursor-pointer text-body-1 d-inline-block\"\n              :class=\"{\n                active: chosenAction && chosenAction.id === item.id,\n                disabled: !hasPermission('feature:api-action'),\n                flash: animated\n              }\"\n              @click=\"selectAction(item)\"\n            >\n              <v-icon small class=\"mr-2\">$prefect </v-icon\n              >{{ item.name || item.action_type }}\n            </div>\n          </v-col>\n        </v-row>\n\n        <v-row v-if=\"!addAction\" class=\"mt-8\" no-gutters>\n          <v-col cols=\"12\">\n            <div class=\"text-overline\">Your actions</div>\n\n            <div v-if=\"!customActions.length\">\n              You have no actions.\n            </div>\n            <div\n              v-for=\"item in customActions\"\n              v-else\n              :key=\"item.id\"\n              v-ripple\n              class=\"chip-small pa-2 mr-4 my-2 cursor-pointer text-body-1 d-inline-block\"\n              :class=\"{\n                active: chosenAction && chosenAction.id === item.id,\n                flash: animated\n              }\"\n              @click=\"selectAction(item)\"\n            >\n              <v-icon small class=\"mr-2\">{{\n                actionIcon(item.action_type) || 'fas fa-desktop'\n              }}</v-icon\n              >{{ item.name || item.action_type }}\n            </div>\n          </v-col>\n        </v-row>\n\n        <ConfirmDialog\n          :value=\"removeDoThisDialog\"\n          :loading=\"deleting\"\n          width=\"30vW\"\n          title=\"Are you sure you want to delete this?\"\n          type=\"error\"\n          @cancel=\"removeDoThisDialog = false\"\n          @confirm=\"removeDoThis\"\n          ><slot\n            ><span class=\"red--text\"\n              >This will also delete any associated Automations.</span\n            ></slot\n          ></ConfirmDialog\n        >\n        <AddAction\n          v-if=\"addAction\"\n          :event-type=\"flowEventType.enum || 'AGENT'\"\n          @close-action=\"addAction = false\"\n          @new-action=\"createAction\"\n        />\n\n        <v-card-actions v-if=\"!addAction\">\n          <v-spacer></v-spacer>\n          <v-btn\n            text\n            title=\"Previous\"\n            class=\"mr-1\"\n            color=\"utilGrayMid\"\n            @click=\"step = steps[previousStep]\"\n            ><span class=\"text-none\">Previous</span>\n          </v-btn>\n          <v-btn\n            color=\"primary\"\n            elevation=\"0\"\n            title=\"Save\"\n            :loading=\"saving\"\n            :disabled=\"!completeAction\"\n            @click=\"createHook\"\n            ><span class=\"text-none\">Save</span>\n          </v-btn>\n        </v-card-actions>\n      </div>\n      <!-- END SELECT ACTION -->\n    </transition>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.chip-bigger {\n  border-radius: 5px;\n  height: 60px;\n  position: relative;\n  transition: all 50ms;\n  width: 100%;\n\n  &::after {\n    border: 1px solid var(--v-utilGrayLight-base);\n    border-radius: 5px;\n    content: '';\n    height: 100%;\n    left: 0;\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  &.active {\n    &::after {\n      border: 2px solid;\n      border-color: var(--v-accentPink-base) !important;\n    }\n  }\n\n  &:hover,\n  &:focus {\n    background-color: rgba(0, 0, 0, 0.05);\n  }\n}\n.agent-chip {\n  border-radius: 5px;\n  max-width: fit-content;\n  border: 1px solid var(--v-utilGrayLight-base);\n\n  &.active {\n    border: 2px solid;\n    border-color: var(--v-accentPink-base) !important;\n  }\n}\n\n.chip-small {\n  border-radius: 5px;\n  max-width: fit-content;\n  position: relative;\n  transition: all 50ms;\n\n  &::after {\n    border: 1px solid var(--v-utilGrayLight-base);\n    border-radius: 5px;\n    content: '';\n    height: 100%;\n    left: 0;\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  &.active {\n    &::after {\n      border: 2px solid;\n      border-color: var(--v-accentPink-base) !important;\n    }\n  }\n\n  &:hover,\n  &:focus {\n    background-color: rgba(0, 0, 0, 0.05);\n  }\n\n  &.disabled {\n    color: var(--v-utilGrayLight-base) !important;\n    pointer-events: none !important;\n  }\n}\n\n.text-decoration-dotted-underline {\n  span {\n    &::after {\n      border-bottom: rgba(0, 0, 0, 0.4) dashed 1.75px;\n      bottom: 0;\n      content: '';\n      left: 0;\n      position: absolute;\n      width: 100%;\n    }\n  }\n}\n\n.flash {\n  &:not(:disabled):not(.disabled) {\n    animation: flash 1.5s;\n  }\n}\n\n@keyframes flash {\n  0%,\n  50%,\n  100% {\n    background-color: transparent;\n    border-color: currentColor !important;\n  }\n\n  25%,\n  75% {\n    background-color: rgba(59, 141, 255, 0.2);\n    border-color: var(--v-primary-base) !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/Automations/AutomationCard.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nimport { mapActions } from 'vuex'\nimport {\n  AUTOMATIONSTATES,\n  titleCasePresentTenseStates,\n  presentTenseStates\n} from '@/utils/automations'\nimport AddAutoCard from '@/pages/Dashboard/Automations/AddAutomationCard'\n\nexport default {\n  components: {\n    AddAutoCard\n  },\n  props: {\n    hook: {\n      type: Object,\n      required: true\n    },\n    canEdit: {\n      type: Boolean,\n      required: false,\n      default: false\n    }\n  },\n  data() {\n    return {\n      menu: false,\n      openEdit: false,\n      hookConfig: {},\n      showHook: true,\n      loadingHook: 0,\n      copiedText: {},\n      deletingHook: false,\n      hookDetails: {\n        FlowRunStateChangedEvent: {\n          type: 'any run from',\n          action: 'changes state',\n          icon: 'pi-flow'\n        },\n        FlowSLAFailedEvent: {\n          type: 'any run from',\n          action: 'SLA fails',\n          icon: 'pi-flow'\n        },\n        AgentSLAFailedEvent: {\n          type: 'agents',\n          icon: 'pi-agent',\n          action: 'are unhealthy'\n        },\n        SCHEDULED_NOT_STARTED: {\n          action: 'does not start'\n        },\n        STARTED_NOT_FINISHED: {\n          action: 'does not finish'\n        }\n      }\n    }\n  },\n  computed: {\n    includeTo() {\n      return this.hook.event_type === 'FlowRunStateChangedEvent'\n    },\n    isAgent() {\n      return !!this.hook?.event_tags?.agent_config_id\n    },\n    states() {\n      return this.hook?.event_tags?.state\n    },\n    agentConfigId() {\n      return this.hook?.event_tags?.agent_config_id[0]\n    },\n    includeSeconds() {\n      return this.hook?.event_type === 'FlowSLAFailedEvent'\n    },\n    hookType() {\n      const event = this.hook?.event_type\n      return `${this.hookDetails[event]?.type} `\n    },\n    hookDetail() {\n      const event = this.hook?.event_type\n      if (event === 'FlowRunStateChangedEvent') return ''\n      const hook = this.includeSeconds\n        ? `${this.hookDetails[this.flowConfig?.kind]?.action}`\n        : this.hookDetails[event]?.action\n      return hook\n    },\n    seconds() {\n      return this.flowConfig?.duration_seconds\n    },\n    hookStates() {\n      return this.states?.length === AUTOMATIONSTATES['All']?.length\n        ? 'changes to <span class=\"font-weight-bold\">any state</span>'\n        : this.states?.length != 1\n        ? 'changes to <span class=\"font-weight-bold\">any of these states</span>'\n        : presentTenseStates[this.states[0].toUpperCase()] ||\n          titleCasePresentTenseStates[this.states[0]]\n    },\n    hookAction() {\n      return this.hook?.action?.name || this.hook?.action?.action_type\n    },\n    hookName() {\n      const allFlows =\n        this.hook?.event_type === 'FlowRunStateChangedEvent' &&\n        !this.hook?.event_tags?.flow_group_id\n      const agentName =\n        this.agentConfig?.agents.length == 1\n          ? this.agentConfig.agents[0].name === 'agent'\n            ? this.agentConfig.agents[0].type\n            : this.agentConfig.agents[0].name\n          : this.agentConfig?.agents\n              .map((agent, index) => {\n                if (index === 0) {\n                  return agent.name === 'agent' ? agent.type : agent.name\n                } else {\n                  return agent.name === 'agent'\n                    ? `or ${agent.type}`\n                    : `or ${agent.name}`\n                }\n              })\n              .toString()\n      const name = this.hook.event_tags.agent_config_id\n        ? agentName\n        : this.hook?.event_tags?.flow_group_id?.length > 2 && this.flowName\n        ? `${this.flowName[0]?.name} and others`\n        : this.hook?.event_tags?.flow_group_id?.length == 2 && this.flowName\n        ? `${this.flowName[0].name} <span class=\"font-weight-regular\">or</span> ${this.flowName[1].name}`\n        : allFlows\n        ? 'any flow'\n        : this.flowName\n        ? this.flowName[0]?.name\n        : ''\n      return name\n    },\n    flowNameList() {\n      return this.flowName?.map(flow => `${flow.name} - ${flow.project.name}`)\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    copyToClipboard(value) {\n      this.copiedText = {}\n      this.copiedText[value] = true\n      navigator.clipboard.writeText(value)\n\n      setTimeout(() => {\n        this.copiedText = {}\n        this.copiedText[value] = false\n      }, 600)\n    },\n    stateVerb(state) {\n      return (\n        presentTenseStates[state] ||\n        titleCasePresentTenseStates[state] ||\n        'changes state'\n      )\n    },\n    async deleteHook() {\n      try {\n        this.deletingHook = true\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/delete-hook.gql'),\n          variables: {\n            hookId: this.hook.id\n          }\n        })\n        await this.handleRefetch()\n      } catch (error) {\n        const errString = `${error}`\n        this.setAlert({\n          alertShow: true,\n          alertMessage: errString,\n          alertType: 'error'\n        })\n      } finally {\n        this.deletingHook = false\n        this.$emit('done')\n      }\n    },\n    closeCard() {\n      this.openEdit = false\n    },\n    handleRefetch() {\n      this.$emit('refetch')\n    },\n    editHook() {\n      if (!this.canEdit) return\n      this.hookConfig = {\n        hook: this.hook,\n        flowConfig: this.flowConfig,\n        flowName: this.flowName,\n        flowNameList: this.flowNameList,\n        agentConfig: this.agentConfig\n      }\n      this.$emit('open-edit')\n      this.openEdit = true\n      // this.$emit('edit-action', {\n      //   hook: this.hook,\n      //   flowConfig: this.flowConfig,\n      //   flowName: this.flowName,\n      //   flowNameList: this.flowNameList,\n      //   agentConfig: this.agentConfig\n      // })\n    }\n  },\n  apollo: {\n    flowName: {\n      query: require('@/graphql/Automations/flows.gql'),\n      variables() {\n        return {\n          flowGroupIds: this.hook?.event_tags?.flow_group_id\n            ? this.hook?.event_tags?.flow_group_id\n            : this.flowConfig?.flow_groups?.map(flow => flow.flow_group_id)\n        }\n      },\n      fetchPolicy: 'no-cache',\n      skip() {\n        const skippy =\n          (!this.hook?.event_tags?.flow_group_id ||\n            !this.hook?.event_tags?.flow_group_id[0]) &&\n          !this.flowConfig?.flow_groups[0]?.flow_group_id\n        return skippy\n      },\n      loadingKey: 'loadingHook',\n      update: data => {\n        return data.flow\n      }\n    },\n    agentConfig: {\n      query: require('@/graphql/Automations/agent-config-by-pk.gql'),\n      variables() {\n        return {\n          agentConfigId: this.hook?.event_tags?.agent_config_id[0] || ''\n        }\n      },\n      loadingKey: 'loadingHook',\n      skip() {\n        return (\n          !this.hook?.event_tags?.agent_config_id ||\n          !this.hook?.event_tags?.agent_config_id[0]\n        )\n      },\n      fetchPolicy: 'no-cache',\n      update: data => data.agent_config_by_pk\n    },\n    flowConfig: {\n      query: require('@/graphql/Automations/flow-config-by-pk.gql'),\n      variables() {\n        return {\n          flowSLAConfigId: this.hook?.event_tags?.flow_sla_config_id\n            ? this.hook?.event_tags?.flow_sla_config_id[0]\n            : ''\n        }\n      },\n      loadingKey: 'loadingHook',\n      skip() {\n        return (\n          !this.hook?.event_tags?.flow_sla_config_id ||\n          !this.hook?.event_tags?.flow_sla_config_id[0]\n        )\n      },\n      update: data => {\n        return data.flow_sla_config_by_pk || []\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-skeleton-loader\n    v-if=\"loadingHook > 0\"\n    type=\"list-item-avatar-three-line\"\n  />\n  <AddAutoCard\n    v-else-if=\"openEdit\"\n    :hook-detail=\"hookConfig\"\n    @refetch-hooks=\"handleRefetch\"\n    @close=\"closeCard\"\n  />\n  <v-card\n    v-else-if=\"showHook\"\n    class=\"text-h6\"\n    :class=\"canEdit ? 'hover-card' : 'view-card'\"\n    outlined\n    @click=\"editHook\"\n  >\n    <v-card-text class=\"text-h6 font-weight-light\">\n      <v-row>\n        <v-col cols=\"11\" lg=\"11\" class=\"d-flex align-center justify-start\">\n          <v-icon color=\"accentPink\" class=\"pr-2\">\n            {{\n              hookDetails[hook.event_type]\n                ? hookDetails[hook.event_type].icon\n                : ''\n            }}\n          </v-icon>\n          <span>\n            When <span v-if=\"!hookName\">all </span>{{ hookType }}\n            <v-tooltip v-if=\"flowName\" top>\n              <template #activator=\"{ on }\">\n                <span class=\"font-weight-bold\" v-on=\"on\" v-html=\"hookName\" />\n              </template>\n              {{ flowNameList.join(', ') }}\n            </v-tooltip>\n            <span v-else class=\"font-weight-bold\" v-html=\"hookName\" />\n            <span v-if=\"isAgent\">\n              with\n              {{\n                agentConfig && agentConfig.name\n                  ? agentConfig.name\n                  : 'this config'\n              }}</span\n            >\n            {{ hookDetail\n            }}<span v-if=\"includeSeconds\">\n              for\n              <span class=\"font-weight-bold\">{{ seconds }} seconds</span>\n            </span>\n            <v-tooltip v-if=\"includeTo\" top>\n              <template #activator=\"{ on }\">\n                <span v-on=\"on\" v-html=\"hookStates\" />\n              </template>\n              <span>{{ states.join(', ') }}</span></v-tooltip\n            >, then <span class=\"font-weight-bold\">{{ hookAction }}</span\n            >.\n          </span>\n          <v-menu\n            v-if=\"isAgent\"\n            v-model=\"menu\"\n            :close-on-content-click=\"false\"\n            :open-on-hover=\"true\"\n          >\n            <template #activator=\"{ on, attrs }\">\n              <v-btn icon small v-bind=\"attrs\" v-on=\"on\">\n                <v-icon>info</v-icon>\n              </v-btn>\n            </template>\n\n            <v-card width=\"30vW\">\n              <v-card-text>\n                <div class=\"pb-2\">\n                  To set up an automation for your agent, you need to add the\n                  agent-config-id flag at agent registration.\n                </div>\n                <div> To use with a new agent, add this flag:</div>\n                <div class=\"pb-2\"\n                  ><v-tooltip bottom>\n                    <template #activator=\"{ on }\">\n                      <span\n                        class=\"cursor-pointer show-icon-hover-focus-only pa-2px\"\n                        role=\"button\"\n                        @click=\"\n                          copyToClipboard(`--agent-config-id ${agentConfigId}`)\n                        \"\n                        v-on=\"on\"\n                      >\n                        --agent-config-id {{ agentConfigId }}\n                      </span>\n                    </template>\n                    <span>\n                      Click to copy\n                    </span>\n                  </v-tooltip></div\n                >\n\n                <div>\n                  Note that if you attach the agent-config-id to multiple\n                  agents, Prefect will only notify you if\n                  <span class=\"font-weight-bold\">all</span> agents are\n                  unhealthy.</div\n                >\n              </v-card-text>\n            </v-card>\n          </v-menu>\n        </v-col>\n        <v-col class=\"text-right\" cols=\"1\" lg=\"1\">\n          <v-menu v-if=\"canEdit\" :close-on-content-click=\"false\" offset-y>\n            <template #activator=\"{ on, attrs }\">\n              <v-btn class=\"px-2\" text small fab v-bind=\"attrs\" v-on=\"on\">\n                <v-icon>more_horiz</v-icon>\n              </v-btn>\n            </template>\n            <v-card>\n              <div>\n                <v-btn\n                  :style=\"{ 'text-transform': 'none', 'min-width': '0px' }\"\n                  text\n                  :loading=\"deletingHook\"\n                  width=\"100%\"\n                  color=\"utilGrayDark\"\n                  @click.stop=\"deleteHook\"\n                >\n                  <v-icon class=\"pr-4\">delete</v-icon>\n                  Delete\n                </v-btn>\n              </div>\n            </v-card>\n          </v-menu>\n        </v-col>\n      </v-row></v-card-text\n    ></v-card\n  >\n</template>\n\n<style lang=\"scss\" scoped>\n.hover-card {\n  transition: box-shadow 150ms ease-in-out;\n\n  &:focus,\n  &:hover {\n    box-shadow: 0 2px 4px -1px rgb(0 0 0 / 20%), 0 4px 5px 0 rgb(0 0 0 / 14%),\n      0 1px 10px 0 rgb(0 0 0 / 12%) !important;\n  }\n}\n.view-card {\n  cursor: default;\n  pointer-events: none;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/Automations/Automations.vue",
    "content": "<script>\nimport AutoCard from '@/pages/Dashboard/Automations/AutomationCard'\nimport AddAutoCard from '@/pages/Dashboard/Automations/AddAutomationCard'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    AutoCard,\n    AddAutoCard\n  },\n  data() {\n    return {\n      loadingHook: 0,\n      closeCard: false,\n      loadCards: false,\n      editHook: null,\n      editAction: null,\n      addAction: false,\n      hookConfig: null,\n      sortedHooks: [],\n      hookDetails: {\n        RunStateChangedEvent: {\n          type: 'flow',\n          action: 'changes',\n          icon: 'pi-flow'\n        },\n        FlowSLAFailedEvent: {\n          type: 'flow',\n          action: 'SLA fails',\n          icon: 'pi-flow'\n        }\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['permissions', 'hasPermission'])\n  },\n  watch: {\n    hooks() {\n      this.sortHooks()\n    }\n  },\n  methods: {\n    async handleRefetch() {\n      await this.$apollo.queries.hooks.refetch()\n    },\n    sortHooks() {\n      this.loadCards = true\n      const hooks = this.hooks ? [...this.hooks] : []\n      const sorted = hooks.sort(\n        (a, b) => new Date(b.created) - new Date(a.created)\n      )\n      this.sortedHooks = sorted\n      this.loadCards = false\n    },\n    handleEdit(hook, index) {\n      this.editHook = hook\n      this.editAction = index\n    },\n    handleRefresh() {\n      this.closeCard = true\n      this.$nextTick(() => (this.closeCard = false))\n    },\n    handleDone() {\n      this.sortHooks()\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.hooks.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    hooks: {\n      query() {\n        return require('@/graphql/Automations/hooks.gql')\n      },\n      variables() {\n        return {}\n      },\n      loadingKey: 'loadingHook',\n      pollInterval: 5000,\n      update: data => data?.hook\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    v-if=\"!hasPermission('read', 'hook')\"\n    v-intersect=\"{ handler: onIntersect }\"\n  >\n    <v-row>\n      <v-col cols=\"12\" class=\"text-center text-h6 pa-12\">\n        You do not have access to Automations. If you'd like to be able to\n        create automations that notify you (or even cancel your run) when\n        there's a change in your agent or a run,\n        <router-link :to=\"{ name: 'plans' }\">upgrade</router-link> your account.\n      </v-col>\n    </v-row>\n  </div>\n  <div v-else>\n    <v-row>\n      <v-col class=\"pb-0\" cols=\"12\">\n        <div class=\"text-overline\">New Automation</div>\n      </v-col>\n\n      <v-col cols=\"12\">\n        <AddAutoCard\n          v-if=\"!!hasPermission('create', 'hook') && !closeCard\"\n          @refresh=\"handleRefresh\"\n          @refetch=\"handleRefetch\"\n          @saving=\"loadCards = true\"\n          @done=\"handleDone\"\n        />\n      </v-col>\n    </v-row>\n\n    <v-divider class=\"my-10 mx-12\" />\n\n    <v-row>\n      <v-col cols=\"12\" class=\"pb-0\">\n        <div class=\"text-overline\">Automations</div>\n      </v-col>\n      <v-progress-circular\n        v-if=\"!sortedHooks.length && loadingHook > 0\"\n        class=\"mx-auto my-4\"\n        indeterminate\n        color=\"primary\"\n      />\n\n      <v-col v-for=\"(hook, i) in sortedHooks\" :key=\"i\" cols=\"12\">\n        <v-skeleton-loader\n          v-if=\"loadingHook > 0 || loadCards\"\n          type=\"list-item-avatar-three-line\"\n          height=\"72\"\n        ></v-skeleton-loader\n        ><AutoCard\n          v-else\n          :hook=\"hook\"\n          :can-edit=\"!!hasPermission('create', 'hook')\"\n          @open-edit=\"handleEdit(hook, i)\"\n          @refetch=\"handleRefetch\"\n          @done=\"handleDone\"\n        />\n      </v-col>\n    </v-row>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/Dashboard/Automations/CreateAgentConfigForm.vue",
    "content": "<script>\nimport { mapActions } from 'vuex'\nexport default {\n  data() {\n    return {\n      loading: false,\n      name: null\n    }\n  },\n  computed: {\n    disabled() {\n      return !this.name\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    handleClose() {\n      this.$emit('close')\n    },\n    async handleSave() {\n      this.loading = true\n\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-agent-config.gql'),\n          variables: {\n            input: {\n              name: this.name\n            }\n          }\n        })\n\n        this.$emit('save', data?.create_agent_config)\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `${e}`,\n          alertType: 'error'\n        })\n      } finally {\n        this.loading = false\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div>\n      <v-col class=\"mb-4 pa-0\" cols=\"12\" sm=\"6\" lg=\"3\">\n        <v-text-field\n          v-model=\"name\"\n          outlined\n          hide-details\n          dense\n          label=\"Config name\"\n        />\n      </v-col>\n    </div>\n    <v-btn\n      text\n      color=\"utilGrayMid\"\n      class=\"light-weight-text mr-1 px-2\"\n      @click=\"handleClose\"\n    >\n      <span style=\"text-transform: none;\">Cancel</span>\n    </v-btn>\n    <v-btn\n      color=\"primary\"\n      elevation=\"0\"\n      :loading=\"loading\"\n      :disabled=\"disabled\"\n      @click=\"handleSave\"\n    >\n      <span style=\"text-transform: none;\">Save</span>\n    </v-btn>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/Dashboard/Automations/DeleteAgentConfig.vue",
    "content": "<script>\nimport { mapActions } from 'vuex'\n\nexport default {\n  props: {\n    config: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    return {\n      deletingConfig: false,\n      copiedText: {}\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    copyToClipboard(value) {\n      this.copiedText = {}\n      this.copiedText[value] = true\n      navigator.clipboard.writeText(value)\n\n      setTimeout(() => {\n        this.copiedText = {}\n        this.copiedText[value] = false\n      }, 600)\n    },\n    async deleteConfig(id) {\n      this.deletingConfig = true\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Automations/delete-agent-config.gql'),\n          variables: {\n            agentConfigInput: {\n              agent_config_id: id\n            }\n          }\n        })\n        this.setAlert({\n          alertShow: true,\n          alertMessage: 'Agent config deleted',\n          alertType: 'info'\n        })\n      } catch (error) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `${error}`,\n          alertType: 'error'\n        })\n      } finally {\n        this.$emit('refetch', id)\n        this.deletingConfig = false\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-menu :close-on-content-click=\"false\" offset-y>\n    <template #activator=\"{ on, attrs }\">\n      <v-btn class=\"px-2\" text small fab v-bind=\"attrs\" v-on=\"on\">\n        <v-icon>more_horiz</v-icon>\n      </v-btn>\n    </template>\n    <v-card class=\"pa-4\">\n      <div>\n        <v-btn\n          text\n          plain\n          class=\"cursor-pointer show-icon-hover-focus-only pa-0 text-subtitle-1\"\n          role=\"button\"\n          @click=\"copyToClipboard(`--agent-config-id ${config.id}`)\"\n        >\n          <v-icon color=\"primary\" class=\"mr-2\">\n            {{\n              copiedText[`--agent-config-id ${config.id}`]\n                ? 'check'\n                : 'file_copy'\n            }}\n          </v-icon>\n          <span class=\"text-subtitle-1\" style=\"text-transform: none;\">\n            --agent-config-id {{ config.id }}\n          </span>\n        </v-btn>\n      </div>\n      <div class=\"mt-2\">\n        <v-btn\n          text\n          plain\n          class=\"cursor-pointer show-icon-hover-focus-only pa-0 text-subtitle-1\"\n          role=\"button\"\n          :loading=\"deletingConfig\"\n          @click=\"deleteConfig(config.id)\"\n        >\n          <v-icon color=\"red\" class=\"mr-2\">\n            delete\n          </v-icon>\n          <span class=\"text-subtitle-1\" style=\"text-transform: none;\">\n            Delete\n          </span>\n        </v-btn>\n      </div>\n    </v-card>\n  </v-menu>\n</template>\n"
  },
  {
    "path": "src/pages/Dashboard/Dashboard.vue",
    "content": "<script>\nimport Calendar from '@/pages/Calendar/Calendar-View'\nimport AgentsTile from '@/pages/Dashboard/Agents-Tile'\nimport BreadCrumbs from '@/components/BreadCrumbs'\nimport FailedFlowsTile from '@/pages/Dashboard/FailedFlows-Tile'\nimport FlowRunHistoryTile from '@/pages/Dashboard/FlowRunHistory-Tile'\nimport FlowTableTile from '@/pages/Dashboard/FlowTable-Tile'\nimport Automations from '@/pages/Dashboard/Automations/Automations'\nimport InProgressTile from '@/pages/Dashboard/InProgress-Tile'\nimport NavTabBar from '@/components/NavTabBar'\nimport NotificationsTile from '@/pages/Dashboard/Notifications-Tile'\nimport ProjectSelector from '@/pages/Dashboard/Project-Selector'\nimport SummaryTile from '@/pages/Dashboard/Summary-Tile'\nimport UpcomingRunsTile from '@/pages/Dashboard/UpcomingRuns-Tile'\nimport UpgradeUsageTile from '@/pages/Dashboard/UsageTiles/UpgradeUsage-Tile'\nimport SubPageNav from '@/layouts/SubPageNav'\nimport { mapGetters, mapActions } from 'vuex'\nimport gql from 'graphql-tag'\n\nconst serverTabs = [\n  {\n    name: 'Overview',\n    target: 'overview',\n    icon: 'view_quilt'\n  },\n  {\n    name: 'Flows',\n    target: 'flows',\n    icon: 'pi-flow'\n  },\n  {\n    name: 'Calendar',\n    target: 'calendar',\n    icon: 'event',\n    iconSize: 'small'\n  }\n]\n\nconst cloudTabs = [\n  {\n    name: 'Automations',\n    target: 'automations',\n    icon: 'fad fa-random'\n  }\n]\n\nexport default {\n  metaInfo() {\n    return {\n      titleTemplate: `%s | ${this.project ? this.project.name : 'All Projects'}`\n    }\n  },\n  components: {\n    Calendar,\n    Automations,\n    AgentsTile,\n    BreadCrumbs,\n    FailedFlowsTile,\n    FlowTableTile,\n    InProgressTile,\n    NavTabBar,\n    NotificationsTile,\n    ProjectSelector,\n    SubPageNav,\n    SummaryTile,\n    FlowRunHistoryTile,\n    UpcomingRunsTile,\n    UpgradeUsageTile\n  },\n  async beforeRouteLeave(to, from, next) {\n    if (to.name == 'project') {\n      await this.activateProject(to.params.id)\n    } else {\n      this.resetActiveData()\n    }\n\n    if (!to.query?.notification_id) return next()\n\n    try {\n      if (to.query?.notification_id) {\n        let mutationString = gql`\n        mutation MarkMessagesAsRead {\n          mark_message_as_read(input: { message_id: \"${to.query.notification_id}\" }) {\n            success\n            error\n          }\n        }\n      `\n        await this.$apollo.mutate({\n          mutation: mutationString\n        })\n\n        delete to.query.notification_id\n      }\n    } finally {\n      next({ name: to.name, params: to.params })\n    }\n  },\n  data() {\n    return {\n      key: 0,\n      loading: 0,\n      loadedTiles: 0,\n      numberOfTiles: 10,\n      projectId: this.$route.params.id,\n      refreshTimeout: null\n    }\n  },\n  computed: {\n    ...mapGetters('alert', ['getAlert']),\n    ...mapGetters('api', ['backend', 'isCloud', 'connected']),\n    ...mapGetters('data', ['activeProject']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['license']),\n    project() {\n      return this.activeProject\n    },\n    tabs() {\n      return [...serverTabs, ...(this.isCloud ? cloudTabs : [])]\n    },\n    includeProjects() {\n      return this.tab != 'automations' && this.tab != 'calendar'\n    },\n    tab() {\n      if ('flows' in this.$route.query) return 'flows'\n      if ('calendar' in this.$route.query) return 'calendar'\n      if ('automations' in this.$route.query) return 'automations'\n      return 'overview'\n    }\n  },\n  watch: {\n    backend() {\n      this.loadedTiles = 0\n\n      this.refreshTimeout = setTimeout(() => {\n        this.refresh()\n        clearTimeout(this.refreshTimeout)\n      }, 3000)\n    },\n    'tenant.id'(val, old) {\n      if (val && val !== old) {\n        this.loadedTiles = 0\n        clearTimeout(this.refreshTimeout)\n        this.refresh()\n      }\n    },\n    license(val) {\n      if (val?.id) {\n        this.loadedTiles = 0\n        clearTimeout(this.refreshTimeout)\n        this.refresh()\n      }\n    }\n  },\n  async beforeMount() {\n    if (this.$route.name == 'project') {\n      await this.activateProject(this.$route.params.id)\n    }\n  },\n  mounted() {\n    this.refresh()\n  },\n  methods: {\n    ...mapActions('data', ['activateProject', 'resetActiveData']),\n    handleAgentDetailsClick() {\n      this.$router.push({\n        name: 'agents',\n        params: { tenant: this.tenant.slug, id: this.projectId }\n      })\n    },\n    handleProjectSelect(val) {\n      this.projectId = val\n      if (this.projectId?.length > 0) this.activateProject(this.projectId)\n    },\n    refresh() {\n      let start\n\n      const animationDuration = 150\n\n      const loadTiles = time => {\n        if (!start) start = time\n\n        const elapsed = time - start\n\n        if (elapsed > this.loadedTiles * animationDuration + 500) {\n          this.loadedTiles++\n        }\n\n        if (this.loadedTiles <= this.numberOfTiles) {\n          requestAnimationFrame(loadTiles)\n        }\n      }\n\n      requestAnimationFrame(loadTiles)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet color=\"appBackground\">\n    <SubPageNav\n      :icon=\"projectId && project ? 'pi-project' : 'view_quilt'\"\n      :page-type=\"projectId && project ? 'Project' : 'Dashboard'\"\n    >\n      <span\n        slot=\"page-title\"\n        :style=\"\n          loading > 0\n            ? {\n                display: 'block',\n                height: '28px',\n                overflow: 'hidden'\n              }\n            : $vuetify.breakpoint.smAndDown && {\n                display: 'inline'\n              }\n        \"\n      >\n        <span v-if=\"loading === 0\">\n          {{ projectId && project ? project.name : tenant.name }}\n        </span>\n        <span v-else>\n          <v-skeleton-loader type=\"heading\" tile></v-skeleton-loader>\n        </span>\n      </span>\n\n      <span\n        v-if=\"projectId && project\"\n        slot=\"breadcrumbs\"\n        :style=\"\n          $vuetify.breakpoint.smAndDown && {\n            display: 'inline',\n            'font-size': '0.875rem'\n          }\n        \"\n      >\n        <BreadCrumbs\n          :crumbs=\"[\n            {\n              route: {\n                name: 'dashboard',\n                params: { tenant: tenant.slug }\n              },\n              text: tenant.name\n            }\n          ]\"\n        />\n      </span>\n\n      <span\n        slot=\"page-actions\"\n        :class=\"{ 'mx-auto': $vuetify.breakpoint.xsOnly }\"\n      >\n        <v-skeleton-loader\n          v-if=\"includeProjects\"\n          slot=\"row-0\"\n          :loading=\"loadedTiles < 4\"\n          type=\"text\"\n          transition=\"quick-fade\"\n          tile\n        >\n          <ProjectSelector @project-select=\"handleProjectSelect\" />\n        </v-skeleton-loader>\n      </span>\n      <span slot=\"tabs\" style=\"width: 100%;\">\n        <NavTabBar :tabs=\"tabs\" page=\"dashboard\" />\n      </span>\n    </SubPageNav>\n\n    <v-tabs-items\n      v-model=\"tab\"\n      class=\"px-6 mx-auto tabs-border-bottom tab-full-height\"\n      :style=\"{\n        'padding-top': $vuetify.breakpoint.smOnly ? '80px' : '130px'\n      }\"\n      mandatory\n    >\n      <v-tab-item\n        class=\"tab-full-height pa-0\"\n        value=\"overview\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <div class=\"tile-grid my-4\">\n          <v-skeleton-loader\n            :loading=\"loadedTiles < 7\"\n            type=\"image\"\n            height=\"184px\"\n            transition=\"quick-fade\"\n            class=\"tile-container span-full span-row-1\"\n            tile\n          >\n            <FlowRunHistoryTile\n              :project-id=\"projectId\"\n              :visible=\"tab == 'overview'\"\n            />\n          </v-skeleton-loader>\n\n          <v-skeleton-loader\n            :loading=\"loadedTiles < 2\"\n            type=\"image\"\n            height=\"100%\"\n            transition=\"quick-fade\"\n            class=\"tile-container span-row-2\"\n            tile\n          >\n            <SummaryTile :project-id=\"projectId\" full-height />\n          </v-skeleton-loader>\n\n          <v-skeleton-loader\n            :loading=\"loadedTiles < 7\"\n            type=\"image\"\n            height=\"100%\"\n            transition=\"quick-fade\"\n            class=\"tile-container\"\n            tile\n          >\n            <FailedFlowsTile :project-id=\"projectId\" />\n          </v-skeleton-loader>\n\n          <v-skeleton-loader\n            :loading=\"loadedTiles < 1\"\n            type=\"image\"\n            height=\"100%\"\n            transition=\"quick-fade\"\n            class=\"tile-container\"\n            tile\n          >\n            <UpcomingRunsTile :key=\"key\" :project-id=\"projectId\" full-height />\n          </v-skeleton-loader>\n\n          <v-skeleton-loader\n            v-if=\"\n              isCloud &&\n                license &&\n                license.terms.is_self_serve &&\n                !license.terms.is_usage_based\n            \"\n            :loading=\"loadedTiles < 6 || usageTile == 'loading'\"\n            type=\"image\"\n            height=\"100%\"\n            transition=\"quick-fade\"\n            class=\"tile-container span-row-1\"\n            tile\n          >\n            <UpgradeUsageTile />\n          </v-skeleton-loader>\n\n          <v-skeleton-loader\n            :loading=\"loadedTiles < 3\"\n            type=\"image\"\n            height=\"100%\"\n            transition=\"quick-fade\"\n            class=\"tile-container\"\n            tile\n          >\n            <InProgressTile :project-id=\"projectId\" full-height />\n          </v-skeleton-loader>\n\n          <v-skeleton-loader\n            :loading=\"loadedTiles < 4\"\n            type=\"image\"\n            height=\"100%\"\n            transition=\"quick-fade\"\n            class=\"tile-container\"\n            tile\n          >\n            <AgentsTile\n              full-height\n              @view-details-clicked=\"handleAgentDetailsClick\"\n            />\n          </v-skeleton-loader>\n\n          <v-skeleton-loader\n            :loading=\"loadedTiles < 5\"\n            type=\"image\"\n            height=\"100%\"\n            transition=\"quick-fade\"\n            class=\"tile-container\"\n            tile\n          >\n            <NotificationsTile :project-id=\"projectId\" full-height />\n          </v-skeleton-loader>\n        </div>\n      </v-tab-item>\n\n      <v-tab-item\n        class=\"tab-full-height\"\n        value=\"flows\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <FlowTableTile\n          v-if=\"loadedTiles > 8\"\n          class=\"mx-3 my-6\"\n          :project-id=\"projectId\"\n        />\n      </v-tab-item>\n\n      <v-tab-item\n        class=\"tab-full-height\"\n        value=\"calendar\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <Calendar v-if=\"loadedTiles > 9\" class=\"mx-3 my-6\" />\n      </v-tab-item>\n\n      <v-tab-item\n        class=\"tab-full-height\"\n        value=\"automations\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <Automations v-if=\"loadedTiles > 10\" class=\"mx-3 my-6\" />\n      </v-tab-item>\n\n      <v-tab-item\n        class=\"tab-full-height\"\n        value=\"analytics\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        Nothing to see here :)\n      </v-tab-item>\n    </v-tabs-items>\n\n    <v-bottom-navigation v-if=\"$vuetify.breakpoint.smAndDown\" app fixed>\n      <v-btn\n        v-for=\"tb in tabs\"\n        :key=\"tb.target\"\n        @click=\"$router.replace({ query: { [tb.target]: null } })\"\n      >\n        {{ tb.name }}\n        <v-icon>{{ tb.icon }}</v-icon>\n      </v-btn>\n    </v-bottom-navigation>\n  </v-sheet>\n</template>\n\n<style lang=\"scss\" scoped>\n$cellsize: 412px;\n$rowsize: 153px;\n$guttersize: 24px;\n$spans: 1, 2, 3, 4, 5, 6;\n\n.tile-grid {\n  column-gap: $guttersize;\n  display: grid;\n  grid-auto-flow: row dense;\n  grid-auto-rows: minmax($rowsize, auto);\n  grid-template-columns: repeat(auto-fit, minmax($cellsize, 1fr));\n  row-gap: $guttersize;\n  width: 100%;\n}\n\n.tile-container {\n  grid-column: span 1;\n  grid-row: span 2;\n\n  @each $span in $spans {\n    &.span-row-#{$span} {\n      grid-row: span $span;\n    }\n  }\n\n  &.span-full {\n    grid-column: 1 / -1;\n  }\n}\n</style>\n\n<style lang=\"scss\">\n// stylelint-disable\n.v-skeleton-loader__image {\n  height: inherit !important;\n}\n// stylelint-enable\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/FailedFlows-Tile.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport { roundedOneAgo } from '@/utils/dateTime'\nimport CardTitle from '@/components/Card-Title'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    CardTitle\n  },\n  mixins: [formatTime],\n  props: {\n    projectId: {\n      type: String,\n      default: null\n    }\n  },\n  data() {\n    return {\n      failures: null,\n      loading: 0,\n      queryError: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    hasError() {\n      return this.queryError && !this.failures\n    },\n    stateColor() {\n      if (this.loading > 0) return 'secondaryGray'\n      if (this.hasError) return 'gray'\n      if (this.failureCount > 0) return 'failRed'\n      return 'Success'\n    },\n    cardTitle() {\n      if (this.hasError) return 'Failed flows'\n      return `${this.failureCount} failed flows`\n    },\n    failureCount() {\n      if (this.failures?.length) {\n        return this.failures.length\n      }\n      return 0\n    }\n  },\n  watch: {\n    tenant(val) {\n      this.failures = []\n\n      if (val) {\n        this.failures = []\n\n        setTimeout(() => {\n          // this.$apollo.queries.failuresCount.refetch()\n          this.$apollo.queries.failures.refetch()\n        }, 1000)\n      }\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.failures.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    failures: {\n      query: require('@/graphql/Dashboard/flow-failures.gql'),\n      variables() {\n        return {\n          projectId: this.projectId ? this.projectId : null,\n          heartbeat: roundedOneAgo(this.selectedDateFilter)\n        }\n      },\n      loadingKey: 'loading',\n      error() {\n        this.queryError = true\n      },\n      pollInterval: 30000,\n      update: data => {\n        return data.flow_run.sort((a, b) => {\n          if (new Date(a.state_timestamp) < new Date(b.state_timestamp)) {\n            return 1\n          } else {\n            return -1\n          }\n        })\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"py-2 position-relative\"\n    tile\n    style=\"height: 100%;\"\n  >\n    <v-system-bar :color=\"stateColor\" :height=\"5\" absolute>\n      <!-- We should include a state icon here when we've got those -->\n      <!-- <v-icon>{{ flow.flow_runs[0].state }}</v-icon> -->\n    </v-system-bar>\n\n    <v-tooltip top>\n      <template #activator=\"{ on }\">\n        <CardTitle\n          :title=\"cardTitle\"\n          icon=\"pi-flow\"\n          :icon-color=\"stateColor\"\n          :loading=\"loading > 0\"\n        >\n          <div slot=\"action\" v-on=\"on\">\n            <v-select\n              data-public\n              v-model=\"selectedDateFilter\"\n              class=\"time-interval-picker\"\n              :items=\"shortDateFilters\"\n              dense\n              solo\n              item-text=\"name\"\n              item-value=\"value\"\n              hide-details\n              flat\n            >\n              <template #prepend-inner>\n                <v-icon color=\"utilGrayDark\" x-small>\n                  history\n                </v-icon>\n              </template>\n            </v-select>\n          </div>\n        </CardTitle>\n      </template>\n      <span>\n        Filter on flow run scheduled start time\n      </span>\n    </v-tooltip>\n\n    <v-card-text class=\"pa-0\">\n      <v-list class=\"card-content\">\n        <v-slide-y-reverse-transition v-if=\"loading > 0\" leave-absolute group>\n          <v-skeleton-loader key=\"skeleton\" type=\"list-item-three-line\">\n          </v-skeleton-loader>\n        </v-slide-y-reverse-transition>\n        <v-slide-y-reverse-transition v-else-if=\"hasError\" leave-absolute group>\n          <v-list-item key=\"error\" color=\"grey\">\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon class=\"error--text\">\n                error\n              </v-icon>\n            </v-list-item-avatar>\n            <v-list-item-content class=\"my-0 py-3\">\n              <div\n                class=\"d-inline-block text-subtitle-1 font-weight-light\"\n                style=\"line-height: 1.25rem;\"\n              >\n                Something went wrong while trying to fetch failed flow\n                information. Please try refreshing your page. If this error\n                persists, return to this page after a few minutes.\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n        </v-slide-y-reverse-transition>\n\n        <v-slide-y-reverse-transition\n          v-else-if=\"failureCount\"\n          leave-absolute\n          group\n        >\n          <v-lazy\n            v-for=\"failure in failures\"\n            :key=\"failure.flow_id\"\n            :options=\"{\n              threshold: 0.75\n            }\"\n            min-height=\"40px\"\n            transition=\"slide-y\"\n          >\n            <v-list-item\n              :to=\"{\n                name: 'flow',\n                params: { id: failure.flow.flow_group_id }\n              }\"\n            >\n              <v-list-item-content>\n                <v-list-item-title>\n                  <div\n                    class=\"text-truncate d-inline-block\"\n                    style=\"max-width: 95%;\"\n                  >\n                    {{ failure.flow.name }}\n                  </div>\n                </v-list-item-title>\n                <v-list-item-subtitle>\n                  {{ formatDateTime(failure.state_timestamp) }}\n                </v-list-item-subtitle>\n              </v-list-item-content>\n              <v-list-item-avatar>\n                <v-icon>arrow_right</v-icon>\n              </v-list-item-avatar>\n            </v-list-item>\n          </v-lazy>\n        </v-slide-y-reverse-transition>\n        <v-slide-y-transition v-else leave-absolute group>\n          <v-list-item key=\"no-data\" color=\"grey\">\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon class=\"green--text\">check</v-icon>\n            </v-list-item-avatar>\n            <v-list-item-content class=\"my-0 py-0\">\n              <div\n                class=\"text-subtitle-1 font-weight-light\"\n                style=\"line-height: 1.25rem;\"\n              >\n                No reported failures in the last {{ selectedDateFilter }}...\n                Everything looks good!\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n        </v-slide-y-transition>\n      </v-list>\n      <div v-if=\"failures && failures.length > 3\" class=\"pa-0 footer\"> </div>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.time-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n\n.card-content {\n  height: 100%;\n  max-height: 254px;\n  overflow-y: auto;\n}\n\n.footer {\n  background-image: linear-gradient(transparent, 60%, rgba(0, 0, 0, 0.1));\n  bottom: 6px;\n  height: 6px !important;\n  pointer-events: none;\n  position: absolute;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/FailedTasks-Tile.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport { roundedOneAgo } from '@/utils/dateTime'\nimport CardTitle from '@/components/Card-Title'\nimport TaskItem from '@/pages/Dashboard/Task-Item'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    CardTitle,\n    TaskItem\n  },\n  mixins: [formatTime],\n  props: {\n    projectId: {\n      type: String,\n      default: null\n    }\n  },\n  data() {\n    return {\n      failures: null,\n      flowIds: [],\n      loading: 0,\n      queryError: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    hasError() {\n      return this.queryError && !this.failures\n    },\n    stateColor() {\n      if (this.loading > 0) return 'secondaryGray'\n      if (this.hasError) return 'gray'\n      if (this.failureCount > 0) return 'failRed'\n      return 'Success'\n    },\n    cardTitle() {\n      if (this.hasError) return 'Failed Tasks'\n      return `${this.failureCount} Failed Tasks`\n    },\n    displayFailures() {\n      if (!this.failures) return null\n      const sorted = this.sortFailures(this.failures)\n      return sorted\n    },\n    failureCount() {\n      return this.failures?.length\n    }\n  },\n  watch: {\n    tenant(val) {\n      this.failures = []\n\n      if (val) {\n        this.failures = []\n\n        setTimeout(() => {\n          // this.$apollo.queries.failuresCount.refetch()\n          this.$apollo.queries.failures.refetch()\n        }, 1000)\n      }\n    }\n  },\n  methods: {\n    failedRuns(failure) {\n      const failedRuns = failure.filter(run => {\n        return run.state === 'Failed'\n      })\n      return failedRuns.length\n    },\n    totalRuns(failure) {\n      return failure.length\n    },\n    sortFailures(failures) {\n      return failures.sort((taskRunA, taskRunB) => {\n        if (new Date(taskRunA.updated) < new Date(taskRunB.updated)) {\n          return -1\n        } else {\n          return 1\n        }\n      })\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.failures.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    failures: {\n      query: require('@/graphql/Dashboard/task-failures.gql'),\n      variables() {\n        return {\n          heartbeat: roundedOneAgo(this.selectedDateFilter)\n        }\n      },\n      loadingKey: 'loading',\n      error() {\n        this.failures = null\n        this.queryError = true\n      },\n      pollInterval: 30000,\n      update: data => {\n        return data.task_run\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"py-2\"\n    tile\n    style=\"height: 100%;\"\n  >\n    <v-system-bar :color=\"stateColor\" :height=\"5\" absolute>\n      <!-- We should include a state icon here when we've got those -->\n      <!-- <v-icon>{{ flow.flow_runs[0].state }}</v-icon> -->\n    </v-system-bar>\n\n    <v-tooltip top>\n      <template #activator=\"{ on }\">\n        <CardTitle\n          :title=\"cardTitle\"\n          icon=\"pi-task\"\n          :icon-color=\"stateColor\"\n          :loading=\"loading > 0\"\n        >\n          <div slot=\"action\" v-on=\"on\">\n            <v-select\n              data-public\n              v-model=\"selectedDateFilter\"\n              class=\"time-interval-picker\"\n              :items=\"shortDateFilters\"\n              dense\n              solo\n              item-text=\"name\"\n              item-value=\"value\"\n              hide-details\n              flat\n            >\n              <template #prepend-inner>\n                <v-icon color=\"black\" x-small>\n                  history\n                </v-icon>\n              </template>\n            </v-select>\n          </div>\n        </CardTitle>\n      </template>\n      <span>\n        Filter by when flows were last updated\n      </span>\n    </v-tooltip>\n\n    <v-card-text class=\"error-card-content pa-0\">\n      <v-list dense>\n        <v-slide-y-reverse-transition v-if=\"loading > 0\" leave-absolute group>\n          <v-skeleton-loader key=\"skeleton\" type=\"list-item-three-line\">\n          </v-skeleton-loader>\n        </v-slide-y-reverse-transition>\n        <v-slide-y-reverse-transition v-else-if=\"hasError\" leave-absolute group>\n          <v-list-item key=\"error\" color=\"grey\">\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon class=\"error--text\">\n                error\n              </v-icon>\n            </v-list-item-avatar>\n            <v-list-item-content class=\"my-0 py-3\">\n              <div\n                class=\"d-inline-block text-subtitle-1 font-weight-light\"\n                style=\"line-height: 1.25rem;\"\n              >\n                Something went wrong while trying to fetch Task failures\n                information. Please try refreshing your page. If this error\n                persists, return to this page after a few minutes.\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n        </v-slide-y-reverse-transition>\n\n        <v-slide-y-reverse-transition\n          v-else-if=\"failureCount > 0\"\n          leave-absolute\n          group\n        >\n          <v-lazy\n            v-for=\"failure in displayFailures\"\n            :key=\"failure.id\"\n            :options=\"{\n              threshold: 0.75\n            }\"\n            min-height=\"40px\"\n            transition=\"fade\"\n          >\n            <TaskItem :failure=\"failure\" />\n          </v-lazy>\n        </v-slide-y-reverse-transition>\n        <v-slide-y-transition v-else leave-absolute group>\n          <v-list-item key=\"no-data\" color=\"grey\">\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon class=\"green--text\">check</v-icon>\n            </v-list-item-avatar>\n            <v-list-item-content class=\"my-0 py-0\">\n              <div\n                class=\"text-subtitle-1 font-weight-light\"\n                style=\"line-height: 1.25rem;\"\n              >\n                No reported failures in the last {{ selectedDateFilter }}...\n                Everything looks good!\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n        </v-slide-y-transition>\n      </v-list>\n      <div v-if=\"failures && failures.length > 3\" class=\"pa-0 footer\"> </div>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.time-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n\n.error-card-content {\n  height: 254px;\n  overflow-y: scroll;\n}\n\n.footer {\n  background-image: linear-gradient(transparent, 60%, rgba(0, 0, 0, 0.1));\n  bottom: 6px;\n  height: 6px !important;\n  pointer-events: none;\n  position: absolute;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/FlowRunHeartbeat-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport HeartbeatTimeline from '@/components/HeartbeatTimeline'\nimport { heartbeatMixin } from '@/mixins/heartbeatMixin.js'\nimport { mapGetters } from 'vuex'\nimport { roundedOneAgo } from '@/utils/dateTime'\n\nexport default {\n  components: { CardTitle, HeartbeatTimeline },\n  mixins: [heartbeatMixin],\n  // These should eventually be moved here as data props\n  // instead of as passed in props\n  props: {\n    projectId: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return { loading: 0 }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant'])\n  },\n  watch: {\n    tenant(val) {\n      if (val) {\n        this.loading = 1\n        setTimeout(async () => {\n          await this.$apollo.queries.heartbeat.refetch(), (this.loading = 0)\n        }, 1000)\n      }\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.heartbeat.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    heartbeat: {\n      query: require('@/graphql/Dashboard/heartbeat.gql'),\n      update: d => d.flow_run,\n      loadingKey: 'loading',\n      variables() {\n        return {\n          projectId: this.projectId ? this.projectId : null,\n          timestamp: roundedOneAgo('month'),\n          state: this.checkedState,\n          filterOutStates: 'Scheduled'\n        }\n      },\n      pollInterval: 10000\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"pa-2\"\n    style=\"height: 100%;\"\n    tile\n  >\n    <CardTitle title=\"Activity\" icon=\"show_chart\">\n      <v-select\n        data-public\n        slot=\"action\"\n        v-model=\"state\"\n        class=\"state-interval-picker font-weight-regular\"\n        :items=\"states\"\n        label=\"State\"\n        dense\n        solo\n        hide-details\n        flat\n      >\n        <template #prepend-inner>\n          <v-icon color=\"black\" x-small>\n            label_important\n          </v-icon>\n        </template>\n      </v-select>\n    </CardTitle>\n\n    <v-container class=\"pa-0 pr-4\">\n      <HeartbeatTimeline :loading=\"loading\" :items=\"heartbeat\" type=\"project\" />\n    </v-container>\n\n    <v-divider></v-divider>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.state-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/FlowRunHistory-Tile.vue",
    "content": "<script>\nimport BarChart from '@/components/Visualizations/BarChart.vue'\nimport { flowRunHistoryMixin } from '@/mixins/flowRunHistoryMixin'\nimport TimelineTooltip from '@/components/TimelineTooltip'\nimport { roundedOneAgo } from '@/utils/dateTime'\n\nexport default {\n  components: {\n    BarChart,\n    TimelineTooltip\n  },\n  mixins: [flowRunHistoryMixin],\n  props: {\n    projectId: {\n      type: String,\n      default: () => null\n    },\n    visible: { type: Boolean, default: () => true }\n  },\n  data() {\n    return {\n      loadingKey: 0\n    }\n  },\n  computed: {\n    loading() {\n      return this.loadingKey > 0\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRuns.skip = !entry.isIntersecting\n      this.$apollo.queries.scheduledFlowRuns.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRuns: {\n      query: require('@/graphql/Dashboard/timeline-flow-runs.gql'),\n      variables() {\n        return {\n          limit: this.scheduledFlowRuns?.length === 0 ? 100 : 90,\n          project_id: this.projectId == '' ? null : this.projectId,\n          date: roundedOneAgo('month')\n        }\n      },\n      pollInterval: 5000,\n      loadingKey: 'loadingKey',\n      update: data => data.flow_run || []\n    },\n    scheduledFlowRuns: {\n      query: require('@/graphql/Dashboard/timeline-scheduled-flow-runs.gql'),\n      variables() {\n        return {\n          project_id: this.projectId == '' ? null : this.projectId\n        }\n      },\n      pollInterval: 5000,\n      loadingKey: 'loadingKey',\n      update: data => data.flow_run || []\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"px-3 pt-7 pb-0\"\n    style=\"height: 100%;\"\n    tile\n  >\n    <div class=\"text-caption text-left grey--text timeline-title\">\n      <v-icon x-small>pi-flow-run</v-icon><span class=\"ml-1\">Run History</span>\n    </div>\n\n    <div\n      v-if=\"!loading && reversedRuns.length === 0\"\n      class=\"text-caption text-center grey--text timeline-no-runs\"\n    >\n      No run history in the last month\n    </div>\n    <BarChart\n      :loading=\"loading\"\n      :items=\"reversedRuns\"\n      :breaklines=\"breaklines\"\n      :height=\"150\"\n      :min-bands=\"100\"\n      show-controls\n      :visible=\"visible\"\n      y-field=\"duration\"\n      @bar-click=\"_barClick\"\n      @bar-mouseout=\"_barMouseout\"\n      @bar-mouseover=\"_barMouseover\"\n    >\n      <template v-if=\"canShowTooltip\" slot=\"tooltip\">\n        <TimelineTooltip\n          :tooltip=\"tooltip\"\n          :loading=\"tooltipLoading\"\n          :show-project-name=\"$route.name === 'dashboard'\"\n        />\n      </template>\n    </BarChart>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.timeline-title {\n  left: 8px;\n  position: absolute;\n  top: 8px;\n}\n\n.timeline-no-runs {\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/FlowTable-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport LastTenRuns from '@/components/LastTenRuns'\nimport ScheduleToggle from '@/components/ScheduleToggle'\n\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { mapGetters } from 'vuex'\nimport debounce from 'lodash/debounce'\n\nconst serverHeaders = [\n  {\n    text: 'Name',\n    value: 'name',\n    width: '30%'\n  },\n  {\n    text: 'Schedule',\n    value: 'schedule',\n    sortable: false,\n    align: 'center',\n    width: '10%'\n  },\n  {\n    text: 'Project',\n    value: 'project.name',\n    sortable: false,\n    width: '15%'\n  },\n  {\n    text: 'Version',\n    value: 'version',\n    sortable: false,\n    width: '7.5%'\n  },\n  {\n    text: 'Created On',\n    value: 'created',\n    width: '15%'\n  }\n]\n\nconst serverHeadersPost = [\n  {\n    text: 'Run History',\n    value: 'flow_runs',\n    sortable: false,\n    width: '20%'\n  }\n]\n\nconst cloudHeaders = [\n  {\n    text: 'Created By',\n    value: 'created_by.username',\n    sortable: false,\n    width: '12.5%'\n  }\n]\n\nexport default {\n  components: {\n    CardTitle,\n    LastTenRuns,\n    ScheduleToggle\n  },\n  filters: {},\n  mixins: [formatTime],\n  props: {\n    projectId: {\n      required: false,\n      type: String,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      flows: [],\n      limit: 30,\n      loading: 0,\n      page: 1,\n      search:\n        this.$route && this.$route.query && this.$route.query.flows\n          ? this.$route.query.flows\n          : null,\n      showArchived:\n        this.$route && this.$route.query && this.$route.query.archived,\n      sortBy: 'name',\n      sortDesc: false\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['timezone', 'settings']),\n    headers() {\n      return [\n        ...(this.showArchived\n          ? [\n              {\n                text: '',\n                value: 'archived',\n                width: 5\n              }\n            ]\n          : []),\n        ...serverHeaders,\n        ...(this.isCloud ? cloudHeaders : []),\n        ...serverHeadersPost\n      ]\n    },\n    placeholderMessage() {\n      if (this.$vuetify.breakpoint.mdAndUp) {\n        return `Search by Flow, ${!this.isCloud ? 'or' : ''} Project${\n          this.isCloud ? ', or User' : ''\n        } `\n      }\n      return ''\n    },\n    searchFormatted() {\n      if (!this.search) return null\n      return `%${this.search}%`\n    },\n    validUUID() {\n      if (!this.search) return false\n\n      const UUIDRegex = /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/\n\n      // Call .trim() to get rid of whitespace on the ends of the\n      // string before making the query\n      return UUIDRegex.test(this.search.trim())\n    }\n  },\n  watch: {\n    search(val) {\n      this.$router.replace({\n        query: { ...this.$route.query, flows: val }\n      })\n    },\n    showArchived(val) {\n      let query = { ...this.$route.query }\n\n      if (val) {\n        query.archived = true\n      } else {\n        delete query.archived\n      }\n      this.$router.replace({\n        query: query\n      })\n    },\n    async limit(val) {\n      if (val && val !== this.settings?.flowTableTileLimit) {\n        try {\n          await this.$apollo.mutate({\n            mutation: require('@/graphql/User/update-user-settings.gql'),\n            variables: {\n              input: { flowTableTileLimit: val }\n            }\n          })\n        } catch (error) {\n          return\n        }\n      }\n    }\n  },\n  mounted() {\n    this.limit = this.settings?.flowTableTileLimit || 30\n  },\n  methods: {\n    async handleTableSearchInput(e) {\n      this.loading++\n      this.debounceSearch(e)\n    },\n    debounceSearch: debounce(function(e) {\n      this.loading--\n      this.search = e\n    }, 500),\n    onIntersect([entry]) {\n      this.$apollo.queries.flows.skip = !entry.isIntersecting\n      this.$apollo.queries.flowCount.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flows: {\n      query() {\n        return require('@/graphql/Dashboard/flows.js').default(this.isCloud)\n      },\n      variables() {\n        let sortBy = {}\n        if (this.sortBy) {\n          if (this.isCloud && this.sortBy.includes('created_by.username')) {\n            sortBy['created_by'] = {}\n            sortBy['created_by']['username'] = this.sortDesc ? 'desc' : 'asc'\n          } else if (Object.keys(this.sortBy) < 1) {\n            sortBy = { name: 'asc' }\n          } else {\n            sortBy[`${this.sortBy}`] = this.sortDesc ? 'desc' : 'asc'\n          }\n        }\n\n        let searchParams = [\n          { archived: { _eq: this.showArchived ? null : false } },\n          { project_id: { _eq: this.projectId ? this.projectId : null } }\n        ]\n\n        let orParams = [\n          {\n            name: { _ilike: this.searchFormatted }\n          },\n          { project: { name: { _ilike: this.searchFormatted } } }\n        ]\n\n        if (this.validUUID) {\n          orParams.push({ id: { _eq: this.search } })\n        }\n\n        if (this.isCloud) {\n          orParams.push({\n            created_by: { username: { _ilike: this.searchFormatted } }\n          })\n        }\n\n        return {\n          limit: this.limit,\n          offset: this.limit * (this.page - 1),\n          orderBy: sortBy,\n          searchParams: {\n            _and: [...searchParams, { _or: [...orParams] }]\n          }\n        }\n      },\n      loadingKey: 'loading',\n      pollInterval: 60000,\n      update: data => {\n        return data?.flow\n      }\n    },\n    flowCount: {\n      query: require('@/graphql/Dashboard/flow-count.gql'),\n      variables() {\n        let searchParams = [\n          { archived: { _eq: this.showArchived ? null : false } },\n          { project_id: { _eq: this.projectId ? this.projectId : null } }\n        ]\n\n        let orParams = [\n          {\n            name: { _ilike: this.searchFormatted }\n          },\n          { project: { name: { _ilike: this.searchFormatted } } }\n        ]\n\n        if (this.validUUID) {\n          orParams.push({ id: { _eq: this.search } })\n        }\n\n        if (this.isCloud) {\n          orParams.push({\n            created_by: { username: { _ilike: this.searchFormatted } }\n          })\n        }\n\n        return {\n          searchParams: { _and: [...searchParams, { _or: [...orParams] }] }\n        }\n      },\n      loadingKey: 'loading',\n      pollInterval: 60000,\n      update: data => data?.flowCount?.aggregate?.count\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2\" tile>\n    <CardTitle title=\"Flows\" icon=\"pi-flow\">\n      <div slot=\"action\" class=\"flex align-center justify-end\">\n        <v-text-field\n          :value=\"search\"\n          class=\"flow-search\"\n          dense\n          hide-details\n          single-line\n          solo\n          flat\n          :placeholder=\"placeholderMessage\"\n          prepend-inner-icon=\"search\"\n          autocomplete=\"new-password\"\n          style=\"min-width: 400px;\"\n          @input=\"handleTableSearchInput\"\n        />\n      </div>\n    </CardTitle>\n\n    <v-card-text class=\"pa-0 pl-8\">\n      <v-data-table\n        fixed-header\n        :search.sync=\"search\"\n        :mobile-breakpoint=\"960\"\n        :loading=\"loading > 0\"\n        loading-text=\"Loading your flows...\"\n        :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n        :items=\"flows\"\n        :headers=\"headers\"\n        :page.sync=\"page\"\n        :items-per-page.sync=\"limit\"\n        class=\"ma-2 overflow-table\"\n        must-sort\n        :no-data-text=\"\n          `You have no flows${projectId ? ' in this project!' : '!'}`\n        \"\n        :server-items-length=\"flowCount\"\n        :sort-by.sync=\"sortBy\"\n        :sort-desc.sync=\"sortDesc\"\n        :class=\"{ 'fixed-table': $vuetify.breakpoint.mdAndUp }\"\n        :footer-props=\"{\n          showFirstLastPage: true,\n          firstIcon: 'first_page',\n          itemsPerPageOptions: [15, 30, 50],\n          lastIcon: 'last_page',\n          prevIcon: 'keyboard_arrow_left',\n          nextIcon: 'keyboard_arrow_right'\n        }\"\n      >\n        <template #item.archived=\"{ item }\">\n          <truncate :content=\"item.archived ? 'Archived' : 'Active'\">\n            <v-icon small dark :color=\"item.archived ? 'accentPink' : 'green'\">\n              {{ item.archived ? 'archive' : 'pi-flow' }}\n            </v-icon>\n          </truncate>\n        </template>\n\n        <template #item.name=\"{ item }\">\n          <truncate :content=\"item.name\">\n            <router-link\n              class=\"link\"\n              :data-cy=\"\n                'flow-link|' +\n                  item.name +\n                  '|' +\n                  (item.archived ? 'archived' : 'active') +\n                  '-' +\n                  item.version\n              \"\n              :to=\"{\n                name: 'flow',\n                params: { id: item.flow_group.id, tenant: tenant.slug }\n              }\"\n            >\n              <span>{{ item.name }}</span>\n            </router-link>\n          </truncate>\n        </template>\n\n        <template #item.project.name=\"{ item }\">\n          <truncate :content=\"item.project.name\">\n            <router-link\n              class=\"link\"\n              :to=\"{\n                name: 'project',\n                params: { id: item.project.id, tenant: tenant.slug }\n              }\"\n            >\n              <span>{{ item.project.name }}</span>\n            </router-link>\n          </truncate>\n        </template>\n\n        <template #item.schedule=\"{ item }\">\n          <ScheduleToggle :flow=\"item\" :flow-group=\"item.flow_group\" />\n        </template>\n\n        <template #item.flow_runs=\"{ item }\">\n          <div class=\"position-relative allow-overflow\" style=\"height: 55px;\">\n            <LastTenRuns :flow-id=\"item.id\" :archived=\"item.archived\" />\n          </div>\n        </template>\n\n        <template #item.created=\"{ item }\">\n          <truncate :content=\"formatTime(item.created)\" />\n        </template>\n\n        <template #item.created_by.username=\"{ item }\">\n          <truncate\n            :content=\"item.created_by ? item.created_by.username : null\"\n          />\n        </template>\n\n        <!-- eslint-disable vue/no-template-shadow -->\n        <template #body.append=\"{ headers }\">\n          <td :colspan=\"headers.length\">\n            <v-row justify=\"end\">\n              <v-switch\n                v-model=\"showArchived\"\n                class=\"archived-checkbox mr-7\"\n                label=\"Show Archived\"\n              ></v-switch>\n            </v-row>\n          </td>\n        </template>\n      </v-data-table>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.flow-search {\n  border-radius: 0 !important;\n  font-size: 0.85rem;\n\n  .v-icon {\n    font-size: 20px !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/InProgress-Tile.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport CancelAll from '@/components/SystemActions/CancelAll'\nimport CardTitle from '@/components/Card-Title'\nimport ConcurrencyInfo from '@/components/ConcurrencyInfo'\nimport DurationSpan from '@/components/DurationSpan'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    CancelAll,\n    CardTitle,\n    ConcurrencyInfo,\n    DurationSpan\n  },\n  mixins: [formatTime],\n  props: {\n    projectId: {\n      required: false,\n      type: String,\n      default: () => null\n    },\n    agentRuns: {\n      required: false,\n      type: Boolean,\n      default: false\n    },\n    agentId: {\n      type: String,\n      required: false,\n      default: null\n    }\n  },\n  data() {\n    const tabs = {\n      all: 0,\n      running: 1,\n      submitted: 2\n    }\n\n    return {\n      loadingKey: 0,\n      overlay: false,\n      tab: tabs.all,\n      tabs\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['timezone']),\n    loading() {\n      return this.loadingKey > 0\n    },\n    all() {\n      if (!this.flowRuns && !this.agentFlowRuns) return []\n      return this.flowRuns || this.agentFlowRuns\n    },\n    running() {\n      if (!this.all) return []\n      return this.all?.filter(\n        run => run.state == 'Running' || run.state == 'Cancelling'\n      )\n    },\n    submitted() {\n      if (!this.all) return []\n      return this.all?.filter(run => run.state == 'Submitted')\n    },\n    cancellable() {\n      if (!this.all) return []\n      if (this.tab == this.tabs.submitted) return this.submitted\n      if (this.tab == this.tabs.running) return this.running\n      return this.all?.filter(run => run.state !== 'Cancelling')\n    },\n    runs() {\n      if (this.tab == this.tabs.submitted) return this.submitted\n      if (this.tab == this.tabs.running) return this.running\n      return this.all\n    },\n    tileColor() {\n      let color = this.loading ? 'grey' : 'InProgress'\n\n      if (this.tab == this.tabs.submitted) {\n        color = 'Submitted'\n      }\n\n      if (this.tab == this.tabs.running) {\n        color = 'Running'\n      }\n\n      return color\n    },\n    title() {\n      let title = this.loading\n        ? 'In progress flow runs'\n        : `${this.all?.length || 0} runs in progress`\n\n      if (this.tab == this.tabs.submitted) {\n        title = this.loading\n          ? 'Submitted flow runs'\n          : `${this.submitted?.length || 0} submitted runs`\n      }\n\n      if (this.tab == this.tabs.running) {\n        title = this.loading\n          ? 'Running flow runs'\n          : `${this.running?.length || 0} running flows`\n      }\n\n      return title\n    },\n    titleIcon() {\n      let icon = 'filter_drama'\n\n      if (this.tab == this.tabs.submitted) {\n        icon = 'filter_drama'\n      }\n\n      if (this.tab == this.tabs.running) {\n        icon = 'filter_drama'\n      }\n\n      return icon\n    }\n  },\n  watch: {\n    async tenant(val) {\n      if (val) {\n        await this.$apollo.queries.flowRuns.refetch()\n        await this.$apollo.queries.agentFlowRuns.refetch()\n      }\n    }\n  },\n  methods: {\n    refetch() {\n      this.$apollo.queries['flowRuns'].refetch()\n      this.$apollo.queries['agentFlowRuns'].refetch()\n      this.overlay = false\n    },\n    toggleOverlay() {\n      this.overlay = !this.overlay\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRuns.skip = !entry.isIntersecting\n      this.$apollo.queries.agentFlowRuns.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRuns: {\n      query: require('@/graphql/Dashboard/in-progress-flow-runs.gql'),\n      variables() {\n        return {\n          projectId: this.projectId ? this.projectId : null\n        }\n      },\n      skip() {\n        return this.agentRuns\n      },\n      loadingKey: 'loadingKey',\n      pollInterval: 3000,\n      update: ({ flow_run }) => flow_run || []\n    },\n    agentFlowRuns: {\n      query: require('@/graphql/Agent/in-progress-flow-runs.gql'),\n      variables() {\n        return {\n          agentId: this.agentId\n        }\n      },\n      skip() {\n        return !this.agentRuns\n      },\n      loadingKey: 'loadingKey',\n      pollInterval: 3000,\n      update: ({ flow_run }) => flow_run || []\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    tile\n    class=\"pb-2 position-relative d-flex flex-column\"\n    style=\"height: 100%;\"\n  >\n    <v-progress-linear\n      striped\n      active\n      height=\"5\"\n      value=\"100\"\n      absolute\n      :indeterminate=\"loading\"\n      :color=\"tileColor\"\n    />\n\n    <CardTitle :icon=\"titleIcon\" :icon-color=\"tileColor\" class=\"pt-2\">\n      <v-row slot=\"title\" no-gutters class=\"d-flex align-center\">\n        <v-col cols=\"10\">\n          <div>\n            <div\n              v-if=\"loading\"\n              style=\"\n                display: inline-block;\n                height: 20px;\n                overflow: hidden;\n                width: 20px;\"\n            >\n              <v-skeleton-loader type=\"avatar\" tile></v-skeleton-loader>\n            </div>\n            {{ title }}\n          </div>\n          <ConcurrencyInfo\n            v-if=\"isCloud\"\n            class=\"text-caption position-absolute\"\n            style=\"bottom: 2px;\"\n          />\n        </v-col>\n      </v-row>\n    </CardTitle>\n\n    <v-tabs\n      v-model=\"tab\"\n      tabs-border-bottom\n      color=\"primary\"\n      class=\"flex-grow-0\"\n    >\n      <v-tab :key=\"tabs.all\" data-cy=\"in-progress-tile-all\">\n        All\n      </v-tab>\n      <v-tab :key=\"tabs.running\" data-cy=\"in-progress-tile-running\">\n        Running\n      </v-tab>\n      <v-tab :key=\"tabs.submitted\" data-cy=\"in-progress-tile-submitted\">\n        Submitted\n      </v-tab>\n    </v-tabs>\n\n    <v-card-text class=\"px-0 py-2 card-content\">\n      <v-overlay v-if=\"overlay\" absolute z-index=\"1\">\n        <CancelAll :flow-runs=\"cancellable\" @finish=\"refetch\" />\n      </v-overlay>\n\n      <v-skeleton-loader v-else-if=\"loading\" type=\"list-item-three-line\">\n      </v-skeleton-loader>\n\n      <v-list v-else-if=\"!loading && runs.length === 0\">\n        <v-list-item>\n          <v-list-item-avatar class=\"mr-0\">\n            <v-icon class=\"mb-1\" :color=\"tileColor\">\n              warning\n            </v-icon>\n          </v-list-item-avatar>\n\n          <v-list-item-content class=\"my-0 py-3\">\n            <div\n              class=\"text-subtitle-1 font-weight-light\"\n              style=\"line-height: 1.25rem;\"\n            >\n              You have no\n              {{\n                tab == tabs.running\n                  ? 'running flows'\n                  : tab == tabs.submitted\n                  ? 'submitted runs'\n                  : 'runs in progress'\n              }}\n            </div>\n          </v-list-item-content>\n        </v-list-item>\n      </v-list>\n\n      <v-virtual-scroll v-else :items=\"runs\" height=\"178px\" item-height=\"50px\">\n        <template #default=\"{item}\">\n          <div\n            :key=\"item.id\"\n            :class=\"item.state == 'Cancelling' ? 'blue-grey lighten-5' : ''\"\n          >\n            <v-list-item>\n              <v-list-item-content>\n                <v-list-item-title class=\"d-flex align-center\">\n                  <div\n                    class=\"text-truncate d-inline-block\"\n                    style=\"max-width: 50%;\"\n                  >\n                    <router-link\n                      :class=\"\n                        item.state == 'Cancelling' ? 'text--disabled' : ''\n                      \"\n                      :to=\"{\n                        name: 'flow',\n                        params: { id: item.flow.flow_group_id }\n                      }\"\n                    >\n                      {{ item.flow.name }}\n                    </router-link>\n                  </div>\n                  <div class=\"font-weight-bold d-inline-block\">\n                    <v-icon style=\"font-size: 12px;\">\n                      chevron_right\n                    </v-icon>\n                  </div>\n\n                  <div\n                    class=\"text-truncate d-inline-block text--disabled\"\n                    style=\"max-width: 35%;\"\n                  >\n                    <router-link\n                      :class=\"\n                        item.state == 'Cancelling' ? 'text--disabled' : ''\n                      \"\n                      :to=\"{ name: 'flow-run', params: { id: item.id } }\"\n                    >\n                      {{ item.name }}\n                    </router-link>\n                  </div>\n                </v-list-item-title>\n                <v-list-item-subtitle v-if=\"item.state == 'Cancelling'\">\n                  Cancelling...\n                </v-list-item-subtitle>\n                <v-list-item-subtitle v-else-if=\"item.start_time\">\n                  Running for\n                  <DurationSpan\n                    class=\"font-weight-bold\"\n                    :start-time=\"item.start_time\"\n                  />\n                </v-list-item-subtitle>\n                <v-list-item-subtitle v-else-if=\"item.state == 'Submitted'\">\n                  Submitted for execution\n                </v-list-item-subtitle>\n              </v-list-item-content>\n            </v-list-item>\n\n            <v-divider class=\"my-1 mx-4 grey lighten-4\" />\n          </div>\n        </template>\n      </v-virtual-scroll>\n\n      <div v-if=\"runs && runs.length > 3\" class=\"pa-0 card-footer\"> </div>\n    </v-card-text>\n\n    <v-spacer />\n\n    <v-card-actions class=\"py-0\">\n      <v-spacer />\n      <v-btn\n        v-if=\"overlay || (cancellable && cancellable.length > 0)\"\n        small\n        depressed\n        :plain=\"overlay\"\n        :color=\"overlay ? 'white' : 'primary'\"\n        width=\"74\"\n        text\n        style=\"z-index: 2;\"\n        @click=\"toggleOverlay\"\n      >\n        {{ overlay ? 'Close' : 'Stop all' }}\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\na {\n  text-decoration: none !important;\n}\n\n.button-transition {\n  transition: border-right 150ms linear;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.card-content {\n  height: 100%;\n  max-height: calc(210px - var(--v-tabs-height));\n  overflow-y: auto;\n}\n\n.card-footer {\n  background-image: linear-gradient(transparent, 60%, rgba(0, 0, 0, 0.1));\n  bottom: 6px;\n  height: 6px !important;\n  pointer-events: none;\n  position: absolute;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/NewProject-Dialog.vue",
    "content": "<script>\nimport { mapGetters, mapActions } from 'vuex'\nimport { clearCache } from '@/vue-apollo'\n\nexport default {\n  props: {\n    show: {\n      type: Boolean,\n      required: true\n    }\n  },\n  data() {\n    return {\n      valid: true,\n      projectName: '',\n      projectDescription: null,\n      nameRules: [\n        v => (v && !!v.trim()) || 'Project name is required',\n        v => !!v || 'Project name is required',\n        v =>\n          (v && v.length <= 50) ||\n          'Project name must be less than 50 characters'\n      ],\n      projectSuccess: false,\n      projectLoading: false,\n      projectError: false,\n      projectId: null,\n      specificProjectErrorMessage: ''\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['role', 'tenant']),\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return !this.hasPermission('create', 'project')\n    }\n  },\n  watch: {\n    show() {\n      if (this.$refs.form) {\n        this.$refs.form.reset()\n        this.projectName = ''\n      }\n    }\n  },\n  methods: {\n    ...mapActions('data', ['activateProject']),\n    async createProject() {\n      this.projectLoading = true\n      try {\n        const { data, errors } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-project.gql'),\n          variables: {\n            name: this.projectName,\n            description: this.projectDescription,\n            tenantId: this.tenant.id\n          },\n          errorPolicy: 'all'\n        })\n        if (data?.create_project) {\n          this.projectId = data.create_project.id\n          this.projectSuccess = true\n          this.projectLoading = false\n          this.$globalApolloQueries['projects']?.refetch()\n          //adding this here to make sure the dialog resets, even if a user clicks outside the box instead of going to the project (the persistent prop in vuetify is currently unreliable)\n          setTimeout(() => (this.projectSuccess = false), 8000)\n        } else if (errors) {\n          if (errors[0].message === 'Uniqueness violation.') {\n            this.specificProjectErrorMessage =\n              'That project name already exists.  Please choose a new one.'\n            this.projectLoading = false\n            setTimeout(() => (this.specificProjectErrorMessage = ''), 3000)\n          } else {\n            this.projectError = true\n            setTimeout(() => (this.projectError = false), 3000)\n          }\n        }\n      } catch (error) {\n        this.projectError = true\n        setTimeout(() => (this.projectError = false), 3000)\n        throw Error\n      }\n    },\n    async goToProject() {\n      clearCache()\n      await this.activateProject(this.projectId)\n      this.$emit('project-select', this.projectId)\n      this.$router\n        .push({\n          name: 'project',\n          params: { ...this.$route.params, id: this.projectId },\n          query: { ...this.$route.query }\n        })\n        .catch(e => e)\n      this.reset()\n    },\n    close() {\n      this.$emit('close')\n      this.reset()\n    },\n    reset() {\n      this.$emit('update:show', false)\n      this.projectName = ''\n      this.projectSuccess = false\n      this.projectLoading = false\n      this.projectError = false\n      this.specificProjectErrorMessage = ''\n    }\n  }\n}\n</script>\n\n<template>\n  <v-dialog :value=\"show\" width=\"500\" persistent @click:outside=\"reset\">\n    <v-card :loading=\"projectLoading\">\n      <v-card-title v-if=\"projectError || specificProjectErrorMessage\">\n        Uh oh! There's a problem\n      </v-card-title>\n      <v-card-title v-else-if=\"projectSuccess\">\n        Success!\n      </v-card-title>\n      <v-card-title v-else-if=\"permissionsCheck\">\n        You don't have permission.\n      </v-card-title>\n\n      <v-card-title v-else>\n        Please give your new project a name\n      </v-card-title>\n      <v-card-text v-if=\"specificProjectErrorMessage\">\n        {{ specificProjectErrorMessage }}\n      </v-card-text>\n      <v-card-text v-else-if=\"permissionsCheck\">\n        You don't have permission to create projects.\n      </v-card-text>\n      <v-card-text v-else-if=\"projectError\">\n        It looks like your project wasn't added. Please try again. If you still\n        need help, visit our\n        <router-link to=\"help\">Support Page</router-link>.\n      </v-card-text>\n\n      <v-card-text v-else-if=\"projectSuccess\">\n        Your project has been added.\n      </v-card-text>\n\n      <v-card-text v-else>\n        <v-form ref=\"form\" v-model=\"valid\" @submit.prevent>\n          <v-text-field\n            id=\"name\"\n            v-model=\"projectName\"\n            autocomplete=\"off\"\n            label=\"Project Name\"\n            required\n            :rules=\"nameRules\"\n            @keyup.enter=\"createProject\"\n          />\n        </v-form>\n      </v-card-text>\n\n      <v-divider></v-divider>\n\n      <v-card-actions>\n        <v-spacer></v-spacer>\n        <v-btn\n          v-if=\"projectSuccess\"\n          color=\"primary\"\n          class=\"white--text\"\n          @click=\"goToProject\"\n        >\n          Go to project\n        </v-btn>\n        <v-btn\n          v-if=\"\n            !projectSuccess && !projectError && !specificProjectErrorMessage\n          \"\n          id=\"add\"\n          v-disable-read-only-user=\"!valid\"\n          :disabled=\"!valid\"\n          :loading=\"projectLoading\"\n          class=\"ml-5 white--text\"\n          color=\"primary\"\n          @click=\"createProject\"\n        >\n          Add Project\n        </v-btn>\n        <v-btn\n          v-if=\"!projectSuccess\"\n          id=\"close\"\n          text\n          data-cy=\"project-select-cancel\"\n          @click=\"close\"\n          >Cancel</v-btn\n        >\n      </v-card-actions>\n    </v-card>\n  </v-dialog>\n</template>\n"
  },
  {
    "path": "src/pages/Dashboard/Notifications-Tile.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport CardTitle from '@/components/Card-Title'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\n// Notification type-specific components\nimport ApprovalNotification from '@/pages/Notifications/NotificationTypes/Approval-Notification'\nimport FlowRunNotification from '@/pages/Notifications/NotificationTypes/FlowRun-Notification'\nimport MembershipNotification from '@/pages/Notifications/NotificationTypes/Membership-Notification'\nimport MessageNotification from '@/pages/Notifications/NotificationTypes/Message-Notification'\nimport WhatsNewNotification from '@/pages/Notifications/NotificationTypes/WhatsNew-Notification'\n\nimport {\n  componentMap,\n  iconMap,\n  iconColorMap,\n  navigationMap\n} from '@/pages/Notifications/utils'\n\nexport default {\n  components: {\n    ApprovalNotification,\n    CardTitle,\n    FlowRunNotification,\n    MembershipNotification,\n    MessageNotification,\n    WhatsNewNotification\n  },\n  mixins: [formatTime],\n  data() {\n    return {\n      loadingKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    cardTitle() {\n      return `${parseInt(\n        this.notificationsCount\n      ).toLocaleString()} unread notification${\n        this.notificationsCount === 1 ? '' : 's'\n      }`\n    },\n    iconColor() {\n      return this.isLoading\n        ? null\n        : this.notificationsCount > 0\n        ? 'codePink'\n        : null\n    },\n    isLoading() {\n      return this.loadingKey > 0\n    },\n    where() {\n      let where = {\n        _or: [\n          { tenant_id: { _eq: this.tenant?.id } },\n          { tenant_id: { _is_null: true } }\n        ],\n        read: { _eq: false }\n      }\n\n      return where\n    }\n  },\n  methods: {\n    notificationComponent(type) {\n      return componentMap[type]\n    },\n    notificationIcon(type) {\n      return iconMap[type]\n    },\n    notificationIconColor(type, n) {\n      return iconColorMap[type](n)\n    },\n    notificationNavigation(notification) {\n      return navigationMap[notification.type](notification, this.tenant)\n    },\n    async markAsRead(notification) {\n      if (notification.content.link) {\n        this.loadingKey++\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/mark-as-read.gql'),\n          variables: {\n            input: { message_id: notification.id }\n          }\n        })\n        this.loadingKey--\n      }\n    },\n    routeToNotifications() {\n      this.$router.push({\n        name: 'notifications'\n      })\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.notifications.skip = !entry.isIntersecting\n      this.$apollo.queries.notificationsCount.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    notifications: {\n      query() {\n        return require('@/graphql/Notifications/notifications.js').default(\n          this.isCloud\n        )\n      },\n      variables() {\n        return {\n          limit: 5,\n          orderBy: { created: 'desc' },\n          where: this.where\n        }\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.notifications,\n      pollInterval: 5000,\n      fetchPolicy: 'network-only'\n    },\n    notificationsCount: {\n      query: require('@/graphql/Notifications/notifications-count.gql'),\n      loadingKey: 'loadingKey',\n      variables() {\n        return {\n          where: this.where\n        }\n      },\n      update: data => data?.message_aggregate?.aggregate?.count,\n      pollInterval: 5000,\n      fetchPolicy: 'network-only'\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"py-2 position-relative d-flex flex-column\"\n    style=\"height: 100%;\"\n    tile\n  >\n    <CardTitle\n      :title=\"cardTitle\"\n      icon=\"notifications\"\n      :icon-color=\"iconColor\"\n      icon-class=\"mb-1\"\n      :loading=\"isLoading\"\n    />\n\n    <v-card-text class=\"pa-0 card-content\">\n      <v-skeleton-loader v-if=\"isLoading\" type=\"list-item-three-line\">\n      </v-skeleton-loader>\n\n      <v-list v-else-if=\"notificationsCount > 0\" class=\" card-content\">\n        <template v-for=\"(n, i) in notifications\">\n          <v-list-item\n            :key=\"n.id\"\n            class=\"position-relative\"\n            :class=\"n.read ? 'o-60 hover-o-100' : ''\"\n            :disabled=\"isLoading > 0\"\n            :to=\"notificationNavigation(n)\"\n            :href=\"n.content.link\"\n            :target=\"notificationNavigation(n) ? null : '_blank'\"\n            exact\n            @click=\"markAsRead(n)\"\n          >\n            <v-icon small class=\"mr-4 grey--text text--darken-1\">\n              {{ n.content.icon ? n.content.icon : notificationIcon(n.type) }}\n            </v-icon>\n\n            <component\n              :is=\"notificationComponent(n.type)\"\n              :timestamp=\"formatDateTime(n.created)\"\n              dense\n              :content=\"n.content\"\n              :read=\"n.read\"\n            />\n\n            <v-list-item-avatar v-if=\"notificationNavigation(n)\">\n              <v-icon>arrow_right</v-icon>\n            </v-list-item-avatar>\n          </v-list-item>\n          <v-divider :key=\"i\" class=\"my-1 mx-4 grey lighten-4\" />\n        </template>\n      </v-list>\n\n      <v-list v-else>\n        <v-list-item>\n          <v-list-item-avatar class=\"mr-0\">\n            <v-icon class=\"green--text\">check</v-icon>\n          </v-list-item-avatar>\n\n          <v-list-item-content class=\"my-0 py-3\">\n            <div\n              class=\"text-subtitle-1 font-weight-light\"\n              style=\"line-height: 1.25rem;\"\n            >\n              You're all caught up!\n            </div>\n          </v-list-item-content>\n        </v-list-item>\n      </v-list>\n    </v-card-text>\n\n    <v-spacer />\n\n    <v-card-actions class=\"py-0\">\n      <v-spacer />\n      <v-btn small color=\"primary\" text :to=\"'/notifications'\">\n        View all notifications\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.card-content {\n  height: 100%;\n  max-height: 210px;\n  overflow-y: auto;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/Project-Selector.vue",
    "content": "<script>\nimport NewProjectDialog from '@/pages/Dashboard/NewProject-Dialog'\nimport { mapGetters } from 'vuex'\nimport { pollsProjectsMixin } from '@/mixins/polling/pollsProjectsMixin'\n\nexport default {\n  components: {\n    NewProjectDialog\n  },\n  mixins: [pollsProjectsMixin],\n  data() {\n    return {\n      newProjectDialog: false,\n      loading: false,\n      previousProject: null,\n      projectId: this.$route.params.id,\n      projectSelect: this.$route.params.id\n        ? this.$route.params\n        : {\n            name: 'All Projects',\n            id: null\n          }\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['backend']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('data', ['activeProject', 'projects']),\n    project() {\n      return this.activeProject\n    },\n    sortedProjects() {\n      if (!this.projects) return []\n      let fullySorted = [...this.projects].sort((a, b) =>\n        a.name.localeCompare(b.name, undefined, { ignorePunctuation: true })\n      )\n      fullySorted.unshift({ name: 'All Projects', id: null })\n      fullySorted.unshift({ name: 'New Project', id: 'new_project' })\n      return fullySorted\n    }\n  },\n  watch: {\n    projectSelect(val) {\n      if (val == 'new_project') {\n        this.newProjectDialog = true\n        return\n      }\n      if (typeof val === 'object') {\n        this.$router\n          .push({\n            name: 'dashboard',\n            params: { ...this.$route.params, id: '' },\n            query: this.$route.query\n          })\n          .catch(e => e)\n        return\n      }\n      this.projectId = val\n      this.$emit('project-select', this.projectId)\n      this.$router\n        .push({\n          name: val ? 'project' : 'dashboard',\n          params: { ...this.$route.params, id: val ? val : '' },\n          query: { ...this.$route.query }\n        })\n        .catch(e => e)\n      if (!val) this.projectSelect = { name: 'All Projects', id: null }\n    },\n    '$route.params.id'(val) {\n      if (!val && this.projectId !== null) {\n        this.projectSelect = null\n        this.projectId = null\n        this.$emit('project-select', null)\n      } else if (val && this.projectId !== val) {\n        // This will ensure the normal emit and project id setting\n        // happens in the watcher above\n        this.projectSelect = val\n      }\n    }\n  },\n  methods: {\n    handleProjectSelect(event) {\n      this.projectId = event\n      this.projectSelect = event\n      this.$emit('project-select', event)\n    },\n    handleClose() {\n      this.projectSelect = null\n    },\n    projectSelectTitleClass(item) {\n      return {\n        'new-project': item.id == 'new_project',\n        'blue--text': item.id == null,\n        'text--darken-4': item.id == null\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-autocomplete\n      data-public\n      id=\"project-dropdown\"\n      v-model=\"projectSelect\"\n      class=\"project-selector\"\n      :class=\"$vuetify.breakpoint.xsOnly ? 'mx-auto' : 'mr-0'\"\n      hide-details\n      data-cy=\"projects\"\n      :items=\"sortedProjects\"\n      :loading=\"loading\"\n      label=\"Project\"\n      item-value=\"id\"\n      item-text=\"name\"\n      prepend-icon=\"pi-project\"\n      dense\n      background-color=\"transparent\"\n    >\n      <template #item=\"{ item }\">\n        <v-list-item-content\n          :class=\"item.id == 'new_project' ? 'new-project' : ''\"\n        >\n          <v-list-item-title :class=\"projectSelectTitleClass(item)\">\n            {{ item.name }}\n          </v-list-item-title>\n          <v-list-item-subtitle v-if=\"item.id == 'new_project'\">\n            Create a new project\n          </v-list-item-subtitle>\n          <v-list-item-subtitle v-if=\"item.id == null\">\n            Data across all your team's projects\n          </v-list-item-subtitle>\n        </v-list-item-content>\n      </template>\n    </v-autocomplete>\n\n    <NewProjectDialog\n      @project-select=\"handleProjectSelect\"\n      @close=\"handleClose\"\n      :show.sync=\"newProjectDialog\"\n    />\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.card-transition {\n  height: auto;\n  transition: all 150ms;\n}\n\n.new-project {\n  color: var(--v-primary-base);\n  font-weight: 500;\n}\n</style>\n\n<style lang=\"scss\">\n.project-selector {\n  font-size: 16px;\n  margin: auto;\n  padding-top: 12px;\n  width: 250px !important;\n\n  div {\n    font-size: 0.9rem !important;\n  }\n\n  .v-label {\n    font-size: 1rem;\n    font-weight: 500;\n    letter-spacing: 0.0892857143em;\n    line-height: 1.25rem;\n    text-transform: uppercase;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/Summary-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport StackedLineChart from '@/components/Visualizations/StackedLineChart'\nimport { STATE_COLORS, STATE_PAST_TENSE } from '@/utils/states'\nimport { roundedOneAgo } from '@/utils/dateTime'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    CardTitle,\n    StackedLineChart\n  },\n  props: {\n    projectId: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      dateFilters: [\n        { name: '1 Hour', value: 'hour' },\n        { name: '24 Hours', value: 'day' },\n        { name: '7 Days', value: 'week' },\n        { name: '30 Days', value: 'month' }\n      ],\n      loading: 0,\n      selectedDateFilter: 'day',\n      stateSegments: [],\n      total: 0\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    computedDateFilter() {\n      return this.dateFilters.find(d => d.value == this.selectedDateFilter)\n        .value\n    },\n    colors() {\n      return STATE_COLORS\n    },\n    filteredStateSegments() {\n      return this.stateSegments\n        .filter(s => s.value > 0)\n        .sort((sA, sB) => {\n          return sA.value > sB.value ? -1 : sA.value < sB.value ? 1 : 0\n        })\n    },\n    moreStateSegments() {\n      return this.filteredStateSegments.slice(3)\n    }\n  },\n  watch: {\n    selectedDateFilter() {\n      this.$apollo.queries.flowRunsAggregate.refetch()\n    },\n    tenant(val) {\n      this.projects = []\n\n      if (val) {\n        this.loading = 1\n        setTimeout(async () => {\n          await this.$apollo.queries.flowRunsAggregate.refetch(),\n            (this.loading = 0)\n        }, 1000)\n      }\n    }\n  },\n  methods: {\n    cursorPointer(event) {\n      event.target.style.cursor = 'pointer'\n    },\n    humanLabel(label) {\n      return STATE_PAST_TENSE[label]\n    },\n    statusStyle(state) {\n      return {\n        'border-radius': '50%',\n        display: 'inline-block',\n        'background-color': this.colors[state],\n        height: '1rem',\n        width: '1rem'\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRunsAggregate.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRunsAggregate: {\n      query: require('@/graphql/Dashboard/flow-runs.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {\n          projectId: this.projectId ? this.projectId : null,\n          heartbeat: roundedOneAgo(this.selectedDateFilter)\n        }\n      },\n      pollInterval: 3000,\n      update(data) {\n        if (data.loading) return\n\n        this.total = 0\n\n        Object.keys(data).forEach(state => {\n          let index = this.stateSegments.findIndex(s => s.label == state)\n          if (index > -1) {\n            this.stateSegments[index].value = data[state].aggregate.count\n          } else {\n            this.stateSegments.push({\n              label: state,\n              value: data[state].aggregate.count\n            })\n          }\n\n          this.total += data[state].aggregate.count\n        })\n        return this.stateSegments\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"py-2\"\n    tile\n    style=\"height: 100%;\"\n  >\n    <v-tooltip top>\n      <template #activator=\"{ on }\">\n        <CardTitle title=\"Summary\" icon=\"pi-flow-run\">\n          <div slot=\"action\" v-on=\"on\">\n            <v-select\n              data-public\n              v-model=\"selectedDateFilter\"\n              class=\"time-interval-picker\"\n              :items=\"dateFilters\"\n              dense\n              solo\n              item-text=\"name\"\n              item-value=\"value\"\n              hide-details\n              flat\n            >\n              <template #prepend-inner>\n                <v-icon color=\"utilGrayDark\" x-small>\n                  history\n                </v-icon>\n              </template>\n            </v-select>\n          </div>\n        </CardTitle>\n      </template>\n      <span>\n        Filter by when flows were last updated\n      </span>\n    </v-tooltip>\n\n    <v-card-text\n      class=\"pb-0 pt-2 card-content d-flex align-center justify-center\"\n    >\n      <div style=\"width: 100%;\">\n        <v-row no-gutters>\n          <v-col class=\"text-subtitle-2 text-center\">\n            In the last {{ selectedDateFilter }}\n          </v-col>\n        </v-row>\n        <v-row>\n          <v-col cols=\"5\">\n            <div class=\"text-center\">\n              <div class=\"font-weight-bold text-h4\" style=\"min-height: 36px;\">\n                <v-skeleton-loader\n                  v-if=\"loading > 0\"\n                  type=\"heading\"\n                  class=\"centered-skeleton\"\n                />\n                <v-tooltip v-else-if=\"filteredStateSegments.length > 0\" bottom>\n                  <template #activator=\"{ on }\">\n                    <span v-on=\"on\">\n                      <span class=\"hoverable\">\n                        {{ total.toLocaleString() }}\n                      </span>\n                    </span>\n                  </template>\n                  <div>\n                    <div\n                      v-for=\"segment in filteredStateSegments\"\n                      :key=\"segment.label\"\n                      class=\"d-flex align-center justify-space-between\"\n                    >\n                      <span>\n                        <span :style=\"statusStyle(segment.label)\" class=\"mr-2\">\n                        </span>\n                        <span>\n                          {{ segment.value.toLocaleString() }}\n                        </span>\n                      </span>\n                      <span class=\"ml-2\">\n                        {{ humanLabel(segment.label) }}\n                      </span>\n                    </div>\n                  </div>\n                </v-tooltip>\n                <div v-else>0</div>\n              </div>\n              <div class=\"subtitle\">flow runs</div>\n            </div>\n          </v-col>\n          <v-col cols=\"2\" class=\"d-flex align-center justify-center\">\n            <StackedLineChart\n              :segments=\"stateSegments\"\n              :colors=\"colors\"\n              :width=\"50\"\n              vertical\n            />\n          </v-col>\n          <v-col cols=\"5\">\n            <div class=\"text-center\">\n              <div class=\"font-weight-bold text-h4\" style=\"min-height: 36px;\">\n                <v-skeleton-loader\n                  v-if=\"loading > 0\"\n                  type=\"heading\"\n                  class=\"centered-skeleton\"\n                />\n                <v-tooltip v-else-if=\"filteredStateSegments.length > 0\" bottom>\n                  <template #activator=\"{ on }\">\n                    <span v-on=\"on\">\n                      <span class=\"hoverable\">\n                        {{\n                          ((filteredStateSegments[0].value / total) * 100)\n                            | roundTenths\n                        }}\n                      </span>\n                      <span class=\"text-subtitle-2\">%</span>\n                    </span>\n                  </template>\n                  <div>\n                    <div\n                      v-for=\"segment in filteredStateSegments\"\n                      :key=\"segment.label\"\n                      class=\"d-flex align-center justify-space-between\"\n                    >\n                      <span>\n                        <span :style=\"statusStyle(segment.label)\" class=\"mr-2\">\n                        </span>\n                        <span>\n                          {{\n                            ((segment.value / total) * 100)\n                              | roundTenths\n                              | filterOnePercent\n                          }}%\n                        </span>\n                      </span>\n                      <span class=\"ml-2\">\n                        {{ humanLabel(segment.label) }}\n                      </span>\n                    </div>\n                  </div>\n                </v-tooltip>\n              </div>\n              <div class=\"subtitle\">\n                <v-skeleton-loader\n                  v-if=\"loading > 0\"\n                  type=\"text\"\n                  class=\"centered-skeleton\"\n                />\n                <div v-else-if=\"filteredStateSegments.length > 0\">\n                  {{ humanLabel(filteredStateSegments[0].label) }}\n                </div>\n              </div>\n            </div>\n          </v-col>\n        </v-row>\n      </div>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.hoverable {\n  border-bottom: 1px dotted var(--v-utilGrayLight-base);\n  box-sizing: content-box;\n}\n\n.time-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n</style>\n\n<style lang=\"scss\">\n.card-content {\n  height: 254px;\n}\n\n.centered-skeleton {\n  // stylelint-disable\n  .v-skeleton-loader__bone {\n    margin: auto !important;\n  }\n  // stylelint-enable\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/Task-Item.vue",
    "content": "<script>\nexport default {\n  components: {},\n  props: {\n    failure: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    return {\n      loading: 0,\n      queryError: false\n    }\n  },\n  watch: {}\n}\n</script>\n\n<template>\n  <div class=\"result apollo\">\n    <v-list-item\n      class=\"text-truncate\"\n      :to=\"{\n        name: 'task-run',\n        params: { id: failure.id }\n      }\"\n    >\n      <v-list-item-content>\n        <v-list-item-title class=\"text-subtitle-2\">\n          <router-link\n            class=\"link\"\n            :to=\"{\n              name: 'task-run',\n              params: { id: failure.id }\n            }\"\n          >\n            {{ failure.task.flow.name }}\n            <span class=\"font-weight-bold\">\n              <v-icon style=\"font-size: 12px;\">\n                chevron_right\n              </v-icon>\n            </span>\n            {{ failure.task.name }}\n          </router-link>\n        </v-list-item-title>\n      </v-list-item-content>\n      <v-list-item-avatar><v-icon>arrow_right</v-icon></v-list-item-avatar>\n    </v-list-item>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/Dashboard/UpcomingRuns-Tile.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport CardTitle from '@/components/Card-Title'\nimport ClearLate from '@/components/SystemActions/ClearLate'\nimport ConcurrencyInfo from '@/components/ConcurrencyInfo'\nimport DurationSpan from '@/components/DurationSpan'\nimport LabelWarning from '@/components/LabelWarning'\nimport WorkQueue from '@/components/SystemActions/WorkQueue'\n\nimport { runFlowNowMixin } from '@/mixins/runFlowNow'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    CardTitle,\n    ClearLate,\n    ConcurrencyInfo,\n    DurationSpan,\n    LabelWarning,\n    WorkQueue\n  },\n  mixins: [runFlowNowMixin, formatTime],\n  props: {\n    projectId: {\n      required: false,\n      type: String,\n      default: () => null\n    },\n    fullHeight: {\n      required: false,\n      type: Boolean,\n      default: () => false\n    }\n  },\n  data() {\n    const tabs = {\n      upcoming: 0,\n      late: 1\n    }\n\n    return {\n      loadingKey: 0,\n      overlay: null,\n      userSetTab: false,\n      tab: tabs.upcoming,\n      tabs\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['timezone']),\n    loading() {\n      return this.loadingKey > 0\n    },\n    paused() {\n      return this.tenant?.settings?.work_queue_paused\n    },\n    lateRuns() {\n      if (!this.upcomingFlowRunsData) return null\n\n      return this.upcomingFlowRunsData.filter(run => this.runIsLate(run))\n    },\n    upcomingRuns() {\n      if (!this.upcomingFlowRunsData) return null\n\n      return this.upcomingFlowRunsData.filter(run => !this.runIsLate(run))\n    },\n    title() {\n      if (!this.upcomingFlowRunsData) return null\n\n      return this.tabProperties[this.tab].title\n    },\n    titleIcon() {\n      return this.tabProperties[this.tab].icon\n    },\n    titleIconColor() {\n      if (this.loading) return 'grey'\n\n      return this.tabProperties[this.tab].icon_color\n    },\n    systemBarColor() {\n      if (this.loading || !this.upcomingFlowRunsData) return 'secondaryGray'\n\n      return this.lateRuns?.length > 0 ? 'deepRed' : 'Success'\n    },\n    tabProperties() {\n      const upcomingCount = this.upcomingRuns?.length || 0\n      const lateCount = this.lateRuns?.length || 0\n\n      return {\n        [this.tabs.upcoming]: {\n          title: `${this.getFriendlyCount(upcomingCount)} upcoming runs`,\n          icon: 'access_time',\n          icon_color: 'primary'\n        },\n        [this.tabs.late]: {\n          title: `${this.getFriendlyCount(lateCount)} late runs`,\n          icon: 'timelapse',\n          icon_color: lateCount > 0 ? 'deepRed' : 'Success'\n        }\n      }\n    },\n    upcomingTabTitle() {\n      const upcomingCount = this.upcomingRuns?.length || 0\n\n      if (this.tab == this.tabs.upcoming || upcomingCount == 0) {\n        return 'Upcoming'\n      }\n\n      return `(${this.getFriendlyCount(upcomingCount)}) Upcoming`\n    },\n    lateTabTitle() {\n      const lateCount = this.lateRuns?.length || 0\n\n      if (this.tab == this.tabs.late || lateCount == 0) {\n        return 'Late'\n      }\n\n      return `(${this.getFriendlyCount(lateCount)}) Late`\n    }\n  },\n  watch: {\n    upcomingFlowRunsData(val) {\n      if (!val || this.userSetTab) return\n\n      if (this.tab == this.tabs.upcoming && this.lateRuns?.length > 0) {\n        this.tab = this.tabs.late\n      } else if (this.tab == this.tabs.late && this.lateRuns?.length == 0) {\n        this.tab = this.tabs.upcoming\n      }\n    },\n    ['tenant.settings.work_queue_paused'](val) {\n      if (!val) {\n        setTimeout(() => {\n          this.hideOverlay()\n        }, 1500)\n      }\n    }\n  },\n  beforeDestroy() {\n    this.upcomingFlowRunsData = []\n    this.tab = this.tabs.upcoming\n  },\n  mounted() {\n    if (this.paused) {\n      this.showOverlay('queue')\n    }\n  },\n  methods: {\n    runIsLate(run) {\n      return this.getTimeOverdue(run.scheduled_start_time) > 20000\n    },\n    getTimeOverdue(time) {\n      return new Date() - new Date(time)\n    },\n    showOverlay(kind) {\n      this.overlay = kind\n    },\n    hideOverlay() {\n      this.overlay = null\n    },\n    refetch() {\n      this.$apollo.queries.upcomingFlowRunsData.refresh()\n      this.overlay = null\n    },\n    getFriendlyCount(count) {\n      return count > 999 ? '1,000+' : count\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.upcomingFlowRunsData.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    upcomingFlowRunsData: {\n      query: require('@/graphql/Dashboard/upcoming-flow-runs.gql'),\n      variables() {\n        return {\n          projectId: this.projectId ? this.projectId : null\n        }\n      },\n      loadingKey: 'loadingKey',\n      pollInterval: 10000,\n      update: data => {\n        const timestamp = new Date().getTime()\n\n        return (data?.flow_run || []).map(run => {\n          run.cacheInvalidation = timestamp\n\n          return run\n        })\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"py-2 position-relative d-flex flex-column\"\n    style=\"height: 100%;\"\n    tile\n  >\n    <v-system-bar :color=\"systemBarColor\" :height=\"5\" absolute />\n\n    <CardTitle :title=\"title\" :icon=\"titleIcon\" :icon-color=\"titleIconColor\">\n      <v-row slot=\"title\" no-gutters class=\"d-flex align-center\">\n        <v-col cols=\"10\">\n          <div>\n            <div\n              v-if=\"loading\"\n              style=\"\n                display: inline-block;\n                height: 20px;\n                overflow: hidden;\n                width: 20px;\"\n            >\n              <v-skeleton-loader type=\"avatar\" tile />\n            </div>\n            {{ title }}\n          </div>\n          <ConcurrencyInfo\n            v-if=\"isCloud && tab === tabs.late\"\n            class=\"text-caption position-absolute\"\n            style=\"bottom: 2px;\"\n          />\n        </v-col>\n      </v-row>\n    </CardTitle>\n\n    <v-card-text v-show=\"overlay\" class=\"pa-0\">\n      <v-overlay v-show=\"overlay == 'late'\" absolute z-index=\"1\">\n        <ClearLate :flow-runs=\"lateRuns\" @finish=\"refetch\" />\n      </v-overlay>\n      <v-overlay v-show=\"overlay == 'queue'\" absolute z-index=\"1\">\n        <WorkQueue />\n      </v-overlay>\n    </v-card-text>\n\n    <v-tabs\n      v-model=\"tab\"\n      tabs-border-bottom\n      :color=\"titleIconColor\"\n      class=\"flex-grow-0\"\n      @change=\"userSetTab = true\"\n    >\n      <v-tab :key=\"tabs.upcoming\" data-cy=\"upcoming-runs-tile-upcoming\">\n        {{ upcomingTabTitle }}\n      </v-tab>\n      <v-tab :key=\"tabs.late\" data-cy=\"upcoming-runs-tile-late\">\n        <v-icon\n          v-if=\"lateRuns && lateRuns.length > 0\"\n          class=\"mr-1\"\n          small\n          color=\"deepRed\"\n        >\n          warning\n        </v-icon>\n        {{ lateTabTitle }}\n      </v-tab>\n    </v-tabs>\n\n    <v-card-text class=\"px-0 py-2 card-content\">\n      <v-tabs-items v-model=\"tab\">\n        <v-tab-item>\n          <v-skeleton-loader v-if=\"loading\" type=\"list-item-three-line\" />\n\n          <v-list-item\n            v-else-if=\"upcomingRuns && upcomingRuns.length === 0\"\n            dense\n          >\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon class=\"green--text\">check</v-icon>\n            </v-list-item-avatar>\n            <v-list-item-content class=\"my-0 py-0\">\n              <div\n                class=\"text-subtitle-1 font-weight-light\"\n                style=\"line-height: 1.25rem;\"\n              >\n                No upcoming runs.\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-virtual-scroll\n            v-else\n            :items=\"upcomingRuns\"\n            height=\"178px\"\n            item-height=\"50px\"\n          >\n            <template #default=\"{item}\">\n              <v-list-item\n                :key=\"item.id\"\n                dense\n                :disabled=\"setToRun.includes(item.id)\"\n              >\n                <v-list-item-content>\n                  <v-list-item-subtitle class=\"text-body-1 font-weight-regular\">\n                    <router-link\n                      :to=\"{ name: 'flow', params: { id: item.flow.id } }\"\n                    >\n                      {{ item.flow.name }}\n                    </router-link>\n                    <span class=\"font-weight-bold\">\n                      <v-icon style=\"font-size: 12px;\">\n                        chevron_right\n                      </v-icon>\n                    </span>\n                    <router-link\n                      :to=\"{ name: 'flow-run', params: { id: item.id } }\"\n                    >\n                      {{ item.name }}\n                    </router-link>\n                  </v-list-item-subtitle>\n\n                  <span class=\"text-caption mb-0 ml-n1 d-flex align-center\">\n                    <LabelWarning :flow=\"item.flow\" :flow-run=\"item\" />\n                    <span class=\"ml-1\">\n                      Scheduled for\n                      {{ formatDateTime(item.scheduled_start_time) }}\n                    </span>\n                  </span>\n                </v-list-item-content>\n\n                <v-list-item-action tile min-width=\"5\" class=\"text-body-2\">\n                  <v-tooltip top>\n                    <template #activator=\"{ on }\">\n                      <v-btn\n                        text\n                        x-small\n                        aria-label=\"Run Now\"\n                        :disabled=\"setToRun.includes(item.id)\"\n                        color=\"primary\"\n                        class=\"vertical-button\"\n                        v-on=\"on\"\n                        @click=\"runFlowNow(item.id, item.version, item.name)\"\n                      >\n                        <v-icon small dense color=\"primary\">fa-rocket</v-icon>\n                      </v-btn>\n                    </template>\n                    <span> Run {{ item.name }} now </span>\n                  </v-tooltip>\n                </v-list-item-action>\n              </v-list-item>\n            </template>\n          </v-virtual-scroll>\n        </v-tab-item>\n\n        <v-tab-item>\n          <v-skeleton-loader v-if=\"loading\" type=\"list-item-three-line\" />\n\n          <v-list-item v-else-if=\"lateRuns && lateRuns.length === 0\" dense>\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon class=\"green--text\">check</v-icon>\n            </v-list-item-avatar>\n            <v-list-item-content class=\"my-0 py-0\">\n              <div\n                class=\"text-subtitle-1 font-weight-light\"\n                style=\"line-height: 1.25rem;\"\n              >\n                Everything is running on schedule!\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-virtual-scroll\n            v-else\n            :items=\"lateRuns\"\n            height=\"178px\"\n            item-height=\"76px\"\n          >\n            <template #default=\"{ item }\">\n              <v-list-item :key=\"item.id\" dense three-line>\n                <v-list-item-content>\n                  <v-list-item-subtitle class=\"text-body-1 font-weight-regular\">\n                    <router-link\n                      :to=\"{ name: 'flow', params: { id: item.flow.id } }\"\n                    >\n                      {{ item.flow.name }}\n                    </router-link>\n                    <span class=\"font-weight-bold\">\n                      <v-icon style=\"font-size: 12px;\">\n                        chevron_right\n                      </v-icon>\n                    </span>\n                    <router-link\n                      :to=\"{ name: 'flow-run', params: { id: item.id } }\"\n                    >\n                      {{ item.name }}\n                    </router-link>\n                  </v-list-item-subtitle>\n\n                  <span class=\"text-caption mb-0 ml-n1 d-flex align-center\">\n                    <LabelWarning :flow=\"item.flow\" :flow-run=\"item\" />\n                    <span class=\"ml-1\">\n                      Scheduled for\n                      {{ formatDateTime(item.scheduled_start_time) }}\n                    </span>\n                  </span>\n\n                  <v-list-item-subtitle class=\"text-caption\">\n                    <DurationSpan :start-time=\"item.scheduled_start_time\" />\n                    behind schedule\n                  </v-list-item-subtitle>\n                </v-list-item-content>\n              </v-list-item>\n            </template>\n          </v-virtual-scroll>\n        </v-tab-item>\n      </v-tabs-items>\n    </v-card-text>\n\n    <v-card-actions class=\"py-0 justify-end\">\n      <v-btn\n        v-if=\"!overlay && lateRuns && lateRuns.length > 0\"\n        small\n        depressed\n        color=\"primary\"\n        text\n        style=\"z-index: 2;\"\n        @click=\"showOverlay('late')\"\n      >\n        Clear late\n      </v-btn>\n\n      <v-btn\n        v-if=\"!overlay && isCloud\"\n        small\n        depressed\n        color=\"primary\"\n        text\n        style=\"z-index: 2;\"\n        @click=\"showOverlay('queue')\"\n      >\n        Options\n      </v-btn>\n\n      <v-btn\n        v-if=\"overlay && !paused\"\n        small\n        depressed\n        plain\n        color=\"white\"\n        width=\"74\"\n        text\n        style=\"z-index: 2;\"\n        @click=\"hideOverlay\"\n      >\n        Close\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\na {\n  text-decoration: none !important;\n}\n\n.button-transition {\n  transition: border-right 150ms linear;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.card-content {\n  height: 100%;\n  max-height: calc(226px - var(--v-tabs-height));\n  overflow-y: auto;\n  position: relative;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/UsageTiles/CommittedUsage-Tile.vue",
    "content": "<script>\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { mapGetters } from 'vuex'\n\nimport MenuTooltip from '@/components/MenuTooltip'\n\nexport default {\n  components: {\n    MenuTooltip\n  },\n  mixins: [formatTime],\n  data() {\n    return {\n      usageLoadingKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license']),\n    ...mapGetters('user', ['isDark']),\n    usageLoading() {\n      return this.usageLoadingKey > 0\n    },\n    runsStyle() {\n      return {\n        [`text--${this.isDark ? 'lighten' : 'darken'}-3`]: this.usage < 10000,\n        [`text--${this.isDark ? 'lighten' : 'darken'}-3`]: this.usage < 10000,\n        [`text--${this.isDark ? 'lighten' : 'darken'}-2`]: this.usage < 50000,\n        [`text--${this.isDark ? 'lighten' : 'darken'}-1`]: this.usage < 100000,\n        'primary--text': this.usage > 0,\n        'amber--text': this.usage <= 0\n      }\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.usage.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    usage: {\n      query: require('@/graphql/Dashboard/committed-usage.gql'),\n      variables() {\n        return {\n          license_id: this.license?.id\n        }\n      },\n      skip() {\n        return !this.license?.id\n      },\n      loadingKey: 'usageLoadingKey',\n      pollInterval: 5000,\n      update: data => data?.usage.reduce((prev, val) => (prev += val.runs), 0)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"position-relative d-flex flex-column justify-space-between\"\n    style=\"height: 100%;\"\n    tile\n  >\n    <v-card-title class=\"text-h4 font-weight-light\"\n      >Run balance\n\n      <MenuTooltip v-if=\"usage && usage < 0\" hide-close>\n        <template #activator>\n          <v-icon class=\"pl-2\">error_outline</v-icon>\n        </template>\n        <div>\n          <div class=\"text-h5 font-weight-light\">\n            You're out of runs!\n          </div>\n          <div class=\"text-subtitle-1\">\n            Please contact sales@prefect.io to refresh your committed runs.\n          </div>\n        </div>\n      </MenuTooltip>\n    </v-card-title>\n    <v-card-text\n      class=\"pa-0 px-3 pt-3 d-flex align-start justify-center flex-column mb-auto\"\n    >\n      <div class=\"text-h3\">\n        <v-skeleton-loader\n          :loading=\"!usage && usageLoading\"\n          type=\"image\"\n          transition=\"quick-fade\"\n          height=\"45\"\n          width=\"100\"\n          tile\n          class=\"d-inline-block\"\n        >\n          <span :class=\"runsStyle\"> {{ usage && usage.toLocaleString() }}</span>\n        </v-skeleton-loader>\n        <span class=\"text--disabled text-subtitle-1 ml-1\">task runs</span>\n      </div>\n    </v-card-text>\n    <v-spacer />\n    <v-card-actions class=\"mt-auto\">\n      <v-spacer />\n      <v-btn\n        color=\"primary\"\n        depressed\n        dark\n        small\n        target=\"_blank\"\n        href=\"https://www.prefect.io/pricing/#contact\"\n      >\n        Add more runs\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.center-absolute {\n  left: 50%;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/UsageTiles/CycleUsage-Tile.vue",
    "content": "<script>\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  mixins: [formatTime],\n  data() {\n    return {\n      usageLoadingKey: 0,\n      invoiceLoadingKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license', 'planType']),\n    projectedCost() {\n      if (!this.invoice) return 0\n      return this.invoice.total * 100\n    },\n    nextPaymentDate() {\n      if (!this.invoice) return null\n      const nextPayment = this.invoice.next_payment_attempt * 1000\n      return this.formatLongDate(nextPayment)\n    },\n    periodStart() {\n      if (!this.invoice) return null\n      return new Date(this.invoice.period_start * 1000)\n    },\n    freeUsage() {\n      if (isNaN(this.usage)) return null\n      const percentage = this.usage / 20000\n      return percentage > 1 ? 100 : (percentage * 100).toFixed()\n    },\n    usageLoading() {\n      return this.usageLoadingKey > 0\n    },\n    invoiceLoading() {\n      return this.invoiceLoadingKey > 0\n    },\n    freeUsageStyle() {\n      return {\n        [`text--${this.isDark ? 'lighten' : 'darken'}-3`]:\n          this.freeUsage > 0 && this.freeUsage < 60,\n        [`text--${this.isDark ? 'lighten' : 'darken'}-2`]:\n          this.freeUsage >= 60 && this.freeUsage < 80,\n        [`text--${this.isDark ? 'lighten' : 'darken'}-1`]:\n          this.freeUsage >= 80 && this.freeUsage < 100,\n        'primary--text': true\n      }\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.usage.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    usage: {\n      query: require('@/graphql/Dashboard/usage.gql'),\n      variables() {\n        return {\n          from: this.periodStart,\n          license_id: this.license.id\n        }\n      },\n      loadingKey: 'usageLoadingKey',\n      skip() {\n        return !this.invoice\n      },\n      pollInterval: 120000,\n      update: data =>\n        data?.usage\n          .filter(u => u.kind == 'USAGE')\n          .reduce((prev, val) => (prev += Math.abs(val.runs)), 0) || 0\n    },\n    invoice: {\n      query: require('@/graphql/Dashboard/invoice.gql'),\n      variables() {\n        return {\n          licenseId: this.license.id\n        }\n      },\n      loadingKey: 'invoiceLoadingKey',\n      skip() {\n        return !this.license?.id\n      },\n      update: data => data?.preview_invoice\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"position-relative d-flex flex-column justify-space-between\"\n    style=\"height: 100%;\"\n    tile\n  >\n    <v-card-title class=\"text-h4 font-weight-light\"\n      >Usage this cycle</v-card-title\n    >\n    <v-card-text\n      class=\"pa-3 pt-0 d-flex align-start justify-center flex-column mb-auto\"\n    >\n      <div class=\"text-h3\">\n        <v-skeleton-loader\n          :loading=\"!usage && (invoiceLoading || usageLoading)\"\n          type=\"image\"\n          transition=\"quick-fade\"\n          height=\"45\"\n          width=\"100\"\n          tile\n          class=\"d-inline-block\"\n        >\n          <span>\n            {{ !usage ? 0 : usage.toLocaleString()\n            }}<span v-if=\"planType('FREE')\" class=\"text-h5 ml-1\"\n              >/20,000</span\n            ></span\n          >\n        </v-skeleton-loader>\n        <span class=\"text--disabled text-subtitle-1 ml-1\"\n          >successful task runs</span\n        >\n      </div>\n      <div class=\"text-subtitle-2 font-weight-light\">\n        <v-skeleton-loader\n          :loading=\"!usage && (invoiceLoading || usageLoading)\"\n          type=\"image\"\n          transition=\"quick-fade\"\n          height=\"12\"\n          width=\"22\"\n          tile\n          class=\"d-inline-block\"\n          style=\"vertical-align: baseline;\"\n        >\n          <span class=\"font-weight-medium\" :class=\"freeUsageStyle\">\n            {{ freeUsage }}\n          </span> </v-skeleton-loader\n        ><span class=\"font-weight-medium\" :class=\"freeUsageStyle\">% </span>\n        <span\n          v-if=\"planType('FREE')\"\n          class=\"text-normal text--disabled font-weight-light\"\n          >of runs used</span\n        ><span v-else class=\"text-normal text--disabled font-weight-light\"\n          >of free runs used</span\n        ></div\n      >\n    </v-card-text>\n    <v-spacer />\n    <v-card-actions v-if=\"planType('FREE')\" class=\"mt-auto\">\n      <v-spacer />\n      <v-btn\n        color=\"accentPink\"\n        depressed\n        dark\n        small\n        target=\"_blank\"\n        :to=\"'/plans'\"\n      >\n        Get more runs\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.center-absolute {\n  left: 50%;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n</style>\n"
  },
  {
    "path": "src/pages/Dashboard/UsageTiles/UpgradeUsage-Tile.vue",
    "content": "<script>\nexport default {}\n</script>\n\n<template>\n  <v-card class=\"upgrade-alert\" tile>\n    <v-card-text class=\"text-h5 font-weight-light mb-auto\" tile\n      >You're on a legacy Cloud plan\n      <div class=\"text-subtitle-1\"\n        >Upgrade to get access to usage-based pricing and new features!</div\n      >\n    </v-card-text>\n\n    <v-card-actions class=\"mt-auto\">\n      <v-spacer />\n      <v-btn\n        color=\"accentPink\"\n        depressed\n        dark\n        small\n        target=\"_blank\"\n        :to=\"'/plans'\"\n      >\n        Upgrade\n      </v-btn>\n      <v-btn small color=\"primary\" text :to=\"'/admin/account'\">\n        Details\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.upgrade-alert {\n  border-left: 6px solid var(--v-accentPink-base);\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Actions.vue",
    "content": "<script>\nimport LogRocket from 'logrocket'\nimport { mapGetters, mapActions } from 'vuex'\n\nimport DeleteButton from '@/components/DeleteFlowButton'\n\nexport default {\n  components: {\n    DeleteButton\n  },\n  props: {\n    archived: {\n      required: true,\n      type: Boolean\n    },\n    flow: {\n      required: true,\n      type: Object\n    },\n    flowGroup: {\n      required: true,\n      type: Object\n    },\n    scheduled: {\n      required: true,\n      type: Boolean\n    },\n    versions: {\n      required: true,\n      type: Array\n    }\n  },\n  data() {\n    return {\n      // Alert data\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n      alertLink: null,\n      scheduleLoading: false,\n      selectedVersion: +this.$route.query.version || null,\n\n      isRunning: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['hasPermission']),\n    isQuickRunnable() {\n      if (!this.flow.parameters) return true\n\n      return this.flow.parameters.reduce((result, param) => {\n        const parameterKey = param.name\n        if (param.required && !this.flowGroup.default_parameters[parameterKey])\n          return false\n        return result\n      }, true)\n    },\n    disableToggle() {\n      const c = !this.hasPermission('create', 'run')\n      const d = !this.hasPermission('delete', 'run')\n      const scheduled = this.isScheduled\n\n      return (c && d) || (!scheduled && c) || (scheduled && d)\n    },\n    isScheduled: {\n      get() {\n        if (this.archived) return false\n        return this.flow.is_schedule_active\n      },\n      set() {\n        return\n      }\n    },\n    schedule() {\n      return this.flow.schedule?.clocks[0] || this.flowGroup.schedule?.clocks[0]\n    }\n  },\n  watch: {\n    '$route.query.version'(val) {\n      if (this.selectedVersion == val) return\n      this.selectedVersion = +val || null\n    }\n  },\n  mounted() {\n    let version = this.versions.find(v => v.value == this.selectedVersion)\n\n    if (this.selectedVersion && !version) {\n      this.selectedVersion = null\n    }\n  },\n  methods: {\n    ...mapActions('alert', [\n      'setAlert',\n      'addNotification',\n      'updateNotification'\n    ]),\n    _changeVersion(val) {\n      if (val) {\n        let query = { ...this.$route.query, version: val }\n        this.$router.replace({\n          query: query\n        })\n      } else {\n        let query = { ...this.$route.query }\n        delete query.version\n        this.$router.replace({ query: query })\n      }\n    },\n    archiveFlow() {},\n    deleteFlow() {},\n    goToRunFlowPage() {\n      this.$router.push({\n        name: 'flow',\n        params: { id: this.flow.id, tenant: this.tenant?.slug },\n        query: { run: '' }\n      })\n    },\n    async quickRunFlow() {\n      this.isRunning = true\n      const notificationId = await this.addNotification({\n        color: 'primaryLight',\n        loading: true,\n        text: 'Creating run...',\n        dismissable: false\n      })\n\n      try {\n        const { data, errors } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-flow-run.gql'),\n          variables: {\n            id: this.flow.id\n          },\n          errorPolicy: 'all'\n        })\n\n        if (errors) throw new Error(errors?.[0]?.message)\n\n        this.isRunning = false\n\n        if (data?.create_flow_run?.id) {\n          const run = await this.$apollo.query({\n            query: require('@/graphql/Flow/flow-run-by-pk.gql'),\n            variables: {\n              id: data.create_flow_run.id\n            },\n            errorPolicy: 'all'\n          })\n\n          await this.updateNotification({\n            id: notificationId,\n            notification: {\n              color: 'primary',\n              loading: false,\n              linkText: 'Visit',\n              to: {\n                name: 'flow-run',\n                params: {\n                  id: data.create_flow_run.id,\n                  tenant: this.tenant?.slug\n                }\n              },\n              text: 'Run created!',\n              subtext: run?.data?.flow_run_by_pk?.name,\n              dismissable: true,\n              timeout: 20000\n            }\n          })\n        }\n      } catch (err) {\n        await this.updateNotification({\n          id: notificationId,\n          notification: {\n            color: 'error',\n            loading: false,\n            text: 'There was a problem creating your run',\n            subtext: err?.message?.includes('archived')\n              ? 'This flow version is archived - you likely have a newer version of your flow'\n              : 'Error',\n            dismissable: true,\n            timeout: 10000\n          }\n        })\n        LogRocket.captureException(err)\n      }\n      this.isRunning = false\n    },\n    async scheduleFlow() {\n      this.scheduleLoading = true\n\n      if (this.isScheduled) {\n        try {\n          const { data } = await this.$apollo.mutate({\n            mutation: require('@/graphql/Mutations/set-schedule-inactive.gql'),\n            variables: {\n              id: this.flow.id\n            }\n          })\n          if (data.set_schedule_inactive.success) {\n            this.alertShow = true\n            this.alertMessage = 'Schedule set to paused'\n            this.alertType = 'info'\n          }\n        } catch (error) {\n          this.isScheduled = false\n          this.alertShow = true\n          this.alertMessage = `${error}`\n          this.alertType = 'error'\n        } finally {\n          this.scheduleLoading = false\n          this.setAlert({\n            alertShow: this.alertShow,\n            alertMessage: this.alertMessage,\n            alertType: this.alertType,\n            alertLink: this.alertLink\n          })\n        }\n      } else {\n        try {\n          const { data } = await this.$apollo.mutate({\n            mutation: require('@/graphql/Mutations/set-schedule-active.gql'),\n            variables: {\n              id: this.flow.id\n            }\n          })\n\n          if (data.set_schedule_active.success) {\n            this.alertShow = true\n            this.alertMessage = 'Schedule set to active'\n            this.alertType = 'info'\n          }\n        } catch (error) {\n          this.alertShow = true\n          this.alertMessage = `${error}`\n          this.alertType = 'error'\n        } finally {\n          this.scheduleLoading = false\n          this.setAlert({\n            alertShow: this.alertShow,\n            alertMessage: this.alertMessage,\n            alertType: this.alertType,\n            alertLink: this.alertLink\n          })\n        }\n      }\n    },\n    unarchiveFlow() {}\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"pa-0 pt-3 mb-2 d-flex align-start\"\n    :class=\"[\n      $vuetify.breakpoint.xsOnly ? 'justify-center' : 'justify-end',\n      $vuetify.breakpoint.xsOnly && 'mx-auto'\n    ]\"\n  >\n    <div class=\"version-selector\">\n      <v-select\n        data-public\n        :value.sync=\"selectedVersion\"\n        :items=\"versions\"\n        dense\n        label=\"Version\"\n        hide-details\n        @change=\"_changeVersion\"\n      />\n    </div>\n\n    <v-tooltip\n      bottom\n      max-width=\"340\"\n      :open-delay=\"\n        !hasPermission('create', 'run') || !isQuickRunnable || archived\n          ? 0\n          : 750\n      \"\n    >\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <v-btn\n            class=\"vertical-button mr-2 position-relative\"\n            color=\"primary\"\n            style=\"height: 46px;\"\n            text\n            tile\n            small\n            data-cy=\"start-flow-quick-run\"\n            :disabled=\"\n              !hasPermission('create', 'run') || !isQuickRunnable || archived\n            \"\n            :loading=\"isRunning\"\n            @click=\"quickRunFlow\"\n          >\n            <v-icon>fa-rocket</v-icon>\n            <v-icon\n              small\n              class=\"position-absolute\"\n              :style=\"{\n                bottom: '-4px',\n                right: '8px',\n                transform: 'rotate(15deg)'\n              }\"\n            >\n              offline_bolt\n            </v-icon>\n            <div class=\"mb-1\">Quick Run</div>\n          </v-btn>\n        </div>\n      </template>\n      <span v-if=\"!hasPermission('create', 'run')\">\n        You don't have permission to run flows\n      </span>\n      <span v-else-if=\"!isQuickRunnable\">\n        This flow has required parameters that must be set before a run. Set a\n        default parameter value in the flow settings page or select the RUN tab\n        to launch this flow.\n      </span>\n      <span v-else-if=\"archived\">\n        This flow is archived and cannot be run.\n      </span>\n      <span v-else>\n        <p>\n          Run this flow immediately, with a generated flow run name and default\n          parameters.\n        </p>\n\n        <p class=\"mb-0\">\n          Select the RUN tab if you want to customize the flow run name, set\n          specific parameters, or provide context.\n        </p>\n      </span>\n    </v-tooltip>\n\n    <v-tooltip bottom>\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <v-badge\n            :value=\"schedule == null && isScheduled\"\n            color=\"warning\"\n            icon=\"priority_high\"\n            overlap\n            top\n            left\n          >\n            <div class=\"vertical-button\">\n              <v-switch\n                v-model=\"isScheduled\"\n                data-cy=\"schedule-toggle\"\n                hide-details\n                class=\"mr-1 v-input--vertical\"\n                color=\"primary\"\n                :loading=\"scheduleLoading\"\n                :disabled=\"disableToggle || archived\"\n                @change=\"scheduleFlow\"\n              >\n                <template #label>\n                  <v-btn small text disabled tile class=\"mb-1\">\n                    Schedule\n                  </v-btn>\n                </template>\n              </v-switch>\n            </div>\n          </v-badge>\n        </div>\n      </template>\n      <span v-if=\"!hasPermission('create', 'run')\">\n        You don't have permission to schedule flows.\n      </span>\n      <span v-else-if=\"schedule == null && isScheduled\">\n        This flow is trying to schedule runs but has no schedules! Visit this\n        flow's\n        <span class=\"font-weight-bold\">Settings > Schedules</span> to set a new\n        schedule.\n      </span>\n      <span v-else-if=\"archived\">\n        Archived flows cannot be scheduled.\n      </span>\n      <span v-else>\n        Turn {{ isScheduled ? 'off' : 'on' }} this flow's schedule\n      </span>\n    </v-tooltip>\n\n    <DeleteButton :flow=\"flow\" :flow-group=\"flowGroup\" type=\"flow\" />\n\n    <!-- <v-tooltip bottom>\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <div class=\"vertical-button ml-2\">\n            <v-switch\n              v-model=\"isArchived\"\n              disabled\n              hide-details\n              class=\"v-input--vertical\"\n              color=\"codePink\"\n            >\n              <template #label>\n                <v-btn tile small text disabled class=\"mb-1\">Archive</v-btn>\n              </template>\n            </v-switch>\n          </div>\n        </div>\n      </template>\n      <span v-if=\"isReadOnlyUser\">\n        Read-only users cannot archive flows.\n      </span>\n      <span v-else>Coming Soon!</span>\n    </v-tooltip> -->\n\n    <!-- We'll add favoriting later, which will show this flow as a favorite on the dashboard -->\n\n    <!-- <v-btn text icon color=\"prefect\">\n        <v-icon>favorite</v-icon>\n      </v-btn> -->\n  </div>\n</template>\n\n<style lang=\"scss\">\n.version-selector {\n  font-size: 16px;\n  padding-top: 12px;\n  width: 100px !important;\n\n  div {\n    font-size: 0.9rem !important;\n  }\n\n  .v-label {\n    font-size: 1rem;\n    font-weight: 500;\n    letter-spacing: 0.0892857143em;\n    line-height: 1.25rem;\n    text-transform: uppercase;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Automations-Tile.vue",
    "content": "<script>\nimport AutoCard from '@/pages/Dashboard/Automations/AutomationCard'\n\nexport default {\n  components: {\n    AutoCard\n  },\n  props: {\n    flow: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      loadingHook: 0,\n      loadCards: false,\n      sortedHooks: []\n    }\n  },\n  watch: {\n    hooks() {\n      this.sortHooks()\n    }\n  },\n  methods: {\n    async sortHooks() {\n      this.loadCards = true\n      const hooks = this.hooks ? [...this.hooks] : []\n      let filtered = hooks.filter(hook =>\n        hook.event_tags.flow_group_id?.includes(this.flow.flow_group_id)\n      )\n      const slaFlows = hooks.filter(\n        hook => hook.event_tags.flow_sla_config_id != null\n      )\n      for (let i = 0; i < slaFlows.length; i++) {\n        const { data } = await this.$apollo.query({\n          query: require('@/graphql/Automations/flow-config-by-pk.gql'),\n          variables: {\n            flowSLAConfigId: slaFlows[i].event_tags.flow_sla_config_id[0]\n          }\n        })\n        if (\n          data.flow_sla_config_by_pk.flow_groups[0].flow_group_id ==\n          this.flow.flow_group_id\n        ) {\n          filtered.push(slaFlows[i])\n        }\n      }\n      const sorted = filtered.sort(\n        (a, b) => new Date(b.created) - new Date(a.created)\n      )\n      this.sortedHooks = sorted\n      this.loadCards = false\n    }\n  },\n  apollo: {\n    hooks: {\n      query() {\n        return require('@/graphql/Automations/flow-only-hooks.gql')\n      },\n      variables() {\n        return {}\n      },\n      loadingKey: 'loadingHook',\n      update: data => data?.hook\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"pa-2 mt-2\" tile>\n    <v-list-item dense class=\"px-0\">\n      <v-list-item-avatar class=\"mr-2\" tile>\n        <v-icon class=\"icon\">\n          fad fa-random\n        </v-icon>\n      </v-list-item-avatar>\n      <v-list-item-content class=\"position: relative;\">\n        <v-list-item-title class=\"text-h6 pb-1\">\n          <div>\n            Automations\n          </div>\n        </v-list-item-title>\n      </v-list-item-content>\n    </v-list-item>\n    <v-divider class=\"ml-12 mr-2\"></v-divider>\n\n    <v-card-text class=\"full-height position-relative\">\n      <v-row>\n        <v-col cols=\"12\" class=\"pb-0\">\n          <div\n            >Displaying automations for this flow. To see all automations or\n            manage automations, go to the main\n            <router-link :to=\"{ name: 'dashboard', query: { automations: '' } }\"\n              >dashboard</router-link\n            >.</div\n          >\n        </v-col>\n        <v-progress-circular\n          v-if=\"loadCards || (!sortedHooks.length && loadingHook > 0)\"\n          class=\"mx-auto my-4\"\n          indeterminate\n          color=\"primary\"\n        />\n        <v-col\n          v-if=\"!sortedHooks.length && loadingHook == 0 && !loadCards\"\n          class=\"text-center text-h6 py-8\"\n          >There are no automations associated with this flow.</v-col\n        >\n        <v-col v-for=\"(hook, i) in sortedHooks\" :key=\"i\" cols=\"12\">\n          <v-skeleton-loader\n            v-if=\"loadingHook > 0\"\n            type=\"list-item-avatar-three-line\"\n            height=\"72\"\n          ></v-skeleton-loader\n          ><AutoCard v-else :hook=\"hook\" :can-edit=\"false\" />\n        </v-col>\n      </v-row>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.full-height {\n  min-height: 68vh;\n}\n.icon {\n  height: 24px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Describe.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nimport { artifact_parser } from '@/utils/markdownParser'\nimport { mapActions } from 'vuex'\nimport { codemirror } from 'vue-codemirror'\nimport 'codemirror/lib/codemirror.css'\n\nexport default {\n  components: {\n    CodeMirror: codemirror\n  },\n  props: {\n    flowDescription: {\n      type: String,\n      required: false,\n      default: ''\n    },\n    fgDescription: {\n      type: String,\n      required: false,\n      default: ''\n    },\n    flowGroupId: {\n      type: String,\n      required: true\n    }\n  },\n  data() {\n    return {\n      description:\n        this.newDescription || this.fgDescription || this.flowDescription || '',\n      newDescription: this.fgDescription || this.flowDescription || '',\n      textArea: false,\n      clear: false,\n      loading: false,\n      tab: 'edit',\n      reload: false\n    }\n  },\n  computed: {\n    cardColor() {\n      return this.textArea || this.newDescription\n        ? 'appForeground'\n        : 'appBackground'\n    },\n    toolBarStyle() {\n      return this.textArea\n        ? {\n            'border-color': 'var(--v-utilGrayLight-base) !important',\n            'border-bottom-style': 'solid',\n            'border-width': '1px',\n            'margin-bottom': '20px'\n          }\n        : ''\n    }\n  },\n  watch: {\n    flowGroupId() {\n      this.reload = true\n      this.newDescription = ''\n      this.description = ''\n      this.$nextTick(() => {\n        this.newDescription = this.fgDescription || this.flowDescription || ''\n        this.description =\n          this.newDescription ||\n          this.fgDescription ||\n          this.flowDescription ||\n          ''\n        this.reload = false\n      })\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    edit() {\n      this.tab = 'edit'\n    },\n    preview() {\n      this.tab = 'preview'\n    },\n    mdParser(md) {\n      return artifact_parser(md)\n    },\n    resetDescription() {\n      this.clear = true\n      this.setFlowGroupDescription()\n    },\n    closeTextArea() {\n      this.textArea = false\n      this.clear = false\n      this.tab = 'edit'\n      this.description =\n        this.newDescription || this.fgDescription || this.flowDescription || ''\n    },\n    async setFlowGroupDescription() {\n      if (this.clear) this.description = ''\n      this.loading = true\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/set-flow-description.gql'),\n          variables: {\n            flowGroupId: this.flowGroupId,\n            description: this.description\n          }\n        })\n        if (data.set_flow_group_description.success) {\n          if (this.clear || !this.description) {\n            this.description = this.flowDescription\n          }\n          this.newDescription = this.description\n        }\n      } catch (error) {\n        const errString = `${error}`\n        this.setAlert({\n          alertShow: true,\n          alertMessage: errString,\n          alertType: 'error'\n        })\n      } finally {\n        this.closeTextArea()\n        this.loading = false\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-if=\"!reload\"\n    class=\"readme\"\n    :outlined=\"!!textArea || !!newDescription\"\n    elevation=\"0\"\n    :color=\"cardColor\"\n    width=\"100%\"\n    :style=\"{\n      'border-color': 'utilGrayLight !important',\n      overflow: 'auto'\n    }\"\n  >\n    <v-btn\n      v-if=\"newDescription && !textArea\"\n      title=\"Edit ReadMe\"\n      icon\n      class=\"mt-4\"\n      absolute\n      depressed\n      right\n      color=\"primary\"\n      @click=\"textArea = true\"\n    >\n      <v-icon>edit</v-icon>\n    </v-btn>\n\n    <v-toolbar\n      v-if=\"textArea\"\n      width=\"100%\"\n      height=\"30px\"\n      dense\n      class=\"ma-0\"\n      :style=\"toolBarStyle\"\n      flat\n    >\n      <v-spacer />\n\n      <v-btn\n        v-if=\"textArea\"\n        text\n        tile\n        color=\"utilGrayDark\"\n        small\n        @click=\"closeTextArea\"\n        ><v-icon x-small>fa-times</v-icon\n        ><span style=\"text-transform: none;\" class=\"pl-1\">Cancel</span></v-btn\n      >\n      <v-btn\n        v-if=\"flowDescription && fgDescription && textArea\"\n        title=\"Reset to ReadMe added at registration\"\n        text\n        small\n        tile\n        color=\"utilGrayDark\"\n        @click=\"resetDescription\"\n        ><v-icon x-small>fa-undo-alt</v-icon>\n        <span style=\"text-transform: none;\" class=\"pl-1\">Reset</span></v-btn\n      >\n      <v-btn\n        v-if=\"textArea\"\n        text\n        small\n        tile\n        color=\"utilGrayDark\"\n        :loading=\"loading\"\n        title=\"Update ReadMe\"\n        @click=\"setFlowGroupDescription\"\n      >\n        <v-icon x-small>fa-save</v-icon>\n        <span style=\"text-transform: none;\" class=\"pl-1\">Save</span>\n      </v-btn>\n    </v-toolbar>\n    <v-toolbar\n      v-if=\"textArea\"\n      width=\"100%\"\n      dense\n      height=\"28px\"\n      class=\"ma-0 pa-0 tbar\"\n      :style=\"toolBarStyle\"\n      flat\n    >\n      <v-btn-toggle\n        v-model=\"tab\"\n        tile\n        borderless\n        class=\"ma-0\"\n        :style=\"{ height: '100%' }\"\n        color=\"primary\"\n        group\n      >\n        <v-btn class=\"ma-0\" height=\"100%\" small tile value=\"edit\">\n          <v-icon small class=\"mr-0\">\n            chevron_left\n          </v-icon>\n          <v-icon small :style=\"{ 'margin-left': '-10px' }\">\n            chevron_right\n          </v-icon>\n          <span style=\"text-transform: none;\"> Editor</span>\n        </v-btn>\n\n        <v-btn height=\"100%\" class=\"ma-0\" tile small value=\"preview\">\n          <v-icon x-small>\n            fa-eye\n          </v-icon>\n          <span style=\"text-transform: none;\" class=\"pl-2\"> Preview</span>\n        </v-btn>\n      </v-btn-toggle>\n    </v-toolbar>\n    <div v-if=\"textArea && tab === 'edit'\" class=\"cmirror\">\n      <CodeMirror\n        ref=\"textA\"\n        v-model=\"description\"\n        outlined\n        :options=\"{\n          lineNumbers: true,\n          lineWrapping: true,\n          mode: 'markdown'\n        }\"\n        line-numbers\n        type=\"markdown\"\n        autofocus\n      >\n      </CodeMirror>\n    </div>\n\n    <div\n      v-else-if=\"textArea && tab === 'preview'\"\n      :style=\"{\n        height: '70vh',\n        width: '100%',\n        'background-color': 'appForeground',\n        overflow: 'auto'\n      }\"\n      class=\"artifact md utilGreyDark--text px-8\"\n      v-html=\"mdParser(description)\"\n    ></div>\n\n    <div\n      v-else-if=\"newDescription && !loading\"\n      class=\"artifact md utilGreyDark--text mx-4 px-8 pt-4 wide\"\n      v-html=\"mdParser(newDescription)\"\n    ></div>\n    <div\n      v-else\n      class=\"text-h5\n          utilGreyDark--text pl-8 pr-12 pt-8 text-center wide\"\n    >\n      This flow has no\n      <span class=\"font-weight-medium\"> ReadMe! </span>\n\n      <div class=\"text-center pt-8\">\n        <v-btn fab title=\"Add ReadMe\" color=\"primary\" @click=\"textArea = true\"\n          ><v-icon>add</v-icon></v-btn\n        >\n      </div>\n    </div>\n  </v-card>\n</template>\n\n<style>\n.white-background-color {\n  background-color: var(--v-appForeground-base);\n}\n\n.app-background-color {\n  background-color: var(--v-appBackground-base);\n}\n\n.wide {\n  max-height: 80vh;\n  min-height: 30vh !important;\n  width: 100%;\n}\n/* stylelint-disable */\n.readme >>> div {\n  border-color: var(--v-utilGrayLight-base) !important;\n}\n\n.readme.pa-0 {\n  padding-top: 50px !important;\n}\n\n.tbar .v-toolbar__content {\n  padding-left: 0;\n}\n.cmirror .CodeMirror {\n  width: 100%;\n  height: 70vh;\n  overflow: auto;\n  background-color: var(--v-appForeground-base);\n  color: var(--v-utilGrayDark-base);\n}\n\n.CodeMirror-gutters {\n  background-color: var(--v-appForeground-base);\n  border-color: var(--v-utilGrayLight-base);\n  color: var(--v-utilGrayMid-base);\n}\n\n.CodeMirror-cursor {\n  border-color: var(--v-utilGrayMid-base);\n}\n\n.cmirror .CodeMirror-vscrollbar {\n  z-index: 4;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Details-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport LabelEdit from '@/components/LabelEdit'\nimport Parameters from '@/components/Parameters'\nimport PrefectSchedule from '@/components/PrefectSchedule'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { parametersMixin } from '@/mixins/parametersMixin'\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  filters: {\n    typeClass: val => val.split('.').pop()\n  },\n  components: {\n    CardTitle,\n    LabelEdit,\n    Parameters,\n    PrefectSchedule\n  },\n  mixins: [formatTime, parametersMixin],\n  props: {\n    flow: {\n      type: Object,\n      default: () => {}\n    },\n    flowGroup: {\n      type: Object,\n      default: () => {}\n    },\n    fullHeight: {\n      required: false,\n      type: Boolean,\n      default: () => false\n    },\n    lastFlowRun: {\n      type: Object,\n      default: () => {}\n    }\n  },\n  data() {\n    const tabs = {\n      overview: 0,\n      details: 1\n    }\n\n    return {\n      paramInfoOpen: false,\n      copiedText: {},\n      tab: tabs.overview,\n      tabs,\n      //labels\n      newLabel: '',\n      labelMenuOpen: false,\n      labelEditOpen: false,\n      labelSearchInput: '',\n      removingLabel: null,\n      newLabels: null,\n      disableRemove: false,\n      disableAdd: false,\n      valid: false,\n      errorMessage: '',\n      duplicateLabel: ''\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['role']),\n    filteredStorage() {\n      if (!this.flow.storage) return {}\n\n      const filtered = ['__version__', 'prefect_version', 'flows']\n\n      return Object.keys(this.flow.storage)\n        .filter(key => !filtered.includes(key))\n        .reduce((obj, key) => {\n          obj[key] = this.flow.storage[key]\n          return obj\n        }, {})\n    },\n    runConfigDisplayFields() {\n      if (!this.flow.run_config?.type) return []\n\n      const typeFieldMap = {\n        LocalRun: ['working_dir'],\n        DockerRun: ['image'],\n        KubernetesRun: [\n          'image',\n          'job_template_path',\n          'cpu_request',\n          'cpu_limit',\n          'memory_request',\n          'memory_limit'\n        ],\n        ECSRun: ['image', 'task_definition_path', 'cpu', 'memory'],\n        UniversalRun: []\n      }\n      const typeFields = typeFieldMap[this.flow.run_config.type] || []\n      return [\n        'type',\n        ...typeFields.filter(field => this.flow.run_config[field] != null)\n      ]\n    },\n    flows() {\n      if (!this.flow.storage?.flows) return null\n\n      return this.flow.storage.flows\n    },\n    hasUser() {\n      return this.flow?.created_by\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    clickAndCopyable(field) {\n      return ['image_tag', 'image_name', 'registry_url'].includes(field)\n    },\n    copyToClipboard(value) {\n      this.copiedText = {}\n      this.copiedText[value] = true\n      navigator.clipboard.writeText(value)\n\n      setTimeout(() => {\n        this.copiedText = {}\n        this.copiedText[value] = false\n      }, 600)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    class=\"pa-2 pr-0\"\n    tile\n    :style=\"{\n      height: fullHeight ? '100%' : 'auto',\n      'max-height': fullHeight ? '100%' : 'auto'\n    }\"\n  >\n    <v-system-bar\n      :color=\"flow.archived ? 'grey' : lastFlowRun ? lastFlowRun.state : 'grey'\"\n      :height=\"5\"\n      absolute\n    >\n      <!-- We should include a state icon here when we've got those -->\n      <!-- <v-icon>{{ flow.flow_runs[0].state }}</v-icon> -->\n    </v-system-bar>\n    <CardTitle :icon=\"flow.archived ? 'archive' : 'pi-flow'\">\n      <v-row slot=\"title\" no-gutters class=\"d-flex align-center\">\n        <v-col cols=\"10\">\n          <div class=\"text-truncate pb-1\">\n            {{ flow.name }}\n          </div>\n          <div\n            class=\"utilGrayDark--text text-caption position-absolute font-weight-medium\"\n            style=\"bottom: 2px;\"\n          >\n            {{ `Version ${flow.version}` }}\n          </div>\n        </v-col>\n      </v-row>\n    </CardTitle>\n\n    <v-tabs\n      v-model=\"tab\"\n      tabs-border-bottom\n      color=\"primary\"\n      class=\"flex-grow-0\"\n    >\n      <v-tab :key=\"tabs.overview\" data-cy=\"details-tile-overview\">\n        Overview\n      </v-tab>\n      <v-tab :key=\"tabs.details\" data-cy=\"details-tile-detail\">\n        Details\n      </v-tab>\n    </v-tabs>\n\n    <v-tabs-items v-model=\"tab\" class=\"flex-grow-1\">\n      <v-tab-item>\n        <v-list class=\"card-content\">\n          <v-list-item dense>\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"text-caption\">\n                Created <span v-if=\"hasUser\">by</span>\n              </v-list-item-subtitle>\n              <div v-if=\"hasUser\" class=\"text-subtitle-2\">\n                {{ flow.created_by.username }}\n              </div>\n              <div\n                class=\"text-caption\"\n                :class=\"{ 'font-weight-bold': !hasUser }\"\n              >\n                {{ formatTime(flow.created) }}\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n\n          <LabelEdit :flow=\"flow\" :flow-group=\"flowGroup\" />\n\n          <v-list-item v-if=\"flow.core_version\" dense>\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"text-caption\">\n                Prefect Core Version:\n              </v-list-item-subtitle>\n              <div class=\"text-subtitle-2\">{{ flow.core_version }}</div>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-list-item dense>\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"text-caption\">\n                Schedule\n              </v-list-item-subtitle>\n              <div class=\"text-subtitle-2\">\n                <PrefectSchedule\n                  v-if=\"flow.schedule || flowGroup.schedule\"\n                  :schedule=\"flow.schedule ? flow.schedule : flowGroup.schedule\"\n                />\n                <span v-else>None</span>\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n        </v-list>\n      </v-tab-item>\n      <v-tab-item>\n        <v-list class=\"card-content\">\n          <v-list-item dense>\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"utilGrayDark--text\">\n                General\n              </v-list-item-subtitle>\n              <v-divider style=\"max-width: 50%;\" />\n              <v-list-item-subtitle class=\"text-caption\">\n                <v-row no-gutters>\n                  <v-col cols=\"6\">\n                    Flow ID\n                  </v-col>\n                  <v-col\n                    cols=\"6\"\n                    class=\"text-right font-weight-bold text-truncate\"\n                  >\n                    <v-tooltip bottom>\n                      <template #activator=\"{ on }\">\n                        <span\n                          class=\"cursor-pointer show-icon-hover-focus-only pa-2px\"\n                          role=\"button\"\n                          @click=\"copyToClipboard(flow.id)\"\n                          v-on=\"on\"\n                        >\n                          <v-icon x-small class=\"mb-2px mr-2\" tabindex=\"0\">\n                            {{ copiedText[flow.id] ? 'check' : 'file_copy' }}\n                          </v-icon>\n                          {{ flow.id }}\n                        </span>\n                      </template>\n                      <span>\n                        {{ flow.id }}\n                      </span>\n                    </v-tooltip>\n                  </v-col>\n                </v-row>\n              </v-list-item-subtitle>\n              <v-list-item-subtitle class=\"text-caption\">\n                <v-row no-gutters>\n                  <v-col cols=\"6\">\n                    Flow Group ID\n                  </v-col>\n                  <v-col\n                    cols=\"6\"\n                    class=\"text-right font-weight-bold text-truncate\"\n                  >\n                    <v-tooltip bottom>\n                      <template #activator=\"{ on }\">\n                        <span\n                          class=\"cursor-pointer show-icon-hover-focus-only pa-2px\"\n                          role=\"button\"\n                          @click=\"copyToClipboard(flow.flow_group_id)\"\n                          v-on=\"on\"\n                        >\n                          <v-icon x-small class=\"mb-2px mr-2\" tabindex=\"0\">\n                            {{\n                              copiedText[flow.flow_group_id]\n                                ? 'check'\n                                : 'file_copy'\n                            }}\n                          </v-icon>\n                          {{ flow.flow_group_id }}\n                        </span>\n                      </template>\n                      <span>\n                        {{ flow.flow_group_id }}\n                      </span>\n                    </v-tooltip>\n                  </v-col>\n                </v-row>\n              </v-list-item-subtitle>\n              <v-list-item-subtitle class=\"text-caption\">\n                <v-row no-gutters>\n                  <v-col cols=\"6\">\n                    Version Group ID\n                  </v-col>\n                  <v-col\n                    cols=\"6\"\n                    class=\"text-right font-weight-bold text-truncate\"\n                  >\n                    <v-tooltip bottom>\n                      <template #activator=\"{ on }\">\n                        <span\n                          class=\"cursor-pointer show-icon-hover-focus-only pa-2px\"\n                          role=\"button\"\n                          @click=\"copyToClipboard(flow.version_group_id)\"\n                          v-on=\"on\"\n                        >\n                          <v-icon x-small class=\"mb-2px mr-2\" tabindex=\"0\">\n                            {{\n                              copiedText[flow.version_group_id]\n                                ? 'check'\n                                : 'file_copy'\n                            }}\n                          </v-icon>\n                          {{ flow.version_group_id }}\n                        </span>\n                      </template>\n                      <span>\n                        {{ flow.version_group_id }}\n                      </span>\n                    </v-tooltip>\n                  </v-col>\n                </v-row>\n              </v-list-item-subtitle>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-list-item dense>\n            <v-list-item-content v-if=\"flow.run_config\">\n              <v-list-item-subtitle class=\"utilGrayDark--text\">\n                Run Config\n              </v-list-item-subtitle>\n              <v-divider style=\"max-width: 50%;\" />\n              <v-list-item-subtitle class=\"text-caption\">\n                <v-row\n                  v-for=\"field in runConfigDisplayFields\"\n                  :key=\"field\"\n                  no-gutters\n                >\n                  <v-col cols=\"6\">\n                    {{ field }}\n                  </v-col>\n                  <v-col\n                    cols=\"6\"\n                    class=\"text-right font-weight-bold text-truncate\"\n                  >\n                    {{ flow.run_config[field] }}\n                  </v-col>\n                </v-row>\n              </v-list-item-subtitle>\n            </v-list-item-content>\n            <v-list-item-content v-else>\n              <v-list-item-subtitle class=\"utilGrayDark--text\">\n                Environment\n              </v-list-item-subtitle>\n              <v-divider style=\"max-width: 50%;\" />\n              <v-list-item-subtitle class=\"text-caption\">\n                <v-row v-if=\"flow.environment.type\" no-gutters>\n                  <v-col cols=\"6\">\n                    Type\n                  </v-col>\n                  <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                    {{ flow.environment.type }}\n                  </v-col>\n                </v-row>\n\n                <v-row v-if=\"flow.environment.executor\" no-gutters>\n                  <v-col cols=\"6\">\n                    Executor\n                  </v-col>\n                  <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                    {{ flow.environment.executor | typeClass }}\n                  </v-col>\n                </v-row>\n              </v-list-item-subtitle>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-list-item v-if=\"flow.storage\" dense class=\"mt-2\">\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"utilGrayDArk--text\">\n                Storage\n              </v-list-item-subtitle>\n              <v-divider style=\"max-width: 50%;\" />\n              <v-list-item-subtitle class=\"text-caption\">\n                <v-row\n                  v-for=\"(value, key) in filteredStorage\"\n                  :key=\"key\"\n                  no-gutters\n                >\n                  <v-col cols=\"4\">\n                    {{ key }}\n                  </v-col>\n                  <v-col\n                    cols=\"8\"\n                    class=\"text-right font-weight-bold text-truncate\"\n                  >\n                    <v-tooltip\n                      v-if=\"clickAndCopyable(key)\"\n                      bottom\n                      max-width=\"300\"\n                    >\n                      <template #activator=\"{ on }\">\n                        <span\n                          class=\"cursor-pointer show-icon-hover-focus-only pa-2px\"\n                          :class=\"{\n                            'bg-gray-transition': copiedText[value],\n                            'bg-white-transition': !copiedText[value]\n                          }\"\n                          role=\"button\"\n                          @click=\"copyToClipboard(value)\"\n                          v-on=\"on\"\n                        >\n                          <v-icon x-small class=\"mb-2px mr-2\" tabindex=\"0\">{{\n                            copiedText[value] ? 'check' : 'file_copy'\n                          }}</v-icon\n                          >{{ value }}\n                        </span>\n                      </template>\n                      <span>\n                        {{ value }}\n                      </span>\n                    </v-tooltip>\n                    <span v-else>\n                      {{ value }}\n                    </span>\n                  </v-col>\n                </v-row>\n              </v-list-item-subtitle>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-list-item v-if=\"flows\" dense class=\"mt-2\">\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"utilGrayDark--text\">\n                Flow Locations\n              </v-list-item-subtitle>\n              <v-divider style=\"max-width: 50%;\" />\n              <v-list-item-subtitle class=\"text-caption\">\n                <v-row\n                  v-for=\"(value, key) in flows\"\n                  :key=\"key\"\n                  no-gutters\n                  class=\"my-1\"\n                >\n                  <v-col cols=\"12\">\n                    {{ key }}\n                  </v-col>\n                  <v-col cols=\"12\" class=\"font-weight-bold\">\n                    {{ value }}\n                  </v-col>\n                </v-row>\n              </v-list-item-subtitle>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-list-item\n            v-if=\"flow.parameters && flow.parameters.length > 0\"\n            dense\n            two-line\n          >\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"utilGrayDark--text\">\n                Parameters\n                <v-menu\n                  v-model=\"paramInfoOpen\"\n                  :close-on-content-click=\"false\"\n                  offset-y\n                  open-on-hover\n                >\n                  <template #activator=\"{ on }\">\n                    <v-btn text icon x-small v-on=\"on\">\n                      <v-icon>\n                        info\n                      </v-icon>\n                    </v-btn>\n                  </template>\n                  <v-card tile class=\"pa-0\" max-width=\"220\">\n                    <v-card-text class=\"pb-0\">\n                      <p>\n                        Here you can see the default paramaters for your\n                        flow.</p\n                      ><p>\n                        If you want to update your flow group's parameters, you\n                        can do so on the parameters tab in\n                        <router-link\n                          :to=\"{ name: 'flow', query: { tab: 'settings' } }\"\n                          @click.native=\"paramInfoOpen = false\"\n                          >Flow Settings</router-link\n                        >.\n                      </p>\n                      <p>\n                        Refer to the\n                        <a\n                          href=\"https://docs.prefect.io/core/concepts/parameters.html#parameters\"\n                          target=\"_blank\"\n                          rel=\"noopener noreferrer\"\n                          @click=\"paramInfoOpen = false\"\n                        >\n                          documentation</a\n                        >\n                        <sup\n                          ><v-icon x-small>\n                            open_in_new\n                          </v-icon></sup\n                        >\n                        for more details on parameters.\n                      </p>\n                    </v-card-text>\n                    <v-card-actions class=\"pt-0\">\n                      <v-spacer></v-spacer>\n                      <v-btn small text @click=\"paramInfoOpen = false\"\n                        >Close</v-btn\n                      >\n                    </v-card-actions>\n                  </v-card>\n                </v-menu>\n              </v-list-item-subtitle>\n              <v-divider style=\"max-width: 50%;\" />\n              <v-list-item-subtitle>\n                <Parameters :parameters=\"defaultParameters\"></Parameters>\n              </v-list-item-subtitle>\n            </v-list-item-content>\n          </v-list-item>\n        </v-list>\n      </v-tab-item>\n    </v-tabs-items>\n  </v-card>\n</template>\n\n<style lang=\"scss\">\n.bg-gray-transition {\n  background-color: var(--v-appBackground-base);\n  transition: background-color 300ms;\n}\n\n.bg-white-transition {\n  background-color: var(--v-appForeground-base);\n  transition: background-color 300ms;\n}\n\n.card-content {\n  max-height: calc(254px - var(--v-tabs-height));\n  overflow-y: auto;\n}\n\n.label-search {\n  border-radius: 0 !important;\n  font-size: 0.85rem !important;\n\n  .v-icon {\n    font-size: 20px !important;\n  }\n}\n\n.max-h-300 {\n  max-height: 300px;\n}\n\n.mb-2px {\n  margin-bottom: 2px;\n}\n\n.pa-2px {\n  padding: 2px;\n}\n\n.show-icon-hover-focus-only {\n  .v-icon {\n    visibility: hidden;\n  }\n\n  &:hover,\n  &:focus {\n    .v-icon {\n      visibility: visible;\n    }\n  }\n}\n\n.w-100 {\n  width: 100% !important;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Errors-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport { mapGetters } from 'vuex'\nimport { roundedOneAgo } from '@/utils/dateTime'\nimport moment from '@/utils/moment'\n\nexport default {\n  components: {\n    CardTitle\n  },\n  props: {\n    aggregate: {\n      type: Boolean,\n      default: () => false\n    },\n    flow: {\n      required: true,\n      type: Object\n    },\n    fullHeight: {\n      required: false,\n      type: Boolean,\n      default: () => false\n    }\n  },\n  data() {\n    return {\n      dateFilters: [\n        { name: '1 Hour', value: 'hour' },\n        { name: '24 Hours', value: 'day' },\n        { name: '7 Days', value: 'week' },\n        { name: '30 Days', value: 'month' }\n      ],\n      loading: 0,\n      selectedDateFilter: 'day'\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone']),\n    pollInterval() {\n      return this.flow.archived ? 0 : 60000\n    },\n    filteredErrors() {\n      return this.errors\n        ?.filter(error => {\n          return error.task_runs?.length > 0\n        })\n        .map(error => error.task_runs)\n        .flat()\n    }\n  },\n  watch: {\n    flow(val, prevVal) {\n      this.$apollo.queries.errors.stopPolling()\n\n      if (this.pollInterval > 0) {\n        this.$apollo.queries.errors.startPolling(this.pollInterval)\n      } else {\n        this.$apollo.queries.errors.refetch()\n      }\n\n      if (val.archived !== prevVal.archived && val.archived) {\n        this.selectedDateFilter = 'day'\n      }\n    }\n  },\n  mounted() {\n    if (this.pollInterval > 0) {\n      this.$apollo.queries.errors.startPolling(this.pollInterval)\n    }\n  },\n  methods: {\n    formatTime(timestamp) {\n      let timeObj = moment(timestamp).tz(this.timezone),\n        shortenedTz = moment()\n          .tz(this.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone)\n          .zoneAbbr()\n      return `${\n        timeObj ? timeObj.format('h:mma') : moment(timestamp).format('h:mma')\n      } ${shortenedTz}`\n    },\n    formatTimeRelative(timestamp) {\n      let timeObj = moment(timestamp).tz(this.timezone)\n      return timeObj ? timeObj.fromNow() : moment(timestamp).fromNow()\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.errors.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    errors: {\n      query: require('@/graphql/Flow/errors.gql'),\n      variables() {\n        let variables = {\n          updated: { _gte: roundedOneAgo(this.selectedDateFilter) }\n        }\n\n        if (this.aggregate) {\n          variables.flow_group_id = this.flow.flow_group_id\n        } else {\n          variables.flow_id = this.flow.id\n        }\n\n        if (this.flow.archived) {\n          variables.updated = {\n            _gte: moment(this.flow.updated)\n              .subtract({ hours: 24 })\n              .format(),\n            _lte: moment(this.flow.updated).format()\n          }\n        }\n\n        return variables\n      },\n      loadingKey: 'loading',\n      update: data => data.flow_run\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"py-2 position-relative\"\n    tile\n    :style=\"{\n      height: fullHeight ? '100%' : 'auto'\n    }\"\n  >\n    <v-system-bar\n      :color=\"\n        flow.archived\n          ? 'grey'\n          : loading > 0\n          ? 'secondaryGray'\n          : filteredErrors && filteredErrors.length > 0\n          ? 'Failed'\n          : 'Success'\n      \"\n      :height=\"5\"\n      absolute\n    >\n      <!-- We should include a state icon here when we've got those -->\n      <!-- <v-icon>{{ flow.flow_runs[0].state }}</v-icon> -->\n    </v-system-bar>\n    <v-tooltip top>\n      <template #activator=\"{ on }\">\n        <CardTitle\n          :title=\"\n            `${filteredErrors ? filteredErrors.length : 0} Recent Task Failures`\n          \"\n          icon=\"error\"\n          :icon-color=\"\n            flow.archived || loading > 0\n              ? 'grey'\n              : filteredErrors && filteredErrors.length > 0\n              ? 'Failed'\n              : 'Success'\n          \"\n          :loading=\"errors && errors.length === 0 && loading > 0\"\n        >\n          <div slot=\"action\" v-on=\"on\">\n            <v-select\n              data-public\n              v-if=\"!flow.archived\"\n              v-model=\"selectedDateFilter\"\n              class=\"time-interval-picker\"\n              :items=\"dateFilters\"\n              dense\n              solo\n              item-text=\"name\"\n              item-value=\"value\"\n              hide-details\n              flat\n            >\n              <template #prepend-inner>\n                <v-icon color=\"utilGrayDark\" x-small>\n                  history\n                </v-icon>\n              </template>\n            </v-select>\n          </div>\n        </CardTitle>\n      </template>\n      <span>\n        Filter by when runs were last updated\n      </span>\n    </v-tooltip>\n\n    <v-list class=\"error-card-content\">\n      <v-slide-y-reverse-transition\n        v-if=\"!errors && loading > 0\"\n        mode=\"out-in\"\n        leave-absolute\n        group\n      >\n        <v-skeleton-loader key=\"skeleton\" type=\"list-item-three-line\">\n        </v-skeleton-loader>\n      </v-slide-y-reverse-transition>\n\n      <v-slide-y-reverse-transition\n        v-else-if=\"filteredErrors && filteredErrors.length > 0\"\n        leave-absolute\n        mode=\"out-in\"\n        group\n      >\n        <v-lazy\n          v-for=\"error in filteredErrors\"\n          :key=\"error.id\"\n          :options=\"{\n            threshold: 0.75\n          }\"\n          min-height=\"40px\"\n          transition=\"fade\"\n        >\n          <v-list-item\n            :to=\"{\n              name: 'task-run',\n              params: { id: error.id },\n              query: {\n                logId: ''\n              }\n            }\"\n          >\n            <v-list-item-content>\n              <v-list-item-title>\n                <div\n                  class=\"text-truncate d-block ma-0 pa-0\"\n                  style=\"max-width: 95%;\"\n                >\n                  {{ error.task.name }}\n                </div>\n              </v-list-item-title>\n              <v-list-item-subtitle class=\"font-weight-light\">\n                <div class=\"text-caption\">\n                  {{ formatTimeRelative(error.state_timestamp) }}\n                </div>\n\n                <div\n                  class=\"text-subtitle-2 font-weight-light Failed--text text--darken-1\"\n                >\n                  {{ error.state_message }}\n                </div>\n              </v-list-item-subtitle>\n            </v-list-item-content>\n\n            <v-list-item-avatar>\n              <v-icon>arrow_right</v-icon>\n            </v-list-item-avatar>\n          </v-list-item>\n        </v-lazy>\n      </v-slide-y-reverse-transition>\n\n      <v-slide-y-transition v-else leave-absolute mode=\"out-in\" group>\n        <v-list-item key=\"no-data\" color=\"grey\">\n          <v-list-item-avatar class=\"mr-0\">\n            <v-icon class=\"green--text\">check</v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content class=\"my-0 py-0\">\n            <div\n              v-if=\"!flow.archived\"\n              class=\"text-subtitle-1 font-weight-light\"\n              style=\"line-height: 1.25rem;\"\n            >\n              No reported errors in the last {{ selectedDateFilter }}...\n              Everything looks good!\n            </div>\n            <div\n              v-else\n              class=\"text-subtitle-1 font-weight-light\"\n              style=\"line-height: 1.25rem;\"\n            >\n              No errors were reported in the last\n              {{ selectedDateFilter }} before this version was archived.\n            </div>\n          </v-list-item-content>\n        </v-list-item>\n      </v-slide-y-transition>\n    </v-list>\n\n    <div v-if=\"errors && errors.length > 3\" class=\"pa-0 error-footer\"> </div>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.error-card-content {\n  max-height: 254px;\n  overflow-y: auto;\n}\n\n.error-footer {\n  background-image: linear-gradient(transparent, 60%, rgba(0, 0, 0, 0.1));\n  bottom: 6px;\n  height: 6px !important;\n  pointer-events: none;\n  position: absolute;\n  width: 100%;\n}\n\n.time-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n\na {\n  text-decoration: none !important;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Flow.vue",
    "content": "<script>\n/* eslint-disable */\nimport Actions from '@/pages/Flow/Actions'\nimport BreadCrumbs from '@/components/BreadCrumbs'\nimport NavTabBar from '@/components/NavTabBar'\nimport DetailsTile from '@/pages/Flow/Details-Tile'\nimport ErrorsTile from '@/pages/Flow/Errors-Tile'\nimport FlowRunHeartbeatTile from '@/pages/Flow/FlowRunHeartbeat-Tile'\nimport FlowRunTableTile from '@/pages/Flow/FlowRunTable-Tile'\nimport RunTiles from '@/pages/Flow/Run'\nimport SchematicTile from '@/pages/Flow/Schematic-Tile'\nimport AutomationsTile from '@/pages/Flow/Automations-Tile'\nimport Settings from '@/pages/Flow/Settings'\nimport SubPageNav from '@/layouts/SubPageNav'\nimport SummaryTile from '@/pages/Flow/Summary-Tile'\nimport DescribeTile from '@/pages/Flow/Describe'\nimport TasksTableTile from '@/pages/Flow/TasksTable-Tile'\nimport TileLayout from '@/layouts/TileLayout'\nimport TileLayoutFull from '@/layouts/TileLayout-Full'\nimport FlowRunHistoryTile from '@/pages/Flow/FlowRunHistory-Tile'\nimport UpcomingRunsTile from '@/pages/Flow/UpcomingRuns-Tile'\nimport VersionsTile from '@/pages/Flow/Versions-Tile'\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  metaInfo() {\n    return {\n      titleTemplate: `Flow | ${this.selectedFlow?.name ?? 'Prefect'}`\n    }\n  },\n  components: {\n    Actions,\n    AutomationsTile,\n    BreadCrumbs,\n    DetailsTile,\n    ErrorsTile,\n    FlowRunHeartbeatTile,\n    FlowRunTableTile,\n    NavTabBar,\n    RunTiles,\n    SchematicTile,\n    Settings,\n    SubPageNav,\n    SummaryTile,\n    TasksTableTile,\n    TileLayout,\n    TileLayoutFull,\n    FlowRunHistoryTile,\n    UpcomingRunsTile,\n    VersionsTile,\n    DescribeTile\n  },\n  async beforeRouteLeave(to, from, next) {\n    if (to.name == 'flow') {\n      await this.activateFlow(to.params.id)\n    } else {\n      this.resetActiveData()\n    }\n    return next()\n  },\n  data() {\n    return {\n      loadingKey: 0,\n      tabs: [\n        {\n          name: 'Overview',\n          target: 'overview',\n          icon: 'view_module'\n        },\n        {\n          name: 'ReadMe',\n          target: 'description',\n          icon: 'far fa-file-code'\n        },\n        {\n          name: 'Tasks',\n          target: 'tasks',\n          icon: 'pi-task'\n        },\n        {\n          name: 'Runs',\n          target: 'runs',\n          icon: 'pi-flow-run'\n        },\n        {\n          name: 'Schematic',\n          target: 'schematic',\n          icon: 'pi-schematic'\n        },\n        {\n          name: 'Automations',\n          target: 'automations',\n          icon: 'fad fa-random'\n        },\n        {\n          name: 'Run',\n          target: 'run',\n          icon: 'fa-rocket'\n        },\n        {\n          name: 'Settings',\n          target: 'settings',\n          icon: 'settings',\n          align: 'right'\n        }\n      ]\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    flowGroupId() {\n      return this.$route.params.id\n    },\n    flows() {\n      if (!this.flowGroup) return\n      return [...this.flowGroup.flows].sort((a, b) => b.version - a.version)\n    },\n    flowVersionId() {\n      return this.$route.query.version\n    },\n    latest() {\n      if (!this.flowGroup) return\n      return this.flows[0]\n    },\n    loading() {\n      return this.loadingKey > 0\n    },\n    project() {\n      if (!this.flowGroup) return\n      return this.selectedFlow.project\n    },\n    selectedFlow() {\n      if (!this.flowGroup) return\n      if (!this.flowVersionId) return this.latest\n      let flow = this.flowGroup.flows.find(f => f.version == this.flowVersionId)\n      return flow ? flow : this.latest\n    },\n    versions() {\n      if (!this.flowGroup) return\n      let versions = this.flows.map((f, i) => {\n        return {\n          text: f.version + (i === 0 ? ' (latest)' : ''),\n          value: f.version\n        }\n      })\n      versions.unshift({ text: 'All', value: null })\n\n      return versions\n    },\n    titleBarMaxWidth() {\n      if (this.$vuetify.breakpoint.lgAndUp) {\n        return '60vw'\n      } else if (this.$vuetify.breakpoint.mdAndDown) {\n        return '40vw'\n      }\n      return '30vw'\n    },\n    tab: {\n      get(){\n      const keys = Object.keys(this.$route.query ?? {})\n      if (keys.length > 0 && this.tabs?.find(tab => tab.target == keys[0])) {\n        return keys[0]\n      }\n\n      return 'overview'\n      },\n      set(value){\n        this.$router.replace({query: { [value]: null }})\n      }\n    },\n    flowTabs() {\n      return this.isCloud\n        ? this.tabs\n        : this.tabs.filter(tab => tab.name !== 'Automations')\n    }\n  },\n  watch: {\n    'this.$route.name'(val){\n      if (val == 'flow') {\n        this.activateFlow(this.$route.params.id)\n      }\n    }\n  },\n  async beforeMount() {\n  await this.activateFlow(this.$route.params.id)\n  },\n  methods: {\n    ...mapActions('data', ['activateFlow', 'resetActiveData']),\n    onIntersect([entry]) {\n      this.$apollo.queries.flowGroup.skip = !entry.isIntersecting\n      this.$apollo.queries.lastFlowRun.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowGroup: {\n      query() {\n        return require('@/graphql/Flow/flow.js').default(this.isCloud)\n      },\n      variables() {\n        return {\n          id: this.flowGroupId\n        }\n      },\n      loadingKey: 'loadingKey',\n      pollInterval: 5000,\n      update: data => data?.flow_group_by_pk\n    },\n    lastFlowRun: {\n      query: require('@/graphql/Flow/last-flow-run.gql'),\n      variables() {\n        return {\n          id: this.selectedFlow.id\n        }\n      },\n      loadingKey: 'loadingKey',\n      pollInterval: 5000,\n      update: data => data?.flow_run[0],\n      skip() {\n        return !this.selectedFlow\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet v-intersect=\"{ handler: onIntersect }\" color=\"appBackground\">\n    <SubPageNav icon=\"pi-flow\" page-type=\"Flow\">\n      <span\n        slot=\"page-title\"\n        :style=\"\n          !flowGroup\n            ? {\n                display: 'block',\n                height: '28px',\n                overflow: 'hidden',\n                width: '400px'\n              }\n            : $vuetify.breakpoint.smAndDown && { display: 'inline' }\n        \"\n      >\n        <div\n          v-if=\"flowGroup\"\n          class=\"text-truncate minTitleWidth\"\n          :style=\"{\n            width: selectedFlow.name.length + 'ch',\n            maxWidth: titleBarMaxWidth\n          }\"\n        >\n          {{ selectedFlow.name }}\n          <span\n            v-if=\"selectedFlow.archived\"\n            class=\"ml-1 text-body-1 grey--text\"\n          >\n            (Archived)\n          </span>\n        </div>\n        <div v-else style=\"width: 500px;\">\n          <v-skeleton-loader type=\"heading\" tile></v-skeleton-loader>\n        </div>\n      </span>\n\n      <span\n        slot=\"breadcrumbs\"\n        :style=\"\n          !flowGroup\n            ? {\n                height: '21px',\n                overflow: 'hidden',\n                width: '500px'\n              }\n            : $vuetify.breakpoint.smAndDown && {\n                display: 'inline',\n                'font-size': '0.875rem'\n              }\n        \"\n      >\n        <BreadCrumbs\n          v-if=\"flowGroup\"\n          slot=\"breadcrumbs\"\n          :crumbs=\"[\n            {\n              route: { name: 'project', params: { id: project.id } },\n              text: project.name\n            }\n          ]\"\n        ></BreadCrumbs>\n        <v-skeleton-loader v-else type=\"text\" />\n      </span>\n\n      <Actions\n        v-if=\"selectedFlow\"\n        slot=\"page-actions\"\n        style=\"height: 55px;\"\n        :archived=\"!!selectedFlow.archived\"\n        :flow=\"selectedFlow\"\n        :flow-group=\"flowGroup\"\n        :scheduled=\"selectedFlow.is_schedule_active\"\n        :versions=\"versions\"\n      />\n      <span slot=\"tabs\" style=\"width: 100%;\"\n        ><NavTabBar :tabs=\"flowTabs\" v-if=\"flowGroup\" page=\"flow\"\n      /></span>\n    </SubPageNav>\n\n    <v-tabs-items\n      v-model=\"tab\"\n      v-if=\"flowGroup\"\n      class=\"px-6 mx-auto tabs-border-bottom tab-full-height\"\n      :style=\"{\n        'padding-top': $vuetify.breakpoint.smOnly ? '80px' : '130px'\n      }\"\n    >\n      <v-tab-item\n        class=\"pa-0\"\n        value=\"overview\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayout>\n          <FlowRunHistoryTile\n            slot=\"row-0\"\n            :aggregate=\"!flowVersionId\"\n            :flow=\"selectedFlow\"\n            :visible=\"tab == 'overview'\"\n          />\n\n          <DetailsTile\n            slot=\"row-1-col-1-tile-1\"\n            :flow=\"selectedFlow\"\n            :flow-group=\"flowGroup\"\n            :last-flow-run=\"lastFlowRun\"\n            full-height\n          />\n\n          <SummaryTile\n            slot=\"row-1-col-2-tile-1\"\n            :aggregate=\"!flowVersionId\"\n            :flow=\"selectedFlow\"\n            full-height\n          />\n\n          <UpcomingRunsTile\n            slot=\"row-1-col-3-tile-1\"\n            :aggregate=\"!flowVersionId\"\n            :flow=\"selectedFlow\"\n            :flow-group=\"flowGroup\"\n            full-height\n          />\n\n          <ErrorsTile\n            slot=\"row-1-col-4-tile-1\"\n            :aggregate=\"!flowVersionId\"\n            :flow=\"selectedFlow\"\n            full-height\n          />\n\n          <FlowRunHeartbeatTile\n            slot=\"row-2-col-1-row-2-tile-1\"\n            :aggregate=\"!flowVersionId\"\n            :flow=\"selectedFlow\"\n          />\n        </TileLayout>\n      </v-tab-item>\n\n      <v-tab-item\n        class=\"tab-full-height\"\n        value=\"tasks\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <TasksTableTile slot=\"row-2-tile\" :flow=\"selectedFlow\" />\n        </TileLayoutFull>\n      </v-tab-item>\n\n      <v-tab-item\n        value=\"runs\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <FlowRunTableTile\n            slot=\"row-2-tile\"\n            :aggregate=\"!flowVersionId\"\n            :flow=\"selectedFlow\"\n          />\n        </TileLayoutFull>\n      </v-tab-item>\n\n      <v-tab-item\n        value=\"schematic\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <SchematicTile slot=\"row-2-tile\" :flow=\"selectedFlow\" />\n        </TileLayoutFull>\n      </v-tab-item>\n\n      <v-tab-item\n        value=\"automations\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <AutomationsTile slot=\"row-2-tile\" :flow=\"selectedFlow\" />\n        </TileLayoutFull>\n      </v-tab-item>\n\n      <v-tab-item\n        value=\"description\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <DescribeTile\n            slot=\"row-2a-tile\"\n            :fg-description=\"flowGroup.description\"\n            :flow-description=\"selectedFlow.description\"\n            :flow-group-id=\"flowGroup.id\"\n          />\n        </TileLayoutFull>\n      </v-tab-item>\n\n      <v-tab-item\n        value=\"versions\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <VersionsTile slot=\"row-2-tile\" :flow-group-id=\"flowGroup.id\" />\n        </TileLayoutFull>\n      </v-tab-item>\n\n      <v-tab-item\n        value=\"run\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <RunTiles\n          v-if=\"tab == 'run'\"\n          :flow=\"selectedFlow\"\n          :flow-group=\"flowGroup\"\n        />\n      </v-tab-item>\n\n      <v-tab-item\n        value=\"settings\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <Settings\n            slot=\"row-2-tile\"\n            :flow=\"selectedFlow\"\n            :flow-group=\"flowGroup\"\n          />\n        </TileLayoutFull>\n      </v-tab-item>\n    </v-tabs-items>\n\n    <v-bottom-navigation\n      v-if=\"$vuetify.breakpoint.smAndDown\"\n      color=\"primary\"\n      app\n      fixed\n    >\n      <v-btn :input-value=\"tab == 'overview'\" @click=\"tab = 'overview'\">\n        Overview\n        <v-icon>view_module</v-icon>\n      </v-btn>\n\n      <v-btn :input-value=\"tab == 'tasks'\" @click=\"tab = 'tasks'\">\n        Tasks\n        <v-icon>pi-task</v-icon>\n      </v-btn>\n\n      <v-btn :input-value=\"tab == 'runs'\" @click=\"tab = 'runs'\">\n        Runs\n        <v-icon>pi-flow-run</v-icon>\n      </v-btn>\n\n      <v-btn :input-value=\"tab == 'schematic'\" @click=\"tab = 'schematic'\">\n        Schematic\n        <v-icon>pi-schematic</v-icon>\n      </v-btn>\n\n      <v-btn :input-value=\"tab == 'automations'\" @click=\"tab = 'automations'\">\n        Automations\n        <v-icon>fad fa-random</v-icon>\n      </v-btn>\n\n      <v-btn :input-value=\"tab == 'versions'\" @click=\"tab = 'description'\">\n        ReadMe\n        <v-icon>far fa-file-code</v-icon>\n      </v-btn>\n\n      <!-- <v-btn disabled @click=\"tab = 'analytics'\">\n        Analytics\n        <v-icon>insert_chart_outlined</v-icon>\n      </v-btn> -->\n\n      <v-btn :input-value=\"tab == 'run'\" @click=\"tab = 'run'\">\n        Run\n        <v-icon>fa-rocket</v-icon>\n      </v-btn>\n\n      <v-btn :input-value=\"tab == 'settings'\" @click=\"tab = 'settings'\">\n        Settings\n        <v-icon>settings</v-icon>\n      </v-btn>\n    </v-bottom-navigation>\n  </v-sheet>\n</template>\n\n<style>\n.minTitleWidth {\n  min-width: 20vw;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/FlowRunHeartbeat-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport HeartbeatTimeline from '@/components/HeartbeatTimeline'\nimport { heartbeatMixin } from '@/mixins/heartbeatMixin.js'\n\nexport default {\n  components: {\n    CardTitle,\n    HeartbeatTimeline\n  },\n  mixins: [heartbeatMixin],\n  // These should eventually be moved here as data props\n  // instead of as passed in props\n  props: {\n    aggregate: {\n      type: Boolean,\n      default: () => false\n    },\n    flow: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    return { loading: 0 }\n  },\n  computed: {\n    pollInterval() {\n      return this.flow.archived ? 0 : 10000\n    }\n  },\n  watch: {\n    flow() {\n      this.$apollo.queries.heartbeat.stopPolling()\n\n      if (this.pollInterval > 0) {\n        this.$apollo.queries.heartbeat.startPolling(this.pollInterval)\n      } else {\n        this.$apollo.queries.heartbeat.refetch()\n      }\n    }\n  },\n  mounted() {\n    if (this.pollInterval > 0) {\n      this.$apollo.queries.heartbeat.startPolling(this.pollInterval)\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.heartbeat.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    heartbeat: {\n      query: require('@/graphql/Flow/heartbeat.gql'),\n      update: d => d.flow_run,\n      loadingKey: 'loading',\n      variables() {\n        let variables = {\n          state: this.checkedState,\n          filterOutStates: 'Scheduled'\n        }\n\n        if (this.aggregate) {\n          variables.flow_group_id = this.flow.flow_group_id\n        } else {\n          variables.flow_id = this.flow.id\n        }\n\n        return variables\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2\" tile>\n    <CardTitle title=\"Activity\" icon=\"show_chart\" :icon-color=\"state\">\n      <v-select\n        data-public\n        slot=\"action\"\n        v-model=\"state\"\n        class=\"state-interval-picker font-weight-regular\"\n        :items=\"states\"\n        label=\"State\"\n        dense\n        solo\n        hide-details\n        flat\n      >\n        <template #prepend-inner>\n          <v-icon color=\"utilGrayDark\" x-small>\n            label_important\n          </v-icon>\n        </template>\n      </v-select>\n    </CardTitle>\n\n    <v-container class=\"pa-0 pr-4\">\n      <HeartbeatTimeline\n        :loading=\"loading\"\n        :items=\"heartbeat\"\n        type=\"flow_run\"\n      />\n    </v-container>\n\n    <v-divider></v-divider>\n  </v-card>\n</template>\n<style lang=\"scss\" scoped>\n.state-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/FlowRunHistory-Tile.vue",
    "content": "<script>\nimport BarChart from '@/components/Visualizations/BarChart.vue'\nimport { flowRunHistoryMixin } from '@/mixins/flowRunHistoryMixin'\nimport TimelineTooltip from '@/components/TimelineTooltip'\n\nexport default {\n  components: {\n    BarChart,\n    TimelineTooltip\n  },\n  mixins: [flowRunHistoryMixin],\n  props: {\n    aggregate: {\n      type: Boolean,\n      default: () => false\n    },\n    flow: {\n      required: true,\n      type: Object\n    },\n    visible: { type: Boolean, default: () => true }\n  },\n  data() {\n    return {\n      loadingKey: 0\n    }\n  },\n  computed: {\n    loading() {\n      return this.loadingKey > 0\n    },\n    pollInterval() {\n      return this.flow.archived ? 0 : 5000\n    }\n  },\n  watch: {\n    watch: {\n      flow() {\n        this.$apollo.queries.flowRuns.stopPolling()\n\n        if (this.pollInterval > 0) {\n          this.$apollo.queries.flowRuns.startPolling(this.pollInterval)\n        } else {\n          this.$apollo.queries.flowRuns.refetch()\n        }\n      }\n    }\n  },\n  mounted() {\n    if (this.pollInterval > 0) {\n      this.$apollo.queries.flowRuns.startPolling(this.pollInterval)\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRuns.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRuns: {\n      query: require('@/graphql/Flow/timeline-flow-runs.gql'),\n      variables() {\n        let variables = { heartbeat: null }\n\n        if (this.aggregate) {\n          variables.flow_group_id = this.flow.flow_group_id\n        } else {\n          variables.flow_id = this.flow.id\n        }\n\n        return variables\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.flow_run || []\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"pa-0 pt-7 mb-4 appBackground\"\n    style=\"max-height: 114px;\"\n    tile\n    flat\n  >\n    <div class=\"text-caption text-left grey--text timeline-title\">\n      <v-icon x-small>pi-flow-run</v-icon><span class=\"ml-1\">Run History</span>\n    </div>\n\n    <div\n      v-if=\"!loading && reversedRuns.length === 0\"\n      class=\"text-caption text-center grey--text timeline-no-runs\"\n    >\n      No run history\n    </div>\n    <BarChart\n      :loading=\"loading\"\n      :items=\"reversedRuns\"\n      :breaklines=\"breaklines\"\n      :height=\"100\"\n      :min-bands=\"100\"\n      show-controls\n      :visible=\"visible\"\n      y-field=\"duration\"\n      @bar-click=\"_barClick\"\n      @bar-mouseout=\"_barMouseout\"\n      @bar-mouseover=\"_barMouseover\"\n    >\n      <TimelineTooltip v-if=\"tooltip\" slot=\"tooltip\" :tooltip=\"tooltip\" />\n    </BarChart>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.timeline-title {\n  left: 0;\n  position: absolute;\n  top: 8px;\n}\n\n.timeline-no-runs {\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/FlowRunTable-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport DurationSpan from '@/components/DurationSpan'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { STATE_NAMES } from '@/utils/states'\nexport default {\n  components: { CardTitle, DurationSpan },\n  mixins: [formatTime],\n  props: {\n    aggregate: {\n      type: Boolean,\n      default: () => false\n    },\n    flow: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      flowRuns: null,\n      flowRunsCount: null,\n      headers: [\n        {\n          text: 'Name',\n          value: 'name',\n          width: '30%',\n          mobile: true\n        },\n        {\n          text: 'Scheduled Start',\n          value: 'scheduled_start_time',\n          align: 'start',\n          width: '10%',\n          mobile: false\n        },\n        {\n          text: 'Start Time',\n          value: 'start_time',\n          align: 'start',\n          width: '10%',\n          mobile: true\n        },\n        {\n          text: 'End Time',\n          value: 'end_time',\n          align: 'start',\n          width: '10%',\n          mobile: true\n        },\n        {\n          text: 'Duration',\n          value: 'duration',\n          align: 'end',\n          width: '10%',\n          sortable: false,\n          mobile: false\n        },\n        {\n          text: 'State',\n          value: 'state',\n          align: 'end',\n          width: '5%',\n          mobile: true\n        }\n      ],\n      itemsPerPage: 15,\n      page: 1,\n      searchTerm: null,\n      sortBy: 'scheduled_start_time',\n      sortDesc: true,\n      state: [],\n      states: STATE_NAMES.slice(1).sort()\n    }\n  },\n  computed: {\n    offset() {\n      return this.itemsPerPage * (this.page - 1)\n    },\n    searchFormatted() {\n      if (!this.searchTerm) return null\n      return `%${this.searchTerm}%`\n    },\n    pollInterval() {\n      return this.flow.archived ? 0 : 5000\n    },\n    headersByViewport() {\n      return this.$vuetify.breakpoint.mdAndUp\n        ? this.headers\n        : this.headers.filter(header => header.mobile)\n    }\n  },\n  watch: {\n    flow() {\n      this.$apollo.queries.flowRuns.stopPolling()\n      this.$apollo.queries.flowRunsCount.stopPolling()\n\n      if (this.pollInterval > 0) {\n        this.$apollo.queries.flowRuns.startPolling(this.pollInterval)\n        this.$apollo.queries.flowRunsCount.startPolling(this.pollInterval)\n      } else {\n        this.$apollo.queries.flowRuns.refetch()\n        this.$apollo.queries.flowRunsCount.refetch()\n      }\n    }\n  },\n  mounted() {\n    if (this.pollInterval > 0) {\n      this.$apollo.queries.flowRuns.startPolling(this.pollInterval)\n      this.$apollo.queries.flowRunsCount.startPolling(this.pollInterval)\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRuns.skip = !entry.isIntersecting\n      this.$apollo.queries.flowRunsCount.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRuns: {\n      query: require('@/graphql/Flow/table-flow-runs.gql'),\n      variables() {\n        const orderBy = {}\n        orderBy[`${this.sortBy}`] = this.sortDesc ? 'desc' : 'asc'\n\n        let variables = {\n          limit: this.itemsPerPage,\n          name: this.searchFormatted,\n          offset: this.offset,\n          state: this.state.length === 0 ? null : this.state,\n          orderBy\n        }\n\n        if (this.aggregate) {\n          variables.flow_group_id = this.flow.flow_group_id\n        } else {\n          variables.flow_id = this.flow.id\n        }\n\n        return variables\n      },\n      update: data => data.flow_run\n    },\n    flowRunsCount: {\n      query: require('@/graphql/Flow/table-flow-runs-count.gql'),\n      variables() {\n        let variables = {\n          name: this.searchFormatted,\n          state: this.state.length === 0 ? null : this.state\n        }\n\n        if (this.aggregate) {\n          variables.flow_group_id = this.flow.flow_group_id\n        } else {\n          variables.flow_id = this.flow.id\n        }\n\n        return variables\n      },\n      update: data =>\n        data && data.flow_run_aggregate\n          ? data.flow_run_aggregate.aggregate.count\n          : null\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2 mt-2\" tile>\n    <CardTitle icon=\"pi-task-run\">\n      <div :slot=\"$vuetify.breakpoint.lgAndUp && 'title'\">\n        Flow Runs\n      </div>\n\n      <div\n        :slot=\"$vuetify.breakpoint.mdAndDown ? 'title' : 'state-filter'\"\n        :class=\"{ 'd-flex': $vuetify.breakpoint.mdAndUp }\"\n      >\n        <v-select\n          data-public\n          v-model=\"state\"\n          outlined\n          class=\"state-filter\"\n          :style=\"[\n            $vuetify.breakpoint.mdAndUp ? { width: '280px' } : { width: '100%' }\n          ]\"\n          dense\n          flat\n          solo\n          hide-details\n          :menu-props=\"{ bottom: true, offsetY: true }\"\n          clearable\n          :items=\"states\"\n          label=\"Filter by state\"\n          multiple\n        >\n          <template #selection=\"{ item, index }\">\n            <v-chip\n              v-if=\"index === 0 || index === 1\"\n              :color=\"item\"\n              label\n              small\n              text-color=\"white\"\n            >\n              {{ item }}\n            </v-chip>\n            <span v-if=\"index === 2\" class=\"grey--text text-caption\">\n              (+{{ state.length - 2 }})\n            </span>\n          </template>\n        </v-select>\n        <v-text-field\n          slot=\"action\"\n          v-model=\"searchTerm\"\n          class=\"search\"\n          dense\n          solo\n          prepend-inner-icon=\"search\"\n          hide-details\n          placeholder=\"Search for a Flow Run\"\n          flat\n          style=\"min-width: 200px;\"\n        >\n        </v-text-field>\n      </div>\n    </CardTitle>\n\n    <v-card-text>\n      <v-data-table\n        :footer-props=\"{\n          showFirstLastPage: true,\n          itemsPerPageOptions: [10, 15, 25, 50],\n          firstIcon: 'first_page',\n          lastIcon: 'last_page',\n          prevIcon: 'keyboard_arrow_left',\n          nextIcon: 'keyboard_arrow_right'\n        }\"\n        class=\"truncate-table\"\n        :headers=\"headersByViewport\"\n        :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n        :items=\"flowRuns || []\"\n        :items-per-page.sync=\"itemsPerPage\"\n        :loading=\"$apollo.queries.flowRuns.loading\"\n        must-sort\n        :page.sync=\"page\"\n        :server-items-length=\"flowRunsCount\"\n        :sort-by.sync=\"sortBy\"\n        :sort-desc.sync=\"sortDesc\"\n        :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n        calculate-widths\n      >\n        <template #item.name=\"{ item }\">\n          <truncate :content=\"item.name\">\n            <router-link\n              class=\"link text-truncate\"\n              :to=\"{ name: 'flow-run', params: { id: item.id } }\"\n            >\n              {{ item.name }}\n            </router-link>\n          </truncate>\n        </template>\n\n        <template #item.scheduled_start_time=\"{ item }\">\n          <truncate :content=\"formatTime(item.scheduled_start_time)\">\n            {{ formDate(item.scheduled_start_time) }}\n          </truncate>\n        </template>\n\n        <template #item.start_time=\"{ item }\">\n          <truncate :content=\"formatTime(item.start_time)\">\n            {{ formDate(item.start_time) }}\n          </truncate>\n        </template>\n\n        <template #item.end_time=\"{ item }\">\n          <truncate :content=\"formatTime(item.end_time)\">\n            {{ formDate(item.end_time) }}\n          </truncate>\n        </template>\n\n        <template #item.duration=\"{ item }\">\n          <DurationSpan\n            v-if=\"item.start_time\"\n            :start-time=\"item.start_time\"\n            :end-time=\"item.end_time\"\n          />\n        </template>\n\n        <template #item.state=\"{ item }\">\n          <truncate :content=\"item.state\">\n            <v-icon class=\"mr-1 pointer\" small :color=\"item.state\">\n              brightness_1\n            </v-icon>\n          </truncate>\n        </template>\n      </v-data-table>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\">\n.search {\n  border-radius: 0 !important;\n  font-size: 0.85rem;\n\n  .v-icon {\n    font-size: 20px !important;\n  }\n}\n\n.state-filter {\n  .v-label {\n    font-size: 0.85rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Run.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nimport { mapGetters, mapActions } from 'vuex'\n\nimport DateTimeSelector from '@/components/RunConfig/DateTimeSelector'\nimport ExternalLink from '@/components/ExternalLink'\nimport ListInput from '@/components/CustomInputs/ListInput'\nimport MenuTooltip from '@/components/MenuTooltip'\nimport RunConfig from '@/components/RunConfig/RunConfig'\nimport { formatTime } from '@/mixins/formatTimeMixin.js'\nimport { parametersMixin } from '@/mixins/parametersMixin.js'\nimport throttle from 'lodash/throttle'\nimport { adjectives } from '@/components/RunConfig/adjectives'\nimport { animals } from '@/components/RunConfig/animals'\nimport { isValidJson, tryParseJson, tryFormatJson } from '@/utils/json'\nimport CodeInput from '@/components/CustomInputs/CodeInput'\nimport ResettableWrapper from '@/components/CustomInputs/ResettableWrapper'\n\nconst adjectivesLength = adjectives.length\nconst animalsLength = animals.length\n\nexport default {\n  components: {\n    DateTimeSelector,\n    ExternalLink,\n    ListInput,\n    MenuTooltip,\n    RunConfig,\n    CodeInput,\n    ResettableWrapper\n  },\n  mixins: [formatTime, parametersMixin],\n  props: {\n    flow: {\n      required: true,\n      type: Object\n    },\n    flowGroup: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      stickyActions: false,\n\n      // Logging Level\n      loggingLevel: 'DEFAULT',\n      loggingLevels: [\n        { text: 'Default', value: 'DEFAULT' },\n        { text: 'Debug', value: 'DEBUG' },\n        { text: 'Info', value: 'INFO' },\n        { text: 'Warn', value: 'WARN' },\n        { text: 'Error', value: 'ERROR' },\n        { text: 'Critical', value: 'CRITICAL' }\n      ],\n\n      // Parameters\n      parameters: null,\n\n      // Context\n      context: null,\n      labels: null,\n\n      // Schedule\n      scheduledStartDateTime: null,\n      scheduledStartTimezone: null,\n\n      // Flow run name input\n      flowRunName: this.generateRandomName(),\n\n      // ID of newly-created flow run\n      flowRunId: null,\n\n      runConfig: null,\n\n      // Loading state\n      loading: false,\n\n      showAdvanced: false,\n      showParameters: this.flow.parameters?.length > 0,\n      parameterDefaults: this.flow.parameters,\n\n      when: 'now',\n      runConfigs: {\n        LocalRun: {\n          label: 'Local',\n          icon: 'fad fa-laptop-house'\n        },\n        UniversalRun: {\n          label: 'Universal',\n          icon: 'fad fa-globe'\n        },\n        DockerRun: {\n          label: 'Docker',\n          icon: 'fab fa-docker'\n        },\n        KubernetesRun: {\n          label: 'Kubernetes',\n          icon: 'pi-kubernetes'\n        },\n        ECSRun: {\n          label: 'ECS',\n          icon: 'fab fa-aws'\n        }\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'role']),\n    contextValue: {\n      get() {\n        return tryParseJson(this.context)\n      },\n      set(value) {\n        this.context = tryFormatJson(value)\n      }\n    },\n    contextModified() {\n      if (!this.contextValue) return false\n      return Object.keys(this.contextValue).filter(c => c !== '').length > 0\n    },\n    parametersValue: {\n      get() {\n        return tryParseJson(this.parameters)\n      },\n      set(value) {\n        this.parameters = tryFormatJson(value)\n      }\n    },\n    parametersModified() {\n      if (!this.parametersValue) return false\n\n      const entries = Object.entries(this.parametersValue)\n      const defaults = Object.fromEntries(\n        this.parameterDefaults?.map(entry => [entry.name, entry.default]) ?? []\n      )\n\n      const keysModified = entries.length !== this.parameterDefaults?.length\n      const valuesModified = entries.some(\n        entry => defaults[entry[0]] != entry[1]\n      )\n\n      return keysModified || valuesModified\n    },\n    runConfigTemplate() {\n      return this.runConfig && this.runConfigs[this.runConfig.type]\n    }\n  },\n  destroyed() {\n    window.removeEventListener('scroll', this.handleScroll)\n  },\n  created() {\n    this.parametersValue = this.defaultParameters.reduce((acc, param) => {\n      acc[param.name] = param.default\n      return acc\n    }, {})\n\n    this.resetRunConfigValues()\n\n    // run config > flow group > flow group run config > flow run config > flow > flow environment ?\n    if (this.flowGroup.labels?.length > 0) {\n      this.labels = this.flowGroup.labels\n    } else if (this.flowGroup.run_config?.labels?.length > 0) {\n      this.labels = this.flowGroup.run_config.labels\n    } else if (this.flow.run_config?.labels?.length > 0) {\n      this.labels = this.flow.run_config.labels\n    } else if (this.flow.labels?.length > 0) {\n      this.labels = this.flow.labels\n    } else if (this.flow.environment?.labels?.length > 0) {\n      this.labels = this.flow.environment.labels\n    }\n\n    window.addEventListener('scroll', this.handleScroll)\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    async run() {\n      if (!this.validate()) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: 'Your run configuration has errors.',\n          alertType: 'error'\n        })\n\n        return\n      }\n\n      try {\n        this.loading = true\n        // if the user has specified a logging level, pass it\n        // to the run config as an env var\n        this.overrideLoggingEnvironmentVariable()\n        const { data, errors } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-flow-run.gql'),\n          variables: {\n            context: this.contextValue,\n            id: this.flow.id,\n            flowRunName: this.flowRunName,\n            parameters: this.parametersValue,\n            scheduledStartTime: this.scheduledStartDateTime,\n            runConfig: this.getRunConfigValues(),\n            labels: this.labels\n          },\n          errorPolicy: 'all'\n        })\n        if (data?.create_flow_run) {\n          this.flowRunId = data.create_flow_run.id\n          this.renderSuccessAlert(this.flowRunId)\n          this.goToFlowRunPage()\n        } else {\n          this.showErrorAlert(errors[0].message)\n        }\n      } catch (error) {\n        this.showErrorAlert(error)\n      } finally {\n        this.loading = false\n      }\n    },\n    validate() {\n      if (!this.$refs.runConfig) {\n        return true\n      }\n      return this.$refs.runConfig.validate()\n    },\n    getRunConfigValues() {\n      if (!this.runConfig?.type) {\n        return null\n      }\n\n      const runConfig = { ...this.runConfig }\n      const jsonProperties = [\n        'env',\n        'host_config',\n        'job_template',\n        'run_task_kwargs',\n        'task_definition'\n      ]\n      jsonProperties.forEach(\n        prop => (runConfig[prop] = this.getRunConfigValue(prop))\n      )\n\n      return runConfig\n    },\n    getRunConfigValue(prop) {\n      const value = this.runConfig[prop]\n\n      if (value && isValidJson(value)) {\n        return tryParseJson(value)\n      }\n\n      return value\n    },\n    generateRandomName() {\n      const adjective = adjectives[Math.floor(Math.random() * adjectivesLength)]\n      const animal = animals[Math.floor(Math.random() * animalsLength)]\n      return adjective + '-' + animal\n    },\n    goToFlowRunPage() {\n      this.$router.push({\n        name: 'flow-run',\n        params: { id: this.flowRunId, tenant: this.tenant?.slug }\n      })\n    },\n    renderSuccessAlert(id) {\n      this.setAlert({\n        alertShow: true,\n        alertMessage: 'Your flow run has been successfully scheduled.',\n        alertType: 'success',\n        alertLink: {\n          name: 'flow-run',\n          params: { id: id, tenant: this.tenant?.slug }\n        }\n      })\n    },\n    showErrorAlert(errorMessage) {\n      this.setAlert({\n        alertShow: true,\n        alertMessage: errorMessage,\n        alertType: 'error'\n      })\n    },\n    overrideLoggingEnvironmentVariable() {\n      if (this.loggingLevel !== 'DEFAULT') {\n        const env = this.getRunConfigValue('env') ?? {}\n        env.PREFECT__LOGGING__LEVEL = this.loggingLevel\n\n        this.runConfig.env = tryFormatJson(env)\n      }\n    },\n    resetRunConfigValues() {\n      this.runConfig = { type: 'UniversalRun', ...this.flow.run_config }\n    },\n    handleScroll: throttle(\n      function() {\n        if (\n          window.innerHeight + window.pageYOffset + 188 >=\n          document.body.offsetHeight\n        ) {\n          this.stickyActions = false\n        } else this.stickyActions = true\n      },\n      150,\n      { leading: true, trailing: true }\n    )\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"utilGrayDark--text mt-2 run-container\" flat outlined>\n    <v-card-text\n      v-if=\"flow.archived\"\n      class=\"run-body d-flex align-center justify-center\"\n      style=\"min-height: 400px;\"\n    >\n      <div class=\"text-h5 text-center blue-grey--text\">\n        <v-icon x-large>archive</v-icon>\n        <div>\n          This version of your flow is archived\n\n          <MenuTooltip>\n            <p>\n              Archived versions of flows cannot be run.\n            </p>\n\n            <p>\n              Refer to the\n              <ExternalLink\n                href=\"https://docs.prefect.io/orchestration/concepts/flows.html#flow-versions-and-archiving\"\n                >documentation</ExternalLink\n              >\n              for more details on versions and archiving.\n            </p>\n          </MenuTooltip>\n        </div>\n      </div>\n    </v-card-text>\n\n    <v-card-text v-else class=\"run-body\">\n      <v-container fluid>\n        <v-row class=\"my-2 pb-8\" no-gutters>\n          <v-col cols=\"12\" md=\"3\">\n            <div class=\"py-0\" :class=\"{ 'pr-24': $vuetify.breakpoint.mdAndUp }\">\n              <div class=\"text-h5\">\n                Name\n              </div>\n            </div>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"9\">\n            <resettable-wrapper v-model=\"flowRunName\">\n              <div class=\" mt-4 mt-md-0 d-flex align-center\">\n                <v-btn\n                  color=\"primary\"\n                  fab\n                  depressed\n                  x-small\n                  title=\"Randomize run name\"\n                  @click=\"flowRunName = generateRandomName()\"\n                >\n                  <v-icon>fad fa-random</v-icon>\n                </v-btn>\n\n                <v-text-field\n                  v-model=\"flowRunName\"\n                  placeholder=\"name\"\n                  class=\"ml-2 text-h5\"\n                  hide-details\n                  outlined\n                  dense\n                />\n              </div>\n            </resettable-wrapper>\n          </v-col>\n        </v-row>\n\n        <v-row class=\"mt-2 py-8\" no-gutters>\n          <v-col cols=\"12\" md=\"3\" class=\"d-flex align-center\">\n            <div class=\"py-0\" :class=\"{ 'pr-24': $vuetify.breakpoint.mdAndUp }\">\n              <div class=\"text-h5\">\n                Start\n              </div>\n            </div>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"9\" class=\"d-flex align-center mt-4 mt-md-0\">\n            <v-btn\n              depressed\n              color=\"blue-grey\"\n              dark\n              large\n              active-class=\"primary font-weight-bold\"\n              class=\"text-none mr-2 text-h6\"\n              :class=\"{ 'lighten-4': when == 'later' }\"\n              :input-value=\"when == 'now'\"\n              @click=\"\n                when = 'now'\n                scheduledStartDateTime = null\n              \"\n              >now</v-btn\n            >\n            <v-btn\n              depressed\n              color=\"blue-grey\"\n              dark\n              large\n              active-class=\"primary font-weight-bold\"\n              class=\"text-none text-h6\"\n              :class=\"{ 'lighten-4': when == 'now' }\"\n              :input-value=\"when == 'later'\"\n              @click=\"when = 'later'\"\n              >later...</v-btn\n            >\n          </v-col>\n        </v-row>\n\n        <v-fade-transition mode=\"out-in\">\n          <v-row\n            v-if=\"when == 'later'\"\n            class=\"pt-n8 pb-8 row-divider\"\n            no-gutters\n          >\n            <v-col cols=\"0\" md=\"2\" />\n            <v-col cols=\"12\" md=\"8\">\n              <DateTimeSelector\n                v-model=\"scheduledStartDateTime\"\n                :timezone.sync=\"scheduledStartTimezone\"\n              />\n            </v-col>\n            <v-col cols=\"0\" md=\"2\" />\n          </v-row>\n        </v-fade-transition>\n\n        <v-row v-if=\"showParameters\" class=\"my-2 py-8\" no-gutters>\n          <v-col cols=\"12\" md=\"3\">\n            <div class=\"py-0\" :class=\"{ 'pr-24': $vuetify.breakpoint.mdAndUp }\">\n              <div class=\"text-h5\">\n                Inputs\n                <MenuTooltip>\n                  <p>\n                    These are the parameters that are passed to your flow\n                    through\n                    <ExternalLink\n                      href=\"https://docs.prefect.io/api/latest/core/parameters.html#parameter-2\"\n                      >Parameter tasks</ExternalLink\n                    >. To update your flow group's default parameters, visit the\n                    parameters tab of the\n                    <router-link\n                      :to=\"{ name: 'flow', query: { tab: 'settings' } }\"\n                    >\n                      settings</router-link\n                    >.\n                  </p>\n                </MenuTooltip>\n              </div>\n            </div>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"9\" class=\"mt-n4 mt-md-0 \">\n            <resettable-wrapper\n              v-model=\"parameters\"\n              class=\"resettable-dictionary-json\"\n            >\n              <code-input\n                v-model=\"parameters\"\n                show-types\n                readonly-key\n                disable-add\n                disable-remove\n              />\n            </resettable-wrapper>\n          </v-col>\n        </v-row>\n\n        <v-row class=\"my-2 py-8 row-divider\" no-gutters>\n          <v-col cols=\"12\" md=\"3\">\n            <div class=\"py-0\" :class=\"{ 'pr-24': $vuetify.breakpoint.mdAndUp }\">\n              <div class=\"text-h5\">\n                Labels\n                <MenuTooltip>\n                  <p>\n                    Labels are identifiers used by Prefect Agents for selecting\n                    flow runs when polling for work. Labels that exist on both\n                    the run and the agent will be submitted!\n                  </p>\n\n                  <p>\n                    Refer to the\n                    <ExternalLink\n                      href=\"https://docs.prefect.io/orchestration/execution/overview.html#labels\"\n                      >documentation</ExternalLink\n                    >\n                    for more details on labels.\n                  </p>\n                </MenuTooltip>\n                <span class=\"text-body-2 text--disabled ml-2\">(Optional)</span>\n              </div>\n            </div>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"9\" class=\"mt-n4 mt-md-0 text-body-1\">\n            <ListInput v-model=\"labels\" label=\"Labels\" />\n          </v-col>\n        </v-row>\n\n        <v-row v-if=\"showAdvanced\" class=\"my-2 py-8 row-divider\" no-gutters>\n          <v-row class=\"my-2 py-8\" no-gutters>\n            <v-col cols=\"12\" md=\"3\">\n              <div\n                class=\"py-0\"\n                :class=\"{ 'pr-24': $vuetify.breakpoint.mdAndUp }\"\n              >\n                <div class=\"text-h5\">\n                  Logging Level\n                  <MenuTooltip>\n                    <p>\n                      Logging level for the flow run. If none is specified,\n                      default agent logging level will be used.\n                    </p>\n                    <p>\n                      This can also be controlled by providing an environment\n                      variable, \"PREFECT__LOGGING__LEVEL\".\n                    </p>\n                    <p>\n                      Any dropdown selection besides \"Default\" will override the\n                      environment variable.\n                    </p>\n                    <p>\n                      Please note this is only guaranteed to work for Agents\n                      running Prefect Core 0.14.17 or later.\n                    </p>\n                  </MenuTooltip>\n                </div>\n              </div>\n            </v-col>\n\n            <v-col cols=\"12\" md=\"9\" class=\"mt-n4 mt-md-0\">\n              <resettable-wrapper v-model=\"loggingLevel\">\n                <v-select\n                  data-public\n                  v-model=\"loggingLevel\"\n                  outlined\n                  :items=\"loggingLevels\"\n                >\n                  <template #item=\"{ item }\">\n                    <div>\n                      <v-chip\n                        class=\"ma-2 debuglevel cursor-pointer\"\n                        :class=\"item.text.toLowerCase()\"\n                      >\n                        {{ item.text }}\n                      </v-chip>\n                    </div>\n                  </template>\n                  <template #selection=\"{ item }\">\n                    <div>\n                      <v-chip\n                        class=\"ma-2 debuglevel cursor-pointer\"\n                        :class=\"item.text.toLowerCase()\"\n                      >\n                        {{ item.text }}\n                      </v-chip>\n                    </div>\n                  </template>\n                </v-select>\n              </resettable-wrapper>\n            </v-col>\n          </v-row>\n        </v-row>\n\n        <v-row v-if=\"showAdvanced\" class=\"my-2 py-8 row-divider\" no-gutters>\n          <v-col cols=\"12\" md=\"3\">\n            <div class=\"py-0\" :class=\"{ 'pr-24': $vuetify.breakpoint.mdAndUp }\">\n              <div class=\"text-h5\">\n                Context\n                <MenuTooltip>\n                  <p>\n                    The\n                    <strong>context</strong> for your run to share information\n                    between tasks without the need for explicit task arguments.\n                  </p>\n\n                  <p>\n                    Refer to the\n                    <ExternalLink\n                      href=\"https://docs.prefect.io/core/concepts/execution.html#context\"\n                      >documentation</ExternalLink\n                    >\n                    for more details on context.\n                  </p>\n                </MenuTooltip>\n                <span class=\"text-body-2 text--disabled ml-2\">(Optional)</span>\n              </div>\n            </div>\n          </v-col>\n\n          <v-col cols=\"12\" md=\"9\" class=\"mt-n4 mt-md-0 text-body-1\">\n            <resettable-wrapper\n              v-model=\"context\"\n              class=\"resettable-dictionary-json\"\n            >\n              <code-input v-model=\"context\" show-types />\n            </resettable-wrapper>\n          </v-col>\n        </v-row>\n\n        <v-row v-if=\"showAdvanced\" class=\"mt-8\" no-gutters>\n          <div class=\"d-flex flex-grow-1 justify-space-between\">\n            <div class=\"text-h5\">\n              Run Configuration\n              <MenuTooltip>\n                <p>\n                  The settings that determine where and how your flow should be\n                  executed. Each run config type corresponds to an agent;\n                  options displayed depend on the type of config selected.\n                </p>\n\n                <p>\n                  Refer to the\n                  <ExternalLink\n                    href=\"https://docs.prefect.io/orchestration/flow_config/run_configs.html#labels\"\n                    >documentation</ExternalLink\n                  >\n                  for more details on run configs, including setting them at\n                  registration time.\n                </p>\n              </MenuTooltip>\n              <span class=\"text-body-2 text--disabled ml-2\">(Optional)</span>\n            </div>\n            <v-btn\n              class=\"text-none\"\n              color=\"utilGrayLight\"\n              x-small\n              depressed\n              @click=\"resetRunConfigValues\"\n              >Reset to default values</v-btn\n            >\n          </div>\n\n          <RunConfig ref=\"runConfig\" v-model=\"runConfig\" />\n        </v-row>\n\n        <div class=\"text-center\">\n          <v-btn\n            depressed\n            text\n            outlined\n            class=\"text-none utilGrayDark--text mt-8 py-6\"\n            @click=\"showAdvanced = !showAdvanced\"\n          >\n            <div>\n              <v-icon v-if=\"showAdvanced\" small>\n                expand_less\n              </v-icon>\n              <div class=\"font-weight-regular\">\n                {{ showAdvanced ? 'Hide' : 'Show' }}\n                advanced run configuration\n              </div>\n              <v-icon v-if=\"!showAdvanced\" small>\n                expand_more\n              </v-icon>\n            </div>\n          </v-btn>\n        </div>\n      </v-container>\n    </v-card-text>\n\n    <!-- This is used to make sure the height of the document doesn't change during the scroll event handling -->\n    <div\n      v-if=\"!flow.archived\"\n      class=\"run-actions placeholder\"\n      :class=\"{\n        sticky: !stickyActions,\n        lg: $vuetify.breakpoint.mdAndUp,\n        sm: $vuetify.breakpoint.smAndDown\n      }\"\n    />\n\n    <v-card-actions\n      v-if=\"!flow.archived\"\n      class=\"run-actions px-4 d-flex align-center\"\n      :class=\"{\n        sticky: stickyActions,\n        'px-12': stickyActions,\n        lg: $vuetify.breakpoint.mdAndUp,\n        sm: $vuetify.breakpoint.smAndDown\n      }\"\n    >\n      <div\n        class=\"text-h4\"\n        :class=\"{\n          'white--text': stickyActions\n        }\"\n        style=\"max-width: 50%;\"\n      >\n        <div\n          class=\"text-body-2 text--disabled text-uppercase font-weight-medium\"\n          style=\"line-height: 0.8rem !important;\"\n        >\n          Run\n        </div>\n        <div class=\"text-truncate\">{{ flowRunName }}</div>\n      </div>\n\n      <v-divider\n        class=\"mx-4 vertical-divider my-auto\"\n        vertical\n        :style=\"{\n          'border-color': stickyActions ? 'appForeground' : null\n        }\"\n      />\n\n      <div\n        class=\"text-caption py-2 summary\"\n        :class=\"{ 'summary-background': stickyActions }\"\n      >\n        <div\n          :class=\"{\n            'white--text': stickyActions\n          }\"\n        >\n          <span>When:</span>\n          <span class=\"float-right font-weight-medium ml-2 accentGreen--text\"\n            >{{\n              when == 'now'\n                ? 'now'\n                : formatDateTimeFromUTC(\n                    scheduledStartDateTime,\n                    scheduledStartTimezone\n                  )\n            }}\n          </span>\n        </div>\n\n        <div\n          v-if=\"showParameters\"\n          :class=\"{\n            'white--text': stickyActions\n          }\"\n        >\n          <span>Parameters:</span>\n          <span class=\"float-right font-weight-medium ml-2\">\n            <span v-if=\"parametersModified\" class=\"accentGreen--text\">\n              modified\n            </span>\n            <span v-else>default</span>\n          </span>\n        </div>\n\n        <div\n          :class=\"{\n            'white--text': stickyActions\n          }\"\n        >\n          <span>Context:</span>\n          <span class=\"float-right font-weight-medium ml-2\">\n            <span v-if=\"contextModified\" class=\"accentGreen--text\">\n              modified\n            </span>\n            <span v-else>default</span>\n          </span>\n        </div>\n\n        <div\n          :class=\"{\n            'white--text': stickyActions\n          }\"\n        >\n          <span>RunConfig:</span>\n          <span class=\"float-right font-weight-medium ml-2\">\n            <span v-if=\"runConfigTemplate\" class=\"accentGreen--text\">\n              <span :key=\"runConfigTemplate.icon\">\n                <i :class=\"runConfigTemplate.icon\" class=\"fa-sm pi-1x\"> </i>\n              </span>\n\n              <span> {{ runConfigTemplate.label }}</span>\n            </span>\n            <span v-else>none</span>\n          </span>\n        </div>\n      </div>\n\n      <v-spacer></v-spacer>\n\n      <v-btn\n        class=\"text-none text-h5 px-4 run-tab-icon\"\n        :class=\"{ 'blue--icon': stickyActions }\"\n        :color=\"stickyActions ? 'appForeground' : 'primary'\"\n        depressed\n        x-large\n        :loading=\"loading\"\n        :disabled=\"flow.archived\"\n        @click=\"run\"\n      >\n        Run\n        <i class=\"fad fa-rocket ml-2\" />\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.vertical-divider {\n  height: 70%;\n  min-height: 0;\n  opacity: 0.6;\n}\n\n.pr-24 {\n  padding-right: 124px !important;\n}\n\n.flow-root {\n  display: flow-root;\n}\n\n.subheader-height {\n  height: 24px;\n}\n\n.width-100 {\n  width: 100%;\n}\n\n.run-actions {\n  background-color: var(--v-appForeground-base);\n  border-top: 1px solid var(--v-utilGrayLight-base);\n  height: 86px;\n  transition: all 150ms;\n  width: 100%;\n\n  &.placeholder {\n    background-color: var(--v-appForeground-base) !important;\n    position: relative !important;\n    transition: none;\n\n    &.sticky {\n      border-bottom: 0 !important;\n      border-top: 0 !important;\n      height: 0 !important;\n    }\n  }\n\n  &.sticky {\n    background-color: var(--v-primary-base);\n    bottom: 0;\n    left: 0;\n    position: fixed;\n\n    // Makes sure the actions are always z-index above the footer (which is z-index 3)\n    z-index: 4;\n\n    &.lg {\n      height: 86px;\n    }\n\n    &.sm {\n      border-bottom: 1px solid var(--v-utilGrayLight-base);\n      bottom: 56px;\n      height: 80px;\n      z-index: 5;\n    }\n  }\n}\n\n.summary {\n  display: grid;\n  grid-auto-flow: column;\n  grid-template-rows: repeat(2, 1fr);\n  height: 60px;\n  width: auto;\n\n  div {\n    min-width: 165px;\n    padding: 0 16px;\n  }\n\n  div:nth-child(n + 3) {\n    border-left: 1px solid rgba(255, 255, 255, 0.2);\n  }\n\n  &.summary-background {\n    background-color: rgba(0, 0, 0, 0.2);\n    border-radius: 2px;\n    color: var(--v-appForeground-base);\n  }\n}\n\n.row-divider:not(:last-of-type) {\n  position: relative;\n\n  &::after {\n    background-color: var(--v-utilGrayLight-base);\n    bottom: 0;\n    content: '';\n    height: 1px;\n    margin: auto;\n    position: absolute;\n    width: 100%;\n  }\n}\n\n.ma-2.debuglevel {\n  color: var(--v-primaryLight-lighten5);\n  font-weight: bold;\n  justify-content: center;\n  width: 75px;\n\n  &.default {\n    background: var(--v-success-lighten2);\n  }\n\n  &.error {\n    background: var(--v-error-lighten2);\n  }\n\n  &.warn {\n    background: var(--v-warning-lighten1);\n  }\n\n  &.info {\n    background: var(--v-info-lighten2);\n  }\n\n  &.debug {\n    background: var(--v-Looped-lighten2);\n  }\n\n  &.critical {\n    background: var(--v-failRed-base);\n  }\n}\n</style>\n\n<style lang=\"scss\">\n.run-tab-icon {\n  .svg-inline--fa {\n    --fa-primary-color: var(--v-appForeground-base);\n    --fa-secondary-color: var(--v-secondaryGrayLight-base);\n    --fa-secondary-opacity: 0.5;\n    transition: all 150ms linear;\n  }\n\n  &.blue--icon {\n    .svg-inline--fa {\n      --fa-primary-color: var(--v-primary-base);\n      --fa-secondary-color: var(--v-utilGrayLight-base);\n      --fa-secondary-opacity: 1;\n    }\n  }\n\n  &:hover,\n  &:focus {\n    .svg-inline--fa {\n      --fa-secondary-color: var(--v-accentPink-base);\n      --fa-secondary-opacity: 1;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Schematic-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport SchematicFlow from '@/components/Schematics/Schematic-Flow'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    CardTitle,\n    SchematicFlow\n  },\n  props: {\n    flow: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      expanded: true,\n      showCards: true,\n      tasks: []\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone'])\n  },\n  watch: {},\n  methods: {},\n  apollo: {\n    flow_by_pk: {\n      query: require('@/graphql/Schematics/flow.gql'),\n      variables() {\n        return {\n          id: this.flow.id\n        }\n      },\n      skip() {\n        return !this.flow\n      },\n      update(data) {\n        if (data.flow_by_pk) {\n          this.tasks = data.flow_by_pk.tasks\n        } else {\n          this.tasks = []\n        }\n\n        return data.flow_by_pk\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"pa-2 mt-2\" tile>\n    <CardTitle title=\"Schematic\" icon=\"pi-schematic\">\n      <div slot=\"action\" class=\"d-flex align-end justify-center flex-column\">\n        <v-checkbox\n          v-model=\"showCards\"\n          dense\n          label=\"Show Cards\"\n          color=\"primary\"\n          class=\"my-0 mr-4\"\n          hide-details\n        ></v-checkbox>\n      </div>\n    </CardTitle>\n\n    <v-card-text class=\"full-height position-relative\">\n      <SchematicFlow\n        :schematic-id=\"flow.id\"\n        :show-cards=\"showCards\"\n        :tasks=\"tasks\"\n      />\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.full-height {\n  min-height: 68vh;\n}\n\n.task-tile {\n  right: 1rem;\n  top: 1rem;\n  width: 25%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Settings/ClockForm.vue",
    "content": "<script>\n/* eslint-disable */\n\nimport CronForm from '@/pages/Flow/Settings/ClockForms/Cron'\nimport IntervalForm from '@/pages/Flow/Settings/ClockForms/Interval'\nimport SimpleForm from '@/pages/Flow/Settings/ClockForms/Simple'\nimport ScheduleParameters from '@/pages/Flow/Settings/ScheduleParameters'\nimport { formatJson, isValidJson, parseJson } from '@/utils/json'\n\nimport moment from 'moment-timezone'\n\nconst timezones = [...moment.tz.names()].map(tz => {\n  return { text: tz.replace(/_/g, ' '), value: tz }\n})\n\nexport default {\n  components: {\n    CronForm,\n    IntervalForm,\n    SimpleForm,\n    ScheduleParameters\n  },\n  props: {\n    defaultParameters: {\n      type: Array,\n      required: false,\n      default: () => {}\n    },\n    selectedTab: {\n      type: [Number, String],\n      required: true,\n      default: () => 0\n    },\n    clock: {\n      type: Object,\n      required: false,\n      default: () => {\n        return {}\n      }\n    },\n    cron: {\n      type: String,\n      required: false,\n      default: () => '* * * * *'\n    },\n    interval: {\n      type: [String, Number],\n      required: false,\n      default: () => 60000000 // Defaults to 1 minute\n    },\n    title: {\n      type: String,\n      required: false,\n      default: () => 'New Schedule'\n    },\n    timezone: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    param: {\n      type: [Object, Array],\n      required: false,\n      default: () => null\n    },\n    flowGroupClocks: {\n      type: Array,\n      required: false,\n      default: () => []\n    }\n  },\n  data() {\n    return {\n      tzs: timezones,\n      selectedTimezone: this.timezone,\n      simpleSelectedTimezone: this.timezone,\n      advanced: false,\n      // Sets the default advanced tab\n      // if a certain type was specific\n      // but defaults to Cron\n      advancedType: this.$options.propsData?.cron\n        ? 'cron'\n        : this.$options.propsData?.interval\n        ? 'interval'\n        : 'interval',\n      advancedTypes: ['cron', 'interval'],\n      cronModel: this.cron,\n      intervalModel: this.interval,\n      simpleModel: this.clock.cron || this.clock.interval || '0 * * * *',\n      valid: true,\n      parameter: null,\n      checked: []\n    }\n  },\n  created() {\n    const params = this.clock?.parameter_defaults ?? {}\n\n    this.parameter = this.formatParams(this.allDefaultParameters, params)\n    this.checked = Object.keys(params)\n  },\n  computed: {\n    allDefaultParameters() {\n      if (!this.defaultParameters) return {}\n\n      return this.defaultParameters.reduce((obj, item) => {\n        obj[item.name] = item.default\n        return obj\n      }, {})\n    },\n    clockToAdd() {\n      return this.advanced ? `${this.advancedType}Model` : 'simpleModel'\n    },\n    createOrSave() {\n      return Object.keys(this.clock ? this.clock : {})?.length === 0\n        ? 'Create'\n        : 'Save'\n    }\n  },\n  methods: {\n    checkDefaultParameters(parameterObj) {\n      return Object.values(parameterObj).length > 0\n    },\n    formatParams(...params) {\n      const combined = params.reduce(\n        (result, obj) => ({ ...result, ...obj }),\n        {}\n      )\n      return formatJson(combined)\n    },\n    cancel() {\n      this.$emit('cancel')\n    },\n    confirm() {\n      const clockType =\n        typeof this[this.clockToAdd] == 'string' ? 'CronClock' : 'IntervalClock'\n      const parameters =\n        this.parameter != null && isValidJson(this.parameter)\n          ? parseJson(this.parameter)\n          : {}\n      const checked = Object.entries(parameters).reduce(\n        (result, [key, value]) => {\n          if (this.checked.includes(key)) {\n            result[key] = value\n          }\n\n          return result\n        },\n        {}\n      )\n      const clock = {\n        type: clockType,\n        [clockType == 'IntervalClock' ? 'interval' : 'cron']: this[\n          this.clockToAdd\n        ],\n        parameter_defaults: checked,\n        timezone: this.advanced\n          ? this.selectedTimezone\n          : this.simpleSelectedTimezone\n      }\n      this.$emit('confirm', clock)\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div\n      class=\"d-flex flex-column align-start justify-start\"\n      style=\"height: 100%;width: 100%;\"\n    >\n      <div class=\"d-flex justify-end mt-2\" style=\"width: 100%;\">\n        <v-switch\n          v-show=\"selectedTab === 0\"\n          v-model=\"advanced\"\n          inset\n          label=\"Advanced\"\n          class=\"mt-0\"\n          hide-details\n        ></v-switch>\n      </div>\n\n      <v-card-text\n        v-show=\"selectedTab === 0\"\n        style=\"max-height: fill;\n      overflow: auto;\"\n      >\n        <v-fade-transition mode=\"out-in\">\n          <div\n            v-if=\"advanced\"\n            key=\"1\"\n            class=\"mt-4 d-block\"\n            style=\"max-width: 100%;\"\n          >\n            <v-chip-group v-model=\"advancedType\" column mandatory>\n              <v-chip\n                v-for=\"type in advancedTypes\"\n                :key=\"type\"\n                active-class=\"primary\"\n                class=\"px-6 text-capitalize\"\n                label\n                :value=\"type\"\n              >\n                {{ type }}\n              </v-chip>\n            </v-chip-group>\n            <v-fade-transition mode=\"out-in\">\n              <div v-if=\"advancedType == 'cron'\" key=\"Cron\">\n                <CronForm\n                  v-model=\"cronModel\"\n                  :valid.sync=\"valid\"\n                  class=\"mt-2\"\n                />\n                <v-autocomplete\n                  data-public\n                  v-model=\"selectedTimezone\"\n                  :items=\"tzs\"\n                  outlined\n                  label=\"Time Zone\"\n                  style=\"margin-top: 110px;\"\n                  prepend-inner-icon=\"access_time\"\n                  :menu-props=\"{ contentClass: 'tz' }\"\n                />\n                <v-alert\n                  v-if=\"flowGroupClocks.length > 0\"\n                  border=\"left\"\n                  colored-border\n                  elevation=\"0\"\n                  type=\"warning\"\n                  dense\n                  icon=\"warning\"\n                >\n                  <span class=\"text-body-2 ma-0\">\n                    Setting the timezone here will take precedence over existing\n                    flow group schedule timezones\n                  </span>\n                </v-alert>\n              </div>\n              <div v-else-if=\"advancedType == 'interval'\" key=\"Interval\">\n                <IntervalForm v-model=\"intervalModel\" class=\"mt-4\" />\n              </div>\n            </v-fade-transition>\n          </div>\n          <div v-else key=\"2\" class=\"mt-4 d-block\" style=\"max-width: 100%;\">\n            <SimpleForm v-model=\"simpleModel\" />\n            <v-autocomplete\n              v-if=\"typeof simpleModel !== 'number'\"\n              v-model=\"simpleSelectedTimezone\"\n              :items=\"tzs\"\n              outlined\n              label=\"Time Zone\"\n              prepend-inner-icon=\"access_time\"\n              :menu-props=\"{ contentClass: 'tz' }\"\n            />\n            <v-alert\n              v-if=\"flowGroupClocks.length > 0\"\n              border=\"left\"\n              colored-border\n              elevation=\"0\"\n              type=\"warning\"\n              dense\n              icon=\"warning\"\n            >\n              <span class=\"text-body-2 ma-0\">\n                Setting the timezone here will take precedence over existing\n                flow group schedule timezones\n              </span>\n            </v-alert>\n          </div>\n        </v-fade-transition>\n      </v-card-text>\n    </div>\n\n    <div v-show=\"selectedTab === 1\">\n      <div\n        v-if=\"!checkDefaultParameters(allDefaultParameters)\"\n        class=\"mt-8 text-body-1\"\n      >\n        This flow has no default parameters.\n      </div>\n\n      <div v-else>\n        <p class=\"mt-8 text-body-1\">\n          Checked parameters will override their corresponding defaults for runs\n          generated from this schedule.\n        </p>\n\n        <schedule-parameters\n          v-model=\"parameter\"\n          style=\"margin: 20px;\"\n          :checked.sync=\"checked\"\n        />\n      </div>\n    </div>\n\n    <div\n      style=\"\n      bottom: 0;\n      padding: 15px;\n      position: absolute;\n      right: 0;\n      \"\n    >\n      <v-btn depressed class=\"mx-1\" @click.stop=\"cancel\">\n        Cancel\n      </v-btn>\n      <v-btn\n        depressed\n        class=\"mx-1\"\n        color=\"primary\"\n        :disabled=\"!valid\"\n        @click.stop=\"confirm\"\n      >\n        {{ createOrSave }}\n      </v-btn>\n    </div>\n  </div>\n</template>\n\n<style>\n/* stylelint-disable */\n.tz.v-menu__content .v-select-list {\n  max-width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Settings/ClockForms/Cron.vue",
    "content": "<script>\nimport CronClock from '@/components/Functional/CronClock'\nimport ExternalLink from '@/components/ExternalLink'\n\n/* eslint-disable no-unused-vars */\nimport {\n  CRON_MINUTE_REGEX as minute,\n  CRON_HOUR_REGEX as hour,\n  CRON_DAY_MONTH_REGEX as dayMonth,\n  CRON_MONTH_REGEX as month,\n  CRON_DAY_WEEK_REGEX as dayWeek\n} from '@/utils/regEx'\n\nconst inputs = ['minute', 'hour', 'dayMonth', 'month', 'dayWeek']\n\nexport default {\n  components: {\n    CronClock,\n    ExternalLink\n  },\n  props: {\n    value: {\n      type: String,\n      required: true\n    }\n  },\n  data() {\n    return {\n      lastPosition: null,\n\n      // Inputs (in order)\n      minute: '*',\n      hour: '*',\n      dayMonth: '*',\n      month: '*',\n      dayWeek: '*'\n    }\n  },\n  computed: {\n    inputsTotal() {\n      return `${this.minute} ${this.hour} ${this.dayMonth} ${this.month} ${this.dayWeek}`\n    },\n    valid() {\n      return (\n        this.minuteValid &&\n        this.hourValid &&\n        this.dayMonthValid &&\n        this.monthValid &&\n        this.dayWeekValid\n      )\n    },\n\n    // Input validity (in order)\n    minuteValid() {\n      return minute.test(this.minute)\n    },\n    hourValid() {\n      return hour.test(this.hour)\n    },\n    dayMonthValid() {\n      return dayMonth.test(this.dayMonth)\n    },\n    monthValid() {\n      return month.test(this.month)\n    },\n    dayWeekValid() {\n      return dayWeek.test(this.dayWeek)\n    }\n  },\n  watch: {\n    inputsTotal(val) {\n      this.$emit('input', val)\n    },\n    valid(val) {\n      this.$emit('update:valid', val)\n    },\n    value(val) {\n      const split = val?.split(' ')\n      if (split?.length > 1) {\n        this.minute = split[0]\n        this.hour = split[1]\n        this.dayMonth = split[2]\n        this.month = split[3]\n        this.dayWeek = split[4]\n      }\n    }\n  },\n  mounted() {\n    const split = this.value?.split(' ')\n    if (split?.length > 1) {\n      this.minute = split[0]\n      this.hour = split[1]\n      this.dayMonth = split[2]\n      this.month = split[3]\n      this.dayWeek = split[4]\n    }\n  },\n  beforeDestroy() {\n    this.$emit('update:valid', true)\n  },\n  methods: {\n    _handleClick(e) {\n      this.lastPosition = e.target.selectionStart\n    },\n    _handleKeypress(e) {\n      const regex = /[0-9]|[a-zA-Z]|[-]|[/]|[,]|[*]|[#]/i\n      !regex.test(e.key) && e.preventDefault()\n    },\n    _handleKeyup(e, source) {\n      const next = inputs.findIndex(c => c == source) + 1\n      const prev = inputs.findIndex(c => c == source) - 1\n      const position = e.target.selectionStart\n\n      if (\n        this.lastPosition !== 0 &&\n        this.lastPosition !== e.target.value.length\n      ) {\n        this.lastPosition = position\n        return\n      }\n\n      this.lastPosition = position\n\n      switch (e.code) {\n        case 'ArrowRight':\n        case 'Space':\n          if (next > 4 || position < e.target.value.length) break\n          if (this.lastPosition !== e.target.value.length) break\n          this.$refs[inputs[next]].focus()\n          this.lastPosition = 0\n          break\n        case 'ArrowLeft':\n          if (prev < 0 || position > 0) break\n          if (this.lastPosition !== 0) break\n          this.$refs[inputs[prev]].focus()\n          this.lastPosition = this.$refs[inputs[prev]]?.value?.length || 0\n          break\n        default:\n          break\n      }\n    },\n    _handlePaste(e) {\n      const paste = e.clipboardData.getData('text')?.split(' ')\n      if (paste?.length > 1) {\n        this.minute = paste[0]\n        this.hour = paste[1]\n        this.dayMonth = paste[2]\n        this.month = paste[3]\n        this.dayWeek = paste[4]\n        e.preventDefault()\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div class=\"text-body-1\"\n      >Manually set your schedule's cron string. For more information, read\n      about\n      <ExternalLink href=\"https://en.wikipedia.org/wiki/Cron#CRON_expression\">\n        cron expressions\n      </ExternalLink>\n      or about\n      <ExternalLink\n        href=\"https://docs.prefect.io/core/concepts/schedules.html#cron-clocks\"\n      >\n        cron clocks in Prefect </ExternalLink\n      >.\n    </div>\n\n    <div class=\"text-h4 text-center mt-8 px-8\">\n      <div class=\"text-subtitle-2\">Run this flow...</div>\n      <CronClock v-if=\"valid\" class=\"text-lowercase\" :cron=\"inputsTotal\" />\n      <span v-else class=\"primary--text\">Invalid input</span>\n    </div>\n\n    <div class=\"megazord-input mt-8\">\n      <div class=\"zord text-h5\">\n        <input\n          ref=\"minute\"\n          v-model=\"minute\"\n          type=\"text\"\n          placeholder=\"*\"\n          name=\"minute\"\n          @paste=\"_handlePaste\"\n          @click=\"_handleClick\"\n          @keypress=\"_handleKeypress\"\n          @keydown.space.prevent\n          @keyup=\"_handleKeyup($event, 'minute')\"\n        />\n        <label\n          class=\"text-subtitle-1\"\n          :class=\"{ invalid: !minuteValid }\"\n          for=\"minute\"\n        >\n          Minute\n        </label>\n      </div>\n\n      <div class=\"zord text-h5\">\n        <input\n          ref=\"hour\"\n          v-model=\"hour\"\n          type=\"text\"\n          placeholder=\"*\"\n          name=\"hour\"\n          @paste=\"_handlePaste\"\n          @click=\"_handleClick\"\n          @keypress=\"_handleKeypress\"\n          @keydown.space.prevent\n          @keyup=\"_handleKeyup($event, 'hour')\"\n        />\n        <label\n          class=\"text-subtitle-1\"\n          :class=\"{ invalid: !hourValid }\"\n          for=\"hour\"\n        >\n          Hour\n        </label>\n      </div>\n\n      <div class=\"zord text-h5\">\n        <input\n          ref=\"dayMonth\"\n          v-model=\"dayMonth\"\n          type=\"text\"\n          placeholder=\"*\"\n          name=\"dayMonth\"\n          @paste=\"_handlePaste\"\n          @click=\"_handleClick\"\n          @keypress=\"_handleKeypress\"\n          @keydown.space.prevent\n          @keyup=\"_handleKeyup($event, 'dayMonth')\"\n        />\n        <label\n          class=\"text-subtitle-1\"\n          :class=\"{ invalid: !dayMonthValid }\"\n          for=\"dayMonth\"\n        >\n          Day (month)\n        </label>\n      </div>\n\n      <div class=\"zord text-h5\">\n        <input\n          ref=\"month\"\n          v-model=\"month\"\n          type=\"text\"\n          placeholder=\"*\"\n          name=\"month\"\n          @paste=\"_handlePaste\"\n          @click=\"_handleClick\"\n          @keypress=\"_handleKeypress\"\n          @keydown.space.prevent\n          @keyup=\"_handleKeyup($event, 'month')\"\n        />\n        <label\n          class=\"text-subtitle-1\"\n          :class=\"{ invalid: !monthValid }\"\n          for=\"month\"\n        >\n          Month\n        </label>\n      </div>\n\n      <div class=\"zord text-h5\">\n        <input\n          ref=\"dayWeek\"\n          v-model=\"dayWeek\"\n          type=\"text\"\n          placeholder=\"*\"\n          name=\"dayWeek\"\n          @paste=\"_handlePaste\"\n          @click=\"_handleClick\"\n          @keypress=\"_handleKeypress\"\n          @keydown.space.prevent\n          @keyup=\"_handleKeyup($event, 'dayWeek')\"\n        />\n        <label\n          class=\"text-subtitle-1\"\n          :class=\"{ invalid: !dayWeekValid }\"\n          for=\"dayWeek\"\n        >\n          Day (week)\n        </label>\n      </div>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.megazord-input {\n  align-content: center;\n  display: flex;\n  justify-content: space-around;\n  margin-bottom: 50px;\n  max-width: 100%;\n  position: relative;\n\n  &::before {\n    background-color: var(--v-utilGrayLight-base);\n    bottom: -4px;\n    content: '';\n    display: block;\n    height: 1px;\n    position: absolute;\n    transition: all 150ms;\n    width: 100%;\n  }\n\n  &:hover,\n  &:focus {\n    &::before {\n      background-color: var(--v-utilGrayDark-base);\n    }\n  }\n\n  &::after {\n    background-color: var(--v-primary-base);\n    bottom: -4px;\n    content: '';\n    display: block;\n    height: 2px;\n    position: absolute;\n    transition: width 150ms;\n    width: 0;\n  }\n\n  .zord {\n    padding: 0;\n    position: relative;\n\n    input {\n      text-align: center;\n      width: 100%;\n\n      // stylelint-disable a11y/no-outline-none\n      &:focus {\n        outline: none;\n      }\n      // stylelint-enable a11y/no-outline-none\n    }\n\n    label {\n      left: 50%;\n      margin: auto;\n      position: absolute;\n      text-align: center;\n      top: 35px;\n      transform: translate(-50%);\n    }\n\n    &:focus-within {\n      label {\n        color: var(--v-primary-base);\n      }\n    }\n\n    .invalid {\n      animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;\n      color: var(--v-error-base) !important;\n      transform: translate(-50%) translate3d(0, 0, 0);\n    }\n\n    @keyframes shake {\n      10%,\n      90% {\n        transform: translate(-50%) translate3d(-1px, 0, 0);\n      }\n\n      20%,\n      80% {\n        transform: translate(-50%) translate3d(2px, 0, 0);\n      }\n\n      30%,\n      50%,\n      70% {\n        transform: translate(-50%) translate3d(-4px, 0, 0);\n      }\n\n      40%,\n      60% {\n        transform: translate(-50%) translate3d(4px, 0, 0);\n      }\n    }\n  }\n\n  &:focus-within {\n    &::after {\n      width: 100%;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Settings/ClockForms/Interval.vue",
    "content": "<script>\nimport IntervalClock from '@/components/Functional/IntervalClock'\nimport ExternalLink from '@/components/ExternalLink'\nimport debounce from 'lodash/debounce'\n\nexport default {\n  components: {\n    ExternalLink,\n    IntervalClock\n  },\n  props: {\n    value: {\n      type: [Number, String],\n      required: true\n    }\n  },\n  data() {\n    return {\n      infoMessage: null,\n      interval: this.value / 1000000\n    }\n  },\n  computed: {\n    _handleInput: function() {\n      return debounce(this._rawHandleInput, 500)\n    }\n  },\n  watch: {\n    interval(val) {\n      this.$emit('input', val * 1000000)\n    }\n  },\n  methods: {\n    _rawHandleInput() {\n      if (this.interval < 60) {\n        this.infoMessage = 'Schedule intervals cannot be lower than 60 seconds.'\n      } else if (this.interval > 2147483647) {\n        this.infoMessage =\n          'Schedule intervals cannot be higher than 2,147,483,647 seconds.'\n      } else {\n        this.infoMessage = null\n      }\n    },\n    decrement() {\n      this.interval > 60 && this.interval--\n    },\n    increment() {\n      // 32 bit limitation\n      this.interval < 2147483647 && this.interval++\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div class=\"text-body-1\"\n      >Manually set your schedule's interval. For more information, read about\n      interval clocks in\n      <ExternalLink\n        href=\"https://docs.prefect.io/core/concepts/schedules.html#interval-clocks\"\n      >\n        the Prefect docs</ExternalLink\n      >.\n    </div>\n\n    <div class=\"text-h4 text-center mt-8 px-8\">\n      <div class=\"text-subtitle-2\">Run this flow...</div>\n      <IntervalClock class=\"text-lowercase\" :interval=\"value\" />\n    </div>\n\n    <v-slide-y-transition mode=\"out-in\">\n      <v-alert\n        v-if=\"infoMessage\"\n        class=\"mx-auto my-4 text-body-2\"\n        border=\"left\"\n        colored-border\n        elevation=\"2\"\n        type=\"warning\"\n        tile\n        icon=\"announcement\"\n        max-width=\"500\"\n      >\n        <p>\n          {{ infoMessage }}\n        </p>\n\n        <p class=\"mt-4 mb-0\">\n          You can read more about schedules in\n          <ExternalLink\n            href=\"https://docs.prefect.io/core/concepts/schedules.html#clocks\"\n          >\n            the Prefect docs</ExternalLink\n          >.\n        </p>\n      </v-alert>\n    </v-slide-y-transition>\n\n    <div class=\"d-flex align-center justify-center mt-8\">\n      <v-icon :disabled=\"interval <= 60\" @click=\"decrement\">\n        remove_circle\n      </v-icon>\n\n      <v-text-field\n        v-model.number=\"interval\"\n        class=\"text-h5 center hidden-spin\"\n        label=\"Seconds\"\n        style=\"max-width: 200px;\"\n        type=\"number\"\n        min=\"60\"\n        max=\"2147483647\"\n        @keyup=\"_handleInput\"\n      />\n      <v-icon :disabled=\"interval >= 2147483647\" @click=\"increment\">\n        add_circle\n      </v-icon>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\">\n// stylelint-disable\n.hidden-spin {\n  input::-webkit-outer-spin-button,\n  input::-webkit-inner-spin-button {\n    -webkit-appearance: none;\n    margin: 0;\n  }\n\n  input[type='number'] {\n    -moz-appearance: textfield;\n  }\n}\n// stylelint-enable\n\n// stylelint-disable\n.center.v-input {\n  input {\n    text-align: center !important;\n  }\n\n  label {\n    left: 50% !important;\n    right: unset !important;\n    top: 0 !important;\n    transform: translate(-50%, -18px) scale(0.75) !important;\n    transform-origin: center !important;\n  }\n}\n// stylelint-enable\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Settings/ClockForms/Simple.vue",
    "content": "<script>\nimport CronClock from '@/components/Functional/CronClock'\nimport IntervalClock from '@/components/Functional/IntervalClock'\nimport { daysWeek, oxfordList } from '@/utils/cron'\nimport { ordinal } from '@/utils/ordinal'\n\nexport default {\n  components: {\n    CronClock,\n    IntervalClock\n  },\n  props: {\n    value: {\n      type: [String, Number],\n      required: true\n    }\n  },\n  data() {\n    return {\n      interval: 'hour',\n      intervalValue: 1,\n      minutes: Array.from({ length: 60 }, (d, i) => i),\n      hours: Array.from({ length: 24 }, (d, i) => i),\n      daysWeek: Array.from({ length: 7 }, (d, i) => {\n        return { label: daysWeek[i][0], value: i }\n      }),\n      daysMonth: Array.from({ length: 31 }, (d, i) => i + 1),\n      minuteValue: 0,\n      hourValue: 0,\n      dayWeekValue: [1],\n      dayMonthValue: [1]\n    }\n  },\n  computed: {\n    clock() {\n      let cron = ''\n      switch (this.interval) {\n        case 'minute':\n          cron = this.intervalValue * 60000000\n          break\n        case 'hour':\n          cron = `${this.minuteValue} */${this.intervalValue} * * *`\n          break\n        case 'day':\n          cron = `0 ${this.hourValue} */${this.intervalValue} * *`\n          break\n        case 'week':\n          cron = `0 0 * * ${this.dayWeekValue.join(',')}`\n          break\n        case 'month':\n          cron = `0 0 ${this.dayMonthValue.join(',')} 1/${this.intervalValue} *`\n          break\n        default:\n          cron = '* * * * *'\n          break\n      }\n      return cron\n    },\n    intervalOptions() {\n      return [\n        {\n          label: `minute${this.intervalValue > 1 ? 's' : ''}`,\n          value: 'minute',\n          min: 1,\n          max: 720\n        },\n        {\n          label: `hour${this.intervalValue > 1 ? 's' : ''}`,\n          value: 'hour',\n          min: 1,\n          max: 168\n        },\n        {\n          label: `day${this.intervalValue > 1 ? 's' : ''}`,\n          value: 'day',\n          min: 1,\n          max: 45\n        },\n        {\n          label: `week${this.intervalValue > 1 ? 's' : ''}`,\n          value: 'week',\n          min: 1,\n          max: 12\n        },\n        {\n          label: `month${this.intervalValue > 1 ? 's' : ''}`,\n          value: 'month',\n          min: 1,\n          max: 18\n        }\n      ]\n    },\n    intervalMin() {\n      return this.intervalOptions.find(i => i.value == this.interval).min\n    },\n    intervalMax() {\n      return this.intervalOptions.find(i => i.value == this.interval).max\n    }\n  },\n  watch: {\n    clock(val) {\n      this.$emit('input', val)\n    }\n  },\n  mounted() {\n    if (!this.value) return\n    if (typeof this.value == 'number') {\n      this.interval = 'minute'\n      this.intervalValue = this.value / 60000000\n      return\n    }\n    const [minute, hour, day, month, dayWeek] = this.value\n      .replace(/\\*\\//g, '')\n      .split(' ')\n\n    if (hour.includes('*/')) {\n      this.minuteValue = parseInt(minute)\n      this.interval = 'hour'\n      this.intervalValue = parseInt(hour)\n    }\n\n    if (day.includes('*/')) {\n      this.interval = 'day'\n      this.hourValue = parseInt(hour)\n      this.intervalValue = parseInt(day)\n    }\n\n    if (dayWeek !== '*') {\n      this.interval = 'week'\n      this.dayWeekValue = dayWeek.split(',').map(v => parseInt(v))\n      this.intervalValue = 1\n    }\n\n    if (month.includes('1/')) {\n      this.interval = 'month'\n      this.dayMonthValue = day.split(',').map(v => parseInt(v))\n      this.intervalValue = parseInt(month.split('1/')[1])\n    }\n  },\n  methods: {\n    ordinal(val) {\n      return ordinal(val)\n    },\n    oxfordReducer(list) {\n      return [...list]\n        .sort((a, b) => a - b)\n        .reduce((acc, val, i, arr) => {\n          return `${acc} ${val}${ordinal(val)}${oxfordList(arr, i)}`\n        }, '')\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div class=\"text-body-1\">\n      Set a schedule for your flow; schedules set in the UI will override any in\n      your Flow's code.\n    </div>\n\n    <div class=\"text-h4 text-center mt-8 px-8\">\n      <div class=\"text-subtitle-2\">Run this flow...</div>\n      <CronClock\n        v-if=\"interval !== 'minute'\"\n        class=\"text-lowercase\"\n        :cron=\"clock\"\n      />\n      <IntervalClock v-else class=\"text-lowercase\" :interval=\"clock\" />\n    </div>\n\n    <div class=\"d-flex align-end justify-start text-h5 my-8\">\n      <div>Run every</div>\n\n      <v-text-field\n        v-if=\"interval !== 'week'\"\n        v-model.number=\"intervalValue\"\n        type=\"number\"\n        class=\"text-h5 ml-2\"\n        outlined\n        dense\n        hide-details\n        :style=\"{ 'max-width': intervalValue > 9 ? '75px' : '60px' }\"\n        :min=\"intervalMin\"\n        :max=\"intervalMax\"\n      />\n\n      <v-select\n        data-public\n        v-model=\"interval\"\n        :items=\"intervalOptions\"\n        class=\"text-h5 ml-2\"\n        outlined\n        dense\n        hide-details\n        style=\"max-width: 150px;\"\n        item-text=\"label\"\n        item-value=\"value\"\n      />\n    </div>\n\n    <div\n      v-if=\"interval == 'hour'\"\n      class=\"d-flex align-end justify-start text-h5 my-8\"\n    >\n      <div>...on the</div>\n      <v-select\n        data-public\n        v-model=\"minuteValue\"\n        :items=\"minutes\"\n        class=\"text-h5 ml-2 mr-1\"\n        outlined\n        dense\n        hide-details\n        style=\"max-width: 85px;\"\n      />\n      <div>{{ ordinal(minuteValue) }} minute of the hour.</div>\n    </div>\n\n    <div\n      v-if=\"interval == 'day'\"\n      class=\"d-flex align-end justify-start text-h5 my-8\"\n    >\n      <div>...at the</div>\n      <v-select\n        data-public\n        v-model=\"hourValue\"\n        :items=\"hours\"\n        class=\"text-h5 ml-2 mr-1\"\n        outlined\n        dense\n        hide-details\n        style=\"max-width: 85px;\"\n      />\n      <div>{{ ordinal(hourValue) }} hour.</div>\n    </div>\n\n    <div v-if=\"interval == 'week'\" class=\"text-h5 my-8\">\n      <div>Repeat on...</div>\n      <v-chip-group\n        v-model=\"dayWeekValue\"\n        active-class=\"primary darken-1\"\n        class=\"my-4\"\n        multiple\n        mandatory\n      >\n        <v-chip\n          v-for=\"day in daysWeek\"\n          :key=\"day.value\"\n          color=\"grey lighten-3\"\n          class=\"rounded-circle align-center justify-center\"\n          style=\"height: 50px;\n          width: 50px;\"\n        >\n          {{ day.label }}\n        </v-chip>\n      </v-chip-group>\n    </div>\n\n    <div v-if=\"interval == 'month'\" class=\"text-h5 my-8\">\n      <div>On the...</div>\n\n      <v-chip-group\n        v-model=\"dayMonthValue\"\n        active-class=\"primary darken-1\"\n        class=\"my-4\"\n        multiple\n        mandatory\n        column\n      >\n        <v-chip\n          v-for=\"day in daysMonth\"\n          :key=\"day\"\n          :value=\"day\"\n          color=\"grey lighten-3\"\n          class=\"rounded-circle align-center justify-center\"\n          style=\"height: 50px;\n          width: 50px;\"\n        >\n          {{ day }}\n        </v-chip>\n      </v-chip-group>\n\n      <div\n        >...{{ oxfordReducer(dayMonthValue) }}\n        {{ dayMonthValue.length === 1 ? 'day' : 'days' }}\n        of the month.\n      </div>\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/Flow/Settings/CloudHooks.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport CloudHookForm from '@/components/CloudHookForm'\nimport { cloudHookMixin } from '@/mixins/cloudHookMixin'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: { CardTitle, CloudHookForm },\n  mixins: [cloudHookMixin],\n  props: {\n    flow: {\n      required: true,\n      type: Object\n    },\n    flowGroup: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      createNewCloudHook: false,\n      error: {\n        createCloudHook: null\n      },\n      loading: {\n        createCloudHook: false\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('license', ['permissions']),\n    ...mapGetters('license', ['hasPermission']),\n    containerClass() {\n      return !this.cloudHooks ? ['py-12', 'text-center'] : []\n    }\n  },\n  methods: {\n    stateGroup(states) {\n      if (this.stateGroupAll(states)) return 'All'\n      if (this.stateGroupFailed(states)) return 'Failed'\n      if (this.stateGroupFinished(states)) return 'Finished'\n      if (this.stateGroupSuccess(states)) return 'Success'\n      return 'Custom'\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.cloudHooks.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    cloudHooks: {\n      query: require('@/graphql/Flow/cloud-hooks.gql'),\n      variables() {\n        return {\n          id: this.flow.version_group_id\n        }\n      },\n      pollInterval: 10000,\n      update: data => {\n        if (!data?.cloud_hook?.length) return\n        return data.cloud_hook.sort((a, b) => {\n          return a.name > b.name ? 1 : a.name < b.name ? -1 : 0\n        })\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2 mt-2\" outlined>\n    <CardTitle title=\"Cloud Hooks\" icon=\"cloud\" />\n\n    <v-card-text class=\"pl-12\">\n      <div class=\"text-body-1\" style=\"max-width: 1000px;\">\n        Cloud Hooks allow you to send notifications to Slack, email, or any\n        other endpoint when your flow enters a given state. For example, send a\n        Slack message to your team when a production-critical flow has failed,\n        along with the reason for the failure, so you can respond immediately.\n        Note that some Cloud Hooks such as email are only available with Prefect\n        Cloud.\n      </div>\n\n      <v-row>\n        <v-col cols=\"12\" class=\"pt-0\">\n          <v-row>\n            <v-col cols=\"12\">\n              <v-dialog v-model=\"createNewCloudHook\" max-width=\"700\">\n                <template #activator=\"{ onD }\">\n                  <v-tooltip top>\n                    <template #activator=\"{ on }\">\n                      <div\n                        class=\"pb-1 text-center\"\n                        :class=\"containerClass\"\n                        :style=\"{\n                          display: !cloudHooks ? 'block' : 'inline-block'\n                        }\"\n                        v-on=\"on\"\n                      >\n                        <v-btn\n                          color=\"primary\"\n                          :small=\"!!cloudHooks\"\n                          :large=\"!cloudHooks\"\n                          :disabled=\"!hasPermission('create', 'cloud-hook')\"\n                          @click=\"createNewCloudHook = true\"\n                          v-on=\"onD\"\n                        >\n                          <v-icon left>cloud</v-icon> New Cloud Hook\n                        </v-btn>\n                        <div v-if=\"!cloudHooks\" class=\"mt-8 text-body-1\">\n                          <span class=\"font-weight-bold\">{{ flow.name }}</span>\n                          has no Cloud Hooks! Create one using the button above.\n                        </div>\n                      </div>\n                    </template>\n                    <span v-if=\"!hasPermission('create', 'cloud-hook')\">\n                      You don't have permission to create new Cloud Hooks.\n                    </span>\n                    <span v-else>\n                      Create a new Cloud Hook for this Flow\n                    </span>\n                  </v-tooltip>\n                </template>\n\n                <v-card tile class=\"pa-2\">\n                  <CardTitle title=\"New Cloud Hook\" icon=\"cloud\" />\n\n                  <v-card-text class=\"pl-12\">\n                    <CloudHookForm\n                      v-if=\"createNewCloudHook\"\n                      :editable=\"\n                        hasPermission('create', 'cloud-hook') &&\n                          hasPermission('delete', 'cloud-hook')\n                      \"\n                      edit-on-render\n                      :version-group-id-prop=\"flow.version_group_id\"\n                      @close=\"createNewCloudHook = false\"\n                      @update=\"$apollo.queries.cloudHooks.refetch()\"\n                    />\n                  </v-card-text>\n                </v-card>\n              </v-dialog>\n\n              <!-- Do we have any docs on this? -->\n              <!--             \n            Read more about it\n            <a\n              href=\"\"\n              target=\"_blank\"\n            >\n              here </a\n            >. -->\n            </v-col>\n          </v-row>\n\n          <div class=\"mt-4\">\n            <v-row no-gutters>\n              <v-col cols=\"12\">\n                <v-expansion-panels focusable tile hover flat>\n                  <v-expansion-panel\n                    v-for=\"item in cloudHooks\"\n                    :key=\"item.id\"\n                    :style=\"{\n                      'border-left': `2px solid var(--v-${stateGroupColor(\n                        stateGroup(item.states)\n                      )}-base) !important`\n                    }\"\n                  >\n                    <v-lazy\n                      :options=\"{\n                        threshold: 0.75\n                      }\"\n                      min-height=\"40px\"\n                      transition=\"fade\"\n                    >\n                      <div>\n                        <v-expansion-panel-header>\n                          <v-progress-linear\n                            :active=\"item.loading\"\n                            :indeterminate=\"item.loading\"\n                            :color=\"stateGroupColor(stateGroup(item.states))\"\n                            background-opacity=\"0\"\n                            absolute\n                            bottom\n                          />\n\n                          <v-list-item class=\"pl-0\">\n                            <v-list-item-content>\n                              <v-list-item-title>\n                                <v-row no-gutters>\n                                  <v-col\n                                    cols=\"2\"\n                                    class=\"d-flex align-center justify-center\"\n                                  >\n                                    <v-icon left class=\"mr-6\">\n                                      {{ typeIcon(item.type) }}\n                                    </v-icon>\n                                  </v-col>\n                                  <v-col\n                                    class=\"d-flex align-center justify-space-between\"\n                                  >\n                                    <div class=\"justify-self-start\">\n                                      <div\n                                        class=\"text-subtitle-1 font-weight-medium\"\n                                      >\n                                        {{ item.name }}\n                                      </div>\n                                      <div class=\"text-body-2\">\n                                        {{ typeTitle(item.type) }}\n                                      </div>\n                                    </div>\n                                    <div class=\"justify-self-end\">\n                                      <v-tooltip bottom>\n                                        <template #activator=\"{ on }\">\n                                          <div v-on=\"on\" @click.stop>\n                                            <div class=\"vertical-button\">\n                                              <v-switch\n                                                v-model=\"item.active\"\n                                                hide-details\n                                                class=\"v-input--vertical\"\n                                                color=\"primary\"\n                                                :loading=\"item.loading\"\n                                                :disabled=\"\n                                                  (!hasPermission(\n                                                    'create',\n                                                    'cloud-hook'\n                                                  ) &&\n                                                    !hasPermission(\n                                                      'delete',\n                                                      'cloud-hook'\n                                                    )) ||\n                                                    item.loading\n                                                \"\n                                                @change=\"\n                                                  _handleSetCloudHookStatusChange(\n                                                    $event,\n                                                    item\n                                                  )\n                                                \"\n                                              >\n                                                <template #label>\n                                                  <v-btn\n                                                    tile\n                                                    small\n                                                    text\n                                                    disabled\n                                                    class=\"mb-1\"\n                                                  >\n                                                    {{\n                                                      item.active ? 'On' : 'Off'\n                                                    }}\n                                                  </v-btn>\n                                                </template>\n                                              </v-switch>\n                                            </div>\n                                          </div>\n                                        </template>\n                                        <span\n                                          v-if=\"\n                                            !hasPermission(\n                                              'update',\n                                              'cloud-hook'\n                                            )\n                                          \"\n                                        >\n                                          You don't have permission to change\n                                          Cloud Hook states.\n                                        </span>\n                                        <span v-else>\n                                          {{\n                                            item.active\n                                              ? 'Deactivate'\n                                              : 'Activate'\n                                          }}\n                                          this Cloud Hook\n                                        </span>\n                                      </v-tooltip>\n                                    </div>\n                                  </v-col>\n                                  <v-col\n                                    v-if=\"$vuetify.breakpoint.smAndUp\"\n                                    cols=\"4\"\n                                    class=\"d-flex align-center justify-end\"\n                                  >\n                                    <div class=\"text-body-2\">\n                                      <span v-if=\"$vuetify.breakpoint.mdAndUp\">\n                                        States:\n                                      </span>\n                                      <v-chip\n                                        label\n                                        dark\n                                        :color=\"\n                                          stateGroupColor(\n                                            stateGroup(item.states)\n                                          )\n                                        \"\n                                        class=\"ml-2\"\n                                      >\n                                        {{ stateGroup(item.states) }}\n                                      </v-chip>\n                                    </div>\n                                  </v-col>\n                                </v-row>\n                              </v-list-item-title>\n                            </v-list-item-content>\n                          </v-list-item>\n                        </v-expansion-panel-header>\n\n                        <v-expansion-panel-content>\n                          <CloudHookForm\n                            :hook=\"item\"\n                            :editable=\"\n                              hasPermission('create', 'cloud-hook') &&\n                                hasPermission('delete', 'cloud-hook')\n                            \"\n                            show-controls\n                            :version-group-id-prop=\"flow.version_group_id\"\n                            :loading.sync=\"item.loading\"\n                            @update=\"$apollo.queries.cloudHooks.refetch()\"\n                          />\n                        </v-expansion-panel-content>\n                      </div>\n                    </v-lazy>\n                  </v-expansion-panel>\n                </v-expansion-panels>\n              </v-col>\n              <v-col cols=\"0\" md=\"2\"></v-col>\n            </v-row>\n          </div>\n        </v-col>\n      </v-row>\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "src/pages/Flow/Settings/DefaultParameters.vue",
    "content": "<script>\nimport { parametersMixin } from '@/mixins/parametersMixin.js'\nimport CardTitle from '@/components/Card-Title'\nimport CodeInput from '@/components/CustomInputs/CodeInput'\nimport { formatJson } from '@/utils/json'\n\nexport default {\n  components: { CardTitle, CodeInput },\n  mixins: [parametersMixin],\n  computed: {\n    originalParameters() {\n      return formatJson(this.selectedFlowParameters)\n    },\n    parametersAreSetToDefault() {\n      return this.originalParameters == this.parameterInput\n    }\n  },\n  created() {\n    this.setParameterInput()\n  },\n  methods: {\n    async reset() {\n      this.parameterInput = this.originalParameters\n    },\n    async save() {\n      await this.setDefaultParams()\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"default-parameters\" :loading=\"loading\" outlined>\n    <CardTitle title=\"Default Parameters\" icon=\"perm_data_setting\" />\n\n    <v-card-text class=\"default-parameters__container\">\n      <div class=\"default-parameters__description\">\n        You can override the default parameter values on your Flow at the Flow\n        Group level. If provided, they take precedence over any default\n        parameters set at flow registration, and apply to all versions of your\n        Flow. Here you can set new flow group default parameters or reset them\n        to the parameters you set at registration.\n      </div>\n      <div class=\"default-parameters__input\">\n        <code-input\n          v-model=\"parameterInput\"\n          show-types\n          readonly-key\n          disable-add\n          disable-remove\n        />\n      </div>\n      <div v-if=\"permissionsCheck\" class=\"default-parameters__actions\">\n        You don't have permission to create or edit parameters.\n      </div>\n      <div class=\"default-parameters__actions\">\n        <v-btn\n          :disabled=\"permissionsCheck || parametersAreSetToDefault\"\n          text\n          @click=\"reset\"\n        >\n          Reset\n        </v-btn>\n        <v-btn\n          :disabled=\"permissionsCheck\"\n          color=\"primary\"\n          :loading=\"loading\"\n          @click=\"save\"\n        >\n          Set Params\n        </v-btn>\n      </div>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style scoped>\n.default-parameters {\n  margin-top: 16px;\n}\n.default-parameters__container {\n  padding-left: 48px;\n}\n\n.default-parameters__description {\n  max-width: 1000px;\n  font-size: 1rem;\n  line-height: 1.5rem;\n}\n\n.default-parameters__actions {\n  display: flex;\n  gap: 4px;\n  justify-content: end;\n  margin-bottom: 4px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Settings/General.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport CardTitle from '@/components/Card-Title'\nimport LogRocket from 'logrocket'\n\nexport default {\n  components: { CardTitle },\n  props: {\n    flow: {\n      required: true,\n      type: Object\n    },\n    flowGroup: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      error: {\n        heartbeat: null,\n        lazarus: null,\n        project: null,\n        versionLocking: null\n      },\n      loading: {\n        heartbeat: false,\n        lazarus: false,\n        project: false,\n        versionLocking: false\n      },\n      selected: {\n        projectId: this.flow.project.id,\n        versionLockingEnabled: this.flowGroup.settings.version_locking_enabled,\n        heartbeatEnabled: this.flowGroup.settings.heartbeat_enabled,\n        lazarusEnabled: this.flowGroup.settings.lazarus_enabled\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('license', ['permissions', 'hasPermission']),\n    sortedProjects() {\n      if (!this.projects) return []\n      return [...this.projects].sort((a, b) =>\n        a.name.localeCompare(b.name, undefined, { ignorePunctuation: true })\n      )\n    },\n    isVersionLocked() {\n      return this.flowGroup.settings.version_locking_enabled\n    },\n    isHeartbeatEnabled() {\n      return this.flowGroup.settings.heartbeat_enabled\n    },\n    isLazarusEnabled() {\n      return this.flowGroup.settings.lazarus_enabled\n    },\n    permissionsCheck() {\n      return !this.hasPermission('update', 'flow')\n    },\n    projectHasChanged() {\n      return this.selected.projectId !== this.flow.project.id\n    },\n    versionLockingPermitted() {\n      return this.permissions?.includes('feature:version-locking')\n    }\n  },\n  methods: {\n    async _handleHeartbeatChange() {\n      this.loading.heartbeat = true\n\n      try {\n        const updateHeartbeat = !this.selected.heartbeatEnabled\n          ? await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/disable-flow-heartbeat.gql'),\n              variables: {\n                input: {\n                  flow_id: this.flow.id\n                }\n              },\n              errorPolicy: 'all'\n            })\n          : await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/enable-flow-heartbeat.gql'),\n              variables: {\n                input: {\n                  flow_id: this.flow.id\n                }\n              },\n              errorPolicy: 'all'\n            })\n\n        setTimeout(() => {\n          let status = updateHeartbeat.data\n            ? updateHeartbeat.data.enable_flow_heartbeat ||\n              updateHeartbeat.data.disable_flow_heartbeat\n            : false\n\n          if (!status || !status.success) {\n            this.error.heartbeat = status.errors[0].message\n            this.loading.heartbeat = false\n          } else {\n            let heartbeatCheckInterval\n            heartbeatCheckInterval = setInterval(() => {\n              if (this.isHeartbeatEnabled == this.selected.heartbeatEnabled) {\n                clearInterval(heartbeatCheckInterval)\n                this.loading.heartbeat = false\n              }\n            }, 500)\n          }\n        }, 500)\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Settings',\n            stage: 'Heartbeat Update'\n          }\n        })\n        this.loading.heartbeat = false\n        this.error.heartbeat = e\n      }\n    },\n    async _handleLazarusChange() {\n      this.loading.lazarus = true\n\n      try {\n        const updateLazarus = !this.selected.lazarusEnabled\n          ? await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/disable-flow-lazarus-process.gql'),\n              variables: {\n                input: {\n                  flow_id: this.flow.id\n                }\n              },\n              errorPolicy: 'all'\n            })\n          : await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/enable-flow-lazarus-process.gql'),\n              variables: {\n                input: {\n                  flow_id: this.flow.id\n                }\n              },\n              errorPolicy: 'all'\n            })\n        setTimeout(() => {\n          let status = updateLazarus.data\n            ? updateLazarus.data.enable_flow_lazarus_process ||\n              updateLazarus.data.disable_flow_lazarus_process\n            : false\n\n          if (!status || !status.success) {\n            this.error.lazarus = status.errors[0].message\n            this.loading.lazarus = false\n          } else {\n            let lazarusCheckInterval\n            lazarusCheckInterval = setInterval(() => {\n              if (this.isLazarusEnabled == this.selected.lazarusEnabled) {\n                clearInterval(lazarusCheckInterval)\n                this.loading.lazarus = false\n              }\n            }, 500)\n          }\n        }, 500)\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Settings',\n            stage: 'Lazarus Update'\n          }\n        })\n        this.loading.lazarus = false\n        this.error.lazarus = e\n      }\n    },\n    async _handleProjectChange() {\n      this.loading.project = true\n\n      try {\n        const changeProject = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/update-flow-project.gql'),\n          variables: {\n            input: {\n              project_id: this.selected.projectId,\n              flow_id: this.flow.id\n            }\n          },\n          errorPolicy: 'all'\n        })\n\n        setTimeout(() => {\n          if (!changeProject.data || !changeProject.data.update_flow_project) {\n            this.error.project = changeProject.errors[0].message\n            this.loading.project = false\n          } else {\n            let projectCheckInterval\n            projectCheckInterval = setInterval(() => {\n              if (this.flow.project.id == this.selected.projectId) {\n                clearInterval(projectCheckInterval)\n                this.loading.project = false\n              }\n            }, 500)\n          }\n        }, 500)\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Settings',\n            stage: 'Project Change'\n          }\n        })\n        this.loading.project = false\n        this.error.project = e\n      }\n    },\n    async _handleVersionLockingChange() {\n      this.loading.versionLocking = true\n\n      try {\n        const updateVersionLocking = !this.selected.versionLockingEnabled\n          ? await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/disable-flow-version-lock.gql'),\n              variables: {\n                input: {\n                  flow_id: this.flow.id\n                }\n              },\n              errorPolicy: 'all'\n            })\n          : await this.$apollo.mutate({\n              mutation: require('@/graphql/Mutations/enable-flow-version-lock.gql'),\n              variables: {\n                input: {\n                  flow_id: this.flow.id\n                }\n              },\n              errorPolicy: 'all'\n            })\n        setTimeout(() => {\n          let status = updateVersionLocking.data\n            ? updateVersionLocking.data.enable_flow_version_lock ||\n              updateVersionLocking.data.disable_flow_version_lock\n            : false\n\n          if (!status || !status.success) {\n            this.error.versionLocking = status.errors[0].message\n            this.loading.versionLocking = false\n          } else {\n            let versionLockingCheckInterval\n            versionLockingCheckInterval = setInterval(() => {\n              if (this.isVersionLocked == this.selected.versionLockingEnabled) {\n                clearInterval(versionLockingCheckInterval)\n                this.loading.versionLocking = false\n              }\n            }, 500)\n          }\n        }, 500)\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Settings',\n            stage: 'Heartbeat Update'\n          }\n        })\n\n        this.loading.versionLocking = false\n        this.error.versionLocking = e\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.projects.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    projects: {\n      query: require('@/graphql/Flow/project-names.gql'),\n      pollInterval: 10000,\n      update: data => data.project\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"pa-2 pb-6 mt-2\"\n    outlined\n  >\n    <CardTitle title=\"Flow Settings\" icon=\"settings\" />\n\n    <v-card-text class=\"pl-12\" style=\"max-width: 1000px;\">\n      <v-row>\n        <v-col cols=\"12\" class=\"pb-0\">\n          <div class=\"text-h6 primary--text\">\n            <!-- We don't really have the visual language necessary to use these I think -->\n            <!-- <v-icon class=\"mr-3\">pi-project</v-icon> -->\n            Project\n          </div>\n        </v-col>\n        <v-col cols=\"12\" class=\"pt-0\">\n          <v-row no-gutters>\n            <v-col cols=\"12\" md=\"6\" sm=\"8\">\n              <v-tooltip bottom>\n                <template #activator=\"{ on }\">\n                  <div v-on=\"on\">\n                    <v-select\n                      data-public\n                      v-model=\"selected.projectId\"\n                      :items=\"sortedProjects\"\n                      item-value=\"id\"\n                      item-text=\"name\"\n                      label=\"Select project\"\n                      hide-details\n                      single-line\n                      :menu-props=\"{ contentClass: 'custom-list-item' }\"\n                      prepend-inner-icon=\"pi-project mr-1\"\n                      :disabled=\"permissionsCheck || loading.project\"\n                    />\n                  </div>\n                </template>\n                <span v-if=\"permissionsCheck\">\n                  You don't have permission to move flows between projects.\n                </span>\n                <span v-else>\n                  Move this flow to a new project.\n                </span>\n              </v-tooltip>\n            </v-col>\n            <v-col cols=\"12\" md=\"4\" align-self=\"center\">\n              <v-tooltip bottom>\n                <template #activator=\"{ on }\">\n                  <div style=\"display: inline-block;\" v-on=\"on\">\n                    <v-btn\n                      :disabled=\"\n                        permissionsCheck ||\n                          !projectHasChanged ||\n                          loading.project\n                      \"\n                      :loading=\"loading.project\"\n                      small\n                      color=\"primary\"\n                      :class=\"$vuetify.breakpoint.mdAndUp ? 'ml-4' : 'mt-4'\"\n                      @click=\"_handleProjectChange\"\n                    >\n                      Save\n                    </v-btn>\n                  </div>\n                </template>\n                <span v-if=\"permissionsCheck\">\n                  You don't have permission to move flows between projects.\n                </span>\n                <span v-else>\n                  Move this flow to a new project.\n                </span>\n              </v-tooltip>\n            </v-col>\n          </v-row>\n\n          <div class=\"mt-4\">\n            Projects are a method of organizing your Flows. Read more about\n            projects\n            <a\n              href=\"https://docs.prefect.io/cloud/concepts/projects.html#creating-a-project\"\n              target=\"_blank\"\n            >\n              here\n            </a>\n            <sup>\n              <v-icon x-small color=\"primary\">\n                open_in_new\n              </v-icon>\n            </sup>\n            .\n          </div>\n        </v-col>\n      </v-row>\n      <v-row v-if=\"isCloud\" class=\"mt-8\">\n        <v-col cols=\"12\" class=\"pb-0\">\n          <div class=\"text-h6 primary--text\">\n            <!-- We don't really have the visual language necessary to use these I think -->\n            <!-- <v-icon class=\"mr-3\">lock</v-icon> -->\n            Version Locking\n          </div>\n        </v-col>\n        <v-col cols=\"12\" class=\"pt-0\">\n          <v-tooltip bottom>\n            <template #activator=\"{ on }\">\n              <div class=\"pb-1\" style=\"display: inline-block;\" v-on=\"on\">\n                <v-switch\n                  v-model=\"selected.versionLockingEnabled\"\n                  hide-details\n                  color=\"primary\"\n                  :loading=\"loading.versionLocking\"\n                  :disabled=\"\n                    permissionsCheck ||\n                      !hasPermission('feature', 'version-locking') ||\n                      loading.versionLocking\n                  \"\n                  @change=\"_handleVersionLockingChange\"\n                >\n                  <template #label>\n                    <label>\n                      Version Locking\n                      <span\n                        :class=\"\n                          isVersionLocked\n                            ? 'prefect--text'\n                            : 'grey--text text--darken-2'\n                        \"\n                        class=\"font-weight-medium\"\n                      >\n                        {{ isVersionLocked ? 'Enabled' : 'Disabled' }}\n                      </span>\n                    </label>\n                  </template>\n                </v-switch>\n              </div>\n            </template>\n            <span v-if=\"permissionsCheck\">\n              You don't have permission to modify flow settings.\n            </span>\n            <span v-if=\"!hasPermission('feature', 'version-locking')\">\n              Your team doesn't have access to version locking.\n            </span>\n            <span v-else>\n              {{ isVersionLocked ? 'Disable' : 'Enable' }} version locking for\n              this flow and its tasks.\n            </span>\n          </v-tooltip>\n\n          <div class=\"mt-4\">\n            Version locking ensures that this flow and its tasks run\n            <i>just once</i>. Read more about it\n            <a\n              href=\"https://docs.prefect.io/cloud/concepts/flows.html#flow-settings\"\n              target=\"_blank\"\n            >\n              here\n            </a>\n            <sup>\n              <v-icon x-small color=\"primary\">\n                open_in_new\n              </v-icon> </sup\n            >.\n          </div>\n        </v-col>\n      </v-row>\n\n      <v-row class=\"mt-8\">\n        <v-col cols=\"12\" class=\"pb-0\">\n          <div class=\"text-h6 primary--text\">\n            <!-- We don't really have the visual language necessary to use these I think -->\n            <!-- <v-icon class=\"mr-3\">favorite</v-icon> -->\n            Heartbeat\n          </div>\n        </v-col>\n        <v-col cols=\"12\" class=\"pt-0\">\n          <v-tooltip bottom>\n            <template #activator=\"{ on }\">\n              <div class=\"pb-1\" style=\"display: inline-block;\" v-on=\"on\">\n                <v-switch\n                  v-model=\"selected.heartbeatEnabled\"\n                  hide-details\n                  color=\"primary\"\n                  :loading=\"loading.heartbeat\"\n                  :disabled=\"permissionsCheck || loading.heartbeat\"\n                  @change=\"_handleHeartbeatChange\"\n                >\n                  <template #label>\n                    <label>\n                      Heartbeat\n                      <span\n                        :class=\"\n                          isHeartbeatEnabled\n                            ? 'prefect--text'\n                            : 'grey--text text--darken-2'\n                        \"\n                        class=\"font-weight-medium\"\n                      >\n                        {{ isHeartbeatEnabled ? 'Enabled' : 'Disabled' }}\n                      </span>\n                    </label>\n                  </template>\n                </v-switch>\n              </div>\n            </template>\n            <span v-if=\"permissionsCheck\">\n              You don't have permission to modify flow settings.\n            </span>\n            <span v-else>\n              {{ isHeartbeatEnabled ? 'Disable' : 'Enable' }} heartbeats for\n              this flow.\n            </span>\n          </v-tooltip>\n\n          <div class=\"mt-4\">\n            Heartbeats are sent by Prefect Core every 30 seconds and are used to\n            confirm the flow run and its associated task runs are healthy; runs\n            missing four heartbeats in a row are marked as\n            <v-chip class=\"mx-1\" label small color=\"Failed\" dark>\n              Failed\n            </v-chip>\n            by the\n            <a\n              href=\"https://docs.prefect.io/cloud/concepts/services.html#zombie-killer\"\n              target=\"_blank\"\n            >\n              Zombie Killer\n            </a>\n            <sup>\n              <v-icon x-small color=\"primary\">\n                open_in_new\n              </v-icon> </sup\n            >. You can read more about heartbeats\n            <a\n              href=\"https://docs.prefect.io/cloud/concepts/flows.html#flow-settings\"\n              target=\"_blank\"\n              >here\n            </a>\n            <sup>\n              <v-icon x-small color=\"primary\">\n                open_in_new\n              </v-icon> </sup\n            >.\n          </div>\n        </v-col>\n      </v-row>\n\n      <v-row class=\"mt-8\">\n        <v-col cols=\"12\" class=\"pb-0\">\n          <div class=\"text-h6 primary--text\">\n            <!-- We don't really have the visual language necessary to use these I think -->\n            <!-- <v-icon class=\"mr-3\">fas fa-book-dead</v-icon> -->\n            Lazarus Process\n          </div>\n        </v-col>\n        <v-col cols=\"12\" class=\"pt-0\">\n          <v-tooltip bottom>\n            <template #activator=\"{ on }\">\n              <div class=\"pb-1\" style=\"display: inline-block;\" v-on=\"on\">\n                <v-switch\n                  v-model=\"selected.lazarusEnabled\"\n                  hide-details\n                  color=\"primary\"\n                  :loading=\"loading.lazarus\"\n                  :disabled=\"permissionsCheck || loading.lazarus\"\n                  @change=\"_handleLazarusChange\"\n                >\n                  <template #label>\n                    <label>\n                      Lazarus\n                      <span\n                        :class=\"\n                          isLazarusEnabled\n                            ? 'prefect--text'\n                            : 'grey--text text--darken-2'\n                        \"\n                        class=\"font-weight-medium\"\n                      >\n                        {{ isLazarusEnabled ? 'Enabled' : 'Disabled' }}\n                      </span>\n                    </label>\n                  </template>\n                </v-switch>\n              </div>\n            </template>\n            <span v-if=\"permissionsCheck\">\n              You don't have permission to modify flow settings.\n            </span>\n            <span v-else>\n              {{ isLazarusEnabled ? 'Disable' : 'Enable' }} Lazarus for this\n              flow.\n            </span>\n          </v-tooltip>\n\n          <div class=\"mt-4\">\n            The Lazarus process is responsible for rescheduling distressed flow\n            runs. Read more about Lazarus\n            <a\n              href=\"https://docs.prefect.io/cloud/concepts/services.html#lazarus\"\n              target=\"_blank\"\n              >here\n            </a>\n            <sup>\n              <v-icon x-small color=\"primary\">\n                open_in_new\n              </v-icon> </sup\n            >.\n          </div>\n        </v-col>\n      </v-row>\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "src/pages/Flow/Settings/ScheduleParameters.vue",
    "content": "<template>\n  <resettable-wrapper\n    :value=\"internalValue\"\n    class=\"resettable-dictionary-json\"\n    @input=\"reset\"\n  >\n    <code-input\n      v-model=\"internalValue\"\n      :editors=\"['dict', 'json']\"\n      :checked.sync=\"internalChecked\"\n      show-checkboxes\n      show-types\n      readonly-key\n      disable-add\n      disable-remove\n      @input=\"autoCheckOnEdit\"\n    />\n  </resettable-wrapper>\n</template>\n\n<script>\nimport ResettableWrapper from '@/components/CustomInputs/ResettableWrapper'\nimport CodeInput from '@/components/CustomInputs/CodeInput'\nimport { tryParseJson } from '@/utils/json'\n\nexport default {\n  name: 'ScheduleParameter',\n  components: {\n    ResettableWrapper,\n    CodeInput\n  },\n  props: {\n    value: {\n      type: String,\n      required: false,\n      default: null\n    },\n    checked: {\n      type: Array,\n      required: false,\n      default: () => []\n    }\n  },\n  computed: {\n    internalValue: {\n      get() {\n        return this.value\n      },\n      set(value) {\n        this.$emit('input', value)\n      }\n    },\n    internalChecked: {\n      get() {\n        return this.checked\n      },\n      set(value) {\n        this.$emit('update:checked', value)\n      }\n    }\n  },\n  methods: {\n    reset(value) {\n      this.internalValue = value\n      this.internalChecked = []\n    },\n    addKeyToChecked(key) {\n      if (!this.internalChecked.includes(key)) {\n        this.internalChecked.push(key)\n      }\n    },\n    autoCheckOnEdit(updated) {\n      const updatedObject = tryParseJson(updated) || {}\n      const previousObject = tryParseJson(this.value) || {}\n\n      const keysThatChanged = Object.entries(updatedObject)\n        .filter(([key, value]) => value !== previousObject[key])\n        .map(([key]) => key)\n\n      keysThatChanged.forEach(this.addKeyToChecked)\n    }\n  }\n}\n</script>\n"
  },
  {
    "path": "src/pages/Flow/Settings/Schedules.vue",
    "content": "<script>\nimport { mapGetters, mapActions } from 'vuex'\n\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport CronClock from '@/components/Functional/CronClock'\nimport ExternalLink from '@/components/ExternalLink'\nimport IntervalClock from '@/components/Functional/IntervalClock'\nimport LogRocket from 'logrocket'\nimport ClockForm from '@/pages/Flow/Settings/ClockForm'\nimport { parametersMixin } from '@/mixins/parametersMixin.js'\nexport default {\n  components: {\n    ConfirmDialog,\n    CronClock,\n    ExternalLink,\n    IntervalClock,\n    ClockForm\n  },\n  mixins: [parametersMixin],\n  props: {\n    flow: { required: true, type: Object },\n    flowGroup: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      cronClock: '0 0 * * * *',\n      clocks: [],\n      clockToRemove: null,\n      error: null,\n      intervalClock: 180000,\n      loading: false,\n      removeScheduleDialog: false,\n      selectedClock: null,\n      scheduleBanner: false,\n      selectedTab: '',\n      parameter: {}\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone']),\n    ...mapGetters('license', ['hasPermission']),\n\n    flowClocks() {\n      return this.flow.schedule?.clocks.map(c => {\n        // This is so we know where each clock originates while allowing us to put them in a single array\n        c.scheduleType = 'flow'\n        return c\n      })\n    },\n    flowGroupClocks() {\n      return this.flowGroup.schedule?.clocks.map(c => {\n        // This is so we know where each clock originates while allowing us to put them in a single array\n        c.scheduleType = 'flow-group'\n        return c\n      })\n    },\n    hasFlowGroupSchedule() {\n      return this.flowGroupClocks && this.flowGroupClocks.length > 0\n    }\n  },\n  watch: {\n    clocks() {\n      this.scheduleBanner =\n        !this.flow?.is_schedule_active && this.clocks.length > 0\n    }\n  },\n  mounted() {\n    this.clocks = [\n      ...((this.flowGroupClocks && this.flowGroupClocks) || []),\n      ...((this.flowClocks && this.flowClocks) || [])\n    ]\n\n    this.scheduleBanner =\n      !this.flow?.is_schedule_active && this.clocks?.length > 0\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    async createClock(val) {\n      let isNew = false\n      this.loading = true\n      if (this.selectedClock > -1) {\n        this.clocks[this.selectedClock] = {\n          ...this.clocks[this.selectedClock],\n          ...val\n        }\n        let shifted = [...this.clocks]\n        shifted.unshift(shifted.splice(this.selectedClock, 1)[0])\n        this.clocks = shifted\n      } else {\n        isNew = true\n        this.clocks.push({ ...val, scheduleType: 'flow-group' })\n        this.clocks = this.clocks.reverse()\n      }\n      await this.modifySchedules({ new: isNew })\n      this.selectedClock = null\n      this.loading = false\n    },\n    async deleteClock() {\n      this.loading = true\n      this.clocks = this.clocks.filter((clock, i) => i !== this.clockToRemove)\n      await this.modifySchedules({ delete: true })\n      this.clockToRemove = null\n      this.removeScheduleDialog = false\n      this.loading = false\n    },\n    async modifySchedules(options) {\n      this.error = false\n\n      try {\n        const cronClocks = [\n          ...this.clocks\n            .filter(c => c.type == 'CronClock' && c.scheduleType !== 'flow')\n            .map(c => {\n              if (c.parameter_defaults) {\n                if (\n                  c.parameter_defaults === null ||\n                  Object.keys(c.parameter_defaults).length === 0\n                ) {\n                  return {\n                    cron: c.cron\n                  }\n                } else {\n                  return {\n                    cron: c.cron,\n                    parameter_defaults: c.parameter_defaults\n                  }\n                }\n              }\n\n              return {\n                cron: c.cron\n              }\n            })\n        ]\n\n        const intervalClocks = [\n          ...this.clocks\n            .filter(c => c.type == 'IntervalClock' && c.scheduleType !== 'flow')\n            .map(c => {\n              if (c.parameter_defaults) {\n                if (\n                  c.parameter_defaults === null ||\n                  Object.keys(c.parameter_defaults).length === 0\n                ) {\n                  // input for interval clocks is seconds but are converted to\n                  // microseconds at the database level so we need to\n                  // convert this back to microseconds\n                  return {\n                    interval: c.interval / 1000000\n                  }\n                } else {\n                  return {\n                    interval: c.interval / 1000000,\n                    parameter_defaults: c.parameter_defaults\n                  }\n                }\n              }\n\n              return {\n                interval: c.interval / 1000000\n              }\n            })\n        ]\n\n        let result\n\n        if (cronClocks?.length === 0 && intervalClocks?.length === 0) {\n          result = await this.$apollo.mutate({\n            mutation: require('@/graphql/Mutations/delete-flow-group-schedule.gql'),\n            variables: {\n              input: {\n                flow_group_id: this.flowGroup.id\n              }\n            }\n          })\n        } else {\n          result = await this.$apollo.mutate({\n            mutation: require('@/graphql/Mutations/set-flow-group-schedule.gql'),\n            variables: {\n              input: {\n                flow_group_id: this.flowGroup.id,\n                cron_clocks: cronClocks,\n                interval_clocks: intervalClocks,\n                timezone: this.clocks[0]?.timezone\n                  ? this.clocks[0]?.timezone\n                  : this.timezone ||\n                    Intl.DateTimeFormat().resolvedOptions().timeZone\n              }\n            }\n          })\n        }\n\n        if (\n          result?.data?.set_flow_group_schedule?.success ||\n          result?.data?.delete_flow_group_schedule?.success\n        ) {\n          this.setAlert({\n            alertShow: true,\n            alertMessage: `Schedule ${\n              options.new ? 'created' : options.delete ? 'deleted' : 'modified'\n            }!`,\n            alertType: 'success'\n          })\n        } else {\n          this.error = result?.data?.set_flow_group_schedule.error\n        }\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Settings - Schedules',\n            stage: 'Modifying schedules'\n          }\n        })\n        this.error = e\n      }\n\n      this.loading = false\n\n      if (this.error) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `There was a problem ${\n            options.new ? 'creating' : options.delete ? 'deleting' : 'modifying'\n          } your schedule, please try again shortly. Error message: ${\n            this.error\n          }`,\n          alertType: 'error'\n        })\n      }\n    },\n    timezoneVal(clock) {\n      if (clock.scheduleType == 'flow') {\n        return clock?.start_date?.tz || 'UTC'\n      } else if (this.clocks[0] && clock.scheduleType == 'flow-group') {\n        return this.clocks[0]?.timezone || this.clocks[0]?.start_date?.tz\n      }\n\n      return this.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone\n    }\n  }\n}\n</script>\n\n<template>\n  <div style=\"overflow: hidden;\">\n    <v-banner\n      key=\"1\"\n      v-model=\"scheduleBanner\"\n      icon=\"alarm_off\"\n      sticky\n      single-line\n      class=\"text-body-2 black--text py-0\"\n      icon-color=\"white\"\n      color=\"amber\"\n      tile\n      transition=\"slide-y-transition\"\n    >\n      Psst! We noticed you've got schedules here but your flow's schedule isn't\n      turned on; turn it on with the toggle at the top of the page to start\n      scheduling flows!\n      <template #actions=\"{ dismiss }\">\n        <v-btn text color=\"white\" @click=\"dismiss\">Close</v-btn>\n      </template>\n    </v-banner>\n\n    <div class=\"schedule-grid my-4\">\n      <div\n        class=\"grid-container\"\n        :class=\"{ 'grid-container-large': selectedClock === -1 }\"\n      >\n        <v-card\n          v-if=\"hasPermission('create', 'run')\"\n          class=\"clock-card\"\n          :class=\"{ 'clock-card-large': selectedClock === -1 }\"\n          :style=\"{ 'pointer-events': selectedClock === -1 ? 'none' : 'auto' }\"\n          tile\n          :ripple=\"false\"\n          @click.native=\"selectedClock = -1\"\n        >\n          <v-card-text\n            style=\"\n            height: 100%;\n            overflow: auto;\n            \"\n            :style=\"{ 'pointer-events': 'auto' }\"\n          >\n            <v-fade-transition mode=\"out-in\">\n              <div v-if=\"selectedClock == -1\" key=\"1\" style=\"height: 100%;\">\n                <span class=\"text-h5 black--text\">New schedule</span>\n\n                <v-tabs v-model=\"selectedTab\">\n                  <v-tab>Schedule</v-tab>\n                  <v-tab>Parameters</v-tab>\n                </v-tabs>\n\n                <ClockForm\n                  :flow-group-clocks=\"flowGroupClocks\"\n                  :timezone=\"\n                    this.timezone ||\n                      Intl.DateTimeFormat().resolvedOptions().timeZone\n                  \"\n                  :selected-tab=\"selectedTab\"\n                  :default-parameters=\"defaultParameters\"\n                  @cancel=\"selectedClock = null\"\n                  @confirm=\"createClock\"\n                />\n              </div>\n              <div\n                v-else\n                key=\"2\"\n                class=\"d-flex align-center justify-center flex-column\"\n                style=\" cursor: pointer;\n            height: 100%;\n            user-select: none;\"\n              >\n                <v-icon color=\"codePink\" x-large>alarm_add</v-icon>\n\n                <div class=\"text-h6 mt-2\">New schedule</div>\n              </div>\n            </v-fade-transition>\n          </v-card-text>\n        </v-card>\n      </div>\n\n      <div\n        v-for=\"(clock, i) in clocks\"\n        :key=\"i\"\n        class=\"grid-container\"\n        :class=\"{ 'grid-container-large': selectedClock === i }\"\n      >\n        <v-card\n          class=\"clock-card text-truncate\"\n          :class=\"{ 'clock-card-large': selectedClock === i }\"\n          color=\"appForeground\"\n          :style=\"{\n            'border-left':\n              clock.scheduleType == 'flow'\n                ? '4px solid var(--v-primary-base) !important'\n                : '',\n            'border-left-color': 'var(--v-primary-base) !important',\n            opacity:\n              hasFlowGroupSchedule && clock.scheduleType == 'flow' ? '0.5' : ''\n          }\"\n          tile\n        >\n          <v-fade-transition mode=\"out-in\">\n            <div\n              v-if=\"selectedClock == i\"\n              key=\"1\"\n              style=\"height: 100%;\n              overflow: auto;\n              padding: 20px;\n              white-space: pre-wrap;\n              \"\n            >\n              <span class=\"text-h5 black--text\">Modify schedule</span>\n\n              <v-tabs v-model=\"selectedTab\">\n                <v-tab>Schedule</v-tab>\n                <v-tab>Parameters</v-tab>\n              </v-tabs>\n\n              <ClockForm\n                :flow-group-clocks=\"flowGroupClocks\"\n                :clock=\"clock\"\n                :cron=\"clock.cron\"\n                :param=\"clock.parameter_defaults\"\n                :interval=\"clock.interval\"\n                :timezone=\"timezoneVal(clock)\"\n                :selected-tab=\"selectedTab\"\n                :default-parameters=\"defaultParameters\"\n                @cancel=\"selectedClock = null\"\n                @confirm=\"createClock\"\n              />\n            </div>\n\n            <div v-else key=\"2\" style=\"height: 100%;\">\n              <v-row\n                style=\"height: 100%;\n        white-space: pre-wrap;\"\n                no-gutters\n              >\n                <v-col cols=\"10\" class=\"d-flex flex-column align-start\">\n                  <div\n                    style=\"height: 90%;\"\n                    class=\"d-flex align-start justify-start pa-4 font-weight-bold text-h5\"\n                    no-gutters\n                  >\n                    <CronClock\n                      v-if=\"clock.type == 'CronClock'\"\n                      :cron=\"clock.cron\"\n                      :timezone=\"timezoneVal(clock)\"\n                    />\n                    <IntervalClock\n                      v-else-if=\"clock.type == 'IntervalClock'\"\n                      :interval=\"clock.interval\"\n                    />\n                    <div v-else>Unrecognized clock</div>\n                  </div>\n\n                  <div class=\"pb-3 pl-4 mt-auto\">\n                    <v-tooltip\n                      v-if=\"clock.scheduleType == 'flow'\"\n                      max-width=\"300\"\n                      top\n                    >\n                      <template #activator=\"{ on }\">\n                        <v-chip\n                          class=\"px-2 rounded-sm mr-1\"\n                          label\n                          x-small\n                          v-on=\"on\"\n                        >\n                          Read-only\n                        </v-chip>\n                      </template>\n                      This schedule was set in your Flow's code so it can't be\n                      modifed.\n                    </v-tooltip>\n\n                    <v-tooltip\n                      v-if=\"\n                        clock.parameter_defaults &&\n                          Object.keys(clock.parameter_defaults).length !== 0\n                      \"\n                      max-width=\"200\"\n                      top\n                    >\n                      <template #activator=\"{ on }\">\n                        <v-chip\n                          v-if=\"\n                            clock.parameter_defaults &&\n                              Object.keys(clock.parameter_defaults).length !== 0\n                          \"\n                          class=\"px-2 rounded-sm mr-1\"\n                          label\n                          color=\"codeBlue lighten-1\"\n                          dark\n                          x-small\n                          v-on=\"on\"\n                        >\n                          Default parameters\n                        </v-chip>\n                      </template>\n                      This schedule overrides default parameters.\n                    </v-tooltip>\n\n                    <v-tooltip\n                      v-if=\"\n                        hasFlowGroupSchedule && clock.scheduleType == 'flow'\n                      \"\n                      max-width=\"300\"\n                      top\n                    >\n                      <template #activator=\"{ on }\">\n                        <v-chip\n                          class=\"px-2 rounded-sm mr-1\"\n                          label\n                          x-small\n                          v-on=\"on\"\n                        >\n                          Not scheduled\n                        </v-chip>\n                      </template>\n                      The existing flow group schedule will overide this\n                      schedule.\n                    </v-tooltip>\n                  </div>\n                </v-col>\n                <v-col\n                  cols=\"2\"\n                  class=\"d-flex align-center flex-column justify-end pa-1\"\n                  style=\"\n                    border-left: 1px solid var(--v-utilGrayLight-base);\n                    height: 100%;\"\n                >\n                  <v-menu\n                    v-model=\"clock.contextMenu\"\n                    offset-y\n                    :close-on-content-click=\"false\"\n                    open-on-hover\n                  >\n                    <template #activator=\"{ on }\">\n                      <div\n                        class=\"my-1 mb-auto d-block text-decoration-none\"\n                        v-on=\"on\"\n                        @focus=\"clock.contextMenu = true\"\n                        @blur=\"clock.contextMenu = false\"\n                      >\n                        <v-icon color=\"grey\" small>\n                          info\n                        </v-icon>\n                      </div>\n                    </template>\n                    <v-card tile class=\"pa-0\" max-width=\"320\">\n                      <v-card-text class=\"pb-0\">\n                        <p v-if=\"clock.scheduleType == 'flow'\">\n                          <v-alert\n                            border=\"left\"\n                            colored-border\n                            elevation=\"0\"\n                            type=\"warning\"\n                            dense\n                            icon=\"warning\"\n                            max-width=\"500\"\n                          >\n                            <div class=\"text-body-2 ma-0\"\n                              >This schedule was set in your Flow's code so it\n                              can't be modifed.</div\n                            >\n\n                            <div\n                              v-if=\"hasFlowGroupSchedule\"\n                              class=\"text-body-2 ma-0 mt-2\"\n                            >\n                              The existing flow group schedule will overide this\n                              schedule.\n                            </div>\n                          </v-alert>\n                        </p>\n                        <p>\n                          This schedule was created as a{{\n                            'cron' in clock\n                              ? ' Cron'\n                              : 'date' in clock\n                              ? ' Date'\n                              : 'n Interval'\n                          }}\n                          clock with a value of\n                          <span class=\"font-weight-bold\">\n                            {{ clock.cron || clock.interval || clock.date\n                            }}{{ clock.interval ? ' µs' : '' }}\n                          </span>\n                        </p>\n                        <p class=\"mt-1\">\n                          <ExternalLink\n                            :href=\"\n                              `https://docs.prefect.io/core/concepts/schedules.html#${\n                                'cron' in clock\n                                  ? 'cron'\n                                  : 'date' in clock\n                                  ? 'date'\n                                  : 'interval'\n                              }-clocks`\n                            \"\n                            @click=\"clock.contextMenu = false\"\n                          >\n                            Visit the docs\n                          </ExternalLink>\n                          to learn more about\n                          {{\n                            'cron' in clock\n                              ? 'Cron'\n                              : 'date' in clock\n                              ? 'Date'\n                              : 'Interval'\n                          }}\n                          clocks on Prefect schedules.\n                        </p>\n                      </v-card-text>\n                      <v-card-actions class=\"pt-0\">\n                        <v-spacer></v-spacer>\n                        <v-btn small text @click=\"clock.contextMenu = false\">\n                          Close\n                        </v-btn>\n                      </v-card-actions>\n                    </v-card>\n                  </v-menu>\n\n                  <v-tooltip\n                    v-if=\"clock.scheduleType == 'flow-group'\"\n                    max-width=\"200\"\n                    :background-opacity=\"1\"\n                    left\n                  >\n                    <template #activator=\"{ on }\">\n                      <v-btn\n                        v-if=\"hasPermission('update', 'run')\"\n                        icon\n                        fab\n                        class=\"my-1\"\n                        color=\"primary lighten-2\"\n                        x-small\n                        @click.native=\"selectedClock = i\"\n                        v-on=\"on\"\n                      >\n                        <v-icon>\n                          edit\n                        </v-icon>\n                      </v-btn>\n                    </template>\n                    Modify this schedule\n                  </v-tooltip>\n\n                  <v-tooltip\n                    v-if=\"clock.scheduleType == 'flow-group'\"\n                    max-width=\"300\"\n                    :background-opacity=\"1\"\n                    left\n                  >\n                    <template #activator=\"{ on }\">\n                      <v-btn\n                        v-if=\"hasPermission('delete', 'run')\"\n                        icon\n                        fab\n                        class=\"mt-1\"\n                        color=\"red lighten-2\"\n                        x-small\n                        @click.native=\"\n                          removeScheduleDialog = true\n                          clockToRemove = i\n                        \"\n                        v-on=\"on\"\n                      >\n                        <v-icon>\n                          delete\n                        </v-icon>\n                      </v-btn>\n                    </template>\n                    Remove this schedule\n                  </v-tooltip>\n                </v-col>\n              </v-row>\n            </div>\n          </v-fade-transition>\n        </v-card>\n      </div>\n\n      <ConfirmDialog\n        v-model=\"removeScheduleDialog\"\n        type=\"error\"\n        :dialog-props=\"{ 'max-width': '500' }\"\n        :disabled=\"loading\"\n        :loading=\"loading\"\n        title=\"Remove schedule\"\n        @cancel=\"clockToRemove = null\"\n        @confirm=\"deleteClock\"\n      >\n        You can always recreate this schedule later.\n      </ConfirmDialog>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n$cellsize: 225px;\n$guttersize: 24px;\n\n.schedule-grid {\n  column-gap: $guttersize;\n  display: grid;\n  grid-auto-flow: dense;\n  grid-auto-rows: $cellsize;\n  grid-template-columns: repeat(auto-fill, $cellsize);\n  justify-content: center;\n  row-gap: $guttersize;\n}\n\n.grid-container {\n  grid-column: span 1;\n  grid-row: span 1;\n  overflow: visible;\n  position: relative;\n\n  &.grid-container-large {\n    grid-column: span 3;\n    grid-row: span 3;\n  }\n}\n\n.clock-card {\n  height: 100%;\n  left: 0;\n  max-height: $cellsize + $guttersize;\n  max-width: $cellsize + $guttersize;\n  min-height: $cellsize;\n  min-width: $cellsize;\n  position: absolute;\n  top: 0;\n  transition: all 250ms;\n  width: 100%;\n\n  &.clock-card-large {\n    max-height: $cellsize * 3 + $guttersize * 3;\n    max-width: $cellsize * 3 + $guttersize * 3;\n    min-height: $cellsize * 3;\n    min-width: $cellsize * 3;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Settings.vue",
    "content": "<script>\nimport CloudHooks from '@/pages/Flow/Settings/CloudHooks'\nimport GeneralSettings from '@/pages/Flow/Settings/General'\nimport Parameters from '@/pages/Flow/Settings/DefaultParameters'\nimport Schedules from '@/pages/Flow/Settings/Schedules'\n\nexport default {\n  components: {\n    CloudHooks,\n    GeneralSettings,\n    Parameters,\n    Schedules\n  },\n  props: {\n    flow: {\n      required: true,\n      type: Object\n    },\n    flowGroup: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      tab: 0\n    }\n  },\n  computed: {\n    isMobile() {\n      return this.$vuetify.breakpoint.smAndDown\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet color=\"appBackground\">\n    <v-tabs\n      v-model=\"tab\"\n      fixed-tabs\n      icons-and-text\n      color=\"accentPink\"\n      tabs-border-bottom\n      class=\"ml-n1 pt-2\"\n      style=\"width: calc(100% + 8px);\"\n    >\n      <v-tab key=\"general\" data-cy=\"flow-settings-general-tab\">\n        General\n        <v-icon>settings</v-icon>\n      </v-tab>\n\n      <v-tab key=\"cloud-hooks\" data-cy=\"flow-settings-cloud-hooks-tab\">\n        Cloud Hooks\n        <v-icon>cloud</v-icon>\n      </v-tab>\n\n      <v-tab key=\"schedules\" data-cy=\"flow-settings-schedules-tab\">\n        Schedules\n        <v-icon>schedule</v-icon>\n      </v-tab>\n\n      <v-tab key=\"parameters\" data-cy=\"flow-settings-parameters-tab\">\n        Parameters\n        <v-icon>perm_data_setting</v-icon>\n      </v-tab>\n    </v-tabs>\n\n    <v-tabs-items v-model=\"tab\">\n      <v-tab-item>\n        <GeneralSettings :flow=\"flow\" :flow-group=\"flowGroup\" />\n      </v-tab-item>\n\n      <v-tab-item>\n        <CloudHooks :flow=\"flow\" :flow-group=\"flowGroup\" />\n      </v-tab-item>\n      <v-tab-item>\n        <Schedules v-if=\"tab == 2\" :flow=\"flow\" :flow-group=\"flowGroup\" />\n      </v-tab-item>\n      <v-tab-item>\n        <Parameters :flow-group=\"flowGroup\" />\n      </v-tab-item>\n    </v-tabs-items>\n\n    <v-bottom-navigation\n      v-if=\"isMobile\"\n      class=\"bottom-sub-nav\"\n      horizontal\n      fixed\n      color=\"accentPink\"\n    >\n      <v-btn :input-value=\"tab == 0\" @click=\"tab = 0\">\n        General\n        <v-icon>settings</v-icon>\n      </v-btn>\n\n      <v-btn :input-value=\"tab == 1\" @click=\"tab = 1\">\n        Cloud Hooks\n        <v-icon>cloud</v-icon>\n      </v-btn>\n\n      <v-btn :input-value=\"tab == 2\" @click=\"tab = 2\">\n        Schedules\n        <v-icon>schedule</v-icon>\n      </v-btn>\n\n      <v-btn :input-value=\"tab == 3\" @click=\"tab = 3\">\n        Parameters\n        <v-icon>format_list_numbered_rtl</v-icon>\n      </v-btn>\n    </v-bottom-navigation>\n  </v-sheet>\n</template>\n\n<style lang=\"scss\">\n.bottom-sub-nav {\n  bottom: 56px !important;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Summary-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport StackedLineChart from '@/components/Visualizations/StackedLineChart'\nimport { STATE_COLORS, STATE_PAST_TENSE } from '@/utils/states'\nimport { roundedOneAgo } from '@/utils/dateTime'\n\nexport default {\n  components: {\n    CardTitle,\n    StackedLineChart\n  },\n  props: {\n    aggregate: {\n      type: Boolean,\n      default: () => false\n    },\n    flow: {\n      type: Object,\n      required: true\n    },\n    fullHeight: {\n      required: false,\n      type: Boolean,\n      default: () => false\n    }\n  },\n  data() {\n    return {\n      dateFilters: [\n        { name: '1 Hour', value: 'hour' },\n        { name: '24 Hours', value: 'day' },\n        { name: '7 Days', value: 'week' },\n        { name: '30 Days', value: 'month' }\n      ],\n      loading: 0,\n      selectedDateFilter: 'day',\n      stateSegments: [],\n      total: 0\n    }\n  },\n  computed: {\n    computedDateFilter() {\n      return this.dateFilters.find(d => d.value == this.selectedDateFilter)\n        .value\n    },\n    colors() {\n      return STATE_COLORS\n    },\n    filteredStateSegments() {\n      return this.stateSegments\n        .filter(s => s.value > 0)\n        .sort((sA, sB) => {\n          return sA.value > sB.value ? -1 : sA.value < sB.value ? 1 : 0\n        })\n    },\n    moreStateSegments() {\n      return this.filteredStateSegments.slice(3)\n    },\n    pollInterval() {\n      return this.flow.archived ? 0 : 5000\n    }\n  },\n  watch: {\n    selectedDateFilter() {\n      this.$apollo.queries.flowRunsAggregate.refetch()\n    },\n    flow() {\n      this.$apollo.queries.flowRunsAggregate.stopPolling()\n\n      if (this.pollInterval > 0) {\n        this.$apollo.queries.flowRunsAggregate.startPolling(this.pollInterval)\n      } else {\n        this.$apollo.queries.flowRunsAggregate.refetch()\n      }\n    }\n  },\n  mounted() {\n    if (this.pollInterval > 0) {\n      this.$apollo.queries.flowRunsAggregate.startPolling(this.pollInterval)\n    }\n  },\n  methods: {\n    cursorPointer(event) {\n      event.target.style.cursor = 'pointer'\n    },\n    humanLabel(label) {\n      return STATE_PAST_TENSE[label]\n    },\n    statusStyle(state) {\n      return {\n        'border-radius': '50%',\n        display: 'inline-block',\n        'background-color': this.colors[state],\n        height: '1rem',\n        width: '1rem'\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRunsAggregate.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRunsAggregate: {\n      query: require('@/graphql/Flow/flow-runs.gql'),\n      loadingKey: 'loading',\n      variables() {\n        let variables = { heartbeat: null }\n\n        if (this.aggregate) {\n          variables.flow_group_id = this.flow.flow_group_id\n        } else {\n          variables.flow_id = this.flow.id\n        }\n\n        if (!this.flow.archived) {\n          variables.heartbeat = roundedOneAgo(this.selectedDateFilter)\n        }\n        return variables\n      },\n      update(data) {\n        if (data.loading) return\n\n        this.total = 0\n\n        Object.keys(data).forEach(state => {\n          let index = this.stateSegments.findIndex(s => s.label == state)\n          if (index > -1) {\n            this.stateSegments[index].value = data[state].aggregate.count\n          } else {\n            this.stateSegments.push({\n              label: state,\n              value: data[state].aggregate.count\n            })\n          }\n\n          this.total += data[state].aggregate.count\n        })\n        return this.stateSegments\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"pa-2\"\n    tile\n    :style=\"{\n      height: fullHeight ? '100%' : 'auto'\n    }\"\n  >\n    <v-tooltip top>\n      <template #activator=\"{ on }\">\n        <CardTitle title=\"Flow Runs Summary\" icon=\"pi-flow-run\">\n          <div slot=\"action\" v-on=\"on\">\n            <v-select\n              data-public\n              v-if=\"!flow.archived\"\n              v-model=\"selectedDateFilter\"\n              class=\"time-interval-picker\"\n              :items=\"dateFilters\"\n              dense\n              solo\n              item-text=\"name\"\n              item-value=\"value\"\n              hide-details\n              flat\n            >\n              <template #prepend-inner>\n                <v-icon color=\"utilGrayDark\" x-small>\n                  history\n                </v-icon>\n              </template>\n            </v-select>\n          </div>\n        </CardTitle>\n      </template>\n      <span>\n        Filter by when runs were last updated\n      </span>\n    </v-tooltip>\n\n    <v-card-text\n      class=\"pb-0 pt-2 card-content d-flex align-center justify-center\"\n    >\n      <div style=\"width: 100%;\">\n        <v-row no-gutters>\n          <v-col v-if=\"!flow.archived\" class=\"text-subtitle-2 text-center\">\n            In the last {{ selectedDateFilter }}\n          </v-col>\n          <v-col v-else class=\"text-subtitle-2 text-center\">\n            All Time\n          </v-col>\n        </v-row>\n        <v-row>\n          <v-col cols=\"5\">\n            <div class=\"text-center\">\n              <div class=\"font-weight-bold text-h4\" style=\"min-height: 36px;\">\n                <v-skeleton-loader\n                  v-if=\"!filteredStateSegments && loading > 0\"\n                  type=\"heading\"\n                  class=\"centered-skeleton\"\n                />\n                <v-tooltip v-else-if=\"filteredStateSegments.length > 0\" bottom>\n                  <template #activator=\"{ on }\">\n                    <span v-on=\"on\">\n                      <span class=\"hoverable\">\n                        {{ total.toLocaleString() }}\n                      </span>\n                    </span>\n                  </template>\n                  <div>\n                    <div\n                      v-for=\"segment in filteredStateSegments\"\n                      :key=\"segment.label\"\n                      class=\"d-flex align-center justify-space-between\"\n                    >\n                      <span>\n                        <span :style=\"statusStyle(segment.label)\" class=\"mr-2\">\n                        </span>\n                        <span>\n                          {{ segment.value.toLocaleString() }}\n                        </span>\n                      </span>\n                      <span class=\"ml-2\">\n                        {{ humanLabel(segment.label) }}\n                      </span>\n                    </div>\n                  </div>\n                </v-tooltip>\n                <div v-else>0</div>\n              </div>\n              <div class=\"subtitle\"> flow run{{ total !== 1 ? 's' : '' }} </div>\n            </div>\n          </v-col>\n          <v-col cols=\"2\" class=\"d-flex align-center justify-center\">\n            <StackedLineChart\n              :segments=\"stateSegments\"\n              :colors=\"colors\"\n              :width=\"50\"\n              vertical\n            />\n          </v-col>\n          <v-col cols=\"5\">\n            <div class=\"text-center\">\n              <div class=\"font-weight-bold text-h5\" style=\"min-height: 36px;\">\n                <v-skeleton-loader\n                  v-if=\"!filteredStateSegments && loading > 0\"\n                  type=\"heading\"\n                  class=\"centered-skeleton\"\n                />\n                <v-tooltip v-else-if=\"filteredStateSegments.length > 0\" bottom>\n                  <template #activator=\"{ on }\">\n                    <span v-on=\"on\">\n                      <span class=\"hoverable\">\n                        {{\n                          ((filteredStateSegments[0].value / total) * 100)\n                            | roundTenths\n                        }}\n                      </span>\n                      <span class=\"text-subtitle-2\">%</span>\n                    </span>\n                  </template>\n                  <div>\n                    <div\n                      v-for=\"segment in filteredStateSegments\"\n                      :key=\"segment.label\"\n                      class=\"d-flex align-center justify-space-between\"\n                    >\n                      <span>\n                        <span :style=\"statusStyle(segment.label)\" class=\"mr-2\">\n                        </span>\n                        <span>\n                          {{\n                            ((segment.value / total) * 100)\n                              | roundTenths\n                              | filterOnePercent\n                          }}%\n                        </span>\n                      </span>\n                      <span class=\"ml-2\">\n                        {{ humanLabel(segment.label) }}\n                      </span>\n                    </div>\n                  </div>\n                </v-tooltip>\n              </div>\n              <div class=\"subtitle\">\n                <v-skeleton-loader\n                  v-if=\"!filteredStateSegments && loading > 0\"\n                  type=\"text\"\n                  class=\"centered-skeleton\"\n                />\n                <div v-else-if=\"filteredStateSegments.length > 0\">\n                  {{ humanLabel(filteredStateSegments[0].label) }}\n                </div>\n              </div>\n            </div>\n          </v-col>\n        </v-row>\n      </div>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.hoverable {\n  border-bottom: 1px dotted var(--v-utilGrayLight-base);\n  box-sizing: content-box;\n}\n\n.time-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n</style>\n\n<style lang=\"scss\">\n.card-content {\n  height: 254px;\n}\n\n.centered-skeleton {\n  // stylelint-disable\n  .v-skeleton-loader__bone {\n    margin: auto !important;\n  }\n  // stylelint-enable\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/TasksTable-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nexport default {\n  components: {\n    CardTitle\n  },\n  filters: {\n    typeClass: val => val.split('.').pop()\n  },\n  props: {\n    flow: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      headers: [\n        { text: 'Name', value: 'name', width: '30%' },\n        { text: 'Max Retries', value: 'max_retries', width: '10%' },\n        { text: 'Retry Delay', value: 'retry_delay', width: '10%' },\n        { text: 'Class', value: 'type', width: '15%' },\n        { text: 'Trigger', value: 'trigger', width: '15%' }\n      ],\n      itemsPerPage: 15,\n      loadingKey: 0,\n      page: 1,\n      searchTerm: null,\n      sortBy: 'name',\n      sortDesc: false,\n      tasks: null,\n      tasksCount: null\n    }\n  },\n  computed: {\n    loading() {\n      return this.loadingKey > 0\n    },\n    offset() {\n      return this.itemsPerPage * (this.page - 1)\n    },\n    searchFormatted() {\n      if (!this.searchTerm) return null\n      return `%${this.searchTerm}%`\n    }\n  },\n  apollo: {\n    tasks: {\n      query: require('@/graphql/Flow/table-tasks.gql'),\n      loadingKey: 'loadingKey',\n      variables() {\n        const orderBy = {}\n        orderBy[`${this.sortBy}`] = this.sortDesc ? 'desc' : 'asc'\n\n        return {\n          flowId: this.flow.id,\n          heartbeat: this.heartbeat,\n          limit: this.itemsPerPage,\n          name: this.searchFormatted,\n          offset: this.offset,\n          orderBy\n        }\n      },\n      update: data => data?.task\n    },\n    tasksCount: {\n      query: require('@/graphql/Flow/table-tasks-count.gql'),\n      loadingKey: 'loadingKey',\n      variables() {\n        return {\n          flowId: this.flow.id,\n          heartbeat: this.heartbeat,\n          name: this.searchFormatted\n        }\n      },\n      update: data => data?.task_aggregate?.aggregate?.count\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"pa-2 mt-2\" tile>\n    <CardTitle title=\"Tasks\" icon=\"pi-task\">\n      <v-text-field\n        slot=\"action\"\n        v-model=\"searchTerm\"\n        class=\"task-search\"\n        placeholder=\"Search for a task\"\n        dense\n        solo\n        flat\n        prepend-inner-icon=\"search\"\n        hide-details\n        style=\"min-width: 400px;\"\n      >\n      </v-text-field>\n    </CardTitle>\n\n    <v-card-text>\n      <v-data-table\n        v-if=\"!loading\"\n        :footer-props=\"{\n          'items-per-page-options': [10, 15, 25, 50],\n          'prev-icon': 'chevron_left',\n          'next-icon': 'chevron_right'\n        }\"\n        class=\"truncate-table\"\n        :headers=\"headers\"\n        :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n        :items=\"tasks\"\n        :items-per-page.sync=\"itemsPerPage\"\n        :loading=\"loading\"\n        must-sort\n        :page.sync=\"page\"\n        :server-items-length=\"tasksCount\"\n        :sort-by.sync=\"sortBy\"\n        :sort-desc.sync=\"sortDesc\"\n      >\n        <template #item.name=\"{ item }\">\n          <truncate :content=\"item.name\">\n            <router-link\n              class=\"link\"\n              :data-cy=\"'task-link|' + item.name\"\n              :to=\"{ name: 'task', params: { id: item.id } }\"\n            >\n              {{ item.name }}\n            </router-link>\n          </truncate>\n        </template>\n\n        <template #item.retry_delay=\"{ item }\">\n          <span v-if=\"item.retry_delay\">{{ item.retry_delay | duration }}</span>\n          <span v-else>\n            -\n          </span>\n        </template>\n\n        <template #item.max_retries=\"{ item }\">\n          {{ item.max_retries }}\n        </template>\n\n        <template #item.type=\"{ item }\">\n          {{ item.type | typeClass }}\n        </template>\n\n        <template #item.trigger=\"{ item }\">\n          {{ item.trigger | typeClass }}\n        </template>\n      </v-data-table>\n\n      <div v-else>\n        <v-skeleton-loader type=\"table-row-divider\" />\n        <v-skeleton-loader type=\"table-row\" />\n        <v-skeleton-loader type=\"table-row\" />\n      </div>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.task-search {\n  border-radius: 0 !important;\n  font-size: 0.85rem;\n\n  .v-icon {\n    font-size: 20px !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/UpcomingRuns-Tile.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport CardTitle from '@/components/Card-Title'\nimport ClearLate from '@/components/SystemActions/ClearLate'\nimport ConcurrencyInfo from '@/components/ConcurrencyInfo'\nimport DurationSpan from '@/components/DurationSpan'\nimport LabelWarning from '@/components/LabelWarning'\nimport WorkQueue from '@/components/SystemActions/WorkQueue'\n\nimport { runFlowNowMixin } from '@/mixins/runFlowNow'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    CardTitle,\n    ClearLate,\n    ConcurrencyInfo,\n    DurationSpan,\n    LabelWarning,\n    WorkQueue\n  },\n  mixins: [runFlowNowMixin, formatTime],\n  props: {\n    aggregate: {\n      type: Boolean,\n      default: () => false\n    },\n    flow: {\n      type: Object,\n      default: () => {}\n    },\n    flowGroup: {\n      type: Object,\n      default: () => {}\n    },\n    fullHeight: {\n      required: false,\n      type: Boolean,\n      default: () => false\n    }\n  },\n  data() {\n    const tabs = {\n      upcoming: 0,\n      late: 1\n    }\n\n    return {\n      loadingKey: 0,\n      overlay: null,\n      userSetTab: false,\n      tab: tabs.upcoming,\n      tabs\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['timezone']),\n    loading() {\n      return this.loadingKey > 0\n    },\n    paused() {\n      return this.tenant?.settings?.work_queue_paused\n    },\n    lateRuns() {\n      if (!this.upcomingFlowRunsData) return null\n\n      return this.upcomingFlowRunsData.filter(run => this.runIsLate(run))\n    },\n    upcomingRuns() {\n      if (!this.upcomingFlowRunsData) return null\n\n      return this.upcomingFlowRunsData.filter(run => !this.runIsLate(run))\n    },\n    title() {\n      if (!this.upcomingFlowRunsData) return null\n\n      return this.tabProperties[this.tab].title\n    },\n    titleIcon() {\n      return this.tabProperties[this.tab].icon\n    },\n    titleIconColor() {\n      if (this.loading) return 'grey'\n\n      return this.tabProperties[this.tab].icon_color\n    },\n    systemBarColor() {\n      if (this.loading || !this.upcomingFlowRunsData) return 'secondaryGray'\n\n      return this.lateRuns?.length > 0 ? 'deepRed' : 'Success'\n    },\n    tabProperties() {\n      const upcomingCount = this.upcomingRuns?.length || 0\n      const lateCount = this.lateRuns?.length || 0\n\n      return {\n        [this.tabs.upcoming]: {\n          title: `${this.getFriendlyCount(upcomingCount)} upcoming runs`,\n          icon: 'access_time',\n          icon_color: 'primary'\n        },\n        [this.tabs.late]: {\n          title: `${this.getFriendlyCount(lateCount)} late runs`,\n          icon: 'timelapse',\n          icon_color: lateCount > 0 ? 'deepRed' : 'Success'\n        }\n      }\n    },\n    upcomingTabTitle() {\n      const upcomingCount = this.upcomingRuns?.length || 0\n\n      if (this.tab == this.tabs.upcoming || upcomingCount == 0) {\n        return 'Upcoming'\n      }\n\n      return `(${this.getFriendlyCount(upcomingCount)}) Upcoming`\n    },\n    lateTabTitle() {\n      const lateCount = this.lateRuns?.length || 0\n\n      if (this.tab == this.tabs.late || lateCount == 0) {\n        return 'Late'\n      }\n\n      return `(${this.getFriendlyCount(lateCount)}) Late`\n    }\n  },\n  watch: {\n    upcomingFlowRunsData(val) {\n      if (!val || this.userSetTab) return\n\n      if (this.tab == this.tabs.upcoming && this.lateRuns?.length > 0) {\n        this.tab = this.tabs.late\n      } else if (this.tab == this.tabs.late && this.lateRuns?.length == 0) {\n        this.tab = this.tabs.upcoming\n      }\n    },\n    ['tenant.settings.work_queue_paused'](val) {\n      if (!val) {\n        setTimeout(() => {\n          this.hideOverlay()\n        }, 1500)\n      }\n    }\n  },\n  beforeDestroy() {\n    this.upcomingFlowRunsData = []\n    this.tab = this.tabs.upcoming\n  },\n  mounted() {\n    if (this.paused) {\n      this.showOverlay('queue')\n    }\n  },\n  methods: {\n    runIsLate(run) {\n      return this.getTimeOverdue(run.scheduled_start_time) > 20000\n    },\n    getTimeOverdue(time) {\n      return new Date() - new Date(time)\n    },\n    showOverlay(kind) {\n      this.overlay = kind\n    },\n    hideOverlay() {\n      this.overlay = null\n    },\n    refetch() {\n      this.$apollo.queries.upcomingFlowRunsData.refresh()\n      this.overlay = null\n    },\n    getFriendlyCount(count) {\n      return count > 999 ? '1,000+' : count\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.upcomingFlowRunsData.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    upcomingFlowRunsData: {\n      query: require('@/graphql/Flow/upcoming-flow-runs.gql'),\n      variables() {\n        let variables = {}\n\n        if (this.aggregate) {\n          variables.flow_group_id = this.flow.flow_group_id\n        } else {\n          variables.flow_id = this.flow.id\n        }\n\n        return variables\n      },\n      loadingKey: 'loadingKey',\n      pollInterval: 10000,\n      update: data => {\n        const timestamp = new Date().getTime()\n\n        return (data?.flow_run || []).map(run => {\n          run.cacheInvalidation = timestamp\n\n          return run\n        })\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"py-2 position-relative d-flex flex-column\"\n    style=\"height: 100%;\"\n    tile\n  >\n    <v-system-bar :color=\"systemBarColor\" :height=\"5\" absolute />\n\n    <CardTitle :title=\"title\" :icon=\"titleIcon\" :icon-color=\"titleIconColor\">\n      <v-row slot=\"title\" no-gutters class=\"d-flex align-center\">\n        <v-col cols=\"10\">\n          <div>\n            <div\n              v-if=\"loading\"\n              style=\"\n                display: inline-block;\n                height: 20px;\n                overflow: hidden;\n                width: 20px;\"\n            >\n              <v-skeleton-loader type=\"avatar\" tile />\n            </div>\n            {{ title }}\n          </div>\n          <ConcurrencyInfo\n            v-if=\"isCloud && tab === tabs.late\"\n            class=\"text-caption position-absolute\"\n            style=\"bottom: 2px;\"\n          />\n        </v-col>\n      </v-row>\n    </CardTitle>\n\n    <v-card-text v-show=\"overlay\" class=\"pa-0\">\n      <v-overlay v-show=\"overlay == 'late'\" absolute z-index=\"1\">\n        <ClearLate :flow-runs=\"lateRuns\" @finish=\"refetch\" />\n      </v-overlay>\n      <v-overlay v-show=\"overlay == 'queue'\" absolute z-index=\"1\">\n        <WorkQueue />\n      </v-overlay>\n    </v-card-text>\n\n    <v-tabs\n      v-model=\"tab\"\n      tabs-border-bottom\n      :color=\"titleIconColor\"\n      class=\"flex-grow-0\"\n      @change=\"userSetTab = true\"\n    >\n      <v-tab :key=\"tabs.upcoming\" data-cy=\"upcoming-runs-tile-upcoming\">\n        {{ upcomingTabTitle }}\n      </v-tab>\n      <v-tab :key=\"tabs.late\" data-cy=\"upcoming-runs-tile-late\">\n        <v-icon\n          v-if=\"lateRuns && lateRuns.length > 0\"\n          class=\"mr-1\"\n          small\n          color=\"deepRed\"\n        >\n          warning\n        </v-icon>\n        {{ lateTabTitle }}\n      </v-tab>\n    </v-tabs>\n\n    <v-card-text class=\"px-0 py-2 card-content\">\n      <v-tabs-items v-model=\"tab\">\n        <v-tab-item>\n          <v-skeleton-loader v-if=\"loading\" type=\"list-item-three-line\" />\n\n          <v-list-item\n            v-else-if=\"upcomingRuns && upcomingRuns.length === 0\"\n            dense\n          >\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon class=\"green--text\">check</v-icon>\n            </v-list-item-avatar>\n            <v-list-item-content class=\"my-0 py-0\">\n              <div\n                class=\"text-subtitle-1 font-weight-light\"\n                style=\"line-height: 1.25rem;\"\n              >\n                No upcoming runs.\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-virtual-scroll\n            v-else\n            :items=\"upcomingRuns\"\n            height=\"178px\"\n            item-height=\"50px\"\n          >\n            <template #default=\"{item}\">\n              <v-list-item\n                :key=\"item.id\"\n                dense\n                :disabled=\"setToRun.includes(item.id)\"\n              >\n                <v-list-item-content>\n                  <v-list-item-subtitle class=\"text-body-1 font-weight-regular\">\n                    <router-link\n                      :to=\"{ name: 'flow-run', params: { id: item.id } }\"\n                    >\n                      {{ item.name }}\n                    </router-link>\n                  </v-list-item-subtitle>\n\n                  <span class=\"text-caption mb-0 ml-n1 d-flex align-center\">\n                    <LabelWarning :flow=\"item.flow\" :flow-run=\"item\" />\n                    <span class=\"ml-1\">\n                      Scheduled for\n                      {{ formatDateTime(item.scheduled_start_time) }}\n                    </span>\n                  </span>\n                </v-list-item-content>\n\n                <v-list-item-action tile min-width=\"5\" class=\"text-body-2\">\n                  <v-tooltip top>\n                    <template #activator=\"{ on }\">\n                      <v-btn\n                        text\n                        x-small\n                        aria-label=\"Run Now\"\n                        :disabled=\"setToRun.includes(item.id)\"\n                        color=\"primary\"\n                        class=\"vertical-button\"\n                        v-on=\"on\"\n                        @click=\"runFlowNow(item.id, item.version, item.name)\"\n                      >\n                        <v-icon small dense color=\"primary\">fa-rocket</v-icon>\n                      </v-btn>\n                    </template>\n                    <span> Run {{ item.name }} now </span>\n                  </v-tooltip>\n                </v-list-item-action>\n              </v-list-item>\n            </template>\n          </v-virtual-scroll>\n        </v-tab-item>\n        <v-tab-item>\n          <v-skeleton-loader v-if=\"loading\" type=\"list-item-three-line\" />\n\n          <v-list-item v-else-if=\"lateRuns && lateRuns.length === 0\" dense>\n            <v-list-item-avatar class=\"mr-0\">\n              <v-icon class=\"green--text\">check</v-icon>\n            </v-list-item-avatar>\n            <v-list-item-content class=\"my-0 py-0\">\n              <div\n                class=\"text-subtitle-1 font-weight-light\"\n                style=\"line-height: 1.25rem;\"\n              >\n                Everything is running on schedule!\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-virtual-scroll\n            v-else\n            :items=\"lateRuns\"\n            height=\"178px\"\n            item-height=\"64px\"\n          >\n            <template #default=\"{ item }\">\n              <v-list-item :key=\"item.id\" dense two-line>\n                <v-list-item-content>\n                  <v-list-item-subtitle class=\"text-body-1 font-weight-regular\">\n                    <router-link\n                      :to=\"{ name: 'flow-run', params: { id: item.id } }\"\n                    >\n                      {{ item.name }}\n                    </router-link>\n                  </v-list-item-subtitle>\n\n                  <span class=\"text-caption mb-0 ml-n1 d-flex align-center\">\n                    <LabelWarning :flow-run=\"item\" location=\"flowPage\" />\n                    <span class=\"ml-1\">\n                      Scheduled for\n                      {{ formatDateTime(item.scheduled_start_time) }}\n                    </span>\n                  </span>\n\n                  <v-list-item-subtitle class=\"text-caption\">\n                    <DurationSpan :start-time=\"item.scheduled_start_time\" />\n                    behind schedule\n                  </v-list-item-subtitle>\n                </v-list-item-content>\n              </v-list-item>\n            </template>\n          </v-virtual-scroll>\n        </v-tab-item>\n      </v-tabs-items>\n    </v-card-text>\n\n    <v-card-actions class=\"py-0 justify-end\">\n      <v-btn\n        v-if=\"!overlay && lateRuns && lateRuns.length > 0\"\n        small\n        depressed\n        color=\"primary\"\n        text\n        style=\"z-index: 2;\"\n        @click=\"showOverlay('late')\"\n      >\n        Clear late\n      </v-btn>\n\n      <v-btn\n        v-if=\"overlay && !paused\"\n        small\n        depressed\n        plain\n        color=\"white\"\n        width=\"74\"\n        text\n        style=\"z-index: 2;\"\n        @click=\"hideOverlay\"\n      >\n        Close\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\na {\n  text-decoration: none !important;\n}\n\n.button-transition {\n  transition: border-right 150ms linear;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.card-content {\n  height: 100%;\n  max-height: calc(226px - var(--v-tabs-height));\n  overflow-y: auto;\n  position: relative;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Flow/Versions-Tile.vue",
    "content": "<script>\nimport LastTenRuns from '@/components/LastTenRuns'\nimport CardTitle from '@/components/Card-Title'\nimport { mapGetters } from 'vuex'\nimport moment from 'moment'\nimport { flowRunHistoryMixin } from '@/mixins/flowRunHistoryMixin'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nconst serverHeaders = [\n  {\n    text: '',\n    value: 'archived',\n    sortable: false,\n    width: '5%'\n  },\n  {\n    text: 'Version',\n    value: 'version',\n    width: '10%'\n  },\n  {\n    text: 'Created',\n    value: 'created',\n    width: '15%'\n  }\n]\n\nconst serverHeadersPost = [\n  {\n    text: 'Last runs',\n    value: 'flow_runs',\n    sortable: false,\n    width: '25%'\n  }\n]\n\nconst cloudHeaders = [\n  {\n    text: 'Created By',\n    value: 'created_by.username',\n    width: '15%'\n  }\n]\n\nexport default {\n  components: {\n    CardTitle,\n    LastTenRuns\n  },\n  mixins: [formatTime, flowRunHistoryMixin],\n  props: {\n    flowGroupId: {\n      required: true,\n      type: String\n    }\n  },\n  data() {\n    return {\n      itemsPerPage: 5,\n      loading: 0,\n      page: 1,\n      runsLoadingKey: 0,\n      searchTerm: null,\n      sortBy: 'version',\n      sortDesc: true,\n      tooltip: null\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['timezone']),\n    headers() {\n      return [\n        ...serverHeaders,\n        ...(this.isCloud ? cloudHeaders : []),\n        ...serverHeadersPost\n      ]\n    },\n    offset() {\n      return this.itemsPerPage * (this.page - 1)\n    },\n    runsLoading() {\n      return this.runsLoadingKey > 0\n    },\n    searchFormatted() {\n      if (!this.searchTerm) return null\n      return parseInt(this.searchTerm)\n    }\n  },\n  watch: {\n    itemsPerPage() {\n      this.$apollo.queries.versionsRuns.refetch()\n    }\n  },\n  methods: {\n    getFlow(flowId) {\n      if (!this.versions || !this.versionsRuns) return\n      return this.versionsRuns.find(flow => flow.id == flowId)\n    },\n    prepFlowRuns(flowId) {\n      if (!this.versions || !this.versionsRuns) return []\n      let flow = this.getFlow(flowId)\n      if (!flow) return []\n\n      const computedStyle = getComputedStyle(document.documentElement)\n\n      return [...flow.flow_runs].reverse().map(d => {\n        if (d.start_time && d.end_time) {\n          let end = new moment(d.end_time),\n            start = new moment(d.start_time)\n          d.duration = moment.duration(end.diff(start))\n        } else {\n          let now = new moment(),\n            start = new moment(d.start_time)\n          d.duration = moment.duration(now.diff(start))\n        }\n\n        d.color = computedStyle.getPropertyValue(`--v-${d.state}-base`)\n        d.opacity = d.start_time ? 0 : 1\n        d.flow_id = flowId\n        return d\n      })\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.versions.skip = !entry.isIntersecting\n      this.$apollo.queries.versionsCount.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    versions: {\n      query() {\n        return require('@/graphql/Flow/flow-versions.js').default(this.isCloud)\n      },\n      variables() {\n        return {\n          flow_group_id: this.flowGroupId,\n          limit: this.itemsPerPage,\n          offset: this.offset,\n          order_by: { [this.sortBy]: this.sortDesc ? 'desc' : 'asc' },\n          search: this.searchFormatted\n        }\n      },\n      loadingKey: 'loading',\n      update: data => data?.flow_group_by_pk?.flows,\n      pollInterval: 10000\n    },\n    versionsCount: {\n      query: require('@/graphql/Flow/flow-versions-count.gql'),\n      variables() {\n        return {\n          flow_group_id: this.flowGroupId,\n          search: this.searchFormatted\n        }\n      },\n      loadingKey: 'loading',\n      update: data => data?.flow_group_by_pk?.flows_aggregate?.aggregate?.count,\n      pollInterval: 10000\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2 mt-2\" tile>\n    <CardTitle title=\"Flow Versions\" icon=\"loop\">\n      <v-text-field\n        slot=\"action\"\n        v-model=\"searchTerm\"\n        class=\"search\"\n        dense\n        flat\n        solo\n        prepend-inner-icon=\"search\"\n        placeholder=\"Search by Version\"\n        hide-details\n        style=\"min-width: 400px;\"\n      >\n      </v-text-field>\n    </CardTitle>\n\n    <v-card-text class=\"pa-0\">\n      <v-data-table\n        class=\"ma-2 overflow-table\"\n        :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n        :headers=\"headers\"\n        :items=\"versions\"\n        :loading=\"loading > 0\"\n        must-sort\n        :page.sync=\"page\"\n        :server-items-length=\"versionsCount\"\n        :sort-by.sync=\"sortBy\"\n        :sort-desc.sync=\"sortDesc\"\n        :items-per-page.sync=\"itemsPerPage\"\n        :footer-props=\"{\n          showFirstLastPage: true,\n          itemsPerPageOptions: [10, 15, 20],\n          firstIcon: 'first_page',\n          lastIcon: 'last_page',\n          prevIcon: 'keyboard_arrow_left',\n          nextIcon: 'keyboard_arrow_right'\n        }\"\n        :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n        calculate-widths\n      >\n        <template #item.version=\"{ item }\">\n          <truncate :content=\"item.version\">\n            <router-link\n              class=\"link\"\n              :to=\"{\n                name: 'flow',\n                params: { id: flowGroupId, tenant: tenant.slug },\n                query: { version: item.version }\n              }\"\n            >\n              {{ item.version }}\n            </router-link>\n          </truncate>\n        </template>\n\n        <template #item.created=\"{ item }\">\n          <truncate :content=\"formatTime(item.created)\">\n            {{ formDate(item.created) }}\n          </truncate>\n        </template>\n\n        <template #item.archived=\"{ item }\">\n          <truncate :content=\"item.archived ? 'Archived' : 'Active'\">\n            <v-icon small dark :color=\"item.archived ? 'accentPink' : 'green'\">\n              {{ item.archived ? 'archive' : 'pi-flow' }}\n            </v-icon>\n          </truncate>\n        </template>\n\n        <template #item.flow_runs=\"{ item }\">\n          <div class=\"position-relative allow-overflow\" style=\"height: 55px;\">\n            <LastTenRuns :flow-id=\"item.id\" :archived=\"item.archived\" />\n          </div>\n        </template>\n      </v-data-table>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.search {\n  border-radius: 0 !important;\n  font-size: 0.85rem;\n\n  .v-icon {\n    font-size: 20px !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/FlowRun/Actions.vue",
    "content": "<script>\nimport { mapGetters, mapActions } from 'vuex'\nimport { FINISHED_STATES } from '@/utils/states'\n\n// We're removing this until the stack functionality\n// is in a more tenable place.\nimport CancelButton from '@/components/CancelButton.vue'\nimport SetStateDialog from '@/components/SetStateDialog.vue'\nimport RestartDialog from '@/pages/FlowRun/Restart-Dialog'\n\nexport default {\n  components: { CancelButton, RestartDialog, SetStateDialog },\n  props: {\n    flowRun: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      runFlowNowClicked: false,\n      runFlowNowLoading: false,\n\n      // Alert\n      alertMessage: '',\n      alertType: 'info',\n\n      //restart\n      eligibleStates: ['Failed', 'Cancelled'],\n      eligibleTaskRunStates: [\n        'Cancelled',\n        'Failed',\n        'TimedOut',\n        'TriggerFailed'\n      ],\n      restartDialog: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('license', ['hasPermission']),\n    isScheduled() {\n      return this.flowRun?.state === 'Scheduled'\n    },\n    isFinished() {\n      return FINISHED_STATES.includes(this.flowRun.state)\n    },\n    canRestart() {\n      return (\n        this.failedTaskRuns?.length > 0 ||\n        this.eligibleStates.includes(this.flowRun.state)\n      )\n    },\n    isLateRun() {\n      return new Date() - new Date(this.flowRun.scheduled_start_time) > 20000\n    }\n  },\n  watch: {\n    flowRun(newVal, oldVal) {\n      if (oldVal.state === 'Scheduled' && newVal.state !== 'Scheduled') {\n        this.isRunningNow = false\n      }\n      if (\n        newVal.state !== oldVal.state &&\n        FINISHED_STATES.includes(newVal.state)\n      ) {\n        this.$apollo.queries.failedTaskRuns.refetch()\n      }\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    deleteFlowRun() {},\n    handleRestartClick() {\n      this.$apollo.queries.failedTaskRuns.refetch()\n      this.restartDialog = true\n    },\n    async runFlowNow() {\n      this.runFlowNowLoading = true\n\n      try {\n        this.runFlowNowClicked = true\n        // Set the flow in a Scheduled state (even if it's already Scheduled).\n        // This causes the flow run to execute immediately.\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/TaskRun/set-flow-run-states.gql'),\n          variables: {\n            flowRunId: this.flowRun.id,\n            version: this.flowRun.version,\n            state: {\n              type: 'Scheduled'\n            }\n          }\n        })\n\n        this.alertMessage =\n          'Your flow run has been scheduled to start immediately.'\n        this.alertType = 'success'\n      } catch (error) {\n        this.alertMessage =\n          'Something went wrong while trying to run this flow. Please try again later.'\n        this.alertType = 'error'\n        this.runFlowNowClicked = false\n        throw error\n      }\n\n      this.runFlowNowLoading = false\n\n      this.setAlert({\n        alertShow: true,\n        alertMessage: this.alertMessage,\n        alertType: this.alertType\n      })\n    }\n  },\n  apollo: {\n    failedTaskRuns: {\n      query: require('@/graphql/FlowRun/failed-task-runs.gql'),\n      variables() {\n        return {\n          flowRunId: this.flowRun.id,\n          failedStates: this.eligibleTaskRunStates\n        }\n      },\n      update: data => data?.task_run\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"pa-0 mb-2 d-flex align-center\"\n    :class=\"[\n      $vuetify.breakpoint.xsOnly ? 'justify-center' : 'justify-end',\n      $vuetify.breakpoint.xsOnly && 'mx-auto'\n    ]\"\n  >\n    <v-tooltip v-if=\"isScheduled\" bottom>\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <v-btn\n            class=\"vertical-button\"\n            style=\"height: 46px;\"\n            color=\"primary\"\n            text\n            depressed\n            :loading=\"runFlowNowLoading\"\n            :disabled=\"\n              isLateRun ||\n                runFlowNowLoading ||\n                runFlowNowClicked ||\n                !hasPermission('create', 'run')\n            \"\n            small\n            @click=\"runFlowNow\"\n          >\n            <v-icon>fa-rocket</v-icon>\n            <div>Start Now</div>\n          </v-btn>\n        </div>\n      </template>\n      <span v-if=\"!hasPermission('update', 'run')\">\n        You don't have permission to restart flow runs\n      </span>\n      <span v-else-if=\"runFlowNowClicked\">\n        This flow run has been scheduled to start as soon as possible.\n      </span>\n      <span v-else-if=\"isLateRun\">\n        Flow run already scheduled to start.\n      </span>\n      <span v-else>\n        Start this flow run immediately\n      </span>\n    </v-tooltip>\n\n    <v-tooltip max-width=\"250px\" bottom>\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <v-btn\n            class=\"vertical-button\"\n            text\n            depressed\n            style=\"height: 46px;\"\n            small\n            :disabled=\"\n              !hasPermission('update', 'run') || !canRestart || restartDialog\n            \"\n            color=\"info\"\n            @click=\"handleRestartClick\"\n          >\n            <v-icon>fab fa-rev</v-icon>\n            <div>Restart</div>\n          </v-btn>\n        </div>\n      </template>\n      <span v-if=\"!hasPermission('update', 'run')\">\n        You don't have permission to restart flow runs\n      </span>\n      <span v-else-if=\"!canRestart\"\n        >You can only restart flow runs from a failed or cancelled state.\n        <span v-if=\"isFinished\"\n          >If you wish to run this flow run again, you can set it (and its task\n          runs) into a scheduled state.</span\n        >\n      </span>\n      <span v-else>Restart run from {{ flowRun.state }} </span>\n    </v-tooltip>\n\n    <v-dialog v-model=\"restartDialog\" width=\"500\">\n      <RestartDialog\n        :flow-run=\"flowRun\"\n        :failed-task-runs=\"failedTaskRuns\"\n        :eligible-states=\"eligibleStates\"\n        @cancel=\"restartDialog = false\"\n        @update=\"$emit('update')\"\n      />\n    </v-dialog>\n\n    <SetStateDialog\n      dialog-type=\"flow run\"\n      :flow-run=\"flowRun\"\n      @update=\"$emit('update')\"\n    />\n\n    <CancelButton\n      dialog-type=\"flow run\"\n      :flow-run=\"flowRun\"\n      @update=\"$emit('update')\"\n    />\n\n    <v-tooltip bottom>\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <v-btn\n            v-if=\"\n              tenant.prefectAdminSettings &&\n                tenant.prefectAdminSettings.deleteFlow\n            \"\n            class=\"vertical-button py-1\"\n            text\n            tile\n            disabled\n            small\n            color=\"red\"\n            @click=\"deleteFlowRun\"\n          >\n            <v-icon>delete</v-icon>\n            <div class=\"mb-1\">Delete</div>\n          </v-btn>\n        </div>\n      </template>\n      <span v-if=\"!hasPermission('delete', 'run')\">\n        You don't have permission to delete flows\n      </span>\n      <span v-else>Coming Soon!</span>\n    </v-tooltip>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/FlowRun/Details-Tile.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport jsBeautify from 'js-beautify'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport CardTitle from '@/components/Card-Title'\nimport DurationSpan from '@/components/DurationSpan'\nimport LabelEdit from '@/components/LabelEdit'\nimport { FINISHED_STATES } from '@/utils/states'\n\nexport default {\n  components: {\n    CardTitle,\n    DurationSpan,\n    LabelEdit\n  },\n  mixins: [formatTime],\n  props: {\n    flowRun: {\n      type: Object,\n      default: () => {}\n    }\n  },\n  data() {\n    const tabs = {\n      overview: 'overview',\n      parameters: 'parameters',\n      context: 'context',\n      run_config: 'run_config'\n    }\n\n    return {\n      tab: tabs.overview,\n      tabs\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('api', ['isCloud']),\n    hasContext() {\n      return (\n        this.flowRun.context && Object.keys(this.flowRun.context).length > 0\n      )\n    },\n    isFinished() {\n      return FINISHED_STATES.includes(this.flowRun.state)\n    },\n    hasParameters() {\n      if (!this.flowRun?.parameters && !this.flowRun?.flow?.parameters)\n        return false\n      return (\n        Object.keys(this.flowRun.parameters).length > 0 ||\n        this.flowRun.flow.parameters.length > 0\n      )\n    },\n    hasRunConfig() {\n      return (\n        this.flowRun?.run_config &&\n        Object.keys(this.flowRun.run_config).length > 0\n      )\n    },\n    flowRunParams() {\n      const flowParams = this.flowRun?.flow?.parameters.reduce(\n        (accum, currentParam) => {\n          accum[currentParam.name] = currentParam.default\n          return accum\n        },\n        {}\n      )\n      return { ...flowParams, ...this.flowRun?.parameters }\n    },\n    isCloudOrAutoScheduled() {\n      return this.isCloud || this.flowRun?.auto_scheduled\n    }\n  },\n  methods: {\n    formatJson(obj) {\n      return jsBeautify(JSON.stringify(obj), {\n        indent_size: 2,\n        space_in_empty_paren: true,\n        preserve_newlines: false\n      })\n    },\n    handleRefetch() {\n      this.$emit('refetch')\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"py-2\" tile>\n    <v-system-bar\n      :color=\"flowRun.state\"\n      :data-cy=\"'details-tile-flow-run-state|' + flowRun.state.toLowerCase()\"\n      :height=\"5\"\n      absolute\n    >\n      <!-- We should include a state icon here when we've got those -->\n      <!-- <v-icon>{{ flowRun.state }}</v-icon> -->\n    </v-system-bar>\n\n    <CardTitle :title=\"flowRun.name\" icon=\"pi-flow-run\" />\n\n    <v-tabs\n      v-if=\"hasParameters || hasContext || hasRunConfig\"\n      v-model=\"tab\"\n      tabs-border-bottom\n      center-active\n      color=\"primary\"\n      class=\"flex-grow-0\"\n    >\n      <v-tab :href=\"`#${tabs.overview}`\" data-cy=\"details-tile-overview\">\n        Overview\n      </v-tab>\n      <template v-if=\"hasParameters\">\n        <v-tab :href=\"`#${tabs.parameters}`\" data-cy=\"details-tile-parameters\">\n          Parameters\n        </v-tab>\n      </template>\n      <template v-if=\"hasContext\">\n        <v-tab :href=\"`#${tabs.context}`\" data-cy=\"details-tile-parameters\">\n          Context\n        </v-tab>\n      </template>\n      <template v-if=\"hasRunConfig\">\n        <v-tab :href=\"`#${tabs.run_config}`\" data-cy=\"details-tile-parameters\">\n          Run Config\n        </v-tab>\n      </template>\n    </v-tabs>\n\n    <v-tabs-items v-model=\"tab\" class=\"flex-grow-1\">\n      <v-tab-item :value=\"tabs.overview\">\n        <v-list>\n          <v-list-item v-if=\"isCloudOrAutoScheduled\">\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"text-caption\">\n                Created by\n              </v-list-item-subtitle>\n              <div class=\"text-subtitle-2\">\n                {{\n                  flowRun.auto_scheduled\n                    ? 'The Prefect Scheduler'\n                    : flowRun.created_by\n                    ? flowRun.created_by.username\n                    : 'A nonexistant user'\n                }}\n              </div>\n            </v-list-item-content>\n          </v-list-item>\n          <LabelEdit\n            type=\"flowRun\"\n            :flow-run=\"flowRun\"\n            @refetch=\"handleRefetch\"\n          />\n          <v-list-item v-if=\"flowRun.state_message\" dense>\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"text-caption\">\n                Last State Message\n              </v-list-item-subtitle>\n\n              <truncate :content=\"flowRun.state_message\">\n                [{{ formatTime(flowRun.state_timestamp) }}]:\n                {{ flowRun.state_message }}\n              </truncate>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-list-item v-if=\"flowRun.agent_id\" dense>\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"text-caption\">\n                Agent ID\n              </v-list-item-subtitle>\n              <router-link\n                class=\"link\"\n                :to=\"{\n                  name: 'agent',\n                  params: { tenant: tenant.slug, id: flowRun.agent_id }\n                }\"\n              >\n                {{ flowRun.agent_id }}\n              </router-link>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-list-item dense>\n            <v-list-item-content>\n              <v-list-item-subtitle class=\"text-caption\">\n                <v-row no-gutters>\n                  <v-col cols=\"6\"> {{ flowRun.flow.name }} version </v-col>\n                  <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                    <router-link\n                      class=\"link\"\n                      :to=\"{\n                        name: 'flow',\n                        params: { id: flowRun.flow.id }\n                      }\"\n                    >\n                      {{ flowRun.flow.version }}\n                    </router-link>\n                  </v-col>\n                </v-row>\n\n                <v-row no-gutters>\n                  <v-col v-if=\"flowRun.start_time\" cols=\"6\">\n                    Scheduled Start Time\n                  </v-col>\n                  <v-col\n                    v-if=\"flowRun.start_time\"\n                    cols=\"6\"\n                    class=\"text-right font-weight-bold\"\n                  >\n                    <v-tooltip top>\n                      <template #activator=\"{ on }\">\n                        <span v-on=\"on\">\n                          {{ formatTime(flowRun.scheduled_start_time) }}\n                        </span>\n                      </template>\n                      <div>\n                        {{ formatDateTime(flowRun.scheduled_start_time) }}\n                      </div>\n                    </v-tooltip>\n                  </v-col>\n                  <v-col cols=\"6\">\n                    {{ flowRun.start_time ? 'Started' : 'Scheduled to start' }}\n                  </v-col>\n                  <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                    <v-tooltip top>\n                      <template #activator=\"{ on }\">\n                        <span v-on=\"on\">\n                          {{\n                            flowRun.start_time\n                              ? formatTime(flowRun.start_time)\n                              : formatTime(flowRun.scheduled_start_time)\n                          }}\n                        </span>\n                      </template>\n                      <div>\n                        {{\n                          flowRun.start_time\n                            ? formatDateTime(flowRun.start_time)\n                            : formatDateTime(flowRun.scheduled_start_time)\n                        }}\n                      </div>\n                    </v-tooltip>\n                  </v-col>\n                </v-row>\n                <v-row v-if=\"flowRun.end_time\" no-gutters>\n                  <v-col cols=\"6\"> Ended </v-col>\n                  <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                    <v-tooltip top>\n                      <template #activator=\"{ on }\">\n                        <span v-on=\"on\">\n                          {{ formatTime(flowRun.end_time) }}\n                        </span>\n                      </template>\n                      <div>\n                        {{ formatDateTime(flowRun.end_time) }}\n                      </div>\n                    </v-tooltip>\n                  </v-col>\n                </v-row>\n                <v-row v-if=\"flowRun.start_time\" no-gutters>\n                  <v-col cols=\"6\"> Duration </v-col>\n                  <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                    <!-- Check for isFinished improves duration handling for restarted flows  -->\n                    <DurationSpan\n                      v-if=\"flowRun.start_time\"\n                      :start-time=\"flowRun.start_time\"\n                      :end-time=\"\n                        isFinished && flowRun.start_time\n                          ? flowRun.end_time\n                          : null\n                      \"\n                    />\n                    <span v-else>\n                      <v-skeleton-loader type=\"text\"></v-skeleton-loader>\n                    </span>\n                  </v-col>\n                </v-row>\n              </v-list-item-subtitle>\n            </v-list-item-content>\n          </v-list-item>\n        </v-list>\n      </v-tab-item>\n      <v-tab-item :value=\"tabs.parameters\">\n        <div class=\"text-body-2 appForeground rounded-sm pa-5 code-block\">\n          {{ formatJson(flowRunParams) }}\n        </div>\n      </v-tab-item>\n      <v-tab-item :value=\"tabs.context\">\n        <div class=\"text-body-2 appForeground rounded-sm pa-5 code-block\">\n          {{ formatJson(flowRun.context) }}\n        </div>\n      </v-tab-item>\n      <v-tab-item :value=\"tabs.run_config\">\n        <div class=\"text-body-2 appForeground rounded-sm pa-5 code-block\">\n          {{ formatJson(flowRun.run_config) }}\n        </div>\n      </v-tab-item>\n    </v-tabs-items>\n  </v-card>\n</template>\n\n<style lang=\"scss\">\n.code-block {\n  border: 1px solid var(--v-utilGrayLight-base) !important;\n  font-family: 'Source Code Pro', monospace !important;\n  white-space: pre-wrap;\n}\n\n.w-100 {\n  width: 100% !important;\n}\n\n.v-slide-group__prev,\n.v-slide-group__next {\n  display: none !important;\n}\n</style>\n"
  },
  {
    "path": "src/pages/FlowRun/FlowRun.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\n\nimport Actions from '@/pages/FlowRun/Actions'\nimport Artifacts from '@/components/Artifacts/Artifacts'\nimport BreadCrumbs from '@/components/BreadCrumbs'\nimport NavTabBar from '@/components/NavTabBar'\nimport DetailsTile from '@/pages/FlowRun/Details-Tile'\nimport EditableTextField from '@/components/EditableTextField'\nimport TimelineTile from '@/pages/FlowRun/Timeline-Tile'\nimport LogsCard from '@/components/LogsCard/LogsCard'\nimport SchematicTile from '@/pages/FlowRun/Schematic-Tile'\nimport SubPageNav from '@/layouts/SubPageNav'\nimport TaskRunHeartbeatTile from '@/pages/FlowRun/TaskRunHeartbeat-Tile'\nimport TaskRunTableTile from '@/pages/FlowRun/TaskRunTable-Tile'\nimport TileLayout from '@/layouts/TileLayout'\nimport TileLayoutFull from '@/layouts/TileLayout-Full'\nimport { parser } from '@/utils/markdownParser'\nimport { FINISHED_STATES } from '@/utils/states'\n\nexport default {\n  metaInfo() {\n    return {\n      title: this.flowRun\n        ? `Run | ${this.flowRun.flow?.name} - ${this.flowRun.name}`\n        : null,\n      link: [\n        {\n          rel: 'icon',\n          type: 'image/svg',\n          href: this.flowRun\n            ? `/state-icons/${this.flowRun.state.toLowerCase()}.svg`\n            : null,\n          vmid: 'favicon'\n        }\n      ]\n    }\n  },\n  components: {\n    Actions,\n    Artifacts,\n    BreadCrumbs,\n    DetailsTile,\n    EditableTextField,\n    TimelineTile,\n    LogsCard,\n    NavTabBar,\n    SchematicTile,\n    SubPageNav,\n    TaskRunHeartbeatTile,\n    TaskRunTableTile,\n    TileLayout,\n    TileLayoutFull\n  },\n  data() {\n    return {\n      error: false,\n      flowRunNameLoading: false,\n      loadingKey: 0,\n      tabs: [\n        {\n          name: 'Overview',\n          target: 'overview',\n          icon: 'view_quilt'\n        },\n        {\n          name: 'Schematic',\n          target: 'schematic',\n          icon: 'pi-schematic'\n        },\n        {\n          name: 'Logs',\n          target: 'logs',\n          icon: 'format_align_left'\n        },\n        {\n          name: 'Artifacts',\n          target: 'artifacts',\n          icon: 'fas fa-fingerprint'\n        }\n      ]\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('api', ['isCloud']),\n    flowId() {\n      return this.flowRun?.flow_id\n    },\n    flowRunId() {\n      return this.$route.params.id\n    },\n    loading() {\n      return this.loadingKey > 0\n    },\n    flowRunNameLength() {\n      return this.flowRun?.name?.length\n    },\n    titleBarMaxWidth() {\n      if (this.$vuetify.breakpoint.lgAndUp) {\n        return '70vw'\n      } else if (this.$vuetify.breakpoint.mdAndDown) {\n        return '40vw'\n      }\n      return '30vw'\n    },\n    tab: {\n      get() {\n        const keys = Object.keys(this.$route.query ?? {})\n        if (keys.length > 0 && this.tabs?.find(tab => tab.target == keys[0])) {\n          return keys[0]\n        }\n\n        return 'overview'\n      },\n      set(value) {\n        this.$router.replace({ query: { [value]: null } })\n      }\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    parseMarkdown(md) {\n      return parser(md)\n    },\n    async saveFlowRunName(e) {\n      const previousName = this.flowRun.name\n      if (previousName === e) return\n\n      try {\n        this.flowRunNameLoading = true\n\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/set-flow-run-name.gql'),\n          variables: {\n            input: {\n              flow_run_id: this.flowRunId,\n              name: e\n            }\n          }\n        })\n\n        await this.$apollo.queries.flowRun.refetch()\n\n        if (!data.set_flow_run_name.success) {\n          throw new Error(data.set_flow_run_name.error)\n        }\n\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `<span class=\"font-weight-medium\">${previousName}</span> has been renamed to <span class=\"font-weight-medium\">${e}</span>`,\n          alertType: 'success'\n        })\n      } catch {\n        this.setAlert({\n          alertShow: true,\n          alertMessage:\n            'Oops! Something went wrong while trying to update your flow run name, please try again.',\n          alertType: 'error'\n        })\n      } finally {\n        this.flowRunNameLoading = false\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRun.skip = !entry.isIntersecting\n    },\n    handleRefetch() {\n      this.$apollo.queries.flowRun.refetch()\n    }\n  },\n  apollo: {\n    flowRun: {\n      query() {\n        return require('@/graphql/FlowRun/flow-run.js').default(this.isCloud)\n      },\n      variables() {\n        return {\n          id: this.flowRunId\n        }\n      },\n      loadingKey: 'loadingKey',\n      error(error) {\n        if (error.toString().includes('invalid input')) {\n          this.error = true\n        }\n      },\n      pollInterval: 5000,\n      update(data) {\n        if (!data) return\n\n        const flowRun = data.flow_run_by_pk\n        if (\n          FINISHED_STATES.includes(flowRun.state) &&\n          flowRun.state !== 'Scheduled'\n        ) {\n          this.$apollo.queries.flowRun.stopPolling()\n\n          this.$apollo.queries.flowRun.startPolling(60000)\n        }\n        return flowRun\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet\n    v-if=\"error && !flowRun\"\n    v-intersect=\"{ handler: onIntersect }\"\n    color=\"appBackground\"\n    class=\"position-relative\"\n  >\n    <div\n      class=\"text-center position-absolute center-absolute text-h4 grey--text text--darken-2\"\n      style=\"z-index: 1;\"\n    >\n      Sorry, we weren't able to find this run.\n    </div>\n  </v-sheet>\n  <v-sheet v-else-if=\"flowRun\" color=\"appBackground\">\n    <SubPageNav icon=\"pi-flow-run\" page-type=\"Flow Run\">\n      <span\n        slot=\"page-title\"\n        class=\"minTitleWidth\"\n        :style=\"{\n          display: $vuetify.breakpoint.smAndDown ? 'inline' : 'block',\n          width: flowRunNameLength + 'ch',\n          maxWidth: titleBarMaxWidth\n        }\"\n      >\n        <EditableTextField\n          :content=\"flowRun.name\"\n          label=\"Flow run name\"\n          :loading=\"flowRunNameLoading\"\n          required\n          @change=\"saveFlowRunName\"\n        />\n      </span>\n\n      <span\n        slot=\"breadcrumbs\"\n        :style=\"\n          $vuetify.breakpoint.smAndDown && {\n            display: 'inline',\n            'font-size': '0.875rem'\n          }\n        \"\n      >\n        <BreadCrumbs\n          :crumbs=\"[\n            {\n              route: {\n                name: 'project',\n                params: { id: flowRun.flow.project.id }\n              },\n              text: flowRun.flow.project.name\n            },\n            {\n              route: {\n                name: 'flow',\n                params: { id: flowRun.flow.flow_group_id }\n              },\n              text: flowRun.flow.name\n            },\n            {\n              route: {\n                name: 'flow',\n                params: { id: flowRun.flow.id }\n              },\n              text:\n                flowRun.flow.version == flowRun.version\n                  ? `Version ${flowRun.flow.version} (Current)`\n                  : `Version ${flowRun.flow.version}`\n            }\n          ]\"\n        />\n      </span>\n\n      <Actions\n        slot=\"page-actions\"\n        style=\"height: 55px;\"\n        :flow-run=\"flowRun\"\n        @update=\"$apollo.queries['flowRun'].refetch()\"\n      />\n      <span slot=\"tabs\" style=\"width: 100%;\">\n        <NavTabBar :tabs=\"tabs\" page=\"flow-run\" />\n      </span>\n    </SubPageNav>\n\n    <v-tabs-items\n      v-model=\"tab\"\n      class=\"px-6 mx-auto tabs-border-bottom tab-full-height\"\n      :style=\"{\n        'padding-top': $vuetify.breakpoint.smOnly ? '80px' : '130px'\n      }\"\n      mandatory\n    >\n      <v-tab-item\n        class=\"pa-0\"\n        value=\"overview\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayout>\n          <TimelineTile\n            v-if=\"flowId\"\n            slot=\"row-0\"\n            :flow-id=\"flowId\"\n            :flow-run-id=\"flowRunId\"\n            :flow-run-end-time=\"flowRun.end_time\"\n            :flow-run-scheduled-start-time=\"flowRun.scheduled_start_time\"\n            :flow-run-start-time=\"flowRun.start_time\"\n            :flow-run-state=\"flowRun.state\"\n            :flow-run-states=\"flowRun.states\"\n          />\n\n          <DetailsTile\n            slot=\"row-2-col-1-row-1-tile-1\"\n            :flow-run=\"flowRun\"\n            @refetch=\"handleRefetch\"\n          />\n\n          <TaskRunHeartbeatTile\n            slot=\"row-2-col-1-row-2-tile-1\"\n            :flow-run-id=\"$route.params.id\"\n          />\n\n          <TaskRunTableTile\n            slot=\"row-2-col-2-row-3-tile-1\"\n            :flow-run-id=\"flowRun.id\"\n          />\n        </TileLayout>\n      </v-tab-item>\n\n      <v-tab-item\n        value=\"schematic\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <SchematicTile slot=\"row-2-tile\" />\n        </TileLayoutFull>\n      </v-tab-item>\n\n      <v-tab-item\n        class=\"tab-full-height\"\n        value=\"logs\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <LogsCard\n            slot=\"row-2-tile\"\n            class=\"py-2 mt-4\"\n            entity=\"flow\"\n            :query=\"require('@/graphql/Logs/flow-run-logs.gql')\"\n            :query-for-scoping=\"\n              require('@/graphql/Logs/flow-run-logs-scoping.gql')\n            \"\n            query-key=\"flow_run_by_pk\"\n            :variables=\"{ id: $route.params.id }\"\n          />\n        </TileLayoutFull>\n      </v-tab-item>\n\n      <v-tab-item\n        class=\"tab-full-height\"\n        value=\"artifacts\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <Artifacts :flow-run-id=\"flowRunId\" />\n      </v-tab-item>\n    </v-tabs-items>\n\n    <v-bottom-navigation v-if=\"$vuetify.breakpoint.smAndDown\" app fixed>\n      <v-btn @click=\"tab = 'overview'\">\n        Overview\n        <v-icon>view_quilt</v-icon>\n      </v-btn>\n\n      <v-btn @click=\"tab = 'schematic'\">\n        Schematic\n        <v-icon>pi-schematic</v-icon>\n      </v-btn>\n\n      <v-btn @click=\"tab = 'logs'\">\n        Logs\n        <v-icon>format_align_left</v-icon>\n      </v-btn>\n\n      <v-btn @click=\"tab = 'artifacts'\">\n        Artifacts\n        <v-icon>fas fa-fingerprint</v-icon>\n      </v-btn>\n    </v-bottom-navigation>\n  </v-sheet>\n</template>\n\n<style lang=\"scss\" scoped>\n.center-absolute {\n  left: 50%;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n</style>\n\n<style lang=\"scss\">\n/* stylelint-disable */\n.v-tab--disabled .v-badge__badge {\n  pointer-events: none;\n}\n\n.v-badge--inline .v-badge__badge,\n.v-badge--inline .v-badge__wrapper {\n  margin: 5px;\n}\n\n.minTitleWidth {\n  min-width: 20vw;\n}\n</style>\n"
  },
  {
    "path": "src/pages/FlowRun/Restart-Dialog.vue",
    "content": "<script>\nimport { mapGetters, mapActions } from 'vuex'\n\nexport default {\n  props: {\n    flowRun: {\n      required: true,\n      type: Object\n    },\n    eligibleStates: {\n      required: true,\n      type: Array\n    },\n    failedTaskRuns: {\n      required: true,\n      type: Array\n    }\n  },\n  data() {\n    return {\n      error: false,\n      loading: false,\n      loadingKey: 0,\n      errorMessage:\n        'Sorry, we hit a problem trying to restart the run; please try again.'\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('user', ['user']),\n    restartMessage() {\n      return `${this.user.username} restarted this flow run`\n    },\n    queryLoading() {\n      return this.loadingKey > 0\n    },\n    isEligibleToRestart() {\n      return (\n        this.hasFailedTaskRuns ||\n        this.eligibleStates.includes(this.flowRun.state)\n      )\n    },\n    hasFailedTaskRuns() {\n      return this.failedTaskRuns?.length > 0\n    },\n    reRunStates() {\n      const reRunStates = this.eligibleStates.slice()\n      reRunStates.splice(this.eligibleStates.length - 1, 0, '&')\n      return reRunStates.join(' ')\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    cancel() {\n      this.$emit('cancel')\n    },\n    async restart() {\n      try {\n        this.loading = true\n\n        this.writeLogs()\n\n        // we want to avoid resetting the parent Mapped state of a mapped pipeline,\n        // as that would cause *all* children to rerun, regardless of whether they failed.\n        // So, first we collect all candidate run states and then filter:\n        // if map_index is null, we can proceed normally - if not null, we explicitly\n        // check whether it's one of the failed states\n        let failedRunIds = this.failedTaskRuns.map(run => run.id)\n\n        const taskRunStates = this.utilityDownstreamTasks\n          .map(task =>\n            task.task.task_runs.map(run => {\n              const noIndex = !run.map_index && run.map_index != 0\n              if (noIndex || failedRunIds.includes(run.id)) {\n                return {\n                  version: run.version,\n                  task_run_id: run.id,\n                  state: { type: 'Pending', message: this.restartMessage }\n                }\n              }\n            })\n          )\n          .flat()\n          // the above flat map doesn't always return objects\n          // but can return something like [undefined, {...}, undefined]\n          // so we filter falsey values here\n          .filter(x => !!x)\n\n        let result\n        if (taskRunStates?.length > 0) {\n          result = await this.$apollo.mutate({\n            mutation: require('@/graphql/TaskRun/set-task-run-states.gql'),\n            variables: {\n              input: taskRunStates\n            }\n          })\n        }\n\n        if (\n          result?.data?.set_task_run_states ||\n          this.eligibleStates.includes(this.flowRun.state)\n        ) {\n          const { data } = await this.$apollo.mutate({\n            mutation: require('@/graphql/TaskRun/set-flow-run-states.gql'),\n            variables: {\n              flowRunId: this.flowRun.id,\n              version: this.flowRun.version,\n              state: { type: 'Scheduled', message: this.restartMessage }\n            }\n          })\n\n          if (data?.set_flow_run_states) {\n            this.loading = false\n            this.cancel()\n            this.$emit('update')\n            this.setAlert({\n              alertShow: true,\n              alertMessage: 'Flow run restarted.',\n              alertType: 'success'\n            })\n          } else {\n            this.error = true\n            this.errorMessage = 'There was an error with the API call'\n          }\n        } else {\n          this.error = true\n          this.errorMessage = 'No eligible states to reset'\n        }\n      } catch (error) {\n        this.error = true\n        this.errorMessage = `${error}`\n        throw error\n      } finally {\n        if (this.error === true) {\n          this.cancel()\n          this.setAlert({\n            alertShow: true,\n            alertMessage: this.errorMessage,\n            alertType: 'error'\n          })\n        }\n        this.loading = false\n      }\n    },\n    async writeLogs() {\n      const { data } = await this.$apollo.mutate({\n        mutation: require('@/graphql/Update/write-run-logs.gql'),\n        variables: {\n          flowRunId: this.flowRun.id,\n          name: this.name,\n          message: this.restartMessage\n        }\n      })\n      return data?.write_run_logs?.success\n    }\n  },\n  apollo: {\n    utilityDownstreamTasks: {\n      query: require('@/graphql/TaskRun/utility_downstream_tasks.gql'),\n      variables() {\n        return {\n          // the start_task_ids argument requires a postgres literal,\n          // which is why these are interpolated between {} brackets\n          taskIds: `{${this.failedTaskRuns\n            .map(task => task.task_id)\n            .join(',')}}`,\n          flowRunId: this.flowRun.id\n        }\n      },\n      loadingKey: 'loadingKey',\n      skip() {\n        return !this.failedTaskRuns\n      },\n      update: data => data.utility_downstream_tasks\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card tile :loading=\"queryLoading\">\n    <v-card-title> Restart? </v-card-title>\n\n    <v-card-text v-if=\"utilityDownstreamTasks\">\n      Click on confirm to restart this flow run. Restarting will restart all\n      task runs in {{ reRunStates }} states and run any task runs in a Pending\n      state. Task runs that rely on upstream results may require additional\n      configuration to restart correctly. Read more about that\n      <a\n        href=\"https://docs.prefect.io/core/concepts/results.html#results\"\n        target=\"_blank\"\n        >in the Results docs</a\n      >.\n    </v-card-text>\n    <v-card-text v-else>\n      Fetching downstream tasks...\n    </v-card-text>\n    <v-card-actions v-if=\"utilityDownstreamTasks\">\n      <v-spacer></v-spacer>\n\n      <v-btn\n        :disabled=\"!isEligibleToRestart || loading\"\n        color=\"primary\"\n        :loading=\"loading\"\n        @click=\"restart\"\n      >\n        Confirm\n      </v-btn>\n\n      <v-btn text @click=\"cancel\">\n        Cancel\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n"
  },
  {
    "path": "src/pages/FlowRun/Schematic-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport DurationSpan from '@/components/DurationSpan'\nimport SchematicFlow from '@/components/Schematics/Schematic-Flow'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  filters: {\n    typeClass: val => val.split('.').pop()\n  },\n  components: {\n    CardTitle,\n    DurationSpan,\n    SchematicFlow\n  },\n  data() {\n    return {\n      expanded: true,\n      showCards: true,\n      tasks: []\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone'])\n  },\n  watch: {},\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRun.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRun: {\n      query: require('@/graphql/Schematics/flow-run.gql'),\n      variables() {\n        return {\n          id: this.$route.params.id\n        }\n      },\n      skip() {\n        return !this.$route.params.id\n      },\n      update(data) {\n        if (data?.flow_run_by_pk) {\n          this.tasks = data.flow_run_by_pk.task_runs.map(tr => {\n            return {\n              ...tr,\n              flow_run_name: data.flow_run_by_pk.name,\n              task_run_id: tr.id\n            }\n          })\n          return data.flow_run_by_pk\n        } else {\n          this.tasks = []\n        }\n      },\n      pollInterval: 3000\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2 mt-2\" tile>\n    <CardTitle title=\"Flow Run Schematic\" icon=\"pi-schematic\">\n      <div v-if=\"flowRun\" slot=\"badge\" class=\"text-body-2\">\n        <span>\n          Run State:\n          <span\n            class=\"font-weight-bold\"\n            :style=\"{ color: `var(--v-${flowRun.state}-base)` }\"\n          >\n            {{ flowRun.state }}\n          </span>\n        </span>\n\n        <span class=\"ml-4\">\n          Duration:\n          <DurationSpan\n            v-if=\"flowRun.start_time\"\n            class=\"font-weight-black\"\n            :start-time=\"flowRun.start_time\"\n            :end-time=\"flowRun.end_time\"\n          />\n        </span>\n      </div>\n      <div slot=\"action\" class=\"d-flex align-end justify-center flex-column\">\n        <v-checkbox\n          v-model=\"showCards\"\n          dense\n          label=\"Show Cards\"\n          color=\"primary\"\n          class=\"my-0 mr-4\"\n          hide-details\n        ></v-checkbox>\n      </div>\n    </CardTitle>\n\n    <v-card-text class=\"full-height position-relative\">\n      <SchematicFlow :tasks=\"tasks\" show-legend :show-cards=\"showCards\" />\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.full-height {\n  min-height: 67vh;\n}\n\n.vertical-divider {\n  border-left: 0.5px solid rgba(0, 0, 0, 0.26);\n  border-right: 0.5px solid rgba(0, 0, 0, 0.26);\n  height: 75%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/FlowRun/TaskRunHeartbeat-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport HeartbeatTimeline from '@/components/HeartbeatTimeline'\nimport { heartbeatMixin } from '@/mixins/heartbeatMixin.js'\n\nexport default {\n  components: {\n    CardTitle,\n    HeartbeatTimeline\n  },\n  mixins: [heartbeatMixin],\n  // These should eventually be moved here as data props\n  // instead of as passed in props\n  props: {\n    flowRunId: {\n      type: String,\n      required: true\n    }\n  },\n  data() {\n    return { loading: 0 }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.heartbeat.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    heartbeat: {\n      query: require('@/graphql/FlowRun/heartbeat.gql'),\n      update: d => d.task_run,\n      loadingKey: 'loading',\n      pollInterval: 10000,\n      variables() {\n        return {\n          flowRunId: this.flowRunId,\n          timestamp: this.timestamp,\n          state: this.checkedState\n        }\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2\" tile>\n    <CardTitle title=\"Activity\" icon=\"show_chart\">\n      <v-select\n        data-public\n        slot=\"action\"\n        v-model=\"state\"\n        class=\"state-interval-picker font-weight-regular\"\n        :items=\"states\"\n        label=\"State\"\n        dense\n        solo\n        hide-details\n        flat\n      >\n        <template #prepend-inner>\n          <v-icon color=\"utilGrayDark\" x-small>\n            label_important\n          </v-icon>\n        </template>\n      </v-select>\n    </CardTitle>\n\n    <v-container class=\"pa-0 pr-4\">\n      <HeartbeatTimeline\n        :loading=\"loading\"\n        :items=\"heartbeat\"\n        type=\"task_run\"\n      />\n    </v-container>\n\n    <v-divider></v-divider>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.state-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/FlowRun/TaskRunTable-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport moment from 'moment-timezone'\nimport DurationSpan from '@/components/DurationSpan'\nimport ResumeButton from '@/components/ResumeButton'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { STATE_NAMES } from '@/utils/states'\nimport { calculateDuration } from '@/utils/states'\n\nexport default {\n  components: {\n    CardTitle,\n    DurationSpan,\n    ResumeButton\n  },\n  filters: {\n    duration: function(v) {\n      if (!v) return ''\n      let d = moment.duration(v)._data,\n        string = ''\n\n      if (d.days) string += ` ${d.days}d`\n      if (d.hours) string += ` ${d.hours}h`\n      if (d.minutes) string += ` ${d.minutes}m`\n      if (d.seconds) string += ` ${d.seconds}s`\n      return string\n    }\n  },\n  mixins: [formatTime],\n  props: {\n    flowRunId: {\n      required: true,\n      type: String\n    }\n  },\n  data() {\n    return {\n      headers: [\n        {\n          text: 'Task',\n          value: 'task.name',\n          sortable: false,\n          width: '37.5%'\n        },\n        {\n          text: 'Start Time',\n          value: 'start_time',\n          align: 'start',\n          width: '15%'\n        },\n        { text: 'End Time', value: 'end_time', align: 'start', width: '15%' },\n        {\n          text: 'Duration',\n          value: 'duration',\n          align: 'end',\n          width: '15.5%',\n          sortable: false\n        },\n        { text: 'State', value: 'state', align: 'end', width: '10%' },\n        {\n          text: '',\n          value: 'action',\n          sortable: false,\n          align: 'center',\n          width: '10%'\n        }\n      ],\n      itemsPerPage: 15,\n      page: 1,\n      searchTerm: null,\n      state: [],\n      states: STATE_NAMES.slice(1).sort(),\n      sortBy: 'start_time',\n      sortDesc: true,\n      taskRunDurations: {}\n    }\n  },\n  computed: {\n    offset() {\n      return this.itemsPerPage * (this.page - 1)\n    },\n    tableTitle() {\n      if (this.flowRun) {\n        return `${this.flowRun.name} Task Runs`\n      } else {\n        return 'Task Runs'\n      }\n    },\n    searchFormatted() {\n      if (!this.searchTerm) return null\n      return `%${this.searchTerm}%`\n    }\n  },\n  methods: {\n    hasChild(name) {\n      const same = this.flowRun.task_runs.filter(\n        taskRun => taskRun.task.name === name\n      )\n      if (same.length > 1) {\n        return true\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRun.skip = !entry.isIntersecting\n      this.$apollo.queries.taskRunsCount.skip = !entry.isIntersecting\n    },\n    calculateDuration\n  },\n  apollo: {\n    flowRun: {\n      query: require('@/graphql/FlowRun/table-task-runs.gql'),\n      variables() {\n        const orderBy = {}\n        orderBy[`${this.sortBy}`] = this.sortDesc ? 'desc' : 'asc'\n        return {\n          flowRunId: this.flowRunId,\n          limit: this.itemsPerPage,\n          name: this.searchFormatted,\n          state: this.state.length === 0 ? null : this.state,\n          offset: this.offset,\n          orderBy\n        }\n      },\n      pollInterval: 5000,\n      update: data => {\n        return data && data.flow_run ? data.flow_run[0] : null\n      }\n    },\n    taskRunsCount: {\n      query: require('@/graphql/FlowRun/table-task-runs-count.gql'),\n      variables() {\n        return {\n          flowRunId: this.flowRunId,\n          name: this.searchFormatted,\n          state: this.state.length === 0 ? null : this.state\n        }\n      },\n      pollInterval: 5000,\n      update: data => {\n        return data && data.task_run_aggregate\n          ? data.task_run_aggregate.aggregate.count\n          : null\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2\" tile>\n    <CardTitle icon=\"pi-task-run\">\n      <div\n        :slot=\"$vuetify.breakpoint.lgAndUp && 'title'\"\n        class=\"text-truncate pb-1\"\n      >\n        {{ tableTitle }}\n      </div>\n\n      <div\n        :slot=\"$vuetify.breakpoint.mdAndDown ? 'title' : 'state-filter'\"\n        :class=\"{ 'd-flex': $vuetify.breakpoint.mdAndUp }\"\n      >\n        <v-select\n          v-model=\"state\"\n          data-public\n          outlined\n          class=\"state-filter\"\n          :style=\"[\n            $vuetify.breakpoint.mdAndUp ? { width: '280px' } : { width: '100%' }\n          ]\"\n          dense\n          flat\n          solo\n          hide-details\n          :menu-props=\"{ top: true, offsetY: true }\"\n          clearable\n          :items=\"states\"\n          label=\"Filter by state\"\n          multiple\n        >\n          <template #selection=\"{ item, index }\">\n            <v-chip\n              v-if=\"index === 0 || index === 1\"\n              :color=\"item\"\n              label\n              small\n              text-color=\"white\"\n            >\n              {{ item }}\n            </v-chip>\n            <span v-if=\"index === 2\" class=\"grey--text text-caption\">\n              (+{{ state.length - 2 }})\n            </span>\n          </template>\n        </v-select>\n        <v-text-field\n          slot=\"action\"\n          v-model=\"searchTerm\"\n          class=\"task-search\"\n          dense\n          flat\n          solo\n          prepend-inner-icon=\"search\"\n          hide-details\n          placeholder=\"Search by Task Name\"\n          style=\"min-width: 210px;\"\n        >\n        </v-text-field>\n      </div>\n    </CardTitle>\n\n    <v-card-text>\n      <v-data-table\n        :footer-props=\"{\n          showFirstLastPage: true,\n          itemsPerPageOptions: [10, 15, 25, 50],\n          firstIcon: 'first_page',\n          lastIcon: 'last_page',\n          prevIcon: 'keyboard_arrow_left',\n          nextIcon: 'keyboard_arrow_right'\n        }\"\n        class=\"truncate-table\"\n        :headers=\"headers\"\n        :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n        :items=\"flowRun ? flowRun.task_runs : [] || []\"\n        :items-per-page.sync=\"itemsPerPage\"\n        :loading=\"$apollo.queries.flowRun.loading\"\n        must-sort\n        :page.sync=\"page\"\n        :server-items-length=\"taskRunsCount\"\n        :sort-by.sync=\"sortBy\"\n        :sort-desc.sync=\"sortDesc\"\n        :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n        calculate-widths\n      >\n        <template #item.task.name=\"{ item }\">\n          <div class=\"text-truncate\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <router-link\n                  class=\"link text-truncate\"\n                  :data-cy=\"'task-run-table-link|' + item.task.name\"\n                  :to=\"{ name: 'task-run', params: { id: item.id } }\"\n                >\n                  <span v-if=\"item.name\" v-on=\"on\">{{ item.name }}</span>\n                  <span v-else v-on=\"on\"\n                    >{{ item.task.name\n                    }}<span v-if=\"item.map_index > -1\">\n                      (Mapped Child {{ item.map_index }})</span\n                    ><span v-else-if=\"hasChild(item.task.name)\">\n                      (Parent)\n                    </span>\n                  </span>\n                </router-link>\n              </template>\n              <span v-if=\"item.name\"\n                >{{ flowRun.name }} - {{ item.task.name }} -\n                {{ item.name }}</span\n              >\n              <span v-else>\n                {{ flowRun.name }} - {{ item.task.name\n                }}<span v-if=\"item.map_index > -1\">\n                  (Mapped Child {{ item.map_index }})</span\n                ><span v-else-if=\"hasChild(item.task.name)\"> (Parent) </span>\n              </span>\n            </v-tooltip>\n          </div>\n        </template>\n\n        <template #item.start_time=\"{ item }\">\n          <truncate :content=\"formatTime(item.start_time)\">\n            {{ formDate(item.start_time) }}\n          </truncate>\n        </template>\n\n        <template #item.end_time=\"{ item }\">\n          <truncate :content=\"formatTime(item.end_time)\">\n            {{ formDate(item.end_time) }}\n          </truncate>\n        </template>\n\n        <template #item.duration=\"{ item }\">\n          <DurationSpan\n            v-if=\"item.start_time\"\n            :start-time=\"item.start_time\"\n            :end-time=\"\n              calculateDuration(item.start_time, item.end_time, item.state)\n            \"\n          />\n          <span v-else>...</span>\n        </template>\n\n        <template #item.state=\"{ item }\">\n          <truncate :content=\"item.state\">\n            <v-icon class=\"mr-1 pointer\" small :color=\"item.state\">\n              brightness_1\n            </v-icon>\n          </truncate>\n        </template>\n\n        <template #item.action=\"{ item }\">\n          <ResumeButton\n            v-if=\"item.state == 'Paused'\"\n            :task-run=\"{ ...item, flow_run: flowRun }\"\n            dialog-type=\"resume\"\n          />\n        </template>\n      </v-data-table>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\">\n.task-search {\n  border-radius: 0 !important;\n  font-size: 0.85rem;\n\n  .v-icon {\n    font-size: 20px !important;\n  }\n}\n\n.state-filter {\n  .v-label {\n    font-size: 0.85rem;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/FlowRun/Timeline-Tile.vue",
    "content": "<script>\nimport gql from 'graphql-tag'\nimport { FINISHED_STATES } from '@/utils/states'\n\nimport { formatTime } from '@/mixins/formatTimeMixin'\nconst computedStyle = getComputedStyle(document.documentElement)\nconst notPastStates = ['Running', 'Submitted', 'Pending']\n\nexport default {\n  components: {\n    RunStateTooltip: () => import('@/components/RunStateTooltip'),\n    TaskRunTooltip: () => import('@/components/TaskRunTooltip'),\n    Timeline: () => import('@/components/Visualizations/Timeline')\n  },\n  mixins: [formatTime],\n  props: {\n    flowId: {\n      type: String,\n      required: true\n    },\n    flowRunId: {\n      type: String,\n      required: true\n    },\n    // flowRun: {\n    //   type: Object,\n    //   required: false,\n    //   default: () => {}\n    // },\n    flowRunEndTime: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    flowRunScheduledStartTime: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    flowRunStartTime: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    flowRunState: {\n      type: String,\n      required: false,\n      default: () => null\n    },\n    flowRunStates: {\n      type: Array,\n      required: false,\n      default: () => []\n    }\n  },\n  data() {\n    return {\n      breakpoints: [],\n      containerHeight: null,\n      hoveredBreakpoints: null,\n      hoveredTaskRuns: [],\n      loadingKey: 0\n    }\n  },\n  computed: {\n    containerStyle() {\n      return {\n        height: '114px'\n      }\n    },\n    endTime() {\n      return this.flowRunEndTime && this.isFinished\n        ? Math.max.apply(null, [\n            new Date(this.flowRunScheduledStartTime),\n            new Date(this.flowRunEndTime),\n            this.maxEndTime\n          ])\n        : null\n    },\n    filteredFlowRunStates() {\n      return this.flowRunStates.filter(state => state.state !== 'Pending')\n    },\n    startTime() {\n      return this.flowRunStartTime\n        ? Math.min.apply(null, [\n            new Date(this.flowRunScheduledStartTime),\n            new Date(this.flowRunStartTime),\n            ...this.filteredFlowRunStates.map(\n              state => new Date(state.start_time ?? state.timestamp)\n            )\n          ])\n        : this.flowRunScheduledStartTime\n    },\n    loading() {\n      return this.loadingKey > 0\n    },\n    items() {\n      if (!this.tasks) return\n      return this.tasks\n        .map(task => {\n          const taskRun = this.taskRunMap[task.id]\n          const mappedRef = this.mappedChildren?.[task.id]\n          const isMapped = taskRun?.state == 'Mapped'\n          const taskRunIsFinished = FINISHED_STATES.includes(taskRun.state)\n\n          const item = {\n            id: task.id,\n            label: task.name,\n            colors: [],\n            start_time: null,\n            shadow: false,\n            end_time: null,\n            links: [],\n            data: {\n              ...task,\n              ...taskRun,\n              mappedChildren: mappedRef\n            }\n          }\n\n          if (!taskRun || (isMapped && !mappedRef)) return item\n\n          if (isMapped) {\n            const states = Object.keys(mappedRef.state_counts).sort(\n              (s1, s2) => notPastStates.indexOf(s1) - notPastStates.indexOf(s2)\n            )\n            const total = Object.values(mappedRef.state_counts).reduce(\n              (a, b) => a + b,\n              0\n            )\n\n            states.forEach(state => {\n              const color = computedStyle\n                .getPropertyValue(`--v-${state}-base`)\n                ?.trim()\n\n              item.colors.push({\n                color: color,\n                value: mappedRef.state_counts[state] / total\n              })\n            })\n\n            if (item.colors.length == 0) {\n              item.colors.push({\n                color: computedStyle.getPropertyValue('--v-Mapped-base'),\n                value: 1\n              })\n            }\n\n            item.start_time = mappedRef.min_start_time\n\n            // If we have n_mapped_states and the flow run isn't finished,\n            // we attempt to set the end time based on mapped children having\n            // all finished states; if any of the mapped children are still pending/submitted/running\n            // we assuming the task run is still going and set the end_time to null\n            if (taskRun?.serialized_state?.n_map_states && !this.isFinished) {\n              item.end_time =\n                taskRun?.serialized_state?.n_map_states == total &&\n                // !this.isFinished &&\n                !states.some(state => notPastStates.includes(state))\n                  ? mappedRef.max_end_time\n                  : null\n              // item.shadow = states.some(state => notPastStates.includes(state))\n            } else {\n              // Using mappedRef.max_end_time means older versions of Core will visually \"jump\"\n              // as new task runs are taken into account for the calculation of max_end_time\n              item.end_time = mappedRef.max_end_time\n              // item.shadow = this.flowRun.state == 'Running'\n            }\n          } else {\n            item.start_time = taskRun.start_time\n            item.end_time = !taskRunIsFinished ? null : taskRun.end_time ?? null\n\n            const color = computedStyle\n              .getPropertyValue(`--v-${taskRun.state}-base`)\n              ?.trim()\n\n            item.colors.push({ color: color, value: 1 })\n            // item.shadow =\n            // taskRun.state == 'Running' || taskRun.state == 'Pending'\n          }\n\n          if (\n            (this.isFinished || (taskRunIsFinished && !isMapped)) &&\n            !item.end_time\n          ) {\n            item.end_time = taskRun.start_time\n              ? taskRun.start_time\n              : taskRun.state_timestamp\n          }\n\n          if ((this.isFinished || taskRunIsFinished) && !item.start_time) {\n            item.start_time = taskRun.state_timestamp\n            item.end_time = taskRun.state_timestamp\n            item.shadow = false\n          }\n\n          return item\n        })\n        .sort((a, b) => {\n          if (!a.start_time && b.start_time) return 1\n          if (!b.start_time && a.start_time) return -1\n          if (!a.start_time && !b.start_time) return 0\n          return new Date(a.start_time) - new Date(b.start_time)\n        })\n    },\n    maxEndTime() {\n      return Math.max.apply(null, [\n        ...this.items.map(item => new Date(item.end_time)),\n        ...this.flowRunStates.map(state => new Date(state.timestamp))\n      ])\n    },\n    isFinished() {\n      return (\n        FINISHED_STATES.includes(this.flowRunState) &&\n        this.flowRunState !== 'Scheduled'\n      )\n    },\n    mappedTaskRuns() {\n      return this.taskRuns?.filter(taskRun => taskRun.state == 'Mapped')\n    },\n    mappedChildrenQuery() {\n      return this.mappedTaskRuns\n        ?.map(\n          (taskRun, index) => `\n         mapped_run_${index}: mapped_children(task_run_id: \"${taskRun.id}\") {\n            max_end_time\n            min_start_time\n            state_counts\n          }\n      `\n        )\n        .join(' ')\n    },\n    taskRunMap() {\n      if (!this.taskRuns || !this.tasks) return {}\n      const taskRunMap = {}\n      this.tasks.map(task => {\n        const run = this.taskRuns.find(tr => tr.task_id == task.id)\n        taskRunMap[task.id] = run ?? {}\n        taskRunMap[task.id].task_id = task.id\n        taskRunMap[task.id].task_name = task.name\n      })\n\n      return taskRunMap\n    }\n  },\n  watch: {\n    flowRun() {\n      this.$apollo.queries.taskRuns.stopPolling()\n      this.$apollo.queries.tasks.stopPolling()\n      this.$apollo.queries.mappedChildren.stopPolling()\n\n      if (this.isFinished) {\n        this.$apollo.queries.taskRuns.startPolling(60000)\n        this.$apollo.queries.mappedChildren.startPolling(60000)\n      } else {\n        this.$apollo.queries.taskRuns.startPolling(3000)\n        this.$apollo.queries.tasks.startPolling(30000)\n        this.$apollo.queries.mappedChildren.startPolling(5000)\n      }\n\n      this.generateBreakpoints()\n    }\n  },\n  mounted() {\n    if (this.isFinished) {\n      this.$apollo.queries.taskRuns.stopPolling()\n      this.$apollo.queries.tasks.stopPolling()\n      this.$apollo.queries.mappedChildren.stopPolling()\n\n      this.$apollo.queries.taskRuns.startPolling(60000)\n      this.$apollo.queries.tasks.startPolling(60000)\n      this.$apollo.queries.mappedChildren.startPolling(60000)\n    }\n\n    this.generateBreakpoints()\n\n    this.containerHeight = getComputedStyle(\n      this.$refs['timeline-container']\n    ).height\n  },\n  methods: {\n    generateBreakpoints() {\n      this.breakpoints = this.filteredFlowRunStates.map(state => {\n        return {\n          label: state.state,\n          time: state.start_time ?? state.timestamp,\n          color: computedStyle.getPropertyValue(`--v-${state.state}-base`)\n        }\n      })\n    },\n    handleClick(e) {\n      if (!e.id) return\n\n      const taskRun = this.items.find(item => e?.id == item.id)\n      if (!taskRun) return\n\n      this.$router.push({\n        name: 'task-run',\n        params: {\n          id: taskRun.data.id\n        }\n      })\n    },\n    handleHover(e) {\n      this.hoveredTaskRuns = this.items.filter(item =>\n        e?.ids?.includes(item.id)\n      )\n    },\n    handleBreakpointHover(e) {\n      e?.breakpoints.forEach(b => {\n        b.formattedTime = this.logTime(b.time)\n      })\n      this.hoveredBreakpoints = e?.breakpoints\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.taskRuns.skip = !entry.isIntersecting\n      this.$apollo.queries.mappedChildren.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    taskRuns: {\n      query: require('@/graphql/FlowRun/timeline-chart-task-runs.gql'),\n      variables() {\n        return {\n          flowRunId: this.flowRunId\n        }\n      },\n      skip() {\n        return !this.flowId || !this.tasks\n      },\n      loadingKey: 'loadingKey',\n      pollInterval: 60000,\n      update: data => data.task_run\n    },\n    tasks: {\n      query: require('@/graphql/FlowRun/timeline-chart-tasks.gql'),\n      variables() {\n        return {\n          flowId: this.flowId\n        }\n      },\n      skip() {\n        return !this.flowRunId\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.task\n    },\n    mappedChildren: {\n      query() {\n        return gql`\n        query MappedChildren {\n          ${this.mappedChildrenQuery}\n        }\n      `\n      },\n      skip() {\n        return !this.taskRuns || !this.mappedTaskRuns.length\n      },\n      pollInterval: 60000,\n      update(data) {\n        // Since mapped_children doesn't return an id (and we can't do this mapping with GraphQL)\n        // we map those here instead\n        const mappedTaskMap = {}\n        Object.keys(data).forEach(\n          (key, index) =>\n            (mappedTaskMap[this.mappedTaskRuns[index]?.task_id] = {\n              ...data[key],\n              parent_id: this.mappedTaskRuns[index]?.id,\n              task_id: this.mappedTaskRuns[index]?.task_id\n            })\n        )\n        return mappedTaskMap\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"px-3 pt-7 pb-2 mx-auto\"\n    style=\"\n      max-height: 200px;\"\n    tile\n  >\n    <div class=\"text-caption text-left grey--text timeline-title\">\n      <v-icon x-small>pi-gantt</v-icon><span class=\"ml-1\">Timeline</span>\n    </div>\n\n    <div\n      v-if=\"!loading && items.length === 0\"\n      class=\"text-caption text-center grey--text timeline-no-runs\"\n    >\n      No timeline\n    </div>\n\n    <v-card-text\n      ref=\"timeline-container\"\n      class=\"timeline-container pa-0\"\n      style=\"height: 150px;\"\n    >\n      <!-- \n            :condensed=\"condensed\"\n        :min-bar-radius=\"10\" -->\n      <Timeline\n        v-if=\"taskRuns && items\"\n        :items=\"items\"\n        :start-time=\"startTime\"\n        :end-time=\"endTime\"\n        :loading=\"loading && (!tasks || !taskRuns)\"\n        :breakpoints=\"breakpoints\"\n        :live=\"!isFinished\"\n        :height=\"containerHeight\"\n        @breakpoint-hover=\"handleBreakpointHover\"\n        @hover=\"handleHover\"\n        @click=\"handleClick\"\n      >\n        <template slot=\"item-tooltip\">\n          <v-fade-transition mode=\"out-in\">\n            <TaskRunTooltip\n              v-if=\"hoveredTaskRuns.length\"\n              :task-runs=\"hoveredTaskRuns\"\n            />\n          </v-fade-transition>\n        </template>\n\n        <template slot=\"breakpoint-tooltip\">\n          <v-fade-transition mode=\"out-in\">\n            <RunStateTooltip\n              v-if=\"hoveredBreakpoints\"\n              :states=\"hoveredBreakpoints\"\n            />\n          </v-fade-transition>\n        </template>\n      </Timeline>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.timeline-title {\n  left: 8px;\n  position: absolute;\n  top: 8px;\n}\n\n.timeline-no-runs {\n  left: 50%;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n}\n</style>\n"
  },
  {
    "path": "src/pages/GettingStarted/ConnectAgent-Section.vue",
    "content": "<script>\nimport ExternalLink from '@/components/ExternalLink'\nimport { mapGetters } from 'vuex'\n\nconst AGENT_TYPES = [\n  { type: 'DockerAgent', icon: 'fab fa-docker pa-1' },\n  { type: 'ECSAgent', icon: 'fab fa-aws pa-1' },\n  { type: 'FargateAgent', icon: 'fab fa-aws pa-1' },\n  { type: 'KubernetesAgent', icon: 'pi-kubernetes' },\n  { type: 'LocalAgent', icon: 'fad fa-laptop-house pa-1' },\n  { type: 'NomadAgent', icon: '$nomad' }\n]\n\nexport default {\n  components: {\n    ExternalLink\n  },\n  data() {\n    return {\n      agentToken: null,\n      error: false,\n      success: false,\n      loadingKey: 0,\n      token: null,\n      tokenId: null\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud', 'connected', 'isServer']),\n    ...mapGetters('user', ['user'])\n  },\n  async mounted() {\n    if (this.isCloud) {\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Tokens/create-api-key.gql'),\n          variables: {\n            name: `default-agent-${Date.now()}`,\n            user_id: this.user?.id\n          }\n        })\n\n        this.tokenId = data.create_api_key.id\n        this.token = data.create_api_key.key\n      } catch {\n        //\n      }\n    }\n  },\n  async beforeDestroy() {\n    // We try to delete the token if it wasn't used\n    if (\n      this.isCloud &&\n      !this.agents?.some(agent => agent.token_id == this.tokenId) &&\n      this.tokenId\n    ) {\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Tokens/delete-token.gql'),\n          variables: {\n            id: this.tokenId\n          }\n        })\n      } catch {\n        //\n      }\n    }\n  },\n  methods: {\n    async _refreshAgents() {\n      this.$apollo.queries.agents.refetch()\n    },\n    agentIcon(type) {\n      return AGENT_TYPES.find(a => a.type == type)?.icon\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.agents.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    agents: {\n      query() {\n        return require('@/graphql/Agent/agents.js').default(this.isCloud)\n      },\n      pollInterval: 5000,\n      loadingKey: 'loadingKey',\n      skip() {\n        return this.isServer\n      },\n      fetchPolicy: 'network-only',\n      update: data =>\n        data?.agent?.sort((a, b) => a.id.localeCompare(b.id)) || []\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-intersect=\"{ handler: onIntersect }\" class=\"appForeground\">\n    <div class=\"text-body-1\">\n      The Prefect Agent is a small entity created to orchestrate flow runs. The\n      Agent works by querying the Prefect API for new or incomplete Flow Runs\n      and allocating resources based on the Flow's configured deployment\n      platform. You can read more about\n      <ExternalLink\n        href=\"https://docs.prefect.io/orchestration/agents/overview.html\"\n      >\n        Agents\n      </ExternalLink>\n      in the docs.\n    </div>\n\n    <ol v-if=\"isServer\" class=\"mt-6\">\n      <li value=\"1\" class=\"text-h6 mt-6 mb-2\">Set backend</li>\n      <div class=\"text-body-1 mt-2\">\n        First, make sure Prefect is working against\n        {{ isCloud ? 'Prefect Cloud' : 'your Prefect Server' }}\n      </div>\n      <div\n        class=\"text-body-1 appBackground utilGrayDark--text rounded-sm pa-3 mt-4\"\n        style=\"border: 1px solid var(--v-utilGrayLight-base) !important;\"\n      >\n        <div class=\"code-block\">\n          <span class=\"blue-grey--text text--lighten-1 user-select-none\"\n            >$\n          </span>\n          <span class=\"primary--text font-weight-medium\">prefect</span>\n          backend\n          <span class=\"deepRed--text font-weight-medium\">server</span>\n        </div>\n      </div>\n    </ol>\n\n    <ol class=\"mt-12\">\n      <li :value=\"isCloud ? 1 : 2\" class=\"text-h6 mt-6 mb-2\">Start an Agent</li>\n      <div class=\"text-body-1 mt-2\">\n        For your Flows to run, you'll need to start an Agent process. There are\n        many different types of Agents to choose from, each of which takes a\n        number of arguments and flags; you can read more about them in the\n        <ExternalLink\n          href=\"https://docs.prefect.io/orchestration/agents/overview.html#usage\"\n        >\n          docs </ExternalLink\n        >. For example, the following CLI command starts a Local Agent on your\n        local machine:\n      </div>\n\n      <div\n        class=\"text-body-1 appBackground utilGrayDark--text rounded-sm pa-3 mt-4\"\n        style=\"border: 1px solid var(--v-utilGrayLight-base) !important;\"\n      >\n        <div class=\"code-block\">\n          <span class=\"blue-grey--text text--lighten-1 user-select-none\"\n            >$\n          </span>\n          <span class=\"primary--text font-weight-medium\">prefect</span>\n          agent local\n          <span class=\"deepRed--text font-weight-medium\">start</span>\n          --name\n          <span class=\"yellow--text text--darken-3 font-weight-medium\"\n            >\"Default Agent\"</span\n          >\n          <span v-if=\"token\">\n            --token\n            <span class=\"yellow--text text--darken-3 font-weight-medium\">{{\n              token\n            }}</span>\n          </span>\n        </div>\n      </div>\n    </ol>\n\n    <ol v-if=\"isCloud\" class=\"mt-12\">\n      <li value=\"2\" class=\"text-h6 mt-6 mb-2\">\n        View polling Agents\n      </li>\n      <div>\n        <v-btn class=\"my-4\" color=\"primary\" small @click=\"_refreshAgents\">\n          <v-icon left>refresh</v-icon>Refresh agents\n        </v-btn>\n\n        <span class=\"ml-2\">\n          <v-fade-transition mode=\"out-in\">\n            <span v-if=\"success\">\n              <v-icon v-if=\"success\" key=\"success\" color=\"green\">\n                check\n              </v-icon>\n              {{ success }}\n            </span>\n            <span v-else-if=\"error\">\n              <v-icon key=\"error\" color=\"error\">\n                error\n              </v-icon>\n              {{ error }}\n            </span>\n          </v-fade-transition>\n        </span>\n      </div>\n\n      <v-simple-table v-if=\"isCloud\">\n        <template #default>\n          <thead>\n            <tr>\n              <th>Type</th>\n              <th>Name</th>\n              <th width=\"50%\">Labels</th>\n            </tr>\n          </thead>\n\n          <tbody v-if=\"agents && agents.length > 0\">\n            <tr>\n              <td\n                colspan=\"3\"\n                class=\"pa-0\"\n                style=\"\n                  border: unset !important;\n                  height: auto !important;\"\n              >\n                <v-progress-linear\n                  :active=\"loadingKey > 0\"\n                  indeterminate\n                  color=\"primary\"\n                />\n              </td>\n            </tr>\n            <tr v-for=\"a in agents\" :key=\"a.id\">\n              <td>\n                <v-icon>\n                  {{ a.type ? agentIcon(a.type) : 'fas fa-robot' }}\n                </v-icon>\n              </td>\n              <td>{{ a.name }}</td>\n              <td>\n                <v-chip\n                  v-for=\"label in a.labels\"\n                  :key=\"label\"\n                  x-small\n                  label\n                  outlined\n                  class=\"mx-1\"\n                  color=\"primary\"\n                >\n                  {{ label }}\n                </v-chip>\n              </td>\n            </tr>\n          </tbody>\n\n          <tbody v-else>\n            <tr>\n              <td>No agents</td>\n            </tr>\n          </tbody>\n        </template>\n      </v-simple-table>\n    </ol>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/GettingStarted/CreateTenant-Section.vue",
    "content": "<script>\nimport { mapGetters, mapActions } from 'vuex'\nimport { pollsTenantsMixin } from '@/mixins/polling/pollsTenantsMixin'\n\nexport default {\n  mixins: [pollsTenantsMixin],\n  data() {\n    return {\n      serverUrlInput: this.serverUrl,\n      error: false,\n      loading: false,\n      success: this.tenants?.length > 0\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant', 'tenants'])\n  },\n  methods: {\n    ...mapActions('tenant', ['getTenants', 'setCurrentTenant']),\n    async _refreshTenants() {\n      this.success = false\n      this.error = false\n      this.loading = true\n\n      try {\n        await this.getTenants()\n\n        if (this.tenants?.length === 0) {\n          this.error = 'No tenants found. Did you create your default tenant?'\n        }\n      } catch (e) {\n        this.error = e\n      }\n\n      this.loading = false\n    },\n    async _selectTenant(slug) {\n      this.success = false\n      this.error = false\n      this.loading = true\n\n      try {\n        await this.setCurrentTenant(slug)\n\n        if (this.tenant) {\n          this.success = 'You successfully set your tenant!'\n        }\n      } catch (e) {\n        this.success = false\n        this.error =\n          'There was a problem setting your tenant... please try again.'\n\n        throw new Error(e)\n      }\n\n      this.loading = false\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"appForeground\">\n    <div class=\"text-body-1\">\n      Tenants (or teams) are a unit Prefect Server uses to organize data such as\n      Projects and Flows. If you ran\n      <br /><kbd>prefect server start</kbd> to spin up your infrastucture, a\n      default tenant was created for you automatically! If you ran the Prefect\n      services separately (such as in a Kubernetes deployment), you'll need to\n      create your own tenant using the steps below.\n    </div>\n\n    <ol class=\"my-6\">\n      <li value=\"1\" class=\"text-h6 mt-6 mb-2\">Set backend</li>\n      <div class=\"text-body-1 mt-2\">\n        First, make sure Prefect is working against\n        {{ isCloud ? 'Prefect Cloud' : 'your Prefect Server' }}\n      </div>\n\n      <div\n        class=\"text-body-1 grey lighten-5 blue-grey--text text--darken-2 rounded-sm pa-3 mt-4\"\n        style=\"border: 1px solid var(--v-utilGrayLight-base) !important;\"\n      >\n        <div class=\"code-block\">\n          <span class=\"blue-grey--text text--lighten-1 user-select-none\"\n            >$\n          </span>\n          <span class=\"primary--text font-weight-medium\">prefect</span>\n          backend<span class=\"deepRed--text font-weight-medium\">\n            {{ isCloud ? 'cloud' : 'server' }}\n          </span>\n        </div>\n      </div>\n    </ol>\n\n    <ol class=\"my-12\">\n      <li value=\"2\" class=\"text-h6 mt-6 mb-2\">Run the CLI Command</li>\n      <div\n        class=\"text-body-1 grey lighten-5 blue-grey--text text--darken-2 rounded-sm pa-3 mt-4\"\n        style=\"border: 1px solid var(--v-utilGrayLight-base) !important;\"\n      >\n        <div class=\"code-block\">\n          <span class=\"blue-grey--text text--lighten-1 user-select-none\"\n            >$\n          </span>\n          <span class=\"primary--text font-weight-medium\">prefect</span>\n          server\n          <span class=\"deepRed--text font-weight-medium\">create-tenant</span>\n          --name\n          <span class=\"yellow--text text--darken-3 font-weight-medium\"\n            >default</span\n          >\n          --slug\n          <span class=\"yellow--text text--darken-3 font-weight-medium\"\n            >default</span\n          >\n        </div>\n      </div>\n    </ol>\n\n    <ol class=\"mt-6\">\n      <li value=\"3\" class=\"text-h6 mt-6 mb-2\">Select your Tenant</li>\n      <div>\n        <v-btn class=\"my-4\" color=\"primary\" small @click=\"_refreshTenants\">\n          <v-icon left>refresh</v-icon>Refresh tenants\n        </v-btn>\n\n        <span class=\"ml-2\">\n          <v-fade-transition mode=\"out-in\">\n            <span v-if=\"success\">\n              <v-icon v-if=\"success\" key=\"success\" color=\"green\">\n                check\n              </v-icon>\n              {{ success }}\n            </span>\n            <span v-else-if=\"error\">\n              <v-icon key=\"error\" color=\"error\">\n                error\n              </v-icon>\n              {{ error }}\n            </span>\n          </v-fade-transition>\n        </span>\n      </div>\n\n      <v-simple-table>\n        <template #default>\n          <thead>\n            <tr>\n              <th class=\"text-left\">Name</th>\n              <th class=\"text-left\">Slug</th>\n              <th class=\"text-left\"></th>\n            </tr>\n          </thead>\n\n          <tbody v-if=\"tenants && tenants.length > 0\">\n            <tr>\n              <td\n                colspan=\"3\"\n                class=\"pa-0\"\n                style=\"\n                  border: unset !important;\n                  height: auto !important;\"\n              >\n                <v-progress-linear\n                  :active=\"loading\"\n                  indeterminate\n                  color=\"primary\"\n                />\n              </td>\n            </tr>\n            <tr v-for=\"t in tenants\" :key=\"t.id\">\n              <td>{{ t.name }}</td>\n              <td>{{ t.slug }}</td>\n              <td class=\"text-right\">\n                <v-btn\n                  color=\"accentOrange\"\n                  :disabled=\"tenant && tenant.id == t.id\"\n                  :dark=\"tenant && tenant.id !== t.id\"\n                  depressed\n                  small\n                  @click=\"_selectTenant(t.slug)\"\n                >\n                  {{ tenant && tenant.id == t.id ? 'Selected' : 'Select' }}\n                </v-btn>\n              </td>\n            </tr>\n          </tbody>\n\n          <tbody v-else>\n            <tr>\n              <td>No tenants</td>\n              <td></td>\n            </tr>\n          </tbody>\n        </template>\n      </v-simple-table>\n    </ol>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/GettingStarted/GettingStarted.vue",
    "content": "<script>\n// Infrastructure components\nimport ConnectAgentSection from '@/pages/GettingStarted/ConnectAgent-Section'\nimport CreateTenantSection from '@/pages/GettingStarted/CreateTenant-Section'\nimport StartPrefectServerSection from '@/pages/GettingStarted/StartPrefectServer-Section'\n\nimport ExternalLink from '@/components/ExternalLink'\nimport { mapGetters } from 'vuex'\n\nconst exploreBlocks = [\n  {\n    headline: 'Read Case Studies',\n    body: 'Learn how our customers build on Prefect',\n    src: require('@/assets/icon-illustrations/tangible-investment.svg'),\n    alt: 'Case studies image',\n    href: 'https://www.prefect.io/why-prefect/case-studies',\n    linkText: 'Read Case Studies'\n  },\n  {\n    headline: 'Explore the Docs',\n    body: 'Get API references, walkthroughs, and tutorials',\n    src: require('@/assets/icon-illustrations/read-the-blog.svg'),\n    alt: 'Explore the docs image',\n    href: 'https://docs.prefect.io',\n    linkText: 'Get the Docs'\n  },\n  {\n    headline: 'Join our Community',\n    body: 'Chat with us, ask questions, and share tips',\n    src: require('@/assets/icon-illustrations/slack-community.svg'),\n    alt: 'Join the community image',\n    href: 'https://prefect.io/slack',\n    linkText: 'Join Slack'\n  }\n]\n\nexport default {\n  components: {\n    CreateTenantSection,\n    ConnectAgentSection,\n    ExternalLink,\n    StartPrefectServerSection\n  },\n  data() {\n    return {\n      exploreBlocks: exploreBlocks,\n      gettingStartedTab: 'infrastructure',\n      sdkTab: 'pip'\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud', 'connected', 'isServer']),\n    ...mapGetters('tenant', ['tenantIsSet'])\n  },\n  watch: {\n    connected(val) {\n      if (val) {\n        // sets the default tab displayed\n        if (this.isCloud) {\n          this.gettingStartedTab = 'agent'\n        } else if (!this.tenantIsSet) {\n          this.gettingStartedTab = 'tenant'\n        } else {\n          this.gettingStartedTab = 'agent'\n        }\n      }\n    }\n  },\n  mounted() {\n    // sets the default tab displayed\n    if (this.isCloud) {\n      this.gettingStartedTab = 'agent'\n    } else if (!this.connected) {\n      this.gettingStartedTab = 'infrastructure'\n    } else if (!this.tenantIsSet) {\n      this.gettingStartedTab = 'tenant'\n    } else {\n      this.gettingStartedTab = 'agent'\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container\n    fluid\n    style=\"max-width: 1000px !important;\"\n    class=\"mx-auto pt-0 px-3 pb-12\"\n  >\n    <v-row class=\"mt-8\">\n      <v-col>\n        <div class=\"text-h2 text-center mb-2\">Welcome to your Prefect UI!</div>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col>\n        <v-card tile>\n          <v-card-title>\n            Getting started with Prefect\n          </v-card-title>\n          <v-card-text>\n            <v-row justify=\"center\">\n              <v-col\n                v-for=\"(block, i) in exploreBlocks\"\n                :key=\"i\"\n                class=\"d-flex flex-column text-center\"\n                cols=\"12\"\n                sm=\"6\"\n                md=\"4\"\n              >\n                <div>\n                  <img\n                    class=\"explore-image\"\n                    :src=\"block.src\"\n                    :alt=\"block.alt\"\n                  />\n                </div>\n\n                <div class=\"text-h6\">\n                  {{ block.headline }}\n                </div>\n                <div class=\"text-body-2 mb-4\">\n                  {{ block.body }}\n                </div>\n                <div>\n                  <v-btn\n                    color=\"accentOrange\"\n                    dark\n                    depressed\n                    small\n                    target=\"_blank\"\n                    :href=\"block.href\"\n                  >\n                    {{ block.linkText }}\n                  </v-btn>\n                </div>\n              </v-col>\n            </v-row>\n          </v-card-text>\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col>\n        <v-card tile>\n          <v-card-title>\n            Connecting your infrastructure\n          </v-card-title>\n          <v-card-text>\n            <v-tabs\n              v-model=\"gettingStartedTab\"\n              :background-color=\"isCloud ? 'primary' : 'secondary'\"\n            >\n              <v-tab v-if=\"isServer\" ref=\"infrastructure\" href=\"#infrastructure\"\n                >Prefect Server</v-tab\n              >\n              <v-tab v-if=\"isServer && !tenantIsSet\" ref=\"tenant\" href=\"#tenant\"\n                >Creating a tenant</v-tab\n              >\n              <v-tab ref=\"agent\" href=\"#agent\">Connecting an Agent</v-tab>\n            </v-tabs>\n\n            <div class=\"pa-5\">\n              <v-tabs-items v-model=\"gettingStartedTab\">\n                <v-tab-item value=\"infrastructure\">\n                  <StartPrefectServerSection />\n                </v-tab-item>\n\n                <v-tab-item v-if=\"isServer\" value=\"tenant\">\n                  <CreateTenantSection />\n                </v-tab-item>\n\n                <v-tab-item value=\"agent\">\n                  <ConnectAgentSection />\n                </v-tab-item>\n              </v-tabs-items>\n            </div>\n          </v-card-text>\n        </v-card>\n      </v-col>\n    </v-row>\n\n    <v-row>\n      <v-col>\n        <v-card tile>\n          <v-card-title>\n            Getting the Prefect SDK\n          </v-card-title>\n          <v-card-text>\n            <div class=\"text-body-1\">\n              <ExternalLink href=\"https://docs.prefect.io\">\n                <div class=\"d-inline-flex align-start justify-start\">\n                  <v-icon class=\"mr-2\" small>fas fa-align-left</v-icon>\n                  <div>View the documentation</div>\n                </div>\n              </ExternalLink>\n\n              <ExternalLink href=\"https://github.com/PrefectHQ/prefect\">\n                <div class=\"d-inline-flex align-start justify-start ml-6\">\n                  <v-icon class=\"mr-2\" small>fab fa-github</v-icon>\n                  <div>Visit GitHub </div>\n                </div>\n              </ExternalLink>\n            </div>\n\n            <div class=\"text-body-1 mt-2\">\n              Get the Prefect Core package and start building!\n            </div>\n\n            <v-tabs\n              v-model=\"sdkTab\"\n              class=\"mt-4\"\n              background-color=\"primary\"\n              style=\"border: 1px solid utilGrayLight !important;\n                border-bottom: unset !important;\"\n            >\n              <v-tab key=\"pip\">Pip</v-tab>\n              <v-tab key=\"conda\">Conda</v-tab>\n              <v-tab key=\"pipenv\">Pipenv</v-tab>\n            </v-tabs>\n\n            <div\n              class=\"text-body-1 appBackground utilGrayDark--text rounded-sm pa-5 code-block\"\n              style=\"border: 1px solid var(--v-utilGrayLight-base) !important;\n                border-top: unset !important;\"\n            >\n              <v-tabs-items v-model=\"sdkTab\">\n                <v-tab-item>\n                  <div class=\"\">\n                    <span class=\"utilGrayMid--text user-select-none\">$ </span\n                    >pip\n                    <span class=\"primary--text font-weight-medium\"\n                      >install</span\n                    >\n                    prefect\n                  </div>\n                </v-tab-item>\n\n                <v-tab-item>\n                  <div class=\"\">\n                    <span class=\"utilGrayMid--text user-select-none\">$ </span\n                    >conda\n                    <span class=\"primary--text font-weight-medium\"\n                      >install</span\n                    >\n                    -c conda-forge prefect\n                  </div>\n                </v-tab-item>\n\n                <v-tab-item>\n                  <div class=\"\">\n                    <span class=\"utilGrayMid--text user-select-none\">$ </span\n                    >pipenv\n                    <span class=\"primary--text font-weight-medium\"\n                      >install</span\n                    >\n                    --pre prefect\n                  </div>\n                </v-tab-item>\n              </v-tabs-items>\n            </div>\n          </v-card-text>\n        </v-card>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.explore-image {\n  height: 125px;\n  max-width: 125px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/GettingStarted/StartPrefectServer-Section.vue",
    "content": "<script>\nimport ExternalLink from '@/components/ExternalLink'\nimport { mapGetters, mapActions, mapMutations } from 'vuex'\n\nexport default {\n  components: {\n    ExternalLink\n  },\n  data() {\n    return {\n      defaultUrl:\n        window.prefect_ui_settings?.server_url ||\n        process.env.VUE_APP_SERVER_URL,\n      error: false,\n      loading: false,\n      success: false,\n      urlInput: null\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud', 'url', 'serverUrl', 'connected'])\n  },\n  methods: {\n    ...mapActions('api', ['getApi']),\n    ...mapActions('tenant', ['updateTenantSettings']),\n    ...mapMutations('api', ['setServerUrl', 'unsetServerUrl']),\n    _handleKeyup() {\n      this.success = false\n      this.error = false\n      this.loading = false\n    },\n    async _resetUrl() {\n      this.unsetServerUrl()\n\n      this.urlInput = this.defaultUrl\n\n      this.error = false\n      this.success = false\n      this.connected = false\n\n      this.setServerUrl(this.defaultUrl)\n    },\n    async _testUrl() {\n      this.success = false\n      this.error = false\n      this.loading = true\n\n      try {\n        this.setServerUrl(this.urlInput)\n        await this.getApi()\n\n        this.success = this.connected\n        this.error = !this.success\n      } catch {\n        this.error = true\n        this.success = false\n        this.connected = false\n      }\n      this.loading = false\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"appForeground\">\n    <div class=\"text-body-1\">\n      Before you can begin to schedule work with\n      <ExternalLink\n        href=\"https://docs.prefect.io/orchestration/server/overview.html\"\n      >\n        Prefect Server\n      </ExternalLink>\n      , you'll need to start the orchestration infrastructure required to manage\n      your Flows. This includes a database, API, scheduler, and various other\n      criticial services. Alternatively, you can use Prefect Cloud and get\n      started right away (it's free!)\n    </div>\n\n    <ol class=\"mt-6\">\n      <li class=\"text-h6\">Start Prefect Server</li>\n      <div class=\"text-body-1 mt-2\">\n        Once you've installed the Prefect Python package, this simple CLI\n        command starts up the various containers that make up Prefect Server.\n        Note that you'll need to have\n        <ExternalLink href=\"https://docs.docker.com/get-started/\">\n          Docker\n        </ExternalLink>\n        running.\n      </div>\n\n      <div\n        class=\"text-body-1 grey lighten-5 blue-grey--text text--darken-2 rounded-sm pa-3 mt-4\"\n        style=\"border: 1px solid var(--v-utilGrayLight-base) !important;\"\n      >\n        <div class=\"code-block\">\n          <span class=\"blue-grey--text text--lighten-1 user-select-none\"\n            >$\n          </span>\n          <span class=\"primary--text font-weight-medium\">prefect</span>\n          server <span class=\"deepRed--text font-weight-medium\">start</span>\n        </div>\n      </div>\n      <div class=\"text-body-1 mt-2\">\n        This command has many options to customize your deployment - run it with\n        the <kbd>-h</kbd> flag to see the documentation!\n      </div>\n    </ol>\n\n    <ol class=\"mt-12\">\n      <li value=\"2\" class=\"text-h6\">Connect the UI</li>\n      <div class=\"text-body-1 mt-2\">\n        The GraphQL endpoint is one of the public URLs exposed by Prefect Server\n        that allows interaction with the API. By default it's exposed at\n        <kbd>http://localhost:4200/graphql</kbd>, but this can be modified. You\n        can directly modify this endpoint in the input box below:\n      </div>\n\n      <div\n        class=\"d-flex align-end justify-start text-h5 utilGrayDark--text mt-6 mb-10\"\n      >\n        <div>Prefect Server GraphQL endpoint:</div>\n        <v-text-field\n          v-model=\"urlInput\"\n          class=\"text-h5 mx-2\"\n          outlined\n          dense\n          hide-details\n          :placeholder=\"serverUrl || 'http://localhost:4200/graphql'\"\n          :style=\"{ 'max-width': '500px' }\"\n          :disabled=\"loading\"\n          @keyup=\"_handleKeyup\"\n        >\n          <template #append>\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <div class=\"mb-2\">\n                  <v-fade-transition mode=\"out-in\">\n                    <v-icon v-if=\"success\" key=\"success\" color=\"green\">\n                      check\n                    </v-icon>\n                    <v-icon v-else-if=\"error\" key=\"error\" color=\"error\">\n                      error\n                    </v-icon>\n                  </v-fade-transition>\n\n                  <v-btn\n                    color=\"blue-grey lighten-1\"\n                    icon\n                    small\n                    @click=\"_resetUrl\"\n                    v-on=\"on\"\n                  >\n                    <v-icon key=\"reset\" color=\"grey\">\n                      settings_backup_restore\n                    </v-icon>\n                  </v-btn>\n                </div>\n              </template>\n              <span>\n                Reset stored GraphQL endpoint\n              </span>\n            </v-tooltip>\n          </template>\n\n          <template #append-outer>\n            <div>\n              <v-btn\n                color=\"primary\"\n                dark\n                small\n                depressed\n                :loading=\"loading\"\n                @click=\"_testUrl\"\n              >\n                Connect\n              </v-btn>\n            </div>\n          </template>\n        </v-text-field>\n      </div>\n\n      <div class=\"text-body-1 mt-2\">\n        ...or by setting <kbd>apollo_url</kbd> in\n        <kbd>./prefect/config.toml</kbd> on whatever machine you're running\n        Prefect Server:\n      </div>\n      <div\n        class=\"text-body-1 grey lighten-5 blue-grey--text text--darken-2 rounded-sm pa-3 mt-4\"\n        style=\"border: 1px solid var(--v-utilGrayLight-base) !important;\"\n      >\n        <div class=\"code-block\">\n          <pre>\n[server]\n  [server.ui]\n    apollo_url=\"http://localhost:4200/graphql\"\n          </pre>\n        </div>\n      </div>\n      <div class=\"text-body-1 mt-2\">\n        Note: The second method will change the default Apollo endpoint but can\n        still be overidden by the input box above.\n      </div>\n\n      <v-scroll-y-transition mode=\"out-in\">\n        <div v-if=\"success\" key=\"success\" class=\"success--text mt-2\">\n          Success! You've successfully connected to your Prefect Server.\n        </div>\n        <div v-else-if=\"error\" key=\"error\" class=\"error--text mt-2\">\n          Oops! It looks like something went wrong when trying to connect; make\n          sure Prefect Server is running at the URL above and try again.\n        </div>\n      </v-scroll-y-transition>\n    </ol>\n\n    <ol class=\"mt-12\">\n      <li value=\"3\" class=\"text-h6 mt-6 mb-2\">Register an Agent</li>\n      <div class=\"text-body-1\">\n        Next you'll want to connect an\n        <ExternalLink\n          href=\"https://docs.prefect.io/orchestration/agents/overview.html\"\n        >\n          Agent </ExternalLink\n        >, which is responsible for executing your workflows.\n      </div>\n    </ol>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n/* stylelint-disable-next-line */\n.v-input__append-inner {\n  margin-top: 0 !important;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Integrations/PagerDuty.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport DictInput from '@/components/CustomInputs/DictInput2'\nimport { formatJson } from '@/utils/json'\n\nexport default {\n  components: { DictInput },\n  props: {\n    pdData: {\n      type: String,\n      default: null\n    }\n  },\n  data() {\n    return {\n      // Table headers\n      headers: [\n        {\n          mobile: true,\n          text: 'Name',\n          value: 'name',\n          width: '25%'\n        },\n        {\n          mobile: false,\n          text: 'Type',\n          value: 'action_type',\n          align: 'left',\n          width: '25%'\n        },\n        {\n          mobile: false,\n          text: 'Action ID',\n          value: 'id',\n          align: 'center',\n          width: '25%'\n        }\n      ],\n      integrationKeys: [...JSON.parse(this.pdData).integration_keys],\n      successIds: [],\n      account: JSON.parse(this.pdData).account,\n      saving: false,\n      enableSave: false,\n      actionConfig: null,\n      actionConfigArray: [],\n      routingKey: '',\n      severity: 'info',\n      severityLevels: [\n        { text: 'Info', value: 'info' },\n        { text: 'Warning', value: 'warning' },\n        { text: 'Error', value: 'error' },\n        { text: 'Critical', value: 'critical' }\n      ],\n      menu: false,\n      errorMessage: '',\n      loading: 0,\n      rules: [\n        val => {\n          return !!val || 'Required'\n        }\n      ]\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('user', ['user']),\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return this.hasPermission('create', 'hook')\n    },\n    headersByViewport() {\n      return this.$vuetify.breakpoint.mdAndUp\n        ? this.headers\n        : this.headers.filter(header => header.mobile)\n    },\n    loadingTable() {\n      return this.loading > 0\n    },\n    allowSave() {\n      return this.integrationKeys.every(\n        key => !!key.integration_key && !!key.severity\n      )\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    addKey() {\n      this.integrationKeys.push({\n        name: '',\n        integration_key: '',\n        severity: 'Info'\n      })\n    },\n    pluralize(count, word) {\n      if (count === 1) return word\n      return `${word}s`\n    },\n    createAllConfigs() {\n      this.integrationKeys.forEach(key => {\n        this.saveConfig(key)\n      })\n    },\n    saveConfig(item) {\n      this.saving = true\n      this.actionConfig = {\n        routing_key: item.integration_key,\n        severity: item.severity\n      }\n      let config = {\n        pagerduty_notification: this.actionConfig\n      }\n      const name = item.name\n      const input = { name: name, config }\n      this.createAction(input)\n    },\n    formatItemValue(item) {\n      return formatJson(item?.action_config)\n    },\n    async createAction(input) {\n      let success\n      try {\n        success = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-action.gql'),\n          variables: {\n            input: { config: input.config, name: input.name }\n          }\n        })\n      } catch (error) {\n        const errString = `${error}`\n        this.setAlert({\n          alertShow: true,\n          alertMessage: errString,\n          alertType: 'error'\n        })\n      } finally {\n        this.saving = false\n        if (success?.data?.create_action?.id) {\n          this.successIds.push(success?.data?.create_action?.id)\n        }\n      }\n    },\n    deleteItemFromList(item, index) {\n      this.integrationKeys.splice(index, 1)\n    }\n  },\n  apollo: {\n    actions: {\n      query: require('@/graphql/Integrations/PagerDutyActions.gql'),\n      update: data => data.actions,\n      variables() {\n        return {\n          includeIds: this.successIds\n        }\n      },\n      loadingKey: 'loading',\n      error() {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to fetch your actions. Please try again later.'\n        )\n      },\n      fetchPolicy: 'no-cache'\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"ma-8 pa-4 pdcard\" max-height=\"60vh\">\n    <v-card-text class=\"text-h4 font-weight-light\">\n      <v-row class=\"pt-2\">\n        <v-col cols=\"9\" lg=\"10\">\n          <v-icon :style=\"{ 'max-height': '30px' }\" size=\"150\" class=\"pdicon\"\n            >$newPagerDuty</v-icon\n          >\n        </v-col>\n        <v-col cols=\"3\" lg=\"2\" class=\"text-right\">\n          <v-btn\n            v-if=\"!successIds.length && permissionsCheck\"\n            color=\"primary\"\n            :disabled=\"!allowSave\"\n            elevation=\"0\"\n            :loading=\"saving\"\n            @click=\"createAllConfigs\"\n            ><span style=\"text-transform: none;\">Save</span></v-btn\n          ></v-col\n        >\n      </v-row>\n    </v-card-text>\n    <v-card-text>\n      <div class=\"mb-4\">\n        <span>\n          Create an action to use with Prefect Automations and the Pager Duty\n          <a\n            href=\"https://support.pagerduty.com/docs/services-and-integrations\"\n            target=\"_blank\"\n            >Events API v2</a\n          >.\n        </span>\n      </div>\n      <div v-if=\"!integrationKeys || !integrationKeys.length\">\n        <div\n          class=\"text-center position-absolute center-absolute text-h5 utilGrayDark--text mt-10\"\n          :style=\"{ 'z-index': 1, width: '100%' }\"\n        >\n          No integration keys\n        </div>\n      </div>\n      <div\n        v-else-if=\"\n          integrationKeys && integrationKeys.length === successIds.length\n        \"\n        class=\"text-center\"\n      >\n        <v-data-table\n          fixed-header\n          :headers=\"headersByViewport\"\n          :items=\"actions\"\n          :items-per-page=\"10\"\n          show-expand\n          hide-default-footer\n          :loading=\"loadingTable || !actions || !actions.length\"\n          class=\"elevation-0\"\n          :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n          :footer-props=\"{\n            showFirstLastPage: true,\n            itemsPerPageOptions: [10, 15, 20, -1],\n            firstIcon: 'first_page',\n            lastIcon: 'last_page',\n            prevIcon: 'keyboard_arrow_left',\n            nextIcon: 'keyboard_arrow_right'\n          }\"\n          no-data-text=\"No actions.\"\n        >\n          <!-- ACTION ID-->\n          <template #item.id=\"{ item }\">\n            {{ item.id }}\n          </template>\n\n          <!-- ACTION NAME -->\n          <template #item.name=\"{ item }\">\n            <div class=\"hidewidth\">\n              {{ item.name }}\n            </div>\n          </template>\n\n          <template #item.type=\"{ item }\">\n            {{ item.action_type }}\n          </template>\n\n          <!-- ACTION CONFIG -->\n          <template #expanded-item=\"{ headers, item }\">\n            <td\n              v-if=\"Object.keys(item.action_config).length\"\n              :colspan=\"headers.length\"\n            >\n              <dict-input\n                v-if=\"Object.keys(item.action_config).length\"\n                class=\"mt-3\"\n                readonly-key\n                readonly-value\n                disable-add\n                disable-remove\n                :value=\"formatItemValue(item)\"\n              />\n            </td>\n            <td v-else :colspan=\"headers.length\">\n              No action config\n            </td>\n          </template>\n        </v-data-table>\n\n        <div class=\"mt-6\" align=\"center\" justify=\"center\">\n          <v-btn color=\"primary\" outlined class=\"mr-4\" :to=\"{ name: 'actions' }\"\n            >Manage Actions</v-btn\n          >\n          <v-btn\n            color=\"primary\"\n            :to=\"{\n              path: `/${tenant.slug}?automations=`\n            }\"\n            >Create Automation</v-btn\n          >\n        </div>\n      </div>\n      <div v-else>\n        <v-row\n          v-for=\"(key, index) in integrationKeys\"\n          :key=\"index\"\n          class=\"mt-2\"\n        >\n          <v-col cols=\"12\" md=\"3\">\n            <v-select\n              data-public\n              v-model=\"key.severity\"\n              :items=\"severityLevels\"\n              outlined\n              :rules=\"rules\"\n              label=\"Severity\"\n            />\n          </v-col>\n          <v-col cols=\"12\" md=\"4\">\n            <v-text-field\n              v-model=\"key.integration_key\"\n              :rules=\"rules\"\n              label=\"Integration Key\"\n              outlined\n            />\n          </v-col>\n          <v-col cols=\"12\" md=\"4\">\n            <v-text-field v-model=\"key.name\" label=\"Action Name\" outlined />\n          </v-col>\n          <v-col cols=\"12\" md=\"1\">\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  class=\"mt-3\"\n                  text\n                  fab\n                  small\n                  color=\"error\"\n                  v-on=\"on\"\n                  @click=\"deleteItemFromList(key, index)\"\n                >\n                  <v-icon>delete</v-icon>\n                </v-btn>\n              </template>\n              Remove action\n            </v-tooltip>\n          </v-col>\n        </v-row>\n\n        <div class=\"text-center\">\n          <v-btn\n            class=\"mx-auto px-8 text-none\"\n            depressed\n            text\n            color=\"primary\"\n            @click=\"addKey\"\n          >\n            Add Action\n            <v-icon right>\n              add\n            </v-icon>\n          </v-btn>\n        </div>\n      </div>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style scoped>\n.pdcard {\n  overflow: auto;\n}\n</style>\n\n<style lang=\"scss\" scoped></style>\n"
  },
  {
    "path": "src/pages/InteractiveAPI/InteractiveAPI.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport gql from 'graphql-tag'\nimport { print } from 'graphql'\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport GraphiQL from 'graphiql'\n\nexport default {\n  data() {\n    return {\n      defaultQuery:\n        this.role === 'READ_ONLY_USER'\n          ? 'Sorry, this page is not available to Read-only users.'\n          : `# Enter your query or mutation here\n# Example:\n\nquery { hello }\n\n# Queries are limited to 100 results, inline query limits under 100 will be respected\n# To paginate results, add the 'offset' argument`,\n      readOnly: this.role === 'READ_ONLY_USER',\n      queriesWithoutLimits: [\n        'agent',\n        'agents',\n        '_aggregate',\n        'api',\n        'auth_info',\n        'authInfo',\n        // *_by_pk queries are helper queries that don't have offset and limit\n        // arguments since by their nature they return just 1 result using a\n        // UUID!\n        '_by_pk',\n        'hello',\n        'preview_invoice',\n        'reference',\n        'reference_data',\n        'task_tag_limit',\n        'taskTagUsage',\n        'task_tag_usage',\n        'mapped_children',\n        'permissions_info',\n        'secretNames',\n        'secret_names',\n        'secretValue',\n        'secret_value',\n        'users'\n      ]\n    }\n  },\n  computed: {\n    ...mapGetters('auth', ['authorizationToken']),\n    ...mapGetters('api', ['url']),\n    ...mapGetters('tenant', ['role'])\n  },\n  async mounted() {\n    let urlQuery\n    if (this.$route.query.query) {\n      urlQuery = print(gql`\n        ${this.$route.query.query}\n      `)\n    }\n    const fetcher = params => {\n      params.query = this.addQueryLimits(params.query)\n      return fetch(this.url, {\n        method: 'post',\n        headers: {\n          'Content-Type': 'application/json',\n          authorization: `Bearer ${this.authorizationToken}`,\n          'X-Prefect-Interactive-API': 'true'\n        },\n        body: JSON.stringify(params)\n      }).then(res => {\n        return res.json()\n      })\n    }\n    const encodeComponent = component => {\n      return encodeURIComponent(component)\n        .replace(/'/g, '%27')\n        .replace(/\"/g, '%22')\n    }\n    const encodeQuery = query => {\n      let variables = ''\n      if (this.$router.history.current.query.variables) {\n        variables =\n          '&variables=' +\n          encodeComponent(this.$router.history.current.query.variables)\n      }\n      return this.$router.push('?query=' + encodeComponent(query) + variables)\n    }\n    const encodeVariables = vars => {\n      let query = '?query='\n      if (this.$router.history.current.query.query) {\n        query += encodeComponent(this.$router.history.current.query.query)\n      }\n      return this.$router.push(query + '&variables=' + encodeComponent(vars))\n    }\n    /* eslint-disable no-undef */\n    ReactDOM.render(\n      React.createElement(GraphiQL, {\n        fetcher,\n        query: urlQuery,\n        defaultQuery: this.defaultQuery,\n        readOnly: this.readOnly,\n        onEditQuery: encodeQuery,\n        onEditVariables: encodeVariables\n      }),\n      /* eslint-enable no-undef */\n      document.getElementById('graphiql')\n    )\n  },\n  methods: {\n    addQueryLimits(query) {\n      if (query.includes('IntrospectionQuery')) return query\n      const queryObject = gql`\n        ${query}\n      `\n\n      // Mutations don't need to be limited (and also limits are supported on mutations)\n      if (queryObject.definitions?.[0]?.operation == 'mutation') return query\n\n      queryObject.definitions[0].selectionSet.selections.forEach(selection => {\n        // Exclude queries that do not support limiting\n        let exclude = false\n        this.queriesWithoutLimits.forEach(query => {\n          exclude = selection.name.value.includes(query) ? true : exclude\n        })\n\n        if (exclude) return\n\n        let limitArg = {\n          kind: 'Argument',\n          manual: true,\n          name: { kind: 'Name', value: 'limit' },\n          value: {\n            kind: 'IntValue',\n            value: 100\n          }\n        }\n\n        let limitIndex = selection.arguments.findIndex(\n          arg => arg.name.value == 'limit'\n        )\n\n        if (\n          limitIndex > -1 &&\n          selection.arguments[limitIndex].value.value > 100\n        ) {\n          selection.arguments[limitIndex] = limitArg\n        } else if (limitIndex == -1) {\n          selection.arguments.push(limitArg)\n        }\n      })\n\n      return print(queryObject)\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    id=\"graphiql\"\n    style=\"height: calc(100vh - 64px);\n    padding-bottom: 0;\"\n  ></div>\n</template>\n\n<style lang=\"scss\">\n@import '../../styles/graphiql.css';\n$toolbar-black: var(--v-appBackground-base);\n$divider-gray: var(--v-appForeground-base);\n$brackets-gray: var(--v-utilGrayMid-base);\n/* stylelint-disable selector-class-pattern */\n/* since we're not writing these class names, we can't abide by stylelint's naming rules */\n.CodeMirror-info {\n  // this popover isn't technically inside the container\n  background: $divider-gray;\n\n  .info-description {\n    color: var(--v-utilGrayDark-base);\n  }\n\n  .type-name {\n    color: var(--v-accentCyan-base);\n  }\n\n  .field-name {\n    color: var(--v-accentOrange-base);\n  }\n}\n\n.graphiql-container {\n  /* overall styles */\n  .CodeMirror {\n    background: var(--v-appForeground-base) !important;\n  }\n\n  .CodeMirror-cursor {\n    border-left: 1px solid $brackets-gray;\n  }\n\n  .CodeMirror-hints {\n    background: $divider-gray;\n\n    /* stylelint-disable-next-line selector-max-compound-selectors */\n    .CodeMirror-hint,\n    .CodeMirror-hint-information .content {\n      color: var(--v-utilGrayDark-base);\n    }\n  }\n\n  .CodeMirror-gutters,\n  .result-window .CodeMirror-gutters,\n  .resultWrap,\n  .secondary-editor-title {\n    background: $toolbar-black;\n    border: 0;\n    color: var(--v-utilGrayDark-base);\n  }\n\n  .secondary-editor {\n    height: 28px;\n  }\n\n  .secondary-editor-title > div {\n    color: var(--v-utilGrayDark-base) !important;\n  }\n\n  button,\n  input {\n    color: var(--v-utilGrayDark-base);\n  }\n  /* History and Documentation sidebars */\n  .historyPaneWrap {\n    z-index: 4 !important; // keeps history panel under sidenav\n  }\n\n  .doc-explorer-title-bar,\n  .history-title-bar {\n    background: $toolbar-black;\n    color: var(--v-utilGrayDark-base);\n    height: 40px;\n    padding: 0 8px;\n\n    .history-title,\n    .doc-explorer-title {\n      margin-top: 14px;\n      overflow: hidden;\n      padding: 0 0 0 10px;\n    }\n\n    .docExplorerHide {\n      padding-top: 22px;\n    }\n  }\n\n  .doc-category-title {\n    border-bottom: 1px solid $divider-gray;\n  }\n\n  .history-contents,\n  .doc-explorer-contents {\n    background: $toolbar-black;\n    border-top: 2px solid $divider-gray;\n    color: var(--v-utilGrayDark-base);\n    top: 40px;\n  }\n\n  .history-contents li {\n    border-bottom: 1px solid $divider-gray;\n\n    &:hover,\n    &:focus {\n      background: var(--v-accentPink-base);\n    }\n\n    /* stylelint-disable-next-line selector-max-compound-selectors */\n    button:not(.history-label) {\n      font-size: 20px;\n    }\n  }\n\n  .search-box {\n    input {\n      padding: 6px 24px;\n    }\n\n    .search-box-clear {\n      background: $divider-gray;\n    }\n  }\n\n  .doc-category {\n    * {\n      color: $brackets-gray;\n    }\n\n    /* stylelint-disable-next-line selector-max-compound-selectors */\n    .doc-category-title,\n    .field-short-description > * {\n      color: var(--v-utilGrayDark-base);\n    }\n\n    .field-name {\n      color: var(--v-accentCyan-base);\n    }\n\n    .arg-name {\n      color: var(--v-accentOrange-base);\n    }\n\n    .type-name {\n      color: var(--v-codeBlue-base);\n    }\n  }\n\n  /* Top nav */\n  .topBar {\n    background: $toolbar-black;\n    border-bottom: 2px solid $divider-gray;\n    height: 42px;\n\n    /* stylelint-disable-next-line a11y/no-display-none */\n    .title {\n      display: none;\n    }\n\n    .execute-button {\n      background: var(--v-accentPink-base);\n      border: 0;\n      box-shadow: none;\n      height: 32px;\n      width: 32px;\n      /* stylelint-disable-next-line selector-max-compound-selectors */\n      * {\n        fill: var(--v-secondaryGrayLight-base);\n      }\n      /* stylelint-disable-next-line a11y/no-outline-none */\n      &:focus {\n        box-shadow: 0 0 4px 3px var(--v-primary-base);\n        outline: none;\n      }\n    }\n\n    .toolbar-button {\n      background: $divider-gray;\n      box-shadow: none;\n      color: var(--v-utilGrayDark-base);\n      padding: 2px 8px;\n    }\n  }\n\n  .docExplorerShow {\n    background: $divider-gray;\n    border: 0;\n    box-shadow: none;\n    color: var(--v-utilGrayDark-base);\n    padding: 2px 8px;\n\n    &::before {\n      border-left: 2px solid var(--v-utilGrayDark-base);\n      border-top: 2px solid var(--v-utilGrayDark-base);\n    }\n  }\n\n  .doc-explorer-back {\n    background: $divider-gray;\n    border-radius: 3px;\n    color: var(--v-utilGrayDark-base);\n    height: 25px;\n    margin: 8px 0 0;\n    overflow: hidden;\n    padding: 2px 8px;\n\n    &::before {\n      border-left: 2px solid var(--v-utilGrayDark-base);\n      border-top: 2px solid var(--v-utilGrayDark-base);\n    }\n  }\n  /* code colors */\n  .cm-keyword,\n  .cm-def {\n    color: var(--v-codePink-base);\n  }\n\n  .cm-property {\n    color: var(--v-codeBlue-base);\n  }\n\n  .cm-string {\n    color: var(--v-accentOrange-base);\n  }\n\n  .cm-variable,\n  .cm-attribute {\n    color: var(--v-accentOrange-base);\n  }\n\n  .cm-punctuation,\n  .cm-ws {\n    color: $brackets-gray;\n  }\n  /* scrollbar styling */\n  ::-webkit-scrollbar-thumb {\n    background: radial-gradient($divider-gray, var(--v-appForeground-darken2));\n    border-radius: 6px;\n  }\n\n  ::-webkit-scrollbar-track,\n  .CodeMirror-vscrollbar,\n  .CodeMirror-hscrollbar {\n    background-color: transparent;\n    scrollbar-color: transparent;\n  }\n\n  ::-webkit-scrollbar {\n    background-color: transparent;\n    width: 10px;\n  }\n\n  /* stylelint-disable-next-line a11y/no-display-none */\n  ::-webkit-scrollbar-button {\n    display: none;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/NotFoundPage.vue",
    "content": "<template>\n  <div\n    class=\"not-found-page\"\n    :class=\"{\n      small: $vuetify.breakpoint.sm,\n      med: $vuetify.breakpoint.mdAndUp,\n      mobile: $vuetify.breakpoint.xs\n    }\"\n  >\n    <div class=\"text\">\n      <h1>Oh no!</h1>\n      <p>\n        This page seems to have gone missing.<br />\n        Sorry for disrupting your <em>flow</em>.\n      </p>\n\n      <v-btn text dark @click=\"$router.push({ name: 'dashboard' })\">\n        <v-icon>arrow_back_ios</v-icon>\n        Back to dashboard\n      </v-btn>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\ni {\n  text-decoration: none;\n}\n\n.not-found-page {\n  background-color: var(--v-primary-base) !important;\n  background-image: url('../assets/backgrounds/not-found.svg') !important;\n  background-position: left !important;\n  background-repeat: no-repeat !important;\n  background-size: cover !important;\n  color: var(--v-cloudUIPrimaryLight-base);\n  height: 100vh;\n\n  .text {\n    position: fixed;\n    top: 15%;\n  }\n\n  &.small {\n    .text {\n      left: 25%;\n    }\n  }\n\n  &.med {\n    .text {\n      left: 20%;\n    }\n  }\n\n  &.mobile {\n    .text {\n      left: 5%;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Notifications/NotificationGroup.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport moment from 'moment-timezone'\nimport FlowRunNotification from '@/pages/Notifications/NotificationTypes/FlowRun-Notification'\nimport MembershipNotification from '@/pages/Notifications/NotificationTypes/Membership-Notification'\nimport ApprovalNotification from '@/pages/Notifications/NotificationTypes/Approval-Notification'\nimport WhatsNewNotification from '@/pages/Notifications/NotificationTypes/WhatsNew-Notification'\nimport MessageNotification from '@/pages/Notifications/NotificationTypes/Message-Notification'\n\nimport {\n  componentMap,\n  iconMap,\n  iconColorMap,\n  navigationMap\n} from '@/pages/Notifications/utils'\n\nexport default {\n  components: {\n    ApprovalNotification,\n    FlowRunNotification,\n    MembershipNotification,\n    MessageNotification,\n    WhatsNewNotification\n  },\n  props: {\n    read: {\n      type: [Boolean, Number],\n      required: true\n    },\n    tenant: {\n      type: Object,\n      required: false,\n      default: () => {\n        return { id: null, name: 'Your notifications' }\n      }\n    },\n    updateKey: {\n      type: Number,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      limit: 15,\n      loading: 0,\n      page: 1,\n      selected: []\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone']),\n    ...mapGetters('api', ['isCloud']),\n    _allSelected() {\n      let selectedIds = this.selected.map(s => s.sid)\n      return this.notifications?.every(n => selectedIds.includes(n.id))\n    },\n    _noneSelected() {\n      return this.selected.length === 0\n    },\n    _someSelected() {\n      return (\n        this.selected.length > 0 &&\n        this.selected.length < this.notifications?.length\n      )\n    },\n    _selected() {\n      if (this._allSelected) return 'all'\n      if (this._someSelected) return 'some'\n      return 'none'\n    },\n    pages() {\n      return Math.ceil(this.notificationsCount / this.limit)\n    },\n    where() {\n      let where = {\n        tenant_id: { _eq: this.tenant?.id }\n      }\n\n      if (this.tenant.id === 'user-notifications') {\n        where.tenant_id = {\n          _is_null: true\n        }\n      }\n\n      if (this.read !== 0) {\n        where.read = { _eq: this.read }\n      }\n      return where\n    }\n  },\n  watch: {\n    loading(current, previous) {\n      this.$emit('loading', current - previous)\n    },\n    notificationsCount(val) {\n      this.$emit('count', { id: this.tenant.id, count: val })\n    },\n    page() {\n      this.$emit('remove', [...this.selected])\n      this.selected = []\n    },\n    updateKey() {\n      this.page = 1\n      this.selected = []\n      this.$apollo.queries.notifications.refetch()\n      this.$apollo.queries.notificationsCount.refetch()\n    }\n  },\n  methods: {\n    active(sid) {\n      return this.selected.findIndex(s => s.sid === sid) > -1\n    },\n    formatDateTime(timestamp) {\n      if (!timestamp) throw new Error('Did not recieve a timestamp')\n\n      let t = moment(timestamp).tz(this.timezone),\n        shortenedTz = moment()\n          .tz(this.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone)\n          .zoneAbbr()\n\n      let timeObj = t ? t : moment(timestamp)\n\n      let formatted = timeObj.calendar(null, {\n        sameDay: 'h:mma',\n        sameElse: 'MMMM D, YYYY [at] h:mma'\n      })\n      return `${formatted} ${shortenedTz}`\n    },\n    handleSelectAll() {\n      if (this._allSelected) {\n        this.$emit('remove', [...this.selected])\n        this.selected = []\n      } else {\n        this.selected = this.notifications.map(n => {\n          let obj = {}\n          obj.sid = n.id\n          obj.read = n.read\n          return obj\n        })\n        this.$emit('add', [...this.selected])\n      }\n    },\n    notificationComponent(type) {\n      return componentMap[type]\n    },\n    notificationIcon(type) {\n      return iconMap[type]\n    },\n    notificationIconColor(type, n) {\n      return iconColorMap[type](n)\n    },\n    notificationNavigation(notification) {\n      return navigationMap[notification.type](notification, this.tenant)\n    },\n    async selectAllNoLimit() {\n      this.loading++\n      const { data } = await this.$apollo.query({\n        query: require('@/graphql/Notifications/all-notifications.gql'),\n        variables: {\n          where: this.where\n        }\n      })\n      this.selected = data.notifications.map(n => {\n        let obj = {}\n        obj.sid = n.id\n        obj.read = n.read\n        return obj\n      })\n      this.$emit('add', [...this.selected])\n\n      this.loading--\n    },\n    updateSelected(sid, read) {\n      let j = this.selected.findIndex(s => s.sid === sid)\n      if (j > -1) {\n        let obj = this.selected[j]\n        this.selected.splice(j, 1)\n        this.$emit('remove', [obj])\n      } else {\n        let obj = {}\n        obj.sid = sid\n        obj.read = read\n        this.selected.push(obj)\n        this.$emit('add', [obj])\n      }\n    }\n  },\n  apollo: {\n    notifications: {\n      query() {\n        return require('@/graphql/Notifications/notifications.js').default(\n          this.isCloud\n        )\n      },\n      variables() {\n        return {\n          limit: this.limit,\n          offset: this.limit * (this.page - 1),\n          orderBy: { created: 'desc' },\n          where: this.where\n        }\n      },\n      loadingKey: 'loading',\n      update: data => data.notifications,\n      pollInterval: 5000,\n      fetchPolicy: 'network-only'\n    },\n    notificationsCount: {\n      query: require('@/graphql/Notifications/notifications-count.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {\n          where: this.where\n        }\n      },\n      update: data => data?.message_aggregate?.aggregate?.count,\n      pollInterval: 5000,\n      fetchPolicy: 'network-only'\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-show=\"notificationsCount > 0\" class=\"mb-4 py-2 px-4\" tile>\n    <v-card-title class=\"pl-1 text-subtitle-2 grey--text text--darken-2\">\n      {{ tenant.name }}\n    </v-card-title>\n\n    <v-divider />\n\n    <div class=\"d-flex align-center justify-start mt-6 mb-2\">\n      <v-checkbox\n        v-if=\"notifications && notifications.length > 0\"\n        class=\"ml-4 py-0 my-0\"\n        hide-details\n        :disabled=\"loading > 0\"\n        :label=\"\n          selected.length === 0 ? 'Select all' : `${selected.length} Selected`\n        \"\n        :input-value=\"_selected\"\n        true-value=\"all\"\n        false-value=\"none\"\n        :indeterminate=\"_someSelected\"\n        @click.stop=\"handleSelectAll\"\n      />\n\n      <v-btn\n        v-if=\"pages > 1\"\n        class=\"ml-4\"\n        small\n        depressed\n        text\n        @click=\"selectAllNoLimit\"\n      >\n        Select all {{ notificationsCount }} notifications\n      </v-btn>\n    </div>\n\n    <v-card-text class=\"pt-0\">\n      <v-list data-cy=\"notifications-list\">\n        <template v-for=\"(n, i) in notifications\">\n          <v-list-item\n            :key=\"n.id\"\n            class=\"px-0 position-relative\"\n            :class=\"n.read ? 'o-60 hover-o-100' : ''\"\n            :disabled=\"loading > 0\"\n            :to=\"notificationNavigation(n)\"\n            exact\n          >\n            <v-icon\n              v-if=\"!n.read\"\n              class=\"notification-badge\"\n              color=\"codePink\"\n              x-small\n            >\n              fiber_manual_record\n            </v-icon>\n\n            <v-list-item-action\n              class=\"cursor-pointer mr-0 my-0 o-100\"\n              style=\"height: 58px;\"\n              @click.prevent=\"updateSelected(n.id, n.read)\"\n              @mousedown.stop\n            >\n              <v-icon :color=\"active(n.id) ? 'primary' : 'grey'\">\n                {{ active(n.id) ? 'check_box' : 'check_box_outline_blank' }}\n              </v-icon>\n            </v-list-item-action>\n\n            <v-list-item-avatar class=\"mx-2 pa-0\">\n              <v-icon :color=\"notificationIconColor(n.type, n)\">\n                {{ n.content.icon ? n.content.icon : notificationIcon(n.type) }}\n              </v-icon>\n            </v-list-item-avatar>\n\n            <component\n              :is=\"notificationComponent(n.type)\"\n              :content=\"n.content\"\n              :read=\"n.read\"\n            />\n\n            <v-list-item-action class=\"o-100\">\n              <v-list-item-action-text>\n                {{ formatDateTime(n.created) }}\n              </v-list-item-action-text>\n            </v-list-item-action>\n          </v-list-item>\n          <v-divider v-if=\"i + 1 < notifications.length\" :key=\"i\"></v-divider>\n        </template>\n      </v-list>\n\n      <v-pagination\n        v-if=\"\n          notifications &&\n            notifications.length > 0 &&\n            notificationsCount > limit\n        \"\n        v-model=\"page\"\n        :length=\"pages\"\n        class=\"mt-4\"\n        total-visible=\"6\"\n      />\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.notification-badge {\n  left: -20px;\n  position: absolute;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Notifications/NotificationTypes/Approval-Notification.vue",
    "content": "<script>\nexport default {\n  props: {\n    content: {\n      type: Object,\n      required: true\n    },\n    dense: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    timestamp: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  computed: {\n    itemTitle() {\n      return `${this.task?.flow?.name} has a\n          paused run that requires approval to resume.`\n    }\n  },\n  apollo: {\n    task: {\n      query: require('@/graphql/Task/task.gql'),\n      variables() {\n        return {\n          id: this.content.task_run.task_id\n        }\n      },\n      loadingKey: 'loading',\n      update: data => data?.task_by_pk\n    }\n  }\n}\n</script>\n\n<template>\n  <v-list-item-content v-if=\"dense\">\n    <v-list-item-title>\n      <div v-if=\"task\">\n        <truncate :content=\"itemTitle\">\n          <span class=\"font-weight-medium\">{{ task.flow.name }}</span> has a\n          paused run that requires approval to resume.\n        </truncate>\n      </div>\n      <div v-else>\n        <v-skeleton-loader type=\"heading\" tile></v-skeleton-loader>\n      </div>\n    </v-list-item-title>\n    <v-list-item-subtitle v-if=\"timestamp\">\n      {{ timestamp }}\n    </v-list-item-subtitle>\n  </v-list-item-content>\n\n  <v-list-item-content v-else>\n    <v-list-item-title>\n      <div v-if=\"task\">\n        <span class=\"font-weight-medium\">{{ task.name }}</span> is paused and\n        requires approval to resume.\n      </div>\n      <div v-else>\n        <v-skeleton-loader type=\"heading\" tile></v-skeleton-loader>\n      </div>\n    </v-list-item-title>\n    <v-list-item-subtitle v-if=\"task\">\n      {{ task.flow.name }}\n    </v-list-item-subtitle>\n  </v-list-item-content>\n</template>\n"
  },
  {
    "path": "src/pages/Notifications/NotificationTypes/FlowRun-Notification.vue",
    "content": "<script>\nexport default {\n  props: {\n    content: {\n      type: Object,\n      required: true\n    },\n    dense: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    timestamp: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  computed: {\n    stateClass() {\n      const lightStates = [\n        'Submitted',\n        'Cancelled',\n        'Cancelling',\n        'Queued',\n        'Pending'\n      ]\n\n      const textColor = lightStates.includes(this.content.event.state)\n        ? 'black--text'\n        : 'white--text'\n\n      return [this.content.event.state, textColor]\n    },\n    itemTitle() {\n      return ` ${this.content.event.flow.name}: ${this.content.event.state}`\n    }\n  }\n}\n</script>\n\n<template>\n  <v-list-item-content v-if=\"dense\">\n    <v-list-item-title>\n      <truncate :content=\"itemTitle\">\n        {{ content.event.flow.name }}:\n        <span\n          :class=\"{\n            [content.event.state]: true,\n            'white--text': content.event.state !== 'Submitted'\n          }\"\n          class=\"px-2 rounded-pill d-inline-block text-body-2\"\n        >\n          {{ content.event.state }}\n        </span>\n      </truncate>\n    </v-list-item-title>\n    <v-list-item-subtitle v-if=\"timestamp\">\n      {{ timestamp }}\n    </v-list-item-subtitle>\n  </v-list-item-content>\n\n  <v-list-item-content v-else>\n    <v-list-item-title>\n      {{ content.event.flow.name }}\n    </v-list-item-title>\n    <v-list-item-subtitle>\n      Entered a new state: {{ content.event.state }}\n    </v-list-item-subtitle>\n  </v-list-item-content>\n</template>\n"
  },
  {
    "path": "src/pages/Notifications/NotificationTypes/Membership-Notification.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport AcceptConfirmInputRow from '@/components/AcceptConfirmInputRow'\nimport { handleMembershipInvitations } from '@/mixins/membershipInvitationMixin'\n\nexport default {\n  components: { AcceptConfirmInputRow },\n  mixins: [handleMembershipInvitations],\n  props: {\n    content: {\n      type: Object,\n      required: true\n    },\n    dense: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    timestamp: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      loading: 0,\n      tempMember: false,\n      tempDecline: false\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['memberships']),\n    isMember() {\n      return this.membershipTeamIds.includes(this.content.sender_tenant_id)\n    },\n    membershipTeamIds() {\n      return this.memberships.map(m => m.tenant.id)\n    },\n    membershipInvitationIsValid() {\n      return this.membershipInvitation\n    },\n    itemTitle() {\n      return this.tempMember || this.isMember\n        ? `You joined ${this.content.sender_tenant_name}`\n        : !this.tempDecline &&\n          !this.isMember &&\n          this.membershipInvitationIsValid\n        ? `${this.content.sender_user_name} invited you to join ${this.content.sender_tenant_name}`\n        : `An invitation to join\n      ${this.content.sender_tenant_name}\n      has expired or was declined.`\n    },\n    rowLabel() {\n      return `\n      <span class=\"font-weight-medium\">${this.content.sender_user_name}</span>\n      invited you to join\n      <span class=\"font-weight-medium\">${this.content.sender_tenant_name}</span>\n      !\n      `\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    ...mapActions('user', ['getUser']),\n    async _acceptInvitation() {\n      this.loading++\n      let success\n      try {\n        const data = await this.acceptMembershipInvitation(\n          this.content.membership_invitation_id\n        )\n        if (data?.accept_membership_invitation) {\n          this.tempMember = true\n          success = true\n        }\n      } catch (e) {\n        success = false\n      } finally {\n        this.setAlert(\n          {\n            alertShow: true,\n            alertMessage: success\n              ? `You joined ${this.content.sender_tenant_name}... hurrah!`\n              : `Something went wrong trying to accept your invitation to ${this.content.sender_tenant_name}... please wait a few moments and try again.`,\n            alertType: success ? 'success' : 'error',\n            alertLink: success\n              ? {\n                  name: 'dashboard',\n                  params: { tenant: this.content.sender_tenant_slug }\n                }\n              : null,\n            linkText: success ? 'Take me to my new tenant!' : ''\n          },\n          3000\n        )\n        await this.getUser()\n        await this.$apollo.queries.membershipInvitation.refetch()\n        this.loading--\n      }\n    },\n    async _declineInvitation() {\n      this.loading++\n      let success\n      try {\n        const data = await this.declineMembershipInvitation(\n          this.content.membership_invitation_id\n        )\n        if (data?.delete_membership_invitation) {\n          this.tempDecline = true\n          success = true\n        }\n      } catch (e) {\n        success = false\n      } finally {\n        this.setAlert(\n          {\n            alertShow: true,\n            alertMessage: success\n              ? `Invitation to join ${this.content.sender_tenant_name} declined.`\n              : `Something went wrong trying to decline your invitation to ${this.content.sender_tenant_name}... please wait a few moments and try again.`,\n            alertType: success ? 'info' : 'error'\n          },\n          3000\n        )\n        this.getUser()\n        await this.$apollo.queries.membershipInvitation.refetch()\n        this.loading--\n      }\n    }\n  },\n  apollo: {\n    membershipInvitation: {\n      query: require('@/graphql/Notifications/membership-invitation.gql'),\n      variables() {\n        return {\n          id: this.content.membership_invitation_id\n        }\n      },\n      loadingKey: 'loading',\n      update: data => data.membership_invitation_by_pk\n    }\n  }\n}\n</script>\n\n<template>\n  <v-list-item-content>\n    <v-skeleton-loader v-if=\"loading > 0\" type=\"text\" tile />\n    <truncate v-else-if=\"dense\" :content=\"itemTitle\">\n      <v-list-item-title v-if=\"tempMember || isMember\">\n        You joined\n        <span class=\"font-weight-medium\">\n          {{ content.sender_tenant_name }}\n        </span>\n        !\n      </v-list-item-title>\n      <v-list-item-title\n        v-else-if=\"!tempDecline && !isMember && membershipInvitationIsValid\"\n      >\n        <AcceptConfirmInputRow\n          :label=\"rowLabel\"\n          :loading=\"loading > 0\"\n          @accept=\"_acceptInvitation\"\n          @decline=\"_declineInvitation\"\n        />\n      </v-list-item-title>\n      <v-list-item-title v-else>\n        An invitation to join\n        <span class=\"font-weight-medium\">{{ content.sender_tenant_name }}</span>\n        has expired or was declined.\n      </v-list-item-title>\n    </truncate>\n    <div v-else>\n      <v-list-item-title v-if=\"tempMember || isMember\">\n        You joined\n        <span class=\"font-weight-medium\">\n          {{ content.sender_tenant_name }}\n        </span>\n        !\n      </v-list-item-title>\n      <v-list-item-title\n        v-else-if=\"!tempDecline && !isMember && membershipInvitationIsValid\"\n      >\n        <AcceptConfirmInputRow\n          :label=\"rowLabel\"\n          :loading=\"loading > 0\"\n          @accept=\"_acceptInvitation\"\n          @decline=\"_declineInvitation\"\n        />\n      </v-list-item-title>\n      <v-list-item-title v-else>\n        An invitation to join\n        <span class=\"font-weight-medium\">{{ content.sender_tenant_name }}</span>\n        has expired or was declined.\n      </v-list-item-title>\n    </div>\n    <v-list-item-subtitle v-if=\"timestamp\">\n      {{ timestamp }}\n    </v-list-item-subtitle>\n  </v-list-item-content>\n</template>\n"
  },
  {
    "path": "src/pages/Notifications/NotificationTypes/Message-Notification.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nimport { parser } from '@/utils/markdownParser'\n\nexport default {\n  props: {\n    content: {\n      type: Object,\n      required: true\n    },\n    dense: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    timestamp: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      showDetails: false\n    }\n  },\n  computed: {\n    renderedContents() {\n      return parser(this.content.message)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-list-item-content v-if=\"dense\">\n    <v-list-item-title>\n      <truncate :content=\"content.title\">\n        {{ content.title }}\n      </truncate>\n    </v-list-item-title>\n    <v-list-item-subtitle v-if=\"timestamp\">\n      {{ timestamp }}\n    </v-list-item-subtitle>\n  </v-list-item-content>\n\n  <v-list-item-content v-else>\n    <v-list-item-title>\n      {{ content.title }}\n    </v-list-item-title>\n\n    <v-fade-transition origin=\"center bottom\" hide-on-leave mode=\"out-in\">\n      <div\n        v-if=\"showDetails\"\n        class=\"subtitle grey--text text--darken-1 pa-4\"\n        v-html=\"renderedContents\"\n      >\n      </div>\n    </v-fade-transition>\n    <span>\n      <a @click=\"showDetails = !showDetails\">\n        {{ showDetails ? 'Hide' : 'Show' }} details\n      </a>\n    </span>\n  </v-list-item-content>\n</template>\n"
  },
  {
    "path": "src/pages/Notifications/NotificationTypes/WhatsNew-Notification.vue",
    "content": "<script>\n/* eslint-disable vue/no-v-html */\nexport default {\n  props: {\n    content: {\n      type: Object,\n      required: true\n    },\n    dense: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    timestamp: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      readMore: false\n    }\n  },\n  computed: {\n    overflow() {\n      return this.content.body?.length > 300\n    }\n  },\n  methods: {\n    decodeHTML(str) {\n      let textArea = document.createElement('textarea')\n      textArea.innerHTML = str\n      return textArea.value\n    }\n  }\n}\n</script>\n\n<template>\n  <v-list-item-content v-if=\"dense\">\n    <v-list-item-title>\n      <truncate :content=\"content.title\">\n        <span\n          class=\"px-2 rounded-pill d-inline-block text-caption white--text codePink\"\n        >\n          New\n        </span>\n        {{ content.title }}\n        <v-icon v-if=\"content.link\" x-small class=\"ml-1\">\n          open_in_new\n        </v-icon>\n      </truncate>\n    </v-list-item-title>\n    <v-list-item-subtitle v-if=\"timestamp\">\n      {{ timestamp }}\n    </v-list-item-subtitle>\n  </v-list-item-content>\n\n  <v-list-item-content v-else>\n    <v-list-item-title>\n      <a\n        v-if=\"content.link\"\n        :href=\"content.link\"\n        target=\"_blank\"\n        style=\"display: inline-block;\"\n      >\n        {{ content.title }}\n      </a>\n      <span v-else>{{ content.title }}</span>\n      <v-icon v-if=\"content.link\" x-small class=\"ml-1\">\n        open_in_new\n      </v-icon>\n    </v-list-item-title>\n\n    <v-list-item-subtitle v-if=\"timestamp\">\n      {{ timestamp }}\n    </v-list-item-subtitle>\n\n    <v-list-item-subtitle v-if=\"!readMore\" v-html=\"decodeHTML(content.body)\">\n    </v-list-item-subtitle>\n\n    <v-fade-transition origin=\"center bottom\" hide-on-leave mode=\"out-in\">\n      <div\n        v-if=\"overflow && readMore\"\n        class=\"subtitle grey--text text--darken-1 pb-4\"\n        v-html=\"decodeHTML(content.body)\"\n      >\n      </div>\n    </v-fade-transition>\n    <span v-if=\"overflow\">\n      <a @click=\"readMore = !readMore\">\n        Read {{ readMore ? 'less' : 'more' }}\n      </a>\n    </span>\n  </v-list-item-content>\n</template>\n"
  },
  {
    "path": "src/pages/Notifications/Notifications.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport BreadCrumbs from '@/components/BreadCrumbs'\nimport NotificationGroup from '@/pages/Notifications/NotificationGroup'\nimport NotificationsLayout from '@/layouts/NotificationsLayout'\nimport SubPageNav from '@/layouts/SubPageNav'\nimport gql from 'graphql-tag'\nimport LogRocket from 'logrocket'\n\nexport default {\n  components: {\n    BreadCrumbs,\n    NotificationGroup,\n    NotificationsLayout,\n    SubPageNav\n  },\n  filters: {},\n  async beforeRouteLeave(to, from, next) {\n    if (!to.query?.notification_id) return next()\n\n    try {\n      if (to.query?.notification_id) {\n        let mutationString = gql`\n        mutation MarkMessagesAsRead {\n          mark_message_as_read(input: { message_id: \"${to.query.notification_id}\" }) {\n            success\n            error\n          }\n        }\n      `\n\n        await this.$apollo.mutate({\n          mutation: mutationString\n        })\n\n        delete to.query.notification_id\n      }\n    } finally {\n      next({ name: to.name, params: to.params })\n    }\n  },\n  data() {\n    return {\n      allCaughtUp: false,\n      counts: [],\n      loading: 0,\n      notificationFilters: { team: undefined },\n      notifications: [],\n      read: false,\n      selected: [],\n      updateKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    _allSelected() {\n      return this.selected.length === this.notifications?.length\n    },\n    _noneSelected() {\n      return this.selected.length === 0\n    },\n    _someSelected() {\n      return (\n        this.selected.length > 0 &&\n        this.selected.length < this.notifications?.length\n      )\n    },\n    _allRead() {\n      return (\n        this.selected.map(i => i.read).every(t => t === true) &&\n        this.selected.length > 0\n      )\n    },\n    _selected() {\n      if (this._allSelected) return 'all'\n      if (this._someSelected) return 'some'\n      return 'none'\n    },\n    count() {\n      return this.counts.reduce((a, b) => a + b.count, 0)\n    },\n    filteredTeams() {\n      if (\n        this.notificationFilters.team &&\n        this.notificationFilters.team !== null\n      ) {\n        return this.teams.filter(\n          team => team.id == this.notificationFilters.team\n        )\n      }\n      return this.teams\n    },\n    hideOnMobile() {\n      return { 'tabs-hidden': this.$vuetify.breakpoint.smAndDown }\n    },\n    showAllCaughtUp() {\n      let count = this.counts.find(c => c.id === this.notificationFilters.team)\n      return this.allCaughtUp || count?.count === 0\n    },\n    where() {\n      let where = {}\n\n      if (this.read !== 0) {\n        where.read = { _eq: this.read }\n      }\n      return where\n    }\n  },\n  watch: {\n    read() {\n      this.selected = []\n      this.updateKey++\n    },\n    teams(val) {\n      if (!val) return\n\n      this.counts = val.map(v => {\n        return {\n          id: v.id,\n          count: 0\n        }\n      })\n\n      // This pushes the user notifications count object\n      this.counts.push({\n        id: 'user-notifications',\n        count: 0\n      })\n    }\n  },\n  methods: {\n    _handleAdd(arr) {\n      this.selected = [...new Set([...this.selected, ...arr])]\n    },\n    _handleRemove(arr) {\n      this.selected = this.selected.filter(i => !arr.includes(i))\n    },\n    getCount(id) {\n      return this.counts.find(c => c.id == id)?.count\n    },\n    handleSelect() {\n      if (this._allSelected) {\n        this.selected = []\n      } else {\n        this.selected = this.notifications.map((n, i) => i)\n      }\n    },\n    async deleteMessages() {\n      if (this.selected?.length === 0) return\n\n      this.loading++\n\n      let messageMutations = ''\n\n      let selectedIds = this.selected.map(s => s.sid)\n\n      selectedIds.forEach((sid, i) => {\n        messageMutations += `\n          d${i}: delete_message(input: { message_id: \"${sid}\" }) {\n              success\n              error\n            }\n        `\n      })\n\n      try {\n        let mutationString = gql`\n              mutation DeleteMessages {\n                ${messageMutations}\n              }\n            `\n\n        const { data } = await this.$apollo.mutate({\n          mutation: mutationString\n        })\n\n        if (data?.d0.success) {\n          this.selected = []\n        }\n      } catch (e) {\n        LogRocket.error(e, {\n          extra: {\n            pageName: 'Notifications',\n            stage: 'Deleting notifications'\n          }\n        })\n      }\n\n      this.loading--\n      this.updateKey++\n    },\n    async markAsRead() {\n      if (this.selected?.length === 0) return\n\n      this.loading++\n\n      let messageMutations = ''\n\n      let selectedIds = this.selected.map(s => s.sid)\n\n      selectedIds.forEach((sid, i) => {\n        messageMutations += `\n          m${i}: mark_message_as_read(input: { message_id: \"${sid}\" }) {\n              success\n              error\n            }\n        `\n      })\n\n      try {\n        let mutationString = gql`\n              mutation MarkMessagesAsRead {\n                ${messageMutations}\n              }\n            `\n\n        const { data } = await this.$apollo.mutate({\n          mutation: mutationString\n        })\n\n        if (data?.m0.success) {\n          this.selected = []\n        }\n      } catch (e) {\n        LogRocket.error(e, {\n          extra: {\n            pageName: 'Notifications',\n            stage: 'Marking notifications as read'\n          }\n        })\n      }\n\n      this.loading--\n      this.updateKey++\n    },\n    async markAsUnread() {\n      if (this.selected?.length === 0) return\n\n      this.loading++\n\n      let messageMutations = ''\n\n      let selectedIds = this.selected.map(s => s.sid)\n\n      selectedIds.forEach((sid, i) => {\n        messageMutations += `\n          m${i}: mark_message_as_unread(input: { message_id: \"${sid}\" }) {\n              success\n              error\n            }\n        `\n      })\n\n      try {\n        let mutationString = gql`\n              mutation MarkMessagesAsUnread {\n                ${messageMutations}\n              }\n            `\n\n        const { data } = await this.$apollo.mutate({\n          mutation: mutationString\n        })\n\n        if (data?.m0.success) {\n          this.selected = []\n        }\n      } catch (e) {\n        LogRocket.error(e, {\n          extra: {\n            pageName: 'Notifications',\n            stage: 'Marking notifications as unread'\n          }\n        })\n      }\n\n      this.loading--\n      this.updateKey++\n    },\n    updateCount(data) {\n      let i = this.counts.findIndex(c => c.id === data.id)\n      this.counts[i].count = data.count\n      this.allCaughtUp = this.count === 0\n    },\n    updateLoading(val) {\n      this.loading += val\n    }\n  },\n  apollo: {\n    teams: {\n      query: require('@/graphql/Notifications/teams.gql'),\n      loadingKey: 'loading',\n      update: data => data.teams\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet color=\"appBackground\">\n    <SubPageNav>\n      <span slot=\"page-type\">Notifications</span>\n      <span\n        slot=\"page-title\"\n        style=\"height: 28px;\n        overflow: hidden;\"\n      >\n        <BreadCrumbs\n          slot=\"breadcrumbs\"\n          :crumbs=\"[\n            {\n              route: { name: 'dashboard', params: { tenant: tenant.slug } },\n              text: 'Dashboard'\n            }\n          ]\"\n        ></BreadCrumbs>\n      </span>\n    </SubPageNav>\n\n    <NotificationsLayout>\n      <v-card slot=\"col-1\" class=\"py-6 px-4 text-left\" tile>\n        <v-progress-linear\n          :active=\"loading > 0\"\n          indeterminate=\"\"\n          color=\"primary\"\n          background-opacity=\"0\"\n          absolute\n          :bottom=\"$vuetify.breakpoint.xs\"\n        />\n\n        <v-btn-toggle\n          v-model=\"read\"\n          :class=\"\n            $vuetify.breakpoint.mdAndDown && !$vuetify.breakpoint.xs\n              ? 'd-flex flex-column stacking-btn-toggle'\n              : 'mr-4 my-2'\n          \"\n          dense\n          mandatory\n        >\n          <v-btn\n            :small=\"$vuetify.breakpoint.xs\"\n            :value=\"null\"\n            :disabled=\"loading > 0\"\n          >\n            All\n          </v-btn>\n\n          <v-btn\n            :small=\"$vuetify.breakpoint.xs\"\n            :value=\"false\"\n            :disabled=\"loading > 0\"\n          >\n            <v-icon left color=\"codePink\" x-small>fiber_manual_record</v-icon>\n            Unread\n          </v-btn>\n\n          <v-btn\n            :small=\"$vuetify.breakpoint.xs\"\n            :value=\"true\"\n            :disabled=\"loading > 0\"\n          >\n            <v-icon left color=\"grey lighten-1\" x-small>\n              fiber_manual_record\n            </v-icon>\n            Read\n          </v-btn>\n        </v-btn-toggle>\n\n        <v-btn\n          v-if=\"!read && _allRead === false\"\n          :small=\"$vuetify.breakpoint.xs\"\n          depressed\n          :disabled=\"loading > 0 || selected.length === 0\"\n          color=\"primary\"\n          :block=\"!$vuetify.breakpoint.xs\"\n          :class=\"$vuetify.breakpoint.xs ? 'mr-4 my-2' : 'my-4'\"\n          @click=\"markAsRead\"\n        >\n          <v-icon left color=\"grey lighten-1\" small>\n            fiber_manual_record\n          </v-icon>\n          Mark as Read\n        </v-btn>\n\n        <v-btn\n          v-else\n          :small=\"$vuetify.breakpoint.xs\"\n          depressed\n          :disabled=\"loading > 0 || selected.length === 0\"\n          color=\"primary\"\n          :block=\"!$vuetify.breakpoint.xs\"\n          :class=\"$vuetify.breakpoint.xs ? 'mr-4 my-2' : 'my-4'\"\n          @click=\"markAsUnread\"\n        >\n          <v-icon left color=\"grey lighten-1\" small>\n            fiber_manual_record\n          </v-icon>\n          Mark as Unread\n        </v-btn>\n\n        <v-btn\n          :small=\"$vuetify.breakpoint.xs\"\n          depressed\n          :disabled=\"loading > 0 || selected.length === 0\"\n          color=\"primary\"\n          :block=\"!$vuetify.breakpoint.xs\"\n          :class=\"$vuetify.breakpoint.xs ? 'mr-4 my-2' : 'my-4'\"\n          @click=\"deleteMessages\"\n        >\n          <v-icon left small>\n            delete\n          </v-icon>\n\n          Delete Selected\n        </v-btn>\n\n        <v-divider />\n\n        <v-card-title\n          class=\"ml-4 pl-0 text-subtitle-2 grey--text text--darken-2\"\n        >\n          Filter\n        </v-card-title>\n        <v-list-item-group v-model=\"notificationFilters.team\" color=\"primary\">\n          <v-list-item selectable value=\"user-notifications\">\n            <v-list-item-content>\n              <v-list-item-title>\n                Your notifications\n                <span\n                  v-if=\"getCount('user-notifications') > 0\"\n                  class=\"font-weight-bold ml-1\"\n                >\n                  ({{ getCount('user-notifications') }})\n                </span>\n              </v-list-item-title>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-list-item\n            v-for=\"team in teams\"\n            :key=\"team.id\"\n            selectable\n            :value=\"team.id\"\n          >\n            <v-list-item-content>\n              <v-list-item-title>\n                {{ team.name }}\n                <span\n                  v-if=\"getCount(team.id) > 0\"\n                  class=\"font-weight-bold ml-1\"\n                >\n                  ({{ getCount(team.id) }})\n                </span>\n              </v-list-item-title>\n            </v-list-item-content>\n          </v-list-item>\n        </v-list-item-group>\n      </v-card>\n\n      <transition-group name=\"bf\">\n        <div v-show=\"!allCaughtUp\" key=\"notificationgroup\">\n          <NotificationGroup\n            v-if=\"\n              teams &&\n                (notificationFilters.team === undefined ||\n                  notificationFilters.team === 'user-notifications')\n            \"\n            :loading=\"loading\"\n            :read=\"read\"\n            :tenant=\"{ id: 'user-notifications', name: 'Your notifications' }\"\n            :update-key=\"updateKey\"\n            @add=\"_handleAdd\"\n            @count=\"updateCount\"\n            @loading=\"updateLoading\"\n            @remove=\"_handleRemove\"\n          />\n\n          <NotificationGroup\n            v-for=\"team in filteredTeams\"\n            :key=\"team.id\"\n            :loading=\"loading\"\n            :read=\"read\"\n            :tenant=\"team\"\n            :update-key=\"updateKey\"\n            @add=\"_handleAdd\"\n            @count=\"updateCount\"\n            @loading=\"updateLoading\"\n            @remove=\"_handleRemove\"\n          />\n        </div>\n\n        <v-card v-if=\"showAllCaughtUp\" key=\"allcaughtup\" class=\"py-2 px-4\" tile>\n          <v-card-text>\n            <v-row class=\"pa-12\">\n              <v-col\n                cols=\"12\"\n                class=\"d-flex justify-center flex-column text-center\"\n              >\n                <img\n                  class=\"photo mx-auto\"\n                  src=\"@/assets/backgrounds/build-a-flow.svg\"\n                  alt=\"All Caught Up Image\"\n                />\n                <div class=\"text-h5 mt-12\">\n                  You're all caught up!\n                </div>\n              </v-col>\n            </v-row>\n          </v-card-text>\n        </v-card>\n      </transition-group>\n    </NotificationsLayout>\n  </v-sheet>\n</template>\n\n<style lang=\"scss\">\n// stylelint-disable\n.bf-enter-active,\n.bf-leave-active {\n  transition: opacity 0.3s !important;\n}\n\n.bf-leave-active {\n  display: none;\n}\n\n.bf-enter,\n.bf-leave-to {\n  opacity: 0 !important;\n}\n// stylelint-enable\n</style>\n\n<style lang=\"scss\" scoped>\n.photo {\n  max-width: 500px;\n  width: 100%;\n\n  @media screen and (max-width: 1366px) {\n    max-width: 470px;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Notifications/utils.js",
    "content": "export const componentMap = {\n  CLOUD_HOOK: 'FlowRunNotification',\n  MEMBERSHIP_INVITATION: 'MembershipNotification',\n  REQUIRES_APPROVAL: 'ApprovalNotification',\n  MESSAGE: 'MessageNotification',\n  WHATS_NEW: 'WhatsNewNotification'\n}\n\nexport const iconMap = {\n  CLOUD_HOOK: 'pi-flow-run',\n  MEMBERSHIP_INVITATION: 'group_add',\n  REQUIRES_APPROVAL: 'pause_circle_outline',\n  MESSAGE: 'chat',\n  WHATS_NEW: '🎉'\n}\n\nexport const iconColorMap = {\n  CLOUD_HOOK: n => {\n    return n.content.event.state\n  },\n  MEMBERSHIP_INVITATION: () => 'primary',\n  WHATS_NEW: () => 'primary',\n  MESSAGE: () => 'primary',\n  REQUIRES_APPROVAL: () => 'accentOrange'\n}\n\nexport const navigationMap = {\n  CLOUD_HOOK: (n, tenant) => {\n    return {\n      name: 'flow-run',\n      params: { id: n.content.event.id, tenant: tenant.slug },\n      query: { notification_id: n.id }\n    }\n  },\n  MEMBERSHIP_INVITATION: () => null,\n  WHATS_NEW: () => null,\n  MESSAGE: () => null,\n  REQUIRES_APPROVAL: (n, tenant) => {\n    return {\n      name: 'task-run',\n      params: { id: n.content.task_run.id, tenant: tenant.slug },\n      query: { notification_id: n.id }\n    }\n  }\n}\n"
  },
  {
    "path": "src/pages/Onboard/AcceptInvitationPage.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport { handleMembershipInvitations } from '@/mixins/membershipInvitationMixin.js'\n\nexport default {\n  mixins: [handleMembershipInvitations],\n  data() {\n    return {\n      loadingKey: 0,\n      loading: false,\n      deleting: false,\n      error: false,\n      dialog: false,\n      invitationId:\n        this.$route.query.invitation_id ||\n        sessionStorage.getItem('invitationId'),\n      membershipInvitation: null,\n      mutationErrorMessage: false\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['user']),\n    ...mapGetters('tenant', ['tenant']),\n    teamName() {\n      return this.membershipInvitation?.tenant?.name || 'a new team'\n    },\n    loadingPage() {\n      return this.loadingKey > 0\n    },\n    invitationError() {\n      return (\n        this.error ||\n        !this.membershipInvitation ||\n        !this.membershipInvitation.user ||\n        this.mutationErrorMessage\n      )\n    },\n    errorMessage() {\n      if (this.membershipInvitation && !this.membershipInvitation.user)\n        return 'This invitation appears to be for someone else - did you log in to the correct account?'\n      if (this.error)\n        return 'It looks like there was a problem with your invitation.  Please check the details and your account and try again.'\n      return `We can't find this invitation... have you already\n              accepted?`\n    }\n  },\n  methods: {\n    ...mapActions('tenant', ['setCurrentTenant']),\n    async accept() {\n      try {\n        this.loading = true\n        const tenant = this.membershipInvitation.tenant\n        const invitationId = this.membershipInvitation.id\n        const accepted = await this.acceptMembershipInvitation(invitationId)\n        if (accepted.accept_membership_invitation.id) {\n          sessionStorage.removeItem('invitationId')\n          await this.setCurrentTenant(tenant.slug)\n          this.toDashboard(tenant)\n          this.loading = false\n        }\n      } catch (e) {\n        this.mutationErrorMessage = e\n          .toString()\n          .split(':')\n          .pop()\n        this.loading = false\n        this.error = true\n      }\n    },\n    async decline() {\n      try {\n        this.deleting = true\n        const invitationId = this.membershipInvitation.id\n        const declined = await this.declineMembershipInvitation(invitationId)\n        if (declined.delete_membership_invitation.success) {\n          this.toDashboard()\n        }\n        this.deleting = false\n      } catch (e) {\n        this.mutationErrorMessage = e\n          .toString()\n          .split(':')\n          .pop()\n        this.dialog = false\n        this.deleting = false\n        this.error = true\n      }\n    },\n    toDashboard(tenant) {\n      sessionStorage.removeItem('invitationId')\n      this.$router.push({\n        name: 'dashboard',\n        params: { tenant: tenant ? tenant.slug : this.tenant.slug }\n      })\n    }\n  },\n  apollo: {\n    membershipInvitation: {\n      query: require('@/graphql/Tenant/membership-invitation.gql'),\n      variables() {\n        return { id: this.invitationId }\n      },\n      skip() {\n        return !this.invitationId\n      },\n      loadingKey: 'loadingKey',\n      update: data => data.membership_invitation_by_pk\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container\n    v-if=\"!loadingPage\"\n    class=\"position-absolute text-center d-flex flex-row align-center justify-center\"\n  >\n    <div v-if=\"invitationError\">\n      <v-col class=\"grey--text text--lighten-5 mx-12\">\n        <div class=\"text-h4\">\n          <span> {{ mutationErrorMessage || errorMessage }} </span>\n        </div>\n        <div>\n          <v-btn class=\"mt-8\" color=\"primary\" x-large @click=\"toDashboard\">\n            Back to the dashboard!\n            <v-icon right>fas fa-rocket</v-icon>\n          </v-btn>\n        </div>\n      </v-col>\n    </div>\n    <div v-else>\n      <v-col>\n        <div class=\"text-h4 grey--text text--lighten-5\">\n          You've been invited to join\n          <span class=\"font-weight-bold\"> {{ teamName }}</span>\n        </div>\n        <div class=\"subtitle grey--text text--lighten-5 mt-4\">\n          To accept, please click below.\n        </div>\n        <div class=\"mt-8\">\n          <v-btn\n            class=\"mr-3\"\n            color=\"accentPink\"\n            dark\n            depressed\n            :loading=\"loading\"\n            @click=\"accept\"\n          >\n            <v-icon class=\"pr-4\">fa-user-friends</v-icon>\n            Accept\n          </v-btn>\n          <v-dialog v-model=\"dialog\" max-width=\"500\">\n            <template #activator=\"{ on, attrs }\">\n              <v-btn outlined class=\"white--text\" v-bind=\"attrs\" v-on=\"on\">\n                No Thanks\n              </v-btn>\n            </template>\n\n            <v-card>\n              <v-card-title class=\"text-h5\">\n                Are you sure you want to decline?\n              </v-card-title>\n\n              <v-card-text>\n                <div\n                  >Clicking <span class=\"font-weight-bold\"> Decline </span> will\n                  delete your invitation and take you back to the dashboard. </div\n                ><div class=\"mt-2\">\n                  If you don't want to confirm or delete your invitation right\n                  now, you can click on\n                  <span class=\"font-weight-bold\"> Dashboard</span>. You'll be\n                  taken back to your team dashboard and be able to accept (or\n                  decline) the invitation later.\n                </div>\n              </v-card-text>\n\n              <v-card-actions>\n                <v-spacer></v-spacer>\n                <v-btn\n                  class=\"white--text\"\n                  color=\"prefect\"\n                  :loading=\"deleting\"\n                  @click=\"decline\"\n                >\n                  Decline\n                </v-btn>\n                <v-btn outlined color=\"prefect\" @click=\"toDashboard\">\n                  Dashboard</v-btn\n                >\n                <v-btn text color=\"prefect\" @click=\"dialog = false\"\n                  >Cancel</v-btn\n                >\n              </v-card-actions>\n            </v-card>\n          </v-dialog>\n        </div>\n      </v-col>\n    </div>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.link-color {\n  color: var(v-prefect-base);\n}\n</style>\n"
  },
  {
    "path": "src/pages/Onboard/NameTeam.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport ExternalLink from '@/components/ExternalLink'\nimport { teamProfileMixin } from '@/mixins/teamProfileMixin.js'\nimport { handleMembershipInvitations } from '@/mixins/membershipInvitationMixin.js'\nimport { shuffle } from '@/utils/array'\n\nlet hidden, visibilityChange\n\nif (window) {\n  if (typeof document.hidden !== 'undefined') {\n    // Opera 12.10 and Firefox 18 and later\n    hidden = 'hidden'\n    visibilityChange = 'visibilitychange'\n  } else if (typeof document.msHidden !== 'undefined') {\n    hidden = 'msHidden'\n    visibilityChange = 'msvisibilitychange'\n  } else if (typeof document.webkitHidden !== 'undefined') {\n    hidden = 'webkitHidden'\n    visibilityChange = 'webkitvisibilitychange'\n  }\n}\n\nexport default {\n  components: { ExternalLink },\n  mixins: [teamProfileMixin, handleMembershipInvitations],\n  data() {\n    return {\n      // Form's computed height\n      height: '0px',\n      loading: 0,\n      accepting: false,\n      activeInvite: null,\n      currentInvitation: null,\n      declining: false,\n      dialog: false,\n      redirectTenant: null,\n\n      // Reveal animation bools\n      revealNote: false,\n      revealNameInput: false,\n      revealUrlInput: false,\n      revealDropdown: false,\n      revealPendingTeams: false,\n      revealConfirm: false,\n\n      // \"how did you hear about us\" options\n      options: [\n        'Twitter',\n        'Google',\n        'LinkedIn',\n        'Colleague',\n        'Conference',\n        'Meetup',\n        'Webinar',\n        'Blog Post',\n        'Other'\n      ],\n      selectedOption: '',\n      extraInfo: ''\n    }\n  },\n  computed: {\n    ...mapGetters('auth', ['user']),\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('license', ['license', 'hasPermission']),\n    ...mapGetters('license', ['license']),\n    disabled() {\n      return this.loading > 0 || !this.revealConfirm\n    },\n    permissionsCheck() {\n      return this.hasPermission('update', 'tenant')\n    },\n    shuffledOptions() {\n      let optionsCopy = [...this.options]\n      let other = optionsCopy.pop()\n      let shuffledArray = shuffle(optionsCopy)\n\n      return [...shuffledArray, other]\n    }\n  },\n  mounted() {\n    this.createLicense()\n\n    this.tenantChanges.name = this.tenant.name\n    this.tenantChanges.slug = this.tenant.slug\n\n    window.addEventListener(\n      visibilityChange,\n      this.handleVisibilityChange,\n      false\n    )\n\n    setTimeout(() => {\n      this.revealNote = true\n\n      setTimeout(() => {\n        this.height = getComputedStyle(this.$refs['main-row']).height\n      }, 250)\n    }, 500)\n\n    setTimeout(() => {\n      this.revealNameInput = true\n      this.revealUrlInput = true\n      this.revealDropdown = true\n      this.revealPendingTeams = true\n      this.revealConfirm = true\n\n      setTimeout(() => {\n        this.height = getComputedStyle(this.$refs['main-row']).height\n      }, 250)\n    }, 1250)\n  },\n  beforeDestroy() {\n    window.removeEventListener(this.handleVisibilityChange)\n  },\n  methods: {\n    ...mapActions('tenant', ['getTenants', 'updateTenantSettings']),\n    ...mapActions('user', ['getUser']),\n    async createLicense() {\n      if (this.license) return\n      this.loading++\n      try {\n        // Create the stripe customer (necessary for creating a self serve license)\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/License/update-stripe-customer.gql'),\n          variables: {\n            input: {\n              email: this.user.email,\n              name: `${this.user.name ? this.user.name : ''}`.trim(),\n              source: null\n            }\n          }\n        })\n\n        // Create usage license\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/License/create-usage-based-license.gql'),\n          variables: {\n            input: {\n              tenant_id: this.tenant.id,\n              plan_name: 'FREE_2021'\n            }\n          }\n        })\n      } catch (e) {\n        /* eslint-disable no-console */\n        console.error(e)\n      }\n\n      this.loading--\n      return\n    },\n    handleVisibilityChange() {\n      // Redundancy for the animation reveals (which are on timeouts)\n      if (!document[hidden]) {\n        this.height = getComputedStyle(this.$refs['main-row']).height\n\n        this.revealNote = true\n        this.revealNameInput = true\n        this.revealUrlInput = true\n        this.revealDropdown = true\n        this.revealPendingTeams = true\n        this.revealConfirm = true\n      }\n    },\n    async updateTenant() {\n      // Async tenant checks\n      await this.checkNameAsync()\n      await this.checkSlugAsync()\n\n      if (this.nameErrors.length > 0 || this.slugErrors.length > 0) {\n        return\n      }\n\n      this.updateServerError = false\n      this.loading++\n\n      if (\n        this.tenantChanges.slug == this.tenant.slug &&\n        this.tenantChanges.name == this.tenant.name\n      ) {\n        await this.updateTenantSettings({\n          teamNamed: true\n        })\n      } else {\n        try {\n          await this.$apollo.mutate({\n            mutation: require('@/graphql/Tenant/update-tenant.gql'),\n            variables: {\n              name: this.tenantChanges.name || this.tenant.name,\n              slug: this.tenantChanges.slug || this.tenant.slug\n            }\n          })\n\n          await this.updateTenantSettings({\n            teamNamed: true\n          })\n\n          await this.getTenants()\n        } catch (e) {\n          if (e.message.includes('Uniqueness violation')) {\n            this.slugErrors = ['Sorry, that slug is already in use.']\n          } else {\n            this.updateServerError = true\n          }\n        }\n      }\n\n      this.loading--\n      if (this.slugErrors.length > 0) {\n        return\n      }\n\n      if (!this.updateServerError) this.goToResources()\n    },\n    async skip() {\n      this.updateTenantSettings({\n        teamNamed: true\n      })\n\n      this.$router.push({\n        name: 'onboard-resources',\n        params: { tenant: this.tenant.slug }\n      })\n    },\n    async accept(pt) {\n      this.loading++\n      this.accepting = true\n      try {\n        this.activeInvite = pt.id\n        const invitationId = pt.id\n        const accepted = await this.acceptMembershipInvitation(invitationId)\n        this.redirectTenant = pt.tenant.slug\n        if (accepted.accept_membership_invitation.id) {\n          this.redirectTenant = pt.tenant.slug\n          this.$apollo.queries.pendingInvitations.refetch()\n        }\n      } catch (e) {\n        this.mutationErrorMessage = e\n          .toString()\n          .split(':')\n          .pop()\n        this.error = true\n      }\n      this.activeInvite = null\n      this.accepting = false\n      this.loading--\n    },\n    openModal(pt) {\n      this.activeInvite = pt.id\n      this.currentInvitation = pt\n      this.dialog = true\n    },\n    async decline(id) {\n      this.loading++\n      this.declining = true\n      try {\n        this.activeInvite = id\n        const declined = await this.declineMembershipInvitation(id)\n        if (declined.delete_membership_invitation.success) {\n          this.dialog = false\n          this.$apollo.queries.pendingInvitations.refetch()\n        }\n      } catch (e) {\n        this.mutationErrorMessage = e\n          .toString()\n          .split(':')\n          .pop()\n        this.error = true\n      }\n      this.declining = false\n      this.activeInvite = null\n      this.loading--\n    },\n    setSelectedOption(option) {\n      this.selectedOption = option\n    },\n    setExtraInfo(extraInfo) {\n      this.extraInfo = extraInfo\n    },\n    async goToResources() {\n      this.revealNameInput = false\n      this.revealUrlInput = false\n      this.revealDropdown = false\n      this.revealConfirm = false\n      this.revealNote = false\n\n      await this.setCurrentTenant(\n        this.redirectTenant ?? this.tenantChanges.slug ?? this.tenant.slug\n      )\n\n      const eventSource = this.isCloud ? 'prefect_cloud' : 'prefect_server'\n\n      fetch('https://sens-o-matic.prefect.io', {\n        method: 'post',\n        headers: {\n          'Content-Type': 'application/json',\n          'x-prefect-event': eventSource\n        },\n        body: JSON.stringify({\n          source: eventSource,\n          type: 'welcome_survey',\n          payload: {\n            location: this.selectedOption,\n            info: this.extraInfo\n          }\n        })\n      }).then(res => {\n        return res.json()\n      })\n\n      this.$router.push({\n        name: 'onboard-resources',\n        params: { tenant: this.tenant.slug }\n      })\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.pendingInvitations.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    pendingInvitations: {\n      query: require('@/graphql/Tenant/pending-invitations-by-email.gql'),\n      variables() {\n        return {\n          email: this.user.email\n        }\n      },\n      pollInterval: 60000,\n      update: data => data?.pendingInvitations ?? []\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    v-if=\"tenant.id\"\n    v-intersect=\"{ handler: onIntersect }\"\n    class=\"text-center mx-auto px-12 py-8 white--text\"\n    flat\n    tile\n    style=\"align-items: center;\n    display: flex;\n    width: fit-content !important;\"\n    color=\"transparent\"\n  >\n    <v-row\n      align=\"center\"\n      justify=\"center\"\n      :style=\"{ 'max-height': height }\"\n      class=\"transition-height\"\n    >\n      <div ref=\"main-row\">\n        <transition-group name=\"fade\">\n          <v-col v-if=\"revealNote\" key=\"name\" cols=\"12\" class=\"pb-0\">\n            <div v-if=\"permissionsCheck\" class=\"text-h4 text-center\">\n              Let's start by creating your team\n              <v-menu\n                :close-on-content-click=\"false\"\n                offset-y\n                transition=\"slide-y-transition\"\n              >\n                <template #activator=\"{ on, attrs }\">\n                  <v-btn icon v-bind=\"attrs\" v-on=\"on\"\n                    ><v-icon class=\"white--text\"\n                      >fa-question-circle</v-icon\n                    ></v-btn\n                  >\n                </template>\n                <v-card tile class=\"pa-3 mt-1\" max-width=\"320\">\n                  <div class=\"text-body-1\">\n                    Prefect automatically creates a sandbox development team for\n                    you to use &mdash; this is a great place to test and deploy\n                    flows as you explore Prefect. When you're ready to\n                    collaborate with others, you can\n                    <ExternalLink href=\"https://www.prefect.io/pricing\">\n                      upgrade this team</ExternalLink\n                    >\n                    to invite more users or\n                    <ExternalLink href=\"https://www.prefect.io/pricing#contact\">\n                      contact us</ExternalLink\n                    >\n                    to add another team. For more information about teams in\n                    Prefect, check out our\n                    <ExternalLink\n                      href=\"https://docs.prefect.io/orchestration/ui/team-settings.html#switching-teams\"\n                      >docs</ExternalLink\n                    >.\n                  </div>\n                </v-card>\n              </v-menu>\n            </div>\n            <div v-else class=\"text-h4 text-center\"> Team Details </div>\n          </v-col>\n\n          <v-col v-if=\"revealNote\" key=\"revealNote\" cols=\"12\">\n            <div v-if=\"permissionsCheck\" class=\"text-body-2 text--darken-1\">\n              (You can always change this later)\n            </div>\n            <div v-else class=\"text-body-2 text--darken-1\">\n              Contact your team administrators to complete onboarding</div\n            >\n          </v-col>\n\n          <v-col\n            v-if=\"revealNameInput\"\n            key=\"input-1\"\n            cols=\"12\"\n            class=\"my-2 mt-12 name-team-input mx-auto\"\n          >\n            <div class=\"text-overline\">\n              Team Name\n            </div>\n            <div v-if=\"!permissionsCheck\" class=\"text-h5\">\n              {{ tenant.name }}\n            </div>\n            <v-text-field\n              v-if=\"permissionsCheck\"\n              v-model=\"name\"\n              data-cy=\"team-name\"\n              :disabled=\"disabled\"\n              :error-messages=\"nameErrors\"\n              :loading=\"isCheckingName\"\n              dark\n              @blur=\"checkName(name)\"\n              @input=\"resetNameMetadata\"\n            >\n              <v-icon\n                v-if=\"showNameIcon && nameErrors.length === 0\"\n                slot=\"append\"\n                class=\"white--text\"\n              >\n                check\n              </v-icon>\n              <v-icon\n                v-if=\"showNameIcon && nameErrors.length > 0\"\n                slot=\"append\"\n                class=\"red--text\"\n              >\n                clear\n              </v-icon>\n            </v-text-field>\n          </v-col>\n          <v-col\n            v-if=\"revealUrlInput\"\n            key=\"input-2\"\n            cols=\"12\"\n            class=\"my-2 name-team-input mx-auto\"\n          >\n            <div class=\"text-overline d-flex justify-center align-center\">\n              <span class=\"mr-1\">Team Slug</span>\n              <Truncate\n                content=\"This slug is used to create shareable links for your flows and runs unique to your team.\"\n              >\n                <v-icon x-small dark>\n                  info\n                </v-icon>\n              </Truncate>\n            </div>\n            <div v-if=\"permissionsCheck\" class=\"text-h5 medium\"> </div>\n            <v-text-field\n              v-if=\"permissionsCheck\"\n              v-model=\"slug\"\n              data-cy=\"team-slug\"\n              :disabled=\"disabled\"\n              :error-messages=\"slugErrors\"\n              :loading=\"isCheckingSlug\"\n              dark\n              @blur=\"checkSlug(slug)\"\n              @input=\"resetSlugMetadata\"\n            >\n              <v-icon\n                v-if=\"showSlugIcon && slugErrors.length === 0\"\n                slot=\"append\"\n                class=\"white--text\"\n              >\n                check\n              </v-icon>\n              <v-icon\n                v-if=\"showSlugIcon && slugErrors.length > 0\"\n                slot=\"append\"\n                class=\"red--text\"\n              >\n                clear\n              </v-icon>\n            </v-text-field>\n          </v-col>\n\n          <v-col\n            v-if=\"revealDropdown\"\n            key=\"input-3\"\n            cols=\"12\"\n            class=\"my-2 mb-12 mx-auto\"\n          >\n            <div class=\"text-overline\">\n              How did you hear about us?\n            </div>\n            <v-select\n              :items=\"shuffledOptions\"\n              dark\n              :menu-props=\"{ maxHeight: 400 }\"\n              label=\"Options\"\n              @change=\"setSelectedOption\"\n            ></v-select>\n            <v-text-field\n              v-show=\"selectedOption == 'Other'\"\n              dark\n              autofocus\n              placeholder=\"Newsletter, advertisement, etc...\"\n              @input=\"setExtraInfo\"\n            ></v-text-field>\n          </v-col>\n\n          <v-col\n            v-if=\"revealPendingTeams && pendingInvitations\"\n            key=\"pendingInvites\"\n            cols=\"12\"\n          >\n            <div v-if=\"pendingInvitations.length\" class=\"text-body-1\">\n              Your pending invitations:\n            </div>\n            <v-list\n              v-for=\"pt in pendingInvitations\"\n              :key=\"pt.id\"\n              color=\"transparent\"\n            >\n              <v-list-item\n                style=\"align-items: baseline;\n                color: appForeground !important;\n                justify-content: space-between;\"\n              >\n                <span class=\"pr-2\">{{ pt.tenant.name }}</span>\n                <div class=\"mt-8\">\n                  <v-btn\n                    class=\"mr-3\"\n                    color=\"accentPink\"\n                    dark\n                    depressed\n                    :disabled=\"disabled\"\n                    :loading=\"activeInvite === pt.id && accepting\"\n                    @click=\"accept(pt)\"\n                  >\n                    <v-icon class=\"pr-4\">fa-user-friends</v-icon>\n                    Accept\n                  </v-btn>\n                  <v-btn\n                    outlined\n                    class=\"white--text\"\n                    :disabled=\"disabled\"\n                    @click=\"openModal(pt)\"\n                  >\n                    No Thanks\n                  </v-btn>\n                </div>\n              </v-list-item>\n            </v-list>\n          </v-col>\n\n          <v-col\n            v-if=\"revealConfirm\"\n            key=\"revealConfirm\"\n            cols=\"12\"\n            class=\"my-2\"\n          >\n            <div>\n              <v-btn\n                v-if=\"permissionsCheck\"\n                color=\"primary\"\n                width=\"200\"\n                data-cy=\"submit-team-info\"\n                :loading=\"loading > 0\"\n                :disabled=\"disabled\"\n                @click=\"updateTenant\"\n              >\n                Next\n              </v-btn>\n            </div>\n            <div class=\"mt-4\">\n              <v-btn\n                color=\"white\"\n                :disabled=\"disabled\"\n                text\n                width=\"auto\"\n                @click=\"skip\"\n              >\n                Skip\n                <v-icon right>arrow_right</v-icon>\n              </v-btn>\n            </div>\n          </v-col>\n\n          <v-col\n            v-if=\"\n              updateServerError &&\n                nameErrors.length === 0 &&\n                slugErrors.length === 0\n            \"\n            key=\"error\"\n            cols=\"12\"\n            class=\"text-h6 red--text text--lighten-1\"\n          >\n            Sorry, something went wrong. Please try again.\n          </v-col>\n        </transition-group>\n      </div>\n    </v-row>\n    <v-dialog v-if=\"currentInvitation\" v-model=\"dialog\" max-width=\"500\">\n      <v-card>\n        <v-card-title class=\"text-h5\">\n          Are you sure you want to decline the invitation to\n          {{ currentInvitation.tenant.name }}?\n        </v-card-title>\n        <v-card-text>\n          <div>\n            Clicking\n            <span class=\"font-weight-bold\"> Decline </span> will delete your\n            invitation.\n          </div>\n          <div class=\"mt-2\">\n            If you don't want to accept or decline your invitation right now,\n            you can click on\n            <span class=\"font-weight-bold\"> Cancel</span>. You'll be able to\n            accept (or decline) the invitation later.\n          </div>\n        </v-card-text>\n        <v-card-actions>\n          <v-spacer></v-spacer>\n          <v-btn\n            class=\"white--text\"\n            color=\"prefect\"\n            :loading=\"declining\"\n            @click=\"decline(currentInvitation.id)\"\n          >\n            Decline\n          </v-btn>\n          <v-btn outlined color=\"prefect\" @click=\"dialog = false\">Cancel</v-btn>\n        </v-card-actions>\n      </v-card>\n    </v-dialog>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.transition-height {\n  transition: max-height 500ms ease;\n}\n\n.name-team-input {\n  max-width: 700px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Onboard/Onboard-Page.vue",
    "content": "<script>\nimport '@/styles/slash.scss'\n\nexport default {\n  data() {\n    return {\n      start: false\n    }\n  },\n  computed: {\n    containerClass() {\n      let route = this.$route.name\n      return {\n        'overflow-y-hidden': this.$vuetify.breakpoint.mdAndUp,\n        'bg-blue': route == 'welcome',\n        'bg-grey': this.nameTeamOrAcceptRoute\n      }\n    },\n    noSlash() {\n      return this.$vuetify.breakpoint.xl\n        ? 15\n        : this.$vuetify.breakpoint.lg\n        ? 10\n        : 5\n    },\n    nameTeamOrAcceptRoute() {\n      return (\n        this.$route.name == 'name-team' ||\n        this.$route.name == 'accept' ||\n        this.$route.name == 'plan'\n      )\n    },\n    slashClass() {\n      return {\n        slash: this.$vuetify.breakpoint.mdAndUp,\n        'slash-horizontal': this.$vuetify.breakpoint.smAndDown,\n        'slash-full': this.$vuetify.breakpoint.smAndDown,\n        'slash-origin-center': this.$vuetify.breakpoint.mdAndUp\n      }\n    },\n    slash1Class() {\n      return {\n        ...this.slashClass,\n        paused: this.$route.name !== 'welcome' || !this.start\n      }\n    },\n    slash2Class() {\n      return {\n        slash: this.$vuetify.breakpoint.mdAndUp,\n        'slash-origin-center': this.$vuetify.breakpoint.mdAndUp,\n        paused: !this.start\n      }\n    },\n    slash3Class() {\n      return {\n        ...this.slashClass,\n        paused: !this.nameTeamOrAcceptRoute\n      }\n    },\n    slash4Class() {\n      return {\n        ...this.slashResourcesClass,\n        'slash-origin-left': this.$vuetify.breakpoint.mdAndUp,\n        paused: this.$route.name !== 'onboard-resources'\n      }\n    },\n    slash5Class() {\n      return {\n        ...this.slashResourcesClass,\n        'slash-origin-right': this.$vuetify.breakpoint.mdAndUp,\n        paused: this.$route.name !== 'onboard-resources'\n      }\n    },\n    slashResourcesClass() {\n      return {\n        slash: this.$vuetify.breakpoint.mdAndUp,\n        'slash-horizontal': this.$vuetify.breakpoint.smAndDown,\n        'slash-full': this.$vuetify.breakpoint.smAndDown\n      }\n    }\n  },\n  mounted() {\n    setTimeout(() => {\n      this.start = true\n    }, 250)\n  },\n  methods: {\n    slash2Style(i) {\n      let width, top\n      if (i > this.noSlash / 2) {\n        top = i * 5 + 50\n        width = Math.floor(Math.random() * (125 - 75)) + 75\n      } else {\n        top = i * 5\n        width = Math.floor(Math.random() * (75 - 25)) + 25\n      }\n\n      return {\n        top: `${top}%`,\n        height: '120px',\n        left: 0,\n        'transition-delay': `${Math.floor(i / 2) * 25 + 250}ms`,\n        width: `${width}%`\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container\n    class=\"ma-0 pa-0 position-relative test-bg mh-100\"\n    :class=\"containerClass\"\n    fluid\n  >\n    <transition-group name=\"fade\" mode=\"out-in\">\n      <div\n        v-if=\"$vuetify.breakpoint.mdAndUp || $route.name == 'welcome'\"\n        key=\"slash-1\"\n        class=\"slash-blue o-slash slash-1\"\n        :class=\"[slash1Class, $vuetify.breakpoint.mdAndUp ? 'slash-1' : '']\"\n      >\n      </div>\n      <div\n        v-if=\"$vuetify.breakpoint.mdAndUp || nameTeamOrAcceptRoute\"\n        key=\"slash-3\"\n        class=\"slash-grey o-slash slash-3\"\n        :class=\"[slash3Class, $vuetify.breakpoint.mdAndUp ? 'slash-3' : '']\"\n      >\n      </div>\n      <div\n        v-if=\"$vuetify.breakpoint.mdAndUp\"\n        key=\"slash-4\"\n        class=\"slash-grey o-slash slash-4\"\n        :class=\"slash4Class\"\n      >\n      </div>\n      <div\n        v-if=\"$vuetify.breakpoint.mdAndUp\"\n        key=\"slash-5\"\n        class=\"slash-orange o-slash slash-5\"\n        :class=\"slash5Class\"\n      >\n      </div>\n\n      <div\n        v-if=\"$vuetify.breakpoint.mdAndUp && $route.name == 'welcome'\"\n        key=\"welcome-slashes\"\n      >\n        <div\n          v-for=\"i in noSlash\"\n          :key=\"`welcome-slash-${i}`\"\n          class=\"o-slash slash-2\"\n          :class=\"[\n            slash2Class,\n            i % 2 === 0 ? 'slash-blue' : 'slash-light-blue'\n          ]\"\n          :style=\"slash2Style(i)\"\n        ></div>\n      </div>\n\n      <div\n        v-if=\"$vuetify.breakpoint.mdAndUp && nameTeamOrAcceptRoute\"\n        key=\"name-team-slashes\"\n      >\n        <div\n          v-for=\"i in noSlash\"\n          :key=\"`name-team-slash-${i}`\"\n          class=\"o-slash slash-2\"\n          :class=\"[\n            slash2Class,\n            i % 2 === 0 ? 'slash-grey' : 'slash-grey-reverse'\n          ]\"\n          :style=\"slash2Style(i)\"\n        ></div>\n      </div>\n    </transition-group>\n\n    <transition name=\"fade\" mode=\"out-in\">\n      <router-view class=\"router-view\" style=\"z-index: 3;\" />\n    </transition>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.mh-100 {\n  min-height: 100vh !important;\n}\n\n.overflow-y-hidden {\n  overflow-y: hidden !important;\n}\n\n.bg-blue {\n  background-image: linear-gradient(\n    105deg,\n    #0e50f5,\n    var(--v-accentCyan-base)\n  ) !important;\n}\n\n.bg-grey {\n  background-image: linear-gradient(\n    105deg,\n    var(--v-secondary-base),\n    #647489\n  ) !important;\n}\n\n.o-slash {\n  backface-visibility: hidden;\n  position: absolute;\n  transition: all 250ms;\n\n  &.slash-full {\n    height: 100vh !important;\n    top: 0 !important;\n    transform: none;\n    width: 100% !important;\n\n    &.slash-4 {\n      left: 0 !important;\n      top: 0 !important;\n    }\n\n    &.slash-5 {\n      left: 0 !important;\n      top: 100vh !important;\n    }\n  }\n\n  &.slash-1 {\n    height: 500px;\n    top: 50%;\n    width: 100%;\n  }\n\n  &.slash-2 {\n    z-index: 1 !important;\n  }\n\n  &.slash-3 {\n    height: 600px;\n    top: 50%;\n    width: 100%;\n  }\n\n  &.slash-4 {\n    height: 600px;\n    left: 0;\n    top: 60%;\n    width: 49%;\n  }\n\n  &.slash-5 {\n    height: 600px;\n    right: 0;\n    top: 40%;\n    width: 49%;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Onboard/Resources.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport '@/styles/slash.scss'\n\nexport default {\n  data() {\n    return {\n      showDashboardNavigation: false,\n      showResources: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    slashClass() {\n      return {\n        slash: this.$vuetify.breakpoint.mdAndUp,\n        'slash-horizontal': this.$vuetify.breakpoint.smAndDown,\n        'slash-lg': this.$vuetify.breakpoint.lgAndUp,\n        // 'slash-shadow': this.$vuetify.breakpoint.mdAndUp,\n        'slash-transition': this.showResources,\n        'text-center': this.$vuetify.breakpoint.smAndDown\n      }\n    }\n  },\n  mounted() {\n    setTimeout(() => {\n      this.showResources = true\n    }, 250)\n\n    setTimeout(() => {\n      this.showDashboardNavigation = true\n    }, 1250)\n  }\n}\n</script>\n\n<template>\n  <v-container class=\"pa-0 h-100 fill-height\" style=\"max-width: 2560px;\" fluid>\n    <v-row v-if=\"$vuetify.breakpoint.mdAndUp\" style=\"z-index: 3;\">\n      <v-slide-x-transition>\n        <v-col v-if=\"showResources\" cols=\"12\" md=\"5\">\n          <div\n            class=\"d-flex align-center justify-center white--text fill-height\"\n            style=\"width: 100%;\"\n          >\n            <div class=\"d-flex flex-column slash-body\">\n              <div class=\"mb-8\">\n                <img\n                  class=\"photo\"\n                  src=\"@/assets/backgrounds/cloud-instructs.svg\"\n                  alt=\"Support Image\"\n                />\n              </div>\n              <div class=\"text-h3 font-weight-medium\">\n                Explore the Docs\n              </div>\n              <div class=\"text-h5 my-6\">\n                Get API references, walkthroughs, and tutorials\n              </div>\n              <div>\n                <v-btn\n                  color=\"accentPink\"\n                  dark\n                  target=\"_blank\"\n                  href=\"https://docs.prefect.io\"\n                >\n                  Prefect Docs\n                </v-btn>\n              </div>\n            </div>\n          </div>\n        </v-col>\n      </v-slide-x-transition>\n\n      <v-col class=\"d-flex align-center justify-center\" cols=\"12\" md=\"2\">\n        <transition name=\"fade\">\n          <v-btn\n            v-if=\"showDashboardNavigation\"\n            :href=\"`/${tenant.slug}`\"\n            data-cy=\"go-to-dashboard\"\n            class=\"dashboard-link-absolute\"\n            color=\"primary\"\n            x-large\n          >\n            To the dashboard!\n            <v-icon right>fas fa-rocket</v-icon>\n          </v-btn>\n        </transition>\n      </v-col>\n\n      <v-slide-x-reverse-transition>\n        <v-col v-if=\"showResources\" cols=\"12\" md=\"5\" class=\"pr-0\">\n          <div\n            class=\"d-flex align-center justify-center fill-height\"\n            style=\"width: 100%;\"\n          >\n            <div class=\"d-flex flex-column slash-body white--text\">\n              <div class=\"text-h3 font-weight-medium\">\n                Join our Community\n              </div>\n              <div class=\"text-h5 my-6\">\n                Chat with us, ask questions, and share tips\n              </div>\n              <div>\n                <v-btn target=\"_blank\" href=\"https://prefect.io/slack\">\n                  Join Slack\n                </v-btn>\n              </div>\n              <div class=\"mt-8\">\n                <img\n                  class=\"photo\"\n                  src=\"@/assets/backgrounds/join-our-community.svg\"\n                  alt=\"Support Image\"\n                />\n              </div>\n            </div>\n          </div>\n        </v-col>\n      </v-slide-x-reverse-transition>\n    </v-row>\n\n    <v-container\n      v-else\n      fluid\n      class=\"pa-0 d-flex align-content-space-between flex-column\"\n      style=\"min-height: 100%;\"\n    >\n      <div class=\"text-h4 white--text my-2 title-absolute text-center\">\n        You're all set!\n      </div>\n\n      <v-row class=\"flex-grow-1\" no-gutters>\n        <v-col class=\"d-flex align-center justify-center pa-0 \" cols=\"12\">\n          <v-carousel\n            height=\"100%\"\n            hide-delimiters\n            show-arrows\n            show-arrows-on-hover\n            cycle\n            continuous\n          >\n            <v-carousel-item :key=\"'resources'\">\n              <v-sheet\n                height=\"100%\"\n                class=\"text-center gradient-background orange--gradient d-flex align-center justify-center \"\n              >\n                <div class=\"d-flex flex-column\" style=\"z-index: 3;\">\n                  <div class=\"mb-8\">\n                    <img\n                      class=\"photo mx-auto\"\n                      src=\"@/assets/backgrounds/join-our-community.svg\"\n                      alt=\"Support Image\"\n                      style=\"width: 65%;\"\n                    />\n                  </div>\n                  <div class=\"text-h4 font-weight-medium\">\n                    Join our Community\n                  </div>\n                  <div class=\"text-subtitle-1 my-6\">\n                    Chat with us, ask questions, and share tips\n                  </div>\n\n                  <div>\n                    <v-btn\n                      color=\"white\"\n                      light\n                      depressed\n                      target=\"_blank\"\n                      href=\"https://prefect.io/slack\"\n                    >\n                      Join Slack\n                    </v-btn>\n                  </div>\n                </div>\n              </v-sheet>\n            </v-carousel-item>\n\n            <v-carousel-item :key=\"'docs'\">\n              <v-sheet\n                height=\"100%\"\n                class=\"text-center gradient-background grey--gradient d-flex align-center justify-center\"\n              >\n                <div\n                  class=\"d-flex flex-column align white--text\"\n                  style=\"z-index: 3;\"\n                >\n                  <div class=\"mb-8\">\n                    <img\n                      class=\"photo mx-auto\"\n                      src=\"@/assets/backgrounds/cloud-instructs.svg\"\n                      alt=\"Support Image\"\n                      style=\"width: 65%;\"\n                    />\n                  </div>\n                  <div class=\"text-h4 font-weight-medium\">\n                    Explore the Docs\n                  </div>\n                  <div class=\"text-subtitle-1 my-6\">\n                    Get API references, walkthroughs, and tutorials\n                  </div>\n                  <div>\n                    <v-btn\n                      color=\"accentPink\"\n                      dark\n                      depressed\n                      target=\"_blank\"\n                      href=\"https://docs.prefect.io\"\n                    >\n                      Prefect Docs\n                    </v-btn>\n                  </div>\n                </div>\n              </v-sheet>\n            </v-carousel-item>\n          </v-carousel>\n        </v-col>\n      </v-row>\n\n      <v-row\n        class=\"position-absolute dashboard-button-row-small mx-auto\"\n        no-gutters\n      >\n        <v-col cols=\"12\" class=\"text-center py-2\">\n          <v-btn\n            href=\"/\"\n            class=\"mx-auto\"\n            color=\"primary\"\n            x-large\n            style=\"z-index: 3;\"\n          >\n            To the dashboard!\n            <v-icon right>fas fa-rocket</v-icon>\n          </v-btn>\n        </v-col>\n      </v-row>\n    </v-container>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.dashboard-button-absolute {\n  bottom: 5vh;\n  left: 50%;\n  position: absolute;\n  transform: translate(-50%, -50%);\n}\n\n.dashboard-button-row-small {\n  bottom: 10px;\n  left: 50%;\n  transform: translate(-50%);\n}\n\n.title-absolute {\n  left: 50%;\n  position: absolute;\n  top: 25px;\n  transform: translate(-50%);\n}\n\n.gradient-background {\n  position: relative;\n\n  &::before {\n    content: '';\n    height: 100%;\n    position: absolute;\n    transform-origin: inherit;\n    transform-origin: 50% 50%;\n    transition-delay: inherit !important;\n    transition-duration: 500ms;\n    transition-property: all;\n    width: 100%;\n    z-index: 0;\n  }\n\n  &.orange--gradient::before {\n    background-image: linear-gradient(105deg, #ff60de, #ff4d20) !important;\n  }\n\n  &.grey--gradient::before {\n    background-image: linear-gradient(\n      105deg,\n      #647489,\n      var(--v-secondary-base)\n    ) !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Onboard/Welcome.vue",
    "content": "<script>\nexport default {\n  data() {\n    return {\n      welcome: false\n    }\n  },\n  mounted() {\n    setTimeout(() => {\n      this.welcome = true\n    }, 750)\n\n    setTimeout(() => {\n      this.$router.push({\n        name: 'name-team'\n      })\n    }, 3500)\n  }\n}\n</script>\n\n<template>\n  <v-container class=\"text-center pa-0\" fluid>\n    <v-slide-x-transition>\n      <div v-if=\"welcome\" class=\"grey--text text--lighten-5 welcome-text\">\n        <div class=\"text-h4\">\n          welcome to\n        </div>\n        <div class=\"logo\">\n          <img\n            class=\"ma-auto white--fill\"\n            src=\"@/assets/logos/cloud-logo-white.svg\"\n          />\n        </div>\n      </div>\n    </v-slide-x-transition>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.welcome-text {\n  left: 50%;\n  max-width: 700px;\n  position: absolute;\n  top: 50%;\n  transform: translate(-50%, -50%);\n  width: 100%;\n  z-index: 3;\n}\n\n.logo {\n  img {\n    height: auto;\n    max-width: 700px;\n    width: 90%;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Plans.vue",
    "content": "<script>\nimport EnterprisePlan from '@/components/Plans/Enterprise'\nimport PlanSelectionForm from '@/components/Plans/PlanSelectionForm'\nimport MenuTooltip from '@/components/MenuTooltip'\nimport StarterPlan from '@/components/Plans/Starter'\nimport StandardPlan from '@/components/Plans/Standard'\n\nimport {\n  PLANS_2021,\n  basicFeatures,\n  infrastructureFeatures,\n  observabilityFeatures,\n  orchestrationFeatures,\n  authorizationFeatures\n} from '@/utils/plans'\n\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    // ChangePlanDialog,\n    EnterprisePlan,\n    MenuTooltip,\n    PlanSelectionForm,\n    StandardPlan,\n    StarterPlan\n  },\n  data() {\n    return {\n      categories: [\n        { title: 'Basic', icon: 'fad fa-atom-alt', features: basicFeatures },\n        {\n          title: 'Auth',\n          icon: 'fad fa-user-shield',\n          features: authorizationFeatures\n        },\n        {\n          title: 'Infrastructure',\n          icon: 'fad fa-network-wired',\n          features: infrastructureFeatures\n        },\n        {\n          title: 'Observability',\n          icon: 'fad fa-chart-scatter',\n          features: observabilityFeatures\n        },\n        {\n          title: 'Orchestration',\n          icon: 'fad fa-chart-network',\n          features: orchestrationFeatures\n        }\n      ],\n      complete: false,\n      plans: PLANS_2021,\n      plan: null,\n      planValue: 2\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license', 'tempLicenseType', 'hasPermission']),\n    ...mapGetters('tenant', ['tenant']),\n    planClass() {\n      return {\n        'scale-100': this.$vuetify.breakpoint.lgAndUp,\n        'scale-85': this.$vuetify.breakpoint.mdOnly,\n        'scale-75': this.$vuetify.breakpoint.smOnly\n      }\n    },\n    plansContainerClass() {\n      return {\n        'd-flex': true,\n        'justify-center': true,\n        'align-center': true,\n        'flex-column': this.$vuetify.breakpoint.smAndDown\n      }\n    },\n    permissionsCheck() {\n      return this.hasPermission('create', 'license')\n    }\n  },\n  methods: {\n    goBack() {\n      this.$router.back()\n    },\n    handlePlanSelection(type) {\n      this.plan = type\n      this.planValue = type == 'starter' ? 1 : 2\n    },\n    handlePlanDeselection() {\n      this.plan = null\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div class=\"position-relative\">\n      <div class=\"position-relative my-0\">\n        <div class=\"slash-container\">\n          <div class=\"slash slash-0\"></div>\n          <div class=\"slash slash-1\"></div>\n          <div class=\"slash slash-2\"></div>\n          <div class=\"slash slash-3\"></div>\n          <div class=\"slash slash-4\"></div>\n        </div>\n\n        <div class=\"header-container\">\n          <div\n            class=\"back-button d-inline-block text-h6 font-weight-light mx-auto cursor-pointer white--text\"\n            @click=\"goBack\"\n          >\n            <v-icon color=\"blue-grey lighten-3\">chevron_left</v-icon>\n            Back\n          </div>\n\n          <div class=\"text-h3 font-weight-light text-center\">\n            <div class=\"blue-grey--text text--darken-4\">\n              Simple,\n              <span>success-based pricing</span>.\n            </div>\n            <div class=\"mt-4 white--text\">\n              Eliminate negative engineering.\n            </div>\n          </div>\n\n          <transition-group\n            name=\"flex\"\n            mode=\"out-in\"\n            class=\"plans-container mt-8 mx-8\"\n            :class=\"plansContainerClass\"\n          >\n            <StarterPlan\n              v-if=\"(!plan || plan == 'starter') && !complete\"\n              key=\"starter\"\n              :hide-details=\"!!plan\"\n              :disabled=\"!permissionsCheck\"\n              @click=\"handlePlanSelection('starter')\"\n            />\n\n            <StandardPlan\n              v-if=\"(!plan || plan == 'standard') && !complete\"\n              key=\"standard\"\n              :hide-details=\"!!plan\"\n              :disabled=\"!permissionsCheck\"\n              @click=\"handlePlanSelection('standard')\"\n            />\n\n            <EnterprisePlan\n              v-if=\"!plan && !complete\"\n              key=\"enterprise\"\n              class=\"mt-md-16 mt-0\"\n              :hide-details=\"!!plan\"\n            />\n\n            <div\n              v-if=\"plan\"\n              key=\"payment-form\"\n              class=\"plan-container mt-n4 px-12 px-md-0\"\n            >\n              <PlanSelectionForm\n                :plan-reference=\"plan\"\n                @complete=\"complete = true\"\n              />\n            </div>\n          </transition-group>\n\n          <div v-if=\"plan && !complete\" class=\"text-center mt-8\">\n            <div\n              class=\"d-inline-block text-h6 font-weight-light mx-auto cursor-pointer\"\n              @click=\"handlePlanDeselection\"\n            >\n              <v-icon color=\"blue-grey\">chevron_left</v-icon>\n              Choose a different plan\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n\n    <transition name=\"quick-fade\">\n      <div v-if=\"!complete\" class=\"features-container utilGrayDark--text\">\n        <div class=\"text-center text-h3 font-weight-light\">Features</div>\n\n        <div class=\"text-center mt-8\">\n          <fieldset class=\"multiswitch\">\n            <legend class=\"text-h5 font-weight-light\">\n              Select a plan to view features\n            </legend>\n\n            <div class=\"slide-container text-h6 font-weight-light\">\n              <input\n                id=\"starter\"\n                v-model=\"planValue\"\n                type=\"radio\"\n                name=\"plan\"\n                :value=\"1\"\n              />\n              <label for=\"starter\">Starter</label>\n              <input\n                id=\"standard\"\n                v-model=\"planValue\"\n                type=\"radio\"\n                name=\"plan\"\n                :value=\"2\"\n                checked\n                required\n              />\n              <label for=\"standard\">Standard</label>\n              <input\n                id=\"enterprise\"\n                v-model=\"planValue\"\n                type=\"radio\"\n                name=\"plan\"\n                :value=\"3\"\n              />\n              <label for=\"enterprise\">Enterprise</label>\n\n              <a class=\"slide\" aria-hidden=\"true\"></a>\n            </div>\n          </fieldset>\n        </div>\n\n        <div class=\"features-body\">\n          <v-row no-gutters>\n            <v-col\n              v-for=\"category in categories\"\n              :key=\"category.title\"\n              cols=\"12\"\n              sm=\"6\"\n              md=\"4\"\n              class=\"d-flex align-start justify-center my-8\"\n            >\n              <div class=\"features-category\">\n                <div class=\"feature-category-icon\">\n                  <v-icon large>\n                    {{ category.icon }}\n                  </v-icon>\n                </div>\n\n                <div class=\"text-h4 font-weight-light my-4\">\n                  {{ category.title }}\n                </div>\n                <div\n                  v-for=\"feature in category.features\"\n                  :key=\"feature.name\"\n                  class=\"text-h6 font-weight-regular my-2\"\n                >\n                  <MenuTooltip\n                    hide-close\n                    offset-y\n                    top\n                    nudge-top=\"12px\"\n                    transition=\"slide-y-reverse-transition\"\n                  >\n                    <template #activator>\n                      <div\n                        class=\"d-flex justify-start align-center utilGrayDark--text flex-grow-1 feature-list-title\"\n                        :class=\"{\n                          'o-50': feature.value && planValue < feature.value\n                        }\"\n                        style=\"transition: all 150ms ease-in-out;\"\n                      >\n                        <span\n                          class=\"flex-grow-0 flex-shrink-0 feature-list-icon\"\n                          :class=\"{\n                            'empty-circle': feature.plan == 'starter',\n                            'feature-list-icon-disabled':\n                              feature.value && planValue < feature.value\n                          }\"\n                        >\n                          <v-icon v-if=\"feature.plan == 'enterprise'\" x-small>\n                            fas fa-circle fa-fw\n                          </v-icon>\n                          <v-icon\n                            v-else-if=\"feature.plan == 'standard'\"\n                            x-small\n                          >\n                            fad fa-dot-circle fa-fw\n                          </v-icon>\n                          <v-icon v-else-if=\"feature.plan == 'starter'\" x-small>\n                            fad fa-dot-circle fa-fw\n                          </v-icon>\n                          <v-icon v-else x-small>fas fa-check fa-fw</v-icon>\n                        </span>\n                        <div class=\"flex-shrink-0 flex-grow-1 ml-2\">\n                          {{ feature.name }}\n                        </div>\n                      </div>\n                    </template>\n\n                    <div\n                      class=\"utilGrayDark--text text--darken-1 text-subtitle-1\"\n                    >\n                      {{ feature.description }}\n                      <div\n                        v-if=\"feature.plan == 'enterprise'\"\n                        class=\"text--disabled font-weight-light mt-4\"\n                      >\n                        Available only on\n                        <span class=\"text-overline primary--text\"\n                          >enterprise</span\n                        >\n                        plans\n                      </div>\n                      <div\n                        v-else-if=\"feature.plan == 'standard'\"\n                        class=\"text--disabled font-weight-light mt-4\"\n                      >\n                        Available on\n                        <span class=\"text-overline primary--text\"\n                          >standard</span\n                        >\n                        plans and above\n                      </div>\n                      <div\n                        v-else-if=\"feature.plan == 'starter'\"\n                        class=\"text--disabled font-weight-light mt-4\"\n                      >\n                        Available on\n                        <span class=\"text-overline primary--text\">starter</span>\n                        plans and above\n                      </div>\n                      <div v-else class=\"text--disabled font-weight-light mt-4\">\n                        Available on all plans\n                      </div>\n                    </div>\n                  </MenuTooltip>\n                </div>\n              </div>\n            </v-col>\n          </v-row>\n        </div>\n      </div>\n    </transition>\n    <transition name=\"quick-fade\">\n      <div v-if=\"!complete\" class=\"support-container\">\n        <div class=\"slash-container\">\n          <div class=\"slash slash-5\"></div>\n          <div class=\"slash slash-6\"></div>\n        </div>\n\n        <v-card\n          class=\"pa-8 margin-auto support-card elevation-4 rounded d-flex align-start justify-start\"\n          tile\n        >\n          <div class=\"d-inline-block support-icon\">\n            <v-icon large>fad fa-concierge-bell</v-icon>\n          </div>\n\n          <v-row class=\"ml-4\" no-gutters>\n            <v-col cols=\"12\" sm=\"8\">\n              <div class=\"utilGrayDark--text text-h4 font-weight-light pa-0\">\n                <span>Premium Support</span>\n              </div>\n              <div\n                class=\"mt-2 text-h6 font-weight-light utilGrayDark--text pa-0\"\n              >\n                A support plan built to help you quickly grow your workflows.\n\n                <div class=\"mt-2 support-table text-h6 font-weight-light\">\n                  <div class=\"my-2 mr-6\">\n                    <span class=\"support-icon mr-2\">\n                      <v-icon>fad fa-badge-check</v-icon>\n                    </span>\n                    Faster, prioritized support responses\n                  </div>\n                  <div class=\"my-2 mr-6\">\n                    <span class=\"support-icon mr-2\">\n                      <v-icon>fad fa-badge-check</v-icon>\n                    </span>\n                    Dedicated support manager\n                  </div>\n                  <div class=\"my-2 mr-6\">\n                    <span class=\"support-icon mr-2\">\n                      <v-icon>fad fa-badge-check</v-icon>\n                    </span>\n                    Emergency support for critical issues\n                  </div>\n                </div>\n              </div>\n            </v-col>\n            <v-col cols=\"12\" sm=\"4\" class=\"d-flex align-center justify-start\">\n              <v-divider class=\"d-inline-block\" vertical />\n              <div class=\"ml-8\">\n                <div class=\"text-h4 accentGreen--text\">\n                  Support built for you\n                </div>\n                <a\n                  class=\"utilGrayDark--text support-link text-h6 font-weight-regular mt-4\"\n                  href=\"https://www.prefect.io/pricing#contact\"\n                  target=\"_blank\"\n                  >Contact us\n                  <v-icon class=\"mb-1\" color=\"grey\">arrow_right</v-icon>\n                </a>\n              </div>\n            </v-col>\n          </v-row>\n        </v-card>\n      </div>\n    </transition>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.slash-container {\n  bottom: 100px;\n  left: 0;\n  position: absolute;\n  right: 0;\n  top: calc(50% + 75px);\n  transform: skewY(-12deg);\n\n  .slash {\n    left: 0;\n    position: absolute;\n    right: 0;\n    top: auto;\n    width: 100%;\n\n    &.slash-0 {\n      background-image: linear-gradient(105deg, #0e50f5, #2edaff) !important;\n      bottom: 10px;\n      height: 5000px;\n    }\n\n    &.slash-1 {\n      background: #27b1ff !important;\n      bottom: 160px;\n      height: 150px;\n      width: 500px;\n    }\n\n    &.slash-2 {\n      background: #3b8dff !important;\n      bottom: 660px;\n      height: 150px;\n      left: auto;\n      right: 0;\n      width: 500px;\n    }\n\n    &.slash-3 {\n      background: #2580ff !important;\n      bottom: 10px;\n      height: 150px;\n      left: 100px;\n      width: 500px;\n    }\n\n    &.slash-4 {\n      background: #27b1ff !important;\n      bottom: 310px;\n      height: 150px;\n      left: 1200px;\n      width: 800px;\n    }\n\n    &.slash-5 {\n      background: #27b1ff !important;\n      bottom: 160px;\n      height: 75px;\n      left: 0;\n      width: 500px;\n    }\n\n    &.slash-6 {\n      background: #2edaff !important;\n      bottom: -75px;\n      height: 75px;\n      left: auto;\n      right: 0;\n      width: 500px;\n    }\n  }\n}\n\n.header-container {\n  min-height: 1072px;\n  padding-top: 48px;\n  position: relative;\n  z-index: 1;\n}\n\n.back-button {\n  left: 24px;\n  position: absolute;\n  top: 24px;\n}\n\n.plan-container {\n  transition: all 250ms;\n}\n\n.features-container {\n  margin-top: 175px;\n  position: relative;\n\n  .features-body {\n    margin: auto;\n    margin-top: 48px;\n    max-width: 1200px;\n  }\n\n  .features-category {\n    height: 100%;\n    max-width: 400px;\n    min-width: 300px;\n    padding: 0 50px;\n    width: 100%;\n  }\n\n  .feature-list-title {\n    cursor: pointer;\n\n    &:hover,\n    &:focus {\n      color: var(--v-primary-base) !important;\n    }\n  }\n\n  .plan-title {\n    letter-spacing: 0.15rem;\n    text-transform: uppercase;\n  }\n}\n\n.multiswitch {\n  $steps: 6, 8, 10, 12;\n  $third: calc(100% / 3);\n\n  border: 0;\n  margin: auto;\n  width: 450px;\n\n  a {\n    background: var(--v-primary-base);\n    border-radius: 4px;\n    height: 100%;\n    position: absolute;\n    top: 50%;\n    transform: translate(0, -50%);\n    transition: all 0.15s ease-in-out;\n    width: #{$third};\n    z-index: 1;\n  }\n\n  input {\n    left: -200vw;\n    position: absolute;\n  }\n\n  label {\n    cursor: pointer;\n    text-align: center;\n    transition: all 0.15s ease-in-out;\n    width: #{$third};\n    z-index: 2;\n  }\n\n  input:checked {\n    ~ a {\n      left: 0;\n    }\n\n    + label {\n      color: #fff;\n      font-weight: 400;\n    }\n  }\n\n  @for $i from 1 through 3 {\n    input:nth-of-type(#{$i}):checked ~ a {\n      left: calc(#{$third} * (#{$i} - 1));\n    }\n  }\n\n  .slide-container {\n    background-color: #eee;\n    border-radius: 4px;\n    box-sizing: content-box;\n    color: var(--v-secondaryGrayDark-base);\n    display: flex;\n    margin-top: 8px;\n    overflow: hidden;\n    padding: 6px 0;\n    position: relative;\n    user-select: none;\n  }\n}\n\n.support-container {\n  margin-bottom: 264px;\n  margin-top: 64px;\n  position: relative;\n\n  .support-card {\n    margin: auto;\n    max-width: 1200px;\n\n    .support-table {\n      display: grid;\n      grid-template-columns: 1fr 1fr;\n    }\n\n    .support-link {\n      color: inherit !important;\n      cursor: pointer;\n      display: block;\n      text-decoration: none;\n    }\n  }\n}\n</style>\n\n<style lang=\"scss\">\n.flex-enter-active {\n  animation: flex-enter 750ms ease;\n}\n\n.flex-leave-active {\n  animation: flex-leave 500ms ease;\n  position: absolute;\n  z-index: -1;\n}\n\n@keyframes flex-enter {\n  0% {\n    opacity: 0;\n    transform: translate(0) scale(0);\n  }\n\n  50% {\n    opacity: 0;\n    transform: translate(0) scale(0.4);\n  }\n\n  100% {\n    opacity: 1;\n    transform: translate(0) scale(1);\n  }\n}\n\n@keyframes flex-leave {\n  0% {\n    opacity: 1;\n    transform: translate(0) scale(1);\n  }\n\n  50% {\n    opacity: 0.1;\n    transform: translate(0) scale(0.4);\n  }\n\n  100% {\n    opacity: 0;\n    transform: translate(100px) scale(0);\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Schematics/Schematics.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nexport default {\n  data() {\n    return {}\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('auth', ['authorizationToken'])\n  },\n  watch: {\n    authorizationToken(val) {\n      if (val) {\n        this.$apollo.queries.flows.refetch()\n      }\n    },\n    flows(val) {\n      if (!val) return\n      if (!this.$route.params || !this.$route.params.id) {\n        if (val[0]) {\n          this.$router.push({\n            params: { id: val[0].id, tenant: this.tenant?.slug }\n          })\n        }\n      }\n    }\n  },\n  mounted() {},\n  methods: {},\n  apollo: {\n    flows: {\n      query: require('@/graphql/Schematics/flow-list.gql'),\n      update: data => {\n        if (data.flow) return data.flow\n      },\n      fetchPolicy: 'no-cache'\n    }\n  }\n}\n</script>\n\n<template>\n  <div class=\"h-100 w-100 pa-0 ma-0\">\n    <v-navigation-drawer\n      clipped\n      left\n      app\n      permanent\n      touchless\n      :mini-variant=\"$vuetify.breakpoint.smAndDown\"\n    >\n      <template #prepend>\n        <v-list-item>\n          <v-list-item-avatar>\n            <v-icon class=\"blue--text accent-4\">\n              account_tree\n            </v-icon>\n          </v-list-item-avatar>\n          <v-list-item-content>\n            <div class=\"font-weight-medium\">\n              Flow Schematics\n            </div>\n          </v-list-item-content>\n        </v-list-item>\n      </template>\n\n      <v-divider />\n\n      <v-list dense>\n        <v-list-item\n          v-for=\"flow in flows\"\n          :key=\"flow.id\"\n          :to=\"{ params: { id: flow.id } }\"\n          ripple\n          exact\n        >\n          <v-list-item-action>\n            <v-icon>timeline</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>{{ flow.name }}</v-list-item-title>\n            <v-list-item-subtitle class=\"id-subtitle\">\n              {{ flow.id }}\n            </v-list-item-subtitle>\n          </v-list-item-content>\n        </v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n\n    <router-view class=\"pa-0 grey lighten-5\" style=\"min-height: 100%;\" />\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\nsvg {\n  cursor: grab;\n  user-select: none;\n\n  &:active {\n    cursor: grabbing;\n  }\n}\n\n.id-subtitle {\n  font-size: 0.6rem !important;\n}\n\n.h-100 {\n  height: calc(100vh - 64px);\n}\n</style>\n"
  },
  {
    "path": "src/pages/Schematics/View.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport SchematicFlow from '@/components/Schematics/Schematic-Flow'\n\nexport default {\n  components: {\n    SchematicFlow\n  },\n  data() {\n    return {\n      flow: null,\n      loading: 0,\n      tasks: []\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant'])\n  },\n  watch: {\n    tenant() {\n      this.$apollo.queries.flow.refetch()\n    }\n  },\n  apollo: {\n    flow: {\n      query: require('@/graphql/Schematics/flow.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {\n          id: this.$route.params.id\n        }\n      },\n      skip() {\n        return !this.$route.params.id\n      },\n      update(data) {\n        if (data.flow && data.flow.length) {\n          this.tasks = data.flow[0].tasks\n          return data.flow[0]\n        } else {\n          this.tasks = []\n        }\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container class=\"ma-0 pa-0 fill-height\" fluid>\n    <v-card\n      v-if=\"!$route.params.id && loading === 0\"\n      class=\"no-flows pa-10 text-center\"\n    >\n      <div class=\"my-4 text-h4\">You have no flows 🤖</div>\n      <div class=\"text-body-2\"\n        >To learn how to deploy a flow, visit our\n        <a\n          href=\"https://docs.prefect.io/cloud/flow-deploy.html#prefect-cloud-deploying-a-flow\"\n          target=\"_blank\"\n          >docs</a\n        >.</div\n      >\n    </v-card>\n\n    <v-row no-gutters>\n      <v-col class=\"full-height\">\n        <SchematicFlow :dev-toolbar=\"true\" :tasks=\"tasks\" />\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.full-height {\n  height: calc(100vh - 64px) !important;\n  min-height: calc(100vh - 64px) !important;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Support.vue",
    "content": "<script>\nimport LogRocket from 'logrocket'\nimport { mapGetters } from 'vuex'\n\nconst categories = [\n  { category: 'I need help', message: 'How can we help?' },\n  {\n    category: \"I've found a bug\",\n    message: \"Please describe what you're seeing\"\n  },\n  {\n    category: 'I have some feedback',\n    message: 'Let us know how we can improve!'\n  },\n  { category: 'Something else', message: \"Let us know what you're thinking\" }\n]\n\nexport default {\n  data() {\n    return {\n      categories: categories,\n      error: false,\n      loading: false,\n      messageRules: [v => !!v || 'Message is required'],\n      message: null,\n      success: false,\n      selectedCategory: 'I need help',\n      valid: true\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['user']),\n    messageLabel() {\n      return this.categories.find(c => c.category == this.selectedCategory)\n        ?.message\n    },\n    mdScreen() {\n      return this.$vuetify?.breakpoint?.mdAndUp\n    }\n  },\n  methods: {\n    submit() {\n      this.error = false\n\n      if (this.$refs.form.validate()) {\n        this.loading = true\n        this.sendFeedback()\n      } else {\n        this.error = true\n      }\n    },\n    async sendFeedback() {\n      try {\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/support/send-feedback.gql'),\n          variables: {\n            type: this.selectedCategory,\n            message: this.message\n          }\n        })\n        this.success = data?.send_feedback?.success\n        this.error = !data?.send_feedback?.success\n      } catch (e) {\n        this.error = true\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Support',\n            stage: 'Form Submit'\n          }\n        })\n      }\n\n      this.loading = false\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container class=\"body\" fluid>\n    <v-row class=\"pa-12\">\n      <v-card class=\"pa-12 mx-auto\" tile>\n        <v-card-text>\n          <v-row class=\"pa-12\">\n            <v-col\n              cols=\"12\"\n              md=\"6\"\n              :class=\"mdScreen ? 'text-right' : 'text-center'\"\n              class=\"d-flex justify-center flex-column\"\n            >\n              <img\n                class=\"photo\"\n                src=\"@/assets/backgrounds/support_illustration.svg\"\n                alt=\"Support Image\"\n              />\n            </v-col>\n            <v-col\n              cols=\"12\"\n              md=\"6\"\n              :class=\"mdScreen ? 'text-left' : 'text-center'\"\n              class=\"d-flex justify-center flex-column\"\n            >\n              <v-fade-transition mode=\"out-in\">\n                <div v-if=\"!success\" key=\"description\">\n                  <div class=\"text-h5\">\n                    How can we help?\n                  </div>\n                  <div class=\"text-subtitle-1 my-4\">\n                    Let us know how our team can improve your experience. We're\n                    up to the task!\n                  </div>\n\n                  <v-form v-if=\"!success\" ref=\"form\" v-model=\"valid\">\n                    <v-select\n                      v-model=\"selectedCategory\"\n                      :disabled=\"loading\"\n                      :items=\"categories\"\n                      item-text=\"category\"\n                      item-value=\"category\"\n                      outlined\n                    ></v-select>\n\n                    <v-textarea\n                      v-model=\"message\"\n                      :disabled=\"loading\"\n                      :label=\"messageLabel\"\n                      :rules=\"messageRules\"\n                      required\n                      auto-grow\n                      row-height=\"4\"\n                    />\n                    <v-btn\n                      :disabled=\"!valid\"\n                      :loading=\"loading\"\n                      color=\"primary\"\n                      class=\"mt-4\"\n                      depressed\n                      @click=\"submit\"\n                    >\n                      Submit\n                    </v-btn>\n                  </v-form>\n\n                  <v-fade-transition mode=\"out-in\">\n                    <div v-if=\"error\" key=\"error\" class=\"primary--text mt-4\">\n                      Oh no! It looks like we didn't quite get your message.\n                      Please try again, or feel free to send us an email at\n                      help@prefect.io!\n                    </div>\n                  </v-fade-transition>\n                </div>\n\n                <div v-else-if=\"success\" key=\"success\">\n                  <div class=\"text-h5\">\n                    We got your message!\n                  </div>\n                  <div class=\"text-subtitle-1 my-4\">\n                    <span v-if=\"selectedCategory == 'I need help'\">\n                      Don't panic! We'll be in touch as soon as possible. <br />\n                      While you wait, you can\n                    </span>\n\n                    <span v-if=\"selectedCategory == 'I\\'ve found a bug'\">\n                      You rock! We'll get our team on it immediately. <br />\n                      By the way, you can\n                    </span>\n\n                    <span v-if=\"selectedCategory == 'I have some feedback'\">\n                      Thanks for letting us know! We're always looking to\n                      improve.\n                      <br />\n                      If you haven't already,\n                    </span>\n\n                    <span v-if=\"selectedCategory == 'Something else'\">\n                      Thanks! We'll look into your message as soon as possible.\n                      <br />\n                      If you haven't already,\n                    </span>\n\n                    <a target=\"_blank\" href=\"https://prefect.io/slack\"\n                      >join our Slack</a\n                    >\n                    to ask questions, provide feedback, or just to chat! You can\n                    also check out our\n                    <a target=\"_blank\" href=\"https://docs.prefect.io\">docs</a>,\n                    which are filled with lots of helpful tutorials,\n                    explanations, and useful information.\n                  </div>\n                </div>\n              </v-fade-transition>\n            </v-col>\n          </v-row>\n        </v-card-text>\n      </v-card>\n    </v-row>\n    <v-row class=\"text-center pa-12\" align=\"end\" justify=\"end\">\n      <v-col class=\"d-flex flex-column\">\n        <div class=\"text-h6 font-weight-medium primary--text\">\n          Explore the Docs\n        </div>\n        <div class=\"text-h6 my-6\">\n          Endless possibilities with Prefect automation\n        </div>\n        <div>\n          <v-btn\n            color=\"accentOrange\"\n            outlined\n            dark\n            depressed\n            target=\"_blank\"\n            href=\"https://docs.prefect.io\"\n          >\n            Prefect Docs\n          </v-btn>\n        </div>\n      </v-col>\n      <v-col>\n        <div class=\"text-h6 font-weight-medium primary--text\">\n          Join our Slack\n        </div>\n        <div class=\"text-h6 my-6\">\n          Chat with us, ask questions, and share tips\n        </div>\n        <div>\n          <v-btn\n            color=\"accentOrange\"\n            outlined\n            dark\n            depressed\n            target=\"_blank\"\n            href=\"https://prefect.io/slack\"\n          >\n            Join Slack\n          </v-btn>\n        </div>\n      </v-col>\n      <v-col>\n        <div class=\"text-h6 font-weight-medium primary--text\">\n          Read the Blog\n        </div>\n        <div class=\"text-h6 my-6\">\n          Find our updates, tutorials, and announcements\n        </div>\n        <div>\n          <v-btn\n            color=\"accentOrange\"\n            outlined\n            dark\n            depressed\n            target=\"_blank\"\n            href=\"https://medium.com/the-prefect-blog\"\n          >\n            Read our blog\n          </v-btn>\n        </div>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<style lang=\"scss\">\n.body {\n  // background-image: linear-gradient(to bottom right, #2196f3 49.9%, #fff 50%);\n  height: 100%;\n}\n\n.row {\n  max-height: 80vh;\n}\n\n.photo-wrapper {\n  max-width: 700px;\n  position: relative;\n\n  @media screen and (max-width: 1366px) {\n    max-width: 470px;\n  }\n}\n\n.photo {\n  max-width: 700px;\n  width: 100%;\n\n  @media screen and (max-width: 1366px) {\n    max-width: 470px;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Task/Dependencies-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport SchematicFlow from '@/components/Schematics/Schematic-Flow'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  filters: {\n    typeClass: val => val.split('.').pop()\n  },\n  components: {\n    CardTitle,\n    SchematicFlow\n  },\n  props: {\n    downstreamCount: {\n      type: Number,\n      required: false,\n      default: () => null\n    },\n    flow: {\n      type: Object,\n      required: false,\n      default: () => {}\n    },\n    loading: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    tasks: {\n      type: Array,\n      required: true\n    },\n    upstreamCount: {\n      type: Number,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      expanded: true,\n      showCards: true,\n      task: this.tasks.find(task => task.id == this.$route.params.id)\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone']),\n    subtitle() {\n      return `${this.upstreamCount} Upstream • ${this.downstreamCount} Downstream`\n    }\n  },\n  watch: {\n    '$route.query.schematic'(val) {\n      this.setTask(val)\n    },\n    tasks() {\n      this.setTask(this.$route.query.schematic)\n    }\n  },\n  methods: {\n    setTask(id) {\n      if (!id) {\n        this.task = null\n      } else {\n        this.task = this.tasks.find(task => task.id == id)\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"pa-2\" tile>\n    <CardTitle title=\"Dependencies\" icon=\"share\" :subtitle=\"subtitle\">\n      <div slot=\"action\" class=\"d-flex align-end justify-center flex-column\">\n        <v-checkbox\n          v-model=\"showCards\"\n          dense\n          label=\"Show Cards\"\n          color=\"primary\"\n          class=\"my-0 mr-4\"\n          hide-details\n        ></v-checkbox>\n      </div>\n    </CardTitle>\n\n    <v-card-text class=\"full-height position-relative\">\n      <SchematicFlow\n        v-if=\"!loading\"\n        :tasks=\"tasks\"\n        :show-cards=\"showCards\"\n        :schematic-id=\"flow ? flow.id : null\"\n      />\n      <v-skeleton-loader v-else type=\"image\" />\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.full-height {\n  min-height: 68vh;\n}\n\n.task-tile {\n  right: 1rem;\n  top: 1rem;\n  width: 250px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Task/Details-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport Parameters from '@/components/Parameters'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  filters: {\n    typeClass: val => val.split('.').pop()\n  },\n  components: {\n    CardTitle,\n    Parameters\n  },\n  mixins: [formatTime],\n  props: {\n    lastRun: {\n      type: Object,\n      required: false,\n      default: () => null\n    },\n    loading: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    task: {\n      type: Object,\n      required: false,\n      default: () => null\n    },\n    fullHeight: {\n      required: false,\n      type: Boolean,\n      default: () => false\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card\n    class=\"pa-2\"\n    tile\n    :style=\"{\n      height: fullHeight ? '100%' : 'auto'\n    }\"\n  >\n    <v-system-bar\n      :color=\"!loading && lastRun ? lastRun.state : 'grey'\"\n      :height=\"5\"\n      absolute\n    >\n    </v-system-bar>\n    <CardTitle\n      :loading=\"loading\"\n      :title=\"task ? task.name : null\"\n      icon=\"pi-task\"\n    />\n\n    <v-card-text class=\"pl-12\">\n      <v-list-item\n        v-if=\"!loading\"\n        dense\n        two-line\n        :to=\"{ name: 'flow', params: { id: task.flow.id } }\"\n        class=\"px-0\"\n      >\n        <v-list-item-content>\n          <span class=\"text-caption mb-0\">\n            Flow\n          </span>\n          <v-list-item-title class=\"text-body-2\">\n            <span>{{ task.flow.name }}</span>\n          </v-list-item-title>\n          <v-list-item-subtitle class=\"text-caption\">\n            Version {{ task.flow.version }}\n          </v-list-item-subtitle>\n        </v-list-item-content>\n      </v-list-item>\n\n      <v-skeleton-loader v-else type=\"list-item-two-line\" />\n\n      <v-list-item\n        v-if=\"!loading && task && task.description\"\n        dense\n        class=\"px-0\"\n      >\n        <v-list-item-content>\n          <v-list-item-subtitle class=\"text-caption\">\n            Description\n          </v-list-item-subtitle>\n          <div class=\"text-caption\">{{ task.description }} </div>\n        </v-list-item-content>\n      </v-list-item>\n\n      <v-list-item dense class=\"pa-0\">\n        <v-list-item-content>\n          <v-list-item-subtitle class=\"text-caption\">\n            <v-row no-gutters>\n              <v-col cols=\"6\">\n                Created\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                <span v-if=\"!loading\">{{ formatTime(task.created) }}</span>\n                <v-skeleton-loader v-else type=\"text\" />\n              </v-col>\n            </v-row>\n            <v-row no-gutters>\n              <v-col cols=\"6\">\n                Class\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                <span v-if=\"!loading\"> {{ task.type | typeClass }}</span>\n                <v-skeleton-loader v-else type=\"text\" />\n              </v-col>\n            </v-row>\n            <v-row no-gutters>\n              <v-col cols=\"6\">\n                Trigger\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                <span v-if=\"!loading\">{{ task.trigger | typeClass }}</span>\n                <v-skeleton-loader v-else type=\"text\" />\n              </v-col>\n            </v-row>\n            <v-row no-gutters>\n              <v-col cols=\"6\">\n                Max Retries\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                <span v-if=\"!loading\">{{ task.max_retries }}</span>\n                <v-skeleton-loader v-else type=\"text\" />\n              </v-col>\n            </v-row>\n            <v-row v-if=\"!loading && task.max_retries\" no-gutters>\n              <v-col cols=\"6\">\n                Retry Delay\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                {{ task.retry_delay }}\n              </v-col>\n            </v-row>\n          </v-list-item-subtitle>\n        </v-list-item-content>\n      </v-list-item>\n\n      <v-list-item\n        v-if=\"!loading && $options.filters.typeClass(task.type) == 'Parameter'\"\n        two-line\n        class=\"px-0\"\n      >\n        <v-list-item-content>\n          <v-list-item-subtitle class=\"text-caption\">\n            <span class=\"mb-0\">\n              Parameter:\n            </span>\n            <Parameters\n              :parameters=\"\n                task.flow.parameters.filter(param => param.name == task.name)\n              \"\n              hide-title\n            ></Parameters>\n          </v-list-item-subtitle>\n        </v-list-item-content>\n      </v-list-item>\n    </v-card-text>\n  </v-card>\n</template>\n"
  },
  {
    "path": "src/pages/Task/Task.vue",
    "content": "<script>\nimport BreadCrumbs from '@/components/BreadCrumbs'\nimport NavTabBar from '@/components/NavTabBar'\nimport DependenciesTile from '@/pages/Task/Dependencies-Tile'\nimport DetailsTile from '@/pages/Task/Details-Tile'\nimport SubPageNav from '@/layouts/SubPageNav'\nimport TaskRunHeartbeatTile from '@/pages/Task/TaskRunHeartbeat-Tile'\nimport TaskRunTableTile from '@/pages/Task/TaskRunTable-Tile'\nimport TileLayout from '@/layouts/TileLayout'\nimport TileLayoutFull from '@/layouts/TileLayout-Full'\nimport { mapActions } from 'vuex'\n\nexport default {\n  metaInfo() {\n    return {\n      title: this.task ? `Task | ${this.task?.name}` : null\n    }\n  },\n  components: {\n    BreadCrumbs,\n    DependenciesTile,\n    DetailsTile,\n    NavTabBar,\n    SubPageNav,\n    TaskRunHeartbeatTile,\n    TaskRunTableTile,\n    TileLayout,\n    TileLayoutFull\n  },\n  async beforeRouteLeave(to, from, next) {\n    if (to.name == 'task') {\n      await this.activateTask(to.params.id)\n    } else {\n      this.resetActiveData()\n    }\n    return next()\n  },\n  data() {\n    return {\n      loading: 0,\n      tabs: [\n        {\n          name: 'Overview',\n          target: 'overview',\n          icon: 'view_module'\n        },\n        {\n          name: 'Runs',\n          target: 'runs',\n          icon: 'pi-task-run'\n        }\n      ]\n    }\n  },\n  computed: {\n    dependencies() {\n      if (!this.task) return []\n      let upstream = this.task.upstream_edges.map(edge => {\n        return {\n          ...edge.upstream_task,\n          downstream_edges: [],\n          upstream_edges: []\n        }\n      })\n      let downstream = this.task.downstream_edges.map(edge => {\n        return {\n          ...edge.downstream_task,\n          downstream_edges: [],\n          upstream_edges: [{ upstream_task: { id: this.taskId } }]\n        }\n      })\n\n      return [this.task, ...upstream, ...downstream]\n    },\n    downstreamCount() {\n      if (!this.task) return null\n      return this.task.downstream_edges.length\n    },\n    taskId() {\n      return this.$route.params.id\n    },\n    upstreamCount() {\n      if (!this.task) return null\n      return this.task.upstream_edges.length\n    },\n    tab: {\n      get() {\n        const keys = Object.keys(this.$route.query ?? {})\n        if (keys.length > 0 && this.tabs?.find(tab => tab.target == keys[0])) {\n          return keys[0]\n        }\n\n        return 'overview'\n      },\n      set(value) {\n        this.$router.replace({ query: { [value]: null } })\n      }\n    }\n  },\n  watch: {\n    '$route.name'(val) {\n      if (val == 'task') {\n        this.activateTask(this.$route.params.id)\n      }\n    },\n    task(val) {\n      if (val === 'not-found') this.$router.push({ name: 'not-found' })\n    }\n  },\n  async beforeMount() {\n    await this.activateTask(this.$route.params.id)\n  },\n  methods: {\n    ...mapActions('data', ['activateTask', 'resetActiveData'])\n  },\n  apollo: {\n    task: {\n      query: require('@/graphql/Task/task.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {\n          id: this.taskId\n        }\n      },\n      error(error) {\n        if (error.toString().includes('invalid input'))\n          this.$router.push({ name: 'not-found' })\n      },\n      update: data => data.task_by_pk || 'not-found'\n    },\n    lastTaskRun: {\n      query: require('@/graphql/Task/last-task-run.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {\n          id: this.taskId\n        }\n      },\n      update: data => data?.task_run?.[0]\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet v-if=\"task\" color=\"appBackground\">\n    <SubPageNav icon=\"pi-task\" page-type=\"Task\">\n      <span\n        slot=\"page-title\"\n        :style=\"\n          loading !== 0\n            ? {\n                display: 'block',\n                height: '28px',\n                overflow: 'hidden',\n                width: '400px'\n              }\n            : $vuetify.breakpoint.smAndDown && {\n                display: 'inline'\n              }\n        \"\n      >\n        <span v-if=\"loading === 0\">\n          {{ task.name }}\n        </span>\n        <span v-else style=\"width: 500px;\">\n          <v-skeleton-loader type=\"heading\" tile></v-skeleton-loader>\n        </span>\n      </span>\n\n      <span\n        slot=\"breadcrumbs\"\n        :style=\"\n          loading !== 0\n            ? {\n                display: 'block',\n                height: '21px',\n                overflow: 'hidden',\n                width: '500px'\n              }\n            : $vuetify.breakpoint.smAndDown && {\n                display: 'inline',\n                'font-size': '0.875rem'\n              }\n        \"\n      >\n        <BreadCrumbs\n          v-if=\"task && loading === 0\"\n          :crumbs=\"[\n            {\n              route: {\n                name: 'project',\n                params: { id: task.flow.project.id }\n              },\n              text: task.flow.project.name\n            },\n            {\n              route: {\n                name: 'flow',\n                params: { id: task.flow.id }\n              },\n              text: task.flow.name\n            }\n          ]\"\n        ></BreadCrumbs>\n        <v-skeleton-loader v-else type=\"text\" />\n      </span>\n      <span slot=\"tabs\" style=\"width: 100%;\"\n        ><NavTabBar :tabs=\"tabs\" page=\"flow\"\n      /></span>\n    </SubPageNav>\n\n    <v-tabs-items\n      v-model=\"tab\"\n      class=\"px-6 mx-auto tabs-border-bottom tab-full-height\"\n      :style=\"\n        $vuetify.breakpoint.mdAndUp ? 'padding-top: 130px' : 'padding-top: 80px'\n      \"\n    >\n      <v-tab-item\n        value=\"runs\"\n        transition=\"quick-fade\"\n        reverse-transition=\"quick-fade\"\n      >\n        <TileLayoutFull>\n          <TaskRunTableTile\n            slot=\"row-2-tile\"\n            :task-id=\"taskId\"\n            :loading=\"loading > 0\"\n          />\n        </TileLayoutFull>\n      </v-tab-item>\n\n      <v-tab-item\n        class=\"pa-0\"\n        value=\"overview\"\n        transition=\"quick-fade\"\n        reverse-transition=\"quick-fade\"\n      >\n        <TileLayout>\n          <DetailsTile\n            slot=\"row-2-col-1-row-1-tile-1\"\n            :task=\"task\"\n            :last-run=\"lastTaskRun\"\n            :loading=\"loading > 0\"\n          />\n\n          <TaskRunHeartbeatTile\n            slot=\"row-2-col-1-row-2-tile-1\"\n            :task-id=\"taskId\"\n          />\n\n          <DependenciesTile\n            slot=\"row-2-col-2-row-3-tile-1\"\n            :downstream-count=\"downstreamCount\"\n            :loading=\"loading > 0\"\n            :flow=\"task ? task.flow : null\"\n            :tasks=\"dependencies\"\n            :upstream-count=\"upstreamCount\"\n          />\n        </TileLayout>\n      </v-tab-item>\n    </v-tabs-items>\n\n    <v-bottom-navigation v-if=\"$vuetify.breakpoint.smAndDown\" app fixed>\n      <v-btn @click=\"tab = 'overview'\">\n        Overview\n        <v-icon>view_module</v-icon>\n      </v-btn>\n\n      <v-btn @click=\"tab = 'runs'\">\n        Runs\n        <v-icon>pi-task-run</v-icon>\n      </v-btn>\n    </v-bottom-navigation>\n  </v-sheet>\n</template>\n"
  },
  {
    "path": "src/pages/Task/TaskRunHeartbeat-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport HeartbeatTimeline from '@/components/HeartbeatTimeline'\nimport { roundedOneAgo } from '@/utils/dateTime'\nimport { heartbeatMixin } from '@/mixins/heartbeatMixin.js'\n\nexport default {\n  components: {\n    CardTitle,\n    HeartbeatTimeline\n  },\n  mixins: [heartbeatMixin],\n  // These should eventually be moved here as data props\n  // instead of as passed in props\n  props: {\n    taskId: {\n      type: String,\n      required: true\n    },\n    timestamp: {\n      type: String,\n      required: false,\n      default: () => roundedOneAgo('hour')\n    }\n  },\n  data() {\n    return { loading: 0 }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.heartbeat.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    heartbeat: {\n      query: require('@/graphql/Task/heartbeat.gql'),\n      update: d => d.task_run,\n      loadingKey: 'loading',\n      pollInterval: 10000,\n      variables() {\n        return {\n          taskId: this.taskId,\n          timestamp: roundedOneAgo('hour'),\n          state: this.checkedState\n        }\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2\" tile>\n    <CardTitle title=\"Activity in the last hour\" icon=\"show_chart\">\n      <v-select\n        data-public\n        slot=\"action\"\n        v-model=\"state\"\n        class=\"state-interval-picker font-weight-regular\"\n        :items=\"states\"\n        label=\"State\"\n        dense\n        solo\n        hide-details\n        flat\n        style=\"max-width: 150px;\"\n      >\n        <template #prepend-inner>\n          <v-icon color=\"utilGrayDark\" x-small>\n            label_important\n          </v-icon>\n        </template>\n      </v-select>\n    </CardTitle>\n\n    <v-container class=\"pa-0 pr-4\">\n      <HeartbeatTimeline :loading=\"loading\" :items=\"heartbeat\" type=\"task\" />\n    </v-container>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.state-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Task/TaskRunTable-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport { roundedOneAgo } from '@/utils/dateTime'\nimport DurationSpan from '@/components/DurationSpan'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { calculateDuration } from '@/utils/states'\n\nexport default {\n  components: {\n    CardTitle,\n    DurationSpan\n  },\n  mixins: [formatTime],\n  props: {\n    taskId: {\n      required: true,\n      type: String\n    }\n  },\n  data() {\n    return {\n      dateFilters: [\n        { name: '1 Hour', value: 'hour' },\n        { name: '24 Hours', value: 'day' },\n        { name: '7 Days', value: 'week' },\n        { name: '30 Days', value: 'month' }\n      ],\n      headers: [\n        {\n          text: 'Flow Run',\n          value: 'flow_run',\n          sortable: false,\n          width: '30%'\n        },\n        {\n          text: 'Start Time',\n          value: 'start_time',\n          align: 'start',\n          width: '15%'\n        },\n        { text: 'End Time', value: 'end_time', align: 'start', width: '15%' },\n        {\n          text: 'Duration',\n          value: 'duration',\n          align: 'end',\n          width: '10%',\n          sortable: false\n        },\n        { text: 'State', value: 'state', align: 'end', width: '10%' }\n      ],\n      itemsPerPage: 15,\n      page: 1,\n      selectedDateFilter: 'day',\n      sortBy: 'start_time',\n      sortDesc: true,\n      taskRunDurations: {},\n      loading: 0\n    }\n  },\n  computed: {\n    tableTitle() {\n      if (this.task) {\n        return `${this.task.name} Task Runs`\n      }\n      return 'Task Runs'\n    },\n    offset() {\n      return this.itemsPerPage * (this.page - 1)\n    },\n    searchFormatted() {\n      if (!this.searchTerm) return null\n      return `%${this.searchTerm}%`\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.task.skip = !entry.isIntersecting\n      this.$apollo.queries.taskRunsCount.skip = !entry.isIntersecting\n    },\n    calculateDuration\n  },\n  apollo: {\n    task: {\n      query: require('@/graphql/Task/table-task-runs.gql'),\n      variables() {\n        const orderBy = {}\n        orderBy[`${this.sortBy}`] = this.sortDesc ? 'desc' : 'asc'\n        return {\n          taskId: this.taskId,\n          heartbeat: roundedOneAgo(this.selectedDateFilter),\n          limit: this.itemsPerPage,\n          offset: this.offset,\n          orderBy\n        }\n      },\n      loadingKey: 'loading',\n      pollInterval: 5000,\n      update: data => {\n        return data.task_by_pk\n      }\n    },\n    taskRunsCount: {\n      query: require('@/graphql/Task/table-task-runs-count.gql'),\n      variables() {\n        return {\n          taskId: this.taskId,\n          heartbeat: roundedOneAgo(this.selectedDateFilter)\n        }\n      },\n      pollInterval: 5000,\n      update: data =>\n        data && data.task_run_aggregate\n          ? data.task_run_aggregate.aggregate.count\n          : null\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2 mt-2\" tile>\n    <v-tooltip top>\n      <template #activator=\"{ on }\">\n        <CardTitle :title=\"tableTitle\" icon=\"pi-task-run\">\n          <div slot=\"action\" v-on=\"on\">\n            <v-select\n              data-public\n              v-model=\"selectedDateFilter\"\n              class=\"time-interval-picker\"\n              :items=\"dateFilters\"\n              dense\n              solo\n              item-text=\"name\"\n              item-value=\"value\"\n              hide-details\n              flat\n            >\n              <template #prepend-inner>\n                <v-icon color=\"black\" x-small>\n                  history\n                </v-icon>\n              </template>\n            </v-select>\n          </div>\n        </CardTitle>\n      </template>\n      <span>\n        Filter by when runs were last updated\n      </span>\n    </v-tooltip>\n\n    <v-card-text>\n      <v-data-table\n        :footer-props=\"{\n          showFirstLastPage: true,\n          itemsPerPageOptions: [10, 15, 25, 50],\n          firstIcon: 'first_page',\n          lastIcon: 'last_page',\n          prevIcon: 'keyboard_arrow_left',\n          nextIcon: 'keyboard_arrow_right'\n        }\"\n        class=\"truncate-table\"\n        :headers=\"headers\"\n        :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n        :items=\"task ? task.task_runs : null || []\"\n        :items-per-page.sync=\"itemsPerPage\"\n        :loading=\"loading > 0\"\n        must-sort\n        :page.sync=\"page\"\n        :server-items-length=\"taskRunsCount\"\n        :sort-by.sync=\"sortBy\"\n        :sort-desc.sync=\"sortDesc\"\n        :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n        calculate-widths\n      >\n        <template #item.flow_run=\"{ item }\">\n          <v-tooltip top>\n            <template #activator=\"{ on }\">\n              <router-link\n                class=\"link\"\n                :to=\"{ name: 'task-run', params: { id: item.id } }\"\n              >\n                <span v-on=\"on\">{{ item.flow_run.name }}</span>\n              </router-link>\n            </template>\n            <span\n              >{{ item.flow_run.name }} - {{ task.name }}\n              <span v-if=\"item.map_index > -1\">\n                (Mapped Child {{ item.map_index }})</span\n              ></span\n            >\n          </v-tooltip>\n        </template>\n\n        <template #item.start_time=\"{ item }\">\n          <truncate :content=\"formatTime(item.start_time)\">\n            {{ formDate(item.start_time) }}\n          </truncate>\n        </template>\n\n        <template #item.end_time=\"{ item }\">\n          <truncate :content=\"formatTime(item.end_time)\">\n            {{ formDate(item.end_time) }}\n          </truncate>\n        </template>\n\n        <template #item.duration=\"{ item }\">\n          <DurationSpan\n            v-if=\"item.start_time\"\n            :start-time=\"item.start_time\"\n            :end-time=\"\n              calculateDuration(item.start_time, item.end_time, item.state)\n            \"\n          />\n          <span v-else>...</span>\n        </template>\n\n        <template #item.state=\"{ item }\">\n          <truncate :content=\"item.state\">\n            <v-icon class=\"mr-1 pointer\" small :color=\"item.state\">\n              brightness_1\n            </v-icon>\n          </truncate>\n        </template>\n      </v-data-table>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.time-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TaskRun/Actions.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n// import CancelButton from '@/components/CancelButton.vue'\nimport SetStateDialog from '@/components/SetStateDialog.vue'\nimport RestartDialog from '@/pages/TaskRun/Restart-Dialog'\nimport ResumeButton from '@/components/ResumeButton'\n\nexport default {\n  components: { RestartDialog, SetStateDialog, ResumeButton },\n  props: {\n    taskRun: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      restartDialog: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return !this.hasPermission('update', 'run')\n    }\n  },\n  methods: {}\n}\n</script>\n\n<template>\n  <div\n    class=\"pa-0 mb-2 d-flex align-center\"\n    :class=\"[\n      $vuetify.breakpoint.xsOnly ? 'justify-center' : 'justify-end',\n      $vuetify.breakpoint.xsOnly && 'mx-auto'\n    ]\"\n  >\n    <ResumeButton\n      v-if=\"taskRun.state == 'Paused'\"\n      dialog-type=\"resume\"\n      :task-run=\"taskRun\"\n      :include-text=\"true\"\n    />\n    <v-tooltip bottom>\n      <template #activator=\"{ on }\">\n        <div v-on=\"on\">\n          <v-btn\n            class=\"vertical-button mr-2\"\n            text\n            depressed\n            small\n            :disabled=\"permissionsCheck\"\n            color=\"primary\"\n            @click=\"restartDialog = true\"\n          >\n            <v-icon>fab fa-rev</v-icon>\n            <div>Restart</div>\n          </v-btn>\n        </div>\n      </template>\n      <span v-if=\"permissionsCheck\">\n        You don't have permission to restart flow runs\n      </span>\n      <span v-else>Restart flow run from this task</span>\n    </v-tooltip>\n\n    <v-dialog v-model=\"restartDialog\" width=\"500\">\n      <RestartDialog\n        :task-run=\"taskRun\"\n        :flow-run-id=\"taskRun.flow_run.id\"\n        @cancel=\"restartDialog = false\"\n      />\n    </v-dialog>\n\n    <SetStateDialog dialog-type=\"task run\" :task-run=\"taskRun\" />\n\n    <!-- Shouldn't we be able to cancel this? -->\n    <!-- <CancelButton dialog-type=\"flow run\" :flow-run=\"flowRun\" /> -->\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/TaskRun/Dependencies-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport { mapGetters } from 'vuex'\nimport SchematicFlow from '@/components/Schematics/Schematic-Flow'\n\nimport gql from 'graphql-tag'\n\nconst taskRunFields = `\n  id\n  task_run_id: id\n  map_index\n  name\n  state\n  task_id\n  serialized_state\n  state_message\n  state_timestamp\n  start_time\n  end_time\n  map_index\n\n  task {\n    id\n    mapped\n    name\n    max_retries\n    retry_delay\n    trigger\n    type\n\n    upstream_edges {\n      upstream_task {\n        id\n        name\n      }\n\n      downstream_task {\n        id\n        name\n      }\n    }\n\n    downstream_edges {\n      upstream_task {\n        id\n        name\n      }\n\n      downstream_task {\n        id\n        name\n      }\n    }\n  }\n`\n\nexport default {\n  filters: {\n    typeClass: val => val.split('.').pop()\n  },\n  components: {\n    CardTitle,\n    SchematicFlow\n  },\n  props: {\n    loading: {\n      type: Boolean,\n      required: false,\n      default: () => false\n    },\n    taskRun: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    return {\n      expanded: true,\n      showCards: true,\n      task: null,\n      tasks: []\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['timezone']),\n    subtitle() {\n      return `${this.taskRun?.task?.upstream_edges?.length} Upstream • ${this.taskRun?.task?.downstream_edges?.length} Downstream`\n    },\n    query() {\n      if (!this.taskRun) return\n      let queryString = ''\n\n      if (this.taskRun.task.upstream_edges.length) {\n        const upstream = this.taskRun.task.upstream_edges.reduce(\n          (string, edge, i) => {\n            string += `\n          upstream_task_run_${i}: task_run(where: { flow_run_id: { _eq: \"${this.taskRun?.flow_run?.id}\" }, task_id: { _eq: \"${edge?.upstream_task?.id}\" }, map_index: { _in: [ -1, ${this.taskRun?.map_index} ] } }) {\n            ${taskRunFields}\n          }\n        `\n            return string\n          },\n          ''\n        )\n        queryString += upstream\n      }\n\n      if (this.taskRun.task.downstream_edges.length) {\n        const downstream = this.taskRun.task.downstream_edges.reduce(\n          (string, edge, i) => {\n            string += `\n          downstream_task_run_${i}: task_run(where: { flow_run_id: { _eq: \"${this.taskRun?.flow_run?.id}\" }, task_id: { _eq: \"${edge?.downstream_task?.id}\" }, map_index: { _in: [ -1, ${this.taskRun?.map_index} ] } }) {\n            ${taskRunFields}\n          }\n        `\n            return string\n          },\n          ''\n        )\n        queryString += downstream\n      }\n\n      return queryString == ''\n        ? null\n        : gql`\n        query TaskRunDependencies {\n          ${queryString}\n        }\n      `\n    },\n    modifiedTaskRun() {\n      return {\n        ...this.taskRun,\n        flow_run_name: this.taskRun.flow_run.name,\n        task: {\n          ...this.taskRun.task,\n          task_run_id: this.taskRun.id,\n          name:\n            this.taskRun.name ??\n            this.taskRun.task.name +\n              (this.taskRun.map_index > -1\n                ? ` (${this.taskRun.map_index})`\n                : '')\n        }\n      }\n    }\n  },\n  watch: {},\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.taskRunDependencies.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    taskRunDependencies: {\n      query() {\n        return this.query\n      },\n      skip() {\n        return (\n          !this.taskRun?.task?.downstream_edges?.length &&\n          !this.taskRun?.task?.upstream_edges?.length\n        )\n      },\n      update(data) {\n        const dependencies = Object.keys(data).map(key => {\n          const task = data[key][0]\n\n          // We filter these because the references don't exist on this subset of tasks\n          task.task.upstream_edges = task.task.upstream_edges.filter(\n            edge => this.taskRun.task.id == edge.upstream_task.id\n          )\n\n          task.task.downstream_edges = task.task.downstream_edges.filter(\n            edge => this.taskRun.task.id == edge.downstream_task.id\n          )\n          return task\n        })\n\n        dependencies.forEach(d => {\n          d.flow_run_name = this.taskRun.flow_run.name\n\n          d.task.name =\n            d.name ?? d.task.name + (d.map_index > -1 ? `(${d.map_index})` : '')\n        })\n        this.tasks = [this.modifiedTaskRun, ...dependencies]\n\n        return data\n      },\n      pollInterval: 5000\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2\" tile>\n    <CardTitle title=\"Dependencies\" icon=\"share\" :subtitle=\"subtitle\">\n      <div slot=\"action\" class=\"d-flex align-end justify-center flex-column\">\n        <v-checkbox\n          v-model=\"showCards\"\n          dense\n          label=\"Show Cards\"\n          color=\"primary\"\n          class=\"my-0 mr-4\"\n          hide-details\n        ></v-checkbox>\n      </div>\n    </CardTitle>\n\n    <v-card-text class=\"full-height position-relative\">\n      <SchematicFlow\n        v-if=\"!loading\"\n        :tasks=\"tasks\"\n        show-legend\n        :show-cards=\"showCards\"\n      />\n      <v-skeleton-loader v-else type=\"image\" />\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.full-height {\n  min-height: 67vh;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TaskRun/Details-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport DurationSpan from '@/components/DurationSpan'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { calculateDuration } from '@/utils/states'\nexport default {\n  filters: {\n    typeClass: val => val.split('.').pop()\n  },\n  components: {\n    CardTitle,\n    DurationSpan\n  },\n  mixins: [formatTime],\n  props: {\n    taskRun: {\n      type: Object,\n      default: () => {}\n    }\n  },\n  data() {\n    return {\n      copiedText: {}\n    }\n  },\n  computed: {\n    expectedRuns() {\n      return (\n        this.taskRun?.serialized_state?.n_map_states?.toLocaleString() ||\n        'Unknown'\n      )\n    },\n    filteredParams() {\n      return {\n        [this.taskRun.task.name]: this.taskRun.flow_run.parameters[\n          this.taskRun.task.name\n        ]\n      }\n    }\n  },\n  methods: {\n    copyTextToClipboard(text) {\n      if (!text) return\n\n      this.copiedText = {}\n      this.copiedText[text] = true\n      navigator.clipboard.writeText(text)\n\n      setTimeout(() => {\n        this.copiedText = {}\n        this.copiedText[text] = false\n      }, 1000)\n    },\n    calculateDuration\n  }\n}\n</script>\n\n<template>\n  <v-card class=\"pa-2\" tile>\n    <v-system-bar :color=\"taskRun.state\" :height=\"5\" absolute>\n      <!-- We should include a state icon here when we've got those -->\n      <!-- <v-icon>{{ flowRun.state }}</v-icon> -->\n    </v-system-bar>\n\n    <CardTitle\n      :title=\"taskRun.task.name\"\n      icon=\"pi-task-run\"\n      :subtitle=\"taskRun.state\"\n      :params=\"{ name: 'task', params: { id: taskRun.task.id } }\"\n    />\n\n    <v-list-item\n      dense\n      two-line\n      :to=\"{ name: 'flow-run', params: { id: taskRun.flow_run.id } }\"\n      class=\"px-0\"\n    >\n      <v-list-item-avatar class=\"mr-2\">\n        <v-icon small>pi-flow-run</v-icon>\n      </v-list-item-avatar>\n      <v-list-item-content>\n        <span class=\"text-caption mb-0\">\n          Flow Run\n        </span>\n        <v-list-item-title class=\"text-body-2\">\n          <span>{{ taskRun.flow_run.name }}</span>\n        </v-list-item-title>\n        <v-list-item-title class=\"text-caption\">\n          <span :class=\"`${taskRun.flow_run.state}--text`\">\n            {{ taskRun.flow_run.state }}\n          </span>\n        </v-list-item-title>\n      </v-list-item-content>\n    </v-list-item>\n\n    <v-card-text class=\"pl-12 py-0\">\n      <v-list-item dense class=\"px-0\">\n        <v-list-item-content v-if=\"taskRun.state_message\">\n          <v-list-item-subtitle class=\"text-caption\">\n            Last State Message\n          </v-list-item-subtitle>\n          <div class=\"text-subtitle-2\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <span class=\"text-caption\" v-on=\"on\">\n                  [{{ formDate(taskRun.state_timestamp) }}]:\n                </span>\n              </template>\n              <div>\n                {{ formatTime(taskRun.state_timestamp) }}\n              </div>\n            </v-tooltip>\n            {{ taskRun.state_message }}\n          </div>\n        </v-list-item-content>\n      </v-list-item>\n\n      <v-list-item dense class=\"pa-0\">\n        <v-list-item-content>\n          <v-list-item-subtitle class=\"text-caption\">\n            <v-row v-if=\"taskRun.state == 'Mapped'\" no-gutters>\n              <v-col cols=\"6\">\n                Expected Mapped Runs\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                <v-tooltip top>\n                  <template #activator=\"{ on }\">\n                    <span v-on=\"on\">\n                      {{ expectedRuns }}\n                    </span>\n                  </template>\n                  <span v-if=\"!taskRun.serialized_state.n_map_states\">\n                    This data is only available on Flows registered with Prefect\n                    Core 0.13.5+\n                  </span>\n                  <span v-else>\n                    The number of mapped children expected to run. Note that the\n                    number of active mapped runs may be less than this if some\n                    have not begun running yet.\n                  </span>\n                </v-tooltip>\n              </v-col>\n            </v-row>\n\n            <v-row v-if=\"taskRun.start_time\" no-gutters>\n              <v-col cols=\"6\">\n                Started\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                <v-tooltip top>\n                  <template #activator=\"{ on }\">\n                    <span v-on=\"on\">\n                      {{\n                        formDate(\n                          taskRun.start_time || taskRun.scheduled_start_time\n                        )\n                      }}\n                    </span>\n                  </template>\n                  <div>\n                    {{\n                      formatTime(\n                        taskRun.start_time || taskRun.scheduled_start_time\n                      )\n                    }}\n                  </div>\n                </v-tooltip>\n              </v-col>\n            </v-row>\n            <v-row v-if=\"taskRun.end_time\" no-gutters>\n              <v-col cols=\"6\">\n                Ended\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                <v-tooltip top>\n                  <template #activator=\"{ on }\">\n                    <span v-on=\"on\">\n                      {{ formDate(taskRun.end_time) }}\n                    </span>\n                  </template>\n                  <div>\n                    {{ formatTime(taskRun.end_time) }}\n                  </div>\n                </v-tooltip>\n              </v-col>\n            </v-row>\n            <v-row v-if=\"taskRun.start_time\" no-gutters>\n              <v-col cols=\"6\">\n                Duration\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                <DurationSpan\n                  v-if=\"taskRun.start_time\"\n                  :start-time=\"taskRun.start_time\"\n                  :end-time=\"\n                    calculateDuration(\n                      taskRun.start_time,\n                      taskRun.end_time,\n                      taskRun.state\n                    )\n                  \"\n                />\n                <span v-else>\n                  <v-skeleton-loader type=\"text\"></v-skeleton-loader>\n                </span>\n              </v-col>\n            </v-row>\n            <v-row v-if=\"taskRun.updated\" no-gutters>\n              <v-col cols=\"6\">\n                Updated\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                <v-tooltip top>\n                  <template #activator=\"{ on }\">\n                    <span v-on=\"on\">\n                      {{ formDate(taskRun.updated) }}\n                    </span>\n                  </template>\n                  <div>\n                    {{ formatTime(taskRun.updated) }}\n                  </div>\n                </v-tooltip>\n              </v-col>\n            </v-row>\n\n            <v-row\n              v-if=\"\n                taskRun.serialized_state && taskRun.serialized_state._result\n              \"\n              no-gutters\n            >\n              <v-col cols=\"6\">\n                Result Type\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                {{ taskRun.serialized_state._result.type | typeClass }}\n              </v-col>\n            </v-row>\n\n            <v-row\n              v-if=\"\n                taskRun.serialized_state && taskRun.serialized_state._result\n              \"\n              no-gutters\n            >\n              <v-col cols=\"6\">\n                Result Location\n              </v-col>\n              <v-col cols=\"6\" class=\"text-right font-weight-bold\">\n                <v-tooltip top>\n                  <template #activator=\"{ on }\">\n                    <span\n                      class=\"cursor-pointer show-icon-hover-focus-only pa-2px\"\n                      role=\"button\"\n                      @click=\"\n                        copyTextToClipboard(\n                          taskRun.serialized_state._result.location\n                        )\n                      \"\n                      v-on=\"on\"\n                    >\n                      <v-icon\n                        v-if=\"taskRun.serialized_state._result.location\"\n                        x-small\n                        class=\"mb-2px mr-2\"\n                        tabindex=\"0\"\n                      >\n                        {{\n                          copiedText[taskRun.serialized_state._result.location]\n                            ? 'check'\n                            : 'file_copy'\n                        }}\n                      </v-icon>\n                      {{ taskRun.serialized_state._result.location || 'None' }}\n                    </span>\n                  </template>\n                  <div>\n                    {{ taskRun.serialized_state._result.location || 'None' }}\n                  </div>\n                </v-tooltip>\n              </v-col>\n            </v-row>\n          </v-list-item-subtitle>\n        </v-list-item-content>\n      </v-list-item>\n\n      <v-list-item\n        v-if=\"\n          taskRun.task &&\n            $options.filters.typeClass(taskRun.task.type) == 'Parameter'\n        \"\n        dense\n        two-line\n        class=\"px-0\"\n      >\n        <v-list-item-content>\n          <v-list-item-subtitle>\n            <div class=\"text-caption mb-0\">\n              Parameter:\n            </div>\n\n            <code class=\"mt-3 pa-3 no-before-after-content code-custom\"\n              >{{ filteredParams }}\n            </code>\n          </v-list-item-subtitle>\n        </v-list-item-content>\n      </v-list-item>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\na {\n  text-decoration: none !important;\n}\n\n.code-custom {\n  background-color: var(--v-appBackground-base);\n  box-shadow: none;\n  color: var(--v-codeBlue-base);\n  font-size: 0.9em;\n}\n\n.no-before-after-content {\n  &::before,\n  &::after {\n    content: '' !important;\n  }\n}\n\n.show-icon-hover-focus-only {\n  .v-icon {\n    visibility: hidden;\n  }\n\n  &:hover,\n  &:focus {\n    .v-icon {\n      visibility: visible;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/TaskRun/MappedTaskRuns-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport DurationSpan from '@/components/DurationSpan'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { calculateDuration } from '@/utils/states'\n\nexport default {\n  components: {\n    CardTitle,\n    DurationSpan\n  },\n  mixins: [formatTime],\n  props: {\n    taskRun: {\n      required: true,\n      type: Object\n    }\n  },\n  data() {\n    return {\n      dateFilters: [\n        { name: '1 Hour', value: 'hour' },\n        { name: '24 Hours', value: 'day' },\n        { name: '7 Days', value: 'week' },\n        { name: '30 Days', value: 'month' }\n      ],\n      headers: [\n        { text: 'State', value: 'state', align: 'start', width: '7.5%' },\n        {\n          text: 'Map Index',\n          value: 'map_index',\n          width: '10%'\n        },\n        {\n          text: 'Task Run Name',\n          value: 'name',\n          width: '20%'\n        },\n        {\n          text: 'Start Time',\n          value: 'start_time',\n          align: 'start',\n          width: '20%'\n        },\n        { text: 'End Time', value: 'end_time', align: 'start', width: '20%' },\n        {\n          text: 'Duration',\n          sortable: false,\n          value: 'duration',\n          align: 'end',\n          width: '15%'\n        }\n      ],\n      initialPageSet: false,\n      itemsPerPage: 25,\n      page: 1,\n      searchTerm: null,\n      selectedDateFilter: 'day',\n      serverItemsLength: null,\n      sortBy: 'map_index',\n      sortDesc: false,\n      taskRunDurations: {},\n      loading: 0,\n      selected: []\n    }\n  },\n  computed: {\n    tableTitle() {\n      return `${this.taskRun?.name ?? this.taskRun?.task?.name} Task Runs`\n    },\n    offset() {\n      return this.itemsPerPage * (this.page - 1)\n    },\n    searchFormatted() {\n      if (!this.searchTerm) return null\n      return `%${this.searchTerm}%`\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.taskRuns.skip = !entry.isIntersecting\n      this.$apollo.queries.taskRunsCount.skip = !entry.isIntersecting\n    },\n    calculateDuration\n  },\n  apollo: {\n    taskRuns: {\n      query: require('@/graphql/TaskRun/table-mapped-task-runs.gql'),\n      throttle: 500,\n      debounce: 250,\n      variables() {\n        const orderBy = {}\n        orderBy[`${this.sortBy}`] = this.sortDesc ? 'desc' : 'asc'\n\n        const where = {\n          task_id: { _eq: this.taskRun.task.id },\n          flow_run_id: { _eq: this.taskRun.flow_run.id }\n        }\n        const _or = []\n        const mapSearch = parseInt(this.searchTerm)\n\n        if (mapSearch) {\n          _or.push({ map_index: { _eq: mapSearch } })\n        }\n        if (this.searchTerm !== null) {\n          _or.push({\n            name: { _ilike: this.searchFormatted }\n          })\n        }\n\n        if (_or.length) {\n          where._or = _or\n        }\n\n        return {\n          where,\n          limit: this.itemsPerPage,\n          offset: this.offset,\n          orderBy\n        }\n      },\n      skip() {\n        return !this.initialPageSet\n      },\n      loadingKey: 'loading',\n      pollInterval: 5000,\n      update(data) {\n        const selected = data.task_run.find(t => t.id == this.taskRun.id)\n        this.selected = [selected]\n        return data.task_run\n      }\n    },\n    taskRunsCount: {\n      query: require('@/graphql/TaskRun/table-mapped-task-runs-count.gql'),\n      throttle: 500,\n      debounce: 250,\n      variables() {\n        const where = {\n          task_id: { _eq: this.taskRun.task.id },\n          flow_run_id: { _eq: this.taskRun.flow_run.id }\n        }\n        const _or = []\n        const mapSearch = parseInt(this.searchTerm)\n\n        if (mapSearch) {\n          _or.push({ map_index: { _eq: mapSearch } })\n        }\n        if (this.searchTerm !== null) {\n          _or.push({\n            name: { _ilike: this.searchFormatted }\n          })\n        }\n\n        if (_or.length) {\n          where._or = _or\n        }\n        return {\n          where\n        }\n      },\n      pollInterval: 5000,\n      update(data) {\n        this.serverItemsLength = data?.task_run_aggregate?.aggregate?.count\n\n        if (!this.initialPageSet) {\n          this.page = Math.ceil(\n            Math.abs(this.taskRun.map_index) / this.itemsPerPage\n          )\n\n          this.initialPageSet = true\n        }\n\n        return data?.task_run_aggregate?.aggregate?.count ?? null\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2 mt-2\" tile>\n    <CardTitle :title=\"tableTitle\" icon=\"pi-task-run\">\n      <v-text-field\n        slot=\"action\"\n        v-model=\"searchTerm\"\n        class=\"task-search\"\n        flat\n        solo\n        prepend-inner-icon=\"search\"\n        hide-details\n        placeholder=\"Search by run name or map index\"\n        style=\"min-width: 300px;\"\n      >\n      </v-text-field>\n    </CardTitle>\n\n    <v-card-text>\n      <v-data-table\n        v-model=\"selected\"\n        :footer-props=\"{\n          showFirstLastPage: true,\n          itemsPerPageOptions: [10, 15, 25, 50],\n          firstIcon: 'first_page',\n          lastIcon: 'last_page',\n          prevIcon: 'keyboard_arrow_left',\n          nextIcon: 'keyboard_arrow_right',\n          showCurrentPage: true\n        }\"\n        single-select\n        class=\"truncate-table\"\n        :headers=\"headers\"\n        :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n        :items=\"taskRuns\"\n        :items-per-page.sync=\"itemsPerPage\"\n        :loading=\"loading > 0\"\n        must-sort\n        item-key=\"id\"\n        :page.sync=\"page\"\n        :server-items-length=\"serverItemsLength\"\n        :sort-by.sync=\"sortBy\"\n        :sort-desc.sync=\"sortDesc\"\n        :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n        calculate-widths\n      >\n        <template #item.name=\"{ item }\">\n          <v-tooltip top>\n            <template #activator=\"{ on }\">\n              <router-link\n                class=\"link\"\n                :to=\"{ name: 'task-run', params: { id: item.id } }\"\n              >\n                <span v-on=\"on\">\n                  {{ item.name || taskRun.task.name }}\n                </span>\n              </router-link>\n            </template>\n            <span v-if=\"item.name\">\n              {{ item.name }}\n              <span v-if=\"item.map_index > -1\">\n                ({{ taskRun.task.name }} Child\n                {{ item.map_index.toLocaleString() }})\n              </span>\n            </span>\n            <span v-else-if=\"item.map_index > -1\">\n              {{ taskRun.task.name }} Child\n              {{ item.map_index.toLocaleString() }}\n            </span>\n            <span v-else> {{ taskRun.task.name }} Parent </span>\n          </v-tooltip>\n        </template>\n\n        <template #item.map_index=\"{ item }\">\n          <span>\n            {{\n              item.map_index === -1 ? 'Parent' : item.map_index.toLocaleString()\n            }}\n          </span>\n        </template>\n\n        <template #item.start_time=\"{ item }\">\n          <v-tooltip v-if=\"item.start_time\" top>\n            <template #activator=\"{ on }\">\n              <span v-on=\"on\"> {{ formDate(item.start_time) }}</span>\n            </template>\n            <span> {{ formatTime(item.start_time) }}</span>\n          </v-tooltip>\n          <span v-else>...</span>\n        </template>\n\n        <template #item.end_time=\"{ item }\">\n          <v-tooltip v-if=\"item.end_time\" top>\n            <template #activator=\"{ on }\">\n              <span v-on=\"on\">{{ formDate(item.end_time) }}</span>\n            </template>\n            <span>{{ formatTime(item.end_time) }}</span>\n          </v-tooltip>\n          <span v-else>...</span>\n        </template>\n\n        <template #item.duration=\"{ item }\">\n          <DurationSpan\n            v-if=\"item.start_time\"\n            :start-time=\"item.start_time\"\n            :end-time=\"\n              calculateDuration(item.start_time, item.end_time, item.state)\n            \"\n          />\n          <span v-else>...</span>\n        </template>\n        <template #item.state=\"{ item }\">\n          <v-tooltip top>\n            <template #activator=\"{ on }\">\n              <v-icon class=\"mr-1 pointer\" small :color=\"item.state\" v-on=\"on\">\n                brightness_1\n              </v-icon>\n            </template>\n            <span>{{ item.state }}</span>\n          </v-tooltip>\n        </template>\n      </v-data-table>\n    </v-card-text>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.task-search {\n  border-radius: 0 !important;\n  font-size: 0.85rem;\n\n  .v-icon {\n    font-size: 20px !important;\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/TaskRun/Restart-Dialog.vue",
    "content": "<script>\nimport { ERROR_MESSAGE } from '@/utils/error'\nimport { mapGetters, mapActions } from 'vuex'\n\nexport default {\n  props: {\n    taskRun: {\n      required: true,\n      type: Object\n    },\n    flowRunId: {\n      required: true,\n      type: String\n    }\n  },\n  data() {\n    return {\n      error: ERROR_MESSAGE,\n      tasksSuccess: true,\n      name: 'PrefectCloudUIRestartButton'\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['user']),\n    ...mapGetters('tenant', ['role']),\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return !this.hasPermission('update', 'run')\n    },\n    message() {\n      return `Flow run restarted by ${this.user.username}`\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    cancel() {\n      this.$emit('cancel')\n    },\n    runOrReRunMessage(oldState) {\n      const state = oldState ? oldState : this.taskRun.state\n      return state !== 'Pending'\n        ? `re-run task ${this.taskRun.task.name} and its downstream dependents`\n        : `run task ${this.taskRun.task.name} and any other pending task runs`\n    },\n    raiseWarning() {\n      const hasCachedInput = Object.keys(\n        this.taskRun?.serialized_state?.cached_inputs\n      )?.length\n      const hasUpstreamEdges = this.taskRun?.task?.upstream_edges?.filter(\n        edge => edge.key\n      )?.length\n      return !!hasUpstreamEdges && !hasCachedInput\n    },\n    async restart() {\n      const oldState = this.taskRun.state\n      this.cancel()\n      try {\n        this.dialog = false\n        await this.writeLogs()\n        let taskStates = []\n        if (this.utilityDownstreamTasks?.length) {\n          taskStates = this.utilityDownstreamTasks.map(task => {\n            return {\n              version: task.task.task_runs[0].version,\n              task_run_id: task.task.task_runs[0].id,\n              state: { type: 'Pending', message: this.message }\n            }\n          })\n        } else {\n          taskStates.push({\n            task_run_id: this.taskRun.id,\n            version: this.taskRun.version,\n            state: { type: 'Pending', message: this.message }\n          })\n        }\n\n        const result = await this.$apollo.mutate({\n          mutation: require('@/graphql/TaskRun/set-task-run-states.gql'),\n          variables: {\n            input: taskStates\n          }\n        })\n\n        if (result?.data?.set_task_run_states) {\n          const { data } = await this.$apollo.mutate({\n            mutation: require('@/graphql/TaskRun/set-flow-run-states.gql'),\n            variables: {\n              flowRunId: this.flowRunId,\n              version: this.taskRun.flow_run.version,\n              state: { type: 'Scheduled', message: this.message }\n            }\n          })\n\n          if (!data?.set_flow_run_states) this.tasksSuccess = false\n        }\n      } catch (error) {\n        this.tasksSuccess = false\n        throw error\n      } finally {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: this.tasksSuccess\n            ? `Flow run ${\n                this.taskRun.flow_run.name\n              } restarted. This will ${this.runOrReRunMessage(oldState)}`\n            : 'Sorry, we hit a problem trying to restart the run; please try again.',\n          alertType: this.tasksSuccess ? 'success' : 'error'\n        })\n      }\n    },\n    async writeLogs() {\n      const { data } = await this.$apollo.mutate({\n        mutation: require('@/graphql/Update/write-run-logs.gql'),\n        variables: {\n          flowRunId: this.flowRunId,\n          name: this.name,\n          message: this.message\n        }\n      })\n      return data?.write_run_logs?.success\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.utilityDownstreamTasks.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    utilityDownstreamTasks: {\n      query: require('@/graphql/TaskRun/utility_downstream_tasks.gql'),\n      variables() {\n        return {\n          taskIds: `{${this.taskRun.task.id}}`,\n          flowRunId: this.flowRunId\n        }\n      },\n      pollInterval: 5000,\n      update: data => data.utility_downstream_tasks\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" tile>\n    <v-card-title>\n      Restart from failed?\n    </v-card-title>\n\n    <v-card-text v-if=\"raiseWarning()\">\n      <div class=\"font-weight-bold black--text\">\n        Warning: This flow has upstream dependencies which have not been cached.\n        If you restart the flow-run from here, it is unlikely to succeed.\n      </div>\n      <div class=\"pb-5\">\n        For extra information, check out\n        <router-link\n          to=\"docs\"\n          target=\"_blank\"\n          href=\"https://docs.prefect.io/core/concepts/persistence.html#input-caching\"\n          >Persistence and Caching</router-link\n        >\n        in our docs.\n      </div>\n      <div>\n        To restart the flow run {{ taskRun.flow_run.name }} from this task run\n        anyway, click on confirm.\n      </div>\n    </v-card-text>\n    <v-card-text v-else>\n      Click on confirm to restart the flow run\n      {{ taskRun.flow_run.name }} from this task run. This will restart your\n      flow run and {{ runOrReRunMessage() }}.\n    </v-card-text>\n\n    <v-card-actions>\n      <v-spacer></v-spacer>\n\n      <v-btn :disabled=\"permissionsCheck\" color=\"primary\" @click=\"restart\">\n        Confirm\n      </v-btn>\n\n      <v-btn text @click=\"cancel\">\n        Cancel\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n"
  },
  {
    "path": "src/pages/TaskRun/TaskRun.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\n\nimport Actions from '@/pages/TaskRun/Actions'\nimport Artifacts from '@/components/Artifacts/Artifacts'\nimport BreadCrumbs from '@/components/BreadCrumbs'\nimport NavTabBar from '@/components/NavTabBar'\nimport DetailsTile from '@/pages/TaskRun/Details-Tile'\nimport EditableTextField from '@/components/EditableTextField'\nimport LogsCard from '@/components/LogsCard/LogsCard'\nimport DependenciesTile from '@/pages/TaskRun/Dependencies-Tile'\nimport MappedTaskRunsTile from '@/pages/TaskRun/MappedTaskRuns-Tile'\nimport SubPageNav from '@/layouts/SubPageNav'\nimport TaskRunHeartbeatTile from '@/pages/TaskRun/TaskRunHeartbeat-Tile'\nimport TileLayout from '@/layouts/TileLayout'\nimport TileLayoutFull from '@/layouts/TileLayout-Full'\nimport { parser } from '@/utils/markdownParser'\n\nexport default {\n  metaInfo() {\n    return {\n      title: this.taskRun\n        ? `Task Run | ${this.taskRun?.name ?? this.taskRun?.task?.name}`\n        : null,\n      link: [\n        {\n          rel: 'icon',\n          type: 'image/svg',\n          href: this.taskRun\n            ? `/state-icons/${this.taskRun.state.toLowerCase()}.svg`\n            : null,\n          vmid: 'favicon'\n        }\n      ]\n    }\n  },\n  components: {\n    Actions,\n    Artifacts,\n    BreadCrumbs,\n    DependenciesTile,\n    DetailsTile,\n    EditableTextField,\n    LogsCard,\n    MappedTaskRunsTile,\n    NavTabBar,\n    SubPageNav,\n    TaskRunHeartbeatTile,\n    TileLayout,\n    TileLayoutFull\n  },\n  data() {\n    return {\n      loading: 0,\n      taskRunNameLoading: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    taskRunNameLength() {\n      return this.taskRun?.name?.length\n    },\n    taskRunId() {\n      return this.$route.params.id\n    },\n    // Is this the correct definition? Can a mapped task run have siblings and children?\n    mappedParent() {\n      return this.taskRun?.map_index === -1\n    },\n    mappedChild() {\n      return this.taskRun?.map_index > -1\n    },\n    tabs() {\n      return [\n        {\n          name: 'Overview',\n          target: 'overview',\n          icon: 'view_module'\n        },\n        {\n          name: 'Logs',\n          target: 'logs',\n          icon: 'format_align_left'\n        },\n        {\n          name: 'Mapped Runs',\n          target: 'mapped-runs',\n          icon: 'device_hub',\n          hidden: !this.mappedParent && !this.mappedChild\n        },\n        {\n          name: 'Artifacts',\n          target: 'artifacts',\n          icon: 'fas fa-fingerprint'\n        }\n      ]\n    },\n    titleBarMaxWidth() {\n      if (this.$vuetify.breakpoint.lgAndUp) {\n        return '70vw'\n      } else if (this.$vuetify.breakpoint.mdAndDown) {\n        return '40vw'\n      }\n      return '30vw'\n    },\n    tab: {\n      get() {\n        const keys = Object.keys(this.$route.query ?? {})\n        if (keys.length > 0 && this.tabs?.find(tab => tab.target == keys[0])) {\n          return keys[0]\n        }\n\n        return 'overview'\n      },\n      set(value) {\n        this.$router.replace({ query: { [value]: null } })\n      }\n    }\n  },\n  watch: {\n    taskRun(val, prevVal) {\n      if (val === 'not-found') this.$router.push({ name: 'not-found' })\n      if (!val || val?.id == prevVal?.id) return\n      if (!this.$route.query || !this.$route.query.schematic) {\n        this.$router\n          .replace({\n            query: {\n              ...this.$route.query,\n              schematic: this.taskRun.task.id\n            }\n          })\n          .catch(e => e)\n      }\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    parseMarkdown(md) {\n      return parser(md)\n    },\n    async saveTaskRunName(e) {\n      const previousName = this.taskRun.name\n      if (previousName === e) return\n\n      try {\n        this.taskRunNameLoading = true\n\n        const { data } = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/set-task-run-name.gql'),\n          variables: {\n            input: {\n              task_run_id: this.taskRunId,\n              name: e\n            }\n          }\n        })\n\n        await this.$apollo.queries.taskRun.refetch()\n\n        if (!data.set_task_run_name.success) {\n          throw new Error(data.set_task_run_name.error)\n        }\n\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `<span class=\"font-weight-medium\">${previousName ||\n            'Your task run'}</span> has been renamed to <span class=\"font-weight-medium\">${e}</span>`,\n          alertType: 'success'\n        })\n      } catch {\n        this.setAlert({\n          alertShow: true,\n          alertMessage:\n            'Oops! Something went wrong while trying to update your task run name, please try again.',\n          alertType: 'error'\n        })\n      } finally {\n        this.taskRunNameLoading = false\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.taskRun.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    taskRun: {\n      query: require('@/graphql/TaskRun/task-run.gql'),\n      variables() {\n        return {\n          id: this.taskRunId\n        }\n      },\n      error(error) {\n        if (error.toString().includes('invalid input'))\n          this.$router.push({ name: 'not-found' })\n      },\n      loadingKey: 'loading',\n      pollInterval: 5000,\n      update: data => data.task_run_by_pk || 'not-found'\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet\n    v-if=\"taskRun\"\n    v-intersect=\"{ handler: onIntersect }\"\n    color=\"appBackground\"\n  >\n    <SubPageNav icon=\"pi-task-run\" page-type=\"Task Run\">\n      <span\n        slot=\"page-title\"\n        class=\"minTitleWidth\"\n        :style=\"{\n          display: $vuetify.breakpoint.smAndDown ? 'inline' : 'block',\n          width: taskRunNameLength + 'ch',\n          maxWidth: titleBarMaxWidth\n        }\"\n      >\n        <EditableTextField\n          :content=\"\n            taskRun.name ||\n              `${taskRun.task.name} ${\n                taskRun.map_index > -1\n                  ? `(Mapped Child ${taskRun.map_index})`\n                  : ''\n              }`\n          \"\n          label=\"Task run name\"\n          :loading=\"taskRunNameLoading\"\n          required\n          @change=\"saveTaskRunName\"\n        />\n      </span>\n      <BreadCrumbs\n        slot=\"breadcrumbs\"\n        :crumbs=\"[\n          {\n            route: {\n              name: 'project',\n              params: { id: taskRun.flow_run.flow.project.id }\n            },\n            text: taskRun.flow_run.flow.project.name\n          },\n          {\n            route: {\n              name: 'flow',\n              params: { id: taskRun.flow_run.flow.flow_group_id }\n            },\n            text: taskRun.flow_run.flow.name\n          },\n          {\n            route: {\n              name: 'flow-run',\n              params: { id: taskRun.flow_run.id }\n            },\n            text: taskRun.flow_run.name\n          }\n        ]\"\n        :style=\"\n          $vuetify.breakpoint.smAndDown && {\n            display: 'inline',\n            'font-size': '0.875rem'\n          }\n        \"\n      ></BreadCrumbs>\n\n      <Actions slot=\"page-actions\" style=\"height: 55px;\" :task-run=\"taskRun\" />\n      <span slot=\"tabs\" style=\"width: 100%;\">\n        <NavTabBar :tabs=\"tabs\" page=\"task-run\" />\n      </span>\n    </SubPageNav>\n\n    <v-tabs-items\n      v-model=\"tab\"\n      class=\"px-6 mx-auto tabs-border-bottom tab-full-height\"\n      :style=\"{\n        'padding-top': $vuetify.breakpoint.smOnly ? '80px' : '130px'\n      }\"\n    >\n      <v-tab-item\n        class=\"pa-0\"\n        value=\"overview\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayout>\n          <DetailsTile slot=\"row-2-col-1-row-1-tile-1\" :task-run=\"taskRun\" />\n\n          <TaskRunHeartbeatTile\n            slot=\"row-2-col-1-row-2-tile-1\"\n            :task-run-id=\"$route.params.id\"\n          />\n\n          <DependenciesTile\n            slot=\"row-2-col-2-row-3-tile-1\"\n            :task-run=\"taskRun\"\n            :loading=\"taskRun && loading > 0\"\n          />\n        </TileLayout>\n      </v-tab-item>\n\n      <v-tab-item\n        class=\"tab-full-height\"\n        value=\"logs\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <LogsCard\n            slot=\"row-2-tile\"\n            class=\"py-2 mt-4\"\n            entity=\"task\"\n            :query=\"require('@/graphql/Logs/task-run-logs.gql')\"\n            :query-for-scoping=\"\n              require('@/graphql/Logs/task-run-logs-scoping.gql')\n            \"\n            query-key=\"task_run_by_pk\"\n            :variables=\"{ id: $route.params.id }\"\n          />\n        </TileLayoutFull>\n      </v-tab-item>\n\n      <v-tab-item\n        class=\"pb-12\"\n        value=\"artifacts\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <Artifacts :task-run-ids=\"[taskRunId]\" />\n      </v-tab-item>\n\n      <v-tab-item\n        value=\"mapped-runs\"\n        transition=\"tab-fade\"\n        reverse-transition=\"tab-fade\"\n      >\n        <TileLayoutFull>\n          <v-skeleton-loader\n            slot=\"row-2-tile\"\n            :loading=\"loading > 0\"\n            type=\"image\"\n            height=\"800\"\n            transition=\"quick-fade\"\n            class=\"my-2\"\n            tile\n          >\n            <MappedTaskRunsTile :task-run=\"taskRun\" />\n          </v-skeleton-loader>\n        </TileLayoutFull>\n      </v-tab-item>\n    </v-tabs-items>\n\n    <v-bottom-navigation v-if=\"$vuetify.breakpoint.smAndDown\" app fixed>\n      <v-btn @click=\"tab = 'overview'\">\n        Overview\n        <v-icon>view_module</v-icon>\n      </v-btn>\n\n      <v-btn @click=\"tab = 'logs'\">\n        Logs\n        <v-icon>format_align_left</v-icon>\n      </v-btn>\n\n      <v-btn @click=\"tab = 'artifacts'\">\n        Artifacts\n        <v-icon>fas fa-fingerprint</v-icon>\n      </v-btn>\n\n      <v-btn @click=\"tab = 'mapped-runs'\">\n        Mapped Runs\n        <v-icon>device_hub</v-icon>\n      </v-btn>\n    </v-bottom-navigation>\n  </v-sheet>\n</template>\n\n<style lang=\"scss\">\n/* stylelint-disable */\n.v-tab--disabled .v-badge__badge {\n  pointer-events: none;\n}\n\n.v-badge--inline .v-badge__badge,\n.v-badge--inline .v-badge__wrapper {\n  margin: 5px;\n}\n\n.minTitleWidth {\n  min-width: 20vw;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TaskRun/TaskRunHeartbeat-Tile.vue",
    "content": "<script>\nimport CardTitle from '@/components/Card-Title'\nimport HeartbeatTimeline from '@/components/HeartbeatTimeline'\nimport { heartbeatMixin } from '@/mixins/heartbeatMixin.js'\n\nexport default {\n  components: {\n    CardTitle,\n    HeartbeatTimeline\n  },\n  mixins: [heartbeatMixin],\n  // These should eventually be moved here as data props\n  // instead of as passed in props\n  props: {\n    taskRunId: {\n      type: String,\n      required: true\n    },\n    timestamp: {\n      type: String,\n      required: false,\n      default: () => null\n    }\n  },\n  data() {\n    return {\n      loading: 0,\n      limit: 10\n    }\n  },\n  computed: {\n    heartbeat() {\n      if (this.taskRun) {\n        return this.taskRun[0].states\n      }\n      return []\n    },\n    count() {\n      return this.taskRun\n        ? this.taskRun[0].states_aggregate.aggregate.count\n        : null\n    }\n  },\n  methods: {\n    onIntersect([entry]) {\n      this.$apollo.queries.taskRun.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    taskRun: {\n      query: require('@/graphql/TaskRun/heartbeat.gql'),\n      update: d => d.task_run,\n      loadingKey: 'loading',\n      pollInterval: 5000,\n      variables() {\n        return {\n          taskRunId: this.taskRunId,\n          timestamp: this.timestamp,\n          state: this.checkedState,\n          limit: this.limit\n        }\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card v-intersect=\"{ handler: onIntersect }\" class=\"pa-2\" tile>\n    <CardTitle title=\"Activity\" icon=\"show_chart\">\n      <v-select\n        data-public\n        slot=\"action\"\n        v-model=\"state\"\n        class=\"state-interval-picker font-weight-regular\"\n        :items=\"states\"\n        label=\"State\"\n        dense\n        solo\n        hide-details\n        flat\n      >\n        <template #prepend-inner>\n          <v-icon color=\"utilGrayDark\" x-small>\n            label_important\n          </v-icon>\n        </template>\n      </v-select>\n    </CardTitle>\n\n    <v-container class=\"pa-0 pr-4\">\n      <HeartbeatTimeline\n        :loading=\"loading\"\n        :items=\"heartbeat\"\n        type=\"task_run_state\"\n      />\n    </v-container>\n\n    <v-divider></v-divider>\n\n    <v-card-actions class=\"justify-center\">\n      <v-btn\n        v-if=\"count > limit\"\n        class=\"blue--text\"\n        text\n        outlined\n        @click=\"limit += 5\"\n      >\n        Show More\n      </v-btn>\n    </v-card-actions>\n  </v-card>\n</template>\n\n<style lang=\"scss\" scoped>\n.state-interval-picker {\n  font-size: 0.85rem;\n  margin: auto;\n  margin-right: 0;\n  max-width: 150px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/Actions.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport Alert from '@/components/Alert'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ExternalLink from '@/components/ExternalLink'\nimport ManagementLayout from '@/layouts/ManagementLayout'\nimport DictInput from '@/components/CustomInputs/DictInput2'\nimport { formatJson } from '@/utils/json'\n\nexport default {\n  components: {\n    Alert,\n    ConfirmDialog,\n    ExternalLink,\n    ManagementLayout,\n    DictInput\n  },\n  mixins: [formatTime],\n  data() {\n    return {\n      // Alert data\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n\n      // Loading states\n      isLoadingTable: true,\n      isRemovingAction: false,\n      isTestingAction: false,\n\n      // Dialogs\n      dialogRemoveAction: false,\n\n      // Store copied action ID\n      // Useful to render feedback that copy was successful\n      copiedActionId: null,\n\n      // Timeout for copy action\n      copyTimeout: null,\n\n      // Table headers\n      headers: [\n        {\n          mobile: true,\n          text: 'Name',\n          value: 'name',\n          width: '25%'\n        },\n        {\n          mobile: true,\n          text: 'Type',\n          value: 'action_type',\n          align: 'left',\n          width: '25%'\n        },\n        {\n          mobile: true,\n          text: 'Action ID',\n          value: 'id',\n          align: 'center',\n          width: '25%'\n        },\n        {\n          mobile: true,\n          text: '',\n          value: 'actions',\n          align: 'end',\n          sortable: false,\n          width: '15%'\n        }\n      ],\n\n      // Forms\n      createFormValid: true,\n      modifyFormValid: true,\n\n      // Input icons\n      showNameInputIcon: false,\n\n      // Action selected for modification or deletion\n      selectedAction: null,\n\n      // default sorting\n      sortBy: 'name',\n      sortDesc: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['user', 'timezone']),\n    ...mapGetters('license', ['hasPermission']),\n    // Surface table headers based on viewport (mobile vs. desktop)\n    headersByViewport() {\n      return this.$vuetify.breakpoint.mdAndUp\n        ? this.headers\n        : this.headers.filter(header => header.mobile)\n    }\n  },\n  watch: {\n    tenant() {\n      this.$apollo.queries.actions.refetch()\n    }\n  },\n  methods: {\n    permissionsCheck(action) {\n      return this.hasPermission(action, 'hook')\n    },\n    closeActionDialog() {\n      this.selectedAction = null\n    },\n    copyTextToClipboard(id) {\n      clearTimeout(this.copyTimeout)\n\n      this.copiedActionId = id\n      navigator.clipboard.writeText(id)\n\n      this.copyTimeout = setTimeout(() => {\n        this.copiedActionId = null\n      }, 3000)\n    },\n    handleAlert(type, message) {\n      this.alertType = type\n      this.alertMessage = message\n      this.alertShow = true\n    },\n    formatItemValue(item) {\n      return formatJson(item?.action_config)\n    },\n    async removeAction() {\n      this.isRemovingAction = true\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/TeamSettings/delete-action.gql'),\n          variables: {\n            actionId: this.selectedAction.id\n          }\n        })\n\n        this.$apollo.queries.actions.refetch()\n        this.handleAlert('success', 'The action has been successfuly deleted.')\n      } catch (e) {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to delete this action. Please try again.'\n        )\n      }\n\n      this.dialogRemoveAction = false\n      this.isRemovingAction = false\n    },\n    async testAction() {\n      this.isTestingAction = this.selectedAction.id\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/TeamSettings/test-action.gql'),\n          variables: {\n            actionId: this.selectedAction.id\n          }\n        })\n\n        this.$apollo.queries.actions.refetch()\n        this.handleAlert('success', 'Test sent')\n        this.isTestingAction = null\n      } catch (e) {\n        if (`${e}`.includes('202')) this.handleAlert('success', 'Test accepted')\n        else this.handleAlert('error', `${e}`)\n        this.isTestingAction = null\n      }\n    },\n    selectAction(action) {\n      this.selectedAction = action\n    }\n  },\n  apollo: {\n    actions: {\n      query: require('@/graphql/TeamSettings/actions.gql'),\n      result({ data }) {\n        this.isLoadingTable = false\n        if (!data) return\n        return data.action\n      },\n      error() {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to fetch your actions. Please try again later.'\n        )\n      },\n      fetchPolicy: 'no-cache'\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout :show=\"!isLoadingTable\" control-show>\n    <template #title>Automation Actions</template>\n\n    <template #subtitle>\n      <span v-if=\"permissionsCheck('delete')\">\n        View and manage your team's\n        <ExternalLink\n          href=\"https://docs.prefect.io/orchestration/concepts/automations.html#automations\"\n          >automation actions</ExternalLink\n        >\n      </span>\n      <span v-else\n        >View the\n        <ExternalLink\n          href=\"https://docs.prefect.io/orchestration/concepts/automations.html#automations\"\n          >Automation Actions</ExternalLink\n        >\n        of {{ tenant.name }}</span\n      >\n    </template>\n\n    <v-card tile>\n      <v-card-text class=\"pa-0\">\n        <!-- ACTIONS TABLE -->\n        <v-data-table\n          fixed-header\n          :headers=\"headersByViewport\"\n          :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n          :items=\"actions\"\n          :items-per-page=\"10\"\n          :sort-by.sync=\"sortBy\"\n          show-expand\n          :sort-desc.sync=\"sortDesc\"\n          class=\"elevation-2 rounded-0 truncate-table\"\n          :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n          :footer-props=\"{\n            showFirstLastPage: true,\n            itemsPerPageOptions: [10, 15, 20, -1],\n            firstIcon: 'first_page',\n            lastIcon: 'last_page',\n            prevIcon: 'keyboard_arrow_left',\n            nextIcon: 'keyboard_arrow_right'\n          }\"\n          no-data-text=\"This team does not have any actions yet.\"\n        >\n          <!-- ACTION ID-->\n          <template #item.id=\"{ item }\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <div\n                  class=\"cursor-pointer text-truncate\"\n                  v-on=\"on\"\n                  @click=\"copyTextToClipboard(item.id)\"\n                >\n                  {{ item.id }}\n                </div>\n              </template>\n              <span>{{\n                copiedActionId === item.id ? 'Copied!' : 'Click to copy ID'\n              }}</span>\n            </v-tooltip>\n          </template>\n\n          <!-- ACTION NAME -->\n          <template #item.name=\"{ item }\">\n            <div class=\"hidewidth\">\n              {{ item.name }}\n            </div>\n          </template>\n\n          <template #item.type=\"{ item }\">\n            {{ item.action_type }}\n          </template>\n\n          <!-- ACTION CONFIG -->\n          <template #expanded-item=\"{ headers, item }\">\n            <td\n              v-if=\"Object.keys(item.action_config).length\"\n              :colspan=\"headers.length\"\n            >\n              <dict-input\n                v-if=\"Object.keys(item.action_config).length\"\n                class=\"mt-3\"\n                readonly-key\n                readonly-value\n                disable-add\n                disable-remove\n                :value=\"formatItemValue(item)\"\n              />\n            </td>\n            <td v-else :colspan=\"headers.length\">\n              No action config\n            </td>\n          </template>\n\n          <template #item.actions=\"{ item }\">\n            <v-btn\n              v-if=\"permissionsCheck('update')\"\n              text\n              fab\n              color=\"primary\"\n              :loading=\"isTestingAction === item.id\"\n              x-small\n              title=\"Test Action\"\n              @click=\"\n                selectAction(item)\n                testAction(item)\n              \"\n            >\n              <v-icon>bug_report</v-icon>\n            </v-btn>\n\n            <v-btn\n              v-if=\"permissionsCheck('delete')\"\n              text\n              fab\n              x-small\n              color=\"error\"\n              title=\"Delete Action\"\n              @click=\"\n                selectAction(item)\n                dialogRemoveAction = true\n              \"\n            >\n              <v-icon>delete</v-icon>\n            </v-btn>\n          </template>\n        </v-data-table>\n      </v-card-text>\n    </v-card>\n\n    <ConfirmDialog\n      v-if=\"selectedAction\"\n      v-model=\"dialogRemoveAction\"\n      type=\"error\"\n      :dialog-props=\"{ 'max-width': '600' }\"\n      :disabled=\"isRemovingAction\"\n      :loading=\"isRemovingAction\"\n      :title=\"\n        `Are you sure you want to delete ${\n          selectedAction.name ? selectedAction.name : 'this action'\n        }?`\n      \"\n      @cancel=\"closeActionDialog\"\n      @confirm=\"removeAction\"\n    >\n    </ConfirmDialog>\n\n    <Alert\n      v-model=\"alertShow\"\n      :type=\"alertType\"\n      :message=\"alertMessage\"\n      :offset-x=\"$vuetify.breakpoint.mdAndUp ? 256 : 56\"\n    ></Alert>\n  </ManagementLayout>\n</template>\n\n<style lang=\"scss\" scoped>\n.flex {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.hidewidth {\n  max-width: 100%;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/CloudHooks.vue",
    "content": "<script>\nimport { mapGetters, mapActions } from 'vuex'\nimport ExternalLink from '@/components/ExternalLink'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ManagementLayout from '@/layouts/ManagementLayout'\nimport { cloudHookMixin } from '@/mixins/cloudHookMixin'\nimport CloudHookForm from '@/components/CloudHookForm'\nimport CardTitle from '@/components/Card-Title'\nimport LogRocket from 'logrocket'\n\nexport default {\n  components: {\n    ExternalLink,\n    ManagementLayout,\n    CloudHookForm,\n    CardTitle,\n    ConfirmDialog\n  },\n  mixins: [cloudHookMixin],\n  data() {\n    return {\n      setTest: '',\n      //dialogs\n      selectHook: {},\n      dialogDeleteHook: false,\n      dialogEditHook: false,\n      removingHook: false,\n      // Search\n      search: null,\n      //headers\n      allHeaders: [\n        {\n          mobile: true,\n          text: 'Name',\n          value: 'name',\n          align: 'center',\n          width: '15%'\n        },\n        {\n          mobile: true,\n          text: 'Type',\n          value: 'type',\n          align: 'center',\n          width: '10%'\n        },\n        {\n          mobile: true,\n          text: 'Flow',\n          value: 'version_group_id',\n          align: 'center',\n          width: '15%'\n        },\n        {\n          mobile: true,\n          text: 'Active',\n          value: 'active',\n          width: '20%',\n          align: 'center'\n        },\n        {\n          mobile: true,\n          text: 'States',\n          value: 'states',\n          width: '20%',\n          align: 'center',\n          sortable: false\n        },\n        {\n          mobile: true,\n          text: '',\n          value: 'action',\n          align: 'end',\n          sortable: false,\n          width: '20%'\n        }\n      ],\n      hooksLoaded: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('license', ['hasPermission']),\n    isLoadingTable() {\n      return this.hooksLoaded\n    },\n    searchFormatted() {\n      if (!this.search) return null\n      return `%${this.search}%`\n    }\n  },\n  watch: {\n    tenant() {\n      this.$apollo.queries.cloudHooks.refetch()\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    closeHookDialog() {\n      this.selectHook = ''\n      this.dialogDeleteHook = false\n    },\n    formatStates(stateArray) {\n      if (stateArray && stateArray.length > 0) {\n        return stateArray\n          .toString()\n          .toLowerCase()\n          .replace(/,/g, ', ')\n      }\n      return 'No states configured'\n    },\n    async testCloudHook(item) {\n      this.setTest = item.id\n      try {\n        let input = {\n          cloud_hook_id: item.id,\n          state_type: 'SUCCESS'\n        }\n\n        const testCloudHookResult = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/test-cloud-hook.gql'),\n          variables: {\n            input: input\n          },\n          errorPolicy: 'all'\n        })\n        setTimeout(() => {\n          if (testCloudHookResult?.data?.test_cloud_hook?.success) {\n            this.setAlert(\n              {\n                alertShow: true,\n                alertMessage: 'Cloud Hook test dispatched.',\n                alertType: 'success'\n              },\n              3000\n            )\n            this.setTest = ''\n          } else {\n            this.setAlert(\n              {\n                alertShow: true,\n                alertMessage: `Cloud Hook test failed with the following message: <strong>${testCloudHookResult?.data?.test_cloud_hook?.error}</strong>`,\n                alertType: 'error'\n              },\n              3000\n            )\n            this.setTest = ''\n          }\n        }, 500)\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Flow Settings',\n            stage: 'Test Cloud Hook'\n          }\n        })\n        this.setAlert(\n          {\n            alertShow: true,\n            alertMessage: `Cloud Hook test failed with the following message: <strong>${e}</strong>`,\n            alertType: 'error'\n          },\n          3000\n        )\n        this.setTest = ''\n      }\n    },\n    async deleteCloudHook() {\n      this.removingHook = true\n      try {\n        let input = {\n          cloud_hook_id: this.selectHook?.id\n        }\n        const deleteCloudHookResult = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/delete-cloud-hook.gql'),\n          variables: {\n            input: input\n          },\n          errorPolicy: 'all'\n        })\n        setTimeout(() => {\n          if (deleteCloudHookResult?.data?.delete_cloud_hook?.success) {\n            this.$apollo.queries.cloudHooks.refetch()\n            this.removingHook = false\n            this.setAlert(\n              {\n                alertShow: true,\n                alertMessage: `Cloud Hook <span>${this.selectHook?.name} <span> deleted`,\n                alertType: 'info'\n              },\n              3000\n            )\n            this.dialogDeleteHook = false\n          } else {\n            this.setAlert(\n              {\n                alertShow: true,\n                alertMessage: `Error deleting Cloud Hook: ${deleteCloudHookResult.errors[0].message}s`,\n                alertType: 'error'\n              },\n              3000\n            )\n            this.removingHook = false\n            this.dialogDeleteHook = false\n          }\n        }, 1000)\n      } catch (e) {\n        LogRocket.captureException(e, {\n          extra: {\n            pageName: 'Cloud Hooks',\n            stage: 'Delete Cloud Hook'\n          }\n        })\n        this.removingHook = false\n        this.setAlert(\n          {\n            alertShow: true,\n            alertMessage: `Error deleting Cloud Hook: ${e}s`,\n            alertType: 'error'\n          },\n          3000\n        )\n        this.dialogDeleteHook = false\n      }\n    }\n  },\n  apollo: {\n    cloudHooks: {\n      query: require('@/graphql/TeamSettings/cloud-hooks.gql'),\n      error() {\n        this.handleError(\n          'Something went wrong while trying to fetch your cloud hooks'\n        )\n      },\n      variables() {\n        let searchParams = []\n        searchParams.push({ name: { _ilike: this.searchFormatted } })\n        searchParams.push({\n          version_group_id: { _ilike: this.searchFormatted }\n        })\n        searchParams.push({\n          type: { _ilike: this.searchFormatted }\n        })\n        return {\n          searchParams: searchParams\n        }\n      },\n      result({ data }) {\n        if (!data) return\n        this.hooksLoaded = true\n      },\n      update: data => data.cloud_hook,\n      fetchPolicy: 'no-cache'\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout show control-show>\n    <template #title>Cloud Hooks</template>\n    <template #subtitle>\n      <div v-if=\"!hasPermission('update', 'cloud-hook')\">\n        View your team's\n        <ExternalLink\n          href=\"https://docs.prefect.io/orchestration/concepts/cloud_hooks.html\"\n          >Cloud Hooks\n        </ExternalLink>\n      </div>\n      <div v-else>\n        View and manage your team's\n        <ExternalLink\n          href=\"https://docs.prefect.io/orchestration/concepts/cloud_hooks.html\"\n        >\n          Cloud Hooks\n        </ExternalLink>\n      </div>\n    </template>\n\n    <template v-if=\"hasPermission('create', 'cloud-hook')\" #cta>\n      <v-dialog v-model=\"createNewCloudHook\" max-width=\"700\">\n        <template #activator=\"{ onD }\">\n          <v-tooltip top>\n            <template #activator=\"{ on }\">\n              <div class=\"pb-1\" style=\"display: inline-block;\" v-on=\"on\">\n                <v-btn\n                  color=\"primary\"\n                  data-cy=\"new-hook\"\n                  large\n                  @click=\"createNewCloudHook = true\"\n                  v-on=\"onD\"\n                >\n                  <v-icon left>cloud</v-icon> New Cloud Hook\n                </v-btn>\n              </div>\n            </template>\n            <span v-if=\"!hasPermission('create', 'cloud-hook')\">\n              You don't have permission to create new Cloud Hooks.\n            </span>\n            <span v-else>\n              Create a new Cloud Hook\n            </span>\n          </v-tooltip>\n        </template>\n\n        <v-card tile class=\"pa-2\">\n          <CardTitle title=\"New Cloud Hook\" icon=\"cloud\" />\n\n          <v-card-text class=\"pl-12\">\n            <CloudHookForm\n              v-if=\"createNewCloudHook\"\n              :editable=\"\n                hasPermission('create', 'cloud-hook') &&\n                  hasPermission('delete', 'cloud-hook')\n              \"\n              edit-on-render\n              @close=\"createNewCloudHook = false\"\n              @update=\"$apollo.queries.cloudHooks.refetch()\"\n            />\n          </v-card-text>\n        </v-card>\n      </v-dialog>\n    </template>\n\n    <v-card :class=\"{ 'mt-3': $vuetify.breakpoint.mdAndUp }\" tile>\n      <div class=\"py-1 mr-2 flex\">\n        <v-text-field\n          v-model=\"search\"\n          class=\"rounded-0 elevation-1\"\n          solo\n          dense\n          hide-details\n          single-line\n          placeholder=\"Search by hook name or type\"\n          prepend-inner-icon=\"search\"\n          autocomplete=\"new-password\"\n          :style=\"{\n            'max-width': $vuetify.breakpoint.mdAndUp ? '420px' : null\n          }\"\n        ></v-text-field>\n      </div>\n      <v-data-table\n        :headers=\"allHeaders\"\n        :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n        data-cy=\"cloud-hook-table\"\n        :search=\"search\"\n        :items=\"cloudHooks\"\n        :items-per-page=\"10\"\n        class=\"elevation-2 rounded-0\"\n        :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n        :footer-props=\"{\n          showFirstLastPage: true,\n          itemsPerPageOptions: [10, 15, 20, -1],\n          firstIcon: 'first_page',\n          lastIcon: 'last_page',\n          prevIcon: 'keyboard_arrow_left',\n          nextIcon: 'keyboard_arrow_right'\n        }\"\n        :loading=\"!isLoadingTable\"\n        no-data-text=\"No Cloud Hooks found.\"\n        ><!-- HEADERS -->\n        <template #header.name=\"{ header }\">\n          <span class=\"text-subtitle-2 text-center\">{{ header.text }}</span>\n        </template>\n        <template #header.active=\"{ header }\">\n          <span class=\"text-subtitle-2 text-center\">{{ header.text }}</span>\n        </template>\n        <template #header.version_group_id=\"{ header }\">\n          <span class=\"text-subtitle-2 text-center\">{{ header.text }}</span>\n        </template>\n        <template #header.type=\"{ header }\">\n          <span class=\"text-subtitle-2 text-center\">{{ header.text }}</span>\n        </template>\n        <template #header.states=\"{ header }\"\n          >text-\n          <span class=\"text-subtitle-2 text-center\">{{ header.text }}</span>\n        </template>\n        <template #item.version_group_id=\"{ item }\">\n          <ApolloQuery\n            :query=\"\n              gql => gql`\n                query($VGI: String) {\n                  flow(\n                    where: {\n                      _and: [\n                        { version_group_id: { _eq: $VGI } }\n                        { archived: { _eq: false } }\n                      ]\n                    }\n                  ) {\n                    id\n                    name\n                  }\n                }\n              `\n            \"\n            :variables=\"{ VGI: item.version_group_id }\"\n            :skip=\"!item.version_group_id\"\n          >\n            <template #default=\"{ result: { loading, error, data } }\">\n              <!-- Loading -->\n              <div v-if=\"loading\" class=\"loading apollo\">Loading...</div>\n              <!-- Error -->\n              <div v-else-if=\"error\" class=\"error apollo\">An error occurred</div\n              ><!-- Result -->\n              <div v-else-if=\"data && data.flow[0]\" class=\"result apollo\">\n                <router-link\n                  :to=\"{\n                    name: 'flow',\n                    params: {\n                      id: data.flow[0].id,\n                      tenant: tenant.slug\n                    },\n                    query: { settings: '' }\n                  }\"\n                >\n                  {{ data.flow[0].name }}</router-link\n                ></div\n              ><div v-else-if=\"data\"> No flow :(</div>\n              <!-- No result -->\n              <div v-else class=\"no-result apollo\">No flow :(</div>\n            </template>\n          </ApolloQuery>\n        </template>\n        <template #item.type=\"{ item }\">\n          <v-tooltip bottom>\n            <template #activator=\"{ on }\">\n              <v-icon class=\"mr-3\" v-on=\"on\">\n                {{ typeIcon(item.type) }}\n              </v-icon>\n            </template>\n            <span>\n              {{ typeTitle(item.type) }}\n            </span>\n          </v-tooltip>\n        </template>\n        <template #item.active=\"{ item }\">\n          <v-tooltip bottom>\n            <template #activator=\"{ on }\">\n              <div v-on=\"on\" @click.stop>\n                <div class=\"vertical-button mr-3\">\n                  <v-switch\n                    v-model=\"item.active\"\n                    hide-details\n                    class=\"v-input--vertical mt-0\"\n                    color=\"primary\"\n                    :loading=\"item.loading\"\n                    :disabled=\"\n                      (!hasPermission('create', 'cloud-hook') &&\n                        !hasPermission('delete', 'cloud-hook')) ||\n                        item.loading\n                    \"\n                    @change=\"_handleSetCloudHookStatusChange($event, item)\"\n                  >\n                    <template #label>\n                      <v-btn tile small text disabled class=\"mb-1\">\n                        {{ item.active ? 'On' : 'Off' }}\n                      </v-btn>\n                    </template>\n                  </v-switch>\n                </div>\n              </div>\n            </template>\n            <span v-if=\"!hasPermission('update', 'cloud-hook')\">\n              You don't have permission to change Cloud Hook states.\n            </span>\n            <span v-else>\n              {{ item.active ? 'Deactivate' : 'Activate' }}\n              this Cloud Hook.\n            </span>\n          </v-tooltip>\n        </template>\n        <template #item.states=\"{ item }\">\n          <v-tooltip bottom>\n            <template #activator=\"{ on }\">\n              <div class=\"text-body-2\" v-on=\"on\">\n                <v-chip\n                  label\n                  small\n                  dark\n                  :color=\"stateGroupColor(stateGroup(item.states))\"\n                  class=\"ml-2\"\n                >\n                  {{ stateGroup(item.states) }}\n                </v-chip>\n              </div>\n            </template>\n            <span class=\"capitalize\">{{ formatStates(item.states) }}</span>\n          </v-tooltip>\n        </template>\n        <template\n          v-if=\"\n            hasPermission('create', 'cloud-hook') &&\n              hasPermission('delete', 'cloud-hook')\n          \"\n          #item.action=\"{ item }\"\n        >\n          <v-tooltip bottom>\n            <template #activator=\"{ on }\">\n              <div style=\"display: inline-block;\" v-on=\"on\">\n                <v-btn\n                  :loading=\"setTest === item.id\"\n                  text\n                  fab\n                  color=\"warning\"\n                  x-small\n                  @click=\"testCloudHook(item)\"\n                >\n                  <v-icon>bug_report</v-icon>\n                </v-btn>\n              </div>\n            </template>\n            <span>\n              Test this Cloud Hook (will send a test call to your endpoint)\n            </span>\n          </v-tooltip>\n          <v-tooltip bottom>\n            <template #activator=\"{ on }\">\n              <v-btn\n                text\n                fab\n                x-small\n                color=\"primary\"\n                v-on=\"on\"\n                @click=\"\n                  dialogEditHook = true\n                  selectHook = item\n                \"\n              >\n                <v-icon>edit</v-icon>\n              </v-btn>\n            </template>\n            Modify this cloud hook\n          </v-tooltip>\n\n          <v-tooltip bottom>\n            <template #activator=\"{ on }\">\n              <v-btn\n                color=\"error\"\n                text\n                fab\n                x-small\n                v-on=\"on\"\n                @click=\"\n                  dialogDeleteHook = true\n                  selectHook = item\n                \"\n              >\n                <v-icon>delete</v-icon>\n              </v-btn>\n            </template>\n            Delete this cloud hook\n          </v-tooltip>\n        </template>\n      </v-data-table>\n\n      <ConfirmDialog\n        v-if=\"selectHook\"\n        v-model=\"dialogDeleteHook\"\n        type=\"error\"\n        :dialog-props=\"{ 'max-width': '600' }\"\n        :disabled=\"removingHook\"\n        :loading=\"removingHook\"\n        :title=\"\n          `Are you sure you want to delete ${\n            selectHook.name ? '' : 'this'\n          } cloud hook ${selectHook.name ? selectHook.name : ''}?`\n        \"\n        @cancel=\"closeHookDialog\"\n        @confirm=\"deleteCloudHook\"\n      />\n      <v-dialog v-model=\"dialogEditHook\" max-width=\"700\">\n        <v-card tile class=\"pa-2\">\n          <CardTitle title=\"Edit Cloud Hook\" icon=\"cloud\" />\n\n          <v-card-text class=\"pl-12\">\n            <CloudHookForm\n              v-if=\"dialogEditHook\"\n              :editable=\"\n                hasPermission('create', 'cloud-hook') &&\n                  hasPermission('delete', 'cloud-hook')\n              \"\n              edit-on-render\n              :hook=\"selectHook\"\n              show-controls\n              :version-group-id-prop=\"selectHook.version_group_id\"\n              :loading.sync=\"selectHook.loading\"\n              @close=\"dialogEditHook = false\"\n              @update=\"$apollo.queries.cloudHooks.refetch()\"\n            />\n          </v-card-text>\n        </v-card>\n      </v-dialog>\n    </v-card>\n  </ManagementLayout>\n</template>\n\n<style lang=\"scss\" scoped>\n.flex {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.capitalize {\n  text-transform: capitalize;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/CreateRoleTable.vue",
    "content": "<script>\nimport { mapActions } from 'vuex'\nimport isEqual from 'lodash/isEqual'\n\nexport default {\n  components: {},\n  props: {\n    roleName: {\n      type: String,\n      required: false,\n      default: ''\n    },\n    template: {\n      type: Object,\n      required: false,\n      default: null\n    }\n  },\n  data() {\n    return {\n      //Skeleton loaders\n      attrs: {\n        class: 'mb-0',\n        elevation: 0\n      },\n      attra: {\n        height: '20px',\n        width: '30%',\n        elevation: 0\n      },\n      attrb: {\n        height: '20px',\n        width: '80%',\n        elevation: 0\n      },\n      loadingKey: 0,\n      loadingRole: false,\n      isChanged: false,\n      templatePermissions: null,\n      permissions: null,\n      defaultRole: false,\n      enableEdit: false,\n      permissionGroups: {\n        Auth: {\n          'api-key': { name: 'User API Key', value: 'api-key' },\n          'service-account': {\n            name: 'Service Account',\n            value: 'service-account'\n          },\n          'service-api-key': {\n            name: 'Service API Key',\n            value: 'service-api-key'\n          }\n        },\n        Flows: {\n          run: { name: 'Run', value: 'run' },\n          project: { name: 'Project', value: 'project' },\n          log: { name: 'Logs', value: 'log' },\n          flow: { name: 'Flow', value: 'flow' }\n        },\n        Agents: {\n          agent: { name: 'Agent', value: 'agent' }\n        },\n        Secrets: {\n          secret: { name: 'Secret', value: 'secret' },\n          ['secret-value']: { name: 'Secret Value', value: 'secret-value' }\n        },\n        Features: {\n          ['cloud-hook']: { name: 'Cloud Hooks', value: 'cloud-hook' },\n          hook: { name: 'Automations', value: 'hook' },\n          ['flow-sla']: { name: 'Flow SLA', value: 'flow-sla' },\n          ['key-value']: { name: 'Key Value', value: 'key-value' },\n          ['concurrency-limit']: {\n            name: 'Concurrency Limit',\n            value: 'concurrency-limit'\n          },\n          ['audit-trail']: { name: 'Audit Trail', value: 'audit-trail' }\n        },\n        Admin: {\n          usage: { name: 'Usage', value: 'usage' },\n          user: { name: 'User', value: 'user', defaultRead: true },\n          tenant: { name: 'Team', value: 'tenant', defaultRead: true },\n          license: { name: 'License', value: 'license', defaultRead: true },\n          role: { name: 'Role', value: 'role', defaultRead: true },\n          membership: { name: 'Membership', value: 'membership' },\n          ['membership-invitation']: {\n            name: 'Membership Invitation',\n            value: 'membership-invitation'\n          },\n          message: { name: 'Notifications', value: 'message', defaultAll: true }\n        }\n      }\n    }\n  },\n  computed: {\n    disableEdit() {\n      if (this.defaultRole) return true\n      if (this.enableEdit) return false\n      if (!this.template) return false\n      return true\n    },\n    noName() {\n      return !this.template && !this.roleName\n    },\n    authPermissionObject() {\n      let obj = Object.values(this.permissionGroups).map(permissionGroup => {\n        this.auth?.user_permissions_filtered_by_license_features?.reduce(\n          (permissionsObj, item) => {\n            const sections = item.split(':')\n            if (permissionsObj[sections[1]]?.includeMore) {\n              if (sections[0] === 'create')\n                permissionsObj[sections[1]].disableCreate = false\n              if (sections[0] === 'read')\n                permissionsObj[sections[1]].disableRead = false\n              if (sections[0] === 'update')\n                permissionsObj[sections[1]].disableUpdate = false\n              if (sections[0] === 'delete')\n                permissionsObj[sections[1]].disableDelete = false\n            } else if (permissionsObj[sections[1]]) {\n              permissionsObj[sections[1]] = {\n                ...permissionsObj[sections[1]],\n                includeMore: true,\n                disableCreate: sections[0] !== 'create',\n                disableUpdate: sections[0] !== 'update',\n                disableRead: sections[0] !== 'read',\n                disableDelete: sections[0] !== 'delete',\n                includeUpdate: false,\n                includeCreate: false,\n                includeDelete: false,\n                includeRead: false,\n                includeAll: false,\n                shortName: sections[1],\n                key: item,\n                value: item\n              }\n            }\n            return permissionsObj\n          },\n          permissionGroup\n        )\n        return permissionGroup\n      })\n      return obj\n    },\n    loading() {\n      return this.loadingKey > 0\n    }\n  },\n  watch: {\n    template(val) {\n      this.defaultRole = val?.default ? true : false\n      this.permissions = Object.values(this.templatePermissionObject())\n      this.enableEdit = false\n    },\n    permissions: {\n      //need a deep handler here to make sure we check the whole nested permissions object\n      handler: function(val) {\n        if (val) this.hasChanges()\n      },\n      deep: true\n    }\n  },\n  created() {\n    this.permissions = Object.values(this.templatePermissionObject())\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    hasChanges() {\n      const equal = isEqual(this.permissions, this.templatePermissions)\n      this.isChanged = !equal\n    },\n    permissionList(item) {\n      return Object.values(item)\n    },\n    groupName(index) {\n      return Object.keys(this.permissionGroups)[index]\n    },\n    templatePermissionObject() {\n      let copiedPermissionsArr = []\n      if (!this.authPermissionObject) return\n      const permissionsArr = this.authPermissionObject.map(group => {\n        Object?.values(group).map(obj => {\n          if (obj.defaultAll) {\n            obj.includeCreate = true\n            obj.includeRead = true\n            obj.includeUpdate = true\n            obj.includeDelete = true\n            obj.includeAll = true\n          } else {\n            obj.includeCreate = false\n            obj.includeRead = false\n            obj.includeUpdate = false\n            obj.includeDelete = false\n            obj.includeAll = false\n            if (obj.defaultRead) obj.includeRead = true\n          }\n        })\n        this.template?.permissions?.map(item => {\n          const sections = item.split(':')\n          if (group[sections[1]]) {\n            if (sections[0] === 'create')\n              group[sections[1]].includeCreate = true\n            if (sections[0] === 'read') group[sections[1]].includeRead = true\n            if (sections[0] === 'update')\n              group[sections[1]].includeUpdate = true\n            if (sections[0] === 'delete')\n              group[sections[1]].includeDelete = true\n            group[sections[1]].includeAll =\n              group[sections[1]].includeDelete &&\n              group[sections[1]].includeUpdate &&\n              group[sections[1]].includeRead &&\n              group[sections[1]].includeCreate\n          }\n        })\n        //Using JSON here to create a deep clone of nested object\n        copiedPermissionsArr.push(JSON.parse(JSON.stringify(group)))\n        return group\n      })\n      this.templatePermissions = copiedPermissionsArr\n      return permissionsArr\n    },\n    cancel() {\n      this.permissions = Object.values(this.templatePermissionObject())\n      this.enableEdit = false\n      this.$emit('close')\n    },\n    handleAll(item) {\n      if (this.disableEdit) return\n      item.includeRead = item.includeAll\n      item.includeCreate = item.includeAll\n      item.includeDelete = item.includeAll\n      item.includeUpdate = item.includeAll\n    },\n    handleCreateUpdateClick() {\n      this.loadingRole = true\n      if (this.template) this.updateRole()\n      else this.createNewRole()\n    },\n    async createNewRole() {\n      try {\n        const includedPermissions = []\n        this.permissions.forEach(group => {\n          Object.values(group).forEach(permission => {\n            if (permission.includeCreate && !permission.disableCreate)\n              includedPermissions.push(`create:${permission.shortName}`)\n            if (permission.includeDelete && !permission.disableDelete)\n              includedPermissions.push(`delete:${permission.shortName}`)\n            if (permission.includeRead && !permission.disableRead)\n              includedPermissions.push(`read:${permission.shortName}`)\n            if (permission.includeUpdate && !permission.disableUpdate)\n              includedPermissions.push(`update:${permission.shortName}`)\n          })\n        })\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-custom-role.gql'),\n          variables: {\n            input: {\n              name: this.roleName,\n              permissions: includedPermissions\n            }\n          }\n        })\n        if (res?.data?.create_custom_role) {\n          this.setAlert({\n            alertShow: true,\n            alertMessage: 'Role created',\n            alertType: 'Success'\n          })\n        }\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `${e}`,\n          alertType: 'error'\n        })\n      } finally {\n        this.loadingRole = false\n        this.enableEdit = false\n        this.$emit('close')\n      }\n    },\n    async updateRole() {\n      try {\n        const includedPermissions = []\n        this.permissions.forEach(group => {\n          Object.values(group).forEach(permission => {\n            if (permission.includeCreate && !permission.disableCreate)\n              includedPermissions.push(`create:${permission.shortName}`)\n            if (permission.includeDelete && !permission.disableDelete)\n              includedPermissions.push(`delete:${permission.shortName}`)\n            if (permission.includeRead && !permission.disableRead)\n              includedPermissions.push(`read:${permission.shortName}`)\n            if (permission.includeUpdate && !permission.disableUpdate)\n              includedPermissions.push(`update:${permission.shortName}`)\n          })\n        })\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/update-custom-role.gql'),\n          variables: {\n            input: {\n              role_id: this.template.id,\n              permissions: includedPermissions\n            }\n          }\n        })\n        if (res?.data?.update_custom_role_permissions) {\n          this.setAlert({\n            alertShow: true,\n            alertMessage: 'Role updated',\n            alertType: 'Success'\n          })\n        }\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `${e}`,\n          alertType: 'error'\n        })\n      } finally {\n        this.loadingRole = false\n        this.enableEdit = false\n        this.$apollo.queries.auth.refetch()\n        this.$emit('close')\n      }\n    }\n  },\n  apollo: {\n    auth: {\n      query: require('@/graphql/TeamSettings/permissions.gql'),\n      loadingKey: 'loadingKey',\n      update: data => data.permissions_info\n    }\n  }\n}\n</script>\n\n<template>\n  <v-card elevation=\"0\" width=\"100%\">\n    <div v-if=\"loading\" :style=\"{ height: '100vH' }\" class=\"text-center pa-4\">\n      <v-row style=\"{height: '35px'}\">\n        <v-col cols=\"12\">\n          <v-skeleton-loader v-bind=\"attra\" type=\"text\"></v-skeleton-loader>\n          <v-divider></v-divider>\n        </v-col>\n      </v-row>\n      <v-row>\n        <v-col cols=\"5\">\n          <v-skeleton-loader v-bind=\"attrb\" type=\"text\"></v-skeleton-loader>\n        </v-col>\n        <v-col cols=\"1\"></v-col>\n        <v-col v-for=\"n in 5\" :key=\"n\" cols=\"1\">\n          <v-skeleton-loader v-bind=\"attrb\" type=\"text\"></v-skeleton-loader>\n        </v-col>\n      </v-row>\n      <v-row>\n        <v-col cols=\"4\">\n          <v-skeleton-loader\n            v-for=\"n in 4\"\n            :key=\"n\"\n            v-bind=\"attrs\"\n            type=\"list-item\"\n          ></v-skeleton-loader>\n        </v-col>\n        <v-col cols=\"8\">\n          <v-skeleton-loader v-bind=\"attrs\" type=\"image\"></v-skeleton-loader>\n        </v-col>\n      </v-row>\n    </div>\n    <div v-else class=\"font-weight-light\">\n      <div height=\"35px\" class=\"pa-2\">\n        <div v-if=\"defaultRole\" class=\"pl-2 pt-2\"\n          >Default Roles can not be modified.</div\n        >\n        <div v-else class=\"text-right\">\n          <div v-if=\"enableEdit || !template\">\n            <v-btn small elevation=\"0\" text class=\"mr-2\" @click.stop=\"cancel\">\n              Cancel\n            </v-btn>\n            <v-btn\n              elevation=\"0\"\n              small\n              color=\"primary\"\n              :loading=\"loadingRole\"\n              :disabled=\"(!isChanged && !!template) || noName\"\n              @click.stop=\"handleCreateUpdateClick\"\n            >\n              {{ template ? 'Update' : 'Create' }} Role\n            </v-btn>\n          </div>\n          <div v-else class=\"mr-2\">\n            <v-btn\n              elevation=\"0\"\n              small\n              color=\"primary\"\n              @click.stop=\"enableEdit = true\"\n            >\n              Edit\n            </v-btn>\n          </div>\n        </div>\n        <v-divider class=\"mt-2\"></v-divider>\n      </div>\n      <v-sheet height=\"95vh\" :style=\"{ overflow: 'auto' }\" class=\"pa-4\">\n        <div v-for=\"(group, index) in permissions\" :key=\"index\">\n          <v-row class=\"mb-4\" no-gutters>\n            <v-col cols=\"4\" class=\"text-h5 font-weight-light text--secondary\">\n              {{ groupName(index) }}\n            </v-col>\n            <v-col class=\"text-center mr-4 text--secondary\" cols=\"1\"\n              ><span>All</span></v-col\n            >\n            <v-col class=\"text-center mx-2 text--secondary\" cols=\"1\"\n              >Create</v-col\n            >\n            <v-col class=\"text-center mx-2 text--secondary\" cols=\"1\"\n              >Read</v-col\n            >\n            <v-col class=\"text-center mx-2 text--secondary\" cols=\"1\"\n              >Update</v-col\n            >\n            <v-col class=\"text-center mx-2 text--secondary\" cols=\"1\"\n              >Delete</v-col\n            >\n          </v-row>\n          <div v-for=\"(item, indexa) in group\" :key=\"indexa\">\n            <v-row no-gutters class=\"pa-0 ma-0\">\n              <v-col cols=\"4\">\n                <span> {{ item.name }} </span>\n              </v-col>\n\n              <v-col class=\"my-0 ml-0 mr-4 text-center\" cols=\"1\">\n                <v-simple-checkbox\n                  v-model=\"item.includeAll\"\n                  hide-details\n                  :ripple=\"false\"\n                  color=\"primary\"\n                  class=\"deep\"\n                  :disabled=\"disableEdit\"\n                  :style=\"{ 'margin-top': '0px' }\"\n                  @click=\"handleAll(item)\"\n                />\n              </v-col>\n              <v-col cols=\"1\" class=\" mx-2 text-center\">\n                <v-simple-checkbox\n                  v-if=\"!item.disableCreate\"\n                  v-model=\"item.includeCreate\"\n                  :disabled=\"disableEdit\"\n                  color=\"primary\"\n                  class=\"deep\"\n                  hide-details\n                  :ripple=\"false\"\n                  :style=\"{ 'margin-top': '0px' }\"\n                />\n              </v-col>\n              <v-col cols=\"1\" class=\" mx-2 text-center\">\n                <v-simple-checkbox\n                  v-if=\"!item.disableRead\"\n                  v-model=\"item.includeRead\"\n                  :disabled=\"disableEdit\"\n                  hide-details\n                  class=\"deep\"\n                  :ripple=\"false\"\n                  color=\"primary\"\n                  :style=\"{ 'margin-top': '0px' }\"\n                />\n              </v-col>\n              <v-col cols=\"1\" class=\" mx-2 text-center\">\n                <v-simple-checkbox\n                  v-if=\"!item.disableUpdate\"\n                  v-model=\"item.includeUpdate\"\n                  :disabled=\"disableEdit\"\n                  hide-details\n                  class=\"deep\"\n                  :ripple=\"false\"\n                  color=\"primary\"\n                  :style=\"{ 'margin-top': '0px' }\"\n                />\n              </v-col>\n              <v-col cols=\"1\" class=\"mx-2 text-center\">\n                <v-simple-checkbox\n                  v-if=\"!item.disableDelete\"\n                  v-model=\"item.includeDelete\"\n                  :disabled=\"disableEdit\"\n                  hide-details\n                  class=\"deep\"\n                  :ripple=\"false\"\n                  color=\"primary\"\n                  :style=\"{ 'margin-top': '0px' }\"\n                />\n              </v-col>\n            </v-row>\n          </div>\n          <v-row>\n            <v-col class=\"my-4\" cols=\"12\"><v-divider></v-divider></v-col>\n          </v-row>\n        </div>\n      </v-sheet>\n    </div>\n  </v-card>\n</template>\n\n<style scoped>\n.deep >>> div {\n  margin-right: 0px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/FlowConcurrency.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nimport Alert from '@/components/Alert'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ExternalLink from '../../components/ExternalLink.vue'\nimport ManagementLayout from '@/layouts/ManagementLayout'\n\nconst ADD_SUCCESS = 'A new label concurrency limit has been successfully added.'\nconst ADD_ERROR =\n  'Something went wrong while trying to add your flow label concurrency limit.'\n\nconst DELETE_SUCCESS =\n  'The label concurrency limit has been successfully deleted.'\nconst DELETE_ERROR =\n  'Something went wrong while trying to delete this concurrency limit.'\n\nconst UPDATE_SUCCESS =\n  'The label concurrency limit has been successfully updated.'\nconst UPDATE_ERROR =\n  'Something went wrong while trying to update this concurrency limit.'\n\nexport default {\n  components: {\n    Alert,\n    ConfirmDialog,\n    ExternalLink,\n    ManagementLayout\n  },\n  data() {\n    return {\n      // Alert data\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n\n      // Labels with concurrency limits\n      // Stored result from GraphQL query\n      labels: [],\n\n      // Map label names (String) to usage (Int)\n      // Stored result from GraphQL query, modified from array to object\n      usage: {},\n\n      // Table headers\n      headers: [\n        {\n          text: 'Label',\n          value: 'name',\n          width: '20%'\n        },\n        {\n          text: 'Usage',\n          value: 'usage',\n          align: 'center',\n          width: '40%',\n          sortable: false\n        },\n        {\n          text: 'Limit',\n          value: 'limit',\n          align: 'center',\n          width: '20%',\n          sortable: false\n        },\n        {\n          text: '',\n          value: 'actions',\n          align: 'right',\n          width: '20%'\n        }\n      ],\n\n      // Form inputs\n      // Limit (used for both add & edit forms)\n      newLimit: null,\n      // Label name (used for add form only)\n      newLabel: null,\n\n      // Input rules\n      rules: {\n        required: value => !!value || 'This field is required.',\n        positiveOnly: value =>\n          parseInt(value) >= 0 ||\n          'The concurrency limit cannot be a negative value.'\n      },\n\n      // Form validation\n      // Determine if add form is valid\n      addValid: true,\n      // Determine if edit form is valid\n      editValid: true,\n\n      // Keep track of label that has been selected for editing or deletion\n      selectedLabel: {},\n\n      // Keep track of label that is in the middle of being deleted\n      deletingLimitId: null,\n\n      // Server error message\n      errorMessage: '',\n\n      // Dialogs\n      showAddDialog: false,\n      showDeleteDialog: false,\n      showEditDialog: false,\n\n      // Search input\n      search: '',\n\n      loadingKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['permissions', 'hasPermission']),\n    // Determine if user has permission to add, edit, and delete concurrency limits\n    hasManagementPermission() {\n      return this.permissionsCheck\n    },\n    permissionsCheck() {\n      return (\n        this.hasPermission('create', 'concurrency-limit') &&\n        this.hasPermission('update', 'concurrency-limit') &&\n        this.hasPermission('delete', 'concurrency-limit')\n      )\n    },\n    // Determine if user has the proper permissions to access TCLs\n    // - They are on a license that grants explicit permission to access this feature\n    isEligible() {\n      // If permissions are still loading...\n      if (!this.permissions) return true\n\n      return this.hasPermission('feature', 'concurrency-limit')\n    },\n    // Merge usage details into labels array\n    labelsWithUsage() {\n      return this.labels.map(label => ({\n        ...label,\n        usage: this.usage[label.name] || 0\n      }))\n    }\n  },\n  watch: {\n    tenant() {\n      this.$apollo?.queries?.labels?.refetch()\n      this.$apollo?.queries?.usage?.refetch()\n    }\n  },\n  methods: {\n    async addFlowLabelLimit() {\n      try {\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/FlowLabelLimit/update-flow-concurrency-limit.gql'),\n          variables: {\n            label: this.newLabel,\n            limit: Number(this.newLimit) // The API expects a type Number, so explicitly casting\n          }\n        })\n\n        if (res?.data?.update_flow_concurrency_limit?.id) {\n          this.$apollo.queries?.labels?.refetch()\n          this.handleSuccess(ADD_SUCCESS)\n        } else {\n          this.handleError(ADD_ERROR)\n        }\n      } catch (error) {\n        this.handleError(ADD_ERROR)\n      } finally {\n        this.showAddDialog = false\n      }\n    },\n    async deleteFlowLabelLimit() {\n      this.deletingLimitId = this.selectedLabel.id\n\n      try {\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/FlowLabelLimit/delete-flow-concurrency-limit.gql'),\n          variables: {\n            limitId: this.selectedLabel.id\n          }\n        })\n        if (res?.data?.delete_flow_concurrency_limit?.success) {\n          this.$apollo.queries?.labels?.refetch()\n          this.handleSuccess(DELETE_SUCCESS)\n        } else {\n          this.handleError(DELETE_ERROR)\n        }\n\n        this.deletingLimitId = null\n      } catch (error) {\n        this.handleError(DELETE_ERROR)\n\n        this.deletingLimitId = null\n      } finally {\n        this.showDeleteDialog = false\n      }\n    },\n    async updateFlowLabelLimit() {\n      try {\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/FlowLabelLimit/update-flow-concurrency-limit.gql'),\n          variables: {\n            label: this.selectedLabel.name,\n            limit: Number(this.newLimit) // The API expects a type Number, so explicitly casting\n          }\n        })\n\n        if (res?.data?.update_flow_concurrency_limit?.id) {\n          this.$apollo.queries?.labels?.refetch()\n          this.handleSuccess(UPDATE_SUCCESS)\n        } else {\n          this.handleError(UPDATE_ERROR)\n        }\n      } catch (error) {\n        this.handleError(UPDATE_ERROR)\n      } finally {\n        this.showEditDialog = false\n      }\n    },\n    openAddDialog() {\n      this.showAddDialog = true\n      this.newLimit = ''\n      this.newLabel = ''\n    },\n    openDeleteDialog(item) {\n      this.selectedLabel = item\n      this.showDeleteDialog = true\n    },\n    openEditDialog(item) {\n      this.selectedLabel = item\n      this.newLimit = item.limit\n      this.showEditDialog = true\n    },\n    handleSuccess(message) {\n      this.alertMessage = message\n      this.alertType = 'success'\n      this.alertShow = true\n    },\n    handleError(message) {\n      this.alertMessage = `${message}. Please try again. If the error persists, please contact help@prefect.io.`\n      this.alertType = 'error'\n      this.alertShow = true\n    },\n    checkValid() {\n      this.addValid = this.newLimit ? true : false\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.labels.skip = !entry.isIntersecting\n      this.$apollo.queries.usage.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    labels: {\n      query: require('@/graphql/FlowLabelLimit/flow-label-limit.gql'),\n      pollInterval: 5000,\n      loadingKey: 'loadingKey',\n      update: data => {\n        return data.flow_concurrency_limit\n      }\n    },\n    usage: {\n      query: require('@/graphql/FlowLabelUsage/flow-label-usage.gql'),\n      variables() {\n        return { labels: this.labels?.map(label => label.name) }\n      },\n      pollInterval: 5000,\n      skip() {\n        return !this.labels?.length\n      },\n      update: data => {\n        // Usage is returned as an array of objects in format { name, usage }\n        // Convert this array into object that maps label names to usage\n        return data?.flow_concurrency?.reduce((accum, usage) => {\n          accum[usage.label] = usage.usage\n          return accum\n        }, {})\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-intersect=\"{ handler: onIntersect }\">\n    <ManagementLayout>\n      <template #title>Flow Concurrency</template>\n\n      <template #subtitle>\n        Impose concurrency limits on the number of flows that are running at any\n        given time\n      </template>\n\n      <template v-if=\"isEligible && hasManagementPermission\" #cta>\n        <v-btn\n          color=\"primary\"\n          class=\"white--text\"\n          data-cy=\"add-flow-concurrency-limit\"\n          large\n          @click=\"openAddDialog\"\n        >\n          <v-icon left>\n            add\n          </v-icon>\n          Add Label\n        </v-btn>\n      </template>\n\n      <template v-if=\"!isEligible\" #alerts>\n        <v-alert\n          class=\"mx-auto\"\n          border=\"left\"\n          colored-border\n          elevation=\"2\"\n          type=\"warning\"\n          tile\n          icon=\"lock\"\n          max-width=\"600\"\n        >\n          Your plan doesn't include flow concurrency limiting.\n          <ExternalLink href=\"/plans\">Upgrade</ExternalLink> to get access to\n          flow concurrency and lots of other cool features!\n        </v-alert>\n      </template>\n\n      <template v-else-if=\"!permissionsCheck\" #alerts>\n        <v-alert\n          class=\"mx-auto\"\n          border=\"left\"\n          colored-border\n          elevation=\"2\"\n          type=\"warning\"\n          tile\n          icon=\"lock\"\n          max-width=\"600\"\n        >\n          Only team administrators can manage flow concurrency limits.\n        </v-alert>\n      </template>\n\n      <v-text-field\n        v-if=\"!$vuetify.breakpoint.mdAndUp\"\n        v-model=\"search\"\n        class=\"rounded-0 elevation-1 mb-1\"\n        solo\n        dense\n        hide-details\n        single-line\n        placeholder=\"Search by flow label or limit\"\n        prepend-inner-icon=\"search\"\n        autocomplete=\"new-password\"\n      ></v-text-field>\n\n      <v-card v-if=\"isEligible\" tile>\n        <v-card-text class=\"pa-0\">\n          <div v-if=\"$vuetify.breakpoint.mdAndUp\" class=\"py-1 mr-2 flex\">\n            <v-text-field\n              v-model=\"search\"\n              class=\"rounded-0 elevation-1\"\n              solo\n              dense\n              hide-details\n              single-line\n              placeholder=\"Search by flow label or limit\"\n              prepend-inner-icon=\"search\"\n              autocomplete=\"new-password\"\n              :style=\"{\n                'max-width': $vuetify.breakpoint.mdAndUp ? '360px' : null\n              }\"\n            ></v-text-field>\n          </div>\n\n          <v-data-table\n            fixed-header\n            data-cy=\"label-table\"\n            class=\"elevation-2 rounded-0 truncate-table\"\n            :headers=\"headers\"\n            :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n            :items=\"labelsWithUsage\"\n            :items-per-page=\"10\"\n            :search=\"search\"\n            :loading=\"loadingKey > 0\"\n            :footer-props=\"{\n              showFirstLastPage: true,\n              itemsPerPageOptions: [10, 15, 20, -1],\n              firstIcon: 'first_page',\n              lastIcon: 'last_page',\n              prevIcon: 'keyboard_arrow_left',\n              nextIcon: 'keyboard_arrow_right'\n            }\"\n            no-results-text=\"No concurrency limits found. Try expanding your search?\"\n            no-data-text=\"This team has not set any flow concurrency limits yet.\"\n          >\n            <template #header.tag=\"{ header }\">\n              <span class=\"text-subtitle-2\">{{ header.text }}</span>\n            </template>\n            <template #header.usage=\"{ header }\">\n              <v-tooltip bottom open-delay=\"500\">\n                <template #activator=\"{ on }\">\n                  <div class=\"text-subtitle-2\" v-on=\"on\">\n                    {{ header.text }}\n                    <v-icon\n                      x-small\n                      class=\"material-icons-outlined\"\n                      :style=\"{ 'margin-bottom': '2px' }\"\n                      >info</v-icon\n                    >\n                  </div>\n                </template>\n                Number of flows that are running with the given label\n              </v-tooltip>\n            </template>\n            <template #header.limit=\"{ header }\">\n              <v-tooltip bottom open-delay=\"500\">\n                <template #activator=\"{ on }\">\n                  <div class=\"text-subtitle-2\" v-on=\"on\">\n                    {{ header.text }}\n                    <v-icon\n                      x-small\n                      class=\"material-icons-outlined\"\n                      :style=\"{ 'margin-bottom': '2px' }\"\n                      >info</v-icon\n                    >\n                  </div>\n                </template>\n                Maximum number of flows that can simultaneously run with the\n                given label\n              </v-tooltip>\n            </template>\n\n            <template #item.label=\"{ item }\">\n              <div class=\"text-body-2\">{{ item.name }}</div>\n            </template>\n\n            <template #item.usage=\"{ item }\">\n              <span>\n                {{ item.usage }} running\n                {{ item.usage === 1 ? 'flow' : 'flows' }} ({{\n                  item.limit === 0\n                    ? 0\n                    : Math.ceil((item.usage / item.limit) * 100)\n                }}%)\n              </span>\n              <div class=\"mx-auto mt-1\">\n                <v-progress-linear\n                  height=\"8\"\n                  :value=\"\n                    item.limit === 0\n                      ? 0\n                      : Math.ceil((item.usage / item.limit) * 100)\n                  \"\n                ></v-progress-linear>\n              </div>\n            </template>\n\n            <template #item.limit=\"{ item }\">\n              <div class=\"text-subtitle-1 position-relative\">\n                <v-tooltip v-if=\"item.limit === 0\" bottom open-delay=\"500\">\n                  <template #activator=\"{ on }\">\n                    <div v-on=\"on\">\n                      {{ item.limit }}\n                      <v-icon\n                        x-small\n                        class=\"position-absolute material-icons-outlined ml-1\"\n                        :style=\"{\n                          top: '6px'\n                        }\"\n                      >\n                        info\n                      </v-icon>\n                    </div>\n                  </template>\n                  A concurrency limit of 0 means that flows with this label will\n                  never run.\n                </v-tooltip>\n                <span v-else>\n                  {{ item.limit }}\n                </span>\n              </div>\n            </template>\n\n            <template #item.actions=\"{ item }\">\n              <v-tooltip bottom>\n                <template #activator=\"{ on }\">\n                  <v-btn\n                    v-if=\"hasManagementPermission\"\n                    color=\"primary\"\n                    text\n                    fab\n                    x-small\n                    v-on=\"on\"\n                    @click=\"openEditDialog(item)\"\n                  >\n                    <v-icon>edit</v-icon>\n                  </v-btn>\n                </template>\n                Edit the limit for this label\n              </v-tooltip>\n\n              <v-tooltip bottom>\n                <template #activator=\"{ on }\">\n                  <v-btn\n                    v-if=\"hasManagementPermission\"\n                    color=\"red\"\n                    text\n                    fab\n                    x-small\n                    v-on=\"on\"\n                    @click=\"openDeleteDialog(item)\"\n                  >\n                    <v-progress-circular\n                      v-if=\"deletingLimitId === item.id\"\n                      indeterminate\n                    />\n                    <v-icon v-else>delete</v-icon>\n                  </v-btn>\n                </template>\n                Remove concurrency limits for flows with this label\n              </v-tooltip>\n            </template>\n          </v-data-table>\n        </v-card-text>\n      </v-card>\n\n      <ConfirmDialog\n        v-model=\"showAddDialog\"\n        :dialog-props=\"{ maxWidth: '440' }\"\n        title=\"Add a new concurrency-limiting label\"\n        :disabled=\"!addValid\"\n        @confirm=\"addFlowLabelLimit\"\n      >\n        <v-form v-model=\"addValid\">\n          <v-text-field\n            v-model=\"newLabel\"\n            outlined\n            dense\n            data-cy=\"label-name\"\n            validate-on-blur\n            :rules=\"[rules.required]\"\n            label=\"Label\"\n            autofocus\n          ></v-text-field>\n          <v-text-field\n            v-model=\"newLimit\"\n            min=\"0\"\n            type=\"number\"\n            data-cy=\"label-limit\"\n            outlined\n            validate-on-blur\n            dense\n            :rules=\"[rules.required, rules.positiveOnly]\"\n            label=\"Limit\"\n            @input=\"checkValid\"\n          ></v-text-field>\n        </v-form>\n      </ConfirmDialog>\n\n      <ConfirmDialog\n        v-if=\"selectedLabel\"\n        v-model=\"showEditDialog\"\n        :dialog-props=\"{ maxWidth: '540' }\"\n        :title=\"\n          `Edit the concurrency limit for flows with the label ${selectedLabel.name}`\n        \"\n        :disabled=\"!editValid\"\n        @confirm=\"updateFlowLabelLimit\"\n      >\n        <v-form v-model=\"editValid\">\n          <v-text-field\n            v-model=\"newLimit\"\n            min=\"0\"\n            type=\"number\"\n            outlined\n            dense\n            label=\"Limit\"\n            autofocus\n            :rules=\"[rules.required, rules.positiveOnly]\"\n            persistent-hint\n          ></v-text-field>\n        </v-form>\n      </ConfirmDialog>\n\n      <ConfirmDialog\n        v-if=\"selectedLabel\"\n        v-model=\"showDeleteDialog\"\n        :dialog-props=\"{ maxWidth: '440' }\"\n        :title=\"\n          `Are you sure you want to remove concurrency limits for flows with the\n          label ${selectedLabel.name}?`\n        \"\n        type=\"error\"\n        @confirm=\"deleteFlowLabelLimit\"\n      >\n      </ConfirmDialog>\n\n      <Alert\n        v-model=\"alertShow\"\n        :type=\"alertType\"\n        :message=\"alertMessage\"\n        :offset-x=\"56\"\n      ></Alert>\n    </ManagementLayout>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.custom-header {\n  font-size: 1.15em;\n}\n\n.flex {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.limit-change-button {\n  transform: scale(0.75);\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/FlowGroups.vue",
    "content": "<script>\nimport gql from 'graphql-tag'\nimport { mapGetters } from 'vuex'\n\nimport Alert from '@/components/Alert'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ExternalLink from '@/components/ExternalLink'\nimport ManagementLayout from '@/layouts/ManagementLayout'\n\nexport default {\n  components: {\n    Alert,\n    ConfirmDialog,\n    ExternalLink,\n    ManagementLayout\n  },\n  data() {\n    return {\n      // Table headers\n      allHeaders: [\n        {\n          mobile: true,\n          text: 'Name',\n          value: 'name',\n          width: '30%'\n        },\n        {\n          mobile: true,\n          text: 'Active',\n          value: 'active',\n          align: 'left',\n          width: '10%'\n        },\n        {\n          mobile: true,\n          text: 'Version Group ID',\n          value: 'version_group_id',\n          width: '25%'\n        },\n        {\n          mobile: false,\n          text: 'Created By',\n          value: 'created_by.username',\n          width: '10%'\n        },\n        {\n          mobile: true,\n          text: 'Project',\n          value: 'project.name',\n          width: '10%'\n        },\n        {\n          mobile: true,\n          text: '',\n          value: 'action',\n          align: 'end',\n          sortable: false,\n          width: '10%'\n        }\n      ],\n\n      // Copying FVG ID\n      copiedFvgId: null,\n      copyTimeout: null,\n\n      // Dialogs\n      dialogDeleteFvg: false,\n\n      // Load states\n      loadingKey: 0,\n      isDeletingFvg: false,\n      isLoadingFvgs: false,\n\n      // Search\n      search: null,\n\n      // FVG selected for deletion\n      selectedFvg: null,\n\n      // Alert data\n      alertShow: false,\n      alertMessage: '',\n      alertType: null\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('license', ['hasPermission']),\n\n    deleteFvgMutation() {\n      if (!this.versionGroupFlows) return {}\n\n      let mutation = this.versionGroupFlows.map(\n        (flow, ind) =>\n          `delete${ind}: deleteFlow(input: { flowId: \"${flow.id}\" }) {\n            success\n          }`\n      )\n\n      return gql`\n        mutation DeleteFlowVersionGroup {\n          ${mutation}\n        }\n      `\n    },\n    headers() {\n      return this.$vuetify.breakpoint.mdAndUp\n        ? this.allHeaders\n        : this.allHeaders.filter(header => header.mobile)\n    },\n    isLoadingTable() {\n      return this.loadingKey > 0\n    },\n    permissionsCheck() {\n      return (\n        this.hasPermission('update', 'run') &&\n        this.hasPermission('delete', 'run')\n      )\n    },\n    items() {\n      if (!(this.versionGroups && this.flows)) return []\n\n      return this.versionGroups.map(item => ({\n        ...item,\n        active:\n          this.flows.filter(\n            flow => flow.version_group_id === item.version_group_id\n          ).length > 0\n      }))\n    }\n  },\n  watch: {\n    tenant() {\n      this.selectedFvg = null\n      this.$apollo.queries.versionGroups.refetch()\n      this.$apollo.queries.flows.refetch()\n    }\n  },\n  methods: {\n    cancelFvgDelete() {\n      this.selectedFvg = null\n      this.dialogDeleteFvg = false\n    },\n    copyTextToClipboard(id) {\n      clearTimeout(this.copyTimeout)\n\n      this.copiedFvgId = id\n\n      navigator.clipboard.writeText(id)\n\n      this.copyTimeout = setTimeout(() => {\n        this.copiedFvgId = null\n      }, 3000)\n    },\n    async deleteFvg() {\n      this.isDeletingFvg = true\n\n      try {\n        await this.$apollo.mutate({\n          mutation: this.deleteFvgMutation\n        })\n\n        this.$apollo.queries.versionGroups.refetch()\n        this.$apollo.queries.flows.refetch()\n\n        this.handleSuccess(\n          'The flow version group has been successfully deleted.'\n        )\n      } catch (e) {\n        this.handleError(\n          'Something went wrong while trying to delete this flow version group.'\n        )\n        throw Error(e)\n      }\n\n      this.dialogDeleteFvg = false\n      this.isDeletingFvg = false\n      this.selectedFvg = null\n    },\n    handleError(message) {\n      this.alertType = 'error'\n      this.alertMessage = `${message}. Please try again later. If this error persists, please contact help@prefect.io.`\n      this.alertShow = true\n    },\n    handleSuccess(message) {\n      this.alertType = 'success'\n      this.alertMessage = message\n      this.alertShow = true\n    },\n    selectFvg(fvg) {\n      this.selectedFvg = fvg\n    }\n  },\n  apollo: {\n    versionGroupFlows: {\n      query: require('@/graphql/Flow/version-group.gql'),\n      variables() {\n        return {\n          versionGroupId: this.selectedFvg.version_group_id\n        }\n      },\n      update(data) {\n        return data.flow\n      },\n      skip() {\n        return !this.selectedFvg\n      },\n      loadingKey: 'loadingKey',\n      error() {\n        this.handleError(\n          'Something went wrong while trying to fetch your flows.'\n        )\n      }\n    },\n    versionGroups: {\n      query() {\n        return require('@/graphql/TeamSettings/flow-version-groups.js').default(\n          this.isCloud\n        )\n      },\n      error() {\n        this.handleError(\n          'Something went wrong while trying to fetch your flows.'\n        )\n      },\n      loadingKey: 'loadingKey',\n      update(data) {\n        return data.versionGroup\n      }\n    },\n    flows: {\n      query: require('@/graphql/TeamSettings/flows.gql'),\n      error() {\n        this.handleError(\n          'Something went wrong while trying to fetch your flows.'\n        )\n      },\n      loadingKey: 'loadingKey',\n      update(data) {\n        return data.flow\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout>\n    <template #title>Flow Groups</template>\n\n    <template #subtitle>\n      <span v-if=\"permissionsCheck\">\n        View and manage your team's flows by\n        <ExternalLink\n          href=\"https://docs.prefect.io/cloud/concepts/flows.html#versioning\"\n          >version group</ExternalLink\n        >\n      </span>\n      <span v-else\n        >View the\n        <ExternalLink\n          href=\"https://docs.prefect.io/cloud/concepts/flows.html#versioning\"\n          >flow groups</ExternalLink\n        >\n        of {{ tenant.name }}</span\n      >\n    </template>\n\n    <!-- SEARCH (MOBILE) -->\n    <v-text-field\n      v-if=\"!$vuetify.breakpoint.mdAndUp\"\n      v-model=\"search\"\n      class=\"rounded-0 elevation-1 mt-2 mb-1\"\n      solo\n      dense\n      hide-details\n      single-line\n      placeholder=\"Search by flow name, project name or creator\"\n      prepend-inner-icon=\"search\"\n      autocomplete=\"new-password\"\n    ></v-text-field>\n\n    <v-card :class=\"{ 'mt-3': $vuetify.breakpoint.mdAndUp }\" tile>\n      <v-card-text class=\"pa-0\">\n        <!-- SEARCH (DESKTOP) -->\n        <div v-if=\"$vuetify.breakpoint.mdAndUp\" class=\"py-1 mr-2 flex\">\n          <v-text-field\n            v-model=\"search\"\n            class=\"rounded-0 elevation-1\"\n            solo\n            dense\n            hide-details\n            single-line\n            placeholder=\"Search by flow name, project name or creator\"\n            prepend-inner-icon=\"search\"\n            autocomplete=\"new-password\"\n            :style=\"{\n              'max-width': $vuetify.breakpoint.mdAndUp ? '420px' : null\n            }\"\n          ></v-text-field>\n        </div>\n\n        <!-- FVG TABLE -->\n        <v-data-table\n          fixed-header\n          :search=\"search\"\n          :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n          :items=\"items\"\n          :headers=\"headers\"\n          :loading=\"loadingKey > 0\"\n          :items-per-page=\"10\"\n          class=\"elevation-2 rounded-0 truncate-table\"\n          :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n          :footer-props=\"{\n            showFirstLastPage: true,\n            itemsPerPageOptions: [10, 15, 20, -1],\n            firstIcon: 'first_page',\n            lastIcon: 'last_page',\n            prevIcon: 'keyboard_arrow_left',\n            nextIcon: 'keyboard_arrow_right'\n          }\"\n        >\n          <!-- HEADERS -->\n          <template #header.name=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.active=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.version_group_id=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.created_by.username=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.project.name=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n\n          <!-- FVG ID -->\n          <template #item.version_group_id=\"{ item }\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <div\n                  class=\"hidewidth cursor-pointer\"\n                  v-on=\"on\"\n                  @click=\"copyTextToClipboard(item.version_group_id)\"\n                >\n                  <span v-if=\"$vuetify.breakpoint.smAndUp\">\n                    {{ item.version_group_id }}\n                  </span>\n                  <span v-else>\n                    {{ item.version_group_id.substring(0, 3) }}...\n                  </span>\n                </div>\n              </template>\n              <span>{{\n                copiedFvgId === item.version_group_id\n                  ? 'Copied!'\n                  : 'Click to copy ID'\n              }}</span>\n            </v-tooltip>\n          </template>\n\n          <!-- FVG NAME -->\n          <template #item.name=\"{ item }\">\n            <v-tooltip v-if=\"item.name\" top>\n              <template #activator=\"{ on }\">\n                <div class=\"hidewidth\" v-on=\"on\">\n                  <router-link\n                    :to=\"{\n                      name: 'flow',\n                      params: {\n                        id: item.id,\n                        tenant: tenant.slug\n                      },\n                      query: { versions: '' }\n                    }\"\n                  >\n                    {{ item.name }}\n                  </router-link>\n                </div>\n              </template>\n              <span>{{ item.name }}</span>\n            </v-tooltip>\n            <span v-else>-</span>\n          </template>\n\n          <!-- FVG ACTIVE/ARCHIVED -->\n          <template #item.active=\"{ item }\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <v-icon v-if=\"item.active\" small dark color=\"green\" v-on=\"on\">\n                  pi-flow\n                </v-icon>\n                <v-icon v-else small dark color=\"accentPink\" v-on=\"on\">\n                  archive\n                </v-icon>\n              </template>\n              <span v-if=\"item.active\">\n                This version group has an active flow\n              </span>\n              <span v-else>\n                All flows in this version group are archived\n              </span>\n            </v-tooltip>\n          </template>\n\n          <!-- FVG ACTIONS -->\n          <template v-if=\"permissionsCheck\" #item.action=\"{ item }\">\n            <v-btn\n              color=\"error\"\n              text\n              fab\n              x-small\n              @click=\"\n                dialogDeleteFvg = true\n                selectFvg(item)\n              \"\n            >\n              <v-icon>delete</v-icon>\n            </v-btn>\n          </template>\n        </v-data-table>\n      </v-card-text>\n    </v-card>\n\n    <!-- DELETE FVG -->\n    <ConfirmDialog\n      v-if=\"selectedFvg\"\n      v-model=\"dialogDeleteFvg\"\n      type=\"error\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      :disabled=\"isDeletingFvg\"\n      :loading=\"isDeletingFvg\"\n      :title=\"\n        `Are you sure you want to delete the version group for ${selectedFvg.name}?`\n      \"\n      @cancel=\"cancelFvgDelete\"\n      @confirm=\"deleteFvg\"\n    >\n      This will delete <span class=\"font-weight-black\">all</span> versions of\n      your flow and cannot be undone.\n    </ConfirmDialog>\n\n    <Alert\n      v-model=\"alertShow\"\n      :type=\"alertType\"\n      :message=\"alertMessage\"\n      :offset-x=\"$vuetify.breakpoint.mdAndUp ? 256 : 56\"\n    ></Alert>\n  </ManagementLayout>\n</template>\n\n<style lang=\"scss\" scoped>\n.flex {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.hidewidth {\n  max-width: 100%;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/KV.vue",
    "content": "<script>\nimport CodeInput from '@/components/CustomInputs/CodeInput'\nimport ResettableWrapper from '@/components/CustomInputs/ResettableWrapper'\nimport ManagementLayout from '@/layouts/ManagementLayout'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport { isValidJson, formatJson, parseJson } from '@/utils/json'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { mapGetters, mapActions } from 'vuex'\n\nexport default {\n  components: {\n    CodeInput,\n    ResettableWrapper,\n    ManagementLayout,\n    ConfirmDialog\n  },\n  mixins: [formatTime],\n  data() {\n    return {\n      isEditable: false,\n      // loading states\n      isFetchingKV: true,\n      isDeletingKV: false,\n      isSettingKV: false,\n\n      // Store previous kv name when modifying kv\n      // This is used to delete the kv with that name and create a new kv with a separate value\n      previousKVName: null,\n\n      // KV selected for modification/deletion\n      selectedKV: null,\n\n      // Input rules\n      rules: {\n        required: val => !!val || 'This field is required.'\n      },\n      errorMessage: '',\n\n      // Types\n      selectedInputMode: 'text',\n      // Create/modify kv key & value input\n      keyInput: null,\n      KvValueInput: '',\n\n      // Distinguish between creating & modifying KV\n      isKvUpdate: false,\n\n      jsonInput: '',\n\n      // table search\n      search: '',\n\n      expanded: [],\n\n      //table headers\n      kvHeaders: [\n        { text: 'Key', value: 'key' },\n        { text: 'Value', value: 'value' },\n        { text: 'Created', value: 'created' },\n        { text: 'Last Updated', value: 'updated' },\n        {\n          text: '',\n          value: 'actions',\n          align: 'right',\n          sortable: false\n        }\n      ],\n\n      // Dialogs\n      keyModifyDialog: false,\n      keyDeleteDialog: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['license', 'hasPermission']),\n    maxKVCount() {\n      return this.license?.terms?.key_value_pairs\n    },\n    kvExists() {\n      if (!this.kv) return false\n\n      if (this.selectedKV?.key === this.keyInput) {\n        return false\n      }\n      return this.kv?.map(kv => kv.key).includes(this.keyInput)\n    },\n    hasEditedKvInput() {\n      return this.KvValueInput != formatJson(this.item?.value)\n    }\n  },\n  watch: {\n    tenant() {\n      this.$apollo.queries.kv.refetch()\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['addNotification']),\n    setSelectedInputMode() {\n      this.selectedInputMode = this.getInputMode(this.KvValueInput)\n    },\n    getInputMode(value) {\n      if (!isValidJson(value)) {\n        return 'text'\n      }\n\n      const parsed = parseJson(value)\n      if (typeof parsed !== 'object' || parsed == null) {\n        return 'text'\n      }\n\n      return 'json'\n    },\n    getItemValue(item) {\n      return formatJson(item?.value)\n    },\n    getItemIsExpanded(item) {\n      const expandedId = this.expanded[0]?.id\n\n      return item.id == expandedId\n    },\n    resetKvValueInput() {\n      this.KvValueInput = ''\n\n      this.setSelectedInputMode()\n    },\n    setKvValueInput(value) {\n      this.KvValueInput = formatJson(value)\n\n      this.setSelectedInputMode()\n    },\n    async copyValue(item) {\n      try {\n        if (typeof item?.value == 'object') {\n          await navigator.clipboard.writeText(this.getItemValue(item))\n        } else {\n          await navigator.clipboard.writeText(item?.value)\n        }\n        this.handleAlert('success', 'Value copied to clipboard')\n      } catch (err) {\n        this.handleAlert(\n          'error',\n          'Something went wrong trying to copy your value to the clipboard'\n        )\n      }\n    },\n    openKVEdit(item) {\n      this.selectedKV = item\n      this.isKvUpdate = true\n      this.previousKVName = item?.key\n      this.keyInput = item?.key\n\n      this.setKvValueInput(item?.value)\n      if (this.isEditable) {\n        this.expanded = [item]\n      } else {\n        this.expanded = []\n      }\n    },\n    openKVDeleteDialog(item) {\n      this.selectedKV = item\n      this.keyDeleteDialog = true\n    },\n    async handleAlert(type, message) {\n      if (type == 'success') {\n        await this.addNotification({\n          color: 'accentGreen',\n          text: message,\n          dismissable: true,\n          timeout: 5000\n        })\n      } else {\n        await this.addNotification({\n          color: 'error',\n          text: message,\n          dismissable: true,\n          timeout: 5000\n        })\n      }\n    },\n    resetSelectedKV() {\n      this.selectedKV = null\n      this.keyInput = null\n      this.resetKvValueInput()\n      this.expanded = []\n      this.isEditable = false\n    },\n    async validateAndSetKV() {\n      if (!this.keyInput || !this.$refs.KvValueInput.validate()) {\n        this.handleAlert('error', 'Cannot save with errors in form.')\n        return\n      }\n\n      await this.setKV()\n    },\n    async setKV() {\n      this.isSettingKV = true\n\n      if (this.isKvUpdate) {\n        const deleteKVResult = await this.deleteKV(\n          { id: this.selectedKV?.id },\n          { isModifying: true }\n        )\n        if (deleteKVResult?.errors) {\n          this.isSettingKV = false\n          this.resetSelectedKV()\n          return\n        }\n      }\n      const value = isValidJson(this.KvValueInput)\n        ? parseJson(this.KvValueInput)\n        : this.KvValueInput\n      const kvResult = await this.$apollo.mutate({\n        mutation: require('@/graphql/KV/set-key-value.gql'),\n        variables: {\n          key: this.keyInput,\n          value\n        },\n        errorPolicy: 'all'\n      })\n\n      if (this.isKvUpdate) this.isSettingKV = false\n\n      if (kvResult?.data?.set_key_value?.id) {\n        this.$apollo.queries.kv.refetch()\n        this.keyModifyDialog = false\n        this.resetSelectedKV()\n        this.handleAlert(\n          'success',\n          `KV ${this.isKvUpdate ? 'updated' : 'added'}.`\n        )\n      } else if (kvResult?.errors) {\n        this.expanded = []\n        this.keyModifyDialog = false\n        this.resetSelectedKV()\n        this.handleAlert('error', kvResult?.errors[0]?.message)\n      } else {\n        this.expanded = []\n        this.keyModifyDialog = false\n        this.resetSelectedKV()\n        this.handleAlert(\n          'error',\n          `Something went wrong when ${\n            this.isKvUpdate ? 'updating' : 'creating'\n          } this kv. Please try again. If this error persists, please contact help@prefect.io.`\n        )\n      }\n\n      this.isSettingKV = false\n      this.keyInput = null\n      this.resetKvValueInput()\n    },\n    async deleteKV(kv, opts = {}) {\n      this.isDeletingKV = true\n\n      const deleteKVResult = await this.$apollo.mutate({\n        mutation: require('@/graphql/KV/delete-key-value.gql'),\n        variables: {\n          id: kv?.id\n        },\n        errorPolicy: 'all'\n      })\n\n      if (deleteKVResult?.data?.delete_key_value?.success) {\n        if (!opts.isModifying) {\n          this.$apollo.queries.kv.refetch()\n          this.keyDeleteDialog = false\n          this.handleAlert('success', 'KV deleted.')\n        }\n      } else if (deleteKVResult?.errors) {\n        this.keyDeleteDialog = false\n        this.handleAlert('error', deleteKVResult?.errors[0]?.message)\n      } else {\n        this.keyDeleteDialog = false\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to delete this KV. Please try again. If this error persists, reach out to help@prefect.io.'\n        )\n      }\n\n      this.isDeletingKV = false\n      return deleteKVResult\n    },\n    handleKVExpand(kv) {\n      this.selectedKV = kv?.item\n      this.isKvUpdate = true\n      this.previousKVName = kv?.item?.key\n\n      this.setKvValueInput(kv?.item?.value)\n\n      this.keyInput = kv?.item?.key\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.kv.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    kv: {\n      query: require('@/graphql/KV/get-key-value.gql'),\n      result() {\n        this.isFetchingKV = false\n      },\n      pollInterval: 30000,\n      update(data) {\n        if (!data) return\n        return data?.key_value\n      },\n      error() {\n        this.isFetchingKV = false\n\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to fetch the kv. Please try again. If this error persists, please contact help@prefect.io.'\n        )\n      },\n      fetchPolicy: 'network-only'\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-intersect=\"{ handler: onIntersect }\">\n    <ManagementLayout :show=\"!isFetchingKV\">\n      <template #title>KV Store</template>\n\n      <template #subtitle>\n        <!-- <ExternalLink href=\"https://docs.prefect.io/orchestration/concepts/kv_store.html\">key:value</ExternalLink> -->\n\n        Manage your team's key/value store\n      </template>\n\n      <template v-if=\"hasPermission('create', 'key-value') && maxKVCount\" #cta>\n        <v-btn\n          color=\"primary\"\n          class=\"white--text\"\n          large\n          :disabled=\"kv ? kv.length >= maxKVCount : false\"\n          @click=\"\n            expanded = []\n            previousKVName = null\n            keyInput = null\n            resetKvValueInput()\n            isKvUpdate = false\n            keyModifyDialog = true\n          \"\n        >\n          <v-icon left>\n            add\n          </v-icon>\n          Add KV\n        </v-btn>\n      </template>\n\n      <template #alerts>\n        <v-alert\n          v-if=\"!hasPermission('create', 'key-value')\"\n          class=\"mx-auto\"\n          border=\"left\"\n          colored-border\n          elevation=\"2\"\n          type=\"warning\"\n          tile\n          icon=\"lock\"\n          max-width=\"380\"\n        >\n          You don't have permission to manage kv.\n        </v-alert>\n\n        <v-alert\n          v-if=\"!maxKVCount\"\n          class=\"mx-auto\"\n          border=\"left\"\n          colored-border\n          elevation=\"2\"\n          type=\"warning\"\n          tile\n          icon=\"lock\"\n          max-width=\"380\"\n        >\n          Your team's license does not include this feature. Please contact\n          help@prefect.io for more information.\n        </v-alert>\n      </template>\n\n      <v-text-field\n        v-if=\"\n          !$vuetify.breakpoint.mdAndUp && !hasPermission('create', 'key-value')\n        \"\n        v-model=\"search\"\n        class=\"rounded-0 elevation-1 mb-1\"\n        solo\n        dense\n        hide-details\n        single-line\n        placeholder=\"Search for a key\"\n        prepend-inner-icon=\"search\"\n      ></v-text-field>\n    </ManagementLayout>\n    <v-card v-if=\"maxKVCount\" tile class=\"mx-auto\">\n      <v-card-text class=\"pa-0\">\n        <!-- SEARCH (DESKTOP) -->\n        <div\n          v-if=\"$vuetify.breakpoint.mdAndUp\"\n          class=\"py-1 mr-2 d-flex justify-end\"\n        >\n          <v-text-field\n            v-model=\"search\"\n            class=\"rounded-0 elevation-1\"\n            solo\n            dense\n            hide-details\n            single-line\n            placeholder=\"Search for a key\"\n            prepend-inner-icon=\"search\"\n            :style=\"{\n              'max-width': $vuetify.breakpoint.mdAndUp ? '360px' : null\n            }\"\n          ></v-text-field>\n        </div>\n        <!-- TABLE -->\n        <v-data-table\n          :headers=\"kvHeaders\"\n          :items=\"kv\"\n          :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n          sort-by=\"created\"\n          sort-desc\n          :search=\"search\"\n          :loading=\"$apollo.queries.kv.loading\"\n          :expanded.sync=\"expanded\"\n          show-expand\n          :single-expand=\"true\"\n          no-results-text=\"No keys found. Try expanding your search?\"\n          no-data-text=\"Your team does not have any keys yet.\"\n          @item-expanded=\"handleKVExpand\"\n        >\n          <!-- ACTIONS -->\n          <template #expanded-item=\"{ headers, item }\">\n            <td :colspan=\"headers.length\">\n              <resettable-wrapper\n                :key=\"item.id\"\n                v-model=\"KvValueInput\"\n                class=\"resettable-dictionary-json\"\n                @input=\"setSelectedInputMode\"\n              >\n                <code-input\n                  ref=\"KvValueInput\"\n                  v-model=\"KvValueInput\"\n                  class=\"text-body-1 mt-2\"\n                  :mode.sync=\"selectedInputMode\"\n                  :editors=\"['text', 'json']\"\n                />\n                <div class=\"d-flex flex-grow-1 justify-end mb-5\">\n                  <v-btn\n                    small\n                    color=\"primary\"\n                    :loading=\"isSettingKV\"\n                    @click=\"validateAndSetKV\"\n                    >Save</v-btn\n                  >\n                </div>\n              </resettable-wrapper>\n            </td>\n          </template>\n          <template #item.value=\"{item}\">\n            <div class=\"d-flex\">\n              <div\n                class=\"text-truncate\"\n                style=\"\n          width: 15vw;\n        \"\n              >\n                {{ item.value }}\n              </div>\n            </div>\n          </template>\n          <template #item.created=\"{item}\">\n            {{ formatTime(item.created) }}\n          </template>\n          <template #item.updated=\"{item}\">\n            {{ formatTime(item.updated) }}\n          </template>\n          <template #item.actions=\"{item}\">\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  v-if=\"hasPermission('update', 'key-value')\"\n                  text\n                  fab\n                  x-small\n                  color=\"primary\"\n                  :disabled=\"getItemIsExpanded(item)\"\n                  v-on=\"on\"\n                  @click=\"\n                    isEditable = !isEditable\n                    openKVEdit(item)\n                  \"\n                >\n                  <v-icon>edit</v-icon>\n                </v-btn>\n              </template>\n              Modify key\n            </v-tooltip>\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  v-if=\"hasPermission('delete', 'key-value')\"\n                  text\n                  fab\n                  x-small\n                  color=\"error\"\n                  v-on=\"on\"\n                  @click=\"openKVDeleteDialog(item)\"\n                >\n                  <v-icon>delete</v-icon>\n                </v-btn>\n              </template>\n              Delete key\n            </v-tooltip>\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  text\n                  fab\n                  x-small\n                  color=\"primary\"\n                  v-on=\"on\"\n                  @click=\"copyValue(item)\"\n                >\n                  <v-icon>content_copy</v-icon>\n                </v-btn>\n              </template>\n              Copy value\n            </v-tooltip>\n          </template>\n\n          <template #footer.page-text>\n            <div class=\"text-caption\">\n              {{ kv ? kv.length : 0 }} out of {{ maxKVCount }} keys used\n            </div>\n          </template>\n        </v-data-table>\n      </v-card-text>\n    </v-card>\n\n    <ConfirmDialog\n      v-model=\"keyModifyDialog\"\n      :dialog-props=\"{ 'max-width': '75vh' }\"\n      :loading=\"isSettingKV\"\n      confirm-text=\"Save\"\n      title=\"Create KV\"\n      @confirm=\"validateAndSetKV\"\n      @cancel=\"resetSelectedKV\"\n    >\n      <v-text-field\n        v-model=\"keyInput\"\n        :rules=\"[rules.required]\"\n        :messages=\"\n          kvExists\n            ? 'A key with this this name already exists. Clicking CONFIRM will overwrite it.'\n            : null\n        \"\n        class=\"_lr-hide mt-6\"\n        autofocus\n        data-private\n        single-line\n        outlined\n        dense\n        placeholder=\"Key\"\n        prepend-inner-icon=\"vpn_key\"\n        validate-on-blur\n      />\n\n      <code-input\n        ref=\"KvValueInput\"\n        v-model=\"KvValueInput\"\n        class=\"text-body-1\"\n        placeholder=\"Value\"\n        :mode.sync=\"selectedInputMode\"\n        :editors=\"['text', 'json']\"\n      />\n    </ConfirmDialog>\n\n    <ConfirmDialog\n      v-model=\"keyDeleteDialog\"\n      type=\"error\"\n      :loading=\"isDeletingKV\"\n      confirm-text=\"Delete\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      title=\"Are you sure you want to delete this key?\"\n      @confirm=\"deleteKV(selectedKV)\"\n    >\n      This action cannot be undone.\n    </ConfirmDialog>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/TeamSettings/Members/Invitations-Table.vue",
    "content": "<script>\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    ConfirmDialog\n  },\n  mixins: [formatTime],\n  props: {\n    permissionsCheck: {\n      type: Boolean,\n      required: true\n    },\n    // Number that updates every time pendingInvitations should be refetched\n    refetchSignal: {\n      type: Number,\n      required: true\n    },\n    // Mapping between role & role color\n    roleColorMap: {\n      type: Object,\n      required: true\n    },\n    // Mapping between role & displayed role text\n    roleMap: {\n      type: Object,\n      required: true\n    },\n    // Search input\n    search: {\n      type: String,\n      required: true\n    },\n    // Tenant information\n    tenant: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    return {\n      // Dialogs\n      dialogRevokeInvite: false,\n\n      // Table headers\n      headers: [\n        {\n          text: 'Email',\n          value: 'email',\n          align: 'left',\n          width: '30%'\n        },\n        {\n          text: 'Role',\n          value: 'role',\n          align: 'left',\n          width: '20%'\n        },\n        {\n          text: 'Sent',\n          value: 'created',\n          align: 'left',\n          width: '30%'\n        },\n        {\n          text: '',\n          value: 'action',\n          align: 'end',\n          sortable: false,\n          width: '20%'\n        }\n      ],\n\n      // Table items (populated by Apollo query)\n      pendingInvitationsItems: [],\n\n      // Loading states\n      isRevokingInvitation: false,\n      isFetchingInvitations: false,\n\n      // Selected user\n      // Set when invitation is being revoked\n      selectedUser: null\n    }\n  },\n  watch: {\n    refetchSignal() {\n      this.$apollo.queries.pendingInvitations.refetch()\n    }\n  },\n  methods: {\n    async revokeInvitation(membershipInvitationId) {\n      this.isRevokingInvitation = true\n\n      const res = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tenant/delete-membership-invitation.gql'),\n        variables: { membershipInvitationId }\n      })\n\n      if (res?.data?.delete_membership_invitation?.success) {\n        this.$emit('successful-action', 'The invitation has been revoked.')\n        this.$apollo.queries.pendingInvitations.refetch()\n      } else {\n        this.$emit(\n          'failed-action',\n          'Something went wrong when trying to revoke this membership. Please try again later.'\n        )\n      }\n\n      this.isRevokingInvitation = false\n      this.dialogRevokeInvite = false\n      this.selectedUser = null\n    }\n  },\n  apollo: {\n    pendingInvitations: {\n      query: require('@/graphql/Tenant/pending-invitations.gql'),\n      watchLoading(isLoading) {\n        this.isFetchingInvitations = isLoading\n      },\n      update(data) {\n        if (!data) return\n\n        // We filter this because we don't want to show invitations\n        // to other tenants, which are returned by this query\n        this.pendingInvitationsItems = data.pendingInvitations\n          .filter(pi => this.tenant.id == pi.tenant.id)\n          .map(invitation => {\n            return {\n              email: invitation.email,\n              membershipInvitationId: invitation.id,\n              role: invitation.role_detail.name,\n              pending: true,\n              created: invitation.created\n            }\n          })\n\n        this.$emit('load-end', this.pendingInvitationsItems)\n        return data\n      },\n      error() {\n        this.$emit(\n          'failed-action',\n          'Something went wrong while trying to fetch invitations. Please try again.'\n        )\n        this.$emit('load-end')\n      },\n      fetchPolicy: 'network-only',\n      skip() {\n        return !this.tenant\n      },\n      pollInterval: 15000\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-data-table\n      fixed-header\n      :headers=\"headers\"\n      :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n      :items=\"pendingInvitationsItems\"\n      :items-per-page=\"10\"\n      class=\"elevation-2 rounded-0 truncate-table\"\n      :footer-props=\"{\n        showFirstLastPage: true,\n        itemsPerPageOptions: [10, 15, 20, -1],\n        firstIcon: 'first_page',\n        lastIcon: 'last_page',\n        prevIcon: 'keyboard_arrow_left',\n        nextIcon: 'keyboard_arrow_right'\n      }\"\n      :search=\"search\"\n      no-results-text=\"No invitations found. Try expanding your search?\"\n      no-data-text=\"There are no pending membership invitations.\"\n    >\n      <!-- HEADERS -->\n      <template #header.email=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text }}</span>\n      </template>\n      <template #header.role=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text }}</span>\n      </template>\n      <template #header.created=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text }}</span>\n      </template>\n\n      <!-- INVITATION SENT TIMESTAMP -->\n      <template #item.created=\"{ item }\">\n        {{ formatDateTime(item.created) }}\n      </template>\n\n      <!-- ROLE -->\n      <template #item.role=\"{ item }\">\n        <v-chip\n          small\n          dark\n          :color=\"\n            !roleColorMap[item.role]\n              ? 'accentPink'\n              : roleColorMap[item.role] || 'secondaryLight'\n          \"\n        >\n          {{ roleMap[item.role] || item.role }}\n        </v-chip>\n      </template>\n\n      <!-- ACTIONS -->\n      <template v-if=\"permissionsCheck\" #item.action=\"{ item }\">\n        <v-tooltip bottom>\n          <template #activator=\"{ on }\">\n            <v-btn\n              text\n              fab\n              x-small\n              color=\"error\"\n              v-on=\"on\"\n              @click=\"\n                selectedUser = item\n                dialogRevokeInvite = true\n              \"\n            >\n              <v-icon>delete</v-icon>\n            </v-btn>\n          </template>\n          Revoke invitation\n        </v-tooltip>\n      </template>\n    </v-data-table>\n\n    <!-- REVOKE INVITATION DIALOG -->\n    <ConfirmDialog\n      v-if=\"selectedUser\"\n      v-model=\"dialogRevokeInvite\"\n      type=\"error\"\n      confirm-text=\"Revoke\"\n      :dialog-props=\"{ 'max-width': '660' }\"\n      :title=\"\n        `Are you sure you want to revoke ${selectedUser.email}'s\n            invitation to your team?`\n      \"\n      :disabled=\"isRevokingInvitation\"\n      :loading=\"isRevokingInvitation\"\n      @confirm=\"revokeInvitation(selectedUser.membershipInvitationId)\"\n    >\n      The user will no longer be able to accept this invitation and will need to\n      be reinvited to join the team.\n    </ConfirmDialog>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/TeamSettings/Members/Members-Table.vue",
    "content": "<script>\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    ConfirmDialog\n  },\n  props: {\n    // Number that updates every time tenantUsers should be refetched\n    refetchSignal: {\n      type: Number,\n      required: true\n    },\n    loading: {\n      type: Boolean,\n      required: false\n    },\n    // Mapping between role & role color\n    roleColorMap: {\n      type: Object,\n      required: true\n    },\n    // Mapping between role & displayed role text\n    roleMap: {\n      type: Object,\n      required: true\n    },\n    // Search input\n    search: {\n      type: String,\n      required: true\n    },\n    // Tenant information\n    tenant: {\n      type: Object,\n      required: true\n    },\n    // Current user information\n    user: {\n      type: Object,\n      required: true\n    },\n    roles: {\n      type: Array,\n      required: true\n    }\n  },\n  data() {\n    return {\n      // Dialogs\n      dialogModifyRole: false,\n      dialogRemoveUser: false,\n\n      // Table headers\n      allHeaders: [\n        {\n          mobile: false,\n          text: this.$vuetify.breakpoint.mdAndUp ? 'First Name' : 'First',\n          value: 'firstName',\n          align: 'left',\n          width: '15%'\n        },\n        {\n          mobile: false,\n          text: this.$vuetify.breakpoint.mdAndUp ? 'Last Name' : 'Last',\n          value: 'lastName',\n          align: 'left',\n          width: '15%'\n        },\n        {\n          mobile: true,\n          text: 'Email',\n          value: 'email',\n          width: '20%'\n        },\n        {\n          mobile: false,\n          text: 'Username',\n          value: 'username',\n          width: '20%'\n        },\n        {\n          mobile: true,\n          text: 'Role',\n          value: 'role',\n          align: 'left',\n          width: '20%'\n        },\n        {\n          mobile: true,\n          text: '',\n          value: 'actions',\n          align: 'end',\n          sortable: false,\n          width: '10%'\n        }\n      ],\n\n      // Table items (populated by Apollo query)\n      membersItems: [],\n\n      // Loading states\n      isFetchingMembers: false,\n      isRemovingUser: false,\n      isSettingRole: false,\n\n      // Inputs\n      roleInput: 'USER',\n\n      // Selected user\n      // Set when modifying a user's role or removing user membership\n      selectedUser: null\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['permissions', 'hasPermission']),\n    headers() {\n      return this.$vuetify.breakpoint.mdAndUp\n        ? this.allHeaders\n        : this.allHeaders.filter(header => header.mobile)\n    },\n    deleteSelfWarning() {\n      return this.user.email === this.selectedUser.email\n    }\n  },\n  watch: {\n    refetchSignal() {\n      this.$apollo.queries.tenantUsers.refetch()\n    }\n  },\n  methods: {\n    async removeUser(membershipId) {\n      this.isRemovingUser = true\n\n      const res = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tenant/delete-membership.gql'),\n        variables: { membershipId },\n        errorPolicy: 'all'\n      })\n\n      if (res?.data?.delete_membership?.success) {\n        this.$emit(\n          'successful-action',\n          'The user has been removed from your team.'\n        )\n        this.$apollo.queries.tenantUsers.refetch()\n      } else {\n        this.$emit(\n          'failed-action',\n          'Something went wrong while trying to remove this member from your team. Please try again.'\n        )\n      }\n\n      this.isRemovingUser = false\n      this.dialogRemoveUser = false\n      this.selectedUser = null\n    },\n    async updateRole(membership_id, role_id) {\n      this.isSettingRole = true\n      const res = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tenant/set-membership-role.gql'),\n        variables: { input: { membership_id, role_id } }\n      })\n\n      if (res?.data?.set_membership_role?.id) {\n        this.$emit('successful-action', \"The user's role has been updated\")\n        this.$apollo.queries.tenantUsers.refetch()\n      } else if (res?.errors) {\n        this.$emit('failed-action', res?.errors[0]?.message)\n      } else {\n        this.$emit(\n          'failed-action',\n          'Something went wrong while trying to update your role. Please try again.'\n        )\n      }\n      this.isSettingRole = false\n      this.dialogModifyRole = false\n      this.selectedUser = null\n    }\n  },\n  apollo: {\n    tenantUsers: {\n      query: require('@/graphql/Tenant/tenant-users.gql'),\n      watchLoading(isLoading) {\n        this.isFetchingMembers = isLoading\n      },\n      update(data) {\n        if (!data) return\n\n        this.membersItems = data.tenantUsers\n          .filter(user =>\n            user.memberships.find(mem => mem.tenant_id == this.tenant.id)\n          )\n          .filter(user => user.account_type === 'USER')\n          .map(user => {\n            let membership = user.memberships.find(\n              mem => mem.tenant_id == this.tenant.id\n            )\n            return {\n              id: user.id,\n              username: user.username,\n              email: user.email,\n              firstName: user.first_name,\n              lastName: user.last_name,\n              userId: user.id,\n              role: membership.role_detail.name,\n              membershipId: membership.id\n            }\n          })\n\n        this.$emit('load-end', this.membersItems)\n        return data\n      },\n      error() {\n        this.$emit(\n          'failed-action',\n          'Something went wrong while trying to fetch your team members. Please try again.'\n        )\n        this.$emit('load-end')\n      },\n      fetchPolicy: 'network-only',\n      skip() {\n        return !this.tenant\n      },\n      pollInterval: 15000\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-data-table\n      fixed-header\n      :headers=\"headers\"\n      :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n      :items=\"membersItems\"\n      :items-per-page=\"10\"\n      class=\"elevation-2 rounded-0 truncate-table\"\n      :footer-props=\"{\n        showFirstLastPage: true,\n        itemsPerPageOptions: [10, 15, 20, -1],\n        firstIcon: 'first_page',\n        lastIcon: 'last_page',\n        prevIcon: 'keyboard_arrow_left',\n        nextIcon: 'keyboard_arrow_right'\n      }\"\n      :loading=\"loading\"\n      :search=\"search\"\n      no-results-text=\"No members found. Try expanding your search?\"\n      no-data-text=\"This team does not have any members yet.\"\n    >\n      <!-- HEADERS -->\n      <template #header.email=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text }}</span>\n      </template>\n      <template #header.username=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text }}</span>\n      </template>\n      <template #header.firstName=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text }}</span>\n      </template>\n      <template #header.lastName=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text }}</span>\n      </template>\n      <template #header.role=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text }}</span>\n      </template>\n\n      <!-- ROLE -->\n      <template #item.role=\"{ item }\">\n        <v-chip\n          small\n          dark\n          :color=\"\n            !roleColorMap[item.role]\n              ? 'accentPink'\n              : roleColorMap[item.role] || 'secondaryLight'\n          \"\n        >\n          {{ roleMap[item.role] || item.role }}\n        </v-chip>\n      </template>\n\n      <!-- ACTIONS -->\n      <template #item.actions=\"{ item }\">\n        <v-tooltip\n          v-if=\"\n            hasPermission('update', 'membership') &&\n              hasPermission('feature', 'basic-rbac')\n          \"\n          bottom\n        >\n          <template #activator=\"{ on }\">\n            <v-btn\n              text\n              fab\n              x-small\n              color=\"primary\"\n              v-on=\"on\"\n              @click=\"\n                selectedUser = item\n                roleInput = selectedUser.role\n                dialogModifyRole = true\n              \"\n            >\n              <v-icon>edit</v-icon>\n            </v-btn>\n          </template>\n          Modify this user's role\n        </v-tooltip>\n        <v-tooltip v-if=\"hasPermission('delete', 'membership')\" bottom>\n          <template #activator=\"{ on }\">\n            <v-btn\n              text\n              fab\n              x-small\n              color=\"error\"\n              v-on=\"on\"\n              @click=\"\n                selectedUser = item\n                dialogRemoveUser = true\n              \"\n            >\n              <v-icon>delete</v-icon>\n            </v-btn>\n          </template>\n          Remove user\n        </v-tooltip>\n      </template>\n    </v-data-table>\n\n    <!-- MODIFY USER ROLE DIALOG -->\n    <ConfirmDialog\n      v-if=\"selectedUser\"\n      v-model=\"dialogModifyRole\"\n      :dialog-props=\"{ 'max-width': '600' }\"\n      :title=\"`Modify ${selectedUser.email}'s role`\"\n      :disabled=\"isSettingRole\"\n      :loading=\"isSettingRole\"\n      confirm-text=\"Save\"\n      @cancel=\"roleInput = 'USER'\"\n      @confirm=\"updateRole(selectedUser.membershipId, roleInput)\"\n    >\n      <v-select\n        data-public\n        v-model=\"roleInput\"\n        class=\"mt-6\"\n        outlined\n        dense\n        autofocus\n        label=\"Role\"\n        :color=\"roleColorMap[roleInput]\"\n        prepend-icon=\"supervised_user_circle\"\n        :items=\"roles\"\n        item-text=\"name\"\n        item-value=\"id\"\n      >\n        <template #item=\"{item}\">\n          {{ roleMap[item.name] ? roleMap[item.name] : item.name }}\n        </template>\n        <template #selection=\"{item}\">\n          {{ roleMap[item.name] ? roleMap[item.name] : item.name }}\n        </template>\n      </v-select>\n    </ConfirmDialog>\n\n    <!-- DELETE USER DIALOG -->\n    <ConfirmDialog\n      v-if=\"selectedUser\"\n      v-model=\"dialogRemoveUser\"\n      type=\"error\"\n      :title=\"\n        deleteSelfWarning\n          ? `Are you sure you want to remove yourself from ${tenant.name}?`\n          : `Are you sure you want to remove ${selectedUser.email} from your team?`\n      \"\n      :dialog-props=\"{ 'max-width': '600' }\"\n      :disabled=\"isRemovingUser\"\n      :loading=\"isRemovingUser\"\n      @confirm=\"removeUser(selectedUser.membershipId)\"\n    >\n      <div v-if=\"deleteSelfWarning\" class=\"red--text\"\n        >Are you sure you want to remove yourself from {{ tenant.name }}? You'll\n        no longer be able to access your run data associated with\n        {{ tenant.name }}.\n      </div>\n      <div v-else>\n        <span class=\"font-weight-bold\">{{ selectedUser.username }}</span>\n        will no longer be able to access your team account.</div\n      >\n    </ConfirmDialog>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/TeamSettings/Members.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\n\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport InvitationsTable from '@/pages/TeamSettings/Members/Invitations-Table'\nimport ManagementLayout from '@/layouts/ManagementLayout'\nimport MembersTable from '@/pages/TeamSettings/Members/Members-Table'\nimport { EMAIL_REGEX } from '@/utils/regEx'\nimport { ROLE_MAP, ROLE_COLOR_MAP } from '@/utils/roles.js'\n\nimport ExternalLink from '@/components/ExternalLink.vue'\n\nexport default {\n  components: {\n    ConfirmDialog,\n    ExternalLink,\n    InvitationsTable,\n    ManagementLayout,\n    MembersTable\n  },\n  data() {\n    return {\n      users: 0,\n      invitations: 0,\n      // Current tab\n      tab: 'members',\n\n      // Alert data\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n\n      // Dialogs\n      dialogInviteUser: false,\n\n      // Inputs\n      inviteEmailInput: null,\n      roleInput: null,\n      searchInput: '',\n\n      // Forms\n      inviteFormValid: true,\n\n      inviteError: null,\n      fullUsers: null,\n      fullInvitations: null,\n      readOnlyInvitations: null,\n      readOnlyUsers: null,\n\n      // Input rules\n      rules: {\n        email: value =>\n          EMAIL_REGEX.test(value) || 'Please enter a valid email address.',\n        required: value => !!value || 'This field is is required.'\n      },\n\n      // Loading states\n      isInvitingUser: false,\n      isLoadingMembersTable: true,\n\n      // Signal passed as prop to MembersTable\n      // MembersTable watches this data attribute & refetches members every time this value changes.\n      membersSignal: 0,\n\n      // Signal passed as prop to InvitationsTable\n      // InvitationsTable watches this data attribute & refetches invites every time this value changes.\n      inviteSignal: 0,\n\n      // Role maps\n      roleMap: ROLE_MAP,\n      roleColorMap: ROLE_COLOR_MAP\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['user']),\n    ...mapGetters('license', [\n      'license',\n      'hasPermission',\n      'allowedUsers',\n      'planType'\n    ]),\n    canUpgradeUsers() {\n      return this.planType('FREE') || this.planType('STARTER')\n    },\n    totalAllowedUsers() {\n      return this.allowedUsers() ?? Infinity\n    },\n    insufficientUsers() {\n      return this.users >= this.totalAllowedUsers\n    },\n    permissionsCheck() {\n      return (\n        this.hasPermission('create', 'membership') &&\n        this.hasPermission('update', 'membership') &&\n        this.hasPermission('delete', 'membership') &&\n        this.hasPermission('feature', 'basic-rbac')\n      )\n    },\n    roleSelectionMap() {\n      return [\n        {\n          role: 'TENANT_ADMIN',\n          label: 'Administrator',\n          color: 'cloudUIPrimaryBlue'\n        },\n        {\n          role: 'USER',\n          label: 'User',\n          color: 'codeBlueBright'\n        },\n        {\n          role: 'READ_ONLY_USER',\n          label: 'Read-Only',\n          color: 'cloudUIPrimaryDark'\n        }\n      ]\n    },\n    totalUsers() {\n      return this.users + this.invitations\n    },\n    filteredRoles() {\n      if (!this.roles) return []\n      let rolesToRM = ['RUNNER']\n      if (!this.hasPermission('license', 'admin')) {\n        rolesToRM = ['ENTERPRISE_LICENSE_ADMIN', 'RUNNER']\n      }\n      return this.roles.filter(role => !rolesToRM.includes(role.name))\n    }\n  },\n  watch: {\n    tenant() {\n      this.membersSignal++\n      this.inviteSignal++\n    }\n  },\n  mounted() {\n    // Hacky fix for a bizarre bug where the tab slider doesn't show up on mount.\n    setTimeout(() => {\n      // Get the width of a tab.\n      const tabWidth = document.getElementsByClassName('v-tab')[0].offsetWidth\n\n      // The tab slider doesn't render because it's width is set at 0.\n      // To fix this, set the slider's width equal to the tab width.\n      document.getElementsByClassName(\n        'v-tabs-slider-wrapper'\n      )[0].style.width = `${tabWidth}px`\n\n      // Bonus - this creates an animation for the slider on mount, so that's pretty nice.\n    }, 400)\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    handleInviteDialog() {\n      this.roleInput = this.roles?.find(r => r.name == 'USER').id\n      this.dialogInviteUser = true\n    },\n    handleAlert(type, message) {\n      this.setAlert({\n        alertShow: true,\n        alertMessage: message,\n        alertType: type\n      })\n    },\n    handleUpdateInvitations(event) {\n      if (event) {\n        this.invitations = event.length\n      }\n    },\n    handleUpdateUsers(event) {\n      this.isLoadingMembersTable = false\n      if (event) {\n        this.users = event.length\n      }\n    },\n    async inviteUser() {\n      this.isInvitingUser = true\n      this.inviteError = null\n      const res = await this.$apollo\n        .mutate({\n          mutation: require('@/graphql/Tenant/create-membership-invitation.gql'),\n          variables: {\n            input: {\n              email: this.inviteEmailInput,\n              role_id: this.roleInput\n            }\n          },\n          errorPolicy: 'all'\n        })\n        .catch(({ graphQLErrors }) => {\n          let error\n          switch (graphQLErrors[0].message) {\n            case 'This tenant already has the maximum number of users.':\n              this.inviteError =\n                'Your team already has the maximum number of users.'\n              if (this.readOnlyInvitations > 0 || this.fullInvitations > 0)\n                this.tab = 'pending'\n              break\n            case 'This tenant already has the maximum number of read-only users.':\n              this.inviteError =\n                'Your team already has the maximum number of read-only users.'\n              if (this.readOnlyInvitations > 0 || this.fullInvitations > 0)\n                this.tab = 'pending'\n              break\n            case `A user with email \"${this.inviteEmailInput}\" has already been invited to tenant ${this.tenant.id}.`:\n              this.inviteError = 'This user has already been invited.'\n              break\n          }\n          return { error: error }\n        })\n\n      if (res?.data?.create_membership_invitation?.id) {\n        //this text is part of the onboard E2E test - please update test if you change\n        this.handleAlert('success', 'Your invitation has been sent!')\n        this.inviteSignal++\n        this.dialogInviteUser = false\n        this.inviteEmailInput = null\n        this.roleInput = this.roles.find(r => r.name == 'USER').id\n        this.tab = 'pending'\n      } else if (res?.errors) {\n        this.handleAlert('error', res?.errors[0]?.message)\n        this.dialogInviteUser = false\n        this.inviteEmailInput = null\n        this.roleInput = this.roles.find(r => r.name == 'USER').id\n      }\n      this.isInvitingUser = false\n    },\n    resetInviteUserDialog() {\n      this.$refs['invite-user-form'].reset()\n      this.$nextTick(() => {\n        this.inviteEmailInput = null\n        this.inviteError = null\n        this.roleInput = this.roles.find(r => r.name == 'USER').id\n      })\n    }\n  },\n  apollo: {\n    roles: {\n      query: require('@/graphql/TeamSettings/roles.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {}\n      },\n      pollInterval: 10000,\n      update(data) {\n        if (!data) return\n        return data.auth_role\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout>\n    <template #title>Team Members</template>\n\n    <template #subtitle>\n      <span v-if=\"permissionsCheck\">\n        View your team's members, manage permissions, and send invitations\n      </span>\n      <span v-else data-cy=\"non-admin-message\">\n        View the other members of {{ tenant.name }}\n      </span>\n    </template>\n\n    <template v-if=\"hasPermission('create', 'membership-invitation')\" #cta>\n      <v-btn\n        :disabled=\"insufficientUsers || !roles\"\n        color=\"primary\"\n        class=\"white--text\"\n        large\n        data-cy=\"invite-member\"\n        @click=\"handleInviteDialog\"\n      >\n        <v-icon left>\n          person_add\n        </v-icon>\n        Invite\n      </v-btn>\n    </template>\n\n    <template v-if=\"insufficientUsers\" #alerts>\n      <v-alert\n        class=\"mx-auto\"\n        border=\"left\"\n        colored-border\n        elevation=\"2\"\n        type=\"warning\"\n        tile\n        icon=\"lock\"\n        max-width=\"600\"\n      >\n        <p v-if=\"canUpgradeUsers\">\n          Your team has no users available;\n          <router-link :to=\"'/plans'\">upgrade your plan</router-link> to get\n          more users and access to more features!\n        </p>\n        <p v-else>\n          Your team has no users available. Contact sales@prefect.io to add\n          more.\n        </p>\n      </v-alert>\n    </template>\n\n    <v-text-field\n      v-if=\"!$vuetify.breakpoint.mdAndUp\"\n      v-model=\"searchInput\"\n      class=\"rounded-0 elevation-1 mb-1\"\n      solo\n      dense\n      hide-details\n      single-line\n      placeholder=\"Search by name or email\"\n      prepend-inner-icon=\"search\"\n      autocomplete=\"new-password\"\n    ></v-text-field>\n    <v-tabs\n      v-model=\"tab\"\n      class=\"elevation-2\"\n      :grow=\"!$vuetify.breakpoint.mdAndUp\"\n    >\n      <!-- DESKTOP TABS -->\n      <template v-if=\"$vuetify.breakpoint.mdAndUp\">\n        <v-tab\n          href=\"#members\"\n          :style=\"{\n            'min-width': '160px'\n          }\"\n        >\n          <v-icon class=\"mr-2\">people</v-icon>\n          Users\n        </v-tab>\n        <v-tab\n          href=\"#pending\"\n          :style=\"{\n            'min-width': '160px'\n          }\"\n        >\n          <v-badge\n            bordered\n            color=\"codePink\"\n            :content=\"readOnlyInvitations + fullInvitations\"\n            :value=\"readOnlyInvitations + fullInvitations\"\n            left\n            offset-x=\"10\"\n            offset-y=\"10\"\n            top\n            overlap\n          >\n            <v-icon class=\"mr-2\">mail</v-icon>\n          </v-badge>\n          Invitations\n        </v-tab>\n        <v-spacer></v-spacer>\n        <v-text-field\n          v-model=\"searchInput\"\n          class=\"rounded-0 mt-1 mr-2\"\n          solo\n          dense\n          hide-details\n          single-line\n          placeholder=\"Search by name or email\"\n          prepend-inner-icon=\"search\"\n          autocomplete=\"new-password\"\n          :style=\"{\n            'max-width': '360px'\n          }\"\n        ></v-text-field>\n      </template>\n\n      <!-- MOBILE/TABLET STYLES -->\n      <template v-else>\n        <v-tab href=\"#members\">\n          <v-icon class=\"mr-2\">people</v-icon>\n          Users\n        </v-tab>\n        <v-tab href=\"#pending\">\n          <v-badge\n            bordered\n            color=\"codePink\"\n            :content=\"readOnlyInvitations + fullInvitations\"\n            :value=\"readOnlyInvitations + fullInvitations\"\n            left\n            offset-x=\"10\"\n            offset-y=\"10\"\n            top\n            overlap\n          >\n            <v-icon class=\"mr-2\">mail</v-icon>\n            Invitations\n          </v-badge>\n        </v-tab>\n      </template>\n\n      <!-- MEMBERS TABLE -->\n      <v-tab-item value=\"members\">\n        <MembersTable\n          :role-color-map=\"roleColorMap\"\n          :role-map=\"roleMap\"\n          :roles=\"filteredRoles\"\n          :search=\"searchInput\"\n          :tenant=\"tenant\"\n          :user=\"user\"\n          :loading=\"isLoadingMembersTable\"\n          :refetch-signal=\"membersSignal\"\n          @load-end=\"handleUpdateUsers($event)\"\n          @successful-action=\"handleAlert('success', $event)\"\n          @failed-action=\"handleAlert('error', $event)\"\n        ></MembersTable>\n      </v-tab-item>\n\n      <!-- PENDING INVITATIONS TABLE -->\n      <v-tab-item value=\"pending\" eager>\n        <InvitationsTable\n          :permissions-check=\"hasPermission('delete', 'membership-invitation')\"\n          :role-color-map=\"roleColorMap\"\n          :role-map=\"roleMap\"\n          :search=\"searchInput\"\n          :tenant=\"tenant\"\n          :user=\"user\"\n          :refetch-signal=\"inviteSignal\"\n          @successful-action=\"handleAlert('success', $event)\"\n          @failed-action=\"handleAlert('error', $event)\"\n          @load-end=\"handleUpdateInvitations($event)\"\n        ></InvitationsTable>\n      </v-tab-item>\n    </v-tabs>\n\n    <!-- INVITE DIALOG -->\n    <ConfirmDialog\n      v-model=\"dialogInviteUser\"\n      title=\"Invite a new team member\"\n      confirm-text=\"Send\"\n      :error=\"inviteError\"\n      :loading=\"isInvitingUser\"\n      :disabled=\"\n        totalUsers >= totalAllowedUsers || !inviteFormValid || isInvitingUser\n      \"\n      :dialog-props=\"{\n        'max-width': '600'\n      }\"\n      @cancel=\"resetInviteUserDialog\"\n      @confirm=\"inviteUser\"\n    >\n      <v-form ref=\"invite-user-form\" v-model=\"inviteFormValid\">\n        <v-alert\n          v-if=\"totalUsers >= totalAllowedUsers\"\n          class=\"mx-auto my-4 mb-12\"\n          border=\"left\"\n          colored-border\n          elevation=\"2\"\n          type=\"warning\"\n          tile\n          icon=\"warning\"\n        >\n          <p>\n            Your team has no users available;\n            <router-link :to=\"'/plans'\">upgrade your plan</router-link> to get\n            more users and access to more features!\n          </p>\n        </v-alert>\n\n        <v-text-field\n          v-model=\"inviteEmailInput\"\n          class=\"mb-3\"\n          autofocus\n          label=\"Email\"\n          data-cy=\"invite-email\"\n          prepend-icon=\"alternate_email\"\n          outlined\n          autocomplete=\"new-password\"\n          :rules=\"[rules.required, rules.email]\"\n          validate-on-blur\n        />\n        <v-select\n          data-public\n          v-model=\"roleInput\"\n          outlined\n          :menu-props=\"{ offsetY: true }\"\n          label=\"Role\"\n          data-cy=\"invite-role\"\n          :disabled=\"!hasPermission('feature', 'basic-rbac')\"\n          prepend-icon=\"supervised_user_circle\"\n          :color=\"roleColorMap[roleInput]\"\n          :items=\"filteredRoles\"\n          :rules=\"[rules.required]\"\n          item-text=\"name\"\n          item-value=\"id\"\n          item-disabled=\"disabled\"\n        >\n          <template #item=\"{item}\">\n            {{ roleMap[item.name] ? roleMap[item.name] : item.name }}\n          </template>\n          <template #selection=\"{item}\">\n            {{ roleMap[item.name] ? roleMap[item.name] : item.name }}\n          </template>\n        </v-select>\n        <div\n          v-if=\"!hasPermission('feature', 'basic-rbac')\"\n          class=\"text-caption\"\n        >\n          Looking for role-based access controls? This feature is available on\n          Standard plans; check out our\n          <ExternalLink href=\"https://prefect.io/pricing\"\n            >pricing page</ExternalLink\n          >\n          for more details.\n        </div>\n        <div\n          v-else-if=\"!hasPermission('feature', 'custom-role')\"\n          class=\"text-caption\"\n        >\n          Looking for custom role-based access controls? This feature is only\n          available on Enterprise plans; check out our\n          <ExternalLink href=\"https://prefect.io/pricing\"\n            >pricing page</ExternalLink\n          >\n          for more details.\n        </div>\n      </v-form>\n    </ConfirmDialog>\n  </ManagementLayout>\n</template>\n"
  },
  {
    "path": "src/pages/TeamSettings/PlanComparison.vue",
    "content": "<script>\nimport ManagementLayout from '@/layouts/ManagementLayout'\nimport PlanCard from '@/components/PlanCard'\nimport ChangePlanDialog from '@/components/License/ChangePlanDialog'\nimport { PLANS_2021 } from '@/utils/plans'\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    ManagementLayout,\n    PlanCard,\n    ChangePlanDialog\n  },\n  data() {\n    return {\n      plans: Object.values(PLANS_2021),\n      selected: 0,\n      basicFeatures: {\n        a: {\n          name: 'Robust Scheduling',\n          description:\n            'Create custom schedules including business days, offsets, and blackout windows, or fall back on good old cron.'\n        },\n        b: {\n          name: 'Intelligent Scheduling',\n          description:\n            'Schedule varying parameter values or even where your runs should occur'\n        },\n        c: {\n          name: 'Artifacts',\n          description: 'Publish custom data and render it in the Prefect UI'\n        },\n        d: {\n          name: 'Mapping',\n          description: 'Dynamically generate parallel pipelines at runtime'\n        },\n        e: {\n          name: 'Retries',\n          description:\n            'Advanced checkpointing and real-time state reporting protect you from the unexpected'\n        },\n        f: {\n          name: 'Run History',\n          description:\n            'Use the Prefect UI to manage all of your flow runs, no matter how often or where they run'\n        },\n        g: {\n          name: 'Dataflow Automation',\n          description:\n            'Pass data between tasks for complex processing and advanced analytics'\n        },\n        h: {\n          name: 'Caching',\n          description:\n            'Persist the results of complex tasks with custom validation logic'\n        },\n        i: {\n          name: 'Versioning',\n          description:\n            \"Every Prefect flow is automatically versioned, so you're always up-to-date\"\n        }\n      },\n      infrastructureFeatures: {\n        a: {\n          name: 'Hosted Orchestration Platform',\n          description:\n            'Focus on your code while Prefect Cloud manages a highly-available orchestration API',\n          plan: 'good'\n        },\n        b: {\n          name: 'Performance',\n          description:\n            'Run tasks as fast as your internet connection allows for',\n          plan: 'good'\n        },\n        c: {\n          name: 'API Security',\n          description: 'Permission access via API tokens',\n          plan: 'good'\n        },\n        d: {\n          name: 'Automatic Updates',\n          description:\n            'Prefect Cloud releases every two weeks with new features and performance enhancements',\n          plan: 'good'\n        },\n        e: {\n          name: 'Raise Rate Limits',\n          description: 'TK',\n          plan: 'best'\n        }\n      },\n      observabilityFeatures: {\n        a: {\n          name: 'Log Management',\n          description: 'Stream, filter, and examine all of your workflow logs',\n          plan: 'good'\n        },\n        b: {\n          name: 'Advanced Alerting',\n          description: 'Configure notifications when custom criteria are met',\n          plan: 'better'\n        },\n        c: {\n          name: 'Flow SLAs',\n          description: 'Set SLAs for late or long-running workflows',\n          plan: 'better'\n        },\n        d: {\n          name: 'Agent SLAs',\n          description: 'Set SLAs for agents to ensure uptime',\n          plan: 'better'\n        },\n        e: {\n          name: 'History Retention',\n          description: 'Track one year of run history',\n          plan: 'best'\n        },\n        f: {\n          name: 'Audit Trail',\n          description: 'Track every action taken via the Prefect API',\n          plan: 'best'\n        }\n      },\n      orchestrationFeatures: {\n        a: {\n          name: 'Stateless Deployments',\n          description:\n            'Spin up and tear down agent deployments with ease - Prefect Cloud manages all state for you',\n          plan: 'good'\n        },\n        b: {\n          name: 'Multiple Execution Environments',\n          description:\n            'Promote your workflows from dev to prod with a single API call, or schedule them to run in multiple places at once!',\n          plan: 'good'\n        },\n        c: {\n          name: 'Secrets',\n          description: 'Manage sensitive information',\n          plan: 'good'\n        },\n        d: {\n          name: 'Advanced Automation',\n          description:\n            'Automatically configure API actions when custom criteria are met',\n          plan: 'better'\n        },\n        e: {\n          name: 'Concurrency Limits',\n          description:\n            'Set concurrency limits at the flow or task level to control access to resources',\n          plan: 'better'\n        }\n      },\n      authorizationFeatures: {\n        a: {\n          name: 'Team Management',\n          description:\n            'Get a complete view of everyone who can access your workflows',\n          plan: 'good'\n        },\n        b: {\n          name: 'Read-Only Users',\n          description:\n            'Invite analyts to work with the output of your workflows',\n          plan: 'better'\n        },\n        c: {\n          name: 'RBAC',\n          description: 'Assign roles to users to control access',\n          plan: 'best'\n        },\n        d: {\n          name: 'Custom Permissions',\n          description:\n            'Assign granular permissions, including per-project limits',\n          plan: 'best'\n        },\n        e: {\n          name: 'SSO',\n          description: 'Log in to Prefect Cloud via SSO',\n          plan: 'best'\n        },\n        f: {\n          name: 'Custom Roles',\n          description: 'Create and assign custom roles',\n          plan: 'best'\n        }\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['license', 'tempLicenseType']),\n    ...mapGetters('tenant', ['tenant']),\n    planType() {\n      return this.plans[this.selected]\n    }\n  },\n  created() {\n    //creates a non-reactive property that isn't tracked by Vue - so that selected doesn't reset\n    const name =\n      this.license?.terms.plan === 'STARTER_2021'\n        ? 'FREE_2021'\n        : this.license?.terms?.plan\n    const plan = this.plans.findIndex(planType => planType.value === name)\n    this.selected = plan\n  },\n  methods: {\n    excluded(feature) {\n      if (\n        this.planType?.title === 'good' &&\n        (feature.plan === 'better' || feature.plan === 'best')\n      ) {\n        return true\n      } else if (this.planType?.title === 'better' && feature.plan === 'best') {\n        return true\n      } else {\n        return false\n      }\n    },\n    updatePlan(type) {\n      const index = this.plans.findIndex(planType => planType.value === type)\n      this.selected = index\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout>\n    <template #title>Prefect Plans</template>\n\n    <div\n      style=\"display: flex;\n            flex-direction: row;\n            justify-content: center;\"\n      class=\"py-8\"\n    >\n      <v-item-group v-model=\"selected\" mandatory>\n        <v-row>\n          <v-col\n            v-for=\"(plan, i) in plans\"\n            :key=\"i\"\n            cols=\"12\"\n            md=\"4\"\n            class=\"pa-0\"\n          >\n            <v-item v-slot=\"{ active, toggle }\">\n              <div @click=\"toggle\">\n                <PlanCard\n                  :plan=\"plan.title\"\n                  :selected=\"active\"\n                  :class=\"\n                    Math.abs(selected - i) > 1\n                      ? 'away elevation-0'\n                      : Math.abs(selected - i) === 1\n                      ? 'adjacent elevation-2'\n                      : 'active elevation-4'\n                  \"\n                />\n              </div>\n            </v-item>\n          </v-col>\n        </v-row>\n      </v-item-group>\n    </div>\n    <div class=\"text-center pb-8\">\n      <v-btn\n        v-if=\"selected === 2\"\n        color=\"primary\"\n        href=\"https://www.prefect.io/pricing#contact\"\n        target=\"_blank\"\n      >\n        Contact Us\n      </v-btn>\n      <ChangePlanDialog v-else :plan=\"planType\" @update=\"updatePlan\" />\n    </div>\n\n    <v-card class=\"pa-6 mb-8\">\n      <h3 class=\"py-2\">All plans come with:</h3>\n      <ul\n        style=\"column-count: 2;\n    column-gap: 40px;\n    list-style-type: none;\"\n      >\n        <li\n          v-for=\"(feature, i) in basicFeatures\"\n          :key=\"i\"\n          style=\"flex-direction: column;\"\n        >\n          <p class=\"feature-title\">{{ feature.name }}</p>\n          <p class=\"subtitle\">{{ feature.description }}</p>\n        </li>\n      </ul>\n    </v-card>\n\n    <h2 class=\"pt-4\">Additionally, this plan includes:</h2>\n\n    <div\n      class=\"pt-4 pb-8\"\n      style=\"display: flex;\n    flex-direction: row;\"\n      :style=\"\n        $vuetify.breakpoint.lgAndDown\n          ? { width: 'auto', flexWrap: 'wrap' }\n          : { width: '100%' }\n      \"\n    >\n      <v-card\n        :style=\"\n          $vuetify.breakpoint.lgAndDown\n            ? { flexBasis: '50%' }\n            : { flexBasis: '25%' }\n        \"\n        class=\"pa-4 mb-8\"\n      >\n        <h3 class=\"py-2\">Infrastructure</h3>\n        <ul style=\"list-style-type: none;\">\n          <li v-for=\"(feature, i) in infrastructureFeatures\" :key=\"i\">\n            <p\n              class=\"feature-title\"\n              :class=\"{ 'text--disabled': excluded(feature) }\"\n              >{{ feature.name }}</p\n            >\n            <p\n              class=\"subtitle\"\n              :class=\"{ 'text--disabled': excluded(feature) }\"\n              >{{ feature.description }}</p\n            >\n          </li>\n        </ul>\n      </v-card>\n      <v-card\n        :style=\"\n          $vuetify.breakpoint.lgAndDown\n            ? { flexBasis: '50%' }\n            : { flexBasis: '25%' }\n        \"\n        class=\"pa-4 mb-8\"\n      >\n        <h3 class=\"py-2\">Observability</h3>\n        <ul style=\"list-style-type: none;\">\n          <li v-for=\"(feature, i) in observabilityFeatures\" :key=\"i\">\n            <p\n              class=\"feature-title\"\n              :class=\"{ 'text--disabled': excluded(feature) }\"\n              >{{ feature.name }}</p\n            >\n            <p\n              class=\"subtitle\"\n              :class=\"{ 'text--disabled': excluded(feature) }\"\n              >{{ feature.description }}</p\n            >\n          </li>\n        </ul>\n      </v-card>\n      <v-card\n        :style=\"\n          $vuetify.breakpoint.lgAndDown\n            ? { flexBasis: '50%' }\n            : { flexBasis: '25%' }\n        \"\n        class=\"pa-4 mb-8\"\n      >\n        <h3 class=\"py-2\">Orchestration</h3>\n        <ul style=\"list-style-type: none;\">\n          <li v-for=\"(feature, i) in orchestrationFeatures\" :key=\"i\">\n            <p\n              class=\"feature-title\"\n              :class=\"{ 'text--disabled': excluded(feature) }\"\n              >{{ feature.name }}</p\n            >\n            <p\n              class=\"subtitle\"\n              :class=\"{ 'text--disabled': excluded(feature) }\"\n              >{{ feature.description }}</p\n            >\n          </li>\n        </ul>\n      </v-card>\n      <v-card\n        :style=\"\n          $vuetify.breakpoint.lgAndDown\n            ? { flexBasis: '50%' }\n            : { flexBasis: '25%' }\n        \"\n        class=\"pa-4 mb-8\"\n      >\n        <h3 class=\"py-2\">Authorization</h3>\n        <ul style=\"list-style-type: none;\">\n          <li v-for=\"(feature, i) in authorizationFeatures\" :key=\"i\">\n            <p\n              class=\"feature-title\"\n              :class=\"{ 'text--disabled': excluded(feature) }\"\n              >{{ feature.name }}</p\n            >\n            <p\n              class=\"subtitle\"\n              :class=\"{ 'text--disabled': excluded(feature) }\"\n              >{{ feature.description }}</p\n            >\n          </li>\n        </ul>\n      </v-card>\n    </div>\n    <div class=\"text-center pb-4\">\n      <v-btn\n        v-if=\"selected === 2\"\n        color=\"primary\"\n        href=\"https://www.prefect.io/pricing#contact\"\n        target=\"_blank\"\n      >\n        Contact Us\n      </v-btn>\n      <ChangePlanDialog v-else :plan=\"planType\" />\n    </div>\n  </ManagementLayout>\n</template>\n\n<style scoped>\n@keyframes adjacent {\n  100% {\n    filter: contrast(65%);\n    transform: scale(0.9);\n  }\n}\n\n@keyframes away {\n  100% {\n    filter: contrast(35%);\n    transform: scale(0.8);\n  }\n}\n\n@keyframes active {\n  100% {\n    filter: contrast(100%);\n    transform: scale(1);\n  }\n}\n\n.active {\n  animation: active 1s forwards;\n}\n\n.adjacent {\n  animation: adjacent 1s forwards;\n}\n\n.away {\n  animation: away 1s forwards;\n}\n\n.feature-title {\n  font-size: 1rem;\n  font-weight: 500;\n  line-height: 1.5rem;\n  margin-bottom: 4px;\n  text-align: left;\n}\n\n.subtitle {\n  color: #444;\n  font-size: 0.875rem;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/Projects.vue",
    "content": "<script>\nimport gql from 'graphql-tag'\nimport LogRocket from 'logrocket'\nimport { mapGetters } from 'vuex'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport Alert from '@/components/Alert'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ExternalLink from '@/components/ExternalLink'\nimport ManagementLayout from '@/layouts/ManagementLayout'\nexport default {\n  components: {\n    Alert,\n    ConfirmDialog,\n    ExternalLink,\n    ManagementLayout\n  },\n  mixins: [formatTime],\n  data() {\n    return {\n      // Alert data\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n\n      // Loading states\n      isLoadingTable: true,\n      isCreatingProject: false,\n      isModifyingProject: false,\n      isRemovingProject: false,\n\n      // Dialogs\n      dialogCreateProject: false,\n      dialogModifyProject: false,\n      dialogRemoveProject: false,\n\n      // Store copied project ID\n      // Useful to render feedback that copy was successful\n      copiedProjectId: null,\n\n      // Timeout for copy action\n      copyTimeout: null,\n\n      // Table headers\n      headers: [\n        {\n          mobile: true,\n          text: 'Name',\n          value: 'name',\n          width: '25%'\n        },\n        {\n          mobile: true,\n          text: 'Description',\n          value: 'description',\n          align: 'left',\n          width: '25%'\n        },\n        {\n          mobile: true,\n          text: 'Flows',\n          value: 'active_flow_count.aggregate.count',\n          align: 'left',\n          width: '10%'\n        },\n        {\n          mobile: false,\n          text: 'Created',\n          value: 'created',\n          align: 'left',\n          width: '15%'\n        },\n        {\n          mobile: false,\n          text: 'Project ID',\n          value: 'id',\n          align: 'center',\n          width: '10%'\n        },\n        {\n          mobile: true,\n          text: '',\n          value: 'actions',\n          align: 'end',\n          sortable: false,\n          width: '10%'\n        }\n      ],\n\n      // Forms\n      createFormValid: true,\n      modifyFormValid: true,\n\n      // Inputs\n      searchInput: null,\n      moveToProjectInput: null,\n      projectNameInput: null,\n      projectDescriptionInput: null,\n\n      // Input error messages\n      projectNameErrors: [],\n\n      // Input icons\n      showNameInputIcon: false,\n\n      // Project selected for modification or deletion\n      selectedProject: null,\n\n      // default sorting\n      sortBy: 'name',\n      sortDesc: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['user', 'timezone']),\n    ...mapGetters('license', ['hasPermission']),\n    // Surface table headers based on viewport (mobile vs. desktop)\n    headersByViewport() {\n      return this.$vuetify.breakpoint.mdAndUp\n        ? this.headers\n        : this.headers.filter(header => header.mobile)\n    },\n    permissionsCheck() {\n      return (\n        this.hasPermission('create', 'project') &&\n        this.hasPermission('update', 'project') &&\n        this.hasPermission('delete', 'project')\n      )\n    },\n    // If the user decides to move flows to a new project before deletion,\n    // provide a list of candidate projects to take these flows\n    moveToProjectDropdownItems() {\n      if (!this.projects) return []\n\n      return (\n        this.projects\n          // Exclude the currently-selected project\n          .filter(project => {\n            if (!this.selectedProject) return true\n            return this.selectedProject.id !== project.id\n          })\n          // Transform into objects with properties \"text\" and \"value\",\n          // as required by v-autocomplete.\n          .map(project => ({\n            text: project.name,\n            value: Object.assign({}, project)\n          }))\n          // Sort alphabetically\n          .sort((p1, p2) =>\n            p1.text.toLowerCase() < p2.text.toLowerCase() ? -1 : 1\n          )\n      )\n    },\n    // Dynamic mutation to move flows to a new project\n    moveProjectFlowsMutation() {\n      if (!this.projectFlows || !this.moveToProjectInput) return ''\n\n      const updateProjects = this.projectFlows.map((flow, i) => {\n        return `updateFlowProject${i}: updateFlowProject(\n          input: { projectId: \"${this.moveToProjectInput.id}\", flowId: \"${flow.id}\" }\n        ) {\n          id\n        }`\n      })\n\n      return gql`\n        mutation {\n          ${updateProjects}\n        }\n      `\n    },\n    // Warn users about the number of active & archived flow counts before project deletion\n    displayFlowCountMessage() {\n      if (\n        this.selectedProject.activeFlowCount > 0 &&\n        this.selectedProject.archivedFlowCount > 0\n      ) {\n        return `This project has ${\n          this.selectedProject.activeFlowCount\n        } active ${this.pluralize(\n          this.selectedProject.activeFlowCount,\n          'flow'\n        )} and ${\n          this.selectedProject.archivedFlowCount\n        } archived ${this.pluralize(\n          this.selectedProject.archivedFlowCount,\n          'flow'\n        )}`\n      } else if (this.selectedProject.activeFlowCount > 0) {\n        return `This project has ${\n          this.selectedProject.activeFlowCount\n        } active ${this.pluralize(\n          this.selectedProject.activeFlowCount,\n          'flow'\n        )}`\n      } else {\n        return `This project has ${\n          this.selectedProject.archivedFlowCount\n        } archived ${this.pluralize(\n          this.selectedProject.archivedFlowCount,\n          'flow'\n        )}`\n      }\n    }\n  },\n  watch: {\n    tenant() {\n      this.$apollo.queries.projects.refetch()\n    }\n  },\n  methods: {\n    closeProjectDialog() {\n      this.selectedProject = null\n      setTimeout(() => {\n        this.projectNameErrors = []\n        this.projectNameInput = null\n        this.projectDescriptionInput = null\n\n        this.moveToProjectInput = null\n      }, 200)\n    },\n    async checkProjectName() {\n      // Check for presence\n      if (!this.projectNameInput) {\n        this.projectNameErrors = ['This field is required.']\n        this.showNameInputIcon = true\n        return\n      }\n\n      // Check if project is being modified and its name hasn't changed\n      if (\n        this.selectedProject &&\n        this.selectedProject.name === this.projectNameInput\n      ) {\n        this.showNameInputIcon = true\n        return\n      }\n\n      // Check project name for uniqueness\n      const projectsWithName = await this.$apollo.query({\n        query: require('@/graphql/TeamSettings/project.gql'),\n        variables: {\n          projectName: this.projectNameInput\n        },\n        fetchPolicy: 'no-cache'\n      })\n      if (projectsWithName?.errors) {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to check this project name. Please try again.'\n        )\n      } else if (projectsWithName?.data?.project?.length > 0) {\n        this.projectNameErrors = [\n          'This project name is already in use. Please enter a different name.'\n        ]\n        this.showNameInputIcon = true\n      } else {\n        this.showNameInputIcon = true\n      }\n    },\n    copyTextToClipboard(id) {\n      clearTimeout(this.copyTimeout)\n\n      this.copiedProjectId = id\n      navigator.clipboard.writeText(id)\n\n      this.copyTimeout = setTimeout(() => {\n        this.copiedProjectId = null\n      }, 3000)\n    },\n    async createProject() {\n      this.isCreatingProject = true\n\n      await this.checkProjectName()\n\n      if (this.projectNameErrors.length > 0) {\n        this.isCreatingProject = false\n        return\n      }\n\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-project.gql'),\n          variables: {\n            name: this.projectNameInput,\n            description: this.projectDescriptionInput,\n            tenantId: this.tenant.id\n          }\n        })\n\n        this.$apollo.queries.projects.refetch()\n\n        this.handleAlert(\n          'success',\n          'Your project has been successfully created.'\n        )\n      } catch (e) {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to create your project. Please try again.'\n        )\n      }\n\n      this.isCreatingProject = false\n      this.dialogCreateProject = false\n    },\n    handleAlert(type, message) {\n      this.alertType = type\n      this.alertMessage = message\n      this.alertShow = true\n    },\n    async modifyProject() {\n      this.isModifyingProject = true\n\n      await this.checkProjectName()\n\n      if (this.projectNameErrors.length > 0) {\n        this.isModifyingProject = false\n        return\n      }\n\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/TeamSettings/modify-project.gql'),\n          variables: {\n            projectId: this.selectedProject.id,\n            projectName: this.projectNameInput,\n            projectDescription: this.projectDescriptionInput\n          }\n        })\n\n        this.$apollo.queries.projects.refetch()\n        this.handleAlert(\n          'success',\n          'Your project has been successfully updated.'\n        )\n      } catch (e) {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to modify this project. Please try again.'\n        )\n      }\n\n      this.isModifyingProject = false\n      this.dialogModifyProject = false\n    },\n    // Hand off a project's flows to a new project before deletion\n    async moveProjectsFlows() {\n      try {\n        // Fetch flows for the project that is about to be deleted.\n        await this.$apollo.queries.projectFlows.refetch()\n\n        // If projectFlows did not update, something went wrong.\n        if (!this.projectFlows) {\n          throw new Error('Failed to fetch project flows')\n        }\n\n        // Do nothing if the project has no flows.\n        if (this.projectFlows.length === 0) return true\n\n        // Execute a mutation that moves all of the almost-deleted project's flows.\n        await this.$apollo.mutate({\n          mutation: this.moveProjectFlowsMutation\n        })\n\n        return true\n      } catch (err) {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to move your flows to a new project. Please try again.'\n        )\n\n        this.isRemovingProject = false\n        this.dialogRemoveProject = false\n\n        LogRocket.captureException(err)\n        return false\n      }\n    },\n    pluralize(count, word) {\n      if (count === 1) return word\n      return `${word}s`\n    },\n    async removeProject() {\n      this.isRemovingProject = true\n\n      // Move project's flow's to new project, if a new project was specified by the user\n      if (this.moveToProjectInput) {\n        const flowsMoved = await this.moveProjectsFlows()\n\n        // Stop execution if project-to-project flow handoff failed for any reason\n        if (!flowsMoved) return\n      }\n\n      try {\n        // Proceed with deleting the project\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/TeamSettings/delete-project.gql'),\n          variables: {\n            projectId: this.selectedProject.id\n          }\n        })\n\n        this.$apollo.queries.projects.refetch()\n        this.handleAlert('success', 'The project has been successfuly deleted.')\n      } catch (e) {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to delete this project. Please try again.'\n        )\n      }\n\n      this.dialogRemoveProject = false\n      this.isRemovingProject = false\n    },\n    selectProject(project) {\n      this.selectedProject = project\n      this.selectedProject.activeFlowCount = this.selectedProject.active_flow_count.aggregate.count\n      this.selectedProject.archivedFlowCount = this.selectedProject.archived_flow_count.aggregate.count\n\n      this.projectNameInput = project.name\n      this.projectDescriptionInput = project.description\n    }\n  },\n  apollo: {\n    projectFlows: {\n      query: require('@/graphql/Project/flow-ids.gql'),\n      variables() {\n        return {\n          projectId: this.selectedProject ? this.selectedProject.id : null\n        }\n      },\n      skip() {\n        return !this.selectedProject\n      },\n      update: data => {\n        return (data && data.project_by_pk && data.project_by_pk.flows) || null\n      }\n    },\n    projects: {\n      query: require('@/graphql/TeamSettings/projects.gql'),\n      result({ data }) {\n        this.isLoadingTable = false\n        if (!data) return\n        return data.projects\n      },\n      error() {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to fetch your projects. Please try again later.'\n        )\n      },\n      fetchPolicy: 'no-cache'\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout :show=\"!isLoadingTable\" control-show>\n    <template #title>Projects</template>\n\n    <template #subtitle>\n      <span v-if=\"permissionsCheck\">\n        View and manage your team's\n        <ExternalLink\n          href=\"https://docs.prefect.io/cloud/concepts/projects.html#projects\"\n          >projects</ExternalLink\n        >\n      </span>\n      <span v-else\n        >View the\n        <ExternalLink\n          href=\"https://docs.prefect.io/cloud/concepts/projects.html#projects\"\n          >projects</ExternalLink\n        >\n        of {{ tenant.name }}</span\n      >\n    </template>\n\n    <template v-if=\"permissionsCheck\" #cta>\n      <v-btn\n        color=\"primary\"\n        class=\"white--text\"\n        large\n        @click=\"\n          selectedProject = null\n          dialogCreateProject = true\n          projectNameInput = ''\n          projectDescriptionInput = ''\n        \"\n      >\n        <v-icon left>\n          view_carousel\n        </v-icon>\n        Add Project\n      </v-btn>\n    </template>\n\n    <v-text-field\n      v-if=\"!$vuetify.breakpoint.mdAndUp\"\n      v-model=\"searchInput\"\n      class=\"rounded-0 elevation-1 mb-1\"\n      solo\n      dense\n      hide-details\n      single-line\n      placeholder=\"Search by project ID, name, or description\"\n      prepend-inner-icon=\"search\"\n      autocomplete=\"new-password\"\n    ></v-text-field>\n\n    <v-card tile>\n      <v-card-text class=\"pa-0\">\n        <div v-if=\"$vuetify.breakpoint.mdAndUp\" class=\"py-1 mr-2 flex\">\n          <v-text-field\n            v-model=\"searchInput\"\n            class=\"rounded-0 elevation-1\"\n            solo\n            dense\n            hide-details\n            single-line\n            placeholder=\"Search by project ID, name, or description\"\n            prepend-inner-icon=\"search\"\n            autocomplete=\"new-password\"\n            :style=\"{\n              'max-width': $vuetify.breakpoint.mdAndUp ? '360px' : null\n            }\"\n          ></v-text-field>\n        </div>\n\n        <!-- PROJECTS TABLE -->\n        <v-data-table\n          fixed-header\n          :headers=\"headersByViewport\"\n          :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n          :search=\"searchInput\"\n          :items=\"projects\"\n          :items-per-page=\"10\"\n          :sort-by.sync=\"sortBy\"\n          :sort-desc.sync=\"sortDesc\"\n          class=\"elevation-2 rounded-0 truncate-table\"\n          :class=\"{ 'fixed-table': $vuetify.breakpoint.smAndUp }\"\n          :footer-props=\"{\n            showFirstLastPage: true,\n            itemsPerPageOptions: [10, 15, 20, -1],\n            firstIcon: 'first_page',\n            lastIcon: 'last_page',\n            prevIcon: 'keyboard_arrow_left',\n            nextIcon: 'keyboard_arrow_right'\n          }\"\n          no-results-text=\"No projects found. Try expanding your search?\"\n          no-data-text=\"This team does not have any projects yet.\"\n        >\n          <!-- HEADERS -->\n          <template #header.name=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.description=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.active_flow_count.aggregate.count=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.created=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.id=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n\n          <!-- PROJECT ID-->\n          <template #item.id=\"{ item }\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <div\n                  class=\"cursor-pointer text-truncate\"\n                  v-on=\"on\"\n                  @click=\"copyTextToClipboard(item.id)\"\n                >\n                  {{ item.id }}\n                </div>\n              </template>\n              <span>{{\n                copiedProjectId === item.id ? 'Copied!' : 'Click to copy ID'\n              }}</span>\n            </v-tooltip>\n          </template>\n\n          <!-- PROJECT NAME -->\n          <template #item.name=\"{ item }\">\n            <v-tooltip v-if=\"item.name\" top>\n              <template #activator=\"{ on }\">\n                <div class=\"hidewidth\" v-on=\"on\">\n                  <router-link\n                    :to=\"{\n                      name: 'project',\n                      params: {\n                        id: item.id,\n                        tenant: tenant.slug\n                      }\n                    }\"\n                  >\n                    {{ item.name }}\n                  </router-link>\n                </div>\n              </template>\n              <span>{{ item.name }}</span>\n            </v-tooltip>\n            <span v-else>-</span>\n          </template>\n\n          <!-- PROJECT CREATION DATETIME -->\n          <template #item.created=\"{ item }\">\n            <v-tooltip v-if=\"item.created\" top>\n              <template #activator=\"{ on }\">\n                <div class=\"hidewidth\" v-on=\"on\">\n                  {{ formDate(item.created) }}\n                </div>\n              </template>\n              <span>{{ formatDateTime(item.created) }}</span>\n            </v-tooltip>\n            <span v-else>-</span>\n          </template>\n\n          <!-- PROJECT DESCRIPTION -->\n          <template #item.description=\"{ item }\">\n            <v-tooltip v-if=\"item.description\" top>\n              <template #activator=\"{ on }\">\n                <div class=\"hidewidth\" v-on=\"on\">\n                  {{ item.description }}\n                </div>\n              </template>\n              <span>{{ item.description }}</span>\n            </v-tooltip>\n            <span v-else>-</span>\n          </template>\n\n          <!-- PROJECT ACTIONS -->\n          <template v-if=\"permissionsCheck\" #item.actions=\"{ item }\">\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  text\n                  fab\n                  x-small\n                  color=\"primary\"\n                  v-on=\"on\"\n                  @click=\"\n                    selectProject(item)\n                    dialogModifyProject = true\n                  \"\n                >\n                  <v-icon>edit</v-icon>\n                </v-btn>\n              </template>\n              Modify this project\n            </v-tooltip>\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  text\n                  fab\n                  x-small\n                  color=\"error\"\n                  v-on=\"on\"\n                  @click=\"\n                    selectProject(item)\n                    dialogRemoveProject = true\n                  \"\n                >\n                  <v-icon>delete</v-icon>\n                </v-btn>\n              </template>\n              Delete this project\n            </v-tooltip>\n          </template>\n        </v-data-table>\n      </v-card-text>\n    </v-card>\n\n    <!-- CREATE PROJECT  -->\n    <ConfirmDialog\n      v-model=\"dialogCreateProject\"\n      :dialog-props=\"{ 'max-width': '600' }\"\n      :disabled=\"isCreatingProject || !createFormValid\"\n      :loading=\"isCreatingProject\"\n      title=\"Create a new project\"\n      confirm-text=\"Create\"\n      @cancel=\"closeProjectDialog\"\n      @confirm=\"createProject\"\n    >\n      <v-form v-model=\"createFormValid\">\n        <v-text-field\n          v-model=\"projectNameInput\"\n          autofocus\n          label=\"Project Name\"\n          counter\n          maxlength=\"30\"\n          :error-messages=\"projectNameErrors\"\n          validate-on-blur\n          outlined\n          dense\n          @focus=\"\n            projectNameErrors = []\n            showNameInputIcon = false\n          \"\n          @blur=\"checkProjectName\"\n        >\n          <v-icon\n            v-if=\"showNameInputIcon && projectNameErrors.length === 0\"\n            slot=\"append\"\n            class=\"green--text\"\n          >\n            check\n          </v-icon>\n          <v-icon\n            v-if=\"showNameInputIcon && projectNameErrors.length > 0\"\n            slot=\"append\"\n            class=\"red--text\"\n          >\n            clear\n          </v-icon>\n        </v-text-field>\n        <v-text-field\n          v-model=\"projectDescriptionInput\"\n          class=\"mt-3\"\n          label=\"Project Description\"\n          counter\n          outlined\n          dense\n          maxlength=\"180\"\n        >\n        </v-text-field>\n      </v-form>\n    </ConfirmDialog>\n\n    <!-- MODIFY PROJECT -->\n    <ConfirmDialog\n      v-if=\"selectedProject\"\n      v-model=\"dialogModifyProject\"\n      :dialog-props=\"{ 'max-width': '600' }\"\n      :disabled=\"isModifyingProject || !modifyFormValid\"\n      :loading=\"isModifyingProject\"\n      :title=\"`Modify the project ${selectedProject.name}`\"\n      confirm-text=\"Save\"\n      @cancel=\"closeProjectDialog\"\n      @confirm=\"modifyProject\"\n    >\n      <v-form v-model=\"modifyFormValid\">\n        <v-text-field\n          v-model=\"projectNameInput\"\n          autofocus\n          label=\"Project Name\"\n          counter\n          maxlength=\"30\"\n          :error-messages=\"projectNameErrors\"\n          validate-on-blur\n          outlined\n          dense\n          @focus=\"\n            projectNameErrors = []\n            showNameInputIcon = false\n          \"\n          @blur=\"checkProjectName\"\n        >\n          <v-icon\n            v-if=\"showNameInputIcon && projectNameErrors.length === 0\"\n            slot=\"append\"\n            class=\"green--text\"\n          >\n            check\n          </v-icon>\n          <v-icon\n            v-if=\"showNameInputIcon && projectNameErrors.length > 0\"\n            slot=\"append\"\n            class=\"red--text\"\n          >\n            clear\n          </v-icon>\n        </v-text-field>\n        <v-text-field\n          v-model=\"projectDescriptionInput\"\n          class=\"mt-3\"\n          label=\"Project Description\"\n          counter\n          maxlength=\"180\"\n          outlined\n          dense\n        >\n        </v-text-field>\n      </v-form>\n    </ConfirmDialog>\n\n    <!-- DELETE PROJECT -->\n    <ConfirmDialog\n      v-if=\"selectedProject\"\n      v-model=\"dialogRemoveProject\"\n      type=\"error\"\n      :dialog-props=\"{ 'max-width': '600' }\"\n      :disabled=\"isRemovingProject\"\n      :loading=\"isRemovingProject\"\n      :title=\"`Are you sure you want to delete ${selectedProject.name}?`\"\n      @cancel=\"closeProjectDialog\"\n      @confirm=\"removeProject\"\n    >\n      <template\n        v-if=\"\n          selectedProject.activeFlowCount || selectedProject.archivedFlowCount\n        \"\n      >\n        <p class=\"mb-6\">\n          {{ displayFlowCountMessage }}. If you would like to preserve these\n          flows, you can move them into a new project now.\n        </p>\n\n        <v-autocomplete\n          data-public\n          v-model=\"moveToProjectInput\"\n          :items=\"moveToProjectDropdownItems\"\n          :menu-props=\"{\n            'offset-y': true,\n            transition: 'slide-y-transition'\n          }\"\n          outlined\n          dense\n          label=\"New Project\"\n          clearable\n        ></v-autocomplete>\n\n        <p v-if=\"moveToProjectInput\" class=\"mb-0\">\n          Select CONFIRM to delete this project and move its flows to\n          <strong>{{ moveToProjectInput.name }}</strong\n          >.\n        </p>\n\n        <p v-else class=\"mb-0\">\n          If you choose to leave the \"New project\" field blank,\n          <strong class=\"red--text\">\n            you will delete this project and all of its flows. This action\n            cannot be undone.\n          </strong>\n        </p>\n      </template>\n\n      <template\n        v-if=\"\n          selectedProject.activeFlowCount === 0 &&\n            selectedProject.archivedFlowCount === 0\n        \"\n      >\n        <p class=\"mb-2\">\n          This project has no flows and can be safely deleted.\n        </p>\n      </template>\n    </ConfirmDialog>\n\n    <Alert\n      v-model=\"alertShow\"\n      :type=\"alertType\"\n      :message=\"alertMessage\"\n      :offset-x=\"$vuetify.breakpoint.mdAndUp ? 256 : 56\"\n    ></Alert>\n  </ManagementLayout>\n</template>\n\n<style lang=\"scss\" scoped>\n.flex {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.hidewidth {\n  max-width: 100%;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  width: 100%;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/Roles.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport CreateRoleTable from '@/pages/TeamSettings/CreateRoleTable'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { ROLE_MAP } from '@/utils/roles.js'\n\nconst DEFAULT_ROLES = [\n  'TENANT_ADMIN',\n  'USER',\n  'READ_ONLY_USER',\n  'ENTERPRISE_LICENSE_ADMIN'\n]\n\nexport default {\n  components: {\n    CreateRoleTable\n  },\n  mixins: [formatTime],\n  data() {\n    return {\n      deleteSelected: null,\n      loading: 0,\n      template: null,\n      deletingRole: null,\n      defaultRoles: DEFAULT_ROLES,\n      useDefault: true,\n      roleName: '',\n      addRole: false,\n      roleId: null,\n      roleMap: ROLE_MAP,\n      defaultRole: null\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['user']),\n    ...mapGetters('license', [\n      'license',\n      'hasPermission',\n      'allowedUsers',\n      'role'\n    ]),\n    loadingRoles() {\n      return Object.values(this.roleMap).filter(\n        role => role !== 'Pending' && role !== 'License administrator'\n      )\n    },\n    selectedRole() {\n      if (this.roleId) return this.roleId\n      if (this.template) return this.template.id\n      return null\n    },\n    editedRoles() {\n      if (!this.roles) return []\n      const defaultRoles = this.roles?.reduce((arr, role) => {\n        if (this.defaultRoles.includes(role.name)) {\n          //Check that only license admins are shown license admin role\n          if (\n            role.id !== '55375f15-fdae-4a2f-b15a-afb6477522cb' ||\n            this.role == '55375f15-fdae-4a2f-b15a-afb6477522cb'\n          )\n            arr.push({ ...role, default: true })\n        }\n        return arr\n      }, [])\n      const tenantRoles = this.roles?.filter(\n        role => role.tenant_id === this.tenant.id\n      )\n      return { defaultRoles, tenantRoles }\n    }\n  },\n  watch: {\n    editedRoles() {\n      if (this.useDefault) {\n        const role =\n          this.editedRoles?.tenantRoles?.filter(\n            role => role.id === this.role\n          )[0] ||\n          this.editedRoles?.defaultRoles?.filter(\n            role => role.id === this.role\n          )[0]\n        this.defaultRole = role\n        this.template = role\n      }\n    },\n    tenant() {\n      this.$apollo.queries.roles.refetch()\n    },\n    license() {\n      if (!this.hasPermission('feature', 'custom-role'))\n        this.$router.push({ name: 'dashboard' })\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    formatName(name) {\n      return this.roleMap[name]\n    },\n    handleRoleSelect(role, roleType) {\n      this.useDefault = false\n      this.roleId = null\n      if (roleType === 'new') {\n        if (this.addRole) this.cancelAddName(false)\n        else this.addRole = true\n      } else {\n        this.addRole = false\n        this.cancelAddName(false)\n      }\n      this.template = role\n    },\n    cancelAddName(changeRole = true) {\n      this.roleName = ''\n      this.addRole = false\n      if (changeRole) this.template = this.defaultRole\n    },\n    async refetch() {\n      await this.$apollo.queries.roles.refetch()\n      if (this.addRole) this.cancelAddName()\n    },\n    //Can not delete a role if it's being used in a membership or invitation\n    roleInUse(role) {\n      return (\n        !!this.rolesInUse.filter(\n          membershipRole => membershipRole.role_id === role.id\n        ).length ||\n        !!this.rolesInvited.filter(\n          invitationRole => invitationRole.role_id === role.id\n        ).length\n      )\n    },\n    async deleteRole(role) {\n      this.deletingRole = role.id\n      try {\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/delete_custom-role.gql'),\n          variables: {\n            input: {\n              role_id: role.id\n            }\n          }\n        })\n        if (res?.data?.delete_custom_role) {\n          this.$apollo.queries.roles.refetch()\n\n          this.setAlert({\n            alertShow: true,\n            alertMessage: 'Role deleted',\n            alertType: 'Success'\n          })\n        }\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `${e}`,\n          alertType: 'error'\n        })\n      } finally {\n        this.deletingRole = null\n        if (this.template.id === role.id)\n          this.template =\n            this.editedRoles?.tenantRoles?.filter(\n              role => role.id === this.role\n            )[0] ||\n            this.editedRoles?.defaultRoles?.filter(\n              role => role.id === this.role\n            )[0]\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.roles.skip = !entry.isIntersecting\n      this.$apollo.queries.rolesInUse.skip = !entry.isIntersecting\n      this.$apollo.queries.rolesInvited.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    roles: {\n      query: require('@/graphql/TeamSettings/roles.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {}\n      },\n      pollInterval: 10000,\n      update: data => data.auth_role\n    },\n    rolesInUse: {\n      query: require('@/graphql/TeamSettings/membership-roles.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {}\n      },\n      pollInterval: 10000,\n      update: data => data.membership\n    },\n    rolesInvited: {\n      query: require('@/graphql/TeamSettings/membership-invitation-roles.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {}\n      },\n      pollInterval: 10000,\n      update: data => data.membership_invitation\n    }\n  }\n}\n</script>\n\n<template>\n  <v-sheet\n    v-if=\"!hasPermission('read', 'role')\"\n    v-intersect=\"{ handler: onIntersect }\"\n    height=\"100vH\"\n    class=\"appBackground\"\n  >\n    <div class=\"text-h4 text-center appBackground pt-8\">\n      You do not have permission to access roles.\n    </div>\n  </v-sheet>\n\n  <v-row v-else>\n    <v-col cols=\"3\" class=\"pa-0 ma-0\">\n      <v-navigation-drawer permanent class=\"ma-0\" height=\"100%\" width=\"100%\">\n        <v-list dense nav>\n          <v-list-item>\n            <v-list-item-content>\n              <v-list-item-title\n                class=\"text-h5 font-weight-light text--secondary mb-2 pt-4\"\n              >\n                Default Roles\n              </v-list-item-title>\n              <v-divider></v-divider>\n            </v-list-item-content>\n          </v-list-item>\n          <div v-if=\"loading\">\n            <v-list-item\n              v-for=\"(name, index) in loadingRoles\"\n              :key=\"index\"\n              link\n            >\n              <v-list-item-content>\n                <v-list-item-title\n                  class=\"text-body-1 font-weight-regular text--secondary\"\n                  >{{ name }}\n                </v-list-item-title>\n              </v-list-item-content>\n            </v-list-item>\n          </div>\n\n          <v-list-item\n            v-for=\"item in editedRoles.defaultRoles\"\n            v-else\n            :key=\"item.name\"\n            link\n            :style=\"\n              selectedRole === item.id\n                ? { 'background-color': 'var(--v-appBackground-darken1)' }\n                : ''\n            \"\n          >\n            <v-list-item-content @click=\"handleRoleSelect(item, 'default')\">\n              <v-list-item-title\n                :class=\"selectedRole === item.id ? 'primary--text' : ''\"\n                class=\"text-body-1 font-weight-regular text--secondary\"\n                >{{ formatName(item.name) }}</v-list-item-title\n              >\n            </v-list-item-content>\n          </v-list-item>\n        </v-list>\n\n        <v-list v-if=\"hasPermission('feature', 'custom-role')\" dense nav>\n          <v-list-item>\n            <v-list-item-content>\n              <v-list-item-title\n                class=\"text-h5 font-weight-light text--secondary\"\n              >\n                <span\n                  >Custom Roles\n                  <v-btn\n                    v-if=\"hasPermission('create', 'role')\"\n                    :disabled=\"addRole\"\n                    color=\"primary\"\n                    icon\n                    small\n                    @click=\"handleRoleSelect(null, 'new')\"\n                  >\n                    <v-icon v-if=\"!addRole\">add</v-icon>\n                  </v-btn></span\n                >\n              </v-list-item-title>\n              <v-divider></v-divider>\n            </v-list-item-content>\n          </v-list-item>\n\n          <v-sheet\n            v-if=\"!loading\"\n            :style=\"{ overflow: 'auto' }\"\n            :height=\"$vuetify.breakpoint.xl ? '70vH' : '40vH'\"\n          >\n            <v-list-item v-if=\"addRole\" link>\n              <v-list-item-content>\n                <v-list-item-title>\n                  <v-text-field\n                    v-model=\"roleName\"\n                    class=\"text-body-1 font-weight-regular text--secondary pa-0\"\n                    required\n                    autofocus\n                    hide-details\n                    placeholder=\"Role Name\"\n                  ></v-text-field>\n                </v-list-item-title>\n              </v-list-item-content>\n              <v-list-item-icon>\n                <v-btn\n                  text\n                  fab\n                  x-small\n                  color=\"blue-grey\"\n                  @click.stop=\"cancelAddName\"\n                >\n                  <v-icon>clear</v-icon>\n                </v-btn>\n              </v-list-item-icon>\n            </v-list-item>\n            <v-list-item\n              v-for=\"item in editedRoles.tenantRoles\"\n              :key=\"item.value\"\n              class=\"show-icon\"\n              link\n              :style=\"\n                selectedRole === item.id\n                  ? { 'background-color': 'var(--v-appBackground-darken1)' }\n                  : ''\n              \"\n            >\n              <v-list-item-content @click=\"handleRoleSelect(item, 'tenant')\">\n                <v-list-item-title\n                  :class=\"selectedRole === item.id ? 'primary--text' : ''\"\n                  class=\"text-body-1 font-weight-regular text--secondary\"\n                  >{{ item.name }}\n                </v-list-item-title>\n              </v-list-item-content>\n\n              <v-list-item-icon class=\"hidden-icon\">\n                <div v-if=\"deleteSelected === item.id\">\n                  <v-btn\n                    :disabled=\"defaultRoles.includes(item.name)\"\n                    outlined\n                    :loading=\"deletingRole === item.id\"\n                    x-small\n                    color=\"error\"\n                    @click=\"deleteRole(item)\"\n                    >Delete\n                    <template #loader>\n                      <span\n                        ><v-progress-circular\n                          indeterminate\n                          color=\"error\"\n                          :width=\"2\"\n                          :size=\"18\"\n                      /></span>\n                    </template>\n                  </v-btn>\n                  <v-btn icon x-small text @click=\"deleteSelected = null\">\n                    <v-icon small>close</v-icon>\n                  </v-btn>\n                </div>\n                <v-tooltip v-else bottom>\n                  <template #activator=\"{ on }\">\n                    <div v-on=\"on\">\n                      <v-btn\n                        :disabled=\"\n                          defaultRoles.includes(item.name) || roleInUse(item)\n                        \"\n                        icon\n                        x-small\n                        class=\"ml-1\"\n                        color=\"error\"\n                        @click=\"deleteSelected = item.id\"\n                        ><v-icon>delete</v-icon></v-btn\n                      >\n                    </div>\n                  </template>\n                  <span>{{\n                    roleInUse(item) ? 'Role in use' : 'Delete role'\n                  }}</span>\n                </v-tooltip>\n              </v-list-item-icon>\n            </v-list-item>\n          </v-sheet>\n        </v-list>\n      </v-navigation-drawer>\n    </v-col>\n    <v-col cols=\"9\" class=\"pa-0\">\n      <CreateRoleTable\n        :template=\"template\"\n        :role-name=\"roleName\"\n        @close=\"refetch\"\n      />\n    </v-col>\n  </v-row>\n</template>\n\n<style scoped>\n.hidden-icon {\n  display: none;\n}\n\n.show-icon:hover .hidden-icon {\n  display: inline;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/Secrets.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport CodeInput from '@/components/CustomInputs/CodeInput'\nimport ManagementLayout from '@/layouts/ManagementLayout'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport Alert from '@/components/Alert'\nimport { tryParseJson } from '@/utils/json'\n\nexport default {\n  components: {\n    Alert,\n    ConfirmDialog,\n    ManagementLayout,\n    CodeInput\n  },\n  data() {\n    return {\n      // Alert data\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n\n      // Table headers\n      headers: [\n        {\n          text: 'Name',\n          value: 'name',\n          sortable: true\n        },\n        {\n          text: '',\n          value: 'actions',\n          align: 'right',\n          sortable: false\n        }\n      ],\n\n      // Loading states\n      isFetchingSecrets: true,\n      isDeletingSecret: false,\n      isSettingSecret: false,\n\n      // Distinguish between creating & modifying secret\n      isSecretUpdate: false,\n\n      // How many rows are displayed at a time,\n      itemsPerPage: 10,\n      rowsPerPageItems: [10, 15, 20, -1],\n\n      // Table search\n      search: null,\n\n      // Input rules\n      errorMessage: '',\n      rules: {\n        required: val => !!val || 'This field is required.'\n      },\n\n      // Dialogs\n      secretModifyDialog: false,\n      secretDeleteDialog: false,\n\n      // Create/modify secret name & value input\n      secretNameInput: null,\n      secretValueInput: '',\n\n      // Secret selected for modification/deletion\n      selectedSecret: null,\n\n      // Store previous secret name when modifying secret\n      // This is used to delete the secret with that name and create a new secret with a separate value\n      previousSecretName: null,\n\n      //secretsInfoCard\n      secretsInfo: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('license', ['hasPermission']),\n    permissionsCheck() {\n      return !this.hasPermission('update', 'secret')\n    },\n    secretExists() {\n      if (!this.secretNames) return false\n\n      if (this.selectedSecret?.name === this.secretNameInput) {\n        return false\n      }\n      return this.secretNames\n        ?.map(secret => secret.name)\n        .includes(this.secretNameInput)\n    }\n  },\n  watch: {\n    tenant() {\n      this.$apollo.queries.secretNames.refetch()\n    }\n  },\n  methods: {\n    async deleteSecret(secret, opts = {}) {\n      this.isDeletingSecret = true\n\n      const secretResult = await this.$apollo.mutate({\n        mutation: require('@/graphql/Secrets/delete-secret.gql'),\n        variables: {\n          name: secret.name\n        }\n      })\n\n      if (secretResult?.data?.delete_secret?.success) {\n        if (!opts.isModifying) {\n          this.$apollo.queries.secretNames.refetch()\n          this.secretDeleteDialog = false\n          this.handleAlert('success', 'Secret deleted.')\n        }\n      } else {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to delete this secret. Please try again. If this error persists, reach out to help@prefect.io.'\n        )\n      }\n\n      this.isDeletingSecret = false\n    },\n    handleAlert(type, message) {\n      this.alertType = type\n      this.alertMessage = message\n      this.alertShow = true\n    },\n    openSecretModifyDialog(secret) {\n      this.selectedSecret = secret\n      this.isSecretUpdate = true\n      this.previousSecretName = secret.name\n      this.secretNameInput = secret.name\n      this.secretModifyDialog = true\n    },\n    openSecretDeleteDialog(secret) {\n      this.selectedSecret = secret\n      this.secretDeleteDialog = true\n    },\n    resetSelectedSecret() {\n      this.selectedSecret = null\n      this.secretNameInput = null\n      this.secretValueInput = null\n      this.selectedTypeIndex = 0\n    },\n    async validateAndSetSecret() {\n      if (!this.secretNameInput || !this.$refs.secretValueInput.validate()) {\n        this.handleAlert('error', 'Cannot save with errors in form.')\n        return\n      }\n\n      await this.setSecret()\n    },\n    async setSecret() {\n      this.isSettingSecret = true\n\n      if (this.isSecretUpdate) {\n        await this.deleteSecret(\n          { name: this.previousSecretName },\n          { isModifying: true }\n        )\n      }\n      const value =\n        tryParseJson(this.secretValueInput) ?? this.secretValueInput ?? []\n      const secretResult = await this.$apollo.mutate({\n        mutation: require('@/graphql/Secrets/set-secret.gql'),\n        variables: {\n          name: this.secretNameInput,\n          value\n        }\n      })\n\n      if (this.isSecretUpdate) this.isSettingSecret = false\n\n      if (secretResult?.data?.set_secret?.success) {\n        this.$apollo.queries.secretNames.refetch()\n        this.secretModifyDialog = false\n        this.resetSelectedSecret()\n        this.handleAlert(\n          'success',\n          `Secret ${this.isSecretUpdate ? 'updated' : 'added'}.`\n        )\n      } else {\n        this.handleAlert(\n          'error',\n          `Something went wrong when ${\n            this.isSecretUpdate ? 'updating' : 'creating'\n          } this secret. Please try again. If this error persists, please contact help@prefect.io.`\n        )\n      }\n\n      this.isSettingSecret = false\n      this.secretNameInput = null\n      this.secretValueInput = null\n    }\n  },\n  apollo: {\n    secretNames: {\n      query: require('@/graphql/Tenant/tenant-secret-names.gql'),\n      result() {\n        this.isFetchingSecrets = false\n      },\n      update(data) {\n        return data?.secret_names?.map(name => ({ name: name, value: null }))\n      },\n      // skip() {\n      //   return this.isReadOnlyUser\n      // },\n      error() {\n        this.isFetchingSecrets = false\n        if (!this.permissionsCheck) {\n          this.handleAlert(\n            'error',\n            'Something went wrong while trying to fetch secrets. Please try again. If this error persists, please contact help@prefect.io.'\n          )\n        }\n      },\n      fetchPolicy: 'network-only'\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout :show=\"!isFetchingSecrets\" control-show>\n    <template #title>Secrets </template>\n\n    <template #subtitle>\n      Manage the\n      <a\n        href=\"https://docs.prefect.io/cloud/cloud_concepts/secrets.html\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        >secrets</a\n      >\n      <sup>\n        <v-icon x-small>\n          open_in_new\n        </v-icon>\n      </sup>\n      required by your team's flow executions\n    </template>\n\n    <template v-if=\"!permissionsCheck\" #cta>\n      <v-btn\n        color=\"primary\"\n        class=\"white--text\"\n        large\n        @click=\"\n          previousSecretName = null\n          isSecretUpdate = false\n          secretModifyDialog = true\n        \"\n      >\n        <v-icon left>\n          add\n        </v-icon>\n        Add Secret\n      </v-btn>\n    </template>\n\n    <template v-if=\"permissionsCheck\" #alerts>\n      <v-alert\n        class=\"mx-auto\"\n        border=\"left\"\n        colored-border\n        elevation=\"2\"\n        type=\"warning\"\n        tile\n        icon=\"lock\"\n        max-width=\"380\"\n      >\n        You don't have permission to manage secrets.\n      </v-alert>\n    </template>\n\n    <!-- SEARCH (MOBILE) -->\n    <v-text-field\n      v-if=\"!$vuetify.breakpoint.mdAndUp && !permissionsCheck\"\n      v-model=\"search\"\n      class=\"rounded-0 elevation-1 mb-1\"\n      solo\n      dense\n      hide-details\n      single-line\n      placeholder=\"Search for a secret\"\n      prepend-inner-icon=\"search\"\n      autocomplete=\"new-password\"\n    ></v-text-field>\n\n    <v-card tile class=\"mx-auto\">\n      <v-card-text class=\"pa-0\">\n        <!-- SEARCH (DESKTOP) -->\n        <div\n          v-if=\"$vuetify.breakpoint.mdAndUp && !permissionsCheck\"\n          class=\"py-1 mr-2 flex\"\n        >\n          <v-text-field\n            v-if=\"!permissionsCheck\"\n            v-model=\"search\"\n            class=\"rounded-0 elevation-1\"\n            solo\n            dense\n            hide-details\n            single-line\n            placeholder=\"Search for a secret\"\n            prepend-inner-icon=\"search\"\n            autocomplete=\"new-password\"\n            :style=\"{\n              'max-width': $vuetify.breakpoint.mdAndUp ? '360px' : null\n            }\"\n          ></v-text-field>\n        </div>\n\n        <!-- TABLE -->\n        <v-data-table\n          v-if=\"!permissionsCheck\"\n          fixed-header\n          :headers=\"headers\"\n          :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n          :search=\"search\"\n          :items=\"secretNames\"\n          :items-per-page.sync=\"itemsPerPage\"\n          sort-by=\"name\"\n          class=\"elevation-2 rounded-0 truncate-table\"\n          :footer-props=\"{\n            firstIcon: 'first_page',\n            itemsPerPageOptions: rowsPerPageItems,\n            lastIcon: 'last_page',\n            nextIcon: 'keyboard_arrow_right',\n            prevIcon: 'keyboard_arrow_left',\n            showFirstLastPage: true\n          }\"\n          no-results-text=\"No secrets found. Try expanding your search?\"\n          no-data-text=\"Your team does not have any secrets yet.\"\n        >\n          <!-- HEADERS -->\n          <template #header.name=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n\n          <!-- ACTIONS -->\n          <template #item.actions=\"{ item }\">\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  text\n                  fab\n                  x-small\n                  color=\"primary\"\n                  v-on=\"on\"\n                  @click=\"openSecretModifyDialog(item)\"\n                >\n                  <v-icon>edit</v-icon>\n                </v-btn>\n              </template>\n              Modify secret\n            </v-tooltip>\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  text\n                  fab\n                  x-small\n                  color=\"error\"\n                  v-on=\"on\"\n                  @click=\"openSecretDeleteDialog(item)\"\n                >\n                  <v-icon>delete</v-icon>\n                </v-btn>\n              </template>\n              Delete secret\n            </v-tooltip>\n          </template>\n        </v-data-table>\n      </v-card-text>\n    </v-card>\n\n    <ConfirmDialog\n      v-model=\"secretModifyDialog\"\n      :dialog-props=\"{ 'max-width': '75vh' }\"\n      :loading=\"isSettingSecret\"\n      :title=\"isSecretUpdate ? 'Modify Secret' : 'Create New Secret'\"\n      @cancel=\"resetSelectedSecret\"\n      @confirm=\"validateAndSetSecret\"\n      data-private\n    >\n      <span v-if=\"!isSecretUpdate\">\n        Add a secret that will allow your team to access sensitive data during\n        flow executions.\n      </span>\n\n      <v-text-field\n        v-model=\"secretNameInput\"\n        class=\"_lr-hide mt-6\"\n        data-private\n        :autofocus=\"!isSecretUpdate\"\n        single-line\n        outlined\n        dense\n        :messages=\"\n          secretExists\n            ? 'A secret with this this name already exists. Clicking CONFIRM will overwrite it.'\n            : null\n        \"\n        :rules=\"[rules.required]\"\n        placeholder=\"Secret Name\"\n        prepend-inner-icon=\"vpn_key\"\n        validate-on-blur\n      />\n\n      <code-input\n        v-if=\"secretModifyDialog\"\n        ref=\"secretValueInput\"\n        v-model=\"secretValueInput\"\n        class=\"text-body-1\"\n        placeholder=\"Secret value\"\n        :editors=\"['text', 'json']\"\n        data-private\n      />\n    </ConfirmDialog>\n\n    <ConfirmDialog\n      v-model=\"secretDeleteDialog\"\n      type=\"error\"\n      confirm-text=\"Delete\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      :loading=\"isDeletingSecret\"\n      title=\"Are you sure you want to delete this secret?\"\n      @confirm=\"deleteSecret(selectedSecret)\"\n    >\n      This action cannot be undone.\n    </ConfirmDialog>\n\n    <Alert\n      v-model=\"alertShow\"\n      :type=\"alertType\"\n      :message=\"alertMessage\"\n      :offset-x=\"$vuetify.breakpoint.mdAndUp ? 256 : 56\"\n    ></Alert>\n  </ManagementLayout>\n</template>\n\n<style lang=\"scss\" scoped>\na {\n  text-decoration: none;\n}\n\n.flex {\n  display: flex;\n  justify-content: flex-end;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/Service-Accounts-Table.vue",
    "content": "<script>\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport DateTime from '@/components/DateTime'\nimport { formatTime } from '@/mixins/formatTimeMixin'\nimport { mapGetters, mapActions } from 'vuex'\n\nexport default {\n  components: {\n    ConfirmDialog,\n    DateTime\n  },\n  mixins: [formatTime],\n  props: {\n    // Mapping between role & role color\n    roleColorMap: {\n      type: Object,\n      required: true\n    },\n    // Mapping between role & displayed role text\n    roleMap: {\n      type: Object,\n      required: true\n    },\n\n    // Number that updates every time tenantUsers should be refetched\n    refetchSignal: {\n      type: Number,\n      required: true\n    },\n    // Search input\n    search: {\n      type: String,\n      required: true\n    },\n    // Tenant information\n    tenant: {\n      type: Object,\n      required: true\n    }\n  },\n  data() {\n    return {\n      // Dialogs\n      dialogCreateKey: false,\n      dialogViewKeys: false,\n      dialogRemoveUser: false,\n\n      // Table headers\n      allHeaders: [\n        {\n          mobile: true,\n          text: 'Name',\n          value: 'firstName'\n        },\n        {\n          mobile: true,\n          text: 'Role',\n          value: 'role'\n        },\n        {\n          mobile: true,\n          text: '',\n          value: 'create',\n          align: 'center',\n          sortable: false\n        },\n        {\n          mobile: true,\n          text: '',\n          value: 'actions',\n          align: 'end',\n          sortable: false\n        }\n      ],\n\n      // Table items (populated by Apollo query)\n      membersItems: [],\n      expanded: [],\n      keys: [],\n\n      // Loading states\n      isFetchingMembers: false,\n      isRemovingUser: false,\n      isCreatingKey: false,\n      isDeletingKey: false,\n\n      // Selected user\n      // Set when removing account membership\n      selectedUser: null,\n      isFetchingKeys: true,\n      expiresAt: null,\n      copyKeyDialog: false,\n      apiKeyCopied: false,\n\n      newAPIKey: '',\n      newKeyName: '',\n      keyToDelete: null,\n      dialogRemoveKey: false\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['hasPermission']),\n    headers() {\n      return this.$vuetify.breakpoint.mdAndUp\n        ? this.allHeaders\n        : this.allHeaders.filter(header => header.mobile)\n    },\n    newKeyFormFilled() {\n      return !!this.newKeyName\n    }\n  },\n  watch: {\n    refetchSignal() {\n      this.$apollo.queries.tenantUsers.refetch()\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    copyNewKey() {\n      const copyText = document.querySelector('#new-api-key')\n      copyText.select()\n      document.execCommand('copy')\n      this.apiKeyCopied = true\n      setTimeout(() => {\n        this.apiKeyCopied = false\n      }, 2000)\n    },\n    async createAPIKey(variables) {\n      this.isCreatingKey = true\n      const result = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tokens/create-api-key.gql'),\n        variables\n      })\n\n      if (\n        result?.data?.create_api_key?.id &&\n        result?.data?.create_api_key?.key\n      ) {\n        this.isCreatingKey = false\n        this.resetNewKey()\n        this.newAPIKey = result.data.create_api_key.key\n        this.dialogCreateKey = false\n        this.copyKeyDialog = true\n        this.$apollo.queries.keys.refetch()\n      } else {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to create your API key. Please try again. If this error persists, please contact help@prefect.io.'\n        )\n        this.isCreatingKey = false\n      }\n    },\n    async deleteKey(key) {\n      this.isDeletingKey = true\n      const result = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tokens/delete-api-key.gql'),\n        variables: {\n          id: key.id\n        }\n      })\n\n      if (result?.data?.delete_api_key?.success) {\n        this.dialogRemoveKey = false\n        this.handleAlert(\n          'success',\n          'The API key has been successfully revoked.'\n        )\n        this.$apollo.queries.keys.refetch()\n      } else {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to delete your API key. Please try again. If this error persists, please contact help@prefect.io.'\n        )\n      }\n\n      this.isDeletingKey = false\n    },\n    handleAlert(type, message) {\n      this.setAlert({\n        alertShow: true,\n        alertMessage: message,\n        alertType: type\n      })\n    },\n    resetNewKey() {\n      this.newKeyName = ''\n      this.newKeyScope = ''\n      this.newAPIKey = ''\n      this.expiresAt = null\n    },\n    async removeAccount(id) {\n      this.isRemovingUser = true\n\n      try {\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/User/delete-service-account.gql'),\n          variables: { id }\n        })\n\n        if (res?.data?.delete_service_account?.success) {\n          this.$emit(\n            'successful-action',\n            'The service account has been removed.'\n          )\n          this.$apollo.queries.tenantUsers.refetch()\n        }\n      } catch (error) {\n        this.$emit(\n          'failed-action',\n          'Something went wrong while trying to remove this service account. Please try again.'\n        )\n        throw error\n      } finally {\n        this.isRemovingUser = false\n        this.dialogRemoveUser = false\n        this.selectedUser = null\n      }\n    },\n    updateRole(account) {\n      this.$emit('update', account)\n    }\n  },\n  apollo: {\n    tenantUsers: {\n      query: require('@/graphql/Tenant/tenant-users.gql'),\n      watchLoading(isLoading) {\n        this.isFetchingMembers = isLoading\n      },\n      result({ data }) {\n        if (!data) return\n        this.membersItems = data.tenantUsers\n          .filter(user =>\n            user.memberships.find(mem => mem.tenant_id == this.tenant.id)\n          )\n          .filter(user => user.account_type === 'SERVICE')\n          .map(user => {\n            user.memberships.find(mem => mem.tenant_id == this.tenant.id)\n            return {\n              id: user.id,\n              membershipID: user.memberships[0].id,\n              firstName: user.first_name,\n              role: user?.memberships[0]?.role_detail?.name\n            }\n          })\n        return data\n      },\n      error() {\n        this.$emit(\n          'failed-action',\n          'Something went wrong while trying to fetch your service accounts. Please try again.'\n        )\n        this.$emit('load-end')\n      },\n      fetchPolicy: 'no-cache',\n      skip() {\n        return !this.tenant\n      }\n    },\n    keys: {\n      query: require('@/graphql/Tokens/api-keys.gql'),\n      fetchPolicy: 'network-only',\n      error() {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to fetch your API keys. Please refresh the page and try again. If this error persists, please email help@prefect.io.'\n        )\n      },\n      result({ data }) {\n        this.keys = data.auth_api_key.map(key => {\n          return {\n            id: key.id,\n            name: key.name,\n            created_at: key.created,\n            expires: key.expires_at,\n            user_id: key.user_id,\n            created_by: key.created_by ? key.created_by.username : ''\n          }\n        })\n        this.isFetchingKeys = false\n      },\n      update: data => data\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <v-data-table\n      fixed-header\n      show-expand\n      :expanded.sync=\"expanded\"\n      :headers=\"headers\"\n      :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n      :items=\"membersItems\"\n      :items-per-page=\"10\"\n      :loading=\"isFetchingKeys\"\n      class=\"elevation-2 rounded-0 truncate-table\"\n      :footer-props=\"{\n        showFirstLastPage: true,\n        itemsPerPageOptions: [10, 15, 20, -1],\n        firstIcon: 'first_page',\n        lastIcon: 'last_page',\n        prevIcon: 'keyboard_arrow_left',\n        nextIcon: 'keyboard_arrow_right'\n      }\"\n      :search=\"search\"\n      no-results-text=\"No service accounts found. Try expanding your search?\"\n      no-data-text=\"This team does not have any service accounts yet.\"\n    >\n      <!-- HEADERS -->\n      <template #header.firstName=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text }}</span>\n      </template>\n\n      <template #expanded-item=\"{item}\">\n        <td :colspan=\"4\">\n          <v-list dense class=\"mx-8\">\n            <v-subheader>{{ item.firstName }}'s Keys</v-subheader>\n            <v-list-item\n              v-if=\"!keys.filter(key => key.user_id === item.id).length\"\n              >{{ item.firstName }} currently has no keys.</v-list-item\n            >\n            <v-list-item\n              v-for=\"key in keys.filter(key => key.user_id === item.id)\"\n              :key=\"key.id\"\n            >\n              <v-list-item-title>{{ key.name }}</v-list-item-title>\n              <v-list-item-subtitle\n                >Created {{ key.created_at ? formDate(key.created_at) : '' }}\n                <span v-if=\"key.created_by\">by {{ key.created_by }}</span>\n              </v-list-item-subtitle>\n              <v-list-item-subtitle>\n                {{\n                  !key.expires\n                    ? 'Never Expires'\n                    : formatTimeRelative(key.expires).includes('ago')\n                    ? `Expired ${formatTimeRelative(key.expires)}`\n                    : `Expires ${formatTimeRelative(key.expires)}`\n                }}</v-list-item-subtitle\n              >\n              <v-tooltip\n                v-if=\"hasPermission('delete', 'service-api-key')\"\n                bottom\n              >\n                <template #activator=\"{ on }\">\n                  <v-btn\n                    text\n                    fab\n                    x-small\n                    color=\"error\"\n                    v-on=\"on\"\n                    @click=\"\n                      keyToDelete = key\n                      dialogRemoveKey = true\n                    \"\n                  >\n                    <v-icon>delete</v-icon>\n                  </v-btn>\n                </template>\n                Remove API key\n              </v-tooltip>\n            </v-list-item>\n          </v-list>\n        </td>\n      </template>\n      <template #item.role=\"{ item }\">\n        <v-chip\n          small\n          dark\n          :color=\"\n            !roleColorMap[item.role]\n              ? 'accentPink'\n              : roleColorMap[item.role] || 'secondaryLight'\n          \"\n        >\n          {{ roleMap[item.role] || item.role }}\n        </v-chip>\n      </template>\n\n      <template\n        v-if=\"hasPermission('create', 'service-api-key')\"\n        #item.create=\"{ item }\"\n      >\n        <v-btn\n          small\n          color=\"primary\"\n          class=\"white--text\"\n          @click=\"\n            selectedUser = item\n            dialogCreateKey = true\n          \"\n          ><v-icon left>\n            add\n          </v-icon>\n          Create API Key\n        </v-btn>\n      </template>\n\n      <!-- ACTIONS -->\n      <template #item.actions=\"{ item }\">\n        <v-tooltip bottom>\n          <template\n            v-if=\"hasPermission('update', 'service-account')\"\n            #activator=\"{ on }\"\n          >\n            <v-btn\n              text\n              fab\n              x-small\n              color=\"primary\"\n              v-on=\"on\"\n              @click=\"updateRole(item)\"\n            >\n              <v-icon>edit</v-icon>\n            </v-btn>\n          </template>\n          Change Service Account role\n        </v-tooltip>\n        <v-tooltip v-if=\"hasPermission('delete', 'service-account')\" bottom>\n          <template #activator=\"{ on }\">\n            <v-btn\n              text\n              fab\n              x-small\n              color=\"error\"\n              v-on=\"on\"\n              @click=\"\n                selectedUser = item\n                dialogRemoveUser = true\n              \"\n            >\n              <v-icon>delete</v-icon>\n            </v-btn>\n          </template>\n          Remove account\n        </v-tooltip>\n      </template>\n    </v-data-table>\n\n    <!-- CREATE KEY DIALOG -->\n    <ConfirmDialog\n      v-model=\"dialogCreateKey\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      :disabled=\"!newKeyFormFilled || isCreatingKey\"\n      :loading=\"isCreatingKey\"\n      title=\"Create an API key\"\n      confirm-text=\"Create\"\n      @cancel=\"resetNewKey\"\n      @confirm=\"\n        createAPIKey({\n          user_id: selectedUser.id,\n          name: newKeyName,\n          expires_at: expiresAt\n        })\n      \"\n    >\n      <v-text-field\n        v-model=\"newKeyName\"\n        class=\"mb-3\"\n        single-line\n        placeholder=\"API Key Name\"\n        autofocus\n        outlined\n        dense\n      />\n      <DateTime\n        v-model=\"expiresAt\"\n        class=\"mb-3\"\n        warning=\"\n           You have selected a time in the past; as a result, your key will have already expired.\n        \"\n        :text-field-props=\"{\n          outlined: true,\n          dense: true,\n          hint: `Leave blank to never expire this API key`,\n          label: 'API Key Expiration',\n          persistentHint: true\n        }\"\n      />\n    </ConfirmDialog>\n\n    <!-- COPY KEY DIALOG -->\n    <ConfirmDialog\n      v-model=\"copyKeyDialog\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      title=\"Your API key has been created\"\n      :confirm-text=\"apiKeyCopied ? 'Copied' : 'Copy'\"\n      cancel-text=\"Close\"\n      @cancel=\"resetNewKey\"\n      @confirm=\"copyNewKey\"\n    >\n      <p>\n        Copy this key and put it in a secure place.\n        <strong>\n          You won't be able to see this key again once you close this dialog.\n        </strong>\n      </p>\n      <v-textarea\n        id=\"new-api-key\"\n        v-model=\"newAPIKey\"\n        data-private\n        class=\"_lr-hide\"\n        auto-grow\n        rows=\"1\"\n        readonly\n        outlined\n        spellcheck=\"false\"\n      />\n    </ConfirmDialog>\n\n    <ConfirmDialog\n      v-if=\"keyToDelete\"\n      v-model=\"dialogRemoveKey\"\n      type=\"error\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      :title=\"\n        `Are you sure you want to revoke the API key\n          ${keyToDelete.name}?`\n      \"\n      confirm-text=\"Revoke\"\n      :disabled=\"isDeletingKey\"\n      :loading=\"isDeletingKey\"\n      @confirm=\"deleteKey(keyToDelete)\"\n    >\n      Once you delete this API key, you will not be able to use it again to\n      interact with the Prefect Cloud API.\n    </ConfirmDialog>\n\n    <!-- DELETE USER DIALOG -->\n    <ConfirmDialog\n      v-if=\"selectedUser\"\n      v-model=\"dialogRemoveUser\"\n      type=\"error\"\n      :title=\"\n        `Are you sure you want to remove ${selectedUser.firstName} from your team?`\n      \"\n      :dialog-props=\"{ 'max-width': '600' }\"\n      :disabled=\"isRemovingUser\"\n      :loading=\"isRemovingUser\"\n      @confirm=\"removeAccount(selectedUser.id)\"\n    >\n      <div>\n        <span class=\"font-weight-bold\">{{ selectedUser.firstName }}</span>\n        and all of their API keys will be deleted.</div\n      >\n    </ConfirmDialog>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.subtable {\n  border: 2px solid var(--v-utilGrayLight-base);\n  border-radius: 8px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/Service-Accounts.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\n\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ManagementLayout from '@/layouts/ManagementLayout'\nimport ServiceAccountsTable from '@/pages/TeamSettings/Service-Accounts-Table'\nimport { ROLE_MAP, ROLE_COLOR_MAP } from '@/utils/roles.js'\n\nexport default {\n  components: {\n    ConfirmDialog,\n    ManagementLayout,\n    ServiceAccountsTable\n  },\n  data() {\n    return {\n      // Dialogs\n      dialogAddServiceAccount: false,\n\n      // Inputs\n      searchInput: '',\n      serviceAccountNameInput: null,\n\n      // Forms\n      serviceAccountFormValid: true,\n\n      accountCreationError: null,\n\n      // Input rules\n      rules: {\n        required: value => !!value || 'This field is is required.'\n      },\n\n      // Loading states\n      isCreatingServiceUser: false,\n      isUpdatingServiceUser: false,\n\n      // Signal passed as prop to ServiceAccountsTable\n      // MembersTable watches this data attribute & refetches members every time this value changes.\n      serviceAccountsSignal: 0,\n      roleInput: null,\n      updateAccountRole: false,\n      serviceAccountID: null,\n      // Role maps\n      roleMap: ROLE_MAP,\n      roleColorMap: ROLE_COLOR_MAP\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('user', ['user']),\n    ...mapGetters('license', ['license', 'hasPermission']),\n    confirmText() {\n      return this.updateAccountRole ? 'Update' : 'Add'\n    },\n    titleText() {\n      return this.updateAccountRole\n        ? 'Update service account role'\n        : 'Add a new service account'\n    },\n    filteredRoles() {\n      if (!this.roles) return []\n      let rolesToRM = ['RUNNER']\n\n      if (!this.hasPermission('license', 'admin')) {\n        rolesToRM.push('ENTERPRISE_LICENSE_ADMIN')\n      }\n\n      if (!this.hasPermission('feature', 'basic-rbac')) {\n        rolesToRM.push('READ_ONLY_USER', 'USER')\n      }\n      return this.roles.filter(role => !rolesToRM.includes(role.name))\n    }\n  },\n  watch: {\n    tenant() {\n      this.serviceAccountsSignal++\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    handleAlert(type, message) {\n      this.setAlert({\n        alertShow: true,\n        alertMessage: message,\n        alertType: type\n      })\n    },\n    async addServiceAccount() {\n      this.isCreatingServiceUser = true\n      this.accountCreationError = null\n\n      try {\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/User/create-service-account.gql'),\n          variables: {\n            input: {\n              tenant_id: this.tenant.id,\n              name: this.serviceAccountNameInput,\n              role_id: this.roleInput\n            }\n          },\n          errorPolicy: 'all'\n        })\n\n        if (res?.data?.create_service_account?.id) {\n          this.serviceAccountsSignal++\n          this.dialogAddServiceAccount = false\n          this.serviceAccountNameInput = null\n        } else if (res?.errors) {\n          this.setAlert({\n            alertShow: true,\n            alertMessage: res?.errors[0]?.message,\n            alertType: 'error'\n          })\n        }\n      } catch (e) {\n        this.accountCreationError = `There was an error creating your service account:\n            ${e}`\n      } finally {\n        this.isCreatingServiceUser = false\n        this.serviceAccountID = null\n        this.serviceAccountNameInput = null\n        this.dialogAddServiceAccount = false\n        this.roleInput = null\n        this.updateAccountRole = false\n      }\n    },\n    resetServiceAccountDialog() {\n      this.serviceAccountNameInput = null\n      this.roleInput = null\n      this.updateAccountRole = false\n      this.accountCreationError = null\n      this.$refs['service-user-form'].reset()\n    },\n    handleAddOrUpdate() {\n      if (this.updateAccountRole) this.updateServiceAccount()\n      else this.addServiceAccount()\n    },\n    async updateServiceAccount() {\n      this.isUpdatingServiceUser = true\n      try {\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/Tenant/set-membership-role.gql'),\n          variables: {\n            input: {\n              role_id: this.roleInput,\n              membership_id: this.serviceAccountID\n            }\n          },\n          errorPolicy: 'all'\n        })\n        if (res?.data?.set_membership_role) {\n          this.serviceAccountsSignal++\n          this.setAlert({\n            alertShow: true,\n            alertMessage: 'Role updated',\n            alertType: 'Success'\n          })\n        } else if (res?.errors) {\n          this.setAlert({\n            alertShow: true,\n            alertMessage: res?.errors[0]?.message,\n            alertType: 'error'\n          })\n        }\n      } catch (e) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: `${e}`,\n          alertType: 'error'\n        })\n      } finally {\n        this.isUpdatingServiceUser = false\n        this.serviceAccountID = null\n        this.serviceAccountNameInput = null\n        this.dialogAddServiceAccount = false\n        this.roleInput = null\n        this.updateAccountRole = false\n      }\n    },\n    updateRole(event) {\n      this.updateAccountRole = true\n      this.serviceAccountNameInput = event.firstName\n      this.serviceAccountID = event.membershipID\n      this.dialogAddServiceAccount = true\n    }\n  },\n  apollo: {\n    roles: {\n      query: require('@/graphql/TeamSettings/roles.gql'),\n      loadingKey: 'loading',\n      variables() {\n        return {}\n      },\n      pollInterval: 10000,\n      update(data) {\n        if (!data) return\n        return data.auth_role\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout>\n    <template #title>Service Accounts</template>\n\n    <template #subtitle>\n      <span v-if=\"hasPermission('create', 'service-account')\">\n        Manage service accounts and their API keys\n      </span>\n      <span v-else>\n        You don't have permission to manage Service Accounts\n      </span>\n    </template>\n\n    <template v-if=\"hasPermission('create', 'service-account')\" #cta>\n      <v-btn\n        color=\"primary\"\n        class=\"white--text\"\n        large\n        :disabled=\"!roles || roles.length === 0\"\n        data-cy=\"invite-service-account\"\n        @click=\"dialogAddServiceAccount = true\"\n      >\n        <v-icon left>\n          person_add\n        </v-icon>\n        Add Service Account\n      </v-btn>\n    </template>\n\n    <v-card tile>\n      <v-card-text class=\"pa-0\">\n        <v-text-field\n          v-if=\"!$vuetify.breakpoint.mdAndUp\"\n          v-model=\"searchInput\"\n          class=\"rounded-0 elevation-1 mb-1\"\n          solo\n          dense\n          hide-details\n          single-line\n          placeholder=\"Search by name\"\n          prepend-inner-icon=\"search\"\n          autocomplete=\"new-password\"\n        ></v-text-field>\n\n        <ServiceAccountsTable\n          :role-color-map=\"roleColorMap\"\n          :role-map=\"roleMap\"\n          :search=\"searchInput\"\n          :tenant=\"tenant\"\n          :refetch-signal=\"serviceAccountsSignal\"\n          @successful-action=\"handleAlert('success', $event)\"\n          @failed-action=\"handleAlert('error', $event)\"\n          @update=\"updateRole\"\n        ></ServiceAccountsTable>\n      </v-card-text>\n    </v-card>\n\n    <!-- SERVICE ACCOUNT ADD DIALOG -->\n    <ConfirmDialog\n      v-model=\"dialogAddServiceAccount\"\n      :title=\"titleText\"\n      :confirm-text=\"confirmText\"\n      :error=\"accountCreationError\"\n      :loading=\"isCreatingServiceUser || isUpdatingServiceUser\"\n      :disabled=\"\n        !serviceAccountFormValid ||\n          isCreatingServiceUser ||\n          isUpdatingServiceUser\n      \"\n      :dialog-props=\"{\n        'max-width': '600'\n      }\"\n      @cancel=\"resetServiceAccountDialog\"\n      @confirm=\"handleAddOrUpdate\"\n    >\n      <v-form\n        ref=\"service-user-form\"\n        v-model=\"serviceAccountFormValid\"\n        @submit.prevent\n      >\n        <v-text-field\n          v-model=\"serviceAccountNameInput\"\n          class=\"mb-3\"\n          autofocus\n          :disabled=\"updateAccountRole\"\n          label=\"Account Name\"\n          data-cy=\"service-account\"\n          prepend-icon=\"engineering\"\n          outlined\n          :rules=\"[rules.required]\"\n          @keydown.enter=\"addServiceAccount\"\n        />\n        <v-select\n          data-public\n          v-model=\"roleInput\"\n          outlined\n          :menu-props=\"{ offsetY: true }\"\n          label=\"Role\"\n          data-cy=\"invite-role\"\n          prepend-icon=\"supervised_user_circle\"\n          :items=\"filteredRoles\"\n          :rules=\"[rules.required]\"\n          item-text=\"name\"\n          item-value=\"id\"\n          item-disabled=\"disabled\"\n        >\n          <template #item=\"{item}\">\n            {{ roleMap[item.name] ? roleMap[item.name] : item.name }}\n          </template>\n          <template #selection=\"{item}\">\n            {{ roleMap[item.name] ? roleMap[item.name] : item.name }}\n          </template>\n        </v-select>\n      </v-form>\n    </ConfirmDialog>\n  </ManagementLayout>\n</template>\n"
  },
  {
    "path": "src/pages/TeamSettings/TaskConcurrency.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nimport Alert from '@/components/Alert'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ExternalLink from '@/components/ExternalLink'\nimport ManagementLayout from '@/layouts/ManagementLayout'\n\nconst ADD_SUCCESS = 'A new tag concurrency limit has been successfully added.'\nconst ADD_ERROR =\n  'Something went wrong while trying to add your task tag concurrency limit.'\n\nconst DELETE_SUCCESS =\n  'The tag concurrency limit has been successfully deleted.'\nconst DELETE_ERROR =\n  'Something went wrong while trying to delete this concurrency limit.'\n\nconst UPDATE_SUCCESS =\n  'The tag concurrency limit has been successfully updated.'\nconst UPDATE_ERROR =\n  'Something went wrong while trying to update this concurrency limit.'\n\nexport default {\n  components: {\n    Alert,\n    ConfirmDialog,\n    ExternalLink,\n    ManagementLayout\n  },\n  data() {\n    return {\n      // Alert data\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n\n      // Tags with concurrency limits\n      // Stored result from GraphQL query\n      tags: [],\n\n      // Map tag names (String) to usage (Int)\n      // Stored result from GraphQL query, modified from array to object\n      usage: {},\n\n      // Table headers\n      headers: [\n        {\n          text: 'Tag',\n          value: 'name',\n          width: '20%'\n        },\n        {\n          text: 'Usage',\n          value: 'usage',\n          align: 'center',\n          width: '40%',\n          sortable: false\n        },\n        {\n          text: 'Limit',\n          value: 'limit',\n          align: 'center',\n          width: '20%',\n          sortable: false\n        },\n        {\n          text: '',\n          value: 'actions',\n          align: 'right',\n          width: '20%'\n        }\n      ],\n\n      // Form inputs\n      // Limit (used for both add & edit forms)\n      newLimit: null,\n      // Tag name (used for add form only)\n      newTag: null,\n\n      // Input rules\n      rules: {\n        required: value => !!value || 'This field is required.',\n        positiveOnly: value =>\n          parseInt(value) >= 0 ||\n          'The concurrency limit cannot be a negative value.'\n      },\n\n      // Form validation\n      // Determine if add form is valid\n      addValid: true,\n      // Determine if edit form is valid\n      editValid: true,\n\n      // Permissions to determine if the user has access to this feature\n      // permissions: null,\n\n      // Keep track of tag that has been selected for editing or deletion\n      selectedTag: {},\n\n      // Keep track of tag that is in the middle of being deleted\n      deletingLimitId: null,\n\n      // Server error message\n      errorMessage: '',\n\n      // Dialogs\n      showAddDialog: false,\n      showDeleteDialog: false,\n      showEditDialog: false,\n\n      // Search input\n      search: '',\n\n      loadingKey: 0\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['permissions', 'hasPermission']),\n    // Determine if user has permission to add, edit, and delete concurrency limits\n    hasManagementPermission() {\n      return this.isEligible && this.permissionsCheck\n    },\n    // Determine if user has the proper permissions to access TCLs\n    // - They are on a license that grants explicit permission to access this feature\n    isEligible() {\n      // If permissions are still loading...\n      if (!this.permissions) return true\n\n      return this.hasPermission('feature', 'concurrency-limit')\n    },\n    permissionsCheck() {\n      return (\n        this.hasPermission('create', 'concurrency-limit') &&\n        this.hasPermission('update', 'concurrency-limit') &&\n        this.hasPermission('delete', 'concurrency-limit')\n      )\n    },\n    // Merge usage details into tags array\n    tagsWithUsage() {\n      return this.tags.map(tag => ({\n        ...tag,\n        usage: this.usage[tag.name] || 0\n      }))\n    }\n  },\n  watch: {\n    tenant() {\n      this.$apollo?.queries?.tags?.refetch()\n      this.$apollo?.queries?.permissions?.refetch()\n      this.$apollo?.queries?.usage?.refetch()\n    }\n  },\n  methods: {\n    async addTaskTagLimit() {\n      try {\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/TaskTagLimit/update-task-concurrency-limit.gql'),\n          variables: {\n            name: this.newTag,\n            limit: Number(this.newLimit) // The API expects a type Number, so explicitly casting\n          }\n        })\n\n        if (res?.data?.update_task_concurrency_limit?.id) {\n          this.$apollo.queries?.tags?.refetch()\n          this.handleSuccess(ADD_SUCCESS)\n        } else {\n          this.handleError(ADD_ERROR)\n        }\n      } catch (error) {\n        this.handleError(ADD_ERROR)\n      } finally {\n        this.showAddDialog = false\n      }\n    },\n    async deleteTaskTagLimit() {\n      this.deletingLimitId = this.selectedTag.id\n\n      try {\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/TaskTagLimit/delete-task-concurrency-limit.gql'),\n          variables: {\n            limitId: this.selectedTag.id\n          }\n        })\n        if (res?.data?.delete_task_concurrency_limit?.success) {\n          this.$apollo.queries?.tags?.refetch()\n          this.handleSuccess(DELETE_SUCCESS)\n        } else {\n          this.handleError(DELETE_ERROR)\n        }\n\n        this.deletingLimitId = null\n      } catch (error) {\n        this.handleError(DELETE_ERROR)\n\n        this.deletingLimitId = null\n      } finally {\n        this.showDeleteDialog = false\n      }\n    },\n    async updateTaskTagLimit() {\n      try {\n        const res = await this.$apollo.mutate({\n          mutation: require('@/graphql/TaskTagLimit/update-task-concurrency-limit.gql'),\n          variables: {\n            name: this.selectedTag.name,\n            limit: Number(this.newLimit) // The API expects a type Number, so explicitly casting\n          }\n        })\n\n        if (res?.data?.update_task_concurrency_limit?.id) {\n          this.$apollo.queries?.tags?.refetch()\n          this.handleSuccess(UPDATE_SUCCESS)\n        } else {\n          this.handleError(UPDATE_ERROR)\n        }\n      } catch (error) {\n        this.handleError(UPDATE_ERROR)\n      } finally {\n        this.showEditDialog = false\n      }\n    },\n    openAddDialog() {\n      this.showAddDialog = true\n      this.newLimit = ''\n      this.newTag = ''\n    },\n    openDeleteDialog(item) {\n      this.selectedTag = item\n      this.showDeleteDialog = true\n    },\n    openEditDialog(item) {\n      this.selectedTag = item\n      this.newLimit = item.limit\n      this.showEditDialog = true\n    },\n    handleSuccess(message) {\n      this.alertMessage = message\n      this.alertType = 'success'\n      this.alertShow = true\n    },\n    handleError(message) {\n      this.alertMessage = `${message}. Please try again. If the error persists, please contact help@prefect.io.`\n      this.alertType = 'error'\n      this.alertShow = true\n    },\n    checkValid() {\n      this.addValid = this.newLimit ? true : false\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.tags.skip = !entry.isIntersecting\n      this.$apollo.queries.usage.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    tags: {\n      query: require('@/graphql/TaskTagLimit/task-tag-limit.gql'),\n      pollInterval: 5000,\n      loadingKey: 'loadingKey',\n      update: data => data.task_concurrency_limit,\n      skip() {\n        // Skip this query if the tenant isn't eligible\n        return !this.isEligible\n      }\n    },\n    usage: {\n      query: require('@/graphql/TaskTagUsage/task-tag-usage.gql'),\n      variables() {\n        return { tags: this.tags?.map(tag => tag.name) }\n      },\n      pollInterval: 5000,\n      skip() {\n        return !this.tags?.length\n      },\n      update: data => {\n        // Usage is returned as an array of objects in format { name, usage }\n        // Convert this array into object that maps tag names to usage\n        return data?.task_concurrency?.reduce((accum, usage) => {\n          accum[usage.name] = usage.usage\n          return accum\n        }, {})\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-intersect=\"{ handler: onIntersect }\">\n    <ManagementLayout>\n      <template #title>Task Concurrency</template>\n\n      <template #subtitle>\n        Impose\n        <ExternalLink\n          href=\"https://docs.prefect.io/orchestration/flow-runs/concurrency-limits.html#task-run-limits\"\n          >concurrency limits</ExternalLink\n        >\n        on the number of tasks that are running at any given time\n      </template>\n\n      <template v-if=\"isEligible && hasManagementPermission\" #cta>\n        <v-btn\n          color=\"primary\"\n          class=\"white--text\"\n          data-cy=\"add-task-concurrency-limit\"\n          large\n          @click=\"openAddDialog\"\n        >\n          <v-icon left>\n            add\n          </v-icon>\n          Add Tag\n        </v-btn>\n      </template>\n\n      <template v-if=\"!isEligible\" #alerts>\n        <v-alert\n          class=\"mx-auto\"\n          border=\"left\"\n          colored-border\n          elevation=\"2\"\n          type=\"warning\"\n          tile\n          icon=\"lock\"\n          max-width=\"600\"\n        >\n          Your plan doesn't include task concurrency limiting.\n          <ExternalLink href=\"/plans\">Upgrade</ExternalLink> to get access to\n          task concurrency and lots of other cool features!\n        </v-alert>\n      </template>\n\n      <template v-else-if=\"!permissionsCheck\" #alerts>\n        <v-alert\n          class=\"mx-auto\"\n          border=\"left\"\n          colored-border\n          elevation=\"2\"\n          type=\"warning\"\n          tile\n          icon=\"lock\"\n          max-width=\"600\"\n        >\n          Only team administrators can manage task concurrency limits.\n        </v-alert>\n      </template>\n\n      <v-text-field\n        v-if=\"isEligible && !$vuetify.breakpoint.mdAndUp\"\n        v-model=\"search\"\n        class=\"rounded-0 elevation-1 mb-1\"\n        solo\n        dense\n        hide-details\n        single-line\n        placeholder=\"Search by tag name or limit\"\n        prepend-inner-icon=\"search\"\n        autocomplete=\"new-password\"\n      ></v-text-field>\n\n      <v-card v-if=\"isEligible\" tile>\n        <v-card-text class=\"pa-0\">\n          <div v-if=\"$vuetify.breakpoint.mdAndUp\" class=\"py-1 mr-2 flex\">\n            <v-text-field\n              v-model=\"search\"\n              class=\"rounded-0 elevation-1\"\n              solo\n              dense\n              hide-details\n              single-line\n              placeholder=\"Search by tag name or limit\"\n              prepend-inner-icon=\"search\"\n              autocomplete=\"new-password\"\n              :style=\"{\n                'max-width': $vuetify.breakpoint.mdAndUp ? '360px' : null\n              }\"\n            ></v-text-field>\n          </div>\n\n          <v-data-table\n            fixed-header\n            data-cy=\"tag-table\"\n            class=\"elevation-2 rounded-0 truncate-table\"\n            :headers=\"headers\"\n            :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n            :items=\"tagsWithUsage\"\n            :items-per-page=\"10\"\n            :search=\"search\"\n            :loading=\"loadingKey > 0\"\n            :footer-props=\"{\n              showFirstLastPage: true,\n              itemsPerPageOptions: [10, 15, 20, -1],\n              firstIcon: 'first_page',\n              lastIcon: 'last_page',\n              prevIcon: 'keyboard_arrow_left',\n              nextIcon: 'keyboard_arrow_right'\n            }\"\n            no-results-text=\"No concurrency limits found. Try expanding your search?\"\n            no-data-text=\"This team has not set any task concurrency limits yet.\"\n          >\n            <template #header.tag=\"{ header }\">\n              <span class=\"text-subtitle-2\">{{ header.text }}</span>\n            </template>\n            <template #header.usage=\"{ header }\">\n              <v-tooltip bottom open-delay=\"500\">\n                <template #activator=\"{ on }\">\n                  <div class=\"text-subtitle-2\" v-on=\"on\">\n                    {{ header.text }}\n                    <v-icon\n                      x-small\n                      class=\"material-icons-outlined\"\n                      :style=\"{ 'margin-bottom': '2px' }\"\n                      >info</v-icon\n                    >\n                  </div>\n                </template>\n                Number of tasks that are running with the given tag\n              </v-tooltip>\n            </template>\n            <template #header.limit=\"{ header }\">\n              <v-tooltip bottom open-delay=\"500\">\n                <template #activator=\"{ on }\">\n                  <div class=\"text-subtitle-2\" v-on=\"on\">\n                    {{ header.text }}\n                    <v-icon\n                      x-small\n                      class=\"material-icons-outlined\"\n                      :style=\"{ 'margin-bottom': '2px' }\"\n                      >info</v-icon\n                    >\n                  </div>\n                </template>\n                Maximum number of tasks that can simultaneously run with the\n                given tag\n              </v-tooltip>\n            </template>\n\n            <template #item.tag=\"{ item }\">\n              <div class=\"text-body-2\">{{ item.name }}</div>\n            </template>\n\n            <template #item.usage=\"{ item }\">\n              <span>\n                {{ item.usage }} running\n                {{ item.usage === 1 ? 'task' : 'tasks' }} ({{\n                  item.limit === 0\n                    ? 0\n                    : Math.ceil((item.usage / item.limit) * 100)\n                }}%)\n              </span>\n              <div class=\"mx-auto mt-1\">\n                <v-progress-linear\n                  height=\"8\"\n                  :value=\"\n                    item.limit === 0\n                      ? 0\n                      : Math.ceil((item.usage / item.limit) * 100)\n                  \"\n                ></v-progress-linear>\n              </div>\n            </template>\n\n            <template #item.limit=\"{ item }\">\n              <div class=\"text-subtitle-1 position-relative\">\n                <v-tooltip v-if=\"item.limit === 0\" bottom open-delay=\"500\">\n                  <template #activator=\"{ on }\">\n                    <div v-on=\"on\">\n                      {{ item.limit }}\n                      <v-icon\n                        x-small\n                        class=\"position-absolute material-icons-outlined ml-1\"\n                        :style=\"{\n                          top: '6px'\n                        }\"\n                      >\n                        info\n                      </v-icon>\n                    </div>\n                  </template>\n                  A concurrency limit of 0 means that tasks with this tag will\n                  never run.\n                </v-tooltip>\n                <span v-else>\n                  {{ item.limit }}\n                </span>\n              </div>\n            </template>\n\n            <template #item.actions=\"{ item }\">\n              <v-tooltip bottom>\n                <template #activator=\"{ on }\">\n                  <v-btn\n                    v-if=\"hasManagementPermission\"\n                    color=\"primary\"\n                    text\n                    fab\n                    x-small\n                    v-on=\"on\"\n                    @click=\"openEditDialog(item)\"\n                  >\n                    <v-icon>edit</v-icon>\n                  </v-btn>\n                </template>\n                Edit the limit for this tag\n              </v-tooltip>\n\n              <v-tooltip bottom>\n                <template #activator=\"{ on }\">\n                  <v-btn\n                    v-if=\"hasManagementPermission\"\n                    color=\"red\"\n                    text\n                    fab\n                    x-small\n                    v-on=\"on\"\n                    @click=\"openDeleteDialog(item)\"\n                  >\n                    <v-progress-circular\n                      v-if=\"deletingLimitId === item.id\"\n                      indeterminate\n                    />\n                    <v-icon v-else>delete</v-icon>\n                  </v-btn>\n                </template>\n                Remove concurrency limits for tasks with this tag\n              </v-tooltip>\n            </template>\n          </v-data-table>\n        </v-card-text>\n      </v-card>\n\n      <ConfirmDialog\n        v-model=\"showAddDialog\"\n        :dialog-props=\"{ maxWidth: '440' }\"\n        title=\"Add a new concurrency-limiting tag\"\n        :disabled=\"!addValid\"\n        @confirm=\"addTaskTagLimit\"\n      >\n        <v-form v-model=\"addValid\">\n          <v-text-field\n            v-model=\"newTag\"\n            outlined\n            dense\n            data-cy=\"tag-name\"\n            validate-on-blur\n            :rules=\"[rules.required]\"\n            label=\"Tag\"\n            autofocus\n          ></v-text-field>\n          <v-text-field\n            v-model=\"newLimit\"\n            min=\"0\"\n            type=\"number\"\n            data-cy=\"tag-limit\"\n            outlined\n            validate-on-blur\n            dense\n            :rules=\"[rules.required, rules.positiveOnly]\"\n            label=\"Limit\"\n            @input=\"checkValid\"\n          ></v-text-field>\n        </v-form>\n      </ConfirmDialog>\n\n      <ConfirmDialog\n        v-if=\"selectedTag\"\n        v-model=\"showEditDialog\"\n        :dialog-props=\"{ maxWidth: '540' }\"\n        :title=\"\n          `Edit the concurrency limit for tasks with the tag ${selectedTag.name}`\n        \"\n        :disabled=\"!editValid\"\n        @confirm=\"updateTaskTagLimit\"\n      >\n        <v-form v-model=\"editValid\">\n          <v-text-field\n            v-model=\"newLimit\"\n            min=\"0\"\n            type=\"number\"\n            outlined\n            dense\n            label=\"Limit\"\n            autofocus\n            :rules=\"[rules.required, rules.positiveOnly]\"\n            persistent-hint\n          ></v-text-field>\n        </v-form>\n      </ConfirmDialog>\n\n      <ConfirmDialog\n        v-if=\"selectedTag\"\n        v-model=\"showDeleteDialog\"\n        :dialog-props=\"{ maxWidth: '440' }\"\n        :title=\"\n          `Are you sure you want to remove concurrency limits for tasks with the\n          tag ${selectedTag.name}?`\n        \"\n        type=\"error\"\n        @confirm=\"deleteTaskTagLimit\"\n      >\n      </ConfirmDialog>\n\n      <Alert\n        v-model=\"alertShow\"\n        :type=\"alertType\"\n        :message=\"alertMessage\"\n        :offset-x=\"56\"\n      ></Alert>\n    </ManagementLayout>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.custom-header {\n  font-size: 1.15em;\n}\n\n.flex {\n  display: flex;\n  justify-content: flex-end;\n}\n\n.limit-change-button {\n  transform: scale(0.75);\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/TeamSettings.vue",
    "content": "<script>\nimport { mapMutations, mapGetters } from 'vuex'\nimport UpgradeBadge from '@/components/UpgradeBadge'\nexport default {\n  components: {\n    UpgradeBadge\n  },\n  data() {\n    return {\n      // Delete team\n      deleteTeamDialog: false,\n      deleteTeamFormValid: false,\n      deleteTeamTimeout: null,\n      deleteTeamLoading: false,\n      deleteTeamError: null,\n\n      // Form rules\n      rules: {\n        confirm: value => value == 'confirm' || 'Input is incorrect.',\n        nameMatches: value =>\n          value == this.tenant.name || 'Input must match Team Name.',\n        required: value => !!value || 'This field is is required.'\n      },\n\n      // Misc\n      teamName: null,\n      show: true\n    }\n  },\n  computed: {\n    ...mapGetters('api', ['isCloud']),\n    ...mapGetters('tenant', ['tenant', 'role']),\n    ...mapGetters('license', ['hasPermission'])\n  },\n  watch: {\n    tenant() {\n      this.show = false\n\n      setTimeout(() => {\n        this.show = true\n      }, 1000)\n    }\n  },\n  methods: {\n    ...mapMutations('tenant', ['setTenant', 'unsetTenant']),\n    _closeTeamDialog() {\n      this.deleteTeamDialog = false\n      this.teamName = null\n      this.deleteTeamLoading = false\n      this.deleteTeamError = null\n      clearTimeout(this.deleteTeamTimeout)\n    },\n    async deleteTeam() {\n      clearTimeout(this.deleteTeamTimeout)\n      this.deleteTeamLoading = true\n      const deleteTeam = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tenant/delete-tenant.gql'),\n        variables: {\n          input: {\n            confirm: true\n          }\n        }\n      })\n      this.deleteTeamTimeout = setTimeout(() => {\n        this.deleteTeamLoading = false\n        this.teamName = null\n        this.nameMatches = false\n        if (deleteTeam?.data?.delete_tenant?.success) {\n          this.unsetTenant()\n          this.$router.push({ name: 'dashboard', tenant: this.tenant?.slug })\n        } else {\n          this.deleteTeamError = 'Something went wrong.'\n        }\n      }, 750)\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container>\n    <v-navigation-drawer\n      clipped\n      left\n      fixed\n      permanent\n      touchless\n      expand-on-hover\n      :mini-variant=\"$vuetify.breakpoint.smAndDown\"\n      :style=\"{\n        height: `calc(100% - ${$vuetify.breakpoint.smAndDown ? 56 : 64}px)`,\n        top: $vuetify.breakpoint.smAndDown ? '56px' : '64px'\n      }\"\n    >\n      <template #prepend>\n        <v-list-item>\n          <v-list-item-action>\n            <v-icon class=\"blue--text accent-4\">\n              settings\n            </v-icon>\n          </v-list-item-action>\n\n          <v-list-item-content>\n            <div class=\"font-weight-medium\">\n              Team\n            </div>\n          </v-list-item-content>\n        </v-list-item>\n      </template>\n\n      <v-divider />\n\n      <v-list dense>\n        <v-list-item\n          :disabled=\"!isCloud\"\n          :to=\"{ name: 'tokens', params: { tenant: tenant.slug } }\"\n          data-cy=\"team-settings-api-tokens\"\n          ripple\n          exact\n        >\n          <v-list-item-action>\n            <v-icon>sync_alt</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>API Tokens</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :disabled=\"!isCloud\"\n          :to=\"{ name: 'actions', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n        >\n          <v-list-item-action>\n            <i class=\"fad fa-random\" style=\"width: 24px; height: 24px;\"></i>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Automation Actions</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :to=\"{ name: 'cloud-hooks', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n          data-cy=\"cloud-hooks\"\n        >\n          <v-list-item-action>\n            <v-icon>cloud_queue</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Cloud Hooks</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :disabled=\"!isCloud\"\n          :to=\"{ name: 'flow-concurrency', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n          data-cy=\"flow-concurrency\"\n        >\n          <v-list-item-action>\n            <v-icon>pi-flow-run</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Flow Concurrency</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :to=\"{ name: 'flow-groups', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n        >\n          <v-list-item-action>\n            <v-icon>pi-flow</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Flow Groups</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :disabled=\"!isCloud\"\n          :to=\"{ name: 'kv', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n        >\n          <v-list-item-action>\n            <i\n              class=\"fad fa-brackets-curly\"\n              style=\"width: 24px; height: 24px;\"\n            ></i>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>KV Store</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :disabled=\"!isCloud\"\n          :to=\"{ name: 'members', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n          data-cy=\"members\"\n        >\n          <v-list-item-action>\n            <v-icon>people</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Members</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :to=\"{ name: 'projects', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n        >\n          <v-list-item-action>\n            <v-icon>pi-project</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Projects</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :disabled=\"!isCloud || !hasPermission('feature', 'custom-role')\"\n          :to=\"{ name: 'roles', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n        >\n          <v-list-item-action>\n            <v-icon>face</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title\n              >Roles\n              <UpgradeBadge\n                v-if=\"isCloud && !hasPermission('feature', 'custom-role')\"\n                inline\n                depressed\n              >\n                <span class=\"font-weight-medium\">Custom Roles</span> are only\n                available on Enterprise plans.\n              </UpgradeBadge>\n            </v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :disabled=\"!isCloud\"\n          :to=\"{ name: 'secrets', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n        >\n          <v-list-item-action>\n            <v-icon>vpn_key</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Secrets</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :disabled=\"!isCloud\"\n          :to=\"{ name: 'service-accounts', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n        >\n          <v-list-item-action>\n            <v-icon>engineering</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Service Accounts</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n\n        <v-list-item\n          :disabled=\"!isCloud\"\n          :to=\"{ name: 'task-concurrency', params: { tenant: tenant.slug } }\"\n          ripple\n          exact\n          data-cy=\"task-concurrency\"\n        >\n          <v-list-item-action>\n            <v-icon>pi-task-run</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Task Concurrency</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n      </v-list>\n\n      <template #append>\n        <v-list dense>\n          <v-list-item\n            v-if=\"false && hasPermission('delete', 'tenant')\"\n            :ripple=\"false\"\n          >\n            <v-list-item-content v-if=\"$vuetify.breakpoint.mdAndUp\">\n              <v-btn\n                color=\"red\"\n                class=\"ma-auto d-block mb-6 px-12\"\n                dark\n                depressed\n                @click=\"deleteTeamDialog = true\"\n              >\n                Delete Team\n              </v-btn>\n            </v-list-item-content>\n            <v-list-item-action v-else-if=\"$vuetify.breakpoint.smAndDown\">\n              <v-icon color=\"red\">remove_circle</v-icon>\n            </v-list-item-action>\n          </v-list-item>\n        </v-list>\n      </template>\n    </v-navigation-drawer>\n\n    <div\n      :class=\"{\n        'sm-and-down-left-padding': $vuetify.breakpoint.smAndDown,\n        'sm-and-up-left-padding': $vuetify.breakpoint.smAndUp\n      }\"\n    >\n      <v-fade-transition mode=\"out-in\">\n        <router-view></router-view>\n      </v-fade-transition>\n    </div>\n\n    <template v-if=\"false && hasPermission('delete', 'tenant')\">\n      <v-dialog v-model=\"deleteTeamDialog\" max-width=\"600\">\n        <v-card>\n          <v-card-title class=\"text-h5 word-break-normal mb-3\">\n            Delete\n            <span class=\"font-weight-bold blue--text ml-2\">\n              {{ tenant.name }}\n            </span>\n            ?\n          </v-card-title>\n          <v-card-text>\n            This will remove all of your team's flows, tasks, schematics, runs,\n            and logs.\n            <div class=\"font-weight-bold\">This can't be undone.</div>\n\n            <div class=\"mt-10\">\n              <div>\n                To confirm, type your team's name below:\n              </div>\n              <v-form v-model=\"deleteTeamFormValid\">\n                <v-text-field\n                  v-if=\"hasPermission('delete', 'tenant')\"\n                  v-model=\"teamName\"\n                  autocomplete=\"off\"\n                  :label=\"tenant.name\"\n                  single-line\n                  :rules=\"[rules.required, rules.nameMatches]\"\n                  color=\"primary\"\n                  :loading=\"deleteTeamLoading\"\n                >\n                </v-text-field>\n              </v-form>\n            </div>\n          </v-card-text>\n          <v-card-actions class=\"pb-4 px-6\">\n            <span v-if=\"deleteTeamError\" class=\"error--text text-body-2\">\n              {{ deleteTeamError }}\n            </span>\n            <v-spacer></v-spacer>\n            <v-btn depressed color=\"primary\" @click=\"_closeTeamDialog\">\n              Cancel\n            </v-btn>\n            <v-btn\n              color=\"red--text darken-1\"\n              depressed\n              :disabled=\"!deleteTeamFormValid\"\n              :loading=\"deleteTeamLoading\"\n              @click=\"deleteTeam\"\n            >\n              Delete\n            </v-btn>\n          </v-card-actions>\n        </v-card>\n      </v-dialog>\n    </template>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.cursor-point {\n  cursor: pointer;\n}\n\n.sm-and-up-left-padding {\n  // Match left padding with User Settings sidebar width\n  padding-left: 56px;\n}\n\n.sm-and-down-left-padding {\n  // Match left padding with collapsed User Settings sidebar width\n  padding-left: 56px;\n}\n\n.transition-height {\n  transition: max-height 500ms ease;\n}\n</style>\n\n<style lang=\"scss\">\n.text-center {\n  // stylelint-disable\n  .v-skeleton-loader__heading {\n    margin: auto !important;\n  }\n  // stylelint-enable\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSettings/Tokens.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nimport Alert from '@/components/Alert'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ManagementLayout from '@/layouts/ManagementLayout'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    Alert,\n    ConfirmDialog,\n    ManagementLayout\n  },\n  mixins: [formatTime],\n  data() {\n    return {\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n      apiTokenCopied: false,\n      copyTokenDialog: false,\n      createTokenDialog: false,\n      expiresAt: null,\n      headers: [\n        {\n          text: 'Name',\n          value: 'name'\n        },\n        {\n          text: 'Created By',\n          value: 'created_by',\n          width: '5%'\n        },\n        {\n          text: 'Created At',\n          value: 'created'\n        },\n        {\n          text: 'Last Used',\n          value: 'last_used'\n        },\n        {\n          text: 'Expires',\n          value: 'expires_at'\n        },\n        {\n          text: 'Scope',\n          value: 'scope'\n        },\n        {\n          text: '',\n          value: 'actions',\n          align: 'right',\n          sortable: false\n        }\n      ],\n      isFetchingTokens: true,\n      newAPIToken: '',\n      newTokenName: '',\n      newTokenScope: 'TENANT',\n      search: null,\n      tokens: [],\n      tokenToDelete: null,\n      tokenToDeleteDialog: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    ...mapGetters('license', ['hasPermission'])\n  },\n\n  watch: {\n    tenant() {\n      this.$apollo.queries.tokens.refetch()\n    },\n    tokenToDeleteDialog(value) {\n      if (!value) {\n        this.tokenToDelete = false\n      }\n    }\n  },\n  methods: {\n    async deleteToken(token) {\n      const result = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tokens/delete-token.gql'),\n        variables: {\n          id: token.id\n        }\n      })\n\n      if (result?.data?.delete_api_token?.success) {\n        this.tokenToDeleteDialog = false\n        this.handleAlert('success', 'The token has been successfully revoked.')\n        this.$apollo.queries.tokens.refetch()\n      } else {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to delete your token. Please try again. If this error persists, please contact help@prefect.io.'\n        )\n      }\n    },\n    handleAlert(type, message) {\n      this.alertType = type\n      this.alertMessage = message\n      this.alertShow = true\n    }\n  },\n  apollo: {\n    tokens: {\n      query: require('@/graphql/Tokens/api-tokens.gql'),\n      fetchPolicy: 'network-only',\n      error() {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to fetch your tokens. Please refresh the page and try again. If this error persists, please email help@prefect.io.'\n        )\n      },\n      result({ data }) {\n        this.tokens = data.api_token.map(token => {\n          return {\n            ...token,\n            created_by: token.created_by ? token.created_by.username : ''\n          }\n        })\n        this.isFetchingTokens = false\n      },\n      update: data => data\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout :show=\"!isFetchingTokens\" control-show>\n    <template #title>API Tokens</template>\n\n    <template v-if=\"hasPermission('create', 'service-account')\" #subtitle>\n      <h4 class=\"error--text\"\n        ><v-icon class=\"error--text mr-1\">error_outline</v-icon>DEPRECATED</h4\n      >\n      <div>\n        <router-link :to=\"{ name: 'service-accounts' }\">\n          Service Accounts</router-link\n        >\n        are replacing API tokens</div\n      >\n      Existing tokens will continue to work, but new ones cannot be created.\n      <br />\n    </template>\n    <template v-else-if=\"!hasPermission('create', 'service-account')\" #subtitle>\n      Manage\n      <a\n        href=\"https://docs.prefect.io/cloud/concepts/api.html#runner\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        >RUNNER</a\n      >\n      <sup>\n        <v-icon x-small>\n          open_in_new\n        </v-icon>\n      </sup>\n      and\n      <a\n        href=\"https://docs.prefect.io/cloud/concepts/api.html#tenant\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        >TENANT</a\n      >\n      <sup>\n        <v-icon x-small>\n          open_in_new\n        </v-icon>\n      </sup>\n      tokens.\n    </template>\n    <template v-else #subtitle>\n      Manage and create your\n      <a\n        href=\"https://docs.prefect.io/cloud/concepts/api.html#tenant\"\n        target=\"_blank\"\n        rel=\"noopener noreferrer\"\n        >TENANT</a\n      >\n      <sup>\n        <v-icon x-small>\n          open_in_new\n        </v-icon>\n      </sup>\n      tokens.\n    </template>\n\n    <template v-if=\"!hasPermission('create', 'service-account')\" #alerts>\n      <v-alert\n        class=\"mx-auto\"\n        border=\"left\"\n        colored-border\n        elevation=\"2\"\n        type=\"warning\"\n        tile\n        icon=\"lock\"\n        max-width=\"380\"\n      >\n        You don't have permission to manage API tokens.\n      </v-alert>\n    </template>\n\n    <!-- SEARCH (MOBILE) -->\n    <v-text-field\n      v-if=\"\n        !$vuetify.breakpoint.mdAndUp &&\n          hasPermission('create', 'service-account')\n      \"\n      v-model=\"search\"\n      class=\"rounded-0 elevation-1 mb-1\"\n      solo\n      dense\n      hide-details\n      single-line\n      placeholder=\"Search for an API Token\"\n      prepend-inner-icon=\"search\"\n      autocomplete=\"new-password\"\n    ></v-text-field>\n\n    <v-card tile>\n      <v-card-text class=\"pa-0\">\n        <div\n          v-if=\"\n            $vuetify.breakpoint.mdAndUp &&\n              hasPermission('create', 'service-account')\n          \"\n          class=\"py-1 mr-2 flex\"\n        >\n          <v-text-field\n            v-model=\"search\"\n            class=\"rounded-0 elevation-1\"\n            solo\n            dense\n            hide-details\n            single-line\n            placeholder=\"Search for an API Token\"\n            prepend-inner-icon=\"search\"\n            autocomplete=\"new-password\"\n            :style=\"{\n              'max-width': $vuetify.breakpoint.mdAndUp ? '400px' : null\n            }\"\n          ></v-text-field>\n        </div>\n\n        <!-- TOKENS TABLE -->\n        <v-data-table\n          v-if=\"hasPermission('update', 'service-account')\"\n          fixed-header\n          :headers=\"headers\"\n          :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n          :search=\"search\"\n          :items=\"tokens\"\n          :items-per-page=\"10\"\n          class=\"elevation-2 rounded-0 truncate-table\"\n          :footer-props=\"{\n            showFirstLastPage: true,\n            itemsPerPageOptions: [10, 15, 20, -1],\n            firstIcon: 'first_page',\n            lastIcon: 'last_page',\n            prevIcon: 'keyboard_arrow_left',\n            nextIcon: 'keyboard_arrow_right'\n          }\"\n          no-results-text=\" No API Tokens found. Try expanding your search?\"\n          no-data-text=\"Your team does not have any API Tokens yet.\"\n        >\n          <!-- HEADERS -->\n          <template #header.name=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.created_by=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.created=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.last_used=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.expires_at=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.scope=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n\n          <!-- TOKEN CREATED-AT TIME -->\n          <template #item.created=\"{ item }\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <span v-on=\"on\">\n                  {{ item.created ? formDate(item.created) : '' }}\n                </span>\n              </template>\n              <span>\n                {{ item.created ? formatTime(item.created) : '' }}\n              </span>\n            </v-tooltip>\n          </template>\n\n          <!-- TOKEN LAST-USED TIME -->\n          <template #item.last_used=\"{ item }\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <span v-on=\"on\">\n                  {{ item.last_used ? formDate(item.last_used) : '' }}\n                </span>\n              </template>\n              <span>\n                {{ item.last_used ? formatTime(item.last_used) : '' }}\n              </span>\n            </v-tooltip>\n          </template>\n\n          <!-- TOKEN EXPIRES-AT TIME -->\n          <template #item.expires_at=\"{ item }\">\n            {{ item.expires_at ? formatTimeRelative(item.expires_at) : '' }}\n          </template>\n\n          <!-- TOKEN ACTIONS -->\n          <template\n            v-if=\"hasPermission('delete', 'service-account')\"\n            #item.actions=\"{ item }\"\n          >\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  text\n                  fab\n                  x-small\n                  color=\"error\"\n                  v-on=\"on\"\n                  @click=\"\n                    tokenToDelete = item\n                    tokenToDeleteDialog = true\n                  \"\n                >\n                  <v-icon>delete</v-icon>\n                </v-btn>\n              </template>\n              Revoke token\n            </v-tooltip>\n          </template>\n        </v-data-table>\n      </v-card-text>\n    </v-card>\n\n    <!-- REVOKE TOKEN DIALOG -->\n    <ConfirmDialog\n      v-if=\"tokenToDelete\"\n      v-model=\"tokenToDeleteDialog\"\n      type=\"error\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      :title=\"\n        `Are you sure you want to revoke the token\n          ${tokenToDelete.name}?`\n      \"\n      confirm-text=\"Revoke\"\n      @confirm=\"deleteToken(tokenToDelete)\"\n    >\n      Once you delete this token, you will not be able to use it again to\n      interact with the Prefect Cloud API.\n    </ConfirmDialog>\n\n    <Alert\n      v-model=\"alertShow\"\n      :type=\"alertType\"\n      :message=\"alertMessage\"\n      :offset-x=\"$vuetify.breakpoint.mdAndUp ? 256 : 56\"\n    ></Alert>\n  </ManagementLayout>\n</template>\n\n<style lang=\"scss\" scoped>\na {\n  text-decoration: none;\n}\n\n.flex {\n  display: flex;\n  justify-content: flex-end;\n}\n</style>\n"
  },
  {
    "path": "src/pages/TeamSwitched.vue",
    "content": "<script>\nexport default {\n  metaInfo() {\n    return {\n      titleTemplate: '%s - Team switched'\n    }\n  }\n}\n</script>\n\n<template>\n  <div\n    class=\"team-switched\"\n    :class=\"{\n      small: $vuetify.breakpoint.sm,\n      med: $vuetify.breakpoint.mdAndUp,\n      mobile: $vuetify.breakpoint.xs\n    }\"\n  >\n    <div class=\"text py-16 px-8 rounded white--text\">\n      <div class=\"text-h4\">Team switched</div>\n      <div class=\"text-subtitle-1\">\n        It looks like you switched your team in a different tab. If you believe\n        this is an error, contact us at help@prefect.io\n      </div>\n\n      <v-btn color=\"white\" class=\"primary--text\" depressed :to=\"'/'\" exact>\n        <v-icon>arrow_back_ios</v-icon>\n        Back to the dashboard\n      </v-btn>\n    </div>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\ni {\n  text-decoration: none;\n}\n\n.team-switched {\n  background-color: var(--v-primary-base) !important;\n  background-image: url('../assets/backgrounds/gradient_background.svg') !important;\n  //   background-position: left !important;\n  //   background-repeat: no-repeat !important;\n  background-size: cover !important;\n  height: 100vh;\n\n  .text {\n    background-color: rgba(0, 0, 0, 0.2);\n    position: fixed;\n    top: 15%;\n  }\n\n  &.small {\n    .text {\n      left: 25%;\n    }\n  }\n\n  &.med {\n    .text {\n      left: 20%;\n    }\n  }\n\n  &.mobile {\n    .text {\n      left: 5%;\n    }\n  }\n}\n</style>\n"
  },
  {
    "path": "src/pages/Tutorials/FlowRun/CreatePersonalAccessTokenStep.vue",
    "content": "<script>\nexport default {\n  data() {\n    return {\n      error: false,\n      errorMessage: null,\n      loginCopied: false,\n      newPersonalAccessToken: null,\n      newTokenName: null,\n      newTokenScope: 'USER'\n    }\n  },\n  computed: {\n    loginCommand() {\n      return `prefect auth login -t ${this.newPersonalAccessToken}`\n    },\n    newTokenFormFilled() {\n      return !!this.newTokenName && !!this.newTokenScope\n    }\n  },\n  methods: {\n    clearError() {\n      this.error = false\n      this.errorMessage = null\n    },\n    copyLoginCommand() {\n      navigator.clipboard.writeText(this.loginCommand).then(() => {\n        this.loginCopied = true\n      })\n      setTimeout(() => {\n        this.loginCopied = false\n      }, 2000)\n    },\n    async createAPIToken(variables) {\n      const result = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tokens/create-api-token.gql'),\n        variables\n      })\n\n      if (\n        result?.data?.create_api_token?.id &&\n        result?.data?.create_api_token?.token\n      ) {\n        this.newPersonalAccessToken = result.data.create_api_token.token\n        this.$emit('set-token', this.newPersonalAccessToken)\n      } else {\n        this.error = true\n        this.errorMessage = 'Something went wrong when creating a token.'\n        setTimeout(() => {\n          this.clearError()\n        }, 4000)\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div v-if=\"newPersonalAccessToken\">\n      <p>\n        Excellent! You just generated a Personal Access token.\n      </p>\n      <p>\n        Let's log in to Prefect Cloud using the Prefect Command Line Interface\n        (CLI). The following command will authenticate you as a Prefect Cloud\n        user from the CLI and store your token to your local disk:\n      </p>\n      <div class=\"position-relative mb-5\">\n        <kbd class=\"pa-1 text-break\">{{ loginCommand }}</kbd>\n        <v-btn\n          class=\"position-absolute copy-button\"\n          x-small\n          @click=\"copyLoginCommand\"\n        >\n          {{ loginCopied ? 'Copied!' : 'Copy' }}\n        </v-btn>\n      </div>\n      <p>\n        When you see the words \"Login successful!\" in your command line, then\n        feel free to move on to the next step.\n      </p>\n      <p>\n        You can find and manage your personal access tokens on the\n        <router-link :to=\"'/user/tokens'\"\n          >User > Personal Access Tokens page</router-link\n        >.\n      </p>\n      <p> </p>\n    </div>\n    <div v-else>\n      <p>\n        Now let's log in to Prefect Cloud from the command line. Before we do\n        this, we'll need to generate a Personal Access token.\n      </p>\n      <p>\n        Personal Access (or <code>USER</code>) tokens are used to represent a\n        single user and to grant access to any teams or projects the user has\n        access to. You can create new tokens and manage existing tokens on the\n        <router-link :to=\"'/user/tokens'\">\n          Personal Access Tokens page\n        </router-link>\n        of the UI.\n      </p>\n      <p>\n        You can also create a new token here:\n      </p>\n\n      <v-text-field\n        v-model=\"newTokenName\"\n        single-line\n        placeholder=\"Token Name\"\n        @keyup.enter.prevent=\"\n          !newPersonalAccessToken\n            ? createAPIToken({ name: newTokenName, scope: newTokenScope })\n            : ''\n        \"\n      />\n\n      <div>\n        <v-btn\n          v-disable-read-only-user=\"\n            !newTokenFormFilled || newPersonalAccessToken !== null\n          \"\n          color=\"blue\"\n          class=\"white--text\"\n          @click=\"createAPIToken({ name: newTokenName, scope: newTokenScope })\"\n        >\n          Create\n        </v-btn>\n      </div>\n    </div>\n\n    <v-btn\n      :class=\"newPersonalAccessToken ? 'mt-6' : 'mt-9'\"\n      color=\"primary\"\n      @click=\"$emit('next')\"\n    >\n      Continue\n    </v-btn>\n\n    <v-snackbar v-model=\"error\">\n      {{ errorMessage }}\n      <v-btn color=\"error\" text @click=\"error = false\">\n        Dismiss\n      </v-btn>\n    </v-snackbar>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.copy-button {\n  bottom: 5px;\n  right: 5px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Tutorials/FlowRun/CreateProjectStep.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\n\nexport default {\n  props: {\n    complete: {\n      required: true,\n      type: Boolean\n    }\n  },\n  data() {\n    return {\n      // These are the rules for the form. A project name: must have a name,\n      // name must be less than 50 characters, name can't already be in use\n      nameRules: [\n        v => !!v || 'Name is required',\n        v => (v && v.length <= 50) || 'Name must be less than 50 characters',\n        v => {\n          if (this.projectNames && this.projectNames.length) {\n            if (this.projectNames.includes(v))\n              return 'That project name is already taken.'\n          }\n          return true\n        }\n      ],\n      projects: null,\n      projectId: null,\n      selectedProjectId: null,\n      selectedProject: null,\n      projectName: null,\n      projectDescription: null,\n      valid: false\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant']),\n    // helps us check for an existing project name\n    projectNames() {\n      if (!this.projects) return\n      return this.projects.map(project => project.name)\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    async handleProjectFormSubmit() {\n      // if the form is invalid, do nothing\n      if (!this.valid) return\n\n      try {\n        const result = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-project.gql'),\n          variables: {\n            name: this.projectName,\n            description: this.projectDescription,\n            tenantId: this.tenant.id\n          }\n        })\n        // extract the project id\n        this.projectId = result.data.create_project.id\n        // emit the result of the step to the parent\n        this.$emit('project-submitted', {\n          projectId: this.projectId,\n          projectName: this.projectName\n        })\n        this.$refs.form.reset()\n      } catch (error) {\n        // if project name already exists\n        if (error.message === 'GraphQL error: Uniqueness violation.') {\n          this.setAlert({\n            alertShow: true,\n            alertMessage:\n              'A project with this name already exists. Please try a different name.',\n            alertType: 'error'\n          })\n        } else {\n          this.setAlert({\n            alertShow: true,\n            alertMessage:\n              'Failed to create project. Please wait a few moments and try again',\n            alertType: 'error'\n          })\n        }\n\n        throw error\n      }\n    },\n    handleProjectSelect(projectId) {\n      this.selectedProject = this.projects.find(p => p.id == projectId)\n    },\n    handleProjectSubmit() {\n      this.$emit('project-submitted', {\n        projectId: this.selectedProject.id,\n        projectName: this.selectedProject.name\n      })\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.projects.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    projects: {\n      query: require('@/graphql/FirstRunWorkflow/project-names.gql'),\n      pollInterval: 5000,\n      update: data => {\n        data.project.unshift({\n          id: 'new-project',\n          name: 'New Project'\n        })\n        return data.project\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container v-intersect=\"{ handler: onIntersect }\">\n    <v-row>\n      <v-col cols=\"12\" class=\"auto pa-0\">\n        <p>\n          Projects are used to organize flows that have been deployed to Prefect\n          Cloud.\n        </p>\n        <p>\n          Every time you deploy a flow, you will need to specify a project to\n          deploy into. There are no limits on the number of projects you can\n          have, and you can always delete projects later. You can read more\n          about interacting with projects\n          <a\n            href=\"https://docs.prefect.io/cloud/concepts/projects.html\"\n            target=\"_blank\"\n            >here</a\n          >.\n        </p>\n      </v-col>\n      <v-col cols=\"12\" md=\"6\" xl=\"4\" class=\"auto pa-0\">\n        <v-select\n          data-public\n          v-model=\"selectedProjectId\"\n          :items=\"projects\"\n          class=\"mb-5\"\n          item-value=\"id\"\n          item-text=\"name\"\n          label=\"Select project\"\n          hide-details\n          single-line\n          prepend-inner-icon=\"pi-project\"\n          :menu-props=\"{ contentClass: 'custom-list-item' }\"\n          @change=\"handleProjectSelect\"\n        />\n\n        <v-form\n          v-if=\"selectedProjectId == 'new-project'\"\n          ref=\"form\"\n          v-model=\"valid\"\n          @submit=\"handleProjectFormSubmit\"\n        >\n          <v-text-field\n            v-model=\"projectName\"\n            :counter=\"50\"\n            :rules=\"nameRules\"\n            label=\"Name\"\n            required\n            @keydown.enter=\"handleProjectFormSubmit\"\n          />\n\n          <v-text-field\n            v-model=\"projectDescription\"\n            label=\"Description (optional)\"\n            @keydown.enter=\"handleProjectFormSubmit\"\n          />\n\n          <v-btn\n            v-disable-read-only-user=\"!valid || !!projectId || complete\"\n            color=\"primary\"\n            class=\"mt-6\"\n            @click=\"handleProjectFormSubmit\"\n          >\n            Submit\n          </v-btn>\n        </v-form>\n\n        <v-btn\n          v-else\n          :disabled=\"!selectedProject\"\n          color=\"primary\"\n          class=\"mt-6\"\n          @click=\"handleProjectSubmit\"\n        >\n          Next\n        </v-btn>\n      </v-col>\n    </v-row>\n  </v-container>\n</template>\n\n<style lang=\"scss\">\n/* stylelint-disable */\n.custom-list-item .v-list-item:first-child .v-list-item__title {\n  color: var(--v-primary-base);\n  font-weight: 500;\n}\n/* stylelint-enable */\n</style>\n"
  },
  {
    "path": "src/pages/Tutorials/FlowRun/DeployFlowStep.vue",
    "content": "<script>\nimport { mapActions } from 'vuex'\n\nexport default {\n  props: {\n    complete: {\n      required: true,\n      type: Boolean\n    },\n    projectId: {\n      required: true,\n      type: String\n    }\n  },\n  data() {\n    return {\n      flowId: null\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    async deployFlow() {\n      try {\n        // Import the demo flow from the JSON file\n        const flow = await import('@/assets/demo-flow/demo-flow')\n\n        // Deploy the demo flow\n        const result = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/deploy-flow.gql'),\n          variables: {\n            projectId: this.projectId,\n            serializedFlow: flow.default\n          }\n        })\n\n        this.flowId = result.data.create_flow.id\n\n        this.$emit('flow-deployed', this.flowId)\n      } catch (error) {\n        this.setAlert(\n          {\n            alertShow: true,\n            alertMessage:\n              'Failed to deploy flow. Please wait a few moments and try again',\n            alertType: 'error'\n          },\n          3000\n        )\n\n        throw error\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container>\n    <v-row v-if=\"!flowId && !complete\">\n      Now that you've successfully created a project, it's time to deploy a\n      flow! We've got a demo flow ready to go, which is stored in a Docker image\n      on our public Dockerhub repository. The code for this demo flow is shown\n      here:\n\n      <v-card flat class=\"my-6\">\n        <div\n          class=\"text-body-1 grey lighten-5 blue-grey--text text--darken-2 rounded-sm pa-3 mt-4\"\n          style=\"border: 1px solid utilGrayLight !important;\"\n        >\n          <pre class=\"code-block\">\nimport prefect\nfrom prefect import task, Flow\nfrom prefect.environments.storage import Docker\n\n\n@task(name=\"Welcome\", slug=\"welcome-task\")\ndef welcome_logger():\n    logger = prefect.context[\"logger\"]\n    with open(\"/ascii-welcome.txt\", \"r\") as f:\n        lines = \"\\n\\n\" + \"\".join(f.readlines()) + \"\\n\\n\"\n\n    logger.info(lines)\n\nstorage = Docker(\n    registry_url=\"prefecthq\",\n    image_name=\"flows\",\n    image_tag=\"welcome-flow\",\n    files={\"welcome.txt\": \"/ascii-welcome.txt\"},\n)\nf = Flow(\"Welcome Flow\", tasks=[welcome_logger], storage=storage)\n          </pre>\n        </div>\n      </v-card>\n      When you click the \"Deploy Flow\" button, we will copy the metadata\n      associated with this flow into your newly created project. The code itself\n      remains stored only in the Docker container storing this flow.\n    </v-row>\n    <v-row v-else>\n      Excellent! We've added the demo flow to your project. Next, it's time to\n      get an agent running!\n    </v-row>\n    <v-row class=\"pt-9\">\n      <v-btn\n        color=\"primary\"\n        :disabled=\"!!flowId || complete\"\n        @click=\"deployFlow\"\n      >\n        Deploy Flow\n      </v-btn>\n    </v-row>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.flow-code {\n  padding-right: 100px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Tutorials/FlowRun/FlowRunTutorial.vue",
    "content": "<script>\nimport TutorialLayout from '@/layouts/TutorialLayout'\n\nimport { mapGetters } from 'vuex'\n\nexport default {\n  components: {\n    TutorialLayout,\n    CreateProjectStep: () =>\n      import('@/pages/Tutorials/FlowRun/CreateProjectStep'),\n    CreatePersonalAccessTokenStep: () =>\n      import('@/pages/Tutorials/FlowRun/CreatePersonalAccessTokenStep'),\n    DeployFlowStep: () => import('@/pages/Tutorials/FlowRun/DeployFlowStep'),\n    RunAFlowStep: () => import('@/pages/Tutorials/FlowRun/RunAFlowStep'),\n    RunLocalAgentStep: () =>\n      import('@/pages/Tutorials/FlowRun/RunLocalAgentStep')\n  },\n  data() {\n    return {\n      state: {\n        agentToken: null,\n        flowId: null,\n        flowRunId: null,\n        projectId: null,\n        projectName: null,\n        stepNumber: 1,\n        personalAccessToken: null,\n        stepCount: 6\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('license', ['hasPermission'])\n  },\n  watch: {\n    state: {\n      handler(state) {\n        localStorage.setItem(\n          'flow_run_tutorial_workflow_state',\n          JSON.stringify(state)\n        )\n      },\n      deep: true\n    }\n  },\n  mounted() {\n    const state = localStorage.getItem('flow_run_tutorial_workflow_state')\n    if (state) {\n      this.state = JSON.parse(state)\n    }\n  },\n  // I'm not sure yet what the intended behaviour should be:\n  // for now, we only remove the local storage token if the component is\n  // destroyed, meaning it's removed from Vue through the normal\n  // lifecycle. This means if the user navigates away, this will reset,\n  // otherwise if they close the browser and come back to it, it'll persist.\n  beforeDestroy() {\n    localStorage.removeItem('flow_run_tutorial_workflow_state')\n  },\n  methods: {\n    handleAgentTokenGenerated(agentToken) {\n      this.state.agentToken = agentToken\n    },\n    handleFlowDeployed(flowId) {\n      this.state.flowId = flowId\n      this.nextStep()\n    },\n    handleFlowRunCreated(flowRunId) {\n      this.state.flowRunId = flowRunId\n    },\n    handleProjectSubmitted(project) {\n      this.state.projectId = project.projectId\n      this.state.projectName = project.projectName\n      this.nextStep()\n    },\n    handleStepClick(selectedStep, furthestStep) {\n      if (selectedStep > furthestStep) return\n      this.state.stepNumber = selectedStep\n    },\n    nextStep() {\n      this.state.stepNumber++\n    },\n    setPersonalAccessToken(token) {\n      this.state.personalAccessToken = token\n    }\n  }\n}\n</script>\n\n<template>\n  <TutorialLayout\n    :step-count=\"state.stepCount\"\n    :step-number=\"state.stepNumber\"\n    @step-click=\"handleStepClick\"\n  >\n    <template #title>\n      Running a Flow\n    </template>\n\n    <template #description>\n      <span>\n        This tutorial guides you through the process of creating a project,\n        authenticating with Prefect Cloud, and running a flow through a\n        <a\n          href=\"https://docs.prefect.io/cloud/agent/docker.html\"\n          target=\"_blank\"\n        >\n          Docker agent.\n        </a>\n        For more details, please see our\n        <a href=\"https://docs.prefect.io/cloud/\" target=\"_blank\">\n          documentation.\n        </a>\n      </span>\n    </template>\n\n    <template #alert>\n      <span\n        v-if=\"\n          !hasPermission('create', 'run') && !hasPermission('create', 'project')\n        \"\n      >\n        You don't have the required permissions to complete this tutorial.\n      </span>\n    </template>\n\n    <!-- STEP 1 -->\n    <template #tutorial-step-1-title>\n      Select a project\n    </template>\n    <template #tutorial-step-1-content>\n      <CreateProjectStep\n        :complete=\"!!state.projectId\"\n        @project-submitted=\"handleProjectSubmitted\"\n      />\n    </template>\n\n    <!-- STEP 2 -->\n    <template #tutorial-step-2-title>\n      Deploy your flow\n    </template>\n    <template #tutorial-step-2-content>\n      <DeployFlowStep\n        v-if=\"state.projectId\"\n        :complete=\"!!state.flowId\"\n        :project-id=\"state.projectId\"\n        @flow-deployed=\"handleFlowDeployed\"\n      />\n    </template>\n\n    <!-- STEP 3 -->\n    <template #tutorial-step-3-title>\n      Set up your local environment\n    </template>\n    <template #tutorial-step-3-content>\n      <p>\n        Next, we need to make sure you have a working Python 3.6+ environment\n        with the latest version of Prefect installed. You can install the latest\n        version of Prefect from the command line using the package manager of\n        your choice, such as\n        <code>pip</code> or <code>conda</code>:\n      </p>\n      <p>\n        <kbd>pip install prefect -U</kbd>\n        <br />\n        <kbd>conda install prefect -c conda-forge</kbd>\n      </p>\n      <p>\n        Prefect Cloud also requires <b>Docker</b> to build and execute flows.\n        Install Docker, Docker for Windows, or Docker for Mac\n\n        <a href=\"https://docs.docker.com/install/\" target=\"_blank\"> here</a>.\n      </p>\n      <p>\n        Once you install Docker, make sure your local Docker daemon is running.\n      </p>\n\n      <v-btn color=\"primary\" class=\"mt-6 mb-0\" @click=\"nextStep\">\n        Continue\n      </v-btn>\n    </template>\n\n    <!-- STEP 4 -->\n    <template #tutorial-step-4-title>\n      Log into Prefect Cloud from the CLI\n    </template>\n    <template #tutorial-step-4-content>\n      <CreatePersonalAccessTokenStep\n        @set-token=\"setPersonalAccessToken\"\n        @next=\"nextStep\"\n      />\n    </template>\n\n    <!-- STEP 5 -->\n    <template #tutorial-step-5-title>\n      Run a Docker agent locally\n    </template>\n    <template #tutorial-step-5-content>\n      <RunLocalAgentStep\n        :agent-token-prop=\"state.agentToken\"\n        @agent-token-generated=\"handleAgentTokenGenerated\"\n        @next=\"nextStep\"\n      />\n    </template>\n\n    <!-- STEP 6 -->\n    <template #tutorial-step-6-title>\n      Run the flow\n    </template>\n    <template #tutorial-step-6-content>\n      <RunAFlowStep\n        v-if=\"state.flowId\"\n        :flow-id=\"state.flowId\"\n        :flow-run-id=\"state.flowRunId\"\n        @flow-run-created=\"handleFlowRunCreated\"\n      />\n    </template>\n  </TutorialLayout>\n</template>\n"
  },
  {
    "path": "src/pages/Tutorials/FlowRun/RunAFlowStep.vue",
    "content": "<script>\nimport { mapActions } from 'vuex'\nimport LogsCard from '@/components/LogsCard/LogsCard'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: { LogsCard },\n  mixins: [formatTime],\n  props: {\n    flowId: {\n      required: true,\n      type: String\n    },\n    flowRunId: {\n      default: '',\n      type: String\n    }\n  },\n  data() {\n    return {\n      flowRun: null,\n      loading: false\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    displayError() {\n      this.setAlert(\n        {\n          alertShow: true,\n          alertMessage:\n            'Failed to start flow run. Please wait a few moments and try again.',\n          alertType: 'error'\n        },\n        5000\n      )\n    },\n    async run() {\n      try {\n        this.loading = true\n        const result = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-tutorial-flow-run.gql'),\n          variables: {\n            flowId: this.flowId\n          },\n          error(error) {\n            this.displayError()\n            throw error\n          }\n        })\n\n        const flowRunId = result.data.create_flow_run.id\n        this.$emit('flow-run-created', flowRunId)\n      } catch (error) {\n        this.displayError()\n        throw error\n      } finally {\n        this.loading = false\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.flowRun.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    flowRun: {\n      query: require('@/graphql/FirstRunWorkflow/flow-run.gql'),\n      variables() {\n        return {\n          id: this.flowRunId\n        }\n      },\n      skip() {\n        return !this.flowRunId\n      },\n      pollInterval: 5000,\n      update: data => data.flow_run_by_pk\n    }\n  }\n}\n</script>\n\n<template>\n  <div v-if=\"!flowRunId\" v-intersect=\"{ handler: onIntersect }\">\n    <p>\n      It's now time to run the demo flow using our locally-deployed agent!\n    </p>\n    <p>\n      When you hit the \"Run Demo Flow\" button below, a new Flow Run will be\n      created and placed in a \"Scheduled\" state. The agent you started will see\n      this scheduled work and submit it for execution on your local machine via\n      Docker. Note that your flow run will remain in a Submitted state as your\n      Agent pulls the Docker image, which can take a moment depending on your\n      connection.\n    </p>\n    <v-btn color=\"info\" large class=\"mt-3\" @click=\"run\">\n      Run Demo Flow\n    </v-btn>\n  </div>\n  <div v-else>\n    <p>\n      Success! You've started your flow run; observe below as the run starts.\n      Here are some\n      <a\n        class=\"link\"\n        href=\"https://docs.prefect.io/cloud/cloud_concepts/debug.html\"\n        target=\"_blank\"\n      >\n        common tips\n      </a>\n      <v-icon small>\n        open_in_new\n      </v-icon>\n      for debugging your flows (just in case this one doesn't succeed).\n    </p>\n    <div v-if=\"flowRun\">\n      <v-simple-table>\n        <thead>\n          <tr>\n            <th class=\"text-left\">\n              Flow Run Name\n            </th>\n            <th class=\"text-left\">\n              State\n            </th>\n            <th class=\"text-left\">\n              Start Time\n            </th>\n            <th class=\"text-left\">\n              End Time\n            </th>\n          </tr>\n        </thead>\n        <tbody>\n          <tr>\n            <td>{{ flowRun.name }}</td>\n            <td>\n              <v-icon :color=\"flowRun.state\">\n                brightness_1\n              </v-icon>\n              {{ flowRun.state }}\n            </td>\n            <td>{{ formatDateTime(flowRun.start_time) }}</td>\n            <td>{{ formatDateTime(flowRun.end_time) }}</td>\n          </tr>\n        </tbody>\n      </v-simple-table>\n\n      <div\n        style=\"\n        max-width: 100%;\n        overflow-x: scroll;\"\n      >\n        <LogsCard\n          class=\"mt-2 overflow-x-auto\"\n          entity=\"flow\"\n          :query=\"require('@/graphql/FirstRunWorkflow/flow-run.gql')\"\n          query-key=\"flow_run_by_pk\"\n          :variables=\"{ id: flowRunId }\"\n          :show-filter-description=\"false\"\n        />\n      </div>\n    </div>\n    <div v-else class=\"d-flex justify-center\" style=\"width: 100%;\">\n      <v-progress-circular indeterminate color=\"primary\" />\n    </div>\n  </div>\n</template>\n"
  },
  {
    "path": "src/pages/Tutorials/FlowRun/RunLocalAgentStep.vue",
    "content": "<script>\nimport { mapActions } from 'vuex'\n\nexport default {\n  props: {\n    agentTokenProp: {\n      default: '',\n      type: String\n    }\n  },\n  data() {\n    return {\n      agentToken: null,\n      agentTokenName: null,\n      agentTokenValidationRules: [\n        v => !!v || 'Name is required',\n        v => (v && v.length <= 50) || 'Name must be less than 50 characters'\n      ],\n      agentCommandCopied: false,\n      valid: false\n    }\n  },\n  computed: {\n    agentCommand() {\n      return `prefect agent start docker -t ${this.agentTokenProp}`\n    }\n  },\n  methods: {\n    ...mapActions('alert', ['setAlert']),\n    copyAgentCommand() {\n      navigator.clipboard.writeText(this.agentCommand).then(() => {\n        this.agentCommandCopied = true\n      })\n      setTimeout(() => {\n        this.agentCommandCopied = false\n      }, 2000)\n    },\n    async generateAgentToken() {\n      if (!this.agentTokenName) return\n\n      try {\n        const name = this.agentTokenName\n        const response = await this.$apollo.mutate({\n          mutation: require('@/graphql/Mutations/create-runner-token.gql'),\n          variables: {\n            name\n          }\n        })\n\n        this.agentToken = response.data.create_api_token.token\n        this.$emit('agent-token-generated', this.agentToken)\n      } catch (error) {\n        this.setAlert({\n          alertShow: true,\n          alertMessage: 'Failed to generate agent token; please try again.',\n          alertType: 'error'\n        })\n\n        throw error\n      }\n    }\n  }\n}\n</script>\n\n<template>\n  <div>\n    <div v-if=\"agentTokenProp\">\n      <p>\n        Excellent! Now that we've created our token, let's start a Prefect\n        Agent. This agent will immediately begin looking for scheduled work from\n        Prefect Cloud. Start your agent with the following command:\n      </p>\n      <div class=\"position-relative\">\n        <kbd class=\"pa-1 text-break\">{{ agentCommand }}</kbd>\n        <v-btn\n          class=\"position-absolute copy-button\"\n          x-small\n          @click=\"copyAgentCommand\"\n        >\n          {{ agentCommandCopied ? 'Copied!' : 'Copy' }}\n        </v-btn>\n      </div>\n      <br />\n      <p>\n        If you see the error message \"docker is not a valid agent\", you are\n        probably running an older version of Prefect Core. You can either\n        upgrade your package or alter the above command to\n        <code>prefect agent start -t TOKEN</code>\n      </p>\n    </div>\n    <div v-else>\n      Our next goal is to get a\n      <a href=\"https://docs.prefect.io/cloud/agent/docker.html\" target=\"_blank\"\n        >Docker agent</a\n      >\n      up and running. Agents are responsible for communicating with Prefect\n      Cloud and submitting your Flows for execution. Your agents will also need\n      tokens (called <code>RUNNER</code> tokens) for authenticating with Prefect\n      Cloud, and as before there is no limit to the number of tokens you can\n      create. Agent tokens can be managed on the Team > API Tokens page of the\n      UI.\n      <br />\n      <v-form ref=\"form\" v-model=\"valid\" @submit.prevent=\"generateAgentToken\">\n        <v-text-field\n          v-model=\"agentTokenName\"\n          :rules=\"agentTokenValidationRules\"\n          :counter=\"50\"\n          label=\"Agent Token Name\"\n          @keydown.enter=\"generateAgentToken\"\n        />\n      </v-form>\n      <br />\n      <v-btn color=\"primary\" :disabled=\"!valid\" @click=\"generateAgentToken\">\n        Generate Agent Token\n      </v-btn>\n    </div>\n    <v-btn color=\"primary\" class=\"mt-12\" @click=\"$emit('next')\">\n      Continue\n    </v-btn>\n  </div>\n</template>\n\n<style lang=\"scss\" scoped>\n.copy-button {\n  bottom: 5px;\n  right: 5px;\n}\n</style>\n"
  },
  {
    "path": "src/pages/Tutorials/Markdown/Universal-Deploy.md",
    "content": "# Universal Deploy\n\nThis tutorial guides you through writing a simple flow and deploying it using [Universal Deploy](https://docs.prefect.io/core/PINs/PIN-13-Universal-Deploy.html#pin-13-universal-cloud-deploys), which allows you to register a flow with Prefect Cloud and run it without configuring external storage.\n\n# Set up your local environment\n\nFirst, let's make sure that your local environment is set up to run Prefect.\n\nMake sure you have a working `Python 3.6+` environment with the latest version of Prefect installed. If Prefect is not installed, you can install the latest version from the command line using the package manager of your choice, such as `pip` or `conda`:\n\n```python\npip install prefect -U\nconda install prefect -c conda-forge\n```\n\n# Run a Flow Using Prefect Core\n\n```python\nimport prefect\nfrom prefect import task, Flow\n\n@task\ndef hello_task():\n    logger = prefect.context.get(\"logger\")\n    logger.info(\"Hello world!\")\n\nflow = Flow(\"hello-flow\", tasks=[hello_task])\n\nflow.run()\n```\n\nPaste the code above into an interactive Python REPL session. You should see the following logs after running `flow.run()` :\n\n```\n[2020-01-08 23:49:00,239] INFO - prefect.FlowRunner | Beginning Flow run for 'hello-flow'\n[2020-01-08 23:49:00,242] INFO - prefect.FlowRunner | Starting flow run.\n[2020-01-08 23:49:00,249] INFO - prefect.TaskRunner | Task 'hello_task': Starting task run...\n[2020-01-08 23:49:00,249] INFO - prefect.Task: hello_task | Hello world!\n[2020-01-08 23:49:00,251] INFO - prefect.TaskRunner | Task 'hello_task': finished task run for task with final state: 'Success'\n[2020-01-08 23:49:00,252] INFO - prefect.FlowRunner | Flow run SUCCESS: all reference tasks succeeded\n```\n\nIf you're running into issues, check that your Python environment is properly set up to run Prefect. Refer to the [Prefect Core Installation](https://docs.prefect.io/core/getting_started/installation.html) documentation for further details.\n\n# Authenticating with Prefect Cloud\n\nTo authenticate, you'll need to create an [API Key](/user/keys) and save it.\n\n- In the user menu in the top right corner go to **Account Settings -> API Keys -> Create An API Key**.\n- Copy the created key\n- Login with the Prefect CLI:\n\n```bash\nprefect auth login --key <YOUR-KEY>\n```\n\n# Creating a project\n\nProjects are used to organize flows that have been deployed to Prefect Cloud.\n\nEvery time you deploy a flow, you will need to specify a project to deploy into. There are no limits on the number of projects you can have, and you can always delete projects later. You can read more about interacting with projects [here](https://docs.prefect.io/cloud/concepts/projects.html).\n\nYou can create a project using the CLI:\n\n```bash\nprefect create project tester\n```\n\nYou can also create a project using the project selector on the dashboard page of the UI or using the API.\n\n# Deploy your flow with Universal Deploy\n\nWe're almost there! With a very slight modification to our flow code, we will be able to register our flow with Prefect Cloud and get a local agent running:\n\n```python\nimport prefect\nfrom prefect import task, Flow\n\n@task\ndef hello_task():\n    logger = prefect.context.get(\"logger\")\n    logger.info(\"Hello world!\")\n\nflow = Flow(\"hello-flow\", tasks=[hello_task])\n\nflow.register(project_name=\"tester\")\n```\n\nAnd that's it! Your flow is now registered with Prefect Cloud.\n\n# Start your agent\n\nStart your agent using the CLI:\n\n```bash\nprefect agent local start\n```\n\n# Run Your Flow In Prefect Cloud\n\nTo run your flow in Prefect Cloud, navigate to it from the `Flows` tab of the Dashboard and use the `Quick Run` button at the top of the page. This will run your flow with no additional settings.\n\nYou can use the `Run` tab on your flow page to pass parameters or context to your flow or to schedule a run for some point in the future. You can update default parameters and add or modify schedules by selecting the `Settings` tab on the flow page.\n\n**Universal Deploy and Labels**\n\nYou may have noticed that both your registered flow and your local agent have labels associated with them. Specifically, your may have noticed that your flow had a single label set to the hostname of your local machine (e.g. \"Janes-MacBook.local\") and your agent had many labels, one of which was also the hostname of your machine.\n\nThis hostname label ensures that only local agents started on this machine can execute your registered flow. Without labels, your flow might get picked up by other agents running in your infrastructure, or your locally running agent would attempt to execute other flows - potentially even flows that it can't access!\n\nLabels are a powerful feature of Prefect Cloud, providing fine control over exactly what flows your agents can execute. Keep an eye out for an upcoming tutorial that will cover running a flow with custom labels.\n"
  },
  {
    "path": "src/pages/Tutorials/Tutorials.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\nimport { parser, getRoutes } from '@/utils/markdownParser'\nimport '@/styles/md-style.scss'\nimport '@/styles/atelier-sulphurpool-light.scss'\n/* eslint-disable vue/no-v-html */\n\nexport default {\n  data() {\n    return {\n      routes: getRoutes()\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant'])\n  },\n  mounted() {\n    if (!this.$route.params?.id) {\n      this.$router.push({\n        params: { id: this.routes[0].name },\n        hash: this.routes[0].children[0].name\n      })\n    }\n  },\n  methods: {\n    mdParser(md) {\n      return parser(md)\n    },\n\n    sentenceCasing(str) {\n      return str\n        .split(' ')\n        .map(word => word.replace(word[0], word[0].toUpperCase()))\n        .join(' ')\n    }\n  }\n}\n</script>\n\n<template>\n  <v-container>\n    <v-navigation-drawer\n      :mini-variant=\"$vuetify.breakpoint.smAndDown\"\n      width=\"280\"\n      clipped\n      permanent\n      left\n      fixed\n      touchless\n      :expand-on-hover=\"$vuetify.breakpoint.smAndDown\"\n      :style=\"{ top: $vuetify.breakpoint.smAndDown ? '56px' : '64px' }\"\n    >\n      <template #prepend>\n        <v-list-item>\n          <v-list-item-action>\n            <v-icon class=\"blue--text accent-4\">\n              school\n            </v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <div class=\"font-weight-medium\">\n              Tutorials\n            </div>\n          </v-list-item-content>\n        </v-list-item>\n      </template>\n\n      <v-divider />\n\n      <v-list>\n        <v-list-group\n          v-for=\"(item, index) in routes\"\n          :key=\"index\"\n          :value=\"true\"\n          no-action\n          sub-group\n        >\n          <template #activator>\n            <v-list-item-content>\n              <v-list-item-title>{{\n                sentenceCasing(item.name.replace(/-/g, ' '))\n              }}</v-list-item-title>\n            </v-list-item-content>\n          </template>\n\n          <v-list-item\n            v-for=\"(child, i) in item.children\"\n            :key=\"i\"\n            link\n            :to=\"{\n              name: 'tutorial',\n              params: { id: child.file },\n              hash: child.name\n            }\"\n          >\n            <v-list-item-title class=\"links\">{{\n              sentenceCasing(child.name.substring(1).replace(/-/g, ' '))\n            }}</v-list-item-title>\n          </v-list-item>\n        </v-list-group>\n      </v-list>\n    </v-navigation-drawer>\n\n    <div\n      :class=\"{\n        'sm-and-down-left-padding': $vuetify.breakpoint.smAndDown,\n        'sm-and-up-left-padding': $vuetify.breakpoint.smAndUp\n      }\"\n      style=\"min-height: 100%;\"\n    >\n      <div\n        v-if=\"$route.params.id\"\n        class=\"md\"\n        v-html=\"mdParser(require(`./Markdown/${$route.params.id}.md`))\"\n      >\n      </div>\n\n      <v-fade-transition mode=\"out-in\">\n        <router-view></router-view>\n      </v-fade-transition>\n    </div>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.container {\n  background: var(--v-appForeground-base);\n}\n\n.cursor-point {\n  cursor: pointer;\n}\n\n.sm-and-up-left-padding {\n  // Match left padding with User Settings sidebar width\n  padding-left: 286px;\n  padding-right: 56px;\n}\n\n.sm-and-down-left-padding {\n  // Match left padding with collapsed User Settings sidebar width\n  padding-left: 56px;\n}\n\n// stylelint-disable\n.links {\n  font-family: Roboto, sans-serif;\n  word-wrap: break-word; /* IE 5.5-7 */\n  white-space: -moz-pre-wrap; /* Firefox 1.0-2.0 */\n  white-space: pre-wrap;\n}\n\n// stylelint-enable\n</style>\n"
  },
  {
    "path": "src/pages/UserSettings/APIKeys.vue",
    "content": "<script>\nimport { setTimeout } from 'timers'\nimport { mapGetters } from 'vuex'\nimport { pollsTenantsMixin } from '@/mixins/polling/pollsTenantsMixin'\nimport DateTime from '@/components/DateTime'\n\nimport Alert from '@/components/Alert'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ManagementLayout from '@/layouts/ManagementLayout'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    DateTime,\n    Alert,\n    ConfirmDialog,\n    ManagementLayout\n  },\n  mixins: [formatTime, pollsTenantsMixin],\n  data() {\n    return {\n      createKeyDialog: false,\n      copyKeyDialog: false,\n      //alert\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n      //data table\n      headers: [\n        {\n          text: 'Name',\n          value: 'name'\n        },\n        {\n          text: 'Created At',\n          value: 'created'\n        },\n        { text: 'Expires', value: 'expires_at' },\n        { text: 'Tenant', value: 'tenant' },\n        {\n          text: '',\n          value: 'actions',\n          align: 'right',\n          sortable: false\n        }\n      ],\n      search: null,\n      //key\n      newKey: '',\n      newKeyName: '',\n      newKeyTenant: null,\n      creatingKey: false,\n      keys: [],\n      keyCopied: false,\n      keyToDelete: false,\n      keyToDeleteDialog: false,\n      expiresAt: null,\n      label: 'Expiry Date',\n      hint: 'Leave blank for an expiry of 2100-01-01 UTC',\n      warning:\n        'You have selected a time in the past.  Your API key will have an expiry of 2100-01-01 UTC'\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['user']),\n    ...mapGetters('tenant', ['tenants', 'tenant']),\n    newKeyFormFilled() {\n      return !!this.newKeyName && !!this.newKeyTenant\n    },\n    localExpiryDate() {\n      return this.formDate('2100-01-01T00:00:00+00:00')\n    }\n  },\n\n  watch: {\n    keyToDeleteDialog(value) {\n      if (!value) {\n        this.keyToDelete = false\n      }\n    }\n  },\n  mounted() {\n    return (this.newKeyTenant = this.tenant)\n  },\n  methods: {\n    clearAlert() {\n      this.alertShow = false\n      this.alertMessage = ''\n      this.alertType = null\n    },\n    copyNewKey() {\n      var copyText = document.querySelector('#new-api-key')\n      copyText.select()\n      document.execCommand('copy')\n      this.keyCopied = true\n      setTimeout(() => {\n        this.keyCopied = false\n      }, 2000)\n    },\n    async createAPIKey(variables) {\n      this.creatingKey = true\n      const result = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tokens/create-api-key.gql'),\n        variables\n      })\n\n      if (\n        result?.data?.create_api_key?.id &&\n        result?.data?.create_api_key?.key\n      ) {\n        this.resetNewKey()\n        this.newKey = result.data.create_api_key.key\n        this.copyKeyDialog = true\n        this.$apollo.queries.keys.refetch()\n      } else {\n        this.alertShow = true\n        this.alertMessage = 'Something went wrong when creating an API key.'\n        this.alertType = 'error'\n      }\n      this.creatingKey = false\n    },\n    async deleteKey(key) {\n      const result = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tokens/delete-api-key.gql'),\n        variables: {\n          id: key.id\n        }\n      })\n      if (result?.data?.delete_api_key?.success) {\n        this.keyToDeleteDialog = false\n        this.alertShow = true\n        this.alertMessage = 'API key was successfully revoked.'\n        this.alertType = 'success'\n        this.$apollo.queries.keys.refetch()\n      } else {\n        this.alertShow = true\n        this.alertMessage = 'Something went wrong when deleting this API key.'\n        this.alertType = 'error'\n      }\n    },\n    resetNewKey() {\n      this.newKeyName = ''\n      this.newKey = ''\n      this.newKeyTenant = this.tenant\n      this.expiresAt = null\n      this.createKeyDialog = false\n      this.copyKeyDialog = false\n    }\n  },\n  apollo: {\n    keys: {\n      query: require('@/graphql/Tokens/api-keys.gql'),\n      fetchPolicy: 'network-only',\n      error() {\n        this.handleAlert(\n          'error',\n          'Something went wrong while trying to fetch your API keys. Please refresh the page and try again. If this error persists, please email help@prefect.io.'\n        )\n      },\n      result({ data }) {\n        this.keys = data.auth_api_key\n          .filter(key => key.user_id === this.user.id)\n          .map(key => {\n            const defaultTenant = this.tenants.find(\n              ({ id }) => id === key.default_tenant_id\n            )\n            return {\n              id: key.id,\n              name: key.name,\n              created_at: key.created,\n              expires: key.expires_at,\n              tenant: defaultTenant?.name,\n              user_id: key.user_id\n            }\n          })\n      },\n      update: data => data\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout show>\n    <template #title>API Keys</template>\n\n    <template #subtitle>\n      API keys are used to represent a single user, and are typically used by\n      Prefect Cloud clients (such as the Prefect Cloud CLI) to perform actions\n      within Prefect.\n    </template>\n\n    <template #cta>\n      <v-btn\n        color=\"blue\"\n        data-cy=\"create-api-key\"\n        class=\"white--text\"\n        @click=\"createKeyDialog = true\"\n      >\n        <v-icon left>\n          add\n        </v-icon>\n        Create an API key\n      </v-btn>\n    </template>\n\n    <v-text-field\n      v-if=\"!$vuetify.breakpoint.mdAndUp\"\n      v-model=\"search\"\n      solo\n      dense\n      hide-details\n      single-line\n      placeholder=\"Search for an API Key\"\n      prepend-inner-icon=\"search\"\n      autocomplete=\"new-password\"\n    ></v-text-field>\n\n    <v-card tile>\n      <v-card-text class=\"pa-0\">\n        <div v-if=\"$vuetify.breakpoint.mdAndUp\" class=\"py-1 mr-2 flex\">\n          <v-text-field\n            v-model=\"search\"\n            class=\"rounded-0 elevation-1\"\n            solo\n            dense\n            hide-details\n            single-line\n            placeholder=\"Search for an API Key\"\n            prepend-inner-icon=\"search\"\n            autocomplete=\"new-password\"\n            :style=\"{\n              'max-width': $vuetify.breakpoint.mdAndUp ? '360px' : null\n            }\"\n          ></v-text-field>\n        </div>\n\n        <v-data-table\n          fixed-header\n          class=\"elevation-2 rounded-0 truncate-table\"\n          :headers=\"headers\"\n          :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n          :search=\"search\"\n          :items=\"keys\"\n          :loading=\"$apollo.queries.keys.loading\"\n          :items-per-page=\"10\"\n          :footer-props=\"{\n            showFirstLastPage: true,\n            firstIcon: 'first_page',\n            lastIcon: 'last_page',\n            prevIcon: 'keyboard_arrow_left',\n            nextIcon: 'keyboard_arrow_right'\n          }\"\n          no-results-text=\"No API keys found. Try expanding your search?\"\n          no-data-text=\"You do not have any API keys yet.\"\n        >\n          <template #header.name=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.created=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.expires_at=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.tenant=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #item.name=\"{ item }\">\n            {{ item.name }}\n          </template>\n\n          <template #item.created=\"{ item }\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <span v-on=\"on\">\n                  {{ item.created_at ? formDate(item.created_at) : '' }}\n                </span>\n              </template>\n              <span>\n                {{ item.created_at ? formatTime(item.created_at) : '' }}\n              </span>\n            </v-tooltip>\n          </template>\n\n          <template #item.expires_at=\"{ item }\">\n            {{ item.expires ? formatTimeRelative(item.expires) : 'Never' }}\n          </template>\n          <template #item.actions=\"{ item }\">\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  text\n                  fab\n                  x-small\n                  color=\"error\"\n                  v-on=\"on\"\n                  @click=\"\n                    keyToDelete = item\n                    keyToDeleteDialog = true\n                  \"\n                >\n                  <v-icon>delete</v-icon>\n                </v-btn>\n              </template>\n              Revoke API key\n            </v-tooltip>\n          </template>\n        </v-data-table>\n      </v-card-text>\n    </v-card>\n\n    <ConfirmDialog\n      v-model=\"createKeyDialog\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      :confirm-props=\"{ 'data-cy': 'submit-new-api-key' }\"\n      :disabled=\"!newKeyFormFilled\"\n      title=\"Create an API key\"\n      confirm-text=\"Create\"\n      :loading=\"creatingKey\"\n      @cancel=\"\n        createKeyDialog = false\n        resetNewKey()\n      \"\n      @confirm=\"\n        createAPIKey({\n          user_id: user.id,\n          name: newKeyName,\n          expires_at: expiresAt,\n          tenant_id: newKeyTenant.id\n        })\n      \"\n    >\n      <v-text-field\n        v-model=\"newKeyName\"\n        class=\"mb-3\"\n        single-line\n        data-cy=\"new-api-key-name\"\n        placeholder=\"API Key Name\"\n        autofocus\n        outlined\n        dense\n      />\n      <DateTime\n        v-model=\"expiresAt\"\n        class=\"mb-3\"\n        warning=\"\n          You have selected a time in the past; as a result, your API key will have already expired.\n        \"\n        :text-field-props=\"{\n          outlined: true,\n          dense: true,\n          hint: `Leave blank to never expire this key`,\n          label: 'API Key Expiration',\n          persistentHint: true\n        }\"\n      />\n      <v-select\n        v-model=\"newKeyTenant\"\n        outlined\n        dense\n        return-object\n        label=\"Tenant\"\n        :items=\"tenants\"\n        item-text=\"name\"\n        item-value=\"id\"\n      >\n      </v-select>\n    </ConfirmDialog>\n\n    <ConfirmDialog\n      v-model=\"copyKeyDialog\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      :cancel-props=\"{ 'data-cy': 'close-api-key-dialog' }\"\n      title=\"Your key has been created\"\n      :confirm-text=\"keyCopied ? 'Copied' : 'Copy'\"\n      cancel-text=\"Close\"\n      @cancel=\"resetNewKey\"\n      @confirm=\"copyNewKey\"\n    >\n      <p>\n        Copy this key and put it in a secure place.\n        <strong>\n          You won't be able to see this key again once you close this dialog.\n        </strong>\n      </p>\n      <v-textarea\n        id=\"new-api-key\"\n        v-model=\"newKey\"\n        data-cy=\"api-key-field\"\n        data-private\n        class=\"_lr-hide\"\n        auto-grow\n        rows=\"1\"\n        readonly\n        single-line\n        outlined\n        spellcheck=\"false\"\n      />\n    </ConfirmDialog>\n\n    <ConfirmDialog\n      v-if=\"keyToDelete\"\n      v-model=\"keyToDeleteDialog\"\n      type=\"error\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      :title=\"\n        `Are you sure you want to revoke the API key\n          ${keyToDelete.name}?`\n      \"\n      confirm-text=\"Revoke\"\n      @confirm=\"deleteKey(keyToDelete)\"\n    >\n      Once you delete this key, you will not be able to use it again to interact\n      with the Prefect Cloud API.\n    </ConfirmDialog>\n\n    <Alert\n      v-model=\"alertShow\"\n      :type=\"alertType\"\n      :message=\"alertMessage\"\n      :offset-x=\"$vuetify.breakpoint.mdAndUp ? 256 : 56\"\n    ></Alert>\n  </ManagementLayout>\n</template>\n\n<style lang=\"scss\">\n.hidewidth {\n  max-width: 100%;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  width: 100%;\n}\n\n.flex {\n  display: flex;\n  justify-content: flex-end;\n}\n</style>\n"
  },
  {
    "path": "src/pages/UserSettings/Profile.vue",
    "content": "<script>\nimport moment from 'moment-timezone'\nimport { mapActions, mapGetters, mapMutations } from 'vuex'\n\nimport Alert from '@/components/Alert'\nimport ManagementLayout from '@/layouts/ManagementLayout.vue'\n\nconst ERROR_ALERT =\n  'Something went wrong while trying to update your user profile. Please try again. If this error persists, please contact help@prefect.io.'\n\nexport default {\n  components: {\n    Alert,\n    ManagementLayout\n  },\n  data() {\n    return {\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n      isUpdatingProfile: false,\n      selectedTimezone: null,\n      tzs: [\n        { text: 'Local', value: '' },\n        'UTC',\n        { divider: '-------' },\n        ...moment.tz.names()\n      ],\n      updatedFirstName: '',\n      updatedLastName: '',\n      updateError: false,\n      user: null\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['firstName', 'lastName', 'timezone']),\n    isProfileUpdatable() {\n      return (\n        this.selectedTimezone === this.timezone &&\n        this.updatedFirstName === this.firstName &&\n        this.updatedLastName === this.lastName\n      )\n    }\n  },\n  beforeMount() {\n    this.selectedTimezone = this.timezone\n    this.updatedFirstName = this.firstName\n    this.updatedLastName = this.lastName\n  },\n  methods: {\n    ...mapMutations('user', ['setUserSettings']),\n    ...mapActions('user', ['getUser']),\n    handleAlert(type, message) {\n      this.alertMessage = message\n      this.alertType = type\n      this.alertShow = true\n    },\n    async updateTZ() {\n      let settings = { timezone: this.selectedTimezone }\n\n      if (this.user) {\n        settings = { ...this.user.settings, ...settings }\n      }\n\n      this.setUserSettings(settings)\n\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/User/update-user-settings.gql'),\n          variables: {\n            input: settings\n          }\n        })\n        return true\n      } catch (error) {\n        this.handleAlert('error', ERROR_ALERT)\n        return false\n      }\n    },\n    async updateUserDetails() {\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/User/update-user-details.gql'),\n          variables: {\n            firstName: this.updatedFirstName,\n            lastName: this.updatedLastName\n          }\n        })\n        await this.getUser()\n        return true\n      } catch (error) {\n        this.handleAlert('error', ERROR_ALERT)\n        return false\n      }\n    },\n    async updateProfile() {\n      this.isUpdatingProfile = true\n\n      let updateTzSuccess = true\n      let updateNameSuccess = true\n\n      if (this.selectedTimezone !== this.timezone) {\n        updateTzSuccess = await this.updateTZ()\n      }\n\n      if (\n        this.updatedFirstName !== this.firstName ||\n        this.updatedLastName !== this.lastName\n      ) {\n        updateNameSuccess = await this.updateUserDetails()\n      }\n\n      if (updateTzSuccess && updateNameSuccess) {\n        this.handleAlert('success', 'Your profile has been updated!')\n      }\n      this.isUpdatingProfile = false\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout class=\"mt-3\">\n    <template #title>Your Profile</template>\n\n    <template #subtitle>\n      Control how your actions are displayed and how timestamps appear in\n      Prefect Cloud\n    </template>\n\n    <v-card tile max-width=\"720\" class=\"mt-6 pa-12 mx-auto\">\n      <v-card-text>\n        <v-text-field\n          v-model=\"updatedFirstName\"\n          data-cy=\"first-name\"\n          label=\"First Name\"\n          type=\"text\"\n          outlined\n          class=\"mb-6\"\n          prepend-inner-icon=\"account_circle\"\n        ></v-text-field>\n\n        <v-text-field\n          v-model=\"updatedLastName\"\n          data-cy=\"last-name\"\n          label=\"Last Name\"\n          type=\"text\"\n          outlined\n          class=\"mb-6\"\n          prepend-inner-icon=\"account_circle\"\n        ></v-text-field>\n\n        <v-autocomplete\n          data-public\n          v-model=\"selectedTimezone\"\n          :items=\"tzs\"\n          label=\"Time Zone\"\n          outlined\n          prepend-inner-icon=\"access_time\"\n          :menu-props=\"{ offsetY: true }\"\n        />\n      </v-card-text>\n      <v-card-actions>\n        <v-spacer></v-spacer>\n        <v-btn\n          id=\"updateProfileButton\"\n          data-cy=\"update-user\"\n          :disabled=\"isProfileUpdatable || isUpdatingProfile\"\n          :loading=\"isUpdatingProfile\"\n          color=\"primary darken-2\"\n          @click=\"updateProfile\"\n          >Save</v-btn\n        >\n      </v-card-actions>\n    </v-card>\n\n    <Alert\n      v-model=\"alertShow\"\n      :type=\"alertType\"\n      :message=\"alertMessage\"\n      :offset-x=\"$vuetify.breakpoint.mdAndUp ? 256 : 56\"\n    ></Alert>\n  </ManagementLayout>\n</template>\n"
  },
  {
    "path": "src/pages/UserSettings/Teams.vue",
    "content": "<script>\nimport { mapActions, mapGetters } from 'vuex'\nimport { clearCache } from '@/vue-apollo'\nimport { pollsTenantsMixin } from '@/mixins/polling/pollsTenantsMixin'\nimport { handleMembershipInvitations } from '@/mixins/membershipInvitationMixin'\nimport AcceptConfirmInputRow from '@/components/AcceptConfirmInputRow'\n\nimport ManagementLayout from '@/layouts/ManagementLayout.vue'\nimport ConfirmDialog from '@/components/ConfirmDialog'\n\nexport default {\n  components: {\n    ManagementLayout,\n    ConfirmDialog,\n    AcceptConfirmInputRow\n  },\n  mixins: [handleMembershipInvitations, pollsTenantsMixin],\n  data() {\n    return {\n      dialogRemoveUser: false,\n      handlingInvitationLoad: false,\n      headers: [\n        { text: 'Name', value: 'tenant.name', width: '35%' },\n        { text: 'URL', value: 'tenant.slug', width: '35%' },\n        { text: '', value: 'id', align: 'right', sortable: false, width: '30%' }\n      ],\n      isRemovingUser: false,\n      pendingInvitations: [],\n      removeTenant: null,\n      confirmInput: null,\n      rules: {\n        confirm: value => value == this.tenant.slug || 'Input is incorrect.',\n        required: value => !!value || 'This field is is required.'\n      }\n    }\n  },\n  computed: {\n    ...mapGetters('user', ['memberships', 'user']),\n    ...mapGetters('tenant', ['tenant', 'tenants']),\n    items() {\n      return [\n        ...this.memberships.map(m => {\n          return {\n            ...m,\n            member: true\n          }\n        }),\n        ...this.pendingInvitations\n      ]\n    },\n    isLastTenant() {\n      return this.tenants?.length === 1\n    }\n  },\n  methods: {\n    ...mapActions('tenant', ['getTenants', 'setCurrentTenant']),\n    ...mapActions('user', ['getUser']),\n    ...mapActions('alert', ['setAlert']),\n    role(item) {\n      let role\n      switch (item) {\n        case 'USER':\n          role = 'User'\n          break\n        case 'READ_ONLY_USER':\n          role = 'Restricted User'\n          break\n        case 'TENANT_ADMIN':\n          role = 'Administrator'\n          break\n        default:\n          role = ''\n          break\n      }\n      return role\n    },\n    async handleAcceptPendingInvitation(id, name, slug) {\n      this.handlingInvitationLoad = true\n      let success\n      try {\n        await this.acceptMembershipInvitation(id)\n        success = true\n      } catch (e) {\n        success = false\n      } finally {\n        this.setAlert(\n          {\n            alertShow: true,\n            alertMessage: success\n              ? `You joined ${name}... hurrah!`\n              : `Something went wrong trying to accept your invitation to ${name}... please wait a few moments and try again.`,\n            alertType: success ? 'success' : 'error',\n            alertLink: success\n              ? {\n                  name: 'dashboard',\n                  params: { tenant: slug }\n                }\n              : null,\n            linkText: success ? 'Take me to my new tenant!' : ''\n          },\n          3000\n        )\n        await this.$apollo.queries.pendingInvitations.refetch()\n        await this.getUser()\n        await this.getTenants()\n        this.handlingInvitationLoad = false\n      }\n    },\n    async handleDeclinePendingInvitation(id, name) {\n      this.handlingInvitationLoad = true\n      let success\n      try {\n        await this.declineMembershipInvitation(id)\n        success = true\n      } catch (e) {\n        success = false\n      } finally {\n        this.setAlert(\n          {\n            alertShow: true,\n            alertMessage: success\n              ? `Invitation to join ${name} declined.`\n              : `Something went wrong trying to decline your invitation to ${name}... please wait a few moments and try again.`,\n            alertType: success ? 'success' : 'error'\n          },\n          3000\n        )\n        await this.$apollo.queries.pendingInvitations.refetch()\n        await this.getUser()\n        await this.getTenants()\n        this.handlingInvitationLoad = false\n      }\n    },\n    async removeUser(removalTenant) {\n      this.isRemovingUser = true\n      const initialTenant = this.tenant\n\n      const membershipId = this.memberships.find(\n        m => m.tenant.id == removalTenant.id\n      )?.id\n\n      if (initialTenant.id !== removalTenant.id) {\n        await this.setCurrentTenant(removalTenant.slug)\n      }\n\n      let success\n\n      try {\n        await this.$apollo.mutate({\n          mutation: require('@/graphql/Tenant/delete-membership.gql'),\n          variables: { membershipId }\n        })\n        success = true\n      } catch (e) {\n        success = false\n      } finally {\n        this.setAlert(\n          {\n            alertShow: true,\n            alertMessage: success\n              ? 'You have removed yourself from this team.'\n              : 'Something went wrong while trying to leave this team. Please try again.',\n            alertType: success ? 'success' : 'error'\n          },\n          3000\n        )\n      }\n\n      if (initialTenant.id !== removalTenant.id) {\n        await this.setCurrentTenant(initialTenant.slug)\n      } else if (this.tenants[0].id === removalTenant.id) {\n        await this.setCurrentTenant(this.tenants[1].slug)\n      } else {\n        await this.setCurrentTenant(this.tenants[0].slug)\n      }\n\n      await this.getUser()\n      await this.getTenants()\n\n      this.resetRemoveUserDialog()\n    },\n    async handleSwitchTenant(tenant) {\n      this.loading = true\n\n      if (tenant.slug == this.tenant.slug) return\n\n      await this.setCurrentTenant(tenant.slug)\n\n      this.loading = false\n\n      clearCache()\n      this.$router.push({\n        name: 'dashboard',\n        params: { tenant: this.tenant.slug }\n      })\n    },\n    resetRemoveUserDialog() {\n      this.dialogRemoveUser = false\n      this.isRemovingUser = false\n      this.confirmInput = null\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.pendingInvitations.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    pendingInvitations: {\n      query: require('@/graphql/Tenant/pending-invitations-by-email.gql'),\n      variables() {\n        return {\n          email: this.user.email\n        }\n      },\n      fetchPolicy: 'network-only',\n      pollInterval: 60000,\n      update: data => data?.pendingInvitations ?? []\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout v-intersect=\"{ handler: onIntersect }\">\n    <template #title>Your Teams</template>\n\n    <template #subtitle>\n      View and manage your team memberships\n    </template>\n\n    <v-data-table\n      fixed-header\n      class=\"elevation-2 rounded-0 truncate-table\"\n      :headers=\"headers\"\n      :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n      :items=\"items\"\n      :footer-props=\"{\n        showFirstLastPage: true,\n        firstIcon: 'first_page',\n        lastIcon: 'last_page',\n        prevIcon: 'keyboard_arrow_left',\n        nextIcon: 'keyboard_arrow_right'\n      }\"\n    >\n      <template #header.name=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text.toUpperCase() }}</span>\n      </template>\n      <template #header.slug=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text.toUpperCase() }}</span>\n      </template>\n      <template #header.role=\"{ header }\">\n        <span class=\"text-subtitle-2\">{{ header.text.toUpperCase() }}</span>\n      </template>\n\n      <template #item.id=\"{item}\">\n        <AcceptConfirmInputRow\n          v-if=\"!item.member\"\n          :loading=\"handlingInvitationLoad\"\n          :tooltips=\"true\"\n          @accept=\"\n            handleAcceptPendingInvitation(\n              item.id,\n              item.tenant.name,\n              item.tenant.slug\n            )\n          \"\n          @decline=\"handleDeclinePendingInvitation(item.id, item.tenant.name)\"\n        />\n        <div style=\"padding-right: 6px;\">\n          <v-tooltip bottom\n            ><template #activator=\"{on}\"\n              ><v-btn\n                v-if=\"item.tenant.id !== tenant.id && item.member\"\n                text\n                small\n                style=\"margin-right: 14px;\"\n                color=\"primary\"\n                v-on=\"on\"\n                @click=\"handleSwitchTenant(item.tenant)\"\n                ><v-icon>swap_horiz</v-icon></v-btn\n              ></template\n            >Switch to this team</v-tooltip\n          >\n          <v-tooltip bottom\n            ><template #activator=\"{on}\"\n              ><v-btn\n                v-if=\"item.member\"\n                text\n                small\n                color=\"error\"\n                v-on=\"on\"\n                @click=\"\n                  dialogRemoveUser = true\n                  removeTenant = item.tenant\n                \"\n                ><v-icon>close</v-icon></v-btn\n              ></template\n            >Leave this team</v-tooltip\n          >\n        </div>\n        <ConfirmDialog\n          v-if=\"removeTenant\"\n          v-model=\"dialogRemoveUser\"\n          type=\"error\"\n          :title=\"\n            `Are you sure you want to remove yourself from ${removeTenant.name}?`\n          \"\n          :dialog-props=\"{ 'max-width': '600' }\"\n          :disabled=\"\n            (isLastTenant && confirmInput !== tenant.slug) || isRemovingUser\n          \"\n          :loading=\"isRemovingUser\"\n          @confirm=\"removeUser(removeTenant)\"\n          @cancel=\"resetRemoveUserDialog\"\n        >\n          <div>\n            <div class=\"red--text mb-2\"\n              >You'll no longer be able to access your run data associated with\n              {{ removeTenant.name }}.</div\n            >\n            <div v-show=\"isLastTenant\" class=\"mt-2\">\n              <div class=\"deepRed--text text-subtitle-1 font-weight-medium\">\n                This is the last team you are part of. If you remove it you will\n                not be able to log back in to Prefect Cloud.\n              </div>\n\n              <div class=\"mt-4\">\n                To confirm, type\n                <span class=\"font-weight-bold\"> your tenant URL slug </span>\n                below:\n              </div>\n\n              <v-text-field\n                v-model=\"confirmInput\"\n                autocomplete=\"off\"\n                class=\"my-1\"\n                placeholder=\"Type your tenant URL slug\"\n                single-line\n                outlined\n                color=\"primary\"\n                :rules=\"[rules.required, rules.confirm]\"\n                :loading=\"isRemovingUser\"\n              >\n              </v-text-field>\n            </div>\n          </div>\n        </ConfirmDialog>\n      </template>\n    </v-data-table>\n  </ManagementLayout>\n</template>\n"
  },
  {
    "path": "src/pages/UserSettings/Tokens.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nimport Alert from '@/components/Alert'\nimport ConfirmDialog from '@/components/ConfirmDialog'\nimport ManagementLayout from '@/layouts/ManagementLayout'\nimport { formatTime } from '@/mixins/formatTimeMixin'\n\nexport default {\n  components: {\n    Alert,\n    ConfirmDialog,\n    ManagementLayout\n  },\n  mixins: [formatTime],\n  data() {\n    return {\n      createTokenDialog: false,\n      copyTokenDialog: false,\n      //alert\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n      //data table\n      headers: [\n        {\n          text: 'Name',\n          value: 'name'\n        },\n        {\n          text: 'Created At',\n          value: 'created'\n        },\n        {\n          text: 'Last Used',\n          value: 'last_used'\n        },\n        { text: 'Expires', value: 'expires_at' },\n        {\n          text: '',\n          value: 'actions',\n          align: 'right',\n          sortable: false\n        }\n      ],\n      search: null,\n      //token\n      newPersonalAccessToken: '',\n      newTokenName: '',\n      newTokenScope: 'USER',\n      tokens: [],\n      tokenCopied: false,\n      tokenToDelete: false,\n      tokenToDeleteDialog: false,\n      expiresAt: null,\n      label: 'Expiry Date',\n      hint: 'Leave blank for an expiry of 2100-01-01 UTC',\n      warning:\n        'You have selected a time in the past.  Your token will have an expiry of 2100-01-01 UTC'\n    }\n  },\n  computed: {\n    ...mapGetters('tenant', ['role'])\n  },\n  watch: {\n    tokenToDeleteDialog(value) {\n      if (!value) {\n        this.tokenToDelete = false\n      }\n    }\n  },\n  methods: {\n    async deleteToken(token) {\n      const result = await this.$apollo.mutate({\n        mutation: require('@/graphql/Tokens/delete-token.gql'),\n        variables: {\n          id: token.id\n        }\n      })\n      if (result?.data?.delete_api_token?.success) {\n        this.tokenToDeleteDialog = false\n        this.alertShow = true\n        this.alertMessage = 'Token was successfully revoked.'\n        this.alertType = 'success'\n      } else {\n        this.alertShow = true\n        this.alertMessage = 'Something went wrong when deleting a token.'\n        this.alertType = 'error'\n      }\n    },\n    onIntersect([entry]) {\n      this.$apollo.queries.tokens.skip = !entry.isIntersecting\n    }\n  },\n  apollo: {\n    tokens: {\n      query: require('@/graphql/Tokens/user-tokens.gql'),\n      fetchPolicy: 'network-only',\n      pollInterval: 5000,\n      update: data => data.api_token\n    }\n  }\n}\n</script>\n\n<template>\n  <ManagementLayout v-intersect=\"{ handler: onIntersect }\" show>\n    <template #title>Personal Access Tokens</template>\n\n    <template #subtitle>\n      <h4 class=\"error--text\"\n        ><v-icon class=\"error--text mr-1\">error_outline</v-icon>DEPRECATED</h4\n      >\n      <div\n        >Use the\n        <router-link :to=\"{ name: 'keys' }\"> API Keys</router-link>\n        page going forward.</div\n      >\n      Existing tokens will continue to work, but new ones cannot be created.\n      <br />\n    </template>\n\n    <v-text-field\n      v-if=\"!$vuetify.breakpoint.mdAndUp\"\n      v-model=\"search\"\n      solo\n      dense\n      hide-details\n      single-line\n      placeholder=\"Search for an API Token\"\n      prepend-inner-icon=\"search\"\n      autocomplete=\"new-password\"\n    ></v-text-field>\n\n    <v-card tile>\n      <v-card-text class=\"pa-0\">\n        <div v-if=\"$vuetify.breakpoint.mdAndUp\" class=\"py-1 mr-2 flex\">\n          <v-text-field\n            v-model=\"search\"\n            class=\"rounded-0 elevation-1\"\n            solo\n            dense\n            hide-details\n            single-line\n            placeholder=\"Search for an API Token\"\n            prepend-inner-icon=\"search\"\n            autocomplete=\"new-password\"\n            :style=\"{\n              'max-width': $vuetify.breakpoint.mdAndUp ? '360px' : null\n            }\"\n          ></v-text-field>\n        </div>\n\n        <v-data-table\n          fixed-header\n          class=\"elevation-2 rounded-0 truncate-table\"\n          :headers=\"headers\"\n          :header-props=\"{ 'sort-icon': 'arrow_drop_up' }\"\n          :search=\"search\"\n          :items=\"tokens\"\n          :loading=\"$apollo.queries.tokens.loading\"\n          :items-per-page=\"10\"\n          :footer-props=\"{\n            showFirstLastPage: true,\n            firstIcon: 'first_page',\n            lastIcon: 'last_page',\n            prevIcon: 'keyboard_arrow_left',\n            nextIcon: 'keyboard_arrow_right'\n          }\"\n          no-results-text=\"No tokens found. Try expanding your search?\"\n          no-data-text=\"You do not have any personal access tokens yet.\"\n        >\n          <template #header.name=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.created=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.last_used=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #header.expires_at=\"{ header }\">\n            <span class=\"text-subtitle-2\">{{ header.text }}</span>\n          </template>\n          <template #item.name=\"{ item }\">\n            {{ item.name }}\n          </template>\n\n          <template #item.created=\"{ item }\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <span v-on=\"on\">\n                  {{ item.created ? formDate(item.created) : '' }}\n                </span>\n              </template>\n              <span>\n                {{ item.created ? formatTime(item.created) : '' }}\n              </span>\n            </v-tooltip>\n          </template>\n\n          <template #item.last_used=\"{ item }\">\n            <v-tooltip top>\n              <template #activator=\"{ on }\">\n                <span v-on=\"on\">\n                  {{ item.last_used ? formDate(item.last_used) : '' }}\n                </span>\n              </template>\n              <span>\n                {{ item.last_used ? formatTime(item.last_used) : '' }}\n              </span>\n            </v-tooltip>\n          </template>\n\n          <template #item.expires_at=\"{ item }\">\n            {{\n              item.expires_at ? formatTimeRelative(item.expires_at) : 'Never'\n            }}\n          </template>\n          <template #item.actions=\"{ item }\">\n            <v-tooltip bottom>\n              <template #activator=\"{ on }\">\n                <v-btn\n                  text\n                  fab\n                  x-small\n                  color=\"error\"\n                  v-on=\"on\"\n                  @click=\"\n                    tokenToDelete = item\n                    tokenToDeleteDialog = true\n                  \"\n                >\n                  <v-icon>delete</v-icon>\n                </v-btn>\n              </template>\n              Revoke token\n            </v-tooltip>\n          </template>\n        </v-data-table>\n      </v-card-text>\n    </v-card>\n\n    <ConfirmDialog\n      v-if=\"tokenToDelete\"\n      v-model=\"tokenToDeleteDialog\"\n      type=\"error\"\n      :dialog-props=\"{ 'max-width': '500' }\"\n      :title=\"\n        `Are you sure you want to revoke the token\n          ${tokenToDelete.name}?`\n      \"\n      confirm-text=\"Revoke\"\n      @confirm=\"deleteToken(tokenToDelete)\"\n    >\n      Once you delete this token, you will not be able to use it again to\n      interact with the Prefect Cloud API.\n    </ConfirmDialog>\n\n    <Alert\n      v-model=\"alertShow\"\n      :type=\"alertType\"\n      :message=\"alertMessage\"\n      :offset-x=\"$vuetify.breakpoint.mdAndUp ? 256 : 56\"\n    ></Alert>\n  </ManagementLayout>\n</template>\n\n<style lang=\"scss\">\n.hidewidth {\n  max-width: 100%;\n  overflow: hidden;\n  text-overflow: ellipsis;\n  width: 100%;\n}\n\n.flex {\n  display: flex;\n  justify-content: flex-end;\n}\n</style>\n"
  },
  {
    "path": "src/pages/UserSettings/UserSettings.vue",
    "content": "<script>\nimport { mapGetters } from 'vuex'\n\nexport default {\n  data() {\n    return {}\n  },\n  computed: {\n    ...mapGetters('tenant', ['tenant'])\n  },\n  watch: {},\n  mounted() {},\n  methods: {}\n}\n</script>\n\n<template>\n  <v-container>\n    <v-navigation-drawer\n      clipped\n      left\n      fixed\n      permanent\n      touchless\n      :mini-variant=\"$vuetify.breakpoint.smAndDown\"\n      :style=\"{ top: $vuetify.breakpoint.smAndDown ? '56px' : '64px' }\"\n    >\n      <template #prepend>\n        <v-list-item>\n          <v-list-item-action>\n            <v-icon class=\"blue--text accent-4\">\n              settings\n            </v-icon>\n          </v-list-item-action>\n\n          <v-list-item-content>\n            <div class=\"font-weight-medium\">\n              User\n            </div>\n          </v-list-item-content>\n        </v-list-item>\n      </template>\n\n      <v-divider />\n\n      <v-list dense>\n        <v-list-item :to=\"'/user/profile'\" ripple exact>\n          <v-list-item-action>\n            <v-icon>person</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Profile</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n        <v-list-item :to=\"{ name: 'keys' }\" ripple exact>\n          <v-list-item-action>\n            <v-icon>vpn_key</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>API Keys</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n        <v-list-item\n          data-cy=\"user-settings-personal-access-tokens\"\n          :to=\"'/user/tokens'\"\n          ripple\n          exact\n        >\n          <v-list-item-action>\n            <v-icon>sync_alt</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Personal Access Tokens</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n        <v-list-item :to=\"'/user/teams'\" ripple exact>\n          <v-list-item-action>\n            <v-icon>people</v-icon>\n          </v-list-item-action>\n          <v-list-item-content>\n            <v-list-item-title>Your Teams</v-list-item-title>\n          </v-list-item-content>\n        </v-list-item>\n      </v-list>\n    </v-navigation-drawer>\n    <div\n      :class=\"{\n        'sm-and-down-left-padding': $vuetify.breakpoint.smAndDown,\n        'sm-and-up-left-padding': $vuetify.breakpoint.smAndUp\n      }\"\n    >\n      <v-fade-transition mode=\"out-in\">\n        <router-view></router-view>\n      </v-fade-transition>\n    </div>\n  </v-container>\n</template>\n\n<style lang=\"scss\" scoped>\n.cursor-point {\n  cursor: pointer;\n}\n\n.sm-and-up-left-padding {\n  // Match left padding with User Settings sidebar width\n  padding-left: 256px;\n}\n\n.sm-and-down-left-padding {\n  // Match left padding with collapsed User Settings sidebar width\n  padding-left: 56px;\n}\n</style>\n"
  },
  {
    "path": "src/plugins/logrocket.js",
    "content": "import LogRocket from 'logrocket'\n\nconst blockedResponses = [\n  'CreateAPIToken',\n  'APITokens',\n  'CreateRunnerToken',\n  'CreateAPIKey'\n]\nconst blockedRequests = ['SetSecret']\n\nconst initializeLogrocket = () => {\n  if (\n    process.env.VUE_APP_LOG_ROCKET_PUBLIC_ID &&\n    process.env.VUE_APP_BACKEND === 'CLOUD'\n  ) {\n    LogRocket.init(process.env.VUE_APP_LOG_ROCKET_PUBLIC_ID, {\n      release: process.env.VUE_APP_RELEASE_TIMESTAMP,\n      dom: {\n        inputSanitizer: true\n      },\n      network: {\n        // Requests in the blockedRequests list\n        // will be sanitized from analytics\n        requestSanitizer: request => {\n          if (request.headers['authorization']) {\n            request.headers['authorization'] = ''\n          }\n\n          if (!request.body) return request\n          try {\n            let res = JSON.parse(request.body)\n            if (!res || !res.operationName) return request\n\n            blockedRequests.forEach(term => {\n              if (res.operationName == term) {\n                request.body = null\n              }\n            })\n          } catch (e) {\n            request.body = null\n          }\n\n          return request\n        },\n        // Responses in the blockedResponses list\n        // will be sanitized from analytics\n        responseSanitizer: response => {\n          if (!response.body) return response\n          try {\n            let res = JSON.parse(response.body)\n            if (!res || !res.data) return response\n\n            blockedResponses.forEach(term => {\n              if (res.data[term]) {\n                response.body = null\n              }\n            })\n          } catch (e) {\n            response.body = null\n          }\n          return response\n        }\n      }\n    })\n\n    LogRocket.identify('Initialized no user')\n  }\n}\n\ntry {\n  initializeLogrocket()\n} catch (e) {\n  // eslint-disable-next-line no-console\n  console.error('Failed to initialize LogRocket: ', e)\n}\n"
  },
  {
    "path": "src/plugins/okta.js",
    "content": "import Vue from 'vue'\n\n// import { OktaAuth } from '@okta/okta-auth-js'\nimport OktaVue from '@okta/okta-vue'\n\nconst { VUE_APP_PUBLIC_CLIENT_ID, VUE_APP_PUBLIC_ISSUER } = process.env\n\n// const config = new OktaAuth({\n//   clientId: VUE_APP_PUBLIC_CLIENT_ID,\n//   issuer: VUE_APP_PUBLIC_ISSUER,\n//   redirectUri: 'http://localhost:8080/login',\n//   scopes: ['openid', 'profile', 'email'],\n//   pkce: true,\n//   testing: {\n//     disableHttpsCheck: true\n//   }\n// })\n\nconst config = {\n  clientId: VUE_APP_PUBLIC_CLIENT_ID,\n  issuer: VUE_APP_PUBLIC_ISSUER,\n  redirectUri: 'http://localhost:8080/login',\n  scopes: ['openid', 'profile', 'email'],\n  pkce: true,\n  testing: {\n    disableHttpsCheck: true\n  }\n}\n\nVue.use(OktaVue, { ...config })\n\nexport default config\n"
  },
  {
    "path": "src/plugins/vuetify.js",
    "content": "import { STATE_COLORS } from '@/utils/states'\nimport Vue from 'vue'\nimport Vuetify from 'vuetify/lib'\n\n// Custom icons\nimport mrIcon from '@/components/Icons/mr.vue'\nimport NomadIcon from '@/components/Icons/Nomad.vue'\nimport PrefectIcon from '@/components/Icons/Prefect.vue'\nimport TwilioIcon from '@/components/Icons/twilio.vue'\nimport PagerDutyIcon from '@/components/Icons/PagerDuty.vue'\nimport newPagerDutyIcon from '@/components/Icons/newPagerDuty.vue'\nimport Hashicorp from '@/components/Icons/Hashicorp.vue'\n\nexport const THEME_COLORS = {\n  prefect: '#27b1ff', // prefect blue\n  primary: '#3b8dff', // primary blue\n  primaryDark: '#2580FF',\n  primaryLight: '#e0f4ff',\n  secondaryGray: '#465968',\n  secondaryGrayDark: '#1d252b',\n  secondaryGrayLight: '#edf0f3',\n  accentPink: '#fe5196',\n  accentCyan: '#2edaff',\n  accentGreen: '#07e798',\n  accentOrange: '#f77062',\n  codePink: '#da2072',\n  codeBlue: '#0073df',\n  codeBlueBright: '#004bff',\n  cloudUIPrimaryBlue: '#007acc',\n  cloudUIPrimaryDark: '#003d66',\n  cloudUIPrimaryLight: '#e0f3ff',\n  secondaryBlue: '#3b8dff',\n  tertiaryBlue: '#0076ff',\n  secondary: '#2F383F', // primary grey-light\n  accent: '#1b5da4', // accent blue\n  error: '#FF5252', // alerts error\n  info: '#2196F3', // vuetify default\n  success: '#4CAF50', // alerts success\n  warning: '#FFC107', // alerts warning\n  deepRed: '#B00000',\n  failRed: '#D50000',\n  appBackground: '#f9f9f9',\n  appForeground: '#fff',\n  navIcons: '#999',\n  utilGrayLight: '#ddd',\n  utilGrayMid: '#767676',\n  utilGrayDark: '#333'\n}\n\nexport const THEME_COLORS_ALT = {\n  appBackground: '#2a2d37',\n  appForeground: '#393e4c',\n  prefect: '#003d66',\n  primary: '#1aa3ff',\n  utilGrayLight: '#585f74',\n  utilGrayMid: '#9ea4b6',\n  utilGrayDark: '#ecedf0'\n}\n\nVue.use(Vuetify)\n\nconst CUSTOM_ICONS = {\n  mr: { component: mrIcon },\n  nomad: { component: NomadIcon },\n  prefect: { component: PrefectIcon },\n  twilio: { component: TwilioIcon },\n  pagerDuty: { component: PagerDutyIcon },\n  hashicorp: { component: Hashicorp },\n  newPagerDuty: { component: newPagerDutyIcon }\n}\n\nexport default new Vuetify({\n  icons: {\n    iconfont: 'md',\n    values: CUSTOM_ICONS\n  },\n  theme: {\n    dark: localStorage.getItem('dark_mode') === 'true',\n    options: {\n      customProperties: true\n    },\n    themes: {\n      // We'll add Core and Cloud themes here\n      light: Object.assign({}, THEME_COLORS, STATE_COLORS),\n      dark: Object.assign({}, THEME_COLORS, THEME_COLORS_ALT, STATE_COLORS)\n    }\n  }\n})\n"
  },
  {
    "path": "src/router.js",
    "content": "import Router from 'vue-router'\n\n//  Nav guards\nimport flowNavGuard from '@/middleware/flowNavGuard'\nimport multiguard from 'vue-router-multiguard'\n\nimport store from '@/store/index'\n\nexport const routes = [\n  {\n    name: 'not-found',\n    path: '/404',\n    component: () =>\n      import(/* webpackChunkName: \"not-found\" */ '@/pages/NotFoundPage.vue')\n  },\n  {\n    name: 'api',\n    path: '/:tenant?/api',\n    component: () =>\n      import(\n        /* webpackChunkName: \"interactive-api\" */ '@/pages/InteractiveAPI/InteractiveAPI.vue'\n      )\n  },\n  {\n    name: 'help',\n    path: '/help',\n    component: () =>\n      import(/* webpackChunkName: \"support\" */ '@/pages/Support.vue')\n  },\n  {\n    name: 'project',\n    path: '/:tenant?/project/:id',\n    component: () =>\n      import(\n        /* webpackChunkName: \"project\" */ '@/pages/Dashboard/Dashboard.vue'\n      )\n  },\n  {\n    name: 'flow',\n    path: '/:tenant?/flow/:id',\n    component: () =>\n      import(/* webpackChunkName: \"flow\" */ '@/pages/Flow/Flow.vue'),\n    beforeEnter: multiguard([flowNavGuard])\n  },\n  {\n    name: 'flow-run',\n    path: '/:tenant?/flow-run/:id',\n    component: () =>\n      import(/* webpackChunkName: \"flow-run\" */ '@/pages/FlowRun/FlowRun.vue')\n  },\n  {\n    name: 'task',\n    path: '/:tenant?/task/:id',\n    component: () =>\n      import(/* webpackChunkName: \"task\" */ '@/pages/Task/Task.vue')\n  },\n  {\n    name: 'task-run',\n    path: '/:tenant?/task-run/:id',\n    component: () =>\n      import(/* webpackChunkName: \"task-run\" */ '@/pages/TaskRun/TaskRun.vue')\n  },\n  // --------------------------- //\n  //\n  // Team settings\n  //\n  // --------------------------- //\n  {\n    name: 'team',\n    path: '/team',\n    component: () =>\n      import(\n        /* webpackChunkName: \"team-settings\" */ '@/pages/TeamSettings/TeamSettings.vue'\n      ),\n    redirect: { name: 'members' },\n    children: [\n      {\n        name: 'projects',\n        path: 'projects',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--projects\" */ '@/pages/TeamSettings/Projects.vue'\n          )\n      },\n      {\n        name: 'actions',\n        path: 'actions',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--actions\" */ '@/pages/TeamSettings/Actions.vue'\n          )\n      },\n      {\n        name: 'flow-groups',\n        path: 'flow-groups',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--flow-groups\" */ '@/pages/TeamSettings/FlowGroups.vue'\n          )\n      },\n      {\n        name: 'flow-concurrency',\n        path: 'flow-concurrency',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--flow-concurrency\" */ '@/pages/TeamSettings/FlowConcurrency.vue'\n          )\n      },\n      {\n        name: 'task-concurrency',\n        path: 'task-concurrency',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--task-concurrency\" */ '@/pages/TeamSettings/TaskConcurrency.vue'\n          )\n      },\n      {\n        name: 'members',\n        path: 'members',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--members\" */ '@/pages/TeamSettings/Members.vue'\n          )\n      },\n      {\n        name: 'roles',\n        path: 'roles',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--members\" */ '@/pages/TeamSettings/Roles.vue'\n          )\n      },\n      {\n        name: 'service-accounts',\n        path: 'service-accounts',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--service-accounts\" */ '@/pages/TeamSettings/Service-Accounts.vue'\n          )\n      },\n      {\n        name: 'kv',\n        path: 'kv',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--kv\" */ '@/pages/TeamSettings/KV.vue'\n          )\n      },\n      {\n        name: 'secrets',\n        path: 'secrets',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--secrets\" */ '@/pages/TeamSettings/Secrets.vue'\n          )\n      },\n      {\n        name: 'cloud-hooks',\n        path: 'cloud-hooks',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--cloud-hooks\" */ '@/pages/TeamSettings/CloudHooks.vue'\n          )\n      },\n      {\n        name: 'tokens',\n        path: 'tokens',\n        component: () =>\n          import(\n            /* webpackChunkName: \"team-settings--tokens\" */ '@/pages/TeamSettings/Tokens.vue'\n          )\n      }\n    ]\n  },\n  // --------------------------- //\n  //\n  // User Settings\n  //\n  // --------------------------- //\n  {\n    name: 'user',\n    path: '/user',\n    component: () =>\n      import(\n        /* webpackChunkName: \"user-settings\" */ '@/pages/UserSettings/UserSettings.vue'\n      ),\n    redirect: { name: 'profile' },\n    children: [\n      {\n        name: 'profile',\n        path: 'profile',\n        component: () =>\n          import(\n            /* webpackChunkName: \"user-settings--profile\" */ '@/pages/UserSettings/Profile.vue'\n          )\n      },\n      {\n        name: 'user-tokens',\n        path: 'tokens',\n        component: () =>\n          import(\n            /* webpackChunkName: \"user-settings--tokens\" */ '@/pages/UserSettings/Tokens.vue'\n          )\n      },\n      {\n        name: 'keys',\n        path: 'keys',\n        component: () =>\n          import(\n            /* webpackChunkName: \"user-settings--keys\" */ '@/pages/UserSettings/APIKeys.vue'\n          )\n      },\n      {\n        name: 'teams',\n        path: 'teams',\n        component: () =>\n          import(\n            /* webpackChunkName: \"user-settings--teams\" */ '@/pages/UserSettings/Teams.vue'\n          )\n      }\n    ]\n  },\n  // ---------------------------//\n  //\n  // Calendar\n  //\n  // ----------------------------//\n  {\n    name: 'calendar',\n    path: '/:tenant?/calendar',\n    component: () =>\n      import(\n        /* webpackChunkName: \"calendar\" */ '@/pages/Calendar/Calendar-View'\n      )\n  },\n  // ---------------------------//\n  //\n  // Agents\n  //\n  // ----------------------------//\n  {\n    name: 'agents',\n    path: '/:tenant?/agent',\n    component: () =>\n      import(/*webpackChunkName: \"agents\" */ '@/pages/Agents/Agents')\n  },\n  {\n    name: 'agent',\n    path: '/:tenant?/agent/:id',\n    component: () =>\n      import(/* webpackChunkName: \"agent\" */ '@/pages/Agents/AgentPage.vue')\n  },\n  // ---------------------------//\n  //\n  // Integrations\n  //\n  // ----------------------------//\n  {\n    name: 'pagerduty',\n    path: '/:tenant?/pagerduty/:config?',\n    props: route => ({ pdData: route.query.config }),\n    beforeEnter(to, from, next) {\n      if (to?.query?.config) next()\n      else next('/')\n    },\n    component: () =>\n      import(\n        /* webpackChunkName: \"pagerduty\" */ '@/pages/Integrations/PagerDuty.vue'\n      )\n  },\n  // --------------------------- //\n  //\n  // Onboarding\n  //\n  // --------------------------- //\n  {\n    path: '/:tenant?/welcome',\n    component: () =>\n      import(\n        /* webpackChunkName: \"onboard\" */ '@/pages/Onboard/Onboard-Page.vue'\n      ),\n    children: [\n      {\n        name: 'welcome',\n        path: '',\n        component: () =>\n          import(\n            /* webpackChunkName: \"onboard--welcome\" */ '@/pages/Onboard/Welcome.vue'\n          )\n      },\n      {\n        name: 'name-team',\n        path: 'name-team',\n        component: () =>\n          import(\n            /* webpackChunkName: \"onboard--name-team\" */ '@/pages/Onboard/NameTeam.vue'\n          )\n      },\n      {\n        name: 'onboard-resources',\n        path: 'resources',\n        component: () =>\n          import(\n            /* webpackChunkName: \"onboard--resources\" */ '@/pages/Onboard/Resources.vue'\n          )\n      },\n      {\n        name: 'accept',\n        path: 'accept',\n        component: () =>\n          import(\n            /* webpackChunkName: \"accept\" */ '@/pages/Onboard/AcceptInvitationPage.vue'\n          )\n      }\n    ]\n  },\n  // --------------------------- //\n  //\n  // Plans\n  //\n  // --------------------------- //\n  {\n    name: 'plans',\n    path: '/plans',\n    component: () => import(/* webpackChunkName: \"plans\" */ '@/pages/Plans.vue')\n  },\n  // --------------------------- //\n  //\n  // Login\n  //\n  // --------------------------- //\n  {\n    name: 'login',\n    path: '/login',\n    redirect: { name: 'sign-in' },\n    component: () =>\n      import(/* webpackChunkName: \"Auth\" */ '@/pages/Auth/Auth.vue'),\n    children: [\n      {\n        name: 'sign-in',\n        path: '',\n        component: () =>\n          import(/* webpackChunkName: \"login\" */ '@/pages/Auth/SignIn.vue')\n      },\n      {\n        name: 'sign-up',\n        path: 'sign-up',\n        component: () =>\n          import(/* webpackChunkName: \"sign-up\" */ '@/pages/Auth/SignUp.vue')\n      },\n      {\n        name: 'forgot-password',\n        path: 'forgot-password',\n        component: () =>\n          import(\n            /* webpackChunkName: \"forgot-password\" */ '@/pages/Auth/ForgotPassword.vue'\n          )\n      }\n    ]\n  },\n  {\n    name: 'logout',\n    path: '/logout',\n    component: () =>\n      import(/* webpackChunkName: \"Auth\" */ '@/pages/Auth/Logout.vue')\n  },\n  {\n    path: '/accept',\n    redirect: 'welcome/accept'\n  },\n  // --------------------------- //\n  //\n  // Tutorials\n  //\n  // --------------------------- //\n  {\n    name: 'tutorial',\n    path: '/tutorial/:id?',\n    component: () =>\n      import(\n        /* webpackChunkName: \"tutorials\" */ '@/pages/Tutorials/Tutorials.vue'\n      )\n  },\n  {\n    name: 'notifications',\n    path: '/notifications',\n    component: () =>\n      import(\n        /* webpackChunkName: \"notifications\" */ '@/pages/Notifications/Notifications.vue'\n      )\n  },\n  {\n    name: 'getting-started',\n    path: '/getting-started',\n    component: () =>\n      import(\n        /* webpackChunkName: \"getting-started\" */ '@/pages/GettingStarted/GettingStarted.vue'\n      )\n  },\n  {\n    name: 'admin',\n    path: '/admin',\n    redirect: { name: 'account' },\n    component: () =>\n      import(/* webpackChunkName: \"admin\" */ '@/pages/Admin/Admin.vue'),\n    children: [\n      {\n        name: 'account',\n        path: 'account',\n        component: () =>\n          import(\n            /* webpackChunkName: \"admin--account\" */ '@/pages/Admin/Account/Account.vue'\n          )\n      },\n      {\n        name: 'admin-teams',\n        path: 'teams',\n        component: () =>\n          import(\n            /* webpackChunkName: \"admin--teams\" */ '@/pages/Admin/Teams/Teams.vue'\n          ),\n        redirect: { name: 'overview' },\n        children: [\n          {\n            name: 'overview',\n            path: '',\n            component: () =>\n              import(\n                /* webpackChunkName: \"admin--teams-overview\" */ '@/pages/Admin/Teams/TeamsOverview.vue'\n              )\n          },\n          {\n            name: 'new',\n            path: 'new',\n            component: () =>\n              import(\n                /* webpackChunkName: \"admin--new-team\" */ '@/pages/Admin/Teams/NewTeam.vue'\n              )\n          }\n        ]\n      }\n    ]\n  },\n  {\n    name: 'team-switched',\n    path: '/team-switched',\n    component: () =>\n      import(/* webpackChunkName: \"team-switched\" */ '@/pages/TeamSwitched.vue')\n  },\n  {\n    name: 'access-denied',\n    path: '/access-denied',\n    component: () =>\n      import(/* webpackChunkName: \"access-denied\" */ '@/pages/AccessDenied.vue')\n  },\n  {\n    name: 'dashboard',\n    alias: '/',\n    path: '/:tenant?',\n    component: () =>\n      import(\n        /* webpackChunkName: \"dashboard\" */ '@/pages/Dashboard/Dashboard.vue'\n      )\n  },\n  {\n    path: '*',\n    redirect: '404'\n  }\n]\n\nfunction getElementPosition(el) {\n  const docEl = document.documentElement\n  const docRect = docEl.getBoundingClientRect()\n  const elRect = el.getBoundingClientRect()\n  return {\n    x: elRect.left - docRect.left,\n    y: elRect.top - docRect.top\n  }\n}\n\nfunction scrollToHash(to) {\n  const targetElement = document.querySelector(to.hash)\n\n  if (targetElement) {\n    let elPos = getElementPosition(targetElement),\n      elRect = targetElement.getBoundingClientRect()\n\n    let position =\n      elRect.height > window.innerHeight\n        ? elPos.y\n        : elPos.y - (window.innerHeight - elRect.height) / 2\n\n    return window.scrollTo({\n      top: position,\n      behavior: 'smooth'\n    })\n  }\n}\n\nexport const createRouter = () => {\n  const router = new Router({\n    mode: 'history',\n    base: window.prefect_ui_settings?.base_url || '',\n    routes,\n    scrollBehavior(to) {\n      if (to.hash) {\n        scrollToHash(to)\n      }\n    }\n  })\n\n  router.beforeEach((to, from, next) => {\n    if (\n      'tenant' in to?.params &&\n      !to?.params?.tenant &&\n      store.getters['tenant/tenant']?.slug\n    ) {\n      return next({\n        name: to.name,\n        replace: true,\n        params: { ...to.params, tenant: store.getters['tenant/tenant'].slug },\n        query: to.query\n      })\n    } else next()\n  })\n\n  return router\n}\n"
  },
  {
    "path": "src/store/agent/index.js",
    "content": "import moment from '@/utils/moment'\n\n//helper functions for sorting\n\nconst agentHealth = agent => {\n  if (agent.last_queried) {\n    const secondsSinceLastQuery = moment().diff(\n      moment(agent.last_queried),\n      'seconds'\n    )\n    agent.secondsSinceLastQuery = secondsSinceLastQuery\n    agent.status =\n      secondsSinceLastQuery < 60 * state.thresholds.stale\n        ? 'healthy'\n        : secondsSinceLastQuery < 60 * state.thresholds.unhealthy\n        ? 'stale'\n        : 'unhealthy'\n  } else {\n    agent.status = 'unhealthy'\n  }\n  return agent\n}\n\nconst state = {\n  thresholds: {\n    // Time before an agent becomes stale\n    stale: 5, // minutes since last query\n    // Time before an agent becomes unhealthy\n    unhealthy: 720 // minutes since last query,\n  },\n  agents: null,\n  sortedAgents: null,\n  sorting: true,\n  flowRuns: null\n}\n\nconst getters = {\n  staleThreshold(state) {\n    return state.thresholds.stale\n  },\n  unhealthyThreshold(state) {\n    return state.thresholds.unhealthy\n  },\n  agents(state) {\n    return state.agents\n  },\n  sortedAgents(state) {\n    return state.sortedAgents\n  },\n  agent: state => id => {\n    return state.agents?.filter(agent => agent.id === id)[0]\n  },\n  sortedAgent: state => id => {\n    return state.sortedAgents?.filter(agent => agent.id === id)[0]\n  },\n  sorting(state) {\n    return state.sorting\n  }\n}\n\nconst mutations = {\n  setSortedAgents(state, agents) {\n    if (!agents) {\n      state.sortedAgents = null\n      state.agents = []\n      return\n    }\n\n    const healthyList = []\n    const staleList = []\n    const oldList = []\n    agents.forEach(agent => {\n      agentHealth(agent)\n      if (agent.status === 'healthy') {\n        healthyList.push(agent)\n      } else if (agent.status === 'stale') {\n        staleList.push(agent)\n      } else {\n        oldList.push(agent)\n      }\n    })\n    state.agents = agents\n    healthyList.sort((a, b) => a.id.localeCompare(b.id))\n    oldList.sort((a, b) => a.secondsSinceLastQuery - b.secondsSinceLastQuery)\n    const fullList = [...healthyList, ...staleList, ...oldList]\n    state.sortedAgents = fullList\n    state.sorting = false\n  }\n}\n\nexport default {\n  getters,\n  mutations,\n  state,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/store/alert/index.js",
    "content": "import uniqueId from 'lodash/uniqueId'\n\nconst state = {\n  alert: {\n    alertShow: false,\n    alertMessage: '',\n    alertType: null,\n    alertLink: null,\n    linkText: '',\n    alertCopy: ''\n  },\n  notifications: [],\n  notificationTimeouts: {}\n}\n\nconst getters = {\n  getAlert(state) {\n    return state.alert\n  },\n  notifications(state) {\n    return state.notifications\n  },\n  notificationTimeouts(state) {\n    return state.notificationTimeouts\n  }\n}\n\nconst mutations = {\n  setAl(state, alert) {\n    state.alert = alert\n  },\n  setEmpty(state) {\n    state.alert = {\n      alertShow: false,\n      alertMessage: '',\n      alertType: null,\n      alertLink: null,\n      linkText: '',\n      alertCopy: ''\n    }\n  },\n  setNotifications(state, notifications = []) {\n    state.notifications = notifications\n  },\n  setNotificationTimeout(state, { id, timeoutId }) {\n    clearTimeout(state['notificationTimeouts'][id])\n    state.notificationTimeouts[id] = timeoutId\n  }\n}\n\nconst actions = {\n  setAlert({ commit }, alert, timeout = 6000) {\n    commit('setAl', alert)\n    setTimeout(commit, timeout, 'setEmpty')\n  },\n  addNotification({ getters, commit, dispatch }, notification) {\n    const id = uniqueId('notification-')\n    const notifications = [...getters['notifications']]\n    notifications.push({ id: id, ...notification })\n\n    commit('setNotifications', notifications)\n\n    if (notification?.timeout) {\n      const timeoutId = setTimeout(() => {\n        dispatch('dismissNotification', { id })\n      }, notification.timeout)\n\n      commit('setNotificationTimeout', { id, timeoutId })\n    }\n\n    return id\n  },\n  dismissNotification({ getters, commit }, { id }) {\n    const notifications = [...getters['notifications']]\n    const index = notifications.findIndex(n => n.id == id)\n\n    if (index > -1) {\n      notifications.splice(index, 1)\n\n      commit('setNotifications', notifications)\n    }\n  },\n  updateNotification({ getters, commit, dispatch }, { id, notification }) {\n    const notifications = [...getters['notifications']]\n    const index = notifications.findIndex(n => n.id == id)\n\n    if (index > -1) {\n      notifications[index] = {\n        ...notifications[index],\n        ...notification\n      }\n\n      commit('setNotifications', notifications)\n\n      if (notification.timeout) {\n        const timeoutId = setTimeout(() => {\n          dispatch('dismissNotification', { id })\n        }, notification.timeout)\n\n        commit('setNotificationTimeout', { id: id, timeoutId })\n      }\n    }\n  }\n}\n\nexport default {\n  getters,\n  mutations,\n  state,\n  actions,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/store/api/index.js",
    "content": "import { fallbackApolloClient } from '@/vue-apollo'\nimport LogRocket from 'logrocket'\n\nconst SERVER_KEY = `${process.env.VUE_APP_RELEASE_TIMESTAMP}_server_url`\n\nconst maxRetries = 3\n\nconst state = {\n  backend: process.env.VUE_APP_BACKEND || 'SERVER',\n  connected: true,\n  connectionMessage: null,\n  connectionTimeout: null,\n  coreVersion: null,\n  releaseTimestamp: null,\n  apiMode: null,\n  cloudUrl: process.env.VUE_APP_CLOUD_URL,\n  retries: 0,\n  serverUrl:\n    localStorage.getItem(SERVER_KEY) ||\n    window.prefect_ui_settings?.server_url ||\n    process.env.VUE_APP_SERVER_URL,\n  version: null\n}\n\nconst getters = {\n  backend(state) {\n    return state.backend\n  },\n  apiMode(state) {\n    return state.apiMode\n  },\n  connected(state) {\n    return state.connected\n  },\n  connecting(state) {\n    return !state.connected && state.retries < maxRetries\n  },\n  connectionMessage(state) {\n    return state.connectionMessage\n  },\n  connectionTimeout(state) {\n    return state.connectionTimeout\n  },\n  isCloud(state) {\n    return state.backend === 'CLOUD'\n  },\n  isServer(state) {\n    return state.backend === 'SERVER'\n  },\n  releaseTimestamp(state) {\n    return state.releaseTimestamp\n  },\n  cloudUrl(state) {\n    return state.cloudUrl\n  },\n  retries(state) {\n    return state.retries\n  },\n  serverUrl(state) {\n    return state.serverUrl\n  },\n  url(state) {\n    switch (state.backend) {\n      case 'CLOUD':\n        return state.cloudUrl\n      case 'SERVER':\n        return state.serverUrl\n      default:\n        return null\n    }\n  },\n  version(state) {\n    return state.version\n  },\n  coreVersion(state) {\n    return state.coreVersion\n  }\n}\n\nconst mutations = {\n  setBackend(state, backend) {\n    if (backend !== 'CLOUD' && backend !== 'SERVER') {\n      throw new Error('Invalid backend')\n    }\n    state.backend = backend\n  },\n  unsetBackend(state) {\n    state.backend = null\n  },\n  setConnected(state, connected) {\n    if (typeof connected !== 'boolean') {\n      throw new Error('Invalid connected state - connected should be a boolean')\n    }\n    state.connected = connected\n  },\n  setConnectionMessage(state, message) {\n    state.connectionMessage = message\n  },\n  unsetConnectionMessage(state) {\n    state.connectionMessage = null\n  },\n  setConnectionTimeout(state, timeout) {\n    state.connectionTimeout = timeout\n  },\n  unsetConnectionTimeout(state) {\n    clearTimeout(state.connectionTimeout)\n    state.connectionTimeout = null\n  },\n  setReleaseTimestamp(state, timestamp) {\n    state.releaseTimestamp = timestamp\n  },\n  setApiMode(state, apiMode) {\n    if (apiMode && apiMode !== 'normal' && apiMode !== 'maintenance') {\n      throw new Error('Unexpected api mode')\n    }\n    state.apiMode = apiMode\n  },\n  unsetReleaseTimetamp(state) {\n    state.releaseTimestamp = null\n  },\n  setRetries(state, retries) {\n    state.retries = retries\n  },\n  setServerUrl(state, url) {\n    state.serverUrl = url\n    localStorage.setItem(SERVER_KEY, url)\n  },\n  unsetServerUrl(state) {\n    state.serverUrl = null\n    localStorage.removeItem(SERVER_KEY)\n  },\n  setVersion(state, version) {\n    state.version = version\n  },\n  unsetVersion(state) {\n    state.version = null\n  },\n  setCoreVersion(state, version) {\n    state.coreVersion = version\n  },\n  unsetCoreVersion(state) {\n    state.coreVersion = null\n  }\n}\n\nconst actions = {\n  async getApi({ commit, dispatch }) {\n    try {\n      const { data } = await fallbackApolloClient.query({\n        query: require('@/graphql/api.gql'),\n        fetchPolicy: 'no-cache'\n      })\n      commit('setReleaseTimestamp', data.api.release_timestamp)\n      commit('setVersion', data.api.version)\n      commit('setCoreVersion', data.api.core_version)\n      commit('setConnected', true)\n      commit('setApiMode', data.api.mode)\n    } catch (error) {\n      commit('unsetReleaseTimetamp')\n      commit('unsetVersion')\n      commit('unsetCoreVersion')\n      commit('setConnected', false)\n\n      LogRocket.captureException(error, {\n        extra: {\n          pageName: 'API Store',\n          stage: 'getApi'\n        }\n      })\n    }\n\n    dispatch('monitorConnection')\n  },\n  async monitorConnection({ getters, commit }) {\n    commit('unsetConnectionTimeout')\n\n    const monitorConnection = async () => {\n      if (getters['retries'] >= maxRetries) {\n        commit('setRetries', 0)\n      }\n      commit('setRetries', getters['retries'] + 1)\n\n      try {\n        const { data } = await fallbackApolloClient.query({\n          query: require('@/graphql/api.gql'),\n          fetchPolicy: 'network-only',\n          errorPolicy: 'none'\n        })\n        if (data) {\n          commit('setReleaseTimestamp', data.api.release_timestamp)\n          commit('setVersion', data.api.version)\n          commit('setConnectionMessage', 'Connected')\n          commit('setRetries', 0)\n          commit('setConnected', true)\n          commit('setApiMode', data.api.mode)\n        } else {\n          throw new Error('no data returned from api query')\n        }\n      } catch (e) {\n        commit('setConnectionMessage', e.toString())\n        commit('setConnected', false)\n      } finally {\n        const timeout = setTimeout(\n          monitorConnection,\n          getters['retries'] >= maxRetries || getters['connected']\n            ? 10000\n            : 3000\n        )\n        commit('setConnectionTimeout', timeout)\n      }\n    }\n\n    monitorConnection()\n  },\n  async setServerUrl({ commit }, url) {\n    commit('setServerUrl', url)\n  },\n  async switchBackend({ commit, dispatch, rootGetters }, backend) {\n    commit('setBackend', backend)\n    commit('tenant/unsetTenant', null, { root: true })\n    commit('tenant/unsetTenants', null, { root: true })\n\n    if (backend == 'CLOUD') {\n      await dispatch('auth/authenticate', null, { root: true })\n      await dispatch('auth/authorize', null, { root: true })\n      await dispatch('user/getUser', null, { root: true })\n    }\n\n    await dispatch('getApi')\n    await dispatch('tenant/getTenants', null, { root: true })\n\n    if (backend == 'SERVER') {\n      commit('tenant/setDefaultTenant', rootGetters['tenant/tenants']?.[0], {\n        root: true\n      })\n    }\n\n    if (rootGetters['tenant/defaultTenant']?.slug) {\n      await dispatch(\n        'tenant/setCurrentTenant',\n        rootGetters['tenant/defaultTenant']?.slug,\n        { root: true }\n      )\n    }\n\n    dispatch('monitorConnection')\n  }\n}\n\nexport default {\n  getters,\n  mutations,\n  state,\n  actions,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/store/auth/index.js",
    "content": "import jwt_decode from 'jwt-decode'\n\nconst state = {\n  authorizationToken: null,\n  authorizationTokenExpiry: null,\n  idToken: null,\n  idTokenExpiry: null,\n  refreshToken: null,\n  refreshTokenExpiry: null,\n  user: null\n}\n\nconst getters = {\n  isAuthenticated(state) {\n    return !!state.idToken && new Date().getTime() < state.idTokenExpiry\n  },\n  isAuthorized(state) {\n    return (\n      !!state.authorizationToken &&\n      new Date().getTime() < state.authorizationTokenExpiry\n    )\n  },\n  user(state) {\n    return state.user\n  },\n  idToken(state) {\n    return state.idToken\n  },\n  idTokenExpiry(state) {\n    return state.idTokenExpiry\n  },\n  refreshToken(state) {\n    return state.refreshToken\n  },\n  refreshTokenExpiry(state) {\n    return state.refreshTokenExpiry\n  },\n  authorizationToken(state) {\n    return state.authorizationToken\n  },\n  authorizationTokenExpiry(state) {\n    return state.authorizationTokenExpiry\n  }\n}\n\nconst mutations = {\n  error(state, error) {\n    state.error = error\n  },\n  user(state, user) {\n    if (typeof user !== 'object' || user == null)\n      throw new TypeError(`user must be an object, got ${typeof user} instead`)\n\n    state.user = user\n  },\n  unsetUser(state) {\n    state.user = null\n  },\n  accessToken(state, accessToken) {\n    try {\n      jwt_decode(accessToken)\n    } catch (e) {\n      throw new TypeError(\n        `accessToken must be a valid JWT, got a malformed one instead. ${e}`\n      )\n    }\n\n    state.accessToken = accessToken\n  },\n  idToken(state, idToken) {\n    try {\n      jwt_decode(idToken)\n    } catch (e) {\n      throw new TypeError(\n        `idToken must be a valid JWT, got a malformed one instead. ${e}`\n      )\n    }\n\n    state.idToken = idToken\n  },\n  unsetIdToken(state) {\n    state.idToken = null\n  },\n  idTokenExpiry(state, idTokenExpiry) {\n    if (typeof idTokenExpiry !== 'number' || idTokenExpiry == null)\n      throw new TypeError(\n        `idTokenExpiry must be an number, got ${typeof idTokenExpiry} instead`\n      )\n\n    state.idTokenExpiry = idTokenExpiry\n  },\n  unsetIdTokenExpiry(state) {\n    state.idTokenExpiry = null\n  },\n  authorizationToken(state, authorizationToken) {\n    try {\n      jwt_decode(authorizationToken)\n    } catch (e) {\n      throw new TypeError(\n        `authorizationToken must be a valid JWT, got a malformed one instead. ${e}`\n      )\n    }\n    state.authorizationToken = authorizationToken\n  },\n  unsetAuthorizationToken(state) {\n    state.authorizationToken = null\n  },\n  refreshToken(state, refreshToken) {\n    try {\n      jwt_decode(refreshToken)\n    } catch (e) {\n      throw new TypeError(\n        `refreshToken must be a valid JWT, got a malformed one instead. ${e}`\n      )\n    }\n    state.refreshToken = refreshToken\n  },\n  unsetRefreshToken(state) {\n    state.refreshToken = null\n  },\n  authorizationTokenExpiry(state, authorizationTokenExpiry) {\n    if (\n      typeof authorizationTokenExpiry !== 'number' ||\n      authorizationTokenExpiry == null\n    )\n      throw new TypeError(\n        `authorizationTokenExpiry must be an number, got ${typeof authorizationTokenExpiry} instead`\n      )\n\n    state.authorizationTokenExpiry = authorizationTokenExpiry\n  },\n  unsetAuthorizationTokenExpiry(state) {\n    state.authorizationTokenExpiry = null\n  },\n  refreshTokenExpiry(state, refreshTokenExpiry) {\n    if (typeof refreshTokenExpiry !== 'number' || refreshTokenExpiry == null)\n      throw new TypeError(\n        `refreshTokenExpiry must be an number, got ${typeof refreshTokenExpiry} instead`\n      )\n\n    state.refreshTokenExpiry = refreshTokenExpiry\n  },\n  unsetRefreshTokenExpiry(state) {\n    state.refreshTokenExpiry = null\n  }\n}\n\nconst actions = {}\n\nexport default {\n  state,\n  getters,\n  mutations,\n  actions,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/store/data/index.js",
    "content": "import { fallbackApolloClient } from '@/vue-apollo'\n\nconst state = {\n  activeFlow: null,\n  activeProject: null,\n  activeTask: null,\n  flows: null,\n  projects: null,\n  tasks: null\n}\n\nconst getters = {\n  activeFlow(state) {\n    return state.activeFlow\n  },\n  activeFlowId(state) {\n    return state.activeFlow?.id\n  },\n  activeProject(state) {\n    return state.activeProject\n  },\n  activeProjectId(state) {\n    return state.activeProject?.id\n  },\n  activeTask(state) {\n    return state.activeTask\n  },\n  activeTaskId(state) {\n    return state.activeTask?.id\n  },\n  flows(state) {\n    return state.flows\n  },\n  projects(state) {\n    return state.projects\n  },\n  tasks(state) {\n    return state.tasks\n  }\n}\n\nconst mutations = {\n  setActiveProject(state, project) {\n    if (\n      !project ||\n      typeof project !== 'object' ||\n      Array.isArray(project) ||\n      Object.keys(project) < 1\n    ) {\n      throw new Error(\n        'passed invalid or empty Project; Expected Object, got: ' + project\n      )\n    }\n\n    state.activeProject = project\n  },\n  unsetActiveProject(state) {\n    state.activeProject = null\n  },\n  setActiveFlow(state, flow) {\n    if (\n      !flow ||\n      typeof flow !== 'object' ||\n      Array.isArray(flow) ||\n      Object.keys(flow) < 1\n    ) {\n      throw new Error(\n        'passed invalid or empty Flow; Expected Object, got: ' + flow\n      )\n    }\n    state.activeFlow = flow\n  },\n  unsetActiveFlow(state) {\n    state.activeFlow = null\n  },\n  setActiveTask(state, task) {\n    if (\n      !task ||\n      typeof task !== 'object' ||\n      Array.isArray(task) ||\n      Object.keys(task) < 1\n    ) {\n      throw new Error(\n        'passed invalid or empty Task; Expected Object, got: ' + task\n      )\n    }\n    state.activeTask = task\n  },\n  unsetActiveTask(state) {\n    state.activeTask = null\n  },\n  addTasks(state, tasks) {\n    if (!tasks || !Array.isArray(tasks)) {\n      throw new Error(\n        'passed null or invalid Tasks; Expected Array, got: ' + tasks\n      )\n    }\n\n    if (!state.tasks) {\n      state.tasks = tasks\n      return\n    }\n\n    tasks.forEach(task => {\n      let i = state.tasks.findIndex(t => t.id == task.id)\n      if (i > -1) state.tasks[i] = task\n      else state.tasks.push(task)\n    })\n  },\n  setTasks(state, tasks) {\n    if (!tasks || !Array.isArray(tasks)) {\n      throw new Error('passed invalid Tasks; Expected Array, got: ' + tasks)\n    }\n    state.tasks = tasks\n  },\n  unsetTasks(state) {\n    state.tasks = null\n  },\n  setFlows(state, flows) {\n    if (!flows || !Array.isArray(flows)) {\n      throw new Error('passed invalid Flows; Expected Array, got: ' + flows)\n    }\n    state.flows = flows\n  },\n  unsetFlows(state) {\n    state.flows = null\n  },\n  setProjects(state, projects) {\n    if (!projects || !Array.isArray(projects)) {\n      throw new Error(\n        'passed invalid Projects; Expected Array, got: ' + projects\n      )\n    }\n    state.projects = projects\n  },\n  unsetProjects(state) {\n    state.projects = null\n  }\n}\n\nconst actions = {\n  async activateFlow({ commit, getters, dispatch }, id) {\n    let flow = getters['flows']?.find(f => f.id == id || f.flow_group_id == id)\n\n    if (!flow || flow.id !== id) {\n      id = flow?.id || id\n\n      const { data } = await fallbackApolloClient.query({\n        query: require('@/graphql/Nav/flow.gql'),\n        variables: {\n          id: id\n        }\n      })\n\n      // Dedupes incoming flows\n      const flows =\n        getters['flows']?.filter(f => !data.flow.find(_f => _f.id == f.id)) ||\n        []\n      commit('setFlows', [...flows, ...data.flow])\n\n      flow = getters['flows']?.find(f => f.id == id || f.flow_group_id == id)\n    }\n\n    if (!flow) throw new Error(\"Couldn't retrieve flow.\")\n\n    commit('setActiveFlow', flow)\n    await dispatch('activateProject', flow.project_id)\n  },\n  async activateProject({ commit, getters }, id) {\n    let project = getters['projects']?.find(p => p.id == id)\n\n    if (!project) {\n      const { data } = await fallbackApolloClient.query({\n        query: require('@/graphql/Nav/projects.gql')\n      })\n\n      commit('setProjects', data.project)\n\n      project = getters['projects'].find(p => p.id == id)\n    }\n\n    if (!project) throw new Error(\"Couldn't retrieve project.\")\n\n    commit('setActiveProject', project)\n  },\n  async activateTask({ commit, getters, dispatch }, id) {\n    let task = getters['tasks']?.find(t => t.id == id)\n\n    if (!task) {\n      const { data } = await fallbackApolloClient.query({\n        query: require('@/graphql/Nav/task.gql'),\n        variables: {\n          taskId: id\n        }\n      })\n\n      commit('addTasks', data.task)\n\n      task = getters['tasks'].find(t => t.id == id)\n    }\n\n    if (!task) throw new Error(\"Couldn't retrieve task.\")\n\n    commit('setActiveTask', task)\n    await dispatch('activateFlow', task.flow_id)\n  },\n  resetActiveData({ commit }) {\n    commit('unsetActiveFlow')\n    commit('unsetActiveProject')\n    commit('unsetActiveTask')\n  },\n  resetData({ commit }) {\n    commit('unsetActiveFlow')\n    commit('unsetActiveProject')\n    commit('unsetActiveTask')\n    commit('unsetFlows')\n    commit('unsetProjects')\n    commit('unsetTasks')\n  }\n}\n\nexport default {\n  getters,\n  mutations,\n  state,\n  actions,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/store/index.js",
    "content": "// Core\nimport Vue from 'vue'\nimport Vuex from 'vuex'\n\n// Plugins\nimport LogRocket from 'logrocket'\nimport createPlugin from 'logrocket-vuex'\n\n// Modules\nimport agent from '@/store/agent'\nimport api from '@/store/api'\nimport auth from '@/store/auth'\nimport data from '@/store/data'\nimport license from '@/store/license'\nimport refresh from '@/store/refresh'\nimport sideNav from '@/store/sideNav'\nimport tenant from '@/store/tenant'\nimport user from '@/store/user'\nimport alert from '@/store/alert'\nimport polling from '@/store/polling'\n\nVue.use(Vuex)\n\nconst logrocketPlugin = createPlugin(LogRocket, mutation => {\n  if (\n    mutation.type === 'setAuthenticationTokens' ||\n    mutation.type === 'setAuthorizationToken' ||\n    mutation.type === 'setUser'\n  ) {\n    return {\n      type: mutation.type\n    }\n  }\n\n  return mutation\n})\n\nconst store = new Vuex.Store({\n  modules: {\n    agent,\n    alert,\n    api,\n    auth,\n    data,\n    license,\n    polling,\n    refresh,\n    sideNav,\n    tenant,\n    user\n  },\n  strict: process.env.NODE_ENV !== 'production',\n  plugins: [logrocketPlugin]\n})\n\nexport default store\n"
  },
  {
    "path": "src/store/license/index.js",
    "content": "import { fallbackApolloClient } from '@/vue-apollo'\nimport LogRocket from 'logrocket'\n\nconst state = {\n  license: null,\n  permissions: null,\n  tempLicenseType: null,\n  role: null\n}\n\nconst getters = {\n  hasLicense(state) {\n    return !!state.license\n  },\n  license(state) {\n    return state.license\n  },\n  permissions(state) {\n    return state.permissions\n  },\n  tempLicenseType(state) {\n    return state.tempLicenseType\n  },\n  planType: state => type => {\n    if (type) {\n      return state.license?.terms?.plan.includes(type)\n    }\n    return state.license?.terms?.plan\n  },\n  hasPermission: state => (operation, ref) => {\n    if (process.env.VUE_APP_BACKEND !== 'CLOUD') return true\n    return state.permissions?.includes(`${operation}:${ref}`)\n  },\n  allowedUsers: state => type => {\n    if (type === 'read') {\n      return state.license?.terms?.read_only_users\n    }\n    return state.license?.terms?.users\n  },\n  role(state) {\n    return state.role\n  }\n}\n\nconst mutations = {\n  setLicense(state, license) {\n    state.license = license\n    state.tempLicenseType = null\n  },\n  setRole(state, role) {\n    state.role = role\n  },\n  setTempLicenseType(state, type) {\n    state.tempLicenseType = type\n  },\n  unsetLicense(state) {\n    state.license = null\n  },\n  setPermissions(state, permissions) {\n    state.permissions = permissions\n  },\n  unsetPermissions(state) {\n    state.permissions = null\n  }\n}\n\nconst actions = {\n  async getLicense({ commit }) {\n    try {\n      const { data } = await fallbackApolloClient.query({\n        query: require('@/graphql/License/license.gql'),\n        fetchPolicy: 'no-cache'\n      })\n\n      if (data?.auth_info?.license) {\n        commit('setLicense', data.auth_info.license)\n      }\n      if (data?.auth_info?.role_id) {\n        commit('setRole', data.auth_info.role_id)\n      }\n      if (data?.auth_info?.permissions) {\n        commit('setPermissions', data.auth_info.permissions)\n      }\n    } catch (error) {\n      commit('unsetLicense')\n      commit('unsetPermissions')\n      // eslint-disable-next-line no-console\n      console.log(error)\n      LogRocket.captureException(error, {\n        extra: {\n          pageName: 'LicenseStore',\n          stage: 'getLicense'\n        }\n      })\n    }\n  }\n}\n\nexport default {\n  getters,\n  mutations,\n  state,\n  actions,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/store/polling/index.js",
    "content": "const state = {\n  uniqueId: -1,\n  tenants: [],\n  agents: [],\n  projects: [],\n  flows: []\n}\n\nconst getters = {\n  shouldPollTenants(state) {\n    return state.tenants.length > 0\n  },\n  shouldPollAgents(state) {\n    return state.agents.length > 0\n  },\n  shouldPollProjects(state) {\n    return state.projects.length > 0\n  },\n  shouldPollFlows(state) {\n    return state.flows.length > 0\n  }\n}\n\nconst mutations = {\n  incrementUniqueId(state) {\n    state.uniqueId++\n  },\n  addSubscriber(state, { stream, uniqueId }) {\n    if (state[stream].indexOf(uniqueId) == -1) {\n      state[stream].push(uniqueId)\n    }\n  },\n  removeSubscriber(state, { stream, uniqueId }) {\n    if (state[stream].indexOf(uniqueId) != -1) {\n      state[stream] = [...state[stream].filter(id => id != uniqueId)]\n    }\n  }\n}\n\nconst actions = {\n  getUniqueId({ commit, state }) {\n    commit('incrementUniqueId')\n\n    return state.uniqueId\n  },\n  async subscribe({ commit, dispatch }, streams) {\n    const uniqueId = await dispatch('getUniqueId')\n    const addSubscriber = stream =>\n      commit('addSubscriber', { uniqueId, stream })\n\n    if (!Array.isArray(streams)) {\n      streams = [streams]\n    }\n\n    streams.forEach(addSubscriber)\n\n    return () => dispatch('unsubscribe', { uniqueId, streams })\n  },\n  unsubscribe({ commit }, { uniqueId, streams }) {\n    streams.forEach(stream => commit('removeSubscriber', { uniqueId, stream }))\n  }\n}\n\nexport default {\n  getters,\n  mutations,\n  state,\n  actions,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/store/refresh/index.js",
    "content": "const state = {\n  componentKey: 0\n}\n\nconst getters = {\n  componentKey(state) {\n    return state.componentKey\n  }\n}\n\nconst mutations = {\n  add(state) {\n    state.componentKey++\n  }\n}\n\nexport default {\n  getters,\n  mutations,\n  state,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/store/sideNav/index.js",
    "content": "const state = {\n  open: false\n}\n\nconst getters = {\n  isOpen(state) {\n    return state.open\n  }\n}\n\nconst mutations = {\n  close(state) {\n    state.open = false\n  },\n  open(state) {\n    state.open = true\n  },\n  toggle(state) {\n    state.open = !state.open\n  }\n}\n\nexport default {\n  getters,\n  mutations,\n  state,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/store/tenant/index.js",
    "content": "import { fallbackApolloClient } from '@/vue-apollo'\nimport { prefectTenants } from '@/middleware/prefectAuth'\nimport { switchTenant, commitTokens } from '@/auth/index.js'\n\nconst state = {\n  defaultTenant: null,\n  tenant: {\n    id: null,\n    name: null,\n    info: null,\n    slug: null,\n    role: null,\n    licenses: [],\n    settings: {},\n    prefectAdminSettings: {},\n    stripe_customer: null\n  },\n  isLoadingTenant: false,\n  tenantIsSet: false,\n  tenants: []\n}\n\nconst getters = {\n  defaultTenant(state) {\n    return state.defaultTenant\n  },\n  isLoadingTenant(state) {\n    return state.isLoadingTenant\n  },\n  role(state) {\n    return state.tenant.role\n  },\n  tenant(state) {\n    return state.tenant || state.defaultTenant\n  },\n  tenantIsSet(state) {\n    return !!state.tenant?.id\n  },\n  tenants(state) {\n    return state.tenants\n  }\n}\n\nconst mutations = {\n  setDefaultTenant(state, tenant) {\n    if (\n      !tenant ||\n      typeof tenant !== 'object' ||\n      Array.isArray(tenant) ||\n      Object.keys(tenant) < 1\n    ) {\n      throw new Error('passed invalid or empty tenant object')\n    }\n    state.defaultTenant = tenant\n  },\n  setIsLoadingTenant(state, value) {\n    if (typeof value !== 'boolean') {\n      throw new Error(\n        `passed invalid value to setIsLoadingTenant mutation, got ${typeof val}, expected Boolean.`\n      )\n    }\n\n    state.isLoadingTenant = value\n  },\n  setTenant(state, tenant) {\n    if (\n      !tenant ||\n      typeof tenant !== 'object' ||\n      Array.isArray(tenant) ||\n      Object.keys(tenant) < 1\n    ) {\n      throw new Error('passed invalid or empty tenant object')\n    }\n    state.tenant = { ...tenant }\n  },\n  setTenants(state, tenants) {\n    if (!tenants || tenants?.length === 0) {\n      throw new Error('passed invalid or empty tenant array')\n    }\n    state.tenants = tenants\n  },\n  unsetTenant(state) {\n    state.tenant = {\n      id: null,\n      name: null,\n      info: null,\n      slug: null,\n      role: null,\n      licenses: [],\n      settings: {},\n      prefectAdminSettings: {},\n      stripe_customer: null\n    }\n  },\n  unsetTenants(state) {\n    state.tenants = []\n  },\n  updateTenantSettings(state, settings) {\n    if (!settings || !Object.keys(settings).length) {\n      throw new Error('passed invalid or empty settings object')\n    }\n    state.tenant.settings = settings\n  }\n}\n\nconst actions = {\n  async getTenants({ commit, getters, rootGetters }) {\n    try {\n      const tenants = await prefectTenants(rootGetters['api/isCloud'])\n      commit('setTenants', tenants)\n\n      // Make sure the current tenant object is updated\n      if (getters['tenantIsSet']) {\n        let tenant = getters['tenants']?.find(\n          t => t.id === getters['tenant'].id\n        )\n\n        tenant.role = rootGetters['user/memberships'].find(\n          membership => membership.tenant.id == tenant.id\n        )?.role_detail?.name\n        commit('setTenant', tenant)\n      }\n    } catch {\n      // Do nothing since the GraphQL error should be logged by Apollo afterware\n    }\n\n    return getters['tenants']\n  },\n  async setCurrentTenant({ commit, dispatch, getters, rootGetters }, slug) {\n    slug = slug || getters['defaultTenant']?.slug || getters['tenants'][0]?.slug\n\n    if (!slug) {\n      throw new Error(\n        'No slug was provided when trying to set the current tenant'\n      )\n    }\n\n    try {\n      commit('setIsLoadingTenant', true)\n\n      let tenant = getters['tenants']?.find(t => t.slug === slug)\n\n      if (!tenant) {\n        // If the tenant doesn't exist\n        // try to retrieve tenants again\n\n        await dispatch('getTenants')\n      }\n\n      tenant = getters['tenants']?.find(t => t.slug === slug)\n      if (!tenant) {\n        throw new Error(\"Unable to set current tenant: tenant doesn't exist\")\n      }\n\n      if (rootGetters['api/isCloud']) {\n        // We only need to get new tokens if we have a tenant\n        // already - otherwise tokens are fetched through the initial\n        // authorization process\n        if (getters['tenantIsSet']) {\n          const tokens = await switchTenant(tenant.id)\n          commitTokens(tokens)\n        }\n\n        // Get the current license\n        await dispatch('license/getLicense', null, { root: true })\n\n        tenant.role = rootGetters['user/memberships'].find(\n          membership => membership.tenant.id == tenant.id\n        )?.role_detail?.name\n      } else {\n        tenant.role = 'TENANT_ADMIN'\n      }\n\n      commit('setTenant', tenant)\n    } catch (e) {\n      throw new Error(`Problem setting tenant: ${e}`)\n    }\n\n    commit('setIsLoadingTenant', false)\n    return getters['tenant']\n  },\n  async updateTenantSettings({ dispatch }, settings) {\n    try {\n      if (!settings || !Object.keys(settings).length) {\n        throw new Error('passed invalid or empty settings object')\n      }\n      await fallbackApolloClient.mutate({\n        mutation: require('@/graphql/Mutations/update-tenant-settings.gql'),\n        variables: {\n          settings\n        },\n        error(error) {\n          throw error\n        }\n      })\n      await dispatch('getTenants')\n    } catch (e) {\n      throw new Error(`Problem updating tenant settings: ${e}`)\n    }\n  }\n}\n\nexport default {\n  actions,\n  getters,\n  mutations,\n  state,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/store/user/index.js",
    "content": "import { prefectUser } from '@/middleware/prefectAuth'\n\nconst state = {\n  user: {\n    id: null,\n    email: null,\n    username: null,\n    default_membership_id: null,\n    memberships: null,\n    first_name: '',\n    last_name: '',\n    settings: {\n      timezone: '',\n      isDark: false\n    }\n  },\n  oktaUser: {\n    name: null,\n    email: null,\n    picture: null\n  },\n  userIsSet: false,\n  invitations: null\n}\n\nconst getters = {\n  user(state) {\n    return state.user\n  },\n  username(state) {\n    return state.username\n  },\n  oktaUser(state) {\n    return state.oktaUser\n  },\n  defaultMembershipId(state) {\n    return state.user.default_membership_id\n  },\n  memberships(state) {\n    return state.user.memberships\n  },\n  userIsSet(state) {\n    return state.userIsSet\n  },\n  timezone(state) {\n    return state.user.settings.timezone\n  },\n  isDark(state) {\n    return state.user.settings.isDark\n  },\n  settings(state) {\n    return state.user.settings\n  },\n  firstName(state) {\n    return state.user.first_name\n  },\n  lastName(state) {\n    return state.user.last_name\n  },\n  invitations(state) {\n    return state.invitations\n  }\n}\n\nconst mutations = {\n  user(state, user) {\n    state.user = { ...user }\n    state.userIsSet = true\n  },\n  setOktaUser(state, oktaUser) {\n    state.oktaUser = {\n      name: oktaUser.name,\n      email: oktaUser.email,\n      picture: oktaUser.picture || oktaUser.picture_url\n    }\n  },\n  setUserSettings(state, settings) {\n    if (state.user.settings != settings) {\n      state.user.settings = settings\n    }\n  },\n  unsetUser(state) {\n    state.user = {\n      id: null,\n      email: null,\n      username: null,\n      first_name: '',\n      last_name: '',\n      default_membership_id: null,\n      memberships: null,\n      settings: { timezone: '' }\n    }\n    state.userIsSet = false\n  },\n  unsetOktaUser(state) {\n    state.oktaUser = {\n      name: null,\n      email: null,\n      picture: null\n    }\n  },\n  setUserDefaultMembershipId(state, membershipId) {\n    state.user.default_membership_id = membershipId\n  },\n  setInvitations(state, invitations) {\n    state.invitations = invitations\n  },\n  unsetInvitations(state) {\n    state.invitations = null\n  }\n}\n\nconst actions = {\n  async setDefaultTenant({ commit, getters, rootGetters }) {\n    const defaultMembershipId = getters['defaultMembershipId']\n    const defaultTenant = getters['memberships']?.find(\n      membership => membership.id === defaultMembershipId\n    )?.tenant\n\n    const firstTenant =\n      getters['memberships']?.[0]?.tenant || rootGetters['tenant/tenants']?.[0]\n\n    commit('tenant/setDefaultTenant', defaultTenant || firstTenant, {\n      root: true\n    })\n  },\n\n  async getUser({ commit, getters, dispatch, rootGetters }) {\n    // If this is Server, we don't continue, since this will fail\n    if (rootGetters['api/isServer']) return\n\n    const user = await prefectUser()\n    commit('user', user)\n    dispatch('setDefaultTenant')\n    return getters['user']\n  }\n}\n\nexport default {\n  getters,\n  mutations,\n  actions,\n  state,\n  namespaced: true\n}\n"
  },
  {
    "path": "src/styles/atelier-sulphurpool-light.scss",
    "content": "/* Base16 Atelier Sulphurpool Light - Theme */\n/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */\n/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */\n\n/* Atelier-Sulphurpool Comment */\n.hljs-comment,\n.hljs-quote {\n  color: #6b7394;\n}\n\n/* Atelier-Sulphurpool Red */\n.hljs-variable,\n.hljs-template-variable,\n.hljs-attribute,\n.hljs-tag,\n.hljs-name,\n.hljs-regexp,\n.hljs-link,\n.hljs-selector-id,\n.hljs-selector-class {\n  color: #c94922;\n}\n\n/* Atelier-Sulphurpool Orange */\n/* stylelint-disable-next-line */\n.hljs-built_in,\n.hljs-number,\n.hljs-meta,\n.hljs-builtin-name,\n.hljs-literal,\n.hljs-type,\n.hljs-params {\n  color: #c76b29;\n}\n\n/* Atelier-Sulphurpool Green */\n.hljs-string,\n.hljs-symbol,\n.hljs-bullet {\n  color: #ac9739;\n}\n\n/* Atelier-Sulphurpool Blue */\n.hljs-title,\n.hljs-section {\n  color: #3d8fd1;\n}\n\n/* Atelier-Sulphurpool Purple */\n.hljs-keyword,\n.hljs-selector-tag {\n  color: #6679cc;\n}\n\n.hljs {\n  background: #f5f7ff;\n  color: #5e6687;\n  display: block;\n  overflow-x: auto;\n  padding: 0.5em;\n}\n\n.hljs-emphasis {\n  font-style: italic;\n}\n\n.hljs-strong {\n  font-weight: bold;\n}\n"
  },
  {
    "path": "src/styles/global.scss",
    "content": "/*\nThis file is for styles used throughout the app, and global overrides.\nThe style sections are:\n  - Transition and Animation classes (used throughout the app for consistent look and feel)\n  - Vuetify overrides (where Vuetify/material theming doesn't fit with our aesthetic)\n  - Utility classes (see if Vuetify offers the class you need before making more of these!)\n  - Common UI elements (used throughout the app for consistent look and feel)\n\nIf you have styles used on several pages, but they aren't truly \"global\", you can create \na \"regional\" stylesheet, and import it only on the pages needed. This will keep our CSS\nconcise and snappy, and the files easier to read!\n*/\n\n:root {\n  --v-tabs-height: 48px;\n  --v-sm: 600px;\n  --v-md: 960px;\n  --v-lg: 1264px;\n  --v-xl: 1904px;\n}\n\nhtml,\nbody {\n  overflow: overlay;\n}\n\n.not-mac * {\n  box-sizing: border-box;\n  -webkit-overflow-scrolling: touch;\n  -ms-overflow-style: -ms-autohiding-scrollbar;\n\n  // This is for scrollbar-css compliant browsers only\n  // ... which is just FireFox for now.\n  // the -webkit-* selectors will be deprecated at some point\n  // so this will serve as a fallback\n  scrollbar-color: #babac0 transparent;\n  scrollbar-width: thin;\n\n  // Styles the scrollbar container\n  ::-webkit-scrollbar {\n    background-color: transparent;\n    width: 16px;\n  }\n\n  // Removes track default background\n  ::-webkit-scrollbar-track {\n    background-color: transparent;\n  }\n\n  // Styles scrollbar body\n  ::-webkit-scrollbar-thumb {\n    background-color: #babac0;\n    border: 4px solid #fff;\n    border-radius: 16px;\n    min-height: 25px;\n  }\n\n  // Removes scrollar arrow buttons\n  /* stylelint-disable-next-line */\n  ::-webkit-scrollbar-button {\n    display: none;\n  }\n}\n\n/* Transition and animation classes */\n.fade-enter-active {\n  animation: fade 500ms;\n}\n\n.fade-leave-active {\n  animation: fade 500ms reverse;\n}\n\n.tooltip-fade-enter-active {\n  animation: fade 150ms;\n}\n\n.tooltip-fade-leave-active {\n  animation: fade 150ms reverse;\n}\n\n@keyframes fade {\n  0% {\n    opacity: 0;\n  }\n\n  100% {\n    opacity: 1;\n  }\n}\n\n.fade-expand-enter-active,\n.fade-expand-leave-active {\n  max-height: 1000px;\n  opacity: 1;\n}\n\n.fade-expand-enter-active {\n  transition: max-height linear 200ms 200ms, opacity linear 200ms 400ms;\n}\n\n.fade-expand-leave-active {\n  transition: max-height linear 200ms 200ms, opacity linear 200ms;\n}\n\n.fade-expand-enter,\n.fade-expand-leave-to {\n  max-height: 0;\n  opacity: 0;\n}\n\n.quick-fade-leave-active {\n  transition: opacity 150ms ease-in-out !important;\n}\n\n.quick-fade-enter-active,\n.quick-fade-leave-active {\n  opacity: 1;\n  transition: opacity 200ms ease-in-out;\n}\n\n.quick-fade-enter,\n.quick-fade-leave-to {\n  opacity: 0;\n}\n\n.tab-fade-leave-active {\n  transition: opacity 150ms ease-in-out !important;\n}\n\n.tab-fade-enter-active,\n.tab-fade-leave-active {\n  opacity: 1;\n  position: absolute;\n  transition: opacity 350ms ease-in-out;\n  width: 100%;\n}\n\n.tab-fade-enter,\n.tab-fade-leave-to {\n  opacity: 0;\n}\n\n.roll {\n  animation: roll 3s ease-in-out;\n  pointer-events: none;\n}\n\n@keyframes roll {\n  from {\n    transform: rotate(0);\n  }\n\n  to {\n    transform: rotate(360deg);\n  }\n}\n/* End transition and animation classes */\n\n/* Vuetify overrides */\n// stylelint-disable\n.vertical-button {\n  &.v-btn--tile {\n    height: auto !important;\n  }\n\n  .v-btn__content {\n    flex-direction: column-reverse !important;\n  }\n}\n\n// toggle button with label above\n.v-input--vertical .v-input__slot {\n  flex-direction: column-reverse !important;\n\n  .v-input--selection-controls__input {\n    align-self: center;\n    margin: auto !important;\n  }\n\n  .v-btn:not(.v-btn--round).v-size--small {\n    height: unset !important;\n  }\n}\n\n// overflow menu with checkboxes\n.v-input--reverse .v-input__slot {\n  flex-direction: row-reverse;\n  justify-content: flex-end;\n\n  .v-application--is-ltr & {\n    .v-input--selection-controls__input {\n      margin-left: 8px;\n      margin-right: 0;\n    }\n  }\n\n  .v-application--is-rtl & {\n    .v-input--selection-controls__input {\n      margin-left: 0;\n      margin-right: 8px;\n    }\n  }\n}\n\n.small-switch.v-input {\n  margin-top: 0 !important;\n  padding-top: 0 !important;\n  transform: scale(0.8);\n}\n\n.multi-color-switch {\n  .v-input--switch__track,\n  .v-input--switch__thumb {\n    color: inherit !important;\n  }\n}\n\n//ugly box shadow on expanded data tables\n.v-data-table\n  > .v-data-table__wrapper\n  tbody\n  tr.v-data-table__expanded__content {\n  box-shadow: none !important;\n}\n\n.theme--light.v-tabs-items {\n  background-color: var(--v-appBackground-base) !important;\n}\n// stylelint-enable\n/* End vuetify overrides */\n\n/* Utility classes */\n.cursor-pointer {\n  cursor: pointer;\n}\n\n.position-absolute {\n  position: absolute !important;\n}\n\n.position-relative {\n  position: relative !important;\n}\n\n.word-break-normal {\n  word-break: normal;\n}\n\n$percents: 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100;\n\n@each $percent in $percents {\n  .o-#{$percent} {\n    opacity: $percent/100 !important;\n  }\n\n  .hover-o-#{$percent} {\n    &:hover,\n    &:focus {\n      opacity: $percent/100 !important;\n    }\n  }\n}\n\n.user-select-none {\n  user-select: none;\n}\n\n.fill-height {\n  height: calc(100vh - 64px);\n}\n\n.code-block {\n  font-family: 'Source Code Pro', monospace !important;\n  white-space: pre-wrap;\n}\n/* End utility classes */\n\n/* Common UI elements */\n.tabs-border-bottom {\n  .v-tabs-bar {\n    border-bottom: 1px solid var(--v-utilGrayLight-base) !important;\n  }\n}\n\n.tabs-border-top {\n  .v-tabs-bar {\n    border-top: 1px solid var(--v-utilGrayLight-base) !important;\n  }\n}\n\n.fixed-table {\n  table {\n    table-layout: fixed;\n  }\n}\n\n.truncate-table.v-data-table {\n  font-size: 0.9rem !important;\n\n  td {\n    font-size: inherit !important;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n}\n\n.remove--disabled.theme--light.v-btn.v-btn--disabled:not(.v-btn--flat):not(.v-btn--text):not(.v-btn-outlined),\n.remove--disabled.theme--dark.v-btn.v-btn--disabled:not(.v-btn--flat):not(.v-btn--text):not(.v-btn-outlined) {\n  .v-icon {\n    color: inherit !important;\n  }\n}\n\n/* stylelint-disable */\n.disabled.v-badge {\n  pointer-events: none !important;\n\n  .v-badge__wrapper,\n  .v-badge__badge {\n    pointer-events: none !important;\n  }\n}\n\n.v-text-field-input-color {\n  .v-text-field__slot {\n    input {\n      color: inherit !important;\n    }\n  }\n}\n\n// hides subnav on small screens\n.tabs-hidden {\n  .v-tabs-bar {\n    display: none;\n  }\n}\n\n.v-picker__body {\n  background: inherit !important;\n}\n\n.overflow-table > .v-data-table__wrapper {\n  overflow: initial !important;\n}\n// stylelint-enable\n/* End common UI elements */\n\n/* Navbar global styles */\n.navbar-icon {\n  font-size: 0.85rem;\n  height: 36px !important;\n  width: 36px !important;\n\n  .svg-inline--fa {\n    --fa-primary-color: #fff;\n    --fa-secondary-color: #efefef;\n    transition: all 150ms linear;\n\n    &.fa-search {\n      --fa-primary-color: #efefef;\n      --fa-secondary-color: #fff;\n      --fa-secondary-opacity: 1;\n    }\n\n    &.fa-bell {\n      --fa-primary-color: #efefef;\n      --fa-secondary-color: #fff;\n      --fa-secondary-opacity: 1;\n    }\n\n    &.fa-server {\n      --fa-secondary-opacity: 1;\n    }\n\n    &.fa-circle {\n      --fa-secondary-color: #fff;\n      --fa-secondary-opacity: 0;\n      height: 0;\n      width: 0;\n    }\n  }\n\n  &:hover,\n  &:focus {\n    .svg-inline--fa {\n      --fa-primary-color: var(--v-accentPink-base);\n    }\n  }\n\n  &.active {\n    .svg-inline--fa.fa-sliders-v-square {\n      --fa-primary-color: var(--v-accentPink-base);\n    }\n  }\n}\n\n.banner-icon {\n  color: transparent;\n  font-size: 36px !important;\n  height: 36px !important;\n  line-height: 36px !important;\n  width: 60px !important;\n\n  .svg-inline--fa {\n    transition: all 150ms linear;\n\n    &.fa-list-ul {\n      --fa-primary-color: var(--v-warning-base);\n      --fa-secondary-color: var(--v-utilGrayLight-base);\n      --fa-secondary-opacity: 1;\n    }\n  }\n}\n\n.system-icon {\n  font-size: 64px !important;\n  height: 64px !important;\n  line-height: 64px !important;\n  width: 80px !important;\n\n  &.fa-stack {\n    position: relative !important;\n\n    .fa-stack-1x,\n    .fa-stack-2x {\n      height: inherit !important;\n      position: relative;\n      width: inherit !important;\n    }\n\n    .svg-inline--fa.fa-stack-1x {\n      position: absolute;\n      top: 50%;\n      left: 50%;\n      transform: translate(-50%, -25%);\n    }\n  }\n\n  .svg-inline--fa {\n    --fa-primary-color: #444;\n    --fa-secondary-opacity: 0.75;\n\n    transition: all 150ms linear;\n\n    &.fa-list-alt {\n      --fa-primary-color: var(--v-warning-base);\n      --fa-secondary-opacity: 1;\n    }\n\n    &.fa-align-slash {\n      --fa-primary-color: var(--v-error-base);\n      --fa-secondary-opacity: 1;\n    }\n\n    &.fa-slash {\n      color: var(--v-error-base);\n    }\n  }\n\n  &.active {\n    .svg-inline--fa {\n      &.fa-list-alt {\n        --fa-primary-color: var(--v-primary-base);\n        --fa-secondary-opacity: 1;\n      }\n    }\n  }\n}\n\n.fa-stack {\n  &.active {\n    .nav-bar-duotone-icon {\n      --fa-primary-color: var(--v-accentPink-base);\n    }\n\n    .fa-stack-1x {\n      height: 100%;\n      left: 50%;\n      transform: translate(-50%, 1.15em) scale(0.6);\n      width: 100%;\n    }\n  }\n}\n\n/* End Navbar global styles */\n\n/* Dark Mode background overrides */\n// stylelint-disable\n.theme--dark {\n  .v-tabs-items,\n  &.v-application {\n    background-color: var(--v-appBackground-base) !important;\n  }\n\n  &.v-calendar-daily,\n  &.v-card,\n  &.v-data-table,\n  &.v-data-table.v-data-table--fixed-header thead th,\n  &.v-navigation-drawer,\n  .v-sheet,\n  &.v-tabs > .v-tabs-bar,\n  &.v-text-field--solo > .v-input__control > .v-input__slot,\n  &.v-toolbar.v-sheet:not(header) {\n    background-color: var(--v-appForeground-base);\n  }\n\n  &.v-data-table\n    > .v-data-table__wrapper\n    > table\n    > tbody\n    > tr:hover:not(.v-data-table__expanded__content):not(.v-data-table__empty-wrapper),\n  &.v-tooltip__content {\n    background-color: var(--v-utilGrayMid-darken2) !important;\n  }\n\n  scrollbar-color: var(--v-utilGrayMid-darken2) transparent;\n  scrollbar-width: thin;\n\n  ::-webkit-scrollbar {\n    background-color: transparent;\n    width: 10px;\n  }\n\n  ::-webkit-scrollbar-track {\n    background-color: transparent;\n  }\n\n  ::-webkit-scrollbar-thumb {\n    background-color: var(--v-utilGrayMid-darken2);\n    border-radius: 16px;\n    min-height: 25px;\n  }\n\n  ::-webkit-scrollbar-corner {\n    background-color: transparent;\n  }\n\n  .v-skeleton-loader__bone {\n    background-color: var(--v-utilGrayMid-darken3) !important;\n  }\n}\n/* End Dark Mode background overrides */\n/* Plans global styles */\n/* stylelint-disable no-descending-specificity */\n.plans-feature-icon {\n  align-items: center;\n  display: inline-flex;\n  height: 20px;\n  justify-content: center;\n  width: 20px;\n\n  .svg-inline--fa {\n    --fa-primary-color: var(--v-primary-base);\n    --fa-secondary-color: var(--v-primary-base);\n    --fa-secondary-opacity: 0.6;\n    transition: all 150ms linear;\n  }\n\n  &.feature-green {\n    .svg-inline--fa {\n      --fa-primary-color: var(--v-accentGreen-base);\n      --fa-secondary-color: var(--v-accentGreen-base);\n      --fa-secondary-opacity: 0.6;\n      transition: all 150ms linear;\n    }\n  }\n\n  .fa-toolbox.svg-inline--fa {\n    --fa-primary-opacity: 0.6 !important;\n    --fa-secondary-opacity: 1 !important;\n  }\n\n  &.plans-feature-icon-light {\n    .svg-inline--fa {\n      --fa-primary-color: var(--v-primary-base);\n      --fa-secondary-color: var(--v-primaryLight-base);\n      --fa-secondary-opacity: 1;\n    }\n  }\n}\n\n.feature-category-icon {\n  .svg-inline--fa {\n    --fa-primary-color: var(--v-primary-base);\n    --fa-secondary-color: var(--v-accentPink-base);\n    --fa-secondary-opacity: 1;\n    transition: all 150ms linear;\n\n    &.fa-chart-scatter {\n      --fa-primary-color: var(--v-accentPink-base);\n      --fa-secondary-color: var(--v-primary-base);\n    }\n  }\n}\n\n.feature-list-icon {\n  $color: #607d8b;\n\n  .svg-inline--fa {\n    --fa-primary-color: #{$color};\n    --fa-secondary-color: #{$color};\n    --fa-secondary-opacity: 1;\n    color: $color;\n    opacity: 1;\n    transition: all 150ms linear;\n  }\n\n  &.empty-circle .svg-inline--fa {\n    --fa-primary-opacity: 0 !important;\n  }\n\n  &.empty-outline .svg-inline--fa {\n    --fa-secondary-opacity: 0 !important;\n  }\n\n  &.feature-list-icon-disabled .svg-inline--fa {\n    opacity: 0.3 !important;\n  }\n}\n\n.support-icon {\n  .svg-inline--fa {\n    --fa-primary-color: var(--v-primary-base);\n    --fa-secondary-color: var(--v-primary-base);\n    --fa-secondary-opacity: 0.5;\n  }\n\n  .fa-badge-check.svg-inline--fa {\n    --fa-primary-color: var(--v-accentGreen-darken2);\n    --fa-secondary-color: var(--v-accentGreen-base);\n  }\n}\n/* stylelint-enable no-descending-specificity */\n/* End plans global styles */\n\n$fa-cc-amex: #007bc1;\n$fa-cc-diners-club: #004a97;\n$fa-cc-discover: #f68121;\n$fa-cc-jcb: #003a8f;\n$fa-cc-mastercard: #0a3a82;\n$fa-cc-paypal: #253b80;\n$fa-cc-stripe: #00afe1;\n$fa-cc-visa: #0157a2;\n\n.fa-cc-amex {\n  color: $fa-cc-amex !important;\n}\n\n.fa-cc-diners-club {\n  color: $fa-cc-diners-club !important;\n}\n\n.fa-cc-discover {\n  color: $fa-cc-discover !important;\n}\n\n.fa-cc-jcb {\n  color: $fa-cc-jcb !important;\n}\n\n.fa-cc-mastercard {\n  color: $fa-cc-mastercard !important;\n}\n\n.fa-cc-paypal {\n  color: $fa-cc-paypal !important;\n}\n\n.fa-cc-stripe {\n  color: $fa-cc-stripe !important;\n}\n\n.fa-cc-visa {\n  color: $fa-cc-visa !important;\n}"
  },
  {
    "path": "src/styles/json-input-style.scss",
    "content": "/* stylelint-disable */\n\n.cm-s-json-input.CodeMirror {\n  background-color: var(--v-appForeground-base) !important;\n  color: var(--v-utilGrayDark-base) !important;\n\n  .CodeMirror-code {\n    letter-spacing: 0.15rem;\n  }\n\n  div.CodeMirror-selected {\n    background: var(--v-primaryLight-base) !important;\n  }\n\n  .CodeMirror-line {\n    &::selection,\n    > span::selection,\n    > span > span::selection {\n      background: var(--v-primaryLight-base) !important;\n    }\n  }\n\n  .CodeMirror-gutters {\n    background: #f8f8f8 !important;\n    border-left: 6px solid rgba(0, 83, 159, 0.65) !important;\n    color: #333 !important;\n  }\n\n  .CodeMirror-linenumber {\n    color: #aaa !important;\n    padding-left: 8px !important;\n  }\n\n  .CodeMirror-cursor {\n    border-left: 1px solid var(--v-utilGrayMid-base) !important;\n  }\n\n  .cm-keyword {\n    color: #6262ff !important;\n  }\n\n  .cm-atom {\n    color: var(--v-accentOrange-base) !important;\n  }\n\n  .cm-number {\n    color: var(--v-accentGreen-base) !important;\n  }\n\n  .cm-def {\n    color: #8da6ce !important;\n  }\n\n  span.cm-variable-2,\n  span.cm-tag {\n    color: #690 !important;\n  }\n\n  span.cm-variable-3,\n  span.cm-def,\n  span.cm-type {\n    color: var(--v-error-base) !important;\n  }\n\n  .cm-variable {\n    color: var(--v-error-base) !important;\n  }\n\n  .cm-qualifier {\n    color: #690 !important;\n  }\n\n  .cm-operator {\n    color: var(--v-error-base) !important;\n  }\n\n  .cm-comment {\n    color: var(--v-utilGrayMid-base) !important;\n    font-weight: normal !important;\n  }\n  .cm-string {\n    color: var(--v-accentPink-base) !important;\n  }\n\n  .cm-property.cm-string {\n    color: var(--v-tertiaryBlue-base) !important;\n  }\n\n  .cm-property {\n    color: var(--v-error-base) !important;\n  }\n\n  .cm-string-2 {\n    color: var(--v-error-base) !important;\n  }\n  .cm-meta {\n    color: #000 !important;\n  }\n\n  .cm-builtin {\n    color: #deaa54 !important;\n  }\n\n  .cm-tag {\n    color: #ff9447 !important;\n  }\n\n  .cm-attribute {\n    color: #d6bb6d !important;\n  }\n\n  .cm-header {\n    color: #ea5a2e !important;\n  }\n\n  .cm-hr {\n    color: #aeaeae !important;\n  }\n\n  .cm-link {\n    color: #42c1d6 !important;\n    font-style: italic !important;\n    text-decoration: none !important;\n  }\n\n  .cm-error {\n    border-bottom: 1px solid red !important;\n  }\n\n  div .CodeMirror-activeline-background {\n    background: #efefff !important;\n  }\n\n  div span.CodeMirror-matchingbracket {\n    background-color: rgb(69, 90, 100, 0.35) !important;\n    color: inherit !important;\n  }\n}\n\n/* stylelint-enable */\n"
  },
  {
    "path": "src/styles/md-style.scss",
    "content": ".md {\n  margin-left: 2.25rem;\n  margin-top: 3.25rem;\n  /* stylelint-disable-next-line */\n  a[aria-hidden='true'] {\n    float: left;\n    font-size: 0.85em;\n    margin-left: -0.87em;\n    margin-top: 0.125em;\n    opacity: 0;\n    padding-right: 0.23em;\n  }\n  /* stylelint-disable-next-line */\n  a[aria-hidden='true']:hover {\n    opacity: 1;\n  }\n\n  h1 {\n    font-size: 2.5em;\n  }\n\n  h2 {\n    font-size: 2em;\n  }\n\n  h3 {\n    font-size: 1.75em;\n  }\n\n  h4 {\n    font-size: 1.5em;\n  }\n\n  h5 {\n    font-size: 1.25em;\n  }\n\n  h6 {\n    font-size: 1em;\n  }\n  /* stylelint-disable a11y/line-height-is-vertical-rhythmed */\n  h1,\n  h2,\n  h3,\n  h4,\n  h5,\n  h6 {\n    border-bottom: 1px solid #d2dadf;\n    color: var(--v-utilGrayDark-base);\n    font-weight: 700;\n    line-height: 1.15;\n    margin-top: 1em;\n    padding-bottom: 0.7rem;\n    text-rendering: optimizeLegibility;\n  }\n  /* stylelint-enable */\n\n  ol,\n  p,\n  ul {\n    color: var(--v-utilGrayDark-base);\n    font-size: 1em;\n    line-height: 1.75;\n  }\n\n  p {\n    color: var(--v-utilGrayDark-base);\n    display: block;\n    margin-block-end: 1em;\n    margin-block-start: 1em;\n    margin-inline-end: 0;\n    margin-inline-start: 0;\n  }\n\n  img {\n    max-width: 100%;\n  }\n\n  a {\n    font-weight: 500;\n    text-decoration: none;\n  }\n\n  pre > code {\n    background-color: var(--v-appBackground-base);\n    border: 1px solid var(--v-appBackground-base);\n    border-radius: 2px;\n    color: var(--v-utilGrayMid-base);\n    display: block;\n    font-family: 'Source Code Pro', monospace;\n    font-size: 1em;\n    font-weight: 400;\n    line-height: 1.5;\n    margin-bottom: 1.6em;\n    margin-top: 16px;\n    max-width: 100%;\n    overflow: auto;\n    padding: 12px;\n    page-break-inside: avoid;\n    word-wrap: break-word;\n  }\n\n  p > code {\n    background-color: var(--v-appBackground-base);\n    border-radius: 3px;\n    color: var(--v-primary-base);\n    font-size: 0.85em;\n    margin: 0;\n    padding: 0.25rem 0.5rem;\n  }\n  /* stylelint-disable a11y/font-size-is-readable */\n  blockquote {\n    background-color: #fffaf1;\n    border-color: #e90;\n    border-left-style: solid;\n    border-left-width: 0.5rem;\n    font-size: 13px;\n    margin: 1rem 0;\n    padding: 0.1rem 1.5rem;\n  }\n  /* stylelint-enable */\n}\n"
  },
  {
    "path": "src/styles/playground.scss",
    "content": ".CodeMirror {\n  font-size: 1.1rem !important;\n  height: 100%;\n  padding: 5px;\n}\n\n.cm-s-playground {\n  &.CodeMirror {\n    background: var(--v-secondaryGrayDark-base);\n    color: #d6d5d4;\n  }\n\n  &.CodeMirror.light {\n    background: var(--v-secondaryGrayLight-base);\n    color: var(--v-secondaryGrayDark-base);\n  }\n\n  div.CodeMirror-selected {\n    background: #3a3432;\n  }\n\n  &.CodeMirror-empty {\n    color: #777;\n  }\n\n  .CodeMirror-gutters {\n    background: var(--v-secondaryGrayDark-base);\n    border-right: 0;\n  }\n\n  .CodeMirror-guttermarker {\n    color: #db2d20;\n  }\n\n  .CodeMirror-guttermarker-subtle,\n  .CodeMirror-linenumber {\n    color: var(--v-secondaryGray-base);\n  }\n\n  .CodeMirror-cursor {\n    border-left: 1px solid #807d7c;\n  }\n\n  span {\n    &.cm-comment {\n      color: #666;\n    }\n\n    &.cm-atom,\n    &.cm-number {\n      color: #a16a94;\n    }\n\n    &.cm-property,\n    &.cm-attribute {\n      color: var(--v-accentOrange-base);\n    }\n\n    &.cm-keyword {\n      color: var(--v-codeBlue-base);\n    }\n\n    &.cm-string {\n      color: #fded02;\n    }\n\n    &.cm-variable {\n      color: #01a252;\n    }\n\n    &.cm-variable-2 {\n      color: #01a0e4;\n    }\n\n    &.cm-def {\n      color: var(--v-codePink-base);\n    }\n\n    &.cm-bracket {\n      color: #d6d5d4;\n    }\n\n    &.cm-tag {\n      color: #db2d20;\n    }\n\n    &.cm-link {\n      color: #a16a94;\n    }\n\n    &.cm-error {\n      background: #db2d20;\n      color: #807d7c;\n    }\n  }\n\n  .CodeMirror-activeline-background {\n    background: #2f2f2f;\n  }\n\n  .CodeMirror-matchingbracket {\n    color: #fff !important;\n    background-color: rgba(0, 115, 223, 0.5);\n  }\n}\n\n.cm-s-playground-light {\n  &.CodeMirror {\n    background: var(--v-secondaryGrayLight-base);\n    color: var(--v-secondaryGrayDark-base);\n    font-size: 0.85rem;\n  }\n\n  div.CodeMirror-selected {\n    background: #3a3432;\n  }\n\n  &.CodeMirror-empty {\n    color: #999;\n  }\n\n  .CodeMirror-gutters {\n    background: var(--v-secondaryGrayDark-base);\n    border-right: 0;\n  }\n\n  .CodeMirror-guttermarker {\n    color: #db2d20;\n  }\n\n  .CodeMirror-guttermarker-subtle,\n  .CodeMirror-linenumber {\n    color: var(--v-secondaryGray-base);\n  }\n\n  .CodeMirror-cursor {\n    border-left: 1px solid #807d7c;\n  }\n\n  span {\n    &.cm-comment {\n      color: #666;\n    }\n\n    &.cm-atom,\n    &.cm-number {\n      color: var(--v-codePink-base);\n    }\n\n    &.cm-property,\n    &.cm-attribute {\n      color: var(--v-accentOrange-base) !important;\n    }\n\n    &.cm-keyword {\n      color: var(--v-codeBlue-base);\n    }\n\n    &.cm-string {\n      color: #0075b8;\n    }\n\n    &.cm-variable {\n      color: #01a252;\n    }\n\n    &.cm-variable-2 {\n      color: #01a0e4;\n    }\n\n    &.cm-def {\n      color: var(--v-codePink-base);\n    }\n\n    &.cm-bracket {\n      color: #d6d5d4;\n    }\n\n    &.cm-tag {\n      color: #db2d20;\n    }\n\n    &.cm-link {\n      color: #a16a94;\n    }\n\n    &.cm-error {\n      background: #db2d20;\n      color: #807d7c;\n    }\n  }\n\n  .CodeMirror-activeline-background {\n    background: #2f2f2f;\n  }\n\n  .CodeMirror-matchingbracket {\n    color: #fff !important;\n    text-decoration: underline;\n  }\n}\n"
  },
  {
    "path": "src/styles/slash.scss",
    "content": "@keyframes slide-right-slant {\n  0% {\n    transform: skewY(-26deg) translate(0, 0);\n    width: 0%;\n  }\n\n  100% {\n    transform: skewY(-26deg) translate(0, -50%);\n    width: 100%;\n  }\n}\n\n@keyframes slide-left-slant {\n  0% {\n    transform: skewY(-26deg) translate(0, -50%);\n    width: 100%;\n  }\n\n  100% {\n    transform: skewY(-26deg) translate(0, 0);\n    width: 0%;\n  }\n}\n\n.slash {\n  animation-delay: unset;\n  position: relative;\n\n  &::before {\n    content: '';\n    height: inherit;\n    position: absolute;\n    transform: skewY(-26deg) translate(0, -50%);\n    transform-origin: inherit;\n    transform-origin: 50% 50%;\n    transition-delay: inherit !important;\n    transition-duration: 500ms;\n    transition-property: all;\n    width: 100%;\n    z-index: 0;\n  }\n\n  &.paused::before {\n    animation-play-state: paused;\n    transform: skewY(-26deg) translate(0, 0);\n    width: 0 !important;\n  }\n\n  &.slash-shadow::before {\n    box-shadow: 0 7px 8px -4px rgba(0, 0, 0, 0.2),\n      0 12px 17px 2px rgba(0, 0, 0, 0.14), 0 5px 22px 4px rgba(0, 0, 0, 0.12) !important;\n  }\n\n  &.slash-enter::before {\n    animation-delay: inherit !important;\n    animation-duration: 500ms;\n    animation-fill-mode: forwards;\n    animation-name: slide-right-slant;\n    animation-timing-function: ease-in-out;\n  }\n\n  &.slash-leave::before {\n    animation-delay: 0 !important;\n    animation-duration: 500ms;\n    animation-fill-mode: forwards;\n    animation-name: slide-left-slant;\n    animation-timing-function: ease-in-out;\n  }\n\n  &.slash-origin-left {\n    &::before {\n      left: 0;\n    }\n  }\n\n  &.slash-origin-right {\n    &::before {\n      right: 0;\n    }\n  }\n\n  &.slash-reverse::before {\n    transform: skewY(26deg);\n  }\n\n  &.slash-grey::before {\n    background-image: linear-gradient(\n      105deg,\n      #647489,\n      var(--v-secondary-base)\n    ) !important;\n  }\n\n  &.slash-grey-reverse::before {\n    background-image: linear-gradient(\n      105deg,\n      var(--v-secondary-base),\n      #647489\n    ) !important;\n  }\n\n  &.slash-orange::before {\n    background-image: linear-gradient(105deg, #ff60de, #ff4d20) !important;\n  }\n\n  &.slash-pink::before {\n    background-image: linear-gradient(105deg, #ff4d20, #ff60de) !important;\n  }\n\n  &.slash-blue::before {\n    background-image: linear-gradient(\n      105deg,\n      var(--v-accentCyan-base),\n      #0e50f5\n    ) !important;\n  }\n\n  &.slash-light-blue::before {\n    background-image: linear-gradient(\n      105deg,\n      #0e50f5,\n      var(--v-accentCyan-base)\n    ) !important;\n  }\n\n  div {\n    z-index: 1 !important;\n  }\n}\n\n.slash-horizontal {\n  position: relative;\n  transition: all 250ms;\n  width: 100%;\n\n  &::before {\n    content: '';\n    height: inherit;\n    left: 0;\n    position: absolute;\n    right: 0;\n    top: 0;\n    transform-origin: inherit;\n    transition: all 250ms;\n    transition-delay: 250ms;\n    width: 100%;\n    z-index: 0;\n  }\n\n  &.slash-grey::before {\n    background-image: linear-gradient(\n      105deg,\n      #647489,\n      var(--v-secondary-base)\n    ) !important;\n  }\n\n  &.slash-grey-reverse::before {\n    background-image: linear-gradient(\n      105deg,\n      var(--v-secondary-base),\n      #647489\n    ) !important;\n  }\n\n  &.slash-blue::before {\n    background-image: linear-gradient(\n      105deg,\n      var(--v-accentCyan-base),\n      #0e50f5\n    ) !important;\n  }\n\n  &.slash-orange::before {\n    background-image: linear-gradient(105deg, #ff60de, #ff4d20) !important;\n  }\n\n  &.slash-pink::before {\n    background-image: linear-gradient(105deg, #ff4d20, #ff60de) !important;\n  }\n\n  div {\n    z-index: 1 !important;\n  }\n\n  &.slash-shadow::before {\n    box-shadow: 0 7px 8px -4px rgba(0, 0, 0, 0.2),\n      0 12px 17px 2px rgba(0, 0, 0, 0.14), 0 5px 22px 4px rgba(0, 0, 0, 0.12) !important;\n  }\n}\n"
  },
  {
    "path": "src/styles/yaml-input-style.scss",
    "content": "/* stylelint-disable */\n\n.cm-s-yaml-input.CodeMirror {\n  background-color: var(--v-appForeground-base) !important;\n  color: var(--v-utilGrayDark-base) !important;\n\n  .CodeMirror-code {\n    letter-spacing: 0.15rem;\n  }\n\n  div.CodeMirror-selected {\n    background: var(--v-primaryLight-base) !important;\n  }\n\n  .CodeMirror-line {\n    &::selection,\n    > span::selection,\n    > span > span::selection {\n      background: var(--v-primaryLight-base) !important;\n    }\n  }\n\n  .CodeMirror-gutters {\n    background: #f8f8f8 !important;\n    border-left: 6px solid rgba(0, 83, 159, 0.65) !important;\n    color: #333 !important;\n  }\n\n  .CodeMirror-linenumber {\n    color: #aaa !important;\n    padding-left: 8px !important;\n  }\n\n  .CodeMirror-cursor {\n    border-left: 1px solid var(--v-utilGrayMid-base) !important;\n  }\n\n  .cm-keyword {\n    color: #6262ff !important;\n  }\n\n  .cm-atom {\n    color: var(--v-accentOrange-base) !important;\n  }\n\n  .cm-number {\n    color: var(--v-accentGreen-base) !important;\n  }\n\n  .cm-def {\n    color: #8da6ce !important;\n  }\n\n  span.cm-variable-2,\n  span.cm-tag {\n    color: #690 !important;\n  }\n\n  span.cm-variable-3,\n  span.cm-def,\n  span.cm-type {\n    color: var(--v-error-base) !important;\n  }\n\n  .cm-variable {\n    color: var(--v-error-base) !important;\n  }\n\n  .cm-qualifier {\n    color: #690 !important;\n  }\n\n  .cm-operator {\n    color: var(--v-error-base) !important;\n  }\n\n  .cm-comment {\n    color: var(--v-utilGrayMid-base) !important;\n    font-weight: normal !important;\n  }\n  .cm-string {\n    color: var(--v-accentPink-base) !important;\n  }\n\n  .cm-property.cm-string {\n    color: var(--v-tertiaryBlue-base) !important;\n  }\n\n  .cm-property {\n    color: var(--v-error-base) !important;\n  }\n\n  .cm-string-2 {\n    color: var(--v-error-base) !important;\n  }\n  .cm-meta {\n    color: #000 !important;\n  }\n\n  .cm-builtin {\n    color: #deaa54 !important;\n  }\n\n  .cm-tag {\n    color: #ff9447 !important;\n  }\n\n  .cm-attribute {\n    color: #d6bb6d !important;\n  }\n\n  .cm-header {\n    color: #ea5a2e !important;\n  }\n\n  .cm-hr {\n    color: #aeaeae !important;\n  }\n\n  .cm-link {\n    color: #42c1d6 !important;\n    font-style: italic !important;\n    text-decoration: none !important;\n  }\n\n  .cm-error {\n    border-bottom: 1px solid red !important;\n  }\n\n  div .CodeMirror-activeline-background {\n    background: #efefff !important;\n  }\n\n  div span.CodeMirror-matchingbracket {\n    background-color: rgb(69, 90, 100, 0.35) !important;\n    color: inherit !important;\n  }\n}\n\n/* stylelint-enable */\n"
  },
  {
    "path": "src/utils/Tree.js",
    "content": "export function Tree(tree) {\n  this.tree = tree\n  this.arr = []\n  this.mapping = {}\n\n  this.inOrder(this.tree)\n\n  this.height = this.calcHeight()\n  this.width = this.calcWidth()\n}\n\nTree.prototype.inOrder = function(node, row = 0) {\n  if (node == null) return\n  let _row = row\n\n  if (!this.mapping[node.id] && node.id) {\n    _row = row + 1\n\n    this.arr[row]\n      ? this.arr[row].push(node.children.length)\n      : (this.arr[row] = [node.children.length])\n\n    this.mapping[node.id] = true\n  }\n\n  let len = node.children.length\n\n  for (let i = 0; i < len; ++i) {\n    this.inOrder(node.children[i], _row)\n  }\n}\n\nTree.prototype.calcWidth = function() {\n  let height = 0\n  let len = this.arr.length\n  for (let i = 0; i < len; ++i) {\n    height = this.arr[i].length > height ? this.arr[i].length : height\n  }\n  return height\n}\n\nTree.prototype.calcHeight = function() {\n  return this.arr.length\n}\n"
  },
  {
    "path": "src/utils/array.js",
    "content": "// fisher yates shuffle\nexport function shuffle(inputArray) {\n  // Copy array so as not to mutate\n  let array = [...inputArray]\n  let currentIndex = array.length,\n    temporaryValue,\n    randomIndex\n\n  // While there remain elements to shuffle...\n  while (0 !== currentIndex) {\n    // Pick a remaining element...\n    randomIndex = Math.floor(Math.random() * currentIndex)\n    currentIndex -= 1\n\n    // And swap it with the current element.\n    temporaryValue = array[currentIndex]\n    array[currentIndex] = array[randomIndex]\n    array[randomIndex] = temporaryValue\n  }\n\n  return array\n}\n"
  },
  {
    "path": "src/utils/automations.js",
    "content": "export const presentTenseStates = {\n  FAILED: 'fails',\n  PENDING: 'is pending',\n  SCHEDULED: 'is scheduled',\n  RETRYING: 'retries',\n  RESUME: 'resumes',\n  QUEUED: 'is queued',\n  SUBMITTED: 'is submitted',\n  PAUSED: 'pauses',\n  RUNNING: 'runs',\n  FINISHED: 'finishes',\n  SUCCESS: 'succeeds',\n  CANCELLED: 'is cancelled',\n  CACHED: 'is cached',\n  TRIGGERFAILED: 'trigger fails',\n  SKIPPED: 'skips',\n  TIMEDOUT: 'times out',\n  MAPPED: 'maps',\n  LOOPED: 'loops'\n}\n\nexport const titleCasePresentTenseStates = {\n  Failed: 'fails',\n  Pending: 'is pending',\n  Scheduled: 'is scheduled',\n  Retrying: 'retries',\n  RESUME: 'resumes',\n  Queued: 'is queued',\n  Submitted: 'is submitted',\n  PAUSED: 'pauses',\n  Running: 'runs',\n  Finished: 'finishes',\n  Success: 'succeeds',\n  Cancelled: 'is cancelled',\n  Cached: 'is cached',\n  Triggerfailed: 'trigger fails',\n  Skipped: 'skips',\n  Timedout: 'times out',\n  Mapped: 'maps',\n  Looped: 'loops'\n}\n\n//Can use requiresCloud or specific permission type to filter where needed\nexport const actionTypes = [\n  {\n    title: 'Email',\n    type: 'EMAIL',\n    actionType: 'EmailNotificationAction',\n    verb: 'email',\n    sendText: 'Send an',\n    icon: 'fas fa-envelope',\n    config: { to: null },\n    requiresCloud: true\n  },\n  {\n    title: 'Slack',\n    type: 'SLACK_WEBHOOK',\n    actionType: 'SlackNotificationAction',\n    verb: 'slack',\n    sendText: 'Send a',\n    icon: 'fab fa-slack',\n    config: { url: null },\n    requiresCloud: false\n  },\n  {\n    title: 'Twilio',\n    type: 'TWILIO',\n    actionType: 'TwilioNotificationAction',\n    sendText: 'Send a',\n    verb: 'twilio',\n    icon: '$twilio',\n    config: {\n      account_sid: null,\n      auth_token: null,\n      to: [],\n      messaging_service_sid: null\n    },\n    requiresCloud: false\n  },\n  {\n    title: 'PagerDuty',\n    sendText: 'Send a',\n    type: 'PAGERDUTY',\n    actionType: 'PagerDutyNotificationAction',\n    verb: 'PagerDuty',\n    icon: '$pagerDuty',\n    config: { routing_key: null, api_token: null, severity: [] },\n    requiresCloud: false\n  },\n  {\n    title: 'Microsoft Teams',\n    sendText: 'Send a',\n    type: 'MS_TEAMS',\n    actionType: 'TeamsWebhookNotificationAction',\n    verb: 'teams',\n    icon: 'fab fa-microsoft',\n    config: { webhook_url_secret: null, message: null, title: null },\n    requiresCloud: true\n  },\n  {\n    title: 'Webhook',\n    sendText: 'Send a',\n    verb: 'send webhook to',\n    type: 'WEBHOOK',\n    icon: 'fas fa-desktop',\n    config: { to: null },\n    requiresCloud: false\n  }\n]\n\nexport const featureFlaggedEventTypes = [...actionTypes]\n\nexport const flowEventTypes = [\n  {\n    name: 'changes state',\n    enum: 'CHANGES_STATE',\n    permission: null\n  },\n  {\n    name: 'does not finish',\n    enum: 'STARTED_NOT_FINISHED',\n    permission: 'feature:flow-sla'\n  },\n  {\n    name: 'does not start',\n    enum: 'SCHEDULED_NOT_STARTED',\n    permission: 'feature:flow-sla'\n  }\n]\n\nexport const AUTOMATIONSTATES = {\n  All: [\n    'Failed',\n    'Pending',\n    'Scheduled',\n    'Retrying',\n    'Resume',\n    'Queued',\n    'Submitted',\n    'Paused',\n    'Running',\n    'Finished',\n    'Success',\n    'Cancelled',\n    'Cached',\n    'Triggerfailed',\n    'Skipped',\n    'Timedout',\n    'Mapped',\n    'Looped'\n  ],\n  Failed: ['Failed', 'Timedout', 'Triggerfailed'],\n  Finished: [\n    'Finished',\n    'Looped',\n    'Cancelled',\n    'Success',\n    'Cached',\n    'Mapped',\n    'Skipped'\n  ],\n  Success: ['Success', 'Cached', 'Mapped', 'Skipped'],\n  Custom: []\n}\n\nexport const jsonPlacehold = {\n  jsonBlob: {\n    event_name: '{event_type}',\n    message: '',\n    tenant_id: '{tenant_id}',\n    tenant_slug: '{tenant_slug}',\n    timestamp: '',\n    id: '{event_id}',\n    flow_id: '{flow_id}',\n    flow_name: '{flow_name}',\n    flow_group_id: '{flow_group_id}',\n    flow_link: '{flow_link}',\n    flow_run_id: '{flow_run_id}',\n    flow_run_name: '{flow_run_name}',\n    state: '{state}',\n    state_message: '{state_message}',\n    flow_run_link: '{flow_run_link}',\n    flow_sla_config_id: '{flow_sla_config_id}',\n    kind: '{flow_sla_type}',\n    duration_seconds: '{duration}',\n    event_type: '{event_type}'\n  }\n}\n"
  },
  {
    "path": "src/utils/cloudHooks.js",
    "content": "export const openCloudHookTypes = [\n  {\n    title: 'Email',\n    type: 'EMAIL',\n    icon: 'fas fa-envelope',\n    config: { to: null },\n    requiresCloud: true\n  },\n  {\n    title: 'Slack',\n    type: 'SLACK_WEBHOOK',\n    icon: 'fab fa-slack',\n    config: { url: null },\n    requiresCloud: false\n  },\n  {\n    title: 'Twilio',\n    type: 'TWILIO',\n    icon: '$twilio',\n    config: {\n      account_sid: null,\n      auth_token: null,\n      to: [],\n      messaging_service_sid: null\n    },\n    requiresCloud: false\n  },\n  {\n    title: 'PagerDuty',\n    type: 'PAGERDUTY',\n    icon: '$pagerDuty',\n    config: { routing_key: null, api_token: null, severity: [] },\n    requiresCloud: false\n  },\n  {\n    title: 'Web',\n    type: 'WEBHOOK',\n    icon: 'fas fa-desktop',\n    config: { to: null },\n    requiresCloud: false\n  },\n  {\n    title: 'Prefect',\n    type: 'PREFECT_MESSAGE',\n    icon: '$prefect',\n    config: {},\n    requiresCloud: false\n  }\n]\n\nexport const presentTenseStates = {\n  FAILED: 'fails',\n  PENDING: 'is pending',\n  SCHEDULED: 'is scheduled',\n  RETRYING: 'retries',\n  // RESUME: 'resumes',\n  QUEUED: 'is queued',\n  SUBMITTED: 'is submitted',\n  // PAUSED: 'pauses',\n  RUNNING: 'runs',\n  FINISHED: 'finishes',\n  SUCCESS: 'succeeds',\n  CANCELLED: 'is cancelled',\n  CACHED: 'is cached',\n  TRIGGERFAILED: 'trigger fails',\n  SKIPPED: 'skips',\n  TIMEDOUT: 'times out',\n  MAPPED: 'maps',\n  LOOPED: 'loops'\n}\n\nexport const titleCasePresentTenseStates = {\n  Failed: 'fails',\n  Pending: 'is pending',\n  Scheduled: 'is scheduled',\n  Retrying: 'retries',\n  // RESUME: 'resumes',\n  Queued: 'is queued',\n  Submitted: 'is submitted',\n  // PAUSED: 'pauses',\n  Running: 'runs',\n  Finished: 'finishes',\n  Success: 'succeeds',\n  Cancelled: 'is cancelled',\n  Cached: 'is cached',\n  Triggerfailed: 'trigger fails',\n  Skipped: 'skips',\n  Timedout: 'times out',\n  Mapped: 'maps',\n  Looped: 'loops'\n}\n\nexport const featureFlaggedCloudHookTypes = [...openCloudHookTypes]\n\nexport const GROUP_COLORS = {\n  All: 'primary',\n  Custom: 'codePink',\n  Failed: 'Failed',\n  Finished: 'Finished',\n  Success: 'Success'\n}\n\nexport const STATES = {\n  All: [\n    'FAILED',\n    'PENDING',\n    'SCHEDULED',\n    'RETRYING',\n    'RESUME',\n    'QUEUED',\n    'SUBMITTED',\n    'PAUSED',\n    'RUNNING',\n    'FINISHED',\n    'SUCCESS',\n    'CANCELLED',\n    'CACHED',\n    'TRIGGERFAILED',\n    'SKIPPED',\n    'TIMEDOUT',\n    'MAPPED',\n    'LOOPED'\n  ],\n  Failed: ['FAILED', 'TIMEDOUT', 'TRIGGERFAILED'],\n  Finished: [\n    'FINISHED',\n    'LOOPED',\n    'CANCELLED',\n    'SUCCESS',\n    'CACHED',\n    'MAPPED',\n    'SKIPPED'\n  ],\n  Success: ['SUCCESS', 'CACHED', 'MAPPED', 'SKIPPED']\n}\n"
  },
  {
    "path": "src/utils/cron.js",
    "content": "export const months = {\n  1: 'January',\n  2: 'February',\n  3: 'March',\n  4: 'April',\n  5: 'May',\n  6: 'June',\n  7: 'July',\n  8: 'August',\n  9: 'September',\n  10: 'October',\n  11: 'November',\n  12: 'December',\n  get JAN() {\n    return this[1]\n  },\n  get FEB() {\n    return this[2]\n  },\n  get MAR() {\n    return this[3]\n  },\n  get APR() {\n    return this[4]\n  },\n  get MAY() {\n    return this[5]\n  },\n  get JUN() {\n    return this[6]\n  },\n  get JUL() {\n    return this[7]\n  },\n  get AUG() {\n    return this[8]\n  },\n  get SEP() {\n    return this[9]\n  },\n  get OCT() {\n    return this[10]\n  },\n  get NOV() {\n    return this[11]\n  },\n  get DEC() {\n    return this[12]\n  }\n}\n\nexport const daysWeek = {\n  0: 'Sunday',\n  1: 'Monday',\n  2: 'Tuesday',\n  3: 'Wednesday',\n  4: 'Thursday',\n  5: 'Friday',\n  6: 'Saturday',\n  get SUN() {\n    return this[0]\n  },\n  get MON() {\n    return this[1]\n  },\n  get TUE() {\n    return this[2]\n  },\n  get WED() {\n    return this[3]\n  },\n  get THU() {\n    return this[4]\n  },\n  get FRI() {\n    return this[5]\n  },\n  get SAT() {\n    return this[6]\n  }\n}\n\nexport const common = {\n  '* * * * *': 'every minute',\n  '* * * * * *': 'every minute',\n  '0 * * * *': 'every hour',\n  '0 * * * * *': 'every hour',\n  '0 0 * * * *': 'every day at 12:00 AM',\n  '0 0 * * *': 'every day at 12:00 AM',\n  '0 0 1 * *': '12:00 AM on the 1st day of every month',\n  '0 0 1 * * *': '12:00 AM on the 1st day of every month'\n}\n\n// Returns nothing, a comma, or 'and'\n// depending on a list and the position of the\n// element in the list\nexport const oxfordList = (list, i) => {\n  const required = list.length > 2\n  const isTwoElements = list.length == 2\n  const isLast = i + 1 == list.length\n  const isSecondToLast = i + 2 == list.length\n\n  if (required && !isLast && !isSecondToLast) {\n    return ', '\n  }\n\n  if (required && isSecondToLast) {\n    return ', and '\n  }\n\n  if (isTwoElements && i === 0) {\n    return ' and '\n  }\n\n  return ''\n}\n"
  },
  {
    "path": "src/utils/curveMetro.js",
    "content": "function Turn(context) {\n  this._context = context\n}\n\nexport function isDiagonal(x1, y1, x2, y2) {\n  return x2 !== x1 && y2 !== y1\n}\n\nexport function makeQuadraticBezierPoints(x1, y1, x2, y2) {\n  const turnDist = 0.3\n\n  let py1 = 0,\n    py2 = 0,\n    dy = y2 - y1,\n    dist = Math.abs(dy) * turnDist\n\n  if (dy > 0) {\n    py1 = y1 + dist\n    py2 = y2 - dist\n  } else {\n    py1 = y1 - dist\n    py2 = y2 + dist\n  }\n\n  return [\n    [x1, py1],\n    [x2, py2]\n  ]\n}\n\nTurn.prototype = {\n  lineStart: function() {\n    this._point = 0\n    this._x = this._y = null\n  },\n  lineEnd: function() {},\n  point: function(x, y) {\n    x = +x\n    y = +y\n\n    switch (this._point) {\n      case 0:\n        this._context.moveTo(x, y)\n        this._point = 1\n        break\n      default:\n        this._point = 2\n        if (isDiagonal(this._x, this._y, x, y)) {\n          let to = makeQuadraticBezierPoints(this._x, this._y, x, y)\n          this._context.lineTo(...to[0])\n          this._context.lineTo(...to[1])\n        }\n        this._context.lineTo(x, y)\n        break\n    }\n\n    this._x = x\n    this._y = y\n  }\n}\n\nexport const curveMetro = function(context) {\n  return new Turn(context)\n}\n"
  },
  {
    "path": "src/utils/dateTime.js",
    "content": "import { duration } from '@/utils/moment'\nimport moment from '@/utils/moment'\nimport { toPluralString } from '@/utils/string'\n\nexport const MS_PER_SECOND = 1000\nexport const MS_PER_MINUTE = MS_PER_SECOND * 60\nexport const MS_PER_HOUR = MS_PER_MINUTE * 60\nexport const MS_PER_DAY = MS_PER_HOUR * 24\n\nexport const runTimeToEnglish = (startDate, endDate) => {\n  if (\n    !startDate ||\n    !endDate ||\n    !(startDate instanceof Date) ||\n    !(endDate instanceof Date)\n  ) {\n    return ''\n  }\n\n  const runTimeInMilliseconds = endDate - startDate\n  const runTime = duration(runTimeInMilliseconds)\n\n  if (runTimeInMilliseconds === 0) {\n    return '0 seconds'\n  } else if (runTime >= duration(1, 'week')) {\n    return runTime.format('w [weeks], d [days], h [hours]')\n  } else if (runTime >= duration(1, 'day')) {\n    return runTime.format('d [days], h [hours], m [minutes]')\n  } else if (runTime >= duration(1, 'hour')) {\n    return runTime.format('h [hours], m [minutes], s [seconds]')\n  } else if (runTime >= duration(1, 'minute')) {\n    return runTime.format('m [minutes], s [seconds]')\n  } else if (runTime >= duration(1, 'second')) {\n    return runTime.format('s [seconds]')\n  } else if (runTime < duration(1, 'second')) {\n    return '~1 second'\n  }\n  return runTime.humanize()\n}\n\nexport const durationToEnglish = durationString => {\n  if (!durationString) return ''\n\n  const runTime = duration(durationString)\n\n  if (runTime >= duration(1, 'week')) {\n    return runTime.format('w [weeks], d [days], h [hours]')\n  } else if (runTime >= duration(1, 'day')) {\n    return runTime.format('d [days], h [hours], m [minutes]')\n  } else if (runTime >= duration(1, 'hour')) {\n    return runTime.format('h [hours], m [minutes], s [seconds]')\n  } else if (runTime >= duration(1, 'minute')) {\n    return runTime.format('m [minutes], s [seconds]')\n  } else if (runTime >= duration(1, 'second')) {\n    return runTime.format('s [seconds]')\n  } else if (runTime < duration(1, 'second')) {\n    return '< 1 second'\n  }\n  return runTime.humanize()\n}\n\nexport const intervalToEnglish = numberOfMilliseconds => {\n  if (numberOfMilliseconds === 604800000) {\n    return 'Weekly'\n  } else if (numberOfMilliseconds === 86400000) {\n    return 'Daily'\n  } else if (numberOfMilliseconds === 3600000) {\n    return 'Hourly'\n  } else if (numberOfMilliseconds === 60000) {\n    return 'Every minute'\n  } else if (numberOfMilliseconds === 1000) {\n    return 'Every second'\n  }\n\n  const interval = duration(numberOfMilliseconds)\n\n  if (interval > duration(1, 'week')) {\n    return interval.format('[Every] w [weeks], d [days], h [hours]', {\n      trim: 'both'\n    })\n  } else if (interval > duration(1, 'day')) {\n    return interval.format('[Every] d [days], h [hours], m [minutes]', {\n      trim: 'both'\n    })\n  } else if (interval > duration(1, 'hour')) {\n    return interval.format('[Every] h [hours], m [minutes], s [seconds]', {\n      trim: 'both'\n    })\n  } else if (interval > duration(1, 'minute')) {\n    return interval.format('[Every] m [minutes], s [seconds]', { trim: 'both' })\n  } else if (interval < duration(1, 'minute')) {\n    return interval.format('[Every] s [seconds]', { trim: 'both' })\n  }\n  return ''\n}\n\nexport const oneAgo = unitOftime => {\n  return moment\n    .utc()\n    .subtract(1, unitOftime)\n    .format()\n}\n\nexport const roundedOneAgo = unitOftime => {\n  let roundedTo\n\n  switch (unitOftime) {\n    case 'year':\n      roundedTo = 'month'\n      break\n    case 'month':\n      roundedTo = 'day'\n      break\n    case 'day':\n      roundedTo = 'hour'\n      break\n    case 'hour':\n      roundedTo = 'minute'\n      break\n    case 'minute':\n      roundedTo = 'second'\n      break\n  }\n\n  return moment\n    .utc()\n    .subtract(1, unitOftime)\n    .startOf(roundedTo)\n    .format()\n}\n\nexport function isIsoDateString(value) {\n  return /\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d/.test(value)\n}\n\nexport function getMillisecondsUntilNextSecond() {\n  const now = new Date()\n  return MS_PER_SECOND - now.getMilliseconds()\n}\n\nexport function getMillisecondsUntilNextMinute() {\n  const now = new Date()\n  return MS_PER_MINUTE - now.getSeconds() * getMillisecondsUntilNextSecond()\n}\n\nexport function getMillisecondsUntilNextHour() {\n  const now = new Date()\n  return MS_PER_HOUR - now.getMinutes() * getMillisecondsUntilNextMinute()\n}\n\nexport function durationDifference(start, end) {\n  const difference = end - start\n  const day = Math.floor(difference / MS_PER_DAY)\n  const hour = Math.floor((difference % MS_PER_DAY) / MS_PER_HOUR)\n  const minute = Math.floor((difference % MS_PER_HOUR) / MS_PER_MINUTE)\n  const second = Math.floor((difference % MS_PER_MINUTE) / MS_PER_SECOND)\n\n  return { day, hour, minute, second }\n}\n\nexport function toDurationDifferenceString(durationDifference) {\n  return Object.entries(durationDifference)\n    .reduce((blocks, [key, value]) => {\n      if (blocks.length < 2 && value > 0) {\n        blocks.push(`${value} ${toPluralString(key, value)}`)\n      }\n\n      return blocks\n    }, [])\n    .join(', ')\n}\n"
  },
  {
    "path": "src/utils/error.js",
    "content": "export const ERROR_MESSAGE =\n  'Oops! Something went wrong - please try again in a few minutes. If the issue persists, try logging out and back in again.'\n"
  },
  {
    "path": "src/utils/features.js",
    "content": "export const featureTypes = [\n  {\n    color: 'accentOrange',\n    type: 'version-locking',\n    title: 'Version Locking',\n    icon: 'lock',\n    text:\n      'Ensure your flows and tasks never run unexpectedly with opt-in version-locking.',\n    link:\n      'https://docs.prefect.io/orchestration/concepts/flows.html#flow-settings'\n  },\n  {\n    color: 'accentCyan',\n    type: 'concurrency-limit',\n    title: 'Task Concurrency',\n    icon: 'pi-task-run',\n    text:\n      'Create team-wide task concurrency limits for fine-grained control of your running tasks - without ever leaving the UI.',\n    link:\n      'https://docs.prefect.io/orchestration/concepts/task-concurrency-limiting.html'\n  },\n  {\n    color: 'accentPink',\n    type: 'audit-trail',\n    title: 'Audit Trail',\n    icon: 'verified',\n    text:\n      \"Keep a record of all actions in your tenant to better understand your team's workflow and ensure security compliance.\",\n    link: ''\n  }\n]\n"
  },
  {
    "path": "src/utils/html.js",
    "content": "export function escapeHTML(value) {\n  return value\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&#x27;')\n}\n"
  },
  {
    "path": "src/utils/json.js",
    "content": "import jsBeautify from 'js-beautify'\n\nexport function tryFormatJson(value) {\n  if (value == null || typeof value !== 'object') {\n    return value\n  }\n\n  try {\n    return formatJson(value)\n  } catch {\n    return null\n  }\n}\n\nexport function tryFormatSingleLineJson(value) {\n  if (value == null || typeof value !== 'object') {\n    return value\n  }\n\n  try {\n    return formatSingleLineJson(value)\n  } catch {\n    return null\n  }\n}\n\nexport function formatJson(value) {\n  return jsBeautify(JSON.stringify(value), {\n    indent_size: 2,\n    space_in_empty_paren: true,\n    preserve_newlines: false\n  })\n}\n\nexport function formatSingleLineJson(value) {\n  const formatted = jsBeautify(JSON.stringify(value), {\n    indent_size: 0,\n    space_in_empty_paren: true,\n    preserve_newlines: false\n  })\n\n  return formatted.replace(/\\n/g, ' ')\n}\n\nexport function tryParseJson(value) {\n  try {\n    return parseJson(value)\n  } catch {\n    return null\n  }\n}\n\nexport function parseJson(value) {\n  return JSON.parse(value)\n}\n\nexport function isValidJson(value) {\n  try {\n    parseJson(value)\n    return true\n  } catch {\n    return false\n  }\n}\n"
  },
  {
    "path": "src/utils/markdownParser.js",
    "content": "import remark from 'remark'\nimport html from 'remark-html'\nimport breaks from 'remark-breaks'\nimport slug from 'remark-slug'\nimport headings from 'remark-autolink-headings'\nimport gfm from 'remark-gfm'\nimport all from 'mdast-util-to-hast/lib/all'\nimport normalize from 'mdurl/encode'\nimport u from 'unist-builder'\nimport table from 'mdast-util-to-hast/lib/handlers/table'\n\nexport function parser(md) {\n  let result = ''\n  if (typeof md === 'string') {\n    remark()\n      .use(breaks)\n      .use(slug)\n      .use(headings, {\n        content: {\n          type: 'text',\n          value: '# '\n        }\n      })\n      .use(html, {\n        sanitize: {\n          clobberPrefix: ''\n        }\n      })\n      .process(md, (err, file) => {\n        result = String(file)\n      })\n  } else {\n    result = `Error! A ${typeof md} was passed in instead of a string`\n  }\n  return result\n}\n\nexport function artifact_parser(md) {\n  let result = ''\n  if (typeof md === 'string') {\n    remark()\n      .use(breaks)\n      .use(slug)\n      .use(gfm)\n      .use(html, {\n        handlers: {\n          heading: function(h, node) {\n            node.data = {\n              hProperties: { className: ['h' + node.depth, 'mt-6'] }\n            }\n            return h(node, 'h' + node.depth, all(h, node))\n          },\n          link: function(h, node) {\n            let props = { href: normalize(node.url), target: '_blank' }\n\n            if (node.title !== null && node.title !== undefined) {\n              props.title = node.title\n            }\n\n            return h(node.position, 'span', [\n              h(node, 'a', props, all(h, node)),\n              h(node.position, 'sup', [\n                h(\n                  node.position,\n                  'i',\n                  {\n                    className: 'v-icon notranslate material-icons theme--light',\n                    style: 'font-size: 12px'\n                  },\n                  [u('text', 'open_in_new')]\n                )\n              ])\n            ])\n          },\n          paragraph: function(h, node) {\n            node.data = {\n              hProperties: { className: 'text-body-1' }\n            }\n            return h(node, 'p', all(h, node))\n          },\n          strong: function(h, node) {\n            node.data = {\n              hProperties: { className: 'font-weight-medium' }\n            }\n            return h(node, 'span', all(h, node))\n          },\n          table: function(h, node) {\n            node.data = {\n              hProperties: {\n                className: [\n                  'my-3',\n                  'grey',\n                  'lighten-5',\n                  'px-4',\n                  'py-2',\n                  'text--darken-2',\n                  'blue-grey--text'\n                ]\n              }\n            }\n            return table(h, node)\n          },\n          thematicBreak: function(h, node) {\n            node.data = {\n              hProperties: { className: ['my-6'] }\n            }\n            return h(node, 'hr')\n          }\n        }\n      })\n      .process(md, (err, str) => {\n        result = String(str)\n      })\n  } else {\n    result = `Error! A ${typeof md} was passed in instead of a string`\n  }\n  return result\n}\n\nexport function getRoutes() {\n  const context = require.context('../pages/Tutorials/Markdown')\n  const obj = context\n    .keys()\n    .map(context)\n    .map((content, i) => {\n      const htmlStr = parser(content)\n      const removeSlash = context.keys()[i].replace(/\\//g, '')\n      const removePeriod = removeSlash.replace(/\\./, '')\n      const file = removePeriod.replace(/\\.md/, '')\n      const allIds = htmlStr.match(/id=\"(.*?)\"/gm).map(id => {\n        const getIDName = id.replace(/id=\"/gm, '#').replace(/^\"|\"$/g, '')\n        return { name: getIDName, file }\n      })\n      return { name: file, children: allIds }\n    })\n  return obj\n}\n"
  },
  {
    "path": "src/utils/moment.js",
    "content": "/*\nWhy? momentDurationFormat is a plugin for moment.js\nBecause plugins for moment look for the defined moment instance by default, I'd like to use this file to install plugins for moment and then export particular functions from moment so that I can use plugins from those functions.\n\nFor example, with the code below Vue components can now:\nimport { duration } from '@/utils/moment'\nand use duration({{ input }}).format() without having to import moment and moment-duration-format.\n*/\nimport moment from 'moment-timezone'\n// eslint-disable-next-line no-unused-vars\nimport momentDurationFormat from 'moment-duration-format'\n\nexport const duration = moment.duration\n\nexport default moment\n"
  },
  {
    "path": "src/utils/ordinal.js",
    "content": "export const ordinal = n => {\n  n = parseInt(n)\n  return (\n    ['st', 'nd', 'rd'][(((((n < 0 ? -n : n) + 90) % 100) - 10) % 10) - 1] ||\n    'th'\n  )\n}\n"
  },
  {
    "path": "src/utils/plans.js",
    "content": "export const PLANS_2021 = {\n  free: {\n    name: 'Free',\n    price: 'Free',\n    taskRuns: 20000,\n    additionalCost: 0,\n    users: 1,\n    value: 'FREE_2021',\n    history: 'week',\n    title: 'developer'\n  },\n  starter: {\n    name: 'Starter',\n    price: '0.0025',\n    taskRuns: 20000,\n    additionalCost: null,\n    users: 1,\n    value: 'STARTER_2021',\n    history: 'week',\n    title: 'starter'\n  },\n  standard: {\n    name: 'Standard',\n    price: '0.0050',\n    taskRuns: 20000,\n    additionalCost: null,\n    value: 'STANDARD_2021',\n    users: 3,\n    history: 'month',\n    title: 'standard'\n  },\n  enterprise: {\n    name: 'Enterprise',\n    price: 'contact',\n    value: 'ENTERPRISE_2021',\n    taskRuns: 0,\n    additionalCost: 0.0025,\n    users: 'unlimited',\n    history: 'year',\n    title: 'enterprise'\n  }\n}\n\nexport const basicFeatures = [\n  {\n    name: 'Robust Scheduling',\n    description:\n      'Create custom schedules including business days, offsets, and blackout windows, or fall back on good old cron.'\n  },\n  {\n    name: 'Intelligent Scheduling',\n    description:\n      'Schedule varying parameter values or even where your runs should occur'\n  },\n  {\n    name: 'Artifacts',\n    description: 'Publish custom data and render it in the Prefect UI'\n  },\n  {\n    name: 'Mapping',\n    description: 'Dynamically generate parallel pipelines at runtime'\n  },\n  {\n    name: 'Retries',\n    description:\n      'Advanced checkpointing and real-time state reporting protect you from the unexpected'\n  },\n  {\n    name: 'Run History',\n    description:\n      'Use the Prefect UI to manage all of your flow runs, no matter how often or where they run'\n  },\n  {\n    name: 'Dataflow Automation',\n    description:\n      'Pass data between tasks for complex processing and advanced analytics'\n  },\n  {\n    name: 'Caching',\n    description:\n      'Persist the results of complex tasks with custom validation logic'\n  },\n  {\n    name: 'Versioning',\n    description:\n      \"Every Prefect flow is automatically versioned, so you're always up-to-date\"\n  }\n]\nexport const infrastructureFeatures = [\n  {\n    name: 'Hosted Orchestration Platform',\n    description:\n      'Focus on your code while Prefect Cloud manages a highly-available orchestration API',\n    plan: 'starter',\n    value: 1\n  },\n  {\n    name: 'Performance',\n    description: 'Run tasks as fast as your infrastructure allows',\n    plan: 'starter',\n    value: 1\n  },\n  {\n    name: 'API Security',\n    description: 'Permission access via API tokens',\n    plan: 'starter',\n    value: 1\n  },\n  {\n    name: 'Automatic Updates',\n    description:\n      'Prefect Cloud releases every two weeks with new features and performance enhancements',\n    plan: 'starter',\n    value: 1\n  },\n  {\n    name: 'Raise Rate Limits',\n    description: 'TK',\n    plan: 'enterprise',\n    value: 3\n  }\n]\nexport const observabilityFeatures = [\n  {\n    name: 'Logs Management',\n    description: 'Stream, filter, and examine all of your workflow logs',\n    plan: 'starter',\n    value: 1\n  },\n  {\n    name: 'Advanced Alerting',\n    description: 'Configure notifications when custom criteria are met',\n    plan: 'standard',\n    value: 2\n  },\n  {\n    name: 'Flow SLAs',\n    description: 'Set SLAs for late or long-running workflows',\n    plan: 'standard',\n    value: 2\n  },\n  {\n    name: 'Agent SLAs',\n    description: 'Set SLAs for agents to ensure uptime',\n    plan: 'standard',\n    value: 2\n  },\n  {\n    name: 'History Retention',\n    description: 'Track one year of run history',\n    plan: 'enterprise',\n    value: 3\n  },\n  {\n    name: 'Audit Trail',\n    description: 'Track every action taken via the Prefect API',\n    plan: 'enterprise',\n    value: 3\n  }\n]\nexport const orchestrationFeatures = [\n  {\n    name: 'Stateless Deployments',\n    description:\n      'Spin up and tear down agent deployments with ease - Prefect Cloud manages all state for you',\n    plan: 'starter',\n    value: 1\n  },\n  {\n    name: 'Multiple Execution Environments',\n    description:\n      'Promote your workflows from dev to prod with a single API call, or schedule them to run in multiple places at once!',\n    plan: 'starter',\n    value: 1\n  },\n  {\n    name: 'Secrets',\n    description: 'Manage sensitive information',\n    plan: 'starter',\n    value: 1\n  },\n  {\n    name: 'Advanced Automation',\n    description:\n      'Automatically configure API actions when custom criteria are met',\n    plan: 'standard',\n    value: 2\n  },\n  {\n    name: 'Concurrency Limits',\n    description:\n      'Set concurrency limits at the flow or task level to control access to resources',\n    plan: 'standard',\n    value: 2\n  }\n]\nexport const authorizationFeatures = [\n  {\n    name: 'Team Management',\n    description:\n      'Get a complete view of everyone who can access your workflows',\n    plan: 'starter',\n    value: 1\n  },\n  {\n    name: 'Read-Only Users',\n    description: 'Invite analyts to work with the output of your workflows',\n    plan: 'standard',\n    value: 2\n  },\n  {\n    name: 'Custom Permissions',\n    description: 'Assign granular permissions, including per-project limits',\n    plan: 'enterprise',\n    value: 3\n  },\n  {\n    name: 'SSO',\n    description: 'Log in to Prefect Cloud via SSO',\n    plan: 'enterprise',\n    value: 3\n  },\n  {\n    name: 'Custom Roles',\n    description: 'Create and assign custom roles',\n    plan: 'enterprise',\n    value: 3\n  }\n]\n"
  },
  {
    "path": "src/utils/regEx.js",
    "content": "const EMAIL_REGEX = /^(([^<>()[\\]\\\\.,;:\\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,}))$/\nconst PARSED_SCHEDULE_REGEX = /([0-9]{1,2}:?[0-9]{0,2})|(?:am|pm|days|day|years|year|weeks|week|hours|hour|minutes|minute|seconds|second|monday|tuesday|wednesday|thursday|friday|saturday|sunday|january|february|march|april|may|june|july|august|september|october|november|december)/gim\n\n// These work in most cases but don't protect against double dashes or slashes\n// e.g. 5/6/7 or 5-6-7\n// It gives us a pretty reasonable approximation of a valid string though.\n\n// [1-5]?[0-9]\n// Tests: https://regex101.com/r/e588QW/1\nconst CRON_MINUTE_REGEX = /(^\\*{1})$|(^(\\*\\/)?[1-5]?[0-9](?:[,-/][1-5]?[0-9])*$)/i\n\n// 2[0-3]|1[0-9]|[0-9]\n// Tests: https://regex101.com/r/5cbtnj/1\nconst CRON_HOUR_REGEX = /^(^\\*{1})$|(^(\\*\\/)?(2[0-3]|1[0-9]|[0-9])(?:[,-/](2[0-3]|1[0-9]|[0-9]))*$)/i\n\n// 3[01]|[12][0-9]|[1-9]\n// Tests: https://regex101.com/r/y1auyB/1\nconst CRON_DAY_MONTH_REGEX = /^(\\*{1})$|(^(\\*\\/)?(3[01]|[12][0-9]|[1-9])(?:[,-/](3[01]|[12][0-9]|[1-9]))*$)/i\n\n// 1[0-2]|[1-9]\n// Tests: https://regex101.com/r/dPw34Y/1\nconst CRON_MONTH_REGEX = /^(\\*{1})$|(^(\\*\\/)?(1[0-2]|[1-9])(?:[,-/](1[0-2]|[1-9]))*$)|(^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)(?:[,-/](jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec))*$)/i\n\n// [0-6]\n// Tests: https://regex101.com/r/G4cbea/1\nconst CRON_DAY_WEEK_REGEX = /^(\\*{1})$|(^(\\*\\/)?([0-6])(?:[,-/#]([0-6]))*$)|(^(sun|mon|tue|wed|thu|fri|sat)(?:[,-/#](sun|mon|tue|wed|thu|fri|sat))*$)/i\n\nexport {\n  EMAIL_REGEX,\n  PARSED_SCHEDULE_REGEX,\n  CRON_MINUTE_REGEX,\n  CRON_HOUR_REGEX,\n  CRON_DAY_MONTH_REGEX,\n  CRON_MONTH_REGEX,\n  CRON_DAY_WEEK_REGEX\n}\n"
  },
  {
    "path": "src/utils/roles.js",
    "content": "export const ROLE_MAP = {\n  READ_ONLY_USER: 'Read only',\n  ENTERPRISE_LICENSE_ADMIN: 'License administrator',\n  USER: 'User',\n  TENANT_ADMIN: 'Administrator',\n  PENDING: 'Pending'\n}\n\nexport const ROLE_COLOR_MAP = {\n  USER: 'codeBlueBright',\n  ENTERPRISE_LICENSE_ADMIN: 'accent',\n  READ_ONLY_USER: 'cloudUIPrimaryDark',\n  TENANT_ADMIN: 'cloudUIPrimaryBlue',\n  PENDING: 'accentOrange'\n}\n"
  },
  {
    "path": "src/utils/states.js",
    "content": "export const STATE_COLORS = {\n  Failed: '#eb0000',\n  Pending: '#b9dcff',\n  Scheduled: '#ffbe1e',\n  ScheduledAlt: '#ffeec4',\n  Retrying: '#fc7b09',\n  Resume: '#f58c0c',\n  Queued: '#fff9c2',\n  Submitted: '#fff499',\n  Paused: '#99a8e8',\n  Running: '#27b1ff',\n  Listening: '#93d8ff',\n  Finished: '#003483',\n  Success: '#2cbe4e',\n  Cancelled: '#bdbdbd',\n  Cancelling: '#E8E8E8',\n  Cached: '#74c367',\n  TriggerFailed: '#c42800',\n  Skipped: '#607583',\n  TimedOut: '#dc370b',\n  Mapped: '#4067a2',\n  Looped: '#4c4cff',\n  InProgress: '#93d2cc'\n}\n\nexport const STATE_TYPES = {\n  Failed: 'Finished',\n  Pending: 'Pending',\n  Scheduled: 'Pending',\n  Retrying: 'Pending',\n  Resume: 'Pending',\n  Submitted: 'Pending',\n  Paused: 'Pending',\n  Queued: 'Pending',\n  Running: 'Running',\n  Listening: 'Running',\n  Finished: 'Finished',\n  Success: 'Finished',\n  Cancelled: 'Finished',\n  Cancelling: 'Running',\n  Cached: 'Finished',\n  TriggerFailed: 'Finished',\n  Skipped: 'Finished',\n  TimedOut: 'Finished',\n  Mapped: 'Finished',\n  Looped: 'Finished'\n}\n\nexport const STATE_NAMES = [\n  'All',\n  'Success',\n  'Failed',\n  'Finished',\n  'Scheduled',\n  'Pending',\n  'Running',\n  'Cancelled',\n  'Cancelling',\n  'Cached',\n  'Retrying',\n  'Queued',\n  'Paused',\n  'Mapped',\n  'Looped',\n  'Skipped',\n  'Resume',\n  'Submitted',\n  'TriggerFailed',\n  'ValidationFailed'\n]\n\nexport const STATE_PAST_TENSE = {\n  Failed: 'failed',\n  Pending: 'are pending',\n  Scheduled: 'are scheduled',\n  Retrying: 'retried',\n  Resuming: 'were resumed',\n  Submitted: 'are submitted',\n  Paused: 'are paused',\n  Queued: 'are queued',\n  Running: 'are running',\n  Listening: 'are listening',\n  Finished: 'are finished',\n  Success: 'succeeded',\n  Cancelled: 'were cancelled',\n  Cancelling: 'are cancelling',\n  Cached: 'are cached',\n  TriggerFailed: 'had failed triggers',\n  Skipped: 'were skipped',\n  TimedOut: 'timed out',\n  Mapped: 'were mapped',\n  Looped: 'were looped'\n}\n\nexport const FINISHED_STATES = [\n  'Finished',\n  'Looped',\n  'Success',\n  'Cancelled',\n  'Failed',\n  'TriggerFailed',\n  'ValidationFailed',\n  'TimedOut',\n  'Cached',\n  'Mapped',\n  'Skipped'\n]\n\nexport function calculateDuration(startTime, endTime, state) {\n  if (endTime) {\n    return endTime\n  }\n\n  if (FINISHED_STATES.includes(state)) {\n    return startTime\n  }\n\n  return null\n}\n\nexport default function(state) {\n  return STATE_COLORS[state]\n}\n"
  },
  {
    "path": "src/utils/string.js",
    "content": "export function toPluralString(word, count) {\n  if (count == 1) {\n    return word\n  }\n\n  const ending = ['s', 'sh', 'ch', 'x', 'z'].some(chars => word.endsWith(chars))\n    ? 'es'\n    : 's'\n\n  return `${word}${ending}`\n}\n"
  },
  {
    "path": "src/utils/types.js",
    "content": "export const types = [\n  'None',\n  'Boolean',\n  'Integer',\n  'String',\n  'Dictionary',\n  'List',\n  'Date'\n]\n\nexport function isValidType(type) {\n  return types.includes(type)\n}\n"
  },
  {
    "path": "src/utils/yaml.js",
    "content": "import YAML from 'yaml'\n\nexport function formatYaml(value) {\n  if (value == null) {\n    return null\n  }\n\n  try {\n    return YAML.stringify(value)\n  } catch {\n    return null\n  }\n}\n\nexport function tryParseYaml(value) {\n  try {\n    return parseYaml(value)\n  } catch {\n    return null\n  }\n}\n\nexport function parseYaml(value) {\n  return YAML.parse(value)\n}\n\nexport function isValidYaml(value) {\n  try {\n    parseYaml(value)\n    return true\n  } catch {\n    return false\n  }\n}\n"
  },
  {
    "path": "src/vue-apollo.js",
    "content": "import Vue from 'vue'\nimport VueApollo from 'vue-apollo'\nimport {\n  createApolloClient,\n  restartWebsockets\n} from 'vue-cli-plugin-apollo/graphql-client'\nimport store from '@/store/index'\nimport { setContext } from 'apollo-link-context'\n\nimport { ApolloLink, Observable } from 'apollo-link'\n\nimport { BatchHttpLink } from 'apollo-link-batch-http'\nimport { onError } from 'apollo-link-error'\nimport { InMemoryCache } from 'apollo-cache-inmemory'\nimport { HttpLink } from '@apollo/client'\nimport LogRocket from 'logrocket'\n\n// Install the vue plugin\nVue.use(VueApollo)\n\n// Name of the localStorage item\nconst AUTH_TOKEN = 'authorization_token'\n\nfunction isExpired(expiry) {\n  return new Date().getTime() > expiry\n}\n\nfunction notExpired(expiry) {\n  return !isExpired(expiry)\n}\n\nlet errors = 0,\n  apiErrors = 0\n\nconst batchLink = new BatchHttpLink({\n  batchMax: 25,\n  batchInterval: 2000,\n  uri: () => store.getters['api/url']\n})\n\nconst httpLink = new HttpLink({ uri: () => store.getters['api/url'] })\n\n// Resets the cache and stops requests if\n// the backend has changed\nconst backendMiddleware = new ApolloLink((operation, forward) => {\n  const context = operation.getContext()\n  if (context.headers?.['X-Backend'] !== store.getters['api/backend']) {\n    defaultApolloClient.cache.reset()\n    return\n  }\n  return forward(operation).map(response => {\n    errors = 0\n    apiErrors = 0\n    return response\n  })\n})\n\n// Used to identify the request in the server\nconst headerMiddleware = setContext((_, { headers }) => {\n  headers['X-Prefect-UI'] = true\n  headers['X-Backend'] = store.getters['api/backend']\n  headers['X-Prefect-Tenant-ID'] = store.getters['tenant/tenant'].id\n  headers['X-Prefect-User-ID'] = store.getters['user/user'].id\n  headers['X-Frame-Options'] = 'deny'\n  headers['X-Content-Type-Options'] = 'nosniff'\n  headers['X-Permitted-Cross-Domain-Policies'] = 'none'\n  headers['Content-Security-Policy'] = \"default-src 'self'\"\n\n  return {\n    headers: {\n      ...headers\n    }\n  }\n})\n\n// After requests have been made, formats errors for the JS console\n// to easily track the error sources in collapsible traces\nconst errorAfterware = onError(\n  ({ response, operation, graphQLErrors, networkError, forward }) => {\n    // Only throw the API error once in a row\n    // (prevents spamming the console when there's no connection)\n    if (operation.operationName === 'Api') {\n      if (apiErrors > 0) {\n        // TODO: fix this\n        Observable\n        // return Observable.of()\n      }\n      apiErrors++\n    }\n\n    if (process.env.NODE_ENV !== 'production') {\n      /* eslint-disable no-console */\n      console.groupCollapsed(\n        `%c${operation.operationName || 'Unnamed Query'} error`,\n        'color: #D64292; font-weight:bold;'\n      )\n      console.log('Operation: ', operation)\n\n      if (graphQLErrors?.length > 0) {\n        console.group('%cGraphQL Errors', 'color: #CA9800; font-weight:bold;')\n        graphQLErrors?.forEach(error => {\n          console.group(\n            `%c${error.extensions?.code || 'ERROR'}`,\n            'color: #B11A04; font-weight:bold;'\n          )\n          console.log(`Message: ${error.message}`)\n          console.log('Full log: ', error)\n          console.groupEnd()\n        })\n        console.groupEnd()\n      }\n\n      if (networkError) {\n        console.group('%cNetwork Error', 'color: #CA9800; font-weight:bold;')\n        console.log(networkError)\n        console.groupEnd()\n      }\n      console.groupEnd()\n      /* eslint-enable no-console */\n    }\n\n    if (\n      store.getters['api/isCloud'] &&\n      graphQLErrors?.[0].message === 'Operation timed out'\n    ) {\n      LogRocket.captureException(operation, {\n        type: 'Timeout'\n      })\n      // For now we just capture Cloud errors,\n      // we can expand this if it's helpful for debugging later\n    } else if (\n      (store.getters['api/isCloud'] && graphQLErrors) ||\n      networkError\n    ) {\n      if (graphQLErrors) {\n        LogRocket.captureException(graphQLErrors, {\n          type: 'GraphQL Errors'\n        })\n      } else if (networkError)\n        LogRocket.captureException(networkError, {\n          type: 'Network Error'\n        })\n    }\n\n    if (response) {\n      response.errors = null\n    }\n    errors++\n    if (errors > 10) {\n      defaultApolloClient.stop()\n    }\n    // Can return Observable.of returned from error link to supress errors\n    //  otherwise return forward(operation)\n    // for a single retry of the failure\n    // if (process.env.NODE_ENV !== 'production') return Observable.of()\n    return forward(operation)\n  }\n)\n\nexport { errorAfterware }\n\n// Adds authorization headers to requests headed for the Cloud API;\n// just forwards requests if headed for a Server API\nconst authMiddleware = setContext(async (_, { headers }) => {\n  if (store.getters['api/isServer']) {\n    return {\n      headers: {\n        ...headers\n      }\n    }\n  }\n\n  const bearer = `Bearer ${store.getters['auth/authorizationToken']}`\n  return {\n    headers: {\n      ...headers,\n      authorization: bearer,\n      'authorization-expiry': store.getters['auth/authorizationTokenExpiry']\n    }\n  }\n})\n\n// The last link in the chain before the request is sent;\n// Checks that the request should be sent based on authorization header expiration\n// and stops the request if it shouldn't be\nconst terminalRequestLink = new ApolloLink((operation, forward) => {\n  if (store.getters['api/isServer']) return forward(operation)\n\n  const context = operation.getContext()\n  const expiration = context.headers?.['authorization-expiry']\n\n  // If there's no expiration, we forward the operation\n  if (!expiration) return forward(operation)\n\n  // otherwise we check that the authorization header hasn't expired before\n  // forwarding the request\n  if (notExpired(expiration)) return forward(operation)\n})\n\n// Apollo link chain; acts as middleware for GraphQL queries\nconst link = ApolloLink.from([\n  authMiddleware,\n  headerMiddleware,\n  backendMiddleware,\n  errorAfterware,\n  terminalRequestLink,\n  batchLink\n])\n\nconst fallbackLink = ApolloLink.from([\n  authMiddleware,\n  headerMiddleware,\n  backendMiddleware,\n  errorAfterware,\n  terminalRequestLink,\n  httpLink\n])\n\nexport const cache = new InMemoryCache({\n  resultCaching: false\n})\n\n// Config\nexport const defaultOptions = {\n  // You can use `https` for secure connection (recommended in production)\n  httpEndpoint: () => store.getters['api/url'],\n  // You can use `wss` for secure connection (recommended in production)\n  // Use `null` to disable subscriptions\n  wsEndpoint: null,\n  //'ws://localhost:4300',\n  // LocalStorage token\n  tokenName: AUTH_TOKEN,\n  // Enable Automatic Query persisting with Apollo Engine\n  persisting: false,\n  // Use websockets for everything (no HTTP)\n  // You need to pass a `wsEndpoint` for this to work\n  websocketsOnly: false,\n  // Is being rendered on the server?\n  ssr: false,\n\n  // Override default apollo link\n  // note: don't override httpLink here, specify httpLink options in the\n  // httpLinkOptions property of defaultOptions.\n  defaultHttpLink: false,\n  link: link,\n\n  // Override default cache\n  cache: cache,\n\n  // Override the way the Authorization header is set\n  // getAuth: () => ...\n\n  // Additional ApolloClient options\n  // apollo: { ... }\n\n  // Client local data (see apollo-link-state)\n  // clientState: { resolvers: { ... }, defaults: { ... } }\n  queryDeduplication: true\n}\n\nlet defaultApolloClient\nlet fallbackApolloClient\n\n// Create apollo client\nexport const createApolloProvider = (options = defaultOptions) => {\n  const { apolloClient, wsClient } = createApolloClient({\n    id: 'initial',\n    ...options\n  })\n  apolloClient.wsClient = wsClient\n\n  // Create vue apollo provider\n  const apolloProvider = new VueApollo({\n    defaultClient: apolloClient,\n    defaultOptions: {\n      $query: {\n        errorPolicy: 'all',\n        fetchPolicy: 'cache-and-network'\n      },\n      $subscription: {\n        errorPolicy: 'all'\n      }\n    }\n  })\n  return apolloProvider\n}\n\nexport const clearCache = () => {\n  defaultApolloClient.cache.reset()\n}\n\nexport const defaultApolloProvider = createApolloProvider()\ndefaultApolloClient = defaultApolloProvider.defaultClient\nexport { defaultApolloClient }\n\n// This is the client we use that is not subject to the stop/restarts of the application\nexport const fallbackApolloProvider = createApolloProvider({\n  ...defaultOptions,\n  link: fallbackLink\n})\nfallbackApolloClient = fallbackApolloProvider.defaultClient\nexport { fallbackApolloClient }\n\nexport async function apolloOnLogin(apolloClient) {\n  if (apolloClient.wsClient) restartWebsockets(apolloClient.wsClient)\n  await apolloClient.clearStore()\n}\n\nexport async function apolloOnLogout(apolloClient) {\n  if (apolloClient.wsClient) restartWebsockets(apolloClient.wsClient)\n  await apolloClient.clearStore()\n}\n"
  },
  {
    "path": "src/workers/auth.worker.js",
    "content": "import {\n  authorize,\n  refreshTokens,\n  authorizeTenant\n} from '@/auth/authorization.js'\nimport jwt_decode from 'jwt-decode'\n\nconst ports = []\nconst channelPorts = []\n\n/*\n    values in the tokens Array<Object> take the form:\n    \n    interface TenantTokens {\n        tenantId: string\n        authorizationToken: string\n        refreshToken: string\n    }\n\n*/\nconst state = {\n  idToken: null,\n  authorizationToken: null,\n  tenantId: null\n}\n\nconst postToConnections = payload => {\n  for (let i = 0; i < ports.length; ++i) {\n    ports[i].postMessage(payload)\n  }\n}\n\nconst postToChannelPorts = payload => {\n  for (let i = 0; i < ports.length; ++i) {\n    channelPorts[i]?.postMessage(payload)\n  }\n  channelPorts.length = 0\n}\n\nconsole.connect = payload => {\n  // eslint-disable\n  console.groupCollapsed('Auth worker trace', payload)\n  console.log(payload)\n  console.trace()\n  console.groupEnd()\n  // eslint-enable\n\n  for (let i = 0; i < ports.length; ++i) {\n    ports[i].postMessage({\n      type: 'console',\n      payload: payload\n    })\n  }\n}\n\nconst refreshAuthorizationToken = async () => {\n  const authorizationResponse = await refreshTokens(\n    state.authorizationToken.access_token,\n    state.authorizationToken.refresh_token\n  )\n\n  setAuthorizationToken(authorizationResponse)\n}\n\nconst handleSwitchTenant = async tenantId => {\n  const authorizationResponse = await authorizeTenant(\n    state.authorizationToken.access_token,\n    tenantId\n  )\n\n  setAuthorizationToken(authorizationResponse)\n\n  postToConnections({\n    type: 'switch-tenant',\n    payload: { token: state.authorizationToken, tenantId: tenantId }\n  })\n\n  console.connect({\n    message: 'handleSwitchTenant',\n    tokenExpiration: state.authorizationToken?.expires_at || 'No token',\n    tenantId: tenantId,\n    currentTime: Date.now()\n  })\n}\n\nlet authorizationTimeout = null\nconst setAuthorizationToken = token => {\n  clearTimeout(authorizationTimeout)\n  state.authorizationToken = token\n\n  postToChannelPorts({\n    type: 'authorizationToken',\n    payload: state.authorizationToken\n  })\n\n  postToConnections({\n    type: 'authorizationToken',\n    payload: state.authorizationToken\n  })\n\n  try {\n    const expiration = new Date(token.expires_at)\n    const timeout = ((expiration - Date.now()) * 3) / 4\n\n    console.connect({\n      message: 'setAuthorizationToken',\n      tokenExpiration: token.expires_at || 'No token',\n      currentTime: new Date().toString()\n    })\n    authorizationTimeout = setTimeout(() => {\n      refreshAuthorizationToken()\n    }, timeout || 15000)\n  } catch (e) {\n    clearTimeout(authorizationTimeout)\n    postToConnections({ type: 'error', payload: e })\n  }\n}\n\nconst handleLogin = async () => {\n  console.connect({\n    message: 'handleLogin',\n    tokenExpiration: state.idToken?.expiresAt\n      ? state.idToken.expiresAt * 1000\n      : 'No Token',\n    currentTime: new Date().toString()\n  })\n\n  postToChannelPorts({ payload: state.idToken })\n}\n\nconst handleLogout = () => {\n  state.idToken = null\n  state.authorizationToken = null\n  postToConnections({ type: 'logout' })\n  console.connect({\n    message: 'handleLogout',\n    tenantId: state.tenantId,\n    currentTime: new Date().toString()\n  })\n}\n\nconst handleClear = () => {\n  state.idToken = null\n  state.authorizationToken = null\n  console.connect({\n    message: 'handleClear',\n    tenantId: state.tenantId || 'No tenant',\n    currentTime: new Date().toString()\n  })\n}\n\nlet authorizing = false\nconst handleAuthorize = async idToken => {\n  authorizing = true\n  if (\n    !state.authorizationToken ||\n    (state.authorizationToken &&\n      new Date(state.authorizationToken.expires_at) <= Date.now())\n  ) {\n    const authorizationResponse = await authorize(idToken)\n\n    if (authorizationResponse && authorizationResponse.access_token) {\n      setAuthorizationToken(authorizationResponse)\n    } else {\n      postToConnections({ type: 'accessDenied', payload: state.idToken })\n    }\n  }\n\n  postToChannelPorts({ payload: state.authorizationToken })\n  authorizing = false\n}\n\nconst connect = c => {\n  const port = c.ports[0]\n  ports.push(port)\n\n  port.onmessage = async e => {\n    try {\n      const type = e.data?.type\n      const channelPort = e.ports[0]\n      const payload = e.data?.payload\n\n      if (type == 'login') {\n        channelPorts.push(channelPort)\n        await handleLogin()\n      }\n\n      if (type == 'idToken') {\n        state.idToken = payload\n      }\n\n      if (type == 'logout') {\n        handleLogout()\n      }\n\n      if (type == 'authorize') {\n        channelPorts.push(channelPort)\n        if (!authorizing) {\n          await handleAuthorize(payload)\n        }\n      }\n\n      if (type == 'switch-tenant') {\n        channelPorts.push(channelPort)\n        await handleSwitchTenant(payload)\n      }\n\n      if (type == 'clear') {\n        handleClear()\n      }\n    } catch (e) {\n      postToConnections({ type: 'error', payload: e })\n    }\n  }\n\n  port.start() // Required when using addEventListener. Otherwise called implicitly by onmessage setter.\n}\n\nself.onconnect = connect\n\nself.onerror = e => {\n  // eslint-disable-next-line no-console\n  console.log('in error handler', e)\n  console.connect({\n    message: 'error',\n    error: e\n  })\n}\n"
  },
  {
    "path": "src/workers/cache.worker.js",
    "content": ""
  },
  {
    "path": "src/workers/schematic.js",
    "content": "import { Tree } from '@/utils/Tree'\nimport * as d3_dag from 'd3-dag'\n\nglobal.process = process\n\n// eslint-disable-next-line no-global-assign\n// window = undefined\n\n// Add our custom curve to d3 base\n// and then merges the libraries together into one\n// access point\nconst d3 = Object.assign({}, d3_dag)\n\nlet layout, dag\n\nexport function GenerateTree(data) {\n  let tree = new Tree(Object.assign({}, data))\n  return tree\n}\n\nexport function Stratify(data) {\n  dag = d3.dagStratify()(data)\n  dag.each(node => (node.heightRatio = 1))\n  return dag\n}\n\nexport function GenerateLayout(data) {\n  const tree = data.tree\n  const height = data.height\n  const layoutPlan = data.layoutPlan\n  const width = data.width\n\n  let canvasAdjustment = { h: null, w: null }\n  let links, descendants\n  // arquint - the layout algorithm of the graph - allows for node heights\n  // size - array of width/height\n  // decross - the amount of crossing edges that will be present in the\n  //           layout; in order of speed (slowest to fastest):\n  //              - decrossOpt (don't use this, it's v v slow for large graphs)\n  //              - decrossTwoLayer().order(d3.twolayerOpt())\n  //              - decrossTwoLayer\n  // columnWidth - function should return a number, ex: () => 1\n  // columnSeparation - space between columns; function should return a number, ex: () => 1\n  // interLayerSeparation - vertical distance between layers\n  // layering - node layer assignment (slowest to fastest):\n  //              - layeringSimplex\n  //              - layeringCoffmanGraham\n  //              - layeringTopological\n  //              - layeringLongestPath().topDown(false)\n  //              - layeringLongestPath\n  // columnAssignment - node column assignment:\n  //             Simple Left     - columnSimpleLeft\n  //             Simple Center   - columnSimpleCenter\n  //             Adjacent Left   - columnAdjacent\n  //             Adjacent Center - columnAdjacent.center(true)\n  //             Complex Left    - columnComplex\n  //             Complex Center  - columnComplex.center(true)\n  // column2Coord(d3.column2CoordRect()) - converts the column assignment of each node to actual x0 and x1 coordinates\n  // coord - coordinate assignment (slowest to fastest):\n  //             Vertical          - coordVert\n  //             Minimum Curves    - coordMinCurve\n  //             Greedy            - coordGreedy\n  //             Center            - coordCenter\n  //\n  if (tree.width <= 3 && tree.height <= 3) {\n    canvasAdjustment.h = height * 0.35\n    canvasAdjustment.w = width * 0.35\n  } else {\n    canvasAdjustment.h = height * (1 / tree.height)\n    canvasAdjustment.w = width * (1 / tree.width)\n  }\n\n  if (layoutPlan == 'sugiyama' && !layout) {\n    layout = d3\n      .sugiyama()\n      .size([width - canvasAdjustment.w, height - canvasAdjustment.h])\n      .layering(d3.layeringLongestPath().topDown(false))\n      // .decross(d3.decrossTwoLayer().order(d3.twolayerOpt())) // Disabling this due to runaway worker memory usage for large graphs\n      // .coord(d3.coordMinCurve()) // Disabling this due to some edge cases with quadratic positive definites\n      .separation((a, b) => {\n        return (a.data !== undefined) + (b.data !== undefined)\n      })\n  }\n\n  layout(dag)\n\n  descendants = dag.descendants()\n  links = dag.links()\n  return { canvasAdjustment, descendants, links }\n}\n"
  },
  {
    "path": "src/workers/timeline.js",
    "content": "export function GenerateRows(items) {\n  const grid = []\n  const start = Date.now()\n  const end = Date.now()\n  const rowMap = {}\n\n  itemLoop: for (let i = 0; i < items.length; ++i) {\n    const item = items[i]\n\n    // If the item hasn't started yet, we distribute\n    // it to the row with the least items already\n    if (!item.start_time) {\n      const lengths = grid.map(row => row.length)\n      let row = lengths.indexOf(Math.min(...lengths))\n\n      rowMap[item.id] = row\n\n      if (!grid[row]) {\n        grid.push([[start, end]])\n      } else {\n        grid[row].push([start, end])\n      }\n\n      continue itemLoop\n    }\n\n    const start_ = item.start_time ? new Date(item.start_time).getTime() : null\n    const end_ = item.end_time ? new Date(item.end_time).getTime() : Date.now()\n\n    for (let row = 0; row <= grid.length; ++row) {\n      // If the current row doesn't exist, create it, put this item on it,\n      // and move to the next item\n      if (!grid[row]) {\n        rowMap[item.id] = row\n        grid.push([[start_, end_]])\n        continue itemLoop\n      }\n\n      if (!start_) {\n        const lengths = grid.map(row => row.length)\n        let row = lengths.indexOf(Math.min(...lengths))\n\n        rowMap[item.id] = row\n        grid[row].push([start_, end_])\n        continue itemLoop\n      }\n\n      // Otherwise check the start and end times against each\n      // start[0] and end[1] time in the row\n      let intersects = grid[row].some(\n        slot => end_ <= slot[0] - 2000 || start_ <= slot[1] + 2000\n      )\n\n      // let intersects = grid[row].some(\n      //   slot => end <= slot[0] || start <= slot[1]\n      // )\n\n      if (!intersects) {\n        rowMap[item.id] = row\n        grid[row].push([start_, end_])\n        continue itemLoop\n      }\n    }\n  }\n\n  return { rowMap, rows: grid.length }\n}\n"
  },
  {
    "path": "src/workers/util/worker-interface.js",
    "content": "// Returns a promise that awaits a message from a passed worker on a provisioned channel\nexport const promiseChannel = (worker, signalType, payload) =>\n  new Promise((res, rej) => {\n    const channel = new MessageChannel()\n\n    channel.port1.onmessage = data => {\n      channel.port1.close()\n      if (data.type == 'error') {\n        rej(data)\n      } else {\n        res(data.data.payload)\n      }\n    }\n\n    worker.port.postMessage({ type: signalType, payload: payload }, [\n      channel.port2\n    ])\n  })\n"
  },
  {
    "path": "start_server.sh",
    "content": "#!/usr/bin/env bash\n\n# Set default prefect_ui_settings if\n# env vars not present\nif [[ -z ${PREFECT_SERVER__APOLLO_URL} ]]\nthen\n    echo \"Missing the PREFECT_SERVER__APOLLO_URL environment variable.  Using default\"\n    PREFECT_SERVER__APOLLO_URL=\"http://localhost:4200/graphql\"\nfi\n\nif [[ -z ${PREFECT_SERVER__BASE_URL} ]]\nthen\n    echo \"Missing the PREFECT_SERVER__BASE_URL environment variable.  Using default\"\n    PREFECT_SERVER__BASE_URL=\"/\"\nfi\n\nsed -i \"s,PREFECT_SERVER__APOLLO_URL,$PREFECT_SERVER__APOLLO_URL,\" /var/www/settings.json \nsed -i \"s,PREFECT_SERVER__BASE_URL,$PREFECT_SERVER__BASE_URL,\" /var/www/settings.json\n\necho \"👾👾👾 UI running at localhost:8080 👾👾👾\"\n\nnginx -g \"daemon off;\"\n"
  },
  {
    "path": "stylelint.config.js",
    "content": "module.exports = {\n  root: true,\n  extends: ['stylelint-config-recommended', 'stylelint-config-sass-guidelines'],\n  plugins: ['stylelint-scss', 'stylelint-order', 'stylelint-a11y'],\n  rules: {\n    'max-nesting-depth': [\n      3,\n      {\n        ignoreAtRules: ['each', 'media', 'supports', 'include']\n      }\n    ],\n    'function-parentheses-space-inside': 'never-single-line',\n    'a11y/no-outline-none': true,\n    'a11y/selector-pseudo-class-focus': true,\n    'a11y/content-property-no-static-value': [true, { severity: 'warning' }],\n    'a11y/font-size-is-readable': [true, { severity: 'warning' }],\n    'a11y/line-height-is-vertical-rhythmed': [true, { severity: 'warning' }],\n    'a11y/no-display-none': [true, { severity: 'warning' }],\n    'a11y/no-spread-text': [true, { severity: 'warning' }],\n    'a11y/no-obsolete-attribute': [true, { severity: 'warning' }],\n    'a11y/no-obsolete-element': [true, { severity: 'warning' }],\n    'a11y/no-text-align-justify': [true, { severity: 'warning' }]\n  }\n}\n"
  },
  {
    "path": "tests/.eslintrc.js",
    "content": "module.exports = {\n  env: {\n    jest: true\n  }\n}\n"
  },
  {
    "path": "tests/__mocks__/@auth0/auth0-js.js",
    "content": "export const mockAuthorize = jest.fn()\n\nexport const mockLogout = jest.fn()\n\nexport const mockParseHashResult = {\n  accessToken: '654334335242321',\n  idToken: '1432g435ewgh55y'\n}\n\nexport const mockParseHash = jest\n  .fn()\n  .mockImplementationOnce(callback => {\n    callback(null, mockParseHashResult)\n  })\n  .mockImplementationOnce(callback => {\n    callback(new Error('test error'))\n  })\n\nclass WebAuth {\n  constructor() {\n    this.authorize = mockAuthorize\n    this.logout = mockLogout\n    this.parseHash = mockParseHash\n  }\n}\n\nconst mock = {\n  WebAuth\n}\n\nexport default mock\n"
  },
  {
    "path": "tests/__mocks__/@auth0/auth0-spa-js.js",
    "content": "export const handleRedirectCallback = jest.fn()\nexport const isAuthenticated = jest.fn().mockReturnValue(Math.random() >= 0.5)\nexport const getUser = jest.fn().mockReturnValue({})\nexport const getIdTokenClaims = jest.fn().mockReturnValue({ __raw: 'eyj' })\nexport const getTokenSilently = jest.fn()\nexport const loginWithRedirect = jest.fn()\nexport const logout = jest.fn()\n\nexport class Auth0Client {\n  constructor() {\n    this.__exists = true\n    this.handleRedirectCallback = handleRedirectCallback\n    this.isAuthenticated = isAuthenticated\n    this.getUser = getUser\n    this.getIdTokenClaims = getIdTokenClaims\n    this.loginWithRedirect = loginWithRedirect\n    this.logout = logout\n    this.getTokenSilently = getTokenSilently\n  }\n}\n\nexport default function createAuth0Client() {\n  return new Promise(resolve => resolve(new Auth0Client()))\n}\n"
  },
  {
    "path": "tests/__mocks__/@okta/okta-auth-js.js",
    "content": "const raw_jwt =\n  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYXdkYXdkYWRhLTQ5NDItNDhhNS04YzY2LWFkYXdkYWRhZCIsInRlbmFudF9pZCI6ImF3ZGF3ZGFkLWQ1NzAtNGYwYy05MTFkLWRjYWFiNWNlYzNkMCIsInJvbGUiOiJURU5BTlRfQURNSU4iLCJpYXQiOjE1Njg4NDAyODQsImV4cCI6MTkzMzk1NDA5OSwianRpIjoiMThiNDRhMTgtNTU2Yy00M2YzLTkxOWEtZDAwOWIwNDIzOTA3IiwiaXNzIjoiUHJlZmVjdCBDbG91ZCIsImF1ZCI6IlByZWZlY3QgQ2xvdWQgQVBJIC0gREVWIn0.iHL0fkdNxMnbRXNJuDwYlvdsaylh1gb-MaRJtuyaZLg'\n\nexport const idToken = {\n  authorizeUrl: 'https://some.authorization.url/oauth2/authorize',\n  claims: {\n    sub: 'abc123',\n    name: 'Marvin',\n    email: 'marvin@theship.com',\n    ver: 1,\n    iss: 'https://some.issuer.url/oauth2',\n    exp: 9999999999,\n    iat: 9999999999,\n    nonce: 'abc123'\n  },\n  clientId: '789xyz',\n  expiresAt: 9999999999,\n  idToken: raw_jwt,\n  issuer: 'https://some.issuer.url/oauth2',\n  scopes: ['openid', 'profile', 'email'],\n  value: raw_jwt\n}\n\nexport const expiredIdToken = {\n  authorizeUrl: 'https://some.authorization.url/oauth2/authorize',\n  claims: {\n    sub: 'abc123',\n    name: 'Marvin',\n    email: 'marvin@theship.com',\n    ver: 1,\n    iss: 'https://some.issuer.url/oauth2',\n    exp: 1305389672,\n    iat: 1305389671,\n    nonce: 'abc123'\n  },\n  clientId: '789xyz',\n  expiresAt: 1305389672,\n  idToken: raw_jwt,\n  issuer: 'https://some.issuer.url/oauth2',\n  scopes: ['openid', 'profile', 'email'],\n  value: raw_jwt\n}\n\nexport const accessToken = {\n  authorizeUrl:\n    'https://universal.prefect.io/oauth2/aus9ej78aeaYy8Lcf1d6/v1/authorize',\n  claims: {\n    aud: 'prefect',\n    cid: 'abc123',\n    exp: 9999999999,\n    iat: 9999999999,\n    iss: 'https://some.issuer.url/oauth2',\n    jti: '456xyz',\n    scp: (3)[('email', 'openid', 'profile')],\n    sub: 'nicholas@prefect.io',\n    uid: '00u9dbxkpyijFlaHF1d6',\n    ver: 1\n  },\n  expiresAt: 9999999999,\n  scopes: ['openid', 'profile', 'email'],\n  tokenType: 'Bearer',\n  userinfoUrl: 'https://some.issuer.url/userinfo',\n  value: raw_jwt\n}\n\nexport const MOCK_TOKEN_PAYLOAD = {\n  tokens: { idToken: idToken, accessToken: accessToken }\n}\n\nexport const parseFromUrl = jest.fn().mockReturnValue(MOCK_TOKEN_PAYLOAD)\nexport const getTokens = jest.fn().mockReturnValue(MOCK_TOKEN_PAYLOAD.tokens)\nexport const getWithRedirect = jest.fn().mockReturnValue(MOCK_TOKEN_PAYLOAD)\nexport const getTokenByKey = jest.fn().mockReturnValue(false)\nexport const isAuthenticated = jest.fn().mockReturnValue(false)\nexport const isLoginRedirect = jest.fn().mockReturnValue(false)\nexport const getUser = jest.fn().mockReturnValue({})\nexport const setTokens = jest.fn()\nexport const start = jest.fn()\nexport const clear = jest.fn()\nexport const signOut = jest.fn()\nexport const on = jest.fn()\nexport const isPKCESupported = jest.fn().mockReturnValue(true)\nexport const hasExpired = jest.fn(\n  token => token.expiresAt * 1000 < new Date().getTime()\n)\nexport const renew = jest.fn().mockReturnValue(idToken)\n\nexport class OktaAuth {\n  static features = {\n    isPKCESupported: isPKCESupported\n  }\n\n  constructor() {\n    this.__exists = true\n\n    this.token = {\n      getWithRedirect: getWithRedirect,\n      parseFromUrl: parseFromUrl\n    }\n\n    this.tokenManager = {\n      hasExpired: hasExpired,\n      getTokens: getTokens,\n      get: getTokenByKey,\n      renew: renew,\n      setTokens: setTokens,\n      on: on,\n      clear: clear\n    }\n\n    this.isLoginRedirect = isLoginRedirect\n    this.isAuthenticated = isAuthenticated\n\n    this.getUser = getUser\n\n    this.signOut = signOut\n\n    this.start = start\n  }\n}\n\nexport default OktaAuth\n"
  },
  {
    "path": "tests/jestSetup.js",
    "content": "import 'babel-polyfill'\n"
  },
  {
    "path": "tests/unit/auth/authentication-construction.spec.js",
    "content": "/*\n\n    This tests only the constructor of the OktaAuth client;\n    keeping this in a separate file from the rest of the authentication tests\n    allows us to work around module import issues. See https://github.com/facebook/jest/issues/2582\n    for more details about the other issues and see @/tests/unit/auth/authentication.spec for the rest\n    of the authentication tests\n\n*/\n\njest.mock('@okta/okta-auth-js', () => {\n  const OktaAuth = jest.fn().mockImplementation(() => {\n    return {\n      start: jest.fn()\n    }\n  })\n\n  OktaAuth.features = { isPKCESupported: jest.fn() }\n\n  return {\n    OktaAuth: OktaAuth\n  }\n})\nimport { OktaAuth } from '@okta/okta-auth-js'\n\ndescribe('authentication', () => {\n  it('initializes the auth client', async () => {\n    require('@/auth/authentication.js')\n\n    expect(OktaAuth).toHaveBeenCalledTimes(1)\n    expect(OktaAuth.features.isPKCESupported).toHaveBeenCalledTimes(1)\n  })\n})\n"
  },
  {
    "path": "tests/unit/auth/authentication.spec.js",
    "content": "jest.mock('@okta/okta-auth-js')\nimport {\n  isLoginRedirect,\n  parseFromUrl,\n  getTokens,\n  getWithRedirect,\n  setTokens,\n  MOCK_TOKEN_PAYLOAD,\n  expiredIdToken,\n  renew\n} from '@okta/okta-auth-js'\n\ndescribe('the authentication module', () => {\n  it('exports the auth client', async () => {\n    const mod = require('@/auth/authentication.js')\n\n    expect(mod.authClient).toBeDefined()\n  })\n\n  it('exports an authenticate method', async () => {\n    const mod = require('@/auth/authentication.js')\n\n    expect(mod.authenticate).toBeDefined()\n  })\n\n  describe('the authenticate method', () => {\n    const clearMocks = () => {\n      isLoginRedirect.mockClear()\n      parseFromUrl.mockClear()\n      setTokens.mockClear()\n      getTokens.mockClear()\n      renew.mockClear()\n      getWithRedirect.mockClear()\n      sessionStorage.setItem.mockClear()\n      sessionStorage.getItem.mockClear()\n      sessionStorage.removeItem.mockClear()\n    }\n\n    let mod\n\n    beforeEach(() => {\n      mod = require('@/auth/authentication.js')\n    })\n\n    afterEach(clearMocks)\n\n    it('calls the isLoginRedirect method', async () => {\n      await mod.authenticate()\n\n      expect(isLoginRedirect).toHaveBeenCalledTimes(1)\n    })\n\n    it('checks session storage for a redirect route', async () => {\n      await mod.authenticate()\n\n      expect(sessionStorage.getItem).toHaveBeenCalledWith('redirectRoute')\n    })\n\n    describe('(login redirect)', () => {\n      let mod\n\n      beforeEach(() => {\n        mod = require('@/auth/authentication.js')\n        isLoginRedirect.mockReturnValueOnce(true)\n      })\n\n      afterEach(clearMocks)\n\n      it('attempts to get tokens from the URL on login redirect', async () => {\n        await mod.authenticate()\n\n        expect(parseFromUrl).toHaveBeenCalledTimes(1)\n      })\n\n      it('calls the set tokens method when parsing tokens from the url', async () => {\n        const tokens = MOCK_TOKEN_PAYLOAD.tokens\n\n        await mod.authenticate()\n\n        // The parseFromUrl method is mocked to return the MOCK_TOKEN_PAYLOAD by default\n        expect(setTokens).toHaveBeenCalledWith(tokens)\n      })\n\n      it('pushes the redirect route to browser history', async () => {\n        // This is necessary for us to get the args from history.replaceState\n        jest.spyOn(window.history, 'replaceState')\n        sessionStorage.getItem.mockReturnValueOnce('/foo')\n\n        await mod.authenticate()\n\n        // The parseFromUrl method is mocked to return the MOCK_TOKEN_PAYLOAD by default\n        expect(history.replaceState).toHaveBeenCalledWith(null, null, '/foo')\n      })\n\n      it('throws error if we fail to get tokens', async () => {\n        parseFromUrl.mockImplementation(() => {\n          throw new Error('access denied')\n        })\n\n        const authenticate = mod.authenticate()\n        await expect(authenticate).rejects.toThrow('access denied')\n      })\n    })\n\n    describe('(not login redirect)', () => {\n      let mod\n\n      beforeEach(() => {\n        mod = require('@/auth/authentication.js')\n        isLoginRedirect.mockReturnValueOnce(false)\n      })\n\n      afterEach(clearMocks)\n\n      it('does not attempt to get tokens from the URL when not login redirect', async () => {\n        await mod.authenticate()\n\n        expect(parseFromUrl).not.toHaveBeenCalled()\n      })\n\n      it('sets the redirect route in session storage when unset', async () => {\n        sessionStorage.getItem.mockReturnValueOnce(undefined)\n\n        await mod.authenticate()\n\n        expect(sessionStorage.setItem).toHaveBeenCalledWith(\n          'redirectRoute',\n          window.location.pathname + window.location.search\n        )\n      })\n\n      it('does not set the redirect route if already set', async () => {\n        sessionStorage.getItem.mockReturnValueOnce('/foo-bar')\n\n        await mod.authenticate()\n\n        expect(sessionStorage.setItem).not.toHaveBeenCalled()\n      })\n\n      it('attempts to get tokens from the token manager', async () => {\n        await mod.authenticate()\n\n        expect(getTokens).toHaveBeenCalledTimes(1)\n      })\n\n      it('gets tokens with redirect if none are returned from the token manager', async () => {\n        getTokens.mockReturnValueOnce(null)\n\n        await mod.authenticate()\n\n        expect(getWithRedirect).toHaveBeenCalledTimes(1)\n      })\n\n      it('attempts to renew expired id tokens', async () => {\n        const tokens = { accessToken: 'bar', idToken: expiredIdToken }\n        getTokens.mockReturnValueOnce(tokens)\n\n        await mod.authenticate()\n\n        expect(renew).toHaveBeenCalledTimes(1)\n      })\n\n      it('calls get with redirect if token renewal throws an error', async () => {\n        const tokens = { accessToken: 'bar', idToken: expiredIdToken }\n        getTokens.mockReturnValueOnce(tokens)\n        renew.mockImplementation(() => {\n          throw new Error('I fail on purpose')\n        })\n\n        await mod.authenticate()\n\n        expect(getWithRedirect).toHaveBeenCalledTimes(1)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/auth/authorization.spec.js",
    "content": "// const query = jest.fn()\n// const mutate = jest.fn()\n\njest.mock('@/apollo.js')\n\nimport { mutate } from '@/apollo.js'\n\njest.mock('@/graphql/log-in.gql', () => 'log in string')\njest.mock('@/graphql/refresh-token.gql', () => 'refresh token string')\njest.mock('@/graphql/Tenant/tenant-token.gql', () => 'switch tenant string')\n\nconst headers = {\n  'X-PREFECT-UI': true,\n  'X-Backend': 'cloud'\n}\n\ndescribe('the authorization module', () => {\n  it('exports the authorize method', () => {\n    const mod = require('@/auth/authorization.js')\n\n    expect(mod.authorize).toBeDefined()\n  })\n\n  it('exports the refreshTokens method', () => {\n    const mod = require('@/auth/authorization.js')\n\n    expect(mod.refreshTokens).toBeDefined()\n  })\n\n  it('exports the authorizeTenant method', () => {\n    const mod = require('@/auth/authorization.js')\n\n    expect(mod.authorizeTenant).toBeDefined()\n  })\n\n  describe('the authorize method', () => {\n    const clearMocks = () => {\n      mutate.mockClear()\n    }\n\n    let mod\n\n    beforeEach(() => {\n      mod = require('@/auth/authorization.js')\n    })\n\n    afterEach(clearMocks)\n\n    it('throws an error when no id token is passed', async () => {\n      await expect(mod.authorize()).rejects.toThrow(\n        'No ID token passed to authorize'\n      )\n    })\n\n    it('calls the client mutate method', async () => {\n      const idToken = 'foo'\n      await mod.authorize(idToken)\n\n      expect(mutate).toHaveBeenCalledWith({\n        mutation: require('@/graphql/log-in.gql'),\n        variables: {\n          input: { id_token: idToken }\n        },\n        context: {\n          headers: headers\n        },\n        errorPolicy: 'all',\n        fetchPolicy: 'no-cache'\n      })\n\n      expect(mutate).toHaveBeenCalledTimes(1)\n    })\n\n    it('returns data from the log in mutation', async () => {\n      const mockReturn = {\n        data: {\n          log_in: {\n            access_token: 'bar',\n            refresh_token: 'batz',\n            expires_at: 99999\n          }\n        }\n      }\n      mutate.mockReturnValueOnce(mockReturn)\n\n      const response = await mod.authorize('foo')\n\n      expect(response).toStrictEqual(mockReturn.data.log_in)\n    })\n  })\n\n  describe('the refreshTokens method', () => {\n    const clearMocks = () => {\n      mutate.mockClear()\n    }\n\n    let mod\n\n    beforeEach(() => {\n      mod = require('@/auth/authorization.js')\n    })\n\n    afterEach(clearMocks)\n\n    it('throws an error when no access token or refresh token is passed', async () => {\n      const error = 'No access or refresh token passed to refreshTokens'\n      await expect(mod.refreshTokens()).rejects.toThrow(error)\n      await expect(mod.refreshTokens('foo', undefined)).rejects.toThrow(error)\n      await expect(mod.refreshTokens(undefined, 'bar')).rejects.toThrow(error)\n    })\n\n    it('calls the client mutate method', async () => {\n      const accessToken = 'foo'\n      const refreshToken = 'bar'\n      await mod.refreshTokens(accessToken, refreshToken)\n\n      expect(mutate).toHaveBeenCalledWith({\n        mutation: require('@/graphql/refresh-token.gql'),\n        variables: {\n          input: { access_token: accessToken }\n        },\n        context: {\n          headers: {\n            ...headers,\n            authorization: `Bearer ${refreshToken}`\n          }\n        },\n        fetchPolicy: 'no-cache'\n      })\n\n      expect(mutate).toHaveBeenCalledTimes(1)\n    })\n\n    it('returns data from the refresh token mutation', async () => {\n      const mockReturn = {\n        data: {\n          refresh_token: {\n            access_token: 'bar',\n            refresh_token: 'batz',\n            expires_at: 99999\n          }\n        }\n      }\n      mutate.mockReturnValueOnce(mockReturn)\n\n      const response = await mod.refreshTokens('foo', 'bar')\n\n      expect(response).toStrictEqual(mockReturn.data.refresh_token)\n    })\n  })\n\n  describe('the authorizeTenant method', () => {\n    const clearMocks = () => {\n      mutate.mockClear()\n    }\n\n    let mod\n\n    beforeEach(() => {\n      mod = require('@/auth/authorization.js')\n    })\n\n    afterEach(clearMocks)\n\n    it('throws an error when no access token or refresh token is passed', async () => {\n      const error = 'No access token or no tenant id passed to authorizeTenant'\n\n      await expect(mod.authorizeTenant()).rejects.toThrow(error)\n      await expect(mod.authorizeTenant('foo', undefined)).rejects.toThrow(error)\n      await expect(mod.authorizeTenant(undefined, 'bar')).rejects.toThrow(error)\n    })\n\n    it('calls the client mutate method', async () => {\n      const accessToken = 'foo'\n      const tenantId = 'bar'\n      await mod.authorizeTenant(accessToken, tenantId)\n\n      expect(mutate).toHaveBeenCalledWith({\n        mutation: require('@/graphql/Tenant/tenant-token.gql'),\n        variables: {\n          tenantId: tenantId\n        },\n        context: {\n          headers: {\n            ...headers,\n            authorization: `Bearer ${accessToken}`\n          }\n        },\n        fetchPolicy: 'no-cache'\n      })\n\n      expect(mutate).toHaveBeenCalledTimes(1)\n    })\n\n    it('returns data from the switch tenant mutation', async () => {\n      const mockReturn = {\n        data: {\n          switch_tenant: {\n            access_token: 'bar',\n            refresh_token: 'batz',\n            expires_at: 99999\n          }\n        }\n      }\n      mutate.mockReturnValueOnce(mockReturn)\n\n      const response = await mod.authorizeTenant('foo', 'bar')\n\n      expect(response).toStrictEqual(mockReturn.data.switch_tenant)\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/auth/index.spec.js",
    "content": "jest.mock('@/auth/authentication.js', () => ({\n  authenticate: jest.fn(),\n  authClient: {\n    tokenManager: {\n      on: jest.fn()\n    }\n  },\n  signOut: jest.fn()\n}))\n\njest.mock('@/main', () => {\n  return {\n    TokenWorker: {\n      postMessage: jest.fn()\n    }\n  }\n})\n\njest.mock('@/auth/authorization.js', () => ({\n  authorize: jest.fn(),\n  authorizeTenant: jest.fn(),\n  refreshTokens: jest.fn()\n}))\n\njest.mock('@/workers/util/worker-interface.js', () => ({\n  promiseChannel: jest.fn()\n}))\n\nconst start = jest.fn()\nconst postMessage = jest.fn()\nconst onmessage = jest.fn()\n\nclass SharedWorker {\n  defaultOptions = { type: 'classic', credentials: 'omit', name: null }\n\n  constructor(url, name, options = {}) {\n    this.url = url\n    this.name = name\n    this.options = { ...this.defaultOptions, ...options }\n  }\n\n  get port() {\n    return {\n      start: start,\n      postMessage: postMessage,\n      onmessage: onmessage\n    }\n  }\n}\n\ndescribe('the auth module', () => {\n  let mod\n\n  const clearMocks = () => {\n    mod = undefined\n  }\n\n  beforeEach(() => {\n    jest.resetModules()\n    // global.SharedWorker = SharedWorker\n  })\n\n  afterEach(clearMocks)\n\n  it('exports a login method', async () => {\n    mod = require('@/auth/index.js')\n\n    expect(mod.login).toBeDefined()\n  })\n\n  it('exports a switchTenant method', async () => {\n    mod = require('@/auth/index.js')\n\n    expect(mod.switchTenant).toBeDefined()\n  })\n\n  it('exports a logout method', async () => {\n    mod = require('@/auth/index.js')\n\n    expect(mod.logout).toBeDefined()\n  })\n\n  it('exports an unsetTokens method', async () => {\n    mod = require('@/auth/index.js')\n\n    expect(mod.unsetTokens).toBeDefined()\n  })\n\n  it('exports a commitTokens method', async () => {\n    mod = require('@/auth/index.js')\n\n    expect(mod.commitTokens).toBeDefined()\n  })\n\n  describe('browser has shared worker support', () => {\n    let mod, promiseChannel, authenticate, TokenWorker\n    const clearMocks = () => {\n      global.SharedWorker = SharedWorker\n      jest.resetModules()\n      promiseChannel?.mockClear()\n      authenticate?.mockClear()\n\n      promiseChannel = require('@/workers/util/worker-interface.js')\n        .promiseChannel\n\n      authenticate = require('@/auth/authentication.js').authenticate\n\n      mod = require('@/auth/index.js')\n      TokenWorker = mod.TokenWorker\n    }\n\n    beforeEach(clearMocks)\n\n    it('exports a shared token worker', () => {\n      expect(TokenWorker).toBeDefined()\n    })\n\n    describe('the login method', () => {\n      beforeEach(clearMocks)\n\n      it('calls the promiseChannel method when a token worker exists', async () => {\n        await mod.login()\n        expect(promiseChannel).toHaveBeenCalledWith(TokenWorker, 'login')\n      })\n\n      describe('expired id token', () => {\n        beforeEach(clearMocks)\n\n        it('calls the authenticate method', async () => {\n          const expiration = Date.now() / 1000 - 1000\n          const idToken = {\n            value: 'foo.bar',\n            expiresAt: expiration\n          }\n          promiseChannel.mockReturnValueOnce(idToken)\n          await mod.login()\n\n          expect(expiration).toBeLessThan(Date.now())\n          expect(authenticate).toHaveBeenCalledTimes(1)\n        })\n      })\n\n      describe('no id token', () => {\n        beforeEach(clearMocks)\n\n        it('calls the authenticate method', async () => {\n          const idToken = undefined\n          promiseChannel.mockReturnValueOnce(idToken)\n          await mod.login()\n          expect(authenticate).toHaveBeenCalledTimes(1)\n        })\n      })\n\n      it('posts the id token payload to the token worker, when none exists', async () => {\n        const idToken = { value: 'foo.bar' }\n        promiseChannel.mockReturnValueOnce(undefined)\n        authenticate.mockReturnValueOnce({ idToken: idToken })\n\n        await mod.login()\n\n        expect(authenticate).toHaveBeenCalledTimes(1)\n        expect(postMessage).toHaveBeenCalledWith({\n          type: 'idToken',\n          payload: idToken\n        })\n        expect(promiseChannel).toHaveBeenCalledWith(\n          TokenWorker,\n          'authorize',\n          idToken.value\n        )\n      })\n    })\n  })\n\n  describe('browser does not have shared worker support', () => {\n    let mod, promiseChannel, authenticate, authorize, TokenWorker\n    const clearMocks = () => {\n      global.SharedWorker = undefined\n      jest.resetModules()\n      promiseChannel?.mockClear()\n      authenticate?.mockClear()\n\n      promiseChannel = require('@/workers/util/worker-interface.js')\n        .promiseChannel\n\n      authenticate = require('@/auth/authentication.js').authenticate\n      authorize = require('@/auth/authorization.js').authorize\n\n      mod = require('@/auth/index.js')\n      TokenWorker = mod.TokenWorker\n    }\n\n    beforeEach(clearMocks)\n\n    it('does not export a shared token worker', () => {\n      expect(TokenWorker).toBeUndefined()\n    })\n\n    it('calls the authenticate method', async () => {\n      const idToken = { value: 'foo.bar' }\n      authenticate.mockReturnValueOnce({ idToken: idToken })\n      authorize.mockReturnValueOnce({\n        expires_at: Date.now() + 5000,\n        access_token: null,\n        refresh_token: null\n      })\n      await mod.login()\n\n      expect(TokenWorker).toBeUndefined()\n      expect(authenticate).toHaveBeenCalledWith()\n    })\n  })\n\n  describe('login uses fallback', () => {\n    let mod, promiseChannel, authenticate, authorize, TokenWorker\n    const clearMocks = () => {\n      global.SharedWorker = SharedWorker\n      jest.resetModules()\n      promiseChannel?.mockClear()\n      authenticate?.mockClear()\n\n      promiseChannel = require('@/workers/util/worker-interface.js')\n        .promiseChannel\n\n      authenticate = require('@/auth/authentication.js').authenticate\n      authorize = require('@/auth/authorization.js').authorize\n\n      mod = require('@/auth/index.js')\n      TokenWorker = mod.TokenWorker\n    }\n\n    beforeEach(clearMocks)\n\n    it('does not use the token worker if fallback is defined', async () => {\n      const idToken = { value: 'foo.bar' }\n      authenticate.mockReturnValueOnce({ idToken: idToken })\n      authorize.mockReturnValueOnce({\n        expires_at: Date.now() + 5000,\n        access_token: null,\n        refresh_token: null\n      })\n      await mod.login(true)\n\n      expect(TokenWorker).toBeDefined()\n      expect(promiseChannel).not.toHaveBeenCalled()\n      expect(authenticate).toHaveBeenCalledWith()\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/main.spec.js",
    "content": "jest.mock('@/app.js', () => ({\n  CreatePrefectUI: jest.fn()\n}))\njest.mock('jwt-decode')\njest.mock('@/auth/index.js', () => ({\n  login: jest.fn(),\n  switchTenant: jest.fn(),\n  commitTokens: jest.fn()\n}))\njest.mock('@/store')\njest.mock('@/plugins/logrocket.js')\njest.mock('logrocket')\n\nimport { login } from '@/auth/index.js'\n\nconst url = 'https://cloud.prefect.io'\nObject.defineProperty(window, 'location', {\n  value: {\n    pathname: url\n  }\n})\n\nimport { CreatePrefectUI } from '@/app.js'\n\ndescribe('Main', () => {\n  it('says hello', () => {\n    expect('hello').toEqual('hello')\n  })\n\n  it('exports the setStartupTenant method', () => {\n    const mod = require('@/main.js')\n\n    expect(mod.setStartupTenant).toBeDefined()\n  })\n\n  it('exports the start method', () => {\n    const mod = require('@/main.js')\n\n    expect(mod.start).toBeDefined()\n  })\n\n  describe('the start method', () => {\n    const clearMocks = () => {\n      login.mockClear()\n    }\n\n    let mod\n\n    beforeEach(() => {\n      mod = require('@/main.js')\n      window.location.pathname = null\n      localStorage.clear()\n\n      // This is required before each test after import\n      // because the script calls the start method\n      // on load\n      CreatePrefectUI.mockClear()\n    })\n\n    afterEach(clearMocks)\n\n    it('immediately creates the application if the window location is the logout route', async () => {\n      window.location.pathname = 'https://cloud.prefect.io/logout'\n      await mod.start()\n\n      expect(CreatePrefectUI).toHaveBeenCalledTimes(1)\n    })\n\n    it('calls the fallback login method if login throws an error', async () => {\n      process.env.VUE_APP_BACKEND = 'CLOUD'\n      login.mockRejectedValueOnce()\n      await mod.start()\n\n      expect(login).toHaveBeenCalledTimes(2)\n      expect(login).toHaveBeenNthCalledWith(1)\n      expect(login).toHaveBeenNthCalledWith(2, true)\n    })\n\n    it('calls the fallback login method if login takes more than 10 seconds', async () => {\n      process.env.VUE_APP_BACKEND = 'CLOUD'\n      login.mockImplementationOnce(\n        () => new Promise(res => setTimeout(() => res('i was rejected'), 50000))\n      )\n      const startPromise = mod.start()\n      jest.runAllTimers()\n\n      await startPromise\n\n      expect(login).toHaveBeenCalledTimes(2)\n      expect(login).toHaveBeenNthCalledWith(1)\n      expect(login).toHaveBeenNthCalledWith(2, true)\n    })\n\n    it('calls the fallback login method if local storage item is set', async () => {\n      process.env.VUE_APP_BACKEND = 'CLOUD'\n      localStorage.setItem('prefect_fallback_auth', Date.now())\n      const startPromise = mod.start()\n      jest.runAllTimers()\n\n      await startPromise\n\n      expect(login).toHaveBeenCalledTimes(1)\n      expect(login).toHaveBeenNthCalledWith(1, true)\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/middleware/flowNavGuard.spec.js",
    "content": "jest.mock('@/main', () => {\n  return {\n    TokenWorker: {\n      postMessage: jest.fn()\n    }\n  }\n})\n\nimport flowNavGuard from '@/middleware/flowNavGuard'\nimport { createLocalVue } from '@vue/test-utils'\nimport Vuex from 'vuex'\nimport store from '@/store'\n\nconst flows = [\n  {\n    id: 'flow_id_1',\n    flow_group_id: 'flow_group_id_1',\n    version: 1\n  }\n]\n\n//simple mock for gql api query\njest.mock('@/vue-apollo', () => {\n  return {\n    fallbackApolloClient: {\n      query: arg => {\n        if (arg.query == 'flow') {\n          if (arg.variables?.id == 'flow_id_2') {\n            return {\n              data: {\n                flow_by_pk: {\n                  id: 'flow_id_2',\n                  flow_group_id: 'flow_group_id_2',\n                  version: 3\n                }\n              }\n            }\n          } else {\n            return { data: 'test-error' }\n          }\n        }\n      }\n    }\n  }\n})\n\njest.mock('@/graphql/Middleware/flow-group.gql', () => 'flow group')\njest.mock('@/graphql/Middleware/flow.gql', () => 'flow')\njest.mock('@/graphql/Nav/flows.gql', () => 'flow')\n\nconst localVue = createLocalVue()\nlocalVue.use(Vuex)\n\ndescribe('flowNavGuard', () => {\n  afterEach(() => {\n    store.commit('data/unsetFlows')\n  })\n\n  test('if there is a flow group that matches the passed id, it returns next', async () => {\n    store.commit('data/setFlows', flows)\n    const next = jest.fn()\n    await flowNavGuard(\n      { name: 'flow', params: { id: 'flow_group_id_1' } },\n      {},\n      next\n    )\n    expect(next).toBeCalledWith()\n  })\n  test('if there is no flow group that matches the passed id, it checks the flow id and returns next if it matches', async () => {\n    const next = jest.fn()\n    await flowNavGuard({ name: 'flow', params: { id: 'flow_id_2' } }, {}, next)\n    expect(next).toBeCalledWith({\n      name: 'flow',\n      params: { id: 'flow_group_id_2' },\n      query: { version: 3 }\n    })\n  })\n  test('if there is no flow or flow group that matches the passed id, it forwards to a 404', async () => {\n    const next = jest.fn()\n    await flowNavGuard(\n      { name: 'flow', params: { id: 'flow_group_id_3' } },\n      {},\n      next\n    )\n    expect(next).toBeCalledWith({\n      name: 'not-found'\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/store/agent.spec.js",
    "content": "import agent from '@/store/agent'\nimport { createLocalVue } from '@vue/test-utils'\n\nimport Vuex from 'vuex'\n\nconst localVue = createLocalVue()\nlocalVue.use(Vuex)\n\ndescribe('Agent Vuex Module', () => {\n  const initialAgentState = () => {\n    return {\n      thresholds: {\n        // Time before an agent becomes stale\n        stale: 5, // minutes since last query\n        // Time before an agent becomes unhealthy\n        unhealthy: 720 // minutes since last query\n      },\n      agents: null,\n      sortedAgents: null\n    }\n  }\n\n  describe('initial state', () => {\n    it('should have a stale threshold and unhealthy threshold', () => {\n      const state = agent.state\n      expect(state.thresholds.stale).toBe(5)\n      expect(state.thresholds.unhealthy).toBe(720)\n    })\n    it('should have no agents', () => {\n      const state = agent.state\n      expect(state.agents).toBe(null)\n    })\n    it('should have no sorted agents', () => {\n      const state = agent.state\n      expect(state.sortedAgents).toBe(null)\n    })\n  })\n\n  describe('getters', () => {\n    let store = new Vuex.Store({\n      state: initialAgentState(),\n      getters: agent.getters\n    })\n\n    it('should return the stale threshold when the staleThreshold getter is called', () => {\n      expect(store.getters.staleThreshold).toBe(store.state.thresholds.stale)\n    })\n\n    it('should return the unhealthy threshold when the unhealthyThreshold getter is called', () => {\n      expect(store.getters.unhealthyThreshold).toBe(\n        store.state.thresholds.unhealthy\n      )\n    })\n    it('should return agents when the agents getters is called', () => {\n      expect(store.getters.agents).toBe(null)\n    })\n    it('should return sorted agents when the sorted agents getters is called', () => {\n      expect(store.getters.sortedAgents).toBe(null)\n    })\n  })\n\n  describe('mutations', () => {\n    let store = new Vuex.Store({\n      state: initialAgentState(),\n      getters: agent.getters,\n      mutations: agent.mutations\n    })\n\n    it('should add new agents, and update status, when the setSortedAgents mutation is called', () => {\n      expect(store.getters.agents).toBe(null)\n      const recentDate = new Date().toISOString()\n      store.commit('setSortedAgents', [\n        { id: '12345', last_queried: recentDate },\n        { id: '67890', last_queried: '2021-04-20T23:36:24.278841+00:00' },\n        { id: '09876', last_queried: NaN }\n      ])\n      expect(store.getters.agents[0].status).toEqual('healthy')\n      expect(store.getters.agents[1].status).toEqual('unhealthy')\n      expect(store.getters.agents[2].status).toEqual('unhealthy')\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/store/alert.spec.js",
    "content": "jest.mock('@/main', () => {\n  return {\n    TokenWorker: {\n      postMessage: jest.fn()\n    }\n  }\n})\n\nimport uniqueId from 'lodash/uniqueId'\njest.mock('lodash/uniqueId')\n\nimport Vuex from 'vuex'\nimport alert from '@/store/alert'\nimport store from '@/store'\n\njest.useFakeTimers()\n\nconst initialState = { ...alert.state }\nconst getInitialState = () => {\n  return { ...initialState }\n}\n\ndescribe('Alert Vuex Module', () => {\n  describe('Global Alert', () => {\n    it('should initially have a show key that is false and other keys should be falsey', () => {\n      expect(store.getters['alert/getAlert']).toStrictEqual({\n        alertShow: false,\n        alertMessage: '',\n        alertType: null,\n        alertLink: null,\n        linkText: '',\n        alertCopy: ''\n      })\n    })\n\n    describe('mutations', () => {\n      it('updates the state when setAl is called', () => {\n        expect(store.getters['alert/getAlert']).toStrictEqual({\n          alertShow: false,\n          alertMessage: '',\n          alertType: null,\n          alertLink: null,\n          linkText: '',\n          alertCopy: ''\n        })\n        store.commit('alert/setAl', {\n          alertShow: true,\n          alertMessage: 'Testing testing 123',\n          alertType: 'error',\n          alertLink: null,\n          linkText: '',\n          alertCopy: ''\n        })\n        expect(store.getters['alert/getAlert']).toStrictEqual({\n          alertShow: true,\n          alertMessage: 'Testing testing 123',\n          alertType: 'error',\n          alertLink: null,\n          linkText: '',\n          alertCopy: ''\n        })\n      })\n      it('empties the state when setEmpty is called', () => {\n        store.commit('alert/setAl', {\n          alertShow: true,\n          alertMessage: 'Testing testing 123',\n          alertType: 'error',\n          alertLink: null,\n          linkText: '',\n          alertCopy: ''\n        })\n        expect(store.getters['alert/getAlert']).toStrictEqual({\n          alertShow: true,\n          alertMessage: 'Testing testing 123',\n          alertType: 'error',\n          alertLink: null,\n          linkText: '',\n          alertCopy: ''\n        })\n        store.commit('alert/setEmpty')\n        expect(store.getters['alert/getAlert']).toStrictEqual({\n          alertShow: false,\n          alertMessage: '',\n          alertType: null,\n          alertLink: null,\n          linkText: '',\n          alertCopy: ''\n        })\n      })\n    })\n\n    describe('actions', () => {\n      test('setAlert sets the new alert state, calls setTimeout and then empties the alert state', async () => {\n        await store.dispatch('alert/setAlert', {\n          alertShow: true,\n          alertMessage: 'Testing testing 234',\n          alertType: 'error',\n          alertLink: null,\n          linkText: '',\n          alertCopy: ''\n        })\n        expect(store.getters['alert/getAlert']).toStrictEqual({\n          alertShow: true,\n          alertMessage: 'Testing testing 234',\n          alertType: 'error',\n          alertLink: null,\n          linkText: '',\n          alertCopy: ''\n        })\n        expect(setTimeout).toHaveBeenCalledTimes(1)\n        expect(setTimeout).toHaveBeenLastCalledWith(\n          expect.any(Function),\n          6000,\n          'setEmpty'\n        )\n      })\n    })\n  })\n\n  describe('Notifications', () => {\n    describe('getters', () => {\n      it('should return notifications', () => {\n        const notifications = ['foo', 'bar', 'batz']\n\n        const store = new Vuex.Store({\n          state: { ...getInitialState(), notifications: [...notifications] },\n          getters: alert.getters\n        })\n\n        expect(store.getters.notifications).toStrictEqual(notifications)\n      })\n\n      it('should return notificationTimeouts', () => {\n        const notificationTimeouts = { 0: 123, 1: 456 }\n\n        const store = new Vuex.Store({\n          state: {\n            ...alert.state,\n            notificationTimeouts: Object.assign({}, notificationTimeouts)\n          },\n          getters: alert.getters\n        })\n\n        expect(store.getters.notificationTimeouts).toStrictEqual(\n          notificationTimeouts\n        )\n      })\n    })\n\n    describe('mutations', () => {\n      let store\n\n      beforeEach(() => {\n        clearTimeout.mockClear()\n        store = new Vuex.Store({\n          state: getInitialState(),\n          getters: alert.getters,\n          actions: alert.actions,\n          mutations: alert.mutations\n        })\n      })\n\n      it('setNotifications correctly stores notifications', () => {\n        const notifications = ['lorem', 'ipsum']\n\n        store.commit('setNotifications', notifications)\n\n        expect(store.getters.notifications).toStrictEqual(notifications)\n      })\n\n      it('setNotificationTimeout clears any existing timeout and stores a new timeout id', () => {\n        const id = 'foo-bar'\n        const timeoutId = 123\n        const timeoutId2 = 456\n\n        store.commit('setNotificationTimeout', { id, timeoutId })\n\n        expect(store.getters.notificationTimeouts).toStrictEqual({\n          [id]: timeoutId\n        })\n\n        store.commit('setNotificationTimeout', { id, timeoutId: timeoutId2 })\n\n        expect(clearTimeout).toHaveBeenCalledWith(timeoutId)\n\n        expect(store.getters.notificationTimeouts).toStrictEqual({\n          [id]: timeoutId2\n        })\n      })\n    })\n\n    // addNotification\n    // dismissNotification\n    // updateNotification\n    describe('actions', () => {\n      let store\n      const storeClear = () => {\n        store = new Vuex.Store({\n          state: getInitialState(),\n          getters: alert.getters,\n          actions: alert.actions,\n          mutations: alert.mutations\n        })\n      }\n\n      describe('addNotification', () => {\n        beforeEach(storeClear)\n\n        it('returns sequential ids for each call', async () => {\n          let id\n\n          uniqueId\n            .mockReturnValueOnce(1)\n            .mockReturnValueOnce(2)\n            .mockReturnValueOnce(3)\n            .mockReturnValueOnce(4)\n\n          id = await store.dispatch('addNotification', { text: 'foo' })\n\n          expect(id).toStrictEqual(1)\n\n          id = await store.dispatch('addNotification', { text: 'bar' })\n\n          expect(id).toStrictEqual(2)\n\n          id = await store.dispatch('addNotification', { text: 'batz' })\n\n          expect(id).toStrictEqual(3)\n\n          id = await store.dispatch('addNotification', { text: 'fiz' })\n\n          expect(id).toStrictEqual(4)\n        })\n\n        it('adds the passed notification to the store', async () => {\n          const notification = { text: 'fix' }\n\n          expect(store.getters.notifications).toStrictEqual([])\n\n          const id = await store.dispatch('addNotification', notification)\n\n          expect(store.getters.notifications).toStrictEqual([\n            { id: id, ...notification }\n          ])\n        })\n\n        // TODO: Add tests for timeout logic\n      })\n\n      describe('dismissNotification', () => {\n        beforeEach(storeClear)\n\n        it('removes the notification with the passed id from the store', async () => {\n          const notification = { text: 'sabe' }\n\n          uniqueId.mockReturnValueOnce(1)\n\n          const id = await store.dispatch('addNotification', notification)\n\n          expect(id).toStrictEqual(1)\n\n          expect(store.getters.notifications).toStrictEqual([\n            { id, ...notification }\n          ])\n\n          await store.dispatch('dismissNotification', { id: 1 })\n\n          expect(store.getters.notifications).toStrictEqual([])\n        })\n      })\n\n      describe('updateNotification', () => {\n        beforeEach(storeClear)\n\n        it('updates the notification with the passed id with new data', async () => {\n          const notification = { text: 'sabe' }\n\n          uniqueId.mockReturnValueOnce(1)\n\n          const id = await store.dispatch('addNotification', notification)\n\n          expect(store.getters.notifications).toStrictEqual([\n            { id, ...notification }\n          ])\n\n          await store.dispatch('updateNotification', {\n            id: 1,\n            notification: { text: 'ebas' }\n          })\n\n          expect(store.getters.notifications[0].text).toStrictEqual('ebas')\n        })\n\n        // TODO: Add tests for timeout logic\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/store/api.spec.js",
    "content": "import api from '@/store/api'\nimport { createLocalVue } from '@vue/test-utils'\nimport Vuex from 'vuex'\njest.useFakeTimers()\n\nconst SERVER_KEY = `${process.env.VUE_APP_RELEASE_TIMESTAMP}_server_url`\n\n//simple mock for gql api query\nlet mockerror = false\n\njest.mock('@/vue-apollo', () => {\n  return {\n    fallbackApolloClient: {\n      query: () => {\n        if (!mockerror) {\n          return {\n            data: {\n              api: {\n                release_timestamp: 'timestamp',\n                version: 2,\n                mode: 'maintenance'\n              }\n            }\n          }\n        } else {\n          return { data: 'error' }\n        }\n      }\n    }\n  }\n})\n\nconst localVue = createLocalVue()\nlocalVue.use(Vuex)\n\njest.mock('@/graphql/api.gql', () => 'api mutation string')\n\ndescribe('API Vuex Module', () => {\n  let initialAPIState\n  let envVarAPIState\n  let localStoreAPIState\n\n  beforeEach(() => {\n    initialAPIState = () => {\n      delete process.env.VUE_APP_BACKEND\n      delete process.env.VUE_APP_CLOUD_URL\n      delete process.env.VUE_APP_SERVER_URL\n      localStorage.clear()\n      return {\n        backend:\n          localStorage.getItem('backend') ||\n          process.env.VUE_APP_BACKEND ||\n          'SERVER',\n        connected: true,\n        connectionMessage: null,\n        connectionTimeout: null,\n        apiMode: null,\n        releaseTimestamp: null,\n        cloudUrl: process.env.VUE_APP_CLOUD_URL,\n        retries: 0,\n        serverUrl:\n          localStorage.getItem(SERVER_KEY) || process.env.VUE_APP_SERVER_URL,\n        version: null\n      }\n    }\n    envVarAPIState = () => {\n      localStorage.clear()\n      process.env.VUE_APP_BACKEND = 'CLOUD'\n      process.env.VUE_APP_CLOUD_URL = 'https://api.prefect.io/graphql'\n      process.env.VUE_APP_SERVER_URL = 'http://localhost:4200/graphql'\n      return {\n        backend:\n          localStorage.getItem('backend') ||\n          process.env.VUE_APP_BACKEND ||\n          'SERVER',\n        connected: true,\n        connectionMessage: null,\n        connectionTimeout: 200,\n        releaseTimestamp: null,\n        apiMode: null,\n        cloudUrl: process.env.VUE_APP_CLOUD_URL,\n        retries: 0,\n        serverUrl:\n          localStorage.getItem(SERVER_KEY) || process.env.VUE_APP_SERVER_URL,\n        version: null\n      }\n    }\n    localStoreAPIState = () => {\n      localStorage.setItem('backend', 'foo')\n      localStorage.setItem(SERVER_KEY, 'http://0.0.0.0:4200/graphql')\n      process.env.VUE_APP_BACKEND = 'CLOUD'\n      process.env.VUE_APP_SERVER_URL = 'http://localhost:4200/graphql'\n      return {\n        backend:\n          localStorage.getItem('backend') ||\n          process.env.VUE_APP_BACKEND ||\n          'SERVER',\n        connected: true,\n        connectionMessage: 'connection message',\n        connectionTimeout: 300,\n        apiMode: null,\n        releaseTimestamp: 'xxxxxx',\n        cloudUrl: process.env.VUE_APP_CLOUD_URL,\n        retries: 5,\n        serverUrl:\n          localStorage.getItem(SERVER_KEY) || process.env.VUE_APP_SERVER_URL,\n        version: 8\n      }\n    }\n  })\n\n  describe('State', () => {\n    test('state returns correct values if no localStorage or environment variables are set', () => {\n      const state = initialAPIState()\n      expect(state.backend).toEqual('SERVER')\n      expect(state.connected).toBe(true)\n      expect(state.connectionMessage).toBe(null)\n      expect(state.connectionTimeout).toBe(null)\n      expect(state.cloudUrl).toBe(undefined)\n      expect(state.retries).toBe(0)\n      expect(state.apiMode).toBe(null)\n      expect(state.serverUrl).toBe(undefined)\n      expect(state.version).toBe(null)\n    })\n    test('state checks local storage before environment variables', () => {\n      const state = localStoreAPIState()\n      expect(localStorage.getItem).toBeCalledWith('backend')\n      expect(state.backend).toEqual('foo')\n      expect(state.serverUrl).toBe('http://0.0.0.0:4200/graphql')\n    })\n    test('state checks environment variables if no local storage', () => {\n      const state = envVarAPIState()\n      expect(localStorage.getItem('backend')).toBe(null)\n      expect(state.backend).toEqual('CLOUD')\n      expect(state.cloudUrl).toBe('https://api.prefect.io/graphql')\n      expect(state.serverUrl).toBe('http://localhost:4200/graphql')\n    })\n  })\n\n  describe('getters', () => {\n    let store\n    beforeEach(() => {\n      const state = initialAPIState()\n      store = new Vuex.Store({\n        state: state,\n        getters: api.getters,\n        mutations: api.mutations\n      })\n    })\n    it('should return the backend', () => {\n      expect(store.getters.backend).toBe('SERVER')\n    })\n    it('should return connected state', () => {\n      expect(store.getters.connected).toBe(true)\n    })\n    it('should return connecting state', () => {\n      expect(store.getters.connecting).toBe(false)\n    })\n    it('should return the connection message', () => {\n      expect(store.getters.connectionMessage).toBe(null)\n    })\n    it('should return the connectionTimeout', () => {\n      expect(store.getters.connectionTimeout).toBe(null)\n    })\n    it('should return the api mode', () => {\n      expect(store.getters.apiMode).toBe(null)\n    })\n    it('should return a boolean about whether the backend is Cloud', () => {\n      expect(store.getters.isCloud).toBe(false)\n    })\n    it('should return a boolean about whether the backend is Server', () => {\n      expect(store.getters.isServer).toBe(true)\n    })\n    it('should return the cloud url', () => {\n      expect(store.getters.cloudUrl).toBe(undefined)\n    })\n    it('should return retries', () => {\n      expect(store.getters.retries).toBe(0)\n    })\n    it('should return the server url', () => {\n      expect(store.getters.serverUrl).toBe(undefined)\n    })\n    it('should return the active url', () => {\n      expect(store.getters.url).toBe(undefined)\n    })\n    it('should return the version', () => {\n      expect(store.getters.version).toBe(null)\n    })\n  })\n\n  describe('Mutations', () => {\n    let store\n\n    beforeEach(() => {\n      store = new Vuex.Store({\n        state: initialAPIState(),\n        getters: api.getters,\n        actions: api.actions,\n        mutations: api.mutations\n      })\n    })\n    describe('setBackend', () => {\n      it('should set backend', () => {\n        store.commit('setBackend', 'SERVER')\n        expect(store.getters['backend']).toBe('SERVER')\n        expect(store.getters['isCloud']).toBe(false)\n        store.commit('setBackend', 'CLOUD')\n        expect(store.getters['backend']).toBe('CLOUD')\n        expect(store.getters['isCloud']).toBe(true)\n      })\n      it('should throw an error if an invalid backend is used', () => {\n        expect(() => store.commit('setBackend', 'FOO')).toThrow(\n          'Invalid backend'\n        )\n      })\n    })\n\n    describe('unsetBackend', () => {\n      it('should set backend to null', () => {\n        store.commit('unsetBackend')\n        expect(store.getters['backend']).toEqual(null)\n      })\n    })\n\n    describe('setConnected', () => {\n      it('should update connected', () => {\n        expect(store.getters['connected']).toBe(true)\n        store.commit('setConnected', false)\n        expect(store.getters['connected']).toBe(false)\n      })\n      it('should throw an error if it tries to set connected to a non-boolean', () => {\n        expect(store.getters['connected']).toBe(true)\n        expect(() => store.commit('setConnected', 'tiger')).toThrow(\n          'Invalid connected state - connected should be a boolean'\n        )\n      })\n    })\n\n    describe('setConnectionMessage', () => {\n      it('should update the connection message', () => {\n        expect(store.getters['connectionMessage']).toBe(null)\n        store.commit('setConnectionMessage', 'hello')\n        expect(store.getters['connectionMessage']).toBe('hello')\n      })\n    })\n\n    describe('unsetConnectionMessage', () => {\n      it('should unset the connection message', () => {\n        store.commit('setConnectionMessage', 'hello')\n        expect(store.getters['connectionMessage']).toBe('hello')\n        store.commit('unsetConnectionMessage')\n        expect(store.getters['connectionMessage']).toBe(null)\n      })\n    })\n\n    describe('setConnectionTimeout', () => {\n      it('should set ConnectionTimeout', () => {\n        store.commit('setConnectionTimeout', 500)\n        expect(store.getters['connectionTimeout']).toBe(500)\n      })\n    })\n\n    describe('unsetConnectionTimeout', () => {\n      it('should unset ConnectionTimeout', () => {\n        store.commit('setConnectionTimeout', 500)\n        expect(store.getters['connectionTimeout']).toBe(500)\n        store.commit('unsetConnectionTimeout')\n        expect(store.getters['connectionTimeout']).toBe(null)\n        expect(clearTimeout).toHaveBeenCalled()\n      })\n    })\n\n    describe('setReleaseTimestamp', () => {\n      it('should set the release timestamp', () => {\n        store.commit('setReleaseTimestamp', 'a timestamp')\n        expect(store.getters['releaseTimestamp']).toBe('a timestamp')\n      })\n    })\n\n    describe('setApiMode', () => {\n      it('should set the api mode', () => {\n        store.commit('setApiMode', 'normal')\n        expect(store.getters['apiMode']).toBe('normal')\n        store.commit('setApiMode', 'maintenance')\n        expect(store.getters['apiMode']).toBe('maintenance')\n      })\n      it('should throw an error if we try to set an api model other than normal or maintenance', () => {\n        expect(() => store.commit('setApiMode', 'notnormal')).toThrow(\n          'Unexpected api mode'\n        )\n      })\n    })\n\n    describe('unsetReleaseTimestamp', () => {\n      it('should unset releaseTimestamp', () => {\n        store.commit('setReleaseTimestamp', 'a timestamp')\n        expect(store.getters['releaseTimestamp']).toBe('a timestamp')\n        store.commit('unsetReleaseTimetamp')\n        expect(store.getters['releaseTimestamp']).toBe(null)\n      })\n    })\n\n    describe('setRetries', () => {\n      it('should set retries', () => {\n        store.commit('setRetries', 5)\n        expect(store.getters['retries']).toBe(5)\n      })\n    })\n\n    describe('setServerUrl', () => {\n      it('should set the server url in state and local storage', () => {\n        store.commit('setServerUrl', 'http:localhost:4200')\n        expect(store.getters['serverUrl']).toEqual('http:localhost:4200')\n        expect(localStorage.setItem).toBeCalledWith(\n          SERVER_KEY,\n          'http:localhost:4200'\n        )\n      })\n    })\n\n    describe('unsetServerUrl', () => {\n      it('should unset the server url in state and local storage', () => {\n        store.commit('unsetServerUrl')\n        expect(store.getters['serverUrl']).toEqual(null)\n        expect(localStorage.removeItem).toBeCalledWith(SERVER_KEY)\n      })\n    })\n\n    describe('setVersion', () => {\n      it('should set the version', () => {\n        store.commit('setVersion', 2)\n        expect(store.getters['version']).toBe(2)\n      })\n    })\n\n    describe('unsetVersion', () => {\n      it('should unset the version', () => {\n        store.commit('setVersion', 2)\n        expect(store.getters['version']).toBe(2)\n        store.commit('unsetVersion')\n        expect(store.getters['version']).toBe(null)\n      })\n    })\n  })\n\n  describe('actions', () => {\n    let store\n    beforeEach(() => {\n      const state = initialAPIState()\n      store = new Vuex.Store({\n        state: state,\n        getters: api.getters,\n        mutations: api.mutations,\n        actions: api.actions\n      })\n    })\n\n    describe('getApi - no api error', () => {\n      beforeEach(() => {\n        mockerror = false\n      })\n      it('should set the version', async () => {\n        await store.dispatch('getApi')\n        expect(store.getters.version).toBe(2)\n      })\n      it('should set the release timestamp', async () => {\n        await store.dispatch('getApi')\n        expect(store.getters.releaseTimestamp).toBe('timestamp')\n      })\n      it('should set connected state', async () => {\n        await store.dispatch('getApi')\n        expect(store.getters.connected).toBe(true)\n      })\n      it('should set api mode', async () => {\n        await store.dispatch('getApi')\n        expect(store.getters.apiMode).toBe('maintenance')\n      })\n    })\n\n    describe('getApi - with api error', () => {\n      beforeEach(() => {\n        mockerror = true\n        const state = localStoreAPIState()\n        store = new Vuex.Store({\n          state: state,\n          getters: api.getters,\n          mutations: api.mutations,\n          actions: api.actions\n        })\n      })\n      it('should unset the version', async () => {\n        expect(store.getters.version).toBe(8)\n        await store.dispatch('getApi')\n        expect(store.getters.version).toBe(null)\n      })\n      it('should unset the release timestamp', async () => {\n        await store.dispatch('getApi')\n        expect(store.getters.releaseTimestamp).toBe(null)\n      })\n      it('should unset connected state', async () => {\n        await store.dispatch('getApi')\n        expect(store.getters.connected).toBe(false)\n      })\n    })\n\n    describe('monitorConnection - no query error', () => {\n      beforeEach(() => {\n        mockerror = false\n        const state = localStoreAPIState()\n        store = new Vuex.Store({\n          state: state,\n          getters: api.getters,\n          mutations: api.mutations,\n          actions: api.actions\n        })\n      })\n      it('should unset connection timeout', async () => {\n        await store.dispatch('monitorConnection')\n        expect(clearTimeout).toHaveBeenCalled()\n      })\n      it('should set the release timestamp', async () => {\n        await store.dispatch('monitorConnection')\n        expect(store.getters.releaseTimestamp).toBe('timestamp')\n      })\n      it('should set connected state', async () => {\n        await store.dispatch('monitorConnection')\n        expect(store.getters.connected).toBe(true)\n      })\n      it('should set the version', async () => {\n        await store.dispatch('monitorConnection')\n        expect(store.getters.version).toBe(2)\n      })\n      it('should set the connection message', async () => {\n        await store.dispatch('monitorConnection')\n        expect(store.getters.connectionMessage).toBe('Connected')\n      })\n      it('should set retries back to 0', async () => {\n        await store.dispatch('monitorConnection')\n        expect(store.getters.retries).toBe(0)\n      })\n    })\n\n    describe('monitorConnection - query error', () => {\n      beforeEach(() => {\n        mockerror = true\n        const state = localStoreAPIState()\n        store = new Vuex.Store({\n          state: state,\n          getters: api.getters,\n          mutations: api.mutations,\n          actions: api.actions\n        })\n      })\n      it('should unset connection timeout', async () => {\n        await store.dispatch('monitorConnection')\n        expect(clearTimeout).toHaveBeenCalled()\n      })\n      it('should set connected state to false', async () => {\n        await store.dispatch('monitorConnection')\n        expect(store.getters.connected).toBe(false)\n      })\n      it('should set the connection message', async () => {\n        await store.dispatch('monitorConnection')\n        expect(store.getters.connectionMessage).toBe(\n          \"TypeError: Cannot read property 'release_timestamp' of undefined\"\n        )\n      })\n    })\n\n    describe('setServerUrl', () => {\n      beforeEach(() => {\n        const state = localStoreAPIState()\n        store = new Vuex.Store({\n          state: state,\n          getters: api.getters,\n          mutations: api.mutations,\n          actions: api.actions\n        })\n      })\n      it('should set the server URL', async () => {\n        expect(store.getters.serverUrl).toBe('http://0.0.0.0:4200/graphql')\n        await store.dispatch('setServerUrl', 'new.url')\n        expect(store.getters.serverUrl).toBe('new.url')\n      })\n    })\n\n    describe('switchBackend', () => {\n      beforeEach(() => {\n        // Mock the mutations and actions from other stores\n        // that we don't want to\n        // test here\n        api.mutations['tenant/setTenant'] = jest.fn()\n        api.mutations['tenant/setDefaultTenant'] = jest.fn()\n        api.mutations['tenant/unsetTenants'] = jest.fn()\n        api.mutations['tenant/unsetTenant'] = jest.fn()\n        api.actions['tenant/getTenants'] = jest.fn()\n        api.actions['auth/authenticate'] = jest.fn()\n        api.actions['auth/authorize'] = jest.fn()\n        api.actions['user/getUser'] = jest.fn()\n\n        const state = localStoreAPIState()\n        store = new Vuex.Store({\n          state: state,\n          getters: api.getters,\n          mutations: api.mutations,\n          actions: api.actions\n        })\n      })\n\n      it('should call unsetTenant', async () => {\n        await store.dispatch('switchBackend', 'SERVER')\n        expect(api.mutations['tenant/unsetTenant']).toHaveBeenCalled()\n      })\n      it('should call unsetTenants', async () => {\n        await store.dispatch('switchBackend', 'SERVER')\n        expect(api.mutations['tenant/unsetTenants']).toHaveBeenCalled()\n      })\n\n      describe('switch backend to SERVER', () => {\n        it('should set the backend to SERVER', async () => {\n          expect(store.getters.backend).toBe('foo')\n          await store.dispatch('switchBackend', 'SERVER')\n          expect(store.getters.backend).toBe('SERVER')\n        })\n        it('should call unsetTenant', async () => {\n          await store.dispatch('switchBackend', 'SERVER')\n          expect(api.mutations['tenant/unsetTenant']).toHaveBeenCalled()\n        })\n        it('should call unsetTenants', async () => {\n          await store.dispatch('switchBackend', 'SERVER')\n          expect(api.mutations['tenant/unsetTenants']).toHaveBeenCalled()\n        })\n        it('should call setDefaultTenant', async () => {\n          await store.dispatch('switchBackend', 'SERVER')\n          expect(api.mutations['tenant/setDefaultTenant']).toHaveBeenCalled()\n        })\n      })\n\n      describe('switch backend to CLOUD', () => {\n        it('should set the backend to CLOUD', async () => {\n          expect(store.getters.backend).toBe('foo')\n          await store.dispatch('switchBackend', 'CLOUD')\n          expect(store.getters.backend).toBe('CLOUD')\n        })\n        it('should not call setDefaultTenant', async () => {\n          await store.dispatch('switchBackend', 'CLOUD')\n          expect(\n            api.mutations['tenant/setDefaultTenant']\n          ).toHaveBeenCalledTimes(0)\n        })\n        it('should authenticate', async () => {\n          await store.dispatch('switchBackend', 'CLOUD')\n          expect(api.actions['auth/authenticate']).toHaveBeenCalled()\n        })\n        it('should authorize', async () => {\n          await store.dispatch('switchBackend', 'CLOUD')\n          expect(api.actions['auth/authorize']).toHaveBeenCalled()\n        })\n        it('should get the user details', async () => {\n          await store.dispatch('switchBackend', 'CLOUD')\n          expect(api.actions['user/getUser']).toHaveBeenCalled()\n        })\n        it('should get tenants', async () => {\n          await store.dispatch('switchBackend', 'CLOUD')\n          expect(api.actions['tenant/getTenants']).toHaveBeenCalled()\n        })\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/store/auth.spec.js",
    "content": "import auth_base from '@/store/auth'\n\nconst auth = { ...auth_base }\n\nimport {\n  MOCK_AUTHORIZATION_TOKEN,\n  MOCK_ID_TOKEN,\n  MOCK_REFRESH_TOKEN\n} from './mockTokens'\n\nimport { createLocalVue } from '@vue/test-utils'\nimport Vuex from 'vuex'\n\nconst localVue = createLocalVue()\nlocalVue.use(Vuex)\n\ndescribe('auth Vuex Module', () => {\n  const loggedInState = () => {\n    return {\n      authorizationToken: MOCK_AUTHORIZATION_TOKEN,\n      authorizationTokenExpiry: new Date().getTime() + 10000,\n      idToken: MOCK_ID_TOKEN,\n      idTokenExpiry: new Date().getTime() + 10000,\n      isAuthenticated: true,\n      refreshToken: MOCK_REFRESH_TOKEN,\n      refreshTokenExpiry: new Date().getTime() + 10000,\n      user: {\n        sub: 'user',\n        name: 'user',\n        email: 'user@domain.com'\n      }\n    }\n  }\n\n  describe('State', () => {\n    it('should be initialized properly without tokens in localStorage ', () => {\n      const state = auth.state\n\n      expect(Object.keys(state).length).toBe(7)\n\n      expect(state.user).toBe(null)\n      expect(state.authorizationToken).toBe(null)\n      expect(state.authorizationTokenExpiry).toBe(null)\n      expect(state.idToken).toBe(null)\n      expect(state.idTokenExpiry).toBe(null)\n      expect(state.refreshToken).toBe(null)\n      expect(state.refreshTokenExpiry).toBe(null)\n    })\n  })\n\n  describe('Getters', () => {\n    let store\n\n    beforeEach(() => {\n      store = new Vuex.Store({\n        state: loggedInState(),\n        getters: auth.getters,\n        actions: auth.actions,\n        mutations: auth.mutations\n      })\n    })\n\n    it('should return the user', () => {\n      expect(store.getters.user).toBe(store.state.user)\n    })\n\n    it('should return the idToken', () => {\n      expect(store.getters.idToken).toBe(store.state.idToken)\n    })\n\n    it('should return isAuthenticated', () => {\n      expect(store.getters.isAuthenticated).toBe(true)\n    })\n\n    it('should return isAuthorized', () => {\n      expect(store.getters.isAuthorized).toBe(true)\n    })\n\n    it('should return the authorizationToken', () => {\n      expect(store.getters.authorizationToken).toBe(\n        store.state.authorizationToken\n      )\n    })\n\n    it('should return the refreshToken', () => {\n      expect(store.getters.refreshToken).toBe(store.state.refreshToken)\n    })\n\n    it('should return the authorizationTokenExpiry', () => {\n      expect(store.getters.authorizationTokenExpiry).toBe(\n        store.state.authorizationTokenExpiry\n      )\n    })\n\n    it('should return the refreshTokenExpiry', () => {\n      expect(store.getters.refreshTokenExpiry).toBe(\n        store.state.refreshTokenExpiry\n      )\n    })\n\n    it('should return the idTokenExpiry', () => {\n      expect(store.getters.idTokenExpiry).toBe(store.state.idTokenExpiry)\n    })\n  })\n\n  describe('Mutations', () => {\n    describe('...correctly set their associated states', () => {\n      let store\n\n      beforeEach(() => {\n        store = new Vuex.Store({\n          state: auth.state,\n          getters: auth.getters,\n          actions: auth.actions,\n          mutations: auth.mutations\n        })\n      })\n\n      it('should set the user', () => {\n        store.commit('user', loggedInState().user)\n        const user = loggedInState().user\n        expect(store.getters['user'].name).toBe(user.name)\n        expect(store.getters['user'].sub).toBe(user.sub)\n        expect(store.getters['user'].email).toBe(user.email)\n      })\n\n      it('should set the idToken', () => {\n        const idToken = loggedInState().idToken\n        store.commit('idToken', idToken)\n        expect(store.getters['idToken']).toBe(idToken)\n      })\n\n      it('should set the authorizationToken', () => {\n        store.commit('authorizationToken', loggedInState().authorizationToken)\n        expect(store.getters['authorizationToken']).toBe(\n          loggedInState().authorizationToken\n        )\n      })\n\n      it('should set the refreshToken', () => {\n        store.commit('refreshToken', loggedInState().refreshToken)\n        expect(store.getters['refreshToken']).toBe(loggedInState().refreshToken)\n      })\n\n      it('should set the authorizationTokenExpiry', () => {\n        const loggedInStateExpiration = loggedInState().authorizationTokenExpiry\n        store.commit('authorizationTokenExpiry', loggedInStateExpiration)\n        expect(store.getters['authorizationTokenExpiry']).toBe(\n          loggedInStateExpiration\n        )\n      })\n\n      it('should set the refreshTokenExpiry', () => {\n        const loggedInStateExpiration = loggedInState().refreshTokenExpiry\n        store.commit('refreshTokenExpiry', loggedInStateExpiration)\n        expect(store.getters['refreshTokenExpiry']).toBe(\n          loggedInStateExpiration\n        )\n      })\n\n      it('should set the idTokenExpiry', () => {\n        const loggedInStateExpiration = loggedInState().idTokenExpiry\n        store.commit('idTokenExpiry', loggedInStateExpiration)\n        expect(store.getters['idTokenExpiry']).toBe(loggedInStateExpiration)\n      })\n    })\n\n    describe('... throw errors when invalid data are passed in', () => {\n      let store\n\n      beforeEach(() => {\n        store = new Vuex.Store({\n          state: auth.state,\n          getters: auth.getters,\n          actions: auth.actions,\n          mutations: auth.mutations\n        })\n\n        localStorage.setItem.mockClear()\n        localStorage.getItem.mockClear()\n        localStorage.removeItem.mockClear()\n      })\n\n      it('user throws error on invalid state', () => {\n        expect(() => store.commit('user', null)).toThrow(TypeError)\n        expect(() => store.commit('user', false)).toThrow(TypeError)\n        expect(() => store.commit('user', undefined)).toThrow(TypeError)\n        expect(() => store.commit('user', 'test')).toThrow(TypeError)\n        expect(() => store.commit('user', 12345)).toThrow(TypeError)\n      })\n\n      it('idToken throws error on invalid state', () => {\n        expect(() => store.commit('idToken', null)).toThrow(TypeError)\n        expect(() => store.commit('idToken', false)).toThrow(TypeError)\n\n        expect(() => store.commit('idToken', undefined)).toThrow(TypeError)\n        expect(() => store.commit('idToken', 'test')).toThrow(TypeError)\n        expect(() => store.commit('idToken', 12345)).toThrow(TypeError)\n      })\n\n      it('authorizationToken throws error on invalid state', () => {\n        expect(() => store.commit('authorizationToken', null)).toThrow(\n          TypeError\n        )\n        expect(() => store.commit('authorizationToken', false)).toThrow(\n          TypeError\n        )\n        expect(() => store.commit('authorizationToken', undefined)).toThrow(\n          TypeError\n        )\n        expect(() => store.commit('authorizationToken', 'test')).toThrow(\n          TypeError\n        )\n        expect(() => store.commit('authorizationToken', 12345)).toThrow(\n          TypeError\n        )\n      })\n\n      it('refreshToken throws error on invalid state', () => {\n        expect(() => store.commit('refreshToken', null)).toThrow(TypeError)\n        expect(() => store.commit('refreshToken', false)).toThrow(TypeError)\n        expect(() => store.commit('refreshToken', undefined)).toThrow(TypeError)\n        expect(() => store.commit('refreshToken', 'test')).toThrow(TypeError)\n        expect(() => store.commit('refreshToken', 12345)).toThrow(TypeError)\n      })\n\n      it('authorizationTokenExpiry throws error on invalid state', () => {\n        expect(() => store.commit('authorizationTokenExpiry', null)).toThrow(\n          TypeError\n        )\n        expect(() => store.commit('authorizationTokenExpiry', false)).toThrow(\n          TypeError\n        )\n        expect(() =>\n          store.commit('authorizationTokenExpiry', undefined)\n        ).toThrow(TypeError)\n        expect(() => store.commit('authorizationTokenExpiry', 'test')).toThrow(\n          TypeError\n        )\n      })\n\n      it('refreshTokenExpiry throws error on invalid state', () => {\n        expect(() => store.commit('refreshTokenExpiry', null)).toThrow(\n          TypeError\n        )\n        expect(() => store.commit('refreshTokenExpiry', false)).toThrow(\n          TypeError\n        )\n        expect(() => store.commit('refreshTokenExpiry', undefined)).toThrow(\n          TypeError\n        )\n        expect(() => store.commit('refreshTokenExpiry', 'test')).toThrow(\n          TypeError\n        )\n      })\n\n      it('idTokenExpiry throws error on invalid state', () => {\n        expect(() => store.commit('idTokenExpiry', null)).toThrow(TypeError)\n        expect(() => store.commit('idTokenExpiry', false)).toThrow(TypeError)\n        expect(() => store.commit('idTokenExpiry', undefined)).toThrow(\n          TypeError\n        )\n        expect(() => store.commit('idTokenExpiry', 'test')).toThrow(TypeError)\n      })\n    })\n\n    describe('... successfully resets stores with unset methods', () => {\n      let store\n\n      beforeEach(() => {\n        store = new Vuex.Store({\n          state: auth.state,\n          getters: auth.getters,\n          actions: auth.actions,\n          mutations: auth.mutations\n        })\n      })\n\n      it('unsets user', () => {\n        store.commit('user', loggedInState().user)\n        expect(store.getters['user']).toEqual(loggedInState().user)\n        store.commit('unsetUser')\n        expect(store.getters['user']).toBe(null)\n      })\n\n      it('unsets idToken', () => {\n        const idToken = loggedInState().idToken\n        store.commit('idToken', idToken)\n        expect(store.getters['idToken']).toBe(idToken)\n\n        store.commit('unsetIdToken')\n        expect(store.getters['idToken']).toBe(null)\n      })\n\n      it('unsets refreshToken', () => {\n        store.commit('refreshToken', loggedInState().refreshToken)\n        expect(store.getters['refreshToken']).toBe(loggedInState().refreshToken)\n\n        store.commit('unsetRefreshToken')\n        expect(store.getters['refreshToken']).toBe(null)\n      })\n\n      it('unsets authorizationTokenExpiry', () => {\n        const loggedInStateExpiration = loggedInState().authorizationTokenExpiry\n        store.commit('authorizationTokenExpiry', loggedInStateExpiration)\n        expect(store.getters['authorizationTokenExpiry']).toBe(\n          loggedInStateExpiration\n        )\n\n        store.commit('unsetAuthorizationTokenExpiry')\n        expect(store.getters['authorizationTokenExpiry']).toBe(null)\n      })\n\n      it('unsets refreshTokenExpiry', () => {\n        const loggedInStateExpiration = loggedInState().refreshTokenExpiry\n        store.commit('refreshTokenExpiry', loggedInStateExpiration)\n        expect(store.getters['refreshTokenExpiry']).toBe(\n          loggedInStateExpiration\n        )\n\n        store.commit('unsetRefreshTokenExpiry')\n        expect(store.getters['refreshTokenExpiry']).toBe(null)\n      })\n\n      it('unsets idTokenExpiry', () => {\n        const loggedInStateExpiration = loggedInState().idTokenExpiry\n        store.commit('idTokenExpiry', loggedInStateExpiration)\n        expect(store.getters['idTokenExpiry']).toBe(loggedInStateExpiration)\n\n        store.commit('unsetIdTokenExpiry')\n        expect(store.getters['idTokenExpiry']).toBe(null)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/store/data.spec.js",
    "content": "import data from '@/store/data'\nimport { createLocalVue } from '@vue/test-utils'\nimport Vuex from 'vuex'\n\nconst localVue = createLocalVue()\nlocalVue.use(Vuex)\n\nlet mockError = false\njest.mock('@/vue-apollo', () => {\n  return {\n    fallbackApolloClient: {\n      query: () => {\n        if (!mockError) {\n          return {\n            data: {\n              flow: [\n                {\n                  id: 'f-111',\n                  flow_group_id: 'fg-111',\n                  project_id: 'p-111',\n                  name: 'Flow 111'\n                }\n              ],\n              project: [\n                {\n                  id: 'p-111',\n                  name: 'Project 111'\n                }\n              ],\n              task: [\n                {\n                  id: 't-111',\n                  flow_id: 'f-111',\n                  name: 'Name 111'\n                }\n              ]\n            }\n          }\n        } else {\n          return { data: 'error' }\n        }\n      }\n    }\n  }\n})\n\njest.mock('@/graphql/Nav/flows.gql', () => 'flows query string')\njest.mock('@/graphql/Nav/flow.gql', () => 'flow query string')\njest.mock('@/graphql/Nav/projects.gql', () => 'projects query string')\njest.mock('@/graphql/Nav/task.gql', () => 'tasks query string')\n\nconst dataObjects = ['flow', 'project', 'task']\n\nconst generators = {\n  flow: (len = 5) => {\n    return Array.from({ length: len }, (v, i) => {\n      return {\n        id: 'f' + i,\n        flow_group_id: 'fg' + i,\n        name: 'Flow ' + i,\n        project_id: 'p' + Math.floor(Math.random() * 5) // Random project id between p0 and p5\n      }\n    })\n  },\n  project: (len = 5) => {\n    return Array.from({ length: len }, (v, i) => {\n      return {\n        id: 'p' + i,\n        name: 'Project ' + i\n      }\n    })\n  },\n  task: (len = 5) => {\n    return Array.from({ length: len }, (v, i) => {\n      return {\n        id: 't' + i,\n        name: 'Task ' + i,\n        flow_id: 'f' + Math.floor(Math.random() * 5) // Random flow id between f0 and f5\n      }\n    })\n  }\n}\n\ndescribe('data Vuex Module', () => {\n  const unsetState = () => {\n    return {\n      activeFlow: null,\n      activeProject: null,\n      activeTask: null,\n      flows: null,\n      projects: null,\n      tasks: null\n    }\n  }\n\n  const setState = () => {\n    const flows = generators.flow()\n    const projects = generators.project()\n    const tasks = generators.task()\n\n    const activeTask = tasks[Math.floor(Math.random() * 5)] // Random activeTask\n    const activeFlow = flows.find(f => f.id == activeTask.flow_id) // activeFlow based on activeTask\n    const activeProject = projects.find(p => p.id == activeFlow.project_id) // activeProject based on activeFlow\n\n    return {\n      activeFlow: activeFlow,\n      activeProject: activeProject,\n      activeTask: activeTask,\n      flows: flows,\n      projects: projects,\n      tasks: tasks\n    }\n  }\n\n  describe('State', () => {\n    it('should hold data', () => {\n      const state = data.state\n      expect(state.activeFlow).toBe(null)\n      expect(state.activeProject).toBe(null)\n      expect(state.activeTask).toBe(null)\n\n      expect(state.flows).toBe(null)\n      expect(state.projects).toBe(null)\n      expect(state.tasks).toBe(null)\n    })\n  })\n\n  describe('Getters', () => {\n    describe('while unset', () => {\n      let state, store\n      beforeEach(() => {\n        state = unsetState()\n        store = new Vuex.Store({\n          state: state,\n          getters: data.getters,\n          actions: data.actions,\n          mutations: data.mutations\n        })\n      })\n\n      dataObjects.forEach(d => {\n        const active = 'active' + d.charAt(0).toUpperCase() + d.slice(1)\n        const plural = d + 's'\n\n        test(`${active} getter should return null`, () => {\n          expect(store.getters[active]).toEqual(null)\n        })\n\n        test(`${plural} getter should return null`, () => {\n          expect(store.getters[plural]).toEqual(null)\n        })\n      })\n    })\n\n    describe('while set', () => {\n      let state, store\n      beforeEach(() => {\n        state = setState()\n        store = new Vuex.Store({\n          state: state,\n          getters: data.getters,\n          actions: data.actions,\n          mutations: data.mutations\n        })\n      })\n\n      dataObjects.forEach(d => {\n        const active = 'active' + d.charAt(0).toUpperCase() + d.slice(1)\n        const plural = d + 's'\n        const id = active + 'Id'\n\n        test(`${active} getter should return the state ${active} object`, () => {\n          expect(store.getters[active]).toEqual(state[active])\n        })\n\n        test(`${plural} getter should return a list of ${plural}`, () => {\n          expect(store.getters[plural]).toEqual(state[plural])\n        })\n\n        test(`${id} getter should return the id of ${active}`, () => {\n          expect(store.getters[id]).toEqual(state[active].id)\n        })\n      })\n    })\n  })\n\n  describe('Mutations', () => {\n    let state, store\n    beforeEach(() => {\n      state = unsetState()\n      store = new Vuex.Store({\n        state: state,\n        getters: data.getters,\n        actions: data.actions,\n        mutations: data.mutations\n      })\n    })\n\n    const activeDataMutations = ['Flow', 'Project', 'Task']\n\n    activeDataMutations.forEach(d => {\n      describe(`setActive${d}`, () => {\n        const error = `passed invalid or empty ${d}; Expected Object, got: `\n\n        it(`should set the active${d}`, () => {\n          const generated = generators[d.toLowerCase()](1)[0] // Creates a new random object\n          store.commit(`setActive${d}`, generated)\n          expect(store.getters[`active${d}`]).toEqual(generated)\n        })\n\n        it(`should throw an error if passed an invalid ${d} data type`, () => {\n          const toPass = [1, 2, 3]\n          expect(() => store.commit(`setActive${d}`, toPass)).toThrow(\n            error + toPass\n          )\n        })\n\n        it(`should throw an error if passed no ${d}`, () => {\n          expect(() => store.commit(`setActive${d}`)).toThrow(\n            error + 'undefined'\n          )\n        })\n\n        it(`should throw an error if passed an empty ${d} object`, () => {\n          const toPass = {}\n          expect(() => store.commit(`setActive${d}`, toPass)).toThrow(\n            error + toPass\n          )\n        })\n      })\n\n      describe(`unsetActive${d}`, () => {\n        let state, store\n        beforeEach(() => {\n          state = setState()\n          store = new Vuex.Store({\n            state: state,\n            getters: data.getters,\n            actions: data.actions,\n            mutations: data.mutations\n          })\n        })\n\n        it(`should unset the active${d}`, () => {\n          expect(store.getters[`active${d}`].id).toEqual(state[`active${d}`].id)\n          store.commit(`unsetActive${d}`)\n          expect(store.getters[`active${d}`]).toEqual(null)\n        })\n      })\n    })\n\n    describe('addTasks', () => {\n      it(\"should add passed tasks to the tasks array and should create it if it doesn't exist\", () => {\n        expect(state.tasks).toEqual(null)\n\n        const tasks = generators.task(5)\n        store.commit('addTasks', tasks)\n\n        expect(state.tasks).toEqual(tasks)\n        expect(state.tasks.length).toEqual(5)\n      })\n\n      it('should update existing tasks in the store if matching ids are passed', () => {\n        expect(state.tasks).toEqual(null)\n\n        const tasks = generators.task(5)\n        const taskToChange = tasks[0]\n\n        store.commit('addTasks', tasks)\n        expect(state.tasks).toEqual(tasks)\n        expect(state.tasks.length).toEqual(5)\n\n        taskToChange.name = 'Some updated task name'\n        store.commit('addTasks', [taskToChange])\n\n        expect(state.tasks.length).toEqual(5)\n\n        const storedTasks = store.getters['tasks']\n        const changedTask = storedTasks.find(t => t.id == taskToChange.id)\n        expect(changedTask).toEqual(taskToChange)\n        expect(changedTask.name).toEqual(taskToChange.name)\n      })\n\n      it('should throw an error if passed an invalid data type', () => {\n        const toPass = { 1: 'foo', 2: 'bar' }\n        expect(() => store.commit('addTasks', toPass)).toThrow(\n          'passed null or invalid Tasks; Expected Array, got: ' + toPass\n        )\n      })\n    })\n\n    const dataMutations = ['Flows', 'Projects', 'Tasks']\n\n    dataMutations.forEach(d => {\n      const ref = d.toLowerCase()\n      const error = `passed invalid ${d}; Expected Array, got: `\n\n      describe(`set${d}`, () => {\n        it(`should set the ${d} array`, () => {\n          const generated = generators[\n            ref.substring(0, d.length - 1) // Uncapitalize and remove plural\n          ](5) // Creates a new random array of objects\n          store.commit(`set${d}`, generated)\n          expect(store.getters[ref]).toEqual(generated)\n          expect(store.getters[ref].length).toEqual(5)\n        })\n\n        it(`should throw an error if passed an invalid ${d} data type`, () => {\n          const toPass = { 1: 'foo', 2: 'bar' }\n          expect(() => store.commit(`set${d}`, toPass)).toThrow(error + toPass)\n        })\n\n        it(`should throw an error if passed no ${d}`, () => {\n          expect(() => store.commit(`set${d}`)).toThrow(error + 'undefined')\n        })\n      })\n\n      describe(`unset${d}`, () => {\n        let state, store\n        beforeEach(() => {\n          state = setState()\n          store = new Vuex.Store({\n            state: state,\n            getters: data.getters,\n            actions: data.actions,\n            mutations: data.mutations\n          })\n        })\n\n        it(`should unset the ${d} array`, () => {\n          expect(store.getters[ref][0].id).toEqual(state[ref][0].id)\n\n          store.commit(`unset${d}`)\n          expect(store.getters[ref]).toEqual(null)\n        })\n      })\n    })\n  })\n\n  describe('Actions', () => {\n    let state, store\n    beforeEach(() => {\n      state = unsetState()\n      store = new Vuex.Store({\n        state: state,\n        getters: data.getters,\n        actions: data.actions,\n        mutations: data.mutations\n      })\n    })\n\n    describe('resetActiveData', () => {\n      it('removes all active* data', () => {\n        state = setState()\n        store = new Vuex.Store({\n          state: state,\n          getters: data.getters,\n          actions: data.actions,\n          mutations: data.mutations\n        })\n\n        expect(store.getters['activeFlow'].id).toEqual(state['activeFlow'].id)\n        expect(store.getters['activeProject'].id).toEqual(\n          state['activeProject'].id\n        )\n        expect(store.getters['activeTask'].id).toEqual(state['activeTask'].id)\n\n        store.dispatch('resetActiveData')\n\n        expect(store.getters['activeFlow']).toEqual(null)\n        expect(store.getters['activeProject']).toEqual(null)\n        expect(store.getters['activeTask']).toEqual(null)\n      })\n    })\n\n    describe('resetData', () => {\n      it('removes all data', () => {\n        state = setState()\n        store = new Vuex.Store({\n          state: state,\n          getters: data.getters,\n          actions: data.actions,\n          mutations: data.mutations\n        })\n\n        expect(store.getters['activeFlow'].id).toEqual(state['activeFlow'].id)\n        expect(store.getters['activeProject'].id).toEqual(\n          state['activeProject'].id\n        )\n        expect(store.getters['activeTask'].id).toEqual(state['activeTask'].id)\n\n        expect(store.getters['flows'].length).toEqual(5)\n        expect(store.getters['projects'].length).toEqual(5)\n        expect(store.getters['tasks'].length).toEqual(5)\n\n        expect(store.getters['flows'][0].id).toEqual(state['flows'][0].id)\n        expect(store.getters['projects'][0].id).toEqual(state['projects'][0].id)\n        expect(store.getters['tasks'][0].id).toEqual(state['tasks'][0].id)\n\n        store.dispatch('resetData')\n\n        expect(store.getters['activeFlow']).toEqual(null)\n        expect(store.getters['activeProject']).toEqual(null)\n        expect(store.getters['activeTask']).toEqual(null)\n        expect(store.getters['flows']).toEqual(null)\n        expect(store.getters['projects']).toEqual(null)\n        expect(store.getters['tasks']).toEqual(null)\n      })\n    })\n\n    describe('activating projects, flows, and tasks', () => {\n      let state, store\n      beforeEach(() => {\n        state = unsetState()\n        store = new Vuex.Store({\n          state: state,\n          getters: data.getters,\n          actions: data.actions,\n          mutations: data.mutations\n        })\n      })\n\n      describe('activateFlow', () => {\n        beforeEach(() => {\n          state = setState()\n          store = new Vuex.Store({\n            state: state,\n            getters: data.getters,\n            actions: data.actions,\n            mutations: data.mutations\n          })\n        })\n\n        it('sets the activeFlow from the store when the flow exists in the store', async () => {\n          expect(store.getters['activeFlow'].id).toEqual(state['activeFlow'].id)\n\n          const id = store.getters['flows'].find(\n            f => f.id !== state['activeFlow'].id\n          ).id // Find the first flow in the store that isn't the activeFlow\n\n          expect(store.getters['activeFlow'].id).not.toEqual(id)\n\n          await store.dispatch('activateFlow', id)\n\n          expect(store.getters['activeFlow'].id).toEqual(id)\n        })\n\n        it('sets the activeProject after setting the activeFlow', async () => {\n          state = unsetState()\n          const spy = jest.spyOn(data.actions, 'activateProject')\n\n          store = new Vuex.Store({\n            state: state,\n            getters: data.getters,\n            actions: data.actions,\n            mutations: data.mutations\n          })\n          const flows = generators['flow'](5)\n\n          store.commit('setFlows', flows)\n          expect(store.getters['flows']).toEqual(flows)\n\n          expect(store.getters['activeFlow']).toEqual(null)\n          expect(store.getters['activeProject']).toEqual(null)\n\n          const id = 'f2'\n          const project_id = flows.find(f => f.id == id).project_id\n          store.commit('setProjects', [\n            { id: project_id, name: 'Some Project Name' }\n          ])\n\n          await store.dispatch('activateFlow', id)\n          await expect(data.actions['activateProject']).toHaveBeenCalledTimes(1)\n\n          expect(store.getters['activeFlow'].id).toEqual(id)\n          expect(store.getters['activeProject'].id).toEqual(project_id)\n\n          spy.mockRestore()\n        })\n\n        it('sets the activeFlow from a flow_group_id', async () => {\n          expect(store.getters['activeFlow'].id).toEqual(state['activeFlow'].id)\n\n          const id = 'fg-111' // Known flow group id\n\n          await store.dispatch('activateFlow', id)\n\n          expect(store.getters['activeFlow'].id).toEqual('f-111')\n        })\n\n        it(\"re-fetches and sets both the flows and the activeFlow if the flow doesn't exist in the store\", async () => {\n          expect(store.getters['activeFlow'].id).toEqual(state['activeFlow'].id)\n\n          const id = 'f-111' // Known flow id\n\n          expect(state['activeFlow'].id).not.toEqual(id)\n\n          expect(store.getters['flows'].find(p => p.id == id)).toBeFalsy()\n\n          await store.dispatch('activateFlow', id)\n\n          expect(store.getters['activeFlow'].id).toEqual(id)\n        })\n\n        it(\"throws an error if the flow doesn't exist in the store and can't be fetched\", async () => {\n          expect(store.getters['flows']).toEqual(state['flows'])\n\n          const id = 'f-222' // Unknown flow id\n\n          expect(store.getters['flows'].find(f => f.id == id)).toBeFalsy()\n\n          expect(store.dispatch('activateFlow', id)).rejects.toThrow(\n            \"Couldn't retrieve flow.\"\n          )\n        })\n      })\n\n      describe('activateProject', () => {\n        beforeEach(() => {\n          state = setState()\n          store = new Vuex.Store({\n            state: state,\n            getters: data.getters,\n            actions: data.actions,\n            mutations: data.mutations\n          })\n        })\n\n        it('sets the activeProject from the store when the project exists in the store', async () => {\n          expect(store.getters['activeProject'].id).toEqual(\n            state['activeProject'].id\n          )\n\n          const id = store.getters['projects'].find(\n            p => p.id !== state['activeProject'].id\n          ).id // Find the first project in the store that isn't the activeProject\n\n          expect(store.getters['activeProject'].id).not.toEqual(id)\n\n          await store.dispatch('activateProject', id)\n\n          expect(store.getters['activeProject'].id).toEqual(id)\n        })\n\n        it(\"re-fetches and sets both the projects and the activeProject if the project doesn't exist in the store\", async () => {\n          expect(store.getters['activeProject'].id).toEqual(\n            state['activeProject'].id\n          )\n\n          const id = 'p-111' // Known project id\n\n          expect(state['activeProject'].id).not.toEqual(id)\n\n          expect(store.getters['projects'].find(p => p.id == id)).toBeFalsy()\n\n          await store.dispatch('activateProject', id)\n\n          expect(store.getters['activeProject'].id).toEqual(id)\n        })\n\n        it(\"throws an error if the project doesn't exist in the store and can't be fetched\", async () => {\n          expect(store.getters['projects']).toEqual(state['projects'])\n\n          const id = 'p-222' // Unknown project id\n\n          expect(store.getters['projects'].find(p => p.id == id)).toBeFalsy()\n\n          expect(store.dispatch('activateProject', id)).rejects.toThrow(\n            \"Couldn't retrieve project.\"\n          )\n        })\n      })\n\n      describe('activateTask', () => {\n        beforeEach(() => {\n          state = setState()\n          store = new Vuex.Store({\n            state: state,\n            getters: data.getters,\n            actions: data.actions,\n            mutations: data.mutations\n          })\n        })\n\n        it('sets the activeTask from the store when the task exists in the store', async () => {\n          expect(store.getters['activeTask'].id).toEqual(state['activeTask'].id)\n\n          const id = store.getters['tasks'].find(\n            p => p.id !== state['activeTask'].id\n          ).id // Find the first task in the store that isn't the activeTask\n\n          expect(store.getters['activeTask'].id).not.toEqual(id)\n\n          await store.dispatch('activateTask', id)\n\n          expect(store.getters['activeTask'].id).toEqual(id)\n        })\n\n        it('sets the activeFlow and activeProject after setting the activeTask', async () => {\n          state = unsetState()\n          const flowSpy = jest.spyOn(data.actions, 'activateFlow')\n          const projectSpy = jest.spyOn(data.actions, 'activateProject')\n\n          store = new Vuex.Store({\n            state: state,\n            getters: data.getters,\n            actions: data.actions,\n            mutations: data.mutations\n          })\n          const tasks = generators['task'](5)\n\n          store.commit('setTasks', tasks)\n          expect(store.getters['tasks']).toEqual(tasks)\n\n          expect(store.getters['activeTask']).toEqual(null)\n          expect(store.getters['activeFlow']).toEqual(null)\n          expect(store.getters['activeProject']).toEqual(null)\n\n          const id = 't2'\n          const flow_id = tasks.find(f => f.id == id).flow_id\n          const project_id = 'p-444'\n          store.commit('setFlows', [\n            {\n              id: flow_id,\n              flow_group_id: 'fg-444',\n              name: 'Some Flow Name',\n              project_id: project_id\n            }\n          ])\n          store.commit('setProjects', [\n            { id: project_id, name: 'Some Project Name' }\n          ])\n\n          await store.dispatch('activateTask', id)\n          await expect(data.actions['activateFlow']).toHaveBeenCalledTimes(1)\n          await expect(data.actions['activateProject']).toHaveBeenCalledTimes(1)\n\n          expect(store.getters['activeTask'].id).toEqual(id)\n          expect(store.getters['activeFlow'].id).toEqual(flow_id)\n          expect(store.getters['activeProject'].id).toEqual(project_id)\n\n          flowSpy.mockRestore()\n          projectSpy.mockRestore()\n        })\n\n        it(\"re-fetches and sets both the tasks and the activeTask if the task doesn't exist in the store\", async () => {\n          expect(store.getters['activeTask'].id).toEqual(state['activeTask'].id)\n\n          const id = 't-111' // Known task id\n\n          expect(state['activeTask'].id).not.toEqual(id)\n\n          expect(store.getters['tasks'].find(p => p.id == id)).toBeFalsy()\n\n          await store.dispatch('activateTask', id)\n\n          expect(store.getters['activeTask'].id).toEqual(id)\n        })\n\n        it(\"throws an error if the task doesn't exist in the store and can't be fetched\", async () => {\n          expect(store.getters['tasks']).toEqual(state['tasks'])\n\n          const id = 't-222' // Unknown task id\n\n          expect(store.getters['tasks'].find(p => p.id == id)).toBeFalsy()\n\n          expect(store.dispatch('activateTask', id)).rejects.toThrow(\n            \"Couldn't retrieve task.\"\n          )\n        })\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/store/license.spec.js",
    "content": "process.env.VUE_APP_BACKEND = 'CLOUD'\n\nimport license from '@/store/license'\nimport { createLocalVue } from '@vue/test-utils'\nimport Vuex from 'vuex'\n\n//simple mock for gql query\nlet mockerror = false\n\njest.mock('logrocket', () => {\n  return {\n    captureException: jest.fn()\n  }\n})\n\njest.mock('@/graphql/License/license.gql', () => 'license query string')\n\njest.mock('@/vue-apollo', () => {\n  return {\n    fallbackApolloClient: {\n      query: () => {\n        if (!mockerror) {\n          return {\n            data: {\n              auth_info: {\n                license: {},\n                permissions: {}\n              }\n            }\n          }\n        } else {\n          return 'error'\n        }\n      }\n    }\n  }\n})\n\nconst localVue = createLocalVue()\nlocalVue.use(Vuex)\n\ndescribe('license Vuex Module', () => {\n  const initialLicenseState = () => {\n    return {\n      license: null,\n      permissions: null\n    }\n  }\n\n  const activePermissions = () => {\n    return ['read:flow', 'read:project']\n  }\n\n  const activeLicense = () => {\n    return {\n      id: 'bar',\n      key: 'foo',\n      active: true,\n      terms: {\n        plan: 'SELF_SERVE',\n        users: 1,\n        history_retention_days: 30,\n        flow_concurrency: 1,\n        permissions: ['tier:scheduler', 'plan:self-serve']\n      }\n    }\n  }\n\n  describe('License State', () => {\n    it('should initally be unset', () => {\n      const state = license.state\n      expect(state.license).toBe(null)\n    })\n  })\n\n  describe('Permissions State', () => {\n    it('should initially be unset', () => {\n      const state = license.state\n      expect(state.permissions).toBe(null)\n    })\n  })\n\n  describe('getters', () => {\n    describe('when no license is set', () => {\n      let store\n\n      beforeEach(() => {\n        process.env.VUE_APP_BACKEND = 'CLOUD'\n        const license = require('@/store/license').default\n        store = new Vuex.Store({\n          state: license.state,\n          getters: license.getters,\n          mutations: license.mutations\n        })\n      })\n\n      it('should return null when the license getter is called', () => {\n        expect(store.getters.license).toBe(null)\n      })\n\n      it('should return false if there is no license when the hasLicense getter is called', () => {\n        expect(store.getters.hasLicense).toBe(false)\n      })\n\n      it('should return null when the permissions getter is called', () => {\n        expect(store.getters.permissions).toBe(null)\n      })\n\n      it('should return undefined when the planType getter is called with no parameters', () => {\n        expect(store.getters.planType()).toBe(undefined)\n      })\n\n      it('should return undefined when the planType getter is called with parameters', () => {\n        expect(store.getters.planType('STARTER')).toBe(undefined)\n      })\n\n      it('should return undefined when the hasPermission getter is called with  no parameters', () => {\n        expect(store.getters.hasPermission()).toBe(undefined)\n      })\n\n      it('should return undefined when the hasPermission getter is called with parameters', () => {\n        expect(store.getters.hasPermission('read', 'flow')).toBe(undefined)\n      })\n    })\n\n    describe('when licenses are set', () => {\n      // testing this works in both types of state\n      let store\n\n      beforeEach(() => {\n        process.env.VUE_APP_BACKEND = 'CLOUD'\n        const license = require('@/store/license').default\n        store = new Vuex.Store({\n          state: { license: activeLicense(), permissions: activePermissions() },\n          getters: license.getters,\n          mutations: license.mutations\n        })\n      })\n\n      it('should return the license when the license getter is called', () => {\n        expect(store.getters.license).toStrictEqual(activeLicense())\n      })\n\n      it('should return true if there is a license when the hasLicense getter is called', () => {\n        expect(store.getters.hasLicense).toBe(true)\n      })\n\n      it('should return permissions when the permissions getter is called', () => {\n        expect(store.getters.permissions).toStrictEqual(activePermissions())\n      })\n\n      it('should return the current planType when the planType getter is called with no parameters', () => {\n        expect(store.getters.planType()).toBe('SELF_SERVE')\n      })\n      it('should return true if the planType is equal to the parameter', () => {\n        expect(store.getters.planType('SELF_SERVE')).toBe(true)\n      })\n\n      it('should return false when the hasPermission getter is called with no parameters', () => {\n        expect(store.getters.hasPermission()).toBe(false)\n      })\n\n      it('should return true when the hasPermission getter is called with parameters', () => {\n        expect(store.getters.hasPermission('read', 'flow')).toBe(true)\n      })\n    })\n\n    describe('permissions in Server', () => {\n      let store\n\n      beforeEach(() => {\n        process.env.VUE_APP_BACKEND = 'SERVER'\n        const license = require('@/store/license').default\n        store = new Vuex.Store({\n          state: license.state,\n          getters: license.getters,\n          mutations: license.mutations\n        })\n      })\n\n      it('should return true when the hasPermission getter is called with any args', () => {\n        expect(process.env.VUE_APP_BACKEND).toBe('SERVER')\n        expect(store.getters.hasPermission('read', 'flow')).toBe(true)\n        expect(store.getters.hasPermission('foo', 'bar')).toBe(true)\n      })\n    })\n  })\n\n  describe('Mutations', () => {\n    let store\n\n    beforeEach(() => {\n      store = new Vuex.Store({\n        state: initialLicenseState(),\n        getters: license.getters,\n        mutations: license.mutations\n      })\n    })\n\n    describe('setLicense', () => {\n      it('should set the license', () => {\n        expect(store.getters.hasLicense).toBe(false)\n\n        store.commit('setLicense', activeLicense())\n\n        expect(store.getters.hasLicense).toBe(true)\n        expect(store.getters.license).toStrictEqual(activeLicense())\n      })\n    })\n\n    describe('unsetLicense', () => {\n      it('should remove the current license', () => {\n        store.commit('setLicense', activeLicense())\n\n        expect(store.getters.hasLicense).toBe(true)\n\n        store.commit('unsetLicense')\n\n        expect(store.getters.hasLicense).toBe(false)\n        expect(store.getters.license).toEqual(initialLicenseState().license)\n      })\n    })\n\n    describe('setPermissions', () => {\n      it('should set permissions', () => {\n        expect(store.state.permissions).toBe(null)\n\n        store.commit('setPermissions', activePermissions())\n\n        expect(store.state.permissions).toStrictEqual(activePermissions())\n      })\n    })\n\n    describe('unsetPermissions', () => {\n      it('should remove the current permissions', () => {\n        store.commit('setPermissions', activePermissions())\n\n        expect(store.getters.permissions).toStrictEqual(activePermissions())\n\n        store.commit('unsetPermissions')\n        expect(store.getters.permissions).toEqual(null)\n      })\n    })\n  })\n\n  describe('actions', () => {\n    describe('getLicense - no query error', () => {\n      let store\n\n      beforeEach(() => {\n        mockerror = false\n        store = new Vuex.Store({\n          state: initialLicenseState(),\n          getters: license.getters,\n          mutations: license.mutations,\n          actions: license.actions\n        })\n      })\n      it('should set new license data', async () => {\n        await store.dispatch('getLicense')\n        expect(store.getters.hasLicense).toBe(true)\n        expect(store.getters.license).toEqual({})\n      })\n      it('should set permissions', async () => {\n        await store.dispatch('getLicense')\n        expect(store.getters.permissions).toEqual({})\n      })\n    })\n\n    describe('getLicense - with query error', () => {\n      let store\n\n      beforeEach(() => {\n        mockerror = true\n        store = new Vuex.Store({\n          state: initialLicenseState(),\n          getters: license.getters,\n          mutations: license.mutations,\n          actions: license.actions\n        })\n      })\n\n      it('should not set license data', async () => {\n        await store.dispatch('getLicense')\n        expect(store.getters.hasLicense).toBe(false)\n        expect(store.getters.license).toEqual(null)\n      })\n      it('should not set permissions', async () => {\n        await store.dispatch('getLicense')\n        expect(store.getters.permissions).toEqual(null)\n      })\n      // it('should call logRocket', async () => {\n      //   await store.dispatch('getLicense')\n      //   expect(LogRocket.captureException).toHaveBeenCalled()\n      // })\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/store/mockTokens.js",
    "content": "const MOCK_AUTHORIZATION_TOKEN =\n  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiYXdkYXdkYWRhLTQ5NDItNDhhNS04YzY2LWFkYXdkYWRhZCIsInRlbmFudF9pZCI6ImF3ZGF3ZGFkLWQ1NzAtNGYwYy05MTFkLWRjYWFiNWNlYzNkMCIsInJvbGUiOiJURU5BTlRfQURNSU4iLCJpYXQiOjE1Njg4NDAyODQsImV4cCI6MTU2ODg0MDI5OSwianRpIjoiMThiNDRhMTgtNTU2Yy00M2YzLTkxOWEtZDAwOWIwNDIzOTA3IiwiaXNzIjoiUHJlZmVjdCBDbG91ZCIsImF1ZCI6IlByZWZlY3QgQ2xvdWQgQVBJIC0gREVWIn0.3rI7CM3lT_u-8PPuTmR78ZlPeRZd4zRxsuIT9GYtr3A'\n\nconst MOCK_ID_TOKEN =\n  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNrbmFtZSI6InVzZXIiLCJuYW1lIjoidXNlciIsInBpY3R1cmUiOm51bGwsInVwZGF0ZWRfYXQiOiIyMDE5LTA5LTE4VDIwOjU4OjAyLjQ4NFoiLCJlbWFpbCI6InVzZXJAc29tZS5kb21haW4iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6Ly91bml2ZXJzYWwucHJlZmVjdC5pby8iLCJzdWIiOiJhdXRoMHw1ZDUxOWVhYmIyYTZlOTBkYWYwYTMyNDIiLCJhdWQiOiJZWk1SQWx1T3hWYzY5RE9nOXFkbk4tV18ydExnbGd5bSIsImlhdCI6MTU2ODg0MDI4NCwiZXhwIjoxOTMzOTU0MDk5LCJub25jZSI6IkctSVgxY0lvSlNwUXNUZnpCUnpRdzVTUGowUE5yeGxnSnpBSTFNWVlKeW0ifQ.zN_8BiuKrRttJ6sds-Gize9jr8oG6ck7bd0E97QF1wQ'\n\nconst MOCK_ID_TOKEN_2 =\n  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNrbmFtZSI6InVzZXIiLCJuYW1lIjoidXNlciIsInBpY3R1cmUiOiJodHRwczovL2p3dC5pby9pbWcvcGljX2xvZ28uc3ZnIiwidXBkYXRlZF9hdCI6IjIwMTktMDktMThUMjA6NTg6MDIuNDg0WiIsImVtYWlsIjoidXNlckBzb21lLmRvbWFpbiIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJpc3MiOiJodHRwczovL3VuaXZlcnNhbC5wcmVmZWN0LmlvLyIsInN1YiI6ImF1dGgwfDVkNTE5ZWFiYjJhNmU5MGRhZjBhMzI0MiIsImF1ZCI6IllaTVJBbHVPeFZjNjlET2c5cWRuTi1XXzJ0TGdsZ3ltIiwiaWF0IjoxNTY4ODQwMjg0LCJleHAiOjE5MzM5NTQwOTksIm5vbmNlIjoiRy1JWDFjSW9KU3BRc1RmekJSelF3NVNQajBQTnJ4bGdKekFJMU1ZWUp5bSJ9.dF8Vrje0Gkl0bxRlCU8qwQ9nUum-NY9hHWpSJ9yrWMI'\n\nconst MOCK_REFRESH_TOKEN =\n  'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhY2Nlc3NfdG9rZW5faWQiOiIxOGI0NGExOC01NTZjLTQzZjMtOTE5YS1kMDA5YjA0MjM5MDciLCJyb2xlIjoiUkVGUkVTSCIsImlhdCI6MTU2ODg0MDI4NSwiZXhwIjoxNTY5NDQwMjg0LCJqdGkiOiJlY2JiZTQxMy01ZTc4LTRjNzMtYjk3Ni0xYmEyYTE0YTc2OTgiLCJpc3MiOiJQcmVmZWN0IENsb3VkIiwiYXVkIjoiUHJlZmVjdCBDbG91ZCBBUEkgLSBERVYifQ.lTttZvW0uPMIkkaFrsGqmd25NUkkJP69PLwY-_Oky5VMptSVonoijwQXp0iXuzIfiJK27fwwLjbRtjAhH0c4Ns4FrzowozrP4U3TJbK0gBPbxqLSHQe5QBXCvTW5Pu_MVZAjU27Vw5ePQkkfDkoNJvIQ_Boce-uwU_oXagYZtEvprUcmSbvyz1G8Nmd9URlPYqiwpoUiywR1_fJGL3E6X9sa6Jbl8mMbiaL6ybFW_N9IPCIE2KZFYxhyYXNha_UmPqk_zQWRM8Xt4Ze-e2ePzoHjKwIugHgjv0o7CWHJwJEGM5rDbBIX91klfBpmpFchW_tCH34nH-5BsyfgR9wtaQ'\n\nconst MOCK_PREFECT_AUTH_PAYLOAD = {\n  access_token: MOCK_AUTHORIZATION_TOKEN,\n  refresh_token: MOCK_REFRESH_TOKEN,\n  expires_at: '2019-11-28T05:52:27.377857+00:00'\n}\n\nexport {\n  MOCK_AUTHORIZATION_TOKEN,\n  MOCK_ID_TOKEN,\n  MOCK_ID_TOKEN_2,\n  MOCK_REFRESH_TOKEN,\n  MOCK_PREFECT_AUTH_PAYLOAD\n}\n"
  },
  {
    "path": "tests/unit/store/refresh.spec.js",
    "content": "import refresh from '@/store/refresh'\nimport { createLocalVue } from '@vue/test-utils'\nimport Vuex from 'vuex'\n\nconst localVue = createLocalVue()\nlocalVue.use(Vuex)\n\ndescribe('Refresh Vuex Module', () => {\n  const initialState = () => {\n    return {\n      componentKey: 0\n    }\n  }\n\n  describe('State', () => {\n    it('should be initally be set to 0', () => {\n      const state = refresh.state\n      expect(state.componentKey).toBe(0)\n    })\n  })\n\n  describe('getters', () => {\n    let store\n    store = new Vuex.Store({\n      state: initialState(),\n      getters: refresh.getters,\n      mutations: refresh.mutations\n    })\n    test('the componentKey getter returns 0 in intial state', () => {\n      expect(store.getters.componentKey).toBe(0)\n    })\n  })\n\n  describe('mutations', () => {\n    let store\n    store = new Vuex.Store({\n      state: initialState(),\n      getters: refresh.getters,\n      mutations: refresh.mutations\n    })\n    test('the add mutation increase the componentKey by 1', () => {\n      expect(store.getters.componentKey).toBe(0)\n      store.commit('add')\n      expect(store.getters.componentKey).toBe(1)\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/store/sidenav.spec.js",
    "content": "import sideNav from '@/store/sideNav'\nimport { createLocalVue } from '@vue/test-utils'\nimport Vuex from 'vuex'\n\nconst localVue = createLocalVue()\nlocalVue.use(Vuex)\n\ndescribe('sideNav Vuex Module', () => {\n  const initialState = () => {\n    return {\n      open: false\n    }\n  }\n  const openState = () => {\n    return {\n      open: true\n    }\n  }\n\n  describe('State', () => {\n    it('should be initally set to false', () => {\n      const state = sideNav.state\n      expect(state.open).toBe(false)\n    })\n  })\n  describe('getters', () => {\n    let store\n    store = new Vuex.Store({\n      state: initialState(),\n      getters: sideNav.getters,\n      mutations: sideNav.mutations\n    })\n\n    it('isOpen should return false in initialState', () => {\n      expect(store.getters.isOpen).toBe(store.state.open)\n    })\n\n    store = new Vuex.Store({\n      state: openState(),\n      getters: sideNav.getters,\n      mutations: sideNav.mutations\n    })\n\n    it('isOpen should return true in openState', () => {\n      expect(store.getters.isOpen).toBe(store.state.open)\n    })\n  })\n\n  describe('Mutations', () => {\n    let store\n\n    beforeEach(() => {\n      store = new Vuex.Store({\n        state: initialState(),\n        getters: sideNav.getters,\n        actions: sideNav.actions,\n        mutations: sideNav.mutations\n      })\n    })\n    describe('open', () => {\n      it('should set open to true', () => {\n        //making sure isOpen is set to false before we call 'open'\n        store.commit('close')\n        expect(store.getters['isOpen']).toBe(false)\n        store.commit('open')\n        expect(store.getters['isOpen']).toBe(true)\n      })\n      it('leave open as true', () => {\n        //making sure isOpen is true to check calling 'open' doesn't change state\n        store.commit('open')\n        expect(store.getters['isOpen']).toBe(true)\n        store.commit('open')\n        expect(store.getters['isOpen']).toBe(true)\n      })\n    })\n    describe('close', () => {\n      it('should set open to false', () => {\n        //making sure isOpen is set to true before we call 'close'\n        store.commit('open')\n        expect(store.getters['isOpen']).toBe(true)\n        store.commit('close')\n        expect(store.getters['isOpen']).toBe(false)\n      })\n      it('should leave open as false', () => {\n        //making sure isOpen is false to check calling 'close' doesn't change state\n        store.commit('close')\n        expect(store.getters['isOpen']).toBe(false)\n        store.commit('close')\n        expect(store.getters['isOpen']).toBe(false)\n      })\n    })\n    describe('toggle', () => {\n      it('should switch to the opposite state', () => {\n        //making sure toggle changes state irrespective of what isOpen is initially set to\n        expect(store.getters['isOpen']).toBe(false)\n        store.commit('toggle')\n        expect(store.getters['isOpen']).toBe(true)\n        store.commit('toggle')\n        expect(store.getters['isOpen']).toBe(false)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/store/tenant.spec.js",
    "content": "jest.mock('@/auth/index.js')\n\nimport tenant from '@/store/tenant'\nimport { createLocalVue } from '@vue/test-utils'\nimport Vuex from 'vuex'\n\nconst localVue = createLocalVue()\nlocalVue.use(Vuex)\n\njest.mock('@/middleware/prefectAuth', () => {\n  return {\n    prefectTenants: jest.fn(),\n    prefectRefresh: jest.fn()\n  }\n})\nimport { prefectTenants } from '@/middleware/prefectAuth'\n\njest.mock(\n  '@/graphql/Tenant/tenant-token.gql',\n  () => 'tenant token mutation string'\n)\n\nconst mockUpdate = jest.fn()\n\njest.mock('@/vue-apollo', () => {\n  return {\n    fallbackApolloClient: {\n      mutate: settings => {\n        mockUpdate(settings.variables.settings)\n        return { data: { tenant: 1 } }\n      }\n    }\n  }\n})\n\njest.mock(\n  '@/graphql/Tenant/membership.gql',\n  () => 'tenant membership query string'\n)\njest.mock('@/graphql/Mutations/update-tenant-settings.gql', () => 'gql string')\n\ndescribe('tenant Vuex Module', () => {\n  const initialTenantState = () => {\n    return {\n      defaultTenant: null,\n      tenant: {\n        id: null,\n        name: null,\n        info: null,\n        slug: null,\n        role: null,\n        settings: {},\n        prefectAdminSettings: {},\n        licenses: [],\n        stripe_customer: null\n      },\n      tenantIsSet: false,\n      tenants: []\n    }\n  }\n\n  const loggedinTenantState = () => {\n    return {\n      defaultTenant: { name: 'TestTenant', slug: 'test', id: 'XXXXXXXXXX' },\n      tenant: {\n        id: 'd38b31a7-d570-4f0c-911d-dcaab5cec3d0',\n        name: 'Test Technologies Inc.',\n        info: null,\n        slug: 'test',\n        role: 'TENANT_ADMIN',\n        settings: { teamNamed: true, agreedToLicense: false },\n        prefectAdminSettings: {},\n        licenses: [{ active: true, product: 'Prefect Cloud Platform' }]\n      },\n      tenantIsSet: true,\n      tenants: [\n        { name: 'TestTenant', slug: 'test', id: 'XXXXXXXXXX' },\n        { name: 'TestTenant2', slug: 'testy', id: 'YYYYYYYYY' },\n        {\n          id: 'd38b31a7-d570-4f0c-911d-dcaab5cec3d0',\n          name: 'Test Technologies Inc.',\n          info: null,\n          slug: 'test',\n          role: 'TENANT_ADMIN',\n          settings: { teamNamed: true, agreedToLicense: false },\n          prefectAdminSettings: {},\n          licenses: [{ active: true, product: 'Prefect Cloud Platform' }]\n        }\n      ]\n    }\n  }\n\n  describe('State', () => {\n    it('should hold tenant info)', () => {\n      const state = tenant.state\n      expect(state.defaultTenant).toBe(null)\n      expect(state.tenant.id).toBe(null)\n      expect(state.tenant.name).toBe(null)\n      expect(state.tenant.info).toBe(null)\n      expect(state.tenant.slug).toBe(null)\n      expect(state.tenant.role).toBe(null)\n      expect(Object.keys(state.tenant.settings).length).toBe(0)\n      expect(state.tenant.licenses.length).toBe(0)\n      expect(state.tenantIsSet).toBe(false)\n      expect(state.tenants.length).toBe(0)\n    })\n  })\n\n  describe('getters', () => {\n    let store\n    beforeEach(() => {\n      store = new Vuex.Store({\n        state: loggedinTenantState(),\n        getters: tenant.getters,\n        actions: tenant.actions,\n        mutations: tenant.mutations\n      })\n    })\n    test('tenant getter should return logged in tenant details', () => {\n      expect(store.getters.tenant).toEqual(loggedinTenantState().tenant)\n    })\n    test('tenantIsSet getter should return true if the tenant is set', () => {\n      expect(store.getters.tenantIsSet).toBe(true)\n    })\n    test('defaultTenant getter should return the defaultTenant', () => {\n      expect(store.getters.defaultTenant.slug).toEqual('test')\n      expect(store.getters.defaultTenant).toEqual(\n        loggedinTenantState().defaultTenant\n      )\n    })\n    test('role getter should return the role', () => {\n      expect(store.getters.role).toEqual('TENANT_ADMIN')\n    })\n    test('tenants getter should return an array of tenant objects', () => {\n      expect(store.getters.tenants[0].slug).toEqual('test')\n      expect(store.getters.tenants).toEqual(loggedinTenantState().tenants)\n    })\n  })\n\n  describe('Mutations', () => {\n    let store\n\n    beforeEach(() => {\n      store = new Vuex.Store({\n        state: initialTenantState(),\n        getters: tenant.getters,\n        actions: tenant.actions,\n        mutations: tenant.mutations\n      })\n    })\n\n    describe('setDefaultTenant', () => {\n      it('should set the defaultTenant', () => {\n        const tenant = loggedinTenantState().tenant\n        store.commit('setDefaultTenant', tenant)\n        expect(store.getters['defaultTenant']).toEqual(\n          loggedinTenantState().tenant\n        )\n      })\n      it('should throw an error if passed an invalid tenant', () => {\n        expect(() => store.commit('setDefaultTenant', [1, 2, 3])).toThrow(\n          'passed invalid or empty tenant object'\n        )\n      })\n\n      it('should throw an error if passed no tenant', () => {\n        expect(() => store.commit('setDefaultTenant')).toThrow(\n          'passed invalid or empty tenant object'\n        )\n      })\n\n      it('should throw an error if passed an empty tenant', () => {\n        expect(() => store.commit('setDefaultTenant', {})).toThrow(\n          'passed invalid or empty tenant object'\n        )\n      })\n    })\n\n    describe('setTenant', () => {\n      it('should set tenantIsSet to true', () => {\n        store.commit('setTenant', loggedinTenantState().tenant)\n        expect(store.getters['tenantIsSet']).toBe(true)\n        expect(store.getters['tenant']).toEqual(loggedinTenantState().tenant)\n      })\n\n      it('should throw an error if given no tenant', () => {\n        store.commit('unsetTenant')\n        expect(() => store.commit('setTenant')).toThrow(\n          'passed invalid or empty tenant object'\n        )\n      })\n\n      it('should throw an error if given an empty tenant', () => {\n        store.commit('unsetTenant')\n        expect(() => store.commit('setTenant', {})).toThrow(\n          'passed invalid or empty tenant object'\n        )\n      })\n    })\n\n    describe('setTenants', () => {\n      it('should set the tenants array', () => {\n        const tenants = loggedinTenantState().tenants\n        store.commit('setTenants', tenants)\n        expect(store.getters['tenants'][0]).toEqual(tenants[0])\n      })\n\n      it('should throw an error if given no tenants array', () => {\n        store.commit('unsetTenants')\n        expect(() => store.commit('setTenants')).toThrow(\n          'passed invalid or empty tenant array'\n        )\n      })\n\n      it('should throw an error if given an empty tenants array', () => {\n        store.commit('unsetTenants')\n        expect(() => store.commit('setTenants', [])).toThrow(\n          'passed invalid or empty tenant array'\n        )\n      })\n    })\n\n    describe('unsetTenant', () => {\n      it('should set tenantIsSet to false', () => {\n        //Make sure store is in logged in state\n        store.commit('setTenant', loggedinTenantState().tenant)\n        expect(store.getters['tenant']).toEqual(loggedinTenantState().tenant)\n        store.commit('unsetTenant')\n        expect(store.getters['tenantIsSet']).toBe(false)\n        expect(store.getters['tenant']).toEqual(initialTenantState().tenant)\n      })\n    })\n\n    describe('unsetTenants', () => {\n      it('should set tenants to an empty array', () => {\n        //Make sure store is in logged in state\n        store.commit('setTenants', loggedinTenantState().tenants)\n        expect(store.getters['tenants']).toEqual(loggedinTenantState().tenants)\n        store.commit('unsetTenants')\n        expect(store.getters['tenants']).toEqual([])\n      })\n    })\n\n    describe('updateTenantSettings', () => {\n      it('should update the settings in the store and leave the rest of the tenant as is', () => {\n        //Make sure store is in logged in state\n        store.commit('setTenant', loggedinTenantState().tenant)\n        expect(store.getters['tenant']).toEqual(loggedinTenantState().tenant)\n        expect(store.getters['tenant'].settings.agreedToLicense).toEqual(false)\n        expect(store.getters['tenantIsSet']).toEqual(\n          loggedinTenantState().tenantIsSet\n        )\n        store.commit('updateTenantSettings', { agreedToLicense: true })\n        expect(store.getters['tenant']).toEqual({\n          ...loggedinTenantState().tenant,\n          settings: { agreedToLicense: true }\n        })\n      })\n      it('should throw an error message if no settings are passed', () => {\n        expect(() => store.commit('updateTenantSettings')).toThrow(\n          'passed invalid or empty settings object'\n        )\n      })\n    })\n  })\n\n  describe('actions', () => {\n    describe('getTenants - no query error', () => {\n      let store\n\n      beforeEach(() => {\n        store = new Vuex.Store({\n          state: initialTenantState(),\n          getters: tenant.getters,\n          mutations: tenant.mutations,\n          actions: tenant.actions\n        })\n      })\n\n      it('should call the prefectTenants method', async () => {\n        await store.dispatch('getTenants')\n        expect(prefectTenants).toHaveBeenCalled()\n      })\n\n      it('should set tenants', async () => {\n        const tenantsArray = [{ name: 'boo', id: '12345' }]\n        prefectTenants.mockReturnValueOnce(tenantsArray)\n        await store.dispatch('getTenants')\n        expect(store.getters.tenants).toEqual(tenantsArray)\n      })\n\n      it('should return tenants', async () => {\n        const tenantsArray = [{ name: 'boo', id: '12345' }]\n        prefectTenants.mockReturnValueOnce(tenantsArray)\n        const returnedTenants = await store.dispatch('getTenants')\n        expect(returnedTenants).toEqual([{ name: 'boo', id: '12345' }])\n      })\n    })\n\n    describe('setCurrentTenant - Server', () => {\n      let store\n\n      beforeEach(() => {\n        store = new Vuex.Store({\n          state: initialTenantState(),\n          getters: tenant.getters,\n          mutations: tenant.mutations,\n          actions: tenant.actions\n        })\n      })\n\n      it('should throw an error if no slug is provided', () => {\n        expect(store.dispatch('setCurrentTenant', false)).rejects.toThrow(\n          'No slug was provided when trying to set the current tenant'\n        )\n      })\n\n      it('should call getTenants if the passed tenant is not present in the store', async () => {\n        expect(store.getters.tenant.slug).toBe(null)\n        expect(store.getters.tenant.name).toBe(null)\n        expect(store.getters.tenant.id).toBe(null)\n        const tenantsArray = [\n          { name: 'boo', id: '12345', slug: 'team2' },\n          { name: 'anotherTenant', id: '45678' }\n        ]\n        prefectTenants.mockReturnValueOnce(tenantsArray)\n        await store.dispatch('setCurrentTenant', 'team2')\n        expect(store.getters.tenant.slug).toEqual('team2')\n        expect(store.getters.tenant.name).toEqual('boo')\n        expect(store.getters.tenant.id).toEqual('12345')\n      })\n\n      it('should throw an error if the requested tenant does not exist', async () => {\n        expect(store.getters.tenant.slug).toBe(null)\n        const tenantsArray = [{ name: 'boo', id: '12345', slug: 'team2' }]\n        prefectTenants.mockReturnValueOnce(tenantsArray)\n        expect(store.dispatch('setCurrentTenant', 'team3')).rejects.toThrow(\n          \"Error: Unable to set current tenant: tenant doesn't exist\"\n        )\n      })\n\n      it('should set the tenant role to TENANT_ADMIN', async () => {\n        //All tenants need an admin - for tenants in server with only one member, that member's role should be admin\n        expect(store.getters.tenant.slug).toBe(null)\n        const tenantsArray = [{ name: 'boo', id: '12345', slug: 'team2' }]\n        prefectTenants.mockReturnValueOnce(tenantsArray)\n        await store.dispatch('setCurrentTenant', 'team2')\n        expect(store.getters.role).toEqual('TENANT_ADMIN')\n      })\n\n      it('should return the tenant', async () => {\n        const tenantsArray = [{ name: 'boo', id: '12345', slug: 'team2' }]\n        prefectTenants.mockReturnValueOnce(tenantsArray)\n        expect(await store.dispatch('setCurrentTenant', 'team2')).toEqual({\n          id: '12345',\n          name: 'boo',\n          role: 'TENANT_ADMIN',\n          slug: 'team2'\n        })\n      })\n    })\n\n    describe('setCurrentTenant - Cloud', () => {\n      let store\n\n      beforeEach(() => {\n        tenant.actions['auth/updateAuthorization'] = jest.fn()\n        tenant.actions['license/getLicense'] = jest.fn()\n        store = new Vuex.Store({\n          state: initialTenantState(),\n          getters: {\n            ...tenant.getters,\n            'api/isCloud': () => true,\n            'user/memberships': () => [\n              { tenant: { id: '12345' }, role_detail: { name: 'USER' } },\n              {\n                tenant: { id: '45678' },\n                role_detail: { name: 'TENANT_ADMIN' }\n              },\n              {\n                tenant: { id: '9101112' },\n                role_detail: { name: 'READ_ONLY_USER' }\n              }\n            ]\n          },\n          mutations: tenant.mutations,\n          actions: tenant.actions\n        })\n      })\n\n      it('should set the tenant role according to user memberships - USER role', async () => {\n        expect(store.getters.tenant.slug).toBe(null)\n        const tenantsArray = [\n          { name: 'boo', id: '12345', slug: 'team2' },\n          { name: 'anotherTeam', id: '45678', slug: 'team3' }\n        ]\n        prefectTenants.mockReturnValueOnce(tenantsArray)\n        await store.dispatch('setCurrentTenant', 'team2')\n        expect(store.getters.role).toEqual('USER')\n      })\n\n      it('should set the tenant role according to user memberships - TENANT_ADMIN role', async () => {\n        expect(store.getters.tenant.slug).toBe(null)\n        const tenantsArray = [\n          { name: 'boo', id: '12345', slug: 'team2' },\n          { name: 'anotherTeam', id: '45678', slug: 'team3' },\n          { name: 'aReadOnlyTeam', id: '9101112', slug: 'team1' }\n        ]\n        prefectTenants.mockReturnValueOnce(tenantsArray)\n        await store.dispatch('setCurrentTenant', 'team1')\n\n        expect(store.getters.role).toEqual('READ_ONLY_USER')\n      })\n    })\n\n    describe('updateTenantSettings', () => {\n      let store\n\n      beforeEach(() => {\n        tenant.actions.getTenants = jest.fn()\n        store = new Vuex.Store({\n          state: initialTenantState(),\n          getters: tenant.getters,\n          mutations: tenant.mutations,\n          actions: tenant.actions\n        })\n      })\n\n      it('should throw an error if no settings are given', async () => {\n        expect(store.dispatch('updateTenantSettings')).rejects.toThrow(\n          'Error: passed invalid or empty settings object'\n        )\n      })\n\n      it('should call the getTenants action when settings are given', async () => {\n        await store.dispatch('updateTenantSettings', { name: 'Tom' })\n        expect(tenant.actions.getTenants).toBeCalled()\n      })\n\n      it('should call the update tenant settings mutation when settings are given', async () => {\n        await store.dispatch('updateTenantSettings', { name: 'Tom' })\n        expect(mockUpdate).toBeCalledWith({ name: 'Tom' })\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "tests/unit/store/user.spec.js",
    "content": "import user from '@/store/user'\nimport { createLocalVue } from '@vue/test-utils'\nimport Vuex from 'vuex'\n\nconst localVue = createLocalVue()\nlocalVue.use(Vuex)\n\njest.mock('@/middleware/prefectAuth', () => {\n  null\n})\n\njest.mock('@/middleware/prefectAuth', () => {\n  return {\n    prefectUser: jest.fn()\n  }\n})\nimport { prefectUser } from '@/middleware/prefectAuth'\n\ndescribe('user Vuex Module', () => {\n  const initialState = () => {\n    return {\n      user: {\n        id: null,\n        email: null,\n        username: null,\n        default_membership_id: null,\n        memberships: null,\n        first_name: '',\n        last_name: '',\n        settings: {\n          timezone: ''\n        }\n      },\n      oktaUser: {\n        name: null,\n        email: null,\n        picture: null\n      },\n      userIsSet: false\n    }\n  }\n\n  const userState = () => {\n    return {\n      user: {\n        id: '12345',\n        email: 'test@test.com',\n        username: 'test123',\n        default_membership_id: '5678',\n        memberships: [\n          {\n            id: '1112131415',\n            role: 'USER',\n            tenant: { id: 'yyyyy', name: 'test2', slug: 'test2' }\n          },\n          {\n            id: '5678',\n            role: 'TENANT_ADMIN',\n            tenant: { id: 'xxx', name: 'test1', slug: 'test1' }\n          }\n        ],\n        first_name: 'first',\n        last_name: 'last',\n        settings: {\n          timezone: 'utc',\n          isDark: false\n        }\n      },\n      oktaUser: {\n        name: 'testtest',\n        email: 'test@test.com',\n        picture: 'linktopicture'\n      },\n      userIsSet: true\n    }\n  }\n\n  describe('State', () => {\n    test('userIsSet should initally be set to false', () => {\n      const state = user.state\n      expect(state.userIsSet).toBe(false)\n    })\n    test('user details should initally be empty', () => {\n      const state = user.state\n      expect(state.user).toEqual({\n        id: null,\n        email: null,\n        username: null,\n        default_membership_id: null,\n        memberships: null,\n        first_name: '',\n        last_name: '',\n        settings: {\n          timezone: '',\n          isDark: false\n        }\n      })\n    })\n    test('oktaUser details should initally be empty', () => {\n      const state = user.state\n      expect(state.oktaUser).toEqual({\n        name: null,\n        email: null,\n        picture: null\n      })\n    })\n  })\n\n  describe('getters', () => {\n    let store\n    store = new Vuex.Store({\n      state: userState(),\n      getters: user.getters,\n      mutations: user.mutations\n    })\n    test('user should return user details', () => {\n      expect(store.getters.user).toBe(store.state.user)\n    })\n    test('userIsSet should initially return false', () => {\n      expect(store.getters.userIsSet).toBe(true)\n    })\n    test('defaultMembershipId should return membership id if user membership id is set', () => {\n      expect(store.getters.defaultMembershipId).toEqual('5678')\n    })\n    test('oktaUser should return oktaUser details', () => {\n      expect(store.getters.oktaUser).toEqual({\n        name: 'testtest',\n        email: 'test@test.com',\n        picture: 'linktopicture'\n      })\n    })\n    test('timezone should return user timezone', () => {\n      expect(store.getters.timezone).toEqual('utc')\n    })\n    test('settings should return user settings', () => {\n      expect(store.getters.settings).toEqual({\n        timezone: 'utc',\n        isDark: false\n      })\n    })\n    test('firstName should return user first name', () => {\n      expect(store.getters.firstName).toEqual('first')\n    })\n    test('lastName should return user last name', () => {\n      expect(store.getters.lastName).toEqual('last')\n    })\n    test('memberships should return memberships array', () => {\n      expect(store.getters.memberships).toEqual(userState().user.memberships)\n    })\n  })\n\n  describe('mutations', () => {\n    let store\n    beforeEach(() => {\n      store = new Vuex.Store({\n        state: initialState(),\n        getters: user.getters,\n        mutations: user.mutations\n      })\n    })\n\n    test('user mutation sets the user and updates user is set', () => {\n      expect(store.getters.user).toEqual(initialState().user)\n      expect(store.getters.userIsSet).toBe(false)\n      store.commit('user', userState().user)\n      expect(store.getters.user).toEqual(userState().user)\n      expect(store.getters.user.email).toEqual('test@test.com')\n      expect(store.getters.userIsSet).toBe(true)\n    })\n    test('setOktaUser mutation sets the okta user', () => {\n      expect(store.getters.oktaUser).toEqual(initialState().oktaUser)\n      store.commit('setOktaUser', userState().oktaUser)\n      expect(store.getters.oktaUser).toEqual(userState().oktaUser)\n      expect(store.getters.oktaUser.email).toEqual('test@test.com')\n    })\n    test('setUsetSettings mutation sets the user settings', () => {\n      expect(store.getters.user).toEqual(initialState().user)\n      store.commit('setUserSettings', userState().user.settings)\n      expect(store.getters.settings).toEqual(userState().user.settings)\n      expect(store.getters.timezone).toEqual('utc')\n      expect(store.getters.isDark).toEqual(false)\n    })\n    test('unsetUser mutation un-sets the user and updates user is set', () => {\n      store.commit('user', userState().user)\n      expect(store.getters.user).toEqual(userState().user)\n      expect(store.getters.user.email).toEqual('test@test.com')\n      expect(store.getters.userIsSet).toBe(true)\n      store.commit('unsetUser')\n      expect(store.getters.user).toEqual(initialState().user)\n      expect(store.getters.userIsSet).toBe(false)\n    })\n    test('unsetOktaUser mutation un-sets the okta user', () => {\n      store.commit('setOktaUser', userState().oktaUser)\n      expect(store.getters.oktaUser).toEqual(userState().oktaUser)\n      expect(store.getters.oktaUser.email).toEqual('test@test.com')\n      store.commit('unsetOktaUser')\n      expect(store.getters.oktaUser).toEqual(initialState().oktaUser)\n      expect(store.getters.oktaUser.email).toEqual(null)\n    })\n    test('setUserDefaultMembershipId mutation sets the default membership', () => {\n      expect(store.getters.defaultMembershipId).toEqual(null)\n      store.commit('setUserDefaultMembershipId', '5678')\n      expect(store.getters.defaultMembershipId).toEqual('5678')\n    })\n  })\n\n  describe('actions', () => {\n    describe('setDefaultTenant action', () => {\n      let store\n      beforeEach(() => {\n        // Mock the mutations and actions from other stores\n        // that we don't want to\n        // test here\n        user.mutations['tenant/setDefaultTenant'] = jest.fn()\n        store = new Vuex.Store({\n          state: userState(),\n          getters: {\n            ...user.getters,\n            'tenant/tenants': () => [\n              { id: '3333', name: 'test33', slug: 'test33' }\n            ]\n          },\n          mutations: user.mutations,\n          actions: user.actions\n        })\n      })\n      it('sets the default tenant according to the default membership id if available', () => {\n        expect(store.getters.defaultMembershipId).toEqual('5678')\n        store.dispatch('setDefaultTenant')\n        expect(\n          //First argument passed is the user state object, second is the default tenant to set\n          user.mutations['tenant/setDefaultTenant'].mock.calls[0][1]\n        ).toEqual({\n          id: 'xxx',\n          name: 'test1',\n          slug: 'test1'\n        })\n      })\n      it('sets the default tenant according to the first tenant in the memberships array if there is no tenant matching the default membership id', async () => {\n        expect(store.getters.defaultMembershipId).toEqual('5678')\n        store.commit('setUserDefaultMembershipId', '2222')\n        expect(store.getters.defaultMembershipId).toEqual('2222')\n        await store.dispatch('setDefaultTenant')\n        expect(\n          //First argument passed is the user state, second is the default tenant to set\n          user.mutations['tenant/setDefaultTenant'].mock.calls[0][1]\n        ).toEqual({ id: 'yyyyy', name: 'test2', slug: 'test2' })\n      })\n      it('sets the default tenant according to the first tenant in the tenants store tenants array if there are no memberships', async () => {\n        store.commit('unsetUser')\n        expect(store.getters.memberships).toEqual(null)\n        await store.dispatch('setDefaultTenant')\n        expect(\n          //First argument passed is the user state, second is the default tenant to set\n          user.mutations['tenant/setDefaultTenant'].mock.calls[0][1]\n        ).toEqual({ id: '3333', name: 'test33', slug: 'test33' })\n      })\n    })\n\n    describe('getUser action', () => {\n      let store\n      beforeEach(() => {\n        // Mock the mutations and actions from other stores\n        // that we don't want to\n        // test here\n        user.mutations['tenant/setDefaultTenant'] = jest.fn()\n        store = new Vuex.Store({\n          state: initialState(),\n          getters: user.getters,\n          mutations: user.mutations,\n          actions: user.actions\n        })\n      })\n      it('calls prefectUser', async () => {\n        await store.dispatch('getUser')\n        expect(prefectUser).toBeCalled()\n      })\n      it('set the user', async () => {\n        expect(store.getters.user).toEqual(initialState().user)\n        prefectUser.mockReturnValueOnce(userState().user)\n        await store.dispatch('getUser')\n        expect(store.getters.user).toEqual(userState().user)\n      })\n      it('calls setDefaultTenant', async () => {\n        await store.dispatch('getUser')\n        expect(user.mutations['tenant/setDefaultTenant']).toBeCalled()\n      })\n      it('returns the user', async () => {\n        prefectUser.mockReturnValueOnce(userState().user)\n        const returnedUser = await store.dispatch('getUser')\n        expect(returnedUser).toEqual(userState().user)\n      })\n    })\n  })\n})\n"
  },
  {
    "path": "vue.config.js",
    "content": "const WorkerPlugin = require('worker-plugin')\nconst webpack = require('webpack')\n\nmodule.exports = {\n  productionSourceMap: false,\n  chainWebpack: config => {\n    config.module\n      .rule('md')\n      .test(/\\.md/)\n      .use('html-loader')\n      .loader('html-loader')\n      .tap(options => {\n        return { ...options, minimize: false }\n      })\n      .end()\n\n    config.resolve.symlinks(false)\n\n    config.output.globalObject('this')\n\n    config.module\n      .rule('flow')\n      .test(/\\.flow$/)\n      .use('ignore-loader')\n      .loader('ignore-loader')\n      .end()\n\n    // This optimization comes from a long-standing bug with the terser webpack plugin\n    // documented here: https://github.com/webpack-contrib/terser-webpack-plugin/issues/143,\n    // and here: https://github.com/terser/terser/issues/571,\n    // and here: https://github.com/webpack-contrib/terser-webpack-plugin/issues/202\n    config.optimization.minimizer('terser').tap(args => {\n      args[0].terserOptions = {\n        terserOptions: {\n          parse: {\n            ecma: 8\n          },\n          compress: {\n            ecma: 5,\n            warnings: false,\n            comparisons: false,\n            inline: 2,\n            drop_console: true\n          },\n          mangle: {\n            safari10: true\n          },\n          output: {\n            ecma: 5,\n            comments: false,\n            ascii_only: true\n          }\n        },\n        parallel: 4, // This should be changed if we modify the resource class of the Circle jobs running the build step\n        cache: true,\n        sourceMap: false,\n        extractComments: false\n      }\n      return args\n    })\n  },\n\n  configureWebpack: {\n    optimization: {\n      splitChunks: {\n        chunks: 'all',\n        minSize: 30000,\n        maxSize: 1000000,\n        minChunks: 1,\n        maxAsyncRequests: 6,\n        maxInitialRequests: 4,\n        automaticNameDelimiter: '~',\n        cacheGroups: {\n          defaultVendors: {\n            test: /[\\\\/]node_modules[\\\\/]/,\n            priority: -10\n          },\n          default: {\n            minChunks: 2,\n            priority: -20,\n            reuseExistingChunk: true\n          }\n        }\n      }\n    },\n    plugins: [\n      new WorkerPlugin({ sharedWorker: true }),\n      new webpack.ContextReplacementPlugin(\n        /moment[/\\\\]locale$/,\n        /en-au|en-ca|en-us|en-mx/\n      )\n    ]\n  },\n\n  pluginOptions: {\n    lintStyleOnBuild: true,\n    stylelint: {},\n    apollo: {\n      lintGQL: true\n    },\n    webpackBundleAnalyzer: {\n      analyzerMode: 'disabled'\n      // you can uncomment this line, run npm build, this will generate dist/stats.json which can be viewed here\n      // https://chrisbateman.github.io/webpack-visualizer/\n      //generateStatsFile: true\n    }\n  },\n\n  // Adding this package specically because\n  // the source has 2 nullish coalscent references\n  // that babel isn't transpiling correctly otherwise\n  transpileDependencies: [\n    '@d3fc/d3fc-axis',\n    'graphql-language-service-interface',\n    'graphql-language-service-parser',\n    'graphql-language-service'\n  ]\n}\n"
  }
]