diff --git a/.github/README.md b/.github/README.md
index a434594..6594946 100644
--- a/.github/README.md
+++ b/.github/README.md
@@ -1,154 +1,57 @@
# libmsdf
-
+
+[](https://github.com/KAJARLABORATORIES/libmsdf/actions/workflows/release.yml)
[](https://www.nuget.org/packages/kajarlabs.osu.Framework.MsdfTextRendering)
-[](https://github.com/KAJARLABORATORIES/libmsdf/blob/main/COPYING)
-
+[](https://github.com/KAJARLABORATORIES/libmsdf/releases/latest)
+
MSDF text rendering for [osu!framework](https://github.com/ppy/osu-framework).
-
-`libmsdf` replaces bitmap glyph rendering with [multi-channel signed distance fields](https://github.com/Chlumsky/msdfgen), so text stays sharp at any size or scale. Glyph coverage is reconstructed in the fragment shader instead of being baked into a texture at a fixed resolution.
-
-> **Pre-release.** The current version is `0.1.0-alpha`. The public API is expected to change before `1.0.0`. Pin an exact version if you depend on it.
-
-## Installation
-
-```bash
-dotnet add package kajarlabs.osu.Framework.MsdfTextRendering --prerelease
-```
-
-Or, as a `PackageReference`:
-
-```xml
-
-```
-
-`--prerelease` is required while the package has no stable release: NuGet hides pre-release versions by default.
-
-## Quick start
-
-Register the MSDF resources and the fonts you want to use, then draw text with `MsdfSpriteText`:
-
-```csharp
-public partial class MsdfShowcase : Game
-{
- private DependencyContainer dependencies = null!;
-
- protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
- => dependencies = new DependencyContainer(parent);
-
- [BackgroundDependencyLoader]
- private void load()
- {
- MsdfTextRendering.CreateCapabilities(Resources);
-
- var msdfFonts = new MsdfFontStore(Host.Renderer, Shaders);
-
- msdfFonts.AddFont(Resources, "WorkSans", "Regular");
- msdfFonts.AddFont(Resources, "WorkSans", "Bold");
-
- dependencies.CacheAs(msdfFonts);
-
- Add(new MsdfSpriteText
- {
- Text = "Hello, MSDF!",
- Font = new FontUsage("WorkSans", 32, "Regular"),
- });
- }
-}
-```
-
-`MsdfSpriteText` behaves like `SpriteText`: same layout model, same sizing rules, same localisation support. Only the glyph rendering path differs.
-
-The fonts themselves are not shipped with the package. See the next section.
-
-## Generating font atlases
-
-An MSDF font is an atlas texture plus a JSON metadata file. Both are required, and both are generated with [`msdf-atlas-gen`](https://github.com/Chlumsky/msdf-atlas-gen):
-
-```bash
-msdf-atlas-gen -font WorkSans-Regular.ttf \
- -type msdf \
- -format png \
- -size 48 \
- -pxrange 4 \
- -yorigin top \
- -imageout WorkSans-Regular.png \
- -json WorkSans-Regular.json
+
+## Using libmsdf in your game
+
+If you are interested in **using** the library, install the package and start from the [setting up MSDF fonts](https://github.com/KAJARLABORATORIES/libmsdf/wiki/Setting-Up-MSDF-Fonts) wiki page, which walks through generating an atlas, registering it and drawing text with it.
+
```
-
-| Option | Why it matters |
-| -------------- | ------------------------------------------------------------------ |
-| `-type msdf` | Multi-channel distance field. `sdf` will not work with the shader. |
-| `-size 48` | Em size used for generation. Larger means a larger atlas. |
-| `-pxrange 4` | Distance range around glyph edges. Too low causes soft corners. |
-| `-yorigin top` | Matches the coordinate system osu!framework expects. |
-
-The JSON carries glyph metrics, atlas and plane bounds, kerning pairs, and the `distanceRange` the shader uses to reconstruct coverage.
-
-Generate one pair per weight and style, and name the files after the family and style you pass to `AddFont`:
-
-```text
-Resources/Typefaces/
-└── WorkSans/
- ├── WorkSans-Regular.png
- ├── WorkSans-Regular.json
- ├── WorkSans-Bold.png
- ├── WorkSans-Bold.json
- ├── WorkSans-RegularItalic.png
- └── WorkSans-RegularItalic.json
+dotnet add package kajarlabs.osu.Framework.MsdfTextRendering --prerelease
```
-
-## What's supported
-
-- Arbitrary sizes and scales without re-rasterisation
-- Font families with weight and italic variants
-- Kerning, baselines and glyph metrics
-- Multiline text, truncation with ellipsis, fixed width
-- Auto-sizing and maximum width
-- Fallback glyphs
-- Shadows
-- Localisation
-- Glyph lookup with caching
-
-## API
-
-### `MsdfSpriteText`
-
-The drawable you use. Mirrors `SpriteText`.
-
-```csharp
-new MsdfSpriteText
-{
- Text = "The quick brown fox jumps over the lazy dog.",
- Font = new FontUsage("WorkSans", 24, "Regular"),
- Shadow = true,
-}
+
+The library is pre-`1.0.0`. The public API may change between `0.x` releases, so pin an exact version if you depend on it.
+
+The rest of the information on this page is related to working *on* the library, not *using* it!
+
+## Objectives
+
+osu!framework renders text from pre-rasterised bitmap atlases. That is fast and predictable, but a glyph baked at one size degrades once it is drawn far beyond it, which shows up in any UI that zooms, animates scale, or shares a typeface across a wide range of sizes.
+
+`libmsdf` provides a second rendering path built on [multi-channel signed distance fields](https://github.com/Chlumsky/msdfgen), where glyph coverage is reconstructed in the fragment shader instead of sampled from a fixed-resolution texture.
+
+- Stay a **drop-in alternative**, not a replacement. `MsdfSpriteText` mirrors `SpriteText`, and MSDF glyphs implement the framework's own glyph abstractions so the existing text builder, layout and localisation keep working.
+- Keep the atlas pipeline **external and standard**. Atlases are produced by [`msdf-atlas-gen`](https://github.com/Chlumsky/msdf-atlas-gen), so nothing here is a bespoke font format.
+- Cover the same text features users already expect: kerning, multiline, truncation, fixed width, fallback glyphs and shadows.
+MSDF is not a free upgrade for every case. At small, static sizes a hinted bitmap font is cheaper and often looks better; this library is aimed at the cases where one atlas has to serve many sizes.
+
+## Requirements
+
+- A desktop platform with the [.NET 10.0 SDK](https://dotnet.microsoft.com/download).
+- [`msdf-atlas-gen`](https://github.com/Chlumsky/msdf-atlas-gen) for generating font atlases.
+- When working with the codebase, we recommend an IDE with intellisense and syntax highlighting, such as [Visual Studio](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/), or [Visual Studio Code](https://code.visualstudio.com/) with the [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) and [C#](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) extensions installed.
+
+### Building
+
```
-
-### `MsdfFontStore`
-
-Resolves families and styles to glyphs, and caches them. Register fonts once, at load time:
-
-```csharp
-msdfFonts.AddFont(Resources, "WorkSans", "Regular");
-msdfFonts.AddFont(Resources, "WorkSans", "Bold");
-msdfFonts.AddFont(Resources, "WorkSans", "RegularItalic");
+dotnet build
+dotnet test
```
-
-Cache it with `CacheAs` so `MsdfSpriteText` can resolve it through dependency injection.
-
-## Shaders
-
-The package ships two fragment shaders:
-
-| Shader | Use |
-| ----------------------------- | --------------------------------------------------------- |
-| `sh_MsdfGlyph.fs` | Default. Anti-aliased coverage from the distance field. |
-| `sh_MsdfGlyphHardThreshold.fs`| Hard cutoff, no anti-aliasing. Useful for pixel-style UI. |
+
+Visual test scenes live in `tests`, and are the recommended place to develop and debug rendering changes: a distance-field bug is something you see, not something an assertion catches.
## Contributing
-
-Issues and pull requests are welcome. For bug reports, include a minimal reproduction and, where relevant, the atlas and JSON metadata that trigger the problem.
-
+
+Contributions can be made via pull requests to this repository. If you are unsure where to start, check the [list of open issues](https://github.com/KAJARLABORATORIES/libmsdf/issues).
+
+When reporting a rendering bug, include a minimal reproduction and the atlas and JSON metadata that trigger it. "The glyph looks wrong" is impossible to act on without the distance range it was generated with.
+
## License
-
-MIT. See [COPYING](https://github.com/KAJARLABORATORIES/libmsdf/blob/main/COPYING).
+
+This library is licensed under the [MIT license](https://opensource.org/licenses/MIT). Please see [the license file](../COPYING) for more information. [tl;dr](https://tldrlegal.com/license/mit-license) you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.
+
+The MSDF technique itself comes from [msdfgen](https://github.com/Chlumsky/msdfgen) by Viktor Chlumský, also MIT licensed. Atlases generated with `msdf-atlas-gen` carry the license of the font they were generated from; check it before shipping one.
diff --git a/.github/README.nuget.md b/.github/README.nuget.md
index a434594..6594946 100644
--- a/.github/README.nuget.md
+++ b/.github/README.nuget.md
@@ -1,154 +1,57 @@
# libmsdf
-
+
+[](https://github.com/KAJARLABORATORIES/libmsdf/actions/workflows/release.yml)
[](https://www.nuget.org/packages/kajarlabs.osu.Framework.MsdfTextRendering)
-[](https://github.com/KAJARLABORATORIES/libmsdf/blob/main/COPYING)
-
+[](https://github.com/KAJARLABORATORIES/libmsdf/releases/latest)
+
MSDF text rendering for [osu!framework](https://github.com/ppy/osu-framework).
-
-`libmsdf` replaces bitmap glyph rendering with [multi-channel signed distance fields](https://github.com/Chlumsky/msdfgen), so text stays sharp at any size or scale. Glyph coverage is reconstructed in the fragment shader instead of being baked into a texture at a fixed resolution.
-
-> **Pre-release.** The current version is `0.1.0-alpha`. The public API is expected to change before `1.0.0`. Pin an exact version if you depend on it.
-
-## Installation
-
-```bash
-dotnet add package kajarlabs.osu.Framework.MsdfTextRendering --prerelease
-```
-
-Or, as a `PackageReference`:
-
-```xml
-
-```
-
-`--prerelease` is required while the package has no stable release: NuGet hides pre-release versions by default.
-
-## Quick start
-
-Register the MSDF resources and the fonts you want to use, then draw text with `MsdfSpriteText`:
-
-```csharp
-public partial class MsdfShowcase : Game
-{
- private DependencyContainer dependencies = null!;
-
- protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
- => dependencies = new DependencyContainer(parent);
-
- [BackgroundDependencyLoader]
- private void load()
- {
- MsdfTextRendering.CreateCapabilities(Resources);
-
- var msdfFonts = new MsdfFontStore(Host.Renderer, Shaders);
-
- msdfFonts.AddFont(Resources, "WorkSans", "Regular");
- msdfFonts.AddFont(Resources, "WorkSans", "Bold");
-
- dependencies.CacheAs(msdfFonts);
-
- Add(new MsdfSpriteText
- {
- Text = "Hello, MSDF!",
- Font = new FontUsage("WorkSans", 32, "Regular"),
- });
- }
-}
-```
-
-`MsdfSpriteText` behaves like `SpriteText`: same layout model, same sizing rules, same localisation support. Only the glyph rendering path differs.
-
-The fonts themselves are not shipped with the package. See the next section.
-
-## Generating font atlases
-
-An MSDF font is an atlas texture plus a JSON metadata file. Both are required, and both are generated with [`msdf-atlas-gen`](https://github.com/Chlumsky/msdf-atlas-gen):
-
-```bash
-msdf-atlas-gen -font WorkSans-Regular.ttf \
- -type msdf \
- -format png \
- -size 48 \
- -pxrange 4 \
- -yorigin top \
- -imageout WorkSans-Regular.png \
- -json WorkSans-Regular.json
+
+## Using libmsdf in your game
+
+If you are interested in **using** the library, install the package and start from the [setting up MSDF fonts](https://github.com/KAJARLABORATORIES/libmsdf/wiki/Setting-Up-MSDF-Fonts) wiki page, which walks through generating an atlas, registering it and drawing text with it.
+
```
-
-| Option | Why it matters |
-| -------------- | ------------------------------------------------------------------ |
-| `-type msdf` | Multi-channel distance field. `sdf` will not work with the shader. |
-| `-size 48` | Em size used for generation. Larger means a larger atlas. |
-| `-pxrange 4` | Distance range around glyph edges. Too low causes soft corners. |
-| `-yorigin top` | Matches the coordinate system osu!framework expects. |
-
-The JSON carries glyph metrics, atlas and plane bounds, kerning pairs, and the `distanceRange` the shader uses to reconstruct coverage.
-
-Generate one pair per weight and style, and name the files after the family and style you pass to `AddFont`:
-
-```text
-Resources/Typefaces/
-└── WorkSans/
- ├── WorkSans-Regular.png
- ├── WorkSans-Regular.json
- ├── WorkSans-Bold.png
- ├── WorkSans-Bold.json
- ├── WorkSans-RegularItalic.png
- └── WorkSans-RegularItalic.json
+dotnet add package kajarlabs.osu.Framework.MsdfTextRendering --prerelease
```
-
-## What's supported
-
-- Arbitrary sizes and scales without re-rasterisation
-- Font families with weight and italic variants
-- Kerning, baselines and glyph metrics
-- Multiline text, truncation with ellipsis, fixed width
-- Auto-sizing and maximum width
-- Fallback glyphs
-- Shadows
-- Localisation
-- Glyph lookup with caching
-
-## API
-
-### `MsdfSpriteText`
-
-The drawable you use. Mirrors `SpriteText`.
-
-```csharp
-new MsdfSpriteText
-{
- Text = "The quick brown fox jumps over the lazy dog.",
- Font = new FontUsage("WorkSans", 24, "Regular"),
- Shadow = true,
-}
+
+The library is pre-`1.0.0`. The public API may change between `0.x` releases, so pin an exact version if you depend on it.
+
+The rest of the information on this page is related to working *on* the library, not *using* it!
+
+## Objectives
+
+osu!framework renders text from pre-rasterised bitmap atlases. That is fast and predictable, but a glyph baked at one size degrades once it is drawn far beyond it, which shows up in any UI that zooms, animates scale, or shares a typeface across a wide range of sizes.
+
+`libmsdf` provides a second rendering path built on [multi-channel signed distance fields](https://github.com/Chlumsky/msdfgen), where glyph coverage is reconstructed in the fragment shader instead of sampled from a fixed-resolution texture.
+
+- Stay a **drop-in alternative**, not a replacement. `MsdfSpriteText` mirrors `SpriteText`, and MSDF glyphs implement the framework's own glyph abstractions so the existing text builder, layout and localisation keep working.
+- Keep the atlas pipeline **external and standard**. Atlases are produced by [`msdf-atlas-gen`](https://github.com/Chlumsky/msdf-atlas-gen), so nothing here is a bespoke font format.
+- Cover the same text features users already expect: kerning, multiline, truncation, fixed width, fallback glyphs and shadows.
+MSDF is not a free upgrade for every case. At small, static sizes a hinted bitmap font is cheaper and often looks better; this library is aimed at the cases where one atlas has to serve many sizes.
+
+## Requirements
+
+- A desktop platform with the [.NET 10.0 SDK](https://dotnet.microsoft.com/download).
+- [`msdf-atlas-gen`](https://github.com/Chlumsky/msdf-atlas-gen) for generating font atlases.
+- When working with the codebase, we recommend an IDE with intellisense and syntax highlighting, such as [Visual Studio](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/), or [Visual Studio Code](https://code.visualstudio.com/) with the [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) and [C#](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) extensions installed.
+
+### Building
+
```
-
-### `MsdfFontStore`
-
-Resolves families and styles to glyphs, and caches them. Register fonts once, at load time:
-
-```csharp
-msdfFonts.AddFont(Resources, "WorkSans", "Regular");
-msdfFonts.AddFont(Resources, "WorkSans", "Bold");
-msdfFonts.AddFont(Resources, "WorkSans", "RegularItalic");
+dotnet build
+dotnet test
```
-
-Cache it with `CacheAs` so `MsdfSpriteText` can resolve it through dependency injection.
-
-## Shaders
-
-The package ships two fragment shaders:
-
-| Shader | Use |
-| ----------------------------- | --------------------------------------------------------- |
-| `sh_MsdfGlyph.fs` | Default. Anti-aliased coverage from the distance field. |
-| `sh_MsdfGlyphHardThreshold.fs`| Hard cutoff, no anti-aliasing. Useful for pixel-style UI. |
+
+Visual test scenes live in `tests`, and are the recommended place to develop and debug rendering changes: a distance-field bug is something you see, not something an assertion catches.
## Contributing
-
-Issues and pull requests are welcome. For bug reports, include a minimal reproduction and, where relevant, the atlas and JSON metadata that trigger the problem.
-
+
+Contributions can be made via pull requests to this repository. If you are unsure where to start, check the [list of open issues](https://github.com/KAJARLABORATORIES/libmsdf/issues).
+
+When reporting a rendering bug, include a minimal reproduction and the atlas and JSON metadata that trigger it. "The glyph looks wrong" is impossible to act on without the distance range it was generated with.
+
## License
-
-MIT. See [COPYING](https://github.com/KAJARLABORATORIES/libmsdf/blob/main/COPYING).
+
+This library is licensed under the [MIT license](https://opensource.org/licenses/MIT). Please see [the license file](../COPYING) for more information. [tl;dr](https://tldrlegal.com/license/mit-license) you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.
+
+The MSDF technique itself comes from [msdfgen](https://github.com/Chlumsky/msdfgen) by Viktor Chlumský, also MIT licensed. Atlases generated with `msdf-atlas-gen` carry the license of the font they were generated from; check it before shipping one.
diff --git a/lib/Graphics/Containers/IMsdfTextPart.cs b/lib/Graphics/Containers/IMsdfTextPart.cs
new file mode 100644
index 0000000..3d827b3
--- /dev/null
+++ b/lib/Graphics/Containers/IMsdfTextPart.cs
@@ -0,0 +1,12 @@
+using osu.Framework.Graphics;
+
+namespace kajarlabs.osu.Framework.MsdfTextRendering.Graphics.Containers;
+
+public interface IMsdfTextPart
+{
+ IEnumerable Drawables { get; }
+
+ event Action>? DrawablePartsRecreated;
+
+ void RecreateDrawablesFor(MsdfTextFlowContainer textFlowContainer);
+}
diff --git a/lib/Graphics/Containers/MsdfTextChunk.cs b/lib/Graphics/Containers/MsdfTextChunk.cs
new file mode 100644
index 0000000..7927b55
--- /dev/null
+++ b/lib/Graphics/Containers/MsdfTextChunk.cs
@@ -0,0 +1,115 @@
+using System.Globalization;
+using System.Text;
+using kajarlabs.osu.Framework.MsdfTextRendering.Graphics.Sprites;
+using osu.Framework.Graphics;
+using osu.Framework.Localisation;
+
+namespace kajarlabs.osu.Framework.MsdfTextRendering.Graphics.Containers;
+
+public class MsdfTextChunk : MsdfTextPart
+ where TMsdfSpriteText : MsdfSpriteText, new()
+{
+ private readonly LocalisableString text;
+ private readonly bool newLineIsParagraph;
+ private readonly Func creationFunc;
+ private readonly Action? creationParameters;
+
+ public MsdfTextChunk(LocalisableString text, bool newLineIsParagraph, Func creationFunc, Action? creationParameters = null)
+ {
+ this.text = text;
+ this.newLineIsParagraph = newLineIsParagraph;
+ this.creationFunc = creationFunc;
+ this.creationParameters = creationParameters;
+ }
+
+ protected override IEnumerable CreateDrawablesFor(MsdfTextFlowContainer textFlowContainer)
+ {
+ var currentContent = textFlowContainer.Localisation?.GetLocalisedString(text) ?? text.ToString();
+
+ var drawables = new List();
+
+ if (!newLineIsParagraph)
+ {
+ var newLine = new MsdfTextNewLine(true);
+
+ newLine.RecreateDrawablesFor(textFlowContainer);
+ drawables.AddRange(newLine.Drawables);
+ }
+
+ drawables.AddRange(CreateDrawablesFor(currentContent, textFlowContainer));
+ return drawables;
+ }
+
+ protected virtual IEnumerable CreateDrawablesFor(string text, MsdfTextFlowContainer textFlowContainer)
+ {
+ var first = true;
+ var sprites = new List();
+
+ foreach (var l in text.Split('\n'))
+ {
+ if (!first)
+ {
+ var lastChild = sprites.LastOrDefault() ?? textFlowContainer.Children.LastOrDefault();
+
+ if (lastChild != null)
+ {
+ var newLine = new MsdfTextFlowContainer.NewLineContainer(newLineIsParagraph);
+
+ sprites.Add(newLine);
+ }
+ }
+
+ foreach (var word in SplitWords(l))
+ {
+ if (string.IsNullOrEmpty(word)) continue;
+
+ var textSprite = CreateSpriteText(textFlowContainer);
+
+ textSprite.Text = word;
+ sprites.Add(textSprite);
+ }
+
+ first = false;
+ }
+
+ return sprites;
+ }
+
+ protected string[] SplitWords(string text)
+ {
+ var words = new List();
+ var builder = new StringBuilder();
+
+ for (var i = 0; i < text.Length; i++)
+ {
+ if (i == 0
+ || char.IsSeparator(text[i - 1])
+ || char.IsControl(text[i - 1])
+ || char.GetUnicodeCategory(text[i - 1]) == UnicodeCategory.DashPunctuation
+ || text[i - 1] == '/'
+ || text[i - 1] == '\\'
+ || (isCjkCharacter(text[i - 1]) && !char.IsPunctuation(text[i])))
+ {
+ words.Add(builder.ToString());
+ builder.Clear();
+ }
+
+ builder.Append(text[i]);
+ }
+
+ if (builder.Length > 0)
+ words.Add(builder.ToString());
+
+ return words.ToArray();
+
+ static bool isCjkCharacter(char c) => c >= '\x2E80' && c <= '\x9FFF';
+ }
+
+ protected virtual TMsdfSpriteText CreateSpriteText(MsdfTextFlowContainer textFlowContainer)
+ {
+ var spriteText = creationFunc.Invoke();
+ textFlowContainer.ApplyDefaultCreationParameters(spriteText);
+ creationParameters?.Invoke(spriteText);
+ return spriteText;
+ }
+}
diff --git a/lib/Graphics/Containers/MsdfTextFlowContainer.cs b/lib/Graphics/Containers/MsdfTextFlowContainer.cs
new file mode 100644
index 0000000..2425043
--- /dev/null
+++ b/lib/Graphics/Containers/MsdfTextFlowContainer.cs
@@ -0,0 +1,503 @@
+using System.Buffers;
+using kajarlabs.osu.Framework.MsdfTextRendering.Graphics.Sprites;
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Caching;
+using osu.Framework.Extensions.EnumExtensions;
+using osu.Framework.Extensions.IEnumerableExtensions;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Localisation;
+using osu.Framework.Utils;
+using osuTK;
+
+namespace kajarlabs.osu.Framework.MsdfTextRendering.Graphics.Containers;
+
+public partial class MsdfTextFlowContainer : CompositeDrawable
+{
+ private readonly Action? defaultCreationParameters;
+
+ private readonly List parts = [];
+
+ private readonly Cached partsCache = new();
+
+ public float FirstLineIndent
+ {
+ get => Flow.FirstLineIndent;
+ set => Flow.FirstLineIndent = value;
+ }
+
+ public float ContentIndent
+ {
+ get => Flow.ContentIndent;
+ set => Flow.ContentIndent = value;
+ }
+
+ public float ParagraphSpacing
+ {
+ get => Flow.ParagraphSpacing;
+ set => Flow.ParagraphSpacing = value;
+ }
+
+ public float LineSpacing
+ {
+ get => Flow.LineSpacing;
+ set => Flow.LineSpacing = value;
+ }
+
+ public Anchor TextAnchor
+ {
+ get => Flow.TextAnchor;
+ set => Flow.TextAnchor = value;
+ }
+
+ public LocalisableString Text
+ {
+ set
+ {
+ Flow.Clear();
+ parts.Clear();
+
+ AddText(value);
+ }
+ }
+
+ public new Axes RelativeSizeAxes
+ {
+ get => base.RelativeSizeAxes;
+ set
+ {
+ base.RelativeSizeAxes = value;
+ setFlowSizing();
+ }
+ }
+
+ public new Axes AutoSizeAxes
+ {
+ get => base.AutoSizeAxes;
+ set
+ {
+ base.AutoSizeAxes = value;
+ setFlowSizing();
+ }
+ }
+
+ public override float Width
+ {
+ get => base.Width;
+ set
+ {
+ base.Width = value;
+ setFlowSizing();
+ }
+ }
+
+ private void setFlowSizing()
+ {
+ if (AutoSizeAxes.HasFlagFast(Axes.X))
+ {
+ Flow.RelativeSizeAxes = Axes.None;
+ Flow.AutoSizeAxes = Axes.Both;
+ }
+ else
+ {
+ Flow.AutoSizeAxes = Axes.Y;
+ Flow.RelativeSizeAxes = Axes.X;
+ }
+ }
+
+ public new MarginPadding Padding
+ {
+ get => base.Padding;
+ set => base.Padding = value;
+ }
+
+ public Vector2 Spacing
+ {
+ get => Flow.Spacing;
+ set => Flow.Spacing = value;
+ }
+
+ public Vector2 MaximumSize
+ {
+ get => Flow.MaximumSize;
+ set => Flow.MaximumSize = value;
+ }
+
+ public new bool Masking
+ {
+ get => base.Masking;
+ set => base.Masking = value;
+ }
+
+ public FillDirection Direction
+ {
+ get => Flow.Direction;
+ set => Flow.Direction = value;
+ }
+
+ public IEnumerable Children => Flow.Children;
+
+ [Resolved]
+ internal LocalisationManager? Localisation { get; private set; }
+
+ protected readonly MsdfInnerFlow Flow;
+ private readonly Bindable localisationParameters = new();
+
+ public MsdfTextFlowContainer(Action? defaultCreationParameters = null)
+ {
+ this.defaultCreationParameters = defaultCreationParameters;
+
+ InternalChild = Flow = CreateFlow().With(f => f.AutoSizeAxes = Axes.Both);
+ }
+
+ protected virtual MsdfInnerFlow CreateFlow() => new();
+
+ protected override void LoadAsyncComplete()
+ {
+ base.LoadAsyncComplete();
+
+ if (Localisation != null)
+ localisationParameters.Value = Localisation.CurrentParameters.Value;
+
+ RecreateAllParts();
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ if (Localisation != null)
+ {
+ localisationParameters.BindValueChanged(_ => partsCache.Invalidate());
+ ((IBindable)localisationParameters).BindTo(Localisation.CurrentParameters);
+ }
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ if (!partsCache.IsValid)
+ RecreateAllParts();
+ }
+
+ protected override int Compare(Drawable x, Drawable y)
+ {
+ if (TextAnchor.HasFlagFast(Anchor.x2))
+ return base.Compare(y, x);
+
+ return base.Compare(x, y);
+ }
+
+ public IMsdfTextPart AddText(LocalisableString text, Action? creationParameters = null)
+ where TMsdfSpriteText : MsdfSpriteText, new()
+ => AddPart(CreateChunkFor(text, true, () => new TMsdfSpriteText(), creationParameters));
+
+ public IMsdfTextPart AddText(LocalisableString text, Action? creationParameters = null)
+ => AddPart(CreateChunkFor(text, true, CreateSpriteText, creationParameters));
+
+ public void AddText(TMsdfSpriteText text, Action? creationParameters = null)
+ where TMsdfSpriteText : MsdfSpriteText
+ {
+ defaultCreationParameters?.Invoke(text);
+ creationParameters?.Invoke(text);
+ AddPart(new MsdfTextPartManual(text.Yield()));
+ }
+
+ public IMsdfTextPart AddParagraph(LocalisableString paragraph, Action? creationParameters = null)
+ where TMsdfSpriteText : MsdfSpriteText, new()
+ => AddPart(CreateChunkFor(paragraph, false, () => new TMsdfSpriteText(), creationParameters));
+
+ ///
+ public IMsdfTextPart AddParagraph(LocalisableString paragraph, Action? creationParameters = null)
+ => AddPart(CreateChunkFor(paragraph, false, CreateSpriteText, creationParameters));
+
+ protected internal virtual MsdfTextChunk CreateChunkFor(LocalisableString text, bool newLineIsParagraph, Func creationFunc, Action? creationParameters = null)
+ where TMsdfSpriteText : MsdfSpriteText, new()
+ => new(text, newLineIsParagraph, creationFunc, creationParameters);
+
+ public void NewLine() => AddPart(new MsdfTextNewLine(false));
+
+ public void NewParagraph() => AddPart(new MsdfTextNewLine(true));
+
+ protected internal virtual MsdfSpriteText CreateSpriteText() => new();
+
+ internal void ApplyDefaultCreationParameters(MsdfSpriteText spriteText) => defaultCreationParameters?.Invoke(spriteText);
+
+ public void Clear(bool disposeChildren = true)
+ {
+ Flow.Clear(disposeChildren);
+ parts.Clear();
+ }
+
+ protected internal IMsdfTextPart AddPart(IMsdfTextPart part)
+ {
+ parts.Add(part);
+
+ if (partsCache.IsValid)
+ recreatePart(part);
+
+ return part;
+ }
+
+ public bool RemovePart(IMsdfTextPart partToRemove)
+ {
+ if (!parts.Remove(partToRemove))
+ return false;
+
+ partsCache.Invalidate();
+ return true;
+ }
+
+ protected virtual void RecreateAllParts()
+ {
+ foreach (var manualPart in parts.OfType())
+ Flow.RemoveRange(manualPart.Drawables, false);
+
+ Flow.Clear(true);
+
+ foreach (var part in parts)
+ recreatePart(part);
+
+ partsCache.Validate();
+ }
+
+ private void recreatePart(IMsdfTextPart part)
+ {
+ part.RecreateDrawablesFor(this);
+ foreach (var drawable in part.Drawables)
+ Flow.Add(drawable);
+ }
+
+ protected partial class MsdfInnerFlow : FillFlowContainer
+ {
+ public float FirstLineIndent
+ {
+ get;
+ set
+ {
+ if (field == value) return;
+
+ field = value;
+
+ InvalidateLayout();
+ }
+ }
+
+ public float ContentIndent
+ {
+ get;
+ set
+ {
+ if (field == value) return;
+
+ field = value;
+
+ InvalidateLayout();
+ }
+ }
+
+ public float ParagraphSpacing
+ {
+ get;
+ set
+ {
+ if (field == value) return;
+
+ field = value;
+
+ InvalidateLayout();
+ }
+ } = 0.5f;
+
+ public float LineSpacing
+ {
+ get;
+ set
+ {
+ if (field == value) return;
+
+ field = value;
+
+ InvalidateLayout();
+ }
+ }
+
+ public Anchor TextAnchor
+ {
+ get;
+ set
+ {
+ if (field == value)
+ return;
+
+ field = value;
+
+ Anchor = value;
+ Origin = value;
+
+ InvalidateLayout();
+ }
+ } = Anchor.TopLeft;
+
+ protected override IEnumerable ComputeLayoutPositions()
+ {
+ var max = MaximumSize;
+
+ if (max == Vector2.Zero)
+ {
+ var s = ChildSize;
+
+ max.X = AutoSizeAxes.HasFlagFast(Axes.X) ? float.PositiveInfinity : s.X;
+ max.Y = AutoSizeAxes.HasFlagFast(Axes.Y) ? float.PositiveInfinity : s.Y;
+ }
+
+ var children = FlowingChildren.ToArray();
+ if (children.Length == 0)
+ yield break;
+
+ var layoutPositions = ArrayPool.Shared.Rent(children.Length);
+
+ var rowIndices = ArrayPool.Shared.Rent(children.Length);
+
+ var rowWidths = new List { 0 };
+ var lineBaseHeights = new List { 0 };
+
+ var rowHeight = 0.0f;
+ var current = Vector2.Zero;
+
+ var size = Vector2.Zero;
+
+ try
+ {
+ for (var i = 0; i < children.Length; ++i)
+ {
+ var c = children[i];
+
+ static Axes toAxes(FillDirection direction)
+ {
+ switch (direction)
+ {
+ case FillDirection.Full:
+ return Axes.Both;
+
+ case FillDirection.Horizontal:
+ return Axes.X;
+
+ case FillDirection.Vertical:
+ return Axes.Y;
+
+ default:
+ throw new ArgumentException($"{direction} is not defined");
+ }
+ }
+
+ if ((c.RelativeSizeAxes & AutoSizeAxes & toAxes(Direction)) != 0
+ && (c.FillMode != FillMode.Fit || c.RelativeSizeAxes != Axes.Both || c.Size.X > RelativeChildSize.X
+ || c.Size.Y > RelativeChildSize.Y || AutoSizeAxes == Axes.Both))
+ {
+ throw new InvalidOperationException(
+ "Drawables inside a fill flow container may not have a relative size axis that the fill flow container is filling in and auto sizing for. " +
+ $"The fill flow container is set to flow in the {Direction} direction and autosize in {AutoSizeAxes} axes and the child is set to relative size in {c.RelativeSizeAxes} axes.");
+ }
+
+ if (c.RelativeAnchorPosition != Vector2.Zero)
+ throw new InvalidOperationException($"All drawables in a {nameof(MsdfTextFlowContainer)} must not specify custom {nameof(RelativeAnchorPosition)}s. Only (0,0) is supported.");
+ if (c.RelativeOriginPosition != Vector2.Zero)
+ throw new InvalidOperationException($"All drawables in a {nameof(MsdfTextFlowContainer)} must not specify custom {nameof(RelativeOriginPosition)}s. Only (0,0) is supported.");
+
+ if (i == 0)
+ {
+ size = c.BoundingBox.Size;
+ current.X = ContentIndent + FirstLineIndent;
+ }
+
+ var rowWidth = current.X + size.X;
+
+ if (Direction != FillDirection.Horizontal && (Precision.DefinitelyBigger(rowWidth, max.X) || Direction == FillDirection.Vertical || c is NewLineContainer))
+ {
+ current.X = ContentIndent;
+ current.Y += rowHeight * (1 + LineSpacing);
+
+ if (c is NewLineContainer nlc)
+ current.Y += nlc.IndicatesNewParagraph ? rowHeight * ParagraphSpacing : 0;
+
+ layoutPositions[i] = current;
+
+ rowWidths.Add(current.X + size.X);
+ lineBaseHeights.Add((c as IHasLineBaseHeight)?.LineBaseHeight ?? 0);
+
+ rowHeight = 0;
+ }
+ else
+ {
+ layoutPositions[i] = current;
+
+ rowWidths[^1] = rowWidth;
+ lineBaseHeights[^1] = Math.Max(lineBaseHeights[^1], (c as IHasLineBaseHeight)?.LineBaseHeight ?? 0);
+ }
+
+ rowIndices[i] = rowWidths.Count - 1;
+ var stride = Vector2.Zero;
+
+ if (i < children.Length - 1)
+ {
+ stride = size;
+
+ c = children[i + 1];
+ size = c.BoundingBox.Size;
+ }
+
+ stride += Spacing;
+
+ if (stride.Y > rowHeight)
+ rowHeight = stride.Y;
+
+ current.X += stride.X;
+ }
+
+ if (!float.IsFinite(max.X))
+ {
+ var newMax = 0.0f;
+ foreach (var rowWidth in rowWidths)
+ newMax = MathF.Max(newMax, rowWidth);
+ max.X = newMax;
+ }
+
+ for (var i = 0; i < children.Length; i++)
+ {
+ var c = children[i];
+ var layoutPosition = layoutPositions[i];
+ var rowOffsetToEnd = max.X - rowWidths[rowIndices[i]];
+
+ if (TextAnchor.HasFlagFast(Anchor.x1))
+ layoutPosition.X += rowOffsetToEnd / 2;
+ else if (TextAnchor.HasFlagFast(Anchor.x2))
+ layoutPosition.X += rowOffsetToEnd;
+
+ if (c is IHasLineBaseHeight hasLineBaseHeight)
+ layoutPosition.Y += lineBaseHeights[rowIndices[i]] - hasLineBaseHeight.LineBaseHeight;
+
+ yield return layoutPosition;
+ }
+ }
+ finally
+ {
+ ArrayPool.Shared.Return(layoutPositions);
+ ArrayPool.Shared.Return(rowIndices);
+ }
+ }
+ }
+
+ public partial class NewLineContainer : Container
+ {
+ public readonly bool IndicatesNewParagraph;
+
+ public NewLineContainer(bool newParagraph)
+ {
+ IndicatesNewParagraph = newParagraph;
+ }
+ }
+}
diff --git a/lib/Graphics/Containers/MsdfTextNewLine.cs b/lib/Graphics/Containers/MsdfTextNewLine.cs
new file mode 100644
index 0000000..de4bbf8
--- /dev/null
+++ b/lib/Graphics/Containers/MsdfTextNewLine.cs
@@ -0,0 +1,20 @@
+using osu.Framework.Extensions.IEnumerableExtensions;
+using osu.Framework.Graphics;
+
+namespace kajarlabs.osu.Framework.MsdfTextRendering.Graphics.Containers;
+
+public class MsdfTextNewLine : MsdfTextPart
+{
+ private readonly bool indicatesNewParagraph;
+
+ public MsdfTextNewLine(bool indicatesNewParagraph)
+ {
+ this.indicatesNewParagraph = indicatesNewParagraph;
+ }
+
+ protected override IEnumerable CreateDrawablesFor(MsdfTextFlowContainer textFlowContainer)
+ {
+ var newLineContainer = new MsdfTextFlowContainer.NewLineContainer(indicatesNewParagraph);
+ return newLineContainer.Yield();
+ }
+}
diff --git a/lib/Graphics/Containers/MsdfTextPart.cs b/lib/Graphics/Containers/MsdfTextPart.cs
new file mode 100644
index 0000000..078f1d8
--- /dev/null
+++ b/lib/Graphics/Containers/MsdfTextPart.cs
@@ -0,0 +1,26 @@
+using osu.Framework.Graphics;
+
+namespace kajarlabs.osu.Framework.MsdfTextRendering.Graphics.Containers;
+
+public abstract class MsdfTextPart : IMsdfTextPart
+{
+ public IEnumerable Drawables { get; }
+
+ public event Action>? DrawablePartsRecreated;
+
+ private readonly List drawables = [];
+
+ protected MsdfTextPart()
+ {
+ Drawables = drawables.AsReadOnly();
+ }
+
+ public void RecreateDrawablesFor(MsdfTextFlowContainer textFlowContainer)
+ {
+ drawables.Clear();
+ drawables.AddRange(CreateDrawablesFor(textFlowContainer));
+ DrawablePartsRecreated?.Invoke(drawables);
+ }
+
+ protected abstract IEnumerable CreateDrawablesFor(MsdfTextFlowContainer textFlowContainer);
+}
diff --git a/lib/Graphics/Containers/MsdfTextPartManual.cs b/lib/Graphics/Containers/MsdfTextPartManual.cs
new file mode 100644
index 0000000..01aad96
--- /dev/null
+++ b/lib/Graphics/Containers/MsdfTextPartManual.cs
@@ -0,0 +1,24 @@
+using System.Collections.Immutable;
+using osu.Framework.Graphics;
+
+namespace kajarlabs.osu.Framework.MsdfTextRendering.Graphics.Containers;
+
+public class MsdfTextPartManual : IMsdfTextPart
+{
+ public IEnumerable Drawables { get; }
+
+ public event Action>? DrawablePartsRecreated
+ {
+ add { }
+ remove { }
+ }
+
+ public MsdfTextPartManual(IEnumerable drawables)
+ {
+ Drawables = drawables.ToImmutableArray();
+ }
+
+ public void RecreateDrawablesFor(MsdfTextFlowContainer textFlowContainer)
+ {
+ }
+}
diff --git a/tests/Resources/Typefaces/NotoSansJP/NotoSansJP-Regular.json b/tests/Resources/Typefaces/NotoSansJP/NotoSansJP-Regular.json
new file mode 100644
index 0000000..9928545
--- /dev/null
+++ b/tests/Resources/Typefaces/NotoSansJP/NotoSansJP-Regular.json
@@ -0,0 +1 @@
+{"atlas":{"type":"msdf","distanceRange":4,"distanceRangeMiddle":0,"size":48,"width":856,"height":856,"yOrigin":"top"},"metrics":{"emSize":1,"lineHeight":1.448,"ascender":-1.1599999999999999,"descender":0.28800000000000003,"underlineY":0.14999999999999999,"underlineThickness":0.050000000000000003},"glyphs":[{"unicode":12288,"advance":1},{"unicode":12289,"advance":1,"planeBounds":{"left":0.0090000000000000375,"top":-0.28125,"right":0.38400000000000001,"bottom":0.11458333333333333},"atlasBounds":{"left":186.5,"top":797.5,"right":204.5,"bottom":816.5}},{"unicode":12290,"advance":1,"planeBounds":{"left":-0.003416666666666659,"top":-0.30208333333333331,"right":0.39241666666666669,"bottom":0.11458333333333333},"atlasBounds":{"left":105.5,"top":797.5,"right":124.5,"bottom":817.5}},{"unicode":12291,"advance":1,"planeBounds":{"left":0.17708333333333331,"top":-0.67708333333333326,"right":0.82291666666666663,"bottom":-0.072916666666666671},"atlasBounds":{"left":407.5,"top":764.5,"right":438.5,"bottom":793.5}},{"unicode":12292,"advance":1,"planeBounds":{"left":-0.010416666666666703,"top":-0.88541666666666663,"right":1.0104166666666667,"bottom":0.13541666666666669},"atlasBounds":{"left":0.5,"top":96.5,"right":49.5,"bottom":145.5}},{"unicode":12293,"advance":1,"planeBounds":{"left":0.054333333333333296,"top":-0.84374999999999989,"right":0.8876666666666666,"bottom":0.072916666666666657},"atlasBounds":{"left":495.5,"top":338.5,"right":535.5,"bottom":382.5}},{"unicode":12294,"advance":1,"planeBounds":{"left":0.10624999999999998,"top":-0.82291666666666663,"right":0.91875000000000007,"bottom":0.11458333333333333},"atlasBounds":{"left":666.5,"top":244.5,"right":705.5,"bottom":289.5}},{"unicode":12295,"advance":1,"planeBounds":{"left":-5.3290705182007515e-18,"top":-0.88541666666666663,"right":1,"bottom":0.11458333333333333},"atlasBounds":{"left":492.5,"top":96.5,"right":540.5,"bottom":144.5}},{"unicode":12296,"advance":1,"planeBounds":{"left":0.53883333333333328,"top":-0.90624999999999989,"right":0.99716666666666665,"bottom":0.13541666666666669},"atlasBounds":{"left":407.5,"top":0.5,"right":429.5,"bottom":50.5}},{"unicode":12297,"advance":1,"planeBounds":{"left":0.0028333333333333483,"top":-0.90624999999999989,"right":0.46116666666666667,"bottom":0.13541666666666669},"atlasBounds":{"left":430.5,"top":0.5,"right":452.5,"bottom":50.5}},{"unicode":12298,"advance":1,"planeBounds":{"left":0.48558333333333331,"top":-0.90624999999999989,"right":1.0064166666666667,"bottom":0.13541666666666669},"atlasBounds":{"left":453.5,"top":0.5,"right":478.5,"bottom":50.5}},{"unicode":12299,"advance":1,"planeBounds":{"left":-0.0074166666666666556,"top":-0.90624999999999989,"right":0.51341666666666663,"bottom":0.13541666666666669},"atlasBounds":{"left":479.5,"top":0.5,"right":504.5,"bottom":50.5}},{"unicode":12300,"advance":1,"planeBounds":{"left":0.59966666666666668,"top":-0.90625,"right":1.0163333333333333,"bottom":-0.15625},"atlasBounds":{"left":70.5,"top":59.5,"right":90.5,"bottom":95.5}},{"unicode":12301,"advance":1,"planeBounds":{"left":-0.0163333333333333,"top":-0.61458333333333326,"right":0.40033333333333337,"bottom":0.13541666666666669},"atlasBounds":{"left":91.5,"top":59.5,"right":111.5,"bottom":95.5}},{"unicode":12302,"advance":1,"planeBounds":{"left":0.55333333333333323,"top":-0.90625,"right":1.0116666666666667,"bottom":-0.13541666666666666},"atlasBounds":{"left":633.5,"top":686.5,"right":655.5,"bottom":723.5}},{"unicode":12303,"advance":1,"planeBounds":{"left":-0.011666666666666631,"top":-0.63541666666666663,"right":0.44666666666666671,"bottom":0.13541666666666669},"atlasBounds":{"left":656.5,"top":686.5,"right":678.5,"bottom":723.5}},{"unicode":12304,"advance":1,"planeBounds":{"left":0.61808333333333332,"top":-0.90624999999999989,"right":1.0139166666666666,"bottom":0.13541666666666669},"atlasBounds":{"left":528.5,"top":0.5,"right":547.5,"bottom":50.5}},{"unicode":12305,"advance":1,"planeBounds":{"left":-0.013916666666666641,"top":-0.90624999999999989,"right":0.38191666666666668,"bottom":0.13541666666666669},"atlasBounds":{"left":548.5,"top":0.5,"right":567.5,"bottom":50.5}},{"unicode":12306,"advance":1,"planeBounds":{"left":0.11458333333333331,"top":-0.76041666666666663,"right":0.88541666666666663,"bottom":0.052083333333333336},"atlasBounds":{"left":818.5,"top":338.5,"right":855.5,"bottom":377.5}},{"unicode":12307,"advance":1,"planeBounds":{"left":0.052083333333333322,"top":-0.82291666666666663,"right":0.94791666666666663,"bottom":0.072916666666666657},"atlasBounds":{"left":812.5,"top":292.5,"right":855.5,"bottom":335.5}},{"unicode":12308,"advance":1,"planeBounds":{"left":0.66983333333333328,"top":-0.90624999999999989,"right":1.0031666666666665,"bottom":0.15625},"atlasBounds":{"left":185.5,"top":0.5,"right":201.5,"bottom":51.5}},{"unicode":12309,"advance":1,"planeBounds":{"left":-0.0031666666666666466,"top":-0.90624999999999989,"right":0.33016666666666672,"bottom":0.15625},"atlasBounds":{"left":202.5,"top":0.5,"right":218.5,"bottom":51.5}},{"unicode":12310,"advance":1,"planeBounds":{"left":0.57574999999999998,"top":-0.90624999999999989,"right":1.01325,"bottom":0.13541666666666669},"atlasBounds":{"left":568.5,"top":0.5,"right":589.5,"bottom":50.5}},{"unicode":12311,"advance":1,"planeBounds":{"left":-0.013249999999999977,"top":-0.90624999999999989,"right":0.42425000000000002,"bottom":0.13541666666666669},"atlasBounds":{"left":590.5,"top":0.5,"right":611.5,"bottom":50.5}},{"unicode":12312,"advance":1,"planeBounds":{"left":0.60966666666666669,"top":-0.92708333333333337,"right":1.0263333333333333,"bottom":0.15625},"atlasBounds":{"left":143.5,"top":0.5,"right":163.5,"bottom":52.5}},{"unicode":12313,"advance":1,"planeBounds":{"left":-0.026333333333333302,"top":-0.92708333333333337,"right":0.39033333333333337,"bottom":0.15625},"atlasBounds":{"left":164.5,"top":0.5,"right":184.5,"bottom":52.5}},{"unicode":12314,"advance":1,"planeBounds":{"left":0.64449999999999996,"top":-0.90624999999999989,"right":1.0195000000000001,"bottom":0.13541666666666669},"atlasBounds":{"left":612.5,"top":0.5,"right":630.5,"bottom":50.5}},{"unicode":12315,"advance":1,"planeBounds":{"left":-0.019499999999999986,"top":-0.90624999999999989,"right":0.35549999999999998,"bottom":0.13541666666666669},"atlasBounds":{"left":631.5,"top":0.5,"right":649.5,"bottom":50.5}},{"unicode":12316,"advance":1,"planeBounds":{"left":-3.552713678800501e-17,"top":-0.57291666666666663,"right":0.99999999999999989,"bottom":-0.19791666666666666},"atlasBounds":{"left":318.5,"top":797.5,"right":366.5,"bottom":815.5}},{"unicode":12317,"advance":1,"planeBounds":{"left":0.624,"top":-0.90625,"right":0.999,"bottom":-0.40625},"atlasBounds":{"left":782.5,"top":827.5,"right":800.5,"bottom":851.5}},{"unicode":12318,"advance":1,"planeBounds":{"left":0.0010000000000000302,"top":-0.90625,"right":0.376,"bottom":-0.40625},"atlasBounds":{"left":801.5,"top":827.5,"right":819.5,"bottom":851.5}},{"unicode":12319,"advance":1,"planeBounds":{"left":0.0010000000000000302,"top":-0.36458333333333326,"right":0.376,"bottom":0.13541666666666669},"atlasBounds":{"left":763.5,"top":827.5,"right":781.5,"bottom":851.5}},{"unicode":12320,"advance":1,"planeBounds":{"left":-0.010416666666666703,"top":-0.78125,"right":1.0104166666666667,"bottom":0.052083333333333336},"atlasBounds":{"left":72.5,"top":604.5,"right":121.5,"bottom":644.5}},{"unicode":12321,"advance":1,"planeBounds":{"left":0.41466666666666663,"top":-0.86458333333333337,"right":0.58133333333333326,"bottom":0.09375},"atlasBounds":{"left":93.5,"top":244.5,"right":101.5,"bottom":290.5}},{"unicode":12322,"advance":1,"planeBounds":{"left":0.28575,"top":-0.86458333333333337,"right":0.72325000000000006,"bottom":0.09375},"atlasBounds":{"left":102.5,"top":244.5,"right":123.5,"bottom":290.5}},{"unicode":12323,"advance":1,"planeBounds":{"left":0.18024999999999997,"top":-0.86458333333333326,"right":0.86775000000000002,"bottom":0.11458333333333333},"atlasBounds":{"left":178.5,"top":195.5,"right":211.5,"bottom":242.5}},{"unicode":12324,"advance":1,"planeBounds":{"left":0.066916666666666638,"top":-0.82291666666666663,"right":0.92108333333333325,"bottom":0.072916666666666657},"atlasBounds":{"left":490.5,"top":429.5,"right":531.5,"bottom":472.5}},{"unicode":12325,"advance":1,"planeBounds":{"left":0.20183333333333331,"top":-0.84374999999999989,"right":0.78516666666666668,"bottom":0.072916666666666657},"atlasBounds":{"left":588.5,"top":338.5,"right":616.5,"bottom":382.5}},{"unicode":12326,"advance":1,"planeBounds":{"left":0.016333333333333293,"top":-0.82291666666666663,"right":0.97466666666666668,"bottom":-0.40625},"atlasBounds":{"left":809.5,"top":686.5,"right":855.5,"bottom":706.5}},{"unicode":12327,"advance":1,"planeBounds":{"left":0.016833333333333308,"top":-0.82291666666666663,"right":0.97516666666666663,"bottom":-0.11458333333333334},"atlasBounds":{"left":749.5,"top":59.5,"right":795.5,"bottom":93.5}},{"unicode":12328,"advance":1,"planeBounds":{"left":0.027249999999999972,"top":-0.84375,"right":0.96474999999999989,"bottom":0.052083333333333336},"atlasBounds":{"left":532.5,"top":429.5,"right":577.5,"bottom":472.5}},{"unicode":12329,"advance":1,"planeBounds":{"left":0.03816666666666664,"top":-0.86458333333333337,"right":0.95483333333333331,"bottom":0.09375},"atlasBounds":{"left":124.5,"top":244.5,"right":168.5,"bottom":290.5}},{"unicode":12330,"advance":0,"planeBounds":{"left":-1.0449166666666667,"top":0.072916666666666685,"right":-0.77408333333333346,"bottom":0.36458333333333331},"atlasBounds":{"left":484.5,"top":797.5,"right":497.5,"bottom":811.5}},{"unicode":12331,"advance":0,"planeBounds":{"left":-1.0449166666666667,"top":-1.1145833333333333,"right":-0.77408333333333346,"bottom":-0.82291666666666663},"atlasBounds":{"left":456.5,"top":797.5,"right":469.5,"bottom":811.5}},{"unicode":12332,"advance":0,"planeBounds":{"left":-0.22591666666666668,"top":-1.1145833333333333,"right":0.04491666666666666,"bottom":-0.82291666666666663},"atlasBounds":{"left":416.5,"top":797.5,"right":429.5,"bottom":811.5}},{"unicode":12333,"advance":0,"planeBounds":{"left":-0.22591666666666668,"top":0.072916666666666685,"right":0.04491666666666666,"bottom":0.36458333333333331},"atlasBounds":{"left":470.5,"top":797.5,"right":483.5,"bottom":811.5}},{"unicode":12334,"advance":0.25,"planeBounds":{"left":0.010416666666666659,"top":-0.51041666666666663,"right":0.23958333333333331,"bottom":-0.26041666666666669},"atlasBounds":{"left":844.5,"top":59.5,"right":855.5,"bottom":71.5}},{"unicode":12335,"advance":0.25,"planeBounds":{"left":0.010416666666666659,"top":-0.61458333333333337,"right":0.23958333333333331,"bottom":-0.15625},"atlasBounds":{"left":56.5,"top":797.5,"right":67.5,"bottom":819.5}},{"unicode":12336,"advance":1,"planeBounds":{"left":-0.052083333333333259,"top":-0.57291666666666663,"right":1.0520833333333333,"bottom":-0.19791666666666666},"atlasBounds":{"left":264.5,"top":797.5,"right":317.5,"bottom":815.5}},{"unicode":12337,"advance":1,"planeBounds":{"left":0.14290151515151517,"top":-1.3854166666666665,"right":0.78873484848484854,"bottom":0.59375},"atlasBounds":{"left":0.5,"top":0.5,"right":31.5,"bottom":95.5}},{"unicode":12338,"advance":1,"planeBounds":{"left":0.13690151515151516,"top":-1.3854166666666665,"right":0.90773484848484853,"bottom":0.59375},"atlasBounds":{"left":32.5,"top":0.5,"right":69.5,"bottom":95.5}},{"unicode":12339,"advance":1,"planeBounds":{"left":0.13623484848484849,"top":-0.88541666666666652,"right":0.74040151515151498,"bottom":0.17708333333333334},"atlasBounds":{"left":219.5,"top":0.5,"right":248.5,"bottom":51.5}},{"unicode":12340,"advance":1,"planeBounds":{"left":0.13690151515151516,"top":-0.88541666666666652,"right":0.90773484848484853,"bottom":0.17708333333333334},"atlasBounds":{"left":249.5,"top":0.5,"right":286.5,"bottom":51.5}},{"unicode":12341,"advance":1,"planeBounds":{"left":0.14658333333333329,"top":-0.92708333333333337,"right":0.79241666666666666,"bottom":0.09375},"atlasBounds":{"left":50.5,"top":96.5,"right":81.5,"bottom":145.5}},{"unicode":12342,"advance":1,"planeBounds":{"left":-0.010416666666666703,"top":-0.88541666666666663,"right":1.0104166666666667,"bottom":0.13541666666666669},"atlasBounds":{"left":82.5,"top":96.5,"right":131.5,"bottom":145.5}},{"unicode":12343,"advance":1,"planeBounds":{"left":-0.012416666666666656,"top":-0.88541666666666663,"right":1.0084166666666667,"bottom":0.13541666666666669},"atlasBounds":{"left":132.5,"top":96.5,"right":181.5,"bottom":145.5}},{"unicode":12344,"advance":1,"planeBounds":{"left":0.019333333333333293,"top":-0.86458333333333326,"right":0.97766666666666668,"bottom":0.11458333333333333},"atlasBounds":{"left":212.5,"top":195.5,"right":258.5,"bottom":242.5}},{"unicode":12345,"advance":1,"planeBounds":{"left":0.019333333333333293,"top":-0.86458333333333326,"right":0.97766666666666668,"bottom":0.11458333333333333},"atlasBounds":{"left":259.5,"top":195.5,"right":305.5,"bottom":242.5}},{"unicode":12346,"advance":1,"planeBounds":{"left":0.019333333333333293,"top":-0.86458333333333326,"right":0.97766666666666668,"bottom":0.13541666666666669},"atlasBounds":{"left":647.5,"top":96.5,"right":693.5,"bottom":144.5}},{"unicode":12347,"advance":1,"planeBounds":{"left":0.1953333333333333,"top":-0.88541666666666663,"right":0.77866666666666662,"bottom":0.13541666666666669},"atlasBounds":{"left":182.5,"top":96.5,"right":210.5,"bottom":145.5}},{"unicode":12348,"advance":1,"planeBounds":{"left":0.062499999999999951,"top":-0.82291666666666663,"right":0.93749999999999989,"bottom":0.052083333333333336},"atlasBounds":{"left":104.5,"top":518.5,"right":146.5,"bottom":560.5}},{"unicode":12349,"advance":1,"planeBounds":{"left":0.035659090909090842,"top":-0.76041666666666663,"right":0.97315909090909081,"bottom":0.03125},"atlasBounds":{"left":221.5,"top":686.5,"right":266.5,"bottom":724.5}},{"unicode":12350,"advance":1,"planeBounds":{"left":-4.085620730620576e-17,"top":-0.88541666666666663,"right":0.99999999999999989,"bottom":0.11458333333333333},"atlasBounds":{"left":694.5,"top":96.5,"right":742.5,"bottom":144.5}},{"unicode":12351,"advance":1,"planeBounds":{"left":0.19791666666666663,"top":-0.82291666666666663,"right":0.80208333333333326,"bottom":0.072916666666666657},"atlasBounds":{"left":629.5,"top":429.5,"right":658.5,"bottom":472.5}},{"unicode":12353,"advance":1,"planeBounds":{"left":0.1300833333333333,"top":-0.71875,"right":0.9009166666666667,"bottom":0.09375},"atlasBounds":{"left":450.5,"top":645.5,"right":487.5,"bottom":684.5}},{"unicode":12354,"advance":1,"planeBounds":{"left":0.059083333333333321,"top":-0.84375,"right":0.95491666666666664,"bottom":0.09375},"atlasBounds":{"left":706.5,"top":244.5,"right":749.5,"bottom":289.5}},{"unicode":12355,"advance":1,"planeBounds":{"left":0.13308333333333328,"top":-0.61458333333333326,"right":0.9039166666666667,"bottom":0.072916666666666657},"atlasBounds":{"left":646.5,"top":726.5,"right":683.5,"bottom":759.5}},{"unicode":12356,"advance":1,"planeBounds":{"left":0.075083333333333308,"top":-0.76041666666666663,"right":0.97091666666666665,"bottom":0.052083333333333336},"atlasBounds":{"left":488.5,"top":645.5,"right":531.5,"bottom":684.5}},{"unicode":12357,"advance":1,"planeBounds":{"left":0.19549999999999998,"top":-0.69791666666666663,"right":0.82050000000000001,"bottom":0.11458333333333333},"atlasBounds":{"left":532.5,"top":645.5,"right":562.5,"bottom":684.5}},{"unicode":12358,"advance":1,"planeBounds":{"left":0.12091666666666664,"top":-0.84375,"right":0.8500833333333333,"bottom":0.09375},"atlasBounds":{"left":750.5,"top":244.5,"right":785.5,"bottom":289.5}},{"unicode":12359,"advance":1,"planeBounds":{"left":0.14049999999999996,"top":-0.69791666666666663,"right":0.89049999999999996,"bottom":0.09375},"atlasBounds":{"left":394.5,"top":686.5,"right":430.5,"bottom":724.5}},{"unicode":12360,"advance":1,"planeBounds":{"left":0.064083333333333325,"top":-0.84375,"right":0.95991666666666664,"bottom":0.09375},"atlasBounds":{"left":786.5,"top":244.5,"right":829.5,"bottom":289.5}},{"unicode":12361,"advance":1,"planeBounds":{"left":0.12174999999999996,"top":-0.67708333333333326,"right":0.93424999999999991,"bottom":0.11458333333333333},"atlasBounds":{"left":431.5,"top":686.5,"right":470.5,"bottom":724.5}},{"unicode":12362,"advance":1,"planeBounds":{"left":0.058749999999999948,"top":-0.84375,"right":0.99624999999999986,"bottom":0.09375},"atlasBounds":{"left":0.5,"top":292.5,"right":45.5,"bottom":337.5}},{"unicode":12363,"advance":1,"planeBounds":{"left":0.03191666666666667,"top":-0.84374999999999989,"right":1.0110833333333333,"bottom":0.072916666666666657},"atlasBounds":{"left":638.5,"top":338.5,"right":685.5,"bottom":382.5}},{"unicode":12364,"advance":1,"planeBounds":{"left":0.019,"top":-0.90625,"right":1.0190000000000001,"bottom":0.09375},"atlasBounds":{"left":743.5,"top":96.5,"right":791.5,"bottom":144.5}},{"unicode":12365,"advance":1,"planeBounds":{"left":0.11366666666666668,"top":-0.84375,"right":0.90533333333333332,"bottom":0.09375},"atlasBounds":{"left":46.5,"top":292.5,"right":84.5,"bottom":337.5}},{"unicode":12366,"advance":1,"planeBounds":{"left":0.076666666666666647,"top":-0.88541666666666663,"right":0.99333333333333329,"bottom":0.09375},"atlasBounds":{"left":306.5,"top":195.5,"right":350.5,"bottom":242.5}},{"unicode":12367,"advance":1,"planeBounds":{"left":0.15277419354838706,"top":-0.86458333333333326,"right":0.77777419354838706,"bottom":0.11458333333333333},"atlasBounds":{"left":351.5,"top":195.5,"right":381.5,"bottom":242.5}},{"unicode":12368,"advance":1,"planeBounds":{"left":0.14268333333333333,"top":-0.86458333333333326,"right":0.89268333333333327,"bottom":0.11458333333333333},"atlasBounds":{"left":382.5,"top":195.5,"right":418.5,"bottom":242.5}},{"unicode":12369,"advance":1,"planeBounds":{"left":0.072583333333333319,"top":-0.82291666666666663,"right":0.9684166666666667,"bottom":0.11458333333333333},"atlasBounds":{"left":85.5,"top":292.5,"right":128.5,"bottom":337.5}},{"unicode":12370,"advance":1,"planeBounds":{"left":0.06433333333333334,"top":-0.86458333333333326,"right":1.0226666666666666,"bottom":0.13541666666666669},"atlasBounds":{"left":792.5,"top":96.5,"right":838.5,"bottom":144.5}},{"unicode":12371,"advance":1,"planeBounds":{"left":0.12899999999999998,"top":-0.76041666666666663,"right":0.87899999999999989,"bottom":0.072916666666666657},"atlasBounds":{"left":431.5,"top":604.5,"right":467.5,"bottom":644.5}},{"unicode":12372,"advance":1,"planeBounds":{"left":0.10616666666666666,"top":-0.88541666666666663,"right":1.0228333333333333,"bottom":0.09375},"atlasBounds":{"left":419.5,"top":195.5,"right":463.5,"bottom":242.5}},{"unicode":12373,"advance":1,"planeBounds":{"left":0.11416666666666662,"top":-0.84375,"right":0.90583333333333327,"bottom":0.09375},"atlasBounds":{"left":153.5,"top":292.5,"right":191.5,"bottom":337.5}},{"unicode":12374,"advance":1,"planeBounds":{"left":0.09866666666666668,"top":-0.90625,"right":1.0153333333333332,"bottom":0.09375},"atlasBounds":{"left":0.5,"top":146.5,"right":44.5,"bottom":194.5}},{"unicode":12375,"advance":1,"planeBounds":{"left":0.19249999999999995,"top":-0.82291666666666663,"right":0.94249999999999989,"bottom":0.09375},"atlasBounds":{"left":781.5,"top":338.5,"right":817.5,"bottom":382.5}},{"unicode":12376,"advance":1,"planeBounds":{"left":0.17949999999999994,"top":-0.82291666666666663,"right":0.92949999999999988,"bottom":0.11458333333333333},"atlasBounds":{"left":192.5,"top":292.5,"right":228.5,"bottom":337.5}},{"unicode":12377,"advance":1,"planeBounds":{"left":0.054166666666666606,"top":-0.84375,"right":0.97083333333333333,"bottom":0.11458333333333333},"atlasBounds":{"left":169.5,"top":244.5,"right":213.5,"bottom":290.5}},{"unicode":12378,"advance":1,"planeBounds":{"left":0.020833333333333315,"top":-0.88541666666666663,"right":0.97916666666666663,"bottom":0.11458333333333333},"atlasBounds":{"left":45.5,"top":146.5,"right":91.5,"bottom":194.5}},{"unicode":12379,"advance":1,"planeBounds":{"left":-0.0060833333333333659,"top":-0.82291666666666663,"right":0.9730833333333333,"bottom":0.072916666666666657},"atlasBounds":{"left":0.5,"top":474.5,"right":47.5,"bottom":517.5}},{"unicode":12380,"advance":1,"planeBounds":{"left":-0.024333333333333335,"top":-0.84375,"right":1.0173333333333332,"bottom":0.09375},"atlasBounds":{"left":805.5,"top":146.5,"right":855.5,"bottom":191.5}},{"unicode":12381,"advance":1,"planeBounds":{"left":0.051999999999999956,"top":-0.82291666666666663,"right":0.92699999999999994,"bottom":0.09375},"atlasBounds":{"left":31.5,"top":384.5,"right":73.5,"bottom":428.5}},{"unicode":12382,"advance":1,"planeBounds":{"left":0.023250000000000007,"top":-0.82291666666666663,"right":0.96074999999999999,"bottom":0.09375},"atlasBounds":{"left":74.5,"top":384.5,"right":119.5,"bottom":428.5}},{"unicode":12383,"advance":1,"planeBounds":{"left":0.056583333333333312,"top":-0.84375,"right":0.95241666666666669,"bottom":0.09375},"atlasBounds":{"left":253.5,"top":292.5,"right":296.5,"bottom":337.5}},{"unicode":12384,"advance":1,"planeBounds":{"left":0.02091666666666667,"top":-0.84375,"right":1.0000833333333332,"bottom":0.09375},"atlasBounds":{"left":297.5,"top":292.5,"right":344.5,"bottom":337.5}},{"unicode":12385,"advance":1,"planeBounds":{"left":0.06433333333333334,"top":-0.84375,"right":0.89766666666666661,"bottom":0.09375},"atlasBounds":{"left":345.5,"top":292.5,"right":385.5,"bottom":337.5}},{"unicode":12386,"advance":1,"planeBounds":{"left":0.030916666666666637,"top":-0.90625,"right":1.0100833333333332,"bottom":0.09375},"atlasBounds":{"left":92.5,"top":146.5,"right":139.5,"bottom":194.5}},{"unicode":12387,"advance":1,"planeBounds":{"left":0.10966666666666668,"top":-0.55208333333333326,"right":0.90133333333333332,"bottom":0.072916666666666657},"atlasBounds":{"left":329.5,"top":764.5,"right":367.5,"bottom":794.5}},{"unicode":12388,"advance":1,"planeBounds":{"left":0.021749999999999985,"top":-0.69791666666666663,"right":0.95925000000000005,"bottom":0.03125},"atlasBounds":{"left":352.5,"top":59.5,"right":397.5,"bottom":94.5}},{"unicode":12389,"advance":1,"planeBounds":{"left":0.01541666666666662,"top":-0.88541666666666663,"right":0.99458333333333326,"bottom":0.052083333333333336},"atlasBounds":{"left":386.5,"top":292.5,"right":433.5,"bottom":337.5}},{"unicode":12390,"advance":1,"planeBounds":{"left":0.035583333333333335,"top":-0.78124999999999989,"right":0.93141666666666667,"bottom":0.072916666666666657},"atlasBounds":{"left":310.5,"top":561.5,"right":353.5,"bottom":602.5}},{"unicode":12391,"advance":1,"planeBounds":{"left":0.034749999999999948,"top":-0.78125,"right":0.97224999999999995,"bottom":0.09375},"atlasBounds":{"left":235.5,"top":518.5,"right":280.5,"bottom":560.5}},{"unicode":12392,"advance":1,"planeBounds":{"left":0.15641666666666665,"top":-0.82291666666666663,"right":0.88558333333333328,"bottom":0.072916666666666657},"atlasBounds":{"left":820.5,"top":429.5,"right":855.5,"bottom":472.5}},{"unicode":12393,"advance":1,"planeBounds":{"left":0.12508333333333332,"top":-0.86458333333333337,"right":1.0209166666666667,"bottom":0.09375},"atlasBounds":{"left":214.5,"top":244.5,"right":257.5,"bottom":290.5}},{"unicode":12394,"advance":1,"planeBounds":{"left":0.044249999999999963,"top":-0.84375,"right":0.9817499999999999,"bottom":0.09375},"atlasBounds":{"left":434.5,"top":292.5,"right":479.5,"bottom":337.5}},{"unicode":12395,"advance":1,"planeBounds":{"left":0.073999999999999969,"top":-0.80208333333333337,"right":0.94899999999999995,"bottom":0.09375},"atlasBounds":{"left":132.5,"top":474.5,"right":174.5,"bottom":517.5}},{"unicode":12396,"advance":1,"planeBounds":{"left":0.030916666666666672,"top":-0.84374999999999989,"right":1.0100833333333332,"bottom":0.072916666666666657},"atlasBounds":{"left":177.5,"top":384.5,"right":224.5,"bottom":428.5}},{"unicode":12397,"advance":1,"planeBounds":{"left":0.0035833333333333377,"top":-0.84375,"right":1.0244166666666668,"bottom":0.09375},"atlasBounds":{"left":480.5,"top":292.5,"right":529.5,"bottom":337.5}},{"unicode":12398,"advance":1,"planeBounds":{"left":0.039666666666666663,"top":-0.76041666666666663,"right":0.95633333333333326,"bottom":0.072916666666666657},"atlasBounds":{"left":545.5,"top":604.5,"right":589.5,"bottom":644.5}},{"unicode":12399,"advance":1,"planeBounds":{"left":0.063750000000000001,"top":-0.82291666666666663,"right":1.00125,"bottom":0.09375},"atlasBounds":{"left":225.5,"top":384.5,"right":270.5,"bottom":428.5}},{"unicode":12400,"advance":1,"planeBounds":{"left":0.041916666666666637,"top":-0.88541666666666663,"right":1.0210833333333333,"bottom":0.09375},"atlasBounds":{"left":464.5,"top":195.5,"right":511.5,"bottom":242.5}},{"unicode":12401,"advance":1,"planeBounds":{"left":0.043916666666666639,"top":-0.88541666666666663,"right":1.0230833333333333,"bottom":0.09375},"atlasBounds":{"left":512.5,"top":195.5,"right":559.5,"bottom":242.5}},{"unicode":12402,"advance":1,"planeBounds":{"left":0.058749999999999948,"top":-0.78125,"right":0.99624999999999986,"bottom":0.09375},"atlasBounds":{"left":422.5,"top":518.5,"right":467.5,"bottom":560.5}},{"unicode":12403,"advance":1,"planeBounds":{"left":0.042916666666666638,"top":-0.86458333333333326,"right":1.0220833333333332,"bottom":0.11458333333333333},"atlasBounds":{"left":560.5,"top":195.5,"right":607.5,"bottom":242.5}},{"unicode":12404,"advance":1,"planeBounds":{"left":0.045916666666666675,"top":-0.86458333333333326,"right":1.0250833333333333,"bottom":0.11458333333333333},"atlasBounds":{"left":608.5,"top":195.5,"right":655.5,"bottom":242.5}},{"unicode":12405,"advance":1,"planeBounds":{"left":-0.0084166666666667025,"top":-0.82291666666666663,"right":1.0124166666666667,"bottom":0.072916666666666657},"atlasBounds":{"left":175.5,"top":474.5,"right":224.5,"bottom":517.5}},{"unicode":12406,"advance":1,"planeBounds":{"left":-0.030833333333333365,"top":-0.82291666666666663,"right":1.0108333333333333,"bottom":0.09375},"atlasBounds":{"left":271.5,"top":384.5,"right":321.5,"bottom":428.5}},{"unicode":12407,"advance":1,"planeBounds":{"left":-0.03133333333333338,"top":-0.82291666666666663,"right":1.0103333333333333,"bottom":0.09375},"atlasBounds":{"left":322.5,"top":384.5,"right":372.5,"bottom":428.5}},{"unicode":12408,"advance":1,"planeBounds":{"left":0.013916666666666678,"top":-0.69791666666666663,"right":0.99308333333333332,"bottom":0.010416666666666666},"atlasBounds":{"left":796.5,"top":59.5,"right":843.5,"bottom":93.5}},{"unicode":12409,"advance":1,"planeBounds":{"left":0.0049166666666666768,"top":-0.78125,"right":0.98408333333333331,"bottom":0.03125},"atlasBounds":{"left":705.5,"top":645.5,"right":752.5,"bottom":684.5}},{"unicode":12410,"advance":1,"planeBounds":{"left":0.0049166666666666768,"top":-0.76041666666666663,"right":0.98408333333333331,"bottom":0.03125},"atlasBounds":{"left":267.5,"top":686.5,"right":314.5,"bottom":724.5}},{"unicode":12411,"advance":1,"planeBounds":{"left":0.072166666666666657,"top":-0.82291666666666663,"right":0.98883333333333323,"bottom":0.09375},"atlasBounds":{"left":373.5,"top":384.5,"right":417.5,"bottom":428.5}},{"unicode":12412,"advance":1,"planeBounds":{"left":0.043416666666666659,"top":-0.86458333333333337,"right":1.0225833333333332,"bottom":0.09375},"atlasBounds":{"left":258.5,"top":244.5,"right":305.5,"bottom":290.5}},{"unicode":12413,"advance":1,"planeBounds":{"left":0.038500000000000048,"top":-0.90625,"right":1.0385,"bottom":0.09375},"atlasBounds":{"left":175.5,"top":146.5,"right":223.5,"bottom":194.5}},{"unicode":12414,"advance":1,"planeBounds":{"left":0.13858333333333325,"top":-0.84375,"right":0.90941666666666665,"bottom":0.09375},"atlasBounds":{"left":530.5,"top":292.5,"right":567.5,"bottom":337.5}},{"unicode":12415,"advance":1,"planeBounds":{"left":0.020416666666666614,"top":-0.80208333333333326,"right":0.99958333333333327,"bottom":0.11458333333333333},"atlasBounds":{"left":418.5,"top":384.5,"right":465.5,"bottom":428.5}},{"unicode":12416,"advance":1,"planeBounds":{"left":0.048666666666666629,"top":-0.84375,"right":0.96533333333333327,"bottom":0.09375},"atlasBounds":{"left":568.5,"top":292.5,"right":612.5,"bottom":337.5}},{"unicode":12417,"advance":1,"planeBounds":{"left":0.037666666666666668,"top":-0.84375,"right":0.95433333333333326,"bottom":0.09375},"atlasBounds":{"left":613.5,"top":292.5,"right":657.5,"bottom":337.5}},{"unicode":12418,"advance":1,"planeBounds":{"left":0.044499999999999977,"top":-0.84375,"right":0.91949999999999998,"bottom":0.09375},"atlasBounds":{"left":658.5,"top":292.5,"right":700.5,"bottom":337.5}},{"unicode":12419,"advance":1,"planeBounds":{"left":0.070249999999999951,"top":-0.67708333333333326,"right":0.88274999999999992,"bottom":0.13541666666666669},"atlasBounds":{"left":0.5,"top":686.5,"right":39.5,"bottom":725.5}},{"unicode":12420,"advance":1,"planeBounds":{"left":0.017749999999999957,"top":-0.86458333333333337,"right":0.95524999999999993,"bottom":0.09375},"atlasBounds":{"left":306.5,"top":244.5,"right":351.5,"bottom":290.5}},{"unicode":12421,"advance":1,"planeBounds":{"left":0.151,"top":-0.67708333333333326,"right":0.90100000000000002,"bottom":0.13541666666666669},"atlasBounds":{"left":753.5,"top":645.5,"right":789.5,"bottom":684.5}},{"unicode":12422,"advance":1,"planeBounds":{"left":0.081999999999999976,"top":-0.84375,"right":0.95699999999999985,"bottom":0.11458333333333333},"atlasBounds":{"left":352.5,"top":244.5,"right":394.5,"bottom":290.5}},{"unicode":12423,"advance":1,"planeBounds":{"left":0.14774999999999999,"top":-0.67708333333333326,"right":0.83525000000000005,"bottom":0.11458333333333333},"atlasBounds":{"left":511.5,"top":686.5,"right":544.5,"bottom":724.5}},{"unicode":12424,"advance":1,"planeBounds":{"left":0.084249999999999992,"top":-0.84375,"right":0.89675000000000005,"bottom":0.09375},"atlasBounds":{"left":701.5,"top":292.5,"right":740.5,"bottom":337.5}},{"unicode":12425,"advance":1,"planeBounds":{"left":0.12958333333333333,"top":-0.84375,"right":0.90041666666666664,"bottom":0.09375},"atlasBounds":{"left":741.5,"top":292.5,"right":778.5,"bottom":337.5}},{"unicode":12426,"advance":1,"planeBounds":{"left":0.16866666666666663,"top":-0.84375,"right":0.83533333333333326,"bottom":0.09375},"atlasBounds":{"left":779.5,"top":292.5,"right":811.5,"bottom":337.5}},{"unicode":12427,"advance":1,"planeBounds":{"left":0.067333333333333301,"top":-0.80208333333333337,"right":0.90066666666666662,"bottom":0.09375},"atlasBounds":{"left":225.5,"top":474.5,"right":265.5,"bottom":517.5}},{"unicode":12428,"advance":1,"planeBounds":{"left":0.0035833333333332986,"top":-0.84375,"right":1.0244166666666668,"bottom":0.09375},"atlasBounds":{"left":0.5,"top":338.5,"right":49.5,"bottom":383.5}},{"unicode":12429,"advance":1,"planeBounds":{"left":0.063333333333333297,"top":-0.80208333333333337,"right":0.89666666666666661,"bottom":0.09375},"atlasBounds":{"left":286.5,"top":474.5,"right":326.5,"bottom":517.5}},{"unicode":12430,"advance":1,"planeBounds":{"left":0.10024999999999999,"top":-0.69791666666666663,"right":0.91275000000000006,"bottom":0.09375},"atlasBounds":{"left":141.5,"top":686.5,"right":180.5,"bottom":724.5}},{"unicode":12431,"advance":1,"planeBounds":{"left":0.012833333333333316,"top":-0.84375,"right":0.97116666666666662,"bottom":0.09375},"atlasBounds":{"left":50.5,"top":338.5,"right":96.5,"bottom":383.5}},{"unicode":12432,"advance":1,"planeBounds":{"left":0.041583333333333299,"top":-0.82291666666666663,"right":0.93741666666666668,"bottom":0.09375},"atlasBounds":{"left":466.5,"top":384.5,"right":509.5,"bottom":428.5}},{"unicode":12433,"advance":1,"planeBounds":{"left":0.015333333333333334,"top":-0.82291666666666663,"right":0.97366666666666668,"bottom":0.09375},"atlasBounds":{"left":510.5,"top":384.5,"right":556.5,"bottom":428.5}},{"unicode":12434,"advance":1,"planeBounds":{"left":0.050999999999999969,"top":-0.84375,"right":0.92599999999999993,"bottom":0.09375},"atlasBounds":{"left":97.5,"top":338.5,"right":139.5,"bottom":383.5}},{"unicode":12435,"advance":1,"planeBounds":{"left":0.032333333333333339,"top":-0.82291666666666663,"right":0.9906666666666667,"bottom":0.09375},"atlasBounds":{"left":557.5,"top":384.5,"right":603.5,"bottom":428.5}},{"unicode":12436,"advance":1,"planeBounds":{"left":0.088666666666666644,"top":-0.84375,"right":1.0053333333333332,"bottom":0.09375},"atlasBounds":{"left":140.5,"top":338.5,"right":184.5,"bottom":383.5}},{"unicode":12437,"advance":1,"planeBounds":{"left":0.1183333333333333,"top":-0.67708333333333326,"right":0.95166666666666666,"bottom":0.11458333333333333},"atlasBounds":{"left":315.5,"top":686.5,"right":355.5,"bottom":724.5}},{"unicode":12438,"advance":1,"planeBounds":{"left":0.14008333333333331,"top":-0.65624999999999989,"right":0.9109166666666666,"bottom":0.13541666666666669},"atlasBounds":{"left":356.5,"top":686.5,"right":393.5,"bottom":724.5}},{"unicode":12441,"advance":0,"planeBounds":{"left":-0.31016666666666665,"top":-0.92708333333333326,"right":0.023166666666666686,"bottom":-0.61458333333333326},"atlasBounds":{"left":839.5,"top":113.5,"right":855.5,"bottom":128.5}},{"unicode":12442,"advance":0,"planeBounds":{"left":-0.27775,"top":-0.92708333333333337,"right":0.034749999999999941,"bottom":-0.59375},"atlasBounds":{"left":832.5,"top":225.5,"right":847.5,"bottom":241.5}},{"unicode":12443,"advance":1,"planeBounds":{"left":-0.033999999999999968,"top":-0.88541666666666663,"right":0.34100000000000003,"bottom":-0.55208333333333326},"atlasBounds":{"left":825.5,"top":707.5,"right":843.5,"bottom":723.5}},{"unicode":12444,"advance":1,"planeBounds":{"left":-0.016249999999999973,"top":-0.86458333333333337,"right":0.29625000000000001,"bottom":-0.53125},"atlasBounds":{"left":809.5,"top":707.5,"right":824.5,"bottom":723.5}},{"unicode":12445,"advance":1,"planeBounds":{"left":0.27758333333333329,"top":-0.69791666666666663,"right":0.79841666666666666,"bottom":-0.010416666666666666},"atlasBounds":{"left":559.5,"top":726.5,"right":584.5,"bottom":759.5}},{"unicode":12446,"advance":1,"planeBounds":{"left":0.23299999999999996,"top":-0.80208333333333326,"right":0.85799999999999987,"bottom":0.010416666666666666},"atlasBounds":{"left":790.5,"top":645.5,"right":820.5,"bottom":684.5}},{"unicode":12447,"advance":1,"planeBounds":{"left":0.029499999999999978,"top":-0.88541666666666663,"right":0.90449999999999997,"bottom":0.11458333333333333},"atlasBounds":{"left":266.5,"top":146.5,"right":308.5,"bottom":194.5}},{"unicode":12448,"advance":1,"planeBounds":{"left":0.23958333333333331,"top":-0.53125,"right":0.76041666666666663,"bottom":-0.23958333333333331},"atlasBounds":{"left":430.5,"top":797.5,"right":455.5,"bottom":811.5}},{"unicode":12449,"advance":1,"planeBounds":{"left":0.12516666666666662,"top":-0.59374999999999989,"right":0.91683333333333328,"bottom":0.13541666666666669},"atlasBounds":{"left":398.5,"top":59.5,"right":436.5,"bottom":94.5}},{"unicode":12450,"advance":1,"planeBounds":{"left":0.079583333333333311,"top":-0.78125,"right":0.9754166666666666,"bottom":0.09375},"atlasBounds":{"left":614.5,"top":518.5,"right":657.5,"bottom":560.5}},{"unicode":12451,"advance":1,"planeBounds":{"left":0.077000000000000013,"top":-0.65624999999999989,"right":0.82700000000000007,"bottom":0.13541666666666669},"atlasBounds":{"left":596.5,"top":686.5,"right":632.5,"bottom":724.5}},{"unicode":12452,"advance":1,"planeBounds":{"left":0.036999999999999991,"top":-0.84374999999999989,"right":0.91200000000000003,"bottom":0.072916666666666657},"atlasBounds":{"left":629.5,"top":384.5,"right":671.5,"bottom":428.5}},{"unicode":12453,"advance":1,"planeBounds":{"left":0.14491666666666664,"top":-0.67708333333333326,"right":0.87408333333333332,"bottom":0.13541666666666669},"atlasBounds":{"left":600.5,"top":645.5,"right":635.5,"bottom":684.5}},{"unicode":12454,"advance":1,"planeBounds":{"left":0.092333333333333351,"top":-0.84375,"right":0.92566666666666664,"bottom":0.09375},"atlasBounds":{"left":185.5,"top":338.5,"right":225.5,"bottom":383.5}},{"unicode":12455,"advance":1,"planeBounds":{"left":0.10516666666666662,"top":-0.57291666666666663,"right":0.89683333333333326,"bottom":0.052083333333333336},"atlasBounds":{"left":368.5,"top":764.5,"right":406.5,"bottom":794.5}},{"unicode":12456,"advance":1,"planeBounds":{"left":0.041666666666666664,"top":-0.71874999999999989,"right":0.95833333333333326,"bottom":0.010416666666666666},"atlasBounds":{"left":437.5,"top":59.5,"right":481.5,"bottom":94.5}},{"unicode":12457,"advance":1,"planeBounds":{"left":0.13158333333333333,"top":-0.65625,"right":0.90241666666666664,"bottom":0.11458333333333333},"atlasBounds":{"left":74.5,"top":726.5,"right":111.5,"bottom":763.5}},{"unicode":12458,"advance":1,"planeBounds":{"left":0.044083333333333322,"top":-0.84374999999999989,"right":0.93991666666666662,"bottom":0.072916666666666657},"atlasBounds":{"left":672.5,"top":384.5,"right":715.5,"bottom":428.5}},{"unicode":12459,"advance":1,"planeBounds":{"left":0.06533333333333334,"top":-0.84374999999999989,"right":0.89866666666666661,"bottom":0.072916666666666657},"atlasBounds":{"left":716.5,"top":384.5,"right":756.5,"bottom":428.5}},{"unicode":12460,"advance":1,"planeBounds":{"left":0.038333333333333296,"top":-0.88541666666666663,"right":0.9966666666666667,"bottom":0.09375},"atlasBounds":{"left":696.5,"top":195.5,"right":742.5,"bottom":242.5}},{"unicode":12461,"advance":1,"planeBounds":{"left":0.064999999999999974,"top":-0.84375,"right":0.93999999999999995,"bottom":0.09375},"atlasBounds":{"left":226.5,"top":338.5,"right":268.5,"bottom":383.5}},{"unicode":12462,"advance":1,"planeBounds":{"left":0.037333333333333295,"top":-0.90625,"right":0.9956666666666667,"bottom":0.11458333333333333},"atlasBounds":{"left":211.5,"top":96.5,"right":257.5,"bottom":145.5}},{"unicode":12463,"advance":1,"planeBounds":{"left":0.047999999999999994,"top":-0.86458333333333337,"right":0.92300000000000004,"bottom":0.09375},"atlasBounds":{"left":395.5,"top":244.5,"right":437.5,"bottom":290.5}},{"unicode":12464,"advance":1,"planeBounds":{"left":0.0084999999999999763,"top":-0.88541666666666663,"right":1.0085,"bottom":0.11458333333333333},"atlasBounds":{"left":309.5,"top":146.5,"right":357.5,"bottom":194.5}},{"unicode":12465,"advance":1,"planeBounds":{"left":0.021749999999999953,"top":-0.84375,"right":0.95924999999999994,"bottom":0.09375},"atlasBounds":{"left":269.5,"top":338.5,"right":314.5,"bottom":383.5}},{"unicode":12466,"advance":1,"planeBounds":{"left":0.0029999999999999949,"top":-0.88541666666666663,"right":1.0030000000000001,"bottom":0.11458333333333333},"atlasBounds":{"left":358.5,"top":146.5,"right":406.5,"bottom":194.5}},{"unicode":12467,"advance":1,"planeBounds":{"left":0.10816666666666666,"top":-0.73958333333333326,"right":0.89983333333333326,"bottom":0.052083333333333336},"atlasBounds":{"left":80.5,"top":686.5,"right":118.5,"bottom":724.5}},{"unicode":12468,"advance":1,"planeBounds":{"left":0.09358333333333331,"top":-0.90625,"right":0.98941666666666661,"bottom":0.09375},"atlasBounds":{"left":407.5,"top":146.5,"right":450.5,"bottom":194.5}},{"unicode":12469,"advance":1,"planeBounds":{"left":0.015333333333333327,"top":-0.82291666666666663,"right":0.97366666666666668,"bottom":0.09375},"atlasBounds":{"left":782.5,"top":384.5,"right":828.5,"bottom":428.5}},{"unicode":12470,"advance":1,"planeBounds":{"left":0.0024999999999999432,"top":-0.84375,"right":1.0024999999999999,"bottom":0.11458333333333333},"atlasBounds":{"left":438.5,"top":244.5,"right":486.5,"bottom":290.5}},{"unicode":12471,"advance":1,"planeBounds":{"left":0.061583333333333309,"top":-0.82291666666666663,"right":0.95741666666666669,"bottom":0.072916666666666657},"atlasBounds":{"left":327.5,"top":474.5,"right":370.5,"bottom":517.5}},{"unicode":12472,"advance":1,"planeBounds":{"left":0.049249999999999974,"top":-0.84375,"right":0.9867499999999999,"bottom":0.09375},"atlasBounds":{"left":315.5,"top":338.5,"right":360.5,"bottom":383.5}},{"unicode":12473,"advance":1,"planeBounds":{"left":0.051583333333333301,"top":-0.76041666666666663,"right":0.94741666666666668,"bottom":0.072916666666666657},"atlasBounds":{"left":740.5,"top":561.5,"right":783.5,"bottom":601.5}},{"unicode":12474,"advance":1,"planeBounds":{"left":0.037833333333333316,"top":-0.90625,"right":0.99616666666666664,"bottom":0.09375},"atlasBounds":{"left":451.5,"top":146.5,"right":497.5,"bottom":194.5}},{"unicode":12475,"advance":1,"planeBounds":{"left":0.014666666666666628,"top":-0.82291666666666663,"right":0.93133333333333324,"bottom":0.072916666666666657},"atlasBounds":{"left":371.5,"top":474.5,"right":415.5,"bottom":517.5}},{"unicode":12476,"advance":1,"planeBounds":{"left":0.0014999999999999805,"top":-0.88541666666666663,"right":1.0015000000000001,"bottom":0.09375},"atlasBounds":{"left":768.5,"top":195.5,"right":816.5,"bottom":242.5}},{"unicode":12477,"advance":1,"planeBounds":{"left":0.080750000000000002,"top":-0.78124999999999989,"right":0.89324999999999999,"bottom":0.072916666666666657},"atlasBounds":{"left":554.5,"top":561.5,"right":593.5,"bottom":602.5}},{"unicode":12478,"advance":1,"planeBounds":{"left":0.058749999999999997,"top":-0.90625,"right":0.99624999999999997,"bottom":0.09375},"atlasBounds":{"left":498.5,"top":146.5,"right":543.5,"bottom":194.5}},{"unicode":12479,"advance":1,"planeBounds":{"left":0.044999999999999991,"top":-0.86458333333333337,"right":0.92000000000000004,"bottom":0.09375},"atlasBounds":{"left":487.5,"top":244.5,"right":529.5,"bottom":290.5}},{"unicode":12480,"advance":1,"planeBounds":{"left":0.0094999999999999373,"top":-0.90625,"right":1.0094999999999998,"bottom":0.11458333333333333},"atlasBounds":{"left":258.5,"top":96.5,"right":306.5,"bottom":145.5}},{"unicode":12481,"advance":1,"planeBounds":{"left":0.042166666666666609,"top":-0.82291666666666663,"right":0.95883333333333332,"bottom":0.09375},"atlasBounds":{"left":0.5,"top":429.5,"right":44.5,"bottom":473.5}},{"unicode":12482,"advance":1,"planeBounds":{"left":0.013916666666666673,"top":-0.80208333333333326,"right":0.99308333333333332,"bottom":0.11458333333333333},"atlasBounds":{"left":45.5,"top":429.5,"right":92.5,"bottom":473.5}},{"unicode":12483,"advance":1,"planeBounds":{"left":0.12558333333333335,"top":-0.63541666666666663,"right":0.89641666666666675,"bottom":0.13541666666666669},"atlasBounds":{"left":112.5,"top":726.5,"right":149.5,"bottom":763.5}},{"unicode":12484,"advance":1,"planeBounds":{"left":0.051083333333333279,"top":-0.80208333333333337,"right":0.94691666666666663,"bottom":0.09375},"atlasBounds":{"left":416.5,"top":474.5,"right":459.5,"bottom":517.5}},{"unicode":12485,"advance":1,"planeBounds":{"left":0.028916666666666636,"top":-0.90625,"right":1.0080833333333332,"bottom":0.11458333333333333},"atlasBounds":{"left":307.5,"top":96.5,"right":354.5,"bottom":145.5}},{"unicode":12486,"advance":1,"planeBounds":{"left":0.046666666666666662,"top":-0.80208333333333337,"right":0.96333333333333326,"bottom":0.09375},"atlasBounds":{"left":460.5,"top":474.5,"right":504.5,"bottom":517.5}},{"unicode":12487,"advance":1,"planeBounds":{"left":0.042416666666666658,"top":-0.90625,"right":1.0215833333333333,"bottom":0.11458333333333333},"atlasBounds":{"left":355.5,"top":96.5,"right":402.5,"bottom":145.5}},{"unicode":12488,"advance":1,"planeBounds":{"left":0.28591666666666665,"top":-0.82291666666666663,"right":0.89008333333333323,"bottom":0.072916666666666657},"atlasBounds":{"left":531.5,"top":474.5,"right":560.5,"bottom":517.5}},{"unicode":12489,"advance":1,"planeBounds":{"left":0.25066666666666665,"top":-0.82291666666666663,"right":0.91733333333333322,"bottom":0.09375},"atlasBounds":{"left":93.5,"top":429.5,"right":125.5,"bottom":473.5}},{"unicode":12490,"advance":1,"planeBounds":{"left":0.05116666666666661,"top":-0.82291666666666663,"right":0.96783333333333332,"bottom":0.09375},"atlasBounds":{"left":126.5,"top":429.5,"right":170.5,"bottom":473.5}},{"unicode":12491,"advance":1,"planeBounds":{"left":0.041583333333333299,"top":-0.69791666666666663,"right":0.93741666666666668,"bottom":-0.010416666666666666},"atlasBounds":{"left":456.5,"top":726.5,"right":499.5,"bottom":759.5}},{"unicode":12492,"advance":1,"planeBounds":{"left":0.082166666666666666,"top":-0.76041666666666663,"right":0.87383333333333324,"bottom":0.09375},"atlasBounds":{"left":366.5,"top":561.5,"right":404.5,"bottom":602.5}},{"unicode":12493,"advance":1,"planeBounds":{"left":0.033749999999999988,"top":-0.84375,"right":0.97125000000000006,"bottom":0.09375},"atlasBounds":{"left":361.5,"top":338.5,"right":406.5,"bottom":383.5}},{"unicode":12494,"advance":1,"planeBounds":{"left":0.095999999999999974,"top":-0.80208333333333326,"right":0.84599999999999986,"bottom":0.072916666666666657},"atlasBounds":{"left":46.5,"top":561.5,"right":82.5,"bottom":603.5}},{"unicode":12495,"advance":1,"planeBounds":{"left":0.030749999999999951,"top":-0.76041666666666663,"right":0.96824999999999994,"bottom":0.052083333333333336},"atlasBounds":{"left":636.5,"top":645.5,"right":681.5,"bottom":684.5}},{"unicode":12496,"advance":1,"planeBounds":{"left":0.021916666666666678,"top":-0.86458333333333326,"right":1.0010833333333333,"bottom":0.052083333333333336},"atlasBounds":{"left":171.5,"top":429.5,"right":218.5,"bottom":473.5}},{"unicode":12497,"advance":1,"planeBounds":{"left":0.012499999999999973,"top":-0.86458333333333326,"right":1.0125,"bottom":0.052083333333333336},"atlasBounds":{"left":219.5,"top":429.5,"right":267.5,"bottom":473.5}},{"unicode":12498,"advance":1,"planeBounds":{"left":0.17741666666666667,"top":-0.82291666666666663,"right":0.9065833333333333,"bottom":0.052083333333333336},"atlasBounds":{"left":785.5,"top":518.5,"right":820.5,"bottom":560.5}},{"unicode":12499,"advance":1,"planeBounds":{"left":0.13733333333333328,"top":-0.88541666666666663,"right":0.97066666666666668,"bottom":0.072916666666666657},"atlasBounds":{"left":530.5,"top":244.5,"right":570.5,"bottom":290.5}},{"unicode":12500,"advance":1,"planeBounds":{"left":0.13441666666666663,"top":-0.86458333333333326,"right":0.98858333333333326,"bottom":0.072916666666666657},"atlasBounds":{"left":407.5,"top":338.5,"right":448.5,"bottom":383.5}},{"unicode":12501,"advance":1,"planeBounds":{"left":0.096749999999999961,"top":-0.76041666666666663,"right":0.90924999999999989,"bottom":0.072916666666666657},"atlasBounds":{"left":640.5,"top":604.5,"right":679.5,"bottom":644.5}},{"unicode":12502,"advance":1,"planeBounds":{"left":0.079250000000000015,"top":-0.90625,"right":1.01675,"bottom":0.09375},"atlasBounds":{"left":544.5,"top":146.5,"right":589.5,"bottom":194.5}},{"unicode":12503,"advance":1,"planeBounds":{"left":0.088250000000000065,"top":-0.88541666666666663,"right":1.0257499999999999,"bottom":0.09375},"atlasBounds":{"left":0.5,"top":244.5,"right":45.5,"bottom":291.5}},{"unicode":12504,"advance":1,"planeBounds":{"left":0.015416666666666655,"top":-0.67708333333333326,"right":0.99458333333333326,"bottom":0.010416666666666666},"atlasBounds":{"left":408.5,"top":726.5,"right":455.5,"bottom":759.5}},{"unicode":12505,"advance":1,"planeBounds":{"left":0.0064166666666666556,"top":-0.78125,"right":0.98558333333333326,"bottom":0.03125},"atlasBounds":{"left":329.5,"top":645.5,"right":376.5,"bottom":684.5}},{"unicode":12506,"advance":1,"planeBounds":{"left":0.0064166666666666556,"top":-0.78125,"right":0.98558333333333326,"bottom":0.03125},"atlasBounds":{"left":377.5,"top":645.5,"right":424.5,"bottom":684.5}},{"unicode":12507,"advance":1,"planeBounds":{"left":0.038250000000000006,"top":-0.84374999999999989,"right":0.97575000000000001,"bottom":0.072916666666666657},"atlasBounds":{"left":292.5,"top":429.5,"right":337.5,"bottom":473.5}},{"unicode":12508,"advance":1,"planeBounds":{"left":0.016916666666666674,"top":-0.86458333333333337,"right":0.99608333333333332,"bottom":0.09375},"atlasBounds":{"left":571.5,"top":244.5,"right":618.5,"bottom":290.5}},{"unicode":12509,"advance":1,"planeBounds":{"left":0.015333333333333332,"top":-0.90625,"right":0.97366666666666668,"bottom":0.09375},"atlasBounds":{"left":590.5,"top":146.5,"right":636.5,"bottom":194.5}},{"unicode":12510,"advance":1,"planeBounds":{"left":0.05766666666666663,"top":-0.73958333333333337,"right":0.97433333333333327,"bottom":0.09375},"atlasBounds":{"left":468.5,"top":604.5,"right":512.5,"bottom":644.5}},{"unicode":12511,"advance":1,"planeBounds":{"left":0.10900000000000001,"top":-0.80208333333333326,"right":0.85899999999999999,"bottom":0.072916666666666657},"atlasBounds":{"left":354.5,"top":518.5,"right":390.5,"bottom":560.5}},{"unicode":12512,"advance":1,"planeBounds":{"left":0.024833333333333273,"top":-0.82291666666666663,"right":0.98316666666666663,"bottom":0.09375},"atlasBounds":{"left":338.5,"top":429.5,"right":384.5,"bottom":473.5}},{"unicode":12513,"advance":1,"planeBounds":{"left":0.066916666666666638,"top":-0.80208333333333326,"right":0.92108333333333325,"bottom":0.072916666666666657},"atlasBounds":{"left":281.5,"top":518.5,"right":322.5,"bottom":560.5}},{"unicode":12514,"advance":1,"planeBounds":{"left":0.063083333333333325,"top":-0.76041666666666663,"right":0.95891666666666664,"bottom":0.072916666666666657},"atlasBounds":{"left":812.5,"top":561.5,"right":855.5,"bottom":601.5}},{"unicode":12515,"advance":1,"planeBounds":{"left":0.10175000000000001,"top":-0.65624999999999989,"right":0.91425000000000001,"bottom":0.13541666666666669},"atlasBounds":{"left":471.5,"top":686.5,"right":510.5,"bottom":724.5}},{"unicode":12516,"advance":1,"planeBounds":{"left":0.021250000000000012,"top":-0.84375,"right":0.95874999999999999,"bottom":0.09375},"atlasBounds":{"left":449.5,"top":338.5,"right":494.5,"bottom":383.5}},{"unicode":12517,"advance":1,"planeBounds":{"left":0.10666666666666669,"top":-0.55208333333333326,"right":0.89833333333333332,"bottom":0.052083333333333336},"atlasBounds":{"left":573.5,"top":764.5,"right":611.5,"bottom":793.5}},{"unicode":12518,"advance":1,"planeBounds":{"left":0.033249999999999974,"top":-0.71875,"right":0.97074999999999989,"bottom":-0.010416666666666666},"atlasBounds":{"left":231.5,"top":726.5,"right":276.5,"bottom":760.5}},{"unicode":12519,"advance":1,"planeBounds":{"left":0.15916666666666662,"top":-0.59375,"right":0.82583333333333331,"bottom":0.11458333333333333},"atlasBounds":{"left":176.5,"top":726.5,"right":208.5,"bottom":760.5}},{"unicode":12520,"advance":1,"planeBounds":{"left":0.10658333333333332,"top":-0.76041666666666663,"right":0.87741666666666662,"bottom":0.072916666666666657},"atlasBounds":{"left":0.5,"top":604.5,"right":37.5,"bottom":644.5}},{"unicode":12521,"advance":1,"planeBounds":{"left":0.092833333333333337,"top":-0.80208333333333337,"right":0.92616666666666669,"bottom":0.09375},"atlasBounds":{"left":648.5,"top":474.5,"right":688.5,"bottom":517.5}},{"unicode":12522,"advance":1,"planeBounds":{"left":0.17508333333333329,"top":-0.80208333333333337,"right":0.82091666666666663,"bottom":0.09375},"atlasBounds":{"left":689.5,"top":474.5,"right":720.5,"bottom":517.5}},{"unicode":12523,"advance":1,"planeBounds":{"left":0.019416666666666658,"top":-0.80208333333333326,"right":0.99858333333333327,"bottom":0.072916666666666657},"atlasBounds":{"left":782.5,"top":474.5,"right":829.5,"bottom":516.5}},{"unicode":12524,"advance":1,"planeBounds":{"left":0.17908333333333329,"top":-0.80208333333333326,"right":0.94991666666666663,"bottom":0.072916666666666657},"atlasBounds":{"left":744.5,"top":474.5,"right":781.5,"bottom":516.5}},{"unicode":12525,"advance":1,"planeBounds":{"left":0.096250000000000016,"top":-0.73958333333333326,"right":0.90875000000000006,"bottom":0.052083333333333336},"atlasBounds":{"left":40.5,"top":686.5,"right":79.5,"bottom":724.5}},{"unicode":12526,"advance":1,"planeBounds":{"left":0.14241666666666664,"top":-0.59374999999999989,"right":0.87158333333333327,"bottom":0.13541666666666669},"atlasBounds":{"left":482.5,"top":59.5,"right":517.5,"bottom":94.5}},{"unicode":12527,"advance":1,"planeBounds":{"left":0.087333333333333305,"top":-0.76041666666666663,"right":0.92066666666666663,"bottom":0.09375},"atlasBounds":{"left":405.5,"top":561.5,"right":445.5,"bottom":602.5}},{"unicode":12528,"advance":1,"planeBounds":{"left":0.045666666666666668,"top":-0.82291666666666663,"right":0.96233333333333326,"bottom":0.09375},"atlasBounds":{"left":385.5,"top":429.5,"right":429.5,"bottom":473.5}},{"unicode":12529,"advance":1,"planeBounds":{"left":0.036250000000000004,"top":-0.73958333333333326,"right":0.97375,"bottom":0.010416666666666666},"atlasBounds":{"left":112.5,"top":59.5,"right":157.5,"bottom":95.5}},{"unicode":12530,"advance":1,"planeBounds":{"left":0.11475,"top":-0.76041666666666663,"right":0.92725000000000002,"bottom":0.09375},"atlasBounds":{"left":204.5,"top":561.5,"right":243.5,"bottom":602.5}},{"unicode":12531,"advance":1,"planeBounds":{"left":0.094499999999999959,"top":-0.78124999999999989,"right":0.96949999999999992,"bottom":0.072916666666666657},"atlasBounds":{"left":267.5,"top":561.5,"right":309.5,"bottom":602.5}},{"unicode":12532,"advance":1,"planeBounds":{"left":0.07166666666666667,"top":-0.90625,"right":0.98833333333333329,"bottom":0.09375},"atlasBounds":{"left":637.5,"top":146.5,"right":681.5,"bottom":194.5}},{"unicode":12533,"advance":1,"planeBounds":{"left":0.11791666666666668,"top":-0.65625,"right":0.8470833333333333,"bottom":0.11458333333333333},"atlasBounds":{"left":38.5,"top":726.5,"right":73.5,"bottom":763.5}},{"unicode":12534,"advance":1,"planeBounds":{"left":0.083249999999999991,"top":-0.65624999999999989,"right":0.89575000000000005,"bottom":0.13541666666666669},"atlasBounds":{"left":181.5,"top":686.5,"right":220.5,"bottom":724.5}},{"unicode":12535,"advance":1,"planeBounds":{"left":0.065666666666666651,"top":-0.90625,"right":0.98233333333333328,"bottom":0.11458333333333333},"atlasBounds":{"left":403.5,"top":96.5,"right":447.5,"bottom":145.5}},{"unicode":12536,"advance":1,"planeBounds":{"left":0.037333333333333336,"top":-0.88541666666666663,"right":0.9956666666666667,"bottom":0.09375},"atlasBounds":{"left":46.5,"top":244.5,"right":92.5,"bottom":291.5}},{"unicode":12537,"advance":1,"planeBounds":{"left":0.024333333333333294,"top":-0.90625,"right":0.98266666666666669,"bottom":0.052083333333333336},"atlasBounds":{"left":619.5,"top":244.5,"right":665.5,"bottom":290.5}},{"unicode":12538,"advance":1,"planeBounds":{"left":0.085083333333333344,"top":-0.90625,"right":0.98091666666666666,"bottom":0.11458333333333333},"atlasBounds":{"left":448.5,"top":96.5,"right":491.5,"bottom":145.5}},{"unicode":12539,"advance":1,"planeBounds":{"left":0.34375,"top":-0.53125,"right":0.65625,"bottom":-0.21875},"atlasBounds":{"left":839.5,"top":129.5,"right":854.5,"bottom":144.5}},{"unicode":12540,"advance":1,"planeBounds":{"left":0.051583333333333294,"top":-0.48958333333333331,"right":0.94741666666666668,"bottom":-0.28125},"atlasBounds":{"left":514.5,"top":797.5,"right":557.5,"bottom":807.5}},{"unicode":12541,"advance":1,"planeBounds":{"left":0.24766666666666665,"top":-0.63541666666666663,"right":0.78933333333333322,"bottom":-0.052083333333333329},"atlasBounds":{"left":40.5,"top":827.5,"right":66.5,"bottom":855.5}},{"unicode":12542,"advance":1,"planeBounds":{"left":0.22349999999999998,"top":-0.78124999999999989,"right":0.84850000000000003,"bottom":-0.052083333333333329},"atlasBounds":{"left":518.5,"top":59.5,"right":548.5,"bottom":94.5}},{"unicode":12543,"advance":1,"planeBounds":{"left":0.14924999999999999,"top":-0.82291666666666663,"right":0.83674999999999999,"bottom":0.09375},"atlasBounds":{"left":430.5,"top":429.5,"right":463.5,"bottom":473.5}},{"unicode":12784,"advance":1,"planeBounds":{"left":0.10549999999999998,"top":-0.69791666666666663,"right":0.85550000000000004,"bottom":0.11458333333333333},"atlasBounds":{"left":563.5,"top":645.5,"right":599.5,"bottom":684.5}},{"unicode":12785,"advance":1,"planeBounds":{"left":0.1330833333333333,"top":-0.67708333333333337,"right":0.9039166666666667,"bottom":0.09375},"atlasBounds":{"left":0.5,"top":726.5,"right":37.5,"bottom":763.5}},{"unicode":12786,"advance":1,"planeBounds":{"left":0.12199999999999997,"top":-0.61458333333333337,"right":0.87199999999999989,"bottom":0.09375},"atlasBounds":{"left":311.5,"top":726.5,"right":347.5,"bottom":760.5}},{"unicode":12787,"advance":1,"planeBounds":{"left":0.32058333333333333,"top":-0.65625,"right":0.8414166666666667,"bottom":0.11458333333333333},"atlasBounds":{"left":150.5,"top":726.5,"right":175.5,"bottom":763.5}},{"unicode":12788,"advance":1,"planeBounds":{"left":0.14016666666666666,"top":-0.61458333333333326,"right":0.80683333333333329,"bottom":0.11458333333333333},"atlasBounds":{"left":549.5,"top":59.5,"right":581.5,"bottom":94.5}},{"unicode":12789,"advance":1,"planeBounds":{"left":0.10966666666666668,"top":-0.61458333333333326,"right":0.90133333333333332,"bottom":0.072916666666666657},"atlasBounds":{"left":717.5,"top":726.5,"right":755.5,"bottom":759.5}},{"unicode":12790,"advance":1,"planeBounds":{"left":0.21599999999999994,"top":-0.67708333333333326,"right":0.84099999999999986,"bottom":0.072916666666666657},"atlasBounds":{"left":158.5,"top":59.5,"right":188.5,"bottom":95.5}},{"unicode":12791,"advance":1,"planeBounds":{"left":0.15974999999999995,"top":-0.63541666666666663,"right":0.84724999999999995,"bottom":0.072916666666666657},"atlasBounds":{"left":277.5,"top":726.5,"right":310.5,"bottom":760.5}},{"unicode":12792,"advance":1,"planeBounds":{"left":0.099749999999999978,"top":-0.55208333333333337,"right":0.91224999999999989,"bottom":0.03125},"atlasBounds":{"left":0.5,"top":827.5,"right":39.5,"bottom":855.5}},{"unicode":12793,"advance":1,"planeBounds":{"left":0.082749999999999962,"top":-0.69791666666666663,"right":0.89524999999999988,"bottom":0.072916666666666657},"atlasBounds":{"left":747.5,"top":686.5,"right":786.5,"bottom":723.5}},{"unicode":12794,"advance":1,"planeBounds":{"left":0.11975000000000001,"top":-0.65625,"right":0.93225000000000002,"bottom":0.11458333333333333},"atlasBounds":{"left":707.5,"top":686.5,"right":746.5,"bottom":723.5}},{"unicode":12795,"advance":1,"planeBounds":{"left":0.13483333333333328,"top":-0.63541666666666663,"right":0.84316666666666662,"bottom":0.11458333333333333},"atlasBounds":{"left":189.5,"top":59.5,"right":223.5,"bottom":95.5}},{"unicode":12796,"advance":1,"planeBounds":{"left":0.20774999999999996,"top":-0.65625,"right":0.77024999999999999,"bottom":0.11458333333333333},"atlasBounds":{"left":679.5,"top":686.5,"right":706.5,"bottom":723.5}},{"unicode":12797,"advance":1,"planeBounds":{"left":0.094333333333333297,"top":-0.65624999999999989,"right":0.92766666666666664,"bottom":0.072916666666666657},"atlasBounds":{"left":582.5,"top":59.5,"right":622.5,"bottom":94.5}},{"unicode":12798,"advance":1,"planeBounds":{"left":0.25766666666666665,"top":-0.63541666666666663,"right":0.92433333333333323,"bottom":0.09375},"atlasBounds":{"left":623.5,"top":59.5,"right":655.5,"bottom":94.5}},{"unicode":12799,"advance":1,"planeBounds":{"left":0.15725,"top":-0.59374999999999989,"right":0.84475,"bottom":0.072916666666666657},"atlasBounds":{"left":785.5,"top":726.5,"right":818.5,"bottom":758.5}},{"unicode":65281,"advance":1,"planeBounds":{"left":0.38541666666666669,"top":-0.80208333333333326,"right":0.61458333333333326,"bottom":0.052083333333333336},"atlasBounds":{"left":354.5,"top":561.5,"right":365.5,"bottom":602.5}},{"unicode":65282,"advance":1,"planeBounds":{"left":0.28125,"top":-0.92708333333333326,"right":0.71875,"bottom":-0.48958333333333331},"atlasBounds":{"left":68.5,"top":797.5,"right":89.5,"bottom":818.5}},{"unicode":65283,"advance":1,"planeBounds":{"left":0.11658333333333336,"top":-0.80208333333333326,"right":0.88741666666666674,"bottom":0.052083333333333336},"atlasBounds":{"left":144.5,"top":561.5,"right":181.5,"bottom":602.5}},{"unicode":65284,"advance":1,"planeBounds":{"left":0.18299999999999997,"top":-0.92708333333333326,"right":0.80800000000000005,"bottom":0.17708333333333334},"atlasBounds":{"left":104.5,"top":0.5,"right":134.5,"bottom":53.5}},{"unicode":65285,"advance":1,"planeBounds":{"left":0.031749999999999952,"top":-0.82291666666666663,"right":0.96924999999999994,"bottom":0.052083333333333336},"atlasBounds":{"left":0.5,"top":561.5,"right":45.5,"bottom":603.5}},{"unicode":65286,"advance":1,"planeBounds":{"left":0.14891666666666661,"top":-0.80208333333333326,"right":0.87808333333333333,"bottom":0.072916666666666657},"atlasBounds":{"left":749.5,"top":518.5,"right":784.5,"bottom":560.5}},{"unicode":65287,"advance":1,"planeBounds":{"left":0.39583333333333331,"top":-0.92708333333333326,"right":0.60416666666666663,"bottom":-0.48958333333333331},"atlasBounds":{"left":844.5,"top":72.5,"right":854.5,"bottom":93.5}},{"unicode":65288,"advance":1,"planeBounds":{"left":0.64741666666666664,"top":-0.90624999999999989,"right":1.0015833333333333,"bottom":0.15625},"atlasBounds":{"left":287.5,"top":0.5,"right":304.5,"bottom":51.5}},{"unicode":65289,"advance":1,"planeBounds":{"left":-0.001583333333333309,"top":-0.90624999999999989,"right":0.3525833333333333,"bottom":0.15625},"atlasBounds":{"left":305.5,"top":0.5,"right":322.5,"bottom":51.5}},{"unicode":65290,"advance":1,"planeBounds":{"left":0.10516666666666666,"top":-0.82291666666666663,"right":0.89683333333333326,"bottom":0.052083333333333336},"atlasBounds":{"left":65.5,"top":518.5,"right":103.5,"bottom":560.5}},{"unicode":65291,"advance":1,"planeBounds":{"left":0.09375,"top":-0.78125,"right":0.90625,"bottom":0.03125},"atlasBounds":{"left":258.5,"top":645.5,"right":297.5,"bottom":684.5}},{"unicode":65292,"advance":1,"planeBounds":{"left":0.086666666666666711,"top":-0.28125,"right":0.37833333333333335,"bottom":0.15625},"atlasBounds":{"left":90.5,"top":797.5,"right":104.5,"bottom":818.5}},{"unicode":65293,"advance":1,"planeBounds":{"left":0.09375,"top":-0.46875,"right":0.90625,"bottom":-0.28125},"atlasBounds":{"left":558.5,"top":797.5,"right":597.5,"bottom":806.5}},{"unicode":65294,"advance":1,"planeBounds":{"left":0.11400000000000003,"top":-0.21875,"right":0.36399999999999999,"bottom":0.052083333333333336},"atlasBounds":{"left":843.5,"top":827.5,"right":855.5,"bottom":840.5}},{"unicode":65295,"advance":1,"planeBounds":{"left":-0.010416666666666696,"top":-0.90624999999999989,"right":1.0104166666666667,"bottom":0.13541666666666669},"atlasBounds":{"left":673.5,"top":0.5,"right":722.5,"bottom":50.5}},{"unicode":65296,"advance":1,"planeBounds":{"left":0.17708333333333331,"top":-0.80208333333333326,"right":0.82291666666666663,"bottom":0.072916666666666657},"atlasBounds":{"left":563.5,"top":518.5,"right":594.5,"bottom":560.5}},{"unicode":65297,"advance":1,"planeBounds":{"left":0.19599999999999995,"top":-0.78125,"right":0.82099999999999995,"bottom":0.052083333333333336},"atlasBounds":{"left":227.5,"top":645.5,"right":257.5,"bottom":685.5}},{"unicode":65298,"advance":1,"planeBounds":{"left":0.18599999999999997,"top":-0.80208333333333326,"right":0.81100000000000005,"bottom":0.052083333333333336},"atlasBounds":{"left":523.5,"top":561.5,"right":553.5,"bottom":602.5}},{"unicode":65299,"advance":1,"planeBounds":{"left":0.17199999999999999,"top":-0.80208333333333326,"right":0.79700000000000004,"bottom":0.072916666666666657},"atlasBounds":{"left":532.5,"top":518.5,"right":562.5,"bottom":560.5}},{"unicode":65300,"advance":1,"planeBounds":{"left":0.17316666666666666,"top":-0.78125,"right":0.83983333333333332,"bottom":0.052083333333333336},"atlasBounds":{"left":735.5,"top":604.5,"right":767.5,"bottom":644.5}},{"unicode":65301,"advance":1,"planeBounds":{"left":0.17449999999999999,"top":-0.78124999999999989,"right":0.79949999999999999,"bottom":0.072916666666666657},"atlasBounds":{"left":492.5,"top":561.5,"right":522.5,"bottom":602.5}},{"unicode":65302,"advance":1,"planeBounds":{"left":0.18949999999999997,"top":-0.80208333333333326,"right":0.8145,"bottom":0.072916666666666657},"atlasBounds":{"left":468.5,"top":518.5,"right":498.5,"bottom":560.5}},{"unicode":65303,"advance":1,"planeBounds":{"left":0.18899999999999995,"top":-0.78125,"right":0.81399999999999995,"bottom":0.052083333333333336},"atlasBounds":{"left":680.5,"top":604.5,"right":710.5,"bottom":644.5}},{"unicode":65304,"advance":1,"planeBounds":{"left":0.18649999999999997,"top":-0.80208333333333326,"right":0.8115,"bottom":0.072916666666666657},"atlasBounds":{"left":391.5,"top":518.5,"right":421.5,"bottom":560.5}},{"unicode":65305,"advance":1,"planeBounds":{"left":0.18549999999999997,"top":-0.80208333333333326,"right":0.8105,"bottom":0.072916666666666657},"atlasBounds":{"left":323.5,"top":518.5,"right":353.5,"bottom":560.5}},{"unicode":65306,"advance":1,"planeBounds":{"left":0.375,"top":-0.73958333333333326,"right":0.625,"bottom":-0.010416666666666666},"atlasBounds":{"left":656.5,"top":59.5,"right":668.5,"bottom":94.5}},{"unicode":65307,"advance":1,"planeBounds":{"left":0.34816666666666668,"top":-0.73958333333333337,"right":0.63983333333333325,"bottom":0.15625},"atlasBounds":{"left":91.5,"top":474.5,"right":105.5,"bottom":517.5}},{"unicode":65308,"advance":1,"planeBounds":{"left":0.05699999999999996,"top":-0.82291666666666663,"right":0.93199999999999994,"bottom":0.072916666666666657},"atlasBounds":{"left":48.5,"top":474.5,"right":90.5,"bottom":517.5}},{"unicode":65309,"advance":1,"planeBounds":{"left":0.09375,"top":-0.57291666666666663,"right":0.90625,"bottom":-0.17708333333333331},"atlasBounds":{"left":205.5,"top":797.5,"right":244.5,"bottom":816.5}},{"unicode":65310,"advance":1,"planeBounds":{"left":0.067999999999999977,"top":-0.82291666666666663,"right":0.94299999999999995,"bottom":0.072916666666666657},"atlasBounds":{"left":777.5,"top":429.5,"right":819.5,"bottom":472.5}},{"unicode":65311,"advance":1,"planeBounds":{"left":0.20533333333333328,"top":-0.82291666666666663,"right":0.78866666666666663,"bottom":0.052083333333333336},"atlasBounds":{"left":0.5,"top":518.5,"right":28.5,"bottom":560.5}},{"unicode":65312,"advance":1,"planeBounds":{"left":0.031249999999999965,"top":-0.88541666666666663,"right":0.96874999999999989,"bottom":0.11458333333333333},"atlasBounds":{"left":46.5,"top":195.5,"right":91.5,"bottom":243.5}},{"unicode":65313,"advance":1,"planeBounds":{"left":0.10958333333333337,"top":-0.78125,"right":0.88041666666666674,"bottom":0.052083333333333336},"atlasBounds":{"left":393.5,"top":604.5,"right":430.5,"bottom":644.5}},{"unicode":65314,"advance":1,"planeBounds":{"left":0.19416666666666665,"top":-0.78125,"right":0.86083333333333323,"bottom":0.052083333333333336},"atlasBounds":{"left":360.5,"top":604.5,"right":392.5,"bottom":644.5}},{"unicode":65315,"advance":1,"planeBounds":{"left":0.1588333333333333,"top":-0.80208333333333326,"right":0.86716666666666664,"bottom":0.072916666666666657},"atlasBounds":{"left":147.5,"top":518.5,"right":181.5,"bottom":560.5}},{"unicode":65316,"advance":1,"planeBounds":{"left":0.17774999999999999,"top":-0.78125,"right":0.86524999999999996,"bottom":0.052083333333333336},"atlasBounds":{"left":294.5,"top":604.5,"right":327.5,"bottom":644.5}},{"unicode":65317,"advance":1,"planeBounds":{"left":0.23433333333333328,"top":-0.78125,"right":0.81766666666666665,"bottom":0.052083333333333336},"atlasBounds":{"left":230.5,"top":604.5,"right":258.5,"bottom":644.5}},{"unicode":65318,"advance":1,"planeBounds":{"left":0.24733333333333327,"top":-0.78125,"right":0.83066666666666666,"bottom":0.052083333333333336},"atlasBounds":{"left":156.5,"top":604.5,"right":184.5,"bottom":644.5}},{"unicode":65319,"advance":1,"planeBounds":{"left":0.12741666666666662,"top":-0.80208333333333326,"right":0.85658333333333325,"bottom":0.072916666666666657},"atlasBounds":{"left":29.5,"top":518.5,"right":64.5,"bottom":560.5}},{"unicode":65320,"advance":1,"planeBounds":{"left":0.15624999999999997,"top":-0.78125,"right":0.84375,"bottom":0.052083333333333336},"atlasBounds":{"left":38.5,"top":604.5,"right":71.5,"bottom":644.5}},{"unicode":65321,"advance":1,"planeBounds":{"left":0.19891666666666663,"top":-0.78125,"right":0.80308333333333326,"bottom":0.052083333333333336},"atlasBounds":{"left":671.5,"top":561.5,"right":700.5,"bottom":601.5}},{"unicode":65322,"advance":1,"planeBounds":{"left":0.19766666666666663,"top":-0.78124999999999989,"right":0.73933333333333329,"bottom":0.072916666666666657},"atlasBounds":{"left":117.5,"top":561.5,"right":143.5,"bottom":602.5}},{"unicode":65323,"advance":1,"planeBounds":{"left":0.1938333333333333,"top":-0.78125,"right":0.90216666666666667,"bottom":0.052083333333333336},"atlasBounds":{"left":259.5,"top":604.5,"right":293.5,"bottom":644.5}},{"unicode":65324,"advance":1,"planeBounds":{"left":0.25774999999999992,"top":-0.78125,"right":0.82024999999999992,"bottom":0.052083333333333336},"atlasBounds":{"left":784.5,"top":561.5,"right":811.5,"bottom":601.5}},{"unicode":65325,"advance":1,"planeBounds":{"left":0.10416666666666662,"top":-0.78125,"right":0.89583333333333326,"bottom":0.052083333333333336},"atlasBounds":{"left":701.5,"top":561.5,"right":739.5,"bottom":601.5}},{"unicode":65326,"advance":1,"planeBounds":{"left":0.15724999999999997,"top":-0.78125,"right":0.84475,"bottom":0.052083333333333336},"atlasBounds":{"left":122.5,"top":604.5,"right":155.5,"bottom":644.5}},{"unicode":65327,"advance":1,"planeBounds":{"left":0.09375,"top":-0.80208333333333326,"right":0.90625,"bottom":0.072916666666666657},"atlasBounds":{"left":684.5,"top":518.5,"right":723.5,"bottom":560.5}},{"unicode":65328,"advance":1,"planeBounds":{"left":0.20258333333333328,"top":-0.78125,"right":0.8484166666666666,"bottom":0.052083333333333336},"atlasBounds":{"left":513.5,"top":604.5,"right":544.5,"bottom":644.5}},{"unicode":65329,"advance":1,"planeBounds":{"left":0.094333333333333297,"top":-0.80208333333333326,"right":0.92766666666666664,"bottom":0.23958333333333334},"atlasBounds":{"left":723.5,"top":0.5,"right":763.5,"bottom":50.5}},{"unicode":65330,"advance":1,"planeBounds":{"left":0.20516666666666666,"top":-0.78125,"right":0.87183333333333324,"bottom":0.052083333333333336},"atlasBounds":{"left":194.5,"top":645.5,"right":226.5,"bottom":685.5}},{"unicode":65331,"advance":1,"planeBounds":{"left":0.16766666666666663,"top":-0.80208333333333326,"right":0.83433333333333326,"bottom":0.072916666666666657},"atlasBounds":{"left":499.5,"top":518.5,"right":531.5,"bottom":560.5}},{"unicode":65332,"advance":1,"planeBounds":{"left":0.14583333333333331,"top":-0.78125,"right":0.85416666666666663,"bottom":0.052083333333333336},"atlasBounds":{"left":123.5,"top":645.5,"right":157.5,"bottom":685.5}},{"unicode":65333,"advance":1,"planeBounds":{"left":0.15875,"top":-0.78124999999999989,"right":0.84625000000000006,"bottom":0.072916666666666657},"atlasBounds":{"left":83.5,"top":561.5,"right":116.5,"bottom":602.5}},{"unicode":65334,"advance":1,"planeBounds":{"left":0.12549999999999997,"top":-0.78125,"right":0.87549999999999994,"bottom":0.052083333333333336},"atlasBounds":{"left":86.5,"top":645.5,"right":122.5,"bottom":685.5}},{"unicode":65335,"advance":1,"planeBounds":{"left":-0.021833333333333364,"top":-0.78125,"right":1.0198333333333334,"bottom":0.052083333333333336},"atlasBounds":{"left":35.5,"top":645.5,"right":85.5,"bottom":685.5}},{"unicode":65336,"advance":1,"planeBounds":{"left":0.14633333333333329,"top":-0.78125,"right":0.85466666666666669,"bottom":0.052083333333333336},"atlasBounds":{"left":0.5,"top":645.5,"right":34.5,"bottom":685.5}},{"unicode":65337,"advance":1,"planeBounds":{"left":0.15624999999999994,"top":-0.78125,"right":0.84374999999999989,"bottom":0.052083333333333336},"atlasBounds":{"left":801.5,"top":604.5,"right":834.5,"bottom":644.5}},{"unicode":65338,"advance":1,"planeBounds":{"left":0.17116666666666666,"top":-0.78125,"right":0.83783333333333332,"bottom":0.052083333333333336},"atlasBounds":{"left":768.5,"top":604.5,"right":800.5,"bottom":644.5}},{"unicode":65339,"advance":1,"planeBounds":{"left":0.6619166666666666,"top":-0.90624999999999989,"right":1.0160833333333332,"bottom":0.13541666666666669},"atlasBounds":{"left":764.5,"top":0.5,"right":781.5,"bottom":50.5}},{"unicode":65340,"advance":1,"planeBounds":{"left":-0.010416666666666696,"top":-0.90624999999999989,"right":1.0104166666666667,"bottom":0.13541666666666669},"atlasBounds":{"left":782.5,"top":0.5,"right":831.5,"bottom":50.5}},{"unicode":65341,"advance":1,"planeBounds":{"left":-0.016083333333333293,"top":-0.90624999999999989,"right":0.3380833333333334,"bottom":0.13541666666666669},"atlasBounds":{"left":832.5,"top":0.5,"right":849.5,"bottom":50.5}},{"unicode":65342,"advance":1,"planeBounds":{"left":0.30066666666666669,"top":-0.98958333333333326,"right":0.71733333333333327,"bottom":-0.76041666666666663},"atlasBounds":{"left":835.5,"top":547.5,"right":855.5,"bottom":558.5}},{"unicode":65343,"advance":1,"planeBounds":{"left":-0.052083333333333259,"top":0.03125,"right":1.0520833333333333,"bottom":0.17708333333333334},"atlasBounds":{"left":643.5,"top":797.5,"right":696.5,"bottom":804.5}},{"unicode":65344,"advance":1,"planeBounds":{"left":0.29325000000000001,"top":-0.98958333333333326,"right":0.60575000000000001,"bottom":-0.76041666666666663},"atlasBounds":{"left":498.5,"top":797.5,"right":513.5,"bottom":808.5}},{"unicode":65345,"advance":1,"planeBounds":{"left":0.20633333333333329,"top":-0.61458333333333326,"right":0.78966666666666663,"bottom":0.072916666666666657},"atlasBounds":{"left":585.5,"top":726.5,"right":613.5,"bottom":759.5}},{"unicode":65346,"advance":1,"planeBounds":{"left":0.20699999999999999,"top":-0.84374999999999989,"right":0.83200000000000007,"bottom":0.072916666666666657},"atlasBounds":{"left":120.5,"top":384.5,"right":150.5,"bottom":428.5}},{"unicode":65347,"advance":1,"planeBounds":{"left":0.20841666666666664,"top":-0.61458333333333326,"right":0.81258333333333332,"bottom":0.072916666666666657},"atlasBounds":{"left":378.5,"top":726.5,"right":407.5,"bottom":759.5}},{"unicode":65348,"advance":1,"planeBounds":{"left":0.16749999999999998,"top":-0.84374999999999989,"right":0.79249999999999998,"bottom":0.072916666666666657},"atlasBounds":{"left":0.5,"top":384.5,"right":30.5,"bottom":428.5}},{"unicode":65349,"advance":1,"planeBounds":{"left":0.18058333333333329,"top":-0.61458333333333326,"right":0.82641666666666669,"bottom":0.072916666666666657},"atlasBounds":{"left":614.5,"top":726.5,"right":645.5,"bottom":759.5}},{"unicode":65350,"advance":1,"planeBounds":{"left":0.23299999999999998,"top":-0.86458333333333326,"right":0.85799999999999998,"bottom":0.052083333333333336},"atlasBounds":{"left":750.5,"top":338.5,"right":780.5,"bottom":382.5}},{"unicode":65351,"advance":1,"planeBounds":{"left":0.18366666666666664,"top":-0.61458333333333326,"right":0.85033333333333327,"bottom":0.30208333333333331},"atlasBounds":{"left":717.5,"top":338.5,"right":749.5,"bottom":382.5}},{"unicode":65352,"advance":1,"planeBounds":{"left":0.21333333333333329,"top":-0.84375,"right":0.79666666666666663,"bottom":0.052083333333333336},"atlasBounds":{"left":722.5,"top":429.5,"right":750.5,"bottom":472.5}},{"unicode":65353,"advance":1,"planeBounds":{"left":0.38541666666666663,"top":-0.84375,"right":0.61458333333333326,"bottom":0.052083333333333336},"atlasBounds":{"left":689.5,"top":429.5,"right":700.5,"bottom":472.5}},{"unicode":65354,"advance":1,"planeBounds":{"left":0.18049999999999997,"top":-0.84375,"right":0.68049999999999999,"bottom":0.30208333333333331},"atlasBounds":{"left":79.5,"top":0.5,"right":103.5,"bottom":55.5}},{"unicode":65355,"advance":1,"planeBounds":{"left":0.23891666666666664,"top":-0.84375,"right":0.8430833333333333,"bottom":0.052083333333333336},"atlasBounds":{"left":659.5,"top":429.5,"right":688.5,"bottom":472.5}},{"unicode":65356,"advance":1,"planeBounds":{"left":0.39466666666666672,"top":-0.84374999999999989,"right":0.81133333333333324,"bottom":0.072916666666666657},"atlasBounds":{"left":617.5,"top":338.5,"right":637.5,"bottom":382.5}},{"unicode":65357,"advance":1,"planeBounds":{"left":0.03425000000000001,"top":-0.61458333333333326,"right":0.97175,"bottom":0.052083333333333336},"atlasBounds":{"left":81.5,"top":764.5,"right":126.5,"bottom":796.5}},{"unicode":65358,"advance":1,"planeBounds":{"left":0.21333333333333329,"top":-0.61458333333333326,"right":0.79666666666666663,"bottom":0.052083333333333336},"atlasBounds":{"left":756.5,"top":726.5,"right":784.5,"bottom":758.5}},{"unicode":65359,"advance":1,"planeBounds":{"left":0.16666666666666663,"top":-0.61458333333333326,"right":0.83333333333333326,"bottom":0.072916666666666657},"atlasBounds":{"left":684.5,"top":726.5,"right":716.5,"bottom":759.5}},{"unicode":65360,"advance":1,"planeBounds":{"left":0.20649999999999999,"top":-0.61458333333333326,"right":0.83150000000000002,"bottom":0.28125},"atlasBounds":{"left":617.5,"top":474.5,"right":647.5,"bottom":517.5}},{"unicode":65361,"advance":1,"planeBounds":{"left":0.16799999999999998,"top":-0.61458333333333326,"right":0.79300000000000004,"bottom":0.28125},"atlasBounds":{"left":586.5,"top":474.5,"right":616.5,"bottom":517.5}},{"unicode":65362,"advance":1,"planeBounds":{"left":0.27716666666666662,"top":-0.61458333333333326,"right":0.8188333333333333,"bottom":0.052083333333333336},"atlasBounds":{"left":54.5,"top":764.5,"right":80.5,"bottom":796.5}},{"unicode":65363,"advance":1,"planeBounds":{"left":0.19641666666666666,"top":-0.61458333333333326,"right":0.80058333333333331,"bottom":0.072916666666666657},"atlasBounds":{"left":348.5,"top":726.5,"right":377.5,"bottom":759.5}},{"unicode":65364,"advance":1,"planeBounds":{"left":0.19549999999999998,"top":-0.73958333333333326,"right":0.82050000000000001,"bottom":0.072916666666666657},"atlasBounds":{"left":298.5,"top":645.5,"right":328.5,"bottom":684.5}},{"unicode":65365,"advance":1,"planeBounds":{"left":0.20433333333333328,"top":-0.59374999999999989,"right":0.78766666666666663,"bottom":0.072916666666666657},"atlasBounds":{"left":127.5,"top":764.5,"right":155.5,"bottom":796.5}},{"unicode":65366,"advance":1,"planeBounds":{"left":0.17708333333333331,"top":-0.59375,"right":0.82291666666666663,"bottom":0.052083333333333336},"atlasBounds":{"left":262.5,"top":764.5,"right":293.5,"bottom":795.5}},{"unicode":65367,"advance":1,"planeBounds":{"left":0.030249999999999971,"top":-0.59375,"right":0.96774999999999989,"bottom":0.052083333333333336},"atlasBounds":{"left":156.5,"top":764.5,"right":201.5,"bottom":795.5}},{"unicode":65368,"advance":1,"planeBounds":{"left":0.18749999999999997,"top":-0.59375,"right":0.8125,"bottom":0.052083333333333336},"atlasBounds":{"left":202.5,"top":764.5,"right":232.5,"bottom":795.5}},{"unicode":65369,"advance":1,"planeBounds":{"left":0.17708333333333329,"top":-0.59375,"right":0.82291666666666663,"bottom":0.28125},"atlasBounds":{"left":203.5,"top":518.5,"right":234.5,"bottom":560.5}},{"unicode":65370,"advance":1,"planeBounds":{"left":0.21033333333333329,"top":-0.59375,"right":0.79366666666666663,"bottom":0.052083333333333336},"atlasBounds":{"left":233.5,"top":764.5,"right":261.5,"bottom":795.5}},{"unicode":65371,"advance":1,"planeBounds":{"left":0.65691666666666659,"top":-0.90624999999999989,"right":1.0110833333333333,"bottom":0.15625},"atlasBounds":{"left":323.5,"top":0.5,"right":340.5,"bottom":51.5}},{"unicode":65372,"advance":1,"planeBounds":{"left":0.42708333333333331,"top":-0.92708333333333326,"right":0.57291666666666663,"bottom":0.17708333333333334},"atlasBounds":{"left":135.5,"top":0.5,"right":142.5,"bottom":53.5}},{"unicode":65373,"advance":1,"planeBounds":{"left":-0.011083333333333327,"top":-0.90624999999999989,"right":0.3430833333333333,"bottom":0.15625},"atlasBounds":{"left":341.5,"top":0.5,"right":358.5,"bottom":51.5}},{"unicode":65374,"advance":1,"planeBounds":{"left":-3.552713678800501e-17,"top":-0.57291666666666663,"right":0.99999999999999989,"bottom":-0.19791666666666666},"atlasBounds":{"left":367.5,"top":797.5,"right":415.5,"bottom":815.5}},{"unicode":65375,"advance":1,"planeBounds":{"left":0.52641666666666664,"top":-0.90624999999999989,"right":1.0055833333333333,"bottom":0.15625},"atlasBounds":{"left":359.5,"top":0.5,"right":382.5,"bottom":51.5}},{"unicode":65376,"advance":1,"planeBounds":{"left":-0.0055833333333333056,"top":-0.90624999999999989,"right":0.47358333333333336,"bottom":0.15625},"atlasBounds":{"left":383.5,"top":0.5,"right":406.5,"bottom":51.5}},{"unicode":65377,"advance":0.5,"planeBounds":{"left":-0.01141666666666666,"top":-0.30208333333333331,"right":0.38441666666666668,"bottom":0.11458333333333333},"atlasBounds":{"left":125.5,"top":797.5,"right":144.5,"bottom":817.5}},{"unicode":65378,"advance":0.5,"planeBounds":{"left":0.099666666666666723,"top":-0.90625,"right":0.51633333333333342,"bottom":-0.15625},"atlasBounds":{"left":224.5,"top":59.5,"right":244.5,"bottom":95.5}},{"unicode":65379,"advance":0.5,"planeBounds":{"left":-0.0163333333333333,"top":-0.61458333333333326,"right":0.40033333333333337,"bottom":0.13541666666666669},"atlasBounds":{"left":245.5,"top":59.5,"right":265.5,"bottom":95.5}},{"unicode":65380,"advance":0.5,"planeBounds":{"left":-0.017999999999999964,"top":-0.28125,"right":0.35699999999999998,"bottom":0.11458333333333333},"atlasBounds":{"left":245.5,"top":797.5,"right":263.5,"bottom":816.5}},{"unicode":65381,"advance":0.5,"planeBounds":{"left":0.11408333333333334,"top":-0.51041666666666663,"right":0.38491666666666668,"bottom":-0.23958333333333331},"atlasBounds":{"left":821.5,"top":547.5,"right":834.5,"bottom":560.5}},{"unicode":65382,"advance":0.5,"planeBounds":{"left":0.032333333333333367,"top":-0.76041666666666663,"right":0.4906666666666667,"bottom":0.09375},"atlasBounds":{"left":446.5,"top":561.5,"right":468.5,"bottom":602.5}},{"unicode":65383,"advance":0.5,"planeBounds":{"left":0.056166666666666684,"top":-0.61458333333333337,"right":0.47283333333333333,"bottom":0.09375},"atlasBounds":{"left":835.5,"top":604.5,"right":855.5,"bottom":638.5}},{"unicode":65384,"advance":0.5,"planeBounds":{"left":0.022583333333333344,"top":-0.65625,"right":0.41841666666666671,"bottom":0.09375},"atlasBounds":{"left":266.5,"top":59.5,"right":285.5,"bottom":95.5}},{"unicode":65385,"advance":0.5,"planeBounds":{"left":0.04766666666666669,"top":-0.65625,"right":0.46433333333333338,"bottom":0.09375},"atlasBounds":{"left":286.5,"top":59.5,"right":306.5,"bottom":95.5}},{"unicode":65386,"advance":0.5,"planeBounds":{"left":0.02675000000000002,"top":-0.55208333333333326,"right":0.46425,"bottom":0.052083333333333336},"atlasBounds":{"left":723.5,"top":764.5,"right":744.5,"bottom":793.5}},{"unicode":65387,"advance":0.5,"planeBounds":{"left":0.025750000000000023,"top":-0.65625,"right":0.46325,"bottom":0.09375},"atlasBounds":{"left":307.5,"top":59.5,"right":328.5,"bottom":95.5}},{"unicode":65388,"advance":0.5,"planeBounds":{"left":0.016333333333333363,"top":-0.65625,"right":0.47466666666666668,"bottom":0.09375},"atlasBounds":{"left":329.5,"top":59.5,"right":351.5,"bottom":95.5}},{"unicode":65389,"advance":0.5,"planeBounds":{"left":0.030750000000000031,"top":-0.55208333333333326,"right":0.46825,"bottom":0.052083333333333336},"atlasBounds":{"left":551.5,"top":764.5,"right":572.5,"bottom":793.5}},{"unicode":65390,"advance":0.5,"planeBounds":{"left":0.060500000000000026,"top":-0.57291666666666663,"right":0.4355,"bottom":0.09375},"atlasBounds":{"left":0.5,"top":764.5,"right":18.5,"bottom":796.5}},{"unicode":65391,"advance":0.5,"planeBounds":{"left":0.026250000000000013,"top":-0.59375,"right":0.46375,"bottom":0.11458333333333333},"atlasBounds":{"left":209.5,"top":726.5,"right":230.5,"bottom":760.5}},{"unicode":65392,"advance":0.5,"planeBounds":{"left":0.0045000000000000127,"top":-0.46875,"right":0.50450000000000006,"bottom":-0.26041666666666669},"atlasBounds":{"left":821.5,"top":674.5,"right":845.5,"bottom":684.5}},{"unicode":65393,"advance":0.5,"planeBounds":{"left":0.01649999999999998,"top":-0.76041666666666663,"right":0.51649999999999996,"bottom":0.09375},"atlasBounds":{"left":646.5,"top":561.5,"right":670.5,"bottom":602.5}},{"unicode":65394,"advance":0.5,"planeBounds":{"left":-0.016999999999999967,"top":-0.82291666666666663,"right":0.48299999999999998,"bottom":0.09375},"atlasBounds":{"left":563.5,"top":338.5,"right":587.5,"bottom":382.5}},{"unicode":65395,"advance":0.5,"planeBounds":{"left":0.016416666666666694,"top":-0.84375,"right":0.49558333333333332,"bottom":0.09375},"atlasBounds":{"left":129.5,"top":292.5,"right":152.5,"bottom":337.5}},{"unicode":65396,"advance":0.5,"planeBounds":{"left":-0.010916666666666642,"top":-0.71874999999999989,"right":0.50991666666666668,"bottom":0.010416666666666666},"atlasBounds":{"left":669.5,"top":59.5,"right":694.5,"bottom":94.5}},{"unicode":65397,"advance":0.5,"planeBounds":{"left":0.0050833333333333199,"top":-0.82291666666666663,"right":0.52591666666666659,"bottom":0.072916666666666657},"atlasBounds":{"left":751.5,"top":429.5,"right":776.5,"bottom":472.5}},{"unicode":65398,"advance":0.5,"planeBounds":{"left":-0.015499999999999984,"top":-0.82291666666666663,"right":0.48449999999999999,"bottom":0.072916666666666657},"atlasBounds":{"left":561.5,"top":474.5,"right":585.5,"bottom":517.5}},{"unicode":65399,"advance":0.5,"planeBounds":{"left":0.012916666666666677,"top":-0.82291666666666663,"right":0.49208333333333332,"bottom":0.09375},"atlasBounds":{"left":268.5,"top":429.5,"right":291.5,"bottom":473.5}},{"unicode":65400,"advance":0.5,"planeBounds":{"left":0.01091666666666671,"top":-0.84375,"right":0.49008333333333337,"bottom":0.09375},"atlasBounds":{"left":229.5,"top":292.5,"right":252.5,"bottom":337.5}},{"unicode":65401,"advance":0.5,"planeBounds":{"left":-0.019916666666666645,"top":-0.82291666666666663,"right":0.50091666666666668,"bottom":0.09375},"atlasBounds":{"left":464.5,"top":429.5,"right":489.5,"bottom":473.5}},{"unicode":65402,"advance":0.5,"planeBounds":{"left":0.030750000000000031,"top":-0.71875,"right":0.46825,"bottom":0.052083333333333336},"atlasBounds":{"left":787.5,"top":686.5,"right":808.5,"bottom":723.5}},{"unicode":65403,"advance":0.5,"planeBounds":{"left":-0.012916666666666646,"top":-0.80208333333333337,"right":0.50791666666666668,"bottom":0.09375},"atlasBounds":{"left":106.5,"top":474.5,"right":131.5,"bottom":517.5}},{"unicode":65404,"advance":0.5,"planeBounds":{"left":-0.0044166666666666269,"top":-0.82291666666666663,"right":0.51641666666666675,"bottom":0.072916666666666657},"atlasBounds":{"left":505.5,"top":474.5,"right":530.5,"bottom":517.5}},{"unicode":65405,"advance":0.5,"planeBounds":{"left":-0.005416666666666627,"top":-0.76041666666666663,"right":0.51541666666666675,"bottom":0.072916666666666657},"atlasBounds":{"left":590.5,"top":604.5,"right":615.5,"bottom":644.5}},{"unicode":65406,"advance":0.5,"planeBounds":{"left":-0.026416666666666665,"top":-0.82291666666666663,"right":0.49441666666666667,"bottom":0.052083333333333336},"atlasBounds":{"left":658.5,"top":518.5,"right":683.5,"bottom":560.5}},{"unicode":65407,"advance":0.5,"planeBounds":{"left":0.010916666666666677,"top":-0.76041666666666663,"right":0.49008333333333332,"bottom":0.072916666666666657},"atlasBounds":{"left":711.5,"top":604.5,"right":734.5,"bottom":644.5}},{"unicode":65408,"advance":0.5,"planeBounds":{"left":-0.012999999999999966,"top":-0.86458333333333326,"right":0.48699999999999999,"bottom":0.11458333333333333},"atlasBounds":{"left":743.5,"top":195.5,"right":767.5,"bottom":242.5}},{"unicode":65409,"advance":0.5,"planeBounds":{"left":0.0010000000000000391,"top":-0.82291666666666663,"right":0.501,"bottom":0.09375},"atlasBounds":{"left":757.5,"top":384.5,"right":781.5,"bottom":428.5}},{"unicode":65410,"advance":0.5,"planeBounds":{"left":-0.016416666666666621,"top":-0.78125,"right":0.50441666666666674,"bottom":0.09375},"atlasBounds":{"left":830.5,"top":474.5,"right":855.5,"bottom":516.5}},{"unicode":65411,"advance":0.5,"planeBounds":{"left":0.0010000000000000356,"top":-0.78125,"right":0.501,"bottom":0.09375},"atlasBounds":{"left":724.5,"top":518.5,"right":748.5,"bottom":560.5}},{"unicode":65412,"advance":0.5,"planeBounds":{"left":0.095500000000000029,"top":-0.80208333333333326,"right":0.47050000000000003,"bottom":0.072916666666666657},"atlasBounds":{"left":595.5,"top":518.5,"right":613.5,"bottom":560.5}},{"unicode":65413,"advance":0.5,"planeBounds":{"left":0.0020000000000000391,"top":-0.82291666666666663,"right":0.502,"bottom":0.09375},"atlasBounds":{"left":604.5,"top":384.5,"right":628.5,"bottom":428.5}},{"unicode":65414,"advance":0.5,"planeBounds":{"left":0.0010000000000000338,"top":-0.69791666666666663,"right":0.501,"bottom":-0.010416666666666666},"atlasBounds":{"left":534.5,"top":726.5,"right":558.5,"bottom":759.5}},{"unicode":65415,"advance":0.5,"planeBounds":{"left":0.0053333333333333661,"top":-0.76041666666666663,"right":0.46366666666666667,"bottom":0.09375},"atlasBounds":{"left":469.5,"top":561.5,"right":491.5,"bottom":602.5}},{"unicode":65416,"advance":0.5,"planeBounds":{"left":-0.0034166666666666946,"top":-0.82291666666666663,"right":0.51741666666666664,"bottom":0.09375},"atlasBounds":{"left":151.5,"top":384.5,"right":176.5,"bottom":428.5}},{"unicode":65417,"advance":0.5,"planeBounds":{"left":0.014250000000000009,"top":-0.78124999999999989,"right":0.45174999999999998,"bottom":0.072916666666666657},"atlasBounds":{"left":182.5,"top":561.5,"right":203.5,"bottom":602.5}},{"unicode":65418,"advance":0.5,"planeBounds":{"left":-0.037750000000000034,"top":-0.73958333333333326,"right":0.52474999999999994,"bottom":0.052083333333333336},"atlasBounds":{"left":545.5,"top":686.5,"right":572.5,"bottom":724.5}},{"unicode":65419,"advance":0.5,"planeBounds":{"left":0.046166666666666682,"top":-0.80208333333333326,"right":0.46283333333333332,"bottom":0.072916666666666657},"atlasBounds":{"left":182.5,"top":518.5,"right":202.5,"bottom":560.5}},{"unicode":65420,"advance":0.5,"planeBounds":{"left":0.031833333333333352,"top":-0.71875,"right":0.49016666666666669,"bottom":0.09375},"atlasBounds":{"left":682.5,"top":645.5,"right":704.5,"bottom":684.5}},{"unicode":65421,"advance":0.5,"planeBounds":{"left":-0.034750000000000038,"top":-0.69791666666666663,"right":0.52774999999999994,"bottom":0.03125},"atlasBounds":{"left":695.5,"top":59.5,"right":722.5,"bottom":94.5}},{"unicode":65422,"advance":0.5,"planeBounds":{"left":-0.020333333333333301,"top":-0.80208333333333326,"right":0.52133333333333332,"bottom":0.072916666666666657},"atlasBounds":{"left":829.5,"top":384.5,"right":855.5,"bottom":426.5}},{"unicode":65423,"advance":0.5,"planeBounds":{"left":-0.00091666666666671403,"top":-0.71875,"right":0.51991666666666669,"bottom":0.09375},"atlasBounds":{"left":830.5,"top":244.5,"right":855.5,"bottom":283.5}},{"unicode":65424,"advance":0.5,"planeBounds":{"left":0.037166666666666688,"top":-0.80208333333333337,"right":0.45383333333333331,"bottom":0.09375},"atlasBounds":{"left":701.5,"top":429.5,"right":721.5,"bottom":472.5}},{"unicode":65425,"advance":0.5,"planeBounds":{"left":-0.021333333333333371,"top":-0.80208333333333337,"right":0.52033333333333331,"bottom":0.09375},"atlasBounds":{"left":602.5,"top":429.5,"right":628.5,"bottom":472.5}},{"unicode":65426,"advance":0.5,"planeBounds":{"left":-8.3333333333289515e-05,"top":-0.80208333333333337,"right":0.47908333333333336,"bottom":0.09375},"atlasBounds":{"left":578.5,"top":429.5,"right":601.5,"bottom":472.5}},{"unicode":65427,"advance":0.5,"planeBounds":{"left":3.7303493627405262e-17,"top":-0.73958333333333326,"right":0.5,"bottom":0.072916666666666657},"atlasBounds":{"left":425.5,"top":645.5,"right":449.5,"bottom":684.5}},{"unicode":65428,"advance":0.5,"planeBounds":{"left":-0.023833333333333321,"top":-0.82291666666666663,"right":0.51783333333333326,"bottom":0.09375},"atlasBounds":{"left":536.5,"top":338.5,"right":562.5,"bottom":382.5}},{"unicode":65429,"advance":0.5,"planeBounds":{"left":-0.010416666666666656,"top":-0.71874999999999989,"right":0.51041666666666674,"bottom":0.010416666666666666},"atlasBounds":{"left":723.5,"top":59.5,"right":748.5,"bottom":94.5}},{"unicode":65430,"advance":0.5,"planeBounds":{"left":0.035750000000000032,"top":-0.73958333333333326,"right":0.47325,"bottom":0.052083333333333336},"atlasBounds":{"left":119.5,"top":686.5,"right":140.5,"bottom":724.5}},{"unicode":65431,"advance":0.5,"planeBounds":{"left":0.024333333333333373,"top":-0.78125,"right":0.48266666666666669,"bottom":0.09375},"atlasBounds":{"left":721.5,"top":474.5,"right":743.5,"bottom":516.5}},{"unicode":65432,"advance":0.5,"planeBounds":{"left":0.046083333333333351,"top":-0.80208333333333337,"right":0.44191666666666668,"bottom":0.09375},"atlasBounds":{"left":266.5,"top":474.5,"right":285.5,"bottom":517.5}},{"unicode":65433,"advance":0.5,"planeBounds":{"left":-0.031250000000000049,"top":-0.78124999999999989,"right":0.53124999999999989,"bottom":0.072916666666666657},"atlasBounds":{"left":618.5,"top":561.5,"right":645.5,"bottom":602.5}},{"unicode":65434,"advance":0.5,"planeBounds":{"left":0.042333333333333362,"top":-0.78124999999999989,"right":0.5006666666666667,"bottom":0.072916666666666657},"atlasBounds":{"left":244.5,"top":561.5,"right":266.5,"bottom":602.5}},{"unicode":65435,"advance":0.5,"planeBounds":{"left":0.023833333333333349,"top":-0.73958333333333326,"right":0.48216666666666669,"bottom":0.052083333333333336},"atlasBounds":{"left":573.5,"top":686.5,"right":595.5,"bottom":724.5}},{"unicode":65436,"advance":0.5,"planeBounds":{"left":0.018416666666666685,"top":-0.73958333333333337,"right":0.49758333333333332,"bottom":0.09375},"atlasBounds":{"left":616.5,"top":604.5,"right":639.5,"bottom":644.5}},{"unicode":65437,"advance":0.5,"planeBounds":{"left":0.017916666666666674,"top":-0.78124999999999989,"right":0.49708333333333332,"bottom":0.072916666666666657},"atlasBounds":{"left":594.5,"top":561.5,"right":617.5,"bottom":602.5}},{"unicode":65438,"advance":0.5,"planeBounds":{"left":-0.02566666666666665,"top":-0.90625,"right":0.3076666666666667,"bottom":-0.57291666666666663},"atlasBounds":{"left":839.5,"top":96.5,"right":855.5,"bottom":112.5}},{"unicode":65439,"advance":0.5,"planeBounds":{"left":-0.022333333333333309,"top":-0.90625,"right":0.26933333333333337,"bottom":-0.55208333333333326},"atlasBounds":{"left":817.5,"top":225.5,"right":831.5,"bottom":242.5}},{"unicode":65441,"advance":0.92000000000000004,"planeBounds":{"left":0.13708333333333328,"top":-0.65625,"right":0.78291666666666659,"bottom":-0.09375},"atlasBounds":{"left":617.5,"top":827.5,"right":648.5,"bottom":854.5}},{"unicode":65442,"advance":0.92000000000000004,"planeBounds":{"left":0.089583333333333362,"top":-0.65625,"right":0.86041666666666672,"bottom":-0.09375},"atlasBounds":{"left":579.5,"top":827.5,"right":616.5,"bottom":854.5}},{"unicode":65443,"advance":0.92000000000000004,"planeBounds":{"left":0.090666666666666687,"top":-0.67708333333333326,"right":0.8823333333333333,"bottom":-0.072916666666666671},"atlasBounds":{"left":817.5,"top":195.5,"right":855.5,"bottom":224.5}},{"unicode":65444,"advance":0.92000000000000004,"planeBounds":{"left":0.13716666666666666,"top":-0.65625,"right":0.80383333333333329,"bottom":-0.09375},"atlasBounds":{"left":546.5,"top":827.5,"right":578.5,"bottom":854.5}},{"unicode":65445,"advance":0.92000000000000004,"planeBounds":{"left":0.10749999999999998,"top":-0.65625,"right":0.85750000000000004,"bottom":-0.072916666666666671},"atlasBounds":{"left":141.5,"top":827.5,"right":177.5,"bottom":855.5}},{"unicode":65446,"advance":0.92000000000000004,"planeBounds":{"left":0.11383333333333333,"top":-0.67708333333333326,"right":0.8221666666666666,"bottom":-0.052083333333333329},"atlasBounds":{"left":294.5,"top":764.5,"right":328.5,"bottom":794.5}},{"unicode":65447,"advance":0.92000000000000004,"planeBounds":{"left":0.14358333333333331,"top":-0.65625,"right":0.78941666666666666,"bottom":-0.09375},"atlasBounds":{"left":328.5,"top":827.5,"right":359.5,"bottom":854.5}},{"unicode":65448,"advance":0.92000000000000004,"planeBounds":{"left":0.1103333333333333,"top":-0.65625,"right":0.81866666666666665,"bottom":-0.09375},"atlasBounds":{"left":466.5,"top":827.5,"right":500.5,"bottom":854.5}},{"unicode":65449,"advance":0.92000000000000004,"planeBounds":{"left":0.13366666666666663,"top":-0.67708333333333326,"right":0.80033333333333323,"bottom":-0.072916666666666671},"atlasBounds":{"left":781.5,"top":764.5,"right":813.5,"bottom":793.5}},{"unicode":65450,"advance":0.92000000000000004,"planeBounds":{"left":0.098916666666666639,"top":-0.67708333333333337,"right":0.82808333333333328,"bottom":-0.09375},"atlasBounds":{"left":292.5,"top":827.5,"right":327.5,"bottom":855.5}},{"unicode":65451,"advance":0.92000000000000004,"planeBounds":{"left":0.10391666666666662,"top":-0.67708333333333337,"right":0.83308333333333329,"bottom":-0.09375},"atlasBounds":{"left":256.5,"top":827.5,"right":291.5,"bottom":855.5}},{"unicode":65452,"advance":0.92000000000000004,"planeBounds":{"left":0.094499999999999987,"top":-0.67708333333333326,"right":0.84450000000000003,"bottom":-0.072916666666666671},"atlasBounds":{"left":651.5,"top":764.5,"right":687.5,"bottom":793.5}},{"unicode":65453,"advance":0.92000000000000004,"planeBounds":{"left":0.098166666666666666,"top":-0.67708333333333326,"right":0.88983333333333325,"bottom":-0.072916666666666671},"atlasBounds":{"left":612.5,"top":764.5,"right":650.5,"bottom":793.5}},{"unicode":65454,"advance":0.92000000000000004,"planeBounds":{"left":0.098499999999999963,"top":-0.67708333333333337,"right":0.84849999999999992,"bottom":-0.09375},"atlasBounds":{"left":104.5,"top":827.5,"right":140.5,"bottom":855.5}},{"unicode":65455,"advance":0.92000000000000004,"planeBounds":{"left":0.10249999999999997,"top":-0.67708333333333337,"right":0.85249999999999992,"bottom":-0.09375},"atlasBounds":{"left":67.5,"top":827.5,"right":103.5,"bottom":855.5}},{"unicode":65456,"advance":0.92000000000000004,"planeBounds":{"left":0.10100000000000002,"top":-0.69791666666666663,"right":0.85099999999999998,"bottom":-0.072916666666666671},"atlasBounds":{"left":819.5,"top":726.5,"right":855.5,"bottom":756.5}},{"unicode":65457,"advance":0.92000000000000004,"planeBounds":{"left":0.13116666666666665,"top":-0.65625,"right":0.79783333333333328,"bottom":-0.09375},"atlasBounds":{"left":360.5,"top":827.5,"right":392.5,"bottom":854.5}},{"unicode":65458,"advance":0.92000000000000004,"planeBounds":{"left":0.14108333333333328,"top":-0.67708333333333326,"right":0.7869166666666666,"bottom":-0.072916666666666671},"atlasBounds":{"left":519.5,"top":764.5,"right":550.5,"bottom":793.5}},{"unicode":65459,"advance":0.92000000000000004,"planeBounds":{"left":0.1153333333333333,"top":-0.67708333333333337,"right":0.82366666666666666,"bottom":-0.09375},"atlasBounds":{"left":821.5,"top":518.5,"right":855.5,"bottom":546.5}},{"unicode":65460,"advance":0.92000000000000004,"planeBounds":{"left":0.11016666666666662,"top":-0.67708333333333326,"right":0.90183333333333326,"bottom":-0.072916666666666671},"atlasBounds":{"left":480.5,"top":764.5,"right":518.5,"bottom":793.5}},{"unicode":65461,"advance":0.92000000000000004,"planeBounds":{"left":0.10041666666666667,"top":-0.67708333333333326,"right":0.82958333333333323,"bottom":-0.072916666666666671},"atlasBounds":{"left":745.5,"top":764.5,"right":780.5,"bottom":793.5}},{"unicode":65462,"advance":0.92000000000000004,"planeBounds":{"left":0.051333333333333328,"top":-0.65625,"right":0.8846666666666666,"bottom":-0.09375},"atlasBounds":{"left":649.5,"top":827.5,"right":689.5,"bottom":854.5}},{"unicode":65463,"advance":0.92000000000000004,"planeBounds":{"left":0.12716666666666665,"top":-0.67708333333333326,"right":0.79383333333333328,"bottom":-0.072916666666666671},"atlasBounds":{"left":814.5,"top":764.5,"right":846.5,"bottom":793.5}},{"unicode":65464,"advance":0.92000000000000004,"planeBounds":{"left":0.11333333333333334,"top":-0.67708333333333326,"right":0.82166666666666666,"bottom":-0.072916666666666671},"atlasBounds":{"left":688.5,"top":764.5,"right":722.5,"bottom":793.5}},{"unicode":65465,"advance":0.92000000000000004,"planeBounds":{"left":0.048833333333333312,"top":-0.67708333333333326,"right":0.88216666666666665,"bottom":-0.072916666666666671},"atlasBounds":{"left":439.5,"top":764.5,"right":479.5,"bottom":793.5}},{"unicode":65466,"advance":0.92000000000000004,"planeBounds":{"left":0.10733333333333331,"top":-0.71874999999999989,"right":0.81566666666666665,"bottom":-0.052083333333333329},"atlasBounds":{"left":19.5,"top":764.5,"right":53.5,"bottom":796.5}},{"unicode":65467,"advance":0.92000000000000004,"planeBounds":{"left":0.12516666666666665,"top":-0.67708333333333326,"right":0.79183333333333328,"bottom":-0.072916666666666671},"atlasBounds":{"left":0.5,"top":797.5,"right":32.5,"bottom":826.5}},{"unicode":65468,"advance":0.92000000000000004,"planeBounds":{"left":0.13616666666666666,"top":-0.67708333333333337,"right":0.80283333333333329,"bottom":-0.09375},"atlasBounds":{"left":178.5,"top":827.5,"right":210.5,"bottom":855.5}},{"unicode":65469,"advance":0.92000000000000004,"planeBounds":{"left":0.11083333333333328,"top":-0.65625,"right":0.8191666666666666,"bottom":-0.072916666666666671},"atlasBounds":{"left":821.5,"top":645.5,"right":855.5,"bottom":673.5}},{"unicode":65470,"advance":0.92000000000000004,"planeBounds":{"left":0.12124999999999998,"top":-0.71875,"right":0.80874999999999997,"bottom":-0.03125},"atlasBounds":{"left":500.5,"top":726.5,"right":533.5,"bottom":759.5}},{"unicode":65474,"advance":0.92000000000000004,"planeBounds":{"left":0.34008333333333335,"top":-0.86458333333333326,"right":0.73591666666666666,"bottom":0.13541666666666669},"atlasBounds":{"left":562.5,"top":96.5,"right":581.5,"bottom":144.5}},{"unicode":65475,"advance":0.92000000000000004,"planeBounds":{"left":0.25916666666666671,"top":-0.86458333333333326,"right":0.67583333333333329,"bottom":0.13541666666666669},"atlasBounds":{"left":541.5,"top":96.5,"right":561.5,"bottom":144.5}},{"unicode":65476,"advance":0.92000000000000004,"planeBounds":{"left":0.32000000000000001,"top":-0.86458333333333326,"right":0.69500000000000006,"bottom":0.13541666666666669},"atlasBounds":{"left":151.5,"top":195.5,"right":169.5,"bottom":243.5}},{"unicode":65477,"advance":0.92000000000000004,"planeBounds":{"left":0.26808333333333334,"top":-0.86458333333333326,"right":0.6639166666666666,"bottom":0.13541666666666669},"atlasBounds":{"left":0.5,"top":195.5,"right":19.5,"bottom":243.5}},{"unicode":65478,"advance":0.92000000000000004,"planeBounds":{"left":0.24658333333333329,"top":-0.86458333333333326,"right":0.64241666666666664,"bottom":0.13541666666666669},"atlasBounds":{"left":92.5,"top":195.5,"right":111.5,"bottom":243.5}},{"unicode":65479,"advance":0.92000000000000004,"planeBounds":{"left":0.18408333333333332,"top":-0.86458333333333326,"right":0.70491666666666664,"bottom":0.13541666666666669},"atlasBounds":{"left":20.5,"top":195.5,"right":45.5,"bottom":243.5}},{"unicode":65482,"advance":0.92000000000000004,"planeBounds":{"left":0.24808333333333329,"top":-0.86458333333333326,"right":0.64391666666666669,"bottom":0.13541666666666669},"atlasBounds":{"left":627.5,"top":96.5,"right":646.5,"bottom":144.5}},{"unicode":65483,"advance":0.92000000000000004,"planeBounds":{"left":0.18058333333333329,"top":-0.86458333333333326,"right":0.70141666666666669,"bottom":0.13541666666666669},"atlasBounds":{"left":149.5,"top":146.5,"right":174.5,"bottom":194.5}},{"unicode":65484,"advance":0.92000000000000004,"planeBounds":{"left":0.00066666666666662349,"top":-0.69791666666666663,"right":0.91733333333333322,"bottom":-0.13541666666666666},"atlasBounds":{"left":421.5,"top":827.5,"right":465.5,"bottom":854.5}},{"unicode":65485,"advance":0.92000000000000004,"planeBounds":{"left":0.0081666666666666051,"top":-0.86458333333333326,"right":0.92483333333333317,"bottom":0.13541666666666669},"atlasBounds":{"left":582.5,"top":96.5,"right":626.5,"bottom":144.5}},{"unicode":65486,"advance":0.92000000000000004,"planeBounds":{"left":0.013916666666666635,"top":-0.86458333333333326,"right":0.86808333333333332,"bottom":0.13541666666666669},"atlasBounds":{"left":224.5,"top":146.5,"right":265.5,"bottom":194.5}},{"unicode":65487,"advance":0.92000000000000004,"planeBounds":{"left":0.048666666666666622,"top":-0.86458333333333326,"right":0.84033333333333327,"bottom":0.13541666666666669},"atlasBounds":{"left":112.5,"top":195.5,"right":150.5,"bottom":243.5}},{"unicode":65490,"advance":0.92000000000000004,"planeBounds":{"left":0.007166666666666606,"top":-0.69791666666666663,"right":0.92383333333333317,"bottom":-0.11458333333333334},"atlasBounds":{"left":211.5,"top":827.5,"right":255.5,"bottom":855.5}},{"unicode":65491,"advance":0.92000000000000004,"planeBounds":{"left":0.0066666666666666237,"top":-0.57291666666666663,"right":0.92333333333333323,"bottom":-0.010416666666666666},"atlasBounds":{"left":501.5,"top":827.5,"right":545.5,"bottom":854.5}},{"unicode":65492,"advance":0.92000000000000004,"planeBounds":{"left":0.032833333333333277,"top":-0.86458333333333326,"right":0.86616666666666664,"bottom":0.13541666666666669},"atlasBounds":{"left":764.5,"top":146.5,"right":804.5,"bottom":194.5}},{"unicode":65493,"advance":0.92000000000000004,"planeBounds":{"left":0.026416666666666658,"top":-0.86458333333333326,"right":0.88058333333333327,"bottom":0.13541666666666669},"atlasBounds":{"left":722.5,"top":146.5,"right":763.5,"bottom":194.5}},{"unicode":65494,"advance":0.92000000000000004,"planeBounds":{"left":0.049749999999999996,"top":-0.86458333333333326,"right":0.86225000000000007,"bottom":0.13541666666666669},"atlasBounds":{"left":682.5,"top":146.5,"right":721.5,"bottom":194.5}},{"unicode":65495,"advance":0.92000000000000004,"planeBounds":{"left":0.00066666666666662349,"top":-0.57291666666666663,"right":0.91733333333333322,"bottom":-0.010416666666666666},"atlasBounds":{"left":718.5,"top":827.5,"right":762.5,"bottom":854.5}},{"unicode":65498,"advance":0.92000000000000004,"planeBounds":{"left":0.00066666666666662349,"top":-0.46875,"right":0.91733333333333322,"bottom":-0.30208333333333337},"atlasBounds":{"left":598.5,"top":797.5,"right":642.5,"bottom":805.5}},{"unicode":65499,"advance":0.92000000000000004,"planeBounds":{"left":0.032249999999999973,"top":-0.84374999999999989,"right":0.84474999999999989,"bottom":0.13541666666666669},"atlasBounds":{"left":656.5,"top":195.5,"right":695.5,"bottom":242.5}},{"unicode":65500,"advance":0.92000000000000004,"planeBounds":{"left":0.38116666666666671,"top":-0.86458333333333326,"right":0.54783333333333328,"bottom":0.13541666666666669},"atlasBounds":{"left":140.5,"top":146.5,"right":148.5,"bottom":194.5}},{"unicode":65504,"advance":1,"planeBounds":{"left":0.19149999999999998,"top":-0.82291666666666663,"right":0.8165,"bottom":0.09375},"atlasBounds":{"left":686.5,"top":338.5,"right":716.5,"bottom":382.5}},{"unicode":65505,"advance":1,"planeBounds":{"left":0.18308333333333332,"top":-0.78125,"right":0.82891666666666663,"bottom":0.052083333333333336},"atlasBounds":{"left":328.5,"top":604.5,"right":359.5,"bottom":644.5}},{"unicode":65506,"advance":1,"planeBounds":{"left":0.072833333333333292,"top":-0.57291666666666663,"right":0.90616666666666668,"bottom":-0.15625},"atlasBounds":{"left":145.5,"top":797.5,"right":185.5,"bottom":817.5}},{"unicode":65507,"advance":1,"planeBounds":{"left":-0.052083333333333259,"top":-0.92708333333333337,"right":1.0520833333333333,"bottom":-0.78125},"atlasBounds":{"left":697.5,"top":797.5,"right":750.5,"bottom":804.5}},{"unicode":65508,"advance":1,"planeBounds":{"left":0.42708333333333331,"top":-0.88541666666666663,"right":0.57291666666666663,"bottom":0.11458333333333333},"atlasBounds":{"left":170.5,"top":195.5,"right":177.5,"bottom":243.5}},{"unicode":65509,"advance":1,"planeBounds":{"left":0.13491666666666663,"top":-0.78125,"right":0.86408333333333331,"bottom":0.052083333333333336},"atlasBounds":{"left":158.5,"top":645.5,"right":193.5,"bottom":685.5}},{"unicode":65510,"advance":1,"planeBounds":{"left":0.041666666666666664,"top":-0.78125,"right":0.95833333333333326,"bottom":0.052083333333333336},"atlasBounds":{"left":185.5,"top":604.5,"right":229.5,"bottom":644.5}},{"unicode":65512,"advance":0.5,"planeBounds":{"left":0.16666666666666669,"top":-0.88541666666666674,"right":0.33333333333333337,"bottom":0.32291666666666663},"atlasBounds":{"left":70.5,"top":0.5,"right":78.5,"bottom":58.5}},{"unicode":65513,"advance":0.5,"planeBounds":{"left":-0.036250000000000018,"top":-0.65625,"right":0.52625,"bottom":-0.09375},"atlasBounds":{"left":690.5,"top":827.5,"right":717.5,"bottom":854.5}},{"unicode":65514,"advance":0.5,"planeBounds":{"left":0.02083333333333335,"top":-0.90624999999999989,"right":0.47916666666666669,"bottom":0.13541666666666669},"atlasBounds":{"left":505.5,"top":0.5,"right":527.5,"bottom":50.5}},{"unicode":65515,"advance":0.5,"planeBounds":{"left":-0.026250000000000016,"top":-0.65625,"right":0.53625,"bottom":-0.09375},"atlasBounds":{"left":393.5,"top":827.5,"right":420.5,"bottom":854.5}},{"unicode":65516,"advance":0.5,"planeBounds":{"left":0.02083333333333335,"top":-0.90624999999999989,"right":0.47916666666666669,"bottom":0.13541666666666669},"atlasBounds":{"left":650.5,"top":0.5,"right":672.5,"bottom":50.5}},{"unicode":65517,"advance":0.5,"planeBounds":{"left":0.020833333333333343,"top":-0.61458333333333337,"right":0.47916666666666669,"bottom":-0.15625},"atlasBounds":{"left":33.5,"top":797.5,"right":55.5,"bottom":819.5}},{"unicode":65518,"advance":0.5,"planeBounds":{"left":0.020333333333333373,"top":-0.61458333333333326,"right":0.47866666666666668,"bottom":-0.13541666666666666},"atlasBounds":{"left":820.5,"top":827.5,"right":842.5,"bottom":850.5}}],"kerning":[]}
diff --git a/tests/Resources/Typefaces/NotoSansJP/NotoSansJP-Regular.png b/tests/Resources/Typefaces/NotoSansJP/NotoSansJP-Regular.png
new file mode 100644
index 0000000..d865662
Binary files /dev/null and b/tests/Resources/Typefaces/NotoSansJP/NotoSansJP-Regular.png differ
diff --git a/tests/SampleGameBase.cs b/tests/SampleGameBase.cs
index bee3871..f23a9d6 100644
--- a/tests/SampleGameBase.cs
+++ b/tests/SampleGameBase.cs
@@ -27,6 +27,8 @@ private void load()
msdfFonts.AddFont(Resources, $"WorkSans", $"{weight}Italic");
}
+ msdfFonts.AddFont(Resources, $"NotoSansJP", "Regular");
+
dependencies?.CacheAs(msdfFonts);
}
diff --git a/tests/VIsual/Containers/TestSceneMsdfTextFlowContainer.cs b/tests/VIsual/Containers/TestSceneMsdfTextFlowContainer.cs
new file mode 100644
index 0000000..8f015b3
--- /dev/null
+++ b/tests/VIsual/Containers/TestSceneMsdfTextFlowContainer.cs
@@ -0,0 +1,215 @@
+using kajarlabs.osu.Framework.MsdfTextRendering.Graphics.Containers;
+using kajarlabs.osu.Framework.MsdfTextRendering.Graphics.Sprites;
+using kajarlabs.osu.Framework.MsdfTextRendering.Tests.Visual.Sprites;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Logging;
+using osuTK;
+using osuTK.Graphics;
+
+namespace kajarlabs.osu.Framework.MsdfTextRendering.Tests.Visual.Containers;
+
+public partial class TestSceneMsdfTextFlowContainer : MsdfComparisonTestScene
+{
+ private const float demo_font_size = 20.0f;
+ private const float flow_width = 380.0f;
+
+ private const string multi_paragraph_text =
+ "The quick brown fox jumps over the lazy dog. A swift movement across the tranquil meadow.\n\n" +
+ "Second paragraph with more descriptive text to demonstrate multi-line wrapping and paragraph spacing.\n" +
+ "This line follows a single newline break.";
+
+ private const string cjk_and_urls_text =
+ "Visit https://osu.ppy.sh/home or browse \\local\\storage\\path. " +
+ "We also support hyphen-based and anti-aliased text splitting. " +
+ "CJK support: こんにちは世界!(Hello World) and 日本語の文章です。";
+
+ private static readonly FontUsage default_fu = FontUsage.Default.With(family: "WorkSans", size: demo_font_size, weight: "Regular");
+
+ private TextFlowContainer leftFlow = null!;
+ private MsdfTextFlowContainer rightFlow = null!;
+
+ protected override string LeftLabel => "TextFlowContainer (without MSDF, bitmap WorkSans)";
+ protected override string RightLabel => "MsdfTextFlowContainer (with MSDF)";
+
+ protected override Drawable CreateLeftSample() => new Container
+ {
+ AutoSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Child = leftFlow = new TextFlowContainer(s => s.Font = default_fu)
+ {
+ Width = flow_width,
+ AutoSizeAxes = Axes.Y,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ }
+ };
+
+ protected override Drawable CreateRightSample() => new Container
+ {
+ AutoSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Child = rightFlow = new MsdfTextFlowContainer(s => s.Font = default_fu)
+ {
+ Width = flow_width,
+ AutoSizeAxes = Axes.Y,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ }
+ };
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ AddStep("Default multi-paragraph", () =>
+ {
+ resetProperties();
+ leftFlow.Text = multi_paragraph_text;
+ rightFlow.Text = multi_paragraph_text;
+ });
+
+ AddStep("AddText (\\n is paragraph)", () =>
+ {
+ resetProperties();
+ leftFlow.Clear();
+ rightFlow.Clear();
+
+ leftFlow.AddText("Line 1\nLine 2\nLine 3");
+ rightFlow.AddText("Line 1\nLine 2\nLine 3");
+
+ Schedule(logFlowMetrics);
+ });
+
+ AddStep("AddParagraph (\\n is line break)", () =>
+ {
+ resetProperties();
+ leftFlow.Clear();
+ rightFlow.Clear();
+
+ leftFlow.AddParagraph("Line 1\nLine 2\nLine 3");
+ rightFlow.AddParagraph("Line 1\nLine 2\nLine 3");
+ });
+
+ foreach (var anchor in new[]
+ {
+ Anchor.TopLeft, Anchor.TopCentre, Anchor.TopRight,
+ Anchor.CentreLeft, Anchor.Centre, Anchor.CentreRight,
+ Anchor.BottomLeft, Anchor.BottomCentre, Anchor.BottomRight
+ })
+ {
+ AddStep($"Anchor: {anchor}", () =>
+ {
+ leftFlow.TextAnchor = anchor;
+ rightFlow.TextAnchor = anchor;
+ });
+ }
+
+ AddStep("Indents: FirstLine=40, Content=20", () =>
+ {
+ resetProperties();
+ leftFlow.FirstLineIndent = 40;
+ leftFlow.ContentIndent = 20;
+ rightFlow.FirstLineIndent = 40;
+ rightFlow.ContentIndent = 20;
+ leftFlow.Text = multi_paragraph_text;
+ rightFlow.Text = multi_paragraph_text;
+ });
+
+ AddStep("Spacing: Para=2.0, Line=10", () =>
+ {
+ resetProperties();
+ leftFlow.ParagraphSpacing = 2.0f;
+ leftFlow.LineSpacing = 10f;
+ rightFlow.ParagraphSpacing = 2.0f;
+ rightFlow.LineSpacing = 10f;
+ leftFlow.Text = multi_paragraph_text;
+ rightFlow.Text = multi_paragraph_text;
+ });
+
+ AddStep("URLs, Hyphens & CJK", () =>
+ {
+ resetProperties();
+ leftFlow.Text = cjk_and_urls_text;
+ rightFlow.Text = cjk_and_urls_text;
+ });
+
+ AddStep("Mixed manual instances", () =>
+ {
+ resetProperties();
+ leftFlow.Clear();
+ rightFlow.Clear();
+
+ leftFlow.AddText("Before manual: ");
+ leftFlow.AddText(new SpriteText
+ {
+ Text = "[MANUAL INSTANCE]",
+ Colour = Color4.Gold,
+ Font = default_fu
+ });
+ leftFlow.AddText(" - After manual text continuation.");
+
+ rightFlow.AddText("Before manual: ");
+ rightFlow.AddText(new MsdfSpriteText
+ {
+ Text = "[MANUAL INSTANCE]",
+ Colour = Color4.Gold,
+ Font = default_fu
+ });
+ rightFlow.AddText(" - After manual text continuation.");
+ });
+
+ AddStep("Baseline alignment (mixed sizes)", () =>
+ {
+ resetProperties();
+ leftFlow.Clear();
+ rightFlow.Clear();
+
+ leftFlow.AddText("Normal (20) ", s => s.Font = default_fu.With(size: 20));
+ leftFlow.AddText("Huge (36) ", s => s.Font = default_fu.With(size: 36));
+ leftFlow.AddText("Small (14) ", s => s.Font = default_fu.With(size: 14));
+ leftFlow.AddText("on same baseline.");
+
+ rightFlow.AddText("Normal (20) ", s => s.Font = default_fu.With(size: 20));
+ rightFlow.AddText("Huge (36) ", s => s.Font = default_fu.With(size: 36));
+ rightFlow.AddText("Small (14) ", s => s.Font = default_fu.With(size: 14));
+ rightFlow.AddText("on same baseline.");
+ });
+ }
+
+ private void logFlowMetrics()
+ {
+ Logger.Log($"--- left (native) flow.Height={leftFlow.DrawHeight:F3} ---");
+ foreach (var c in leftFlow.Children)
+ Logger.Log($" {c.GetType().Name,-20} '{(c as SpriteText)?.Text}' Y={c.Y,8:F3} H={c.DrawHeight,8:F3}");
+
+ Logger.Log($"--- right (msdf) flow.Height={rightFlow.DrawHeight:F3} ---");
+ foreach (var c in rightFlow.Children)
+ Logger.Log($" {c.GetType().Name,-20} '{(c as MsdfSpriteText)?.Text}' Y={c.Y,8:F3} H={c.DrawHeight,8:F3}");
+ }
+
+ private void resetProperties()
+ {
+ leftFlow.TextAnchor = Anchor.TopLeft;
+ rightFlow.TextAnchor = Anchor.TopLeft;
+
+ leftFlow.FirstLineIndent = 0;
+ rightFlow.FirstLineIndent = 0;
+
+ leftFlow.ContentIndent = 0;
+ rightFlow.ContentIndent = 0;
+
+ leftFlow.ParagraphSpacing = 0.5f;
+ rightFlow.ParagraphSpacing = 0.5f;
+
+ leftFlow.LineSpacing = 0;
+ rightFlow.LineSpacing = 0;
+
+ leftFlow.Spacing = Vector2.Zero;
+ rightFlow.Spacing = Vector2.Zero;
+ }
+}
+
diff --git a/tests/VIsual/MsdfComparisonTestScene.cs b/tests/VIsual/MsdfComparisonTestScene.cs
new file mode 100644
index 0000000..4ecc662
--- /dev/null
+++ b/tests/VIsual/MsdfComparisonTestScene.cs
@@ -0,0 +1,200 @@
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Graphics.UserInterface;
+using osu.Framework.Input.Events;
+using osuTK;
+using osuTK.Graphics;
+
+namespace kajarlabs.osu.Framework.MsdfTextRendering.Tests.Visual;
+
+public abstract partial class SampleComparisonTestScene : SampleTestScene
+{
+ private const float top_bar_height = 40;
+ private const float min_zoom = 0.5f;
+ private const float max_zoom = 32f;
+
+ private readonly BindableNumber zoom = new(1f)
+ {
+ MinValue = min_zoom,
+ MaxValue = max_zoom,
+ Precision = 0.01f,
+ };
+
+ private readonly Bindable pan = new();
+
+ private SpriteText zoomValueText = null!;
+
+ protected abstract string LeftLabel { get; }
+ protected abstract string RightLabel { get; }
+
+ protected abstract Drawable CreateLeftSample();
+ protected abstract Drawable CreateRightSample();
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ Children =
+ [
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.MidnightBlue,
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Top = top_bar_height },
+ Children =
+ [
+ new ComparisonColumn(LeftLabel, CreateLeftSample(), zoom, pan)
+ {
+ RelativeSizeAxes = Axes.Both,
+ RelativePositionAxes = Axes.X,
+ Width = 0.5f,
+ Padding = new MarginPadding { Top = 8 },
+ },
+ new ComparisonColumn(RightLabel, CreateRightSample(), zoom, pan)
+ {
+ RelativeSizeAxes = Axes.Both,
+ RelativePositionAxes = Axes.X,
+ Width = 0.5f,
+ X = 0.5f,
+ Padding = new MarginPadding { Top = 8 },
+ },
+ new Box
+ {
+ RelativeSizeAxes = Axes.Y,
+ RelativePositionAxes = Axes.X,
+ Width = 2,
+ X = 0.5f,
+ Origin = Anchor.TopCentre,
+ Colour = Color4.White,
+ Alpha = 0.25f,
+ },
+ ],
+ },
+ new Container
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = top_bar_height,
+ Children =
+ [
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Black,
+ Alpha = 0.6f,
+ },
+ new SpriteText
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ X = 16,
+ Text = "Scroll to zoom, drag to pan",
+ Font = FontUsage.Default.With( size: 16, weight: "Regular"),
+ Colour = Color4.LightGray,
+ },
+ zoomValueText = new SpriteText
+ {
+ Anchor = Anchor.CentreRight,
+ Origin = Anchor.CentreRight,
+ X = -84,
+ Font = FontUsage.Default.With(size: 18, weight: "Regular"),
+ },
+ new BasicButton
+ {
+ Anchor = Anchor.CentreRight,
+ Origin = Anchor.CentreRight,
+ X = -8,
+ Width = 64,
+ Height = 28,
+ Text = "Reset",
+ Action = reset,
+ },
+ ],
+ },
+ ];
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ zoom.BindValueChanged(e => zoomValueText.Text = $"{e.NewValue:0.00}x", true);
+ }
+
+ protected override bool OnScroll(ScrollEvent e)
+ {
+ var factor = MathF.Pow(1.2f, e.ScrollDelta.Y);
+ zoom.Value = Math.Clamp(zoom.Value * factor, min_zoom, max_zoom);
+ return true;
+ }
+
+ protected override bool OnDragStart(DragStartEvent e) => true;
+
+ protected override void OnDrag(DragEvent e)
+ {
+ pan.Value += e.Delta;
+ base.OnDrag(e);
+ }
+
+ private void reset()
+ {
+ zoom.Value = 1f;
+ pan.Value = Vector2.Zero;
+ }
+
+ private partial class ComparisonColumn : Container
+ {
+ private readonly string label;
+ private readonly Drawable sample;
+ private readonly Bindable zoom;
+ private readonly Bindable pan;
+
+ private Container zoomArea = null!;
+
+ public ComparisonColumn(string label, Drawable sample, Bindable zoom, Bindable pan)
+ {
+ this.label = label;
+ this.sample = sample;
+ this.zoom = zoom.GetBoundCopy();
+ this.pan = pan.GetBoundCopy();
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ Masking = true;
+
+ InternalChildren =
+ [
+ new SpriteText
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ Text = label,
+ Font = FontUsage.Default.With(size: 20),
+ },
+ zoomArea = new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Child = sample,
+ },
+ ];
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ zoom.BindValueChanged(e => zoomArea.Scale = new Vector2(e.NewValue), true);
+ pan.BindValueChanged(e => zoomArea.Position = e.NewValue, true);
+ }
+ }
+}