first commit; migrate code from minimal/docs-server

This commit is contained in:
James Brumond 2023-04-29 14:48:17 -07:00
commit c366c1e605
Signed by: james
GPG Key ID: 24BA25B8B303B023
124 changed files with 6694 additions and 0 deletions

14
.editorconfig Normal file
View File

@ -0,0 +1,14 @@
root = true
[*]
indent_size = 4
indent_style = tab
[*.{js,ts,css,html}]
indent_size = 4
indent_style = tab
[*.{md,json,jsonc,yml,yaml,sql}]
indent_size = 2
indent_style = space

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
build

2
bin/markdown2html Executable file
View File

@ -0,0 +1,2 @@
#!/bin/sh
node $(dirname $0)/markdown2html.js $*

2
bin/markdown2html.js Executable file
View File

@ -0,0 +1,2 @@
#!/usr/bin/env node
require('../build/bin/markdown2html.js');

3485
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

35
package.json Normal file
View File

@ -0,0 +1,35 @@
{
"name": "markdown-to-html",
"private": true,
"scripts": {
"tsc": "tsc"
},
"bin": {
"markdown2html": "./bin/markdown2html"
},
"exports": "./build/index.js",
"devDependencies": {
"@types/dompurify": "^2.3.3",
"@types/jsdom": "^20.0.0",
"@types/katex": "^0.16.0",
"@types/luxon": "^3.1.0",
"@types/marked": "^4.0.3",
"@types/node": "^18.11.18",
"@types/prismjs": "^1.26.0",
"@types/qrcode": "^1.5.0",
"typescript": "^5.0.4"
},
"dependencies": {
"bytefield-svg": "^1.6.1",
"dompurify": "^2.3.6",
"jsdom": "^20.0.1",
"katex": "^0.16.7",
"marked": "^4.1.1",
"nomnoml": "^1.5.2",
"pikchr": "^0.0.5",
"prismjs": "^1.29.0",
"qrcode": "^1.5.1",
"vega": "^5.22.1",
"yaml": "^2.2.2"
}
}

41
src/async-steps.ts Normal file
View File

@ -0,0 +1,41 @@
// marked does not support asynchronous steps in the rendering process.
// as such, in order to support external renderers that do their processing
// async, this handles swapping out a placeholder for the additionally processed
// content after marked is finished rendering
let next_task_id = 1;
const data_binding = /{{@@!@!@@ MARKED ASYNC DATA BINDING PLACEHOLDER {{([0-9]+)}} @@!@!@@}}/g;
const pending_tasks: Record<number, Promise<string>> = { };
export function bind_data_async(data_generator: Promise<string>) {
const task_id = next_task_id++;
const placeholder = `{{@@!@!@@ MARKED ASYNC DATA BINDING PLACEHOLDER {{${task_id}}} @@!@!@@}}`;
pending_tasks[task_id] = data_generator;
return placeholder;
}
export async function resolve_async_bindings(html: string) {
const bindings: string[] = [ ];
const promises: Promise<string>[] = [ ];
let match: RegExpMatchArray;
while (match = data_binding.exec(html)) {
bindings.push(match[0]);
promises.push(pending_tasks[match[1]]);
delete pending_tasks[match[1]];
}
data_binding.lastIndex = 0;
const results = await Promise.all(promises);
for (let i = 0; i < results.length; i++) {
html = html.replace(bindings[i], results[i]);
}
return html;
}

94
src/attrs.ts Normal file
View File

@ -0,0 +1,94 @@
import { Lazy, resolve_lazy } from './lazy';
const attrs_pattern = /\s+\{\s*(?:[\.#:][^\s]+(?:\s*[\.#:][^\s]+)*)?\s*}$/;
export interface ParsedAttributes {
id?: string;
classes: string[];
attrs: Record<string, string | string[]>;
html_attrs: string[];
text: string;
}
export function parse_attributes(text: string, fallback_id?: Lazy<string>) {
const attrs: ParsedAttributes = {
id: null,
classes: [ ],
attrs: { },
html_attrs: [ ],
text,
};
const attrs_match = attrs_pattern.exec(text);
if (attrs_match) {
attrs.text = text.slice(0, -attrs_match[0].length).trim();
const raw_attrs = attrs_match[0].trim().slice(1, -1).trim().split(/\s+/g);
for (const attr of raw_attrs) {
if (attr.startsWith('.')) {
attrs.classes.push(attr.slice(1));
}
else if (attr.startsWith('#')) {
attrs.id = attr.slice(1);
}
else if (attr.startsWith(':')) {
const eq_index = attr.indexOf('=');
if (eq_index === -1) {
const name = attr.slice(1);
attrs.attrs[name] = '';
}
const name = attr.slice(1, eq_index);
const value = attr.slice(eq_index + 1);
// Enable passing the same attribute more than once for lists, i.e.:
// {:rel=external :rel=nofollow}
// should render as:
// rel="external nofollow"
if (attrs.attrs[name]) {
if (! Array.isArray(attrs.attrs[name])) {
attrs.attrs[name] = [ attrs.attrs[name] as string ];
}
(attrs.attrs[name] as string[]).push(value);
}
else {
attrs.attrs[name] = value;
}
}
}
}
if (! attrs.id) {
attrs.id = resolve_lazy(fallback_id);
}
if (attrs.id) {
attrs.html_attrs.push(`id="${attrs.id}"`);
}
if (attrs.classes.length) {
attrs.html_attrs.push(`class="${attrs.classes.join(' ')}"`);
}
for (const [name, value] of Object.entries(attrs.attrs)) {
if (Array.isArray(value)) {
attrs.html_attrs.push(`${name}="${value.join(' ')}"`);
}
else {
attrs.html_attrs.push(value ? `${name}="${value}"` : name);
}
}
console.log(attrs);
return attrs;
}

2
src/bin/markdown2html.ts Normal file
View File

@ -0,0 +1,2 @@
console.log('markdown2html');

92
src/description-list.ts Normal file
View File

@ -0,0 +1,92 @@
import { marked } from 'marked';
import { MarkdownOptions } from './render';
export interface DescriptionListToken extends marked.Tokens.Generic {
items: (DescriptionTermToken | DescriptionDetailToken)[];
}
export interface DescriptionTermToken extends marked.Tokens.Generic {
text: string;
}
export interface DescriptionDetailToken extends marked.Tokens.Generic {
text: string;
}
export function description_list_ext(renderer: marked.Renderer, opts: MarkdownOptions) : marked.TokenizerExtension & marked.RendererExtension {
return {
name: 'description_list',
level: 'block',
start: (src) => src.match(/^:[:#-]/)?.index,
tokenizer(src, tokens) {
const rule = /^(?::[:#-](?:\s[^\n]*)?(?:\n|$))+/;
const match = rule.exec(src);
if (match) {
const token: DescriptionListToken = {
type: 'description_list',
raw: match[0],
items: [ ]
};
const items = token.raw.trim().split('\n');
const raw_buffer: string[] = [ ];
const text_buffer: string[] = [ ];
const flush_buffer = () => {
if (! raw_buffer.length) {
return;
}
// Grab the second character from the first line to determine the
// token type (should be "#" or "-")
const type = raw_buffer[0][1] === '#' ? 'description_term' : 'description_detail';
const sub_token: (DescriptionTermToken | DescriptionDetailToken) = {
type,
raw: raw_buffer.join('\n'),
text: text_buffer.join('\n'),
tokens: [ ],
};
raw_buffer.length = 0;
text_buffer.length = 0;
this.lexer.blockTokens(sub_token.text, sub_token.tokens);
token.items.push(sub_token);
};
for (const line of items) {
const rule = /^:([:#-])(?:\s([^\n]*))?(?:\n|$)/;
const match = rule.exec(line);
if (match) {
if (match[1] !== ':') {
flush_buffer();
}
raw_buffer.push(match[0]);
text_buffer.push(match[2]);
}
}
flush_buffer();
return token;
}
},
renderer(token: DescriptionListToken) {
const items = token.items.map((item) => {
const tag = item.type === 'description_term' ? 'dt' : 'dd';
return `
<${tag}>
${this.parser.parse(item.tokens)}
</${tag}>
`;
});
return `<dl>${items.join('')}</dl>`;
}
};
}

206
src/footnotes.ts Normal file
View File

@ -0,0 +1,206 @@
import { marked } from 'marked';
import { MarkdownOptions } from './render';
const footnotes = Symbol('footnotes');
// We're going to hang some extra data off of the lexer so we can reference it
// later when generating links back to references
declare module 'marked' {
export interface Lexer {
[footnotes]: Record<string, number>;
}
}
export interface FootnoteLinkToken extends marked.Tokens.Generic {
id: string;
inst: number;
}
export function footnote_ref_ext(renderer: marked.Renderer, opts: MarkdownOptions) : marked.TokenizerExtension & marked.RendererExtension {
return {
name: 'footnote_ref',
level: 'inline',
start: (src) => src.match(/\[\^/)?.index,
tokenizer(src, tokens) {
const rule = /^\[\^([a-zA-Z0-9-._§]+)]/;
const match = rule.exec(src);
if (match) {
const id = match[1];
return {
type: 'footnote_ref',
raw: match[0],
id: id,
inst: next_cite_inst(this.lexer, id)
};
}
},
renderer(token: FootnoteLinkToken) {
return `<sup id="cite:ref-${token.id}-${token.inst}"><a href="#cite:note-${token.id}">[${token.id}]</a></sup>`;
}
};
}
export interface FootnoteListToken extends marked.Tokens.Generic {
text: string;
items: FootnoteToken[];
}
export interface FootnoteToken extends marked.Tokens.Generic {
id: string;
text: string;
inst_count() : number;
}
export function footnote_list_ext(renderer: marked.Renderer, opts: MarkdownOptions) : marked.TokenizerExtension & marked.RendererExtension {
return {
name: 'footnote_list',
level: 'block',
start: (src) => src.match(/^\[/)?.index,
tokenizer(src, tokens) {
const token: FootnoteListToken = {
type: 'footnote_list',
raw: '',
text: '',
items: [ ]
};
let remaining = src;
const prefix_rule = /^\[\^([a-zA-Z0-9\._§-]+)]:/;
const whitespace_rule = /^\s*(?:\n|$)/;
if (! prefix_rule.test(src)) {
return null;
}
const items: { prefix: string, content: string }[] = [ ];
let current: { prefix: string, content: string };
function take(str: string) {
token.raw += str;
remaining = remaining.slice(str.length);
return str;
}
line_loop:
while (true) {
const prefix_match = prefix_rule.exec(remaining);
if (prefix_match) {
take(prefix_match[0]);
items.push(
current = {
prefix: prefix_match[1],
content: '',
}
);
continue line_loop;
}
const whitespace_match = whitespace_rule.exec(remaining);
if (whitespace_match) {
if (! take(whitespace_match[0])) {
break line_loop;
}
current = null;
continue line_loop;
}
if (current) {
const next_newline = remaining.indexOf('\n');
if (next_newline < 0) {
current.content += take(remaining);
break;
}
current.content += take(remaining.slice(0, next_newline + 1));
continue line_loop;
}
break;
}
token.text = token.raw.trim();
token.items = items.map(({ prefix, content }) => {
const token = {
type: 'footnote',
raw: `[^${prefix}]:${content}`,
id: prefix,
text: content,
tokens: [ ],
inst_count: () => get_cite_inst_count(this.lexer, prefix)
};
this.lexer.inline(token.text, token.tokens);
return token;
});
return token;
},
renderer(token: FootnoteListToken) {
const items = token.items.map((item) => (`
<li role="doc-footnote" id="cite:note-${item.id}">
<span class="cite-label">[${item.id}]</span>
${footnote_link_backs(item.id, item.inst_count())}
${this.parser.parseInline(item.tokens, renderer)}
</li>
`));
return `<ul role="doc-endnotes">${items.join('')}</ul>`;
}
};
}
function get_cite_inst_count(lexer: marked.Lexer, id: string) {
if (! lexer[footnotes]) {
lexer[footnotes] = { };
}
return lexer[footnotes][id] || 0;
}
function next_cite_inst(lexer: marked.Lexer, id: string) {
if (! lexer[footnotes]) {
lexer[footnotes] = { };
}
if (! lexer[footnotes][id]) {
lexer[footnotes][id] = 0;
}
return ++lexer[footnotes][id];
}
const letters = 'abcdefghijklmnopqrstuvwxyz';
function footnote_link_backs(id: string, count: number) {
if (! count) {
return '';
}
if (count === 1) {
return `<sup><a href="#cite:ref-${id}-1" title="Back to reference">^</a></sup>`;
}
// note: We're using letters for link backs; If we run out, only
// show the first 26 references
// todo: A more ideal solution would be to start using double-letters,
// like "aa", "ab", "ac", etc. after running out of single letter options
count = Math.min(count, 26);
const links: string[] = [ ];
for (let i = 0; i < count; i++) {
const letter = letters[i];
links[i] = `<a href="#cite:ref-${id}-${i + 1}" title="Back to reference ${letter}">${letter}</a>`;
}
return `<sup>^ ${links.join(' ')}</sup>`;
}

14
src/html-sanitize.ts Normal file
View File

@ -0,0 +1,14 @@
import { JSDOM } from 'jsdom';
import createDOMPurify = require('dompurify');
export function sanitize_html(html: string) : string {
const { window } = new JSDOM('');
const dom_purify = createDOMPurify(window as any as Window);
return dom_purify.sanitize(html, {
CUSTOM_ELEMENT_HANDLING: {
tagNameCheck: (tag_name) => tag_name === 'svg-icon',
attributeNameCheck: (attr_name) => attr_name === 'icon',
}
});
}

32
src/icon.ts Normal file
View File

@ -0,0 +1,32 @@
import { marked } from 'marked';
import { icons } from './icons';
import { MarkdownOptions } from './render';
export interface IconToken extends marked.Tokens.Generic {
text: string;
}
export function icon_ext(renderer: marked.Renderer, opts: MarkdownOptions) : marked.TokenizerExtension & marked.RendererExtension {
return {
name: 'icon',
level: 'inline',
start: (src) => src.match(/\{:/)?.index,
tokenizer(src, tokens) {
const rule = /^\{:([a-zA-Z0-9-]+):\}/;
const match = rule.exec(src);
if (match) {
return {
type: 'icon',
raw: match[0],
text: match[1],
tokens: this.lexer.inlineTokens(match[1], [ ])
};
}
},
renderer(token: IconToken) {
return icons[token.text] || `<!-- unknown icon "${token.text}" -->`;
}
};
}

25
src/icons.ts Normal file
View File

@ -0,0 +1,25 @@
export const icons: Record<string, string> = Object.create(null);
const whitespace = /[\s\t\n]+/g;
const feather_icons: Record<string, string> = require('../vendor/feather-icons/icons.json');
// todo: css variables
for (const [name, contents] of Object.entries(feather_icons)) {
icons[name] = `
<svg xmlns="http://www.w3.org/2000/svg"
class="icon ${name}"
aria-hidden="true"
style="width: var(--icon-size, 1rem); height: var(--icon-size, 1rem)"
viewBox="0 0 24 24"
fill="none"
stroke="currentcolor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>${contents}</svg>
`.replace(whitespace, ' ').trim();
}
Object.freeze(icons);

2
src/index.ts Normal file
View File

@ -0,0 +1,2 @@
export * from './render';

67
src/katex.ts Normal file
View File

@ -0,0 +1,67 @@
import { marked } from 'marked';
import katex = require('katex');
import type { KatexOptions } from 'katex';
import { MarkdownOptions } from './render';
export interface KatexToken extends marked.Tokens.Generic {
text: string;
}
export function katex_block_ext(renderer: marked.Renderer, opts: MarkdownOptions) : marked.TokenizerExtension & marked.RendererExtension {
return {
name: 'katex_block',
level: 'block',
start: (src) => src.match(/^\$\$/)?.index,
tokenizer(src, tokens) {
const rule = /^\$\$((?:[^\$]|\$(?!\$))+)\$\$/;
const match = rule.exec(src);
if (match) {
return {
type: 'katex_block',
raw: match[0],
text: match[1]
};
}
},
renderer(token: KatexToken) {
const katex_opts: KatexOptions = {
displayMode: true, // true == "block"
output: 'html',
macros: opts.katex_macros,
};
return (katex as any).renderToString(token.text, katex_opts);
}
};
}
export function katex_inline_ext(renderer: marked.Renderer, opts: MarkdownOptions) : marked.TokenizerExtension & marked.RendererExtension {
return {
name: 'katex_inline',
level: 'inline',
start: (src) => src.match(/\$/)?.index,
tokenizer(src, tokens) {
const rule = /^\$([^\n\s](?:[^\n\$]*[^\n\s])?)\$/;
const match = rule.exec(src);
if (match) {
return {
type: 'katex_inline',
raw: match[0],
text: match[1]
};
}
},
renderer(token: KatexToken) {
const katex_opts: KatexOptions = {
displayMode: false, // false == "inline"
output: 'html',
macros: opts.katex_macros,
};
return (katex as any).renderToString(token.text, katex_opts);
}
};
}

8
src/lazy.ts Normal file
View File

@ -0,0 +1,8 @@
export type NotFunc = string | number | boolean | object;
export type Lazy<T extends NotFunc> = T | (() => T);
export function resolve_lazy<T extends NotFunc>(lazy: Lazy<T>) : T {
return typeof lazy === 'function' ? lazy() : lazy;
}

31
src/mark.ts Normal file
View File

@ -0,0 +1,31 @@
import { marked } from 'marked';
import { MarkdownOptions } from './render';
export interface MarkToken extends marked.Tokens.Generic {
text: string;
}
export function mark_ext(renderer: marked.Renderer, opts: MarkdownOptions) : marked.TokenizerExtension & marked.RendererExtension {
return {
name: 'mark',
level: 'inline',
start: (src) => src.match(/=/)?.index,
tokenizer(src, tokens) {
const rule = /^==([^\n\s](?:(?:[^\n=]|=(?!=))*[^\n\s])?)==/;
const match = rule.exec(src);
if (match) {
return {
type: 'mark',
raw: match[0],
text: match[1],
tokens: this.lexer.inlineTokens(match[1], [ ])
};
}
},
renderer(token: MarkToken) {
return `<mark>${this.parser.parseInline(token.tokens, renderer)}</mark>`;
}
};
}

15
src/prism/index.ts Normal file
View File

@ -0,0 +1,15 @@
import { highlight as prism_highlight, languages/* , hooks */ } from 'prismjs';
import load_languages = require('prismjs/components/index');
load_languages();
require('./wasm');
// hooks.add('after-tokenize', (env) => {
// //
// });
export function highlight(code: string, lang: string) {
const grammar = typeof languages[lang] === 'object' ? languages[lang] : languages.plain;
return prism_highlight(code, grammar, lang);
}

79
src/prism/wasm.ts Normal file
View File

@ -0,0 +1,79 @@
import { languages } from 'prismjs';
const extra_keywords = [
{
pattern: /\b(?:memory\.(?:init|copy|fill)|data\.(?:drop)|table\.(?:init|copy|grow|size|fill|get|set)|elem\.(?:drop)|ref\.(?:null|is_null|func))\b/,
inside: {
'punctuation': /\./
}
},
/\b(?:funcref|externref)\b/,
// ===== SIMD / Vectors =====
{
pattern: /\b(?:v128\.(?:const|store(?:(?:8|16|32|64)_lane)?|load(?:(?:8x8|16x4|32x2)_[su]|(?:8|16|32|64)_splat|(?:8|16|32|64)_lane|(?:32|64)_zero)?|not|and|andnot|or|xor|bitselect|any_true))\b/,
inside: {
'punctuation': /\./
}
},
{
pattern: /\b(?:i(?:8x16|16x8|32x4|64x2)\.(?:splat|replace_lane|abs|neg|all_true|bitmask|shl|eq|ne|(?:shr)_[su]))\b/,
inside: {
'punctuation': /\./
}
},
{
pattern: /\b(?:i(?:8x16|16x8|32x4)\.(?:(?:[gl][te]|min|max)_[su]))\b/,
inside: {
'punctuation': /\./
}
},
{
pattern: /\b(?:i8x16\.(?:shuffle|swizzle|popcnt|avgr_u|(?:add|sub)(?:_sat_[su])?|(?:extract_lane|narrow_i16x8|extadd_pairwise_(?:i8x16|i16x8))_[su]))\b/,
inside: {
'punctuation': /\./
}
},
{
pattern: /\b(?:i16x8\.(?:mul|avgr_u|q15mulr_sat_s|(?:add|sub)(?:_sat_[su])?|(?:extract_lane|narrow_i32x4|(?:extend|extmul)_(?:low|high)_i8x16)_[su]))\b/,
inside: {
'punctuation': /\./
}
},
{
pattern: /\b(?:i32x4\.(?:extract_lane|add|sub|mul|dot_i16x8_s|(?:(?:extend|extmul)_(?:low|high)_i16x8|trunc_sat_f32x4)_[su]|trunc_sat_f64x2_[su]_zero))\b/,
inside: {
'punctuation': /\./
}
},
{
pattern: /\b(?:i64x2\.(?:extract_lane|add|sub|mul|[gl][te]_s|(?:extend|extmul)_(?:low|high)_i32x4_[su]))\b/,
inside: {
'punctuation': /\./
}
},
{
pattern: /\b(?:f(?:32x4|64x2)\.(?:splat|extract_lane|replace_lane|eq|ne|[gl][te]|ceil|floor|trunc|nearest|abs|neg|sqrt|add|sub|mul|div|p?(?:min|max)))\b/,
inside: {
'punctuation': /\./
}
},
{
pattern: /\b(?:f32x4\.(?:demote_f64x2_zero|convert_i32x4_[su]))\b/,
inside: {
'punctuation': /\./
}
},
{
pattern: /\b(?:f64x2\.(?:promote_low_f32x4|convert_low_i32x4_[su]))\b/,
inside: {
'punctuation': /\./
}
},
/\b(?:i8x16|i16x8|i32x4|i64x2|f32x4|f64x2)\b/,
];
if (Array.isArray(languages.wasm.keyword)) {
languages.wasm.keyword.unshift(...extra_keywords);
}

114
src/qrcode.ts Normal file
View File

@ -0,0 +1,114 @@
import { toString, QRCodeRenderersOptions } from 'qrcode';
type Colors = QRCodeRenderersOptions['color'];
export interface WifiInfo {
ssid: string;
password: string;
hidden: boolean;
encryption: 'WPA' | 'WEP' | 'None';
}
export interface MeCardInfo {
adr?: string;
bday?: string;
email?: string;
n?: string;
nickname?: string;
note?: string;
sound?: string;
tel?: string;
tel_av?: string;
url?: string;
}
// todo: css variables
export async function generate_qr_code(data: string, colors?: Colors) {
colors = colors || {
dark: 'var(--theme-text-heading, currentcolor)',
light: 'var(--theme-bg-main, transparent)'
};
const svg = await toString(data, {
type: 'svg',
color: {
dark: '#000000',
light: '#ffffff'
}
});
const colored_svg = svg.replace(/#000000/g, colors.dark).replace(/#ffffff/g, colors.light).trim();
return colored_svg.replace(/^<svg /, '<svg class="qrcode" ')
}
export function generate_wifi_qr_code(info: WifiInfo, colors?: Colors) {
const ssid = escape(info.ssid);
const password = escape(info.password);
let data = `WIFI:S:${ssid};P:${password};H:${info.hidden};`
if (info.encryption) {
data += `T:${info.encryption};`;
}
return generate_qr_code(data, colors);
}
export function generate_mecard_qr_code(info: MeCardInfo, colors?: Colors) {
let data = 'MECARD:';
if (info.adr) {
data += `ADR:${escape(info.adr)};`;
}
if (info.bday) {
data += `BDAY:${escape(info.bday)};`;
}
if (info.email) {
data += `EMAIL:${escape(info.email)};`;
}
if (info.n) {
data += `N:${escape(info.n)};`;
}
if (info.nickname) {
data += `NICKNAME:${escape(info.nickname)};`;
}
if (info.adr) {
data += `ADR:${escape(info.adr)};`;
}
if (info.adr) {
data += `ADR:${escape(info.adr)};`;
}
if (info.adr) {
data += `ADR:${escape(info.adr)};`;
}
if (info.adr) {
data += `ADR:${escape(info.adr)};`;
}
if (info.adr) {
data += `ADR:${escape(info.adr)};`;
}
data += ';';
return generate_qr_code(data, colors);
}
function escape(str: string) {
return str
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/;/g, '\\;')
.replace(/,/g, '\\,')
.replace(/:/g, '\\:');
}

68
src/render.ts Normal file
View File

@ -0,0 +1,68 @@
import { marked } from 'marked';
import { create_renderer } from './renderer';
import { mark_ext } from './mark';
import { section_ext } from './section';
import { icon_ext } from './icon';
import { sanitize_html } from './html-sanitize';
import { katex_block_ext, katex_inline_ext } from './katex';
import { footnote_list_ext, footnote_ref_ext } from './footnotes';
import { description_list_ext } from './description-list';
import { resolve_async_bindings } from './async-steps';
export interface MarkdownOptions {
base_url?: string;
breaks?: boolean;
inline?: boolean;
katex_macros?: Record<string, string>;
extensions?: MarkdownExtension[];
}
export interface MarkdownExtension {
(renderer: marked.Renderer, opts: MarkdownOptions): marked.TokenizerExtension & marked.RendererExtension
}
export async function render_markdown_to_html(markdown: string, options: MarkdownOptions = { }) {
const marked_options: marked.MarkedOptions = {
baseUrl: options.base_url,
breaks: options.breaks || false,
renderer: create_renderer(options),
};
marked.use({
extensions: [
katex_block_ext(marked_options.renderer, options),
katex_inline_ext(marked_options.renderer, options),
footnote_ref_ext(marked_options.renderer, options),
footnote_list_ext(marked_options.renderer, options),
mark_ext(marked_options.renderer, options),
description_list_ext(marked_options.renderer, options),
section_ext(marked_options.renderer, options),
icon_ext(marked_options.renderer, options),
...(options.extensions || [ ]).map((ext) => {
return ext(marked_options.renderer, options);
}),
],
tokenizer: {
url(src) {
// disable auto-linking; more can be added here to auto-link only sometimes
// see: https://github.com/markedjs/marked/issues/882#issuecomment-781628889
return null;
}
},
});
const unsafe_html = options.inline
? marked.parseInline(markdown, marked_options)
: await new Promise<string>((resolve, reject) => {
marked.parse(markdown, marked_options, (error, unsafe_html) => {
if (error) {
return reject(error);
}
resolve_async_bindings(unsafe_html).then(resolve, reject);
});
});
return sanitize_html(unsafe_html);
}

297
src/renderer.ts Normal file
View File

@ -0,0 +1,297 @@
import { marked } from 'marked';
import { highlight } from './prism';
import katex = require('katex');
import type { KatexOptions } from 'katex';
import render_bytefield = require('bytefield-svg');
import { renderSvg as render_nomnoml } from 'nomnoml';
import { pikchr } from 'pikchr';
import { parse as parse_yaml } from 'yaml';
import { icons } from './icons';
import { strip_svg } from './svg';
import { generate_mecard_qr_code, generate_qr_code } from './qrcode';
import { bind_data_async } from './async-steps';
import { render_vega_spec } from './vega';
import { parse_attributes } from './attrs';
import { MarkdownOptions } from './render';
export function create_renderer(opts: MarkdownOptions) {
const renderer = new marked.Renderer();
renderer.heading = heading(renderer, opts);
renderer.code = code(renderer, opts);
// ...
return renderer;
}
function heading(renderer: marked.Renderer, opts: MarkdownOptions) {
return function(orig_text: string, level: 1 | 2 | 3 | 4 | 5 | 6, raw: string, slugger) {
let { text, id, html_attrs } = parse_attributes(raw);
if (! id) {
id = slugger.slug(text);
html_attrs.push(`id="${id}"`);
}
return `
<h${level} ${html_attrs.join(' ')}>
${text}
<a class="heading-anchor" href="#${id}">
${icons.link}
<span style="display: none">Section titled ${text}</span>
</a>
</h${level}>
`;
};
}
function code(renderer: marked.Renderer, opts: MarkdownOptions) {
return function(code: string, infostring: string, is_escaped: boolean) {
const args = parse_code_args(infostring);
if (! args || ! args[0]) {
return `<pre class="language-txt"><code>${escape(code, is_escaped)}</code></pre>`;
}
let caption = '';
const flags = new Set<string>();
for (let i = 1; i < args.length; i++) {
if (args[i][0] === ':') {
flags.add(args[i]);
}
else {
caption = `<figcaption>${marked.parseInline(args[i], renderer.options)}</figcaption>`;
break;
}
}
const size
= flags.has(':small') ? 'small'
: flags.has(':medium') ? 'medium'
: flags.has(':large') ? 'large'
: flags.has(':full') ? 'full'
: 'medium';
const figure = (content: string) => `<figure data-lang="${args[0]}" data-size="${size}">${content}${caption}</figure>`;
if (args[0].startsWith('http:')) {
return render_http_with_content(code, args[0].slice(5));
}
switch (args[0]) {
case 'samp':
return figure(`<pre class="language-txt"><samp>${escape(code, is_escaped)}</samp></pre>`);
case 'bash:samp': {
// Find the first newline that is not preceeded by a "\"
const end_of_input = /(?<!\\)(?:\r\n|\r|\n)/.exec(code);
// If there is no such newline, the whole content is input
if (! end_of_input) {
return figure(`<pre class="language-bash">${render_prism(code, 'bash')}</pre>`);
}
const input = code.slice(0, end_of_input.index);
const rendered_input = render_prism(input, 'bash');
const output = code.slice(end_of_input.index + 1);
const rendered_output = `<samp>${escape(output, is_escaped)}</samp>`;
return figure(`<pre class="language-bash">${rendered_input}\n${rendered_output}</pre>`);
};
case 'katex': {
const katex_opts: KatexOptions = {
displayMode: true, // true == "block"
output: 'html',
macros: opts.katex_macros,
};
return figure(
(katex as any).renderToString(code, katex_opts)
);
};
case 'nomnoml': {
const svg = render_nomnoml(code);
return figure(post_process_nomnoml_svg(svg));
};
case 'clojure:bytefield': {
const svg = render_bytefield(code);
return figure(post_process_bytefield_svg(svg));
};
case 'pikchr': {
const svg = pikchr(code);
return figure(post_process_pikchr_svg(svg));
};
case 'qrcode': {
const promise = generate_qr_code(code);
const async_binding = bind_data_async(promise);
return figure(async_binding);
};
case 'yaml:mecard': {
const parsed = parse_yaml(code);
const promise = generate_mecard_qr_code(parsed);
const async_binding = bind_data_async(promise);
return figure(async_binding);
};
case 'json:vega': {
const spec = JSON.parse(code);
const promise = render_vega_spec(spec);
const binding = bind_data_async(promise);
return figure(binding);
};
case 'yaml:vega': {
const spec = parse_yaml(code);
const promise = render_vega_spec(spec);
const binding = bind_data_async(promise);
return figure(binding);
};
default:
return figure(`<pre class="language-${args[0] || 'txt'}">${render_prism(code, args[0])}</pre>`);
}
function render_http_with_content(code: string, lang: string) {
// Find the first double newline
const end_of_header = /(?:\r\n|\r|\n)(?:\r\n|\r|\n)/.exec(code);
// If there is no such newline, the whole content is HTTP header
if (! end_of_header) {
return figure(`<pre class="language-http">${render_prism(code, 'http')}</pre>`);
}
const header = code.slice(0, end_of_header.index);
const rendered_header = render_prism(header, 'http', true);
const content = code.slice(end_of_header.index + 1);
const rendered_content = render_prism(content, lang, true);
return figure(`<pre class="language-http language-${lang}">${rendered_header}\n${rendered_content}</pre>`);
}
function render_prism(code: string, lang: string, include_class = false) {
const out = highlight(code, lang);
if (out != null && out !== code) {
is_escaped = true;
code = out;
}
const classname = include_class ? `class="language-${lang}"` : '';
return `<code ${classname}>${escape(code, is_escaped)}</code>`;
}
};
}
const arg_pattern = /^(?:[a-zA-Z0-9_:-]+|"(?:[^"\n]|(?<=\\)")*")/;
function parse_code_args(text: string) {
const args: string[] = [ ];
text = text.trim();
while (text.length) {
const match = arg_pattern.exec(text);
if (! match) {
break;
}
if (match[0][0] === '"') {
args.push(match[0].slice(1, -1));
}
else {
args.push(match[0]);
}
text = text.slice(match[0].length).trimStart();
}
return args;
}
function escape(str: string, is_escaped: boolean) {
return is_escaped ? str : str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;');
}
const svg_text = /<text /gi
const svg_stroke_000000 = /\bstroke="#000000"/gi;
// todo: css variables
function post_process_bytefield_svg(svg: string, size?: string) {
svg = strip_svg(svg);
svg = svg.replace(svg_text, '<text fill="var(--theme-text-body, currentcolor)" ');
svg = svg.replace(svg_stroke_000000, 'stroke="var(--theme-line, currentcolor)"');
return svg;
}
const svg_fill_33322e = /\bfill="#33322e"/gi;
const svg_fill_eee8d5 = /\bfill="#eee8d5"/gi;
const svg_fill_fdf6e3 = /\bfill="#fdf6e3"/gi;
const svg_stroke_33322e = /\bstroke="#33322E"/gi;
const svg_font_family_helvetica = /\bfont-family="helvetica"/gi;
const svg_nomnoml_filled_arrow_head = /<g fill="#33322E">\s*<path d="([^"]+)">\s*<\/path>\s*<\/g>/gi;
const svg_nomnoml_unfilled_arrow_head = /<path d="([^"]+)">/gi;
// todo: css variables
function post_process_nomnoml_svg(svg: string, size?: string) {
svg = strip_svg(svg);
// nomnoml uses some specific built-in styles for things, which we will be replacing
// with variables (referencing the color themes) that fall back to safe defaults for
// rendering the svg in a context that has css (like an RSS feed or other embedded
// use case)
// default text font
svg = svg.replace(svg_font_family_helvetica, 'font-family="var(--theme-open-sans, helvetica)"');
// root-level boxes background
svg = svg.replace(svg_fill_eee8d5, 'fill="var(--theme-bg-light, transparent)"');
// outlines and relationship lines
svg = svg.replace(svg_stroke_33322e, 'stroke="var(--theme-line, currentcolor)"');
// arrow heads
svg = svg.replace(svg_nomnoml_filled_arrow_head, ($0, $1) => `<path d="${$1}" fill="var(--theme-line, currentcolor)"></path>`);
svg = svg.replace(svg_nomnoml_unfilled_arrow_head, ($0, $1) => `<path d="${$1}" fill="none">`);
// text color
svg = svg.replace(svg_fill_33322e, 'fill="var(--theme-text-body, currentcolor)"');
// nested boxes background
svg = svg.replace(svg_fill_fdf6e3, 'fill="var(--theme-bg-heavy, transparent)"');
return svg;
}
const svg_text_fill_rgb_000 = /\b<text fill="rgb\(0,0,0\)"/gi;
const svg_fill_rgb_000 = /fill:rgb\(0,0,0\)/gi;
const svg_stroke_rgb_000 = /stroke:rgb\(0,0,0\)/gi;
// todo: css variables
function post_process_pikchr_svg(svg: string, size?: string) {
svg = strip_svg(svg);
// text
svg = svg.replace(svg_text_fill_rgb_000, '<text fill="var(--theme-text-body, currentcolor)"');
// arrow heads
svg = svg.replace(svg_fill_rgb_000, 'fill:var(--theme-line, currentcolor)');
// lines / boxes
svg = svg.replace(svg_stroke_rgb_000, 'stroke:var(--theme-line, currentcolor)');
return svg;
}

37
src/section.ts Normal file
View File

@ -0,0 +1,37 @@
import { marked } from 'marked';
import { ParsedAttributes, parse_attributes } from './attrs';
import { MarkdownOptions } from './render';
export interface SectionToken extends marked.Tokens.Generic {
text: string;
attrs: ParsedAttributes;
}
export function section_ext(renderer: marked.Renderer, opts: MarkdownOptions) : marked.TokenizerExtension & marked.RendererExtension {
return {
name: 'section',
level: 'block',
start: (src) => src.match(/^!!!/)?.index,
tokenizer(src, tokens) {
const rule = /^!!!(!*)([^\n]+)?(?:\n)((?:[^!]|!!?(?!!\1))+)!!!\1/;
const match = rule.exec(src);
if (match) {
const token: SectionToken = {
type: 'section',
raw: match[0],
text: match[3],
attrs: parse_attributes(match[2] || ''),
tokens: [ ],
};
this.lexer.blockTokens(match[3], token.tokens);
return token;
}
},
renderer(token: SectionToken) {
return `<section ${token.attrs.html_attrs.join(' ')}>${this.parser.parse(token.tokens)}</section>`;
}
};
}

12
src/svg.ts Normal file
View File

@ -0,0 +1,12 @@
const svg_header = /^<\?xml version="1\.0" encoding="UTF-8"\?>/;
const svg_dimensions = /^<svg[^>]* (height="[\d\.]+"\s+width="[\d\.]+"|width="[\d\.]+"\s+height="[\d\.]+")/;
// Removes fixed dimension attributes and meta-declaration from SVGs so we can scale them with CSS
export function strip_svg(svg: string) {
return svg
.replace(svg_header, '')
.replace(svg_dimensions, (match, dimensions) => {
return match.slice(0, -dimensions.length);
});
}

28
src/vega/data-colors.ts Normal file
View File

@ -0,0 +1,28 @@
// note: fallback colors come from "category10" scheme
// https://vega.github.io/vega/docs/schemes/#category10
// todo: css variables
export const chart_data_colors = [
'var(--theme-chart-data-0, #1f77b4)',
'var(--theme-chart-data-1, #ff7f0e)',
'var(--theme-chart-data-2, #2ca02c)',
'var(--theme-chart-data-3, #d62728)',
'var(--theme-chart-data-4, #9467bd)',
'var(--theme-chart-data-5, #8c564b)',
'var(--theme-chart-data-6, #e377c2)',
'var(--theme-chart-data-7, #7f7f7f)',
'var(--theme-chart-data-8, #bcbd22)',
'var(--theme-chart-data-9, #17becf)',
];
export function* chart_data_color_generator() : Generator<string, never> {
let next = 0;
while (true) {
yield chart_data_colors[next++];
if (next >= chart_data_colors.length) {
next = 0;
}
}
}

15
src/vega/index.ts Normal file
View File

@ -0,0 +1,15 @@
import { Spec, View } from 'vega';
import { strip_svg } from '../svg';
import { parse_vega_spec } from './vega-spec';
export async function render_vega_spec(spec: Spec) {
const runtime = parse_vega_spec(spec);
const view = new View(runtime, { renderer: 'none' });
let svg = await view.toSVG();
svg = strip_svg(svg);
return svg;
}

39
src/vega/vega-spec.ts Normal file
View File

@ -0,0 +1,39 @@
import * as vega from 'vega';
import { chart_data_color_generator } from './data-colors';
// todo: css variables
export function parse_vega_spec(spec: vega.Spec) {
const config: vega.Config = {
rect: {
fill: 'var(--theme-line, currentcolor)',
},
text: {
font: 'var(--font-open-sans, sans-serif)',
fill: 'var(--theme-text-body, currentcolor)',
},
axis: {
labelFont: 'var(--font-open-sans, sans-serif)',
labelColor: 'var(--theme-text-body, currentcolor)',
domainColor: 'var(--theme-line, currentcolor)',
gridColor: 'var(--theme-line, currentcolor)',
tickColor: 'var(--theme-line, currentcolor)',
}
};
if (spec.marks) {
const colors = chart_data_color_generator();
for (const mark of spec.marks) {
switch (mark.type) {
case 'rect':
mark.encode.enter.fill = { value: colors.next().value };
break;
// todo: apply colors to more mark types
}
}
}
return vega.parse(spec, config);
}

27
tsconfig.json Normal file
View File

@ -0,0 +1,27 @@
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"outDir": "build",
"rootDir": "src",
"declaration": true,
"sourceMap": true,
"declarationMap": false,
"incremental": true,
"moduleResolution": "node",
"typeRoots": [
"node_modules/@types/"
],
"tsBuildInfoFile": "build/.tsbuildinfo",
"lib": [
"es2020"
]
},
"exclude": [
"node_modules",
"build"
],
"include": [
"src/**/*.ts"
]
}

289
vendor/feather-icons/icons.json vendored Normal file
View File

@ -0,0 +1,289 @@
{
"activity": "<polyline points=\"22 12 18 12 15 21 9 3 6 12 2 12\"></polyline>",
"airplay": "<path d=\"M5 17H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-1\"></path><polygon points=\"12 15 17 21 7 21 12 15\"></polygon>",
"alert-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line>",
"alert-octagon": "<polygon points=\"7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2\"></polygon><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"></line>",
"alert-triangle": "<path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"></path><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\"></line><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"></line>",
"align-center": "<line x1=\"18\" y1=\"10\" x2=\"6\" y2=\"10\"></line><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"></line><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"></line><line x1=\"18\" y1=\"18\" x2=\"6\" y2=\"18\"></line>",
"align-justify": "<line x1=\"21\" y1=\"10\" x2=\"3\" y2=\"10\"></line><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"></line><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"></line><line x1=\"21\" y1=\"18\" x2=\"3\" y2=\"18\"></line>",
"align-left": "<line x1=\"17\" y1=\"10\" x2=\"3\" y2=\"10\"></line><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"></line><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"></line><line x1=\"17\" y1=\"18\" x2=\"3\" y2=\"18\"></line>",
"align-right": "<line x1=\"21\" y1=\"10\" x2=\"7\" y2=\"10\"></line><line x1=\"21\" y1=\"6\" x2=\"3\" y2=\"6\"></line><line x1=\"21\" y1=\"14\" x2=\"3\" y2=\"14\"></line><line x1=\"21\" y1=\"18\" x2=\"7\" y2=\"18\"></line>",
"anchor": "<circle cx=\"12\" cy=\"5\" r=\"3\"></circle><line x1=\"12\" y1=\"22\" x2=\"12\" y2=\"8\"></line><path d=\"M5 12H2a10 10 0 0 0 20 0h-3\"></path>",
"aperture": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"14.31\" y1=\"8\" x2=\"20.05\" y2=\"17.94\"></line><line x1=\"9.69\" y1=\"8\" x2=\"21.17\" y2=\"8\"></line><line x1=\"7.38\" y1=\"12\" x2=\"13.12\" y2=\"2.06\"></line><line x1=\"9.69\" y1=\"16\" x2=\"3.95\" y2=\"6.06\"></line><line x1=\"14.31\" y1=\"16\" x2=\"2.83\" y2=\"16\"></line><line x1=\"16.62\" y1=\"12\" x2=\"10.88\" y2=\"21.94\"></line>",
"archive": "<polyline points=\"21 8 21 21 3 21 3 8\"></polyline><rect x=\"1\" y=\"3\" width=\"22\" height=\"5\"></rect><line x1=\"10\" y1=\"12\" x2=\"14\" y2=\"12\"></line>",
"arrow-down-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"8 12 12 16 16 12\"></polyline><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"16\"></line>",
"arrow-down-left": "<line x1=\"17\" y1=\"7\" x2=\"7\" y2=\"17\"></line><polyline points=\"17 17 7 17 7 7\"></polyline>",
"arrow-down-right": "<line x1=\"7\" y1=\"7\" x2=\"17\" y2=\"17\"></line><polyline points=\"17 7 17 17 7 17\"></polyline>",
"arrow-down": "<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line><polyline points=\"19 12 12 19 5 12\"></polyline>",
"arrow-left-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"12 8 8 12 12 16\"></polyline><line x1=\"16\" y1=\"12\" x2=\"8\" y2=\"12\"></line>",
"arrow-left": "<line x1=\"19\" y1=\"12\" x2=\"5\" y2=\"12\"></line><polyline points=\"12 19 5 12 12 5\"></polyline>",
"arrow-right-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"12 16 16 12 12 8\"></polyline><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"arrow-right": "<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line><polyline points=\"12 5 19 12 12 19\"></polyline>",
"arrow-up-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"16 12 12 8 8 12\"></polyline><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"8\"></line>",
"arrow-up-left": "<line x1=\"17\" y1=\"17\" x2=\"7\" y2=\"7\"></line><polyline points=\"7 17 7 7 17 7\"></polyline>",
"arrow-up-right": "<line x1=\"7\" y1=\"17\" x2=\"17\" y2=\"7\"></line><polyline points=\"7 7 17 7 17 17\"></polyline>",
"arrow-up": "<line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"5\"></line><polyline points=\"5 12 12 5 19 12\"></polyline>",
"at-sign": "<circle cx=\"12\" cy=\"12\" r=\"4\"></circle><path d=\"M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94\"></path>",
"award": "<circle cx=\"12\" cy=\"8\" r=\"7\"></circle><polyline points=\"8.21 13.89 7 23 12 20 17 23 15.79 13.88\"></polyline>",
"bar-chart-2": "<line x1=\"18\" y1=\"20\" x2=\"18\" y2=\"10\"></line><line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"4\"></line><line x1=\"6\" y1=\"20\" x2=\"6\" y2=\"14\"></line>",
"bar-chart": "<line x1=\"12\" y1=\"20\" x2=\"12\" y2=\"10\"></line><line x1=\"18\" y1=\"20\" x2=\"18\" y2=\"4\"></line><line x1=\"6\" y1=\"20\" x2=\"6\" y2=\"16\"></line>",
"battery-charging": "<path d=\"M5 18H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h3.19M15 6h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-3.19\"></path><line x1=\"23\" y1=\"13\" x2=\"23\" y2=\"11\"></line><polyline points=\"11 6 7 12 13 12 9 18\"></polyline>",
"battery": "<rect x=\"1\" y=\"6\" width=\"18\" height=\"12\" rx=\"2\" ry=\"2\"></rect><line x1=\"23\" y1=\"13\" x2=\"23\" y2=\"11\"></line>",
"bell-off": "<path d=\"M13.73 21a2 2 0 0 1-3.46 0\"></path><path d=\"M18.63 13A17.89 17.89 0 0 1 18 8\"></path><path d=\"M6.26 6.26A5.86 5.86 0 0 0 6 8c0 7-3 9-3 9h14\"></path><path d=\"M18 8a6 6 0 0 0-9.33-5\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"bell": "<path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"></path><path d=\"M13.73 21a2 2 0 0 1-3.46 0\"></path>",
"bluetooth": "<polyline points=\"6.5 6.5 17.5 17.5 12 23 12 1 17.5 6.5 6.5 17.5\"></polyline>",
"bold": "<path d=\"M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"></path><path d=\"M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z\"></path>",
"book-open": "<path d=\"M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z\"></path><path d=\"M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z\"></path>",
"book": "<path d=\"M4 19.5A2.5 2.5 0 0 1 6.5 17H20\"></path><path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z\"></path>",
"bookmark": "<path d=\"M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z\"></path>",
"box": "<path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"></path><polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"></polyline><line x1=\"12\" y1=\"22.08\" x2=\"12\" y2=\"12\"></line>",
"briefcase": "<rect x=\"2\" y=\"7\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"></rect><path d=\"M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16\"></path>",
"calendar": "<rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"></line><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"></line><line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"></line>",
"camera-off": "<line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line><path d=\"M21 21H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h3m3-3h6l2 3h4a2 2 0 0 1 2 2v9.34m-7.72-2.06a4 4 0 1 1-5.56-5.56\"></path>",
"camera": "<path d=\"M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z\"></path><circle cx=\"12\" cy=\"13\" r=\"4\"></circle>",
"cast": "<path d=\"M2 16.1A5 5 0 0 1 5.9 20M2 12.05A9 9 0 0 1 9.95 20M2 8V6a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6\"></path><line x1=\"2\" y1=\"20\" x2=\"2.01\" y2=\"20\"></line>",
"check-circle": "<path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path><polyline points=\"22 4 12 14.01 9 11.01\"></polyline>",
"check-square": "<polyline points=\"9 11 12 14 22 4\"></polyline><path d=\"M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11\"></path>",
"check": "<polyline points=\"20 6 9 17 4 12\"></polyline>",
"chevron-down": "<polyline points=\"6 9 12 15 18 9\"></polyline>",
"chevron-left": "<polyline points=\"15 18 9 12 15 6\"></polyline>",
"chevron-right": "<polyline points=\"9 18 15 12 9 6\"></polyline>",
"chevron-up": "<polyline points=\"18 15 12 9 6 15\"></polyline>",
"chevrons-down": "<polyline points=\"7 13 12 18 17 13\"></polyline><polyline points=\"7 6 12 11 17 6\"></polyline>",
"chevrons-left": "<polyline points=\"11 17 6 12 11 7\"></polyline><polyline points=\"18 17 13 12 18 7\"></polyline>",
"chevrons-right": "<polyline points=\"13 17 18 12 13 7\"></polyline><polyline points=\"6 17 11 12 6 7\"></polyline>",
"chevrons-up": "<polyline points=\"17 11 12 6 7 11\"></polyline><polyline points=\"17 18 12 13 7 18\"></polyline>",
"chrome": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><circle cx=\"12\" cy=\"12\" r=\"4\"></circle><line x1=\"21.17\" y1=\"8\" x2=\"12\" y2=\"8\"></line><line x1=\"3.95\" y1=\"6.06\" x2=\"8.54\" y2=\"14\"></line><line x1=\"10.88\" y1=\"21.94\" x2=\"15.46\" y2=\"14\"></line>",
"circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle>",
"clipboard": "<path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"></path><rect x=\"8\" y=\"2\" width=\"8\" height=\"4\" rx=\"1\" ry=\"1\"></rect>",
"clock": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polyline points=\"12 6 12 12 16 14\"></polyline>",
"cloud-drizzle": "<line x1=\"8\" y1=\"19\" x2=\"8\" y2=\"21\"></line><line x1=\"8\" y1=\"13\" x2=\"8\" y2=\"15\"></line><line x1=\"16\" y1=\"19\" x2=\"16\" y2=\"21\"></line><line x1=\"16\" y1=\"13\" x2=\"16\" y2=\"15\"></line><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"></line><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"17\"></line><path d=\"M20 16.58A5 5 0 0 0 18 7h-1.26A8 8 0 1 0 4 15.25\"></path>",
"cloud-lightning": "<path d=\"M19 16.9A5 5 0 0 0 18 7h-1.26a8 8 0 1 0-11.62 9\"></path><polyline points=\"13 11 9 17 15 17 11 23\"></polyline>",
"cloud-off": "<path d=\"M22.61 16.95A5 5 0 0 0 18 10h-1.26a8 8 0 0 0-7.05-6M5 5a8 8 0 0 0 4 15h9a5 5 0 0 0 1.7-.3\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"cloud-rain": "<line x1=\"16\" y1=\"13\" x2=\"16\" y2=\"21\"></line><line x1=\"8\" y1=\"13\" x2=\"8\" y2=\"21\"></line><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"23\"></line><path d=\"M20 16.58A5 5 0 0 0 18 7h-1.26A8 8 0 1 0 4 15.25\"></path>",
"cloud-snow": "<path d=\"M20 17.58A5 5 0 0 0 18 8h-1.26A8 8 0 1 0 4 16.25\"></path><line x1=\"8\" y1=\"16\" x2=\"8.01\" y2=\"16\"></line><line x1=\"8\" y1=\"20\" x2=\"8.01\" y2=\"20\"></line><line x1=\"12\" y1=\"18\" x2=\"12.01\" y2=\"18\"></line><line x1=\"12\" y1=\"22\" x2=\"12.01\" y2=\"22\"></line><line x1=\"16\" y1=\"16\" x2=\"16.01\" y2=\"16\"></line><line x1=\"16\" y1=\"20\" x2=\"16.01\" y2=\"20\"></line>",
"cloud": "<path d=\"M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z\"></path>",
"code": "<polyline points=\"16 18 22 12 16 6\"></polyline><polyline points=\"8 6 2 12 8 18\"></polyline>",
"codepen": "<polygon points=\"12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2\"></polygon><line x1=\"12\" y1=\"22\" x2=\"12\" y2=\"15.5\"></line><polyline points=\"22 8.5 12 15.5 2 8.5\"></polyline><polyline points=\"2 15.5 12 8.5 22 15.5\"></polyline><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"8.5\"></line>",
"codesandbox": "<path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"></path><polyline points=\"7.5 4.21 12 6.81 16.5 4.21\"></polyline><polyline points=\"7.5 19.79 7.5 14.6 3 12\"></polyline><polyline points=\"21 12 16.5 14.6 16.5 19.79\"></polyline><polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"></polyline><line x1=\"12\" y1=\"22.08\" x2=\"12\" y2=\"12\"></line>",
"coffee": "<path d=\"M18 8h1a4 4 0 0 1 0 8h-1\"></path><path d=\"M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z\"></path><line x1=\"6\" y1=\"1\" x2=\"6\" y2=\"4\"></line><line x1=\"10\" y1=\"1\" x2=\"10\" y2=\"4\"></line><line x1=\"14\" y1=\"1\" x2=\"14\" y2=\"4\"></line>",
"columns": "<path d=\"M12 3h7a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-7m0-18H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h7m0-18v18\"></path>",
"command": "<path d=\"M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z\"></path>",
"compass": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polygon points=\"16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76\"></polygon>",
"copy": "<rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path>",
"corner-down-left": "<polyline points=\"9 10 4 15 9 20\"></polyline><path d=\"M20 4v7a4 4 0 0 1-4 4H4\"></path>",
"corner-down-right": "<polyline points=\"15 10 20 15 15 20\"></polyline><path d=\"M4 4v7a4 4 0 0 0 4 4h12\"></path>",
"corner-left-down": "<polyline points=\"14 15 9 20 4 15\"></polyline><path d=\"M20 4h-7a4 4 0 0 0-4 4v12\"></path>",
"corner-left-up": "<polyline points=\"14 9 9 4 4 9\"></polyline><path d=\"M20 20h-7a4 4 0 0 1-4-4V4\"></path>",
"corner-right-down": "<polyline points=\"10 15 15 20 20 15\"></polyline><path d=\"M4 4h7a4 4 0 0 1 4 4v12\"></path>",
"corner-right-up": "<polyline points=\"10 9 15 4 20 9\"></polyline><path d=\"M4 20h7a4 4 0 0 0 4-4V4\"></path>",
"corner-up-left": "<polyline points=\"9 14 4 9 9 4\"></polyline><path d=\"M20 20v-7a4 4 0 0 0-4-4H4\"></path>",
"corner-up-right": "<polyline points=\"15 14 20 9 15 4\"></polyline><path d=\"M4 20v-7a4 4 0 0 1 4-4h12\"></path>",
"cpu": "<rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\" ry=\"2\"></rect><rect x=\"9\" y=\"9\" width=\"6\" height=\"6\"></rect><line x1=\"9\" y1=\"1\" x2=\"9\" y2=\"4\"></line><line x1=\"15\" y1=\"1\" x2=\"15\" y2=\"4\"></line><line x1=\"9\" y1=\"20\" x2=\"9\" y2=\"23\"></line><line x1=\"15\" y1=\"20\" x2=\"15\" y2=\"23\"></line><line x1=\"20\" y1=\"9\" x2=\"23\" y2=\"9\"></line><line x1=\"20\" y1=\"14\" x2=\"23\" y2=\"14\"></line><line x1=\"1\" y1=\"9\" x2=\"4\" y2=\"9\"></line><line x1=\"1\" y1=\"14\" x2=\"4\" y2=\"14\"></line>",
"credit-card": "<rect x=\"1\" y=\"4\" width=\"22\" height=\"16\" rx=\"2\" ry=\"2\"></rect><line x1=\"1\" y1=\"10\" x2=\"23\" y2=\"10\"></line>",
"crop": "<path d=\"M6.13 1L6 16a2 2 0 0 0 2 2h15\"></path><path d=\"M1 6.13L16 6a2 2 0 0 1 2 2v15\"></path>",
"crosshair": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"22\" y1=\"12\" x2=\"18\" y2=\"12\"></line><line x1=\"6\" y1=\"12\" x2=\"2\" y2=\"12\"></line><line x1=\"12\" y1=\"6\" x2=\"12\" y2=\"2\"></line><line x1=\"12\" y1=\"22\" x2=\"12\" y2=\"18\"></line>",
"database": "<ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"></ellipse><path d=\"M21 12c0 1.66-4 3-9 3s-9-1.34-9-3\"></path><path d=\"M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5\"></path>",
"delete": "<path d=\"M21 4H8l-7 8 7 8h13a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z\"></path><line x1=\"18\" y1=\"9\" x2=\"12\" y2=\"15\"></line><line x1=\"12\" y1=\"9\" x2=\"18\" y2=\"15\"></line>",
"disc": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><circle cx=\"12\" cy=\"12\" r=\"3\"></circle>",
"divide-circle": "<line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"16\"></line><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"8\"></line><circle cx=\"12\" cy=\"12\" r=\"10\"></circle>",
"divide-square": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"16\"></line><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"8\"></line>",
"divide": "<circle cx=\"12\" cy=\"6\" r=\"2\"></circle><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line><circle cx=\"12\" cy=\"18\" r=\"2\"></circle>",
"dollar-sign": "<line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"23\"></line><path d=\"M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6\"></path>",
"download-cloud": "<polyline points=\"8 17 12 21 16 17\"></polyline><line x1=\"12\" y1=\"12\" x2=\"12\" y2=\"21\"></line><path d=\"M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29\"></path>",
"download": "<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path><polyline points=\"7 10 12 15 17 10\"></polyline><line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"></line>",
"dribbble": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M8.56 2.75c4.37 6.03 6.02 9.42 8.03 17.72m2.54-15.38c-3.72 4.35-8.94 5.66-16.88 5.85m19.5 1.9c-3.5-.93-6.63-.82-8.94 0-2.58.92-5.01 2.86-7.44 6.32\"></path>",
"droplet": "<path d=\"M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z\"></path>",
"edit-2": "<path d=\"M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z\"></path>",
"edit-3": "<path d=\"M12 20h9\"></path><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z\"></path>",
"edit": "<path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\"></path><path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\"></path>",
"external-link": "<path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\"></path><polyline points=\"15 3 21 3 21 9\"></polyline><line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\"></line>",
"eye-off": "<path d=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"eye": "<path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"></path><circle cx=\"12\" cy=\"12\" r=\"3\"></circle>",
"facebook": "<path d=\"M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z\"></path>",
"fast-forward": "<polygon points=\"13 19 22 12 13 5 13 19\"></polygon><polygon points=\"2 19 11 12 2 5 2 19\"></polygon>",
"feather": "<path d=\"M20.24 12.24a6 6 0 0 0-8.49-8.49L5 10.5V19h8.5z\"></path><line x1=\"16\" y1=\"8\" x2=\"2\" y2=\"22\"></line><line x1=\"17.5\" y1=\"15\" x2=\"9\" y2=\"15\"></line>",
"figma": "<path d=\"M5 5.5A3.5 3.5 0 0 1 8.5 2H12v7H8.5A3.5 3.5 0 0 1 5 5.5z\"></path><path d=\"M12 2h3.5a3.5 3.5 0 1 1 0 7H12V2z\"></path><path d=\"M12 12.5a3.5 3.5 0 1 1 7 0 3.5 3.5 0 1 1-7 0z\"></path><path d=\"M5 19.5A3.5 3.5 0 0 1 8.5 16H12v3.5a3.5 3.5 0 1 1-7 0z\"></path><path d=\"M5 12.5A3.5 3.5 0 0 1 8.5 9H12v7H8.5A3.5 3.5 0 0 1 5 12.5z\"></path>",
"file-minus": "<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path><polyline points=\"14 2 14 8 20 8\"></polyline><line x1=\"9\" y1=\"15\" x2=\"15\" y2=\"15\"></line>",
"file-plus": "<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path><polyline points=\"14 2 14 8 20 8\"></polyline><line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"12\"></line><line x1=\"9\" y1=\"15\" x2=\"15\" y2=\"15\"></line>",
"file-text": "<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\"></path><polyline points=\"14 2 14 8 20 8\"></polyline><line x1=\"16\" y1=\"13\" x2=\"8\" y2=\"13\"></line><line x1=\"16\" y1=\"17\" x2=\"8\" y2=\"17\"></line><polyline points=\"10 9 9 9 8 9\"></polyline>",
"file": "<path d=\"M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z\"></path><polyline points=\"13 2 13 9 20 9\"></polyline>",
"film": "<rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"2.18\" ry=\"2.18\"></rect><line x1=\"7\" y1=\"2\" x2=\"7\" y2=\"22\"></line><line x1=\"17\" y1=\"2\" x2=\"17\" y2=\"22\"></line><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"></line><line x1=\"2\" y1=\"7\" x2=\"7\" y2=\"7\"></line><line x1=\"2\" y1=\"17\" x2=\"7\" y2=\"17\"></line><line x1=\"17\" y1=\"17\" x2=\"22\" y2=\"17\"></line><line x1=\"17\" y1=\"7\" x2=\"22\" y2=\"7\"></line>",
"filter": "<polygon points=\"22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3\"></polygon>",
"flag": "<path d=\"M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z\"></path><line x1=\"4\" y1=\"22\" x2=\"4\" y2=\"15\"></line>",
"folder-minus": "<path d=\"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z\"></path><line x1=\"9\" y1=\"14\" x2=\"15\" y2=\"14\"></line>",
"folder-plus": "<path d=\"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z\"></path><line x1=\"12\" y1=\"11\" x2=\"12\" y2=\"17\"></line><line x1=\"9\" y1=\"14\" x2=\"15\" y2=\"14\"></line>",
"folder": "<path d=\"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z\"></path>",
"framer": "<path d=\"M5 16V9h14V2H5l14 14h-7m-7 0l7 7v-7m-7 0h7\"></path>",
"frown": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M16 16s-1.5-2-4-2-4 2-4 2\"></path><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\"></line><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\"></line>",
"gift": "<polyline points=\"20 12 20 22 4 22 4 12\"></polyline><rect x=\"2\" y=\"7\" width=\"20\" height=\"5\"></rect><line x1=\"12\" y1=\"22\" x2=\"12\" y2=\"7\"></line><path d=\"M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z\"></path><path d=\"M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z\"></path>",
"git-branch": "<line x1=\"6\" y1=\"3\" x2=\"6\" y2=\"15\"></line><circle cx=\"18\" cy=\"6\" r=\"3\"></circle><circle cx=\"6\" cy=\"18\" r=\"3\"></circle><path d=\"M18 9a9 9 0 0 1-9 9\"></path>",
"git-commit": "<circle cx=\"12\" cy=\"12\" r=\"4\"></circle><line x1=\"1.05\" y1=\"12\" x2=\"7\" y2=\"12\"></line><line x1=\"17.01\" y1=\"12\" x2=\"22.96\" y2=\"12\"></line>",
"git-merge": "<circle cx=\"18\" cy=\"18\" r=\"3\"></circle><circle cx=\"6\" cy=\"6\" r=\"3\"></circle><path d=\"M6 21V9a9 9 0 0 0 9 9\"></path>",
"git-pull-request": "<circle cx=\"18\" cy=\"18\" r=\"3\"></circle><circle cx=\"6\" cy=\"6\" r=\"3\"></circle><path d=\"M13 6h3a2 2 0 0 1 2 2v7\"></path><line x1=\"6\" y1=\"9\" x2=\"6\" y2=\"21\"></line>",
"github": "<path d=\"M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22\"></path>",
"gitlab": "<path d=\"M22.65 14.39L12 22.13 1.35 14.39a.84.84 0 0 1-.3-.94l1.22-3.78 2.44-7.51A.42.42 0 0 1 4.82 2a.43.43 0 0 1 .58 0 .42.42 0 0 1 .11.18l2.44 7.49h8.1l2.44-7.51A.42.42 0 0 1 18.6 2a.43.43 0 0 1 .58 0 .42.42 0 0 1 .11.18l2.44 7.51L23 13.45a.84.84 0 0 1-.35.94z\"></path>",
"globe": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"></line><path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"></path>",
"grid": "<rect x=\"3\" y=\"3\" width=\"7\" height=\"7\"></rect><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\"></rect><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\"></rect><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\"></rect>",
"hard-drive": "<line x1=\"22\" y1=\"12\" x2=\"2\" y2=\"12\"></line><path d=\"M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\"></path><line x1=\"6\" y1=\"16\" x2=\"6.01\" y2=\"16\"></line><line x1=\"10\" y1=\"16\" x2=\"10.01\" y2=\"16\"></line>",
"hash": "<line x1=\"4\" y1=\"9\" x2=\"20\" y2=\"9\"></line><line x1=\"4\" y1=\"15\" x2=\"20\" y2=\"15\"></line><line x1=\"10\" y1=\"3\" x2=\"8\" y2=\"21\"></line><line x1=\"16\" y1=\"3\" x2=\"14\" y2=\"21\"></line>",
"headphones": "<path d=\"M3 18v-6a9 9 0 0 1 18 0v6\"></path><path d=\"M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z\"></path>",
"heart": "<path d=\"M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z\"></path>",
"help-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"></path><line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\"></line>",
"hexagon": "<path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"></path>",
"home": "<path d=\"M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\"></path><polyline points=\"9 22 9 12 15 12 15 22\"></polyline>",
"image": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"></circle><polyline points=\"21 15 16 10 5 21\"></polyline>",
"inbox": "<polyline points=\"22 12 16 12 14 15 10 15 8 12 2 12\"></polyline><path d=\"M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\"></path>",
"info": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\"></line>",
"instagram": "<rect x=\"2\" y=\"2\" width=\"20\" height=\"20\" rx=\"5\" ry=\"5\"></rect><path d=\"M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z\"></path><line x1=\"17.5\" y1=\"6.5\" x2=\"17.51\" y2=\"6.5\"></line>",
"italic": "<line x1=\"19\" y1=\"4\" x2=\"10\" y2=\"4\"></line><line x1=\"14\" y1=\"20\" x2=\"5\" y2=\"20\"></line><line x1=\"15\" y1=\"4\" x2=\"9\" y2=\"20\"></line>",
"key": "<path d=\"M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4\"></path>",
"layers": "<polygon points=\"12 2 2 7 12 12 22 7 12 2\"></polygon><polyline points=\"2 17 12 22 22 17\"></polyline><polyline points=\"2 12 12 17 22 12\"></polyline>",
"layout": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"></line><line x1=\"9\" y1=\"21\" x2=\"9\" y2=\"9\"></line>",
"life-buoy": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><circle cx=\"12\" cy=\"12\" r=\"4\"></circle><line x1=\"4.93\" y1=\"4.93\" x2=\"9.17\" y2=\"9.17\"></line><line x1=\"14.83\" y1=\"14.83\" x2=\"19.07\" y2=\"19.07\"></line><line x1=\"14.83\" y1=\"9.17\" x2=\"19.07\" y2=\"4.93\"></line><line x1=\"14.83\" y1=\"9.17\" x2=\"18.36\" y2=\"5.64\"></line><line x1=\"4.93\" y1=\"19.07\" x2=\"9.17\" y2=\"14.83\"></line>",
"link-2": "<path d=\"M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3\"></path><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"link": "<path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\"></path><path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\"></path>",
"linkedin": "<path d=\"M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z\"></path><rect x=\"2\" y=\"9\" width=\"4\" height=\"12\"></rect><circle cx=\"4\" cy=\"4\" r=\"2\"></circle>",
"list": "<line x1=\"8\" y1=\"6\" x2=\"21\" y2=\"6\"></line><line x1=\"8\" y1=\"12\" x2=\"21\" y2=\"12\"></line><line x1=\"8\" y1=\"18\" x2=\"21\" y2=\"18\"></line><line x1=\"3\" y1=\"6\" x2=\"3.01\" y2=\"6\"></line><line x1=\"3\" y1=\"12\" x2=\"3.01\" y2=\"12\"></line><line x1=\"3\" y1=\"18\" x2=\"3.01\" y2=\"18\"></line>",
"loader": "<line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"6\"></line><line x1=\"12\" y1=\"18\" x2=\"12\" y2=\"22\"></line><line x1=\"4.93\" y1=\"4.93\" x2=\"7.76\" y2=\"7.76\"></line><line x1=\"16.24\" y1=\"16.24\" x2=\"19.07\" y2=\"19.07\"></line><line x1=\"2\" y1=\"12\" x2=\"6\" y2=\"12\"></line><line x1=\"18\" y1=\"12\" x2=\"22\" y2=\"12\"></line><line x1=\"4.93\" y1=\"19.07\" x2=\"7.76\" y2=\"16.24\"></line><line x1=\"16.24\" y1=\"7.76\" x2=\"19.07\" y2=\"4.93\"></line>",
"lock": "<rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"></path>",
"log-in": "<path d=\"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4\"></path><polyline points=\"10 17 15 12 10 7\"></polyline><line x1=\"15\" y1=\"12\" x2=\"3\" y2=\"12\"></line>",
"log-out": "<path d=\"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4\"></path><polyline points=\"16 17 21 12 16 7\"></polyline><line x1=\"21\" y1=\"12\" x2=\"9\" y2=\"12\"></line>",
"mail": "<path d=\"M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z\"></path><polyline points=\"22,6 12,13 2,6\"></polyline>",
"map-pin": "<path d=\"M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z\"></path><circle cx=\"12\" cy=\"10\" r=\"3\"></circle>",
"map": "<polygon points=\"1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6\"></polygon><line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"18\"></line><line x1=\"16\" y1=\"6\" x2=\"16\" y2=\"22\"></line>",
"maximize-2": "<polyline points=\"15 3 21 3 21 9\"></polyline><polyline points=\"9 21 3 21 3 15\"></polyline><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\"></line><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"></line>",
"maximize": "<path d=\"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3\"></path>",
"meh": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"8\" y1=\"15\" x2=\"16\" y2=\"15\"></line><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\"></line><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\"></line>",
"menu": "<line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"></line><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line><line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"></line>",
"message-circle": "<path d=\"M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z\"></path>",
"message-square": "<path d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"></path>",
"mic-off": "<line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line><path d=\"M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6\"></path><path d=\"M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23\"></path><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"></line>",
"mic": "<path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"></path><path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path><line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line><line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"></line>",
"minimize-2": "<polyline points=\"4 14 10 14 10 20\"></polyline><polyline points=\"20 10 14 10 14 4\"></polyline><line x1=\"14\" y1=\"10\" x2=\"21\" y2=\"3\"></line><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\"></line>",
"minimize": "<path d=\"M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3\"></path>",
"minus-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"minus-square": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"minus": "<line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line>",
"monitor": "<rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\" ry=\"2\"></rect><line x1=\"8\" y1=\"21\" x2=\"16\" y2=\"21\"></line><line x1=\"12\" y1=\"17\" x2=\"12\" y2=\"21\"></line>",
"moon": "<path d=\"M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z\"></path>",
"more-horizontal": "<circle cx=\"12\" cy=\"12\" r=\"1\"></circle><circle cx=\"19\" cy=\"12\" r=\"1\"></circle><circle cx=\"5\" cy=\"12\" r=\"1\"></circle>",
"more-vertical": "<circle cx=\"12\" cy=\"12\" r=\"1\"></circle><circle cx=\"12\" cy=\"5\" r=\"1\"></circle><circle cx=\"12\" cy=\"19\" r=\"1\"></circle>",
"mouse-pointer": "<path d=\"M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z\"></path><path d=\"M13 13l6 6\"></path>",
"move": "<polyline points=\"5 9 2 12 5 15\"></polyline><polyline points=\"9 5 12 2 15 5\"></polyline><polyline points=\"15 19 12 22 9 19\"></polyline><polyline points=\"19 9 22 12 19 15\"></polyline><line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"></line><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"22\"></line>",
"music": "<path d=\"M9 18V5l12-2v13\"></path><circle cx=\"6\" cy=\"18\" r=\"3\"></circle><circle cx=\"18\" cy=\"16\" r=\"3\"></circle>",
"navigation-2": "<polygon points=\"12 2 19 21 12 17 5 21 12 2\"></polygon>",
"navigation": "<polygon points=\"3 11 22 2 13 21 11 13 3 11\"></polygon>",
"octagon": "<polygon points=\"7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2\"></polygon>",
"package": "<line x1=\"16.5\" y1=\"9.4\" x2=\"7.5\" y2=\"4.21\"></line><path d=\"M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z\"></path><polyline points=\"3.27 6.96 12 12.01 20.73 6.96\"></polyline><line x1=\"12\" y1=\"22.08\" x2=\"12\" y2=\"12\"></line>",
"paperclip": "<path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\"></path>",
"pause-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"10\" y1=\"15\" x2=\"10\" y2=\"9\"></line><line x1=\"14\" y1=\"15\" x2=\"14\" y2=\"9\"></line>",
"pause": "<rect x=\"6\" y=\"4\" width=\"4\" height=\"16\"></rect><rect x=\"14\" y=\"4\" width=\"4\" height=\"16\"></rect>",
"pen-tool": "<path d=\"M12 19l7-7 3 3-7 7-3-3z\"></path><path d=\"M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z\"></path><path d=\"M2 2l7.586 7.586\"></path><circle cx=\"11\" cy=\"11\" r=\"2\"></circle>",
"percent": "<line x1=\"19\" y1=\"5\" x2=\"5\" y2=\"19\"></line><circle cx=\"6.5\" cy=\"6.5\" r=\"2.5\"></circle><circle cx=\"17.5\" cy=\"17.5\" r=\"2.5\"></circle>",
"phone-call": "<path d=\"M15.05 5A5 5 0 0 1 19 8.95M15.05 1A9 9 0 0 1 23 8.94m-1 7.98v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"phone-forwarded": "<polyline points=\"19 1 23 5 19 9\"></polyline><line x1=\"15\" y1=\"5\" x2=\"23\" y2=\"5\"></line><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"phone-incoming": "<polyline points=\"16 2 16 8 22 8\"></polyline><line x1=\"23\" y1=\"1\" x2=\"16\" y2=\"8\"></line><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"phone-missed": "<line x1=\"23\" y1=\"1\" x2=\"17\" y2=\"7\"></line><line x1=\"17\" y1=\"1\" x2=\"23\" y2=\"7\"></line><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"phone-off": "<path d=\"M10.68 13.31a16 16 0 0 0 3.41 2.6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7 2 2 0 0 1 1.72 2v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.42 19.42 0 0 1-3.33-2.67m-2.67-3.34a19.79 19.79 0 0 1-3.07-8.63A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91\"></path><line x1=\"23\" y1=\"1\" x2=\"1\" y2=\"23\"></line>",
"phone-outgoing": "<polyline points=\"23 7 23 1 17 1\"></polyline><line x1=\"16\" y1=\"8\" x2=\"23\" y2=\"1\"></line><path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"phone": "<path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z\"></path>",
"pie-chart": "<path d=\"M21.21 15.89A10 10 0 1 1 8 2.83\"></path><path d=\"M22 12A10 10 0 0 0 12 2v10z\"></path>",
"play-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><polygon points=\"10 8 16 12 10 16 10 8\"></polygon>",
"play": "<polygon points=\"5 3 19 12 5 21 5 3\"></polygon>",
"plus-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"16\"></line><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"plus-square": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"16\"></line><line x1=\"8\" y1=\"12\" x2=\"16\" y2=\"12\"></line>",
"plus": "<line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\"></line><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"></line>",
"pocket": "<path d=\"M4 3h16a2 2 0 0 1 2 2v6a10 10 0 0 1-10 10A10 10 0 0 1 2 11V5a2 2 0 0 1 2-2z\"></path><polyline points=\"8 10 12 14 16 10\"></polyline>",
"power": "<path d=\"M18.36 6.64a9 9 0 1 1-12.73 0\"></path><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"12\"></line>",
"printer": "<polyline points=\"6 9 6 2 18 2 18 9\"></polyline><path d=\"M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2\"></path><rect x=\"6\" y=\"14\" width=\"12\" height=\"8\"></rect>",
"radio": "<circle cx=\"12\" cy=\"12\" r=\"2\"></circle><path d=\"M16.24 7.76a6 6 0 0 1 0 8.49m-8.48-.01a6 6 0 0 1 0-8.49m11.31-2.82a10 10 0 0 1 0 14.14m-14.14 0a10 10 0 0 1 0-14.14\"></path>",
"refresh-ccw": "<polyline points=\"1 4 1 10 7 10\"></polyline><polyline points=\"23 20 23 14 17 14\"></polyline><path d=\"M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15\"></path>",
"refresh-cw": "<polyline points=\"23 4 23 10 17 10\"></polyline><polyline points=\"1 20 1 14 7 14\"></polyline><path d=\"M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15\"></path>",
"repeat": "<polyline points=\"17 1 21 5 17 9\"></polyline><path d=\"M3 11V9a4 4 0 0 1 4-4h14\"></path><polyline points=\"7 23 3 19 7 15\"></polyline><path d=\"M21 13v2a4 4 0 0 1-4 4H3\"></path>",
"rewind": "<polygon points=\"11 19 2 12 11 5 11 19\"></polygon><polygon points=\"22 19 13 12 22 5 22 19\"></polygon>",
"rotate-ccw": "<polyline points=\"1 4 1 10 7 10\"></polyline><path d=\"M3.51 15a9 9 0 1 0 2.13-9.36L1 10\"></path>",
"rotate-cw": "<polyline points=\"23 4 23 10 17 10\"></polyline><path d=\"M20.49 15a9 9 0 1 1-2.12-9.36L23 10\"></path>",
"rss": "<path d=\"M4 11a9 9 0 0 1 9 9\"></path><path d=\"M4 4a16 16 0 0 1 16 16\"></path><circle cx=\"5\" cy=\"19\" r=\"1\"></circle>",
"save": "<path d=\"M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z\"></path><polyline points=\"17 21 17 13 7 13 7 21\"></polyline><polyline points=\"7 3 7 8 15 8\"></polyline>",
"scissors": "<circle cx=\"6\" cy=\"6\" r=\"3\"></circle><circle cx=\"6\" cy=\"18\" r=\"3\"></circle><line x1=\"20\" y1=\"4\" x2=\"8.12\" y2=\"15.88\"></line><line x1=\"14.47\" y1=\"14.48\" x2=\"20\" y2=\"20\"></line><line x1=\"8.12\" y1=\"8.12\" x2=\"12\" y2=\"12\"></line>",
"search": "<circle cx=\"11\" cy=\"11\" r=\"8\"></circle><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>",
"send": "<line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line><polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>",
"server": "<rect x=\"2\" y=\"2\" width=\"20\" height=\"8\" rx=\"2\" ry=\"2\"></rect><rect x=\"2\" y=\"14\" width=\"20\" height=\"8\" rx=\"2\" ry=\"2\"></rect><line x1=\"6\" y1=\"6\" x2=\"6.01\" y2=\"6\"></line><line x1=\"6\" y1=\"18\" x2=\"6.01\" y2=\"18\"></line>",
"settings": "<circle cx=\"12\" cy=\"12\" r=\"3\"></circle><path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z\"></path>",
"share-2": "<circle cx=\"18\" cy=\"5\" r=\"3\"></circle><circle cx=\"6\" cy=\"12\" r=\"3\"></circle><circle cx=\"18\" cy=\"19\" r=\"3\"></circle><line x1=\"8.59\" y1=\"13.51\" x2=\"15.42\" y2=\"17.49\"></line><line x1=\"15.41\" y1=\"6.51\" x2=\"8.59\" y2=\"10.49\"></line>",
"share": "<path d=\"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8\"></path><polyline points=\"16 6 12 2 8 6\"></polyline><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"15\"></line>",
"shield-off": "<path d=\"M19.69 14a6.9 6.9 0 0 0 .31-2V5l-8-3-3.16 1.18\"></path><path d=\"M4.73 4.73L4 5v7c0 6 8 10 8 10a20.29 20.29 0 0 0 5.62-4.38\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"shield": "<path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"></path>",
"shopping-bag": "<path d=\"M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z\"></path><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"></line><path d=\"M16 10a4 4 0 0 1-8 0\"></path>",
"shopping-cart": "<circle cx=\"9\" cy=\"21\" r=\"1\"></circle><circle cx=\"20\" cy=\"21\" r=\"1\"></circle><path d=\"M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6\"></path>",
"shuffle": "<polyline points=\"16 3 21 3 21 8\"></polyline><line x1=\"4\" y1=\"20\" x2=\"21\" y2=\"3\"></line><polyline points=\"21 16 21 21 16 21\"></polyline><line x1=\"15\" y1=\"15\" x2=\"21\" y2=\"21\"></line><line x1=\"4\" y1=\"4\" x2=\"9\" y2=\"9\"></line>",
"sidebar": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"9\" y1=\"3\" x2=\"9\" y2=\"21\"></line>",
"skip-back": "<polygon points=\"19 20 9 12 19 4 19 20\"></polygon><line x1=\"5\" y1=\"19\" x2=\"5\" y2=\"5\"></line>",
"skip-forward": "<polygon points=\"5 4 15 12 5 20 5 4\"></polygon><line x1=\"19\" y1=\"5\" x2=\"19\" y2=\"19\"></line>",
"slack": "<path d=\"M14.5 10c-.83 0-1.5-.67-1.5-1.5v-5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5v5c0 .83-.67 1.5-1.5 1.5z\"></path><path d=\"M20.5 10H19V8.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z\"></path><path d=\"M9.5 14c.83 0 1.5.67 1.5 1.5v5c0 .83-.67 1.5-1.5 1.5S8 21.33 8 20.5v-5c0-.83.67-1.5 1.5-1.5z\"></path><path d=\"M3.5 14H5v1.5c0 .83-.67 1.5-1.5 1.5S2 16.33 2 15.5 2.67 14 3.5 14z\"></path><path d=\"M14 14.5c0-.83.67-1.5 1.5-1.5h5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-5c-.83 0-1.5-.67-1.5-1.5z\"></path><path d=\"M15.5 19H14v1.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z\"></path><path d=\"M10 9.5C10 8.67 9.33 8 8.5 8h-5C2.67 8 2 8.67 2 9.5S2.67 11 3.5 11h5c.83 0 1.5-.67 1.5-1.5z\"></path><path d=\"M8.5 5H10V3.5C10 2.67 9.33 2 8.5 2S7 2.67 7 3.5 7.67 5 8.5 5z\"></path>",
"slash": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"4.93\" y1=\"4.93\" x2=\"19.07\" y2=\"19.07\"></line>",
"sliders": "<line x1=\"4\" y1=\"21\" x2=\"4\" y2=\"14\"></line><line x1=\"4\" y1=\"10\" x2=\"4\" y2=\"3\"></line><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"12\"></line><line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"3\"></line><line x1=\"20\" y1=\"21\" x2=\"20\" y2=\"16\"></line><line x1=\"20\" y1=\"12\" x2=\"20\" y2=\"3\"></line><line x1=\"1\" y1=\"14\" x2=\"7\" y2=\"14\"></line><line x1=\"9\" y1=\"8\" x2=\"15\" y2=\"8\"></line><line x1=\"17\" y1=\"16\" x2=\"23\" y2=\"16\"></line>",
"smartphone": "<rect x=\"5\" y=\"2\" width=\"14\" height=\"20\" rx=\"2\" ry=\"2\"></rect><line x1=\"12\" y1=\"18\" x2=\"12.01\" y2=\"18\"></line>",
"smile": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M8 14s1.5 2 4 2 4-2 4-2\"></path><line x1=\"9\" y1=\"9\" x2=\"9.01\" y2=\"9\"></line><line x1=\"15\" y1=\"9\" x2=\"15.01\" y2=\"9\"></line>",
"speaker": "<rect x=\"4\" y=\"2\" width=\"16\" height=\"20\" rx=\"2\" ry=\"2\"></rect><circle cx=\"12\" cy=\"14\" r=\"4\"></circle><line x1=\"12\" y1=\"6\" x2=\"12.01\" y2=\"6\"></line>",
"square": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect>",
"star": "<polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\"></polygon>",
"stop-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><rect x=\"9\" y=\"9\" width=\"6\" height=\"6\"></rect>",
"sun": "<circle cx=\"12\" cy=\"12\" r=\"5\"></circle><line x1=\"12\" y1=\"1\" x2=\"12\" y2=\"3\"></line><line x1=\"12\" y1=\"21\" x2=\"12\" y2=\"23\"></line><line x1=\"4.22\" y1=\"4.22\" x2=\"5.64\" y2=\"5.64\"></line><line x1=\"18.36\" y1=\"18.36\" x2=\"19.78\" y2=\"19.78\"></line><line x1=\"1\" y1=\"12\" x2=\"3\" y2=\"12\"></line><line x1=\"21\" y1=\"12\" x2=\"23\" y2=\"12\"></line><line x1=\"4.22\" y1=\"19.78\" x2=\"5.64\" y2=\"18.36\"></line><line x1=\"18.36\" y1=\"5.64\" x2=\"19.78\" y2=\"4.22\"></line>",
"sunrise": "<path d=\"M17 18a5 5 0 0 0-10 0\"></path><line x1=\"12\" y1=\"2\" x2=\"12\" y2=\"9\"></line><line x1=\"4.22\" y1=\"10.22\" x2=\"5.64\" y2=\"11.64\"></line><line x1=\"1\" y1=\"18\" x2=\"3\" y2=\"18\"></line><line x1=\"21\" y1=\"18\" x2=\"23\" y2=\"18\"></line><line x1=\"18.36\" y1=\"11.64\" x2=\"19.78\" y2=\"10.22\"></line><line x1=\"23\" y1=\"22\" x2=\"1\" y2=\"22\"></line><polyline points=\"8 6 12 2 16 6\"></polyline>",
"sunset": "<path d=\"M17 18a5 5 0 0 0-10 0\"></path><line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"2\"></line><line x1=\"4.22\" y1=\"10.22\" x2=\"5.64\" y2=\"11.64\"></line><line x1=\"1\" y1=\"18\" x2=\"3\" y2=\"18\"></line><line x1=\"21\" y1=\"18\" x2=\"23\" y2=\"18\"></line><line x1=\"18.36\" y1=\"11.64\" x2=\"19.78\" y2=\"10.22\"></line><line x1=\"23\" y1=\"22\" x2=\"1\" y2=\"22\"></line><polyline points=\"16 5 12 9 8 5\"></polyline>",
"table": "<path d=\"M9 3H5a2 2 0 0 0-2 2v4m6-6h10a2 2 0 0 1 2 2v4M9 3v18m0 0h10a2 2 0 0 0 2-2V9M9 21H5a2 2 0 0 1-2-2V9m0 0h18\"></path>",
"tablet": "<rect x=\"4\" y=\"2\" width=\"16\" height=\"20\" rx=\"2\" ry=\"2\"></rect><line x1=\"12\" y1=\"18\" x2=\"12.01\" y2=\"18\"></line>",
"tag": "<path d=\"M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z\"></path><line x1=\"7\" y1=\"7\" x2=\"7.01\" y2=\"7\"></line>",
"target": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><circle cx=\"12\" cy=\"12\" r=\"6\"></circle><circle cx=\"12\" cy=\"12\" r=\"2\"></circle>",
"terminal": "<polyline points=\"4 17 10 11 4 5\"></polyline><line x1=\"12\" y1=\"19\" x2=\"20\" y2=\"19\"></line>",
"thermometer": "<path d=\"M14 14.76V3.5a2.5 2.5 0 0 0-5 0v11.26a4.5 4.5 0 1 0 5 0z\"></path>",
"thumbs-down": "<path d=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"></path>",
"thumbs-up": "<path d=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"></path>",
"toggle-left": "<rect x=\"1\" y=\"5\" width=\"22\" height=\"14\" rx=\"7\" ry=\"7\"></rect><circle cx=\"8\" cy=\"12\" r=\"3\"></circle>",
"toggle-right": "<rect x=\"1\" y=\"5\" width=\"22\" height=\"14\" rx=\"7\" ry=\"7\"></rect><circle cx=\"16\" cy=\"12\" r=\"3\"></circle>",
"tool": "<path d=\"M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z\"></path>",
"trash-2": "<polyline points=\"3 6 5 6 21 6\"></polyline><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path><line x1=\"10\" y1=\"11\" x2=\"10\" y2=\"17\"></line><line x1=\"14\" y1=\"11\" x2=\"14\" y2=\"17\"></line>",
"trash": "<polyline points=\"3 6 5 6 21 6\"></polyline><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"></path>",
"trello": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><rect x=\"7\" y=\"7\" width=\"3\" height=\"9\"></rect><rect x=\"14\" y=\"7\" width=\"3\" height=\"5\"></rect>",
"trending-down": "<polyline points=\"23 18 13.5 8.5 8.5 13.5 1 6\"></polyline><polyline points=\"17 18 23 18 23 12\"></polyline>",
"trending-up": "<polyline points=\"23 6 13.5 15.5 8.5 10.5 1 18\"></polyline><polyline points=\"17 6 23 6 23 12\"></polyline>",
"triangle": "<path d=\"M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\"></path>",
"truck": "<rect x=\"1\" y=\"3\" width=\"15\" height=\"13\"></rect><polygon points=\"16 8 20 8 23 11 23 16 16 16 16 8\"></polygon><circle cx=\"5.5\" cy=\"18.5\" r=\"2.5\"></circle><circle cx=\"18.5\" cy=\"18.5\" r=\"2.5\"></circle>",
"tv": "<rect x=\"2\" y=\"7\" width=\"20\" height=\"15\" rx=\"2\" ry=\"2\"></rect><polyline points=\"17 2 12 7 7 2\"></polyline>",
"twitch": "<path d=\"M21 2H3v16h5v4l4-4h5l4-4V2zm-10 9V7m5 4V7\"></path>",
"twitter": "<path d=\"M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z\"></path>",
"type": "<polyline points=\"4 7 4 4 20 4 20 7\"></polyline><line x1=\"9\" y1=\"20\" x2=\"15\" y2=\"20\"></line><line x1=\"12\" y1=\"4\" x2=\"12\" y2=\"20\"></line>",
"umbrella": "<path d=\"M23 12a11.05 11.05 0 0 0-22 0zm-5 7a3 3 0 0 1-6 0v-7\"></path>",
"underline": "<path d=\"M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3\"></path><line x1=\"4\" y1=\"21\" x2=\"20\" y2=\"21\"></line>",
"unlock": "<rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"></rect><path d=\"M7 11V7a5 5 0 0 1 9.9-1\"></path>",
"upload-cloud": "<polyline points=\"16 16 12 12 8 16\"></polyline><line x1=\"12\" y1=\"12\" x2=\"12\" y2=\"21\"></line><path d=\"M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3\"></path><polyline points=\"16 16 12 12 8 16\"></polyline>",
"upload": "<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path><polyline points=\"17 8 12 3 7 8\"></polyline><line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\"></line>",
"user-check": "<path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"></path><circle cx=\"8.5\" cy=\"7\" r=\"4\"></circle><polyline points=\"17 11 19 13 23 9\"></polyline>",
"user-minus": "<path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"></path><circle cx=\"8.5\" cy=\"7\" r=\"4\"></circle><line x1=\"23\" y1=\"11\" x2=\"17\" y2=\"11\"></line>",
"user-plus": "<path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"></path><circle cx=\"8.5\" cy=\"7\" r=\"4\"></circle><line x1=\"20\" y1=\"8\" x2=\"20\" y2=\"14\"></line><line x1=\"23\" y1=\"11\" x2=\"17\" y2=\"11\"></line>",
"user-x": "<path d=\"M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"></path><circle cx=\"8.5\" cy=\"7\" r=\"4\"></circle><line x1=\"18\" y1=\"8\" x2=\"23\" y2=\"13\"></line><line x1=\"23\" y1=\"8\" x2=\"18\" y2=\"13\"></line>",
"user": "<path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"></path><circle cx=\"12\" cy=\"7\" r=\"4\"></circle>",
"users": "<path d=\"M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2\"></path><circle cx=\"9\" cy=\"7\" r=\"4\"></circle><path d=\"M23 21v-2a4 4 0 0 0-3-3.87\"></path><path d=\"M16 3.13a4 4 0 0 1 0 7.75\"></path>",
"video-off": "<path d=\"M16 16v1a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2m5.66 0H14a2 2 0 0 1 2 2v3.34l1 1L23 7v10\"></path><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"video": "<polygon points=\"23 7 16 12 23 17 23 7\"></polygon><rect x=\"1\" y=\"5\" width=\"15\" height=\"14\" rx=\"2\" ry=\"2\"></rect>",
"voicemail": "<circle cx=\"5.5\" cy=\"11.5\" r=\"4.5\"></circle><circle cx=\"18.5\" cy=\"11.5\" r=\"4.5\"></circle><line x1=\"5.5\" y1=\"16\" x2=\"18.5\" y2=\"16\"></line>",
"volume-1": "<polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"></polygon><path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\"></path>",
"volume-2": "<polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"></polygon><path d=\"M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07\"></path>",
"volume-x": "<polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"></polygon><line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\"></line><line x1=\"17\" y1=\"9\" x2=\"23\" y2=\"15\"></line>",
"volume": "<polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"></polygon>",
"watch": "<circle cx=\"12\" cy=\"12\" r=\"7\"></circle><polyline points=\"12 9 12 12 13.5 13.5\"></polyline><path d=\"M16.51 17.35l-.35 3.83a2 2 0 0 1-2 1.82H9.83a2 2 0 0 1-2-1.82l-.35-3.83m.01-10.7l.35-3.83A2 2 0 0 1 9.83 1h4.35a2 2 0 0 1 2 1.82l.35 3.83\"></path>",
"wifi-off": "<line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line><path d=\"M16.72 11.06A10.94 10.94 0 0 1 19 12.55\"></path><path d=\"M5 12.55a10.94 10.94 0 0 1 5.17-2.39\"></path><path d=\"M10.71 5.05A16 16 0 0 1 22.58 9\"></path><path d=\"M1.42 9a15.91 15.91 0 0 1 4.7-2.88\"></path><path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\"></path><line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\"></line>",
"wifi": "<path d=\"M5 12.55a11 11 0 0 1 14.08 0\"></path><path d=\"M1.42 9a16 16 0 0 1 21.16 0\"></path><path d=\"M8.53 16.11a6 6 0 0 1 6.95 0\"></path><line x1=\"12\" y1=\"20\" x2=\"12.01\" y2=\"20\"></line>",
"wind": "<path d=\"M9.59 4.59A2 2 0 1 1 11 8H2m10.59 11.41A2 2 0 1 0 14 16H2m15.73-8.27A2.5 2.5 0 1 1 19.5 12H2\"></path>",
"x-circle": "<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line>",
"x-octagon": "<polygon points=\"7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2\"></polygon><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line>",
"x-square": "<rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"9\" y1=\"9\" x2=\"15\" y2=\"15\"></line><line x1=\"15\" y1=\"9\" x2=\"9\" y2=\"15\"></line>",
"x": "<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>",
"youtube": "<path d=\"M22.54 6.42a2.78 2.78 0 0 0-1.94-2C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 2A29 29 0 0 0 1 11.75a29 29 0 0 0 .46 5.33A2.78 2.78 0 0 0 3.4 19c1.72.46 8.6.46 8.6.46s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-2 29 29 0 0 0 .46-5.25 29 29 0 0 0-.46-5.33z\"></path><polygon points=\"9.75 15.02 15.5 11.75 9.75 8.48 9.75 15.02\"></polygon>",
"zap-off": "<polyline points=\"12.41 6.75 13 2 10.57 4.92\"></polyline><polyline points=\"18.57 12.91 21 10 15.66 10\"></polyline><polyline points=\"8 8 3 14 12 14 11 22 16 16\"></polyline><line x1=\"1\" y1=\"1\" x2=\"23\" y2=\"23\"></line>",
"zap": "<polygon points=\"13 2 3 14 12 14 11 22 21 10 12 10 13 2\"></polygon>",
"zoom-in": "<circle cx=\"11\" cy=\"11\" r=\"8\"></circle><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line><line x1=\"11\" y1=\"8\" x2=\"11\" y2=\"14\"></line><line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\"></line>",
"zoom-out": "<circle cx=\"11\" cy=\"11\" r=\"8\"></circle><line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line><line x1=\"8\" y1=\"11\" x2=\"14\" y2=\"11\"></line>"
}

24
vendor/feather-icons/license vendored Normal file
View File

@ -0,0 +1,24 @@
https://github.com/feathericons/feather/blob/master/LICENSE
---
The MIT License (MIT)
Copyright (c) 2013-2017 Cole Bemis
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.

6
vendor/feather-icons/readme.md vendored Normal file
View File

@ -0,0 +1,6 @@
https://github.com/feathericons/feather
`icons.json` here is sourced from `dist/icons.json` from the bundle, version 4.29.0.
This is intentionally not installed from `npm install feather-icons` because that package includes all of `core-js` as a dependency (which this project gets zero benefit from and is very large, impacting container image size).

BIN
vendor/katex/KaTeX_AMS-Regular.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_AMS-Regular.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_AMS-Regular.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Caligraphic-Bold.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Caligraphic-Bold.woff vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
vendor/katex/KaTeX_Fraktur-Bold.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Fraktur-Bold.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Fraktur-Bold.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Fraktur-Regular.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Fraktur-Regular.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Fraktur-Regular.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-Bold.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-Bold.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-Bold.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-BoldItalic.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-BoldItalic.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-BoldItalic.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-Italic.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-Italic.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-Italic.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-Regular.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-Regular.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Main-Regular.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Math-BoldItalic.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Math-BoldItalic.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Math-BoldItalic.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Math-Italic.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Math-Italic.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Math-Italic.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_SansSerif-Bold.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_SansSerif-Bold.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_SansSerif-Bold.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_SansSerif-Italic.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_SansSerif-Italic.woff vendored Normal file

Binary file not shown.

Binary file not shown.

BIN
vendor/katex/KaTeX_SansSerif-Regular.ttf vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
vendor/katex/KaTeX_Script-Regular.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Script-Regular.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Script-Regular.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size1-Regular.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size1-Regular.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size1-Regular.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size2-Regular.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size2-Regular.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size2-Regular.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size3-Regular.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size3-Regular.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size3-Regular.woff2 vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size4-Regular.ttf vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size4-Regular.woff vendored Normal file

Binary file not shown.

BIN
vendor/katex/KaTeX_Size4-Regular.woff2 vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

21
vendor/katex/LICENSE vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2013-2020 Khan Academy and other contributors
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.

1079
vendor/katex/katex.css vendored Normal file

File diff suppressed because it is too large Load Diff

1
vendor/katex/katex.min.css vendored Normal file

File diff suppressed because one or more lines are too long

184
vendor/katex/package.json vendored Normal file
View File

@ -0,0 +1,184 @@
{
"name": "katex",
"version": "0.16.0",
"description": "Fast math typesetting for the web.",
"main": "dist/katex.js",
"exports": {
".": {
"require": "./dist/katex.js",
"import": "./dist/katex.mjs"
},
"./contrib/auto-render": {
"require": "./dist/contrib/auto-render.js",
"import": "./dist/contrib/auto-render.mjs"
},
"./contrib/mhchem": {
"require": "./dist/contrib/mhchem.js",
"import": "./dist/contrib/mhchem.mjs"
},
"./contrib/copy-tex": {
"require": "./dist/contrib/copy-tex.js",
"import": "./dist/contrib/copy-tex.mjs"
},
"./contrib/mathtex-script-type": {
"require": "./dist/contrib/mathtex-script-type.js",
"import": "./dist/contrib/mathtex-script-type.mjs"
},
"./contrib/render-a11y-string": {
"require": "./dist/contrib/render-a11y-string.js",
"import": "./dist/contrib/render-a11y-string.mjs"
},
"./*": "./*"
},
"homepage": "https://katex.org",
"repository": {
"type": "git",
"url": "https://github.com/KaTeX/KaTeX.git"
},
"funding": [
"https://opencollective.com/katex",
"https://github.com/sponsors/katex"
],
"files": [
"katex.js",
"cli.js",
"src/",
"contrib/",
"dist/"
],
"license": "MIT",
"packageManager": "yarn@3.2.0",
"devDependencies": {
"@babel/core": "^7.10.4",
"@babel/eslint-parser": "^7.15.0",
"@babel/plugin-proposal-class-properties": "^7.10.4",
"@babel/plugin-syntax-flow": "^7.14.5",
"@babel/plugin-transform-react-jsx": "^7.14.9",
"@babel/plugin-transform-runtime": "^7.10.4",
"@babel/preset-env": "^7.10.4",
"@babel/preset-flow": "^7.10.4",
"@babel/preset-react": "^7.14.5",
"@babel/register": "^7.10.4",
"@babel/runtime": "^7.10.4",
"@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-babel": "^5.0.4",
"@semantic-release/changelog": "^6.0.0",
"@semantic-release/git": "^10.0.0",
"babel-jest": "^27.0.0",
"babel-loader": "^8.0.5",
"babel-plugin-istanbul": "^6.0.0",
"babel-plugin-preval": "^5.0.0",
"babel-plugin-version-inline": "^1.0.0",
"benchmark": "^2.1.4",
"browserslist": "^4.13.0",
"browserstack-local": "^1.4.5",
"caniuse-lite": "^1.0.30001102",
"css-loader": "^6.0.0",
"cssnano": "^5.0.0-rc.1",
"eslint": "^8.0.0",
"eslint-import-resolver-webpack": "^0.13.2",
"eslint-plugin-actions": "^2.0.0",
"eslint-plugin-flowtype": "^8.0.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-react": "^7.20.3",
"flow-bin": "^0.135.0",
"fs-extra": "^10.0.0",
"got": "^11.8.0",
"husky": "^4.2.5",
"istanbul-lib-coverage": "^3.0.0",
"istanbul-lib-report": "^3.0.0",
"istanbul-reports": "^3.0.2",
"jest": "^27.0.0",
"jest-diff": "^27.0.0",
"jest-matcher-utils": "^27.0.0",
"jest-message-util": "^27.0.0",
"jest-serializer-html": "^7.0.0",
"js-yaml": "^4.0.0",
"json-stable-stringify": "^1.0.1",
"jspngopt": "^0.2.0",
"less": "^4.0.0",
"less-loader": "^10.0.0",
"mini-css-extract-plugin": "^2.0.0",
"mkdirp": "^1.0.4",
"p-retry": "^4.6.1",
"pako": "^2.0.0",
"postcss": "^8.0.0",
"postcss-less": "^6.0.0",
"postcss-loader": "^6.0.0",
"postcss-preset-env": "^7.0.0",
"prettier": "^2.0.5",
"query-string": "^7.0.0",
"rimraf": "^3.0.2",
"rollup": "^2.21.0",
"selenium-webdriver": "^4.0.0-beta.4",
"semantic-release": "^18.0.0",
"sri-toolbox": "^0.2.0",
"style-loader": "^3.0.0",
"stylelint": "^14.0.0",
"stylelint-config-standard": "^24.0.0",
"terser-webpack-plugin": "^5.0.3",
"webpack": "^5.51.1",
"webpack-bundle-analyzer": "^4.0.0",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.0.0"
},
"bin": "cli.js",
"scripts": {
"test": "yarn test:lint && yarn test:flow && yarn test:jest",
"test:lint": "yarn test:lint:js && yarn test:lint:css",
"test:lint:js": "eslint .",
"test:lint:css": "stylelint src/katex.less static/main.css website/static/**/*.css",
"test:flow": "flow",
"test:jest": "jest",
"test:jest:watch": "jest --watch",
"test:jest:update": "jest --updateSnapshot",
"test:jest:coverage": "jest --coverage",
"test:screenshots": "yarn test:screenshots:update --verify",
"test:screenshots:update": "dockers/screenshotter/screenshotter.sh",
"test:perf": "NODE_ENV=test node test/perf-test.js",
"clean": "rm -rf dist/ node_modules/",
"clean-install": "yarn clean && yarn",
"start": "webpack serve --config webpack.dev.js",
"analyze": "webpack --config webpack.analyze.js",
"build": "rimraf dist/ && mkdirp dist && cp README.md dist && rollup -c --failAfterWarnings && webpack && node update-sri.js package dist/README.md",
"build:fonts": "dockers/fonts/buildFonts.sh",
"build:metrics": "dockers/fonts/buildMetrics.sh",
"watch": "yarn build --watch",
"postversion": "yarn dist && node update-sri.js package README.md contrib/*/README.md docs/*.md website/pages/index.html",
"semantic-release": "semantic-release",
"dist": "yarn build && yarn dist:zip",
"dist:zip": "rimraf katex/ katex.tar.gz katex.zip && cp -R dist katex && tar czf katex.tar.gz katex && zip -rq katex.zip katex && rimraf katex/"
},
"dependencies": {
"commander": "^8.0.0"
},
"husky": {
"hooks": {
"pre-commit": "yarn test:lint"
}
},
"jest": {
"collectCoverageFrom": [
"src/**/*.js",
"contrib/**/*.js",
"!src/unicodeSymbols.js",
"!contrib/mhchem/**"
],
"setupFilesAfterEnv": [
"<rootDir>/test/setup.js"
],
"snapshotSerializers": [
"jest-serializer-html"
],
"testMatch": [
"**/test/*-spec.js"
],
"testURL": "http://localhost/",
"transform": {
"^.+\\.js$": "babel-jest"
},
"moduleNameMapper": {
"^katex$": "<rootDir>/katex.js"
}
}
}

2
vendor/katex/readme.md vendored Normal file
View File

@ -0,0 +1,2 @@
Pulled from the `katex` package on npm (which is installed in `node_modules`) for the purposes of serving static assets (css and fonts)

88
vendor/open-sans/license vendored Normal file
View File

@ -0,0 +1,88 @@
Copyright 2020 The Open Sans Project Authors (https://github.com/googlefonts/opensans)
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font
creation efforts of academic and linguistic communities, and to
provide a free and open framework in which fonts may be shared and
improved in partnership with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply to
any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software
components as distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to,
deleting, or substituting -- in part or in whole -- any of the
components of the Original Version, by changing formats or by porting
the Font Software to a new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed,
modify, redistribute, and sell modified and unmodified copies of the
Font Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components, in
Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the
corresponding Copyright Holder. This restriction only applies to the
primary font name as presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created using
the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

BIN
vendor/open-sans/open-sans-v34-300.woff vendored Normal file

Binary file not shown.

BIN
vendor/open-sans/open-sans-v34-300.woff2 vendored Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More