[
  {
    "path": ".github/workflows/scheduled-data-update.yml",
    "content": "# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node\n# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions\n\nname: Scheduled data update\n\non:\n  workflow_dispatch: null\n  schedule:\n    # * is a special character in YAML so you have to quote this string\n    - cron: \"30 10 * * *\"\n  # push:\n  #   branches:\n  #     - master\n\njobs:\n  build:\n    name: Update data on schedule\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v2\n      - uses: actions/setup-node@v1\n        with:\n          node-version: \"18.x\"\n      - name: Restore cache\n        uses: actions/cache@v2\n        with:\n          path: |\n            node_modules\n            */*/node_modules\n          key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }}\n      - name: Install\n        run: yarn install\n      - name: Run update job script\n        run: export ACCESS_TOKEN_GITHUB=${{ secrets.ACCESS_TOKEN_GITHUB }} && export SLACK_WEBHOOK_URL=${{ secrets.SLACK_WEBHOOK_URL }} && sh ./update-copy.sh\n      - name: Commit changes\n        uses: EndBug/add-and-commit@v7 # You can change this to use a specific version\n        with:\n          author_name: Data Update Worker\n          author_email: igor@cube.dev\n          cwd: \".\"\n          default_author: github_actor\n          message: \"chore(copy): update data on schedule\"\n          pull: \"--no-rebase\"\n          push: true\n\n      # - name: Build Next site\n      #   run: sh ./build-site.sh\n      # - name: Install Netlify CLI\n      #   run: npm install -g netlify-cli\n      # - name: Deploy to Netlify\n      #   run: netlify deploy --dir=out --prod\n      #   env:\n      #     NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# next.js\n/.next/\n/out/\n\n# production\n/build\n\n# misc\n.DS_Store\n*.pem\n\n# debug\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# local env files\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\n# vercel\n.vercel\n\n# Local Netlify folder\n# .netlify"
  },
  {
    "path": ".netlify/state.json",
    "content": "{\n\t\"siteId\": \"51f8094d-998a-424a-b471-6499f5bf2933\"\n}"
  },
  {
    "path": ".nvmrc",
    "content": "lts/*"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Cube Dev, Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<h1><a href='https://awesome.cube.dev'>awesome.cube.dev</a> — charts, data grids, maps, etc.</h1>\n\nChoose the best tool for your needs by type, framework, language, or license. Get started in an instant.\n\n<p align=\"center\"><img src='.github/screenshot.png'/></p>\n\nVisit [awesome.cube.dev](https://awesome.cube.dev) or suggest an [improvement](https://github.com/cube-js/awesome-tools/issues).\n"
  },
  {
    "path": "components/Button/Button.jsx",
    "content": "import styles from \"./Button.module.scss\";\nimport Link from \"next/link\";\n\nexport default function Button(props) {\n  return (\n    <Link href={props.href} legacyBehavior>\n      <a\n        type=\"button\"\n        role=\"button\"\n        {...props}\n        className={\n          props.className\n            ? `${props.className} ${styles.button}`\n            : styles.button\n        }\n      >\n        <span>{props.children}</span>\n      </a>\n    </Link>\n  );\n}\n"
  },
  {
    "path": "components/Button/Button.module.scss",
    "content": "@import \"/styles/variables\";\n\n.button {\n  font-family: CeraPro;\n  font-size: 20px;\n  // line-height: 25px;\n  text-align: center;\n  letter-spacing: 0.02em;\n  color: $purple-02;\n  border: 2px solid $purple-02;\n  padding: 8px 22px;\n  border-radius: 12px;\n  display: flex;\n  flex-direction: row;\n  justify-content: center;\n  align-items: center;\n  background: transparent;\n  cursor: pointer;\n  transition: background-color 0.3s ease-in-out, border-color 0.3s ease-in-out,\n    color 0.3s ease-in-out;\n\n  &:hover {\n    background: rgba(202, 201, 255, 0.5);\n    color: $purple-hover;\n    border-color: $purple-hover;\n  }\n\n  &:active {\n    background: rgba(202, 201, 255, 0.8);\n    color: $purple-press;\n    border-color: $purple-press;\n  }\n\n  &[disabled=\"disabled\"] {\n    user-select: none;\n    pointer-events: none;\n    cursor: not-allowed;\n    border-color: $dark-05;\n    color: $dark-05;\n  }\n}\n"
  },
  {
    "path": "components/Button/index.js",
    "content": "import Button from \"./Button\";\nexport default Button;\n"
  },
  {
    "path": "components/ButtonLanding/ButtonLanding.jsx",
    "content": "import * as React from 'react';\nimport { useEffect } from 'react';\nimport Link from 'next/link';\nimport classNames from 'classnames/bind';\n\nimport { useState } from 'react';\n\nimport styles from './ButtonLanding.module.css';\n\nconst cn = classNames.bind(styles);\nconst loader = (\n  <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"none\">\n    <path\n      d=\"M8 15a7 7 0 0 1-7-7 .5.5 0 1 1 1 0 6 6 0 0 0 3.7 5.5 6 6 0 0 0 6.6-1.2 6 6 0 0 0 0-8.6A6 6 0 0 0 8 2a.5.5 0 1 1 0-1 7 7 0 0 1 7 7 7 7 0 0 1-7 7Z\"\n      fill=\"currentColor\"\n      stroke=\"currentColor\"\n      strokeWidth=\".5\"\n    />\n  </svg>\n);\n\nexport const ButtonLanding = React.forwardRef(\n  (\n    {\n      appearance = 'light',\n      color = 'transparent',\n      variant = 'default',\n      type = 'button',\n      size = 'm',\n      disabled = false,\n      pseudoHover = false,\n      pseudoFocus = false,\n      pseudoActive = false,\n      isLoad = false,\n      className = '',\n      children,\n      href = '',\n      ...rest\n    },\n    ref\n  ) => {\n    const loaderAppearAnimationDuration = 700;\n\n    const classNames = cn('Button', `Button--appearance-${appearance}`, className, {\n      'Button--pink': color === 'pink',\n      'Button--purple': color === 'purple',\n      'Button--cherry': color === 'cherry',\n      'Button--transparent': color === 'transparent',\n      'Button--back': color === 'back',\n      'Button--size-s': size === 's',\n      'Button--size-m': size === 'm',\n      'Button--size-l': size === 'l',\n      'Button--variant-outline': variant === 'outline',\n      'Button--pseudoHover': pseudoHover,\n      'Button--pseudoFocus': pseudoFocus,\n      'Button--pseudoActive': pseudoActive,\n    });\n\n    const [isLoaderVisible, setIsLoaderVisible] = useState(isLoad);\n\n    useEffect(() => {\n      if (isLoad === false) {\n        setTimeout(() => {\n          setIsLoaderVisible(false);\n        }, loaderAppearAnimationDuration);\n      } else {\n        setIsLoaderVisible(true);\n      }\n    }, [isLoad]);\n\n    let prefix;\n    if (isLoad || isLoaderVisible) {\n      const prefixClassName = cn('Button__prefix', 'Button__prefix--loader', {\n        'Button__prefix--removing': isLoaderVisible !== isLoad && !isLoad,\n      });\n      prefix = <span className={prefixClassName}>{loader}</span>;\n    }\n\n    if (href) {\n      if (href.startsWith('/')) {\n        return (\n          <Link href={href} passHref legacyBehavior>\n            <a ref={ref} {...rest} className={classNames}>\n              {children}\n            </a>\n          </Link>\n        );\n      }\n      return (\n        <a ref={ref} {...rest} href={href} className={classNames}>\n          {children}\n        </a>\n      );\n    }\n\n    return (\n      <button\n        ref={ref}\n        {...rest}\n        className={classNames}\n        type={type}\n        disabled={disabled || isLoad}\n        style={{ '--loader-time': loaderAppearAnimationDuration + 'ms' }}\n      >\n        {prefix}\n        {children}\n      </button>\n    );\n  }\n);\n\nexport default ButtonLanding;\n"
  },
  {
    "path": "components/ButtonLanding/ButtonLanding.module.css",
    "content": ".Button {\n  --dark: hsl(240, 32%, 10%);\n  --dark_a70: rgba(15, 15, 35, 0.7);\n  --dark_01: var(--dark);\n  --dark_02: hsla(240, 14%, 23%);\n  --dark_03: hsl(240, 8%, 45%);\n  --dark_03_a50: hsl(240, 32%, 10%, 0.5);\n  --dark_02_a75: hsla(240, 32%, 10%, 0.75);\n  --dark_04: hsl(240, 9%, 69%);\n  --dark_04_a30: hsl(240, 32%, 10%, 0.3);\n  --dark_05_a12: hsl(240, 32%, 10%, 0.12);\n  --dark_05: hsla(240, 16%, 91%, 1);\n  --dark_06: hsl(240, 40%, 10%);\n\n  --dark_bg: hsl(240, 12%, 97%, 1);\n  --dark_bg_a04: hsla(240, 32%, 10%, 0.04);\n  --dark_bg_a08: hsla(240, 32%, 10%, 0.08);\n\n  --white: hsla(240, 0%, 100%, 1);\n  --white_a01: hsla(240, 0%, 100%, 0.1);\n  --white_a08: hsla(0, 0%, 100%, 0.08);\n  --white_a12: hsla(240, 0%, 100%, 0.12);\n  --white_a15: hsla(240, 0%, 100%, 0.15);\n  --white_a24: hsla(240, 0%, 100%, 0.24);\n\n  --gray_01: hsl(228, 6%, 31%, 1);\n  --gray_02: hsl(225, 4%, 39%, 1);\n\n  --purple: hsl(251, 94%, 66%, 1);\n  --purple_03: hsla(241, 94%, 84%, 1);\n  --purple_03_a60: hsl(241, 94%, 66%, 0.6);\n  --purple_04_a30: hsl(241, 94%, 66%, 0.3);\n  --purple_bg_02: hsl(240, 50%, 98%);\n  --purple_bg_a08: hsla(244, 94%, 66%, 0.08);\n  --purple_bright: hsl(251, 61%, 52%, 1);\n  --purple_a12: hsla(251, 94%, 66%, 0.12);\n\n  --pink: hsl(342, 69%, 53%, 1);\n  --pink_03_a60: hsl(342, 69%, 53%, 0.6);\n  --pink_04_a30: hsl(342, 69%, 53%, 0.3);\n  --pink_bg_a10: hsl(342, 69%, 53%, 0.1);\n  --pink_bright: hsl(342, 62%, 48%, 1);\n  --pink_bright_02: var(--pink_bright);\n\n  --cherry: var(--pink);\n  --cherry_dark: var(--pink_bright);\n\n  --white_a08_on_dark_02: #434353;\n  \n  --loader_time: 700ms;\n  --hover_transition: 0.2s;\n\n  transition: background-color var(--hover_transition), color var(--hover_transition),\n    box-shadow var(--hover_transition), opacity var(--loader_time);\n  font-family: inherit;\n  font-weight: 700;\n  border: none;\n  margin: 0;\n\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  text-decoration: none;\n}\n\n.Button:hover {\n  cursor: pointer;\n}\n\n.Button:disabled {\n  opacity: 0.4;\n  cursor: default;\n}\n\n/* transparent */\n\n.Button--transparent {\n  background-color: transparent;\n  color: var(--dark);\n}\n\n.Button--transparent.Button--variant-outline {\n  box-shadow: inset 0 0 0 1px var(--dark_05);\n}\n\n.Button--transparent.Button--variant-outline:hover,\n.Button--transparent.Button--variant-outline.Button--pseudoHover {\n  background-color: var(--dark_bg_a04);\n}\n\n.Button--transparent.Button--variant-outline:focus-visible,\n.Button--transparent.Button--variant-outline.Button--pseudoFocus {\n  box-shadow: 0 0 0 3px var(--pink_04_a30);\n}\n\n.Button--transparent.Button--variant-outline:active,\n.Button--transparent.Button--variant-outline.Button--pseudoActive {\n  background-color: var(--dark_bg_a04);\n  box-shadow: inset 0 0 0 1px var(--dark_03);\n}\n\n/* transparent-dark */\n\n.Button--appearance-dark.Button--transparent {\n  background-color: transparent;\n  color: var(--white);\n}\n\n.Button--appearance-dark.Button--transparent.Button--variant-outline {\n  box-shadow: inset 0 0 0 1px var(--dark_03);\n}\n\n.Button--appearance-dark.Button--transparent.Button--variant-outline:hover,\n.Button--appearance-dark.Button--transparent.Button--variant-outline.Button--pseudoHover {\n  background-color: var(--white_a08);\n}\n\n.Button--appearance-dark.Button--transparent.Button--variant-outline:focus-visible,\n.Button--appearance-dark.Button--transparent.Button--variant-outline.Button--pseudoFocus {\n  box-shadow: 0 0 0 3px var(--pink_04_a30);\n}\n\n.Button--appearance-dark.Button--transparent.Button--variant-outline:active,\n.Button--appearance-dark.Button--transparent.Button--variant-outline.Button--pseudoActive {\n  background-color: var(--white_a08);\n  box-shadow: inset 0 0 0 1px var(--dark_05);\n}\n\n/* purple */\n\n.Button--purple {\n  background-color: var(--purple);\n  color: var(--white);\n}\n\n.Button--purple:hover,\n.Button--purple.Button--pseudoHover {\n  background-color: var(--purple_bright);\n  color: var(--white);\n}\n\n.Button--purple:focus-visible,\n.Button--purple.Button--pseudoFocus {\n  box-shadow: 0 0 0 3px var(--purple_04_a30);\n}\n\n.Button--purple:active,\n.Button--purple.Button--pseudoActive {\n  background-color: var(--purple);\n  box-shadow: inset 0 0 0 1px var(--purple_bright);\n  color: var(--white);\n}\n\n/* purple-outline */\n\n.Button--purple.Button--variant-outline {\n  background-color: var(--white);\n  color: var(--purple_bright);\n  box-shadow: inset 0 0 0 1px var(--purple_04_a30);\n}\n\n.Button--purple.Button--variant-outline:hover,\n.Button--purple.Button--variant-outline.Button--pseudoHover {\n  background-color: var(--purple_bg_a08);\n  color: var(--purple_bright);\n}\n\n.Button--purple.Button--variant-outline:focus-visible,\n.Button--purple.Button--variant-outline.Button--pseudoFocus {\n  box-shadow: 0 0 0 3px var(--purple_04_a30);\n}\n\n.Button--purple.Button--variant-outline:active,\n.Button--purple.Button--variant-outline.Button--pseudoActive {\n  background-color: var(--purple_bg_a08);\n  box-shadow: inset 0 0 0 1px var(--purple_bright);\n  color: var(--purple_bright);\n}\n\n/* autoprefixer: ignore next */\n@supports not selector(:focus-visible) {\n  .Button--purple:focus {\n    box-shadow: 0 0 0 3px var(--purple_04_a30);\n  }\n}\n\n/* pink */\n\n.Button--pink {\n  background-color: var(--pink);\n  color: var(--white);\n}\n\n.Button--pink:hover,\n.Button--pink.Button--pseudoHover {\n  background-color: var(--pink_bright);\n  color: var(--white);\n}\n\n.Button--pink:focus-visible,\n.Button--pink.Button--pseudoFocus {\n  box-shadow: 0 0 0 3px var(--pink_04_a30);\n}\n\n.Button--pink:active,\n.Button--pink.Button--pseudoActive {\n  background-color: var(--pink);\n  box-shadow: inset 0 0 0 1px var(--pink_bright);\n  color: var(--white);\n}\n\n/* pink-outline */\n\n.Button--pink.Button--variant-outline {\n  background-color: var(--white);\n  color: var(--pink_bright);\n  box-shadow: inset 0 0 0 1px var(--pink_04_a30);\n}\n\n.Button--pink.Button--variant-outline:hover,\n.Button--pink.Button--variant-outline.Button--pseudoHover {\n  background-color: var(--pink_bg_a10);\n  color: var(--pink_bright);\n}\n\n.Button--pink.Button--variant-outline:focus-visible,\n.Button--pink.Button--variant-outline.Button--pseudoFocus {\n  box-shadow: 0 0 0 3px var(--pink_04_a30);\n}\n\n.Button--pink.Button--variant-outline:active,\n.Button--pink.Button--variant-outline.Button--pseudoActive {\n  background-color: var(--pink_bg_a10);\n  box-shadow: inset 0 0 0 1px var(--pink_bright);\n  color: var(--pink_bright);\n}\n\n/* pink-outline dark */\n\n.Button--appearance-dark.Button--pink.Button--variant-outline {\n  background-color: transparent;\n  color: var(--white);\n}\n\n/* autoprefixer: ignore next */\n@supports not selector(:focus-visible) {\n  .Button--pink:focus {\n    box-shadow: 0 0 0 3px var(--pink_04_a30);\n  }\n}\n\n/* cherry */\n\n.Button--cherry {\n  background-color: var(--cherry);\n  color: var(--white);\n}\n\n.Button--cherry:hover,\n.Button--cherry.Button--pseudoHover {\n  background-color: var(--cherry_dark);\n}\n\n.Button--cherry:focus-visible,\n.Button--cherry.Button--pseudoFocus {\n  box-shadow: 0 0 0 3px var(--pink_04_a30);\n}\n\n.Button--cherry:active,\n.Button--cherry.Button--pseudoActive {\n  background-color: var(--cherry);\n  box-shadow: inset 0 0 0 1px var(--cherry_dark);\n}\n\n/* cherry-outline */\n\n.Button--cherry.Button--variant-outline {\n  color: var(--cherry);\n  background-color: transparent;\n  box-shadow: inset 0 0 0 1px var(--pink_03_a60);\n}\n\n.Button--cherry.Button--variant-outline:hover,\n.Button--cherry.Button--variant-outline.Button--pseudoHover {\n  background-color: var(--pink_bg_a10);\n}\n\n.Button--cherry.Button--variant-outline:focus-visible,\n.Button--cherry.Button--variant-outline.Button--pseudoFocus {\n  box-shadow: 0 0 0 3px var(--pink_04_a30);\n}\n\n.Button--cherry.Button--variant-outline:active,\n.Button--cherry.Button--variant-outline.Button--pseudoActive {\n  background-color: var(--pink_bg_a10);\n  box-shadow: inset 0 0 0 1px var(--cherry);\n}\n\n/* cherry-outline dark */\n\n.Button--appearance-dark.Button--cherry.Button--variant-outline {\n  color: var(--white);\n}\n\n/* autoprefixer: ignore next */\n@supports not selector(:focus-visible) {\n  .Button--cherry:focus {\n    box-shadow: 0 0 0 3px var(--pink_04_a30);\n  }\n}\n\n/* sizes */\n\n.Button--size-s {\n  height: 40px;\n  padding: 0 16px;\n  font-size: 16px;\n  border-radius: 8px;\n}\n\n.Button--size-m {\n  height: 48px;\n  padding: 0 24px;\n  font-size: 16px;\n  border-radius: 8px;\n}\n\n.Button--size-l {\n  height: 64px;\n  padding: 0 40px;\n  font-size: 20px;\n  font-style: normal;\n  font-weight: 700;\n  border-radius: 8px;\n}\n\n.Button__prefix--loader {\n  animation-name: loader_appear;\n  animation-duration: var(--loader_time);\n  animation-fill-mode: forwards;\n\n  width: 16px;\n}\n\n.Button__prefix--loader + * {\n  margin-left: 8px;\n}\n\n.Button__prefix--removing {\n  animation-name: loader_disappear;\n}\n\n.Button__prefix--loader svg {\n  display: block;\n\n  animation-name: loader_rotation;\n  animation-duration: var(--loader_time);\n  animation-iteration-count: infinite;\n  animation-timing-function: linear;\n}\n\n@keyframes loader_appear {\n  0% {\n    width: 0;\n    margin-right: 0;\n    opacity: 0;\n  }\n  33% {\n    opacity: 0;\n  }\n  66% {\n    width: 16px;\n    margin-right: 8px;\n  }\n  100% {\n    opacity: 1;\n  }\n}\n\n@keyframes loader_disappear {\n  100% {\n    width: 0;\n    margin-right: 0;\n    opacity: 0;\n  }\n  66% {\n    opacity: 0;\n  }\n  33% {\n    width: 16px;\n    margin-right: 8px;\n  }\n  0% {\n    opacity: 1;\n  }\n}\n\n@keyframes loader_rotation {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(360deg);\n  }\n}\n"
  },
  {
    "path": "components/CTAButtons/CTAButtons.jsx",
    "content": "import * as React from 'react';\nimport classnames from 'classnames/bind';\nimport classes from './CTAButtons.module.css';\nimport ButtonLanding from '../ButtonLanding/ButtonLanding';\nimport { trackClick } from '../../utils/tracking';\n\nconst cn = classnames.bind(classes);\n\nexport const CTAButtons = ({\n  reverseButtonsOrder = false,\n  signupCTAId,\n  bookDemoCTAId,\n}) => {\n  const reverse = reverseButtonsOrder;\n\n  const bookProps = {\n    href: 'https://cube.dev/contact',\n    onClick: bookDemoCTAId ? trackClick(bookDemoCTAId) : undefined,\n    children: 'Request a demo',\n  };\n\n  const signupProps = {\n    href: 'https://cubecloud.dev/auth/signup',\n    onClick: signupCTAId ? trackClick(signupCTAId) : undefined,\n    children: 'Try Free',\n  };\n  return (\n    <>\n      <ButtonLanding\n        size=\"l\"\n        color=\"cherry\"\n        variant=\"default\"\n        className={classes.CTAButtons__button}\n        {...(reverse ? bookProps : signupProps)}\n      />\n\n      <ButtonLanding\n        size=\"l\"\n        color=\"cherry\"\n        variant=\"outline\"\n        appearance=\"dark\"\n        className={classes.CTAButtons__button}\n        {...(reverse ? signupProps : bookProps)}\n      />\n    </>\n  );\n};\n"
  },
  {
    "path": "components/CTAButtons/CTAButtons.module.css",
    "content": ".CTAButtons__button {\n  color: white;\n}\n"
  },
  {
    "path": "components/Card/Card.jsx",
    "content": "import styles from \"./Card.module.scss\";\nimport { ReactSVG } from \"react-svg\";\n\nexport default function Card(props) {\n  let Wrapper = \"a\";\n  if (props.notLink) {\n    Wrapper = \"div\";\n  }\n  return (\n    <Wrapper\n      href={props?.link}\n      target=\"_blank\"\n      role=\"button\"\n      className={props.height ? styles.full : null}\n    >\n      <div\n        big={props.isBig ? \"big\" : null}\n        color={props.color ? props.color : null}\n        className={\n          props.className ? styles.card + \" \" + props.className : styles.card\n        }\n        height={props.height || null}\n      >\n        {props.icons &&\n          props.icons.map((icon) => {\n            return (\n              <ReactSVG\n                key={icon}\n                className={styles.icon}\n                wrapper=\"span\"\n                src={icon}\n                width=\"100%\"\n                height=\"100%\"\n              />\n            );\n          })}\n        {props.icon && (\n          <ReactSVG\n            className={styles.icon}\n            wrapper=\"div\"\n            src={props.icon}\n          ></ReactSVG>\n        )}\n        <div className={styles.text}>{props.text}</div>\n        {props.description && (\n          <div className={styles.description}>{props.description}</div>\n        )}\n        {props.smallText && (\n          <div className={styles.smallText}>{props.smallText}</div>\n        )}\n        {props.footerText && (\n          <div\n            className={styles.footer}\n            dangerouslySetInnerHTML={{ __html: props.footerText }}\n          ></div>\n        )}\n      </div>\n    </Wrapper>\n  );\n}\n"
  },
  {
    "path": "components/Card/Card.module.scss",
    "content": "@import \"/styles/variables\";\n\n.card {\n  width: 100%;\n  padding: 32px;\n  border-radius: 24px;\n  border: 1px solid $dark-07;\n\n  color: $dark;\n  background-color: $dark-07;\n  transition: background-color 0.3s ease-in-out, border-color 0.3s ease-in-out,\n    color 0.3s ease-in-out;\n\n  &:hover {\n    background: $light;\n    border-color: $purple-04;\n  }\n\n  &:active {\n    background: #ececff;\n    border-color: $purple-03;\n  }\n}\n.card[color=\"orange\"] {\n  color: $orange;\n  background-color: $orange-02;\n  border-color: $orange-02;\n  &:hover {\n    background: #ffecda;\n    border-color: #ffc2a5;\n  }\n\n  &:active {\n    background: #ffe4cb;\n    border-color: #ff905d;\n  }\n  &[disabled=\"disabled\"] {\n    user-select: none;\n    pointer-events: none;\n    cursor: not-allowed;\n    border-color: $dark-05;\n    color: $dark-05;\n  }\n}\n.icon {\n  width: 22px;\n  height: 22px;\n  margin-bottom: 10px;\n  display: inline-flex;\n  margin-right: 8px;\n  svg {\n    width: 100%;\n    height: 100%;\n  }\n}\n.text {\n  // margin-top: 10px;\n  font-size: 24px;\n  line-height: 30px;\n  font-weight: 500;\n  // margin-bottom: 8px;\n}\n// .description {\n//   //\n// }\n.smallText {\n  margin-top: 8px;\n}\n.link {\n  margin-top: 8px;\n}\n.footer {\n  margin-top: 24px;\n  color: $dark-02;\n}\n.card[color=\"orange\"] {\n  .footer {\n    color: $orange;\n  }\n}\n.card[big=\"big\"] {\n  width: 100%;\n  padding: 48px 42px;\n  border-radius: 24px;\n  .text {\n    font-size: 48px;\n    line-height: 60px;\n    margin-bottom: 0;\n  }\n  .icon {\n    width: 24px;\n    height: 24px;\n    margin-bottom: 10px;\n  }\n}\n\n// fix\n.full {\n  height: 100%;\n}\n.card[height=\"full\"] {\n  height: 100%;\n}\n"
  },
  {
    "path": "components/Chip/Chip.jsx",
    "content": "import styles from \"./Chip.module.scss\";\n\nexport default function Chip(props) {\n  return (\n    <button\n      type=\"button\"\n      onClick={props.onClick}\n      className={\n        props.className ? styles.chip + \" \" + props.className : styles.chip\n      }\n      active={props.active}\n    >\n      <span>\n        {props.icon && (\n          <img\n            className={styles.icon}\n            src={`/images/logo/${props.icon}`}\n            alt={props.title}\n          />\n        )}\n        <span>{props.title}</span>\n      </span>\n    </button>\n  );\n}\n"
  },
  {
    "path": "components/Chip/Chip.module.scss",
    "content": "@import \"/styles/variables\";\n\n.chip {\n  font-family: CeraPro;\n  border: none;\n  padding: 8px 16px;\n  background-color: $dark-06;\n  border: 1px solid $dark-06;\n  border-radius: 40px;\n  color: $dark-03;\n  font-size: 24px;\n  line-height: 30px;\n  transition: background-color 0.3s ease-in-out, color 0.3s ease-in-out,\n    border-color 0.3s ease-in-out;\n  cursor: pointer;\n  display: flex;\n  align-items: center;\n  span {\n    display: inline-flex;\n    align-items: center;\n  }\n  img {\n    width: 18px;\n    height: 18px;\n    margin-right: 8px;\n    fill: red;\n  }\n\n  &:hover {\n    @media (hover) {\n      color: $purple-hover;\n      border: 1px solid $purple-04;\n    }\n  }\n\n  &[active=\"active\"] {\n    background-color: $light;\n    color: $purple-hover;\n    border: 1px solid $purple-04;\n  }\n\n  @media (max-width: 991.98px) {\n    margin-top: 8px;\n    margin-bottom: 8px;\n  }\n  @media (max-width: 767.98px) {\n    padding: 4px 8px;\n  }\n}\n\n.icon {\n  display: inline-flex;\n  margin-right: 8px;\n  min-width: 22px;\n  min-height: 22px;\n  svg {\n    width: 22px;\n    height: 22px;\n  }\n}\n"
  },
  {
    "path": "components/Chip/index.js",
    "content": "import Chip from \"./Chip\";\nexport default Chip;\n"
  },
  {
    "path": "components/ExploreToolsCard/ExploreToolsCard.jsx",
    "content": "import styles from \"./ExploreToolsCard.module.scss\";\nimport { ReactSVG } from \"react-svg\";\n\nexport default function ExploreToolsCard(props) {\n  return (\n    <a\n      className=\"col-6 col-md-6 col-lg-4 col-xl-2\"\n      onClick={props.onClick}\n      role=\"button\"\n    >\n      <div className={styles.exploreToolsCard} active={props.active || null}>\n        <div className={styles.exploreToolsCard__wrap}>\n          <h2\n            className={styles.exploreToolsCard__text}\n            dangerouslySetInnerHTML={{ __html: props.text.replace(' ', '<br/>') }}\n          ></h2>\n        </div>\n        {props.image && (\n          <ReactSVG\n            wrapper=\"span\"\n            src={`/images/${props.image}`}\n            className={styles.exploreToolsCard__image}\n          />\n        )}\n      </div>\n    </a>\n  );\n}\n"
  },
  {
    "path": "components/ExploreToolsCard/ExploreToolsCard.module.scss",
    "content": "@import \"/styles/variables\";\n\n.exploreToolsCard {\n  background: $dark-06;\n  border: 1px solid $dark-06;\n  transition: border 0.3s ease-in-out, background 0.3s ease-in-out;\n  border-radius: 24px;\n  overflow: hidden;\n  cursor: pointer;\n  margin-bottom: 16px;\n  user-select: none;\n  font-weight: 500;\n\n  &[active=\"active\"] {\n    background-color: darken(#ecebff, 5%);\n  }\n  &__wrap {\n    padding: 24px 24px 0px 24px;\n    @media (max-width: 767.98px) {\n      padding: 16px 16px 0 16px;\n    }\n  }\n\n  &__text {\n    font-size: 24px;\n    font-weight: 500;\n    line-height: 30px;\n    color: $dark-03;\n    margin: 0;\n    transition: color 0.3s ease-in-out;\n  }\n\n  &__image {\n    display: flex;\n    align-items: center;\n    justify-content: flex-end;\n    transition: color 0.3s ease-in-out;\n    color: $dark-05;\n    height: 64px;\n  }\n\n  &:hover {\n    // fix mobile hover effect\n    @media (hover) {\n      border: 1px solid $purple-04;\n      .exploreToolsCard__text {\n        color: $purple-hover;\n      }\n      .exploreToolsCard__image {\n        color: $purple-04;\n      }\n    }\n  }\n\n  &[active=\"active\"] {\n    background: $light;\n    border: 1px solid $purple-04;\n    .exploreToolsCard__text {\n      color: $purple-hover;\n    }\n    .exploreToolsCard__image {\n      color: $purple-04;\n    }\n  }\n\n  &[disabled=\"disabled\"] {\n    .exploreToolsCard__text {\n      color: $dark-07;\n    }\n  }\n  @media (max-width: 767.98px) {\n    margin-bottom: 8px;\n  }\n}\n"
  },
  {
    "path": "components/ExploreToolsCard/index.js",
    "content": "import ExploreToolsCard from \"./ExploreToolsCard\";\nexport default ExploreToolsCard;\n"
  },
  {
    "path": "components/Footer/Footer.jsx",
    "content": "import styles from \"./Footer.module.scss\";\nimport { ReactSVG } from \"react-svg\";\n\nexport default function Footer() {\n  return (\n    <footer className={styles.footer + \" container custom-container\"}>\n      <div>\n        <ReactSVG\n          className={styles.footer__logo}\n          src=\"/images/logo/cubejs-logo.svg\"\n        />\n      </div>\n      <div className={styles.info}>\n        <p>\n          Created and maintained in open source\n          <br />\n          by{\" \"}\n          <a href=\"https://cube.dev/\" target=\"_blank\">\n            Cube Dev\n          </a>\n          , the creators of{\" \"}\n          <a href=\"https://github.com/cube-js/cube.js\" target=\"_blank\">\n            Cube\n          </a>\n        </p>\n        <p>\n          Want to add a new tool or update the info?{\" \"}\n          <br className=\"xs-hidden\" />\n          We appreciate{\" \"}\n          <a\n            href=\"https://github.com/cube-js/awesome-tools/issues\"\n            target=\"_blank\"\n          >\n            issues\n          </a>{\" \"}\n          and{\" \"}\n          <a\n            href=\"https://github.com/cube-js/awesome-tools/pulls\"\n            target=\"_blank\"\n          >\n            pull requests\n          </a>\n        </p>\n      </div>\n    </footer>\n  );\n}\n"
  },
  {
    "path": "components/Footer/Footer.module.scss",
    "content": "@import \"/styles/variables\";\n\n.footer {\n  margin-top: 90px;\n  border-top: 2px solid #e7e9ed;\n  padding-top: 64px;\n  padding-bottom: 80px;\n}\n.info {\n  margin-top: 16px;\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  p {\n    margin: 0;\n    font-size: 16px;\n    line-height: 28px;\n    color: $dark-03;\n  }\n  a {\n    color: $dark;\n  }\n  @media (max-width: 767.98px) {\n    flex-direction: column;\n    align-items: flex-start;\n    p:last-child {\n      margin-top: 16px;\n    }\n  }\n}\n"
  },
  {
    "path": "components/Footer/index.js",
    "content": "import Footer from \"./Footer\";\nexport default Footer;\n"
  },
  {
    "path": "components/Gallery/Gallery.jsx",
    "content": "import dynamic from \"next/dynamic\";\nimport styles from \"./Gallery.module.scss\";\nimport H2 from \"../Text/H2\";\nconst Slider = dynamic(() => import(\"../../components/Slider\"));\n\nexport default function Gallery(props) {\n  return (\n    <div className={styles.gallery + \" row\"}>\n      <div className=\"col-sm-3\">\n        <H2>Gallery</H2>\n        {props.link && (\n          <div className=\"mt-sm\">\n            <a href={props.link} className=\"link\" target=\"_blank\">\n              All examples →\n            </a>\n          </div>\n        )}\n      </div>\n      <div className={styles.sliderWrap + \" col-sm-9\"}>\n        <Slider slidesData={props.gallery} />\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/Gallery/Gallery.module.scss",
    "content": ".gallery {\n  margin-bottom: 104px;\n  @media (max-width: 767.98px) {\n    margin-bottom: 48px;\n  }\n}\n.sliderWrap {\n  @media (max-width: 767.98px) {\n    margin-top: 24px;\n  }\n}\n"
  },
  {
    "path": "components/Gallery/index.js",
    "content": "import Gallery from \"./Gallery\";\nexport default Gallery;\n"
  },
  {
    "path": "components/GetHelpCard/GetHelpCard.jsx",
    "content": "import styles from \"./GetHelpCard.module.scss\";\nimport Link from \"next/link\";\n\nexport default function Card(props) {\n  return (\n    <Link href={props.href} legacyBehavior>\n      <a target=\"_blank\">\n        <div\n          className={\n            props.className ? styles.card + \" \" + props.className : styles.card\n          }\n        >\n          {props.icon && (\n            <div\n              className={styles.icon}\n              style={{ backgroundImage: `url(${props.icon})` }}\n            ></div>\n          )}\n          {props.title && <div className={styles.title}>{props.title}</div>}\n          {props.footer && <div className={styles.footer}>{props.footer}</div>}\n        </div>\n      </a>\n    </Link>\n  );\n}\n"
  },
  {
    "path": "components/GetHelpCard/GetHelpCard.module.scss",
    "content": "@import \"/styles/variables\";\n.card {\n  box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.3);\n  transition: box-shadow 0.32s ease-in-out;\n  border-radius: 32px;\n  background: #ffffff;\n  padding: 32px;\n  cursor: pointer;\n  height: 100%;\n  &:hover {\n    box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.5);\n  }\n}\n.icon {\n  width: 64px;\n  height: 64px;\n  background-size: contain;\n  background-repeat: no-repeat;\n  background-position: center;\n}\n.title {\n  margin-top: 16px;\n  font-size: 24px;\n  font-weight: 500;\n  line-height: 30px;\n  color: $dark;\n}\n.footer {\n  margin-top: 8px;\n  font-size: 14px;\n  line-height: 18px;\n  letter-spacing: 0.02em;\n  color: $dark;\n}\n"
  },
  {
    "path": "components/GetHelpCard/index.js",
    "content": "import GetHelpCard from \"./GetHelpCard\";\nexport default GetHelpCard;\n"
  },
  {
    "path": "components/GetStartedCard/GetStartedCard.jsx",
    "content": "import styles from \"./GetStartedCard.module.scss\";\nimport { ReactSVG } from \"react-svg\";\n\nexport default function Card(props) {\n  return (\n    <a href={props.link} target=\"_blank\">\n      <div\n        className={\n          props.className ? styles.card + \" \" + props.className : styles.card\n        }\n      >\n        {props.icon && (\n          <ReactSVG\n            className={styles.icon}\n            wrapper=\"div\"\n            src={props.icon}\n          ></ReactSVG>\n        )}\n        {props.type && <div className={styles.type}>{props.type}</div>}\n        {props.title && <div className={styles.title}>{props.title}</div>}\n        {props.link && (\n          <div className={styles.link}>\n            <span className=\"link\">Read more →</span>\n          </div>\n        )}\n      </div>\n    </a>\n  );\n}\n"
  },
  {
    "path": "components/GetStartedCard/GetStartedCard.module.scss",
    "content": "@import \"/styles/variables\";\n\n.card {\n  box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.3);\n  transition: box-shadow 0.32s ease-in-out;\n  border-radius: 32px;\n  padding: 32px;\n  height: 100%;\n  // margin-bottom: 32px;\n  &:hover {\n    box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.5);\n  }\n  &:nth-child(3) {\n    margin-top: 32px;\n  }\n}\n.type {\n  margin-top: 16px;\n  font-size: 16px;\n  line-height: 26px;\n  text-transform: uppercase;\n  color: $dark;\n}\n.title {\n  font-size: 24px;\n  line-height: 30px;\n  font-weight: 500;\n  color: $dark;\n  margin-top: 16px;\n}\n.link {\n  margin-top: 24px;\n  margin-bottom: 23px;\n}\n"
  },
  {
    "path": "components/GetStartedCard/index.js",
    "content": "import GetStartedCard from \"./GetStartedCard\";\nexport default GetStartedCard;\n"
  },
  {
    "path": "components/GlobalSignUp/GlobalSignUp.jsx",
    "content": "import * as React from 'react';\nimport classnames from 'classnames/bind';\nimport classes from './GlobalSignUp.module.css';\n\nconst cn = classnames.bind(classes);\n\n\nexport const GlobalSignUp = ({ className, children }) => {\n  return (\n    <div\n      style={\n          {\n            '--section_padding_top': `48px`,\n            '--section_padding_bottom': `48px`,\n          }\n        }\n        className={cn(\n          'Section',\n          `Section--appearance-dark`,\n          `Section--gap-xl`,\n          cn('GlobalSignUp', className)\n        )}\n    >\n      <div\n        className={cn(\n          'SectionContent',\n          `SectionContent--align-none`,\n          `SectionContent--size-m`,\n          `Section--gap-none`,\n          classes.GlobalSignUp__content\n        )}\n      >\n        <h2 className={classes.GlobalSignUp__title}>Deliver better data, faster—with Cube.</h2>\n        <div className={classes.GlobalSignUp__buttons}>{children}</div>\n      </div>\n    </div>\n  );\n};\n"
  },
  {
    "path": "components/GlobalSignUp/GlobalSignUp.module.css",
    "content": ".GlobalSignUp {\n  background-color: hsl(240, 32%, 10%);\n  overflow: hidden;\n  position: relative;\n}\n\n.GlobalSignUp::before {\n  content: \"\";\n  position: absolute;\n  width: 100%;\n  min-width: 600px;\n  /* stylelint-disable-next-line */\n  padding-bottom: 100%;\n  right: -40%;\n  top: 50%;\n  transform: translateY(-50%);\n  background-image: radial-gradient(#ac0053 30%, #ac005300 65%);\n  opacity: 0.6;\n  z-index: 0;\n}\n\n@media (max-width: 639px) {\n  .GlobalSignUp::before {\n    background-image: radial-gradient(#ac0053 40%, #ac005300 75%);\n    right: 50%;\n    transform: translateX(50%) translateY(-5%);\n  }\n}\n\n.GlobalSignUp > * {\n  z-index: 1;\n}\n\n.GlobalSignUp__content {\n  display: flex;\n  flex-direction: row;\n  align-items: center;\n  gap: 16px;\n}\n\n.GlobalSignUp__content a {\n  color: white;\n}\n\n.GlobalSignUp__title {\n  font-size: 32px;\n  line-height: 44px;\n  font-weight: 700;\n  font-family: CeraPro;\n  flex-grow: 1;\n  margin: 0;\n}\n\n.GlobalSignUp__buttons {\n  display: flex;\n  gap: 16px;\n}\n\n@media (min-width: 640px) {\n  .GlobalSignUp__buttons > * {\n    flex-grow: 1;\n    flex-basis: 0;\n  }\n}\n\n@media (max-width: 979px) {\n  .GlobalSignUp__content {\n    flex-direction: column;\n  }\n  .GlobalSignUp__buttons {\n    width: 100%;\n  }\n\n  .GlobalSignUp__title {\n    text-align: center;\n  }\n}\n\n@media (max-width: 639px) {\n  .GlobalSignUp__buttons {\n    flex-direction: column;\n  }\n}\n\n\n.Section {\n  --section_padding_top: 0px;\n  --section_padding_bottom: 0px;\n  display: flex;\n  flex-flow: column;\n  overflow: hidden;\n  padding: var(--section_padding_top) 0 var(--section_padding_bottom);\n}\n\n.Section--gap-l {\n  gap: 32px;\n}\n\n.Section--gap-xl {\n  gap: 48px;\n}\n\n.Section--gap-2xl {\n  gap: 64px;\n}\n\n.Section--gap-3xl {\n  gap: 80px;\n}\n\n@media (min-width: 640px) {\n  .Section--rounded {\n    border-radius: 32px;\n    margin: 16px;\n  }\n}\n\n@media (min-width: 1980px) {\n  .Section--rounded {\n    max-width: calc(1980px - 32px);\n    width: 100%;\n    margin: 16px auto;\n  }\n}\n\n.Section--bordered-bottom {\n  box-shadow: inset 0 -1px 0 rgba(192, 192, 234, 0.4);\n}\n\n.Section--appearance-light {\n  background-color: white;\n}\n\n.Section--hero.Section--appearance-light {\n  background-color: ¿hsl(240, 12%, 97%, 1);;\n}\n\n.Section--appearance-dark {\n  background-color: hsla(240, 14%, 23%);\n  color: white;\n}\n\n.Section--transparent {\n  background-color: transparent;\n}\n\n/*  */\n\n.Section--absoluteTop {\n  position: relative;\n  overflow: visible;\n}\n\n.Section--absoluteTop > * {\n  position: absolute !important;\n  top: 0;\n  left: 0;\n  right: 0;\n}\n\n.Section--absoluteTop + .Section {\n  padding-top: calc(var(--section_padding_top) + var(--topbar_height));\n}\n\n/* content */\n\n.SectionContent {\n  width: 100%;\n  margin: 0 auto;\n  padding: 0 24px;\n}\n\n.SectionContent--size-xs {\n  max-width: calc(800px + 2 * 24px);\n}\n\n.SectionContent--size-s {\n  max-width: calc(1040px + 2 * 24px);\n}\n\n.SectionContent--size-m {\n  max-width: calc(1120px + 2 * 24px);\n}\n\n.SectionContent--size-l {\n  max-width: calc(1248px + 2 * 24px);\n}\n\n.SectionContent--align-center {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\n.SectionContent.Section--gap-xl,\n.SectionContent.Section--gap-2xl,\n.SectionContent.Section--gap-3xl {\n  display: flex;\n  flex-flow: column;\n}\n"
  },
  {
    "path": "components/Header/Header.jsx",
    "content": "import styles from \"./Header.module.scss\";\nimport { useRouter } from \"next/router\";\nimport Link from \"next/link\";\n\nexport default function Header() {\n  const router = useRouter();\n  const isRoot = router.pathname === \"/\";\n\n  return (\n    <header className={styles.header}>\n      <div className={styles.header__logo + \" container custom-container\"}>\n        <a href=\"https://cube.dev/\" target=\"_blank\" aria-label=\"Cube\">\n          <span className={styles.header__logo}>\n            <img src={`/images/logo/cubejs-logo.svg`} alt=\"Cube\" />\n          </span>\n        </a>\n        <ConditionalWrapper\n          condition={!isRoot}\n          wrapper={(children) => <Link href=\"/\">{children}</Link>}\n        >\n          <span\n            className={styles.header__text}\n            active={!isRoot ? \"active\" : \"\"}\n          >\n            <img\n              src={`/images/logo/cubejs-awesome-tools.svg`}\n              alt=\"Awesome tools\"\n            />\n          </span>\n        </ConditionalWrapper>\n      </div>\n    </header>\n  );\n}\n\nconst ConditionalWrapper = ({ condition, wrapper, children }) => (\n  <>{condition ? wrapper(children) : children}</>\n);\n"
  },
  {
    "path": "components/Header/Header.module.scss",
    "content": ".header {\n  padding: 24px 0;\n\n  &__logo {\n    display: flex;\n    align-items: center;\n    min-height: 28px;\n  }\n\n  &__text {\n    margin-left: 8px;\n\n    &[active=\"active\"] {\n      cursor: pointer;\n    }\n  }\n}\n"
  },
  {
    "path": "components/Header/index.js",
    "content": "import Header from \"./Header\";\nexport default Header;\n"
  },
  {
    "path": "components/ListPage/ListPage.jsx",
    "content": "import React, { useState, useEffect } from \"react\";\nimport dynamic from \"next/dynamic\";\nimport { useRouter } from \"next/router\";\nimport { filter, setParamsFromRouter } from \"../../data/filter\";\nimport allFrameworks from \"../../data/frameworks\";\nimport allTypes from \"../../data/types\";\nimport Chip from \"../Chip\";\nimport ExploreToolsCard from \"../ExploreToolsCard\";\nimport H1 from \"../Text/H1\";\nimport AccentedText from \"../Text/AccentedText\";\nimport { NextSeo } from \"next-seo\";\nimport ToolCard from \"../ToolCard\";\nimport ToolsNumberControl from \"../ToolsNumberControl\";\n\nexport default function ListPage({\n  tools,\n  framework,\n  title,\n  showType = true,\n  showCompatibleWith = true,\n  showLicense = true,\n}) {\n  const router = useRouter();\n  const query = router.query;\n  const [isFirstLoad, setLoad] = useState(false);\n  const [exploreTools, setExploreTools] = useState([]);\n  const [frameworks, setFrameworks] = useState([]);\n  const [languages, setLanguages] = useState([]);\n  const [licenses, setLicenses] = useState([]);\n  const [renders, setRenders] = useState([]);\n\n  const isFiltered =\n    exploreTools.length ||\n    frameworks.length ||\n    languages.length ||\n    licenses.length ||\n    renders.length;\n\n  useEffect(() => {\n    if (Object.keys(query).length && !isFirstLoad) {\n      setParamsFromRouter(\n        query,\n        setExploreTools,\n        setFrameworks,\n        setLanguages,\n        setLicenses,\n        setRenders\n      );\n      setLoad(true);\n    }\n  }, [query]);\n\n  useEffect(() => {\n    router.push(\n      {\n        query: {\n          ...(framework && { framework }),\n          tools: exploreTools,\n          ...(!framework && { frameworks }),\n          languages,\n          licenses,\n          renders,\n        },\n      },\n      undefined,\n      { scroll: false }\n    );\n  }, [framework, exploreTools, frameworks, languages, licenses, renders]);\n\n  const filteredTools = isFiltered\n    ? filter(tools, frameworks, languages, licenses, renders, exploreTools)\n    : tools;\n\n  const setItem = (array, set, item) => {\n    const index = array.indexOf(item);\n    if (index === -1) {\n      set([...array, item]);\n      // return true;\n    } else {\n      array.splice(index, 1);\n      set([...array]);\n      // return false;\n    }\n  };\n\n  return (\n    <>\n      <NextSeo\n        title={`${title} — the awesome list`}\n        description={`${title} for application developers: charting libraries, data grids, maps, etc.`}\n      />\n\n      <div className=\"container custom-container\">\n        <main>\n          <H1>\n            {title} <br className=\"xl-hidden\" /> for application developers\n          </H1>\n\n          {showType && (\n            <div className=\"row mb-md\">\n              {Object.values(allTypes).map((type, i) => (\n                <ExploreToolsCard\n                  key={type.slug}\n                  onClick={() =>\n                    setItem(exploreTools, setExploreTools, type.slug)\n                  }\n                  active={exploreTools.includes(type.slug) ? \"active\" : null}\n                  text={type.name}\n                  image={type.image}\n                />\n              ))}\n            </div>\n          )}\n\n          {showCompatibleWith && (\n            <div className=\"flex flex-wrap-row flex-items-center mb-sm\">\n              <AccentedText className=\"mr-xs\">Compatible with</AccentedText>\n\n              {Object.values(allFrameworks).map((framework) => (\n                <Chip\n                  key={framework.slug}\n                  className=\"mr-xs\"\n                  icon={framework.icon}\n                  title={framework.name}\n                  active={frameworks.includes(framework.slug) ? \"active\" : null}\n                  onClick={() =>\n                    setItem(frameworks, setFrameworks, framework.slug)\n                  }\n                />\n              ))}\n            </div>\n          )}\n\n          <div className=\"flex flex-wrap-row flex-items-center mb-sm\">\n            <AccentedText className=\"mr-xs\">With support for</AccentedText>\n\n            <Chip\n              icon=\"typescript.svg\"\n              title=\"TypeScript\"\n              active={languages.includes(\"typescript\") ? \"active\" : null}\n              onClick={() => setItem(languages, setLanguages, \"typescript\")}\n            />\n            {showLicense && (\n              <AccentedText className=\"mr-xs ml-xs\">and</AccentedText>\n            )}\n            {showLicense && (\n              <>\n                <Chip\n                  className=\"mr-xs\"\n                  icon=\"open-source.svg\"\n                  title=\"open source\"\n                  active={licenses.includes(\"open-source\") ? \"active\" : null}\n                  onClick={() => setItem(licenses, setLicenses, \"open-source\")}\n                />\n                <Chip\n                  icon=\"proprietary.svg\"\n                  title=\"proprietary\"\n                  active={licenses.includes(\"proprietary\") ? \"active\" : null}\n                  onClick={() => setItem(licenses, setLicenses, \"proprietary\")}\n                />\n                <AccentedText className=\"ml-xs\">license</AccentedText>\n              </>\n            )}\n          </div>\n          <div className=\"flex flex-wrap-row flex-items-center\">\n            <AccentedText className=\"mr-xs\">Rendering</AccentedText>\n\n            <Chip\n              title=\"Canvas\"\n              className=\"mr-xs\"\n              active={renders.includes(\"canvas\") ? \"active\" : null}\n              onClick={() => setItem(renders, setRenders, \"canvas\")}\n            />\n            <Chip\n              title=\"SVG\"\n              className=\"mr-xs\"\n              active={renders.includes(\"svg\") ? \"active\" : null}\n              onClick={() => setItem(renders, setRenders, \"svg\")}\n            />\n            <Chip\n              title=\"HTML\"\n              active={renders.includes(\"html\") ? \"active\" : null}\n              onClick={() => setItem(renders, setRenders, \"html\")}\n            />\n          </div>\n\n          <div className=\"number-control-wrap\">\n            <ToolsNumberControl\n              filteredTools={filteredTools}\n              isChanged={isFiltered}\n              clearFilters={() => {\n                clearFilters([\n                  setExploreTools,\n                  setFrameworks,\n                  setLanguages,\n                  setLicenses,\n                  setRenders,\n                ]);\n              }}\n            />\n          </div>\n\n          <div className=\"row\">\n            {filteredTools &&\n              filteredTools.map((tool) => (\n                <div className=\"col-xl-6 mb-md\" key={tool.id}>\n                  {/* to lazy load on scroll need to set heigth */}\n                  <ToolCard {...tool} />\n                </div>\n              ))}\n          </div>\n        </main>\n      </div>\n    </>\n  );\n}\n\nfunction clearFilters(arrayOfFunctions) {\n  arrayOfFunctions.forEach((fn) => {\n    fn([]);\n  });\n}\n"
  },
  {
    "path": "components/ListPage/index.js",
    "content": "import ListPage from \"./ListPage\";\nexport default ListPage;\n"
  },
  {
    "path": "components/Slider/Slider.jsx",
    "content": "// App.js\nimport React, { useState, useEffect } from \"react\";\nimport styles from \"./Slider.module.scss\";\n// import \"./App.css\";\n\nimport Slider from \"react-slick\";\n\nimport \"slick-carousel/slick/slick.css\";\nimport \"slick-carousel/slick/slick-theme.css\";\n\nfunction getSettingsThumbs(slidesToShow) {\n  return {\n    slidesToShow: Math.min(4, slidesToShow),\n    slidesToScroll: 1,\n    asNavFor: \".slider-for\",\n    dots: false,\n    centerMode: false,\n    swipeToSlide: true,\n    focusOnSelect: true,\n  };\n}\n\nfunction App(props) {\n  const [nav1, setNav1] = useState(null);\n  const [nav2, setNav2] = useState(null);\n  const [slider1, setSlider1] = useState(null);\n  const [slider2, setSlider2] = useState(null);\n\n  useEffect(() => {\n    setNav1(slider1);\n    setNav2(slider2);\n  });\n\n  const settingsMain = {\n    slidesToShow: 1,\n    slidesToScroll: 1,\n    arrows: false,\n    fade: true,\n    asNavFor: \".slider-nav\",\n  };\n\n  return (\n    <div className={styles.slider}>\n      <div className={styles.sliderWrapper}>\n        <Slider\n          {...settingsMain}\n          asNavFor={nav2}\n          ref={(slider) => setSlider1(slider)}\n        >\n          {props.slidesData &&\n            props.slidesData.map((slide, i) => (\n              <div className={styles.slickSlide} key={slide}>\n                <img\n                  className={styles.slickSlideImage}\n                  src={slide}\n                  alt={`Preview ${i}`}\n                />\n              </div>\n            ))}\n        </Slider>\n        <div className={styles.thumbnailSliderWrap}>\n          <Slider\n            {...getSettingsThumbs(props.slidesData.length)}\n            asNavFor={nav1}\n            ref={(slider) => setSlider2(slider)}\n          >\n            {props.slidesData &&\n              props.slidesData.map((slide, i) => (\n                <div className={styles.slickSlide} key={slide}>\n                  <img\n                    className={styles.slickSlideImage}\n                    src={slide}\n                    alt={`Thumbnail ${i}`}\n                  />\n                </div>\n              ))}\n          </Slider>\n        </div>\n      </div>\n    </div>\n  );\n}\n\nexport default App;\n"
  },
  {
    "path": "components/Slider/Slider.module.scss",
    "content": ".thumbnailSliderWrap {\n  margin-top: 27px;\n  // height: 85px;\n  @media (max-width: 767.98px) {\n    margin-top: 16px;\n  }\n}\n.slickSlide {\n  text-align: center;\n}\n.sliderWrapper {\n  .slickSlide img {\n    border: 2px solid #e7e7e7;\n    box-sizing: border-box;\n    border-radius: 16px;\n    width: 100%;\n    @media (max-width: 767.98px) {\n      width: 100%;\n    }\n  }\n}\n.thumbnailSliderWrap {\n  max-height: 111px;\n  overflow: hidden;\n  @media (max-width: 1200px) {\n    height: 70px;\n  }\n  @media (max-width: 767.98px) {\n    height: 50px;\n  }\n  .slickSlide img {\n    cursor: pointer;\n    // width: 90%;\n    max-width: 213px;\n    border: 1px solid #d5d5e2;\n    border-radius: 8px;\n    outline: none;\n    max-height: 111px;\n    @media (max-width: 1400px) {\n      width: 90%;\n    }\n    @media (max-width: 1200px) {\n      max-height: 70px;\n    }\n    @media (max-width: 767.98px) {\n      max-height: 50px;\n    }\n  }\n}\n"
  },
  {
    "path": "components/Slider/index.js",
    "content": "import Slider from \"./Slider\";\nexport default Slider;\n"
  },
  {
    "path": "components/Text/AccentedText.jsx",
    "content": "import styles from \"./AccentedText.module.scss\";\n\nexport default function AccentedText(props) {\n  return (\n    <span\n      className={\n        props.className\n          ? styles.accented + \" \" + props.className\n          : styles.accented\n      }\n    >\n      {props.children}\n    </span>\n  );\n}\n"
  },
  {
    "path": "components/Text/AccentedText.module.scss",
    "content": ".accented {\n  font-size: 24px;\n  line-height: 30px;\n}\n"
  },
  {
    "path": "components/Text/H1.jsx",
    "content": "import styles from \"./H1.module.scss\";\n\nexport default function H1(props) {\n  return <h1 className={styles.title}>{props.children}</h1>;\n}\n"
  },
  {
    "path": "components/Text/H1.module.scss",
    "content": "@import \"/styles/variables\";\n\n.title {\n  font-style: normal;\n  font-weight: 700;\n  font-size: 64px;\n  line-height: 72px;\n  margin: 24px 0;\n\n  @media (max-width: 767.98px) {\n    font-size: 32px;\n    line-height: 44px;\n  }\n}\n"
  },
  {
    "path": "components/Text/H2.jsx",
    "content": "import styles from \"./H2.module.scss\";\n\nexport default function H2(props) {\n  return (\n    <h2\n      {...props}\n      className={\n        props.className ? styles.h2 + \" \" + props.className : styles.h2\n      }\n    >\n      {props.children}\n    </h2>\n  );\n}\n"
  },
  {
    "path": "components/Text/H2.module.scss",
    "content": "@import \"/styles/variables\";\n\n.h2 {\n  font-size: 40px;\n  line-height: 50px;\n  color: $dark;\n  margin: 0;\n  @media (max-width: 767.98px) {\n    font-size: 26px;\n    line-height: 36px;\n  }\n}\n"
  },
  {
    "path": "components/ToolCard/ToolCard.jsx",
    "content": "import styles from \"./ToolCard.module.scss\";\nimport dayjs from \"dayjs\";\nimport dayjsUtc from \"dayjs/plugin/utc\";\nimport Link from \"next/link\";\nimport abbreviateNumber from \"../../utils/number\";\n\ndayjs.extend(dayjsUtc);\n\nexport default function ToolCard(props) {\n  let shadow = getShadowByLabel(props?.feature_label);\n  let language = null;\n  if (props.languages && props.languages.length > 0) {\n    language = props?.languages?.includes(\"TypeScript\")\n      ? \"TypeScript\"\n      : \"JavaScript\";\n  }\n\n  return (\n    <Link href={\"/tools/\" + props.id} className=\"full-height\" legacyBehavior>\n      <a className=\"full-height\">\n        <div className={styles.toolCard} shadow={shadow}>\n          <div className=\"flex flex-items-center\">\n            <img\n              className={styles.toolCard__logo}\n              src={`/images/logo/${props.logo}`}\n              alt={`${props.title} logo`}\n            />\n            <div className=\"flex flex-column\">\n              <h2 className={styles.toolCard__title}>\n                {props.title || \"\"}\n                {props.developer && (\n                  <span className={styles.toolCard__developer}>\n                    &nbsp;by&nbsp;{props.developer}\n                  </span>\n                )}\n              </h2>\n            </div>\n          </div>\n          <p\n            className={styles.toolCard__description}\n            dangerouslySetInnerHTML={{ __html: props.description }}\n          ></p>\n          <div className=\"flex flex-wrap-row\">\n            {props?.github_data && (\n              <div className=\"flex flex-column\">\n                <span className={styles.features}>GitHub stars</span>\n                <div className={styles.github}>\n                  <img\n                    className={styles.icon}\n                    src={`/images/logo/github.svg`}\n                    alt={`${props.title} logo`}\n                  />\n                  <span className={styles.features__text}>\n                    {abbreviateNumber(props?.github_data?.stars) || \"-\"}\n                  </span>\n                </div>\n              </div>\n            )}\n\n            {props.frameworks && props.frameworks.length > 0 && (\n              <div className=\"flex flex-column\">\n                <span className={styles.features}>Framework</span>\n                <div className={styles.framework}>\n                  {props.frameworks &&\n                    props.frameworks.map((framework, i) => {\n                      return (\n                        <div\n                          className={styles.framework__wrapper}\n                          key={`${framework}_${i}`}\n                        >\n                          {framework !== \"Universal\" ? (\n                            <img\n                              className={styles.icon}\n                              src={`/images/logo/${framework.toLowerCase()}.svg`}\n                              alt={`${props.title} logo`}\n                            />\n                          ) : null}\n                          {props.frameworks.length === 1 && (\n                            <span className={styles.features__text}>\n                              {framework === \"vanilla-js\"\n                                ? \"vanilla JS\"\n                                : framework}\n                            </span>\n                          )}\n                        </div>\n                      );\n                    })}\n                </div>\n              </div>\n            )}\n\n            {language && (\n              <div className=\"flex flex-column\">\n                <span className={styles.features}>Language</span>\n                <div className={styles.language}>\n                  <div className={styles.language__wrapper}>\n                    {language ? (\n                      <img\n                        className={styles.icon}\n                        src={`/images/logo/${language.toLowerCase()}.svg`}\n                        alt={`${props.title} logo`}\n                      />\n                    ) : null}\n                    <span className={styles.features__text}>{language}</span>\n                  </div>\n                </div>\n              </div>\n            )}\n\n            {props?.github_data?.last_release?.date && (\n              <div className=\"flex flex-column\">\n                <span className={styles.features}>Last release</span>\n                <div>\n                  <span className={styles.features__text}>\n                    {dayjs(props?.github_data?.last_release?.date)\n                      .utc()\n                      .format(\"MMM DD, YYYY\") || \"-\"}\n                  </span>\n                </div>\n              </div>\n            )}\n          </div>\n          {props.feature_label && (\n            <div className={styles.toolCard__achievement}>\n              <img\n                className={styles.toolCard__achievement__icon}\n                src={`/images/${props.feature_label}.svg`}\n                alt={`${props.title} logo`}\n              />\n            </div>\n          )}\n        </div>\n      </a>\n    </Link>\n  );\n}\n\nfunction getShadowByLabel(label) {\n  if (!label) {\n    return \"gray\";\n  }\n\n  return label;\n}\n"
  },
  {
    "path": "components/ToolCard/ToolCard.module.scss",
    "content": "@import \"/styles/variables\";\n\n.toolCard {\n  cursor: pointer;\n  padding: 32px;\n  color: $dark;\n  background: #ffffff;\n  box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.3);\n  border-radius: 40px;\n  position: relative;\n  max-width: 600px;\n  height: 100%;\n  transition: box-shadow 0.3s ease-in-out;\n  margin: 0 auto;\n\n  @media (max-width: 767.98px) {\n    padding: 24px;\n  }\n\n  &:hover {\n    box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.5);\n  }\n\n  &__logo {\n    width: 60px;\n    height: 60px;\n    border: 1px solid rgba(213, 213, 226, 0.5);\n    border-radius: 16px;\n  }\n\n  &__title {\n    font-weight: 700;\n    font-size: 26px;\n    line-height: 36px;\n    margin: 0 0 0 16px;\n  }\n\n  &__developer {\n    color: $dark-03;\n  }\n\n  &__description {\n    font-size: 18px;\n    line-height: 24px;\n    font-style: normal;\n    font-weight: normal;\n    max-width: 424px;\n    min-height: 48px;\n    margin-top: 24px;\n    margin-bottom: 48px;\n    @media (min-width: 1200px) and (max-width: 1400px) {\n      max-width: 400px;\n    }\n    @media (min-width: 767.98px) and (max-width: 1200px) {\n      max-width: 290px;\n    }\n    @media (max-width: 767.98px) {\n      margin-bottom: 16px;\n      margin-top: 16px;\n    }\n  }\n\n  &__achievement {\n    position: absolute;\n    right: 32px;\n    top: 32px;\n    @media (max-width: 767.98px) {\n      right: 0;\n      top: 0;\n      transform: scale3d(0.5, 0.5, 0.5);\n    }\n\n    &__icon {\n      width: 104px;\n      height: 104px;\n    }\n  }\n}\n\n.features {\n  color: $dark-03;\n  font-size: 12px;\n  line-height: 15px;\n  padding-bottom: 5px;\n  min-width: 94px;\n  margin-right: 40px;\n  &__text {\n    text-transform: capitalize;\n    font-size: 16px;\n    font-weight: 500;\n  }\n  @media (max-width: 1400px) {\n    margin-right: 20px;\n  }\n  @media (max-width: 767.98px) {\n    margin-right: 40px;\n  }\n}\n.github {\n  display: flex;\n  align-items: center;\n  .icon {\n    width: 16px;\n    height: 16px;\n    margin-right: 5px;\n  }\n}\n.language {\n  display: flex;\n  align-items: center;\n  &__wrapper {\n    display: flex;\n    align-items: center;\n  }\n  .icon {\n    width: 16px;\n    height: 16px;\n    display: flex;\n    align-items: center;\n    margin-right: 5px;\n  }\n}\n.framework {\n  display: flex;\n  align-items: center;\n  &__wrapper {\n    display: flex;\n    align-items: center;\n    @media (max-width: 767.98px) {\n      margin-bottom: 8px;\n    }\n  }\n  .icon {\n    width: 16px;\n    height: 16px;\n    display: flex;\n    align-items: center;\n    margin-right: 5px;\n  }\n}\n\n.toolCard[shadow=\"well-documented\"] {\n  box-shadow: 16px 24px 80px rgba(255, 133, 95, 0.3);\n  &:hover {\n    box-shadow: 16px 24px 80px rgba(255, 133, 95, 0.5);\n  }\n}\n.toolCard[shadow=\"easy-to-start-with\"] {\n  box-shadow: -16px 24px 80px rgba(66, 204, 173, 0.3);\n  &:hover {\n    box-shadow: -16px 24px 80px rgba(66, 204, 173, 0.5);\n  }\n}\n.toolCard[shadow=\"full-fledged\"] {\n  box-shadow: 0px 24px 80px rgba(255, 124, 226, 0.4);\n  &:hover {\n    box-shadow: 0px 24px 80px rgba(255, 124, 226, 0.5);\n  }\n}\n.toolCard[shadow=\"easy-to-customize\"] {\n  box-shadow: 0px 24px 80px rgba(115, 159, 243, 0.4);\n  &:hover {\n    box-shadow: 0px 24px 80px rgba(115, 159, 243, 0.5);\n  }\n}\n.toolCard[shadow=\"very-popular\"] {\n  box-shadow: 0px 24px 80px rgba(255, 194, 123, 0.4);\n  &:hover {\n    box-shadow: 0px 24px 80px rgba(255, 194, 123, 0.5);\n  }\n}\n.toolCard[shadow=\"gray\"] {\n  box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.3);\n  &:hover {\n    box-shadow: 0px 8px 32px rgba(194, 194, 218, 0.5);\n  }\n}\n"
  },
  {
    "path": "components/ToolCard/index.js",
    "content": "import ToolCard from \"./ToolCard\";\nexport default ToolCard;\n"
  },
  {
    "path": "components/ToolPage/Description.jsx",
    "content": "import styles from \"./Description.module.scss\";\n\nexport default function Description(props) {\n  return (\n    <div className={styles.description}>\n      <div className={styles.description__text}>{props.description}</div>\n      {props.based && (\n        <div className={styles.based}>\n          <span>Based on</span>\n          {props.based.map((tag) => (\n            <span key={tag} className={styles.based__tag}>\n              {tag}\n            </span>\n          ))}\n        </div>\n      )}\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/ToolPage/Description.module.scss",
    "content": "@import \"/styles/variables\";\n\n.description {\n  margin-top: 24px;\n  &__text {\n    font-size: 22px;\n    line-height: 28px;\n    color: $dark;\n    font-style: normal;\n    font-weight: normal;\n  }\n}\n.based {\n  display: flex;\n  align-items: center;\n  color: $dark-03;\n  font-size: 16px;\n  line-height: 20px;\n  margin-top: 24px;\n\n  &__tag {\n    margin-left: 8px;\n    color: #8381ee;\n  }\n}\n"
  },
  {
    "path": "components/ToolPage/DescriptionCards.jsx",
    "content": "import styles from \"./DescriptionCards.module.scss\";\nimport Card from \"../Card/Card\";\n\nconst getLicense = (props) => {\n  let isOpen = false;\n  let isPrice = false;\n  let smallText = \"\";\n  let icon = \"/images/logo/proprietary.svg\";\n  let link = props?.links?.pricing;\n\n  props?.licenses?.forEach((obj) => {\n    if (obj.type === \"open-source\") {\n      isOpen = true;\n      smallText = obj.title;\n      link = obj.link;\n      icon = \"/images/logo/open-source.svg\";\n    } else {\n      isPrice = true;\n      link = obj.link;\n    }\n  });\n\n  if (isOpen && isPrice) {\n    return {\n      icons: [\"/images/logo/proprietary.svg\", \"/images/logo/open-source.svg\"],\n      text: \"Open-source and proprietary licenses\",\n      link: props?.links?.pricing || link,\n      smallText: props?.links?.pricing ? \"Priсing page →\" : \"License →\",\n    };\n  }\n  if (isOpen) {\n    return {\n      text: \"Open-source license\",\n      smallText: `${smallText} →`,\n      link,\n      icon,\n    };\n  }\n  if (isPrice) {\n    return {\n      text: \"Proprietary license\",\n      link: props?.links?.pricing || link,\n      smallText: props?.links?.pricing ? \"Priсing page →\" : \"License →\",\n      icon,\n    };\n  }\n};\n\nconst getFrameworks = (props) => {\n  if (props?.frameworks?.length === 1) {\n    let fr = props.frameworks[0];\n    return {\n      icon: `/images/logo/${fr.toLowerCase()}.svg`,\n      text: `${fr === 'vanilla-js' ? 'Vanilla JS' : capitalizeFirstLetter(fr)} only`,\n      link: `https://github.com/${props.slugs.github}`,\n      smallText: `GitHub repository →`,\n    };\n  }\n\n  let frameworksOnly = props.frameworks.filter((fr) => fr !== \"vanilla-js\");\n\n  return {\n    text: frameworksOnly.map((s, index) => {\n      return (\n        <span key={s}>\n          {capitalizeFirstLetter(s)}\n          {index === frameworksOnly.length - 1 ? \" \" : \", \"}\n        </span>\n      );\n    }),\n    icons: props.frameworks.map((fr) => `/images/logo/${fr}.svg`),\n    smallText: `GitHub repository →`,\n    link: `https://github.com/${props.slugs.github}`,\n  };\n};\n\nconst getLanguage = (languages, slugs) => {\n  let hasTS = languages.includes(\"TypeScript\");\n  let hasDT = slugs.npm_types !== undefined\n\n  let icon = \"/images/logo/javascript.svg\";\n  let text = \"JavaScript only\";\n  let smallText = \"No TypeScript support\";\n  let color = \"orange\";\n  let link = undefined;\n\n  if (hasTS) {\n    icon = \"/images/logo/typescript.svg\";\n    text = \"TypeScript support\";\n    smallText = hasDT ? \"DefinitelyTyped definitions →\" : \"*.d.ts files →\";\n    color = \"gray\";\n    link = hasDT ? `https://www.npmjs.com/package/${slugs.npm_types}` : `https://github.com/search?q=repo%3A${encodeURIComponent(slugs.github)}+filename%3A.d.ts&type=Code`;\n  }\n\n  return {\n    icon,\n    text,\n    smallText,\n    color,\n    link,\n  };\n};\n\nexport default function DescriptionCards(props) {\n  return (\n    <div className={styles.descriptionCards + \" row\"}>\n      {props.licenses && (\n        <div className={styles.cardWrap + \" col-xl-4 col-lg-4 col-md-12\"}>\n          <Card height=\"full\" {...getLicense(props)} />\n        </div>\n      )}\n      {props.frameworks && props.slugs.github && (\n        <div className={styles.cardWrap + \" col-xl-4 col-lg-4 col-md-12\"}>\n          <Card height=\"full\" color=\"gray\" {...getFrameworks(props)} />\n        </div>\n      )}\n      {props.languages && (\n        <div className={styles.cardWrap + \" col-xl-4 col-lg-4 col-md-12\"}>\n          <Card height=\"full\" {...getLanguage(props.languages, props.slugs)} />\n        </div>\n      )}\n    </div>\n  );\n}\n\nfunction capitalizeFirstLetter(string) {\n  return string.charAt(0).toUpperCase() + string.slice(1);\n}\n"
  },
  {
    "path": "components/ToolPage/DescriptionCards.module.scss",
    "content": ".descriptionCards {\n  margin-top: 40px;\n  display: flex;\n  margin-bottom: 104px;\n  @media (max-width: 767.98px) {\n    margin-bottom: 48px;\n  }\n}\n.cardWrap {\n  @media (max-width: 991.98px) {\n    margin-bottom: 16px;\n  }\n}\n"
  },
  {
    "path": "components/ToolPage/Header.jsx",
    "content": "import styles from \"./Header.module.scss\";\nimport Button from \"../Button\";\n\nexport default function Header(props) {\n  return (\n    <div className={styles.header}>\n      <div className={styles.title}>\n        <img\n          className={styles.title__img}\n          src={`/images/logo/${props.logo}`}\n          alt={`${props.title} logo`}\n        />\n        <h1 className={styles.title__text}>\n          {props.title}\n          {props.developer && (\n            <span className={styles.title__developer}>\n              &nbsp;by&nbsp;{props.developer}\n            </span>\n          )}\n          {props.framework && (\n            <span className={styles.title__framework}>\n              &nbsp;for&nbsp;{props.framework}&nbsp;developers\n            </span>\n          )}\n        </h1>\n        {props.achievement && (\n          <div>\n            <img\n              className={styles.achievement}\n              src={`/images/${props.achievement}.svg`}\n              alt=\"tool label\"\n            />\n          </div>\n        )}\n      </div>\n      <div className={styles.buttons}>\n        {props.github && (\n          <Button target=\"_blank\" href={`https://github.com/${props.github}`}>\n            GitHub\n          </Button>\n        )}\n        {props.website && (\n          <Button target=\"_blank\" href={props.website}>\n            Website\n          </Button>\n        )}\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/ToolPage/Header.module.scss",
    "content": "@import \"/styles/variables\";\n\n.header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  @media (max-width: 767.98px) {\n    flex-direction: column;\n  }\n}\n.title {\n  display: flex;\n  position: relative;\n  @media (max-width: 767.98px) {\n    flex-wrap: wrap;\n    margin-bottom: 16px;\n    width: 100%;\n  }\n  &__img {\n    border: 1px solid rgba(213, 213, 226, 0.5);\n    border-radius: 24px;\n    width: 77px;\n    height: 77px;\n  }\n  &__text {\n    display: flex;\n    align-items: center;\n    margin: 0 0 0 16px;\n    font-size: 40px;\n    line-height: 40px;\n    color: $dark;\n  }\n  &__developer {\n    color: $dark-03;\n  }\n  &__framework {\n    color: $dark-03;\n  }\n}\n.buttons {\n  display: flex;\n  a:first-child {\n    margin-right: 8px;\n  }\n}\n\n.achievement {\n  margin-top: -56px;\n  @media (max-width: 767.98px) {\n    position: absolute;\n    top: -56px;\n    right: 0;\n    margin: 0;\n    // margin: 0;\n    transform: scale3d(0.5, 0.5, 0.5);\n  }\n  // height: 104px;\n  // width: 104px;\n}\n"
  },
  {
    "path": "components/ToolPage/HowToGetHelp.jsx",
    "content": "import styles from \"./HowToGetHelp.module.scss\";\nimport GetHelpCard from \"../GetHelpCard\";\nimport H2 from \"../Text/H2\";\nimport abbreviateNumber from \"../../utils/number\";\n\nexport default function HowToGetHelp(props) {\n  const cards = [\n    {\n      href: props.links.slack,\n      title: `${props.name} Slack →`,\n      icon: \"/images/logo/slack-big.svg\",\n    },\n    {\n      href: props.links.docs,\n      title: `${props.name} docs →`,\n      icon: `/images/logo/${props.logo}`,\n    },\n    {\n      href: props.stackoverflow,\n      title: \"Stack Overflow →\",\n      icon: \"/images/logo/stackoverflow-64.svg\",\n      footer: `${abbreviateNumber(\n        props?.stackoverflow_data?.questions_count\n      )} questions`,\n    },\n    {\n      href: \"https://slack.cube.dev/\",\n      title: \"Cube Slack →\",\n      icon: \"/images/logo/slack-big.svg\",\n      footer: `${abbreviateNumber(props.slackMembers)} followers`,\n    },\n  ];\n  return (\n    <div className={styles.HowToGetHelp}>\n      <div className=\"row mb-md\">\n        <div className={styles.textWrap + \" col-lg-3\"}>\n          <H2>\n            How to\n            <br />\n            Get Help\n          </H2>\n        </div>\n        {cards\n          .filter((card) => card.href)\n          .map((card, index) => {\n            let className = \" col-lg-4\";\n            // if (index === 0) {\n            //   className = \"col-lg-4\";\n            // }\n            if (index === 1) {\n              className = \" col-lg-5\";\n            }\n            if (index === 2) {\n              className = \" col-lg-5 offset-lg-3\";\n            }\n            // let className = \" col-lg-5\";\n            // if (index % 2 === 0 && index !== 0) {\n            //   className = \" col-lg-5 offset-lg-3\";\n            // }\n            // if (index % 2 !== 0) {\n            //   className = \" col-lg-4\";\n            // }\n            return card.href ? (\n              <div key={card.title} className={styles.cardWrap + className}>\n                <GetHelpCard {...card} />\n              </div>\n            ) : null;\n          })}\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/ToolPage/HowToGetHelp.module.scss",
    "content": ".HowToGetHelp {\n  margin-bottom: 104px;\n  @media (max-width: 767.98px) {\n    margin-bottom: 48px;\n  }\n}\n.cardWrap {\n  margin-bottom: 26px;\n  @media (max-width: 991.98px) {\n    margin-bottom: 24px;\n  }\n}\n.textWrap {\n  @media (max-width: 991.98px) {\n    margin-bottom: 24px;\n  }\n}\n"
  },
  {
    "path": "components/ToolPage/HowToGetStarted.jsx",
    "content": "import styles from \"./HowToGetStarted.module.scss\";\nimport GetStartedCard from \"../GetStartedCard\";\nimport H2 from \"../Text/H2\";\n\nexport default function HowToGetStarted(props) {\n  return (\n    <div className={styles.HowToGetStarted + \" row\"}>\n      <div className=\"col-sm-3\">\n        <H2>\n          How to\n          <br />Get Started\n        </H2>\n      </div>\n      {props.content.map((obj, index) => {\n        const icon =\n          obj.type === \"official\"\n            ? \"/images/logo/official.svg\"\n            : \"/images/logo/cubejs-big.svg\";\n          \n        const className =\n          styles.cardWrap + \" \" +\n          (index === 0 ? \"col-sm-5\" : \"col-sm-4\") +\n          (index !== 0 && index % 2 === 0 ? \" offset-lg-3\" : \"\");\n\n        return (\n          <div key={index} className={className}>\n            <GetStartedCard\n              icon={icon}\n              type={obj.type === \"official\" ? \"Official tutorial\" : \"Community guide\"}\n              title={obj.title}\n              link={obj.link}\n            />\n          </div>\n        );\n      })}\n\n      {/* <div className=\"col-sm-4\">\n        <GetStartedCard />\n      </div> */}\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/ToolPage/HowToGetStarted.module.scss",
    "content": ".HowToGetStarted {\n  margin-bottom: 104px;\n}\n.cardWrap {\n  margin-bottom: 26px;\n  @media (max-width: 991.98px) {\n    margin-bottom: 24px;\n  }\n}"
  },
  {
    "path": "components/ToolPage/Integrations.jsx",
    "content": "import styles from \"./Integrations.module.scss\";\nimport Card from \"../Card/Card\";\nimport H2 from \"../Text/H2\";\nimport frameworks from '../../data/frameworks';\n\nexport default function Integrations(props) {\n  const integrations = props.integrations || [ props.integration ]\n\n  return (\n    <div className={styles.integration + \" row\"}>\n      <div className=\"col-lg-3\">\n        <H2>\n          {props.integration ? frameworks[props.integration.framework].name : \"Framework\"} Support\n        </H2>\n      </div>\n      <div className={styles.cards + \" col-lg-9 row\"}>\n        {integrations.map(integration => {\n          const framework = frameworks[integration.framework]\n          const link = integration.links?.website\n            ? integration.links.website\n            : `https://github.com/${integration.slugs.github}`;\n\n          return (\n            <div className={styles.cardWrap + (props.integration ? \" col-xl-12 col-lg-12 col-md-12\" : \" col-xl-6 col-lg-6 col-md-12\")}>\n              <Card\n                key={integration.framework}\n                link={link}\n                icon={`/images/logo/${framework.icon}`}\n                text={integration.slugs.npm}\n                smallText={`${framework.name} components`}\n              />\n            </div>\n          );\n        })}\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/ToolPage/Integrations.module.scss",
    "content": ".integration {\n  margin-bottom: 104px;\n  @media (max-width: 767.98px) {\n    margin-bottom: 48px;\n  }\n}\n.cards {\n  display: flex;\n}\n.cardWrap {\n  margin-bottom: 24px;\n}"
  },
  {
    "path": "components/ToolPage/Popularity.jsx",
    "content": "import styles from \"./Popularity.module.scss\";\nimport Card from \"../Card/Card\";\nimport H2 from \"../Text/H2\";\nimport dayjs from \"dayjs\";\nimport abbreviateNumber from \"../../utils/number\";\n\nexport default function Popularity(props) {\n  return (\n    <div className={styles.popularity + \" row\"}>\n      <div className=\"col-lg-3\">\n        <H2>\n          Popularity\n          <br />& Relevance\n        </H2>\n      </div>\n      <div className={styles.bigCardWrap + \" col-lg-3\"}>\n        <Card\n          isBig={true}\n          link={`https://github.com/${props?.slugs?.github}/stargazers`}\n          color={\n            props?.positions?.stars / props?.positions?.total > 0.67\n              ? \"orange\"\n              : null\n          }\n          icon=\"/images/logo/github-big.svg\"\n          text={abbreviateNumber(props?.github?.stars) || 0}\n          description=\"GitHub stars\"\n          footerText={`${props?.positions?.stars} of ${props?.positions?.total} place`}\n        />\n      </div>\n      <div className={styles.bigCardWrap + \" col-lg-3\"}>\n        <Card\n          isBig={true}\n          color={props?.percentages?.stale_issues > 50 ? \"orange\" : null}\n          link={`https://github.com/${props?.slugs?.github}/issues`}\n          icon=\"/images/edit.svg\"\n          text={props?.github?.issues}\n          description=\"open issues\"\n          footerText={`${props?.percentages?.stale_issues?.toFixed(\n            0\n          )}&thinsp;% older than 1 year`}\n        />\n      </div>\n      <div className={styles.smallCardWrap + \" col-lg-3\"}>\n        <Card\n          link={`https://github.com/${props?.slugs?.github}/graphs/contributors`}\n          className=\"mb-md\"\n          color=\"gray\"\n          text={abbreviateNumber(props?.github?.contributors)}\n          description=\"contributors\"\n        />\n        {props?.github?.last_release?.date && (\n          <Card\n            link={props?.github?.last_release?.link}\n            color=\"gray\"\n            text={\n              dayjs(props?.github?.last_release?.date).format(\n                \"MMM DD, YYYY\"\n              ) || \"-\"\n            }\n            description=\"last release date\"\n          />\n        )}\n      </div>\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/ToolPage/Popularity.module.scss",
    "content": ".popularity {\n  margin-bottom: 104px;\n  @media (max-width: 767.98px) {\n    margin-bottom: 48px;\n  }\n}\n.bigCardWrap {\n  @media (max-width: 991.98px) {\n    margin-top: 24px;\n  }\n}\n.smallCardWrap {\n  @media (max-width: 991.98px) {\n    margin-top: 24px;\n  }\n}\n"
  },
  {
    "path": "components/ToolPage/ToolPage.jsx",
    "content": "import React from \"react\";\nimport dynamic from \"next/dynamic\";\nimport { NextSeo } from 'next-seo';\nimport Header from \"./Header\";\nimport Description from \"./Description\";\nimport DescriptionCards from \"./DescriptionCards\";\n\nimport useSlackMembers from \"../../data/useSlackMembers\";\nimport types from '../../data/types';\nimport Integrations from './Integrations';\n\nconst Gallery = dynamic(() => import(\"../Gallery\"));\nconst Popularity = dynamic(() => import(\"./Popularity\"));\nconst HowToGetStarted = dynamic(() => import(\"./HowToGetStarted\"));\nconst HowToGetHelp = dynamic(() => import(\"./HowToGetHelp\"));\n\nexport default function ToolPage(props) {\n  const type = types[props.types[0]];\n  const slackMembers = useSlackMembers();\n\n  return (\n    <>\n      <NextSeo\n        title={`${props.title} — ${type.descriptor}`}\n        description={`${props.title} examples, tutorials, compatibility, and popularity`}\n      />\n\n      <div className=\"container custom-container mt-lg\">\n        <main>\n          <Header\n            logo={props.logo}\n            title={props.title}\n            developer={props.developer}\n            website={props?.links?.website}\n            github={props?.slugs?.github}\n            achievement={props?.feature_label}\n          />\n          <Description based={props.based_on} description={props.description} />\n          <DescriptionCards\n            licenses={props.licenses}\n            frameworks={props.frameworks}\n            languages={props.languages}\n            links={props.links}\n            slugs={props.slugs}\n          />\n          {props.gallery && props.gallery.length !== 0 && (\n            <Gallery gallery={props.gallery} link={props?.links?.examples} />\n          )}\n          {props.github_data && (\n            <Popularity\n              slugs={props.slugs}\n              github={props.github_data}\n              positions={props.positions}\n              percentages={props.percentages}\n            />\n          )}\n          {props.integrations?.length > 0 && (\n            <Integrations integrations={props.integrations} />\n          )}\n          {props.content && props.content.length > 0 && (\n            <HowToGetStarted content={props.content} />\n          )}\n          <HowToGetHelp\n            slackMembers={slackMembers}\n            logo={props.logo}\n            name={props.title}\n            links={props.links}\n            positions={props.positions}\n            stackoverflow={\n              props?.tags?.stackoverflow\n                ? `https://stackoverflow.com/questions/tagged/${encodeURIComponent(\n                  props?.tags?.stackoverflow.join(\" or \"),\n                )}`\n                : null\n            }\n            stackoverflow_data={props.stackoverflow_data}\n          />\n        </main>\n      </div>\n    </>\n  );\n}"
  },
  {
    "path": "components/ToolPage/ToolPageForFramework.jsx",
    "content": "import React from \"react\";\nimport dynamic from \"next/dynamic\";\nimport { NextSeo } from 'next-seo';\nimport Header from \"./Header\";\nimport Description from \"./Description\";\nimport DescriptionCards from \"./DescriptionCards\";\n\nimport useSlackMembers from \"../../data/useSlackMembers\";\nimport frameworks from '../../data/frameworks';\nimport types from '../../data/types';\nimport Integrations from './Integrations';\n\nconst Gallery = dynamic(() => import(\"../Gallery\"));\nconst Popularity = dynamic(() => import(\"./Popularity\"));\nconst HowToGetStarted = dynamic(() => import(\"./HowToGetStarted\"));\nconst HowToGetHelp = dynamic(() => import(\"./HowToGetHelp\"));\n\nexport default function ToolPageForFramework(props) {\n  const type = types[props.types[0]];\n  const framework = frameworks[props.framework];\n  const integration = props.integrations?.find(i => i.framework === props.framework);\n  const slackMembers = useSlackMembers();\n\n  return (\n    <>\n      <NextSeo\n        title={`${props.title} — ${type.descriptor} for ${framework.name} developers`}\n        description={`${props.title} support in ${framework.name}${integration && ` with ${integration.slugs.npm}`}, examples, tutorials, compatibility, and popularity`}\n      />\n\n      <div className=\"container custom-container mt-lg\">\n        <main>\n          <Header\n            logo={props.logo}\n            title={props.title}\n            framework={framework.name}\n            developer={props.developer}\n            website={props?.links?.website}\n            github={props?.slugs?.github}\n            achievement={props?.feature_label}\n          />\n          <Description description={props.description} />\n          <DescriptionCards\n            licenses={props.licenses}\n            frameworks={props.frameworks}\n            languages={props.languages}\n            links={props.links}\n            slugs={props.slugs}\n          />\n          {integration && (\n            <Integrations integration={integration} />\n          )}\n          {props.gallery && props.gallery.length !== 0 && (\n            <Gallery gallery={props.gallery} link={props?.links?.examples} />\n          )}\n          {props.github_data && (\n            <Popularity\n              slugs={props.slugs}\n              github={props.github_data}\n              positions={props.positions}\n              percentages={props.percentages}\n            />\n          )}\n          {props.content && props.content.length > 0 && (\n            <HowToGetStarted content={props.content} />\n          )}\n          <HowToGetHelp\n            slackMembers={slackMembers}\n            logo={props.logo}\n            name={props.title}\n            links={props.links}\n            positions={props.positions}\n            stackoverflow={\n              props?.tags?.stackoverflow\n                ? `https://stackoverflow.com/questions/tagged/${encodeURIComponent(\n                  props?.tags?.stackoverflow.join(\" or \"),\n                )}`\n                : null\n            }\n            stackoverflow_data={props.stackoverflow_data}\n          />\n        </main>\n      </div>\n    </>\n  );\n}"
  },
  {
    "path": "components/ToolsNumberControl/ToolsNumberControl.jsx",
    "content": "import styles from \"./ToolsNumberControl.module.scss\";\nimport { ReactSVG } from \"react-svg\";\nexport default function ToolsNumberControl(props) {\n  let text = \"awesome tools — and counting!\";\n  if (props.isChanged) {\n    text = props.filteredTools.length === 1\n      ? \"awesome tool matching your criteria\"\n      : \"awesome tools matching your criteria\";\n  }\n  return (\n    <div className={styles.toolsControl}>\n      <div className={styles.toolsControl__text}>\n        {props.filteredTools.length}&nbsp;{text}\n      </div>\n      {props.isChanged !== 0 && (\n        <button\n          className={styles.toolsControl__button}\n          role=\"button\"\n          onClick={props.clearFilters}\n        >\n          <span>Clear filter</span>\n          <ReactSVG\n            wrapper=\"span\"\n            className={styles.clear}\n            src=\"/images/clear.svg\"\n          />\n        </button>\n      )}\n    </div>\n  );\n}\n"
  },
  {
    "path": "components/ToolsNumberControl/ToolsNumberControl.module.scss",
    "content": "@import \"/styles/variables\";\n\n.toolsControl {\n  min-height: 34px;\n  display: flex;\n  align-items: center;\n  @media (max-width: 767.98px) {\n    align-items: flex-start;\n    flex-direction: column;\n  }\n\n  &__button {\n    cursor: pointer;\n    display: flex;\n    align-items: center;\n    font-family: CeraPro;\n    margin-left: 16px;\n    padding: 0px 12px;\n    background: rgba(255, 193, 211, 0.24);\n    border-radius: 20px;\n    border: none;\n    font-size: 20px;\n    line-height: 30px;\n    color: $pink-hover;\n\n    @media (max-width: 767.98px) {\n      margin-top: 4px;\n      margin-left: 0;\n      padding: 0px 8px;\n      font-size: 16px;\n    }\n  }\n\n  &__text {\n    font-size: 20px;\n    line-height: 30px;\n    color: $dark-03;\n    white-space: nowrap;\n\n    @media (max-width: 767.98px) {\n      font-size: 16px;\n    }\n  }\n}\n.clear {\n  margin-left: 8px;\n}\n"
  },
  {
    "path": "components/ToolsNumberControl/index.js",
    "content": "import ToolsNumberControl from \"./ToolsNumberControl\";\nexport default ToolsNumberControl;\n"
  },
  {
    "path": "copy/tools/.example",
    "content": "title: AG Grid\ndescription: Self-proclaimed best JavaScript grid in the world\nlogo: ag-grid.svg\ndeveloper: Google\n\nbased_on:\n  - d3\n\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: https://github.com/apache/echarts/blob/master/LICENSE\n\ntypes:\n  - 3d\n  - app\n  - charts\n  - grid\n  - low-level\n  - maps\n\nrenders:\n  - svg\n  - html\n  - canvas\n\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\n\ngallery:\n  - /images/slider/reaflow-1.png\n  - /images/slider/reaflow-2.png\n  - /images/slider/reaflow-3.png\n  - /images/slider/reaflow-4.png\n  - /images/slider/reaflow-5.png\n\nlanguages:\n  - JavaScript\n  - TypeScript\n\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\n  - svelte\n\nslugs:\n  github: ag-grid/ag-grid\n  npm: ag-grid-community\n  npm_types: \"@types/mapbox-gl\"\n\ntags:\n  stackoverflow:\n    - ag-grid\n    - aggrid\n  twitter:\n    - aggrid\n    - ag_grid\n\nlinks:\n  website: https://www.ag-grid.com\n  examples: https://www.ag-grid.com/example.php\n  docs: https://www.ag-grid.com/javascript-grid/\n  pricing: null\n  slack: https://slack.example.com\n\ncontent:\n  - type: official\n    title: \"JavaScript Grid: Get Started with AG Grid\"\n    link: https://www.ag-grid.com/javascript-grid/getting-started/\n  - type: cube\n    title: React Pivot Table with AG Grid and Cube.js\n    link: https://react-pivot-table.cube.dev\n\ngithub_data:\n  stars: 7200\n  contributors: 84\n  issues: 17\n  stale_issues: 0\n  last_release:\n    date: \"2021-04-30T00:00:00Z\"\n    link: https://github.com/ag-grid/ag-grid/releases/tag/v25.2.0\n\nstackoverflow_data:\n  questions_count: 37620"
  },
  {
    "path": "copy/tools/.extended.example",
    "content": "# Everything from .example and also the following fields\n\npositions:\n  total: 45\n  stars: 3\n\npercentages:\n  stale_issues: 32"
  },
  {
    "path": "copy/tools/ag-grid.yml",
    "content": "title: AG Grid\ndescription: Self-proclaimed best JavaScript grid in the world\nlogo: ag-grid.svg\nbased_on: null\nlicenses:\n  - type: proprietary\n  - type: open-source\n    title: MIT\ntypes:\n  - grid\nrenders:\n  - html\nfeatures:\n  easy-to-customize: 1\n  easy-to-start-with: 0\n  full-fledged: 1\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/ag-grid-1.png\n  - /images/slider/ag-grid-2.png\n  - /images/slider/ag-grid-3.png\n  - /images/slider/ag-grid-5.png\n  - /images/slider/ag-grid-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\nslugs:\n  github: ag-grid/ag-grid\n  npm: ag-grid-community\ntags:\n  stackoverflow:\n    - ag-grid\n  twitter:\n    - aggrid\n    - ag_grid\nlinks:\n  website: 'https://www.ag-grid.com'\n  examples: 'https://www.ag-grid.com/example.php'\n  docs: 'https://www.ag-grid.com/javascript-grid/'\n  pricing: 'https://www.ag-grid.com/license-pricing.php'\n  slack: null\ncontent:\n  - type: official\n    title: 'JavaScript Grid: Get Started with AG Grid'\n    link: 'https://www.ag-grid.com/javascript-grid/getting-started/'\n  - type: cube\n    title: React Pivot Table with AG Grid and Cube.js\n    link: 'https://react-pivot-table.cube.dev'\ngithub_data:\n  stars: 13513\n  contributors: 193\n  issues: 39\n  stale_issues: 1\n  last_release:\n    date: '2025-02-20T08:36:33Z'\n    link: 'https://github.com/ag-grid/ag-grid/releases/tag/v33.1.1'\nstackoverflow_data:\n  questions_count: 5142\n"
  },
  {
    "path": "copy/tools/amcharts.yml",
    "content": "title: amCharts\ndescription: JavaScript charts & maps for all data visualization needs\nlogo: amcharts.svg\nbased_on: null\nlicenses:\n  - type: proprietary\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 1\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/amcharts-1.png\n  - /images/slider/amcharts-2.png\n  - /images/slider/amcharts-3.png\n  - /images/slider/amcharts-4.png\n  - /images/slider/amcharts-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: amcharts/amcharts4\n  npm: '@amcharts/amcharts4'\ntags:\n  stackoverflow:\n    - amcharts\n    - amcharts4\n  twitter:\n    - amcharts\n    - amcharts4\nlinks:\n  website: 'https://www.amcharts.com'\n  examples: 'https://www.amcharts.com/demos/'\n  docs: 'https://www.amcharts.com/docs/v4/'\n  pricing: 'https://www.amcharts.com/online-store/'\n  slack: null\ncontent:\n  - type: official\n    title: Starting from Basics of amCharts 4\n    link: 'https://www.amcharts.com/docs/v4/getting-started/basics/'\ngithub_data:\n  stars: 1157\n  contributors: 6\n  issues: 31\n  stale_issues: 30\n  last_release:\n    date: '2024-06-18T09:36:19Z'\n    link: 'https://github.com/amcharts/amcharts4/releases/tag/4.10.39'\nstackoverflow_data:\n  questions_count: 3221\n"
  },
  {
    "path": "copy/tools/ant-design-charts.yml",
    "content": "title: Ant Design Charts\ndescription: 'React charting library, based on G2Plot, G6, X6, L7'\nlogo: antv.svg\ndeveloper: AntV\nbased_on:\n  - g2plot\n  - g6\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/ant-design/ant-design-charts/blob/master/LICENSE'\ntypes:\n  - charts\n  - maps\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 1\n  very-popular: 0\n  well-documented: 1\ngallery:\n  - /images/slider/ant-design-charts-1.png\n  - /images/slider/ant-design-charts-2.png\n  - /images/slider/ant-design-charts-3.png\n  - /images/slider/ant-design-charts-4.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - react\nslugs:\n  github: ant-design/ant-design-charts\n  npm: '@an-design/charts'\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'https://charts.ant.design/en'\n  examples: 'https://charts.ant.design/en/examples/gallery'\n  docs: 'https://charts.ant.design/en/docs/manual/introduction'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Quick Start\n    link: 'https://charts.ant.design/en/docs/manual/getting-started'\ngithub_data:\n  stars: 2001\n  contributors: 72\n  issues: 336\n  stale_issues: 156\n  last_release:\n    date: '2024-12-13T09:23:24Z'\n    link: 'https://github.com/ant-design/ant-design-charts/releases/tag/2.2.5'\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/anychart.yml",
    "content": "title: AnyChart\ndescription: Interactive JavaScript charts\nlogo: anychart.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: proprietary\n    link: 'https://www.anychart.com/support/pages/faq/'\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/anychart-1.png\n  - /images/slider/anychart-2.png\n  - /images/slider/anychart-3.png\n  - /images/slider/anychart-4.png\n  - /images/slider/anychart-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\nslugs:\n  github: AnyChart/AnyChart\n  npm: anychart\ntags:\n  stackoverflow:\n    - anychart\n  twitter:\n    - AnyChart\nlinks:\n  website: 'https://www.anychart.com'\n  examples: 'https://www.anychart.com/products/anychart/gallery/'\n  docs: 'https://www.anychart.com/products/anychart/docs/'\n  pricing: 'https://www.anychart.com/buy/'\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started with AnyChart\n    link: 'https://github.com/AnyChart/AnyChart#getting-started'\n  - type: official\n    title: Chartopedia\n    link: 'https://www.anychart.com/chartopedia/usage-type/'\ngithub_data:\n  stars: 383\n  contributors: 21\n  issues: 18\n  stale_issues: 13\n  last_release:\n    date: '2024-09-25T05:29:05Z'\n    link: 'https://github.com/AnyChart/AnyChart/releases/tag/v8.13.0'\nstackoverflow_data:\n  questions_count: 474\n"
  },
  {
    "path": "copy/tools/apexcharts.yml",
    "content": "title: ApexCharts\ndescription: Modern & interactive open-source charts\nlogo: apexcharts.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/apexcharts/apexcharts.js/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/apexcharts-1.png\n  - /images/slider/apexcharts-2.png\n  - /images/slider/apexcharts-3.png\n  - /images/slider/apexcharts-4.png\n  - /images/slider/apexcharts-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\n  - svelte\nslugs:\n  github: apexcharts/apexcharts.js\n  npm: apexcharts\ntags:\n  stackoverflow:\n    - apexcharts\n  twitter:\n    - ApexCharts\nlinks:\n  website: 'https://apexcharts.com'\n  examples: 'https://apexcharts.com/javascript-chart-demos/'\n  docs: 'https://apexcharts.com/docs/installation/'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Creating your first JavaScript chart\n    link: 'https://apexcharts.com/docs/creating-first-javascript-chart/'\ngithub_data:\n  stars: 14647\n  contributors: 224\n  issues: 297\n  stale_issues: 218\n  last_release:\n    date: '2025-02-19T11:09:43Z'\n    link: 'https://github.com/apexcharts/apexcharts.js/releases/tag/v4.5.0'\nstackoverflow_data:\n  questions_count: 1087\n"
  },
  {
    "path": "copy/tools/appsmith.yml",
    "content": "title: Appsmith\ndescription: Low-code tool for building internal apps using pre-built UI widgets\nlogo: appsmith.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/appsmithorg/appsmith/blob/release/LICENSE'\ntypes:\n  - app\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/appsmith-1.png\n  - /images/slider/appsmith-2.png\n  - /images/slider/appsmith-3.png\n  - /images/slider/appsmith-5.png\n  - /images/slider/appsmith-5.png\nlanguages: null\nframeworks: null\nslugs:\n  github: appsmithorg/appsmith\n  npm: null\n  npm_types: null\ntags:\n  stackoverflow:\n    - appsmith\n  twitter:\n    - appsmith\nlinks:\n  website: 'https://www.appsmith.com'\n  examples: 'https://www.appsmith.com/widgets'\n  docs: 'https://docs.appsmith.com/'\n  pricing: 'https://www.appsmith.com/pricing'\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://docs.appsmith.com/#getting-started-with-appsmith'\n  - type: cube\n    title: Building an Appsmith Dashboard with Cube\n    link: 'https://cube.dev/blog/building-an-appsmith-dashboard-with-cube'\ngithub_data:\n  stars: 35807\n  contributors: 366\n  issues: 4138\n  stale_issues: 2524\n  last_release:\n    date: '2025-02-19T09:48:52Z'\n    link: 'https://github.com/appsmithorg/appsmith/releases/tag/v1.62'\nstackoverflow_data:\n  questions_count: 27\n"
  },
  {
    "path": "copy/tools/billboard.yml",
    "content": "title: Billboard.js\ndescription: 'Re-usable, easy interface JavaScript chart library based on D3.js'\nlogo: billboard.svg\ndeveloper: null\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/naver/billboard.js/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/billboard-1.png\n  - /images/slider/billboard-2.png\n  - /images/slider/billboard-3.png\n  - /images/slider/billboard-4.png\n  - /images/slider/billboard-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\nslugs:\n  github: naver/billboard.js\n  npm: billboard.js\ntags:\n  stackoverflow:\n    - billboard.js\n  twitter:\n    - BillboardJS\nlinks:\n  website: 'https://naver.github.io/billboard.js/'\n  examples: 'https://naver.github.io/billboard.js/demo/'\n  docs: 'https://naver.github.io/billboard.js/release/latest/doc/'\n  pricing: null\n  slack: null\ncontent: null\ngithub_data:\n  stars: 5878\n  contributors: 190\n  issues: 146\n  stale_issues: 139\n  last_release:\n    date: '2025-01-07T08:55:27Z'\n    link: 'https://github.com/naver/billboard.js/releases/tag/3.14.3'\nstackoverflow_data:\n  questions_count: 66\n"
  },
  {
    "path": "copy/tools/c3.yml",
    "content": "title: C3.js\ndescription: D3.js-based reusable chart library\nlogo: c3.svg\ndeveloper: null\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/c3js/c3/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/c3-1.png\n  - /images/slider/c3-2.png\n  - /images/slider/c3-3.png\n  - /images/slider/c3-4.png\n  - /images/slider/c3-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: c3js/c3\n  npm: c3\n  npm_types: '@types/c3'\ntags:\n  stackoverflow:\n    - c3.js\n  twitter:\n    - c3js\nlinks:\n  website: 'https://c3js.org'\n  examples: 'https://c3js.org/examples.html'\n  docs: 'https://c3js.org/reference.html'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started with c3.js\n    link: 'https://c3js.org/gettingstarted.html'\ngithub_data:\n  stars: 9347\n  contributors: 169\n  issues: 726\n  stale_issues: 723\n  last_release:\n    date: '2020-08-08T09:14:36Z'\n    link: 'https://github.com/c3js/c3/releases/tag/v0.7.20'\nstackoverflow_data:\n  questions_count: 1116\n"
  },
  {
    "path": "copy/tools/chartist.yml",
    "content": "title: Chartist\ndescription: Simple responsive SVG charts\nlogo: chartist.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/chartist-js/chartist/blob/main/LICENSE-MIT'\n  - type: open-source\n    title: WTFPL\n    link: 'https://github.com/gionkunz/chartist-js/blob/main/LICENSE-WTFPL'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 1\n  easy-to-start-with: 2\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/chartist-1.png\n  - /images/slider/chartist-2.png\n  - /images/slider/chartist-3.png\n  - /images/slider/chartist-4.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: chartist-js/chartist\n  npm: chartist\ntags:\n  stackoverflow:\n    - chartist.js\nlinks:\n  website: 'https://gionkunz.github.io/chartist-js/'\n  examples: 'https://gionkunz.github.io/chartist-js/examples.html'\n  docs: 'https://gionkunz.github.io/chartist-js/api-documentation.html'\n  pricing: null\ncontent:\n  - type: official\n    title: A quick start guide for Chartist\n    link: 'https://github.com/chartist-js/chartist#quickstart'\ngithub_data:\n  stars: 13360\n  contributors: 89\n  issues: 198\n  stale_issues: 197\n  last_release:\n    date: '2022-11-03T11:45:38Z'\n    link: 'https://github.com/chartist-js/chartist/releases/tag/v1.3.0'\nstackoverflow_data:\n  questions_count: 235\n"
  },
  {
    "path": "copy/tools/chartjs.yml",
    "content": "title: Chart.js\ndescription: Simple yet flexible JavaScript charting for designers & developers\nlogo: chartjs.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/chartjs/Chart.js/blob/master/LICENSE.md'\ntypes:\n  - charts\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 2\n  easy-to-start-with: 3\n  full-fledged: 0\n  very-popular: 1\n  well-documented: 1\ngallery:\n  - /images/slider/chartjs-1.png\n  - /images/slider/chartjs-2.png\n  - /images/slider/chartjs-3.png\n  - /images/slider/chartjs-4.png\n  - /images/slider/chartjs-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\nslugs:\n  github: chartjs/Chart.js\n  npm: chart.js\ntags:\n  stackoverflow:\n    - chart.js\n    - react-chartjs\n    - react-chartjs-2\n  twitter:\n    - chartjs\nlinks:\n  website: 'https://www.chartjs.org'\n  examples: 'https://www.chartjs.org/docs/latest/samples/bar/vertical.html'\n  docs: 'https://www.chartjs.org/docs/latest/'\n  pricing: null\n  slack: 'https://chartjs-slack.herokuapp.com'\ncontent:\n  - type: official\n    title: Awesome Chart.js — a curated list of things related to Chart.js\n    link: 'https://github.com/chartjs/awesome'\n  - type: cube\n    title: Chart.js Example with Dynamic Dataset\n    link: 'https://cube.dev/blog/chart-js-example-with-dynamic-dataset/'\ngithub_data:\n  stars: 65416\n  contributors: 514\n  issues: 442\n  stale_issues: 331\n  last_release:\n    date: '2025-02-19T15:45:55Z'\n    link: 'https://github.com/chartjs/Chart.js/releases/tag/v4.4.8'\nstackoverflow_data:\n  questions_count: 13463\nintegrations:\n  - framework: react\n    slugs:\n      github: reactchartjs/react-chartjs-2\n      npm: react-chartjs-2\n    links:\n      website: 'https://react-chartjs-2.js.org'\n  - framework: angular\n    slugs:\n      github: valor-software/ng2-charts\n      npm: ng2-charts\n    links:\n      website: 'https://valor-software.com/ng2-charts/'\n  - framework: vue\n    slugs:\n      github: apertureless/vue-chartjs\n      npm: vue-chartjs\n    links:\n      website: 'https://vue-chartjs.org'\n  - framework: svelte\n    slugs:\n      github: SauravKanchan/svelte-chartjs\n      npm: svelte-chartjs\n    links:\n      website: 'https://saurav.tech/mdbsvelte/?path=/story/charts--examples'\n"
  },
  {
    "path": "copy/tools/cytoscape.yml",
    "content": "title: Cytoscape.js\ndescription: Graph theory (network) library for visualisation and analysis\nlogo: cytoscape.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/cytoscape/cytoscape.js/blob/unstable/LICENSE'\ntypes:\n  - low-level\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/cytoscape-1.png\n  - /images/slider/cytoscape-2.png\n  - /images/slider/cytoscape-3.png\n  - /images/slider/cytoscape-4.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\nslugs:\n  github: cytoscape/cytoscape.js\n  npm: cytoscape\n  npm_types: '@types/cytoscape'\ntags:\n  stackoverflow:\n    - cytoscape.js\n  twitter: null\nlinks:\n  website: 'https://js.cytoscape.org'\n  examples: 'https://js.cytoscape.org/#demos'\n  docs: 'https://js.cytoscape.org/#notation'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://js.cytoscape.org/#getting-started'\ngithub_data:\n  stars: 10279\n  contributors: 155\n  issues: 14\n  stale_issues: 2\n  last_release:\n    date: '2025-02-26T19:47:13Z'\n    link: 'https://github.com/cytoscape/cytoscape.js/releases/tag/v3.31.1'\nstackoverflow_data:\n  questions_count: 1283\n"
  },
  {
    "path": "copy/tools/d3.yml",
    "content": "title: D3.js\ndescription: JavaScript library for manipulating documents based on data\nlogo: d3.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: BSD\n    link: 'https://github.com/d3/d3/blob/master/LICENSE'\ntypes:\n  - low-level\nrenders:\n  - svg\n  - html\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 2\n  very-popular: 1\n  well-documented: 0\ngallery:\n  - /images/slider/d3-1.png\n  - /images/slider/d3-2.png\n  - /images/slider/d3-3.png\n  - /images/slider/d3-4.png\n  - /images/slider/d3-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: d3/d3\n  npm: d3\n  npm_types: '@types/d3'\ntags:\n  stackoverflow:\n    - d3.js\n  twitter:\n    - D3js\nlinks:\n  website: 'https://d3js.org'\n  examples: 'https://observablehq.com/@d3/gallery'\n  docs: 'https://github.com/d3/d3/wiki'\n  pricing: null\n  slack: 'https://d3-slackin.herokuapp.com'\ncontent:\n  - type: official\n    title: 'Learn D3: Introduction'\n    link: 'https://observablehq.com/@d3/learn-d3'\n  - type: cube\n    title: D3 Dashboard Tutorial\n    link: 'https://d3-dashboard.cube.dev'\ngithub_data:\n  stars: 109948\n  contributors: 152\n  issues: 9\n  stale_issues: 6\n  last_release:\n    date: '2024-03-12T22:18:19Z'\n    link: 'https://github.com/d3/d3/releases/tag/v7.9.0'\nstackoverflow_data:\n  questions_count: 39316\n"
  },
  {
    "path": "copy/tools/datasette.yml",
    "content": "title: Datasette\ndescription: Open-source multi-tool for exploring and publishing data\nlogo: datasette.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/simonw/datasette/blob/main/LICENSE'\ntypes:\n  - app\nrenders: null\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/datasette-1.png\n  - /images/slider/datasette-2.png\n  - /images/slider/datasette-3.png\n  - /images/slider/datasette-4.png\nlanguages: null\nframeworks: null\nslugs:\n  github: simonw/datasette\n  npm: null\n  npm_types: null\ntags:\n  stackoverflow:\n    - datasette\n  twitter: null\nlinks:\n  website: 'https://datasette.io'\n  examples: 'https://datasette.io/examples'\n  docs: 'https://docs.datasette.io/en/stable/'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://docs.datasette.io/en/stable/getting_started.html'\ngithub_data:\n  stars: 9831\n  contributors: 81\n  issues: 565\n  stale_issues: 500\n  last_release:\n    date: '2025-02-06T19:14:10Z'\n    link: 'https://github.com/simonw/datasette/releases/tag/1.0a17'\nstackoverflow_data:\n  questions_count: 4\n"
  },
  {
    "path": "copy/tools/deck-gl.yml",
    "content": "title: deck.gl\ndescription: WebGL-powered visualization framework for large-scale datasets\nlogo: deck-gl.svg\ndeveloper: Uber\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/visgl/deck.gl/blob/master/LICENSE'\ntypes:\n  - low-level\n  - maps\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/deck-gl-1.jpg\n  - /images/slider/deck-gl-2.jpg\n  - /images/slider/deck-gl-3.jpg\n  - /images/slider/deck-gl-4.jpg\n  - /images/slider/deck-gl-5.jpg\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - vue\nslugs:\n  github: visgl/deck.gl\n  npm: deck.gl\n  npm_types: '@danmarshall/deckgl-typings'\ntags:\n  stackoverflow:\n    - deck.gl\n  twitter:\n    - deckgl\nlinks:\n  website: 'https://deck.gl'\n  examples: 'https://deck.gl/examples'\n  docs: 'https://deck.gl/docs'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://deck.gl/docs/get-started/using-standalone'\ngithub_data:\n  stars: 12524\n  contributors: 283\n  issues: 350\n  stale_issues: 226\n  last_release:\n    date: '2025-02-27T07:02:11Z'\n    link: 'https://github.com/visgl/deck.gl/releases/tag/v9.1.4'\nstackoverflow_data:\n  questions_count: 258\n"
  },
  {
    "path": "copy/tools/echarts.yml",
    "content": "title: Apache ECharts\ndescription: Open-source JavaScript visualization library\nlogo: echarts.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/apache/echarts/blob/master/LICENSE'\ntypes:\n  - charts\n  - maps\n  - 3d\nrenders:\n  - svg\n  - canvas\nfeatures:\n  easy-to-customize: 2\n  easy-to-start-with: 1\n  full-fledged: 2\n  very-popular: 0\n  well-documented: 2\ngallery:\n  - /images/slider/echarts-1.png\n  - /images/slider/echarts-2.png\n  - /images/slider/echarts-3.png\n  - /images/slider/echarts-4.png\n  - /images/slider/echarts-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\nslugs:\n  github: apache/echarts\n  npm: ag-grid-community\n  npm_types: '@types/echarts'\ntags:\n  stackoverflow:\n    - echarts\n  twitter:\n    - ECharts\nlinks:\n  website: 'https://echarts.apache.org/en/index.html'\n  examples: 'https://echarts.apache.org/examples/en/index.html'\n  docs: 'https://echarts.apache.org/en/api.html#echarts'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Get started with ECharts in 5 minutes\n    link: >-\n      https://echarts.apache.org/en/tutorial.html#Get%20Started%20with%20ECharts%20in%205%20minutes\n  - type: cube\n    title: Building an Apache ECharts dashboard with React and Cube\n    link: >-\n      https://cube.dev/blog/building-an-apache-echarts-dashboard-with-react-and-cube/\n  - type: cube\n    title: Building an Apache ECharts Dashboard with Angular and Cube\n    link: >-\n      https://cube.dev/blog/building-an-apache-echarts-dashboard-with-angular-and-cube/\n  - type: cube\n    title: Building an Apache ECharts Dashboard with Vue 3 and Cube\n    link: >-\n      https://cube.dev/blog/building-an-apache-echarts-dashboard-with-vue-3-and-cube/\ngithub_data:\n  stars: 61997\n  contributors: 293\n  issues: 2029\n  stale_issues: 1406\n  last_release:\n    date: '2024-12-28T06:52:31Z'\n    link: 'https://github.com/apache/echarts/releases/tag/5.6.0'\nstackoverflow_data:\n  questions_count: 1480\nintegrations:\n  - framework: react\n    slugs:\n      github: hustcc/echarts-for-react\n      npm: echarts-for-react\n    links:\n      website: 'https://git.hust.cc/echarts-for-react/'\n  - framework: angular\n    slugs:\n      github: xieziyu/ngx-echarts\n      npm: ngx-echarts\n    links:\n      website: 'https://xieziyu.github.io/ngx-echarts/'\n  - framework: vue\n    slugs:\n      github: ecomfe/vue-echarts\n      npm: vue-echarts\n    links:\n      website: 'https://vue-echarts.dev'\n"
  },
  {
    "path": "copy/tools/flot.yml",
    "content": "title: Flot\ndescription: Attractive JavaScript charts for jQuery\nlogo: flot.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/flot/flot/blob/master/LICENSE.txt'\ntypes:\n  - charts\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\nslugs:\n  github: flot/flot\n  npm: flot\n  npm_types: '@types/flot'\ntags:\n  stackoverflow:\n    - flot\n  twitter: null\nlinks:\n  website: 'http://www.flotcharts.org'\n  examples: 'http://www.flotcharts.org/flot/examples/'\n  docs: 'https://github.com/flot/flot/blob/master/API.md'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://github.com/flot/flot/blob/master/README.md#installation'\ngithub_data:\n  stars: 5940\n  contributors: 93\n  issues: 457\n  stale_issues: 453\n  last_release:\n    date: '2014-04-21T20:53:45Z'\n    link: 'https://github.com/flot/flot/releases/tag/v0.8.3'\nstackoverflow_data:\n  questions_count: 2059\n"
  },
  {
    "path": "copy/tools/frappe.yml",
    "content": "title: Frappe\ndescription: >-\n  GitHub-inspired simple and modern SVG charts for the web with zero\n  dependencies\nlogo: frappe.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/frappe/charts/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\nframeworks:\n  - vanilla-js\n  - react\n  - vue\n  - svelte\nslugs:\n  github: frappe/charts\n  npm: frappe-charts\ntags:\n  stackoverflow:\n    - frappe\n  twitter: null\nlinks:\n  website: 'https://frappe.io/charts'\n  examples: 'https://frappe.io/charts'\n  docs: 'https://frappe.io/charts/docs'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Quick Start\n    link: 'https://frappe.io/charts/docs'\ngithub_data:\n  stars: 14984\n  contributors: 55\n  issues: 125\n  stale_issues: 122\n  last_release:\n    date: '2022-04-27T10:43:31Z'\n    link: 'https://github.com/frappe/charts/releases/tag/v1.6.3'\nstackoverflow_data:\n  questions_count: 220\n"
  },
  {
    "path": "copy/tools/fusioncharts.yml",
    "content": "title: FusionCharts\ndescription: JavaScript charts for web & mobile\nlogo: fusioncharts.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: proprietary\n    link: >-\n      https://www.ideracorp.com/Legal/FusionCharts/MasterISVSoftwareSubscriptionAgreement\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/fusioncharts-1.png\n  - /images/slider/fusioncharts-2.png\n  - /images/slider/fusioncharts-3.png\n  - /images/slider/fusioncharts-4.png\n  - /images/slider/fusioncharts-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\n  - svelte\nslugs:\n  github: fusioncharts/fusioncharts-dist\n  npm: fusioncharts\n  npm_types: '@types/fusioncharts'\ntags:\n  stackoverflow:\n    - fusioncharts\n  twitter:\n    - FusionCharts\nlinks:\n  website: 'https://www.fusioncharts.com/fusioncharts'\n  examples: 'https://www.fusioncharts.com/charts'\n  docs: 'https://www.fusioncharts.com/dev/fusioncharts'\n  pricing: 'https://www.fusioncharts.com/buy'\n  slack: null\ncontent:\n  - type: official\n    title: Create a Chart Using FusionCharts\n    link: >-\n      https://www.fusioncharts.com/dev/getting-started/plain-javascript/your-first-chart-using-plain-javascript\ngithub_data:\n  stars: 85\n  contributors: 9\n  issues: 40\n  stale_issues: 34\n  last_release:\n    date: '2024-11-12T14:58:42Z'\n    link: 'https://github.com/fusioncharts/fusioncharts-dist/releases/tag/4.1.0'\nstackoverflow_data:\n  questions_count: 799\n"
  },
  {
    "path": "copy/tools/g2.yml",
    "content": "title: G2\ndescription: Highly interactive data-driven visualization grammar for statistical charts\nlogo: antv.svg\ndeveloper: AntV\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/antvis/G2/blob/master/LICENSE'\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 1\n  very-popular: 0\n  well-documented: 1\ngallery:\n  - /images/slider/g2-1.png\n  - /images/slider/g2-2.png\n  - /images/slider/g2-3.png\n  - /images/slider/g2-4.png\n  - /images/slider/g2-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: antvis/G2\n  npm: '@antv/g2'\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'https://g2.antv.vision/en'\n  examples: 'https://g2.antv.vision/en/examples/gallery'\n  docs: 'https://g2.antv.vision/en/docs/manual/about-g2'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Quick Start\n    link: 'https://g2.antv.vision/en/docs/manual/getting-started'\ngithub_data:\n  stars: 12209\n  contributors: 207\n  issues: 214\n  stale_issues: 80\n  last_release:\n    date: '2025-02-11T08:23:42Z'\n    link: 'https://github.com/antvis/G2/releases/tag/5.2.11'\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/g2plot.yml",
    "content": "title: G2Plot\ndescription: Interactive and responsive charting library based on the grammar of graphics\nlogo: antv.svg\ndeveloper: AntV\nbased_on:\n  - g2\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/antvis/G2Plot/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 1\n  very-popular: 0\n  well-documented: 1\ngallery:\n  - /images/slider/g2plot-1.png\n  - /images/slider/g2plot-2.png\n  - /images/slider/g2plot-3.png\n  - /images/slider/g2plot-4.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - vue\nslugs:\n  github: antvis/G2Plot\n  npm: '@antv/g2plot'\ntags:\n  stackoverflow:\n    - g2plot\n  twitter:\n    - G2Plot\nlinks:\n  website: 'https://g2plot.antv.vision/en'\n  examples: 'https://g2plot.antv.vision/en/examples/gallery'\n  docs: 'https://g2plot.antv.vision/en/docs/manual/introduction'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Quick Start\n    link: 'https://g2plot.antv.vision/en/docs/manual/getting-started'\ngithub_data:\n  stars: 2584\n  contributors: 67\n  issues: 438\n  stale_issues: 393\n  last_release:\n    date: '2024-07-30T08:47:03Z'\n    link: 'https://github.com/antvis/G2Plot/releases/tag/2.4.32'\nstackoverflow_data:\n  questions_count: 10\n"
  },
  {
    "path": "copy/tools/g6.yml",
    "content": "title: G6\ndescription: Graph visualization engine with simplicity and convenience\nlogo: antv.svg\ndeveloper: AntV\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/antvis/G6/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 1\n  very-popular: 0\n  well-documented: 1\ngallery:\n  - /images/slider/g6-1.png\n  - /images/slider/g6-2.png\n  - /images/slider/g6-3.png\n  - /images/slider/g6-4.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: antvis/G6\n  npm: '@antv/g6'\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'https://g6.antv.vision/en'\n  examples: 'https://g6.antv.vision/en/examples/gallery'\n  docs: 'https://g6.antv.vision/en/docs/manual/introduction'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://g6.antv.vision/en/docs/manual/getting-started'\ngithub_data:\n  stars: 11338\n  contributors: 171\n  issues: 158\n  stale_issues: 3\n  last_release:\n    date: '2025-02-14T08:55:41Z'\n    link: 'https://github.com/antvis/G6/releases/tag/5.0.43'\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/google-charts.yml",
    "content": "title: Google Charts\ndescription: Interactive charts for browsers and mobile devices\nlogo: google-charts.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: proprietary\n    link: 'https://developers.google.com/chart/terms'\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\n  - html\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/google-charts-1.png\n  - /images/slider/google-charts-2.png\n  - /images/slider/google-charts-3.png\n  - /images/slider/google-charts-4.png\n  - /images/slider/google-charts-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  npm_types: '@types/google.visualization'\ntags:\n  stackoverflow:\n    - google-visualization\n  twitter:\n    - googlecharts\nlinks:\n  website: 'https://developers.google.com/chart'\n  examples: 'https://developers.google.com/chart/interactive/docs/gallery'\n  docs: 'https://developers.google.com/chart/interactive/docs'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Quick Start\n    link: 'https://developers.google.com/chart/interactive/docs/quick_start'\n  - type: cube\n    title: \"Google Charts Dashboard: a Tutorial with an Artistic Touch of MoMA \\U0001F5BC\"\n    link: 'https://cube.dev/blog/google-charts-dashboard/'\n  - type: cube\n    title: Building a Dashboard with a React Wrapper for Google Charts\n    link: 'https://cube.dev/blog/react-google-charts-dashboard/'\ngithub_data: null\nstackoverflow_data:\n  questions_count: 9023\nintegrations:\n  - framework: react\n    slugs:\n      github: RakanNimer/react-google-charts\n      npm: react-google-charts\n    links:\n      website: 'https://react-google-charts.com'\n  - framework: angular\n    slugs:\n      github: FERNman/angular-google-charts\n      npm: angular-google-charts\n    links:\n      website: null\n  - framework: vue\n    slugs:\n      github: devstark-com/vue-google-charts\n      npm: vue-google-charts\n    links:\n      website: null\n"
  },
  {
    "path": "copy/tools/highcharts.yml",
    "content": "title: Highcharts\ndescription: Modern SVG-based multi-platform charting library\nlogo: highcharts.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: proprietary\n    license: 'https://github.com/highcharts/highcharts/blob/master/license.txt'\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 1\n  easy-to-start-with: 0\n  full-fledged: 1\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/highcharts-1.png\n  - /images/slider/highcharts-2.png\n  - /images/slider/highcharts-3.png\n  - /images/slider/highcharts-4.png\n  - /images/slider/highcharts-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\nslugs:\n  github: highcharts/highcharts\n  npm: highcharts\ntags:\n  stackoverflow:\n    - highcharts\n  twitter:\n    - highcharts\nlinks:\n  website: 'https://www.highcharts.com'\n  examples: 'https://www.highcharts.com/demo'\n  docs: 'https://www.highcharts.com/docs/index'\n  pricing: 'https://shop.highsoft.com'\n  slack: null\ncontent:\n  - type: cube\n    title: React Highcharts Example with Cube.js\n    link: 'https://cube.dev/blog/react-highcharts-example/'\ngithub_data:\n  stars: 12176\n  contributors: 264\n  issues: 849\n  stale_issues: 465\n  last_release:\n    date: null\n    link: null\nstackoverflow_data:\n  questions_count: 26238\n"
  },
  {
    "path": "copy/tools/kepler-gl.yml",
    "content": "title: Kepler.gl\ndescription: Open-source geospatial analysis tool for large-scale data sets\nlogo: kepler-gl.svg\ndeveloper: Uber\nbased_on:\n  - mapbox-gl\n  - deck-gl\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/keplergl/kepler.gl/blob/master/LICENSE'\ntypes:\n  - maps\nrenders:\n  - svg\n  - html\n  - canvas\n  - webgl\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\nslugs:\n  github: keplergl/kepler.gl\n  npm: kepler.gl\ntags:\n  stackoverflow:\n    - kepler.gl\n  twitter:\n    - KeplerGL\nlinks:\n  website: 'https://kepler.gl'\n  examples: 'https://docs.kepler.gl/examples'\n  docs: 'https://docs.kepler.gl/docs'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://vis.academy/#/kepler.gl/setup'\n  - type: community\n    title: Exploring Geospatial Data with Kepler.gl\n    link: >-\n      https://medium.com/vis-gl/exploring-geospatial-data-with-kepler-gl-cf655839628f\ngithub_data:\n  stars: 10596\n  contributors: 130\n  issues: 498\n  stale_issues: 444\n  last_release:\n    date: '2025-01-29T16:00:29Z'\n    link: 'https://github.com/keplergl/kepler.gl/releases/tag/v3.1.0'\nstackoverflow_data:\n  questions_count: 77\n"
  },
  {
    "path": "copy/tools/laue.yml",
    "content": "title: Laue\ndescription: Modern charts for Vue.js\nlogo: laue.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/QingWei-Li/laue/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/laue-1.png\n  - /images/slider/laue-2.png\n  - /images/slider/laue-3.png\n  - /images/slider/laue-4.png\n  - /images/slider/laue-5.png\nlanguages:\n  - JavaScript\nframeworks:\n  - vue\nslugs:\n  github: qingwei-li/laue\n  npm: laue\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'https://laue.js.org'\n  examples: 'https://laue.js.org/examples'\n  docs: 'https://laue.js.org/api'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Quick start with Laue\n    link: 'https://laue.js.org/guide#quick-started'\ngithub_data:\n  stars: 263\n  contributors: 8\n  issues: 15\n  stale_issues: 15\n  last_release:\n    date: '2018-10-31T15:52:54Z'\n    link: 'https://github.com/QingWei-Li/laue/releases/tag/v0.2.0'\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/layer-cake.yml",
    "content": "title: Layer Cake\ndescription: Graphics framework for Svelte\nlogo: layer-cake.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/mhkeller/layercake/blob/master/LICENSE'\ntypes:\n  - charts\n  - low-level\n  - maps\nrenders:\n  - svg\n  - html\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\nframeworks:\n  - svelte\nslugs:\n  github: mhkeller/layercake\n  npm: layercake\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'https://layercake.graphics'\n  examples: 'https://layercake.graphics'\n  docs: 'https://layercake.graphics/guide'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://layercake.graphics/guide#getting-started'\ngithub_data:\n  stars: 1516\n  contributors: 11\n  issues: 7\n  stale_issues: 2\n  last_release:\n    date: '2024-10-19T23:08:21Z'\n    link: 'https://github.com/mhkeller/layercake/releases/tag/v8.4.0'\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/leaflet.yml",
    "content": "title: Leaflet\ndescription: JavaScript library for mobile-friendly interactive maps\nlogo: leafletjs.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: BSD\n    link: 'https://github.com/Leaflet/Leaflet/blob/main/LICENSE'\ntypes:\n  - maps\nrenders:\n  - svg\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/leaflet-1.png\n  - /images/slider/leaflet-2.png\n  - /images/slider/leaflet-3.png\n  - /images/slider/leaflet-4.png\n  - /images/slider/leaflet-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: leaflet/leaflet\n  npm: leaflet\n  npm_types: '@types/leaflet'\ntags:\n  stackoverflow:\n    - leaflet\n  twitter:\n    - leafletjs\nlinks:\n  website: 'https://leafletjs.com'\n  examples: 'https://leafletjs.com/examples.html'\n  docs: 'https://leafletjs.com/reference-1.7.1.html'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: leafletjs Quick Start Guide\n    link: 'https://leafletjs.com/examples/quick-start/'\ngithub_data:\n  stars: 42153\n  contributors: 987\n  issues: 404\n  stale_issues: 377\n  last_release:\n    date: '2023-05-18T11:12:03Z'\n    link: 'https://github.com/Leaflet/Leaflet/releases/tag/v1.9.4'\nstackoverflow_data:\n  questions_count: 12948\n"
  },
  {
    "path": "copy/tools/lightweight-charts.yml",
    "content": "title: Lightweight Charts\ndescription: Financial lightweight charts built with HTML5 canvas\nlogo: lightweight-charts.svg\ndeveloper: TradingView\nbased_on: null\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/tradingview/lightweight-charts/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - vue\n  - angular\nslugs:\n  github: tradingview/lightweight-charts\n  npm: lightweight-charts\ntags:\n  stackoverflow:\n    - lightweight-charts\n  twitter:\n    - lightweightcharts\nlinks:\n  website: 'https://www.tradingview.com/lightweight-charts/'\n  examples: 'https://www.tradingview.com/lightweight-charts/'\n  docs: 'https://tradingview.github.io/lightweight-charts/'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://tradingview.github.io/lightweight-charts/docs'\n  - type: official\n    title: Customization\n    link: >-\n      https://tradingview.github.io/lightweight-charts/tutorials/customization/intro\n  - type: official\n    title: Framework integrations\n    link: >-\n      https://tradingview.github.io/lightweight-charts/tutorials#framework-integrations\ngithub_data:\n  stars: 10832\n  contributors: 55\n  issues: 97\n  stale_issues: 50\n  last_release:\n    date: '2025-02-26T14:27:04Z'\n    link: 'https://github.com/tradingview/lightweight-charts/releases/tag/v5.0.3'\nstackoverflow_data:\n  questions_count: 162\n"
  },
  {
    "path": "copy/tools/mapbox-gl.yml",
    "content": "title: Mapbox GL JS\ndescription: >-\n  Interactive, thoroughly customizable maps in the browser, powered by vector\n  tiles and WebGL\nlogo: mapbox-gl.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: proprietary\n    link: 'https://github.com/mapbox/mapbox-gl-js/blob/main/LICENSE.txt'\ntypes:\n  - maps\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/mapbox-gl-1.png\n  - /images/slider/mapbox-gl-2.png\n  - /images/slider/mapbox-gl-3.png\n  - /images/slider/mapbox-gl-4.png\n  - /images/slider/mapbox-gl-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: mapbox/mapbox-gl-js\n  npm: mapbox-gl\n  npm_types: '@types/mapbox-gl'\ntags:\n  stackoverflow:\n    - mapbox\n    - mapbox-gl-js\n  twitter:\n    - mapbox\nlinks:\n  website: 'https://docs.mapbox.com/mapbox-gl-js/api/'\n  examples: 'https://docs.mapbox.com/mapbox-gl-js/example/'\n  docs: 'https://docs.mapbox.com/mapbox-gl-js/api/'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Tutorials\n    link: 'https://docs.mapbox.com/help/tutorials/?product=Mapbox+GL+JS'\n  - type: cube\n    title: JavaScript Map Data Visualization with Mapbox\n    link: 'https://mapbox-guide.cube.dev'\ngithub_data:\n  stars: 11440\n  contributors: 440\n  issues: 1316\n  stale_issues: 1152\n  last_release:\n    date: '2025-02-13T16:41:06Z'\n    link: 'https://github.com/mapbox/mapbox-gl-js/releases/tag/v3.10.0'\nstackoverflow_data:\n  questions_count: 9204\n"
  },
  {
    "path": "copy/tools/material-ui-data-grid.yml",
    "content": "title: MUI X Data Grid\ndescription: Fast and extendable data table and data grid for React\nlogo: material-ui.svg\ndeveloper: MUI\nbased_on: null\nlicenses:\n  - type: proprietary\n    title: MUI X Premium\n    link: >-\n      https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid-premium/LICENSE\n  - type: proprietary\n    title: MUI X Pro\n    link: >-\n      https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid-pro/LICENSE\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/mui/mui-x/blob/master/packages/grid/x-data-grid/LICENSE'\ntypes:\n  - grid\nrenders:\n  - html\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/mui-x-data-grid-1.png\n  - /images/slider/mui-x-data-grid-2.png\n  - /images/slider/mui-x-data-grid-3.png\n  - /images/slider/mui-x-data-grid-4.png\n  - /images/slider/mui-x-data-grid-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - react\nslugs:\n  github: mui/mui-x\n  npm: '@mui/x-data-grid'\ntags:\n  stackoverflow:\n    - mui-x\n  twitter:\n    - MUI_hq\nlinks:\n  website: 'https://mui.com/x/react-data-grid/'\n  examples: 'https://mui.com/x/react-data-grid/#mit-version-free-forever'\n  docs: 'https://mui.com/x/react-data-grid/'\n  pricing: 'https://mui.com/pricing/'\n  slack: null\ncontent:\n  - type: cube\n    title: Material UI Dashboard with React\n    link: 'https://material-ui-dashboard.cube.dev'\ngithub_data:\n  stars: 4692\n  contributors: 440\n  issues: 1308\n  stale_issues: 787\n  last_release:\n    date: '2025-02-28T16:07:27Z'\n    link: 'https://github.com/mui/mui-x/releases/tag/v8.0.0-alpha.13'\nstackoverflow_data:\n  questions_count: 261\n"
  },
  {
    "path": "copy/tools/metabase.yml",
    "content": "title: Metabase\ndescription: 'Easy, open-source way to ask questions and learn from data'\nlogo: metabase.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: proprietary\n    link: 'https://github.com/metabase/metabase/blob/master/LICENSE.txt'\n  - type: open-source\n    title: AGPL\n    link: 'https://github.com/metabase/metabase/blob/master/LICENSE.txt'\ntypes:\n  - app\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/metabase-1.png\n  - /images/slider/metabase-2.png\n  - /images/slider/metabase-3.png\n  - /images/slider/metabase-4.png\n  - /images/slider/metabase-5.png\nlanguages: null\nframeworks: null\nslugs:\n  github: metabase/metabase\ntags:\n  stackoverflow:\n    - metabase\n  twitter:\n    - Metabase\nlinks:\n  website: 'https://www.metabase.com'\n  examples: >-\n    https://www.metabase.com/learn/getting-started/getting-started/tour-of-metabase.html\n  docs: 'https://www.ag-grid.com/javascript-grid/'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting started with Metabase\n    link: >-\n      https://www.metabase.com/learn/getting-started/getting-started/getting-started.html\n  - type: cube\n    title: Connecting Metabase to Cube.js\n    link: 'https://github.com/pyrooka/metabase-cubejs-driver#usage'\ngithub_data:\n  stars: 41031\n  contributors: 441\n  issues: 3803\n  stale_issues: 2364\n  last_release:\n    date: '2025-02-25T19:30:05Z'\n    link: 'https://github.com/metabase/metabase/releases/tag/v0.52.13'\nstackoverflow_data:\n  questions_count: 382\n"
  },
  {
    "path": "copy/tools/muze.yml",
    "content": "title: Muze\ndescription: Free library for creating exploratory data visualizations using WebAssembly\nlogo: muze.svg\ndeveloper: Charts.com\nbased_on: null\nlicenses:\n  - type: proprietary\n    title: EULA\n    link: 'https://github.com/chartshq/muze/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/muze-1.png\n  - /images/slider/muze-2.png\n  - /images/slider/muze-3.png\n  - /images/slider/muze-4.png\n  - /images/slider/muze-5.png\nlanguages:\n  - JavaScript\nframeworks:\n  - vanilla-js\n  - react\nslugs:\n  github: chartshq/muze\n  npm: muze\ntags:\n  stackoverflow:\n    - muze\n  twitter: null\nlinks:\n  website: 'https://muzejs.org'\n  examples: 'https://muzejs.org/demos/wa/latest'\n  docs: 'https://muzejs.org/docs/wa/latest/introduction'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started with Muze\n    link: >-\n      https://muzejs.org/docs/wa/latest/introduction?id=getting-started-with-muze\n  - type: cube\n    title: 'Tableau-like Charts with MuzeJS, Cube.js, and React'\n    link: 'https://cube.dev/blog/react-muzejs-tutorial/'\ngithub_data:\n  stars: 1185\n  contributors: 21\n  issues: 4\n  stale_issues: 4\n  last_release:\n    date: '2020-07-31T14:11:59Z'\n    link: 'https://github.com/chartshq/muze/releases/tag/v2.0.0'\nstackoverflow_data:\n  questions_count: 0\n"
  },
  {
    "path": "copy/tools/ngx-charts.yml",
    "content": "title: ngx-charts\ndescription: Declarative charting framework for Angular\nlogo: ngx-charts.svg\ndeveloper: Swimlane\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/swimlane/ngx-charts/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/ngx-charts-1.png\n  - /images/slider/ngx-charts-2.png\n  - /images/slider/ngx-charts-3.png\n  - /images/slider/ngx-charts-4.png\n  - /images/slider/ngx-charts-5.png\nlanguages:\n  - TypeScript\nframeworks:\n  - angular\nslugs:\n  github: swimlane/ngx-charts\n  npm: '@swimlane/ngx-charts'\ntags:\n  stackoverflow:\n    - ngx-charts\n  twitter:\n    - ngxcharts\nlinks:\n  website: 'https://swimlane.github.io/ngx-charts/'\n  examples: 'https://swimlane.github.io/ngx-charts/'\n  docs: 'https://swimlane.gitbook.io/ngx-charts'\n  pricing: null\n  slack: null\ncontent: null\ngithub_data:\n  stars: 4312\n  contributors: 133\n  issues: 712\n  stale_issues: 688\n  last_release:\n    date: null\n    link: null\nstackoverflow_data:\n  questions_count: 247\n"
  },
  {
    "path": "copy/tools/nivo.yml",
    "content": "title: nivo\ndescription: Supercharged React components to easily build dataviz apps\nlogo: nivo.png\ndeveloper: null\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: MIT\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\n  - html\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/nivo-1.png\n  - /images/slider/nivo-2.png\n  - /images/slider/nivo-3.png\n  - /images/slider/nivo-4.png\n  - /images/slider/nivo-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - react\nslugs:\n  github: plouc/nivo\n  npm: null\ntags:\n  stackoverflow:\n    - nivo-react\n  twitter:\n    - nivo\nlinks:\n  website: 'https://nivo.rocks'\n  examples: 'https://nivo.rocks/storybook/'\n  docs: 'https://nivo.rocks/components'\n  pricing: null\n  slack: null\ncontent:\n  - type: cube\n    title: Building a nivo Dashboard with Cube\n    link: 'https://cube.dev/blog/building-a-nivo-dashboard-with-cube'\ngithub_data:\n  stars: 13415\n  contributors: 220\n  issues: 89\n  stale_issues: 56\n  last_release:\n    date: '2024-11-11T01:52:42Z'\n    link: 'https://github.com/plouc/nivo/releases/tag/v0.88.0'\nstackoverflow_data:\n  questions_count: 84\n"
  },
  {
    "path": "copy/tools/observable-plot.yml",
    "content": "title: Observable Plot\ndescription: Concise API for exploratory data visualization\nlogo: observable.png\ndeveloper: null\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: ISC\n    link: 'https://github.com/observablehq/plot/blob/main/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/observable-plot-1.png\n  - /images/slider/observable-plot-2.png\n  - /images/slider/observable-plot-3.png\n  - /images/slider/observable-plot-4.png\n  - /images/slider/observable-plot-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: observablehq/plot\n  npm: '@observablehq/plot'\ntags:\n  stackoverflow:\n    - observablehq\n  twitter:\n    - observablehq\nlinks:\n  website: 'https://observablehq.com/plot'\n  examples: 'https://observablehq.com/@observablehq/plot-gallery'\n  docs: 'https://observablehq.com/plot'\n  pricing: null\n  slack: 'https://observable-community.slack.com/ssb/redirect'\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://observablehq.com/plot/getting-started'\ngithub_data:\n  stars: 4605\n  contributors: 26\n  issues: 250\n  stale_issues: 204\n  last_release:\n    date: '2025-02-14T16:05:17Z'\n    link: 'https://github.com/observablehq/plot/releases/tag/v0.6.17'\nstackoverflow_data:\n  questions_count: 136\n"
  },
  {
    "path": "copy/tools/p5.yml",
    "content": "title: p5.js\ndescription: >-\n  JavaScript library for creative coding that makes coding accessible and\n  inclusive\nlogo: p5.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: GNU LGPL 2.1\n    link: 'https://github.com/processing/p5.js/blob/main/license.txt'\ntypes:\n  - low-level\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/p5-1.png\n  - /images/slider/p5-2.png\n  - /images/slider/p5-3.png\n  - /images/slider/p5-4.png\n  - /images/slider/p5-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: processing/p5.js\n  npm: p5\n  npm_types: '@types/p5'\ntags:\n  stackoverflow:\n    - p5.js\n  twitter:\n    - p5js\n    - p5xjs\nlinks:\n  website: 'https://p5js.org'\n  examples: 'https://p5js.org/examples/'\n  docs: 'https://p5js.org/examples/'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Get Started with p5.js\n    link: 'https://p5js.org/get-started/'\ngithub_data:\n  stars: 22172\n  contributors: 796\n  issues: 302\n  stale_issues: 201\n  last_release:\n    date: '2025-02-25T21:27:36Z'\n    link: 'https://github.com/processing/p5.js/releases/tag/v2.0.0-beta.3'\nstackoverflow_data:\n  questions_count: 3185\n"
  },
  {
    "path": "copy/tools/pancake.yml",
    "content": "title: Pancake\ndescription: 'Responsive charts, JavaScript optional'\nlogo: pancake.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/Rich-Harris/pancake/blob/master/package.json#L24'\ntypes:\n  - charts\nrenders:\n  - svg\n  - html\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\nframeworks:\n  - svelte\nslugs:\n  github: Rich-Harris/pancake\n  npm: '@sveltejs/pancake'\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'https://pancake-charts.surge.sh'\n  examples: 'https://pancake-charts.surge.sh'\n  docs: null\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: 'A new technique for making responsive, JavaScript-free charts'\n    link: >-\n      https://dev.to/richharris/a-new-technique-for-making-responsive-javascript-free-charts-gmp\ngithub_data:\n  stars: 1303\n  contributors: 2\n  issues: 17\n  stale_issues: 17\n  last_release:\n    date: null\n    link: null\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/perspective.yml",
    "content": "title: Perspective\ndescription: >-\n  Interactive analytics and data visualization component, especially well-suited\n  for large and/or streaming datasets\nlogo: finos.svg\ndeveloper: J.P. Morgan\nbased_on: null\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/finos/perspective/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\n  - html\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/perspective-1.png\n  - /images/slider/perspective-2.png\n  - /images/slider/perspective-3.png\n  - /images/slider/perspective-4.png\n  - /images/slider/perspective-5.png\nlanguages:\n  - JavaScript\n  - Python\nframeworks:\n  - vanilla-js\nslugs:\n  github: finos/perspective\n  npm: '@finos/perspective'\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'https://perspective.finos.org'\n  examples: 'https://perspective.finos.org'\n  docs: 'https://perspective.finos.org/docs/js'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: JavaScript User Guide\n    link: 'https://perspective.finos.org/docs/js'\n  - type: official\n    title: Python User Guide\n    link: 'https://perspective.finos.org/docs/python'\ngithub_data:\n  stars: 8836\n  contributors: 98\n  issues: 97\n  stale_issues: 69\n  last_release:\n    date: '2025-02-10T05:23:05Z'\n    link: 'https://github.com/finos/perspective/releases/tag/v3.3.4'\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/plotly.yml",
    "content": "title: Plotly\ndescription: 'High-level, declarative charting library'\nlogo: plotly.svg\ndeveloper: null\nbased_on:\n  - d3\n  - stackgl\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/plotly/plotly.js/blob/master/LICENSE'\ntypes:\n  - charts\n  - maps\n  - 3d\nrenders:\n  - svg\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/plotly-1.png\n  - /images/slider/plotly-2.png\n  - /images/slider/plotly-3.png\n  - /images/slider/plotly-4.png\n  - /images/slider/plotly-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\nslugs:\n  github: plotly/plotly.js\n  npm: plotly.js\n  npm_types: '@types/plotly.js'\ntags:\n  stackoverflow:\n    - plotly\n    - plotly.js\n  twitter:\n    - plotly\n    - plotlyjs\nlinks:\n  website: 'https://plotly.com/javascript/'\n  examples: 'https://plotly.com/javascript/'\n  docs: 'https://www.ag-grid.com/javascript-grid/'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started in JavaScript\n    link: 'https://plotly.com/javascript/getting-started/'\ngithub_data:\n  stars: 17388\n  contributors: 295\n  issues: 634\n  stale_issues: 472\n  last_release:\n    date: '2025-02-18T16:55:38Z'\n    link: 'https://github.com/plotly/plotly.js/releases/tag/v3.0.1'\nstackoverflow_data:\n  questions_count: 15318\n"
  },
  {
    "path": "copy/tools/plottable.yml",
    "content": "title: Plottable\ndescription: Library of modular chart components built on D3.js\nlogo: plottable.svg\ndeveloper: Palantir\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/palantir/plottable/blob/develop/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: palantir/plottable\n  npm: plottable\ntags:\n  stackoverflow:\n    - plottable\n  twitter:\n    - aggrid\n    - ag_grid\nlinks:\n  website: 'http://plottablejs.org'\n  examples: 'http://plottablejs.org/examples/'\n  docs: 'http://plottablejs.org/docs/modules/plottable.html'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Quick Start\n    link: 'https://github.com/palantir/plottable/blob/develop/README.md#quick-start'\ngithub_data:\n  stars: 2989\n  contributors: 85\n  issues: 305\n  stale_issues: 305\n  last_release:\n    date: '2021-11-22T14:30:28Z'\n    link: 'https://github.com/palantir/plottable/releases/tag/v3.13.0'\nstackoverflow_data:\n  questions_count: 44\n"
  },
  {
    "path": "copy/tools/pts.yml",
    "content": "title: Pts\ndescription: Library for visualization and creative-coding\nlogo: pts.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/williamngan/pts/blob/master/LICENSE'\ntypes:\n  - low-level\nrenders:\n  - svg\n  - html\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/pts-1.png\n  - /images/slider/pts-2.png\n  - /images/slider/pts-3.png\n  - /images/slider/pts-4.png\n  - /images/slider/pts-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: williamngan/pts\n  npm: pts\ntags:\n  stackoverflow: null\n  twitter:\n    - ptsjs\nlinks:\n  website: 'https://ptsjs.org'\n  examples: 'https://ptsjs.org/demo/'\n  docs: 'https://ptsjs.org/docs/'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Get started with Pts.js\n    link: 'https://ptsjs.org/guide/get-started-0100'\ngithub_data:\n  stars: 5225\n  contributors: 24\n  issues: 48\n  stale_issues: 42\n  last_release:\n    date: '2022-12-08T09:43:45Z'\n    link: 'https://github.com/williamngan/pts/releases/tag/v0.11.3'\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/react-charts.yml",
    "content": "title: React Charts\ndescription: 'Simple, immersive & interactive charts for React'\nlogo: react-charts.svg\ndeveloper: null\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/TanStack/react-charts/blob/main/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - react\nslugs:\n  github: TanStack/react-charts\n  npm: react-charts\ntags:\n  stackoverflow:\n    - react-charts\n  twitter:\n    - ReactCharts\nlinks:\n  website: 'https://react-charts.tanstack.com'\n  examples: 'https://react-charts.tanstack.com/examples/simple'\n  docs: 'https://react-charts.tanstack.com/docs/overview'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Installation\n    link: 'https://react-charts.tanstack.com/docs/installation'\ngithub_data:\n  stars: 3043\n  contributors: 32\n  issues: 60\n  stale_issues: 52\n  last_release:\n    date: '2023-11-02T22:14:26Z'\n    link: 'https://github.com/TanStack/react-charts/releases/tag/v3.0.0-beta.57'\nstackoverflow_data:\n  questions_count: 11\n"
  },
  {
    "path": "copy/tools/reaflow.yml",
    "content": "title: reaflow\ndescription: 'React library for building workflow editors, flow charts, and diagrams'\nlogo: reaflow.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/reaviz/reaflow/blob/master/LICENSE'\ntypes:\n  - low-level\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/reaflow-1.png\n  - /images/slider/reaflow-2.png\n  - /images/slider/reaflow-3.png\n  - /images/slider/reaflow-4.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - react\nslugs:\n  github: reaviz/reaflow\n  npm: reaflow\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'https://reaflow.dev'\n  examples: 'https://reaflow.dev/?path=/story/demos-basic--custom-elements'\n  docs: 'https://reaflow.dev/?path=/story/docs-introduction--page'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://reaflow.dev/?path=/story/docs-getting-started-installing--page'\ngithub_data:\n  stars: 2248\n  contributors: 27\n  issues: 86\n  stale_issues: 78\n  last_release:\n    date: null\n    link: null\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/reaviz.yml",
    "content": "title: REAVIZ\ndescription: >-\n  Modular chart library that leverages React natively while using D3.js under\n  the hood\nlogo: reaviz.png\ndeveloper: null\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/reaviz/reaviz/blob/master/LICENSE'\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - react\nslugs:\n  github: reaviz/reaviz\n  npm: reaviz\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'https://reaviz.io'\n  examples: 'https://reaviz.io/?path=/story/docs-intro--page'\n  docs: 'https://reaviz.io/?path=/story/docs-intro--page'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://reaviz.io/?path=/story/docs-getting-started-quick-start--page'\ngithub_data:\n  stars: 1092\n  contributors: 28\n  issues: 36\n  stale_issues: 27\n  last_release:\n    date: null\n    link: null\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/recharts.yml",
    "content": "title: Recharts\ndescription: Composable charting library built on React components\nlogo: recharts.png\ndeveloper: null\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/recharts/recharts/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 1\n  easy-to-start-with: 3\n  full-fledged: 0\n  very-popular: 1\n  well-documented: 3\ngallery:\n  - /images/slider/recharts-1.png\n  - /images/slider/recharts-2.png\n  - /images/slider/recharts-3.png\n  - /images/slider/recharts-4.png\n  - /images/slider/recharts-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - react\nslugs:\n  github: recharts/recharts\n  npm: recharts\ntags:\n  stackoverflow:\n    - recharts\n  twitter:\n    - recharts\nlinks:\n  website: 'https://recharts.org/en-US/'\n  examples: 'https://recharts.org/en-US/examples'\n  docs: 'https://recharts.org/en-US/api'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting started\n    link: 'https://recharts.org/en-US/guide/getting-started'\n  - type: cube\n    title: Building a Recharts Dashboard with Cube\n    link: 'https://cube.dev/blog/building-a-recharts-dashboard-with-cube/'\n  - type: cube\n    title: 'React Dashboard: an Ultimate Guide'\n    link: 'https://react-dashboard.cube.dev'\ngithub_data:\n  stars: 24690\n  contributors: 351\n  issues: 444\n  stale_issues: 348\n  last_release:\n    date: '2025-02-26T04:14:36Z'\n    link: 'https://github.com/recharts/recharts/releases/tag/v3.0.0-alpha.8'\nstackoverflow_data:\n  questions_count: 783\n"
  },
  {
    "path": "copy/tools/redash.yml",
    "content": "title: Redash\ndescription: Collaborative visualization and dashboarding platform\nlogo: redash.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: BSD\n    link: 'https://github.com/getredash/redash/blob/master/LICENSE'\ntypes:\n  - app\nrenders: null\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages: null\nframeworks: null\nslugs:\n  github: getredash/redash\n  npm: null\n  npm_types: null\ntags:\n  stackoverflow:\n    - redash\n  twitter:\n    - redash\nlinks:\n  website: 'https://redash.io'\n  examples: 'https://redash.io/help/user-guide/visualizations/visualization-types'\n  docs: 'https://redash.io/help/open-source/setup'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://redash.io/help/user-guide/getting-started'\ngithub_data:\n  stars: 27000\n  contributors: 525\n  issues: 595\n  stale_issues: 525\n  last_release:\n    date: '2025-01-08T19:06:48Z'\n    link: 'https://github.com/getredash/redash/releases/tag/v25.1.0'\nstackoverflow_data:\n  questions_count: 138\n"
  },
  {
    "path": "copy/tools/rough.yml",
    "content": "title: Rough.js\ndescription: 'Graphics library for drawing with a hand-drawn, sketchy appearance'\nlogo: rough.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/rough-stuff/rough/blob/master/LICENSE'\ntypes:\n  - low-level\nrenders:\n  - svg\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/rough-1.png\n  - /images/slider/rough-2.png\n  - /images/slider/rough-3.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - vue\nslugs:\n  github: rough-stuff/rough\n  npm: roughjs\ntags:\n  stackoverflow: null\n  twitter:\n    - roughjs\nlinks:\n  website: 'https://roughjs.com'\n  examples: null\n  docs: 'https://github.com/rough-stuff/rough/wiki'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://roughjs.com'\ngithub_data:\n  stars: 20139\n  contributors: 13\n  issues: 34\n  stale_issues: 29\n  last_release:\n    date: '2019-03-14T19:05:30Z'\n    link: 'https://github.com/rough-stuff/rough/releases/tag/v3.1.0'\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/roughviz.yml",
    "content": "title: roughViz.js\ndescription: >-\n  JavaScript library for creating sketchy/hand-drawn styled charts, based on\n  D3.js, Rough.js, and Handy\nlogo: roughviz.png\ndeveloper: null\nbased_on:\n  - d3\n  - rough\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/jwilber/roughViz/blob/master/LICENSE'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/roughviz-1.png\n  - /images/slider/roughviz-2.png\nlanguages:\n  - JavaScript\nframeworks:\n  - vanilla-js\n  - react\n  - vue\nslugs:\n  github: jwilber/roughViz\n  npm: rough-viz\ntags:\n  stackoverflow: null\n  twitter:\n    - roughViz\nlinks:\n  website: null\n  examples: null\n  docs: 'https://github.com/jwilber/roughViz#api'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://github.com/jwilber/roughViz#installation'\ngithub_data:\n  stars: 6762\n  contributors: 16\n  issues: 10\n  stale_issues: 10\n  last_release:\n    date: null\n    link: null\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/semiotic.yml",
    "content": "title: Semiotic\ndescription: Data visualization framework for React\nlogo: semiotic.png\ndeveloper: null\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/nteract/semiotic/blob/master/LICENSE'\ntypes:\n  - low-level\nrenders:\n  - svg\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/semiotic-1.png\n  - /images/slider/semiotic-2.png\n  - /images/slider/semiotic-3.png\n  - /images/slider/semiotic-4.png\n  - /images/slider/semiotic-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - react\nslugs:\n  github: nteract/semiotic\n  npm: semiotic\ntags:\n  stackoverflow:\n    - semiotic\n  twitter: null\nlinks:\n  website: 'https://semiotic.nteract.io'\n  examples: 'https://semiotic.nteract.io/examples'\n  docs: 'https://semiotic.nteract.io/api'\n  pricing: null\n  slack: null\ncontent: null\ngithub_data:\n  stars: 2444\n  contributors: 31\n  issues: 33\n  stale_issues: 33\n  last_release:\n    date: '2020-01-21T03:13:12Z'\n    link: 'https://github.com/nteract/semiotic/releases/tag/v1.20.5'\nstackoverflow_data:\n  questions_count: 4\n"
  },
  {
    "path": "copy/tools/stackgl.yml",
    "content": "title: stackgl\ndescription: Open software ecosystem for WebGL\nlogo: stackgl.svg\ndeveloper: null\nbased_on: null\nlicenses: null\ntypes:\n  - low-level\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/stackgl-1.jpg\n  - /images/slider/stackgl-2.jpg\n  - /images/slider/stackgl-3.jpg\n  - /images/slider/stackgl-4.jpg\n  - /images/slider/stackgl-5.jpg\nlanguages:\n  - JavaScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: stackgl/shader-school\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'http://stack.gl'\n  examples: 'http://stack.gl/#examples'\n  docs: 'http://stack.gl/packages/'\n  pricing: null\n  slack: null\ncontent: null\ngithub_data:\n  stars: 4342\n  contributors: 22\n  issues: 44\n  stale_issues: 44\n  last_release:\n    date: null\n    link: null\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/superset.yml",
    "content": "title: Apache Superset\ndescription: Modern data exploration and visualization platform\nlogo: superset.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/apache/superset/blob/master/LICENSE.txt'\ntypes:\n  - app\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/superset-1.png\n  - /images/slider/superset-2.png\n  - /images/slider/superset-3.png\n  - /images/slider/superset-4.png\n  - /images/slider/superset-5.png\nlanguages: null\nframeworks: null\nslugs:\n  github: apache/superset\ntags:\n  stackoverflow:\n    - superset\n    - apache-superset\n  twitter:\n    - ApacheSuperset\nlinks:\n  website: 'https://superset.apache.org'\n  examples: 'https://superset.apache.org/gallery'\n  docs: 'https://superset.apache.org/docs/intro'\n  pricing: null\n  slack: >-\n    https://apache-superset.slack.com/join/shared_invite/zt-l5f5e0av-fyYu8tlfdqbMdz_sPLwUqQ\ncontent:\n  - type: official\n    title: What is Apache Superset?\n    link: 'https://superset.apache.org/docs/intro'\n  - type: cube\n    title: Building a metrics dashboard with Superset and Cube\n    link: 'https://cube.dev/blog/building-metrics-dashboard-with-superset/'\ngithub_data:\n  stars: 64736\n  contributors: 1275\n  issues: 766\n  stale_issues: 203\n  last_release:\n    date: '2025-02-04T19:04:37Z'\n    link: 'https://github.com/apache/superset/releases/tag/5.0.0rc1'\nstackoverflow_data:\n  questions_count: 1417\n"
  },
  {
    "path": "copy/tools/three.yml",
    "content": "title: three.js\ndescription: JavaScript 3D library\nlogo: threejs.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/mrdoob/three.js/blob/dev/LICENSE'\ntypes:\n  - 3d\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 1\n  well-documented: 0\ngallery:\n  - /images/slider/three-1.jpg\n  - /images/slider/three-2.jpg\n  - /images/slider/three-3.jpg\n  - /images/slider/three-4.jpg\n  - /images/slider/three-5.jpg\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\nslugs:\n  github: mrdoob/three.js\n  npm: three\n  npm_types: '@types/three'\ntags:\n  stackoverflow:\n    - three.js\n  twitter:\n    - threejs\nlinks:\n  website: 'https://threejs.org'\n  examples: 'https://threejs.org/examples/#webgl_animation_cloth'\n  docs: 'https://threejs.org/docs/index.html'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Creating a scene in three.js\n    link: >-\n      https://threejs.org/docs/index.html#manual/en/introduction/Creating-a-scene\ngithub_data:\n  stars: 104617\n  contributors: 2359\n  issues: 428\n  stale_issues: 296\n  last_release:\n    date: '2025-02-27T09:33:44Z'\n    link: 'https://github.com/mrdoob/three.js/releases/tag/r174'\nstackoverflow_data:\n  questions_count: 21272\n"
  },
  {
    "path": "copy/tools/toast-ui-chart.yml",
    "content": "title: TOAST UI Chart\ndescription: Beautiful chart for data visualization\nlogo: toast-ui-chart.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/nhn/tui.chart/blob/main/LICENSE'\ntypes:\n  - charts\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - vue\nslugs:\n  github: nhn/tui.chart\n  npm: tui-chart\ntags:\n  stackoverflow:\n    - toast-ui-chart\n  twitter: null\nlinks:\n  website: 'https://ui.toast.com/tui-chart'\n  examples: >-\n    https://nhn.github.io/tui.chart/latest/tutorial-example01-01-area-chart-basic\n  docs: 'https://nhn.github.io/tui.chart/latest/'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://github.com/nhn/tui.chart/blob/main/docs/en/getting-started.md'\ngithub_data:\n  stars: 5363\n  contributors: 12\n  issues: 19\n  stale_issues: 15\n  last_release:\n    date: '2022-12-21T03:06:57Z'\n    link: 'https://github.com/nhn/tui.chart/releases/tag/v4.6.1'\nstackoverflow_data:\n  questions_count: 2\n"
  },
  {
    "path": "copy/tools/unovis.yml",
    "content": "title: Unovis\ndescription: >-\n  Modular data visualization framework for React, Angular, Svelte, and vanilla\n  TypeScript or JavaScript\nlogo: unovis.svg\ndeveloper: null\nbased_on:\n  - d3\n  - leaflet\n  - maplibre\nlicenses:\n  - type: open-source\n    title: Apache-2.0\n    link: 'https://github.com/f5/unovis/blob/main/LICENSE'\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 1\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 1\ngallery:\n  - /images/slider/unovis-1.png\n  - /images/slider/unovis-2.png\n  - /images/slider/unovis-3.png\n  - /images/slider/unovis-4.png\n  - /images/slider/unovis-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - svelte\nslugs:\n  github: f5/unovis\n  npm: '@unovis'\ntags:\n  stackoverflow:\n    - unovis\n  twitter:\n    - unovisdev\nlinks:\n  website: 'https://unovis.dev'\n  examples: 'https://unovis.dev/gallery'\n  docs: 'https://unovis.dev/docs'\n  pricing: null\ncontent:\n  - type: official\n    title: Quick Start Guide\n    link: 'https://unovis.dev/docs/quick-start'\ngithub_data:\n  stars: 2384\n  contributors: 14\n  issues: 52\n  stale_issues: 11\n  last_release:\n    date: '2025-02-19T18:33:01Z'\n    link: 'https://github.com/f5/unovis/releases/tag/1.5.1'\nstackoverflow_data:\n  questions_count: 0\n"
  },
  {
    "path": "copy/tools/vega-lite.yml",
    "content": "title: Vega-Lite\ndescription: 'Concise grammar of interactive graphics, built on Vega'\nlogo: vega-lite.svg\ndeveloper: null\nbased_on:\n  - vega\nlicenses:\n  - type: open-source\n    title: BSD\n    link: 'https://github.com/vega/vega-lite/blob/master/LICENSE'\ntypes:\n  - low-level\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/vega-lite-1.png\n  - /images/slider/vega-lite-2.png\n  - /images/slider/vega-lite-3.png\n  - /images/slider/vega-lite-4.png\n  - /images/slider/vega-lite-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\nslugs:\n  github: vega/vega-lite\n  npm: vega-lite\ntags:\n  stackoverflow:\n    - vega-lite\n  twitter:\n    - vegalite\nlinks:\n  website: 'https://vega.github.io/vega-lite/'\n  examples: 'https://vega.github.io/vega-lite/examples/'\n  docs: 'https://vega.github.io/vega-lite/docs/'\n  pricing: null\n  slack: 'https://bit.ly/join-vega-slack-2020'\ncontent:\n  - type: official\n    title: Introduction to Vega-Lite\n    link: 'https://vega.github.io/vega-lite/tutorials/getting_started.html'\ngithub_data:\n  stars: 4774\n  contributors: 213\n  issues: 708\n  stale_issues: 637\n  last_release:\n    date: '2024-12-10T17:38:11Z'\n    link: 'https://github.com/vega/vega-lite/releases/tag/v5.23.0'\nstackoverflow_data:\n  questions_count: 1552\n"
  },
  {
    "path": "copy/tools/vega.yml",
    "content": "title: Vega\ndescription: >-\n  Visualization grammar, a declarative language for creating and sharing\n  visualization designs\nlogo: vega.svg\ndeveloper: null\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: BSD\n    link: 'https://github.com/vega/vega/blob/master/LICENSE'\ntypes:\n  - low-level\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/vega-1.png\n  - /images/slider/vega-2.png\n  - /images/slider/vega-3.png\n  - /images/slider/vega-4.png\n  - /images/slider/vega-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\nslugs:\n  github: vega/vega\n  npm: vega\ntags:\n  stackoverflow:\n    - vega\n  twitter:\n    - vegajs\nlinks:\n  website: 'https://vega.github.io/vega/'\n  examples: 'https://vega.github.io/vega/examples/'\n  docs: 'https://vega.github.io/vega/docs/'\n  pricing: null\n  slack: 'https://bit.ly/join-vega-slack-2020'\ncontent:\n  - type: official\n    title: Let's Make a Bar Chart\n    link: 'https://vega.github.io/vega/tutorials/bar-chart/'\ngithub_data:\n  stars: 11384\n  contributors: 156\n  issues: 445\n  stale_issues: 407\n  last_release:\n    date: '2025-02-28T02:48:35Z'\n    link: 'https://github.com/vega/vega/releases/tag/v5.32.0'\nstackoverflow_data:\n  questions_count: 1077\n"
  },
  {
    "path": "copy/tools/victory.yml",
    "content": "title: Victory\ndescription: React components for modular charting and data visualization\nlogo: victory.png\ndeveloper: Formidable\nbased_on: null\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/FormidableLabs/victory/blob/main/LICENSE.txt'\ntypes:\n  - charts\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/victory-1.png\n  - /images/slider/victory-2.png\n  - /images/slider/victory-3.png\n  - /images/slider/victory-4.png\n  - /images/slider/victory-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - react\nslugs:\n  github: FormidableLabs/victory\n  npm: victory\ntags:\n  stackoverflow:\n    - victory-charts\n    - victory-native\n  twitter:\n    - VictoryCharts\nlinks:\n  website: 'https://formidable.com/open-source/victory/'\n  examples: 'https://formidable.com/open-source/victory/gallery'\n  docs: 'https://formidable.com/open-source/victory/docs'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting Started with Victory\n    link: 'https://formidable.com/open-source/victory/docs'\n  - type: cube\n    title: React Native Charts with Cube.js and Victory\n    link: 'https://cube.dev/blog/react-native-charts-with-cubejs-victory/'\ngithub_data:\n  stars: 11096\n  contributors: 247\n  issues: 91\n  stale_issues: 66\n  last_release:\n    date: '2025-01-14T17:23:54Z'\n    link: 'https://github.com/FormidableLabs/victory/releases/tag/v37.3.6'\nstackoverflow_data:\n  questions_count: 306\n"
  },
  {
    "path": "copy/tools/vis.yml",
    "content": "title: vis.js\ndescription: Dynamic visualization library\nlogo: visjs.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/visjs/vis-charts/blob/master/LICENSE-APACHE-2.0'\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/vis-1.png\n  - /images/slider/vis-2.png\n  - /images/slider/vis-3.png\n  - /images/slider/vis-4.png\n  - /images/slider/vis-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: visjs/vis-charts\n  npm: vis-charts\n  npm_types: '@types/vis'\ntags:\n  stackoverflow:\n    - vis.js\n  twitter:\n    - visjs\nlinks:\n  website: 'https://visjs.org'\n  examples: 'https://visjs.github.io/vis-timeline/examples/graph2d/'\n  docs: 'https://visjs.github.io/vis-timeline/docs/graph2d/'\n  pricing: null\n  slack: null\ncontent: null\ngithub_data:\n  stars: 113\n  contributors: 43\n  issues: 0\n  stale_issues: 0\n  last_release:\n    date: '2020-05-17T12:03:36Z'\n    link: 'https://github.com/visjs/vis-charts/releases/tag/v3.0.0'\nstackoverflow_data:\n  questions_count: 795\n"
  },
  {
    "path": "copy/tools/visx.yml",
    "content": "title: visx\ndescription: 'Collection of expressive, low-level visualization primitives for React'\nlogo: visx.png\ndeveloper: Airbnb\nbased_on:\n  - d3\nlicenses:\n  - type: open-source\n    title: MIT\n    link: 'https://github.com/airbnb/visx/blob/master/LICENSE'\ntypes:\n  - low-level\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/visx-1.png\n  - /images/slider/visx-2.png\n  - /images/slider/visx-3.png\n  - /images/slider/visx-4.png\n  - /images/slider/visx-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - react\nslugs:\n  github: airbnb/visx\n  npm: '@visxx/visx'\ntags:\n  stackoverflow: null\n  twitter: null\nlinks:\n  website: 'https://airbnb.io/visx/'\n  examples: 'https://airbnb.io/visx/gallery'\n  docs: 'https://airbnb.io/visx/docs'\n  pricing: null\n  slack: null\ncontent:\n  - type: official\n    title: Getting started with vx\n    link: 'https://medium.com/vx-code/getting-started-with-vx-1756bb661410'\n  - type: cube\n    title: Building a visx Dashboard with Cube\n    link: 'https://cube.dev/blog/building-a-visx-dashboard-with-cube'\ngithub_data:\n  stars: 19799\n  contributors: 177\n  issues: 126\n  stale_issues: 106\n  last_release:\n    date: '2024-11-07T18:38:04Z'\n    link: 'https://github.com/airbnb/visx/releases/tag/v3.12.0'\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/vizzu.yml",
    "content": "title: Vizzu\ndescription: Library for animated data visualizations and data stories\nlogo: vizzu.svg\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: open-source\n    title: Apache 2.0\n    link: 'https://github.com/vizzuhq/vizzu-lib/blob/main/LICENSE'\ntypes:\n  - charts\nrenders:\n  - canvas\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery: []\nlanguages:\n  - JavaScript\nframeworks:\n  - vanilla-js\nslugs:\n  github: vizzuhq/vizzu-lib\n  npm: vizzu\ntags:\n  stackoverflow: null\n  twitter:\n    - Vizzu\nlinks:\n  website: 'https://vizzuhq.com'\n  examples: 'https://lib.vizzuhq.com/0.3.0/#examples-1.0'\n  docs: 'https://lib.vizzuhq.com/0.3.0/'\n  pricing: null\n  slack: >-\n    https://join.slack.com/t/vizzu-community/shared_invite/zt-w2nqhq44-2CCWL4o7qn2Ns1EFSf9kEg\ncontent:\n  - type: official\n    title: Getting Started\n    link: 'https://lib.vizzuhq.com/0.3.0/'\ngithub_data:\n  stars: 1954\n  contributors: 14\n  issues: 2\n  stale_issues: 2\n  last_release:\n    date: '2025-02-24T19:33:42Z'\n    link: 'https://github.com/vizzuhq/vizzu-lib/releases/tag/v0.16.1'\nstackoverflow_data: null\n"
  },
  {
    "path": "copy/tools/zingchart.yml",
    "content": "title: ZingChart\ndescription: >-\n  Declarative, efficient, and simple JavaScript library for building responsive\n  charts\nlogo: zingchart.png\ndeveloper: null\nbased_on: null\nlicenses:\n  - type: proprietary\ntypes:\n  - charts\n  - maps\nrenders:\n  - svg\nfeatures:\n  easy-to-customize: 0\n  easy-to-start-with: 0\n  full-fledged: 0\n  very-popular: 0\n  well-documented: 0\ngallery:\n  - /images/slider/zingchart-1.png\n  - /images/slider/zingchart-2.png\n  - /images/slider/zingchart-3.png\n  - /images/slider/zingchart-4.png\n  - /images/slider/zingchart-5.png\nlanguages:\n  - JavaScript\n  - TypeScript\nframeworks:\n  - vanilla-js\n  - react\n  - angular\n  - vue\nslugs:\n  github: zingchart/ZingChart\n  npm: zingchart\n  npm_types: '@types/zingchart'\ntags:\n  stackoverflow:\n    - zingchart\n  twitter:\n    - ZingChart\nlinks:\n  website: 'https://www.zingchart.com'\n  examples: 'https://www.zingchart.com/gallery?type=chartType'\n  docs: 'https://www.zingchart.com/docs'\n  pricing: 'https://www.zingchart.com/pricing'\n  slack: null\ncontent:\n  - type: official\n    title: Your First JavaScript Chart\n    link: 'https://www.zingchart.com/docs/getting-started/your-first-javascript-chart'\ngithub_data:\n  stars: 277\n  contributors: 23\n  issues: 0\n  stale_issues: 0\n  last_release:\n    date: '2025-01-16T18:07:36Z'\n    link: 'https://github.com/zingchart/ZingChart/releases/tag/2.9.16-1'\nstackoverflow_data:\n  questions_count: 259\n"
  },
  {
    "path": "data/filter.js",
    "content": "const filter = (tools, framework, language, license, render, exploreTools) => {\n  const filtered = tools.filter((tool) => {\n    let isValid = true;\n\n    if (exploreTools.length && isValid) {\n      isValid = hasTypes(tool, exploreTools);\n    }\n    if (framework.length && isValid) {\n      isValid = isCompatibleWith(tool, framework);\n    }\n    if (language.length && isValid) {\n      let hasInclude = 0;\n      tool?.languages?.forEach((lg) => {\n        if (language.includes(lg.toLowerCase())) {\n          hasInclude++;\n        }\n      });\n      isValid = language.length === hasInclude;\n    }\n    if (license.length && isValid) {\n      isValid = hasLicenses(tool, license);\n    }\n    if (render.length && isValid) {\n      let hasInclude = 0;\n      tool?.renders?.forEach((obj) => {\n        if (render.includes(obj.toLowerCase())) {\n          hasInclude++;\n        }\n      });\n      isValid = render.length === hasInclude;\n    }\n    return isValid;\n  });\n\n  const maxFeatureScores = getMaxFeatureScores(tools);\n  const maxFeatureScoresCopy = Object.assign({}, maxFeatureScores);\n\n  return filtered\n    .map((tool) => {\n      const feature_label = getFeatureWithMaxScore(tool, maxFeatureScores);\n\n      if (feature_label) {\n        delete maxFeatureScores[feature_label];\n      }\n\n      return {\n        ...tool,\n        feature_label,\n      };\n    })\n    .sort(getComparator(maxFeatureScoresCopy));\n};\n\nfunction getComparator(maxFeatureScores) {\n  return function (a, b) {\n    // Adding 1,000,000 to the number of GitHub stars is going to pull the tool up to the top.\n    // As of 2021-06-01, freeCodeCamp/freeCodeCamp has 325,000 stars\n    const aSortKey =\n      (a.feature_label ? 1000000 : 0) + (a.github_data?.stars || 0);\n    const bSortKey =\n      (b.feature_label ? 1000000 : 0) + (b.github_data?.stars || 0);\n\n    return bSortKey - aSortKey;\n  };\n}\n\nfunction getMaxFeatureScores(tools) {\n  return tools.reduce((features, tool) => {\n    if (tool.features) {\n      Object.entries(tool.features)\n        .filter(([_, score]) => score !== 0)\n        .forEach(([feature, score]) => {\n          features[feature] =\n            features[feature] !== undefined\n              ? Math.max(features[feature], score)\n              : score;\n        });\n    }\n\n    return features;\n  }, {});\n}\n\nfunction getFeatureWithMaxScore(tool, maxFeatureScores) {\n  if (tool.features) {\n    return Object.entries(tool.features)\n      .sort((a, b) => b[1] - a[1])\n      .filter(([_, score]) => score !== 0)\n      .reduce((selectMaxFeature, [feature, score]) => {\n        return (\n          selectMaxFeature ||\n          Object.entries(maxFeatureScores).find(\n            ([maxFeature, maxScore]) =>\n              feature === maxFeature && score === maxScore\n          )?.[0]\n        );\n      }, undefined);\n  }\n\n  return false;\n}\n\nconst setParamsFromRouter = (\n  query,\n  setExploreTools,\n  setFramework,\n  setLanguage,\n  setLicense\n) => {\n  if (query.tools) {\n    setExploreTools(\n      typeof query.tools === \"string\" ? [query.tools] : [...query.tools]\n    );\n  }\n  if (query.framework) {\n    setFramework(\n      typeof query.framework === \"string\"\n        ? [query.framework]\n        : [...query.framework]\n    );\n  }\n  if (query.language) {\n    setLanguage(\n      typeof query.language === \"string\"\n        ? [query.language]\n        : [...query.language]\n    );\n  }\n  if (query.license) {\n    setLicense(\n      typeof query.license === \"string\" ? [query.license] : [...query.license]\n    );\n  }\n};\n\nfunction hasTypes(tool, types) {\n  return types.every(t => tool?.types?.some(type => type === t.toLowerCase()))\n}\n\nfunction isCompatibleWith(tool, frameworks) {\n  return frameworks.every(fw => tool?.frameworks?.some(framework => framework === fw.toLowerCase()))\n}\n\nfunction hasLicenses(tool, licenses) {\n  return licenses.every(l => tool?.licenses?.some(license => license.type === l.toLowerCase()))\n}\n\nexport { filter, setParamsFromRouter, hasTypes, isCompatibleWith, hasLicenses };\n"
  },
  {
    "path": "data/frameworks.js",
    "content": "export default {\n  react: {\n    slug: \"react\",\n    name: \"React\",\n    icon: \"react.svg\",\n  },\n  angular: {\n    slug: \"angular\",\n    name: \"Angular\",\n    icon: \"angular.svg\",\n  },\n  vue: {\n    slug: \"vue\",\n    name: \"Vue\",\n    icon: \"vue.svg\",\n  },\n  svelte: {\n    slug: \"svelte\",\n    name: \"Svelte\",\n    icon: \"svelte.svg\",\n  },\n};"
  },
  {
    "path": "data/tools.js",
    "content": "import fs from \"fs\";\nimport yaml from \"node-yaml\";\n\nexport const toolCopyPath = `${process.cwd()}/copy/tools`;\n\nasync function readTools() {\n  const files = fs.readdirSync(toolCopyPath);\n  const ids = files\n    .filter((filename) => filename.endsWith(\".yml\"))\n    .map((filename) => filename.split(\".\")[0]);\n\n  const tools = {};\n  const extendedTools = {};\n\n  for (const id of ids) {\n    tools[id] = await readTool(id);\n  }\n\n  for (const id of ids) {\n    extendedTools[id] = await extendTool(tools[id], tools);\n  }\n\n  return extendedTools;\n}\n\nexport async function readTool(id) {\n  const tool = await yaml.read(`${toolCopyPath}/${id}.yml`);\n  return { id, ...tool };\n}\n\nasync function extendTool(tool, tools) {\n  const positionsByStars = Object.values(tools)\n    .map((t) => ({ key: t.id, value: t.github_data?.stars }))\n    .sort(compare);\n\n  tool.positions = {\n    total: Object.keys(tools).length,\n    stars:\n      1 +\n      positionsByStars.findIndex(\n        (pair) => pair.value === tool.github_data?.stars\n      ),\n  };\n\n  tool.percentages = {\n    stale_issues:\n      tool.github_data?.issues > 0\n        ? 100 *\n          (\n            (tool.github_data?.stale_issues || 0) / tool.github_data?.issues\n          ).toFixed(2)\n        : 0,\n  };\n\n  return tool;\n}\n\nfunction compare(a, b) {\n  return (b.value || 0) - (a.value || 0);\n}\n\nexport async function getTools() {\n  const tools = await readTools();\n  return Object.values(tools);\n}\n\nexport async function getTool(id) {\n  const tools = await readTools();\n  return tools[id];\n}\n"
  },
  {
    "path": "data/types.js",
    "content": "export default {\n  charts: {\n    slug: \"charts\",\n    name: \"Charting libraries\",\n    image: \"chart.svg\",\n    descriptor: \"a charting library\",\n  },\n  \"low-level\": {\n    slug: \"low-level\",\n    name: \"Low-level tools\",\n    image: \"lines.svg\",\n    descriptor: \"a low-level data visualization library\",\n  },\n  maps: {\n    slug: \"maps\",\n    name: \"Mapping tools\",\n    image: \"globe.svg\",\n    descriptor: \"a mapping or spatial library\",\n  },\n  grid: {\n    slug: \"grid\",\n    name: \"Data grids\",\n    image: \"grid.svg\",\n    descriptor: \"a data grid or pivot table library\",\n  },\n  \"3d\": {\n    slug: \"3d\",\n    name: \"3D tools\",\n    image: \"3d.svg\",\n    descriptor: \"a 3D visualization library\",\n  },\n  app: {\n    slug: \"app\",\n    name: \"Exploration apps\",\n    image: \"apps.svg\",\n    descriptor: \"a data exploration application\",\n  },\n};"
  },
  {
    "path": "data/useSlackMembers.js",
    "content": "import { useState, useEffect } from \"react\";\nimport fetch from \"isomorphic-unfetch\";\nimport abbreviateNumber from \"../utils/number\";\n\nconst cubeUrl = \"https://amaranth-leech.gcp-us-central1.cubecloudapp.dev/cubejs-api/v1/load\";\nconst cubeToken = \"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjEwMDAwMDAwMDAsImV4cCI6NTAwMDAwMDAwMH0.OHZOpOBVKr-sCwn8sbZ5UFsqI3uCs6e4omT7P6WVMFw\";\n\nconst cubeQuery = {\n  measures: [\n    \"SlackUsers.count\"\n  ]\n};\n\nexport default function useSlackMembers() {\n  const [slackMembers, setSlackMembers] = useState(abbreviateNumber(5100));\n\n  useEffect(() => {\n    const url = new URL(cubeUrl);\n    url.search = new URLSearchParams({\n      query: JSON.stringify(cubeQuery, null, 2)\n    }).toString();\n\n    const options = {\n      headers: {\n        Authorization: cubeToken\n      },\n    };\n\n    fetch(url, options)\n      .then((response) => response.json())\n      .then((response) => response.data[0][\"SlackUsers.count\"])\n      .then((count) => setSlackMembers(abbreviateNumber(count)))\n      .catch(() => {}); // Skip error\n  }, []);\n\n  return slackMembers;\n}\n"
  },
  {
    "path": "data-update-worker/.gitignore",
    "content": ".env\nnode_modules"
  },
  {
    "path": "data-update-worker/fetchData.js",
    "content": "const fetch = require(\"node-fetch\");\nrequire(\"dotenv\").config();\n\nconst getGithubData = async (githubSlug) => {\n  if (!githubSlug) {\n    return null;\n  }\n  const headers = {\n    headers: {\n      Authorization: `token ${process.env.ACCESS_TOKEN_GITHUB}`,\n    },\n  };\n  let repo = null;\n  let contributors = null;\n  let releases = null;\n  let issues = null;\n  let stale_issues = null;\n  let stale_date = getStaleDate();\n\n  try {\n    issues = await loadJSON(\n      `https://api.github.com/search/issues?q=repo:${githubSlug}+type:issue+state:open&per_page=1`,\n      headers\n    );\n    stale_issues = await loadJSON(\n      `https://api.github.com/search/issues?q=repo:${githubSlug}+type:issue+created:<${stale_date}+state:open&per_page=1`,\n      headers\n    );\n    repo = await loadJSON(\n      `https://api.github.com/repos/${githubSlug}`,\n      headers\n    );\n    contributors = await loadHeaders(\n      `https://api.github.com/repos/${githubSlug}/contributors?per_page=1&anon=true`,\n      headers\n    );\n    releases = await loadJSON(\n      `https://api.github.com/repos/${githubSlug}/releases`,\n      headers\n    );\n  } catch (e) {\n    throw new Error(e);\n  }\n\n  if (\n    repo.message ||\n    releases.message ||\n    issues.message ||\n    stale_issues.message ||\n    contributors.message\n  ) {\n    throw new Error(\n      `Bad request: ${\n        repo.message ||\n        releases.message ||\n        issues.message ||\n        stale_issues.message ||\n        contributors.message\n      }`\n    );\n  }\n\n  return {\n    stars: repo?.stargazers_count,\n    contributors: getContributorsByResponseHeaders(contributors),\n    issues: issues?.total_count,\n    stale_issues: stale_issues?.total_count,\n    last_release: {\n      date: releases?.[0]?.published_at || null,\n      link: releases?.[0]?.html_url || null,\n    },\n  };\n};\n\nconst getStackoverflowDataByTags = async (tags) => {\n  if (!tags) {\n    return null;\n  }\n  // const headers = {};\n  let result = 0;\n  try {\n    await asyncForEach(tags, async (tag) => {\n      const response = await loadJSON(\n        `https://api.stackexchange.com/2.2/tags?order=desc&sort=popular&inname=${tag}&site=stackoverflow`\n      );\n\n      response?.items?.forEach((item) => {\n        if (item.name === tag && item.count) {\n          result += item.count;\n        }\n      });\n    });\n  } catch (e) {\n    console.log(e);\n    throw new Error(e);\n  }\n  return {\n    questions_count: result,\n  };\n};\n\nasync function loadJSON(url, headers) {\n  try {\n    const res = await fetch(url, headers);\n    return await res.json();\n  } catch (e) {\n    throw new Error(e);\n  }\n}\nasync function loadHeaders(url, headers) {\n  try {\n    const res = await fetch(url, headers);\n    return await res.headers.get(\"Link\");\n  } catch (e) {\n    throw new Error(e);\n  }\n}\n\nfunction getStaleDate() {\n  var date = new Date();\n  date.setFullYear(date.getFullYear() - 1);\n\n  return date.toISOString().split(\"T\")[0];\n}\n\nfunction getContributorsByResponseHeaders(str) {\n  if (!str) {\n    return null;\n  }\n  let newStr = str.slice(str.indexOf('rel=\"next\"'));\n  let start = newStr.indexOf(\"&page=\");\n  let end = newStr.length - 13;\n  let result = newStr.slice(start, end);\n  let numb = result.match(/\\d/g);\n  return parseInt(numb.join(\"\"));\n}\n\nasync function asyncForEach(array, callback) {\n  for (let index = 0; index < array.length; index++) {\n    await callback(array[index], index, array);\n  }\n}\n\nexports.getGithubData = getGithubData;\nexports.getStackoverflowDataByTags = getStackoverflowDataByTags;\n"
  },
  {
    "path": "data-update-worker/index.js",
    "content": "const yaml = require(\"node-yaml\");\nconst fs = require(\"fs\");\nconst get = require(\"./fetchData.js\");\nconst { notifySlackUpdateFailures } = require(\"./notifySlack.js\");\n\nconst files = fs.readdirSync(\"../copy/tools\");\nconst ids = files\n  .filter((filename) => filename.endsWith(\".yml\"))\n  .map((filename) => filename.split(\".\")[0]);\n\nlet failures = [];\n\nasyncForEach(ids, async (id) => {\n  try {\n    const file = await yaml.read(`../copy/tools/${id}.yml`);\n    file.github_data = await get.getGithubData(file?.slugs?.github);\n\n    file.stackoverflow_data = await get.getStackoverflowDataByTags(\n      file?.tags?.stackoverflow\n    );\n\n    await yaml.write(`../copy/tools/${id}.yml`, file);\n    console.log(id, \"success\");\n\n    // sleep\n    await new Promise((resolve) => setTimeout(resolve, 15000));\n  } catch (e) {\n    console.log(`${id}`, e);\n    failures.push({\n      id,\n      error: e,\n    });\n  }\n}).then(() => {\n  if (failures.length) {\n    return notifySlackUpdateFailures(failures);\n  }\n});\n\nasync function asyncForEach(array, callback) {\n  for (let index = 0; index < array.length; index++) {\n    await callback(array[index], index, array);\n  }\n}\n"
  },
  {
    "path": "data-update-worker/notifySlack.js",
    "content": "const fetch = require(\"node-fetch\");\nrequire(\"dotenv\").config();\n\n/**\n * @param {Array<any>} blocks \n * @returns Promise\n */\nconst notifySlack = async (blocks) =>\n  fetch(process.env.SLACK_WEBHOOK_URL, {\n    method: \"POST\",\n    body: JSON.stringify({\n      blocks,\n    }),\n  });\n\n/**\n * @param {Array<{ id: string; error: string }>} failures \n * @returns Promise\n */\nconst notifySlackUpdateFailures = async (failures) =>\n  notifySlack([\n    {\n      type: \"header\",\n      text: {\n        type: \"plain_text\",\n        text: \"⚠️ Failed to update some tools\",\n        emoji: true,\n      },\n    },\n\n    {\n      type: \"section\",\n      text: {\n        type: \"mrkdwn\",\n        text: `<${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}|GitHub Run>`,\n      },\n    },\n\n    ...failures.map((failure) => ({\n      type: \"section\",\n      text: {\n        type: \"mrkdwn\",\n        text: `*${failure.id}:*\\n${failure.error}`,\n      },\n    })),\n  ]);\n\nexports.notifySlack = notifySlack;\nexports.notifySlackUpdateFailures = notifySlackUpdateFailures;\n"
  },
  {
    "path": "data-update-worker/package.json",
    "content": "{\n  \"name\": \"job\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"author\": \"\",\n  \"license\": \"ISC\",\n  \"dependencies\": {\n    \"dotenv\": \"^10.0.0\",\n    \"fs\": \"^0.0.1-security\",\n    \"js-yaml\": \"^4.1.0\",\n    \"node-fetch\": \"^2.6.1\"\n  }\n}\n"
  },
  {
    "path": "netlify.toml",
    "content": "[build]\n  publish = \".next\"\n"
  },
  {
    "path": "next-sitemap.config.js",
    "content": "/** @type {import('next-sitemap').IConfig} */\nmodule.exports = {\n  siteUrl: process.env.SITE_URL || \"https://awesome.cube.dev/\",\n  generateRobotsTxt: true, // (optional)\n};\n"
  },
  {
    "path": "next.config.js",
    "content": "const withBundleAnalyzer = require(\"@next/bundle-analyzer\")({\n  enabled: process.env.ANALYZE === \"true\",\n});\n\nconst ContentSecurityPolicy = `\n  default-src 'self';\n  script-src 'report-sample' 'self' 'unsafe-eval' 'unsafe-inline';\n  style-src 'report-sample' 'self' 'unsafe-inline';\n  object-src 'none';\n  base-uri 'self';\n  connect-src 'self' https://amaranth-leech.gcp-us-central1.cubecloudapp.dev https://track.cube.dev https://graphql.contentful.com;\n  font-src 'self';\n  frame-src 'self';\n  img-src 'self';\n  manifest-src 'self';\n  media-src 'self';\n  worker-src 'none';\n`;\n\n/**\n * @type {import('next').NextConfig}\n */\nconst config = {\n    reactStrictMode: true,\n    async headers() {\n        return [\n            {\n                source: \"/(.*)\",\n                headers: [\n                  {\n                    key: \"Strict-Transport-Security\",\n                    value: \"max-age=31536000; includeSubDomains;\",\n                  },\n                  {\n                      key: 'Content-Security-Policy',\n                      value: ContentSecurityPolicy.replace(/\\s{2,}/g, ' ').trim(),\n                  }\n                ]\n            },\n        ]\n    },\n}\n\nmodule.exports = withBundleAnalyzer(config);\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"awesome-dataviz-tools\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"scripts\": {\n    \"dev\": \"next dev\",\n    \"build\": \"next build\",\n    \"postbuild\": \"next-sitemap\",\n    \"export\": \"next export\",\n    \"start\": \"next start\"\n  },\n  \"dependencies\": {\n    \"@cube-dev/purple-banner\": \"2.0.19\",\n    \"@netlify/plugin-nextjs\": \"^4.30.3\",\n    \"bootstrap\": \"^5.0.1\",\n    \"classnames\": \"^2.3.2\",\n    \"cubedev-tracking\": \"1.1.0\",\n    \"dayjs\": \"^1.10.7\",\n    \"isomorphic-unfetch\": \"^3.1.0\",\n    \"js-yaml\": \"^3.14.1\",\n    \"next\": \"^13.1.6\",\n    \"next-seo\": \"^5.15.0\",\n    \"next-sitemap\": \"^3.1.49\",\n    \"node-yaml\": \"^4.0.1\",\n    \"react\": \"^18.2.0\",\n    \"react-dom\": \"^18.2.0\",\n    \"react-slick\": \"^0.28.1\",\n    \"react-svg\": \"^13.0.5\",\n    \"slick-carousel\": \"^1.8.1\"\n  },\n  \"devDependencies\": {\n    \"@netlify/next\": \"^1.4.3\",\n    \"@next/bundle-analyzer\": \"^13.1.6\",\n    \"sass\": \"^1.32.13\"\n  }\n}\n"
  },
  {
    "path": "pages/_app.js",
    "content": "import React, { Fragment, useEffect } from \"react\";\nimport dynamic from \"next/dynamic\";\nimport \"../styles/globals.scss\";\nimport \"bootstrap/dist/css/bootstrap-grid.min.css\";\nimport Head from \"next/head\";\nimport Header from \"../components/Header\";\nimport PurpleBanner from \"@cube-dev/purple-banner\";\nimport { DefaultSeo } from \"next-seo\";\nimport { useRouter } from \"next/router\";\n\nconst Footer = dynamic(() => import(\"../components/Footer\"));\n\nfunction MyApp({ Component, pageProps }) {\n  useEffect(() => {\n    const { page } = require(\"cubedev-tracking\");\n    page();\n  }, []);\n\n  const router = useRouter();\n\n  return (\n    <Fragment>\n      <Head>\n        <link\n          rel=\"apple-touch-icon\"\n          sizes=\"180x180\"\n          href=\"/apple-touch-icon.png\"\n        />\n        <link\n          rel=\"icon\"\n          type=\"image/png\"\n          sizes=\"32x32\"\n          href=\"/favicon-32x32.png\"\n        />\n        <link\n          rel=\"icon\"\n          type=\"image/png\"\n          sizes=\"16x16\"\n          href=\"/favicon-16x16.png\"\n        />\n        <link rel=\"manifest\" href=\"/site.webmanifest\" />\n        <link rel=\"mask-icon\" href=\"/safari-pinned-tab.svg\" color=\"#5bbad5\" />\n        <link rel=\"icon\" href=\"/favicon.png\" type=\"image/png\" />\n        <meta name=\"msapplication-TileColor\" content=\"#da532c\" />\n        <meta name=\"theme-color\" content=\"#ffffff\" />\n\n        <meta\n          name=\"google-site-verification\"\n          content=\"zJjljUArvZ0PVn8naOnxEue8ZX0wh0nsM0q32NYnzzQ\"\n        />\n        <link\n          rel=\"preload\"\n          href=\"/fonts/CeraPro-Regular.woff2\"\n          as=\"font\"\n          crossOrigin=\"anonymous\"\n        />\n        <link\n          rel=\"preload\"\n          href=\"/fonts/CeraPro-Medium.woff2\"\n          as=\"font\"\n          crossOrigin=\"anonymous\"\n        />\n      </Head>\n\n      <DefaultSeo\n        openGraph={{\n          type: \"website\",\n          url: `https://awesome.cube.dev${router.asPath}`,\n          images: [\n            {\n              url: \"https://cubedev-blog-images.s3.us-east-2.amazonaws.com/482a86d6-d049-4d92-a0bf-0fcc5830476f.jpeg\",\n              alt: \"Data visualization tools for application developers\",\n              width: 1200,\n              height: 630,\n            },\n          ],\n        }}\n        twitter={{\n          cardType: \"summary_large_image\",\n          site: \"@thecubejs\",\n        }}\n      />\n\n      <PurpleBanner\n        utmSource=\"awesome\"\n        debugMode={process.env.NEXT_PUBLIC_SHOW_PURPLE_BANNER === \"true\"}\n      />\n      <Header />\n      <Component {...pageProps} />\n      <Footer />\n    </Fragment>\n  );\n}\n\nexport default MyApp;\n"
  },
  {
    "path": "pages/_document.js",
    "content": "import Document, { Html, Head, Main, NextScript } from 'next/document'\n\nclass MyDocument extends Document {\n  render() {\n    return (\n      <Html lang=\"en\">\n        <Head />\n        <body>\n          <Main />\n          <NextScript />\n        </body>\n      </Html>\n    )\n  }\n}\n\nexport default MyDocument"
  },
  {
    "path": "pages/for/[framework]/charting-libraries.js",
    "content": "import ListPage from '../../../components/ListPage';\nimport { getTools } from '../../../data/tools';\nimport { hasTypes, isCompatibleWith } from '../../../data/filter';\nimport frameworks from '../../../data/frameworks';\n\nexport default function Page({ tools, framework }) {\n  const frameworkName = frameworks[framework].name;\n\n  return (\n    <ListPage\n      tools={tools}\n      framework={framework}\n      title={`${frameworkName} charting libraries`}\n      showType={false}\n      showCompatibleWith={false}\n    />\n  );\n}\n\nexport async function getStaticPaths() {\n  const paths = Object.values(frameworks).map(framework => ({\n    params: { framework: framework.slug },\n  }));\n\n  return {\n    paths,\n    fallback: false,\n  };\n}\n\nexport async function getStaticProps({ params }) {\n  const tools = await getTools();\n  const filtered = tools.filter(tool => hasTypes(tool, [ \"charts\" ]) && isCompatibleWith(tool, [ params.framework ]));\n\n  return {\n    props: {\n      tools: filtered,\n      framework: params.framework,\n    }\n  };\n}"
  },
  {
    "path": "pages/for/[framework]/index.js",
    "content": "import ListPage from '../../../components/ListPage';\nimport { getTools } from '../../../data/tools';\nimport { isCompatibleWith } from '../../../data/filter';\nimport frameworks from '../../../data/frameworks';\n\nexport default function Page({ tools, framework }) {\n  const frameworkName = frameworks[framework].name;\n\n  return (\n    <ListPage\n      tools={tools}\n      framework={framework}\n      title={`${frameworkName} data visualization tools`}\n      showCompatibleWith={false}\n    />\n  );\n}\n\nexport async function getStaticPaths() {\n  const paths = Object.values(frameworks).map(framework => ({\n    params: { framework: framework.slug },\n  }));\n\n  return {\n    paths,\n    fallback: false,\n  };\n}\n\nexport async function getStaticProps({ params }) {\n  const tools = await getTools();\n  const filtered = tools.filter(tool => isCompatibleWith(tool, [ params.framework ]));\n\n  return {\n    props: {\n      tools: filtered,\n      framework: params.framework,\n    }\n  };\n}"
  },
  {
    "path": "pages/for/open-source.js",
    "content": "import ListPage from '../../components/ListPage';\nimport { getTools } from '../../data/tools';\nimport { hasLicenses, isCompatibleWith } from '../../data/filter';\n\nexport default function Page({ tools }) {\n  return (\n    <ListPage\n      tools={tools}\n      title=\"Open source data visualization tools\"\n      showLicense={false}\n    />\n  );\n}\n\nexport async function getStaticProps() {\n  const tools = await getTools();\n  const filtered = tools.filter(tool => hasLicenses(tool, [ \"open-source\" ]));\n  return { props: { tools: filtered } };\n}"
  },
  {
    "path": "pages/index.js",
    "content": "import ListPage from '../components/ListPage';\nimport { getTools } from '../data/tools';\nimport { GlobalSignUp } from '../components/GlobalSignUp/GlobalSignUp';\nimport { CTAButtons } from '../components/CTAButtons/CTAButtons';\n\nexport default function Home({ tools }) {\n  return (\n    <>\n      <ListPage\n        tools={tools}\n        title=\"Front-end data tools\"\n      />\n      <GlobalSignUp>\n        <CTAButtons\n          signupCTAId=\"awesome-tools.button.cta-global_cloud-signup\"\n          bookDemoCTAId=\"awesome-tools.button.cta-global_book-a-demo\"\n        />\n      </GlobalSignUp>\n    </>\n  );\n}\n\nexport async function getStaticProps() {\n  const tools = await getTools();\n  return { props: { tools } };\n}"
  },
  {
    "path": "pages/tools/[id]/[framework].js",
    "content": "import React from \"react\";\nimport ToolPage from '../../../components/ToolPage/ToolPage';\n\nimport fs from \"fs\";\nimport { toolCopyPath, getTool } from \"../../../data/tools\";\nimport frameworks from \"../../../data/frameworks\";\nimport ToolPageForFramework from '../../../components/ToolPage/ToolPageForFramework';\n\nexport default function Tool(props) {\n  return (\n    <ToolPageForFramework {...props} />\n  );\n}\n\nexport async function getStaticPaths() {\n  const files = fs.readdirSync(toolCopyPath);\n  const ids = files\n    .filter((filename) => filename.endsWith(\".yml\"))\n    .map((filename) => filename.split(\".\")[0]);\n\n  const paths = ids.map(id => Object.values(frameworks).map(framework => ({\n    params: {\n      id,\n      framework: framework.slug,\n    },\n  }))).flat();\n\n  return {\n    paths,\n    fallback: false,\n  };\n}\n\nexport async function getStaticProps({ params }) {\n  const tool = await getTool(params.id);\n\n  return {\n    props: {\n      id: params.id,\n      framework: params.framework,\n      ...tool,\n    },\n  };\n}\n"
  },
  {
    "path": "pages/tools/[id]/index.js",
    "content": "import React from \"react\";\nimport ToolPage from '../../../components/ToolPage/ToolPage';\n\nimport fs from \"fs\";\nimport { toolCopyPath, getTool } from \"../../../data/tools\";\n\nexport default function Tool(props) {\n  return (\n    <ToolPage {...props} />\n  );\n}\n\nexport async function getStaticPaths() {\n  const files = fs.readdirSync(toolCopyPath);\n  const ids = files\n    .filter((filename) => filename.endsWith(\".yml\"))\n    .map((filename) => filename.split(\".\")[0]);\n\n  const paths = ids.map(id => ({\n    params: {\n      id\n    },\n  }));\n\n  return {\n    paths,\n    fallback: false,\n  };\n}\n\nexport async function getStaticProps({ params }) {\n  const tool = await getTool(params.id);\n\n  return {\n    props: {\n      id: params.id,\n      ...tool,\n    },\n  };\n}\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>#da532c</TileColor>\n        </tile>\n    </msapplication>\n</browserconfig>\n"
  },
  {
    "path": "public/robots.txt",
    "content": "# *\nUser-agent: *\nAllow: /\n\n# Host\nHost: https://awesome.cube.dev/\n\n# Sitemaps\nSitemap: https://awesome.cube.dev/sitemap.xml\n"
  },
  {
    "path": "public/site.webmanifest",
    "content": "{\n    \"name\": \"\",\n    \"short_name\": \"\",\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": "public/sitemap-0.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" xmlns:news=\"http://www.google.com/schemas/sitemap-news/0.9\" xmlns:xhtml=\"http://www.w3.org/1999/xhtml\" xmlns:mobile=\"http://www.google.com/schemas/sitemap-mobile/1.0\" xmlns:image=\"http://www.google.com/schemas/sitemap-image/1.1\" xmlns:video=\"http://www.google.com/schemas/sitemap-video/1.1\">\n<url><loc>https://awesome.cube.dev</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/for/open-source</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/for/react/charting-libraries</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/for/angular/charting-libraries</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/for/vue/charting-libraries</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/for/svelte/charting-libraries</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ag-grid/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ag-grid/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ag-grid/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ag-grid/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/amcharts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/amcharts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/amcharts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/amcharts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ant-design-charts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ant-design-charts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ant-design-charts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ant-design-charts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/anychart/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/anychart/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/anychart/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/anychart/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/apexcharts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/apexcharts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/apexcharts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/apexcharts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/appsmith/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/appsmith/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/appsmith/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/appsmith/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/billboard/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/billboard/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/billboard/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/billboard/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/c3/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/c3/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/c3/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/c3/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/chartist/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/chartist/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/chartist/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/chartist/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/chartjs/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/chartjs/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/chartjs/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/chartjs/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/cytoscape/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/cytoscape/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/cytoscape/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/cytoscape/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/d3/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/d3/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/d3/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/d3/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/datasette/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/datasette/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/datasette/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/datasette/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/deck-gl/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/deck-gl/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/deck-gl/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/deck-gl/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/echarts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/echarts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/echarts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/echarts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/flot/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/flot/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/flot/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/flot/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/frappe/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/frappe/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/frappe/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/frappe/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/fusioncharts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/fusioncharts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/fusioncharts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/fusioncharts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g2/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g2/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g2/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g2/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g2plot/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g2plot/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g2plot/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g2plot/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g6/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g6/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g6/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g6/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/google-charts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/google-charts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/google-charts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/google-charts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/highcharts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/highcharts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/highcharts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/highcharts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/kepler-gl/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/kepler-gl/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/kepler-gl/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/kepler-gl/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/laue/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/laue/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/laue/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/laue/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/layer-cake/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/layer-cake/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/layer-cake/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/layer-cake/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/leaflet/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/leaflet/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/leaflet/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/leaflet/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/lightweight-charts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/lightweight-charts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/lightweight-charts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/lightweight-charts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/mapbox-gl/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/mapbox-gl/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/mapbox-gl/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/mapbox-gl/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/material-ui-data-grid/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/material-ui-data-grid/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/material-ui-data-grid/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/material-ui-data-grid/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/metabase/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/metabase/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/metabase/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/metabase/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/muze/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/muze/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/muze/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/muze/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ngx-charts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ngx-charts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ngx-charts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ngx-charts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/nivo/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/nivo/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/nivo/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/nivo/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/observable-plot/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/observable-plot/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/observable-plot/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/observable-plot/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/p5/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/p5/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/p5/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/p5/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/pancake/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/pancake/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/pancake/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/pancake/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/perspective/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/perspective/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/perspective/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/perspective/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/plotly/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/plotly/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/plotly/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/plotly/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/plottable/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/plottable/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/plottable/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/plottable/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/pts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/pts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/pts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/pts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/react-charts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/react-charts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/react-charts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/react-charts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/reaflow/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/reaflow/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/reaflow/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/reaflow/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/reaviz/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/reaviz/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/reaviz/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/reaviz/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/recharts/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/recharts/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/recharts/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/recharts/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/redash/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/redash/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/redash/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/redash/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/rough/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/rough/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/rough/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/rough/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/roughviz/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/roughviz/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/roughviz/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/roughviz/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/semiotic/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/semiotic/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/semiotic/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/semiotic/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/stackgl/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/stackgl/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/stackgl/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/stackgl/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/superset/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/superset/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/superset/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/superset/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/three/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/three/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/three/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/three/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/toast-ui-chart/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/toast-ui-chart/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/toast-ui-chart/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/toast-ui-chart/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vega-lite/react</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vega-lite/angular</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vega-lite/vue</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vega-lite/svelte</loc><lastmod>2023-02-02T07:21:30.356Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vega/react</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vega/angular</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vega/vue</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vega/svelte</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/victory/react</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/victory/angular</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/victory/vue</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/victory/svelte</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vis/react</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vis/angular</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vis/vue</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vis/svelte</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/visx/react</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/visx/angular</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/visx/vue</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/visx/svelte</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vizzu/react</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vizzu/angular</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vizzu/vue</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vizzu/svelte</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/zingchart/react</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/zingchart/angular</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/zingchart/vue</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/zingchart/svelte</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ag-grid</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/amcharts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ant-design-charts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/anychart</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/apexcharts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/appsmith</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/billboard</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/c3</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/chartist</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/chartjs</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/cytoscape</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/d3</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/datasette</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/deck-gl</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/echarts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/flot</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/frappe</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/fusioncharts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g2</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g2plot</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/g6</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/google-charts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/highcharts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/kepler-gl</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/laue</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/layer-cake</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/leaflet</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/lightweight-charts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/mapbox-gl</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/material-ui-data-grid</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/metabase</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/muze</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/ngx-charts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/nivo</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/observable-plot</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/p5</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/pancake</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/perspective</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/plotly</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/plottable</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/pts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/react-charts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/reaflow</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/reaviz</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/recharts</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/redash</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/rough</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/roughviz</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/semiotic</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/stackgl</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/superset</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/three</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/toast-ui-chart</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vega-lite</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vega</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/victory</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vis</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/visx</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/vizzu</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/tools/zingchart</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/for/react</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/for/angular</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/for/vue</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n<url><loc>https://awesome.cube.dev/for/svelte</loc><lastmod>2023-02-02T07:21:30.357Z</lastmod><changefreq>daily</changefreq><priority>0.7</priority></url>\n</urlset>"
  },
  {
    "path": "public/sitemap.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<sitemapindex xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n<sitemap><loc>https://awesome.cube.dev/sitemap-0.xml</loc></sitemap>\n</sitemapindex>"
  },
  {
    "path": "styles/_variables.scss",
    "content": "$dark: #141446;\n$dark-02: #43436b;\n$dark-03: #727290;\n$dark-04: #a1a1b5;\n$dark-05: #d5d5e2;\n$dark-06: #f8f8f8;\n$light-dark: rgba(56, 56, 56, 0.3);\n$purple-active: #6b4cf6;\n$purple-hover: #6b4cf6;\n$purple-press: #5a39ef;\n$purple-02: #6b4cf6;\n$purple-03: #afadff;\n$purple-04: #cac9ff;\n$orange: #cc3700;\n$orange-01: rgba(255, 165, 123, 0.6);\n$orange-02: #fff4e9;\n$light: #f3f3fb;\n$pink-hover: #fa326e;\n\n// custom\n$dark-07: #f8f9fb;\n"
  },
  {
    "path": "styles/globals.scss",
    "content": "@import \"/styles/variables\";\nhtml,\nbody {\n  padding: 0;\n  margin: 0;\n  font-family: CeraPro, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,\n    Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;\n  color: $dark;\n}\n\na {\n  color: inherit;\n  text-decoration: none;\n}\n\na.link,\nspan.link {\n  font-size: 16px;\n  line-height: 20px;\n  color: $purple-active;\n}\n\nbutton {\n  outline-color: $dark;\n}\n\n* {\n  box-sizing: border-box;\n}\n\n.flex {\n  display: flex;\n}\n\n.flex-wrap-row {\n  flex-wrap: wrap;\n}\n\n.flex-column {\n  flex-direction: column;\n}\n\n.flex-items-center {\n  align-items: center;\n}\n\n.flex-center {\n  justify-content: center;\n}\n\n.flex-space-between {\n  justify-content: space-between;\n}\n\n.mt-xs {\n  margin-top: 8px;\n}\n.mb-xs {\n  margin-bottom: 8px;\n}\n.ml-xs {\n  margin-left: 8px;\n}\n.mr-xs {\n  margin-right: 8px;\n}\n\n.mt-sm {\n  margin-top: 16px;\n}\n.mb-sm {\n  margin-bottom: 16px;\n}\n.ml-sm {\n  margin-left: 16px;\n}\n.mr-sm {\n  margin-right: 16px;\n}\n\n.mt-md {\n  margin-top: 24px;\n}\n.mb-md {\n  margin-bottom: 24px;\n}\n.ml-md {\n  margin-left: 24px;\n}\n.mr-md {\n  margin-right: 24px;\n}\n\n.mt-lg {\n  margin-top: 48px;\n}\n.mb-lg {\n  margin-bottom: 48px;\n}\n.ml-lg {\n  margin-left: 48px;\n}\n.mr-lg {\n  margin-right: 48px;\n}\n\n.number-control-wrap {\n  margin-top: 80px;\n  margin-bottom: 24px;\n  @media (max-width: 767.98px) {\n    margin-top: 48px;\n  }\n}\n\n.isHovered {\n  &:hover {\n    color: $purple-hover;\n  }\n}\n\n.xs-hidden {\n  @media (max-width: 767.98px) {\n    display: none;\n  }\n}\n.xl-hidden {\n  @media (max-width: 1200px) {\n    display: none;\n  }\n}\n\n.full-height {\n  height: 100%;\n}\n\n@media (min-width: 1400px) {\n  .container.custom-container {\n    max-width: 1248px;\n  }\n}\n\n@font-face {\n  font-family: CeraPro;\n  src: url(/fonts/CeraPro-Regular.woff2);\n  font-weight: 400;\n  font-style: normal;\n  font-display: swap;\n}\n\n@font-face {\n  font-family: CeraPro;\n  src: url(/fonts/CeraPro-Medium.woff2);\n  font-weight: 500;\n  font-style: normal;\n  font-display: swap;\n}\n\n@font-face {\n  font-family: CeraPro;\n  src: url(/fonts/CeraPro-Bold.woff2);\n  font-weight: 700;\n  font-style: normal;\n  font-display: swap;\n}\n"
  },
  {
    "path": "styles/indexPage.scss",
    "content": ".counter {\n  margin-top: 80px;\n  margin-bottom: 80px;\n}\n"
  },
  {
    "path": "update-copy.sh",
    "content": "cd data-update-worker && npm install && node index.js"
  },
  {
    "path": "utils/number.js",
    "content": "export default function abbreviateNumber(value) {\n  if (!value) {\n    return null;\n  }\n  var newValue = value;\n  if (value >= 1000) {\n    var suffixes = [\"\", \"\\u202FK\", \"\\u202FM\", \"\\u202FB\", \"\\u202FT\"];\n    var suffixNum = Math.floor((\"\" + value).length / 3);\n    var shortValue = \"\";\n    for (var precision = 2; precision >= 1; precision--) {\n      shortValue = parseFloat(\n        (suffixNum != 0\n          ? value / Math.pow(1000, suffixNum)\n          : value\n        ).toPrecision(precision)\n      );\n      var dotLessShortValue = (shortValue + \"\").replace(/[^a-zA-Z 0-9]+/g, \"\");\n      if (dotLessShortValue.length <= 2) {\n        break;\n      }\n    }\n    if (shortValue % 1 != 0) shortValue = shortValue.toFixed(1);\n    newValue = shortValue + suffixes[suffixNum];\n  }\n  return newValue;\n}\n"
  },
  {
    "path": "utils/tracking.js",
    "content": "export const tracking = {\n  async init() {\n    tracking.gateway = await import('cubedev-tracking');\n    window.cubedevEvent = tracking.event;\n  },\n};\n\n['event', 'identify', 'page'].forEach((method) => {\n  tracking[method] = async (...args) => {\n    if (!process.browser) return;\n\n    if (!tracking.gateway) {\n      await tracking.init();\n    }\n\n    tracking.gateway[method](...args);\n  };\n});\n\nexport const trackSource = (\n  sourceId,\n  params = {}\n) => {\n  tracking.event('Web User Action', { action_source: sourceId, ...params });\n};\n\nexport const trackClick = (\n    sourceId,\n    params = {}\n  ) =>\n  () =>\n    trackSource(sourceId, params);\n"
  }
]