diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2930ea9..fa92af6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,7 +58,7 @@ jobs: run: python -m build - name: Verify metadata run: twine check dist/* - - name: Verify bundled assets are in the wheel + - name: Verify bundled assets and license files are in the wheel run: | python - <<'PY' import glob, zipfile, sys @@ -66,14 +66,26 @@ jobs: names = zipfile.ZipFile(wheel).namelist() required = [ "imagespec/fonts/NotoSansKR-Regular.ttf", - "imagespec/fonts/ppb.ttf", + "imagespec/fonts/OFL.txt", "imagespec/icons/materialdesignicons-webfont.ttf", "imagespec/icons/materialdesignicons-webfont_meta.json", + "imagespec/icons/LICENSE", + "imagespec/icons/fontawesome-free-solid.otf", + "imagespec/icons/fontawesome-free-regular.otf", + "imagespec/icons/fontawesome-free-brands.otf", + "imagespec/icons/fontawesome-free_meta.json", + "imagespec/icons/LICENSE-FONTAWESOME", ] missing = [r for r in required if r not in names] if missing: print("MISSING from wheel:", missing); sys.exit(1) - print("All bundled assets present in", wheel) + # license-files (PEP 639) land under /licenses/ + license_names = {n.rsplit("/", 1)[-1] for n in names if "/licenses/" in n} + required_licenses = {"LICENSE", "LICENSE-APACHE-2.0", "NOTICE"} + missing_licenses = required_licenses - license_names + if missing_licenses: + print("MISSING from dist-info/licenses:", missing_licenses); sys.exit(1) + print("All bundled assets and license files present in", wheel) PY - uses: actions/upload-artifact@v7 with: diff --git a/LICENSE-APACHE-2.0 b/LICENSE-APACHE-2.0 new file mode 100644 index 0000000..45e71fc --- /dev/null +++ b/LICENSE-APACHE-2.0 @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the + purposes of this License, Derivative Works shall not include works + that remain separable from, or merely link (or bind by name) to the + interfaces of, the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/MANIFEST.in b/MANIFEST.in index 247804e..cf29f1d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,7 @@ -include LICENSE README.md -recursive-include src/imagespec/fonts *.ttf *.otf *.json *.md -recursive-include src/imagespec/icons *.ttf *.otf *.json *.md +include LICENSE LICENSE-APACHE-2.0 NOTICE README.md +recursive-include src/imagespec/fonts *.ttf *.otf *.json *.md *.txt +recursive-include src/imagespec/icons *.ttf *.otf *.json *.md LICENSE LICENSE-FONTAWESOME recursive-include tests *.py recursive-include examples *.py +recursive-include scripts *.py recursive-include docs *.md diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..8e05ac0 --- /dev/null +++ b/NOTICE @@ -0,0 +1,52 @@ +imagespec — Third-Party Notices +================================ + +imagespec's own source code is licensed under the MIT License (see LICENSE). + +Code origin (Apache License 2.0) +--------------------------------- +The rendering engine in this project (registry-based element dispatch, color +quantization, and the shape/text/media/codes/charts element handlers) was +originally adapted from the `imagegen` module of: + + OpenEPaperLink Home Assistant Integration + https://github.com/OpenEPaperLink/Home_Assistant_Integration + Copyright (c) OpenEPaperLink and contributors + Licensed under the Apache License, Version 2.0 + (full text: LICENSE-APACHE-2.0, or http://www.apache.org/licenses/LICENSE-2.0) + +That code has since been substantially modified, rewritten, and extended — +including porting/merging behaviour from the separate `hass-gicisky` and +`hass-niimbot` integrations (see README), changing the color/palette model, +adding device-aware rotation, dithering, new element types, and more — but +the original architecture and several element handlers trace back to it, so +this notice is included per the Apache License's redistribution terms +(Section 4). It does not change the MIT license that covers imagespec's own +code and modifications; it documents the origin of code that predates this +project's MIT copyright. + +Bundled assets (Apache License 2.0 / SIL Open Font License 1.1 / CC BY 4.0) +------------------------------------------------------------------------------ +- `src/imagespec/icons/materialdesignicons-webfont.ttf` (+ metadata) — + Material Design Icons webfont, Copyright (c) Pictogrammers / Austin Andrews + and Contributors, licensed under the Apache License, Version 2.0. + Source: https://github.com/Templarian/MaterialDesign-Webfont + Full text: src/imagespec/icons/LICENSE + +- `src/imagespec/fonts/NotoSansKR-Regular.ttf` — Noto Sans KR, Copyright 2014- + 2021 Adobe, with Reserved Font Name 'Noto', licensed under the SIL Open Font + License, Version 1.1. + Source: https://fonts.google.com/noto/specimen/Noto+Sans+KR + Full text: src/imagespec/fonts/OFL.txt + +- `src/imagespec/icons/fontawesome-free-{solid,regular,brands}.otf` (+ trimmed + metadata) — Font Awesome Free, Copyright (c) 2024 Fonticons, Inc., with + Reserved Font Name "Font Awesome". Fonts licensed under the SIL Open Font + License, Version 1.1; icons licensed under CC BY 4.0. Brand icons are + trademarks of their respective owners (not Fonticons/Font Awesome) — use them + only to represent the brand they refer to. + Source: https://github.com/FortAwesome/Font-Awesome + Full text: src/imagespec/icons/LICENSE-FONTAWESOME + +The contents of this NOTICE file are for informational purposes only and do +not modify any license. diff --git a/README.md b/README.md index db925d9..3336c9d 100644 --- a/README.md +++ b/README.md @@ -10,11 +10,14 @@ This is the shared rendering core extracted from [`hass-niimbot`](https://github.com/eigger/hass-niimbot). Both integrations had near-identical renderers that had drifted apart; `imagespec` unifies them and removes the Home Assistant dependency so the engine can be reused and tested -standalone. +standalone. The rendering engine itself was originally adapted from +[OpenEPaperLink's Home Assistant Integration](https://github.com/OpenEPaperLink/Home_Assistant_Integration) +(`imagegen` module, Apache License 2.0) and has since been substantially +rewritten and extended — see [`NOTICE`](NOTICE) for the full attribution. ## Status -✅ **29 elements** (21 ported + 8 new) rendering, with a 97-test suite. +✅ **29 elements** (21 ported + 8 new) rendering, with a 128-test suite. Architecture (HA-decoupled context, registry dispatch, device-specific rotation + palette) is in place. Remaining work is packaging polish and switching the two components over to it. @@ -83,7 +86,7 @@ python examples/smoke_test.py ```bash pip install -e ".[dev,datamatrix]" -pytest # 97 tests: every element, palettes, rotation, dither, errors +pytest # 128 tests: every element, palettes, rotation, dither, errors ruff check . && ruff format --check . # lint + format python -m build # build sdist + wheel (bundles fonts/icons) ``` @@ -131,7 +134,7 @@ All ported from the original renderers (superset behaviour where they differed): | ![](examples/elements/qrcode.png) | `qrcode` | codes | + `eclevel` (niimbot) | | ![](examples/elements/barcode.png) | `barcode` | codes | | | ![](examples/elements/datamatrix.png) | `datamatrix` | codes | optional dep `pyStrich` (`imagespec[datamatrix]`) | -| ![](examples/elements/icon.png) | `icon` | media | Material Design Icons; needs bundled `icons/` assets | +| ![](examples/elements/icon.png) | `icon` | media | Material Design Icons (default) **+ Font Awesome Free** (`fa:`/`fas:`/`far:`/`fab:`); needs bundled `icons/` assets | | ![](examples/elements/dlimg.png) | `dlimg` | media | + fit modes (stretch/fit/fill/contain) | | ![](examples/elements/diagram.png) | `diagram` | charts | bar chart | | ![](examples/elements/plot.png) | `plot` | charts | needs `history_provider`; + area_fill, xlegend | @@ -217,6 +220,7 @@ Payloads are specified as a list (sequence) of dictionary elements, which can be - **`rich_text`**: Draws a single line of text with mixed formatting (text, icons, colors, sizes) side-by-side. - `x`, `y` (int, required) - `spans` (list of span dicts: `[{"text": "Temp: "}, {"icon": "mdi:fire", "color": "orange"}]`, required) + — `icon` accepts the same `mdi:`/`fa:`/`fas:`/`far:`/`fab:` names as the `icon` element - `size` (default: `12`), `align` (left/right/center, default: `"left"`) - **`table`**: Renders a simple structured table. - `x`, `y` (int top-left, required) @@ -273,9 +277,12 @@ Payloads are specified as a list (sequence) of dictionary elements, which can be - `boxsize` (int pixels per cell, default: `2`), **or** `width`/`height` (int px box — scaled square & crisp to fit, like `qrcode`) - `color`, `bgcolor` (optional) -- **`icon`**: Renders a vector icon from Material Design Icons. +- **`icon`**: Renders a vector icon from Material Design Icons or Font Awesome Free. - `x`, `y` (int top-left, required) - - `value` (string slug, e.g. `"mdi:home"`, required) + - `value` (string slug, required) — `"mdi:home"` (or a bare name, e.g. `"home"`, + for backward compatibility) for **Material Design Icons**; `"fa:home"` / + `"fas:home"` (solid) / `"far:star"` (regular) / `"fab:github"` (brands) for + **Font Awesome Free**. Plain `"fa:"` auto-picks solid > regular > brands. - `size` (int, default: `24`), `color` (optional) - **`dlimg`**: Downloads and renders an external image (with fit and dithering). - `x`, `y`, `xsize`, `ysize` (int box, required) @@ -316,7 +323,9 @@ Payloads are specified as a list (sequence) of dictionary elements, which can be #### Widgets - **`legend`**: Draws color-swatch ↔ label rows (companion to `pie`/`plot`). - `x`, `y` (int top-left, required) - - `items` (required) — list of `{"label": ..., "color": ..., "icon": ...}` dicts, or a `"label,color;label,color"` string + - `items` (required) — list of `{"label": ..., "color": ..., "icon": ...}` dicts (icon + accepts `mdi:`/`fa:`/`fas:`/`far:`/`fab:` names, same as `icon`), or a + `"label,color;label,color"` string - `orientation` (`"vertical"` / `"horizontal"`, default: `"vertical"`) - `shape` (`"square"` / `"circle"` / `"line"`, default: `"square"`) - `size` (font size, default: `12`), `swatch_size`, `gap`, `spacing` (optional) @@ -428,10 +437,14 @@ python examples/compare_dither.py ## Fonts & assets -Bundled in the package (offline baseline): +Bundled in the package (offline baseline, ~12 MB total): -- `icons/materialdesignicons-webfont.ttf` + `_meta.json` — required by `icon`. -- `fonts/NotoSansKR-Regular.ttf` (default) and `fonts/ppb.ttf` (niimbot default). +- `icons/materialdesignicons-webfont.ttf` + `_meta.json` — `icon`'s default set + (`mdi:` prefix, or no prefix). +- `icons/fontawesome-free-{solid,regular,brands}.otf` + trimmed metadata — + `icon`'s second set (`fa:`/`fas:`/`far:`/`fab:` prefix). +- `fonts/NotoSansKR-Regular.ttf` — the only bundled font, and the default for + every payload (`RenderContext.default_font`). Anything else is resolved at runtime, in order: `font_resolver` (host) → bundled font of the same basename → bundled default. Helpers in @@ -440,21 +453,54 @@ bundled font of the same basename → bundled default. Helpers in - `directory_resolver(dir)` — look up fonts in a host directory (e.g. `www/fonts`). - `caching_resolver(cache_dir, sources)` — **download on first use, cache to disk, reuse offline** (internet needed only once per font). +- `google_fonts_resolver(cache_dir, families=None)` — a `caching_resolver` + preset over verified-license Google Fonts (`ofl/` directory → all SIL OFL + 1.1), covering scripts the bundled Noto Sans KR doesn't: Japanese, Simplified/ + Traditional Chinese, Arabic, Thai, plus a broader Latin/Cyrillic/Greek family. + See `GOOGLE_FONTS_SOURCES` for the exact list. - `chain_resolvers(a, b, ...)` — try several in order. -This is why the core bundles only the essentials (~11 MB) and **not** gicisky's -full 74 MB font set — decorative fonts are better downloaded-and-cached or served -from `www/fonts`. +This is why the core bundles only the essentials and **not** gicisky's full +74 MB font set — decorative/other-script fonts are better downloaded-and-cached +(`google_fonts_resolver`/`caching_resolver`) or served from `www/fonts`. (Earlier +builds also bundled niimbot's `ppb.ttf` as a second default font; it was dropped +because its license/origin could not be confirmed — see *Licensing & attribution* +below. Pass `default_font=` your own niimbot-style font if you need that look.) + +### Licensing & attribution + +`imagespec` is **MIT AND Apache-2.0** (see the `license` field in +`pyproject.toml`) — not pure MIT — because it's a combined work: + +| Component | License | Source | +|---|---|---| +| imagespec's own code/modifications | MIT | [`LICENSE`](LICENSE) | +| Rendering engine origin (registry dispatch, element handlers) | Apache License 2.0 | [OpenEPaperLink Home Assistant Integration](https://github.com/OpenEPaperLink/Home_Assistant_Integration) — see [`NOTICE`](NOTICE) | +| `icons/materialdesignicons-webfont.ttf` (+ metadata) | Apache License 2.0 | [Pictogrammers / Templarian MaterialDesign-Webfont](https://github.com/Templarian/MaterialDesign-Webfont) | +| `icons/fontawesome-free-*.otf` (+ metadata) | SIL OFL 1.1 (fonts) / CC BY 4.0 (icons) | [Font Awesome Free](https://github.com/FortAwesome/Font-Awesome) | +| `fonts/NotoSansKR-Regular.ttf` | SIL Open Font License 1.1 | [Google Noto Fonts](https://fonts.google.com/noto/specimen/Noto+Sans+KR) | + +The engine was originally adapted from OpenEPaperLink's code and has since been +substantially rewritten and extended (palette/color model, device-aware +rotation, dithering, new elements, ...); [`NOTICE`](NOTICE) documents this per +the Apache License's redistribution terms. Full license texts ship in the +package: [`LICENSE-APACHE-2.0`](LICENSE-APACHE-2.0) (covers the engine origin +and the MDI font), [`icons/LICENSE`](src/imagespec/icons/LICENSE) (a co-located +copy for the icons directory), [`icons/LICENSE-FONTAWESOME`](src/imagespec/icons/LICENSE-FONTAWESOME) +(Font Awesome Free — also notes brand-icon trademark restrictions), and +[`fonts/OFL.txt`](src/imagespec/fonts/OFL.txt). ## Open decisions -- **Default font.** `NotoSansKR-Regular.ttf` (gicisky) vs `ppb.ttf` (niimbot). - Default is Noto; bundle both so existing payloads render unchanged. +None currently open. > Resolved: rotation is now a per-device `rotate_mode` (`"canvas"` for gicisky, > `"image"` for niimbot), and `RenderState.canvas_width/height` always reflect > the actual drawing surface — so `plot`/`diagram` default extents are > consistent in both modes. +> +> Resolved: the default font is `NotoSansKR-Regular.ttf` only — niimbot's +> `ppb.ttf` was dropped (unverifiable license; see *Licensing & attribution*). ## Integrating back into the components diff --git a/docs/migration.md b/docs/migration.md index 33afd8c..4c9aa48 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -115,7 +115,11 @@ def customimage(entity_id, service, hass): rotate=service.data.get("rotate", 0), rotate_mode="image", # label printer: variable size, drawing rotates background=service.data.get("background", "white"), - context=_make_context(hass, default_font="ppb.ttf", palette="bw"), + # niimbot's old `ppb.ttf` default isn't bundled by imagespec (its + # license/origin couldn't be verified) — supply it via font_resolver + # (e.g. from `www/fonts`) if you need that look; otherwise this falls + # back to imagespec's bundled NotoSansKR-Regular.ttf. + context=_make_context(hass, palette="bw"), ) except RenderError as err: raise HomeAssistantError(str(err)) from err @@ -129,7 +133,7 @@ def customimage(entity_id, service, hass): |---|---|---| | `rotate_mode` | `"canvas"` (output stays W×H) | `"image"` (output dims swap) | | `palette` | varies by model (`"2"`/`"4"`/`"7"`) | usually `"bw"` | -| `default_font` | `NotoSansKR-Regular.ttf` | `ppb.ttf` | +| `default_font` | `NotoSansKR-Regular.ttf` (imagespec default) | bring your own via `font_resolver`/`www/fonts` (`ppb.ttf` is no longer bundled — unverified license) | | canvas size | from `device.width/height` | from `service.data["width"/"height"]` | Colors in a payload are auto-quantized to the device `palette`, so the same @@ -140,9 +144,10 @@ payload renders correctly on a 2/4/7-color panel without changes. ## 6. Optional cleanups enabled by the move - **Delete bundled fonts** from each component that `imagespec` already ships - (`NotoSansKR-Regular.ttf`, `ppb.ttf`, the MDI webfont + meta). Decorative fonts - the components still need can stay in `www/fonts`, or be downloaded on demand - via `imagespec.resolvers.caching_resolver` (download-once, cache offline). + (`NotoSansKR-Regular.ttf`, the MDI webfont + meta). Decorative fonts the + components still need (e.g. niimbot's `ppb.ttf`, if its license is confirmed) + can stay in `www/fonts`, or be downloaded on demand via + `imagespec.resolvers.caching_resolver` (download-once, cache offline). - **Image quality**: pass `dither=True` to `render(...)`, or `"dither": true` on a `dlimg`, for Floyd–Steinberg dithering on limited-color panels. diff --git a/pyproject.toml b/pyproject.toml index d9fbcd3..ea75c7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,8 +8,8 @@ version = "0.2.1" description = "Render images from a declarative YAML/dict spec — shapes, text, charts, QR/barcodes — for e-paper ESL tags and label printers." readme = "README.md" requires-python = ">=3.11" -license = "MIT" -license-files = ["LICENSE"] +license = "MIT AND Apache-2.0" +license-files = ["LICENSE", "LICENSE-APACHE-2.0", "NOTICE"] authors = [{ name = "eigger" }] keywords = ["image", "render", "yaml", "spec", "e-paper", "esl", "label", "pillow"] classifiers = [ diff --git a/scripts/build_fontawesome_assets.py b/scripts/build_fontawesome_assets.py new file mode 100644 index 0000000..a50cb8c --- /dev/null +++ b/scripts/build_fontawesome_assets.py @@ -0,0 +1,81 @@ +"""Regenerate the bundled Font Awesome Free assets in ``src/imagespec/icons/``. + +Maintenance/dev tool — not shipped in the package. Downloads the three Free +webfonts (Solid/Regular/Brands) and trims upstream's ``metadata/icons.json`` +(which embeds full SVG path data and is ~4.5 MB) down to just what `icon` +needs to resolve a name to a codepoint: ``name``, ``codepoint``, ``styles`` +(which of the three Free webfonts contain it), and ``aliases``. + +Only icons in the **Free** tier (``"free": [...]`` non-empty upstream) are +included — Pro-only icons are dropped since their fonts aren't available +under an open license. + +Run from the repository root: + python scripts/build_fontawesome_assets.py +""" + +from __future__ import annotations + +import json +import os +import urllib.request + +FA_REF = "6.x" +RAW_BASE = f"https://raw.githubusercontent.com/FortAwesome/Font-Awesome/{FA_REF}" +ICONS_DIR = os.path.join(os.path.dirname(__file__), "..", "src", "imagespec", "icons") + +FONT_FILES = { + "fontawesome-free-solid.otf": "otfs/Font%20Awesome%206%20Free-Solid-900.otf", + "fontawesome-free-regular.otf": "otfs/Font%20Awesome%206%20Free-Regular-400.otf", + "fontawesome-free-brands.otf": "otfs/Font%20Awesome%206%20Brands-Regular-400.otf", +} + + +def _download(url: str, dest: str) -> None: + print(f" GET {url}") + urllib.request.urlretrieve(url, dest) # noqa: S310 — fixed, trusted upstream URLs + + +def main() -> None: + os.makedirs(ICONS_DIR, exist_ok=True) + + print("Downloading webfonts...") + for filename, path in FONT_FILES.items(): + _download(f"{RAW_BASE}/{path}", os.path.join(ICONS_DIR, filename)) + + print("Downloading + trimming metadata...") + meta_path = os.path.join(ICONS_DIR, "_fa_icons_raw.json") + _download(f"{RAW_BASE}/metadata/icons.json", meta_path) + with open(meta_path, encoding="utf-8") as f: + raw = json.load(f) + os.remove(meta_path) + + trimmed = [] + primary_names = set(raw) + for name, entry in raw.items(): + free_styles = entry.get("free") or [] + if not free_styles: + continue # Pro-only icon — not bundled + aliases = [a for a in entry.get("aliases", {}).get("names", []) if a not in primary_names] + trimmed.append( + { + "name": name, + "codepoint": entry["unicode"], + "styles": free_styles, + "aliases": aliases, + } + ) + trimmed.sort(key=lambda e: e["name"]) + + out_path = os.path.join(ICONS_DIR, "fontawesome-free_meta.json") + with open(out_path, "w", encoding="utf-8") as f: + json.dump(trimmed, f, separators=(",", ":")) + print(f"Wrote {len(trimmed)} free icons to {out_path}") + + license_path = os.path.join(ICONS_DIR, "LICENSE-FONTAWESOME") + _download(f"{RAW_BASE}/LICENSE.txt", license_path) + print(f"Wrote {license_path}") + + +if __name__ == "__main__": + main() diff --git a/src/imagespec/__init__.py b/src/imagespec/__init__.py index 62f6219..7c72f47 100644 --- a/src/imagespec/__init__.py +++ b/src/imagespec/__init__.py @@ -27,7 +27,13 @@ from .core import ROTATE_MODE_CANVAS, ROTATE_MODE_IMAGE, render from .exceptions import RenderError from .registry import known_types -from .resolvers import caching_resolver, chain_resolvers, directory_resolver +from .resolvers import ( + GOOGLE_FONTS_SOURCES, + caching_resolver, + chain_resolvers, + directory_resolver, + google_fonts_resolver, +) __all__ = [ "render", @@ -47,6 +53,8 @@ "caching_resolver", "chain_resolvers", "directory_resolver", + "google_fonts_resolver", + "GOOGLE_FONTS_SOURCES", ] # The version is defined statically in pyproject.toml. diff --git a/src/imagespec/elements/media.py b/src/imagespec/elements/media.py index 26a3cca..1547450 100644 --- a/src/imagespec/elements/media.py +++ b/src/imagespec/elements/media.py @@ -1,4 +1,5 @@ -"""Asset-backed elements: icon (Material Design Icons glyph), dlimg (image).""" +"""Asset-backed elements: icon (Material Design Icons / Font Awesome Free +glyph), dlimg (image).""" from __future__ import annotations @@ -72,13 +73,108 @@ def mdi_font(icons_dir: str, size): return ImageFont.truetype(font_file, size) +# ── Font Awesome Free (solid/regular/brands) ─────────────────────────────── +# Metadata is trimmed from upstream's metadata/icons.json (name -> codepoint, +# which of the 3 Free webfonts contain it, and aliases) by +# scripts/build_fontawesome_assets.py — Pro-only icons are not included. +_fa_meta_cache: dict[str, list] = {} +_FA_STYLE_FILES = { + "solid": "fontawesome-free-solid.otf", + "regular": "fontawesome-free-regular.otf", + "brands": "fontawesome-free-brands.otf", +} +_FA_STYLE_PREFERENCE = ("solid", "regular", "brands") # used by the generic "fa:" prefix +_FA_PREFIX_STYLE = {"fas": "solid", "far": "regular", "fab": "brands"} +_FA_PREFIXES = ("fa:", "fas:", "far:", "fab:") + + +def _fa_meta(icons_dir: str) -> list: + meta_file = os.path.join(icons_dir, "fontawesome-free_meta.json") + cached = _fa_meta_cache.get(meta_file) + if cached is None: + if not os.path.exists(meta_file): + raise RenderError( + f"icon: Font Awesome metadata not found at {meta_file}. Run " + "scripts/build_fontawesome_assets.py to (re)generate the bundled assets." + ) + with open(meta_file, encoding="utf-8") as f: + cached = json.load(f) + _fa_meta_cache[meta_file] = cached + return cached + + +def _fa_lookup(name: str, icons_dir: str) -> dict: + icon_data = _fa_meta(icons_dir) + for ic in icon_data: + if ic["name"] == name: + return ic + for ic in icon_data: + if name in ic["aliases"]: + return ic + raise RenderError("Non valid Font Awesome icon used: " + name) + + +def fa_font(icons_dir: str, size, style: str): + """Load one of the bundled Font Awesome Free webfonts at ``size``.""" + from PIL import ImageFont + + filename = _FA_STYLE_FILES.get(style) + if filename is None: + raise RenderError(f"icon: unknown Font Awesome style {style!r} (expected solid/regular/brands)") + font_file = os.path.join(icons_dir, filename) + if not os.path.exists(font_file): + raise RenderError(f"icon: Font Awesome webfont not found at {font_file}.") + return ImageFont.truetype(font_file, size) + + +def fa_char_and_style(value: str, icons_dir: str) -> tuple[str, str]: + """Resolve ``fa:name`` / ``fas:name`` / ``far:name`` / ``fab:name`` to ``(glyph, style)``. + + ``fas``/``far``/``fab`` force solid/regular/brands respectively (error if the + icon has no glyph in that style); plain ``fa:`` auto-picks the first + available style in solid > regular > brands order. + """ + forced_style = None + for prefix, style in _FA_PREFIX_STYLE.items(): + if value.startswith(f"{prefix}:"): + forced_style, value = style, value[len(prefix) + 1 :] + break + else: + if value.startswith("fa:"): + value = value[3:] + entry = _fa_lookup(value, icons_dir) + if forced_style is not None: + if forced_style not in entry["styles"]: + raise RenderError( + f"icon: Font Awesome icon '{value}' has no {forced_style!r} style " + f"(available: {', '.join(entry['styles'])})" + ) + chosen = forced_style + else: + chosen = next((s for s in _FA_STYLE_PREFERENCE if s in entry["styles"]), entry["styles"][0]) + return chr(int(entry["codepoint"], 16)), chosen + + +def resolve_icon(value: str, icons_dir: str, size): + """Resolve an ``icon``/``rich_text``/``legend`` icon ``value`` to ``(glyph, font)``. + + ``value`` is a Font Awesome name (``"fa:home"``, or with an explicit style — + ``"fas:"``/``"far:"``/``"fab:"``) or a Material Design Icons name + (``"mdi:..."``; also the default when no recognized prefix is present, for + backward compatibility). + """ + if value.startswith(_FA_PREFIXES): + glyph, style = fa_char_and_style(value, icons_dir) + return glyph, fa_font(icons_dir, size, style) + return mdi_char(value, icons_dir), mdi_font(icons_dir, size) + + @element("icon") def icon(state: RenderState, element: dict) -> None: require(element, ["x", "y", "value", "size"], "icon") d = ImageDraw.Draw(state.img) d.fontmode = "1" - glyph = mdi_char(element["value"], state.context.icons_dir) - font = mdi_font(state.context.icons_dir, element["size"]) + glyph, font = resolve_icon(element["value"], state.context.icons_dir, element["size"]) anchor = element.get("anchor", "la") stroke_width = element.get("stroke_width", 0) stroke_fill = state.context.color(element.get("stroke_fill", "white")) diff --git a/src/imagespec/elements/text.py b/src/imagespec/elements/text.py index 27afb49..aededed 100644 --- a/src/imagespec/elements/text.py +++ b/src/imagespec/elements/text.py @@ -322,13 +322,14 @@ def table(state: RenderState, element: dict) -> None: def rich_text(state: RenderState, element: dict) -> None: """Draw inline spans (text and/or icons) left-to-right on one baseline. - Each span is ``{"text": ...}`` or ``{"icon": "mdi:..."}`` with optional - per-span ``size``/``color``/``font``. ``element["y"]`` is the vertical center - (spans are middle-anchored); ``align`` (left/center/right) positions the run - relative to ``element["x"]``. + Each span is ``{"text": ...}`` or ``{"icon": "mdi:..."}`` (also accepts + ``"fa:..."``/``"fas:..."``/``"far:..."``/``"fab:..."`` for Font Awesome) with + optional per-span ``size``/``color``/``font``. ``element["y"]`` is the + vertical center (spans are middle-anchored); ``align`` (left/center/right) + positions the run relative to ``element["x"]``. """ require(element, ["x", "y", "spans"], "rich_text") - from .media import mdi_char, mdi_font + from .media import resolve_icon spacing = element.get("spacing", 0) default_size = element.get("size", 20) @@ -340,8 +341,7 @@ def rich_text(state: RenderState, element: dict) -> None: size = sp.get("size", default_size) color = sp.get("color", default_color) if "icon" in sp: - text = mdi_char(sp["icon"], state.context.icons_dir) - font = mdi_font(state.context.icons_dir, size) + text, font = resolve_icon(sp["icon"], state.context.icons_dir, size) else: text = str(sp.get("text", "")) font = state.context.font(sp.get("font", default_font), size) diff --git a/src/imagespec/elements/widgets.py b/src/imagespec/elements/widgets.py index ad43016..5433616 100644 --- a/src/imagespec/elements/widgets.py +++ b/src/imagespec/elements/widgets.py @@ -64,10 +64,10 @@ def legend(state: RenderState, element: dict) -> None: cy = cursor_y + line_h / 2 col = state.context.color(color) if icon is not None: - from .media import mdi_char, mdi_font + from .media import resolve_icon - glyph = mdi_char(icon, state.context.icons_dir) - d.text((cursor_x, cy), glyph, font=mdi_font(state.context.icons_dir, swatch), fill=col, anchor="lm") + glyph, icon_font = resolve_icon(icon, state.context.icons_dir, swatch) + d.text((cursor_x, cy), glyph, font=icon_font, fill=col, anchor="lm") elif shape == "circle": d.ellipse([(cursor_x, cy - swatch / 2), (cursor_x + swatch, cy + swatch / 2)], fill=col) elif shape == "line": diff --git a/src/imagespec/fonts/OFL.txt b/src/imagespec/fonts/OFL.txt new file mode 100644 index 0000000..7bf6fbd --- /dev/null +++ b/src/imagespec/fonts/OFL.txt @@ -0,0 +1,99 @@ +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name +'Noto'. Noto is a trademark of Google LLC. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +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. + +--- + +This license applies to NotoSansKR-Regular.ttf bundled in this directory. +Source: https://fonts.google.com/noto/specimen/Noto+Sans+KR diff --git a/src/imagespec/fonts/README.md b/src/imagespec/fonts/README.md index 0d069d4..f250b58 100644 --- a/src/imagespec/fonts/README.md +++ b/src/imagespec/fonts/README.md @@ -1,20 +1,19 @@ # Bundled fonts -Drop the default font(s) here so the package can render text without the host -application supplying one. +The default font the package renders text with when no `font_resolver`/payload +`font` resolves to anything else (referenced as `RenderContext.default_font`): -Expected (referenced as `RenderContext.default_font`): +- `NotoSansKR-Regular.ttf` — licensed under the **SIL Open Font License 1.1** + (full text: [`OFL.txt`](OFL.txt)), sourced from + [Google Noto Fonts](https://fonts.google.com/noto/specimen/Noto+Sans+KR). -- `NotoSansKR-Regular.ttf` ← copy from `hass-gicisky/custom_components/gicisky/fonts/` - -Optional / commonly referenced by existing payloads: - -- `ppb.ttf` ← niimbot's default; copy if you want niimbot payloads to render unchanged. +niimbot's `ppb.ttf` (a former second bundled font) was removed — its +license/origin could not be verified, which is a real risk for a font shipped +in a published PyPI package. If you need that look, supply your own font file +via `font_resolver` or `directory_resolver(...)`; do **not** re-add it here +without confirming its license first. Font name resolution order (see `context.py`): 1. `RenderContext.font_resolver(name)` (host-supplied, e.g. `www/fonts`) 2. a file of the same basename in this folder 3. `default_font` in this folder - -> These binary files are intentionally **not** committed yet — copy them in -> before packaging/publishing. diff --git a/src/imagespec/fonts/ppb.ttf b/src/imagespec/fonts/ppb.ttf deleted file mode 100644 index 00559ee..0000000 Binary files a/src/imagespec/fonts/ppb.ttf and /dev/null differ diff --git a/src/imagespec/icons/LICENSE b/src/imagespec/icons/LICENSE new file mode 100644 index 0000000..803d52c --- /dev/null +++ b/src/imagespec/icons/LICENSE @@ -0,0 +1,210 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the + purposes of this License, Derivative Works shall not include works + that remain separable from, or merely link (or bind by name) to the + interfaces of, the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--- + +This license applies to the Material Design Icons webfont +(`materialdesignicons-webfont.ttf`) and its metadata +(`materialdesignicons-webfont_meta.json`) bundled in this directory. + +Copyright (c) Pictogrammers / Austin Andrews and Contributors +Source: https://github.com/Templarian/MaterialDesign-Webfont diff --git a/src/imagespec/icons/LICENSE-FONTAWESOME b/src/imagespec/icons/LICENSE-FONTAWESOME new file mode 100644 index 0000000..e69c5e3 --- /dev/null +++ b/src/imagespec/icons/LICENSE-FONTAWESOME @@ -0,0 +1,165 @@ +Fonticons, Inc. (https://fontawesome.com) + +-------------------------------------------------------------------------------- + +Font Awesome Free License + +Font Awesome Free is free, open source, and GPL friendly. You can use it for +commercial projects, open source projects, or really almost whatever you want. +Full Font Awesome Free license: https://fontawesome.com/license/free. + +-------------------------------------------------------------------------------- + +# Icons: CC BY 4.0 License (https://creativecommons.org/licenses/by/4.0/) + +The Font Awesome Free download is licensed under a Creative Commons +Attribution 4.0 International License and applies to all icons packaged +as SVG and JS file types. + +-------------------------------------------------------------------------------- + +# Fonts: SIL OFL 1.1 License + +In the Font Awesome Free download, the SIL OFL license applies to all icons +packaged as web and desktop font files. + +Copyright (c) 2024 Fonticons, Inc. (https://fontawesome.com) +with Reserved Font Name: "Font Awesome". + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +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. + +-------------------------------------------------------------------------------- + +# Code: MIT License (https://opensource.org/licenses/MIT) + +In the Font Awesome Free download, the MIT license applies to all non-font and +non-icon files. + +Copyright 2024 Fonticons, Inc. + +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. + +-------------------------------------------------------------------------------- + +# Attribution + +Attribution is required by MIT, SIL OFL, and CC BY licenses. Downloaded Font +Awesome Free files already contain embedded comments with sufficient +attribution, so you shouldn't need to do anything additional when using these +files normally. + +We've kept attribution comments terse, so we ask that you do not actively work +to remove them from files, especially code. They're a great way for folks to +learn about Font Awesome. + +-------------------------------------------------------------------------------- + +# Brand Icons + +All brand icons are trademarks of their respective owners. The use of these +trademarks does not indicate endorsement of the trademark holder by Font +Awesome, nor vice versa. **Please do not use brand logos for any purpose except +to represent the company, product, or service to which they refer.** diff --git a/src/imagespec/icons/README.md b/src/imagespec/icons/README.md index e5568c5..75ed117 100644 --- a/src/imagespec/icons/README.md +++ b/src/imagespec/icons/README.md @@ -1,13 +1,23 @@ -# Bundled icons (Material Design Icons) +# Bundled icons (Material Design Icons + Font Awesome Free) -The `icon` element needs the MDI webfont and its codepoint metadata. Copy both -files here before enabling the `icon` handler: +The `icon` (and `rich_text`/`legend` icon spans) element resolves a name +against one of two bundled icon sets, by prefix: -- `materialdesignicons-webfont.ttf` -- `materialdesignicons-webfont_meta.json` - -Source: https://github.com/Templarian/MaterialDesign-Webfont/tree/master/fonts -(both components already ship these — copy from either -`hass-gicisky/.../fonts/` or `hass-niimbot/.../`). +- `"mdi:home"` (or no prefix, e.g. `"home"` — kept for backward compatibility) + → **Material Design Icons**: `materialdesignicons-webfont.ttf` + + `materialdesignicons-webfont_meta.json`. + Source: [Pictogrammers / Templarian MaterialDesign-Webfont](https://github.com/Templarian/MaterialDesign-Webfont/tree/master/fonts). + Licensed under the **Apache License 2.0** (full text: [`LICENSE`](LICENSE)). +- `"fa:home"` / `"fas:home"` (solid) / `"far:star"` (regular) / `"fab:github"` + (brands) → **Font Awesome Free**: `fontawesome-free-{solid,regular,brands}.otf` + + `fontawesome-free_meta.json` (trimmed from upstream's metadata by + [`scripts/build_fontawesome_assets.py`](../../../scripts/build_fontawesome_assets.py) — Pro-only icons are not included). + Plain `"fa:"` auto-picks the first available style in solid > regular > brands + order; a forced style (`fas:`/`far:`/`fab:`) errors if that icon has no glyph + in it. Source: [Font Awesome Free](https://github.com/FortAwesome/Font-Awesome). + Licensed under **SIL Open Font License 1.1** (fonts) / **CC BY 4.0** (icons) + (full text: [`LICENSE-FONTAWESOME`](LICENSE-FONTAWESOME)). Brand icons are + trademarks of their respective owners — see that license file's "Brand Icons" + section before using them to represent anything other than the brand itself. `RenderContext.icons_dir` defaults to this folder. diff --git a/src/imagespec/icons/fontawesome-free-brands.otf b/src/imagespec/icons/fontawesome-free-brands.otf new file mode 100644 index 0000000..30ce70f Binary files /dev/null and b/src/imagespec/icons/fontawesome-free-brands.otf differ diff --git a/src/imagespec/icons/fontawesome-free-regular.otf b/src/imagespec/icons/fontawesome-free-regular.otf new file mode 100644 index 0000000..038c755 Binary files /dev/null and b/src/imagespec/icons/fontawesome-free-regular.otf differ diff --git a/src/imagespec/icons/fontawesome-free-solid.otf b/src/imagespec/icons/fontawesome-free-solid.otf new file mode 100644 index 0000000..ddfe47f Binary files /dev/null and b/src/imagespec/icons/fontawesome-free-solid.otf differ diff --git a/src/imagespec/icons/fontawesome-free_meta.json b/src/imagespec/icons/fontawesome-free_meta.json new file mode 100644 index 0000000..9e84888 --- /dev/null +++ b/src/imagespec/icons/fontawesome-free_meta.json @@ -0,0 +1 @@ +[{"name":"0","codepoint":"30","styles":["solid"],"aliases":[]},{"name":"1","codepoint":"31","styles":["solid"],"aliases":[]},{"name":"2","codepoint":"32","styles":["solid"],"aliases":[]},{"name":"3","codepoint":"33","styles":["solid"],"aliases":[]},{"name":"4","codepoint":"34","styles":["solid"],"aliases":[]},{"name":"42-group","codepoint":"e080","styles":["brands"],"aliases":["innosoft"]},{"name":"5","codepoint":"35","styles":["solid"],"aliases":[]},{"name":"500px","codepoint":"f26e","styles":["brands"],"aliases":[]},{"name":"6","codepoint":"36","styles":["solid"],"aliases":[]},{"name":"7","codepoint":"37","styles":["solid"],"aliases":[]},{"name":"8","codepoint":"38","styles":["solid"],"aliases":[]},{"name":"9","codepoint":"39","styles":["solid"],"aliases":[]},{"name":"a","codepoint":"41","styles":["solid"],"aliases":[]},{"name":"accessible-icon","codepoint":"f368","styles":["brands"],"aliases":[]},{"name":"accusoft","codepoint":"f369","styles":["brands"],"aliases":[]},{"name":"address-book","codepoint":"f2b9","styles":["regular","solid"],"aliases":["contact-book"]},{"name":"address-card","codepoint":"f2bb","styles":["regular","solid"],"aliases":["contact-card","vcard"]},{"name":"adn","codepoint":"f170","styles":["brands"],"aliases":[]},{"name":"adversal","codepoint":"f36a","styles":["brands"],"aliases":[]},{"name":"affiliatetheme","codepoint":"f36b","styles":["brands"],"aliases":[]},{"name":"airbnb","codepoint":"f834","styles":["brands"],"aliases":[]},{"name":"algolia","codepoint":"f36c","styles":["brands"],"aliases":[]},{"name":"align-center","codepoint":"f037","styles":["solid"],"aliases":[]},{"name":"align-justify","codepoint":"f039","styles":["solid"],"aliases":[]},{"name":"align-left","codepoint":"f036","styles":["solid"],"aliases":[]},{"name":"align-right","codepoint":"f038","styles":["solid"],"aliases":[]},{"name":"alipay","codepoint":"f642","styles":["brands"],"aliases":[]},{"name":"amazon","codepoint":"f270","styles":["brands"],"aliases":[]},{"name":"amazon-pay","codepoint":"f42c","styles":["brands"],"aliases":[]},{"name":"amilia","codepoint":"f36d","styles":["brands"],"aliases":[]},{"name":"anchor","codepoint":"f13d","styles":["solid"],"aliases":[]},{"name":"anchor-circle-check","codepoint":"e4aa","styles":["solid"],"aliases":[]},{"name":"anchor-circle-exclamation","codepoint":"e4ab","styles":["solid"],"aliases":[]},{"name":"anchor-circle-xmark","codepoint":"e4ac","styles":["solid"],"aliases":[]},{"name":"anchor-lock","codepoint":"e4ad","styles":["solid"],"aliases":[]},{"name":"android","codepoint":"f17b","styles":["brands"],"aliases":[]},{"name":"angellist","codepoint":"f209","styles":["brands"],"aliases":[]},{"name":"angle-down","codepoint":"f107","styles":["solid"],"aliases":[]},{"name":"angle-left","codepoint":"f104","styles":["solid"],"aliases":[]},{"name":"angle-right","codepoint":"f105","styles":["solid"],"aliases":[]},{"name":"angle-up","codepoint":"f106","styles":["solid"],"aliases":[]},{"name":"angles-down","codepoint":"f103","styles":["solid"],"aliases":["angle-double-down"]},{"name":"angles-left","codepoint":"f100","styles":["solid"],"aliases":["angle-double-left"]},{"name":"angles-right","codepoint":"f101","styles":["solid"],"aliases":["angle-double-right"]},{"name":"angles-up","codepoint":"f102","styles":["solid"],"aliases":["angle-double-up"]},{"name":"angrycreative","codepoint":"f36e","styles":["brands"],"aliases":[]},{"name":"angular","codepoint":"f420","styles":["brands"],"aliases":[]},{"name":"ankh","codepoint":"f644","styles":["solid"],"aliases":[]},{"name":"app-store","codepoint":"f36f","styles":["brands"],"aliases":[]},{"name":"app-store-ios","codepoint":"f370","styles":["brands"],"aliases":[]},{"name":"apper","codepoint":"f371","styles":["brands"],"aliases":[]},{"name":"apple","codepoint":"f179","styles":["brands"],"aliases":[]},{"name":"apple-pay","codepoint":"f415","styles":["brands"],"aliases":[]},{"name":"apple-whole","codepoint":"f5d1","styles":["solid"],"aliases":["apple-alt"]},{"name":"archway","codepoint":"f557","styles":["solid"],"aliases":[]},{"name":"arrow-down","codepoint":"f063","styles":["solid"],"aliases":[]},{"name":"arrow-down-1-9","codepoint":"f162","styles":["solid"],"aliases":["sort-numeric-asc","sort-numeric-down"]},{"name":"arrow-down-9-1","codepoint":"f886","styles":["solid"],"aliases":["sort-numeric-desc","sort-numeric-down-alt"]},{"name":"arrow-down-a-z","codepoint":"f15d","styles":["solid"],"aliases":["sort-alpha-asc","sort-alpha-down"]},{"name":"arrow-down-long","codepoint":"f175","styles":["solid"],"aliases":["long-arrow-down"]},{"name":"arrow-down-short-wide","codepoint":"f884","styles":["solid"],"aliases":["sort-amount-desc","sort-amount-down-alt"]},{"name":"arrow-down-up-across-line","codepoint":"e4af","styles":["solid"],"aliases":[]},{"name":"arrow-down-up-lock","codepoint":"e4b0","styles":["solid"],"aliases":[]},{"name":"arrow-down-wide-short","codepoint":"f160","styles":["solid"],"aliases":["sort-amount-asc","sort-amount-down"]},{"name":"arrow-down-z-a","codepoint":"f881","styles":["solid"],"aliases":["sort-alpha-desc","sort-alpha-down-alt"]},{"name":"arrow-left","codepoint":"f060","styles":["solid"],"aliases":[]},{"name":"arrow-left-long","codepoint":"f177","styles":["solid"],"aliases":["long-arrow-left"]},{"name":"arrow-pointer","codepoint":"f245","styles":["solid"],"aliases":["mouse-pointer"]},{"name":"arrow-right","codepoint":"f061","styles":["solid"],"aliases":[]},{"name":"arrow-right-arrow-left","codepoint":"f0ec","styles":["solid"],"aliases":["exchange"]},{"name":"arrow-right-from-bracket","codepoint":"f08b","styles":["solid"],"aliases":["sign-out"]},{"name":"arrow-right-long","codepoint":"f178","styles":["solid"],"aliases":["long-arrow-right"]},{"name":"arrow-right-to-bracket","codepoint":"f090","styles":["solid"],"aliases":["sign-in"]},{"name":"arrow-right-to-city","codepoint":"e4b3","styles":["solid"],"aliases":[]},{"name":"arrow-rotate-left","codepoint":"f0e2","styles":["solid"],"aliases":["arrow-left-rotate","arrow-rotate-back","arrow-rotate-backward","undo"]},{"name":"arrow-rotate-right","codepoint":"f01e","styles":["solid"],"aliases":["arrow-right-rotate","arrow-rotate-forward","redo"]},{"name":"arrow-trend-down","codepoint":"e097","styles":["solid"],"aliases":[]},{"name":"arrow-trend-up","codepoint":"e098","styles":["solid"],"aliases":[]},{"name":"arrow-turn-down","codepoint":"f149","styles":["solid"],"aliases":["level-down"]},{"name":"arrow-turn-up","codepoint":"f148","styles":["solid"],"aliases":["level-up"]},{"name":"arrow-up","codepoint":"f062","styles":["solid"],"aliases":[]},{"name":"arrow-up-1-9","codepoint":"f163","styles":["solid"],"aliases":["sort-numeric-up"]},{"name":"arrow-up-9-1","codepoint":"f887","styles":["solid"],"aliases":["sort-numeric-up-alt"]},{"name":"arrow-up-a-z","codepoint":"f15e","styles":["solid"],"aliases":["sort-alpha-up"]},{"name":"arrow-up-from-bracket","codepoint":"e09a","styles":["solid"],"aliases":[]},{"name":"arrow-up-from-ground-water","codepoint":"e4b5","styles":["solid"],"aliases":[]},{"name":"arrow-up-from-water-pump","codepoint":"e4b6","styles":["solid"],"aliases":[]},{"name":"arrow-up-long","codepoint":"f176","styles":["solid"],"aliases":["long-arrow-up"]},{"name":"arrow-up-right-dots","codepoint":"e4b7","styles":["solid"],"aliases":[]},{"name":"arrow-up-right-from-square","codepoint":"f08e","styles":["solid"],"aliases":["external-link"]},{"name":"arrow-up-short-wide","codepoint":"f885","styles":["solid"],"aliases":["sort-amount-up-alt"]},{"name":"arrow-up-wide-short","codepoint":"f161","styles":["solid"],"aliases":["sort-amount-up"]},{"name":"arrow-up-z-a","codepoint":"f882","styles":["solid"],"aliases":["sort-alpha-up-alt"]},{"name":"arrows-down-to-line","codepoint":"e4b8","styles":["solid"],"aliases":[]},{"name":"arrows-down-to-people","codepoint":"e4b9","styles":["solid"],"aliases":[]},{"name":"arrows-left-right","codepoint":"f07e","styles":["solid"],"aliases":["arrows-h"]},{"name":"arrows-left-right-to-line","codepoint":"e4ba","styles":["solid"],"aliases":[]},{"name":"arrows-rotate","codepoint":"f021","styles":["solid"],"aliases":["refresh","sync"]},{"name":"arrows-spin","codepoint":"e4bb","styles":["solid"],"aliases":[]},{"name":"arrows-split-up-and-left","codepoint":"e4bc","styles":["solid"],"aliases":[]},{"name":"arrows-to-circle","codepoint":"e4bd","styles":["solid"],"aliases":[]},{"name":"arrows-to-dot","codepoint":"e4be","styles":["solid"],"aliases":[]},{"name":"arrows-to-eye","codepoint":"e4bf","styles":["solid"],"aliases":[]},{"name":"arrows-turn-right","codepoint":"e4c0","styles":["solid"],"aliases":[]},{"name":"arrows-turn-to-dots","codepoint":"e4c1","styles":["solid"],"aliases":[]},{"name":"arrows-up-down","codepoint":"f07d","styles":["solid"],"aliases":["arrows-v"]},{"name":"arrows-up-down-left-right","codepoint":"f047","styles":["solid"],"aliases":["arrows"]},{"name":"arrows-up-to-line","codepoint":"e4c2","styles":["solid"],"aliases":[]},{"name":"artstation","codepoint":"f77a","styles":["brands"],"aliases":[]},{"name":"asterisk","codepoint":"2a","styles":["solid"],"aliases":[]},{"name":"asymmetrik","codepoint":"f372","styles":["brands"],"aliases":[]},{"name":"at","codepoint":"40","styles":["solid"],"aliases":[]},{"name":"atlassian","codepoint":"f77b","styles":["brands"],"aliases":[]},{"name":"atom","codepoint":"f5d2","styles":["solid"],"aliases":[]},{"name":"audible","codepoint":"f373","styles":["brands"],"aliases":[]},{"name":"audio-description","codepoint":"f29e","styles":["solid"],"aliases":[]},{"name":"austral-sign","codepoint":"e0a9","styles":["solid"],"aliases":[]},{"name":"autoprefixer","codepoint":"f41c","styles":["brands"],"aliases":[]},{"name":"avianex","codepoint":"f374","styles":["brands"],"aliases":[]},{"name":"aviato","codepoint":"f421","styles":["brands"],"aliases":[]},{"name":"award","codepoint":"f559","styles":["solid"],"aliases":[]},{"name":"aws","codepoint":"f375","styles":["brands"],"aliases":[]},{"name":"b","codepoint":"42","styles":["solid"],"aliases":[]},{"name":"baby","codepoint":"f77c","styles":["solid"],"aliases":[]},{"name":"baby-carriage","codepoint":"f77d","styles":["solid"],"aliases":["carriage-baby"]},{"name":"backward","codepoint":"f04a","styles":["solid"],"aliases":[]},{"name":"backward-fast","codepoint":"f049","styles":["solid"],"aliases":["fast-backward"]},{"name":"backward-step","codepoint":"f048","styles":["solid"],"aliases":["step-backward"]},{"name":"bacon","codepoint":"f7e5","styles":["solid"],"aliases":[]},{"name":"bacteria","codepoint":"e059","styles":["solid"],"aliases":[]},{"name":"bacterium","codepoint":"e05a","styles":["solid"],"aliases":[]},{"name":"bag-shopping","codepoint":"f290","styles":["solid"],"aliases":["shopping-bag"]},{"name":"bahai","codepoint":"f666","styles":["solid"],"aliases":["haykal"]},{"name":"baht-sign","codepoint":"e0ac","styles":["solid"],"aliases":[]},{"name":"ban","codepoint":"f05e","styles":["solid"],"aliases":["cancel"]},{"name":"ban-smoking","codepoint":"f54d","styles":["solid"],"aliases":["smoking-ban"]},{"name":"bandage","codepoint":"f462","styles":["solid"],"aliases":["band-aid"]},{"name":"bandcamp","codepoint":"f2d5","styles":["brands"],"aliases":[]},{"name":"bangladeshi-taka-sign","codepoint":"e2e6","styles":["solid"],"aliases":[]},{"name":"barcode","codepoint":"f02a","styles":["solid"],"aliases":[]},{"name":"bars","codepoint":"f0c9","styles":["solid"],"aliases":["navicon"]},{"name":"bars-progress","codepoint":"f828","styles":["solid"],"aliases":["tasks-alt"]},{"name":"bars-staggered","codepoint":"f550","styles":["solid"],"aliases":["reorder","stream"]},{"name":"baseball","codepoint":"f433","styles":["solid"],"aliases":["baseball-ball"]},{"name":"baseball-bat-ball","codepoint":"f432","styles":["solid"],"aliases":[]},{"name":"basket-shopping","codepoint":"f291","styles":["solid"],"aliases":["shopping-basket"]},{"name":"basketball","codepoint":"f434","styles":["solid"],"aliases":["basketball-ball"]},{"name":"bath","codepoint":"f2cd","styles":["solid"],"aliases":["bathtub"]},{"name":"battery-empty","codepoint":"f244","styles":["solid"],"aliases":["battery-0"]},{"name":"battery-full","codepoint":"f240","styles":["solid"],"aliases":["battery","battery-5"]},{"name":"battery-half","codepoint":"f242","styles":["solid"],"aliases":["battery-3"]},{"name":"battery-quarter","codepoint":"f243","styles":["solid"],"aliases":["battery-2"]},{"name":"battery-three-quarters","codepoint":"f241","styles":["solid"],"aliases":["battery-4"]},{"name":"battle-net","codepoint":"f835","styles":["brands"],"aliases":[]},{"name":"bed","codepoint":"f236","styles":["solid"],"aliases":[]},{"name":"bed-pulse","codepoint":"f487","styles":["solid"],"aliases":["procedures"]},{"name":"beer-mug-empty","codepoint":"f0fc","styles":["solid"],"aliases":["beer"]},{"name":"behance","codepoint":"f1b4","styles":["brands"],"aliases":[]},{"name":"bell","codepoint":"f0f3","styles":["regular","solid"],"aliases":[]},{"name":"bell-concierge","codepoint":"f562","styles":["solid"],"aliases":["concierge-bell"]},{"name":"bell-slash","codepoint":"f1f6","styles":["regular","solid"],"aliases":[]},{"name":"bezier-curve","codepoint":"f55b","styles":["solid"],"aliases":[]},{"name":"bicycle","codepoint":"f206","styles":["solid"],"aliases":[]},{"name":"bilibili","codepoint":"e3d9","styles":["brands"],"aliases":[]},{"name":"bimobject","codepoint":"f378","styles":["brands"],"aliases":[]},{"name":"binoculars","codepoint":"f1e5","styles":["solid"],"aliases":[]},{"name":"biohazard","codepoint":"f780","styles":["solid"],"aliases":[]},{"name":"bitbucket","codepoint":"f171","styles":["brands"],"aliases":[]},{"name":"bitcoin","codepoint":"f379","styles":["brands"],"aliases":[]},{"name":"bitcoin-sign","codepoint":"e0b4","styles":["solid"],"aliases":[]},{"name":"bity","codepoint":"f37a","styles":["brands"],"aliases":[]},{"name":"black-tie","codepoint":"f27e","styles":["brands"],"aliases":[]},{"name":"blackberry","codepoint":"f37b","styles":["brands"],"aliases":[]},{"name":"blender","codepoint":"f517","styles":["solid"],"aliases":[]},{"name":"blender-phone","codepoint":"f6b6","styles":["solid"],"aliases":[]},{"name":"blog","codepoint":"f781","styles":["solid"],"aliases":[]},{"name":"blogger","codepoint":"f37c","styles":["brands"],"aliases":[]},{"name":"blogger-b","codepoint":"f37d","styles":["brands"],"aliases":[]},{"name":"bluesky","codepoint":"e671","styles":["brands"],"aliases":[]},{"name":"bluetooth","codepoint":"f293","styles":["brands"],"aliases":[]},{"name":"bluetooth-b","codepoint":"f294","styles":["brands"],"aliases":[]},{"name":"bold","codepoint":"f032","styles":["solid"],"aliases":[]},{"name":"bolt","codepoint":"f0e7","styles":["solid"],"aliases":["zap"]},{"name":"bolt-lightning","codepoint":"e0b7","styles":["solid"],"aliases":[]},{"name":"bomb","codepoint":"f1e2","styles":["solid"],"aliases":[]},{"name":"bone","codepoint":"f5d7","styles":["solid"],"aliases":[]},{"name":"bong","codepoint":"f55c","styles":["solid"],"aliases":[]},{"name":"book","codepoint":"f02d","styles":["solid"],"aliases":[]},{"name":"book-atlas","codepoint":"f558","styles":["solid"],"aliases":["atlas"]},{"name":"book-bible","codepoint":"f647","styles":["solid"],"aliases":["bible"]},{"name":"book-bookmark","codepoint":"e0bb","styles":["solid"],"aliases":[]},{"name":"book-journal-whills","codepoint":"f66a","styles":["solid"],"aliases":["journal-whills"]},{"name":"book-medical","codepoint":"f7e6","styles":["solid"],"aliases":[]},{"name":"book-open","codepoint":"f518","styles":["solid"],"aliases":[]},{"name":"book-open-reader","codepoint":"f5da","styles":["solid"],"aliases":["book-reader"]},{"name":"book-quran","codepoint":"f687","styles":["solid"],"aliases":["quran"]},{"name":"book-skull","codepoint":"f6b7","styles":["solid"],"aliases":["book-dead"]},{"name":"book-tanakh","codepoint":"f827","styles":["solid"],"aliases":["tanakh"]},{"name":"bookmark","codepoint":"f02e","styles":["regular","solid"],"aliases":[]},{"name":"bootstrap","codepoint":"f836","styles":["brands"],"aliases":[]},{"name":"border-all","codepoint":"f84c","styles":["solid"],"aliases":[]},{"name":"border-none","codepoint":"f850","styles":["solid"],"aliases":[]},{"name":"border-top-left","codepoint":"f853","styles":["solid"],"aliases":["border-style"]},{"name":"bore-hole","codepoint":"e4c3","styles":["solid"],"aliases":[]},{"name":"bots","codepoint":"e340","styles":["brands"],"aliases":[]},{"name":"bottle-droplet","codepoint":"e4c4","styles":["solid"],"aliases":[]},{"name":"bottle-water","codepoint":"e4c5","styles":["solid"],"aliases":[]},{"name":"bowl-food","codepoint":"e4c6","styles":["solid"],"aliases":[]},{"name":"bowl-rice","codepoint":"e2eb","styles":["solid"],"aliases":[]},{"name":"bowling-ball","codepoint":"f436","styles":["solid"],"aliases":[]},{"name":"box","codepoint":"f466","styles":["solid"],"aliases":[]},{"name":"box-archive","codepoint":"f187","styles":["solid"],"aliases":["archive"]},{"name":"box-open","codepoint":"f49e","styles":["solid"],"aliases":[]},{"name":"box-tissue","codepoint":"e05b","styles":["solid"],"aliases":[]},{"name":"boxes-packing","codepoint":"e4c7","styles":["solid"],"aliases":[]},{"name":"boxes-stacked","codepoint":"f468","styles":["solid"],"aliases":["boxes","boxes-alt"]},{"name":"braille","codepoint":"f2a1","styles":["solid"],"aliases":[]},{"name":"brain","codepoint":"f5dc","styles":["solid"],"aliases":[]},{"name":"brave","codepoint":"e63c","styles":["brands"],"aliases":[]},{"name":"brave-reverse","codepoint":"e63d","styles":["brands"],"aliases":[]},{"name":"brazilian-real-sign","codepoint":"e46c","styles":["solid"],"aliases":[]},{"name":"bread-slice","codepoint":"f7ec","styles":["solid"],"aliases":[]},{"name":"bridge","codepoint":"e4c8","styles":["solid"],"aliases":[]},{"name":"bridge-circle-check","codepoint":"e4c9","styles":["solid"],"aliases":[]},{"name":"bridge-circle-exclamation","codepoint":"e4ca","styles":["solid"],"aliases":[]},{"name":"bridge-circle-xmark","codepoint":"e4cb","styles":["solid"],"aliases":[]},{"name":"bridge-lock","codepoint":"e4cc","styles":["solid"],"aliases":[]},{"name":"bridge-water","codepoint":"e4ce","styles":["solid"],"aliases":[]},{"name":"briefcase","codepoint":"f0b1","styles":["solid"],"aliases":[]},{"name":"briefcase-medical","codepoint":"f469","styles":["solid"],"aliases":[]},{"name":"broom","codepoint":"f51a","styles":["solid"],"aliases":[]},{"name":"broom-ball","codepoint":"f458","styles":["solid"],"aliases":["quidditch","quidditch-broom-ball"]},{"name":"brush","codepoint":"f55d","styles":["solid"],"aliases":[]},{"name":"btc","codepoint":"f15a","styles":["brands"],"aliases":[]},{"name":"bucket","codepoint":"e4cf","styles":["solid"],"aliases":[]},{"name":"buffer","codepoint":"f837","styles":["brands"],"aliases":[]},{"name":"bug","codepoint":"f188","styles":["solid"],"aliases":[]},{"name":"bug-slash","codepoint":"e490","styles":["solid"],"aliases":[]},{"name":"bugs","codepoint":"e4d0","styles":["solid"],"aliases":[]},{"name":"building","codepoint":"f1ad","styles":["regular","solid"],"aliases":[]},{"name":"building-circle-arrow-right","codepoint":"e4d1","styles":["solid"],"aliases":[]},{"name":"building-circle-check","codepoint":"e4d2","styles":["solid"],"aliases":[]},{"name":"building-circle-exclamation","codepoint":"e4d3","styles":["solid"],"aliases":[]},{"name":"building-circle-xmark","codepoint":"e4d4","styles":["solid"],"aliases":[]},{"name":"building-columns","codepoint":"f19c","styles":["solid"],"aliases":["bank","institution","museum","university"]},{"name":"building-flag","codepoint":"e4d5","styles":["solid"],"aliases":[]},{"name":"building-lock","codepoint":"e4d6","styles":["solid"],"aliases":[]},{"name":"building-ngo","codepoint":"e4d7","styles":["solid"],"aliases":[]},{"name":"building-shield","codepoint":"e4d8","styles":["solid"],"aliases":[]},{"name":"building-un","codepoint":"e4d9","styles":["solid"],"aliases":[]},{"name":"building-user","codepoint":"e4da","styles":["solid"],"aliases":[]},{"name":"building-wheat","codepoint":"e4db","styles":["solid"],"aliases":[]},{"name":"bullhorn","codepoint":"f0a1","styles":["solid"],"aliases":[]},{"name":"bullseye","codepoint":"f140","styles":["solid"],"aliases":[]},{"name":"burger","codepoint":"f805","styles":["solid"],"aliases":["hamburger"]},{"name":"buromobelexperte","codepoint":"f37f","styles":["brands"],"aliases":[]},{"name":"burst","codepoint":"e4dc","styles":["solid"],"aliases":[]},{"name":"bus","codepoint":"f207","styles":["solid"],"aliases":[]},{"name":"bus-simple","codepoint":"f55e","styles":["solid"],"aliases":["bus-alt"]},{"name":"business-time","codepoint":"f64a","styles":["solid"],"aliases":["briefcase-clock"]},{"name":"buy-n-large","codepoint":"f8a6","styles":["brands"],"aliases":[]},{"name":"buysellads","codepoint":"f20d","styles":["brands"],"aliases":[]},{"name":"c","codepoint":"43","styles":["solid"],"aliases":[]},{"name":"cable-car","codepoint":"f7da","styles":["solid"],"aliases":["tram"]},{"name":"cake-candles","codepoint":"f1fd","styles":["solid"],"aliases":["birthday-cake","cake"]},{"name":"calculator","codepoint":"f1ec","styles":["solid"],"aliases":[]},{"name":"calendar","codepoint":"f133","styles":["regular","solid"],"aliases":[]},{"name":"calendar-check","codepoint":"f274","styles":["regular","solid"],"aliases":[]},{"name":"calendar-day","codepoint":"f783","styles":["solid"],"aliases":[]},{"name":"calendar-days","codepoint":"f073","styles":["regular","solid"],"aliases":["calendar-alt"]},{"name":"calendar-minus","codepoint":"f272","styles":["regular","solid"],"aliases":[]},{"name":"calendar-plus","codepoint":"f271","styles":["regular","solid"],"aliases":[]},{"name":"calendar-week","codepoint":"f784","styles":["solid"],"aliases":[]},{"name":"calendar-xmark","codepoint":"f273","styles":["regular","solid"],"aliases":["calendar-times"]},{"name":"camera","codepoint":"f030","styles":["solid"],"aliases":["camera-alt"]},{"name":"camera-retro","codepoint":"f083","styles":["solid"],"aliases":[]},{"name":"camera-rotate","codepoint":"e0d8","styles":["solid"],"aliases":[]},{"name":"campground","codepoint":"f6bb","styles":["solid"],"aliases":[]},{"name":"canadian-maple-leaf","codepoint":"f785","styles":["brands"],"aliases":[]},{"name":"candy-cane","codepoint":"f786","styles":["solid"],"aliases":[]},{"name":"cannabis","codepoint":"f55f","styles":["solid"],"aliases":[]},{"name":"capsules","codepoint":"f46b","styles":["solid"],"aliases":[]},{"name":"car","codepoint":"f1b9","styles":["solid"],"aliases":["automobile"]},{"name":"car-battery","codepoint":"f5df","styles":["solid"],"aliases":["battery-car"]},{"name":"car-burst","codepoint":"f5e1","styles":["solid"],"aliases":["car-crash"]},{"name":"car-on","codepoint":"e4dd","styles":["solid"],"aliases":[]},{"name":"car-rear","codepoint":"f5de","styles":["solid"],"aliases":["car-alt"]},{"name":"car-side","codepoint":"f5e4","styles":["solid"],"aliases":[]},{"name":"car-tunnel","codepoint":"e4de","styles":["solid"],"aliases":[]},{"name":"caravan","codepoint":"f8ff","styles":["solid"],"aliases":[]},{"name":"caret-down","codepoint":"f0d7","styles":["solid"],"aliases":[]},{"name":"caret-left","codepoint":"f0d9","styles":["solid"],"aliases":[]},{"name":"caret-right","codepoint":"f0da","styles":["solid"],"aliases":[]},{"name":"caret-up","codepoint":"f0d8","styles":["solid"],"aliases":[]},{"name":"carrot","codepoint":"f787","styles":["solid"],"aliases":[]},{"name":"cart-arrow-down","codepoint":"f218","styles":["solid"],"aliases":[]},{"name":"cart-flatbed","codepoint":"f474","styles":["solid"],"aliases":["dolly-flatbed"]},{"name":"cart-flatbed-suitcase","codepoint":"f59d","styles":["solid"],"aliases":["luggage-cart"]},{"name":"cart-plus","codepoint":"f217","styles":["solid"],"aliases":[]},{"name":"cart-shopping","codepoint":"f07a","styles":["solid"],"aliases":["shopping-cart"]},{"name":"cash-register","codepoint":"f788","styles":["solid"],"aliases":[]},{"name":"cat","codepoint":"f6be","styles":["solid"],"aliases":[]},{"name":"cc-amazon-pay","codepoint":"f42d","styles":["brands"],"aliases":[]},{"name":"cc-amex","codepoint":"f1f3","styles":["brands"],"aliases":[]},{"name":"cc-apple-pay","codepoint":"f416","styles":["brands"],"aliases":[]},{"name":"cc-diners-club","codepoint":"f24c","styles":["brands"],"aliases":[]},{"name":"cc-discover","codepoint":"f1f2","styles":["brands"],"aliases":[]},{"name":"cc-jcb","codepoint":"f24b","styles":["brands"],"aliases":[]},{"name":"cc-mastercard","codepoint":"f1f1","styles":["brands"],"aliases":[]},{"name":"cc-paypal","codepoint":"f1f4","styles":["brands"],"aliases":[]},{"name":"cc-stripe","codepoint":"f1f5","styles":["brands"],"aliases":[]},{"name":"cc-visa","codepoint":"f1f0","styles":["brands"],"aliases":[]},{"name":"cedi-sign","codepoint":"e0df","styles":["solid"],"aliases":[]},{"name":"cent-sign","codepoint":"e3f5","styles":["solid"],"aliases":[]},{"name":"centercode","codepoint":"f380","styles":["brands"],"aliases":[]},{"name":"centos","codepoint":"f789","styles":["brands"],"aliases":[]},{"name":"certificate","codepoint":"f0a3","styles":["solid"],"aliases":[]},{"name":"chair","codepoint":"f6c0","styles":["solid"],"aliases":[]},{"name":"chalkboard","codepoint":"f51b","styles":["solid"],"aliases":["blackboard"]},{"name":"chalkboard-user","codepoint":"f51c","styles":["solid"],"aliases":["chalkboard-teacher"]},{"name":"champagne-glasses","codepoint":"f79f","styles":["solid"],"aliases":["glass-cheers"]},{"name":"charging-station","codepoint":"f5e7","styles":["solid"],"aliases":[]},{"name":"chart-area","codepoint":"f1fe","styles":["solid"],"aliases":["area-chart"]},{"name":"chart-bar","codepoint":"f080","styles":["regular","solid"],"aliases":["bar-chart"]},{"name":"chart-column","codepoint":"e0e3","styles":["solid"],"aliases":[]},{"name":"chart-diagram","codepoint":"e695","styles":["solid"],"aliases":[]},{"name":"chart-gantt","codepoint":"e0e4","styles":["solid"],"aliases":[]},{"name":"chart-line","codepoint":"f201","styles":["solid"],"aliases":["line-chart"]},{"name":"chart-pie","codepoint":"f200","styles":["solid"],"aliases":["pie-chart"]},{"name":"chart-simple","codepoint":"e473","styles":["solid"],"aliases":[]},{"name":"check","codepoint":"f00c","styles":["solid"],"aliases":[]},{"name":"check-double","codepoint":"f560","styles":["solid"],"aliases":[]},{"name":"check-to-slot","codepoint":"f772","styles":["solid"],"aliases":["vote-yea"]},{"name":"cheese","codepoint":"f7ef","styles":["solid"],"aliases":[]},{"name":"chess","codepoint":"f439","styles":["solid"],"aliases":[]},{"name":"chess-bishop","codepoint":"f43a","styles":["regular","solid"],"aliases":[]},{"name":"chess-board","codepoint":"f43c","styles":["solid"],"aliases":[]},{"name":"chess-king","codepoint":"f43f","styles":["regular","solid"],"aliases":[]},{"name":"chess-knight","codepoint":"f441","styles":["regular","solid"],"aliases":[]},{"name":"chess-pawn","codepoint":"f443","styles":["regular","solid"],"aliases":[]},{"name":"chess-queen","codepoint":"f445","styles":["regular","solid"],"aliases":[]},{"name":"chess-rook","codepoint":"f447","styles":["regular","solid"],"aliases":[]},{"name":"chevron-down","codepoint":"f078","styles":["solid"],"aliases":[]},{"name":"chevron-left","codepoint":"f053","styles":["solid"],"aliases":[]},{"name":"chevron-right","codepoint":"f054","styles":["solid"],"aliases":[]},{"name":"chevron-up","codepoint":"f077","styles":["solid"],"aliases":[]},{"name":"child","codepoint":"f1ae","styles":["solid"],"aliases":[]},{"name":"child-combatant","codepoint":"e4e0","styles":["solid"],"aliases":["child-rifle"]},{"name":"child-dress","codepoint":"e59c","styles":["solid"],"aliases":[]},{"name":"child-reaching","codepoint":"e59d","styles":["solid"],"aliases":[]},{"name":"children","codepoint":"e4e1","styles":["solid"],"aliases":[]},{"name":"chrome","codepoint":"f268","styles":["brands"],"aliases":[]},{"name":"chromecast","codepoint":"f838","styles":["brands"],"aliases":[]},{"name":"church","codepoint":"f51d","styles":["solid"],"aliases":[]},{"name":"circle","codepoint":"f111","styles":["regular","solid"],"aliases":[]},{"name":"circle-arrow-down","codepoint":"f0ab","styles":["solid"],"aliases":["arrow-circle-down"]},{"name":"circle-arrow-left","codepoint":"f0a8","styles":["solid"],"aliases":["arrow-circle-left"]},{"name":"circle-arrow-right","codepoint":"f0a9","styles":["solid"],"aliases":["arrow-circle-right"]},{"name":"circle-arrow-up","codepoint":"f0aa","styles":["solid"],"aliases":["arrow-circle-up"]},{"name":"circle-check","codepoint":"f058","styles":["regular","solid"],"aliases":["check-circle"]},{"name":"circle-chevron-down","codepoint":"f13a","styles":["solid"],"aliases":["chevron-circle-down"]},{"name":"circle-chevron-left","codepoint":"f137","styles":["solid"],"aliases":["chevron-circle-left"]},{"name":"circle-chevron-right","codepoint":"f138","styles":["solid"],"aliases":["chevron-circle-right"]},{"name":"circle-chevron-up","codepoint":"f139","styles":["solid"],"aliases":["chevron-circle-up"]},{"name":"circle-dollar-to-slot","codepoint":"f4b9","styles":["solid"],"aliases":["donate"]},{"name":"circle-dot","codepoint":"f192","styles":["regular","solid"],"aliases":["dot-circle"]},{"name":"circle-down","codepoint":"f358","styles":["regular","solid"],"aliases":["arrow-alt-circle-down"]},{"name":"circle-exclamation","codepoint":"f06a","styles":["solid"],"aliases":["exclamation-circle"]},{"name":"circle-h","codepoint":"f47e","styles":["solid"],"aliases":["hospital-symbol"]},{"name":"circle-half-stroke","codepoint":"f042","styles":["solid"],"aliases":["adjust"]},{"name":"circle-info","codepoint":"f05a","styles":["solid"],"aliases":["info-circle"]},{"name":"circle-left","codepoint":"f359","styles":["regular","solid"],"aliases":["arrow-alt-circle-left"]},{"name":"circle-minus","codepoint":"f056","styles":["solid"],"aliases":["minus-circle"]},{"name":"circle-nodes","codepoint":"e4e2","styles":["solid"],"aliases":[]},{"name":"circle-notch","codepoint":"f1ce","styles":["solid"],"aliases":[]},{"name":"circle-pause","codepoint":"f28b","styles":["regular","solid"],"aliases":["pause-circle"]},{"name":"circle-play","codepoint":"f144","styles":["regular","solid"],"aliases":["play-circle"]},{"name":"circle-plus","codepoint":"f055","styles":["solid"],"aliases":["plus-circle"]},{"name":"circle-question","codepoint":"f059","styles":["regular","solid"],"aliases":["question-circle"]},{"name":"circle-radiation","codepoint":"f7ba","styles":["solid"],"aliases":["radiation-alt"]},{"name":"circle-right","codepoint":"f35a","styles":["regular","solid"],"aliases":["arrow-alt-circle-right"]},{"name":"circle-stop","codepoint":"f28d","styles":["regular","solid"],"aliases":["stop-circle"]},{"name":"circle-up","codepoint":"f35b","styles":["regular","solid"],"aliases":["arrow-alt-circle-up"]},{"name":"circle-user","codepoint":"f2bd","styles":["regular","solid"],"aliases":["user-circle"]},{"name":"circle-xmark","codepoint":"f057","styles":["regular","solid"],"aliases":["times-circle","xmark-circle"]},{"name":"city","codepoint":"f64f","styles":["solid"],"aliases":[]},{"name":"clapperboard","codepoint":"e131","styles":["solid"],"aliases":[]},{"name":"clipboard","codepoint":"f328","styles":["regular","solid"],"aliases":[]},{"name":"clipboard-check","codepoint":"f46c","styles":["solid"],"aliases":[]},{"name":"clipboard-list","codepoint":"f46d","styles":["solid"],"aliases":[]},{"name":"clipboard-question","codepoint":"e4e3","styles":["solid"],"aliases":[]},{"name":"clipboard-user","codepoint":"f7f3","styles":["solid"],"aliases":[]},{"name":"clock","codepoint":"f017","styles":["regular","solid"],"aliases":["clock-four"]},{"name":"clock-rotate-left","codepoint":"f1da","styles":["solid"],"aliases":["history"]},{"name":"clone","codepoint":"f24d","styles":["regular","solid"],"aliases":[]},{"name":"closed-captioning","codepoint":"f20a","styles":["regular","solid"],"aliases":[]},{"name":"cloud","codepoint":"f0c2","styles":["solid"],"aliases":[]},{"name":"cloud-arrow-down","codepoint":"f0ed","styles":["solid"],"aliases":["cloud-download","cloud-download-alt"]},{"name":"cloud-arrow-up","codepoint":"f0ee","styles":["solid"],"aliases":["cloud-upload","cloud-upload-alt"]},{"name":"cloud-bolt","codepoint":"f76c","styles":["solid"],"aliases":["thunderstorm"]},{"name":"cloud-meatball","codepoint":"f73b","styles":["solid"],"aliases":[]},{"name":"cloud-moon","codepoint":"f6c3","styles":["solid"],"aliases":[]},{"name":"cloud-moon-rain","codepoint":"f73c","styles":["solid"],"aliases":[]},{"name":"cloud-rain","codepoint":"f73d","styles":["solid"],"aliases":[]},{"name":"cloud-showers-heavy","codepoint":"f740","styles":["solid"],"aliases":[]},{"name":"cloud-showers-water","codepoint":"e4e4","styles":["solid"],"aliases":[]},{"name":"cloud-sun","codepoint":"f6c4","styles":["solid"],"aliases":[]},{"name":"cloud-sun-rain","codepoint":"f743","styles":["solid"],"aliases":[]},{"name":"cloudflare","codepoint":"e07d","styles":["brands"],"aliases":[]},{"name":"cloudscale","codepoint":"f383","styles":["brands"],"aliases":[]},{"name":"cloudsmith","codepoint":"f384","styles":["brands"],"aliases":[]},{"name":"cloudversify","codepoint":"f385","styles":["brands"],"aliases":[]},{"name":"clover","codepoint":"e139","styles":["solid"],"aliases":[]},{"name":"cmplid","codepoint":"e360","styles":["brands"],"aliases":[]},{"name":"code","codepoint":"f121","styles":["solid"],"aliases":[]},{"name":"code-branch","codepoint":"f126","styles":["solid"],"aliases":[]},{"name":"code-commit","codepoint":"f386","styles":["solid"],"aliases":[]},{"name":"code-compare","codepoint":"e13a","styles":["solid"],"aliases":[]},{"name":"code-fork","codepoint":"e13b","styles":["solid"],"aliases":[]},{"name":"code-merge","codepoint":"f387","styles":["solid"],"aliases":[]},{"name":"code-pull-request","codepoint":"e13c","styles":["solid"],"aliases":[]},{"name":"codepen","codepoint":"f1cb","styles":["brands"],"aliases":[]},{"name":"codiepie","codepoint":"f284","styles":["brands"],"aliases":[]},{"name":"coins","codepoint":"f51e","styles":["solid"],"aliases":[]},{"name":"colon-sign","codepoint":"e140","styles":["solid"],"aliases":[]},{"name":"comment","codepoint":"f075","styles":["regular","solid"],"aliases":[]},{"name":"comment-dollar","codepoint":"f651","styles":["solid"],"aliases":[]},{"name":"comment-dots","codepoint":"f4ad","styles":["regular","solid"],"aliases":["commenting"]},{"name":"comment-medical","codepoint":"f7f5","styles":["solid"],"aliases":[]},{"name":"comment-nodes","codepoint":"e696","styles":["solid"],"aliases":[]},{"name":"comment-slash","codepoint":"f4b3","styles":["solid"],"aliases":[]},{"name":"comment-sms","codepoint":"f7cd","styles":["solid"],"aliases":["sms"]},{"name":"comments","codepoint":"f086","styles":["regular","solid"],"aliases":[]},{"name":"comments-dollar","codepoint":"f653","styles":["solid"],"aliases":[]},{"name":"compact-disc","codepoint":"f51f","styles":["solid"],"aliases":[]},{"name":"compass","codepoint":"f14e","styles":["regular","solid"],"aliases":[]},{"name":"compass-drafting","codepoint":"f568","styles":["solid"],"aliases":["drafting-compass"]},{"name":"compress","codepoint":"f066","styles":["solid"],"aliases":[]},{"name":"computer","codepoint":"e4e5","styles":["solid"],"aliases":[]},{"name":"computer-mouse","codepoint":"f8cc","styles":["solid"],"aliases":["mouse"]},{"name":"confluence","codepoint":"f78d","styles":["brands"],"aliases":[]},{"name":"connectdevelop","codepoint":"f20e","styles":["brands"],"aliases":[]},{"name":"contao","codepoint":"f26d","styles":["brands"],"aliases":[]},{"name":"cookie","codepoint":"f563","styles":["solid"],"aliases":[]},{"name":"cookie-bite","codepoint":"f564","styles":["solid"],"aliases":[]},{"name":"copy","codepoint":"f0c5","styles":["regular","solid"],"aliases":[]},{"name":"copyright","codepoint":"f1f9","styles":["regular","solid"],"aliases":[]},{"name":"cotton-bureau","codepoint":"f89e","styles":["brands"],"aliases":[]},{"name":"couch","codepoint":"f4b8","styles":["solid"],"aliases":[]},{"name":"cow","codepoint":"f6c8","styles":["solid"],"aliases":[]},{"name":"cpanel","codepoint":"f388","styles":["brands"],"aliases":[]},{"name":"creative-commons","codepoint":"f25e","styles":["brands"],"aliases":[]},{"name":"creative-commons-by","codepoint":"f4e7","styles":["brands"],"aliases":[]},{"name":"creative-commons-nc","codepoint":"f4e8","styles":["brands"],"aliases":[]},{"name":"creative-commons-nc-eu","codepoint":"f4e9","styles":["brands"],"aliases":[]},{"name":"creative-commons-nc-jp","codepoint":"f4ea","styles":["brands"],"aliases":[]},{"name":"creative-commons-nd","codepoint":"f4eb","styles":["brands"],"aliases":[]},{"name":"creative-commons-pd","codepoint":"f4ec","styles":["brands"],"aliases":[]},{"name":"creative-commons-pd-alt","codepoint":"f4ed","styles":["brands"],"aliases":[]},{"name":"creative-commons-remix","codepoint":"f4ee","styles":["brands"],"aliases":[]},{"name":"creative-commons-sa","codepoint":"f4ef","styles":["brands"],"aliases":[]},{"name":"creative-commons-sampling","codepoint":"f4f0","styles":["brands"],"aliases":[]},{"name":"creative-commons-sampling-plus","codepoint":"f4f1","styles":["brands"],"aliases":[]},{"name":"creative-commons-share","codepoint":"f4f2","styles":["brands"],"aliases":[]},{"name":"creative-commons-zero","codepoint":"f4f3","styles":["brands"],"aliases":[]},{"name":"credit-card","codepoint":"f09d","styles":["regular","solid"],"aliases":["credit-card-alt"]},{"name":"critical-role","codepoint":"f6c9","styles":["brands"],"aliases":[]},{"name":"crop","codepoint":"f125","styles":["solid"],"aliases":[]},{"name":"crop-simple","codepoint":"f565","styles":["solid"],"aliases":["crop-alt"]},{"name":"cross","codepoint":"f654","styles":["solid"],"aliases":[]},{"name":"crosshairs","codepoint":"f05b","styles":["solid"],"aliases":[]},{"name":"crow","codepoint":"f520","styles":["solid"],"aliases":[]},{"name":"crown","codepoint":"f521","styles":["solid"],"aliases":[]},{"name":"crutch","codepoint":"f7f7","styles":["solid"],"aliases":[]},{"name":"cruzeiro-sign","codepoint":"e152","styles":["solid"],"aliases":[]},{"name":"css","codepoint":"e6a2","styles":["brands"],"aliases":[]},{"name":"css3","codepoint":"f13c","styles":["brands"],"aliases":[]},{"name":"css3-alt","codepoint":"f38b","styles":["brands"],"aliases":[]},{"name":"cube","codepoint":"f1b2","styles":["solid"],"aliases":[]},{"name":"cubes","codepoint":"f1b3","styles":["solid"],"aliases":[]},{"name":"cubes-stacked","codepoint":"e4e6","styles":["solid"],"aliases":[]},{"name":"cuttlefish","codepoint":"f38c","styles":["brands"],"aliases":[]},{"name":"d","codepoint":"44","styles":["solid"],"aliases":[]},{"name":"d-and-d","codepoint":"f38d","styles":["brands"],"aliases":[]},{"name":"d-and-d-beyond","codepoint":"f6ca","styles":["brands"],"aliases":[]},{"name":"dailymotion","codepoint":"e052","styles":["brands"],"aliases":[]},{"name":"dart-lang","codepoint":"e693","styles":["brands"],"aliases":[]},{"name":"dashcube","codepoint":"f210","styles":["brands"],"aliases":[]},{"name":"database","codepoint":"f1c0","styles":["solid"],"aliases":[]},{"name":"debian","codepoint":"e60b","styles":["brands"],"aliases":[]},{"name":"deezer","codepoint":"e077","styles":["brands"],"aliases":[]},{"name":"delete-left","codepoint":"f55a","styles":["solid"],"aliases":["backspace"]},{"name":"delicious","codepoint":"f1a5","styles":["brands"],"aliases":[]},{"name":"democrat","codepoint":"f747","styles":["solid"],"aliases":[]},{"name":"deploydog","codepoint":"f38e","styles":["brands"],"aliases":[]},{"name":"deskpro","codepoint":"f38f","styles":["brands"],"aliases":[]},{"name":"desktop","codepoint":"f390","styles":["solid"],"aliases":["desktop-alt"]},{"name":"dev","codepoint":"f6cc","styles":["brands"],"aliases":[]},{"name":"deviantart","codepoint":"f1bd","styles":["brands"],"aliases":[]},{"name":"dharmachakra","codepoint":"f655","styles":["solid"],"aliases":[]},{"name":"dhl","codepoint":"f790","styles":["brands"],"aliases":[]},{"name":"diagram-next","codepoint":"e476","styles":["solid"],"aliases":[]},{"name":"diagram-predecessor","codepoint":"e477","styles":["solid"],"aliases":[]},{"name":"diagram-project","codepoint":"f542","styles":["solid"],"aliases":["project-diagram"]},{"name":"diagram-successor","codepoint":"e47a","styles":["solid"],"aliases":[]},{"name":"diamond","codepoint":"f219","styles":["solid"],"aliases":[]},{"name":"diamond-turn-right","codepoint":"f5eb","styles":["solid"],"aliases":["directions"]},{"name":"diaspora","codepoint":"f791","styles":["brands"],"aliases":[]},{"name":"dice","codepoint":"f522","styles":["solid"],"aliases":[]},{"name":"dice-d20","codepoint":"f6cf","styles":["solid"],"aliases":[]},{"name":"dice-d6","codepoint":"f6d1","styles":["solid"],"aliases":[]},{"name":"dice-five","codepoint":"f523","styles":["solid"],"aliases":[]},{"name":"dice-four","codepoint":"f524","styles":["solid"],"aliases":[]},{"name":"dice-one","codepoint":"f525","styles":["solid"],"aliases":[]},{"name":"dice-six","codepoint":"f526","styles":["solid"],"aliases":[]},{"name":"dice-three","codepoint":"f527","styles":["solid"],"aliases":[]},{"name":"dice-two","codepoint":"f528","styles":["solid"],"aliases":[]},{"name":"digg","codepoint":"f1a6","styles":["brands"],"aliases":[]},{"name":"digital-ocean","codepoint":"f391","styles":["brands"],"aliases":[]},{"name":"discord","codepoint":"f392","styles":["brands"],"aliases":[]},{"name":"discourse","codepoint":"f393","styles":["brands"],"aliases":[]},{"name":"disease","codepoint":"f7fa","styles":["solid"],"aliases":[]},{"name":"display","codepoint":"e163","styles":["solid"],"aliases":[]},{"name":"divide","codepoint":"f529","styles":["solid"],"aliases":[]},{"name":"dna","codepoint":"f471","styles":["solid"],"aliases":[]},{"name":"dochub","codepoint":"f394","styles":["brands"],"aliases":[]},{"name":"docker","codepoint":"f395","styles":["brands"],"aliases":[]},{"name":"dog","codepoint":"f6d3","styles":["solid"],"aliases":[]},{"name":"dollar-sign","codepoint":"24","styles":["solid"],"aliases":["dollar","usd"]},{"name":"dolly","codepoint":"f472","styles":["solid"],"aliases":["dolly-box"]},{"name":"dong-sign","codepoint":"e169","styles":["solid"],"aliases":[]},{"name":"door-closed","codepoint":"f52a","styles":["solid"],"aliases":[]},{"name":"door-open","codepoint":"f52b","styles":["solid"],"aliases":[]},{"name":"dove","codepoint":"f4ba","styles":["solid"],"aliases":[]},{"name":"down-left-and-up-right-to-center","codepoint":"f422","styles":["solid"],"aliases":["compress-alt"]},{"name":"down-long","codepoint":"f309","styles":["solid"],"aliases":["long-arrow-alt-down"]},{"name":"download","codepoint":"f019","styles":["solid"],"aliases":[]},{"name":"draft2digital","codepoint":"f396","styles":["brands"],"aliases":[]},{"name":"dragon","codepoint":"f6d5","styles":["solid"],"aliases":[]},{"name":"draw-polygon","codepoint":"f5ee","styles":["solid"],"aliases":[]},{"name":"dribbble","codepoint":"f17d","styles":["brands"],"aliases":[]},{"name":"dropbox","codepoint":"f16b","styles":["brands"],"aliases":[]},{"name":"droplet","codepoint":"f043","styles":["solid"],"aliases":["tint"]},{"name":"droplet-slash","codepoint":"f5c7","styles":["solid"],"aliases":["tint-slash"]},{"name":"drum","codepoint":"f569","styles":["solid"],"aliases":[]},{"name":"drum-steelpan","codepoint":"f56a","styles":["solid"],"aliases":[]},{"name":"drumstick-bite","codepoint":"f6d7","styles":["solid"],"aliases":[]},{"name":"drupal","codepoint":"f1a9","styles":["brands"],"aliases":[]},{"name":"dumbbell","codepoint":"f44b","styles":["solid"],"aliases":[]},{"name":"dumpster","codepoint":"f793","styles":["solid"],"aliases":[]},{"name":"dumpster-fire","codepoint":"f794","styles":["solid"],"aliases":[]},{"name":"dungeon","codepoint":"f6d9","styles":["solid"],"aliases":[]},{"name":"dyalog","codepoint":"f399","styles":["brands"],"aliases":[]},{"name":"e","codepoint":"45","styles":["solid"],"aliases":[]},{"name":"ear-deaf","codepoint":"f2a4","styles":["solid"],"aliases":["deaf","deafness","hard-of-hearing"]},{"name":"ear-listen","codepoint":"f2a2","styles":["solid"],"aliases":["assistive-listening-systems"]},{"name":"earlybirds","codepoint":"f39a","styles":["brands"],"aliases":[]},{"name":"earth-africa","codepoint":"f57c","styles":["solid"],"aliases":["globe-africa"]},{"name":"earth-americas","codepoint":"f57d","styles":["solid"],"aliases":["earth","earth-america","globe-americas"]},{"name":"earth-asia","codepoint":"f57e","styles":["solid"],"aliases":["globe-asia"]},{"name":"earth-europe","codepoint":"f7a2","styles":["solid"],"aliases":["globe-europe"]},{"name":"earth-oceania","codepoint":"e47b","styles":["solid"],"aliases":["globe-oceania"]},{"name":"ebay","codepoint":"f4f4","styles":["brands"],"aliases":[]},{"name":"edge","codepoint":"f282","styles":["brands"],"aliases":[]},{"name":"edge-legacy","codepoint":"e078","styles":["brands"],"aliases":[]},{"name":"egg","codepoint":"f7fb","styles":["solid"],"aliases":[]},{"name":"eject","codepoint":"f052","styles":["solid"],"aliases":[]},{"name":"elementor","codepoint":"f430","styles":["brands"],"aliases":[]},{"name":"elevator","codepoint":"e16d","styles":["solid"],"aliases":[]},{"name":"ellipsis","codepoint":"f141","styles":["solid"],"aliases":["ellipsis-h"]},{"name":"ellipsis-vertical","codepoint":"f142","styles":["solid"],"aliases":["ellipsis-v"]},{"name":"ello","codepoint":"f5f1","styles":["brands"],"aliases":[]},{"name":"ember","codepoint":"f423","styles":["brands"],"aliases":[]},{"name":"empire","codepoint":"f1d1","styles":["brands"],"aliases":[]},{"name":"envelope","codepoint":"f0e0","styles":["regular","solid"],"aliases":[]},{"name":"envelope-circle-check","codepoint":"e4e8","styles":["solid"],"aliases":[]},{"name":"envelope-open","codepoint":"f2b6","styles":["regular","solid"],"aliases":[]},{"name":"envelope-open-text","codepoint":"f658","styles":["solid"],"aliases":[]},{"name":"envelopes-bulk","codepoint":"f674","styles":["solid"],"aliases":["mail-bulk"]},{"name":"envira","codepoint":"f299","styles":["brands"],"aliases":[]},{"name":"equals","codepoint":"3d","styles":["solid"],"aliases":[]},{"name":"eraser","codepoint":"f12d","styles":["solid"],"aliases":[]},{"name":"erlang","codepoint":"f39d","styles":["brands"],"aliases":[]},{"name":"ethereum","codepoint":"f42e","styles":["brands"],"aliases":[]},{"name":"ethernet","codepoint":"f796","styles":["solid"],"aliases":[]},{"name":"etsy","codepoint":"f2d7","styles":["brands"],"aliases":[]},{"name":"euro-sign","codepoint":"f153","styles":["solid"],"aliases":["eur","euro"]},{"name":"evernote","codepoint":"f839","styles":["brands"],"aliases":[]},{"name":"exclamation","codepoint":"21","styles":["solid"],"aliases":[]},{"name":"expand","codepoint":"f065","styles":["solid"],"aliases":[]},{"name":"expeditedssl","codepoint":"f23e","styles":["brands"],"aliases":[]},{"name":"explosion","codepoint":"e4e9","styles":["solid"],"aliases":[]},{"name":"eye","codepoint":"f06e","styles":["regular","solid"],"aliases":[]},{"name":"eye-dropper","codepoint":"f1fb","styles":["solid"],"aliases":["eye-dropper-empty","eyedropper"]},{"name":"eye-low-vision","codepoint":"f2a8","styles":["solid"],"aliases":["low-vision"]},{"name":"eye-slash","codepoint":"f070","styles":["regular","solid"],"aliases":[]},{"name":"f","codepoint":"46","styles":["solid"],"aliases":[]},{"name":"face-angry","codepoint":"f556","styles":["regular","solid"],"aliases":["angry"]},{"name":"face-dizzy","codepoint":"f567","styles":["regular","solid"],"aliases":["dizzy"]},{"name":"face-flushed","codepoint":"f579","styles":["regular","solid"],"aliases":["flushed"]},{"name":"face-frown","codepoint":"f119","styles":["regular","solid"],"aliases":["frown"]},{"name":"face-frown-open","codepoint":"f57a","styles":["regular","solid"],"aliases":["frown-open"]},{"name":"face-grimace","codepoint":"f57f","styles":["regular","solid"],"aliases":["grimace"]},{"name":"face-grin","codepoint":"f580","styles":["regular","solid"],"aliases":["grin"]},{"name":"face-grin-beam","codepoint":"f582","styles":["regular","solid"],"aliases":["grin-beam"]},{"name":"face-grin-beam-sweat","codepoint":"f583","styles":["regular","solid"],"aliases":["grin-beam-sweat"]},{"name":"face-grin-hearts","codepoint":"f584","styles":["regular","solid"],"aliases":["grin-hearts"]},{"name":"face-grin-squint","codepoint":"f585","styles":["regular","solid"],"aliases":["grin-squint"]},{"name":"face-grin-squint-tears","codepoint":"f586","styles":["regular","solid"],"aliases":["grin-squint-tears"]},{"name":"face-grin-stars","codepoint":"f587","styles":["regular","solid"],"aliases":["grin-stars"]},{"name":"face-grin-tears","codepoint":"f588","styles":["regular","solid"],"aliases":["grin-tears"]},{"name":"face-grin-tongue","codepoint":"f589","styles":["regular","solid"],"aliases":["grin-tongue"]},{"name":"face-grin-tongue-squint","codepoint":"f58a","styles":["regular","solid"],"aliases":["grin-tongue-squint"]},{"name":"face-grin-tongue-wink","codepoint":"f58b","styles":["regular","solid"],"aliases":["grin-tongue-wink"]},{"name":"face-grin-wide","codepoint":"f581","styles":["regular","solid"],"aliases":["grin-alt"]},{"name":"face-grin-wink","codepoint":"f58c","styles":["regular","solid"],"aliases":["grin-wink"]},{"name":"face-kiss","codepoint":"f596","styles":["regular","solid"],"aliases":["kiss"]},{"name":"face-kiss-beam","codepoint":"f597","styles":["regular","solid"],"aliases":["kiss-beam"]},{"name":"face-kiss-wink-heart","codepoint":"f598","styles":["regular","solid"],"aliases":["kiss-wink-heart"]},{"name":"face-laugh","codepoint":"f599","styles":["regular","solid"],"aliases":["laugh"]},{"name":"face-laugh-beam","codepoint":"f59a","styles":["regular","solid"],"aliases":["laugh-beam"]},{"name":"face-laugh-squint","codepoint":"f59b","styles":["regular","solid"],"aliases":["laugh-squint"]},{"name":"face-laugh-wink","codepoint":"f59c","styles":["regular","solid"],"aliases":["laugh-wink"]},{"name":"face-meh","codepoint":"f11a","styles":["regular","solid"],"aliases":["meh"]},{"name":"face-meh-blank","codepoint":"f5a4","styles":["regular","solid"],"aliases":["meh-blank"]},{"name":"face-rolling-eyes","codepoint":"f5a5","styles":["regular","solid"],"aliases":["meh-rolling-eyes"]},{"name":"face-sad-cry","codepoint":"f5b3","styles":["regular","solid"],"aliases":["sad-cry"]},{"name":"face-sad-tear","codepoint":"f5b4","styles":["regular","solid"],"aliases":["sad-tear"]},{"name":"face-smile","codepoint":"f118","styles":["regular","solid"],"aliases":["smile"]},{"name":"face-smile-beam","codepoint":"f5b8","styles":["regular","solid"],"aliases":["smile-beam"]},{"name":"face-smile-wink","codepoint":"f4da","styles":["regular","solid"],"aliases":["smile-wink"]},{"name":"face-surprise","codepoint":"f5c2","styles":["regular","solid"],"aliases":["surprise"]},{"name":"face-tired","codepoint":"f5c8","styles":["regular","solid"],"aliases":["tired"]},{"name":"facebook","codepoint":"f09a","styles":["brands"],"aliases":[]},{"name":"facebook-f","codepoint":"f39e","styles":["brands"],"aliases":[]},{"name":"facebook-messenger","codepoint":"f39f","styles":["brands"],"aliases":[]},{"name":"fan","codepoint":"f863","styles":["solid"],"aliases":[]},{"name":"fantasy-flight-games","codepoint":"f6dc","styles":["brands"],"aliases":[]},{"name":"faucet","codepoint":"e005","styles":["solid"],"aliases":[]},{"name":"faucet-drip","codepoint":"e006","styles":["solid"],"aliases":[]},{"name":"fax","codepoint":"f1ac","styles":["solid"],"aliases":[]},{"name":"feather","codepoint":"f52d","styles":["solid"],"aliases":[]},{"name":"feather-pointed","codepoint":"f56b","styles":["solid"],"aliases":["feather-alt"]},{"name":"fedex","codepoint":"f797","styles":["brands"],"aliases":[]},{"name":"fedora","codepoint":"f798","styles":["brands"],"aliases":[]},{"name":"ferry","codepoint":"e4ea","styles":["solid"],"aliases":[]},{"name":"figma","codepoint":"f799","styles":["brands"],"aliases":[]},{"name":"file","codepoint":"f15b","styles":["regular","solid"],"aliases":[]},{"name":"file-arrow-down","codepoint":"f56d","styles":["solid"],"aliases":["file-download"]},{"name":"file-arrow-up","codepoint":"f574","styles":["solid"],"aliases":["file-upload"]},{"name":"file-audio","codepoint":"f1c7","styles":["regular","solid"],"aliases":[]},{"name":"file-circle-check","codepoint":"e5a0","styles":["solid"],"aliases":[]},{"name":"file-circle-exclamation","codepoint":"e4eb","styles":["solid"],"aliases":[]},{"name":"file-circle-minus","codepoint":"e4ed","styles":["solid"],"aliases":[]},{"name":"file-circle-plus","codepoint":"e494","styles":["solid"],"aliases":[]},{"name":"file-circle-question","codepoint":"e4ef","styles":["solid"],"aliases":[]},{"name":"file-circle-xmark","codepoint":"e5a1","styles":["solid"],"aliases":[]},{"name":"file-code","codepoint":"f1c9","styles":["regular","solid"],"aliases":[]},{"name":"file-contract","codepoint":"f56c","styles":["solid"],"aliases":[]},{"name":"file-csv","codepoint":"f6dd","styles":["solid"],"aliases":[]},{"name":"file-excel","codepoint":"f1c3","styles":["regular","solid"],"aliases":[]},{"name":"file-export","codepoint":"f56e","styles":["solid"],"aliases":["arrow-right-from-file"]},{"name":"file-fragment","codepoint":"e697","styles":["solid"],"aliases":[]},{"name":"file-half-dashed","codepoint":"e698","styles":["solid"],"aliases":[]},{"name":"file-image","codepoint":"f1c5","styles":["regular","solid"],"aliases":[]},{"name":"file-import","codepoint":"f56f","styles":["solid"],"aliases":["arrow-right-to-file"]},{"name":"file-invoice","codepoint":"f570","styles":["solid"],"aliases":[]},{"name":"file-invoice-dollar","codepoint":"f571","styles":["solid"],"aliases":[]},{"name":"file-lines","codepoint":"f15c","styles":["regular","solid"],"aliases":["file-alt","file-text"]},{"name":"file-medical","codepoint":"f477","styles":["solid"],"aliases":[]},{"name":"file-pdf","codepoint":"f1c1","styles":["regular","solid"],"aliases":[]},{"name":"file-pen","codepoint":"f31c","styles":["solid"],"aliases":["file-edit"]},{"name":"file-powerpoint","codepoint":"f1c4","styles":["regular","solid"],"aliases":[]},{"name":"file-prescription","codepoint":"f572","styles":["solid"],"aliases":[]},{"name":"file-shield","codepoint":"e4f0","styles":["solid"],"aliases":[]},{"name":"file-signature","codepoint":"f573","styles":["solid"],"aliases":[]},{"name":"file-video","codepoint":"f1c8","styles":["regular","solid"],"aliases":[]},{"name":"file-waveform","codepoint":"f478","styles":["solid"],"aliases":["file-medical-alt"]},{"name":"file-word","codepoint":"f1c2","styles":["regular","solid"],"aliases":[]},{"name":"file-zipper","codepoint":"f1c6","styles":["regular","solid"],"aliases":["file-archive"]},{"name":"files-pinwheel","codepoint":"e69f","styles":["brands"],"aliases":[]},{"name":"fill","codepoint":"f575","styles":["solid"],"aliases":[]},{"name":"fill-drip","codepoint":"f576","styles":["solid"],"aliases":[]},{"name":"film","codepoint":"f008","styles":["solid"],"aliases":[]},{"name":"filter","codepoint":"f0b0","styles":["solid"],"aliases":[]},{"name":"filter-circle-dollar","codepoint":"f662","styles":["solid"],"aliases":["funnel-dollar"]},{"name":"filter-circle-xmark","codepoint":"e17b","styles":["solid"],"aliases":[]},{"name":"fingerprint","codepoint":"f577","styles":["solid"],"aliases":[]},{"name":"fire","codepoint":"f06d","styles":["solid"],"aliases":[]},{"name":"fire-burner","codepoint":"e4f1","styles":["solid"],"aliases":[]},{"name":"fire-extinguisher","codepoint":"f134","styles":["solid"],"aliases":[]},{"name":"fire-flame-curved","codepoint":"f7e4","styles":["solid"],"aliases":["fire-alt"]},{"name":"fire-flame-simple","codepoint":"f46a","styles":["solid"],"aliases":["burn"]},{"name":"firefox","codepoint":"f269","styles":["brands"],"aliases":[]},{"name":"firefox-browser","codepoint":"e007","styles":["brands"],"aliases":[]},{"name":"first-order","codepoint":"f2b0","styles":["brands"],"aliases":[]},{"name":"first-order-alt","codepoint":"f50a","styles":["brands"],"aliases":[]},{"name":"firstdraft","codepoint":"f3a1","styles":["brands"],"aliases":[]},{"name":"fish","codepoint":"f578","styles":["solid"],"aliases":[]},{"name":"fish-fins","codepoint":"e4f2","styles":["solid"],"aliases":[]},{"name":"flag","codepoint":"f024","styles":["regular","solid"],"aliases":[]},{"name":"flag-checkered","codepoint":"f11e","styles":["solid"],"aliases":[]},{"name":"flag-usa","codepoint":"f74d","styles":["solid"],"aliases":[]},{"name":"flask","codepoint":"f0c3","styles":["solid"],"aliases":[]},{"name":"flask-vial","codepoint":"e4f3","styles":["solid"],"aliases":[]},{"name":"flickr","codepoint":"f16e","styles":["brands"],"aliases":[]},{"name":"flipboard","codepoint":"f44d","styles":["brands"],"aliases":[]},{"name":"floppy-disk","codepoint":"f0c7","styles":["regular","solid"],"aliases":["save"]},{"name":"florin-sign","codepoint":"e184","styles":["solid"],"aliases":[]},{"name":"flutter","codepoint":"e694","styles":["brands"],"aliases":[]},{"name":"fly","codepoint":"f417","styles":["brands"],"aliases":[]},{"name":"folder","codepoint":"f07b","styles":["regular","solid"],"aliases":["folder-blank"]},{"name":"folder-closed","codepoint":"e185","styles":["regular","solid"],"aliases":[]},{"name":"folder-minus","codepoint":"f65d","styles":["solid"],"aliases":[]},{"name":"folder-open","codepoint":"f07c","styles":["regular","solid"],"aliases":[]},{"name":"folder-plus","codepoint":"f65e","styles":["solid"],"aliases":[]},{"name":"folder-tree","codepoint":"f802","styles":["solid"],"aliases":[]},{"name":"font","codepoint":"f031","styles":["solid"],"aliases":[]},{"name":"font-awesome","codepoint":"f2b4","styles":["brands","regular","solid"],"aliases":["font-awesome-flag","font-awesome-logo-full"]},{"name":"fonticons","codepoint":"f280","styles":["brands"],"aliases":[]},{"name":"fonticons-fi","codepoint":"f3a2","styles":["brands"],"aliases":[]},{"name":"football","codepoint":"f44e","styles":["solid"],"aliases":["football-ball"]},{"name":"fort-awesome","codepoint":"f286","styles":["brands"],"aliases":[]},{"name":"fort-awesome-alt","codepoint":"f3a3","styles":["brands"],"aliases":[]},{"name":"forumbee","codepoint":"f211","styles":["brands"],"aliases":[]},{"name":"forward","codepoint":"f04e","styles":["solid"],"aliases":[]},{"name":"forward-fast","codepoint":"f050","styles":["solid"],"aliases":["fast-forward"]},{"name":"forward-step","codepoint":"f051","styles":["solid"],"aliases":["step-forward"]},{"name":"foursquare","codepoint":"f180","styles":["brands"],"aliases":[]},{"name":"franc-sign","codepoint":"e18f","styles":["solid"],"aliases":[]},{"name":"free-code-camp","codepoint":"f2c5","styles":["brands"],"aliases":[]},{"name":"freebsd","codepoint":"f3a4","styles":["brands"],"aliases":[]},{"name":"frog","codepoint":"f52e","styles":["solid"],"aliases":[]},{"name":"fulcrum","codepoint":"f50b","styles":["brands"],"aliases":[]},{"name":"futbol","codepoint":"f1e3","styles":["regular","solid"],"aliases":["futbol-ball","soccer-ball"]},{"name":"g","codepoint":"47","styles":["solid"],"aliases":[]},{"name":"galactic-republic","codepoint":"f50c","styles":["brands"],"aliases":[]},{"name":"galactic-senate","codepoint":"f50d","styles":["brands"],"aliases":[]},{"name":"gamepad","codepoint":"f11b","styles":["solid"],"aliases":[]},{"name":"gas-pump","codepoint":"f52f","styles":["solid"],"aliases":[]},{"name":"gauge","codepoint":"f624","styles":["solid"],"aliases":["dashboard","gauge-med","tachometer-alt-average"]},{"name":"gauge-high","codepoint":"f625","styles":["solid"],"aliases":["tachometer-alt","tachometer-alt-fast"]},{"name":"gauge-simple","codepoint":"f629","styles":["solid"],"aliases":["gauge-simple-med","tachometer-average"]},{"name":"gauge-simple-high","codepoint":"f62a","styles":["solid"],"aliases":["tachometer","tachometer-fast"]},{"name":"gavel","codepoint":"f0e3","styles":["solid"],"aliases":["legal"]},{"name":"gear","codepoint":"f013","styles":["solid"],"aliases":["cog"]},{"name":"gears","codepoint":"f085","styles":["solid"],"aliases":["cogs"]},{"name":"gem","codepoint":"f3a5","styles":["regular","solid"],"aliases":[]},{"name":"genderless","codepoint":"f22d","styles":["solid"],"aliases":[]},{"name":"get-pocket","codepoint":"f265","styles":["brands"],"aliases":[]},{"name":"gg","codepoint":"f260","styles":["brands"],"aliases":[]},{"name":"gg-circle","codepoint":"f261","styles":["brands"],"aliases":[]},{"name":"ghost","codepoint":"f6e2","styles":["solid"],"aliases":[]},{"name":"gift","codepoint":"f06b","styles":["solid"],"aliases":[]},{"name":"gifts","codepoint":"f79c","styles":["solid"],"aliases":[]},{"name":"git","codepoint":"f1d3","styles":["brands"],"aliases":[]},{"name":"git-alt","codepoint":"f841","styles":["brands"],"aliases":[]},{"name":"github","codepoint":"f09b","styles":["brands"],"aliases":[]},{"name":"github-alt","codepoint":"f113","styles":["brands"],"aliases":[]},{"name":"gitkraken","codepoint":"f3a6","styles":["brands"],"aliases":[]},{"name":"gitlab","codepoint":"f296","styles":["brands"],"aliases":[]},{"name":"gitter","codepoint":"f426","styles":["brands"],"aliases":[]},{"name":"glass-water","codepoint":"e4f4","styles":["solid"],"aliases":[]},{"name":"glass-water-droplet","codepoint":"e4f5","styles":["solid"],"aliases":[]},{"name":"glasses","codepoint":"f530","styles":["solid"],"aliases":[]},{"name":"glide","codepoint":"f2a5","styles":["brands"],"aliases":[]},{"name":"glide-g","codepoint":"f2a6","styles":["brands"],"aliases":[]},{"name":"globe","codepoint":"f0ac","styles":["solid"],"aliases":[]},{"name":"gofore","codepoint":"f3a7","styles":["brands"],"aliases":[]},{"name":"golang","codepoint":"e40f","styles":["brands"],"aliases":[]},{"name":"golf-ball-tee","codepoint":"f450","styles":["solid"],"aliases":["golf-ball"]},{"name":"goodreads","codepoint":"f3a8","styles":["brands"],"aliases":[]},{"name":"goodreads-g","codepoint":"f3a9","styles":["brands"],"aliases":[]},{"name":"google","codepoint":"f1a0","styles":["brands"],"aliases":[]},{"name":"google-drive","codepoint":"f3aa","styles":["brands"],"aliases":[]},{"name":"google-pay","codepoint":"e079","styles":["brands"],"aliases":[]},{"name":"google-play","codepoint":"f3ab","styles":["brands"],"aliases":[]},{"name":"google-plus","codepoint":"f2b3","styles":["brands"],"aliases":[]},{"name":"google-plus-g","codepoint":"f0d5","styles":["brands"],"aliases":[]},{"name":"google-scholar","codepoint":"e63b","styles":["brands"],"aliases":[]},{"name":"google-wallet","codepoint":"f1ee","styles":["brands"],"aliases":[]},{"name":"gopuram","codepoint":"f664","styles":["solid"],"aliases":[]},{"name":"graduation-cap","codepoint":"f19d","styles":["solid"],"aliases":["mortar-board"]},{"name":"gratipay","codepoint":"f184","styles":["brands"],"aliases":[]},{"name":"grav","codepoint":"f2d6","styles":["brands"],"aliases":[]},{"name":"greater-than","codepoint":"3e","styles":["solid"],"aliases":[]},{"name":"greater-than-equal","codepoint":"f532","styles":["solid"],"aliases":[]},{"name":"grip","codepoint":"f58d","styles":["solid"],"aliases":["grip-horizontal"]},{"name":"grip-lines","codepoint":"f7a4","styles":["solid"],"aliases":[]},{"name":"grip-lines-vertical","codepoint":"f7a5","styles":["solid"],"aliases":[]},{"name":"grip-vertical","codepoint":"f58e","styles":["solid"],"aliases":[]},{"name":"gripfire","codepoint":"f3ac","styles":["brands"],"aliases":[]},{"name":"group-arrows-rotate","codepoint":"e4f6","styles":["solid"],"aliases":[]},{"name":"grunt","codepoint":"f3ad","styles":["brands"],"aliases":[]},{"name":"guarani-sign","codepoint":"e19a","styles":["solid"],"aliases":[]},{"name":"guilded","codepoint":"e07e","styles":["brands"],"aliases":[]},{"name":"guitar","codepoint":"f7a6","styles":["solid"],"aliases":[]},{"name":"gulp","codepoint":"f3ae","styles":["brands"],"aliases":[]},{"name":"gun","codepoint":"e19b","styles":["solid"],"aliases":[]},{"name":"h","codepoint":"48","styles":["solid"],"aliases":[]},{"name":"hacker-news","codepoint":"f1d4","styles":["brands"],"aliases":[]},{"name":"hackerrank","codepoint":"f5f7","styles":["brands"],"aliases":[]},{"name":"hammer","codepoint":"f6e3","styles":["solid"],"aliases":[]},{"name":"hamsa","codepoint":"f665","styles":["solid"],"aliases":[]},{"name":"hand","codepoint":"f256","styles":["regular","solid"],"aliases":["hand-paper"]},{"name":"hand-back-fist","codepoint":"f255","styles":["regular","solid"],"aliases":["hand-rock"]},{"name":"hand-dots","codepoint":"f461","styles":["solid"],"aliases":["allergies"]},{"name":"hand-fist","codepoint":"f6de","styles":["solid"],"aliases":["fist-raised"]},{"name":"hand-holding","codepoint":"f4bd","styles":["solid"],"aliases":[]},{"name":"hand-holding-dollar","codepoint":"f4c0","styles":["solid"],"aliases":["hand-holding-usd"]},{"name":"hand-holding-droplet","codepoint":"f4c1","styles":["solid"],"aliases":["hand-holding-water"]},{"name":"hand-holding-hand","codepoint":"e4f7","styles":["solid"],"aliases":[]},{"name":"hand-holding-heart","codepoint":"f4be","styles":["solid"],"aliases":[]},{"name":"hand-holding-medical","codepoint":"e05c","styles":["solid"],"aliases":[]},{"name":"hand-lizard","codepoint":"f258","styles":["regular","solid"],"aliases":[]},{"name":"hand-middle-finger","codepoint":"f806","styles":["solid"],"aliases":[]},{"name":"hand-peace","codepoint":"f25b","styles":["regular","solid"],"aliases":[]},{"name":"hand-point-down","codepoint":"f0a7","styles":["regular","solid"],"aliases":[]},{"name":"hand-point-left","codepoint":"f0a5","styles":["regular","solid"],"aliases":[]},{"name":"hand-point-right","codepoint":"f0a4","styles":["regular","solid"],"aliases":[]},{"name":"hand-point-up","codepoint":"f0a6","styles":["regular","solid"],"aliases":[]},{"name":"hand-pointer","codepoint":"f25a","styles":["regular","solid"],"aliases":[]},{"name":"hand-scissors","codepoint":"f257","styles":["regular","solid"],"aliases":[]},{"name":"hand-sparkles","codepoint":"e05d","styles":["solid"],"aliases":[]},{"name":"hand-spock","codepoint":"f259","styles":["regular","solid"],"aliases":[]},{"name":"handcuffs","codepoint":"e4f8","styles":["solid"],"aliases":[]},{"name":"hands","codepoint":"f2a7","styles":["solid"],"aliases":["sign-language","signing"]},{"name":"hands-asl-interpreting","codepoint":"f2a3","styles":["solid"],"aliases":["american-sign-language-interpreting","asl-interpreting","hands-american-sign-language-interpreting"]},{"name":"hands-bound","codepoint":"e4f9","styles":["solid"],"aliases":[]},{"name":"hands-bubbles","codepoint":"e05e","styles":["solid"],"aliases":["hands-wash"]},{"name":"hands-clapping","codepoint":"e1a8","styles":["solid"],"aliases":[]},{"name":"hands-holding","codepoint":"f4c2","styles":["solid"],"aliases":[]},{"name":"hands-holding-child","codepoint":"e4fa","styles":["solid"],"aliases":[]},{"name":"hands-holding-circle","codepoint":"e4fb","styles":["solid"],"aliases":[]},{"name":"hands-praying","codepoint":"f684","styles":["solid"],"aliases":["praying-hands"]},{"name":"handshake","codepoint":"f2b5","styles":["regular","solid"],"aliases":[]},{"name":"handshake-angle","codepoint":"f4c4","styles":["solid"],"aliases":["hands-helping"]},{"name":"handshake-simple","codepoint":"f4c6","styles":["solid"],"aliases":["handshake-alt"]},{"name":"handshake-simple-slash","codepoint":"e05f","styles":["solid"],"aliases":["handshake-alt-slash"]},{"name":"handshake-slash","codepoint":"e060","styles":["solid"],"aliases":[]},{"name":"hanukiah","codepoint":"f6e6","styles":["solid"],"aliases":[]},{"name":"hard-drive","codepoint":"f0a0","styles":["regular","solid"],"aliases":["hdd"]},{"name":"hashnode","codepoint":"e499","styles":["brands"],"aliases":[]},{"name":"hashtag","codepoint":"23","styles":["solid"],"aliases":[]},{"name":"hat-cowboy","codepoint":"f8c0","styles":["solid"],"aliases":[]},{"name":"hat-cowboy-side","codepoint":"f8c1","styles":["solid"],"aliases":[]},{"name":"hat-wizard","codepoint":"f6e8","styles":["solid"],"aliases":[]},{"name":"head-side-cough","codepoint":"e061","styles":["solid"],"aliases":[]},{"name":"head-side-cough-slash","codepoint":"e062","styles":["solid"],"aliases":[]},{"name":"head-side-mask","codepoint":"e063","styles":["solid"],"aliases":[]},{"name":"head-side-virus","codepoint":"e064","styles":["solid"],"aliases":[]},{"name":"heading","codepoint":"f1dc","styles":["solid"],"aliases":["header"]},{"name":"headphones","codepoint":"f025","styles":["solid"],"aliases":[]},{"name":"headphones-simple","codepoint":"f58f","styles":["solid"],"aliases":["headphones-alt"]},{"name":"headset","codepoint":"f590","styles":["solid"],"aliases":[]},{"name":"heart","codepoint":"f004","styles":["regular","solid"],"aliases":[]},{"name":"heart-circle-bolt","codepoint":"e4fc","styles":["solid"],"aliases":[]},{"name":"heart-circle-check","codepoint":"e4fd","styles":["solid"],"aliases":[]},{"name":"heart-circle-exclamation","codepoint":"e4fe","styles":["solid"],"aliases":[]},{"name":"heart-circle-minus","codepoint":"e4ff","styles":["solid"],"aliases":[]},{"name":"heart-circle-plus","codepoint":"e500","styles":["solid"],"aliases":[]},{"name":"heart-circle-xmark","codepoint":"e501","styles":["solid"],"aliases":[]},{"name":"heart-crack","codepoint":"f7a9","styles":["solid"],"aliases":["heart-broken"]},{"name":"heart-pulse","codepoint":"f21e","styles":["solid"],"aliases":["heartbeat"]},{"name":"helicopter","codepoint":"f533","styles":["solid"],"aliases":[]},{"name":"helicopter-symbol","codepoint":"e502","styles":["solid"],"aliases":[]},{"name":"helmet-safety","codepoint":"f807","styles":["solid"],"aliases":["hard-hat","hat-hard"]},{"name":"helmet-un","codepoint":"e503","styles":["solid"],"aliases":[]},{"name":"hexagon-nodes","codepoint":"e699","styles":["solid"],"aliases":[]},{"name":"hexagon-nodes-bolt","codepoint":"e69a","styles":["solid"],"aliases":[]},{"name":"highlighter","codepoint":"f591","styles":["solid"],"aliases":[]},{"name":"hill-avalanche","codepoint":"e507","styles":["solid"],"aliases":[]},{"name":"hill-rockslide","codepoint":"e508","styles":["solid"],"aliases":[]},{"name":"hippo","codepoint":"f6ed","styles":["solid"],"aliases":[]},{"name":"hips","codepoint":"f452","styles":["brands"],"aliases":[]},{"name":"hire-a-helper","codepoint":"f3b0","styles":["brands"],"aliases":[]},{"name":"hive","codepoint":"e07f","styles":["brands"],"aliases":[]},{"name":"hockey-puck","codepoint":"f453","styles":["solid"],"aliases":[]},{"name":"holly-berry","codepoint":"f7aa","styles":["solid"],"aliases":[]},{"name":"hooli","codepoint":"f427","styles":["brands"],"aliases":[]},{"name":"hornbill","codepoint":"f592","styles":["brands"],"aliases":[]},{"name":"horse","codepoint":"f6f0","styles":["solid"],"aliases":[]},{"name":"horse-head","codepoint":"f7ab","styles":["solid"],"aliases":[]},{"name":"hospital","codepoint":"f0f8","styles":["regular","solid"],"aliases":["hospital-alt","hospital-wide"]},{"name":"hospital-user","codepoint":"f80d","styles":["solid"],"aliases":[]},{"name":"hot-tub-person","codepoint":"f593","styles":["solid"],"aliases":["hot-tub"]},{"name":"hotdog","codepoint":"f80f","styles":["solid"],"aliases":[]},{"name":"hotel","codepoint":"f594","styles":["solid"],"aliases":[]},{"name":"hotjar","codepoint":"f3b1","styles":["brands"],"aliases":[]},{"name":"hourglass","codepoint":"f254","styles":["regular","solid"],"aliases":["hourglass-empty"]},{"name":"hourglass-end","codepoint":"f253","styles":["solid"],"aliases":["hourglass-3"]},{"name":"hourglass-half","codepoint":"f252","styles":["regular","solid"],"aliases":["hourglass-2"]},{"name":"hourglass-start","codepoint":"f251","styles":["solid"],"aliases":["hourglass-1"]},{"name":"house","codepoint":"f015","styles":["solid"],"aliases":["home","home-alt","home-lg-alt"]},{"name":"house-chimney","codepoint":"e3af","styles":["solid"],"aliases":["home-lg"]},{"name":"house-chimney-crack","codepoint":"f6f1","styles":["solid"],"aliases":["house-damage"]},{"name":"house-chimney-medical","codepoint":"f7f2","styles":["solid"],"aliases":["clinic-medical"]},{"name":"house-chimney-user","codepoint":"e065","styles":["solid"],"aliases":[]},{"name":"house-chimney-window","codepoint":"e00d","styles":["solid"],"aliases":[]},{"name":"house-circle-check","codepoint":"e509","styles":["solid"],"aliases":[]},{"name":"house-circle-exclamation","codepoint":"e50a","styles":["solid"],"aliases":[]},{"name":"house-circle-xmark","codepoint":"e50b","styles":["solid"],"aliases":[]},{"name":"house-crack","codepoint":"e3b1","styles":["solid"],"aliases":[]},{"name":"house-fire","codepoint":"e50c","styles":["solid"],"aliases":[]},{"name":"house-flag","codepoint":"e50d","styles":["solid"],"aliases":[]},{"name":"house-flood-water","codepoint":"e50e","styles":["solid"],"aliases":[]},{"name":"house-flood-water-circle-arrow-right","codepoint":"e50f","styles":["solid"],"aliases":[]},{"name":"house-laptop","codepoint":"e066","styles":["solid"],"aliases":["laptop-house"]},{"name":"house-lock","codepoint":"e510","styles":["solid"],"aliases":[]},{"name":"house-medical","codepoint":"e3b2","styles":["solid"],"aliases":[]},{"name":"house-medical-circle-check","codepoint":"e511","styles":["solid"],"aliases":[]},{"name":"house-medical-circle-exclamation","codepoint":"e512","styles":["solid"],"aliases":[]},{"name":"house-medical-circle-xmark","codepoint":"e513","styles":["solid"],"aliases":[]},{"name":"house-medical-flag","codepoint":"e514","styles":["solid"],"aliases":[]},{"name":"house-signal","codepoint":"e012","styles":["solid"],"aliases":[]},{"name":"house-tsunami","codepoint":"e515","styles":["solid"],"aliases":[]},{"name":"house-user","codepoint":"e1b0","styles":["solid"],"aliases":["home-user"]},{"name":"houzz","codepoint":"f27c","styles":["brands"],"aliases":[]},{"name":"hryvnia-sign","codepoint":"f6f2","styles":["solid"],"aliases":["hryvnia"]},{"name":"html5","codepoint":"f13b","styles":["brands"],"aliases":[]},{"name":"hubspot","codepoint":"f3b2","styles":["brands"],"aliases":[]},{"name":"hurricane","codepoint":"f751","styles":["solid"],"aliases":[]},{"name":"i","codepoint":"49","styles":["solid"],"aliases":[]},{"name":"i-cursor","codepoint":"f246","styles":["solid"],"aliases":[]},{"name":"ice-cream","codepoint":"f810","styles":["solid"],"aliases":[]},{"name":"icicles","codepoint":"f7ad","styles":["solid"],"aliases":[]},{"name":"icons","codepoint":"f86d","styles":["solid"],"aliases":["heart-music-camera-bolt"]},{"name":"id-badge","codepoint":"f2c1","styles":["regular","solid"],"aliases":[]},{"name":"id-card","codepoint":"f2c2","styles":["regular","solid"],"aliases":["drivers-license"]},{"name":"id-card-clip","codepoint":"f47f","styles":["solid"],"aliases":["id-card-alt"]},{"name":"ideal","codepoint":"e013","styles":["brands"],"aliases":[]},{"name":"igloo","codepoint":"f7ae","styles":["solid"],"aliases":[]},{"name":"image","codepoint":"f03e","styles":["regular","solid"],"aliases":[]},{"name":"image-portrait","codepoint":"f3e0","styles":["solid"],"aliases":["portrait"]},{"name":"images","codepoint":"f302","styles":["regular","solid"],"aliases":[]},{"name":"imdb","codepoint":"f2d8","styles":["brands"],"aliases":[]},{"name":"inbox","codepoint":"f01c","styles":["solid"],"aliases":[]},{"name":"indent","codepoint":"f03c","styles":["solid"],"aliases":[]},{"name":"indian-rupee-sign","codepoint":"e1bc","styles":["solid"],"aliases":["indian-rupee","inr"]},{"name":"industry","codepoint":"f275","styles":["solid"],"aliases":[]},{"name":"infinity","codepoint":"f534","styles":["solid"],"aliases":[]},{"name":"info","codepoint":"f129","styles":["solid"],"aliases":[]},{"name":"instagram","codepoint":"f16d","styles":["brands"],"aliases":[]},{"name":"instalod","codepoint":"e081","styles":["brands"],"aliases":[]},{"name":"intercom","codepoint":"f7af","styles":["brands"],"aliases":[]},{"name":"internet-explorer","codepoint":"f26b","styles":["brands"],"aliases":[]},{"name":"invision","codepoint":"f7b0","styles":["brands"],"aliases":[]},{"name":"ioxhost","codepoint":"f208","styles":["brands"],"aliases":[]},{"name":"italic","codepoint":"f033","styles":["solid"],"aliases":[]},{"name":"itch-io","codepoint":"f83a","styles":["brands"],"aliases":[]},{"name":"itunes","codepoint":"f3b4","styles":["brands"],"aliases":[]},{"name":"itunes-note","codepoint":"f3b5","styles":["brands"],"aliases":[]},{"name":"j","codepoint":"4a","styles":["solid"],"aliases":[]},{"name":"jar","codepoint":"e516","styles":["solid"],"aliases":[]},{"name":"jar-wheat","codepoint":"e517","styles":["solid"],"aliases":[]},{"name":"java","codepoint":"f4e4","styles":["brands"],"aliases":[]},{"name":"jedi","codepoint":"f669","styles":["solid"],"aliases":[]},{"name":"jedi-order","codepoint":"f50e","styles":["brands"],"aliases":[]},{"name":"jenkins","codepoint":"f3b6","styles":["brands"],"aliases":[]},{"name":"jet-fighter","codepoint":"f0fb","styles":["solid"],"aliases":["fighter-jet"]},{"name":"jet-fighter-up","codepoint":"e518","styles":["solid"],"aliases":[]},{"name":"jira","codepoint":"f7b1","styles":["brands"],"aliases":[]},{"name":"joget","codepoint":"f3b7","styles":["brands"],"aliases":[]},{"name":"joint","codepoint":"f595","styles":["solid"],"aliases":[]},{"name":"joomla","codepoint":"f1aa","styles":["brands"],"aliases":[]},{"name":"js","codepoint":"f3b8","styles":["brands"],"aliases":[]},{"name":"jsfiddle","codepoint":"f1cc","styles":["brands"],"aliases":[]},{"name":"jug-detergent","codepoint":"e519","styles":["solid"],"aliases":[]},{"name":"jxl","codepoint":"e67b","styles":["brands"],"aliases":[]},{"name":"k","codepoint":"4b","styles":["solid"],"aliases":[]},{"name":"kaaba","codepoint":"f66b","styles":["solid"],"aliases":[]},{"name":"kaggle","codepoint":"f5fa","styles":["brands"],"aliases":[]},{"name":"key","codepoint":"f084","styles":["solid"],"aliases":[]},{"name":"keybase","codepoint":"f4f5","styles":["brands"],"aliases":[]},{"name":"keyboard","codepoint":"f11c","styles":["regular","solid"],"aliases":[]},{"name":"keycdn","codepoint":"f3ba","styles":["brands"],"aliases":[]},{"name":"khanda","codepoint":"f66d","styles":["solid"],"aliases":[]},{"name":"kickstarter","codepoint":"f3bb","styles":["brands"],"aliases":["square-kickstarter"]},{"name":"kickstarter-k","codepoint":"f3bc","styles":["brands"],"aliases":[]},{"name":"kip-sign","codepoint":"e1c4","styles":["solid"],"aliases":[]},{"name":"kit-medical","codepoint":"f479","styles":["solid"],"aliases":["first-aid"]},{"name":"kitchen-set","codepoint":"e51a","styles":["solid"],"aliases":[]},{"name":"kiwi-bird","codepoint":"f535","styles":["solid"],"aliases":[]},{"name":"korvue","codepoint":"f42f","styles":["brands"],"aliases":[]},{"name":"l","codepoint":"4c","styles":["solid"],"aliases":[]},{"name":"land-mine-on","codepoint":"e51b","styles":["solid"],"aliases":[]},{"name":"landmark","codepoint":"f66f","styles":["solid"],"aliases":[]},{"name":"landmark-dome","codepoint":"f752","styles":["solid"],"aliases":["landmark-alt"]},{"name":"landmark-flag","codepoint":"e51c","styles":["solid"],"aliases":[]},{"name":"language","codepoint":"f1ab","styles":["solid"],"aliases":[]},{"name":"laptop","codepoint":"f109","styles":["solid"],"aliases":[]},{"name":"laptop-code","codepoint":"f5fc","styles":["solid"],"aliases":[]},{"name":"laptop-file","codepoint":"e51d","styles":["solid"],"aliases":[]},{"name":"laptop-medical","codepoint":"f812","styles":["solid"],"aliases":[]},{"name":"laravel","codepoint":"f3bd","styles":["brands"],"aliases":[]},{"name":"lari-sign","codepoint":"e1c8","styles":["solid"],"aliases":[]},{"name":"lastfm","codepoint":"f202","styles":["brands"],"aliases":[]},{"name":"layer-group","codepoint":"f5fd","styles":["solid"],"aliases":[]},{"name":"leaf","codepoint":"f06c","styles":["solid"],"aliases":[]},{"name":"leanpub","codepoint":"f212","styles":["brands"],"aliases":[]},{"name":"left-long","codepoint":"f30a","styles":["solid"],"aliases":["long-arrow-alt-left"]},{"name":"left-right","codepoint":"f337","styles":["solid"],"aliases":["arrows-alt-h"]},{"name":"lemon","codepoint":"f094","styles":["regular","solid"],"aliases":[]},{"name":"less","codepoint":"f41d","styles":["brands"],"aliases":[]},{"name":"less-than","codepoint":"3c","styles":["solid"],"aliases":[]},{"name":"less-than-equal","codepoint":"f537","styles":["solid"],"aliases":[]},{"name":"letterboxd","codepoint":"e62d","styles":["brands"],"aliases":[]},{"name":"life-ring","codepoint":"f1cd","styles":["regular","solid"],"aliases":[]},{"name":"lightbulb","codepoint":"f0eb","styles":["regular","solid"],"aliases":[]},{"name":"line","codepoint":"f3c0","styles":["brands"],"aliases":[]},{"name":"lines-leaning","codepoint":"e51e","styles":["solid"],"aliases":[]},{"name":"link","codepoint":"f0c1","styles":["solid"],"aliases":["chain"]},{"name":"link-slash","codepoint":"f127","styles":["solid"],"aliases":["chain-broken","chain-slash","unlink"]},{"name":"linkedin","codepoint":"f08c","styles":["brands"],"aliases":[]},{"name":"linkedin-in","codepoint":"f0e1","styles":["brands"],"aliases":[]},{"name":"linode","codepoint":"f2b8","styles":["brands"],"aliases":[]},{"name":"linux","codepoint":"f17c","styles":["brands"],"aliases":[]},{"name":"lira-sign","codepoint":"f195","styles":["solid"],"aliases":[]},{"name":"list","codepoint":"f03a","styles":["solid"],"aliases":["list-squares"]},{"name":"list-check","codepoint":"f0ae","styles":["solid"],"aliases":["tasks"]},{"name":"list-ol","codepoint":"f0cb","styles":["solid"],"aliases":["list-1-2","list-numeric"]},{"name":"list-ul","codepoint":"f0ca","styles":["solid"],"aliases":["list-dots"]},{"name":"litecoin-sign","codepoint":"e1d3","styles":["solid"],"aliases":[]},{"name":"location-arrow","codepoint":"f124","styles":["solid"],"aliases":[]},{"name":"location-crosshairs","codepoint":"f601","styles":["solid"],"aliases":["location"]},{"name":"location-dot","codepoint":"f3c5","styles":["solid"],"aliases":["map-marker-alt"]},{"name":"location-pin","codepoint":"f041","styles":["solid"],"aliases":["map-marker"]},{"name":"location-pin-lock","codepoint":"e51f","styles":["solid"],"aliases":[]},{"name":"lock","codepoint":"f023","styles":["solid"],"aliases":[]},{"name":"lock-open","codepoint":"f3c1","styles":["solid"],"aliases":[]},{"name":"locust","codepoint":"e520","styles":["solid"],"aliases":[]},{"name":"lungs","codepoint":"f604","styles":["solid"],"aliases":[]},{"name":"lungs-virus","codepoint":"e067","styles":["solid"],"aliases":[]},{"name":"lyft","codepoint":"f3c3","styles":["brands"],"aliases":[]},{"name":"m","codepoint":"4d","styles":["solid"],"aliases":[]},{"name":"magento","codepoint":"f3c4","styles":["brands"],"aliases":[]},{"name":"magnet","codepoint":"f076","styles":["solid"],"aliases":[]},{"name":"magnifying-glass","codepoint":"f002","styles":["solid"],"aliases":["search"]},{"name":"magnifying-glass-arrow-right","codepoint":"e521","styles":["solid"],"aliases":[]},{"name":"magnifying-glass-chart","codepoint":"e522","styles":["solid"],"aliases":[]},{"name":"magnifying-glass-dollar","codepoint":"f688","styles":["solid"],"aliases":["search-dollar"]},{"name":"magnifying-glass-location","codepoint":"f689","styles":["solid"],"aliases":["search-location"]},{"name":"magnifying-glass-minus","codepoint":"f010","styles":["solid"],"aliases":["search-minus"]},{"name":"magnifying-glass-plus","codepoint":"f00e","styles":["solid"],"aliases":["search-plus"]},{"name":"mailchimp","codepoint":"f59e","styles":["brands"],"aliases":[]},{"name":"manat-sign","codepoint":"e1d5","styles":["solid"],"aliases":[]},{"name":"mandalorian","codepoint":"f50f","styles":["brands"],"aliases":[]},{"name":"map","codepoint":"f279","styles":["regular","solid"],"aliases":[]},{"name":"map-location","codepoint":"f59f","styles":["solid"],"aliases":["map-marked"]},{"name":"map-location-dot","codepoint":"f5a0","styles":["solid"],"aliases":["map-marked-alt"]},{"name":"map-pin","codepoint":"f276","styles":["solid"],"aliases":[]},{"name":"markdown","codepoint":"f60f","styles":["brands"],"aliases":[]},{"name":"marker","codepoint":"f5a1","styles":["solid"],"aliases":[]},{"name":"mars","codepoint":"f222","styles":["solid"],"aliases":[]},{"name":"mars-and-venus","codepoint":"f224","styles":["solid"],"aliases":[]},{"name":"mars-and-venus-burst","codepoint":"e523","styles":["solid"],"aliases":[]},{"name":"mars-double","codepoint":"f227","styles":["solid"],"aliases":[]},{"name":"mars-stroke","codepoint":"f229","styles":["solid"],"aliases":[]},{"name":"mars-stroke-right","codepoint":"f22b","styles":["solid"],"aliases":["mars-stroke-h"]},{"name":"mars-stroke-up","codepoint":"f22a","styles":["solid"],"aliases":["mars-stroke-v"]},{"name":"martini-glass","codepoint":"f57b","styles":["solid"],"aliases":["glass-martini-alt"]},{"name":"martini-glass-citrus","codepoint":"f561","styles":["solid"],"aliases":["cocktail"]},{"name":"martini-glass-empty","codepoint":"f000","styles":["solid"],"aliases":["glass-martini"]},{"name":"mask","codepoint":"f6fa","styles":["solid"],"aliases":[]},{"name":"mask-face","codepoint":"e1d7","styles":["solid"],"aliases":[]},{"name":"mask-ventilator","codepoint":"e524","styles":["solid"],"aliases":[]},{"name":"masks-theater","codepoint":"f630","styles":["solid"],"aliases":["theater-masks"]},{"name":"mastodon","codepoint":"f4f6","styles":["brands"],"aliases":[]},{"name":"mattress-pillow","codepoint":"e525","styles":["solid"],"aliases":[]},{"name":"maxcdn","codepoint":"f136","styles":["brands"],"aliases":[]},{"name":"maximize","codepoint":"f31e","styles":["solid"],"aliases":["expand-arrows-alt"]},{"name":"mdb","codepoint":"f8ca","styles":["brands"],"aliases":[]},{"name":"medal","codepoint":"f5a2","styles":["solid"],"aliases":[]},{"name":"medapps","codepoint":"f3c6","styles":["brands"],"aliases":[]},{"name":"medium","codepoint":"f23a","styles":["brands"],"aliases":["medium-m"]},{"name":"medrt","codepoint":"f3c8","styles":["brands"],"aliases":[]},{"name":"meetup","codepoint":"f2e0","styles":["brands"],"aliases":[]},{"name":"megaport","codepoint":"f5a3","styles":["brands"],"aliases":[]},{"name":"memory","codepoint":"f538","styles":["solid"],"aliases":[]},{"name":"mendeley","codepoint":"f7b3","styles":["brands"],"aliases":[]},{"name":"menorah","codepoint":"f676","styles":["solid"],"aliases":[]},{"name":"mercury","codepoint":"f223","styles":["solid"],"aliases":[]},{"name":"message","codepoint":"f27a","styles":["regular","solid"],"aliases":["comment-alt"]},{"name":"meta","codepoint":"e49b","styles":["brands"],"aliases":[]},{"name":"meteor","codepoint":"f753","styles":["solid"],"aliases":[]},{"name":"microblog","codepoint":"e01a","styles":["brands"],"aliases":[]},{"name":"microchip","codepoint":"f2db","styles":["solid"],"aliases":[]},{"name":"microphone","codepoint":"f130","styles":["solid"],"aliases":[]},{"name":"microphone-lines","codepoint":"f3c9","styles":["solid"],"aliases":["microphone-alt"]},{"name":"microphone-lines-slash","codepoint":"f539","styles":["solid"],"aliases":["microphone-alt-slash"]},{"name":"microphone-slash","codepoint":"f131","styles":["solid"],"aliases":[]},{"name":"microscope","codepoint":"f610","styles":["solid"],"aliases":[]},{"name":"microsoft","codepoint":"f3ca","styles":["brands"],"aliases":[]},{"name":"mill-sign","codepoint":"e1ed","styles":["solid"],"aliases":[]},{"name":"minimize","codepoint":"f78c","styles":["solid"],"aliases":["compress-arrows-alt"]},{"name":"mintbit","codepoint":"e62f","styles":["brands"],"aliases":[]},{"name":"minus","codepoint":"f068","styles":["solid"],"aliases":["subtract"]},{"name":"mitten","codepoint":"f7b5","styles":["solid"],"aliases":[]},{"name":"mix","codepoint":"f3cb","styles":["brands"],"aliases":[]},{"name":"mixcloud","codepoint":"f289","styles":["brands"],"aliases":[]},{"name":"mixer","codepoint":"e056","styles":["brands"],"aliases":[]},{"name":"mizuni","codepoint":"f3cc","styles":["brands"],"aliases":[]},{"name":"mobile","codepoint":"f3ce","styles":["solid"],"aliases":["mobile-android","mobile-phone"]},{"name":"mobile-button","codepoint":"f10b","styles":["solid"],"aliases":[]},{"name":"mobile-retro","codepoint":"e527","styles":["solid"],"aliases":[]},{"name":"mobile-screen","codepoint":"f3cf","styles":["solid"],"aliases":["mobile-android-alt"]},{"name":"mobile-screen-button","codepoint":"f3cd","styles":["solid"],"aliases":["mobile-alt"]},{"name":"modx","codepoint":"f285","styles":["brands"],"aliases":[]},{"name":"monero","codepoint":"f3d0","styles":["brands"],"aliases":[]},{"name":"money-bill","codepoint":"f0d6","styles":["solid"],"aliases":[]},{"name":"money-bill-1","codepoint":"f3d1","styles":["regular","solid"],"aliases":["money-bill-alt"]},{"name":"money-bill-1-wave","codepoint":"f53b","styles":["solid"],"aliases":["money-bill-wave-alt"]},{"name":"money-bill-transfer","codepoint":"e528","styles":["solid"],"aliases":[]},{"name":"money-bill-trend-up","codepoint":"e529","styles":["solid"],"aliases":[]},{"name":"money-bill-wave","codepoint":"f53a","styles":["solid"],"aliases":[]},{"name":"money-bill-wheat","codepoint":"e52a","styles":["solid"],"aliases":[]},{"name":"money-bills","codepoint":"e1f3","styles":["solid"],"aliases":[]},{"name":"money-check","codepoint":"f53c","styles":["solid"],"aliases":[]},{"name":"money-check-dollar","codepoint":"f53d","styles":["solid"],"aliases":["money-check-alt"]},{"name":"monument","codepoint":"f5a6","styles":["solid"],"aliases":[]},{"name":"moon","codepoint":"f186","styles":["regular","solid"],"aliases":[]},{"name":"mortar-pestle","codepoint":"f5a7","styles":["solid"],"aliases":[]},{"name":"mosque","codepoint":"f678","styles":["solid"],"aliases":[]},{"name":"mosquito","codepoint":"e52b","styles":["solid"],"aliases":[]},{"name":"mosquito-net","codepoint":"e52c","styles":["solid"],"aliases":[]},{"name":"motorcycle","codepoint":"f21c","styles":["solid"],"aliases":[]},{"name":"mound","codepoint":"e52d","styles":["solid"],"aliases":[]},{"name":"mountain","codepoint":"f6fc","styles":["solid"],"aliases":[]},{"name":"mountain-city","codepoint":"e52e","styles":["solid"],"aliases":[]},{"name":"mountain-sun","codepoint":"e52f","styles":["solid"],"aliases":[]},{"name":"mug-hot","codepoint":"f7b6","styles":["solid"],"aliases":[]},{"name":"mug-saucer","codepoint":"f0f4","styles":["solid"],"aliases":["coffee"]},{"name":"music","codepoint":"f001","styles":["solid"],"aliases":[]},{"name":"n","codepoint":"4e","styles":["solid"],"aliases":[]},{"name":"naira-sign","codepoint":"e1f6","styles":["solid"],"aliases":[]},{"name":"napster","codepoint":"f3d2","styles":["brands"],"aliases":[]},{"name":"neos","codepoint":"f612","styles":["brands"],"aliases":[]},{"name":"network-wired","codepoint":"f6ff","styles":["solid"],"aliases":[]},{"name":"neuter","codepoint":"f22c","styles":["solid"],"aliases":[]},{"name":"newspaper","codepoint":"f1ea","styles":["regular","solid"],"aliases":[]},{"name":"nfc-directional","codepoint":"e530","styles":["brands"],"aliases":[]},{"name":"nfc-symbol","codepoint":"e531","styles":["brands"],"aliases":[]},{"name":"nimblr","codepoint":"f5a8","styles":["brands"],"aliases":[]},{"name":"node","codepoint":"f419","styles":["brands"],"aliases":[]},{"name":"node-js","codepoint":"f3d3","styles":["brands"],"aliases":[]},{"name":"not-equal","codepoint":"f53e","styles":["solid"],"aliases":[]},{"name":"notdef","codepoint":"e1fe","styles":["solid"],"aliases":[]},{"name":"note-sticky","codepoint":"f249","styles":["regular","solid"],"aliases":["sticky-note"]},{"name":"notes-medical","codepoint":"f481","styles":["solid"],"aliases":[]},{"name":"npm","codepoint":"f3d4","styles":["brands"],"aliases":[]},{"name":"ns8","codepoint":"f3d5","styles":["brands"],"aliases":[]},{"name":"nutritionix","codepoint":"f3d6","styles":["brands"],"aliases":[]},{"name":"o","codepoint":"4f","styles":["solid"],"aliases":[]},{"name":"object-group","codepoint":"f247","styles":["regular","solid"],"aliases":[]},{"name":"object-ungroup","codepoint":"f248","styles":["regular","solid"],"aliases":[]},{"name":"octopus-deploy","codepoint":"e082","styles":["brands"],"aliases":[]},{"name":"odnoklassniki","codepoint":"f263","styles":["brands"],"aliases":[]},{"name":"odysee","codepoint":"e5c6","styles":["brands"],"aliases":[]},{"name":"oil-can","codepoint":"f613","styles":["solid"],"aliases":[]},{"name":"oil-well","codepoint":"e532","styles":["solid"],"aliases":[]},{"name":"old-republic","codepoint":"f510","styles":["brands"],"aliases":[]},{"name":"om","codepoint":"f679","styles":["solid"],"aliases":[]},{"name":"opencart","codepoint":"f23d","styles":["brands"],"aliases":[]},{"name":"openid","codepoint":"f19b","styles":["brands"],"aliases":[]},{"name":"opensuse","codepoint":"e62b","styles":["brands"],"aliases":[]},{"name":"opera","codepoint":"f26a","styles":["brands"],"aliases":[]},{"name":"optin-monster","codepoint":"f23c","styles":["brands"],"aliases":[]},{"name":"orcid","codepoint":"f8d2","styles":["brands"],"aliases":[]},{"name":"osi","codepoint":"f41a","styles":["brands"],"aliases":[]},{"name":"otter","codepoint":"f700","styles":["solid"],"aliases":[]},{"name":"outdent","codepoint":"f03b","styles":["solid"],"aliases":["dedent"]},{"name":"p","codepoint":"50","styles":["solid"],"aliases":[]},{"name":"padlet","codepoint":"e4a0","styles":["brands"],"aliases":[]},{"name":"page4","codepoint":"f3d7","styles":["brands"],"aliases":[]},{"name":"pagelines","codepoint":"f18c","styles":["brands"],"aliases":[]},{"name":"pager","codepoint":"f815","styles":["solid"],"aliases":[]},{"name":"paint-roller","codepoint":"f5aa","styles":["solid"],"aliases":[]},{"name":"paintbrush","codepoint":"f1fc","styles":["solid"],"aliases":["paint-brush"]},{"name":"palette","codepoint":"f53f","styles":["solid"],"aliases":[]},{"name":"palfed","codepoint":"f3d8","styles":["brands"],"aliases":[]},{"name":"pallet","codepoint":"f482","styles":["solid"],"aliases":[]},{"name":"panorama","codepoint":"e209","styles":["solid"],"aliases":[]},{"name":"paper-plane","codepoint":"f1d8","styles":["regular","solid"],"aliases":[]},{"name":"paperclip","codepoint":"f0c6","styles":["solid"],"aliases":[]},{"name":"parachute-box","codepoint":"f4cd","styles":["solid"],"aliases":[]},{"name":"paragraph","codepoint":"f1dd","styles":["solid"],"aliases":[]},{"name":"passport","codepoint":"f5ab","styles":["solid"],"aliases":[]},{"name":"paste","codepoint":"f0ea","styles":["regular","solid"],"aliases":["file-clipboard"]},{"name":"patreon","codepoint":"f3d9","styles":["brands"],"aliases":[]},{"name":"pause","codepoint":"f04c","styles":["solid"],"aliases":[]},{"name":"paw","codepoint":"f1b0","styles":["solid"],"aliases":[]},{"name":"paypal","codepoint":"f1ed","styles":["brands"],"aliases":[]},{"name":"peace","codepoint":"f67c","styles":["solid"],"aliases":[]},{"name":"pen","codepoint":"f304","styles":["solid"],"aliases":[]},{"name":"pen-clip","codepoint":"f305","styles":["solid"],"aliases":["pen-alt"]},{"name":"pen-fancy","codepoint":"f5ac","styles":["solid"],"aliases":[]},{"name":"pen-nib","codepoint":"f5ad","styles":["solid"],"aliases":[]},{"name":"pen-ruler","codepoint":"f5ae","styles":["solid"],"aliases":["pencil-ruler"]},{"name":"pen-to-square","codepoint":"f044","styles":["regular","solid"],"aliases":["edit"]},{"name":"pencil","codepoint":"f303","styles":["solid"],"aliases":["pencil-alt"]},{"name":"people-arrows","codepoint":"e068","styles":["solid"],"aliases":["people-arrows-left-right"]},{"name":"people-carry-box","codepoint":"f4ce","styles":["solid"],"aliases":["people-carry"]},{"name":"people-group","codepoint":"e533","styles":["solid"],"aliases":[]},{"name":"people-line","codepoint":"e534","styles":["solid"],"aliases":[]},{"name":"people-pulling","codepoint":"e535","styles":["solid"],"aliases":[]},{"name":"people-robbery","codepoint":"e536","styles":["solid"],"aliases":[]},{"name":"people-roof","codepoint":"e537","styles":["solid"],"aliases":[]},{"name":"pepper-hot","codepoint":"f816","styles":["solid"],"aliases":[]},{"name":"perbyte","codepoint":"e083","styles":["brands"],"aliases":[]},{"name":"percent","codepoint":"25","styles":["solid"],"aliases":["percentage"]},{"name":"periscope","codepoint":"f3da","styles":["brands"],"aliases":[]},{"name":"person","codepoint":"f183","styles":["solid"],"aliases":["male"]},{"name":"person-arrow-down-to-line","codepoint":"e538","styles":["solid"],"aliases":[]},{"name":"person-arrow-up-from-line","codepoint":"e539","styles":["solid"],"aliases":[]},{"name":"person-biking","codepoint":"f84a","styles":["solid"],"aliases":["biking"]},{"name":"person-booth","codepoint":"f756","styles":["solid"],"aliases":[]},{"name":"person-breastfeeding","codepoint":"e53a","styles":["solid"],"aliases":[]},{"name":"person-burst","codepoint":"e53b","styles":["solid"],"aliases":[]},{"name":"person-cane","codepoint":"e53c","styles":["solid"],"aliases":[]},{"name":"person-chalkboard","codepoint":"e53d","styles":["solid"],"aliases":[]},{"name":"person-circle-check","codepoint":"e53e","styles":["solid"],"aliases":[]},{"name":"person-circle-exclamation","codepoint":"e53f","styles":["solid"],"aliases":[]},{"name":"person-circle-minus","codepoint":"e540","styles":["solid"],"aliases":[]},{"name":"person-circle-plus","codepoint":"e541","styles":["solid"],"aliases":[]},{"name":"person-circle-question","codepoint":"e542","styles":["solid"],"aliases":[]},{"name":"person-circle-xmark","codepoint":"e543","styles":["solid"],"aliases":[]},{"name":"person-digging","codepoint":"f85e","styles":["solid"],"aliases":["digging"]},{"name":"person-dots-from-line","codepoint":"f470","styles":["solid"],"aliases":["diagnoses"]},{"name":"person-dress","codepoint":"f182","styles":["solid"],"aliases":["female"]},{"name":"person-dress-burst","codepoint":"e544","styles":["solid"],"aliases":[]},{"name":"person-drowning","codepoint":"e545","styles":["solid"],"aliases":[]},{"name":"person-falling","codepoint":"e546","styles":["solid"],"aliases":[]},{"name":"person-falling-burst","codepoint":"e547","styles":["solid"],"aliases":[]},{"name":"person-half-dress","codepoint":"e548","styles":["solid"],"aliases":[]},{"name":"person-harassing","codepoint":"e549","styles":["solid"],"aliases":[]},{"name":"person-hiking","codepoint":"f6ec","styles":["solid"],"aliases":["hiking"]},{"name":"person-military-pointing","codepoint":"e54a","styles":["solid"],"aliases":[]},{"name":"person-military-rifle","codepoint":"e54b","styles":["solid"],"aliases":[]},{"name":"person-military-to-person","codepoint":"e54c","styles":["solid"],"aliases":[]},{"name":"person-praying","codepoint":"f683","styles":["solid"],"aliases":["pray"]},{"name":"person-pregnant","codepoint":"e31e","styles":["solid"],"aliases":[]},{"name":"person-rays","codepoint":"e54d","styles":["solid"],"aliases":[]},{"name":"person-rifle","codepoint":"e54e","styles":["solid"],"aliases":[]},{"name":"person-running","codepoint":"f70c","styles":["solid"],"aliases":["running"]},{"name":"person-shelter","codepoint":"e54f","styles":["solid"],"aliases":[]},{"name":"person-skating","codepoint":"f7c5","styles":["solid"],"aliases":["skating"]},{"name":"person-skiing","codepoint":"f7c9","styles":["solid"],"aliases":["skiing"]},{"name":"person-skiing-nordic","codepoint":"f7ca","styles":["solid"],"aliases":["skiing-nordic"]},{"name":"person-snowboarding","codepoint":"f7ce","styles":["solid"],"aliases":["snowboarding"]},{"name":"person-swimming","codepoint":"f5c4","styles":["solid"],"aliases":["swimmer"]},{"name":"person-through-window","codepoint":"e5a9","styles":["solid"],"aliases":[]},{"name":"person-walking","codepoint":"f554","styles":["solid"],"aliases":["walking"]},{"name":"person-walking-arrow-loop-left","codepoint":"e551","styles":["solid"],"aliases":[]},{"name":"person-walking-arrow-right","codepoint":"e552","styles":["solid"],"aliases":[]},{"name":"person-walking-dashed-line-arrow-right","codepoint":"e553","styles":["solid"],"aliases":[]},{"name":"person-walking-luggage","codepoint":"e554","styles":["solid"],"aliases":[]},{"name":"person-walking-with-cane","codepoint":"f29d","styles":["solid"],"aliases":["blind"]},{"name":"peseta-sign","codepoint":"e221","styles":["solid"],"aliases":[]},{"name":"peso-sign","codepoint":"e222","styles":["solid"],"aliases":[]},{"name":"phabricator","codepoint":"f3db","styles":["brands"],"aliases":[]},{"name":"phoenix-framework","codepoint":"f3dc","styles":["brands"],"aliases":[]},{"name":"phoenix-squadron","codepoint":"f511","styles":["brands"],"aliases":[]},{"name":"phone","codepoint":"f095","styles":["solid"],"aliases":[]},{"name":"phone-flip","codepoint":"f879","styles":["solid"],"aliases":["phone-alt"]},{"name":"phone-slash","codepoint":"f3dd","styles":["solid"],"aliases":[]},{"name":"phone-volume","codepoint":"f2a0","styles":["solid"],"aliases":["volume-control-phone"]},{"name":"photo-film","codepoint":"f87c","styles":["solid"],"aliases":["photo-video"]},{"name":"php","codepoint":"f457","styles":["brands"],"aliases":[]},{"name":"pied-piper","codepoint":"f2ae","styles":["brands"],"aliases":[]},{"name":"pied-piper-alt","codepoint":"f1a8","styles":["brands"],"aliases":[]},{"name":"pied-piper-hat","codepoint":"f4e5","styles":["brands"],"aliases":[]},{"name":"pied-piper-pp","codepoint":"f1a7","styles":["brands"],"aliases":[]},{"name":"piggy-bank","codepoint":"f4d3","styles":["solid"],"aliases":[]},{"name":"pills","codepoint":"f484","styles":["solid"],"aliases":[]},{"name":"pinterest","codepoint":"f0d2","styles":["brands"],"aliases":[]},{"name":"pinterest-p","codepoint":"f231","styles":["brands"],"aliases":[]},{"name":"pix","codepoint":"e43a","styles":["brands"],"aliases":[]},{"name":"pixiv","codepoint":"e640","styles":["brands"],"aliases":[]},{"name":"pizza-slice","codepoint":"f818","styles":["solid"],"aliases":[]},{"name":"place-of-worship","codepoint":"f67f","styles":["solid"],"aliases":[]},{"name":"plane","codepoint":"f072","styles":["solid"],"aliases":[]},{"name":"plane-arrival","codepoint":"f5af","styles":["solid"],"aliases":[]},{"name":"plane-circle-check","codepoint":"e555","styles":["solid"],"aliases":[]},{"name":"plane-circle-exclamation","codepoint":"e556","styles":["solid"],"aliases":[]},{"name":"plane-circle-xmark","codepoint":"e557","styles":["solid"],"aliases":[]},{"name":"plane-departure","codepoint":"f5b0","styles":["solid"],"aliases":[]},{"name":"plane-lock","codepoint":"e558","styles":["solid"],"aliases":[]},{"name":"plane-slash","codepoint":"e069","styles":["solid"],"aliases":[]},{"name":"plane-up","codepoint":"e22d","styles":["solid"],"aliases":[]},{"name":"plant-wilt","codepoint":"e5aa","styles":["solid"],"aliases":[]},{"name":"plate-wheat","codepoint":"e55a","styles":["solid"],"aliases":[]},{"name":"play","codepoint":"f04b","styles":["solid"],"aliases":[]},{"name":"playstation","codepoint":"f3df","styles":["brands"],"aliases":[]},{"name":"plug","codepoint":"f1e6","styles":["solid"],"aliases":[]},{"name":"plug-circle-bolt","codepoint":"e55b","styles":["solid"],"aliases":[]},{"name":"plug-circle-check","codepoint":"e55c","styles":["solid"],"aliases":[]},{"name":"plug-circle-exclamation","codepoint":"e55d","styles":["solid"],"aliases":[]},{"name":"plug-circle-minus","codepoint":"e55e","styles":["solid"],"aliases":[]},{"name":"plug-circle-plus","codepoint":"e55f","styles":["solid"],"aliases":[]},{"name":"plug-circle-xmark","codepoint":"e560","styles":["solid"],"aliases":[]},{"name":"plus","codepoint":"2b","styles":["solid"],"aliases":["add"]},{"name":"plus-minus","codepoint":"e43c","styles":["solid"],"aliases":[]},{"name":"podcast","codepoint":"f2ce","styles":["solid"],"aliases":[]},{"name":"poo","codepoint":"f2fe","styles":["solid"],"aliases":[]},{"name":"poo-storm","codepoint":"f75a","styles":["solid"],"aliases":["poo-bolt"]},{"name":"poop","codepoint":"f619","styles":["solid"],"aliases":[]},{"name":"power-off","codepoint":"f011","styles":["solid"],"aliases":[]},{"name":"prescription","codepoint":"f5b1","styles":["solid"],"aliases":[]},{"name":"prescription-bottle","codepoint":"f485","styles":["solid"],"aliases":[]},{"name":"prescription-bottle-medical","codepoint":"f486","styles":["solid"],"aliases":["prescription-bottle-alt"]},{"name":"print","codepoint":"f02f","styles":["solid"],"aliases":[]},{"name":"product-hunt","codepoint":"f288","styles":["brands"],"aliases":[]},{"name":"pump-medical","codepoint":"e06a","styles":["solid"],"aliases":[]},{"name":"pump-soap","codepoint":"e06b","styles":["solid"],"aliases":[]},{"name":"pushed","codepoint":"f3e1","styles":["brands"],"aliases":[]},{"name":"puzzle-piece","codepoint":"f12e","styles":["solid"],"aliases":[]},{"name":"python","codepoint":"f3e2","styles":["brands"],"aliases":[]},{"name":"q","codepoint":"51","styles":["solid"],"aliases":[]},{"name":"qq","codepoint":"f1d6","styles":["brands"],"aliases":[]},{"name":"qrcode","codepoint":"f029","styles":["solid"],"aliases":[]},{"name":"question","codepoint":"3f","styles":["solid"],"aliases":[]},{"name":"quinscape","codepoint":"f459","styles":["brands"],"aliases":[]},{"name":"quora","codepoint":"f2c4","styles":["brands"],"aliases":[]},{"name":"quote-left","codepoint":"f10d","styles":["solid"],"aliases":["quote-left-alt"]},{"name":"quote-right","codepoint":"f10e","styles":["solid"],"aliases":["quote-right-alt"]},{"name":"r","codepoint":"52","styles":["solid"],"aliases":[]},{"name":"r-project","codepoint":"f4f7","styles":["brands"],"aliases":[]},{"name":"radiation","codepoint":"f7b9","styles":["solid"],"aliases":[]},{"name":"radio","codepoint":"f8d7","styles":["solid"],"aliases":[]},{"name":"rainbow","codepoint":"f75b","styles":["solid"],"aliases":[]},{"name":"ranking-star","codepoint":"e561","styles":["solid"],"aliases":[]},{"name":"raspberry-pi","codepoint":"f7bb","styles":["brands"],"aliases":[]},{"name":"ravelry","codepoint":"f2d9","styles":["brands"],"aliases":[]},{"name":"react","codepoint":"f41b","styles":["brands"],"aliases":[]},{"name":"reacteurope","codepoint":"f75d","styles":["brands"],"aliases":[]},{"name":"readme","codepoint":"f4d5","styles":["brands"],"aliases":[]},{"name":"rebel","codepoint":"f1d0","styles":["brands"],"aliases":[]},{"name":"receipt","codepoint":"f543","styles":["solid"],"aliases":[]},{"name":"record-vinyl","codepoint":"f8d9","styles":["solid"],"aliases":[]},{"name":"rectangle-ad","codepoint":"f641","styles":["solid"],"aliases":["ad"]},{"name":"rectangle-list","codepoint":"f022","styles":["regular","solid"],"aliases":["list-alt"]},{"name":"rectangle-xmark","codepoint":"f410","styles":["regular","solid"],"aliases":["rectangle-times","times-rectangle","window-close"]},{"name":"recycle","codepoint":"f1b8","styles":["solid"],"aliases":[]},{"name":"red-river","codepoint":"f3e3","styles":["brands"],"aliases":[]},{"name":"reddit","codepoint":"f1a1","styles":["brands"],"aliases":[]},{"name":"reddit-alien","codepoint":"f281","styles":["brands"],"aliases":[]},{"name":"redhat","codepoint":"f7bc","styles":["brands"],"aliases":[]},{"name":"registered","codepoint":"f25d","styles":["regular","solid"],"aliases":[]},{"name":"renren","codepoint":"f18b","styles":["brands"],"aliases":[]},{"name":"repeat","codepoint":"f363","styles":["solid"],"aliases":[]},{"name":"reply","codepoint":"f3e5","styles":["solid"],"aliases":["mail-reply"]},{"name":"reply-all","codepoint":"f122","styles":["solid"],"aliases":["mail-reply-all"]},{"name":"replyd","codepoint":"f3e6","styles":["brands"],"aliases":[]},{"name":"republican","codepoint":"f75e","styles":["solid"],"aliases":[]},{"name":"researchgate","codepoint":"f4f8","styles":["brands"],"aliases":[]},{"name":"resolving","codepoint":"f3e7","styles":["brands"],"aliases":[]},{"name":"restroom","codepoint":"f7bd","styles":["solid"],"aliases":[]},{"name":"retweet","codepoint":"f079","styles":["solid"],"aliases":[]},{"name":"rev","codepoint":"f5b2","styles":["brands"],"aliases":[]},{"name":"ribbon","codepoint":"f4d6","styles":["solid"],"aliases":[]},{"name":"right-from-bracket","codepoint":"f2f5","styles":["solid"],"aliases":["sign-out-alt"]},{"name":"right-left","codepoint":"f362","styles":["solid"],"aliases":["exchange-alt"]},{"name":"right-long","codepoint":"f30b","styles":["solid"],"aliases":["long-arrow-alt-right"]},{"name":"right-to-bracket","codepoint":"f2f6","styles":["solid"],"aliases":["sign-in-alt"]},{"name":"ring","codepoint":"f70b","styles":["solid"],"aliases":[]},{"name":"road","codepoint":"f018","styles":["solid"],"aliases":[]},{"name":"road-barrier","codepoint":"e562","styles":["solid"],"aliases":[]},{"name":"road-bridge","codepoint":"e563","styles":["solid"],"aliases":[]},{"name":"road-circle-check","codepoint":"e564","styles":["solid"],"aliases":[]},{"name":"road-circle-exclamation","codepoint":"e565","styles":["solid"],"aliases":[]},{"name":"road-circle-xmark","codepoint":"e566","styles":["solid"],"aliases":[]},{"name":"road-lock","codepoint":"e567","styles":["solid"],"aliases":[]},{"name":"road-spikes","codepoint":"e568","styles":["solid"],"aliases":[]},{"name":"robot","codepoint":"f544","styles":["solid"],"aliases":[]},{"name":"rocket","codepoint":"f135","styles":["solid"],"aliases":[]},{"name":"rocketchat","codepoint":"f3e8","styles":["brands"],"aliases":[]},{"name":"rockrms","codepoint":"f3e9","styles":["brands"],"aliases":[]},{"name":"rotate","codepoint":"f2f1","styles":["solid"],"aliases":["sync-alt"]},{"name":"rotate-left","codepoint":"f2ea","styles":["solid"],"aliases":["rotate-back","rotate-backward","undo-alt"]},{"name":"rotate-right","codepoint":"f2f9","styles":["solid"],"aliases":["redo-alt","rotate-forward"]},{"name":"route","codepoint":"f4d7","styles":["solid"],"aliases":[]},{"name":"rss","codepoint":"f09e","styles":["solid"],"aliases":["feed"]},{"name":"ruble-sign","codepoint":"f158","styles":["solid"],"aliases":["rouble","rub","ruble"]},{"name":"rug","codepoint":"e569","styles":["solid"],"aliases":[]},{"name":"ruler","codepoint":"f545","styles":["solid"],"aliases":[]},{"name":"ruler-combined","codepoint":"f546","styles":["solid"],"aliases":[]},{"name":"ruler-horizontal","codepoint":"f547","styles":["solid"],"aliases":[]},{"name":"ruler-vertical","codepoint":"f548","styles":["solid"],"aliases":[]},{"name":"rupee-sign","codepoint":"f156","styles":["solid"],"aliases":["rupee"]},{"name":"rupiah-sign","codepoint":"e23d","styles":["solid"],"aliases":[]},{"name":"rust","codepoint":"e07a","styles":["brands"],"aliases":[]},{"name":"s","codepoint":"53","styles":["solid"],"aliases":[]},{"name":"sack-dollar","codepoint":"f81d","styles":["solid"],"aliases":[]},{"name":"sack-xmark","codepoint":"e56a","styles":["solid"],"aliases":[]},{"name":"safari","codepoint":"f267","styles":["brands"],"aliases":[]},{"name":"sailboat","codepoint":"e445","styles":["solid"],"aliases":[]},{"name":"salesforce","codepoint":"f83b","styles":["brands"],"aliases":[]},{"name":"sass","codepoint":"f41e","styles":["brands"],"aliases":[]},{"name":"satellite","codepoint":"f7bf","styles":["solid"],"aliases":[]},{"name":"satellite-dish","codepoint":"f7c0","styles":["solid"],"aliases":[]},{"name":"scale-balanced","codepoint":"f24e","styles":["solid"],"aliases":["balance-scale"]},{"name":"scale-unbalanced","codepoint":"f515","styles":["solid"],"aliases":["balance-scale-left"]},{"name":"scale-unbalanced-flip","codepoint":"f516","styles":["solid"],"aliases":["balance-scale-right"]},{"name":"schlix","codepoint":"f3ea","styles":["brands"],"aliases":[]},{"name":"school","codepoint":"f549","styles":["solid"],"aliases":[]},{"name":"school-circle-check","codepoint":"e56b","styles":["solid"],"aliases":[]},{"name":"school-circle-exclamation","codepoint":"e56c","styles":["solid"],"aliases":[]},{"name":"school-circle-xmark","codepoint":"e56d","styles":["solid"],"aliases":[]},{"name":"school-flag","codepoint":"e56e","styles":["solid"],"aliases":[]},{"name":"school-lock","codepoint":"e56f","styles":["solid"],"aliases":[]},{"name":"scissors","codepoint":"f0c4","styles":["solid"],"aliases":["cut"]},{"name":"screenpal","codepoint":"e570","styles":["brands"],"aliases":[]},{"name":"screwdriver","codepoint":"f54a","styles":["solid"],"aliases":[]},{"name":"screwdriver-wrench","codepoint":"f7d9","styles":["solid"],"aliases":["tools"]},{"name":"scribd","codepoint":"f28a","styles":["brands"],"aliases":[]},{"name":"scroll","codepoint":"f70e","styles":["solid"],"aliases":[]},{"name":"scroll-torah","codepoint":"f6a0","styles":["solid"],"aliases":["torah"]},{"name":"sd-card","codepoint":"f7c2","styles":["solid"],"aliases":[]},{"name":"searchengin","codepoint":"f3eb","styles":["brands"],"aliases":[]},{"name":"section","codepoint":"e447","styles":["solid"],"aliases":[]},{"name":"seedling","codepoint":"f4d8","styles":["solid"],"aliases":["sprout"]},{"name":"sellcast","codepoint":"f2da","styles":["brands"],"aliases":[]},{"name":"sellsy","codepoint":"f213","styles":["brands"],"aliases":[]},{"name":"server","codepoint":"f233","styles":["solid"],"aliases":[]},{"name":"servicestack","codepoint":"f3ec","styles":["brands"],"aliases":[]},{"name":"shapes","codepoint":"f61f","styles":["solid"],"aliases":["triangle-circle-square"]},{"name":"share","codepoint":"f064","styles":["solid"],"aliases":["mail-forward"]},{"name":"share-from-square","codepoint":"f14d","styles":["regular","solid"],"aliases":["share-square"]},{"name":"share-nodes","codepoint":"f1e0","styles":["solid"],"aliases":["share-alt"]},{"name":"sheet-plastic","codepoint":"e571","styles":["solid"],"aliases":[]},{"name":"shekel-sign","codepoint":"f20b","styles":["solid"],"aliases":["ils","shekel","sheqel","sheqel-sign"]},{"name":"shield","codepoint":"f132","styles":["solid"],"aliases":["shield-blank"]},{"name":"shield-cat","codepoint":"e572","styles":["solid"],"aliases":[]},{"name":"shield-dog","codepoint":"e573","styles":["solid"],"aliases":[]},{"name":"shield-halved","codepoint":"f3ed","styles":["solid"],"aliases":["shield-alt"]},{"name":"shield-heart","codepoint":"e574","styles":["solid"],"aliases":[]},{"name":"shield-virus","codepoint":"e06c","styles":["solid"],"aliases":[]},{"name":"ship","codepoint":"f21a","styles":["solid"],"aliases":[]},{"name":"shirt","codepoint":"f553","styles":["solid"],"aliases":["t-shirt","tshirt"]},{"name":"shirtsinbulk","codepoint":"f214","styles":["brands"],"aliases":[]},{"name":"shoe-prints","codepoint":"f54b","styles":["solid"],"aliases":[]},{"name":"shoelace","codepoint":"e60c","styles":["brands"],"aliases":[]},{"name":"shop","codepoint":"f54f","styles":["solid"],"aliases":["store-alt"]},{"name":"shop-lock","codepoint":"e4a5","styles":["solid"],"aliases":[]},{"name":"shop-slash","codepoint":"e070","styles":["solid"],"aliases":["store-alt-slash"]},{"name":"shopify","codepoint":"e057","styles":["brands"],"aliases":[]},{"name":"shopware","codepoint":"f5b5","styles":["brands"],"aliases":[]},{"name":"shower","codepoint":"f2cc","styles":["solid"],"aliases":[]},{"name":"shrimp","codepoint":"e448","styles":["solid"],"aliases":[]},{"name":"shuffle","codepoint":"f074","styles":["solid"],"aliases":["random"]},{"name":"shuttle-space","codepoint":"f197","styles":["solid"],"aliases":["space-shuttle"]},{"name":"sign-hanging","codepoint":"f4d9","styles":["solid"],"aliases":["sign"]},{"name":"signal","codepoint":"f012","styles":["solid"],"aliases":["signal-5","signal-perfect"]},{"name":"signal-messenger","codepoint":"e663","styles":["brands"],"aliases":[]},{"name":"signature","codepoint":"f5b7","styles":["solid"],"aliases":[]},{"name":"signs-post","codepoint":"f277","styles":["solid"],"aliases":["map-signs"]},{"name":"sim-card","codepoint":"f7c4","styles":["solid"],"aliases":[]},{"name":"simplybuilt","codepoint":"f215","styles":["brands"],"aliases":[]},{"name":"sink","codepoint":"e06d","styles":["solid"],"aliases":[]},{"name":"sistrix","codepoint":"f3ee","styles":["brands"],"aliases":[]},{"name":"sitemap","codepoint":"f0e8","styles":["solid"],"aliases":[]},{"name":"sith","codepoint":"f512","styles":["brands"],"aliases":[]},{"name":"sitrox","codepoint":"e44a","styles":["brands"],"aliases":[]},{"name":"sketch","codepoint":"f7c6","styles":["brands"],"aliases":[]},{"name":"skull","codepoint":"f54c","styles":["solid"],"aliases":[]},{"name":"skull-crossbones","codepoint":"f714","styles":["solid"],"aliases":[]},{"name":"skyatlas","codepoint":"f216","styles":["brands"],"aliases":[]},{"name":"skype","codepoint":"f17e","styles":["brands"],"aliases":[]},{"name":"slack","codepoint":"f198","styles":["brands"],"aliases":["slack-hash"]},{"name":"slash","codepoint":"f715","styles":["solid"],"aliases":[]},{"name":"sleigh","codepoint":"f7cc","styles":["solid"],"aliases":[]},{"name":"sliders","codepoint":"f1de","styles":["solid"],"aliases":["sliders-h"]},{"name":"slideshare","codepoint":"f1e7","styles":["brands"],"aliases":[]},{"name":"smog","codepoint":"f75f","styles":["solid"],"aliases":[]},{"name":"smoking","codepoint":"f48d","styles":["solid"],"aliases":[]},{"name":"snapchat","codepoint":"f2ab","styles":["brands"],"aliases":["snapchat-ghost"]},{"name":"snowflake","codepoint":"f2dc","styles":["regular","solid"],"aliases":[]},{"name":"snowman","codepoint":"f7d0","styles":["solid"],"aliases":[]},{"name":"snowplow","codepoint":"f7d2","styles":["solid"],"aliases":[]},{"name":"soap","codepoint":"e06e","styles":["solid"],"aliases":[]},{"name":"socks","codepoint":"f696","styles":["solid"],"aliases":[]},{"name":"solar-panel","codepoint":"f5ba","styles":["solid"],"aliases":[]},{"name":"sort","codepoint":"f0dc","styles":["solid"],"aliases":["unsorted"]},{"name":"sort-down","codepoint":"f0dd","styles":["solid"],"aliases":["sort-desc"]},{"name":"sort-up","codepoint":"f0de","styles":["solid"],"aliases":["sort-asc"]},{"name":"soundcloud","codepoint":"f1be","styles":["brands"],"aliases":[]},{"name":"sourcetree","codepoint":"f7d3","styles":["brands"],"aliases":[]},{"name":"spa","codepoint":"f5bb","styles":["solid"],"aliases":[]},{"name":"space-awesome","codepoint":"e5ac","styles":["brands"],"aliases":[]},{"name":"spaghetti-monster-flying","codepoint":"f67b","styles":["solid"],"aliases":["pastafarianism"]},{"name":"speakap","codepoint":"f3f3","styles":["brands"],"aliases":[]},{"name":"speaker-deck","codepoint":"f83c","styles":["brands"],"aliases":[]},{"name":"spell-check","codepoint":"f891","styles":["solid"],"aliases":[]},{"name":"spider","codepoint":"f717","styles":["solid"],"aliases":[]},{"name":"spinner","codepoint":"f110","styles":["solid"],"aliases":[]},{"name":"splotch","codepoint":"f5bc","styles":["solid"],"aliases":[]},{"name":"spoon","codepoint":"f2e5","styles":["solid"],"aliases":["utensil-spoon"]},{"name":"spotify","codepoint":"f1bc","styles":["brands"],"aliases":[]},{"name":"spray-can","codepoint":"f5bd","styles":["solid"],"aliases":[]},{"name":"spray-can-sparkles","codepoint":"f5d0","styles":["solid"],"aliases":["air-freshener"]},{"name":"square","codepoint":"f0c8","styles":["regular","solid"],"aliases":[]},{"name":"square-arrow-up-right","codepoint":"f14c","styles":["solid"],"aliases":["external-link-square"]},{"name":"square-behance","codepoint":"f1b5","styles":["brands"],"aliases":["behance-square"]},{"name":"square-binary","codepoint":"e69b","styles":["solid"],"aliases":[]},{"name":"square-bluesky","codepoint":"e6a3","styles":["brands"],"aliases":[]},{"name":"square-caret-down","codepoint":"f150","styles":["regular","solid"],"aliases":["caret-square-down"]},{"name":"square-caret-left","codepoint":"f191","styles":["regular","solid"],"aliases":["caret-square-left"]},{"name":"square-caret-right","codepoint":"f152","styles":["regular","solid"],"aliases":["caret-square-right"]},{"name":"square-caret-up","codepoint":"f151","styles":["regular","solid"],"aliases":["caret-square-up"]},{"name":"square-check","codepoint":"f14a","styles":["regular","solid"],"aliases":["check-square"]},{"name":"square-dribbble","codepoint":"f397","styles":["brands"],"aliases":["dribbble-square"]},{"name":"square-envelope","codepoint":"f199","styles":["solid"],"aliases":["envelope-square"]},{"name":"square-facebook","codepoint":"f082","styles":["brands"],"aliases":["facebook-square"]},{"name":"square-font-awesome","codepoint":"e5ad","styles":["brands"],"aliases":[]},{"name":"square-font-awesome-stroke","codepoint":"f35c","styles":["brands"],"aliases":["font-awesome-alt"]},{"name":"square-full","codepoint":"f45c","styles":["regular","solid"],"aliases":[]},{"name":"square-git","codepoint":"f1d2","styles":["brands"],"aliases":["git-square"]},{"name":"square-github","codepoint":"f092","styles":["brands"],"aliases":["github-square"]},{"name":"square-gitlab","codepoint":"e5ae","styles":["brands"],"aliases":["gitlab-square"]},{"name":"square-google-plus","codepoint":"f0d4","styles":["brands"],"aliases":["google-plus-square"]},{"name":"square-h","codepoint":"f0fd","styles":["solid"],"aliases":["h-square"]},{"name":"square-hacker-news","codepoint":"f3af","styles":["brands"],"aliases":["hacker-news-square"]},{"name":"square-instagram","codepoint":"e055","styles":["brands"],"aliases":["instagram-square"]},{"name":"square-js","codepoint":"f3b9","styles":["brands"],"aliases":["js-square"]},{"name":"square-lastfm","codepoint":"f203","styles":["brands"],"aliases":["lastfm-square"]},{"name":"square-letterboxd","codepoint":"e62e","styles":["brands"],"aliases":[]},{"name":"square-minus","codepoint":"f146","styles":["regular","solid"],"aliases":["minus-square"]},{"name":"square-nfi","codepoint":"e576","styles":["solid"],"aliases":[]},{"name":"square-odnoklassniki","codepoint":"f264","styles":["brands"],"aliases":["odnoklassniki-square"]},{"name":"square-parking","codepoint":"f540","styles":["solid"],"aliases":["parking"]},{"name":"square-pen","codepoint":"f14b","styles":["solid"],"aliases":["pen-square","pencil-square"]},{"name":"square-person-confined","codepoint":"e577","styles":["solid"],"aliases":[]},{"name":"square-phone","codepoint":"f098","styles":["solid"],"aliases":["phone-square"]},{"name":"square-phone-flip","codepoint":"f87b","styles":["solid"],"aliases":["phone-square-alt"]},{"name":"square-pied-piper","codepoint":"e01e","styles":["brands"],"aliases":["pied-piper-square"]},{"name":"square-pinterest","codepoint":"f0d3","styles":["brands"],"aliases":["pinterest-square"]},{"name":"square-plus","codepoint":"f0fe","styles":["regular","solid"],"aliases":["plus-square"]},{"name":"square-poll-horizontal","codepoint":"f682","styles":["solid"],"aliases":["poll-h"]},{"name":"square-poll-vertical","codepoint":"f681","styles":["solid"],"aliases":["poll"]},{"name":"square-reddit","codepoint":"f1a2","styles":["brands"],"aliases":["reddit-square"]},{"name":"square-root-variable","codepoint":"f698","styles":["solid"],"aliases":["square-root-alt"]},{"name":"square-rss","codepoint":"f143","styles":["solid"],"aliases":["rss-square"]},{"name":"square-share-nodes","codepoint":"f1e1","styles":["solid"],"aliases":["share-alt-square"]},{"name":"square-snapchat","codepoint":"f2ad","styles":["brands"],"aliases":["snapchat-square"]},{"name":"square-steam","codepoint":"f1b7","styles":["brands"],"aliases":["steam-square"]},{"name":"square-threads","codepoint":"e619","styles":["brands"],"aliases":[]},{"name":"square-tumblr","codepoint":"f174","styles":["brands"],"aliases":["tumblr-square"]},{"name":"square-twitter","codepoint":"f081","styles":["brands"],"aliases":["twitter-square"]},{"name":"square-up-right","codepoint":"f360","styles":["solid"],"aliases":["external-link-square-alt"]},{"name":"square-upwork","codepoint":"e67c","styles":["brands"],"aliases":[]},{"name":"square-viadeo","codepoint":"f2aa","styles":["brands"],"aliases":["viadeo-square"]},{"name":"square-vimeo","codepoint":"f194","styles":["brands"],"aliases":["vimeo-square"]},{"name":"square-virus","codepoint":"e578","styles":["solid"],"aliases":[]},{"name":"square-web-awesome","codepoint":"e683","styles":["brands"],"aliases":[]},{"name":"square-web-awesome-stroke","codepoint":"e684","styles":["brands"],"aliases":[]},{"name":"square-whatsapp","codepoint":"f40c","styles":["brands"],"aliases":["whatsapp-square"]},{"name":"square-x-twitter","codepoint":"e61a","styles":["brands"],"aliases":[]},{"name":"square-xing","codepoint":"f169","styles":["brands"],"aliases":["xing-square"]},{"name":"square-xmark","codepoint":"f2d3","styles":["solid"],"aliases":["times-square","xmark-square"]},{"name":"square-youtube","codepoint":"f431","styles":["brands"],"aliases":["youtube-square"]},{"name":"squarespace","codepoint":"f5be","styles":["brands"],"aliases":[]},{"name":"stack-exchange","codepoint":"f18d","styles":["brands"],"aliases":[]},{"name":"stack-overflow","codepoint":"f16c","styles":["brands"],"aliases":[]},{"name":"stackpath","codepoint":"f842","styles":["brands"],"aliases":[]},{"name":"staff-snake","codepoint":"e579","styles":["solid"],"aliases":["rod-asclepius","rod-snake","staff-aesculapius"]},{"name":"stairs","codepoint":"e289","styles":["solid"],"aliases":[]},{"name":"stamp","codepoint":"f5bf","styles":["solid"],"aliases":[]},{"name":"stapler","codepoint":"e5af","styles":["solid"],"aliases":[]},{"name":"star","codepoint":"f005","styles":["regular","solid"],"aliases":[]},{"name":"star-and-crescent","codepoint":"f699","styles":["solid"],"aliases":[]},{"name":"star-half","codepoint":"f089","styles":["regular","solid"],"aliases":[]},{"name":"star-half-stroke","codepoint":"f5c0","styles":["regular","solid"],"aliases":["star-half-alt"]},{"name":"star-of-david","codepoint":"f69a","styles":["solid"],"aliases":[]},{"name":"star-of-life","codepoint":"f621","styles":["solid"],"aliases":[]},{"name":"staylinked","codepoint":"f3f5","styles":["brands"],"aliases":[]},{"name":"steam","codepoint":"f1b6","styles":["brands"],"aliases":[]},{"name":"steam-symbol","codepoint":"f3f6","styles":["brands"],"aliases":[]},{"name":"sterling-sign","codepoint":"f154","styles":["solid"],"aliases":["gbp","pound-sign"]},{"name":"stethoscope","codepoint":"f0f1","styles":["solid"],"aliases":[]},{"name":"sticker-mule","codepoint":"f3f7","styles":["brands"],"aliases":[]},{"name":"stop","codepoint":"f04d","styles":["solid"],"aliases":[]},{"name":"stopwatch","codepoint":"f2f2","styles":["solid"],"aliases":[]},{"name":"stopwatch-20","codepoint":"e06f","styles":["solid"],"aliases":[]},{"name":"store","codepoint":"f54e","styles":["solid"],"aliases":[]},{"name":"store-slash","codepoint":"e071","styles":["solid"],"aliases":[]},{"name":"strava","codepoint":"f428","styles":["brands"],"aliases":[]},{"name":"street-view","codepoint":"f21d","styles":["solid"],"aliases":[]},{"name":"strikethrough","codepoint":"f0cc","styles":["solid"],"aliases":[]},{"name":"stripe","codepoint":"f429","styles":["brands"],"aliases":[]},{"name":"stripe-s","codepoint":"f42a","styles":["brands"],"aliases":[]},{"name":"stroopwafel","codepoint":"f551","styles":["solid"],"aliases":[]},{"name":"stubber","codepoint":"e5c7","styles":["brands"],"aliases":[]},{"name":"studiovinari","codepoint":"f3f8","styles":["brands"],"aliases":[]},{"name":"stumbleupon","codepoint":"f1a4","styles":["brands"],"aliases":[]},{"name":"stumbleupon-circle","codepoint":"f1a3","styles":["brands"],"aliases":[]},{"name":"subscript","codepoint":"f12c","styles":["solid"],"aliases":[]},{"name":"suitcase","codepoint":"f0f2","styles":["solid"],"aliases":[]},{"name":"suitcase-medical","codepoint":"f0fa","styles":["solid"],"aliases":["medkit"]},{"name":"suitcase-rolling","codepoint":"f5c1","styles":["solid"],"aliases":[]},{"name":"sun","codepoint":"f185","styles":["regular","solid"],"aliases":[]},{"name":"sun-plant-wilt","codepoint":"e57a","styles":["solid"],"aliases":[]},{"name":"superpowers","codepoint":"f2dd","styles":["brands"],"aliases":[]},{"name":"superscript","codepoint":"f12b","styles":["solid"],"aliases":[]},{"name":"supple","codepoint":"f3f9","styles":["brands"],"aliases":[]},{"name":"suse","codepoint":"f7d6","styles":["brands"],"aliases":[]},{"name":"swatchbook","codepoint":"f5c3","styles":["solid"],"aliases":[]},{"name":"swift","codepoint":"f8e1","styles":["brands"],"aliases":[]},{"name":"symfony","codepoint":"f83d","styles":["brands"],"aliases":[]},{"name":"synagogue","codepoint":"f69b","styles":["solid"],"aliases":[]},{"name":"syringe","codepoint":"f48e","styles":["solid"],"aliases":[]},{"name":"t","codepoint":"54","styles":["solid"],"aliases":[]},{"name":"table","codepoint":"f0ce","styles":["solid"],"aliases":[]},{"name":"table-cells","codepoint":"f00a","styles":["solid"],"aliases":["th"]},{"name":"table-cells-column-lock","codepoint":"e678","styles":["solid"],"aliases":[]},{"name":"table-cells-large","codepoint":"f009","styles":["solid"],"aliases":["th-large"]},{"name":"table-cells-row-lock","codepoint":"e67a","styles":["solid"],"aliases":[]},{"name":"table-cells-row-unlock","codepoint":"e691","styles":["solid"],"aliases":[]},{"name":"table-columns","codepoint":"f0db","styles":["solid"],"aliases":["columns"]},{"name":"table-list","codepoint":"f00b","styles":["solid"],"aliases":["th-list"]},{"name":"table-tennis-paddle-ball","codepoint":"f45d","styles":["solid"],"aliases":["ping-pong-paddle-ball","table-tennis"]},{"name":"tablet","codepoint":"f3fb","styles":["solid"],"aliases":["tablet-android"]},{"name":"tablet-button","codepoint":"f10a","styles":["solid"],"aliases":[]},{"name":"tablet-screen-button","codepoint":"f3fa","styles":["solid"],"aliases":["tablet-alt"]},{"name":"tablets","codepoint":"f490","styles":["solid"],"aliases":[]},{"name":"tachograph-digital","codepoint":"f566","styles":["solid"],"aliases":["digital-tachograph"]},{"name":"tag","codepoint":"f02b","styles":["solid"],"aliases":[]},{"name":"tags","codepoint":"f02c","styles":["solid"],"aliases":[]},{"name":"tape","codepoint":"f4db","styles":["solid"],"aliases":[]},{"name":"tarp","codepoint":"e57b","styles":["solid"],"aliases":[]},{"name":"tarp-droplet","codepoint":"e57c","styles":["solid"],"aliases":[]},{"name":"taxi","codepoint":"f1ba","styles":["solid"],"aliases":["cab"]},{"name":"teamspeak","codepoint":"f4f9","styles":["brands"],"aliases":[]},{"name":"teeth","codepoint":"f62e","styles":["solid"],"aliases":[]},{"name":"teeth-open","codepoint":"f62f","styles":["solid"],"aliases":[]},{"name":"telegram","codepoint":"f2c6","styles":["brands"],"aliases":["telegram-plane"]},{"name":"temperature-arrow-down","codepoint":"e03f","styles":["solid"],"aliases":["temperature-down"]},{"name":"temperature-arrow-up","codepoint":"e040","styles":["solid"],"aliases":["temperature-up"]},{"name":"temperature-empty","codepoint":"f2cb","styles":["solid"],"aliases":["temperature-0","thermometer-0","thermometer-empty"]},{"name":"temperature-full","codepoint":"f2c7","styles":["solid"],"aliases":["temperature-4","thermometer-4","thermometer-full"]},{"name":"temperature-half","codepoint":"f2c9","styles":["solid"],"aliases":["temperature-2","thermometer-2","thermometer-half"]},{"name":"temperature-high","codepoint":"f769","styles":["solid"],"aliases":[]},{"name":"temperature-low","codepoint":"f76b","styles":["solid"],"aliases":[]},{"name":"temperature-quarter","codepoint":"f2ca","styles":["solid"],"aliases":["temperature-1","thermometer-1","thermometer-quarter"]},{"name":"temperature-three-quarters","codepoint":"f2c8","styles":["solid"],"aliases":["temperature-3","thermometer-3","thermometer-three-quarters"]},{"name":"tencent-weibo","codepoint":"f1d5","styles":["brands"],"aliases":[]},{"name":"tenge-sign","codepoint":"f7d7","styles":["solid"],"aliases":["tenge"]},{"name":"tent","codepoint":"e57d","styles":["solid"],"aliases":[]},{"name":"tent-arrow-down-to-line","codepoint":"e57e","styles":["solid"],"aliases":[]},{"name":"tent-arrow-left-right","codepoint":"e57f","styles":["solid"],"aliases":[]},{"name":"tent-arrow-turn-left","codepoint":"e580","styles":["solid"],"aliases":[]},{"name":"tent-arrows-down","codepoint":"e581","styles":["solid"],"aliases":[]},{"name":"tents","codepoint":"e582","styles":["solid"],"aliases":[]},{"name":"terminal","codepoint":"f120","styles":["solid"],"aliases":[]},{"name":"text-height","codepoint":"f034","styles":["solid"],"aliases":[]},{"name":"text-slash","codepoint":"f87d","styles":["solid"],"aliases":["remove-format"]},{"name":"text-width","codepoint":"f035","styles":["solid"],"aliases":[]},{"name":"the-red-yeti","codepoint":"f69d","styles":["brands"],"aliases":[]},{"name":"themeco","codepoint":"f5c6","styles":["brands"],"aliases":[]},{"name":"themeisle","codepoint":"f2b2","styles":["brands"],"aliases":[]},{"name":"thermometer","codepoint":"f491","styles":["solid"],"aliases":[]},{"name":"think-peaks","codepoint":"f731","styles":["brands"],"aliases":[]},{"name":"threads","codepoint":"e618","styles":["brands"],"aliases":[]},{"name":"thumbs-down","codepoint":"f165","styles":["regular","solid"],"aliases":[]},{"name":"thumbs-up","codepoint":"f164","styles":["regular","solid"],"aliases":[]},{"name":"thumbtack","codepoint":"f08d","styles":["solid"],"aliases":["thumb-tack"]},{"name":"thumbtack-slash","codepoint":"e68f","styles":["solid"],"aliases":["thumb-tack-slash"]},{"name":"ticket","codepoint":"f145","styles":["solid"],"aliases":[]},{"name":"ticket-simple","codepoint":"f3ff","styles":["solid"],"aliases":["ticket-alt"]},{"name":"tiktok","codepoint":"e07b","styles":["brands"],"aliases":[]},{"name":"timeline","codepoint":"e29c","styles":["solid"],"aliases":[]},{"name":"toggle-off","codepoint":"f204","styles":["solid"],"aliases":[]},{"name":"toggle-on","codepoint":"f205","styles":["solid"],"aliases":[]},{"name":"toilet","codepoint":"f7d8","styles":["solid"],"aliases":[]},{"name":"toilet-paper","codepoint":"f71e","styles":["solid"],"aliases":[]},{"name":"toilet-paper-slash","codepoint":"e072","styles":["solid"],"aliases":[]},{"name":"toilet-portable","codepoint":"e583","styles":["solid"],"aliases":[]},{"name":"toilets-portable","codepoint":"e584","styles":["solid"],"aliases":[]},{"name":"toolbox","codepoint":"f552","styles":["solid"],"aliases":[]},{"name":"tooth","codepoint":"f5c9","styles":["solid"],"aliases":[]},{"name":"torii-gate","codepoint":"f6a1","styles":["solid"],"aliases":[]},{"name":"tornado","codepoint":"f76f","styles":["solid"],"aliases":[]},{"name":"tower-broadcast","codepoint":"f519","styles":["solid"],"aliases":["broadcast-tower"]},{"name":"tower-cell","codepoint":"e585","styles":["solid"],"aliases":[]},{"name":"tower-observation","codepoint":"e586","styles":["solid"],"aliases":[]},{"name":"tractor","codepoint":"f722","styles":["solid"],"aliases":[]},{"name":"trade-federation","codepoint":"f513","styles":["brands"],"aliases":[]},{"name":"trademark","codepoint":"f25c","styles":["solid"],"aliases":[]},{"name":"traffic-light","codepoint":"f637","styles":["solid"],"aliases":[]},{"name":"trailer","codepoint":"e041","styles":["solid"],"aliases":[]},{"name":"train","codepoint":"f238","styles":["solid"],"aliases":[]},{"name":"train-subway","codepoint":"f239","styles":["solid"],"aliases":["subway"]},{"name":"train-tram","codepoint":"e5b4","styles":["solid"],"aliases":[]},{"name":"transgender","codepoint":"f225","styles":["solid"],"aliases":["transgender-alt"]},{"name":"trash","codepoint":"f1f8","styles":["solid"],"aliases":[]},{"name":"trash-arrow-up","codepoint":"f829","styles":["solid"],"aliases":["trash-restore"]},{"name":"trash-can","codepoint":"f2ed","styles":["regular","solid"],"aliases":["trash-alt"]},{"name":"trash-can-arrow-up","codepoint":"f82a","styles":["solid"],"aliases":["trash-restore-alt"]},{"name":"tree","codepoint":"f1bb","styles":["solid"],"aliases":[]},{"name":"tree-city","codepoint":"e587","styles":["solid"],"aliases":[]},{"name":"trello","codepoint":"f181","styles":["brands"],"aliases":[]},{"name":"triangle-exclamation","codepoint":"f071","styles":["solid"],"aliases":["exclamation-triangle","warning"]},{"name":"trophy","codepoint":"f091","styles":["solid"],"aliases":[]},{"name":"trowel","codepoint":"e589","styles":["solid"],"aliases":[]},{"name":"trowel-bricks","codepoint":"e58a","styles":["solid"],"aliases":[]},{"name":"truck","codepoint":"f0d1","styles":["solid"],"aliases":[]},{"name":"truck-arrow-right","codepoint":"e58b","styles":["solid"],"aliases":[]},{"name":"truck-droplet","codepoint":"e58c","styles":["solid"],"aliases":[]},{"name":"truck-fast","codepoint":"f48b","styles":["solid"],"aliases":["shipping-fast"]},{"name":"truck-field","codepoint":"e58d","styles":["solid"],"aliases":[]},{"name":"truck-field-un","codepoint":"e58e","styles":["solid"],"aliases":[]},{"name":"truck-front","codepoint":"e2b7","styles":["solid"],"aliases":[]},{"name":"truck-medical","codepoint":"f0f9","styles":["solid"],"aliases":["ambulance"]},{"name":"truck-monster","codepoint":"f63b","styles":["solid"],"aliases":[]},{"name":"truck-moving","codepoint":"f4df","styles":["solid"],"aliases":[]},{"name":"truck-pickup","codepoint":"f63c","styles":["solid"],"aliases":[]},{"name":"truck-plane","codepoint":"e58f","styles":["solid"],"aliases":[]},{"name":"truck-ramp-box","codepoint":"f4de","styles":["solid"],"aliases":["truck-loading"]},{"name":"tty","codepoint":"f1e4","styles":["solid"],"aliases":["teletype"]},{"name":"tumblr","codepoint":"f173","styles":["brands"],"aliases":[]},{"name":"turkish-lira-sign","codepoint":"e2bb","styles":["solid"],"aliases":["try","turkish-lira"]},{"name":"turn-down","codepoint":"f3be","styles":["solid"],"aliases":["level-down-alt"]},{"name":"turn-up","codepoint":"f3bf","styles":["solid"],"aliases":["level-up-alt"]},{"name":"tv","codepoint":"f26c","styles":["solid"],"aliases":["television","tv-alt"]},{"name":"twitch","codepoint":"f1e8","styles":["brands"],"aliases":[]},{"name":"twitter","codepoint":"f099","styles":["brands"],"aliases":[]},{"name":"typo3","codepoint":"f42b","styles":["brands"],"aliases":[]},{"name":"u","codepoint":"55","styles":["solid"],"aliases":[]},{"name":"uber","codepoint":"f402","styles":["brands"],"aliases":[]},{"name":"ubuntu","codepoint":"f7df","styles":["brands"],"aliases":[]},{"name":"uikit","codepoint":"f403","styles":["brands"],"aliases":[]},{"name":"umbraco","codepoint":"f8e8","styles":["brands"],"aliases":[]},{"name":"umbrella","codepoint":"f0e9","styles":["solid"],"aliases":[]},{"name":"umbrella-beach","codepoint":"f5ca","styles":["solid"],"aliases":[]},{"name":"uncharted","codepoint":"e084","styles":["brands"],"aliases":[]},{"name":"underline","codepoint":"f0cd","styles":["solid"],"aliases":[]},{"name":"uniregistry","codepoint":"f404","styles":["brands"],"aliases":[]},{"name":"unity","codepoint":"e049","styles":["brands"],"aliases":[]},{"name":"universal-access","codepoint":"f29a","styles":["solid"],"aliases":[]},{"name":"unlock","codepoint":"f09c","styles":["solid"],"aliases":[]},{"name":"unlock-keyhole","codepoint":"f13e","styles":["solid"],"aliases":["unlock-alt"]},{"name":"unsplash","codepoint":"e07c","styles":["brands"],"aliases":[]},{"name":"untappd","codepoint":"f405","styles":["brands"],"aliases":[]},{"name":"up-down","codepoint":"f338","styles":["solid"],"aliases":["arrows-alt-v"]},{"name":"up-down-left-right","codepoint":"f0b2","styles":["solid"],"aliases":["arrows-alt"]},{"name":"up-long","codepoint":"f30c","styles":["solid"],"aliases":["long-arrow-alt-up"]},{"name":"up-right-and-down-left-from-center","codepoint":"f424","styles":["solid"],"aliases":["expand-alt"]},{"name":"up-right-from-square","codepoint":"f35d","styles":["solid"],"aliases":["external-link-alt"]},{"name":"upload","codepoint":"f093","styles":["solid"],"aliases":[]},{"name":"ups","codepoint":"f7e0","styles":["brands"],"aliases":[]},{"name":"upwork","codepoint":"e641","styles":["brands"],"aliases":[]},{"name":"usb","codepoint":"f287","styles":["brands"],"aliases":[]},{"name":"user","codepoint":"f007","styles":["regular","solid"],"aliases":[]},{"name":"user-astronaut","codepoint":"f4fb","styles":["solid"],"aliases":[]},{"name":"user-check","codepoint":"f4fc","styles":["solid"],"aliases":[]},{"name":"user-clock","codepoint":"f4fd","styles":["solid"],"aliases":[]},{"name":"user-doctor","codepoint":"f0f0","styles":["solid"],"aliases":["user-md"]},{"name":"user-gear","codepoint":"f4fe","styles":["solid"],"aliases":["user-cog"]},{"name":"user-graduate","codepoint":"f501","styles":["solid"],"aliases":[]},{"name":"user-group","codepoint":"f500","styles":["solid"],"aliases":["user-friends"]},{"name":"user-injured","codepoint":"f728","styles":["solid"],"aliases":[]},{"name":"user-large","codepoint":"f406","styles":["solid"],"aliases":["user-alt"]},{"name":"user-large-slash","codepoint":"f4fa","styles":["solid"],"aliases":["user-alt-slash"]},{"name":"user-lock","codepoint":"f502","styles":["solid"],"aliases":[]},{"name":"user-minus","codepoint":"f503","styles":["solid"],"aliases":[]},{"name":"user-ninja","codepoint":"f504","styles":["solid"],"aliases":[]},{"name":"user-nurse","codepoint":"f82f","styles":["solid"],"aliases":[]},{"name":"user-pen","codepoint":"f4ff","styles":["solid"],"aliases":["user-edit"]},{"name":"user-plus","codepoint":"f234","styles":["solid"],"aliases":[]},{"name":"user-secret","codepoint":"f21b","styles":["solid"],"aliases":[]},{"name":"user-shield","codepoint":"f505","styles":["solid"],"aliases":[]},{"name":"user-slash","codepoint":"f506","styles":["solid"],"aliases":[]},{"name":"user-tag","codepoint":"f507","styles":["solid"],"aliases":[]},{"name":"user-tie","codepoint":"f508","styles":["solid"],"aliases":[]},{"name":"user-xmark","codepoint":"f235","styles":["solid"],"aliases":["user-times"]},{"name":"users","codepoint":"f0c0","styles":["solid"],"aliases":[]},{"name":"users-between-lines","codepoint":"e591","styles":["solid"],"aliases":[]},{"name":"users-gear","codepoint":"f509","styles":["solid"],"aliases":["users-cog"]},{"name":"users-line","codepoint":"e592","styles":["solid"],"aliases":[]},{"name":"users-rays","codepoint":"e593","styles":["solid"],"aliases":[]},{"name":"users-rectangle","codepoint":"e594","styles":["solid"],"aliases":[]},{"name":"users-slash","codepoint":"e073","styles":["solid"],"aliases":[]},{"name":"users-viewfinder","codepoint":"e595","styles":["solid"],"aliases":[]},{"name":"usps","codepoint":"f7e1","styles":["brands"],"aliases":[]},{"name":"ussunnah","codepoint":"f407","styles":["brands"],"aliases":[]},{"name":"utensils","codepoint":"f2e7","styles":["solid"],"aliases":["cutlery"]},{"name":"v","codepoint":"56","styles":["solid"],"aliases":[]},{"name":"vaadin","codepoint":"f408","styles":["brands"],"aliases":[]},{"name":"van-shuttle","codepoint":"f5b6","styles":["solid"],"aliases":["shuttle-van"]},{"name":"vault","codepoint":"e2c5","styles":["solid"],"aliases":[]},{"name":"vector-square","codepoint":"f5cb","styles":["solid"],"aliases":[]},{"name":"venus","codepoint":"f221","styles":["solid"],"aliases":[]},{"name":"venus-double","codepoint":"f226","styles":["solid"],"aliases":[]},{"name":"venus-mars","codepoint":"f228","styles":["solid"],"aliases":[]},{"name":"vest","codepoint":"e085","styles":["solid"],"aliases":[]},{"name":"vest-patches","codepoint":"e086","styles":["solid"],"aliases":[]},{"name":"viacoin","codepoint":"f237","styles":["brands"],"aliases":[]},{"name":"viadeo","codepoint":"f2a9","styles":["brands"],"aliases":[]},{"name":"vial","codepoint":"f492","styles":["solid"],"aliases":[]},{"name":"vial-circle-check","codepoint":"e596","styles":["solid"],"aliases":[]},{"name":"vial-virus","codepoint":"e597","styles":["solid"],"aliases":[]},{"name":"vials","codepoint":"f493","styles":["solid"],"aliases":[]},{"name":"viber","codepoint":"f409","styles":["brands"],"aliases":[]},{"name":"video","codepoint":"f03d","styles":["solid"],"aliases":["video-camera"]},{"name":"video-slash","codepoint":"f4e2","styles":["solid"],"aliases":[]},{"name":"vihara","codepoint":"f6a7","styles":["solid"],"aliases":[]},{"name":"vimeo","codepoint":"f40a","styles":["brands"],"aliases":[]},{"name":"vimeo-v","codepoint":"f27d","styles":["brands"],"aliases":[]},{"name":"vine","codepoint":"f1ca","styles":["brands"],"aliases":[]},{"name":"virus","codepoint":"e074","styles":["solid"],"aliases":[]},{"name":"virus-covid","codepoint":"e4a8","styles":["solid"],"aliases":[]},{"name":"virus-covid-slash","codepoint":"e4a9","styles":["solid"],"aliases":[]},{"name":"virus-slash","codepoint":"e075","styles":["solid"],"aliases":[]},{"name":"viruses","codepoint":"e076","styles":["solid"],"aliases":[]},{"name":"vk","codepoint":"f189","styles":["brands"],"aliases":[]},{"name":"vnv","codepoint":"f40b","styles":["brands"],"aliases":[]},{"name":"voicemail","codepoint":"f897","styles":["solid"],"aliases":[]},{"name":"volcano","codepoint":"f770","styles":["solid"],"aliases":[]},{"name":"volleyball","codepoint":"f45f","styles":["solid"],"aliases":["volleyball-ball"]},{"name":"volume-high","codepoint":"f028","styles":["solid"],"aliases":["volume-up"]},{"name":"volume-low","codepoint":"f027","styles":["solid"],"aliases":["volume-down"]},{"name":"volume-off","codepoint":"f026","styles":["solid"],"aliases":[]},{"name":"volume-xmark","codepoint":"f6a9","styles":["solid"],"aliases":["volume-mute","volume-times"]},{"name":"vr-cardboard","codepoint":"f729","styles":["solid"],"aliases":[]},{"name":"vuejs","codepoint":"f41f","styles":["brands"],"aliases":[]},{"name":"w","codepoint":"57","styles":["solid"],"aliases":[]},{"name":"walkie-talkie","codepoint":"f8ef","styles":["solid"],"aliases":[]},{"name":"wallet","codepoint":"f555","styles":["solid"],"aliases":[]},{"name":"wand-magic","codepoint":"f0d0","styles":["solid"],"aliases":["magic"]},{"name":"wand-magic-sparkles","codepoint":"e2ca","styles":["solid"],"aliases":["magic-wand-sparkles"]},{"name":"wand-sparkles","codepoint":"f72b","styles":["solid"],"aliases":[]},{"name":"warehouse","codepoint":"f494","styles":["solid"],"aliases":[]},{"name":"watchman-monitoring","codepoint":"e087","styles":["brands"],"aliases":[]},{"name":"water","codepoint":"f773","styles":["solid"],"aliases":[]},{"name":"water-ladder","codepoint":"f5c5","styles":["solid"],"aliases":["ladder-water","swimming-pool"]},{"name":"wave-square","codepoint":"f83e","styles":["solid"],"aliases":[]},{"name":"waze","codepoint":"f83f","styles":["brands"],"aliases":[]},{"name":"web-awesome","codepoint":"e682","styles":["brands","solid"],"aliases":[]},{"name":"webflow","codepoint":"e65c","styles":["brands"],"aliases":[]},{"name":"weebly","codepoint":"f5cc","styles":["brands"],"aliases":[]},{"name":"weibo","codepoint":"f18a","styles":["brands"],"aliases":[]},{"name":"weight-hanging","codepoint":"f5cd","styles":["solid"],"aliases":[]},{"name":"weight-scale","codepoint":"f496","styles":["solid"],"aliases":["weight"]},{"name":"weixin","codepoint":"f1d7","styles":["brands"],"aliases":[]},{"name":"whatsapp","codepoint":"f232","styles":["brands"],"aliases":[]},{"name":"wheat-awn","codepoint":"e2cd","styles":["solid"],"aliases":["wheat-alt"]},{"name":"wheat-awn-circle-exclamation","codepoint":"e598","styles":["solid"],"aliases":[]},{"name":"wheelchair","codepoint":"f193","styles":["solid"],"aliases":[]},{"name":"wheelchair-move","codepoint":"e2ce","styles":["solid"],"aliases":["wheelchair-alt"]},{"name":"whiskey-glass","codepoint":"f7a0","styles":["solid"],"aliases":["glass-whiskey"]},{"name":"whmcs","codepoint":"f40d","styles":["brands"],"aliases":[]},{"name":"wifi","codepoint":"f1eb","styles":["solid"],"aliases":["wifi-3","wifi-strong"]},{"name":"wikipedia-w","codepoint":"f266","styles":["brands"],"aliases":[]},{"name":"wind","codepoint":"f72e","styles":["solid"],"aliases":[]},{"name":"window-maximize","codepoint":"f2d0","styles":["regular","solid"],"aliases":[]},{"name":"window-minimize","codepoint":"f2d1","styles":["regular","solid"],"aliases":[]},{"name":"window-restore","codepoint":"f2d2","styles":["regular","solid"],"aliases":[]},{"name":"windows","codepoint":"f17a","styles":["brands"],"aliases":[]},{"name":"wine-bottle","codepoint":"f72f","styles":["solid"],"aliases":[]},{"name":"wine-glass","codepoint":"f4e3","styles":["solid"],"aliases":[]},{"name":"wine-glass-empty","codepoint":"f5ce","styles":["solid"],"aliases":["wine-glass-alt"]},{"name":"wirsindhandwerk","codepoint":"e2d0","styles":["brands"],"aliases":["wsh"]},{"name":"wix","codepoint":"f5cf","styles":["brands"],"aliases":[]},{"name":"wizards-of-the-coast","codepoint":"f730","styles":["brands"],"aliases":[]},{"name":"wodu","codepoint":"e088","styles":["brands"],"aliases":[]},{"name":"wolf-pack-battalion","codepoint":"f514","styles":["brands"],"aliases":[]},{"name":"won-sign","codepoint":"f159","styles":["solid"],"aliases":["krw","won"]},{"name":"wordpress","codepoint":"f19a","styles":["brands"],"aliases":[]},{"name":"wordpress-simple","codepoint":"f411","styles":["brands"],"aliases":[]},{"name":"worm","codepoint":"e599","styles":["solid"],"aliases":[]},{"name":"wpbeginner","codepoint":"f297","styles":["brands"],"aliases":[]},{"name":"wpexplorer","codepoint":"f2de","styles":["brands"],"aliases":[]},{"name":"wpforms","codepoint":"f298","styles":["brands"],"aliases":[]},{"name":"wpressr","codepoint":"f3e4","styles":["brands"],"aliases":["rendact"]},{"name":"wrench","codepoint":"f0ad","styles":["solid"],"aliases":[]},{"name":"x","codepoint":"58","styles":["solid"],"aliases":[]},{"name":"x-ray","codepoint":"f497","styles":["solid"],"aliases":[]},{"name":"x-twitter","codepoint":"e61b","styles":["brands"],"aliases":[]},{"name":"xbox","codepoint":"f412","styles":["brands"],"aliases":[]},{"name":"xing","codepoint":"f168","styles":["brands"],"aliases":[]},{"name":"xmark","codepoint":"f00d","styles":["solid"],"aliases":["close","multiply","remove","times"]},{"name":"xmarks-lines","codepoint":"e59a","styles":["solid"],"aliases":[]},{"name":"y","codepoint":"59","styles":["solid"],"aliases":[]},{"name":"y-combinator","codepoint":"f23b","styles":["brands"],"aliases":[]},{"name":"yahoo","codepoint":"f19e","styles":["brands"],"aliases":[]},{"name":"yammer","codepoint":"f840","styles":["brands"],"aliases":[]},{"name":"yandex","codepoint":"f413","styles":["brands"],"aliases":[]},{"name":"yandex-international","codepoint":"f414","styles":["brands"],"aliases":[]},{"name":"yarn","codepoint":"f7e3","styles":["brands"],"aliases":[]},{"name":"yelp","codepoint":"f1e9","styles":["brands"],"aliases":[]},{"name":"yen-sign","codepoint":"f157","styles":["solid"],"aliases":["cny","jpy","rmb","yen"]},{"name":"yin-yang","codepoint":"f6ad","styles":["solid"],"aliases":[]},{"name":"yoast","codepoint":"f2b1","styles":["brands"],"aliases":[]},{"name":"youtube","codepoint":"f167","styles":["brands"],"aliases":[]},{"name":"z","codepoint":"5a","styles":["solid"],"aliases":[]},{"name":"zhihu","codepoint":"f63f","styles":["brands"],"aliases":[]}] \ No newline at end of file diff --git a/src/imagespec/resolvers.py b/src/imagespec/resolvers.py index 495bdfa..ed55084 100644 --- a/src/imagespec/resolvers.py +++ b/src/imagespec/resolvers.py @@ -89,3 +89,57 @@ def resolver(name: str) -> str | None: return cached return resolver + + +# ── Verified-license Google Fonts preset ──────────────────────────────────── +# Direct download URLs from the official google/fonts GitHub repo's `ofl/` +# directory — every family there is licensed under the SIL Open Font License +# 1.1 (the directory name is google/fonts' own convention for this), so there +# is no per-font license to chase down before using these, unlike an arbitrary +# font URL. Covers scripts NotoSansKR-Regular.ttf (this package's bundled +# default) doesn't: Japanese, Simplified/Traditional Chinese, Arabic, Thai, +# plus a broader Latin/Cyrillic/Greek family. +# +# These are variable fonts (a single file covering a weight/width range); PIL +# loads them at their default instance, which is fine for `ImageFont.truetype`. +GOOGLE_FONTS_SOURCES: dict[str, str] = { + "NotoSans-Regular.ttf": "https://raw.githubusercontent.com/google/fonts/main/ofl/notosans/NotoSans%5Bwdth%2Cwght%5D.ttf", + "NotoSansJP-Regular.ttf": "https://raw.githubusercontent.com/google/fonts/main/ofl/notosansjp/NotoSansJP%5Bwght%5D.ttf", + "NotoSansSC-Regular.ttf": "https://raw.githubusercontent.com/google/fonts/main/ofl/notosanssc/NotoSansSC%5Bwght%5D.ttf", + "NotoSansTC-Regular.ttf": "https://raw.githubusercontent.com/google/fonts/main/ofl/notosanstc/NotoSansTC%5Bwght%5D.ttf", + "NotoSansArabic-Regular.ttf": "https://raw.githubusercontent.com/google/fonts/main/ofl/notosansarabic/NotoSansArabic%5Bwdth%2Cwght%5D.ttf", + "NotoSansThai-Regular.ttf": "https://raw.githubusercontent.com/google/fonts/main/ofl/notosansthai/NotoSansThai%5Bwdth%2Cwght%5D.ttf", +} + + +def google_fonts_resolver( + cache_dir: str, + families: list[str] | None = None, + *, + session: requests.Session | None = None, + timeout: float = 30, +) -> FontResolver: + """``caching_resolver`` pre-loaded with :data:`GOOGLE_FONTS_SOURCES`. + + Downloads on first use and caches to disk, same as :func:`caching_resolver` + — this just saves looking up/typing the source URLs yourself. + + Parameters + ---------- + cache_dir: + Directory to store downloaded fonts (created if missing). + families: + Subset of :data:`GOOGLE_FONTS_SOURCES` keys to make available (e.g. + ``["NotoSansJP-Regular.ttf"]``); ``None`` (default) makes all of them + available — nothing is downloaded until a payload actually asks for one. + + Example + ------- + :: + + ctx = RenderContext(font_resolver=google_fonts_resolver("~/.cache/imagespec/fonts")) + # a payload with `"font": "NotoSansJP-Regular.ttf"` now resolves, + # downloading once and reusing the cached file after that. + """ + sources = GOOGLE_FONTS_SOURCES if families is None else {k: GOOGLE_FONTS_SOURCES[k] for k in families} + return caching_resolver(cache_dir, sources=sources, session=session, timeout=timeout) diff --git a/tests/test_features.py b/tests/test_features.py index 94e3a2e..3941ec0 100644 --- a/tests/test_features.py +++ b/tests/test_features.py @@ -8,7 +8,7 @@ import pytest from PIL import Image -from imagespec import render +from imagespec import RenderError, render @pytest.fixture @@ -201,3 +201,74 @@ def test_qrcode_pixel_box_fits_and_square(bw_ctx): # fits within the 5..65 box on both axes and is (near-)square assert max(xs) <= 65 and max(ys) <= 65 assert abs((max(xs) - min(xs)) - (max(ys) - min(ys))) <= 1 + + +# --- Font Awesome Free icons (icon / rich_text / legend), alongside MDI --- + + +def _has_dark_pixel(img): + return any(img.getpixel((x, y)) != (255, 255, 255) for x in range(img.width) for y in range(img.height)) + + +def test_icon_fa_auto_style_renders(bw_ctx): + # "fa:" with no forced style auto-picks solid (house's only free style) + el = {"type": "icon", "x": 2, "y": 2, "value": "fa:house", "size": 24} + img = render([el], 30, 30, background="white", context=bw_ctx) + assert _has_dark_pixel(img) + + +def test_icon_fa_forced_solid_and_brands_render(bw_ctx): + solid = render([{"type": "icon", "x": 2, "y": 2, "value": "fas:house", "size": 24}], 30, 30, context=bw_ctx) + brands = render([{"type": "icon", "x": 2, "y": 2, "value": "fab:github", "size": 24}], 30, 30, context=bw_ctx) + assert _has_dark_pixel(solid) + assert _has_dark_pixel(brands) + + +def test_icon_fa_alias_resolves(bw_ctx): + # FA6 renamed "home" -> "house"; "home" is registered as an alias + el = {"type": "icon", "x": 2, "y": 2, "value": "fa:home", "size": 24} + img = render([el], 30, 30, background="white", context=bw_ctx) + assert _has_dark_pixel(img) + + +def test_icon_mdi_still_default_without_prefix(ctx): + # backward compatibility: a bare/`mdi:` name still resolves via MDI + el = {"type": "icon", "x": 0, "y": 0, "value": "home", "size": 16} + assert render([el], 20, 20, context=ctx).size == (20, 20) + + +def test_icon_fa_forced_style_without_glyph_raises(ctx): + # "house" has no brands-style glyph + el = {"type": "icon", "x": 0, "y": 0, "value": "fab:house", "size": 16} + with pytest.raises(RenderError, match="brands"): + render([el], 20, 20, context=ctx) + + +def test_icon_fa_unknown_name_raises(ctx): + el = {"type": "icon", "x": 0, "y": 0, "value": "fa:not-a-real-icon", "size": 16} + with pytest.raises(RenderError): + render([el], 20, 20, context=ctx) + + +def test_rich_text_fa_icon_span(ctx): + el = { + "type": "rich_text", + "x": 2, + "y": 10, + "spans": [{"text": "Temp "}, {"icon": "fas:house", "size": 14}], + "size": 12, + } + assert render([el], 80, 20, context=ctx).size == (80, 20) + + +def test_legend_fa_icon_item(bw_ctx): + el = { + "type": "legend", + "x": 0, + "y": 0, + "items": [{"label": "home", "icon": "fas:house", "color": "black"}], + "size": 12, + "swatch_size": 12, + } + img = render([el], 60, 20, background="white", context=bw_ctx) + assert _has_dark_pixel(img) diff --git a/tests/test_resolvers.py b/tests/test_resolvers.py index 3cb6b88..72176a0 100644 --- a/tests/test_resolvers.py +++ b/tests/test_resolvers.py @@ -4,14 +4,14 @@ import os -from imagespec import chain_resolvers, directory_resolver +from imagespec import GOOGLE_FONTS_SOURCES, chain_resolvers, directory_resolver, google_fonts_resolver from imagespec.context import BUNDLED_FONTS_DIR from imagespec.resolvers import caching_resolver def test_directory_resolver_hit(): r = directory_resolver(BUNDLED_FONTS_DIR) - assert r("ppb.ttf") == os.path.join(BUNDLED_FONTS_DIR, "ppb.ttf") + assert r("NotoSansKR-Regular.ttf") == os.path.join(BUNDLED_FONTS_DIR, "NotoSansKR-Regular.ttf") def test_directory_resolver_miss(): @@ -23,12 +23,12 @@ def test_chain_picks_first_hit(): directory_resolver("/no/such/dir"), directory_resolver(BUNDLED_FONTS_DIR), ) - assert r("ppb.ttf") == os.path.join(BUNDLED_FONTS_DIR, "ppb.ttf") + assert r("NotoSansKR-Regular.ttf") == os.path.join(BUNDLED_FONTS_DIR, "NotoSansKR-Regular.ttf") def test_chain_all_miss(): r = chain_resolvers(directory_resolver("/no/such/dir"), None) - assert r("ppb.ttf") is None + assert r("NotoSansKR-Regular.ttf") is None def test_caching_resolver_unknown_returns_none(tmp_path): @@ -42,3 +42,33 @@ def test_caching_resolver_uses_existing_cache(tmp_path): cached.write_bytes(b"not really a font") r = caching_resolver(str(tmp_path), sources={"Seed.ttf": "http://example/should-not-fetch"}) assert r("Seed.ttf") == str(cached) + + +def test_google_fonts_sources_cover_expected_scripts(): + # a sanity check on the preset table itself, not network access + for name in ( + "NotoSans-Regular.ttf", + "NotoSansJP-Regular.ttf", + "NotoSansSC-Regular.ttf", + "NotoSansTC-Regular.ttf", + "NotoSansArabic-Regular.ttf", + "NotoSansThai-Regular.ttf", + ): + assert name in GOOGLE_FONTS_SOURCES + url = GOOGLE_FONTS_SOURCES[name] + assert url.startswith("https://raw.githubusercontent.com/google/fonts/main/ofl/") + assert url.endswith(".ttf") + + +def test_google_fonts_resolver_uses_existing_cache(tmp_path): + # same caching behaviour as caching_resolver, pre-seeded so no network is hit + cached = tmp_path / "NotoSansJP-Regular.ttf" + cached.write_bytes(b"not really a font") + r = google_fonts_resolver(str(tmp_path)) + assert r("NotoSansJP-Regular.ttf") == str(cached) + + +def test_google_fonts_resolver_families_filter_excludes_others(tmp_path): + r = google_fonts_resolver(str(tmp_path), families=["NotoSansJP-Regular.ttf"]) + # not in the filtered subset, and not cached -> no source to fetch from -> None + assert r("NotoSansArabic-Regular.ttf") is None