[
  {
    "path": ".gitattributes",
    "content": "# Auto detect text files and perform LF normalization\n* text=auto\n"
  },
  {
    "path": ".gitignore",
    "content": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\ndemo/zfont.*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directory for instrumented libs generated by jscoverage/JSCover\nlib-cov\n\n# Coverage directory used by tools like istanbul\ncoverage\n\n# nyc test coverage\n.nyc_output\n\n# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)\n.grunt\n\n# Bower dependency directory (https://bower.io/)\nbower_components\n\n# node-waf configuration\n.lock-wscript\n\n# Compiled binary addons (https://nodejs.org/api/addons.html)\nbuild/Release\n\n# Dependency directories\nnode_modules/\njspm_packages/\n\n# TypeScript v1 declaration files\ntypings/\n\n# Optional npm cache directory\n.npm\n\n# Optional eslint cache\n.eslintcache\n\n# Optional REPL history\n.node_repl_history\n\n# Output of 'npm pack'\n*.tgz\n\n# Yarn Integrity file\n.yarn-integrity\n\n# dotenv environment variables file\n.env\n\n# parcel-bundler cache (https://parceljs.org/)\n.cache\n\n# next.js build output\n.next\n\n# nuxt.js build output\n.nuxt\n\n# vuepress build output\n.vuepress/dist\n\n# Serverless directories\n.serverless\n\n# FuseBox cache\n.fusebox/\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 james\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "README.md",
    "content": "\n<h1 align=\"center\"><a href=\"https://github.com/jaames/zfont\" target=\"blank\"><img width=\"888\" src=\"https://raw.githubusercontent.com/jaames/zfont/master/assets/banner.gif\"/><br/>Zfont</a></h1>\n\n<p align=\"center\">\n<b>A text plugin for the <a href=\"https://github.com/metafizzy/zdog\">Zdog</a> 3D engine! Renders TrueType fonts via <a href=\"https://github.com/photopea/Typr.js\">Typr.js</a> | <a href=\"https://jaames.github.io/zfont/\">jaames.github.io/zfont</a>\n</b>\n</p>\n\n<p align=\"center\">\n<a href=\"#features\">Features</a> | <a href=\"#caveats\">Caveats</a> | <a href=\"#demo\">Demo</a> | <a href=\"#installation\">Installation</a> | <a href=\"#usage\">Usage</a> | <a href=\"#api\">API</a> | <a href=\"#zdogfont\">Zdog.Font</a> | <a href=\"#zdogtext\">Zdog.Text</a> | <a href=\"#zdogtextgroup\">Zdog.TextGroup</a> | <a href=\"#todo\">Todo</a> | <a href=\"#building\">Building</a>\n</p>\n\n<br/>\n\n## Features\n\n* Built on top of [Typr.js](https://github.com/photopea/Typr.js), which supports a wide range of .ttf and .otf fonts with speed and grace\n* Less than 14kB minified and gzipped\n* No need to worry about waiting for fonts to load; text automatically pops into existence once the font is ready\n* Includes support for multiline text\n* Update font, text, color, alignment, etc at any time\n* Bonus utilities for measuring text, waiting for font load & more!\n\n## Caveats\n\n* You have to provide a .ttf to use yourself; it isn't possible to use system fonts\n* Character range is limited to whichever glyphs are supported by your chosen font, and font stacks/fallbacks aren't supported yet\n\n## Demo\n\nA live demo can be found [here](https://jaames.github.io/zfont/), there's also some more in-depth examples on [Codepen](https://codepen.io/collection/DPKGvY/)!\n\n## Installation\n\n### Install with NPM\n\n```bash\n$ npm install zfont --save\n```\n\nIf you are using a module bundler like Webpack or Rollup, import Zfont into your project: \n\n```javascript\n// Using ES6 module syntax\nimport Zfont from 'zfont';\n\n// Using CommonJS modules\nconst Zfont = require('zfont');\n```\n\n### Using the jsDelivr CDN\n\n```html\n<script src=\"https://cdn.jsdelivr.net/npm/zfont/dist/zfont.min.js\"></script>\n```\n\nWhen manually including the library like this, it will be globally available on `window.Zfont`\n\n### Download and Host Yourself\n\n**[Development version](https://raw.githubusercontent.com/jaames/zfont/master/dist/zfont.js)**<br/>\nUncompressed at around 75kB, with source comments included\n\n**[Production version](https://raw.githubusercontent.com/jaames/zfont/master/dist/zfont.min.js)**<br/>\nMinified to 45kB\n\nThen add it to the `<head>` of your page with a `<script>` tag:\n\n```html\n<html>\n  <head>\n    <!-- ... -->\n    <script src=\"./path/to/zfont.min.js\"></script>\n  </head>\n  <!-- ... -->\n</html>\n```\n\n## Usage\n\n### Register Plugin\n\nAfter both Zdog and Zfont have been imported/downloaded, we need to initialize the Zfont plugin. Once it's initialized, the `Zdog.Font`, `Zdog.Text` and `Zdog.TextGroup` classes will be available:\n\n```js\nZfont.init(Zdog);\n```\n\n### Hello World\n\n(Pssst! If you prefer to dive in, check out the [basic demo over on Codepen](https://codepen.io/rakujira/pen/vqLBwz))\n\nTo draw some text in a Zdog scene, first we need to set up a new `Zdog.Font` object with the .ttf url for our desired font, then we can create a new `Zdog.Text` object and add it to the illustration like any other shape:\n\n```js\n// Initialize Zfont\nZfont.init(Zdog);\n\n\n// Create a Zdog illustration\nlet illo = new Zdog.Illustration({\n  element: '.zdog-canvas'\n});\n\n// Set up a font to use\nlet myFont = new Zdog.Font({\n  src: './path/to/font.ttf'\n});\n\n// Create a text object\n// This is just a Zdog.Shape object with a couple of extra parameters!\nnew Zdog.Text({\n  addTo: illo,\n  font: myFont,\n  value: 'Hey, Zdog!',\n  fontSize: 64,\n  color: '#fff'\n});\n\n// Animation loop\nfunction animate() {\n  illo.updateRenderGraph();\n  requestAnimationFrame(animate);\n}\nanimate();\n```\n\n### Multiline Text\n\nBoth `Zdog.Text` and `Zdog.TextGroup` support multiline text, by inserting a newline character (`\\n`) wherever you wish to add a line break:\n\n```js\nnew Zdog.Text({\n  ...\n  value: 'The quick brown fox\\njumps over the\\nlazy zdog',\n});\n```\n\nFor better readability you may prefer to use an array of strings for the `value` option. In this case, each string in the array will be treated as a seperate line of text:\n\n```js\nnew Zdog.Text({\n  ...\n  value: [\n    'The quick brown fox'\n    'jumps over the',\n    'lazy zdog'\n  ]\n});\n```\n\n### Waiting for Fonts to Load\n\nIn most cases you don't have to worry about waiting for fonts to load, as text objects will magically pop into existence once their font is ready to use. However, the plugin also provides a `Zdog.waitForFonts()` utility function if you need to delay anything until all the fonts in your scene have finished loading.\n\nFor example, let's modify the animation loop from the previous example so that it doesn't begin until the fonts are ready:\n\n```js\n// Animation loop\nfunction animate() {\n  illo.updateRenderGraph();\n  requestAnimationFrame(animate);\n}\n// Zdog.waitForFonts() returns a Promise which is resolved once all the fonts added to the scene so far have been loaded\nZdog.waitForFonts().then(() => {\n  // Once the fonts are done, start the animation loop\n  animate();\n})\n```\n\n## API\n\n### Zdog.Font\n\nRepresents a font that can be used by an instance of either [`Zdog.Text`](#zdogtext) or [`Zdog.TextGroup`](#zdogtextgroup).\n\n```js\nlet font = new Zdog.Font({\n  src: './path/to/font.ttf'\n})\n```\n\n#### Options\n\n| Param      | Details | Default |\n|:-----------|:--------|:--------|\n| `src`      | Font URL path. This can be a `.ttf` or `.otf` font, check out the [Typr.js repo](https://github.com/photopea/Typr.js) for more details about font support | `''` |\n\n#### Methods\n\n##### `measureText(text, fontSize)`\n\nGet the measurements for the specified string `text` when rendered at `fontSize` (measured in pixels), similar to [`Canvas​Rendering​Context2D.measure​Text()`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/measureText). \n\nReturns an object with `width`, `height`, `descender`, `ascender`.\n\n##### `getTextPath(text, fontSize, x=0, y=0, z=0, alignX='left', alignY='bottom')`\n\nReturns an array of [Zdog path commands](https://zzz.dog/shapes#shape-path-commands) for the specified string `text`, when rendered at `fontSize` (measured in pixels).\n\n* (`x`, `y`, `z`) is the origin point of the path\n* `alignX` is the horizontal text alignment (equivalent to the CSS `text-align` property); either `\"left\"`, `\"center\"` or `\"right\"`. \n* `alignY` is the vertical text alignment; either `\"top\"`, `\"middle\"` or `\"bottom\".`\n\n##### `waitForLoad()`\n\nReturns a Promise which resolves once this font has finished loading.\n\n### Zdog.Text\n\nAn object used for rendering text. It inherits everything from the [`Zdog.Shape`](https://zzz.dog/api#shape) class.\n\n```js\nnew Zdog.Text({\n  addTo: illo,\n  font: font,\n  value: 'Hey, Zdog!',\n  textAlign: 'center',\n  textBaseline: 'middle',\n  color: '#5222ee',\n  stroke: 1,\n})\n```\n\n#### Options\n\n`Zdog.Text` inherits all the options from the [`Zdog.Shape`](https://zzz.dog/api#shape) class, plus a couple of extras:\n\n| Param      | Details | Default |\n|:-----------|:--------|:--------|\n| `font`     | [`Zdog.Font`](#zdog-font) to use for this text. This is required. | `null` |\n| `value`    | Text string | `''` |\n| `fontSize` | Text size, measured in pixels | `64` |\n| `textAlign`| Horizontal text alignment, equivalent to the CSS `text-align` property. This can be either `'left'`, `'center'` or `'right'` | `'left'` |\n| `textBaseline`| Vertical text alignment, equivalent to the HTML5 canvas' [`textBaseline`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline) property. This can be either `'top'`, `'middle'` or `'bottom'` | `'bottom'` |\n\n#### Properties\n\n`Zdog.Text` inherits all the properties from the [`Zdog.Shape`](https://zzz.dog/api#shape) class, as well as some extras. All of these properties can be updated at any time and the rendered text will update automatically. \n\n##### `font`\n\nThe [`Zdog.Font`](#zdog-font) instance being used for this text.\n\n##### `value`\n\nText value as a string.\n\n##### `fontSize`\n\nFont size, measured in pixels.\n\n##### `textAlign`\n\nHorizontal text alignment, equivalent to the CSS `text-align` property. This can be either `'left'`, `'center'` or `'right'`\n\n##### `textBaseline`\n\nVertical text alignment, equivalent to the HTML5 canvas' [`textBaseline`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline) property. This can be either `'top'`, `'middle'` or `'bottom'`\n\n### Zdog.TextGroup\n\nThis class is very similar to [`Zdog.Text`](#zdog-text), except it acts as a [`Zdog.Group`](https://zzz.dog/api#group) instead, and each text glyph is rendered as its own shape. This is helpful for more advanced use-cases where you need control over each character.\n\n```js\nnew Zdog.TextGroup({\n  addTo: illo,\n  font: font,\n  value: 'Hey, Zdog!',\n  textAlign: 'center',\n  color: '#5222ee',\n  stroke: 2,\n})\n```\n\n#### Options\n\n`Zdog.TextGroup` inherits all the options from the [`Zdog.Group`](https://zzz.dog/api#group) class, plus a few extras:\n\n| Param      | Details | Default |\n|:-----------|:--------|:--------|\n| `font`     | [`Zdog.Font`](#zdog-font) to use for this text. This is required. | `null` |\n| `value`    | Text string | `''` |\n| `fontSize` | Text size, measured in pixels | `64` |\n| `textAlign`| Horizontal text alignment, equivalent to the CSS `text-align` property. This can be either `'left'`, `'center'` or `'right'` | `'left'` |\n| `textBaseline`| Vertical text alignment, equivalent to the HTML5 canvas' [`textBaseline`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline) property. This can be either `'top'`, `'middle'` or `'bottom'` | `'bottom'` |\n| `color` | Text color | `#333` |\n| `fill` | Text fill | `false` |\n| `stroke` | Text stroke | `stroke` |\n\n#### Properties\n\n`Zdog.TextGroup` inherits all the properties from the [`Zdog.Group`](https://zzz.dog/api#group) class, as well as some extras. All of these properties can be updated at any time and the rendered text will update automatically. \n\n##### `font`\n\nThe [`Zdog.Font`](#zdog-font) instance being used for this text.\n\n##### `value`\n\nText value as a string.\n\n##### `fontSize`\n\nFont size, measured in pixels.\n\n##### `textAlign`\n\nHorizontal text alignment, equivalent to the CSS `text-align` property. This can be either `'left'`, `'center'` or `'right'`\n\n##### `textBaseline`\n\nVertical text alignment, equivalent to the HTML5 canvas' [`textBaseline`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline) property. This can be either `'top'`, `'middle'` or `'bottom'`\n\n##### `color`\n\nText color, equivalent to [`Shape.color`](https://zzz.dog/api#shape-color). Setting this will update the color for all of the group's children.\n\n##### `fill`\n\nText fill, equivalent to [`Shape.fill`](https://zzz.dog/api#shape-fill). Setting this will update the fill for all of the group's children.\n\n##### `stroke`\n\nText stroke, equivalent to [`Shape.stroke`](https://zzz.dog/api#shape-stroke). Setting this will update the stroke for all of the group's children.\n\n### Zdog.waitForFonts\n\nReturns a Promise which resolves as soon as all the fonts currently added to the scene are loaded and ready for use.\n\n```js\nZdog.waitForFonts().then(function() {\n  // Do something once the font is ready\n}\n```\n\n## Todo\n\n* Google Fonts & Typekit integration?\n* Support for different text directions, e.g. right-to-left\n* Support for fallback fonts\n* Support for color (SVG) fonts\n\n## Building\n\n### Install Dependencies with NPM\n\n```bash\n$ npm install\n```\n\n### Run Devserver\n\n```bash\n$ npm start\n```\n\n### Build production files\n\n```bash\n$ npm run build\n```\n\n----\n\n2019 [James Daniel](//github.com/jaames)\n"
  },
  {
    "path": "demo/demo.css",
    "content": "@import url('https://simbo.codes/css-reset-and-normalize/reset-and-normalize.min.css');\n@import url('https://fonts.googleapis.com/css?family=Fredoka+One');\n\nbody {\n  color: #000032;\n  background: #eef;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n  font-size: 16px;\n  line-height: 1.5;\n  letter-spacing: .015em;\n  font-smoothing: antialiased;\n  text-rendering: optimizeLegibility;\n  -webkit-font-smoothing: antialiased;\n  -webkit-text-rendering: optimizeLegibility;\n  -moz-font-smoothing: antialiased;\n  -moz-text-rendering: optimizeLegibility;\n}\n\nh1, h2, h3, h4, h5, h6, .Button {\n  font-family: \"Fredoka One\", -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";\n}\n\nh1 {\n  font-size: 3.5rem;\n  font-weight: bold;\n}\n\nh2 {\n  font-size: 1.25rem;\n}\n\nh3 {\n  font-size: 1.25rem;\n}\n\na {\n  color: #645bdf;\n  cursor: pointer;\n  text-decoration: none;\n  border-bottom: .08em dashed currentColor;\n}\n\na:hover {\n  color: #5222ee;\n}\n\n.Page {\n  width: 100%;\n  max-width: 728px;\n  margin: 0 auto;\n  padding: 3rem 12px;\n}\n\n.Header {\n  text-align: center;\n  margin: 4rem 0;\n}\n\n.Section {\n  margin: 2rem 0;\n}\n\n.Section h3 {\n  margin-bottom: 1em;\n}\n\n.Button {\n  display: inline-block;\n  background: #000032;\n  box-shadow: 0 5px 0 -2px #adadc0;\n  color: #fff;\n  padding: 0.5em 1.5em;\n  border-radius: 12px;\n  margin: 0 6px;\n  border: 0;\n  font-size: 1.2rem; \n  transition: transform 0.1s ease-in-out, box-shadow 0.1s ease-in-out;\n}\n\n.Button:hover {\n  color: #6e66e2;\n  transform: scale(1.025);\n  box-shadow: 0 8px 0 -5px #adadc0;\n}\n\n.ButtonGroup {\n  margin: 2rem 0;\n  display: flex;\n  justify-content: center;\n}\n\n.ButtonGroup .Button {\n  /* flex: 1 */\n}\n\n.FeatureList {\n  padding: 0;\n  list-style-type: none;\n}\n\n.FeatureList .FeatureItem {\n  padding: 8px 0;\n}\n\n@media screen and (min-width: 700px) {\n  .FeatureList {\n    display: flex;\n    margin: 0 -8px;\n  }\n  .FeatureList .FeatureItem {\n    padding: 0 8px;\n    flex: 1;\n  }\n}\n\n.FeatureList .FeatureItem p {\n  /* font-family:  */\n}\n\n.Canvas {\n  width: 100%;\n  border-radius: 12px;\n  background: #5222ee;\n  box-shadow: 0 5px 0 -2px #8d88d6;\n  cursor: pointer;\n}\n\n.Textarea {\n  /* font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\"; */\n  border: 2px solid #dde;\n  box-shadow: 0 5px 0 -2px #c3c3dd;\n  border-radius: 12px;\n  display: block;\n  width: 100%;\n  margin-top: 12px;\n  padding: 16px;\n  resize: vertical;\n}\n\n.Footer {\n  text-align: right;\n  margin: 2rem 0;\n}\n\n.GithubCorner {\n  z-index: 10;\n  border: 0;\n  display: block;\n  position: fixed;\n  top: -5px;\n  right: -5px;\n  background: transparent;\n}\n\n.GithubCorner__svg {\n  width: 100px;\n  height: 100px;\n  fill: #000032;\n  transition: transform 0.2s;\n}\n\n.GithubCorner:hover .GithubCorner__svg {\n  -webkit-transform: translate(-5px,5px);\n  transform: translate(-5px,5px);\n}\n\n.GithubCorner .octo-arm, \n.GithubCorner .octo-body {\n fill: #eef;\n}"
  },
  {
    "path": "demo/demo.js",
    "content": "// Register Zfont plugin\nZfont.init(Zdog);\n\nconst textarea = document.getElementById('textarea');\n\n// create illo\nlet illo = new Zdog.Illustration({\n  element: '.Canvas',\n  dragRotate: true,\n  resize: true,\n  rotate: {x: -0.32, y: 0.64, z: 0}\n});\n\n// create font\nlet font = new Zdog.Font({\n\tsrc: './fredokaone.ttf'\n});\n\nlet text = new Zdog.Text({\n  addTo: illo,\n  font: font,\n  value: textarea.value,\n  fontSize: 48,\n  textAlign: 'center',\n  textBaseline: 'middle',\n  color: '#fff',\n  fill: true,\n});\n\n// text \"shadow\"\nlet shadow1 = text.copy({\n  addTo: illo,\n  translate: {z: -3},\n  color: '#aab',\n});\nlet shadow2 = text.copy({\n  addTo: illo,\n  translate: {z: -6},\n  color: '#aab',\n});\n\ntextarea.addEventListener('input', function() {\n  text.value = textarea.value;\n  shadow1.value = textarea.value;\n  shadow2.value = textarea.value;\n});\n\n// animation loop\nfunction animate() {\n  illo.updateRenderGraph();\n  requestAnimationFrame(animate);\n}\n\nanimate();"
  },
  {
    "path": "demo/index.html",
    "content": "<html>\n  <head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n    <title>Zfont</title>\n    <meta name=\"description\" content=\"Zfont - a text plugin for the Zdog 3d engine\">\n    <link rel=\"stylesheet\" href=\"./demo.css\">\n    <script src=\"https://unpkg.com/zdog@1/dist/zdog.dist.min.js\"></script>\n    <script src=\"./zfont.js\" charset=\"utf-8\"></script>\n    <script async defer data-domain=\"jaames.github.io\" src=\"https://st2.jamesdaniel.dev/js/index.js\"></script>\n  </head>\n  <body>\n    <a href=\"https://github.com/jaames/zfont\" target=\"_blank\" class=\"GithubCorner\">\n      <svg class=\"GithubCorner__svg\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 250 250\">\n        <path d=\"M0 0l115 115h15l12 27 108 108V0z\"/>\n        <path class=\"octo-arm\" d=\"M128 109c-15-9-9-19-9-19 3-7 2-11 2-11-1-7 3-2 3-2 4 5 2 11 2 11-3 10 5 15 9 16\" style=\"-webkit-transform-origin: 130px 106px; transform-origin: 130px 106px\"/>\n        <path class=\"octo-body\" d=\"M115 115s4 2 5 0l14-14c3-2 6-3 8-3-8-11-15-24 2-41 5-5 10-7 16-7 1-2 3-7 12-11 0 0 5 3 7 16 4 2 8 5 12 9s7 8 9 12c14 3 17 7 17 7-4 8-9 11-11 11 0 6-2 11-7 16-16 16-30 10-41 2 0 3-1 7-5 11l-12 11c-1 1 1 5 1 5z\"/>\n      </svg>\n    </a>\n    <main class=\"Page\">\n      <header class=\"Header\">\n        <h1 class=\"Title\">Zfont</h1>\n        <h2 class=\"Subtitle\">\n          A text plugin for the <a href=\"https://zzz.dog/\" target=\"_blank\">Zdog</a> 3D engine\n        </h2>  \n        <div class=\"ButtonGroup\">\n          <a href=\"https://codepen.io/collection/DPKGvY/\" class=\"Button\">\n            Codepen Demos\n          </a>\n          <a href=\"https://github.com/jaames/zfont#installation\" class=\"Button\">\n            Get Started →\n          </a>\n        </div>\n      </header>\n      <section class=\"Section Section--Features\">\n        <h3>Features</h3>\n        <ul class=\"FeatureList\">\n          <li class=\"FeatureItem\">\n            <h4>Easy to customize</h4>\n            <p>Text works like any regular Zdog shape, you can control the color, size, alignment, etc and update them at any time</p>\n          </li>\n          <li class=\"FeatureItem\">\n            <h4>Use any font</h4>\n            <p>Zfont is built on top of <a href=\"https://github.com/photopea/Typr.js\" target=\"_blank\">Typr.js</a>, which provides solid support for a wide range of .ttf and .otf fonts</p>\n          </li>\n          <li class=\"FeatureItem\">\n            <h4>Helpful extras</h4>\n            <p>A small collection of extra utilities help with measuring text, waiting for fonts to load, and more!</p>\n          </li>\n        </ul>\n      </section>\n      <section class=\"Section Section--Demo\">\n        <h3>Demo</h3>\n        <canvas class=\"Canvas\" width=\"720\" height=\"380\"></canvas>\n        <textarea class=\"Textarea\" name=\"\" id=\"textarea\" rows=\"3\">Zfont!&#13;&#10;A text plugin for&#13;&#10;the Zdog 3D engine</textarea>    \n      </section>\n      <footer class=\"Footer\">\n        Built by <a href=\"https://jamesdaniel.dev\">James Daniel</a>\n      </footer>\n    </main>\n    <script src=\"./demo.js\" charset=\"utf-8\"></script>\n  </body>\n</html>"
  },
  {
    "path": "deploy.sh",
    "content": "#!/usr/bin/env sh\n\n# abort on errors\nset -e\n\n# copy dist code into demo\ncp -a dist/. demo/\n\n# navigate into the build output directory\ncd demo\n\n# create commit\ngit init\ngit add -A\ngit commit -m 'deploy demo page'\n\n# force push commit to gh-pages branch\ngit push -f git@github.com:jaames/zfont.git master:gh-pages\n\n# navigate to last directory\ncd -"
  },
  {
    "path": "dist/zfont.es.js",
    "content": "/*!\n * Zfont v1.2.8\n * Text plugin for Zdog\n * 2019 James Daniel\n * MIT Licensed \n * github.com/jaames/zfont\n */\n\nvar Typr={};Typr.parse=function(buff){var bin=Typr._bin;var data=new Uint8Array(buff);var offset=0;var sfnt_version=bin.readFixed(data,offset);offset+=4;var numTables=bin.readUshort(data,offset);offset+=2;var searchRange=bin.readUshort(data,offset);offset+=2;var entrySelector=bin.readUshort(data,offset);offset+=2;var rangeShift=bin.readUshort(data,offset);offset+=2;var tags=[\"cmap\",\"head\",\"hhea\",\"maxp\",\"hmtx\",\"name\",\"OS/2\",\"post\",\"loca\",\"glyf\",\"kern\",\"CFF \",\"GPOS\",\"GSUB\",\"SVG \"];var obj={_data:data};var tabs={};for(var i=0;i<numTables;i++){var tag=bin.readASCII(data,offset,4);offset+=4;var checkSum=bin.readUint(data,offset);offset+=4;var toffset=bin.readUint(data,offset);offset+=4;var length=bin.readUint(data,offset);offset+=4;tabs[tag]={offset:toffset,length:length};}for(var i=0;i<tags.length;i++){var t=tags[i];if(tabs[t]){ obj[t.trim()]=Typr[t.trim()].parse(data,tabs[t].offset,tabs[t].length,obj); }}return obj};Typr._tabOffset=function(data,tab){var bin=Typr._bin;var numTables=bin.readUshort(data,4);var offset=12;for(var i=0;i<numTables;i++){var tag=bin.readASCII(data,offset,4);offset+=4;var checkSum=bin.readUint(data,offset);offset+=4;var toffset=bin.readUint(data,offset);offset+=4;var length=bin.readUint(data,offset);offset+=4;if(tag==tab){ return toffset }}return 0};Typr._bin={readFixed:function(data,o){return (data[o]<<8|data[o+1])+(data[o+2]<<8|data[o+3])/(256*256+4)},readF2dot14:function(data,o){var num=Typr._bin.readShort(data,o);return num/16384;},readInt:function(buff,p){var a=Typr._bin.t.uint8;a[0]=buff[p+3];a[1]=buff[p+2];a[2]=buff[p+1];a[3]=buff[p];return Typr._bin.t.int32[0]},readInt8:function(buff,p){var a=Typr._bin.t.uint8;a[0]=buff[p];return Typr._bin.t.int8[0]},readShort:function(buff,p){var a=Typr._bin.t.uint8;a[1]=buff[p];a[0]=buff[p+1];return Typr._bin.t.int16[0]},readUshort:function(buff,p){return buff[p]<<8|buff[p+1]},readUshorts:function(buff,p,len){var arr=[];for(var i=0;i<len;i++){ arr.push(Typr._bin.readUshort(buff,p+i*2)); }return arr},readUint:function(buff,p){var a=Typr._bin.t.uint8;a[3]=buff[p];a[2]=buff[p+1];a[1]=buff[p+2];a[0]=buff[p+3];return Typr._bin.t.uint32[0]},readUint64:function(buff,p){return Typr._bin.readUint(buff,p)*(4294967295+1)+Typr._bin.readUint(buff,p+4)},readASCII:function(buff,p,l){var s=\"\";for(var i=0;i<l;i++){ s+=String.fromCharCode(buff[p+i]); }return s},readUnicode:function(buff,p,l){var s=\"\";for(var i=0;i<l;i++){var c=buff[p++]<<8|buff[p++];s+=String.fromCharCode(c);}return s},_tdec:window[\"TextDecoder\"]?new window[\"TextDecoder\"]:null,readUTF8:function(buff,p,l){var tdec=Typr._bin._tdec;if(tdec&&p==0&&l==buff.length){ return tdec[\"decode\"](buff); }return Typr._bin.readASCII(buff,p,l)},readBytes:function(buff,p,l){var arr=[];for(var i=0;i<l;i++){ arr.push(buff[p+i]); }return arr},readASCIIArray:function(buff,p,l){var s=[];for(var i=0;i<l;i++){ s.push(String.fromCharCode(buff[p+i])); }return s}};Typr._bin.t={buff:new ArrayBuffer(8)};Typr._bin.t.int8=new Int8Array(Typr._bin.t.buff);Typr._bin.t.uint8=new Uint8Array(Typr._bin.t.buff);Typr._bin.t.int16=new Int16Array(Typr._bin.t.buff);Typr._bin.t.uint16=new Uint16Array(Typr._bin.t.buff);Typr._bin.t.int32=new Int32Array(Typr._bin.t.buff);Typr._bin.t.uint32=new Uint32Array(Typr._bin.t.buff);Typr._lctf={};Typr._lctf.parse=function(data,offset,length,font,subt){var bin=Typr._bin;var obj={};var offset0=offset;var tableVersion=bin.readFixed(data,offset);offset+=4;var offScriptList=bin.readUshort(data,offset);offset+=2;var offFeatureList=bin.readUshort(data,offset);offset+=2;var offLookupList=bin.readUshort(data,offset);offset+=2;obj.scriptList=Typr._lctf.readScriptList(data,offset0+offScriptList);obj.featureList=Typr._lctf.readFeatureList(data,offset0+offFeatureList);obj.lookupList=Typr._lctf.readLookupList(data,offset0+offLookupList,subt);return obj};Typr._lctf.readLookupList=function(data,offset,subt){var bin=Typr._bin;var offset0=offset;var obj=[];var count=bin.readUshort(data,offset);offset+=2;for(var i=0;i<count;i++){var noff=bin.readUshort(data,offset);offset+=2;var lut=Typr._lctf.readLookupTable(data,offset0+noff,subt);obj.push(lut);}return obj};Typr._lctf.readLookupTable=function(data,offset,subt){var bin=Typr._bin;var offset0=offset;var obj={tabs:[]};obj.ltype=bin.readUshort(data,offset);offset+=2;obj.flag=bin.readUshort(data,offset);offset+=2;var cnt=bin.readUshort(data,offset);offset+=2;for(var i=0;i<cnt;i++){var noff=bin.readUshort(data,offset);offset+=2;var tab=subt(data,obj.ltype,offset0+noff);obj.tabs.push(tab);}return obj};Typr._lctf.numOfOnes=function(n){var num=0;for(var i=0;i<32;i++){ if((n>>>i&1)!=0){ num++; } }return num};Typr._lctf.readClassDef=function(data,offset){var bin=Typr._bin;var obj=[];var format=bin.readUshort(data,offset);offset+=2;if(format==1){var startGlyph=bin.readUshort(data,offset);offset+=2;var glyphCount=bin.readUshort(data,offset);offset+=2;for(var i=0;i<glyphCount;i++){obj.push(startGlyph+i);obj.push(startGlyph+i);obj.push(bin.readUshort(data,offset));offset+=2;}}if(format==2){var count=bin.readUshort(data,offset);offset+=2;for(var i=0;i<count;i++){obj.push(bin.readUshort(data,offset));offset+=2;obj.push(bin.readUshort(data,offset));offset+=2;obj.push(bin.readUshort(data,offset));offset+=2;}}return obj};Typr._lctf.getInterval=function(tab,val){for(var i=0;i<tab.length;i+=3){var start=tab[i],end=tab[i+1],index=tab[i+2];if(start<=val&&val<=end){ return i }}return -1};Typr._lctf.readValueRecord=function(data,offset,valFmt){var bin=Typr._bin;var arr=[];arr.push(valFmt&1?bin.readShort(data,offset):0);offset+=valFmt&1?2:0;arr.push(valFmt&2?bin.readShort(data,offset):0);offset+=valFmt&2?2:0;arr.push(valFmt&4?bin.readShort(data,offset):0);offset+=valFmt&4?2:0;arr.push(valFmt&8?bin.readShort(data,offset):0);offset+=valFmt&8?2:0;return arr};Typr._lctf.readCoverage=function(data,offset){var bin=Typr._bin;var cvg={};cvg.fmt=bin.readUshort(data,offset);offset+=2;var count=bin.readUshort(data,offset);offset+=2;if(cvg.fmt==1){ cvg.tab=bin.readUshorts(data,offset,count); }if(cvg.fmt==2){ cvg.tab=bin.readUshorts(data,offset,count*3); }return cvg};Typr._lctf.coverageIndex=function(cvg,val){var tab=cvg.tab;if(cvg.fmt==1){ return tab.indexOf(val); }if(cvg.fmt==2){var ind=Typr._lctf.getInterval(tab,val);if(ind!=-1){ return tab[ind+2]+(val-tab[ind]) }}return -1};Typr._lctf.readFeatureList=function(data,offset){var bin=Typr._bin;var offset0=offset;var obj=[];var count=bin.readUshort(data,offset);offset+=2;for(var i=0;i<count;i++){var tag=bin.readASCII(data,offset,4);offset+=4;var noff=bin.readUshort(data,offset);offset+=2;obj.push({tag:tag.trim(),tab:Typr._lctf.readFeatureTable(data,offset0+noff)});}return obj};Typr._lctf.readFeatureTable=function(data,offset){var bin=Typr._bin;var featureParams=bin.readUshort(data,offset);offset+=2;var lookupCount=bin.readUshort(data,offset);offset+=2;var indices=[];for(var i=0;i<lookupCount;i++){ indices.push(bin.readUshort(data,offset+2*i)); }return indices};Typr._lctf.readScriptList=function(data,offset){var bin=Typr._bin;var offset0=offset;var obj={};var count=bin.readUshort(data,offset);offset+=2;for(var i=0;i<count;i++){var tag=bin.readASCII(data,offset,4);offset+=4;var noff=bin.readUshort(data,offset);offset+=2;obj[tag.trim()]=Typr._lctf.readScriptTable(data,offset0+noff);}return obj};Typr._lctf.readScriptTable=function(data,offset){var bin=Typr._bin;var offset0=offset;var obj={};var defLangSysOff=bin.readUshort(data,offset);offset+=2;obj.default=Typr._lctf.readLangSysTable(data,offset0+defLangSysOff);var langSysCount=bin.readUshort(data,offset);offset+=2;for(var i=0;i<langSysCount;i++){var tag=bin.readASCII(data,offset,4);offset+=4;var langSysOff=bin.readUshort(data,offset);offset+=2;obj[tag.trim()]=Typr._lctf.readLangSysTable(data,offset0+langSysOff);}return obj};Typr._lctf.readLangSysTable=function(data,offset){var bin=Typr._bin;var obj={};var lookupOrder=bin.readUshort(data,offset);offset+=2;obj.reqFeature=bin.readUshort(data,offset);offset+=2;var featureCount=bin.readUshort(data,offset);offset+=2;obj.features=bin.readUshorts(data,offset,featureCount);return obj};Typr.CFF={};Typr.CFF.parse=function(data,offset,length){var bin=Typr._bin;data=new Uint8Array(data.buffer,offset,length);offset=0;var major=data[offset];offset++;var minor=data[offset];offset++;var hdrSize=data[offset];offset++;var offsize=data[offset];offset++;var ninds=[];offset=Typr.CFF.readIndex(data,offset,ninds);var names=[];for(var i=0;i<ninds.length-1;i++){ names.push(bin.readASCII(data,offset+ninds[i],ninds[i+1]-ninds[i])); }offset+=ninds[ninds.length-1];var tdinds=[];offset=Typr.CFF.readIndex(data,offset,tdinds);var topDicts=[];for(var i=0;i<tdinds.length-1;i++){ topDicts.push(Typr.CFF.readDict(data,offset+tdinds[i],offset+tdinds[i+1])); }offset+=tdinds[tdinds.length-1];var topdict=topDicts[0];var sinds=[];offset=Typr.CFF.readIndex(data,offset,sinds);var strings=[];for(var i=0;i<sinds.length-1;i++){ strings.push(bin.readASCII(data,offset+sinds[i],sinds[i+1]-sinds[i])); }offset+=sinds[sinds.length-1];Typr.CFF.readSubrs(data,offset,topdict);if(topdict.CharStrings){offset=topdict.CharStrings;var sinds=[];offset=Typr.CFF.readIndex(data,offset,sinds);var cstr=[];for(var i=0;i<sinds.length-1;i++){ cstr.push(bin.readBytes(data,offset+sinds[i],sinds[i+1]-sinds[i])); }topdict.CharStrings=cstr;}if(topdict.Encoding){ topdict.Encoding=Typr.CFF.readEncoding(data,topdict.Encoding,topdict.CharStrings.length); }if(topdict.charset){ topdict.charset=Typr.CFF.readCharset(data,topdict.charset,topdict.CharStrings.length); }if(topdict.Private){offset=topdict.Private[1];topdict.Private=Typr.CFF.readDict(data,offset,offset+topdict.Private[0]);if(topdict.Private.Subrs){ Typr.CFF.readSubrs(data,offset+topdict.Private.Subrs,topdict.Private); }}var obj={};for(var p in topdict){if([\"FamilyName\",\"FullName\",\"Notice\",\"version\",\"Copyright\"].indexOf(p)!=-1){ obj[p]=strings[topdict[p]-426+35]; }else { obj[p]=topdict[p]; }}return obj};Typr.CFF.readSubrs=function(data,offset,obj){var bin=Typr._bin;var gsubinds=[];offset=Typr.CFF.readIndex(data,offset,gsubinds);var bias,nSubrs=gsubinds.length;if(nSubrs<1240){ bias=107; }else if(nSubrs<33900){ bias=1131; }else { bias=32768; }obj.Bias=bias;obj.Subrs=[];for(var i=0;i<gsubinds.length-1;i++){ obj.Subrs.push(bin.readBytes(data,offset+gsubinds[i],gsubinds[i+1]-gsubinds[i])); }};Typr.CFF.tableSE=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,0,111,112,113,114,0,115,116,117,118,119,120,121,122,0,123,0,124,125,126,127,128,129,130,131,0,132,133,0,134,135,136,137,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,0,139,0,0,0,0,140,141,142,143,0,0,0,0,0,144,0,0,0,145,0,0,146,147,148,149,0,0,0,0];Typr.CFF.glyphByUnicode=function(cff,code){for(var i=0;i<cff.charset.length;i++){ if(cff.charset[i]==code){ return i; } }return -1};Typr.CFF.glyphBySE=function(cff,charcode){if(charcode<0||charcode>255){ return -1; }return Typr.CFF.glyphByUnicode(cff,Typr.CFF.tableSE[charcode])};Typr.CFF.readEncoding=function(data,offset,num){var bin=Typr._bin;var array=[\".notdef\"];var format=data[offset];offset++;if(format==0){var nCodes=data[offset];offset++;for(var i=0;i<nCodes;i++){ array.push(data[offset+i]); }}else { throw \"error: unknown encoding format: \"+format; }return array};Typr.CFF.readCharset=function(data,offset,num){var bin=Typr._bin;var charset=[\".notdef\"];var format=data[offset];offset++;if(format==0){for(var i=0;i<num;i++){var first=bin.readUshort(data,offset);offset+=2;charset.push(first);}}else if(format==1||format==2){while(charset.length<num){var first=bin.readUshort(data,offset);offset+=2;var nLeft=0;if(format==1){nLeft=data[offset];offset++;}else {nLeft=bin.readUshort(data,offset);offset+=2;}for(var i=0;i<=nLeft;i++){charset.push(first);first++;}}}else { throw \"error: format: \"+format; }return charset};Typr.CFF.readIndex=function(data,offset,inds){var bin=Typr._bin;var count=bin.readUshort(data,offset);offset+=2;var offsize=data[offset];offset++;if(offsize==1){ for(var i=0;i<count+1;i++){ inds.push(data[offset+i]); } }else if(offsize==2){ for(var i=0;i<count+1;i++){ inds.push(bin.readUshort(data,offset+i*2)); } }else if(offsize==3){ for(var i=0;i<count+1;i++){ inds.push(bin.readUint(data,offset+i*3-1)&16777215); } }else if(count!=0){ throw \"unsupported offset size: \"+offsize+\", count: \"+count; }offset+=(count+1)*offsize;return offset-1};Typr.CFF.getCharString=function(data,offset,o){var bin=Typr._bin;var b0=data[offset],b1=data[offset+1],b2=data[offset+2],b3=data[offset+3],b4=data[offset+4];var vs=1;var op=null,val=null;if(b0<=20){op=b0;vs=1;}if(b0==12){op=b0*100+b1;vs=2;}if(21<=b0&&b0<=27){op=b0;vs=1;}if(b0==28){val=bin.readShort(data,offset+1);vs=3;}if(29<=b0&&b0<=31){op=b0;vs=1;}if(32<=b0&&b0<=246){val=b0-139;vs=1;}if(247<=b0&&b0<=250){val=(b0-247)*256+b1+108;vs=2;}if(251<=b0&&b0<=254){val=-(b0-251)*256-b1-108;vs=2;}if(b0==255){val=bin.readInt(data,offset+1)/65535;vs=5;}o.val=val!=null?val:\"o\"+op;o.size=vs;};Typr.CFF.readCharString=function(data,offset,length){var end=offset+length;var bin=Typr._bin;var arr=[];while(offset<end){var b0=data[offset],b1=data[offset+1],b2=data[offset+2],b3=data[offset+3],b4=data[offset+4];var vs=1;var op=null,val=null;if(b0<=20){op=b0;vs=1;}if(b0==12){op=b0*100+b1;vs=2;}if(b0==19||b0==20){op=b0;vs=2;}if(21<=b0&&b0<=27){op=b0;vs=1;}if(b0==28){val=bin.readShort(data,offset+1);vs=3;}if(29<=b0&&b0<=31){op=b0;vs=1;}if(32<=b0&&b0<=246){val=b0-139;vs=1;}if(247<=b0&&b0<=250){val=(b0-247)*256+b1+108;vs=2;}if(251<=b0&&b0<=254){val=-(b0-251)*256-b1-108;vs=2;}if(b0==255){val=bin.readInt(data,offset+1)/65535;vs=5;}arr.push(val!=null?val:\"o\"+op);offset+=vs;}return arr};Typr.CFF.readDict=function(data,offset,end){var bin=Typr._bin;var dict={};var carr=[];while(offset<end){var b0=data[offset],b1=data[offset+1],b2=data[offset+2],b3=data[offset+3],b4=data[offset+4];var vs=1;var key=null,val=null;if(b0==28){val=bin.readShort(data,offset+1);vs=3;}if(b0==29){val=bin.readInt(data,offset+1);vs=5;}if(32<=b0&&b0<=246){val=b0-139;vs=1;}if(247<=b0&&b0<=250){val=(b0-247)*256+b1+108;vs=2;}if(251<=b0&&b0<=254){val=-(b0-251)*256-b1-108;vs=2;}if(b0==255){val=bin.readInt(data,offset+1)/65535;vs=5;throw \"unknown number\"}if(b0==30){var nibs=[];vs=1;while(true){var b=data[offset+vs];vs++;var nib0=b>>4,nib1=b&15;if(nib0!=15){ nibs.push(nib0); }if(nib1!=15){ nibs.push(nib1); }if(nib1==15){ break }}var s=\"\";var chars=[0,1,2,3,4,5,6,7,8,9,\".\",\"e\",\"e-\",\"reserved\",\"-\",\"endOfNumber\"];for(var i=0;i<nibs.length;i++){ s+=chars[nibs[i]]; }val=parseFloat(s);}if(b0<=21){var keys=[\"version\",\"Notice\",\"FullName\",\"FamilyName\",\"Weight\",\"FontBBox\",\"BlueValues\",\"OtherBlues\",\"FamilyBlues\",\"FamilyOtherBlues\",\"StdHW\",\"StdVW\",\"escape\",\"UniqueID\",\"XUID\",\"charset\",\"Encoding\",\"CharStrings\",\"Private\",\"Subrs\",\"defaultWidthX\",\"nominalWidthX\"];key=keys[b0];vs=1;if(b0==12){var keys=[\"Copyright\",\"isFixedPitch\",\"ItalicAngle\",\"UnderlinePosition\",\"UnderlineThickness\",\"PaintType\",\"CharstringType\",\"FontMatrix\",\"StrokeWidth\",\"BlueScale\",\"BlueShift\",\"BlueFuzz\",\"StemSnapH\",\"StemSnapV\",\"ForceBold\",0,0,\"LanguageGroup\",\"ExpansionFactor\",\"initialRandomSeed\",\"SyntheticBase\",\"PostScript\",\"BaseFontName\",\"BaseFontBlend\",0,0,0,0,0,0,\"ROS\",\"CIDFontVersion\",\"CIDFontRevision\",\"CIDFontType\",\"CIDCount\",\"UIDBase\",\"FDArray\",\"FDSelect\",\"FontName\"];key=keys[b1];vs=2;}}if(key!=null){dict[key]=carr.length==1?carr[0]:carr;carr=[];}else { carr.push(val); }offset+=vs;}return dict};Typr.cmap={};Typr.cmap.parse=function(data,offset,length){data=new Uint8Array(data.buffer,offset,length);offset=0;var bin=Typr._bin;var obj={};var version=bin.readUshort(data,offset);offset+=2;var numTables=bin.readUshort(data,offset);offset+=2;var offs=[];obj.tables=[];for(var i=0;i<numTables;i++){var platformID=bin.readUshort(data,offset);offset+=2;var encodingID=bin.readUshort(data,offset);offset+=2;var noffset=bin.readUint(data,offset);offset+=4;var id=\"p\"+platformID+\"e\"+encodingID;var tind=offs.indexOf(noffset);if(tind==-1){tind=obj.tables.length;var subt;offs.push(noffset);var format=bin.readUshort(data,noffset);if(format==0){ subt=Typr.cmap.parse0(data,noffset); }else if(format==4){ subt=Typr.cmap.parse4(data,noffset); }else if(format==6){ subt=Typr.cmap.parse6(data,noffset); }else if(format==12){ subt=Typr.cmap.parse12(data,noffset); }else { console.log(\"unknown format: \"+format,platformID,encodingID,noffset); }obj.tables.push(subt);}if(obj[id]!=null){ throw \"multiple tables for one platform+encoding\"; }obj[id]=tind;}return obj};Typr.cmap.parse0=function(data,offset){var bin=Typr._bin;var obj={};obj.format=bin.readUshort(data,offset);offset+=2;var len=bin.readUshort(data,offset);offset+=2;var lang=bin.readUshort(data,offset);offset+=2;obj.map=[];for(var i=0;i<len-6;i++){ obj.map.push(data[offset+i]); }return obj};Typr.cmap.parse4=function(data,offset){var bin=Typr._bin;var offset0=offset;var obj={};obj.format=bin.readUshort(data,offset);offset+=2;var length=bin.readUshort(data,offset);offset+=2;var language=bin.readUshort(data,offset);offset+=2;var segCountX2=bin.readUshort(data,offset);offset+=2;var segCount=segCountX2/2;obj.searchRange=bin.readUshort(data,offset);offset+=2;obj.entrySelector=bin.readUshort(data,offset);offset+=2;obj.rangeShift=bin.readUshort(data,offset);offset+=2;obj.endCount=bin.readUshorts(data,offset,segCount);offset+=segCount*2;offset+=2;obj.startCount=bin.readUshorts(data,offset,segCount);offset+=segCount*2;obj.idDelta=[];for(var i=0;i<segCount;i++){obj.idDelta.push(bin.readShort(data,offset));offset+=2;}obj.idRangeOffset=bin.readUshorts(data,offset,segCount);offset+=segCount*2;obj.glyphIdArray=[];while(offset<offset0+length){obj.glyphIdArray.push(bin.readUshort(data,offset));offset+=2;}return obj};Typr.cmap.parse6=function(data,offset){var bin=Typr._bin;var obj={};obj.format=bin.readUshort(data,offset);offset+=2;var length=bin.readUshort(data,offset);offset+=2;var language=bin.readUshort(data,offset);offset+=2;obj.firstCode=bin.readUshort(data,offset);offset+=2;var entryCount=bin.readUshort(data,offset);offset+=2;obj.glyphIdArray=[];for(var i=0;i<entryCount;i++){obj.glyphIdArray.push(bin.readUshort(data,offset));offset+=2;}return obj};Typr.cmap.parse12=function(data,offset){var bin=Typr._bin;var obj={};obj.format=bin.readUshort(data,offset);offset+=2;offset+=2;var length=bin.readUint(data,offset);offset+=4;var lang=bin.readUint(data,offset);offset+=4;var nGroups=bin.readUint(data,offset);offset+=4;obj.groups=[];for(var i=0;i<nGroups;i++){var off=offset+i*12;var startCharCode=bin.readUint(data,off+0);var endCharCode=bin.readUint(data,off+4);var startGlyphID=bin.readUint(data,off+8);obj.groups.push([startCharCode,endCharCode,startGlyphID]);}return obj};Typr.glyf={};Typr.glyf.parse=function(data,offset,length,font){var obj=[];for(var g=0;g<font.maxp.numGlyphs;g++){ obj.push(null); }return obj};Typr.glyf._parseGlyf=function(font,g){var bin=Typr._bin;var data=font._data;var offset=Typr._tabOffset(data,\"glyf\")+font.loca[g];if(font.loca[g]==font.loca[g+1]){ return null; }var gl={};gl.noc=bin.readShort(data,offset);offset+=2;gl.xMin=bin.readShort(data,offset);offset+=2;gl.yMin=bin.readShort(data,offset);offset+=2;gl.xMax=bin.readShort(data,offset);offset+=2;gl.yMax=bin.readShort(data,offset);offset+=2;if(gl.xMin>=gl.xMax||gl.yMin>=gl.yMax){ return null; }if(gl.noc>0){gl.endPts=[];for(var i=0;i<gl.noc;i++){gl.endPts.push(bin.readUshort(data,offset));offset+=2;}var instructionLength=bin.readUshort(data,offset);offset+=2;if(data.length-offset<instructionLength){ return null; }gl.instructions=bin.readBytes(data,offset,instructionLength);offset+=instructionLength;var crdnum=gl.endPts[gl.noc-1]+1;gl.flags=[];for(var i=0;i<crdnum;i++){var flag=data[offset];offset++;gl.flags.push(flag);if((flag&8)!=0){var rep=data[offset];offset++;for(var j=0;j<rep;j++){gl.flags.push(flag);i++;}}}gl.xs=[];for(var i=0;i<crdnum;i++){var i8=(gl.flags[i]&2)!=0,same=(gl.flags[i]&16)!=0;if(i8){gl.xs.push(same?data[offset]:-data[offset]);offset++;}else {if(same){ gl.xs.push(0); }else {gl.xs.push(bin.readShort(data,offset));offset+=2;}}}gl.ys=[];for(var i=0;i<crdnum;i++){var i8=(gl.flags[i]&4)!=0,same=(gl.flags[i]&32)!=0;if(i8){gl.ys.push(same?data[offset]:-data[offset]);offset++;}else {if(same){ gl.ys.push(0); }else {gl.ys.push(bin.readShort(data,offset));offset+=2;}}}var x=0,y=0;for(var i=0;i<crdnum;i++){x+=gl.xs[i];y+=gl.ys[i];gl.xs[i]=x;gl.ys[i]=y;}}else {var ARG_1_AND_2_ARE_WORDS=1<<0;var ARGS_ARE_XY_VALUES=1<<1;var WE_HAVE_A_SCALE=1<<3;var MORE_COMPONENTS=1<<5;var WE_HAVE_AN_X_AND_Y_SCALE=1<<6;var WE_HAVE_A_TWO_BY_TWO=1<<7;var WE_HAVE_INSTRUCTIONS=1<<8;gl.parts=[];var flags;do{flags=bin.readUshort(data,offset);offset+=2;var part={m:{a:1,b:0,c:0,d:1,tx:0,ty:0},p1:-1,p2:-1};gl.parts.push(part);part.glyphIndex=bin.readUshort(data,offset);offset+=2;if(flags&ARG_1_AND_2_ARE_WORDS){var arg1=bin.readShort(data,offset);offset+=2;var arg2=bin.readShort(data,offset);offset+=2;}else {var arg1=bin.readInt8(data,offset);offset++;var arg2=bin.readInt8(data,offset);offset++;}if(flags&ARGS_ARE_XY_VALUES){part.m.tx=arg1;part.m.ty=arg2;}else {part.p1=arg1;part.p2=arg2;}if(flags&WE_HAVE_A_SCALE){part.m.a=part.m.d=bin.readF2dot14(data,offset);offset+=2;}else if(flags&WE_HAVE_AN_X_AND_Y_SCALE){part.m.a=bin.readF2dot14(data,offset);offset+=2;part.m.d=bin.readF2dot14(data,offset);offset+=2;}else if(flags&WE_HAVE_A_TWO_BY_TWO){part.m.a=bin.readF2dot14(data,offset);offset+=2;part.m.b=bin.readF2dot14(data,offset);offset+=2;part.m.c=bin.readF2dot14(data,offset);offset+=2;part.m.d=bin.readF2dot14(data,offset);offset+=2;}}while(flags&MORE_COMPONENTS);if(flags&WE_HAVE_INSTRUCTIONS){var numInstr=bin.readUshort(data,offset);offset+=2;gl.instr=[];for(var i=0;i<numInstr;i++){gl.instr.push(data[offset]);offset++;}}}return gl};Typr.GPOS={};Typr.GPOS.parse=function(data,offset,length,font){return Typr._lctf.parse(data,offset,length,font,Typr.GPOS.subt)};Typr.GPOS.subt=function(data,ltype,offset){if(ltype!=2){ return null; }var bin=Typr._bin,offset0=offset,tab={};tab.format=bin.readUshort(data,offset);offset+=2;var covOff=bin.readUshort(data,offset);offset+=2;tab.coverage=Typr._lctf.readCoverage(data,covOff+offset0);tab.valFmt1=bin.readUshort(data,offset);offset+=2;tab.valFmt2=bin.readUshort(data,offset);offset+=2;var ones1=Typr._lctf.numOfOnes(tab.valFmt1);var ones2=Typr._lctf.numOfOnes(tab.valFmt2);if(tab.format==1){tab.pairsets=[];var count=bin.readUshort(data,offset);offset+=2;for(var i=0;i<count;i++){var psoff=bin.readUshort(data,offset);offset+=2;psoff+=offset0;var pvcount=bin.readUshort(data,psoff);psoff+=2;var arr=[];for(var j=0;j<pvcount;j++){var gid2=bin.readUshort(data,psoff);psoff+=2;var value1,value2;if(tab.valFmt1!=0){value1=Typr._lctf.readValueRecord(data,psoff,tab.valFmt1);psoff+=ones1*2;}if(tab.valFmt2!=0){value2=Typr._lctf.readValueRecord(data,psoff,tab.valFmt2);psoff+=ones2*2;}arr.push({gid2:gid2,val1:value1,val2:value2});}tab.pairsets.push(arr);}}if(tab.format==2){var classDef1=bin.readUshort(data,offset);offset+=2;var classDef2=bin.readUshort(data,offset);offset+=2;var class1Count=bin.readUshort(data,offset);offset+=2;var class2Count=bin.readUshort(data,offset);offset+=2;tab.classDef1=Typr._lctf.readClassDef(data,offset0+classDef1);tab.classDef2=Typr._lctf.readClassDef(data,offset0+classDef2);tab.matrix=[];for(var i=0;i<class1Count;i++){var row=[];for(var j=0;j<class2Count;j++){var value1=null,value2=null;if(tab.valFmt1!=0){value1=Typr._lctf.readValueRecord(data,offset,tab.valFmt1);offset+=ones1*2;}if(tab.valFmt2!=0){value2=Typr._lctf.readValueRecord(data,offset,tab.valFmt2);offset+=ones2*2;}row.push({val1:value1,val2:value2});}tab.matrix.push(row);}}return tab};Typr.GSUB={};Typr.GSUB.parse=function(data,offset,length,font){return Typr._lctf.parse(data,offset,length,font,Typr.GSUB.subt)};Typr.GSUB.subt=function(data,ltype,offset){var bin=Typr._bin,offset0=offset,tab={};if(ltype!=1&&ltype!=4&&ltype!=5){ return null; }tab.fmt=bin.readUshort(data,offset);offset+=2;var covOff=bin.readUshort(data,offset);offset+=2;tab.coverage=Typr._lctf.readCoverage(data,covOff+offset0);if(ltype==1){if(tab.fmt==1){tab.delta=bin.readShort(data,offset);offset+=2;}else if(tab.fmt==2){var cnt=bin.readUshort(data,offset);offset+=2;tab.newg=bin.readUshorts(data,offset,cnt);offset+=tab.newg.length*2;}}else if(ltype==4){tab.vals=[];var cnt=bin.readUshort(data,offset);offset+=2;for(var i=0;i<cnt;i++){var loff=bin.readUshort(data,offset);offset+=2;tab.vals.push(Typr.GSUB.readLigatureSet(data,offset0+loff));}}else if(ltype==5){if(tab.fmt==2){var cDefOffset=bin.readUshort(data,offset);offset+=2;tab.cDef=Typr._lctf.readClassDef(data,offset0+cDefOffset);tab.scset=[];var subClassSetCount=bin.readUshort(data,offset);offset+=2;for(var i=0;i<subClassSetCount;i++){var scsOff=bin.readUshort(data,offset);offset+=2;tab.scset.push(scsOff==0?null:Typr.GSUB.readSubClassSet(data,offset0+scsOff));}}else { console.log(\"unknown table format\",tab.fmt); }}return tab};Typr.GSUB.readSubClassSet=function(data,offset){var rUs=Typr._bin.readUshort,offset0=offset,lset=[];var cnt=rUs(data,offset);offset+=2;for(var i=0;i<cnt;i++){var loff=rUs(data,offset);offset+=2;lset.push(Typr.GSUB.readSubClassRule(data,offset0+loff));}return lset};Typr.GSUB.readSubClassRule=function(data,offset){var rUs=Typr._bin.readUshort,rule={};var gcount=rUs(data,offset);offset+=2;var scount=rUs(data,offset);offset+=2;rule.input=[];for(var i=0;i<gcount-1;i++){rule.input.push(rUs(data,offset));offset+=2;}rule.substLookupRecords=Typr.GSUB.readSubstLookupRecords(data,offset,scount);return rule};Typr.GSUB.readSubstLookupRecords=function(data,offset,cnt){var rUs=Typr._bin.readUshort;var out=[];for(var i=0;i<cnt;i++){out.push(rUs(data,offset),rUs(data,offset+2));offset+=4;}return out};Typr.GSUB.readChainSubClassSet=function(data,offset){var bin=Typr._bin,offset0=offset,lset=[];var cnt=bin.readUshort(data,offset);offset+=2;for(var i=0;i<cnt;i++){var loff=bin.readUshort(data,offset);offset+=2;lset.push(Typr.GSUB.readChainSubClassRule(data,offset0+loff));}return lset};Typr.GSUB.readChainSubClassRule=function(data,offset){var bin=Typr._bin,rule={};var pps=[\"backtrack\",\"input\",\"lookahead\"];for(var pi=0;pi<pps.length;pi++){var cnt=bin.readUshort(data,offset);offset+=2;if(pi==1){ cnt--; }rule[pps[pi]]=bin.readUshorts(data,offset,cnt);offset+=rule[pps[pi]].length*2;}var cnt=bin.readUshort(data,offset);offset+=2;rule.subst=bin.readUshorts(data,offset,cnt*2);offset+=rule.subst.length*2;return rule};Typr.GSUB.readLigatureSet=function(data,offset){var bin=Typr._bin,offset0=offset,lset=[];var lcnt=bin.readUshort(data,offset);offset+=2;for(var j=0;j<lcnt;j++){var loff=bin.readUshort(data,offset);offset+=2;lset.push(Typr.GSUB.readLigature(data,offset0+loff));}return lset};Typr.GSUB.readLigature=function(data,offset){var bin=Typr._bin,lig={chain:[]};lig.nglyph=bin.readUshort(data,offset);offset+=2;var ccnt=bin.readUshort(data,offset);offset+=2;for(var k=0;k<ccnt-1;k++){lig.chain.push(bin.readUshort(data,offset));offset+=2;}return lig};Typr.head={};Typr.head.parse=function(data,offset,length){var bin=Typr._bin;var obj={};var tableVersion=bin.readFixed(data,offset);offset+=4;obj.fontRevision=bin.readFixed(data,offset);offset+=4;var checkSumAdjustment=bin.readUint(data,offset);offset+=4;var magicNumber=bin.readUint(data,offset);offset+=4;obj.flags=bin.readUshort(data,offset);offset+=2;obj.unitsPerEm=bin.readUshort(data,offset);offset+=2;obj.created=bin.readUint64(data,offset);offset+=8;obj.modified=bin.readUint64(data,offset);offset+=8;obj.xMin=bin.readShort(data,offset);offset+=2;obj.yMin=bin.readShort(data,offset);offset+=2;obj.xMax=bin.readShort(data,offset);offset+=2;obj.yMax=bin.readShort(data,offset);offset+=2;obj.macStyle=bin.readUshort(data,offset);offset+=2;obj.lowestRecPPEM=bin.readUshort(data,offset);offset+=2;obj.fontDirectionHint=bin.readShort(data,offset);offset+=2;obj.indexToLocFormat=bin.readShort(data,offset);offset+=2;obj.glyphDataFormat=bin.readShort(data,offset);offset+=2;return obj};Typr.hhea={};Typr.hhea.parse=function(data,offset,length){var bin=Typr._bin;var obj={};var tableVersion=bin.readFixed(data,offset);offset+=4;obj.ascender=bin.readShort(data,offset);offset+=2;obj.descender=bin.readShort(data,offset);offset+=2;obj.lineGap=bin.readShort(data,offset);offset+=2;obj.advanceWidthMax=bin.readUshort(data,offset);offset+=2;obj.minLeftSideBearing=bin.readShort(data,offset);offset+=2;obj.minRightSideBearing=bin.readShort(data,offset);offset+=2;obj.xMaxExtent=bin.readShort(data,offset);offset+=2;obj.caretSlopeRise=bin.readShort(data,offset);offset+=2;obj.caretSlopeRun=bin.readShort(data,offset);offset+=2;obj.caretOffset=bin.readShort(data,offset);offset+=2;offset+=4*2;obj.metricDataFormat=bin.readShort(data,offset);offset+=2;obj.numberOfHMetrics=bin.readUshort(data,offset);offset+=2;return obj};Typr.hmtx={};Typr.hmtx.parse=function(data,offset,length,font){var bin=Typr._bin;var obj={};obj.aWidth=[];obj.lsBearing=[];var aw=0,lsb=0;for(var i=0;i<font.maxp.numGlyphs;i++){if(i<font.hhea.numberOfHMetrics){aw=bin.readUshort(data,offset);offset+=2;lsb=bin.readShort(data,offset);offset+=2;}obj.aWidth.push(aw);obj.lsBearing.push(lsb);}return obj};Typr.kern={};Typr.kern.parse=function(data,offset,length,font){var bin=Typr._bin;var version=bin.readUshort(data,offset);offset+=2;if(version==1){ return Typr.kern.parseV1(data,offset-2,length,font); }var nTables=bin.readUshort(data,offset);offset+=2;var map={glyph1:[],rval:[]};for(var i=0;i<nTables;i++){offset+=2;var length=bin.readUshort(data,offset);offset+=2;var coverage=bin.readUshort(data,offset);offset+=2;var format=coverage>>>8;format&=15;if(format==0){ offset=Typr.kern.readFormat0(data,offset,map); }else { throw \"unknown kern table format: \"+format }}return map};Typr.kern.parseV1=function(data,offset,length,font){var bin=Typr._bin;var version=bin.readFixed(data,offset);offset+=4;var nTables=bin.readUint(data,offset);offset+=4;var map={glyph1:[],rval:[]};for(var i=0;i<nTables;i++){var length=bin.readUint(data,offset);offset+=4;var coverage=bin.readUshort(data,offset);offset+=2;var tupleIndex=bin.readUshort(data,offset);offset+=2;var format=coverage>>>8;format&=15;if(format==0){ offset=Typr.kern.readFormat0(data,offset,map); }else { throw \"unknown kern table format: \"+format }}return map};Typr.kern.readFormat0=function(data,offset,map){var bin=Typr._bin;var pleft=-1;var nPairs=bin.readUshort(data,offset);offset+=2;var searchRange=bin.readUshort(data,offset);offset+=2;var entrySelector=bin.readUshort(data,offset);offset+=2;var rangeShift=bin.readUshort(data,offset);offset+=2;for(var j=0;j<nPairs;j++){var left=bin.readUshort(data,offset);offset+=2;var right=bin.readUshort(data,offset);offset+=2;var value=bin.readShort(data,offset);offset+=2;if(left!=pleft){map.glyph1.push(left);map.rval.push({glyph2:[],vals:[]});}var rval=map.rval[map.rval.length-1];rval.glyph2.push(right);rval.vals.push(value);pleft=left;}return offset};Typr.loca={};Typr.loca.parse=function(data,offset,length,font){var bin=Typr._bin;var obj=[];var ver=font.head.indexToLocFormat;var len=font.maxp.numGlyphs+1;if(ver==0){ for(var i=0;i<len;i++){ obj.push(bin.readUshort(data,offset+(i<<1))<<1); } }if(ver==1){ for(var i=0;i<len;i++){ obj.push(bin.readUint(data,offset+(i<<2))); } }return obj};Typr.maxp={};Typr.maxp.parse=function(data,offset,length){var bin=Typr._bin;var obj={};var ver=bin.readUint(data,offset);offset+=4;obj.numGlyphs=bin.readUshort(data,offset);offset+=2;if(ver==65536){obj.maxPoints=bin.readUshort(data,offset);offset+=2;obj.maxContours=bin.readUshort(data,offset);offset+=2;obj.maxCompositePoints=bin.readUshort(data,offset);offset+=2;obj.maxCompositeContours=bin.readUshort(data,offset);offset+=2;obj.maxZones=bin.readUshort(data,offset);offset+=2;obj.maxTwilightPoints=bin.readUshort(data,offset);offset+=2;obj.maxStorage=bin.readUshort(data,offset);offset+=2;obj.maxFunctionDefs=bin.readUshort(data,offset);offset+=2;obj.maxInstructionDefs=bin.readUshort(data,offset);offset+=2;obj.maxStackElements=bin.readUshort(data,offset);offset+=2;obj.maxSizeOfInstructions=bin.readUshort(data,offset);offset+=2;obj.maxComponentElements=bin.readUshort(data,offset);offset+=2;obj.maxComponentDepth=bin.readUshort(data,offset);offset+=2;}return obj};Typr.name={};Typr.name.parse=function(data,offset,length){var bin=Typr._bin;var obj={};var format=bin.readUshort(data,offset);offset+=2;var count=bin.readUshort(data,offset);offset+=2;var stringOffset=bin.readUshort(data,offset);offset+=2;var offset0=offset;for(var i=0;i<count;i++){var platformID=bin.readUshort(data,offset);offset+=2;var encodingID=bin.readUshort(data,offset);offset+=2;var languageID=bin.readUshort(data,offset);offset+=2;var nameID=bin.readUshort(data,offset);offset+=2;var length=bin.readUshort(data,offset);offset+=2;var noffset=bin.readUshort(data,offset);offset+=2;var plat=\"p\"+platformID;if(obj[plat]==null){ obj[plat]={}; }var names=[\"copyright\",\"fontFamily\",\"fontSubfamily\",\"ID\",\"fullName\",\"version\",\"postScriptName\",\"trademark\",\"manufacturer\",\"designer\",\"description\",\"urlVendor\",\"urlDesigner\",\"licence\",\"licenceURL\",\"---\",\"typoFamilyName\",\"typoSubfamilyName\",\"compatibleFull\",\"sampleText\",\"postScriptCID\",\"wwsFamilyName\",\"wwsSubfamilyName\",\"lightPalette\",\"darkPalette\"];var cname=names[nameID];var soff=offset0+count*12+noffset;var str;if(platformID==0){ str=bin.readUnicode(data,soff,length/2); }else if(platformID==3&&encodingID==0){ str=bin.readUnicode(data,soff,length/2); }else if(encodingID==0){ str=bin.readASCII(data,soff,length); }else if(encodingID==1){ str=bin.readUnicode(data,soff,length/2); }else if(encodingID==3){ str=bin.readUnicode(data,soff,length/2); }else if(platformID==1){str=bin.readASCII(data,soff,length);console.log(\"reading unknown MAC encoding \"+encodingID+\" as ASCII\");}else { throw \"unknown encoding \"+encodingID+\", platformID: \"+platformID; }obj[plat][cname]=str;obj[plat]._lang=languageID;}for(var p in obj){ if(obj[p].postScriptName!=null&&obj[p]._lang==1033){ return obj[p]; } }for(var p in obj){ if(obj[p].postScriptName!=null&&obj[p]._lang==3084){ return obj[p]; } }for(var p in obj){ if(obj[p].postScriptName!=null){ return obj[p]; } }var tname;for(var p in obj){tname=p;break}console.log(\"returning name table with languageID \"+obj[tname]._lang);return obj[tname]};Typr[\"OS/2\"]={};Typr[\"OS/2\"].parse=function(data,offset,length){var bin=Typr._bin;var ver=bin.readUshort(data,offset);offset+=2;var obj={};if(ver==0){ Typr[\"OS/2\"].version0(data,offset,obj); }else if(ver==1){ Typr[\"OS/2\"].version1(data,offset,obj); }else if(ver==2||ver==3||ver==4){ Typr[\"OS/2\"].version2(data,offset,obj); }else if(ver==5){ Typr[\"OS/2\"].version5(data,offset,obj); }else { throw \"unknown OS/2 table version: \"+ver; }return obj};Typr[\"OS/2\"].version0=function(data,offset,obj){var bin=Typr._bin;obj.xAvgCharWidth=bin.readShort(data,offset);offset+=2;obj.usWeightClass=bin.readUshort(data,offset);offset+=2;obj.usWidthClass=bin.readUshort(data,offset);offset+=2;obj.fsType=bin.readUshort(data,offset);offset+=2;obj.ySubscriptXSize=bin.readShort(data,offset);offset+=2;obj.ySubscriptYSize=bin.readShort(data,offset);offset+=2;obj.ySubscriptXOffset=bin.readShort(data,offset);offset+=2;obj.ySubscriptYOffset=bin.readShort(data,offset);offset+=2;obj.ySuperscriptXSize=bin.readShort(data,offset);offset+=2;obj.ySuperscriptYSize=bin.readShort(data,offset);offset+=2;obj.ySuperscriptXOffset=bin.readShort(data,offset);offset+=2;obj.ySuperscriptYOffset=bin.readShort(data,offset);offset+=2;obj.yStrikeoutSize=bin.readShort(data,offset);offset+=2;obj.yStrikeoutPosition=bin.readShort(data,offset);offset+=2;obj.sFamilyClass=bin.readShort(data,offset);offset+=2;obj.panose=bin.readBytes(data,offset,10);offset+=10;obj.ulUnicodeRange1=bin.readUint(data,offset);offset+=4;obj.ulUnicodeRange2=bin.readUint(data,offset);offset+=4;obj.ulUnicodeRange3=bin.readUint(data,offset);offset+=4;obj.ulUnicodeRange4=bin.readUint(data,offset);offset+=4;obj.achVendID=[bin.readInt8(data,offset),bin.readInt8(data,offset+1),bin.readInt8(data,offset+2),bin.readInt8(data,offset+3)];offset+=4;obj.fsSelection=bin.readUshort(data,offset);offset+=2;obj.usFirstCharIndex=bin.readUshort(data,offset);offset+=2;obj.usLastCharIndex=bin.readUshort(data,offset);offset+=2;obj.sTypoAscender=bin.readShort(data,offset);offset+=2;obj.sTypoDescender=bin.readShort(data,offset);offset+=2;obj.sTypoLineGap=bin.readShort(data,offset);offset+=2;obj.usWinAscent=bin.readUshort(data,offset);offset+=2;obj.usWinDescent=bin.readUshort(data,offset);offset+=2;return offset};Typr[\"OS/2\"].version1=function(data,offset,obj){var bin=Typr._bin;offset=Typr[\"OS/2\"].version0(data,offset,obj);obj.ulCodePageRange1=bin.readUint(data,offset);offset+=4;obj.ulCodePageRange2=bin.readUint(data,offset);offset+=4;return offset};Typr[\"OS/2\"].version2=function(data,offset,obj){var bin=Typr._bin;offset=Typr[\"OS/2\"].version1(data,offset,obj);obj.sxHeight=bin.readShort(data,offset);offset+=2;obj.sCapHeight=bin.readShort(data,offset);offset+=2;obj.usDefault=bin.readUshort(data,offset);offset+=2;obj.usBreak=bin.readUshort(data,offset);offset+=2;obj.usMaxContext=bin.readUshort(data,offset);offset+=2;return offset};Typr[\"OS/2\"].version5=function(data,offset,obj){var bin=Typr._bin;offset=Typr[\"OS/2\"].version2(data,offset,obj);obj.usLowerOpticalPointSize=bin.readUshort(data,offset);offset+=2;obj.usUpperOpticalPointSize=bin.readUshort(data,offset);offset+=2;return offset};Typr.post={};Typr.post.parse=function(data,offset,length){var bin=Typr._bin;var obj={};obj.version=bin.readFixed(data,offset);offset+=4;obj.italicAngle=bin.readFixed(data,offset);offset+=4;obj.underlinePosition=bin.readShort(data,offset);offset+=2;obj.underlineThickness=bin.readShort(data,offset);offset+=2;return obj};Typr.SVG={};Typr.SVG.parse=function(data,offset,length){var bin=Typr._bin;var obj={entries:[]};var offset0=offset;var tableVersion=bin.readUshort(data,offset);offset+=2;var svgDocIndexOffset=bin.readUint(data,offset);offset+=4;var reserved=bin.readUint(data,offset);offset+=4;offset=svgDocIndexOffset+offset0;var numEntries=bin.readUshort(data,offset);offset+=2;for(var i=0;i<numEntries;i++){var startGlyphID=bin.readUshort(data,offset);offset+=2;var endGlyphID=bin.readUshort(data,offset);offset+=2;var svgDocOffset=bin.readUint(data,offset);offset+=4;var svgDocLength=bin.readUint(data,offset);offset+=4;var sbuf=new Uint8Array(data.buffer,offset0+svgDocOffset+svgDocIndexOffset,svgDocLength);var svg=bin.readUTF8(sbuf,0,sbuf.length);for(var f=startGlyphID;f<=endGlyphID;f++){obj.entries[f]=svg;}}return obj};Typr.SVG.toPath=function(str){var pth={cmds:[],crds:[]};if(str==null){ return pth; }var prsr=new DOMParser;var doc=prsr[\"parseFromString\"](str,\"image/svg+xml\");var svg=doc.firstChild;while(svg.tagName!=\"svg\"){ svg=svg.nextSibling; }var vb=svg.getAttribute(\"viewBox\");if(vb){ vb=vb.trim().split(\" \").map(parseFloat); }else { vb=[0,0,1e3,1e3]; }Typr.SVG._toPath(svg.children,pth);for(var i=0;i<pth.crds.length;i+=2){var x=pth.crds[i],y=pth.crds[i+1];x-=vb[0];y-=vb[1];y=-y;pth.crds[i]=x;pth.crds[i+1]=y;}return pth};Typr.SVG._toPath=function(nds,pth,fill){for(var ni=0;ni<nds.length;ni++){var nd=nds[ni],tn=nd.tagName;var cfl=nd.getAttribute(\"fill\");if(cfl==null){ cfl=fill; }if(tn==\"g\"){ Typr.SVG._toPath(nd.children,pth,cfl); }else if(tn==\"path\"){pth.cmds.push(cfl?cfl:\"#000000\");var d=nd.getAttribute(\"d\");var toks=Typr.SVG._tokens(d);Typr.SVG._toksToPath(toks,pth);pth.cmds.push(\"X\");}else if(tn==\"defs\");else { console.log(tn,nd); }}};Typr.SVG._tokens=function(d){var ts=[],off=0,rn=false,cn=\"\";while(off<d.length){var cc=d.charCodeAt(off),ch=d.charAt(off);off++;var isNum=48<=cc&&cc<=57||ch==\".\"||ch==\"-\";if(rn){if(ch==\"-\"){ts.push(parseFloat(cn));cn=ch;}else if(isNum){ cn+=ch; }else {ts.push(parseFloat(cn));if(ch!=\",\"&&ch!=\" \"){ ts.push(ch); }rn=false;}}else {if(isNum){cn=ch;rn=true;}else if(ch!=\",\"&&ch!=\" \"){ ts.push(ch); }}}if(rn){ ts.push(parseFloat(cn)); }return ts};Typr.SVG._toksToPath=function(ts,pth){var i=0,x=0,y=0,ox=0,oy=0;var pc={M:2,L:2,H:1,V:1,S:4,C:6};var cmds=pth.cmds,crds=pth.crds;while(i<ts.length){var cmd=ts[i];i++;if(cmd==\"z\"){cmds.push(\"Z\");x=ox;y=oy;}else {var cmu=cmd.toUpperCase();var ps=pc[cmu],reps=Typr.SVG._reps(ts,i,ps);for(var j=0;j<reps;j++){var xi=0,yi=0;if(cmd!=cmu){xi=x;yi=y;}if(cmu==\"M\"){x=xi+ts[i++];y=yi+ts[i++];cmds.push(\"M\");crds.push(x,y);ox=x;oy=y;}else if(cmu==\"L\"){x=xi+ts[i++];y=yi+ts[i++];cmds.push(\"L\");crds.push(x,y);}else if(cmu==\"H\"){x=xi+ts[i++];cmds.push(\"L\");crds.push(x,y);}else if(cmu==\"V\"){y=yi+ts[i++];cmds.push(\"L\");crds.push(x,y);}else if(cmu==\"C\"){var x1=xi+ts[i++],y1=yi+ts[i++],x2=xi+ts[i++],y2=yi+ts[i++],x3=xi+ts[i++],y3=yi+ts[i++];cmds.push(\"C\");crds.push(x1,y1,x2,y2,x3,y3);x=x3;y=y3;}else if(cmu==\"S\"){var co=Math.max(crds.length-4,0);var x1=x+x-crds[co],y1=y+y-crds[co+1];var x2=xi+ts[i++],y2=yi+ts[i++],x3=xi+ts[i++],y3=yi+ts[i++];cmds.push(\"C\");crds.push(x1,y1,x2,y2,x3,y3);x=x3;y=y3;}else { console.log(\"Unknown SVG command \"+cmd); }}}}};Typr.SVG._reps=function(ts,off,ps){var i=off;while(i<ts.length){if(typeof ts[i]==\"string\"){ break; }i+=ps;}return (i-off)/ps};if(Typr==null){ Typr={}; }if(Typr.U==null){ Typr.U={}; }Typr.U.codeToGlyph=function(font,code){var cmap=font.cmap;var tind=-1;if(cmap.p0e4!=null){ tind=cmap.p0e4; }else if(cmap.p3e1!=null){ tind=cmap.p3e1; }else if(cmap.p1e0!=null){ tind=cmap.p1e0; }if(tind==-1){ throw \"no familiar platform and encoding!\"; }var tab=cmap.tables[tind];if(tab.format==0){if(code>=tab.map.length){ return 0; }return tab.map[code]}else if(tab.format==4){var sind=-1;for(var i=0;i<tab.endCount.length;i++){ if(code<=tab.endCount[i]){sind=i;break} }if(sind==-1){ return 0; }if(tab.startCount[sind]>code){ return 0; }var gli=0;if(tab.idRangeOffset[sind]!=0){ gli=tab.glyphIdArray[code-tab.startCount[sind]+(tab.idRangeOffset[sind]>>1)-(tab.idRangeOffset.length-sind)]; }else { gli=code+tab.idDelta[sind]; }return gli&65535}else if(tab.format==12){if(code>tab.groups[tab.groups.length-1][1]){ return 0; }for(var i=0;i<tab.groups.length;i++){var grp=tab.groups[i];if(grp[0]<=code&&code<=grp[1]){ return grp[2]+(code-grp[0]) }}return 0}else { throw \"unknown cmap table format \"+tab.format }};Typr.U.glyphToPath=function(font,gid){var path={cmds:[],crds:[]};if(font.SVG&&font.SVG.entries[gid]){var p=font.SVG.entries[gid];if(p==null){ return path; }if(typeof p==\"string\"){p=Typr.SVG.toPath(p);font.SVG.entries[gid]=p;}return p}else if(font.CFF){var state={x:0,y:0,stack:[],nStems:0,haveWidth:false,width:font.CFF.Private?font.CFF.Private.defaultWidthX:0,open:false};Typr.U._drawCFF(font.CFF.CharStrings[gid],state,font.CFF,path);}else if(font.glyf){Typr.U._drawGlyf(gid,font,path);}return path};Typr.U._drawGlyf=function(gid,font,path){var gl=font.glyf[gid];if(gl==null){ gl=font.glyf[gid]=Typr.glyf._parseGlyf(font,gid); }if(gl!=null){if(gl.noc>-1){ Typr.U._simpleGlyph(gl,path); }else { Typr.U._compoGlyph(gl,font,path); }}};Typr.U._simpleGlyph=function(gl,p){for(var c=0;c<gl.noc;c++){var i0=c==0?0:gl.endPts[c-1]+1;var il=gl.endPts[c];for(var i=i0;i<=il;i++){var pr=i==i0?il:i-1;var nx=i==il?i0:i+1;var onCurve=gl.flags[i]&1;var prOnCurve=gl.flags[pr]&1;var nxOnCurve=gl.flags[nx]&1;var x=gl.xs[i],y=gl.ys[i];if(i==i0){if(onCurve){if(prOnCurve){ Typr.U.P.moveTo(p,gl.xs[pr],gl.ys[pr]); }else {Typr.U.P.moveTo(p,x,y);continue}}else {if(prOnCurve){ Typr.U.P.moveTo(p,gl.xs[pr],gl.ys[pr]); }else { Typr.U.P.moveTo(p,(gl.xs[pr]+x)/2,(gl.ys[pr]+y)/2); }}}if(onCurve){if(prOnCurve){ Typr.U.P.lineTo(p,x,y); }}else {if(nxOnCurve){ Typr.U.P.qcurveTo(p,x,y,gl.xs[nx],gl.ys[nx]); }else { Typr.U.P.qcurveTo(p,x,y,(x+gl.xs[nx])/2,(y+gl.ys[nx])/2); }}}Typr.U.P.closePath(p);}};Typr.U._compoGlyph=function(gl,font,p){for(var j=0;j<gl.parts.length;j++){var path={cmds:[],crds:[]};var prt=gl.parts[j];Typr.U._drawGlyf(prt.glyphIndex,font,path);var m=prt.m;for(var i=0;i<path.crds.length;i+=2){var x=path.crds[i],y=path.crds[i+1];p.crds.push(x*m.a+y*m.b+m.tx);p.crds.push(x*m.c+y*m.d+m.ty);}for(var i=0;i<path.cmds.length;i++){ p.cmds.push(path.cmds[i]); }}};Typr.U._getGlyphClass=function(g,cd){var intr=Typr._lctf.getInterval(cd,g);return intr==-1?0:cd[intr+2]};Typr.U.getPairAdjustment=function(font,g1,g2){if(font.GPOS){var ltab=null;for(var i=0;i<font.GPOS.featureList.length;i++){var fl=font.GPOS.featureList[i];if(fl.tag==\"kern\"){ for(var j=0;j<fl.tab.length;j++){ if(font.GPOS.lookupList[fl.tab[j]].ltype==2){ ltab=font.GPOS.lookupList[fl.tab[j]]; } } }}if(ltab){for(var i=0;i<ltab.tabs.length;i++){var tab=ltab.tabs[i];var ind=Typr._lctf.coverageIndex(tab.coverage,g1);if(ind==-1){ continue; }var adj;if(tab.format==1){var right=tab.pairsets[ind];for(var j=0;j<right.length;j++){ if(right[j].gid2==g2){ adj=right[j]; } }if(adj==null){ continue }}else if(tab.format==2){var c1=Typr.U._getGlyphClass(g1,tab.classDef1);var c2=Typr.U._getGlyphClass(g2,tab.classDef2);var adj=tab.matrix[c1][c2];}return adj.val1[2]}}}if(font.kern){var ind1=font.kern.glyph1.indexOf(g1);if(ind1!=-1){var ind2=font.kern.rval[ind1].glyph2.indexOf(g2);if(ind2!=-1){ return font.kern.rval[ind1].vals[ind2] }}}return 0};Typr.U.stringToGlyphs=function(font,str){var gls=[];for(var i=0;i<str.length;i++){var cc=str.codePointAt(i);if(cc>65535){ i++; }gls.push(Typr.U.codeToGlyph(font,cc));}var gsub=font[\"GSUB\"];if(gsub==null){ return gls; }var llist=gsub.lookupList,flist=gsub.featureList;var wsep='\\n\\t\" ,.:;!?()  ،';var R=\"آأؤإاةدذرزوٱٲٳٵٶٷڈډڊڋڌڍڎڏڐڑڒړڔڕږڗژڙۀۃۄۅۆۇۈۉۊۋۍۏےۓەۮۯܐܕܖܗܘܙܞܨܪܬܯݍݙݚݛݫݬݱݳݴݸݹࡀࡆࡇࡉࡔࡧࡩࡪࢪࢫࢬࢮࢱࢲࢹૅેૉ૊૎૏ૐ૑૒૝ૡ૤૯஁ஃ஄அஉ஌எஏ஑னப஫஬\";var L=\"ꡲ્૗\";for(var ci=0;ci<gls.length;ci++){var gl=gls[ci];var slft=ci==0||wsep.indexOf(str[ci-1])!=-1;var srgt=ci==gls.length-1||wsep.indexOf(str[ci+1])!=-1;if(!slft&&R.indexOf(str[ci-1])!=-1){ slft=true; }if(!srgt&&R.indexOf(str[ci])!=-1){ srgt=true; }if(!srgt&&L.indexOf(str[ci+1])!=-1){ srgt=true; }if(!slft&&L.indexOf(str[ci])!=-1){ slft=true; }var feat=null;if(slft){ feat=srgt?\"isol\":\"init\"; }else { feat=srgt?\"fina\":\"medi\"; }for(var fi=0;fi<flist.length;fi++){if(flist[fi].tag!=feat){ continue; }for(var ti=0;ti<flist[fi].tab.length;ti++){var tab=llist[flist[fi].tab[ti]];if(tab.ltype!=1){ continue; }Typr.U._applyType1(gls,ci,tab);}}}var cligs=[\"rlig\",\"liga\",\"mset\"];for(var ci=0;ci<gls.length;ci++){var gl=gls[ci];var rlim=Math.min(3,gls.length-ci-1);for(var fi=0;fi<flist.length;fi++){var fl=flist[fi];if(cligs.indexOf(fl.tag)==-1){ continue; }for(var ti=0;ti<fl.tab.length;ti++){var tab=llist[fl.tab[ti]];for(var j=0;j<tab.tabs.length;j++){if(tab.tabs[j]==null){ continue; }var ind=Typr._lctf.coverageIndex(tab.tabs[j].coverage,gl);if(ind==-1){ continue; }if(tab.ltype==4){var vals=tab.tabs[j].vals[ind];for(var k=0;k<vals.length;k++){var lig=vals[k],rl=lig.chain.length;if(rl>rlim){ continue; }var good=true;for(var l=0;l<rl;l++){ if(lig.chain[l]!=gls[ci+(1+l)]){ good=false; } }if(!good){ continue; }gls[ci]=lig.nglyph;for(var l=0;l<rl;l++){ gls[ci+l+1]=-1; }}}else if(tab.ltype==5){var ltab=tab.tabs[j];if(ltab.fmt!=2){ continue; }var cind=Typr._lctf.getInterval(ltab.cDef,gl);var cls=ltab.cDef[cind+2],scs=ltab.scset[cls];for(var i=0;i<scs.length;i++){var sc=scs[i],inp=sc.input;if(inp.length>rlim){ continue; }var good=true;for(var l=0;l<inp.length;l++){var cind2=Typr._lctf.getInterval(ltab.cDef,gls[ci+1+l]);if(cind==-1&&ltab.cDef[cind2+2]!=inp[l]){good=false;break}}if(!good){ continue; }var lrs=sc.substLookupRecords;for(var k=0;k<lrs.length;k+=2){var gi=lrs[k],tabi=lrs[k+1];}}}}}}}return gls};Typr.U._applyType1=function(gls,ci,tab){var gl=gls[ci];for(var j=0;j<tab.tabs.length;j++){var ttab=tab.tabs[j];var ind=Typr._lctf.coverageIndex(ttab.coverage,gl);if(ind==-1){ continue; }if(ttab.fmt==1){ gls[ci]=gls[ci]+ttab.delta; }else { gls[ci]=ttab.newg[ind]; }}};Typr.U.glyphsToPath=function(font,gls,clr){var tpath={cmds:[],crds:[]};var x=0;for(var i=0;i<gls.length;i++){var gid=gls[i];if(gid==-1){ continue; }var gid2=i<gls.length-1&&gls[i+1]!=-1?gls[i+1]:0;var path=Typr.U.glyphToPath(font,gid);for(var j=0;j<path.crds.length;j+=2){tpath.crds.push(path.crds[j]+x);tpath.crds.push(path.crds[j+1]);}if(clr){ tpath.cmds.push(clr); }for(var j=0;j<path.cmds.length;j++){ tpath.cmds.push(path.cmds[j]); }if(clr){ tpath.cmds.push(\"X\"); }x+=font.hmtx.aWidth[gid];if(i<gls.length-1){ x+=Typr.U.getPairAdjustment(font,gid,gid2); }}return tpath};Typr.U.pathToSVG=function(path,prec){if(prec==null){ prec=5; }var out=[],co=0,lmap={M:2,L:2,Q:4,C:6};for(var i=0;i<path.cmds.length;i++){var cmd=path.cmds[i],cn=co+(lmap[cmd]?lmap[cmd]:0);out.push(cmd);while(co<cn){var c=path.crds[co++];out.push(parseFloat(c.toFixed(prec))+(co==cn?\"\":\" \"));}}return out.join(\"\")};Typr.U.pathToContext=function(path,ctx){var c=0,crds=path.crds;for(var j=0;j<path.cmds.length;j++){var cmd=path.cmds[j];if(cmd==\"M\"){ctx.moveTo(crds[c],crds[c+1]);c+=2;}else if(cmd==\"L\"){ctx.lineTo(crds[c],crds[c+1]);c+=2;}else if(cmd==\"C\"){ctx.bezierCurveTo(crds[c],crds[c+1],crds[c+2],crds[c+3],crds[c+4],crds[c+5]);c+=6;}else if(cmd==\"Q\"){ctx.quadraticCurveTo(crds[c],crds[c+1],crds[c+2],crds[c+3]);c+=4;}else if(cmd.charAt(0)==\"#\"){ctx.beginPath();ctx.fillStyle=cmd;}else if(cmd==\"Z\"){ctx.closePath();}else if(cmd==\"X\"){ctx.fill();}}};Typr.U.P={};Typr.U.P.moveTo=function(p,x,y){p.cmds.push(\"M\");p.crds.push(x,y);};Typr.U.P.lineTo=function(p,x,y){p.cmds.push(\"L\");p.crds.push(x,y);};Typr.U.P.curveTo=function(p,a,b,c,d,e,f){p.cmds.push(\"C\");p.crds.push(a,b,c,d,e,f);};Typr.U.P.qcurveTo=function(p,a,b,c,d){p.cmds.push(\"Q\");p.crds.push(a,b,c,d);};Typr.U.P.closePath=function(p){p.cmds.push(\"Z\");};Typr.U._drawCFF=function(cmds,state,font,p){var stack=state.stack;var nStems=state.nStems,haveWidth=state.haveWidth,width=state.width,open=state.open;var i=0;var x=state.x,y=state.y,c1x=0,c1y=0,c2x=0,c2y=0,c3x=0,c3y=0,c4x=0,c4y=0,jpx=0,jpy=0;var o={val:0,size:0};while(i<cmds.length){Typr.CFF.getCharString(cmds,i,o);var v=o.val;i+=o.size;if(v==\"o1\"||v==\"o18\"){var hasWidthArg;hasWidthArg=stack.length%2!==0;if(hasWidthArg&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;}nStems+=stack.length>>1;stack.length=0;haveWidth=true;}else if(v==\"o3\"||v==\"o23\"){var hasWidthArg;hasWidthArg=stack.length%2!==0;if(hasWidthArg&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;}nStems+=stack.length>>1;stack.length=0;haveWidth=true;}else if(v==\"o4\"){if(stack.length>1&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;haveWidth=true;}if(open){ Typr.U.P.closePath(p); }y+=stack.pop();Typr.U.P.moveTo(p,x,y);open=true;}else if(v==\"o5\"){while(stack.length>0){x+=stack.shift();y+=stack.shift();Typr.U.P.lineTo(p,x,y);}}else if(v==\"o6\"||v==\"o7\"){var count=stack.length;var isX=v==\"o6\";for(var j=0;j<count;j++){var sval=stack.shift();if(isX){ x+=sval; }else { y+=sval; }isX=!isX;Typr.U.P.lineTo(p,x,y);}}else if(v==\"o8\"||v==\"o24\"){var count=stack.length;var index=0;while(index+6<=count){c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y+stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,x,y);index+=6;}if(v==\"o24\"){x+=stack.shift();y+=stack.shift();Typr.U.P.lineTo(p,x,y);}}else if(v==\"o11\"){ break; }else if(v==\"o1234\"||v==\"o1235\"||v==\"o1236\"||v==\"o1237\"){if(v==\"o1234\"){c1x=x+stack.shift();c1y=y;c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y;c3x=jpx+stack.shift();c3y=c2y;c4x=c3x+stack.shift();c4y=y;x=c4x+stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,jpx,jpy);Typr.U.P.curveTo(p,c3x,c3y,c4x,c4y,x,y);}if(v==\"o1235\"){c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y+stack.shift();c3x=jpx+stack.shift();c3y=jpy+stack.shift();c4x=c3x+stack.shift();c4y=c3y+stack.shift();x=c4x+stack.shift();y=c4y+stack.shift();stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,jpx,jpy);Typr.U.P.curveTo(p,c3x,c3y,c4x,c4y,x,y);}if(v==\"o1236\"){c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y;c3x=jpx+stack.shift();c3y=c2y;c4x=c3x+stack.shift();c4y=c3y+stack.shift();x=c4x+stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,jpx,jpy);Typr.U.P.curveTo(p,c3x,c3y,c4x,c4y,x,y);}if(v==\"o1237\"){c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y+stack.shift();c3x=jpx+stack.shift();c3y=jpy+stack.shift();c4x=c3x+stack.shift();c4y=c3y+stack.shift();if(Math.abs(c4x-x)>Math.abs(c4y-y)){x=c4x+stack.shift();}else {y=c4y+stack.shift();}Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,jpx,jpy);Typr.U.P.curveTo(p,c3x,c3y,c4x,c4y,x,y);}}else if(v==\"o14\"){if(stack.length>0&&!haveWidth){width=stack.shift()+font.nominalWidthX;haveWidth=true;}if(stack.length==4){var adx=stack.shift();var ady=stack.shift();var bchar=stack.shift();var achar=stack.shift();var bind=Typr.CFF.glyphBySE(font,bchar);var aind=Typr.CFF.glyphBySE(font,achar);Typr.U._drawCFF(font.CharStrings[bind],state,font,p);state.x=adx;state.y=ady;Typr.U._drawCFF(font.CharStrings[aind],state,font,p);}if(open){Typr.U.P.closePath(p);open=false;}}else if(v==\"o19\"||v==\"o20\"){var hasWidthArg;hasWidthArg=stack.length%2!==0;if(hasWidthArg&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;}nStems+=stack.length>>1;stack.length=0;haveWidth=true;i+=nStems+7>>3;}else if(v==\"o21\"){if(stack.length>2&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;haveWidth=true;}y+=stack.pop();x+=stack.pop();if(open){ Typr.U.P.closePath(p); }Typr.U.P.moveTo(p,x,y);open=true;}else if(v==\"o22\"){if(stack.length>1&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;haveWidth=true;}x+=stack.pop();if(open){ Typr.U.P.closePath(p); }Typr.U.P.moveTo(p,x,y);open=true;}else if(v==\"o25\"){while(stack.length>6){x+=stack.shift();y+=stack.shift();Typr.U.P.lineTo(p,x,y);}c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y+stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,x,y);}else if(v==\"o26\"){if(stack.length%2){x+=stack.shift();}while(stack.length>0){c1x=x;c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x;y=c2y+stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,x,y);}}else if(v==\"o27\"){if(stack.length%2){y+=stack.shift();}while(stack.length>0){c1x=x+stack.shift();c1y=y;c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y;Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,x,y);}}else if(v==\"o10\"||v==\"o29\"){var obj=v==\"o10\"?font.Private:font;if(stack.length==0){console.log(\"error: empty stack\");}else {var ind=stack.pop();var subr=obj.Subrs[ind+obj.Bias];state.x=x;state.y=y;state.nStems=nStems;state.haveWidth=haveWidth;state.width=width;state.open=open;Typr.U._drawCFF(subr,state,font,p);x=state.x;y=state.y;nStems=state.nStems;haveWidth=state.haveWidth;width=state.width;open=state.open;}}else if(v==\"o30\"||v==\"o31\"){var count,count1=stack.length;var index=0;var alternate=v==\"o31\";count=count1&~2;index+=count1-count;while(index<count){if(alternate){c1x=x+stack.shift();c1y=y;c2x=c1x+stack.shift();c2y=c1y+stack.shift();y=c2y+stack.shift();if(count-index==5){x=c2x+stack.shift();index++;}else { x=c2x; }alternate=false;}else {c1x=x;c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();if(count-index==5){y=c2y+stack.shift();index++;}else { y=c2y; }alternate=true;}Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,x,y);index+=4;}}else if((v+\"\").charAt(0)==\"o\"){console.log(\"Unknown operation: \"+v,cmds);throw v}else { stack.push(v); }}state.x=x;state.y=y;state.nStems=nStems;state.haveWidth=haveWidth;state.width=width;state.open=open;};var typr_js=Typr;\n\nvar TEXT_NEWLINE_REGEXP = /\\r?\\n/;\n\nfunction registerFontClass(Zdog) {\n  // Zdog.Font class\n  var ZdogFont = function ZdogFont(props) {\n    var this$1 = this;\n\n    // Set missing props to default values\n    props = Zdog.extend({\n      src: '',\n    }, props);\n    this.src = props.src;\n    this.font = null;\n    this._hasLoaded = false;\n    this._loadCallbacks = [];\n    // Add this font instance to the internal font list\n    Zdog.FontList.push(this);\n    // Begin loading font file\n    this._fetchFontResource(this.src)\n      .then(function (buffer) {\n        var font = typr_js.parse(buffer);\n        // check font fields to see if the font was parsed correctly\n        if ((!font.head) || (!font.hmtx) || (!font.hhea) || (!font.glyf)) {\n          // get a list of missing font fields (only checks for ones that zfont uses)\n          var missingFields = ['head', 'hmtx', 'hhea', 'glyf'].filter(function (field) { return !font[field]; });\n          throw new Error((\"Typr.js could not parse this font (unable to find \" + (missingFields.join(', ')) + \")\"));\n        }\n        return font;\n      })\n      .then(function (font) {\n        this$1.font = font;\n        this$1._hasLoaded = true;\n        this$1._loadCallbacks.forEach(function (callback) { return callback(); });\n      })\n      .catch(function (err) {\n        throw new Error((\"Unable to load font from \" + (this$1.src) + \":\\n\" + err));\n      });\n  };\n\n  ZdogFont.prototype.waitForLoad = function waitForLoad () {\n      var this$1 = this;\n\n    return new Promise(function (resolve, reject) {\n      // If the font is loaded, we can resolve right away\n      if (this$1._hasLoaded && this$1._hasLoaded) {\n        resolve();\n      }\n      // Otherwise, wait for it to load\n      else {\n        this$1._loadCallbacks.push(resolve);\n      }\n    });\n  };\n\n  ZdogFont.prototype.getFontScale = function getFontScale (fontSize) {\n    if (!this._hasLoaded) {\n      return null;\n    } else {\n      return 1 / this.font.head.unitsPerEm * fontSize;\n    }\n  };\n\n  ZdogFont.prototype.measureText = function measureText (text, fontSize) {\n      var this$1 = this;\n      if ( fontSize === void 0 ) fontSize=64;\n\n    if (!this._hasLoaded) {\n      return null;\n    }\n    var lines = Array.isArray(text) ? text : text.split(TEXT_NEWLINE_REGEXP);\n    var font = this.font;\n    var advanceWidthTable = font.hmtx.aWidth;\n    var fontScale = this.getFontScale(fontSize);\n    var descender = font.hhea.descender;\n    var ascender = font.hhea.ascender;\n    var lineGap = font.hhea.lineGap;\n    var lineWidths = lines.map(function (line) {\n      var glyphs = typr_js.U.stringToGlyphs(this$1.font, line);\n      return glyphs.reduce(function (advanceWidth, glyphId) {\n        // stringToGlyphs returns an array on glyph IDs that is the same length as the text string\n        // an ID can sometimes be -1 in cases where multiple characters are merged into a single ligature\n        if (glyphId > -1 && glyphId < advanceWidthTable.length) {\n          advanceWidth += advanceWidthTable[glyphId];\n        }\n        return advanceWidth;\n      }, 0);\n    });\n    var width = Math.max.apply(Math, lineWidths);\n    var lineHeight = (0 - descender) + ascender;\n    var height = lineHeight * lines.length;\n      \n    // Multiply by fontScale to convert from font units to pixels\n    return {\n      width: width * fontScale,\n      height: height * fontScale,\n      lineHeight: lineHeight * fontScale,\n      lineWidths: lineWidths.map(function (width) { return width * fontScale; }),\n      descender: descender * fontScale,\n      ascender: ascender * fontScale,\n    };\n  };\n\n  ZdogFont.prototype.getTextPath = function getTextPath (text, fontSize, x, y, z, alignX, alignY) {\n      var this$1 = this;\n      if ( fontSize === void 0 ) fontSize=64;\n      if ( x === void 0 ) x=0;\n      if ( y === void 0 ) y=0;\n      if ( z === void 0 ) z=0;\n      if ( alignX === void 0 ) alignX='left';\n      if ( alignY === void 0 ) alignY='bottom';\n\n    if (!this._hasLoaded) {\n      return [];\n    }\n    var lines = Array.isArray(text) ? text : text.split(TEXT_NEWLINE_REGEXP);\n    var measurements = this.measureText(text, fontSize);\n    var lineWidths = measurements.lineWidths;\n    var lineHeight = measurements.lineHeight;\n    return lines.map(function (line, lineIndex) {\n      var ref = this$1.getTextOrigin(Object.assign({}, measurements,\n        {width: lineWidths[lineIndex]}), x, y, z, alignX, alignY);\n        var _x = ref[0];\n        var _y = ref[1];\n        var _z = ref[2];\n      y += lineHeight;\n      var glyphs = typr_js.U.stringToGlyphs(this$1.font, line);\n      var path = typr_js.U.glyphsToPath(this$1.font, glyphs);\n      return this$1._convertPathCommands(path, fontSize, _x, _y, z);\n    }).flat();\n  };\n\n  ZdogFont.prototype.getTextGlyphs = function getTextGlyphs (text, fontSize, x, y, z, alignX, alignY) {\n      var this$1 = this;\n      if ( fontSize === void 0 ) fontSize=64;\n      if ( x === void 0 ) x=0;\n      if ( y === void 0 ) y=0;\n      if ( z === void 0 ) z=0;\n      if ( alignX === void 0 ) alignX='left';\n      if ( alignY === void 0 ) alignY='bottom';\n\n    if (!this._hasLoaded) {\n      return [];\n    }\n    var measurements = this.measureText(text, fontSize);\n    var advanceWidthTable = this.font.hmtx.aWidth;\n    var fontScale = this.getFontScale(fontSize);\n    var lineWidths = measurements.lineWidths;\n    var lineHeight = measurements.lineHeight;\n    var lines = Array.isArray(text) ? text : text.split(TEXT_NEWLINE_REGEXP);\n    return lines.map(function (line, lineIndex) {\n      var glyphs = typr_js.U.stringToGlyphs(this$1.font, line);\n      var ref = this$1.getTextOrigin(Object.assign({}, measurements,\n        {width: lineWidths[lineIndex]}), x, y, z, alignX, alignY);\n        var _x = ref[0];\n        var _y = ref[1];\n        var _z = ref[2];\n      y += lineHeight;\n      return glyphs.filter(function (glyph) { return glyph !== -1; }).map(function (glyphId) {\n        var path = typr_js.U.glyphToPath(this$1.font, glyphId);\n        var shape = {\n          translate: {x:_x, y: _y, z:_z},\n          path: this$1._convertPathCommands(path, fontSize, 0, 0, 0)\n        };\n        _x += advanceWidthTable[glyphId] * fontScale;\n        return shape;\n      });\n    }).flat(); \n  };\n\n  ZdogFont.prototype.getTextOrigin = function getTextOrigin (measuement, x, y, z, alignX, alignY) {\n      if ( x === void 0 ) x=0;\n      if ( y === void 0 ) y=0;\n      if ( z === void 0 ) z=0;\n      if ( alignX === void 0 ) alignX='left';\n      if ( alignY === void 0 ) alignY='bottom';\n\n    var width = measuement.width;\n      var height = measuement.height;\n      var lineHeight = measuement.lineHeight;\n    switch (alignX) {\n      case 'right':\n        x -= width;\n        break;\n      case 'center':\n        x -= width / 2;\n        break;\n    }\n    switch (alignY) {\n      case 'middle':\n        y -= (height / 2)- lineHeight;\n        break;\n      case 'bottom':\n      default:\n        y -= height - lineHeight;\n        break;\n    }\n    return [x, y, z];\n  };\n\n  // Convert Typr.js path commands to Zdog commands\n  // Also apply font size scaling and coordinate adjustment\n  // https://github.com/photopea/Typr.js\n  // https://zzz.dog/shapes#shape-path-commands\n  ZdogFont.prototype._convertPathCommands = function _convertPathCommands (path, fontSize, x, y, z) {\n      if ( x === void 0 ) x=0;\n      if ( y === void 0 ) y=0;\n      if ( z === void 0 ) z=0;\n\n    var yDir = -1;\n    var xDir = 1;\n    var fontScale = this.getFontScale(fontSize);\n    var commands = path.cmds;\n    // Apply font scale to all coords\n    var coords = path.crds.map(function (coord) { return coord * fontScale; });\n    // Convert coords to Zdog commands\n    var startCoord = null;\n    var coordOffset = 0;\n    return commands.map(function (cmd) {\n      var result = null;\n      if (!startCoord) {\n        startCoord = {x: x + coords[coordOffset] * xDir, y: y + coords[coordOffset + 1] * yDir, z: z};\n      }\n      switch (cmd) {\n        case 'M': // moveTo command\n          result = {\n            move: {x: x + coords[coordOffset] * xDir, y: y + coords[coordOffset + 1] * yDir, z: z}\n          };\n          coordOffset += 2;\n          return result;\n        case 'L': // lineTo command\n          result = {\n            line: {x: x + coords[coordOffset] * xDir, y: y + coords[coordOffset + 1] * yDir, z: z}\n          };\n          coordOffset += 2;\n          return result;\n        case 'C': // curveTo command\n          result = {\n            bezier: [\n              {x: x + coords[coordOffset]   * xDir, y: y + coords[coordOffset + 1] * yDir, z: z},\n              {x: x + coords[coordOffset + 2] * xDir, y: y + coords[coordOffset + 3] * yDir, z: z},\n              {x: x + coords[coordOffset + 4] * xDir, y: y + coords[coordOffset + 5] * yDir, z: z} ]\n          };\n          coordOffset += 6;\n          return result;\n        case 'Q': // arcTo command\n          result = {\n            arc: [\n              {x: x + coords[coordOffset]   * xDir, y: y + coords[coordOffset + 1] * yDir, z: z},\n              {x: x + coords[coordOffset + 2] * xDir, y: y + coords[coordOffset + 3] * yDir, z: z} ]\n          };\n          coordOffset += 4;\n          return result;\n        case 'Z': // close path\n          if (startCoord) {\n            result = {\n              line: startCoord\n            };\n            startCoord = null;\n          }\n          return result;\n        // unhandled type\n        // currently, #rrggbb and X types (used in multicolor fonts) aren't supported\n        default:\n          return result;\n      }\n    }).filter(function (cmd) { return cmd !== null; }); // filter out null commands\n  };\n\n  ZdogFont.prototype._fetchFontResource = function _fetchFontResource (source) {\n    return new Promise(function (resolve, reject) {\n      var request = new XMLHttpRequest();\n      // Fetch as an arrayBuffer for Typr.parse\n      request.responseType = 'arraybuffer'; \n      request.open('GET', source, true);\n      request.onreadystatechange = function (e) {\n        if (request.readyState === 4) {\n          if (request.status >= 200 && request.status < 300) {\n            resolve(request.response);\n          } else {\n            reject((\"HTTP error \" + (request.status) + \": \" + (request.statusText)));\n          }\n        }\n      };\n      request.send(null);\n    });\n  };\n\n  Zdog.Font = ZdogFont;\n  return Zdog;\n}\n\nfunction objectWithoutProperties (obj, exclude) { var target = {}; for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k) && exclude.indexOf(k) === -1) target[k] = obj[k]; return target; }\nfunction registerTextClass(Zdog) {\n\n  // Zdog.Text class\n  var ZdogText = /*@__PURE__*/(function (superclass) {\n    function ZdogText(props) {\n      // Set missing props to default values\n      props = Zdog.extend({\n        font: null,\n        value: '',\n        fontSize: 64,\n        textAlign: 'left',\n        textBaseline: 'bottom',\n      }, props);\n      // Split props\n      var font = props.font;\n      var value = props.value;\n      var fontSize = props.fontSize;\n      var textAlign = props.textAlign;\n      var textBaseline = props.textBaseline;\n      var rest = objectWithoutProperties( props, [\"font\", \"value\", \"fontSize\", \"textAlign\", \"textBaseline\"] );\n      var shapeProps = rest;\n      // Create shape object\n      superclass.call(this, Object.assign({}, shapeProps,\n        {closed: true,\n        visible: false, // hide until font is loaded\n        path: [{}]}));\n      this._font = null;\n      this._value = value;\n      this._fontSize = fontSize;\n      this._textAlign = textAlign;\n      this._textBaseline = textBaseline;\n      this.font = font;\n    }\n\n    if ( superclass ) ZdogText.__proto__ = superclass;\n    ZdogText.prototype = Object.create( superclass && superclass.prototype );\n    ZdogText.prototype.constructor = ZdogText;\n\n    var prototypeAccessors = { font: { configurable: true },value: { configurable: true },fontSize: { configurable: true },textAlign: { configurable: true },textBaseline: { configurable: true } };\n\n    ZdogText.prototype.updateText = function updateText () {\n      var path = this.font.getTextPath(this.value, this.fontSize, 0, 0, 0, this.textAlign, this.textBaseline);\n      if (path.length == 0) { // zdog doesn't know what to do with empty path arrays\n        this.path = [{}];\n        this.visible = false;\n      } else {\n        this.path = path;\n        this.visible = true;\n      }\n      this.updatePath();\n    };\n\n    prototypeAccessors.font.set = function (newFont) {\n      var this$1 = this;\n\n      this._font = newFont;\n      this.font.waitForLoad().then(function () {\n        this$1.updateText();\n        this$1.visible = true;\n        // Find root Zdog.Illustration instance\n        var root = this$1.addTo;\n        while (root.addTo !== undefined) {\n          root = root.addTo;\n        }\n        // Update render graph\n        if (root && typeof root.updateRenderGraph === 'function') {\n          root.updateRenderGraph();\n        }\n      });\n    };\n\n    prototypeAccessors.font.get = function () {\n      return this._font;\n    };\n\n    prototypeAccessors.value.set = function (newValue) {\n      this._value = newValue;\n      this.updateText();\n    };\n    \n    prototypeAccessors.value.get = function () {\n      return this._value;\n    };\n\n    prototypeAccessors.fontSize.set = function (newSize) {\n      this._fontSize = newSize;\n      this.updateText();\n    };\n\n    prototypeAccessors.fontSize.get = function () {\n      return this._fontSize;\n    };\n\n    prototypeAccessors.textAlign.set = function (newValue) {\n      this._textAlign = newValue;\n      this.updateText();\n    };\n\n    prototypeAccessors.textAlign.get = function () {\n      return this._textAlign;\n    };\n\n    prototypeAccessors.textBaseline.set = function (newValue) {\n      this._textBaseline = newValue;\n      this.updateText();\n    };\n\n    prototypeAccessors.textBaseline.get = function () {\n      return this._textBaseline;\n    };\n\n    Object.defineProperties( ZdogText.prototype, prototypeAccessors );\n\n    return ZdogText;\n  }(Zdog.Shape));\n\n  ZdogText.optionKeys = ZdogText.optionKeys.concat(['font', 'fontSize', 'value', 'textAlign', 'textBaseline']);\n  Zdog.Text = ZdogText;\n  return Zdog;\n}\n\nfunction objectWithoutProperties$1 (obj, exclude) { var target = {}; for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k) && exclude.indexOf(k) === -1) target[k] = obj[k]; return target; }\nfunction registerTextGroupClass(Zdog) {\n\n  // Zdog.TextGroup class\n  var ZdogTextGroup = /*@__PURE__*/(function (superclass) {\n    function ZdogTextGroup(props) {\n      // Set missing props to default values\n      props = Zdog.extend({\n        font: null,\n        value: '',\n        fontSize: 64,\n        textAlign: 'left',\n        textBaseline: 'bottom',\n        color: '#333',\n        fill: false,\n        stroke: 1,\n      }, props);\n      // Split props\n      var font = props.font;\n      var value = props.value;\n      var fontSize = props.fontSize;\n      var textAlign = props.textAlign;\n      var textBaseline = props.textBaseline;\n      var color = props.color;\n      var fill = props.fill;\n      var stroke = props.stroke;\n      var rest = objectWithoutProperties$1( props, [\"font\", \"value\", \"fontSize\", \"textAlign\", \"textBaseline\", \"color\", \"fill\", \"stroke\"] );\n      var groupProps = rest;\n      // Create group object\n      superclass.call(this, Object.assign({}, groupProps,\n        {visible: false}));\n      this._font = null;\n      this._value = value;\n      this._fontSize = fontSize;\n      this._textAlign = textAlign;\n      this._textBaseline = textBaseline;\n      this._color = color;\n      this._fill = fill;\n      this._stroke = stroke;\n      this.font = font;\n    }\n\n    if ( superclass ) ZdogTextGroup.__proto__ = superclass;\n    ZdogTextGroup.prototype = Object.create( superclass && superclass.prototype );\n    ZdogTextGroup.prototype.constructor = ZdogTextGroup;\n\n    var prototypeAccessors = { font: { configurable: true },value: { configurable: true },fontSize: { configurable: true },textAlign: { configurable: true },textBaseline: { configurable: true },color: { configurable: true },fill: { configurable: true },stroke: { configurable: true } };\n\n    ZdogTextGroup.prototype.updateText = function updateText () {\n      var this$1 = this;\n\n      // Remove old children\n      while (this.children.length > 0) {\n        this.removeChild(this.children[0]);\n      }\n      // Get text paths for each glyph\n      var glyphs = this.font.getTextGlyphs(this.value, this.fontSize, 0, 0, 0, this.textAlign, this.textBaseline);\n      // Convert glyphs to new shapes\n      glyphs.filter(function (shape) { return shape.path.length > 0; }).forEach(function (shape) {\n        this$1.addChild(new Zdog.Shape({\n          translate: shape.translate,\n          path: shape.path,\n          color: this$1.color,\n          fill: this$1.fill,\n          stroke: this$1.stroke,\n          closed: true,\n        }));\n      });\n      this.updateFlatGraph();\n    };\n\n    prototypeAccessors.font.set = function (newFont) {\n      var this$1 = this;\n\n      this._font = newFont;\n      this._font.waitForLoad().then(function () {\n        this$1.updateText();\n        this$1.visible = true;\n        // Find root Zdog.Illustration instance\n        var root = this$1.addTo;\n        while (root.addTo !== undefined) {\n          root = root.addTo;\n        }\n        // Update render graph\n        if (root && typeof root.updateRenderGraph === 'function') {\n          root.updateRenderGraph();\n        }\n      });\n    };\n\n    prototypeAccessors.font.get = function () {\n      return this._font;\n    };\n\n    prototypeAccessors.value.set = function (newValue) {\n      this._value = newValue;\n      this.updateText();\n    };\n    \n    prototypeAccessors.value.get = function () {\n      return this._value;\n    };\n\n    prototypeAccessors.fontSize.set = function (newSize) {\n      this._fontSize = newSize;\n      this.updateText();\n    };\n\n    prototypeAccessors.fontSize.get = function () {\n      return this._fontSize;\n    };\n\n    prototypeAccessors.textAlign.set = function (newValue) {\n      this._textAlign = newValue;\n      this.updateText();\n    };\n\n    prototypeAccessors.textAlign.get = function () {\n      return this._textAlign;\n    };\n\n    prototypeAccessors.textBaseline.set = function (newValue) {\n      this._textBaseline = newValue;\n      this.updateText();\n    };\n\n    prototypeAccessors.textBaseline.get = function () {\n      return this._textBaseline;\n    };\n\n    prototypeAccessors.color.set = function (newColor) {\n      this._color = newColor;\n      this.children.forEach(function (child) { return child.color = newColor; });\n    };\n\n    prototypeAccessors.color.get = function () {\n      return this._color;\n    };\n\n    prototypeAccessors.fill.set = function (newFill) {\n      this._fill = newFill;\n      this.children.forEach(function (child) { return child.fill = newFill; });\n    };\n\n    prototypeAccessors.fill.get = function () {\n      return this._fill;\n    };\n\n    prototypeAccessors.stroke.set = function (newStroke) {\n      this._stroke = newStroke;\n      this.children.forEach(function (child) { return child.stroke = newStroke; });\n    };\n\n    prototypeAccessors.stroke.get = function () {\n      return this._stroke;\n    };\n\n    Object.defineProperties( ZdogTextGroup.prototype, prototypeAccessors );\n\n    return ZdogTextGroup;\n  }(Zdog.Group));\n\n  ZdogTextGroup.optionKeys = ZdogTextGroup.optionKeys.concat(['color', 'fill', 'stroke', 'font', 'fontSize', 'value', 'textAlign', 'textBaseline']);\n  Zdog.TextGroup = ZdogTextGroup;\n  return Zdog;\n}\n\nvar index = {\n  init: function init(Zdog) {\n    // Global font list to keep track of all fonts\n    Zdog.FontList = [];\n\n    // Helper to wait for all fonts to load\n    Zdog.waitForFonts = function() {\n      return Promise.all(Zdog.FontList.map(function (font) { return font.waitForLoad(); }));\n    };\n    \n    // Register Zfont classes onto the Zdog object\n    registerFontClass(Zdog);\n    registerTextClass(Zdog);\n    registerTextGroupClass(Zdog);\n\n    return Zdog;\n  },\n  version: \"1.2.8\",\n};\n\nexport default index;\n//# sourceMappingURL=zfont.es.js.map\n"
  },
  {
    "path": "dist/zfont.js",
    "content": "/*!\n * Zfont v1.2.8\n * Text plugin for Zdog\n * 2019 James Daniel\n * MIT Licensed \n * github.com/jaames/zfont\n */\n\n(function (global, factory) {\n  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n  typeof define === 'function' && define.amd ? define(factory) :\n  (global = global || self, global.Zfont = factory());\n}(this, (function () { 'use strict';\n\n  var Typr={};Typr.parse=function(buff){var bin=Typr._bin;var data=new Uint8Array(buff);var offset=0;var sfnt_version=bin.readFixed(data,offset);offset+=4;var numTables=bin.readUshort(data,offset);offset+=2;var searchRange=bin.readUshort(data,offset);offset+=2;var entrySelector=bin.readUshort(data,offset);offset+=2;var rangeShift=bin.readUshort(data,offset);offset+=2;var tags=[\"cmap\",\"head\",\"hhea\",\"maxp\",\"hmtx\",\"name\",\"OS/2\",\"post\",\"loca\",\"glyf\",\"kern\",\"CFF \",\"GPOS\",\"GSUB\",\"SVG \"];var obj={_data:data};var tabs={};for(var i=0;i<numTables;i++){var tag=bin.readASCII(data,offset,4);offset+=4;var checkSum=bin.readUint(data,offset);offset+=4;var toffset=bin.readUint(data,offset);offset+=4;var length=bin.readUint(data,offset);offset+=4;tabs[tag]={offset:toffset,length:length};}for(var i=0;i<tags.length;i++){var t=tags[i];if(tabs[t]){ obj[t.trim()]=Typr[t.trim()].parse(data,tabs[t].offset,tabs[t].length,obj); }}return obj};Typr._tabOffset=function(data,tab){var bin=Typr._bin;var numTables=bin.readUshort(data,4);var offset=12;for(var i=0;i<numTables;i++){var tag=bin.readASCII(data,offset,4);offset+=4;var checkSum=bin.readUint(data,offset);offset+=4;var toffset=bin.readUint(data,offset);offset+=4;var length=bin.readUint(data,offset);offset+=4;if(tag==tab){ return toffset }}return 0};Typr._bin={readFixed:function(data,o){return (data[o]<<8|data[o+1])+(data[o+2]<<8|data[o+3])/(256*256+4)},readF2dot14:function(data,o){var num=Typr._bin.readShort(data,o);return num/16384;},readInt:function(buff,p){var a=Typr._bin.t.uint8;a[0]=buff[p+3];a[1]=buff[p+2];a[2]=buff[p+1];a[3]=buff[p];return Typr._bin.t.int32[0]},readInt8:function(buff,p){var a=Typr._bin.t.uint8;a[0]=buff[p];return Typr._bin.t.int8[0]},readShort:function(buff,p){var a=Typr._bin.t.uint8;a[1]=buff[p];a[0]=buff[p+1];return Typr._bin.t.int16[0]},readUshort:function(buff,p){return buff[p]<<8|buff[p+1]},readUshorts:function(buff,p,len){var arr=[];for(var i=0;i<len;i++){ arr.push(Typr._bin.readUshort(buff,p+i*2)); }return arr},readUint:function(buff,p){var a=Typr._bin.t.uint8;a[3]=buff[p];a[2]=buff[p+1];a[1]=buff[p+2];a[0]=buff[p+3];return Typr._bin.t.uint32[0]},readUint64:function(buff,p){return Typr._bin.readUint(buff,p)*(4294967295+1)+Typr._bin.readUint(buff,p+4)},readASCII:function(buff,p,l){var s=\"\";for(var i=0;i<l;i++){ s+=String.fromCharCode(buff[p+i]); }return s},readUnicode:function(buff,p,l){var s=\"\";for(var i=0;i<l;i++){var c=buff[p++]<<8|buff[p++];s+=String.fromCharCode(c);}return s},_tdec:window[\"TextDecoder\"]?new window[\"TextDecoder\"]:null,readUTF8:function(buff,p,l){var tdec=Typr._bin._tdec;if(tdec&&p==0&&l==buff.length){ return tdec[\"decode\"](buff); }return Typr._bin.readASCII(buff,p,l)},readBytes:function(buff,p,l){var arr=[];for(var i=0;i<l;i++){ arr.push(buff[p+i]); }return arr},readASCIIArray:function(buff,p,l){var s=[];for(var i=0;i<l;i++){ s.push(String.fromCharCode(buff[p+i])); }return s}};Typr._bin.t={buff:new ArrayBuffer(8)};Typr._bin.t.int8=new Int8Array(Typr._bin.t.buff);Typr._bin.t.uint8=new Uint8Array(Typr._bin.t.buff);Typr._bin.t.int16=new Int16Array(Typr._bin.t.buff);Typr._bin.t.uint16=new Uint16Array(Typr._bin.t.buff);Typr._bin.t.int32=new Int32Array(Typr._bin.t.buff);Typr._bin.t.uint32=new Uint32Array(Typr._bin.t.buff);Typr._lctf={};Typr._lctf.parse=function(data,offset,length,font,subt){var bin=Typr._bin;var obj={};var offset0=offset;var tableVersion=bin.readFixed(data,offset);offset+=4;var offScriptList=bin.readUshort(data,offset);offset+=2;var offFeatureList=bin.readUshort(data,offset);offset+=2;var offLookupList=bin.readUshort(data,offset);offset+=2;obj.scriptList=Typr._lctf.readScriptList(data,offset0+offScriptList);obj.featureList=Typr._lctf.readFeatureList(data,offset0+offFeatureList);obj.lookupList=Typr._lctf.readLookupList(data,offset0+offLookupList,subt);return obj};Typr._lctf.readLookupList=function(data,offset,subt){var bin=Typr._bin;var offset0=offset;var obj=[];var count=bin.readUshort(data,offset);offset+=2;for(var i=0;i<count;i++){var noff=bin.readUshort(data,offset);offset+=2;var lut=Typr._lctf.readLookupTable(data,offset0+noff,subt);obj.push(lut);}return obj};Typr._lctf.readLookupTable=function(data,offset,subt){var bin=Typr._bin;var offset0=offset;var obj={tabs:[]};obj.ltype=bin.readUshort(data,offset);offset+=2;obj.flag=bin.readUshort(data,offset);offset+=2;var cnt=bin.readUshort(data,offset);offset+=2;for(var i=0;i<cnt;i++){var noff=bin.readUshort(data,offset);offset+=2;var tab=subt(data,obj.ltype,offset0+noff);obj.tabs.push(tab);}return obj};Typr._lctf.numOfOnes=function(n){var num=0;for(var i=0;i<32;i++){ if((n>>>i&1)!=0){ num++; } }return num};Typr._lctf.readClassDef=function(data,offset){var bin=Typr._bin;var obj=[];var format=bin.readUshort(data,offset);offset+=2;if(format==1){var startGlyph=bin.readUshort(data,offset);offset+=2;var glyphCount=bin.readUshort(data,offset);offset+=2;for(var i=0;i<glyphCount;i++){obj.push(startGlyph+i);obj.push(startGlyph+i);obj.push(bin.readUshort(data,offset));offset+=2;}}if(format==2){var count=bin.readUshort(data,offset);offset+=2;for(var i=0;i<count;i++){obj.push(bin.readUshort(data,offset));offset+=2;obj.push(bin.readUshort(data,offset));offset+=2;obj.push(bin.readUshort(data,offset));offset+=2;}}return obj};Typr._lctf.getInterval=function(tab,val){for(var i=0;i<tab.length;i+=3){var start=tab[i],end=tab[i+1],index=tab[i+2];if(start<=val&&val<=end){ return i }}return -1};Typr._lctf.readValueRecord=function(data,offset,valFmt){var bin=Typr._bin;var arr=[];arr.push(valFmt&1?bin.readShort(data,offset):0);offset+=valFmt&1?2:0;arr.push(valFmt&2?bin.readShort(data,offset):0);offset+=valFmt&2?2:0;arr.push(valFmt&4?bin.readShort(data,offset):0);offset+=valFmt&4?2:0;arr.push(valFmt&8?bin.readShort(data,offset):0);offset+=valFmt&8?2:0;return arr};Typr._lctf.readCoverage=function(data,offset){var bin=Typr._bin;var cvg={};cvg.fmt=bin.readUshort(data,offset);offset+=2;var count=bin.readUshort(data,offset);offset+=2;if(cvg.fmt==1){ cvg.tab=bin.readUshorts(data,offset,count); }if(cvg.fmt==2){ cvg.tab=bin.readUshorts(data,offset,count*3); }return cvg};Typr._lctf.coverageIndex=function(cvg,val){var tab=cvg.tab;if(cvg.fmt==1){ return tab.indexOf(val); }if(cvg.fmt==2){var ind=Typr._lctf.getInterval(tab,val);if(ind!=-1){ return tab[ind+2]+(val-tab[ind]) }}return -1};Typr._lctf.readFeatureList=function(data,offset){var bin=Typr._bin;var offset0=offset;var obj=[];var count=bin.readUshort(data,offset);offset+=2;for(var i=0;i<count;i++){var tag=bin.readASCII(data,offset,4);offset+=4;var noff=bin.readUshort(data,offset);offset+=2;obj.push({tag:tag.trim(),tab:Typr._lctf.readFeatureTable(data,offset0+noff)});}return obj};Typr._lctf.readFeatureTable=function(data,offset){var bin=Typr._bin;var featureParams=bin.readUshort(data,offset);offset+=2;var lookupCount=bin.readUshort(data,offset);offset+=2;var indices=[];for(var i=0;i<lookupCount;i++){ indices.push(bin.readUshort(data,offset+2*i)); }return indices};Typr._lctf.readScriptList=function(data,offset){var bin=Typr._bin;var offset0=offset;var obj={};var count=bin.readUshort(data,offset);offset+=2;for(var i=0;i<count;i++){var tag=bin.readASCII(data,offset,4);offset+=4;var noff=bin.readUshort(data,offset);offset+=2;obj[tag.trim()]=Typr._lctf.readScriptTable(data,offset0+noff);}return obj};Typr._lctf.readScriptTable=function(data,offset){var bin=Typr._bin;var offset0=offset;var obj={};var defLangSysOff=bin.readUshort(data,offset);offset+=2;obj.default=Typr._lctf.readLangSysTable(data,offset0+defLangSysOff);var langSysCount=bin.readUshort(data,offset);offset+=2;for(var i=0;i<langSysCount;i++){var tag=bin.readASCII(data,offset,4);offset+=4;var langSysOff=bin.readUshort(data,offset);offset+=2;obj[tag.trim()]=Typr._lctf.readLangSysTable(data,offset0+langSysOff);}return obj};Typr._lctf.readLangSysTable=function(data,offset){var bin=Typr._bin;var obj={};var lookupOrder=bin.readUshort(data,offset);offset+=2;obj.reqFeature=bin.readUshort(data,offset);offset+=2;var featureCount=bin.readUshort(data,offset);offset+=2;obj.features=bin.readUshorts(data,offset,featureCount);return obj};Typr.CFF={};Typr.CFF.parse=function(data,offset,length){var bin=Typr._bin;data=new Uint8Array(data.buffer,offset,length);offset=0;var major=data[offset];offset++;var minor=data[offset];offset++;var hdrSize=data[offset];offset++;var offsize=data[offset];offset++;var ninds=[];offset=Typr.CFF.readIndex(data,offset,ninds);var names=[];for(var i=0;i<ninds.length-1;i++){ names.push(bin.readASCII(data,offset+ninds[i],ninds[i+1]-ninds[i])); }offset+=ninds[ninds.length-1];var tdinds=[];offset=Typr.CFF.readIndex(data,offset,tdinds);var topDicts=[];for(var i=0;i<tdinds.length-1;i++){ topDicts.push(Typr.CFF.readDict(data,offset+tdinds[i],offset+tdinds[i+1])); }offset+=tdinds[tdinds.length-1];var topdict=topDicts[0];var sinds=[];offset=Typr.CFF.readIndex(data,offset,sinds);var strings=[];for(var i=0;i<sinds.length-1;i++){ strings.push(bin.readASCII(data,offset+sinds[i],sinds[i+1]-sinds[i])); }offset+=sinds[sinds.length-1];Typr.CFF.readSubrs(data,offset,topdict);if(topdict.CharStrings){offset=topdict.CharStrings;var sinds=[];offset=Typr.CFF.readIndex(data,offset,sinds);var cstr=[];for(var i=0;i<sinds.length-1;i++){ cstr.push(bin.readBytes(data,offset+sinds[i],sinds[i+1]-sinds[i])); }topdict.CharStrings=cstr;}if(topdict.Encoding){ topdict.Encoding=Typr.CFF.readEncoding(data,topdict.Encoding,topdict.CharStrings.length); }if(topdict.charset){ topdict.charset=Typr.CFF.readCharset(data,topdict.charset,topdict.CharStrings.length); }if(topdict.Private){offset=topdict.Private[1];topdict.Private=Typr.CFF.readDict(data,offset,offset+topdict.Private[0]);if(topdict.Private.Subrs){ Typr.CFF.readSubrs(data,offset+topdict.Private.Subrs,topdict.Private); }}var obj={};for(var p in topdict){if([\"FamilyName\",\"FullName\",\"Notice\",\"version\",\"Copyright\"].indexOf(p)!=-1){ obj[p]=strings[topdict[p]-426+35]; }else { obj[p]=topdict[p]; }}return obj};Typr.CFF.readSubrs=function(data,offset,obj){var bin=Typr._bin;var gsubinds=[];offset=Typr.CFF.readIndex(data,offset,gsubinds);var bias,nSubrs=gsubinds.length;if(nSubrs<1240){ bias=107; }else if(nSubrs<33900){ bias=1131; }else { bias=32768; }obj.Bias=bias;obj.Subrs=[];for(var i=0;i<gsubinds.length-1;i++){ obj.Subrs.push(bin.readBytes(data,offset+gsubinds[i],gsubinds[i+1]-gsubinds[i])); }};Typr.CFF.tableSE=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,0,111,112,113,114,0,115,116,117,118,119,120,121,122,0,123,0,124,125,126,127,128,129,130,131,0,132,133,0,134,135,136,137,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,0,139,0,0,0,0,140,141,142,143,0,0,0,0,0,144,0,0,0,145,0,0,146,147,148,149,0,0,0,0];Typr.CFF.glyphByUnicode=function(cff,code){for(var i=0;i<cff.charset.length;i++){ if(cff.charset[i]==code){ return i; } }return -1};Typr.CFF.glyphBySE=function(cff,charcode){if(charcode<0||charcode>255){ return -1; }return Typr.CFF.glyphByUnicode(cff,Typr.CFF.tableSE[charcode])};Typr.CFF.readEncoding=function(data,offset,num){var bin=Typr._bin;var array=[\".notdef\"];var format=data[offset];offset++;if(format==0){var nCodes=data[offset];offset++;for(var i=0;i<nCodes;i++){ array.push(data[offset+i]); }}else { throw \"error: unknown encoding format: \"+format; }return array};Typr.CFF.readCharset=function(data,offset,num){var bin=Typr._bin;var charset=[\".notdef\"];var format=data[offset];offset++;if(format==0){for(var i=0;i<num;i++){var first=bin.readUshort(data,offset);offset+=2;charset.push(first);}}else if(format==1||format==2){while(charset.length<num){var first=bin.readUshort(data,offset);offset+=2;var nLeft=0;if(format==1){nLeft=data[offset];offset++;}else {nLeft=bin.readUshort(data,offset);offset+=2;}for(var i=0;i<=nLeft;i++){charset.push(first);first++;}}}else { throw \"error: format: \"+format; }return charset};Typr.CFF.readIndex=function(data,offset,inds){var bin=Typr._bin;var count=bin.readUshort(data,offset);offset+=2;var offsize=data[offset];offset++;if(offsize==1){ for(var i=0;i<count+1;i++){ inds.push(data[offset+i]); } }else if(offsize==2){ for(var i=0;i<count+1;i++){ inds.push(bin.readUshort(data,offset+i*2)); } }else if(offsize==3){ for(var i=0;i<count+1;i++){ inds.push(bin.readUint(data,offset+i*3-1)&16777215); } }else if(count!=0){ throw \"unsupported offset size: \"+offsize+\", count: \"+count; }offset+=(count+1)*offsize;return offset-1};Typr.CFF.getCharString=function(data,offset,o){var bin=Typr._bin;var b0=data[offset],b1=data[offset+1],b2=data[offset+2],b3=data[offset+3],b4=data[offset+4];var vs=1;var op=null,val=null;if(b0<=20){op=b0;vs=1;}if(b0==12){op=b0*100+b1;vs=2;}if(21<=b0&&b0<=27){op=b0;vs=1;}if(b0==28){val=bin.readShort(data,offset+1);vs=3;}if(29<=b0&&b0<=31){op=b0;vs=1;}if(32<=b0&&b0<=246){val=b0-139;vs=1;}if(247<=b0&&b0<=250){val=(b0-247)*256+b1+108;vs=2;}if(251<=b0&&b0<=254){val=-(b0-251)*256-b1-108;vs=2;}if(b0==255){val=bin.readInt(data,offset+1)/65535;vs=5;}o.val=val!=null?val:\"o\"+op;o.size=vs;};Typr.CFF.readCharString=function(data,offset,length){var end=offset+length;var bin=Typr._bin;var arr=[];while(offset<end){var b0=data[offset],b1=data[offset+1],b2=data[offset+2],b3=data[offset+3],b4=data[offset+4];var vs=1;var op=null,val=null;if(b0<=20){op=b0;vs=1;}if(b0==12){op=b0*100+b1;vs=2;}if(b0==19||b0==20){op=b0;vs=2;}if(21<=b0&&b0<=27){op=b0;vs=1;}if(b0==28){val=bin.readShort(data,offset+1);vs=3;}if(29<=b0&&b0<=31){op=b0;vs=1;}if(32<=b0&&b0<=246){val=b0-139;vs=1;}if(247<=b0&&b0<=250){val=(b0-247)*256+b1+108;vs=2;}if(251<=b0&&b0<=254){val=-(b0-251)*256-b1-108;vs=2;}if(b0==255){val=bin.readInt(data,offset+1)/65535;vs=5;}arr.push(val!=null?val:\"o\"+op);offset+=vs;}return arr};Typr.CFF.readDict=function(data,offset,end){var bin=Typr._bin;var dict={};var carr=[];while(offset<end){var b0=data[offset],b1=data[offset+1],b2=data[offset+2],b3=data[offset+3],b4=data[offset+4];var vs=1;var key=null,val=null;if(b0==28){val=bin.readShort(data,offset+1);vs=3;}if(b0==29){val=bin.readInt(data,offset+1);vs=5;}if(32<=b0&&b0<=246){val=b0-139;vs=1;}if(247<=b0&&b0<=250){val=(b0-247)*256+b1+108;vs=2;}if(251<=b0&&b0<=254){val=-(b0-251)*256-b1-108;vs=2;}if(b0==255){val=bin.readInt(data,offset+1)/65535;vs=5;throw \"unknown number\"}if(b0==30){var nibs=[];vs=1;while(true){var b=data[offset+vs];vs++;var nib0=b>>4,nib1=b&15;if(nib0!=15){ nibs.push(nib0); }if(nib1!=15){ nibs.push(nib1); }if(nib1==15){ break }}var s=\"\";var chars=[0,1,2,3,4,5,6,7,8,9,\".\",\"e\",\"e-\",\"reserved\",\"-\",\"endOfNumber\"];for(var i=0;i<nibs.length;i++){ s+=chars[nibs[i]]; }val=parseFloat(s);}if(b0<=21){var keys=[\"version\",\"Notice\",\"FullName\",\"FamilyName\",\"Weight\",\"FontBBox\",\"BlueValues\",\"OtherBlues\",\"FamilyBlues\",\"FamilyOtherBlues\",\"StdHW\",\"StdVW\",\"escape\",\"UniqueID\",\"XUID\",\"charset\",\"Encoding\",\"CharStrings\",\"Private\",\"Subrs\",\"defaultWidthX\",\"nominalWidthX\"];key=keys[b0];vs=1;if(b0==12){var keys=[\"Copyright\",\"isFixedPitch\",\"ItalicAngle\",\"UnderlinePosition\",\"UnderlineThickness\",\"PaintType\",\"CharstringType\",\"FontMatrix\",\"StrokeWidth\",\"BlueScale\",\"BlueShift\",\"BlueFuzz\",\"StemSnapH\",\"StemSnapV\",\"ForceBold\",0,0,\"LanguageGroup\",\"ExpansionFactor\",\"initialRandomSeed\",\"SyntheticBase\",\"PostScript\",\"BaseFontName\",\"BaseFontBlend\",0,0,0,0,0,0,\"ROS\",\"CIDFontVersion\",\"CIDFontRevision\",\"CIDFontType\",\"CIDCount\",\"UIDBase\",\"FDArray\",\"FDSelect\",\"FontName\"];key=keys[b1];vs=2;}}if(key!=null){dict[key]=carr.length==1?carr[0]:carr;carr=[];}else { carr.push(val); }offset+=vs;}return dict};Typr.cmap={};Typr.cmap.parse=function(data,offset,length){data=new Uint8Array(data.buffer,offset,length);offset=0;var bin=Typr._bin;var obj={};var version=bin.readUshort(data,offset);offset+=2;var numTables=bin.readUshort(data,offset);offset+=2;var offs=[];obj.tables=[];for(var i=0;i<numTables;i++){var platformID=bin.readUshort(data,offset);offset+=2;var encodingID=bin.readUshort(data,offset);offset+=2;var noffset=bin.readUint(data,offset);offset+=4;var id=\"p\"+platformID+\"e\"+encodingID;var tind=offs.indexOf(noffset);if(tind==-1){tind=obj.tables.length;var subt;offs.push(noffset);var format=bin.readUshort(data,noffset);if(format==0){ subt=Typr.cmap.parse0(data,noffset); }else if(format==4){ subt=Typr.cmap.parse4(data,noffset); }else if(format==6){ subt=Typr.cmap.parse6(data,noffset); }else if(format==12){ subt=Typr.cmap.parse12(data,noffset); }else { console.log(\"unknown format: \"+format,platformID,encodingID,noffset); }obj.tables.push(subt);}if(obj[id]!=null){ throw \"multiple tables for one platform+encoding\"; }obj[id]=tind;}return obj};Typr.cmap.parse0=function(data,offset){var bin=Typr._bin;var obj={};obj.format=bin.readUshort(data,offset);offset+=2;var len=bin.readUshort(data,offset);offset+=2;var lang=bin.readUshort(data,offset);offset+=2;obj.map=[];for(var i=0;i<len-6;i++){ obj.map.push(data[offset+i]); }return obj};Typr.cmap.parse4=function(data,offset){var bin=Typr._bin;var offset0=offset;var obj={};obj.format=bin.readUshort(data,offset);offset+=2;var length=bin.readUshort(data,offset);offset+=2;var language=bin.readUshort(data,offset);offset+=2;var segCountX2=bin.readUshort(data,offset);offset+=2;var segCount=segCountX2/2;obj.searchRange=bin.readUshort(data,offset);offset+=2;obj.entrySelector=bin.readUshort(data,offset);offset+=2;obj.rangeShift=bin.readUshort(data,offset);offset+=2;obj.endCount=bin.readUshorts(data,offset,segCount);offset+=segCount*2;offset+=2;obj.startCount=bin.readUshorts(data,offset,segCount);offset+=segCount*2;obj.idDelta=[];for(var i=0;i<segCount;i++){obj.idDelta.push(bin.readShort(data,offset));offset+=2;}obj.idRangeOffset=bin.readUshorts(data,offset,segCount);offset+=segCount*2;obj.glyphIdArray=[];while(offset<offset0+length){obj.glyphIdArray.push(bin.readUshort(data,offset));offset+=2;}return obj};Typr.cmap.parse6=function(data,offset){var bin=Typr._bin;var obj={};obj.format=bin.readUshort(data,offset);offset+=2;var length=bin.readUshort(data,offset);offset+=2;var language=bin.readUshort(data,offset);offset+=2;obj.firstCode=bin.readUshort(data,offset);offset+=2;var entryCount=bin.readUshort(data,offset);offset+=2;obj.glyphIdArray=[];for(var i=0;i<entryCount;i++){obj.glyphIdArray.push(bin.readUshort(data,offset));offset+=2;}return obj};Typr.cmap.parse12=function(data,offset){var bin=Typr._bin;var obj={};obj.format=bin.readUshort(data,offset);offset+=2;offset+=2;var length=bin.readUint(data,offset);offset+=4;var lang=bin.readUint(data,offset);offset+=4;var nGroups=bin.readUint(data,offset);offset+=4;obj.groups=[];for(var i=0;i<nGroups;i++){var off=offset+i*12;var startCharCode=bin.readUint(data,off+0);var endCharCode=bin.readUint(data,off+4);var startGlyphID=bin.readUint(data,off+8);obj.groups.push([startCharCode,endCharCode,startGlyphID]);}return obj};Typr.glyf={};Typr.glyf.parse=function(data,offset,length,font){var obj=[];for(var g=0;g<font.maxp.numGlyphs;g++){ obj.push(null); }return obj};Typr.glyf._parseGlyf=function(font,g){var bin=Typr._bin;var data=font._data;var offset=Typr._tabOffset(data,\"glyf\")+font.loca[g];if(font.loca[g]==font.loca[g+1]){ return null; }var gl={};gl.noc=bin.readShort(data,offset);offset+=2;gl.xMin=bin.readShort(data,offset);offset+=2;gl.yMin=bin.readShort(data,offset);offset+=2;gl.xMax=bin.readShort(data,offset);offset+=2;gl.yMax=bin.readShort(data,offset);offset+=2;if(gl.xMin>=gl.xMax||gl.yMin>=gl.yMax){ return null; }if(gl.noc>0){gl.endPts=[];for(var i=0;i<gl.noc;i++){gl.endPts.push(bin.readUshort(data,offset));offset+=2;}var instructionLength=bin.readUshort(data,offset);offset+=2;if(data.length-offset<instructionLength){ return null; }gl.instructions=bin.readBytes(data,offset,instructionLength);offset+=instructionLength;var crdnum=gl.endPts[gl.noc-1]+1;gl.flags=[];for(var i=0;i<crdnum;i++){var flag=data[offset];offset++;gl.flags.push(flag);if((flag&8)!=0){var rep=data[offset];offset++;for(var j=0;j<rep;j++){gl.flags.push(flag);i++;}}}gl.xs=[];for(var i=0;i<crdnum;i++){var i8=(gl.flags[i]&2)!=0,same=(gl.flags[i]&16)!=0;if(i8){gl.xs.push(same?data[offset]:-data[offset]);offset++;}else {if(same){ gl.xs.push(0); }else {gl.xs.push(bin.readShort(data,offset));offset+=2;}}}gl.ys=[];for(var i=0;i<crdnum;i++){var i8=(gl.flags[i]&4)!=0,same=(gl.flags[i]&32)!=0;if(i8){gl.ys.push(same?data[offset]:-data[offset]);offset++;}else {if(same){ gl.ys.push(0); }else {gl.ys.push(bin.readShort(data,offset));offset+=2;}}}var x=0,y=0;for(var i=0;i<crdnum;i++){x+=gl.xs[i];y+=gl.ys[i];gl.xs[i]=x;gl.ys[i]=y;}}else {var ARG_1_AND_2_ARE_WORDS=1<<0;var ARGS_ARE_XY_VALUES=1<<1;var WE_HAVE_A_SCALE=1<<3;var MORE_COMPONENTS=1<<5;var WE_HAVE_AN_X_AND_Y_SCALE=1<<6;var WE_HAVE_A_TWO_BY_TWO=1<<7;var WE_HAVE_INSTRUCTIONS=1<<8;gl.parts=[];var flags;do{flags=bin.readUshort(data,offset);offset+=2;var part={m:{a:1,b:0,c:0,d:1,tx:0,ty:0},p1:-1,p2:-1};gl.parts.push(part);part.glyphIndex=bin.readUshort(data,offset);offset+=2;if(flags&ARG_1_AND_2_ARE_WORDS){var arg1=bin.readShort(data,offset);offset+=2;var arg2=bin.readShort(data,offset);offset+=2;}else {var arg1=bin.readInt8(data,offset);offset++;var arg2=bin.readInt8(data,offset);offset++;}if(flags&ARGS_ARE_XY_VALUES){part.m.tx=arg1;part.m.ty=arg2;}else {part.p1=arg1;part.p2=arg2;}if(flags&WE_HAVE_A_SCALE){part.m.a=part.m.d=bin.readF2dot14(data,offset);offset+=2;}else if(flags&WE_HAVE_AN_X_AND_Y_SCALE){part.m.a=bin.readF2dot14(data,offset);offset+=2;part.m.d=bin.readF2dot14(data,offset);offset+=2;}else if(flags&WE_HAVE_A_TWO_BY_TWO){part.m.a=bin.readF2dot14(data,offset);offset+=2;part.m.b=bin.readF2dot14(data,offset);offset+=2;part.m.c=bin.readF2dot14(data,offset);offset+=2;part.m.d=bin.readF2dot14(data,offset);offset+=2;}}while(flags&MORE_COMPONENTS);if(flags&WE_HAVE_INSTRUCTIONS){var numInstr=bin.readUshort(data,offset);offset+=2;gl.instr=[];for(var i=0;i<numInstr;i++){gl.instr.push(data[offset]);offset++;}}}return gl};Typr.GPOS={};Typr.GPOS.parse=function(data,offset,length,font){return Typr._lctf.parse(data,offset,length,font,Typr.GPOS.subt)};Typr.GPOS.subt=function(data,ltype,offset){if(ltype!=2){ return null; }var bin=Typr._bin,offset0=offset,tab={};tab.format=bin.readUshort(data,offset);offset+=2;var covOff=bin.readUshort(data,offset);offset+=2;tab.coverage=Typr._lctf.readCoverage(data,covOff+offset0);tab.valFmt1=bin.readUshort(data,offset);offset+=2;tab.valFmt2=bin.readUshort(data,offset);offset+=2;var ones1=Typr._lctf.numOfOnes(tab.valFmt1);var ones2=Typr._lctf.numOfOnes(tab.valFmt2);if(tab.format==1){tab.pairsets=[];var count=bin.readUshort(data,offset);offset+=2;for(var i=0;i<count;i++){var psoff=bin.readUshort(data,offset);offset+=2;psoff+=offset0;var pvcount=bin.readUshort(data,psoff);psoff+=2;var arr=[];for(var j=0;j<pvcount;j++){var gid2=bin.readUshort(data,psoff);psoff+=2;var value1,value2;if(tab.valFmt1!=0){value1=Typr._lctf.readValueRecord(data,psoff,tab.valFmt1);psoff+=ones1*2;}if(tab.valFmt2!=0){value2=Typr._lctf.readValueRecord(data,psoff,tab.valFmt2);psoff+=ones2*2;}arr.push({gid2:gid2,val1:value1,val2:value2});}tab.pairsets.push(arr);}}if(tab.format==2){var classDef1=bin.readUshort(data,offset);offset+=2;var classDef2=bin.readUshort(data,offset);offset+=2;var class1Count=bin.readUshort(data,offset);offset+=2;var class2Count=bin.readUshort(data,offset);offset+=2;tab.classDef1=Typr._lctf.readClassDef(data,offset0+classDef1);tab.classDef2=Typr._lctf.readClassDef(data,offset0+classDef2);tab.matrix=[];for(var i=0;i<class1Count;i++){var row=[];for(var j=0;j<class2Count;j++){var value1=null,value2=null;if(tab.valFmt1!=0){value1=Typr._lctf.readValueRecord(data,offset,tab.valFmt1);offset+=ones1*2;}if(tab.valFmt2!=0){value2=Typr._lctf.readValueRecord(data,offset,tab.valFmt2);offset+=ones2*2;}row.push({val1:value1,val2:value2});}tab.matrix.push(row);}}return tab};Typr.GSUB={};Typr.GSUB.parse=function(data,offset,length,font){return Typr._lctf.parse(data,offset,length,font,Typr.GSUB.subt)};Typr.GSUB.subt=function(data,ltype,offset){var bin=Typr._bin,offset0=offset,tab={};if(ltype!=1&&ltype!=4&&ltype!=5){ return null; }tab.fmt=bin.readUshort(data,offset);offset+=2;var covOff=bin.readUshort(data,offset);offset+=2;tab.coverage=Typr._lctf.readCoverage(data,covOff+offset0);if(ltype==1){if(tab.fmt==1){tab.delta=bin.readShort(data,offset);offset+=2;}else if(tab.fmt==2){var cnt=bin.readUshort(data,offset);offset+=2;tab.newg=bin.readUshorts(data,offset,cnt);offset+=tab.newg.length*2;}}else if(ltype==4){tab.vals=[];var cnt=bin.readUshort(data,offset);offset+=2;for(var i=0;i<cnt;i++){var loff=bin.readUshort(data,offset);offset+=2;tab.vals.push(Typr.GSUB.readLigatureSet(data,offset0+loff));}}else if(ltype==5){if(tab.fmt==2){var cDefOffset=bin.readUshort(data,offset);offset+=2;tab.cDef=Typr._lctf.readClassDef(data,offset0+cDefOffset);tab.scset=[];var subClassSetCount=bin.readUshort(data,offset);offset+=2;for(var i=0;i<subClassSetCount;i++){var scsOff=bin.readUshort(data,offset);offset+=2;tab.scset.push(scsOff==0?null:Typr.GSUB.readSubClassSet(data,offset0+scsOff));}}else { console.log(\"unknown table format\",tab.fmt); }}return tab};Typr.GSUB.readSubClassSet=function(data,offset){var rUs=Typr._bin.readUshort,offset0=offset,lset=[];var cnt=rUs(data,offset);offset+=2;for(var i=0;i<cnt;i++){var loff=rUs(data,offset);offset+=2;lset.push(Typr.GSUB.readSubClassRule(data,offset0+loff));}return lset};Typr.GSUB.readSubClassRule=function(data,offset){var rUs=Typr._bin.readUshort,rule={};var gcount=rUs(data,offset);offset+=2;var scount=rUs(data,offset);offset+=2;rule.input=[];for(var i=0;i<gcount-1;i++){rule.input.push(rUs(data,offset));offset+=2;}rule.substLookupRecords=Typr.GSUB.readSubstLookupRecords(data,offset,scount);return rule};Typr.GSUB.readSubstLookupRecords=function(data,offset,cnt){var rUs=Typr._bin.readUshort;var out=[];for(var i=0;i<cnt;i++){out.push(rUs(data,offset),rUs(data,offset+2));offset+=4;}return out};Typr.GSUB.readChainSubClassSet=function(data,offset){var bin=Typr._bin,offset0=offset,lset=[];var cnt=bin.readUshort(data,offset);offset+=2;for(var i=0;i<cnt;i++){var loff=bin.readUshort(data,offset);offset+=2;lset.push(Typr.GSUB.readChainSubClassRule(data,offset0+loff));}return lset};Typr.GSUB.readChainSubClassRule=function(data,offset){var bin=Typr._bin,rule={};var pps=[\"backtrack\",\"input\",\"lookahead\"];for(var pi=0;pi<pps.length;pi++){var cnt=bin.readUshort(data,offset);offset+=2;if(pi==1){ cnt--; }rule[pps[pi]]=bin.readUshorts(data,offset,cnt);offset+=rule[pps[pi]].length*2;}var cnt=bin.readUshort(data,offset);offset+=2;rule.subst=bin.readUshorts(data,offset,cnt*2);offset+=rule.subst.length*2;return rule};Typr.GSUB.readLigatureSet=function(data,offset){var bin=Typr._bin,offset0=offset,lset=[];var lcnt=bin.readUshort(data,offset);offset+=2;for(var j=0;j<lcnt;j++){var loff=bin.readUshort(data,offset);offset+=2;lset.push(Typr.GSUB.readLigature(data,offset0+loff));}return lset};Typr.GSUB.readLigature=function(data,offset){var bin=Typr._bin,lig={chain:[]};lig.nglyph=bin.readUshort(data,offset);offset+=2;var ccnt=bin.readUshort(data,offset);offset+=2;for(var k=0;k<ccnt-1;k++){lig.chain.push(bin.readUshort(data,offset));offset+=2;}return lig};Typr.head={};Typr.head.parse=function(data,offset,length){var bin=Typr._bin;var obj={};var tableVersion=bin.readFixed(data,offset);offset+=4;obj.fontRevision=bin.readFixed(data,offset);offset+=4;var checkSumAdjustment=bin.readUint(data,offset);offset+=4;var magicNumber=bin.readUint(data,offset);offset+=4;obj.flags=bin.readUshort(data,offset);offset+=2;obj.unitsPerEm=bin.readUshort(data,offset);offset+=2;obj.created=bin.readUint64(data,offset);offset+=8;obj.modified=bin.readUint64(data,offset);offset+=8;obj.xMin=bin.readShort(data,offset);offset+=2;obj.yMin=bin.readShort(data,offset);offset+=2;obj.xMax=bin.readShort(data,offset);offset+=2;obj.yMax=bin.readShort(data,offset);offset+=2;obj.macStyle=bin.readUshort(data,offset);offset+=2;obj.lowestRecPPEM=bin.readUshort(data,offset);offset+=2;obj.fontDirectionHint=bin.readShort(data,offset);offset+=2;obj.indexToLocFormat=bin.readShort(data,offset);offset+=2;obj.glyphDataFormat=bin.readShort(data,offset);offset+=2;return obj};Typr.hhea={};Typr.hhea.parse=function(data,offset,length){var bin=Typr._bin;var obj={};var tableVersion=bin.readFixed(data,offset);offset+=4;obj.ascender=bin.readShort(data,offset);offset+=2;obj.descender=bin.readShort(data,offset);offset+=2;obj.lineGap=bin.readShort(data,offset);offset+=2;obj.advanceWidthMax=bin.readUshort(data,offset);offset+=2;obj.minLeftSideBearing=bin.readShort(data,offset);offset+=2;obj.minRightSideBearing=bin.readShort(data,offset);offset+=2;obj.xMaxExtent=bin.readShort(data,offset);offset+=2;obj.caretSlopeRise=bin.readShort(data,offset);offset+=2;obj.caretSlopeRun=bin.readShort(data,offset);offset+=2;obj.caretOffset=bin.readShort(data,offset);offset+=2;offset+=4*2;obj.metricDataFormat=bin.readShort(data,offset);offset+=2;obj.numberOfHMetrics=bin.readUshort(data,offset);offset+=2;return obj};Typr.hmtx={};Typr.hmtx.parse=function(data,offset,length,font){var bin=Typr._bin;var obj={};obj.aWidth=[];obj.lsBearing=[];var aw=0,lsb=0;for(var i=0;i<font.maxp.numGlyphs;i++){if(i<font.hhea.numberOfHMetrics){aw=bin.readUshort(data,offset);offset+=2;lsb=bin.readShort(data,offset);offset+=2;}obj.aWidth.push(aw);obj.lsBearing.push(lsb);}return obj};Typr.kern={};Typr.kern.parse=function(data,offset,length,font){var bin=Typr._bin;var version=bin.readUshort(data,offset);offset+=2;if(version==1){ return Typr.kern.parseV1(data,offset-2,length,font); }var nTables=bin.readUshort(data,offset);offset+=2;var map={glyph1:[],rval:[]};for(var i=0;i<nTables;i++){offset+=2;var length=bin.readUshort(data,offset);offset+=2;var coverage=bin.readUshort(data,offset);offset+=2;var format=coverage>>>8;format&=15;if(format==0){ offset=Typr.kern.readFormat0(data,offset,map); }else { throw \"unknown kern table format: \"+format }}return map};Typr.kern.parseV1=function(data,offset,length,font){var bin=Typr._bin;var version=bin.readFixed(data,offset);offset+=4;var nTables=bin.readUint(data,offset);offset+=4;var map={glyph1:[],rval:[]};for(var i=0;i<nTables;i++){var length=bin.readUint(data,offset);offset+=4;var coverage=bin.readUshort(data,offset);offset+=2;var tupleIndex=bin.readUshort(data,offset);offset+=2;var format=coverage>>>8;format&=15;if(format==0){ offset=Typr.kern.readFormat0(data,offset,map); }else { throw \"unknown kern table format: \"+format }}return map};Typr.kern.readFormat0=function(data,offset,map){var bin=Typr._bin;var pleft=-1;var nPairs=bin.readUshort(data,offset);offset+=2;var searchRange=bin.readUshort(data,offset);offset+=2;var entrySelector=bin.readUshort(data,offset);offset+=2;var rangeShift=bin.readUshort(data,offset);offset+=2;for(var j=0;j<nPairs;j++){var left=bin.readUshort(data,offset);offset+=2;var right=bin.readUshort(data,offset);offset+=2;var value=bin.readShort(data,offset);offset+=2;if(left!=pleft){map.glyph1.push(left);map.rval.push({glyph2:[],vals:[]});}var rval=map.rval[map.rval.length-1];rval.glyph2.push(right);rval.vals.push(value);pleft=left;}return offset};Typr.loca={};Typr.loca.parse=function(data,offset,length,font){var bin=Typr._bin;var obj=[];var ver=font.head.indexToLocFormat;var len=font.maxp.numGlyphs+1;if(ver==0){ for(var i=0;i<len;i++){ obj.push(bin.readUshort(data,offset+(i<<1))<<1); } }if(ver==1){ for(var i=0;i<len;i++){ obj.push(bin.readUint(data,offset+(i<<2))); } }return obj};Typr.maxp={};Typr.maxp.parse=function(data,offset,length){var bin=Typr._bin;var obj={};var ver=bin.readUint(data,offset);offset+=4;obj.numGlyphs=bin.readUshort(data,offset);offset+=2;if(ver==65536){obj.maxPoints=bin.readUshort(data,offset);offset+=2;obj.maxContours=bin.readUshort(data,offset);offset+=2;obj.maxCompositePoints=bin.readUshort(data,offset);offset+=2;obj.maxCompositeContours=bin.readUshort(data,offset);offset+=2;obj.maxZones=bin.readUshort(data,offset);offset+=2;obj.maxTwilightPoints=bin.readUshort(data,offset);offset+=2;obj.maxStorage=bin.readUshort(data,offset);offset+=2;obj.maxFunctionDefs=bin.readUshort(data,offset);offset+=2;obj.maxInstructionDefs=bin.readUshort(data,offset);offset+=2;obj.maxStackElements=bin.readUshort(data,offset);offset+=2;obj.maxSizeOfInstructions=bin.readUshort(data,offset);offset+=2;obj.maxComponentElements=bin.readUshort(data,offset);offset+=2;obj.maxComponentDepth=bin.readUshort(data,offset);offset+=2;}return obj};Typr.name={};Typr.name.parse=function(data,offset,length){var bin=Typr._bin;var obj={};var format=bin.readUshort(data,offset);offset+=2;var count=bin.readUshort(data,offset);offset+=2;var stringOffset=bin.readUshort(data,offset);offset+=2;var offset0=offset;for(var i=0;i<count;i++){var platformID=bin.readUshort(data,offset);offset+=2;var encodingID=bin.readUshort(data,offset);offset+=2;var languageID=bin.readUshort(data,offset);offset+=2;var nameID=bin.readUshort(data,offset);offset+=2;var length=bin.readUshort(data,offset);offset+=2;var noffset=bin.readUshort(data,offset);offset+=2;var plat=\"p\"+platformID;if(obj[plat]==null){ obj[plat]={}; }var names=[\"copyright\",\"fontFamily\",\"fontSubfamily\",\"ID\",\"fullName\",\"version\",\"postScriptName\",\"trademark\",\"manufacturer\",\"designer\",\"description\",\"urlVendor\",\"urlDesigner\",\"licence\",\"licenceURL\",\"---\",\"typoFamilyName\",\"typoSubfamilyName\",\"compatibleFull\",\"sampleText\",\"postScriptCID\",\"wwsFamilyName\",\"wwsSubfamilyName\",\"lightPalette\",\"darkPalette\"];var cname=names[nameID];var soff=offset0+count*12+noffset;var str;if(platformID==0){ str=bin.readUnicode(data,soff,length/2); }else if(platformID==3&&encodingID==0){ str=bin.readUnicode(data,soff,length/2); }else if(encodingID==0){ str=bin.readASCII(data,soff,length); }else if(encodingID==1){ str=bin.readUnicode(data,soff,length/2); }else if(encodingID==3){ str=bin.readUnicode(data,soff,length/2); }else if(platformID==1){str=bin.readASCII(data,soff,length);console.log(\"reading unknown MAC encoding \"+encodingID+\" as ASCII\");}else { throw \"unknown encoding \"+encodingID+\", platformID: \"+platformID; }obj[plat][cname]=str;obj[plat]._lang=languageID;}for(var p in obj){ if(obj[p].postScriptName!=null&&obj[p]._lang==1033){ return obj[p]; } }for(var p in obj){ if(obj[p].postScriptName!=null&&obj[p]._lang==3084){ return obj[p]; } }for(var p in obj){ if(obj[p].postScriptName!=null){ return obj[p]; } }var tname;for(var p in obj){tname=p;break}console.log(\"returning name table with languageID \"+obj[tname]._lang);return obj[tname]};Typr[\"OS/2\"]={};Typr[\"OS/2\"].parse=function(data,offset,length){var bin=Typr._bin;var ver=bin.readUshort(data,offset);offset+=2;var obj={};if(ver==0){ Typr[\"OS/2\"].version0(data,offset,obj); }else if(ver==1){ Typr[\"OS/2\"].version1(data,offset,obj); }else if(ver==2||ver==3||ver==4){ Typr[\"OS/2\"].version2(data,offset,obj); }else if(ver==5){ Typr[\"OS/2\"].version5(data,offset,obj); }else { throw \"unknown OS/2 table version: \"+ver; }return obj};Typr[\"OS/2\"].version0=function(data,offset,obj){var bin=Typr._bin;obj.xAvgCharWidth=bin.readShort(data,offset);offset+=2;obj.usWeightClass=bin.readUshort(data,offset);offset+=2;obj.usWidthClass=bin.readUshort(data,offset);offset+=2;obj.fsType=bin.readUshort(data,offset);offset+=2;obj.ySubscriptXSize=bin.readShort(data,offset);offset+=2;obj.ySubscriptYSize=bin.readShort(data,offset);offset+=2;obj.ySubscriptXOffset=bin.readShort(data,offset);offset+=2;obj.ySubscriptYOffset=bin.readShort(data,offset);offset+=2;obj.ySuperscriptXSize=bin.readShort(data,offset);offset+=2;obj.ySuperscriptYSize=bin.readShort(data,offset);offset+=2;obj.ySuperscriptXOffset=bin.readShort(data,offset);offset+=2;obj.ySuperscriptYOffset=bin.readShort(data,offset);offset+=2;obj.yStrikeoutSize=bin.readShort(data,offset);offset+=2;obj.yStrikeoutPosition=bin.readShort(data,offset);offset+=2;obj.sFamilyClass=bin.readShort(data,offset);offset+=2;obj.panose=bin.readBytes(data,offset,10);offset+=10;obj.ulUnicodeRange1=bin.readUint(data,offset);offset+=4;obj.ulUnicodeRange2=bin.readUint(data,offset);offset+=4;obj.ulUnicodeRange3=bin.readUint(data,offset);offset+=4;obj.ulUnicodeRange4=bin.readUint(data,offset);offset+=4;obj.achVendID=[bin.readInt8(data,offset),bin.readInt8(data,offset+1),bin.readInt8(data,offset+2),bin.readInt8(data,offset+3)];offset+=4;obj.fsSelection=bin.readUshort(data,offset);offset+=2;obj.usFirstCharIndex=bin.readUshort(data,offset);offset+=2;obj.usLastCharIndex=bin.readUshort(data,offset);offset+=2;obj.sTypoAscender=bin.readShort(data,offset);offset+=2;obj.sTypoDescender=bin.readShort(data,offset);offset+=2;obj.sTypoLineGap=bin.readShort(data,offset);offset+=2;obj.usWinAscent=bin.readUshort(data,offset);offset+=2;obj.usWinDescent=bin.readUshort(data,offset);offset+=2;return offset};Typr[\"OS/2\"].version1=function(data,offset,obj){var bin=Typr._bin;offset=Typr[\"OS/2\"].version0(data,offset,obj);obj.ulCodePageRange1=bin.readUint(data,offset);offset+=4;obj.ulCodePageRange2=bin.readUint(data,offset);offset+=4;return offset};Typr[\"OS/2\"].version2=function(data,offset,obj){var bin=Typr._bin;offset=Typr[\"OS/2\"].version1(data,offset,obj);obj.sxHeight=bin.readShort(data,offset);offset+=2;obj.sCapHeight=bin.readShort(data,offset);offset+=2;obj.usDefault=bin.readUshort(data,offset);offset+=2;obj.usBreak=bin.readUshort(data,offset);offset+=2;obj.usMaxContext=bin.readUshort(data,offset);offset+=2;return offset};Typr[\"OS/2\"].version5=function(data,offset,obj){var bin=Typr._bin;offset=Typr[\"OS/2\"].version2(data,offset,obj);obj.usLowerOpticalPointSize=bin.readUshort(data,offset);offset+=2;obj.usUpperOpticalPointSize=bin.readUshort(data,offset);offset+=2;return offset};Typr.post={};Typr.post.parse=function(data,offset,length){var bin=Typr._bin;var obj={};obj.version=bin.readFixed(data,offset);offset+=4;obj.italicAngle=bin.readFixed(data,offset);offset+=4;obj.underlinePosition=bin.readShort(data,offset);offset+=2;obj.underlineThickness=bin.readShort(data,offset);offset+=2;return obj};Typr.SVG={};Typr.SVG.parse=function(data,offset,length){var bin=Typr._bin;var obj={entries:[]};var offset0=offset;var tableVersion=bin.readUshort(data,offset);offset+=2;var svgDocIndexOffset=bin.readUint(data,offset);offset+=4;var reserved=bin.readUint(data,offset);offset+=4;offset=svgDocIndexOffset+offset0;var numEntries=bin.readUshort(data,offset);offset+=2;for(var i=0;i<numEntries;i++){var startGlyphID=bin.readUshort(data,offset);offset+=2;var endGlyphID=bin.readUshort(data,offset);offset+=2;var svgDocOffset=bin.readUint(data,offset);offset+=4;var svgDocLength=bin.readUint(data,offset);offset+=4;var sbuf=new Uint8Array(data.buffer,offset0+svgDocOffset+svgDocIndexOffset,svgDocLength);var svg=bin.readUTF8(sbuf,0,sbuf.length);for(var f=startGlyphID;f<=endGlyphID;f++){obj.entries[f]=svg;}}return obj};Typr.SVG.toPath=function(str){var pth={cmds:[],crds:[]};if(str==null){ return pth; }var prsr=new DOMParser;var doc=prsr[\"parseFromString\"](str,\"image/svg+xml\");var svg=doc.firstChild;while(svg.tagName!=\"svg\"){ svg=svg.nextSibling; }var vb=svg.getAttribute(\"viewBox\");if(vb){ vb=vb.trim().split(\" \").map(parseFloat); }else { vb=[0,0,1e3,1e3]; }Typr.SVG._toPath(svg.children,pth);for(var i=0;i<pth.crds.length;i+=2){var x=pth.crds[i],y=pth.crds[i+1];x-=vb[0];y-=vb[1];y=-y;pth.crds[i]=x;pth.crds[i+1]=y;}return pth};Typr.SVG._toPath=function(nds,pth,fill){for(var ni=0;ni<nds.length;ni++){var nd=nds[ni],tn=nd.tagName;var cfl=nd.getAttribute(\"fill\");if(cfl==null){ cfl=fill; }if(tn==\"g\"){ Typr.SVG._toPath(nd.children,pth,cfl); }else if(tn==\"path\"){pth.cmds.push(cfl?cfl:\"#000000\");var d=nd.getAttribute(\"d\");var toks=Typr.SVG._tokens(d);Typr.SVG._toksToPath(toks,pth);pth.cmds.push(\"X\");}else if(tn==\"defs\");else { console.log(tn,nd); }}};Typr.SVG._tokens=function(d){var ts=[],off=0,rn=false,cn=\"\";while(off<d.length){var cc=d.charCodeAt(off),ch=d.charAt(off);off++;var isNum=48<=cc&&cc<=57||ch==\".\"||ch==\"-\";if(rn){if(ch==\"-\"){ts.push(parseFloat(cn));cn=ch;}else if(isNum){ cn+=ch; }else {ts.push(parseFloat(cn));if(ch!=\",\"&&ch!=\" \"){ ts.push(ch); }rn=false;}}else {if(isNum){cn=ch;rn=true;}else if(ch!=\",\"&&ch!=\" \"){ ts.push(ch); }}}if(rn){ ts.push(parseFloat(cn)); }return ts};Typr.SVG._toksToPath=function(ts,pth){var i=0,x=0,y=0,ox=0,oy=0;var pc={M:2,L:2,H:1,V:1,S:4,C:6};var cmds=pth.cmds,crds=pth.crds;while(i<ts.length){var cmd=ts[i];i++;if(cmd==\"z\"){cmds.push(\"Z\");x=ox;y=oy;}else {var cmu=cmd.toUpperCase();var ps=pc[cmu],reps=Typr.SVG._reps(ts,i,ps);for(var j=0;j<reps;j++){var xi=0,yi=0;if(cmd!=cmu){xi=x;yi=y;}if(cmu==\"M\"){x=xi+ts[i++];y=yi+ts[i++];cmds.push(\"M\");crds.push(x,y);ox=x;oy=y;}else if(cmu==\"L\"){x=xi+ts[i++];y=yi+ts[i++];cmds.push(\"L\");crds.push(x,y);}else if(cmu==\"H\"){x=xi+ts[i++];cmds.push(\"L\");crds.push(x,y);}else if(cmu==\"V\"){y=yi+ts[i++];cmds.push(\"L\");crds.push(x,y);}else if(cmu==\"C\"){var x1=xi+ts[i++],y1=yi+ts[i++],x2=xi+ts[i++],y2=yi+ts[i++],x3=xi+ts[i++],y3=yi+ts[i++];cmds.push(\"C\");crds.push(x1,y1,x2,y2,x3,y3);x=x3;y=y3;}else if(cmu==\"S\"){var co=Math.max(crds.length-4,0);var x1=x+x-crds[co],y1=y+y-crds[co+1];var x2=xi+ts[i++],y2=yi+ts[i++],x3=xi+ts[i++],y3=yi+ts[i++];cmds.push(\"C\");crds.push(x1,y1,x2,y2,x3,y3);x=x3;y=y3;}else { console.log(\"Unknown SVG command \"+cmd); }}}}};Typr.SVG._reps=function(ts,off,ps){var i=off;while(i<ts.length){if(typeof ts[i]==\"string\"){ break; }i+=ps;}return (i-off)/ps};if(Typr==null){ Typr={}; }if(Typr.U==null){ Typr.U={}; }Typr.U.codeToGlyph=function(font,code){var cmap=font.cmap;var tind=-1;if(cmap.p0e4!=null){ tind=cmap.p0e4; }else if(cmap.p3e1!=null){ tind=cmap.p3e1; }else if(cmap.p1e0!=null){ tind=cmap.p1e0; }if(tind==-1){ throw \"no familiar platform and encoding!\"; }var tab=cmap.tables[tind];if(tab.format==0){if(code>=tab.map.length){ return 0; }return tab.map[code]}else if(tab.format==4){var sind=-1;for(var i=0;i<tab.endCount.length;i++){ if(code<=tab.endCount[i]){sind=i;break} }if(sind==-1){ return 0; }if(tab.startCount[sind]>code){ return 0; }var gli=0;if(tab.idRangeOffset[sind]!=0){ gli=tab.glyphIdArray[code-tab.startCount[sind]+(tab.idRangeOffset[sind]>>1)-(tab.idRangeOffset.length-sind)]; }else { gli=code+tab.idDelta[sind]; }return gli&65535}else if(tab.format==12){if(code>tab.groups[tab.groups.length-1][1]){ return 0; }for(var i=0;i<tab.groups.length;i++){var grp=tab.groups[i];if(grp[0]<=code&&code<=grp[1]){ return grp[2]+(code-grp[0]) }}return 0}else { throw \"unknown cmap table format \"+tab.format }};Typr.U.glyphToPath=function(font,gid){var path={cmds:[],crds:[]};if(font.SVG&&font.SVG.entries[gid]){var p=font.SVG.entries[gid];if(p==null){ return path; }if(typeof p==\"string\"){p=Typr.SVG.toPath(p);font.SVG.entries[gid]=p;}return p}else if(font.CFF){var state={x:0,y:0,stack:[],nStems:0,haveWidth:false,width:font.CFF.Private?font.CFF.Private.defaultWidthX:0,open:false};Typr.U._drawCFF(font.CFF.CharStrings[gid],state,font.CFF,path);}else if(font.glyf){Typr.U._drawGlyf(gid,font,path);}return path};Typr.U._drawGlyf=function(gid,font,path){var gl=font.glyf[gid];if(gl==null){ gl=font.glyf[gid]=Typr.glyf._parseGlyf(font,gid); }if(gl!=null){if(gl.noc>-1){ Typr.U._simpleGlyph(gl,path); }else { Typr.U._compoGlyph(gl,font,path); }}};Typr.U._simpleGlyph=function(gl,p){for(var c=0;c<gl.noc;c++){var i0=c==0?0:gl.endPts[c-1]+1;var il=gl.endPts[c];for(var i=i0;i<=il;i++){var pr=i==i0?il:i-1;var nx=i==il?i0:i+1;var onCurve=gl.flags[i]&1;var prOnCurve=gl.flags[pr]&1;var nxOnCurve=gl.flags[nx]&1;var x=gl.xs[i],y=gl.ys[i];if(i==i0){if(onCurve){if(prOnCurve){ Typr.U.P.moveTo(p,gl.xs[pr],gl.ys[pr]); }else {Typr.U.P.moveTo(p,x,y);continue}}else {if(prOnCurve){ Typr.U.P.moveTo(p,gl.xs[pr],gl.ys[pr]); }else { Typr.U.P.moveTo(p,(gl.xs[pr]+x)/2,(gl.ys[pr]+y)/2); }}}if(onCurve){if(prOnCurve){ Typr.U.P.lineTo(p,x,y); }}else {if(nxOnCurve){ Typr.U.P.qcurveTo(p,x,y,gl.xs[nx],gl.ys[nx]); }else { Typr.U.P.qcurveTo(p,x,y,(x+gl.xs[nx])/2,(y+gl.ys[nx])/2); }}}Typr.U.P.closePath(p);}};Typr.U._compoGlyph=function(gl,font,p){for(var j=0;j<gl.parts.length;j++){var path={cmds:[],crds:[]};var prt=gl.parts[j];Typr.U._drawGlyf(prt.glyphIndex,font,path);var m=prt.m;for(var i=0;i<path.crds.length;i+=2){var x=path.crds[i],y=path.crds[i+1];p.crds.push(x*m.a+y*m.b+m.tx);p.crds.push(x*m.c+y*m.d+m.ty);}for(var i=0;i<path.cmds.length;i++){ p.cmds.push(path.cmds[i]); }}};Typr.U._getGlyphClass=function(g,cd){var intr=Typr._lctf.getInterval(cd,g);return intr==-1?0:cd[intr+2]};Typr.U.getPairAdjustment=function(font,g1,g2){if(font.GPOS){var ltab=null;for(var i=0;i<font.GPOS.featureList.length;i++){var fl=font.GPOS.featureList[i];if(fl.tag==\"kern\"){ for(var j=0;j<fl.tab.length;j++){ if(font.GPOS.lookupList[fl.tab[j]].ltype==2){ ltab=font.GPOS.lookupList[fl.tab[j]]; } } }}if(ltab){for(var i=0;i<ltab.tabs.length;i++){var tab=ltab.tabs[i];var ind=Typr._lctf.coverageIndex(tab.coverage,g1);if(ind==-1){ continue; }var adj;if(tab.format==1){var right=tab.pairsets[ind];for(var j=0;j<right.length;j++){ if(right[j].gid2==g2){ adj=right[j]; } }if(adj==null){ continue }}else if(tab.format==2){var c1=Typr.U._getGlyphClass(g1,tab.classDef1);var c2=Typr.U._getGlyphClass(g2,tab.classDef2);var adj=tab.matrix[c1][c2];}return adj.val1[2]}}}if(font.kern){var ind1=font.kern.glyph1.indexOf(g1);if(ind1!=-1){var ind2=font.kern.rval[ind1].glyph2.indexOf(g2);if(ind2!=-1){ return font.kern.rval[ind1].vals[ind2] }}}return 0};Typr.U.stringToGlyphs=function(font,str){var gls=[];for(var i=0;i<str.length;i++){var cc=str.codePointAt(i);if(cc>65535){ i++; }gls.push(Typr.U.codeToGlyph(font,cc));}var gsub=font[\"GSUB\"];if(gsub==null){ return gls; }var llist=gsub.lookupList,flist=gsub.featureList;var wsep='\\n\\t\" ,.:;!?()  ،';var R=\"آأؤإاةدذرزوٱٲٳٵٶٷڈډڊڋڌڍڎڏڐڑڒړڔڕږڗژڙۀۃۄۅۆۇۈۉۊۋۍۏےۓەۮۯܐܕܖܗܘܙܞܨܪܬܯݍݙݚݛݫݬݱݳݴݸݹࡀࡆࡇࡉࡔࡧࡩࡪࢪࢫࢬࢮࢱࢲࢹૅેૉ૊૎૏ૐ૑૒૝ૡ૤૯஁ஃ஄அஉ஌எஏ஑னப஫஬\";var L=\"ꡲ્૗\";for(var ci=0;ci<gls.length;ci++){var gl=gls[ci];var slft=ci==0||wsep.indexOf(str[ci-1])!=-1;var srgt=ci==gls.length-1||wsep.indexOf(str[ci+1])!=-1;if(!slft&&R.indexOf(str[ci-1])!=-1){ slft=true; }if(!srgt&&R.indexOf(str[ci])!=-1){ srgt=true; }if(!srgt&&L.indexOf(str[ci+1])!=-1){ srgt=true; }if(!slft&&L.indexOf(str[ci])!=-1){ slft=true; }var feat=null;if(slft){ feat=srgt?\"isol\":\"init\"; }else { feat=srgt?\"fina\":\"medi\"; }for(var fi=0;fi<flist.length;fi++){if(flist[fi].tag!=feat){ continue; }for(var ti=0;ti<flist[fi].tab.length;ti++){var tab=llist[flist[fi].tab[ti]];if(tab.ltype!=1){ continue; }Typr.U._applyType1(gls,ci,tab);}}}var cligs=[\"rlig\",\"liga\",\"mset\"];for(var ci=0;ci<gls.length;ci++){var gl=gls[ci];var rlim=Math.min(3,gls.length-ci-1);for(var fi=0;fi<flist.length;fi++){var fl=flist[fi];if(cligs.indexOf(fl.tag)==-1){ continue; }for(var ti=0;ti<fl.tab.length;ti++){var tab=llist[fl.tab[ti]];for(var j=0;j<tab.tabs.length;j++){if(tab.tabs[j]==null){ continue; }var ind=Typr._lctf.coverageIndex(tab.tabs[j].coverage,gl);if(ind==-1){ continue; }if(tab.ltype==4){var vals=tab.tabs[j].vals[ind];for(var k=0;k<vals.length;k++){var lig=vals[k],rl=lig.chain.length;if(rl>rlim){ continue; }var good=true;for(var l=0;l<rl;l++){ if(lig.chain[l]!=gls[ci+(1+l)]){ good=false; } }if(!good){ continue; }gls[ci]=lig.nglyph;for(var l=0;l<rl;l++){ gls[ci+l+1]=-1; }}}else if(tab.ltype==5){var ltab=tab.tabs[j];if(ltab.fmt!=2){ continue; }var cind=Typr._lctf.getInterval(ltab.cDef,gl);var cls=ltab.cDef[cind+2],scs=ltab.scset[cls];for(var i=0;i<scs.length;i++){var sc=scs[i],inp=sc.input;if(inp.length>rlim){ continue; }var good=true;for(var l=0;l<inp.length;l++){var cind2=Typr._lctf.getInterval(ltab.cDef,gls[ci+1+l]);if(cind==-1&&ltab.cDef[cind2+2]!=inp[l]){good=false;break}}if(!good){ continue; }var lrs=sc.substLookupRecords;for(var k=0;k<lrs.length;k+=2){var gi=lrs[k],tabi=lrs[k+1];}}}}}}}return gls};Typr.U._applyType1=function(gls,ci,tab){var gl=gls[ci];for(var j=0;j<tab.tabs.length;j++){var ttab=tab.tabs[j];var ind=Typr._lctf.coverageIndex(ttab.coverage,gl);if(ind==-1){ continue; }if(ttab.fmt==1){ gls[ci]=gls[ci]+ttab.delta; }else { gls[ci]=ttab.newg[ind]; }}};Typr.U.glyphsToPath=function(font,gls,clr){var tpath={cmds:[],crds:[]};var x=0;for(var i=0;i<gls.length;i++){var gid=gls[i];if(gid==-1){ continue; }var gid2=i<gls.length-1&&gls[i+1]!=-1?gls[i+1]:0;var path=Typr.U.glyphToPath(font,gid);for(var j=0;j<path.crds.length;j+=2){tpath.crds.push(path.crds[j]+x);tpath.crds.push(path.crds[j+1]);}if(clr){ tpath.cmds.push(clr); }for(var j=0;j<path.cmds.length;j++){ tpath.cmds.push(path.cmds[j]); }if(clr){ tpath.cmds.push(\"X\"); }x+=font.hmtx.aWidth[gid];if(i<gls.length-1){ x+=Typr.U.getPairAdjustment(font,gid,gid2); }}return tpath};Typr.U.pathToSVG=function(path,prec){if(prec==null){ prec=5; }var out=[],co=0,lmap={M:2,L:2,Q:4,C:6};for(var i=0;i<path.cmds.length;i++){var cmd=path.cmds[i],cn=co+(lmap[cmd]?lmap[cmd]:0);out.push(cmd);while(co<cn){var c=path.crds[co++];out.push(parseFloat(c.toFixed(prec))+(co==cn?\"\":\" \"));}}return out.join(\"\")};Typr.U.pathToContext=function(path,ctx){var c=0,crds=path.crds;for(var j=0;j<path.cmds.length;j++){var cmd=path.cmds[j];if(cmd==\"M\"){ctx.moveTo(crds[c],crds[c+1]);c+=2;}else if(cmd==\"L\"){ctx.lineTo(crds[c],crds[c+1]);c+=2;}else if(cmd==\"C\"){ctx.bezierCurveTo(crds[c],crds[c+1],crds[c+2],crds[c+3],crds[c+4],crds[c+5]);c+=6;}else if(cmd==\"Q\"){ctx.quadraticCurveTo(crds[c],crds[c+1],crds[c+2],crds[c+3]);c+=4;}else if(cmd.charAt(0)==\"#\"){ctx.beginPath();ctx.fillStyle=cmd;}else if(cmd==\"Z\"){ctx.closePath();}else if(cmd==\"X\"){ctx.fill();}}};Typr.U.P={};Typr.U.P.moveTo=function(p,x,y){p.cmds.push(\"M\");p.crds.push(x,y);};Typr.U.P.lineTo=function(p,x,y){p.cmds.push(\"L\");p.crds.push(x,y);};Typr.U.P.curveTo=function(p,a,b,c,d,e,f){p.cmds.push(\"C\");p.crds.push(a,b,c,d,e,f);};Typr.U.P.qcurveTo=function(p,a,b,c,d){p.cmds.push(\"Q\");p.crds.push(a,b,c,d);};Typr.U.P.closePath=function(p){p.cmds.push(\"Z\");};Typr.U._drawCFF=function(cmds,state,font,p){var stack=state.stack;var nStems=state.nStems,haveWidth=state.haveWidth,width=state.width,open=state.open;var i=0;var x=state.x,y=state.y,c1x=0,c1y=0,c2x=0,c2y=0,c3x=0,c3y=0,c4x=0,c4y=0,jpx=0,jpy=0;var o={val:0,size:0};while(i<cmds.length){Typr.CFF.getCharString(cmds,i,o);var v=o.val;i+=o.size;if(v==\"o1\"||v==\"o18\"){var hasWidthArg;hasWidthArg=stack.length%2!==0;if(hasWidthArg&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;}nStems+=stack.length>>1;stack.length=0;haveWidth=true;}else if(v==\"o3\"||v==\"o23\"){var hasWidthArg;hasWidthArg=stack.length%2!==0;if(hasWidthArg&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;}nStems+=stack.length>>1;stack.length=0;haveWidth=true;}else if(v==\"o4\"){if(stack.length>1&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;haveWidth=true;}if(open){ Typr.U.P.closePath(p); }y+=stack.pop();Typr.U.P.moveTo(p,x,y);open=true;}else if(v==\"o5\"){while(stack.length>0){x+=stack.shift();y+=stack.shift();Typr.U.P.lineTo(p,x,y);}}else if(v==\"o6\"||v==\"o7\"){var count=stack.length;var isX=v==\"o6\";for(var j=0;j<count;j++){var sval=stack.shift();if(isX){ x+=sval; }else { y+=sval; }isX=!isX;Typr.U.P.lineTo(p,x,y);}}else if(v==\"o8\"||v==\"o24\"){var count=stack.length;var index=0;while(index+6<=count){c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y+stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,x,y);index+=6;}if(v==\"o24\"){x+=stack.shift();y+=stack.shift();Typr.U.P.lineTo(p,x,y);}}else if(v==\"o11\"){ break; }else if(v==\"o1234\"||v==\"o1235\"||v==\"o1236\"||v==\"o1237\"){if(v==\"o1234\"){c1x=x+stack.shift();c1y=y;c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y;c3x=jpx+stack.shift();c3y=c2y;c4x=c3x+stack.shift();c4y=y;x=c4x+stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,jpx,jpy);Typr.U.P.curveTo(p,c3x,c3y,c4x,c4y,x,y);}if(v==\"o1235\"){c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y+stack.shift();c3x=jpx+stack.shift();c3y=jpy+stack.shift();c4x=c3x+stack.shift();c4y=c3y+stack.shift();x=c4x+stack.shift();y=c4y+stack.shift();stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,jpx,jpy);Typr.U.P.curveTo(p,c3x,c3y,c4x,c4y,x,y);}if(v==\"o1236\"){c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y;c3x=jpx+stack.shift();c3y=c2y;c4x=c3x+stack.shift();c4y=c3y+stack.shift();x=c4x+stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,jpx,jpy);Typr.U.P.curveTo(p,c3x,c3y,c4x,c4y,x,y);}if(v==\"o1237\"){c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();jpx=c2x+stack.shift();jpy=c2y+stack.shift();c3x=jpx+stack.shift();c3y=jpy+stack.shift();c4x=c3x+stack.shift();c4y=c3y+stack.shift();if(Math.abs(c4x-x)>Math.abs(c4y-y)){x=c4x+stack.shift();}else {y=c4y+stack.shift();}Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,jpx,jpy);Typr.U.P.curveTo(p,c3x,c3y,c4x,c4y,x,y);}}else if(v==\"o14\"){if(stack.length>0&&!haveWidth){width=stack.shift()+font.nominalWidthX;haveWidth=true;}if(stack.length==4){var adx=stack.shift();var ady=stack.shift();var bchar=stack.shift();var achar=stack.shift();var bind=Typr.CFF.glyphBySE(font,bchar);var aind=Typr.CFF.glyphBySE(font,achar);Typr.U._drawCFF(font.CharStrings[bind],state,font,p);state.x=adx;state.y=ady;Typr.U._drawCFF(font.CharStrings[aind],state,font,p);}if(open){Typr.U.P.closePath(p);open=false;}}else if(v==\"o19\"||v==\"o20\"){var hasWidthArg;hasWidthArg=stack.length%2!==0;if(hasWidthArg&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;}nStems+=stack.length>>1;stack.length=0;haveWidth=true;i+=nStems+7>>3;}else if(v==\"o21\"){if(stack.length>2&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;haveWidth=true;}y+=stack.pop();x+=stack.pop();if(open){ Typr.U.P.closePath(p); }Typr.U.P.moveTo(p,x,y);open=true;}else if(v==\"o22\"){if(stack.length>1&&!haveWidth){width=stack.shift()+font.Private.nominalWidthX;haveWidth=true;}x+=stack.pop();if(open){ Typr.U.P.closePath(p); }Typr.U.P.moveTo(p,x,y);open=true;}else if(v==\"o25\"){while(stack.length>6){x+=stack.shift();y+=stack.shift();Typr.U.P.lineTo(p,x,y);}c1x=x+stack.shift();c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y+stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,x,y);}else if(v==\"o26\"){if(stack.length%2){x+=stack.shift();}while(stack.length>0){c1x=x;c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x;y=c2y+stack.shift();Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,x,y);}}else if(v==\"o27\"){if(stack.length%2){y+=stack.shift();}while(stack.length>0){c1x=x+stack.shift();c1y=y;c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();y=c2y;Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,x,y);}}else if(v==\"o10\"||v==\"o29\"){var obj=v==\"o10\"?font.Private:font;if(stack.length==0){console.log(\"error: empty stack\");}else {var ind=stack.pop();var subr=obj.Subrs[ind+obj.Bias];state.x=x;state.y=y;state.nStems=nStems;state.haveWidth=haveWidth;state.width=width;state.open=open;Typr.U._drawCFF(subr,state,font,p);x=state.x;y=state.y;nStems=state.nStems;haveWidth=state.haveWidth;width=state.width;open=state.open;}}else if(v==\"o30\"||v==\"o31\"){var count,count1=stack.length;var index=0;var alternate=v==\"o31\";count=count1&~2;index+=count1-count;while(index<count){if(alternate){c1x=x+stack.shift();c1y=y;c2x=c1x+stack.shift();c2y=c1y+stack.shift();y=c2y+stack.shift();if(count-index==5){x=c2x+stack.shift();index++;}else { x=c2x; }alternate=false;}else {c1x=x;c1y=y+stack.shift();c2x=c1x+stack.shift();c2y=c1y+stack.shift();x=c2x+stack.shift();if(count-index==5){y=c2y+stack.shift();index++;}else { y=c2y; }alternate=true;}Typr.U.P.curveTo(p,c1x,c1y,c2x,c2y,x,y);index+=4;}}else if((v+\"\").charAt(0)==\"o\"){console.log(\"Unknown operation: \"+v,cmds);throw v}else { stack.push(v); }}state.x=x;state.y=y;state.nStems=nStems;state.haveWidth=haveWidth;state.width=width;state.open=open;};var typr_js=Typr;\n\n  var TEXT_NEWLINE_REGEXP = /\\r?\\n/;\n\n  function registerFontClass(Zdog) {\n    // Zdog.Font class\n    var ZdogFont = function ZdogFont(props) {\n      var this$1 = this;\n\n      // Set missing props to default values\n      props = Zdog.extend({\n        src: '',\n      }, props);\n      this.src = props.src;\n      this.font = null;\n      this._hasLoaded = false;\n      this._loadCallbacks = [];\n      // Add this font instance to the internal font list\n      Zdog.FontList.push(this);\n      // Begin loading font file\n      this._fetchFontResource(this.src)\n        .then(function (buffer) {\n          var font = typr_js.parse(buffer);\n          // check font fields to see if the font was parsed correctly\n          if ((!font.head) || (!font.hmtx) || (!font.hhea) || (!font.glyf)) {\n            // get a list of missing font fields (only checks for ones that zfont uses)\n            var missingFields = ['head', 'hmtx', 'hhea', 'glyf'].filter(function (field) { return !font[field]; });\n            throw new Error((\"Typr.js could not parse this font (unable to find \" + (missingFields.join(', ')) + \")\"));\n          }\n          return font;\n        })\n        .then(function (font) {\n          this$1.font = font;\n          this$1._hasLoaded = true;\n          this$1._loadCallbacks.forEach(function (callback) { return callback(); });\n        })\n        .catch(function (err) {\n          throw new Error((\"Unable to load font from \" + (this$1.src) + \":\\n\" + err));\n        });\n    };\n\n    ZdogFont.prototype.waitForLoad = function waitForLoad () {\n        var this$1 = this;\n\n      return new Promise(function (resolve, reject) {\n        // If the font is loaded, we can resolve right away\n        if (this$1._hasLoaded && this$1._hasLoaded) {\n          resolve();\n        }\n        // Otherwise, wait for it to load\n        else {\n          this$1._loadCallbacks.push(resolve);\n        }\n      });\n    };\n\n    ZdogFont.prototype.getFontScale = function getFontScale (fontSize) {\n      if (!this._hasLoaded) {\n        return null;\n      } else {\n        return 1 / this.font.head.unitsPerEm * fontSize;\n      }\n    };\n\n    ZdogFont.prototype.measureText = function measureText (text, fontSize) {\n        var this$1 = this;\n        if ( fontSize === void 0 ) fontSize=64;\n\n      if (!this._hasLoaded) {\n        return null;\n      }\n      var lines = Array.isArray(text) ? text : text.split(TEXT_NEWLINE_REGEXP);\n      var font = this.font;\n      var advanceWidthTable = font.hmtx.aWidth;\n      var fontScale = this.getFontScale(fontSize);\n      var descender = font.hhea.descender;\n      var ascender = font.hhea.ascender;\n      var lineGap = font.hhea.lineGap;\n      var lineWidths = lines.map(function (line) {\n        var glyphs = typr_js.U.stringToGlyphs(this$1.font, line);\n        return glyphs.reduce(function (advanceWidth, glyphId) {\n          // stringToGlyphs returns an array on glyph IDs that is the same length as the text string\n          // an ID can sometimes be -1 in cases where multiple characters are merged into a single ligature\n          if (glyphId > -1 && glyphId < advanceWidthTable.length) {\n            advanceWidth += advanceWidthTable[glyphId];\n          }\n          return advanceWidth;\n        }, 0);\n      });\n      var width = Math.max.apply(Math, lineWidths);\n      var lineHeight = (0 - descender) + ascender;\n      var height = lineHeight * lines.length;\n        \n      // Multiply by fontScale to convert from font units to pixels\n      return {\n        width: width * fontScale,\n        height: height * fontScale,\n        lineHeight: lineHeight * fontScale,\n        lineWidths: lineWidths.map(function (width) { return width * fontScale; }),\n        descender: descender * fontScale,\n        ascender: ascender * fontScale,\n      };\n    };\n\n    ZdogFont.prototype.getTextPath = function getTextPath (text, fontSize, x, y, z, alignX, alignY) {\n        var this$1 = this;\n        if ( fontSize === void 0 ) fontSize=64;\n        if ( x === void 0 ) x=0;\n        if ( y === void 0 ) y=0;\n        if ( z === void 0 ) z=0;\n        if ( alignX === void 0 ) alignX='left';\n        if ( alignY === void 0 ) alignY='bottom';\n\n      if (!this._hasLoaded) {\n        return [];\n      }\n      var lines = Array.isArray(text) ? text : text.split(TEXT_NEWLINE_REGEXP);\n      var measurements = this.measureText(text, fontSize);\n      var lineWidths = measurements.lineWidths;\n      var lineHeight = measurements.lineHeight;\n      return lines.map(function (line, lineIndex) {\n        var ref = this$1.getTextOrigin(Object.assign({}, measurements,\n          {width: lineWidths[lineIndex]}), x, y, z, alignX, alignY);\n          var _x = ref[0];\n          var _y = ref[1];\n          var _z = ref[2];\n        y += lineHeight;\n        var glyphs = typr_js.U.stringToGlyphs(this$1.font, line);\n        var path = typr_js.U.glyphsToPath(this$1.font, glyphs);\n        return this$1._convertPathCommands(path, fontSize, _x, _y, z);\n      }).flat();\n    };\n\n    ZdogFont.prototype.getTextGlyphs = function getTextGlyphs (text, fontSize, x, y, z, alignX, alignY) {\n        var this$1 = this;\n        if ( fontSize === void 0 ) fontSize=64;\n        if ( x === void 0 ) x=0;\n        if ( y === void 0 ) y=0;\n        if ( z === void 0 ) z=0;\n        if ( alignX === void 0 ) alignX='left';\n        if ( alignY === void 0 ) alignY='bottom';\n\n      if (!this._hasLoaded) {\n        return [];\n      }\n      var measurements = this.measureText(text, fontSize);\n      var advanceWidthTable = this.font.hmtx.aWidth;\n      var fontScale = this.getFontScale(fontSize);\n      var lineWidths = measurements.lineWidths;\n      var lineHeight = measurements.lineHeight;\n      var lines = Array.isArray(text) ? text : text.split(TEXT_NEWLINE_REGEXP);\n      return lines.map(function (line, lineIndex) {\n        var glyphs = typr_js.U.stringToGlyphs(this$1.font, line);\n        var ref = this$1.getTextOrigin(Object.assign({}, measurements,\n          {width: lineWidths[lineIndex]}), x, y, z, alignX, alignY);\n          var _x = ref[0];\n          var _y = ref[1];\n          var _z = ref[2];\n        y += lineHeight;\n        return glyphs.filter(function (glyph) { return glyph !== -1; }).map(function (glyphId) {\n          var path = typr_js.U.glyphToPath(this$1.font, glyphId);\n          var shape = {\n            translate: {x:_x, y: _y, z:_z},\n            path: this$1._convertPathCommands(path, fontSize, 0, 0, 0)\n          };\n          _x += advanceWidthTable[glyphId] * fontScale;\n          return shape;\n        });\n      }).flat(); \n    };\n\n    ZdogFont.prototype.getTextOrigin = function getTextOrigin (measuement, x, y, z, alignX, alignY) {\n        if ( x === void 0 ) x=0;\n        if ( y === void 0 ) y=0;\n        if ( z === void 0 ) z=0;\n        if ( alignX === void 0 ) alignX='left';\n        if ( alignY === void 0 ) alignY='bottom';\n\n      var width = measuement.width;\n        var height = measuement.height;\n        var lineHeight = measuement.lineHeight;\n      switch (alignX) {\n        case 'right':\n          x -= width;\n          break;\n        case 'center':\n          x -= width / 2;\n          break;\n      }\n      switch (alignY) {\n        case 'middle':\n          y -= (height / 2)- lineHeight;\n          break;\n        case 'bottom':\n        default:\n          y -= height - lineHeight;\n          break;\n      }\n      return [x, y, z];\n    };\n\n    // Convert Typr.js path commands to Zdog commands\n    // Also apply font size scaling and coordinate adjustment\n    // https://github.com/photopea/Typr.js\n    // https://zzz.dog/shapes#shape-path-commands\n    ZdogFont.prototype._convertPathCommands = function _convertPathCommands (path, fontSize, x, y, z) {\n        if ( x === void 0 ) x=0;\n        if ( y === void 0 ) y=0;\n        if ( z === void 0 ) z=0;\n\n      var yDir = -1;\n      var xDir = 1;\n      var fontScale = this.getFontScale(fontSize);\n      var commands = path.cmds;\n      // Apply font scale to all coords\n      var coords = path.crds.map(function (coord) { return coord * fontScale; });\n      // Convert coords to Zdog commands\n      var startCoord = null;\n      var coordOffset = 0;\n      return commands.map(function (cmd) {\n        var result = null;\n        if (!startCoord) {\n          startCoord = {x: x + coords[coordOffset] * xDir, y: y + coords[coordOffset + 1] * yDir, z: z};\n        }\n        switch (cmd) {\n          case 'M': // moveTo command\n            result = {\n              move: {x: x + coords[coordOffset] * xDir, y: y + coords[coordOffset + 1] * yDir, z: z}\n            };\n            coordOffset += 2;\n            return result;\n          case 'L': // lineTo command\n            result = {\n              line: {x: x + coords[coordOffset] * xDir, y: y + coords[coordOffset + 1] * yDir, z: z}\n            };\n            coordOffset += 2;\n            return result;\n          case 'C': // curveTo command\n            result = {\n              bezier: [\n                {x: x + coords[coordOffset]   * xDir, y: y + coords[coordOffset + 1] * yDir, z: z},\n                {x: x + coords[coordOffset + 2] * xDir, y: y + coords[coordOffset + 3] * yDir, z: z},\n                {x: x + coords[coordOffset + 4] * xDir, y: y + coords[coordOffset + 5] * yDir, z: z} ]\n            };\n            coordOffset += 6;\n            return result;\n          case 'Q': // arcTo command\n            result = {\n              arc: [\n                {x: x + coords[coordOffset]   * xDir, y: y + coords[coordOffset + 1] * yDir, z: z},\n                {x: x + coords[coordOffset + 2] * xDir, y: y + coords[coordOffset + 3] * yDir, z: z} ]\n            };\n            coordOffset += 4;\n            return result;\n          case 'Z': // close path\n            if (startCoord) {\n              result = {\n                line: startCoord\n              };\n              startCoord = null;\n            }\n            return result;\n          // unhandled type\n          // currently, #rrggbb and X types (used in multicolor fonts) aren't supported\n          default:\n            return result;\n        }\n      }).filter(function (cmd) { return cmd !== null; }); // filter out null commands\n    };\n\n    ZdogFont.prototype._fetchFontResource = function _fetchFontResource (source) {\n      return new Promise(function (resolve, reject) {\n        var request = new XMLHttpRequest();\n        // Fetch as an arrayBuffer for Typr.parse\n        request.responseType = 'arraybuffer'; \n        request.open('GET', source, true);\n        request.onreadystatechange = function (e) {\n          if (request.readyState === 4) {\n            if (request.status >= 200 && request.status < 300) {\n              resolve(request.response);\n            } else {\n              reject((\"HTTP error \" + (request.status) + \": \" + (request.statusText)));\n            }\n          }\n        };\n        request.send(null);\n      });\n    };\n\n    Zdog.Font = ZdogFont;\n    return Zdog;\n  }\n\n  function objectWithoutProperties (obj, exclude) { var target = {}; for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k) && exclude.indexOf(k) === -1) target[k] = obj[k]; return target; }\n  function registerTextClass(Zdog) {\n\n    // Zdog.Text class\n    var ZdogText = /*@__PURE__*/(function (superclass) {\n      function ZdogText(props) {\n        // Set missing props to default values\n        props = Zdog.extend({\n          font: null,\n          value: '',\n          fontSize: 64,\n          textAlign: 'left',\n          textBaseline: 'bottom',\n        }, props);\n        // Split props\n        var font = props.font;\n        var value = props.value;\n        var fontSize = props.fontSize;\n        var textAlign = props.textAlign;\n        var textBaseline = props.textBaseline;\n        var rest = objectWithoutProperties( props, [\"font\", \"value\", \"fontSize\", \"textAlign\", \"textBaseline\"] );\n        var shapeProps = rest;\n        // Create shape object\n        superclass.call(this, Object.assign({}, shapeProps,\n          {closed: true,\n          visible: false, // hide until font is loaded\n          path: [{}]}));\n        this._font = null;\n        this._value = value;\n        this._fontSize = fontSize;\n        this._textAlign = textAlign;\n        this._textBaseline = textBaseline;\n        this.font = font;\n      }\n\n      if ( superclass ) ZdogText.__proto__ = superclass;\n      ZdogText.prototype = Object.create( superclass && superclass.prototype );\n      ZdogText.prototype.constructor = ZdogText;\n\n      var prototypeAccessors = { font: { configurable: true },value: { configurable: true },fontSize: { configurable: true },textAlign: { configurable: true },textBaseline: { configurable: true } };\n\n      ZdogText.prototype.updateText = function updateText () {\n        var path = this.font.getTextPath(this.value, this.fontSize, 0, 0, 0, this.textAlign, this.textBaseline);\n        if (path.length == 0) { // zdog doesn't know what to do with empty path arrays\n          this.path = [{}];\n          this.visible = false;\n        } else {\n          this.path = path;\n          this.visible = true;\n        }\n        this.updatePath();\n      };\n\n      prototypeAccessors.font.set = function (newFont) {\n        var this$1 = this;\n\n        this._font = newFont;\n        this.font.waitForLoad().then(function () {\n          this$1.updateText();\n          this$1.visible = true;\n          // Find root Zdog.Illustration instance\n          var root = this$1.addTo;\n          while (root.addTo !== undefined) {\n            root = root.addTo;\n          }\n          // Update render graph\n          if (root && typeof root.updateRenderGraph === 'function') {\n            root.updateRenderGraph();\n          }\n        });\n      };\n\n      prototypeAccessors.font.get = function () {\n        return this._font;\n      };\n\n      prototypeAccessors.value.set = function (newValue) {\n        this._value = newValue;\n        this.updateText();\n      };\n      \n      prototypeAccessors.value.get = function () {\n        return this._value;\n      };\n\n      prototypeAccessors.fontSize.set = function (newSize) {\n        this._fontSize = newSize;\n        this.updateText();\n      };\n\n      prototypeAccessors.fontSize.get = function () {\n        return this._fontSize;\n      };\n\n      prototypeAccessors.textAlign.set = function (newValue) {\n        this._textAlign = newValue;\n        this.updateText();\n      };\n\n      prototypeAccessors.textAlign.get = function () {\n        return this._textAlign;\n      };\n\n      prototypeAccessors.textBaseline.set = function (newValue) {\n        this._textBaseline = newValue;\n        this.updateText();\n      };\n\n      prototypeAccessors.textBaseline.get = function () {\n        return this._textBaseline;\n      };\n\n      Object.defineProperties( ZdogText.prototype, prototypeAccessors );\n\n      return ZdogText;\n    }(Zdog.Shape));\n\n    ZdogText.optionKeys = ZdogText.optionKeys.concat(['font', 'fontSize', 'value', 'textAlign', 'textBaseline']);\n    Zdog.Text = ZdogText;\n    return Zdog;\n  }\n\n  function objectWithoutProperties$1 (obj, exclude) { var target = {}; for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k) && exclude.indexOf(k) === -1) target[k] = obj[k]; return target; }\n  function registerTextGroupClass(Zdog) {\n\n    // Zdog.TextGroup class\n    var ZdogTextGroup = /*@__PURE__*/(function (superclass) {\n      function ZdogTextGroup(props) {\n        // Set missing props to default values\n        props = Zdog.extend({\n          font: null,\n          value: '',\n          fontSize: 64,\n          textAlign: 'left',\n          textBaseline: 'bottom',\n          color: '#333',\n          fill: false,\n          stroke: 1,\n        }, props);\n        // Split props\n        var font = props.font;\n        var value = props.value;\n        var fontSize = props.fontSize;\n        var textAlign = props.textAlign;\n        var textBaseline = props.textBaseline;\n        var color = props.color;\n        var fill = props.fill;\n        var stroke = props.stroke;\n        var rest = objectWithoutProperties$1( props, [\"font\", \"value\", \"fontSize\", \"textAlign\", \"textBaseline\", \"color\", \"fill\", \"stroke\"] );\n        var groupProps = rest;\n        // Create group object\n        superclass.call(this, Object.assign({}, groupProps,\n          {visible: false}));\n        this._font = null;\n        this._value = value;\n        this._fontSize = fontSize;\n        this._textAlign = textAlign;\n        this._textBaseline = textBaseline;\n        this._color = color;\n        this._fill = fill;\n        this._stroke = stroke;\n        this.font = font;\n      }\n\n      if ( superclass ) ZdogTextGroup.__proto__ = superclass;\n      ZdogTextGroup.prototype = Object.create( superclass && superclass.prototype );\n      ZdogTextGroup.prototype.constructor = ZdogTextGroup;\n\n      var prototypeAccessors = { font: { configurable: true },value: { configurable: true },fontSize: { configurable: true },textAlign: { configurable: true },textBaseline: { configurable: true },color: { configurable: true },fill: { configurable: true },stroke: { configurable: true } };\n\n      ZdogTextGroup.prototype.updateText = function updateText () {\n        var this$1 = this;\n\n        // Remove old children\n        while (this.children.length > 0) {\n          this.removeChild(this.children[0]);\n        }\n        // Get text paths for each glyph\n        var glyphs = this.font.getTextGlyphs(this.value, this.fontSize, 0, 0, 0, this.textAlign, this.textBaseline);\n        // Convert glyphs to new shapes\n        glyphs.filter(function (shape) { return shape.path.length > 0; }).forEach(function (shape) {\n          this$1.addChild(new Zdog.Shape({\n            translate: shape.translate,\n            path: shape.path,\n            color: this$1.color,\n            fill: this$1.fill,\n            stroke: this$1.stroke,\n            closed: true,\n          }));\n        });\n        this.updateFlatGraph();\n      };\n\n      prototypeAccessors.font.set = function (newFont) {\n        var this$1 = this;\n\n        this._font = newFont;\n        this._font.waitForLoad().then(function () {\n          this$1.updateText();\n          this$1.visible = true;\n          // Find root Zdog.Illustration instance\n          var root = this$1.addTo;\n          while (root.addTo !== undefined) {\n            root = root.addTo;\n          }\n          // Update render graph\n          if (root && typeof root.updateRenderGraph === 'function') {\n            root.updateRenderGraph();\n          }\n        });\n      };\n\n      prototypeAccessors.font.get = function () {\n        return this._font;\n      };\n\n      prototypeAccessors.value.set = function (newValue) {\n        this._value = newValue;\n        this.updateText();\n      };\n      \n      prototypeAccessors.value.get = function () {\n        return this._value;\n      };\n\n      prototypeAccessors.fontSize.set = function (newSize) {\n        this._fontSize = newSize;\n        this.updateText();\n      };\n\n      prototypeAccessors.fontSize.get = function () {\n        return this._fontSize;\n      };\n\n      prototypeAccessors.textAlign.set = function (newValue) {\n        this._textAlign = newValue;\n        this.updateText();\n      };\n\n      prototypeAccessors.textAlign.get = function () {\n        return this._textAlign;\n      };\n\n      prototypeAccessors.textBaseline.set = function (newValue) {\n        this._textBaseline = newValue;\n        this.updateText();\n      };\n\n      prototypeAccessors.textBaseline.get = function () {\n        return this._textBaseline;\n      };\n\n      prototypeAccessors.color.set = function (newColor) {\n        this._color = newColor;\n        this.children.forEach(function (child) { return child.color = newColor; });\n      };\n\n      prototypeAccessors.color.get = function () {\n        return this._color;\n      };\n\n      prototypeAccessors.fill.set = function (newFill) {\n        this._fill = newFill;\n        this.children.forEach(function (child) { return child.fill = newFill; });\n      };\n\n      prototypeAccessors.fill.get = function () {\n        return this._fill;\n      };\n\n      prototypeAccessors.stroke.set = function (newStroke) {\n        this._stroke = newStroke;\n        this.children.forEach(function (child) { return child.stroke = newStroke; });\n      };\n\n      prototypeAccessors.stroke.get = function () {\n        return this._stroke;\n      };\n\n      Object.defineProperties( ZdogTextGroup.prototype, prototypeAccessors );\n\n      return ZdogTextGroup;\n    }(Zdog.Group));\n\n    ZdogTextGroup.optionKeys = ZdogTextGroup.optionKeys.concat(['color', 'fill', 'stroke', 'font', 'fontSize', 'value', 'textAlign', 'textBaseline']);\n    Zdog.TextGroup = ZdogTextGroup;\n    return Zdog;\n  }\n\n  var index = {\n    init: function init(Zdog) {\n      // Global font list to keep track of all fonts\n      Zdog.FontList = [];\n\n      // Helper to wait for all fonts to load\n      Zdog.waitForFonts = function() {\n        return Promise.all(Zdog.FontList.map(function (font) { return font.waitForLoad(); }));\n      };\n      \n      // Register Zfont classes onto the Zdog object\n      registerFontClass(Zdog);\n      registerTextClass(Zdog);\n      registerTextGroupClass(Zdog);\n\n      return Zdog;\n    },\n    version: \"1.2.8\",\n  };\n\n  return index;\n\n})));\n//# sourceMappingURL=zfont.js.map\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"zfont\",\n  \"version\": \"1.2.8\",\n  \"description\": \"Text plugin for Zdog\",\n  \"module\": \"dist/zfont.es.js\",\n  \"main\": \"dist/zfont.js\",\n  \"files\": [\n    \"dist/zfont.min.js\",\n    \"dist/zfont.js\",\n    \"dist/zfont.es.js\"\n  ],\n  \"scripts\": {\n    \"start\": \"rollup -c --watch --environment DEV_SERVER,BUILD:development\",\n    \"dev\": \"rollup -c --environment BUILD:development\",\n    \"build\": \"npm run dev && npm run build:es && npm run build:min\",\n    \"build:min\": \"rollup -c --environment BUILD:production\",\n    \"build:es\": \"rollup -c --environment ES_MODULE,BUILD:production\"\n  },\n  \"dependencies\": {\n    \"typr.js\": \"^1.0.0\"\n  },\n  \"devDependencies\": {\n    \"rollup\": \"^1.13.0\",\n    \"rollup-plugin-alias\": \"^1.5.1\",\n    \"rollup-plugin-buble\": \"^0.19.6\",\n    \"rollup-plugin-commonjs\": \"^10.0.0\",\n    \"rollup-plugin-filesize\": \"^6.1.0\",\n    \"rollup-plugin-livereload\": \"^1.0.4\",\n    \"rollup-plugin-node-resolve\": \"^5.0.1\",\n    \"rollup-plugin-replace\": \"^2.2.0\",\n    \"rollup-plugin-serve\": \"^1.0.1\",\n    \"rollup-plugin-uglify\": \"^6.0.2\"\n  },\n  \"keywords\": [\n    \"zdog\",\n    \"3d\",\n    \"font\",\n    \"text\",\n    \"truetype\",\n    \"ttf\"\n  ],\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/jaames/zfont.git\"\n  },\n  \"author\": \"James Daniel <jamesdaniel.dev>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/jaames/zfont/issues\"\n  },\n  \"homepage\": \"https://github.com/jaames/zfont\"\n}\n"
  },
  {
    "path": "rollup.config.js",
    "content": "import { version, description } from './package.json';\nimport filesize from 'rollup-plugin-filesize';\nimport buble from 'rollup-plugin-buble';\nimport alias from 'rollup-plugin-alias';\nimport commonjs from 'rollup-plugin-commonjs';\nimport nodeResolve from 'rollup-plugin-node-resolve';\nimport replace from 'rollup-plugin-replace';\nimport { uglify } from 'rollup-plugin-uglify';\nimport serve from 'rollup-plugin-serve';\nimport livereload from 'rollup-plugin-livereload';\n\nconst build = process.env.BUILD || \"development\";\nconst devserver = process.env.DEV_SERVER || false;\nconst esmodule = process.env.ES_MODULE || false;\nconst prod = build === \"production\";\n\nconst banner = `/*!\n * Zfont v${version}\n * ${description}\n * 2019 James Daniel\n * MIT Licensed \n * github.com/jaames/zfont\n */\n`\n\nmodule.exports = {\n  input: 'src/index.js',\n  output: [\n    esmodule ? {\n      file: 'dist/zfont.es.js',\n      format: 'es',\n      name: 'Zfont',\n      banner: banner,\n      sourcemap: true,\n      sourcemapFile: 'dist/zfont.es.map'\n    } : {\n      file: prod ? 'dist/zfont.min.js' : 'dist/zfont.js',\n      format: 'umd',\n      name: 'Zfont',\n      banner: banner,\n      sourcemap: true,\n      sourcemapFile: prod ? 'dist/zfont.min.js.map' : 'dist/zfont.js.map'\n    }\n  ].filter(Boolean),\n  plugins: [\n    alias({\n      resolve: ['.jsx', '.js']\n    }),\n    replace({\n      VERSION: JSON.stringify(version),\n      PROD: prod ? 'true' : 'false',\n      DEV_SERVER: devserver ? 'true' : 'false'\n    }),\n    buble({\n      jsx: 'h',\n      objectAssign: 'Object.assign',\n      transforms: {\n      }\n    }),\n    nodeResolve(),\n    commonjs(),\n    !prod && devserver ? serve({\n      contentBase: ['dist', 'demo']\n    }) : false,\n    !prod && devserver ? livereload() : false,\n    // show filesize stats when building dist files\n    !devserver ? filesize() : false,\n    // only minify if we're producing a non-es production build\n    prod && !esmodule ? uglify({\n      output: {\n        comments: function(node, comment) {\n          if (comment.type === 'comment2') {\n            // preserve banner comment\n            return /\\!/i.test(comment.value);\n          }\n          return false;\n        }\n      }\n    }) : false,\n  ].filter(Boolean)\n};"
  },
  {
    "path": "src/ZdogFont.js",
    "content": "import Typr from 'typr.js';\n\nconst TEXT_NEWLINE_REGEXP = /\\r?\\n/;\n\nexport function registerFontClass(Zdog) {\n  // Zdog.Font class\n  class ZdogFont {\n    constructor(props) {\n      // Set missing props to default values\n      props = Zdog.extend({\n        src: '',\n      }, props);\n      this.src = props.src;\n      this.font = null;\n      this._hasLoaded = false;\n      this._loadCallbacks = [];\n      // Add this font instance to the internal font list\n      Zdog.FontList.push(this);\n      // Begin loading font file\n      this._fetchFontResource(this.src)\n        .then(buffer => {\n          const font = Typr.parse(buffer);\n          // check font fields to see if the font was parsed correctly\n          if ((!font.head) || (!font.hmtx) || (!font.hhea) || (!font.glyf)) {\n            // get a list of missing font fields (only checks for ones that zfont uses)\n            const missingFields = ['head', 'hmtx', 'hhea', 'glyf'].filter(field => !font[field]);\n            throw new Error(`Typr.js could not parse this font (unable to find ${ missingFields.join(', ') })`);\n          }\n          return font;\n        })\n        .then(font => {\n          this.font = font;\n          this._hasLoaded = true;\n          this._loadCallbacks.forEach(callback => callback());\n        })\n        .catch(err => {\n          throw new Error(`Unable to load font from ${this.src}:\\n${err}`);\n        })\n    }\n\n    waitForLoad() {\n      return new Promise((resolve, reject) => {\n        // If the font is loaded, we can resolve right away\n        if (this._hasLoaded && this._hasLoaded) {\n          resolve();\n        }\n        // Otherwise, wait for it to load\n        else {\n          this._loadCallbacks.push(resolve);\n        }\n      });\n    }\n\n    getFontScale(fontSize) {\n      if (!this._hasLoaded) {\n        return null;\n      } else {\n        return 1 / this.font.head.unitsPerEm * fontSize;\n      }\n    }\n\n    measureText(text, fontSize=64) {\n      if (!this._hasLoaded) {\n        return null;\n      }\n      const lines = Array.isArray(text) ? text : text.split(TEXT_NEWLINE_REGEXP);\n      const font = this.font;\n      const advanceWidthTable = font.hmtx.aWidth;\n      const fontScale = this.getFontScale(fontSize);\n      const descender = font.hhea.descender;\n      const ascender = font.hhea.ascender;\n      const lineGap = font.hhea.lineGap;\n      const lineWidths = lines.map(line => {\n        const glyphs = Typr.U.stringToGlyphs(this.font, line);\n        return glyphs.reduce((advanceWidth, glyphId) => {\n          // stringToGlyphs returns an array on glyph IDs that is the same length as the text string\n          // an ID can sometimes be -1 in cases where multiple characters are merged into a single ligature\n          if (glyphId > -1 && glyphId < advanceWidthTable.length) {\n            advanceWidth += advanceWidthTable[glyphId];\n          }\n          return advanceWidth;\n        }, 0);\n      });\n      const width = Math.max(...lineWidths);\n      const lineHeight = (0 - descender) + ascender;\n      const height = lineHeight * lines.length;\n      \n      // Multiply by fontScale to convert from font units to pixels\n      return {\n        width: width * fontScale,\n        height: height * fontScale,\n        lineHeight: lineHeight * fontScale,\n        lineWidths: lineWidths.map(width => width * fontScale),\n        descender: descender * fontScale,\n        ascender: ascender * fontScale,\n      };\n    }\n\n    getTextPath(text, fontSize=64, x=0, y=0, z=0, alignX='left', alignY='bottom') {\n      if (!this._hasLoaded) {\n        return [];\n      }\n      const lines = Array.isArray(text) ? text : text.split(TEXT_NEWLINE_REGEXP);\n      const measurements = this.measureText(text, fontSize);\n      const lineWidths = measurements.lineWidths;\n      const lineHeight = measurements.lineHeight;\n      return lines.map((line, lineIndex) => {\n        const [_x, _y, _z] = this.getTextOrigin({\n          ...measurements,\n          width: lineWidths[lineIndex],\n        }, x, y, z, alignX, alignY);\n        y += lineHeight;\n        const glyphs = Typr.U.stringToGlyphs(this.font, line);\n        const path = Typr.U.glyphsToPath(this.font, glyphs);\n        return this._convertPathCommands(path, fontSize, _x, _y, z);\n      }).flat();\n    }\n\n    getTextGlyphs(text, fontSize=64, x=0, y=0, z=0, alignX='left', alignY='bottom') {\n      if (!this._hasLoaded) {\n        return [];\n      }\n      const measurements = this.measureText(text, fontSize);\n      const advanceWidthTable = this.font.hmtx.aWidth;\n      const fontScale = this.getFontScale(fontSize);\n      const lineWidths = measurements.lineWidths;\n      const lineHeight = measurements.lineHeight;\n      const lines = Array.isArray(text) ? text : text.split(TEXT_NEWLINE_REGEXP);\n      return lines.map((line, lineIndex) => {\n        const glyphs = Typr.U.stringToGlyphs(this.font, line);\n        let [_x, _y, _z] = this.getTextOrigin({\n          ...measurements,\n          width: lineWidths[lineIndex]\n        }, x, y, z, alignX, alignY);\n        y += lineHeight;\n        return glyphs.filter(glyph => glyph !== -1).map(glyphId => {\n          const path = Typr.U.glyphToPath(this.font, glyphId);\n          const shape = {\n            translate: {x:_x, y: _y, z:_z},\n            path: this._convertPathCommands(path, fontSize, 0, 0, 0)\n          };\n          _x += advanceWidthTable[glyphId] * fontScale;\n          return shape;\n        });\n      }).flat(); \n    }\n\n    getTextOrigin(measuement, x=0, y=0, z=0, alignX='left', alignY='bottom') {\n      let { width, height, lineHeight } = measuement;\n      switch (alignX) {\n        case 'right':\n          x -= width;\n          break;\n        case 'center':\n          x -= width / 2;\n          break;\n        default:\n          break;\n      }\n      switch (alignY) {\n        case 'middle':\n          y -= (height / 2)  - lineHeight;\n          break;\n        case 'bottom':\n        default:\n          y -= height - lineHeight;\n          break;\n      }\n      return [x, y, z];\n    }\n\n    // Convert Typr.js path commands to Zdog commands\n    // Also apply font size scaling and coordinate adjustment\n    // https://github.com/photopea/Typr.js\n    // https://zzz.dog/shapes#shape-path-commands\n    _convertPathCommands(path, fontSize, x=0, y=0, z=0) {\n      const yDir = -1;\n      const xDir = 1;\n      const fontScale = this.getFontScale(fontSize);\n      const commands = path.cmds;\n      // Apply font scale to all coords\n      const coords = path.crds.map(coord => coord * fontScale);\n      // Convert coords to Zdog commands\n      let startCoord = null;\n      let coordOffset = 0;\n      return commands.map((cmd) => {\n        let result = null;\n        if (!startCoord) {\n          startCoord = {x: x + coords[coordOffset] * xDir, y: y + coords[coordOffset + 1] * yDir, z};\n        }\n        switch (cmd) {\n          case 'M': // moveTo command\n            result = {\n              move: {x: x + coords[coordOffset] * xDir, y: y + coords[coordOffset + 1] * yDir, z}\n            };\n            coordOffset += 2;\n            return result;\n          case 'L': // lineTo command\n            result = {\n              line: {x: x + coords[coordOffset] * xDir, y: y + coords[coordOffset + 1] * yDir, z}\n            };\n            coordOffset += 2;\n            return result;\n          case 'C': // curveTo command\n            result = {\n              bezier: [\n                {x: x + coords[coordOffset]     * xDir, y: y + coords[coordOffset + 1] * yDir, z},\n                {x: x + coords[coordOffset + 2] * xDir, y: y + coords[coordOffset + 3] * yDir, z},\n                {x: x + coords[coordOffset + 4] * xDir, y: y + coords[coordOffset + 5] * yDir, z},\n              ]\n            };\n            coordOffset += 6;\n            return result;\n          case 'Q': // arcTo command\n            result = {\n              arc: [\n                {x: x + coords[coordOffset]     * xDir, y: y + coords[coordOffset + 1] * yDir, z},\n                {x: x + coords[coordOffset + 2] * xDir, y: y + coords[coordOffset + 3] * yDir, z},\n              ]\n            };\n            coordOffset += 4;\n            return result;\n          case 'Z': // close path\n            if (startCoord) {\n              result = {\n                line: startCoord\n              };\n              startCoord = null;\n            }\n            return result;\n          // unhandled type\n          // currently, #rrggbb and X types (used in multicolor fonts) aren't supported\n          default:\n            return result;\n        }\n      }).filter(cmd => cmd !== null); // filter out null commands\n    }\n\n    _fetchFontResource(source) {\n      return new Promise((resolve, reject) => {\n        const request = new XMLHttpRequest();\n        // Fetch as an arrayBuffer for Typr.parse\n        request.responseType = 'arraybuffer'; \n        request.open('GET', source, true);\n        request.onreadystatechange = e => {\n          if (request.readyState === 4) {\n            if (request.status >= 200 && request.status < 300) {\n              resolve(request.response);\n            } else {\n              reject(`HTTP error ${request.status}: ${request.statusText}`);\n            }\n          }\n        };\n        request.send(null);\n      });\n    }\n  }\n\n  Zdog.Font = ZdogFont;\n  return Zdog;\n}"
  },
  {
    "path": "src/ZdogText.js",
    "content": "export function registerTextClass(Zdog) {\n\n  // Zdog.Text class\n  class ZdogText extends Zdog.Shape {\n    constructor(props) {\n      // Set missing props to default values\n      props = Zdog.extend({\n        font: null,\n        value: '',\n        fontSize: 64,\n        textAlign: 'left',\n        textBaseline: 'bottom',\n      }, props);\n      // Split props\n      const {\n        font,\n        value,\n        fontSize,\n        textAlign,\n        textBaseline,\n        ...shapeProps\n      } = props;\n      // Create shape object\n      super({\n        ...shapeProps,\n        closed: true,\n        visible: false, // hide until font is loaded\n        path: [{}]\n      });\n      this._font = null;\n      this._value = value;\n      this._fontSize = fontSize;\n      this._textAlign = textAlign;\n      this._textBaseline = textBaseline;\n      this.font = font;\n    }\n\n    updateText() {\n      let path = this.font.getTextPath(this.value, this.fontSize, 0, 0, 0, this.textAlign, this.textBaseline);\n      if (path.length == 0) { // zdog doesn't know what to do with empty path arrays\n        this.path = [{}];\n        this.visible = false;\n      } else {\n        this.path = path;\n        this.visible = true;\n      }\n      this.updatePath();\n    }\n\n    set font(newFont) {\n      this._font = newFont;\n      this.font.waitForLoad().then(() => {\n        this.updateText();\n        this.visible = true;\n        // Find root Zdog.Illustration instance\n        let root = this.addTo;\n        while (root.addTo !== undefined) {\n          root = root.addTo;\n        }\n        // Update render graph\n        if (root && typeof root.updateRenderGraph === 'function') {\n          root.updateRenderGraph();\n        }\n      });\n    }\n\n    get font() {\n      return this._font;\n    }\n\n    set value(newValue) {\n      this._value = newValue;\n      this.updateText();\n    }\n    \n    get value() {\n      return this._value;\n    }\n\n    set fontSize(newSize) {\n      this._fontSize = newSize;\n      this.updateText();\n    }\n\n    get fontSize() {\n      return this._fontSize;\n    }\n\n    set textAlign(newValue) {\n      this._textAlign = newValue;\n      this.updateText();\n    }\n\n    get textAlign() {\n      return this._textAlign;\n    }\n\n    set textBaseline(newValue) {\n      this._textBaseline = newValue;\n      this.updateText();\n    }\n\n    get textBaseline() {\n      return this._textBaseline;\n    }\n  }\n\n  ZdogText.optionKeys = ZdogText.optionKeys.concat(['font', 'fontSize', 'value', 'textAlign', 'textBaseline']);\n  Zdog.Text = ZdogText;\n  return Zdog;\n}"
  },
  {
    "path": "src/ZdogTextGroup.js",
    "content": "export function registerTextGroupClass(Zdog) {\n\n  // Zdog.TextGroup class\n  class ZdogTextGroup extends Zdog.Group {\n    \n    constructor(props) {\n      // Set missing props to default values\n      props = Zdog.extend({\n        font: null,\n        value: '',\n        fontSize: 64,\n        textAlign: 'left',\n        textBaseline: 'bottom',\n        color: '#333',\n        fill: false,\n        stroke: 1,\n      }, props);\n      // Split props\n      const {\n        font,\n        value,\n        fontSize,\n        textAlign,\n        textBaseline,\n        color,\n        fill,\n        stroke,\n        ...groupProps\n      } = props;\n      // Create group object\n      super({\n        ...groupProps,\n        visible: false, // hide until font is loaded\n      });\n      this._font = null;\n      this._value = value;\n      this._fontSize = fontSize;\n      this._textAlign = textAlign;\n      this._textBaseline = textBaseline;\n      this._color = color;\n      this._fill = fill;\n      this._stroke = stroke;\n      this.font = font;\n    }\n\n    updateText() {\n      // Remove old children\n      while (this.children.length > 0) {\n        this.removeChild(this.children[0]);\n      }\n      // Get text paths for each glyph\n      const glyphs = this.font.getTextGlyphs(this.value, this.fontSize, 0, 0, 0, this.textAlign, this.textBaseline);\n      // Convert glyphs to new shapes\n      glyphs.filter(shape => shape.path.length > 0).forEach(shape => {\n        this.addChild(new Zdog.Shape({\n          translate: shape.translate,\n          path: shape.path,\n          color: this.color,\n          fill: this.fill,\n          stroke: this.stroke,\n          closed: true,\n        }));\n      });\n      this.updateFlatGraph();\n    }\n\n    set font(newFont) {\n      this._font = newFont;\n      this._font.waitForLoad().then(() => {\n        this.updateText();\n        this.visible = true;\n        // Find root Zdog.Illustration instance\n        let root = this.addTo;\n        while (root.addTo !== undefined) {\n          root = root.addTo;\n        }\n        // Update render graph\n        if (root && typeof root.updateRenderGraph === 'function') {\n          root.updateRenderGraph();\n        }\n      });\n    }\n\n    get font() {\n      return this._font;\n    }\n\n    set value(newValue) {\n      this._value = newValue;\n      this.updateText();\n    }\n    \n    get value() {\n      return this._value;\n    }\n\n    set fontSize(newSize) {\n      this._fontSize = newSize;\n      this.updateText();\n    }\n\n    get fontSize() {\n      return this._fontSize;\n    }\n\n    set textAlign(newValue) {\n      this._textAlign = newValue;\n      this.updateText();\n    }\n\n    get textAlign() {\n      return this._textAlign;\n    }\n\n    set textBaseline(newValue) {\n      this._textBaseline = newValue;\n      this.updateText();\n    }\n\n    get textBaseline() {\n      return this._textBaseline;\n    }\n\n    set color(newColor) {\n      this._color = newColor;\n      this.children.forEach(child => child.color = newColor);\n    }\n\n    get color() {\n      return this._color;\n    }\n\n    set fill(newFill) {\n      this._fill = newFill;\n      this.children.forEach(child => child.fill = newFill);\n    }\n\n    get fill() {\n      return this._fill;\n    }\n\n    set stroke(newStroke) {\n      this._stroke = newStroke;\n      this.children.forEach(child => child.stroke = newStroke);\n    }\n\n    get stroke() {\n      return this._stroke;\n    }\n  }\n\n  ZdogTextGroup.optionKeys = ZdogTextGroup.optionKeys.concat(['color', 'fill', 'stroke', 'font', 'fontSize', 'value', 'textAlign', 'textBaseline']);\n  Zdog.TextGroup = ZdogTextGroup;\n  return Zdog;\n}"
  },
  {
    "path": "src/index.js",
    "content": "import { registerFontClass } from './ZdogFont';\nimport { registerTextClass } from './ZdogText';\nimport { registerTextGroupClass } from './ZdogTextGroup';\n\nexport default {\n  init(Zdog) {\n    // Global font list to keep track of all fonts\n    Zdog.FontList = [];\n\n    // Helper to wait for all fonts to load\n    Zdog.waitForFonts = function() {\n      return Promise.all(Zdog.FontList.map(font => font.waitForLoad()));\n    };\n    \n    // Register Zfont classes onto the Zdog object\n    registerFontClass(Zdog);\n    registerTextClass(Zdog);\n    registerTextGroupClass(Zdog);\n\n    return Zdog;\n  },\n  version: VERSION,\n}\n\n// add dev server flag to the window object\n// this will be stripped in production builds\nif (DEV_SERVER) {\n  window.isDevServer = true;\n}"
  }
]