Repository: sqlhabit/sql_schema_visualizer
Branch: main
Commit: 0a97236ce7ee
Files: 213
Total size: 807.4 KB
Directory structure:
gitextract_3ikh_njc/
├── .github/
│ └── workflows/
│ └── deploy.yml
├── .gitignore
├── .npmrc
├── .nvmrc
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── bin/
│ ├── create_db_pages
│ ├── import
│ └── reset
├── build/
│ ├── asset-manifest.json
│ ├── databases/
│ │ ├── bindle.html
│ │ ├── ecommerce.html
│ │ ├── finance.html
│ │ ├── live.html
│ │ ├── movies.html
│ │ ├── nba.html
│ │ └── the-bank-job.html
│ ├── index.html
│ └── static/
│ ├── css/
│ │ └── main.9f228f45.css
│ └── js/
│ ├── 226.0d90ab44.chunk.js
│ ├── 226.0d90ab44.chunk.js.LICENSE.txt
│ ├── 394.14a9b9da.chunk.js
│ ├── bindle-edges-json.94501736.chunk.js
│ ├── bindle-schemaColors-json.b87e5760.chunk.js
│ ├── bindle-tablePositions-json.847db583.chunk.js
│ ├── bindle-tables.0d2bfe46.chunk.js
│ ├── ecommerce-edges-json.fe131063.chunk.js
│ ├── ecommerce-schemaColors-json.fdb98809.chunk.js
│ ├── ecommerce-tablePositions-json.03a16298.chunk.js
│ ├── ecommerce-tables.f5264437.chunk.js
│ ├── finance-edges-json.cc1c201e.chunk.js
│ ├── finance-schemaColors-json.e0d3a5af.chunk.js
│ ├── finance-tablePositions-json.9ab03387.chunk.js
│ ├── finance-tables.eac6da84.chunk.js
│ ├── live-edges-json.849f23e8.chunk.js
│ ├── live-schemaColors-json.3efe2122.chunk.js
│ ├── live-tablePositions-json.88001c8e.chunk.js
│ ├── live-tables.5a699030.chunk.js
│ ├── main.33dfc6b0.js
│ ├── main.33dfc6b0.js.LICENSE.txt
│ ├── movies-edges-json.5b3266f6.chunk.js
│ ├── movies-schemaColors-json.a48d91cc.chunk.js
│ ├── movies-tablePositions-json.1435348f.chunk.js
│ ├── movies-tables.37f21107.chunk.js
│ ├── nba-edges-json.b14b1c04.chunk.js
│ ├── nba-schemaColors-json.e0912a1a.chunk.js
│ ├── nba-tablePositions-json.eda5bb0d.chunk.js
│ ├── nba-tables.7858f3c9.chunk.js
│ ├── the-bank-job-edges-json.f4126c62.chunk.js
│ ├── the-bank-job-schemaColors-json.00b0e9ee.chunk.js
│ ├── the-bank-job-tablePositions-json.1ddd80ab.chunk.js
│ └── the-bank-job-tables.b72c42c8.chunk.js
├── design_notes/
│ └── 0001_using_regular_links.md
├── package.json
├── public/
│ └── index.html
├── schema.csv.template
├── src/
│ ├── App/
│ │ ├── App.css
│ │ ├── App.test.tsx
│ │ ├── SQLHabitLogo.tsx
│ │ └── index.tsx
│ ├── Visualizer/
│ │ ├── Style.ts
│ │ ├── Visualizer.test.tsx
│ │ ├── components/
│ │ │ ├── CloseIcon.tsx
│ │ │ ├── DatabaseIcon.tsx
│ │ │ ├── DatabaseMenuSidebar.tsx
│ │ │ ├── InfoIcon.tsx
│ │ │ ├── InfoPopup.tsx
│ │ │ ├── KeyIcon.tsx
│ │ │ ├── Markers.tsx
│ │ │ ├── MaximizeIcon.tsx
│ │ │ ├── MinimizeIcon.tsx
│ │ │ ├── TableNode.tsx
│ │ │ └── index.ts
│ │ ├── helpers/
│ │ │ ├── calculateEdges.ts
│ │ │ ├── calculateSourcePosition.ts
│ │ │ ├── calculateTargetPosition.ts
│ │ │ ├── edgeClassName.ts
│ │ │ ├── edgeMarkerName.ts
│ │ │ ├── fullTableName.ts
│ │ │ ├── index.ts
│ │ │ ├── initializeNodes.ts
│ │ │ ├── loadDatabaseConfig.ts
│ │ │ ├── loadDatabases.ts
│ │ │ ├── logTablePositions.ts
│ │ │ ├── markdown.ts
│ │ │ ├── moveSVGInFront.ts
│ │ │ ├── setEdgeClassName.ts
│ │ │ ├── setHighlightEdgeClassName.ts
│ │ │ └── tableHighlights.ts
│ │ ├── index.tsx
│ │ ├── style/
│ │ │ ├── column-name.scss
│ │ │ ├── database-menu-sidebar.scss
│ │ │ ├── flow.css
│ │ │ ├── handle.css
│ │ │ ├── has-many-edge.scss
│ │ │ ├── has-one-edge.scss
│ │ │ ├── info-popup.scss
│ │ │ ├── key-icon.css
│ │ │ ├── react-flow.scss
│ │ │ └── table.scss
│ │ └── types/
│ │ ├── CloseIconProps.ts
│ │ ├── DatabaseConfig.ts
│ │ ├── EdgeConfig.ts
│ │ ├── PopupProps.ts
│ │ ├── Position.ts
│ │ ├── SchemaColors.ts
│ │ ├── TableColumnConfig.ts
│ │ ├── TableConfig.ts
│ │ ├── TablePositions.ts
│ │ └── index.ts
│ ├── config/
│ │ ├── databases/
│ │ │ ├── bindle/
│ │ │ │ ├── edges.json
│ │ │ │ ├── schemaColors.json
│ │ │ │ ├── tablePositions.json
│ │ │ │ ├── tables/
│ │ │ │ │ ├── accounts.json
│ │ │ │ │ ├── adjust_callbacks.json
│ │ │ │ │ ├── books.json
│ │ │ │ │ ├── books_users.json
│ │ │ │ │ ├── devices.json
│ │ │ │ │ ├── helpers_dates.json
│ │ │ │ │ ├── marketing_spends.json
│ │ │ │ │ ├── mobile_analytics_events.json
│ │ │ │ │ ├── products.json
│ │ │ │ │ ├── profiles.json
│ │ │ │ │ ├── purchases.json
│ │ │ │ │ ├── users.json
│ │ │ │ │ ├── web_analytics_events.json
│ │ │ │ │ └── web_analytics_pageviews.json
│ │ │ │ └── tables.ts
│ │ │ ├── ecommerce/
│ │ │ │ ├── edges.json
│ │ │ │ ├── schemaColors.json
│ │ │ │ ├── tablePositions.json
│ │ │ │ ├── tables/
│ │ │ │ │ ├── carts.json
│ │ │ │ │ ├── carts_items.json
│ │ │ │ │ ├── categories.json
│ │ │ │ │ ├── discount_codes.json
│ │ │ │ │ ├── items.json
│ │ │ │ │ ├── purchases.json
│ │ │ │ │ ├── returns.json
│ │ │ │ │ ├── reviews.json
│ │ │ │ │ ├── users.json
│ │ │ │ │ └── vendors.json
│ │ │ │ └── tables.ts
│ │ │ ├── finance/
│ │ │ │ ├── edges.json
│ │ │ │ ├── schemaColors.json
│ │ │ │ ├── tablePositions.json
│ │ │ │ ├── tables/
│ │ │ │ │ ├── transactions.json
│ │ │ │ │ └── vendors.json
│ │ │ │ └── tables.ts
│ │ │ ├── live/
│ │ │ │ ├── edges.json
│ │ │ │ ├── schemaColors.json
│ │ │ │ ├── tablePositions.json
│ │ │ │ ├── tables/
│ │ │ │ │ ├── mobile_analytics_events.json
│ │ │ │ │ ├── products.json
│ │ │ │ │ ├── purchases.json
│ │ │ │ │ ├── trials.json
│ │ │ │ │ └── users.json
│ │ │ │ └── tables.ts
│ │ │ ├── movies/
│ │ │ │ ├── edges.json
│ │ │ │ ├── schemaColors.json
│ │ │ │ ├── tablePositions.json
│ │ │ │ ├── tables/
│ │ │ │ │ ├── actors.json
│ │ │ │ │ ├── actors_movies.json
│ │ │ │ │ ├── directors.json
│ │ │ │ │ ├── genres.json
│ │ │ │ │ ├── genres_movies.json
│ │ │ │ │ ├── movies.json
│ │ │ │ │ └── ratings.json
│ │ │ │ └── tables.ts
│ │ │ ├── nba/
│ │ │ │ ├── edges.json
│ │ │ │ ├── schemaColors.json
│ │ │ │ ├── tablePositions.json
│ │ │ │ ├── tables/
│ │ │ │ │ ├── games.json
│ │ │ │ │ ├── player_game_stats.json
│ │ │ │ │ ├── players.json
│ │ │ │ │ ├── team_game_stats.json
│ │ │ │ │ └── teams.json
│ │ │ │ └── tables.ts
│ │ │ └── the-bank-job/
│ │ │ ├── edges.json
│ │ │ ├── schemaColors.json
│ │ │ ├── tablePositions.json
│ │ │ ├── tables/
│ │ │ │ ├── accounts.json
│ │ │ │ ├── art_works.json
│ │ │ │ ├── authorized_vehicles.json
│ │ │ │ ├── cases.json
│ │ │ │ ├── cases_crime_types.json
│ │ │ │ ├── cases_criminals.json
│ │ │ │ ├── crime_types.json
│ │ │ │ ├── criminal_aliases.json
│ │ │ │ ├── criminals.json
│ │ │ │ ├── employees.json
│ │ │ │ ├── event_log.json
│ │ │ │ ├── road_camera_events.json
│ │ │ │ ├── safe_deposit_boxes.json
│ │ │ │ ├── storage_units.json
│ │ │ │ ├── storage_units_log.json
│ │ │ │ ├── transactions.json
│ │ │ │ ├── vaults.json
│ │ │ │ └── vehicles.json
│ │ │ └── tables.ts
│ │ ├── databases.json
│ │ ├── databases.json.template
│ │ ├── databases.ts
│ │ ├── edges.json.template
│ │ ├── nodeTypes.ts
│ │ ├── schemaColors.json.template
│ │ ├── tablePositions.json.template
│ │ └── tables.ts.template
│ ├── index.css
│ ├── index.tsx
│ ├── react-app-env.d.ts
│ └── setupTests.ts
└── tsconfig.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/deploy.yml
================================================
# https://dev.to/github/how-to-deploy-a-static-site-in-any-framework-of-your-choice-github-pages-neh
name: Deploy to GitHub Pages
on:
# Trigger the workflow every time you push to the `main` branch
push:
branches: [ main ]
# Allows you to run this workflow manually from the Actions tab on GitHub.
workflow_dispatch:
# Allow this job to clone the repo and create a page deployment
permissions:
contents: read
pages: write
id-token: write
jobs:
specs:
runs-on: ubuntu-latest
steps:
- name: Check out your repository using git
uses: actions/checkout@v4
- name: Use Node.js 16
uses: actions/setup-node@v4
with:
node-version: '16'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run specs
run: npm run test
build:
runs-on: ubuntu-latest
needs: specs
env:
NODE_ENV: production
steps:
- name: Check out your repository using git
uses: actions/checkout@v4
- name: Use Node.js 16
uses: actions/setup-node@v4
with:
node-version: '16'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build React
run: npm run build
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./build
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
================================================
FILE: .gitignore
================================================
.DS_Store
.cache
node_modules
dist
.env
.eslintcache
.idea
.log
.rollup.cache
*.csv
================================================
FILE: .npmrc
================================================
8.19.3
================================================
FILE: .nvmrc
================================================
16.19.0
================================================
FILE: CONTRIBUTING.md
================================================
# SQL Schema Visualizer Contribution Guidelines
First of all, thank you for your interest in contributing to the Schema Visualizer :raised_hands: Every form of contribution is appreciated. From issues to pull requests and documentation.
Please, check out [existing issues](https://github.com/sqlhabit/sql_schema_visualizer/issues) before you open a new one.
## Bugs and Features
If you have a **question**, **feature request** or a **bug report** simply create a [new issue](https://github.com/sqlhabit/sql_schema_visualizer/issues/new/choose).
## Pull Requests
Before submitting a substantial PR, please, open a [new issue](https://github.com/sqlhabit/sql_schema_visualizer/issues/new/choose). Let's discuss and plan it first. :pray:
### :mag: Anatomy of a great PR
1. Use a meaningful commit name.
2. Add a detailed PR description.
3. Write comments for key code changes. They'll help reviewing and serve as future documentation.
4. Write specs to make your changes bullet proof.
5. PROFIT. :beers:
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2023 Anatoli Makarevich @ SQL Habit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================

# SQL Schema Visualizer


A relational database schema visualizer built with React and [ReactFlow](https://github.com/wbkd/react-flow).
Originally built for [the SQL Habit course](https://www.sqlhabit.com/), it's available for everyone. Enjoy :heart:
[:mag: How to visualize your schema](https://github.com/sqlhabit/sql_schema_visualizer#how-to-visualize-your-schema) | [:microscope: How it works](https://github.com/sqlhabit/sql_schema_visualizer#under-the-hood) | [:handshake: Contributing](https://github.com/sqlhabit/sql_schema_visualizer#contributing)
## Features
:dash: **Easy to start**: you can import your schema(s) in 1.5 minutes.
:checkered_flag: **Easy to finish**: you only need to configure edges and table positions.
:wrench: **Customizable**: add table/column descriptions and schema colors.
:rocket: **Make it yours**: you get the whole React app, so you can change everything.
### Highlight specific tables and columns via a URL param
You can highlight tables and columns via the `highlights` URL param. Here's an example URL:
https://sqlhabit.github.io/sql_schema_visualizer/databases/bindle?highlights=users:id,email,signup_date;purchases:user_id,created_at
:mag: Note that tables are followed by semicolons `:` and column names are separated with commas `,`. Here's how it looks like:
## How to visualize your schema(s)
Schema Visualizer can visualize multiple schemas – each schema will have its own URL.
A schema configuration lives in [its own folder](https://github.com/sqlhabit/sql_schema_visualizer/tree/main/src/config/databases) and contains a bunch of [simple JSON files](https://github.com/sqlhabit/sql_schema_visualizer/tree/main/src/config/databases/bindle).
Here's how you can import your schema:
### Step 1. Clone and set up the repo
Clone the repo:
```bash
git clone https://github.com/sqlhabit/sql_schema_visualizer.git
cd sql_schema_visualizer
```
Install dependencies:
```bash
npm install
```
:bulb: You might need to install [nvm](https://github.com/nvm-sh/nvm#installing-and-updating) as well to make sure you're not using an old Node version.
### Step 2. Reset schema configuration
By default, Schema Visualizer contains [SQL Habit's](https://www.sqlhabit.com) dataset schemas. Let's delete all before we import new schemas:
```bash
npm run reset
```
### Step 3. Export your schema into a CSV file
A schema config consists of [tables](https://github.com/sqlhabit/sql_schema_visualizer/tree/main/src/config/databases/bindle/tables), [edges](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/edges.json), [table positions](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/tablePositions.json) and [schema colors](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/schemaColors.json).
Good news is that we can import tables using an SQL query. :rocket:
Pick a query for your database type and save the output to a CSV file like `my_schema.csv`. Put it to the root folder (next to [the `schema.csv.template` file](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/schema.csv.template)).
#### Postgres / Redshift
```sql
SELECT
t.table_schema,
t.table_name,
c.column_name,
c.data_type,
c.ordinal_position
FROM information_schema.tables t
LEFT JOIN information_schema.columns c
ON t.table_schema = c.table_schema
AND t.table_name = c.table_name
WHERE
t.table_schema NOT IN ('information_schema', 'pg_catalog')
AND t.table_name NOT IN ('schema_migrations', 'ar_internal_metadata')
ORDER BY 1, 2, 5
```
#### BigQuery
```sql
SELECT
c.table_schema,
c.table_name,
c.column_name,
c.data_type,
c.ordinal_position
FROM %PROJECT_NAME%.%DATASET_NAME%.INFORMATION_SCHEMA.COLUMNS c
JOIN %PROJECT_NAME%.%DATASET_NAME%.INFORMATION_SCHEMA.TABLES t
ON c.table_schema = t.table_schema
AND c.table_name = t.table_name
WHERE
c.table_schema NOT IN ('INFORMATION_SCHEMA')
ORDER BY 1, 2, 5
```
:mag: Make sure to replace `%PROJECT_NAME%.%DATASET_NAME%` with proper values.
#### Snowflake
```sql
SELECT
c.table_schema,
c.table_name,
c.column_name,
c.data_type,
c.ordinal_position
FROM information_schema.columns c
JOIN information_schema.tables t
ON c.table_schema = t.table_schema
AND c.table_name = t.table_name
WHERE
c.table_schema NOT IN ('INFORMATION_SCHEMA')
AND t.table_type = 'BASE TABLE'
ORDER BY 1, 2, 5
```
#### MySQL
```sql
SELECT
c.table_schema,
c.table_name,
c.column_name,
c.data_type,
c.ordinal_position
FROM information_schema.columns c
LEFT JOIN information_schema.views v
ON v.table_schema = c.table_schema
AND v.table_name = c.table_name
WHERE
c.table_schema NOT IN ('sys','information_schema', 'mysql', 'performance_schema')
AND c.table_name NOT IN ('schema_migrations', 'ar_internal_metadata')
ORDER BY 1, 2, 5
```
#### [SAP ASE](https://github.com/sqlhabit/sql_schema_visualizer/issues/8)
```sql
SELECT
'public' as table_schema,
so.name as table_name,
sc.name as column_name,
sc.type as data_type,
sc.colid as ordinal_position
FROM syscolumns sc
INNER JOIN sysobjects so
ON sc.id = so.id
WHERE so.type = 'U'
```
### Step 4. Import schema
Now we can import tables. The argument of the `npm run import` command is your CSV file name:
```bash
npm run import my_schema
```
You should see table JSON files added to the `src/config/databases/my_schema/tables` folder.
Let's spin up a dev server and see our tables [in the browser](http://localhost:3000/):
```bash
npm run start
```
### Step 5. Configure your schema
#### A. Set primary keys
To show a :key: icon next to the column name, add the `key` param to a column definition. Here's an example from [the `users` table](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/tables/users.json):
```json
{
"name": "id",
"key": true,
"description": "Unique identifier of a user.",
"type": "number"
}
```
#### B. Add edges
Define edges in [the `src/config/edges.json` file](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/edges.json):
Here's an example for **has one** relation:
```json
{
"source": "users",
"sourceKey": "id",
"target": "profiles",
"targetKey": "user_id",
"relation": "hasOne"
}
```
and **has many** relation:
```json
{
"source": "users",
"sourceKey": "id",
"target": "purchases",
"targetKey": "user_id",
"relation": "hasMany"
}
```
#### C. Add schema colors
You can set custom header colors for tables that belongs to the same schema in [the `schemaColors.json` file](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/schemaColors.json). Here's an example:
```json
{
"DEFAULT": "#91C4F2",
"public": "#BEB8EB",
"adjust": "#AFA2FF",
"helpers": "#75C9C8",
"web_analytics": "#F6BDD1",
"mobile_analytics": "#FFD791"
}
```
#### D. Add table positions
Table positions are defined in the [`tablePositions.json` file](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/tablePositions.json):
```json
{
"adjust.callbacks": {
"x": 864,
"y": -192
},
"helpers.dates": {
"x": 512,
"y": 528
},
"mobile_analytics.events": {
"x": 656,
"y": -336
}
```
After you import a schema, every table will have a default position set in the [`tablePositions.json`](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/tablePositions.json) file.
There's no need to update them manually. Instead:
1. Open Schema Visualizer [http://localhost:3000](http://localhost:3000).
2. Drag table nodes around to find a perfect arrangement.
3. **CTRL** + **P**. It copies node positions JSON to your clipboard.
4. Paste (**CMD** + **V**) JSON with positions to the [`tablePositions.json`](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/tablePositions.json) file of your schema.
5. PROFIT :beers:
#### E. Add table and column descriptions
Table and column descriptions are visible if you press `CMD` key and hover over a table or column name.
Add custom copy to the `"description"` keys [in table config files](https://github.com/sqlhabit/sql_schema_visualizer/tree/main/src/config/databases/bindle/tables/users.json). Here's an example:
```json
{
"name": "users",
"description": "This table contains all user records of Bindle.",
"columns": [
{
"name": "id",
"key": true,
"description": "Unique identifier of a user.",
"type": "number"
}
]
}
```
### Publish your schema online
#### Building your Schema Visualizer
Once you're finished with config file, build the project and upload the files from the [`/build`](https://github.com/sqlhabit/sql_schema_visualizer/tree/main/build) folder to your hosting of choice:
```sh
npm build
```
I highly recommend https://surge.sh/. It'll take you ~2 minutes to deploy your schema online:
1. `npm install --global surge`.
2. `cd build`
3. `surge`
4. PROFIT :beers:
## Contributing
You're more than welcome to contribute. In fact, I'm really looking forward to it! :rocket:
Just make sure to check out the [contribution guidelines](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/CONTRIBUTING.md). :pray:
## Under the hood
Schema Visualizer is built with [ReactFlow](https://reactflow.dev/).
Every table is a ReactFlow [Custom Node](https://reactflow.dev/docs/guides/custom-nodes/) with custom [Markers](https://reactflow.dev/docs/examples/edges/markers/) (those SVG icons with dot and fork).
Here's [a ReactFlow sandbox example](https://github.com/wbkd/react-flow-example-apps/tree/main/reactflow-create-react-app) of Custom Nodes.
### Config files
It all starts with plain [JSON config files](https://github.com/sqlhabit/sql_schema_visualizer/tree/main/src/config). There're 4 of them:
* [tables](https://github.com/sqlhabit/sql_schema_visualizer/tree/main/src/config/databases/bindle/tables)
* [edges](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/edges.json)
* [tablePositions](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/tablePositions.json)
* [schemaColors](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/config/databases/bindle/schemaColors.json)
Later they're translated into Nodes and Edges digestible by ReactFlow.
### Nodes and Handles
ReactFlow draws SVG edges between custom [Table Nodes](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/Visualizer/components/TableNode.tsx#L64).
Those edges start and end in ReactFlow Handle's. Every table column row has 2 handles – left and right. :bulb: A handle could be either **source** (for an outgoing edge) or a **target** (for an incoming edge). Handles are configured [based on the edges config](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/Visualizer/helpers/initializeNodes.ts#L4).
### Edges
As you can see, edges are dynamically change handles and orientation depending on relative node positions. That way it's less config to maintain, here're [helper](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/Visualizer/helpers/calculateTargetPosition.ts) [functions](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/Visualizer/helpers/calculateSourcePosition.ts) that take care of that.
### More details
[Here's the entry file](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/src/Visualizer/index.tsx) to the ReactFlow app.
Have fun exploring the app, it was a pleasure to build! If you have a question – open a [new issue](https://github.com/sqlhabit/sql_schema_visualizer/issues/new/choose). :beers:
## Development
You'll need to install dependencies and start a dev server:
```sh
npm install
npm start
```
You'll find the running visualizer at [http://localhost:3000](http://localhost:3000).
## Testing
Tests are written with the [React Testing Library](https://testing-library.com/docs/react-testing-library/example-intro). Run all of them via
```sh
npm test
```
## Maintainers
Schema Visualizer is a project of Anatoli of [SQL Habit](https://www.sqlhabit.com/). Hi from Berlin! :wave: :beers:
Anatoli Makarevich • [Twitter](https://twitter.com/makaroni4) • [Github](https://github.com/makaroni4)
## License
SQL Schema Visualizer is [MIT licensed](https://github.com/sqlhabit/sql_schema_visualizer/blob/main/LICENSE).
================================================
FILE: bin/create_db_pages
================================================
#!/usr/bin/env node
const databases = require("../src/config/databases.json");
const fs = require("fs").promises;
// design_notes/0001_using_regular_links.md
(async () => {
await fs.mkdir("build/databases");
for (const databaseSlug of Object.keys(databases)) {
await fs.copyFile("build/index.html", `build/databases/${databaseSlug}.html`);
};
})();
================================================
FILE: bin/import
================================================
#!/usr/bin/env node
const fs = require("fs").promises;
const SCHEMA_COLORS_TEMPLATE_FILE = "src/config/schemaColors.json.template";
const TABLES_INDEX_FILE_TEMPLATE = "src/config/tables.ts.template";
const DATABASES_FILE = "src/config/databases.json";
const DATA_TYPES = {
"character varying": "text",
"timestamp without time zone": "timestamp"
}
const adjustDataTypeName = (rawName) => {
if(DATA_TYPES[rawName]) {
return DATA_TYPES[rawName];
} else {
return rawName;
}
};
const readTableData = async (databaseName) => {
const schema = await fs.readFile(`${databaseName}.csv`, "utf8");
const schemaData = schema.replaceAll('"', '').trim().split("\n").map(row => row.split(","));
const [headers] = schemaData.splice(0, 1);
const data = schemaData.map(row => {
return Object.fromEntries(headers.map((key, index) => [key, row[index]]));
});
data.map(o => o.data_type = adjustDataTypeName(o.data_type));
return data;
};
const importSchemaColors = async (databaseName, schemas) => {
const schemasTemplateFile = await fs.readFile(SCHEMA_COLORS_TEMPLATE_FILE, "utf8");
const defaultSchemaColors = JSON.parse(schemasTemplateFile);
let schemaColors = Object.keys(schemas).reduce((acc, schemaName) => {
acc[schemaName] = defaultSchemaColors.DEFAULT;
return acc;
}, {});
schemaColors = {
...defaultSchemaColors,
...schemaColors
};
await fs.writeFile(`src/config/databases/${databaseName}/schemaColors.json`, JSON.stringify(schemaColors, null, 2), "utf8");
};
const importTablePositions = async (databaseName, tables) => {
const tableCount = Object.keys(tables).length;
const tablesPerRow = Math.round(Math.sqrt(tableCount));
const tablePositions = Object.keys(tables).reduce((acc, tableName, index) => {
const fullTableName = tableName.includes(".") ? tableName : `public.${tableName}`;
const yPosition = Math.floor(index / tablesPerRow);
const xPosition = index % tablesPerRow;
acc[fullTableName] = {
x: xPosition * 300,
y: yPosition * 450
};
return acc;
}, {});
await fs.writeFile(`src/config/databases/${databaseName}/tablePositions.json`, JSON.stringify(tablePositions, null, 2), "utf8");
};
const importTableConfigs = async (databaseName, tables) => {
await fs.mkdir(`src/config/databases/${databaseName}/tables`);
Object.keys(tables).forEach(async tableName => {
const tableFile = `src/config/databases/${databaseName}/tables/${tableName}.json`;
const tableConfig = {
name: tableName,
description: "",
schemaColor: "#91C4F2",
columns: []
};
tables[tableName].forEach(row => {
const columnName = row[0];
const columnType = row[1];
tableConfig.columns.push({
name: columnName,
description: "",
type: columnType
});
});
await fs.writeFile(tableFile, JSON.stringify(tableConfig, null, 2), "utf8");
});
};
// https://ourcodeworld.com/articles/read/608/how-to-camelize-and-decamelize-strings-in-javascript
const camelize = (text) => {
return text.replace(/\W/, "-").replace(/^([A-Z])|[\s-_]+(\w)/g, function(match, p1, p2, offset) {
if (p2) return p2.toUpperCase();
return p1.toLowerCase();
});
};
const importEdgeConfigs = async (databaseName, tables) => {
await fs.writeFile(`src/config/databases/${databaseName}/edges.json`, JSON.stringify([], null, 2), "utf8");
};
const importTablesIndexFile = async (databaseName, tables) => {
const importStatements = [];
const names = [];
Object.keys(tables).forEach(tableName => {
const tableConfigFileName = `${camelize(tableName)}Table`;
importStatements.push(`import ${tableConfigFileName} from "./tables/${tableName}.json";`);
names.push(` ${tableConfigFileName}`);
});
const loadTablesTemplate = await fs.readFile(TABLES_INDEX_FILE_TEMPLATE, "utf8");
const loadTablesHelper = loadTablesTemplate
.replace("%TABLE_FILES%", importStatements.join("\n"))
.replace("%TABLE_NAMES%", names.join(",\n"))
await fs.writeFile(`src/config/databases/${databaseName}/tables.ts`, loadTablesHelper, "utf8");
};
const addDatabaseEntry = async (databaseName) => {
const rawDatabases = await fs.readFile(DATABASES_FILE, "utf8");
const databases = JSON.parse(rawDatabases);
databases[databaseName] = {
name: databaseName,
description: ""
}
await fs.writeFile(DATABASES_FILE, JSON.stringify(databases, null, 2), "utf8");
};
const importConfigFiles = async ({ databaseName }) => {
const databaseConfigFolder = `src/config/databases/${databaseName}`;
await fs.mkdir(databaseConfigFolder);
const tableData = await readTableData(databaseName);
const tables = {};
const schemas = {};
tableData.forEach(row => {
schemas[row.table_schema] = true;
const name = row.table_schema === "public" ? row.table_name : `${row.table_schema}.${row.table_name}`;
if(tables[name]) {
tables[name].push([row.column_name, row.data_type]);
} else {
tables[name] = [[row.column_name, row.data_type]];
}
});
await importSchemaColors(databaseName, schemas);
await importTablePositions(databaseName, tables);
await importTableConfigs(databaseName, tables);
await importEdgeConfigs(databaseName, tables);
await importTablesIndexFile(databaseName, tables);
await addDatabaseEntry(databaseName);
};
(async () => {
const databaseName = process.argv[2];
if(!databaseName) {
console.log("--> Provide a database name like 'npm run import foobar'");
return;
}
const databaseConfigFolder = `src/config/databases/${databaseName}`;
try {
if(await fs.stat(databaseConfigFolder)) {
console.log(`⚠️ Folder ${databaseConfigFolder} already exists.`);
return;
}
} catch {}
const readline = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
readline.question("Do you want to import schema from a CSV file? y/n\n", async (answer) => {
if(answer.toLowerCase().includes("y")) {
await importConfigFiles({ databaseName });
console.log("Roger, everything is imported.");
} else {
console.log("Roger, skipping importing.");
}
readline.close();
});
})();
================================================
FILE: bin/reset
================================================
#!/usr/bin/env node
const fs = require("fs").promises;
const resetConfigFile = async (filePath, templatePath = `${filePath}.template`) => {
const templateData = await fs.readFile(templatePath, "utf8");
await fs.writeFile(filePath, templateData, "utf8");
};
const cleanUpDatabasesFolder = async () => {
await fs.rm("src/config/databases", { recursive: true });
await fs.mkdir("src/config/databases");
};
const readline = require("readline").createInterface({
input: process.stdin,
output: process.stdout
});
readline.question("Do you want to reset existing tables, edges and schema colors? y/n\n", async (answer) => {
if(answer.toLowerCase().includes("y")) {
await resetConfigFile("src/config/databases.json");
await cleanUpDatabasesFolder();
console.log("Roger, everything is reset.");
} else {
console.log("Roger, skipping resetting.");
}
readline.close();
});
================================================
FILE: build/asset-manifest.json
================================================
{
"files": {
"main.css": "/sql_schema_visualizer/static/css/main.9f228f45.css",
"main.js": "/sql_schema_visualizer/static/js/main.33dfc6b0.js",
"static/js/394.14a9b9da.chunk.js": "/sql_schema_visualizer/static/js/394.14a9b9da.chunk.js",
"static/js/226.0d90ab44.chunk.js": "/sql_schema_visualizer/static/js/226.0d90ab44.chunk.js",
"bindle-edges-json.js": "/sql_schema_visualizer/static/js/bindle-edges-json.94501736.chunk.js",
"ecommerce-edges-json.js": "/sql_schema_visualizer/static/js/ecommerce-edges-json.fe131063.chunk.js",
"finance-edges-json.js": "/sql_schema_visualizer/static/js/finance-edges-json.cc1c201e.chunk.js",
"live-edges-json.js": "/sql_schema_visualizer/static/js/live-edges-json.849f23e8.chunk.js",
"movies-edges-json.js": "/sql_schema_visualizer/static/js/movies-edges-json.5b3266f6.chunk.js",
"nba-edges-json.js": "/sql_schema_visualizer/static/js/nba-edges-json.b14b1c04.chunk.js",
"the-bank-job-edges-json.js": "/sql_schema_visualizer/static/js/the-bank-job-edges-json.f4126c62.chunk.js",
"bindle-tablePositions-json.js": "/sql_schema_visualizer/static/js/bindle-tablePositions-json.847db583.chunk.js",
"ecommerce-tablePositions-json.js": "/sql_schema_visualizer/static/js/ecommerce-tablePositions-json.03a16298.chunk.js",
"finance-tablePositions-json.js": "/sql_schema_visualizer/static/js/finance-tablePositions-json.9ab03387.chunk.js",
"live-tablePositions-json.js": "/sql_schema_visualizer/static/js/live-tablePositions-json.88001c8e.chunk.js",
"movies-tablePositions-json.js": "/sql_schema_visualizer/static/js/movies-tablePositions-json.1435348f.chunk.js",
"nba-tablePositions-json.js": "/sql_schema_visualizer/static/js/nba-tablePositions-json.eda5bb0d.chunk.js",
"the-bank-job-tablePositions-json.js": "/sql_schema_visualizer/static/js/the-bank-job-tablePositions-json.1ddd80ab.chunk.js",
"bindle-schemaColors-json.js": "/sql_schema_visualizer/static/js/bindle-schemaColors-json.b87e5760.chunk.js",
"ecommerce-schemaColors-json.js": "/sql_schema_visualizer/static/js/ecommerce-schemaColors-json.fdb98809.chunk.js",
"finance-schemaColors-json.js": "/sql_schema_visualizer/static/js/finance-schemaColors-json.e0d3a5af.chunk.js",
"live-schemaColors-json.js": "/sql_schema_visualizer/static/js/live-schemaColors-json.3efe2122.chunk.js",
"movies-schemaColors-json.js": "/sql_schema_visualizer/static/js/movies-schemaColors-json.a48d91cc.chunk.js",
"nba-schemaColors-json.js": "/sql_schema_visualizer/static/js/nba-schemaColors-json.e0912a1a.chunk.js",
"the-bank-job-schemaColors-json.js": "/sql_schema_visualizer/static/js/the-bank-job-schemaColors-json.00b0e9ee.chunk.js",
"bindle-tables.js": "/sql_schema_visualizer/static/js/bindle-tables.0d2bfe46.chunk.js",
"ecommerce-tables.js": "/sql_schema_visualizer/static/js/ecommerce-tables.f5264437.chunk.js",
"finance-tables.js": "/sql_schema_visualizer/static/js/finance-tables.eac6da84.chunk.js",
"live-tables.js": "/sql_schema_visualizer/static/js/live-tables.5a699030.chunk.js",
"movies-tables.js": "/sql_schema_visualizer/static/js/movies-tables.37f21107.chunk.js",
"nba-tables.js": "/sql_schema_visualizer/static/js/nba-tables.7858f3c9.chunk.js",
"the-bank-job-tables.js": "/sql_schema_visualizer/static/js/the-bank-job-tables.b72c42c8.chunk.js",
"index.html": "/sql_schema_visualizer/index.html",
"main.9f228f45.css.map": "/sql_schema_visualizer/static/css/main.9f228f45.css.map",
"main.33dfc6b0.js.map": "/sql_schema_visualizer/static/js/main.33dfc6b0.js.map",
"394.14a9b9da.chunk.js.map": "/sql_schema_visualizer/static/js/394.14a9b9da.chunk.js.map",
"226.0d90ab44.chunk.js.map": "/sql_schema_visualizer/static/js/226.0d90ab44.chunk.js.map",
"bindle-tables.0d2bfe46.chunk.js.map": "/sql_schema_visualizer/static/js/bindle-tables.0d2bfe46.chunk.js.map",
"ecommerce-tables.f5264437.chunk.js.map": "/sql_schema_visualizer/static/js/ecommerce-tables.f5264437.chunk.js.map",
"finance-tables.eac6da84.chunk.js.map": "/sql_schema_visualizer/static/js/finance-tables.eac6da84.chunk.js.map",
"live-tables.5a699030.chunk.js.map": "/sql_schema_visualizer/static/js/live-tables.5a699030.chunk.js.map",
"movies-tables.37f21107.chunk.js.map": "/sql_schema_visualizer/static/js/movies-tables.37f21107.chunk.js.map",
"nba-tables.7858f3c9.chunk.js.map": "/sql_schema_visualizer/static/js/nba-tables.7858f3c9.chunk.js.map",
"the-bank-job-tables.b72c42c8.chunk.js.map": "/sql_schema_visualizer/static/js/the-bank-job-tables.b72c42c8.chunk.js.map"
},
"entrypoints": [
"static/css/main.9f228f45.css",
"static/js/main.33dfc6b0.js"
]
}
================================================
FILE: build/databases/bindle.html
================================================
Schema Visualizer
================================================
FILE: build/databases/ecommerce.html
================================================
Schema Visualizer
================================================
FILE: build/databases/finance.html
================================================
Schema Visualizer
================================================
FILE: build/databases/live.html
================================================
Schema Visualizer
================================================
FILE: build/databases/movies.html
================================================
Schema Visualizer
================================================
FILE: build/databases/nba.html
================================================
Schema Visualizer
================================================
FILE: build/databases/the-bank-job.html
================================================
Schema Visualizer
================================================
FILE: build/index.html
================================================
Schema Visualizer
================================================
FILE: build/static/css/main.9f228f45.css
================================================
@import url(https://fonts.googleapis.com/css?family=Muli:400,400i,500,600,700,800&display=swap);.react-flow__resize-control{position:absolute}.react-flow__resize-control.left,.react-flow__resize-control.right{cursor:ew-resize}.react-flow__resize-control.bottom,.react-flow__resize-control.top{cursor:ns-resize}.react-flow__resize-control.bottom.right,.react-flow__resize-control.top.left{cursor:nwse-resize}.react-flow__resize-control.bottom.left,.react-flow__resize-control.top.right{cursor:nesw-resize}.react-flow__resize-control.handle{background-color:#3367d9;border:1px solid #fff;border-radius:1px;height:4px;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:4px}.react-flow__resize-control.handle.left{left:0;top:50%}.react-flow__resize-control.handle.right{left:100%;top:50%}.react-flow__resize-control.handle.top{left:50%;top:0}.react-flow__resize-control.handle.bottom{left:50%;top:100%}.react-flow__resize-control.handle.bottom.left,.react-flow__resize-control.handle.top.left{left:0}.react-flow__resize-control.handle.bottom.right,.react-flow__resize-control.handle.top.right{left:100%}.react-flow__resize-control.line{border:0 solid #3367d9}.react-flow__resize-control.line.left,.react-flow__resize-control.line.right{height:100%;top:0;-webkit-transform:translate(-50%);transform:translate(-50%);width:1px}.react-flow__resize-control.line.left{border-left-width:1px;left:0}.react-flow__resize-control.line.right{border-right-width:1px;left:100%}.react-flow__resize-control.line.bottom,.react-flow__resize-control.line.top{height:1px;left:0;-webkit-transform:translateY(-50%);transform:translateY(-50%);width:100%}.react-flow__resize-control.line.top{border-top-width:1px;top:0}.react-flow__resize-control.line.bottom{border-bottom-width:1px;top:100%}.react-flow__container{height:100%;left:0;position:absolute;top:0;width:100%}.react-flow__pane{cursor:grab;z-index:1}.react-flow__pane.selection{cursor:pointer}.react-flow__pane.dragging{cursor:grabbing}.react-flow__viewport{pointer-events:none;-webkit-transform-origin:0 0;transform-origin:0 0;z-index:2}.react-flow__renderer{z-index:4}.react-flow__selection{z-index:6}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible{outline:none}.react-flow .react-flow__edges{overflow:visible;pointer-events:none}.react-flow__connection-path,.react-flow__edge-path{stroke:#b1b1b7;stroke-width:1;fill:none}.react-flow__edge{cursor:pointer;pointer-events:visibleStroke}.react-flow__edge.animated path{stroke-dasharray:5;-webkit-animation:dashdraw .5s linear infinite;animation:dashdraw .5s linear infinite}.react-flow__edge.animated path.react-flow__edge-interaction{stroke-dasharray:none;-webkit-animation:none;animation:none}.react-flow__edge.inactive{pointer-events:none}.react-flow__edge.selected,.react-flow__edge:focus,.react-flow__edge:focus-visible{outline:none}.react-flow__edge.selected .react-flow__edge-path,.react-flow__edge:focus .react-flow__edge-path,.react-flow__edge:focus-visible .react-flow__edge-path{stroke:#555}.react-flow__edge-textwrapper{pointer-events:all}.react-flow__edge-textbg{fill:#fff}.react-flow__edge .react-flow__edge-text{pointer-events:none;-webkit-user-select:none;user-select:none}.react-flow__connection{pointer-events:none}.react-flow__connection.animated{stroke-dasharray:5;-webkit-animation:dashdraw .5s linear infinite;animation:dashdraw .5s linear infinite}.react-flow__connectionline{z-index:1001}.react-flow__nodes{pointer-events:none}.react-flow__node,.react-flow__nodes{-webkit-transform-origin:0 0;transform-origin:0 0}.react-flow__node{box-sizing:border-box;cursor:grab;pointer-events:all;position:absolute;-webkit-user-select:none;user-select:none}.react-flow__node.dragging{cursor:grabbing}.react-flow__nodesselection{pointer-events:none;-webkit-transform-origin:left top;transform-origin:left top;z-index:3}.react-flow__nodesselection-rect{cursor:grab;pointer-events:all;position:absolute}.react-flow__handle{background:#1a192b;border:1px solid #fff;border-radius:100%;height:6px;min-height:5px;min-width:5px;pointer-events:none;position:absolute;width:6px}.react-flow__handle.connectable{cursor:crosshair;pointer-events:all}.react-flow__handle-bottom{bottom:-4px;top:auto}.react-flow__handle-bottom,.react-flow__handle-top{left:50%;-webkit-transform:translate(-50%);transform:translate(-50%)}.react-flow__handle-top{top:-4px}.react-flow__handle-left{left:-4px}.react-flow__handle-left,.react-flow__handle-right{top:50%;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.react-flow__handle-right{right:-4px}.react-flow__edgeupdater{cursor:move;pointer-events:all}.react-flow__panel{margin:15px;position:absolute;z-index:5}.react-flow__panel.top{top:0}.react-flow__panel.bottom{bottom:0}.react-flow__panel.left{left:0}.react-flow__panel.right{right:0}.react-flow__panel.center{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.react-flow__attribution{background:hsla(0,0%,100%,.5);font-size:10px;margin:0;padding:2px 3px}.react-flow__attribution a{color:#999;text-decoration:none}@-webkit-keyframes dashdraw{0%{stroke-dashoffset:10}}@keyframes dashdraw{0%{stroke-dashoffset:10}}.react-flow__edgelabel-renderer{height:100%;pointer-events:none;position:absolute;width:100%}.react-flow__edge.updating .react-flow__edge-path{stroke:#777}.react-flow__edge-text{font-size:10px}.react-flow__node.selectable:focus,.react-flow__node.selectable:focus-visible{outline:none}.react-flow__node-default,.react-flow__node-group,.react-flow__node-input,.react-flow__node-output{background-color:#fff;border:1px solid #1a192b;border-radius:3px;color:#222;font-size:12px;padding:10px;text-align:center;width:150px}.react-flow__node-default.selectable:hover,.react-flow__node-group.selectable:hover,.react-flow__node-input.selectable:hover,.react-flow__node-output.selectable:hover{box-shadow:0 1px 4px 1px rgba(0,0,0,.08)}.react-flow__node-default.selectable.selected,.react-flow__node-default.selectable:focus,.react-flow__node-default.selectable:focus-visible,.react-flow__node-group.selectable.selected,.react-flow__node-group.selectable:focus,.react-flow__node-group.selectable:focus-visible,.react-flow__node-input.selectable.selected,.react-flow__node-input.selectable:focus,.react-flow__node-input.selectable:focus-visible,.react-flow__node-output.selectable.selected,.react-flow__node-output.selectable:focus,.react-flow__node-output.selectable:focus-visible{box-shadow:0 0 0 .5px #1a192b}.react-flow__node-group{background-color:hsla(0,0%,94%,.25)}.react-flow__nodesselection-rect,.react-flow__selection{background:rgba(0,89,220,.08);border:1px dotted rgba(0,89,220,.8)}.react-flow__nodesselection-rect:focus,.react-flow__nodesselection-rect:focus-visible,.react-flow__selection:focus,.react-flow__selection:focus-visible{outline:none}.react-flow__controls{box-shadow:0 0 2px 1px rgba(0,0,0,.08)}.react-flow__controls-button{align-items:center;background:#fefefe;border:none;border-bottom:1px solid #eee;box-sizing:initial;cursor:pointer;display:flex;height:16px;justify-content:center;padding:5px;-webkit-user-select:none;user-select:none;width:16px}.react-flow__controls-button:hover{background:#f4f4f4}.react-flow__controls-button svg{max-height:12px;max-width:12px;width:100%}.react-flow__minimap{background-color:#fff}.Flow{flex-grow:1;font-size:12px;height:100%;width:100%}:not(:root):-webkit-full-screen::backdrop{background-color:#fff}:not(:root):fullscreen::-webkit-backdrop{background-color:#fff}:not(:root):fullscreen::backdrop{background-color:#fff}.react-flow__node-custom{border:1px solid #555;border-radius:5px;padding:10px;width:300px}.react-flow__edge.selected .react-flow__edge-path{stroke:#2186eb!important}.react-flow__node{background-color:#f5f7fa;max-width:288px}.react-flow__attribution a{background:none}.react-flow__handle-left,.react-flow__handle-right{background:transparent!important;border:0!important}.table{background-color:#fff}.table__name{border:0;border-radius:4px 4px 0 0;font-weight:700;padding:8px;position:relative;text-align:center}.table__columns{border:1px solid #cbd2d9;border-radius:0 0 4px 4px;border-top:0}.table__description{background-color:#fff;border:1px solid #cbd2d9;border-radius:4px;display:none;font-weight:400;padding:8px;position:absolute;right:-6px;text-align:left;top:50%;-webkit-transform:translateX(100%) translateY(-50%);transform:translateX(100%) translateY(-50%);width:150px;z-index:1000}.table__description:after{border:3px solid transparent;border-right-color:#fff;content:"";position:absolute;right:100%;top:50%;-webkit-transform:translateX(0) translateY(-50%);transform:translateX(0) translateY(-50%)}.table__description:before{border:4px solid transparent;border-right-color:#cbd2d9;content:"";position:absolute;right:100%;top:50%;-webkit-transform:translateX(-.5px) translateY(-50%);transform:translateX(-.5px) translateY(-50%)}.table__description--active{display:block}.table--highlighted .table__name{background-color:#fadb5f}.table--highlighted .table__columns{border:2px dashed #fadb5f;border-top:0}.table:hover .table__name{opacity:1}.table--dimmed .table__name{opacity:.4}.column-name{border-bottom:0;cursor:pointer;font-size:12px;line-height:1;position:relative;z-index:50}.column-name__name{margin-right:16px}.column-name__type{color:#bbb}.column-name__description{background-color:#fff;border:1px solid #cbd2d9;border-radius:4px;display:none;line-height:1.2;padding:8px;position:absolute;right:-6px;top:50%;-webkit-transform:translateX(100%) translateY(-50%);transform:translateX(100%) translateY(-50%);width:150px;z-index:1000}.column-name__description:before{border:4px solid transparent;border-right-color:#cbd2d9;content:"";position:absolute;right:100%;top:50%;-webkit-transform:translateX(-.5px) translateY(-50%);transform:translateX(-.5px) translateY(-50%)}.column-name__description:after{border:3px solid transparent;border-right-color:#fff;content:"";position:absolute;right:100%;top:50%;-webkit-transform:translateX(0) translateY(-50%);transform:translateX(0) translateY(-50%)}.column-name__inner{display:flex;justify-content:space-between;padding:8px;position:relative}.column-name:last-child{border-bottom:0!important;border-radius:0 0 4px 4px}.column-name:hover{background-color:#efefef;opacity:1}.column-name--highlighted{background-color:#fff3c4;border-color:#fff3c4}.column-name--dimmed{opacity:.4}.column-name--selected .column-name__description{display:block;opacity:1}.info-popup{align-items:center;background-color:rgba(0,0,0,.7);display:flex;height:100%;justify-content:center;left:0;position:fixed;top:0;width:100%;z-index:100000}.info-popup__inner{background-color:#fff;border-radius:8px;font-size:16px;left:50%;line-height:1.4;max-height:100%;overflow-y:auto;padding:16px 16px 8px;position:fixed;top:50%;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);width:100%;z-index:200000}@media(min-width:512px){.info-popup__inner{max-width:576px}}.info-popup__headline{margin-top:0}.info-popup__database-name{margin-bottom:8px}.info-popup__database-name+p{margin-top:0}.info-popup__close-icon{cursor:pointer;position:absolute;right:12px;top:12px}.info-popup__close-icon:hover{opacity:.7}.has-one-edge.selected path.react-flow__edge-path{marker-end:url(#hasOneSelected);stroke-width:1.5px}.has-one-edge--highlighted path.react-flow__connection-path,.has-one-edge--highlighted path.react-flow__edge-interaction,.has-one-edge--highlighted path.react-flow__edge-path{stroke:#2186eb!important;stroke-width:1.5px}.has-one-edge-reversed.selected path.react-flow__edge-path{marker-end:url(#hasOneReversedSelected);stroke-width:1.5px}.has-one-edge-reversed--highlighted path.react-flow__connection-path,.has-one-edge-reversed--highlighted path.react-flow__edge-interaction,.has-one-edge-reversed--highlighted path.react-flow__edge-path{stroke:#2186eb!important;stroke-width:1.5px}.has-many-edge.selected path.react-flow__edge-path{marker-end:url(#hasManySelected);stroke-width:1.5}.has-many-edge--highlighted path.react-flow__connection-path,.has-many-edge--highlighted path.react-flow__edge-interaction,.has-many-edge--highlighted path.react-flow__edge-path{stroke:#2186eb!important;stroke-width:1.5px}.has-many-edge-reversed.selected path.react-flow__edge-path{marker-end:url(#hasManyReversedSelected);stroke-width:1.5}.has-many-edge-reversed--highlighted path.react-flow__connection-path,.has-many-edge-reversed--highlighted path.react-flow__edge-interaction,.has-many-edge-reversed--highlighted path.react-flow__edge-path{stroke:#2186eb!important;stroke-width:1.5px}.key-icon{height:12px;margin-right:4px;width:12px}.left-handle{left:0;-webkit-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%)}.left-handle,.right-handle{height:2px;min-width:2px;top:50%;width:2px}.right-handle{right:0;-webkit-transform:translateX(50%) translateY(-50%);transform:translateX(50%) translateY(-50%)}.App{display:flex;flex-direction:column;height:100%}.App-header{align-items:center;border-bottom:1px solid #eee;display:flex;height:40px;padding:0 1rem}.App__logo{background:none;cursor:pointer;left:16px;position:fixed;text-decoration:none;top:16px;z-index:50000}.layout{position:fixed}.layout,.layout__outlet{height:100%;width:100%}html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}body{color:#1f2933;font-display:swap;font-family:Muli,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;margin:0}#root,body,html{height:100%}h1,h2,h3,h4{margin-bottom:0;margin-top:1em}a{background:linear-gradient(90deg,#1f2933,#1f2933),linear-gradient(90deg,red,#ff00b4,#2186eb);background-position:100% 100%,0 100%;background-repeat:no-repeat;background-size:100% 1px,0 1px;color:inherit;text-decoration:none;transition:background-size .4s}a:hover{background-size:0 1px,100% 1px}.emoji{height:1.1em;margin:0 .05em 0 .1em;vertical-align:-.1em;width:1.1em}.mb-32{margin-bottom:32px}
/*# sourceMappingURL=main.9f228f45.css.map*/
================================================
FILE: build/static/js/226.0d90ab44.chunk.js
================================================
/*! For license information please see 226.0d90ab44.chunk.js.LICENSE.txt */
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[226],{3226:function(d,u,f){f.r(u);var c=function(){var d={base:"https://twemoji.maxcdn.com/v/14.0.2/",ext:".png",size:"72x72",className:"emoji",convert:{fromCodePoint:function(d){var u="string"===typeof d?parseInt(d,16):d;if(u<65536)return t(u);return t(55296+((u-=65536)>>10),56320+(1023&u))},toCodePoint:g},onerror:function(){this.parentNode&&this.parentNode.replaceChild(r(this.alt,!1),this)},parse:function(u,f){f&&"function"!==typeof f||(f={callback:f});return("string"===typeof u?l:i)(u,{callback:f.callback||n,attributes:"function"===typeof f.attributes?f.attributes:h,base:"string"===typeof f.base?f.base:d.base,ext:f.ext||d.ext,size:f.folder||(c=f.size||d.size,"number"===typeof c?c+"x"+c:c),className:f.className||d.className,onerror:f.onerror||d.onerror});var c},replace:m,test:function(d){f.lastIndex=0;var u=f.test(d);return f.lastIndex=0,u}},u={"&":"&","<":"<",">":">","'":"'",'"':"""},f=/(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91]|\ud83e\udd1d)|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[\xa9\xae\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd\udec3-\udec5\udef0-\udef6]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udedd-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7c\ude80-\ude86\ude90-\udeac\udeb0-\udeba\udec0-\udec2\uded0-\uded9\udee0-\udee7]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f/g,c=/\uFE0F/g,e=String.fromCharCode(8205),b=/[&<>'"]/g,a=/^(?:iframe|noframes|noscript|script|select|style|textarea)$/,t=String.fromCharCode;return d;function r(d,u){return document.createTextNode(u?d.replace(c,""):d)}function n(d,u){return"".concat(u.base,u.size,"/",d,u.ext)}function o(d,u){for(var f,c,e=d.childNodes,b=e.length;b--;)3===(c=(f=e[b]).nodeType)?u.push(f):1!==c||"ownerSVGElement"in f||a.test(f.nodeName.toLowerCase())||o(f,u);return u}function s(d){return g(d.indexOf(e)<0?d.replace(c,""):d)}function i(d,u){for(var c,e,b,a,t,n,i,l,p,h,m,g,x,C=o(d,[]),v=C.length;v--;){for(b=!1,a=document.createDocumentFragment(),n=(t=C[v]).nodeValue,l=0;i=f.exec(n);){if((p=i.index)!==l&&a.appendChild(r(n.slice(l,p),!0)),g=s(m=i[0]),l=p+m.length,x=u.callback(g,u),g&&x){for(e in(h=new Image).onerror=u.onerror,h.setAttribute("draggable","false"),c=u.attributes(m,g))c.hasOwnProperty(e)&&0!==e.indexOf("on")&&!h.hasAttribute(e)&&h.setAttribute(e,c[e]);h.className=u.className,h.alt=m,h.src=x,b=!0,a.appendChild(h)}h||a.appendChild(r(m,!1)),h=null}b&&(l")}return e}))}function p(d){return u[d]}function h(){return null}function m(d,u){return String(d).replace(f,u)}function g(d,u){for(var f=[],c=0,e=0,b=0;b:(",">:-("],blush:[':")',':-")'],broken_heart:["3","<\\3"],confused:[":/",":-/"],cry:[":'(",":'-(",":,(",":,-("],frowning:[":(",":-("],heart:["<3"],imp:["]:(","]:-("],innocent:["o:)","O:)","o:-)","O:-)","0:)","0:-)"],joy:[":')",":'-)",":,)",":,-)",":'D",":'-D",":,D",":,-D"],kissing:[":*",":-*"],laughing:["x-)","X-)"],neutral_face:[":|",":-|"],open_mouth:[":o",":-o",":O",":-O"],rage:[":@",":-@"],smile:[":D",":-D"],smiley:[":)",":-)"],smiling_imp:["]:)","]:-)"],sob:[":,'(",":,'-(",";(",";-("],stuck_out_tongue:[":P",":-P"],sunglasses:["8-)","B-)"],sweat:[",:(",",:-("],sweat_smile:[",:)",",:-)"],unamused:[":s",":-S",":z",":-Z",":$",":-$"],wink:[";)",";-)"]}},6906:function(a){a.exports=function(a){var e,n=a.defs;a.enabled.length&&(n=Object.keys(n).reduce((function(e,o){return a.enabled.indexOf(o)>=0&&(e[o]=n[o]),e}),{})),e=Object.keys(a.shortcuts).reduce((function(e,o){return n[o]?Array.isArray(a.shortcuts[o])?(a.shortcuts[o].forEach((function(a){e[a]=o})),e):(e[a.shortcuts[o]]=o,e):e}),{});var o,i=Object.keys(n);o=0===i.length?"^$":i.map((function(a){return":"+a+":"})).concat(Object.keys(e)).sort().reverse().map((function(a){return a.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")})).join("|");var _=RegExp(o),r=RegExp(o,"g");return{defs:n,shortcuts:e,scanRE:_,replaceRE:r}}},2644:function(a){a.exports=function(a,e){return a[e].content}},5020:function(a){a.exports=function(a,e,n,o,i){var _=a.utils.arrayReplaceAt,r=a.utils.lib.ucmicro,t=new RegExp([r.Z.source,r.P.source,r.Cc.source].join("|"));function s(a,o,_){var r,s=0,l=[];return a.replace(i,(function(o,i,c){var m;if(n.hasOwnProperty(o)){if(m=n[o],i>0&&!t.test(c[i-1]))return;if(i+o.lengths&&((r=new _("text","",0)).content=a.slice(s,i),l.push(r)),(r=new _("emoji","",0)).markup=m,r.content=e[m],l.push(r),s=i+o.length})),s=0;e--)"link_open"!==(t=r[e]).type&&"link_close"!==t.type||"auto"===t.info&&(c-=t.nesting),"text"===t.type&&0===c&&o.test(t.content)&&(l[n].children=r=_(r,e,s(t.content,t.level,a.Token)))}}},5297:function(a){a.exports=JSON.parse('{"100":"\ud83d\udcaf","1234":"\ud83d\udd22","grinning":"\ud83d\ude00","smiley":"\ud83d\ude03","smile":"\ud83d\ude04","grin":"\ud83d\ude01","laughing":"\ud83d\ude06","satisfied":"\ud83d\ude06","sweat_smile":"\ud83d\ude05","rofl":"\ud83e\udd23","joy":"\ud83d\ude02","slightly_smiling_face":"\ud83d\ude42","upside_down_face":"\ud83d\ude43","wink":"\ud83d\ude09","blush":"\ud83d\ude0a","innocent":"\ud83d\ude07","smiling_face_with_three_hearts":"\ud83e\udd70","heart_eyes":"\ud83d\ude0d","star_struck":"\ud83e\udd29","kissing_heart":"\ud83d\ude18","kissing":"\ud83d\ude17","relaxed":"\u263a\ufe0f","kissing_closed_eyes":"\ud83d\ude1a","kissing_smiling_eyes":"\ud83d\ude19","smiling_face_with_tear":"\ud83e\udd72","yum":"\ud83d\ude0b","stuck_out_tongue":"\ud83d\ude1b","stuck_out_tongue_winking_eye":"\ud83d\ude1c","zany_face":"\ud83e\udd2a","stuck_out_tongue_closed_eyes":"\ud83d\ude1d","money_mouth_face":"\ud83e\udd11","hugs":"\ud83e\udd17","hand_over_mouth":"\ud83e\udd2d","shushing_face":"\ud83e\udd2b","thinking":"\ud83e\udd14","zipper_mouth_face":"\ud83e\udd10","raised_eyebrow":"\ud83e\udd28","neutral_face":"\ud83d\ude10","expressionless":"\ud83d\ude11","no_mouth":"\ud83d\ude36","smirk":"\ud83d\ude0f","unamused":"\ud83d\ude12","roll_eyes":"\ud83d\ude44","grimacing":"\ud83d\ude2c","lying_face":"\ud83e\udd25","relieved":"\ud83d\ude0c","pensive":"\ud83d\ude14","sleepy":"\ud83d\ude2a","drooling_face":"\ud83e\udd24","sleeping":"\ud83d\ude34","mask":"\ud83d\ude37","face_with_thermometer":"\ud83e\udd12","face_with_head_bandage":"\ud83e\udd15","nauseated_face":"\ud83e\udd22","vomiting_face":"\ud83e\udd2e","sneezing_face":"\ud83e\udd27","hot_face":"\ud83e\udd75","cold_face":"\ud83e\udd76","woozy_face":"\ud83e\udd74","dizzy_face":"\ud83d\ude35","exploding_head":"\ud83e\udd2f","cowboy_hat_face":"\ud83e\udd20","partying_face":"\ud83e\udd73","disguised_face":"\ud83e\udd78","sunglasses":"\ud83d\ude0e","nerd_face":"\ud83e\udd13","monocle_face":"\ud83e\uddd0","confused":"\ud83d\ude15","worried":"\ud83d\ude1f","slightly_frowning_face":"\ud83d\ude41","frowning_face":"\u2639\ufe0f","open_mouth":"\ud83d\ude2e","hushed":"\ud83d\ude2f","astonished":"\ud83d\ude32","flushed":"\ud83d\ude33","pleading_face":"\ud83e\udd7a","frowning":"\ud83d\ude26","anguished":"\ud83d\ude27","fearful":"\ud83d\ude28","cold_sweat":"\ud83d\ude30","disappointed_relieved":"\ud83d\ude25","cry":"\ud83d\ude22","sob":"\ud83d\ude2d","scream":"\ud83d\ude31","confounded":"\ud83d\ude16","persevere":"\ud83d\ude23","disappointed":"\ud83d\ude1e","sweat":"\ud83d\ude13","weary":"\ud83d\ude29","tired_face":"\ud83d\ude2b","yawning_face":"\ud83e\udd71","triumph":"\ud83d\ude24","rage":"\ud83d\ude21","pout":"\ud83d\ude21","angry":"\ud83d\ude20","cursing_face":"\ud83e\udd2c","smiling_imp":"\ud83d\ude08","imp":"\ud83d\udc7f","skull":"\ud83d\udc80","skull_and_crossbones":"\u2620\ufe0f","hankey":"\ud83d\udca9","poop":"\ud83d\udca9","shit":"\ud83d\udca9","clown_face":"\ud83e\udd21","japanese_ogre":"\ud83d\udc79","japanese_goblin":"\ud83d\udc7a","ghost":"\ud83d\udc7b","alien":"\ud83d\udc7d","space_invader":"\ud83d\udc7e","robot":"\ud83e\udd16","smiley_cat":"\ud83d\ude3a","smile_cat":"\ud83d\ude38","joy_cat":"\ud83d\ude39","heart_eyes_cat":"\ud83d\ude3b","smirk_cat":"\ud83d\ude3c","kissing_cat":"\ud83d\ude3d","scream_cat":"\ud83d\ude40","crying_cat_face":"\ud83d\ude3f","pouting_cat":"\ud83d\ude3e","see_no_evil":"\ud83d\ude48","hear_no_evil":"\ud83d\ude49","speak_no_evil":"\ud83d\ude4a","kiss":"\ud83d\udc8b","love_letter":"\ud83d\udc8c","cupid":"\ud83d\udc98","gift_heart":"\ud83d\udc9d","sparkling_heart":"\ud83d\udc96","heartpulse":"\ud83d\udc97","heartbeat":"\ud83d\udc93","revolving_hearts":"\ud83d\udc9e","two_hearts":"\ud83d\udc95","heart_decoration":"\ud83d\udc9f","heavy_heart_exclamation":"\u2763\ufe0f","broken_heart":"\ud83d\udc94","heart":"\u2764\ufe0f","orange_heart":"\ud83e\udde1","yellow_heart":"\ud83d\udc9b","green_heart":"\ud83d\udc9a","blue_heart":"\ud83d\udc99","purple_heart":"\ud83d\udc9c","brown_heart":"\ud83e\udd0e","black_heart":"\ud83d\udda4","white_heart":"\ud83e\udd0d","anger":"\ud83d\udca2","boom":"\ud83d\udca5","collision":"\ud83d\udca5","dizzy":"\ud83d\udcab","sweat_drops":"\ud83d\udca6","dash":"\ud83d\udca8","hole":"\ud83d\udd73\ufe0f","bomb":"\ud83d\udca3","speech_balloon":"\ud83d\udcac","eye_speech_bubble":"\ud83d\udc41\ufe0f\u200d\ud83d\udde8\ufe0f","left_speech_bubble":"\ud83d\udde8\ufe0f","right_anger_bubble":"\ud83d\uddef\ufe0f","thought_balloon":"\ud83d\udcad","zzz":"\ud83d\udca4","wave":"\ud83d\udc4b","raised_back_of_hand":"\ud83e\udd1a","raised_hand_with_fingers_splayed":"\ud83d\udd90\ufe0f","hand":"\u270b","raised_hand":"\u270b","vulcan_salute":"\ud83d\udd96","ok_hand":"\ud83d\udc4c","pinched_fingers":"\ud83e\udd0c","pinching_hand":"\ud83e\udd0f","v":"\u270c\ufe0f","crossed_fingers":"\ud83e\udd1e","love_you_gesture":"\ud83e\udd1f","metal":"\ud83e\udd18","call_me_hand":"\ud83e\udd19","point_left":"\ud83d\udc48","point_right":"\ud83d\udc49","point_up_2":"\ud83d\udc46","middle_finger":"\ud83d\udd95","fu":"\ud83d\udd95","point_down":"\ud83d\udc47","point_up":"\u261d\ufe0f","+1":"\ud83d\udc4d","thumbsup":"\ud83d\udc4d","-1":"\ud83d\udc4e","thumbsdown":"\ud83d\udc4e","fist_raised":"\u270a","fist":"\u270a","fist_oncoming":"\ud83d\udc4a","facepunch":"\ud83d\udc4a","punch":"\ud83d\udc4a","fist_left":"\ud83e\udd1b","fist_right":"\ud83e\udd1c","clap":"\ud83d\udc4f","raised_hands":"\ud83d\ude4c","open_hands":"\ud83d\udc50","palms_up_together":"\ud83e\udd32","handshake":"\ud83e\udd1d","pray":"\ud83d\ude4f","writing_hand":"\u270d\ufe0f","nail_care":"\ud83d\udc85","selfie":"\ud83e\udd33","muscle":"\ud83d\udcaa","mechanical_arm":"\ud83e\uddbe","mechanical_leg":"\ud83e\uddbf","leg":"\ud83e\uddb5","foot":"\ud83e\uddb6","ear":"\ud83d\udc42","ear_with_hearing_aid":"\ud83e\uddbb","nose":"\ud83d\udc43","brain":"\ud83e\udde0","anatomical_heart":"\ud83e\udec0","lungs":"\ud83e\udec1","tooth":"\ud83e\uddb7","bone":"\ud83e\uddb4","eyes":"\ud83d\udc40","eye":"\ud83d\udc41\ufe0f","tongue":"\ud83d\udc45","lips":"\ud83d\udc44","baby":"\ud83d\udc76","child":"\ud83e\uddd2","boy":"\ud83d\udc66","girl":"\ud83d\udc67","adult":"\ud83e\uddd1","blond_haired_person":"\ud83d\udc71","man":"\ud83d\udc68","bearded_person":"\ud83e\uddd4","red_haired_man":"\ud83d\udc68\u200d\ud83e\uddb0","curly_haired_man":"\ud83d\udc68\u200d\ud83e\uddb1","white_haired_man":"\ud83d\udc68\u200d\ud83e\uddb3","bald_man":"\ud83d\udc68\u200d\ud83e\uddb2","woman":"\ud83d\udc69","red_haired_woman":"\ud83d\udc69\u200d\ud83e\uddb0","person_red_hair":"\ud83e\uddd1\u200d\ud83e\uddb0","curly_haired_woman":"\ud83d\udc69\u200d\ud83e\uddb1","person_curly_hair":"\ud83e\uddd1\u200d\ud83e\uddb1","white_haired_woman":"\ud83d\udc69\u200d\ud83e\uddb3","person_white_hair":"\ud83e\uddd1\u200d\ud83e\uddb3","bald_woman":"\ud83d\udc69\u200d\ud83e\uddb2","person_bald":"\ud83e\uddd1\u200d\ud83e\uddb2","blond_haired_woman":"\ud83d\udc71\u200d\u2640\ufe0f","blonde_woman":"\ud83d\udc71\u200d\u2640\ufe0f","blond_haired_man":"\ud83d\udc71\u200d\u2642\ufe0f","older_adult":"\ud83e\uddd3","older_man":"\ud83d\udc74","older_woman":"\ud83d\udc75","frowning_person":"\ud83d\ude4d","frowning_man":"\ud83d\ude4d\u200d\u2642\ufe0f","frowning_woman":"\ud83d\ude4d\u200d\u2640\ufe0f","pouting_face":"\ud83d\ude4e","pouting_man":"\ud83d\ude4e\u200d\u2642\ufe0f","pouting_woman":"\ud83d\ude4e\u200d\u2640\ufe0f","no_good":"\ud83d\ude45","no_good_man":"\ud83d\ude45\u200d\u2642\ufe0f","ng_man":"\ud83d\ude45\u200d\u2642\ufe0f","no_good_woman":"\ud83d\ude45\u200d\u2640\ufe0f","ng_woman":"\ud83d\ude45\u200d\u2640\ufe0f","ok_person":"\ud83d\ude46","ok_man":"\ud83d\ude46\u200d\u2642\ufe0f","ok_woman":"\ud83d\ude46\u200d\u2640\ufe0f","tipping_hand_person":"\ud83d\udc81","information_desk_person":"\ud83d\udc81","tipping_hand_man":"\ud83d\udc81\u200d\u2642\ufe0f","sassy_man":"\ud83d\udc81\u200d\u2642\ufe0f","tipping_hand_woman":"\ud83d\udc81\u200d\u2640\ufe0f","sassy_woman":"\ud83d\udc81\u200d\u2640\ufe0f","raising_hand":"\ud83d\ude4b","raising_hand_man":"\ud83d\ude4b\u200d\u2642\ufe0f","raising_hand_woman":"\ud83d\ude4b\u200d\u2640\ufe0f","deaf_person":"\ud83e\uddcf","deaf_man":"\ud83e\uddcf\u200d\u2642\ufe0f","deaf_woman":"\ud83e\uddcf\u200d\u2640\ufe0f","bow":"\ud83d\ude47","bowing_man":"\ud83d\ude47\u200d\u2642\ufe0f","bowing_woman":"\ud83d\ude47\u200d\u2640\ufe0f","facepalm":"\ud83e\udd26","man_facepalming":"\ud83e\udd26\u200d\u2642\ufe0f","woman_facepalming":"\ud83e\udd26\u200d\u2640\ufe0f","shrug":"\ud83e\udd37","man_shrugging":"\ud83e\udd37\u200d\u2642\ufe0f","woman_shrugging":"\ud83e\udd37\u200d\u2640\ufe0f","health_worker":"\ud83e\uddd1\u200d\u2695\ufe0f","man_health_worker":"\ud83d\udc68\u200d\u2695\ufe0f","woman_health_worker":"\ud83d\udc69\u200d\u2695\ufe0f","student":"\ud83e\uddd1\u200d\ud83c\udf93","man_student":"\ud83d\udc68\u200d\ud83c\udf93","woman_student":"\ud83d\udc69\u200d\ud83c\udf93","teacher":"\ud83e\uddd1\u200d\ud83c\udfeb","man_teacher":"\ud83d\udc68\u200d\ud83c\udfeb","woman_teacher":"\ud83d\udc69\u200d\ud83c\udfeb","judge":"\ud83e\uddd1\u200d\u2696\ufe0f","man_judge":"\ud83d\udc68\u200d\u2696\ufe0f","woman_judge":"\ud83d\udc69\u200d\u2696\ufe0f","farmer":"\ud83e\uddd1\u200d\ud83c\udf3e","man_farmer":"\ud83d\udc68\u200d\ud83c\udf3e","woman_farmer":"\ud83d\udc69\u200d\ud83c\udf3e","cook":"\ud83e\uddd1\u200d\ud83c\udf73","man_cook":"\ud83d\udc68\u200d\ud83c\udf73","woman_cook":"\ud83d\udc69\u200d\ud83c\udf73","mechanic":"\ud83e\uddd1\u200d\ud83d\udd27","man_mechanic":"\ud83d\udc68\u200d\ud83d\udd27","woman_mechanic":"\ud83d\udc69\u200d\ud83d\udd27","factory_worker":"\ud83e\uddd1\u200d\ud83c\udfed","man_factory_worker":"\ud83d\udc68\u200d\ud83c\udfed","woman_factory_worker":"\ud83d\udc69\u200d\ud83c\udfed","office_worker":"\ud83e\uddd1\u200d\ud83d\udcbc","man_office_worker":"\ud83d\udc68\u200d\ud83d\udcbc","woman_office_worker":"\ud83d\udc69\u200d\ud83d\udcbc","scientist":"\ud83e\uddd1\u200d\ud83d\udd2c","man_scientist":"\ud83d\udc68\u200d\ud83d\udd2c","woman_scientist":"\ud83d\udc69\u200d\ud83d\udd2c","technologist":"\ud83e\uddd1\u200d\ud83d\udcbb","man_technologist":"\ud83d\udc68\u200d\ud83d\udcbb","woman_technologist":"\ud83d\udc69\u200d\ud83d\udcbb","singer":"\ud83e\uddd1\u200d\ud83c\udfa4","man_singer":"\ud83d\udc68\u200d\ud83c\udfa4","woman_singer":"\ud83d\udc69\u200d\ud83c\udfa4","artist":"\ud83e\uddd1\u200d\ud83c\udfa8","man_artist":"\ud83d\udc68\u200d\ud83c\udfa8","woman_artist":"\ud83d\udc69\u200d\ud83c\udfa8","pilot":"\ud83e\uddd1\u200d\u2708\ufe0f","man_pilot":"\ud83d\udc68\u200d\u2708\ufe0f","woman_pilot":"\ud83d\udc69\u200d\u2708\ufe0f","astronaut":"\ud83e\uddd1\u200d\ud83d\ude80","man_astronaut":"\ud83d\udc68\u200d\ud83d\ude80","woman_astronaut":"\ud83d\udc69\u200d\ud83d\ude80","firefighter":"\ud83e\uddd1\u200d\ud83d\ude92","man_firefighter":"\ud83d\udc68\u200d\ud83d\ude92","woman_firefighter":"\ud83d\udc69\u200d\ud83d\ude92","police_officer":"\ud83d\udc6e","cop":"\ud83d\udc6e","policeman":"\ud83d\udc6e\u200d\u2642\ufe0f","policewoman":"\ud83d\udc6e\u200d\u2640\ufe0f","detective":"\ud83d\udd75\ufe0f","male_detective":"\ud83d\udd75\ufe0f\u200d\u2642\ufe0f","female_detective":"\ud83d\udd75\ufe0f\u200d\u2640\ufe0f","guard":"\ud83d\udc82","guardsman":"\ud83d\udc82\u200d\u2642\ufe0f","guardswoman":"\ud83d\udc82\u200d\u2640\ufe0f","ninja":"\ud83e\udd77","construction_worker":"\ud83d\udc77","construction_worker_man":"\ud83d\udc77\u200d\u2642\ufe0f","construction_worker_woman":"\ud83d\udc77\u200d\u2640\ufe0f","prince":"\ud83e\udd34","princess":"\ud83d\udc78","person_with_turban":"\ud83d\udc73","man_with_turban":"\ud83d\udc73\u200d\u2642\ufe0f","woman_with_turban":"\ud83d\udc73\u200d\u2640\ufe0f","man_with_gua_pi_mao":"\ud83d\udc72","woman_with_headscarf":"\ud83e\uddd5","person_in_tuxedo":"\ud83e\udd35","man_in_tuxedo":"\ud83e\udd35\u200d\u2642\ufe0f","woman_in_tuxedo":"\ud83e\udd35\u200d\u2640\ufe0f","person_with_veil":"\ud83d\udc70","man_with_veil":"\ud83d\udc70\u200d\u2642\ufe0f","woman_with_veil":"\ud83d\udc70\u200d\u2640\ufe0f","bride_with_veil":"\ud83d\udc70\u200d\u2640\ufe0f","pregnant_woman":"\ud83e\udd30","breast_feeding":"\ud83e\udd31","woman_feeding_baby":"\ud83d\udc69\u200d\ud83c\udf7c","man_feeding_baby":"\ud83d\udc68\u200d\ud83c\udf7c","person_feeding_baby":"\ud83e\uddd1\u200d\ud83c\udf7c","angel":"\ud83d\udc7c","santa":"\ud83c\udf85","mrs_claus":"\ud83e\udd36","mx_claus":"\ud83e\uddd1\u200d\ud83c\udf84","superhero":"\ud83e\uddb8","superhero_man":"\ud83e\uddb8\u200d\u2642\ufe0f","superhero_woman":"\ud83e\uddb8\u200d\u2640\ufe0f","supervillain":"\ud83e\uddb9","supervillain_man":"\ud83e\uddb9\u200d\u2642\ufe0f","supervillain_woman":"\ud83e\uddb9\u200d\u2640\ufe0f","mage":"\ud83e\uddd9","mage_man":"\ud83e\uddd9\u200d\u2642\ufe0f","mage_woman":"\ud83e\uddd9\u200d\u2640\ufe0f","fairy":"\ud83e\uddda","fairy_man":"\ud83e\uddda\u200d\u2642\ufe0f","fairy_woman":"\ud83e\uddda\u200d\u2640\ufe0f","vampire":"\ud83e\udddb","vampire_man":"\ud83e\udddb\u200d\u2642\ufe0f","vampire_woman":"\ud83e\udddb\u200d\u2640\ufe0f","merperson":"\ud83e\udddc","merman":"\ud83e\udddc\u200d\u2642\ufe0f","mermaid":"\ud83e\udddc\u200d\u2640\ufe0f","elf":"\ud83e\udddd","elf_man":"\ud83e\udddd\u200d\u2642\ufe0f","elf_woman":"\ud83e\udddd\u200d\u2640\ufe0f","genie":"\ud83e\uddde","genie_man":"\ud83e\uddde\u200d\u2642\ufe0f","genie_woman":"\ud83e\uddde\u200d\u2640\ufe0f","zombie":"\ud83e\udddf","zombie_man":"\ud83e\udddf\u200d\u2642\ufe0f","zombie_woman":"\ud83e\udddf\u200d\u2640\ufe0f","massage":"\ud83d\udc86","massage_man":"\ud83d\udc86\u200d\u2642\ufe0f","massage_woman":"\ud83d\udc86\u200d\u2640\ufe0f","haircut":"\ud83d\udc87","haircut_man":"\ud83d\udc87\u200d\u2642\ufe0f","haircut_woman":"\ud83d\udc87\u200d\u2640\ufe0f","walking":"\ud83d\udeb6","walking_man":"\ud83d\udeb6\u200d\u2642\ufe0f","walking_woman":"\ud83d\udeb6\u200d\u2640\ufe0f","standing_person":"\ud83e\uddcd","standing_man":"\ud83e\uddcd\u200d\u2642\ufe0f","standing_woman":"\ud83e\uddcd\u200d\u2640\ufe0f","kneeling_person":"\ud83e\uddce","kneeling_man":"\ud83e\uddce\u200d\u2642\ufe0f","kneeling_woman":"\ud83e\uddce\u200d\u2640\ufe0f","person_with_probing_cane":"\ud83e\uddd1\u200d\ud83e\uddaf","man_with_probing_cane":"\ud83d\udc68\u200d\ud83e\uddaf","woman_with_probing_cane":"\ud83d\udc69\u200d\ud83e\uddaf","person_in_motorized_wheelchair":"\ud83e\uddd1\u200d\ud83e\uddbc","man_in_motorized_wheelchair":"\ud83d\udc68\u200d\ud83e\uddbc","woman_in_motorized_wheelchair":"\ud83d\udc69\u200d\ud83e\uddbc","person_in_manual_wheelchair":"\ud83e\uddd1\u200d\ud83e\uddbd","man_in_manual_wheelchair":"\ud83d\udc68\u200d\ud83e\uddbd","woman_in_manual_wheelchair":"\ud83d\udc69\u200d\ud83e\uddbd","runner":"\ud83c\udfc3","running":"\ud83c\udfc3","running_man":"\ud83c\udfc3\u200d\u2642\ufe0f","running_woman":"\ud83c\udfc3\u200d\u2640\ufe0f","woman_dancing":"\ud83d\udc83","dancer":"\ud83d\udc83","man_dancing":"\ud83d\udd7a","business_suit_levitating":"\ud83d\udd74\ufe0f","dancers":"\ud83d\udc6f","dancing_men":"\ud83d\udc6f\u200d\u2642\ufe0f","dancing_women":"\ud83d\udc6f\u200d\u2640\ufe0f","sauna_person":"\ud83e\uddd6","sauna_man":"\ud83e\uddd6\u200d\u2642\ufe0f","sauna_woman":"\ud83e\uddd6\u200d\u2640\ufe0f","climbing":"\ud83e\uddd7","climbing_man":"\ud83e\uddd7\u200d\u2642\ufe0f","climbing_woman":"\ud83e\uddd7\u200d\u2640\ufe0f","person_fencing":"\ud83e\udd3a","horse_racing":"\ud83c\udfc7","skier":"\u26f7\ufe0f","snowboarder":"\ud83c\udfc2","golfing":"\ud83c\udfcc\ufe0f","golfing_man":"\ud83c\udfcc\ufe0f\u200d\u2642\ufe0f","golfing_woman":"\ud83c\udfcc\ufe0f\u200d\u2640\ufe0f","surfer":"\ud83c\udfc4","surfing_man":"\ud83c\udfc4\u200d\u2642\ufe0f","surfing_woman":"\ud83c\udfc4\u200d\u2640\ufe0f","rowboat":"\ud83d\udea3","rowing_man":"\ud83d\udea3\u200d\u2642\ufe0f","rowing_woman":"\ud83d\udea3\u200d\u2640\ufe0f","swimmer":"\ud83c\udfca","swimming_man":"\ud83c\udfca\u200d\u2642\ufe0f","swimming_woman":"\ud83c\udfca\u200d\u2640\ufe0f","bouncing_ball_person":"\u26f9\ufe0f","bouncing_ball_man":"\u26f9\ufe0f\u200d\u2642\ufe0f","basketball_man":"\u26f9\ufe0f\u200d\u2642\ufe0f","bouncing_ball_woman":"\u26f9\ufe0f\u200d\u2640\ufe0f","basketball_woman":"\u26f9\ufe0f\u200d\u2640\ufe0f","weight_lifting":"\ud83c\udfcb\ufe0f","weight_lifting_man":"\ud83c\udfcb\ufe0f\u200d\u2642\ufe0f","weight_lifting_woman":"\ud83c\udfcb\ufe0f\u200d\u2640\ufe0f","bicyclist":"\ud83d\udeb4","biking_man":"\ud83d\udeb4\u200d\u2642\ufe0f","biking_woman":"\ud83d\udeb4\u200d\u2640\ufe0f","mountain_bicyclist":"\ud83d\udeb5","mountain_biking_man":"\ud83d\udeb5\u200d\u2642\ufe0f","mountain_biking_woman":"\ud83d\udeb5\u200d\u2640\ufe0f","cartwheeling":"\ud83e\udd38","man_cartwheeling":"\ud83e\udd38\u200d\u2642\ufe0f","woman_cartwheeling":"\ud83e\udd38\u200d\u2640\ufe0f","wrestling":"\ud83e\udd3c","men_wrestling":"\ud83e\udd3c\u200d\u2642\ufe0f","women_wrestling":"\ud83e\udd3c\u200d\u2640\ufe0f","water_polo":"\ud83e\udd3d","man_playing_water_polo":"\ud83e\udd3d\u200d\u2642\ufe0f","woman_playing_water_polo":"\ud83e\udd3d\u200d\u2640\ufe0f","handball_person":"\ud83e\udd3e","man_playing_handball":"\ud83e\udd3e\u200d\u2642\ufe0f","woman_playing_handball":"\ud83e\udd3e\u200d\u2640\ufe0f","juggling_person":"\ud83e\udd39","man_juggling":"\ud83e\udd39\u200d\u2642\ufe0f","woman_juggling":"\ud83e\udd39\u200d\u2640\ufe0f","lotus_position":"\ud83e\uddd8","lotus_position_man":"\ud83e\uddd8\u200d\u2642\ufe0f","lotus_position_woman":"\ud83e\uddd8\u200d\u2640\ufe0f","bath":"\ud83d\udec0","sleeping_bed":"\ud83d\udecc","people_holding_hands":"\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1","two_women_holding_hands":"\ud83d\udc6d","couple":"\ud83d\udc6b","two_men_holding_hands":"\ud83d\udc6c","couplekiss":"\ud83d\udc8f","couplekiss_man_woman":"\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68","couplekiss_man_man":"\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68","couplekiss_woman_woman":"\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69","couple_with_heart":"\ud83d\udc91","couple_with_heart_woman_man":"\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc68","couple_with_heart_man_man":"\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68","couple_with_heart_woman_woman":"\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc69","family":"\ud83d\udc6a","family_man_woman_boy":"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66","family_man_woman_girl":"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67","family_man_woman_girl_boy":"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66","family_man_woman_boy_boy":"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66","family_man_woman_girl_girl":"\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67","family_man_man_boy":"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66","family_man_man_girl":"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67","family_man_man_girl_boy":"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66","family_man_man_boy_boy":"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66","family_man_man_girl_girl":"\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67","family_woman_woman_boy":"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66","family_woman_woman_girl":"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67","family_woman_woman_girl_boy":"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66","family_woman_woman_boy_boy":"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66","family_woman_woman_girl_girl":"\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67","family_man_boy":"\ud83d\udc68\u200d\ud83d\udc66","family_man_boy_boy":"\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66","family_man_girl":"\ud83d\udc68\u200d\ud83d\udc67","family_man_girl_boy":"\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc66","family_man_girl_girl":"\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d\udc67","family_woman_boy":"\ud83d\udc69\u200d\ud83d\udc66","family_woman_boy_boy":"\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66","family_woman_girl":"\ud83d\udc69\u200d\ud83d\udc67","family_woman_girl_boy":"\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc66","family_woman_girl_girl":"\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d\udc67","speaking_head":"\ud83d\udde3\ufe0f","bust_in_silhouette":"\ud83d\udc64","busts_in_silhouette":"\ud83d\udc65","people_hugging":"\ud83e\udec2","footprints":"\ud83d\udc63","monkey_face":"\ud83d\udc35","monkey":"\ud83d\udc12","gorilla":"\ud83e\udd8d","orangutan":"\ud83e\udda7","dog":"\ud83d\udc36","dog2":"\ud83d\udc15","guide_dog":"\ud83e\uddae","service_dog":"\ud83d\udc15\u200d\ud83e\uddba","poodle":"\ud83d\udc29","wolf":"\ud83d\udc3a","fox_face":"\ud83e\udd8a","raccoon":"\ud83e\udd9d","cat":"\ud83d\udc31","cat2":"\ud83d\udc08","black_cat":"\ud83d\udc08\u200d\u2b1b","lion":"\ud83e\udd81","tiger":"\ud83d\udc2f","tiger2":"\ud83d\udc05","leopard":"\ud83d\udc06","horse":"\ud83d\udc34","racehorse":"\ud83d\udc0e","unicorn":"\ud83e\udd84","zebra":"\ud83e\udd93","deer":"\ud83e\udd8c","bison":"\ud83e\uddac","cow":"\ud83d\udc2e","ox":"\ud83d\udc02","water_buffalo":"\ud83d\udc03","cow2":"\ud83d\udc04","pig":"\ud83d\udc37","pig2":"\ud83d\udc16","boar":"\ud83d\udc17","pig_nose":"\ud83d\udc3d","ram":"\ud83d\udc0f","sheep":"\ud83d\udc11","goat":"\ud83d\udc10","dromedary_camel":"\ud83d\udc2a","camel":"\ud83d\udc2b","llama":"\ud83e\udd99","giraffe":"\ud83e\udd92","elephant":"\ud83d\udc18","mammoth":"\ud83e\udda3","rhinoceros":"\ud83e\udd8f","hippopotamus":"\ud83e\udd9b","mouse":"\ud83d\udc2d","mouse2":"\ud83d\udc01","rat":"\ud83d\udc00","hamster":"\ud83d\udc39","rabbit":"\ud83d\udc30","rabbit2":"\ud83d\udc07","chipmunk":"\ud83d\udc3f\ufe0f","beaver":"\ud83e\uddab","hedgehog":"\ud83e\udd94","bat":"\ud83e\udd87","bear":"\ud83d\udc3b","polar_bear":"\ud83d\udc3b\u200d\u2744\ufe0f","koala":"\ud83d\udc28","panda_face":"\ud83d\udc3c","sloth":"\ud83e\udda5","otter":"\ud83e\udda6","skunk":"\ud83e\udda8","kangaroo":"\ud83e\udd98","badger":"\ud83e\udda1","feet":"\ud83d\udc3e","paw_prints":"\ud83d\udc3e","turkey":"\ud83e\udd83","chicken":"\ud83d\udc14","rooster":"\ud83d\udc13","hatching_chick":"\ud83d\udc23","baby_chick":"\ud83d\udc24","hatched_chick":"\ud83d\udc25","bird":"\ud83d\udc26","penguin":"\ud83d\udc27","dove":"\ud83d\udd4a\ufe0f","eagle":"\ud83e\udd85","duck":"\ud83e\udd86","swan":"\ud83e\udda2","owl":"\ud83e\udd89","dodo":"\ud83e\udda4","feather":"\ud83e\udeb6","flamingo":"\ud83e\udda9","peacock":"\ud83e\udd9a","parrot":"\ud83e\udd9c","frog":"\ud83d\udc38","crocodile":"\ud83d\udc0a","turtle":"\ud83d\udc22","lizard":"\ud83e\udd8e","snake":"\ud83d\udc0d","dragon_face":"\ud83d\udc32","dragon":"\ud83d\udc09","sauropod":"\ud83e\udd95","t-rex":"\ud83e\udd96","whale":"\ud83d\udc33","whale2":"\ud83d\udc0b","dolphin":"\ud83d\udc2c","flipper":"\ud83d\udc2c","seal":"\ud83e\uddad","fish":"\ud83d\udc1f","tropical_fish":"\ud83d\udc20","blowfish":"\ud83d\udc21","shark":"\ud83e\udd88","octopus":"\ud83d\udc19","shell":"\ud83d\udc1a","snail":"\ud83d\udc0c","butterfly":"\ud83e\udd8b","bug":"\ud83d\udc1b","ant":"\ud83d\udc1c","bee":"\ud83d\udc1d","honeybee":"\ud83d\udc1d","beetle":"\ud83e\udeb2","lady_beetle":"\ud83d\udc1e","cricket":"\ud83e\udd97","cockroach":"\ud83e\udeb3","spider":"\ud83d\udd77\ufe0f","spider_web":"\ud83d\udd78\ufe0f","scorpion":"\ud83e\udd82","mosquito":"\ud83e\udd9f","fly":"\ud83e\udeb0","worm":"\ud83e\udeb1","microbe":"\ud83e\udda0","bouquet":"\ud83d\udc90","cherry_blossom":"\ud83c\udf38","white_flower":"\ud83d\udcae","rosette":"\ud83c\udff5\ufe0f","rose":"\ud83c\udf39","wilted_flower":"\ud83e\udd40","hibiscus":"\ud83c\udf3a","sunflower":"\ud83c\udf3b","blossom":"\ud83c\udf3c","tulip":"\ud83c\udf37","seedling":"\ud83c\udf31","potted_plant":"\ud83e\udeb4","evergreen_tree":"\ud83c\udf32","deciduous_tree":"\ud83c\udf33","palm_tree":"\ud83c\udf34","cactus":"\ud83c\udf35","ear_of_rice":"\ud83c\udf3e","herb":"\ud83c\udf3f","shamrock":"\u2618\ufe0f","four_leaf_clover":"\ud83c\udf40","maple_leaf":"\ud83c\udf41","fallen_leaf":"\ud83c\udf42","leaves":"\ud83c\udf43","grapes":"\ud83c\udf47","melon":"\ud83c\udf48","watermelon":"\ud83c\udf49","tangerine":"\ud83c\udf4a","orange":"\ud83c\udf4a","mandarin":"\ud83c\udf4a","lemon":"\ud83c\udf4b","banana":"\ud83c\udf4c","pineapple":"\ud83c\udf4d","mango":"\ud83e\udd6d","apple":"\ud83c\udf4e","green_apple":"\ud83c\udf4f","pear":"\ud83c\udf50","peach":"\ud83c\udf51","cherries":"\ud83c\udf52","strawberry":"\ud83c\udf53","blueberries":"\ud83e\uded0","kiwi_fruit":"\ud83e\udd5d","tomato":"\ud83c\udf45","olive":"\ud83e\uded2","coconut":"\ud83e\udd65","avocado":"\ud83e\udd51","eggplant":"\ud83c\udf46","potato":"\ud83e\udd54","carrot":"\ud83e\udd55","corn":"\ud83c\udf3d","hot_pepper":"\ud83c\udf36\ufe0f","bell_pepper":"\ud83e\uded1","cucumber":"\ud83e\udd52","leafy_green":"\ud83e\udd6c","broccoli":"\ud83e\udd66","garlic":"\ud83e\uddc4","onion":"\ud83e\uddc5","mushroom":"\ud83c\udf44","peanuts":"\ud83e\udd5c","chestnut":"\ud83c\udf30","bread":"\ud83c\udf5e","croissant":"\ud83e\udd50","baguette_bread":"\ud83e\udd56","flatbread":"\ud83e\uded3","pretzel":"\ud83e\udd68","bagel":"\ud83e\udd6f","pancakes":"\ud83e\udd5e","waffle":"\ud83e\uddc7","cheese":"\ud83e\uddc0","meat_on_bone":"\ud83c\udf56","poultry_leg":"\ud83c\udf57","cut_of_meat":"\ud83e\udd69","bacon":"\ud83e\udd53","hamburger":"\ud83c\udf54","fries":"\ud83c\udf5f","pizza":"\ud83c\udf55","hotdog":"\ud83c\udf2d","sandwich":"\ud83e\udd6a","taco":"\ud83c\udf2e","burrito":"\ud83c\udf2f","tamale":"\ud83e\uded4","stuffed_flatbread":"\ud83e\udd59","falafel":"\ud83e\uddc6","egg":"\ud83e\udd5a","fried_egg":"\ud83c\udf73","shallow_pan_of_food":"\ud83e\udd58","stew":"\ud83c\udf72","fondue":"\ud83e\uded5","bowl_with_spoon":"\ud83e\udd63","green_salad":"\ud83e\udd57","popcorn":"\ud83c\udf7f","butter":"\ud83e\uddc8","salt":"\ud83e\uddc2","canned_food":"\ud83e\udd6b","bento":"\ud83c\udf71","rice_cracker":"\ud83c\udf58","rice_ball":"\ud83c\udf59","rice":"\ud83c\udf5a","curry":"\ud83c\udf5b","ramen":"\ud83c\udf5c","spaghetti":"\ud83c\udf5d","sweet_potato":"\ud83c\udf60","oden":"\ud83c\udf62","sushi":"\ud83c\udf63","fried_shrimp":"\ud83c\udf64","fish_cake":"\ud83c\udf65","moon_cake":"\ud83e\udd6e","dango":"\ud83c\udf61","dumpling":"\ud83e\udd5f","fortune_cookie":"\ud83e\udd60","takeout_box":"\ud83e\udd61","crab":"\ud83e\udd80","lobster":"\ud83e\udd9e","shrimp":"\ud83e\udd90","squid":"\ud83e\udd91","oyster":"\ud83e\uddaa","icecream":"\ud83c\udf66","shaved_ice":"\ud83c\udf67","ice_cream":"\ud83c\udf68","doughnut":"\ud83c\udf69","cookie":"\ud83c\udf6a","birthday":"\ud83c\udf82","cake":"\ud83c\udf70","cupcake":"\ud83e\uddc1","pie":"\ud83e\udd67","chocolate_bar":"\ud83c\udf6b","candy":"\ud83c\udf6c","lollipop":"\ud83c\udf6d","custard":"\ud83c\udf6e","honey_pot":"\ud83c\udf6f","baby_bottle":"\ud83c\udf7c","milk_glass":"\ud83e\udd5b","coffee":"\u2615","teapot":"\ud83e\uded6","tea":"\ud83c\udf75","sake":"\ud83c\udf76","champagne":"\ud83c\udf7e","wine_glass":"\ud83c\udf77","cocktail":"\ud83c\udf78","tropical_drink":"\ud83c\udf79","beer":"\ud83c\udf7a","beers":"\ud83c\udf7b","clinking_glasses":"\ud83e\udd42","tumbler_glass":"\ud83e\udd43","cup_with_straw":"\ud83e\udd64","bubble_tea":"\ud83e\uddcb","beverage_box":"\ud83e\uddc3","mate":"\ud83e\uddc9","ice_cube":"\ud83e\uddca","chopsticks":"\ud83e\udd62","plate_with_cutlery":"\ud83c\udf7d\ufe0f","fork_and_knife":"\ud83c\udf74","spoon":"\ud83e\udd44","hocho":"\ud83d\udd2a","knife":"\ud83d\udd2a","amphora":"\ud83c\udffa","earth_africa":"\ud83c\udf0d","earth_americas":"\ud83c\udf0e","earth_asia":"\ud83c\udf0f","globe_with_meridians":"\ud83c\udf10","world_map":"\ud83d\uddfa\ufe0f","japan":"\ud83d\uddfe","compass":"\ud83e\udded","mountain_snow":"\ud83c\udfd4\ufe0f","mountain":"\u26f0\ufe0f","volcano":"\ud83c\udf0b","mount_fuji":"\ud83d\uddfb","camping":"\ud83c\udfd5\ufe0f","beach_umbrella":"\ud83c\udfd6\ufe0f","desert":"\ud83c\udfdc\ufe0f","desert_island":"\ud83c\udfdd\ufe0f","national_park":"\ud83c\udfde\ufe0f","stadium":"\ud83c\udfdf\ufe0f","classical_building":"\ud83c\udfdb\ufe0f","building_construction":"\ud83c\udfd7\ufe0f","bricks":"\ud83e\uddf1","rock":"\ud83e\udea8","wood":"\ud83e\udeb5","hut":"\ud83d\uded6","houses":"\ud83c\udfd8\ufe0f","derelict_house":"\ud83c\udfda\ufe0f","house":"\ud83c\udfe0","house_with_garden":"\ud83c\udfe1","office":"\ud83c\udfe2","post_office":"\ud83c\udfe3","european_post_office":"\ud83c\udfe4","hospital":"\ud83c\udfe5","bank":"\ud83c\udfe6","hotel":"\ud83c\udfe8","love_hotel":"\ud83c\udfe9","convenience_store":"\ud83c\udfea","school":"\ud83c\udfeb","department_store":"\ud83c\udfec","factory":"\ud83c\udfed","japanese_castle":"\ud83c\udfef","european_castle":"\ud83c\udff0","wedding":"\ud83d\udc92","tokyo_tower":"\ud83d\uddfc","statue_of_liberty":"\ud83d\uddfd","church":"\u26ea","mosque":"\ud83d\udd4c","hindu_temple":"\ud83d\uded5","synagogue":"\ud83d\udd4d","shinto_shrine":"\u26e9\ufe0f","kaaba":"\ud83d\udd4b","fountain":"\u26f2","tent":"\u26fa","foggy":"\ud83c\udf01","night_with_stars":"\ud83c\udf03","cityscape":"\ud83c\udfd9\ufe0f","sunrise_over_mountains":"\ud83c\udf04","sunrise":"\ud83c\udf05","city_sunset":"\ud83c\udf06","city_sunrise":"\ud83c\udf07","bridge_at_night":"\ud83c\udf09","hotsprings":"\u2668\ufe0f","carousel_horse":"\ud83c\udfa0","ferris_wheel":"\ud83c\udfa1","roller_coaster":"\ud83c\udfa2","barber":"\ud83d\udc88","circus_tent":"\ud83c\udfaa","steam_locomotive":"\ud83d\ude82","railway_car":"\ud83d\ude83","bullettrain_side":"\ud83d\ude84","bullettrain_front":"\ud83d\ude85","train2":"\ud83d\ude86","metro":"\ud83d\ude87","light_rail":"\ud83d\ude88","station":"\ud83d\ude89","tram":"\ud83d\ude8a","monorail":"\ud83d\ude9d","mountain_railway":"\ud83d\ude9e","train":"\ud83d\ude8b","bus":"\ud83d\ude8c","oncoming_bus":"\ud83d\ude8d","trolleybus":"\ud83d\ude8e","minibus":"\ud83d\ude90","ambulance":"\ud83d\ude91","fire_engine":"\ud83d\ude92","police_car":"\ud83d\ude93","oncoming_police_car":"\ud83d\ude94","taxi":"\ud83d\ude95","oncoming_taxi":"\ud83d\ude96","car":"\ud83d\ude97","red_car":"\ud83d\ude97","oncoming_automobile":"\ud83d\ude98","blue_car":"\ud83d\ude99","pickup_truck":"\ud83d\udefb","truck":"\ud83d\ude9a","articulated_lorry":"\ud83d\ude9b","tractor":"\ud83d\ude9c","racing_car":"\ud83c\udfce\ufe0f","motorcycle":"\ud83c\udfcd\ufe0f","motor_scooter":"\ud83d\udef5","manual_wheelchair":"\ud83e\uddbd","motorized_wheelchair":"\ud83e\uddbc","auto_rickshaw":"\ud83d\udefa","bike":"\ud83d\udeb2","kick_scooter":"\ud83d\udef4","skateboard":"\ud83d\udef9","roller_skate":"\ud83d\udefc","busstop":"\ud83d\ude8f","motorway":"\ud83d\udee3\ufe0f","railway_track":"\ud83d\udee4\ufe0f","oil_drum":"\ud83d\udee2\ufe0f","fuelpump":"\u26fd","rotating_light":"\ud83d\udea8","traffic_light":"\ud83d\udea5","vertical_traffic_light":"\ud83d\udea6","stop_sign":"\ud83d\uded1","construction":"\ud83d\udea7","anchor":"\u2693","boat":"\u26f5","sailboat":"\u26f5","canoe":"\ud83d\udef6","speedboat":"\ud83d\udea4","passenger_ship":"\ud83d\udef3\ufe0f","ferry":"\u26f4\ufe0f","motor_boat":"\ud83d\udee5\ufe0f","ship":"\ud83d\udea2","airplane":"\u2708\ufe0f","small_airplane":"\ud83d\udee9\ufe0f","flight_departure":"\ud83d\udeeb","flight_arrival":"\ud83d\udeec","parachute":"\ud83e\ude82","seat":"\ud83d\udcba","helicopter":"\ud83d\ude81","suspension_railway":"\ud83d\ude9f","mountain_cableway":"\ud83d\udea0","aerial_tramway":"\ud83d\udea1","artificial_satellite":"\ud83d\udef0\ufe0f","rocket":"\ud83d\ude80","flying_saucer":"\ud83d\udef8","bellhop_bell":"\ud83d\udece\ufe0f","luggage":"\ud83e\uddf3","hourglass":"\u231b","hourglass_flowing_sand":"\u23f3","watch":"\u231a","alarm_clock":"\u23f0","stopwatch":"\u23f1\ufe0f","timer_clock":"\u23f2\ufe0f","mantelpiece_clock":"\ud83d\udd70\ufe0f","clock12":"\ud83d\udd5b","clock1230":"\ud83d\udd67","clock1":"\ud83d\udd50","clock130":"\ud83d\udd5c","clock2":"\ud83d\udd51","clock230":"\ud83d\udd5d","clock3":"\ud83d\udd52","clock330":"\ud83d\udd5e","clock4":"\ud83d\udd53","clock430":"\ud83d\udd5f","clock5":"\ud83d\udd54","clock530":"\ud83d\udd60","clock6":"\ud83d\udd55","clock630":"\ud83d\udd61","clock7":"\ud83d\udd56","clock730":"\ud83d\udd62","clock8":"\ud83d\udd57","clock830":"\ud83d\udd63","clock9":"\ud83d\udd58","clock930":"\ud83d\udd64","clock10":"\ud83d\udd59","clock1030":"\ud83d\udd65","clock11":"\ud83d\udd5a","clock1130":"\ud83d\udd66","new_moon":"\ud83c\udf11","waxing_crescent_moon":"\ud83c\udf12","first_quarter_moon":"\ud83c\udf13","moon":"\ud83c\udf14","waxing_gibbous_moon":"\ud83c\udf14","full_moon":"\ud83c\udf15","waning_gibbous_moon":"\ud83c\udf16","last_quarter_moon":"\ud83c\udf17","waning_crescent_moon":"\ud83c\udf18","crescent_moon":"\ud83c\udf19","new_moon_with_face":"\ud83c\udf1a","first_quarter_moon_with_face":"\ud83c\udf1b","last_quarter_moon_with_face":"\ud83c\udf1c","thermometer":"\ud83c\udf21\ufe0f","sunny":"\u2600\ufe0f","full_moon_with_face":"\ud83c\udf1d","sun_with_face":"\ud83c\udf1e","ringed_planet":"\ud83e\ude90","star":"\u2b50","star2":"\ud83c\udf1f","stars":"\ud83c\udf20","milky_way":"\ud83c\udf0c","cloud":"\u2601\ufe0f","partly_sunny":"\u26c5","cloud_with_lightning_and_rain":"\u26c8\ufe0f","sun_behind_small_cloud":"\ud83c\udf24\ufe0f","sun_behind_large_cloud":"\ud83c\udf25\ufe0f","sun_behind_rain_cloud":"\ud83c\udf26\ufe0f","cloud_with_rain":"\ud83c\udf27\ufe0f","cloud_with_snow":"\ud83c\udf28\ufe0f","cloud_with_lightning":"\ud83c\udf29\ufe0f","tornado":"\ud83c\udf2a\ufe0f","fog":"\ud83c\udf2b\ufe0f","wind_face":"\ud83c\udf2c\ufe0f","cyclone":"\ud83c\udf00","rainbow":"\ud83c\udf08","closed_umbrella":"\ud83c\udf02","open_umbrella":"\u2602\ufe0f","umbrella":"\u2614","parasol_on_ground":"\u26f1\ufe0f","zap":"\u26a1","snowflake":"\u2744\ufe0f","snowman_with_snow":"\u2603\ufe0f","snowman":"\u26c4","comet":"\u2604\ufe0f","fire":"\ud83d\udd25","droplet":"\ud83d\udca7","ocean":"\ud83c\udf0a","jack_o_lantern":"\ud83c\udf83","christmas_tree":"\ud83c\udf84","fireworks":"\ud83c\udf86","sparkler":"\ud83c\udf87","firecracker":"\ud83e\udde8","sparkles":"\u2728","balloon":"\ud83c\udf88","tada":"\ud83c\udf89","confetti_ball":"\ud83c\udf8a","tanabata_tree":"\ud83c\udf8b","bamboo":"\ud83c\udf8d","dolls":"\ud83c\udf8e","flags":"\ud83c\udf8f","wind_chime":"\ud83c\udf90","rice_scene":"\ud83c\udf91","red_envelope":"\ud83e\udde7","ribbon":"\ud83c\udf80","gift":"\ud83c\udf81","reminder_ribbon":"\ud83c\udf97\ufe0f","tickets":"\ud83c\udf9f\ufe0f","ticket":"\ud83c\udfab","medal_military":"\ud83c\udf96\ufe0f","trophy":"\ud83c\udfc6","medal_sports":"\ud83c\udfc5","1st_place_medal":"\ud83e\udd47","2nd_place_medal":"\ud83e\udd48","3rd_place_medal":"\ud83e\udd49","soccer":"\u26bd","baseball":"\u26be","softball":"\ud83e\udd4e","basketball":"\ud83c\udfc0","volleyball":"\ud83c\udfd0","football":"\ud83c\udfc8","rugby_football":"\ud83c\udfc9","tennis":"\ud83c\udfbe","flying_disc":"\ud83e\udd4f","bowling":"\ud83c\udfb3","cricket_game":"\ud83c\udfcf","field_hockey":"\ud83c\udfd1","ice_hockey":"\ud83c\udfd2","lacrosse":"\ud83e\udd4d","ping_pong":"\ud83c\udfd3","badminton":"\ud83c\udff8","boxing_glove":"\ud83e\udd4a","martial_arts_uniform":"\ud83e\udd4b","goal_net":"\ud83e\udd45","golf":"\u26f3","ice_skate":"\u26f8\ufe0f","fishing_pole_and_fish":"\ud83c\udfa3","diving_mask":"\ud83e\udd3f","running_shirt_with_sash":"\ud83c\udfbd","ski":"\ud83c\udfbf","sled":"\ud83d\udef7","curling_stone":"\ud83e\udd4c","dart":"\ud83c\udfaf","yo_yo":"\ud83e\ude80","kite":"\ud83e\ude81","8ball":"\ud83c\udfb1","crystal_ball":"\ud83d\udd2e","magic_wand":"\ud83e\ude84","nazar_amulet":"\ud83e\uddff","video_game":"\ud83c\udfae","joystick":"\ud83d\udd79\ufe0f","slot_machine":"\ud83c\udfb0","game_die":"\ud83c\udfb2","jigsaw":"\ud83e\udde9","teddy_bear":"\ud83e\uddf8","pinata":"\ud83e\ude85","nesting_dolls":"\ud83e\ude86","spades":"\u2660\ufe0f","hearts":"\u2665\ufe0f","diamonds":"\u2666\ufe0f","clubs":"\u2663\ufe0f","chess_pawn":"\u265f\ufe0f","black_joker":"\ud83c\udccf","mahjong":"\ud83c\udc04","flower_playing_cards":"\ud83c\udfb4","performing_arts":"\ud83c\udfad","framed_picture":"\ud83d\uddbc\ufe0f","art":"\ud83c\udfa8","thread":"\ud83e\uddf5","sewing_needle":"\ud83e\udea1","yarn":"\ud83e\uddf6","knot":"\ud83e\udea2","eyeglasses":"\ud83d\udc53","dark_sunglasses":"\ud83d\udd76\ufe0f","goggles":"\ud83e\udd7d","lab_coat":"\ud83e\udd7c","safety_vest":"\ud83e\uddba","necktie":"\ud83d\udc54","shirt":"\ud83d\udc55","tshirt":"\ud83d\udc55","jeans":"\ud83d\udc56","scarf":"\ud83e\udde3","gloves":"\ud83e\udde4","coat":"\ud83e\udde5","socks":"\ud83e\udde6","dress":"\ud83d\udc57","kimono":"\ud83d\udc58","sari":"\ud83e\udd7b","one_piece_swimsuit":"\ud83e\ude71","swim_brief":"\ud83e\ude72","shorts":"\ud83e\ude73","bikini":"\ud83d\udc59","womans_clothes":"\ud83d\udc5a","purse":"\ud83d\udc5b","handbag":"\ud83d\udc5c","pouch":"\ud83d\udc5d","shopping":"\ud83d\udecd\ufe0f","school_satchel":"\ud83c\udf92","thong_sandal":"\ud83e\ude74","mans_shoe":"\ud83d\udc5e","shoe":"\ud83d\udc5e","athletic_shoe":"\ud83d\udc5f","hiking_boot":"\ud83e\udd7e","flat_shoe":"\ud83e\udd7f","high_heel":"\ud83d\udc60","sandal":"\ud83d\udc61","ballet_shoes":"\ud83e\ude70","boot":"\ud83d\udc62","crown":"\ud83d\udc51","womans_hat":"\ud83d\udc52","tophat":"\ud83c\udfa9","mortar_board":"\ud83c\udf93","billed_cap":"\ud83e\udde2","military_helmet":"\ud83e\ude96","rescue_worker_helmet":"\u26d1\ufe0f","prayer_beads":"\ud83d\udcff","lipstick":"\ud83d\udc84","ring":"\ud83d\udc8d","gem":"\ud83d\udc8e","mute":"\ud83d\udd07","speaker":"\ud83d\udd08","sound":"\ud83d\udd09","loud_sound":"\ud83d\udd0a","loudspeaker":"\ud83d\udce2","mega":"\ud83d\udce3","postal_horn":"\ud83d\udcef","bell":"\ud83d\udd14","no_bell":"\ud83d\udd15","musical_score":"\ud83c\udfbc","musical_note":"\ud83c\udfb5","notes":"\ud83c\udfb6","studio_microphone":"\ud83c\udf99\ufe0f","level_slider":"\ud83c\udf9a\ufe0f","control_knobs":"\ud83c\udf9b\ufe0f","microphone":"\ud83c\udfa4","headphones":"\ud83c\udfa7","radio":"\ud83d\udcfb","saxophone":"\ud83c\udfb7","accordion":"\ud83e\ude97","guitar":"\ud83c\udfb8","musical_keyboard":"\ud83c\udfb9","trumpet":"\ud83c\udfba","violin":"\ud83c\udfbb","banjo":"\ud83e\ude95","drum":"\ud83e\udd41","long_drum":"\ud83e\ude98","iphone":"\ud83d\udcf1","calling":"\ud83d\udcf2","phone":"\u260e\ufe0f","telephone":"\u260e\ufe0f","telephone_receiver":"\ud83d\udcde","pager":"\ud83d\udcdf","fax":"\ud83d\udce0","battery":"\ud83d\udd0b","electric_plug":"\ud83d\udd0c","computer":"\ud83d\udcbb","desktop_computer":"\ud83d\udda5\ufe0f","printer":"\ud83d\udda8\ufe0f","keyboard":"\u2328\ufe0f","computer_mouse":"\ud83d\uddb1\ufe0f","trackball":"\ud83d\uddb2\ufe0f","minidisc":"\ud83d\udcbd","floppy_disk":"\ud83d\udcbe","cd":"\ud83d\udcbf","dvd":"\ud83d\udcc0","abacus":"\ud83e\uddee","movie_camera":"\ud83c\udfa5","film_strip":"\ud83c\udf9e\ufe0f","film_projector":"\ud83d\udcfd\ufe0f","clapper":"\ud83c\udfac","tv":"\ud83d\udcfa","camera":"\ud83d\udcf7","camera_flash":"\ud83d\udcf8","video_camera":"\ud83d\udcf9","vhs":"\ud83d\udcfc","mag":"\ud83d\udd0d","mag_right":"\ud83d\udd0e","candle":"\ud83d\udd6f\ufe0f","bulb":"\ud83d\udca1","flashlight":"\ud83d\udd26","izakaya_lantern":"\ud83c\udfee","lantern":"\ud83c\udfee","diya_lamp":"\ud83e\ude94","notebook_with_decorative_cover":"\ud83d\udcd4","closed_book":"\ud83d\udcd5","book":"\ud83d\udcd6","open_book":"\ud83d\udcd6","green_book":"\ud83d\udcd7","blue_book":"\ud83d\udcd8","orange_book":"\ud83d\udcd9","books":"\ud83d\udcda","notebook":"\ud83d\udcd3","ledger":"\ud83d\udcd2","page_with_curl":"\ud83d\udcc3","scroll":"\ud83d\udcdc","page_facing_up":"\ud83d\udcc4","newspaper":"\ud83d\udcf0","newspaper_roll":"\ud83d\uddde\ufe0f","bookmark_tabs":"\ud83d\udcd1","bookmark":"\ud83d\udd16","label":"\ud83c\udff7\ufe0f","moneybag":"\ud83d\udcb0","coin":"\ud83e\ude99","yen":"\ud83d\udcb4","dollar":"\ud83d\udcb5","euro":"\ud83d\udcb6","pound":"\ud83d\udcb7","money_with_wings":"\ud83d\udcb8","credit_card":"\ud83d\udcb3","receipt":"\ud83e\uddfe","chart":"\ud83d\udcb9","envelope":"\u2709\ufe0f","email":"\ud83d\udce7","e-mail":"\ud83d\udce7","incoming_envelope":"\ud83d\udce8","envelope_with_arrow":"\ud83d\udce9","outbox_tray":"\ud83d\udce4","inbox_tray":"\ud83d\udce5","package":"\ud83d\udce6","mailbox":"\ud83d\udceb","mailbox_closed":"\ud83d\udcea","mailbox_with_mail":"\ud83d\udcec","mailbox_with_no_mail":"\ud83d\udced","postbox":"\ud83d\udcee","ballot_box":"\ud83d\uddf3\ufe0f","pencil2":"\u270f\ufe0f","black_nib":"\u2712\ufe0f","fountain_pen":"\ud83d\udd8b\ufe0f","pen":"\ud83d\udd8a\ufe0f","paintbrush":"\ud83d\udd8c\ufe0f","crayon":"\ud83d\udd8d\ufe0f","memo":"\ud83d\udcdd","pencil":"\ud83d\udcdd","briefcase":"\ud83d\udcbc","file_folder":"\ud83d\udcc1","open_file_folder":"\ud83d\udcc2","card_index_dividers":"\ud83d\uddc2\ufe0f","date":"\ud83d\udcc5","calendar":"\ud83d\udcc6","spiral_notepad":"\ud83d\uddd2\ufe0f","spiral_calendar":"\ud83d\uddd3\ufe0f","card_index":"\ud83d\udcc7","chart_with_upwards_trend":"\ud83d\udcc8","chart_with_downwards_trend":"\ud83d\udcc9","bar_chart":"\ud83d\udcca","clipboard":"\ud83d\udccb","pushpin":"\ud83d\udccc","round_pushpin":"\ud83d\udccd","paperclip":"\ud83d\udcce","paperclips":"\ud83d\udd87\ufe0f","straight_ruler":"\ud83d\udccf","triangular_ruler":"\ud83d\udcd0","scissors":"\u2702\ufe0f","card_file_box":"\ud83d\uddc3\ufe0f","file_cabinet":"\ud83d\uddc4\ufe0f","wastebasket":"\ud83d\uddd1\ufe0f","lock":"\ud83d\udd12","unlock":"\ud83d\udd13","lock_with_ink_pen":"\ud83d\udd0f","closed_lock_with_key":"\ud83d\udd10","key":"\ud83d\udd11","old_key":"\ud83d\udddd\ufe0f","hammer":"\ud83d\udd28","axe":"\ud83e\ude93","pick":"\u26cf\ufe0f","hammer_and_pick":"\u2692\ufe0f","hammer_and_wrench":"\ud83d\udee0\ufe0f","dagger":"\ud83d\udde1\ufe0f","crossed_swords":"\u2694\ufe0f","gun":"\ud83d\udd2b","boomerang":"\ud83e\ude83","bow_and_arrow":"\ud83c\udff9","shield":"\ud83d\udee1\ufe0f","carpentry_saw":"\ud83e\ude9a","wrench":"\ud83d\udd27","screwdriver":"\ud83e\ude9b","nut_and_bolt":"\ud83d\udd29","gear":"\u2699\ufe0f","clamp":"\ud83d\udddc\ufe0f","balance_scale":"\u2696\ufe0f","probing_cane":"\ud83e\uddaf","link":"\ud83d\udd17","chains":"\u26d3\ufe0f","hook":"\ud83e\ude9d","toolbox":"\ud83e\uddf0","magnet":"\ud83e\uddf2","ladder":"\ud83e\ude9c","alembic":"\u2697\ufe0f","test_tube":"\ud83e\uddea","petri_dish":"\ud83e\uddeb","dna":"\ud83e\uddec","microscope":"\ud83d\udd2c","telescope":"\ud83d\udd2d","satellite":"\ud83d\udce1","syringe":"\ud83d\udc89","drop_of_blood":"\ud83e\ude78","pill":"\ud83d\udc8a","adhesive_bandage":"\ud83e\ude79","stethoscope":"\ud83e\ude7a","door":"\ud83d\udeaa","elevator":"\ud83d\uded7","mirror":"\ud83e\ude9e","window":"\ud83e\ude9f","bed":"\ud83d\udecf\ufe0f","couch_and_lamp":"\ud83d\udecb\ufe0f","chair":"\ud83e\ude91","toilet":"\ud83d\udebd","plunger":"\ud83e\udea0","shower":"\ud83d\udebf","bathtub":"\ud83d\udec1","mouse_trap":"\ud83e\udea4","razor":"\ud83e\ude92","lotion_bottle":"\ud83e\uddf4","safety_pin":"\ud83e\uddf7","broom":"\ud83e\uddf9","basket":"\ud83e\uddfa","roll_of_paper":"\ud83e\uddfb","bucket":"\ud83e\udea3","soap":"\ud83e\uddfc","toothbrush":"\ud83e\udea5","sponge":"\ud83e\uddfd","fire_extinguisher":"\ud83e\uddef","shopping_cart":"\ud83d\uded2","smoking":"\ud83d\udeac","coffin":"\u26b0\ufe0f","headstone":"\ud83e\udea6","funeral_urn":"\u26b1\ufe0f","moyai":"\ud83d\uddff","placard":"\ud83e\udea7","atm":"\ud83c\udfe7","put_litter_in_its_place":"\ud83d\udeae","potable_water":"\ud83d\udeb0","wheelchair":"\u267f","mens":"\ud83d\udeb9","womens":"\ud83d\udeba","restroom":"\ud83d\udebb","baby_symbol":"\ud83d\udebc","wc":"\ud83d\udebe","passport_control":"\ud83d\udec2","customs":"\ud83d\udec3","baggage_claim":"\ud83d\udec4","left_luggage":"\ud83d\udec5","warning":"\u26a0\ufe0f","children_crossing":"\ud83d\udeb8","no_entry":"\u26d4","no_entry_sign":"\ud83d\udeab","no_bicycles":"\ud83d\udeb3","no_smoking":"\ud83d\udead","do_not_litter":"\ud83d\udeaf","non-potable_water":"\ud83d\udeb1","no_pedestrians":"\ud83d\udeb7","no_mobile_phones":"\ud83d\udcf5","underage":"\ud83d\udd1e","radioactive":"\u2622\ufe0f","biohazard":"\u2623\ufe0f","arrow_up":"\u2b06\ufe0f","arrow_upper_right":"\u2197\ufe0f","arrow_right":"\u27a1\ufe0f","arrow_lower_right":"\u2198\ufe0f","arrow_down":"\u2b07\ufe0f","arrow_lower_left":"\u2199\ufe0f","arrow_left":"\u2b05\ufe0f","arrow_upper_left":"\u2196\ufe0f","arrow_up_down":"\u2195\ufe0f","left_right_arrow":"\u2194\ufe0f","leftwards_arrow_with_hook":"\u21a9\ufe0f","arrow_right_hook":"\u21aa\ufe0f","arrow_heading_up":"\u2934\ufe0f","arrow_heading_down":"\u2935\ufe0f","arrows_clockwise":"\ud83d\udd03","arrows_counterclockwise":"\ud83d\udd04","back":"\ud83d\udd19","end":"\ud83d\udd1a","on":"\ud83d\udd1b","soon":"\ud83d\udd1c","top":"\ud83d\udd1d","place_of_worship":"\ud83d\uded0","atom_symbol":"\u269b\ufe0f","om":"\ud83d\udd49\ufe0f","star_of_david":"\u2721\ufe0f","wheel_of_dharma":"\u2638\ufe0f","yin_yang":"\u262f\ufe0f","latin_cross":"\u271d\ufe0f","orthodox_cross":"\u2626\ufe0f","star_and_crescent":"\u262a\ufe0f","peace_symbol":"\u262e\ufe0f","menorah":"\ud83d\udd4e","six_pointed_star":"\ud83d\udd2f","aries":"\u2648","taurus":"\u2649","gemini":"\u264a","cancer":"\u264b","leo":"\u264c","virgo":"\u264d","libra":"\u264e","scorpius":"\u264f","sagittarius":"\u2650","capricorn":"\u2651","aquarius":"\u2652","pisces":"\u2653","ophiuchus":"\u26ce","twisted_rightwards_arrows":"\ud83d\udd00","repeat":"\ud83d\udd01","repeat_one":"\ud83d\udd02","arrow_forward":"\u25b6\ufe0f","fast_forward":"\u23e9","next_track_button":"\u23ed\ufe0f","play_or_pause_button":"\u23ef\ufe0f","arrow_backward":"\u25c0\ufe0f","rewind":"\u23ea","previous_track_button":"\u23ee\ufe0f","arrow_up_small":"\ud83d\udd3c","arrow_double_up":"\u23eb","arrow_down_small":"\ud83d\udd3d","arrow_double_down":"\u23ec","pause_button":"\u23f8\ufe0f","stop_button":"\u23f9\ufe0f","record_button":"\u23fa\ufe0f","eject_button":"\u23cf\ufe0f","cinema":"\ud83c\udfa6","low_brightness":"\ud83d\udd05","high_brightness":"\ud83d\udd06","signal_strength":"\ud83d\udcf6","vibration_mode":"\ud83d\udcf3","mobile_phone_off":"\ud83d\udcf4","female_sign":"\u2640\ufe0f","male_sign":"\u2642\ufe0f","transgender_symbol":"\u26a7\ufe0f","heavy_multiplication_x":"\u2716\ufe0f","heavy_plus_sign":"\u2795","heavy_minus_sign":"\u2796","heavy_division_sign":"\u2797","infinity":"\u267e\ufe0f","bangbang":"\u203c\ufe0f","interrobang":"\u2049\ufe0f","question":"\u2753","grey_question":"\u2754","grey_exclamation":"\u2755","exclamation":"\u2757","heavy_exclamation_mark":"\u2757","wavy_dash":"\u3030\ufe0f","currency_exchange":"\ud83d\udcb1","heavy_dollar_sign":"\ud83d\udcb2","medical_symbol":"\u2695\ufe0f","recycle":"\u267b\ufe0f","fleur_de_lis":"\u269c\ufe0f","trident":"\ud83d\udd31","name_badge":"\ud83d\udcdb","beginner":"\ud83d\udd30","o":"\u2b55","white_check_mark":"\u2705","ballot_box_with_check":"\u2611\ufe0f","heavy_check_mark":"\u2714\ufe0f","x":"\u274c","negative_squared_cross_mark":"\u274e","curly_loop":"\u27b0","loop":"\u27bf","part_alternation_mark":"\u303d\ufe0f","eight_spoked_asterisk":"\u2733\ufe0f","eight_pointed_black_star":"\u2734\ufe0f","sparkle":"\u2747\ufe0f","copyright":"\xa9\ufe0f","registered":"\xae\ufe0f","tm":"\u2122\ufe0f","hash":"#\ufe0f\u20e3","asterisk":"*\ufe0f\u20e3","zero":"0\ufe0f\u20e3","one":"1\ufe0f\u20e3","two":"2\ufe0f\u20e3","three":"3\ufe0f\u20e3","four":"4\ufe0f\u20e3","five":"5\ufe0f\u20e3","six":"6\ufe0f\u20e3","seven":"7\ufe0f\u20e3","eight":"8\ufe0f\u20e3","nine":"9\ufe0f\u20e3","keycap_ten":"\ud83d\udd1f","capital_abcd":"\ud83d\udd20","abcd":"\ud83d\udd21","symbols":"\ud83d\udd23","abc":"\ud83d\udd24","a":"\ud83c\udd70\ufe0f","ab":"\ud83c\udd8e","b":"\ud83c\udd71\ufe0f","cl":"\ud83c\udd91","cool":"\ud83c\udd92","free":"\ud83c\udd93","information_source":"\u2139\ufe0f","id":"\ud83c\udd94","m":"\u24c2\ufe0f","new":"\ud83c\udd95","ng":"\ud83c\udd96","o2":"\ud83c\udd7e\ufe0f","ok":"\ud83c\udd97","parking":"\ud83c\udd7f\ufe0f","sos":"\ud83c\udd98","up":"\ud83c\udd99","vs":"\ud83c\udd9a","koko":"\ud83c\ude01","sa":"\ud83c\ude02\ufe0f","ideograph_advantage":"\ud83c\ude50","accept":"\ud83c\ude51","congratulations":"\u3297\ufe0f","secret":"\u3299\ufe0f","u6e80":"\ud83c\ude35","red_circle":"\ud83d\udd34","orange_circle":"\ud83d\udfe0","yellow_circle":"\ud83d\udfe1","green_circle":"\ud83d\udfe2","large_blue_circle":"\ud83d\udd35","purple_circle":"\ud83d\udfe3","brown_circle":"\ud83d\udfe4","black_circle":"\u26ab","white_circle":"\u26aa","red_square":"\ud83d\udfe5","orange_square":"\ud83d\udfe7","yellow_square":"\ud83d\udfe8","green_square":"\ud83d\udfe9","blue_square":"\ud83d\udfe6","purple_square":"\ud83d\udfea","brown_square":"\ud83d\udfeb","black_large_square":"\u2b1b","white_large_square":"\u2b1c","black_medium_square":"\u25fc\ufe0f","white_medium_square":"\u25fb\ufe0f","black_medium_small_square":"\u25fe","white_medium_small_square":"\u25fd","black_small_square":"\u25aa\ufe0f","white_small_square":"\u25ab\ufe0f","large_orange_diamond":"\ud83d\udd36","large_blue_diamond":"\ud83d\udd37","small_orange_diamond":"\ud83d\udd38","small_blue_diamond":"\ud83d\udd39","small_red_triangle":"\ud83d\udd3a","small_red_triangle_down":"\ud83d\udd3b","diamond_shape_with_a_dot_inside":"\ud83d\udca0","radio_button":"\ud83d\udd18","white_square_button":"\ud83d\udd33","black_square_button":"\ud83d\udd32","checkered_flag":"\ud83c\udfc1","triangular_flag_on_post":"\ud83d\udea9","crossed_flags":"\ud83c\udf8c","black_flag":"\ud83c\udff4","white_flag":"\ud83c\udff3\ufe0f","rainbow_flag":"\ud83c\udff3\ufe0f\u200d\ud83c\udf08","transgender_flag":"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","pirate_flag":"\ud83c\udff4\u200d\u2620\ufe0f","ascension_island":"\ud83c\udde6\ud83c\udde8","andorra":"\ud83c\udde6\ud83c\udde9","united_arab_emirates":"\ud83c\udde6\ud83c\uddea","afghanistan":"\ud83c\udde6\ud83c\uddeb","antigua_barbuda":"\ud83c\udde6\ud83c\uddec","anguilla":"\ud83c\udde6\ud83c\uddee","albania":"\ud83c\udde6\ud83c\uddf1","armenia":"\ud83c\udde6\ud83c\uddf2","angola":"\ud83c\udde6\ud83c\uddf4","antarctica":"\ud83c\udde6\ud83c\uddf6","argentina":"\ud83c\udde6\ud83c\uddf7","american_samoa":"\ud83c\udde6\ud83c\uddf8","austria":"\ud83c\udde6\ud83c\uddf9","australia":"\ud83c\udde6\ud83c\uddfa","aruba":"\ud83c\udde6\ud83c\uddfc","aland_islands":"\ud83c\udde6\ud83c\uddfd","azerbaijan":"\ud83c\udde6\ud83c\uddff","bosnia_herzegovina":"\ud83c\udde7\ud83c\udde6","barbados":"\ud83c\udde7\ud83c\udde7","bangladesh":"\ud83c\udde7\ud83c\udde9","belgium":"\ud83c\udde7\ud83c\uddea","burkina_faso":"\ud83c\udde7\ud83c\uddeb","bulgaria":"\ud83c\udde7\ud83c\uddec","bahrain":"\ud83c\udde7\ud83c\udded","burundi":"\ud83c\udde7\ud83c\uddee","benin":"\ud83c\udde7\ud83c\uddef","st_barthelemy":"\ud83c\udde7\ud83c\uddf1","bermuda":"\ud83c\udde7\ud83c\uddf2","brunei":"\ud83c\udde7\ud83c\uddf3","bolivia":"\ud83c\udde7\ud83c\uddf4","caribbean_netherlands":"\ud83c\udde7\ud83c\uddf6","brazil":"\ud83c\udde7\ud83c\uddf7","bahamas":"\ud83c\udde7\ud83c\uddf8","bhutan":"\ud83c\udde7\ud83c\uddf9","bouvet_island":"\ud83c\udde7\ud83c\uddfb","botswana":"\ud83c\udde7\ud83c\uddfc","belarus":"\ud83c\udde7\ud83c\uddfe","belize":"\ud83c\udde7\ud83c\uddff","canada":"\ud83c\udde8\ud83c\udde6","cocos_islands":"\ud83c\udde8\ud83c\udde8","congo_kinshasa":"\ud83c\udde8\ud83c\udde9","central_african_republic":"\ud83c\udde8\ud83c\uddeb","congo_brazzaville":"\ud83c\udde8\ud83c\uddec","switzerland":"\ud83c\udde8\ud83c\udded","cote_divoire":"\ud83c\udde8\ud83c\uddee","cook_islands":"\ud83c\udde8\ud83c\uddf0","chile":"\ud83c\udde8\ud83c\uddf1","cameroon":"\ud83c\udde8\ud83c\uddf2","cn":"\ud83c\udde8\ud83c\uddf3","colombia":"\ud83c\udde8\ud83c\uddf4","clipperton_island":"\ud83c\udde8\ud83c\uddf5","costa_rica":"\ud83c\udde8\ud83c\uddf7","cuba":"\ud83c\udde8\ud83c\uddfa","cape_verde":"\ud83c\udde8\ud83c\uddfb","curacao":"\ud83c\udde8\ud83c\uddfc","christmas_island":"\ud83c\udde8\ud83c\uddfd","cyprus":"\ud83c\udde8\ud83c\uddfe","czech_republic":"\ud83c\udde8\ud83c\uddff","de":"\ud83c\udde9\ud83c\uddea","diego_garcia":"\ud83c\udde9\ud83c\uddec","djibouti":"\ud83c\udde9\ud83c\uddef","denmark":"\ud83c\udde9\ud83c\uddf0","dominica":"\ud83c\udde9\ud83c\uddf2","dominican_republic":"\ud83c\udde9\ud83c\uddf4","algeria":"\ud83c\udde9\ud83c\uddff","ceuta_melilla":"\ud83c\uddea\ud83c\udde6","ecuador":"\ud83c\uddea\ud83c\udde8","estonia":"\ud83c\uddea\ud83c\uddea","egypt":"\ud83c\uddea\ud83c\uddec","western_sahara":"\ud83c\uddea\ud83c\udded","eritrea":"\ud83c\uddea\ud83c\uddf7","es":"\ud83c\uddea\ud83c\uddf8","ethiopia":"\ud83c\uddea\ud83c\uddf9","eu":"\ud83c\uddea\ud83c\uddfa","european_union":"\ud83c\uddea\ud83c\uddfa","finland":"\ud83c\uddeb\ud83c\uddee","fiji":"\ud83c\uddeb\ud83c\uddef","falkland_islands":"\ud83c\uddeb\ud83c\uddf0","micronesia":"\ud83c\uddeb\ud83c\uddf2","faroe_islands":"\ud83c\uddeb\ud83c\uddf4","fr":"\ud83c\uddeb\ud83c\uddf7","gabon":"\ud83c\uddec\ud83c\udde6","gb":"\ud83c\uddec\ud83c\udde7","uk":"\ud83c\uddec\ud83c\udde7","grenada":"\ud83c\uddec\ud83c\udde9","georgia":"\ud83c\uddec\ud83c\uddea","french_guiana":"\ud83c\uddec\ud83c\uddeb","guernsey":"\ud83c\uddec\ud83c\uddec","ghana":"\ud83c\uddec\ud83c\udded","gibraltar":"\ud83c\uddec\ud83c\uddee","greenland":"\ud83c\uddec\ud83c\uddf1","gambia":"\ud83c\uddec\ud83c\uddf2","guinea":"\ud83c\uddec\ud83c\uddf3","guadeloupe":"\ud83c\uddec\ud83c\uddf5","equatorial_guinea":"\ud83c\uddec\ud83c\uddf6","greece":"\ud83c\uddec\ud83c\uddf7","south_georgia_south_sandwich_islands":"\ud83c\uddec\ud83c\uddf8","guatemala":"\ud83c\uddec\ud83c\uddf9","guam":"\ud83c\uddec\ud83c\uddfa","guinea_bissau":"\ud83c\uddec\ud83c\uddfc","guyana":"\ud83c\uddec\ud83c\uddfe","hong_kong":"\ud83c\udded\ud83c\uddf0","heard_mcdonald_islands":"\ud83c\udded\ud83c\uddf2","honduras":"\ud83c\udded\ud83c\uddf3","croatia":"\ud83c\udded\ud83c\uddf7","haiti":"\ud83c\udded\ud83c\uddf9","hungary":"\ud83c\udded\ud83c\uddfa","canary_islands":"\ud83c\uddee\ud83c\udde8","indonesia":"\ud83c\uddee\ud83c\udde9","ireland":"\ud83c\uddee\ud83c\uddea","israel":"\ud83c\uddee\ud83c\uddf1","isle_of_man":"\ud83c\uddee\ud83c\uddf2","india":"\ud83c\uddee\ud83c\uddf3","british_indian_ocean_territory":"\ud83c\uddee\ud83c\uddf4","iraq":"\ud83c\uddee\ud83c\uddf6","iran":"\ud83c\uddee\ud83c\uddf7","iceland":"\ud83c\uddee\ud83c\uddf8","it":"\ud83c\uddee\ud83c\uddf9","jersey":"\ud83c\uddef\ud83c\uddea","jamaica":"\ud83c\uddef\ud83c\uddf2","jordan":"\ud83c\uddef\ud83c\uddf4","jp":"\ud83c\uddef\ud83c\uddf5","kenya":"\ud83c\uddf0\ud83c\uddea","kyrgyzstan":"\ud83c\uddf0\ud83c\uddec","cambodia":"\ud83c\uddf0\ud83c\udded","kiribati":"\ud83c\uddf0\ud83c\uddee","comoros":"\ud83c\uddf0\ud83c\uddf2","st_kitts_nevis":"\ud83c\uddf0\ud83c\uddf3","north_korea":"\ud83c\uddf0\ud83c\uddf5","kr":"\ud83c\uddf0\ud83c\uddf7","kuwait":"\ud83c\uddf0\ud83c\uddfc","cayman_islands":"\ud83c\uddf0\ud83c\uddfe","kazakhstan":"\ud83c\uddf0\ud83c\uddff","laos":"\ud83c\uddf1\ud83c\udde6","lebanon":"\ud83c\uddf1\ud83c\udde7","st_lucia":"\ud83c\uddf1\ud83c\udde8","liechtenstein":"\ud83c\uddf1\ud83c\uddee","sri_lanka":"\ud83c\uddf1\ud83c\uddf0","liberia":"\ud83c\uddf1\ud83c\uddf7","lesotho":"\ud83c\uddf1\ud83c\uddf8","lithuania":"\ud83c\uddf1\ud83c\uddf9","luxembourg":"\ud83c\uddf1\ud83c\uddfa","latvia":"\ud83c\uddf1\ud83c\uddfb","libya":"\ud83c\uddf1\ud83c\uddfe","morocco":"\ud83c\uddf2\ud83c\udde6","monaco":"\ud83c\uddf2\ud83c\udde8","moldova":"\ud83c\uddf2\ud83c\udde9","montenegro":"\ud83c\uddf2\ud83c\uddea","st_martin":"\ud83c\uddf2\ud83c\uddeb","madagascar":"\ud83c\uddf2\ud83c\uddec","marshall_islands":"\ud83c\uddf2\ud83c\udded","macedonia":"\ud83c\uddf2\ud83c\uddf0","mali":"\ud83c\uddf2\ud83c\uddf1","myanmar":"\ud83c\uddf2\ud83c\uddf2","mongolia":"\ud83c\uddf2\ud83c\uddf3","macau":"\ud83c\uddf2\ud83c\uddf4","northern_mariana_islands":"\ud83c\uddf2\ud83c\uddf5","martinique":"\ud83c\uddf2\ud83c\uddf6","mauritania":"\ud83c\uddf2\ud83c\uddf7","montserrat":"\ud83c\uddf2\ud83c\uddf8","malta":"\ud83c\uddf2\ud83c\uddf9","mauritius":"\ud83c\uddf2\ud83c\uddfa","maldives":"\ud83c\uddf2\ud83c\uddfb","malawi":"\ud83c\uddf2\ud83c\uddfc","mexico":"\ud83c\uddf2\ud83c\uddfd","malaysia":"\ud83c\uddf2\ud83c\uddfe","mozambique":"\ud83c\uddf2\ud83c\uddff","namibia":"\ud83c\uddf3\ud83c\udde6","new_caledonia":"\ud83c\uddf3\ud83c\udde8","niger":"\ud83c\uddf3\ud83c\uddea","norfolk_island":"\ud83c\uddf3\ud83c\uddeb","nigeria":"\ud83c\uddf3\ud83c\uddec","nicaragua":"\ud83c\uddf3\ud83c\uddee","netherlands":"\ud83c\uddf3\ud83c\uddf1","norway":"\ud83c\uddf3\ud83c\uddf4","nepal":"\ud83c\uddf3\ud83c\uddf5","nauru":"\ud83c\uddf3\ud83c\uddf7","niue":"\ud83c\uddf3\ud83c\uddfa","new_zealand":"\ud83c\uddf3\ud83c\uddff","oman":"\ud83c\uddf4\ud83c\uddf2","panama":"\ud83c\uddf5\ud83c\udde6","peru":"\ud83c\uddf5\ud83c\uddea","french_polynesia":"\ud83c\uddf5\ud83c\uddeb","papua_new_guinea":"\ud83c\uddf5\ud83c\uddec","philippines":"\ud83c\uddf5\ud83c\udded","pakistan":"\ud83c\uddf5\ud83c\uddf0","poland":"\ud83c\uddf5\ud83c\uddf1","st_pierre_miquelon":"\ud83c\uddf5\ud83c\uddf2","pitcairn_islands":"\ud83c\uddf5\ud83c\uddf3","puerto_rico":"\ud83c\uddf5\ud83c\uddf7","palestinian_territories":"\ud83c\uddf5\ud83c\uddf8","portugal":"\ud83c\uddf5\ud83c\uddf9","palau":"\ud83c\uddf5\ud83c\uddfc","paraguay":"\ud83c\uddf5\ud83c\uddfe","qatar":"\ud83c\uddf6\ud83c\udde6","reunion":"\ud83c\uddf7\ud83c\uddea","romania":"\ud83c\uddf7\ud83c\uddf4","serbia":"\ud83c\uddf7\ud83c\uddf8","ru":"\ud83c\uddf7\ud83c\uddfa","rwanda":"\ud83c\uddf7\ud83c\uddfc","saudi_arabia":"\ud83c\uddf8\ud83c\udde6","solomon_islands":"\ud83c\uddf8\ud83c\udde7","seychelles":"\ud83c\uddf8\ud83c\udde8","sudan":"\ud83c\uddf8\ud83c\udde9","sweden":"\ud83c\uddf8\ud83c\uddea","singapore":"\ud83c\uddf8\ud83c\uddec","st_helena":"\ud83c\uddf8\ud83c\udded","slovenia":"\ud83c\uddf8\ud83c\uddee","svalbard_jan_mayen":"\ud83c\uddf8\ud83c\uddef","slovakia":"\ud83c\uddf8\ud83c\uddf0","sierra_leone":"\ud83c\uddf8\ud83c\uddf1","san_marino":"\ud83c\uddf8\ud83c\uddf2","senegal":"\ud83c\uddf8\ud83c\uddf3","somalia":"\ud83c\uddf8\ud83c\uddf4","suriname":"\ud83c\uddf8\ud83c\uddf7","south_sudan":"\ud83c\uddf8\ud83c\uddf8","sao_tome_principe":"\ud83c\uddf8\ud83c\uddf9","el_salvador":"\ud83c\uddf8\ud83c\uddfb","sint_maarten":"\ud83c\uddf8\ud83c\uddfd","syria":"\ud83c\uddf8\ud83c\uddfe","swaziland":"\ud83c\uddf8\ud83c\uddff","tristan_da_cunha":"\ud83c\uddf9\ud83c\udde6","turks_caicos_islands":"\ud83c\uddf9\ud83c\udde8","chad":"\ud83c\uddf9\ud83c\udde9","french_southern_territories":"\ud83c\uddf9\ud83c\uddeb","togo":"\ud83c\uddf9\ud83c\uddec","thailand":"\ud83c\uddf9\ud83c\udded","tajikistan":"\ud83c\uddf9\ud83c\uddef","tokelau":"\ud83c\uddf9\ud83c\uddf0","timor_leste":"\ud83c\uddf9\ud83c\uddf1","turkmenistan":"\ud83c\uddf9\ud83c\uddf2","tunisia":"\ud83c\uddf9\ud83c\uddf3","tonga":"\ud83c\uddf9\ud83c\uddf4","tr":"\ud83c\uddf9\ud83c\uddf7","trinidad_tobago":"\ud83c\uddf9\ud83c\uddf9","tuvalu":"\ud83c\uddf9\ud83c\uddfb","taiwan":"\ud83c\uddf9\ud83c\uddfc","tanzania":"\ud83c\uddf9\ud83c\uddff","ukraine":"\ud83c\uddfa\ud83c\udde6","uganda":"\ud83c\uddfa\ud83c\uddec","us_outlying_islands":"\ud83c\uddfa\ud83c\uddf2","united_nations":"\ud83c\uddfa\ud83c\uddf3","us":"\ud83c\uddfa\ud83c\uddf8","uruguay":"\ud83c\uddfa\ud83c\uddfe","uzbekistan":"\ud83c\uddfa\ud83c\uddff","vatican_city":"\ud83c\uddfb\ud83c\udde6","st_vincent_grenadines":"\ud83c\uddfb\ud83c\udde8","venezuela":"\ud83c\uddfb\ud83c\uddea","british_virgin_islands":"\ud83c\uddfb\ud83c\uddec","us_virgin_islands":"\ud83c\uddfb\ud83c\uddee","vietnam":"\ud83c\uddfb\ud83c\uddf3","vanuatu":"\ud83c\uddfb\ud83c\uddfa","wallis_futuna":"\ud83c\uddfc\ud83c\uddeb","samoa":"\ud83c\uddfc\ud83c\uddf8","kosovo":"\ud83c\uddfd\ud83c\uddf0","yemen":"\ud83c\uddfe\ud83c\uddea","mayotte":"\ud83c\uddfe\ud83c\uddf9","south_africa":"\ud83c\uddff\ud83c\udde6","zambia":"\ud83c\uddff\ud83c\uddf2","zimbabwe":"\ud83c\uddff\ud83c\uddfc","england":"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","scotland":"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f","wales":"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f"}')}}]);
//# sourceMappingURL=394.14a9b9da.chunk.js.map
================================================
FILE: build/static/js/bindle-edges-json.94501736.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[691],{8866:function(e){e.exports=JSON.parse('[{"source":"users","sourceKey":"id","target":"purchases","targetKey":"user_id","relation":"hasMany"},{"source":"users","sourceKey":"id","target":"books_users","targetKey":"user_id","relation":"hasMany"},{"source":"products","sourceKey":"id","target":"purchases","targetKey":"product_id","relation":"hasMany"},{"source":"books","sourceKey":"id","target":"books_users","targetKey":"book_id","relation":"hasMany"},{"source":"users","sourceKey":"id","target":"profiles","targetKey":"user_id","relation":"hasOne"},{"source":"users","sourceKey":"id","target":"accounts","targetKey":"user_id","relation":"hasOne"},{"source":"users","sourceKey":"id","target":"devices","targetKey":"user_id","relation":"hasMany"},{"source":"users","sourceKey":"id","target":"adjust.callbacks","targetKey":"user_id","relation":"hasMany"},{"source":"users","sourceKey":"visitor_id","target":"web_analytics.pageviews","targetKey":"visitor_id","relation":"hasMany"},{"source":"web_analytics.pageviews","sourceKey":"pageview_id","target":"web_analytics.events","targetKey":"pageview_id","relation":"hasMany"},{"source":"users","sourceKey":"id","target":"mobile_analytics.events","targetKey":"user_id","relation":"hasMany"},{"source":"users","sourceKey":"id","target":"users","targetKey":"referrer_id","relation":"hasMany","sourcePosition":"left","targetPosition":"left"}]')}}]);
================================================
FILE: build/static/js/bindle-schemaColors-json.b87e5760.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[480],{1737:function(s){s.exports=JSON.parse('{"DEFAULT":"#91C4F2","public":"#BEB8EB","adjust":"#AFA2FF","helpers":"#75C9C8","web_analytics":"#F6BDD1","mobile_analytics":"#FFD791"}')}}]);
================================================
FILE: build/static/js/bindle-tablePositions-json.847db583.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[356],{3366:function(s){s.exports=JSON.parse('{"adjust.callbacks":{"x":864,"y":-192},"helpers.dates":{"x":512,"y":528},"mobile_analytics.events":{"x":656,"y":-336},"public.accounts":{"x":-240,"y":-192},"public.books":{"x":-432,"y":320},"public.books_users":{"x":-208,"y":224},"public.devices":{"x":-48,"y":-336},"public.marketing_spends":{"x":672,"y":528},"public.products":{"x":704,"y":304},"public.profiles":{"x":-384,"y":-16},"public.purchases":{"x":432,"y":192},"public.users":{"x":192,"y":-96},"web_analytics.events":{"x":-368,"y":624},"web_analytics.pageviews":{"x":-96,"y":544}}')}}]);
================================================
FILE: build/static/js/bindle-tables.0d2bfe46.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[112],{2905:function(e,t,i){i.r(t),i.d(t,{default:function(){return a}});var a=[JSON.parse('{"name":"accounts","description":"Accounts of platforms users can sign up with. Bindle users might have Facebook or Email accounts.","columns":[{"name":"id","description":"Unique identifier of an account.","key":true,"type":"integer"},{"name":"user_id","description":"User\u2019s id.","type":"integer"},{"name":"platform","description":"Account\u2019s platform. Bindle allows email and facebook signups.","type":"text"},{"name":"email","description":"Email attached to the account. Note that different platforms could have different emails.","type":"text"},{"name":"created_at","description":"Timestamp when this account was created. created_at of the first account is user\u2019s signup timestamp.","type":"datetime"}]}'),JSON.parse('{"schema":"adjust","name":"callbacks","description":"Adjust is a mobile attribution service, sort of Google Analytics for the mobile world. Adjust sends back callbacks with information (attribution) about every mobile install, like where this install comes from, which link a person clicked before installing the app.","columns":[{"name":"id","description":"Unique ID of an Adjust callback.","type":"integer","key":true},{"name":"tracker","description":"Adjust\u2019s tracker parameter. For example https://app.adjust.com/gxel3d1.","type":"text"},{"name":"created_at","description":"Timestamp of a callback.","type":"datetime"},{"name":"campaign_name","description":"The value of campaign paramenter in Adjust URL.","type":"text"},{"name":"adgroup_name","description":"The value of adgroup paramenter in Adjust URL.","type":"text"},{"name":"creative_name","description":"The value of creative paramenter in Adjust URL.","type":"text"},{"name":"label","description":"The value of label paramenter in Adjust URL.","type":"text"},{"name":"device_name","description":"Model and OS version of a user\u2019s device.","type":"text"},{"name":"app_version","description":"Bindle\u2019s app version at the moment.","type":"text"},{"name":"activity_kind","description":"Predefined Adjust event, could be click, install, event (means custom event and event_name will be present) or else.","type":"text"},{"name":"event_name","description":"Custom Adjust event; Bindle has custom signup event.","type":"text"},{"name":"adid","description":"Adjust\u2019s device ID.","type":"text"},{"name":"user_id","description":"ID of a user (from users table). Present for signup event.","type":"integer"},{"name":"country","description":"Country derived from user\u2019s IP address.","type":"text"}]}'),JSON.parse('{"name":"books_users","description":"A join table for many-to-many relationship between users and books.","columns":[{"name":"book_id","description":"Book\u2019s id.","type":"integer"},{"name":"user_id","description":"User\u2019s id.","type":"integer"},{"name":"last_page","description":"A number of the last page a user read in the book.","type":"integer"},{"name":"created_at","description":"When the user started reading the book.","type":"datetime"}]}'),JSON.parse('{"name":"books","description":"All books available in the Bindle\'s library.","columns":[{"name":"id","description":"Unique identifier of the book.","key":true,"type":"integer"},{"name":"name","description":"Name of the book.","type":"text"},{"name":"slug","description":"Identifer of a book used in URLs. For example https://www.bindle.com/books/final-future. Usually generated from book\u2019s name.","type":"text"},{"name":"genre","description":"Book\u2019s genre.","type":"text"},{"name":"pages_count","description":"Number of pages in the book.","type":"integer"}]}'),JSON.parse('{"name":"devices","description":"This table keeps track of all devices users log in to Bindle with \u2013 browsers or mobile apps.","columns":[{"name":"id","description":"Unique identifier of a user\u2019s device.","key":true,"type":"integer"},{"name":"user_id","description":"id of a user who uses this device.","type":"integer"},{"name":"device_type","description":"Type of the device, could be **browser** (for users who are using Bindle website) or **iphone** (users who are reading via Bindle app).","type":"text"},{"name":"connected_at","description":"Timestamp when a user started using this device. Device with the earliest **connected_at** field is the device which user used for signing up.","type":"datetime"},{"name":"version","description":"For browser devices it\u2019s a User Agent. For iPhone devices it\u2019s a version of user\u2019s iPhone and a version of iOS separated by comma.","type":"text"}]}'),JSON.parse('{"schema":"helpers","name":"dates","description":"A helper table with consecutive dates. Might be useful to join sparse timelines to for reporting metrics per day.","columns":[{"name":"id","description":"Unique identifier of a date. Just a primary key, an index of the table.","key":true,"type":"integer"},{"name":"date","description":"A date. By joining the very sparse timeline data to the consecutive range of dates we won\u2019t have gaps.","type":"date"}]}'),JSON.parse('{"name":"marketing_spends","description":"A table that keeps track of Bindle\'s marketing investments per campaign, per day.","columns":[{"name":"id","description":"Unique identifier of spend, just a primary key in a table.","key":true,"type":"integer"},{"name":"spent_at","description":"The date of a spend. Spend data is usually reported by date.","type":"date"},{"name":"amount","description":"Amount of money in USD.","type":"integer"},{"name":"clicks","description":"Number of clicks on the ad on this date.","type":"integer"},{"name":"utm_source","description":"utm_source of marketing campaign.","type":"text"},{"name":"utm_campaign","description":"utm_campaign of marketing campaign.","type":"text"},{"name":"utm_term","description":"utm_term of marketing campaign.","type":"text"},{"name":"utm_content","description":"utm_content of marketing campaign.","type":"text"},{"name":"utm_medium","description":"utm_medium of marketing campaign.","type":"text"}]}'),JSON.parse('{"schema":"mobile_analytics","name":"events","description":"This analytics table contains all events fired by Bindle\'s mobile app.","columns":[{"name":"event_id","description":"Unique identifier of an event.","type":"text","key":true},{"name":"category","description":"Category parameter of an event, for example onboarding.","type":"text"},{"name":"action","description":"Action parameter of an event, for example screenview.","type":"text"},{"name":"name","description":"Name parameter of an event, for example bindle-content.","type":"text"},{"name":"screen_resolution","description":"Resolution of a user\u2019s smartphone, for example 375x812.","type":"text"},{"name":"device_type","description":"Model of a user\u2019s smartphone and the version of the OS, for example iPhone 7,12.1.0.","type":"text"},{"name":"user_id","description":"If user is logged in \u2013 ID of a user in the users table.","type":"integer"},{"name":"adid","description":"Unique identifier of a user\u2019s smartphone, same as in Adjust callbacks table.","type":"text"},{"name":"country","description":"Country derived from user\u2019s IP address.","type":"text"},{"name":"custom_parameters","description":"All custom parameters of an even in a key-value format.","type":"JSON"},{"name":"created_at","description":"Timestamp of an event.","type":"datetime"},{"name":"app_version","description":"Version of the Bindle app a user is using, for example 1.1.1.","type":"text"}]}'),JSON.parse('{"name":"products","description":"The list of all purchasable Bindle products (subscriptions).","columns":[{"name":"id","description":"Unique identifier of a product.","key":true,"type":"integer"},{"name":"name","description":"Name of a product.","type":"text"},{"name":"price","description":"Price of a product","type":"float"}]}'),JSON.parse('{"name":"profiles","description":"To avoid growing the users table further, users\' profile information was extracted to this table.","columns":[{"name":"id","key":true,"type":"number","description":"Unique identifier of a profile."},{"name":"user_id","type":"number","description":"User\u2019s id."},{"name":"about","type":"text","description":"Information about a user."},{"name":"interests","type":"text","description":"User\u2019s interests. Comma separated list of tags."},{"name":"avatar_url","type":"text","description":"URL of an avatar user uploaded. Check some of them out ;)"},{"name":"postal_code","type":"text","description":"A postal code of a user for books delivery."}]}'),JSON.parse('{"name":"purchases","description":"This table contains all purchase transactions.","columns":[{"name":"id","description":"Unique identifier of purchase.","type":"integer","key":true},{"name":"user_id","description":"id of a user who made the purchase.","type":"integer"},{"name":"product_id","description":"id of a product inside products table.","type":"integer"},{"name":"amount","description":"How much money user paid. The number might vary since users could apply discounts. Amount is always in US dollars.","type":"float"},{"name":"refunded","description":"Status of a purchase, we receive money on the bank account only if purchase wasn\u2019t refunded.","type":"boolean"},{"name":"created_at","description":"When purchase was made.","type":"datetime"}]}'),JSON.parse('{"name":"users","description":"This table contains all user records of Bindle.","columns":[{"name":"id","key":true,"description":"Unique identifier of a user.","type":"number"},{"name":"email","type":"text","description":"User\u2019s email, unique."},{"name":"first_name","type":"text","description":"User\u2019s first name."},{"name":"last_name","type":"text","description":"User\u2019s last name."},{"name":"country","type":"text","description":"User\u2019s signup country."},{"name":"signup_date","type":"date","description":"Date when user signed up."},{"name":"created_at","type":"datetime","description":"Timestamp when user record was created, we can treat it as signup date and time."},{"name":"status","type":"text","description":"What status user has in Bindle, could be free (can read only free books) or customer (user who purchased a subscription, can read all books)."},{"name":"age","type":"integer","description":"User\u2019s age."},{"name":"referrer_id","type":"integer","description":"id of another user who referred this user (this is usually set when users sign up via referral link)."},{"name":"visitor_id","type":"text","description":"Identifier of a user in the web_analytics.pageviews table. Generated by a web analytics system and stored in a cookie."},{"name":"utm_source","type":"text","description":"utm_source in URL when user signed up, used for marketing attribution"},{"name":"utm_campaign","type":"text","description":"utm_campaign in URL when user signed up, used for marketing attribution"},{"name":"utm_term","type":"text","description":"utm_term in URL when user signed up, used for marketing attribution"},{"name":"utm_content","type":"text","description":"utm_content in URL when user signed up, used for marketing attribution"},{"name":"utm_medium","type":"text","description":"utm_medium in URL when user signed up, used for marketing attribution"},{"name":"adjust_tracker","type":"text","description":"Adjust tracker in case user signed up via an Adjust link https://app.adjust.com/gxel3d1."},{"name":"adjust_campaign","type":"text","description":"The value of campaign paramenter in Adjust URL."},{"name":"adjust_adgroup","type":"text","description":"The value of adgroup paramenter in Adjust URL."},{"name":"adjust_creative","type":"text","description":"The value of creative paramenter in Adjust URL."}]}'),JSON.parse('{"schema":"web_analytics","name":"events","description":"This table contains all events that happen on Bindle\'s website pages. Events are tracked during a pageview, that\'s why there\'s a has-many relation between pageviews and events.","columns":[{"name":"pageview_id","description":"Category parameter of an event, for example Signup.","type":"text"},{"name":"category","description":"Action parameter of an event, for example Click.","type":"text"},{"name":"action","description":"Name parameter of an event, for example Signup for free.","type":"text"},{"name":"name","description":"Unique identifier of a record inside pageviews table. All events happen within one pageview. \u26a0\ufe0f","type":"text"},{"name":"created_at","description":"Timestamp of an event.","type":"datetime"}]}'),JSON.parse('{"schema":"web_analytics","name":"pageviews","description":"This table contains all pageviews of Bindle\'s website.","columns":[{"name":"pageview_id","description":"Unique identifier of a pageview.","type":"text","key":true},{"name":"visitor_id","description":"Unique identifier of a visitor. A fingerprint used to keep track of guest visitors who haven\u2019t had signed up.","type":"text"},{"name":"user_id","description":"If user is logged in \u2013 ID of a user in users table.","type":"integer"},{"name":"url","description":"URL of the visited page.","type":"text"},{"name":"referer_url","description":"URL of the previous page where user clicked on a link with URL.","type":"text"},{"name":"screen_resolution","description":"Screen resolution of a user\u2019s device. Example: 1024x1366.","type":"text"},{"name":"device_type","description":"Type of a user\u2019s device. Could be mobile, tablet or desktop.","type":"text"},{"name":"custom_parameters","description":"All custom parameters of a pageview in a key-value format. Could be added per page, for example we might add ab_test_variation key to keep track of what AB-test variation user had seen.","type":"JSON"},{"name":"created_at","description":"Timestamp of a pageview.","type":"datetime"},{"name":"country","description":"Country derived from user\u2019s IP address.","type":"text"}]}')]}}]);
//# sourceMappingURL=bindle-tables.0d2bfe46.chunk.js.map
================================================
FILE: build/static/js/ecommerce-edges-json.fe131063.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[547],{5336:function(e){e.exports=JSON.parse('[{"source":"vendors","sourceKey":"id","target":"items","targetKey":"vendor_id","relation":"hasMany"},{"source":"categories","sourceKey":"id","target":"items","targetKey":"category_id","relation":"hasMany"},{"source":"items","sourceKey":"id","target":"reviews","targetKey":"item_id","relation":"hasMany"},{"source":"users","sourceKey":"id","target":"reviews","targetKey":"user_id","relation":"hasMany"},{"source":"items","sourceKey":"id","target":"carts_items","targetKey":"item_id","relation":"hasMany"},{"source":"carts","sourceKey":"id","target":"carts_items","targetKey":"cart_id","relation":"hasMany"},{"source":"users","sourceKey":"id","target":"carts","targetKey":"user_id","relation":"hasMany"},{"source":"carts","sourceKey":"id","target":"returns","targetKey":"cart_id","relation":"hasMany"},{"source":"items","sourceKey":"id","target":"returns","targetKey":"item_id","relation":"hasMany"},{"source":"carts","sourceKey":"id","target":"purchases","targetKey":"cart_id","relation":"hasOne"},{"source":"discount_codes","sourceKey":"code","target":"purchases","targetKey":"discount_code","relation":"hasMany"}]')}}]);
================================================
FILE: build/static/js/ecommerce-schemaColors-json.fdb98809.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[415],{1090:function(s){s.exports=JSON.parse('{"DEFAULT":"#91C4F2","public":"#91C4F2"}')}}]);
================================================
FILE: build/static/js/ecommerce-tablePositions-json.03a16298.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[743],{9543:function(s){s.exports=JSON.parse('{"public.carts":{"x":672,"y":368},"public.carts_items":{"x":464,"y":560},"public.categories":{"x":-160,"y":496},"public.discount_codes":{"x":1136,"y":336},"public.items":{"x":112,"y":608},"public.purchases":{"x":896,"y":160},"public.returns":{"x":400,"y":288},"public.reviews":{"x":400,"y":800},"public.users":{"x":688,"y":720},"public.vendors":{"x":-160,"y":848}}')}}]);
================================================
FILE: build/static/js/ecommerce-tables.f5264437.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[679],{4213:function(e,t,a){a.r(t),a.d(t,{default:function(){return i}});var i=[JSON.parse('{"name":"carts","description":"This table contains all carts (purchased or not) that were ever assembled by users.","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a cart.","type":"bigint"},{"name":"user_id","description":"ID of a user who assemled a cart.","type":"bigint"},{"name":"created_at","description":"When a cart was created (when a user added the first item to a cart).","type":"timestamp"}]}'),JSON.parse('{"name":"carts_items","description":"This is a join table that enables many-to-many relation between carts and items.","schemaColor":"#91C4F2","columns":[{"name":"item_id","description":"ID of an item that was added to a cart.","type":"bigint"},{"name":"cart_id","description":"Cart\'s ID.","type":"bigint"},{"name":"created_at","description":"When an item was added to a cart.","type":"timestamp"},{"name":"quantity","description":"How many identical items are in a cart.","type":"integer"}]}'),JSON.parse('{"name":"categories","description":"This table contains item categories. Note that cateories are nested and a category could have multiple children categories.","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of an item category.","type":"bigint"},{"name":"name","description":"Category name, like \\"Sport shoes\\".","type":"text"},{"name":"parent_id","description":"ID of a parent category. Yep, categories have nested structure. For example, \\"books\\" category have \\"fiction\\" and \\"non-fiction\\" categories. \\"Fiction\\" category has categories like \\"History\\", \\"Detective\\", etc.","type":"bigint"},{"name":"created_at","description":"When a category was added.","type":"timestamp"}]}'),JSON.parse('{"name":"discount_codes","description":"Thsi table contains all discount codes that could be redeemed by a user when making a purchase. Note that discount codes could save a fixed amount or a percentage of the final price.","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a discount code.","type":"bigint"},{"name":"amount_off","description":"Amount in USD that will be subtracted from a total cart\'s price if a user redeems this discount code.","type":"bigint"},{"name":"percent_off","description":"Percentage of a total cart\'s price that will be removed if a user redeems this discount code.","type":"bigint"},{"name":"code","description":"Unique code of a discount code. Codes are shared with customers, not ID-s :warning:.","type":"text"},{"name":"created_at","description":"When discount code was created.","type":"timestamp"},{"name":"valid_until","description":"The latest timestamp when customers are able to redeem a discount code.","type":"timestamp"}]}'),JSON.parse('{"name":"items","description":"This table contains all items that could be purchased by users. Note that only published items are available to website visitors (have value in the `published_at` column).","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of an item.","type":"bigint"},{"name":"name","description":"Item\'s name.","type":"text"},{"name":"category_id","description":"ID of item\'s category.","type":"bigint"},{"name":"vendor_id","description":"ID of a vendor who produces or sells this item in our E-commerce store.","type":"bigint"},{"name":"price_usd","description":"Item\'s price in USD.","type":"numeric"},{"name":"created_at","description":"Timestamp when an item was first added to our E-commerce store.","type":"timestamp"},{"name":"published_at","description":"Timestamp when an item was first available for purchasing.","type":"timestamp"}]}'),JSON.parse('{"name":"purchases","description":"This table contains all cart purchases.","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a return.","type":"bigint"},{"name":"discount_code","description":"Discount code that was used by a user. It\'s a foreign key for the `discount_codes` table.","type":"text"},{"name":"country","description":"Country of a user who made a purchase (IP based).","type":"text"},{"name":"city","description":"City of a user who made a purchase (IP based).","type":"text"},{"name":"payment_method","description":"Payment method that was used for a purchase. Could be **cc** (credit card) or **paypal**.","type":"text"},{"name":"created_at","description":"Timestamp of a purchase.","type":"timestamp"},{"name":"cart_id","description":"ID of a cart that was purchased.","type":"bigint"}]}'),JSON.parse('{"name":"returns","description":"This table contains all returns (full carts or partial item returns).","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a return.","type":"bigint"},{"name":"cart_id","description":"ID of a cart that a retuned item belongs to. In our E-commerce store users add items to a cart, then purchase the whole cart. Users are allowed to return as many items from a purchased cart as they want.","type":"bigint"},{"name":"item_id","description":"ID of an item that was returned.","type":"bigint"},{"name":"quantity","description":"How many items were returned.","type":"integer"},{"name":"created_at","description":"Timestamp when a return was processed.","type":"timestamp"}]}'),JSON.parse('{"name":"reviews","description":"This table contains all user reviews for individual items.","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a review.","type":"bigint"},{"name":"item_id","description":"ID of an item that was reviewed.","type":"bigint"},{"name":"user_id","description":"ID of a user who left a review.","type":"bigint"},{"name":"rating","description":"Star rating that a user selected in a review form.","type":"integer"},{"name":"created_at","description":"Timestamp when a user left a review.","type":"timestamp"},{"name":"feedback","description":"Text feedback that a user types in a review form.","type":"text"}]}'),JSON.parse('{"name":"users","description":"This table contains all user records (accounts).","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a user.","type":"bigint"},{"name":"email","description":"User\'s email.","type":"text"},{"name":"first_name","description":"User\'s first name.","type":"text"},{"name":"last_name","description":"User\'s last name.","type":"text"},{"name":"country","description":"User\'s country (IP based).","type":"text"},{"name":"city","description":"User\'s city (IP based).","type":"text"},{"name":"created_at","description":"Timestamp when a user created an account.","type":"timestamp"}]}'),JSON.parse('{"name":"vendors","description":"This table contains all vendors (people or companies that sell items on our E-commerce platform).","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a vendor.","type":"bigint"},{"name":"name","description":"Vendor\'s name (person or company name).","type":"text"},{"name":"created_at","description":"Timestamp when a vendor started working with our E-commerce store.","type":"timestamp"}]}')]}}]);
//# sourceMappingURL=ecommerce-tables.f5264437.chunk.js.map
================================================
FILE: build/static/js/finance-edges-json.cc1c201e.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[575],{5490:function(e){e.exports=JSON.parse('[{"source":"vendors","sourceKey":"id","target":"transactions","targetKey":"vendor_id","relation":"hasMany"}]')}}]);
================================================
FILE: build/static/js/finance-schemaColors-json.e0d3a5af.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[988],{5881:function(s){s.exports=JSON.parse('{"DEFAULT":"#91C4F2","public":"#91C4F2"}')}}]);
================================================
FILE: build/static/js/finance-tablePositions-json.9ab03387.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[342],{514:function(s){s.exports=JSON.parse('{"public.transactions":{"x":192,"y":176},"public.vendors":{"x":-64,"y":240}}')}}]);
================================================
FILE: build/static/js/finance-tables.eac6da84.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[990],{8986:function(e,n,a){a.r(n),a.d(n,{default:function(){return i}});var i=[JSON.parse('{"name":"transactions","description":"This table contains transactions of all vendors.","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a transaction.","type":"bigint"},{"name":"vendor_id","description":"ID of a vendor from the `vendors` table.","type":"bigint"},{"name":"amount_usd","description":"Transaction\'s amount in USD. Positive value indicates a **credit** transaction, negative indicates **debit** transaction.","type":"numeric"},{"name":"created_at","description":"Timestamp of a transaction.","type":"timestamp"}]}'),JSON.parse('{"name":"vendors","description":"This table contains all vendors.","schemaColor":"#91C4F2","columns":[{"name":"id","description":"Unique identifier of a vendor. A vendor can have **credit** transactions with us (pay us money) and **debit** transactions (we pay money to a vendor).","type":"bigint"},{"name":"name","description":"Vendor\'s name (could be a person or a company).","type":"text"}]}')]}}]);
//# sourceMappingURL=finance-tables.eac6da84.chunk.js.map
================================================
FILE: build/static/js/live-edges-json.849f23e8.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[961],{8140:function(e){e.exports=JSON.parse('[{"source":"products","sourceKey":"id","target":"purchases","targetKey":"product_id","relation":"hasMany"},{"source":"users","sourceKey":"id","target":"purchases","targetKey":"user_id","relation":"hasMany"},{"source":"users","sourceKey":"id","target":"trials","targetKey":"user_id","relation":"hasOne"},{"source":"products","sourceKey":"id","target":"trials","targetKey":"product_id","relation":"hasMany"},{"source":"users","sourceKey":"id","target":"users","targetKey":"referrer_id","relation":"hasMany","sourcePosition":"right","targetPosition":"right"},{"source":"users","sourceKey":"id","target":"mobile_analytics.events","targetKey":"user_id","relation":"hasMany"}]')}}]);
================================================
FILE: build/static/js/live-schemaColors-json.3efe2122.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[418],{8669:function(s){s.exports=JSON.parse('{"DEFAULT":"#91C4F2","public":"#91C4F2","mobile_analytics":"#FFD791"}')}}]);
================================================
FILE: build/static/js/live-tablePositions-json.88001c8e.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[583],{6431:function(s){s.exports=JSON.parse('{"mobile_analytics.events":{"x":784,"y":-128},"public.products":{"x":0,"y":96},"public.purchases":{"x":256,"y":-128},"public.trials":{"x":256,"y":224},"public.users":{"x":560,"y":80}}')}}]);
================================================
FILE: build/static/js/live-tables.5a699030.chunk.js
================================================
"use strict";(self.webpackChunksql_schema_visualizer=self.webpackChunksql_schema_visualizer||[]).push([[752],{3456:function(e,t,i){i.r(t),i.d(t,{default:function(){return a}});var a=[JSON.parse('{"name":"products","description":"All available products (available via subscriptions or one-time payments) users can buy.","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a product.","type":"bigint"},{"name":"name","description":"Product\'s name.","type":"text"},{"name":"price","description":"Product\'s price in USD.","type":"numeric"},{"name":"trial_days","description":"T[he number of free trial days.","type":"integer"},{"name":"renewal_period","description":"Renewal period of a subscription product: 1 for monthly, 12 for yearly.","type":"integer"}]}'),JSON.parse('{"name":"purchases","description":"This table contains all purchase records.","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a purchase.","type":"bigint"},{"name":"user_id","description":"ID of a user who made this purchase.","type":"bigint"},{"name":"product_id","description":"ID of a purchased product.","type":"bigint"},{"name":"trial_id","description":"ID of an associated trial for a subscription product.","type":"bigint"},{"name":"amount","description":"Amount paid in USD.","type":"numeric"},{"name":"created_at","description":"Timestamp of a purchase.","type":"timestamp"},{"name":"refunded_at","description":"Timestamp of a full refund in case a user asked for it.","type":"timestamp"}]}'),JSON.parse('{"name":"trials","description":"This table contains all started trials (trials are available only for subscription products).","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a trial.","type":"bigint"},{"name":"user_id","description":"ID of a user who started a trial.","type":"bigint"},{"name":"product_id","description":"ID of a subscription product.","type":"bigint"},{"name":"started_at","description":"Timestamp when a user started a trial.","type":"timestamp"},{"name":"cancelled_at","description":"Timestamp when a user cancelled a trial.","type":"timestamp"},{"name":"finished_at","description":"Timestamp when a trial was finished and a purchase was made (user was automatically charged the product\'s price).","type":"timestamp"}]}'),JSON.parse('{"name":"users","description":"This table contains all user records (accounts).","schemaColor":"#91C4F2","columns":[{"name":"id","key":true,"description":"Unique identifier of a user.","type":"bigint"},{"name":"referrer_id","description":"id of another user who invited this user.","type":"bigint"},{"name":"first_name","description":"User\'s first name.","type":"text"},{"name":"last_name","description":"User\'s last name.","type":"text"},{"name":"email","description":"User\'s email.","type":"text"},{"name":"country","description":"User\'s country (IP based).","type":"text"},{"name":"city","description":"User\'s city (IP based).","type":"text"},{"name":"age","description":"User\'s age.","type":"integer"},{"name":"timezone","description":"User\'s timezone. Don\'t forget that all timestamps are in UTC.","type":"text"},{"name":"utc_offset","description":"User\'s timezone offset from UTC.","type":"integer"},{"name":"created_at","description":"Timestamp when a user created an account.","type":"timestamp"}]}'),JSON.parse('{"schema":"mobile_analytics","name":"events","description":"This analytics table contains all events tracked in the Meditation iOS app.","columns":[{"name":"id","description":"Unique identifier of an event.","type":"bigint","key":true},{"name":"category","description":"Category parameter of an event, for example onboarding.","type":"text"},{"name":"action","description":"Action parameter of an event, for example screenview.","type":"text"},{"name":"name","description":"Name parameter of an event, for example bindle-content.","type":"text"},{"name":"screen_resolution","description":"Resolution of a user\u2019s smartphone, for example 375x812.","type":"text"},{"name":"device_type","description":"Model of a user\u2019s smartphone and the version of the OS, for example iPhone 15 Pro,17.0","type":"text"},{"name":"user_id","description":"ID of a user in the users table.","type":"integer"},{"name":"country","description":"Country derived from user\u2019s IP address.","type":"text"},{"name":"custom_parameters","description":"All custom parameters of an even in a key-value format.","type":"JSON"},{"name":"created_at","description":"Timestamp of an event.","type":"datetime"}]}')]}}]);
//# sourceMappingURL=live-tables.5a699030.chunk.js.map
================================================
FILE: build/static/js/main.33dfc6b0.js
================================================
/*! For license information please see main.33dfc6b0.js.LICENSE.txt */
!function(){var e={6927:function(e,t,n){"use strict";function r(e){var t=Array.prototype.slice.call(arguments,1);return t.forEach((function(t){t&&Object.keys(t).forEach((function(n){e[n]=t[n]}))})),e}function o(e){return Object.prototype.toString.call(e)}function i(e){return"[object Function]"===o(e)}function a(e){return e.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}var l={fuzzyLink:!0,fuzzyEmail:!0,fuzzyIP:!1};var s={"http:":{validate:function(e,t,n){var r=e.slice(t);return n.re.http||(n.re.http=new RegExp("^\\/\\/"+n.re.src_auth+n.re.src_host_port_strict+n.re.src_path,"i")),n.re.http.test(r)?r.match(n.re.http)[0].length:0}},"https:":"http:","ftp:":"http:","//":{validate:function(e,t,n){var r=e.slice(t);return n.re.no_http||(n.re.no_http=new RegExp("^"+n.re.src_auth+"(?:localhost|(?:(?:"+n.re.src_domain+")\\.)+"+n.re.src_domain_root+")"+n.re.src_port+n.re.src_host_terminator+n.re.src_path,"i")),n.re.no_http.test(r)?t>=3&&":"===e[t-3]||t>=3&&"/"===e[t-3]?0:r.match(n.re.no_http)[0].length:0}},"mailto:":{validate:function(e,t,n){var r=e.slice(t);return n.re.mailto||(n.re.mailto=new RegExp("^"+n.re.src_email_name+"@"+n.re.src_host_strict,"i")),n.re.mailto.test(r)?r.match(n.re.mailto)[0].length:0}}},u="biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|\u0440\u0444".split("|");function c(e){var t=e.re=n(1875)(e.__opts__),r=e.__tlds__.slice();function l(e){return e.replace("%TLDS%",t.src_tlds)}e.onCompile(),e.__tlds_replaced__||r.push("a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]"),r.push(t.src_xn),t.src_tlds=r.join("|"),t.email_fuzzy=RegExp(l(t.tpl_email_fuzzy),"i"),t.link_fuzzy=RegExp(l(t.tpl_link_fuzzy),"i"),t.link_no_ip_fuzzy=RegExp(l(t.tpl_link_no_ip_fuzzy),"i"),t.host_fuzzy_test=RegExp(l(t.tpl_host_fuzzy_test),"i");var s=[];function u(e,t){throw new Error('(LinkifyIt) Invalid schema "'+e+'": '+t)}e.__compiled__={},Object.keys(e.__schemas__).forEach((function(t){var n=e.__schemas__[t];if(null!==n){var r={validate:null,link:null};if(e.__compiled__[t]=r,"[object Object]"===o(n))return!function(e){return"[object RegExp]"===o(e)}(n.validate)?i(n.validate)?r.validate=n.validate:u(t,n):r.validate=function(e){return function(t,n){var r=t.slice(n);return e.test(r)?r.match(e)[0].length:0}}(n.validate),void(i(n.normalize)?r.normalize=n.normalize:n.normalize?u(t,n):r.normalize=function(e,t){t.normalize(e)});!function(e){return"[object String]"===o(e)}(n)?u(t,n):s.push(t)}})),s.forEach((function(t){e.__compiled__[e.__schemas__[t]]&&(e.__compiled__[t].validate=e.__compiled__[e.__schemas__[t]].validate,e.__compiled__[t].normalize=e.__compiled__[e.__schemas__[t]].normalize)})),e.__compiled__[""]={validate:null,normalize:function(e,t){t.normalize(e)}};var c=Object.keys(e.__compiled__).filter((function(t){return t.length>0&&e.__compiled__[t]})).map(a).join("|");e.re.schema_test=RegExp("(^|(?!_)(?:[><\uff5c]|"+t.src_ZPCc+"))("+c+")","i"),e.re.schema_search=RegExp("(^|(?!_)(?:[><\uff5c]|"+t.src_ZPCc+"))("+c+")","ig"),e.re.schema_at_start=RegExp("^"+e.re.schema_search.source,"i"),e.re.pretest=RegExp("("+e.re.schema_test.source+")|("+e.re.host_fuzzy_test.source+")|@","i"),function(e){e.__index__=-1,e.__text_cache__=""}(e)}function d(e,t){var n=e.__index__,r=e.__last_index__,o=e.__text_cache__.slice(n,r);this.schema=e.__schema__.toLowerCase(),this.index=n+t,this.lastIndex=r+t,this.raw=o,this.text=o,this.url=o}function f(e,t){var n=new d(e,t);return e.__compiled__[n.schema].normalize(n,e),n}function h(e,t){if(!(this instanceof h))return new h(e,t);var n;t||(n=e,Object.keys(n||{}).reduce((function(e,t){return e||l.hasOwnProperty(t)}),!1)&&(t=e,e={})),this.__opts__=r({},l,t),this.__index__=-1,this.__last_index__=-1,this.__schema__="",this.__text_cache__="",this.__schemas__=r({},s,e),this.__compiled__={},this.__tlds__=u,this.__tlds_replaced__=!1,this.re={},c(this)}h.prototype.add=function(e,t){return this.__schemas__[e]=t,c(this),this},h.prototype.set=function(e){return this.__opts__=r(this.__opts__,e),this},h.prototype.test=function(e){if(this.__text_cache__=e,this.__index__=-1,!e.length)return!1;var t,n,r,o,i,a,l,s;if(this.re.schema_test.test(e))for((l=this.re.schema_search).lastIndex=0;null!==(t=l.exec(e));)if(o=this.testSchemaAt(e,t[2],l.lastIndex)){this.__schema__=t[2],this.__index__=t.index+t[1].length,this.__last_index__=t.index+t[0].length+o;break}return this.__opts__.fuzzyLink&&this.__compiled__["http:"]&&(s=e.search(this.re.host_fuzzy_test))>=0&&(this.__index__<0||s=0&&null!==(r=e.match(this.re.email_fuzzy))&&(i=r.index+r[1].length,a=r.index+r[0].length,(this.__index__<0||ithis.__last_index__)&&(this.__schema__="mailto:",this.__index__=i,this.__last_index__=a)),this.__index__>=0},h.prototype.pretest=function(e){return this.re.pretest.test(e)},h.prototype.testSchemaAt=function(e,t,n){return this.__compiled__[t.toLowerCase()]?this.__compiled__[t.toLowerCase()].validate(e,n,this):0},h.prototype.match=function(e){var t=0,n=[];this.__index__>=0&&this.__text_cache__===e&&(n.push(f(this,t)),t=this.__last_index__);for(var r=t?e.slice(t):e;this.test(r);)n.push(f(this,t)),r=r.slice(this.__last_index__),t+=this.__last_index__;return n.length?n:null},h.prototype.matchAtStart=function(e){if(this.__text_cache__=e,this.__index__=-1,!e.length)return null;var t=this.re.schema_at_start.exec(e);if(!t)return null;var n=this.testSchemaAt(e,t[2],t[0].length);return n?(this.__schema__=t[2],this.__index__=t.index+t[1].length,this.__last_index__=t.index+t[0].length+n,f(this,0)):null},h.prototype.tlds=function(e,t){return e=Array.isArray(e)?e:[e],t?(this.__tlds__=this.__tlds__.concat(e).sort().filter((function(e,t,n){return e!==n[t-1]})).reverse(),c(this),this):(this.__tlds__=e.slice(),this.__tlds_replaced__=!0,c(this),this)},h.prototype.normalize=function(e){e.schema||(e.url="http://"+e.url),"mailto:"!==e.schema||/^mailto:/i.test(e.url)||(e.url="mailto:"+e.url)},h.prototype.onCompile=function(){},e.exports=h},1875:function(e,t,n){"use strict";e.exports=function(e){var t={};e=e||{},t.src_Any=n(5510).source,t.src_Cc=n(538).source,t.src_Z=n(2426).source,t.src_P=n(3741).source,t.src_ZPCc=[t.src_Z,t.src_P,t.src_Cc].join("|"),t.src_ZCc=[t.src_Z,t.src_Cc].join("|");var r="[><\uff5c]";return t.src_pseudo_letter="(?:(?![><\uff5c]|"+t.src_ZPCc+")"+t.src_Any+")",t.src_ip4="(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",t.src_auth="(?:(?:(?!"+t.src_ZCc+"|[@/\\[\\]()]).)+@)?",t.src_port="(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?",t.src_host_terminator="(?=$|[><\uff5c]|"+t.src_ZPCc+")(?!"+(e["---"]?"-(?!--)|":"-|")+"_|:\\d|\\.-|\\.(?!$|"+t.src_ZPCc+"))",t.src_path="(?:[/?#](?:(?!"+t.src_ZCc+"|"+r+"|[()[\\]{}.,\"'?!\\-;]).|\\[(?:(?!"+t.src_ZCc+"|\\]).)*\\]|\\((?:(?!"+t.src_ZCc+"|[)]).)*\\)|\\{(?:(?!"+t.src_ZCc+'|[}]).)*\\}|\\"(?:(?!'+t.src_ZCc+'|["]).)+\\"|\\\'(?:(?!'+t.src_ZCc+"|[']).)+\\'|\\'(?="+t.src_pseudo_letter+"|[-])|\\.{2,}[a-zA-Z0-9%/&]|\\.(?!"+t.src_ZCc+"|[.]|$)|"+(e["---"]?"\\-(?!--(?:[^-]|$))(?:-*)|":"\\-+|")+",(?!"+t.src_ZCc+"|$)|;(?!"+t.src_ZCc+"|$)|\\!+(?!"+t.src_ZCc+"|[!]|$)|\\?(?!"+t.src_ZCc+"|[?]|$))+|\\/)?",t.src_email_name='[\\-;:&=\\+\\$,\\.a-zA-Z0-9_][\\-;:&=\\+\\$,\\"\\.a-zA-Z0-9_]*',t.src_xn="xn--[a-z0-9\\-]{1,59}",t.src_domain_root="(?:"+t.src_xn+"|"+t.src_pseudo_letter+"{1,63})",t.src_domain="(?:"+t.src_xn+"|(?:"+t.src_pseudo_letter+")|(?:"+t.src_pseudo_letter+"(?:-|"+t.src_pseudo_letter+"){0,61}"+t.src_pseudo_letter+"))",t.src_host="(?:(?:(?:(?:"+t.src_domain+")\\.)*"+t.src_domain+"))",t.tpl_host_fuzzy="(?:"+t.src_ip4+"|(?:(?:(?:"+t.src_domain+")\\.)+(?:%TLDS%)))",t.tpl_host_no_ip_fuzzy="(?:(?:(?:"+t.src_domain+")\\.)+(?:%TLDS%))",t.src_host_strict=t.src_host+t.src_host_terminator,t.tpl_host_fuzzy_strict=t.tpl_host_fuzzy+t.src_host_terminator,t.src_host_port_strict=t.src_host+t.src_port+t.src_host_terminator,t.tpl_host_port_fuzzy_strict=t.tpl_host_fuzzy+t.src_port+t.src_host_terminator,t.tpl_host_port_no_ip_fuzzy_strict=t.tpl_host_no_ip_fuzzy+t.src_port+t.src_host_terminator,t.tpl_host_fuzzy_test="localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:"+t.src_ZPCc+"|>|$))",t.tpl_email_fuzzy='(^|[><\uff5c]|"|\\(|'+t.src_ZCc+")("+t.src_email_name+"@"+t.tpl_host_fuzzy_strict+")",t.tpl_link_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|"+t.src_ZPCc+"))((?![$+<=>^`|\uff5c])"+t.tpl_host_port_fuzzy_strict+t.src_path+")",t.tpl_link_no_ip_fuzzy="(^|(?![.:/\\-_@])(?:[$+<=>^`|\uff5c]|"+t.src_ZPCc+"))((?![$+<=>^`|\uff5c])"+t.tpl_host_port_no_ip_fuzzy_strict+t.src_path+")",t}},3534:function(e,t,n){"use strict";e.exports=n(9890)},1285:function(e,t,n){"use strict";e.exports=n(9323)},1437:function(e){"use strict";e.exports=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","section","source","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"]},5850:function(e){"use strict";var t="<[A-Za-z][A-Za-z0-9\\-]*(?:\\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\\s*=\\s*(?:[^\"'=<>`\\x00-\\x20]+|'[^']*'|\"[^\"]*\"))?)*\\s*\\/?>",n="<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>",r=new RegExp("^(?:"+t+"|"+n+"|\x3c!----\x3e|\x3c!--(?:-?[^>-])(?:-?[^-])*--\x3e|<[?][\\s\\S]*?[?]>|]*>|)"),o=new RegExp("^(?:"+t+"|"+n+")");e.exports.n=r,e.exports.q=o},786:function(e,t,n){"use strict";var r=Object.prototype.hasOwnProperty;function o(e,t){return r.call(e,t)}function i(e){return!(e>=55296&&e<=57343)&&(!(e>=64976&&e<=65007)&&(65535!==(65535&e)&&65534!==(65535&e)&&(!(e>=0&&e<=8)&&(11!==e&&(!(e>=14&&e<=31)&&(!(e>=127&&e<=159)&&!(e>1114111)))))))}function a(e){if(e>65535){var t=55296+((e-=65536)>>10),n=56320+(1023&e);return String.fromCharCode(t,n)}return String.fromCharCode(e)}var l=/\\([!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~])/g,s=new RegExp(l.source+"|"+/&([a-z#][a-z0-9]{1,31});/gi.source,"gi"),u=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i,c=n(1285);var d=/[&<>"]/,f=/[&<>"]/g,h={"&":"&","<":"<",">":">",'"':"""};function p(e){return h[e]}var m=/[.?*+^$[\]\\(){}|-]/g;var g=n(3741);t.lib={},t.lib.mdurl=n(3461),t.lib.ucmicro=n(6937),t.assign=function(e){var t=Array.prototype.slice.call(arguments,1);return t.forEach((function(t){if(t){if("object"!==typeof t)throw new TypeError(t+"must be object");Object.keys(t).forEach((function(n){e[n]=t[n]}))}})),e},t.isString=function(e){return"[object String]"===function(e){return Object.prototype.toString.call(e)}(e)},t.has=o,t.unescapeMd=function(e){return e.indexOf("\\")<0?e:e.replace(l,"$1")},t.unescapeAll=function(e){return e.indexOf("\\")<0&&e.indexOf("&")<0?e:e.replace(s,(function(e,t,n){return t||function(e,t){var n=0;return o(c,t)?c[t]:35===t.charCodeAt(0)&&u.test(t)&&i(n="x"===t[1].toLowerCase()?parseInt(t.slice(2),16):parseInt(t.slice(1),10))?a(n):e}(e,n)}))},t.isValidEntityCode=i,t.fromCodePoint=a,t.escapeHtml=function(e){return d.test(e)?e.replace(f,p):e},t.arrayReplaceAt=function(e,t,n){return[].concat(e.slice(0,t),n,e.slice(t+1))},t.isSpace=function(e){switch(e){case 9:case 32:return!0}return!1},t.isWhiteSpace=function(e){if(e>=8192&&e<=8202)return!0;switch(e){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1},t.isMdAsciiPunct=function(e){switch(e){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}},t.isPunctChar=function(e){return g.test(e)},t.escapeRE=function(e){return e.replace(m,"\\$&")},t.normalizeReference=function(e){return e=e.trim().replace(/\s+/g," "),"\u1e7e"==="\u1e9e".toLowerCase()&&(e=e.replace(/\u1e9e/g,"\xdf")),e.toLowerCase().toUpperCase()}},4937:function(e,t,n){"use strict";t.parseLinkLabel=n(9162),t.parseLinkDestination=n(9738),t.parseLinkTitle=n(4890)},9738:function(e,t,n){"use strict";var r=n(786).unescapeAll;e.exports=function(e,t,n){var o,i,a=t,l={ok:!1,pos:0,lines:0,str:""};if(60===e.charCodeAt(t)){for(t++;t32)return l;if(41===o){if(0===i)break;i--}t++}return a===t||0!==i||(l.str=r(e.slice(a,t)),l.lines=0,l.pos=t,l.ok=!0),l}},9162:function(e){"use strict";e.exports=function(e,t,n){var r,o,i,a,l=-1,s=e.posMax,u=e.pos;for(e.pos=t+1,r=1;e.pos=n)return s;if(34!==(i=e.charCodeAt(t))&&39!==i&&40!==i)return s;for(t++,40===i&&(i=41);t=0))try{t.hostname=d.toASCII(t.hostname)}catch(n){}return c.encode(c.format(t))}function y(e){var t=c.parse(e,!0);if(t.hostname&&(!t.protocol||g.indexOf(t.protocol)>=0))try{t.hostname=d.toUnicode(t.hostname)}catch(n){}return c.decode(c.format(t),c.decode.defaultChars+"%")}function b(e,t){if(!(this instanceof b))return new b(e,t);t||r.isString(e)||(t=e||{},e="default"),this.inline=new s,this.block=new l,this.core=new a,this.renderer=new i,this.linkify=new u,this.validateLink=m,this.normalizeLink=v,this.normalizeLinkText=y,this.utils=r,this.helpers=r.assign({},o),this.options={},this.configure(e),t&&this.set(t)}b.prototype.set=function(e){return r.assign(this.options,e),this},b.prototype.configure=function(e){var t,n=this;if(r.isString(e)&&!(e=f[t=e]))throw new Error('Wrong `markdown-it` preset "'+t+'", check name');if(!e)throw new Error("Wrong `markdown-it` preset, can't be empty");return e.options&&n.set(e.options),e.components&&Object.keys(e.components).forEach((function(t){e.components[t].rules&&n[t].ruler.enableOnly(e.components[t].rules),e.components[t].rules2&&n[t].ruler2.enableOnly(e.components[t].rules2)})),this},b.prototype.enable=function(e,t){var n=[];Array.isArray(e)||(e=[e]),["core","block","inline"].forEach((function(t){n=n.concat(this[t].ruler.enable(e,!0))}),this),n=n.concat(this.inline.ruler2.enable(e,!0));var r=e.filter((function(e){return n.indexOf(e)<0}));if(r.length&&!t)throw new Error("MarkdownIt. Failed to enable unknown rule(s): "+r);return this},b.prototype.disable=function(e,t){var n=[];Array.isArray(e)||(e=[e]),["core","block","inline"].forEach((function(t){n=n.concat(this[t].ruler.disable(e,!0))}),this),n=n.concat(this.inline.ruler2.disable(e,!0));var r=e.filter((function(e){return n.indexOf(e)<0}));if(r.length&&!t)throw new Error("MarkdownIt. Failed to disable unknown rule(s): "+r);return this},b.prototype.use=function(e){var t=[this].concat(Array.prototype.slice.call(arguments,1));return e.apply(e,t),this},b.prototype.parse=function(e,t){if("string"!==typeof e)throw new Error("Input data should be a String");var n=new this.core.State(e,this,t);return this.core.process(n),n.tokens},b.prototype.render=function(e,t){return t=t||{},this.renderer.render(this.parse(e,t),this.options,t)},b.prototype.parseInline=function(e,t){var n=new this.core.State(e,this,t);return n.inlineMode=!0,this.core.process(n),n.tokens},b.prototype.renderInline=function(e,t){return t=t||{},this.renderer.render(this.parseInline(e,t),this.options,t)},e.exports=b},7782:function(e,t,n){"use strict";var r=n(8674),o=[["table",n(9399),["paragraph","reference"]],["code",n(5078)],["fence",n(1077),["paragraph","reference","blockquote","list"]],["blockquote",n(9224),["paragraph","reference","blockquote","list"]],["hr",n(7542),["paragraph","reference","blockquote","list"]],["list",n(7168),["paragraph","reference","blockquote"]],["reference",n(9277)],["html_block",n(5672),["paragraph","reference","blockquote"]],["heading",n(969),["paragraph","reference","blockquote"]],["lheading",n(7671)],["paragraph",n(6572)]];function i(){this.ruler=new r;for(var e=0;e=n))&&!(e.sCount[a]=s){e.line=n;break}for(r=0;r=i)break}else e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()},a.prototype.parse=function(e,t,n,r){var o,i,a,l=new this.State(e,t,n,r);for(this.tokenize(l),a=(i=this.ruler2.getRules("")).length,o=0;o"+i(e[t].content)+""},a.code_block=function(e,t,n,r,o){var a=e[t];return"