Sfoglia il codice sorgente

Merge branch 'dev' into nanite

sunag 8 ore fa
parent
commit
ce810fd00f
61 ha cambiato i file con 1739 aggiunte e 31172 eliminazioni
  1. 18 5
      build/three.cjs
  2. 18 5
      build/three.module.js
  3. 0 0
      build/three.module.min.js
  4. 2 0
      build/three.tsl.js
  5. 0 0
      build/three.tsl.min.js
  6. 454 201
      build/three.webgpu.js
  7. 0 0
      build/three.webgpu.min.js
  8. 454 201
      build/three.webgpu.nodes.js
  9. 0 0
      build/three.webgpu.nodes.min.js
  10. 1 1
      editor/index.html
  11. 1 2
      editor/js/Menubar.File.js
  12. 18 2
      editor/js/Sidebar.Geometry.js
  13. 26 5
      examples/jsm/exporters/DRACOExporter.js
  14. 4 4
      examples/jsm/inspector/tabs/Console.js
  15. 17 3
      examples/jsm/inspector/tabs/Performance.js
  16. 79 10
      examples/jsm/inspector/tabs/Viewer.js
  17. 49 3
      examples/jsm/inspector/ui/Profiler.js
  18. 89 107
      examples/jsm/inspector/ui/Style.js
  19. 0 822
      examples/jsm/libs/ammo.wasm.js
  20. BIN
      examples/jsm/libs/ammo.wasm.wasm
  21. 0 3
      examples/jsm/libs/draco/draco_encoder.js
  22. 0 3
      examples/jsm/libs/draco/gltf/draco_encoder.js
  23. 0 14849
      examples/jsm/libs/lottie_canvas.module.js
  24. 0 14506
      examples/jsm/libs/opentype.module.js
  25. 1 1
      examples/jsm/loaders/LottieLoader.js
  26. 1 1
      examples/jsm/loaders/TTFLoader.js
  27. 15 8
      examples/jsm/physics/AmmoPhysics.js
  28. 27 23
      examples/jsm/tsl/display/SSGINode.js
  29. 1 1
      examples/jsm/tsl/lighting/ClusteredLightsNode.js
  30. 3 3
      examples/misc_exporter_draco.html
  31. 1 1
      examples/physics_ammo_break.html
  32. 1 1
      examples/physics_ammo_cloth.html
  33. 0 2
      examples/physics_ammo_instancing.html
  34. 1 1
      examples/physics_ammo_rope.html
  35. 1 1
      examples/physics_ammo_terrain.html
  36. 1 1
      examples/physics_ammo_volume.html
  37. BIN
      examples/screenshots/webgl_tsl_shadowmap.jpg
  38. BIN
      examples/screenshots/webgpu_lights_clustered.jpg
  39. BIN
      examples/screenshots/webgpu_modifier_curve.jpg
  40. BIN
      examples/screenshots/webgpu_shadowmap.jpg
  41. 151 174
      examples/webgpu_lights_clustered.html
  42. 0 26
      src/materials/nodes/Line2NodeMaterial.js
  43. 0 9
      src/materials/nodes/MeshPhongNodeMaterial.js
  44. 0 30
      src/materials/nodes/MeshPhysicalNodeMaterial.js
  45. 0 13
      src/materials/nodes/MeshSSSNodeMaterial.js
  46. 0 11
      src/materials/nodes/MeshStandardNodeMaterial.js
  47. 68 28
      src/materials/nodes/NodeMaterial.js
  48. 0 10
      src/materials/nodes/SpriteNodeMaterial.js
  49. 5 1
      src/nodes/accessors/Position.js
  50. 30 17
      src/nodes/core/OverrideContextNode.js
  51. 2 2
      src/nodes/lighting/ShadowNode.js
  52. 15 7
      src/renderers/common/RenderObject.js
  53. 1 2
      src/renderers/common/Renderer.js
  54. 7 1
      src/renderers/common/nodes/NodeManager.js
  55. 13 1
      src/renderers/webgl-fallback/utils/WebGLTextureUtils.js
  56. 18 5
      src/renderers/webgl/WebGLTextures.js
  57. 24 5
      src/renderers/webgpu/WebGPUBackend.js
  58. 65 17
      src/renderers/webgpu/utils/WebGPUAttributeUtils.js
  59. 18 32
      src/renderers/webgpu/utils/WebGPUPipelineUtils.js
  60. 23 4
      src/renderers/webgpu/utils/WebGPUTextureUtils.js
  61. 16 1
      src/renderers/webgpu/utils/WebGPUUtils.js

+ 18 - 5
build/three.cjs

@@ -72275,12 +72275,25 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 					}
 
-					const level = 0;
-					const internalFormat = _gl.RGBA;
-					const srcFormat = _gl.RGBA;
-					const srcType = _gl.UNSIGNED_BYTE;
+					if ( _gl.texElementImage2D.length === 3 ) {
+
+						// Chrome 150+
+
+						_gl.texElementImage2D( _gl.TEXTURE_2D, _gl.RGBA8, image );
+
+					} else {
+
+						// Chrome 138 - 149
+
+						const level = 0;
+						const internalFormat = _gl.RGBA;
+						const srcFormat = _gl.RGBA;
+						const srcType = _gl.UNSIGNED_BYTE;
+
+						_gl.texElementImage2D( _gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image );
+
+					}
 
-					_gl.texElementImage2D( _gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image );
 					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR );
 					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
 					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );

+ 18 - 5
build/three.module.js

@@ -12298,12 +12298,25 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 					}
 
-					const level = 0;
-					const internalFormat = _gl.RGBA;
-					const srcFormat = _gl.RGBA;
-					const srcType = _gl.UNSIGNED_BYTE;
+					if ( _gl.texElementImage2D.length === 3 ) {
+
+						// Chrome 150+
+
+						_gl.texElementImage2D( _gl.TEXTURE_2D, _gl.RGBA8, image );
+
+					} else {
+
+						// Chrome 138 - 149
+
+						const level = 0;
+						const internalFormat = _gl.RGBA;
+						const srcFormat = _gl.RGBA;
+						const srcType = _gl.UNSIGNED_BYTE;
+
+						_gl.texElementImage2D( _gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image );
+
+					}
 
-					_gl.texElementImage2D( _gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image );
 					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR );
 					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
 					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );

File diff suppressed because it is too large
+ 0 - 0
build/three.module.min.js


File diff suppressed because it is too large
+ 2 - 0
build/three.tsl.js


File diff suppressed because it is too large
+ 0 - 0
build/three.tsl.min.js


File diff suppressed because it is too large
+ 454 - 201
build/three.webgpu.js


File diff suppressed because it is too large
+ 0 - 0
build/three.webgpu.min.js


File diff suppressed because it is too large
+ 454 - 201
build/three.webgpu.nodes.js


File diff suppressed because it is too large
+ 0 - 0
build/three.webgpu.nodes.min.js


+ 1 - 1
editor/index.html

@@ -26,7 +26,7 @@
 			}
 		</script>
 
-		<script src="../examples/jsm/libs/draco/draco_encoder.js"></script>
+		<script src="https://cdn.jsdelivr.net/gh/google/draco@1.5.7/javascript/draco_encoder.js"></script>
 
 		<link rel="stylesheet" href="js/libs/codemirror/codemirror.css">
 		<link rel="stylesheet" href="js/libs/codemirror/theme/monokai.css">

+ 1 - 2
editor/js/Menubar.File.js

@@ -261,8 +261,7 @@ function MenubarFile( editor ) {
 			exportColor: object.geometry.hasAttribute( 'color' )
 		};
 
-		// TODO: Change to DRACOExporter's parse( geometry, onParse )?
-		const result = exporter.parse( object, options );
+		const result = await exporter.parseAsync( object, options );
 		saveArrayBuffer( result, 'model.drc' );
 
 	} );

+ 18 - 2
editor/js/Sidebar.Geometry.js

@@ -204,7 +204,7 @@ function SidebarGeometry( editor ) {
 
 		if ( editor.helpers[ object.id ] === undefined ) {
 
-			editor.addHelper( object, new VertexNormalsHelper( object ) );
+			editor.addHelper( object, new VertexNormalsHelper( object, vertexNormalsSize.getValue() ) );
 
 		} else {
 
@@ -217,6 +217,22 @@ function SidebarGeometry( editor ) {
 	} );
 	helpersRow.add( vertexNormalsButton );
 
+	const vertexNormalsSize = new UINumber( 1 ).setWidth( '30px' ).setMarginLeft( '7px' ).setRange( 0, Infinity ).onChange( function () {
+
+		const object = editor.selected;
+		const helper = editor.helpers[ object.id ];
+
+		if ( helper !== undefined && helper.isVertexNormalsHelper === true ) {
+
+			helper.size = vertexNormalsSize.getValue();
+
+			signals.objectChanged.dispatch( object );
+
+		}
+
+	} );
+	helpersRow.add( vertexNormalsSize );
+
 	// Export JSON
 
 	const exportJson = new UIButton( strings.getKey( 'sidebar/geometry/export' ) );
@@ -317,7 +333,7 @@ function SidebarGeometry( editor ) {
 			if ( helper !== undefined && helper.isVertexNormalsHelper === true ) {
 
 				editor.removeHelper( object );
-				editor.addHelper( object, new VertexNormalsHelper( object ) );
+				editor.addHelper( object, new VertexNormalsHelper( object, vertexNormalsSize.getValue() ) );
 
 			}
 

+ 26 - 5
examples/jsm/exporters/DRACOExporter.js

@@ -15,9 +15,15 @@ import { Color, ColorManagement, SRGBColorSpace } from 'three';
  * inside of a glTF file. A normal glTF file can be converted to a Draco-compressed glTF file
  * using [glTF-Pipeline](https://github.com/AnalyticalGraphicsInc/gltf-pipeline).
  *
+ * The exporter requires the Draco encoder to be loaded as a global script in advance:
+ *
+ * ```html
+ * <script src="https://cdn.jsdelivr.net/gh/google/draco@1.5.7/javascript/draco_encoder.js"></script>
+ * ```
+ *
  * ```js
  * const exporter = new DRACOExporter();
- * const data = exporter.parse( mesh, options );
+ * const data = await exporter.parseAsync( mesh, options );
  * ```
  *
  * @three_import import { DRACOExporter } from 'three/addons/exporters/DRACOExporter.js';
@@ -27,11 +33,12 @@ class DRACOExporter {
 	/**
 	 * Parses the given mesh or point cloud and generates the Draco output.
 	 *
+	 * @async
 	 * @param {(Mesh|Points)} object - The mesh or point cloud to export.
 	 * @param {DRACOExporter~Options} options - The export options.
-	 * @return {Int8Array} The exported Draco.
+	 * @return {Promise<Int8Array>} A Promise that resolves with the exported Draco.
 	 */
-	parse( object, options = {} ) {
+	async parseAsync( object, options = {} ) {
 
 		options = Object.assign( {
 			decodeSpeed: 5,
@@ -43,7 +50,7 @@ class DRACOExporter {
 			exportColor: false,
 		}, options );
 
-		if ( DracoEncoderModule === undefined ) {
+		if ( typeof DracoEncoderModule === 'undefined' ) {
 
 			throw new Error( 'THREE.DRACOExporter: required the draco_encoder to work.' );
 
@@ -51,7 +58,12 @@ class DRACOExporter {
 
 		const geometry = object.geometry;
 
-		const dracoEncoder = DracoEncoderModule();
+		let dracoEncoder = DracoEncoderModule();
+
+		// older encoder builds expose the module synchronously, newer builds return a promise
+
+		if ( dracoEncoder.Encoder === undefined ) dracoEncoder = await dracoEncoder;
+
 		const encoder = new dracoEncoder.Encoder();
 		let builder;
 		let dracoObject;
@@ -222,6 +234,15 @@ class DRACOExporter {
 
 	}
 
+	/**
+	 * @deprecated Use {@link DRACOExporter#parseAsync} instead.
+	 */
+	parse() {
+
+		throw new Error( 'THREE.DRACOExporter: parse() has been replaced by parseAsync().' );
+
+	}
+
 }
 
 function createVertexColorSRGBArray( attribute ) {

+ 4 - 4
examples/jsm/inspector/tabs/Console.js

@@ -259,7 +259,7 @@ class Console extends Tab {
 
 			if ( this.unreadErrors > 0 ) {
 
-				errorBadge.textContent = this.unreadErrors;
+				errorBadge.textContent = this.unreadErrors > 99 ? '+99' : this.unreadErrors;
 				errorBadge.style.display = '';
 
 			} else {
@@ -274,7 +274,7 @@ class Console extends Tab {
 
 			if ( this.unreadWarns > 0 ) {
 
-				warnBadge.textContent = this.unreadWarns;
+				warnBadge.textContent = this.unreadWarns > 99 ? '+99' : this.unreadWarns;
 				warnBadge.style.display = '';
 
 			} else {
@@ -289,7 +289,7 @@ class Console extends Tab {
 
 			if ( this.unreadErrors > 0 ) {
 
-				this.tabErrorBadge.textContent = this.unreadErrors;
+				this.tabErrorBadge.textContent = this.unreadErrors > 99 ? '+99' : this.unreadErrors;
 				this.tabErrorBadge.style.display = '';
 
 			} else {
@@ -304,7 +304,7 @@ class Console extends Tab {
 
 			if ( this.unreadWarns > 0 ) {
 
-				this.tabWarnBadge.textContent = this.unreadWarns;
+				this.tabWarnBadge.textContent = this.unreadWarns > 99 ? '+99' : this.unreadWarns;
 				this.tabWarnBadge.style.display = '';
 
 			} else {

+ 17 - 3
examples/jsm/inspector/tabs/Performance.js

@@ -26,7 +26,8 @@ class Performance extends Tab {
 
 		const graph = new Graph();
 		graph.addLine( 'fps', 'var( --color-fps )' );
-		//graph.addLine( 'gpu', 'var( --color-yellow )' );
+		graph.addLine( 'cpu', 'var( --color-yellow )' );
+		graph.addLine( 'gpu', 'var( --color-green )' );
 		graphContainer.append( graph.domElement );
 
 		//
@@ -161,9 +162,22 @@ class Performance extends Tab {
 
 	}
 
-	updateGraph( inspector/*, frame*/ ) {
+	updateGraph( inspector, frame ) {
+
+		const fps = inspector.fps;
+
+		this.graph.addPoint( 'fps', fps );
+
+		if ( frame ) {
+
+			const cpuValue = Math.min( ( ( frame.cpu || 0 ) * fps ) / 1000, 1.0 ) * fps;
+			const gpuValue = Math.min( ( ( frame.gpu || 0 ) * fps ) / 1000, 1.0 ) * fps;
+
+			this.graph.addPoint( 'cpu', cpuValue );
+			this.graph.addPoint( 'gpu', gpuValue );
+
+		}
 
-		this.graph.addPoint( 'fps', inspector.fps );
 		this.graph.update();
 
 	}

+ 79 - 10
examples/jsm/inspector/tabs/Viewer.js

@@ -2,6 +2,7 @@ import { Tab } from '../ui/Tab.js';
 import { List } from '../ui/List.js';
 import { Item } from '../ui/Item.js';
 import { splitPath, splitCamelCase } from '../ui/utils.js';
+import { getItem, setItem } from '../Inspector.js';
 
 import { RendererUtils, NoToneMapping, LinearSRGBColorSpace, QuadMesh, NodeMaterial, CanvasTarget, Vector2 } from 'three/webgpu';
 import { renderOutput, vec2, vec3, vec4, Fn, screenUV, step, OnMaterialUpdate, uniform, float } from 'three/tsl';
@@ -108,6 +109,7 @@ class Viewer extends Tab {
 		this.select = select;
 		this.backBtn = backBtn;
 		this.activeFullNodeId = null;
+		this.pendingRestoreView = true;
 
 		backBtn.addEventListener( 'click', () => {
 
@@ -126,6 +128,8 @@ class Viewer extends Tab {
 
 			}
 
+			this.saveLastView();
+
 		} );
 
 		select.addEventListener( 'change', () => {
@@ -142,6 +146,8 @@ class Viewer extends Tab {
 
 			}
 
+			this.saveLastView();
+
 		} );
 
 		// Event forwarding setup for OrbitControls
@@ -243,6 +249,7 @@ class Viewer extends Tab {
 				e.stopPropagation();
 				this.select.value = canvasData.id;
 				this.showNodeView( canvasData.id );
+				this.saveLastView();
 
 			};
 
@@ -276,6 +283,8 @@ class Viewer extends Tab {
 
 				}
 
+				this.saveLastView();
+
 			};
 
 			wrapper.appendChild( domElement );
@@ -475,6 +484,8 @@ class Viewer extends Tab {
 
 		if ( canvasData ) {
 
+			this.addNodeItem( canvasData );
+
 			this.activeFullNodeId = nodeId;
 			this.backBtn.style.display = 'flex';
 
@@ -625,25 +636,61 @@ class Viewer extends Tab {
 
 			}
 
-			// Restore selection if still valid
-			let hasSelectedValue = false;
+			// Try to restore from saved view first on initial load
+			let restored = false;
 
-			for ( let i = 0; i < this.select.options.length; i ++ ) {
+			if ( this.pendingRestoreView ) {
 
-				if ( this.select.options[ i ].value === currentSelectedValue ) {
+				const savedView = getItem( 'viewerLastView' );
 
-					this.select.selectedIndex = i;
-					hasSelectedValue = true;
-					break;
+				if ( savedView !== 'list' ) {
+
+					for ( let i = 0; i < this.select.options.length; i ++ ) {
+
+						if ( this.select.options[ i ].textContent === savedView ) {
+
+							this.select.selectedIndex = i;
+							const nodeId = this.select.options[ i ].value;
+							this.showNodeView( nodeId );
+							restored = true;
+							this.pendingRestoreView = false;
+							break;
+
+						}
+
+					}
+
+				} else {
+
+					this.pendingRestoreView = false;
 
 				}
 
 			}
 
-			if ( ! hasSelectedValue ) {
+			if ( ! restored ) {
 
-				this.select.value = 'list';
-				this.showListView();
+				// Restore selection if still valid
+				let hasSelectedValue = false;
+
+				for ( let i = 0; i < this.select.options.length; i ++ ) {
+
+					if ( this.select.options[ i ].value === currentSelectedValue ) {
+
+						this.select.selectedIndex = i;
+						hasSelectedValue = true;
+						break;
+
+					}
+
+				}
+
+				if ( ! hasSelectedValue ) {
+
+					this.select.value = 'list';
+					this.showListView();
+
+				}
 
 			}
 
@@ -804,6 +851,28 @@ class Viewer extends Tab {
 
 	}
 
+	saveLastView() {
+
+		const selectedValue = this.select.value;
+
+		if ( selectedValue === 'list' ) {
+
+			setItem( 'viewerLastView', 'list' );
+
+		} else {
+
+			const selectedOption = this.select.options[ this.select.selectedIndex ];
+
+			if ( selectedOption ) {
+
+				setItem( 'viewerLastView', selectedOption.textContent );
+
+			}
+
+		}
+
+	}
+
 }
 
 export { Viewer };

+ 49 - 3
examples/jsm/inspector/ui/Profiler.js

@@ -31,6 +31,18 @@ export class Profiler extends EventDispatcher {
 		// Setup orientation change listener for mobile devices
 		this.setupOrientationListener();
 
+		this.checkHeaderScroll();
+
+		this.panel.addEventListener( 'transitionend', ( e ) => {
+
+			if ( e.target === this.panel && ( e.propertyName === 'width' || e.propertyName === 'height' || e.propertyName === 'transform' ) ) {
+
+				this.checkHeaderScroll();
+
+			}
+
+		} );
+
 	}
 
 	getSize() {
@@ -181,6 +193,7 @@ export class Profiler extends EventDispatcher {
 
 			constrainDetachedWindows();
 			constrainMainPanel();
+			this.checkHeaderScroll();
 
 		} );
 
@@ -397,6 +410,7 @@ export class Profiler extends EventDispatcher {
 				}
 
 				this.dispatchEvent( { type: 'resize' } );
+				this.checkHeaderScroll();
 
 			};
 
@@ -774,7 +788,7 @@ export class Profiler extends EventDispatcher {
 			// No tabs visible - set to minimum size
 			if ( this.position === 'bottom' ) {
 
-				this.panel.style.height = '38px';
+				this.panel.style.height = '32px';
 
 			} else if ( this.position === 'right' ) {
 
@@ -793,7 +807,7 @@ export class Profiler extends EventDispatcher {
 				if ( this.position === 'bottom' ) {
 
 					const currentHeight = parseInt( this.panel.style.height );
-					if ( currentHeight === 38 ) {
+					if ( currentHeight === 32 || currentHeight === 38 ) {
 
 						this.panel.style.height = `${ this.lastHeightBottom }px`;
 
@@ -815,6 +829,29 @@ export class Profiler extends EventDispatcher {
 		}
 
 		this.dispatchEvent( { type: 'resize' } );
+		this.checkHeaderScroll();
+
+	}
+
+	checkHeaderScroll() {
+
+		const header = this.panel.querySelector( '.profiler-header' );
+
+		if ( header ) {
+
+			const hasScroll = header.scrollWidth > header.clientWidth + 1;
+
+			if ( hasScroll ) {
+
+				this.panel.classList.add( 'has-horizontal-scroll' );
+
+			} else {
+
+				this.panel.classList.remove( 'has-horizontal-scroll' );
+
+			}
+
+		}
 
 	}
 
@@ -1624,11 +1661,20 @@ export class Profiler extends EventDispatcher {
 
 		if ( this.tabs[ id ] ) {
 
-			this.tabs[ id ].setActive( true );
+			const tab = this.tabs[ id ];
+
+			if ( ! tab.isVisible ) {
+
+				tab.show();
+
+			}
+
+			tab.setActive( true );
 
 		}
 
 		this.saveLayout();
+		this.checkHeaderScroll();
 
 	}
 

+ 89 - 107
examples/jsm/inspector/ui/Style.js

@@ -22,7 +22,7 @@ export class Style {
 		--font-mono: 'Courier New', Courier, monospace;
 	}
 
-	.profiler-panel *, .profiler-toggle * {
+	.profiler-panel *, .profiler-toggle *, .detached-tab-panel * {
 		text-transform: initial;
 		line-height: normal;
 		box-sizing: border-box;
@@ -699,31 +699,35 @@ export class Style {
 
 		overflow-x: auto;
 		overflow-y: hidden;
-		width: calc(100% - 134px);
-		height: 38px;
+		width: calc(100% - 120px);
+		height: 32px;
 		user-select: none;
 		-webkit-user-select: none;
 	}
 
+	.profiler-panel.has-horizontal-scroll .profiler-header {
+		height: 38px;
+	}
+
 	/* Adjust header width based on panel position */
 	.profiler-panel.position-right .profiler-header,
 	.profiler-panel.position-left .profiler-header {
-		width: calc(100% - 134px);
+		width: calc(100% - 120px);
 	}
 
 	.profiler-panel.position-bottom .profiler-header,
 	.profiler-panel.position-top .profiler-header {
-		width: calc(100% - 134px);
+		width: calc(100% - 120px);
 	}
 
 	/* Adjust header width when position toggle button is hidden (mobile) */
 	.profiler-panel.hide-position-toggle .profiler-header {
-		width: calc(100% - 90px);
+		width: calc(100% - 80px);
 	}
 
 	/* Adjust header width when maximized (floating position toggle button is hidden) */
 	.profiler-panel.maximized .profiler-header {
-		width: calc(100% - 90px);
+		width: calc(100% - 80px);
 	}
 
 	/* ===== RULES FOR WHEN THERE ARE NO TABS ===== */
@@ -731,14 +735,14 @@ export class Style {
 	/* Horizontal mode (bottom/top) without tabs */
 	.profiler-panel.position-bottom.no-tabs:not(.maximized),
 	.profiler-panel.position-top.no-tabs:not(.maximized) {
-		height: 38px !important;
-		min-height: 38px !important;
+		height: 32px !important;
+		min-height: 32px !important;
 	}
 
 	.profiler-panel.position-bottom.no-tabs .profiler-header,
 	.profiler-panel.position-top.no-tabs .profiler-header {
 		width: 100%;
-		height: 38px;
+		height: 32px;
 		border-bottom: none;
 	}
 
@@ -755,8 +759,8 @@ export class Style {
 	/* Vertical mode (right/left) without tabs */
 	.profiler-panel.position-right.no-tabs:not(.maximized),
 	.profiler-panel.position-left.no-tabs:not(.maximized) {
-		width: 45px !important;
-		min-width: 45px !important;
+		width: 40px !important;
+		min-width: 40px !important;
 	}
 
 	/* Vertical layout for header when no tabs */
@@ -784,7 +788,7 @@ export class Style {
 	.profiler-panel.position-right.no-tabs .profiler-controls button,
 	.profiler-panel.position-left.no-tabs .profiler-controls button {
 		width: 100%;
-		height: 45px;
+		height: 40px;
 		border-left: none;
 		border-top: none;
 		border-bottom: 1px solid var(--profiler-border);
@@ -808,8 +812,8 @@ export class Style {
 	/* Hide position toggle on mobile without tabs */
 	.profiler-panel.hide-position-toggle.position-right.no-tabs:not(.maximized),
 	.profiler-panel.hide-position-toggle.position-left.no-tabs:not(.maximized) {
-		width: 45px !important;
-		min-width: 45px !important;
+		width: 40px !important;
+		min-width: 40px !important;
 	}
 
 	/* Hide drag indicator on mobile devices */
@@ -817,29 +821,69 @@ export class Style {
 		display: none;
 	}
 
-	.profiler-header::-webkit-scrollbar {
-		width: 8px;
-		height: 8px;
+	.profiler-header::-webkit-scrollbar,
+	.profiler-tabs::-webkit-scrollbar,
+	.profiler-content::-webkit-scrollbar,
+	.detached-tab-content::-webkit-scrollbar,
+	.console-log::-webkit-scrollbar,
+	.timelineTrack::-webkit-scrollbar,
+	.list-scroll-wrapper::-webkit-scrollbar {
+		width: 4px;
+		height: 4px;
 	}
 
-	.profiler-header::-webkit-scrollbar-track {
+	.profiler-header::-webkit-scrollbar-track,
+	.profiler-tabs::-webkit-scrollbar-track,
+	.profiler-content::-webkit-scrollbar-track,
+	.detached-tab-content::-webkit-scrollbar-track,
+	.console-log::-webkit-scrollbar-track,
+	.timelineTrack::-webkit-scrollbar-track,
+	.list-scroll-wrapper::-webkit-scrollbar-track {
 		background: transparent;
 	}
 
-	.profiler-header::-webkit-scrollbar-thumb {
-		background-color: rgba(0, 0, 0, 0.25);
-		border-radius: 10px;
-		transition: background 0.3s ease;
+	.profiler-header::-webkit-scrollbar-thumb,
+	.profiler-tabs::-webkit-scrollbar-thumb,
+	.profiler-content::-webkit-scrollbar-thumb,
+	.detached-tab-content::-webkit-scrollbar-thumb,
+	.console-log::-webkit-scrollbar-thumb,
+	.timelineTrack::-webkit-scrollbar-thumb,
+	.list-scroll-wrapper::-webkit-scrollbar-thumb {
+		background-color: rgba(255, 255, 255, 0.15);
+		border-radius: 2px;
 	}
 
-	.profiler-header::-webkit-scrollbar-thumb:hover {
-		background-color: rgba(0, 0, 0, 0.4);
+	.profiler-header::-webkit-scrollbar-thumb:hover,
+	.profiler-tabs::-webkit-scrollbar-thumb:hover,
+	.profiler-content::-webkit-scrollbar-thumb:hover,
+	.detached-tab-content::-webkit-scrollbar-thumb:hover,
+	.console-log::-webkit-scrollbar-thumb:hover,
+	.timelineTrack::-webkit-scrollbar-thumb:hover,
+	.list-scroll-wrapper::-webkit-scrollbar-thumb:hover {
+		background-color: rgba(255, 255, 255, 0.3);
 	}
 
-	.profiler-header::-webkit-scrollbar-corner {
+	.profiler-header::-webkit-scrollbar-corner,
+	.profiler-tabs::-webkit-scrollbar-corner,
+	.profiler-content::-webkit-scrollbar-corner,
+	.detached-tab-content::-webkit-scrollbar-corner,
+	.console-log::-webkit-scrollbar-corner,
+	.timelineTrack::-webkit-scrollbar-corner,
+	.list-scroll-wrapper::-webkit-scrollbar-corner {
 		background: transparent;
 	}
 
+	.profiler-header,
+	.profiler-tabs,
+	.profiler-content,
+	.detached-tab-content,
+	.console-log,
+	.timelineTrack,
+	.list-scroll-wrapper {
+		scrollbar-width: thin;
+		scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
+	}
+
 	.profiler-panel.dragging .profiler-header {
 		cursor: grabbing !important;
 	}
@@ -858,52 +902,36 @@ export class Style {
 		cursor: grabbing;
 	}
 
-	.profiler-tabs::-webkit-scrollbar {
-		width: 8px;
-		height: 8px;
-	}
-
-	.profiler-tabs::-webkit-scrollbar-track {
-		background: transparent;
-	}
-
-	.profiler-tabs::-webkit-scrollbar-thumb {
-		background-color: rgba(0, 0, 0, 0.25);
-		border-radius: 10px;
-		transition: background 0.3s ease;
-	}
-
-	.profiler-tabs::-webkit-scrollbar-thumb:hover {
-		background-color: rgba(0, 0, 0, 0.4);
-	}
-
-	.profiler-tabs::-webkit-scrollbar-corner {
-		background: transparent;
-	}
 
 	.profiler-controls {
 		display: flex;
 		position: absolute;
 		right: 0;
 		top: 0;
-		height: 38px;
+		height: 32px;
 		background: var(--profiler-header-background);
 		border-bottom: 1px solid var(--profiler-border);
 	}
 
+	.profiler-panel.has-horizontal-scroll .profiler-controls {
+		height: 38px;
+	}
+
 	.tab-btn {
 		position: relative;
 		background: transparent;
 		border: none;
 		/*border-right: 1px solid var(--profiler-border);*/
 		color: var(--text-secondary);
-		padding: 8px 18px;
+		padding: 0 15px 2px 15px;
+		height: 100%;
+		box-sizing: border-box;
 		cursor: default;
 		display: flex;
 		align-items: center;
 		font-family: var(--font-family);
 		font-weight: 600;
-		font-size: 14px;
+		font-size: 13px;
 		user-select: none;
 		transition: opacity 0.2s, transform 0.2s;
 		touch-action: pan-x;
@@ -918,7 +946,7 @@ export class Style {
 	.tab-btn.active::before {
 		content: '⋮⋮';
 		position: absolute;
-		left: 3px;
+		left: 2px;
 		top: calc(50% - .1rem);
 		transform: translateY(-50%);
 		color: var(--profiler-border);
@@ -938,7 +966,7 @@ export class Style {
 		border: none;
 		border-left: 1px solid var(--profiler-border);
 		color: var(--text-secondary);
-		width: 45px;
+		width: 40px;
 		height: 100%;
 		cursor: pointer;
 		transition: all 0.2s;
@@ -1011,33 +1039,6 @@ export class Style {
 		overflow: auto; /* make sure scrollbars can appear */
 	}
 
-	.profiler-content::-webkit-scrollbar {
-		width: 8px;
-		height: 8px;
-	}
-
-	.profiler-content::-webkit-scrollbar-track {
-		background: transparent;
-	}
-
-	.profiler-content::-webkit-scrollbar-thumb {
-		background-color: rgba(0, 0, 0, 0.25);
-		border-radius: 10px;
-		transition: background 0.3s ease;
-	}
-
-	.profiler-content::-webkit-scrollbar-thumb:hover {
-		background-color: rgba(0, 0, 0, 0.4);
-	}
-
-	.profiler-content::-webkit-scrollbar-corner {
-		background: transparent;
-	}
-
-	.profiler-content {
-		scrollbar-width: thin; /* "auto" | "thin" */
-		scrollbar-color: rgba(0, 0, 0, 0.25) transparent;
-	}
 
 	.list-item-row {
 		display: grid;
@@ -1590,6 +1591,8 @@ export class Style {
 		opacity: 1;
 		visibility: visible;
 		transition: opacity 0.2s, visibility 0.2s;
+		font-family: var(--font-mono);
+		font-size: 13px;
 	}
 
 	.profiler-panel:not(.visible) ~ * .detached-tab-panel,
@@ -1601,9 +1604,9 @@ export class Style {
 
 	.detached-tab-header {
 		background: var(--profiler-header-background);
-		padding: 0 7px 0 15px;
+		padding: 0 3px 0 10px;
 		font-family: var(--font-family);
-		font-size: 14px;
+		font-size: 13px;
 		color: var(--text-primary);
 		font-weight: 600;
 		display: flex;
@@ -1612,7 +1615,7 @@ export class Style {
 		border-bottom: 1px solid var(--profiler-border);
 		cursor: grab;
 		user-select: none;
-		height: 38px;
+		height: 32px;
 		flex-shrink: 0;
 		-webkit-font-smoothing: antialiased;
 		-moz-osx-font-smoothing: grayscale;
@@ -1653,36 +1656,15 @@ export class Style {
 
 	.detached-tab-content {
 		flex: 1;
-		overflow: auto;
+		overflow: hidden;
 		position: relative;
 		background: var(--profiler-background);
 	}
 
-	.detached-tab-content::-webkit-scrollbar {
-		width: 8px;
-		height: 8px;
-	}
-
-	.detached-tab-content::-webkit-scrollbar-track {
-		background: transparent;
-	}
-
-	.detached-tab-content::-webkit-scrollbar-thumb {
-		background-color: rgba(0, 0, 0, 0.25);
-		border-radius: 10px;
-		transition: background 0.3s ease;
-	}
-
-	.detached-tab-content::-webkit-scrollbar-thumb:hover {
-		background-color: rgba(0, 0, 0, 0.4);
-	}
-
-	.detached-tab-content::-webkit-scrollbar-corner {
-		background: transparent;
-	}
 
 	.detached-tab-content .profiler-content {
-		display: block !important;
+		display: flex !important;
+		flex-direction: column !important;
 		height: 100%;
 		visibility: visible !important;
 		opacity: 1 !important;

+ 0 - 822
examples/jsm/libs/ammo.wasm.js

@@ -1,822 +0,0 @@
-
-// This is ammo.js, a port of Bullet Physics to JavaScript. zlib licensed.
-
-var Ammo = (function() {
-  var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
-  if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
-  return (
-function(Ammo) {
-  Ammo = Ammo || {};
-
-
-var b;b||(b=typeof Ammo !== 'undefined' ? Ammo : {});var ba;b.ready=new Promise(function(a){ba=a});var ca={},da;for(da in b)b.hasOwnProperty(da)&&(ca[da]=b[da]);var ea=!1,fa=!1,ha=!1,ia=!1;ea="object"===typeof window;fa="function"===typeof importScripts;ha="object"===typeof process&&"object"===typeof process.versions&&"string"===typeof process.versions.node;ia=!ea&&!ha&&!fa;var ja="",ka,la,ma,na;
-if(ha)ja=fa?require("path").dirname(ja)+"/":__dirname+"/",ka=function(a,c){ma||(ma=require("fs"));na||(na=require("path"));a=na.normalize(a);return ma.readFileSync(a,c?null:"utf8")},la=function(a){a=ka(a,!0);a.buffer||(a=new Uint8Array(a));assert(a.buffer);return a},1<process.argv.length&&process.argv[1].replace(/\\/g,"/"),process.argv.slice(2),process.on("uncaughtException",function(a){throw a;}),process.on("unhandledRejection",oa),b.inspect=function(){return"[Emscripten Module object]"};else if(ia)"undefined"!=
-typeof read&&(ka=function(a){return read(a)}),la=function(a){if("function"===typeof readbuffer)return new Uint8Array(readbuffer(a));a=read(a,"binary");assert("object"===typeof a);return a},"undefined"!==typeof print&&("undefined"===typeof console&&(console={}),console.log=print,console.warn=console.error="undefined"!==typeof printErr?printErr:print);else if(ea||fa)fa?ja=self.location.href:document.currentScript&&(ja=document.currentScript.src),_scriptDir&&(ja=_scriptDir),ja=0!==ja.indexOf("blob:")?
-ja.substr(0,ja.lastIndexOf("/")+1):"",ka=function(a){var c=new XMLHttpRequest;c.open("GET",a,!1);c.send(null);return c.responseText},fa&&(la=function(a){var c=new XMLHttpRequest;c.open("GET",a,!1);c.responseType="arraybuffer";c.send(null);return new Uint8Array(c.response)});var pa=b.print||console.log.bind(console),qa=b.printErr||console.warn.bind(console);for(da in ca)ca.hasOwnProperty(da)&&(b[da]=ca[da]);ca=null;var ra;b.wasmBinary&&(ra=b.wasmBinary);var noExitRuntime;
-b.noExitRuntime&&(noExitRuntime=b.noExitRuntime);"object"!==typeof WebAssembly&&qa("no native wasm support detected");var sa,ua=new WebAssembly.Table({initial:930,maximum:930,element:"anyfunc"}),va=!1;function assert(a,c){a||oa("Assertion failed: "+c)}var wa="undefined"!==typeof TextDecoder?new TextDecoder("utf8"):void 0,xa,ya,za,Aa,Ba,Ca,Da=b.INITIAL_MEMORY||67108864;if(sa=b.wasmMemory?b.wasmMemory:new WebAssembly.Memory({initial:Da/65536,maximum:Da/65536}))xa=sa.buffer;Da=xa.byteLength;var Ea=xa;
-xa=Ea;b.HEAP8=ya=new Int8Array(Ea);b.HEAP16=new Int16Array(Ea);b.HEAP32=Aa=new Int32Array(Ea);b.HEAPU8=za=new Uint8Array(Ea);b.HEAPU16=new Uint16Array(Ea);b.HEAPU32=new Uint32Array(Ea);b.HEAPF32=Ba=new Float32Array(Ea);b.HEAPF64=Ca=new Float64Array(Ea);Aa[7848]=5274432;function Fa(a){for(;0<a.length;){var c=a.shift();if("function"==typeof c)c(b);else{var d=c.Xy;"number"===typeof d?void 0===c.Ey?b.dynCall_v(d):b.dynCall_vi(d,c.Ey):d(void 0===c.Ey?null:c.Ey)}}}var Ga=[],Ha=[],Ia=[],Ja=[],Ka=!1;
-function La(){var a=b.preRun.shift();Ga.unshift(a)}var Ma=0,Na=null,Oa=null;b.preloadedImages={};b.preloadedAudios={};function oa(a){if(b.onAbort)b.onAbort(a);a+="";pa(a);qa(a);va=!0;throw new WebAssembly.RuntimeError("abort("+a+"). Build with -s ASSERTIONS=1 for more info.");}function Pa(a){var c=Qa;return String.prototype.startsWith?c.startsWith(a):0===c.indexOf(a)}function Ra(){return Pa("data:application/octet-stream;base64,")}var Qa="ammo.wasm.wasm";
-if(!Ra()){var Sa=Qa;Qa=b.locateFile?b.locateFile(Sa,ja):ja+Sa}function Ta(){try{if(ra)return new Uint8Array(ra);if(la)return la(Qa);throw"both async and sync fetching of the wasm failed";}catch(a){oa(a)}}function Ua(){return ra||!ea&&!fa||"function"!==typeof fetch||Pa("file://")?new Promise(function(a){a(Ta())}):fetch(Qa,{credentials:"same-origin"}).then(function(a){if(!a.ok)throw"failed to load wasm binary file at '"+Qa+"'";return a.arrayBuffer()}).catch(function(){return Ta()})}
-var Va={1960:function(a,c,d,e,g,n,F,aa){a=b.getCache(b.ConcreteContactResultCallback)[a];if(!a.hasOwnProperty("addSingleResult"))throw"a JSImplementation must implement all functions, you forgot ConcreteContactResultCallback::addSingleResult.";return a.addSingleResult(c,d,e,g,n,F,aa)},2520:function(a,c,d,e){a=b.getCache(b.DebugDrawer)[a];if(!a.hasOwnProperty("drawLine"))throw"a JSImplementation must implement all functions, you forgot DebugDrawer::drawLine.";a.drawLine(c,d,e)},2745:function(a,c,d,
-e,g,n){a=b.getCache(b.DebugDrawer)[a];if(!a.hasOwnProperty("drawContactPoint"))throw"a JSImplementation must implement all functions, you forgot DebugDrawer::drawContactPoint.";a.drawContactPoint(c,d,e,g,n)},3002:function(a,c){a=b.getCache(b.DebugDrawer)[a];if(!a.hasOwnProperty("reportErrorWarning"))throw"a JSImplementation must implement all functions, you forgot DebugDrawer::reportErrorWarning.";a.reportErrorWarning(c)},3249:function(a,c,d){a=b.getCache(b.DebugDrawer)[a];if(!a.hasOwnProperty("draw3dText"))throw"a JSImplementation must implement all functions, you forgot DebugDrawer::draw3dText.";
-a.draw3dText(c,d)},3476:function(a,c){a=b.getCache(b.DebugDrawer)[a];if(!a.hasOwnProperty("setDebugMode"))throw"a JSImplementation must implement all functions, you forgot DebugDrawer::setDebugMode.";a.setDebugMode(c)},3705:function(a){a=b.getCache(b.DebugDrawer)[a];if(!a.hasOwnProperty("getDebugMode"))throw"a JSImplementation must implement all functions, you forgot DebugDrawer::getDebugMode.";return a.getDebugMode()}};Ha.push({Xy:function(){Wa()}});var Xa=[];
-function Ya(a,c){Xa.length=0;var d;for(c>>=2;d=za[a++];)Xa.push(105>d?Ca[++c>>1]:Aa[c]),++c;return Xa}var Za={f:function(){oa()},c:function(a,c,d){c=Ya(c,d);return Va[a].apply(null,c)},a:function(a,c,d){c=Ya(c,d);return Va[a].apply(null,c)},d:function(a,c,d){za.copyWithin(a,c,c+d)},e:function(){oa("OOM")},b:function(a){var c=Date.now();Aa[a>>2]=c/1E3|0;Aa[a+4>>2]=c%1E3*1E3|0;return 0},memory:sa,table:ua};
-(function(){function a(g){b.asm=g.exports;Ma--;b.monitorRunDependencies&&b.monitorRunDependencies(Ma);0==Ma&&(null!==Na&&(clearInterval(Na),Na=null),Oa&&(g=Oa,Oa=null,g()))}function c(g){a(g.instance)}function d(g){return Ua().then(function(n){return WebAssembly.instantiate(n,e)}).then(g,function(n){qa("failed to asynchronously prepare wasm: "+n);oa(n)})}var e={a:Za};Ma++;b.monitorRunDependencies&&b.monitorRunDependencies(Ma);if(b.instantiateWasm)try{return b.instantiateWasm(e,a)}catch(g){return qa("Module.instantiateWasm callback failed with error: "+
-g),!1}(function(){if(ra||"function"!==typeof WebAssembly.instantiateStreaming||Ra()||Pa("file://")||"function"!==typeof fetch)return d(c);fetch(Qa,{credentials:"same-origin"}).then(function(g){return WebAssembly.instantiateStreaming(g,e).then(c,function(n){qa("wasm streaming compile failed: "+n);qa("falling back to ArrayBuffer instantiation");return d(c)})})})();return{}})();var Wa=b.___wasm_call_ctors=function(){return(Wa=b.___wasm_call_ctors=b.asm.g).apply(null,arguments)};
-b.___em_js__array_bounds_check_error=function(){return(b.___em_js__array_bounds_check_error=b.asm.h).apply(null,arguments)};
-var $a=b._emscripten_bind_btCollisionWorld_getDispatcher_0=function(){return($a=b._emscripten_bind_btCollisionWorld_getDispatcher_0=b.asm.i).apply(null,arguments)},ab=b._emscripten_bind_btCollisionWorld_rayTest_3=function(){return(ab=b._emscripten_bind_btCollisionWorld_rayTest_3=b.asm.j).apply(null,arguments)},bb=b._emscripten_bind_btCollisionWorld_getPairCache_0=function(){return(bb=b._emscripten_bind_btCollisionWorld_getPairCache_0=b.asm.k).apply(null,arguments)},cb=b._emscripten_bind_btCollisionWorld_getDispatchInfo_0=
-function(){return(cb=b._emscripten_bind_btCollisionWorld_getDispatchInfo_0=b.asm.l).apply(null,arguments)},db=b._emscripten_bind_btCollisionWorld_addCollisionObject_1=function(){return(db=b._emscripten_bind_btCollisionWorld_addCollisionObject_1=b.asm.m).apply(null,arguments)},eb=b._emscripten_bind_btCollisionWorld_addCollisionObject_2=function(){return(eb=b._emscripten_bind_btCollisionWorld_addCollisionObject_2=b.asm.n).apply(null,arguments)},fb=b._emscripten_bind_btCollisionWorld_addCollisionObject_3=
-function(){return(fb=b._emscripten_bind_btCollisionWorld_addCollisionObject_3=b.asm.o).apply(null,arguments)},gb=b._emscripten_bind_btCollisionWorld_removeCollisionObject_1=function(){return(gb=b._emscripten_bind_btCollisionWorld_removeCollisionObject_1=b.asm.p).apply(null,arguments)},hb=b._emscripten_bind_btCollisionWorld_getBroadphase_0=function(){return(hb=b._emscripten_bind_btCollisionWorld_getBroadphase_0=b.asm.q).apply(null,arguments)},ib=b._emscripten_bind_btCollisionWorld_convexSweepTest_5=
-function(){return(ib=b._emscripten_bind_btCollisionWorld_convexSweepTest_5=b.asm.r).apply(null,arguments)},jb=b._emscripten_bind_btCollisionWorld_contactPairTest_3=function(){return(jb=b._emscripten_bind_btCollisionWorld_contactPairTest_3=b.asm.s).apply(null,arguments)},kb=b._emscripten_bind_btCollisionWorld_contactTest_2=function(){return(kb=b._emscripten_bind_btCollisionWorld_contactTest_2=b.asm.t).apply(null,arguments)},lb=b._emscripten_bind_btCollisionWorld_updateSingleAabb_1=function(){return(lb=
-b._emscripten_bind_btCollisionWorld_updateSingleAabb_1=b.asm.u).apply(null,arguments)},mb=b._emscripten_bind_btCollisionWorld_setDebugDrawer_1=function(){return(mb=b._emscripten_bind_btCollisionWorld_setDebugDrawer_1=b.asm.v).apply(null,arguments)},nb=b._emscripten_bind_btCollisionWorld_getDebugDrawer_0=function(){return(nb=b._emscripten_bind_btCollisionWorld_getDebugDrawer_0=b.asm.w).apply(null,arguments)},ob=b._emscripten_bind_btCollisionWorld_debugDrawWorld_0=function(){return(ob=b._emscripten_bind_btCollisionWorld_debugDrawWorld_0=
-b.asm.x).apply(null,arguments)},pb=b._emscripten_bind_btCollisionWorld_debugDrawObject_3=function(){return(pb=b._emscripten_bind_btCollisionWorld_debugDrawObject_3=b.asm.y).apply(null,arguments)},qb=b._emscripten_bind_btCollisionWorld___destroy___0=function(){return(qb=b._emscripten_bind_btCollisionWorld___destroy___0=b.asm.z).apply(null,arguments)},rb=b._emscripten_bind_btCollisionShape_setLocalScaling_1=function(){return(rb=b._emscripten_bind_btCollisionShape_setLocalScaling_1=b.asm.A).apply(null,
-arguments)},sb=b._emscripten_bind_btCollisionShape_getLocalScaling_0=function(){return(sb=b._emscripten_bind_btCollisionShape_getLocalScaling_0=b.asm.B).apply(null,arguments)},tb=b._emscripten_bind_btCollisionShape_calculateLocalInertia_2=function(){return(tb=b._emscripten_bind_btCollisionShape_calculateLocalInertia_2=b.asm.C).apply(null,arguments)},ub=b._emscripten_bind_btCollisionShape_setMargin_1=function(){return(ub=b._emscripten_bind_btCollisionShape_setMargin_1=b.asm.D).apply(null,arguments)},
-vb=b._emscripten_bind_btCollisionShape_getMargin_0=function(){return(vb=b._emscripten_bind_btCollisionShape_getMargin_0=b.asm.E).apply(null,arguments)},wb=b._emscripten_bind_btCollisionShape___destroy___0=function(){return(wb=b._emscripten_bind_btCollisionShape___destroy___0=b.asm.F).apply(null,arguments)},xb=b._emscripten_bind_btCollisionObject_setAnisotropicFriction_2=function(){return(xb=b._emscripten_bind_btCollisionObject_setAnisotropicFriction_2=b.asm.G).apply(null,arguments)},yb=b._emscripten_bind_btCollisionObject_getCollisionShape_0=
-function(){return(yb=b._emscripten_bind_btCollisionObject_getCollisionShape_0=b.asm.H).apply(null,arguments)},zb=b._emscripten_bind_btCollisionObject_setContactProcessingThreshold_1=function(){return(zb=b._emscripten_bind_btCollisionObject_setContactProcessingThreshold_1=b.asm.I).apply(null,arguments)},Ab=b._emscripten_bind_btCollisionObject_setActivationState_1=function(){return(Ab=b._emscripten_bind_btCollisionObject_setActivationState_1=b.asm.J).apply(null,arguments)},Bb=b._emscripten_bind_btCollisionObject_forceActivationState_1=
-function(){return(Bb=b._emscripten_bind_btCollisionObject_forceActivationState_1=b.asm.K).apply(null,arguments)},Cb=b._emscripten_bind_btCollisionObject_activate_0=function(){return(Cb=b._emscripten_bind_btCollisionObject_activate_0=b.asm.L).apply(null,arguments)},Db=b._emscripten_bind_btCollisionObject_activate_1=function(){return(Db=b._emscripten_bind_btCollisionObject_activate_1=b.asm.M).apply(null,arguments)},Eb=b._emscripten_bind_btCollisionObject_isActive_0=function(){return(Eb=b._emscripten_bind_btCollisionObject_isActive_0=
-b.asm.N).apply(null,arguments)},Fb=b._emscripten_bind_btCollisionObject_isKinematicObject_0=function(){return(Fb=b._emscripten_bind_btCollisionObject_isKinematicObject_0=b.asm.O).apply(null,arguments)},Gb=b._emscripten_bind_btCollisionObject_isStaticObject_0=function(){return(Gb=b._emscripten_bind_btCollisionObject_isStaticObject_0=b.asm.P).apply(null,arguments)},Hb=b._emscripten_bind_btCollisionObject_isStaticOrKinematicObject_0=function(){return(Hb=b._emscripten_bind_btCollisionObject_isStaticOrKinematicObject_0=
-b.asm.Q).apply(null,arguments)},Ib=b._emscripten_bind_btCollisionObject_getRestitution_0=function(){return(Ib=b._emscripten_bind_btCollisionObject_getRestitution_0=b.asm.R).apply(null,arguments)},Jb=b._emscripten_bind_btCollisionObject_getFriction_0=function(){return(Jb=b._emscripten_bind_btCollisionObject_getFriction_0=b.asm.S).apply(null,arguments)},Kb=b._emscripten_bind_btCollisionObject_getRollingFriction_0=function(){return(Kb=b._emscripten_bind_btCollisionObject_getRollingFriction_0=b.asm.T).apply(null,
-arguments)},Lb=b._emscripten_bind_btCollisionObject_setRestitution_1=function(){return(Lb=b._emscripten_bind_btCollisionObject_setRestitution_1=b.asm.U).apply(null,arguments)},Mb=b._emscripten_bind_btCollisionObject_setFriction_1=function(){return(Mb=b._emscripten_bind_btCollisionObject_setFriction_1=b.asm.V).apply(null,arguments)},Nb=b._emscripten_bind_btCollisionObject_setRollingFriction_1=function(){return(Nb=b._emscripten_bind_btCollisionObject_setRollingFriction_1=b.asm.W).apply(null,arguments)},
-Ob=b._emscripten_bind_btCollisionObject_getWorldTransform_0=function(){return(Ob=b._emscripten_bind_btCollisionObject_getWorldTransform_0=b.asm.X).apply(null,arguments)},Pb=b._emscripten_bind_btCollisionObject_getCollisionFlags_0=function(){return(Pb=b._emscripten_bind_btCollisionObject_getCollisionFlags_0=b.asm.Y).apply(null,arguments)},Qb=b._emscripten_bind_btCollisionObject_setCollisionFlags_1=function(){return(Qb=b._emscripten_bind_btCollisionObject_setCollisionFlags_1=b.asm.Z).apply(null,arguments)},
-Sb=b._emscripten_bind_btCollisionObject_setWorldTransform_1=function(){return(Sb=b._emscripten_bind_btCollisionObject_setWorldTransform_1=b.asm._).apply(null,arguments)},Tb=b._emscripten_bind_btCollisionObject_setCollisionShape_1=function(){return(Tb=b._emscripten_bind_btCollisionObject_setCollisionShape_1=b.asm.$).apply(null,arguments)},Ub=b._emscripten_bind_btCollisionObject_setCcdMotionThreshold_1=function(){return(Ub=b._emscripten_bind_btCollisionObject_setCcdMotionThreshold_1=b.asm.aa).apply(null,
-arguments)},Vb=b._emscripten_bind_btCollisionObject_setCcdSweptSphereRadius_1=function(){return(Vb=b._emscripten_bind_btCollisionObject_setCcdSweptSphereRadius_1=b.asm.ba).apply(null,arguments)},Wb=b._emscripten_bind_btCollisionObject_getUserIndex_0=function(){return(Wb=b._emscripten_bind_btCollisionObject_getUserIndex_0=b.asm.ca).apply(null,arguments)},Xb=b._emscripten_bind_btCollisionObject_setUserIndex_1=function(){return(Xb=b._emscripten_bind_btCollisionObject_setUserIndex_1=b.asm.da).apply(null,
-arguments)},Yb=b._emscripten_bind_btCollisionObject_getUserPointer_0=function(){return(Yb=b._emscripten_bind_btCollisionObject_getUserPointer_0=b.asm.ea).apply(null,arguments)},Zb=b._emscripten_bind_btCollisionObject_setUserPointer_1=function(){return(Zb=b._emscripten_bind_btCollisionObject_setUserPointer_1=b.asm.fa).apply(null,arguments)},$b=b._emscripten_bind_btCollisionObject_getBroadphaseHandle_0=function(){return($b=b._emscripten_bind_btCollisionObject_getBroadphaseHandle_0=b.asm.ga).apply(null,
-arguments)},ac=b._emscripten_bind_btCollisionObject___destroy___0=function(){return(ac=b._emscripten_bind_btCollisionObject___destroy___0=b.asm.ha).apply(null,arguments)},bc=b._emscripten_bind_btDynamicsWorld_addAction_1=function(){return(bc=b._emscripten_bind_btDynamicsWorld_addAction_1=b.asm.ia).apply(null,arguments)},cc=b._emscripten_bind_btDynamicsWorld_removeAction_1=function(){return(cc=b._emscripten_bind_btDynamicsWorld_removeAction_1=b.asm.ja).apply(null,arguments)},dc=b._emscripten_bind_btDynamicsWorld_getSolverInfo_0=
-function(){return(dc=b._emscripten_bind_btDynamicsWorld_getSolverInfo_0=b.asm.ka).apply(null,arguments)},ec=b._emscripten_bind_btDynamicsWorld_setInternalTickCallback_1=function(){return(ec=b._emscripten_bind_btDynamicsWorld_setInternalTickCallback_1=b.asm.la).apply(null,arguments)},fc=b._emscripten_bind_btDynamicsWorld_setInternalTickCallback_2=function(){return(fc=b._emscripten_bind_btDynamicsWorld_setInternalTickCallback_2=b.asm.ma).apply(null,arguments)},hc=b._emscripten_bind_btDynamicsWorld_setInternalTickCallback_3=
-function(){return(hc=b._emscripten_bind_btDynamicsWorld_setInternalTickCallback_3=b.asm.na).apply(null,arguments)},ic=b._emscripten_bind_btDynamicsWorld_getDispatcher_0=function(){return(ic=b._emscripten_bind_btDynamicsWorld_getDispatcher_0=b.asm.oa).apply(null,arguments)},jc=b._emscripten_bind_btDynamicsWorld_rayTest_3=function(){return(jc=b._emscripten_bind_btDynamicsWorld_rayTest_3=b.asm.pa).apply(null,arguments)},kc=b._emscripten_bind_btDynamicsWorld_getPairCache_0=function(){return(kc=b._emscripten_bind_btDynamicsWorld_getPairCache_0=
-b.asm.qa).apply(null,arguments)},lc=b._emscripten_bind_btDynamicsWorld_getDispatchInfo_0=function(){return(lc=b._emscripten_bind_btDynamicsWorld_getDispatchInfo_0=b.asm.ra).apply(null,arguments)},mc=b._emscripten_bind_btDynamicsWorld_addCollisionObject_1=function(){return(mc=b._emscripten_bind_btDynamicsWorld_addCollisionObject_1=b.asm.sa).apply(null,arguments)},nc=b._emscripten_bind_btDynamicsWorld_addCollisionObject_2=function(){return(nc=b._emscripten_bind_btDynamicsWorld_addCollisionObject_2=
-b.asm.ta).apply(null,arguments)},oc=b._emscripten_bind_btDynamicsWorld_addCollisionObject_3=function(){return(oc=b._emscripten_bind_btDynamicsWorld_addCollisionObject_3=b.asm.ua).apply(null,arguments)},pc=b._emscripten_bind_btDynamicsWorld_removeCollisionObject_1=function(){return(pc=b._emscripten_bind_btDynamicsWorld_removeCollisionObject_1=b.asm.va).apply(null,arguments)},qc=b._emscripten_bind_btDynamicsWorld_getBroadphase_0=function(){return(qc=b._emscripten_bind_btDynamicsWorld_getBroadphase_0=
-b.asm.wa).apply(null,arguments)},rc=b._emscripten_bind_btDynamicsWorld_convexSweepTest_5=function(){return(rc=b._emscripten_bind_btDynamicsWorld_convexSweepTest_5=b.asm.xa).apply(null,arguments)},sc=b._emscripten_bind_btDynamicsWorld_contactPairTest_3=function(){return(sc=b._emscripten_bind_btDynamicsWorld_contactPairTest_3=b.asm.ya).apply(null,arguments)},tc=b._emscripten_bind_btDynamicsWorld_contactTest_2=function(){return(tc=b._emscripten_bind_btDynamicsWorld_contactTest_2=b.asm.za).apply(null,
-arguments)},uc=b._emscripten_bind_btDynamicsWorld_updateSingleAabb_1=function(){return(uc=b._emscripten_bind_btDynamicsWorld_updateSingleAabb_1=b.asm.Aa).apply(null,arguments)},vc=b._emscripten_bind_btDynamicsWorld_setDebugDrawer_1=function(){return(vc=b._emscripten_bind_btDynamicsWorld_setDebugDrawer_1=b.asm.Ba).apply(null,arguments)},wc=b._emscripten_bind_btDynamicsWorld_getDebugDrawer_0=function(){return(wc=b._emscripten_bind_btDynamicsWorld_getDebugDrawer_0=b.asm.Ca).apply(null,arguments)},xc=
-b._emscripten_bind_btDynamicsWorld_debugDrawWorld_0=function(){return(xc=b._emscripten_bind_btDynamicsWorld_debugDrawWorld_0=b.asm.Da).apply(null,arguments)},yc=b._emscripten_bind_btDynamicsWorld_debugDrawObject_3=function(){return(yc=b._emscripten_bind_btDynamicsWorld_debugDrawObject_3=b.asm.Ea).apply(null,arguments)},zc=b._emscripten_bind_btDynamicsWorld___destroy___0=function(){return(zc=b._emscripten_bind_btDynamicsWorld___destroy___0=b.asm.Fa).apply(null,arguments)},Ac=b._emscripten_bind_btTypedConstraint_enableFeedback_1=
-function(){return(Ac=b._emscripten_bind_btTypedConstraint_enableFeedback_1=b.asm.Ga).apply(null,arguments)},Bc=b._emscripten_bind_btTypedConstraint_getBreakingImpulseThreshold_0=function(){return(Bc=b._emscripten_bind_btTypedConstraint_getBreakingImpulseThreshold_0=b.asm.Ha).apply(null,arguments)},Cc=b._emscripten_bind_btTypedConstraint_setBreakingImpulseThreshold_1=function(){return(Cc=b._emscripten_bind_btTypedConstraint_setBreakingImpulseThreshold_1=b.asm.Ia).apply(null,arguments)},Dc=b._emscripten_bind_btTypedConstraint_getParam_2=
-function(){return(Dc=b._emscripten_bind_btTypedConstraint_getParam_2=b.asm.Ja).apply(null,arguments)},Ec=b._emscripten_bind_btTypedConstraint_setParam_3=function(){return(Ec=b._emscripten_bind_btTypedConstraint_setParam_3=b.asm.Ka).apply(null,arguments)},Fc=b._emscripten_bind_btTypedConstraint___destroy___0=function(){return(Fc=b._emscripten_bind_btTypedConstraint___destroy___0=b.asm.La).apply(null,arguments)},Gc=b._emscripten_bind_btConcaveShape_setLocalScaling_1=function(){return(Gc=b._emscripten_bind_btConcaveShape_setLocalScaling_1=
-b.asm.Ma).apply(null,arguments)},Hc=b._emscripten_bind_btConcaveShape_getLocalScaling_0=function(){return(Hc=b._emscripten_bind_btConcaveShape_getLocalScaling_0=b.asm.Na).apply(null,arguments)},Ic=b._emscripten_bind_btConcaveShape_calculateLocalInertia_2=function(){return(Ic=b._emscripten_bind_btConcaveShape_calculateLocalInertia_2=b.asm.Oa).apply(null,arguments)},Jc=b._emscripten_bind_btConcaveShape___destroy___0=function(){return(Jc=b._emscripten_bind_btConcaveShape___destroy___0=b.asm.Pa).apply(null,
-arguments)},Kc=b._emscripten_bind_btCapsuleShape_btCapsuleShape_2=function(){return(Kc=b._emscripten_bind_btCapsuleShape_btCapsuleShape_2=b.asm.Qa).apply(null,arguments)},Lc=b._emscripten_bind_btCapsuleShape_setMargin_1=function(){return(Lc=b._emscripten_bind_btCapsuleShape_setMargin_1=b.asm.Ra).apply(null,arguments)},Mc=b._emscripten_bind_btCapsuleShape_getMargin_0=function(){return(Mc=b._emscripten_bind_btCapsuleShape_getMargin_0=b.asm.Sa).apply(null,arguments)},Nc=b._emscripten_bind_btCapsuleShape_getUpAxis_0=
-function(){return(Nc=b._emscripten_bind_btCapsuleShape_getUpAxis_0=b.asm.Ta).apply(null,arguments)},Oc=b._emscripten_bind_btCapsuleShape_getRadius_0=function(){return(Oc=b._emscripten_bind_btCapsuleShape_getRadius_0=b.asm.Ua).apply(null,arguments)},Pc=b._emscripten_bind_btCapsuleShape_getHalfHeight_0=function(){return(Pc=b._emscripten_bind_btCapsuleShape_getHalfHeight_0=b.asm.Va).apply(null,arguments)},Qc=b._emscripten_bind_btCapsuleShape_setLocalScaling_1=function(){return(Qc=b._emscripten_bind_btCapsuleShape_setLocalScaling_1=
-b.asm.Wa).apply(null,arguments)},Rc=b._emscripten_bind_btCapsuleShape_getLocalScaling_0=function(){return(Rc=b._emscripten_bind_btCapsuleShape_getLocalScaling_0=b.asm.Xa).apply(null,arguments)},Sc=b._emscripten_bind_btCapsuleShape_calculateLocalInertia_2=function(){return(Sc=b._emscripten_bind_btCapsuleShape_calculateLocalInertia_2=b.asm.Ya).apply(null,arguments)},Tc=b._emscripten_bind_btCapsuleShape___destroy___0=function(){return(Tc=b._emscripten_bind_btCapsuleShape___destroy___0=b.asm.Za).apply(null,
-arguments)},Uc=b._emscripten_bind_btIDebugDraw_drawLine_3=function(){return(Uc=b._emscripten_bind_btIDebugDraw_drawLine_3=b.asm._a).apply(null,arguments)},Vc=b._emscripten_bind_btIDebugDraw_drawContactPoint_5=function(){return(Vc=b._emscripten_bind_btIDebugDraw_drawContactPoint_5=b.asm.$a).apply(null,arguments)},Wc=b._emscripten_bind_btIDebugDraw_reportErrorWarning_1=function(){return(Wc=b._emscripten_bind_btIDebugDraw_reportErrorWarning_1=b.asm.ab).apply(null,arguments)},Xc=b._emscripten_bind_btIDebugDraw_draw3dText_2=
-function(){return(Xc=b._emscripten_bind_btIDebugDraw_draw3dText_2=b.asm.bb).apply(null,arguments)},Yc=b._emscripten_bind_btIDebugDraw_setDebugMode_1=function(){return(Yc=b._emscripten_bind_btIDebugDraw_setDebugMode_1=b.asm.cb).apply(null,arguments)},Zc=b._emscripten_bind_btIDebugDraw_getDebugMode_0=function(){return(Zc=b._emscripten_bind_btIDebugDraw_getDebugMode_0=b.asm.db).apply(null,arguments)},$c=b._emscripten_bind_btIDebugDraw___destroy___0=function(){return($c=b._emscripten_bind_btIDebugDraw___destroy___0=
-b.asm.eb).apply(null,arguments)},ad=b._emscripten_bind_btDefaultCollisionConfiguration_btDefaultCollisionConfiguration_0=function(){return(ad=b._emscripten_bind_btDefaultCollisionConfiguration_btDefaultCollisionConfiguration_0=b.asm.fb).apply(null,arguments)},bd=b._emscripten_bind_btDefaultCollisionConfiguration_btDefaultCollisionConfiguration_1=function(){return(bd=b._emscripten_bind_btDefaultCollisionConfiguration_btDefaultCollisionConfiguration_1=b.asm.gb).apply(null,arguments)},cd=b._emscripten_bind_btDefaultCollisionConfiguration___destroy___0=
-function(){return(cd=b._emscripten_bind_btDefaultCollisionConfiguration___destroy___0=b.asm.hb).apply(null,arguments)},dd=b._emscripten_bind_btTriangleMeshShape_setLocalScaling_1=function(){return(dd=b._emscripten_bind_btTriangleMeshShape_setLocalScaling_1=b.asm.ib).apply(null,arguments)},ed=b._emscripten_bind_btTriangleMeshShape_getLocalScaling_0=function(){return(ed=b._emscripten_bind_btTriangleMeshShape_getLocalScaling_0=b.asm.jb).apply(null,arguments)},fd=b._emscripten_bind_btTriangleMeshShape_calculateLocalInertia_2=
-function(){return(fd=b._emscripten_bind_btTriangleMeshShape_calculateLocalInertia_2=b.asm.kb).apply(null,arguments)},gd=b._emscripten_bind_btTriangleMeshShape___destroy___0=function(){return(gd=b._emscripten_bind_btTriangleMeshShape___destroy___0=b.asm.lb).apply(null,arguments)},hd=b._emscripten_bind_btGhostObject_btGhostObject_0=function(){return(hd=b._emscripten_bind_btGhostObject_btGhostObject_0=b.asm.mb).apply(null,arguments)},id=b._emscripten_bind_btGhostObject_getNumOverlappingObjects_0=function(){return(id=
-b._emscripten_bind_btGhostObject_getNumOverlappingObjects_0=b.asm.nb).apply(null,arguments)},jd=b._emscripten_bind_btGhostObject_getOverlappingObject_1=function(){return(jd=b._emscripten_bind_btGhostObject_getOverlappingObject_1=b.asm.ob).apply(null,arguments)},kd=b._emscripten_bind_btGhostObject_setAnisotropicFriction_2=function(){return(kd=b._emscripten_bind_btGhostObject_setAnisotropicFriction_2=b.asm.pb).apply(null,arguments)},ld=b._emscripten_bind_btGhostObject_getCollisionShape_0=function(){return(ld=
-b._emscripten_bind_btGhostObject_getCollisionShape_0=b.asm.qb).apply(null,arguments)},md=b._emscripten_bind_btGhostObject_setContactProcessingThreshold_1=function(){return(md=b._emscripten_bind_btGhostObject_setContactProcessingThreshold_1=b.asm.rb).apply(null,arguments)},nd=b._emscripten_bind_btGhostObject_setActivationState_1=function(){return(nd=b._emscripten_bind_btGhostObject_setActivationState_1=b.asm.sb).apply(null,arguments)},od=b._emscripten_bind_btGhostObject_forceActivationState_1=function(){return(od=
-b._emscripten_bind_btGhostObject_forceActivationState_1=b.asm.tb).apply(null,arguments)},pd=b._emscripten_bind_btGhostObject_activate_0=function(){return(pd=b._emscripten_bind_btGhostObject_activate_0=b.asm.ub).apply(null,arguments)},qd=b._emscripten_bind_btGhostObject_activate_1=function(){return(qd=b._emscripten_bind_btGhostObject_activate_1=b.asm.vb).apply(null,arguments)},rd=b._emscripten_bind_btGhostObject_isActive_0=function(){return(rd=b._emscripten_bind_btGhostObject_isActive_0=b.asm.wb).apply(null,
-arguments)},sd=b._emscripten_bind_btGhostObject_isKinematicObject_0=function(){return(sd=b._emscripten_bind_btGhostObject_isKinematicObject_0=b.asm.xb).apply(null,arguments)},td=b._emscripten_bind_btGhostObject_isStaticObject_0=function(){return(td=b._emscripten_bind_btGhostObject_isStaticObject_0=b.asm.yb).apply(null,arguments)},ud=b._emscripten_bind_btGhostObject_isStaticOrKinematicObject_0=function(){return(ud=b._emscripten_bind_btGhostObject_isStaticOrKinematicObject_0=b.asm.zb).apply(null,arguments)},
-vd=b._emscripten_bind_btGhostObject_getRestitution_0=function(){return(vd=b._emscripten_bind_btGhostObject_getRestitution_0=b.asm.Ab).apply(null,arguments)},wd=b._emscripten_bind_btGhostObject_getFriction_0=function(){return(wd=b._emscripten_bind_btGhostObject_getFriction_0=b.asm.Bb).apply(null,arguments)},xd=b._emscripten_bind_btGhostObject_getRollingFriction_0=function(){return(xd=b._emscripten_bind_btGhostObject_getRollingFriction_0=b.asm.Cb).apply(null,arguments)},yd=b._emscripten_bind_btGhostObject_setRestitution_1=
-function(){return(yd=b._emscripten_bind_btGhostObject_setRestitution_1=b.asm.Db).apply(null,arguments)},zd=b._emscripten_bind_btGhostObject_setFriction_1=function(){return(zd=b._emscripten_bind_btGhostObject_setFriction_1=b.asm.Eb).apply(null,arguments)},Ad=b._emscripten_bind_btGhostObject_setRollingFriction_1=function(){return(Ad=b._emscripten_bind_btGhostObject_setRollingFriction_1=b.asm.Fb).apply(null,arguments)},Bd=b._emscripten_bind_btGhostObject_getWorldTransform_0=function(){return(Bd=b._emscripten_bind_btGhostObject_getWorldTransform_0=
-b.asm.Gb).apply(null,arguments)},Cd=b._emscripten_bind_btGhostObject_getCollisionFlags_0=function(){return(Cd=b._emscripten_bind_btGhostObject_getCollisionFlags_0=b.asm.Hb).apply(null,arguments)},Dd=b._emscripten_bind_btGhostObject_setCollisionFlags_1=function(){return(Dd=b._emscripten_bind_btGhostObject_setCollisionFlags_1=b.asm.Ib).apply(null,arguments)},Ed=b._emscripten_bind_btGhostObject_setWorldTransform_1=function(){return(Ed=b._emscripten_bind_btGhostObject_setWorldTransform_1=b.asm.Jb).apply(null,
-arguments)},Fd=b._emscripten_bind_btGhostObject_setCollisionShape_1=function(){return(Fd=b._emscripten_bind_btGhostObject_setCollisionShape_1=b.asm.Kb).apply(null,arguments)},Gd=b._emscripten_bind_btGhostObject_setCcdMotionThreshold_1=function(){return(Gd=b._emscripten_bind_btGhostObject_setCcdMotionThreshold_1=b.asm.Lb).apply(null,arguments)},Hd=b._emscripten_bind_btGhostObject_setCcdSweptSphereRadius_1=function(){return(Hd=b._emscripten_bind_btGhostObject_setCcdSweptSphereRadius_1=b.asm.Mb).apply(null,
-arguments)},Id=b._emscripten_bind_btGhostObject_getUserIndex_0=function(){return(Id=b._emscripten_bind_btGhostObject_getUserIndex_0=b.asm.Nb).apply(null,arguments)},Jd=b._emscripten_bind_btGhostObject_setUserIndex_1=function(){return(Jd=b._emscripten_bind_btGhostObject_setUserIndex_1=b.asm.Ob).apply(null,arguments)},Kd=b._emscripten_bind_btGhostObject_getUserPointer_0=function(){return(Kd=b._emscripten_bind_btGhostObject_getUserPointer_0=b.asm.Pb).apply(null,arguments)},Ld=b._emscripten_bind_btGhostObject_setUserPointer_1=
-function(){return(Ld=b._emscripten_bind_btGhostObject_setUserPointer_1=b.asm.Qb).apply(null,arguments)},Md=b._emscripten_bind_btGhostObject_getBroadphaseHandle_0=function(){return(Md=b._emscripten_bind_btGhostObject_getBroadphaseHandle_0=b.asm.Rb).apply(null,arguments)},Nd=b._emscripten_bind_btGhostObject___destroy___0=function(){return(Nd=b._emscripten_bind_btGhostObject___destroy___0=b.asm.Sb).apply(null,arguments)},Od=b._emscripten_bind_btConeShape_btConeShape_2=function(){return(Od=b._emscripten_bind_btConeShape_btConeShape_2=
-b.asm.Tb).apply(null,arguments)},Pd=b._emscripten_bind_btConeShape_setLocalScaling_1=function(){return(Pd=b._emscripten_bind_btConeShape_setLocalScaling_1=b.asm.Ub).apply(null,arguments)},Qd=b._emscripten_bind_btConeShape_getLocalScaling_0=function(){return(Qd=b._emscripten_bind_btConeShape_getLocalScaling_0=b.asm.Vb).apply(null,arguments)},Rd=b._emscripten_bind_btConeShape_calculateLocalInertia_2=function(){return(Rd=b._emscripten_bind_btConeShape_calculateLocalInertia_2=b.asm.Wb).apply(null,arguments)},
-Sd=b._emscripten_bind_btConeShape___destroy___0=function(){return(Sd=b._emscripten_bind_btConeShape___destroy___0=b.asm.Xb).apply(null,arguments)},Td=b._emscripten_bind_btActionInterface_updateAction_2=function(){return(Td=b._emscripten_bind_btActionInterface_updateAction_2=b.asm.Yb).apply(null,arguments)},Ud=b._emscripten_bind_btActionInterface___destroy___0=function(){return(Ud=b._emscripten_bind_btActionInterface___destroy___0=b.asm.Zb).apply(null,arguments)},Vd=b._emscripten_bind_btVector3_btVector3_0=
-function(){return(Vd=b._emscripten_bind_btVector3_btVector3_0=b.asm._b).apply(null,arguments)},Wd=b._emscripten_bind_btVector3_btVector3_3=function(){return(Wd=b._emscripten_bind_btVector3_btVector3_3=b.asm.$b).apply(null,arguments)},Xd=b._emscripten_bind_btVector3_length_0=function(){return(Xd=b._emscripten_bind_btVector3_length_0=b.asm.ac).apply(null,arguments)},Yd=b._emscripten_bind_btVector3_x_0=function(){return(Yd=b._emscripten_bind_btVector3_x_0=b.asm.bc).apply(null,arguments)},Zd=b._emscripten_bind_btVector3_y_0=
-function(){return(Zd=b._emscripten_bind_btVector3_y_0=b.asm.cc).apply(null,arguments)},$d=b._emscripten_bind_btVector3_z_0=function(){return($d=b._emscripten_bind_btVector3_z_0=b.asm.dc).apply(null,arguments)},ae=b._emscripten_bind_btVector3_setX_1=function(){return(ae=b._emscripten_bind_btVector3_setX_1=b.asm.ec).apply(null,arguments)},be=b._emscripten_bind_btVector3_setY_1=function(){return(be=b._emscripten_bind_btVector3_setY_1=b.asm.fc).apply(null,arguments)},ce=b._emscripten_bind_btVector3_setZ_1=
-function(){return(ce=b._emscripten_bind_btVector3_setZ_1=b.asm.gc).apply(null,arguments)},de=b._emscripten_bind_btVector3_setValue_3=function(){return(de=b._emscripten_bind_btVector3_setValue_3=b.asm.hc).apply(null,arguments)},ee=b._emscripten_bind_btVector3_normalize_0=function(){return(ee=b._emscripten_bind_btVector3_normalize_0=b.asm.ic).apply(null,arguments)},fe=b._emscripten_bind_btVector3_rotate_2=function(){return(fe=b._emscripten_bind_btVector3_rotate_2=b.asm.jc).apply(null,arguments)},ge=
-b._emscripten_bind_btVector3_dot_1=function(){return(ge=b._emscripten_bind_btVector3_dot_1=b.asm.kc).apply(null,arguments)},he=b._emscripten_bind_btVector3_op_mul_1=function(){return(he=b._emscripten_bind_btVector3_op_mul_1=b.asm.lc).apply(null,arguments)},ie=b._emscripten_bind_btVector3_op_add_1=function(){return(ie=b._emscripten_bind_btVector3_op_add_1=b.asm.mc).apply(null,arguments)},je=b._emscripten_bind_btVector3_op_sub_1=function(){return(je=b._emscripten_bind_btVector3_op_sub_1=b.asm.nc).apply(null,
-arguments)},ke=b._emscripten_bind_btVector3___destroy___0=function(){return(ke=b._emscripten_bind_btVector3___destroy___0=b.asm.oc).apply(null,arguments)},le=b._emscripten_bind_btVehicleRaycaster_castRay_3=function(){return(le=b._emscripten_bind_btVehicleRaycaster_castRay_3=b.asm.pc).apply(null,arguments)},me=b._emscripten_bind_btVehicleRaycaster___destroy___0=function(){return(me=b._emscripten_bind_btVehicleRaycaster___destroy___0=b.asm.qc).apply(null,arguments)},ne=b._emscripten_bind_btQuadWord_x_0=
-function(){return(ne=b._emscripten_bind_btQuadWord_x_0=b.asm.rc).apply(null,arguments)},oe=b._emscripten_bind_btQuadWord_y_0=function(){return(oe=b._emscripten_bind_btQuadWord_y_0=b.asm.sc).apply(null,arguments)},pe=b._emscripten_bind_btQuadWord_z_0=function(){return(pe=b._emscripten_bind_btQuadWord_z_0=b.asm.tc).apply(null,arguments)},qe=b._emscripten_bind_btQuadWord_w_0=function(){return(qe=b._emscripten_bind_btQuadWord_w_0=b.asm.uc).apply(null,arguments)},re=b._emscripten_bind_btQuadWord_setX_1=
-function(){return(re=b._emscripten_bind_btQuadWord_setX_1=b.asm.vc).apply(null,arguments)},se=b._emscripten_bind_btQuadWord_setY_1=function(){return(se=b._emscripten_bind_btQuadWord_setY_1=b.asm.wc).apply(null,arguments)},te=b._emscripten_bind_btQuadWord_setZ_1=function(){return(te=b._emscripten_bind_btQuadWord_setZ_1=b.asm.xc).apply(null,arguments)},ue=b._emscripten_bind_btQuadWord_setW_1=function(){return(ue=b._emscripten_bind_btQuadWord_setW_1=b.asm.yc).apply(null,arguments)},ve=b._emscripten_bind_btQuadWord___destroy___0=
-function(){return(ve=b._emscripten_bind_btQuadWord___destroy___0=b.asm.zc).apply(null,arguments)},we=b._emscripten_bind_btCylinderShape_btCylinderShape_1=function(){return(we=b._emscripten_bind_btCylinderShape_btCylinderShape_1=b.asm.Ac).apply(null,arguments)},xe=b._emscripten_bind_btCylinderShape_setMargin_1=function(){return(xe=b._emscripten_bind_btCylinderShape_setMargin_1=b.asm.Bc).apply(null,arguments)},ye=b._emscripten_bind_btCylinderShape_getMargin_0=function(){return(ye=b._emscripten_bind_btCylinderShape_getMargin_0=
-b.asm.Cc).apply(null,arguments)},ze=b._emscripten_bind_btCylinderShape_setLocalScaling_1=function(){return(ze=b._emscripten_bind_btCylinderShape_setLocalScaling_1=b.asm.Dc).apply(null,arguments)},Ae=b._emscripten_bind_btCylinderShape_getLocalScaling_0=function(){return(Ae=b._emscripten_bind_btCylinderShape_getLocalScaling_0=b.asm.Ec).apply(null,arguments)},Be=b._emscripten_bind_btCylinderShape_calculateLocalInertia_2=function(){return(Be=b._emscripten_bind_btCylinderShape_calculateLocalInertia_2=
-b.asm.Fc).apply(null,arguments)},Ce=b._emscripten_bind_btCylinderShape___destroy___0=function(){return(Ce=b._emscripten_bind_btCylinderShape___destroy___0=b.asm.Gc).apply(null,arguments)},De=b._emscripten_bind_btDiscreteDynamicsWorld_btDiscreteDynamicsWorld_4=function(){return(De=b._emscripten_bind_btDiscreteDynamicsWorld_btDiscreteDynamicsWorld_4=b.asm.Hc).apply(null,arguments)},Ee=b._emscripten_bind_btDiscreteDynamicsWorld_setGravity_1=function(){return(Ee=b._emscripten_bind_btDiscreteDynamicsWorld_setGravity_1=
-b.asm.Ic).apply(null,arguments)},Fe=b._emscripten_bind_btDiscreteDynamicsWorld_getGravity_0=function(){return(Fe=b._emscripten_bind_btDiscreteDynamicsWorld_getGravity_0=b.asm.Jc).apply(null,arguments)},Ge=b._emscripten_bind_btDiscreteDynamicsWorld_addRigidBody_1=function(){return(Ge=b._emscripten_bind_btDiscreteDynamicsWorld_addRigidBody_1=b.asm.Kc).apply(null,arguments)},He=b._emscripten_bind_btDiscreteDynamicsWorld_addRigidBody_3=function(){return(He=b._emscripten_bind_btDiscreteDynamicsWorld_addRigidBody_3=
-b.asm.Lc).apply(null,arguments)},Ie=b._emscripten_bind_btDiscreteDynamicsWorld_removeRigidBody_1=function(){return(Ie=b._emscripten_bind_btDiscreteDynamicsWorld_removeRigidBody_1=b.asm.Mc).apply(null,arguments)},Je=b._emscripten_bind_btDiscreteDynamicsWorld_addConstraint_1=function(){return(Je=b._emscripten_bind_btDiscreteDynamicsWorld_addConstraint_1=b.asm.Nc).apply(null,arguments)},Ke=b._emscripten_bind_btDiscreteDynamicsWorld_addConstraint_2=function(){return(Ke=b._emscripten_bind_btDiscreteDynamicsWorld_addConstraint_2=
-b.asm.Oc).apply(null,arguments)},Le=b._emscripten_bind_btDiscreteDynamicsWorld_removeConstraint_1=function(){return(Le=b._emscripten_bind_btDiscreteDynamicsWorld_removeConstraint_1=b.asm.Pc).apply(null,arguments)},Me=b._emscripten_bind_btDiscreteDynamicsWorld_stepSimulation_1=function(){return(Me=b._emscripten_bind_btDiscreteDynamicsWorld_stepSimulation_1=b.asm.Qc).apply(null,arguments)},Ne=b._emscripten_bind_btDiscreteDynamicsWorld_stepSimulation_2=function(){return(Ne=b._emscripten_bind_btDiscreteDynamicsWorld_stepSimulation_2=
-b.asm.Rc).apply(null,arguments)},Oe=b._emscripten_bind_btDiscreteDynamicsWorld_stepSimulation_3=function(){return(Oe=b._emscripten_bind_btDiscreteDynamicsWorld_stepSimulation_3=b.asm.Sc).apply(null,arguments)},Pe=b._emscripten_bind_btDiscreteDynamicsWorld_setContactAddedCallback_1=function(){return(Pe=b._emscripten_bind_btDiscreteDynamicsWorld_setContactAddedCallback_1=b.asm.Tc).apply(null,arguments)},Qe=b._emscripten_bind_btDiscreteDynamicsWorld_setContactProcessedCallback_1=function(){return(Qe=
-b._emscripten_bind_btDiscreteDynamicsWorld_setContactProcessedCallback_1=b.asm.Uc).apply(null,arguments)},Re=b._emscripten_bind_btDiscreteDynamicsWorld_setContactDestroyedCallback_1=function(){return(Re=b._emscripten_bind_btDiscreteDynamicsWorld_setContactDestroyedCallback_1=b.asm.Vc).apply(null,arguments)},Se=b._emscripten_bind_btDiscreteDynamicsWorld_getDispatcher_0=function(){return(Se=b._emscripten_bind_btDiscreteDynamicsWorld_getDispatcher_0=b.asm.Wc).apply(null,arguments)},Te=b._emscripten_bind_btDiscreteDynamicsWorld_rayTest_3=
-function(){return(Te=b._emscripten_bind_btDiscreteDynamicsWorld_rayTest_3=b.asm.Xc).apply(null,arguments)},Ue=b._emscripten_bind_btDiscreteDynamicsWorld_getPairCache_0=function(){return(Ue=b._emscripten_bind_btDiscreteDynamicsWorld_getPairCache_0=b.asm.Yc).apply(null,arguments)},Ve=b._emscripten_bind_btDiscreteDynamicsWorld_getDispatchInfo_0=function(){return(Ve=b._emscripten_bind_btDiscreteDynamicsWorld_getDispatchInfo_0=b.asm.Zc).apply(null,arguments)},We=b._emscripten_bind_btDiscreteDynamicsWorld_addCollisionObject_1=
-function(){return(We=b._emscripten_bind_btDiscreteDynamicsWorld_addCollisionObject_1=b.asm._c).apply(null,arguments)},Xe=b._emscripten_bind_btDiscreteDynamicsWorld_addCollisionObject_2=function(){return(Xe=b._emscripten_bind_btDiscreteDynamicsWorld_addCollisionObject_2=b.asm.$c).apply(null,arguments)},Ye=b._emscripten_bind_btDiscreteDynamicsWorld_addCollisionObject_3=function(){return(Ye=b._emscripten_bind_btDiscreteDynamicsWorld_addCollisionObject_3=b.asm.ad).apply(null,arguments)},Ze=b._emscripten_bind_btDiscreteDynamicsWorld_removeCollisionObject_1=
-function(){return(Ze=b._emscripten_bind_btDiscreteDynamicsWorld_removeCollisionObject_1=b.asm.bd).apply(null,arguments)},$e=b._emscripten_bind_btDiscreteDynamicsWorld_getBroadphase_0=function(){return($e=b._emscripten_bind_btDiscreteDynamicsWorld_getBroadphase_0=b.asm.cd).apply(null,arguments)},af=b._emscripten_bind_btDiscreteDynamicsWorld_convexSweepTest_5=function(){return(af=b._emscripten_bind_btDiscreteDynamicsWorld_convexSweepTest_5=b.asm.dd).apply(null,arguments)},bf=b._emscripten_bind_btDiscreteDynamicsWorld_contactPairTest_3=
-function(){return(bf=b._emscripten_bind_btDiscreteDynamicsWorld_contactPairTest_3=b.asm.ed).apply(null,arguments)},cf=b._emscripten_bind_btDiscreteDynamicsWorld_contactTest_2=function(){return(cf=b._emscripten_bind_btDiscreteDynamicsWorld_contactTest_2=b.asm.fd).apply(null,arguments)},df=b._emscripten_bind_btDiscreteDynamicsWorld_updateSingleAabb_1=function(){return(df=b._emscripten_bind_btDiscreteDynamicsWorld_updateSingleAabb_1=b.asm.gd).apply(null,arguments)},ef=b._emscripten_bind_btDiscreteDynamicsWorld_setDebugDrawer_1=
-function(){return(ef=b._emscripten_bind_btDiscreteDynamicsWorld_setDebugDrawer_1=b.asm.hd).apply(null,arguments)},ff=b._emscripten_bind_btDiscreteDynamicsWorld_getDebugDrawer_0=function(){return(ff=b._emscripten_bind_btDiscreteDynamicsWorld_getDebugDrawer_0=b.asm.id).apply(null,arguments)},gf=b._emscripten_bind_btDiscreteDynamicsWorld_debugDrawWorld_0=function(){return(gf=b._emscripten_bind_btDiscreteDynamicsWorld_debugDrawWorld_0=b.asm.jd).apply(null,arguments)},hf=b._emscripten_bind_btDiscreteDynamicsWorld_debugDrawObject_3=
-function(){return(hf=b._emscripten_bind_btDiscreteDynamicsWorld_debugDrawObject_3=b.asm.kd).apply(null,arguments)},jf=b._emscripten_bind_btDiscreteDynamicsWorld_addAction_1=function(){return(jf=b._emscripten_bind_btDiscreteDynamicsWorld_addAction_1=b.asm.ld).apply(null,arguments)},kf=b._emscripten_bind_btDiscreteDynamicsWorld_removeAction_1=function(){return(kf=b._emscripten_bind_btDiscreteDynamicsWorld_removeAction_1=b.asm.md).apply(null,arguments)},lf=b._emscripten_bind_btDiscreteDynamicsWorld_getSolverInfo_0=
-function(){return(lf=b._emscripten_bind_btDiscreteDynamicsWorld_getSolverInfo_0=b.asm.nd).apply(null,arguments)},mf=b._emscripten_bind_btDiscreteDynamicsWorld_setInternalTickCallback_1=function(){return(mf=b._emscripten_bind_btDiscreteDynamicsWorld_setInternalTickCallback_1=b.asm.od).apply(null,arguments)},nf=b._emscripten_bind_btDiscreteDynamicsWorld_setInternalTickCallback_2=function(){return(nf=b._emscripten_bind_btDiscreteDynamicsWorld_setInternalTickCallback_2=b.asm.pd).apply(null,arguments)},
-of=b._emscripten_bind_btDiscreteDynamicsWorld_setInternalTickCallback_3=function(){return(of=b._emscripten_bind_btDiscreteDynamicsWorld_setInternalTickCallback_3=b.asm.qd).apply(null,arguments)},pf=b._emscripten_bind_btDiscreteDynamicsWorld___destroy___0=function(){return(pf=b._emscripten_bind_btDiscreteDynamicsWorld___destroy___0=b.asm.rd).apply(null,arguments)},qf=b._emscripten_bind_btConvexShape_setLocalScaling_1=function(){return(qf=b._emscripten_bind_btConvexShape_setLocalScaling_1=b.asm.sd).apply(null,
-arguments)},rf=b._emscripten_bind_btConvexShape_getLocalScaling_0=function(){return(rf=b._emscripten_bind_btConvexShape_getLocalScaling_0=b.asm.td).apply(null,arguments)},sf=b._emscripten_bind_btConvexShape_calculateLocalInertia_2=function(){return(sf=b._emscripten_bind_btConvexShape_calculateLocalInertia_2=b.asm.ud).apply(null,arguments)},tf=b._emscripten_bind_btConvexShape_setMargin_1=function(){return(tf=b._emscripten_bind_btConvexShape_setMargin_1=b.asm.vd).apply(null,arguments)},uf=b._emscripten_bind_btConvexShape_getMargin_0=
-function(){return(uf=b._emscripten_bind_btConvexShape_getMargin_0=b.asm.wd).apply(null,arguments)},vf=b._emscripten_bind_btConvexShape___destroy___0=function(){return(vf=b._emscripten_bind_btConvexShape___destroy___0=b.asm.xd).apply(null,arguments)},wf=b._emscripten_bind_btDispatcher_getNumManifolds_0=function(){return(wf=b._emscripten_bind_btDispatcher_getNumManifolds_0=b.asm.yd).apply(null,arguments)},xf=b._emscripten_bind_btDispatcher_getManifoldByIndexInternal_1=function(){return(xf=b._emscripten_bind_btDispatcher_getManifoldByIndexInternal_1=
-b.asm.zd).apply(null,arguments)},yf=b._emscripten_bind_btDispatcher___destroy___0=function(){return(yf=b._emscripten_bind_btDispatcher___destroy___0=b.asm.Ad).apply(null,arguments)},zf=b._emscripten_bind_btGeneric6DofConstraint_btGeneric6DofConstraint_3=function(){return(zf=b._emscripten_bind_btGeneric6DofConstraint_btGeneric6DofConstraint_3=b.asm.Bd).apply(null,arguments)},Af=b._emscripten_bind_btGeneric6DofConstraint_btGeneric6DofConstraint_5=function(){return(Af=b._emscripten_bind_btGeneric6DofConstraint_btGeneric6DofConstraint_5=
-b.asm.Cd).apply(null,arguments)},Bf=b._emscripten_bind_btGeneric6DofConstraint_setLinearLowerLimit_1=function(){return(Bf=b._emscripten_bind_btGeneric6DofConstraint_setLinearLowerLimit_1=b.asm.Dd).apply(null,arguments)},Cf=b._emscripten_bind_btGeneric6DofConstraint_setLinearUpperLimit_1=function(){return(Cf=b._emscripten_bind_btGeneric6DofConstraint_setLinearUpperLimit_1=b.asm.Ed).apply(null,arguments)},Df=b._emscripten_bind_btGeneric6DofConstraint_setAngularLowerLimit_1=function(){return(Df=b._emscripten_bind_btGeneric6DofConstraint_setAngularLowerLimit_1=
-b.asm.Fd).apply(null,arguments)},Ef=b._emscripten_bind_btGeneric6DofConstraint_setAngularUpperLimit_1=function(){return(Ef=b._emscripten_bind_btGeneric6DofConstraint_setAngularUpperLimit_1=b.asm.Gd).apply(null,arguments)},Ff=b._emscripten_bind_btGeneric6DofConstraint_getFrameOffsetA_0=function(){return(Ff=b._emscripten_bind_btGeneric6DofConstraint_getFrameOffsetA_0=b.asm.Hd).apply(null,arguments)},Gf=b._emscripten_bind_btGeneric6DofConstraint_enableFeedback_1=function(){return(Gf=b._emscripten_bind_btGeneric6DofConstraint_enableFeedback_1=
-b.asm.Id).apply(null,arguments)},Hf=b._emscripten_bind_btGeneric6DofConstraint_getBreakingImpulseThreshold_0=function(){return(Hf=b._emscripten_bind_btGeneric6DofConstraint_getBreakingImpulseThreshold_0=b.asm.Jd).apply(null,arguments)},If=b._emscripten_bind_btGeneric6DofConstraint_setBreakingImpulseThreshold_1=function(){return(If=b._emscripten_bind_btGeneric6DofConstraint_setBreakingImpulseThreshold_1=b.asm.Kd).apply(null,arguments)},Jf=b._emscripten_bind_btGeneric6DofConstraint_getParam_2=function(){return(Jf=
-b._emscripten_bind_btGeneric6DofConstraint_getParam_2=b.asm.Ld).apply(null,arguments)},Kf=b._emscripten_bind_btGeneric6DofConstraint_setParam_3=function(){return(Kf=b._emscripten_bind_btGeneric6DofConstraint_setParam_3=b.asm.Md).apply(null,arguments)},Lf=b._emscripten_bind_btGeneric6DofConstraint___destroy___0=function(){return(Lf=b._emscripten_bind_btGeneric6DofConstraint___destroy___0=b.asm.Nd).apply(null,arguments)},Mf=b._emscripten_bind_btStridingMeshInterface_setScaling_1=function(){return(Mf=
-b._emscripten_bind_btStridingMeshInterface_setScaling_1=b.asm.Od).apply(null,arguments)},Nf=b._emscripten_bind_btStridingMeshInterface___destroy___0=function(){return(Nf=b._emscripten_bind_btStridingMeshInterface___destroy___0=b.asm.Pd).apply(null,arguments)},Of=b._emscripten_bind_btMotionState_getWorldTransform_1=function(){return(Of=b._emscripten_bind_btMotionState_getWorldTransform_1=b.asm.Qd).apply(null,arguments)},Pf=b._emscripten_bind_btMotionState_setWorldTransform_1=function(){return(Pf=b._emscripten_bind_btMotionState_setWorldTransform_1=
-b.asm.Rd).apply(null,arguments)},Qf=b._emscripten_bind_btMotionState___destroy___0=function(){return(Qf=b._emscripten_bind_btMotionState___destroy___0=b.asm.Sd).apply(null,arguments)},Rf=b._emscripten_bind_ConvexResultCallback_hasHit_0=function(){return(Rf=b._emscripten_bind_ConvexResultCallback_hasHit_0=b.asm.Td).apply(null,arguments)},Sf=b._emscripten_bind_ConvexResultCallback_get_m_collisionFilterGroup_0=function(){return(Sf=b._emscripten_bind_ConvexResultCallback_get_m_collisionFilterGroup_0=
-b.asm.Ud).apply(null,arguments)},Tf=b._emscripten_bind_ConvexResultCallback_set_m_collisionFilterGroup_1=function(){return(Tf=b._emscripten_bind_ConvexResultCallback_set_m_collisionFilterGroup_1=b.asm.Vd).apply(null,arguments)},Uf=b._emscripten_bind_ConvexResultCallback_get_m_collisionFilterMask_0=function(){return(Uf=b._emscripten_bind_ConvexResultCallback_get_m_collisionFilterMask_0=b.asm.Wd).apply(null,arguments)},Vf=b._emscripten_bind_ConvexResultCallback_set_m_collisionFilterMask_1=function(){return(Vf=
-b._emscripten_bind_ConvexResultCallback_set_m_collisionFilterMask_1=b.asm.Xd).apply(null,arguments)},Wf=b._emscripten_bind_ConvexResultCallback_get_m_closestHitFraction_0=function(){return(Wf=b._emscripten_bind_ConvexResultCallback_get_m_closestHitFraction_0=b.asm.Yd).apply(null,arguments)},Xf=b._emscripten_bind_ConvexResultCallback_set_m_closestHitFraction_1=function(){return(Xf=b._emscripten_bind_ConvexResultCallback_set_m_closestHitFraction_1=b.asm.Zd).apply(null,arguments)},Yf=b._emscripten_bind_ConvexResultCallback___destroy___0=
-function(){return(Yf=b._emscripten_bind_ConvexResultCallback___destroy___0=b.asm._d).apply(null,arguments)},Zf=b._emscripten_bind_ContactResultCallback_addSingleResult_7=function(){return(Zf=b._emscripten_bind_ContactResultCallback_addSingleResult_7=b.asm.$d).apply(null,arguments)},$f=b._emscripten_bind_ContactResultCallback___destroy___0=function(){return($f=b._emscripten_bind_ContactResultCallback___destroy___0=b.asm.ae).apply(null,arguments)},ag=b._emscripten_bind_btSoftBodySolver___destroy___0=
-function(){return(ag=b._emscripten_bind_btSoftBodySolver___destroy___0=b.asm.be).apply(null,arguments)},bg=b._emscripten_bind_RayResultCallback_hasHit_0=function(){return(bg=b._emscripten_bind_RayResultCallback_hasHit_0=b.asm.ce).apply(null,arguments)},cg=b._emscripten_bind_RayResultCallback_get_m_collisionFilterGroup_0=function(){return(cg=b._emscripten_bind_RayResultCallback_get_m_collisionFilterGroup_0=b.asm.de).apply(null,arguments)},dg=b._emscripten_bind_RayResultCallback_set_m_collisionFilterGroup_1=
-function(){return(dg=b._emscripten_bind_RayResultCallback_set_m_collisionFilterGroup_1=b.asm.ee).apply(null,arguments)},eg=b._emscripten_bind_RayResultCallback_get_m_collisionFilterMask_0=function(){return(eg=b._emscripten_bind_RayResultCallback_get_m_collisionFilterMask_0=b.asm.fe).apply(null,arguments)},fg=b._emscripten_bind_RayResultCallback_set_m_collisionFilterMask_1=function(){return(fg=b._emscripten_bind_RayResultCallback_set_m_collisionFilterMask_1=b.asm.ge).apply(null,arguments)},gg=b._emscripten_bind_RayResultCallback_get_m_closestHitFraction_0=
-function(){return(gg=b._emscripten_bind_RayResultCallback_get_m_closestHitFraction_0=b.asm.he).apply(null,arguments)},hg=b._emscripten_bind_RayResultCallback_set_m_closestHitFraction_1=function(){return(hg=b._emscripten_bind_RayResultCallback_set_m_closestHitFraction_1=b.asm.ie).apply(null,arguments)},ig=b._emscripten_bind_RayResultCallback_get_m_collisionObject_0=function(){return(ig=b._emscripten_bind_RayResultCallback_get_m_collisionObject_0=b.asm.je).apply(null,arguments)},jg=b._emscripten_bind_RayResultCallback_set_m_collisionObject_1=
-function(){return(jg=b._emscripten_bind_RayResultCallback_set_m_collisionObject_1=b.asm.ke).apply(null,arguments)},kg=b._emscripten_bind_RayResultCallback___destroy___0=function(){return(kg=b._emscripten_bind_RayResultCallback___destroy___0=b.asm.le).apply(null,arguments)},lg=b._emscripten_bind_btMatrix3x3_setEulerZYX_3=function(){return(lg=b._emscripten_bind_btMatrix3x3_setEulerZYX_3=b.asm.me).apply(null,arguments)},mg=b._emscripten_bind_btMatrix3x3_getRotation_1=function(){return(mg=b._emscripten_bind_btMatrix3x3_getRotation_1=
-b.asm.ne).apply(null,arguments)},ng=b._emscripten_bind_btMatrix3x3_getRow_1=function(){return(ng=b._emscripten_bind_btMatrix3x3_getRow_1=b.asm.oe).apply(null,arguments)},og=b._emscripten_bind_btMatrix3x3___destroy___0=function(){return(og=b._emscripten_bind_btMatrix3x3___destroy___0=b.asm.pe).apply(null,arguments)},pg=b._emscripten_bind_btScalarArray_size_0=function(){return(pg=b._emscripten_bind_btScalarArray_size_0=b.asm.qe).apply(null,arguments)},qg=b._emscripten_bind_btScalarArray_at_1=function(){return(qg=
-b._emscripten_bind_btScalarArray_at_1=b.asm.re).apply(null,arguments)},rg=b._emscripten_bind_btScalarArray___destroy___0=function(){return(rg=b._emscripten_bind_btScalarArray___destroy___0=b.asm.se).apply(null,arguments)},sg=b._emscripten_bind_Material_get_m_kLST_0=function(){return(sg=b._emscripten_bind_Material_get_m_kLST_0=b.asm.te).apply(null,arguments)},tg=b._emscripten_bind_Material_set_m_kLST_1=function(){return(tg=b._emscripten_bind_Material_set_m_kLST_1=b.asm.ue).apply(null,arguments)},ug=
-b._emscripten_bind_Material_get_m_kAST_0=function(){return(ug=b._emscripten_bind_Material_get_m_kAST_0=b.asm.ve).apply(null,arguments)},vg=b._emscripten_bind_Material_set_m_kAST_1=function(){return(vg=b._emscripten_bind_Material_set_m_kAST_1=b.asm.we).apply(null,arguments)},wg=b._emscripten_bind_Material_get_m_kVST_0=function(){return(wg=b._emscripten_bind_Material_get_m_kVST_0=b.asm.xe).apply(null,arguments)},xg=b._emscripten_bind_Material_set_m_kVST_1=function(){return(xg=b._emscripten_bind_Material_set_m_kVST_1=
-b.asm.ye).apply(null,arguments)},yg=b._emscripten_bind_Material_get_m_flags_0=function(){return(yg=b._emscripten_bind_Material_get_m_flags_0=b.asm.ze).apply(null,arguments)},zg=b._emscripten_bind_Material_set_m_flags_1=function(){return(zg=b._emscripten_bind_Material_set_m_flags_1=b.asm.Ae).apply(null,arguments)},Ag=b._emscripten_bind_Material___destroy___0=function(){return(Ag=b._emscripten_bind_Material___destroy___0=b.asm.Be).apply(null,arguments)},Bg=b._emscripten_bind_btDispatcherInfo_get_m_timeStep_0=
-function(){return(Bg=b._emscripten_bind_btDispatcherInfo_get_m_timeStep_0=b.asm.Ce).apply(null,arguments)},Cg=b._emscripten_bind_btDispatcherInfo_set_m_timeStep_1=function(){return(Cg=b._emscripten_bind_btDispatcherInfo_set_m_timeStep_1=b.asm.De).apply(null,arguments)},Dg=b._emscripten_bind_btDispatcherInfo_get_m_stepCount_0=function(){return(Dg=b._emscripten_bind_btDispatcherInfo_get_m_stepCount_0=b.asm.Ee).apply(null,arguments)},Eg=b._emscripten_bind_btDispatcherInfo_set_m_stepCount_1=function(){return(Eg=
-b._emscripten_bind_btDispatcherInfo_set_m_stepCount_1=b.asm.Fe).apply(null,arguments)},Fg=b._emscripten_bind_btDispatcherInfo_get_m_dispatchFunc_0=function(){return(Fg=b._emscripten_bind_btDispatcherInfo_get_m_dispatchFunc_0=b.asm.Ge).apply(null,arguments)},Gg=b._emscripten_bind_btDispatcherInfo_set_m_dispatchFunc_1=function(){return(Gg=b._emscripten_bind_btDispatcherInfo_set_m_dispatchFunc_1=b.asm.He).apply(null,arguments)},Hg=b._emscripten_bind_btDispatcherInfo_get_m_timeOfImpact_0=function(){return(Hg=
-b._emscripten_bind_btDispatcherInfo_get_m_timeOfImpact_0=b.asm.Ie).apply(null,arguments)},Ig=b._emscripten_bind_btDispatcherInfo_set_m_timeOfImpact_1=function(){return(Ig=b._emscripten_bind_btDispatcherInfo_set_m_timeOfImpact_1=b.asm.Je).apply(null,arguments)},Jg=b._emscripten_bind_btDispatcherInfo_get_m_useContinuous_0=function(){return(Jg=b._emscripten_bind_btDispatcherInfo_get_m_useContinuous_0=b.asm.Ke).apply(null,arguments)},Kg=b._emscripten_bind_btDispatcherInfo_set_m_useContinuous_1=function(){return(Kg=
-b._emscripten_bind_btDispatcherInfo_set_m_useContinuous_1=b.asm.Le).apply(null,arguments)},Lg=b._emscripten_bind_btDispatcherInfo_get_m_enableSatConvex_0=function(){return(Lg=b._emscripten_bind_btDispatcherInfo_get_m_enableSatConvex_0=b.asm.Me).apply(null,arguments)},Mg=b._emscripten_bind_btDispatcherInfo_set_m_enableSatConvex_1=function(){return(Mg=b._emscripten_bind_btDispatcherInfo_set_m_enableSatConvex_1=b.asm.Ne).apply(null,arguments)},Ng=b._emscripten_bind_btDispatcherInfo_get_m_enableSPU_0=
-function(){return(Ng=b._emscripten_bind_btDispatcherInfo_get_m_enableSPU_0=b.asm.Oe).apply(null,arguments)},Og=b._emscripten_bind_btDispatcherInfo_set_m_enableSPU_1=function(){return(Og=b._emscripten_bind_btDispatcherInfo_set_m_enableSPU_1=b.asm.Pe).apply(null,arguments)},Pg=b._emscripten_bind_btDispatcherInfo_get_m_useEpa_0=function(){return(Pg=b._emscripten_bind_btDispatcherInfo_get_m_useEpa_0=b.asm.Qe).apply(null,arguments)},Qg=b._emscripten_bind_btDispatcherInfo_set_m_useEpa_1=function(){return(Qg=
-b._emscripten_bind_btDispatcherInfo_set_m_useEpa_1=b.asm.Re).apply(null,arguments)},Rg=b._emscripten_bind_btDispatcherInfo_get_m_allowedCcdPenetration_0=function(){return(Rg=b._emscripten_bind_btDispatcherInfo_get_m_allowedCcdPenetration_0=b.asm.Se).apply(null,arguments)},Sg=b._emscripten_bind_btDispatcherInfo_set_m_allowedCcdPenetration_1=function(){return(Sg=b._emscripten_bind_btDispatcherInfo_set_m_allowedCcdPenetration_1=b.asm.Te).apply(null,arguments)},Tg=b._emscripten_bind_btDispatcherInfo_get_m_useConvexConservativeDistanceUtil_0=
-function(){return(Tg=b._emscripten_bind_btDispatcherInfo_get_m_useConvexConservativeDistanceUtil_0=b.asm.Ue).apply(null,arguments)},Ug=b._emscripten_bind_btDispatcherInfo_set_m_useConvexConservativeDistanceUtil_1=function(){return(Ug=b._emscripten_bind_btDispatcherInfo_set_m_useConvexConservativeDistanceUtil_1=b.asm.Ve).apply(null,arguments)},Vg=b._emscripten_bind_btDispatcherInfo_get_m_convexConservativeDistanceThreshold_0=function(){return(Vg=b._emscripten_bind_btDispatcherInfo_get_m_convexConservativeDistanceThreshold_0=
-b.asm.We).apply(null,arguments)},Wg=b._emscripten_bind_btDispatcherInfo_set_m_convexConservativeDistanceThreshold_1=function(){return(Wg=b._emscripten_bind_btDispatcherInfo_set_m_convexConservativeDistanceThreshold_1=b.asm.Xe).apply(null,arguments)},Xg=b._emscripten_bind_btDispatcherInfo___destroy___0=function(){return(Xg=b._emscripten_bind_btDispatcherInfo___destroy___0=b.asm.Ye).apply(null,arguments)},Yg=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_chassisConnectionCS_0=function(){return(Yg=
-b._emscripten_bind_btWheelInfoConstructionInfo_get_m_chassisConnectionCS_0=b.asm.Ze).apply(null,arguments)},Zg=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_chassisConnectionCS_1=function(){return(Zg=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_chassisConnectionCS_1=b.asm._e).apply(null,arguments)},$g=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_wheelDirectionCS_0=function(){return($g=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_wheelDirectionCS_0=b.asm.$e).apply(null,
-arguments)},ah=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_wheelDirectionCS_1=function(){return(ah=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_wheelDirectionCS_1=b.asm.af).apply(null,arguments)},bh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_wheelAxleCS_0=function(){return(bh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_wheelAxleCS_0=b.asm.bf).apply(null,arguments)},ch=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_wheelAxleCS_1=function(){return(ch=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_wheelAxleCS_1=
-b.asm.cf).apply(null,arguments)},dh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_suspensionRestLength_0=function(){return(dh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_suspensionRestLength_0=b.asm.df).apply(null,arguments)},eh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_suspensionRestLength_1=function(){return(eh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_suspensionRestLength_1=b.asm.ef).apply(null,arguments)},fh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_maxSuspensionTravelCm_0=
-function(){return(fh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_maxSuspensionTravelCm_0=b.asm.ff).apply(null,arguments)},gh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_maxSuspensionTravelCm_1=function(){return(gh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_maxSuspensionTravelCm_1=b.asm.gf).apply(null,arguments)},hh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_wheelRadius_0=function(){return(hh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_wheelRadius_0=b.asm.hf).apply(null,
-arguments)},ih=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_wheelRadius_1=function(){return(ih=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_wheelRadius_1=b.asm.jf).apply(null,arguments)},jh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_suspensionStiffness_0=function(){return(jh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_suspensionStiffness_0=b.asm.kf).apply(null,arguments)},kh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_suspensionStiffness_1=function(){return(kh=
-b._emscripten_bind_btWheelInfoConstructionInfo_set_m_suspensionStiffness_1=b.asm.lf).apply(null,arguments)},lh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_wheelsDampingCompression_0=function(){return(lh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_wheelsDampingCompression_0=b.asm.mf).apply(null,arguments)},mh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_wheelsDampingCompression_1=function(){return(mh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_wheelsDampingCompression_1=
-b.asm.nf).apply(null,arguments)},nh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_wheelsDampingRelaxation_0=function(){return(nh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_wheelsDampingRelaxation_0=b.asm.of).apply(null,arguments)},oh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_wheelsDampingRelaxation_1=function(){return(oh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_wheelsDampingRelaxation_1=b.asm.pf).apply(null,arguments)},ph=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_frictionSlip_0=
-function(){return(ph=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_frictionSlip_0=b.asm.qf).apply(null,arguments)},qh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_frictionSlip_1=function(){return(qh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_frictionSlip_1=b.asm.rf).apply(null,arguments)},rh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_maxSuspensionForce_0=function(){return(rh=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_maxSuspensionForce_0=b.asm.sf).apply(null,
-arguments)},sh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_maxSuspensionForce_1=function(){return(sh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_maxSuspensionForce_1=b.asm.tf).apply(null,arguments)},th=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_bIsFrontWheel_0=function(){return(th=b._emscripten_bind_btWheelInfoConstructionInfo_get_m_bIsFrontWheel_0=b.asm.uf).apply(null,arguments)},uh=b._emscripten_bind_btWheelInfoConstructionInfo_set_m_bIsFrontWheel_1=function(){return(uh=
-b._emscripten_bind_btWheelInfoConstructionInfo_set_m_bIsFrontWheel_1=b.asm.vf).apply(null,arguments)},vh=b._emscripten_bind_btWheelInfoConstructionInfo___destroy___0=function(){return(vh=b._emscripten_bind_btWheelInfoConstructionInfo___destroy___0=b.asm.wf).apply(null,arguments)},wh=b._emscripten_bind_btConvexTriangleMeshShape_btConvexTriangleMeshShape_1=function(){return(wh=b._emscripten_bind_btConvexTriangleMeshShape_btConvexTriangleMeshShape_1=b.asm.xf).apply(null,arguments)},xh=b._emscripten_bind_btConvexTriangleMeshShape_btConvexTriangleMeshShape_2=
-function(){return(xh=b._emscripten_bind_btConvexTriangleMeshShape_btConvexTriangleMeshShape_2=b.asm.yf).apply(null,arguments)},yh=b._emscripten_bind_btConvexTriangleMeshShape_setLocalScaling_1=function(){return(yh=b._emscripten_bind_btConvexTriangleMeshShape_setLocalScaling_1=b.asm.zf).apply(null,arguments)},zh=b._emscripten_bind_btConvexTriangleMeshShape_getLocalScaling_0=function(){return(zh=b._emscripten_bind_btConvexTriangleMeshShape_getLocalScaling_0=b.asm.Af).apply(null,arguments)},Ah=b._emscripten_bind_btConvexTriangleMeshShape_calculateLocalInertia_2=
-function(){return(Ah=b._emscripten_bind_btConvexTriangleMeshShape_calculateLocalInertia_2=b.asm.Bf).apply(null,arguments)},Bh=b._emscripten_bind_btConvexTriangleMeshShape_setMargin_1=function(){return(Bh=b._emscripten_bind_btConvexTriangleMeshShape_setMargin_1=b.asm.Cf).apply(null,arguments)},Ch=b._emscripten_bind_btConvexTriangleMeshShape_getMargin_0=function(){return(Ch=b._emscripten_bind_btConvexTriangleMeshShape_getMargin_0=b.asm.Df).apply(null,arguments)},Dh=b._emscripten_bind_btConvexTriangleMeshShape___destroy___0=
-function(){return(Dh=b._emscripten_bind_btConvexTriangleMeshShape___destroy___0=b.asm.Ef).apply(null,arguments)},Eh=b._emscripten_bind_btBroadphaseInterface_getOverlappingPairCache_0=function(){return(Eh=b._emscripten_bind_btBroadphaseInterface_getOverlappingPairCache_0=b.asm.Ff).apply(null,arguments)},Fh=b._emscripten_bind_btBroadphaseInterface___destroy___0=function(){return(Fh=b._emscripten_bind_btBroadphaseInterface___destroy___0=b.asm.Gf).apply(null,arguments)},Gh=b._emscripten_bind_btRigidBodyConstructionInfo_btRigidBodyConstructionInfo_3=
-function(){return(Gh=b._emscripten_bind_btRigidBodyConstructionInfo_btRigidBodyConstructionInfo_3=b.asm.Hf).apply(null,arguments)},Hh=b._emscripten_bind_btRigidBodyConstructionInfo_btRigidBodyConstructionInfo_4=function(){return(Hh=b._emscripten_bind_btRigidBodyConstructionInfo_btRigidBodyConstructionInfo_4=b.asm.If).apply(null,arguments)},Ih=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_linearDamping_0=function(){return(Ih=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_linearDamping_0=
-b.asm.Jf).apply(null,arguments)},Jh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_linearDamping_1=function(){return(Jh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_linearDamping_1=b.asm.Kf).apply(null,arguments)},Kh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_angularDamping_0=function(){return(Kh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_angularDamping_0=b.asm.Lf).apply(null,arguments)},Lh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_angularDamping_1=function(){return(Lh=
-b._emscripten_bind_btRigidBodyConstructionInfo_set_m_angularDamping_1=b.asm.Mf).apply(null,arguments)},Mh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_friction_0=function(){return(Mh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_friction_0=b.asm.Nf).apply(null,arguments)},Nh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_friction_1=function(){return(Nh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_friction_1=b.asm.Of).apply(null,arguments)},Oh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_rollingFriction_0=
-function(){return(Oh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_rollingFriction_0=b.asm.Pf).apply(null,arguments)},Ph=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_rollingFriction_1=function(){return(Ph=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_rollingFriction_1=b.asm.Qf).apply(null,arguments)},Qh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_restitution_0=function(){return(Qh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_restitution_0=b.asm.Rf).apply(null,
-arguments)},Rh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_restitution_1=function(){return(Rh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_restitution_1=b.asm.Sf).apply(null,arguments)},Sh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_linearSleepingThreshold_0=function(){return(Sh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_linearSleepingThreshold_0=b.asm.Tf).apply(null,arguments)},Th=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_linearSleepingThreshold_1=function(){return(Th=
-b._emscripten_bind_btRigidBodyConstructionInfo_set_m_linearSleepingThreshold_1=b.asm.Uf).apply(null,arguments)},Uh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_angularSleepingThreshold_0=function(){return(Uh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_angularSleepingThreshold_0=b.asm.Vf).apply(null,arguments)},Vh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_angularSleepingThreshold_1=function(){return(Vh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_angularSleepingThreshold_1=
-b.asm.Wf).apply(null,arguments)},Wh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_additionalDamping_0=function(){return(Wh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_additionalDamping_0=b.asm.Xf).apply(null,arguments)},Xh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_additionalDamping_1=function(){return(Xh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_additionalDamping_1=b.asm.Yf).apply(null,arguments)},Yh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_additionalDampingFactor_0=
-function(){return(Yh=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_additionalDampingFactor_0=b.asm.Zf).apply(null,arguments)},Zh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_additionalDampingFactor_1=function(){return(Zh=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_additionalDampingFactor_1=b.asm._f).apply(null,arguments)},$h=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_additionalLinearDampingThresholdSqr_0=function(){return($h=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_additionalLinearDampingThresholdSqr_0=
-b.asm.$f).apply(null,arguments)},ai=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_additionalLinearDampingThresholdSqr_1=function(){return(ai=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_additionalLinearDampingThresholdSqr_1=b.asm.ag).apply(null,arguments)},bi=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_additionalAngularDampingThresholdSqr_0=function(){return(bi=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_additionalAngularDampingThresholdSqr_0=b.asm.bg).apply(null,
-arguments)},ci=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_additionalAngularDampingThresholdSqr_1=function(){return(ci=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_additionalAngularDampingThresholdSqr_1=b.asm.cg).apply(null,arguments)},di=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_additionalAngularDampingFactor_0=function(){return(di=b._emscripten_bind_btRigidBodyConstructionInfo_get_m_additionalAngularDampingFactor_0=b.asm.dg).apply(null,arguments)},ei=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_additionalAngularDampingFactor_1=
-function(){return(ei=b._emscripten_bind_btRigidBodyConstructionInfo_set_m_additionalAngularDampingFactor_1=b.asm.eg).apply(null,arguments)},fi=b._emscripten_bind_btRigidBodyConstructionInfo___destroy___0=function(){return(fi=b._emscripten_bind_btRigidBodyConstructionInfo___destroy___0=b.asm.fg).apply(null,arguments)},gi=b._emscripten_bind_btCollisionConfiguration___destroy___0=function(){return(gi=b._emscripten_bind_btCollisionConfiguration___destroy___0=b.asm.gg).apply(null,arguments)},hi=b._emscripten_bind_btPersistentManifold_btPersistentManifold_0=
-function(){return(hi=b._emscripten_bind_btPersistentManifold_btPersistentManifold_0=b.asm.hg).apply(null,arguments)},ii=b._emscripten_bind_btPersistentManifold_getBody0_0=function(){return(ii=b._emscripten_bind_btPersistentManifold_getBody0_0=b.asm.ig).apply(null,arguments)},ji=b._emscripten_bind_btPersistentManifold_getBody1_0=function(){return(ji=b._emscripten_bind_btPersistentManifold_getBody1_0=b.asm.jg).apply(null,arguments)},ki=b._emscripten_bind_btPersistentManifold_getNumContacts_0=function(){return(ki=
-b._emscripten_bind_btPersistentManifold_getNumContacts_0=b.asm.kg).apply(null,arguments)},li=b._emscripten_bind_btPersistentManifold_getContactPoint_1=function(){return(li=b._emscripten_bind_btPersistentManifold_getContactPoint_1=b.asm.lg).apply(null,arguments)},mi=b._emscripten_bind_btPersistentManifold___destroy___0=function(){return(mi=b._emscripten_bind_btPersistentManifold___destroy___0=b.asm.mg).apply(null,arguments)},ni=b._emscripten_bind_btCompoundShape_btCompoundShape_0=function(){return(ni=
-b._emscripten_bind_btCompoundShape_btCompoundShape_0=b.asm.ng).apply(null,arguments)},oi=b._emscripten_bind_btCompoundShape_btCompoundShape_1=function(){return(oi=b._emscripten_bind_btCompoundShape_btCompoundShape_1=b.asm.og).apply(null,arguments)},pi=b._emscripten_bind_btCompoundShape_addChildShape_2=function(){return(pi=b._emscripten_bind_btCompoundShape_addChildShape_2=b.asm.pg).apply(null,arguments)},qi=b._emscripten_bind_btCompoundShape_removeChildShape_1=function(){return(qi=b._emscripten_bind_btCompoundShape_removeChildShape_1=
-b.asm.qg).apply(null,arguments)},ri=b._emscripten_bind_btCompoundShape_removeChildShapeByIndex_1=function(){return(ri=b._emscripten_bind_btCompoundShape_removeChildShapeByIndex_1=b.asm.rg).apply(null,arguments)},si=b._emscripten_bind_btCompoundShape_getNumChildShapes_0=function(){return(si=b._emscripten_bind_btCompoundShape_getNumChildShapes_0=b.asm.sg).apply(null,arguments)},ti=b._emscripten_bind_btCompoundShape_getChildShape_1=function(){return(ti=b._emscripten_bind_btCompoundShape_getChildShape_1=
-b.asm.tg).apply(null,arguments)},ui=b._emscripten_bind_btCompoundShape_updateChildTransform_2=function(){return(ui=b._emscripten_bind_btCompoundShape_updateChildTransform_2=b.asm.ug).apply(null,arguments)},vi=b._emscripten_bind_btCompoundShape_updateChildTransform_3=function(){return(vi=b._emscripten_bind_btCompoundShape_updateChildTransform_3=b.asm.vg).apply(null,arguments)},wi=b._emscripten_bind_btCompoundShape_setMargin_1=function(){return(wi=b._emscripten_bind_btCompoundShape_setMargin_1=b.asm.wg).apply(null,
-arguments)},xi=b._emscripten_bind_btCompoundShape_getMargin_0=function(){return(xi=b._emscripten_bind_btCompoundShape_getMargin_0=b.asm.xg).apply(null,arguments)},yi=b._emscripten_bind_btCompoundShape_setLocalScaling_1=function(){return(yi=b._emscripten_bind_btCompoundShape_setLocalScaling_1=b.asm.yg).apply(null,arguments)},zi=b._emscripten_bind_btCompoundShape_getLocalScaling_0=function(){return(zi=b._emscripten_bind_btCompoundShape_getLocalScaling_0=b.asm.zg).apply(null,arguments)},Ai=b._emscripten_bind_btCompoundShape_calculateLocalInertia_2=
-function(){return(Ai=b._emscripten_bind_btCompoundShape_calculateLocalInertia_2=b.asm.Ag).apply(null,arguments)},Bi=b._emscripten_bind_btCompoundShape___destroy___0=function(){return(Bi=b._emscripten_bind_btCompoundShape___destroy___0=b.asm.Bg).apply(null,arguments)},Ci=b._emscripten_bind_ClosestConvexResultCallback_ClosestConvexResultCallback_2=function(){return(Ci=b._emscripten_bind_ClosestConvexResultCallback_ClosestConvexResultCallback_2=b.asm.Cg).apply(null,arguments)},Di=b._emscripten_bind_ClosestConvexResultCallback_hasHit_0=
-function(){return(Di=b._emscripten_bind_ClosestConvexResultCallback_hasHit_0=b.asm.Dg).apply(null,arguments)},Ei=b._emscripten_bind_ClosestConvexResultCallback_get_m_convexFromWorld_0=function(){return(Ei=b._emscripten_bind_ClosestConvexResultCallback_get_m_convexFromWorld_0=b.asm.Eg).apply(null,arguments)},Fi=b._emscripten_bind_ClosestConvexResultCallback_set_m_convexFromWorld_1=function(){return(Fi=b._emscripten_bind_ClosestConvexResultCallback_set_m_convexFromWorld_1=b.asm.Fg).apply(null,arguments)},
-Gi=b._emscripten_bind_ClosestConvexResultCallback_get_m_convexToWorld_0=function(){return(Gi=b._emscripten_bind_ClosestConvexResultCallback_get_m_convexToWorld_0=b.asm.Gg).apply(null,arguments)},Hi=b._emscripten_bind_ClosestConvexResultCallback_set_m_convexToWorld_1=function(){return(Hi=b._emscripten_bind_ClosestConvexResultCallback_set_m_convexToWorld_1=b.asm.Hg).apply(null,arguments)},Ii=b._emscripten_bind_ClosestConvexResultCallback_get_m_hitNormalWorld_0=function(){return(Ii=b._emscripten_bind_ClosestConvexResultCallback_get_m_hitNormalWorld_0=
-b.asm.Ig).apply(null,arguments)},Ji=b._emscripten_bind_ClosestConvexResultCallback_set_m_hitNormalWorld_1=function(){return(Ji=b._emscripten_bind_ClosestConvexResultCallback_set_m_hitNormalWorld_1=b.asm.Jg).apply(null,arguments)},Ki=b._emscripten_bind_ClosestConvexResultCallback_get_m_hitPointWorld_0=function(){return(Ki=b._emscripten_bind_ClosestConvexResultCallback_get_m_hitPointWorld_0=b.asm.Kg).apply(null,arguments)},Li=b._emscripten_bind_ClosestConvexResultCallback_set_m_hitPointWorld_1=function(){return(Li=
-b._emscripten_bind_ClosestConvexResultCallback_set_m_hitPointWorld_1=b.asm.Lg).apply(null,arguments)},Mi=b._emscripten_bind_ClosestConvexResultCallback_get_m_collisionFilterGroup_0=function(){return(Mi=b._emscripten_bind_ClosestConvexResultCallback_get_m_collisionFilterGroup_0=b.asm.Mg).apply(null,arguments)},Ni=b._emscripten_bind_ClosestConvexResultCallback_set_m_collisionFilterGroup_1=function(){return(Ni=b._emscripten_bind_ClosestConvexResultCallback_set_m_collisionFilterGroup_1=b.asm.Ng).apply(null,
-arguments)},Oi=b._emscripten_bind_ClosestConvexResultCallback_get_m_collisionFilterMask_0=function(){return(Oi=b._emscripten_bind_ClosestConvexResultCallback_get_m_collisionFilterMask_0=b.asm.Og).apply(null,arguments)},Pi=b._emscripten_bind_ClosestConvexResultCallback_set_m_collisionFilterMask_1=function(){return(Pi=b._emscripten_bind_ClosestConvexResultCallback_set_m_collisionFilterMask_1=b.asm.Pg).apply(null,arguments)},Qi=b._emscripten_bind_ClosestConvexResultCallback_get_m_closestHitFraction_0=
-function(){return(Qi=b._emscripten_bind_ClosestConvexResultCallback_get_m_closestHitFraction_0=b.asm.Qg).apply(null,arguments)},Ri=b._emscripten_bind_ClosestConvexResultCallback_set_m_closestHitFraction_1=function(){return(Ri=b._emscripten_bind_ClosestConvexResultCallback_set_m_closestHitFraction_1=b.asm.Rg).apply(null,arguments)},Si=b._emscripten_bind_ClosestConvexResultCallback___destroy___0=function(){return(Si=b._emscripten_bind_ClosestConvexResultCallback___destroy___0=b.asm.Sg).apply(null,arguments)},
-Ti=b._emscripten_bind_AllHitsRayResultCallback_AllHitsRayResultCallback_2=function(){return(Ti=b._emscripten_bind_AllHitsRayResultCallback_AllHitsRayResultCallback_2=b.asm.Tg).apply(null,arguments)},Ui=b._emscripten_bind_AllHitsRayResultCallback_hasHit_0=function(){return(Ui=b._emscripten_bind_AllHitsRayResultCallback_hasHit_0=b.asm.Ug).apply(null,arguments)},Vi=b._emscripten_bind_AllHitsRayResultCallback_get_m_collisionObjects_0=function(){return(Vi=b._emscripten_bind_AllHitsRayResultCallback_get_m_collisionObjects_0=
-b.asm.Vg).apply(null,arguments)},Wi=b._emscripten_bind_AllHitsRayResultCallback_set_m_collisionObjects_1=function(){return(Wi=b._emscripten_bind_AllHitsRayResultCallback_set_m_collisionObjects_1=b.asm.Wg).apply(null,arguments)},Xi=b._emscripten_bind_AllHitsRayResultCallback_get_m_rayFromWorld_0=function(){return(Xi=b._emscripten_bind_AllHitsRayResultCallback_get_m_rayFromWorld_0=b.asm.Xg).apply(null,arguments)},Yi=b._emscripten_bind_AllHitsRayResultCallback_set_m_rayFromWorld_1=function(){return(Yi=
-b._emscripten_bind_AllHitsRayResultCallback_set_m_rayFromWorld_1=b.asm.Yg).apply(null,arguments)},Zi=b._emscripten_bind_AllHitsRayResultCallback_get_m_rayToWorld_0=function(){return(Zi=b._emscripten_bind_AllHitsRayResultCallback_get_m_rayToWorld_0=b.asm.Zg).apply(null,arguments)},$i=b._emscripten_bind_AllHitsRayResultCallback_set_m_rayToWorld_1=function(){return($i=b._emscripten_bind_AllHitsRayResultCallback_set_m_rayToWorld_1=b.asm._g).apply(null,arguments)},aj=b._emscripten_bind_AllHitsRayResultCallback_get_m_hitNormalWorld_0=
-function(){return(aj=b._emscripten_bind_AllHitsRayResultCallback_get_m_hitNormalWorld_0=b.asm.$g).apply(null,arguments)},bj=b._emscripten_bind_AllHitsRayResultCallback_set_m_hitNormalWorld_1=function(){return(bj=b._emscripten_bind_AllHitsRayResultCallback_set_m_hitNormalWorld_1=b.asm.ah).apply(null,arguments)},cj=b._emscripten_bind_AllHitsRayResultCallback_get_m_hitPointWorld_0=function(){return(cj=b._emscripten_bind_AllHitsRayResultCallback_get_m_hitPointWorld_0=b.asm.bh).apply(null,arguments)},
-dj=b._emscripten_bind_AllHitsRayResultCallback_set_m_hitPointWorld_1=function(){return(dj=b._emscripten_bind_AllHitsRayResultCallback_set_m_hitPointWorld_1=b.asm.ch).apply(null,arguments)},ej=b._emscripten_bind_AllHitsRayResultCallback_get_m_hitFractions_0=function(){return(ej=b._emscripten_bind_AllHitsRayResultCallback_get_m_hitFractions_0=b.asm.dh).apply(null,arguments)},fj=b._emscripten_bind_AllHitsRayResultCallback_set_m_hitFractions_1=function(){return(fj=b._emscripten_bind_AllHitsRayResultCallback_set_m_hitFractions_1=
-b.asm.eh).apply(null,arguments)},gj=b._emscripten_bind_AllHitsRayResultCallback_get_m_collisionFilterGroup_0=function(){return(gj=b._emscripten_bind_AllHitsRayResultCallback_get_m_collisionFilterGroup_0=b.asm.fh).apply(null,arguments)},hj=b._emscripten_bind_AllHitsRayResultCallback_set_m_collisionFilterGroup_1=function(){return(hj=b._emscripten_bind_AllHitsRayResultCallback_set_m_collisionFilterGroup_1=b.asm.gh).apply(null,arguments)},ij=b._emscripten_bind_AllHitsRayResultCallback_get_m_collisionFilterMask_0=
-function(){return(ij=b._emscripten_bind_AllHitsRayResultCallback_get_m_collisionFilterMask_0=b.asm.hh).apply(null,arguments)},jj=b._emscripten_bind_AllHitsRayResultCallback_set_m_collisionFilterMask_1=function(){return(jj=b._emscripten_bind_AllHitsRayResultCallback_set_m_collisionFilterMask_1=b.asm.ih).apply(null,arguments)},kj=b._emscripten_bind_AllHitsRayResultCallback_get_m_closestHitFraction_0=function(){return(kj=b._emscripten_bind_AllHitsRayResultCallback_get_m_closestHitFraction_0=b.asm.jh).apply(null,
-arguments)},lj=b._emscripten_bind_AllHitsRayResultCallback_set_m_closestHitFraction_1=function(){return(lj=b._emscripten_bind_AllHitsRayResultCallback_set_m_closestHitFraction_1=b.asm.kh).apply(null,arguments)},mj=b._emscripten_bind_AllHitsRayResultCallback_get_m_collisionObject_0=function(){return(mj=b._emscripten_bind_AllHitsRayResultCallback_get_m_collisionObject_0=b.asm.lh).apply(null,arguments)},nj=b._emscripten_bind_AllHitsRayResultCallback_set_m_collisionObject_1=function(){return(nj=b._emscripten_bind_AllHitsRayResultCallback_set_m_collisionObject_1=
-b.asm.mh).apply(null,arguments)},oj=b._emscripten_bind_AllHitsRayResultCallback___destroy___0=function(){return(oj=b._emscripten_bind_AllHitsRayResultCallback___destroy___0=b.asm.nh).apply(null,arguments)},pj=b._emscripten_bind_tMaterialArray_size_0=function(){return(pj=b._emscripten_bind_tMaterialArray_size_0=b.asm.oh).apply(null,arguments)},qj=b._emscripten_bind_tMaterialArray_at_1=function(){return(qj=b._emscripten_bind_tMaterialArray_at_1=b.asm.ph).apply(null,arguments)},rj=b._emscripten_bind_tMaterialArray___destroy___0=
-function(){return(rj=b._emscripten_bind_tMaterialArray___destroy___0=b.asm.qh).apply(null,arguments)},sj=b._emscripten_bind_btDefaultVehicleRaycaster_btDefaultVehicleRaycaster_1=function(){return(sj=b._emscripten_bind_btDefaultVehicleRaycaster_btDefaultVehicleRaycaster_1=b.asm.rh).apply(null,arguments)},tj=b._emscripten_bind_btDefaultVehicleRaycaster_castRay_3=function(){return(tj=b._emscripten_bind_btDefaultVehicleRaycaster_castRay_3=b.asm.sh).apply(null,arguments)},uj=b._emscripten_bind_btDefaultVehicleRaycaster___destroy___0=
-function(){return(uj=b._emscripten_bind_btDefaultVehicleRaycaster___destroy___0=b.asm.th).apply(null,arguments)},vj=b._emscripten_bind_btEmptyShape_btEmptyShape_0=function(){return(vj=b._emscripten_bind_btEmptyShape_btEmptyShape_0=b.asm.uh).apply(null,arguments)},wj=b._emscripten_bind_btEmptyShape_setLocalScaling_1=function(){return(wj=b._emscripten_bind_btEmptyShape_setLocalScaling_1=b.asm.vh).apply(null,arguments)},xj=b._emscripten_bind_btEmptyShape_getLocalScaling_0=function(){return(xj=b._emscripten_bind_btEmptyShape_getLocalScaling_0=
-b.asm.wh).apply(null,arguments)},yj=b._emscripten_bind_btEmptyShape_calculateLocalInertia_2=function(){return(yj=b._emscripten_bind_btEmptyShape_calculateLocalInertia_2=b.asm.xh).apply(null,arguments)},zj=b._emscripten_bind_btEmptyShape___destroy___0=function(){return(zj=b._emscripten_bind_btEmptyShape___destroy___0=b.asm.yh).apply(null,arguments)},Aj=b._emscripten_bind_btConstraintSetting_btConstraintSetting_0=function(){return(Aj=b._emscripten_bind_btConstraintSetting_btConstraintSetting_0=b.asm.zh).apply(null,
-arguments)},Bj=b._emscripten_bind_btConstraintSetting_get_m_tau_0=function(){return(Bj=b._emscripten_bind_btConstraintSetting_get_m_tau_0=b.asm.Ah).apply(null,arguments)},Cj=b._emscripten_bind_btConstraintSetting_set_m_tau_1=function(){return(Cj=b._emscripten_bind_btConstraintSetting_set_m_tau_1=b.asm.Bh).apply(null,arguments)},Dj=b._emscripten_bind_btConstraintSetting_get_m_damping_0=function(){return(Dj=b._emscripten_bind_btConstraintSetting_get_m_damping_0=b.asm.Ch).apply(null,arguments)},Ej=b._emscripten_bind_btConstraintSetting_set_m_damping_1=
-function(){return(Ej=b._emscripten_bind_btConstraintSetting_set_m_damping_1=b.asm.Dh).apply(null,arguments)},Fj=b._emscripten_bind_btConstraintSetting_get_m_impulseClamp_0=function(){return(Fj=b._emscripten_bind_btConstraintSetting_get_m_impulseClamp_0=b.asm.Eh).apply(null,arguments)},Gj=b._emscripten_bind_btConstraintSetting_set_m_impulseClamp_1=function(){return(Gj=b._emscripten_bind_btConstraintSetting_set_m_impulseClamp_1=b.asm.Fh).apply(null,arguments)},Hj=b._emscripten_bind_btConstraintSetting___destroy___0=
-function(){return(Hj=b._emscripten_bind_btConstraintSetting___destroy___0=b.asm.Gh).apply(null,arguments)},Ij=b._emscripten_bind_LocalShapeInfo_get_m_shapePart_0=function(){return(Ij=b._emscripten_bind_LocalShapeInfo_get_m_shapePart_0=b.asm.Hh).apply(null,arguments)},Jj=b._emscripten_bind_LocalShapeInfo_set_m_shapePart_1=function(){return(Jj=b._emscripten_bind_LocalShapeInfo_set_m_shapePart_1=b.asm.Ih).apply(null,arguments)},Kj=b._emscripten_bind_LocalShapeInfo_get_m_triangleIndex_0=function(){return(Kj=
-b._emscripten_bind_LocalShapeInfo_get_m_triangleIndex_0=b.asm.Jh).apply(null,arguments)},Lj=b._emscripten_bind_LocalShapeInfo_set_m_triangleIndex_1=function(){return(Lj=b._emscripten_bind_LocalShapeInfo_set_m_triangleIndex_1=b.asm.Kh).apply(null,arguments)},Mj=b._emscripten_bind_LocalShapeInfo___destroy___0=function(){return(Mj=b._emscripten_bind_LocalShapeInfo___destroy___0=b.asm.Lh).apply(null,arguments)},Nj=b._emscripten_bind_btRigidBody_btRigidBody_1=function(){return(Nj=b._emscripten_bind_btRigidBody_btRigidBody_1=
-b.asm.Mh).apply(null,arguments)},Oj=b._emscripten_bind_btRigidBody_getCenterOfMassTransform_0=function(){return(Oj=b._emscripten_bind_btRigidBody_getCenterOfMassTransform_0=b.asm.Nh).apply(null,arguments)},Pj=b._emscripten_bind_btRigidBody_setCenterOfMassTransform_1=function(){return(Pj=b._emscripten_bind_btRigidBody_setCenterOfMassTransform_1=b.asm.Oh).apply(null,arguments)},Qj=b._emscripten_bind_btRigidBody_setSleepingThresholds_2=function(){return(Qj=b._emscripten_bind_btRigidBody_setSleepingThresholds_2=
-b.asm.Ph).apply(null,arguments)},Rj=b._emscripten_bind_btRigidBody_getLinearDamping_0=function(){return(Rj=b._emscripten_bind_btRigidBody_getLinearDamping_0=b.asm.Qh).apply(null,arguments)},Sj=b._emscripten_bind_btRigidBody_getAngularDamping_0=function(){return(Sj=b._emscripten_bind_btRigidBody_getAngularDamping_0=b.asm.Rh).apply(null,arguments)},Tj=b._emscripten_bind_btRigidBody_setDamping_2=function(){return(Tj=b._emscripten_bind_btRigidBody_setDamping_2=b.asm.Sh).apply(null,arguments)},Uj=b._emscripten_bind_btRigidBody_setMassProps_2=
-function(){return(Uj=b._emscripten_bind_btRigidBody_setMassProps_2=b.asm.Th).apply(null,arguments)},Vj=b._emscripten_bind_btRigidBody_getLinearFactor_0=function(){return(Vj=b._emscripten_bind_btRigidBody_getLinearFactor_0=b.asm.Uh).apply(null,arguments)},Wj=b._emscripten_bind_btRigidBody_setLinearFactor_1=function(){return(Wj=b._emscripten_bind_btRigidBody_setLinearFactor_1=b.asm.Vh).apply(null,arguments)},Xj=b._emscripten_bind_btRigidBody_applyTorque_1=function(){return(Xj=b._emscripten_bind_btRigidBody_applyTorque_1=
-b.asm.Wh).apply(null,arguments)},Yj=b._emscripten_bind_btRigidBody_applyLocalTorque_1=function(){return(Yj=b._emscripten_bind_btRigidBody_applyLocalTorque_1=b.asm.Xh).apply(null,arguments)},Zj=b._emscripten_bind_btRigidBody_applyForce_2=function(){return(Zj=b._emscripten_bind_btRigidBody_applyForce_2=b.asm.Yh).apply(null,arguments)},ak=b._emscripten_bind_btRigidBody_applyCentralForce_1=function(){return(ak=b._emscripten_bind_btRigidBody_applyCentralForce_1=b.asm.Zh).apply(null,arguments)},bk=b._emscripten_bind_btRigidBody_applyCentralLocalForce_1=
-function(){return(bk=b._emscripten_bind_btRigidBody_applyCentralLocalForce_1=b.asm._h).apply(null,arguments)},ck=b._emscripten_bind_btRigidBody_applyTorqueImpulse_1=function(){return(ck=b._emscripten_bind_btRigidBody_applyTorqueImpulse_1=b.asm.$h).apply(null,arguments)},dk=b._emscripten_bind_btRigidBody_applyImpulse_2=function(){return(dk=b._emscripten_bind_btRigidBody_applyImpulse_2=b.asm.ai).apply(null,arguments)},ek=b._emscripten_bind_btRigidBody_applyCentralImpulse_1=function(){return(ek=b._emscripten_bind_btRigidBody_applyCentralImpulse_1=
-b.asm.bi).apply(null,arguments)},fk=b._emscripten_bind_btRigidBody_updateInertiaTensor_0=function(){return(fk=b._emscripten_bind_btRigidBody_updateInertiaTensor_0=b.asm.ci).apply(null,arguments)},gk=b._emscripten_bind_btRigidBody_getLinearVelocity_0=function(){return(gk=b._emscripten_bind_btRigidBody_getLinearVelocity_0=b.asm.di).apply(null,arguments)},hk=b._emscripten_bind_btRigidBody_getAngularVelocity_0=function(){return(hk=b._emscripten_bind_btRigidBody_getAngularVelocity_0=b.asm.ei).apply(null,
-arguments)},ik=b._emscripten_bind_btRigidBody_setLinearVelocity_1=function(){return(ik=b._emscripten_bind_btRigidBody_setLinearVelocity_1=b.asm.fi).apply(null,arguments)},jk=b._emscripten_bind_btRigidBody_setAngularVelocity_1=function(){return(jk=b._emscripten_bind_btRigidBody_setAngularVelocity_1=b.asm.gi).apply(null,arguments)},kk=b._emscripten_bind_btRigidBody_getMotionState_0=function(){return(kk=b._emscripten_bind_btRigidBody_getMotionState_0=b.asm.hi).apply(null,arguments)},lk=b._emscripten_bind_btRigidBody_setMotionState_1=
-function(){return(lk=b._emscripten_bind_btRigidBody_setMotionState_1=b.asm.ii).apply(null,arguments)},mk=b._emscripten_bind_btRigidBody_getAngularFactor_0=function(){return(mk=b._emscripten_bind_btRigidBody_getAngularFactor_0=b.asm.ji).apply(null,arguments)},nk=b._emscripten_bind_btRigidBody_setAngularFactor_1=function(){return(nk=b._emscripten_bind_btRigidBody_setAngularFactor_1=b.asm.ki).apply(null,arguments)},ok=b._emscripten_bind_btRigidBody_upcast_1=function(){return(ok=b._emscripten_bind_btRigidBody_upcast_1=
-b.asm.li).apply(null,arguments)},pk=b._emscripten_bind_btRigidBody_getAabb_2=function(){return(pk=b._emscripten_bind_btRigidBody_getAabb_2=b.asm.mi).apply(null,arguments)},qk=b._emscripten_bind_btRigidBody_applyGravity_0=function(){return(qk=b._emscripten_bind_btRigidBody_applyGravity_0=b.asm.ni).apply(null,arguments)},rk=b._emscripten_bind_btRigidBody_getGravity_0=function(){return(rk=b._emscripten_bind_btRigidBody_getGravity_0=b.asm.oi).apply(null,arguments)},sk=b._emscripten_bind_btRigidBody_setGravity_1=
-function(){return(sk=b._emscripten_bind_btRigidBody_setGravity_1=b.asm.pi).apply(null,arguments)},tk=b._emscripten_bind_btRigidBody_getBroadphaseProxy_0=function(){return(tk=b._emscripten_bind_btRigidBody_getBroadphaseProxy_0=b.asm.qi).apply(null,arguments)},uk=b._emscripten_bind_btRigidBody_clearForces_0=function(){return(uk=b._emscripten_bind_btRigidBody_clearForces_0=b.asm.ri).apply(null,arguments)},vk=b._emscripten_bind_btRigidBody_setAnisotropicFriction_2=function(){return(vk=b._emscripten_bind_btRigidBody_setAnisotropicFriction_2=
-b.asm.si).apply(null,arguments)},wk=b._emscripten_bind_btRigidBody_getCollisionShape_0=function(){return(wk=b._emscripten_bind_btRigidBody_getCollisionShape_0=b.asm.ti).apply(null,arguments)},xk=b._emscripten_bind_btRigidBody_setContactProcessingThreshold_1=function(){return(xk=b._emscripten_bind_btRigidBody_setContactProcessingThreshold_1=b.asm.ui).apply(null,arguments)},yk=b._emscripten_bind_btRigidBody_setActivationState_1=function(){return(yk=b._emscripten_bind_btRigidBody_setActivationState_1=
-b.asm.vi).apply(null,arguments)},zk=b._emscripten_bind_btRigidBody_forceActivationState_1=function(){return(zk=b._emscripten_bind_btRigidBody_forceActivationState_1=b.asm.wi).apply(null,arguments)},Ak=b._emscripten_bind_btRigidBody_activate_0=function(){return(Ak=b._emscripten_bind_btRigidBody_activate_0=b.asm.xi).apply(null,arguments)},Bk=b._emscripten_bind_btRigidBody_activate_1=function(){return(Bk=b._emscripten_bind_btRigidBody_activate_1=b.asm.yi).apply(null,arguments)},Ck=b._emscripten_bind_btRigidBody_isActive_0=
-function(){return(Ck=b._emscripten_bind_btRigidBody_isActive_0=b.asm.zi).apply(null,arguments)},Dk=b._emscripten_bind_btRigidBody_isKinematicObject_0=function(){return(Dk=b._emscripten_bind_btRigidBody_isKinematicObject_0=b.asm.Ai).apply(null,arguments)},Ek=b._emscripten_bind_btRigidBody_isStaticObject_0=function(){return(Ek=b._emscripten_bind_btRigidBody_isStaticObject_0=b.asm.Bi).apply(null,arguments)},Fk=b._emscripten_bind_btRigidBody_isStaticOrKinematicObject_0=function(){return(Fk=b._emscripten_bind_btRigidBody_isStaticOrKinematicObject_0=
-b.asm.Ci).apply(null,arguments)},Gk=b._emscripten_bind_btRigidBody_getRestitution_0=function(){return(Gk=b._emscripten_bind_btRigidBody_getRestitution_0=b.asm.Di).apply(null,arguments)},Hk=b._emscripten_bind_btRigidBody_getFriction_0=function(){return(Hk=b._emscripten_bind_btRigidBody_getFriction_0=b.asm.Ei).apply(null,arguments)},Ik=b._emscripten_bind_btRigidBody_getRollingFriction_0=function(){return(Ik=b._emscripten_bind_btRigidBody_getRollingFriction_0=b.asm.Fi).apply(null,arguments)},Jk=b._emscripten_bind_btRigidBody_setRestitution_1=
-function(){return(Jk=b._emscripten_bind_btRigidBody_setRestitution_1=b.asm.Gi).apply(null,arguments)},Kk=b._emscripten_bind_btRigidBody_setFriction_1=function(){return(Kk=b._emscripten_bind_btRigidBody_setFriction_1=b.asm.Hi).apply(null,arguments)},Lk=b._emscripten_bind_btRigidBody_setRollingFriction_1=function(){return(Lk=b._emscripten_bind_btRigidBody_setRollingFriction_1=b.asm.Ii).apply(null,arguments)},Mk=b._emscripten_bind_btRigidBody_getWorldTransform_0=function(){return(Mk=b._emscripten_bind_btRigidBody_getWorldTransform_0=
-b.asm.Ji).apply(null,arguments)},Nk=b._emscripten_bind_btRigidBody_getCollisionFlags_0=function(){return(Nk=b._emscripten_bind_btRigidBody_getCollisionFlags_0=b.asm.Ki).apply(null,arguments)},Ok=b._emscripten_bind_btRigidBody_setCollisionFlags_1=function(){return(Ok=b._emscripten_bind_btRigidBody_setCollisionFlags_1=b.asm.Li).apply(null,arguments)},Pk=b._emscripten_bind_btRigidBody_setWorldTransform_1=function(){return(Pk=b._emscripten_bind_btRigidBody_setWorldTransform_1=b.asm.Mi).apply(null,arguments)},
-Qk=b._emscripten_bind_btRigidBody_setCollisionShape_1=function(){return(Qk=b._emscripten_bind_btRigidBody_setCollisionShape_1=b.asm.Ni).apply(null,arguments)},Rk=b._emscripten_bind_btRigidBody_setCcdMotionThreshold_1=function(){return(Rk=b._emscripten_bind_btRigidBody_setCcdMotionThreshold_1=b.asm.Oi).apply(null,arguments)},Sk=b._emscripten_bind_btRigidBody_setCcdSweptSphereRadius_1=function(){return(Sk=b._emscripten_bind_btRigidBody_setCcdSweptSphereRadius_1=b.asm.Pi).apply(null,arguments)},Tk=b._emscripten_bind_btRigidBody_getUserIndex_0=
-function(){return(Tk=b._emscripten_bind_btRigidBody_getUserIndex_0=b.asm.Qi).apply(null,arguments)},Uk=b._emscripten_bind_btRigidBody_setUserIndex_1=function(){return(Uk=b._emscripten_bind_btRigidBody_setUserIndex_1=b.asm.Ri).apply(null,arguments)},Vk=b._emscripten_bind_btRigidBody_getUserPointer_0=function(){return(Vk=b._emscripten_bind_btRigidBody_getUserPointer_0=b.asm.Si).apply(null,arguments)},Wk=b._emscripten_bind_btRigidBody_setUserPointer_1=function(){return(Wk=b._emscripten_bind_btRigidBody_setUserPointer_1=
-b.asm.Ti).apply(null,arguments)},Xk=b._emscripten_bind_btRigidBody_getBroadphaseHandle_0=function(){return(Xk=b._emscripten_bind_btRigidBody_getBroadphaseHandle_0=b.asm.Ui).apply(null,arguments)},Yk=b._emscripten_bind_btRigidBody___destroy___0=function(){return(Yk=b._emscripten_bind_btRigidBody___destroy___0=b.asm.Vi).apply(null,arguments)},Zk=b._emscripten_bind_btIndexedMeshArray_size_0=function(){return(Zk=b._emscripten_bind_btIndexedMeshArray_size_0=b.asm.Wi).apply(null,arguments)},$k=b._emscripten_bind_btIndexedMeshArray_at_1=
-function(){return($k=b._emscripten_bind_btIndexedMeshArray_at_1=b.asm.Xi).apply(null,arguments)},al=b._emscripten_bind_btIndexedMeshArray___destroy___0=function(){return(al=b._emscripten_bind_btIndexedMeshArray___destroy___0=b.asm.Yi).apply(null,arguments)},bl=b._emscripten_bind_btDbvtBroadphase_btDbvtBroadphase_0=function(){return(bl=b._emscripten_bind_btDbvtBroadphase_btDbvtBroadphase_0=b.asm.Zi).apply(null,arguments)},cl=b._emscripten_bind_btDbvtBroadphase___destroy___0=function(){return(cl=b._emscripten_bind_btDbvtBroadphase___destroy___0=
-b.asm._i).apply(null,arguments)},dl=b._emscripten_bind_btHeightfieldTerrainShape_btHeightfieldTerrainShape_9=function(){return(dl=b._emscripten_bind_btHeightfieldTerrainShape_btHeightfieldTerrainShape_9=b.asm.$i).apply(null,arguments)},el=b._emscripten_bind_btHeightfieldTerrainShape_setMargin_1=function(){return(el=b._emscripten_bind_btHeightfieldTerrainShape_setMargin_1=b.asm.aj).apply(null,arguments)},fl=b._emscripten_bind_btHeightfieldTerrainShape_getMargin_0=function(){return(fl=b._emscripten_bind_btHeightfieldTerrainShape_getMargin_0=
-b.asm.bj).apply(null,arguments)},gl=b._emscripten_bind_btHeightfieldTerrainShape_setLocalScaling_1=function(){return(gl=b._emscripten_bind_btHeightfieldTerrainShape_setLocalScaling_1=b.asm.cj).apply(null,arguments)},hl=b._emscripten_bind_btHeightfieldTerrainShape_getLocalScaling_0=function(){return(hl=b._emscripten_bind_btHeightfieldTerrainShape_getLocalScaling_0=b.asm.dj).apply(null,arguments)},il=b._emscripten_bind_btHeightfieldTerrainShape_calculateLocalInertia_2=function(){return(il=b._emscripten_bind_btHeightfieldTerrainShape_calculateLocalInertia_2=
-b.asm.ej).apply(null,arguments)},jl=b._emscripten_bind_btHeightfieldTerrainShape___destroy___0=function(){return(jl=b._emscripten_bind_btHeightfieldTerrainShape___destroy___0=b.asm.fj).apply(null,arguments)},kl=b._emscripten_bind_btDefaultSoftBodySolver_btDefaultSoftBodySolver_0=function(){return(kl=b._emscripten_bind_btDefaultSoftBodySolver_btDefaultSoftBodySolver_0=b.asm.gj).apply(null,arguments)},ll=b._emscripten_bind_btDefaultSoftBodySolver___destroy___0=function(){return(ll=b._emscripten_bind_btDefaultSoftBodySolver___destroy___0=
-b.asm.hj).apply(null,arguments)},ml=b._emscripten_bind_btCollisionDispatcher_btCollisionDispatcher_1=function(){return(ml=b._emscripten_bind_btCollisionDispatcher_btCollisionDispatcher_1=b.asm.ij).apply(null,arguments)},nl=b._emscripten_bind_btCollisionDispatcher_getNumManifolds_0=function(){return(nl=b._emscripten_bind_btCollisionDispatcher_getNumManifolds_0=b.asm.jj).apply(null,arguments)},ol=b._emscripten_bind_btCollisionDispatcher_getManifoldByIndexInternal_1=function(){return(ol=b._emscripten_bind_btCollisionDispatcher_getManifoldByIndexInternal_1=
-b.asm.kj).apply(null,arguments)},pl=b._emscripten_bind_btCollisionDispatcher___destroy___0=function(){return(pl=b._emscripten_bind_btCollisionDispatcher___destroy___0=b.asm.lj).apply(null,arguments)},ql=b._emscripten_bind_btAxisSweep3_btAxisSweep3_2=function(){return(ql=b._emscripten_bind_btAxisSweep3_btAxisSweep3_2=b.asm.mj).apply(null,arguments)},rl=b._emscripten_bind_btAxisSweep3_btAxisSweep3_3=function(){return(rl=b._emscripten_bind_btAxisSweep3_btAxisSweep3_3=b.asm.nj).apply(null,arguments)},
-sl=b._emscripten_bind_btAxisSweep3_btAxisSweep3_4=function(){return(sl=b._emscripten_bind_btAxisSweep3_btAxisSweep3_4=b.asm.oj).apply(null,arguments)},tl=b._emscripten_bind_btAxisSweep3_btAxisSweep3_5=function(){return(tl=b._emscripten_bind_btAxisSweep3_btAxisSweep3_5=b.asm.pj).apply(null,arguments)},ul=b._emscripten_bind_btAxisSweep3___destroy___0=function(){return(ul=b._emscripten_bind_btAxisSweep3___destroy___0=b.asm.qj).apply(null,arguments)},vl=b._emscripten_bind_VoidPtr___destroy___0=function(){return(vl=
-b._emscripten_bind_VoidPtr___destroy___0=b.asm.rj).apply(null,arguments)},wl=b._emscripten_bind_btSoftBodyWorldInfo_btSoftBodyWorldInfo_0=function(){return(wl=b._emscripten_bind_btSoftBodyWorldInfo_btSoftBodyWorldInfo_0=b.asm.sj).apply(null,arguments)},xl=b._emscripten_bind_btSoftBodyWorldInfo_get_air_density_0=function(){return(xl=b._emscripten_bind_btSoftBodyWorldInfo_get_air_density_0=b.asm.tj).apply(null,arguments)},yl=b._emscripten_bind_btSoftBodyWorldInfo_set_air_density_1=function(){return(yl=
-b._emscripten_bind_btSoftBodyWorldInfo_set_air_density_1=b.asm.uj).apply(null,arguments)},zl=b._emscripten_bind_btSoftBodyWorldInfo_get_water_density_0=function(){return(zl=b._emscripten_bind_btSoftBodyWorldInfo_get_water_density_0=b.asm.vj).apply(null,arguments)},Al=b._emscripten_bind_btSoftBodyWorldInfo_set_water_density_1=function(){return(Al=b._emscripten_bind_btSoftBodyWorldInfo_set_water_density_1=b.asm.wj).apply(null,arguments)},Bl=b._emscripten_bind_btSoftBodyWorldInfo_get_water_offset_0=
-function(){return(Bl=b._emscripten_bind_btSoftBodyWorldInfo_get_water_offset_0=b.asm.xj).apply(null,arguments)},Cl=b._emscripten_bind_btSoftBodyWorldInfo_set_water_offset_1=function(){return(Cl=b._emscripten_bind_btSoftBodyWorldInfo_set_water_offset_1=b.asm.yj).apply(null,arguments)},Dl=b._emscripten_bind_btSoftBodyWorldInfo_get_m_maxDisplacement_0=function(){return(Dl=b._emscripten_bind_btSoftBodyWorldInfo_get_m_maxDisplacement_0=b.asm.zj).apply(null,arguments)},El=b._emscripten_bind_btSoftBodyWorldInfo_set_m_maxDisplacement_1=
-function(){return(El=b._emscripten_bind_btSoftBodyWorldInfo_set_m_maxDisplacement_1=b.asm.Aj).apply(null,arguments)},Fl=b._emscripten_bind_btSoftBodyWorldInfo_get_water_normal_0=function(){return(Fl=b._emscripten_bind_btSoftBodyWorldInfo_get_water_normal_0=b.asm.Bj).apply(null,arguments)},Gl=b._emscripten_bind_btSoftBodyWorldInfo_set_water_normal_1=function(){return(Gl=b._emscripten_bind_btSoftBodyWorldInfo_set_water_normal_1=b.asm.Cj).apply(null,arguments)},Hl=b._emscripten_bind_btSoftBodyWorldInfo_get_m_broadphase_0=
-function(){return(Hl=b._emscripten_bind_btSoftBodyWorldInfo_get_m_broadphase_0=b.asm.Dj).apply(null,arguments)},Il=b._emscripten_bind_btSoftBodyWorldInfo_set_m_broadphase_1=function(){return(Il=b._emscripten_bind_btSoftBodyWorldInfo_set_m_broadphase_1=b.asm.Ej).apply(null,arguments)},Jl=b._emscripten_bind_btSoftBodyWorldInfo_get_m_dispatcher_0=function(){return(Jl=b._emscripten_bind_btSoftBodyWorldInfo_get_m_dispatcher_0=b.asm.Fj).apply(null,arguments)},Kl=b._emscripten_bind_btSoftBodyWorldInfo_set_m_dispatcher_1=
-function(){return(Kl=b._emscripten_bind_btSoftBodyWorldInfo_set_m_dispatcher_1=b.asm.Gj).apply(null,arguments)},Ll=b._emscripten_bind_btSoftBodyWorldInfo_get_m_gravity_0=function(){return(Ll=b._emscripten_bind_btSoftBodyWorldInfo_get_m_gravity_0=b.asm.Hj).apply(null,arguments)},Ml=b._emscripten_bind_btSoftBodyWorldInfo_set_m_gravity_1=function(){return(Ml=b._emscripten_bind_btSoftBodyWorldInfo_set_m_gravity_1=b.asm.Ij).apply(null,arguments)},Nl=b._emscripten_bind_btSoftBodyWorldInfo___destroy___0=
-function(){return(Nl=b._emscripten_bind_btSoftBodyWorldInfo___destroy___0=b.asm.Jj).apply(null,arguments)},Ol=b._emscripten_bind_btConeTwistConstraint_btConeTwistConstraint_2=function(){return(Ol=b._emscripten_bind_btConeTwistConstraint_btConeTwistConstraint_2=b.asm.Kj).apply(null,arguments)},Pl=b._emscripten_bind_btConeTwistConstraint_btConeTwistConstraint_4=function(){return(Pl=b._emscripten_bind_btConeTwistConstraint_btConeTwistConstraint_4=b.asm.Lj).apply(null,arguments)},Ql=b._emscripten_bind_btConeTwistConstraint_setLimit_2=
-function(){return(Ql=b._emscripten_bind_btConeTwistConstraint_setLimit_2=b.asm.Mj).apply(null,arguments)},Rl=b._emscripten_bind_btConeTwistConstraint_setAngularOnly_1=function(){return(Rl=b._emscripten_bind_btConeTwistConstraint_setAngularOnly_1=b.asm.Nj).apply(null,arguments)},Sl=b._emscripten_bind_btConeTwistConstraint_setDamping_1=function(){return(Sl=b._emscripten_bind_btConeTwistConstraint_setDamping_1=b.asm.Oj).apply(null,arguments)},Tl=b._emscripten_bind_btConeTwistConstraint_enableMotor_1=
-function(){return(Tl=b._emscripten_bind_btConeTwistConstraint_enableMotor_1=b.asm.Pj).apply(null,arguments)},Ul=b._emscripten_bind_btConeTwistConstraint_setMaxMotorImpulse_1=function(){return(Ul=b._emscripten_bind_btConeTwistConstraint_setMaxMotorImpulse_1=b.asm.Qj).apply(null,arguments)},Vl=b._emscripten_bind_btConeTwistConstraint_setMaxMotorImpulseNormalized_1=function(){return(Vl=b._emscripten_bind_btConeTwistConstraint_setMaxMotorImpulseNormalized_1=b.asm.Rj).apply(null,arguments)},Wl=b._emscripten_bind_btConeTwistConstraint_setMotorTarget_1=
-function(){return(Wl=b._emscripten_bind_btConeTwistConstraint_setMotorTarget_1=b.asm.Sj).apply(null,arguments)},Xl=b._emscripten_bind_btConeTwistConstraint_setMotorTargetInConstraintSpace_1=function(){return(Xl=b._emscripten_bind_btConeTwistConstraint_setMotorTargetInConstraintSpace_1=b.asm.Tj).apply(null,arguments)},Yl=b._emscripten_bind_btConeTwistConstraint_enableFeedback_1=function(){return(Yl=b._emscripten_bind_btConeTwistConstraint_enableFeedback_1=b.asm.Uj).apply(null,arguments)},Zl=b._emscripten_bind_btConeTwistConstraint_getBreakingImpulseThreshold_0=
-function(){return(Zl=b._emscripten_bind_btConeTwistConstraint_getBreakingImpulseThreshold_0=b.asm.Vj).apply(null,arguments)},$l=b._emscripten_bind_btConeTwistConstraint_setBreakingImpulseThreshold_1=function(){return($l=b._emscripten_bind_btConeTwistConstraint_setBreakingImpulseThreshold_1=b.asm.Wj).apply(null,arguments)},am=b._emscripten_bind_btConeTwistConstraint_getParam_2=function(){return(am=b._emscripten_bind_btConeTwistConstraint_getParam_2=b.asm.Xj).apply(null,arguments)},bm=b._emscripten_bind_btConeTwistConstraint_setParam_3=
-function(){return(bm=b._emscripten_bind_btConeTwistConstraint_setParam_3=b.asm.Yj).apply(null,arguments)},cm=b._emscripten_bind_btConeTwistConstraint___destroy___0=function(){return(cm=b._emscripten_bind_btConeTwistConstraint___destroy___0=b.asm.Zj).apply(null,arguments)},dm=b._emscripten_bind_btHingeConstraint_btHingeConstraint_2=function(){return(dm=b._emscripten_bind_btHingeConstraint_btHingeConstraint_2=b.asm._j).apply(null,arguments)},em=b._emscripten_bind_btHingeConstraint_btHingeConstraint_3=
-function(){return(em=b._emscripten_bind_btHingeConstraint_btHingeConstraint_3=b.asm.$j).apply(null,arguments)},fm=b._emscripten_bind_btHingeConstraint_btHingeConstraint_4=function(){return(fm=b._emscripten_bind_btHingeConstraint_btHingeConstraint_4=b.asm.ak).apply(null,arguments)},gm=b._emscripten_bind_btHingeConstraint_btHingeConstraint_5=function(){return(gm=b._emscripten_bind_btHingeConstraint_btHingeConstraint_5=b.asm.bk).apply(null,arguments)},hm=b._emscripten_bind_btHingeConstraint_btHingeConstraint_6=
-function(){return(hm=b._emscripten_bind_btHingeConstraint_btHingeConstraint_6=b.asm.ck).apply(null,arguments)},im=b._emscripten_bind_btHingeConstraint_btHingeConstraint_7=function(){return(im=b._emscripten_bind_btHingeConstraint_btHingeConstraint_7=b.asm.dk).apply(null,arguments)},jm=b._emscripten_bind_btHingeConstraint_setLimit_4=function(){return(jm=b._emscripten_bind_btHingeConstraint_setLimit_4=b.asm.ek).apply(null,arguments)},km=b._emscripten_bind_btHingeConstraint_setLimit_5=function(){return(km=
-b._emscripten_bind_btHingeConstraint_setLimit_5=b.asm.fk).apply(null,arguments)},lm=b._emscripten_bind_btHingeConstraint_enableAngularMotor_3=function(){return(lm=b._emscripten_bind_btHingeConstraint_enableAngularMotor_3=b.asm.gk).apply(null,arguments)},mm=b._emscripten_bind_btHingeConstraint_setAngularOnly_1=function(){return(mm=b._emscripten_bind_btHingeConstraint_setAngularOnly_1=b.asm.hk).apply(null,arguments)},nm=b._emscripten_bind_btHingeConstraint_enableMotor_1=function(){return(nm=b._emscripten_bind_btHingeConstraint_enableMotor_1=
-b.asm.ik).apply(null,arguments)},om=b._emscripten_bind_btHingeConstraint_setMaxMotorImpulse_1=function(){return(om=b._emscripten_bind_btHingeConstraint_setMaxMotorImpulse_1=b.asm.jk).apply(null,arguments)},pm=b._emscripten_bind_btHingeConstraint_setMotorTarget_2=function(){return(pm=b._emscripten_bind_btHingeConstraint_setMotorTarget_2=b.asm.kk).apply(null,arguments)},qm=b._emscripten_bind_btHingeConstraint_enableFeedback_1=function(){return(qm=b._emscripten_bind_btHingeConstraint_enableFeedback_1=
-b.asm.lk).apply(null,arguments)},rm=b._emscripten_bind_btHingeConstraint_getBreakingImpulseThreshold_0=function(){return(rm=b._emscripten_bind_btHingeConstraint_getBreakingImpulseThreshold_0=b.asm.mk).apply(null,arguments)},sm=b._emscripten_bind_btHingeConstraint_setBreakingImpulseThreshold_1=function(){return(sm=b._emscripten_bind_btHingeConstraint_setBreakingImpulseThreshold_1=b.asm.nk).apply(null,arguments)},tm=b._emscripten_bind_btHingeConstraint_getParam_2=function(){return(tm=b._emscripten_bind_btHingeConstraint_getParam_2=
-b.asm.ok).apply(null,arguments)},um=b._emscripten_bind_btHingeConstraint_setParam_3=function(){return(um=b._emscripten_bind_btHingeConstraint_setParam_3=b.asm.pk).apply(null,arguments)},wm=b._emscripten_bind_btHingeConstraint___destroy___0=function(){return(wm=b._emscripten_bind_btHingeConstraint___destroy___0=b.asm.qk).apply(null,arguments)},xm=b._emscripten_bind_btConeShapeZ_btConeShapeZ_2=function(){return(xm=b._emscripten_bind_btConeShapeZ_btConeShapeZ_2=b.asm.rk).apply(null,arguments)},ym=b._emscripten_bind_btConeShapeZ_setLocalScaling_1=
-function(){return(ym=b._emscripten_bind_btConeShapeZ_setLocalScaling_1=b.asm.sk).apply(null,arguments)},zm=b._emscripten_bind_btConeShapeZ_getLocalScaling_0=function(){return(zm=b._emscripten_bind_btConeShapeZ_getLocalScaling_0=b.asm.tk).apply(null,arguments)},Am=b._emscripten_bind_btConeShapeZ_calculateLocalInertia_2=function(){return(Am=b._emscripten_bind_btConeShapeZ_calculateLocalInertia_2=b.asm.uk).apply(null,arguments)},Bm=b._emscripten_bind_btConeShapeZ___destroy___0=function(){return(Bm=b._emscripten_bind_btConeShapeZ___destroy___0=
-b.asm.vk).apply(null,arguments)},Cm=b._emscripten_bind_btConeShapeX_btConeShapeX_2=function(){return(Cm=b._emscripten_bind_btConeShapeX_btConeShapeX_2=b.asm.wk).apply(null,arguments)},Dm=b._emscripten_bind_btConeShapeX_setLocalScaling_1=function(){return(Dm=b._emscripten_bind_btConeShapeX_setLocalScaling_1=b.asm.xk).apply(null,arguments)},Em=b._emscripten_bind_btConeShapeX_getLocalScaling_0=function(){return(Em=b._emscripten_bind_btConeShapeX_getLocalScaling_0=b.asm.yk).apply(null,arguments)},Fm=
-b._emscripten_bind_btConeShapeX_calculateLocalInertia_2=function(){return(Fm=b._emscripten_bind_btConeShapeX_calculateLocalInertia_2=b.asm.zk).apply(null,arguments)},Gm=b._emscripten_bind_btConeShapeX___destroy___0=function(){return(Gm=b._emscripten_bind_btConeShapeX___destroy___0=b.asm.Ak).apply(null,arguments)},Hm=b._emscripten_bind_btTriangleMesh_btTriangleMesh_0=function(){return(Hm=b._emscripten_bind_btTriangleMesh_btTriangleMesh_0=b.asm.Bk).apply(null,arguments)},Im=b._emscripten_bind_btTriangleMesh_btTriangleMesh_1=
-function(){return(Im=b._emscripten_bind_btTriangleMesh_btTriangleMesh_1=b.asm.Ck).apply(null,arguments)},Jm=b._emscripten_bind_btTriangleMesh_btTriangleMesh_2=function(){return(Jm=b._emscripten_bind_btTriangleMesh_btTriangleMesh_2=b.asm.Dk).apply(null,arguments)},Km=b._emscripten_bind_btTriangleMesh_addTriangle_3=function(){return(Km=b._emscripten_bind_btTriangleMesh_addTriangle_3=b.asm.Ek).apply(null,arguments)},Lm=b._emscripten_bind_btTriangleMesh_addTriangle_4=function(){return(Lm=b._emscripten_bind_btTriangleMesh_addTriangle_4=
-b.asm.Fk).apply(null,arguments)},Mm=b._emscripten_bind_btTriangleMesh_findOrAddVertex_2=function(){return(Mm=b._emscripten_bind_btTriangleMesh_findOrAddVertex_2=b.asm.Gk).apply(null,arguments)},Nm=b._emscripten_bind_btTriangleMesh_addIndex_1=function(){return(Nm=b._emscripten_bind_btTriangleMesh_addIndex_1=b.asm.Hk).apply(null,arguments)},Om=b._emscripten_bind_btTriangleMesh_getIndexedMeshArray_0=function(){return(Om=b._emscripten_bind_btTriangleMesh_getIndexedMeshArray_0=b.asm.Ik).apply(null,arguments)},
-Pm=b._emscripten_bind_btTriangleMesh_setScaling_1=function(){return(Pm=b._emscripten_bind_btTriangleMesh_setScaling_1=b.asm.Jk).apply(null,arguments)},Qm=b._emscripten_bind_btTriangleMesh___destroy___0=function(){return(Qm=b._emscripten_bind_btTriangleMesh___destroy___0=b.asm.Kk).apply(null,arguments)},Rm=b._emscripten_bind_btConvexHullShape_btConvexHullShape_0=function(){return(Rm=b._emscripten_bind_btConvexHullShape_btConvexHullShape_0=b.asm.Lk).apply(null,arguments)},Sm=b._emscripten_bind_btConvexHullShape_btConvexHullShape_1=
-function(){return(Sm=b._emscripten_bind_btConvexHullShape_btConvexHullShape_1=b.asm.Mk).apply(null,arguments)},Tm=b._emscripten_bind_btConvexHullShape_btConvexHullShape_2=function(){return(Tm=b._emscripten_bind_btConvexHullShape_btConvexHullShape_2=b.asm.Nk).apply(null,arguments)},Um=b._emscripten_bind_btConvexHullShape_addPoint_1=function(){return(Um=b._emscripten_bind_btConvexHullShape_addPoint_1=b.asm.Ok).apply(null,arguments)},Vm=b._emscripten_bind_btConvexHullShape_addPoint_2=function(){return(Vm=
-b._emscripten_bind_btConvexHullShape_addPoint_2=b.asm.Pk).apply(null,arguments)},Wm=b._emscripten_bind_btConvexHullShape_setMargin_1=function(){return(Wm=b._emscripten_bind_btConvexHullShape_setMargin_1=b.asm.Qk).apply(null,arguments)},Xm=b._emscripten_bind_btConvexHullShape_getMargin_0=function(){return(Xm=b._emscripten_bind_btConvexHullShape_getMargin_0=b.asm.Rk).apply(null,arguments)},Ym=b._emscripten_bind_btConvexHullShape_getNumVertices_0=function(){return(Ym=b._emscripten_bind_btConvexHullShape_getNumVertices_0=
-b.asm.Sk).apply(null,arguments)},Zm=b._emscripten_bind_btConvexHullShape_initializePolyhedralFeatures_1=function(){return(Zm=b._emscripten_bind_btConvexHullShape_initializePolyhedralFeatures_1=b.asm.Tk).apply(null,arguments)},$m=b._emscripten_bind_btConvexHullShape_recalcLocalAabb_0=function(){return($m=b._emscripten_bind_btConvexHullShape_recalcLocalAabb_0=b.asm.Uk).apply(null,arguments)},an=b._emscripten_bind_btConvexHullShape_getConvexPolyhedron_0=function(){return(an=b._emscripten_bind_btConvexHullShape_getConvexPolyhedron_0=
-b.asm.Vk).apply(null,arguments)},bn=b._emscripten_bind_btConvexHullShape_setLocalScaling_1=function(){return(bn=b._emscripten_bind_btConvexHullShape_setLocalScaling_1=b.asm.Wk).apply(null,arguments)},cn=b._emscripten_bind_btConvexHullShape_getLocalScaling_0=function(){return(cn=b._emscripten_bind_btConvexHullShape_getLocalScaling_0=b.asm.Xk).apply(null,arguments)},dn=b._emscripten_bind_btConvexHullShape_calculateLocalInertia_2=function(){return(dn=b._emscripten_bind_btConvexHullShape_calculateLocalInertia_2=
-b.asm.Yk).apply(null,arguments)},en=b._emscripten_bind_btConvexHullShape___destroy___0=function(){return(en=b._emscripten_bind_btConvexHullShape___destroy___0=b.asm.Zk).apply(null,arguments)},fn=b._emscripten_bind_btVehicleTuning_btVehicleTuning_0=function(){return(fn=b._emscripten_bind_btVehicleTuning_btVehicleTuning_0=b.asm._k).apply(null,arguments)},gn=b._emscripten_bind_btVehicleTuning_get_m_suspensionStiffness_0=function(){return(gn=b._emscripten_bind_btVehicleTuning_get_m_suspensionStiffness_0=
-b.asm.$k).apply(null,arguments)},hn=b._emscripten_bind_btVehicleTuning_set_m_suspensionStiffness_1=function(){return(hn=b._emscripten_bind_btVehicleTuning_set_m_suspensionStiffness_1=b.asm.al).apply(null,arguments)},jn=b._emscripten_bind_btVehicleTuning_get_m_suspensionCompression_0=function(){return(jn=b._emscripten_bind_btVehicleTuning_get_m_suspensionCompression_0=b.asm.bl).apply(null,arguments)},kn=b._emscripten_bind_btVehicleTuning_set_m_suspensionCompression_1=function(){return(kn=b._emscripten_bind_btVehicleTuning_set_m_suspensionCompression_1=
-b.asm.cl).apply(null,arguments)},ln=b._emscripten_bind_btVehicleTuning_get_m_suspensionDamping_0=function(){return(ln=b._emscripten_bind_btVehicleTuning_get_m_suspensionDamping_0=b.asm.dl).apply(null,arguments)},mn=b._emscripten_bind_btVehicleTuning_set_m_suspensionDamping_1=function(){return(mn=b._emscripten_bind_btVehicleTuning_set_m_suspensionDamping_1=b.asm.el).apply(null,arguments)},nn=b._emscripten_bind_btVehicleTuning_get_m_maxSuspensionTravelCm_0=function(){return(nn=b._emscripten_bind_btVehicleTuning_get_m_maxSuspensionTravelCm_0=
-b.asm.fl).apply(null,arguments)},on=b._emscripten_bind_btVehicleTuning_set_m_maxSuspensionTravelCm_1=function(){return(on=b._emscripten_bind_btVehicleTuning_set_m_maxSuspensionTravelCm_1=b.asm.gl).apply(null,arguments)},pn=b._emscripten_bind_btVehicleTuning_get_m_frictionSlip_0=function(){return(pn=b._emscripten_bind_btVehicleTuning_get_m_frictionSlip_0=b.asm.hl).apply(null,arguments)},qn=b._emscripten_bind_btVehicleTuning_set_m_frictionSlip_1=function(){return(qn=b._emscripten_bind_btVehicleTuning_set_m_frictionSlip_1=
-b.asm.il).apply(null,arguments)},rn=b._emscripten_bind_btVehicleTuning_get_m_maxSuspensionForce_0=function(){return(rn=b._emscripten_bind_btVehicleTuning_get_m_maxSuspensionForce_0=b.asm.jl).apply(null,arguments)},sn=b._emscripten_bind_btVehicleTuning_set_m_maxSuspensionForce_1=function(){return(sn=b._emscripten_bind_btVehicleTuning_set_m_maxSuspensionForce_1=b.asm.kl).apply(null,arguments)},tn=b._emscripten_bind_btCollisionObjectWrapper_getWorldTransform_0=function(){return(tn=b._emscripten_bind_btCollisionObjectWrapper_getWorldTransform_0=
-b.asm.ll).apply(null,arguments)},un=b._emscripten_bind_btCollisionObjectWrapper_getCollisionObject_0=function(){return(un=b._emscripten_bind_btCollisionObjectWrapper_getCollisionObject_0=b.asm.ml).apply(null,arguments)},vn=b._emscripten_bind_btCollisionObjectWrapper_getCollisionShape_0=function(){return(vn=b._emscripten_bind_btCollisionObjectWrapper_getCollisionShape_0=b.asm.nl).apply(null,arguments)},wn=b._emscripten_bind_btShapeHull_btShapeHull_1=function(){return(wn=b._emscripten_bind_btShapeHull_btShapeHull_1=
-b.asm.ol).apply(null,arguments)},xn=b._emscripten_bind_btShapeHull_buildHull_1=function(){return(xn=b._emscripten_bind_btShapeHull_buildHull_1=b.asm.pl).apply(null,arguments)},yn=b._emscripten_bind_btShapeHull_numVertices_0=function(){return(yn=b._emscripten_bind_btShapeHull_numVertices_0=b.asm.ql).apply(null,arguments)},zn=b._emscripten_bind_btShapeHull_getVertexPointer_0=function(){return(zn=b._emscripten_bind_btShapeHull_getVertexPointer_0=b.asm.rl).apply(null,arguments)},An=b._emscripten_bind_btShapeHull___destroy___0=
-function(){return(An=b._emscripten_bind_btShapeHull___destroy___0=b.asm.sl).apply(null,arguments)},Bn=b._emscripten_bind_btDefaultMotionState_btDefaultMotionState_0=function(){return(Bn=b._emscripten_bind_btDefaultMotionState_btDefaultMotionState_0=b.asm.tl).apply(null,arguments)},Cn=b._emscripten_bind_btDefaultMotionState_btDefaultMotionState_1=function(){return(Cn=b._emscripten_bind_btDefaultMotionState_btDefaultMotionState_1=b.asm.ul).apply(null,arguments)},Dn=b._emscripten_bind_btDefaultMotionState_btDefaultMotionState_2=
-function(){return(Dn=b._emscripten_bind_btDefaultMotionState_btDefaultMotionState_2=b.asm.vl).apply(null,arguments)},En=b._emscripten_bind_btDefaultMotionState_getWorldTransform_1=function(){return(En=b._emscripten_bind_btDefaultMotionState_getWorldTransform_1=b.asm.wl).apply(null,arguments)},Fn=b._emscripten_bind_btDefaultMotionState_setWorldTransform_1=function(){return(Fn=b._emscripten_bind_btDefaultMotionState_setWorldTransform_1=b.asm.xl).apply(null,arguments)},Gn=b._emscripten_bind_btDefaultMotionState_get_m_graphicsWorldTrans_0=
-function(){return(Gn=b._emscripten_bind_btDefaultMotionState_get_m_graphicsWorldTrans_0=b.asm.yl).apply(null,arguments)},Hn=b._emscripten_bind_btDefaultMotionState_set_m_graphicsWorldTrans_1=function(){return(Hn=b._emscripten_bind_btDefaultMotionState_set_m_graphicsWorldTrans_1=b.asm.zl).apply(null,arguments)},In=b._emscripten_bind_btDefaultMotionState___destroy___0=function(){return(In=b._emscripten_bind_btDefaultMotionState___destroy___0=b.asm.Al).apply(null,arguments)},Jn=b._emscripten_bind_btWheelInfo_btWheelInfo_1=
-function(){return(Jn=b._emscripten_bind_btWheelInfo_btWheelInfo_1=b.asm.Bl).apply(null,arguments)},Kn=b._emscripten_bind_btWheelInfo_getSuspensionRestLength_0=function(){return(Kn=b._emscripten_bind_btWheelInfo_getSuspensionRestLength_0=b.asm.Cl).apply(null,arguments)},Ln=b._emscripten_bind_btWheelInfo_updateWheel_2=function(){return(Ln=b._emscripten_bind_btWheelInfo_updateWheel_2=b.asm.Dl).apply(null,arguments)},Mn=b._emscripten_bind_btWheelInfo_get_m_suspensionStiffness_0=function(){return(Mn=b._emscripten_bind_btWheelInfo_get_m_suspensionStiffness_0=
-b.asm.El).apply(null,arguments)},Nn=b._emscripten_bind_btWheelInfo_set_m_suspensionStiffness_1=function(){return(Nn=b._emscripten_bind_btWheelInfo_set_m_suspensionStiffness_1=b.asm.Fl).apply(null,arguments)},On=b._emscripten_bind_btWheelInfo_get_m_frictionSlip_0=function(){return(On=b._emscripten_bind_btWheelInfo_get_m_frictionSlip_0=b.asm.Gl).apply(null,arguments)},Pn=b._emscripten_bind_btWheelInfo_set_m_frictionSlip_1=function(){return(Pn=b._emscripten_bind_btWheelInfo_set_m_frictionSlip_1=b.asm.Hl).apply(null,
-arguments)},Qn=b._emscripten_bind_btWheelInfo_get_m_engineForce_0=function(){return(Qn=b._emscripten_bind_btWheelInfo_get_m_engineForce_0=b.asm.Il).apply(null,arguments)},Rn=b._emscripten_bind_btWheelInfo_set_m_engineForce_1=function(){return(Rn=b._emscripten_bind_btWheelInfo_set_m_engineForce_1=b.asm.Jl).apply(null,arguments)},Sn=b._emscripten_bind_btWheelInfo_get_m_rollInfluence_0=function(){return(Sn=b._emscripten_bind_btWheelInfo_get_m_rollInfluence_0=b.asm.Kl).apply(null,arguments)},Tn=b._emscripten_bind_btWheelInfo_set_m_rollInfluence_1=
-function(){return(Tn=b._emscripten_bind_btWheelInfo_set_m_rollInfluence_1=b.asm.Ll).apply(null,arguments)},Un=b._emscripten_bind_btWheelInfo_get_m_suspensionRestLength1_0=function(){return(Un=b._emscripten_bind_btWheelInfo_get_m_suspensionRestLength1_0=b.asm.Ml).apply(null,arguments)},Vn=b._emscripten_bind_btWheelInfo_set_m_suspensionRestLength1_1=function(){return(Vn=b._emscripten_bind_btWheelInfo_set_m_suspensionRestLength1_1=b.asm.Nl).apply(null,arguments)},Wn=b._emscripten_bind_btWheelInfo_get_m_wheelsRadius_0=
-function(){return(Wn=b._emscripten_bind_btWheelInfo_get_m_wheelsRadius_0=b.asm.Ol).apply(null,arguments)},Xn=b._emscripten_bind_btWheelInfo_set_m_wheelsRadius_1=function(){return(Xn=b._emscripten_bind_btWheelInfo_set_m_wheelsRadius_1=b.asm.Pl).apply(null,arguments)},Yn=b._emscripten_bind_btWheelInfo_get_m_wheelsDampingCompression_0=function(){return(Yn=b._emscripten_bind_btWheelInfo_get_m_wheelsDampingCompression_0=b.asm.Ql).apply(null,arguments)},Zn=b._emscripten_bind_btWheelInfo_set_m_wheelsDampingCompression_1=
-function(){return(Zn=b._emscripten_bind_btWheelInfo_set_m_wheelsDampingCompression_1=b.asm.Rl).apply(null,arguments)},$n=b._emscripten_bind_btWheelInfo_get_m_wheelsDampingRelaxation_0=function(){return($n=b._emscripten_bind_btWheelInfo_get_m_wheelsDampingRelaxation_0=b.asm.Sl).apply(null,arguments)},ao=b._emscripten_bind_btWheelInfo_set_m_wheelsDampingRelaxation_1=function(){return(ao=b._emscripten_bind_btWheelInfo_set_m_wheelsDampingRelaxation_1=b.asm.Tl).apply(null,arguments)},bo=b._emscripten_bind_btWheelInfo_get_m_steering_0=
-function(){return(bo=b._emscripten_bind_btWheelInfo_get_m_steering_0=b.asm.Ul).apply(null,arguments)},co=b._emscripten_bind_btWheelInfo_set_m_steering_1=function(){return(co=b._emscripten_bind_btWheelInfo_set_m_steering_1=b.asm.Vl).apply(null,arguments)},eo=b._emscripten_bind_btWheelInfo_get_m_maxSuspensionForce_0=function(){return(eo=b._emscripten_bind_btWheelInfo_get_m_maxSuspensionForce_0=b.asm.Wl).apply(null,arguments)},fo=b._emscripten_bind_btWheelInfo_set_m_maxSuspensionForce_1=function(){return(fo=
-b._emscripten_bind_btWheelInfo_set_m_maxSuspensionForce_1=b.asm.Xl).apply(null,arguments)},go=b._emscripten_bind_btWheelInfo_get_m_maxSuspensionTravelCm_0=function(){return(go=b._emscripten_bind_btWheelInfo_get_m_maxSuspensionTravelCm_0=b.asm.Yl).apply(null,arguments)},ho=b._emscripten_bind_btWheelInfo_set_m_maxSuspensionTravelCm_1=function(){return(ho=b._emscripten_bind_btWheelInfo_set_m_maxSuspensionTravelCm_1=b.asm.Zl).apply(null,arguments)},io=b._emscripten_bind_btWheelInfo_get_m_wheelsSuspensionForce_0=
-function(){return(io=b._emscripten_bind_btWheelInfo_get_m_wheelsSuspensionForce_0=b.asm._l).apply(null,arguments)},jo=b._emscripten_bind_btWheelInfo_set_m_wheelsSuspensionForce_1=function(){return(jo=b._emscripten_bind_btWheelInfo_set_m_wheelsSuspensionForce_1=b.asm.$l).apply(null,arguments)},ko=b._emscripten_bind_btWheelInfo_get_m_bIsFrontWheel_0=function(){return(ko=b._emscripten_bind_btWheelInfo_get_m_bIsFrontWheel_0=b.asm.am).apply(null,arguments)},lo=b._emscripten_bind_btWheelInfo_set_m_bIsFrontWheel_1=
-function(){return(lo=b._emscripten_bind_btWheelInfo_set_m_bIsFrontWheel_1=b.asm.bm).apply(null,arguments)},mo=b._emscripten_bind_btWheelInfo_get_m_raycastInfo_0=function(){return(mo=b._emscripten_bind_btWheelInfo_get_m_raycastInfo_0=b.asm.cm).apply(null,arguments)},no=b._emscripten_bind_btWheelInfo_set_m_raycastInfo_1=function(){return(no=b._emscripten_bind_btWheelInfo_set_m_raycastInfo_1=b.asm.dm).apply(null,arguments)},oo=b._emscripten_bind_btWheelInfo_get_m_chassisConnectionPointCS_0=function(){return(oo=
-b._emscripten_bind_btWheelInfo_get_m_chassisConnectionPointCS_0=b.asm.em).apply(null,arguments)},po=b._emscripten_bind_btWheelInfo_set_m_chassisConnectionPointCS_1=function(){return(po=b._emscripten_bind_btWheelInfo_set_m_chassisConnectionPointCS_1=b.asm.fm).apply(null,arguments)},qo=b._emscripten_bind_btWheelInfo_get_m_worldTransform_0=function(){return(qo=b._emscripten_bind_btWheelInfo_get_m_worldTransform_0=b.asm.gm).apply(null,arguments)},ro=b._emscripten_bind_btWheelInfo_set_m_worldTransform_1=
-function(){return(ro=b._emscripten_bind_btWheelInfo_set_m_worldTransform_1=b.asm.hm).apply(null,arguments)},so=b._emscripten_bind_btWheelInfo_get_m_wheelDirectionCS_0=function(){return(so=b._emscripten_bind_btWheelInfo_get_m_wheelDirectionCS_0=b.asm.im).apply(null,arguments)},to=b._emscripten_bind_btWheelInfo_set_m_wheelDirectionCS_1=function(){return(to=b._emscripten_bind_btWheelInfo_set_m_wheelDirectionCS_1=b.asm.jm).apply(null,arguments)},uo=b._emscripten_bind_btWheelInfo_get_m_wheelAxleCS_0=function(){return(uo=
-b._emscripten_bind_btWheelInfo_get_m_wheelAxleCS_0=b.asm.km).apply(null,arguments)},vo=b._emscripten_bind_btWheelInfo_set_m_wheelAxleCS_1=function(){return(vo=b._emscripten_bind_btWheelInfo_set_m_wheelAxleCS_1=b.asm.lm).apply(null,arguments)},wo=b._emscripten_bind_btWheelInfo_get_m_rotation_0=function(){return(wo=b._emscripten_bind_btWheelInfo_get_m_rotation_0=b.asm.mm).apply(null,arguments)},xo=b._emscripten_bind_btWheelInfo_set_m_rotation_1=function(){return(xo=b._emscripten_bind_btWheelInfo_set_m_rotation_1=
-b.asm.nm).apply(null,arguments)},yo=b._emscripten_bind_btWheelInfo_get_m_deltaRotation_0=function(){return(yo=b._emscripten_bind_btWheelInfo_get_m_deltaRotation_0=b.asm.om).apply(null,arguments)},zo=b._emscripten_bind_btWheelInfo_set_m_deltaRotation_1=function(){return(zo=b._emscripten_bind_btWheelInfo_set_m_deltaRotation_1=b.asm.pm).apply(null,arguments)},Ao=b._emscripten_bind_btWheelInfo_get_m_brake_0=function(){return(Ao=b._emscripten_bind_btWheelInfo_get_m_brake_0=b.asm.qm).apply(null,arguments)},
-Bo=b._emscripten_bind_btWheelInfo_set_m_brake_1=function(){return(Bo=b._emscripten_bind_btWheelInfo_set_m_brake_1=b.asm.rm).apply(null,arguments)},Co=b._emscripten_bind_btWheelInfo_get_m_clippedInvContactDotSuspension_0=function(){return(Co=b._emscripten_bind_btWheelInfo_get_m_clippedInvContactDotSuspension_0=b.asm.sm).apply(null,arguments)},Do=b._emscripten_bind_btWheelInfo_set_m_clippedInvContactDotSuspension_1=function(){return(Do=b._emscripten_bind_btWheelInfo_set_m_clippedInvContactDotSuspension_1=
-b.asm.tm).apply(null,arguments)},Eo=b._emscripten_bind_btWheelInfo_get_m_suspensionRelativeVelocity_0=function(){return(Eo=b._emscripten_bind_btWheelInfo_get_m_suspensionRelativeVelocity_0=b.asm.um).apply(null,arguments)},Fo=b._emscripten_bind_btWheelInfo_set_m_suspensionRelativeVelocity_1=function(){return(Fo=b._emscripten_bind_btWheelInfo_set_m_suspensionRelativeVelocity_1=b.asm.vm).apply(null,arguments)},Go=b._emscripten_bind_btWheelInfo_get_m_skidInfo_0=function(){return(Go=b._emscripten_bind_btWheelInfo_get_m_skidInfo_0=
-b.asm.wm).apply(null,arguments)},Ho=b._emscripten_bind_btWheelInfo_set_m_skidInfo_1=function(){return(Ho=b._emscripten_bind_btWheelInfo_set_m_skidInfo_1=b.asm.xm).apply(null,arguments)},Io=b._emscripten_bind_btWheelInfo___destroy___0=function(){return(Io=b._emscripten_bind_btWheelInfo___destroy___0=b.asm.ym).apply(null,arguments)},Jo=b._emscripten_bind_btVector4_btVector4_0=function(){return(Jo=b._emscripten_bind_btVector4_btVector4_0=b.asm.zm).apply(null,arguments)},Ko=b._emscripten_bind_btVector4_btVector4_4=
-function(){return(Ko=b._emscripten_bind_btVector4_btVector4_4=b.asm.Am).apply(null,arguments)},Lo=b._emscripten_bind_btVector4_w_0=function(){return(Lo=b._emscripten_bind_btVector4_w_0=b.asm.Bm).apply(null,arguments)},Mo=b._emscripten_bind_btVector4_setValue_4=function(){return(Mo=b._emscripten_bind_btVector4_setValue_4=b.asm.Cm).apply(null,arguments)},No=b._emscripten_bind_btVector4_length_0=function(){return(No=b._emscripten_bind_btVector4_length_0=b.asm.Dm).apply(null,arguments)},Oo=b._emscripten_bind_btVector4_x_0=
-function(){return(Oo=b._emscripten_bind_btVector4_x_0=b.asm.Em).apply(null,arguments)},Po=b._emscripten_bind_btVector4_y_0=function(){return(Po=b._emscripten_bind_btVector4_y_0=b.asm.Fm).apply(null,arguments)},Qo=b._emscripten_bind_btVector4_z_0=function(){return(Qo=b._emscripten_bind_btVector4_z_0=b.asm.Gm).apply(null,arguments)},Ro=b._emscripten_bind_btVector4_setX_1=function(){return(Ro=b._emscripten_bind_btVector4_setX_1=b.asm.Hm).apply(null,arguments)},So=b._emscripten_bind_btVector4_setY_1=
-function(){return(So=b._emscripten_bind_btVector4_setY_1=b.asm.Im).apply(null,arguments)},To=b._emscripten_bind_btVector4_setZ_1=function(){return(To=b._emscripten_bind_btVector4_setZ_1=b.asm.Jm).apply(null,arguments)},Uo=b._emscripten_bind_btVector4_normalize_0=function(){return(Uo=b._emscripten_bind_btVector4_normalize_0=b.asm.Km).apply(null,arguments)},Vo=b._emscripten_bind_btVector4_rotate_2=function(){return(Vo=b._emscripten_bind_btVector4_rotate_2=b.asm.Lm).apply(null,arguments)},Wo=b._emscripten_bind_btVector4_dot_1=
-function(){return(Wo=b._emscripten_bind_btVector4_dot_1=b.asm.Mm).apply(null,arguments)},Xo=b._emscripten_bind_btVector4_op_mul_1=function(){return(Xo=b._emscripten_bind_btVector4_op_mul_1=b.asm.Nm).apply(null,arguments)},Yo=b._emscripten_bind_btVector4_op_add_1=function(){return(Yo=b._emscripten_bind_btVector4_op_add_1=b.asm.Om).apply(null,arguments)},Zo=b._emscripten_bind_btVector4_op_sub_1=function(){return(Zo=b._emscripten_bind_btVector4_op_sub_1=b.asm.Pm).apply(null,arguments)},$o=b._emscripten_bind_btVector4___destroy___0=
-function(){return($o=b._emscripten_bind_btVector4___destroy___0=b.asm.Qm).apply(null,arguments)},ap=b._emscripten_bind_btDefaultCollisionConstructionInfo_btDefaultCollisionConstructionInfo_0=function(){return(ap=b._emscripten_bind_btDefaultCollisionConstructionInfo_btDefaultCollisionConstructionInfo_0=b.asm.Rm).apply(null,arguments)},bp=b._emscripten_bind_btDefaultCollisionConstructionInfo___destroy___0=function(){return(bp=b._emscripten_bind_btDefaultCollisionConstructionInfo___destroy___0=b.asm.Sm).apply(null,
-arguments)},cp=b._emscripten_bind_Anchor_get_m_node_0=function(){return(cp=b._emscripten_bind_Anchor_get_m_node_0=b.asm.Tm).apply(null,arguments)},dp=b._emscripten_bind_Anchor_set_m_node_1=function(){return(dp=b._emscripten_bind_Anchor_set_m_node_1=b.asm.Um).apply(null,arguments)},ep=b._emscripten_bind_Anchor_get_m_local_0=function(){return(ep=b._emscripten_bind_Anchor_get_m_local_0=b.asm.Vm).apply(null,arguments)},fp=b._emscripten_bind_Anchor_set_m_local_1=function(){return(fp=b._emscripten_bind_Anchor_set_m_local_1=
-b.asm.Wm).apply(null,arguments)},gp=b._emscripten_bind_Anchor_get_m_body_0=function(){return(gp=b._emscripten_bind_Anchor_get_m_body_0=b.asm.Xm).apply(null,arguments)},hp=b._emscripten_bind_Anchor_set_m_body_1=function(){return(hp=b._emscripten_bind_Anchor_set_m_body_1=b.asm.Ym).apply(null,arguments)},ip=b._emscripten_bind_Anchor_get_m_influence_0=function(){return(ip=b._emscripten_bind_Anchor_get_m_influence_0=b.asm.Zm).apply(null,arguments)},jp=b._emscripten_bind_Anchor_set_m_influence_1=function(){return(jp=
-b._emscripten_bind_Anchor_set_m_influence_1=b.asm._m).apply(null,arguments)},kp=b._emscripten_bind_Anchor_get_m_c0_0=function(){return(kp=b._emscripten_bind_Anchor_get_m_c0_0=b.asm.$m).apply(null,arguments)},lp=b._emscripten_bind_Anchor_set_m_c0_1=function(){return(lp=b._emscripten_bind_Anchor_set_m_c0_1=b.asm.an).apply(null,arguments)},mp=b._emscripten_bind_Anchor_get_m_c1_0=function(){return(mp=b._emscripten_bind_Anchor_get_m_c1_0=b.asm.bn).apply(null,arguments)},np=b._emscripten_bind_Anchor_set_m_c1_1=
-function(){return(np=b._emscripten_bind_Anchor_set_m_c1_1=b.asm.cn).apply(null,arguments)},op=b._emscripten_bind_Anchor_get_m_c2_0=function(){return(op=b._emscripten_bind_Anchor_get_m_c2_0=b.asm.dn).apply(null,arguments)},pp=b._emscripten_bind_Anchor_set_m_c2_1=function(){return(pp=b._emscripten_bind_Anchor_set_m_c2_1=b.asm.en).apply(null,arguments)},qp=b._emscripten_bind_Anchor___destroy___0=function(){return(qp=b._emscripten_bind_Anchor___destroy___0=b.asm.fn).apply(null,arguments)},rp=b._emscripten_bind_btVehicleRaycasterResult_get_m_hitPointInWorld_0=
-function(){return(rp=b._emscripten_bind_btVehicleRaycasterResult_get_m_hitPointInWorld_0=b.asm.gn).apply(null,arguments)},sp=b._emscripten_bind_btVehicleRaycasterResult_set_m_hitPointInWorld_1=function(){return(sp=b._emscripten_bind_btVehicleRaycasterResult_set_m_hitPointInWorld_1=b.asm.hn).apply(null,arguments)},tp=b._emscripten_bind_btVehicleRaycasterResult_get_m_hitNormalInWorld_0=function(){return(tp=b._emscripten_bind_btVehicleRaycasterResult_get_m_hitNormalInWorld_0=b.asm.jn).apply(null,arguments)},
-up=b._emscripten_bind_btVehicleRaycasterResult_set_m_hitNormalInWorld_1=function(){return(up=b._emscripten_bind_btVehicleRaycasterResult_set_m_hitNormalInWorld_1=b.asm.kn).apply(null,arguments)},vp=b._emscripten_bind_btVehicleRaycasterResult_get_m_distFraction_0=function(){return(vp=b._emscripten_bind_btVehicleRaycasterResult_get_m_distFraction_0=b.asm.ln).apply(null,arguments)},wp=b._emscripten_bind_btVehicleRaycasterResult_set_m_distFraction_1=function(){return(wp=b._emscripten_bind_btVehicleRaycasterResult_set_m_distFraction_1=
-b.asm.mn).apply(null,arguments)},xp=b._emscripten_bind_btVehicleRaycasterResult___destroy___0=function(){return(xp=b._emscripten_bind_btVehicleRaycasterResult___destroy___0=b.asm.nn).apply(null,arguments)},yp=b._emscripten_bind_btVector3Array_size_0=function(){return(yp=b._emscripten_bind_btVector3Array_size_0=b.asm.on).apply(null,arguments)},zp=b._emscripten_bind_btVector3Array_at_1=function(){return(zp=b._emscripten_bind_btVector3Array_at_1=b.asm.pn).apply(null,arguments)},Ap=b._emscripten_bind_btVector3Array___destroy___0=
-function(){return(Ap=b._emscripten_bind_btVector3Array___destroy___0=b.asm.qn).apply(null,arguments)},Bp=b._emscripten_bind_btConstraintSolver___destroy___0=function(){return(Bp=b._emscripten_bind_btConstraintSolver___destroy___0=b.asm.rn).apply(null,arguments)},Cp=b._emscripten_bind_btRaycastVehicle_btRaycastVehicle_3=function(){return(Cp=b._emscripten_bind_btRaycastVehicle_btRaycastVehicle_3=b.asm.sn).apply(null,arguments)},Dp=b._emscripten_bind_btRaycastVehicle_applyEngineForce_2=function(){return(Dp=
-b._emscripten_bind_btRaycastVehicle_applyEngineForce_2=b.asm.tn).apply(null,arguments)},Ep=b._emscripten_bind_btRaycastVehicle_setSteeringValue_2=function(){return(Ep=b._emscripten_bind_btRaycastVehicle_setSteeringValue_2=b.asm.un).apply(null,arguments)},Fp=b._emscripten_bind_btRaycastVehicle_getWheelTransformWS_1=function(){return(Fp=b._emscripten_bind_btRaycastVehicle_getWheelTransformWS_1=b.asm.vn).apply(null,arguments)},Gp=b._emscripten_bind_btRaycastVehicle_updateWheelTransform_2=function(){return(Gp=
-b._emscripten_bind_btRaycastVehicle_updateWheelTransform_2=b.asm.wn).apply(null,arguments)},Hp=b._emscripten_bind_btRaycastVehicle_addWheel_7=function(){return(Hp=b._emscripten_bind_btRaycastVehicle_addWheel_7=b.asm.xn).apply(null,arguments)},Ip=b._emscripten_bind_btRaycastVehicle_getNumWheels_0=function(){return(Ip=b._emscripten_bind_btRaycastVehicle_getNumWheels_0=b.asm.yn).apply(null,arguments)},Jp=b._emscripten_bind_btRaycastVehicle_getRigidBody_0=function(){return(Jp=b._emscripten_bind_btRaycastVehicle_getRigidBody_0=
-b.asm.zn).apply(null,arguments)},Kp=b._emscripten_bind_btRaycastVehicle_getWheelInfo_1=function(){return(Kp=b._emscripten_bind_btRaycastVehicle_getWheelInfo_1=b.asm.An).apply(null,arguments)},Lp=b._emscripten_bind_btRaycastVehicle_setBrake_2=function(){return(Lp=b._emscripten_bind_btRaycastVehicle_setBrake_2=b.asm.Bn).apply(null,arguments)},Mp=b._emscripten_bind_btRaycastVehicle_setCoordinateSystem_3=function(){return(Mp=b._emscripten_bind_btRaycastVehicle_setCoordinateSystem_3=b.asm.Cn).apply(null,
-arguments)},Np=b._emscripten_bind_btRaycastVehicle_getCurrentSpeedKmHour_0=function(){return(Np=b._emscripten_bind_btRaycastVehicle_getCurrentSpeedKmHour_0=b.asm.Dn).apply(null,arguments)},Op=b._emscripten_bind_btRaycastVehicle_getChassisWorldTransform_0=function(){return(Op=b._emscripten_bind_btRaycastVehicle_getChassisWorldTransform_0=b.asm.En).apply(null,arguments)},Pp=b._emscripten_bind_btRaycastVehicle_rayCast_1=function(){return(Pp=b._emscripten_bind_btRaycastVehicle_rayCast_1=b.asm.Fn).apply(null,
-arguments)},Qp=b._emscripten_bind_btRaycastVehicle_updateVehicle_1=function(){return(Qp=b._emscripten_bind_btRaycastVehicle_updateVehicle_1=b.asm.Gn).apply(null,arguments)},Rp=b._emscripten_bind_btRaycastVehicle_resetSuspension_0=function(){return(Rp=b._emscripten_bind_btRaycastVehicle_resetSuspension_0=b.asm.Hn).apply(null,arguments)},Sp=b._emscripten_bind_btRaycastVehicle_getSteeringValue_1=function(){return(Sp=b._emscripten_bind_btRaycastVehicle_getSteeringValue_1=b.asm.In).apply(null,arguments)},
-Tp=b._emscripten_bind_btRaycastVehicle_updateWheelTransformsWS_1=function(){return(Tp=b._emscripten_bind_btRaycastVehicle_updateWheelTransformsWS_1=b.asm.Jn).apply(null,arguments)},Up=b._emscripten_bind_btRaycastVehicle_updateWheelTransformsWS_2=function(){return(Up=b._emscripten_bind_btRaycastVehicle_updateWheelTransformsWS_2=b.asm.Kn).apply(null,arguments)},Vp=b._emscripten_bind_btRaycastVehicle_setPitchControl_1=function(){return(Vp=b._emscripten_bind_btRaycastVehicle_setPitchControl_1=b.asm.Ln).apply(null,
-arguments)},Wp=b._emscripten_bind_btRaycastVehicle_updateSuspension_1=function(){return(Wp=b._emscripten_bind_btRaycastVehicle_updateSuspension_1=b.asm.Mn).apply(null,arguments)},Xp=b._emscripten_bind_btRaycastVehicle_updateFriction_1=function(){return(Xp=b._emscripten_bind_btRaycastVehicle_updateFriction_1=b.asm.Nn).apply(null,arguments)},Yp=b._emscripten_bind_btRaycastVehicle_getRightAxis_0=function(){return(Yp=b._emscripten_bind_btRaycastVehicle_getRightAxis_0=b.asm.On).apply(null,arguments)},
-Zp=b._emscripten_bind_btRaycastVehicle_getUpAxis_0=function(){return(Zp=b._emscripten_bind_btRaycastVehicle_getUpAxis_0=b.asm.Pn).apply(null,arguments)},$p=b._emscripten_bind_btRaycastVehicle_getForwardAxis_0=function(){return($p=b._emscripten_bind_btRaycastVehicle_getForwardAxis_0=b.asm.Qn).apply(null,arguments)},aq=b._emscripten_bind_btRaycastVehicle_getForwardVector_0=function(){return(aq=b._emscripten_bind_btRaycastVehicle_getForwardVector_0=b.asm.Rn).apply(null,arguments)},bq=b._emscripten_bind_btRaycastVehicle_getUserConstraintType_0=
-function(){return(bq=b._emscripten_bind_btRaycastVehicle_getUserConstraintType_0=b.asm.Sn).apply(null,arguments)},cq=b._emscripten_bind_btRaycastVehicle_setUserConstraintType_1=function(){return(cq=b._emscripten_bind_btRaycastVehicle_setUserConstraintType_1=b.asm.Tn).apply(null,arguments)},dq=b._emscripten_bind_btRaycastVehicle_setUserConstraintId_1=function(){return(dq=b._emscripten_bind_btRaycastVehicle_setUserConstraintId_1=b.asm.Un).apply(null,arguments)},eq=b._emscripten_bind_btRaycastVehicle_getUserConstraintId_0=
-function(){return(eq=b._emscripten_bind_btRaycastVehicle_getUserConstraintId_0=b.asm.Vn).apply(null,arguments)},fq=b._emscripten_bind_btRaycastVehicle_updateAction_2=function(){return(fq=b._emscripten_bind_btRaycastVehicle_updateAction_2=b.asm.Wn).apply(null,arguments)},gq=b._emscripten_bind_btRaycastVehicle___destroy___0=function(){return(gq=b._emscripten_bind_btRaycastVehicle___destroy___0=b.asm.Xn).apply(null,arguments)},hq=b._emscripten_bind_btCylinderShapeX_btCylinderShapeX_1=function(){return(hq=
-b._emscripten_bind_btCylinderShapeX_btCylinderShapeX_1=b.asm.Yn).apply(null,arguments)},iq=b._emscripten_bind_btCylinderShapeX_setMargin_1=function(){return(iq=b._emscripten_bind_btCylinderShapeX_setMargin_1=b.asm.Zn).apply(null,arguments)},jq=b._emscripten_bind_btCylinderShapeX_getMargin_0=function(){return(jq=b._emscripten_bind_btCylinderShapeX_getMargin_0=b.asm._n).apply(null,arguments)},kq=b._emscripten_bind_btCylinderShapeX_setLocalScaling_1=function(){return(kq=b._emscripten_bind_btCylinderShapeX_setLocalScaling_1=
-b.asm.$n).apply(null,arguments)},lq=b._emscripten_bind_btCylinderShapeX_getLocalScaling_0=function(){return(lq=b._emscripten_bind_btCylinderShapeX_getLocalScaling_0=b.asm.ao).apply(null,arguments)},mq=b._emscripten_bind_btCylinderShapeX_calculateLocalInertia_2=function(){return(mq=b._emscripten_bind_btCylinderShapeX_calculateLocalInertia_2=b.asm.bo).apply(null,arguments)},nq=b._emscripten_bind_btCylinderShapeX___destroy___0=function(){return(nq=b._emscripten_bind_btCylinderShapeX___destroy___0=b.asm.co).apply(null,
-arguments)},oq=b._emscripten_bind_btCylinderShapeZ_btCylinderShapeZ_1=function(){return(oq=b._emscripten_bind_btCylinderShapeZ_btCylinderShapeZ_1=b.asm.eo).apply(null,arguments)},pq=b._emscripten_bind_btCylinderShapeZ_setMargin_1=function(){return(pq=b._emscripten_bind_btCylinderShapeZ_setMargin_1=b.asm.fo).apply(null,arguments)},qq=b._emscripten_bind_btCylinderShapeZ_getMargin_0=function(){return(qq=b._emscripten_bind_btCylinderShapeZ_getMargin_0=b.asm.go).apply(null,arguments)},rq=b._emscripten_bind_btCylinderShapeZ_setLocalScaling_1=
-function(){return(rq=b._emscripten_bind_btCylinderShapeZ_setLocalScaling_1=b.asm.ho).apply(null,arguments)},sq=b._emscripten_bind_btCylinderShapeZ_getLocalScaling_0=function(){return(sq=b._emscripten_bind_btCylinderShapeZ_getLocalScaling_0=b.asm.io).apply(null,arguments)},tq=b._emscripten_bind_btCylinderShapeZ_calculateLocalInertia_2=function(){return(tq=b._emscripten_bind_btCylinderShapeZ_calculateLocalInertia_2=b.asm.jo).apply(null,arguments)},uq=b._emscripten_bind_btCylinderShapeZ___destroy___0=
-function(){return(uq=b._emscripten_bind_btCylinderShapeZ___destroy___0=b.asm.ko).apply(null,arguments)},vq=b._emscripten_bind_btConvexPolyhedron_get_m_vertices_0=function(){return(vq=b._emscripten_bind_btConvexPolyhedron_get_m_vertices_0=b.asm.lo).apply(null,arguments)},wq=b._emscripten_bind_btConvexPolyhedron_set_m_vertices_1=function(){return(wq=b._emscripten_bind_btConvexPolyhedron_set_m_vertices_1=b.asm.mo).apply(null,arguments)},xq=b._emscripten_bind_btConvexPolyhedron_get_m_faces_0=function(){return(xq=
-b._emscripten_bind_btConvexPolyhedron_get_m_faces_0=b.asm.no).apply(null,arguments)},yq=b._emscripten_bind_btConvexPolyhedron_set_m_faces_1=function(){return(yq=b._emscripten_bind_btConvexPolyhedron_set_m_faces_1=b.asm.oo).apply(null,arguments)},zq=b._emscripten_bind_btConvexPolyhedron___destroy___0=function(){return(zq=b._emscripten_bind_btConvexPolyhedron___destroy___0=b.asm.po).apply(null,arguments)},Aq=b._emscripten_bind_btSequentialImpulseConstraintSolver_btSequentialImpulseConstraintSolver_0=
-function(){return(Aq=b._emscripten_bind_btSequentialImpulseConstraintSolver_btSequentialImpulseConstraintSolver_0=b.asm.qo).apply(null,arguments)},Bq=b._emscripten_bind_btSequentialImpulseConstraintSolver___destroy___0=function(){return(Bq=b._emscripten_bind_btSequentialImpulseConstraintSolver___destroy___0=b.asm.ro).apply(null,arguments)},Cq=b._emscripten_bind_tAnchorArray_size_0=function(){return(Cq=b._emscripten_bind_tAnchorArray_size_0=b.asm.so).apply(null,arguments)},Dq=b._emscripten_bind_tAnchorArray_at_1=
-function(){return(Dq=b._emscripten_bind_tAnchorArray_at_1=b.asm.to).apply(null,arguments)},Eq=b._emscripten_bind_tAnchorArray_clear_0=function(){return(Eq=b._emscripten_bind_tAnchorArray_clear_0=b.asm.uo).apply(null,arguments)},Fq=b._emscripten_bind_tAnchorArray_push_back_1=function(){return(Fq=b._emscripten_bind_tAnchorArray_push_back_1=b.asm.vo).apply(null,arguments)},Gq=b._emscripten_bind_tAnchorArray_pop_back_0=function(){return(Gq=b._emscripten_bind_tAnchorArray_pop_back_0=b.asm.wo).apply(null,
-arguments)},Hq=b._emscripten_bind_tAnchorArray___destroy___0=function(){return(Hq=b._emscripten_bind_tAnchorArray___destroy___0=b.asm.xo).apply(null,arguments)},Iq=b._emscripten_bind_RaycastInfo_get_m_contactNormalWS_0=function(){return(Iq=b._emscripten_bind_RaycastInfo_get_m_contactNormalWS_0=b.asm.yo).apply(null,arguments)},Jq=b._emscripten_bind_RaycastInfo_set_m_contactNormalWS_1=function(){return(Jq=b._emscripten_bind_RaycastInfo_set_m_contactNormalWS_1=b.asm.zo).apply(null,arguments)},Kq=b._emscripten_bind_RaycastInfo_get_m_contactPointWS_0=
-function(){return(Kq=b._emscripten_bind_RaycastInfo_get_m_contactPointWS_0=b.asm.Ao).apply(null,arguments)},Lq=b._emscripten_bind_RaycastInfo_set_m_contactPointWS_1=function(){return(Lq=b._emscripten_bind_RaycastInfo_set_m_contactPointWS_1=b.asm.Bo).apply(null,arguments)},Mq=b._emscripten_bind_RaycastInfo_get_m_suspensionLength_0=function(){return(Mq=b._emscripten_bind_RaycastInfo_get_m_suspensionLength_0=b.asm.Co).apply(null,arguments)},Nq=b._emscripten_bind_RaycastInfo_set_m_suspensionLength_1=
-function(){return(Nq=b._emscripten_bind_RaycastInfo_set_m_suspensionLength_1=b.asm.Do).apply(null,arguments)},Oq=b._emscripten_bind_RaycastInfo_get_m_hardPointWS_0=function(){return(Oq=b._emscripten_bind_RaycastInfo_get_m_hardPointWS_0=b.asm.Eo).apply(null,arguments)},Pq=b._emscripten_bind_RaycastInfo_set_m_hardPointWS_1=function(){return(Pq=b._emscripten_bind_RaycastInfo_set_m_hardPointWS_1=b.asm.Fo).apply(null,arguments)},Qq=b._emscripten_bind_RaycastInfo_get_m_wheelDirectionWS_0=function(){return(Qq=
-b._emscripten_bind_RaycastInfo_get_m_wheelDirectionWS_0=b.asm.Go).apply(null,arguments)},Rq=b._emscripten_bind_RaycastInfo_set_m_wheelDirectionWS_1=function(){return(Rq=b._emscripten_bind_RaycastInfo_set_m_wheelDirectionWS_1=b.asm.Ho).apply(null,arguments)},Sq=b._emscripten_bind_RaycastInfo_get_m_wheelAxleWS_0=function(){return(Sq=b._emscripten_bind_RaycastInfo_get_m_wheelAxleWS_0=b.asm.Io).apply(null,arguments)},Tq=b._emscripten_bind_RaycastInfo_set_m_wheelAxleWS_1=function(){return(Tq=b._emscripten_bind_RaycastInfo_set_m_wheelAxleWS_1=
-b.asm.Jo).apply(null,arguments)},Uq=b._emscripten_bind_RaycastInfo_get_m_isInContact_0=function(){return(Uq=b._emscripten_bind_RaycastInfo_get_m_isInContact_0=b.asm.Ko).apply(null,arguments)},Vq=b._emscripten_bind_RaycastInfo_set_m_isInContact_1=function(){return(Vq=b._emscripten_bind_RaycastInfo_set_m_isInContact_1=b.asm.Lo).apply(null,arguments)},Wq=b._emscripten_bind_RaycastInfo_get_m_groundObject_0=function(){return(Wq=b._emscripten_bind_RaycastInfo_get_m_groundObject_0=b.asm.Mo).apply(null,arguments)},
-Xq=b._emscripten_bind_RaycastInfo_set_m_groundObject_1=function(){return(Xq=b._emscripten_bind_RaycastInfo_set_m_groundObject_1=b.asm.No).apply(null,arguments)},Yq=b._emscripten_bind_RaycastInfo___destroy___0=function(){return(Yq=b._emscripten_bind_RaycastInfo___destroy___0=b.asm.Oo).apply(null,arguments)},Zq=b._emscripten_bind_btMultiSphereShape_btMultiSphereShape_3=function(){return(Zq=b._emscripten_bind_btMultiSphereShape_btMultiSphereShape_3=b.asm.Po).apply(null,arguments)},$q=b._emscripten_bind_btMultiSphereShape_setLocalScaling_1=
-function(){return($q=b._emscripten_bind_btMultiSphereShape_setLocalScaling_1=b.asm.Qo).apply(null,arguments)},ar=b._emscripten_bind_btMultiSphereShape_getLocalScaling_0=function(){return(ar=b._emscripten_bind_btMultiSphereShape_getLocalScaling_0=b.asm.Ro).apply(null,arguments)},br=b._emscripten_bind_btMultiSphereShape_calculateLocalInertia_2=function(){return(br=b._emscripten_bind_btMultiSphereShape_calculateLocalInertia_2=b.asm.So).apply(null,arguments)},cr=b._emscripten_bind_btMultiSphereShape___destroy___0=
-function(){return(cr=b._emscripten_bind_btMultiSphereShape___destroy___0=b.asm.To).apply(null,arguments)},dr=b._emscripten_bind_btSoftBody_btSoftBody_4=function(){return(dr=b._emscripten_bind_btSoftBody_btSoftBody_4=b.asm.Uo).apply(null,arguments)},er=b._emscripten_bind_btSoftBody_checkLink_2=function(){return(er=b._emscripten_bind_btSoftBody_checkLink_2=b.asm.Vo).apply(null,arguments)},fr=b._emscripten_bind_btSoftBody_checkFace_3=function(){return(fr=b._emscripten_bind_btSoftBody_checkFace_3=b.asm.Wo).apply(null,
-arguments)},gr=b._emscripten_bind_btSoftBody_appendMaterial_0=function(){return(gr=b._emscripten_bind_btSoftBody_appendMaterial_0=b.asm.Xo).apply(null,arguments)},hr=b._emscripten_bind_btSoftBody_appendNode_2=function(){return(hr=b._emscripten_bind_btSoftBody_appendNode_2=b.asm.Yo).apply(null,arguments)},ir=b._emscripten_bind_btSoftBody_appendLink_4=function(){return(ir=b._emscripten_bind_btSoftBody_appendLink_4=b.asm.Zo).apply(null,arguments)},jr=b._emscripten_bind_btSoftBody_appendFace_4=function(){return(jr=
-b._emscripten_bind_btSoftBody_appendFace_4=b.asm._o).apply(null,arguments)},kr=b._emscripten_bind_btSoftBody_appendTetra_5=function(){return(kr=b._emscripten_bind_btSoftBody_appendTetra_5=b.asm.$o).apply(null,arguments)},lr=b._emscripten_bind_btSoftBody_appendAnchor_4=function(){return(lr=b._emscripten_bind_btSoftBody_appendAnchor_4=b.asm.ap).apply(null,arguments)},mr=b._emscripten_bind_btSoftBody_addForce_1=function(){return(mr=b._emscripten_bind_btSoftBody_addForce_1=b.asm.bp).apply(null,arguments)},
-nr=b._emscripten_bind_btSoftBody_addForce_2=function(){return(nr=b._emscripten_bind_btSoftBody_addForce_2=b.asm.cp).apply(null,arguments)},or=b._emscripten_bind_btSoftBody_addAeroForceToNode_2=function(){return(or=b._emscripten_bind_btSoftBody_addAeroForceToNode_2=b.asm.dp).apply(null,arguments)},pr=b._emscripten_bind_btSoftBody_getTotalMass_0=function(){return(pr=b._emscripten_bind_btSoftBody_getTotalMass_0=b.asm.ep).apply(null,arguments)},qr=b._emscripten_bind_btSoftBody_setTotalMass_2=function(){return(qr=
-b._emscripten_bind_btSoftBody_setTotalMass_2=b.asm.fp).apply(null,arguments)},rr=b._emscripten_bind_btSoftBody_setMass_2=function(){return(rr=b._emscripten_bind_btSoftBody_setMass_2=b.asm.gp).apply(null,arguments)},sr=b._emscripten_bind_btSoftBody_transform_1=function(){return(sr=b._emscripten_bind_btSoftBody_transform_1=b.asm.hp).apply(null,arguments)},tr=b._emscripten_bind_btSoftBody_translate_1=function(){return(tr=b._emscripten_bind_btSoftBody_translate_1=b.asm.ip).apply(null,arguments)},ur=b._emscripten_bind_btSoftBody_rotate_1=
-function(){return(ur=b._emscripten_bind_btSoftBody_rotate_1=b.asm.jp).apply(null,arguments)},vr=b._emscripten_bind_btSoftBody_scale_1=function(){return(vr=b._emscripten_bind_btSoftBody_scale_1=b.asm.kp).apply(null,arguments)},wr=b._emscripten_bind_btSoftBody_generateClusters_1=function(){return(wr=b._emscripten_bind_btSoftBody_generateClusters_1=b.asm.lp).apply(null,arguments)},xr=b._emscripten_bind_btSoftBody_generateClusters_2=function(){return(xr=b._emscripten_bind_btSoftBody_generateClusters_2=
-b.asm.mp).apply(null,arguments)},yr=b._emscripten_bind_btSoftBody_generateBendingConstraints_2=function(){return(yr=b._emscripten_bind_btSoftBody_generateBendingConstraints_2=b.asm.np).apply(null,arguments)},zr=b._emscripten_bind_btSoftBody_upcast_1=function(){return(zr=b._emscripten_bind_btSoftBody_upcast_1=b.asm.op).apply(null,arguments)},Ar=b._emscripten_bind_btSoftBody_setAnisotropicFriction_2=function(){return(Ar=b._emscripten_bind_btSoftBody_setAnisotropicFriction_2=b.asm.pp).apply(null,arguments)},
-Br=b._emscripten_bind_btSoftBody_getCollisionShape_0=function(){return(Br=b._emscripten_bind_btSoftBody_getCollisionShape_0=b.asm.qp).apply(null,arguments)},Cr=b._emscripten_bind_btSoftBody_setContactProcessingThreshold_1=function(){return(Cr=b._emscripten_bind_btSoftBody_setContactProcessingThreshold_1=b.asm.rp).apply(null,arguments)},Dr=b._emscripten_bind_btSoftBody_setActivationState_1=function(){return(Dr=b._emscripten_bind_btSoftBody_setActivationState_1=b.asm.sp).apply(null,arguments)},Er=b._emscripten_bind_btSoftBody_forceActivationState_1=
-function(){return(Er=b._emscripten_bind_btSoftBody_forceActivationState_1=b.asm.tp).apply(null,arguments)},Fr=b._emscripten_bind_btSoftBody_activate_0=function(){return(Fr=b._emscripten_bind_btSoftBody_activate_0=b.asm.up).apply(null,arguments)},Gr=b._emscripten_bind_btSoftBody_activate_1=function(){return(Gr=b._emscripten_bind_btSoftBody_activate_1=b.asm.vp).apply(null,arguments)},Hr=b._emscripten_bind_btSoftBody_isActive_0=function(){return(Hr=b._emscripten_bind_btSoftBody_isActive_0=b.asm.wp).apply(null,
-arguments)},Ir=b._emscripten_bind_btSoftBody_isKinematicObject_0=function(){return(Ir=b._emscripten_bind_btSoftBody_isKinematicObject_0=b.asm.xp).apply(null,arguments)},Jr=b._emscripten_bind_btSoftBody_isStaticObject_0=function(){return(Jr=b._emscripten_bind_btSoftBody_isStaticObject_0=b.asm.yp).apply(null,arguments)},Kr=b._emscripten_bind_btSoftBody_isStaticOrKinematicObject_0=function(){return(Kr=b._emscripten_bind_btSoftBody_isStaticOrKinematicObject_0=b.asm.zp).apply(null,arguments)},Lr=b._emscripten_bind_btSoftBody_getRestitution_0=
-function(){return(Lr=b._emscripten_bind_btSoftBody_getRestitution_0=b.asm.Ap).apply(null,arguments)},Mr=b._emscripten_bind_btSoftBody_getFriction_0=function(){return(Mr=b._emscripten_bind_btSoftBody_getFriction_0=b.asm.Bp).apply(null,arguments)},Nr=b._emscripten_bind_btSoftBody_getRollingFriction_0=function(){return(Nr=b._emscripten_bind_btSoftBody_getRollingFriction_0=b.asm.Cp).apply(null,arguments)},Or=b._emscripten_bind_btSoftBody_setRestitution_1=function(){return(Or=b._emscripten_bind_btSoftBody_setRestitution_1=
-b.asm.Dp).apply(null,arguments)},Pr=b._emscripten_bind_btSoftBody_setFriction_1=function(){return(Pr=b._emscripten_bind_btSoftBody_setFriction_1=b.asm.Ep).apply(null,arguments)},Qr=b._emscripten_bind_btSoftBody_setRollingFriction_1=function(){return(Qr=b._emscripten_bind_btSoftBody_setRollingFriction_1=b.asm.Fp).apply(null,arguments)},Rr=b._emscripten_bind_btSoftBody_getWorldTransform_0=function(){return(Rr=b._emscripten_bind_btSoftBody_getWorldTransform_0=b.asm.Gp).apply(null,arguments)},Sr=b._emscripten_bind_btSoftBody_getCollisionFlags_0=
-function(){return(Sr=b._emscripten_bind_btSoftBody_getCollisionFlags_0=b.asm.Hp).apply(null,arguments)},Tr=b._emscripten_bind_btSoftBody_setCollisionFlags_1=function(){return(Tr=b._emscripten_bind_btSoftBody_setCollisionFlags_1=b.asm.Ip).apply(null,arguments)},Ur=b._emscripten_bind_btSoftBody_setWorldTransform_1=function(){return(Ur=b._emscripten_bind_btSoftBody_setWorldTransform_1=b.asm.Jp).apply(null,arguments)},Vr=b._emscripten_bind_btSoftBody_setCollisionShape_1=function(){return(Vr=b._emscripten_bind_btSoftBody_setCollisionShape_1=
-b.asm.Kp).apply(null,arguments)},Wr=b._emscripten_bind_btSoftBody_setCcdMotionThreshold_1=function(){return(Wr=b._emscripten_bind_btSoftBody_setCcdMotionThreshold_1=b.asm.Lp).apply(null,arguments)},Xr=b._emscripten_bind_btSoftBody_setCcdSweptSphereRadius_1=function(){return(Xr=b._emscripten_bind_btSoftBody_setCcdSweptSphereRadius_1=b.asm.Mp).apply(null,arguments)},Yr=b._emscripten_bind_btSoftBody_getUserIndex_0=function(){return(Yr=b._emscripten_bind_btSoftBody_getUserIndex_0=b.asm.Np).apply(null,
-arguments)},Zr=b._emscripten_bind_btSoftBody_setUserIndex_1=function(){return(Zr=b._emscripten_bind_btSoftBody_setUserIndex_1=b.asm.Op).apply(null,arguments)},$r=b._emscripten_bind_btSoftBody_getUserPointer_0=function(){return($r=b._emscripten_bind_btSoftBody_getUserPointer_0=b.asm.Pp).apply(null,arguments)},as=b._emscripten_bind_btSoftBody_setUserPointer_1=function(){return(as=b._emscripten_bind_btSoftBody_setUserPointer_1=b.asm.Qp).apply(null,arguments)},bs=b._emscripten_bind_btSoftBody_getBroadphaseHandle_0=
-function(){return(bs=b._emscripten_bind_btSoftBody_getBroadphaseHandle_0=b.asm.Rp).apply(null,arguments)},cs=b._emscripten_bind_btSoftBody_get_m_cfg_0=function(){return(cs=b._emscripten_bind_btSoftBody_get_m_cfg_0=b.asm.Sp).apply(null,arguments)},ds=b._emscripten_bind_btSoftBody_set_m_cfg_1=function(){return(ds=b._emscripten_bind_btSoftBody_set_m_cfg_1=b.asm.Tp).apply(null,arguments)},es=b._emscripten_bind_btSoftBody_get_m_nodes_0=function(){return(es=b._emscripten_bind_btSoftBody_get_m_nodes_0=b.asm.Up).apply(null,
-arguments)},gs=b._emscripten_bind_btSoftBody_set_m_nodes_1=function(){return(gs=b._emscripten_bind_btSoftBody_set_m_nodes_1=b.asm.Vp).apply(null,arguments)},hs=b._emscripten_bind_btSoftBody_get_m_faces_0=function(){return(hs=b._emscripten_bind_btSoftBody_get_m_faces_0=b.asm.Wp).apply(null,arguments)},is=b._emscripten_bind_btSoftBody_set_m_faces_1=function(){return(is=b._emscripten_bind_btSoftBody_set_m_faces_1=b.asm.Xp).apply(null,arguments)},js=b._emscripten_bind_btSoftBody_get_m_materials_0=function(){return(js=
-b._emscripten_bind_btSoftBody_get_m_materials_0=b.asm.Yp).apply(null,arguments)},ks=b._emscripten_bind_btSoftBody_set_m_materials_1=function(){return(ks=b._emscripten_bind_btSoftBody_set_m_materials_1=b.asm.Zp).apply(null,arguments)},ls=b._emscripten_bind_btSoftBody_get_m_anchors_0=function(){return(ls=b._emscripten_bind_btSoftBody_get_m_anchors_0=b.asm._p).apply(null,arguments)},ms=b._emscripten_bind_btSoftBody_set_m_anchors_1=function(){return(ms=b._emscripten_bind_btSoftBody_set_m_anchors_1=b.asm.$p).apply(null,
-arguments)},ns=b._emscripten_bind_btSoftBody___destroy___0=function(){return(ns=b._emscripten_bind_btSoftBody___destroy___0=b.asm.aq).apply(null,arguments)},ps=b._emscripten_bind_btIntArray_size_0=function(){return(ps=b._emscripten_bind_btIntArray_size_0=b.asm.bq).apply(null,arguments)},qs=b._emscripten_bind_btIntArray_at_1=function(){return(qs=b._emscripten_bind_btIntArray_at_1=b.asm.cq).apply(null,arguments)},rs=b._emscripten_bind_btIntArray___destroy___0=function(){return(rs=b._emscripten_bind_btIntArray___destroy___0=
-b.asm.dq).apply(null,arguments)},ss=b._emscripten_bind_Config_get_kVCF_0=function(){return(ss=b._emscripten_bind_Config_get_kVCF_0=b.asm.eq).apply(null,arguments)},ts=b._emscripten_bind_Config_set_kVCF_1=function(){return(ts=b._emscripten_bind_Config_set_kVCF_1=b.asm.fq).apply(null,arguments)},us=b._emscripten_bind_Config_get_kDP_0=function(){return(us=b._emscripten_bind_Config_get_kDP_0=b.asm.gq).apply(null,arguments)},vs=b._emscripten_bind_Config_set_kDP_1=function(){return(vs=b._emscripten_bind_Config_set_kDP_1=
-b.asm.hq).apply(null,arguments)},xs=b._emscripten_bind_Config_get_kDG_0=function(){return(xs=b._emscripten_bind_Config_get_kDG_0=b.asm.iq).apply(null,arguments)},ys=b._emscripten_bind_Config_set_kDG_1=function(){return(ys=b._emscripten_bind_Config_set_kDG_1=b.asm.jq).apply(null,arguments)},zs=b._emscripten_bind_Config_get_kLF_0=function(){return(zs=b._emscripten_bind_Config_get_kLF_0=b.asm.kq).apply(null,arguments)},As=b._emscripten_bind_Config_set_kLF_1=function(){return(As=b._emscripten_bind_Config_set_kLF_1=
-b.asm.lq).apply(null,arguments)},Bs=b._emscripten_bind_Config_get_kPR_0=function(){return(Bs=b._emscripten_bind_Config_get_kPR_0=b.asm.mq).apply(null,arguments)},Cs=b._emscripten_bind_Config_set_kPR_1=function(){return(Cs=b._emscripten_bind_Config_set_kPR_1=b.asm.nq).apply(null,arguments)},Ds=b._emscripten_bind_Config_get_kVC_0=function(){return(Ds=b._emscripten_bind_Config_get_kVC_0=b.asm.oq).apply(null,arguments)},Es=b._emscripten_bind_Config_set_kVC_1=function(){return(Es=b._emscripten_bind_Config_set_kVC_1=
-b.asm.pq).apply(null,arguments)},Fs=b._emscripten_bind_Config_get_kDF_0=function(){return(Fs=b._emscripten_bind_Config_get_kDF_0=b.asm.qq).apply(null,arguments)},Gs=b._emscripten_bind_Config_set_kDF_1=function(){return(Gs=b._emscripten_bind_Config_set_kDF_1=b.asm.rq).apply(null,arguments)},Hs=b._emscripten_bind_Config_get_kMT_0=function(){return(Hs=b._emscripten_bind_Config_get_kMT_0=b.asm.sq).apply(null,arguments)},Is=b._emscripten_bind_Config_set_kMT_1=function(){return(Is=b._emscripten_bind_Config_set_kMT_1=
-b.asm.tq).apply(null,arguments)},Js=b._emscripten_bind_Config_get_kCHR_0=function(){return(Js=b._emscripten_bind_Config_get_kCHR_0=b.asm.uq).apply(null,arguments)},Ks=b._emscripten_bind_Config_set_kCHR_1=function(){return(Ks=b._emscripten_bind_Config_set_kCHR_1=b.asm.vq).apply(null,arguments)},Ls=b._emscripten_bind_Config_get_kKHR_0=function(){return(Ls=b._emscripten_bind_Config_get_kKHR_0=b.asm.wq).apply(null,arguments)},Ms=b._emscripten_bind_Config_set_kKHR_1=function(){return(Ms=b._emscripten_bind_Config_set_kKHR_1=
-b.asm.xq).apply(null,arguments)},Ns=b._emscripten_bind_Config_get_kSHR_0=function(){return(Ns=b._emscripten_bind_Config_get_kSHR_0=b.asm.yq).apply(null,arguments)},Os=b._emscripten_bind_Config_set_kSHR_1=function(){return(Os=b._emscripten_bind_Config_set_kSHR_1=b.asm.zq).apply(null,arguments)},Ps=b._emscripten_bind_Config_get_kAHR_0=function(){return(Ps=b._emscripten_bind_Config_get_kAHR_0=b.asm.Aq).apply(null,arguments)},Qs=b._emscripten_bind_Config_set_kAHR_1=function(){return(Qs=b._emscripten_bind_Config_set_kAHR_1=
-b.asm.Bq).apply(null,arguments)},Rs=b._emscripten_bind_Config_get_kSRHR_CL_0=function(){return(Rs=b._emscripten_bind_Config_get_kSRHR_CL_0=b.asm.Cq).apply(null,arguments)},Ss=b._emscripten_bind_Config_set_kSRHR_CL_1=function(){return(Ss=b._emscripten_bind_Config_set_kSRHR_CL_1=b.asm.Dq).apply(null,arguments)},Ts=b._emscripten_bind_Config_get_kSKHR_CL_0=function(){return(Ts=b._emscripten_bind_Config_get_kSKHR_CL_0=b.asm.Eq).apply(null,arguments)},Us=b._emscripten_bind_Config_set_kSKHR_CL_1=function(){return(Us=
-b._emscripten_bind_Config_set_kSKHR_CL_1=b.asm.Fq).apply(null,arguments)},Vs=b._emscripten_bind_Config_get_kSSHR_CL_0=function(){return(Vs=b._emscripten_bind_Config_get_kSSHR_CL_0=b.asm.Gq).apply(null,arguments)},Ws=b._emscripten_bind_Config_set_kSSHR_CL_1=function(){return(Ws=b._emscripten_bind_Config_set_kSSHR_CL_1=b.asm.Hq).apply(null,arguments)},Xs=b._emscripten_bind_Config_get_kSR_SPLT_CL_0=function(){return(Xs=b._emscripten_bind_Config_get_kSR_SPLT_CL_0=b.asm.Iq).apply(null,arguments)},Ys=b._emscripten_bind_Config_set_kSR_SPLT_CL_1=
-function(){return(Ys=b._emscripten_bind_Config_set_kSR_SPLT_CL_1=b.asm.Jq).apply(null,arguments)},Zs=b._emscripten_bind_Config_get_kSK_SPLT_CL_0=function(){return(Zs=b._emscripten_bind_Config_get_kSK_SPLT_CL_0=b.asm.Kq).apply(null,arguments)},$s=b._emscripten_bind_Config_set_kSK_SPLT_CL_1=function(){return($s=b._emscripten_bind_Config_set_kSK_SPLT_CL_1=b.asm.Lq).apply(null,arguments)},at=b._emscripten_bind_Config_get_kSS_SPLT_CL_0=function(){return(at=b._emscripten_bind_Config_get_kSS_SPLT_CL_0=b.asm.Mq).apply(null,
-arguments)},bt=b._emscripten_bind_Config_set_kSS_SPLT_CL_1=function(){return(bt=b._emscripten_bind_Config_set_kSS_SPLT_CL_1=b.asm.Nq).apply(null,arguments)},ct=b._emscripten_bind_Config_get_maxvolume_0=function(){return(ct=b._emscripten_bind_Config_get_maxvolume_0=b.asm.Oq).apply(null,arguments)},dt=b._emscripten_bind_Config_set_maxvolume_1=function(){return(dt=b._emscripten_bind_Config_set_maxvolume_1=b.asm.Pq).apply(null,arguments)},et=b._emscripten_bind_Config_get_timescale_0=function(){return(et=
-b._emscripten_bind_Config_get_timescale_0=b.asm.Qq).apply(null,arguments)},ft=b._emscripten_bind_Config_set_timescale_1=function(){return(ft=b._emscripten_bind_Config_set_timescale_1=b.asm.Rq).apply(null,arguments)},gt=b._emscripten_bind_Config_get_viterations_0=function(){return(gt=b._emscripten_bind_Config_get_viterations_0=b.asm.Sq).apply(null,arguments)},ht=b._emscripten_bind_Config_set_viterations_1=function(){return(ht=b._emscripten_bind_Config_set_viterations_1=b.asm.Tq).apply(null,arguments)},
-it=b._emscripten_bind_Config_get_piterations_0=function(){return(it=b._emscripten_bind_Config_get_piterations_0=b.asm.Uq).apply(null,arguments)},jt=b._emscripten_bind_Config_set_piterations_1=function(){return(jt=b._emscripten_bind_Config_set_piterations_1=b.asm.Vq).apply(null,arguments)},kt=b._emscripten_bind_Config_get_diterations_0=function(){return(kt=b._emscripten_bind_Config_get_diterations_0=b.asm.Wq).apply(null,arguments)},lt=b._emscripten_bind_Config_set_diterations_1=function(){return(lt=
-b._emscripten_bind_Config_set_diterations_1=b.asm.Xq).apply(null,arguments)},mt=b._emscripten_bind_Config_get_citerations_0=function(){return(mt=b._emscripten_bind_Config_get_citerations_0=b.asm.Yq).apply(null,arguments)},nt=b._emscripten_bind_Config_set_citerations_1=function(){return(nt=b._emscripten_bind_Config_set_citerations_1=b.asm.Zq).apply(null,arguments)},ot=b._emscripten_bind_Config_get_collisions_0=function(){return(ot=b._emscripten_bind_Config_get_collisions_0=b.asm._q).apply(null,arguments)},
-pt=b._emscripten_bind_Config_set_collisions_1=function(){return(pt=b._emscripten_bind_Config_set_collisions_1=b.asm.$q).apply(null,arguments)},qt=b._emscripten_bind_Config___destroy___0=function(){return(qt=b._emscripten_bind_Config___destroy___0=b.asm.ar).apply(null,arguments)},rt=b._emscripten_bind_Node_get_m_x_0=function(){return(rt=b._emscripten_bind_Node_get_m_x_0=b.asm.br).apply(null,arguments)},st=b._emscripten_bind_Node_set_m_x_1=function(){return(st=b._emscripten_bind_Node_set_m_x_1=b.asm.cr).apply(null,
-arguments)},tt=b._emscripten_bind_Node_get_m_q_0=function(){return(tt=b._emscripten_bind_Node_get_m_q_0=b.asm.dr).apply(null,arguments)},ut=b._emscripten_bind_Node_set_m_q_1=function(){return(ut=b._emscripten_bind_Node_set_m_q_1=b.asm.er).apply(null,arguments)},vt=b._emscripten_bind_Node_get_m_v_0=function(){return(vt=b._emscripten_bind_Node_get_m_v_0=b.asm.fr).apply(null,arguments)},wt=b._emscripten_bind_Node_set_m_v_1=function(){return(wt=b._emscripten_bind_Node_set_m_v_1=b.asm.gr).apply(null,arguments)},
-xt=b._emscripten_bind_Node_get_m_f_0=function(){return(xt=b._emscripten_bind_Node_get_m_f_0=b.asm.hr).apply(null,arguments)},yt=b._emscripten_bind_Node_set_m_f_1=function(){return(yt=b._emscripten_bind_Node_set_m_f_1=b.asm.ir).apply(null,arguments)},zt=b._emscripten_bind_Node_get_m_n_0=function(){return(zt=b._emscripten_bind_Node_get_m_n_0=b.asm.jr).apply(null,arguments)},At=b._emscripten_bind_Node_set_m_n_1=function(){return(At=b._emscripten_bind_Node_set_m_n_1=b.asm.kr).apply(null,arguments)},Bt=
-b._emscripten_bind_Node_get_m_im_0=function(){return(Bt=b._emscripten_bind_Node_get_m_im_0=b.asm.lr).apply(null,arguments)},Ct=b._emscripten_bind_Node_set_m_im_1=function(){return(Ct=b._emscripten_bind_Node_set_m_im_1=b.asm.mr).apply(null,arguments)},Dt=b._emscripten_bind_Node_get_m_area_0=function(){return(Dt=b._emscripten_bind_Node_get_m_area_0=b.asm.nr).apply(null,arguments)},Et=b._emscripten_bind_Node_set_m_area_1=function(){return(Et=b._emscripten_bind_Node_set_m_area_1=b.asm.or).apply(null,
-arguments)},Ft=b._emscripten_bind_Node___destroy___0=function(){return(Ft=b._emscripten_bind_Node___destroy___0=b.asm.pr).apply(null,arguments)},Gt=b._emscripten_bind_btGhostPairCallback_btGhostPairCallback_0=function(){return(Gt=b._emscripten_bind_btGhostPairCallback_btGhostPairCallback_0=b.asm.qr).apply(null,arguments)},Ht=b._emscripten_bind_btGhostPairCallback___destroy___0=function(){return(Ht=b._emscripten_bind_btGhostPairCallback___destroy___0=b.asm.rr).apply(null,arguments)},It=b._emscripten_bind_btOverlappingPairCallback___destroy___0=
-function(){return(It=b._emscripten_bind_btOverlappingPairCallback___destroy___0=b.asm.sr).apply(null,arguments)},Jt=b._emscripten_bind_btKinematicCharacterController_btKinematicCharacterController_3=function(){return(Jt=b._emscripten_bind_btKinematicCharacterController_btKinematicCharacterController_3=b.asm.tr).apply(null,arguments)},Kt=b._emscripten_bind_btKinematicCharacterController_btKinematicCharacterController_4=function(){return(Kt=b._emscripten_bind_btKinematicCharacterController_btKinematicCharacterController_4=
-b.asm.ur).apply(null,arguments)},Lt=b._emscripten_bind_btKinematicCharacterController_setUpAxis_1=function(){return(Lt=b._emscripten_bind_btKinematicCharacterController_setUpAxis_1=b.asm.vr).apply(null,arguments)},Mt=b._emscripten_bind_btKinematicCharacterController_setWalkDirection_1=function(){return(Mt=b._emscripten_bind_btKinematicCharacterController_setWalkDirection_1=b.asm.wr).apply(null,arguments)},Nt=b._emscripten_bind_btKinematicCharacterController_setVelocityForTimeInterval_2=function(){return(Nt=
-b._emscripten_bind_btKinematicCharacterController_setVelocityForTimeInterval_2=b.asm.xr).apply(null,arguments)},Ot=b._emscripten_bind_btKinematicCharacterController_warp_1=function(){return(Ot=b._emscripten_bind_btKinematicCharacterController_warp_1=b.asm.yr).apply(null,arguments)},Pt=b._emscripten_bind_btKinematicCharacterController_preStep_1=function(){return(Pt=b._emscripten_bind_btKinematicCharacterController_preStep_1=b.asm.zr).apply(null,arguments)},Qt=b._emscripten_bind_btKinematicCharacterController_playerStep_2=
-function(){return(Qt=b._emscripten_bind_btKinematicCharacterController_playerStep_2=b.asm.Ar).apply(null,arguments)},Rt=b._emscripten_bind_btKinematicCharacterController_setFallSpeed_1=function(){return(Rt=b._emscripten_bind_btKinematicCharacterController_setFallSpeed_1=b.asm.Br).apply(null,arguments)},St=b._emscripten_bind_btKinematicCharacterController_setJumpSpeed_1=function(){return(St=b._emscripten_bind_btKinematicCharacterController_setJumpSpeed_1=b.asm.Cr).apply(null,arguments)},Tt=b._emscripten_bind_btKinematicCharacterController_setMaxJumpHeight_1=
-function(){return(Tt=b._emscripten_bind_btKinematicCharacterController_setMaxJumpHeight_1=b.asm.Dr).apply(null,arguments)},Ut=b._emscripten_bind_btKinematicCharacterController_canJump_0=function(){return(Ut=b._emscripten_bind_btKinematicCharacterController_canJump_0=b.asm.Er).apply(null,arguments)},Vt=b._emscripten_bind_btKinematicCharacterController_jump_0=function(){return(Vt=b._emscripten_bind_btKinematicCharacterController_jump_0=b.asm.Fr).apply(null,arguments)},Wt=b._emscripten_bind_btKinematicCharacterController_setGravity_1=
-function(){return(Wt=b._emscripten_bind_btKinematicCharacterController_setGravity_1=b.asm.Gr).apply(null,arguments)},Xt=b._emscripten_bind_btKinematicCharacterController_getGravity_0=function(){return(Xt=b._emscripten_bind_btKinematicCharacterController_getGravity_0=b.asm.Hr).apply(null,arguments)},Yt=b._emscripten_bind_btKinematicCharacterController_setMaxSlope_1=function(){return(Yt=b._emscripten_bind_btKinematicCharacterController_setMaxSlope_1=b.asm.Ir).apply(null,arguments)},Zt=b._emscripten_bind_btKinematicCharacterController_getMaxSlope_0=
-function(){return(Zt=b._emscripten_bind_btKinematicCharacterController_getMaxSlope_0=b.asm.Jr).apply(null,arguments)},$t=b._emscripten_bind_btKinematicCharacterController_getGhostObject_0=function(){return($t=b._emscripten_bind_btKinematicCharacterController_getGhostObject_0=b.asm.Kr).apply(null,arguments)},au=b._emscripten_bind_btKinematicCharacterController_setUseGhostSweepTest_1=function(){return(au=b._emscripten_bind_btKinematicCharacterController_setUseGhostSweepTest_1=b.asm.Lr).apply(null,arguments)},
-bu=b._emscripten_bind_btKinematicCharacterController_onGround_0=function(){return(bu=b._emscripten_bind_btKinematicCharacterController_onGround_0=b.asm.Mr).apply(null,arguments)},cu=b._emscripten_bind_btKinematicCharacterController_setUpInterpolate_1=function(){return(cu=b._emscripten_bind_btKinematicCharacterController_setUpInterpolate_1=b.asm.Nr).apply(null,arguments)},du=b._emscripten_bind_btKinematicCharacterController_updateAction_2=function(){return(du=b._emscripten_bind_btKinematicCharacterController_updateAction_2=
-b.asm.Or).apply(null,arguments)},eu=b._emscripten_bind_btKinematicCharacterController___destroy___0=function(){return(eu=b._emscripten_bind_btKinematicCharacterController___destroy___0=b.asm.Pr).apply(null,arguments)},fu=b._emscripten_bind_btSoftBodyArray_size_0=function(){return(fu=b._emscripten_bind_btSoftBodyArray_size_0=b.asm.Qr).apply(null,arguments)},gu=b._emscripten_bind_btSoftBodyArray_at_1=function(){return(gu=b._emscripten_bind_btSoftBodyArray_at_1=b.asm.Rr).apply(null,arguments)},hu=b._emscripten_bind_btSoftBodyArray___destroy___0=
-function(){return(hu=b._emscripten_bind_btSoftBodyArray___destroy___0=b.asm.Sr).apply(null,arguments)},iu=b._emscripten_bind_btFaceArray_size_0=function(){return(iu=b._emscripten_bind_btFaceArray_size_0=b.asm.Tr).apply(null,arguments)},ju=b._emscripten_bind_btFaceArray_at_1=function(){return(ju=b._emscripten_bind_btFaceArray_at_1=b.asm.Ur).apply(null,arguments)},ku=b._emscripten_bind_btFaceArray___destroy___0=function(){return(ku=b._emscripten_bind_btFaceArray___destroy___0=b.asm.Vr).apply(null,arguments)},
-lu=b._emscripten_bind_btStaticPlaneShape_btStaticPlaneShape_2=function(){return(lu=b._emscripten_bind_btStaticPlaneShape_btStaticPlaneShape_2=b.asm.Wr).apply(null,arguments)},mu=b._emscripten_bind_btStaticPlaneShape_setLocalScaling_1=function(){return(mu=b._emscripten_bind_btStaticPlaneShape_setLocalScaling_1=b.asm.Xr).apply(null,arguments)},nu=b._emscripten_bind_btStaticPlaneShape_getLocalScaling_0=function(){return(nu=b._emscripten_bind_btStaticPlaneShape_getLocalScaling_0=b.asm.Yr).apply(null,
-arguments)},ou=b._emscripten_bind_btStaticPlaneShape_calculateLocalInertia_2=function(){return(ou=b._emscripten_bind_btStaticPlaneShape_calculateLocalInertia_2=b.asm.Zr).apply(null,arguments)},pu=b._emscripten_bind_btStaticPlaneShape___destroy___0=function(){return(pu=b._emscripten_bind_btStaticPlaneShape___destroy___0=b.asm._r).apply(null,arguments)},qu=b._emscripten_bind_btOverlappingPairCache_setInternalGhostPairCallback_1=function(){return(qu=b._emscripten_bind_btOverlappingPairCache_setInternalGhostPairCallback_1=
-b.asm.$r).apply(null,arguments)},ru=b._emscripten_bind_btOverlappingPairCache_getNumOverlappingPairs_0=function(){return(ru=b._emscripten_bind_btOverlappingPairCache_getNumOverlappingPairs_0=b.asm.as).apply(null,arguments)},su=b._emscripten_bind_btOverlappingPairCache___destroy___0=function(){return(su=b._emscripten_bind_btOverlappingPairCache___destroy___0=b.asm.bs).apply(null,arguments)},tu=b._emscripten_bind_btIndexedMesh_get_m_numTriangles_0=function(){return(tu=b._emscripten_bind_btIndexedMesh_get_m_numTriangles_0=
-b.asm.cs).apply(null,arguments)},uu=b._emscripten_bind_btIndexedMesh_set_m_numTriangles_1=function(){return(uu=b._emscripten_bind_btIndexedMesh_set_m_numTriangles_1=b.asm.ds).apply(null,arguments)},vu=b._emscripten_bind_btIndexedMesh___destroy___0=function(){return(vu=b._emscripten_bind_btIndexedMesh___destroy___0=b.asm.es).apply(null,arguments)},wu=b._emscripten_bind_btSoftRigidDynamicsWorld_btSoftRigidDynamicsWorld_5=function(){return(wu=b._emscripten_bind_btSoftRigidDynamicsWorld_btSoftRigidDynamicsWorld_5=
-b.asm.fs).apply(null,arguments)},xu=b._emscripten_bind_btSoftRigidDynamicsWorld_addSoftBody_3=function(){return(xu=b._emscripten_bind_btSoftRigidDynamicsWorld_addSoftBody_3=b.asm.gs).apply(null,arguments)},yu=b._emscripten_bind_btSoftRigidDynamicsWorld_removeSoftBody_1=function(){return(yu=b._emscripten_bind_btSoftRigidDynamicsWorld_removeSoftBody_1=b.asm.hs).apply(null,arguments)},zu=b._emscripten_bind_btSoftRigidDynamicsWorld_removeCollisionObject_1=function(){return(zu=b._emscripten_bind_btSoftRigidDynamicsWorld_removeCollisionObject_1=
-b.asm.is).apply(null,arguments)},Au=b._emscripten_bind_btSoftRigidDynamicsWorld_getWorldInfo_0=function(){return(Au=b._emscripten_bind_btSoftRigidDynamicsWorld_getWorldInfo_0=b.asm.js).apply(null,arguments)},Bu=b._emscripten_bind_btSoftRigidDynamicsWorld_getSoftBodyArray_0=function(){return(Bu=b._emscripten_bind_btSoftRigidDynamicsWorld_getSoftBodyArray_0=b.asm.ks).apply(null,arguments)},Cu=b._emscripten_bind_btSoftRigidDynamicsWorld_getDispatcher_0=function(){return(Cu=b._emscripten_bind_btSoftRigidDynamicsWorld_getDispatcher_0=
-b.asm.ls).apply(null,arguments)},Du=b._emscripten_bind_btSoftRigidDynamicsWorld_rayTest_3=function(){return(Du=b._emscripten_bind_btSoftRigidDynamicsWorld_rayTest_3=b.asm.ms).apply(null,arguments)},Eu=b._emscripten_bind_btSoftRigidDynamicsWorld_getPairCache_0=function(){return(Eu=b._emscripten_bind_btSoftRigidDynamicsWorld_getPairCache_0=b.asm.ns).apply(null,arguments)},Fu=b._emscripten_bind_btSoftRigidDynamicsWorld_getDispatchInfo_0=function(){return(Fu=b._emscripten_bind_btSoftRigidDynamicsWorld_getDispatchInfo_0=
-b.asm.os).apply(null,arguments)},Gu=b._emscripten_bind_btSoftRigidDynamicsWorld_addCollisionObject_1=function(){return(Gu=b._emscripten_bind_btSoftRigidDynamicsWorld_addCollisionObject_1=b.asm.ps).apply(null,arguments)},Hu=b._emscripten_bind_btSoftRigidDynamicsWorld_addCollisionObject_2=function(){return(Hu=b._emscripten_bind_btSoftRigidDynamicsWorld_addCollisionObject_2=b.asm.qs).apply(null,arguments)},Iu=b._emscripten_bind_btSoftRigidDynamicsWorld_addCollisionObject_3=function(){return(Iu=b._emscripten_bind_btSoftRigidDynamicsWorld_addCollisionObject_3=
-b.asm.rs).apply(null,arguments)},Ju=b._emscripten_bind_btSoftRigidDynamicsWorld_getBroadphase_0=function(){return(Ju=b._emscripten_bind_btSoftRigidDynamicsWorld_getBroadphase_0=b.asm.ss).apply(null,arguments)},Ku=b._emscripten_bind_btSoftRigidDynamicsWorld_convexSweepTest_5=function(){return(Ku=b._emscripten_bind_btSoftRigidDynamicsWorld_convexSweepTest_5=b.asm.ts).apply(null,arguments)},Lu=b._emscripten_bind_btSoftRigidDynamicsWorld_contactPairTest_3=function(){return(Lu=b._emscripten_bind_btSoftRigidDynamicsWorld_contactPairTest_3=
-b.asm.us).apply(null,arguments)},Mu=b._emscripten_bind_btSoftRigidDynamicsWorld_contactTest_2=function(){return(Mu=b._emscripten_bind_btSoftRigidDynamicsWorld_contactTest_2=b.asm.vs).apply(null,arguments)},Nu=b._emscripten_bind_btSoftRigidDynamicsWorld_updateSingleAabb_1=function(){return(Nu=b._emscripten_bind_btSoftRigidDynamicsWorld_updateSingleAabb_1=b.asm.ws).apply(null,arguments)},Ou=b._emscripten_bind_btSoftRigidDynamicsWorld_setDebugDrawer_1=function(){return(Ou=b._emscripten_bind_btSoftRigidDynamicsWorld_setDebugDrawer_1=
-b.asm.xs).apply(null,arguments)},Pu=b._emscripten_bind_btSoftRigidDynamicsWorld_getDebugDrawer_0=function(){return(Pu=b._emscripten_bind_btSoftRigidDynamicsWorld_getDebugDrawer_0=b.asm.ys).apply(null,arguments)},Qu=b._emscripten_bind_btSoftRigidDynamicsWorld_debugDrawWorld_0=function(){return(Qu=b._emscripten_bind_btSoftRigidDynamicsWorld_debugDrawWorld_0=b.asm.zs).apply(null,arguments)},Ru=b._emscripten_bind_btSoftRigidDynamicsWorld_debugDrawObject_3=function(){return(Ru=b._emscripten_bind_btSoftRigidDynamicsWorld_debugDrawObject_3=
-b.asm.As).apply(null,arguments)},Su=b._emscripten_bind_btSoftRigidDynamicsWorld_setGravity_1=function(){return(Su=b._emscripten_bind_btSoftRigidDynamicsWorld_setGravity_1=b.asm.Bs).apply(null,arguments)},Tu=b._emscripten_bind_btSoftRigidDynamicsWorld_getGravity_0=function(){return(Tu=b._emscripten_bind_btSoftRigidDynamicsWorld_getGravity_0=b.asm.Cs).apply(null,arguments)},Uu=b._emscripten_bind_btSoftRigidDynamicsWorld_addRigidBody_1=function(){return(Uu=b._emscripten_bind_btSoftRigidDynamicsWorld_addRigidBody_1=
-b.asm.Ds).apply(null,arguments)},Vu=b._emscripten_bind_btSoftRigidDynamicsWorld_addRigidBody_3=function(){return(Vu=b._emscripten_bind_btSoftRigidDynamicsWorld_addRigidBody_3=b.asm.Es).apply(null,arguments)},Wu=b._emscripten_bind_btSoftRigidDynamicsWorld_removeRigidBody_1=function(){return(Wu=b._emscripten_bind_btSoftRigidDynamicsWorld_removeRigidBody_1=b.asm.Fs).apply(null,arguments)},Xu=b._emscripten_bind_btSoftRigidDynamicsWorld_addConstraint_1=function(){return(Xu=b._emscripten_bind_btSoftRigidDynamicsWorld_addConstraint_1=
-b.asm.Gs).apply(null,arguments)},Yu=b._emscripten_bind_btSoftRigidDynamicsWorld_addConstraint_2=function(){return(Yu=b._emscripten_bind_btSoftRigidDynamicsWorld_addConstraint_2=b.asm.Hs).apply(null,arguments)},Zu=b._emscripten_bind_btSoftRigidDynamicsWorld_removeConstraint_1=function(){return(Zu=b._emscripten_bind_btSoftRigidDynamicsWorld_removeConstraint_1=b.asm.Is).apply(null,arguments)},$u=b._emscripten_bind_btSoftRigidDynamicsWorld_stepSimulation_1=function(){return($u=b._emscripten_bind_btSoftRigidDynamicsWorld_stepSimulation_1=
-b.asm.Js).apply(null,arguments)},av=b._emscripten_bind_btSoftRigidDynamicsWorld_stepSimulation_2=function(){return(av=b._emscripten_bind_btSoftRigidDynamicsWorld_stepSimulation_2=b.asm.Ks).apply(null,arguments)},bv=b._emscripten_bind_btSoftRigidDynamicsWorld_stepSimulation_3=function(){return(bv=b._emscripten_bind_btSoftRigidDynamicsWorld_stepSimulation_3=b.asm.Ls).apply(null,arguments)},cv=b._emscripten_bind_btSoftRigidDynamicsWorld_setContactAddedCallback_1=function(){return(cv=b._emscripten_bind_btSoftRigidDynamicsWorld_setContactAddedCallback_1=
-b.asm.Ms).apply(null,arguments)},dv=b._emscripten_bind_btSoftRigidDynamicsWorld_setContactProcessedCallback_1=function(){return(dv=b._emscripten_bind_btSoftRigidDynamicsWorld_setContactProcessedCallback_1=b.asm.Ns).apply(null,arguments)},ev=b._emscripten_bind_btSoftRigidDynamicsWorld_setContactDestroyedCallback_1=function(){return(ev=b._emscripten_bind_btSoftRigidDynamicsWorld_setContactDestroyedCallback_1=b.asm.Os).apply(null,arguments)},fv=b._emscripten_bind_btSoftRigidDynamicsWorld_addAction_1=
-function(){return(fv=b._emscripten_bind_btSoftRigidDynamicsWorld_addAction_1=b.asm.Ps).apply(null,arguments)},gv=b._emscripten_bind_btSoftRigidDynamicsWorld_removeAction_1=function(){return(gv=b._emscripten_bind_btSoftRigidDynamicsWorld_removeAction_1=b.asm.Qs).apply(null,arguments)},hv=b._emscripten_bind_btSoftRigidDynamicsWorld_getSolverInfo_0=function(){return(hv=b._emscripten_bind_btSoftRigidDynamicsWorld_getSolverInfo_0=b.asm.Rs).apply(null,arguments)},iv=b._emscripten_bind_btSoftRigidDynamicsWorld_setInternalTickCallback_1=
-function(){return(iv=b._emscripten_bind_btSoftRigidDynamicsWorld_setInternalTickCallback_1=b.asm.Ss).apply(null,arguments)},jv=b._emscripten_bind_btSoftRigidDynamicsWorld_setInternalTickCallback_2=function(){return(jv=b._emscripten_bind_btSoftRigidDynamicsWorld_setInternalTickCallback_2=b.asm.Ts).apply(null,arguments)},kv=b._emscripten_bind_btSoftRigidDynamicsWorld_setInternalTickCallback_3=function(){return(kv=b._emscripten_bind_btSoftRigidDynamicsWorld_setInternalTickCallback_3=b.asm.Us).apply(null,
-arguments)},lv=b._emscripten_bind_btSoftRigidDynamicsWorld___destroy___0=function(){return(lv=b._emscripten_bind_btSoftRigidDynamicsWorld___destroy___0=b.asm.Vs).apply(null,arguments)},mv=b._emscripten_bind_btFixedConstraint_btFixedConstraint_4=function(){return(mv=b._emscripten_bind_btFixedConstraint_btFixedConstraint_4=b.asm.Ws).apply(null,arguments)},nv=b._emscripten_bind_btFixedConstraint_enableFeedback_1=function(){return(nv=b._emscripten_bind_btFixedConstraint_enableFeedback_1=b.asm.Xs).apply(null,
-arguments)},ov=b._emscripten_bind_btFixedConstraint_getBreakingImpulseThreshold_0=function(){return(ov=b._emscripten_bind_btFixedConstraint_getBreakingImpulseThreshold_0=b.asm.Ys).apply(null,arguments)},pv=b._emscripten_bind_btFixedConstraint_setBreakingImpulseThreshold_1=function(){return(pv=b._emscripten_bind_btFixedConstraint_setBreakingImpulseThreshold_1=b.asm.Zs).apply(null,arguments)},qv=b._emscripten_bind_btFixedConstraint_getParam_2=function(){return(qv=b._emscripten_bind_btFixedConstraint_getParam_2=
-b.asm._s).apply(null,arguments)},rv=b._emscripten_bind_btFixedConstraint_setParam_3=function(){return(rv=b._emscripten_bind_btFixedConstraint_setParam_3=b.asm.$s).apply(null,arguments)},sv=b._emscripten_bind_btFixedConstraint___destroy___0=function(){return(sv=b._emscripten_bind_btFixedConstraint___destroy___0=b.asm.at).apply(null,arguments)},tv=b._emscripten_bind_btTransform_btTransform_0=function(){return(tv=b._emscripten_bind_btTransform_btTransform_0=b.asm.bt).apply(null,arguments)},uv=b._emscripten_bind_btTransform_btTransform_2=
-function(){return(uv=b._emscripten_bind_btTransform_btTransform_2=b.asm.ct).apply(null,arguments)},vv=b._emscripten_bind_btTransform_setIdentity_0=function(){return(vv=b._emscripten_bind_btTransform_setIdentity_0=b.asm.dt).apply(null,arguments)},wv=b._emscripten_bind_btTransform_setOrigin_1=function(){return(wv=b._emscripten_bind_btTransform_setOrigin_1=b.asm.et).apply(null,arguments)},xv=b._emscripten_bind_btTransform_setRotation_1=function(){return(xv=b._emscripten_bind_btTransform_setRotation_1=
-b.asm.ft).apply(null,arguments)},yv=b._emscripten_bind_btTransform_getOrigin_0=function(){return(yv=b._emscripten_bind_btTransform_getOrigin_0=b.asm.gt).apply(null,arguments)},zv=b._emscripten_bind_btTransform_getRotation_0=function(){return(zv=b._emscripten_bind_btTransform_getRotation_0=b.asm.ht).apply(null,arguments)},Av=b._emscripten_bind_btTransform_getBasis_0=function(){return(Av=b._emscripten_bind_btTransform_getBasis_0=b.asm.it).apply(null,arguments)},Bv=b._emscripten_bind_btTransform_setFromOpenGLMatrix_1=
-function(){return(Bv=b._emscripten_bind_btTransform_setFromOpenGLMatrix_1=b.asm.jt).apply(null,arguments)},Cv=b._emscripten_bind_btTransform_inverse_0=function(){return(Cv=b._emscripten_bind_btTransform_inverse_0=b.asm.kt).apply(null,arguments)},Dv=b._emscripten_bind_btTransform_op_mul_1=function(){return(Dv=b._emscripten_bind_btTransform_op_mul_1=b.asm.lt).apply(null,arguments)},Ev=b._emscripten_bind_btTransform___destroy___0=function(){return(Ev=b._emscripten_bind_btTransform___destroy___0=b.asm.mt).apply(null,
-arguments)},Fv=b._emscripten_bind_ClosestRayResultCallback_ClosestRayResultCallback_2=function(){return(Fv=b._emscripten_bind_ClosestRayResultCallback_ClosestRayResultCallback_2=b.asm.nt).apply(null,arguments)},Gv=b._emscripten_bind_ClosestRayResultCallback_hasHit_0=function(){return(Gv=b._emscripten_bind_ClosestRayResultCallback_hasHit_0=b.asm.ot).apply(null,arguments)},Hv=b._emscripten_bind_ClosestRayResultCallback_get_m_rayFromWorld_0=function(){return(Hv=b._emscripten_bind_ClosestRayResultCallback_get_m_rayFromWorld_0=
-b.asm.pt).apply(null,arguments)},Iv=b._emscripten_bind_ClosestRayResultCallback_set_m_rayFromWorld_1=function(){return(Iv=b._emscripten_bind_ClosestRayResultCallback_set_m_rayFromWorld_1=b.asm.qt).apply(null,arguments)},Jv=b._emscripten_bind_ClosestRayResultCallback_get_m_rayToWorld_0=function(){return(Jv=b._emscripten_bind_ClosestRayResultCallback_get_m_rayToWorld_0=b.asm.rt).apply(null,arguments)},Kv=b._emscripten_bind_ClosestRayResultCallback_set_m_rayToWorld_1=function(){return(Kv=b._emscripten_bind_ClosestRayResultCallback_set_m_rayToWorld_1=
-b.asm.st).apply(null,arguments)},Lv=b._emscripten_bind_ClosestRayResultCallback_get_m_hitNormalWorld_0=function(){return(Lv=b._emscripten_bind_ClosestRayResultCallback_get_m_hitNormalWorld_0=b.asm.tt).apply(null,arguments)},Mv=b._emscripten_bind_ClosestRayResultCallback_set_m_hitNormalWorld_1=function(){return(Mv=b._emscripten_bind_ClosestRayResultCallback_set_m_hitNormalWorld_1=b.asm.ut).apply(null,arguments)},Nv=b._emscripten_bind_ClosestRayResultCallback_get_m_hitPointWorld_0=function(){return(Nv=
-b._emscripten_bind_ClosestRayResultCallback_get_m_hitPointWorld_0=b.asm.vt).apply(null,arguments)},Ov=b._emscripten_bind_ClosestRayResultCallback_set_m_hitPointWorld_1=function(){return(Ov=b._emscripten_bind_ClosestRayResultCallback_set_m_hitPointWorld_1=b.asm.wt).apply(null,arguments)},Pv=b._emscripten_bind_ClosestRayResultCallback_get_m_collisionFilterGroup_0=function(){return(Pv=b._emscripten_bind_ClosestRayResultCallback_get_m_collisionFilterGroup_0=b.asm.xt).apply(null,arguments)},Qv=b._emscripten_bind_ClosestRayResultCallback_set_m_collisionFilterGroup_1=
-function(){return(Qv=b._emscripten_bind_ClosestRayResultCallback_set_m_collisionFilterGroup_1=b.asm.yt).apply(null,arguments)},Rv=b._emscripten_bind_ClosestRayResultCallback_get_m_collisionFilterMask_0=function(){return(Rv=b._emscripten_bind_ClosestRayResultCallback_get_m_collisionFilterMask_0=b.asm.zt).apply(null,arguments)},Sv=b._emscripten_bind_ClosestRayResultCallback_set_m_collisionFilterMask_1=function(){return(Sv=b._emscripten_bind_ClosestRayResultCallback_set_m_collisionFilterMask_1=b.asm.At).apply(null,
-arguments)},Tv=b._emscripten_bind_ClosestRayResultCallback_get_m_closestHitFraction_0=function(){return(Tv=b._emscripten_bind_ClosestRayResultCallback_get_m_closestHitFraction_0=b.asm.Bt).apply(null,arguments)},Uv=b._emscripten_bind_ClosestRayResultCallback_set_m_closestHitFraction_1=function(){return(Uv=b._emscripten_bind_ClosestRayResultCallback_set_m_closestHitFraction_1=b.asm.Ct).apply(null,arguments)},Vv=b._emscripten_bind_ClosestRayResultCallback_get_m_collisionObject_0=function(){return(Vv=
-b._emscripten_bind_ClosestRayResultCallback_get_m_collisionObject_0=b.asm.Dt).apply(null,arguments)},Wv=b._emscripten_bind_ClosestRayResultCallback_set_m_collisionObject_1=function(){return(Wv=b._emscripten_bind_ClosestRayResultCallback_set_m_collisionObject_1=b.asm.Et).apply(null,arguments)},Xv=b._emscripten_bind_ClosestRayResultCallback___destroy___0=function(){return(Xv=b._emscripten_bind_ClosestRayResultCallback___destroy___0=b.asm.Ft).apply(null,arguments)},Yv=b._emscripten_bind_btSoftBodyRigidBodyCollisionConfiguration_btSoftBodyRigidBodyCollisionConfiguration_0=
-function(){return(Yv=b._emscripten_bind_btSoftBodyRigidBodyCollisionConfiguration_btSoftBodyRigidBodyCollisionConfiguration_0=b.asm.Gt).apply(null,arguments)},Zv=b._emscripten_bind_btSoftBodyRigidBodyCollisionConfiguration_btSoftBodyRigidBodyCollisionConfiguration_1=function(){return(Zv=b._emscripten_bind_btSoftBodyRigidBodyCollisionConfiguration_btSoftBodyRigidBodyCollisionConfiguration_1=b.asm.Ht).apply(null,arguments)},$v=b._emscripten_bind_btSoftBodyRigidBodyCollisionConfiguration___destroy___0=
-function(){return($v=b._emscripten_bind_btSoftBodyRigidBodyCollisionConfiguration___destroy___0=b.asm.It).apply(null,arguments)},aw=b._emscripten_bind_ConcreteContactResultCallback_ConcreteContactResultCallback_0=function(){return(aw=b._emscripten_bind_ConcreteContactResultCallback_ConcreteContactResultCallback_0=b.asm.Jt).apply(null,arguments)},bw=b._emscripten_bind_ConcreteContactResultCallback_addSingleResult_7=function(){return(bw=b._emscripten_bind_ConcreteContactResultCallback_addSingleResult_7=
-b.asm.Kt).apply(null,arguments)},cw=b._emscripten_bind_ConcreteContactResultCallback___destroy___0=function(){return(cw=b._emscripten_bind_ConcreteContactResultCallback___destroy___0=b.asm.Lt).apply(null,arguments)},dw=b._emscripten_bind_btBvhTriangleMeshShape_btBvhTriangleMeshShape_2=function(){return(dw=b._emscripten_bind_btBvhTriangleMeshShape_btBvhTriangleMeshShape_2=b.asm.Mt).apply(null,arguments)},ew=b._emscripten_bind_btBvhTriangleMeshShape_btBvhTriangleMeshShape_3=function(){return(ew=b._emscripten_bind_btBvhTriangleMeshShape_btBvhTriangleMeshShape_3=
-b.asm.Nt).apply(null,arguments)},fw=b._emscripten_bind_btBvhTriangleMeshShape_setLocalScaling_1=function(){return(fw=b._emscripten_bind_btBvhTriangleMeshShape_setLocalScaling_1=b.asm.Ot).apply(null,arguments)},gw=b._emscripten_bind_btBvhTriangleMeshShape_getLocalScaling_0=function(){return(gw=b._emscripten_bind_btBvhTriangleMeshShape_getLocalScaling_0=b.asm.Pt).apply(null,arguments)},hw=b._emscripten_bind_btBvhTriangleMeshShape_calculateLocalInertia_2=function(){return(hw=b._emscripten_bind_btBvhTriangleMeshShape_calculateLocalInertia_2=
-b.asm.Qt).apply(null,arguments)},iw=b._emscripten_bind_btBvhTriangleMeshShape___destroy___0=function(){return(iw=b._emscripten_bind_btBvhTriangleMeshShape___destroy___0=b.asm.Rt).apply(null,arguments)},jw=b._emscripten_bind_btConstCollisionObjectArray_size_0=function(){return(jw=b._emscripten_bind_btConstCollisionObjectArray_size_0=b.asm.St).apply(null,arguments)},kw=b._emscripten_bind_btConstCollisionObjectArray_at_1=function(){return(kw=b._emscripten_bind_btConstCollisionObjectArray_at_1=b.asm.Tt).apply(null,
-arguments)},lw=b._emscripten_bind_btConstCollisionObjectArray___destroy___0=function(){return(lw=b._emscripten_bind_btConstCollisionObjectArray___destroy___0=b.asm.Ut).apply(null,arguments)},mw=b._emscripten_bind_btSliderConstraint_btSliderConstraint_3=function(){return(mw=b._emscripten_bind_btSliderConstraint_btSliderConstraint_3=b.asm.Vt).apply(null,arguments)},nw=b._emscripten_bind_btSliderConstraint_btSliderConstraint_5=function(){return(nw=b._emscripten_bind_btSliderConstraint_btSliderConstraint_5=
-b.asm.Wt).apply(null,arguments)},ow=b._emscripten_bind_btSliderConstraint_setLowerLinLimit_1=function(){return(ow=b._emscripten_bind_btSliderConstraint_setLowerLinLimit_1=b.asm.Xt).apply(null,arguments)},pw=b._emscripten_bind_btSliderConstraint_setUpperLinLimit_1=function(){return(pw=b._emscripten_bind_btSliderConstraint_setUpperLinLimit_1=b.asm.Yt).apply(null,arguments)},qw=b._emscripten_bind_btSliderConstraint_setLowerAngLimit_1=function(){return(qw=b._emscripten_bind_btSliderConstraint_setLowerAngLimit_1=
-b.asm.Zt).apply(null,arguments)},rw=b._emscripten_bind_btSliderConstraint_setUpperAngLimit_1=function(){return(rw=b._emscripten_bind_btSliderConstraint_setUpperAngLimit_1=b.asm._t).apply(null,arguments)},sw=b._emscripten_bind_btSliderConstraint_enableFeedback_1=function(){return(sw=b._emscripten_bind_btSliderConstraint_enableFeedback_1=b.asm.$t).apply(null,arguments)},tw=b._emscripten_bind_btSliderConstraint_getBreakingImpulseThreshold_0=function(){return(tw=b._emscripten_bind_btSliderConstraint_getBreakingImpulseThreshold_0=
-b.asm.au).apply(null,arguments)},uw=b._emscripten_bind_btSliderConstraint_setBreakingImpulseThreshold_1=function(){return(uw=b._emscripten_bind_btSliderConstraint_setBreakingImpulseThreshold_1=b.asm.bu).apply(null,arguments)},vw=b._emscripten_bind_btSliderConstraint_getParam_2=function(){return(vw=b._emscripten_bind_btSliderConstraint_getParam_2=b.asm.cu).apply(null,arguments)},ww=b._emscripten_bind_btSliderConstraint_setParam_3=function(){return(ww=b._emscripten_bind_btSliderConstraint_setParam_3=
-b.asm.du).apply(null,arguments)},xw=b._emscripten_bind_btSliderConstraint___destroy___0=function(){return(xw=b._emscripten_bind_btSliderConstraint___destroy___0=b.asm.eu).apply(null,arguments)},yw=b._emscripten_bind_btPairCachingGhostObject_btPairCachingGhostObject_0=function(){return(yw=b._emscripten_bind_btPairCachingGhostObject_btPairCachingGhostObject_0=b.asm.fu).apply(null,arguments)},zw=b._emscripten_bind_btPairCachingGhostObject_setAnisotropicFriction_2=function(){return(zw=b._emscripten_bind_btPairCachingGhostObject_setAnisotropicFriction_2=
-b.asm.gu).apply(null,arguments)},Aw=b._emscripten_bind_btPairCachingGhostObject_getCollisionShape_0=function(){return(Aw=b._emscripten_bind_btPairCachingGhostObject_getCollisionShape_0=b.asm.hu).apply(null,arguments)},Bw=b._emscripten_bind_btPairCachingGhostObject_setContactProcessingThreshold_1=function(){return(Bw=b._emscripten_bind_btPairCachingGhostObject_setContactProcessingThreshold_1=b.asm.iu).apply(null,arguments)},Cw=b._emscripten_bind_btPairCachingGhostObject_setActivationState_1=function(){return(Cw=
-b._emscripten_bind_btPairCachingGhostObject_setActivationState_1=b.asm.ju).apply(null,arguments)},Dw=b._emscripten_bind_btPairCachingGhostObject_forceActivationState_1=function(){return(Dw=b._emscripten_bind_btPairCachingGhostObject_forceActivationState_1=b.asm.ku).apply(null,arguments)},Ew=b._emscripten_bind_btPairCachingGhostObject_activate_0=function(){return(Ew=b._emscripten_bind_btPairCachingGhostObject_activate_0=b.asm.lu).apply(null,arguments)},Fw=b._emscripten_bind_btPairCachingGhostObject_activate_1=
-function(){return(Fw=b._emscripten_bind_btPairCachingGhostObject_activate_1=b.asm.mu).apply(null,arguments)},Gw=b._emscripten_bind_btPairCachingGhostObject_isActive_0=function(){return(Gw=b._emscripten_bind_btPairCachingGhostObject_isActive_0=b.asm.nu).apply(null,arguments)},Hw=b._emscripten_bind_btPairCachingGhostObject_isKinematicObject_0=function(){return(Hw=b._emscripten_bind_btPairCachingGhostObject_isKinematicObject_0=b.asm.ou).apply(null,arguments)},Iw=b._emscripten_bind_btPairCachingGhostObject_isStaticObject_0=
-function(){return(Iw=b._emscripten_bind_btPairCachingGhostObject_isStaticObject_0=b.asm.pu).apply(null,arguments)},Jw=b._emscripten_bind_btPairCachingGhostObject_isStaticOrKinematicObject_0=function(){return(Jw=b._emscripten_bind_btPairCachingGhostObject_isStaticOrKinematicObject_0=b.asm.qu).apply(null,arguments)},Kw=b._emscripten_bind_btPairCachingGhostObject_getRestitution_0=function(){return(Kw=b._emscripten_bind_btPairCachingGhostObject_getRestitution_0=b.asm.ru).apply(null,arguments)},Lw=b._emscripten_bind_btPairCachingGhostObject_getFriction_0=
-function(){return(Lw=b._emscripten_bind_btPairCachingGhostObject_getFriction_0=b.asm.su).apply(null,arguments)},Mw=b._emscripten_bind_btPairCachingGhostObject_getRollingFriction_0=function(){return(Mw=b._emscripten_bind_btPairCachingGhostObject_getRollingFriction_0=b.asm.tu).apply(null,arguments)},Nw=b._emscripten_bind_btPairCachingGhostObject_setRestitution_1=function(){return(Nw=b._emscripten_bind_btPairCachingGhostObject_setRestitution_1=b.asm.uu).apply(null,arguments)},Ow=b._emscripten_bind_btPairCachingGhostObject_setFriction_1=
-function(){return(Ow=b._emscripten_bind_btPairCachingGhostObject_setFriction_1=b.asm.vu).apply(null,arguments)},Pw=b._emscripten_bind_btPairCachingGhostObject_setRollingFriction_1=function(){return(Pw=b._emscripten_bind_btPairCachingGhostObject_setRollingFriction_1=b.asm.wu).apply(null,arguments)},Qw=b._emscripten_bind_btPairCachingGhostObject_getWorldTransform_0=function(){return(Qw=b._emscripten_bind_btPairCachingGhostObject_getWorldTransform_0=b.asm.xu).apply(null,arguments)},Rw=b._emscripten_bind_btPairCachingGhostObject_getCollisionFlags_0=
-function(){return(Rw=b._emscripten_bind_btPairCachingGhostObject_getCollisionFlags_0=b.asm.yu).apply(null,arguments)},Sw=b._emscripten_bind_btPairCachingGhostObject_setCollisionFlags_1=function(){return(Sw=b._emscripten_bind_btPairCachingGhostObject_setCollisionFlags_1=b.asm.zu).apply(null,arguments)},Tw=b._emscripten_bind_btPairCachingGhostObject_setWorldTransform_1=function(){return(Tw=b._emscripten_bind_btPairCachingGhostObject_setWorldTransform_1=b.asm.Au).apply(null,arguments)},Uw=b._emscripten_bind_btPairCachingGhostObject_setCollisionShape_1=
-function(){return(Uw=b._emscripten_bind_btPairCachingGhostObject_setCollisionShape_1=b.asm.Bu).apply(null,arguments)},Vw=b._emscripten_bind_btPairCachingGhostObject_setCcdMotionThreshold_1=function(){return(Vw=b._emscripten_bind_btPairCachingGhostObject_setCcdMotionThreshold_1=b.asm.Cu).apply(null,arguments)},Ww=b._emscripten_bind_btPairCachingGhostObject_setCcdSweptSphereRadius_1=function(){return(Ww=b._emscripten_bind_btPairCachingGhostObject_setCcdSweptSphereRadius_1=b.asm.Du).apply(null,arguments)},
-Xw=b._emscripten_bind_btPairCachingGhostObject_getUserIndex_0=function(){return(Xw=b._emscripten_bind_btPairCachingGhostObject_getUserIndex_0=b.asm.Eu).apply(null,arguments)},Yw=b._emscripten_bind_btPairCachingGhostObject_setUserIndex_1=function(){return(Yw=b._emscripten_bind_btPairCachingGhostObject_setUserIndex_1=b.asm.Fu).apply(null,arguments)},Zw=b._emscripten_bind_btPairCachingGhostObject_getUserPointer_0=function(){return(Zw=b._emscripten_bind_btPairCachingGhostObject_getUserPointer_0=b.asm.Gu).apply(null,
-arguments)},$w=b._emscripten_bind_btPairCachingGhostObject_setUserPointer_1=function(){return($w=b._emscripten_bind_btPairCachingGhostObject_setUserPointer_1=b.asm.Hu).apply(null,arguments)},ax=b._emscripten_bind_btPairCachingGhostObject_getBroadphaseHandle_0=function(){return(ax=b._emscripten_bind_btPairCachingGhostObject_getBroadphaseHandle_0=b.asm.Iu).apply(null,arguments)},bx=b._emscripten_bind_btPairCachingGhostObject_getNumOverlappingObjects_0=function(){return(bx=b._emscripten_bind_btPairCachingGhostObject_getNumOverlappingObjects_0=
-b.asm.Ju).apply(null,arguments)},cx=b._emscripten_bind_btPairCachingGhostObject_getOverlappingObject_1=function(){return(cx=b._emscripten_bind_btPairCachingGhostObject_getOverlappingObject_1=b.asm.Ku).apply(null,arguments)},dx=b._emscripten_bind_btPairCachingGhostObject___destroy___0=function(){return(dx=b._emscripten_bind_btPairCachingGhostObject___destroy___0=b.asm.Lu).apply(null,arguments)},ex=b._emscripten_bind_btManifoldPoint_getPositionWorldOnA_0=function(){return(ex=b._emscripten_bind_btManifoldPoint_getPositionWorldOnA_0=
-b.asm.Mu).apply(null,arguments)},fx=b._emscripten_bind_btManifoldPoint_getPositionWorldOnB_0=function(){return(fx=b._emscripten_bind_btManifoldPoint_getPositionWorldOnB_0=b.asm.Nu).apply(null,arguments)},gx=b._emscripten_bind_btManifoldPoint_getAppliedImpulse_0=function(){return(gx=b._emscripten_bind_btManifoldPoint_getAppliedImpulse_0=b.asm.Ou).apply(null,arguments)},hx=b._emscripten_bind_btManifoldPoint_getDistance_0=function(){return(hx=b._emscripten_bind_btManifoldPoint_getDistance_0=b.asm.Pu).apply(null,
-arguments)},ix=b._emscripten_bind_btManifoldPoint_get_m_localPointA_0=function(){return(ix=b._emscripten_bind_btManifoldPoint_get_m_localPointA_0=b.asm.Qu).apply(null,arguments)},jx=b._emscripten_bind_btManifoldPoint_set_m_localPointA_1=function(){return(jx=b._emscripten_bind_btManifoldPoint_set_m_localPointA_1=b.asm.Ru).apply(null,arguments)},kx=b._emscripten_bind_btManifoldPoint_get_m_localPointB_0=function(){return(kx=b._emscripten_bind_btManifoldPoint_get_m_localPointB_0=b.asm.Su).apply(null,
-arguments)},lx=b._emscripten_bind_btManifoldPoint_set_m_localPointB_1=function(){return(lx=b._emscripten_bind_btManifoldPoint_set_m_localPointB_1=b.asm.Tu).apply(null,arguments)},mx=b._emscripten_bind_btManifoldPoint_get_m_positionWorldOnB_0=function(){return(mx=b._emscripten_bind_btManifoldPoint_get_m_positionWorldOnB_0=b.asm.Uu).apply(null,arguments)},nx=b._emscripten_bind_btManifoldPoint_set_m_positionWorldOnB_1=function(){return(nx=b._emscripten_bind_btManifoldPoint_set_m_positionWorldOnB_1=b.asm.Vu).apply(null,
-arguments)},ox=b._emscripten_bind_btManifoldPoint_get_m_positionWorldOnA_0=function(){return(ox=b._emscripten_bind_btManifoldPoint_get_m_positionWorldOnA_0=b.asm.Wu).apply(null,arguments)},px=b._emscripten_bind_btManifoldPoint_set_m_positionWorldOnA_1=function(){return(px=b._emscripten_bind_btManifoldPoint_set_m_positionWorldOnA_1=b.asm.Xu).apply(null,arguments)},qx=b._emscripten_bind_btManifoldPoint_get_m_normalWorldOnB_0=function(){return(qx=b._emscripten_bind_btManifoldPoint_get_m_normalWorldOnB_0=
-b.asm.Yu).apply(null,arguments)},rx=b._emscripten_bind_btManifoldPoint_set_m_normalWorldOnB_1=function(){return(rx=b._emscripten_bind_btManifoldPoint_set_m_normalWorldOnB_1=b.asm.Zu).apply(null,arguments)},sx=b._emscripten_bind_btManifoldPoint_get_m_userPersistentData_0=function(){return(sx=b._emscripten_bind_btManifoldPoint_get_m_userPersistentData_0=b.asm._u).apply(null,arguments)},tx=b._emscripten_bind_btManifoldPoint_set_m_userPersistentData_1=function(){return(tx=b._emscripten_bind_btManifoldPoint_set_m_userPersistentData_1=
-b.asm.$u).apply(null,arguments)},ux=b._emscripten_bind_btManifoldPoint___destroy___0=function(){return(ux=b._emscripten_bind_btManifoldPoint___destroy___0=b.asm.av).apply(null,arguments)},vx=b._emscripten_bind_btPoint2PointConstraint_btPoint2PointConstraint_2=function(){return(vx=b._emscripten_bind_btPoint2PointConstraint_btPoint2PointConstraint_2=b.asm.bv).apply(null,arguments)},wx=b._emscripten_bind_btPoint2PointConstraint_btPoint2PointConstraint_4=function(){return(wx=b._emscripten_bind_btPoint2PointConstraint_btPoint2PointConstraint_4=
-b.asm.cv).apply(null,arguments)},xx=b._emscripten_bind_btPoint2PointConstraint_setPivotA_1=function(){return(xx=b._emscripten_bind_btPoint2PointConstraint_setPivotA_1=b.asm.dv).apply(null,arguments)},yx=b._emscripten_bind_btPoint2PointConstraint_setPivotB_1=function(){return(yx=b._emscripten_bind_btPoint2PointConstraint_setPivotB_1=b.asm.ev).apply(null,arguments)},zx=b._emscripten_bind_btPoint2PointConstraint_getPivotInA_0=function(){return(zx=b._emscripten_bind_btPoint2PointConstraint_getPivotInA_0=
-b.asm.fv).apply(null,arguments)},Ax=b._emscripten_bind_btPoint2PointConstraint_getPivotInB_0=function(){return(Ax=b._emscripten_bind_btPoint2PointConstraint_getPivotInB_0=b.asm.gv).apply(null,arguments)},Bx=b._emscripten_bind_btPoint2PointConstraint_enableFeedback_1=function(){return(Bx=b._emscripten_bind_btPoint2PointConstraint_enableFeedback_1=b.asm.hv).apply(null,arguments)},Cx=b._emscripten_bind_btPoint2PointConstraint_getBreakingImpulseThreshold_0=function(){return(Cx=b._emscripten_bind_btPoint2PointConstraint_getBreakingImpulseThreshold_0=
-b.asm.iv).apply(null,arguments)},Dx=b._emscripten_bind_btPoint2PointConstraint_setBreakingImpulseThreshold_1=function(){return(Dx=b._emscripten_bind_btPoint2PointConstraint_setBreakingImpulseThreshold_1=b.asm.jv).apply(null,arguments)},Ex=b._emscripten_bind_btPoint2PointConstraint_getParam_2=function(){return(Ex=b._emscripten_bind_btPoint2PointConstraint_getParam_2=b.asm.kv).apply(null,arguments)},Fx=b._emscripten_bind_btPoint2PointConstraint_setParam_3=function(){return(Fx=b._emscripten_bind_btPoint2PointConstraint_setParam_3=
-b.asm.lv).apply(null,arguments)},Gx=b._emscripten_bind_btPoint2PointConstraint_get_m_setting_0=function(){return(Gx=b._emscripten_bind_btPoint2PointConstraint_get_m_setting_0=b.asm.mv).apply(null,arguments)},Hx=b._emscripten_bind_btPoint2PointConstraint_set_m_setting_1=function(){return(Hx=b._emscripten_bind_btPoint2PointConstraint_set_m_setting_1=b.asm.nv).apply(null,arguments)},Ix=b._emscripten_bind_btPoint2PointConstraint___destroy___0=function(){return(Ix=b._emscripten_bind_btPoint2PointConstraint___destroy___0=
-b.asm.ov).apply(null,arguments)},Jx=b._emscripten_bind_btSoftBodyHelpers_btSoftBodyHelpers_0=function(){return(Jx=b._emscripten_bind_btSoftBodyHelpers_btSoftBodyHelpers_0=b.asm.pv).apply(null,arguments)},Kx=b._emscripten_bind_btSoftBodyHelpers_CreateRope_5=function(){return(Kx=b._emscripten_bind_btSoftBodyHelpers_CreateRope_5=b.asm.qv).apply(null,arguments)},Lx=b._emscripten_bind_btSoftBodyHelpers_CreatePatch_9=function(){return(Lx=b._emscripten_bind_btSoftBodyHelpers_CreatePatch_9=b.asm.rv).apply(null,
-arguments)},Mx=b._emscripten_bind_btSoftBodyHelpers_CreatePatchUV_10=function(){return(Mx=b._emscripten_bind_btSoftBodyHelpers_CreatePatchUV_10=b.asm.sv).apply(null,arguments)},Nx=b._emscripten_bind_btSoftBodyHelpers_CreateEllipsoid_4=function(){return(Nx=b._emscripten_bind_btSoftBodyHelpers_CreateEllipsoid_4=b.asm.tv).apply(null,arguments)},Ox=b._emscripten_bind_btSoftBodyHelpers_CreateFromTriMesh_5=function(){return(Ox=b._emscripten_bind_btSoftBodyHelpers_CreateFromTriMesh_5=b.asm.uv).apply(null,
-arguments)},Px=b._emscripten_bind_btSoftBodyHelpers_CreateFromConvexHull_4=function(){return(Px=b._emscripten_bind_btSoftBodyHelpers_CreateFromConvexHull_4=b.asm.vv).apply(null,arguments)},Qx=b._emscripten_bind_btSoftBodyHelpers___destroy___0=function(){return(Qx=b._emscripten_bind_btSoftBodyHelpers___destroy___0=b.asm.wv).apply(null,arguments)},Rx=b._emscripten_bind_btBroadphaseProxy_get_m_collisionFilterGroup_0=function(){return(Rx=b._emscripten_bind_btBroadphaseProxy_get_m_collisionFilterGroup_0=
-b.asm.xv).apply(null,arguments)},Sx=b._emscripten_bind_btBroadphaseProxy_set_m_collisionFilterGroup_1=function(){return(Sx=b._emscripten_bind_btBroadphaseProxy_set_m_collisionFilterGroup_1=b.asm.yv).apply(null,arguments)},Tx=b._emscripten_bind_btBroadphaseProxy_get_m_collisionFilterMask_0=function(){return(Tx=b._emscripten_bind_btBroadphaseProxy_get_m_collisionFilterMask_0=b.asm.zv).apply(null,arguments)},Ux=b._emscripten_bind_btBroadphaseProxy_set_m_collisionFilterMask_1=function(){return(Ux=b._emscripten_bind_btBroadphaseProxy_set_m_collisionFilterMask_1=
-b.asm.Av).apply(null,arguments)},Vx=b._emscripten_bind_btBroadphaseProxy___destroy___0=function(){return(Vx=b._emscripten_bind_btBroadphaseProxy___destroy___0=b.asm.Bv).apply(null,arguments)},Wx=b._emscripten_bind_tNodeArray_size_0=function(){return(Wx=b._emscripten_bind_tNodeArray_size_0=b.asm.Cv).apply(null,arguments)},Xx=b._emscripten_bind_tNodeArray_at_1=function(){return(Xx=b._emscripten_bind_tNodeArray_at_1=b.asm.Dv).apply(null,arguments)},Yx=b._emscripten_bind_tNodeArray___destroy___0=function(){return(Yx=
-b._emscripten_bind_tNodeArray___destroy___0=b.asm.Ev).apply(null,arguments)},Zx=b._emscripten_bind_btBoxShape_btBoxShape_1=function(){return(Zx=b._emscripten_bind_btBoxShape_btBoxShape_1=b.asm.Fv).apply(null,arguments)},$x=b._emscripten_bind_btBoxShape_setMargin_1=function(){return($x=b._emscripten_bind_btBoxShape_setMargin_1=b.asm.Gv).apply(null,arguments)},ay=b._emscripten_bind_btBoxShape_getMargin_0=function(){return(ay=b._emscripten_bind_btBoxShape_getMargin_0=b.asm.Hv).apply(null,arguments)},
-by=b._emscripten_bind_btBoxShape_setLocalScaling_1=function(){return(by=b._emscripten_bind_btBoxShape_setLocalScaling_1=b.asm.Iv).apply(null,arguments)},cy=b._emscripten_bind_btBoxShape_getLocalScaling_0=function(){return(cy=b._emscripten_bind_btBoxShape_getLocalScaling_0=b.asm.Jv).apply(null,arguments)},dy=b._emscripten_bind_btBoxShape_calculateLocalInertia_2=function(){return(dy=b._emscripten_bind_btBoxShape_calculateLocalInertia_2=b.asm.Kv).apply(null,arguments)},ey=b._emscripten_bind_btBoxShape___destroy___0=
-function(){return(ey=b._emscripten_bind_btBoxShape___destroy___0=b.asm.Lv).apply(null,arguments)},fy=b._emscripten_bind_btFace_get_m_indices_0=function(){return(fy=b._emscripten_bind_btFace_get_m_indices_0=b.asm.Mv).apply(null,arguments)},gy=b._emscripten_bind_btFace_set_m_indices_1=function(){return(gy=b._emscripten_bind_btFace_set_m_indices_1=b.asm.Nv).apply(null,arguments)},hy=b._emscripten_bind_btFace_get_m_plane_1=function(){return(hy=b._emscripten_bind_btFace_get_m_plane_1=b.asm.Ov).apply(null,
-arguments)},iy=b._emscripten_bind_btFace_set_m_plane_2=function(){return(iy=b._emscripten_bind_btFace_set_m_plane_2=b.asm.Pv).apply(null,arguments)},jy=b._emscripten_bind_btFace___destroy___0=function(){return(jy=b._emscripten_bind_btFace___destroy___0=b.asm.Qv).apply(null,arguments)},ky=b._emscripten_bind_DebugDrawer_DebugDrawer_0=function(){return(ky=b._emscripten_bind_DebugDrawer_DebugDrawer_0=b.asm.Rv).apply(null,arguments)},ly=b._emscripten_bind_DebugDrawer_drawLine_3=function(){return(ly=b._emscripten_bind_DebugDrawer_drawLine_3=
-b.asm.Sv).apply(null,arguments)},my=b._emscripten_bind_DebugDrawer_drawContactPoint_5=function(){return(my=b._emscripten_bind_DebugDrawer_drawContactPoint_5=b.asm.Tv).apply(null,arguments)},ny=b._emscripten_bind_DebugDrawer_reportErrorWarning_1=function(){return(ny=b._emscripten_bind_DebugDrawer_reportErrorWarning_1=b.asm.Uv).apply(null,arguments)},oy=b._emscripten_bind_DebugDrawer_draw3dText_2=function(){return(oy=b._emscripten_bind_DebugDrawer_draw3dText_2=b.asm.Vv).apply(null,arguments)},py=b._emscripten_bind_DebugDrawer_setDebugMode_1=
-function(){return(py=b._emscripten_bind_DebugDrawer_setDebugMode_1=b.asm.Wv).apply(null,arguments)},qy=b._emscripten_bind_DebugDrawer_getDebugMode_0=function(){return(qy=b._emscripten_bind_DebugDrawer_getDebugMode_0=b.asm.Xv).apply(null,arguments)},ry=b._emscripten_bind_DebugDrawer___destroy___0=function(){return(ry=b._emscripten_bind_DebugDrawer___destroy___0=b.asm.Yv).apply(null,arguments)},sy=b._emscripten_bind_btCapsuleShapeX_btCapsuleShapeX_2=function(){return(sy=b._emscripten_bind_btCapsuleShapeX_btCapsuleShapeX_2=
-b.asm.Zv).apply(null,arguments)},ty=b._emscripten_bind_btCapsuleShapeX_setMargin_1=function(){return(ty=b._emscripten_bind_btCapsuleShapeX_setMargin_1=b.asm._v).apply(null,arguments)},uy=b._emscripten_bind_btCapsuleShapeX_getMargin_0=function(){return(uy=b._emscripten_bind_btCapsuleShapeX_getMargin_0=b.asm.$v).apply(null,arguments)},vy=b._emscripten_bind_btCapsuleShapeX_getUpAxis_0=function(){return(vy=b._emscripten_bind_btCapsuleShapeX_getUpAxis_0=b.asm.aw).apply(null,arguments)},wy=b._emscripten_bind_btCapsuleShapeX_getRadius_0=
-function(){return(wy=b._emscripten_bind_btCapsuleShapeX_getRadius_0=b.asm.bw).apply(null,arguments)},xy=b._emscripten_bind_btCapsuleShapeX_getHalfHeight_0=function(){return(xy=b._emscripten_bind_btCapsuleShapeX_getHalfHeight_0=b.asm.cw).apply(null,arguments)},yy=b._emscripten_bind_btCapsuleShapeX_setLocalScaling_1=function(){return(yy=b._emscripten_bind_btCapsuleShapeX_setLocalScaling_1=b.asm.dw).apply(null,arguments)},zy=b._emscripten_bind_btCapsuleShapeX_getLocalScaling_0=function(){return(zy=b._emscripten_bind_btCapsuleShapeX_getLocalScaling_0=
-b.asm.ew).apply(null,arguments)},Ay=b._emscripten_bind_btCapsuleShapeX_calculateLocalInertia_2=function(){return(Ay=b._emscripten_bind_btCapsuleShapeX_calculateLocalInertia_2=b.asm.fw).apply(null,arguments)},By=b._emscripten_bind_btCapsuleShapeX___destroy___0=function(){return(By=b._emscripten_bind_btCapsuleShapeX___destroy___0=b.asm.gw).apply(null,arguments)},Cy=b._emscripten_bind_btQuaternion_btQuaternion_4=function(){return(Cy=b._emscripten_bind_btQuaternion_btQuaternion_4=b.asm.hw).apply(null,
-arguments)},Dy=b._emscripten_bind_btQuaternion_setValue_4=function(){return(Dy=b._emscripten_bind_btQuaternion_setValue_4=b.asm.iw).apply(null,arguments)},Ey=b._emscripten_bind_btQuaternion_setEulerZYX_3=function(){return(Ey=b._emscripten_bind_btQuaternion_setEulerZYX_3=b.asm.jw).apply(null,arguments)},Fy=b._emscripten_bind_btQuaternion_setRotation_2=function(){return(Fy=b._emscripten_bind_btQuaternion_setRotation_2=b.asm.kw).apply(null,arguments)},Gy=b._emscripten_bind_btQuaternion_normalize_0=function(){return(Gy=
-b._emscripten_bind_btQuaternion_normalize_0=b.asm.lw).apply(null,arguments)},Hy=b._emscripten_bind_btQuaternion_length2_0=function(){return(Hy=b._emscripten_bind_btQuaternion_length2_0=b.asm.mw).apply(null,arguments)},Iy=b._emscripten_bind_btQuaternion_length_0=function(){return(Iy=b._emscripten_bind_btQuaternion_length_0=b.asm.nw).apply(null,arguments)},Jy=b._emscripten_bind_btQuaternion_dot_1=function(){return(Jy=b._emscripten_bind_btQuaternion_dot_1=b.asm.ow).apply(null,arguments)},Ky=b._emscripten_bind_btQuaternion_normalized_0=
-function(){return(Ky=b._emscripten_bind_btQuaternion_normalized_0=b.asm.pw).apply(null,arguments)},Ly=b._emscripten_bind_btQuaternion_getAxis_0=function(){return(Ly=b._emscripten_bind_btQuaternion_getAxis_0=b.asm.qw).apply(null,arguments)},My=b._emscripten_bind_btQuaternion_inverse_0=function(){return(My=b._emscripten_bind_btQuaternion_inverse_0=b.asm.rw).apply(null,arguments)},Ny=b._emscripten_bind_btQuaternion_getAngle_0=function(){return(Ny=b._emscripten_bind_btQuaternion_getAngle_0=b.asm.sw).apply(null,
-arguments)},Oy=b._emscripten_bind_btQuaternion_getAngleShortestPath_0=function(){return(Oy=b._emscripten_bind_btQuaternion_getAngleShortestPath_0=b.asm.tw).apply(null,arguments)},Py=b._emscripten_bind_btQuaternion_angle_1=function(){return(Py=b._emscripten_bind_btQuaternion_angle_1=b.asm.uw).apply(null,arguments)},Qy=b._emscripten_bind_btQuaternion_angleShortestPath_1=function(){return(Qy=b._emscripten_bind_btQuaternion_angleShortestPath_1=b.asm.vw).apply(null,arguments)},Ry=b._emscripten_bind_btQuaternion_op_add_1=
-function(){return(Ry=b._emscripten_bind_btQuaternion_op_add_1=b.asm.ww).apply(null,arguments)},Sy=b._emscripten_bind_btQuaternion_op_sub_1=function(){return(Sy=b._emscripten_bind_btQuaternion_op_sub_1=b.asm.xw).apply(null,arguments)},Ty=b._emscripten_bind_btQuaternion_op_mul_1=function(){return(Ty=b._emscripten_bind_btQuaternion_op_mul_1=b.asm.yw).apply(null,arguments)},Uy=b._emscripten_bind_btQuaternion_op_mulq_1=function(){return(Uy=b._emscripten_bind_btQuaternion_op_mulq_1=b.asm.zw).apply(null,
-arguments)},Vy=b._emscripten_bind_btQuaternion_op_div_1=function(){return(Vy=b._emscripten_bind_btQuaternion_op_div_1=b.asm.Aw).apply(null,arguments)},Wy=b._emscripten_bind_btQuaternion_x_0=function(){return(Wy=b._emscripten_bind_btQuaternion_x_0=b.asm.Bw).apply(null,arguments)},Xy=b._emscripten_bind_btQuaternion_y_0=function(){return(Xy=b._emscripten_bind_btQuaternion_y_0=b.asm.Cw).apply(null,arguments)},Yy=b._emscripten_bind_btQuaternion_z_0=function(){return(Yy=b._emscripten_bind_btQuaternion_z_0=
-b.asm.Dw).apply(null,arguments)},Zy=b._emscripten_bind_btQuaternion_w_0=function(){return(Zy=b._emscripten_bind_btQuaternion_w_0=b.asm.Ew).apply(null,arguments)},$y=b._emscripten_bind_btQuaternion_setX_1=function(){return($y=b._emscripten_bind_btQuaternion_setX_1=b.asm.Fw).apply(null,arguments)},az=b._emscripten_bind_btQuaternion_setY_1=function(){return(az=b._emscripten_bind_btQuaternion_setY_1=b.asm.Gw).apply(null,arguments)},bz=b._emscripten_bind_btQuaternion_setZ_1=function(){return(bz=b._emscripten_bind_btQuaternion_setZ_1=
-b.asm.Hw).apply(null,arguments)},cz=b._emscripten_bind_btQuaternion_setW_1=function(){return(cz=b._emscripten_bind_btQuaternion_setW_1=b.asm.Iw).apply(null,arguments)},dz=b._emscripten_bind_btQuaternion___destroy___0=function(){return(dz=b._emscripten_bind_btQuaternion___destroy___0=b.asm.Jw).apply(null,arguments)},ez=b._emscripten_bind_btCapsuleShapeZ_btCapsuleShapeZ_2=function(){return(ez=b._emscripten_bind_btCapsuleShapeZ_btCapsuleShapeZ_2=b.asm.Kw).apply(null,arguments)},fz=b._emscripten_bind_btCapsuleShapeZ_setMargin_1=
-function(){return(fz=b._emscripten_bind_btCapsuleShapeZ_setMargin_1=b.asm.Lw).apply(null,arguments)},gz=b._emscripten_bind_btCapsuleShapeZ_getMargin_0=function(){return(gz=b._emscripten_bind_btCapsuleShapeZ_getMargin_0=b.asm.Mw).apply(null,arguments)},hz=b._emscripten_bind_btCapsuleShapeZ_getUpAxis_0=function(){return(hz=b._emscripten_bind_btCapsuleShapeZ_getUpAxis_0=b.asm.Nw).apply(null,arguments)},iz=b._emscripten_bind_btCapsuleShapeZ_getRadius_0=function(){return(iz=b._emscripten_bind_btCapsuleShapeZ_getRadius_0=
-b.asm.Ow).apply(null,arguments)},jz=b._emscripten_bind_btCapsuleShapeZ_getHalfHeight_0=function(){return(jz=b._emscripten_bind_btCapsuleShapeZ_getHalfHeight_0=b.asm.Pw).apply(null,arguments)},kz=b._emscripten_bind_btCapsuleShapeZ_setLocalScaling_1=function(){return(kz=b._emscripten_bind_btCapsuleShapeZ_setLocalScaling_1=b.asm.Qw).apply(null,arguments)},lz=b._emscripten_bind_btCapsuleShapeZ_getLocalScaling_0=function(){return(lz=b._emscripten_bind_btCapsuleShapeZ_getLocalScaling_0=b.asm.Rw).apply(null,
-arguments)},mz=b._emscripten_bind_btCapsuleShapeZ_calculateLocalInertia_2=function(){return(mz=b._emscripten_bind_btCapsuleShapeZ_calculateLocalInertia_2=b.asm.Sw).apply(null,arguments)},nz=b._emscripten_bind_btCapsuleShapeZ___destroy___0=function(){return(nz=b._emscripten_bind_btCapsuleShapeZ___destroy___0=b.asm.Tw).apply(null,arguments)},oz=b._emscripten_bind_btContactSolverInfo_get_m_splitImpulse_0=function(){return(oz=b._emscripten_bind_btContactSolverInfo_get_m_splitImpulse_0=b.asm.Uw).apply(null,
-arguments)},pz=b._emscripten_bind_btContactSolverInfo_set_m_splitImpulse_1=function(){return(pz=b._emscripten_bind_btContactSolverInfo_set_m_splitImpulse_1=b.asm.Vw).apply(null,arguments)},qz=b._emscripten_bind_btContactSolverInfo_get_m_splitImpulsePenetrationThreshold_0=function(){return(qz=b._emscripten_bind_btContactSolverInfo_get_m_splitImpulsePenetrationThreshold_0=b.asm.Ww).apply(null,arguments)},rz=b._emscripten_bind_btContactSolverInfo_set_m_splitImpulsePenetrationThreshold_1=function(){return(rz=
-b._emscripten_bind_btContactSolverInfo_set_m_splitImpulsePenetrationThreshold_1=b.asm.Xw).apply(null,arguments)},sz=b._emscripten_bind_btContactSolverInfo_get_m_numIterations_0=function(){return(sz=b._emscripten_bind_btContactSolverInfo_get_m_numIterations_0=b.asm.Yw).apply(null,arguments)},tz=b._emscripten_bind_btContactSolverInfo_set_m_numIterations_1=function(){return(tz=b._emscripten_bind_btContactSolverInfo_set_m_numIterations_1=b.asm.Zw).apply(null,arguments)},uz=b._emscripten_bind_btContactSolverInfo___destroy___0=
-function(){return(uz=b._emscripten_bind_btContactSolverInfo___destroy___0=b.asm._w).apply(null,arguments)},vz=b._emscripten_bind_btGeneric6DofSpringConstraint_btGeneric6DofSpringConstraint_3=function(){return(vz=b._emscripten_bind_btGeneric6DofSpringConstraint_btGeneric6DofSpringConstraint_3=b.asm.$w).apply(null,arguments)},wz=b._emscripten_bind_btGeneric6DofSpringConstraint_btGeneric6DofSpringConstraint_5=function(){return(wz=b._emscripten_bind_btGeneric6DofSpringConstraint_btGeneric6DofSpringConstraint_5=
-b.asm.ax).apply(null,arguments)},xz=b._emscripten_bind_btGeneric6DofSpringConstraint_enableSpring_2=function(){return(xz=b._emscripten_bind_btGeneric6DofSpringConstraint_enableSpring_2=b.asm.bx).apply(null,arguments)},yz=b._emscripten_bind_btGeneric6DofSpringConstraint_setStiffness_2=function(){return(yz=b._emscripten_bind_btGeneric6DofSpringConstraint_setStiffness_2=b.asm.cx).apply(null,arguments)},zz=b._emscripten_bind_btGeneric6DofSpringConstraint_setDamping_2=function(){return(zz=b._emscripten_bind_btGeneric6DofSpringConstraint_setDamping_2=
-b.asm.dx).apply(null,arguments)},Az=b._emscripten_bind_btGeneric6DofSpringConstraint_setEquilibriumPoint_0=function(){return(Az=b._emscripten_bind_btGeneric6DofSpringConstraint_setEquilibriumPoint_0=b.asm.ex).apply(null,arguments)},Bz=b._emscripten_bind_btGeneric6DofSpringConstraint_setEquilibriumPoint_1=function(){return(Bz=b._emscripten_bind_btGeneric6DofSpringConstraint_setEquilibriumPoint_1=b.asm.fx).apply(null,arguments)},Cz=b._emscripten_bind_btGeneric6DofSpringConstraint_setEquilibriumPoint_2=
-function(){return(Cz=b._emscripten_bind_btGeneric6DofSpringConstraint_setEquilibriumPoint_2=b.asm.gx).apply(null,arguments)},Dz=b._emscripten_bind_btGeneric6DofSpringConstraint_setLinearLowerLimit_1=function(){return(Dz=b._emscripten_bind_btGeneric6DofSpringConstraint_setLinearLowerLimit_1=b.asm.hx).apply(null,arguments)},Ez=b._emscripten_bind_btGeneric6DofSpringConstraint_setLinearUpperLimit_1=function(){return(Ez=b._emscripten_bind_btGeneric6DofSpringConstraint_setLinearUpperLimit_1=b.asm.ix).apply(null,
-arguments)},Fz=b._emscripten_bind_btGeneric6DofSpringConstraint_setAngularLowerLimit_1=function(){return(Fz=b._emscripten_bind_btGeneric6DofSpringConstraint_setAngularLowerLimit_1=b.asm.jx).apply(null,arguments)},Gz=b._emscripten_bind_btGeneric6DofSpringConstraint_setAngularUpperLimit_1=function(){return(Gz=b._emscripten_bind_btGeneric6DofSpringConstraint_setAngularUpperLimit_1=b.asm.kx).apply(null,arguments)},Hz=b._emscripten_bind_btGeneric6DofSpringConstraint_getFrameOffsetA_0=function(){return(Hz=
-b._emscripten_bind_btGeneric6DofSpringConstraint_getFrameOffsetA_0=b.asm.lx).apply(null,arguments)},Iz=b._emscripten_bind_btGeneric6DofSpringConstraint_enableFeedback_1=function(){return(Iz=b._emscripten_bind_btGeneric6DofSpringConstraint_enableFeedback_1=b.asm.mx).apply(null,arguments)},Jz=b._emscripten_bind_btGeneric6DofSpringConstraint_getBreakingImpulseThreshold_0=function(){return(Jz=b._emscripten_bind_btGeneric6DofSpringConstraint_getBreakingImpulseThreshold_0=b.asm.nx).apply(null,arguments)},
-Kz=b._emscripten_bind_btGeneric6DofSpringConstraint_setBreakingImpulseThreshold_1=function(){return(Kz=b._emscripten_bind_btGeneric6DofSpringConstraint_setBreakingImpulseThreshold_1=b.asm.ox).apply(null,arguments)},Lz=b._emscripten_bind_btGeneric6DofSpringConstraint_getParam_2=function(){return(Lz=b._emscripten_bind_btGeneric6DofSpringConstraint_getParam_2=b.asm.px).apply(null,arguments)},Mz=b._emscripten_bind_btGeneric6DofSpringConstraint_setParam_3=function(){return(Mz=b._emscripten_bind_btGeneric6DofSpringConstraint_setParam_3=
-b.asm.qx).apply(null,arguments)},Nz=b._emscripten_bind_btGeneric6DofSpringConstraint___destroy___0=function(){return(Nz=b._emscripten_bind_btGeneric6DofSpringConstraint___destroy___0=b.asm.rx).apply(null,arguments)},Oz=b._emscripten_bind_btSphereShape_btSphereShape_1=function(){return(Oz=b._emscripten_bind_btSphereShape_btSphereShape_1=b.asm.sx).apply(null,arguments)},Pz=b._emscripten_bind_btSphereShape_setMargin_1=function(){return(Pz=b._emscripten_bind_btSphereShape_setMargin_1=b.asm.tx).apply(null,
-arguments)},Qz=b._emscripten_bind_btSphereShape_getMargin_0=function(){return(Qz=b._emscripten_bind_btSphereShape_getMargin_0=b.asm.ux).apply(null,arguments)},Rz=b._emscripten_bind_btSphereShape_setLocalScaling_1=function(){return(Rz=b._emscripten_bind_btSphereShape_setLocalScaling_1=b.asm.vx).apply(null,arguments)},Sz=b._emscripten_bind_btSphereShape_getLocalScaling_0=function(){return(Sz=b._emscripten_bind_btSphereShape_getLocalScaling_0=b.asm.wx).apply(null,arguments)},Tz=b._emscripten_bind_btSphereShape_calculateLocalInertia_2=
-function(){return(Tz=b._emscripten_bind_btSphereShape_calculateLocalInertia_2=b.asm.xx).apply(null,arguments)},Uz=b._emscripten_bind_btSphereShape___destroy___0=function(){return(Uz=b._emscripten_bind_btSphereShape___destroy___0=b.asm.yx).apply(null,arguments)},Vz=b._emscripten_bind_Face_get_m_n_1=function(){return(Vz=b._emscripten_bind_Face_get_m_n_1=b.asm.zx).apply(null,arguments)},Wz=b._emscripten_bind_Face_set_m_n_2=function(){return(Wz=b._emscripten_bind_Face_set_m_n_2=b.asm.Ax).apply(null,arguments)},
-Xz=b._emscripten_bind_Face_get_m_normal_0=function(){return(Xz=b._emscripten_bind_Face_get_m_normal_0=b.asm.Bx).apply(null,arguments)},Yz=b._emscripten_bind_Face_set_m_normal_1=function(){return(Yz=b._emscripten_bind_Face_set_m_normal_1=b.asm.Cx).apply(null,arguments)},Zz=b._emscripten_bind_Face_get_m_ra_0=function(){return(Zz=b._emscripten_bind_Face_get_m_ra_0=b.asm.Dx).apply(null,arguments)},$z=b._emscripten_bind_Face_set_m_ra_1=function(){return($z=b._emscripten_bind_Face_set_m_ra_1=b.asm.Ex).apply(null,
-arguments)},aA=b._emscripten_bind_Face___destroy___0=function(){return(aA=b._emscripten_bind_Face___destroy___0=b.asm.Fx).apply(null,arguments)},bA=b._emscripten_bind_tFaceArray_size_0=function(){return(bA=b._emscripten_bind_tFaceArray_size_0=b.asm.Gx).apply(null,arguments)},cA=b._emscripten_bind_tFaceArray_at_1=function(){return(cA=b._emscripten_bind_tFaceArray_at_1=b.asm.Hx).apply(null,arguments)},dA=b._emscripten_bind_tFaceArray___destroy___0=function(){return(dA=b._emscripten_bind_tFaceArray___destroy___0=
-b.asm.Ix).apply(null,arguments)},eA=b._emscripten_bind_LocalConvexResult_LocalConvexResult_5=function(){return(eA=b._emscripten_bind_LocalConvexResult_LocalConvexResult_5=b.asm.Jx).apply(null,arguments)},fA=b._emscripten_bind_LocalConvexResult_get_m_hitCollisionObject_0=function(){return(fA=b._emscripten_bind_LocalConvexResult_get_m_hitCollisionObject_0=b.asm.Kx).apply(null,arguments)},gA=b._emscripten_bind_LocalConvexResult_set_m_hitCollisionObject_1=function(){return(gA=b._emscripten_bind_LocalConvexResult_set_m_hitCollisionObject_1=
-b.asm.Lx).apply(null,arguments)},hA=b._emscripten_bind_LocalConvexResult_get_m_localShapeInfo_0=function(){return(hA=b._emscripten_bind_LocalConvexResult_get_m_localShapeInfo_0=b.asm.Mx).apply(null,arguments)},iA=b._emscripten_bind_LocalConvexResult_set_m_localShapeInfo_1=function(){return(iA=b._emscripten_bind_LocalConvexResult_set_m_localShapeInfo_1=b.asm.Nx).apply(null,arguments)},jA=b._emscripten_bind_LocalConvexResult_get_m_hitNormalLocal_0=function(){return(jA=b._emscripten_bind_LocalConvexResult_get_m_hitNormalLocal_0=
-b.asm.Ox).apply(null,arguments)},kA=b._emscripten_bind_LocalConvexResult_set_m_hitNormalLocal_1=function(){return(kA=b._emscripten_bind_LocalConvexResult_set_m_hitNormalLocal_1=b.asm.Px).apply(null,arguments)},lA=b._emscripten_bind_LocalConvexResult_get_m_hitPointLocal_0=function(){return(lA=b._emscripten_bind_LocalConvexResult_get_m_hitPointLocal_0=b.asm.Qx).apply(null,arguments)},mA=b._emscripten_bind_LocalConvexResult_set_m_hitPointLocal_1=function(){return(mA=b._emscripten_bind_LocalConvexResult_set_m_hitPointLocal_1=
-b.asm.Rx).apply(null,arguments)},nA=b._emscripten_bind_LocalConvexResult_get_m_hitFraction_0=function(){return(nA=b._emscripten_bind_LocalConvexResult_get_m_hitFraction_0=b.asm.Sx).apply(null,arguments)},oA=b._emscripten_bind_LocalConvexResult_set_m_hitFraction_1=function(){return(oA=b._emscripten_bind_LocalConvexResult_set_m_hitFraction_1=b.asm.Tx).apply(null,arguments)},pA=b._emscripten_bind_LocalConvexResult___destroy___0=function(){return(pA=b._emscripten_bind_LocalConvexResult___destroy___0=
-b.asm.Ux).apply(null,arguments)},qA=b._emscripten_enum_btConstraintParams_BT_CONSTRAINT_ERP=function(){return(qA=b._emscripten_enum_btConstraintParams_BT_CONSTRAINT_ERP=b.asm.Vx).apply(null,arguments)},rA=b._emscripten_enum_btConstraintParams_BT_CONSTRAINT_STOP_ERP=function(){return(rA=b._emscripten_enum_btConstraintParams_BT_CONSTRAINT_STOP_ERP=b.asm.Wx).apply(null,arguments)},sA=b._emscripten_enum_btConstraintParams_BT_CONSTRAINT_CFM=function(){return(sA=b._emscripten_enum_btConstraintParams_BT_CONSTRAINT_CFM=
-b.asm.Xx).apply(null,arguments)},tA=b._emscripten_enum_btConstraintParams_BT_CONSTRAINT_STOP_CFM=function(){return(tA=b._emscripten_enum_btConstraintParams_BT_CONSTRAINT_STOP_CFM=b.asm.Yx).apply(null,arguments)},uA=b._emscripten_enum_PHY_ScalarType_PHY_FLOAT=function(){return(uA=b._emscripten_enum_PHY_ScalarType_PHY_FLOAT=b.asm.Zx).apply(null,arguments)},vA=b._emscripten_enum_PHY_ScalarType_PHY_DOUBLE=function(){return(vA=b._emscripten_enum_PHY_ScalarType_PHY_DOUBLE=b.asm._x).apply(null,arguments)},
-wA=b._emscripten_enum_PHY_ScalarType_PHY_INTEGER=function(){return(wA=b._emscripten_enum_PHY_ScalarType_PHY_INTEGER=b.asm.$x).apply(null,arguments)},xA=b._emscripten_enum_PHY_ScalarType_PHY_SHORT=function(){return(xA=b._emscripten_enum_PHY_ScalarType_PHY_SHORT=b.asm.ay).apply(null,arguments)},yA=b._emscripten_enum_PHY_ScalarType_PHY_FIXEDPOINT88=function(){return(yA=b._emscripten_enum_PHY_ScalarType_PHY_FIXEDPOINT88=b.asm.by).apply(null,arguments)},zA=b._emscripten_enum_PHY_ScalarType_PHY_UCHAR=function(){return(zA=
-b._emscripten_enum_PHY_ScalarType_PHY_UCHAR=b.asm.cy).apply(null,arguments)};b._malloc=function(){return(b._malloc=b.asm.dy).apply(null,arguments)};b._free=function(){return(b._free=b.asm.ey).apply(null,arguments)};b.dynCall_vi=function(){return(b.dynCall_vi=b.asm.fy).apply(null,arguments)};b.dynCall_v=function(){return(b.dynCall_v=b.asm.gy).apply(null,arguments)};
-b.UTF8ToString=function(a,c){if(a){var d=a+c;for(c=a;za[c]&&!(c>=d);)++c;if(16<c-a&&za.subarray&&wa)a=wa.decode(za.subarray(a,c));else{for(d="";a<c;){var e=za[a++];if(e&128){var g=za[a++]&63;if(192==(e&224))d+=String.fromCharCode((e&31)<<6|g);else{var n=za[a++]&63;e=224==(e&240)?(e&15)<<12|g<<6|n:(e&7)<<18|g<<12|n<<6|za[a++]&63;65536>e?d+=String.fromCharCode(e):(e-=65536,d+=String.fromCharCode(55296|e>>10,56320|e&1023))}}else d+=String.fromCharCode(e)}a=d}}else a="";return a};var AA;
-Oa=function BA(){AA||CA();AA||(Oa=BA)};
-function CA(){function a(){if(!AA&&(AA=!0,b.calledRun=!0,!va)){Ka=!0;Fa(Ha);Fa(Ia);ba(b);if(b.onRuntimeInitialized)b.onRuntimeInitialized();if(b.postRun)for("function"==typeof b.postRun&&(b.postRun=[b.postRun]);b.postRun.length;){var c=b.postRun.shift();Ja.unshift(c)}Fa(Ja)}}if(!(0<Ma)){if(b.preRun)for("function"==typeof b.preRun&&(b.preRun=[b.preRun]);b.preRun.length;)La();Fa(Ga);0<Ma||(b.setStatus?(b.setStatus("Running..."),setTimeout(function(){setTimeout(function(){b.setStatus("")},1);a()},1)):
-a())}}b.run=CA;if(b.preInit)for("function"==typeof b.preInit&&(b.preInit=[b.preInit]);0<b.preInit.length;)b.preInit.pop()();noExitRuntime=!0;CA();function f(){}f.prototype=Object.create(f.prototype);f.prototype.constructor=f;f.prototype.iy=f;f.jy={};b.WrapperObject=f;function h(a){return(a||f).jy}b.getCache=h;function k(a,c){var d=h(c),e=d[a];if(e)return e;e=Object.create((c||f).prototype);e.hy=a;return d[a]=e}b.wrapPointer=k;b.castObject=function(a,c){return k(a.hy,c)};b.NULL=k(0);
-b.destroy=function(a){if(!a.__destroy__)throw"Error: Cannot destroy object. (Did you create it yourself?)";a.__destroy__();delete h(a.iy)[a.hy]};b.compare=function(a,c){return a.hy===c.hy};b.getPointer=function(a){return a.hy};b.getClass=function(a){return a.iy};var DA=0,EA=0,FA=0,GA=[],HA=0;function IA(){if(HA){for(var a=0;a<GA.length;a++)b._free(GA[a]);GA.length=0;b._free(DA);DA=0;EA+=HA;HA=0}DA||(EA+=128,DA=b._malloc(EA),assert(DA));FA=0}
-function JA(a,c){assert(DA);a=a.length*c.BYTES_PER_ELEMENT;a=a+7&-8;FA+a>=EA?(assert(0<a),HA+=a,c=b._malloc(a),GA.push(c)):(c=DA+FA,FA+=a);return c}function KA(a,c,d){d>>>=0;switch(c.BYTES_PER_ELEMENT){case 2:d>>>=1;break;case 4:d>>>=2;break;case 8:d>>>=3}for(var e=0;e<a.length;e++)c[d+e]=a[e]}
-function LA(a){if("string"===typeof a){for(var c=0,d=0;d<a.length;++d){var e=a.charCodeAt(d);55296<=e&&57343>=e&&(e=65536+((e&1023)<<10)|a.charCodeAt(++d)&1023);127>=e?++c:c=2047>=e?c+2:65535>=e?c+3:c+4}c=Array(c+1);e=c.length;d=0;if(0<e){e=d+e-1;for(var g=0;g<a.length;++g){var n=a.charCodeAt(g);if(55296<=n&&57343>=n){var F=a.charCodeAt(++g);n=65536+((n&1023)<<10)|F&1023}if(127>=n){if(d>=e)break;c[d++]=n}else{if(2047>=n){if(d+1>=e)break;c[d++]=192|n>>6}else{if(65535>=n){if(d+2>=e)break;c[d++]=224|
-n>>12}else{if(d+3>=e)break;c[d++]=240|n>>18;c[d++]=128|n>>12&63}c[d++]=128|n>>6&63}c[d++]=128|n&63}}c[d]=0}a=JA(c,ya);KA(c,ya,a)}return a}function MA(a){if("object"===typeof a){var c=JA(a,Ba);KA(a,Ba,c);return c}return a}function NA(){throw"cannot construct a btCollisionWorld, no constructor in IDL";}NA.prototype=Object.create(f.prototype);NA.prototype.constructor=NA;NA.prototype.iy=NA;NA.jy={};b.btCollisionWorld=NA;NA.prototype.getDispatcher=function(){return k($a(this.hy),OA)};
-NA.prototype.rayTest=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);ab(e,a,c,d)};NA.prototype.getPairCache=function(){return k(bb(this.hy),PA)};NA.prototype.getDispatchInfo=function(){return k(cb(this.hy),l)};
-NA.prototype.addCollisionObject=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);void 0===c?db(e,a):void 0===d?eb(e,a,c):fb(e,a,c,d)};NA.prototype.removeCollisionObject=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);gb(c,a)};NA.prototype.getBroadphase=function(){return k(hb(this.hy),QA)};
-NA.prototype.convexSweepTest=function(a,c,d,e,g){var n=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);ib(n,a,c,d,e,g)};NA.prototype.contactPairTest=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);jb(e,a,c,d)};
-NA.prototype.contactTest=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);kb(d,a,c)};NA.prototype.updateSingleAabb=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);lb(c,a)};NA.prototype.setDebugDrawer=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);mb(c,a)};NA.prototype.getDebugDrawer=function(){return k(nb(this.hy),RA)};NA.prototype.debugDrawWorld=function(){ob(this.hy)};
-NA.prototype.debugDrawObject=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);pb(e,a,c,d)};NA.prototype.__destroy__=function(){qb(this.hy)};function m(){throw"cannot construct a btCollisionShape, no constructor in IDL";}m.prototype=Object.create(f.prototype);m.prototype.constructor=m;m.prototype.iy=m;m.jy={};b.btCollisionShape=m;
-m.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);rb(c,a)};m.prototype.getLocalScaling=function(){return k(sb(this.hy),p)};m.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);tb(d,a,c)};m.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ub(c,a)};m.prototype.getMargin=function(){return vb(this.hy)};m.prototype.__destroy__=function(){wb(this.hy)};
-function q(){throw"cannot construct a btCollisionObject, no constructor in IDL";}q.prototype=Object.create(f.prototype);q.prototype.constructor=q;q.prototype.iy=q;q.jy={};b.btCollisionObject=q;q.prototype.setAnisotropicFriction=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);xb(d,a,c)};q.prototype.getCollisionShape=function(){return k(yb(this.hy),m)};
-q.prototype.setContactProcessingThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);zb(c,a)};q.prototype.setActivationState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ab(c,a)};q.prototype.forceActivationState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Bb(c,a)};q.prototype.activate=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);void 0===a?Cb(c):Db(c,a)};q.prototype.isActive=function(){return!!Eb(this.hy)};q.prototype.isKinematicObject=function(){return!!Fb(this.hy)};
-q.prototype.isStaticObject=function(){return!!Gb(this.hy)};q.prototype.isStaticOrKinematicObject=function(){return!!Hb(this.hy)};q.prototype.getRestitution=function(){return Ib(this.hy)};q.prototype.getFriction=function(){return Jb(this.hy)};q.prototype.getRollingFriction=function(){return Kb(this.hy)};q.prototype.setRestitution=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Lb(c,a)};q.prototype.setFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Mb(c,a)};
-q.prototype.setRollingFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Nb(c,a)};q.prototype.getWorldTransform=function(){return k(Ob(this.hy),r)};q.prototype.getCollisionFlags=function(){return Pb(this.hy)};q.prototype.setCollisionFlags=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Qb(c,a)};q.prototype.setWorldTransform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Sb(c,a)};
-q.prototype.setCollisionShape=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Tb(c,a)};q.prototype.setCcdMotionThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ub(c,a)};q.prototype.setCcdSweptSphereRadius=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Vb(c,a)};q.prototype.getUserIndex=function(){return Wb(this.hy)};q.prototype.setUserIndex=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Xb(c,a)};
-q.prototype.getUserPointer=function(){return k(Yb(this.hy),SA)};q.prototype.setUserPointer=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Zb(c,a)};q.prototype.getBroadphaseHandle=function(){return k($b(this.hy),t)};q.prototype.__destroy__=function(){ac(this.hy)};function u(){throw"cannot construct a btDynamicsWorld, no constructor in IDL";}u.prototype=Object.create(NA.prototype);u.prototype.constructor=u;u.prototype.iy=u;u.jy={};b.btDynamicsWorld=u;
-u.prototype.addAction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);bc(c,a)};u.prototype.removeAction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);cc(c,a)};u.prototype.getSolverInfo=function(){return k(dc(this.hy),v)};u.prototype.setInternalTickCallback=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);void 0===c?ec(e,a):void 0===d?fc(e,a,c):hc(e,a,c,d)};
-u.prototype.getDispatcher=function(){return k(ic(this.hy),OA)};u.prototype.rayTest=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);jc(e,a,c,d)};u.prototype.getPairCache=function(){return k(kc(this.hy),PA)};u.prototype.getDispatchInfo=function(){return k(lc(this.hy),l)};
-u.prototype.addCollisionObject=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);void 0===c?mc(e,a):void 0===d?nc(e,a,c):oc(e,a,c,d)};u.prototype.removeCollisionObject=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);pc(c,a)};u.prototype.getBroadphase=function(){return k(qc(this.hy),QA)};
-u.prototype.convexSweepTest=function(a,c,d,e,g){var n=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);rc(n,a,c,d,e,g)};u.prototype.contactPairTest=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);sc(e,a,c,d)};
-u.prototype.contactTest=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);tc(d,a,c)};u.prototype.updateSingleAabb=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);uc(c,a)};u.prototype.setDebugDrawer=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);vc(c,a)};u.prototype.getDebugDrawer=function(){return k(wc(this.hy),RA)};u.prototype.debugDrawWorld=function(){xc(this.hy)};
-u.prototype.debugDrawObject=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);yc(e,a,c,d)};u.prototype.__destroy__=function(){zc(this.hy)};function TA(){throw"cannot construct a btTypedConstraint, no constructor in IDL";}TA.prototype=Object.create(f.prototype);TA.prototype.constructor=TA;TA.prototype.iy=TA;TA.jy={};b.btTypedConstraint=TA;
-TA.prototype.enableFeedback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ac(c,a)};TA.prototype.getBreakingImpulseThreshold=function(){return Bc(this.hy)};TA.prototype.setBreakingImpulseThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Cc(c,a)};TA.prototype.getParam=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return Dc(d,a,c)};
-TA.prototype.setParam=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Ec(e,a,c,d)};TA.prototype.__destroy__=function(){Fc(this.hy)};function UA(){throw"cannot construct a btConcaveShape, no constructor in IDL";}UA.prototype=Object.create(m.prototype);UA.prototype.constructor=UA;UA.prototype.iy=UA;UA.jy={};b.btConcaveShape=UA;
-UA.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Gc(c,a)};UA.prototype.getLocalScaling=function(){return k(Hc(this.hy),p)};UA.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Ic(d,a,c)};UA.prototype.__destroy__=function(){Jc(this.hy)};function VA(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=Kc(a,c);h(VA)[this.hy]=this}VA.prototype=Object.create(m.prototype);
-VA.prototype.constructor=VA;VA.prototype.iy=VA;VA.jy={};b.btCapsuleShape=VA;VA.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Lc(c,a)};VA.prototype.getMargin=function(){return Mc(this.hy)};VA.prototype.getUpAxis=function(){return Nc(this.hy)};VA.prototype.getRadius=function(){return Oc(this.hy)};VA.prototype.getHalfHeight=function(){return Pc(this.hy)};VA.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Qc(c,a)};
-VA.prototype.getLocalScaling=function(){return k(Rc(this.hy),p)};VA.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Sc(d,a,c)};VA.prototype.__destroy__=function(){Tc(this.hy)};function RA(){throw"cannot construct a btIDebugDraw, no constructor in IDL";}RA.prototype=Object.create(f.prototype);RA.prototype.constructor=RA;RA.prototype.iy=RA;RA.jy={};b.btIDebugDraw=RA;
-RA.prototype.drawLine=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Uc(e,a,c,d)};RA.prototype.drawContactPoint=function(a,c,d,e,g){var n=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);Vc(n,a,c,d,e,g)};
-RA.prototype.reportErrorWarning=function(a){var c=this.hy;IA();a=a&&"object"===typeof a?a.hy:LA(a);Wc(c,a)};RA.prototype.draw3dText=function(a,c){var d=this.hy;IA();a&&"object"===typeof a&&(a=a.hy);c=c&&"object"===typeof c?c.hy:LA(c);Xc(d,a,c)};RA.prototype.setDebugMode=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Yc(c,a)};RA.prototype.getDebugMode=function(){return Zc(this.hy)};RA.prototype.__destroy__=function(){$c(this.hy)};
-function WA(a){a&&"object"===typeof a&&(a=a.hy);this.hy=void 0===a?ad():bd(a);h(WA)[this.hy]=this}WA.prototype=Object.create(f.prototype);WA.prototype.constructor=WA;WA.prototype.iy=WA;WA.jy={};b.btDefaultCollisionConfiguration=WA;WA.prototype.__destroy__=function(){cd(this.hy)};function XA(){throw"cannot construct a btTriangleMeshShape, no constructor in IDL";}XA.prototype=Object.create(UA.prototype);XA.prototype.constructor=XA;XA.prototype.iy=XA;XA.jy={};b.btTriangleMeshShape=XA;
-XA.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);dd(c,a)};XA.prototype.getLocalScaling=function(){return k(ed(this.hy),p)};XA.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);fd(d,a,c)};XA.prototype.__destroy__=function(){gd(this.hy)};function w(){this.hy=hd();h(w)[this.hy]=this}w.prototype=Object.create(q.prototype);w.prototype.constructor=w;w.prototype.iy=w;w.jy={};
-b.btGhostObject=w;w.prototype.getNumOverlappingObjects=function(){return id(this.hy)};w.prototype.getOverlappingObject=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(jd(c,a),q)};w.prototype.setAnisotropicFriction=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);kd(d,a,c)};w.prototype.getCollisionShape=function(){return k(ld(this.hy),m)};
-w.prototype.setContactProcessingThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);md(c,a)};w.prototype.setActivationState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);nd(c,a)};w.prototype.forceActivationState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);od(c,a)};w.prototype.activate=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);void 0===a?pd(c):qd(c,a)};w.prototype.isActive=function(){return!!rd(this.hy)};w.prototype.isKinematicObject=function(){return!!sd(this.hy)};
-w.prototype.isStaticObject=function(){return!!td(this.hy)};w.prototype.isStaticOrKinematicObject=function(){return!!ud(this.hy)};w.prototype.getRestitution=function(){return vd(this.hy)};w.prototype.getFriction=function(){return wd(this.hy)};w.prototype.getRollingFriction=function(){return xd(this.hy)};w.prototype.setRestitution=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);yd(c,a)};w.prototype.setFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);zd(c,a)};
-w.prototype.setRollingFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ad(c,a)};w.prototype.getWorldTransform=function(){return k(Bd(this.hy),r)};w.prototype.getCollisionFlags=function(){return Cd(this.hy)};w.prototype.setCollisionFlags=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Dd(c,a)};w.prototype.setWorldTransform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ed(c,a)};
-w.prototype.setCollisionShape=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Fd(c,a)};w.prototype.setCcdMotionThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Gd(c,a)};w.prototype.setCcdSweptSphereRadius=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Hd(c,a)};w.prototype.getUserIndex=function(){return Id(this.hy)};w.prototype.setUserIndex=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Jd(c,a)};
-w.prototype.getUserPointer=function(){return k(Kd(this.hy),SA)};w.prototype.setUserPointer=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ld(c,a)};w.prototype.getBroadphaseHandle=function(){return k(Md(this.hy),t)};w.prototype.__destroy__=function(){Nd(this.hy)};function YA(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=Od(a,c);h(YA)[this.hy]=this}YA.prototype=Object.create(m.prototype);YA.prototype.constructor=YA;YA.prototype.iy=YA;YA.jy={};
-b.btConeShape=YA;YA.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pd(c,a)};YA.prototype.getLocalScaling=function(){return k(Qd(this.hy),p)};YA.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Rd(d,a,c)};YA.prototype.__destroy__=function(){Sd(this.hy)};function ZA(){throw"cannot construct a btActionInterface, no constructor in IDL";}ZA.prototype=Object.create(f.prototype);
-ZA.prototype.constructor=ZA;ZA.prototype.iy=ZA;ZA.jy={};b.btActionInterface=ZA;ZA.prototype.updateAction=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Td(d,a,c)};ZA.prototype.__destroy__=function(){Ud(this.hy)};
-function p(a,c,d){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);this.hy=void 0===a?Vd():void 0===c?_emscripten_bind_btVector3_btVector3_1(a):void 0===d?_emscripten_bind_btVector3_btVector3_2(a,c):Wd(a,c,d);h(p)[this.hy]=this}p.prototype=Object.create(f.prototype);p.prototype.constructor=p;p.prototype.iy=p;p.jy={};b.btVector3=p;p.prototype.length=p.prototype.length=function(){return Xd(this.hy)};p.prototype.x=p.prototype.x=function(){return Yd(this.hy)};
-p.prototype.y=p.prototype.y=function(){return Zd(this.hy)};p.prototype.z=p.prototype.z=function(){return $d(this.hy)};p.prototype.setX=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ae(c,a)};p.prototype.setY=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);be(c,a)};p.prototype.setZ=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ce(c,a)};
-p.prototype.setValue=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);de(e,a,c,d)};p.prototype.normalize=p.prototype.normalize=function(){ee(this.hy)};p.prototype.rotate=p.prototype.rotate=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return k(fe(d,a,c),p)};p.prototype.dot=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return ge(c,a)};
-p.prototype.op_mul=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(he(c,a),p)};p.prototype.op_add=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(ie(c,a),p)};p.prototype.op_sub=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(je(c,a),p)};p.prototype.__destroy__=function(){ke(this.hy)};function $A(){throw"cannot construct a btVehicleRaycaster, no constructor in IDL";}$A.prototype=Object.create(f.prototype);$A.prototype.constructor=$A;
-$A.prototype.iy=$A;$A.jy={};b.btVehicleRaycaster=$A;$A.prototype.castRay=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);le(e,a,c,d)};$A.prototype.__destroy__=function(){me(this.hy)};function aB(){throw"cannot construct a btQuadWord, no constructor in IDL";}aB.prototype=Object.create(f.prototype);aB.prototype.constructor=aB;aB.prototype.iy=aB;aB.jy={};b.btQuadWord=aB;aB.prototype.x=aB.prototype.x=function(){return ne(this.hy)};
-aB.prototype.y=aB.prototype.y=function(){return oe(this.hy)};aB.prototype.z=aB.prototype.z=function(){return pe(this.hy)};aB.prototype.w=function(){return qe(this.hy)};aB.prototype.setX=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);re(c,a)};aB.prototype.setY=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);se(c,a)};aB.prototype.setZ=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);te(c,a)};
-aB.prototype.setW=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ue(c,a)};aB.prototype.__destroy__=function(){ve(this.hy)};function bB(a){a&&"object"===typeof a&&(a=a.hy);this.hy=we(a);h(bB)[this.hy]=this}bB.prototype=Object.create(m.prototype);bB.prototype.constructor=bB;bB.prototype.iy=bB;bB.jy={};b.btCylinderShape=bB;bB.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);xe(c,a)};bB.prototype.getMargin=function(){return ye(this.hy)};
-bB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ze(c,a)};bB.prototype.getLocalScaling=function(){return k(Ae(this.hy),p)};bB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Be(d,a,c)};bB.prototype.__destroy__=function(){Ce(this.hy)};
-function x(a,c,d,e){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);this.hy=De(a,c,d,e);h(x)[this.hy]=this}x.prototype=Object.create(u.prototype);x.prototype.constructor=x;x.prototype.iy=x;x.jy={};b.btDiscreteDynamicsWorld=x;x.prototype.setGravity=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ee(c,a)};x.prototype.getGravity=function(){return k(Fe(this.hy),p)};
-x.prototype.addRigidBody=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);void 0===c?Ge(e,a):void 0===d?_emscripten_bind_btDiscreteDynamicsWorld_addRigidBody_2(e,a,c):He(e,a,c,d)};x.prototype.removeRigidBody=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ie(c,a)};
-x.prototype.addConstraint=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);void 0===c?Je(d,a):Ke(d,a,c)};x.prototype.removeConstraint=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Le(c,a)};x.prototype.stepSimulation=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);return void 0===c?Me(e,a):void 0===d?Ne(e,a,c):Oe(e,a,c,d)};
-x.prototype.setContactAddedCallback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pe(c,a)};x.prototype.setContactProcessedCallback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Qe(c,a)};x.prototype.setContactDestroyedCallback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Re(c,a)};x.prototype.getDispatcher=function(){return k(Se(this.hy),OA)};
-x.prototype.rayTest=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Te(e,a,c,d)};x.prototype.getPairCache=function(){return k(Ue(this.hy),PA)};x.prototype.getDispatchInfo=function(){return k(Ve(this.hy),l)};x.prototype.addCollisionObject=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);void 0===c?We(e,a):void 0===d?Xe(e,a,c):Ye(e,a,c,d)};
-x.prototype.removeCollisionObject=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ze(c,a)};x.prototype.getBroadphase=function(){return k($e(this.hy),QA)};x.prototype.convexSweepTest=function(a,c,d,e,g){var n=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);af(n,a,c,d,e,g)};
-x.prototype.contactPairTest=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);bf(e,a,c,d)};x.prototype.contactTest=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);cf(d,a,c)};x.prototype.updateSingleAabb=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);df(c,a)};x.prototype.setDebugDrawer=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ef(c,a)};
-x.prototype.getDebugDrawer=function(){return k(ff(this.hy),RA)};x.prototype.debugDrawWorld=function(){gf(this.hy)};x.prototype.debugDrawObject=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);hf(e,a,c,d)};x.prototype.addAction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);jf(c,a)};x.prototype.removeAction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);kf(c,a)};
-x.prototype.getSolverInfo=function(){return k(lf(this.hy),v)};x.prototype.setInternalTickCallback=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);void 0===c?mf(e,a):void 0===d?nf(e,a,c):of(e,a,c,d)};x.prototype.__destroy__=function(){pf(this.hy)};function cB(){throw"cannot construct a btConvexShape, no constructor in IDL";}cB.prototype=Object.create(m.prototype);cB.prototype.constructor=cB;cB.prototype.iy=cB;cB.jy={};
-b.btConvexShape=cB;cB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);qf(c,a)};cB.prototype.getLocalScaling=function(){return k(rf(this.hy),p)};cB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);sf(d,a,c)};cB.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);tf(c,a)};cB.prototype.getMargin=function(){return uf(this.hy)};cB.prototype.__destroy__=function(){vf(this.hy)};
-function OA(){throw"cannot construct a btDispatcher, no constructor in IDL";}OA.prototype=Object.create(f.prototype);OA.prototype.constructor=OA;OA.prototype.iy=OA;OA.jy={};b.btDispatcher=OA;OA.prototype.getNumManifolds=function(){return wf(this.hy)};OA.prototype.getManifoldByIndexInternal=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(xf(c,a),dB)};OA.prototype.__destroy__=function(){yf(this.hy)};
-function eB(a,c,d,e,g){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);this.hy=void 0===e?zf(a,c,d):void 0===g?_emscripten_bind_btGeneric6DofConstraint_btGeneric6DofConstraint_4(a,c,d,e):Af(a,c,d,e,g);h(eB)[this.hy]=this}eB.prototype=Object.create(TA.prototype);eB.prototype.constructor=eB;eB.prototype.iy=eB;eB.jy={};b.btGeneric6DofConstraint=eB;
-eB.prototype.setLinearLowerLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Bf(c,a)};eB.prototype.setLinearUpperLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Cf(c,a)};eB.prototype.setAngularLowerLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Df(c,a)};eB.prototype.setAngularUpperLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ef(c,a)};eB.prototype.getFrameOffsetA=function(){return k(Ff(this.hy),r)};
-eB.prototype.enableFeedback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Gf(c,a)};eB.prototype.getBreakingImpulseThreshold=function(){return Hf(this.hy)};eB.prototype.setBreakingImpulseThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);If(c,a)};eB.prototype.getParam=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return Jf(d,a,c)};
-eB.prototype.setParam=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Kf(e,a,c,d)};eB.prototype.__destroy__=function(){Lf(this.hy)};function fB(){throw"cannot construct a btStridingMeshInterface, no constructor in IDL";}fB.prototype=Object.create(f.prototype);fB.prototype.constructor=fB;fB.prototype.iy=fB;fB.jy={};b.btStridingMeshInterface=fB;
-fB.prototype.setScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Mf(c,a)};fB.prototype.__destroy__=function(){Nf(this.hy)};function gB(){throw"cannot construct a btMotionState, no constructor in IDL";}gB.prototype=Object.create(f.prototype);gB.prototype.constructor=gB;gB.prototype.iy=gB;gB.jy={};b.btMotionState=gB;gB.prototype.getWorldTransform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Of(c,a)};
-gB.prototype.setWorldTransform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pf(c,a)};gB.prototype.__destroy__=function(){Qf(this.hy)};function y(){throw"cannot construct a ConvexResultCallback, no constructor in IDL";}y.prototype=Object.create(f.prototype);y.prototype.constructor=y;y.prototype.iy=y;y.jy={};b.ConvexResultCallback=y;y.prototype.hasHit=function(){return!!Rf(this.hy)};y.prototype.get_m_collisionFilterGroup=y.prototype.ky=function(){return Sf(this.hy)};
-y.prototype.set_m_collisionFilterGroup=y.prototype.my=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Tf(c,a)};Object.defineProperty(y.prototype,"m_collisionFilterGroup",{get:y.prototype.ky,set:y.prototype.my});y.prototype.get_m_collisionFilterMask=y.prototype.ly=function(){return Uf(this.hy)};y.prototype.set_m_collisionFilterMask=y.prototype.ny=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Vf(c,a)};
-Object.defineProperty(y.prototype,"m_collisionFilterMask",{get:y.prototype.ly,set:y.prototype.ny});y.prototype.get_m_closestHitFraction=y.prototype.oy=function(){return Wf(this.hy)};y.prototype.set_m_closestHitFraction=y.prototype.py=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Xf(c,a)};Object.defineProperty(y.prototype,"m_closestHitFraction",{get:y.prototype.oy,set:y.prototype.py});y.prototype.__destroy__=function(){Yf(this.hy)};
-function hB(){throw"cannot construct a ContactResultCallback, no constructor in IDL";}hB.prototype=Object.create(f.prototype);hB.prototype.constructor=hB;hB.prototype.iy=hB;hB.jy={};b.ContactResultCallback=hB;
-hB.prototype.addSingleResult=function(a,c,d,e,g,n,F){var aa=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);n&&"object"===typeof n&&(n=n.hy);F&&"object"===typeof F&&(F=F.hy);return Zf(aa,a,c,d,e,g,n,F)};hB.prototype.__destroy__=function(){$f(this.hy)};function iB(){throw"cannot construct a btSoftBodySolver, no constructor in IDL";}iB.prototype=Object.create(f.prototype);
-iB.prototype.constructor=iB;iB.prototype.iy=iB;iB.jy={};b.btSoftBodySolver=iB;iB.prototype.__destroy__=function(){ag(this.hy)};function z(){throw"cannot construct a RayResultCallback, no constructor in IDL";}z.prototype=Object.create(f.prototype);z.prototype.constructor=z;z.prototype.iy=z;z.jy={};b.RayResultCallback=z;z.prototype.hasHit=function(){return!!bg(this.hy)};z.prototype.get_m_collisionFilterGroup=z.prototype.ky=function(){return cg(this.hy)};
-z.prototype.set_m_collisionFilterGroup=z.prototype.my=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);dg(c,a)};Object.defineProperty(z.prototype,"m_collisionFilterGroup",{get:z.prototype.ky,set:z.prototype.my});z.prototype.get_m_collisionFilterMask=z.prototype.ly=function(){return eg(this.hy)};z.prototype.set_m_collisionFilterMask=z.prototype.ny=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);fg(c,a)};
-Object.defineProperty(z.prototype,"m_collisionFilterMask",{get:z.prototype.ly,set:z.prototype.ny});z.prototype.get_m_closestHitFraction=z.prototype.oy=function(){return gg(this.hy)};z.prototype.set_m_closestHitFraction=z.prototype.py=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);hg(c,a)};Object.defineProperty(z.prototype,"m_closestHitFraction",{get:z.prototype.oy,set:z.prototype.py});z.prototype.get_m_collisionObject=z.prototype.qy=function(){return k(ig(this.hy),q)};
-z.prototype.set_m_collisionObject=z.prototype.xy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);jg(c,a)};Object.defineProperty(z.prototype,"m_collisionObject",{get:z.prototype.qy,set:z.prototype.xy});z.prototype.__destroy__=function(){kg(this.hy)};function jB(){throw"cannot construct a btMatrix3x3, no constructor in IDL";}jB.prototype=Object.create(f.prototype);jB.prototype.constructor=jB;jB.prototype.iy=jB;jB.jy={};b.btMatrix3x3=jB;
-jB.prototype.setEulerZYX=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);lg(e,a,c,d)};jB.prototype.getRotation=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);mg(c,a)};jB.prototype.getRow=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(ng(c,a),p)};jB.prototype.__destroy__=function(){og(this.hy)};function kB(){throw"cannot construct a btScalarArray, no constructor in IDL";}kB.prototype=Object.create(f.prototype);
-kB.prototype.constructor=kB;kB.prototype.iy=kB;kB.jy={};b.btScalarArray=kB;kB.prototype.size=kB.prototype.size=function(){return pg(this.hy)};kB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return qg(c,a)};kB.prototype.__destroy__=function(){rg(this.hy)};function A(){throw"cannot construct a Material, no constructor in IDL";}A.prototype=Object.create(f.prototype);A.prototype.constructor=A;A.prototype.iy=A;A.jy={};b.Material=A;A.prototype.get_m_kLST=A.prototype.vA=function(){return sg(this.hy)};
-A.prototype.set_m_kLST=A.prototype.bD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);tg(c,a)};Object.defineProperty(A.prototype,"m_kLST",{get:A.prototype.vA,set:A.prototype.bD});A.prototype.get_m_kAST=A.prototype.uA=function(){return ug(this.hy)};A.prototype.set_m_kAST=A.prototype.aD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);vg(c,a)};Object.defineProperty(A.prototype,"m_kAST",{get:A.prototype.uA,set:A.prototype.aD});A.prototype.get_m_kVST=A.prototype.wA=function(){return wg(this.hy)};
-A.prototype.set_m_kVST=A.prototype.cD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);xg(c,a)};Object.defineProperty(A.prototype,"m_kVST",{get:A.prototype.wA,set:A.prototype.cD});A.prototype.get_m_flags=A.prototype.cA=function(){return yg(this.hy)};A.prototype.set_m_flags=A.prototype.JC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);zg(c,a)};Object.defineProperty(A.prototype,"m_flags",{get:A.prototype.cA,set:A.prototype.JC});A.prototype.__destroy__=function(){Ag(this.hy)};
-function l(){throw"cannot construct a btDispatcherInfo, no constructor in IDL";}l.prototype=Object.create(f.prototype);l.prototype.constructor=l;l.prototype.iy=l;l.jy={};b.btDispatcherInfo=l;l.prototype.get_m_timeStep=l.prototype.jB=function(){return Bg(this.hy)};l.prototype.set_m_timeStep=l.prototype.QD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Cg(c,a)};Object.defineProperty(l.prototype,"m_timeStep",{get:l.prototype.jB,set:l.prototype.QD});
-l.prototype.get_m_stepCount=l.prototype.aB=function(){return Dg(this.hy)};l.prototype.set_m_stepCount=l.prototype.HD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Eg(c,a)};Object.defineProperty(l.prototype,"m_stepCount",{get:l.prototype.aB,set:l.prototype.HD});l.prototype.get_m_dispatchFunc=l.prototype.Wz=function(){return Fg(this.hy)};l.prototype.set_m_dispatchFunc=l.prototype.CC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Gg(c,a)};
-Object.defineProperty(l.prototype,"m_dispatchFunc",{get:l.prototype.Wz,set:l.prototype.CC});l.prototype.get_m_timeOfImpact=l.prototype.iB=function(){return Hg(this.hy)};l.prototype.set_m_timeOfImpact=l.prototype.PD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ig(c,a)};Object.defineProperty(l.prototype,"m_timeOfImpact",{get:l.prototype.iB,set:l.prototype.PD});l.prototype.get_m_useContinuous=l.prototype.lB=function(){return!!Jg(this.hy)};
-l.prototype.set_m_useContinuous=l.prototype.SD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Kg(c,a)};Object.defineProperty(l.prototype,"m_useContinuous",{get:l.prototype.lB,set:l.prototype.SD});l.prototype.get_m_enableSatConvex=l.prototype.$z=function(){return!!Lg(this.hy)};l.prototype.set_m_enableSatConvex=l.prototype.GC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Mg(c,a)};Object.defineProperty(l.prototype,"m_enableSatConvex",{get:l.prototype.$z,set:l.prototype.GC});
-l.prototype.get_m_enableSPU=l.prototype.Zz=function(){return!!Ng(this.hy)};l.prototype.set_m_enableSPU=l.prototype.FC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Og(c,a)};Object.defineProperty(l.prototype,"m_enableSPU",{get:l.prototype.Zz,set:l.prototype.FC});l.prototype.get_m_useEpa=l.prototype.nB=function(){return!!Pg(this.hy)};l.prototype.set_m_useEpa=l.prototype.UD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Qg(c,a)};
-Object.defineProperty(l.prototype,"m_useEpa",{get:l.prototype.nB,set:l.prototype.UD});l.prototype.get_m_allowedCcdPenetration=l.prototype.zz=function(){return Rg(this.hy)};l.prototype.set_m_allowedCcdPenetration=l.prototype.fC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Sg(c,a)};Object.defineProperty(l.prototype,"m_allowedCcdPenetration",{get:l.prototype.zz,set:l.prototype.fC});l.prototype.get_m_useConvexConservativeDistanceUtil=l.prototype.mB=function(){return!!Tg(this.hy)};
-l.prototype.set_m_useConvexConservativeDistanceUtil=l.prototype.TD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ug(c,a)};Object.defineProperty(l.prototype,"m_useConvexConservativeDistanceUtil",{get:l.prototype.mB,set:l.prototype.TD});l.prototype.get_m_convexConservativeDistanceThreshold=l.prototype.Rz=function(){return Vg(this.hy)};l.prototype.set_m_convexConservativeDistanceThreshold=l.prototype.xC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wg(c,a)};
-Object.defineProperty(l.prototype,"m_convexConservativeDistanceThreshold",{get:l.prototype.Rz,set:l.prototype.xC});l.prototype.__destroy__=function(){Xg(this.hy)};function B(){throw"cannot construct a btWheelInfoConstructionInfo, no constructor in IDL";}B.prototype=Object.create(f.prototype);B.prototype.constructor=B;B.prototype.iy=B;B.jy={};b.btWheelInfoConstructionInfo=B;B.prototype.get_m_chassisConnectionCS=B.prototype.Lz=function(){return k(Yg(this.hy),p)};
-B.prototype.set_m_chassisConnectionCS=B.prototype.rC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Zg(c,a)};Object.defineProperty(B.prototype,"m_chassisConnectionCS",{get:B.prototype.Lz,set:B.prototype.rC});B.prototype.get_m_wheelDirectionCS=B.prototype.Ly=function(){return k($g(this.hy),p)};B.prototype.set_m_wheelDirectionCS=B.prototype.Uy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ah(c,a)};Object.defineProperty(B.prototype,"m_wheelDirectionCS",{get:B.prototype.Ly,set:B.prototype.Uy});
-B.prototype.get_m_wheelAxleCS=B.prototype.Ky=function(){return k(bh(this.hy),p)};B.prototype.set_m_wheelAxleCS=B.prototype.Ty=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ch(c,a)};Object.defineProperty(B.prototype,"m_wheelAxleCS",{get:B.prototype.Ky,set:B.prototype.Ty});B.prototype.get_m_suspensionRestLength=B.prototype.fB=function(){return dh(this.hy)};B.prototype.set_m_suspensionRestLength=B.prototype.MD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);eh(c,a)};
-Object.defineProperty(B.prototype,"m_suspensionRestLength",{get:B.prototype.fB,set:B.prototype.MD});B.prototype.get_m_maxSuspensionTravelCm=B.prototype.vy=function(){return fh(this.hy)};B.prototype.set_m_maxSuspensionTravelCm=B.prototype.Cy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);gh(c,a)};Object.defineProperty(B.prototype,"m_maxSuspensionTravelCm",{get:B.prototype.vy,set:B.prototype.Cy});B.prototype.get_m_wheelRadius=B.prototype.tB=function(){return hh(this.hy)};
-B.prototype.set_m_wheelRadius=B.prototype.$D=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ih(c,a)};Object.defineProperty(B.prototype,"m_wheelRadius",{get:B.prototype.tB,set:B.prototype.$D});B.prototype.get_m_suspensionStiffness=B.prototype.wy=function(){return jh(this.hy)};B.prototype.set_m_suspensionStiffness=B.prototype.Dy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);kh(c,a)};Object.defineProperty(B.prototype,"m_suspensionStiffness",{get:B.prototype.wy,set:B.prototype.Dy});
-B.prototype.get_m_wheelsDampingCompression=B.prototype.My=function(){return lh(this.hy)};B.prototype.set_m_wheelsDampingCompression=B.prototype.Vy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);mh(c,a)};Object.defineProperty(B.prototype,"m_wheelsDampingCompression",{get:B.prototype.My,set:B.prototype.Vy});B.prototype.get_m_wheelsDampingRelaxation=B.prototype.Ny=function(){return nh(this.hy)};
-B.prototype.set_m_wheelsDampingRelaxation=B.prototype.Wy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);oh(c,a)};Object.defineProperty(B.prototype,"m_wheelsDampingRelaxation",{get:B.prototype.Ny,set:B.prototype.Wy});B.prototype.get_m_frictionSlip=B.prototype.ry=function(){return ph(this.hy)};B.prototype.set_m_frictionSlip=B.prototype.yy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);qh(c,a)};Object.defineProperty(B.prototype,"m_frictionSlip",{get:B.prototype.ry,set:B.prototype.yy});
-B.prototype.get_m_maxSuspensionForce=B.prototype.uy=function(){return rh(this.hy)};B.prototype.set_m_maxSuspensionForce=B.prototype.By=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);sh(c,a)};Object.defineProperty(B.prototype,"m_maxSuspensionForce",{get:B.prototype.uy,set:B.prototype.By});B.prototype.get_m_bIsFrontWheel=B.prototype.Fy=function(){return!!th(this.hy)};B.prototype.set_m_bIsFrontWheel=B.prototype.Oy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);uh(c,a)};
-Object.defineProperty(B.prototype,"m_bIsFrontWheel",{get:B.prototype.Fy,set:B.prototype.Oy});B.prototype.__destroy__=function(){vh(this.hy)};function lB(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=void 0===c?wh(a):xh(a,c);h(lB)[this.hy]=this}lB.prototype=Object.create(cB.prototype);lB.prototype.constructor=lB;lB.prototype.iy=lB;lB.jy={};b.btConvexTriangleMeshShape=lB;lB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);yh(c,a)};
-lB.prototype.getLocalScaling=function(){return k(zh(this.hy),p)};lB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Ah(d,a,c)};lB.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Bh(c,a)};lB.prototype.getMargin=function(){return Ch(this.hy)};lB.prototype.__destroy__=function(){Dh(this.hy)};function QA(){throw"cannot construct a btBroadphaseInterface, no constructor in IDL";}QA.prototype=Object.create(f.prototype);
-QA.prototype.constructor=QA;QA.prototype.iy=QA;QA.jy={};b.btBroadphaseInterface=QA;QA.prototype.getOverlappingPairCache=function(){return k(Eh(this.hy),PA)};QA.prototype.__destroy__=function(){Fh(this.hy)};function C(a,c,d,e){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);this.hy=void 0===e?Gh(a,c,d):Hh(a,c,d,e);h(C)[this.hy]=this}C.prototype=Object.create(f.prototype);C.prototype.constructor=C;C.prototype.iy=C;
-C.jy={};b.btRigidBodyConstructionInfo=C;C.prototype.get_m_linearDamping=C.prototype.xA=function(){return Ih(this.hy)};C.prototype.set_m_linearDamping=C.prototype.dD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Jh(c,a)};Object.defineProperty(C.prototype,"m_linearDamping",{get:C.prototype.xA,set:C.prototype.dD});C.prototype.get_m_angularDamping=C.prototype.Bz=function(){return Kh(this.hy)};
-C.prototype.set_m_angularDamping=C.prototype.hC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Lh(c,a)};Object.defineProperty(C.prototype,"m_angularDamping",{get:C.prototype.Bz,set:C.prototype.hC});C.prototype.get_m_friction=C.prototype.dA=function(){return Mh(this.hy)};C.prototype.set_m_friction=C.prototype.KC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Nh(c,a)};Object.defineProperty(C.prototype,"m_friction",{get:C.prototype.dA,set:C.prototype.KC});
-C.prototype.get_m_rollingFriction=C.prototype.TA=function(){return Oh(this.hy)};C.prototype.set_m_rollingFriction=C.prototype.zD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ph(c,a)};Object.defineProperty(C.prototype,"m_rollingFriction",{get:C.prototype.TA,set:C.prototype.zD});C.prototype.get_m_restitution=C.prototype.RA=function(){return Qh(this.hy)};C.prototype.set_m_restitution=C.prototype.xD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Rh(c,a)};
-Object.defineProperty(C.prototype,"m_restitution",{get:C.prototype.RA,set:C.prototype.xD});C.prototype.get_m_linearSleepingThreshold=C.prototype.yA=function(){return Sh(this.hy)};C.prototype.set_m_linearSleepingThreshold=C.prototype.eD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Th(c,a)};Object.defineProperty(C.prototype,"m_linearSleepingThreshold",{get:C.prototype.yA,set:C.prototype.eD});C.prototype.get_m_angularSleepingThreshold=C.prototype.Cz=function(){return Uh(this.hy)};
-C.prototype.set_m_angularSleepingThreshold=C.prototype.iC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Vh(c,a)};Object.defineProperty(C.prototype,"m_angularSleepingThreshold",{get:C.prototype.Cz,set:C.prototype.iC});C.prototype.get_m_additionalDamping=C.prototype.wz=function(){return!!Wh(this.hy)};C.prototype.set_m_additionalDamping=C.prototype.cC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Xh(c,a)};
-Object.defineProperty(C.prototype,"m_additionalDamping",{get:C.prototype.wz,set:C.prototype.cC});C.prototype.get_m_additionalDampingFactor=C.prototype.xz=function(){return Yh(this.hy)};C.prototype.set_m_additionalDampingFactor=C.prototype.dC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Zh(c,a)};Object.defineProperty(C.prototype,"m_additionalDampingFactor",{get:C.prototype.xz,set:C.prototype.dC});C.prototype.get_m_additionalLinearDampingThresholdSqr=C.prototype.yz=function(){return $h(this.hy)};
-C.prototype.set_m_additionalLinearDampingThresholdSqr=C.prototype.eC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ai(c,a)};Object.defineProperty(C.prototype,"m_additionalLinearDampingThresholdSqr",{get:C.prototype.yz,set:C.prototype.eC});C.prototype.get_m_additionalAngularDampingThresholdSqr=C.prototype.vz=function(){return bi(this.hy)};C.prototype.set_m_additionalAngularDampingThresholdSqr=C.prototype.bC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ci(c,a)};
-Object.defineProperty(C.prototype,"m_additionalAngularDampingThresholdSqr",{get:C.prototype.vz,set:C.prototype.bC});C.prototype.get_m_additionalAngularDampingFactor=C.prototype.uz=function(){return di(this.hy)};C.prototype.set_m_additionalAngularDampingFactor=C.prototype.aC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ei(c,a)};Object.defineProperty(C.prototype,"m_additionalAngularDampingFactor",{get:C.prototype.uz,set:C.prototype.aC});C.prototype.__destroy__=function(){fi(this.hy)};
-function mB(){throw"cannot construct a btCollisionConfiguration, no constructor in IDL";}mB.prototype=Object.create(f.prototype);mB.prototype.constructor=mB;mB.prototype.iy=mB;mB.jy={};b.btCollisionConfiguration=mB;mB.prototype.__destroy__=function(){gi(this.hy)};function dB(){this.hy=hi();h(dB)[this.hy]=this}dB.prototype=Object.create(f.prototype);dB.prototype.constructor=dB;dB.prototype.iy=dB;dB.jy={};b.btPersistentManifold=dB;dB.prototype.getBody0=function(){return k(ii(this.hy),q)};
-dB.prototype.getBody1=function(){return k(ji(this.hy),q)};dB.prototype.getNumContacts=function(){return ki(this.hy)};dB.prototype.getContactPoint=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(li(c,a),D)};dB.prototype.__destroy__=function(){mi(this.hy)};function nB(a){a&&"object"===typeof a&&(a=a.hy);this.hy=void 0===a?ni():oi(a);h(nB)[this.hy]=this}nB.prototype=Object.create(m.prototype);nB.prototype.constructor=nB;nB.prototype.iy=nB;nB.jy={};b.btCompoundShape=nB;
-nB.prototype.addChildShape=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);pi(d,a,c)};nB.prototype.removeChildShape=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);qi(c,a)};nB.prototype.removeChildShapeByIndex=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ri(c,a)};nB.prototype.getNumChildShapes=function(){return si(this.hy)};nB.prototype.getChildShape=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(ti(c,a),m)};
-nB.prototype.updateChildTransform=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);void 0===d?ui(e,a,c):vi(e,a,c,d)};nB.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);wi(c,a)};nB.prototype.getMargin=function(){return xi(this.hy)};nB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);yi(c,a)};nB.prototype.getLocalScaling=function(){return k(zi(this.hy),p)};
-nB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Ai(d,a,c)};nB.prototype.__destroy__=function(){Bi(this.hy)};function E(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=Ci(a,c);h(E)[this.hy]=this}E.prototype=Object.create(y.prototype);E.prototype.constructor=E;E.prototype.iy=E;E.jy={};b.ClosestConvexResultCallback=E;E.prototype.hasHit=function(){return!!Di(this.hy)};
-E.prototype.get_m_convexFromWorld=E.prototype.Sz=function(){return k(Ei(this.hy),p)};E.prototype.set_m_convexFromWorld=E.prototype.yC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Fi(c,a)};Object.defineProperty(E.prototype,"m_convexFromWorld",{get:E.prototype.Sz,set:E.prototype.yC});E.prototype.get_m_convexToWorld=E.prototype.Tz=function(){return k(Gi(this.hy),p)};E.prototype.set_m_convexToWorld=E.prototype.zC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Hi(c,a)};
-Object.defineProperty(E.prototype,"m_convexToWorld",{get:E.prototype.Tz,set:E.prototype.zC});E.prototype.get_m_hitNormalWorld=E.prototype.sy=function(){return k(Ii(this.hy),p)};E.prototype.set_m_hitNormalWorld=E.prototype.zy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ji(c,a)};Object.defineProperty(E.prototype,"m_hitNormalWorld",{get:E.prototype.sy,set:E.prototype.zy});E.prototype.get_m_hitPointWorld=E.prototype.ty=function(){return k(Ki(this.hy),p)};
-E.prototype.set_m_hitPointWorld=E.prototype.Ay=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Li(c,a)};Object.defineProperty(E.prototype,"m_hitPointWorld",{get:E.prototype.ty,set:E.prototype.Ay});E.prototype.get_m_collisionFilterGroup=E.prototype.ky=function(){return Mi(this.hy)};E.prototype.set_m_collisionFilterGroup=E.prototype.my=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ni(c,a)};Object.defineProperty(E.prototype,"m_collisionFilterGroup",{get:E.prototype.ky,set:E.prototype.my});
-E.prototype.get_m_collisionFilterMask=E.prototype.ly=function(){return Oi(this.hy)};E.prototype.set_m_collisionFilterMask=E.prototype.ny=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pi(c,a)};Object.defineProperty(E.prototype,"m_collisionFilterMask",{get:E.prototype.ly,set:E.prototype.ny});E.prototype.get_m_closestHitFraction=E.prototype.oy=function(){return Qi(this.hy)};
-E.prototype.set_m_closestHitFraction=E.prototype.py=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ri(c,a)};Object.defineProperty(E.prototype,"m_closestHitFraction",{get:E.prototype.oy,set:E.prototype.py});E.prototype.__destroy__=function(){Si(this.hy)};function G(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=Ti(a,c);h(G)[this.hy]=this}G.prototype=Object.create(z.prototype);G.prototype.constructor=G;G.prototype.iy=G;G.jy={};b.AllHitsRayResultCallback=G;
-G.prototype.hasHit=function(){return!!Ui(this.hy)};G.prototype.get_m_collisionObjects=G.prototype.Oz=function(){return k(Vi(this.hy),oB)};G.prototype.set_m_collisionObjects=G.prototype.uC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wi(c,a)};Object.defineProperty(G.prototype,"m_collisionObjects",{get:G.prototype.Oz,set:G.prototype.uC});G.prototype.get_m_rayFromWorld=G.prototype.Iy=function(){return k(Xi(this.hy),p)};
-G.prototype.set_m_rayFromWorld=G.prototype.Ry=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Yi(c,a)};Object.defineProperty(G.prototype,"m_rayFromWorld",{get:G.prototype.Iy,set:G.prototype.Ry});G.prototype.get_m_rayToWorld=G.prototype.Jy=function(){return k(Zi(this.hy),p)};G.prototype.set_m_rayToWorld=G.prototype.Sy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);$i(c,a)};Object.defineProperty(G.prototype,"m_rayToWorld",{get:G.prototype.Jy,set:G.prototype.Sy});
-G.prototype.get_m_hitNormalWorld=G.prototype.sy=function(){return k(aj(this.hy),pB)};G.prototype.set_m_hitNormalWorld=G.prototype.zy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);bj(c,a)};Object.defineProperty(G.prototype,"m_hitNormalWorld",{get:G.prototype.sy,set:G.prototype.zy});G.prototype.get_m_hitPointWorld=G.prototype.ty=function(){return k(cj(this.hy),pB)};G.prototype.set_m_hitPointWorld=G.prototype.Ay=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);dj(c,a)};
-Object.defineProperty(G.prototype,"m_hitPointWorld",{get:G.prototype.ty,set:G.prototype.Ay});G.prototype.get_m_hitFractions=G.prototype.kA=function(){return k(ej(this.hy),kB)};G.prototype.set_m_hitFractions=G.prototype.RC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);fj(c,a)};Object.defineProperty(G.prototype,"m_hitFractions",{get:G.prototype.kA,set:G.prototype.RC});G.prototype.get_m_collisionFilterGroup=G.prototype.ky=function(){return gj(this.hy)};
-G.prototype.set_m_collisionFilterGroup=G.prototype.my=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);hj(c,a)};Object.defineProperty(G.prototype,"m_collisionFilterGroup",{get:G.prototype.ky,set:G.prototype.my});G.prototype.get_m_collisionFilterMask=G.prototype.ly=function(){return ij(this.hy)};G.prototype.set_m_collisionFilterMask=G.prototype.ny=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);jj(c,a)};
-Object.defineProperty(G.prototype,"m_collisionFilterMask",{get:G.prototype.ly,set:G.prototype.ny});G.prototype.get_m_closestHitFraction=G.prototype.oy=function(){return kj(this.hy)};G.prototype.set_m_closestHitFraction=G.prototype.py=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);lj(c,a)};Object.defineProperty(G.prototype,"m_closestHitFraction",{get:G.prototype.oy,set:G.prototype.py});G.prototype.get_m_collisionObject=G.prototype.qy=function(){return k(mj(this.hy),q)};
-G.prototype.set_m_collisionObject=G.prototype.xy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);nj(c,a)};Object.defineProperty(G.prototype,"m_collisionObject",{get:G.prototype.qy,set:G.prototype.xy});G.prototype.__destroy__=function(){oj(this.hy)};function qB(){throw"cannot construct a tMaterialArray, no constructor in IDL";}qB.prototype=Object.create(f.prototype);qB.prototype.constructor=qB;qB.prototype.iy=qB;qB.jy={};b.tMaterialArray=qB;qB.prototype.size=qB.prototype.size=function(){return pj(this.hy)};
-qB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(qj(c,a),A)};qB.prototype.__destroy__=function(){rj(this.hy)};function rB(a){a&&"object"===typeof a&&(a=a.hy);this.hy=sj(a);h(rB)[this.hy]=this}rB.prototype=Object.create($A.prototype);rB.prototype.constructor=rB;rB.prototype.iy=rB;rB.jy={};b.btDefaultVehicleRaycaster=rB;
-rB.prototype.castRay=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);tj(e,a,c,d)};rB.prototype.__destroy__=function(){uj(this.hy)};function sB(){this.hy=vj();h(sB)[this.hy]=this}sB.prototype=Object.create(UA.prototype);sB.prototype.constructor=sB;sB.prototype.iy=sB;sB.jy={};b.btEmptyShape=sB;sB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);wj(c,a)};
-sB.prototype.getLocalScaling=function(){return k(xj(this.hy),p)};sB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);yj(d,a,c)};sB.prototype.__destroy__=function(){zj(this.hy)};function H(){this.hy=Aj();h(H)[this.hy]=this}H.prototype=Object.create(f.prototype);H.prototype.constructor=H;H.prototype.iy=H;H.jy={};b.btConstraintSetting=H;H.prototype.get_m_tau=H.prototype.hB=function(){return Bj(this.hy)};
-H.prototype.set_m_tau=H.prototype.OD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Cj(c,a)};Object.defineProperty(H.prototype,"m_tau",{get:H.prototype.hB,set:H.prototype.OD});H.prototype.get_m_damping=H.prototype.Uz=function(){return Dj(this.hy)};H.prototype.set_m_damping=H.prototype.AC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ej(c,a)};Object.defineProperty(H.prototype,"m_damping",{get:H.prototype.Uz,set:H.prototype.AC});
-H.prototype.get_m_impulseClamp=H.prototype.qA=function(){return Fj(this.hy)};H.prototype.set_m_impulseClamp=H.prototype.XC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Gj(c,a)};Object.defineProperty(H.prototype,"m_impulseClamp",{get:H.prototype.qA,set:H.prototype.XC});H.prototype.__destroy__=function(){Hj(this.hy)};function tB(){throw"cannot construct a LocalShapeInfo, no constructor in IDL";}tB.prototype=Object.create(f.prototype);tB.prototype.constructor=tB;tB.prototype.iy=tB;
-tB.jy={};b.LocalShapeInfo=tB;tB.prototype.get_m_shapePart=tB.prototype.WA=function(){return Ij(this.hy)};tB.prototype.set_m_shapePart=tB.prototype.CD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Jj(c,a)};Object.defineProperty(tB.prototype,"m_shapePart",{get:tB.prototype.WA,set:tB.prototype.CD});tB.prototype.get_m_triangleIndex=tB.prototype.kB=function(){return Kj(this.hy)};
-tB.prototype.set_m_triangleIndex=tB.prototype.RD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Lj(c,a)};Object.defineProperty(tB.prototype,"m_triangleIndex",{get:tB.prototype.kB,set:tB.prototype.RD});tB.prototype.__destroy__=function(){Mj(this.hy)};function I(a){a&&"object"===typeof a&&(a=a.hy);this.hy=Nj(a);h(I)[this.hy]=this}I.prototype=Object.create(q.prototype);I.prototype.constructor=I;I.prototype.iy=I;I.jy={};b.btRigidBody=I;
-I.prototype.getCenterOfMassTransform=function(){return k(Oj(this.hy),r)};I.prototype.setCenterOfMassTransform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pj(c,a)};I.prototype.setSleepingThresholds=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Qj(d,a,c)};I.prototype.getLinearDamping=function(){return Rj(this.hy)};I.prototype.getAngularDamping=function(){return Sj(this.hy)};
-I.prototype.setDamping=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Tj(d,a,c)};I.prototype.setMassProps=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Uj(d,a,c)};I.prototype.getLinearFactor=function(){return k(Vj(this.hy),p)};I.prototype.setLinearFactor=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wj(c,a)};
-I.prototype.applyTorque=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Xj(c,a)};I.prototype.applyLocalTorque=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Yj(c,a)};I.prototype.applyForce=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Zj(d,a,c)};I.prototype.applyCentralForce=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ak(c,a)};
-I.prototype.applyCentralLocalForce=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);bk(c,a)};I.prototype.applyTorqueImpulse=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ck(c,a)};I.prototype.applyImpulse=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);dk(d,a,c)};I.prototype.applyCentralImpulse=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ek(c,a)};I.prototype.updateInertiaTensor=function(){fk(this.hy)};
-I.prototype.getLinearVelocity=function(){return k(gk(this.hy),p)};I.prototype.getAngularVelocity=function(){return k(hk(this.hy),p)};I.prototype.setLinearVelocity=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ik(c,a)};I.prototype.setAngularVelocity=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);jk(c,a)};I.prototype.getMotionState=function(){return k(kk(this.hy),gB)};I.prototype.setMotionState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);lk(c,a)};
-I.prototype.getAngularFactor=function(){return k(mk(this.hy),p)};I.prototype.setAngularFactor=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);nk(c,a)};I.prototype.upcast=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(ok(c,a),I)};I.prototype.getAabb=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);pk(d,a,c)};I.prototype.applyGravity=function(){qk(this.hy)};I.prototype.getGravity=function(){return k(rk(this.hy),p)};
-I.prototype.setGravity=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);sk(c,a)};I.prototype.getBroadphaseProxy=function(){return k(tk(this.hy),t)};I.prototype.clearForces=function(){uk(this.hy)};I.prototype.setAnisotropicFriction=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);vk(d,a,c)};I.prototype.getCollisionShape=function(){return k(wk(this.hy),m)};
-I.prototype.setContactProcessingThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);xk(c,a)};I.prototype.setActivationState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);yk(c,a)};I.prototype.forceActivationState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);zk(c,a)};I.prototype.activate=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);void 0===a?Ak(c):Bk(c,a)};I.prototype.isActive=function(){return!!Ck(this.hy)};I.prototype.isKinematicObject=function(){return!!Dk(this.hy)};
-I.prototype.isStaticObject=function(){return!!Ek(this.hy)};I.prototype.isStaticOrKinematicObject=function(){return!!Fk(this.hy)};I.prototype.getRestitution=function(){return Gk(this.hy)};I.prototype.getFriction=function(){return Hk(this.hy)};I.prototype.getRollingFriction=function(){return Ik(this.hy)};I.prototype.setRestitution=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Jk(c,a)};I.prototype.setFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Kk(c,a)};
-I.prototype.setRollingFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Lk(c,a)};I.prototype.getWorldTransform=function(){return k(Mk(this.hy),r)};I.prototype.getCollisionFlags=function(){return Nk(this.hy)};I.prototype.setCollisionFlags=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ok(c,a)};I.prototype.setWorldTransform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pk(c,a)};
-I.prototype.setCollisionShape=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Qk(c,a)};I.prototype.setCcdMotionThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Rk(c,a)};I.prototype.setCcdSweptSphereRadius=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Sk(c,a)};I.prototype.getUserIndex=function(){return Tk(this.hy)};I.prototype.setUserIndex=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Uk(c,a)};
-I.prototype.getUserPointer=function(){return k(Vk(this.hy),SA)};I.prototype.setUserPointer=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wk(c,a)};I.prototype.getBroadphaseHandle=function(){return k(Xk(this.hy),t)};I.prototype.__destroy__=function(){Yk(this.hy)};function uB(){throw"cannot construct a btIndexedMeshArray, no constructor in IDL";}uB.prototype=Object.create(f.prototype);uB.prototype.constructor=uB;uB.prototype.iy=uB;uB.jy={};b.btIndexedMeshArray=uB;
-uB.prototype.size=uB.prototype.size=function(){return Zk(this.hy)};uB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k($k(c,a),vB)};uB.prototype.__destroy__=function(){al(this.hy)};function wB(){this.hy=bl();h(wB)[this.hy]=this}wB.prototype=Object.create(f.prototype);wB.prototype.constructor=wB;wB.prototype.iy=wB;wB.jy={};b.btDbvtBroadphase=wB;wB.prototype.__destroy__=function(){cl(this.hy)};
-function xB(a,c,d,e,g,n,F,aa,ta){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);n&&"object"===typeof n&&(n=n.hy);F&&"object"===typeof F&&(F=F.hy);aa&&"object"===typeof aa&&(aa=aa.hy);ta&&"object"===typeof ta&&(ta=ta.hy);this.hy=dl(a,c,d,e,g,n,F,aa,ta);h(xB)[this.hy]=this}xB.prototype=Object.create(UA.prototype);xB.prototype.constructor=xB;xB.prototype.iy=xB;xB.jy={};
-b.btHeightfieldTerrainShape=xB;xB.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);el(c,a)};xB.prototype.getMargin=function(){return fl(this.hy)};xB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);gl(c,a)};xB.prototype.getLocalScaling=function(){return k(hl(this.hy),p)};xB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);il(d,a,c)};
-xB.prototype.__destroy__=function(){jl(this.hy)};function yB(){this.hy=kl();h(yB)[this.hy]=this}yB.prototype=Object.create(iB.prototype);yB.prototype.constructor=yB;yB.prototype.iy=yB;yB.jy={};b.btDefaultSoftBodySolver=yB;yB.prototype.__destroy__=function(){ll(this.hy)};function zB(a){a&&"object"===typeof a&&(a=a.hy);this.hy=ml(a);h(zB)[this.hy]=this}zB.prototype=Object.create(OA.prototype);zB.prototype.constructor=zB;zB.prototype.iy=zB;zB.jy={};b.btCollisionDispatcher=zB;
-zB.prototype.getNumManifolds=function(){return nl(this.hy)};zB.prototype.getManifoldByIndexInternal=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(ol(c,a),dB)};zB.prototype.__destroy__=function(){pl(this.hy)};
-function AB(a,c,d,e,g){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);this.hy=void 0===d?ql(a,c):void 0===e?rl(a,c,d):void 0===g?sl(a,c,d,e):tl(a,c,d,e,g);h(AB)[this.hy]=this}AB.prototype=Object.create(f.prototype);AB.prototype.constructor=AB;AB.prototype.iy=AB;AB.jy={};b.btAxisSweep3=AB;AB.prototype.__destroy__=function(){ul(this.hy)};
-function SA(){throw"cannot construct a VoidPtr, no constructor in IDL";}SA.prototype=Object.create(f.prototype);SA.prototype.constructor=SA;SA.prototype.iy=SA;SA.jy={};b.VoidPtr=SA;SA.prototype.__destroy__=function(){vl(this.hy)};function J(){this.hy=wl();h(J)[this.hy]=this}J.prototype=Object.create(f.prototype);J.prototype.constructor=J;J.prototype.iy=J;J.jy={};b.btSoftBodyWorldInfo=J;J.prototype.get_air_density=J.prototype.Yy=function(){return xl(this.hy)};
-J.prototype.set_air_density=J.prototype.FB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);yl(c,a)};Object.defineProperty(J.prototype,"air_density",{get:J.prototype.Yy,set:J.prototype.FB});J.prototype.get_water_density=J.prototype.CB=function(){return zl(this.hy)};J.prototype.set_water_density=J.prototype.iE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Al(c,a)};Object.defineProperty(J.prototype,"water_density",{get:J.prototype.CB,set:J.prototype.iE});
-J.prototype.get_water_offset=J.prototype.EB=function(){return Bl(this.hy)};J.prototype.set_water_offset=J.prototype.kE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Cl(c,a)};Object.defineProperty(J.prototype,"water_offset",{get:J.prototype.EB,set:J.prototype.kE});J.prototype.get_m_maxDisplacement=J.prototype.EA=function(){return Dl(this.hy)};J.prototype.set_m_maxDisplacement=J.prototype.kD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);El(c,a)};
-Object.defineProperty(J.prototype,"m_maxDisplacement",{get:J.prototype.EA,set:J.prototype.kD});J.prototype.get_water_normal=J.prototype.DB=function(){return k(Fl(this.hy),p)};J.prototype.set_water_normal=J.prototype.jE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Gl(c,a)};Object.defineProperty(J.prototype,"water_normal",{get:J.prototype.DB,set:J.prototype.jE});J.prototype.get_m_broadphase=J.prototype.Gz=function(){return k(Hl(this.hy),QA)};
-J.prototype.set_m_broadphase=J.prototype.mC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Il(c,a)};Object.defineProperty(J.prototype,"m_broadphase",{get:J.prototype.Gz,set:J.prototype.mC});J.prototype.get_m_dispatcher=J.prototype.Xz=function(){return k(Jl(this.hy),OA)};J.prototype.set_m_dispatcher=J.prototype.DC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Kl(c,a)};Object.defineProperty(J.prototype,"m_dispatcher",{get:J.prototype.Xz,set:J.prototype.DC});
-J.prototype.get_m_gravity=J.prototype.fA=function(){return k(Ll(this.hy),p)};J.prototype.set_m_gravity=J.prototype.MC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ml(c,a)};Object.defineProperty(J.prototype,"m_gravity",{get:J.prototype.fA,set:J.prototype.MC});J.prototype.__destroy__=function(){Nl(this.hy)};
-function BB(a,c,d,e){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);this.hy=void 0===d?Ol(a,c):void 0===e?_emscripten_bind_btConeTwistConstraint_btConeTwistConstraint_3(a,c,d):Pl(a,c,d,e);h(BB)[this.hy]=this}BB.prototype=Object.create(TA.prototype);BB.prototype.constructor=BB;BB.prototype.iy=BB;BB.jy={};b.btConeTwistConstraint=BB;
-BB.prototype.setLimit=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Ql(d,a,c)};BB.prototype.setAngularOnly=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Rl(c,a)};BB.prototype.setDamping=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Sl(c,a)};BB.prototype.enableMotor=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Tl(c,a)};
-BB.prototype.setMaxMotorImpulse=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ul(c,a)};BB.prototype.setMaxMotorImpulseNormalized=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Vl(c,a)};BB.prototype.setMotorTarget=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wl(c,a)};BB.prototype.setMotorTargetInConstraintSpace=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Xl(c,a)};
-BB.prototype.enableFeedback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Yl(c,a)};BB.prototype.getBreakingImpulseThreshold=function(){return Zl(this.hy)};BB.prototype.setBreakingImpulseThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);$l(c,a)};BB.prototype.getParam=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return am(d,a,c)};
-BB.prototype.setParam=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);bm(e,a,c,d)};BB.prototype.__destroy__=function(){cm(this.hy)};
-function CB(a,c,d,e,g,n,F){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);n&&"object"===typeof n&&(n=n.hy);F&&"object"===typeof F&&(F=F.hy);this.hy=void 0===d?dm(a,c):void 0===e?em(a,c,d):void 0===g?fm(a,c,d,e):void 0===n?gm(a,c,d,e,g):void 0===F?hm(a,c,d,e,g,n):im(a,c,d,e,g,n,F);h(CB)[this.hy]=this}CB.prototype=Object.create(TA.prototype);CB.prototype.constructor=CB;
-CB.prototype.iy=CB;CB.jy={};b.btHingeConstraint=CB;CB.prototype.setLimit=function(a,c,d,e,g){var n=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);void 0===g?jm(n,a,c,d,e):km(n,a,c,d,e,g)};CB.prototype.enableAngularMotor=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);lm(e,a,c,d)};
-CB.prototype.setAngularOnly=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);mm(c,a)};CB.prototype.enableMotor=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);nm(c,a)};CB.prototype.setMaxMotorImpulse=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);om(c,a)};CB.prototype.setMotorTarget=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);pm(d,a,c)};
-CB.prototype.enableFeedback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);qm(c,a)};CB.prototype.getBreakingImpulseThreshold=function(){return rm(this.hy)};CB.prototype.setBreakingImpulseThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);sm(c,a)};CB.prototype.getParam=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return tm(d,a,c)};
-CB.prototype.setParam=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);um(e,a,c,d)};CB.prototype.__destroy__=function(){wm(this.hy)};function DB(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=xm(a,c);h(DB)[this.hy]=this}DB.prototype=Object.create(YA.prototype);DB.prototype.constructor=DB;DB.prototype.iy=DB;DB.jy={};b.btConeShapeZ=DB;
-DB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ym(c,a)};DB.prototype.getLocalScaling=function(){return k(zm(this.hy),p)};DB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Am(d,a,c)};DB.prototype.__destroy__=function(){Bm(this.hy)};function EB(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=Cm(a,c);h(EB)[this.hy]=this}EB.prototype=Object.create(YA.prototype);
-EB.prototype.constructor=EB;EB.prototype.iy=EB;EB.jy={};b.btConeShapeX=EB;EB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Dm(c,a)};EB.prototype.getLocalScaling=function(){return k(Em(this.hy),p)};EB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Fm(d,a,c)};EB.prototype.__destroy__=function(){Gm(this.hy)};
-function FB(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=void 0===a?Hm():void 0===c?Im(a):Jm(a,c);h(FB)[this.hy]=this}FB.prototype=Object.create(fB.prototype);FB.prototype.constructor=FB;FB.prototype.iy=FB;FB.jy={};b.btTriangleMesh=FB;FB.prototype.addTriangle=function(a,c,d,e){var g=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);void 0===e?Km(g,a,c,d):Lm(g,a,c,d,e)};
-FB.prototype.findOrAddVertex=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return Mm(d,a,c)};FB.prototype.addIndex=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Nm(c,a)};FB.prototype.getIndexedMeshArray=function(){return k(Om(this.hy),uB)};FB.prototype.setScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pm(c,a)};FB.prototype.__destroy__=function(){Qm(this.hy)};
-function GB(a,c){IA();"object"==typeof a&&(a=MA(a));c&&"object"===typeof c&&(c=c.hy);this.hy=void 0===a?Rm():void 0===c?Sm(a):Tm(a,c);h(GB)[this.hy]=this}GB.prototype=Object.create(m.prototype);GB.prototype.constructor=GB;GB.prototype.iy=GB;GB.jy={};b.btConvexHullShape=GB;GB.prototype.addPoint=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);void 0===c?Um(d,a):Vm(d,a,c)};
-GB.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wm(c,a)};GB.prototype.getMargin=function(){return Xm(this.hy)};GB.prototype.getNumVertices=function(){return Ym(this.hy)};GB.prototype.initializePolyhedralFeatures=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return!!Zm(c,a)};GB.prototype.recalcLocalAabb=function(){$m(this.hy)};GB.prototype.getConvexPolyhedron=function(){return k(an(this.hy),HB)};
-GB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);bn(c,a)};GB.prototype.getLocalScaling=function(){return k(cn(this.hy),p)};GB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);dn(d,a,c)};GB.prototype.__destroy__=function(){en(this.hy)};function K(){this.hy=fn();h(K)[this.hy]=this}K.prototype=Object.create(f.prototype);K.prototype.constructor=K;K.prototype.iy=K;K.jy={};
-b.btVehicleTuning=K;K.prototype.get_m_suspensionStiffness=K.prototype.wy=function(){return gn(this.hy)};K.prototype.set_m_suspensionStiffness=K.prototype.Dy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);hn(c,a)};Object.defineProperty(K.prototype,"m_suspensionStiffness",{get:K.prototype.wy,set:K.prototype.Dy});K.prototype.get_m_suspensionCompression=K.prototype.bB=function(){return jn(this.hy)};
-K.prototype.set_m_suspensionCompression=K.prototype.ID=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);kn(c,a)};Object.defineProperty(K.prototype,"m_suspensionCompression",{get:K.prototype.bB,set:K.prototype.ID});K.prototype.get_m_suspensionDamping=K.prototype.cB=function(){return ln(this.hy)};K.prototype.set_m_suspensionDamping=K.prototype.JD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);mn(c,a)};
-Object.defineProperty(K.prototype,"m_suspensionDamping",{get:K.prototype.cB,set:K.prototype.JD});K.prototype.get_m_maxSuspensionTravelCm=K.prototype.vy=function(){return nn(this.hy)};K.prototype.set_m_maxSuspensionTravelCm=K.prototype.Cy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);on(c,a)};Object.defineProperty(K.prototype,"m_maxSuspensionTravelCm",{get:K.prototype.vy,set:K.prototype.Cy});K.prototype.get_m_frictionSlip=K.prototype.ry=function(){return pn(this.hy)};
-K.prototype.set_m_frictionSlip=K.prototype.yy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);qn(c,a)};Object.defineProperty(K.prototype,"m_frictionSlip",{get:K.prototype.ry,set:K.prototype.yy});K.prototype.get_m_maxSuspensionForce=K.prototype.uy=function(){return rn(this.hy)};K.prototype.set_m_maxSuspensionForce=K.prototype.By=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);sn(c,a)};Object.defineProperty(K.prototype,"m_maxSuspensionForce",{get:K.prototype.uy,set:K.prototype.By});
-function IB(){throw"cannot construct a btCollisionObjectWrapper, no constructor in IDL";}IB.prototype=Object.create(f.prototype);IB.prototype.constructor=IB;IB.prototype.iy=IB;IB.jy={};b.btCollisionObjectWrapper=IB;IB.prototype.getWorldTransform=function(){return k(tn(this.hy),r)};IB.prototype.getCollisionObject=function(){return k(un(this.hy),q)};IB.prototype.getCollisionShape=function(){return k(vn(this.hy),m)};function JB(a){a&&"object"===typeof a&&(a=a.hy);this.hy=wn(a);h(JB)[this.hy]=this}
-JB.prototype=Object.create(f.prototype);JB.prototype.constructor=JB;JB.prototype.iy=JB;JB.jy={};b.btShapeHull=JB;JB.prototype.buildHull=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return!!xn(c,a)};JB.prototype.numVertices=function(){return yn(this.hy)};JB.prototype.getVertexPointer=function(){return k(zn(this.hy),p)};JB.prototype.__destroy__=function(){An(this.hy)};
-function KB(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=void 0===a?Bn():void 0===c?Cn(a):Dn(a,c);h(KB)[this.hy]=this}KB.prototype=Object.create(gB.prototype);KB.prototype.constructor=KB;KB.prototype.iy=KB;KB.jy={};b.btDefaultMotionState=KB;KB.prototype.getWorldTransform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);En(c,a)};KB.prototype.setWorldTransform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Fn(c,a)};
-KB.prototype.get_m_graphicsWorldTrans=KB.prototype.eA=function(){return k(Gn(this.hy),r)};KB.prototype.set_m_graphicsWorldTrans=KB.prototype.LC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Hn(c,a)};Object.defineProperty(KB.prototype,"m_graphicsWorldTrans",{get:KB.prototype.eA,set:KB.prototype.LC});KB.prototype.__destroy__=function(){In(this.hy)};function L(a){a&&"object"===typeof a&&(a=a.hy);this.hy=Jn(a);h(L)[this.hy]=this}L.prototype=Object.create(f.prototype);
-L.prototype.constructor=L;L.prototype.iy=L;L.jy={};b.btWheelInfo=L;L.prototype.getSuspensionRestLength=function(){return Kn(this.hy)};L.prototype.updateWheel=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Ln(d,a,c)};L.prototype.get_m_suspensionStiffness=L.prototype.wy=function(){return Mn(this.hy)};L.prototype.set_m_suspensionStiffness=L.prototype.Dy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Nn(c,a)};
-Object.defineProperty(L.prototype,"m_suspensionStiffness",{get:L.prototype.wy,set:L.prototype.Dy});L.prototype.get_m_frictionSlip=L.prototype.ry=function(){return On(this.hy)};L.prototype.set_m_frictionSlip=L.prototype.yy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pn(c,a)};Object.defineProperty(L.prototype,"m_frictionSlip",{get:L.prototype.ry,set:L.prototype.yy});L.prototype.get_m_engineForce=L.prototype.aA=function(){return Qn(this.hy)};
-L.prototype.set_m_engineForce=L.prototype.HC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Rn(c,a)};Object.defineProperty(L.prototype,"m_engineForce",{get:L.prototype.aA,set:L.prototype.HC});L.prototype.get_m_rollInfluence=L.prototype.SA=function(){return Sn(this.hy)};L.prototype.set_m_rollInfluence=L.prototype.yD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Tn(c,a)};Object.defineProperty(L.prototype,"m_rollInfluence",{get:L.prototype.SA,set:L.prototype.yD});
-L.prototype.get_m_suspensionRestLength1=L.prototype.gB=function(){return Un(this.hy)};L.prototype.set_m_suspensionRestLength1=L.prototype.ND=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Vn(c,a)};Object.defineProperty(L.prototype,"m_suspensionRestLength1",{get:L.prototype.gB,set:L.prototype.ND});L.prototype.get_m_wheelsRadius=L.prototype.uB=function(){return Wn(this.hy)};L.prototype.set_m_wheelsRadius=L.prototype.aE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Xn(c,a)};
-Object.defineProperty(L.prototype,"m_wheelsRadius",{get:L.prototype.uB,set:L.prototype.aE});L.prototype.get_m_wheelsDampingCompression=L.prototype.My=function(){return Yn(this.hy)};L.prototype.set_m_wheelsDampingCompression=L.prototype.Vy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Zn(c,a)};Object.defineProperty(L.prototype,"m_wheelsDampingCompression",{get:L.prototype.My,set:L.prototype.Vy});L.prototype.get_m_wheelsDampingRelaxation=L.prototype.Ny=function(){return $n(this.hy)};
-L.prototype.set_m_wheelsDampingRelaxation=L.prototype.Wy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ao(c,a)};Object.defineProperty(L.prototype,"m_wheelsDampingRelaxation",{get:L.prototype.Ny,set:L.prototype.Wy});L.prototype.get_m_steering=L.prototype.$A=function(){return bo(this.hy)};L.prototype.set_m_steering=L.prototype.GD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);co(c,a)};Object.defineProperty(L.prototype,"m_steering",{get:L.prototype.$A,set:L.prototype.GD});
-L.prototype.get_m_maxSuspensionForce=L.prototype.uy=function(){return eo(this.hy)};L.prototype.set_m_maxSuspensionForce=L.prototype.By=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);fo(c,a)};Object.defineProperty(L.prototype,"m_maxSuspensionForce",{get:L.prototype.uy,set:L.prototype.By});L.prototype.get_m_maxSuspensionTravelCm=L.prototype.vy=function(){return go(this.hy)};
-L.prototype.set_m_maxSuspensionTravelCm=L.prototype.Cy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ho(c,a)};Object.defineProperty(L.prototype,"m_maxSuspensionTravelCm",{get:L.prototype.vy,set:L.prototype.Cy});L.prototype.get_m_wheelsSuspensionForce=L.prototype.vB=function(){return io(this.hy)};L.prototype.set_m_wheelsSuspensionForce=L.prototype.bE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);jo(c,a)};
-Object.defineProperty(L.prototype,"m_wheelsSuspensionForce",{get:L.prototype.vB,set:L.prototype.bE});L.prototype.get_m_bIsFrontWheel=L.prototype.Fy=function(){return!!ko(this.hy)};L.prototype.set_m_bIsFrontWheel=L.prototype.Oy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);lo(c,a)};Object.defineProperty(L.prototype,"m_bIsFrontWheel",{get:L.prototype.Fy,set:L.prototype.Oy});L.prototype.get_m_raycastInfo=L.prototype.QA=function(){return k(mo(this.hy),M)};
-L.prototype.set_m_raycastInfo=L.prototype.wD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);no(c,a)};Object.defineProperty(L.prototype,"m_raycastInfo",{get:L.prototype.QA,set:L.prototype.wD});L.prototype.get_m_chassisConnectionPointCS=L.prototype.Mz=function(){return k(oo(this.hy),p)};L.prototype.set_m_chassisConnectionPointCS=L.prototype.sC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);po(c,a)};
-Object.defineProperty(L.prototype,"m_chassisConnectionPointCS",{get:L.prototype.Mz,set:L.prototype.sC});L.prototype.get_m_worldTransform=L.prototype.wB=function(){return k(qo(this.hy),r)};L.prototype.set_m_worldTransform=L.prototype.cE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ro(c,a)};Object.defineProperty(L.prototype,"m_worldTransform",{get:L.prototype.wB,set:L.prototype.cE});L.prototype.get_m_wheelDirectionCS=L.prototype.Ly=function(){return k(so(this.hy),p)};
-L.prototype.set_m_wheelDirectionCS=L.prototype.Uy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);to(c,a)};Object.defineProperty(L.prototype,"m_wheelDirectionCS",{get:L.prototype.Ly,set:L.prototype.Uy});L.prototype.get_m_wheelAxleCS=L.prototype.Ky=function(){return k(uo(this.hy),p)};L.prototype.set_m_wheelAxleCS=L.prototype.Ty=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);vo(c,a)};Object.defineProperty(L.prototype,"m_wheelAxleCS",{get:L.prototype.Ky,set:L.prototype.Ty});
-L.prototype.get_m_rotation=L.prototype.UA=function(){return wo(this.hy)};L.prototype.set_m_rotation=L.prototype.AD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);xo(c,a)};Object.defineProperty(L.prototype,"m_rotation",{get:L.prototype.UA,set:L.prototype.AD});L.prototype.get_m_deltaRotation=L.prototype.Vz=function(){return yo(this.hy)};L.prototype.set_m_deltaRotation=L.prototype.BC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);zo(c,a)};
-Object.defineProperty(L.prototype,"m_deltaRotation",{get:L.prototype.Vz,set:L.prototype.BC});L.prototype.get_m_brake=L.prototype.Fz=function(){return Ao(this.hy)};L.prototype.set_m_brake=L.prototype.lC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Bo(c,a)};Object.defineProperty(L.prototype,"m_brake",{get:L.prototype.Fz,set:L.prototype.lC});L.prototype.get_m_clippedInvContactDotSuspension=L.prototype.Nz=function(){return Co(this.hy)};
-L.prototype.set_m_clippedInvContactDotSuspension=L.prototype.tC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Do(c,a)};Object.defineProperty(L.prototype,"m_clippedInvContactDotSuspension",{get:L.prototype.Nz,set:L.prototype.tC});L.prototype.get_m_suspensionRelativeVelocity=L.prototype.eB=function(){return Eo(this.hy)};L.prototype.set_m_suspensionRelativeVelocity=L.prototype.LD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Fo(c,a)};
-Object.defineProperty(L.prototype,"m_suspensionRelativeVelocity",{get:L.prototype.eB,set:L.prototype.LD});L.prototype.get_m_skidInfo=L.prototype.XA=function(){return Go(this.hy)};L.prototype.set_m_skidInfo=L.prototype.DD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ho(c,a)};Object.defineProperty(L.prototype,"m_skidInfo",{get:L.prototype.XA,set:L.prototype.DD});L.prototype.__destroy__=function(){Io(this.hy)};
-function N(a,c,d,e){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);this.hy=void 0===a?Jo():void 0===c?_emscripten_bind_btVector4_btVector4_1(a):void 0===d?_emscripten_bind_btVector4_btVector4_2(a,c):void 0===e?_emscripten_bind_btVector4_btVector4_3(a,c,d):Ko(a,c,d,e);h(N)[this.hy]=this}N.prototype=Object.create(p.prototype);N.prototype.constructor=N;N.prototype.iy=N;N.jy={};b.btVector4=N;N.prototype.w=function(){return Lo(this.hy)};
-N.prototype.setValue=function(a,c,d,e){var g=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);Mo(g,a,c,d,e)};N.prototype.length=N.prototype.length=function(){return No(this.hy)};N.prototype.x=N.prototype.x=function(){return Oo(this.hy)};N.prototype.y=N.prototype.y=function(){return Po(this.hy)};N.prototype.z=N.prototype.z=function(){return Qo(this.hy)};
-N.prototype.setX=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ro(c,a)};N.prototype.setY=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);So(c,a)};N.prototype.setZ=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);To(c,a)};N.prototype.normalize=N.prototype.normalize=function(){Uo(this.hy)};N.prototype.rotate=N.prototype.rotate=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return k(Vo(d,a,c),p)};
-N.prototype.dot=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return Wo(c,a)};N.prototype.op_mul=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Xo(c,a),p)};N.prototype.op_add=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Yo(c,a),p)};N.prototype.op_sub=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Zo(c,a),p)};N.prototype.__destroy__=function(){$o(this.hy)};function LB(){this.hy=ap();h(LB)[this.hy]=this}LB.prototype=Object.create(f.prototype);
-LB.prototype.constructor=LB;LB.prototype.iy=LB;LB.jy={};b.btDefaultCollisionConstructionInfo=LB;LB.prototype.__destroy__=function(){bp(this.hy)};function O(){throw"cannot construct a Anchor, no constructor in IDL";}O.prototype=Object.create(f.prototype);O.prototype.constructor=O;O.prototype.iy=O;O.jy={};b.Anchor=O;O.prototype.get_m_node=O.prototype.FA=function(){return k(cp(this.hy),Node)};O.prototype.set_m_node=O.prototype.lD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);dp(c,a)};
-Object.defineProperty(O.prototype,"m_node",{get:O.prototype.FA,set:O.prototype.lD});O.prototype.get_m_local=O.prototype.zA=function(){return k(ep(this.hy),p)};O.prototype.set_m_local=O.prototype.fD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);fp(c,a)};Object.defineProperty(O.prototype,"m_local",{get:O.prototype.zA,set:O.prototype.fD});O.prototype.get_m_body=O.prototype.Ez=function(){return k(gp(this.hy),I)};
-O.prototype.set_m_body=O.prototype.kC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);hp(c,a)};Object.defineProperty(O.prototype,"m_body",{get:O.prototype.Ez,set:O.prototype.kC});O.prototype.get_m_influence=O.prototype.sA=function(){return ip(this.hy)};O.prototype.set_m_influence=O.prototype.ZC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);jp(c,a)};Object.defineProperty(O.prototype,"m_influence",{get:O.prototype.sA,set:O.prototype.ZC});
-O.prototype.get_m_c0=O.prototype.Hz=function(){return k(kp(this.hy),jB)};O.prototype.set_m_c0=O.prototype.nC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);lp(c,a)};Object.defineProperty(O.prototype,"m_c0",{get:O.prototype.Hz,set:O.prototype.nC});O.prototype.get_m_c1=O.prototype.Iz=function(){return k(mp(this.hy),p)};O.prototype.set_m_c1=O.prototype.oC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);np(c,a)};Object.defineProperty(O.prototype,"m_c1",{get:O.prototype.Iz,set:O.prototype.oC});
-O.prototype.get_m_c2=O.prototype.Jz=function(){return op(this.hy)};O.prototype.set_m_c2=O.prototype.pC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);pp(c,a)};Object.defineProperty(O.prototype,"m_c2",{get:O.prototype.Jz,set:O.prototype.pC});O.prototype.__destroy__=function(){qp(this.hy)};function P(){throw"cannot construct a btVehicleRaycasterResult, no constructor in IDL";}P.prototype=Object.create(f.prototype);P.prototype.constructor=P;P.prototype.iy=P;P.jy={};
-b.btVehicleRaycasterResult=P;P.prototype.get_m_hitPointInWorld=P.prototype.nA=function(){return k(rp(this.hy),p)};P.prototype.set_m_hitPointInWorld=P.prototype.UC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);sp(c,a)};Object.defineProperty(P.prototype,"m_hitPointInWorld",{get:P.prototype.nA,set:P.prototype.UC});P.prototype.get_m_hitNormalInWorld=P.prototype.lA=function(){return k(tp(this.hy),p)};
-P.prototype.set_m_hitNormalInWorld=P.prototype.SC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);up(c,a)};Object.defineProperty(P.prototype,"m_hitNormalInWorld",{get:P.prototype.lA,set:P.prototype.SC});P.prototype.get_m_distFraction=P.prototype.Yz=function(){return vp(this.hy)};P.prototype.set_m_distFraction=P.prototype.EC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);wp(c,a)};Object.defineProperty(P.prototype,"m_distFraction",{get:P.prototype.Yz,set:P.prototype.EC});
-P.prototype.__destroy__=function(){xp(this.hy)};function pB(){throw"cannot construct a btVector3Array, no constructor in IDL";}pB.prototype=Object.create(f.prototype);pB.prototype.constructor=pB;pB.prototype.iy=pB;pB.jy={};b.btVector3Array=pB;pB.prototype.size=pB.prototype.size=function(){return yp(this.hy)};pB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(zp(c,a),p)};pB.prototype.__destroy__=function(){Ap(this.hy)};
-function MB(){throw"cannot construct a btConstraintSolver, no constructor in IDL";}MB.prototype=Object.create(f.prototype);MB.prototype.constructor=MB;MB.prototype.iy=MB;MB.jy={};b.btConstraintSolver=MB;MB.prototype.__destroy__=function(){Bp(this.hy)};function Q(a,c,d){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);this.hy=Cp(a,c,d);h(Q)[this.hy]=this}Q.prototype=Object.create(ZA.prototype);Q.prototype.constructor=Q;Q.prototype.iy=Q;Q.jy={};
-b.btRaycastVehicle=Q;Q.prototype.applyEngineForce=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Dp(d,a,c)};Q.prototype.setSteeringValue=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Ep(d,a,c)};Q.prototype.getWheelTransformWS=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Fp(c,a),r)};
-Q.prototype.updateWheelTransform=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Gp(d,a,c)};Q.prototype.addWheel=function(a,c,d,e,g,n,F){var aa=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);n&&"object"===typeof n&&(n=n.hy);F&&"object"===typeof F&&(F=F.hy);return k(Hp(aa,a,c,d,e,g,n,F),L)};Q.prototype.getNumWheels=function(){return Ip(this.hy)};
-Q.prototype.getRigidBody=function(){return k(Jp(this.hy),I)};Q.prototype.getWheelInfo=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Kp(c,a),L)};Q.prototype.setBrake=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Lp(d,a,c)};Q.prototype.setCoordinateSystem=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Mp(e,a,c,d)};Q.prototype.getCurrentSpeedKmHour=function(){return Np(this.hy)};
-Q.prototype.getChassisWorldTransform=function(){return k(Op(this.hy),r)};Q.prototype.rayCast=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return Pp(c,a)};Q.prototype.updateVehicle=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Qp(c,a)};Q.prototype.resetSuspension=function(){Rp(this.hy)};Q.prototype.getSteeringValue=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return Sp(c,a)};
-Q.prototype.updateWheelTransformsWS=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);void 0===c?Tp(d,a):Up(d,a,c)};Q.prototype.setPitchControl=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Vp(c,a)};Q.prototype.updateSuspension=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wp(c,a)};Q.prototype.updateFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Xp(c,a)};Q.prototype.getRightAxis=function(){return Yp(this.hy)};
-Q.prototype.getUpAxis=function(){return Zp(this.hy)};Q.prototype.getForwardAxis=function(){return $p(this.hy)};Q.prototype.getForwardVector=function(){return k(aq(this.hy),p)};Q.prototype.getUserConstraintType=function(){return bq(this.hy)};Q.prototype.setUserConstraintType=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);cq(c,a)};Q.prototype.setUserConstraintId=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);dq(c,a)};Q.prototype.getUserConstraintId=function(){return eq(this.hy)};
-Q.prototype.updateAction=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);fq(d,a,c)};Q.prototype.__destroy__=function(){gq(this.hy)};function NB(a){a&&"object"===typeof a&&(a=a.hy);this.hy=hq(a);h(NB)[this.hy]=this}NB.prototype=Object.create(bB.prototype);NB.prototype.constructor=NB;NB.prototype.iy=NB;NB.jy={};b.btCylinderShapeX=NB;NB.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);iq(c,a)};NB.prototype.getMargin=function(){return jq(this.hy)};
-NB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);kq(c,a)};NB.prototype.getLocalScaling=function(){return k(lq(this.hy),p)};NB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);mq(d,a,c)};NB.prototype.__destroy__=function(){nq(this.hy)};function OB(a){a&&"object"===typeof a&&(a=a.hy);this.hy=oq(a);h(OB)[this.hy]=this}OB.prototype=Object.create(bB.prototype);OB.prototype.constructor=OB;
-OB.prototype.iy=OB;OB.jy={};b.btCylinderShapeZ=OB;OB.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);pq(c,a)};OB.prototype.getMargin=function(){return qq(this.hy)};OB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);rq(c,a)};OB.prototype.getLocalScaling=function(){return k(sq(this.hy),p)};OB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);tq(d,a,c)};
-OB.prototype.__destroy__=function(){uq(this.hy)};function HB(){throw"cannot construct a btConvexPolyhedron, no constructor in IDL";}HB.prototype=Object.create(f.prototype);HB.prototype.constructor=HB;HB.prototype.iy=HB;HB.jy={};b.btConvexPolyhedron=HB;HB.prototype.get_m_vertices=HB.prototype.qB=function(){return k(vq(this.hy),pB)};HB.prototype.set_m_vertices=HB.prototype.XD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);wq(c,a)};
-Object.defineProperty(HB.prototype,"m_vertices",{get:HB.prototype.qB,set:HB.prototype.XD});HB.prototype.get_m_faces=HB.prototype.Gy=function(){return k(xq(this.hy),PB)};HB.prototype.set_m_faces=HB.prototype.Py=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);yq(c,a)};Object.defineProperty(HB.prototype,"m_faces",{get:HB.prototype.Gy,set:HB.prototype.Py});HB.prototype.__destroy__=function(){zq(this.hy)};function QB(){this.hy=Aq();h(QB)[this.hy]=this}QB.prototype=Object.create(f.prototype);
-QB.prototype.constructor=QB;QB.prototype.iy=QB;QB.jy={};b.btSequentialImpulseConstraintSolver=QB;QB.prototype.__destroy__=function(){Bq(this.hy)};function RB(){throw"cannot construct a tAnchorArray, no constructor in IDL";}RB.prototype=Object.create(f.prototype);RB.prototype.constructor=RB;RB.prototype.iy=RB;RB.jy={};b.tAnchorArray=RB;RB.prototype.size=RB.prototype.size=function(){return Cq(this.hy)};RB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Dq(c,a),O)};
-RB.prototype.clear=RB.prototype.clear=function(){Eq(this.hy)};RB.prototype.push_back=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Fq(c,a)};RB.prototype.pop_back=function(){Gq(this.hy)};RB.prototype.__destroy__=function(){Hq(this.hy)};function M(){throw"cannot construct a RaycastInfo, no constructor in IDL";}M.prototype=Object.create(f.prototype);M.prototype.constructor=M;M.prototype.iy=M;M.jy={};b.RaycastInfo=M;
-M.prototype.get_m_contactNormalWS=M.prototype.Pz=function(){return k(Iq(this.hy),p)};M.prototype.set_m_contactNormalWS=M.prototype.vC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Jq(c,a)};Object.defineProperty(M.prototype,"m_contactNormalWS",{get:M.prototype.Pz,set:M.prototype.vC});M.prototype.get_m_contactPointWS=M.prototype.Qz=function(){return k(Kq(this.hy),p)};M.prototype.set_m_contactPointWS=M.prototype.wC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Lq(c,a)};
-Object.defineProperty(M.prototype,"m_contactPointWS",{get:M.prototype.Qz,set:M.prototype.wC});M.prototype.get_m_suspensionLength=M.prototype.dB=function(){return Mq(this.hy)};M.prototype.set_m_suspensionLength=M.prototype.KD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Nq(c,a)};Object.defineProperty(M.prototype,"m_suspensionLength",{get:M.prototype.dB,set:M.prototype.KD});M.prototype.get_m_hardPointWS=M.prototype.hA=function(){return k(Oq(this.hy),p)};
-M.prototype.set_m_hardPointWS=M.prototype.OC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pq(c,a)};Object.defineProperty(M.prototype,"m_hardPointWS",{get:M.prototype.hA,set:M.prototype.OC});M.prototype.get_m_wheelDirectionWS=M.prototype.sB=function(){return k(Qq(this.hy),p)};M.prototype.set_m_wheelDirectionWS=M.prototype.ZD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Rq(c,a)};Object.defineProperty(M.prototype,"m_wheelDirectionWS",{get:M.prototype.sB,set:M.prototype.ZD});
-M.prototype.get_m_wheelAxleWS=M.prototype.rB=function(){return k(Sq(this.hy),p)};M.prototype.set_m_wheelAxleWS=M.prototype.YD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Tq(c,a)};Object.defineProperty(M.prototype,"m_wheelAxleWS",{get:M.prototype.rB,set:M.prototype.YD});M.prototype.get_m_isInContact=M.prototype.tA=function(){return!!Uq(this.hy)};M.prototype.set_m_isInContact=M.prototype.$C=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Vq(c,a)};
-Object.defineProperty(M.prototype,"m_isInContact",{get:M.prototype.tA,set:M.prototype.$C});M.prototype.get_m_groundObject=M.prototype.gA=function(){return Wq(this.hy)};M.prototype.set_m_groundObject=M.prototype.NC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Xq(c,a)};Object.defineProperty(M.prototype,"m_groundObject",{get:M.prototype.gA,set:M.prototype.NC});M.prototype.__destroy__=function(){Yq(this.hy)};
-function SB(a,c,d){IA();a&&"object"===typeof a&&(a=a.hy);"object"==typeof c&&(c=MA(c));d&&"object"===typeof d&&(d=d.hy);this.hy=Zq(a,c,d);h(SB)[this.hy]=this}SB.prototype=Object.create(m.prototype);SB.prototype.constructor=SB;SB.prototype.iy=SB;SB.jy={};b.btMultiSphereShape=SB;SB.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);$q(c,a)};SB.prototype.getLocalScaling=function(){return k(ar(this.hy),p)};
-SB.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);br(d,a,c)};SB.prototype.__destroy__=function(){cr(this.hy)};function R(a,c,d,e){IA();a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);"object"==typeof e&&(e=MA(e));this.hy=dr(a,c,d,e);h(R)[this.hy]=this}R.prototype=Object.create(q.prototype);R.prototype.constructor=R;R.prototype.iy=R;R.jy={};b.btSoftBody=R;
-R.prototype.checkLink=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return!!er(d,a,c)};R.prototype.checkFace=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);return!!fr(e,a,c,d)};R.prototype.appendMaterial=function(){return k(gr(this.hy),A)};R.prototype.appendNode=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);hr(d,a,c)};
-R.prototype.appendLink=function(a,c,d,e){var g=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);ir(g,a,c,d,e)};R.prototype.appendFace=function(a,c,d,e){var g=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);jr(g,a,c,d,e)};
-R.prototype.appendTetra=function(a,c,d,e,g){var n=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);kr(n,a,c,d,e,g)};R.prototype.appendAnchor=function(a,c,d,e){var g=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);lr(g,a,c,d,e)};
-R.prototype.addForce=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);void 0===c?mr(d,a):nr(d,a,c)};R.prototype.addAeroForceToNode=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);or(d,a,c)};R.prototype.getTotalMass=function(){return pr(this.hy)};R.prototype.setTotalMass=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);qr(d,a,c)};
-R.prototype.setMass=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);rr(d,a,c)};R.prototype.transform=R.prototype.transform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);sr(c,a)};R.prototype.translate=R.prototype.translate=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);tr(c,a)};R.prototype.rotate=R.prototype.rotate=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ur(c,a)};
-R.prototype.scale=R.prototype.scale=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);vr(c,a)};R.prototype.generateClusters=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return void 0===c?wr(d,a):xr(d,a,c)};R.prototype.generateBendingConstraints=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return yr(d,a,c)};
-R.prototype.upcast=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(zr(c,a),R)};R.prototype.setAnisotropicFriction=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Ar(d,a,c)};R.prototype.getCollisionShape=function(){return k(Br(this.hy),m)};R.prototype.setContactProcessingThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Cr(c,a)};
-R.prototype.setActivationState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Dr(c,a)};R.prototype.forceActivationState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Er(c,a)};R.prototype.activate=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);void 0===a?Fr(c):Gr(c,a)};R.prototype.isActive=function(){return!!Hr(this.hy)};R.prototype.isKinematicObject=function(){return!!Ir(this.hy)};R.prototype.isStaticObject=function(){return!!Jr(this.hy)};
-R.prototype.isStaticOrKinematicObject=function(){return!!Kr(this.hy)};R.prototype.getRestitution=function(){return Lr(this.hy)};R.prototype.getFriction=function(){return Mr(this.hy)};R.prototype.getRollingFriction=function(){return Nr(this.hy)};R.prototype.setRestitution=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Or(c,a)};R.prototype.setFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pr(c,a)};
-R.prototype.setRollingFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Qr(c,a)};R.prototype.getWorldTransform=function(){return k(Rr(this.hy),r)};R.prototype.getCollisionFlags=function(){return Sr(this.hy)};R.prototype.setCollisionFlags=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Tr(c,a)};R.prototype.setWorldTransform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ur(c,a)};
-R.prototype.setCollisionShape=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Vr(c,a)};R.prototype.setCcdMotionThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wr(c,a)};R.prototype.setCcdSweptSphereRadius=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Xr(c,a)};R.prototype.getUserIndex=function(){return Yr(this.hy)};R.prototype.setUserIndex=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Zr(c,a)};
-R.prototype.getUserPointer=function(){return k($r(this.hy),SA)};R.prototype.setUserPointer=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);as(c,a)};R.prototype.getBroadphaseHandle=function(){return k(bs(this.hy),t)};R.prototype.get_m_cfg=R.prototype.Kz=function(){return k(cs(this.hy),S)};R.prototype.set_m_cfg=R.prototype.qC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ds(c,a)};Object.defineProperty(R.prototype,"m_cfg",{get:R.prototype.Kz,set:R.prototype.qC});
-R.prototype.get_m_nodes=R.prototype.GA=function(){return k(es(this.hy),TB)};R.prototype.set_m_nodes=R.prototype.mD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);gs(c,a)};Object.defineProperty(R.prototype,"m_nodes",{get:R.prototype.GA,set:R.prototype.mD});R.prototype.get_m_faces=R.prototype.Gy=function(){return k(hs(this.hy),UB)};R.prototype.set_m_faces=R.prototype.Py=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);is(c,a)};
-Object.defineProperty(R.prototype,"m_faces",{get:R.prototype.Gy,set:R.prototype.Py});R.prototype.get_m_materials=R.prototype.DA=function(){return k(js(this.hy),qB)};R.prototype.set_m_materials=R.prototype.jD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ks(c,a)};Object.defineProperty(R.prototype,"m_materials",{get:R.prototype.DA,set:R.prototype.jD});R.prototype.get_m_anchors=R.prototype.Az=function(){return k(ls(this.hy),RB)};
-R.prototype.set_m_anchors=R.prototype.gC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ms(c,a)};Object.defineProperty(R.prototype,"m_anchors",{get:R.prototype.Az,set:R.prototype.gC});R.prototype.__destroy__=function(){ns(this.hy)};function VB(){throw"cannot construct a btIntArray, no constructor in IDL";}VB.prototype=Object.create(f.prototype);VB.prototype.constructor=VB;VB.prototype.iy=VB;VB.jy={};b.btIntArray=VB;VB.prototype.size=VB.prototype.size=function(){return ps(this.hy)};
-VB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return qs(c,a)};VB.prototype.__destroy__=function(){rs(this.hy)};function S(){throw"cannot construct a Config, no constructor in IDL";}S.prototype=Object.create(f.prototype);S.prototype.constructor=S;S.prototype.iy=S;S.jy={};b.Config=S;S.prototype.get_kVCF=S.prototype.sz=function(){return ss(this.hy)};S.prototype.set_kVCF=S.prototype.$B=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ts(c,a)};
-Object.defineProperty(S.prototype,"kVCF",{get:S.prototype.sz,set:S.prototype.$B});S.prototype.get_kDP=S.prototype.fz=function(){return us(this.hy)};S.prototype.set_kDP=S.prototype.NB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);vs(c,a)};Object.defineProperty(S.prototype,"kDP",{get:S.prototype.fz,set:S.prototype.NB});S.prototype.get_kDG=S.prototype.ez=function(){return xs(this.hy)};S.prototype.set_kDG=S.prototype.MB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ys(c,a)};
-Object.defineProperty(S.prototype,"kDG",{get:S.prototype.ez,set:S.prototype.MB});S.prototype.get_kLF=S.prototype.hz=function(){return zs(this.hy)};S.prototype.set_kLF=S.prototype.PB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);As(c,a)};Object.defineProperty(S.prototype,"kLF",{get:S.prototype.hz,set:S.prototype.PB});S.prototype.get_kPR=S.prototype.jz=function(){return Bs(this.hy)};S.prototype.set_kPR=S.prototype.RB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Cs(c,a)};
-Object.defineProperty(S.prototype,"kPR",{get:S.prototype.jz,set:S.prototype.RB});S.prototype.get_kVC=S.prototype.rz=function(){return Ds(this.hy)};S.prototype.set_kVC=S.prototype.ZB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Es(c,a)};Object.defineProperty(S.prototype,"kVC",{get:S.prototype.rz,set:S.prototype.ZB});S.prototype.get_kDF=S.prototype.dz=function(){return Fs(this.hy)};S.prototype.set_kDF=S.prototype.LB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Gs(c,a)};
-Object.defineProperty(S.prototype,"kDF",{get:S.prototype.dz,set:S.prototype.LB});S.prototype.get_kMT=S.prototype.iz=function(){return Hs(this.hy)};S.prototype.set_kMT=S.prototype.QB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Is(c,a)};Object.defineProperty(S.prototype,"kMT",{get:S.prototype.iz,set:S.prototype.QB});S.prototype.get_kCHR=S.prototype.cz=function(){return Js(this.hy)};S.prototype.set_kCHR=S.prototype.KB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ks(c,a)};
-Object.defineProperty(S.prototype,"kCHR",{get:S.prototype.cz,set:S.prototype.KB});S.prototype.get_kKHR=S.prototype.gz=function(){return Ls(this.hy)};S.prototype.set_kKHR=S.prototype.OB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ms(c,a)};Object.defineProperty(S.prototype,"kKHR",{get:S.prototype.gz,set:S.prototype.OB});S.prototype.get_kSHR=S.prototype.kz=function(){return Ns(this.hy)};
-S.prototype.set_kSHR=S.prototype.SB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Os(c,a)};Object.defineProperty(S.prototype,"kSHR",{get:S.prototype.kz,set:S.prototype.SB});S.prototype.get_kAHR=S.prototype.bz=function(){return Ps(this.hy)};S.prototype.set_kAHR=S.prototype.JB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Qs(c,a)};Object.defineProperty(S.prototype,"kAHR",{get:S.prototype.bz,set:S.prototype.JB});S.prototype.get_kSRHR_CL=S.prototype.nz=function(){return Rs(this.hy)};
-S.prototype.set_kSRHR_CL=S.prototype.VB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ss(c,a)};Object.defineProperty(S.prototype,"kSRHR_CL",{get:S.prototype.nz,set:S.prototype.VB});S.prototype.get_kSKHR_CL=S.prototype.lz=function(){return Ts(this.hy)};S.prototype.set_kSKHR_CL=S.prototype.TB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Us(c,a)};Object.defineProperty(S.prototype,"kSKHR_CL",{get:S.prototype.lz,set:S.prototype.TB});S.prototype.get_kSSHR_CL=S.prototype.pz=function(){return Vs(this.hy)};
-S.prototype.set_kSSHR_CL=S.prototype.XB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ws(c,a)};Object.defineProperty(S.prototype,"kSSHR_CL",{get:S.prototype.pz,set:S.prototype.XB});S.prototype.get_kSR_SPLT_CL=S.prototype.oz=function(){return Xs(this.hy)};S.prototype.set_kSR_SPLT_CL=S.prototype.WB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ys(c,a)};Object.defineProperty(S.prototype,"kSR_SPLT_CL",{get:S.prototype.oz,set:S.prototype.WB});
-S.prototype.get_kSK_SPLT_CL=S.prototype.mz=function(){return Zs(this.hy)};S.prototype.set_kSK_SPLT_CL=S.prototype.UB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);$s(c,a)};Object.defineProperty(S.prototype,"kSK_SPLT_CL",{get:S.prototype.mz,set:S.prototype.UB});S.prototype.get_kSS_SPLT_CL=S.prototype.qz=function(){return at(this.hy)};S.prototype.set_kSS_SPLT_CL=S.prototype.YB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);bt(c,a)};
-Object.defineProperty(S.prototype,"kSS_SPLT_CL",{get:S.prototype.qz,set:S.prototype.YB});S.prototype.get_maxvolume=S.prototype.yB=function(){return ct(this.hy)};S.prototype.set_maxvolume=S.prototype.eE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);dt(c,a)};Object.defineProperty(S.prototype,"maxvolume",{get:S.prototype.yB,set:S.prototype.eE});S.prototype.get_timescale=S.prototype.AB=function(){return et(this.hy)};
-S.prototype.set_timescale=S.prototype.gE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ft(c,a)};Object.defineProperty(S.prototype,"timescale",{get:S.prototype.AB,set:S.prototype.gE});S.prototype.get_viterations=S.prototype.BB=function(){return gt(this.hy)};S.prototype.set_viterations=S.prototype.hE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ht(c,a)};Object.defineProperty(S.prototype,"viterations",{get:S.prototype.BB,set:S.prototype.hE});
-S.prototype.get_piterations=S.prototype.zB=function(){return it(this.hy)};S.prototype.set_piterations=S.prototype.fE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);jt(c,a)};Object.defineProperty(S.prototype,"piterations",{get:S.prototype.zB,set:S.prototype.fE});S.prototype.get_diterations=S.prototype.az=function(){return kt(this.hy)};S.prototype.set_diterations=S.prototype.IB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);lt(c,a)};
-Object.defineProperty(S.prototype,"diterations",{get:S.prototype.az,set:S.prototype.IB});S.prototype.get_citerations=S.prototype.Zy=function(){return mt(this.hy)};S.prototype.set_citerations=S.prototype.GB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);nt(c,a)};Object.defineProperty(S.prototype,"citerations",{get:S.prototype.Zy,set:S.prototype.GB});S.prototype.get_collisions=S.prototype.$y=function(){return ot(this.hy)};
-S.prototype.set_collisions=S.prototype.HB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);pt(c,a)};Object.defineProperty(S.prototype,"collisions",{get:S.prototype.$y,set:S.prototype.HB});S.prototype.__destroy__=function(){qt(this.hy)};function Node(){throw"cannot construct a Node, no constructor in IDL";}Node.prototype=Object.create(f.prototype);Node.prototype.constructor=Node;Node.prototype.iy=Node;Node.jy={};b.Node=Node;
-Node.prototype.get_m_x=Node.prototype.xB=function(){return k(rt(this.hy),p)};Node.prototype.set_m_x=Node.prototype.dE=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);st(c,a)};Object.defineProperty(Node.prototype,"m_x",{get:Node.prototype.xB,set:Node.prototype.dE});Node.prototype.get_m_q=Node.prototype.OA=function(){return k(tt(this.hy),p)};Node.prototype.set_m_q=Node.prototype.uD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ut(c,a)};
-Object.defineProperty(Node.prototype,"m_q",{get:Node.prototype.OA,set:Node.prototype.uD});Node.prototype.get_m_v=Node.prototype.pB=function(){return k(vt(this.hy),p)};Node.prototype.set_m_v=Node.prototype.WD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);wt(c,a)};Object.defineProperty(Node.prototype,"m_v",{get:Node.prototype.pB,set:Node.prototype.WD});Node.prototype.get_m_f=Node.prototype.bA=function(){return k(xt(this.hy),p)};
-Node.prototype.set_m_f=Node.prototype.IC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);yt(c,a)};Object.defineProperty(Node.prototype,"m_f",{get:Node.prototype.bA,set:Node.prototype.IC});Node.prototype.get_m_n=Node.prototype.Hy=function(){return k(zt(this.hy),p)};Node.prototype.set_m_n=Node.prototype.Qy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);At(c,a)};Object.defineProperty(Node.prototype,"m_n",{get:Node.prototype.Hy,set:Node.prototype.Qy});
-Node.prototype.get_m_im=Node.prototype.pA=function(){return Bt(this.hy)};Node.prototype.set_m_im=Node.prototype.WC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ct(c,a)};Object.defineProperty(Node.prototype,"m_im",{get:Node.prototype.pA,set:Node.prototype.WC});Node.prototype.get_m_area=Node.prototype.Dz=function(){return Dt(this.hy)};Node.prototype.set_m_area=Node.prototype.jC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Et(c,a)};
-Object.defineProperty(Node.prototype,"m_area",{get:Node.prototype.Dz,set:Node.prototype.jC});Node.prototype.__destroy__=function(){Ft(this.hy)};function WB(){this.hy=Gt();h(WB)[this.hy]=this}WB.prototype=Object.create(f.prototype);WB.prototype.constructor=WB;WB.prototype.iy=WB;WB.jy={};b.btGhostPairCallback=WB;WB.prototype.__destroy__=function(){Ht(this.hy)};function XB(){throw"cannot construct a btOverlappingPairCallback, no constructor in IDL";}XB.prototype=Object.create(f.prototype);
-XB.prototype.constructor=XB;XB.prototype.iy=XB;XB.jy={};b.btOverlappingPairCallback=XB;XB.prototype.__destroy__=function(){It(this.hy)};function T(a,c,d,e){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);this.hy=void 0===e?Jt(a,c,d):Kt(a,c,d,e);h(T)[this.hy]=this}T.prototype=Object.create(ZA.prototype);T.prototype.constructor=T;T.prototype.iy=T;T.jy={};b.btKinematicCharacterController=T;
-T.prototype.setUpAxis=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Lt(c,a)};T.prototype.setWalkDirection=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Mt(c,a)};T.prototype.setVelocityForTimeInterval=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Nt(d,a,c)};T.prototype.warp=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ot(c,a)};T.prototype.preStep=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pt(c,a)};
-T.prototype.playerStep=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Qt(d,a,c)};T.prototype.setFallSpeed=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Rt(c,a)};T.prototype.setJumpSpeed=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);St(c,a)};T.prototype.setMaxJumpHeight=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Tt(c,a)};T.prototype.canJump=function(){return!!Ut(this.hy)};T.prototype.jump=function(){Vt(this.hy)};
-T.prototype.setGravity=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wt(c,a)};T.prototype.getGravity=function(){return Xt(this.hy)};T.prototype.setMaxSlope=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Yt(c,a)};T.prototype.getMaxSlope=function(){return Zt(this.hy)};T.prototype.getGhostObject=function(){return k($t(this.hy),U)};T.prototype.setUseGhostSweepTest=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);au(c,a)};T.prototype.onGround=function(){return!!bu(this.hy)};
-T.prototype.setUpInterpolate=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);cu(c,a)};T.prototype.updateAction=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);du(d,a,c)};T.prototype.__destroy__=function(){eu(this.hy)};function YB(){throw"cannot construct a btSoftBodyArray, no constructor in IDL";}YB.prototype=Object.create(f.prototype);YB.prototype.constructor=YB;YB.prototype.iy=YB;YB.jy={};b.btSoftBodyArray=YB;
-YB.prototype.size=YB.prototype.size=function(){return fu(this.hy)};YB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(gu(c,a),R)};YB.prototype.__destroy__=function(){hu(this.hy)};function PB(){throw"cannot construct a btFaceArray, no constructor in IDL";}PB.prototype=Object.create(f.prototype);PB.prototype.constructor=PB;PB.prototype.iy=PB;PB.jy={};b.btFaceArray=PB;PB.prototype.size=PB.prototype.size=function(){return iu(this.hy)};
-PB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(ju(c,a),ZB)};PB.prototype.__destroy__=function(){ku(this.hy)};function $B(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=lu(a,c);h($B)[this.hy]=this}$B.prototype=Object.create(UA.prototype);$B.prototype.constructor=$B;$B.prototype.iy=$B;$B.jy={};b.btStaticPlaneShape=$B;$B.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);mu(c,a)};
-$B.prototype.getLocalScaling=function(){return k(nu(this.hy),p)};$B.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);ou(d,a,c)};$B.prototype.__destroy__=function(){pu(this.hy)};function PA(){throw"cannot construct a btOverlappingPairCache, no constructor in IDL";}PA.prototype=Object.create(f.prototype);PA.prototype.constructor=PA;PA.prototype.iy=PA;PA.jy={};b.btOverlappingPairCache=PA;
-PA.prototype.setInternalGhostPairCallback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);qu(c,a)};PA.prototype.getNumOverlappingPairs=function(){return ru(this.hy)};PA.prototype.__destroy__=function(){su(this.hy)};function vB(){throw"cannot construct a btIndexedMesh, no constructor in IDL";}vB.prototype=Object.create(f.prototype);vB.prototype.constructor=vB;vB.prototype.iy=vB;vB.jy={};b.btIndexedMesh=vB;vB.prototype.get_m_numTriangles=vB.prototype.KA=function(){return tu(this.hy)};
-vB.prototype.set_m_numTriangles=vB.prototype.qD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);uu(c,a)};Object.defineProperty(vB.prototype,"m_numTriangles",{get:vB.prototype.KA,set:vB.prototype.qD});vB.prototype.__destroy__=function(){vu(this.hy)};function V(a,c,d,e,g){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);this.hy=wu(a,c,d,e,g);h(V)[this.hy]=this}V.prototype=Object.create(x.prototype);
-V.prototype.constructor=V;V.prototype.iy=V;V.jy={};b.btSoftRigidDynamicsWorld=V;V.prototype.addSoftBody=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);xu(e,a,c,d)};V.prototype.removeSoftBody=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);yu(c,a)};V.prototype.removeCollisionObject=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);zu(c,a)};V.prototype.getWorldInfo=function(){return k(Au(this.hy),J)};
-V.prototype.getSoftBodyArray=function(){return k(Bu(this.hy),YB)};V.prototype.getDispatcher=function(){return k(Cu(this.hy),OA)};V.prototype.rayTest=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Du(e,a,c,d)};V.prototype.getPairCache=function(){return k(Eu(this.hy),PA)};V.prototype.getDispatchInfo=function(){return k(Fu(this.hy),l)};
-V.prototype.addCollisionObject=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);void 0===c?Gu(e,a):void 0===d?Hu(e,a,c):Iu(e,a,c,d)};V.prototype.getBroadphase=function(){return k(Ju(this.hy),QA)};
-V.prototype.convexSweepTest=function(a,c,d,e,g){var n=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);Ku(n,a,c,d,e,g)};V.prototype.contactPairTest=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Lu(e,a,c,d)};
-V.prototype.contactTest=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Mu(d,a,c)};V.prototype.updateSingleAabb=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Nu(c,a)};V.prototype.setDebugDrawer=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ou(c,a)};V.prototype.getDebugDrawer=function(){return k(Pu(this.hy),RA)};V.prototype.debugDrawWorld=function(){Qu(this.hy)};
-V.prototype.debugDrawObject=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Ru(e,a,c,d)};V.prototype.setGravity=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Su(c,a)};V.prototype.getGravity=function(){return k(Tu(this.hy),p)};
-V.prototype.addRigidBody=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);void 0===c?Uu(e,a):void 0===d?_emscripten_bind_btSoftRigidDynamicsWorld_addRigidBody_2(e,a,c):Vu(e,a,c,d)};V.prototype.removeRigidBody=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wu(c,a)};
-V.prototype.addConstraint=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);void 0===c?Xu(d,a):Yu(d,a,c)};V.prototype.removeConstraint=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Zu(c,a)};V.prototype.stepSimulation=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);return void 0===c?$u(e,a):void 0===d?av(e,a,c):bv(e,a,c,d)};
-V.prototype.setContactAddedCallback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);cv(c,a)};V.prototype.setContactProcessedCallback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);dv(c,a)};V.prototype.setContactDestroyedCallback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ev(c,a)};V.prototype.addAction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);fv(c,a)};V.prototype.removeAction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);gv(c,a)};
-V.prototype.getSolverInfo=function(){return k(hv(this.hy),v)};V.prototype.setInternalTickCallback=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);void 0===c?iv(e,a):void 0===d?jv(e,a,c):kv(e,a,c,d)};V.prototype.__destroy__=function(){lv(this.hy)};
-function aC(a,c,d,e){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);this.hy=mv(a,c,d,e);h(aC)[this.hy]=this}aC.prototype=Object.create(TA.prototype);aC.prototype.constructor=aC;aC.prototype.iy=aC;aC.jy={};b.btFixedConstraint=aC;aC.prototype.enableFeedback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);nv(c,a)};aC.prototype.getBreakingImpulseThreshold=function(){return ov(this.hy)};
-aC.prototype.setBreakingImpulseThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);pv(c,a)};aC.prototype.getParam=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return qv(d,a,c)};aC.prototype.setParam=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);rv(e,a,c,d)};aC.prototype.__destroy__=function(){sv(this.hy)};
-function r(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=void 0===a?tv():void 0===c?_emscripten_bind_btTransform_btTransform_1(a):uv(a,c);h(r)[this.hy]=this}r.prototype=Object.create(f.prototype);r.prototype.constructor=r;r.prototype.iy=r;r.jy={};b.btTransform=r;r.prototype.setIdentity=function(){vv(this.hy)};r.prototype.setOrigin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);wv(c,a)};
-r.prototype.setRotation=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);xv(c,a)};r.prototype.getOrigin=function(){return k(yv(this.hy),p)};r.prototype.getRotation=function(){return k(zv(this.hy),W)};r.prototype.getBasis=function(){return k(Av(this.hy),jB)};r.prototype.setFromOpenGLMatrix=function(a){var c=this.hy;IA();"object"==typeof a&&(a=MA(a));Bv(c,a)};r.prototype.inverse=r.prototype.inverse=function(){return k(Cv(this.hy),r)};
-r.prototype.op_mul=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Dv(c,a),r)};r.prototype.__destroy__=function(){Ev(this.hy)};function X(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=Fv(a,c);h(X)[this.hy]=this}X.prototype=Object.create(z.prototype);X.prototype.constructor=X;X.prototype.iy=X;X.jy={};b.ClosestRayResultCallback=X;X.prototype.hasHit=function(){return!!Gv(this.hy)};
-X.prototype.get_m_rayFromWorld=X.prototype.Iy=function(){return k(Hv(this.hy),p)};X.prototype.set_m_rayFromWorld=X.prototype.Ry=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Iv(c,a)};Object.defineProperty(X.prototype,"m_rayFromWorld",{get:X.prototype.Iy,set:X.prototype.Ry});X.prototype.get_m_rayToWorld=X.prototype.Jy=function(){return k(Jv(this.hy),p)};X.prototype.set_m_rayToWorld=X.prototype.Sy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Kv(c,a)};
-Object.defineProperty(X.prototype,"m_rayToWorld",{get:X.prototype.Jy,set:X.prototype.Sy});X.prototype.get_m_hitNormalWorld=X.prototype.sy=function(){return k(Lv(this.hy),p)};X.prototype.set_m_hitNormalWorld=X.prototype.zy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Mv(c,a)};Object.defineProperty(X.prototype,"m_hitNormalWorld",{get:X.prototype.sy,set:X.prototype.zy});X.prototype.get_m_hitPointWorld=X.prototype.ty=function(){return k(Nv(this.hy),p)};
-X.prototype.set_m_hitPointWorld=X.prototype.Ay=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ov(c,a)};Object.defineProperty(X.prototype,"m_hitPointWorld",{get:X.prototype.ty,set:X.prototype.Ay});X.prototype.get_m_collisionFilterGroup=X.prototype.ky=function(){return Pv(this.hy)};X.prototype.set_m_collisionFilterGroup=X.prototype.my=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Qv(c,a)};Object.defineProperty(X.prototype,"m_collisionFilterGroup",{get:X.prototype.ky,set:X.prototype.my});
-X.prototype.get_m_collisionFilterMask=X.prototype.ly=function(){return Rv(this.hy)};X.prototype.set_m_collisionFilterMask=X.prototype.ny=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Sv(c,a)};Object.defineProperty(X.prototype,"m_collisionFilterMask",{get:X.prototype.ly,set:X.prototype.ny});X.prototype.get_m_closestHitFraction=X.prototype.oy=function(){return Tv(this.hy)};
-X.prototype.set_m_closestHitFraction=X.prototype.py=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Uv(c,a)};Object.defineProperty(X.prototype,"m_closestHitFraction",{get:X.prototype.oy,set:X.prototype.py});X.prototype.get_m_collisionObject=X.prototype.qy=function(){return k(Vv(this.hy),q)};X.prototype.set_m_collisionObject=X.prototype.xy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Wv(c,a)};Object.defineProperty(X.prototype,"m_collisionObject",{get:X.prototype.qy,set:X.prototype.xy});
-X.prototype.__destroy__=function(){Xv(this.hy)};function bC(a){a&&"object"===typeof a&&(a=a.hy);this.hy=void 0===a?Yv():Zv(a);h(bC)[this.hy]=this}bC.prototype=Object.create(WA.prototype);bC.prototype.constructor=bC;bC.prototype.iy=bC;bC.jy={};b.btSoftBodyRigidBodyCollisionConfiguration=bC;bC.prototype.__destroy__=function(){$v(this.hy)};function cC(){this.hy=aw();h(cC)[this.hy]=this}cC.prototype=Object.create(hB.prototype);cC.prototype.constructor=cC;cC.prototype.iy=cC;cC.jy={};
-b.ConcreteContactResultCallback=cC;cC.prototype.addSingleResult=function(a,c,d,e,g,n,F){var aa=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);n&&"object"===typeof n&&(n=n.hy);F&&"object"===typeof F&&(F=F.hy);return bw(aa,a,c,d,e,g,n,F)};cC.prototype.__destroy__=function(){cw(this.hy)};
-function dC(a,c,d){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);this.hy=void 0===d?dw(a,c):ew(a,c,d);h(dC)[this.hy]=this}dC.prototype=Object.create(XA.prototype);dC.prototype.constructor=dC;dC.prototype.iy=dC;dC.jy={};b.btBvhTriangleMeshShape=dC;dC.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);fw(c,a)};dC.prototype.getLocalScaling=function(){return k(gw(this.hy),p)};
-dC.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);hw(d,a,c)};dC.prototype.__destroy__=function(){iw(this.hy)};function oB(){throw"cannot construct a btConstCollisionObjectArray, no constructor in IDL";}oB.prototype=Object.create(f.prototype);oB.prototype.constructor=oB;oB.prototype.iy=oB;oB.jy={};b.btConstCollisionObjectArray=oB;oB.prototype.size=oB.prototype.size=function(){return jw(this.hy)};
-oB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(kw(c,a),q)};oB.prototype.__destroy__=function(){lw(this.hy)};function eC(a,c,d,e,g){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);this.hy=void 0===e?mw(a,c,d):void 0===g?_emscripten_bind_btSliderConstraint_btSliderConstraint_4(a,c,d,e):nw(a,c,d,e,g);h(eC)[this.hy]=this}eC.prototype=Object.create(TA.prototype);
-eC.prototype.constructor=eC;eC.prototype.iy=eC;eC.jy={};b.btSliderConstraint=eC;eC.prototype.setLowerLinLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ow(c,a)};eC.prototype.setUpperLinLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);pw(c,a)};eC.prototype.setLowerAngLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);qw(c,a)};eC.prototype.setUpperAngLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);rw(c,a)};
-eC.prototype.enableFeedback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);sw(c,a)};eC.prototype.getBreakingImpulseThreshold=function(){return tw(this.hy)};eC.prototype.setBreakingImpulseThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);uw(c,a)};eC.prototype.getParam=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return vw(d,a,c)};
-eC.prototype.setParam=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);ww(e,a,c,d)};eC.prototype.__destroy__=function(){xw(this.hy)};function U(){this.hy=yw();h(U)[this.hy]=this}U.prototype=Object.create(w.prototype);U.prototype.constructor=U;U.prototype.iy=U;U.jy={};b.btPairCachingGhostObject=U;
-U.prototype.setAnisotropicFriction=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);zw(d,a,c)};U.prototype.getCollisionShape=function(){return k(Aw(this.hy),m)};U.prototype.setContactProcessingThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Bw(c,a)};U.prototype.setActivationState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Cw(c,a)};
-U.prototype.forceActivationState=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Dw(c,a)};U.prototype.activate=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);void 0===a?Ew(c):Fw(c,a)};U.prototype.isActive=function(){return!!Gw(this.hy)};U.prototype.isKinematicObject=function(){return!!Hw(this.hy)};U.prototype.isStaticObject=function(){return!!Iw(this.hy)};U.prototype.isStaticOrKinematicObject=function(){return!!Jw(this.hy)};U.prototype.getRestitution=function(){return Kw(this.hy)};
-U.prototype.getFriction=function(){return Lw(this.hy)};U.prototype.getRollingFriction=function(){return Mw(this.hy)};U.prototype.setRestitution=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Nw(c,a)};U.prototype.setFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ow(c,a)};U.prototype.setRollingFriction=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pw(c,a)};U.prototype.getWorldTransform=function(){return k(Qw(this.hy),r)};U.prototype.getCollisionFlags=function(){return Rw(this.hy)};
-U.prototype.setCollisionFlags=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Sw(c,a)};U.prototype.setWorldTransform=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Tw(c,a)};U.prototype.setCollisionShape=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Uw(c,a)};U.prototype.setCcdMotionThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Vw(c,a)};U.prototype.setCcdSweptSphereRadius=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ww(c,a)};
-U.prototype.getUserIndex=function(){return Xw(this.hy)};U.prototype.setUserIndex=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Yw(c,a)};U.prototype.getUserPointer=function(){return k(Zw(this.hy),SA)};U.prototype.setUserPointer=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);$w(c,a)};U.prototype.getBroadphaseHandle=function(){return k(ax(this.hy),t)};U.prototype.getNumOverlappingObjects=function(){return bx(this.hy)};
-U.prototype.getOverlappingObject=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(cx(c,a),q)};U.prototype.__destroy__=function(){dx(this.hy)};function D(){throw"cannot construct a btManifoldPoint, no constructor in IDL";}D.prototype=Object.create(f.prototype);D.prototype.constructor=D;D.prototype.iy=D;D.jy={};b.btManifoldPoint=D;D.prototype.getPositionWorldOnA=function(){return k(ex(this.hy),p)};D.prototype.getPositionWorldOnB=function(){return k(fx(this.hy),p)};
-D.prototype.getAppliedImpulse=function(){return gx(this.hy)};D.prototype.getDistance=function(){return hx(this.hy)};D.prototype.get_m_localPointA=D.prototype.AA=function(){return k(ix(this.hy),p)};D.prototype.set_m_localPointA=D.prototype.gD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);jx(c,a)};Object.defineProperty(D.prototype,"m_localPointA",{get:D.prototype.AA,set:D.prototype.gD});D.prototype.get_m_localPointB=D.prototype.BA=function(){return k(kx(this.hy),p)};
-D.prototype.set_m_localPointB=D.prototype.hD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);lx(c,a)};Object.defineProperty(D.prototype,"m_localPointB",{get:D.prototype.BA,set:D.prototype.hD});D.prototype.get_m_positionWorldOnB=D.prototype.NA=function(){return k(mx(this.hy),p)};D.prototype.set_m_positionWorldOnB=D.prototype.tD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);nx(c,a)};Object.defineProperty(D.prototype,"m_positionWorldOnB",{get:D.prototype.NA,set:D.prototype.tD});
-D.prototype.get_m_positionWorldOnA=D.prototype.MA=function(){return k(ox(this.hy),p)};D.prototype.set_m_positionWorldOnA=D.prototype.sD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);px(c,a)};Object.defineProperty(D.prototype,"m_positionWorldOnA",{get:D.prototype.MA,set:D.prototype.sD});D.prototype.get_m_normalWorldOnB=D.prototype.IA=function(){return k(qx(this.hy),p)};D.prototype.set_m_normalWorldOnB=D.prototype.oD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);rx(c,a)};
-Object.defineProperty(D.prototype,"m_normalWorldOnB",{get:D.prototype.IA,set:D.prototype.oD});D.prototype.get_m_userPersistentData=D.prototype.oB=function(){return sx(this.hy)};D.prototype.set_m_userPersistentData=D.prototype.VD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);tx(c,a)};Object.defineProperty(D.prototype,"m_userPersistentData",{get:D.prototype.oB,set:D.prototype.VD});D.prototype.__destroy__=function(){ux(this.hy)};
-function fC(a,c,d,e){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);this.hy=void 0===d?vx(a,c):void 0===e?_emscripten_bind_btPoint2PointConstraint_btPoint2PointConstraint_3(a,c,d):wx(a,c,d,e);h(fC)[this.hy]=this}fC.prototype=Object.create(TA.prototype);fC.prototype.constructor=fC;fC.prototype.iy=fC;fC.jy={};b.btPoint2PointConstraint=fC;
-fC.prototype.setPivotA=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);xx(c,a)};fC.prototype.setPivotB=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);yx(c,a)};fC.prototype.getPivotInA=function(){return k(zx(this.hy),p)};fC.prototype.getPivotInB=function(){return k(Ax(this.hy),p)};fC.prototype.enableFeedback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Bx(c,a)};fC.prototype.getBreakingImpulseThreshold=function(){return Cx(this.hy)};
-fC.prototype.setBreakingImpulseThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Dx(c,a)};fC.prototype.getParam=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return Ex(d,a,c)};fC.prototype.setParam=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Fx(e,a,c,d)};fC.prototype.get_m_setting=fC.prototype.VA=function(){return k(Gx(this.hy),H)};
-fC.prototype.set_m_setting=fC.prototype.BD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Hx(c,a)};Object.defineProperty(fC.prototype,"m_setting",{get:fC.prototype.VA,set:fC.prototype.BD});fC.prototype.__destroy__=function(){Ix(this.hy)};function gC(){this.hy=Jx();h(gC)[this.hy]=this}gC.prototype=Object.create(f.prototype);gC.prototype.constructor=gC;gC.prototype.iy=gC;gC.jy={};b.btSoftBodyHelpers=gC;
-gC.prototype.CreateRope=function(a,c,d,e,g){var n=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);return k(Kx(n,a,c,d,e,g),R)};
-gC.prototype.CreatePatch=function(a,c,d,e,g,n,F,aa,ta){var Rb=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);n&&"object"===typeof n&&(n=n.hy);F&&"object"===typeof F&&(F=F.hy);aa&&"object"===typeof aa&&(aa=aa.hy);ta&&"object"===typeof ta&&(ta=ta.hy);return k(Lx(Rb,a,c,d,e,g,n,F,aa,ta),R)};
-gC.prototype.CreatePatchUV=function(a,c,d,e,g,n,F,aa,ta,Rb){var nC=this.hy;IA();a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);n&&"object"===typeof n&&(n=n.hy);F&&"object"===typeof F&&(F=F.hy);aa&&"object"===typeof aa&&(aa=aa.hy);ta&&"object"===typeof ta&&(ta=ta.hy);"object"==typeof Rb&&(Rb=MA(Rb));return k(Mx(nC,a,c,d,e,g,n,F,aa,ta,Rb),R)};
-gC.prototype.CreateEllipsoid=function(a,c,d,e){var g=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);return k(Nx(g,a,c,d,e),R)};
-gC.prototype.CreateFromTriMesh=function(a,c,d,e,g){var n=this.hy;IA();a&&"object"===typeof a&&(a=a.hy);"object"==typeof c&&(c=MA(c));if("object"==typeof d&&"object"===typeof d){var F=JA(d,Aa);KA(d,Aa,F);d=F}e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);return k(Ox(n,a,c,d,e,g),R)};
-gC.prototype.CreateFromConvexHull=function(a,c,d,e){var g=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);return k(Px(g,a,c,d,e),R)};gC.prototype.__destroy__=function(){Qx(this.hy)};function t(){throw"cannot construct a btBroadphaseProxy, no constructor in IDL";}t.prototype=Object.create(f.prototype);t.prototype.constructor=t;t.prototype.iy=t;t.jy={};b.btBroadphaseProxy=t;
-t.prototype.get_m_collisionFilterGroup=t.prototype.ky=function(){return Rx(this.hy)};t.prototype.set_m_collisionFilterGroup=t.prototype.my=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Sx(c,a)};Object.defineProperty(t.prototype,"m_collisionFilterGroup",{get:t.prototype.ky,set:t.prototype.my});t.prototype.get_m_collisionFilterMask=t.prototype.ly=function(){return Tx(this.hy)};
-t.prototype.set_m_collisionFilterMask=t.prototype.ny=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ux(c,a)};Object.defineProperty(t.prototype,"m_collisionFilterMask",{get:t.prototype.ly,set:t.prototype.ny});t.prototype.__destroy__=function(){Vx(this.hy)};function TB(){throw"cannot construct a tNodeArray, no constructor in IDL";}TB.prototype=Object.create(f.prototype);TB.prototype.constructor=TB;TB.prototype.iy=TB;TB.jy={};b.tNodeArray=TB;TB.prototype.size=TB.prototype.size=function(){return Wx(this.hy)};
-TB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Xx(c,a),Node)};TB.prototype.__destroy__=function(){Yx(this.hy)};function hC(a){a&&"object"===typeof a&&(a=a.hy);this.hy=Zx(a);h(hC)[this.hy]=this}hC.prototype=Object.create(m.prototype);hC.prototype.constructor=hC;hC.prototype.iy=hC;hC.jy={};b.btBoxShape=hC;hC.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);$x(c,a)};hC.prototype.getMargin=function(){return ay(this.hy)};
-hC.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);by(c,a)};hC.prototype.getLocalScaling=function(){return k(cy(this.hy),p)};hC.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);dy(d,a,c)};hC.prototype.__destroy__=function(){ey(this.hy)};function ZB(){throw"cannot construct a btFace, no constructor in IDL";}ZB.prototype=Object.create(f.prototype);ZB.prototype.constructor=ZB;
-ZB.prototype.iy=ZB;ZB.jy={};b.btFace=ZB;ZB.prototype.get_m_indices=ZB.prototype.rA=function(){return k(fy(this.hy),VB)};ZB.prototype.set_m_indices=ZB.prototype.YC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);gy(c,a)};Object.defineProperty(ZB.prototype,"m_indices",{get:ZB.prototype.rA,set:ZB.prototype.YC});ZB.prototype.get_m_plane=ZB.prototype.LA=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return hy(c,a)};
-ZB.prototype.set_m_plane=ZB.prototype.rD=function(a,c){var d=this.hy;IA();a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);iy(d,a,c)};Object.defineProperty(ZB.prototype,"m_plane",{get:ZB.prototype.LA,set:ZB.prototype.rD});ZB.prototype.__destroy__=function(){jy(this.hy)};function iC(){this.hy=ky();h(iC)[this.hy]=this}iC.prototype=Object.create(RA.prototype);iC.prototype.constructor=iC;iC.prototype.iy=iC;iC.jy={};b.DebugDrawer=iC;
-iC.prototype.drawLine=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);ly(e,a,c,d)};iC.prototype.drawContactPoint=function(a,c,d,e,g){var n=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);my(n,a,c,d,e,g)};
-iC.prototype.reportErrorWarning=function(a){var c=this.hy;IA();a=a&&"object"===typeof a?a.hy:LA(a);ny(c,a)};iC.prototype.draw3dText=function(a,c){var d=this.hy;IA();a&&"object"===typeof a&&(a=a.hy);c=c&&"object"===typeof c?c.hy:LA(c);oy(d,a,c)};iC.prototype.setDebugMode=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);py(c,a)};iC.prototype.getDebugMode=function(){return qy(this.hy)};iC.prototype.__destroy__=function(){ry(this.hy)};
-function jC(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=sy(a,c);h(jC)[this.hy]=this}jC.prototype=Object.create(VA.prototype);jC.prototype.constructor=jC;jC.prototype.iy=jC;jC.jy={};b.btCapsuleShapeX=jC;jC.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);ty(c,a)};jC.prototype.getMargin=function(){return uy(this.hy)};jC.prototype.getUpAxis=function(){return vy(this.hy)};jC.prototype.getRadius=function(){return wy(this.hy)};
-jC.prototype.getHalfHeight=function(){return xy(this.hy)};jC.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);yy(c,a)};jC.prototype.getLocalScaling=function(){return k(zy(this.hy),p)};jC.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Ay(d,a,c)};jC.prototype.__destroy__=function(){By(this.hy)};
-function W(a,c,d,e){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);this.hy=Cy(a,c,d,e);h(W)[this.hy]=this}W.prototype=Object.create(aB.prototype);W.prototype.constructor=W;W.prototype.iy=W;W.jy={};b.btQuaternion=W;W.prototype.setValue=function(a,c,d,e){var g=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);Dy(g,a,c,d,e)};
-W.prototype.setEulerZYX=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Ey(e,a,c,d)};W.prototype.setRotation=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Fy(d,a,c)};W.prototype.normalize=W.prototype.normalize=function(){Gy(this.hy)};W.prototype.length2=function(){return Hy(this.hy)};W.prototype.length=W.prototype.length=function(){return Iy(this.hy)};
-W.prototype.dot=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return Jy(c,a)};W.prototype.normalized=function(){return k(Ky(this.hy),W)};W.prototype.getAxis=function(){return k(Ly(this.hy),p)};W.prototype.inverse=W.prototype.inverse=function(){return k(My(this.hy),W)};W.prototype.getAngle=function(){return Ny(this.hy)};W.prototype.getAngleShortestPath=function(){return Oy(this.hy)};
-W.prototype.angle=W.prototype.angle=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return Py(c,a)};W.prototype.angleShortestPath=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return Qy(c,a)};W.prototype.op_add=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Ry(c,a),W)};W.prototype.op_sub=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Sy(c,a),W)};
-W.prototype.op_mul=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Ty(c,a),W)};W.prototype.op_mulq=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Uy(c,a),W)};W.prototype.op_div=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Vy(c,a),W)};W.prototype.x=W.prototype.x=function(){return Wy(this.hy)};W.prototype.y=W.prototype.y=function(){return Xy(this.hy)};W.prototype.z=W.prototype.z=function(){return Yy(this.hy)};W.prototype.w=function(){return Zy(this.hy)};
-W.prototype.setX=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);$y(c,a)};W.prototype.setY=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);az(c,a)};W.prototype.setZ=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);bz(c,a)};W.prototype.setW=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);cz(c,a)};W.prototype.__destroy__=function(){dz(this.hy)};
-function kC(a,c){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);this.hy=ez(a,c);h(kC)[this.hy]=this}kC.prototype=Object.create(VA.prototype);kC.prototype.constructor=kC;kC.prototype.iy=kC;kC.jy={};b.btCapsuleShapeZ=kC;kC.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);fz(c,a)};kC.prototype.getMargin=function(){return gz(this.hy)};kC.prototype.getUpAxis=function(){return hz(this.hy)};kC.prototype.getRadius=function(){return iz(this.hy)};
-kC.prototype.getHalfHeight=function(){return jz(this.hy)};kC.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);kz(c,a)};kC.prototype.getLocalScaling=function(){return k(lz(this.hy),p)};kC.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);mz(d,a,c)};kC.prototype.__destroy__=function(){nz(this.hy)};function v(){throw"cannot construct a btContactSolverInfo, no constructor in IDL";}
-v.prototype=Object.create(f.prototype);v.prototype.constructor=v;v.prototype.iy=v;v.jy={};b.btContactSolverInfo=v;v.prototype.get_m_splitImpulse=v.prototype.YA=function(){return!!oz(this.hy)};v.prototype.set_m_splitImpulse=v.prototype.ED=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);pz(c,a)};Object.defineProperty(v.prototype,"m_splitImpulse",{get:v.prototype.YA,set:v.prototype.ED});v.prototype.get_m_splitImpulsePenetrationThreshold=v.prototype.ZA=function(){return qz(this.hy)};
-v.prototype.set_m_splitImpulsePenetrationThreshold=v.prototype.FD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);rz(c,a)};Object.defineProperty(v.prototype,"m_splitImpulsePenetrationThreshold",{get:v.prototype.ZA,set:v.prototype.FD});v.prototype.get_m_numIterations=v.prototype.JA=function(){return sz(this.hy)};v.prototype.set_m_numIterations=v.prototype.pD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);tz(c,a)};
-Object.defineProperty(v.prototype,"m_numIterations",{get:v.prototype.JA,set:v.prototype.pD});v.prototype.__destroy__=function(){uz(this.hy)};function lC(a,c,d,e,g){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);this.hy=void 0===e?vz(a,c,d):void 0===g?_emscripten_bind_btGeneric6DofSpringConstraint_btGeneric6DofSpringConstraint_4(a,c,d,e):wz(a,c,d,e,g);h(lC)[this.hy]=this}
-lC.prototype=Object.create(eB.prototype);lC.prototype.constructor=lC;lC.prototype.iy=lC;lC.jy={};b.btGeneric6DofSpringConstraint=lC;lC.prototype.enableSpring=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);xz(d,a,c)};lC.prototype.setStiffness=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);yz(d,a,c)};
-lC.prototype.setDamping=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);zz(d,a,c)};lC.prototype.setEquilibriumPoint=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);void 0===a?Az(d):void 0===c?Bz(d,a):Cz(d,a,c)};lC.prototype.setLinearLowerLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Dz(c,a)};
-lC.prototype.setLinearUpperLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Ez(c,a)};lC.prototype.setAngularLowerLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Fz(c,a)};lC.prototype.setAngularUpperLimit=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Gz(c,a)};lC.prototype.getFrameOffsetA=function(){return k(Hz(this.hy),r)};lC.prototype.enableFeedback=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Iz(c,a)};
-lC.prototype.getBreakingImpulseThreshold=function(){return Jz(this.hy)};lC.prototype.setBreakingImpulseThreshold=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Kz(c,a)};lC.prototype.getParam=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);return Lz(d,a,c)};lC.prototype.setParam=function(a,c,d){var e=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);Mz(e,a,c,d)};
-lC.prototype.__destroy__=function(){Nz(this.hy)};function mC(a){a&&"object"===typeof a&&(a=a.hy);this.hy=Oz(a);h(mC)[this.hy]=this}mC.prototype=Object.create(m.prototype);mC.prototype.constructor=mC;mC.prototype.iy=mC;mC.jy={};b.btSphereShape=mC;mC.prototype.setMargin=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Pz(c,a)};mC.prototype.getMargin=function(){return Qz(this.hy)};mC.prototype.setLocalScaling=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Rz(c,a)};
-mC.prototype.getLocalScaling=function(){return k(Sz(this.hy),p)};mC.prototype.calculateLocalInertia=function(a,c){var d=this.hy;a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Tz(d,a,c)};mC.prototype.__destroy__=function(){Uz(this.hy)};function Y(){throw"cannot construct a Face, no constructor in IDL";}Y.prototype=Object.create(f.prototype);Y.prototype.constructor=Y;Y.prototype.iy=Y;Y.jy={};b.Face=Y;
-Y.prototype.get_m_n=Y.prototype.Hy=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(Vz(c,a),Node)};Y.prototype.set_m_n=Y.prototype.Qy=function(a,c){var d=this.hy;IA();a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);Wz(d,a,c)};Object.defineProperty(Y.prototype,"m_n",{get:Y.prototype.Hy,set:Y.prototype.Qy});Y.prototype.get_m_normal=Y.prototype.HA=function(){return k(Xz(this.hy),p)};
-Y.prototype.set_m_normal=Y.prototype.nD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);Yz(c,a)};Object.defineProperty(Y.prototype,"m_normal",{get:Y.prototype.HA,set:Y.prototype.nD});Y.prototype.get_m_ra=Y.prototype.PA=function(){return Zz(this.hy)};Y.prototype.set_m_ra=Y.prototype.vD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);$z(c,a)};Object.defineProperty(Y.prototype,"m_ra",{get:Y.prototype.PA,set:Y.prototype.vD});Y.prototype.__destroy__=function(){aA(this.hy)};
-function UB(){throw"cannot construct a tFaceArray, no constructor in IDL";}UB.prototype=Object.create(f.prototype);UB.prototype.constructor=UB;UB.prototype.iy=UB;UB.jy={};b.tFaceArray=UB;UB.prototype.size=UB.prototype.size=function(){return bA(this.hy)};UB.prototype.at=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);return k(cA(c,a),Y)};UB.prototype.__destroy__=function(){dA(this.hy)};
-function Z(a,c,d,e,g){a&&"object"===typeof a&&(a=a.hy);c&&"object"===typeof c&&(c=c.hy);d&&"object"===typeof d&&(d=d.hy);e&&"object"===typeof e&&(e=e.hy);g&&"object"===typeof g&&(g=g.hy);this.hy=eA(a,c,d,e,g);h(Z)[this.hy]=this}Z.prototype=Object.create(f.prototype);Z.prototype.constructor=Z;Z.prototype.iy=Z;Z.jy={};b.LocalConvexResult=Z;Z.prototype.get_m_hitCollisionObject=Z.prototype.iA=function(){return k(fA(this.hy),q)};
-Z.prototype.set_m_hitCollisionObject=Z.prototype.PC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);gA(c,a)};Object.defineProperty(Z.prototype,"m_hitCollisionObject",{get:Z.prototype.iA,set:Z.prototype.PC});Z.prototype.get_m_localShapeInfo=Z.prototype.CA=function(){return k(hA(this.hy),tB)};Z.prototype.set_m_localShapeInfo=Z.prototype.iD=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);iA(c,a)};Object.defineProperty(Z.prototype,"m_localShapeInfo",{get:Z.prototype.CA,set:Z.prototype.iD});
-Z.prototype.get_m_hitNormalLocal=Z.prototype.mA=function(){return k(jA(this.hy),p)};Z.prototype.set_m_hitNormalLocal=Z.prototype.TC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);kA(c,a)};Object.defineProperty(Z.prototype,"m_hitNormalLocal",{get:Z.prototype.mA,set:Z.prototype.TC});Z.prototype.get_m_hitPointLocal=Z.prototype.oA=function(){return k(lA(this.hy),p)};Z.prototype.set_m_hitPointLocal=Z.prototype.VC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);mA(c,a)};
-Object.defineProperty(Z.prototype,"m_hitPointLocal",{get:Z.prototype.oA,set:Z.prototype.VC});Z.prototype.get_m_hitFraction=Z.prototype.jA=function(){return nA(this.hy)};Z.prototype.set_m_hitFraction=Z.prototype.QC=function(a){var c=this.hy;a&&"object"===typeof a&&(a=a.hy);oA(c,a)};Object.defineProperty(Z.prototype,"m_hitFraction",{get:Z.prototype.jA,set:Z.prototype.QC});Z.prototype.__destroy__=function(){pA(this.hy)};
-(function(){function a(){b.BT_CONSTRAINT_ERP=qA();b.BT_CONSTRAINT_STOP_ERP=rA();b.BT_CONSTRAINT_CFM=sA();b.BT_CONSTRAINT_STOP_CFM=tA();b.PHY_FLOAT=uA();b.PHY_DOUBLE=vA();b.PHY_INTEGER=wA();b.PHY_SHORT=xA();b.PHY_FIXEDPOINT88=yA();b.PHY_UCHAR=zA()}Ka?a():Ia.unshift(a)})();this.Ammo=b;
-
-
-  return Ammo.ready
-}
-);
-})();
-if (typeof exports === 'object' && typeof module === 'object')
-      module.exports = Ammo;
-    else if (typeof define === 'function' && define['amd'])
-      define([], function() { return Ammo; });
-    else if (typeof exports === 'object')
-      exports["Ammo"] = Ammo;
-    

BIN
examples/jsm/libs/ammo.wasm.wasm


File diff suppressed because it is too large
+ 0 - 3
examples/jsm/libs/draco/draco_encoder.js


File diff suppressed because it is too large
+ 0 - 3
examples/jsm/libs/draco/gltf/draco_encoder.js


+ 0 - 14849
examples/jsm/libs/lottie_canvas.module.js

@@ -1,14849 +0,0 @@
-const lottie = {};
-
-if (typeof document !== 'undefined') {
-
-const svgNS = 'http://www.w3.org/2000/svg';
-
-let locationHref = '';
-let _useWebWorker = false;
-
-const initialDefaultFrame = -999999;
-
-const setWebWorker = (flag) => { _useWebWorker = !!flag; };
-const getWebWorker = () => _useWebWorker;
-
-const setLocationHref = (value) => { locationHref = value; };
-const getLocationHref = () => locationHref;
-
-function createTag(type) {
-  // return {appendChild:function(){},setAttribute:function(){},style:{}}
-  return document.createElement(type);
-}
-
-function extendPrototype(sources, destination) {
-  var i;
-  var len = sources.length;
-  var sourcePrototype;
-  for (i = 0; i < len; i += 1) {
-    sourcePrototype = sources[i].prototype;
-    for (var attr in sourcePrototype) {
-      if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
-    }
-  }
-}
-
-function getDescriptor(object, prop) {
-  return Object.getOwnPropertyDescriptor(object, prop);
-}
-
-function createProxyFunction(prototype) {
-  function ProxyFunction() {}
-  ProxyFunction.prototype = prototype;
-  return ProxyFunction;
-}
-
-// import Howl from '../../3rd_party/howler';
-
-const audioControllerFactory = (function () {
-  function AudioController(audioFactory) {
-    this.audios = [];
-    this.audioFactory = audioFactory;
-    this._volume = 1;
-    this._isMuted = false;
-  }
-
-  AudioController.prototype = {
-    addAudio: function (audio) {
-      this.audios.push(audio);
-    },
-    pause: function () {
-      var i;
-      var len = this.audios.length;
-      for (i = 0; i < len; i += 1) {
-        this.audios[i].pause();
-      }
-    },
-    resume: function () {
-      var i;
-      var len = this.audios.length;
-      for (i = 0; i < len; i += 1) {
-        this.audios[i].resume();
-      }
-    },
-    setRate: function (rateValue) {
-      var i;
-      var len = this.audios.length;
-      for (i = 0; i < len; i += 1) {
-        this.audios[i].setRate(rateValue);
-      }
-    },
-    createAudio: function (assetPath) {
-      if (this.audioFactory) {
-        return this.audioFactory(assetPath);
-      } if (window.Howl) {
-        return new window.Howl({
-          src: [assetPath],
-        });
-      }
-      return {
-        isPlaying: false,
-        play: function () { this.isPlaying = true; },
-        seek: function () { this.isPlaying = false; },
-        playing: function () {},
-        rate: function () {},
-        setVolume: function () {},
-      };
-    },
-    setAudioFactory: function (audioFactory) {
-      this.audioFactory = audioFactory;
-    },
-    setVolume: function (value) {
-      this._volume = value;
-      this._updateVolume();
-    },
-    mute: function () {
-      this._isMuted = true;
-      this._updateVolume();
-    },
-    unmute: function () {
-      this._isMuted = false;
-      this._updateVolume();
-    },
-    getVolume: function () {
-      return this._volume;
-    },
-    _updateVolume: function () {
-      var i;
-      var len = this.audios.length;
-      for (i = 0; i < len; i += 1) {
-        this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
-      }
-    },
-  };
-
-  return function () {
-    return new AudioController();
-  };
-}());
-
-const createTypedArray = (function () {
-  function createRegularArray(type, len) {
-    var i = 0;
-    var arr = [];
-    var value;
-    switch (type) {
-      case 'int16':
-      case 'uint8c':
-        value = 1;
-        break;
-      default:
-        value = 1.1;
-        break;
-    }
-    for (i = 0; i < len; i += 1) {
-      arr.push(value);
-    }
-    return arr;
-  }
-  function createTypedArrayFactory(type, len) {
-    if (type === 'float32') {
-      return new Float32Array(len);
-    } if (type === 'int16') {
-      return new Int16Array(len);
-    } if (type === 'uint8c') {
-      return new Uint8ClampedArray(len);
-    }
-    return createRegularArray(type, len);
-  }
-  if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
-    return createTypedArrayFactory;
-  }
-  return createRegularArray;
-}());
-
-function createSizedArray(len) {
-  return Array.apply(null, { length: len });
-}
-
-let subframeEnabled = true;
-let expressionsPlugin = null;
-let idPrefix$1 = '';
-const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
-let _shouldRoundValues = false;
-const bmPow = Math.pow;
-const bmSqrt = Math.sqrt;
-const bmFloor = Math.floor;
-const bmMax = Math.max;
-const bmMin = Math.min;
-
-const BMMath = {};
-(function () {
-  var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
-  var i;
-  var len = propertyNames.length;
-  for (i = 0; i < len; i += 1) {
-    BMMath[propertyNames[i]] = Math[propertyNames[i]];
-  }
-}());
-
-function ProjectInterface$1() { return {}; }
-BMMath.random = Math.random;
-BMMath.abs = function (val) {
-  var tOfVal = typeof val;
-  if (tOfVal === 'object' && val.length) {
-    var absArr = createSizedArray(val.length);
-    var i;
-    var len = val.length;
-    for (i = 0; i < len; i += 1) {
-      absArr[i] = Math.abs(val[i]);
-    }
-    return absArr;
-  }
-  return Math.abs(val);
-};
-let defaultCurveSegments = 150;
-const degToRads = Math.PI / 180;
-const roundCorner = 0.5519;
-
-function roundValues(flag) {
-  _shouldRoundValues = !!flag;
-}
-
-function bmRnd(value) {
-  if (_shouldRoundValues) {
-    return Math.round(value);
-  }
-  return value;
-}
-
-function styleDiv(element) {
-  element.style.position = 'absolute';
-  element.style.top = 0;
-  element.style.left = 0;
-  element.style.display = 'block';
-  element.style.transformOrigin = '0 0';
-  element.style.webkitTransformOrigin = '0 0';
-  element.style.backfaceVisibility = 'visible';
-  element.style.webkitBackfaceVisibility = 'visible';
-  element.style.transformStyle = 'preserve-3d';
-  element.style.webkitTransformStyle = 'preserve-3d';
-  element.style.mozTransformStyle = 'preserve-3d';
-}
-
-function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
-  this.type = type;
-  this.currentTime = currentTime;
-  this.totalTime = totalTime;
-  this.direction = frameMultiplier < 0 ? -1 : 1;
-}
-
-function BMCompleteEvent(type, frameMultiplier) {
-  this.type = type;
-  this.direction = frameMultiplier < 0 ? -1 : 1;
-}
-
-function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
-  this.type = type;
-  this.currentLoop = currentLoop;
-  this.totalLoops = totalLoops;
-  this.direction = frameMultiplier < 0 ? -1 : 1;
-}
-
-function BMSegmentStartEvent(type, firstFrame, totalFrames) {
-  this.type = type;
-  this.firstFrame = firstFrame;
-  this.totalFrames = totalFrames;
-}
-
-function BMDestroyEvent(type, target) {
-  this.type = type;
-  this.target = target;
-}
-
-function BMRenderFrameErrorEvent(nativeError, currentTime) {
-  this.type = 'renderFrameError';
-  this.nativeError = nativeError;
-  this.currentTime = currentTime;
-}
-
-function BMConfigErrorEvent(nativeError) {
-  this.type = 'configError';
-  this.nativeError = nativeError;
-}
-
-function BMAnimationConfigErrorEvent(type, nativeError) {
-  this.type = type;
-  this.nativeError = nativeError;
-}
-
-const createElementID = (function () {
-  var _count = 0;
-  return function createID() {
-    _count += 1;
-    return idPrefix$1 + '__lottie_element_' + _count;
-  };
-}());
-
-function HSVtoRGB(h, s, v) {
-  var r;
-  var g;
-  var b;
-  var i;
-  var f;
-  var p;
-  var q;
-  var t;
-  i = Math.floor(h * 6);
-  f = h * 6 - i;
-  p = v * (1 - s);
-  q = v * (1 - f * s);
-  t = v * (1 - (1 - f) * s);
-  switch (i % 6) {
-    case 0: r = v; g = t; b = p; break;
-    case 1: r = q; g = v; b = p; break;
-    case 2: r = p; g = v; b = t; break;
-    case 3: r = p; g = q; b = v; break;
-    case 4: r = t; g = p; b = v; break;
-    case 5: r = v; g = p; b = q; break;
-    default: break;
-  }
-  return [r,
-    g,
-    b];
-}
-
-function RGBtoHSV(r, g, b) {
-  var max = Math.max(r, g, b);
-  var min = Math.min(r, g, b);
-  var d = max - min;
-  var h;
-  var s = (max === 0 ? 0 : d / max);
-  var v = max / 255;
-
-  switch (max) {
-    case min: h = 0; break;
-    case r: h = (g - b) + d * (g < b ? 6 : 0); h /= 6 * d; break;
-    case g: h = (b - r) + d * 2; h /= 6 * d; break;
-    case b: h = (r - g) + d * 4; h /= 6 * d; break;
-    default: break;
-  }
-
-  return [
-    h,
-    s,
-    v,
-  ];
-}
-
-function addSaturationToRGB(color, offset) {
-  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
-  hsv[1] += offset;
-  if (hsv[1] > 1) {
-    hsv[1] = 1;
-  } else if (hsv[1] <= 0) {
-    hsv[1] = 0;
-  }
-  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
-}
-
-function addBrightnessToRGB(color, offset) {
-  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
-  hsv[2] += offset;
-  if (hsv[2] > 1) {
-    hsv[2] = 1;
-  } else if (hsv[2] < 0) {
-    hsv[2] = 0;
-  }
-  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
-}
-
-function addHueToRGB(color, offset) {
-  var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
-  hsv[0] += offset / 360;
-  if (hsv[0] > 1) {
-    hsv[0] -= 1;
-  } else if (hsv[0] < 0) {
-    hsv[0] += 1;
-  }
-  return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
-}
-
-const rgbToHex = (function () {
-  var colorMap = [];
-  var i;
-  var hex;
-  for (i = 0; i < 256; i += 1) {
-    hex = i.toString(16);
-    colorMap[i] = hex.length === 1 ? '0' + hex : hex;
-  }
-
-  return function (r, g, b) {
-    if (r < 0) {
-      r = 0;
-    }
-    if (g < 0) {
-      g = 0;
-    }
-    if (b < 0) {
-      b = 0;
-    }
-    return '#' + colorMap[r] + colorMap[g] + colorMap[b];
-  };
-}());
-
-const setSubframeEnabled = (flag) => { subframeEnabled = !!flag; };
-const getSubframeEnabled = () => subframeEnabled;
-const setExpressionsPlugin = (value) => { expressionsPlugin = value; };
-const getExpressionsPlugin = () => expressionsPlugin;
-const setDefaultCurveSegments = (value) => { defaultCurveSegments = value; };
-const getDefaultCurveSegments = () => defaultCurveSegments;
-const setIdPrefix = (value) => { idPrefix$1 = value; };
-const getIdPrefix = () => idPrefix$1;
-
-function createNS(type) {
-  // return {appendChild:function(){},setAttribute:function(){},style:{}}
-  return document.createElementNS(svgNS, type);
-}
-
-const dataManager = (function () {
-  var _counterId = 1;
-  var processes = [];
-  var workerFn;
-  var workerInstance;
-  var workerProxy = {
-    onmessage: function () {
-
-    },
-    postMessage: function (path) {
-      workerFn({
-        data: path,
-      });
-    },
-  };
-  var _workerSelf = {
-    postMessage: function (data) {
-      workerProxy.onmessage({
-        data: data,
-      });
-    },
-  };
-  function createWorker(fn) {
-    if (window.Worker && window.Blob && getWebWorker()) {
-      var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-      // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
-      var url = URL.createObjectURL(blob);
-      return new Worker(url);
-    }
-    workerFn = fn;
-    return workerProxy;
-  }
-
-  function setupWorker() {
-    if (!workerInstance) {
-      workerInstance = createWorker(function workerStart(e) {
-        function dataFunctionManager() {
-          function completeLayers(layers, comps) {
-            var layerData;
-            var i;
-            var len = layers.length;
-            var j;
-            var jLen;
-            var k;
-            var kLen;
-            for (i = 0; i < len; i += 1) {
-              layerData = layers[i];
-              if (('ks' in layerData) && !layerData.completed) {
-                layerData.completed = true;
-                if (layerData.tt) {
-                  layers[i - 1].td = layerData.tt;
-                }
-                if (layerData.hasMask) {
-                  var maskProps = layerData.masksProperties;
-                  jLen = maskProps.length;
-                  for (j = 0; j < jLen; j += 1) {
-                    if (maskProps[j].pt.k.i) {
-                      convertPathsToAbsoluteValues(maskProps[j].pt.k);
-                    } else {
-                      kLen = maskProps[j].pt.k.length;
-                      for (k = 0; k < kLen; k += 1) {
-                        if (maskProps[j].pt.k[k].s) {
-                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
-                        }
-                        if (maskProps[j].pt.k[k].e) {
-                          convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
-                        }
-                      }
-                    }
-                  }
-                }
-                if (layerData.ty === 0) {
-                  layerData.layers = findCompLayers(layerData.refId, comps);
-                  completeLayers(layerData.layers, comps);
-                } else if (layerData.ty === 4) {
-                  completeShapes(layerData.shapes);
-                } else if (layerData.ty === 5) {
-                  completeText(layerData);
-                }
-              }
-            }
-          }
-
-          function completeChars(chars, assets) {
-            if (chars) {
-              var i = 0;
-              var len = chars.length;
-              for (i = 0; i < len; i += 1) {
-                if (chars[i].t === 1) {
-                  // var compData = findComp(chars[i].data.refId, assets);
-                  chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
-                  // chars[i].data.ip = 0;
-                  // chars[i].data.op = 99999;
-                  // chars[i].data.st = 0;
-                  // chars[i].data.sr = 1;
-                  // chars[i].w = compData.w;
-                  // chars[i].data.ks = {
-                  //   a: { k: [0, 0, 0], a: 0 },
-                  //   p: { k: [0, -compData.h, 0], a: 0 },
-                  //   r: { k: 0, a: 0 },
-                  //   s: { k: [100, 100], a: 0 },
-                  //   o: { k: 100, a: 0 },
-                  // };
-                  completeLayers(chars[i].data.layers, assets);
-                }
-              }
-            }
-          }
-
-          function findComp(id, comps) {
-            var i = 0;
-            var len = comps.length;
-            while (i < len) {
-              if (comps[i].id === id) {
-                return comps[i];
-              }
-              i += 1;
-            }
-            return null;
-          }
-
-          function findCompLayers(id, comps) {
-            var comp = findComp(id, comps);
-            if (comp) {
-              if (!comp.layers.__used) {
-                comp.layers.__used = true;
-                return comp.layers;
-              }
-              return JSON.parse(JSON.stringify(comp.layers));
-            }
-            return null;
-          }
-
-          function completeShapes(arr) {
-            var i;
-            var len = arr.length;
-            var j;
-            var jLen;
-            for (i = len - 1; i >= 0; i -= 1) {
-              if (arr[i].ty === 'sh') {
-                if (arr[i].ks.k.i) {
-                  convertPathsToAbsoluteValues(arr[i].ks.k);
-                } else {
-                  jLen = arr[i].ks.k.length;
-                  for (j = 0; j < jLen; j += 1) {
-                    if (arr[i].ks.k[j].s) {
-                      convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
-                    }
-                    if (arr[i].ks.k[j].e) {
-                      convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
-                    }
-                  }
-                }
-              } else if (arr[i].ty === 'gr') {
-                completeShapes(arr[i].it);
-              }
-            }
-          }
-
-          function convertPathsToAbsoluteValues(path) {
-            var i;
-            var len = path.i.length;
-            for (i = 0; i < len; i += 1) {
-              path.i[i][0] += path.v[i][0];
-              path.i[i][1] += path.v[i][1];
-              path.o[i][0] += path.v[i][0];
-              path.o[i][1] += path.v[i][1];
-            }
-          }
-
-          function checkVersion(minimum, animVersionString) {
-            var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
-            if (minimum[0] > animVersion[0]) {
-              return true;
-            } if (animVersion[0] > minimum[0]) {
-              return false;
-            }
-            if (minimum[1] > animVersion[1]) {
-              return true;
-            } if (animVersion[1] > minimum[1]) {
-              return false;
-            }
-            if (minimum[2] > animVersion[2]) {
-              return true;
-            } if (animVersion[2] > minimum[2]) {
-              return false;
-            }
-            return null;
-          }
-
-          var checkText = (function () {
-            var minimumVersion = [4, 4, 14];
-
-            function updateTextLayer(textLayer) {
-              var documentData = textLayer.t.d;
-              textLayer.t.d = {
-                k: [
-                  {
-                    s: documentData,
-                    t: 0,
-                  },
-                ],
-              };
-            }
-
-            function iterateLayers(layers) {
-              var i;
-              var len = layers.length;
-              for (i = 0; i < len; i += 1) {
-                if (layers[i].ty === 5) {
-                  updateTextLayer(layers[i]);
-                }
-              }
-            }
-
-            return function (animationData) {
-              if (checkVersion(minimumVersion, animationData.v)) {
-                iterateLayers(animationData.layers);
-                if (animationData.assets) {
-                  var i;
-                  var len = animationData.assets.length;
-                  for (i = 0; i < len; i += 1) {
-                    if (animationData.assets[i].layers) {
-                      iterateLayers(animationData.assets[i].layers);
-                    }
-                  }
-                }
-              }
-            };
-          }());
-
-          var checkChars = (function () {
-            var minimumVersion = [4, 7, 99];
-            return function (animationData) {
-              if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
-                var i;
-                var len = animationData.chars.length;
-                for (i = 0; i < len; i += 1) {
-                  var charData = animationData.chars[i];
-                  if (charData.data && charData.data.shapes) {
-                    completeShapes(charData.data.shapes);
-                    charData.data.ip = 0;
-                    charData.data.op = 99999;
-                    charData.data.st = 0;
-                    charData.data.sr = 1;
-                    charData.data.ks = {
-                      p: { k: [0, 0], a: 0 },
-                      s: { k: [100, 100], a: 0 },
-                      a: { k: [0, 0], a: 0 },
-                      r: { k: 0, a: 0 },
-                      o: { k: 100, a: 0 },
-                    };
-                    if (!animationData.chars[i].t) {
-                      charData.data.shapes.push(
-                        {
-                          ty: 'no',
-                        }
-                      );
-                      charData.data.shapes[0].it.push(
-                        {
-                          p: { k: [0, 0], a: 0 },
-                          s: { k: [100, 100], a: 0 },
-                          a: { k: [0, 0], a: 0 },
-                          r: { k: 0, a: 0 },
-                          o: { k: 100, a: 0 },
-                          sk: { k: 0, a: 0 },
-                          sa: { k: 0, a: 0 },
-                          ty: 'tr',
-                        }
-                      );
-                    }
-                  }
-                }
-              }
-            };
-          }());
-
-          var checkPathProperties = (function () {
-            var minimumVersion = [5, 7, 15];
-
-            function updateTextLayer(textLayer) {
-              var pathData = textLayer.t.p;
-              if (typeof pathData.a === 'number') {
-                pathData.a = {
-                  a: 0,
-                  k: pathData.a,
-                };
-              }
-              if (typeof pathData.p === 'number') {
-                pathData.p = {
-                  a: 0,
-                  k: pathData.p,
-                };
-              }
-              if (typeof pathData.r === 'number') {
-                pathData.r = {
-                  a: 0,
-                  k: pathData.r,
-                };
-              }
-            }
-
-            function iterateLayers(layers) {
-              var i;
-              var len = layers.length;
-              for (i = 0; i < len; i += 1) {
-                if (layers[i].ty === 5) {
-                  updateTextLayer(layers[i]);
-                }
-              }
-            }
-
-            return function (animationData) {
-              if (checkVersion(minimumVersion, animationData.v)) {
-                iterateLayers(animationData.layers);
-                if (animationData.assets) {
-                  var i;
-                  var len = animationData.assets.length;
-                  for (i = 0; i < len; i += 1) {
-                    if (animationData.assets[i].layers) {
-                      iterateLayers(animationData.assets[i].layers);
-                    }
-                  }
-                }
-              }
-            };
-          }());
-
-          var checkColors = (function () {
-            var minimumVersion = [4, 1, 9];
-
-            function iterateShapes(shapes) {
-              var i;
-              var len = shapes.length;
-              var j;
-              var jLen;
-              for (i = 0; i < len; i += 1) {
-                if (shapes[i].ty === 'gr') {
-                  iterateShapes(shapes[i].it);
-                } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
-                  if (shapes[i].c.k && shapes[i].c.k[0].i) {
-                    jLen = shapes[i].c.k.length;
-                    for (j = 0; j < jLen; j += 1) {
-                      if (shapes[i].c.k[j].s) {
-                        shapes[i].c.k[j].s[0] /= 255;
-                        shapes[i].c.k[j].s[1] /= 255;
-                        shapes[i].c.k[j].s[2] /= 255;
-                        shapes[i].c.k[j].s[3] /= 255;
-                      }
-                      if (shapes[i].c.k[j].e) {
-                        shapes[i].c.k[j].e[0] /= 255;
-                        shapes[i].c.k[j].e[1] /= 255;
-                        shapes[i].c.k[j].e[2] /= 255;
-                        shapes[i].c.k[j].e[3] /= 255;
-                      }
-                    }
-                  } else {
-                    shapes[i].c.k[0] /= 255;
-                    shapes[i].c.k[1] /= 255;
-                    shapes[i].c.k[2] /= 255;
-                    shapes[i].c.k[3] /= 255;
-                  }
-                }
-              }
-            }
-
-            function iterateLayers(layers) {
-              var i;
-              var len = layers.length;
-              for (i = 0; i < len; i += 1) {
-                if (layers[i].ty === 4) {
-                  iterateShapes(layers[i].shapes);
-                }
-              }
-            }
-
-            return function (animationData) {
-              if (checkVersion(minimumVersion, animationData.v)) {
-                iterateLayers(animationData.layers);
-                if (animationData.assets) {
-                  var i;
-                  var len = animationData.assets.length;
-                  for (i = 0; i < len; i += 1) {
-                    if (animationData.assets[i].layers) {
-                      iterateLayers(animationData.assets[i].layers);
-                    }
-                  }
-                }
-              }
-            };
-          }());
-
-          var checkShapes = (function () {
-            var minimumVersion = [4, 4, 18];
-
-            function completeClosingShapes(arr) {
-              var i;
-              var len = arr.length;
-              var j;
-              var jLen;
-              for (i = len - 1; i >= 0; i -= 1) {
-                if (arr[i].ty === 'sh') {
-                  if (arr[i].ks.k.i) {
-                    arr[i].ks.k.c = arr[i].closed;
-                  } else {
-                    jLen = arr[i].ks.k.length;
-                    for (j = 0; j < jLen; j += 1) {
-                      if (arr[i].ks.k[j].s) {
-                        arr[i].ks.k[j].s[0].c = arr[i].closed;
-                      }
-                      if (arr[i].ks.k[j].e) {
-                        arr[i].ks.k[j].e[0].c = arr[i].closed;
-                      }
-                    }
-                  }
-                } else if (arr[i].ty === 'gr') {
-                  completeClosingShapes(arr[i].it);
-                }
-              }
-            }
-
-            function iterateLayers(layers) {
-              var layerData;
-              var i;
-              var len = layers.length;
-              var j;
-              var jLen;
-              var k;
-              var kLen;
-              for (i = 0; i < len; i += 1) {
-                layerData = layers[i];
-                if (layerData.hasMask) {
-                  var maskProps = layerData.masksProperties;
-                  jLen = maskProps.length;
-                  for (j = 0; j < jLen; j += 1) {
-                    if (maskProps[j].pt.k.i) {
-                      maskProps[j].pt.k.c = maskProps[j].cl;
-                    } else {
-                      kLen = maskProps[j].pt.k.length;
-                      for (k = 0; k < kLen; k += 1) {
-                        if (maskProps[j].pt.k[k].s) {
-                          maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
-                        }
-                        if (maskProps[j].pt.k[k].e) {
-                          maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
-                        }
-                      }
-                    }
-                  }
-                }
-                if (layerData.ty === 4) {
-                  completeClosingShapes(layerData.shapes);
-                }
-              }
-            }
-
-            return function (animationData) {
-              if (checkVersion(minimumVersion, animationData.v)) {
-                iterateLayers(animationData.layers);
-                if (animationData.assets) {
-                  var i;
-                  var len = animationData.assets.length;
-                  for (i = 0; i < len; i += 1) {
-                    if (animationData.assets[i].layers) {
-                      iterateLayers(animationData.assets[i].layers);
-                    }
-                  }
-                }
-              }
-            };
-          }());
-
-          function completeData(animationData) {
-            if (animationData.__complete) {
-              return;
-            }
-            checkColors(animationData);
-            checkText(animationData);
-            checkChars(animationData);
-            checkPathProperties(animationData);
-            checkShapes(animationData);
-            completeLayers(animationData.layers, animationData.assets);
-            completeChars(animationData.chars, animationData.assets);
-            animationData.__complete = true;
-          }
-
-          function completeText(data) {
-            if (data.t.a.length === 0 && !('m' in data.t.p)) {
-              // data.singleShape = true;
-            }
-          }
-
-          var moduleOb = {};
-          moduleOb.completeData = completeData;
-          moduleOb.checkColors = checkColors;
-          moduleOb.checkChars = checkChars;
-          moduleOb.checkPathProperties = checkPathProperties;
-          moduleOb.checkShapes = checkShapes;
-          moduleOb.completeLayers = completeLayers;
-
-          return moduleOb;
-        }
-        if (!_workerSelf.dataManager) {
-          _workerSelf.dataManager = dataFunctionManager();
-        }
-
-        if (!_workerSelf.assetLoader) {
-          _workerSelf.assetLoader = (function () {
-            function formatResponse(xhr) {
-              // using typeof doubles the time of execution of this method,
-              // so if available, it's better to use the header to validate the type
-              var contentTypeHeader = xhr.getResponseHeader('content-type');
-              if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
-                return xhr.response;
-              }
-              if (xhr.response && typeof xhr.response === 'object') {
-                return xhr.response;
-              } if (xhr.response && typeof xhr.response === 'string') {
-                return JSON.parse(xhr.response);
-              } if (xhr.responseText) {
-                return JSON.parse(xhr.responseText);
-              }
-              return null;
-            }
-
-            function loadAsset(path, fullPath, callback, errorCallback) {
-              var response;
-              var xhr = new XMLHttpRequest();
-              // set responseType after calling open or IE will break.
-              try {
-                // This crashes on Android WebView prior to KitKat
-                xhr.responseType = 'json';
-              } catch (err) {} // eslint-disable-line no-empty
-              xhr.onreadystatechange = function () {
-                if (xhr.readyState === 4) {
-                  if (xhr.status === 200) {
-                    response = formatResponse(xhr);
-                    callback(response);
-                  } else {
-                    try {
-                      response = formatResponse(xhr);
-                      callback(response);
-                    } catch (err) {
-                      if (errorCallback) {
-                        errorCallback(err);
-                      }
-                    }
-                  }
-                }
-              };
-              try {
-                xhr.open('GET', path, true);
-              } catch (error) {
-                xhr.open('GET', fullPath + '/' + path, true);
-              }
-              xhr.send();
-            }
-            return {
-              load: loadAsset,
-            };
-          }());
-        }
-
-        if (e.data.type === 'loadAnimation') {
-          _workerSelf.assetLoader.load(
-            e.data.path,
-            e.data.fullPath,
-            function (data) {
-              _workerSelf.dataManager.completeData(data);
-              _workerSelf.postMessage({
-                id: e.data.id,
-                payload: data,
-                status: 'success',
-              });
-            },
-            function () {
-              _workerSelf.postMessage({
-                id: e.data.id,
-                status: 'error',
-              });
-            }
-          );
-        } else if (e.data.type === 'complete') {
-          var animation = e.data.animation;
-          _workerSelf.dataManager.completeData(animation);
-          _workerSelf.postMessage({
-            id: e.data.id,
-            payload: animation,
-            status: 'success',
-          });
-        } else if (e.data.type === 'loadData') {
-          _workerSelf.assetLoader.load(
-            e.data.path,
-            e.data.fullPath,
-            function (data) {
-              _workerSelf.postMessage({
-                id: e.data.id,
-                payload: data,
-                status: 'success',
-              });
-            },
-            function () {
-              _workerSelf.postMessage({
-                id: e.data.id,
-                status: 'error',
-              });
-            }
-          );
-        }
-      });
-
-      workerInstance.onmessage = function (event) {
-        var data = event.data;
-        var id = data.id;
-        var process = processes[id];
-        processes[id] = null;
-        if (data.status === 'success') {
-          process.onComplete(data.payload);
-        } else if (process.onError) {
-          process.onError();
-        }
-      };
-    }
-  }
-
-  function createProcess(onComplete, onError) {
-    _counterId += 1;
-    var id = 'processId_' + _counterId;
-    processes[id] = {
-      onComplete: onComplete,
-      onError: onError,
-    };
-    return id;
-  }
-
-  function loadAnimation(path, onComplete, onError) {
-    setupWorker();
-    var processId = createProcess(onComplete, onError);
-    workerInstance.postMessage({
-      type: 'loadAnimation',
-      path: path,
-      fullPath: window.location.origin + window.location.pathname,
-      id: processId,
-    });
-  }
-
-  function loadData(path, onComplete, onError) {
-    setupWorker();
-    var processId = createProcess(onComplete, onError);
-    workerInstance.postMessage({
-      type: 'loadData',
-      path: path,
-      fullPath: window.location.origin + window.location.pathname,
-      id: processId,
-    });
-  }
-
-  function completeAnimation(anim, onComplete, onError) {
-    setupWorker();
-    var processId = createProcess(onComplete, onError);
-    workerInstance.postMessage({
-      type: 'complete',
-      animation: anim,
-      id: processId,
-    });
-  }
-
-  return {
-    loadAnimation: loadAnimation,
-    loadData: loadData,
-    completeAnimation: completeAnimation,
-  };
-}());
-
-const ImagePreloader = (function () {
-  var proxyImage = (function () {
-    var canvas = createTag('canvas');
-    canvas.width = 1;
-    canvas.height = 1;
-    var ctx = canvas.getContext('2d');
-    ctx.fillStyle = 'rgba(0,0,0,0)';
-    ctx.fillRect(0, 0, 1, 1);
-    return canvas;
-  }());
-
-  function imageLoaded() {
-    this.loadedAssets += 1;
-    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
-      if (this.imagesLoadedCb) {
-        this.imagesLoadedCb(null);
-      }
-    }
-  }
-  function footageLoaded() {
-    this.loadedFootagesCount += 1;
-    if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
-      if (this.imagesLoadedCb) {
-        this.imagesLoadedCb(null);
-      }
-    }
-  }
-
-  function getAssetsPath(assetData, assetsPath, originalPath) {
-    var path = '';
-    if (assetData.e) {
-      path = assetData.p;
-    } else if (assetsPath) {
-      var imagePath = assetData.p;
-      if (imagePath.indexOf('images/') !== -1) {
-        imagePath = imagePath.split('/')[1];
-      }
-      path = assetsPath + imagePath;
-    } else {
-      path = originalPath;
-      path += assetData.u ? assetData.u : '';
-      path += assetData.p;
-    }
-    return path;
-  }
-
-  function testImageLoaded(img) {
-    var _count = 0;
-    var intervalId = setInterval(function () {
-      var box = img.getBBox();
-      if (box.width || _count > 500) {
-        this._imageLoaded();
-        clearInterval(intervalId);
-      }
-      _count += 1;
-    }.bind(this), 50);
-  }
-
-  function createImageData(assetData) {
-    var path = getAssetsPath(assetData, this.assetsPath, this.path);
-    var img = createNS('image');
-    if (isSafari) {
-      this.testImageLoaded(img);
-    } else {
-      img.addEventListener('load', this._imageLoaded, false);
-    }
-    img.addEventListener('error', function () {
-      ob.img = proxyImage;
-      this._imageLoaded();
-    }.bind(this), false);
-    img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
-    if (this._elementHelper.append) {
-      this._elementHelper.append(img);
-    } else {
-      this._elementHelper.appendChild(img);
-    }
-    var ob = {
-      img: img,
-      assetData: assetData,
-    };
-    return ob;
-  }
-
-  function createImgData(assetData) {
-    var path = getAssetsPath(assetData, this.assetsPath, this.path);
-    var img = createTag('img');
-    img.crossOrigin = 'anonymous';
-    img.addEventListener('load', this._imageLoaded, false);
-    img.addEventListener('error', function () {
-      ob.img = proxyImage;
-      this._imageLoaded();
-    }.bind(this), false);
-    img.src = path;
-    var ob = {
-      img: img,
-      assetData: assetData,
-    };
-    return ob;
-  }
-
-  function createFootageData(data) {
-    var ob = {
-      assetData: data,
-    };
-    var path = getAssetsPath(data, this.assetsPath, this.path);
-    dataManager.loadData(path, function (footageData) {
-      ob.img = footageData;
-      this._footageLoaded();
-    }.bind(this), function () {
-      ob.img = {};
-      this._footageLoaded();
-    }.bind(this));
-    return ob;
-  }
-
-  function loadAssets(assets, cb) {
-    this.imagesLoadedCb = cb;
-    var i;
-    var len = assets.length;
-    for (i = 0; i < len; i += 1) {
-      if (!assets[i].layers) {
-        if (!assets[i].t || assets[i].t === 'seq') {
-          this.totalImages += 1;
-          this.images.push(this._createImageData(assets[i]));
-        } else if (assets[i].t === 3) {
-          this.totalFootages += 1;
-          this.images.push(this.createFootageData(assets[i]));
-        }
-      }
-    }
-  }
-
-  function setPath(path) {
-    this.path = path || '';
-  }
-
-  function setAssetsPath(path) {
-    this.assetsPath = path || '';
-  }
-
-  function getAsset(assetData) {
-    var i = 0;
-    var len = this.images.length;
-    while (i < len) {
-      if (this.images[i].assetData === assetData) {
-        return this.images[i].img;
-      }
-      i += 1;
-    }
-    return null;
-  }
-
-  function destroy() {
-    this.imagesLoadedCb = null;
-    this.images.length = 0;
-  }
-
-  function loadedImages() {
-    return this.totalImages === this.loadedAssets;
-  }
-
-  function loadedFootages() {
-    return this.totalFootages === this.loadedFootagesCount;
-  }
-
-  function setCacheType(type, elementHelper) {
-    if (type === 'svg') {
-      this._elementHelper = elementHelper;
-      this._createImageData = this.createImageData.bind(this);
-    } else {
-      this._createImageData = this.createImgData.bind(this);
-    }
-  }
-
-  function ImagePreloaderFactory() {
-    this._imageLoaded = imageLoaded.bind(this);
-    this._footageLoaded = footageLoaded.bind(this);
-    this.testImageLoaded = testImageLoaded.bind(this);
-    this.createFootageData = createFootageData.bind(this);
-    this.assetsPath = '';
-    this.path = '';
-    this.totalImages = 0;
-    this.totalFootages = 0;
-    this.loadedAssets = 0;
-    this.loadedFootagesCount = 0;
-    this.imagesLoadedCb = null;
-    this.images = [];
-  }
-
-  ImagePreloaderFactory.prototype = {
-    loadAssets: loadAssets,
-    setAssetsPath: setAssetsPath,
-    setPath: setPath,
-    loadedImages: loadedImages,
-    loadedFootages: loadedFootages,
-    destroy: destroy,
-    getAsset: getAsset,
-    createImgData: createImgData,
-    createImageData: createImageData,
-    imageLoaded: imageLoaded,
-    footageLoaded: footageLoaded,
-    setCacheType: setCacheType,
-  };
-
-  return ImagePreloaderFactory;
-}());
-
-function BaseEvent() {}
-BaseEvent.prototype = {
-  triggerEvent: function (eventName, args) {
-    if (this._cbs[eventName]) {
-      var callbacks = this._cbs[eventName];
-      for (var i = 0; i < callbacks.length; i += 1) {
-        callbacks[i](args);
-      }
-    }
-  },
-  addEventListener: function (eventName, callback) {
-    if (!this._cbs[eventName]) {
-      this._cbs[eventName] = [];
-    }
-    this._cbs[eventName].push(callback);
-
-    return function () {
-      this.removeEventListener(eventName, callback);
-    }.bind(this);
-  },
-  removeEventListener: function (eventName, callback) {
-    if (!callback) {
-      this._cbs[eventName] = null;
-    } else if (this._cbs[eventName]) {
-      var i = 0;
-      var len = this._cbs[eventName].length;
-      while (i < len) {
-        if (this._cbs[eventName][i] === callback) {
-          this._cbs[eventName].splice(i, 1);
-          i -= 1;
-          len -= 1;
-        }
-        i += 1;
-      }
-      if (!this._cbs[eventName].length) {
-        this._cbs[eventName] = null;
-      }
-    }
-  },
-};
-
-const markerParser = (
-
-  function () {
-    function parsePayloadLines(payload) {
-      var lines = payload.split('\r\n');
-      var keys = {};
-      var line;
-      var keysCount = 0;
-      for (var i = 0; i < lines.length; i += 1) {
-        line = lines[i].split(':');
-        if (line.length === 2) {
-          keys[line[0]] = line[1].trim();
-          keysCount += 1;
-        }
-      }
-      if (keysCount === 0) {
-        throw new Error();
-      }
-      return keys;
-    }
-
-    return function (_markers) {
-      var markers = [];
-      for (var i = 0; i < _markers.length; i += 1) {
-        var _marker = _markers[i];
-        var markerData = {
-          time: _marker.tm,
-          duration: _marker.dr,
-        };
-        try {
-          markerData.payload = JSON.parse(_markers[i].cm);
-        } catch (_) {
-          try {
-            markerData.payload = parsePayloadLines(_markers[i].cm);
-          } catch (__) {
-            markerData.payload = {
-              name: _markers[i].cm,
-            };
-          }
-        }
-        markers.push(markerData);
-      }
-      return markers;
-    };
-  }());
-
-const ProjectInterface = (function () {
-  function registerComposition(comp) {
-    this.compositions.push(comp);
-  }
-
-  return function () {
-    function _thisProjectFunction(name) {
-      var i = 0;
-      var len = this.compositions.length;
-      while (i < len) {
-        if (this.compositions[i].data && this.compositions[i].data.nm === name) {
-          if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
-            this.compositions[i].prepareFrame(this.currentFrame);
-          }
-          return this.compositions[i].compInterface;
-        }
-        i += 1;
-      }
-      return null;
-    }
-
-    _thisProjectFunction.compositions = [];
-    _thisProjectFunction.currentFrame = 0;
-
-    _thisProjectFunction.registerComposition = registerComposition;
-
-    return _thisProjectFunction;
-  };
-}());
-
-const renderers = {};
-
-const registerRenderer = (key, value) => {
-  renderers[key] = value;
-};
-
-function getRenderer(key) {
-  return renderers[key];
-}
-
-const AnimationItem = function () {
-  this._cbs = [];
-  this.name = '';
-  this.path = '';
-  this.isLoaded = false;
-  this.currentFrame = 0;
-  this.currentRawFrame = 0;
-  this.firstFrame = 0;
-  this.totalFrames = 0;
-  this.frameRate = 0;
-  this.frameMult = 0;
-  this.playSpeed = 1;
-  this.playDirection = 1;
-  this.playCount = 0;
-  this.animationData = {};
-  this.assets = [];
-  this.isPaused = true;
-  this.autoplay = false;
-  this.loop = true;
-  this.renderer = null;
-  this.animationID = createElementID();
-  this.assetsPath = '';
-  this.timeCompleted = 0;
-  this.segmentPos = 0;
-  this.isSubframeEnabled = getSubframeEnabled();
-  this.segments = [];
-  this._idle = true;
-  this._completedLoop = false;
-  this.projectInterface = ProjectInterface();
-  this.imagePreloader = new ImagePreloader();
-  this.audioController = audioControllerFactory();
-  this.markers = [];
-  this.configAnimation = this.configAnimation.bind(this);
-  this.onSetupError = this.onSetupError.bind(this);
-  this.onSegmentComplete = this.onSegmentComplete.bind(this);
-  this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
-};
-
-extendPrototype([BaseEvent], AnimationItem);
-
-AnimationItem.prototype.setParams = function (params) {
-  if (params.wrapper || params.container) {
-    this.wrapper = params.wrapper || params.container;
-  }
-  var animType = 'svg';
-  if (params.animType) {
-    animType = params.animType;
-  } else if (params.renderer) {
-    animType = params.renderer;
-  }
-  const RendererClass = getRenderer(animType);
-  this.renderer = new RendererClass(this, params.rendererSettings);
-  this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
-  this.renderer.setProjectInterface(this.projectInterface);
-  this.animType = animType;
-  if (params.loop === ''
-        || params.loop === null
-        || params.loop === undefined
-        || params.loop === true) {
-    this.loop = true;
-  } else if (params.loop === false) {
-    this.loop = false;
-  } else {
-    this.loop = parseInt(params.loop, 10);
-  }
-  this.autoplay = 'autoplay' in params ? params.autoplay : true;
-  this.name = params.name ? params.name : '';
-  this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
-  this.assetsPath = params.assetsPath;
-  this.initialSegment = params.initialSegment;
-  if (params.audioFactory) {
-    this.audioController.setAudioFactory(params.audioFactory);
-  }
-  if (params.animationData) {
-    this.setupAnimation(params.animationData);
-  } else if (params.path) {
-    if (params.path.lastIndexOf('\\') !== -1) {
-      this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
-    } else {
-      this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
-    }
-    this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
-    this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
-    dataManager.loadAnimation(
-      params.path,
-      this.configAnimation,
-      this.onSetupError
-    );
-  }
-};
-
-AnimationItem.prototype.onSetupError = function () {
-  this.trigger('data_failed');
-};
-
-AnimationItem.prototype.setupAnimation = function (data) {
-  dataManager.completeAnimation(
-    data,
-    this.configAnimation
-  );
-};
-
-AnimationItem.prototype.setData = function (wrapper, animationData) {
-  if (animationData) {
-    if (typeof animationData !== 'object') {
-      animationData = JSON.parse(animationData);
-    }
-  }
-  var params = {
-    wrapper: wrapper,
-    animationData: animationData,
-  };
-  var wrapperAttributes = wrapper.attributes;
-
-  params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
-    ? wrapperAttributes.getNamedItem('data-animation-path').value
-    : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
-      ? wrapperAttributes.getNamedItem('data-bm-path').value
-      : wrapperAttributes.getNamedItem('bm-path')
-        ? wrapperAttributes.getNamedItem('bm-path').value
-        : '';
-  params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
-    ? wrapperAttributes.getNamedItem('data-anim-type').value
-    : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
-      ? wrapperAttributes.getNamedItem('data-bm-type').value
-      : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
-        ? wrapperAttributes.getNamedItem('bm-type').value
-        : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
-          ? wrapperAttributes.getNamedItem('data-bm-renderer').value
-          : wrapperAttributes.getNamedItem('bm-renderer')
-            ? wrapperAttributes.getNamedItem('bm-renderer').value
-            : 'canvas';
-
-  var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
-    ? wrapperAttributes.getNamedItem('data-anim-loop').value
-    : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
-      ? wrapperAttributes.getNamedItem('data-bm-loop').value
-      : wrapperAttributes.getNamedItem('bm-loop')
-        ? wrapperAttributes.getNamedItem('bm-loop').value
-        : '';
-  if (loop === 'false') {
-    params.loop = false;
-  } else if (loop === 'true') {
-    params.loop = true;
-  } else if (loop !== '') {
-    params.loop = parseInt(loop, 10);
-  }
-  var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
-    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value
-    : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
-      ? wrapperAttributes.getNamedItem('data-bm-autoplay').value
-      : wrapperAttributes.getNamedItem('bm-autoplay')
-        ? wrapperAttributes.getNamedItem('bm-autoplay').value
-        : true;
-  params.autoplay = autoplay !== 'false';
-
-  params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
-    ? wrapperAttributes.getNamedItem('data-name').value
-    : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
-      ? wrapperAttributes.getNamedItem('data-bm-name').value
-      : wrapperAttributes.getNamedItem('bm-name')
-        ? wrapperAttributes.getNamedItem('bm-name').value
-        : '';
-  var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
-    ? wrapperAttributes.getNamedItem('data-anim-prerender').value
-    : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
-      ? wrapperAttributes.getNamedItem('data-bm-prerender').value
-      : wrapperAttributes.getNamedItem('bm-prerender')
-        ? wrapperAttributes.getNamedItem('bm-prerender').value
-        : '';
-
-  if (prerender === 'false') {
-    params.prerender = false;
-  }
-  this.setParams(params);
-};
-
-AnimationItem.prototype.includeLayers = function (data) {
-  if (data.op > this.animationData.op) {
-    this.animationData.op = data.op;
-    this.totalFrames = Math.floor(data.op - this.animationData.ip);
-  }
-  var layers = this.animationData.layers;
-  var i;
-  var len = layers.length;
-  var newLayers = data.layers;
-  var j;
-  var jLen = newLayers.length;
-  for (j = 0; j < jLen; j += 1) {
-    i = 0;
-    while (i < len) {
-      if (layers[i].id === newLayers[j].id) {
-        layers[i] = newLayers[j];
-        break;
-      }
-      i += 1;
-    }
-  }
-  if (data.chars || data.fonts) {
-    this.renderer.globalData.fontManager.addChars(data.chars);
-    this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
-  }
-  if (data.assets) {
-    len = data.assets.length;
-    for (i = 0; i < len; i += 1) {
-      this.animationData.assets.push(data.assets[i]);
-    }
-  }
-  this.animationData.__complete = false;
-  dataManager.completeAnimation(
-    this.animationData,
-    this.onSegmentComplete
-  );
-};
-
-AnimationItem.prototype.onSegmentComplete = function (data) {
-  this.animationData = data;
-  var expressionsPlugin = getExpressionsPlugin();
-  if (expressionsPlugin) {
-    expressionsPlugin.initExpressions(this);
-  }
-  this.loadNextSegment();
-};
-
-AnimationItem.prototype.loadNextSegment = function () {
-  var segments = this.animationData.segments;
-  if (!segments || segments.length === 0 || !this.autoloadSegments) {
-    this.trigger('data_ready');
-    this.timeCompleted = this.totalFrames;
-    return;
-  }
-  var segment = segments.shift();
-  this.timeCompleted = segment.time * this.frameRate;
-  var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
-  this.segmentPos += 1;
-  dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
-    this.trigger('data_failed');
-  }.bind(this));
-};
-
-AnimationItem.prototype.loadSegments = function () {
-  var segments = this.animationData.segments;
-  if (!segments) {
-    this.timeCompleted = this.totalFrames;
-  }
-  this.loadNextSegment();
-};
-
-AnimationItem.prototype.imagesLoaded = function () {
-  this.trigger('loaded_images');
-  this.checkLoaded();
-};
-
-AnimationItem.prototype.preloadImages = function () {
-  this.imagePreloader.setAssetsPath(this.assetsPath);
-  this.imagePreloader.setPath(this.path);
-  this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
-};
-
-AnimationItem.prototype.configAnimation = function (animData) {
-  if (!this.renderer) {
-    return;
-  }
-  try {
-    this.animationData = animData;
-    if (this.initialSegment) {
-      this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
-      this.firstFrame = Math.round(this.initialSegment[0]);
-    } else {
-      this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
-      this.firstFrame = Math.round(this.animationData.ip);
-    }
-    this.renderer.configAnimation(animData);
-    if (!animData.assets) {
-      animData.assets = [];
-    }
-
-    this.assets = this.animationData.assets;
-    this.frameRate = this.animationData.fr;
-    this.frameMult = this.animationData.fr / 1000;
-    this.renderer.searchExtraCompositions(animData.assets);
-    this.markers = markerParser(animData.markers || []);
-    this.trigger('config_ready');
-    this.preloadImages();
-    this.loadSegments();
-    this.updaFrameModifier();
-    this.waitForFontsLoaded();
-    if (this.isPaused) {
-      this.audioController.pause();
-    }
-  } catch (error) {
-    this.triggerConfigError(error);
-  }
-};
-
-AnimationItem.prototype.waitForFontsLoaded = function () {
-  if (!this.renderer) {
-    return;
-  }
-  if (this.renderer.globalData.fontManager.isLoaded) {
-    this.checkLoaded();
-  } else {
-    setTimeout(this.waitForFontsLoaded.bind(this), 20);
-  }
-};
-
-AnimationItem.prototype.checkLoaded = function () {
-  if (!this.isLoaded
-        && this.renderer.globalData.fontManager.isLoaded
-        && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas')
-        && (this.imagePreloader.loadedFootages())
-  ) {
-    this.isLoaded = true;
-    var expressionsPlugin = getExpressionsPlugin();
-    if (expressionsPlugin) {
-      expressionsPlugin.initExpressions(this);
-    }
-    this.renderer.initItems();
-    setTimeout(function () {
-      this.trigger('DOMLoaded');
-    }.bind(this), 0);
-    this.gotoFrame();
-    if (this.autoplay) {
-      this.play();
-    }
-  }
-};
-
-AnimationItem.prototype.resize = function () {
-  this.renderer.updateContainerSize();
-};
-
-AnimationItem.prototype.setSubframe = function (flag) {
-  this.isSubframeEnabled = !!flag;
-};
-
-AnimationItem.prototype.gotoFrame = function () {
-  this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise
-
-  if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
-    this.currentFrame = this.timeCompleted;
-  }
-  this.trigger('enterFrame');
-  this.renderFrame();
-  this.trigger('drawnFrame');
-};
-
-AnimationItem.prototype.renderFrame = function () {
-  if (this.isLoaded === false || !this.renderer) {
-    return;
-  }
-  try {
-    this.renderer.renderFrame(this.currentFrame + this.firstFrame);
-  } catch (error) {
-    this.triggerRenderFrameError(error);
-  }
-};
-
-AnimationItem.prototype.play = function (name) {
-  if (name && this.name !== name) {
-    return;
-  }
-  if (this.isPaused === true) {
-    this.isPaused = false;
-    this.trigger('_pause');
-    this.audioController.resume();
-    if (this._idle) {
-      this._idle = false;
-      this.trigger('_active');
-    }
-  }
-};
-
-AnimationItem.prototype.pause = function (name) {
-  if (name && this.name !== name) {
-    return;
-  }
-  if (this.isPaused === false) {
-    this.isPaused = true;
-    this.trigger('_play');
-    this._idle = true;
-    this.trigger('_idle');
-    this.audioController.pause();
-  }
-};
-
-AnimationItem.prototype.togglePause = function (name) {
-  if (name && this.name !== name) {
-    return;
-  }
-  if (this.isPaused === true) {
-    this.play();
-  } else {
-    this.pause();
-  }
-};
-
-AnimationItem.prototype.stop = function (name) {
-  if (name && this.name !== name) {
-    return;
-  }
-  this.pause();
-  this.playCount = 0;
-  this._completedLoop = false;
-  this.setCurrentRawFrameValue(0);
-};
-
-AnimationItem.prototype.getMarkerData = function (markerName) {
-  var marker;
-  for (var i = 0; i < this.markers.length; i += 1) {
-    marker = this.markers[i];
-    if (marker.payload && marker.payload.name === markerName) {
-      return marker;
-    }
-  }
-  return null;
-};
-
-AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
-  if (name && this.name !== name) {
-    return;
-  }
-  var numValue = Number(value);
-  if (isNaN(numValue)) {
-    var marker = this.getMarkerData(value);
-    if (marker) {
-      this.goToAndStop(marker.time, true);
-    }
-  } else if (isFrame) {
-    this.setCurrentRawFrameValue(value);
-  } else {
-    this.setCurrentRawFrameValue(value * this.frameModifier);
-  }
-  this.pause();
-};
-
-AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
-  if (name && this.name !== name) {
-    return;
-  }
-  var numValue = Number(value);
-  if (isNaN(numValue)) {
-    var marker = this.getMarkerData(value);
-    if (marker) {
-      if (!marker.duration) {
-        this.goToAndStop(marker.time, true);
-      } else {
-        this.playSegments([marker.time, marker.time + marker.duration], true);
-      }
-    }
-  } else {
-    this.goToAndStop(numValue, isFrame, name);
-  }
-  this.play();
-};
-
-AnimationItem.prototype.advanceTime = function (value) {
-  if (this.isPaused === true || this.isLoaded === false) {
-    return;
-  }
-  var nextValue = this.currentRawFrame + value * this.frameModifier;
-  var _isComplete = false;
-  // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
-  // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
-  if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
-    if (!this.loop || this.playCount === this.loop) {
-      if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
-        _isComplete = true;
-        nextValue = this.totalFrames - 1;
-      }
-    } else if (nextValue >= this.totalFrames) {
-      this.playCount += 1;
-      if (!this.checkSegments(nextValue % this.totalFrames)) {
-        this.setCurrentRawFrameValue(nextValue % this.totalFrames);
-        this._completedLoop = true;
-        this.trigger('loopComplete');
-      }
-    } else {
-      this.setCurrentRawFrameValue(nextValue);
-    }
-  } else if (nextValue < 0) {
-    if (!this.checkSegments(nextValue % this.totalFrames)) {
-      if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) { // eslint-disable-line no-plusplus
-        this.setCurrentRawFrameValue(this.totalFrames + (nextValue % this.totalFrames));
-        if (!this._completedLoop) {
-          this._completedLoop = true;
-        } else {
-          this.trigger('loopComplete');
-        }
-      } else {
-        _isComplete = true;
-        nextValue = 0;
-      }
-    }
-  } else {
-    this.setCurrentRawFrameValue(nextValue);
-  }
-  if (_isComplete) {
-    this.setCurrentRawFrameValue(nextValue);
-    this.pause();
-    this.trigger('complete');
-  }
-};
-
-AnimationItem.prototype.adjustSegment = function (arr, offset) {
-  this.playCount = 0;
-  if (arr[1] < arr[0]) {
-    if (this.frameModifier > 0) {
-      if (this.playSpeed < 0) {
-        this.setSpeed(-this.playSpeed);
-      } else {
-        this.setDirection(-1);
-      }
-    }
-    this.totalFrames = arr[0] - arr[1];
-    this.timeCompleted = this.totalFrames;
-    this.firstFrame = arr[1];
-    this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
-  } else if (arr[1] > arr[0]) {
-    if (this.frameModifier < 0) {
-      if (this.playSpeed < 0) {
-        this.setSpeed(-this.playSpeed);
-      } else {
-        this.setDirection(1);
-      }
-    }
-    this.totalFrames = arr[1] - arr[0];
-    this.timeCompleted = this.totalFrames;
-    this.firstFrame = arr[0];
-    this.setCurrentRawFrameValue(0.001 + offset);
-  }
-  this.trigger('segmentStart');
-};
-AnimationItem.prototype.setSegment = function (init, end) {
-  var pendingFrame = -1;
-  if (this.isPaused) {
-    if (this.currentRawFrame + this.firstFrame < init) {
-      pendingFrame = init;
-    } else if (this.currentRawFrame + this.firstFrame > end) {
-      pendingFrame = end - init;
-    }
-  }
-
-  this.firstFrame = init;
-  this.totalFrames = end - init;
-  this.timeCompleted = this.totalFrames;
-  if (pendingFrame !== -1) {
-    this.goToAndStop(pendingFrame, true);
-  }
-};
-
-AnimationItem.prototype.playSegments = function (arr, forceFlag) {
-  if (forceFlag) {
-    this.segments.length = 0;
-  }
-  if (typeof arr[0] === 'object') {
-    var i;
-    var len = arr.length;
-    for (i = 0; i < len; i += 1) {
-      this.segments.push(arr[i]);
-    }
-  } else {
-    this.segments.push(arr);
-  }
-  if (this.segments.length && forceFlag) {
-    this.adjustSegment(this.segments.shift(), 0);
-  }
-  if (this.isPaused) {
-    this.play();
-  }
-};
-
-AnimationItem.prototype.resetSegments = function (forceFlag) {
-  this.segments.length = 0;
-  this.segments.push([this.animationData.ip, this.animationData.op]);
-  if (forceFlag) {
-    this.checkSegments(0);
-  }
-};
-AnimationItem.prototype.checkSegments = function (offset) {
-  if (this.segments.length) {
-    this.adjustSegment(this.segments.shift(), offset);
-    return true;
-  }
-  return false;
-};
-
-AnimationItem.prototype.destroy = function (name) {
-  if ((name && this.name !== name) || !this.renderer) {
-    return;
-  }
-  this.renderer.destroy();
-  this.imagePreloader.destroy();
-  this.trigger('destroy');
-  this._cbs = null;
-  this.onEnterFrame = null;
-  this.onLoopComplete = null;
-  this.onComplete = null;
-  this.onSegmentStart = null;
-  this.onDestroy = null;
-  this.renderer = null;
-  this.renderer = null;
-  this.imagePreloader = null;
-  this.projectInterface = null;
-};
-
-AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
-  this.currentRawFrame = value;
-  this.gotoFrame();
-};
-
-AnimationItem.prototype.setSpeed = function (val) {
-  this.playSpeed = val;
-  this.updaFrameModifier();
-};
-
-AnimationItem.prototype.setDirection = function (val) {
-  this.playDirection = val < 0 ? -1 : 1;
-  this.updaFrameModifier();
-};
-
-AnimationItem.prototype.setVolume = function (val, name) {
-  if (name && this.name !== name) {
-    return;
-  }
-  this.audioController.setVolume(val);
-};
-
-AnimationItem.prototype.getVolume = function () {
-  return this.audioController.getVolume();
-};
-
-AnimationItem.prototype.mute = function (name) {
-  if (name && this.name !== name) {
-    return;
-  }
-  this.audioController.mute();
-};
-
-AnimationItem.prototype.unmute = function (name) {
-  if (name && this.name !== name) {
-    return;
-  }
-  this.audioController.unmute();
-};
-
-AnimationItem.prototype.updaFrameModifier = function () {
-  this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
-  this.audioController.setRate(this.playSpeed * this.playDirection);
-};
-
-AnimationItem.prototype.getPath = function () {
-  return this.path;
-};
-
-AnimationItem.prototype.getAssetsPath = function (assetData) {
-  var path = '';
-  if (assetData.e) {
-    path = assetData.p;
-  } else if (this.assetsPath) {
-    var imagePath = assetData.p;
-    if (imagePath.indexOf('images/') !== -1) {
-      imagePath = imagePath.split('/')[1];
-    }
-    path = this.assetsPath + imagePath;
-  } else {
-    path = this.path;
-    path += assetData.u ? assetData.u : '';
-    path += assetData.p;
-  }
-  return path;
-};
-
-AnimationItem.prototype.getAssetData = function (id) {
-  var i = 0;
-  var len = this.assets.length;
-  while (i < len) {
-    if (id === this.assets[i].id) {
-      return this.assets[i];
-    }
-    i += 1;
-  }
-  return null;
-};
-
-AnimationItem.prototype.hide = function () {
-  this.renderer.hide();
-};
-
-AnimationItem.prototype.show = function () {
-  this.renderer.show();
-};
-
-AnimationItem.prototype.getDuration = function (isFrame) {
-  return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
-};
-
-AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
-  try {
-    var element = this.renderer.getElementByPath(path);
-    element.updateDocumentData(documentData, index);
-  } catch (error) {
-    // TODO: decide how to handle catch case
-  }
-};
-
-AnimationItem.prototype.trigger = function (name) {
-  if (this._cbs && this._cbs[name]) {
-    switch (name) {
-      case 'enterFrame':
-        this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
-        break;
-      case 'drawnFrame':
-        this.drawnFrameEvent.currentTime = this.currentFrame;
-        this.drawnFrameEvent.totalTime = this.totalFrames;
-        this.drawnFrameEvent.direction = this.frameModifier;
-        this.triggerEvent(name, this.drawnFrameEvent);
-        break;
-      case 'loopComplete':
-        this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
-        break;
-      case 'complete':
-        this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
-        break;
-      case 'segmentStart':
-        this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
-        break;
-      case 'destroy':
-        this.triggerEvent(name, new BMDestroyEvent(name, this));
-        break;
-      default:
-        this.triggerEvent(name);
-    }
-  }
-  if (name === 'enterFrame' && this.onEnterFrame) {
-    this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
-  }
-  if (name === 'loopComplete' && this.onLoopComplete) {
-    this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
-  }
-  if (name === 'complete' && this.onComplete) {
-    this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
-  }
-  if (name === 'segmentStart' && this.onSegmentStart) {
-    this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
-  }
-  if (name === 'destroy' && this.onDestroy) {
-    this.onDestroy.call(this, new BMDestroyEvent(name, this));
-  }
-};
-
-AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
-  var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
-  this.triggerEvent('error', error);
-
-  if (this.onError) {
-    this.onError.call(this, error);
-  }
-};
-
-AnimationItem.prototype.triggerConfigError = function (nativeError) {
-  var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
-  this.triggerEvent('error', error);
-
-  if (this.onError) {
-    this.onError.call(this, error);
-  }
-};
-
-const animationManager = (function () {
-  var moduleOb = {};
-  var registeredAnimations = [];
-  var initTime = 0;
-  var len = 0;
-  var playingAnimationsNum = 0;
-  var _stopped = true;
-  var _isFrozen = false;
-
-  function removeElement(ev) {
-    var i = 0;
-    var animItem = ev.target;
-    while (i < len) {
-      if (registeredAnimations[i].animation === animItem) {
-        registeredAnimations.splice(i, 1);
-        i -= 1;
-        len -= 1;
-        if (!animItem.isPaused) {
-          subtractPlayingCount();
-        }
-      }
-      i += 1;
-    }
-  }
-
-  function registerAnimation(element, animationData) {
-    if (!element) {
-      return null;
-    }
-    var i = 0;
-    while (i < len) {
-      if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
-        return registeredAnimations[i].animation;
-      }
-      i += 1;
-    }
-    var animItem = new AnimationItem();
-    setupAnimation(animItem, element);
-    animItem.setData(element, animationData);
-    return animItem;
-  }
-
-  function getRegisteredAnimations() {
-    var i;
-    var lenAnims = registeredAnimations.length;
-    var animations = [];
-    for (i = 0; i < lenAnims; i += 1) {
-      animations.push(registeredAnimations[i].animation);
-    }
-    return animations;
-  }
-
-  function addPlayingCount() {
-    playingAnimationsNum += 1;
-    activate();
-  }
-
-  function subtractPlayingCount() {
-    playingAnimationsNum -= 1;
-  }
-
-  function setupAnimation(animItem, element) {
-    animItem.addEventListener('destroy', removeElement);
-    animItem.addEventListener('_active', addPlayingCount);
-    animItem.addEventListener('_idle', subtractPlayingCount);
-    registeredAnimations.push({ elem: element, animation: animItem });
-    len += 1;
-  }
-
-  function loadAnimation(params) {
-    var animItem = new AnimationItem();
-    setupAnimation(animItem, null);
-    animItem.setParams(params);
-    return animItem;
-  }
-
-  function setSpeed(val, animation) {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.setSpeed(val, animation);
-    }
-  }
-
-  function setDirection(val, animation) {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.setDirection(val, animation);
-    }
-  }
-
-  function play(animation) {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.play(animation);
-    }
-  }
-  function resume(nowTime) {
-    var elapsedTime = nowTime - initTime;
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.advanceTime(elapsedTime);
-    }
-    initTime = nowTime;
-    if (playingAnimationsNum && !_isFrozen) {
-      window.requestAnimationFrame(resume);
-    } else {
-      _stopped = true;
-    }
-  }
-
-  function first(nowTime) {
-    initTime = nowTime;
-    window.requestAnimationFrame(resume);
-  }
-
-  function pause(animation) {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.pause(animation);
-    }
-  }
-
-  function goToAndStop(value, isFrame, animation) {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
-    }
-  }
-
-  function stop(animation) {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.stop(animation);
-    }
-  }
-
-  function togglePause(animation) {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.togglePause(animation);
-    }
-  }
-
-  function destroy(animation) {
-    var i;
-    for (i = (len - 1); i >= 0; i -= 1) {
-      registeredAnimations[i].animation.destroy(animation);
-    }
-  }
-
-  function searchAnimations(animationData, standalone, renderer) {
-    var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')),
-      [].slice.call(document.getElementsByClassName('bodymovin')));
-    var i;
-    var lenAnims = animElements.length;
-    for (i = 0; i < lenAnims; i += 1) {
-      if (renderer) {
-        animElements[i].setAttribute('data-bm-type', renderer);
-      }
-      registerAnimation(animElements[i], animationData);
-    }
-    if (standalone && lenAnims === 0) {
-      if (!renderer) {
-        renderer = 'svg';
-      }
-      var body = document.getElementsByTagName('body')[0];
-      body.innerText = '';
-      var div = createTag('div');
-      div.style.width = '100%';
-      div.style.height = '100%';
-      div.setAttribute('data-bm-type', renderer);
-      body.appendChild(div);
-      registerAnimation(div, animationData);
-    }
-  }
-
-  function resize() {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.resize();
-    }
-  }
-
-  function activate() {
-    if (!_isFrozen && playingAnimationsNum) {
-      if (_stopped) {
-        window.requestAnimationFrame(first);
-        _stopped = false;
-      }
-    }
-  }
-
-  function freeze() {
-    _isFrozen = true;
-  }
-
-  function unfreeze() {
-    _isFrozen = false;
-    activate();
-  }
-
-  function setVolume(val, animation) {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.setVolume(val, animation);
-    }
-  }
-
-  function mute(animation) {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.mute(animation);
-    }
-  }
-
-  function unmute(animation) {
-    var i;
-    for (i = 0; i < len; i += 1) {
-      registeredAnimations[i].animation.unmute(animation);
-    }
-  }
-
-  moduleOb.registerAnimation = registerAnimation;
-  moduleOb.loadAnimation = loadAnimation;
-  moduleOb.setSpeed = setSpeed;
-  moduleOb.setDirection = setDirection;
-  moduleOb.play = play;
-  moduleOb.pause = pause;
-  moduleOb.stop = stop;
-  moduleOb.togglePause = togglePause;
-  moduleOb.searchAnimations = searchAnimations;
-  moduleOb.resize = resize;
-  // moduleOb.start = start;
-  moduleOb.goToAndStop = goToAndStop;
-  moduleOb.destroy = destroy;
-  moduleOb.freeze = freeze;
-  moduleOb.unfreeze = unfreeze;
-  moduleOb.setVolume = setVolume;
-  moduleOb.mute = mute;
-  moduleOb.unmute = unmute;
-  moduleOb.getRegisteredAnimations = getRegisteredAnimations;
-  return moduleOb;
-}());
-
-/* eslint-disable */
-const BezierFactory = (function () {
-  /**
-     * BezierEasing - use bezier curve for transition easing function
-     * by Gaëtan Renaudeau 2014 - 2015 – MIT License
-     *
-     * Credits: is based on Firefox's nsSMILKeySpline.cpp
-     * Usage:
-     * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
-     * spline.get(x) => returns the easing value | x must be in [0, 1] range
-     *
-     */
-
-  var ob = {};
-  ob.getBezierEasing = getBezierEasing;
-  var beziers = {};
-
-  function getBezierEasing(a, b, c, d, nm) {
-    var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
-    if (beziers[str]) {
-      return beziers[str];
-    }
-    var bezEasing = new BezierEasing([a, b, c, d]);
-    beziers[str] = bezEasing;
-    return bezEasing;
-  }
-
-  // These values are established by empiricism with tests (tradeoff: performance VS precision)
-  var NEWTON_ITERATIONS = 4;
-  var NEWTON_MIN_SLOPE = 0.001;
-  var SUBDIVISION_PRECISION = 0.0000001;
-  var SUBDIVISION_MAX_ITERATIONS = 10;
-
-  var kSplineTableSize = 11;
-  var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
-
-  var float32ArraySupported = typeof Float32Array === 'function';
-
-  function A(aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
-  function B(aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
-  function C(aA1) { return 3.0 * aA1; }
-
-  // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
-  function calcBezier(aT, aA1, aA2) {
-    return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
-  }
-
-  // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
-  function getSlope(aT, aA1, aA2) {
-    return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
-  }
-
-  function binarySubdivide(aX, aA, aB, mX1, mX2) {
-    var currentX,
-      currentT,
-      i = 0;
-    do {
-      currentT = aA + (aB - aA) / 2.0;
-      currentX = calcBezier(currentT, mX1, mX2) - aX;
-      if (currentX > 0.0) {
-        aB = currentT;
-      } else {
-        aA = currentT;
-      }
-    } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
-    return currentT;
-  }
-
-  function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
-    for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
-      var currentSlope = getSlope(aGuessT, mX1, mX2);
-      if (currentSlope === 0.0) return aGuessT;
-      var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
-      aGuessT -= currentX / currentSlope;
-    }
-    return aGuessT;
-  }
-
-  /**
-     * points is an array of [ mX1, mY1, mX2, mY2 ]
-     */
-  function BezierEasing(points) {
-    this._p = points;
-    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
-    this._precomputed = false;
-
-    this.get = this.get.bind(this);
-  }
-
-  BezierEasing.prototype = {
-
-    get: function (x) {
-      var mX1 = this._p[0],
-        mY1 = this._p[1],
-        mX2 = this._p[2],
-        mY2 = this._p[3];
-      if (!this._precomputed) this._precompute();
-      if (mX1 === mY1 && mX2 === mY2) return x; // linear
-      // Because JavaScript number are imprecise, we should guarantee the extremes are right.
-      if (x === 0) return 0;
-      if (x === 1) return 1;
-      return calcBezier(this._getTForX(x), mY1, mY2);
-    },
-
-    // Private part
-
-    _precompute: function () {
-      var mX1 = this._p[0],
-        mY1 = this._p[1],
-        mX2 = this._p[2],
-        mY2 = this._p[3];
-      this._precomputed = true;
-      if (mX1 !== mY1 || mX2 !== mY2) { this._calcSampleValues(); }
-    },
-
-    _calcSampleValues: function () {
-      var mX1 = this._p[0],
-        mX2 = this._p[2];
-      for (var i = 0; i < kSplineTableSize; ++i) {
-        this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
-      }
-    },
-
-    /**
-         * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
-         */
-    _getTForX: function (aX) {
-      var mX1 = this._p[0],
-        mX2 = this._p[2],
-        mSampleValues = this._mSampleValues;
-
-      var intervalStart = 0.0;
-      var currentSample = 1;
-      var lastSample = kSplineTableSize - 1;
-
-      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
-        intervalStart += kSampleStepSize;
-      }
-      --currentSample;
-
-      // Interpolate to provide an initial guess for t
-      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
-      var guessForT = intervalStart + dist * kSampleStepSize;
-
-      var initialSlope = getSlope(guessForT, mX1, mX2);
-      if (initialSlope >= NEWTON_MIN_SLOPE) {
-        return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
-      } if (initialSlope === 0.0) {
-        return guessForT;
-      }
-      return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
-    },
-  };
-
-  return ob;
-}());
-
-const pooling = (function () {
-  function double(arr) {
-    return arr.concat(createSizedArray(arr.length));
-  }
-
-  return {
-    double: double,
-  };
-}());
-
-const poolFactory = (function () {
-  return function (initialLength, _create, _release) {
-    var _length = 0;
-    var _maxLength = initialLength;
-    var pool = createSizedArray(_maxLength);
-
-    var ob = {
-      newElement: newElement,
-      release: release,
-    };
-
-    function newElement() {
-      var element;
-      if (_length) {
-        _length -= 1;
-        element = pool[_length];
-      } else {
-        element = _create();
-      }
-      return element;
-    }
-
-    function release(element) {
-      if (_length === _maxLength) {
-        pool = pooling.double(pool);
-        _maxLength *= 2;
-      }
-      if (_release) {
-        _release(element);
-      }
-      pool[_length] = element;
-      _length += 1;
-    }
-
-    return ob;
-  };
-}());
-
-const bezierLengthPool = (function () {
-  function create() {
-    return {
-      addedLength: 0,
-      percents: createTypedArray('float32', getDefaultCurveSegments()),
-      lengths: createTypedArray('float32', getDefaultCurveSegments()),
-    };
-  }
-  return poolFactory(8, create);
-}());
-
-const segmentsLengthPool = (function () {
-  function create() {
-    return {
-      lengths: [],
-      totalLength: 0,
-    };
-  }
-
-  function release(element) {
-    var i;
-    var len = element.lengths.length;
-    for (i = 0; i < len; i += 1) {
-      bezierLengthPool.release(element.lengths[i]);
-    }
-    element.lengths.length = 0;
-  }
-
-  return poolFactory(8, create, release);
-}());
-
-function bezFunction() {
-  var math = Math;
-
-  function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
-    var det1 = (x1 * y2) + (y1 * x3) + (x2 * y3) - (x3 * y2) - (y3 * x1) - (x2 * y1);
-    return det1 > -0.001 && det1 < 0.001;
-  }
-
-  function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
-    if (z1 === 0 && z2 === 0 && z3 === 0) {
-      return pointOnLine2D(x1, y1, x2, y2, x3, y3);
-    }
-    var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
-    var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
-    var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
-    var diffDist;
-    if (dist1 > dist2) {
-      if (dist1 > dist3) {
-        diffDist = dist1 - dist2 - dist3;
-      } else {
-        diffDist = dist3 - dist2 - dist1;
-      }
-    } else if (dist3 > dist2) {
-      diffDist = dist3 - dist2 - dist1;
-    } else {
-      diffDist = dist2 - dist1 - dist3;
-    }
-    return diffDist > -0.0001 && diffDist < 0.0001;
-  }
-
-  var getBezierLength = (function () {
-    return function (pt1, pt2, pt3, pt4) {
-      var curveSegments = getDefaultCurveSegments();
-      var k;
-      var i;
-      var len;
-      var ptCoord;
-      var perc;
-      var addedLength = 0;
-      var ptDistance;
-      var point = [];
-      var lastPoint = [];
-      var lengthData = bezierLengthPool.newElement();
-      len = pt3.length;
-      for (k = 0; k < curveSegments; k += 1) {
-        perc = k / (curveSegments - 1);
-        ptDistance = 0;
-        for (i = 0; i < len; i += 1) {
-          ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
-          point[i] = ptCoord;
-          if (lastPoint[i] !== null) {
-            ptDistance += bmPow(point[i] - lastPoint[i], 2);
-          }
-          lastPoint[i] = point[i];
-        }
-        if (ptDistance) {
-          ptDistance = bmSqrt(ptDistance);
-          addedLength += ptDistance;
-        }
-        lengthData.percents[k] = perc;
-        lengthData.lengths[k] = addedLength;
-      }
-      lengthData.addedLength = addedLength;
-      return lengthData;
-    };
-  }());
-
-  function getSegmentsLength(shapeData) {
-    var segmentsLength = segmentsLengthPool.newElement();
-    var closed = shapeData.c;
-    var pathV = shapeData.v;
-    var pathO = shapeData.o;
-    var pathI = shapeData.i;
-    var i;
-    var len = shapeData._length;
-    var lengths = segmentsLength.lengths;
-    var totalLength = 0;
-    for (i = 0; i < len - 1; i += 1) {
-      lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
-      totalLength += lengths[i].addedLength;
-    }
-    if (closed && len) {
-      lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
-      totalLength += lengths[i].addedLength;
-    }
-    segmentsLength.totalLength = totalLength;
-    return segmentsLength;
-  }
-
-  function BezierData(length) {
-    this.segmentLength = 0;
-    this.points = new Array(length);
-  }
-
-  function PointData(partial, point) {
-    this.partialLength = partial;
-    this.point = point;
-  }
-
-  var buildBezierData = (function () {
-    var storedData = {};
-
-    return function (pt1, pt2, pt3, pt4) {
-      var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
-      if (!storedData[bezierName]) {
-        var curveSegments = getDefaultCurveSegments();
-        var k;
-        var i;
-        var len;
-        var ptCoord;
-        var perc;
-        var addedLength = 0;
-        var ptDistance;
-        var point;
-        var lastPoint = null;
-        if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
-          curveSegments = 2;
-        }
-        var bezierData = new BezierData(curveSegments);
-        len = pt3.length;
-        for (k = 0; k < curveSegments; k += 1) {
-          point = createSizedArray(len);
-          perc = k / (curveSegments - 1);
-          ptDistance = 0;
-          for (i = 0; i < len; i += 1) {
-            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
-            point[i] = ptCoord;
-            if (lastPoint !== null) {
-              ptDistance += bmPow(point[i] - lastPoint[i], 2);
-            }
-          }
-          ptDistance = bmSqrt(ptDistance);
-          addedLength += ptDistance;
-          bezierData.points[k] = new PointData(ptDistance, point);
-          lastPoint = point;
-        }
-        bezierData.segmentLength = addedLength;
-        storedData[bezierName] = bezierData;
-      }
-      return storedData[bezierName];
-    };
-  }());
-
-  function getDistancePerc(perc, bezierData) {
-    var percents = bezierData.percents;
-    var lengths = bezierData.lengths;
-    var len = percents.length;
-    var initPos = bmFloor((len - 1) * perc);
-    var lengthPos = perc * bezierData.addedLength;
-    var lPerc = 0;
-    if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
-      return percents[initPos];
-    }
-    var dir = lengths[initPos] > lengthPos ? -1 : 1;
-    var flag = true;
-    while (flag) {
-      if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
-        lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
-        flag = false;
-      } else {
-        initPos += dir;
-      }
-      if (initPos < 0 || initPos >= len - 1) {
-        // FIX for TypedArrays that don't store floating point values with enough accuracy
-        if (initPos === len - 1) {
-          return percents[initPos];
-        }
-        flag = false;
-      }
-    }
-    return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
-  }
-
-  function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
-    var t1 = getDistancePerc(percent, bezierData);
-    var u1 = 1 - t1;
-    var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
-    var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
-    return [ptX, ptY];
-  }
-
-  var bezierSegmentPoints = createTypedArray('float32', 8);
-
-  function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
-    if (startPerc < 0) {
-      startPerc = 0;
-    } else if (startPerc > 1) {
-      startPerc = 1;
-    }
-    var t0 = getDistancePerc(startPerc, bezierData);
-    endPerc = endPerc > 1 ? 1 : endPerc;
-    var t1 = getDistancePerc(endPerc, bezierData);
-    var i;
-    var len = pt1.length;
-    var u0 = 1 - t0;
-    var u1 = 1 - t1;
-    var u0u0u0 = u0 * u0 * u0;
-    var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
-    var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
-    var t0t0t0 = t0 * t0 * t0;
-    //
-    var u0u0u1 = u0 * u0 * u1;
-    var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
-    var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
-    var t0t0t1 = t0 * t0 * t1;
-    //
-    var u0u1u1 = u0 * u1 * u1;
-    var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
-    var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
-    var t0t1t1 = t0 * t1 * t1;
-    //
-    var u1u1u1 = u1 * u1 * u1;
-    var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
-    var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
-    var t1t1t1 = t1 * t1 * t1;
-    for (i = 0; i < len; i += 1) {
-      bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-      bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-      bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-      bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
-    }
-
-    return bezierSegmentPoints;
-  }
-
-  return {
-    getSegmentsLength: getSegmentsLength,
-    getNewSegment: getNewSegment,
-    getPointInSegment: getPointInSegment,
-    buildBezierData: buildBezierData,
-    pointOnLine2D: pointOnLine2D,
-    pointOnLine3D: pointOnLine3D,
-  };
-}
-
-const bez = bezFunction();
-
-const PropertyFactory = (function () {
-  var initFrame = initialDefaultFrame;
-  var mathAbs = Math.abs;
-
-  function interpolateValue(frameNum, caching) {
-    var offsetTime = this.offsetTime;
-    var newValue;
-    if (this.propType === 'multidimensional') {
-      newValue = createTypedArray('float32', this.pv.length);
-    }
-    var iterationIndex = caching.lastIndex;
-    var i = iterationIndex;
-    var len = this.keyframes.length - 1;
-    var flag = true;
-    var keyData;
-    var nextKeyData;
-    var keyframeMetadata;
-
-    while (flag) {
-      keyData = this.keyframes[i];
-      nextKeyData = this.keyframes[i + 1];
-      if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
-        if (keyData.h) {
-          keyData = nextKeyData;
-        }
-        iterationIndex = 0;
-        break;
-      }
-      if ((nextKeyData.t - offsetTime) > frameNum) {
-        iterationIndex = i;
-        break;
-      }
-      if (i < len - 1) {
-        i += 1;
-      } else {
-        iterationIndex = 0;
-        flag = false;
-      }
-    }
-    keyframeMetadata = this.keyframesMetadata[i] || {};
-
-    var k;
-    var kLen;
-    var perc;
-    var jLen;
-    var j;
-    var fnc;
-    var nextKeyTime = nextKeyData.t - offsetTime;
-    var keyTime = keyData.t - offsetTime;
-    var endValue;
-    if (keyData.to) {
-      if (!keyframeMetadata.bezierData) {
-        keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
-      }
-      var bezierData = keyframeMetadata.bezierData;
-      if (frameNum >= nextKeyTime || frameNum < keyTime) {
-        var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
-        kLen = bezierData.points[ind].point.length;
-        for (k = 0; k < kLen; k += 1) {
-          newValue[k] = bezierData.points[ind].point[k];
-        }
-        // caching._lastKeyframeIndex = -1;
-      } else {
-        if (keyframeMetadata.__fnct) {
-          fnc = keyframeMetadata.__fnct;
-        } else {
-          fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
-          keyframeMetadata.__fnct = fnc;
-        }
-        perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
-        var distanceInLine = bezierData.segmentLength * perc;
-
-        var segmentPerc;
-        var addedLength = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastAddedLength : 0;
-        j = (caching.lastFrame < frameNum && caching._lastKeyframeIndex === i) ? caching._lastPoint : 0;
-        flag = true;
-        jLen = bezierData.points.length;
-        while (flag) {
-          addedLength += bezierData.points[j].partialLength;
-          if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
-            kLen = bezierData.points[j].point.length;
-            for (k = 0; k < kLen; k += 1) {
-              newValue[k] = bezierData.points[j].point[k];
-            }
-            break;
-          } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
-            segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
-            kLen = bezierData.points[j].point.length;
-            for (k = 0; k < kLen; k += 1) {
-              newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
-            }
-            break;
-          }
-          if (j < jLen - 1) {
-            j += 1;
-          } else {
-            flag = false;
-          }
-        }
-        caching._lastPoint = j;
-        caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
-        caching._lastKeyframeIndex = i;
-      }
-    } else {
-      var outX;
-      var outY;
-      var inX;
-      var inY;
-      var keyValue;
-      len = keyData.s.length;
-      endValue = nextKeyData.s || keyData.e;
-      if (this.sh && keyData.h !== 1) {
-        if (frameNum >= nextKeyTime) {
-          newValue[0] = endValue[0];
-          newValue[1] = endValue[1];
-          newValue[2] = endValue[2];
-        } else if (frameNum <= keyTime) {
-          newValue[0] = keyData.s[0];
-          newValue[1] = keyData.s[1];
-          newValue[2] = keyData.s[2];
-        } else {
-          var quatStart = createQuaternion(keyData.s);
-          var quatEnd = createQuaternion(endValue);
-          var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
-          quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
-        }
-      } else {
-        for (i = 0; i < len; i += 1) {
-          if (keyData.h !== 1) {
-            if (frameNum >= nextKeyTime) {
-              perc = 1;
-            } else if (frameNum < keyTime) {
-              perc = 0;
-            } else {
-              if (keyData.o.x.constructor === Array) {
-                if (!keyframeMetadata.__fnct) {
-                  keyframeMetadata.__fnct = [];
-                }
-                if (!keyframeMetadata.__fnct[i]) {
-                  outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
-                  outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
-                  inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
-                  inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
-                  fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
-                  keyframeMetadata.__fnct[i] = fnc;
-                } else {
-                  fnc = keyframeMetadata.__fnct[i];
-                }
-              } else if (!keyframeMetadata.__fnct) {
-                outX = keyData.o.x;
-                outY = keyData.o.y;
-                inX = keyData.i.x;
-                inY = keyData.i.y;
-                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
-                keyData.keyframeMetadata = fnc;
-              } else {
-                fnc = keyframeMetadata.__fnct;
-              }
-              perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
-            }
-          }
-
-          endValue = nextKeyData.s || keyData.e;
-          keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
-
-          if (this.propType === 'multidimensional') {
-            newValue[i] = keyValue;
-          } else {
-            newValue = keyValue;
-          }
-        }
-      }
-    }
-    caching.lastIndex = iterationIndex;
-    return newValue;
-  }
-
-  // based on @Toji's https://github.com/toji/gl-matrix/
-  function slerp(a, b, t) {
-    var out = [];
-    var ax = a[0];
-    var ay = a[1];
-    var az = a[2];
-    var aw = a[3];
-    var bx = b[0];
-    var by = b[1];
-    var bz = b[2];
-    var bw = b[3];
-
-    var omega;
-    var cosom;
-    var sinom;
-    var scale0;
-    var scale1;
-
-    cosom = ax * bx + ay * by + az * bz + aw * bw;
-    if (cosom < 0.0) {
-      cosom = -cosom;
-      bx = -bx;
-      by = -by;
-      bz = -bz;
-      bw = -bw;
-    }
-    if ((1.0 - cosom) > 0.000001) {
-      omega = Math.acos(cosom);
-      sinom = Math.sin(omega);
-      scale0 = Math.sin((1.0 - t) * omega) / sinom;
-      scale1 = Math.sin(t * omega) / sinom;
-    } else {
-      scale0 = 1.0 - t;
-      scale1 = t;
-    }
-    out[0] = scale0 * ax + scale1 * bx;
-    out[1] = scale0 * ay + scale1 * by;
-    out[2] = scale0 * az + scale1 * bz;
-    out[3] = scale0 * aw + scale1 * bw;
-
-    return out;
-  }
-
-  function quaternionToEuler(out, quat) {
-    var qx = quat[0];
-    var qy = quat[1];
-    var qz = quat[2];
-    var qw = quat[3];
-    var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
-    var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
-    var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
-    out[0] = heading / degToRads;
-    out[1] = attitude / degToRads;
-    out[2] = bank / degToRads;
-  }
-
-  function createQuaternion(values) {
-    var heading = values[0] * degToRads;
-    var attitude = values[1] * degToRads;
-    var bank = values[2] * degToRads;
-    var c1 = Math.cos(heading / 2);
-    var c2 = Math.cos(attitude / 2);
-    var c3 = Math.cos(bank / 2);
-    var s1 = Math.sin(heading / 2);
-    var s2 = Math.sin(attitude / 2);
-    var s3 = Math.sin(bank / 2);
-    var w = c1 * c2 * c3 - s1 * s2 * s3;
-    var x = s1 * s2 * c3 + c1 * c2 * s3;
-    var y = s1 * c2 * c3 + c1 * s2 * s3;
-    var z = c1 * s2 * c3 - s1 * c2 * s3;
-
-    return [x, y, z, w];
-  }
-
-  function getValueAtCurrentTime() {
-    var frameNum = this.comp.renderedFrame - this.offsetTime;
-    var initTime = this.keyframes[0].t - this.offsetTime;
-    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-    if (!(frameNum === this._caching.lastFrame || (this._caching.lastFrame !== initFrame && ((this._caching.lastFrame >= endTime && frameNum >= endTime) || (this._caching.lastFrame < initTime && frameNum < initTime))))) {
-      if (this._caching.lastFrame >= frameNum) {
-        this._caching._lastKeyframeIndex = -1;
-        this._caching.lastIndex = 0;
-      }
-
-      var renderResult = this.interpolateValue(frameNum, this._caching);
-      this.pv = renderResult;
-    }
-    this._caching.lastFrame = frameNum;
-    return this.pv;
-  }
-
-  function setVValue(val) {
-    var multipliedValue;
-    if (this.propType === 'unidimensional') {
-      multipliedValue = val * this.mult;
-      if (mathAbs(this.v - multipliedValue) > 0.00001) {
-        this.v = multipliedValue;
-        this._mdf = true;
-      }
-    } else {
-      var i = 0;
-      var len = this.v.length;
-      while (i < len) {
-        multipliedValue = val[i] * this.mult;
-        if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
-          this.v[i] = multipliedValue;
-          this._mdf = true;
-        }
-        i += 1;
-      }
-    }
-  }
-
-  function processEffectsSequence() {
-    if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
-      return;
-    }
-    if (this.lock) {
-      this.setVValue(this.pv);
-      return;
-    }
-    this.lock = true;
-    this._mdf = this._isFirstFrame;
-    var i;
-    var len = this.effectsSequence.length;
-    var finalValue = this.kf ? this.pv : this.data.k;
-    for (i = 0; i < len; i += 1) {
-      finalValue = this.effectsSequence[i](finalValue);
-    }
-    this.setVValue(finalValue);
-    this._isFirstFrame = false;
-    this.lock = false;
-    this.frameId = this.elem.globalData.frameId;
-  }
-
-  function addEffect(effectFunction) {
-    this.effectsSequence.push(effectFunction);
-    this.container.addDynamicProperty(this);
-  }
-
-  function ValueProperty(elem, data, mult, container) {
-    this.propType = 'unidimensional';
-    this.mult = mult || 1;
-    this.data = data;
-    this.v = mult ? data.k * mult : data.k;
-    this.pv = data.k;
-    this._mdf = false;
-    this.elem = elem;
-    this.container = container;
-    this.comp = elem.comp;
-    this.k = false;
-    this.kf = false;
-    this.vel = 0;
-    this.effectsSequence = [];
-    this._isFirstFrame = true;
-    this.getValue = processEffectsSequence;
-    this.setVValue = setVValue;
-    this.addEffect = addEffect;
-  }
-
-  function MultiDimensionalProperty(elem, data, mult, container) {
-    this.propType = 'multidimensional';
-    this.mult = mult || 1;
-    this.data = data;
-    this._mdf = false;
-    this.elem = elem;
-    this.container = container;
-    this.comp = elem.comp;
-    this.k = false;
-    this.kf = false;
-    this.frameId = -1;
-    var i;
-    var len = data.k.length;
-    this.v = createTypedArray('float32', len);
-    this.pv = createTypedArray('float32', len);
-    this.vel = createTypedArray('float32', len);
-    for (i = 0; i < len; i += 1) {
-      this.v[i] = data.k[i] * this.mult;
-      this.pv[i] = data.k[i];
-    }
-    this._isFirstFrame = true;
-    this.effectsSequence = [];
-    this.getValue = processEffectsSequence;
-    this.setVValue = setVValue;
-    this.addEffect = addEffect;
-  }
-
-  function KeyframedValueProperty(elem, data, mult, container) {
-    this.propType = 'unidimensional';
-    this.keyframes = data.k;
-    this.keyframesMetadata = [];
-    this.offsetTime = elem.data.st;
-    this.frameId = -1;
-    this._caching = {
-      lastFrame: initFrame, lastIndex: 0, value: 0, _lastKeyframeIndex: -1,
-    };
-    this.k = true;
-    this.kf = true;
-    this.data = data;
-    this.mult = mult || 1;
-    this.elem = elem;
-    this.container = container;
-    this.comp = elem.comp;
-    this.v = initFrame;
-    this.pv = initFrame;
-    this._isFirstFrame = true;
-    this.getValue = processEffectsSequence;
-    this.setVValue = setVValue;
-    this.interpolateValue = interpolateValue;
-    this.effectsSequence = [getValueAtCurrentTime.bind(this)];
-    this.addEffect = addEffect;
-  }
-
-  function KeyframedMultidimensionalProperty(elem, data, mult, container) {
-    this.propType = 'multidimensional';
-    var i;
-    var len = data.k.length;
-    var s;
-    var e;
-    var to;
-    var ti;
-    for (i = 0; i < len - 1; i += 1) {
-      if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
-        s = data.k[i].s;
-        e = data.k[i + 1].s;
-        to = data.k[i].to;
-        ti = data.k[i].ti;
-        if ((s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1])) || (s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2]))) {
-          data.k[i].to = null;
-          data.k[i].ti = null;
-        }
-        if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
-          if (s.length === 2 || (s[2] === e[2] && to[2] === 0 && ti[2] === 0)) {
-            data.k[i].to = null;
-            data.k[i].ti = null;
-          }
-        }
-      }
-    }
-    this.effectsSequence = [getValueAtCurrentTime.bind(this)];
-    this.data = data;
-    this.keyframes = data.k;
-    this.keyframesMetadata = [];
-    this.offsetTime = elem.data.st;
-    this.k = true;
-    this.kf = true;
-    this._isFirstFrame = true;
-    this.mult = mult || 1;
-    this.elem = elem;
-    this.container = container;
-    this.comp = elem.comp;
-    this.getValue = processEffectsSequence;
-    this.setVValue = setVValue;
-    this.interpolateValue = interpolateValue;
-    this.frameId = -1;
-    var arrLen = data.k[0].s.length;
-    this.v = createTypedArray('float32', arrLen);
-    this.pv = createTypedArray('float32', arrLen);
-    for (i = 0; i < arrLen; i += 1) {
-      this.v[i] = initFrame;
-      this.pv[i] = initFrame;
-    }
-    this._caching = { lastFrame: initFrame, lastIndex: 0, value: createTypedArray('float32', arrLen) };
-    this.addEffect = addEffect;
-  }
-
-  function getProp(elem, data, type, mult, container) {
-    var p;
-    if (!data.k.length) {
-      p = new ValueProperty(elem, data, mult, container);
-    } else if (typeof (data.k[0]) === 'number') {
-      p = new MultiDimensionalProperty(elem, data, mult, container);
-    } else {
-      switch (type) {
-        case 0:
-          p = new KeyframedValueProperty(elem, data, mult, container);
-          break;
-        case 1:
-          p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
-          break;
-        default:
-          break;
-      }
-    }
-    if (p.effectsSequence.length) {
-      container.addDynamicProperty(p);
-    }
-    return p;
-  }
-
-  var ob = {
-    getProp: getProp,
-  };
-  return ob;
-}());
-
-function DynamicPropertyContainer() {}
-DynamicPropertyContainer.prototype = {
-  addDynamicProperty: function (prop) {
-    if (this.dynamicProperties.indexOf(prop) === -1) {
-      this.dynamicProperties.push(prop);
-      this.container.addDynamicProperty(this);
-      this._isAnimated = true;
-    }
-  },
-  iterateDynamicProperties: function () {
-    this._mdf = false;
-    var i;
-    var len = this.dynamicProperties.length;
-    for (i = 0; i < len; i += 1) {
-      this.dynamicProperties[i].getValue();
-      if (this.dynamicProperties[i]._mdf) {
-        this._mdf = true;
-      }
-    }
-  },
-  initDynamicPropertyContainer: function (container) {
-    this.container = container;
-    this.dynamicProperties = [];
-    this._mdf = false;
-    this._isAnimated = false;
-  },
-};
-
-const pointPool = (function () {
-  function create() {
-    return createTypedArray('float32', 2);
-  }
-  return poolFactory(8, create);
-}());
-
-function ShapePath() {
-  this.c = false;
-  this._length = 0;
-  this._maxLength = 8;
-  this.v = createSizedArray(this._maxLength);
-  this.o = createSizedArray(this._maxLength);
-  this.i = createSizedArray(this._maxLength);
-}
-
-ShapePath.prototype.setPathData = function (closed, len) {
-  this.c = closed;
-  this.setLength(len);
-  var i = 0;
-  while (i < len) {
-    this.v[i] = pointPool.newElement();
-    this.o[i] = pointPool.newElement();
-    this.i[i] = pointPool.newElement();
-    i += 1;
-  }
-};
-
-ShapePath.prototype.setLength = function (len) {
-  while (this._maxLength < len) {
-    this.doubleArrayLength();
-  }
-  this._length = len;
-};
-
-ShapePath.prototype.doubleArrayLength = function () {
-  this.v = this.v.concat(createSizedArray(this._maxLength));
-  this.i = this.i.concat(createSizedArray(this._maxLength));
-  this.o = this.o.concat(createSizedArray(this._maxLength));
-  this._maxLength *= 2;
-};
-
-ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
-  var arr;
-  this._length = Math.max(this._length, pos + 1);
-  if (this._length >= this._maxLength) {
-    this.doubleArrayLength();
-  }
-  switch (type) {
-    case 'v':
-      arr = this.v;
-      break;
-    case 'i':
-      arr = this.i;
-      break;
-    case 'o':
-      arr = this.o;
-      break;
-    default:
-      arr = [];
-      break;
-  }
-  if (!arr[pos] || (arr[pos] && !replace)) {
-    arr[pos] = pointPool.newElement();
-  }
-  arr[pos][0] = x;
-  arr[pos][1] = y;
-};
-
-ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
-  this.setXYAt(vX, vY, 'v', pos, replace);
-  this.setXYAt(oX, oY, 'o', pos, replace);
-  this.setXYAt(iX, iY, 'i', pos, replace);
-};
-
-ShapePath.prototype.reverse = function () {
-  var newPath = new ShapePath();
-  newPath.setPathData(this.c, this._length);
-  var vertices = this.v;
-  var outPoints = this.o;
-  var inPoints = this.i;
-  var init = 0;
-  if (this.c) {
-    newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
-    init = 1;
-  }
-  var cnt = this._length - 1;
-  var len = this._length;
-
-  var i;
-  for (i = init; i < len; i += 1) {
-    newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
-    cnt -= 1;
-  }
-  return newPath;
-};
-
-const shapePool = (function () {
-  function create() {
-    return new ShapePath();
-  }
-
-  function release(shapePath) {
-    var len = shapePath._length;
-    var i;
-    for (i = 0; i < len; i += 1) {
-      pointPool.release(shapePath.v[i]);
-      pointPool.release(shapePath.i[i]);
-      pointPool.release(shapePath.o[i]);
-      shapePath.v[i] = null;
-      shapePath.i[i] = null;
-      shapePath.o[i] = null;
-    }
-    shapePath._length = 0;
-    shapePath.c = false;
-  }
-
-  function clone(shape) {
-    var cloned = factory.newElement();
-    var i;
-    var len = shape._length === undefined ? shape.v.length : shape._length;
-    cloned.setLength(len);
-    cloned.c = shape.c;
-
-    for (i = 0; i < len; i += 1) {
-      cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
-    }
-    return cloned;
-  }
-
-  var factory = poolFactory(4, create, release);
-  factory.clone = clone;
-
-  return factory;
-}());
-
-function ShapeCollection() {
-  this._length = 0;
-  this._maxLength = 4;
-  this.shapes = createSizedArray(this._maxLength);
-}
-
-ShapeCollection.prototype.addShape = function (shapeData) {
-  if (this._length === this._maxLength) {
-    this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
-    this._maxLength *= 2;
-  }
-  this.shapes[this._length] = shapeData;
-  this._length += 1;
-};
-
-ShapeCollection.prototype.releaseShapes = function () {
-  var i;
-  for (i = 0; i < this._length; i += 1) {
-    shapePool.release(this.shapes[i]);
-  }
-  this._length = 0;
-};
-
-const shapeCollectionPool = (function () {
-  var ob = {
-    newShapeCollection: newShapeCollection,
-    release: release,
-  };
-
-  var _length = 0;
-  var _maxLength = 4;
-  var pool = createSizedArray(_maxLength);
-
-  function newShapeCollection() {
-    var shapeCollection;
-    if (_length) {
-      _length -= 1;
-      shapeCollection = pool[_length];
-    } else {
-      shapeCollection = new ShapeCollection();
-    }
-    return shapeCollection;
-  }
-
-  function release(shapeCollection) {
-    var i;
-    var len = shapeCollection._length;
-    for (i = 0; i < len; i += 1) {
-      shapePool.release(shapeCollection.shapes[i]);
-    }
-    shapeCollection._length = 0;
-
-    if (_length === _maxLength) {
-      pool = pooling.double(pool);
-      _maxLength *= 2;
-    }
-    pool[_length] = shapeCollection;
-    _length += 1;
-  }
-
-  return ob;
-}());
-
-const ShapePropertyFactory = (function () {
-  var initFrame = -999999;
-
-  function interpolateShape(frameNum, previousValue, caching) {
-    var iterationIndex = caching.lastIndex;
-    var keyPropS;
-    var keyPropE;
-    var isHold;
-    var j;
-    var k;
-    var jLen;
-    var kLen;
-    var perc;
-    var vertexValue;
-    var kf = this.keyframes;
-    if (frameNum < kf[0].t - this.offsetTime) {
-      keyPropS = kf[0].s[0];
-      isHold = true;
-      iterationIndex = 0;
-    } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
-      keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
-      /* if(kf[kf.length - 1].s){
-                keyPropS = kf[kf.length - 1].s[0];
-            }else{
-                keyPropS = kf[kf.length - 2].e[0];
-            } */
-      isHold = true;
-    } else {
-      var i = iterationIndex;
-      var len = kf.length - 1;
-      var flag = true;
-      var keyData;
-      var nextKeyData;
-      var keyframeMetadata;
-      while (flag) {
-        keyData = kf[i];
-        nextKeyData = kf[i + 1];
-        if ((nextKeyData.t - this.offsetTime) > frameNum) {
-          break;
-        }
-        if (i < len - 1) {
-          i += 1;
-        } else {
-          flag = false;
-        }
-      }
-      keyframeMetadata = this.keyframesMetadata[i] || {};
-      isHold = keyData.h === 1;
-      iterationIndex = i;
-      if (!isHold) {
-        if (frameNum >= nextKeyData.t - this.offsetTime) {
-          perc = 1;
-        } else if (frameNum < keyData.t - this.offsetTime) {
-          perc = 0;
-        } else {
-          var fnc;
-          if (keyframeMetadata.__fnct) {
-            fnc = keyframeMetadata.__fnct;
-          } else {
-            fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
-            keyframeMetadata.__fnct = fnc;
-          }
-          perc = fnc((frameNum - (keyData.t - this.offsetTime)) / ((nextKeyData.t - this.offsetTime) - (keyData.t - this.offsetTime)));
-        }
-        keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
-      }
-      keyPropS = keyData.s[0];
-    }
-    jLen = previousValue._length;
-    kLen = keyPropS.i[0].length;
-    caching.lastIndex = iterationIndex;
-
-    for (j = 0; j < jLen; j += 1) {
-      for (k = 0; k < kLen; k += 1) {
-        vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
-        previousValue.i[j][k] = vertexValue;
-        vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
-        previousValue.o[j][k] = vertexValue;
-        vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
-        previousValue.v[j][k] = vertexValue;
-      }
-    }
-  }
-
-  function interpolateShapeCurrentTime() {
-    var frameNum = this.comp.renderedFrame - this.offsetTime;
-    var initTime = this.keyframes[0].t - this.offsetTime;
-    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
-    var lastFrame = this._caching.lastFrame;
-    if (!(lastFrame !== initFrame && ((lastFrame < initTime && frameNum < initTime) || (lastFrame > endTime && frameNum > endTime)))) {
-      /// /
-      this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
-      this.interpolateShape(frameNum, this.pv, this._caching);
-      /// /
-    }
-    this._caching.lastFrame = frameNum;
-    return this.pv;
-  }
-
-  function resetShape() {
-    this.paths = this.localShapeCollection;
-  }
-
-  function shapesEqual(shape1, shape2) {
-    if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
-      return false;
-    }
-    var i;
-    var len = shape1._length;
-    for (i = 0; i < len; i += 1) {
-      if (shape1.v[i][0] !== shape2.v[i][0]
-            || shape1.v[i][1] !== shape2.v[i][1]
-            || shape1.o[i][0] !== shape2.o[i][0]
-            || shape1.o[i][1] !== shape2.o[i][1]
-            || shape1.i[i][0] !== shape2.i[i][0]
-            || shape1.i[i][1] !== shape2.i[i][1]) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  function setVValue(newPath) {
-    if (!shapesEqual(this.v, newPath)) {
-      this.v = shapePool.clone(newPath);
-      this.localShapeCollection.releaseShapes();
-      this.localShapeCollection.addShape(this.v);
-      this._mdf = true;
-      this.paths = this.localShapeCollection;
-    }
-  }
-
-  function processEffectsSequence() {
-    if (this.elem.globalData.frameId === this.frameId) {
-      return;
-    } if (!this.effectsSequence.length) {
-      this._mdf = false;
-      return;
-    }
-    if (this.lock) {
-      this.setVValue(this.pv);
-      return;
-    }
-    this.lock = true;
-    this._mdf = false;
-    var finalValue;
-    if (this.kf) {
-      finalValue = this.pv;
-    } else if (this.data.ks) {
-      finalValue = this.data.ks.k;
-    } else {
-      finalValue = this.data.pt.k;
-    }
-    var i;
-    var len = this.effectsSequence.length;
-    for (i = 0; i < len; i += 1) {
-      finalValue = this.effectsSequence[i](finalValue);
-    }
-    this.setVValue(finalValue);
-    this.lock = false;
-    this.frameId = this.elem.globalData.frameId;
-  }
-
-  function ShapeProperty(elem, data, type) {
-    this.propType = 'shape';
-    this.comp = elem.comp;
-    this.container = elem;
-    this.elem = elem;
-    this.data = data;
-    this.k = false;
-    this.kf = false;
-    this._mdf = false;
-    var pathData = type === 3 ? data.pt.k : data.ks.k;
-    this.v = shapePool.clone(pathData);
-    this.pv = shapePool.clone(this.v);
-    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
-    this.paths = this.localShapeCollection;
-    this.paths.addShape(this.v);
-    this.reset = resetShape;
-    this.effectsSequence = [];
-  }
-
-  function addEffect(effectFunction) {
-    this.effectsSequence.push(effectFunction);
-    this.container.addDynamicProperty(this);
-  }
-
-  ShapeProperty.prototype.interpolateShape = interpolateShape;
-  ShapeProperty.prototype.getValue = processEffectsSequence;
-  ShapeProperty.prototype.setVValue = setVValue;
-  ShapeProperty.prototype.addEffect = addEffect;
-
-  function KeyframedShapeProperty(elem, data, type) {
-    this.propType = 'shape';
-    this.comp = elem.comp;
-    this.elem = elem;
-    this.container = elem;
-    this.offsetTime = elem.data.st;
-    this.keyframes = type === 3 ? data.pt.k : data.ks.k;
-    this.keyframesMetadata = [];
-    this.k = true;
-    this.kf = true;
-    var len = this.keyframes[0].s[0].i.length;
-    this.v = shapePool.newElement();
-    this.v.setPathData(this.keyframes[0].s[0].c, len);
-    this.pv = shapePool.clone(this.v);
-    this.localShapeCollection = shapeCollectionPool.newShapeCollection();
-    this.paths = this.localShapeCollection;
-    this.paths.addShape(this.v);
-    this.lastFrame = initFrame;
-    this.reset = resetShape;
-    this._caching = { lastFrame: initFrame, lastIndex: 0 };
-    this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
-  }
-  KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
-  KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
-  KeyframedShapeProperty.prototype.setVValue = setVValue;
-  KeyframedShapeProperty.prototype.addEffect = addEffect;
-
-  var EllShapeProperty = (function () {
-    var cPoint = roundCorner;
-
-    function EllShapePropertyFactory(elem, data) {
-      this.v = shapePool.newElement();
-      this.v.setPathData(true, 4);
-      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
-      this.paths = this.localShapeCollection;
-      this.localShapeCollection.addShape(this.v);
-      this.d = data.d;
-      this.elem = elem;
-      this.comp = elem.comp;
-      this.frameId = -1;
-      this.initDynamicPropertyContainer(elem);
-      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
-      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-      if (this.dynamicProperties.length) {
-        this.k = true;
-      } else {
-        this.k = false;
-        this.convertEllToPath();
-      }
-    }
-
-    EllShapePropertyFactory.prototype = {
-      reset: resetShape,
-      getValue: function () {
-        if (this.elem.globalData.frameId === this.frameId) {
-          return;
-        }
-        this.frameId = this.elem.globalData.frameId;
-        this.iterateDynamicProperties();
-
-        if (this._mdf) {
-          this.convertEllToPath();
-        }
-      },
-      convertEllToPath: function () {
-        var p0 = this.p.v[0];
-        var p1 = this.p.v[1];
-        var s0 = this.s.v[0] / 2;
-        var s1 = this.s.v[1] / 2;
-        var _cw = this.d !== 3;
-        var _v = this.v;
-        _v.v[0][0] = p0;
-        _v.v[0][1] = p1 - s1;
-        _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
-        _v.v[1][1] = p1;
-        _v.v[2][0] = p0;
-        _v.v[2][1] = p1 + s1;
-        _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
-        _v.v[3][1] = p1;
-        _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
-        _v.i[0][1] = p1 - s1;
-        _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
-        _v.i[1][1] = p1 - s1 * cPoint;
-        _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
-        _v.i[2][1] = p1 + s1;
-        _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
-        _v.i[3][1] = p1 + s1 * cPoint;
-        _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
-        _v.o[0][1] = p1 - s1;
-        _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
-        _v.o[1][1] = p1 + s1 * cPoint;
-        _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
-        _v.o[2][1] = p1 + s1;
-        _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
-        _v.o[3][1] = p1 - s1 * cPoint;
-      },
-    };
-
-    extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
-
-    return EllShapePropertyFactory;
-  }());
-
-  var StarShapeProperty = (function () {
-    function StarShapePropertyFactory(elem, data) {
-      this.v = shapePool.newElement();
-      this.v.setPathData(true, 0);
-      this.elem = elem;
-      this.comp = elem.comp;
-      this.data = data;
-      this.frameId = -1;
-      this.d = data.d;
-      this.initDynamicPropertyContainer(elem);
-      if (data.sy === 1) {
-        this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
-        this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
-        this.convertToPath = this.convertStarToPath;
-      } else {
-        this.convertToPath = this.convertPolygonToPath;
-      }
-      this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
-      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
-      this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
-      this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
-      this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
-      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
-      this.localShapeCollection.addShape(this.v);
-      this.paths = this.localShapeCollection;
-      if (this.dynamicProperties.length) {
-        this.k = true;
-      } else {
-        this.k = false;
-        this.convertToPath();
-      }
-    }
-
-    StarShapePropertyFactory.prototype = {
-      reset: resetShape,
-      getValue: function () {
-        if (this.elem.globalData.frameId === this.frameId) {
-          return;
-        }
-        this.frameId = this.elem.globalData.frameId;
-        this.iterateDynamicProperties();
-        if (this._mdf) {
-          this.convertToPath();
-        }
-      },
-      convertStarToPath: function () {
-        var numPts = Math.floor(this.pt.v) * 2;
-        var angle = (Math.PI * 2) / numPts;
-        /* this.v.v.length = numPts;
-                this.v.i.length = numPts;
-                this.v.o.length = numPts; */
-        var longFlag = true;
-        var longRad = this.or.v;
-        var shortRad = this.ir.v;
-        var longRound = this.os.v;
-        var shortRound = this.is.v;
-        var longPerimSegment = (2 * Math.PI * longRad) / (numPts * 2);
-        var shortPerimSegment = (2 * Math.PI * shortRad) / (numPts * 2);
-        var i;
-        var rad;
-        var roundness;
-        var perimSegment;
-        var currentAng = -Math.PI / 2;
-        currentAng += this.r.v;
-        var dir = this.data.d === 3 ? -1 : 1;
-        this.v._length = 0;
-        for (i = 0; i < numPts; i += 1) {
-          rad = longFlag ? longRad : shortRad;
-          roundness = longFlag ? longRound : shortRound;
-          perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
-          var x = rad * Math.cos(currentAng);
-          var y = rad * Math.sin(currentAng);
-          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
-          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
-          x += +this.p.v[0];
-          y += +this.p.v[1];
-          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
-
-          /* this.v.v[i] = [x,y];
-                    this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
-                    this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
-                    this.v._length = numPts; */
-          longFlag = !longFlag;
-          currentAng += angle * dir;
-        }
-      },
-      convertPolygonToPath: function () {
-        var numPts = Math.floor(this.pt.v);
-        var angle = (Math.PI * 2) / numPts;
-        var rad = this.or.v;
-        var roundness = this.os.v;
-        var perimSegment = (2 * Math.PI * rad) / (numPts * 4);
-        var i;
-        var currentAng = -Math.PI * 0.5;
-        var dir = this.data.d === 3 ? -1 : 1;
-        currentAng += this.r.v;
-        this.v._length = 0;
-        for (i = 0; i < numPts; i += 1) {
-          var x = rad * Math.cos(currentAng);
-          var y = rad * Math.sin(currentAng);
-          var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
-          var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
-          x += +this.p.v[0];
-          y += +this.p.v[1];
-          this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
-          currentAng += angle * dir;
-        }
-        this.paths.length = 0;
-        this.paths[0] = this.v;
-      },
-
-    };
-    extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
-
-    return StarShapePropertyFactory;
-  }());
-
-  var RectShapeProperty = (function () {
-    function RectShapePropertyFactory(elem, data) {
-      this.v = shapePool.newElement();
-      this.v.c = true;
-      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
-      this.localShapeCollection.addShape(this.v);
-      this.paths = this.localShapeCollection;
-      this.elem = elem;
-      this.comp = elem.comp;
-      this.frameId = -1;
-      this.d = data.d;
-      this.initDynamicPropertyContainer(elem);
-      this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
-      this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
-      this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
-      if (this.dynamicProperties.length) {
-        this.k = true;
-      } else {
-        this.k = false;
-        this.convertRectToPath();
-      }
-    }
-
-    RectShapePropertyFactory.prototype = {
-      convertRectToPath: function () {
-        var p0 = this.p.v[0];
-        var p1 = this.p.v[1];
-        var v0 = this.s.v[0] / 2;
-        var v1 = this.s.v[1] / 2;
-        var round = bmMin(v0, v1, this.r.v);
-        var cPoint = round * (1 - roundCorner);
-        this.v._length = 0;
-
-        if (this.d === 2 || this.d === 1) {
-          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
-          this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
-          if (round !== 0) {
-            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
-            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
-            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
-            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
-            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
-            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
-          } else {
-            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
-            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
-          }
-        } else {
-          this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
-          if (round !== 0) {
-            this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
-            this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
-            this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
-            this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
-            this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
-            this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
-            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
-          } else {
-            this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
-            this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
-            this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
-          }
-        }
-      },
-      getValue: function () {
-        if (this.elem.globalData.frameId === this.frameId) {
-          return;
-        }
-        this.frameId = this.elem.globalData.frameId;
-        this.iterateDynamicProperties();
-        if (this._mdf) {
-          this.convertRectToPath();
-        }
-      },
-      reset: resetShape,
-    };
-    extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
-
-    return RectShapePropertyFactory;
-  }());
-
-  function getShapeProp(elem, data, type) {
-    var prop;
-    if (type === 3 || type === 4) {
-      var dataProp = type === 3 ? data.pt : data.ks;
-      var keys = dataProp.k;
-      if (keys.length) {
-        prop = new KeyframedShapeProperty(elem, data, type);
-      } else {
-        prop = new ShapeProperty(elem, data, type);
-      }
-    } else if (type === 5) {
-      prop = new RectShapeProperty(elem, data);
-    } else if (type === 6) {
-      prop = new EllShapeProperty(elem, data);
-    } else if (type === 7) {
-      prop = new StarShapeProperty(elem, data);
-    }
-    if (prop.k) {
-      elem.addDynamicProperty(prop);
-    }
-    return prop;
-  }
-
-  function getConstructorFunction() {
-    return ShapeProperty;
-  }
-
-  function getKeyframedConstructorFunction() {
-    return KeyframedShapeProperty;
-  }
-
-  var ob = {};
-  ob.getShapeProp = getShapeProp;
-  ob.getConstructorFunction = getConstructorFunction;
-  ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
-  return ob;
-}());
-
-/*!
- Transformation Matrix v2.0
- (c) Epistemex 2014-2015
- www.epistemex.com
- By Ken Fyrstenberg
- Contributions by leeoniya.
- License: MIT, header required.
- */
-
-/**
- * 2D transformation matrix object initialized with identity matrix.
- *
- * The matrix can synchronize a canvas context by supplying the context
- * as an argument, or later apply current absolute transform to an
- * existing context.
- *
- * All values are handled as floating point values.
- *
- * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
- * @prop {number} a - scale x
- * @prop {number} b - shear y
- * @prop {number} c - shear x
- * @prop {number} d - scale y
- * @prop {number} e - translate x
- * @prop {number} f - translate y
- * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
- * @constructor
- */
-
-const Matrix = (function () {
-  var _cos = Math.cos;
-  var _sin = Math.sin;
-  var _tan = Math.tan;
-  var _rnd = Math.round;
-
-  function reset() {
-    this.props[0] = 1;
-    this.props[1] = 0;
-    this.props[2] = 0;
-    this.props[3] = 0;
-    this.props[4] = 0;
-    this.props[5] = 1;
-    this.props[6] = 0;
-    this.props[7] = 0;
-    this.props[8] = 0;
-    this.props[9] = 0;
-    this.props[10] = 1;
-    this.props[11] = 0;
-    this.props[12] = 0;
-    this.props[13] = 0;
-    this.props[14] = 0;
-    this.props[15] = 1;
-    return this;
-  }
-
-  function rotate(angle) {
-    if (angle === 0) {
-      return this;
-    }
-    var mCos = _cos(angle);
-    var mSin = _sin(angle);
-    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
-  }
-
-  function rotateX(angle) {
-    if (angle === 0) {
-      return this;
-    }
-    var mCos = _cos(angle);
-    var mSin = _sin(angle);
-    return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
-  }
-
-  function rotateY(angle) {
-    if (angle === 0) {
-      return this;
-    }
-    var mCos = _cos(angle);
-    var mSin = _sin(angle);
-    return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
-  }
-
-  function rotateZ(angle) {
-    if (angle === 0) {
-      return this;
-    }
-    var mCos = _cos(angle);
-    var mSin = _sin(angle);
-    return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
-  }
-
-  function shear(sx, sy) {
-    return this._t(1, sy, sx, 1, 0, 0);
-  }
-
-  function skew(ax, ay) {
-    return this.shear(_tan(ax), _tan(ay));
-  }
-
-  function skewFromAxis(ax, angle) {
-    var mCos = _cos(angle);
-    var mSin = _sin(angle);
-    return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
-      ._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)
-      ._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
-    // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
-  }
-
-  function scale(sx, sy, sz) {
-    if (!sz && sz !== 0) {
-      sz = 1;
-    }
-    if (sx === 1 && sy === 1 && sz === 1) {
-      return this;
-    }
-    return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
-  }
-
-  function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
-    this.props[0] = a;
-    this.props[1] = b;
-    this.props[2] = c;
-    this.props[3] = d;
-    this.props[4] = e;
-    this.props[5] = f;
-    this.props[6] = g;
-    this.props[7] = h;
-    this.props[8] = i;
-    this.props[9] = j;
-    this.props[10] = k;
-    this.props[11] = l;
-    this.props[12] = m;
-    this.props[13] = n;
-    this.props[14] = o;
-    this.props[15] = p;
-    return this;
-  }
-
-  function translate(tx, ty, tz) {
-    tz = tz || 0;
-    if (tx !== 0 || ty !== 0 || tz !== 0) {
-      return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
-    }
-    return this;
-  }
-
-  function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
-    var _p = this.props;
-
-    if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
-      // NOTE: commenting this condition because TurboFan deoptimizes code when present
-      // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
-      _p[12] = _p[12] * a2 + _p[15] * m2;
-      _p[13] = _p[13] * f2 + _p[15] * n2;
-      _p[14] = _p[14] * k2 + _p[15] * o2;
-      _p[15] *= p2;
-      // }
-      this._identityCalculated = false;
-      return this;
-    }
-
-    var a1 = _p[0];
-    var b1 = _p[1];
-    var c1 = _p[2];
-    var d1 = _p[3];
-    var e1 = _p[4];
-    var f1 = _p[5];
-    var g1 = _p[6];
-    var h1 = _p[7];
-    var i1 = _p[8];
-    var j1 = _p[9];
-    var k1 = _p[10];
-    var l1 = _p[11];
-    var m1 = _p[12];
-    var n1 = _p[13];
-    var o1 = _p[14];
-    var p1 = _p[15];
-
-    /* matrix order (canvas compatible):
-         * ace
-         * bdf
-         * 001
-         */
-    _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
-    _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
-    _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
-    _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
-
-    _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
-    _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
-    _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
-    _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
-
-    _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
-    _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
-    _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
-    _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
-
-    _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
-    _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
-    _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
-    _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
-
-    this._identityCalculated = false;
-    return this;
-  }
-
-  function isIdentity() {
-    if (!this._identityCalculated) {
-      this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
-      this._identityCalculated = true;
-    }
-    return this._identity;
-  }
-
-  function equals(matr) {
-    var i = 0;
-    while (i < 16) {
-      if (matr.props[i] !== this.props[i]) {
-        return false;
-      }
-      i += 1;
-    }
-    return true;
-  }
-
-  function clone(matr) {
-    var i;
-    for (i = 0; i < 16; i += 1) {
-      matr.props[i] = this.props[i];
-    }
-    return matr;
-  }
-
-  function cloneFromProps(props) {
-    var i;
-    for (i = 0; i < 16; i += 1) {
-      this.props[i] = props[i];
-    }
-  }
-
-  function applyToPoint(x, y, z) {
-    return {
-      x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
-      y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
-      z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
-    };
-    /* return {
-         x: x * me.a + y * me.c + me.e,
-         y: x * me.b + y * me.d + me.f
-         }; */
-  }
-  function applyToX(x, y, z) {
-    return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
-  }
-  function applyToY(x, y, z) {
-    return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
-  }
-  function applyToZ(x, y, z) {
-    return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
-  }
-
-  function getInverseMatrix() {
-    var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
-    var a = this.props[5] / determinant;
-    var b = -this.props[1] / determinant;
-    var c = -this.props[4] / determinant;
-    var d = this.props[0] / determinant;
-    var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
-    var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
-    var inverseMatrix = new Matrix();
-    inverseMatrix.props[0] = a;
-    inverseMatrix.props[1] = b;
-    inverseMatrix.props[4] = c;
-    inverseMatrix.props[5] = d;
-    inverseMatrix.props[12] = e;
-    inverseMatrix.props[13] = f;
-    return inverseMatrix;
-  }
-
-  function inversePoint(pt) {
-    var inverseMatrix = this.getInverseMatrix();
-    return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
-  }
-
-  function inversePoints(pts) {
-    var i;
-    var len = pts.length;
-    var retPts = [];
-    for (i = 0; i < len; i += 1) {
-      retPts[i] = inversePoint(pts[i]);
-    }
-    return retPts;
-  }
-
-  function applyToTriplePoints(pt1, pt2, pt3) {
-    var arr = createTypedArray('float32', 6);
-    if (this.isIdentity()) {
-      arr[0] = pt1[0];
-      arr[1] = pt1[1];
-      arr[2] = pt2[0];
-      arr[3] = pt2[1];
-      arr[4] = pt3[0];
-      arr[5] = pt3[1];
-    } else {
-      var p0 = this.props[0];
-      var p1 = this.props[1];
-      var p4 = this.props[4];
-      var p5 = this.props[5];
-      var p12 = this.props[12];
-      var p13 = this.props[13];
-      arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
-      arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
-      arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
-      arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
-      arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
-      arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
-    }
-    return arr;
-  }
-
-  function applyToPointArray(x, y, z) {
-    var arr;
-    if (this.isIdentity()) {
-      arr = [x, y, z];
-    } else {
-      arr = [
-        x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
-        x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
-        x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14],
-      ];
-    }
-    return arr;
-  }
-
-  function applyToPointStringified(x, y) {
-    if (this.isIdentity()) {
-      return x + ',' + y;
-    }
-    var _p = this.props;
-    return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
-  }
-
-  function toCSS() {
-    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-    /* if(this.isIdentity()) {
-            return '';
-        } */
-    var i = 0;
-    var props = this.props;
-    var cssValue = 'matrix3d(';
-    var v = 10000;
-    while (i < 16) {
-      cssValue += _rnd(props[i] * v) / v;
-      cssValue += i === 15 ? ')' : ',';
-      i += 1;
-    }
-    return cssValue;
-  }
-
-  function roundMatrixProperty(val) {
-    var v = 10000;
-    if ((val < 0.000001 && val > 0) || (val > -0.000001 && val < 0)) {
-      return _rnd(val * v) / v;
-    }
-    return val;
-  }
-
-  function to2dCSS() {
-    // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
-    /* if(this.isIdentity()) {
-            return '';
-        } */
-    var props = this.props;
-    var _a = roundMatrixProperty(props[0]);
-    var _b = roundMatrixProperty(props[1]);
-    var _c = roundMatrixProperty(props[4]);
-    var _d = roundMatrixProperty(props[5]);
-    var _e = roundMatrixProperty(props[12]);
-    var _f = roundMatrixProperty(props[13]);
-    return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
-  }
-
-  return function () {
-    this.reset = reset;
-    this.rotate = rotate;
-    this.rotateX = rotateX;
-    this.rotateY = rotateY;
-    this.rotateZ = rotateZ;
-    this.skew = skew;
-    this.skewFromAxis = skewFromAxis;
-    this.shear = shear;
-    this.scale = scale;
-    this.setTransform = setTransform;
-    this.translate = translate;
-    this.transform = transform;
-    this.applyToPoint = applyToPoint;
-    this.applyToX = applyToX;
-    this.applyToY = applyToY;
-    this.applyToZ = applyToZ;
-    this.applyToPointArray = applyToPointArray;
-    this.applyToTriplePoints = applyToTriplePoints;
-    this.applyToPointStringified = applyToPointStringified;
-    this.toCSS = toCSS;
-    this.to2dCSS = to2dCSS;
-    this.clone = clone;
-    this.cloneFromProps = cloneFromProps;
-    this.equals = equals;
-    this.inversePoints = inversePoints;
-    this.inversePoint = inversePoint;
-    this.getInverseMatrix = getInverseMatrix;
-    this._t = this.transform;
-    this.isIdentity = isIdentity;
-    this._identity = true;
-    this._identityCalculated = false;
-
-    this.props = createTypedArray('float32', 16);
-    this.reset();
-  };
-}());
-
-var standalone = '__[STANDALONE]__';
-var animationData = '__[ANIMATIONDATA]__';
-var renderer = '';
-
-function setLocation(href) {
-  setLocationHref(href);
-}
-
-function searchAnimations() {
-  if (standalone === true) {
-    animationManager.searchAnimations(animationData, standalone, renderer);
-  } else {
-    animationManager.searchAnimations();
-  }
-}
-
-function setSubframeRendering(flag) {
-  setSubframeEnabled(flag);
-}
-
-function setPrefix(prefix) {
-  setIdPrefix(prefix);
-}
-
-function loadAnimation(params) {
-  if (standalone === true) {
-    params.animationData = JSON.parse(animationData);
-  }
-  return animationManager.loadAnimation(params);
-}
-
-function setQuality(value) {
-  if (typeof value === 'string') {
-    switch (value) {
-      case 'high':
-        setDefaultCurveSegments(200);
-        break;
-      default:
-      case 'medium':
-        setDefaultCurveSegments(50);
-        break;
-      case 'low':
-        setDefaultCurveSegments(10);
-        break;
-    }
-  } else if (!isNaN(value) && value > 1) {
-    setDefaultCurveSegments(value);
-  }
-  if (getDefaultCurveSegments() >= 50) {
-    roundValues(false);
-  } else {
-    roundValues(true);
-  }
-}
-
-function inBrowser() {
-  return typeof navigator !== 'undefined';
-}
-
-function installPlugin(type, plugin) {
-  if (type === 'expressions') {
-    setExpressionsPlugin(plugin);
-  }
-}
-
-function getFactory(name) {
-  switch (name) {
-    case 'propertyFactory':
-      return PropertyFactory;
-    case 'shapePropertyFactory':
-      return ShapePropertyFactory;
-    case 'matrix':
-      return Matrix;
-    default:
-      return null;
-  }
-}
-
-lottie.play = animationManager.play;
-lottie.pause = animationManager.pause;
-lottie.setLocationHref = setLocation;
-lottie.togglePause = animationManager.togglePause;
-lottie.setSpeed = animationManager.setSpeed;
-lottie.setDirection = animationManager.setDirection;
-lottie.stop = animationManager.stop;
-lottie.searchAnimations = searchAnimations;
-lottie.registerAnimation = animationManager.registerAnimation;
-lottie.loadAnimation = loadAnimation;
-lottie.setSubframeRendering = setSubframeRendering;
-lottie.resize = animationManager.resize;
-// lottie.start = start;
-lottie.goToAndStop = animationManager.goToAndStop;
-lottie.destroy = animationManager.destroy;
-lottie.setQuality = setQuality;
-lottie.inBrowser = inBrowser;
-lottie.installPlugin = installPlugin;
-lottie.freeze = animationManager.freeze;
-lottie.unfreeze = animationManager.unfreeze;
-lottie.setVolume = animationManager.setVolume;
-lottie.mute = animationManager.mute;
-lottie.unmute = animationManager.unmute;
-lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
-lottie.useWebWorker = setWebWorker;
-lottie.setIDPrefix = setPrefix;
-lottie.__getFactory = getFactory;
-lottie.version = '[[BM_VERSION]]';
-
-function checkReady() {
-  if (document.readyState === 'complete') {
-    clearInterval(readyStateCheckInterval);
-    searchAnimations();
-  }
-}
-
-function getQueryVariable(variable) {
-  var vars = queryString.split('&');
-  for (var i = 0; i < vars.length; i += 1) {
-    var pair = vars[i].split('=');
-    if (decodeURIComponent(pair[0]) == variable) { // eslint-disable-line eqeqeq
-      return decodeURIComponent(pair[1]);
-    }
-  }
-  return null;
-}
-var queryString = '';
-if (standalone) {
-  var scripts = document.getElementsByTagName('script');
-  var index = scripts.length - 1;
-  var myScript = scripts[index] || {
-    src: '',
-  };
-  queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
-  renderer = getQueryVariable('renderer');
-}
-var readyStateCheckInterval = setInterval(checkReady, 100);
-
-// this adds bodymovin to the window object for backwards compatibility
-try {
-  if (!(typeof exports === 'object' && typeof module !== 'undefined')
-    && !(typeof define === 'function' && define.amd) // eslint-disable-line no-undef
-  ) {
-    window.bodymovin = lottie;
-  }
-} catch (err) {
-  //
-}
-
-const ShapeModifiers = (function () {
-  var ob = {};
-  var modifiers = {};
-  ob.registerModifier = registerModifier;
-  ob.getModifier = getModifier;
-
-  function registerModifier(nm, factory) {
-    if (!modifiers[nm]) {
-      modifiers[nm] = factory;
-    }
-  }
-
-  function getModifier(nm, elem, data) {
-    return new modifiers[nm](elem, data);
-  }
-
-  return ob;
-}());
-
-function ShapeModifier() {}
-ShapeModifier.prototype.initModifierProperties = function () {};
-ShapeModifier.prototype.addShapeToModifier = function () {};
-ShapeModifier.prototype.addShape = function (data) {
-  if (!this.closed) {
-    // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
-    data.sh.container.addDynamicProperty(data.sh);
-    var shapeData = { shape: data.sh, data: data, localShapeCollection: shapeCollectionPool.newShapeCollection() };
-    this.shapes.push(shapeData);
-    this.addShapeToModifier(shapeData);
-    if (this._isAnimated) {
-      data.setAsAnimated();
-    }
-  }
-};
-ShapeModifier.prototype.init = function (elem, data) {
-  this.shapes = [];
-  this.elem = elem;
-  this.initDynamicPropertyContainer(elem);
-  this.initModifierProperties(elem, data);
-  this.frameId = initialDefaultFrame;
-  this.closed = false;
-  this.k = false;
-  if (this.dynamicProperties.length) {
-    this.k = true;
-  } else {
-    this.getValue(true);
-  }
-};
-ShapeModifier.prototype.processKeys = function () {
-  if (this.elem.globalData.frameId === this.frameId) {
-    return;
-  }
-  this.frameId = this.elem.globalData.frameId;
-  this.iterateDynamicProperties();
-};
-
-extendPrototype([DynamicPropertyContainer], ShapeModifier);
-
-function TrimModifier() {
-}
-extendPrototype([ShapeModifier], TrimModifier);
-TrimModifier.prototype.initModifierProperties = function (elem, data) {
-  this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
-  this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
-  this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
-  this.sValue = 0;
-  this.eValue = 0;
-  this.getValue = this.processKeys;
-  this.m = data.m;
-  this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
-};
-
-TrimModifier.prototype.addShapeToModifier = function (shapeData) {
-  shapeData.pathsData = [];
-};
-
-TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
-  var segments = [];
-  if (e <= 1) {
-    segments.push({
-      s: s,
-      e: e,
-    });
-  } else if (s >= 1) {
-    segments.push({
-      s: s - 1,
-      e: e - 1,
-    });
-  } else {
-    segments.push({
-      s: s,
-      e: 1,
-    });
-    segments.push({
-      s: 0,
-      e: e - 1,
-    });
-  }
-  var shapeSegments = [];
-  var i;
-  var len = segments.length;
-  var segmentOb;
-  for (i = 0; i < len; i += 1) {
-    segmentOb = segments[i];
-    if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
-      var shapeS;
-      var shapeE;
-      if (segmentOb.s * totalModifierLength <= addedLength) {
-        shapeS = 0;
-      } else {
-        shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
-      }
-      if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
-        shapeE = 1;
-      } else {
-        shapeE = ((segmentOb.e * totalModifierLength - addedLength) / shapeLength);
-      }
-      shapeSegments.push([shapeS, shapeE]);
-    }
-  }
-  if (!shapeSegments.length) {
-    shapeSegments.push([0, 0]);
-  }
-  return shapeSegments;
-};
-
-TrimModifier.prototype.releasePathsData = function (pathsData) {
-  var i;
-  var len = pathsData.length;
-  for (i = 0; i < len; i += 1) {
-    segmentsLengthPool.release(pathsData[i]);
-  }
-  pathsData.length = 0;
-  return pathsData;
-};
-
-TrimModifier.prototype.processShapes = function (_isFirstFrame) {
-  var s;
-  var e;
-  if (this._mdf || _isFirstFrame) {
-    var o = (this.o.v % 360) / 360;
-    if (o < 0) {
-      o += 1;
-    }
-    if (this.s.v > 1) {
-      s = 1 + o;
-    } else if (this.s.v < 0) {
-      s = 0 + o;
-    } else {
-      s = this.s.v + o;
-    }
-    if (this.e.v > 1) {
-      e = 1 + o;
-    } else if (this.e.v < 0) {
-      e = 0 + o;
-    } else {
-      e = this.e.v + o;
-    }
-
-    if (s > e) {
-      var _s = s;
-      s = e;
-      e = _s;
-    }
-    s = Math.round(s * 10000) * 0.0001;
-    e = Math.round(e * 10000) * 0.0001;
-    this.sValue = s;
-    this.eValue = e;
-  } else {
-    s = this.sValue;
-    e = this.eValue;
-  }
-  var shapePaths;
-  var i;
-  var len = this.shapes.length;
-  var j;
-  var jLen;
-  var pathsData;
-  var pathData;
-  var totalShapeLength;
-  var totalModifierLength = 0;
-
-  if (e === s) {
-    for (i = 0; i < len; i += 1) {
-      this.shapes[i].localShapeCollection.releaseShapes();
-      this.shapes[i].shape._mdf = true;
-      this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
-      if (this._mdf) {
-        this.shapes[i].pathsData.length = 0;
-      }
-    }
-  } else if (!((e === 1 && s === 0) || (e === 0 && s === 1))) {
-    var segments = [];
-    var shapeData;
-    var localShapeCollection;
-    for (i = 0; i < len; i += 1) {
-      shapeData = this.shapes[i];
-      // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
-      if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
-        shapeData.shape.paths = shapeData.localShapeCollection;
-      } else {
-        shapePaths = shapeData.shape.paths;
-        jLen = shapePaths._length;
-        totalShapeLength = 0;
-        if (!shapeData.shape._mdf && shapeData.pathsData.length) {
-          totalShapeLength = shapeData.totalShapeLength;
-        } else {
-          pathsData = this.releasePathsData(shapeData.pathsData);
-          for (j = 0; j < jLen; j += 1) {
-            pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
-            pathsData.push(pathData);
-            totalShapeLength += pathData.totalLength;
-          }
-          shapeData.totalShapeLength = totalShapeLength;
-          shapeData.pathsData = pathsData;
-        }
-
-        totalModifierLength += totalShapeLength;
-        shapeData.shape._mdf = true;
-      }
-    }
-    var shapeS = s;
-    var shapeE = e;
-    var addedLength = 0;
-    var edges;
-    for (i = len - 1; i >= 0; i -= 1) {
-      shapeData = this.shapes[i];
-      if (shapeData.shape._mdf) {
-        localShapeCollection = shapeData.localShapeCollection;
-        localShapeCollection.releaseShapes();
-        // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
-        if (this.m === 2 && len > 1) {
-          edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
-          addedLength += shapeData.totalShapeLength;
-        } else {
-          edges = [[shapeS, shapeE]];
-        }
-        jLen = edges.length;
-        for (j = 0; j < jLen; j += 1) {
-          shapeS = edges[j][0];
-          shapeE = edges[j][1];
-          segments.length = 0;
-          if (shapeE <= 1) {
-            segments.push({
-              s: shapeData.totalShapeLength * shapeS,
-              e: shapeData.totalShapeLength * shapeE,
-            });
-          } else if (shapeS >= 1) {
-            segments.push({
-              s: shapeData.totalShapeLength * (shapeS - 1),
-              e: shapeData.totalShapeLength * (shapeE - 1),
-            });
-          } else {
-            segments.push({
-              s: shapeData.totalShapeLength * shapeS,
-              e: shapeData.totalShapeLength,
-            });
-            segments.push({
-              s: 0,
-              e: shapeData.totalShapeLength * (shapeE - 1),
-            });
-          }
-          var newShapesData = this.addShapes(shapeData, segments[0]);
-          if (segments[0].s !== segments[0].e) {
-            if (segments.length > 1) {
-              var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
-              if (lastShapeInCollection.c) {
-                var lastShape = newShapesData.pop();
-                this.addPaths(newShapesData, localShapeCollection);
-                newShapesData = this.addShapes(shapeData, segments[1], lastShape);
-              } else {
-                this.addPaths(newShapesData, localShapeCollection);
-                newShapesData = this.addShapes(shapeData, segments[1]);
-              }
-            }
-            this.addPaths(newShapesData, localShapeCollection);
-          }
-        }
-        shapeData.shape.paths = localShapeCollection;
-      }
-    }
-  } else if (this._mdf) {
-    for (i = 0; i < len; i += 1) {
-      // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
-      // Don't remove this even if it's losing cached info.
-      this.shapes[i].pathsData.length = 0;
-      this.shapes[i].shape._mdf = true;
-    }
-  }
-};
-
-TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
-  var i;
-  var len = newPaths.length;
-  for (i = 0; i < len; i += 1) {
-    localShapeCollection.addShape(newPaths[i]);
-  }
-};
-
-TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
-  shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
-  shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
-  if (newShape) {
-    shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
-  }
-  shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
-};
-
-TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
-  shapePath.setXYAt(points[1], points[5], 'o', pos);
-  shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
-  if (newShape) {
-    shapePath.setXYAt(points[0], points[4], 'v', pos);
-  }
-  shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
-};
-
-TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
-  var pathsData = shapeData.pathsData;
-  var shapePaths = shapeData.shape.paths.shapes;
-  var i;
-  var len = shapeData.shape.paths._length;
-  var j;
-  var jLen;
-  var addedLength = 0;
-  var currentLengthData;
-  var segmentCount;
-  var lengths;
-  var segment;
-  var shapes = [];
-  var initPos;
-  var newShape = true;
-  if (!shapePath) {
-    shapePath = shapePool.newElement();
-    segmentCount = 0;
-    initPos = 0;
-  } else {
-    segmentCount = shapePath._length;
-    initPos = shapePath._length;
-  }
-  shapes.push(shapePath);
-  for (i = 0; i < len; i += 1) {
-    lengths = pathsData[i].lengths;
-    shapePath.c = shapePaths[i].c;
-    jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
-    for (j = 1; j < jLen; j += 1) {
-      currentLengthData = lengths[j - 1];
-      if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
-        addedLength += currentLengthData.addedLength;
-        shapePath.c = false;
-      } else if (addedLength > shapeSegment.e) {
-        shapePath.c = false;
-        break;
-      } else {
-        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
-          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
-          newShape = false;
-        } else {
-          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
-          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
-          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-          newShape = false;
-          shapePath.c = false;
-        }
-        addedLength += currentLengthData.addedLength;
-        segmentCount += 1;
-      }
-    }
-    if (shapePaths[i].c && lengths.length) {
-      currentLengthData = lengths[j - 1];
-      if (addedLength <= shapeSegment.e) {
-        var segmentLength = lengths[j - 1].addedLength;
-        if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
-          this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
-          newShape = false;
-        } else {
-          segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
-          this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
-          // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
-          newShape = false;
-          shapePath.c = false;
-        }
-      } else {
-        shapePath.c = false;
-      }
-      addedLength += currentLengthData.addedLength;
-      segmentCount += 1;
-    }
-    if (shapePath._length) {
-      shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
-      shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
-    }
-    if (addedLength > shapeSegment.e) {
-      break;
-    }
-    if (i < len - 1) {
-      shapePath = shapePool.newElement();
-      newShape = true;
-      shapes.push(shapePath);
-      segmentCount = 0;
-    }
-  }
-  return shapes;
-};
-
-function PuckerAndBloatModifier() {}
-extendPrototype([ShapeModifier], PuckerAndBloatModifier);
-PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
-  this.getValue = this.processKeys;
-  this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
-  this._isAnimated = !!this.amount.effectsSequence.length;
-};
-
-PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
-  var percent = amount / 100;
-  var centerPoint = [0, 0];
-  var pathLength = path._length;
-  var i = 0;
-  for (i = 0; i < pathLength; i += 1) {
-    centerPoint[0] += path.v[i][0];
-    centerPoint[1] += path.v[i][1];
-  }
-  centerPoint[0] /= pathLength;
-  centerPoint[1] /= pathLength;
-  var clonedPath = shapePool.newElement();
-  clonedPath.c = path.c;
-  var vX;
-  var vY;
-  var oX;
-  var oY;
-  var iX;
-  var iY;
-  for (i = 0; i < pathLength; i += 1) {
-    vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
-    vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
-    oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
-    oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
-    iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
-    iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
-    clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
-  }
-  return clonedPath;
-};
-
-PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
-  var shapePaths;
-  var i;
-  var len = this.shapes.length;
-  var j;
-  var jLen;
-  var amount = this.amount.v;
-
-  if (amount !== 0) {
-    var shapeData;
-    var localShapeCollection;
-    for (i = 0; i < len; i += 1) {
-      shapeData = this.shapes[i];
-      localShapeCollection = shapeData.localShapeCollection;
-      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
-        localShapeCollection.releaseShapes();
-        shapeData.shape._mdf = true;
-        shapePaths = shapeData.shape.paths.shapes;
-        jLen = shapeData.shape.paths._length;
-        for (j = 0; j < jLen; j += 1) {
-          localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
-        }
-      }
-      shapeData.shape.paths = shapeData.localShapeCollection;
-    }
-  }
-  if (!this.dynamicProperties.length) {
-    this._mdf = false;
-  }
-};
-
-const TransformPropertyFactory = (function () {
-  var defaultVector = [0, 0];
-
-  function applyToMatrix(mat) {
-    var _mdf = this._mdf;
-    this.iterateDynamicProperties();
-    this._mdf = this._mdf || _mdf;
-    if (this.a) {
-      mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
-    }
-    if (this.s) {
-      mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
-    }
-    if (this.sk) {
-      mat.skewFromAxis(-this.sk.v, this.sa.v);
-    }
-    if (this.r) {
-      mat.rotate(-this.r.v);
-    } else {
-      mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
-        .rotateY(this.or.v[1])
-        .rotateX(this.or.v[0]);
-    }
-    if (this.data.p.s) {
-      if (this.data.p.z) {
-        mat.translate(this.px.v, this.py.v, -this.pz.v);
-      } else {
-        mat.translate(this.px.v, this.py.v, 0);
-      }
-    } else {
-      mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
-    }
-  }
-  function processKeys(forceRender) {
-    if (this.elem.globalData.frameId === this.frameId) {
-      return;
-    }
-    if (this._isDirty) {
-      this.precalculateMatrix();
-      this._isDirty = false;
-    }
-
-    this.iterateDynamicProperties();
-
-    if (this._mdf || forceRender) {
-      var frameRate;
-      this.v.cloneFromProps(this.pre.props);
-      if (this.appliedTransformations < 1) {
-        this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
-      }
-      if (this.appliedTransformations < 2) {
-        this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
-      }
-      if (this.sk && this.appliedTransformations < 3) {
-        this.v.skewFromAxis(-this.sk.v, this.sa.v);
-      }
-      if (this.r && this.appliedTransformations < 4) {
-        this.v.rotate(-this.r.v);
-      } else if (!this.r && this.appliedTransformations < 4) {
-        this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
-          .rotateY(this.or.v[1])
-          .rotateX(this.or.v[0]);
-      }
-      if (this.autoOriented) {
-        var v1;
-        var v2;
-        frameRate = this.elem.globalData.frameRate;
-        if (this.p && this.p.keyframes && this.p.getValueAtTime) {
-          if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
-            v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
-            v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
-          } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
-            v1 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t / frameRate), 0);
-            v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
-          } else {
-            v1 = this.p.pv;
-            v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
-          }
-        } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
-          v1 = [];
-          v2 = [];
-          var px = this.px;
-          var py = this.py;
-          if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
-            v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
-            v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
-            v2[0] = px.getValueAtTime((px.keyframes[0].t) / frameRate, 0);
-            v2[1] = py.getValueAtTime((py.keyframes[0].t) / frameRate, 0);
-          } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
-            v1[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t / frameRate), 0);
-            v1[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t / frameRate), 0);
-            v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
-            v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
-          } else {
-            v1 = [px.pv, py.pv];
-            v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
-            v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
-          }
-        } else {
-          v2 = defaultVector;
-          v1 = v2;
-        }
-        this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
-      }
-      if (this.data.p && this.data.p.s) {
-        if (this.data.p.z) {
-          this.v.translate(this.px.v, this.py.v, -this.pz.v);
-        } else {
-          this.v.translate(this.px.v, this.py.v, 0);
-        }
-      } else {
-        this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
-      }
-    }
-    this.frameId = this.elem.globalData.frameId;
-  }
-
-  function precalculateMatrix() {
-    if (!this.a.k) {
-      this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
-      this.appliedTransformations = 1;
-    } else {
-      return;
-    }
-    if (!this.s.effectsSequence.length) {
-      this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
-      this.appliedTransformations = 2;
-    } else {
-      return;
-    }
-    if (this.sk) {
-      if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
-        this.pre.skewFromAxis(-this.sk.v, this.sa.v);
-        this.appliedTransformations = 3;
-      } else {
-        return;
-      }
-    }
-    if (this.r) {
-      if (!this.r.effectsSequence.length) {
-        this.pre.rotate(-this.r.v);
-        this.appliedTransformations = 4;
-      }
-    } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
-      this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2])
-        .rotateY(this.or.v[1])
-        .rotateX(this.or.v[0]);
-      this.appliedTransformations = 4;
-    }
-  }
-
-  function autoOrient() {
-    //
-    // var prevP = this.getValueAtTime();
-  }
-
-  function addDynamicProperty(prop) {
-    this._addDynamicProperty(prop);
-    this.elem.addDynamicProperty(prop);
-    this._isDirty = true;
-  }
-
-  function TransformProperty(elem, data, container) {
-    this.elem = elem;
-    this.frameId = -1;
-    this.propType = 'transform';
-    this.data = data;
-    this.v = new Matrix();
-    // Precalculated matrix with non animated properties
-    this.pre = new Matrix();
-    this.appliedTransformations = 0;
-    this.initDynamicPropertyContainer(container || elem);
-    if (data.p && data.p.s) {
-      this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
-      this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
-      if (data.p.z) {
-        this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
-      }
-    } else {
-      this.p = PropertyFactory.getProp(elem, data.p || { k: [0, 0, 0] }, 1, 0, this);
-    }
-    if (data.rx) {
-      this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
-      this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
-      this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
-      if (data.or.k[0].ti) {
-        var i;
-        var len = data.or.k.length;
-        for (i = 0; i < len; i += 1) {
-          data.or.k[i].to = null;
-          data.or.k[i].ti = null;
-        }
-      }
-      this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
-      // sh Indicates it needs to be capped between -180 and 180
-      this.or.sh = true;
-    } else {
-      this.r = PropertyFactory.getProp(elem, data.r || { k: 0 }, 0, degToRads, this);
-    }
-    if (data.sk) {
-      this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
-      this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
-    }
-    this.a = PropertyFactory.getProp(elem, data.a || { k: [0, 0, 0] }, 1, 0, this);
-    this.s = PropertyFactory.getProp(elem, data.s || { k: [100, 100, 100] }, 1, 0.01, this);
-    // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
-    if (data.o) {
-      this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
-    } else {
-      this.o = { _mdf: false, v: 1 };
-    }
-    this._isDirty = true;
-    if (!this.dynamicProperties.length) {
-      this.getValue(true);
-    }
-  }
-
-  TransformProperty.prototype = {
-    applyToMatrix: applyToMatrix,
-    getValue: processKeys,
-    precalculateMatrix: precalculateMatrix,
-    autoOrient: autoOrient,
-  };
-
-  extendPrototype([DynamicPropertyContainer], TransformProperty);
-  TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
-  TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
-
-  function getTransformProperty(elem, data, container) {
-    return new TransformProperty(elem, data, container);
-  }
-
-  return {
-    getTransformProperty: getTransformProperty,
-  };
-}());
-
-function RepeaterModifier() {}
-extendPrototype([ShapeModifier], RepeaterModifier);
-
-RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
-  this.getValue = this.processKeys;
-  this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
-  this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
-  this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
-  this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
-  this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
-  this.data = data;
-  if (!this.dynamicProperties.length) {
-    this.getValue(true);
-  }
-  this._isAnimated = !!this.dynamicProperties.length;
-  this.pMatrix = new Matrix();
-  this.rMatrix = new Matrix();
-  this.sMatrix = new Matrix();
-  this.tMatrix = new Matrix();
-  this.matrix = new Matrix();
-};
-
-RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
-  var dir = inv ? -1 : 1;
-  var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
-  var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
-  pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
-  rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
-  rMatrix.rotate(-transform.r.v * dir * perc);
-  rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
-  sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
-  sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
-  sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
-};
-
-RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
-  this.elem = elem;
-  this.arr = arr;
-  this.pos = pos;
-  this.elemsData = elemsData;
-  this._currentCopies = 0;
-  this._elements = [];
-  this._groups = [];
-  this.frameId = -1;
-  this.initDynamicPropertyContainer(elem);
-  this.initModifierProperties(elem, arr[pos]);
-  while (pos > 0) {
-    pos -= 1;
-    // this._elements.unshift(arr.splice(pos,1)[0]);
-    this._elements.unshift(arr[pos]);
-  }
-  if (this.dynamicProperties.length) {
-    this.k = true;
-  } else {
-    this.getValue(true);
-  }
-};
-
-RepeaterModifier.prototype.resetElements = function (elements) {
-  var i;
-  var len = elements.length;
-  for (i = 0; i < len; i += 1) {
-    elements[i]._processed = false;
-    if (elements[i].ty === 'gr') {
-      this.resetElements(elements[i].it);
-    }
-  }
-};
-
-RepeaterModifier.prototype.cloneElements = function (elements) {
-  var newElements = JSON.parse(JSON.stringify(elements));
-  this.resetElements(newElements);
-  return newElements;
-};
-
-RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
-  var i;
-  var len = elements.length;
-  for (i = 0; i < len; i += 1) {
-    elements[i]._render = renderFlag;
-    if (elements[i].ty === 'gr') {
-      this.changeGroupRender(elements[i].it, renderFlag);
-    }
-  }
-};
-
-RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
-  var items;
-  var itemsTransform;
-  var i;
-  var dir;
-  var cont;
-  var hasReloaded = false;
-  if (this._mdf || _isFirstFrame) {
-    var copies = Math.ceil(this.c.v);
-    if (this._groups.length < copies) {
-      while (this._groups.length < copies) {
-        var group = {
-          it: this.cloneElements(this._elements),
-          ty: 'gr',
-        };
-        group.it.push({
-          a: { a: 0, ix: 1, k: [0, 0] }, nm: 'Transform', o: { a: 0, ix: 7, k: 100 }, p: { a: 0, ix: 2, k: [0, 0] }, r: { a: 1, ix: 6, k: [{ s: 0, e: 0, t: 0 }, { s: 0, e: 0, t: 1 }] }, s: { a: 0, ix: 3, k: [100, 100] }, sa: { a: 0, ix: 5, k: 0 }, sk: { a: 0, ix: 4, k: 0 }, ty: 'tr',
-        });
-
-        this.arr.splice(0, 0, group);
-        this._groups.splice(0, 0, group);
-        this._currentCopies += 1;
-      }
-      this.elem.reloadShapes();
-      hasReloaded = true;
-    }
-    cont = 0;
-    var renderFlag;
-    for (i = 0; i <= this._groups.length - 1; i += 1) {
-      renderFlag = cont < copies;
-      this._groups[i]._render = renderFlag;
-      this.changeGroupRender(this._groups[i].it, renderFlag);
-      if (!renderFlag) {
-        var elems = this.elemsData[i].it;
-        var transformData = elems[elems.length - 1];
-        if (transformData.transform.op.v !== 0) {
-          transformData.transform.op._mdf = true;
-          transformData.transform.op.v = 0;
-        } else {
-          transformData.transform.op._mdf = false;
-        }
-      }
-      cont += 1;
-    }
-
-    this._currentCopies = copies;
-    /// /
-
-    var offset = this.o.v;
-    var offsetModulo = offset % 1;
-    var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
-    var pProps = this.pMatrix.props;
-    var rProps = this.rMatrix.props;
-    var sProps = this.sMatrix.props;
-    this.pMatrix.reset();
-    this.rMatrix.reset();
-    this.sMatrix.reset();
-    this.tMatrix.reset();
-    this.matrix.reset();
-    var iteration = 0;
-
-    if (offset > 0) {
-      while (iteration < roundOffset) {
-        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
-        iteration += 1;
-      }
-      if (offsetModulo) {
-        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
-        iteration += offsetModulo;
-      }
-    } else if (offset < 0) {
-      while (iteration > roundOffset) {
-        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
-        iteration -= 1;
-      }
-      if (offsetModulo) {
-        this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
-        iteration -= offsetModulo;
-      }
-    }
-    i = this.data.m === 1 ? 0 : this._currentCopies - 1;
-    dir = this.data.m === 1 ? 1 : -1;
-    cont = this._currentCopies;
-    var j;
-    var jLen;
-    while (cont) {
-      items = this.elemsData[i].it;
-      itemsTransform = items[items.length - 1].transform.mProps.v.props;
-      jLen = itemsTransform.length;
-      items[items.length - 1].transform.mProps._mdf = true;
-      items[items.length - 1].transform.op._mdf = true;
-      items[items.length - 1].transform.op.v = this._currentCopies === 1
-        ? this.so.v
-        : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
-
-      if (iteration !== 0) {
-        if ((i !== 0 && dir === 1) || (i !== this._currentCopies - 1 && dir === -1)) {
-          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
-        }
-        this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
-        this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
-        this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
-
-        for (j = 0; j < jLen; j += 1) {
-          itemsTransform[j] = this.matrix.props[j];
-        }
-        this.matrix.reset();
-      } else {
-        this.matrix.reset();
-        for (j = 0; j < jLen; j += 1) {
-          itemsTransform[j] = this.matrix.props[j];
-        }
-      }
-      iteration += 1;
-      cont -= 1;
-      i += dir;
-    }
-  } else {
-    cont = this._currentCopies;
-    i = 0;
-    dir = 1;
-    while (cont) {
-      items = this.elemsData[i].it;
-      itemsTransform = items[items.length - 1].transform.mProps.v.props;
-      items[items.length - 1].transform.mProps._mdf = false;
-      items[items.length - 1].transform.op._mdf = false;
-      cont -= 1;
-      i += dir;
-    }
-  }
-  return hasReloaded;
-};
-
-RepeaterModifier.prototype.addShape = function () {};
-
-function RoundCornersModifier() {}
-extendPrototype([ShapeModifier], RoundCornersModifier);
-RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
-  this.getValue = this.processKeys;
-  this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
-  this._isAnimated = !!this.rd.effectsSequence.length;
-};
-
-RoundCornersModifier.prototype.processPath = function (path, round) {
-  var clonedPath = shapePool.newElement();
-  clonedPath.c = path.c;
-  var i;
-  var len = path._length;
-  var currentV;
-  var currentI;
-  var currentO;
-  var closerV;
-  var distance;
-  var newPosPerc;
-  var index = 0;
-  var vX;
-  var vY;
-  var oX;
-  var oY;
-  var iX;
-  var iY;
-  for (i = 0; i < len; i += 1) {
-    currentV = path.v[i];
-    currentO = path.o[i];
-    currentI = path.i[i];
-    if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
-      if ((i === 0 || i === len - 1) && !path.c) {
-        clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
-        /* clonedPath.v[index] = currentV;
-                clonedPath.o[index] = currentO;
-                clonedPath.i[index] = currentI; */
-        index += 1;
-      } else {
-        if (i === 0) {
-          closerV = path.v[len - 1];
-        } else {
-          closerV = path.v[i - 1];
-        }
-        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
-        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
-        iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
-        vX = iX;
-        iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
-        vY = iY;
-        oX = vX - (vX - currentV[0]) * roundCorner;
-        oY = vY - (vY - currentV[1]) * roundCorner;
-        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
-        index += 1;
-
-        if (i === len - 1) {
-          closerV = path.v[0];
-        } else {
-          closerV = path.v[i + 1];
-        }
-        distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
-        newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
-        oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
-        vX = oX;
-        oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
-        vY = oY;
-        iX = vX - (vX - currentV[0]) * roundCorner;
-        iY = vY - (vY - currentV[1]) * roundCorner;
-        clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
-        index += 1;
-      }
-    } else {
-      clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
-      index += 1;
-    }
-  }
-  return clonedPath;
-};
-
-RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
-  var shapePaths;
-  var i;
-  var len = this.shapes.length;
-  var j;
-  var jLen;
-  var rd = this.rd.v;
-
-  if (rd !== 0) {
-    var shapeData;
-    var localShapeCollection;
-    for (i = 0; i < len; i += 1) {
-      shapeData = this.shapes[i];
-      localShapeCollection = shapeData.localShapeCollection;
-      if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
-        localShapeCollection.releaseShapes();
-        shapeData.shape._mdf = true;
-        shapePaths = shapeData.shape.paths.shapes;
-        jLen = shapeData.shape.paths._length;
-        for (j = 0; j < jLen; j += 1) {
-          localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
-        }
-      }
-      shapeData.shape.paths = shapeData.localShapeCollection;
-    }
-  }
-  if (!this.dynamicProperties.length) {
-    this._mdf = false;
-  }
-};
-
-function getFontProperties(fontData) {
-  var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
-
-  var fWeight = 'normal'; var
-    fStyle = 'normal';
-  var len = styles.length;
-  var styleName;
-  for (var i = 0; i < len; i += 1) {
-    styleName = styles[i].toLowerCase();
-    switch (styleName) {
-      case 'italic':
-        fStyle = 'italic';
-        break;
-      case 'bold':
-        fWeight = '700';
-        break;
-      case 'black':
-        fWeight = '900';
-        break;
-      case 'medium':
-        fWeight = '500';
-        break;
-      case 'regular':
-      case 'normal':
-        fWeight = '400';
-        break;
-      case 'light':
-      case 'thin':
-        fWeight = '200';
-        break;
-      default:
-        break;
-    }
-  }
-
-  return {
-    style: fStyle,
-    weight: fontData.fWeight || fWeight,
-  };
-}
-
-const FontManager = (function () {
-  var maxWaitingTime = 5000;
-  var emptyChar = {
-    w: 0,
-    size: 0,
-    shapes: [],
-    data: {
-      shapes: [],
-    },
-  };
-  var combinedCharacters = [];
-  // Hindi characters
-  combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366,
-    2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379,
-    2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
-
-  var surrogateModifiers = [
-    'd83cdffb',
-    'd83cdffc',
-    'd83cdffd',
-    'd83cdffe',
-    'd83cdfff',
-  ];
-
-  var zeroWidthJoiner = [65039, 8205];
-
-  function trimFontOptions(font) {
-    var familyArray = font.split(',');
-    var i;
-    var len = familyArray.length;
-    var enabledFamilies = [];
-    for (i = 0; i < len; i += 1) {
-      if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
-        enabledFamilies.push(familyArray[i]);
-      }
-    }
-    return enabledFamilies.join(',');
-  }
-
-  function setUpNode(font, family) {
-    var parentNode = createTag('span');
-    // Node is invisible to screen readers.
-    parentNode.setAttribute('aria-hidden', true);
-    parentNode.style.fontFamily = family;
-    var node = createTag('span');
-    // Characters that vary significantly among different fonts
-    node.innerText = 'giItT1WQy@!-/#';
-    // Visible - so we can measure it - but not on the screen
-    parentNode.style.position = 'absolute';
-    parentNode.style.left = '-10000px';
-    parentNode.style.top = '-10000px';
-    // Large font size makes even subtle changes obvious
-    parentNode.style.fontSize = '300px';
-    // Reset any font properties
-    parentNode.style.fontVariant = 'normal';
-    parentNode.style.fontStyle = 'normal';
-    parentNode.style.fontWeight = 'normal';
-    parentNode.style.letterSpacing = '0';
-    parentNode.appendChild(node);
-    document.body.appendChild(parentNode);
-
-    // Remember width with no applied web font
-    var width = node.offsetWidth;
-    node.style.fontFamily = trimFontOptions(font) + ', ' + family;
-    return { node: node, w: width, parent: parentNode };
-  }
-
-  function checkLoadedFonts() {
-    var i;
-    var len = this.fonts.length;
-    var node;
-    var w;
-    var loadedCount = len;
-    for (i = 0; i < len; i += 1) {
-      if (this.fonts[i].loaded) {
-        loadedCount -= 1;
-      } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
-        this.fonts[i].loaded = true;
-      } else {
-        node = this.fonts[i].monoCase.node;
-        w = this.fonts[i].monoCase.w;
-        if (node.offsetWidth !== w) {
-          loadedCount -= 1;
-          this.fonts[i].loaded = true;
-        } else {
-          node = this.fonts[i].sansCase.node;
-          w = this.fonts[i].sansCase.w;
-          if (node.offsetWidth !== w) {
-            loadedCount -= 1;
-            this.fonts[i].loaded = true;
-          }
-        }
-        if (this.fonts[i].loaded) {
-          this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
-          this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
-        }
-      }
-    }
-
-    if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
-      setTimeout(this.checkLoadedFontsBinded, 20);
-    } else {
-      setTimeout(this.setIsLoadedBinded, 10);
-    }
-  }
-
-  function createHelper(fontData, def) {
-    var engine = (document.body && def) ? 'svg' : 'canvas';
-    var helper;
-    var fontProps = getFontProperties(fontData);
-    if (engine === 'svg') {
-      var tHelper = createNS('text');
-      tHelper.style.fontSize = '100px';
-      // tHelper.style.fontFamily = fontData.fFamily;
-      tHelper.setAttribute('font-family', fontData.fFamily);
-      tHelper.setAttribute('font-style', fontProps.style);
-      tHelper.setAttribute('font-weight', fontProps.weight);
-      tHelper.textContent = '1';
-      if (fontData.fClass) {
-        tHelper.style.fontFamily = 'inherit';
-        tHelper.setAttribute('class', fontData.fClass);
-      } else {
-        tHelper.style.fontFamily = fontData.fFamily;
-      }
-      def.appendChild(tHelper);
-      helper = tHelper;
-    } else {
-      var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
-      tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
-      helper = tCanvasHelper;
-    }
-    function measure(text) {
-      if (engine === 'svg') {
-        helper.textContent = text;
-        return helper.getComputedTextLength();
-      }
-      return helper.measureText(text).width;
-    }
-    return {
-      measureText: measure,
-    };
-  }
-
-  function addFonts(fontData, defs) {
-    if (!fontData) {
-      this.isLoaded = true;
-      return;
-    }
-    if (this.chars) {
-      this.isLoaded = true;
-      this.fonts = fontData.list;
-      return;
-    }
-    if (!document.body) {
-      this.isLoaded = true;
-      fontData.list.forEach((data) => {
-        data.helper = createHelper(data);
-        data.cache = {};
-      });
-      this.fonts = fontData.list;
-      return;
-    }
-
-    var fontArr = fontData.list;
-    var i;
-    var len = fontArr.length;
-    var _pendingFonts = len;
-    for (i = 0; i < len; i += 1) {
-      var shouldLoadFont = true;
-      var loadedSelector;
-      var j;
-      fontArr[i].loaded = false;
-      fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
-      fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
-      if (!fontArr[i].fPath) {
-        fontArr[i].loaded = true;
-        _pendingFonts -= 1;
-      } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
-        loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
-
-        if (loadedSelector.length > 0) {
-          shouldLoadFont = false;
-        }
-
-        if (shouldLoadFont) {
-          var s = createTag('style');
-          s.setAttribute('f-forigin', fontArr[i].fOrigin);
-          s.setAttribute('f-origin', fontArr[i].origin);
-          s.setAttribute('f-family', fontArr[i].fFamily);
-          s.type = 'text/css';
-          s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
-          defs.appendChild(s);
-        }
-      } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
-        loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
-
-        for (j = 0; j < loadedSelector.length; j += 1) {
-          if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
-            // Font is already loaded
-            shouldLoadFont = false;
-          }
-        }
-
-        if (shouldLoadFont) {
-          var l = createTag('link');
-          l.setAttribute('f-forigin', fontArr[i].fOrigin);
-          l.setAttribute('f-origin', fontArr[i].origin);
-          l.type = 'text/css';
-          l.rel = 'stylesheet';
-          l.href = fontArr[i].fPath;
-          document.body.appendChild(l);
-        }
-      } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
-        loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
-
-        for (j = 0; j < loadedSelector.length; j += 1) {
-          if (fontArr[i].fPath === loadedSelector[j].src) {
-            // Font is already loaded
-            shouldLoadFont = false;
-          }
-        }
-
-        if (shouldLoadFont) {
-          var sc = createTag('link');
-          sc.setAttribute('f-forigin', fontArr[i].fOrigin);
-          sc.setAttribute('f-origin', fontArr[i].origin);
-          sc.setAttribute('rel', 'stylesheet');
-          sc.setAttribute('href', fontArr[i].fPath);
-          defs.appendChild(sc);
-        }
-      }
-      fontArr[i].helper = createHelper(fontArr[i], defs);
-      fontArr[i].cache = {};
-      this.fonts.push(fontArr[i]);
-    }
-    if (_pendingFonts === 0) {
-      this.isLoaded = true;
-    } else {
-      // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
-      // Adding this timeout seems to fix it
-      setTimeout(this.checkLoadedFonts.bind(this), 100);
-    }
-  }
-
-  function addChars(chars) {
-    if (!chars) {
-      return;
-    }
-    if (!this.chars) {
-      this.chars = [];
-    }
-    var i;
-    var len = chars.length;
-    var j;
-    var jLen = this.chars.length;
-    var found;
-    for (i = 0; i < len; i += 1) {
-      j = 0;
-      found = false;
-      while (j < jLen) {
-        if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
-          found = true;
-        }
-        j += 1;
-      }
-      if (!found) {
-        this.chars.push(chars[i]);
-        jLen += 1;
-      }
-    }
-  }
-
-  function getCharData(char, style, font) {
-    var i = 0;
-    var len = this.chars.length;
-    while (i < len) {
-      if (this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font) {
-        return this.chars[i];
-      }
-      i += 1;
-    }
-    if (((typeof char === 'string' && char.charCodeAt(0) !== 13) || !char)
-            && console
-            && console.warn // eslint-disable-line no-console
-            && !this._warned
-    ) {
-      this._warned = true;
-      console.warn('Missing character from exported characters list: ', char, style, font); // eslint-disable-line no-console
-    }
-    return emptyChar;
-  }
-
-  function measureText(char, fontName, size) {
-    var fontData = this.getFontByName(fontName);
-    var index = char.charCodeAt(0);
-    if (!fontData.cache[index + 1]) {
-      var tHelper = fontData.helper;
-      if (char === ' ') {
-        var doubleSize = tHelper.measureText('|' + char + '|');
-        var singleSize = tHelper.measureText('||');
-        fontData.cache[index + 1] = (doubleSize - singleSize) / 100;
-      } else {
-        fontData.cache[index + 1] = tHelper.measureText(char) / 100;
-      }
-    }
-    return fontData.cache[index + 1] * size;
-  }
-
-  function getFontByName(name) {
-    var i = 0;
-    var len = this.fonts.length;
-    while (i < len) {
-      if (this.fonts[i].fName === name) {
-        return this.fonts[i];
-      }
-      i += 1;
-    }
-    return this.fonts[0];
-  }
-
-  function isModifier(firstCharCode, secondCharCode) {
-    var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
-    return surrogateModifiers.indexOf(sum) !== -1;
-  }
-
-  function isZeroWidthJoiner(firstCharCode, secondCharCode) {
-    if (!secondCharCode) {
-      return firstCharCode === zeroWidthJoiner[1];
-    }
-    return firstCharCode === zeroWidthJoiner[0] && secondCharCode === zeroWidthJoiner[1];
-  }
-
-  function isCombinedCharacter(char) {
-    return combinedCharacters.indexOf(char) !== -1;
-  }
-
-  function setIsLoaded() {
-    this.isLoaded = true;
-  }
-
-  var Font = function () {
-    this.fonts = [];
-    this.chars = null;
-    this.typekitLoaded = 0;
-    this.isLoaded = false;
-    this._warned = false;
-    this.initTime = Date.now();
-    this.setIsLoadedBinded = this.setIsLoaded.bind(this);
-    this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
-  };
-  Font.isModifier = isModifier;
-  Font.isZeroWidthJoiner = isZeroWidthJoiner;
-  Font.isCombinedCharacter = isCombinedCharacter;
-
-  var fontPrototype = {
-    addChars: addChars,
-    addFonts: addFonts,
-    getCharData: getCharData,
-    getFontByName: getFontByName,
-    measureText: measureText,
-    checkLoadedFonts: checkLoadedFonts,
-    setIsLoaded: setIsLoaded,
-  };
-
-  Font.prototype = fontPrototype;
-
-  return Font;
-}());
-
-function RenderableElement() {
-
-}
-
-RenderableElement.prototype = {
-  initRenderable: function () {
-    // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
-    this.isInRange = false;
-    // layer's display state
-    this.hidden = false;
-    // If layer's transparency equals 0, it can be hidden
-    this.isTransparent = false;
-    // list of animated components
-    this.renderableComponents = [];
-  },
-  addRenderableComponent: function (component) {
-    if (this.renderableComponents.indexOf(component) === -1) {
-      this.renderableComponents.push(component);
-    }
-  },
-  removeRenderableComponent: function (component) {
-    if (this.renderableComponents.indexOf(component) !== -1) {
-      this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
-    }
-  },
-  prepareRenderableFrame: function (num) {
-    this.checkLayerLimits(num);
-  },
-  checkTransparency: function () {
-    if (this.finalTransform.mProp.o.v <= 0) {
-      if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
-        this.isTransparent = true;
-        this.hide();
-      }
-    } else if (this.isTransparent) {
-      this.isTransparent = false;
-      this.show();
-    }
-  },
-  /**
-     * @function
-     * Initializes frame related properties.
-     *
-     * @param {number} num
-     * current frame number in Layer's time
-     *
-     */
-  checkLayerLimits: function (num) {
-    if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
-      if (this.isInRange !== true) {
-        this.globalData._mdf = true;
-        this._mdf = true;
-        this.isInRange = true;
-        this.show();
-      }
-    } else if (this.isInRange !== false) {
-      this.globalData._mdf = true;
-      this.isInRange = false;
-      this.hide();
-    }
-  },
-  renderRenderable: function () {
-    var i;
-    var len = this.renderableComponents.length;
-    for (i = 0; i < len; i += 1) {
-      this.renderableComponents[i].renderFrame(this._isFirstFrame);
-    }
-    /* this.maskManager.renderFrame(this.finalTransform.mat);
-        this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
-  },
-  sourceRectAtTime: function () {
-    return {
-      top: 0,
-      left: 0,
-      width: 100,
-      height: 100,
-    };
-  },
-  getLayerSize: function () {
-    if (this.data.ty === 5) {
-      return { w: this.data.textData.width, h: this.data.textData.height };
-    }
-    return { w: this.data.width, h: this.data.height };
-  },
-};
-
-const MaskManagerInterface = (function () {
-  function MaskInterface(mask, data) {
-    this._mask = mask;
-    this._data = data;
-  }
-  Object.defineProperty(MaskInterface.prototype, 'maskPath', {
-    get: function () {
-      if (this._mask.prop.k) {
-        this._mask.prop.getValue();
-      }
-      return this._mask.prop;
-    },
-  });
-  Object.defineProperty(MaskInterface.prototype, 'maskOpacity', {
-    get: function () {
-      if (this._mask.op.k) {
-        this._mask.op.getValue();
-      }
-      return this._mask.op.v * 100;
-    },
-  });
-
-  var MaskManager = function (maskManager) {
-    var _masksInterfaces = createSizedArray(maskManager.viewData.length);
-    var i;
-    var len = maskManager.viewData.length;
-    for (i = 0; i < len; i += 1) {
-      _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
-    }
-
-    var maskFunction = function (name) {
-      i = 0;
-      while (i < len) {
-        if (maskManager.masksProperties[i].nm === name) {
-          return _masksInterfaces[i];
-        }
-        i += 1;
-      }
-      return null;
-    };
-    return maskFunction;
-  };
-  return MaskManager;
-}());
-
-const ExpressionPropertyInterface = (function () {
-  var defaultUnidimensionalValue = { pv: 0, v: 0, mult: 1 };
-  var defaultMultidimensionalValue = { pv: [0, 0, 0], v: [0, 0, 0], mult: 1 };
-
-  function completeProperty(expressionValue, property, type) {
-    Object.defineProperty(expressionValue, 'velocity', {
-      get: function () {
-        return property.getVelocityAtTime(property.comp.currentFrame);
-      },
-    });
-    expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
-    expressionValue.key = function (pos) {
-      if (!expressionValue.numKeys) {
-        return 0;
-      }
-      var value = '';
-      if ('s' in property.keyframes[pos - 1]) {
-        value = property.keyframes[pos - 1].s;
-      } else if ('e' in property.keyframes[pos - 2]) {
-        value = property.keyframes[pos - 2].e;
-      } else {
-        value = property.keyframes[pos - 2].s;
-      }
-      var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
-      valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
-      valueProp.value = type === 'unidimensional' ? value[0] : value;
-      return valueProp;
-    };
-    expressionValue.valueAtTime = property.getValueAtTime;
-    expressionValue.speedAtTime = property.getSpeedAtTime;
-    expressionValue.velocityAtTime = property.getVelocityAtTime;
-    expressionValue.propertyGroup = property.propertyGroup;
-  }
-
-  function UnidimensionalPropertyInterface(property) {
-    if (!property || !('pv' in property)) {
-      property = defaultUnidimensionalValue;
-    }
-    var mult = 1 / property.mult;
-    var val = property.pv * mult;
-    var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-    expressionValue.value = val;
-    completeProperty(expressionValue, property, 'unidimensional');
-
-    return function () {
-      if (property.k) {
-        property.getValue();
-      }
-      val = property.v * mult;
-      if (expressionValue.value !== val) {
-        expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
-        expressionValue.value = val;
-        completeProperty(expressionValue, property, 'unidimensional');
-      }
-      return expressionValue;
-    };
-  }
-
-  function MultidimensionalPropertyInterface(property) {
-    if (!property || !('pv' in property)) {
-      property = defaultMultidimensionalValue;
-    }
-    var mult = 1 / property.mult;
-    var len = (property.data && property.data.l) || property.pv.length;
-    var expressionValue = createTypedArray('float32', len);
-    var arrValue = createTypedArray('float32', len);
-    expressionValue.value = arrValue;
-    completeProperty(expressionValue, property, 'multidimensional');
-
-    return function () {
-      if (property.k) {
-        property.getValue();
-      }
-      for (var i = 0; i < len; i += 1) {
-        arrValue[i] = property.v[i] * mult;
-        expressionValue[i] = arrValue[i];
-      }
-      return expressionValue;
-    };
-  }
-
-  // TODO: try to avoid using this getter
-  function defaultGetter() {
-    return defaultUnidimensionalValue;
-  }
-
-  return function (property) {
-    if (!property) {
-      return defaultGetter;
-    } if (property.propType === 'unidimensional') {
-      return UnidimensionalPropertyInterface(property);
-    }
-    return MultidimensionalPropertyInterface(property);
-  };
-}());
-
-const TransformExpressionInterface = (function () {
-  return function (transform) {
-    function _thisFunction(name) {
-      switch (name) {
-        case 'scale':
-        case 'Scale':
-        case 'ADBE Scale':
-        case 6:
-          return _thisFunction.scale;
-        case 'rotation':
-        case 'Rotation':
-        case 'ADBE Rotation':
-        case 'ADBE Rotate Z':
-        case 10:
-          return _thisFunction.rotation;
-        case 'ADBE Rotate X':
-          return _thisFunction.xRotation;
-        case 'ADBE Rotate Y':
-          return _thisFunction.yRotation;
-        case 'position':
-        case 'Position':
-        case 'ADBE Position':
-        case 2:
-          return _thisFunction.position;
-        case 'ADBE Position_0':
-          return _thisFunction.xPosition;
-        case 'ADBE Position_1':
-          return _thisFunction.yPosition;
-        case 'ADBE Position_2':
-          return _thisFunction.zPosition;
-        case 'anchorPoint':
-        case 'AnchorPoint':
-        case 'Anchor Point':
-        case 'ADBE AnchorPoint':
-        case 1:
-          return _thisFunction.anchorPoint;
-        case 'opacity':
-        case 'Opacity':
-        case 11:
-          return _thisFunction.opacity;
-        default:
-          return null;
-      }
-    }
-    Object.defineProperty(_thisFunction, 'rotation', {
-      get: ExpressionPropertyInterface(transform.r || transform.rz),
-    });
-
-    Object.defineProperty(_thisFunction, 'zRotation', {
-      get: ExpressionPropertyInterface(transform.rz || transform.r),
-    });
-
-    Object.defineProperty(_thisFunction, 'xRotation', {
-      get: ExpressionPropertyInterface(transform.rx),
-    });
-
-    Object.defineProperty(_thisFunction, 'yRotation', {
-      get: ExpressionPropertyInterface(transform.ry),
-    });
-    Object.defineProperty(_thisFunction, 'scale', {
-      get: ExpressionPropertyInterface(transform.s),
-    });
-    var _px;
-    var _py;
-    var _pz;
-    var _transformFactory;
-    if (transform.p) {
-      _transformFactory = ExpressionPropertyInterface(transform.p);
-    } else {
-      _px = ExpressionPropertyInterface(transform.px);
-      _py = ExpressionPropertyInterface(transform.py);
-      if (transform.pz) {
-        _pz = ExpressionPropertyInterface(transform.pz);
-      }
-    }
-    Object.defineProperty(_thisFunction, 'position', {
-      get: function () {
-        if (transform.p) {
-          return _transformFactory();
-        }
-        return [
-          _px(),
-          _py(),
-          _pz ? _pz() : 0];
-      },
-    });
-
-    Object.defineProperty(_thisFunction, 'xPosition', {
-      get: ExpressionPropertyInterface(transform.px),
-    });
-
-    Object.defineProperty(_thisFunction, 'yPosition', {
-      get: ExpressionPropertyInterface(transform.py),
-    });
-
-    Object.defineProperty(_thisFunction, 'zPosition', {
-      get: ExpressionPropertyInterface(transform.pz),
-    });
-
-    Object.defineProperty(_thisFunction, 'anchorPoint', {
-      get: ExpressionPropertyInterface(transform.a),
-    });
-
-    Object.defineProperty(_thisFunction, 'opacity', {
-      get: ExpressionPropertyInterface(transform.o),
-    });
-
-    Object.defineProperty(_thisFunction, 'skew', {
-      get: ExpressionPropertyInterface(transform.sk),
-    });
-
-    Object.defineProperty(_thisFunction, 'skewAxis', {
-      get: ExpressionPropertyInterface(transform.sa),
-    });
-
-    Object.defineProperty(_thisFunction, 'orientation', {
-      get: ExpressionPropertyInterface(transform.or),
-    });
-
-    return _thisFunction;
-  };
-}());
-
-const LayerExpressionInterface = (function () {
-  function getMatrix(time) {
-    var toWorldMat = new Matrix();
-    if (time !== undefined) {
-      var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
-      propMatrix.clone(toWorldMat);
-    } else {
-      var transformMat = this._elem.finalTransform.mProp;
-      transformMat.applyToMatrix(toWorldMat);
-    }
-    return toWorldMat;
-  }
-
-  function toWorldVec(arr, time) {
-    var toWorldMat = this.getMatrix(time);
-    toWorldMat.props[12] = 0;
-    toWorldMat.props[13] = 0;
-    toWorldMat.props[14] = 0;
-    return this.applyPoint(toWorldMat, arr);
-  }
-
-  function toWorld(arr, time) {
-    var toWorldMat = this.getMatrix(time);
-    return this.applyPoint(toWorldMat, arr);
-  }
-
-  function fromWorldVec(arr, time) {
-    var toWorldMat = this.getMatrix(time);
-    toWorldMat.props[12] = 0;
-    toWorldMat.props[13] = 0;
-    toWorldMat.props[14] = 0;
-    return this.invertPoint(toWorldMat, arr);
-  }
-
-  function fromWorld(arr, time) {
-    var toWorldMat = this.getMatrix(time);
-    return this.invertPoint(toWorldMat, arr);
-  }
-
-  function applyPoint(matrix, arr) {
-    if (this._elem.hierarchy && this._elem.hierarchy.length) {
-      var i;
-      var len = this._elem.hierarchy.length;
-      for (i = 0; i < len; i += 1) {
-        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
-      }
-    }
-    return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
-  }
-
-  function invertPoint(matrix, arr) {
-    if (this._elem.hierarchy && this._elem.hierarchy.length) {
-      var i;
-      var len = this._elem.hierarchy.length;
-      for (i = 0; i < len; i += 1) {
-        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
-      }
-    }
-    return matrix.inversePoint(arr);
-  }
-
-  function fromComp(arr) {
-    var toWorldMat = new Matrix();
-    toWorldMat.reset();
-    this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
-    if (this._elem.hierarchy && this._elem.hierarchy.length) {
-      var i;
-      var len = this._elem.hierarchy.length;
-      for (i = 0; i < len; i += 1) {
-        this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
-      }
-      return toWorldMat.inversePoint(arr);
-    }
-    return toWorldMat.inversePoint(arr);
-  }
-
-  function sampleImage() {
-    return [1, 1, 1, 1];
-  }
-
-  return function (elem) {
-    var transformInterface;
-
-    function _registerMaskInterface(maskManager) {
-      _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
-    }
-    function _registerEffectsInterface(effects) {
-      _thisLayerFunction.effect = effects;
-    }
-
-    function _thisLayerFunction(name) {
-      switch (name) {
-        case 'ADBE Root Vectors Group':
-        case 'Contents':
-        case 2:
-          return _thisLayerFunction.shapeInterface;
-        case 1:
-        case 6:
-        case 'Transform':
-        case 'transform':
-        case 'ADBE Transform Group':
-          return transformInterface;
-        case 4:
-        case 'ADBE Effect Parade':
-        case 'effects':
-        case 'Effects':
-          return _thisLayerFunction.effect;
-        case 'ADBE Text Properties':
-          return _thisLayerFunction.textInterface;
-        default:
-          return null;
-      }
-    }
-    _thisLayerFunction.getMatrix = getMatrix;
-    _thisLayerFunction.invertPoint = invertPoint;
-    _thisLayerFunction.applyPoint = applyPoint;
-    _thisLayerFunction.toWorld = toWorld;
-    _thisLayerFunction.toWorldVec = toWorldVec;
-    _thisLayerFunction.fromWorld = fromWorld;
-    _thisLayerFunction.fromWorldVec = fromWorldVec;
-    _thisLayerFunction.toComp = toWorld;
-    _thisLayerFunction.fromComp = fromComp;
-    _thisLayerFunction.sampleImage = sampleImage;
-    _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem);
-    _thisLayerFunction._elem = elem;
-    transformInterface = TransformExpressionInterface(elem.finalTransform.mProp);
-    var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint');
-    Object.defineProperties(_thisLayerFunction, {
-      hasParent: {
-        get: function () {
-          return elem.hierarchy.length;
-        },
-      },
-      parent: {
-        get: function () {
-          return elem.hierarchy[0].layerInterface;
-        },
-      },
-      rotation: getDescriptor(transformInterface, 'rotation'),
-      scale: getDescriptor(transformInterface, 'scale'),
-      position: getDescriptor(transformInterface, 'position'),
-      opacity: getDescriptor(transformInterface, 'opacity'),
-      anchorPoint: anchorPointDescriptor,
-      anchor_point: anchorPointDescriptor,
-      transform: {
-        get: function () {
-          return transformInterface;
-        },
-      },
-      active: {
-        get: function () {
-          return elem.isInRange;
-        },
-      },
-    });
-
-    _thisLayerFunction.startTime = elem.data.st;
-    _thisLayerFunction.index = elem.data.ind;
-    _thisLayerFunction.source = elem.data.refId;
-    _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100;
-    _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100;
-    _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate;
-    _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate;
-    _thisLayerFunction._name = elem.data.nm;
-
-    _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
-    _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
-    return _thisLayerFunction;
-  };
-}());
-
-const propertyGroupFactory = (function () {
-  return function (interfaceFunction, parentPropertyGroup) {
-    return function (val) {
-      val = val === undefined ? 1 : val;
-      if (val <= 0) {
-        return interfaceFunction;
-      }
-      return parentPropertyGroup(val - 1);
-    };
-  };
-}());
-
-const PropertyInterface = (function () {
-  return function (propertyName, propertyGroup) {
-    var interfaceFunction = {
-      _name: propertyName,
-    };
-
-    function _propertyGroup(val) {
-      val = val === undefined ? 1 : val;
-      if (val <= 0) {
-        return interfaceFunction;
-      }
-      return propertyGroup(val - 1);
-    }
-
-    return _propertyGroup;
-  };
-}());
-
-const EffectsExpressionInterface = (function () {
-  var ob = {
-    createEffectsInterface: createEffectsInterface,
-  };
-
-  function createEffectsInterface(elem, propertyGroup) {
-    if (elem.effectsManager) {
-      var effectElements = [];
-      var effectsData = elem.data.ef;
-      var i;
-      var len = elem.effectsManager.effectElements.length;
-      for (i = 0; i < len; i += 1) {
-        effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
-      }
-
-      var effects = elem.data.ef || [];
-      var groupInterface = function (name) {
-        i = 0;
-        len = effects.length;
-        while (i < len) {
-          if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
-            return effectElements[i];
-          }
-          i += 1;
-        }
-        return null;
-      };
-      Object.defineProperty(groupInterface, 'numProperties', {
-        get: function () {
-          return effects.length;
-        },
-      });
-      return groupInterface;
-    }
-    return null;
-  }
-
-  function createGroupInterface(data, elements, propertyGroup, elem) {
-    function groupInterface(name) {
-      var effects = data.ef;
-      var i = 0;
-      var len = effects.length;
-      while (i < len) {
-        if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
-          if (effects[i].ty === 5) {
-            return effectElements[i];
-          }
-          return effectElements[i]();
-        }
-        i += 1;
-      }
-      throw new Error();
-    }
-    var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
-
-    var effectElements = [];
-    var i;
-    var len = data.ef.length;
-    for (i = 0; i < len; i += 1) {
-      if (data.ef[i].ty === 5) {
-        effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
-      } else {
-        effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
-      }
-    }
-
-    if (data.mn === 'ADBE Color Control') {
-      Object.defineProperty(groupInterface, 'color', {
-        get: function () {
-          return effectElements[0]();
-        },
-      });
-    }
-    Object.defineProperties(groupInterface, {
-      numProperties: {
-        get: function () {
-          return data.np;
-        },
-      },
-      _name: { value: data.nm },
-      propertyGroup: { value: _propertyGroup },
-    });
-    groupInterface.enabled = data.en !== 0;
-    groupInterface.active = groupInterface.enabled;
-    return groupInterface;
-  }
-
-  function createValueInterface(element, type, elem, propertyGroup) {
-    var expressionProperty = ExpressionPropertyInterface(element.p);
-    function interfaceFunction() {
-      if (type === 10) {
-        return elem.comp.compInterface(element.p.v);
-      }
-      return expressionProperty();
-    }
-
-    if (element.p.setGroupProperty) {
-      element.p.setGroupProperty(PropertyInterface('', propertyGroup));
-    }
-
-    return interfaceFunction;
-  }
-
-  return ob;
-}());
-
-const CompExpressionInterface = (function () {
-  return function (comp) {
-    function _thisLayerFunction(name) {
-      var i = 0;
-      var len = comp.layers.length;
-      while (i < len) {
-        if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
-          return comp.elements[i].layerInterface;
-        }
-        i += 1;
-      }
-      return null;
-      // return {active:false};
-    }
-    Object.defineProperty(_thisLayerFunction, '_name', { value: comp.data.nm });
-    _thisLayerFunction.layer = _thisLayerFunction;
-    _thisLayerFunction.pixelAspect = 1;
-    _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h;
-    _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w;
-    _thisLayerFunction.pixelAspect = 1;
-    _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate;
-    _thisLayerFunction.displayStartTime = 0;
-    _thisLayerFunction.numLayers = comp.layers.length;
-    return _thisLayerFunction;
-  };
-}());
-
-const ShapePathInterface = (
-
-  function () {
-    return function pathInterfaceFactory(shape, view, propertyGroup) {
-      var prop = view.sh;
-
-      function interfaceFunction(val) {
-        if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
-          return interfaceFunction.path;
-        }
-        return null;
-      }
-
-      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-      prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
-      Object.defineProperties(interfaceFunction, {
-        path: {
-          get: function () {
-            if (prop.k) {
-              prop.getValue();
-            }
-            return prop;
-          },
-        },
-        shape: {
-          get: function () {
-            if (prop.k) {
-              prop.getValue();
-            }
-            return prop;
-          },
-        },
-        _name: { value: shape.nm },
-        ix: { value: shape.ix },
-        propertyIndex: { value: shape.ix },
-        mn: { value: shape.mn },
-        propertyGroup: { value: propertyGroup },
-      });
-      return interfaceFunction;
-    };
-  }()
-);
-
-const ShapeExpressionInterface = (function () {
-  function iterateElements(shapes, view, propertyGroup) {
-    var arr = [];
-    var i;
-    var len = shapes ? shapes.length : 0;
-    for (i = 0; i < len; i += 1) {
-      if (shapes[i].ty === 'gr') {
-        arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
-      } else if (shapes[i].ty === 'fl') {
-        arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup));
-      } else if (shapes[i].ty === 'st') {
-        arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
-      } else if (shapes[i].ty === 'tm') {
-        arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
-      } else if (shapes[i].ty === 'tr') {
-        // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
-      } else if (shapes[i].ty === 'el') {
-        arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
-      } else if (shapes[i].ty === 'sr') {
-        arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup));
-      } else if (shapes[i].ty === 'sh') {
-        arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup));
-      } else if (shapes[i].ty === 'rc') {
-        arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup));
-      } else if (shapes[i].ty === 'rd') {
-        arr.push(roundedInterfaceFactory(shapes[i], view[i], propertyGroup));
-      } else if (shapes[i].ty === 'rp') {
-        arr.push(repeaterInterfaceFactory(shapes[i], view[i], propertyGroup));
-      } else if (shapes[i].ty === 'gf') {
-        arr.push(gradientFillInterfaceFactory(shapes[i], view[i], propertyGroup));
-      } else {
-        arr.push(defaultInterfaceFactory(shapes[i], view[i], propertyGroup));
-      }
-    }
-    return arr;
-  }
-
-  function contentsInterfaceFactory(shape, view, propertyGroup) {
-    var interfaces;
-    var interfaceFunction = function _interfaceFunction(value) {
-      var i = 0;
-      var len = interfaces.length;
-      while (i < len) {
-        if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
-          return interfaces[i];
-        }
-        i += 1;
-      }
-      if (typeof value === 'number') {
-        return interfaces[value - 1];
-      }
-      return null;
-    };
-
-    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-    interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
-    interfaceFunction.numProperties = interfaces.length;
-    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
-    interfaceFunction.transform = transformInterface;
-    interfaceFunction.propertyIndex = shape.cix;
-    interfaceFunction._name = shape.nm;
-
-    return interfaceFunction;
-  }
-
-  function groupInterfaceFactory(shape, view, propertyGroup) {
-    var interfaceFunction = function _interfaceFunction(value) {
-      switch (value) {
-        case 'ADBE Vectors Group':
-        case 'Contents':
-        case 2:
-          return interfaceFunction.content;
-          // Not necessary for now. Keeping them here in case a new case appears
-          // case 'ADBE Vector Transform Group':
-          // case 3:
-        default:
-          return interfaceFunction.transform;
-      }
-    };
-    interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-    var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
-    var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
-    interfaceFunction.content = content;
-    interfaceFunction.transform = transformInterface;
-    Object.defineProperty(interfaceFunction, '_name', {
-      get: function () {
-        return shape.nm;
-      },
-    });
-    // interfaceFunction.content = interfaceFunction;
-    interfaceFunction.numProperties = shape.np;
-    interfaceFunction.propertyIndex = shape.ix;
-    interfaceFunction.nm = shape.nm;
-    interfaceFunction.mn = shape.mn;
-    return interfaceFunction;
-  }
-
-  function fillInterfaceFactory(shape, view, propertyGroup) {
-    function interfaceFunction(val) {
-      if (val === 'Color' || val === 'color') {
-        return interfaceFunction.color;
-      } if (val === 'Opacity' || val === 'opacity') {
-        return interfaceFunction.opacity;
-      }
-      return null;
-    }
-    Object.defineProperties(interfaceFunction, {
-      color: {
-        get: ExpressionPropertyInterface(view.c),
-      },
-      opacity: {
-        get: ExpressionPropertyInterface(view.o),
-      },
-      _name: { value: shape.nm },
-      mn: { value: shape.mn },
-    });
-
-    view.c.setGroupProperty(PropertyInterface('Color', propertyGroup));
-    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
-    return interfaceFunction;
-  }
-
-  function gradientFillInterfaceFactory(shape, view, propertyGroup) {
-    function interfaceFunction(val) {
-      if (val === 'Start Point' || val === 'start point') {
-        return interfaceFunction.startPoint;
-      }
-      if (val === 'End Point' || val === 'end point') {
-        return interfaceFunction.endPoint;
-      }
-      if (val === 'Opacity' || val === 'opacity') {
-        return interfaceFunction.opacity;
-      }
-      return null;
-    }
-    Object.defineProperties(interfaceFunction, {
-      startPoint: {
-        get: ExpressionPropertyInterface(view.s),
-      },
-      endPoint: {
-        get: ExpressionPropertyInterface(view.e),
-      },
-      opacity: {
-        get: ExpressionPropertyInterface(view.o),
-      },
-      type: {
-        get: function () {
-          return 'a';
-        },
-      },
-      _name: { value: shape.nm },
-      mn: { value: shape.mn },
-    });
-
-    view.s.setGroupProperty(PropertyInterface('Start Point', propertyGroup));
-    view.e.setGroupProperty(PropertyInterface('End Point', propertyGroup));
-    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
-    return interfaceFunction;
-  }
-  function defaultInterfaceFactory() {
-    function interfaceFunction() {
-      return null;
-    }
-    return interfaceFunction;
-  }
-
-  function strokeInterfaceFactory(shape, view, propertyGroup) {
-    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-    var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
-    function addPropertyToDashOb(i) {
-      Object.defineProperty(dashOb, shape.d[i].nm, {
-        get: ExpressionPropertyInterface(view.d.dataProps[i].p),
-      });
-    }
-    var i;
-    var len = shape.d ? shape.d.length : 0;
-    var dashOb = {};
-    for (i = 0; i < len; i += 1) {
-      addPropertyToDashOb(i);
-      view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
-    }
-
-    function interfaceFunction(val) {
-      if (val === 'Color' || val === 'color') {
-        return interfaceFunction.color;
-      } if (val === 'Opacity' || val === 'opacity') {
-        return interfaceFunction.opacity;
-      } if (val === 'Stroke Width' || val === 'stroke width') {
-        return interfaceFunction.strokeWidth;
-      }
-      return null;
-    }
-    Object.defineProperties(interfaceFunction, {
-      color: {
-        get: ExpressionPropertyInterface(view.c),
-      },
-      opacity: {
-        get: ExpressionPropertyInterface(view.o),
-      },
-      strokeWidth: {
-        get: ExpressionPropertyInterface(view.w),
-      },
-      dash: {
-        get: function () {
-          return dashOb;
-        },
-      },
-      _name: { value: shape.nm },
-      mn: { value: shape.mn },
-    });
-
-    view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup));
-    view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
-    view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
-    return interfaceFunction;
-  }
-
-  function trimInterfaceFactory(shape, view, propertyGroup) {
-    function interfaceFunction(val) {
-      if (val === shape.e.ix || val === 'End' || val === 'end') {
-        return interfaceFunction.end;
-      }
-      if (val === shape.s.ix) {
-        return interfaceFunction.start;
-      }
-      if (val === shape.o.ix) {
-        return interfaceFunction.offset;
-      }
-      return null;
-    }
-
-    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-    interfaceFunction.propertyIndex = shape.ix;
-
-    view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
-    view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
-    view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
-    interfaceFunction.propertyIndex = shape.ix;
-    interfaceFunction.propertyGroup = propertyGroup;
-
-    Object.defineProperties(interfaceFunction, {
-      start: {
-        get: ExpressionPropertyInterface(view.s),
-      },
-      end: {
-        get: ExpressionPropertyInterface(view.e),
-      },
-      offset: {
-        get: ExpressionPropertyInterface(view.o),
-      },
-      _name: { value: shape.nm },
-    });
-    interfaceFunction.mn = shape.mn;
-    return interfaceFunction;
-  }
-
-  function transformInterfaceFactory(shape, view, propertyGroup) {
-    function interfaceFunction(value) {
-      if (shape.a.ix === value || value === 'Anchor Point') {
-        return interfaceFunction.anchorPoint;
-      }
-      if (shape.o.ix === value || value === 'Opacity') {
-        return interfaceFunction.opacity;
-      }
-      if (shape.p.ix === value || value === 'Position') {
-        return interfaceFunction.position;
-      }
-      if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
-        return interfaceFunction.rotation;
-      }
-      if (shape.s.ix === value || value === 'Scale') {
-        return interfaceFunction.scale;
-      }
-      if ((shape.sk && shape.sk.ix === value) || value === 'Skew') {
-        return interfaceFunction.skew;
-      }
-      if ((shape.sa && shape.sa.ix === value) || value === 'Skew Axis') {
-        return interfaceFunction.skewAxis;
-      }
-      return null;
-    }
-    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-    view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
-    view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
-    view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
-    view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
-    view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-    if (view.transform.mProps.sk) {
-      view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
-      view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
-    }
-    view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
-    Object.defineProperties(interfaceFunction, {
-      opacity: {
-        get: ExpressionPropertyInterface(view.transform.mProps.o),
-      },
-      position: {
-        get: ExpressionPropertyInterface(view.transform.mProps.p),
-      },
-      anchorPoint: {
-        get: ExpressionPropertyInterface(view.transform.mProps.a),
-      },
-      scale: {
-        get: ExpressionPropertyInterface(view.transform.mProps.s),
-      },
-      rotation: {
-        get: ExpressionPropertyInterface(view.transform.mProps.r),
-      },
-      skew: {
-        get: ExpressionPropertyInterface(view.transform.mProps.sk),
-      },
-      skewAxis: {
-        get: ExpressionPropertyInterface(view.transform.mProps.sa),
-      },
-      _name: { value: shape.nm },
-    });
-    interfaceFunction.ty = 'tr';
-    interfaceFunction.mn = shape.mn;
-    interfaceFunction.propertyGroup = propertyGroup;
-    return interfaceFunction;
-  }
-
-  function ellipseInterfaceFactory(shape, view, propertyGroup) {
-    function interfaceFunction(value) {
-      if (shape.p.ix === value) {
-        return interfaceFunction.position;
-      }
-      if (shape.s.ix === value) {
-        return interfaceFunction.size;
-      }
-      return null;
-    }
-    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-    interfaceFunction.propertyIndex = shape.ix;
-    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
-    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
-    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
-
-    Object.defineProperties(interfaceFunction, {
-      size: {
-        get: ExpressionPropertyInterface(prop.s),
-      },
-      position: {
-        get: ExpressionPropertyInterface(prop.p),
-      },
-      _name: { value: shape.nm },
-    });
-    interfaceFunction.mn = shape.mn;
-    return interfaceFunction;
-  }
-
-  function starInterfaceFactory(shape, view, propertyGroup) {
-    function interfaceFunction(value) {
-      if (shape.p.ix === value) {
-        return interfaceFunction.position;
-      }
-      if (shape.r.ix === value) {
-        return interfaceFunction.rotation;
-      }
-      if (shape.pt.ix === value) {
-        return interfaceFunction.points;
-      }
-      if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
-        return interfaceFunction.outerRadius;
-      }
-      if (shape.os.ix === value) {
-        return interfaceFunction.outerRoundness;
-      }
-      if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
-        return interfaceFunction.innerRadius;
-      }
-      if (shape.is && shape.is.ix === value) {
-        return interfaceFunction.innerRoundness;
-      }
-      return null;
-    }
-
-    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
-    interfaceFunction.propertyIndex = shape.ix;
-    prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
-    prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup));
-    prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
-    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
-    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-    if (shape.ir) {
-      prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
-      prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
-    }
-
-    Object.defineProperties(interfaceFunction, {
-      position: {
-        get: ExpressionPropertyInterface(prop.p),
-      },
-      rotation: {
-        get: ExpressionPropertyInterface(prop.r),
-      },
-      points: {
-        get: ExpressionPropertyInterface(prop.pt),
-      },
-      outerRadius: {
-        get: ExpressionPropertyInterface(prop.or),
-      },
-      outerRoundness: {
-        get: ExpressionPropertyInterface(prop.os),
-      },
-      innerRadius: {
-        get: ExpressionPropertyInterface(prop.ir),
-      },
-      innerRoundness: {
-        get: ExpressionPropertyInterface(prop.is),
-      },
-      _name: { value: shape.nm },
-    });
-    interfaceFunction.mn = shape.mn;
-    return interfaceFunction;
-  }
-
-  function rectInterfaceFactory(shape, view, propertyGroup) {
-    function interfaceFunction(value) {
-      if (shape.p.ix === value) {
-        return interfaceFunction.position;
-      }
-      if (shape.r.ix === value) {
-        return interfaceFunction.roundness;
-      }
-      if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
-        return interfaceFunction.size;
-      }
-      return null;
-    }
-    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-
-    var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
-    interfaceFunction.propertyIndex = shape.ix;
-    prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
-    prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
-    prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
-
-    Object.defineProperties(interfaceFunction, {
-      position: {
-        get: ExpressionPropertyInterface(prop.p),
-      },
-      roundness: {
-        get: ExpressionPropertyInterface(prop.r),
-      },
-      size: {
-        get: ExpressionPropertyInterface(prop.s),
-      },
-      _name: { value: shape.nm },
-    });
-    interfaceFunction.mn = shape.mn;
-    return interfaceFunction;
-  }
-
-  function roundedInterfaceFactory(shape, view, propertyGroup) {
-    function interfaceFunction(value) {
-      if (shape.r.ix === value || value === 'Round Corners 1') {
-        return interfaceFunction.radius;
-      }
-      return null;
-    }
-
-    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-    var prop = view;
-    interfaceFunction.propertyIndex = shape.ix;
-    prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
-
-    Object.defineProperties(interfaceFunction, {
-      radius: {
-        get: ExpressionPropertyInterface(prop.rd),
-      },
-      _name: { value: shape.nm },
-    });
-    interfaceFunction.mn = shape.mn;
-    return interfaceFunction;
-  }
-
-  function repeaterInterfaceFactory(shape, view, propertyGroup) {
-    function interfaceFunction(value) {
-      if (shape.c.ix === value || value === 'Copies') {
-        return interfaceFunction.copies;
-      } if (shape.o.ix === value || value === 'Offset') {
-        return interfaceFunction.offset;
-      }
-      return null;
-    }
-
-    var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
-    var prop = view;
-    interfaceFunction.propertyIndex = shape.ix;
-    prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
-    prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
-    Object.defineProperties(interfaceFunction, {
-      copies: {
-        get: ExpressionPropertyInterface(prop.c),
-      },
-      offset: {
-        get: ExpressionPropertyInterface(prop.o),
-      },
-      _name: { value: shape.nm },
-    });
-    interfaceFunction.mn = shape.mn;
-    return interfaceFunction;
-  }
-
-  return function (shapes, view, propertyGroup) {
-    var interfaces;
-    function _interfaceFunction(value) {
-      if (typeof value === 'number') {
-        value = value === undefined ? 1 : value;
-        if (value === 0) {
-          return propertyGroup;
-        }
-        return interfaces[value - 1];
-      }
-      var i = 0;
-      var len = interfaces.length;
-      while (i < len) {
-        if (interfaces[i]._name === value) {
-          return interfaces[i];
-        }
-        i += 1;
-      }
-      return null;
-    }
-    function parentGroupWrapper() {
-      return propertyGroup;
-    }
-    _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
-    interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
-    _interfaceFunction.numProperties = interfaces.length;
-    _interfaceFunction._name = 'Contents';
-    return _interfaceFunction;
-  };
-}());
-
-const TextExpressionInterface = (function () {
-  return function (elem) {
-    var _prevValue;
-    var _sourceText;
-    function _thisLayerFunction(name) {
-      switch (name) {
-        case 'ADBE Text Document':
-          return _thisLayerFunction.sourceText;
-        default:
-          return null;
-      }
-    }
-    Object.defineProperty(_thisLayerFunction, 'sourceText', {
-      get: function () {
-        elem.textProperty.getValue();
-        var stringValue = elem.textProperty.currentData.t;
-        if (stringValue !== _prevValue) {
-          elem.textProperty.currentData.t = _prevValue;
-          _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
-          // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
-          _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
-        }
-        return _sourceText;
-      },
-    });
-    return _thisLayerFunction;
-  };
-}());
-
-const getBlendMode = (function () {
-  var blendModeEnums = {
-    0: 'source-over',
-    1: 'multiply',
-    2: 'screen',
-    3: 'overlay',
-    4: 'darken',
-    5: 'lighten',
-    6: 'color-dodge',
-    7: 'color-burn',
-    8: 'hard-light',
-    9: 'soft-light',
-    10: 'difference',
-    11: 'exclusion',
-    12: 'hue',
-    13: 'saturation',
-    14: 'color',
-    15: 'luminosity',
-  };
-
-  return function (mode) {
-    return blendModeEnums[mode] || '';
-  };
-}());
-
-function SliderEffect(data, elem, container) {
-  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
-}
-function AngleEffect(data, elem, container) {
-  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
-}
-function ColorEffect(data, elem, container) {
-  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
-}
-function PointEffect(data, elem, container) {
-  this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
-}
-function LayerIndexEffect(data, elem, container) {
-  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
-}
-function MaskIndexEffect(data, elem, container) {
-  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
-}
-function CheckboxEffect(data, elem, container) {
-  this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
-}
-function NoValueEffect() {
-  this.p = {};
-}
-
-function EffectsManager(data, element) {
-  var effects = data.ef || [];
-  this.effectElements = [];
-  var i;
-  var len = effects.length;
-  var effectItem;
-  for (i = 0; i < len; i += 1) {
-    effectItem = new GroupEffect(effects[i], element);
-    this.effectElements.push(effectItem);
-  }
-}
-
-function GroupEffect(data, element) {
-  this.init(data, element);
-}
-
-extendPrototype([DynamicPropertyContainer], GroupEffect);
-
-GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
-
-GroupEffect.prototype.init = function (data, element) {
-  this.data = data;
-  this.effectElements = [];
-  this.initDynamicPropertyContainer(element);
-  var i;
-  var len = this.data.ef.length;
-  var eff;
-  var effects = this.data.ef;
-  for (i = 0; i < len; i += 1) {
-    eff = null;
-    switch (effects[i].ty) {
-      case 0:
-        eff = new SliderEffect(effects[i], element, this);
-        break;
-      case 1:
-        eff = new AngleEffect(effects[i], element, this);
-        break;
-      case 2:
-        eff = new ColorEffect(effects[i], element, this);
-        break;
-      case 3:
-        eff = new PointEffect(effects[i], element, this);
-        break;
-      case 4:
-      case 7:
-        eff = new CheckboxEffect(effects[i], element, this);
-        break;
-      case 10:
-        eff = new LayerIndexEffect(effects[i], element, this);
-        break;
-      case 11:
-        eff = new MaskIndexEffect(effects[i], element, this);
-        break;
-      case 5:
-        eff = new EffectsManager(effects[i], element, this);
-        break;
-        // case 6:
-      default:
-        eff = new NoValueEffect(effects[i], element, this);
-        break;
-    }
-    if (eff) {
-      this.effectElements.push(eff);
-    }
-  }
-};
-
-function BaseElement() {
-}
-
-BaseElement.prototype = {
-  checkMasks: function () {
-    if (!this.data.hasMask) {
-      return false;
-    }
-    var i = 0;
-    var len = this.data.masksProperties.length;
-    while (i < len) {
-      if ((this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false)) {
-        return true;
-      }
-      i += 1;
-    }
-    return false;
-  },
-  initExpressions: function () {
-    this.layerInterface = LayerExpressionInterface(this);
-    if (this.data.hasMask && this.maskManager) {
-      this.layerInterface.registerMaskInterface(this.maskManager);
-    }
-    var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
-    this.layerInterface.registerEffectsInterface(effectsInterface);
-
-    if (this.data.ty === 0 || this.data.xt) {
-      this.compInterface = CompExpressionInterface(this);
-    } else if (this.data.ty === 4) {
-      this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
-      this.layerInterface.content = this.layerInterface.shapeInterface;
-    } else if (this.data.ty === 5) {
-      this.layerInterface.textInterface = TextExpressionInterface(this);
-      this.layerInterface.text = this.layerInterface.textInterface;
-    }
-  },
-  setBlendMode: function () {
-    var blendModeValue = getBlendMode(this.data.bm);
-    var elem = this.baseElement || this.layerElement;
-
-    elem.style['mix-blend-mode'] = blendModeValue;
-  },
-  initBaseData: function (data, globalData, comp) {
-    this.globalData = globalData;
-    this.comp = comp;
-    this.data = data;
-    this.layerId = createElementID();
-
-    // Stretch factor for old animations missing this property.
-    if (!this.data.sr) {
-      this.data.sr = 1;
-    }
-    // effects manager
-    this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
-  },
-  getType: function () {
-    return this.type;
-  },
-  sourceRectAtTime: function () {},
-};
-
-/**
- * @file
- * Handles element's layer frame update.
- * Checks layer in point and out point
- *
- */
-
-function FrameElement() {}
-
-FrameElement.prototype = {
-  /**
-     * @function
-     * Initializes frame related properties.
-     *
-     */
-  initFrame: function () {
-    // set to true when inpoint is rendered
-    this._isFirstFrame = false;
-    // list of animated properties
-    this.dynamicProperties = [];
-    // If layer has been modified in current tick this will be true
-    this._mdf = false;
-  },
-  /**
-     * @function
-     * Calculates all dynamic values
-     *
-     * @param {number} num
-     * current frame number in Layer's time
-     * @param {boolean} isVisible
-     * if layers is currently in range
-     *
-     */
-  prepareProperties: function (num, isVisible) {
-    var i;
-    var len = this.dynamicProperties.length;
-    for (i = 0; i < len; i += 1) {
-      if (isVisible || (this._isParent && this.dynamicProperties[i].propType === 'transform')) {
-        this.dynamicProperties[i].getValue();
-        if (this.dynamicProperties[i]._mdf) {
-          this.globalData._mdf = true;
-          this._mdf = true;
-        }
-      }
-    }
-  },
-  addDynamicProperty: function (prop) {
-    if (this.dynamicProperties.indexOf(prop) === -1) {
-      this.dynamicProperties.push(prop);
-    }
-  },
-};
-
-const FootageInterface = (function () {
-  var outlineInterfaceFactory = (function (elem) {
-    var currentPropertyName = '';
-    var currentProperty = elem.getFootageData();
-    function init() {
-      currentPropertyName = '';
-      currentProperty = elem.getFootageData();
-      return searchProperty;
-    }
-    function searchProperty(value) {
-      if (currentProperty[value]) {
-        currentPropertyName = value;
-        currentProperty = currentProperty[value];
-        if (typeof currentProperty === 'object') {
-          return searchProperty;
-        }
-        return currentProperty;
-      }
-      var propertyNameIndex = value.indexOf(currentPropertyName);
-      if (propertyNameIndex !== -1) {
-        var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
-        currentProperty = currentProperty[index];
-        if (typeof currentProperty === 'object') {
-          return searchProperty;
-        }
-        return currentProperty;
-      }
-      return '';
-    }
-    return init;
-  });
-
-  var dataInterfaceFactory = function (elem) {
-    function interfaceFunction(value) {
-      if (value === 'Outline') {
-        return interfaceFunction.outlineInterface();
-      }
-      return null;
-    }
-
-    interfaceFunction._name = 'Outline';
-    interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
-    return interfaceFunction;
-  };
-
-  return function (elem) {
-    function _interfaceFunction(value) {
-      if (value === 'Data') {
-        return _interfaceFunction.dataInterface;
-      }
-      return null;
-    }
-
-    _interfaceFunction._name = 'Data';
-    _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
-    return _interfaceFunction;
-  };
-}());
-
-function FootageElement(data, globalData, comp) {
-  this.initFrame();
-  this.initRenderable();
-  this.assetData = globalData.getAssetData(data.refId);
-  this.footageData = globalData.imageLoader.getAsset(this.assetData);
-  this.initBaseData(data, globalData, comp);
-}
-
-FootageElement.prototype.prepareFrame = function () {
-};
-
-extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
-
-FootageElement.prototype.getBaseElement = function () {
-  return null;
-};
-
-FootageElement.prototype.renderFrame = function () {
-};
-
-FootageElement.prototype.destroy = function () {
-};
-
-FootageElement.prototype.initExpressions = function () {
-  this.layerInterface = FootageInterface(this);
-};
-
-FootageElement.prototype.getFootageData = function () {
-  return this.footageData;
-};
-
-function AudioElement(data, globalData, comp) {
-  this.initFrame();
-  this.initRenderable();
-  this.assetData = globalData.getAssetData(data.refId);
-  this.initBaseData(data, globalData, comp);
-  this._isPlaying = false;
-  this._canPlay = false;
-  var assetPath = this.globalData.getAssetsPath(this.assetData);
-  this.audio = this.globalData.audioController.createAudio(assetPath);
-  this._currentTime = 0;
-  this.globalData.audioController.addAudio(this);
-  this._volumeMultiplier = 1;
-  this._volume = 1;
-  this._previousVolume = null;
-  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
-  this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : { k: [100] }, 1, 0.01, this);
-}
-
-AudioElement.prototype.prepareFrame = function (num) {
-  this.prepareRenderableFrame(num, true);
-  this.prepareProperties(num, true);
-  if (!this.tm._placeholder) {
-    var timeRemapped = this.tm.v;
-    this._currentTime = timeRemapped;
-  } else {
-    this._currentTime = num / this.data.sr;
-  }
-  this._volume = this.lv.v[0];
-  var totalVolume = this._volume * this._volumeMultiplier;
-  if (this._previousVolume !== totalVolume) {
-    this._previousVolume = totalVolume;
-    this.audio.volume(totalVolume);
-  }
-};
-
-extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
-
-AudioElement.prototype.renderFrame = function () {
-  if (this.isInRange && this._canPlay) {
-    if (!this._isPlaying) {
-      this.audio.play();
-      this.audio.seek(this._currentTime / this.globalData.frameRate);
-      this._isPlaying = true;
-    } else if (!this.audio.playing()
-      || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1
-    ) {
-      this.audio.seek(this._currentTime / this.globalData.frameRate);
-    }
-  }
-};
-
-AudioElement.prototype.show = function () {
-  // this.audio.play()
-};
-
-AudioElement.prototype.hide = function () {
-  this.audio.pause();
-  this._isPlaying = false;
-};
-
-AudioElement.prototype.pause = function () {
-  this.audio.pause();
-  this._isPlaying = false;
-  this._canPlay = false;
-};
-
-AudioElement.prototype.resume = function () {
-  this._canPlay = true;
-};
-
-AudioElement.prototype.setRate = function (rateValue) {
-  this.audio.rate(rateValue);
-};
-
-AudioElement.prototype.volume = function (volumeValue) {
-  this._volumeMultiplier = volumeValue;
-  this._previousVolume = volumeValue * this._volume;
-  this.audio.volume(this._previousVolume);
-};
-
-AudioElement.prototype.getBaseElement = function () {
-  return null;
-};
-
-AudioElement.prototype.destroy = function () {
-};
-
-AudioElement.prototype.sourceRectAtTime = function () {
-};
-
-AudioElement.prototype.initExpressions = function () {
-};
-
-function BaseRenderer() {}
-BaseRenderer.prototype.checkLayers = function (num) {
-  var i;
-  var len = this.layers.length;
-  var data;
-  this.completeLayers = true;
-  for (i = len - 1; i >= 0; i -= 1) {
-    if (!this.elements[i]) {
-      data = this.layers[i];
-      if (data.ip - data.st <= (num - this.layers[i].st) && data.op - data.st > (num - this.layers[i].st)) {
-        this.buildItem(i);
-      }
-    }
-    this.completeLayers = this.elements[i] ? this.completeLayers : false;
-  }
-  this.checkPendingElements();
-};
-
-BaseRenderer.prototype.createItem = function (layer) {
-  switch (layer.ty) {
-    case 2:
-      return this.createImage(layer);
-    case 0:
-      return this.createComp(layer);
-    case 1:
-      return this.createSolid(layer);
-    case 3:
-      return this.createNull(layer);
-    case 4:
-      return this.createShape(layer);
-    case 5:
-      return this.createText(layer);
-    case 6:
-      return this.createAudio(layer);
-    case 13:
-      return this.createCamera(layer);
-    case 15:
-      return this.createFootage(layer);
-    default:
-      return this.createNull(layer);
-  }
-};
-
-BaseRenderer.prototype.createCamera = function () {
-  throw new Error('You\'re using a 3d camera. Try the html renderer.');
-};
-
-BaseRenderer.prototype.createAudio = function (data) {
-  return new AudioElement(data, this.globalData, this);
-};
-
-BaseRenderer.prototype.createFootage = function (data) {
-  return new FootageElement(data, this.globalData, this);
-};
-
-BaseRenderer.prototype.buildAllItems = function () {
-  var i;
-  var len = this.layers.length;
-  for (i = 0; i < len; i += 1) {
-    this.buildItem(i);
-  }
-  this.checkPendingElements();
-};
-
-BaseRenderer.prototype.includeLayers = function (newLayers) {
-  this.completeLayers = false;
-  var i;
-  var len = newLayers.length;
-  var j;
-  var jLen = this.layers.length;
-  for (i = 0; i < len; i += 1) {
-    j = 0;
-    while (j < jLen) {
-      if (this.layers[j].id === newLayers[i].id) {
-        this.layers[j] = newLayers[i];
-        break;
-      }
-      j += 1;
-    }
-  }
-};
-
-BaseRenderer.prototype.setProjectInterface = function (pInterface) {
-  this.globalData.projectInterface = pInterface;
-};
-
-BaseRenderer.prototype.initItems = function () {
-  if (!this.globalData.progressiveLoad) {
-    this.buildAllItems();
-  }
-};
-BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
-  var elements = this.elements;
-  var layers = this.layers;
-  var i = 0;
-  var len = layers.length;
-  while (i < len) {
-    if (layers[i].ind == parentName) { // eslint-disable-line eqeqeq
-      if (!elements[i] || elements[i] === true) {
-        this.buildItem(i);
-        this.addPendingElement(element);
-      } else {
-        hierarchy.push(elements[i]);
-        elements[i].setAsParent();
-        if (layers[i].parent !== undefined) {
-          this.buildElementParenting(element, layers[i].parent, hierarchy);
-        } else {
-          element.setHierarchy(hierarchy);
-        }
-      }
-    }
-    i += 1;
-  }
-};
-
-BaseRenderer.prototype.addPendingElement = function (element) {
-  this.pendingElements.push(element);
-};
-
-BaseRenderer.prototype.searchExtraCompositions = function (assets) {
-  var i;
-  var len = assets.length;
-  for (i = 0; i < len; i += 1) {
-    if (assets[i].xt) {
-      var comp = this.createComp(assets[i]);
-      comp.initExpressions();
-      this.globalData.projectInterface.registerComposition(comp);
-    }
-  }
-};
-
-BaseRenderer.prototype.getElementByPath = function (path) {
-  var pathValue = path.shift();
-  var element;
-  if (typeof pathValue === 'number') {
-    element = this.elements[pathValue];
-  } else {
-    var i;
-    var len = this.elements.length;
-    for (i = 0; i < len; i += 1) {
-      if (this.elements[i].data.nm === pathValue) {
-        element = this.elements[i];
-        break;
-      }
-    }
-  }
-  if (path.length === 0) {
-    return element;
-  }
-  return element.getElementByPath(path);
-};
-
-BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
-  this.globalData.fontManager = new FontManager();
-  this.globalData.fontManager.addChars(animData.chars);
-  this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
-  this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
-  this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
-  this.globalData.imageLoader = this.animationItem.imagePreloader;
-  this.globalData.audioController = this.animationItem.audioController;
-  this.globalData.frameId = 0;
-  this.globalData.frameRate = animData.fr;
-  this.globalData.nm = animData.nm;
-  this.globalData.compSize = {
-    w: animData.w,
-    h: animData.h,
-  };
-};
-
-function TransformElement() {}
-
-TransformElement.prototype = {
-  initTransform: function () {
-    this.finalTransform = {
-      mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : { o: 0 },
-      _matMdf: false,
-      _opMdf: false,
-      mat: new Matrix(),
-    };
-    if (this.data.ao) {
-      this.finalTransform.mProp.autoOriented = true;
-    }
-
-    // TODO: check TYPE 11: Guided elements
-    if (this.data.ty !== 11) {
-      // this.createElements();
-    }
-  },
-  renderTransform: function () {
-    this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
-    this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
-
-    if (this.hierarchy) {
-      var mat;
-      var finalMat = this.finalTransform.mat;
-      var i = 0;
-      var len = this.hierarchy.length;
-      // Checking if any of the transformation matrices in the hierarchy chain has changed.
-      if (!this.finalTransform._matMdf) {
-        while (i < len) {
-          if (this.hierarchy[i].finalTransform.mProp._mdf) {
-            this.finalTransform._matMdf = true;
-            break;
-          }
-          i += 1;
-        }
-      }
-
-      if (this.finalTransform._matMdf) {
-        mat = this.finalTransform.mProp.v.props;
-        finalMat.cloneFromProps(mat);
-        for (i = 0; i < len; i += 1) {
-          mat = this.hierarchy[i].finalTransform.mProp.v.props;
-          finalMat.transform(mat[0], mat[1], mat[2], mat[3], mat[4], mat[5], mat[6], mat[7], mat[8], mat[9], mat[10], mat[11], mat[12], mat[13], mat[14], mat[15]);
-        }
-      }
-    }
-  },
-  globalToLocal: function (pt) {
-    var transforms = [];
-    transforms.push(this.finalTransform);
-    var flag = true;
-    var comp = this.comp;
-    while (flag) {
-      if (comp.finalTransform) {
-        if (comp.data.hasMask) {
-          transforms.splice(0, 0, comp.finalTransform);
-        }
-        comp = comp.comp;
-      } else {
-        flag = false;
-      }
-    }
-    var i;
-    var len = transforms.length;
-    var ptNew;
-    for (i = 0; i < len; i += 1) {
-      ptNew = transforms[i].mat.applyToPointArray(0, 0, 0);
-      // ptNew = transforms[i].mat.applyToPointArray(pt[0],pt[1],pt[2]);
-      pt = [pt[0] - ptNew[0], pt[1] - ptNew[1], 0];
-    }
-    return pt;
-  },
-  mHelper: new Matrix(),
-};
-
-function MaskElement(data, element, globalData) {
-  this.data = data;
-  this.element = element;
-  this.globalData = globalData;
-  this.storedData = [];
-  this.masksProperties = this.data.masksProperties || [];
-  this.maskElement = null;
-  var defs = this.globalData.defs;
-  var i;
-  var len = this.masksProperties ? this.masksProperties.length : 0;
-  this.viewData = createSizedArray(len);
-  this.solidPath = '';
-
-  var path;
-  var properties = this.masksProperties;
-  var count = 0;
-  var currentMasks = [];
-  var j;
-  var jLen;
-  var layerId = createElementID();
-  var rect;
-  var expansor;
-  var feMorph;
-  var x;
-  var maskType = 'clipPath';
-  var maskRef = 'clip-path';
-  for (i = 0; i < len; i += 1) {
-    if ((properties[i].mode !== 'a' && properties[i].mode !== 'n') || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
-      maskType = 'mask';
-      maskRef = 'mask';
-    }
-
-    if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
-      rect = createNS('rect');
-      rect.setAttribute('fill', '#ffffff');
-      rect.setAttribute('width', this.element.comp.data.w || 0);
-      rect.setAttribute('height', this.element.comp.data.h || 0);
-      currentMasks.push(rect);
-    } else {
-      rect = null;
-    }
-
-    path = createNS('path');
-    if (properties[i].mode === 'n') {
-      // TODO move this to a factory or to a constructor
-      this.viewData[i] = {
-        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
-        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
-        elem: path,
-        lastPath: '',
-      };
-      defs.appendChild(path);
-    } else {
-      count += 1;
-
-      path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
-      path.setAttribute('clip-rule', 'nonzero');
-      var filterID;
-
-      if (properties[i].x.k !== 0) {
-        maskType = 'mask';
-        maskRef = 'mask';
-        x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
-        filterID = createElementID();
-        expansor = createNS('filter');
-        expansor.setAttribute('id', filterID);
-        feMorph = createNS('feMorphology');
-        feMorph.setAttribute('operator', 'erode');
-        feMorph.setAttribute('in', 'SourceGraphic');
-        feMorph.setAttribute('radius', '0');
-        expansor.appendChild(feMorph);
-        defs.appendChild(expansor);
-        path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
-      } else {
-        feMorph = null;
-        x = null;
-      }
-
-      // TODO move this to a factory or to a constructor
-      this.storedData[i] = {
-        elem: path,
-        x: x,
-        expan: feMorph,
-        lastPath: '',
-        lastOperator: '',
-        filterId: filterID,
-        lastRadius: 0,
-      };
-      if (properties[i].mode === 'i') {
-        jLen = currentMasks.length;
-        var g = createNS('g');
-        for (j = 0; j < jLen; j += 1) {
-          g.appendChild(currentMasks[j]);
-        }
-        var mask = createNS('mask');
-        mask.setAttribute('mask-type', 'alpha');
-        mask.setAttribute('id', layerId + '_' + count);
-        mask.appendChild(path);
-        defs.appendChild(mask);
-        g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
-
-        currentMasks.length = 0;
-        currentMasks.push(g);
-      } else {
-        currentMasks.push(path);
-      }
-      if (properties[i].inv && !this.solidPath) {
-        this.solidPath = this.createLayerSolidPath();
-      }
-      // TODO move this to a factory or to a constructor
-      this.viewData[i] = {
-        elem: path,
-        lastPath: '',
-        op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
-        prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
-        invRect: rect,
-      };
-      if (!this.viewData[i].prop.k) {
-        this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
-      }
-    }
-  }
-
-  this.maskElement = createNS(maskType);
-
-  len = currentMasks.length;
-  for (i = 0; i < len; i += 1) {
-    this.maskElement.appendChild(currentMasks[i]);
-  }
-
-  if (count > 0) {
-    this.maskElement.setAttribute('id', layerId);
-    this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
-    defs.appendChild(this.maskElement);
-  }
-  if (this.viewData.length) {
-    this.element.addRenderableComponent(this);
-  }
-}
-
-MaskElement.prototype.getMaskProperty = function (pos) {
-  return this.viewData[pos].prop;
-};
-
-MaskElement.prototype.renderFrame = function (isFirstFrame) {
-  var finalMat = this.element.finalTransform.mat;
-  var i;
-  var len = this.masksProperties.length;
-  for (i = 0; i < len; i += 1) {
-    if (this.viewData[i].prop._mdf || isFirstFrame) {
-      this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
-    }
-    if (this.viewData[i].op._mdf || isFirstFrame) {
-      this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
-    }
-    if (this.masksProperties[i].mode !== 'n') {
-      if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
-        this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
-      }
-      if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
-        var feMorph = this.storedData[i].expan;
-        if (this.storedData[i].x.v < 0) {
-          if (this.storedData[i].lastOperator !== 'erode') {
-            this.storedData[i].lastOperator = 'erode';
-            this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
-          }
-          feMorph.setAttribute('radius', -this.storedData[i].x.v);
-        } else {
-          if (this.storedData[i].lastOperator !== 'dilate') {
-            this.storedData[i].lastOperator = 'dilate';
-            this.storedData[i].elem.setAttribute('filter', null);
-          }
-          this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
-        }
-      }
-    }
-  }
-};
-
-MaskElement.prototype.getMaskelement = function () {
-  return this.maskElement;
-};
-
-MaskElement.prototype.createLayerSolidPath = function () {
-  var path = 'M0,0 ';
-  path += ' h' + this.globalData.compSize.w;
-  path += ' v' + this.globalData.compSize.h;
-  path += ' h-' + this.globalData.compSize.w;
-  path += ' v-' + this.globalData.compSize.h + ' ';
-  return path;
-};
-
-MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
-  var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-  var i;
-  var len;
-  len = pathNodes._length;
-  for (i = 1; i < len; i += 1) {
-    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
-    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
-  }
-  // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
-  if (pathNodes.c && len > 1) {
-    pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
-  }
-  // pathNodes.__renderedString = pathString;
-
-  if (viewData.lastPath !== pathString) {
-    var pathShapeValue = '';
-    if (viewData.elem) {
-      if (pathNodes.c) {
-        pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
-      }
-      viewData.elem.setAttribute('d', pathShapeValue);
-    }
-    viewData.lastPath = pathString;
-  }
-};
-
-MaskElement.prototype.destroy = function () {
-  this.element = null;
-  this.globalData = null;
-  this.maskElement = null;
-  this.data = null;
-  this.masksProperties = null;
-};
-
-const filtersFactory = (function () {
-  var ob = {};
-  ob.createFilter = createFilter;
-  ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
-
-  function createFilter(filId, skipCoordinates) {
-    var fil = createNS('filter');
-    fil.setAttribute('id', filId);
-    if (skipCoordinates !== true) {
-      fil.setAttribute('filterUnits', 'objectBoundingBox');
-      fil.setAttribute('x', '0%');
-      fil.setAttribute('y', '0%');
-      fil.setAttribute('width', '100%');
-      fil.setAttribute('height', '100%');
-    }
-    return fil;
-  }
-
-  function createAlphaToLuminanceFilter() {
-    var feColorMatrix = createNS('feColorMatrix');
-    feColorMatrix.setAttribute('type', 'matrix');
-    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
-    feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
-    return feColorMatrix;
-  }
-
-  return ob;
-}());
-
-const featureSupport = (function () {
-  var ob = {
-    maskType: true,
-  };
-  if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
-    ob.maskType = false;
-  }
-  return ob;
-}());
-
-var registeredEffects = {};
-var idPrefix = 'filter_result_';
-
-function SVGEffects(elem) {
-  var i;
-  var source = 'SourceGraphic';
-  var len = elem.data.ef ? elem.data.ef.length : 0;
-  var filId = createElementID();
-  var fil = filtersFactory.createFilter(filId, true);
-  var count = 0;
-  this.filters = [];
-  var filterManager;
-  for (i = 0; i < len; i += 1) {
-    filterManager = null;
-    var type = elem.data.ef[i].ty;
-    if (registeredEffects[type]) {
-      var Effect = registeredEffects[type].effect;
-      filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
-      source = idPrefix + count;
-      if (registeredEffects[type].countsAsEffect) {
-        count += 1;
-      }
-    }
-    if (filterManager) {
-      this.filters.push(filterManager);
-    }
-  }
-  if (count) {
-    elem.globalData.defs.appendChild(fil);
-    elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
-  }
-  if (this.filters.length) {
-    elem.addRenderableComponent(this);
-  }
-}
-
-SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
-  var i;
-  var len = this.filters.length;
-  for (i = 0; i < len; i += 1) {
-    this.filters[i].renderFrame(_isFirstFrame);
-  }
-};
-
-function registerEffect(id, effect, countsAsEffect) {
-  registeredEffects[id] = {
-    effect,
-    countsAsEffect,
-  };
-}
-
-function SVGBaseElement() {
-}
-
-SVGBaseElement.prototype = {
-  initRendererElement: function () {
-    this.layerElement = createNS('g');
-  },
-  createContainerElements: function () {
-    this.matteElement = createNS('g');
-    this.transformedElement = this.layerElement;
-    this.maskedElement = this.layerElement;
-    this._sizeChanged = false;
-    var layerElementParent = null;
-    // If this layer acts as a mask for the following layer
-    var filId;
-    var fil;
-    var gg;
-    if (this.data.td) {
-      if (this.data.td == 3 || this.data.td == 1) { // eslint-disable-line eqeqeq
-        var masker = createNS('mask');
-        masker.setAttribute('id', this.layerId);
-        masker.setAttribute('mask-type', this.data.td == 3 ? 'luminance' : 'alpha'); // eslint-disable-line eqeqeq
-        masker.appendChild(this.layerElement);
-        layerElementParent = masker;
-        this.globalData.defs.appendChild(masker);
-        // This is only for IE and Edge when mask if of type alpha
-        if (!featureSupport.maskType && this.data.td == 1) { // eslint-disable-line eqeqeq
-          masker.setAttribute('mask-type', 'luminance');
-          filId = createElementID();
-          fil = filtersFactory.createFilter(filId);
-          this.globalData.defs.appendChild(fil);
-          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
-          gg = createNS('g');
-          gg.appendChild(this.layerElement);
-          layerElementParent = gg;
-          masker.appendChild(gg);
-          gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
-        }
-      } else if (this.data.td == 2) { // eslint-disable-line eqeqeq
-        var maskGroup = createNS('mask');
-        maskGroup.setAttribute('id', this.layerId);
-        maskGroup.setAttribute('mask-type', 'alpha');
-        var maskGrouper = createNS('g');
-        maskGroup.appendChild(maskGrouper);
-        filId = createElementID();
-        fil = filtersFactory.createFilter(filId);
-        /// /
-
-        // This solution doesn't work on Android when meta tag with viewport attribute is set
-        /* var feColorMatrix = createNS('feColorMatrix');
-                feColorMatrix.setAttribute('type', 'matrix');
-                feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
-                feColorMatrix.setAttribute('values','1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 -1 1');
-                fil.appendChild(feColorMatrix); */
-        /// /
-        var feCTr = createNS('feComponentTransfer');
-        feCTr.setAttribute('in', 'SourceGraphic');
-        fil.appendChild(feCTr);
-        var feFunc = createNS('feFuncA');
-        feFunc.setAttribute('type', 'table');
-        feFunc.setAttribute('tableValues', '1.0 0.0');
-        feCTr.appendChild(feFunc);
-        /// /
-        this.globalData.defs.appendChild(fil);
-        var alphaRect = createNS('rect');
-        alphaRect.setAttribute('width', this.comp.data.w);
-        alphaRect.setAttribute('height', this.comp.data.h);
-        alphaRect.setAttribute('x', '0');
-        alphaRect.setAttribute('y', '0');
-        alphaRect.setAttribute('fill', '#ffffff');
-        alphaRect.setAttribute('opacity', '0');
-        maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
-        maskGrouper.appendChild(alphaRect);
-        maskGrouper.appendChild(this.layerElement);
-        layerElementParent = maskGrouper;
-        if (!featureSupport.maskType) {
-          maskGroup.setAttribute('mask-type', 'luminance');
-          fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
-          gg = createNS('g');
-          maskGrouper.appendChild(alphaRect);
-          gg.appendChild(this.layerElement);
-          layerElementParent = gg;
-          maskGrouper.appendChild(gg);
-        }
-        this.globalData.defs.appendChild(maskGroup);
-      }
-    } else if (this.data.tt) {
-      this.matteElement.appendChild(this.layerElement);
-      layerElementParent = this.matteElement;
-      this.baseElement = this.matteElement;
-    } else {
-      this.baseElement = this.layerElement;
-    }
-    if (this.data.ln) {
-      this.layerElement.setAttribute('id', this.data.ln);
-    }
-    if (this.data.cl) {
-      this.layerElement.setAttribute('class', this.data.cl);
-    }
-    // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
-    if (this.data.ty === 0 && !this.data.hd) {
-      var cp = createNS('clipPath');
-      var pt = createNS('path');
-      pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
-      var clipId = createElementID();
-      cp.setAttribute('id', clipId);
-      cp.appendChild(pt);
-      this.globalData.defs.appendChild(cp);
-
-      if (this.checkMasks()) {
-        var cpGroup = createNS('g');
-        cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
-        cpGroup.appendChild(this.layerElement);
-        this.transformedElement = cpGroup;
-        if (layerElementParent) {
-          layerElementParent.appendChild(this.transformedElement);
-        } else {
-          this.baseElement = this.transformedElement;
-        }
-      } else {
-        this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
-      }
-    }
-    if (this.data.bm !== 0) {
-      this.setBlendMode();
-    }
-  },
-  renderElement: function () {
-    if (this.finalTransform._matMdf) {
-      this.transformedElement.setAttribute('transform', this.finalTransform.mat.to2dCSS());
-    }
-    if (this.finalTransform._opMdf) {
-      this.transformedElement.setAttribute('opacity', this.finalTransform.mProp.o.v);
-    }
-  },
-  destroyBaseElement: function () {
-    this.layerElement = null;
-    this.matteElement = null;
-    this.maskManager.destroy();
-  },
-  getBaseElement: function () {
-    if (this.data.hd) {
-      return null;
-    }
-    return this.baseElement;
-  },
-  createRenderableComponents: function () {
-    this.maskManager = new MaskElement(this.data, this, this.globalData);
-    this.renderableEffectsManager = new SVGEffects(this);
-  },
-  setMatte: function (id) {
-    if (!this.matteElement) {
-      return;
-    }
-    this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
-  },
-};
-
-/**
- * @file
- * Handles AE's layer parenting property.
- *
- */
-
-function HierarchyElement() {}
-
-HierarchyElement.prototype = {
-  /**
-     * @function
-     * Initializes hierarchy properties
-     *
-     */
-  initHierarchy: function () {
-    // element's parent list
-    this.hierarchy = [];
-    // if element is parent of another layer _isParent will be true
-    this._isParent = false;
-    this.checkParenting();
-  },
-  /**
-     * @function
-     * Sets layer's hierarchy.
-     * @param {array} hierarch
-     * layer's parent list
-     *
-     */
-  setHierarchy: function (hierarchy) {
-    this.hierarchy = hierarchy;
-  },
-  /**
-     * @function
-     * Sets layer as parent.
-     *
-     */
-  setAsParent: function () {
-    this._isParent = true;
-  },
-  /**
-     * @function
-     * Searches layer's parenting chain
-     *
-     */
-  checkParenting: function () {
-    if (this.data.parent !== undefined) {
-      this.comp.buildElementParenting(this, this.data.parent, []);
-    }
-  },
-};
-
-function RenderableDOMElement() {}
-
-(function () {
-  var _prototype = {
-    initElement: function (data, globalData, comp) {
-      this.initFrame();
-      this.initBaseData(data, globalData, comp);
-      this.initTransform(data, globalData, comp);
-      this.initHierarchy();
-      this.initRenderable();
-      this.initRendererElement();
-      this.createContainerElements();
-      this.createRenderableComponents();
-      this.createContent();
-      this.hide();
-    },
-    hide: function () {
-      // console.log('HIDE', this);
-      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
-        var elem = this.baseElement || this.layerElement;
-        elem.style.display = 'none';
-        this.hidden = true;
-      }
-    },
-    show: function () {
-      // console.log('SHOW', this);
-      if (this.isInRange && !this.isTransparent) {
-        if (!this.data.hd) {
-          var elem = this.baseElement || this.layerElement;
-          elem.style.display = 'block';
-        }
-        this.hidden = false;
-        this._isFirstFrame = true;
-      }
-    },
-    renderFrame: function () {
-      // If it is exported as hidden (data.hd === true) no need to render
-      // If it is not visible no need to render
-      if (this.data.hd || this.hidden) {
-        return;
-      }
-      this.renderTransform();
-      this.renderRenderable();
-      this.renderElement();
-      this.renderInnerContent();
-      if (this._isFirstFrame) {
-        this._isFirstFrame = false;
-      }
-    },
-    renderInnerContent: function () {},
-    prepareFrame: function (num) {
-      this._mdf = false;
-      this.prepareRenderableFrame(num);
-      this.prepareProperties(num, this.isInRange);
-      this.checkTransparency();
-    },
-    destroy: function () {
-      this.innerElem = null;
-      this.destroyBaseElement();
-    },
-  };
-  extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
-}());
-
-function IImageElement(data, globalData, comp) {
-  this.assetData = globalData.getAssetData(data.refId);
-  this.initElement(data, globalData, comp);
-  this.sourceRect = {
-    top: 0, left: 0, width: this.assetData.w, height: this.assetData.h,
-  };
-}
-
-extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
-
-IImageElement.prototype.createContent = function () {
-  var assetPath = this.globalData.getAssetsPath(this.assetData);
-
-  this.innerElem = createNS('image');
-  this.innerElem.setAttribute('width', this.assetData.w + 'px');
-  this.innerElem.setAttribute('height', this.assetData.h + 'px');
-  this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
-  this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
-
-  this.layerElement.appendChild(this.innerElem);
-};
-
-IImageElement.prototype.sourceRectAtTime = function () {
-  return this.sourceRect;
-};
-
-function ProcessedElement(element, position) {
-  this.elem = element;
-  this.pos = position;
-}
-
-function IShapeElement() {
-}
-
-IShapeElement.prototype = {
-  addShapeToModifiers: function (data) {
-    var i;
-    var len = this.shapeModifiers.length;
-    for (i = 0; i < len; i += 1) {
-      this.shapeModifiers[i].addShape(data);
-    }
-  },
-  isShapeInAnimatedModifiers: function (data) {
-    var i = 0;
-    var len = this.shapeModifiers.length;
-    while (i < len) {
-      if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
-        return true;
-      }
-    }
-    return false;
-  },
-  renderModifiers: function () {
-    if (!this.shapeModifiers.length) {
-      return;
-    }
-    var i;
-    var len = this.shapes.length;
-    for (i = 0; i < len; i += 1) {
-      this.shapes[i].sh.reset();
-    }
-
-    len = this.shapeModifiers.length;
-    var shouldBreakProcess;
-    for (i = len - 1; i >= 0; i -= 1) {
-      shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
-      // workaround to fix cases where a repeater resets the shape so the following processes get called twice
-      // TODO: find a better solution for this
-      if (shouldBreakProcess) {
-        break;
-      }
-    }
-  },
-
-  searchProcessedElement: function (elem) {
-    var elements = this.processedElements;
-    var i = 0;
-    var len = elements.length;
-    while (i < len) {
-      if (elements[i].elem === elem) {
-        return elements[i].pos;
-      }
-      i += 1;
-    }
-    return 0;
-  },
-  addProcessedElement: function (elem, pos) {
-    var elements = this.processedElements;
-    var i = elements.length;
-    while (i) {
-      i -= 1;
-      if (elements[i].elem === elem) {
-        elements[i].pos = pos;
-        return;
-      }
-    }
-    elements.push(new ProcessedElement(elem, pos));
-  },
-  prepareFrame: function (num) {
-    this.prepareRenderableFrame(num);
-    this.prepareProperties(num, this.isInRange);
-  },
-};
-
-const lineCapEnum = {
-  1: 'butt',
-  2: 'round',
-  3: 'square',
-};
-
-const lineJoinEnum = {
-  1: 'miter',
-  2: 'round',
-  3: 'bevel',
-};
-
-function SVGShapeData(transformers, level, shape) {
-  this.caches = [];
-  this.styles = [];
-  this.transformers = transformers;
-  this.lStr = '';
-  this.sh = shape;
-  this.lvl = level;
-  // TODO find if there are some cases where _isAnimated can be false.
-  // For now, since shapes add up with other shapes. They have to be calculated every time.
-  // One way of finding out is checking if all styles associated to this shape depend only of this shape
-  this._isAnimated = !!shape.k;
-  // TODO: commenting this for now since all shapes are animated
-  var i = 0;
-  var len = transformers.length;
-  while (i < len) {
-    if (transformers[i].mProps.dynamicProperties.length) {
-      this._isAnimated = true;
-      break;
-    }
-    i += 1;
-  }
-}
-
-SVGShapeData.prototype.setAsAnimated = function () {
-  this._isAnimated = true;
-};
-
-function SVGStyleData(data, level) {
-  this.data = data;
-  this.type = data.ty;
-  this.d = '';
-  this.lvl = level;
-  this._mdf = false;
-  this.closed = data.hd === true;
-  this.pElem = createNS('path');
-  this.msElem = null;
-}
-
-SVGStyleData.prototype.reset = function () {
-  this.d = '';
-  this._mdf = false;
-};
-
-function DashProperty(elem, data, renderer, container) {
-  this.elem = elem;
-  this.frameId = -1;
-  this.dataProps = createSizedArray(data.length);
-  this.renderer = renderer;
-  this.k = false;
-  this.dashStr = '';
-  this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
-  this.dashoffset = createTypedArray('float32', 1);
-  this.initDynamicPropertyContainer(container);
-  var i;
-  var len = data.length || 0;
-  var prop;
-  for (i = 0; i < len; i += 1) {
-    prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
-    this.k = prop.k || this.k;
-    this.dataProps[i] = { n: data[i].n, p: prop };
-  }
-  if (!this.k) {
-    this.getValue(true);
-  }
-  this._isAnimated = this.k;
-}
-
-DashProperty.prototype.getValue = function (forceRender) {
-  if (this.elem.globalData.frameId === this.frameId && !forceRender) {
-    return;
-  }
-  this.frameId = this.elem.globalData.frameId;
-  this.iterateDynamicProperties();
-  this._mdf = this._mdf || forceRender;
-  if (this._mdf) {
-    var i = 0;
-    var len = this.dataProps.length;
-    if (this.renderer === 'svg') {
-      this.dashStr = '';
-    }
-    for (i = 0; i < len; i += 1) {
-      if (this.dataProps[i].n !== 'o') {
-        if (this.renderer === 'svg') {
-          this.dashStr += ' ' + this.dataProps[i].p.v;
-        } else {
-          this.dashArray[i] = this.dataProps[i].p.v;
-        }
-      } else {
-        this.dashoffset[0] = this.dataProps[i].p.v;
-      }
-    }
-  }
-};
-extendPrototype([DynamicPropertyContainer], DashProperty);
-
-function SVGStrokeStyleData(elem, data, styleOb) {
-  this.initDynamicPropertyContainer(elem);
-  this.getValue = this.iterateDynamicProperties;
-  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
-  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
-  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
-  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
-  this.style = styleOb;
-  this._isAnimated = !!this._isAnimated;
-}
-
-extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
-
-function SVGFillStyleData(elem, data, styleOb) {
-  this.initDynamicPropertyContainer(elem);
-  this.getValue = this.iterateDynamicProperties;
-  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
-  this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
-  this.style = styleOb;
-}
-
-extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
-
-function SVGNoStyleData(elem, data, styleOb) {
-  this.initDynamicPropertyContainer(elem);
-  this.getValue = this.iterateDynamicProperties;
-  this.style = styleOb;
-}
-
-extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
-
-function GradientProperty(elem, data, container) {
-  this.data = data;
-  this.c = createTypedArray('uint8c', data.p * 4);
-  var cLength = data.k.k[0].s ? (data.k.k[0].s.length - data.p * 4) : data.k.k.length - data.p * 4;
-  this.o = createTypedArray('float32', cLength);
-  this._cmdf = false;
-  this._omdf = false;
-  this._collapsable = this.checkCollapsable();
-  this._hasOpacity = cLength;
-  this.initDynamicPropertyContainer(container);
-  this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
-  this.k = this.prop.k;
-  this.getValue(true);
-}
-
-GradientProperty.prototype.comparePoints = function (values, points) {
-  var i = 0;
-  var len = this.o.length / 2;
-  var diff;
-  while (i < len) {
-    diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
-    if (diff > 0.01) {
-      return false;
-    }
-    i += 1;
-  }
-  return true;
-};
-
-GradientProperty.prototype.checkCollapsable = function () {
-  if (this.o.length / 2 !== this.c.length / 4) {
-    return false;
-  }
-  if (this.data.k.k[0].s) {
-    var i = 0;
-    var len = this.data.k.k.length;
-    while (i < len) {
-      if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
-        return false;
-      }
-      i += 1;
-    }
-  } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
-    return false;
-  }
-  return true;
-};
-
-GradientProperty.prototype.getValue = function (forceRender) {
-  this.prop.getValue();
-  this._mdf = false;
-  this._cmdf = false;
-  this._omdf = false;
-  if (this.prop._mdf || forceRender) {
-    var i;
-    var len = this.data.p * 4;
-    var mult;
-    var val;
-    for (i = 0; i < len; i += 1) {
-      mult = i % 4 === 0 ? 100 : 255;
-      val = Math.round(this.prop.v[i] * mult);
-      if (this.c[i] !== val) {
-        this.c[i] = val;
-        this._cmdf = !forceRender;
-      }
-    }
-    if (this.o.length) {
-      len = this.prop.v.length;
-      for (i = this.data.p * 4; i < len; i += 1) {
-        mult = i % 2 === 0 ? 100 : 1;
-        val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
-        if (this.o[i - this.data.p * 4] !== val) {
-          this.o[i - this.data.p * 4] = val;
-          this._omdf = !forceRender;
-        }
-      }
-    }
-    this._mdf = !forceRender;
-  }
-};
-
-extendPrototype([DynamicPropertyContainer], GradientProperty);
-
-function SVGGradientFillStyleData(elem, data, styleOb) {
-  this.initDynamicPropertyContainer(elem);
-  this.getValue = this.iterateDynamicProperties;
-  this.initGradientData(elem, data, styleOb);
-}
-
-SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
-  this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
-  this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
-  this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
-  this.h = PropertyFactory.getProp(elem, data.h || { k: 0 }, 0, 0.01, this);
-  this.a = PropertyFactory.getProp(elem, data.a || { k: 0 }, 0, degToRads, this);
-  this.g = new GradientProperty(elem, data.g, this);
-  this.style = styleOb;
-  this.stops = [];
-  this.setGradientData(styleOb.pElem, data);
-  this.setGradientOpacity(data, styleOb);
-  this._isAnimated = !!this._isAnimated;
-};
-
-SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
-  var gradientId = createElementID();
-  var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
-  gfill.setAttribute('id', gradientId);
-  gfill.setAttribute('spreadMethod', 'pad');
-  gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
-  var stops = [];
-  var stop;
-  var j;
-  var jLen;
-  jLen = data.g.p * 4;
-  for (j = 0; j < jLen; j += 4) {
-    stop = createNS('stop');
-    gfill.appendChild(stop);
-    stops.push(stop);
-  }
-  pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
-  this.gf = gfill;
-  this.cst = stops;
-};
-
-SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
-  if (this.g._hasOpacity && !this.g._collapsable) {
-    var stop;
-    var j;
-    var jLen;
-    var mask = createNS('mask');
-    var maskElement = createNS('path');
-    mask.appendChild(maskElement);
-    var opacityId = createElementID();
-    var maskId = createElementID();
-    mask.setAttribute('id', maskId);
-    var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
-    opFill.setAttribute('id', opacityId);
-    opFill.setAttribute('spreadMethod', 'pad');
-    opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
-    jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
-    var stops = this.stops;
-    for (j = data.g.p * 4; j < jLen; j += 2) {
-      stop = createNS('stop');
-      stop.setAttribute('stop-color', 'rgb(255,255,255)');
-      opFill.appendChild(stop);
-      stops.push(stop);
-    }
-    maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + opacityId + ')');
-    if (data.ty === 'gs') {
-      maskElement.setAttribute('stroke-linecap', lineCapEnum[data.lc || 2]);
-      maskElement.setAttribute('stroke-linejoin', lineJoinEnum[data.lj || 2]);
-      if (data.lj === 1) {
-        maskElement.setAttribute('stroke-miterlimit', data.ml);
-      }
-    }
-    this.of = opFill;
-    this.ms = mask;
-    this.ost = stops;
-    this.maskId = maskId;
-    styleOb.msElem = maskElement;
-  }
-};
-
-extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
-
-function SVGGradientStrokeStyleData(elem, data, styleOb) {
-  this.initDynamicPropertyContainer(elem);
-  this.getValue = this.iterateDynamicProperties;
-  this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
-  this.d = new DashProperty(elem, data.d || {}, 'svg', this);
-  this.initGradientData(elem, data, styleOb);
-  this._isAnimated = !!this._isAnimated;
-}
-
-extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
-
-function ShapeGroupData() {
-  this.it = [];
-  this.prevViewData = [];
-  this.gr = createNS('g');
-}
-
-function SVGTransformData(mProps, op, container) {
-  this.transform = {
-    mProps: mProps,
-    op: op,
-    container: container,
-  };
-  this.elements = [];
-  this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
-}
-
-const buildShapeString = function (pathNodes, length, closed, mat) {
-  if (length === 0) {
-    return '';
-  }
-  var _o = pathNodes.o;
-  var _i = pathNodes.i;
-  var _v = pathNodes.v;
-  var i;
-  var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-  for (i = 1; i < length; i += 1) {
-    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
-  }
-  if (closed && length) {
-    shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
-    shapeString += 'z';
-  }
-  return shapeString;
-};
-
-const SVGElementsRenderer = (function () {
-  var _identityMatrix = new Matrix();
-  var _matrixHelper = new Matrix();
-
-  var ob = {
-    createRenderFunction: createRenderFunction,
-  };
-
-  function createRenderFunction(data) {
-    switch (data.ty) {
-      case 'fl':
-        return renderFill;
-      case 'gf':
-        return renderGradient;
-      case 'gs':
-        return renderGradientStroke;
-      case 'st':
-        return renderStroke;
-      case 'sh':
-      case 'el':
-      case 'rc':
-      case 'sr':
-        return renderPath;
-      case 'tr':
-        return renderContentTransform;
-      case 'no':
-        return renderNoop;
-      default:
-        return null;
-    }
-  }
-
-  function renderContentTransform(styleData, itemData, isFirstFrame) {
-    if (isFirstFrame || itemData.transform.op._mdf) {
-      itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
-    }
-    if (isFirstFrame || itemData.transform.mProps._mdf) {
-      itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
-    }
-  }
-
-  function renderNoop() {
-
-  }
-
-  function renderPath(styleData, itemData, isFirstFrame) {
-    var j;
-    var jLen;
-    var pathStringTransformed;
-    var redraw;
-    var pathNodes;
-    var l;
-    var lLen = itemData.styles.length;
-    var lvl = itemData.lvl;
-    var paths;
-    var mat;
-    var props;
-    var iterations;
-    var k;
-    for (l = 0; l < lLen; l += 1) {
-      redraw = itemData.sh._mdf || isFirstFrame;
-      if (itemData.styles[l].lvl < lvl) {
-        mat = _matrixHelper.reset();
-        iterations = lvl - itemData.styles[l].lvl;
-        k = itemData.transformers.length - 1;
-        while (!redraw && iterations > 0) {
-          redraw = itemData.transformers[k].mProps._mdf || redraw;
-          iterations -= 1;
-          k -= 1;
-        }
-        if (redraw) {
-          iterations = lvl - itemData.styles[l].lvl;
-          k = itemData.transformers.length - 1;
-          while (iterations > 0) {
-            props = itemData.transformers[k].mProps.v.props;
-            mat.transform(props[0], props[1], props[2], props[3], props[4], props[5], props[6], props[7], props[8], props[9], props[10], props[11], props[12], props[13], props[14], props[15]);
-            iterations -= 1;
-            k -= 1;
-          }
-        }
-      } else {
-        mat = _identityMatrix;
-      }
-      paths = itemData.sh.paths;
-      jLen = paths._length;
-      if (redraw) {
-        pathStringTransformed = '';
-        for (j = 0; j < jLen; j += 1) {
-          pathNodes = paths.shapes[j];
-          if (pathNodes && pathNodes._length) {
-            pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
-          }
-        }
-        itemData.caches[l] = pathStringTransformed;
-      } else {
-        pathStringTransformed = itemData.caches[l];
-      }
-      itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
-      itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
-    }
-  }
-
-  function renderFill(styleData, itemData, isFirstFrame) {
-    var styleElem = itemData.style;
-
-    if (itemData.c._mdf || isFirstFrame) {
-      styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
-    }
-    if (itemData.o._mdf || isFirstFrame) {
-      styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
-    }
-  }
-
-  function renderGradientStroke(styleData, itemData, isFirstFrame) {
-    renderGradient(styleData, itemData, isFirstFrame);
-    renderStroke(styleData, itemData, isFirstFrame);
-  }
-
-  function renderGradient(styleData, itemData, isFirstFrame) {
-    var gfill = itemData.gf;
-    var hasOpacity = itemData.g._hasOpacity;
-    var pt1 = itemData.s.v;
-    var pt2 = itemData.e.v;
-
-    if (itemData.o._mdf || isFirstFrame) {
-      var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
-      itemData.style.pElem.setAttribute(attr, itemData.o.v);
-    }
-    if (itemData.s._mdf || isFirstFrame) {
-      var attr1 = styleData.t === 1 ? 'x1' : 'cx';
-      var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
-      gfill.setAttribute(attr1, pt1[0]);
-      gfill.setAttribute(attr2, pt1[1]);
-      if (hasOpacity && !itemData.g._collapsable) {
-        itemData.of.setAttribute(attr1, pt1[0]);
-        itemData.of.setAttribute(attr2, pt1[1]);
-      }
-    }
-    var stops;
-    var i;
-    var len;
-    var stop;
-    if (itemData.g._cmdf || isFirstFrame) {
-      stops = itemData.cst;
-      var cValues = itemData.g.c;
-      len = stops.length;
-      for (i = 0; i < len; i += 1) {
-        stop = stops[i];
-        stop.setAttribute('offset', cValues[i * 4] + '%');
-        stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
-      }
-    }
-    if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
-      var oValues = itemData.g.o;
-      if (itemData.g._collapsable) {
-        stops = itemData.cst;
-      } else {
-        stops = itemData.ost;
-      }
-      len = stops.length;
-      for (i = 0; i < len; i += 1) {
-        stop = stops[i];
-        if (!itemData.g._collapsable) {
-          stop.setAttribute('offset', oValues[i * 2] + '%');
-        }
-        stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
-      }
-    }
-    if (styleData.t === 1) {
-      if (itemData.e._mdf || isFirstFrame) {
-        gfill.setAttribute('x2', pt2[0]);
-        gfill.setAttribute('y2', pt2[1]);
-        if (hasOpacity && !itemData.g._collapsable) {
-          itemData.of.setAttribute('x2', pt2[0]);
-          itemData.of.setAttribute('y2', pt2[1]);
-        }
-      }
-    } else {
-      var rad;
-      if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
-        rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
-        gfill.setAttribute('r', rad);
-        if (hasOpacity && !itemData.g._collapsable) {
-          itemData.of.setAttribute('r', rad);
-        }
-      }
-      if (itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
-        if (!rad) {
-          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
-        }
-        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
-
-        var percent = itemData.h.v;
-        if (percent >= 1) {
-          percent = 0.99;
-        } else if (percent <= -1) {
-          percent = -0.99;
-        }
-        var dist = rad * percent;
-        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
-        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
-        gfill.setAttribute('fx', x);
-        gfill.setAttribute('fy', y);
-        if (hasOpacity && !itemData.g._collapsable) {
-          itemData.of.setAttribute('fx', x);
-          itemData.of.setAttribute('fy', y);
-        }
-      }
-      // gfill.setAttribute('fy','200');
-    }
-  }
-
-  function renderStroke(styleData, itemData, isFirstFrame) {
-    var styleElem = itemData.style;
-    var d = itemData.d;
-    if (d && (d._mdf || isFirstFrame) && d.dashStr) {
-      styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
-      styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
-    }
-    if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
-      styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
-    }
-    if (itemData.o._mdf || isFirstFrame) {
-      styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
-    }
-    if (itemData.w._mdf || isFirstFrame) {
-      styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
-      if (styleElem.msElem) {
-        styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
-      }
-    }
-  }
-
-  return ob;
-}());
-
-function SVGShapeElement(data, globalData, comp) {
-  // List of drawable elements
-  this.shapes = [];
-  // Full shape data
-  this.shapesData = data.shapes;
-  // List of styles that will be applied to shapes
-  this.stylesList = [];
-  // List of modifiers that will be applied to shapes
-  this.shapeModifiers = [];
-  // List of items in shape tree
-  this.itemsData = [];
-  // List of items in previous shape tree
-  this.processedElements = [];
-  // List of animated components
-  this.animatedContents = [];
-  this.initElement(data, globalData, comp);
-  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
-  // List of elements that have been created
-  this.prevViewData = [];
-  // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
-}
-
-extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
-
-SVGShapeElement.prototype.initSecondaryElement = function () {
-};
-
-SVGShapeElement.prototype.identityMatrix = new Matrix();
-
-SVGShapeElement.prototype.buildExpressionInterface = function () {};
-
-SVGShapeElement.prototype.createContent = function () {
-  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
-  this.filterUniqueShapes();
-};
-
-/*
-This method searches for multiple shapes that affect a single element and one of them is animated
-*/
-SVGShapeElement.prototype.filterUniqueShapes = function () {
-  var i;
-  var len = this.shapes.length;
-  var shape;
-  var j;
-  var jLen = this.stylesList.length;
-  var style;
-  var tempShapes = [];
-  var areAnimated = false;
-  for (j = 0; j < jLen; j += 1) {
-    style = this.stylesList[j];
-    areAnimated = false;
-    tempShapes.length = 0;
-    for (i = 0; i < len; i += 1) {
-      shape = this.shapes[i];
-      if (shape.styles.indexOf(style) !== -1) {
-        tempShapes.push(shape);
-        areAnimated = shape._isAnimated || areAnimated;
-      }
-    }
-    if (tempShapes.length > 1 && areAnimated) {
-      this.setShapesAsAnimated(tempShapes);
-    }
-  }
-};
-
-SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
-  var i;
-  var len = shapes.length;
-  for (i = 0; i < len; i += 1) {
-    shapes[i].setAsAnimated();
-  }
-};
-
-SVGShapeElement.prototype.createStyleElement = function (data, level) {
-  // TODO: prevent drawing of hidden styles
-  var elementData;
-  var styleOb = new SVGStyleData(data, level);
-
-  var pathElement = styleOb.pElem;
-  if (data.ty === 'st') {
-    elementData = new SVGStrokeStyleData(this, data, styleOb);
-  } else if (data.ty === 'fl') {
-    elementData = new SVGFillStyleData(this, data, styleOb);
-  } else if (data.ty === 'gf' || data.ty === 'gs') {
-    var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
-    elementData = new GradientConstructor(this, data, styleOb);
-    this.globalData.defs.appendChild(elementData.gf);
-    if (elementData.maskId) {
-      this.globalData.defs.appendChild(elementData.ms);
-      this.globalData.defs.appendChild(elementData.of);
-      pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
-    }
-  } else if (data.ty === 'no') {
-    elementData = new SVGNoStyleData(this, data, styleOb);
-  }
-
-  if (data.ty === 'st' || data.ty === 'gs') {
-    pathElement.setAttribute('stroke-linecap', lineCapEnum[data.lc || 2]);
-    pathElement.setAttribute('stroke-linejoin', lineJoinEnum[data.lj || 2]);
-    pathElement.setAttribute('fill-opacity', '0');
-    if (data.lj === 1) {
-      pathElement.setAttribute('stroke-miterlimit', data.ml);
-    }
-  }
-
-  if (data.r === 2) {
-    pathElement.setAttribute('fill-rule', 'evenodd');
-  }
-
-  if (data.ln) {
-    pathElement.setAttribute('id', data.ln);
-  }
-  if (data.cl) {
-    pathElement.setAttribute('class', data.cl);
-  }
-  if (data.bm) {
-    pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
-  }
-  this.stylesList.push(styleOb);
-  this.addToAnimatedContents(data, elementData);
-  return elementData;
-};
-
-SVGShapeElement.prototype.createGroupElement = function (data) {
-  var elementData = new ShapeGroupData();
-  if (data.ln) {
-    elementData.gr.setAttribute('id', data.ln);
-  }
-  if (data.cl) {
-    elementData.gr.setAttribute('class', data.cl);
-  }
-  if (data.bm) {
-    elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
-  }
-  return elementData;
-};
-
-SVGShapeElement.prototype.createTransformElement = function (data, container) {
-  var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
-  var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
-  this.addToAnimatedContents(data, elementData);
-  return elementData;
-};
-
-SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
-  var ty = 4;
-  if (data.ty === 'rc') {
-    ty = 5;
-  } else if (data.ty === 'el') {
-    ty = 6;
-  } else if (data.ty === 'sr') {
-    ty = 7;
-  }
-  var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
-  var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
-  this.shapes.push(elementData);
-  this.addShapeToModifiers(elementData);
-  this.addToAnimatedContents(data, elementData);
-  return elementData;
-};
-
-SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
-  var i = 0;
-  var len = this.animatedContents.length;
-  while (i < len) {
-    if (this.animatedContents[i].element === element) {
-      return;
-    }
-    i += 1;
-  }
-  this.animatedContents.push({
-    fn: SVGElementsRenderer.createRenderFunction(data),
-    element: element,
-    data: data,
-  });
-};
-
-SVGShapeElement.prototype.setElementStyles = function (elementData) {
-  var arr = elementData.styles;
-  var j;
-  var jLen = this.stylesList.length;
-  for (j = 0; j < jLen; j += 1) {
-    if (!this.stylesList[j].closed) {
-      arr.push(this.stylesList[j]);
-    }
-  }
-};
-
-SVGShapeElement.prototype.reloadShapes = function () {
-  this._isFirstFrame = true;
-  var i;
-  var len = this.itemsData.length;
-  for (i = 0; i < len; i += 1) {
-    this.prevViewData[i] = this.itemsData[i];
-  }
-  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
-  this.filterUniqueShapes();
-  len = this.dynamicProperties.length;
-  for (i = 0; i < len; i += 1) {
-    this.dynamicProperties[i].getValue();
-  }
-  this.renderModifiers();
-};
-
-SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
-  var ownTransformers = [].concat(transformers);
-  var i;
-  var len = arr.length - 1;
-  var j;
-  var jLen;
-  var ownStyles = [];
-  var ownModifiers = [];
-  var currentTransform;
-  var modifier;
-  var processedPos;
-  for (i = len; i >= 0; i -= 1) {
-    processedPos = this.searchProcessedElement(arr[i]);
-    if (!processedPos) {
-      arr[i]._render = render;
-    } else {
-      itemsData[i] = prevViewData[processedPos - 1];
-    }
-    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
-      if (!processedPos) {
-        itemsData[i] = this.createStyleElement(arr[i], level);
-      } else {
-        itemsData[i].style.closed = false;
-      }
-      if (arr[i]._render) {
-        if (itemsData[i].style.pElem.parentNode !== container) {
-          container.appendChild(itemsData[i].style.pElem);
-        }
-      }
-      ownStyles.push(itemsData[i].style);
-    } else if (arr[i].ty === 'gr') {
-      if (!processedPos) {
-        itemsData[i] = this.createGroupElement(arr[i]);
-      } else {
-        jLen = itemsData[i].it.length;
-        for (j = 0; j < jLen; j += 1) {
-          itemsData[i].prevViewData[j] = itemsData[i].it[j];
-        }
-      }
-      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
-      if (arr[i]._render) {
-        if (itemsData[i].gr.parentNode !== container) {
-          container.appendChild(itemsData[i].gr);
-        }
-      }
-    } else if (arr[i].ty === 'tr') {
-      if (!processedPos) {
-        itemsData[i] = this.createTransformElement(arr[i], container);
-      }
-      currentTransform = itemsData[i].transform;
-      ownTransformers.push(currentTransform);
-    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
-      if (!processedPos) {
-        itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
-      }
-      this.setElementStyles(itemsData[i]);
-    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb') {
-      if (!processedPos) {
-        modifier = ShapeModifiers.getModifier(arr[i].ty);
-        modifier.init(this, arr[i]);
-        itemsData[i] = modifier;
-        this.shapeModifiers.push(modifier);
-      } else {
-        modifier = itemsData[i];
-        modifier.closed = false;
-      }
-      ownModifiers.push(modifier);
-    } else if (arr[i].ty === 'rp') {
-      if (!processedPos) {
-        modifier = ShapeModifiers.getModifier(arr[i].ty);
-        itemsData[i] = modifier;
-        modifier.init(this, arr, i, itemsData);
-        this.shapeModifiers.push(modifier);
-        render = false;
-      } else {
-        modifier = itemsData[i];
-        modifier.closed = true;
-      }
-      ownModifiers.push(modifier);
-    }
-    this.addProcessedElement(arr[i], i + 1);
-  }
-  len = ownStyles.length;
-  for (i = 0; i < len; i += 1) {
-    ownStyles[i].closed = true;
-  }
-  len = ownModifiers.length;
-  for (i = 0; i < len; i += 1) {
-    ownModifiers[i].closed = true;
-  }
-};
-
-SVGShapeElement.prototype.renderInnerContent = function () {
-  this.renderModifiers();
-  var i;
-  var len = this.stylesList.length;
-  for (i = 0; i < len; i += 1) {
-    this.stylesList[i].reset();
-  }
-  this.renderShape();
-  for (i = 0; i < len; i += 1) {
-    if (this.stylesList[i]._mdf || this._isFirstFrame) {
-      if (this.stylesList[i].msElem) {
-        this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
-        // Adding M0 0 fixes same mask bug on all browsers
-        this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
-      }
-      this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
-    }
-  }
-};
-
-SVGShapeElement.prototype.renderShape = function () {
-  var i;
-  var len = this.animatedContents.length;
-  var animatedContent;
-  for (i = 0; i < len; i += 1) {
-    animatedContent = this.animatedContents[i];
-    if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
-      animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
-    }
-  }
-};
-
-SVGShapeElement.prototype.destroy = function () {
-  this.destroyBaseElement();
-  this.shapesData = null;
-  this.itemsData = null;
-};
-
-function LetterProps(o, sw, sc, fc, m, p) {
-  this.o = o;
-  this.sw = sw;
-  this.sc = sc;
-  this.fc = fc;
-  this.m = m;
-  this.p = p;
-  this._mdf = {
-    o: true,
-    sw: !!sw,
-    sc: !!sc,
-    fc: !!fc,
-    m: true,
-    p: true,
-  };
-}
-
-LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
-  this._mdf.o = false;
-  this._mdf.sw = false;
-  this._mdf.sc = false;
-  this._mdf.fc = false;
-  this._mdf.m = false;
-  this._mdf.p = false;
-  var updated = false;
-
-  if (this.o !== o) {
-    this.o = o;
-    this._mdf.o = true;
-    updated = true;
-  }
-  if (this.sw !== sw) {
-    this.sw = sw;
-    this._mdf.sw = true;
-    updated = true;
-  }
-  if (this.sc !== sc) {
-    this.sc = sc;
-    this._mdf.sc = true;
-    updated = true;
-  }
-  if (this.fc !== fc) {
-    this.fc = fc;
-    this._mdf.fc = true;
-    updated = true;
-  }
-  if (this.m !== m) {
-    this.m = m;
-    this._mdf.m = true;
-    updated = true;
-  }
-  if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
-    this.p = p;
-    this._mdf.p = true;
-    updated = true;
-  }
-  return updated;
-};
-
-function TextProperty(elem, data) {
-  this._frameId = initialDefaultFrame;
-  this.pv = '';
-  this.v = '';
-  this.kf = false;
-  this._isFirstFrame = true;
-  this._mdf = false;
-  this.data = data;
-  this.elem = elem;
-  this.comp = this.elem.comp;
-  this.keysIndex = 0;
-  this.canResize = false;
-  this.minimumFontSize = 1;
-  this.effectsSequence = [];
-  this.currentData = {
-    ascent: 0,
-    boxWidth: this.defaultBoxWidth,
-    f: '',
-    fStyle: '',
-    fWeight: '',
-    fc: '',
-    j: '',
-    justifyOffset: '',
-    l: [],
-    lh: 0,
-    lineWidths: [],
-    ls: '',
-    of: '',
-    s: '',
-    sc: '',
-    sw: 0,
-    t: 0,
-    tr: 0,
-    sz: 0,
-    ps: null,
-    fillColorAnim: false,
-    strokeColorAnim: false,
-    strokeWidthAnim: false,
-    yOffset: 0,
-    finalSize: 0,
-    finalText: [],
-    finalLineHeight: 0,
-    __complete: false,
-
-  };
-  this.copyData(this.currentData, this.data.d.k[0].s);
-
-  if (!this.searchProperty()) {
-    this.completeTextData(this.currentData);
-  }
-}
-
-TextProperty.prototype.defaultBoxWidth = [0, 0];
-
-TextProperty.prototype.copyData = function (obj, data) {
-  for (var s in data) {
-    if (Object.prototype.hasOwnProperty.call(data, s)) {
-      obj[s] = data[s];
-    }
-  }
-  return obj;
-};
-
-TextProperty.prototype.setCurrentData = function (data) {
-  if (!data.__complete) {
-    this.completeTextData(data);
-  }
-  this.currentData = data;
-  this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
-  this._mdf = true;
-};
-
-TextProperty.prototype.searchProperty = function () {
-  return this.searchKeyframes();
-};
-
-TextProperty.prototype.searchKeyframes = function () {
-  this.kf = this.data.d.k.length > 1;
-  if (this.kf) {
-    this.addEffect(this.getKeyframeValue.bind(this));
-  }
-  return this.kf;
-};
-
-TextProperty.prototype.addEffect = function (effectFunction) {
-  this.effectsSequence.push(effectFunction);
-  this.elem.addDynamicProperty(this);
-};
-
-TextProperty.prototype.getValue = function (_finalValue) {
-  if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
-    return;
-  }
-  this.currentData.t = this.data.d.k[this.keysIndex].s.t;
-  var currentValue = this.currentData;
-  var currentIndex = this.keysIndex;
-  if (this.lock) {
-    this.setCurrentData(this.currentData);
-    return;
-  }
-  this.lock = true;
-  this._mdf = false;
-  var i; var
-    len = this.effectsSequence.length;
-  var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
-  for (i = 0; i < len; i += 1) {
-    // Checking if index changed to prevent creating a new object every time the expression updates.
-    if (currentIndex !== this.keysIndex) {
-      finalValue = this.effectsSequence[i](finalValue, finalValue.t);
-    } else {
-      finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
-    }
-  }
-  if (currentValue !== finalValue) {
-    this.setCurrentData(finalValue);
-  }
-  this.v = this.currentData;
-  this.pv = this.v;
-  this.lock = false;
-  this.frameId = this.elem.globalData.frameId;
-};
-
-TextProperty.prototype.getKeyframeValue = function () {
-  var textKeys = this.data.d.k;
-  var frameNum = this.elem.comp.renderedFrame;
-  var i = 0; var
-    len = textKeys.length;
-  while (i <= len - 1) {
-    if (i === len - 1 || textKeys[i + 1].t > frameNum) {
-      break;
-    }
-    i += 1;
-  }
-  if (this.keysIndex !== i) {
-    this.keysIndex = i;
-  }
-  return this.data.d.k[this.keysIndex].s;
-};
-
-TextProperty.prototype.buildFinalText = function (text) {
-  var charactersArray = [];
-  var i = 0;
-  var len = text.length;
-  var charCode;
-  var secondCharCode;
-  var shouldCombine = false;
-  while (i < len) {
-    charCode = text.charCodeAt(i);
-    if (FontManager.isCombinedCharacter(charCode)) {
-      charactersArray[charactersArray.length - 1] += text.charAt(i);
-    } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
-      secondCharCode = text.charCodeAt(i + 1);
-      if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
-        if (shouldCombine || FontManager.isModifier(charCode, secondCharCode)) {
-          charactersArray[charactersArray.length - 1] += text.substr(i, 2);
-          shouldCombine = false;
-        } else {
-          charactersArray.push(text.substr(i, 2));
-        }
-        i += 1;
-      } else {
-        charactersArray.push(text.charAt(i));
-      }
-    } else if (charCode > 0xDBFF) {
-      secondCharCode = text.charCodeAt(i + 1);
-      if (FontManager.isZeroWidthJoiner(charCode, secondCharCode)) {
-        shouldCombine = true;
-        charactersArray[charactersArray.length - 1] += text.substr(i, 2);
-        i += 1;
-      } else {
-        charactersArray.push(text.charAt(i));
-      }
-    } else if (FontManager.isZeroWidthJoiner(charCode)) {
-      charactersArray[charactersArray.length - 1] += text.charAt(i);
-      shouldCombine = true;
-    } else {
-      charactersArray.push(text.charAt(i));
-    }
-    i += 1;
-  }
-  return charactersArray;
-};
-
-TextProperty.prototype.completeTextData = function (documentData) {
-  documentData.__complete = true;
-  var fontManager = this.elem.globalData.fontManager;
-  var data = this.data;
-  var letters = [];
-  var i; var
-    len;
-  var newLineFlag; var index = 0; var
-    val;
-  var anchorGrouping = data.m.g;
-  var currentSize = 0; var currentPos = 0; var currentLine = 0; var
-    lineWidths = [];
-  var lineWidth = 0;
-  var maxLineWidth = 0;
-  var j; var
-    jLen;
-  var fontData = fontManager.getFontByName(documentData.f);
-  var charData; var
-    cLength = 0;
-
-  var fontProps = getFontProperties(fontData);
-  documentData.fWeight = fontProps.weight;
-  documentData.fStyle = fontProps.style;
-  documentData.finalSize = documentData.s;
-  documentData.finalText = this.buildFinalText(documentData.t);
-  len = documentData.finalText.length;
-  documentData.finalLineHeight = documentData.lh;
-  var trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
-  var charCode;
-  if (documentData.sz) {
-    var flag = true;
-    var boxWidth = documentData.sz[0];
-    var boxHeight = documentData.sz[1];
-    var currentHeight; var
-      finalText;
-    while (flag) {
-      finalText = this.buildFinalText(documentData.t);
-      currentHeight = 0;
-      lineWidth = 0;
-      len = finalText.length;
-      trackingOffset = (documentData.tr / 1000) * documentData.finalSize;
-      var lastSpaceIndex = -1;
-      for (i = 0; i < len; i += 1) {
-        charCode = finalText[i].charCodeAt(0);
-        newLineFlag = false;
-        if (finalText[i] === ' ') {
-          lastSpaceIndex = i;
-        } else if (charCode === 13 || charCode === 3) {
-          lineWidth = 0;
-          newLineFlag = true;
-          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-        }
-        if (fontManager.chars) {
-          charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
-          cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
-        } else {
-          // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
-          cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
-        }
-        if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
-          if (lastSpaceIndex === -1) {
-            len += 1;
-          } else {
-            i = lastSpaceIndex;
-          }
-          currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
-          finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
-          // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
-          lastSpaceIndex = -1;
-          lineWidth = 0;
-        } else {
-          lineWidth += cLength;
-          lineWidth += trackingOffset;
-        }
-      }
-      currentHeight += (fontData.ascent * documentData.finalSize) / 100;
-      if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
-        documentData.finalSize -= 1;
-        documentData.finalLineHeight = (documentData.finalSize * documentData.lh) / documentData.s;
-      } else {
-        documentData.finalText = finalText;
-        len = documentData.finalText.length;
-        flag = false;
-      }
-    }
-  }
-  lineWidth = -trackingOffset;
-  cLength = 0;
-  var uncollapsedSpaces = 0;
-  var currentChar;
-  for (i = 0; i < len; i += 1) {
-    newLineFlag = false;
-    currentChar = documentData.finalText[i];
-    charCode = currentChar.charCodeAt(0);
-    if (charCode === 13 || charCode === 3) {
-      uncollapsedSpaces = 0;
-      lineWidths.push(lineWidth);
-      maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
-      lineWidth = -2 * trackingOffset;
-      val = '';
-      newLineFlag = true;
-      currentLine += 1;
-    } else {
-      val = currentChar;
-    }
-    if (fontManager.chars) {
-      charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
-      cLength = newLineFlag ? 0 : (charData.w * documentData.finalSize) / 100;
-    } else {
-      // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
-      // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
-      cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
-    }
-
-    //
-    if (currentChar === ' ') {
-      uncollapsedSpaces += cLength + trackingOffset;
-    } else {
-      lineWidth += cLength + trackingOffset + uncollapsedSpaces;
-      uncollapsedSpaces = 0;
-    }
-    letters.push({
-      l: cLength, an: cLength, add: currentSize, n: newLineFlag, anIndexes: [], val: val, line: currentLine, animatorJustifyOffset: 0,
-    });
-    if (anchorGrouping == 2) { // eslint-disable-line eqeqeq
-      currentSize += cLength;
-      if (val === '' || val === ' ' || i === len - 1) {
-        if (val === '' || val === ' ') {
-          currentSize -= cLength;
-        }
-        while (currentPos <= i) {
-          letters[currentPos].an = currentSize;
-          letters[currentPos].ind = index;
-          letters[currentPos].extra = cLength;
-          currentPos += 1;
-        }
-        index += 1;
-        currentSize = 0;
-      }
-    } else if (anchorGrouping == 3) { // eslint-disable-line eqeqeq
-      currentSize += cLength;
-      if (val === '' || i === len - 1) {
-        if (val === '') {
-          currentSize -= cLength;
-        }
-        while (currentPos <= i) {
-          letters[currentPos].an = currentSize;
-          letters[currentPos].ind = index;
-          letters[currentPos].extra = cLength;
-          currentPos += 1;
-        }
-        currentSize = 0;
-        index += 1;
-      }
-    } else {
-      letters[index].ind = index;
-      letters[index].extra = 0;
-      index += 1;
-    }
-  }
-  documentData.l = letters;
-  maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
-  lineWidths.push(lineWidth);
-  if (documentData.sz) {
-    documentData.boxWidth = documentData.sz[0];
-    documentData.justifyOffset = 0;
-  } else {
-    documentData.boxWidth = maxLineWidth;
-    switch (documentData.j) {
-      case 1:
-        documentData.justifyOffset = -documentData.boxWidth;
-        break;
-      case 2:
-        documentData.justifyOffset = -documentData.boxWidth / 2;
-        break;
-      default:
-        documentData.justifyOffset = 0;
-    }
-  }
-  documentData.lineWidths = lineWidths;
-
-  var animators = data.a; var animatorData; var
-    letterData;
-  jLen = animators.length;
-  var based; var ind; var
-    indexes = [];
-  for (j = 0; j < jLen; j += 1) {
-    animatorData = animators[j];
-    if (animatorData.a.sc) {
-      documentData.strokeColorAnim = true;
-    }
-    if (animatorData.a.sw) {
-      documentData.strokeWidthAnim = true;
-    }
-    if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
-      documentData.fillColorAnim = true;
-    }
-    ind = 0;
-    based = animatorData.s.b;
-    for (i = 0; i < len; i += 1) {
-      letterData = letters[i];
-      letterData.anIndexes[j] = ind;
-      if ((based == 1 && letterData.val !== '') || (based == 2 && letterData.val !== '' && letterData.val !== ' ') || (based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1)) || (based == 4 && (letterData.n || i == len - 1))) { // eslint-disable-line eqeqeq
-        if (animatorData.s.rn === 1) {
-          indexes.push(ind);
-        }
-        ind += 1;
-      }
-    }
-    data.a[j].s.totalChars = ind;
-    var currentInd = -1; var
-      newInd;
-    if (animatorData.s.rn === 1) {
-      for (i = 0; i < len; i += 1) {
-        letterData = letters[i];
-        if (currentInd != letterData.anIndexes[j]) { // eslint-disable-line eqeqeq
-          currentInd = letterData.anIndexes[j];
-          newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
-        }
-        letterData.anIndexes[j] = newInd;
-      }
-    }
-  }
-  documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
-  documentData.ls = documentData.ls || 0;
-  documentData.ascent = (fontData.ascent * documentData.finalSize) / 100;
-};
-
-TextProperty.prototype.updateDocumentData = function (newData, index) {
-  index = index === undefined ? this.keysIndex : index;
-  var dData = this.copyData({}, this.data.d.k[index].s);
-  dData = this.copyData(dData, newData);
-  this.data.d.k[index].s = dData;
-  this.recalculate(index);
-  this.elem.addDynamicProperty(this);
-};
-
-TextProperty.prototype.recalculate = function (index) {
-  var dData = this.data.d.k[index].s;
-  dData.__complete = false;
-  this.keysIndex = 0;
-  this._isFirstFrame = true;
-  this.getValue(dData);
-};
-
-TextProperty.prototype.canResizeFont = function (_canResize) {
-  this.canResize = _canResize;
-  this.recalculate(this.keysIndex);
-  this.elem.addDynamicProperty(this);
-};
-
-TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
-  this.minimumFontSize = Math.floor(_fontValue) || 1;
-  this.recalculate(this.keysIndex);
-  this.elem.addDynamicProperty(this);
-};
-
-const TextSelectorProp = (function () {
-  var max = Math.max;
-  var min = Math.min;
-  var floor = Math.floor;
-
-  function TextSelectorPropFactory(elem, data) {
-    this._currentTextLength = -1;
-    this.k = false;
-    this.data = data;
-    this.elem = elem;
-    this.comp = elem.comp;
-    this.finalS = 0;
-    this.finalE = 0;
-    this.initDynamicPropertyContainer(elem);
-    this.s = PropertyFactory.getProp(elem, data.s || { k: 0 }, 0, 0, this);
-    if ('e' in data) {
-      this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
-    } else {
-      this.e = { v: 100 };
-    }
-    this.o = PropertyFactory.getProp(elem, data.o || { k: 0 }, 0, 0, this);
-    this.xe = PropertyFactory.getProp(elem, data.xe || { k: 0 }, 0, 0, this);
-    this.ne = PropertyFactory.getProp(elem, data.ne || { k: 0 }, 0, 0, this);
-    this.sm = PropertyFactory.getProp(elem, data.sm || { k: 100 }, 0, 0, this);
-    this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
-    if (!this.dynamicProperties.length) {
-      this.getValue();
-    }
-  }
-
-  TextSelectorPropFactory.prototype = {
-    getMult: function (ind) {
-      if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
-        this.getValue();
-      }
-      var x1 = 0;
-      var y1 = 0;
-      var x2 = 1;
-      var y2 = 1;
-      if (this.ne.v > 0) {
-        x1 = this.ne.v / 100.0;
-      } else {
-        y1 = -this.ne.v / 100.0;
-      }
-      if (this.xe.v > 0) {
-        x2 = 1.0 - this.xe.v / 100.0;
-      } else {
-        y2 = 1.0 + this.xe.v / 100.0;
-      }
-      var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
-
-      var mult = 0;
-      var s = this.finalS;
-      var e = this.finalE;
-      var type = this.data.sh;
-      if (type === 2) {
-        if (e === s) {
-          mult = ind >= e ? 1 : 0;
-        } else {
-          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-        }
-        mult = easer(mult);
-      } else if (type === 3) {
-        if (e === s) {
-          mult = ind >= e ? 0 : 1;
-        } else {
-          mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-        }
-
-        mult = easer(mult);
-      } else if (type === 4) {
-        if (e === s) {
-          mult = 0;
-        } else {
-          mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
-          if (mult < 0.5) {
-            mult *= 2;
-          } else {
-            mult = 1 - 2 * (mult - 0.5);
-          }
-        }
-        mult = easer(mult);
-      } else if (type === 5) {
-        if (e === s) {
-          mult = 0;
-        } else {
-          var tot = e - s;
-          /* ind += 0.5;
-                    mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
-          ind = min(max(0, ind + 0.5 - s), e - s);
-          var x = -tot / 2 + ind;
-          var a = tot / 2;
-          mult = Math.sqrt(1 - (x * x) / (a * a));
-        }
-        mult = easer(mult);
-      } else if (type === 6) {
-        if (e === s) {
-          mult = 0;
-        } else {
-          ind = min(max(0, ind + 0.5 - s), e - s);
-          mult = (1 + (Math.cos((Math.PI + Math.PI * 2 * (ind) / (e - s))))) / 2; // eslint-disable-line
-        }
-        mult = easer(mult);
-      } else {
-        if (ind >= floor(s)) {
-          if (ind - s < 0) {
-            mult = max(0, min(min(e, 1) - (s - ind), 1));
-          } else {
-            mult = max(0, min(e - ind, 1));
-          }
-        }
-        mult = easer(mult);
-      }
-      // Smoothness implementation.
-      // The smoothness represents a reduced range of the original [0; 1] range.
-      // if smoothness is 25%, the new range will be [0.375; 0.625]
-      // Steps are:
-      // - find the lower value of the new range (threshold)
-      // - if multiplier is smaller than that value, floor it to 0
-      // - if it is larger,
-      //     - subtract the threshold
-      //     - divide it by the smoothness (this will return the range to [0; 1])
-      // Note: If it doesn't work on some scenarios, consider applying it before the easer.
-      if (this.sm.v !== 100) {
-        var smoothness = this.sm.v * 0.01;
-        if (smoothness === 0) {
-          smoothness = 0.00000001;
-        }
-        var threshold = 0.5 - smoothness * 0.5;
-        if (mult < threshold) {
-          mult = 0;
-        } else {
-          mult = (mult - threshold) / smoothness;
-          if (mult > 1) {
-            mult = 1;
-          }
-        }
-      }
-      return mult * this.a.v;
-    },
-    getValue: function (newCharsFlag) {
-      this.iterateDynamicProperties();
-      this._mdf = newCharsFlag || this._mdf;
-      this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
-      if (newCharsFlag && this.data.r === 2) {
-        this.e.v = this._currentTextLength;
-      }
-      var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
-      var o = this.o.v / divisor;
-      var s = this.s.v / divisor + o;
-      var e = (this.e.v / divisor) + o;
-      if (s > e) {
-        var _s = s;
-        s = e;
-        e = _s;
-      }
-      this.finalS = s;
-      this.finalE = e;
-    },
-  };
-  extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
-
-  function getTextSelectorProp(elem, data, arr) {
-    return new TextSelectorPropFactory(elem, data, arr);
-  }
-
-  return {
-    getTextSelectorProp: getTextSelectorProp,
-  };
-}());
-
-function TextAnimatorDataProperty(elem, animatorProps, container) {
-  var defaultData = { propType: false };
-  var getProp = PropertyFactory.getProp;
-  var textAnimatorAnimatables = animatorProps.a;
-  this.a = {
-    r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
-    rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
-    ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
-    sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
-    sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
-    s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
-    a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
-    o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
-    p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
-    sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
-    sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
-    fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
-    fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
-    fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
-    fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
-    t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData,
-  };
-
-  this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
-  this.s.t = animatorProps.s.t;
-}
-
-function TextAnimatorProperty(textData, renderType, elem) {
-  this._isFirstFrame = true;
-  this._hasMaskedPath = false;
-  this._frameId = -1;
-  this._textData = textData;
-  this._renderType = renderType;
-  this._elem = elem;
-  this._animatorsData = createSizedArray(this._textData.a.length);
-  this._pathData = {};
-  this._moreOptions = {
-    alignment: {},
-  };
-  this.renderedLetters = [];
-  this.lettersChangedFlag = false;
-  this.initDynamicPropertyContainer(elem);
-}
-
-TextAnimatorProperty.prototype.searchProperties = function () {
-  var i;
-  var len = this._textData.a.length;
-  var animatorProps;
-  var getProp = PropertyFactory.getProp;
-  for (i = 0; i < len; i += 1) {
-    animatorProps = this._textData.a[i];
-    this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
-  }
-  if (this._textData.p && 'm' in this._textData.p) {
-    this._pathData = {
-      a: getProp(this._elem, this._textData.p.a, 0, 0, this),
-      f: getProp(this._elem, this._textData.p.f, 0, 0, this),
-      l: getProp(this._elem, this._textData.p.l, 0, 0, this),
-      r: getProp(this._elem, this._textData.p.r, 0, 0, this),
-      p: getProp(this._elem, this._textData.p.p, 0, 0, this),
-      m: this._elem.maskManager.getMaskProperty(this._textData.p.m),
-    };
-    this._hasMaskedPath = true;
-  } else {
-    this._hasMaskedPath = false;
-  }
-  this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
-};
-
-TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
-  this.lettersChangedFlag = lettersChangedFlag;
-  if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
-    return;
-  }
-  this._isFirstFrame = false;
-  var alignment = this._moreOptions.alignment.v;
-  var animators = this._animatorsData;
-  var textData = this._textData;
-  var matrixHelper = this.mHelper;
-  var renderType = this._renderType;
-  var renderedLettersCount = this.renderedLetters.length;
-  var xPos;
-  var yPos;
-  var i;
-  var len;
-  var letters = documentData.l;
-  var pathInfo;
-  var currentLength;
-  var currentPoint;
-  var segmentLength;
-  var flag;
-  var pointInd;
-  var segmentInd;
-  var prevPoint;
-  var points;
-  var segments;
-  var partialLength;
-  var totalLength;
-  var perc;
-  var tanAngle;
-  var mask;
-  if (this._hasMaskedPath) {
-    mask = this._pathData.m;
-    if (!this._pathData.n || this._pathData._mdf) {
-      var paths = mask.v;
-      if (this._pathData.r.v) {
-        paths = paths.reverse();
-      }
-      // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
-      pathInfo = {
-        tLength: 0,
-        segments: [],
-      };
-      len = paths._length - 1;
-      var bezierData;
-      totalLength = 0;
-      for (i = 0; i < len; i += 1) {
-        bezierData = bez.buildBezierData(paths.v[i],
-          paths.v[i + 1],
-          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
-          [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
-        pathInfo.tLength += bezierData.segmentLength;
-        pathInfo.segments.push(bezierData);
-        totalLength += bezierData.segmentLength;
-      }
-      i = len;
-      if (mask.v.c) {
-        bezierData = bez.buildBezierData(paths.v[i],
-          paths.v[0],
-          [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]],
-          [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
-        pathInfo.tLength += bezierData.segmentLength;
-        pathInfo.segments.push(bezierData);
-        totalLength += bezierData.segmentLength;
-      }
-      this._pathData.pi = pathInfo;
-    }
-    pathInfo = this._pathData.pi;
-
-    currentLength = this._pathData.f.v;
-    segmentInd = 0;
-    pointInd = 1;
-    segmentLength = 0;
-    flag = true;
-    segments = pathInfo.segments;
-    if (currentLength < 0 && mask.v.c) {
-      if (pathInfo.tLength < Math.abs(currentLength)) {
-        currentLength = -Math.abs(currentLength) % pathInfo.tLength;
-      }
-      segmentInd = segments.length - 1;
-      points = segments[segmentInd].points;
-      pointInd = points.length - 1;
-      while (currentLength < 0) {
-        currentLength += points[pointInd].partialLength;
-        pointInd -= 1;
-        if (pointInd < 0) {
-          segmentInd -= 1;
-          points = segments[segmentInd].points;
-          pointInd = points.length - 1;
-        }
-      }
-    }
-    points = segments[segmentInd].points;
-    prevPoint = points[pointInd - 1];
-    currentPoint = points[pointInd];
-    partialLength = currentPoint.partialLength;
-  }
-
-  len = letters.length;
-  xPos = 0;
-  yPos = 0;
-  var yOff = documentData.finalSize * 1.2 * 0.714;
-  var firstLine = true;
-  var animatorProps;
-  var animatorSelector;
-  var j;
-  var jLen;
-  var letterValue;
-
-  jLen = animators.length;
-
-  var mult;
-  var ind = -1;
-  var offf;
-  var xPathPos;
-  var yPathPos;
-  var initPathPos = currentLength;
-  var initSegmentInd = segmentInd;
-  var initPointInd = pointInd;
-  var currentLine = -1;
-  var elemOpacity;
-  var sc;
-  var sw;
-  var fc;
-  var k;
-  var letterSw;
-  var letterSc;
-  var letterFc;
-  var letterM = '';
-  var letterP = this.defaultPropsArray;
-  var letterO;
-
-  //
-  if (documentData.j === 2 || documentData.j === 1) {
-    var animatorJustifyOffset = 0;
-    var animatorFirstCharOffset = 0;
-    var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
-    var lastIndex = 0;
-    var isNewLine = true;
-
-    for (i = 0; i < len; i += 1) {
-      if (letters[i].n) {
-        if (animatorJustifyOffset) {
-          animatorJustifyOffset += animatorFirstCharOffset;
-        }
-        while (lastIndex < i) {
-          letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
-          lastIndex += 1;
-        }
-        animatorJustifyOffset = 0;
-        isNewLine = true;
-      } else {
-        for (j = 0; j < jLen; j += 1) {
-          animatorProps = animators[j].a;
-          if (animatorProps.t.propType) {
-            if (isNewLine && documentData.j === 2) {
-              animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
-            }
-            animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-            if (mult.length) {
-              animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
-            } else {
-              animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
-            }
-          }
-        }
-        isNewLine = false;
-      }
-    }
-    if (animatorJustifyOffset) {
-      animatorJustifyOffset += animatorFirstCharOffset;
-    }
-    while (lastIndex < i) {
-      letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
-      lastIndex += 1;
-    }
-  }
-  //
-
-  for (i = 0; i < len; i += 1) {
-    matrixHelper.reset();
-    elemOpacity = 1;
-    if (letters[i].n) {
-      xPos = 0;
-      yPos += documentData.yOffset;
-      yPos += firstLine ? 1 : 0;
-      currentLength = initPathPos;
-      firstLine = false;
-      if (this._hasMaskedPath) {
-        segmentInd = initSegmentInd;
-        pointInd = initPointInd;
-        points = segments[segmentInd].points;
-        prevPoint = points[pointInd - 1];
-        currentPoint = points[pointInd];
-        partialLength = currentPoint.partialLength;
-        segmentLength = 0;
-      }
-      letterM = '';
-      letterFc = '';
-      letterSw = '';
-      letterO = '';
-      letterP = this.defaultPropsArray;
-    } else {
-      if (this._hasMaskedPath) {
-        if (currentLine !== letters[i].line) {
-          switch (documentData.j) {
-            case 1:
-              currentLength += totalLength - documentData.lineWidths[letters[i].line];
-              break;
-            case 2:
-              currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
-              break;
-            default:
-              break;
-          }
-          currentLine = letters[i].line;
-        }
-        if (ind !== letters[i].ind) {
-          if (letters[ind]) {
-            currentLength += letters[ind].extra;
-          }
-          currentLength += letters[i].an / 2;
-          ind = letters[i].ind;
-        }
-        currentLength += (alignment[0] * letters[i].an) * 0.005;
-        var animatorOffset = 0;
-        for (j = 0; j < jLen; j += 1) {
-          animatorProps = animators[j].a;
-          if (animatorProps.p.propType) {
-            animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-            if (mult.length) {
-              animatorOffset += animatorProps.p.v[0] * mult[0];
-            } else {
-              animatorOffset += animatorProps.p.v[0] * mult;
-            }
-          }
-          if (animatorProps.a.propType) {
-            animatorSelector = animators[j].s;
-            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-            if (mult.length) {
-              animatorOffset += animatorProps.a.v[0] * mult[0];
-            } else {
-              animatorOffset += animatorProps.a.v[0] * mult;
-            }
-          }
-        }
-        flag = true;
-        // Force alignment only works with a single line for now
-        if (this._pathData.a.v) {
-          currentLength = letters[0].an * 0.5 + ((totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind) / (len - 1);
-          currentLength += this._pathData.f.v;
-        }
-        while (flag) {
-          if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
-            perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
-            xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
-            yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
-            matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, -(alignment[1] * yOff) * 0.01);
-            flag = false;
-          } else if (points) {
-            segmentLength += currentPoint.partialLength;
-            pointInd += 1;
-            if (pointInd >= points.length) {
-              pointInd = 0;
-              segmentInd += 1;
-              if (!segments[segmentInd]) {
-                if (mask.v.c) {
-                  pointInd = 0;
-                  segmentInd = 0;
-                  points = segments[segmentInd].points;
-                } else {
-                  segmentLength -= currentPoint.partialLength;
-                  points = null;
-                }
-              } else {
-                points = segments[segmentInd].points;
-              }
-            }
-            if (points) {
-              prevPoint = currentPoint;
-              currentPoint = points[pointInd];
-              partialLength = currentPoint.partialLength;
-            }
-          }
-        }
-        offf = letters[i].an / 2 - letters[i].add;
-        matrixHelper.translate(-offf, 0, 0);
-      } else {
-        offf = letters[i].an / 2 - letters[i].add;
-        matrixHelper.translate(-offf, 0, 0);
-
-        // Grouping alignment
-        matrixHelper.translate((-alignment[0] * letters[i].an) * 0.005, (-alignment[1] * yOff) * 0.01, 0);
-      }
-
-      for (j = 0; j < jLen; j += 1) {
-        animatorProps = animators[j].a;
-        if (animatorProps.t.propType) {
-          animatorSelector = animators[j].s;
-          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-          // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
-          if (xPos !== 0 || documentData.j !== 0) {
-            if (this._hasMaskedPath) {
-              if (mult.length) {
-                currentLength += animatorProps.t.v * mult[0];
-              } else {
-                currentLength += animatorProps.t.v * mult;
-              }
-            } else if (mult.length) {
-              xPos += animatorProps.t.v * mult[0];
-            } else {
-              xPos += animatorProps.t.v * mult;
-            }
-          }
-        }
-      }
-      if (documentData.strokeWidthAnim) {
-        sw = documentData.sw || 0;
-      }
-      if (documentData.strokeColorAnim) {
-        if (documentData.sc) {
-          sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
-        } else {
-          sc = [0, 0, 0];
-        }
-      }
-      if (documentData.fillColorAnim && documentData.fc) {
-        fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
-      }
-      for (j = 0; j < jLen; j += 1) {
-        animatorProps = animators[j].a;
-        if (animatorProps.a.propType) {
-          animatorSelector = animators[j].s;
-          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-
-          if (mult.length) {
-            matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
-          } else {
-            matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
-          }
-        }
-      }
-      for (j = 0; j < jLen; j += 1) {
-        animatorProps = animators[j].a;
-        if (animatorProps.s.propType) {
-          animatorSelector = animators[j].s;
-          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-          if (mult.length) {
-            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult[0]), 1 + ((animatorProps.s.v[1] - 1) * mult[1]), 1);
-          } else {
-            matrixHelper.scale(1 + ((animatorProps.s.v[0] - 1) * mult), 1 + ((animatorProps.s.v[1] - 1) * mult), 1);
-          }
-        }
-      }
-      for (j = 0; j < jLen; j += 1) {
-        animatorProps = animators[j].a;
-        animatorSelector = animators[j].s;
-        mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-        if (animatorProps.sk.propType) {
-          if (mult.length) {
-            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
-          } else {
-            matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
-          }
-        }
-        if (animatorProps.r.propType) {
-          if (mult.length) {
-            matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
-          } else {
-            matrixHelper.rotateZ(-animatorProps.r.v * mult);
-          }
-        }
-        if (animatorProps.ry.propType) {
-          if (mult.length) {
-            matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
-          } else {
-            matrixHelper.rotateY(animatorProps.ry.v * mult);
-          }
-        }
-        if (animatorProps.rx.propType) {
-          if (mult.length) {
-            matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
-          } else {
-            matrixHelper.rotateX(animatorProps.rx.v * mult);
-          }
-        }
-        if (animatorProps.o.propType) {
-          if (mult.length) {
-            elemOpacity += ((animatorProps.o.v) * mult[0] - elemOpacity) * mult[0];
-          } else {
-            elemOpacity += ((animatorProps.o.v) * mult - elemOpacity) * mult;
-          }
-        }
-        if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
-          if (mult.length) {
-            sw += animatorProps.sw.v * mult[0];
-          } else {
-            sw += animatorProps.sw.v * mult;
-          }
-        }
-        if (documentData.strokeColorAnim && animatorProps.sc.propType) {
-          for (k = 0; k < 3; k += 1) {
-            if (mult.length) {
-              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
-            } else {
-              sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
-            }
-          }
-        }
-        if (documentData.fillColorAnim && documentData.fc) {
-          if (animatorProps.fc.propType) {
-            for (k = 0; k < 3; k += 1) {
-              if (mult.length) {
-                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
-              } else {
-                fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
-              }
-            }
-          }
-          if (animatorProps.fh.propType) {
-            if (mult.length) {
-              fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
-            } else {
-              fc = addHueToRGB(fc, animatorProps.fh.v * mult);
-            }
-          }
-          if (animatorProps.fs.propType) {
-            if (mult.length) {
-              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
-            } else {
-              fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
-            }
-          }
-          if (animatorProps.fb.propType) {
-            if (mult.length) {
-              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
-            } else {
-              fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
-            }
-          }
-        }
-      }
-
-      for (j = 0; j < jLen; j += 1) {
-        animatorProps = animators[j].a;
-
-        if (animatorProps.p.propType) {
-          animatorSelector = animators[j].s;
-          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
-          if (this._hasMaskedPath) {
-            if (mult.length) {
-              matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
-            } else {
-              matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
-            }
-          } else if (mult.length) {
-            matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
-          } else {
-            matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
-          }
-        }
-      }
-      if (documentData.strokeWidthAnim) {
-        letterSw = sw < 0 ? 0 : sw;
-      }
-      if (documentData.strokeColorAnim) {
-        letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
-      }
-      if (documentData.fillColorAnim && documentData.fc) {
-        letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
-      }
-
-      if (this._hasMaskedPath) {
-        matrixHelper.translate(0, -documentData.ls);
-
-        matrixHelper.translate(0, (alignment[1] * yOff) * 0.01 + yPos, 0);
-        if (this._pathData.p.v) {
-          tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
-          var rot = (Math.atan(tanAngle) * 180) / Math.PI;
-          if (currentPoint.point[0] < prevPoint.point[0]) {
-            rot += 180;
-          }
-          matrixHelper.rotate((-rot * Math.PI) / 180);
-        }
-        matrixHelper.translate(xPathPos, yPathPos, 0);
-        currentLength -= (alignment[0] * letters[i].an) * 0.005;
-        if (letters[i + 1] && ind !== letters[i + 1].ind) {
-          currentLength += letters[i].an / 2;
-          currentLength += (documentData.tr * 0.001) * documentData.finalSize;
-        }
-      } else {
-        matrixHelper.translate(xPos, yPos, 0);
-
-        if (documentData.ps) {
-          // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
-          matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
-        }
-        switch (documentData.j) {
-          case 1:
-            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
-            break;
-          case 2:
-            matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
-            break;
-          default:
-            break;
-        }
-        matrixHelper.translate(0, -documentData.ls);
-        matrixHelper.translate(offf, 0, 0);
-        matrixHelper.translate((alignment[0] * letters[i].an) * 0.005, (alignment[1] * yOff) * 0.01, 0);
-        xPos += letters[i].l + (documentData.tr * 0.001) * documentData.finalSize;
-      }
-      if (renderType === 'html') {
-        letterM = matrixHelper.toCSS();
-      } else if (renderType === 'svg') {
-        letterM = matrixHelper.to2dCSS();
-      } else {
-        letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
-      }
-      letterO = elemOpacity;
-    }
-
-    if (renderedLettersCount <= i) {
-      letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
-      this.renderedLetters.push(letterValue);
-      renderedLettersCount += 1;
-      this.lettersChangedFlag = true;
-    } else {
-      letterValue = this.renderedLetters[i];
-      this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
-    }
-  }
-};
-
-TextAnimatorProperty.prototype.getValue = function () {
-  if (this._elem.globalData.frameId === this._frameId) {
-    return;
-  }
-  this._frameId = this._elem.globalData.frameId;
-  this.iterateDynamicProperties();
-};
-
-TextAnimatorProperty.prototype.mHelper = new Matrix();
-TextAnimatorProperty.prototype.defaultPropsArray = [];
-extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
-
-function ITextElement() {
-}
-
-ITextElement.prototype.initElement = function (data, globalData, comp) {
-  this.lettersChangedFlag = true;
-  this.initFrame();
-  this.initBaseData(data, globalData, comp);
-  this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
-  this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
-  this.initTransform(data, globalData, comp);
-  this.initHierarchy();
-  this.initRenderable();
-  this.initRendererElement();
-  this.createContainerElements();
-  this.createRenderableComponents();
-  this.createContent();
-  this.hide();
-  this.textAnimator.searchProperties(this.dynamicProperties);
-};
-
-ITextElement.prototype.prepareFrame = function (num) {
-  this._mdf = false;
-  this.prepareRenderableFrame(num);
-  this.prepareProperties(num, this.isInRange);
-  if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
-    this.buildNewText();
-    this.textProperty._isFirstFrame = false;
-    this.textProperty._mdf = false;
-  }
-};
-
-ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
-  var j;
-  var jLen = shapes.length;
-  var pathNodes;
-  var shapeStr = '';
-  for (j = 0; j < jLen; j += 1) {
-    if (shapes[j].ty === 'sh') {
-      pathNodes = shapes[j].ks.k;
-      shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
-    }
-  }
-  return shapeStr;
-};
-
-ITextElement.prototype.updateDocumentData = function (newData, index) {
-  this.textProperty.updateDocumentData(newData, index);
-};
-
-ITextElement.prototype.canResizeFont = function (_canResize) {
-  this.textProperty.canResizeFont(_canResize);
-};
-
-ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
-  this.textProperty.setMinimumFontSize(_fontSize);
-};
-
-ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
-  if (documentData.ps) {
-    matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
-  }
-  matrixHelper.translate(0, -documentData.ls, 0);
-  switch (documentData.j) {
-    case 1:
-      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
-      break;
-    case 2:
-      matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
-      break;
-    default:
-      break;
-  }
-  matrixHelper.translate(xPos, yPos, 0);
-};
-
-ITextElement.prototype.buildColor = function (colorData) {
-  return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
-};
-
-ITextElement.prototype.emptyProp = new LetterProps();
-
-ITextElement.prototype.destroy = function () {
-
-};
-
-var emptyShapeData = {
-  shapes: [],
-};
-
-function SVGTextLottieElement(data, globalData, comp) {
-  this.textSpans = [];
-  this.renderType = 'svg';
-  this.initElement(data, globalData, comp);
-}
-
-extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
-
-SVGTextLottieElement.prototype.createContent = function () {
-  if (this.data.singleShape && !this.globalData.fontManager.chars) {
-    this.textContainer = createNS('text');
-  }
-};
-
-SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
-  var i = 0;
-  var len = textArray.length;
-  var textContents = [];
-  var currentTextContent = '';
-  while (i < len) {
-    if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
-      textContents.push(currentTextContent);
-      currentTextContent = '';
-    } else {
-      currentTextContent += textArray[i];
-    }
-    i += 1;
-  }
-  textContents.push(currentTextContent);
-  return textContents;
-};
-
-SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
-  // data should probably be cloned to apply scale separately to each instance of a text on different layers
-  // but since text internal content gets only rendered once and then it's never rerendered,
-  // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
-  // Avoiding cloning is preferred since cloning each character shape data is expensive
-  if (data.shapes && data.shapes.length) {
-    var shape = data.shapes[0];
-    if (shape.it) {
-      var shapeItem = shape.it[shape.it.length - 1];
-      if (shapeItem.s) {
-        shapeItem.s.k[0] = scale;
-        shapeItem.s.k[1] = scale;
-      }
-    }
-  }
-  return data;
-};
-
-SVGTextLottieElement.prototype.buildNewText = function () {
-  this.addDynamicProperty(this);
-  var i;
-  var len;
-
-  var documentData = this.textProperty.currentData;
-  this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
-  if (documentData.fc) {
-    this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
-  } else {
-    this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
-  }
-  if (documentData.sc) {
-    this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
-    this.layerElement.setAttribute('stroke-width', documentData.sw);
-  }
-  this.layerElement.setAttribute('font-size', documentData.finalSize);
-  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-  if (fontData.fClass) {
-    this.layerElement.setAttribute('class', fontData.fClass);
-  } else {
-    this.layerElement.setAttribute('font-family', fontData.fFamily);
-    var fWeight = documentData.fWeight;
-    var fStyle = documentData.fStyle;
-    this.layerElement.setAttribute('font-style', fStyle);
-    this.layerElement.setAttribute('font-weight', fWeight);
-  }
-  this.layerElement.setAttribute('aria-label', documentData.t);
-
-  var letters = documentData.l || [];
-  var usesGlyphs = !!this.globalData.fontManager.chars;
-  len = letters.length;
-
-  var tSpan;
-  var matrixHelper = this.mHelper;
-  var shapeStr = '';
-  var singleShape = this.data.singleShape;
-  var xPos = 0;
-  var yPos = 0;
-  var firstLine = true;
-  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-  if (singleShape && !usesGlyphs && !documentData.sz) {
-    var tElement = this.textContainer;
-    var justify = 'start';
-    switch (documentData.j) {
-      case 1:
-        justify = 'end';
-        break;
-      case 2:
-        justify = 'middle';
-        break;
-      default:
-        justify = 'start';
-        break;
-    }
-    tElement.setAttribute('text-anchor', justify);
-    tElement.setAttribute('letter-spacing', trackingOffset);
-    var textContent = this.buildTextContents(documentData.finalText);
-    len = textContent.length;
-    yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
-    for (i = 0; i < len; i += 1) {
-      tSpan = this.textSpans[i].span || createNS('tspan');
-      tSpan.textContent = textContent[i];
-      tSpan.setAttribute('x', 0);
-      tSpan.setAttribute('y', yPos);
-      tSpan.style.display = 'inherit';
-      tElement.appendChild(tSpan);
-      if (!this.textSpans[i]) {
-        this.textSpans[i] = {
-          span: null,
-          glyph: null,
-        };
-      }
-      this.textSpans[i].span = tSpan;
-      yPos += documentData.finalLineHeight;
-    }
-
-    this.layerElement.appendChild(tElement);
-  } else {
-    var cachedSpansLength = this.textSpans.length;
-    var charData;
-    for (i = 0; i < len; i += 1) {
-      if (!this.textSpans[i]) {
-        this.textSpans[i] = {
-          span: null,
-          childSpan: null,
-          glyph: null,
-        };
-      }
-      if (!usesGlyphs || !singleShape || i === 0) {
-        tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
-        if (cachedSpansLength <= i) {
-          tSpan.setAttribute('stroke-linecap', 'butt');
-          tSpan.setAttribute('stroke-linejoin', 'round');
-          tSpan.setAttribute('stroke-miterlimit', '4');
-          this.textSpans[i].span = tSpan;
-          if (usesGlyphs) {
-            var childSpan = createNS('g');
-            tSpan.appendChild(childSpan);
-            this.textSpans[i].childSpan = childSpan;
-          }
-          this.textSpans[i].span = tSpan;
-          this.layerElement.appendChild(tSpan);
-        }
-        tSpan.style.display = 'inherit';
-      }
-
-      matrixHelper.reset();
-      if (singleShape) {
-        if (letters[i].n) {
-          xPos = -trackingOffset;
-          yPos += documentData.yOffset;
-          yPos += firstLine ? 1 : 0;
-          firstLine = false;
-        }
-        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-        xPos += letters[i].l || 0;
-        // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
-        xPos += trackingOffset;
-      }
-      if (usesGlyphs) {
-        charData = this.globalData.fontManager.getCharData(
-          documentData.finalText[i],
-          fontData.fStyle,
-          this.globalData.fontManager.getFontByName(documentData.f).fFamily
-        );
-        var glyphElement;
-        // t === 1 means the character has been replaced with an animated shaped
-        if (charData.t === 1) {
-          glyphElement = new SVGCompElement(charData.data, this.globalData, this);
-        } else {
-          var data = emptyShapeData;
-          if (charData.data && charData.data.shapes) {
-            data = this.buildShapeData(charData.data, documentData.finalSize);
-          }
-          glyphElement = new SVGShapeElement(data, this.globalData, this);
-        }
-        if (this.textSpans[i].glyph) {
-          var glyph = this.textSpans[i].glyph;
-          this.textSpans[i].childSpan.removeChild(glyph.layerElement);
-          glyph.destroy();
-        }
-        this.textSpans[i].glyph = glyphElement;
-        glyphElement._debug = true;
-        glyphElement.prepareFrame(0);
-        glyphElement.renderFrame();
-        this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
-        // when using animated shapes, the layer will be scaled instead of replacing the internal scale
-        // this might have issues with strokes and might need a different solution
-        if (charData.t === 1) {
-          this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
-        }
-      } else {
-        if (singleShape) {
-          tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
-        }
-        tSpan.textContent = letters[i].val;
-        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-      }
-      //
-    }
-    if (singleShape && tSpan) {
-      tSpan.setAttribute('d', shapeStr);
-    }
-  }
-  while (i < this.textSpans.length) {
-    this.textSpans[i].span.style.display = 'none';
-    i += 1;
-  }
-
-  this._sizeChanged = true;
-};
-
-SVGTextLottieElement.prototype.sourceRectAtTime = function () {
-  this.prepareFrame(this.comp.renderedFrame - this.data.st);
-  this.renderInnerContent();
-  if (this._sizeChanged) {
-    this._sizeChanged = false;
-    var textBox = this.layerElement.getBBox();
-    this.bbox = {
-      top: textBox.y,
-      left: textBox.x,
-      width: textBox.width,
-      height: textBox.height,
-    };
-  }
-  return this.bbox;
-};
-
-SVGTextLottieElement.prototype.getValue = function () {
-  var i;
-  var len = this.textSpans.length;
-  var glyphElement;
-  this.renderedFrame = this.comp.renderedFrame;
-  for (i = 0; i < len; i += 1) {
-    glyphElement = this.textSpans[i].glyph;
-    if (glyphElement) {
-      glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
-      if (glyphElement._mdf) {
-        this._mdf = true;
-      }
-    }
-  }
-};
-
-SVGTextLottieElement.prototype.renderInnerContent = function () {
-  if (!this.data.singleShape || this._mdf) {
-    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-    if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
-      this._sizeChanged = true;
-      var i;
-      var len;
-      var renderedLetters = this.textAnimator.renderedLetters;
-
-      var letters = this.textProperty.currentData.l;
-
-      len = letters.length;
-      var renderedLetter;
-      var textSpan;
-      var glyphElement;
-      for (i = 0; i < len; i += 1) {
-        if (!letters[i].n) {
-          renderedLetter = renderedLetters[i];
-          textSpan = this.textSpans[i].span;
-          glyphElement = this.textSpans[i].glyph;
-          if (glyphElement) {
-            glyphElement.renderFrame();
-          }
-          if (renderedLetter._mdf.m) {
-            textSpan.setAttribute('transform', renderedLetter.m);
-          }
-          if (renderedLetter._mdf.o) {
-            textSpan.setAttribute('opacity', renderedLetter.o);
-          }
-          if (renderedLetter._mdf.sw) {
-            textSpan.setAttribute('stroke-width', renderedLetter.sw);
-          }
-          if (renderedLetter._mdf.sc) {
-            textSpan.setAttribute('stroke', renderedLetter.sc);
-          }
-          if (renderedLetter._mdf.fc) {
-            textSpan.setAttribute('fill', renderedLetter.fc);
-          }
-        }
-      }
-    }
-  }
-};
-
-function ISolidElement(data, globalData, comp) {
-  this.initElement(data, globalData, comp);
-}
-extendPrototype([IImageElement], ISolidElement);
-
-ISolidElement.prototype.createContent = function () {
-  var rect = createNS('rect');
-  /// /rect.style.width = this.data.sw;
-  /// /rect.style.height = this.data.sh;
-  /// /rect.style.fill = this.data.sc;
-  rect.setAttribute('width', this.data.sw);
-  rect.setAttribute('height', this.data.sh);
-  rect.setAttribute('fill', this.data.sc);
-  this.layerElement.appendChild(rect);
-};
-
-function NullElement(data, globalData, comp) {
-  this.initFrame();
-  this.initBaseData(data, globalData, comp);
-  this.initFrame();
-  this.initTransform(data, globalData, comp);
-  this.initHierarchy();
-}
-
-NullElement.prototype.prepareFrame = function (num) {
-  this.prepareProperties(num, true);
-};
-
-NullElement.prototype.renderFrame = function () {
-};
-
-NullElement.prototype.getBaseElement = function () {
-  return null;
-};
-
-NullElement.prototype.destroy = function () {
-};
-
-NullElement.prototype.sourceRectAtTime = function () {
-};
-
-NullElement.prototype.hide = function () {
-};
-
-extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
-
-function SVGRendererBase() {
-}
-
-extendPrototype([BaseRenderer], SVGRendererBase);
-
-SVGRendererBase.prototype.createNull = function (data) {
-  return new NullElement(data, this.globalData, this);
-};
-
-SVGRendererBase.prototype.createShape = function (data) {
-  return new SVGShapeElement(data, this.globalData, this);
-};
-
-SVGRendererBase.prototype.createText = function (data) {
-  return new SVGTextLottieElement(data, this.globalData, this);
-};
-
-SVGRendererBase.prototype.createImage = function (data) {
-  return new IImageElement(data, this.globalData, this);
-};
-
-SVGRendererBase.prototype.createSolid = function (data) {
-  return new ISolidElement(data, this.globalData, this);
-};
-
-SVGRendererBase.prototype.configAnimation = function (animData) {
-  this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
-  if (this.renderConfig.viewBoxSize) {
-    this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
-  } else {
-    this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
-  }
-
-  if (!this.renderConfig.viewBoxOnly) {
-    this.svgElement.setAttribute('width', animData.w);
-    this.svgElement.setAttribute('height', animData.h);
-    this.svgElement.style.width = '100%';
-    this.svgElement.style.height = '100%';
-    this.svgElement.style.transform = 'translate3d(0,0,0)';
-    this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
-  }
-  if (this.renderConfig.width) {
-    this.svgElement.setAttribute('width', this.renderConfig.width);
-  }
-  if (this.renderConfig.height) {
-    this.svgElement.setAttribute('height', this.renderConfig.height);
-  }
-  if (this.renderConfig.className) {
-    this.svgElement.setAttribute('class', this.renderConfig.className);
-  }
-  if (this.renderConfig.id) {
-    this.svgElement.setAttribute('id', this.renderConfig.id);
-  }
-  if (this.renderConfig.focusable !== undefined) {
-    this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
-  }
-  this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
-  // this.layerElement.style.transform = 'translate3d(0,0,0)';
-  // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
-  this.animationItem.wrapper.appendChild(this.svgElement);
-  // Mask animation
-  var defs = this.globalData.defs;
-
-  this.setupGlobalData(animData, defs);
-  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
-  this.data = animData;
-
-  var maskElement = createNS('clipPath');
-  var rect = createNS('rect');
-  rect.setAttribute('width', animData.w);
-  rect.setAttribute('height', animData.h);
-  rect.setAttribute('x', 0);
-  rect.setAttribute('y', 0);
-  var maskId = createElementID();
-  maskElement.setAttribute('id', maskId);
-  maskElement.appendChild(rect);
-  this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
-
-  defs.appendChild(maskElement);
-  this.layers = animData.layers;
-  this.elements = createSizedArray(animData.layers.length);
-};
-
-SVGRendererBase.prototype.destroy = function () {
-  if (this.animationItem.wrapper) {
-    this.animationItem.wrapper.innerText = '';
-  }
-  this.layerElement = null;
-  this.globalData.defs = null;
-  var i;
-  var len = this.layers ? this.layers.length : 0;
-  for (i = 0; i < len; i += 1) {
-    if (this.elements[i]) {
-      this.elements[i].destroy();
-    }
-  }
-  this.elements.length = 0;
-  this.destroyed = true;
-  this.animationItem = null;
-};
-
-SVGRendererBase.prototype.updateContainerSize = function () {
-};
-
-SVGRendererBase.prototype.buildItem = function (pos) {
-  var elements = this.elements;
-  if (elements[pos] || this.layers[pos].ty === 99) {
-    return;
-  }
-  elements[pos] = true;
-  var element = this.createItem(this.layers[pos]);
-
-  elements[pos] = element;
-  if (getExpressionsPlugin()) {
-    if (this.layers[pos].ty === 0) {
-      this.globalData.projectInterface.registerComposition(element);
-    }
-    element.initExpressions();
-  }
-  this.appendElementInPos(element, pos);
-  if (this.layers[pos].tt) {
-    if (!this.elements[pos - 1] || this.elements[pos - 1] === true) {
-      this.buildItem(pos - 1);
-      this.addPendingElement(element);
-    } else {
-      element.setMatte(elements[pos - 1].layerId);
-    }
-  }
-};
-
-SVGRendererBase.prototype.checkPendingElements = function () {
-  while (this.pendingElements.length) {
-    var element = this.pendingElements.pop();
-    element.checkParenting();
-    if (element.data.tt) {
-      var i = 0;
-      var len = this.elements.length;
-      while (i < len) {
-        if (this.elements[i] === element) {
-          element.setMatte(this.elements[i - 1].layerId);
-          break;
-        }
-        i += 1;
-      }
-    }
-  }
-};
-
-SVGRendererBase.prototype.renderFrame = function (num) {
-  if (this.renderedFrame === num || this.destroyed) {
-    return;
-  }
-  if (num === null) {
-    num = this.renderedFrame;
-  } else {
-    this.renderedFrame = num;
-  }
-  // console.log('-------');
-  // console.log('FRAME ',num);
-  this.globalData.frameNum = num;
-  this.globalData.frameId += 1;
-  this.globalData.projectInterface.currentFrame = num;
-  this.globalData._mdf = false;
-  var i;
-  var len = this.layers.length;
-  if (!this.completeLayers) {
-    this.checkLayers(num);
-  }
-  for (i = len - 1; i >= 0; i -= 1) {
-    if (this.completeLayers || this.elements[i]) {
-      this.elements[i].prepareFrame(num - this.layers[i].st);
-    }
-  }
-  if (this.globalData._mdf) {
-    for (i = 0; i < len; i += 1) {
-      if (this.completeLayers || this.elements[i]) {
-        this.elements[i].renderFrame();
-      }
-    }
-  }
-};
-
-SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
-  var newElement = element.getBaseElement();
-  if (!newElement) {
-    return;
-  }
-  var i = 0;
-  var nextElement;
-  while (i < pos) {
-    if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
-      nextElement = this.elements[i].getBaseElement();
-    }
-    i += 1;
-  }
-  if (nextElement) {
-    this.layerElement.insertBefore(newElement, nextElement);
-  } else {
-    this.layerElement.appendChild(newElement);
-  }
-};
-
-SVGRendererBase.prototype.hide = function () {
-  this.layerElement.style.display = 'none';
-};
-
-SVGRendererBase.prototype.show = function () {
-  this.layerElement.style.display = 'block';
-};
-
-function ICompElement() {}
-
-extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
-
-ICompElement.prototype.initElement = function (data, globalData, comp) {
-  this.initFrame();
-  this.initBaseData(data, globalData, comp);
-  this.initTransform(data, globalData, comp);
-  this.initRenderable();
-  this.initHierarchy();
-  this.initRendererElement();
-  this.createContainerElements();
-  this.createRenderableComponents();
-  if (this.data.xt || !globalData.progressiveLoad) {
-    this.buildAllItems();
-  }
-  this.hide();
-};
-
-/* ICompElement.prototype.hide = function(){
-    if(!this.hidden){
-        this.hideElement();
-        var i,len = this.elements.length;
-        for( i = 0; i < len; i+=1 ){
-            if(this.elements[i]){
-                this.elements[i].hide();
-            }
-        }
-    }
-}; */
-
-ICompElement.prototype.prepareFrame = function (num) {
-  this._mdf = false;
-  this.prepareRenderableFrame(num);
-  this.prepareProperties(num, this.isInRange);
-  if (!this.isInRange && !this.data.xt) {
-    return;
-  }
-
-  if (!this.tm._placeholder) {
-    var timeRemapped = this.tm.v;
-    if (timeRemapped === this.data.op) {
-      timeRemapped = this.data.op - 1;
-    }
-    this.renderedFrame = timeRemapped;
-  } else {
-    this.renderedFrame = num / this.data.sr;
-  }
-  var i;
-  var len = this.elements.length;
-  if (!this.completeLayers) {
-    this.checkLayers(this.renderedFrame);
-  }
-  // This iteration needs to be backwards because of how expressions connect between each other
-  for (i = len - 1; i >= 0; i -= 1) {
-    if (this.completeLayers || this.elements[i]) {
-      this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
-      if (this.elements[i]._mdf) {
-        this._mdf = true;
-      }
-    }
-  }
-};
-
-ICompElement.prototype.renderInnerContent = function () {
-  var i;
-  var len = this.layers.length;
-  for (i = 0; i < len; i += 1) {
-    if (this.completeLayers || this.elements[i]) {
-      this.elements[i].renderFrame();
-    }
-  }
-};
-
-ICompElement.prototype.setElements = function (elems) {
-  this.elements = elems;
-};
-
-ICompElement.prototype.getElements = function () {
-  return this.elements;
-};
-
-ICompElement.prototype.destroyElements = function () {
-  var i;
-  var len = this.layers.length;
-  for (i = 0; i < len; i += 1) {
-    if (this.elements[i]) {
-      this.elements[i].destroy();
-    }
-  }
-};
-
-ICompElement.prototype.destroy = function () {
-  this.destroyElements();
-  this.destroyBaseElement();
-};
-
-function SVGCompElement(data, globalData, comp) {
-  this.layers = data.layers;
-  this.supports3d = true;
-  this.completeLayers = false;
-  this.pendingElements = [];
-  this.elements = this.layers ? createSizedArray(this.layers.length) : [];
-  this.initElement(data, globalData, comp);
-  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
-}
-
-extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
-
-SVGCompElement.prototype.createComp = function (data) {
-  return new SVGCompElement(data, this.globalData, this);
-};
-
-function SVGRenderer(animationItem, config) {
-  this.animationItem = animationItem;
-  this.layers = null;
-  this.renderedFrame = -1;
-  this.svgElement = createNS('svg');
-  var ariaLabel = '';
-  if (config && config.title) {
-    var titleElement = createNS('title');
-    var titleId = createElementID();
-    titleElement.setAttribute('id', titleId);
-    titleElement.textContent = config.title;
-    this.svgElement.appendChild(titleElement);
-    ariaLabel += titleId;
-  }
-  if (config && config.description) {
-    var descElement = createNS('desc');
-    var descId = createElementID();
-    descElement.setAttribute('id', descId);
-    descElement.textContent = config.description;
-    this.svgElement.appendChild(descElement);
-    ariaLabel += ' ' + descId;
-  }
-  if (ariaLabel) {
-    this.svgElement.setAttribute('aria-labelledby', ariaLabel);
-  }
-  var defs = createNS('defs');
-  this.svgElement.appendChild(defs);
-  var maskElement = createNS('g');
-  this.svgElement.appendChild(maskElement);
-  this.layerElement = maskElement;
-  this.renderConfig = {
-    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
-    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
-    contentVisibility: (config && config.contentVisibility) || 'visible',
-    progressiveLoad: (config && config.progressiveLoad) || false,
-    hideOnTransparent: !((config && config.hideOnTransparent === false)),
-    viewBoxOnly: (config && config.viewBoxOnly) || false,
-    viewBoxSize: (config && config.viewBoxSize) || false,
-    className: (config && config.className) || '',
-    id: (config && config.id) || '',
-    focusable: config && config.focusable,
-    filterSize: {
-      width: (config && config.filterSize && config.filterSize.width) || '100%',
-      height: (config && config.filterSize && config.filterSize.height) || '100%',
-      x: (config && config.filterSize && config.filterSize.x) || '0%',
-      y: (config && config.filterSize && config.filterSize.y) || '0%',
-    },
-    width: (config && config.width),
-    height: (config && config.height),
-  };
-
-  this.globalData = {
-    _mdf: false,
-    frameNum: -1,
-    defs: defs,
-    renderConfig: this.renderConfig,
-  };
-  this.elements = [];
-  this.pendingElements = [];
-  this.destroyed = false;
-  this.rendererType = 'svg';
-}
-
-extendPrototype([SVGRendererBase], SVGRenderer);
-
-SVGRenderer.prototype.createComp = function (data) {
-  return new SVGCompElement(data, this.globalData, this);
-};
-
-function CVContextData() {
-  this.saved = [];
-  this.cArrPos = 0;
-  this.cTr = new Matrix();
-  this.cO = 1;
-  var i;
-  var len = 15;
-  this.savedOp = createTypedArray('float32', len);
-  for (i = 0; i < len; i += 1) {
-    this.saved[i] = createTypedArray('float32', 16);
-  }
-  this._length = len;
-}
-
-CVContextData.prototype.duplicate = function () {
-  var newLength = this._length * 2;
-  var currentSavedOp = this.savedOp;
-  this.savedOp = createTypedArray('float32', newLength);
-  this.savedOp.set(currentSavedOp);
-  var i = 0;
-  for (i = this._length; i < newLength; i += 1) {
-    this.saved[i] = createTypedArray('float32', 16);
-  }
-  this._length = newLength;
-};
-
-CVContextData.prototype.reset = function () {
-  this.cArrPos = 0;
-  this.cTr.reset();
-  this.cO = 1;
-};
-
-function ShapeTransformManager() {
-  this.sequences = {};
-  this.sequenceList = [];
-  this.transform_key_count = 0;
-}
-
-ShapeTransformManager.prototype = {
-  addTransformSequence: function (transforms) {
-    var i;
-    var len = transforms.length;
-    var key = '_';
-    for (i = 0; i < len; i += 1) {
-      key += transforms[i].transform.key + '_';
-    }
-    var sequence = this.sequences[key];
-    if (!sequence) {
-      sequence = {
-        transforms: [].concat(transforms),
-        finalTransform: new Matrix(),
-        _mdf: false,
-      };
-      this.sequences[key] = sequence;
-      this.sequenceList.push(sequence);
-    }
-    return sequence;
-  },
-  processSequence: function (sequence, isFirstFrame) {
-    var i = 0;
-    var len = sequence.transforms.length;
-    var _mdf = isFirstFrame;
-    while (i < len && !isFirstFrame) {
-      if (sequence.transforms[i].transform.mProps._mdf) {
-        _mdf = true;
-        break;
-      }
-      i += 1;
-    }
-    if (_mdf) {
-      var props;
-      sequence.finalTransform.reset();
-      for (i = len - 1; i >= 0; i -= 1) {
-        props = sequence.transforms[i].transform.mProps.v.props;
-        sequence.finalTransform.transform(props[0], props[1], props[2], props[3], props[4], props[5], props[6], props[7], props[8], props[9], props[10], props[11], props[12], props[13], props[14], props[15]);
-      }
-    }
-    sequence._mdf = _mdf;
-  },
-  processSequences: function (isFirstFrame) {
-    var i;
-    var len = this.sequenceList.length;
-    for (i = 0; i < len; i += 1) {
-      this.processSequence(this.sequenceList[i], isFirstFrame);
-    }
-  },
-  getNewKey: function () {
-    this.transform_key_count += 1;
-    return '_' + this.transform_key_count;
-  },
-};
-
-function CVEffects() {
-
-}
-CVEffects.prototype.renderFrame = function () {};
-
-function CVMaskElement(data, element) {
-  this.data = data;
-  this.element = element;
-  this.masksProperties = this.data.masksProperties || [];
-  this.viewData = createSizedArray(this.masksProperties.length);
-  var i;
-  var len = this.masksProperties.length;
-  var hasMasks = false;
-  for (i = 0; i < len; i += 1) {
-    if (this.masksProperties[i].mode !== 'n') {
-      hasMasks = true;
-    }
-    this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
-  }
-  this.hasMasks = hasMasks;
-  if (hasMasks) {
-    this.element.addRenderableComponent(this);
-  }
-}
-
-CVMaskElement.prototype.renderFrame = function () {
-  if (!this.hasMasks) {
-    return;
-  }
-  var transform = this.element.finalTransform.mat;
-  var ctx = this.element.canvasContext;
-  var i;
-  var len = this.masksProperties.length;
-  var pt;
-  var pts;
-  var data;
-  ctx.beginPath();
-  for (i = 0; i < len; i += 1) {
-    if (this.masksProperties[i].mode !== 'n') {
-      if (this.masksProperties[i].inv) {
-        ctx.moveTo(0, 0);
-        ctx.lineTo(this.element.globalData.compSize.w, 0);
-        ctx.lineTo(this.element.globalData.compSize.w, this.element.globalData.compSize.h);
-        ctx.lineTo(0, this.element.globalData.compSize.h);
-        ctx.lineTo(0, 0);
-      }
-      data = this.viewData[i].v;
-      pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
-      ctx.moveTo(pt[0], pt[1]);
-      var j;
-      var jLen = data._length;
-      for (j = 1; j < jLen; j += 1) {
-        pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
-        ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
-      }
-      pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
-      ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
-    }
-  }
-  this.element.globalData.renderer.save(true);
-  ctx.clip();
-};
-
-CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
-
-CVMaskElement.prototype.destroy = function () {
-  this.element = null;
-};
-
-function CVBaseElement() {
-}
-
-CVBaseElement.prototype = {
-  createElements: function () {},
-  initRendererElement: function () {},
-  createContainerElements: function () {
-    this.canvasContext = this.globalData.canvasContext;
-    this.renderableEffectsManager = new CVEffects(this);
-  },
-  createContent: function () {},
-  setBlendMode: function () {
-    var globalData = this.globalData;
-    if (globalData.blendMode !== this.data.bm) {
-      globalData.blendMode = this.data.bm;
-      var blendModeValue = getBlendMode(this.data.bm);
-      globalData.canvasContext.globalCompositeOperation = blendModeValue;
-    }
-  },
-  createRenderableComponents: function () {
-    this.maskManager = new CVMaskElement(this.data, this);
-  },
-  hideElement: function () {
-    if (!this.hidden && (!this.isInRange || this.isTransparent)) {
-      this.hidden = true;
-    }
-  },
-  showElement: function () {
-    if (this.isInRange && !this.isTransparent) {
-      this.hidden = false;
-      this._isFirstFrame = true;
-      this.maskManager._isFirstFrame = true;
-    }
-  },
-  renderFrame: function () {
-    if (this.hidden || this.data.hd) {
-      return;
-    }
-    this.renderTransform();
-    this.renderRenderable();
-    this.setBlendMode();
-    var forceRealStack = this.data.ty === 0;
-    this.globalData.renderer.save(forceRealStack);
-    this.globalData.renderer.ctxTransform(this.finalTransform.mat.props);
-    this.globalData.renderer.ctxOpacity(this.finalTransform.mProp.o.v);
-    this.renderInnerContent();
-    this.globalData.renderer.restore(forceRealStack);
-    if (this.maskManager.hasMasks) {
-      this.globalData.renderer.restore(true);
-    }
-    if (this._isFirstFrame) {
-      this._isFirstFrame = false;
-    }
-  },
-  destroy: function () {
-    this.canvasContext = null;
-    this.data = null;
-    this.globalData = null;
-    this.maskManager.destroy();
-  },
-  mHelper: new Matrix(),
-};
-CVBaseElement.prototype.hide = CVBaseElement.prototype.hideElement;
-CVBaseElement.prototype.show = CVBaseElement.prototype.showElement;
-
-function CVShapeData(element, data, styles, transformsManager) {
-  this.styledShapes = [];
-  this.tr = [0, 0, 0, 0, 0, 0];
-  var ty = 4;
-  if (data.ty === 'rc') {
-    ty = 5;
-  } else if (data.ty === 'el') {
-    ty = 6;
-  } else if (data.ty === 'sr') {
-    ty = 7;
-  }
-  this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
-  var i;
-  var len = styles.length;
-  var styledShape;
-  for (i = 0; i < len; i += 1) {
-    if (!styles[i].closed) {
-      styledShape = {
-        transforms: transformsManager.addTransformSequence(styles[i].transforms),
-        trNodes: [],
-      };
-      this.styledShapes.push(styledShape);
-      styles[i].elements.push(styledShape);
-    }
-  }
-}
-
-CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
-
-function CVShapeElement(data, globalData, comp) {
-  this.shapes = [];
-  this.shapesData = data.shapes;
-  this.stylesList = [];
-  this.itemsData = [];
-  this.prevViewData = [];
-  this.shapeModifiers = [];
-  this.processedElements = [];
-  this.transformsManager = new ShapeTransformManager();
-  this.initElement(data, globalData, comp);
-}
-
-extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
-
-CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
-
-CVShapeElement.prototype.transformHelper = { opacity: 1, _opMdf: false };
-
-CVShapeElement.prototype.dashResetter = [];
-
-CVShapeElement.prototype.createContent = function () {
-  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
-};
-
-CVShapeElement.prototype.createStyleElement = function (data, transforms) {
-  var styleElem = {
-    data: data,
-    type: data.ty,
-    preTransforms: this.transformsManager.addTransformSequence(transforms),
-    transforms: [],
-    elements: [],
-    closed: data.hd === true,
-  };
-  var elementData = {};
-  if (data.ty === 'fl' || data.ty === 'st') {
-    elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
-    if (!elementData.c.k) {
-      styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
-    }
-  } else if (data.ty === 'gf' || data.ty === 'gs') {
-    elementData.s = PropertyFactory.getProp(this, data.s, 1, null, this);
-    elementData.e = PropertyFactory.getProp(this, data.e, 1, null, this);
-    elementData.h = PropertyFactory.getProp(this, data.h || { k: 0 }, 0, 0.01, this);
-    elementData.a = PropertyFactory.getProp(this, data.a || { k: 0 }, 0, degToRads, this);
-    elementData.g = new GradientProperty(this, data.g, this);
-  }
-  elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
-  if (data.ty === 'st' || data.ty === 'gs') {
-    styleElem.lc = lineCapEnum[data.lc || 2];
-    styleElem.lj = lineJoinEnum[data.lj || 2];
-    if (data.lj == 1) { // eslint-disable-line eqeqeq
-      styleElem.ml = data.ml;
-    }
-    elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
-    if (!elementData.w.k) {
-      styleElem.wi = elementData.w.v;
-    }
-    if (data.d) {
-      var d = new DashProperty(this, data.d, 'canvas', this);
-      elementData.d = d;
-      if (!elementData.d.k) {
-        styleElem.da = elementData.d.dashArray;
-        styleElem.do = elementData.d.dashoffset[0];
-      }
-    }
-  } else {
-    styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
-  }
-  this.stylesList.push(styleElem);
-  elementData.style = styleElem;
-  return elementData;
-};
-
-CVShapeElement.prototype.createGroupElement = function () {
-  var elementData = {
-    it: [],
-    prevViewData: [],
-  };
-  return elementData;
-};
-
-CVShapeElement.prototype.createTransformElement = function (data) {
-  var elementData = {
-    transform: {
-      opacity: 1,
-      _opMdf: false,
-      key: this.transformsManager.getNewKey(),
-      op: PropertyFactory.getProp(this, data.o, 0, 0.01, this),
-      mProps: TransformPropertyFactory.getTransformProperty(this, data, this),
-    },
-  };
-  return elementData;
-};
-
-CVShapeElement.prototype.createShapeElement = function (data) {
-  var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
-
-  this.shapes.push(elementData);
-  this.addShapeToModifiers(elementData);
-  return elementData;
-};
-
-CVShapeElement.prototype.reloadShapes = function () {
-  this._isFirstFrame = true;
-  var i;
-  var len = this.itemsData.length;
-  for (i = 0; i < len; i += 1) {
-    this.prevViewData[i] = this.itemsData[i];
-  }
-  this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
-  len = this.dynamicProperties.length;
-  for (i = 0; i < len; i += 1) {
-    this.dynamicProperties[i].getValue();
-  }
-  this.renderModifiers();
-  this.transformsManager.processSequences(this._isFirstFrame);
-};
-
-CVShapeElement.prototype.addTransformToStyleList = function (transform) {
-  var i;
-  var len = this.stylesList.length;
-  for (i = 0; i < len; i += 1) {
-    if (!this.stylesList[i].closed) {
-      this.stylesList[i].transforms.push(transform);
-    }
-  }
-};
-
-CVShapeElement.prototype.removeTransformFromStyleList = function () {
-  var i;
-  var len = this.stylesList.length;
-  for (i = 0; i < len; i += 1) {
-    if (!this.stylesList[i].closed) {
-      this.stylesList[i].transforms.pop();
-    }
-  }
-};
-
-CVShapeElement.prototype.closeStyles = function (styles) {
-  var i;
-  var len = styles.length;
-  for (i = 0; i < len; i += 1) {
-    styles[i].closed = true;
-  }
-};
-
-CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
-  var i;
-  var len = arr.length - 1;
-  var j;
-  var jLen;
-  var ownStyles = [];
-  var ownModifiers = [];
-  var processedPos;
-  var modifier;
-  var currentTransform;
-  var ownTransforms = [].concat(transforms);
-  for (i = len; i >= 0; i -= 1) {
-    processedPos = this.searchProcessedElement(arr[i]);
-    if (!processedPos) {
-      arr[i]._shouldRender = shouldRender;
-    } else {
-      itemsData[i] = prevViewData[processedPos - 1];
-    }
-    if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
-      if (!processedPos) {
-        itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
-      } else {
-        itemsData[i].style.closed = false;
-      }
-
-      ownStyles.push(itemsData[i].style);
-    } else if (arr[i].ty === 'gr') {
-      if (!processedPos) {
-        itemsData[i] = this.createGroupElement(arr[i]);
-      } else {
-        jLen = itemsData[i].it.length;
-        for (j = 0; j < jLen; j += 1) {
-          itemsData[i].prevViewData[j] = itemsData[i].it[j];
-        }
-      }
-      this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
-    } else if (arr[i].ty === 'tr') {
-      if (!processedPos) {
-        currentTransform = this.createTransformElement(arr[i]);
-        itemsData[i] = currentTransform;
-      }
-      ownTransforms.push(itemsData[i]);
-      this.addTransformToStyleList(itemsData[i]);
-    } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
-      if (!processedPos) {
-        itemsData[i] = this.createShapeElement(arr[i]);
-      }
-    } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'pb') {
-      if (!processedPos) {
-        modifier = ShapeModifiers.getModifier(arr[i].ty);
-        modifier.init(this, arr[i]);
-        itemsData[i] = modifier;
-        this.shapeModifiers.push(modifier);
-      } else {
-        modifier = itemsData[i];
-        modifier.closed = false;
-      }
-      ownModifiers.push(modifier);
-    } else if (arr[i].ty === 'rp') {
-      if (!processedPos) {
-        modifier = ShapeModifiers.getModifier(arr[i].ty);
-        itemsData[i] = modifier;
-        modifier.init(this, arr, i, itemsData);
-        this.shapeModifiers.push(modifier);
-        shouldRender = false;
-      } else {
-        modifier = itemsData[i];
-        modifier.closed = true;
-      }
-      ownModifiers.push(modifier);
-    }
-    this.addProcessedElement(arr[i], i + 1);
-  }
-  this.removeTransformFromStyleList();
-  this.closeStyles(ownStyles);
-  len = ownModifiers.length;
-  for (i = 0; i < len; i += 1) {
-    ownModifiers[i].closed = true;
-  }
-};
-
-CVShapeElement.prototype.renderInnerContent = function () {
-  this.transformHelper.opacity = 1;
-  this.transformHelper._opMdf = false;
-  this.renderModifiers();
-  this.transformsManager.processSequences(this._isFirstFrame);
-  this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
-};
-
-CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
-  if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
-    groupTransform.opacity = parentTransform.opacity;
-    groupTransform.opacity *= groupTransform.op.v;
-    groupTransform._opMdf = true;
-  }
-};
-
-CVShapeElement.prototype.drawLayer = function () {
-  var i;
-  var len = this.stylesList.length;
-  var j;
-  var jLen;
-  var k;
-  var kLen;
-  var elems;
-  var nodes;
-  var renderer = this.globalData.renderer;
-  var ctx = this.globalData.canvasContext;
-  var type;
-  var currentStyle;
-  for (i = 0; i < len; i += 1) {
-    currentStyle = this.stylesList[i];
-    type = currentStyle.type;
-
-    // Skipping style when
-    // Stroke width equals 0
-    // style should not be rendered (extra unused repeaters)
-    // current opacity equals 0
-    // global opacity equals 0
-    if (!(((type === 'st' || type === 'gs') && currentStyle.wi === 0) || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
-      renderer.save();
-      elems = currentStyle.elements;
-      if (type === 'st' || type === 'gs') {
-        ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
-        ctx.lineWidth = currentStyle.wi;
-        ctx.lineCap = currentStyle.lc;
-        ctx.lineJoin = currentStyle.lj;
-        ctx.miterLimit = currentStyle.ml || 0;
-      } else {
-        ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
-      }
-      renderer.ctxOpacity(currentStyle.coOp);
-      if (type !== 'st' && type !== 'gs') {
-        ctx.beginPath();
-      }
-      renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
-      jLen = elems.length;
-      for (j = 0; j < jLen; j += 1) {
-        if (type === 'st' || type === 'gs') {
-          ctx.beginPath();
-          if (currentStyle.da) {
-            ctx.setLineDash(currentStyle.da);
-            ctx.lineDashOffset = currentStyle.do;
-          }
-        }
-        nodes = elems[j].trNodes;
-        kLen = nodes.length;
-
-        for (k = 0; k < kLen; k += 1) {
-          if (nodes[k].t === 'm') {
-            ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
-          } else if (nodes[k].t === 'c') {
-            ctx.bezierCurveTo(nodes[k].pts[0], nodes[k].pts[1], nodes[k].pts[2], nodes[k].pts[3], nodes[k].pts[4], nodes[k].pts[5]);
-          } else {
-            ctx.closePath();
-          }
-        }
-        if (type === 'st' || type === 'gs') {
-          ctx.stroke();
-          if (currentStyle.da) {
-            ctx.setLineDash(this.dashResetter);
-          }
-        }
-      }
-      if (type !== 'st' && type !== 'gs') {
-        ctx.fill(currentStyle.r);
-      }
-      renderer.restore();
-    }
-  }
-};
-
-CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
-  var i;
-  var len = items.length - 1;
-  var groupTransform;
-  groupTransform = parentTransform;
-  for (i = len; i >= 0; i -= 1) {
-    if (items[i].ty === 'tr') {
-      groupTransform = data[i].transform;
-      this.renderShapeTransform(parentTransform, groupTransform);
-    } else if (items[i].ty === 'sh' || items[i].ty === 'el' || items[i].ty === 'rc' || items[i].ty === 'sr') {
-      this.renderPath(items[i], data[i]);
-    } else if (items[i].ty === 'fl') {
-      this.renderFill(items[i], data[i], groupTransform);
-    } else if (items[i].ty === 'st') {
-      this.renderStroke(items[i], data[i], groupTransform);
-    } else if (items[i].ty === 'gf' || items[i].ty === 'gs') {
-      this.renderGradientFill(items[i], data[i], groupTransform);
-    } else if (items[i].ty === 'gr') {
-      this.renderShape(groupTransform, items[i].it, data[i].it);
-    } else if (items[i].ty === 'tm') {
-      //
-    }
-  }
-  if (isMain) {
-    this.drawLayer();
-  }
-};
-
-CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
-  if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
-    var shapeNodes = styledShape.trNodes;
-    var paths = shape.paths;
-    var i;
-    var len;
-    var j;
-    var jLen = paths._length;
-    shapeNodes.length = 0;
-    var groupTransformMat = styledShape.transforms.finalTransform;
-    for (j = 0; j < jLen; j += 1) {
-      var pathNodes = paths.shapes[j];
-      if (pathNodes && pathNodes.v) {
-        len = pathNodes._length;
-        for (i = 1; i < len; i += 1) {
-          if (i === 1) {
-            shapeNodes.push({
-              t: 'm',
-              p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
-            });
-          }
-          shapeNodes.push({
-            t: 'c',
-            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i]),
-          });
-        }
-        if (len === 1) {
-          shapeNodes.push({
-            t: 'm',
-            p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0),
-          });
-        }
-        if (pathNodes.c && len) {
-          shapeNodes.push({
-            t: 'c',
-            pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0]),
-          });
-          shapeNodes.push({
-            t: 'z',
-          });
-        }
-      }
-    }
-    styledShape.trNodes = shapeNodes;
-  }
-};
-
-CVShapeElement.prototype.renderPath = function (pathData, itemData) {
-  if (pathData.hd !== true && pathData._shouldRender) {
-    var i;
-    var len = itemData.styledShapes.length;
-    for (i = 0; i < len; i += 1) {
-      this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
-    }
-  }
-};
-
-CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
-  var styleElem = itemData.style;
-
-  if (itemData.c._mdf || this._isFirstFrame) {
-    styleElem.co = 'rgb('
-        + bmFloor(itemData.c.v[0]) + ','
-        + bmFloor(itemData.c.v[1]) + ','
-        + bmFloor(itemData.c.v[2]) + ')';
-  }
-  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
-    styleElem.coOp = itemData.o.v * groupTransform.opacity;
-  }
-};
-
-CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
-  var styleElem = itemData.style;
-  var grd;
-  if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || (styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf))) {
-    var ctx = this.globalData.canvasContext;
-    var pt1 = itemData.s.v;
-    var pt2 = itemData.e.v;
-    if (styleData.t === 1) {
-      grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
-    } else {
-      var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
-      var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
-
-      var percent = itemData.h.v;
-      if (percent >= 1) {
-        percent = 0.99;
-      } else if (percent <= -1) {
-        percent = -0.99;
-      }
-      var dist = rad * percent;
-      var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
-      var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
-      grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
-    }
-
-    var i;
-    var len = styleData.g.p;
-    var cValues = itemData.g.c;
-    var opacity = 1;
-
-    for (i = 0; i < len; i += 1) {
-      if (itemData.g._hasOpacity && itemData.g._collapsable) {
-        opacity = itemData.g.o[i * 2 + 1];
-      }
-      grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
-    }
-    styleElem.grd = grd;
-  }
-  styleElem.coOp = itemData.o.v * groupTransform.opacity;
-};
-
-CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
-  var styleElem = itemData.style;
-  var d = itemData.d;
-  if (d && (d._mdf || this._isFirstFrame)) {
-    styleElem.da = d.dashArray;
-    styleElem.do = d.dashoffset[0];
-  }
-  if (itemData.c._mdf || this._isFirstFrame) {
-    styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
-  }
-  if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
-    styleElem.coOp = itemData.o.v * groupTransform.opacity;
-  }
-  if (itemData.w._mdf || this._isFirstFrame) {
-    styleElem.wi = itemData.w.v;
-  }
-};
-
-CVShapeElement.prototype.destroy = function () {
-  this.shapesData = null;
-  this.globalData = null;
-  this.canvasContext = null;
-  this.stylesList.length = 0;
-  this.itemsData.length = 0;
-};
-
-function CVTextElement(data, globalData, comp) {
-  this.textSpans = [];
-  this.yOffset = 0;
-  this.fillColorAnim = false;
-  this.strokeColorAnim = false;
-  this.strokeWidthAnim = false;
-  this.stroke = false;
-  this.fill = false;
-  this.justifyOffset = 0;
-  this.currentRender = null;
-  this.renderType = 'canvas';
-  this.values = {
-    fill: 'rgba(0,0,0,0)',
-    stroke: 'rgba(0,0,0,0)',
-    sWidth: 0,
-    fValue: '',
-  };
-  this.initElement(data, globalData, comp);
-}
-extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
-
-CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
-
-CVTextElement.prototype.buildNewText = function () {
-  var documentData = this.textProperty.currentData;
-  this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
-
-  var hasFill = false;
-  if (documentData.fc) {
-    hasFill = true;
-    this.values.fill = this.buildColor(documentData.fc);
-  } else {
-    this.values.fill = 'rgba(0,0,0,0)';
-  }
-  this.fill = hasFill;
-  var hasStroke = false;
-  if (documentData.sc) {
-    hasStroke = true;
-    this.values.stroke = this.buildColor(documentData.sc);
-    this.values.sWidth = documentData.sw;
-  }
-  var fontData = this.globalData.fontManager.getFontByName(documentData.f);
-  var i;
-  var len;
-  var letters = documentData.l;
-  var matrixHelper = this.mHelper;
-  this.stroke = hasStroke;
-  this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
-  len = documentData.finalText.length;
-  // this.tHelper.font = this.values.fValue;
-  var charData;
-  var shapeData;
-  var k;
-  var kLen;
-  var shapes;
-  var j;
-  var jLen;
-  var pathNodes;
-  var commands;
-  var pathArr;
-  var singleShape = this.data.singleShape;
-  var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
-  var xPos = 0;
-  var yPos = 0;
-  var firstLine = true;
-  var cnt = 0;
-  for (i = 0; i < len; i += 1) {
-    charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
-    shapeData = (charData && charData.data) || {};
-    matrixHelper.reset();
-    if (singleShape && letters[i].n) {
-      xPos = -trackingOffset;
-      yPos += documentData.yOffset;
-      yPos += firstLine ? 1 : 0;
-      firstLine = false;
-    }
-    shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
-    jLen = shapes.length;
-    matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
-    if (singleShape) {
-      this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
-    }
-    commands = createSizedArray(jLen - 1);
-    var commandsCounter = 0;
-    for (j = 0; j < jLen; j += 1) {
-      if (shapes[j].ty === 'sh') {
-        kLen = shapes[j].ks.k.i.length;
-        pathNodes = shapes[j].ks.k;
-        pathArr = [];
-        for (k = 1; k < kLen; k += 1) {
-          if (k === 1) {
-            pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
-          }
-          pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
-        }
-        pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
-        commands[commandsCounter] = pathArr;
-        commandsCounter += 1;
-      }
-    }
-    if (singleShape) {
-      xPos += letters[i].l;
-      xPos += trackingOffset;
-    }
-    if (this.textSpans[cnt]) {
-      this.textSpans[cnt].elem = commands;
-    } else {
-      this.textSpans[cnt] = { elem: commands };
-    }
-    cnt += 1;
-  }
-};
-
-CVTextElement.prototype.renderInnerContent = function () {
-  var ctx = this.canvasContext;
-  ctx.font = this.values.fValue;
-  ctx.lineCap = 'butt';
-  ctx.lineJoin = 'miter';
-  ctx.miterLimit = 4;
-
-  if (!this.data.singleShape) {
-    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
-  }
-
-  var i;
-  var len;
-  var j;
-  var jLen;
-  var k;
-  var kLen;
-  var renderedLetters = this.textAnimator.renderedLetters;
-
-  var letters = this.textProperty.currentData.l;
-
-  len = letters.length;
-  var renderedLetter;
-  var lastFill = null;
-  var lastStroke = null;
-  var lastStrokeW = null;
-  var commands;
-  var pathArr;
-  for (i = 0; i < len; i += 1) {
-    if (!letters[i].n) {
-      renderedLetter = renderedLetters[i];
-      if (renderedLetter) {
-        this.globalData.renderer.save();
-        this.globalData.renderer.ctxTransform(renderedLetter.p);
-        this.globalData.renderer.ctxOpacity(renderedLetter.o);
-      }
-      if (this.fill) {
-        if (renderedLetter && renderedLetter.fc) {
-          if (lastFill !== renderedLetter.fc) {
-            lastFill = renderedLetter.fc;
-            ctx.fillStyle = renderedLetter.fc;
-          }
-        } else if (lastFill !== this.values.fill) {
-          lastFill = this.values.fill;
-          ctx.fillStyle = this.values.fill;
-        }
-        commands = this.textSpans[i].elem;
-        jLen = commands.length;
-        this.globalData.canvasContext.beginPath();
-        for (j = 0; j < jLen; j += 1) {
-          pathArr = commands[j];
-          kLen = pathArr.length;
-          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-          for (k = 2; k < kLen; k += 6) {
-            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
-          }
-        }
-        this.globalData.canvasContext.closePath();
-        this.globalData.canvasContext.fill();
-        /// ctx.fillText(this.textSpans[i].val,0,0);
-      }
-      if (this.stroke) {
-        if (renderedLetter && renderedLetter.sw) {
-          if (lastStrokeW !== renderedLetter.sw) {
-            lastStrokeW = renderedLetter.sw;
-            ctx.lineWidth = renderedLetter.sw;
-          }
-        } else if (lastStrokeW !== this.values.sWidth) {
-          lastStrokeW = this.values.sWidth;
-          ctx.lineWidth = this.values.sWidth;
-        }
-        if (renderedLetter && renderedLetter.sc) {
-          if (lastStroke !== renderedLetter.sc) {
-            lastStroke = renderedLetter.sc;
-            ctx.strokeStyle = renderedLetter.sc;
-          }
-        } else if (lastStroke !== this.values.stroke) {
-          lastStroke = this.values.stroke;
-          ctx.strokeStyle = this.values.stroke;
-        }
-        commands = this.textSpans[i].elem;
-        jLen = commands.length;
-        this.globalData.canvasContext.beginPath();
-        for (j = 0; j < jLen; j += 1) {
-          pathArr = commands[j];
-          kLen = pathArr.length;
-          this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
-          for (k = 2; k < kLen; k += 6) {
-            this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
-          }
-        }
-        this.globalData.canvasContext.closePath();
-        this.globalData.canvasContext.stroke();
-        /// ctx.strokeText(letters[i].val,0,0);
-      }
-      if (renderedLetter) {
-        this.globalData.renderer.restore();
-      }
-    }
-  }
-};
-
-function CVImageElement(data, globalData, comp) {
-  this.assetData = globalData.getAssetData(data.refId);
-  this.img = globalData.imageLoader.getAsset(this.assetData);
-  this.initElement(data, globalData, comp);
-}
-extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
-
-CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
-CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
-CVImageElement.prototype.createContent = function () {
-  if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
-    var canvas = createTag('canvas');
-    canvas.width = this.assetData.w;
-    canvas.height = this.assetData.h;
-    var ctx = canvas.getContext('2d');
-
-    var imgW = this.img.width;
-    var imgH = this.img.height;
-    var imgRel = imgW / imgH;
-    var canvasRel = this.assetData.w / this.assetData.h;
-    var widthCrop;
-    var heightCrop;
-    var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
-    if ((imgRel > canvasRel && par === 'xMidYMid slice') || (imgRel < canvasRel && par !== 'xMidYMid slice')) {
-      heightCrop = imgH;
-      widthCrop = heightCrop * canvasRel;
-    } else {
-      widthCrop = imgW;
-      heightCrop = widthCrop / canvasRel;
-    }
-    ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
-    this.img = canvas;
-  }
-};
-
-CVImageElement.prototype.renderInnerContent = function () {
-  this.canvasContext.drawImage(this.img, 0, 0);
-};
-
-CVImageElement.prototype.destroy = function () {
-  this.img = null;
-};
-
-function CVSolidElement(data, globalData, comp) {
-  this.initElement(data, globalData, comp);
-}
-extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
-
-CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
-CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
-
-CVSolidElement.prototype.renderInnerContent = function () {
-  var ctx = this.canvasContext;
-  ctx.fillStyle = this.data.sc;
-  ctx.fillRect(0, 0, this.data.sw, this.data.sh);
-  //
-};
-
-function CanvasRendererBase(animationItem, config) {
-  this.animationItem = animationItem;
-  this.renderConfig = {
-    clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true,
-    context: (config && config.context) || null,
-    progressiveLoad: (config && config.progressiveLoad) || false,
-    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
-    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
-    contentVisibility: (config && config.contentVisibility) || 'visible',
-    className: (config && config.className) || '',
-    id: (config && config.id) || '',
-  };
-  this.renderConfig.dpr = (config && config.dpr) || 1;
-  if (this.animationItem.wrapper) {
-    this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1;
-  }
-  this.renderedFrame = -1;
-  this.globalData = {
-    frameNum: -1,
-    _mdf: false,
-    renderConfig: this.renderConfig,
-    currentGlobalAlpha: -1,
-  };
-  this.contextData = new CVContextData();
-  this.elements = [];
-  this.pendingElements = [];
-  this.transformMat = new Matrix();
-  this.completeLayers = false;
-  this.rendererType = 'canvas';
-}
-extendPrototype([BaseRenderer], CanvasRendererBase);
-
-CanvasRendererBase.prototype.createShape = function (data) {
-  return new CVShapeElement(data, this.globalData, this);
-};
-
-CanvasRendererBase.prototype.createText = function (data) {
-  return new CVTextElement(data, this.globalData, this);
-};
-
-CanvasRendererBase.prototype.createImage = function (data) {
-  return new CVImageElement(data, this.globalData, this);
-};
-
-CanvasRendererBase.prototype.createSolid = function (data) {
-  return new CVSolidElement(data, this.globalData, this);
-};
-
-CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
-
-CanvasRendererBase.prototype.ctxTransform = function (props) {
-  if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
-    return;
-  }
-  if (!this.renderConfig.clearCanvas) {
-    this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
-    return;
-  }
-  this.transformMat.cloneFromProps(props);
-  var cProps = this.contextData.cTr.props;
-  this.transformMat.transform(cProps[0], cProps[1], cProps[2], cProps[3], cProps[4], cProps[5], cProps[6], cProps[7], cProps[8], cProps[9], cProps[10], cProps[11], cProps[12], cProps[13], cProps[14], cProps[15]);
-  // this.contextData.cTr.transform(props[0],props[1],props[2],props[3],props[4],props[5],props[6],props[7],props[8],props[9],props[10],props[11],props[12],props[13],props[14],props[15]);
-  this.contextData.cTr.cloneFromProps(this.transformMat.props);
-  var trProps = this.contextData.cTr.props;
-  this.canvasContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
-};
-
-CanvasRendererBase.prototype.ctxOpacity = function (op) {
-  /* if(op === 1){
-        return;
-    } */
-  if (!this.renderConfig.clearCanvas) {
-    this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
-    this.globalData.currentGlobalAlpha = this.contextData.cO;
-    return;
-  }
-  this.contextData.cO *= op < 0 ? 0 : op;
-  if (this.globalData.currentGlobalAlpha !== this.contextData.cO) {
-    this.canvasContext.globalAlpha = this.contextData.cO;
-    this.globalData.currentGlobalAlpha = this.contextData.cO;
-  }
-};
-
-CanvasRendererBase.prototype.reset = function () {
-  if (!this.renderConfig.clearCanvas) {
-    this.canvasContext.restore();
-    return;
-  }
-  this.contextData.reset();
-};
-
-CanvasRendererBase.prototype.save = function (actionFlag) {
-  if (!this.renderConfig.clearCanvas) {
-    this.canvasContext.save();
-    return;
-  }
-  if (actionFlag) {
-    this.canvasContext.save();
-  }
-  var props = this.contextData.cTr.props;
-  if (this.contextData._length <= this.contextData.cArrPos) {
-    this.contextData.duplicate();
-  }
-  var i;
-  var arr = this.contextData.saved[this.contextData.cArrPos];
-  for (i = 0; i < 16; i += 1) {
-    arr[i] = props[i];
-  }
-  this.contextData.savedOp[this.contextData.cArrPos] = this.contextData.cO;
-  this.contextData.cArrPos += 1;
-};
-
-CanvasRendererBase.prototype.restore = function (actionFlag) {
-  if (!this.renderConfig.clearCanvas) {
-    this.canvasContext.restore();
-    return;
-  }
-  if (actionFlag) {
-    this.canvasContext.restore();
-    this.globalData.blendMode = 'source-over';
-  }
-  this.contextData.cArrPos -= 1;
-  var popped = this.contextData.saved[this.contextData.cArrPos];
-  var i;
-  var arr = this.contextData.cTr.props;
-  for (i = 0; i < 16; i += 1) {
-    arr[i] = popped[i];
-  }
-  this.canvasContext.setTransform(popped[0], popped[1], popped[4], popped[5], popped[12], popped[13]);
-  popped = this.contextData.savedOp[this.contextData.cArrPos];
-  this.contextData.cO = popped;
-  if (this.globalData.currentGlobalAlpha !== popped) {
-    this.canvasContext.globalAlpha = popped;
-    this.globalData.currentGlobalAlpha = popped;
-  }
-};
-
-CanvasRendererBase.prototype.configAnimation = function (animData) {
-  if (this.animationItem.wrapper) {
-    this.animationItem.container = createTag('canvas');
-    var containerStyle = this.animationItem.container.style;
-    containerStyle.width = '100%';
-    containerStyle.height = '100%';
-    var origin = '0px 0px 0px';
-    containerStyle.transformOrigin = origin;
-    containerStyle.mozTransformOrigin = origin;
-    containerStyle.webkitTransformOrigin = origin;
-    containerStyle['-webkit-transform'] = origin;
-    containerStyle.contentVisibility = this.renderConfig.contentVisibility;
-    this.animationItem.wrapper.appendChild(this.animationItem.container);
-    this.canvasContext = this.animationItem.container.getContext('2d');
-    if (this.renderConfig.className) {
-      this.animationItem.container.setAttribute('class', this.renderConfig.className);
-    }
-    if (this.renderConfig.id) {
-      this.animationItem.container.setAttribute('id', this.renderConfig.id);
-    }
-  } else {
-    this.canvasContext = this.renderConfig.context;
-  }
-  this.data = animData;
-  this.layers = animData.layers;
-  this.transformCanvas = {
-    w: animData.w,
-    h: animData.h,
-    sx: 0,
-    sy: 0,
-    tx: 0,
-    ty: 0,
-  };
-  this.setupGlobalData(animData, document.body);
-  this.globalData.canvasContext = this.canvasContext;
-  this.globalData.renderer = this;
-  this.globalData.isDashed = false;
-  this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
-  this.globalData.transformCanvas = this.transformCanvas;
-  this.elements = createSizedArray(animData.layers.length);
-
-  this.updateContainerSize();
-};
-
-CanvasRendererBase.prototype.updateContainerSize = function () {
-  this.reset();
-  var elementWidth;
-  var elementHeight;
-  if (this.animationItem.wrapper && this.animationItem.container) {
-    elementWidth = this.animationItem.wrapper.offsetWidth;
-    elementHeight = this.animationItem.wrapper.offsetHeight;
-    this.animationItem.container.setAttribute('width', elementWidth * this.renderConfig.dpr);
-    this.animationItem.container.setAttribute('height', elementHeight * this.renderConfig.dpr);
-  } else {
-    elementWidth = this.canvasContext.canvas.width * this.renderConfig.dpr;
-    elementHeight = this.canvasContext.canvas.height * this.renderConfig.dpr;
-  }
-  var elementRel;
-  var animationRel;
-  if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
-    var par = this.renderConfig.preserveAspectRatio.split(' ');
-    var fillType = par[1] || 'meet';
-    var pos = par[0] || 'xMidYMid';
-    var xPos = pos.substr(0, 4);
-    var yPos = pos.substr(4);
-    elementRel = elementWidth / elementHeight;
-    animationRel = this.transformCanvas.w / this.transformCanvas.h;
-    if ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice')) {
-      this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
-      this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
-    } else {
-      this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
-      this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
-    }
-
-    if (xPos === 'xMid' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
-      this.transformCanvas.tx = ((elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2) * this.renderConfig.dpr;
-    } else if (xPos === 'xMax' && ((animationRel < elementRel && fillType === 'meet') || (animationRel > elementRel && fillType === 'slice'))) {
-      this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) * this.renderConfig.dpr;
-    } else {
-      this.transformCanvas.tx = 0;
-    }
-    if (yPos === 'YMid' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
-      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2) * this.renderConfig.dpr;
-    } else if (yPos === 'YMax' && ((animationRel > elementRel && fillType === 'meet') || (animationRel < elementRel && fillType === 'slice'))) {
-      this.transformCanvas.ty = ((elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w))) * this.renderConfig.dpr;
-    } else {
-      this.transformCanvas.ty = 0;
-    }
-  } else if (this.renderConfig.preserveAspectRatio === 'none') {
-    this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
-    this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
-    this.transformCanvas.tx = 0;
-    this.transformCanvas.ty = 0;
-  } else {
-    this.transformCanvas.sx = this.renderConfig.dpr;
-    this.transformCanvas.sy = this.renderConfig.dpr;
-    this.transformCanvas.tx = 0;
-    this.transformCanvas.ty = 0;
-  }
-  this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
-  /* var i, len = this.elements.length;
-    for(i=0;i<len;i+=1){
-        if(this.elements[i] && this.elements[i].data.ty === 0){
-            this.elements[i].resize(this.globalData.transformCanvas);
-        }
-    } */
-  this.ctxTransform(this.transformCanvas.props);
-  this.canvasContext.beginPath();
-  this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
-  this.canvasContext.closePath();
-  this.canvasContext.clip();
-
-  this.renderFrame(this.renderedFrame, true);
-};
-
-CanvasRendererBase.prototype.destroy = function () {
-  if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
-    this.animationItem.wrapper.innerText = '';
-  }
-  var i;
-  var len = this.layers ? this.layers.length : 0;
-  for (i = len - 1; i >= 0; i -= 1) {
-    if (this.elements[i]) {
-      this.elements[i].destroy();
-    }
-  }
-  this.elements.length = 0;
-  this.globalData.canvasContext = null;
-  this.animationItem.container = null;
-  this.destroyed = true;
-};
-
-CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
-  if ((this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender) || this.destroyed || num === -1) {
-    return;
-  }
-  this.renderedFrame = num;
-  this.globalData.frameNum = num - this.animationItem._isFirstFrame;
-  this.globalData.frameId += 1;
-  this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
-  this.globalData.projectInterface.currentFrame = num;
-
-  // console.log('--------');
-  // console.log('NEW: ',num);
-  var i;
-  var len = this.layers.length;
-  if (!this.completeLayers) {
-    this.checkLayers(num);
-  }
-
-  for (i = 0; i < len; i += 1) {
-    if (this.completeLayers || this.elements[i]) {
-      this.elements[i].prepareFrame(num - this.layers[i].st);
-    }
-  }
-  if (this.globalData._mdf) {
-    if (this.renderConfig.clearCanvas === true) {
-      this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
-    } else {
-      this.save();
-    }
-    for (i = len - 1; i >= 0; i -= 1) {
-      if (this.completeLayers || this.elements[i]) {
-        this.elements[i].renderFrame();
-      }
-    }
-    if (this.renderConfig.clearCanvas !== true) {
-      this.restore();
-    }
-  }
-};
-
-CanvasRendererBase.prototype.buildItem = function (pos) {
-  var elements = this.elements;
-  if (elements[pos] || this.layers[pos].ty === 99) {
-    return;
-  }
-  var element = this.createItem(this.layers[pos], this, this.globalData);
-  elements[pos] = element;
-  element.initExpressions();
-  /* if(this.layers[pos].ty === 0){
-        element.resize(this.globalData.transformCanvas);
-    } */
-};
-
-CanvasRendererBase.prototype.checkPendingElements = function () {
-  while (this.pendingElements.length) {
-    var element = this.pendingElements.pop();
-    element.checkParenting();
-  }
-};
-
-CanvasRendererBase.prototype.hide = function () {
-  this.animationItem.container.style.display = 'none';
-};
-
-CanvasRendererBase.prototype.show = function () {
-  this.animationItem.container.style.display = 'block';
-};
-
-function CVCompElement(data, globalData, comp) {
-  this.completeLayers = false;
-  this.layers = data.layers;
-  this.pendingElements = [];
-  this.elements = createSizedArray(this.layers.length);
-  this.initElement(data, globalData, comp);
-  this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : { _placeholder: true };
-}
-
-extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
-
-CVCompElement.prototype.renderInnerContent = function () {
-  var ctx = this.canvasContext;
-  ctx.beginPath();
-  ctx.moveTo(0, 0);
-  ctx.lineTo(this.data.w, 0);
-  ctx.lineTo(this.data.w, this.data.h);
-  ctx.lineTo(0, this.data.h);
-  ctx.lineTo(0, 0);
-  ctx.clip();
-  var i;
-  var len = this.layers.length;
-  for (i = len - 1; i >= 0; i -= 1) {
-    if (this.completeLayers || this.elements[i]) {
-      this.elements[i].renderFrame();
-    }
-  }
-};
-
-CVCompElement.prototype.destroy = function () {
-  var i;
-  var len = this.layers.length;
-  for (i = len - 1; i >= 0; i -= 1) {
-    if (this.elements[i]) {
-      this.elements[i].destroy();
-    }
-  }
-  this.layers = null;
-  this.elements = null;
-};
-
-CVCompElement.prototype.createComp = function (data) {
-  return new CVCompElement(data, this.globalData, this);
-};
-
-function CanvasRenderer(animationItem, config) {
-  this.animationItem = animationItem;
-  this.renderConfig = {
-    clearCanvas: (config && config.clearCanvas !== undefined) ? config.clearCanvas : true,
-    context: (config && config.context) || null,
-    progressiveLoad: (config && config.progressiveLoad) || false,
-    preserveAspectRatio: (config && config.preserveAspectRatio) || 'xMidYMid meet',
-    imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
-    contentVisibility: (config && config.contentVisibility) || 'visible',
-    className: (config && config.className) || '',
-    id: (config && config.id) || '',
-  };
-  this.renderConfig.dpr = (config && config.dpr) || 1;
-  if (this.animationItem.wrapper) {
-    this.renderConfig.dpr = (config && config.dpr) || window.devicePixelRatio || 1;
-  }
-  this.renderedFrame = -1;
-  this.globalData = {
-    frameNum: -1,
-    _mdf: false,
-    renderConfig: this.renderConfig,
-    currentGlobalAlpha: -1,
-  };
-  this.contextData = new CVContextData();
-  this.elements = [];
-  this.pendingElements = [];
-  this.transformMat = new Matrix();
-  this.completeLayers = false;
-  this.rendererType = 'canvas';
-}
-extendPrototype([CanvasRendererBase], CanvasRenderer);
-
-CanvasRenderer.prototype.createComp = function (data) {
-  return new CVCompElement(data, this.globalData, this);
-};
-
-// Registering renderers
-registerRenderer('canvas', CanvasRenderer);
-
-// Registering shape modifiers
-ShapeModifiers.registerModifier('tm', TrimModifier);
-ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
-ShapeModifiers.registerModifier('rp', RepeaterModifier);
-ShapeModifiers.registerModifier('rd', RoundCornersModifier);
-
-const Expressions = (function () {
-  var ob = {};
-  ob.initExpressions = initExpressions;
-
-  function initExpressions(animation) {
-    var stackCount = 0;
-    var registers = [];
-
-    function pushExpression() {
-      stackCount += 1;
-    }
-
-    function popExpression() {
-      stackCount -= 1;
-      if (stackCount === 0) {
-        releaseInstances();
-      }
-    }
-
-    function registerExpressionProperty(expression) {
-      if (registers.indexOf(expression) === -1) {
-        registers.push(expression);
-      }
-    }
-
-    function releaseInstances() {
-      var i;
-      var len = registers.length;
-      for (i = 0; i < len; i += 1) {
-        registers[i].release();
-      }
-      registers.length = 0;
-    }
-
-    animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
-    animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
-    animation.renderer.globalData.pushExpression = pushExpression;
-    animation.renderer.globalData.popExpression = popExpression;
-    animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
-  }
-  return ob;
-}());
-
-/* eslint-disable */
-/*
- Copyright 2014 David Bau.
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- */
-
-function seedRandom(pool, math) {
-//
-// The following constants are related to IEEE 754 limits.
-//
-    var global = this,
-        width = 256,        // each RC4 output is 0 <= x < 256
-        chunks = 6,         // at least six RC4 outputs for each double
-        digits = 52,        // there are 52 significant digits in a double
-        rngname = 'random', // rngname: name for Math.random and Math.seedrandom
-        startdenom = math.pow(width, chunks),
-        significance = math.pow(2, digits),
-        overflow = significance * 2,
-        mask = width - 1,
-        nodecrypto;         // node.js crypto module, initialized at the bottom.
-
-//
-// seedrandom()
-// This is the seedrandom function described above.
-//
-    function seedrandom(seed, options, callback) {
-        var key = [];
-        options = (options === true) ? { entropy: true } : (options || {});
-
-        // Flatten the seed string or build one from local entropy if needed.
-        var shortseed = mixkey(flatten(
-            options.entropy ? [seed, tostring(pool)] :
-                (seed === null) ? autoseed() : seed, 3), key);
-
-        // Use the seed to initialize an ARC4 generator.
-        var arc4 = new ARC4(key);
-
-        // This function returns a random double in [0, 1) that contains
-        // randomness in every bit of the mantissa of the IEEE 754 value.
-        var prng = function() {
-            var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48
-                d = startdenom,                 //   and denominator d = 2 ^ 48.
-                x = 0;                          //   and no 'extra last byte'.
-            while (n < significance) {          // Fill up all significant digits by
-                n = (n + x) * width;              //   shifting numerator and
-                d *= width;                       //   denominator and generating a
-                x = arc4.g(1);                    //   new least-significant-byte.
-            }
-            while (n >= overflow) {             // To avoid rounding up, before adding
-                n /= 2;                           //   last byte, shift everything
-                d /= 2;                           //   right using integer math until
-                x >>>= 1;                         //   we have exactly the desired bits.
-            }
-            return (n + x) / d;                 // Form the number within [0, 1).
-        };
-
-        prng.int32 = function() { return arc4.g(4) | 0; };
-        prng.quick = function() { return arc4.g(4) / 0x100000000; };
-        prng.double = prng;
-
-        // Mix the randomness into accumulated entropy.
-        mixkey(tostring(arc4.S), pool);
-
-        // Calling convention: what to return as a function of prng, seed, is_math.
-        return (options.pass || callback ||
-        function(prng, seed, is_math_call, state) {
-            if (state) {
-                // Load the arc4 state from the given state if it has an S array.
-                if (state.S) { copy(state, arc4); }
-                // Only provide the .state method if requested via options.state.
-                prng.state = function() { return copy(arc4, {}); };
-            }
-
-            // If called as a method of Math (Math.seedrandom()), mutate
-            // Math.random because that is how seedrandom.js has worked since v1.0.
-            if (is_math_call) { math[rngname] = prng; return seed; }
-
-            // Otherwise, it is a newer calling convention, so return the
-            // prng directly.
-            else return prng;
-        })(
-            prng,
-            shortseed,
-            'global' in options ? options.global : (this == math),
-            options.state);
-    }
-    math['seed' + rngname] = seedrandom;
-
-//
-// ARC4
-//
-// An ARC4 implementation.  The constructor takes a key in the form of
-// an array of at most (width) integers that should be 0 <= x < (width).
-//
-// The g(count) method returns a pseudorandom integer that concatenates
-// the next (count) outputs from ARC4.  Its return value is a number x
-// that is in the range 0 <= x < (width ^ count).
-//
-    function ARC4(key) {
-        var t, keylen = key.length,
-            me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
-
-        // The empty key [] is treated as [0].
-        if (!keylen) { key = [keylen++]; }
-
-        // Set up S using the standard key scheduling algorithm.
-        while (i < width) {
-            s[i] = i++;
-        }
-        for (i = 0; i < width; i++) {
-            s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
-            s[j] = t;
-        }
-
-        // The "g" method returns the next (count) outputs as one number.
-        me.g = function(count) {
-            // Using instance members instead of closure state nearly doubles speed.
-            var t, r = 0,
-                i = me.i, j = me.j, s = me.S;
-            while (count--) {
-                t = s[i = mask & (i + 1)];
-                r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
-            }
-            me.i = i; me.j = j;
-            return r;
-            // For robust unpredictability, the function call below automatically
-            // discards an initial batch of values.  This is called RC4-drop[256].
-            // See http://google.com/search?q=rsa+fluhrer+response&btnI
-        };
-    }
-
-//
-// copy()
-// Copies internal state of ARC4 to or from a plain object.
-//
-    function copy(f, t) {
-        t.i = f.i;
-        t.j = f.j;
-        t.S = f.S.slice();
-        return t;
-    }
-
-//
-// flatten()
-// Converts an object tree to nested arrays of strings.
-//
-    function flatten(obj, depth) {
-        var result = [], typ = (typeof obj), prop;
-        if (depth && typ == 'object') {
-            for (prop in obj) {
-                try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
-            }
-        }
-        return (result.length ? result : typ == 'string' ? obj : obj + '\0');
-    }
-
-//
-// mixkey()
-// Mixes a string seed into a key that is an array of integers, and
-// returns a shortened string seed that is equivalent to the result key.
-//
-    function mixkey(seed, key) {
-        var stringseed = seed + '', smear, j = 0;
-        while (j < stringseed.length) {
-            key[mask & j] =
-                mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
-        }
-        return tostring(key);
-    }
-
-//
-// autoseed()
-// Returns an object for autoseeding, using window.crypto and Node crypto
-// module if available.
-//
-    function autoseed() {
-        try {
-            if (nodecrypto) { return tostring(nodecrypto.randomBytes(width)); }
-            var out = new Uint8Array(width);
-            (global.crypto || global.msCrypto).getRandomValues(out);
-            return tostring(out);
-        } catch (e) {
-            var browser = global.navigator,
-                plugins = browser && browser.plugins;
-            return [+new Date(), global, plugins, global.screen, tostring(pool)];
-        }
-    }
-
-//
-// tostring()
-// Converts an array of charcodes to a string
-//
-    function tostring(a) {
-        return String.fromCharCode.apply(0, a);
-    }
-
-//
-// When seedrandom.js is loaded, we immediately mix a few bits
-// from the built-in RNG into the entropy pool.  Because we do
-// not want to interfere with deterministic PRNG state later,
-// seedrandom will not call math.random on its own again after
-// initialization.
-//
-    mixkey(math.random(), pool);
-
-//
-// Nodejs and AMD support: export the implementation as a module using
-// either convention.
-//
-
-// End anonymous scope, and pass initial values.
-};
-
-function initialize$2(BMMath) {
-    seedRandom([], BMMath);
-}
-
-var propTypes = {
-  SHAPE: 'shape',
-};
-
-/* eslint-disable camelcase */
-
-const ExpressionManager = (function () {
-  'use strict';
-
-  var ob = {};
-  var Math = BMMath;
-  var window = null;
-  var document = null;
-  var XMLHttpRequest = null;
-  var fetch = null;
-  var frames = null;
-  initialize$2(BMMath);
-
-  function $bm_isInstanceOfArray(arr) {
-    return arr.constructor === Array || arr.constructor === Float32Array;
-  }
-
-  function isNumerable(tOfV, v) {
-    return tOfV === 'number' || tOfV === 'boolean' || tOfV === 'string' || v instanceof Number;
-  }
-
-  function $bm_neg(a) {
-    var tOfA = typeof a;
-    if (tOfA === 'number' || tOfA === 'boolean' || a instanceof Number) {
-      return -a;
-    }
-    if ($bm_isInstanceOfArray(a)) {
-      var i;
-      var lenA = a.length;
-      var retArr = [];
-      for (i = 0; i < lenA; i += 1) {
-        retArr[i] = -a[i];
-      }
-      return retArr;
-    }
-    if (a.propType) {
-      return a.v;
-    }
-    return -a;
-  }
-
-  var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
-  var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
-  var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
-
-  function sum(a, b) {
-    var tOfA = typeof a;
-    var tOfB = typeof b;
-    if (tOfA === 'string' || tOfB === 'string') {
-      return a + b;
-    }
-    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
-      return a + b;
-    }
-    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
-      a = a.slice(0);
-      a[0] += b;
-      return a;
-    }
-    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
-      b = b.slice(0);
-      b[0] = a + b[0];
-      return b;
-    }
-    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
-      var i = 0;
-      var lenA = a.length;
-      var lenB = b.length;
-      var retArr = [];
-      while (i < lenA || i < lenB) {
-        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
-          retArr[i] = a[i] + b[i];
-        } else {
-          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
-        }
-        i += 1;
-      }
-      return retArr;
-    }
-    return 0;
-  }
-  var add = sum;
-
-  function sub(a, b) {
-    var tOfA = typeof a;
-    var tOfB = typeof b;
-    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
-      if (tOfA === 'string') {
-        a = parseInt(a, 10);
-      }
-      if (tOfB === 'string') {
-        b = parseInt(b, 10);
-      }
-      return a - b;
-    }
-    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
-      a = a.slice(0);
-      a[0] -= b;
-      return a;
-    }
-    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
-      b = b.slice(0);
-      b[0] = a - b[0];
-      return b;
-    }
-    if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
-      var i = 0;
-      var lenA = a.length;
-      var lenB = b.length;
-      var retArr = [];
-      while (i < lenA || i < lenB) {
-        if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
-          retArr[i] = a[i] - b[i];
-        } else {
-          retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
-        }
-        i += 1;
-      }
-      return retArr;
-    }
-    return 0;
-  }
-
-  function mul(a, b) {
-    var tOfA = typeof a;
-    var tOfB = typeof b;
-    var arr;
-    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
-      return a * b;
-    }
-
-    var i;
-    var len;
-    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
-      len = a.length;
-      arr = createTypedArray('float32', len);
-      for (i = 0; i < len; i += 1) {
-        arr[i] = a[i] * b;
-      }
-      return arr;
-    }
-    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
-      len = b.length;
-      arr = createTypedArray('float32', len);
-      for (i = 0; i < len; i += 1) {
-        arr[i] = a * b[i];
-      }
-      return arr;
-    }
-    return 0;
-  }
-
-  function div(a, b) {
-    var tOfA = typeof a;
-    var tOfB = typeof b;
-    var arr;
-    if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
-      return a / b;
-    }
-    var i;
-    var len;
-    if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
-      len = a.length;
-      arr = createTypedArray('float32', len);
-      for (i = 0; i < len; i += 1) {
-        arr[i] = a[i] / b;
-      }
-      return arr;
-    }
-    if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
-      len = b.length;
-      arr = createTypedArray('float32', len);
-      for (i = 0; i < len; i += 1) {
-        arr[i] = a / b[i];
-      }
-      return arr;
-    }
-    return 0;
-  }
-  function mod(a, b) {
-    if (typeof a === 'string') {
-      a = parseInt(a, 10);
-    }
-    if (typeof b === 'string') {
-      b = parseInt(b, 10);
-    }
-    return a % b;
-  }
-  var $bm_sum = sum;
-  var $bm_sub = sub;
-  var $bm_mul = mul;
-  var $bm_div = div;
-  var $bm_mod = mod;
-
-  function clamp(num, min, max) {
-    if (min > max) {
-      var mm = max;
-      max = min;
-      min = mm;
-    }
-    return Math.min(Math.max(num, min), max);
-  }
-
-  function radiansToDegrees(val) {
-    return val / degToRads;
-  }
-  var radians_to_degrees = radiansToDegrees;
-
-  function degreesToRadians(val) {
-    return val * degToRads;
-  }
-  var degrees_to_radians = radiansToDegrees;
-
-  var helperLengthArray = [0, 0, 0, 0, 0, 0];
-
-  function length(arr1, arr2) {
-    if (typeof arr1 === 'number' || arr1 instanceof Number) {
-      arr2 = arr2 || 0;
-      return Math.abs(arr1 - arr2);
-    }
-    if (!arr2) {
-      arr2 = helperLengthArray;
-    }
-    var i;
-    var len = Math.min(arr1.length, arr2.length);
-    var addedLength = 0;
-    for (i = 0; i < len; i += 1) {
-      addedLength += Math.pow(arr2[i] - arr1[i], 2);
-    }
-    return Math.sqrt(addedLength);
-  }
-
-  function normalize(vec) {
-    return div(vec, length(vec));
-  }
-
-  function rgbToHsl(val) {
-    var r = val[0]; var g = val[1]; var b = val[2];
-    var max = Math.max(r, g, b);
-    var min = Math.min(r, g, b);
-    var h;
-    var s;
-    var l = (max + min) / 2;
-
-    if (max === min) {
-      h = 0; // achromatic
-      s = 0; // achromatic
-    } else {
-      var d = max - min;
-      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
-      switch (max) {
-        case r: h = (g - b) / d + (g < b ? 6 : 0); break;
-        case g: h = (b - r) / d + 2; break;
-        case b: h = (r - g) / d + 4; break;
-        default: break;
-      }
-      h /= 6;
-    }
-
-    return [h, s, l, val[3]];
-  }
-
-  function hue2rgb(p, q, t) {
-    if (t < 0) t += 1;
-    if (t > 1) t -= 1;
-    if (t < 1 / 6) return p + (q - p) * 6 * t;
-    if (t < 1 / 2) return q;
-    if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
-    return p;
-  }
-
-  function hslToRgb(val) {
-    var h = val[0];
-    var s = val[1];
-    var l = val[2];
-
-    var r;
-    var g;
-    var b;
-
-    if (s === 0) {
-      r = l; // achromatic
-      b = l; // achromatic
-      g = l; // achromatic
-    } else {
-      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
-      var p = 2 * l - q;
-      r = hue2rgb(p, q, h + 1 / 3);
-      g = hue2rgb(p, q, h);
-      b = hue2rgb(p, q, h - 1 / 3);
-    }
-
-    return [r, g, b, val[3]];
-  }
-
-  function linear(t, tMin, tMax, value1, value2) {
-    if (value1 === undefined || value2 === undefined) {
-      value1 = tMin;
-      value2 = tMax;
-      tMin = 0;
-      tMax = 1;
-    }
-    if (tMax < tMin) {
-      var _tMin = tMax;
-      tMax = tMin;
-      tMin = _tMin;
-    }
-    if (t <= tMin) {
-      return value1;
-    } if (t >= tMax) {
-      return value2;
-    }
-    var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
-    if (!value1.length) {
-      return value1 + (value2 - value1) * perc;
-    }
-    var i;
-    var len = value1.length;
-    var arr = createTypedArray('float32', len);
-    for (i = 0; i < len; i += 1) {
-      arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
-    }
-    return arr;
-  }
-  function random(min, max) {
-    if (max === undefined) {
-      if (min === undefined) {
-        min = 0;
-        max = 1;
-      } else {
-        max = min;
-        min = undefined;
-      }
-    }
-    if (max.length) {
-      var i;
-      var len = max.length;
-      if (!min) {
-        min = createTypedArray('float32', len);
-      }
-      var arr = createTypedArray('float32', len);
-      var rnd = BMMath.random();
-      for (i = 0; i < len; i += 1) {
-        arr[i] = min[i] + rnd * (max[i] - min[i]);
-      }
-      return arr;
-    }
-    if (min === undefined) {
-      min = 0;
-    }
-    var rndm = BMMath.random();
-    return min + rndm * (max - min);
-  }
-
-  function createPath(points, inTangents, outTangents, closed) {
-    var i;
-    var len = points.length;
-    var path = shapePool.newElement();
-    path.setPathData(!!closed, len);
-    var arrPlaceholder = [0, 0];
-    var inVertexPoint;
-    var outVertexPoint;
-    for (i = 0; i < len; i += 1) {
-      inVertexPoint = (inTangents && inTangents[i]) ? inTangents[i] : arrPlaceholder;
-      outVertexPoint = (outTangents && outTangents[i]) ? outTangents[i] : arrPlaceholder;
-      path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
-    }
-    return path;
-  }
-
-  function initiateExpression(elem, data, property) {
-    var val = data.x;
-    var needsVelocity = /velocity(?![\w\d])/.test(val);
-    var _needsRandom = val.indexOf('random') !== -1;
-    var elemType = elem.data.ty;
-    var transform;
-    var $bm_transform;
-    var content;
-    var effect;
-    var thisProperty = property;
-    thisProperty.valueAtTime = thisProperty.getValueAtTime;
-    Object.defineProperty(thisProperty, 'value', {
-      get: function () {
-        return thisProperty.v;
-      },
-    });
-    elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate;
-    elem.comp.displayStartTime = 0;
-    var inPoint = elem.data.ip / elem.comp.globalData.frameRate;
-    var outPoint = elem.data.op / elem.comp.globalData.frameRate;
-    var width = elem.data.sw ? elem.data.sw : 0;
-    var height = elem.data.sh ? elem.data.sh : 0;
-    var name = elem.data.nm;
-    var loopIn;
-    var loop_in;
-    var loopOut;
-    var loop_out;
-    var smooth;
-    var toWorld;
-    var fromWorld;
-    var fromComp;
-    var toComp;
-    var fromCompToSurface;
-    var position;
-    var rotation;
-    var anchorPoint;
-    var scale;
-    var thisLayer;
-    var thisComp;
-    var mask;
-    var valueAtTime;
-    var velocityAtTime;
-
-    var scoped_bm_rt;
-    // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
-    var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
-    var numKeys = property.kf ? data.k.length : 0;
-
-    var active = !this.data || this.data.hd !== true;
-
-    var wiggle = function wiggle(freq, amp) {
-      var iWiggle;
-      var j;
-      var lenWiggle = this.pv.length ? this.pv.length : 1;
-      var addedAmps = createTypedArray('float32', lenWiggle);
-      freq = 5;
-      var iterations = Math.floor(time * freq);
-      iWiggle = 0;
-      j = 0;
-      while (iWiggle < iterations) {
-        // var rnd = BMMath.random();
-        for (j = 0; j < lenWiggle; j += 1) {
-          addedAmps[j] += -amp + amp * 2 * BMMath.random();
-          // addedAmps[j] += -amp + amp*2*rnd;
-        }
-        iWiggle += 1;
-      }
-      // var rnd2 = BMMath.random();
-      var periods = time * freq;
-      var perc = periods - Math.floor(periods);
-      var arr = createTypedArray('float32', lenWiggle);
-      if (lenWiggle > 1) {
-        for (j = 0; j < lenWiggle; j += 1) {
-          arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
-          // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
-          // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
-        }
-        return arr;
-      }
-      return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
-    }.bind(this);
-
-    if (thisProperty.loopIn) {
-      loopIn = thisProperty.loopIn.bind(thisProperty);
-      loop_in = loopIn;
-    }
-
-    if (thisProperty.loopOut) {
-      loopOut = thisProperty.loopOut.bind(thisProperty);
-      loop_out = loopOut;
-    }
-
-    if (thisProperty.smooth) {
-      smooth = thisProperty.smooth.bind(thisProperty);
-    }
-
-    function loopInDuration(type, duration) {
-      return loopIn(type, duration, true);
-    }
-
-    function loopOutDuration(type, duration) {
-      return loopOut(type, duration, true);
-    }
-
-    if (this.getValueAtTime) {
-      valueAtTime = this.getValueAtTime.bind(this);
-    }
-
-    if (this.getVelocityAtTime) {
-      velocityAtTime = this.getVelocityAtTime.bind(this);
-    }
-
-    var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
-
-    function lookAt(elem1, elem2) {
-      var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
-      var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
-      var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
-      return [yaw, pitch, 0];
-    }
-
-    function easeOut(t, tMin, tMax, val1, val2) {
-      return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
-    }
-
-    function easeIn(t, tMin, tMax, val1, val2) {
-      return applyEase(easeInBez, t, tMin, tMax, val1, val2);
-    }
-
-    function ease(t, tMin, tMax, val1, val2) {
-      return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
-    }
-
-    function applyEase(fn, t, tMin, tMax, val1, val2) {
-      if (val1 === undefined) {
-        val1 = tMin;
-        val2 = tMax;
-      } else {
-        t = (t - tMin) / (tMax - tMin);
-      }
-      if (t > 1) {
-        t = 1;
-      } else if (t < 0) {
-        t = 0;
-      }
-      var mult = fn(t);
-      if ($bm_isInstanceOfArray(val1)) {
-        var iKey;
-        var lenKey = val1.length;
-        var arr = createTypedArray('float32', lenKey);
-        for (iKey = 0; iKey < lenKey; iKey += 1) {
-          arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
-        }
-        return arr;
-      }
-      return (val2 - val1) * mult + val1;
-    }
-
-    function nearestKey(time) {
-      var iKey;
-      var lenKey = data.k.length;
-      var index;
-      var keyTime;
-      if (!data.k.length || typeof (data.k[0]) === 'number') {
-        index = 0;
-        keyTime = 0;
-      } else {
-        index = -1;
-        time *= elem.comp.globalData.frameRate;
-        if (time < data.k[0].t) {
-          index = 1;
-          keyTime = data.k[0].t;
-        } else {
-          for (iKey = 0; iKey < lenKey - 1; iKey += 1) {
-            if (time === data.k[iKey].t) {
-              index = iKey + 1;
-              keyTime = data.k[iKey].t;
-              break;
-            } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) {
-              if (time - data.k[iKey].t > data.k[iKey + 1].t - time) {
-                index = iKey + 2;
-                keyTime = data.k[iKey + 1].t;
-              } else {
-                index = iKey + 1;
-                keyTime = data.k[iKey].t;
-              }
-              break;
-            }
-          }
-          if (index === -1) {
-            index = iKey + 1;
-            keyTime = data.k[iKey].t;
-          }
-        }
-      }
-      var obKey = {};
-      obKey.index = index;
-      obKey.time = keyTime / elem.comp.globalData.frameRate;
-      return obKey;
-    }
-
-    function key(ind) {
-      var obKey;
-      var iKey;
-      var lenKey;
-      if (!data.k.length || typeof (data.k[0]) === 'number') {
-        throw new Error('The property has no keyframe at index ' + ind);
-      }
-      ind -= 1;
-      obKey = {
-        time: data.k[ind].t / elem.comp.globalData.frameRate,
-        value: [],
-      };
-      var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
-
-      lenKey = arr.length;
-      for (iKey = 0; iKey < lenKey; iKey += 1) {
-        obKey[iKey] = arr[iKey];
-        obKey.value[iKey] = arr[iKey];
-      }
-      return obKey;
-    }
-
-    function framesToTime(fr, fps) {
-      if (!fps) {
-        fps = elem.comp.globalData.frameRate;
-      }
-      return fr / fps;
-    }
-
-    function timeToFrames(t, fps) {
-      if (!t && t !== 0) {
-        t = time;
-      }
-      if (!fps) {
-        fps = elem.comp.globalData.frameRate;
-      }
-      return t * fps;
-    }
-
-    function seedRandom(seed) {
-      BMMath.seedrandom(randSeed + seed);
-    }
-
-    function sourceRectAtTime() {
-      return elem.sourceRectAtTime();
-    }
-
-    function substring(init, end) {
-      if (typeof value === 'string') {
-        if (end === undefined) {
-          return value.substring(init);
-        }
-        return value.substring(init, end);
-      }
-      return '';
-    }
-
-    function substr(init, end) {
-      if (typeof value === 'string') {
-        if (end === undefined) {
-          return value.substr(init);
-        }
-        return value.substr(init, end);
-      }
-      return '';
-    }
-
-    function posterizeTime(framesPerSecond) {
-      time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
-      value = valueAtTime(time);
-    }
-
-    var time;
-    var velocity;
-    var value;
-    var text;
-    var textIndex;
-    var textTotal;
-    var selectorValue;
-    var index = elem.data.ind;
-    var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
-    var parent;
-    var randSeed = Math.floor(Math.random() * 1000000);
-    var globalData = elem.globalData;
-    function executeExpression(_value) {
-      // globalData.pushExpression();
-      value = _value;
-      if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
-        return value;
-      }
-      if (this.propType === 'textSelector') {
-        textIndex = this.textIndex;
-        textTotal = this.textTotal;
-        selectorValue = this.selectorValue;
-      }
-      if (!thisLayer) {
-        text = elem.layerInterface.text;
-        thisLayer = elem.layerInterface;
-        thisComp = elem.comp.compInterface;
-        toWorld = thisLayer.toWorld.bind(thisLayer);
-        fromWorld = thisLayer.fromWorld.bind(thisLayer);
-        fromComp = thisLayer.fromComp.bind(thisLayer);
-        toComp = thisLayer.toComp.bind(thisLayer);
-        mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
-        fromCompToSurface = fromComp;
-      }
-      if (!transform) {
-        transform = elem.layerInterface('ADBE Transform Group');
-        $bm_transform = transform;
-        if (transform) {
-          anchorPoint = transform.anchorPoint;
-          /* position = transform.position;
-                    rotation = transform.rotation;
-                    scale = transform.scale; */
-        }
-      }
-
-      if (elemType === 4 && !content) {
-        content = thisLayer('ADBE Root Vectors Group');
-      }
-      if (!effect) {
-        effect = thisLayer(4);
-      }
-      hasParent = !!(elem.hierarchy && elem.hierarchy.length);
-      if (hasParent && !parent) {
-        parent = elem.hierarchy[0].layerInterface;
-      }
-      time = this.comp.renderedFrame / this.comp.globalData.frameRate;
-      if (_needsRandom) {
-        seedRandom(randSeed + time);
-      }
-      if (needsVelocity) {
-        velocity = velocityAtTime(time);
-      }
-      expression_function();
-      this.frameExpressionId = elem.globalData.frameId;
-
-      // TODO: Check if it's possible to return on ShapeInterface the .v value
-      // Changed this to a ternary operation because Rollup failed compiling it correctly
-      scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE
-        ? scoped_bm_rt.v
-        : scoped_bm_rt;
-      return scoped_bm_rt;
-    }
-    // Bundlers will see these as dead code and unless we reference them
-    executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
-    return executeExpression;
-  }
-
-  ob.initiateExpression = initiateExpression;
-  ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath];
-  return ob;
-}());
-
-const expressionHelpers = (function () {
-  function searchExpressions(elem, data, prop) {
-    if (data.x) {
-      prop.k = true;
-      prop.x = true;
-      prop.initiateExpression = ExpressionManager.initiateExpression;
-      prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
-    }
-  }
-
-  function getValueAtTime(frameNum) {
-    frameNum *= this.elem.globalData.frameRate;
-    frameNum -= this.offsetTime;
-    if (frameNum !== this._cachingAtTime.lastFrame) {
-      this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
-      this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
-      this._cachingAtTime.lastFrame = frameNum;
-    }
-    return this._cachingAtTime.value;
-  }
-
-  function getSpeedAtTime(frameNum) {
-    var delta = -0.01;
-    var v1 = this.getValueAtTime(frameNum);
-    var v2 = this.getValueAtTime(frameNum + delta);
-    var speed = 0;
-    if (v1.length) {
-      var i;
-      for (i = 0; i < v1.length; i += 1) {
-        speed += Math.pow(v2[i] - v1[i], 2);
-      }
-      speed = Math.sqrt(speed) * 100;
-    } else {
-      speed = 0;
-    }
-    return speed;
-  }
-
-  function getVelocityAtTime(frameNum) {
-    if (this.vel !== undefined) {
-      return this.vel;
-    }
-    var delta = -0.001;
-    // frameNum += this.elem.data.st;
-    var v1 = this.getValueAtTime(frameNum);
-    var v2 = this.getValueAtTime(frameNum + delta);
-    var velocity;
-    if (v1.length) {
-      velocity = createTypedArray('float32', v1.length);
-      var i;
-      for (i = 0; i < v1.length; i += 1) {
-        // removing frameRate
-        // if needed, don't add it here
-        // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
-        velocity[i] = (v2[i] - v1[i]) / delta;
-      }
-    } else {
-      velocity = (v2 - v1) / delta;
-    }
-    return velocity;
-  }
-
-  function getStaticValueAtTime() {
-    return this.pv;
-  }
-
-  function setGroupProperty(propertyGroup) {
-    this.propertyGroup = propertyGroup;
-  }
-
-  return {
-    searchExpressions: searchExpressions,
-    getSpeedAtTime: getSpeedAtTime,
-    getVelocityAtTime: getVelocityAtTime,
-    getValueAtTime: getValueAtTime,
-    getStaticValueAtTime: getStaticValueAtTime,
-    setGroupProperty: setGroupProperty,
-  };
-}());
-
-function addPropertyDecorator() {
-  function loopOut(type, duration, durationFlag) {
-    if (!this.k || !this.keyframes) {
-      return this.pv;
-    }
-    type = type ? type.toLowerCase() : '';
-    var currentFrame = this.comp.renderedFrame;
-    var keyframes = this.keyframes;
-    var lastKeyFrame = keyframes[keyframes.length - 1].t;
-    if (currentFrame <= lastKeyFrame) {
-      return this.pv;
-    }
-    var cycleDuration;
-    var firstKeyFrame;
-    if (!durationFlag) {
-      if (!duration || duration > keyframes.length - 1) {
-        duration = keyframes.length - 1;
-      }
-      firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
-      cycleDuration = lastKeyFrame - firstKeyFrame;
-    } else {
-      if (!duration) {
-        cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip);
-      } else {
-        cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
-      }
-      firstKeyFrame = lastKeyFrame - cycleDuration;
-    }
-    var i;
-    var len;
-    var ret;
-    if (type === 'pingpong') {
-      var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-      if (iterations % 2 !== 0) {
-          return this.getValueAtTime(((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-      }
-    } else if (type === 'offset') {
-      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
-      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
-        var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-      var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
-      if (this.pv.length) {
-        ret = new Array(initV.length);
-        len = ret.length;
-        for (i = 0; i < len; i += 1) {
-          ret[i] = (endV[i] - initV[i]) * repeats + current[i];
-        }
-        return ret;
-      }
-      return (endV - initV) * repeats + current;
-    } else if (type === 'continue') {
-      var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
-      var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
-      if (this.pv.length) {
-        ret = new Array(lastValue.length);
-        len = ret.length;
-        for (i = 0; i < len; i += 1) {
-            ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
-        }
-        return ret;
-      }
-      return lastValue + (lastValue - nextLastValue) * (((currentFrame - lastKeyFrame)) / 0.001);
-    }
-      return this.getValueAtTime((((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-
-  }
-
-  function loopIn(type, duration, durationFlag) {
-    if (!this.k) {
-      return this.pv;
-    }
-    type = type ? type.toLowerCase() : '';
-    var currentFrame = this.comp.renderedFrame;
-    var keyframes = this.keyframes;
-    var firstKeyFrame = keyframes[0].t;
-    if (currentFrame >= firstKeyFrame) {
-      return this.pv;
-    }
-    var cycleDuration;
-    var lastKeyFrame;
-    if (!durationFlag) {
-      if (!duration || duration > keyframes.length - 1) {
-        duration = keyframes.length - 1;
-      }
-      lastKeyFrame = keyframes[duration].t;
-      cycleDuration = lastKeyFrame - firstKeyFrame;
-    } else {
-      if (!duration) {
-        cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame);
-      } else {
-        cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
-      }
-      lastKeyFrame = firstKeyFrame + cycleDuration;
-    }
-    var i;
-    var len;
-    var ret;
-    if (type === 'pingpong') {
-      var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
-      if (iterations % 2 === 0) {
-          return this.getValueAtTime((((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-      }
-    } else if (type === 'offset') {
-      var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
-      var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
-      var current = this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration) + firstKeyFrame) / this.comp.globalData.frameRate, 0);
-      var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
-      if (this.pv.length) {
-        ret = new Array(initV.length);
-        len = ret.length;
-        for (i = 0; i < len; i += 1) {
-          ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
-        }
-        return ret;
-      }
-      return current - (endV - initV) * repeats;
-    } else if (type === 'continue') {
-      var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
-      var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
-      if (this.pv.length) {
-        ret = new Array(firstValue.length);
-        len = ret.length;
-        for (i = 0; i < len; i += 1) {
-          ret[i] = firstValue[i] + ((firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame)) / 0.001;
-        }
-        return ret;
-      }
-      return firstValue + ((firstValue - nextFirstValue) * (firstKeyFrame - currentFrame)) / 0.001;
-    }
-      return this.getValueAtTime(((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame))) / this.comp.globalData.frameRate, 0); // eslint-disable-line
-
-  }
-
-  function smooth(width, samples) {
-    if (!this.k) {
-      return this.pv;
-    }
-    width = (width || 0.4) * 0.5;
-    samples = Math.floor(samples || 5);
-    if (samples <= 1) {
-      return this.pv;
-    }
-    var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
-    var initFrame = currentTime - width;
-    var endFrame = currentTime + width;
-    var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1;
-    var i = 0;
-    var j = 0;
-    var value;
-    if (this.pv.length) {
-      value = createTypedArray('float32', this.pv.length);
-    } else {
-      value = 0;
-    }
-    var sampleValue;
-    while (i < samples) {
-      sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
-      if (this.pv.length) {
-        for (j = 0; j < this.pv.length; j += 1) {
-          value[j] += sampleValue[j];
-        }
-      } else {
-        value += sampleValue;
-      }
-      i += 1;
-    }
-    if (this.pv.length) {
-      for (j = 0; j < this.pv.length; j += 1) {
-        value[j] /= samples;
-      }
-    } else {
-      value /= samples;
-    }
-    return value;
-  }
-
-  function getTransformValueAtTime(time) {
-    if (!this._transformCachingAtTime) {
-      this._transformCachingAtTime = {
-        v: new Matrix(),
-      };
-    }
-    /// /
-    var matrix = this._transformCachingAtTime.v;
-    matrix.cloneFromProps(this.pre.props);
-    if (this.appliedTransformations < 1) {
-      var anchor = this.a.getValueAtTime(time);
-      matrix.translate(
-        -anchor[0] * this.a.mult,
-        -anchor[1] * this.a.mult,
-        anchor[2] * this.a.mult
-      );
-    }
-    if (this.appliedTransformations < 2) {
-      var scale = this.s.getValueAtTime(time);
-      matrix.scale(
-        scale[0] * this.s.mult,
-        scale[1] * this.s.mult,
-        scale[2] * this.s.mult
-      );
-    }
-    if (this.sk && this.appliedTransformations < 3) {
-      var skew = this.sk.getValueAtTime(time);
-      var skewAxis = this.sa.getValueAtTime(time);
-      matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
-    }
-    if (this.r && this.appliedTransformations < 4) {
-      var rotation = this.r.getValueAtTime(time);
-      matrix.rotate(-rotation * this.r.mult);
-    } else if (!this.r && this.appliedTransformations < 4) {
-      var rotationZ = this.rz.getValueAtTime(time);
-      var rotationY = this.ry.getValueAtTime(time);
-      var rotationX = this.rx.getValueAtTime(time);
-      var orientation = this.or.getValueAtTime(time);
-      matrix.rotateZ(-rotationZ * this.rz.mult)
-        .rotateY(rotationY * this.ry.mult)
-        .rotateX(rotationX * this.rx.mult)
-        .rotateZ(-orientation[2] * this.or.mult)
-        .rotateY(orientation[1] * this.or.mult)
-        .rotateX(orientation[0] * this.or.mult);
-    }
-    if (this.data.p && this.data.p.s) {
-      var positionX = this.px.getValueAtTime(time);
-      var positionY = this.py.getValueAtTime(time);
-      if (this.data.p.z) {
-        var positionZ = this.pz.getValueAtTime(time);
-        matrix.translate(
-          positionX * this.px.mult,
-          positionY * this.py.mult,
-          -positionZ * this.pz.mult
-        );
-      } else {
-        matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0);
-      }
-    } else {
-      var position = this.p.getValueAtTime(time);
-      matrix.translate(
-        position[0] * this.p.mult,
-        position[1] * this.p.mult,
-        -position[2] * this.p.mult
-      );
-    }
-    return matrix;
-    /// /
-  }
-
-  function getTransformStaticValueAtTime() {
-    return this.v.clone(new Matrix());
-  }
-
-  var getTransformProperty = TransformPropertyFactory.getTransformProperty;
-  TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
-    var prop = getTransformProperty(elem, data, container);
-    if (prop.dynamicProperties.length) {
-      prop.getValueAtTime = getTransformValueAtTime.bind(prop);
-    } else {
-      prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
-    }
-    prop.setGroupProperty = expressionHelpers.setGroupProperty;
-    return prop;
-  };
-
-  var propertyGetProp = PropertyFactory.getProp;
-  PropertyFactory.getProp = function (elem, data, type, mult, container) {
-    var prop = propertyGetProp(elem, data, type, mult, container);
-    // prop.getVelocityAtTime = getVelocityAtTime;
-    // prop.loopOut = loopOut;
-    // prop.loopIn = loopIn;
-    if (prop.kf) {
-      prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
-    } else {
-      prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
-    }
-    prop.setGroupProperty = expressionHelpers.setGroupProperty;
-    prop.loopOut = loopOut;
-    prop.loopIn = loopIn;
-    prop.smooth = smooth;
-    prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop);
-    prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop);
-    prop.numKeys = data.a === 1 ? data.k.length : 0;
-    prop.propertyIndex = data.ix;
-    var value = 0;
-    if (type !== 0) {
-      value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
-    }
-    prop._cachingAtTime = {
-      lastFrame: initialDefaultFrame,
-      lastIndex: 0,
-      value: value,
-    };
-    expressionHelpers.searchExpressions(elem, data, prop);
-    if (prop.k) {
-      container.addDynamicProperty(prop);
-    }
-
-    return prop;
-  };
-
-  function getShapeValueAtTime(frameNum) {
-    // For now this caching object is created only when needed instead of creating it when the shape is initialized.
-    if (!this._cachingAtTime) {
-      this._cachingAtTime = {
-        shapeValue: shapePool.clone(this.pv),
-        lastIndex: 0,
-        lastTime: initialDefaultFrame,
-      };
-    }
-
-    frameNum *= this.elem.globalData.frameRate;
-    frameNum -= this.offsetTime;
-    if (frameNum !== this._cachingAtTime.lastTime) {
-      this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
-      this._cachingAtTime.lastTime = frameNum;
-      this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
-    }
-    return this._cachingAtTime.shapeValue;
-  }
-
-  var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
-  var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
-
-  function ShapeExpressions() {}
-  ShapeExpressions.prototype = {
-    vertices: function (prop, time) {
-      if (this.k) {
-        this.getValue();
-      }
-      var shapePath = this.v;
-      if (time !== undefined) {
-        shapePath = this.getValueAtTime(time, 0);
-      }
-      var i;
-      var len = shapePath._length;
-      var vertices = shapePath[prop];
-      var points = shapePath.v;
-      var arr = createSizedArray(len);
-      for (i = 0; i < len; i += 1) {
-        if (prop === 'i' || prop === 'o') {
-          arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
-        } else {
-          arr[i] = [vertices[i][0], vertices[i][1]];
-        }
-      }
-      return arr;
-    },
-    points: function (time) {
-      return this.vertices('v', time);
-    },
-    inTangents: function (time) {
-      return this.vertices('i', time);
-    },
-    outTangents: function (time) {
-      return this.vertices('o', time);
-    },
-    isClosed: function () {
-      return this.v.c;
-    },
-    pointOnPath: function (perc, time) {
-      var shapePath = this.v;
-      if (time !== undefined) {
-        shapePath = this.getValueAtTime(time, 0);
-      }
-      if (!this._segmentsLength) {
-        this._segmentsLength = bez.getSegmentsLength(shapePath);
-      }
-
-      var segmentsLength = this._segmentsLength;
-      var lengths = segmentsLength.lengths;
-      var lengthPos = segmentsLength.totalLength * perc;
-      var i = 0;
-      var len = lengths.length;
-      var accumulatedLength = 0;
-      var pt;
-      while (i < len) {
-        if (accumulatedLength + lengths[i].addedLength > lengthPos) {
-          var initIndex = i;
-          var endIndex = (shapePath.c && i === len - 1) ? 0 : i + 1;
-          var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength;
-          pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]);
-          break;
-        } else {
-          accumulatedLength += lengths[i].addedLength;
-        }
-        i += 1;
-      }
-      if (!pt) {
-        pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
-      }
-      return pt;
-    },
-    vectorOnPath: function (perc, time, vectorType) {
-      // perc doesn't use triple equality because it can be a Number object as well as a primitive.
-      if (perc == 1) { // eslint-disable-line eqeqeq
-        perc = this.v.c;
-      } else if (perc == 0) { // eslint-disable-line eqeqeq
-        perc = 0.999;
-      }
-      var pt1 = this.pointOnPath(perc, time);
-      var pt2 = this.pointOnPath(perc + 0.001, time);
-      var xLength = pt2[0] - pt1[0];
-      var yLength = pt2[1] - pt1[1];
-      var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
-      if (magnitude === 0) {
-        return [0, 0];
-      }
-      var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
-      return unitVector;
-    },
-    tangentOnPath: function (perc, time) {
-      return this.vectorOnPath(perc, time, 'tangent');
-    },
-    normalOnPath: function (perc, time) {
-      return this.vectorOnPath(perc, time, 'normal');
-    },
-    setGroupProperty: expressionHelpers.setGroupProperty,
-    getValueAtTime: expressionHelpers.getStaticValueAtTime,
-  };
-  extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction);
-  extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction);
-  KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
-  KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
-
-  var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
-  ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
-    var prop = propertyGetShapeProp(elem, data, type, arr, trims);
-    prop.propertyIndex = data.ix;
-    prop.lock = false;
-    if (type === 3) {
-      expressionHelpers.searchExpressions(elem, data.pt, prop);
-    } else if (type === 4) {
-      expressionHelpers.searchExpressions(elem, data.ks, prop);
-    }
-    if (prop.k) {
-      elem.addDynamicProperty(prop);
-    }
-    return prop;
-  };
-}
-
-function initialize$1() {
-  addPropertyDecorator();
-}
-
-function addDecorator() {
-  function searchExpressions() {
-    if (this.data.d.x) {
-      this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this);
-      this.addEffect(this.getExpressionValue.bind(this));
-      return true;
-    }
-    return null;
-  }
-
-  TextProperty.prototype.getExpressionValue = function (currentValue, text) {
-    var newValue = this.calculateExpression(text);
-    if (currentValue.t !== newValue) {
-      var newData = {};
-      this.copyData(newData, currentValue);
-      newData.t = newValue.toString();
-      newData.__complete = false;
-      return newData;
-    }
-    return currentValue;
-  };
-
-  TextProperty.prototype.searchProperty = function () {
-    var isKeyframed = this.searchKeyframes();
-    var hasExpressions = this.searchExpressions();
-    this.kf = isKeyframed || hasExpressions;
-    return this.kf;
-  };
-
-  TextProperty.prototype.searchExpressions = searchExpressions;
-}
-
-function initialize() {
-  addDecorator();
-}
-
-// Registering expression plugin
-setExpressionsPlugin(Expressions);
-initialize$1();
-initialize();
-
-}
-
-export { lottie as default };

+ 0 - 14506
examples/jsm/libs/opentype.module.js

@@ -1,14506 +0,0 @@
-/**
- * https://opentype.js.org v1.3.4 | (c) Frederik De Bleser and other contributors | MIT License | Uses tiny-inflate by Devon Govett and string.prototype.codepointat polyfill by Mathias Bynens
- */
-
-/*! https://mths.be/codepointat v0.2.0 by @mathias */
-if (!String.prototype.codePointAt) {
-	(function() {
-		var defineProperty = (function() {
-			// IE 8 only supports `Object.defineProperty` on DOM elements
-			try {
-				var object = {};
-				var $defineProperty = Object.defineProperty;
-				var result = $defineProperty(object, object, object) && $defineProperty;
-			} catch(error) {}
-			return result;
-		}());
-		var codePointAt = function(position) {
-			if (this == null) {
-				throw TypeError();
-			}
-			var string = String(this);
-			var size = string.length;
-			// `ToInteger`
-			var index = position ? Number(position) : 0;
-			if (index != index) { // better `isNaN`
-				index = 0;
-			}
-			// Account for out-of-bounds indices:
-			if (index < 0 || index >= size) {
-				return undefined;
-			}
-			// Get the first code unit
-			var first = string.charCodeAt(index);
-			var second;
-			if ( // check if it’s the start of a surrogate pair
-				first >= 0xD800 && first <= 0xDBFF && // high surrogate
-				size > index + 1 // there is a next code unit
-			) {
-				second = string.charCodeAt(index + 1);
-				if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
-					// https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
-					return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
-				}
-			}
-			return first;
-		};
-		if (defineProperty) {
-			defineProperty(String.prototype, 'codePointAt', {
-				'value': codePointAt,
-				'configurable': true,
-				'writable': true
-			});
-		} else {
-			String.prototype.codePointAt = codePointAt;
-		}
-	}());
-}
-
-var TINF_OK = 0;
-var TINF_DATA_ERROR = -3;
-
-function Tree() {
-  this.table = new Uint16Array(16);   /* table of code length counts */
-  this.trans = new Uint16Array(288);  /* code -> symbol translation table */
-}
-
-function Data(source, dest) {
-  this.source = source;
-  this.sourceIndex = 0;
-  this.tag = 0;
-  this.bitcount = 0;
-  
-  this.dest = dest;
-  this.destLen = 0;
-  
-  this.ltree = new Tree();  /* dynamic length/symbol tree */
-  this.dtree = new Tree();  /* dynamic distance tree */
-}
-
-/* --------------------------------------------------- *
- * -- uninitialized global data (static structures) -- *
- * --------------------------------------------------- */
-
-var sltree = new Tree();
-var sdtree = new Tree();
-
-/* extra bits and base tables for length codes */
-var length_bits = new Uint8Array(30);
-var length_base = new Uint16Array(30);
-
-/* extra bits and base tables for distance codes */
-var dist_bits = new Uint8Array(30);
-var dist_base = new Uint16Array(30);
-
-/* special ordering of code length codes */
-var clcidx = new Uint8Array([
-  16, 17, 18, 0, 8, 7, 9, 6,
-  10, 5, 11, 4, 12, 3, 13, 2,
-  14, 1, 15
-]);
-
-/* used by tinf_decode_trees, avoids allocations every call */
-var code_tree = new Tree();
-var lengths = new Uint8Array(288 + 32);
-
-/* ----------------------- *
- * -- utility functions -- *
- * ----------------------- */
-
-/* build extra bits and base tables */
-function tinf_build_bits_base(bits, base, delta, first) {
-  var i, sum;
-
-  /* build bits table */
-  for (i = 0; i < delta; ++i) { bits[i] = 0; }
-  for (i = 0; i < 30 - delta; ++i) { bits[i + delta] = i / delta | 0; }
-
-  /* build base table */
-  for (sum = first, i = 0; i < 30; ++i) {
-    base[i] = sum;
-    sum += 1 << bits[i];
-  }
-}
-
-/* build the fixed huffman trees */
-function tinf_build_fixed_trees(lt, dt) {
-  var i;
-
-  /* build fixed length tree */
-  for (i = 0; i < 7; ++i) { lt.table[i] = 0; }
-
-  lt.table[7] = 24;
-  lt.table[8] = 152;
-  lt.table[9] = 112;
-
-  for (i = 0; i < 24; ++i) { lt.trans[i] = 256 + i; }
-  for (i = 0; i < 144; ++i) { lt.trans[24 + i] = i; }
-  for (i = 0; i < 8; ++i) { lt.trans[24 + 144 + i] = 280 + i; }
-  for (i = 0; i < 112; ++i) { lt.trans[24 + 144 + 8 + i] = 144 + i; }
-
-  /* build fixed distance tree */
-  for (i = 0; i < 5; ++i) { dt.table[i] = 0; }
-
-  dt.table[5] = 32;
-
-  for (i = 0; i < 32; ++i) { dt.trans[i] = i; }
-}
-
-/* given an array of code lengths, build a tree */
-var offs = new Uint16Array(16);
-
-function tinf_build_tree(t, lengths, off, num) {
-  var i, sum;
-
-  /* clear code length count table */
-  for (i = 0; i < 16; ++i) { t.table[i] = 0; }
-
-  /* scan symbol lengths, and sum code length counts */
-  for (i = 0; i < num; ++i) { t.table[lengths[off + i]]++; }
-
-  t.table[0] = 0;
-
-  /* compute offset table for distribution sort */
-  for (sum = 0, i = 0; i < 16; ++i) {
-    offs[i] = sum;
-    sum += t.table[i];
-  }
-
-  /* create code->symbol translation table (symbols sorted by code) */
-  for (i = 0; i < num; ++i) {
-    if (lengths[off + i]) { t.trans[offs[lengths[off + i]]++] = i; }
-  }
-}
-
-/* ---------------------- *
- * -- decode functions -- *
- * ---------------------- */
-
-/* get one bit from source stream */
-function tinf_getbit(d) {
-  /* check if tag is empty */
-  if (!d.bitcount--) {
-    /* load next tag */
-    d.tag = d.source[d.sourceIndex++];
-    d.bitcount = 7;
-  }
-
-  /* shift bit out of tag */
-  var bit = d.tag & 1;
-  d.tag >>>= 1;
-
-  return bit;
-}
-
-/* read a num bit value from a stream and add base */
-function tinf_read_bits(d, num, base) {
-  if (!num)
-    { return base; }
-
-  while (d.bitcount < 24) {
-    d.tag |= d.source[d.sourceIndex++] << d.bitcount;
-    d.bitcount += 8;
-  }
-
-  var val = d.tag & (0xffff >>> (16 - num));
-  d.tag >>>= num;
-  d.bitcount -= num;
-  return val + base;
-}
-
-/* given a data stream and a tree, decode a symbol */
-function tinf_decode_symbol(d, t) {
-  while (d.bitcount < 24) {
-    d.tag |= d.source[d.sourceIndex++] << d.bitcount;
-    d.bitcount += 8;
-  }
-  
-  var sum = 0, cur = 0, len = 0;
-  var tag = d.tag;
-
-  /* get more bits while code value is above sum */
-  do {
-    cur = 2 * cur + (tag & 1);
-    tag >>>= 1;
-    ++len;
-
-    sum += t.table[len];
-    cur -= t.table[len];
-  } while (cur >= 0);
-  
-  d.tag = tag;
-  d.bitcount -= len;
-
-  return t.trans[sum + cur];
-}
-
-/* given a data stream, decode dynamic trees from it */
-function tinf_decode_trees(d, lt, dt) {
-  var hlit, hdist, hclen;
-  var i, num, length;
-
-  /* get 5 bits HLIT (257-286) */
-  hlit = tinf_read_bits(d, 5, 257);
-
-  /* get 5 bits HDIST (1-32) */
-  hdist = tinf_read_bits(d, 5, 1);
-
-  /* get 4 bits HCLEN (4-19) */
-  hclen = tinf_read_bits(d, 4, 4);
-
-  for (i = 0; i < 19; ++i) { lengths[i] = 0; }
-
-  /* read code lengths for code length alphabet */
-  for (i = 0; i < hclen; ++i) {
-    /* get 3 bits code length (0-7) */
-    var clen = tinf_read_bits(d, 3, 0);
-    lengths[clcidx[i]] = clen;
-  }
-
-  /* build code length tree */
-  tinf_build_tree(code_tree, lengths, 0, 19);
-
-  /* decode code lengths for the dynamic trees */
-  for (num = 0; num < hlit + hdist;) {
-    var sym = tinf_decode_symbol(d, code_tree);
-
-    switch (sym) {
-      case 16:
-        /* copy previous code length 3-6 times (read 2 bits) */
-        var prev = lengths[num - 1];
-        for (length = tinf_read_bits(d, 2, 3); length; --length) {
-          lengths[num++] = prev;
-        }
-        break;
-      case 17:
-        /* repeat code length 0 for 3-10 times (read 3 bits) */
-        for (length = tinf_read_bits(d, 3, 3); length; --length) {
-          lengths[num++] = 0;
-        }
-        break;
-      case 18:
-        /* repeat code length 0 for 11-138 times (read 7 bits) */
-        for (length = tinf_read_bits(d, 7, 11); length; --length) {
-          lengths[num++] = 0;
-        }
-        break;
-      default:
-        /* values 0-15 represent the actual code lengths */
-        lengths[num++] = sym;
-        break;
-    }
-  }
-
-  /* build dynamic trees */
-  tinf_build_tree(lt, lengths, 0, hlit);
-  tinf_build_tree(dt, lengths, hlit, hdist);
-}
-
-/* ----------------------------- *
- * -- block inflate functions -- *
- * ----------------------------- */
-
-/* given a stream and two trees, inflate a block of data */
-function tinf_inflate_block_data(d, lt, dt) {
-  while (1) {
-    var sym = tinf_decode_symbol(d, lt);
-
-    /* check for end of block */
-    if (sym === 256) {
-      return TINF_OK;
-    }
-
-    if (sym < 256) {
-      d.dest[d.destLen++] = sym;
-    } else {
-      var length, dist, offs;
-      var i;
-
-      sym -= 257;
-
-      /* possibly get more bits from length code */
-      length = tinf_read_bits(d, length_bits[sym], length_base[sym]);
-
-      dist = tinf_decode_symbol(d, dt);
-
-      /* possibly get more bits from distance code */
-      offs = d.destLen - tinf_read_bits(d, dist_bits[dist], dist_base[dist]);
-
-      /* copy match */
-      for (i = offs; i < offs + length; ++i) {
-        d.dest[d.destLen++] = d.dest[i];
-      }
-    }
-  }
-}
-
-/* inflate an uncompressed block of data */
-function tinf_inflate_uncompressed_block(d) {
-  var length, invlength;
-  var i;
-  
-  /* unread from bitbuffer */
-  while (d.bitcount > 8) {
-    d.sourceIndex--;
-    d.bitcount -= 8;
-  }
-
-  /* get length */
-  length = d.source[d.sourceIndex + 1];
-  length = 256 * length + d.source[d.sourceIndex];
-
-  /* get one's complement of length */
-  invlength = d.source[d.sourceIndex + 3];
-  invlength = 256 * invlength + d.source[d.sourceIndex + 2];
-
-  /* check length */
-  if (length !== (~invlength & 0x0000ffff))
-    { return TINF_DATA_ERROR; }
-
-  d.sourceIndex += 4;
-
-  /* copy block */
-  for (i = length; i; --i)
-    { d.dest[d.destLen++] = d.source[d.sourceIndex++]; }
-
-  /* make sure we start next block on a byte boundary */
-  d.bitcount = 0;
-
-  return TINF_OK;
-}
-
-/* inflate stream from source to dest */
-function tinf_uncompress(source, dest) {
-  var d = new Data(source, dest);
-  var bfinal, btype, res;
-
-  do {
-    /* read final block flag */
-    bfinal = tinf_getbit(d);
-
-    /* read block type (2 bits) */
-    btype = tinf_read_bits(d, 2, 0);
-
-    /* decompress block */
-    switch (btype) {
-      case 0:
-        /* decompress uncompressed block */
-        res = tinf_inflate_uncompressed_block(d);
-        break;
-      case 1:
-        /* decompress block with fixed huffman trees */
-        res = tinf_inflate_block_data(d, sltree, sdtree);
-        break;
-      case 2:
-        /* decompress block with dynamic huffman trees */
-        tinf_decode_trees(d, d.ltree, d.dtree);
-        res = tinf_inflate_block_data(d, d.ltree, d.dtree);
-        break;
-      default:
-        res = TINF_DATA_ERROR;
-    }
-
-    if (res !== TINF_OK)
-      { throw new Error('Data error'); }
-
-  } while (!bfinal);
-
-  if (d.destLen < d.dest.length) {
-    if (typeof d.dest.slice === 'function')
-      { return d.dest.slice(0, d.destLen); }
-    else
-      { return d.dest.subarray(0, d.destLen); }
-  }
-  
-  return d.dest;
-}
-
-/* -------------------- *
- * -- initialization -- *
- * -------------------- */
-
-/* build fixed huffman trees */
-tinf_build_fixed_trees(sltree, sdtree);
-
-/* build extra bits and base tables */
-tinf_build_bits_base(length_bits, length_base, 4, 3);
-tinf_build_bits_base(dist_bits, dist_base, 2, 1);
-
-/* fix a special case */
-length_bits[28] = 0;
-length_base[28] = 258;
-
-var tinyInflate = tinf_uncompress;
-
-// The Bounding Box object
-
-function derive(v0, v1, v2, v3, t) {
-    return Math.pow(1 - t, 3) * v0 +
-        3 * Math.pow(1 - t, 2) * t * v1 +
-        3 * (1 - t) * Math.pow(t, 2) * v2 +
-        Math.pow(t, 3) * v3;
-}
-/**
- * A bounding box is an enclosing box that describes the smallest measure within which all the points lie.
- * It is used to calculate the bounding box of a glyph or text path.
- *
- * On initialization, x1/y1/x2/y2 will be NaN. Check if the bounding box is empty using `isEmpty()`.
- *
- * @exports opentype.BoundingBox
- * @class
- * @constructor
- */
-function BoundingBox() {
-    this.x1 = Number.NaN;
-    this.y1 = Number.NaN;
-    this.x2 = Number.NaN;
-    this.y2 = Number.NaN;
-}
-
-/**
- * Returns true if the bounding box is empty, that is, no points have been added to the box yet.
- */
-BoundingBox.prototype.isEmpty = function() {
-    return isNaN(this.x1) || isNaN(this.y1) || isNaN(this.x2) || isNaN(this.y2);
-};
-
-/**
- * Add the point to the bounding box.
- * The x1/y1/x2/y2 coordinates of the bounding box will now encompass the given point.
- * @param {number} x - The X coordinate of the point.
- * @param {number} y - The Y coordinate of the point.
- */
-BoundingBox.prototype.addPoint = function(x, y) {
-    if (typeof x === 'number') {
-        if (isNaN(this.x1) || isNaN(this.x2)) {
-            this.x1 = x;
-            this.x2 = x;
-        }
-        if (x < this.x1) {
-            this.x1 = x;
-        }
-        if (x > this.x2) {
-            this.x2 = x;
-        }
-    }
-    if (typeof y === 'number') {
-        if (isNaN(this.y1) || isNaN(this.y2)) {
-            this.y1 = y;
-            this.y2 = y;
-        }
-        if (y < this.y1) {
-            this.y1 = y;
-        }
-        if (y > this.y2) {
-            this.y2 = y;
-        }
-    }
-};
-
-/**
- * Add a X coordinate to the bounding box.
- * This extends the bounding box to include the X coordinate.
- * This function is used internally inside of addBezier.
- * @param {number} x - The X coordinate of the point.
- */
-BoundingBox.prototype.addX = function(x) {
-    this.addPoint(x, null);
-};
-
-/**
- * Add a Y coordinate to the bounding box.
- * This extends the bounding box to include the Y coordinate.
- * This function is used internally inside of addBezier.
- * @param {number} y - The Y coordinate of the point.
- */
-BoundingBox.prototype.addY = function(y) {
-    this.addPoint(null, y);
-};
-
-/**
- * Add a Bézier curve to the bounding box.
- * This extends the bounding box to include the entire Bézier.
- * @param {number} x0 - The starting X coordinate.
- * @param {number} y0 - The starting Y coordinate.
- * @param {number} x1 - The X coordinate of the first control point.
- * @param {number} y1 - The Y coordinate of the first control point.
- * @param {number} x2 - The X coordinate of the second control point.
- * @param {number} y2 - The Y coordinate of the second control point.
- * @param {number} x - The ending X coordinate.
- * @param {number} y - The ending Y coordinate.
- */
-BoundingBox.prototype.addBezier = function(x0, y0, x1, y1, x2, y2, x, y) {
-    // This code is based on http://nishiohirokazu.blogspot.com/2009/06/how-to-calculate-bezier-curves-bounding.html
-    // and https://github.com/icons8/svg-path-bounding-box
-
-    var p0 = [x0, y0];
-    var p1 = [x1, y1];
-    var p2 = [x2, y2];
-    var p3 = [x, y];
-
-    this.addPoint(x0, y0);
-    this.addPoint(x, y);
-
-    for (var i = 0; i <= 1; i++) {
-        var b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
-        var a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
-        var c = 3 * p1[i] - 3 * p0[i];
-
-        if (a === 0) {
-            if (b === 0) { continue; }
-            var t = -c / b;
-            if (0 < t && t < 1) {
-                if (i === 0) { this.addX(derive(p0[i], p1[i], p2[i], p3[i], t)); }
-                if (i === 1) { this.addY(derive(p0[i], p1[i], p2[i], p3[i], t)); }
-            }
-            continue;
-        }
-
-        var b2ac = Math.pow(b, 2) - 4 * c * a;
-        if (b2ac < 0) { continue; }
-        var t1 = (-b + Math.sqrt(b2ac)) / (2 * a);
-        if (0 < t1 && t1 < 1) {
-            if (i === 0) { this.addX(derive(p0[i], p1[i], p2[i], p3[i], t1)); }
-            if (i === 1) { this.addY(derive(p0[i], p1[i], p2[i], p3[i], t1)); }
-        }
-        var t2 = (-b - Math.sqrt(b2ac)) / (2 * a);
-        if (0 < t2 && t2 < 1) {
-            if (i === 0) { this.addX(derive(p0[i], p1[i], p2[i], p3[i], t2)); }
-            if (i === 1) { this.addY(derive(p0[i], p1[i], p2[i], p3[i], t2)); }
-        }
-    }
-};
-
-/**
- * Add a quadratic curve to the bounding box.
- * This extends the bounding box to include the entire quadratic curve.
- * @param {number} x0 - The starting X coordinate.
- * @param {number} y0 - The starting Y coordinate.
- * @param {number} x1 - The X coordinate of the control point.
- * @param {number} y1 - The Y coordinate of the control point.
- * @param {number} x - The ending X coordinate.
- * @param {number} y - The ending Y coordinate.
- */
-BoundingBox.prototype.addQuad = function(x0, y0, x1, y1, x, y) {
-    var cp1x = x0 + 2 / 3 * (x1 - x0);
-    var cp1y = y0 + 2 / 3 * (y1 - y0);
-    var cp2x = cp1x + 1 / 3 * (x - x0);
-    var cp2y = cp1y + 1 / 3 * (y - y0);
-    this.addBezier(x0, y0, cp1x, cp1y, cp2x, cp2y, x, y);
-};
-
-// Geometric objects
-
-/**
- * A bézier path containing a set of path commands similar to a SVG path.
- * Paths can be drawn on a context using `draw`.
- * @exports opentype.Path
- * @class
- * @constructor
- */
-function Path() {
-    this.commands = [];
-    this.fill = 'black';
-    this.stroke = null;
-    this.strokeWidth = 1;
-}
-
-/**
- * @param  {number} x
- * @param  {number} y
- */
-Path.prototype.moveTo = function(x, y) {
-    this.commands.push({
-        type: 'M',
-        x: x,
-        y: y
-    });
-};
-
-/**
- * @param  {number} x
- * @param  {number} y
- */
-Path.prototype.lineTo = function(x, y) {
-    this.commands.push({
-        type: 'L',
-        x: x,
-        y: y
-    });
-};
-
-/**
- * Draws cubic curve
- * @function
- * curveTo
- * @memberof opentype.Path.prototype
- * @param  {number} x1 - x of control 1
- * @param  {number} y1 - y of control 1
- * @param  {number} x2 - x of control 2
- * @param  {number} y2 - y of control 2
- * @param  {number} x - x of path point
- * @param  {number} y - y of path point
- */
-
-/**
- * Draws cubic curve
- * @function
- * bezierCurveTo
- * @memberof opentype.Path.prototype
- * @param  {number} x1 - x of control 1
- * @param  {number} y1 - y of control 1
- * @param  {number} x2 - x of control 2
- * @param  {number} y2 - y of control 2
- * @param  {number} x - x of path point
- * @param  {number} y - y of path point
- * @see curveTo
- */
-Path.prototype.curveTo = Path.prototype.bezierCurveTo = function(x1, y1, x2, y2, x, y) {
-    this.commands.push({
-        type: 'C',
-        x1: x1,
-        y1: y1,
-        x2: x2,
-        y2: y2,
-        x: x,
-        y: y
-    });
-};
-
-/**
- * Draws quadratic curve
- * @function
- * quadraticCurveTo
- * @memberof opentype.Path.prototype
- * @param  {number} x1 - x of control
- * @param  {number} y1 - y of control
- * @param  {number} x - x of path point
- * @param  {number} y - y of path point
- */
-
-/**
- * Draws quadratic curve
- * @function
- * quadTo
- * @memberof opentype.Path.prototype
- * @param  {number} x1 - x of control
- * @param  {number} y1 - y of control
- * @param  {number} x - x of path point
- * @param  {number} y - y of path point
- */
-Path.prototype.quadTo = Path.prototype.quadraticCurveTo = function(x1, y1, x, y) {
-    this.commands.push({
-        type: 'Q',
-        x1: x1,
-        y1: y1,
-        x: x,
-        y: y
-    });
-};
-
-/**
- * Closes the path
- * @function closePath
- * @memberof opentype.Path.prototype
- */
-
-/**
- * Close the path
- * @function close
- * @memberof opentype.Path.prototype
- */
-Path.prototype.close = Path.prototype.closePath = function() {
-    this.commands.push({
-        type: 'Z'
-    });
-};
-
-/**
- * Add the given path or list of commands to the commands of this path.
- * @param  {Array} pathOrCommands - another opentype.Path, an opentype.BoundingBox, or an array of commands.
- */
-Path.prototype.extend = function(pathOrCommands) {
-    if (pathOrCommands.commands) {
-        pathOrCommands = pathOrCommands.commands;
-    } else if (pathOrCommands instanceof BoundingBox) {
-        var box = pathOrCommands;
-        this.moveTo(box.x1, box.y1);
-        this.lineTo(box.x2, box.y1);
-        this.lineTo(box.x2, box.y2);
-        this.lineTo(box.x1, box.y2);
-        this.close();
-        return;
-    }
-
-    Array.prototype.push.apply(this.commands, pathOrCommands);
-};
-
-/**
- * Calculate the bounding box of the path.
- * @returns {opentype.BoundingBox}
- */
-Path.prototype.getBoundingBox = function() {
-    var box = new BoundingBox();
-
-    var startX = 0;
-    var startY = 0;
-    var prevX = 0;
-    var prevY = 0;
-    for (var i = 0; i < this.commands.length; i++) {
-        var cmd = this.commands[i];
-        switch (cmd.type) {
-            case 'M':
-                box.addPoint(cmd.x, cmd.y);
-                startX = prevX = cmd.x;
-                startY = prevY = cmd.y;
-                break;
-            case 'L':
-                box.addPoint(cmd.x, cmd.y);
-                prevX = cmd.x;
-                prevY = cmd.y;
-                break;
-            case 'Q':
-                box.addQuad(prevX, prevY, cmd.x1, cmd.y1, cmd.x, cmd.y);
-                prevX = cmd.x;
-                prevY = cmd.y;
-                break;
-            case 'C':
-                box.addBezier(prevX, prevY, cmd.x1, cmd.y1, cmd.x2, cmd.y2, cmd.x, cmd.y);
-                prevX = cmd.x;
-                prevY = cmd.y;
-                break;
-            case 'Z':
-                prevX = startX;
-                prevY = startY;
-                break;
-            default:
-                throw new Error('Unexpected path command ' + cmd.type);
-        }
-    }
-    if (box.isEmpty()) {
-        box.addPoint(0, 0);
-    }
-    return box;
-};
-
-/**
- * Draw the path to a 2D context.
- * @param {CanvasRenderingContext2D} ctx - A 2D drawing context.
- */
-Path.prototype.draw = function(ctx) {
-    ctx.beginPath();
-    for (var i = 0; i < this.commands.length; i += 1) {
-        var cmd = this.commands[i];
-        if (cmd.type === 'M') {
-            ctx.moveTo(cmd.x, cmd.y);
-        } else if (cmd.type === 'L') {
-            ctx.lineTo(cmd.x, cmd.y);
-        } else if (cmd.type === 'C') {
-            ctx.bezierCurveTo(cmd.x1, cmd.y1, cmd.x2, cmd.y2, cmd.x, cmd.y);
-        } else if (cmd.type === 'Q') {
-            ctx.quadraticCurveTo(cmd.x1, cmd.y1, cmd.x, cmd.y);
-        } else if (cmd.type === 'Z') {
-            ctx.closePath();
-        }
-    }
-
-    if (this.fill) {
-        ctx.fillStyle = this.fill;
-        ctx.fill();
-    }
-
-    if (this.stroke) {
-        ctx.strokeStyle = this.stroke;
-        ctx.lineWidth = this.strokeWidth;
-        ctx.stroke();
-    }
-};
-
-/**
- * Convert the Path to a string of path data instructions
- * See http://www.w3.org/TR/SVG/paths.html#PathData
- * @param  {number} [decimalPlaces=2] - The amount of decimal places for floating-point values
- * @return {string}
- */
-Path.prototype.toPathData = function(decimalPlaces) {
-    decimalPlaces = decimalPlaces !== undefined ? decimalPlaces : 2;
-
-    function floatToString(v) {
-        if (Math.round(v) === v) {
-            return '' + Math.round(v);
-        } else {
-            return v.toFixed(decimalPlaces);
-        }
-    }
-
-    function packValues() {
-        var arguments$1 = arguments;
-
-        var s = '';
-        for (var i = 0; i < arguments.length; i += 1) {
-            var v = arguments$1[i];
-            if (v >= 0 && i > 0) {
-                s += ' ';
-            }
-
-            s += floatToString(v);
-        }
-
-        return s;
-    }
-
-    var d = '';
-    for (var i = 0; i < this.commands.length; i += 1) {
-        var cmd = this.commands[i];
-        if (cmd.type === 'M') {
-            d += 'M' + packValues(cmd.x, cmd.y);
-        } else if (cmd.type === 'L') {
-            d += 'L' + packValues(cmd.x, cmd.y);
-        } else if (cmd.type === 'C') {
-            d += 'C' + packValues(cmd.x1, cmd.y1, cmd.x2, cmd.y2, cmd.x, cmd.y);
-        } else if (cmd.type === 'Q') {
-            d += 'Q' + packValues(cmd.x1, cmd.y1, cmd.x, cmd.y);
-        } else if (cmd.type === 'Z') {
-            d += 'Z';
-        }
-    }
-
-    return d;
-};
-
-/**
- * Convert the path to an SVG <path> element, as a string.
- * @param  {number} [decimalPlaces=2] - The amount of decimal places for floating-point values
- * @return {string}
- */
-Path.prototype.toSVG = function(decimalPlaces) {
-    var svg = '<path d="';
-    svg += this.toPathData(decimalPlaces);
-    svg += '"';
-    if (this.fill && this.fill !== 'black') {
-        if (this.fill === null) {
-            svg += ' fill="none"';
-        } else {
-            svg += ' fill="' + this.fill + '"';
-        }
-    }
-
-    if (this.stroke) {
-        svg += ' stroke="' + this.stroke + '" stroke-width="' + this.strokeWidth + '"';
-    }
-
-    svg += '/>';
-    return svg;
-};
-
-/**
- * Convert the path to a DOM element.
- * @param  {number} [decimalPlaces=2] - The amount of decimal places for floating-point values
- * @return {SVGPathElement}
- */
-Path.prototype.toDOMElement = function(decimalPlaces) {
-    var temporaryPath = this.toPathData(decimalPlaces);
-    var newPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
-
-    newPath.setAttribute('d', temporaryPath);
-
-    return newPath;
-};
-
-// Run-time checking of preconditions.
-
-function fail(message) {
-    throw new Error(message);
-}
-
-// Precondition function that checks if the given predicate is true.
-// If not, it will throw an error.
-function argument(predicate, message) {
-    if (!predicate) {
-        fail(message);
-    }
-}
-var check = { fail: fail, argument: argument, assert: argument };
-
-// Data types used in the OpenType font file.
-
-var LIMIT16 = 32768; // The limit at which a 16-bit number switches signs == 2^15
-var LIMIT32 = 2147483648; // The limit at which a 32-bit number switches signs == 2 ^ 31
-
-/**
- * @exports opentype.decode
- * @class
- */
-var decode = {};
-/**
- * @exports opentype.encode
- * @class
- */
-var encode = {};
-/**
- * @exports opentype.sizeOf
- * @class
- */
-var sizeOf = {};
-
-// Return a function that always returns the same value.
-function constant(v) {
-    return function() {
-        return v;
-    };
-}
-
-// OpenType data types //////////////////////////////////////////////////////
-
-/**
- * Convert an 8-bit unsigned integer to a list of 1 byte.
- * @param {number}
- * @returns {Array}
- */
-encode.BYTE = function(v) {
-    check.argument(v >= 0 && v <= 255, 'Byte value should be between 0 and 255.');
-    return [v];
-};
-/**
- * @constant
- * @type {number}
- */
-sizeOf.BYTE = constant(1);
-
-/**
- * Convert a 8-bit signed integer to a list of 1 byte.
- * @param {string}
- * @returns {Array}
- */
-encode.CHAR = function(v) {
-    return [v.charCodeAt(0)];
-};
-
-/**
- * @constant
- * @type {number}
- */
-sizeOf.CHAR = constant(1);
-
-/**
- * Convert an ASCII string to a list of bytes.
- * @param {string}
- * @returns {Array}
- */
-encode.CHARARRAY = function(v) {
-    if (typeof v === 'undefined') {
-        v = '';
-        console.warn('Undefined CHARARRAY encountered and treated as an empty string. This is probably caused by a missing glyph name.');
-    }
-    var b = [];
-    for (var i = 0; i < v.length; i += 1) {
-        b[i] = v.charCodeAt(i);
-    }
-
-    return b;
-};
-
-/**
- * @param {Array}
- * @returns {number}
- */
-sizeOf.CHARARRAY = function(v) {
-    if (typeof v === 'undefined') {
-        return 0;
-    }
-    return v.length;
-};
-
-/**
- * Convert a 16-bit unsigned integer to a list of 2 bytes.
- * @param {number}
- * @returns {Array}
- */
-encode.USHORT = function(v) {
-    return [(v >> 8) & 0xFF, v & 0xFF];
-};
-
-/**
- * @constant
- * @type {number}
- */
-sizeOf.USHORT = constant(2);
-
-/**
- * Convert a 16-bit signed integer to a list of 2 bytes.
- * @param {number}
- * @returns {Array}
- */
-encode.SHORT = function(v) {
-    // Two's complement
-    if (v >= LIMIT16) {
-        v = -(2 * LIMIT16 - v);
-    }
-
-    return [(v >> 8) & 0xFF, v & 0xFF];
-};
-
-/**
- * @constant
- * @type {number}
- */
-sizeOf.SHORT = constant(2);
-
-/**
- * Convert a 24-bit unsigned integer to a list of 3 bytes.
- * @param {number}
- * @returns {Array}
- */
-encode.UINT24 = function(v) {
-    return [(v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF];
-};
-
-/**
- * @constant
- * @type {number}
- */
-sizeOf.UINT24 = constant(3);
-
-/**
- * Convert a 32-bit unsigned integer to a list of 4 bytes.
- * @param {number}
- * @returns {Array}
- */
-encode.ULONG = function(v) {
-    return [(v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF];
-};
-
-/**
- * @constant
- * @type {number}
- */
-sizeOf.ULONG = constant(4);
-
-/**
- * Convert a 32-bit unsigned integer to a list of 4 bytes.
- * @param {number}
- * @returns {Array}
- */
-encode.LONG = function(v) {
-    // Two's complement
-    if (v >= LIMIT32) {
-        v = -(2 * LIMIT32 - v);
-    }
-
-    return [(v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF];
-};
-
-/**
- * @constant
- * @type {number}
- */
-sizeOf.LONG = constant(4);
-
-encode.FIXED = encode.ULONG;
-sizeOf.FIXED = sizeOf.ULONG;
-
-encode.FWORD = encode.SHORT;
-sizeOf.FWORD = sizeOf.SHORT;
-
-encode.UFWORD = encode.USHORT;
-sizeOf.UFWORD = sizeOf.USHORT;
-
-/**
- * Convert a 32-bit Apple Mac timestamp integer to a list of 8 bytes, 64-bit timestamp.
- * @param {number}
- * @returns {Array}
- */
-encode.LONGDATETIME = function(v) {
-    return [0, 0, 0, 0, (v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF];
-};
-
-/**
- * @constant
- * @type {number}
- */
-sizeOf.LONGDATETIME = constant(8);
-
-/**
- * Convert a 4-char tag to a list of 4 bytes.
- * @param {string}
- * @returns {Array}
- */
-encode.TAG = function(v) {
-    check.argument(v.length === 4, 'Tag should be exactly 4 ASCII characters.');
-    return [v.charCodeAt(0),
-            v.charCodeAt(1),
-            v.charCodeAt(2),
-            v.charCodeAt(3)];
-};
-
-/**
- * @constant
- * @type {number}
- */
-sizeOf.TAG = constant(4);
-
-// CFF data types ///////////////////////////////////////////////////////////
-
-encode.Card8 = encode.BYTE;
-sizeOf.Card8 = sizeOf.BYTE;
-
-encode.Card16 = encode.USHORT;
-sizeOf.Card16 = sizeOf.USHORT;
-
-encode.OffSize = encode.BYTE;
-sizeOf.OffSize = sizeOf.BYTE;
-
-encode.SID = encode.USHORT;
-sizeOf.SID = sizeOf.USHORT;
-
-// Convert a numeric operand or charstring number to a variable-size list of bytes.
-/**
- * Convert a numeric operand or charstring number to a variable-size list of bytes.
- * @param {number}
- * @returns {Array}
- */
-encode.NUMBER = function(v) {
-    if (v >= -107 && v <= 107) {
-        return [v + 139];
-    } else if (v >= 108 && v <= 1131) {
-        v = v - 108;
-        return [(v >> 8) + 247, v & 0xFF];
-    } else if (v >= -1131 && v <= -108) {
-        v = -v - 108;
-        return [(v >> 8) + 251, v & 0xFF];
-    } else if (v >= -32768 && v <= 32767) {
-        return encode.NUMBER16(v);
-    } else {
-        return encode.NUMBER32(v);
-    }
-};
-
-/**
- * @param {number}
- * @returns {number}
- */
-sizeOf.NUMBER = function(v) {
-    return encode.NUMBER(v).length;
-};
-
-/**
- * Convert a signed number between -32768 and +32767 to a three-byte value.
- * This ensures we always use three bytes, but is not the most compact format.
- * @param {number}
- * @returns {Array}
- */
-encode.NUMBER16 = function(v) {
-    return [28, (v >> 8) & 0xFF, v & 0xFF];
-};
-
-/**
- * @constant
- * @type {number}
- */
-sizeOf.NUMBER16 = constant(3);
-
-/**
- * Convert a signed number between -(2^31) and +(2^31-1) to a five-byte value.
- * This is useful if you want to be sure you always use four bytes,
- * at the expense of wasting a few bytes for smaller numbers.
- * @param {number}
- * @returns {Array}
- */
-encode.NUMBER32 = function(v) {
-    return [29, (v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF];
-};
-
-/**
- * @constant
- * @type {number}
- */
-sizeOf.NUMBER32 = constant(5);
-
-/**
- * @param {number}
- * @returns {Array}
- */
-encode.REAL = function(v) {
-    var value = v.toString();
-
-    // Some numbers use an epsilon to encode the value. (e.g. JavaScript will store 0.0000001 as 1e-7)
-    // This code converts it back to a number without the epsilon.
-    var m = /\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(value);
-    if (m) {
-        var epsilon = parseFloat('1e' + ((m[2] ? +m[2] : 0) + m[1].length));
-        value = (Math.round(v * epsilon) / epsilon).toString();
-    }
-
-    var nibbles = '';
-    for (var i = 0, ii = value.length; i < ii; i += 1) {
-        var c = value[i];
-        if (c === 'e') {
-            nibbles += value[++i] === '-' ? 'c' : 'b';
-        } else if (c === '.') {
-            nibbles += 'a';
-        } else if (c === '-') {
-            nibbles += 'e';
-        } else {
-            nibbles += c;
-        }
-    }
-
-    nibbles += (nibbles.length & 1) ? 'f' : 'ff';
-    var out = [30];
-    for (var i$1 = 0, ii$1 = nibbles.length; i$1 < ii$1; i$1 += 2) {
-        out.push(parseInt(nibbles.substr(i$1, 2), 16));
-    }
-
-    return out;
-};
-
-/**
- * @param {number}
- * @returns {number}
- */
-sizeOf.REAL = function(v) {
-    return encode.REAL(v).length;
-};
-
-encode.NAME = encode.CHARARRAY;
-sizeOf.NAME = sizeOf.CHARARRAY;
-
-encode.STRING = encode.CHARARRAY;
-sizeOf.STRING = sizeOf.CHARARRAY;
-
-/**
- * @param {DataView} data
- * @param {number} offset
- * @param {number} numBytes
- * @returns {string}
- */
-decode.UTF8 = function(data, offset, numBytes) {
-    var codePoints = [];
-    var numChars = numBytes;
-    for (var j = 0; j < numChars; j++, offset += 1) {
-        codePoints[j] = data.getUint8(offset);
-    }
-
-    return String.fromCharCode.apply(null, codePoints);
-};
-
-/**
- * @param {DataView} data
- * @param {number} offset
- * @param {number} numBytes
- * @returns {string}
- */
-decode.UTF16 = function(data, offset, numBytes) {
-    var codePoints = [];
-    var numChars = numBytes / 2;
-    for (var j = 0; j < numChars; j++, offset += 2) {
-        codePoints[j] = data.getUint16(offset);
-    }
-
-    return String.fromCharCode.apply(null, codePoints);
-};
-
-/**
- * Convert a JavaScript string to UTF16-BE.
- * @param {string}
- * @returns {Array}
- */
-encode.UTF16 = function(v) {
-    var b = [];
-    for (var i = 0; i < v.length; i += 1) {
-        var codepoint = v.charCodeAt(i);
-        b[b.length] = (codepoint >> 8) & 0xFF;
-        b[b.length] = codepoint & 0xFF;
-    }
-
-    return b;
-};
-
-/**
- * @param {string}
- * @returns {number}
- */
-sizeOf.UTF16 = function(v) {
-    return v.length * 2;
-};
-
-// Data for converting old eight-bit Macintosh encodings to Unicode.
-// This representation is optimized for decoding; encoding is slower
-// and needs more memory. The assumption is that all opentype.js users
-// want to open fonts, but saving a font will be comparatively rare
-// so it can be more expensive. Keyed by IANA character set name.
-//
-// Python script for generating these strings:
-//
-//     s = u''.join([chr(c).decode('mac_greek') for c in range(128, 256)])
-//     print(s.encode('utf-8'))
-/**
- * @private
- */
-var eightBitMacEncodings = {
-    'x-mac-croatian':  // Python: 'mac_croatian'
-    'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø' +
-    '¿¡¬√ƒ≈ƫȅ ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ',
-    'x-mac-cyrillic':  // Python: 'mac_cyrillic'
-    'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњ' +
-    'јЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю',
-    'x-mac-gaelic': // http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/GAELIC.TXT
-    'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæø' +
-    'ṁṖṗɼƒſṠ«»… ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ',
-    'x-mac-greek':  // Python: 'mac_greek'
-    'Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩ' +
-    'άΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ\u00AD',
-    'x-mac-icelandic':  // Python: 'mac_iceland'
-    'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüݰ¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø' +
-    '¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ',
-    'x-mac-inuit': // http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/INUIT.TXT
-    'ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗ' +
-    'ᓘᓚᓛᓪᔨᔩᔪᔫᔭ… ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł',
-    'x-mac-ce':  // Python: 'mac_latin2'
-    'ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅ' +
-    'ņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ',
-    macintosh:  // Python: 'mac_roman'
-    'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø' +
-    '¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ',
-    'x-mac-romanian':  // Python: 'mac_romanian'
-    'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș' +
-    '¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ',
-    'x-mac-turkish':  // Python: 'mac_turkish'
-    'ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø' +
-    '¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ'
-};
-
-/**
- * Decodes an old-style Macintosh string. Returns either a Unicode JavaScript
- * string, or 'undefined' if the encoding is unsupported. For example, we do
- * not support Chinese, Japanese or Korean because these would need large
- * mapping tables.
- * @param {DataView} dataView
- * @param {number} offset
- * @param {number} dataLength
- * @param {string} encoding
- * @returns {string}
- */
-decode.MACSTRING = function(dataView, offset, dataLength, encoding) {
-    var table = eightBitMacEncodings[encoding];
-    if (table === undefined) {
-        return undefined;
-    }
-
-    var result = '';
-    for (var i = 0; i < dataLength; i++) {
-        var c = dataView.getUint8(offset + i);
-        // In all eight-bit Mac encodings, the characters 0x00..0x7F are
-        // mapped to U+0000..U+007F; we only need to look up the others.
-        if (c <= 0x7F) {
-            result += String.fromCharCode(c);
-        } else {
-            result += table[c & 0x7F];
-        }
-    }
-
-    return result;
-};
-
-// Helper function for encode.MACSTRING. Returns a dictionary for mapping
-// Unicode character codes to their 8-bit MacOS equivalent. This table
-// is not exactly a super cheap data structure, but we do not care because
-// encoding Macintosh strings is only rarely needed in typical applications.
-var macEncodingTableCache = typeof WeakMap === 'function' && new WeakMap();
-var macEncodingCacheKeys;
-var getMacEncodingTable = function (encoding) {
-    // Since we use encoding as a cache key for WeakMap, it has to be
-    // a String object and not a literal. And at least on NodeJS 2.10.1,
-    // WeakMap requires that the same String instance is passed for cache hits.
-    if (!macEncodingCacheKeys) {
-        macEncodingCacheKeys = {};
-        for (var e in eightBitMacEncodings) {
-            /*jshint -W053 */  // Suppress "Do not use String as a constructor."
-            macEncodingCacheKeys[e] = new String(e);
-        }
-    }
-
-    var cacheKey = macEncodingCacheKeys[encoding];
-    if (cacheKey === undefined) {
-        return undefined;
-    }
-
-    // We can't do "if (cache.has(key)) {return cache.get(key)}" here:
-    // since garbage collection may run at any time, it could also kick in
-    // between the calls to cache.has() and cache.get(). In that case,
-    // we would return 'undefined' even though we do support the encoding.
-    if (macEncodingTableCache) {
-        var cachedTable = macEncodingTableCache.get(cacheKey);
-        if (cachedTable !== undefined) {
-            return cachedTable;
-        }
-    }
-
-    var decodingTable = eightBitMacEncodings[encoding];
-    if (decodingTable === undefined) {
-        return undefined;
-    }
-
-    var encodingTable = {};
-    for (var i = 0; i < decodingTable.length; i++) {
-        encodingTable[decodingTable.charCodeAt(i)] = i + 0x80;
-    }
-
-    if (macEncodingTableCache) {
-        macEncodingTableCache.set(cacheKey, encodingTable);
-    }
-
-    return encodingTable;
-};
-
-/**
- * Encodes an old-style Macintosh string. Returns a byte array upon success.
- * If the requested encoding is unsupported, or if the input string contains
- * a character that cannot be expressed in the encoding, the function returns
- * 'undefined'.
- * @param {string} str
- * @param {string} encoding
- * @returns {Array}
- */
-encode.MACSTRING = function(str, encoding) {
-    var table = getMacEncodingTable(encoding);
-    if (table === undefined) {
-        return undefined;
-    }
-
-    var result = [];
-    for (var i = 0; i < str.length; i++) {
-        var c = str.charCodeAt(i);
-
-        // In all eight-bit Mac encodings, the characters 0x00..0x7F are
-        // mapped to U+0000..U+007F; we only need to look up the others.
-        if (c >= 0x80) {
-            c = table[c];
-            if (c === undefined) {
-                // str contains a Unicode character that cannot be encoded
-                // in the requested encoding.
-                return undefined;
-            }
-        }
-        result[i] = c;
-        // result.push(c);
-    }
-
-    return result;
-};
-
-/**
- * @param {string} str
- * @param {string} encoding
- * @returns {number}
- */
-sizeOf.MACSTRING = function(str, encoding) {
-    var b = encode.MACSTRING(str, encoding);
-    if (b !== undefined) {
-        return b.length;
-    } else {
-        return 0;
-    }
-};
-
-// Helper for encode.VARDELTAS
-function isByteEncodable(value) {
-    return value >= -128 && value <= 127;
-}
-
-// Helper for encode.VARDELTAS
-function encodeVarDeltaRunAsZeroes(deltas, pos, result) {
-    var runLength = 0;
-    var numDeltas = deltas.length;
-    while (pos < numDeltas && runLength < 64 && deltas[pos] === 0) {
-        ++pos;
-        ++runLength;
-    }
-    result.push(0x80 | (runLength - 1));
-    return pos;
-}
-
-// Helper for encode.VARDELTAS
-function encodeVarDeltaRunAsBytes(deltas, offset, result) {
-    var runLength = 0;
-    var numDeltas = deltas.length;
-    var pos = offset;
-    while (pos < numDeltas && runLength < 64) {
-        var value = deltas[pos];
-        if (!isByteEncodable(value)) {
-            break;
-        }
-
-        // Within a byte-encoded run of deltas, a single zero is best
-        // stored literally as 0x00 value. However, if we have two or
-        // more zeroes in a sequence, it is better to start a new run.
-        // Fore example, the sequence of deltas [15, 15, 0, 15, 15]
-        // becomes 6 bytes (04 0F 0F 00 0F 0F) when storing the zero
-        // within the current run, but 7 bytes (01 0F 0F 80 01 0F 0F)
-        // when starting a new run.
-        if (value === 0 && pos + 1 < numDeltas && deltas[pos + 1] === 0) {
-            break;
-        }
-
-        ++pos;
-        ++runLength;
-    }
-    result.push(runLength - 1);
-    for (var i = offset; i < pos; ++i) {
-        result.push((deltas[i] + 256) & 0xff);
-    }
-    return pos;
-}
-
-// Helper for encode.VARDELTAS
-function encodeVarDeltaRunAsWords(deltas, offset, result) {
-    var runLength = 0;
-    var numDeltas = deltas.length;
-    var pos = offset;
-    while (pos < numDeltas && runLength < 64) {
-        var value = deltas[pos];
-
-        // Within a word-encoded run of deltas, it is easiest to start
-        // a new run (with a different encoding) whenever we encounter
-        // a zero value. For example, the sequence [0x6666, 0, 0x7777]
-        // needs 7 bytes when storing the zero inside the current run
-        // (42 66 66 00 00 77 77), and equally 7 bytes when starting a
-        // new run (40 66 66 80 40 77 77).
-        if (value === 0) {
-            break;
-        }
-
-        // Within a word-encoded run of deltas, a single value in the
-        // range (-128..127) should be encoded within the current run
-        // because it is more compact. For example, the sequence
-        // [0x6666, 2, 0x7777] becomes 7 bytes when storing the value
-        // literally (42 66 66 00 02 77 77), but 8 bytes when starting
-        // a new run (40 66 66 00 02 40 77 77).
-        if (isByteEncodable(value) && pos + 1 < numDeltas && isByteEncodable(deltas[pos + 1])) {
-            break;
-        }
-
-        ++pos;
-        ++runLength;
-    }
-    result.push(0x40 | (runLength - 1));
-    for (var i = offset; i < pos; ++i) {
-        var val = deltas[i];
-        result.push(((val + 0x10000) >> 8) & 0xff, (val + 0x100) & 0xff);
-    }
-    return pos;
-}
-
-/**
- * Encode a list of variation adjustment deltas.
- *
- * Variation adjustment deltas are used in ‘gvar’ and ‘cvar’ tables.
- * They indicate how points (in ‘gvar’) or values (in ‘cvar’) get adjusted
- * when generating instances of variation fonts.
- *
- * @see https://www.microsoft.com/typography/otspec/gvar.htm
- * @see https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6gvar.html
- * @param {Array}
- * @return {Array}
- */
-encode.VARDELTAS = function(deltas) {
-    var pos = 0;
-    var result = [];
-    while (pos < deltas.length) {
-        var value = deltas[pos];
-        if (value === 0) {
-            pos = encodeVarDeltaRunAsZeroes(deltas, pos, result);
-        } else if (value >= -128 && value <= 127) {
-            pos = encodeVarDeltaRunAsBytes(deltas, pos, result);
-        } else {
-            pos = encodeVarDeltaRunAsWords(deltas, pos, result);
-        }
-    }
-    return result;
-};
-
-// Convert a list of values to a CFF INDEX structure.
-// The values should be objects containing name / type / value.
-/**
- * @param {Array} l
- * @returns {Array}
- */
-encode.INDEX = function(l) {
-    //var offset, offsets, offsetEncoder, encodedOffsets, encodedOffset, data,
-    //    i, v;
-    // Because we have to know which data type to use to encode the offsets,
-    // we have to go through the values twice: once to encode the data and
-    // calculate the offsets, then again to encode the offsets using the fitting data type.
-    var offset = 1; // First offset is always 1.
-    var offsets = [offset];
-    var data = [];
-    for (var i = 0; i < l.length; i += 1) {
-        var v = encode.OBJECT(l[i]);
-        Array.prototype.push.apply(data, v);
-        offset += v.length;
-        offsets.push(offset);
-    }
-
-    if (data.length === 0) {
-        return [0, 0];
-    }
-
-    var encodedOffsets = [];
-    var offSize = (1 + Math.floor(Math.log(offset) / Math.log(2)) / 8) | 0;
-    var offsetEncoder = [undefined, encode.BYTE, encode.USHORT, encode.UINT24, encode.ULONG][offSize];
-    for (var i$1 = 0; i$1 < offsets.length; i$1 += 1) {
-        var encodedOffset = offsetEncoder(offsets[i$1]);
-        Array.prototype.push.apply(encodedOffsets, encodedOffset);
-    }
-
-    return Array.prototype.concat(encode.Card16(l.length),
-                           encode.OffSize(offSize),
-                           encodedOffsets,
-                           data);
-};
-
-/**
- * @param {Array}
- * @returns {number}
- */
-sizeOf.INDEX = function(v) {
-    return encode.INDEX(v).length;
-};
-
-/**
- * Convert an object to a CFF DICT structure.
- * The keys should be numeric.
- * The values should be objects containing name / type / value.
- * @param {Object} m
- * @returns {Array}
- */
-encode.DICT = function(m) {
-    var d = [];
-    var keys = Object.keys(m);
-    var length = keys.length;
-
-    for (var i = 0; i < length; i += 1) {
-        // Object.keys() return string keys, but our keys are always numeric.
-        var k = parseInt(keys[i], 0);
-        var v = m[k];
-        // Value comes before the key.
-        d = d.concat(encode.OPERAND(v.value, v.type));
-        d = d.concat(encode.OPERATOR(k));
-    }
-
-    return d;
-};
-
-/**
- * @param {Object}
- * @returns {number}
- */
-sizeOf.DICT = function(m) {
-    return encode.DICT(m).length;
-};
-
-/**
- * @param {number}
- * @returns {Array}
- */
-encode.OPERATOR = function(v) {
-    if (v < 1200) {
-        return [v];
-    } else {
-        return [12, v - 1200];
-    }
-};
-
-/**
- * @param {Array} v
- * @param {string}
- * @returns {Array}
- */
-encode.OPERAND = function(v, type) {
-    var d = [];
-    if (Array.isArray(type)) {
-        for (var i = 0; i < type.length; i += 1) {
-            check.argument(v.length === type.length, 'Not enough arguments given for type' + type);
-            d = d.concat(encode.OPERAND(v[i], type[i]));
-        }
-    } else {
-        if (type === 'SID') {
-            d = d.concat(encode.NUMBER(v));
-        } else if (type === 'offset') {
-            // We make it easy for ourselves and always encode offsets as
-            // 4 bytes. This makes offset calculation for the top dict easier.
-            d = d.concat(encode.NUMBER32(v));
-        } else if (type === 'number') {
-            d = d.concat(encode.NUMBER(v));
-        } else if (type === 'real') {
-            d = d.concat(encode.REAL(v));
-        } else {
-            throw new Error('Unknown operand type ' + type);
-            // FIXME Add support for booleans
-        }
-    }
-
-    return d;
-};
-
-encode.OP = encode.BYTE;
-sizeOf.OP = sizeOf.BYTE;
-
-// memoize charstring encoding using WeakMap if available
-var wmm = typeof WeakMap === 'function' && new WeakMap();
-
-/**
- * Convert a list of CharString operations to bytes.
- * @param {Array}
- * @returns {Array}
- */
-encode.CHARSTRING = function(ops) {
-    // See encode.MACSTRING for why we don't do "if (wmm && wmm.has(ops))".
-    if (wmm) {
-        var cachedValue = wmm.get(ops);
-        if (cachedValue !== undefined) {
-            return cachedValue;
-        }
-    }
-
-    var d = [];
-    var length = ops.length;
-
-    for (var i = 0; i < length; i += 1) {
-        var op = ops[i];
-        d = d.concat(encode[op.type](op.value));
-    }
-
-    if (wmm) {
-        wmm.set(ops, d);
-    }
-
-    return d;
-};
-
-/**
- * @param {Array}
- * @returns {number}
- */
-sizeOf.CHARSTRING = function(ops) {
-    return encode.CHARSTRING(ops).length;
-};
-
-// Utility functions ////////////////////////////////////////////////////////
-
-/**
- * Convert an object containing name / type / value to bytes.
- * @param {Object}
- * @returns {Array}
- */
-encode.OBJECT = function(v) {
-    var encodingFunction = encode[v.type];
-    check.argument(encodingFunction !== undefined, 'No encoding function for type ' + v.type);
-    return encodingFunction(v.value);
-};
-
-/**
- * @param {Object}
- * @returns {number}
- */
-sizeOf.OBJECT = function(v) {
-    var sizeOfFunction = sizeOf[v.type];
-    check.argument(sizeOfFunction !== undefined, 'No sizeOf function for type ' + v.type);
-    return sizeOfFunction(v.value);
-};
-
-/**
- * Convert a table object to bytes.
- * A table contains a list of fields containing the metadata (name, type and default value).
- * The table itself has the field values set as attributes.
- * @param {opentype.Table}
- * @returns {Array}
- */
-encode.TABLE = function(table) {
-    var d = [];
-    var length = table.fields.length;
-    var subtables = [];
-    var subtableOffsets = [];
-
-    for (var i = 0; i < length; i += 1) {
-        var field = table.fields[i];
-        var encodingFunction = encode[field.type];
-        check.argument(encodingFunction !== undefined, 'No encoding function for field type ' + field.type + ' (' + field.name + ')');
-        var value = table[field.name];
-        if (value === undefined) {
-            value = field.value;
-        }
-
-        var bytes = encodingFunction(value);
-
-        if (field.type === 'TABLE') {
-            subtableOffsets.push(d.length);
-            d = d.concat([0, 0]);
-            subtables.push(bytes);
-        } else {
-            d = d.concat(bytes);
-        }
-    }
-
-    for (var i$1 = 0; i$1 < subtables.length; i$1 += 1) {
-        var o = subtableOffsets[i$1];
-        var offset = d.length;
-        check.argument(offset < 65536, 'Table ' + table.tableName + ' too big.');
-        d[o] = offset >> 8;
-        d[o + 1] = offset & 0xff;
-        d = d.concat(subtables[i$1]);
-    }
-
-    return d;
-};
-
-/**
- * @param {opentype.Table}
- * @returns {number}
- */
-sizeOf.TABLE = function(table) {
-    var numBytes = 0;
-    var length = table.fields.length;
-
-    for (var i = 0; i < length; i += 1) {
-        var field = table.fields[i];
-        var sizeOfFunction = sizeOf[field.type];
-        check.argument(sizeOfFunction !== undefined, 'No sizeOf function for field type ' + field.type + ' (' + field.name + ')');
-        var value = table[field.name];
-        if (value === undefined) {
-            value = field.value;
-        }
-
-        numBytes += sizeOfFunction(value);
-
-        // Subtables take 2 more bytes for offsets.
-        if (field.type === 'TABLE') {
-            numBytes += 2;
-        }
-    }
-
-    return numBytes;
-};
-
-encode.RECORD = encode.TABLE;
-sizeOf.RECORD = sizeOf.TABLE;
-
-// Merge in a list of bytes.
-encode.LITERAL = function(v) {
-    return v;
-};
-
-sizeOf.LITERAL = function(v) {
-    return v.length;
-};
-
-// Table metadata
-
-/**
- * @exports opentype.Table
- * @class
- * @param {string} tableName
- * @param {Array} fields
- * @param {Object} options
- * @constructor
- */
-function Table(tableName, fields, options) {
-    // For coverage tables with coverage format 2, we do not want to add the coverage data directly to the table object,
-    // as this will result in wrong encoding order of the coverage data on serialization to bytes.
-    // The fallback of using the field values directly when not present on the table is handled in types.encode.TABLE() already.
-    if (fields.length && (fields[0].name !== 'coverageFormat' || fields[0].value === 1)) {
-        for (var i = 0; i < fields.length; i += 1) {
-            var field = fields[i];
-            this[field.name] = field.value;
-        }
-    }
-
-    this.tableName = tableName;
-    this.fields = fields;
-    if (options) {
-        var optionKeys = Object.keys(options);
-        for (var i$1 = 0; i$1 < optionKeys.length; i$1 += 1) {
-            var k = optionKeys[i$1];
-            var v = options[k];
-            if (this[k] !== undefined) {
-                this[k] = v;
-            }
-        }
-    }
-}
-
-/**
- * Encodes the table and returns an array of bytes
- * @return {Array}
- */
-Table.prototype.encode = function() {
-    return encode.TABLE(this);
-};
-
-/**
- * Get the size of the table.
- * @return {number}
- */
-Table.prototype.sizeOf = function() {
-    return sizeOf.TABLE(this);
-};
-
-/**
- * @private
- */
-function ushortList(itemName, list, count) {
-    if (count === undefined) {
-        count = list.length;
-    }
-    var fields = new Array(list.length + 1);
-    fields[0] = {name: itemName + 'Count', type: 'USHORT', value: count};
-    for (var i = 0; i < list.length; i++) {
-        fields[i + 1] = {name: itemName + i, type: 'USHORT', value: list[i]};
-    }
-    return fields;
-}
-
-/**
- * @private
- */
-function tableList(itemName, records, itemCallback) {
-    var count = records.length;
-    var fields = new Array(count + 1);
-    fields[0] = {name: itemName + 'Count', type: 'USHORT', value: count};
-    for (var i = 0; i < count; i++) {
-        fields[i + 1] = {name: itemName + i, type: 'TABLE', value: itemCallback(records[i], i)};
-    }
-    return fields;
-}
-
-/**
- * @private
- */
-function recordList(itemName, records, itemCallback) {
-    var count = records.length;
-    var fields = [];
-    fields[0] = {name: itemName + 'Count', type: 'USHORT', value: count};
-    for (var i = 0; i < count; i++) {
-        fields = fields.concat(itemCallback(records[i], i));
-    }
-    return fields;
-}
-
-// Common Layout Tables
-
-/**
- * @exports opentype.Coverage
- * @class
- * @param {opentype.Table}
- * @constructor
- * @extends opentype.Table
- */
-function Coverage(coverageTable) {
-    if (coverageTable.format === 1) {
-        Table.call(this, 'coverageTable',
-            [{name: 'coverageFormat', type: 'USHORT', value: 1}]
-            .concat(ushortList('glyph', coverageTable.glyphs))
-        );
-    } else if (coverageTable.format === 2) {
-        Table.call(this, 'coverageTable',
-            [{name: 'coverageFormat', type: 'USHORT', value: 2}]
-            .concat(recordList('rangeRecord', coverageTable.ranges, function(RangeRecord) {
-                return [
-                    {name: 'startGlyphID', type: 'USHORT', value: RangeRecord.start},
-                    {name: 'endGlyphID', type: 'USHORT', value: RangeRecord.end},
-                    {name: 'startCoverageIndex', type: 'USHORT', value: RangeRecord.index} ];
-            }))
-        );
-    } else {
-        check.assert(false, 'Coverage format must be 1 or 2.');
-    }
-}
-Coverage.prototype = Object.create(Table.prototype);
-Coverage.prototype.constructor = Coverage;
-
-function ScriptList(scriptListTable) {
-    Table.call(this, 'scriptListTable',
-        recordList('scriptRecord', scriptListTable, function(scriptRecord, i) {
-            var script = scriptRecord.script;
-            var defaultLangSys = script.defaultLangSys;
-            check.assert(!!defaultLangSys, 'Unable to write GSUB: script ' + scriptRecord.tag + ' has no default language system.');
-            return [
-                {name: 'scriptTag' + i, type: 'TAG', value: scriptRecord.tag},
-                {name: 'script' + i, type: 'TABLE', value: new Table('scriptTable', [
-                    {name: 'defaultLangSys', type: 'TABLE', value: new Table('defaultLangSys', [
-                        {name: 'lookupOrder', type: 'USHORT', value: 0},
-                        {name: 'reqFeatureIndex', type: 'USHORT', value: defaultLangSys.reqFeatureIndex}]
-                        .concat(ushortList('featureIndex', defaultLangSys.featureIndexes)))}
-                    ].concat(recordList('langSys', script.langSysRecords, function(langSysRecord, i) {
-                        var langSys = langSysRecord.langSys;
-                        return [
-                            {name: 'langSysTag' + i, type: 'TAG', value: langSysRecord.tag},
-                            {name: 'langSys' + i, type: 'TABLE', value: new Table('langSys', [
-                                {name: 'lookupOrder', type: 'USHORT', value: 0},
-                                {name: 'reqFeatureIndex', type: 'USHORT', value: langSys.reqFeatureIndex}
-                                ].concat(ushortList('featureIndex', langSys.featureIndexes)))}
-                        ];
-                    })))}
-            ];
-        })
-    );
-}
-ScriptList.prototype = Object.create(Table.prototype);
-ScriptList.prototype.constructor = ScriptList;
-
-/**
- * @exports opentype.FeatureList
- * @class
- * @param {opentype.Table}
- * @constructor
- * @extends opentype.Table
- */
-function FeatureList(featureListTable) {
-    Table.call(this, 'featureListTable',
-        recordList('featureRecord', featureListTable, function(featureRecord, i) {
-            var feature = featureRecord.feature;
-            return [
-                {name: 'featureTag' + i, type: 'TAG', value: featureRecord.tag},
-                {name: 'feature' + i, type: 'TABLE', value: new Table('featureTable', [
-                    {name: 'featureParams', type: 'USHORT', value: feature.featureParams} ].concat(ushortList('lookupListIndex', feature.lookupListIndexes)))}
-            ];
-        })
-    );
-}
-FeatureList.prototype = Object.create(Table.prototype);
-FeatureList.prototype.constructor = FeatureList;
-
-/**
- * @exports opentype.LookupList
- * @class
- * @param {opentype.Table}
- * @param {Object}
- * @constructor
- * @extends opentype.Table
- */
-function LookupList(lookupListTable, subtableMakers) {
-    Table.call(this, 'lookupListTable', tableList('lookup', lookupListTable, function(lookupTable) {
-        var subtableCallback = subtableMakers[lookupTable.lookupType];
-        check.assert(!!subtableCallback, 'Unable to write GSUB lookup type ' + lookupTable.lookupType + ' tables.');
-        return new Table('lookupTable', [
-            {name: 'lookupType', type: 'USHORT', value: lookupTable.lookupType},
-            {name: 'lookupFlag', type: 'USHORT', value: lookupTable.lookupFlag}
-        ].concat(tableList('subtable', lookupTable.subtables, subtableCallback)));
-    }));
-}
-LookupList.prototype = Object.create(Table.prototype);
-LookupList.prototype.constructor = LookupList;
-
-// Record = same as Table, but inlined (a Table has an offset and its data is further in the stream)
-// Don't use offsets inside Records (probable bug), only in Tables.
-var table = {
-    Table: Table,
-    Record: Table,
-    Coverage: Coverage,
-    ScriptList: ScriptList,
-    FeatureList: FeatureList,
-    LookupList: LookupList,
-    ushortList: ushortList,
-    tableList: tableList,
-    recordList: recordList,
-};
-
-// Parsing utility functions
-
-// Retrieve an unsigned byte from the DataView.
-function getByte(dataView, offset) {
-    return dataView.getUint8(offset);
-}
-
-// Retrieve an unsigned 16-bit short from the DataView.
-// The value is stored in big endian.
-function getUShort(dataView, offset) {
-    return dataView.getUint16(offset, false);
-}
-
-// Retrieve a signed 16-bit short from the DataView.
-// The value is stored in big endian.
-function getShort(dataView, offset) {
-    return dataView.getInt16(offset, false);
-}
-
-// Retrieve an unsigned 32-bit long from the DataView.
-// The value is stored in big endian.
-function getULong(dataView, offset) {
-    return dataView.getUint32(offset, false);
-}
-
-// Retrieve a 32-bit signed fixed-point number (16.16) from the DataView.
-// The value is stored in big endian.
-function getFixed(dataView, offset) {
-    var decimal = dataView.getInt16(offset, false);
-    var fraction = dataView.getUint16(offset + 2, false);
-    return decimal + fraction / 65535;
-}
-
-// Retrieve a 4-character tag from the DataView.
-// Tags are used to identify tables.
-function getTag(dataView, offset) {
-    var tag = '';
-    for (var i = offset; i < offset + 4; i += 1) {
-        tag += String.fromCharCode(dataView.getInt8(i));
-    }
-
-    return tag;
-}
-
-// Retrieve an offset from the DataView.
-// Offsets are 1 to 4 bytes in length, depending on the offSize argument.
-function getOffset(dataView, offset, offSize) {
-    var v = 0;
-    for (var i = 0; i < offSize; i += 1) {
-        v <<= 8;
-        v += dataView.getUint8(offset + i);
-    }
-
-    return v;
-}
-
-// Retrieve a number of bytes from start offset to the end offset from the DataView.
-function getBytes(dataView, startOffset, endOffset) {
-    var bytes = [];
-    for (var i = startOffset; i < endOffset; i += 1) {
-        bytes.push(dataView.getUint8(i));
-    }
-
-    return bytes;
-}
-
-// Convert the list of bytes to a string.
-function bytesToString(bytes) {
-    var s = '';
-    for (var i = 0; i < bytes.length; i += 1) {
-        s += String.fromCharCode(bytes[i]);
-    }
-
-    return s;
-}
-
-var typeOffsets = {
-    byte: 1,
-    uShort: 2,
-    short: 2,
-    uLong: 4,
-    fixed: 4,
-    longDateTime: 8,
-    tag: 4
-};
-
-// A stateful parser that changes the offset whenever a value is retrieved.
-// The data is a DataView.
-function Parser(data, offset) {
-    this.data = data;
-    this.offset = offset;
-    this.relativeOffset = 0;
-}
-
-Parser.prototype.parseByte = function() {
-    var v = this.data.getUint8(this.offset + this.relativeOffset);
-    this.relativeOffset += 1;
-    return v;
-};
-
-Parser.prototype.parseChar = function() {
-    var v = this.data.getInt8(this.offset + this.relativeOffset);
-    this.relativeOffset += 1;
-    return v;
-};
-
-Parser.prototype.parseCard8 = Parser.prototype.parseByte;
-
-Parser.prototype.parseUShort = function() {
-    var v = this.data.getUint16(this.offset + this.relativeOffset);
-    this.relativeOffset += 2;
-    return v;
-};
-
-Parser.prototype.parseCard16 = Parser.prototype.parseUShort;
-Parser.prototype.parseSID = Parser.prototype.parseUShort;
-Parser.prototype.parseOffset16 = Parser.prototype.parseUShort;
-
-Parser.prototype.parseShort = function() {
-    var v = this.data.getInt16(this.offset + this.relativeOffset);
-    this.relativeOffset += 2;
-    return v;
-};
-
-Parser.prototype.parseF2Dot14 = function() {
-    var v = this.data.getInt16(this.offset + this.relativeOffset) / 16384;
-    this.relativeOffset += 2;
-    return v;
-};
-
-Parser.prototype.parseULong = function() {
-    var v = getULong(this.data, this.offset + this.relativeOffset);
-    this.relativeOffset += 4;
-    return v;
-};
-
-Parser.prototype.parseOffset32 = Parser.prototype.parseULong;
-
-Parser.prototype.parseFixed = function() {
-    var v = getFixed(this.data, this.offset + this.relativeOffset);
-    this.relativeOffset += 4;
-    return v;
-};
-
-Parser.prototype.parseString = function(length) {
-    var dataView = this.data;
-    var offset = this.offset + this.relativeOffset;
-    var string = '';
-    this.relativeOffset += length;
-    for (var i = 0; i < length; i++) {
-        string += String.fromCharCode(dataView.getUint8(offset + i));
-    }
-
-    return string;
-};
-
-Parser.prototype.parseTag = function() {
-    return this.parseString(4);
-};
-
-// LONGDATETIME is a 64-bit integer.
-// JavaScript and unix timestamps traditionally use 32 bits, so we
-// only take the last 32 bits.
-// + Since until 2038 those bits will be filled by zeros we can ignore them.
-Parser.prototype.parseLongDateTime = function() {
-    var v = getULong(this.data, this.offset + this.relativeOffset + 4);
-    // Subtract seconds between 01/01/1904 and 01/01/1970
-    // to convert Apple Mac timestamp to Standard Unix timestamp
-    v -= 2082844800;
-    this.relativeOffset += 8;
-    return v;
-};
-
-Parser.prototype.parseVersion = function(minorBase) {
-    var major = getUShort(this.data, this.offset + this.relativeOffset);
-
-    // How to interpret the minor version is very vague in the spec. 0x5000 is 5, 0x1000 is 1
-    // Default returns the correct number if minor = 0xN000 where N is 0-9
-    // Set minorBase to 1 for tables that use minor = N where N is 0-9
-    var minor = getUShort(this.data, this.offset + this.relativeOffset + 2);
-    this.relativeOffset += 4;
-    if (minorBase === undefined) { minorBase = 0x1000; }
-    return major + minor / minorBase / 10;
-};
-
-Parser.prototype.skip = function(type, amount) {
-    if (amount === undefined) {
-        amount = 1;
-    }
-
-    this.relativeOffset += typeOffsets[type] * amount;
-};
-
-///// Parsing lists and records ///////////////////////////////
-
-// Parse a list of 32 bit unsigned integers.
-Parser.prototype.parseULongList = function(count) {
-    if (count === undefined) { count = this.parseULong(); }
-    var offsets = new Array(count);
-    var dataView = this.data;
-    var offset = this.offset + this.relativeOffset;
-    for (var i = 0; i < count; i++) {
-        offsets[i] = dataView.getUint32(offset);
-        offset += 4;
-    }
-
-    this.relativeOffset += count * 4;
-    return offsets;
-};
-
-// Parse a list of 16 bit unsigned integers. The length of the list can be read on the stream
-// or provided as an argument.
-Parser.prototype.parseOffset16List =
-Parser.prototype.parseUShortList = function(count) {
-    if (count === undefined) { count = this.parseUShort(); }
-    var offsets = new Array(count);
-    var dataView = this.data;
-    var offset = this.offset + this.relativeOffset;
-    for (var i = 0; i < count; i++) {
-        offsets[i] = dataView.getUint16(offset);
-        offset += 2;
-    }
-
-    this.relativeOffset += count * 2;
-    return offsets;
-};
-
-// Parses a list of 16 bit signed integers.
-Parser.prototype.parseShortList = function(count) {
-    var list = new Array(count);
-    var dataView = this.data;
-    var offset = this.offset + this.relativeOffset;
-    for (var i = 0; i < count; i++) {
-        list[i] = dataView.getInt16(offset);
-        offset += 2;
-    }
-
-    this.relativeOffset += count * 2;
-    return list;
-};
-
-// Parses a list of bytes.
-Parser.prototype.parseByteList = function(count) {
-    var list = new Array(count);
-    var dataView = this.data;
-    var offset = this.offset + this.relativeOffset;
-    for (var i = 0; i < count; i++) {
-        list[i] = dataView.getUint8(offset++);
-    }
-
-    this.relativeOffset += count;
-    return list;
-};
-
-/**
- * Parse a list of items.
- * Record count is optional, if omitted it is read from the stream.
- * itemCallback is one of the Parser methods.
- */
-Parser.prototype.parseList = function(count, itemCallback) {
-    if (!itemCallback) {
-        itemCallback = count;
-        count = this.parseUShort();
-    }
-    var list = new Array(count);
-    for (var i = 0; i < count; i++) {
-        list[i] = itemCallback.call(this);
-    }
-    return list;
-};
-
-Parser.prototype.parseList32 = function(count, itemCallback) {
-    if (!itemCallback) {
-        itemCallback = count;
-        count = this.parseULong();
-    }
-    var list = new Array(count);
-    for (var i = 0; i < count; i++) {
-        list[i] = itemCallback.call(this);
-    }
-    return list;
-};
-
-/**
- * Parse a list of records.
- * Record count is optional, if omitted it is read from the stream.
- * Example of recordDescription: { sequenceIndex: Parser.uShort, lookupListIndex: Parser.uShort }
- */
-Parser.prototype.parseRecordList = function(count, recordDescription) {
-    // If the count argument is absent, read it in the stream.
-    if (!recordDescription) {
-        recordDescription = count;
-        count = this.parseUShort();
-    }
-    var records = new Array(count);
-    var fields = Object.keys(recordDescription);
-    for (var i = 0; i < count; i++) {
-        var rec = {};
-        for (var j = 0; j < fields.length; j++) {
-            var fieldName = fields[j];
-            var fieldType = recordDescription[fieldName];
-            rec[fieldName] = fieldType.call(this);
-        }
-        records[i] = rec;
-    }
-    return records;
-};
-
-Parser.prototype.parseRecordList32 = function(count, recordDescription) {
-    // If the count argument is absent, read it in the stream.
-    if (!recordDescription) {
-        recordDescription = count;
-        count = this.parseULong();
-    }
-    var records = new Array(count);
-    var fields = Object.keys(recordDescription);
-    for (var i = 0; i < count; i++) {
-        var rec = {};
-        for (var j = 0; j < fields.length; j++) {
-            var fieldName = fields[j];
-            var fieldType = recordDescription[fieldName];
-            rec[fieldName] = fieldType.call(this);
-        }
-        records[i] = rec;
-    }
-    return records;
-};
-
-// Parse a data structure into an object
-// Example of description: { sequenceIndex: Parser.uShort, lookupListIndex: Parser.uShort }
-Parser.prototype.parseStruct = function(description) {
-    if (typeof description === 'function') {
-        return description.call(this);
-    } else {
-        var fields = Object.keys(description);
-        var struct = {};
-        for (var j = 0; j < fields.length; j++) {
-            var fieldName = fields[j];
-            var fieldType = description[fieldName];
-            struct[fieldName] = fieldType.call(this);
-        }
-        return struct;
-    }
-};
-
-/**
- * Parse a GPOS valueRecord
- * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#value-record
- * valueFormat is optional, if omitted it is read from the stream.
- */
-Parser.prototype.parseValueRecord = function(valueFormat) {
-    if (valueFormat === undefined) {
-        valueFormat = this.parseUShort();
-    }
-    if (valueFormat === 0) {
-        // valueFormat2 in kerning pairs is most often 0
-        // in this case return undefined instead of an empty object, to save space
-        return;
-    }
-    var valueRecord = {};
-
-    if (valueFormat & 0x0001) { valueRecord.xPlacement = this.parseShort(); }
-    if (valueFormat & 0x0002) { valueRecord.yPlacement = this.parseShort(); }
-    if (valueFormat & 0x0004) { valueRecord.xAdvance = this.parseShort(); }
-    if (valueFormat & 0x0008) { valueRecord.yAdvance = this.parseShort(); }
-
-    // Device table (non-variable font) / VariationIndex table (variable font) not supported
-    // https://docs.microsoft.com/fr-fr/typography/opentype/spec/chapter2#devVarIdxTbls
-    if (valueFormat & 0x0010) { valueRecord.xPlaDevice = undefined; this.parseShort(); }
-    if (valueFormat & 0x0020) { valueRecord.yPlaDevice = undefined; this.parseShort(); }
-    if (valueFormat & 0x0040) { valueRecord.xAdvDevice = undefined; this.parseShort(); }
-    if (valueFormat & 0x0080) { valueRecord.yAdvDevice = undefined; this.parseShort(); }
-
-    return valueRecord;
-};
-
-/**
- * Parse a list of GPOS valueRecords
- * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#value-record
- * valueFormat and valueCount are read from the stream.
- */
-Parser.prototype.parseValueRecordList = function() {
-    var valueFormat = this.parseUShort();
-    var valueCount = this.parseUShort();
-    var values = new Array(valueCount);
-    for (var i = 0; i < valueCount; i++) {
-        values[i] = this.parseValueRecord(valueFormat);
-    }
-    return values;
-};
-
-Parser.prototype.parsePointer = function(description) {
-    var structOffset = this.parseOffset16();
-    if (structOffset > 0) {
-        // NULL offset => return undefined
-        return new Parser(this.data, this.offset + structOffset).parseStruct(description);
-    }
-    return undefined;
-};
-
-Parser.prototype.parsePointer32 = function(description) {
-    var structOffset = this.parseOffset32();
-    if (structOffset > 0) {
-        // NULL offset => return undefined
-        return new Parser(this.data, this.offset + structOffset).parseStruct(description);
-    }
-    return undefined;
-};
-
-/**
- * Parse a list of offsets to lists of 16-bit integers,
- * or a list of offsets to lists of offsets to any kind of items.
- * If itemCallback is not provided, a list of list of UShort is assumed.
- * If provided, itemCallback is called on each item and must parse the item.
- * See examples in tables/gsub.js
- */
-Parser.prototype.parseListOfLists = function(itemCallback) {
-    var offsets = this.parseOffset16List();
-    var count = offsets.length;
-    var relativeOffset = this.relativeOffset;
-    var list = new Array(count);
-    for (var i = 0; i < count; i++) {
-        var start = offsets[i];
-        if (start === 0) {
-            // NULL offset
-            // Add i as owned property to list. Convenient with assert.
-            list[i] = undefined;
-            continue;
-        }
-        this.relativeOffset = start;
-        if (itemCallback) {
-            var subOffsets = this.parseOffset16List();
-            var subList = new Array(subOffsets.length);
-            for (var j = 0; j < subOffsets.length; j++) {
-                this.relativeOffset = start + subOffsets[j];
-                subList[j] = itemCallback.call(this);
-            }
-            list[i] = subList;
-        } else {
-            list[i] = this.parseUShortList();
-        }
-    }
-    this.relativeOffset = relativeOffset;
-    return list;
-};
-
-///// Complex tables parsing //////////////////////////////////
-
-// Parse a coverage table in a GSUB, GPOS or GDEF table.
-// https://www.microsoft.com/typography/OTSPEC/chapter2.htm
-// parser.offset must point to the start of the table containing the coverage.
-Parser.prototype.parseCoverage = function() {
-    var startOffset = this.offset + this.relativeOffset;
-    var format = this.parseUShort();
-    var count = this.parseUShort();
-    if (format === 1) {
-        return {
-            format: 1,
-            glyphs: this.parseUShortList(count)
-        };
-    } else if (format === 2) {
-        var ranges = new Array(count);
-        for (var i = 0; i < count; i++) {
-            ranges[i] = {
-                start: this.parseUShort(),
-                end: this.parseUShort(),
-                index: this.parseUShort()
-            };
-        }
-        return {
-            format: 2,
-            ranges: ranges
-        };
-    }
-    throw new Error('0x' + startOffset.toString(16) + ': Coverage format must be 1 or 2.');
-};
-
-// Parse a Class Definition Table in a GSUB, GPOS or GDEF table.
-// https://www.microsoft.com/typography/OTSPEC/chapter2.htm
-Parser.prototype.parseClassDef = function() {
-    var startOffset = this.offset + this.relativeOffset;
-    var format = this.parseUShort();
-    if (format === 1) {
-        return {
-            format: 1,
-            startGlyph: this.parseUShort(),
-            classes: this.parseUShortList()
-        };
-    } else if (format === 2) {
-        return {
-            format: 2,
-            ranges: this.parseRecordList({
-                start: Parser.uShort,
-                end: Parser.uShort,
-                classId: Parser.uShort
-            })
-        };
-    }
-    throw new Error('0x' + startOffset.toString(16) + ': ClassDef format must be 1 or 2.');
-};
-
-///// Static methods ///////////////////////////////////
-// These convenience methods can be used as callbacks and should be called with "this" context set to a Parser instance.
-
-Parser.list = function(count, itemCallback) {
-    return function() {
-        return this.parseList(count, itemCallback);
-    };
-};
-
-Parser.list32 = function(count, itemCallback) {
-    return function() {
-        return this.parseList32(count, itemCallback);
-    };
-};
-
-Parser.recordList = function(count, recordDescription) {
-    return function() {
-        return this.parseRecordList(count, recordDescription);
-    };
-};
-
-Parser.recordList32 = function(count, recordDescription) {
-    return function() {
-        return this.parseRecordList32(count, recordDescription);
-    };
-};
-
-Parser.pointer = function(description) {
-    return function() {
-        return this.parsePointer(description);
-    };
-};
-
-Parser.pointer32 = function(description) {
-    return function() {
-        return this.parsePointer32(description);
-    };
-};
-
-Parser.tag = Parser.prototype.parseTag;
-Parser.byte = Parser.prototype.parseByte;
-Parser.uShort = Parser.offset16 = Parser.prototype.parseUShort;
-Parser.uShortList = Parser.prototype.parseUShortList;
-Parser.uLong = Parser.offset32 = Parser.prototype.parseULong;
-Parser.uLongList = Parser.prototype.parseULongList;
-Parser.struct = Parser.prototype.parseStruct;
-Parser.coverage = Parser.prototype.parseCoverage;
-Parser.classDef = Parser.prototype.parseClassDef;
-
-///// Script, Feature, Lookup lists ///////////////////////////////////////////////
-// https://www.microsoft.com/typography/OTSPEC/chapter2.htm
-
-var langSysTable = {
-    reserved: Parser.uShort,
-    reqFeatureIndex: Parser.uShort,
-    featureIndexes: Parser.uShortList
-};
-
-Parser.prototype.parseScriptList = function() {
-    return this.parsePointer(Parser.recordList({
-        tag: Parser.tag,
-        script: Parser.pointer({
-            defaultLangSys: Parser.pointer(langSysTable),
-            langSysRecords: Parser.recordList({
-                tag: Parser.tag,
-                langSys: Parser.pointer(langSysTable)
-            })
-        })
-    })) || [];
-};
-
-Parser.prototype.parseFeatureList = function() {
-    return this.parsePointer(Parser.recordList({
-        tag: Parser.tag,
-        feature: Parser.pointer({
-            featureParams: Parser.offset16,
-            lookupListIndexes: Parser.uShortList
-        })
-    })) || [];
-};
-
-Parser.prototype.parseLookupList = function(lookupTableParsers) {
-    return this.parsePointer(Parser.list(Parser.pointer(function() {
-        var lookupType = this.parseUShort();
-        check.argument(1 <= lookupType && lookupType <= 9, 'GPOS/GSUB lookup type ' + lookupType + ' unknown.');
-        var lookupFlag = this.parseUShort();
-        var useMarkFilteringSet = lookupFlag & 0x10;
-        return {
-            lookupType: lookupType,
-            lookupFlag: lookupFlag,
-            subtables: this.parseList(Parser.pointer(lookupTableParsers[lookupType])),
-            markFilteringSet: useMarkFilteringSet ? this.parseUShort() : undefined
-        };
-    }))) || [];
-};
-
-Parser.prototype.parseFeatureVariationsList = function() {
-    return this.parsePointer32(function() {
-        var majorVersion = this.parseUShort();
-        var minorVersion = this.parseUShort();
-        check.argument(majorVersion === 1 && minorVersion < 1, 'GPOS/GSUB feature variations table unknown.');
-        var featureVariations = this.parseRecordList32({
-            conditionSetOffset: Parser.offset32,
-            featureTableSubstitutionOffset: Parser.offset32
-        });
-        return featureVariations;
-    }) || [];
-};
-
-var parse = {
-    getByte: getByte,
-    getCard8: getByte,
-    getUShort: getUShort,
-    getCard16: getUShort,
-    getShort: getShort,
-    getULong: getULong,
-    getFixed: getFixed,
-    getTag: getTag,
-    getOffset: getOffset,
-    getBytes: getBytes,
-    bytesToString: bytesToString,
-    Parser: Parser,
-};
-
-// The `cmap` table stores the mappings from characters to glyphs.
-
-function parseCmapTableFormat12(cmap, p) {
-    //Skip reserved.
-    p.parseUShort();
-
-    // Length in bytes of the sub-tables.
-    cmap.length = p.parseULong();
-    cmap.language = p.parseULong();
-
-    var groupCount;
-    cmap.groupCount = groupCount = p.parseULong();
-    cmap.glyphIndexMap = {};
-
-    for (var i = 0; i < groupCount; i += 1) {
-        var startCharCode = p.parseULong();
-        var endCharCode = p.parseULong();
-        var startGlyphId = p.parseULong();
-
-        for (var c = startCharCode; c <= endCharCode; c += 1) {
-            cmap.glyphIndexMap[c] = startGlyphId;
-            startGlyphId++;
-        }
-    }
-}
-
-function parseCmapTableFormat4(cmap, p, data, start, offset) {
-    // Length in bytes of the sub-tables.
-    cmap.length = p.parseUShort();
-    cmap.language = p.parseUShort();
-
-    // segCount is stored x 2.
-    var segCount;
-    cmap.segCount = segCount = p.parseUShort() >> 1;
-
-    // Skip searchRange, entrySelector, rangeShift.
-    p.skip('uShort', 3);
-
-    // The "unrolled" mapping from character codes to glyph indices.
-    cmap.glyphIndexMap = {};
-    var endCountParser = new parse.Parser(data, start + offset + 14);
-    var startCountParser = new parse.Parser(data, start + offset + 16 + segCount * 2);
-    var idDeltaParser = new parse.Parser(data, start + offset + 16 + segCount * 4);
-    var idRangeOffsetParser = new parse.Parser(data, start + offset + 16 + segCount * 6);
-    var glyphIndexOffset = start + offset + 16 + segCount * 8;
-    for (var i = 0; i < segCount - 1; i += 1) {
-        var glyphIndex = (void 0);
-        var endCount = endCountParser.parseUShort();
-        var startCount = startCountParser.parseUShort();
-        var idDelta = idDeltaParser.parseShort();
-        var idRangeOffset = idRangeOffsetParser.parseUShort();
-        for (var c = startCount; c <= endCount; c += 1) {
-            if (idRangeOffset !== 0) {
-                // The idRangeOffset is relative to the current position in the idRangeOffset array.
-                // Take the current offset in the idRangeOffset array.
-                glyphIndexOffset = (idRangeOffsetParser.offset + idRangeOffsetParser.relativeOffset - 2);
-
-                // Add the value of the idRangeOffset, which will move us into the glyphIndex array.
-                glyphIndexOffset += idRangeOffset;
-
-                // Then add the character index of the current segment, multiplied by 2 for USHORTs.
-                glyphIndexOffset += (c - startCount) * 2;
-                glyphIndex = parse.getUShort(data, glyphIndexOffset);
-                if (glyphIndex !== 0) {
-                    glyphIndex = (glyphIndex + idDelta) & 0xFFFF;
-                }
-            } else {
-                glyphIndex = (c + idDelta) & 0xFFFF;
-            }
-
-            cmap.glyphIndexMap[c] = glyphIndex;
-        }
-    }
-}
-
-// Parse the `cmap` table. This table stores the mappings from characters to glyphs.
-// There are many available formats, but we only support the Windows format 4 and 12.
-// This function returns a `CmapEncoding` object or null if no supported format could be found.
-function parseCmapTable(data, start) {
-    var cmap = {};
-    cmap.version = parse.getUShort(data, start);
-    check.argument(cmap.version === 0, 'cmap table version should be 0.');
-
-    // The cmap table can contain many sub-tables, each with their own format.
-    // We're only interested in a "platform 0" (Unicode format) and "platform 3" (Windows format) table.
-    cmap.numTables = parse.getUShort(data, start + 2);
-    var offset = -1;
-    for (var i = cmap.numTables - 1; i >= 0; i -= 1) {
-        var platformId = parse.getUShort(data, start + 4 + (i * 8));
-        var encodingId = parse.getUShort(data, start + 4 + (i * 8) + 2);
-        if ((platformId === 3 && (encodingId === 0 || encodingId === 1 || encodingId === 10)) ||
-            (platformId === 0 && (encodingId === 0 || encodingId === 1 || encodingId === 2 || encodingId === 3 || encodingId === 4))) {
-            offset = parse.getULong(data, start + 4 + (i * 8) + 4);
-            break;
-        }
-    }
-
-    if (offset === -1) {
-        // There is no cmap table in the font that we support.
-        throw new Error('No valid cmap sub-tables found.');
-    }
-
-    var p = new parse.Parser(data, start + offset);
-    cmap.format = p.parseUShort();
-
-    if (cmap.format === 12) {
-        parseCmapTableFormat12(cmap, p);
-    } else if (cmap.format === 4) {
-        parseCmapTableFormat4(cmap, p, data, start, offset);
-    } else {
-        throw new Error('Only format 4 and 12 cmap tables are supported (found format ' + cmap.format + ').');
-    }
-
-    return cmap;
-}
-
-function addSegment(t, code, glyphIndex) {
-    t.segments.push({
-        end: code,
-        start: code,
-        delta: -(code - glyphIndex),
-        offset: 0,
-        glyphIndex: glyphIndex
-    });
-}
-
-function addTerminatorSegment(t) {
-    t.segments.push({
-        end: 0xFFFF,
-        start: 0xFFFF,
-        delta: 1,
-        offset: 0
-    });
-}
-
-// Make cmap table, format 4 by default, 12 if needed only
-function makeCmapTable(glyphs) {
-    // Plan 0 is the base Unicode Plan but emojis, for example are on another plan, and needs cmap 12 format (with 32bit)
-    var isPlan0Only = true;
-    var i;
-
-    // Check if we need to add cmap format 12 or if format 4 only is fine
-    for (i = glyphs.length - 1; i > 0; i -= 1) {
-        var g = glyphs.get(i);
-        if (g.unicode > 65535) {
-            console.log('Adding CMAP format 12 (needed!)');
-            isPlan0Only = false;
-            break;
-        }
-    }
-
-    var cmapTable = [
-        {name: 'version', type: 'USHORT', value: 0},
-        {name: 'numTables', type: 'USHORT', value: isPlan0Only ? 1 : 2},
-
-        // CMAP 4 header
-        {name: 'platformID', type: 'USHORT', value: 3},
-        {name: 'encodingID', type: 'USHORT', value: 1},
-        {name: 'offset', type: 'ULONG', value: isPlan0Only ? 12 : (12 + 8)}
-    ];
-
-    if (!isPlan0Only)
-        { cmapTable = cmapTable.concat([
-            // CMAP 12 header
-            {name: 'cmap12PlatformID', type: 'USHORT', value: 3}, // We encode only for PlatformID = 3 (Windows) because it is supported everywhere
-            {name: 'cmap12EncodingID', type: 'USHORT', value: 10},
-            {name: 'cmap12Offset', type: 'ULONG', value: 0}
-        ]); }
-
-    cmapTable = cmapTable.concat([
-        // CMAP 4 Subtable
-        {name: 'format', type: 'USHORT', value: 4},
-        {name: 'cmap4Length', type: 'USHORT', value: 0},
-        {name: 'language', type: 'USHORT', value: 0},
-        {name: 'segCountX2', type: 'USHORT', value: 0},
-        {name: 'searchRange', type: 'USHORT', value: 0},
-        {name: 'entrySelector', type: 'USHORT', value: 0},
-        {name: 'rangeShift', type: 'USHORT', value: 0}
-    ]);
-
-    var t = new table.Table('cmap', cmapTable);
-
-    t.segments = [];
-    for (i = 0; i < glyphs.length; i += 1) {
-        var glyph = glyphs.get(i);
-        for (var j = 0; j < glyph.unicodes.length; j += 1) {
-            addSegment(t, glyph.unicodes[j], i);
-        }
-
-        t.segments = t.segments.sort(function (a, b) {
-            return a.start - b.start;
-        });
-    }
-
-    addTerminatorSegment(t);
-
-    var segCount = t.segments.length;
-    var segCountToRemove = 0;
-
-    // CMAP 4
-    // Set up parallel segment arrays.
-    var endCounts = [];
-    var startCounts = [];
-    var idDeltas = [];
-    var idRangeOffsets = [];
-    var glyphIds = [];
-
-    // CMAP 12
-    var cmap12Groups = [];
-
-    // Reminder this loop is not following the specification at 100%
-    // The specification -> find suites of characters and make a group
-    // Here we're doing one group for each letter
-    // Doing as the spec can save 8 times (or more) space
-    for (i = 0; i < segCount; i += 1) {
-        var segment = t.segments[i];
-
-        // CMAP 4
-        if (segment.end <= 65535 && segment.start <= 65535) {
-            endCounts = endCounts.concat({name: 'end_' + i, type: 'USHORT', value: segment.end});
-            startCounts = startCounts.concat({name: 'start_' + i, type: 'USHORT', value: segment.start});
-            idDeltas = idDeltas.concat({name: 'idDelta_' + i, type: 'SHORT', value: segment.delta});
-            idRangeOffsets = idRangeOffsets.concat({name: 'idRangeOffset_' + i, type: 'USHORT', value: segment.offset});
-            if (segment.glyphId !== undefined) {
-                glyphIds = glyphIds.concat({name: 'glyph_' + i, type: 'USHORT', value: segment.glyphId});
-            }
-        } else {
-            // Skip Unicode > 65535 (16bit unsigned max) for CMAP 4, will be added in CMAP 12
-            segCountToRemove += 1;
-        }
-
-        // CMAP 12
-        // Skip Terminator Segment
-        if (!isPlan0Only && segment.glyphIndex !== undefined) {
-            cmap12Groups = cmap12Groups.concat({name: 'cmap12Start_' + i, type: 'ULONG', value: segment.start});
-            cmap12Groups = cmap12Groups.concat({name: 'cmap12End_' + i, type: 'ULONG', value: segment.end});
-            cmap12Groups = cmap12Groups.concat({name: 'cmap12Glyph_' + i, type: 'ULONG', value: segment.glyphIndex});
-        }
-    }
-
-    // CMAP 4 Subtable
-    t.segCountX2 = (segCount - segCountToRemove) * 2;
-    t.searchRange = Math.pow(2, Math.floor(Math.log((segCount - segCountToRemove)) / Math.log(2))) * 2;
-    t.entrySelector = Math.log(t.searchRange / 2) / Math.log(2);
-    t.rangeShift = t.segCountX2 - t.searchRange;
-
-    t.fields = t.fields.concat(endCounts);
-    t.fields.push({name: 'reservedPad', type: 'USHORT', value: 0});
-    t.fields = t.fields.concat(startCounts);
-    t.fields = t.fields.concat(idDeltas);
-    t.fields = t.fields.concat(idRangeOffsets);
-    t.fields = t.fields.concat(glyphIds);
-
-    t.cmap4Length = 14 + // Subtable header
-        endCounts.length * 2 +
-        2 + // reservedPad
-        startCounts.length * 2 +
-        idDeltas.length * 2 +
-        idRangeOffsets.length * 2 +
-        glyphIds.length * 2;
-
-    if (!isPlan0Only) {
-        // CMAP 12 Subtable
-        var cmap12Length = 16 + // Subtable header
-            cmap12Groups.length * 4;
-
-        t.cmap12Offset = 12 + (2 * 2) + 4 + t.cmap4Length;
-        t.fields = t.fields.concat([
-            {name: 'cmap12Format', type: 'USHORT', value: 12},
-            {name: 'cmap12Reserved', type: 'USHORT', value: 0},
-            {name: 'cmap12Length', type: 'ULONG', value: cmap12Length},
-            {name: 'cmap12Language', type: 'ULONG', value: 0},
-            {name: 'cmap12nGroups', type: 'ULONG', value: cmap12Groups.length / 3}
-        ]);
-
-        t.fields = t.fields.concat(cmap12Groups);
-    }
-
-    return t;
-}
-
-var cmap = { parse: parseCmapTable, make: makeCmapTable };
-
-// Glyph encoding
-
-var cffStandardStrings = [
-    '.notdef', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', 'quoteright',
-    'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two',
-    'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater',
-    'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
-    'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore',
-    'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
-    'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', 'exclamdown', 'cent', 'sterling',
-    'fraction', 'yen', 'florin', 'section', 'currency', 'quotesingle', 'quotedblleft', 'guillemotleft',
-    'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'endash', 'dagger', 'daggerdbl', 'periodcentered', 'paragraph',
-    'bullet', 'quotesinglbase', 'quotedblbase', 'quotedblright', 'guillemotright', 'ellipsis', 'perthousand',
-    'questiondown', 'grave', 'acute', 'circumflex', 'tilde', 'macron', 'breve', 'dotaccent', 'dieresis', 'ring',
-    'cedilla', 'hungarumlaut', 'ogonek', 'caron', 'emdash', 'AE', 'ordfeminine', 'Lslash', 'Oslash', 'OE',
-    'ordmasculine', 'ae', 'dotlessi', 'lslash', 'oslash', 'oe', 'germandbls', 'onesuperior', 'logicalnot', 'mu',
-    'trademark', 'Eth', 'onehalf', 'plusminus', 'Thorn', 'onequarter', 'divide', 'brokenbar', 'degree', 'thorn',
-    'threequarters', 'twosuperior', 'registered', 'minus', 'eth', 'multiply', 'threesuperior', 'copyright',
-    'Aacute', 'Acircumflex', 'Adieresis', 'Agrave', 'Aring', 'Atilde', 'Ccedilla', 'Eacute', 'Ecircumflex',
-    'Edieresis', 'Egrave', 'Iacute', 'Icircumflex', 'Idieresis', 'Igrave', 'Ntilde', 'Oacute', 'Ocircumflex',
-    'Odieresis', 'Ograve', 'Otilde', 'Scaron', 'Uacute', 'Ucircumflex', 'Udieresis', 'Ugrave', 'Yacute',
-    'Ydieresis', 'Zcaron', 'aacute', 'acircumflex', 'adieresis', 'agrave', 'aring', 'atilde', 'ccedilla', 'eacute',
-    'ecircumflex', 'edieresis', 'egrave', 'iacute', 'icircumflex', 'idieresis', 'igrave', 'ntilde', 'oacute',
-    'ocircumflex', 'odieresis', 'ograve', 'otilde', 'scaron', 'uacute', 'ucircumflex', 'udieresis', 'ugrave',
-    'yacute', 'ydieresis', 'zcaron', 'exclamsmall', 'Hungarumlautsmall', 'dollaroldstyle', 'dollarsuperior',
-    'ampersandsmall', 'Acutesmall', 'parenleftsuperior', 'parenrightsuperior', '266 ff', 'onedotenleader',
-    'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle', 'fouroldstyle', 'fiveoldstyle', 'sixoldstyle',
-    'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', 'commasuperior', 'threequartersemdash', 'periodsuperior',
-    'questionsmall', 'asuperior', 'bsuperior', 'centsuperior', 'dsuperior', 'esuperior', 'isuperior', 'lsuperior',
-    'msuperior', 'nsuperior', 'osuperior', 'rsuperior', 'ssuperior', 'tsuperior', 'ff', 'ffi', 'ffl',
-    'parenleftinferior', 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', 'Asmall',
-    'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', 'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall',
-    'Msmall', 'Nsmall', 'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', 'Vsmall', 'Wsmall',
-    'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', 'onefitted', 'rupiah', 'Tildesmall', 'exclamdownsmall',
-    'centoldstyle', 'Lslashsmall', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall', 'Brevesmall', 'Caronsmall',
-    'Dotaccentsmall', 'Macronsmall', 'figuredash', 'hypheninferior', 'Ogoneksmall', 'Ringsmall', 'Cedillasmall',
-    'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', 'seveneighths', 'onethird', 'twothirds',
-    'zerosuperior', 'foursuperior', 'fivesuperior', 'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior',
-    'zeroinferior', 'oneinferior', 'twoinferior', 'threeinferior', 'fourinferior', 'fiveinferior', 'sixinferior',
-    'seveninferior', 'eightinferior', 'nineinferior', 'centinferior', 'dollarinferior', 'periodinferior',
-    'commainferior', 'Agravesmall', 'Aacutesmall', 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall',
-    'Aringsmall', 'AEsmall', 'Ccedillasmall', 'Egravesmall', 'Eacutesmall', 'Ecircumflexsmall', 'Edieresissmall',
-    'Igravesmall', 'Iacutesmall', 'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall', 'Ogravesmall',
-    'Oacutesmall', 'Ocircumflexsmall', 'Otildesmall', 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall',
-    'Uacutesmall', 'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', 'Ydieresissmall', '001.000',
-    '001.001', '001.002', '001.003', 'Black', 'Bold', 'Book', 'Light', 'Medium', 'Regular', 'Roman', 'Semibold'];
-
-var cffStandardEncoding = [
-    '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
-    '', '', '', '', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent', 'ampersand', 'quoteright',
-    'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 'zero', 'one', 'two',
-    'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less', 'equal', 'greater',
-    'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
-    'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright', 'asciicircum', 'underscore',
-    'quoteleft', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
-    'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde', '', '', '', '', '', '', '', '',
-    '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
-    'exclamdown', 'cent', 'sterling', 'fraction', 'yen', 'florin', 'section', 'currency', 'quotesingle',
-    'quotedblleft', 'guillemotleft', 'guilsinglleft', 'guilsinglright', 'fi', 'fl', '', 'endash', 'dagger',
-    'daggerdbl', 'periodcentered', '', 'paragraph', 'bullet', 'quotesinglbase', 'quotedblbase', 'quotedblright',
-    'guillemotright', 'ellipsis', 'perthousand', '', 'questiondown', '', 'grave', 'acute', 'circumflex', 'tilde',
-    'macron', 'breve', 'dotaccent', 'dieresis', '', 'ring', 'cedilla', '', 'hungarumlaut', 'ogonek', 'caron',
-    'emdash', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'AE', '', 'ordfeminine', '', '', '',
-    '', 'Lslash', 'Oslash', 'OE', 'ordmasculine', '', '', '', '', '', 'ae', '', '', '', 'dotlessi', '', '',
-    'lslash', 'oslash', 'oe', 'germandbls'];
-
-var cffExpertEncoding = [
-    '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
-    '', '', '', '', 'space', 'exclamsmall', 'Hungarumlautsmall', '', 'dollaroldstyle', 'dollarsuperior',
-    'ampersandsmall', 'Acutesmall', 'parenleftsuperior', 'parenrightsuperior', 'twodotenleader', 'onedotenleader',
-    'comma', 'hyphen', 'period', 'fraction', 'zerooldstyle', 'oneoldstyle', 'twooldstyle', 'threeoldstyle',
-    'fouroldstyle', 'fiveoldstyle', 'sixoldstyle', 'sevenoldstyle', 'eightoldstyle', 'nineoldstyle', 'colon',
-    'semicolon', 'commasuperior', 'threequartersemdash', 'periodsuperior', 'questionsmall', '', 'asuperior',
-    'bsuperior', 'centsuperior', 'dsuperior', 'esuperior', '', '', 'isuperior', '', '', 'lsuperior', 'msuperior',
-    'nsuperior', 'osuperior', '', '', 'rsuperior', 'ssuperior', 'tsuperior', '', 'ff', 'fi', 'fl', 'ffi', 'ffl',
-    'parenleftinferior', '', 'parenrightinferior', 'Circumflexsmall', 'hyphensuperior', 'Gravesmall', 'Asmall',
-    'Bsmall', 'Csmall', 'Dsmall', 'Esmall', 'Fsmall', 'Gsmall', 'Hsmall', 'Ismall', 'Jsmall', 'Ksmall', 'Lsmall',
-    'Msmall', 'Nsmall', 'Osmall', 'Psmall', 'Qsmall', 'Rsmall', 'Ssmall', 'Tsmall', 'Usmall', 'Vsmall', 'Wsmall',
-    'Xsmall', 'Ysmall', 'Zsmall', 'colonmonetary', 'onefitted', 'rupiah', 'Tildesmall', '', '', '', '', '', '', '',
-    '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
-    'exclamdownsmall', 'centoldstyle', 'Lslashsmall', '', '', 'Scaronsmall', 'Zcaronsmall', 'Dieresissmall',
-    'Brevesmall', 'Caronsmall', '', 'Dotaccentsmall', '', '', 'Macronsmall', '', '', 'figuredash', 'hypheninferior',
-    '', '', 'Ogoneksmall', 'Ringsmall', 'Cedillasmall', '', '', '', 'onequarter', 'onehalf', 'threequarters',
-    'questiondownsmall', 'oneeighth', 'threeeighths', 'fiveeighths', 'seveneighths', 'onethird', 'twothirds', '',
-    '', 'zerosuperior', 'onesuperior', 'twosuperior', 'threesuperior', 'foursuperior', 'fivesuperior',
-    'sixsuperior', 'sevensuperior', 'eightsuperior', 'ninesuperior', 'zeroinferior', 'oneinferior', 'twoinferior',
-    'threeinferior', 'fourinferior', 'fiveinferior', 'sixinferior', 'seveninferior', 'eightinferior',
-    'nineinferior', 'centinferior', 'dollarinferior', 'periodinferior', 'commainferior', 'Agravesmall',
-    'Aacutesmall', 'Acircumflexsmall', 'Atildesmall', 'Adieresissmall', 'Aringsmall', 'AEsmall', 'Ccedillasmall',
-    'Egravesmall', 'Eacutesmall', 'Ecircumflexsmall', 'Edieresissmall', 'Igravesmall', 'Iacutesmall',
-    'Icircumflexsmall', 'Idieresissmall', 'Ethsmall', 'Ntildesmall', 'Ogravesmall', 'Oacutesmall',
-    'Ocircumflexsmall', 'Otildesmall', 'Odieresissmall', 'OEsmall', 'Oslashsmall', 'Ugravesmall', 'Uacutesmall',
-    'Ucircumflexsmall', 'Udieresissmall', 'Yacutesmall', 'Thornsmall', 'Ydieresissmall'];
-
-var standardNames = [
-    '.notdef', '.null', 'nonmarkingreturn', 'space', 'exclam', 'quotedbl', 'numbersign', 'dollar', 'percent',
-    'ampersand', 'quotesingle', 'parenleft', 'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash',
-    'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'colon', 'semicolon', 'less',
-    'equal', 'greater', 'question', 'at', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
-    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 'backslash', 'bracketright',
-    'asciicircum', 'underscore', 'grave', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
-    'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 'asciitilde',
-    'Adieresis', 'Aring', 'Ccedilla', 'Eacute', 'Ntilde', 'Odieresis', 'Udieresis', 'aacute', 'agrave',
-    'acircumflex', 'adieresis', 'atilde', 'aring', 'ccedilla', 'eacute', 'egrave', 'ecircumflex', 'edieresis',
-    'iacute', 'igrave', 'icircumflex', 'idieresis', 'ntilde', 'oacute', 'ograve', 'ocircumflex', 'odieresis',
-    'otilde', 'uacute', 'ugrave', 'ucircumflex', 'udieresis', 'dagger', 'degree', 'cent', 'sterling', 'section',
-    'bullet', 'paragraph', 'germandbls', 'registered', 'copyright', 'trademark', 'acute', 'dieresis', 'notequal',
-    'AE', 'Oslash', 'infinity', 'plusminus', 'lessequal', 'greaterequal', 'yen', 'mu', 'partialdiff', 'summation',
-    'product', 'pi', 'integral', 'ordfeminine', 'ordmasculine', 'Omega', 'ae', 'oslash', 'questiondown',
-    'exclamdown', 'logicalnot', 'radical', 'florin', 'approxequal', 'Delta', 'guillemotleft', 'guillemotright',
-    'ellipsis', 'nonbreakingspace', 'Agrave', 'Atilde', 'Otilde', 'OE', 'oe', 'endash', 'emdash', 'quotedblleft',
-    'quotedblright', 'quoteleft', 'quoteright', 'divide', 'lozenge', 'ydieresis', 'Ydieresis', 'fraction',
-    'currency', 'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'daggerdbl', 'periodcentered', 'quotesinglbase',
-    'quotedblbase', 'perthousand', 'Acircumflex', 'Ecircumflex', 'Aacute', 'Edieresis', 'Egrave', 'Iacute',
-    'Icircumflex', 'Idieresis', 'Igrave', 'Oacute', 'Ocircumflex', 'apple', 'Ograve', 'Uacute', 'Ucircumflex',
-    'Ugrave', 'dotlessi', 'circumflex', 'tilde', 'macron', 'breve', 'dotaccent', 'ring', 'cedilla', 'hungarumlaut',
-    'ogonek', 'caron', 'Lslash', 'lslash', 'Scaron', 'scaron', 'Zcaron', 'zcaron', 'brokenbar', 'Eth', 'eth',
-    'Yacute', 'yacute', 'Thorn', 'thorn', 'minus', 'multiply', 'onesuperior', 'twosuperior', 'threesuperior',
-    'onehalf', 'onequarter', 'threequarters', 'franc', 'Gbreve', 'gbreve', 'Idotaccent', 'Scedilla', 'scedilla',
-    'Cacute', 'cacute', 'Ccaron', 'ccaron', 'dcroat'];
-
-/**
- * This is the encoding used for fonts created from scratch.
- * It loops through all glyphs and finds the appropriate unicode value.
- * Since it's linear time, other encodings will be faster.
- * @exports opentype.DefaultEncoding
- * @class
- * @constructor
- * @param {opentype.Font}
- */
-function DefaultEncoding(font) {
-    this.font = font;
-}
-
-DefaultEncoding.prototype.charToGlyphIndex = function(c) {
-    var code = c.codePointAt(0);
-    var glyphs = this.font.glyphs;
-    if (glyphs) {
-        for (var i = 0; i < glyphs.length; i += 1) {
-            var glyph = glyphs.get(i);
-            for (var j = 0; j < glyph.unicodes.length; j += 1) {
-                if (glyph.unicodes[j] === code) {
-                    return i;
-                }
-            }
-        }
-    }
-    return null;
-};
-
-/**
- * @exports opentype.CmapEncoding
- * @class
- * @constructor
- * @param {Object} cmap - a object with the cmap encoded data
- */
-function CmapEncoding(cmap) {
-    this.cmap = cmap;
-}
-
-/**
- * @param  {string} c - the character
- * @return {number} The glyph index.
- */
-CmapEncoding.prototype.charToGlyphIndex = function(c) {
-    return this.cmap.glyphIndexMap[c.codePointAt(0)] || 0;
-};
-
-/**
- * @exports opentype.CffEncoding
- * @class
- * @constructor
- * @param {string} encoding - The encoding
- * @param {Array} charset - The character set.
- */
-function CffEncoding(encoding, charset) {
-    this.encoding = encoding;
-    this.charset = charset;
-}
-
-/**
- * @param  {string} s - The character
- * @return {number} The index.
- */
-CffEncoding.prototype.charToGlyphIndex = function(s) {
-    var code = s.codePointAt(0);
-    var charName = this.encoding[code];
-    return this.charset.indexOf(charName);
-};
-
-/**
- * @exports opentype.GlyphNames
- * @class
- * @constructor
- * @param {Object} post
- */
-function GlyphNames(post) {
-    switch (post.version) {
-        case 1:
-            this.names = standardNames.slice();
-            break;
-        case 2:
-            this.names = new Array(post.numberOfGlyphs);
-            for (var i = 0; i < post.numberOfGlyphs; i++) {
-                if (post.glyphNameIndex[i] < standardNames.length) {
-                    this.names[i] = standardNames[post.glyphNameIndex[i]];
-                } else {
-                    this.names[i] = post.names[post.glyphNameIndex[i] - standardNames.length];
-                }
-            }
-
-            break;
-        case 2.5:
-            this.names = new Array(post.numberOfGlyphs);
-            for (var i$1 = 0; i$1 < post.numberOfGlyphs; i$1++) {
-                this.names[i$1] = standardNames[i$1 + post.glyphNameIndex[i$1]];
-            }
-
-            break;
-        case 3:
-            this.names = [];
-            break;
-        default:
-            this.names = [];
-            break;
-    }
-}
-
-/**
- * Gets the index of a glyph by name.
- * @param  {string} name - The glyph name
- * @return {number} The index
- */
-GlyphNames.prototype.nameToGlyphIndex = function(name) {
-    return this.names.indexOf(name);
-};
-
-/**
- * @param  {number} gid
- * @return {string}
- */
-GlyphNames.prototype.glyphIndexToName = function(gid) {
-    return this.names[gid];
-};
-
-function addGlyphNamesAll(font) {
-    var glyph;
-    var glyphIndexMap = font.tables.cmap.glyphIndexMap;
-    var charCodes = Object.keys(glyphIndexMap);
-
-    for (var i = 0; i < charCodes.length; i += 1) {
-        var c = charCodes[i];
-        var glyphIndex = glyphIndexMap[c];
-        glyph = font.glyphs.get(glyphIndex);
-        glyph.addUnicode(parseInt(c));
-    }
-
-    for (var i$1 = 0; i$1 < font.glyphs.length; i$1 += 1) {
-        glyph = font.glyphs.get(i$1);
-        if (font.cffEncoding) {
-            if (font.isCIDFont) {
-                glyph.name = 'gid' + i$1;
-            } else {
-                glyph.name = font.cffEncoding.charset[i$1];
-            }
-        } else if (font.glyphNames.names) {
-            glyph.name = font.glyphNames.glyphIndexToName(i$1);
-        }
-    }
-}
-
-function addGlyphNamesToUnicodeMap(font) {
-    font._IndexToUnicodeMap = {};
-
-    var glyphIndexMap = font.tables.cmap.glyphIndexMap;
-    var charCodes = Object.keys(glyphIndexMap);
-
-    for (var i = 0; i < charCodes.length; i += 1) {
-        var c = charCodes[i];
-        var glyphIndex = glyphIndexMap[c];
-        if (font._IndexToUnicodeMap[glyphIndex] === undefined) {
-            font._IndexToUnicodeMap[glyphIndex] = {
-                unicodes: [parseInt(c)]
-            };
-        } else {
-            font._IndexToUnicodeMap[glyphIndex].unicodes.push(parseInt(c));
-        }
-    }
-}
-
-/**
- * @alias opentype.addGlyphNames
- * @param {opentype.Font}
- * @param {Object}
- */
-function addGlyphNames(font, opt) {
-    if (opt.lowMemory) {
-        addGlyphNamesToUnicodeMap(font);
-    } else {
-        addGlyphNamesAll(font);
-    }
-}
-
-// Drawing utility functions.
-
-// Draw a line on the given context from point `x1,y1` to point `x2,y2`.
-function line(ctx, x1, y1, x2, y2) {
-    ctx.beginPath();
-    ctx.moveTo(x1, y1);
-    ctx.lineTo(x2, y2);
-    ctx.stroke();
-}
-
-var draw = { line: line };
-
-// The Glyph object
-// import glyf from './tables/glyf' Can't be imported here, because it's a circular dependency
-
-function getPathDefinition(glyph, path) {
-    var _path = path || new Path();
-    return {
-        configurable: true,
-
-        get: function() {
-            if (typeof _path === 'function') {
-                _path = _path();
-            }
-
-            return _path;
-        },
-
-        set: function(p) {
-            _path = p;
-        }
-    };
-}
-/**
- * @typedef GlyphOptions
- * @type Object
- * @property {string} [name] - The glyph name
- * @property {number} [unicode]
- * @property {Array} [unicodes]
- * @property {number} [xMin]
- * @property {number} [yMin]
- * @property {number} [xMax]
- * @property {number} [yMax]
- * @property {number} [advanceWidth]
- */
-
-// A Glyph is an individual mark that often corresponds to a character.
-// Some glyphs, such as ligatures, are a combination of many characters.
-// Glyphs are the basic building blocks of a font.
-//
-// The `Glyph` class contains utility methods for drawing the path and its points.
-/**
- * @exports opentype.Glyph
- * @class
- * @param {GlyphOptions}
- * @constructor
- */
-function Glyph(options) {
-    // By putting all the code on a prototype function (which is only declared once)
-    // we reduce the memory requirements for larger fonts by some 2%
-    this.bindConstructorValues(options);
-}
-
-/**
- * @param  {GlyphOptions}
- */
-Glyph.prototype.bindConstructorValues = function(options) {
-    this.index = options.index || 0;
-
-    // These three values cannot be deferred for memory optimization:
-    this.name = options.name || null;
-    this.unicode = options.unicode || undefined;
-    this.unicodes = options.unicodes || options.unicode !== undefined ? [options.unicode] : [];
-
-    // But by binding these values only when necessary, we reduce can
-    // the memory requirements by almost 3% for larger fonts.
-    if ('xMin' in options) {
-        this.xMin = options.xMin;
-    }
-
-    if ('yMin' in options) {
-        this.yMin = options.yMin;
-    }
-
-    if ('xMax' in options) {
-        this.xMax = options.xMax;
-    }
-
-    if ('yMax' in options) {
-        this.yMax = options.yMax;
-    }
-
-    if ('advanceWidth' in options) {
-        this.advanceWidth = options.advanceWidth;
-    }
-
-    // The path for a glyph is the most memory intensive, and is bound as a value
-    // with a getter/setter to ensure we actually do path parsing only once the
-    // path is actually needed by anything.
-    Object.defineProperty(this, 'path', getPathDefinition(this, options.path));
-};
-
-/**
- * @param {number}
- */
-Glyph.prototype.addUnicode = function(unicode) {
-    if (this.unicodes.length === 0) {
-        this.unicode = unicode;
-    }
-
-    this.unicodes.push(unicode);
-};
-
-/**
- * Calculate the minimum bounding box for this glyph.
- * @return {opentype.BoundingBox}
- */
-Glyph.prototype.getBoundingBox = function() {
-    return this.path.getBoundingBox();
-};
-
-/**
- * Convert the glyph to a Path we can draw on a drawing context.
- * @param  {number} [x=0] - Horizontal position of the beginning of the text.
- * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
- * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- * @param  {Object=} options - xScale, yScale to stretch the glyph.
- * @param  {opentype.Font} if hinting is to be used, the font
- * @return {opentype.Path}
- */
-Glyph.prototype.getPath = function(x, y, fontSize, options, font) {
-    x = x !== undefined ? x : 0;
-    y = y !== undefined ? y : 0;
-    fontSize = fontSize !== undefined ? fontSize : 72;
-    var commands;
-    var hPoints;
-    if (!options) { options = { }; }
-    var xScale = options.xScale;
-    var yScale = options.yScale;
-
-    if (options.hinting && font && font.hinting) {
-        // in case of hinting, the hinting engine takes care
-        // of scaling the points (not the path) before hinting.
-        hPoints = this.path && font.hinting.exec(this, fontSize);
-        // in case the hinting engine failed hPoints is undefined
-        // and thus reverts to plain rending
-    }
-
-    if (hPoints) {
-        // Call font.hinting.getCommands instead of `glyf.getPath(hPoints).commands` to avoid a circular dependency
-        commands = font.hinting.getCommands(hPoints);
-        x = Math.round(x);
-        y = Math.round(y);
-        // TODO in case of hinting xyScaling is not yet supported
-        xScale = yScale = 1;
-    } else {
-        commands = this.path.commands;
-        var scale = 1 / (this.path.unitsPerEm || 1000) * fontSize;
-        if (xScale === undefined) { xScale = scale; }
-        if (yScale === undefined) { yScale = scale; }
-    }
-
-    var p = new Path();
-    for (var i = 0; i < commands.length; i += 1) {
-        var cmd = commands[i];
-        if (cmd.type === 'M') {
-            p.moveTo(x + (cmd.x * xScale), y + (-cmd.y * yScale));
-        } else if (cmd.type === 'L') {
-            p.lineTo(x + (cmd.x * xScale), y + (-cmd.y * yScale));
-        } else if (cmd.type === 'Q') {
-            p.quadraticCurveTo(x + (cmd.x1 * xScale), y + (-cmd.y1 * yScale),
-                               x + (cmd.x * xScale), y + (-cmd.y * yScale));
-        } else if (cmd.type === 'C') {
-            p.curveTo(x + (cmd.x1 * xScale), y + (-cmd.y1 * yScale),
-                      x + (cmd.x2 * xScale), y + (-cmd.y2 * yScale),
-                      x + (cmd.x * xScale), y + (-cmd.y * yScale));
-        } else if (cmd.type === 'Z') {
-            p.closePath();
-        }
-    }
-
-    return p;
-};
-
-/**
- * Split the glyph into contours.
- * This function is here for backwards compatibility, and to
- * provide raw access to the TrueType glyph outlines.
- * @return {Array}
- */
-Glyph.prototype.getContours = function() {
-    if (this.points === undefined) {
-        return [];
-    }
-
-    var contours = [];
-    var currentContour = [];
-    for (var i = 0; i < this.points.length; i += 1) {
-        var pt = this.points[i];
-        currentContour.push(pt);
-        if (pt.lastPointOfContour) {
-            contours.push(currentContour);
-            currentContour = [];
-        }
-    }
-
-    check.argument(currentContour.length === 0, 'There are still points left in the current contour.');
-    return contours;
-};
-
-/**
- * Calculate the xMin/yMin/xMax/yMax/lsb/rsb for a Glyph.
- * @return {Object}
- */
-Glyph.prototype.getMetrics = function() {
-    var commands = this.path.commands;
-    var xCoords = [];
-    var yCoords = [];
-    for (var i = 0; i < commands.length; i += 1) {
-        var cmd = commands[i];
-        if (cmd.type !== 'Z') {
-            xCoords.push(cmd.x);
-            yCoords.push(cmd.y);
-        }
-
-        if (cmd.type === 'Q' || cmd.type === 'C') {
-            xCoords.push(cmd.x1);
-            yCoords.push(cmd.y1);
-        }
-
-        if (cmd.type === 'C') {
-            xCoords.push(cmd.x2);
-            yCoords.push(cmd.y2);
-        }
-    }
-
-    var metrics = {
-        xMin: Math.min.apply(null, xCoords),
-        yMin: Math.min.apply(null, yCoords),
-        xMax: Math.max.apply(null, xCoords),
-        yMax: Math.max.apply(null, yCoords),
-        leftSideBearing: this.leftSideBearing
-    };
-
-    if (!isFinite(metrics.xMin)) {
-        metrics.xMin = 0;
-    }
-
-    if (!isFinite(metrics.xMax)) {
-        metrics.xMax = this.advanceWidth;
-    }
-
-    if (!isFinite(metrics.yMin)) {
-        metrics.yMin = 0;
-    }
-
-    if (!isFinite(metrics.yMax)) {
-        metrics.yMax = 0;
-    }
-
-    metrics.rightSideBearing = this.advanceWidth - metrics.leftSideBearing - (metrics.xMax - metrics.xMin);
-    return metrics;
-};
-
-/**
- * Draw the glyph on the given context.
- * @param  {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
- * @param  {number} [x=0] - Horizontal position of the beginning of the text.
- * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
- * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- * @param  {Object=} options - xScale, yScale to stretch the glyph.
- */
-Glyph.prototype.draw = function(ctx, x, y, fontSize, options) {
-    this.getPath(x, y, fontSize, options).draw(ctx);
-};
-
-/**
- * Draw the points of the glyph.
- * On-curve points will be drawn in blue, off-curve points will be drawn in red.
- * @param  {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
- * @param  {number} [x=0] - Horizontal position of the beginning of the text.
- * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
- * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- */
-Glyph.prototype.drawPoints = function(ctx, x, y, fontSize) {
-    function drawCircles(l, x, y, scale) {
-        ctx.beginPath();
-        for (var j = 0; j < l.length; j += 1) {
-            ctx.moveTo(x + (l[j].x * scale), y + (l[j].y * scale));
-            ctx.arc(x + (l[j].x * scale), y + (l[j].y * scale), 2, 0, Math.PI * 2, false);
-        }
-
-        ctx.closePath();
-        ctx.fill();
-    }
-
-    x = x !== undefined ? x : 0;
-    y = y !== undefined ? y : 0;
-    fontSize = fontSize !== undefined ? fontSize : 24;
-    var scale = 1 / this.path.unitsPerEm * fontSize;
-
-    var blueCircles = [];
-    var redCircles = [];
-    var path = this.path;
-    for (var i = 0; i < path.commands.length; i += 1) {
-        var cmd = path.commands[i];
-        if (cmd.x !== undefined) {
-            blueCircles.push({x: cmd.x, y: -cmd.y});
-        }
-
-        if (cmd.x1 !== undefined) {
-            redCircles.push({x: cmd.x1, y: -cmd.y1});
-        }
-
-        if (cmd.x2 !== undefined) {
-            redCircles.push({x: cmd.x2, y: -cmd.y2});
-        }
-    }
-
-    ctx.fillStyle = 'blue';
-    drawCircles(blueCircles, x, y, scale);
-    ctx.fillStyle = 'red';
-    drawCircles(redCircles, x, y, scale);
-};
-
-/**
- * Draw lines indicating important font measurements.
- * Black lines indicate the origin of the coordinate system (point 0,0).
- * Blue lines indicate the glyph bounding box.
- * Green line indicates the advance width of the glyph.
- * @param  {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
- * @param  {number} [x=0] - Horizontal position of the beginning of the text.
- * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
- * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- */
-Glyph.prototype.drawMetrics = function(ctx, x, y, fontSize) {
-    var scale;
-    x = x !== undefined ? x : 0;
-    y = y !== undefined ? y : 0;
-    fontSize = fontSize !== undefined ? fontSize : 24;
-    scale = 1 / this.path.unitsPerEm * fontSize;
-    ctx.lineWidth = 1;
-
-    // Draw the origin
-    ctx.strokeStyle = 'black';
-    draw.line(ctx, x, -10000, x, 10000);
-    draw.line(ctx, -10000, y, 10000, y);
-
-    // This code is here due to memory optimization: by not using
-    // defaults in the constructor, we save a notable amount of memory.
-    var xMin = this.xMin || 0;
-    var yMin = this.yMin || 0;
-    var xMax = this.xMax || 0;
-    var yMax = this.yMax || 0;
-    var advanceWidth = this.advanceWidth || 0;
-
-    // Draw the glyph box
-    ctx.strokeStyle = 'blue';
-    draw.line(ctx, x + (xMin * scale), -10000, x + (xMin * scale), 10000);
-    draw.line(ctx, x + (xMax * scale), -10000, x + (xMax * scale), 10000);
-    draw.line(ctx, -10000, y + (-yMin * scale), 10000, y + (-yMin * scale));
-    draw.line(ctx, -10000, y + (-yMax * scale), 10000, y + (-yMax * scale));
-
-    // Draw the advance width
-    ctx.strokeStyle = 'green';
-    draw.line(ctx, x + (advanceWidth * scale), -10000, x + (advanceWidth * scale), 10000);
-};
-
-// The GlyphSet object
-
-// Define a property on the glyph that depends on the path being loaded.
-function defineDependentProperty(glyph, externalName, internalName) {
-    Object.defineProperty(glyph, externalName, {
-        get: function() {
-            // Request the path property to make sure the path is loaded.
-            glyph.path; // jshint ignore:line
-            return glyph[internalName];
-        },
-        set: function(newValue) {
-            glyph[internalName] = newValue;
-        },
-        enumerable: true,
-        configurable: true
-    });
-}
-
-/**
- * A GlyphSet represents all glyphs available in the font, but modelled using
- * a deferred glyph loader, for retrieving glyphs only once they are absolutely
- * necessary, to keep the memory footprint down.
- * @exports opentype.GlyphSet
- * @class
- * @param {opentype.Font}
- * @param {Array}
- */
-function GlyphSet(font, glyphs) {
-    this.font = font;
-    this.glyphs = {};
-    if (Array.isArray(glyphs)) {
-        for (var i = 0; i < glyphs.length; i++) {
-            var glyph = glyphs[i];
-            glyph.path.unitsPerEm = font.unitsPerEm;
-            this.glyphs[i] = glyph;
-        }
-    }
-
-    this.length = (glyphs && glyphs.length) || 0;
-}
-
-/**
- * @param  {number} index
- * @return {opentype.Glyph}
- */
-GlyphSet.prototype.get = function(index) {
-    // this.glyphs[index] is 'undefined' when low memory mode is on. glyph is pushed on request only.
-    if (this.glyphs[index] === undefined) {
-        this.font._push(index);
-        if (typeof this.glyphs[index] === 'function') {
-            this.glyphs[index] = this.glyphs[index]();
-        }
-
-        var glyph = this.glyphs[index];
-        var unicodeObj = this.font._IndexToUnicodeMap[index];
-
-        if (unicodeObj) {
-            for (var j = 0; j < unicodeObj.unicodes.length; j++)
-                { glyph.addUnicode(unicodeObj.unicodes[j]); }
-        }
-
-        if (this.font.cffEncoding) {
-            if (this.font.isCIDFont) {
-                glyph.name = 'gid' + index;
-            } else {
-                glyph.name = this.font.cffEncoding.charset[index];
-            }
-        } else if (this.font.glyphNames.names) {
-            glyph.name = this.font.glyphNames.glyphIndexToName(index);
-        }
-
-        this.glyphs[index].advanceWidth = this.font._hmtxTableData[index].advanceWidth;
-        this.glyphs[index].leftSideBearing = this.font._hmtxTableData[index].leftSideBearing;
-    } else {
-        if (typeof this.glyphs[index] === 'function') {
-            this.glyphs[index] = this.glyphs[index]();
-        }
-    }
-
-    return this.glyphs[index];
-};
-
-/**
- * @param  {number} index
- * @param  {Object}
- */
-GlyphSet.prototype.push = function(index, loader) {
-    this.glyphs[index] = loader;
-    this.length++;
-};
-
-/**
- * @alias opentype.glyphLoader
- * @param  {opentype.Font} font
- * @param  {number} index
- * @return {opentype.Glyph}
- */
-function glyphLoader(font, index) {
-    return new Glyph({index: index, font: font});
-}
-
-/**
- * Generate a stub glyph that can be filled with all metadata *except*
- * the "points" and "path" properties, which must be loaded only once
- * the glyph's path is actually requested for text shaping.
- * @alias opentype.ttfGlyphLoader
- * @param  {opentype.Font} font
- * @param  {number} index
- * @param  {Function} parseGlyph
- * @param  {Object} data
- * @param  {number} position
- * @param  {Function} buildPath
- * @return {opentype.Glyph}
- */
-function ttfGlyphLoader(font, index, parseGlyph, data, position, buildPath) {
-    return function() {
-        var glyph = new Glyph({index: index, font: font});
-
-        glyph.path = function() {
-            parseGlyph(glyph, data, position);
-            var path = buildPath(font.glyphs, glyph);
-            path.unitsPerEm = font.unitsPerEm;
-            return path;
-        };
-
-        defineDependentProperty(glyph, 'xMin', '_xMin');
-        defineDependentProperty(glyph, 'xMax', '_xMax');
-        defineDependentProperty(glyph, 'yMin', '_yMin');
-        defineDependentProperty(glyph, 'yMax', '_yMax');
-
-        return glyph;
-    };
-}
-/**
- * @alias opentype.cffGlyphLoader
- * @param  {opentype.Font} font
- * @param  {number} index
- * @param  {Function} parseCFFCharstring
- * @param  {string} charstring
- * @return {opentype.Glyph}
- */
-function cffGlyphLoader(font, index, parseCFFCharstring, charstring) {
-    return function() {
-        var glyph = new Glyph({index: index, font: font});
-
-        glyph.path = function() {
-            var path = parseCFFCharstring(font, glyph, charstring);
-            path.unitsPerEm = font.unitsPerEm;
-            return path;
-        };
-
-        return glyph;
-    };
-}
-
-var glyphset = { GlyphSet: GlyphSet, glyphLoader: glyphLoader, ttfGlyphLoader: ttfGlyphLoader, cffGlyphLoader: cffGlyphLoader };
-
-// The `CFF` table contains the glyph outlines in PostScript format.
-
-// Custom equals function that can also check lists.
-function equals(a, b) {
-    if (a === b) {
-        return true;
-    } else if (Array.isArray(a) && Array.isArray(b)) {
-        if (a.length !== b.length) {
-            return false;
-        }
-
-        for (var i = 0; i < a.length; i += 1) {
-            if (!equals(a[i], b[i])) {
-                return false;
-            }
-        }
-
-        return true;
-    } else {
-        return false;
-    }
-}
-
-// Subroutines are encoded using the negative half of the number space.
-// See type 2 chapter 4.7 "Subroutine operators".
-function calcCFFSubroutineBias(subrs) {
-    var bias;
-    if (subrs.length < 1240) {
-        bias = 107;
-    } else if (subrs.length < 33900) {
-        bias = 1131;
-    } else {
-        bias = 32768;
-    }
-
-    return bias;
-}
-
-// Parse a `CFF` INDEX array.
-// An index array consists of a list of offsets, then a list of objects at those offsets.
-function parseCFFIndex(data, start, conversionFn) {
-    var offsets = [];
-    var objects = [];
-    var count = parse.getCard16(data, start);
-    var objectOffset;
-    var endOffset;
-    if (count !== 0) {
-        var offsetSize = parse.getByte(data, start + 2);
-        objectOffset = start + ((count + 1) * offsetSize) + 2;
-        var pos = start + 3;
-        for (var i = 0; i < count + 1; i += 1) {
-            offsets.push(parse.getOffset(data, pos, offsetSize));
-            pos += offsetSize;
-        }
-
-        // The total size of the index array is 4 header bytes + the value of the last offset.
-        endOffset = objectOffset + offsets[count];
-    } else {
-        endOffset = start + 2;
-    }
-
-    for (var i$1 = 0; i$1 < offsets.length - 1; i$1 += 1) {
-        var value = parse.getBytes(data, objectOffset + offsets[i$1], objectOffset + offsets[i$1 + 1]);
-        if (conversionFn) {
-            value = conversionFn(value);
-        }
-
-        objects.push(value);
-    }
-
-    return {objects: objects, startOffset: start, endOffset: endOffset};
-}
-
-function parseCFFIndexLowMemory(data, start) {
-    var offsets = [];
-    var count = parse.getCard16(data, start);
-    var objectOffset;
-    var endOffset;
-    if (count !== 0) {
-        var offsetSize = parse.getByte(data, start + 2);
-        objectOffset = start + ((count + 1) * offsetSize) + 2;
-        var pos = start + 3;
-        for (var i = 0; i < count + 1; i += 1) {
-            offsets.push(parse.getOffset(data, pos, offsetSize));
-            pos += offsetSize;
-        }
-
-        // The total size of the index array is 4 header bytes + the value of the last offset.
-        endOffset = objectOffset + offsets[count];
-    } else {
-        endOffset = start + 2;
-    }
-
-    return {offsets: offsets, startOffset: start, endOffset: endOffset};
-}
-function getCffIndexObject(i, offsets, data, start, conversionFn) {
-    var count = parse.getCard16(data, start);
-    var objectOffset = 0;
-    if (count !== 0) {
-        var offsetSize = parse.getByte(data, start + 2);
-        objectOffset = start + ((count + 1) * offsetSize) + 2;
-    }
-
-    var value = parse.getBytes(data, objectOffset + offsets[i], objectOffset + offsets[i + 1]);
-    if (conversionFn) {
-        value = conversionFn(value);
-    }
-    return value;
-}
-
-// Parse a `CFF` DICT real value.
-function parseFloatOperand(parser) {
-    var s = '';
-    var eof = 15;
-    var lookup = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', 'E', 'E-', null, '-'];
-    while (true) {
-        var b = parser.parseByte();
-        var n1 = b >> 4;
-        var n2 = b & 15;
-
-        if (n1 === eof) {
-            break;
-        }
-
-        s += lookup[n1];
-
-        if (n2 === eof) {
-            break;
-        }
-
-        s += lookup[n2];
-    }
-
-    return parseFloat(s);
-}
-
-// Parse a `CFF` DICT operand.
-function parseOperand(parser, b0) {
-    var b1;
-    var b2;
-    var b3;
-    var b4;
-    if (b0 === 28) {
-        b1 = parser.parseByte();
-        b2 = parser.parseByte();
-        return b1 << 8 | b2;
-    }
-
-    if (b0 === 29) {
-        b1 = parser.parseByte();
-        b2 = parser.parseByte();
-        b3 = parser.parseByte();
-        b4 = parser.parseByte();
-        return b1 << 24 | b2 << 16 | b3 << 8 | b4;
-    }
-
-    if (b0 === 30) {
-        return parseFloatOperand(parser);
-    }
-
-    if (b0 >= 32 && b0 <= 246) {
-        return b0 - 139;
-    }
-
-    if (b0 >= 247 && b0 <= 250) {
-        b1 = parser.parseByte();
-        return (b0 - 247) * 256 + b1 + 108;
-    }
-
-    if (b0 >= 251 && b0 <= 254) {
-        b1 = parser.parseByte();
-        return -(b0 - 251) * 256 - b1 - 108;
-    }
-
-    throw new Error('Invalid b0 ' + b0);
-}
-
-// Convert the entries returned by `parseDict` to a proper dictionary.
-// If a value is a list of one, it is unpacked.
-function entriesToObject(entries) {
-    var o = {};
-    for (var i = 0; i < entries.length; i += 1) {
-        var key = entries[i][0];
-        var values = entries[i][1];
-        var value = (void 0);
-        if (values.length === 1) {
-            value = values[0];
-        } else {
-            value = values;
-        }
-
-        if (o.hasOwnProperty(key) && !isNaN(o[key])) {
-            throw new Error('Object ' + o + ' already has key ' + key);
-        }
-
-        o[key] = value;
-    }
-
-    return o;
-}
-
-// Parse a `CFF` DICT object.
-// A dictionary contains key-value pairs in a compact tokenized format.
-function parseCFFDict(data, start, size) {
-    start = start !== undefined ? start : 0;
-    var parser = new parse.Parser(data, start);
-    var entries = [];
-    var operands = [];
-    size = size !== undefined ? size : data.length;
-
-    while (parser.relativeOffset < size) {
-        var op = parser.parseByte();
-
-        // The first byte for each dict item distinguishes between operator (key) and operand (value).
-        // Values <= 21 are operators.
-        if (op <= 21) {
-            // Two-byte operators have an initial escape byte of 12.
-            if (op === 12) {
-                op = 1200 + parser.parseByte();
-            }
-
-            entries.push([op, operands]);
-            operands = [];
-        } else {
-            // Since the operands (values) come before the operators (keys), we store all operands in a list
-            // until we encounter an operator.
-            operands.push(parseOperand(parser, op));
-        }
-    }
-
-    return entriesToObject(entries);
-}
-
-// Given a String Index (SID), return the value of the string.
-// Strings below index 392 are standard CFF strings and are not encoded in the font.
-function getCFFString(strings, index) {
-    if (index <= 390) {
-        index = cffStandardStrings[index];
-    } else {
-        index = strings[index - 391];
-    }
-
-    return index;
-}
-
-// Interpret a dictionary and return a new dictionary with readable keys and values for missing entries.
-// This function takes `meta` which is a list of objects containing `operand`, `name` and `default`.
-function interpretDict(dict, meta, strings) {
-    var newDict = {};
-    var value;
-
-    // Because we also want to include missing values, we start out from the meta list
-    // and lookup values in the dict.
-    for (var i = 0; i < meta.length; i += 1) {
-        var m = meta[i];
-
-        if (Array.isArray(m.type)) {
-            var values = [];
-            values.length = m.type.length;
-            for (var j = 0; j < m.type.length; j++) {
-                value = dict[m.op] !== undefined ? dict[m.op][j] : undefined;
-                if (value === undefined) {
-                    value = m.value !== undefined && m.value[j] !== undefined ? m.value[j] : null;
-                }
-                if (m.type[j] === 'SID') {
-                    value = getCFFString(strings, value);
-                }
-                values[j] = value;
-            }
-            newDict[m.name] = values;
-        } else {
-            value = dict[m.op];
-            if (value === undefined) {
-                value = m.value !== undefined ? m.value : null;
-            }
-
-            if (m.type === 'SID') {
-                value = getCFFString(strings, value);
-            }
-            newDict[m.name] = value;
-        }
-    }
-
-    return newDict;
-}
-
-// Parse the CFF header.
-function parseCFFHeader(data, start) {
-    var header = {};
-    header.formatMajor = parse.getCard8(data, start);
-    header.formatMinor = parse.getCard8(data, start + 1);
-    header.size = parse.getCard8(data, start + 2);
-    header.offsetSize = parse.getCard8(data, start + 3);
-    header.startOffset = start;
-    header.endOffset = start + 4;
-    return header;
-}
-
-var TOP_DICT_META = [
-    {name: 'version', op: 0, type: 'SID'},
-    {name: 'notice', op: 1, type: 'SID'},
-    {name: 'copyright', op: 1200, type: 'SID'},
-    {name: 'fullName', op: 2, type: 'SID'},
-    {name: 'familyName', op: 3, type: 'SID'},
-    {name: 'weight', op: 4, type: 'SID'},
-    {name: 'isFixedPitch', op: 1201, type: 'number', value: 0},
-    {name: 'italicAngle', op: 1202, type: 'number', value: 0},
-    {name: 'underlinePosition', op: 1203, type: 'number', value: -100},
-    {name: 'underlineThickness', op: 1204, type: 'number', value: 50},
-    {name: 'paintType', op: 1205, type: 'number', value: 0},
-    {name: 'charstringType', op: 1206, type: 'number', value: 2},
-    {
-        name: 'fontMatrix',
-        op: 1207,
-        type: ['real', 'real', 'real', 'real', 'real', 'real'],
-        value: [0.001, 0, 0, 0.001, 0, 0]
-    },
-    {name: 'uniqueId', op: 13, type: 'number'},
-    {name: 'fontBBox', op: 5, type: ['number', 'number', 'number', 'number'], value: [0, 0, 0, 0]},
-    {name: 'strokeWidth', op: 1208, type: 'number', value: 0},
-    {name: 'xuid', op: 14, type: [], value: null},
-    {name: 'charset', op: 15, type: 'offset', value: 0},
-    {name: 'encoding', op: 16, type: 'offset', value: 0},
-    {name: 'charStrings', op: 17, type: 'offset', value: 0},
-    {name: 'private', op: 18, type: ['number', 'offset'], value: [0, 0]},
-    {name: 'ros', op: 1230, type: ['SID', 'SID', 'number']},
-    {name: 'cidFontVersion', op: 1231, type: 'number', value: 0},
-    {name: 'cidFontRevision', op: 1232, type: 'number', value: 0},
-    {name: 'cidFontType', op: 1233, type: 'number', value: 0},
-    {name: 'cidCount', op: 1234, type: 'number', value: 8720},
-    {name: 'uidBase', op: 1235, type: 'number'},
-    {name: 'fdArray', op: 1236, type: 'offset'},
-    {name: 'fdSelect', op: 1237, type: 'offset'},
-    {name: 'fontName', op: 1238, type: 'SID'}
-];
-
-var PRIVATE_DICT_META = [
-    {name: 'subrs', op: 19, type: 'offset', value: 0},
-    {name: 'defaultWidthX', op: 20, type: 'number', value: 0},
-    {name: 'nominalWidthX', op: 21, type: 'number', value: 0}
-];
-
-// Parse the CFF top dictionary. A CFF table can contain multiple fonts, each with their own top dictionary.
-// The top dictionary contains the essential metadata for the font, together with the private dictionary.
-function parseCFFTopDict(data, strings) {
-    var dict = parseCFFDict(data, 0, data.byteLength);
-    return interpretDict(dict, TOP_DICT_META, strings);
-}
-
-// Parse the CFF private dictionary. We don't fully parse out all the values, only the ones we need.
-function parseCFFPrivateDict(data, start, size, strings) {
-    var dict = parseCFFDict(data, start, size);
-    return interpretDict(dict, PRIVATE_DICT_META, strings);
-}
-
-// Returns a list of "Top DICT"s found using an INDEX list.
-// Used to read both the usual high-level Top DICTs and also the FDArray
-// discovered inside CID-keyed fonts.  When a Top DICT has a reference to
-// a Private DICT that is read and saved into the Top DICT.
-//
-// In addition to the expected/optional values as outlined in TOP_DICT_META
-// the following values might be saved into the Top DICT.
-//
-//    _subrs []        array of local CFF subroutines from Private DICT
-//    _subrsBias       bias value computed from number of subroutines
-//                      (see calcCFFSubroutineBias() and parseCFFCharstring())
-//    _defaultWidthX   default widths for CFF characters
-//    _nominalWidthX   bias added to width embedded within glyph description
-//
-//    _privateDict     saved copy of parsed Private DICT from Top DICT
-function gatherCFFTopDicts(data, start, cffIndex, strings) {
-    var topDictArray = [];
-    for (var iTopDict = 0; iTopDict < cffIndex.length; iTopDict += 1) {
-        var topDictData = new DataView(new Uint8Array(cffIndex[iTopDict]).buffer);
-        var topDict = parseCFFTopDict(topDictData, strings);
-        topDict._subrs = [];
-        topDict._subrsBias = 0;
-        topDict._defaultWidthX = 0;
-        topDict._nominalWidthX = 0;
-        var privateSize = topDict.private[0];
-        var privateOffset = topDict.private[1];
-        if (privateSize !== 0 && privateOffset !== 0) {
-            var privateDict = parseCFFPrivateDict(data, privateOffset + start, privateSize, strings);
-            topDict._defaultWidthX = privateDict.defaultWidthX;
-            topDict._nominalWidthX = privateDict.nominalWidthX;
-            if (privateDict.subrs !== 0) {
-                var subrOffset = privateOffset + privateDict.subrs;
-                var subrIndex = parseCFFIndex(data, subrOffset + start);
-                topDict._subrs = subrIndex.objects;
-                topDict._subrsBias = calcCFFSubroutineBias(topDict._subrs);
-            }
-            topDict._privateDict = privateDict;
-        }
-        topDictArray.push(topDict);
-    }
-    return topDictArray;
-}
-
-// Parse the CFF charset table, which contains internal names for all the glyphs.
-// This function will return a list of glyph names.
-// See Adobe TN #5176 chapter 13, "Charsets".
-function parseCFFCharset(data, start, nGlyphs, strings) {
-    var sid;
-    var count;
-    var parser = new parse.Parser(data, start);
-
-    // The .notdef glyph is not included, so subtract 1.
-    nGlyphs -= 1;
-    var charset = ['.notdef'];
-
-    var format = parser.parseCard8();
-    if (format === 0) {
-        for (var i = 0; i < nGlyphs; i += 1) {
-            sid = parser.parseSID();
-            charset.push(getCFFString(strings, sid));
-        }
-    } else if (format === 1) {
-        while (charset.length <= nGlyphs) {
-            sid = parser.parseSID();
-            count = parser.parseCard8();
-            for (var i$1 = 0; i$1 <= count; i$1 += 1) {
-                charset.push(getCFFString(strings, sid));
-                sid += 1;
-            }
-        }
-    } else if (format === 2) {
-        while (charset.length <= nGlyphs) {
-            sid = parser.parseSID();
-            count = parser.parseCard16();
-            for (var i$2 = 0; i$2 <= count; i$2 += 1) {
-                charset.push(getCFFString(strings, sid));
-                sid += 1;
-            }
-        }
-    } else {
-        throw new Error('Unknown charset format ' + format);
-    }
-
-    return charset;
-}
-
-// Parse the CFF encoding data. Only one encoding can be specified per font.
-// See Adobe TN #5176 chapter 12, "Encodings".
-function parseCFFEncoding(data, start, charset) {
-    var code;
-    var enc = {};
-    var parser = new parse.Parser(data, start);
-    var format = parser.parseCard8();
-    if (format === 0) {
-        var nCodes = parser.parseCard8();
-        for (var i = 0; i < nCodes; i += 1) {
-            code = parser.parseCard8();
-            enc[code] = i;
-        }
-    } else if (format === 1) {
-        var nRanges = parser.parseCard8();
-        code = 1;
-        for (var i$1 = 0; i$1 < nRanges; i$1 += 1) {
-            var first = parser.parseCard8();
-            var nLeft = parser.parseCard8();
-            for (var j = first; j <= first + nLeft; j += 1) {
-                enc[j] = code;
-                code += 1;
-            }
-        }
-    } else {
-        throw new Error('Unknown encoding format ' + format);
-    }
-
-    return new CffEncoding(enc, charset);
-}
-
-// Take in charstring code and return a Glyph object.
-// The encoding is described in the Type 2 Charstring Format
-// https://www.microsoft.com/typography/OTSPEC/charstr2.htm
-function parseCFFCharstring(font, glyph, code) {
-    var c1x;
-    var c1y;
-    var c2x;
-    var c2y;
-    var p = new Path();
-    var stack = [];
-    var nStems = 0;
-    var haveWidth = false;
-    var open = false;
-    var x = 0;
-    var y = 0;
-    var subrs;
-    var subrsBias;
-    var defaultWidthX;
-    var nominalWidthX;
-    if (font.isCIDFont) {
-        var fdIndex = font.tables.cff.topDict._fdSelect[glyph.index];
-        var fdDict = font.tables.cff.topDict._fdArray[fdIndex];
-        subrs = fdDict._subrs;
-        subrsBias = fdDict._subrsBias;
-        defaultWidthX = fdDict._defaultWidthX;
-        nominalWidthX = fdDict._nominalWidthX;
-    } else {
-        subrs = font.tables.cff.topDict._subrs;
-        subrsBias = font.tables.cff.topDict._subrsBias;
-        defaultWidthX = font.tables.cff.topDict._defaultWidthX;
-        nominalWidthX = font.tables.cff.topDict._nominalWidthX;
-    }
-    var width = defaultWidthX;
-
-    function newContour(x, y) {
-        if (open) {
-            p.closePath();
-        }
-
-        p.moveTo(x, y);
-        open = true;
-    }
-
-    function parseStems() {
-        var hasWidthArg;
-
-        // The number of stem operators on the stack is always even.
-        // If the value is uneven, that means a width is specified.
-        hasWidthArg = stack.length % 2 !== 0;
-        if (hasWidthArg && !haveWidth) {
-            width = stack.shift() + nominalWidthX;
-        }
-
-        nStems += stack.length >> 1;
-        stack.length = 0;
-        haveWidth = true;
-    }
-
-    function parse(code) {
-        var b1;
-        var b2;
-        var b3;
-        var b4;
-        var codeIndex;
-        var subrCode;
-        var jpx;
-        var jpy;
-        var c3x;
-        var c3y;
-        var c4x;
-        var c4y;
-
-        var i = 0;
-        while (i < code.length) {
-            var v = code[i];
-            i += 1;
-            switch (v) {
-                case 1: // hstem
-                    parseStems();
-                    break;
-                case 3: // vstem
-                    parseStems();
-                    break;
-                case 4: // vmoveto
-                    if (stack.length > 1 && !haveWidth) {
-                        width = stack.shift() + nominalWidthX;
-                        haveWidth = true;
-                    }
-
-                    y += stack.pop();
-                    newContour(x, y);
-                    break;
-                case 5: // rlineto
-                    while (stack.length > 0) {
-                        x += stack.shift();
-                        y += stack.shift();
-                        p.lineTo(x, y);
-                    }
-
-                    break;
-                case 6: // hlineto
-                    while (stack.length > 0) {
-                        x += stack.shift();
-                        p.lineTo(x, y);
-                        if (stack.length === 0) {
-                            break;
-                        }
-
-                        y += stack.shift();
-                        p.lineTo(x, y);
-                    }
-
-                    break;
-                case 7: // vlineto
-                    while (stack.length > 0) {
-                        y += stack.shift();
-                        p.lineTo(x, y);
-                        if (stack.length === 0) {
-                            break;
-                        }
-
-                        x += stack.shift();
-                        p.lineTo(x, y);
-                    }
-
-                    break;
-                case 8: // rrcurveto
-                    while (stack.length > 0) {
-                        c1x = x + stack.shift();
-                        c1y = y + stack.shift();
-                        c2x = c1x + stack.shift();
-                        c2y = c1y + stack.shift();
-                        x = c2x + stack.shift();
-                        y = c2y + stack.shift();
-                        p.curveTo(c1x, c1y, c2x, c2y, x, y);
-                    }
-
-                    break;
-                case 10: // callsubr
-                    codeIndex = stack.pop() + subrsBias;
-                    subrCode = subrs[codeIndex];
-                    if (subrCode) {
-                        parse(subrCode);
-                    }
-
-                    break;
-                case 11: // return
-                    return;
-                case 12: // flex operators
-                    v = code[i];
-                    i += 1;
-                    switch (v) {
-                        case 35: // flex
-                            // |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 dx6 dy6 fd flex (12 35) |-
-                            c1x = x   + stack.shift();    // dx1
-                            c1y = y   + stack.shift();    // dy1
-                            c2x = c1x + stack.shift();    // dx2
-                            c2y = c1y + stack.shift();    // dy2
-                            jpx = c2x + stack.shift();    // dx3
-                            jpy = c2y + stack.shift();    // dy3
-                            c3x = jpx + stack.shift();    // dx4
-                            c3y = jpy + stack.shift();    // dy4
-                            c4x = c3x + stack.shift();    // dx5
-                            c4y = c3y + stack.shift();    // dy5
-                            x = c4x   + stack.shift();    // dx6
-                            y = c4y   + stack.shift();    // dy6
-                            stack.shift();                // flex depth
-                            p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy);
-                            p.curveTo(c3x, c3y, c4x, c4y, x, y);
-                            break;
-                        case 34: // hflex
-                            // |- dx1 dx2 dy2 dx3 dx4 dx5 dx6 hflex (12 34) |-
-                            c1x = x   + stack.shift();    // dx1
-                            c1y = y;                      // dy1
-                            c2x = c1x + stack.shift();    // dx2
-                            c2y = c1y + stack.shift();    // dy2
-                            jpx = c2x + stack.shift();    // dx3
-                            jpy = c2y;                    // dy3
-                            c3x = jpx + stack.shift();    // dx4
-                            c3y = c2y;                    // dy4
-                            c4x = c3x + stack.shift();    // dx5
-                            c4y = y;                      // dy5
-                            x = c4x + stack.shift();      // dx6
-                            p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy);
-                            p.curveTo(c3x, c3y, c4x, c4y, x, y);
-                            break;
-                        case 36: // hflex1
-                            // |- dx1 dy1 dx2 dy2 dx3 dx4 dx5 dy5 dx6 hflex1 (12 36) |-
-                            c1x = x   + stack.shift();    // dx1
-                            c1y = y   + stack.shift();    // dy1
-                            c2x = c1x + stack.shift();    // dx2
-                            c2y = c1y + stack.shift();    // dy2
-                            jpx = c2x + stack.shift();    // dx3
-                            jpy = c2y;                    // dy3
-                            c3x = jpx + stack.shift();    // dx4
-                            c3y = c2y;                    // dy4
-                            c4x = c3x + stack.shift();    // dx5
-                            c4y = c3y + stack.shift();    // dy5
-                            x = c4x + stack.shift();      // dx6
-                            p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy);
-                            p.curveTo(c3x, c3y, c4x, c4y, x, y);
-                            break;
-                        case 37: // flex1
-                            // |- dx1 dy1 dx2 dy2 dx3 dy3 dx4 dy4 dx5 dy5 d6 flex1 (12 37) |-
-                            c1x = x   + stack.shift();    // dx1
-                            c1y = y   + stack.shift();    // dy1
-                            c2x = c1x + stack.shift();    // dx2
-                            c2y = c1y + stack.shift();    // dy2
-                            jpx = c2x + stack.shift();    // dx3
-                            jpy = c2y + stack.shift();    // dy3
-                            c3x = jpx + stack.shift();    // dx4
-                            c3y = jpy + stack.shift();    // dy4
-                            c4x = c3x + stack.shift();    // dx5
-                            c4y = c3y + stack.shift();    // dy5
-                            if (Math.abs(c4x - x) > Math.abs(c4y - y)) {
-                                x = c4x + stack.shift();
-                            } else {
-                                y = c4y + stack.shift();
-                            }
-
-                            p.curveTo(c1x, c1y, c2x, c2y, jpx, jpy);
-                            p.curveTo(c3x, c3y, c4x, c4y, x, y);
-                            break;
-                        default:
-                            console.log('Glyph ' + glyph.index + ': unknown operator ' + 1200 + v);
-                            stack.length = 0;
-                    }
-                    break;
-                case 14: // endchar
-                    if (stack.length > 0 && !haveWidth) {
-                        width = stack.shift() + nominalWidthX;
-                        haveWidth = true;
-                    }
-
-                    if (open) {
-                        p.closePath();
-                        open = false;
-                    }
-
-                    break;
-                case 18: // hstemhm
-                    parseStems();
-                    break;
-                case 19: // hintmask
-                case 20: // cntrmask
-                    parseStems();
-                    i += (nStems + 7) >> 3;
-                    break;
-                case 21: // rmoveto
-                    if (stack.length > 2 && !haveWidth) {
-                        width = stack.shift() + nominalWidthX;
-                        haveWidth = true;
-                    }
-
-                    y += stack.pop();
-                    x += stack.pop();
-                    newContour(x, y);
-                    break;
-                case 22: // hmoveto
-                    if (stack.length > 1 && !haveWidth) {
-                        width = stack.shift() + nominalWidthX;
-                        haveWidth = true;
-                    }
-
-                    x += stack.pop();
-                    newContour(x, y);
-                    break;
-                case 23: // vstemhm
-                    parseStems();
-                    break;
-                case 24: // rcurveline
-                    while (stack.length > 2) {
-                        c1x = x + stack.shift();
-                        c1y = y + stack.shift();
-                        c2x = c1x + stack.shift();
-                        c2y = c1y + stack.shift();
-                        x = c2x + stack.shift();
-                        y = c2y + stack.shift();
-                        p.curveTo(c1x, c1y, c2x, c2y, x, y);
-                    }
-
-                    x += stack.shift();
-                    y += stack.shift();
-                    p.lineTo(x, y);
-                    break;
-                case 25: // rlinecurve
-                    while (stack.length > 6) {
-                        x += stack.shift();
-                        y += stack.shift();
-                        p.lineTo(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();
-                    p.curveTo(c1x, c1y, c2x, c2y, x, y);
-                    break;
-                case 26: // vvcurveto
-                    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();
-                        p.curveTo(c1x, c1y, c2x, c2y, x, y);
-                    }
-
-                    break;
-                case 27: // hhcurveto
-                    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;
-                        p.curveTo(c1x, c1y, c2x, c2y, x, y);
-                    }
-
-                    break;
-                case 28: // shortint
-                    b1 = code[i];
-                    b2 = code[i + 1];
-                    stack.push(((b1 << 24) | (b2 << 16)) >> 16);
-                    i += 2;
-                    break;
-                case 29: // callgsubr
-                    codeIndex = stack.pop() + font.gsubrsBias;
-                    subrCode = font.gsubrs[codeIndex];
-                    if (subrCode) {
-                        parse(subrCode);
-                    }
-
-                    break;
-                case 30: // vhcurveto
-                    while (stack.length > 0) {
-                        c1x = x;
-                        c1y = y + stack.shift();
-                        c2x = c1x + stack.shift();
-                        c2y = c1y + stack.shift();
-                        x = c2x + stack.shift();
-                        y = c2y + (stack.length === 1 ? stack.shift() : 0);
-                        p.curveTo(c1x, c1y, c2x, c2y, x, y);
-                        if (stack.length === 0) {
-                            break;
-                        }
-
-                        c1x = x + stack.shift();
-                        c1y = y;
-                        c2x = c1x + stack.shift();
-                        c2y = c1y + stack.shift();
-                        y = c2y + stack.shift();
-                        x = c2x + (stack.length === 1 ? stack.shift() : 0);
-                        p.curveTo(c1x, c1y, c2x, c2y, x, y);
-                    }
-
-                    break;
-                case 31: // hvcurveto
-                    while (stack.length > 0) {
-                        c1x = x + stack.shift();
-                        c1y = y;
-                        c2x = c1x + stack.shift();
-                        c2y = c1y + stack.shift();
-                        y = c2y + stack.shift();
-                        x = c2x + (stack.length === 1 ? stack.shift() : 0);
-                        p.curveTo(c1x, c1y, c2x, c2y, x, y);
-                        if (stack.length === 0) {
-                            break;
-                        }
-
-                        c1x = x;
-                        c1y = y + stack.shift();
-                        c2x = c1x + stack.shift();
-                        c2y = c1y + stack.shift();
-                        x = c2x + stack.shift();
-                        y = c2y + (stack.length === 1 ? stack.shift() : 0);
-                        p.curveTo(c1x, c1y, c2x, c2y, x, y);
-                    }
-
-                    break;
-                default:
-                    if (v < 32) {
-                        console.log('Glyph ' + glyph.index + ': unknown operator ' + v);
-                    } else if (v < 247) {
-                        stack.push(v - 139);
-                    } else if (v < 251) {
-                        b1 = code[i];
-                        i += 1;
-                        stack.push((v - 247) * 256 + b1 + 108);
-                    } else if (v < 255) {
-                        b1 = code[i];
-                        i += 1;
-                        stack.push(-(v - 251) * 256 - b1 - 108);
-                    } else {
-                        b1 = code[i];
-                        b2 = code[i + 1];
-                        b3 = code[i + 2];
-                        b4 = code[i + 3];
-                        i += 4;
-                        stack.push(((b1 << 24) | (b2 << 16) | (b3 << 8) | b4) / 65536);
-                    }
-            }
-        }
-    }
-
-    parse(code);
-
-    glyph.advanceWidth = width;
-    return p;
-}
-
-function parseCFFFDSelect(data, start, nGlyphs, fdArrayCount) {
-    var fdSelect = [];
-    var fdIndex;
-    var parser = new parse.Parser(data, start);
-    var format = parser.parseCard8();
-    if (format === 0) {
-        // Simple list of nGlyphs elements
-        for (var iGid = 0; iGid < nGlyphs; iGid++) {
-            fdIndex = parser.parseCard8();
-            if (fdIndex >= fdArrayCount) {
-                throw new Error('CFF table CID Font FDSelect has bad FD index value ' + fdIndex + ' (FD count ' + fdArrayCount + ')');
-            }
-            fdSelect.push(fdIndex);
-        }
-    } else if (format === 3) {
-        // Ranges
-        var nRanges = parser.parseCard16();
-        var first = parser.parseCard16();
-        if (first !== 0) {
-            throw new Error('CFF Table CID Font FDSelect format 3 range has bad initial GID ' + first);
-        }
-        var next;
-        for (var iRange = 0; iRange < nRanges; iRange++) {
-            fdIndex = parser.parseCard8();
-            next = parser.parseCard16();
-            if (fdIndex >= fdArrayCount) {
-                throw new Error('CFF table CID Font FDSelect has bad FD index value ' + fdIndex + ' (FD count ' + fdArrayCount + ')');
-            }
-            if (next > nGlyphs) {
-                throw new Error('CFF Table CID Font FDSelect format 3 range has bad GID ' + next);
-            }
-            for (; first < next; first++) {
-                fdSelect.push(fdIndex);
-            }
-            first = next;
-        }
-        if (next !== nGlyphs) {
-            throw new Error('CFF Table CID Font FDSelect format 3 range has bad final GID ' + next);
-        }
-    } else {
-        throw new Error('CFF Table CID Font FDSelect table has unsupported format ' + format);
-    }
-    return fdSelect;
-}
-
-// Parse the `CFF` table, which contains the glyph outlines in PostScript format.
-function parseCFFTable(data, start, font, opt) {
-    font.tables.cff = {};
-    var header = parseCFFHeader(data, start);
-    var nameIndex = parseCFFIndex(data, header.endOffset, parse.bytesToString);
-    var topDictIndex = parseCFFIndex(data, nameIndex.endOffset);
-    var stringIndex = parseCFFIndex(data, topDictIndex.endOffset, parse.bytesToString);
-    var globalSubrIndex = parseCFFIndex(data, stringIndex.endOffset);
-    font.gsubrs = globalSubrIndex.objects;
-    font.gsubrsBias = calcCFFSubroutineBias(font.gsubrs);
-
-    var topDictArray = gatherCFFTopDicts(data, start, topDictIndex.objects, stringIndex.objects);
-    if (topDictArray.length !== 1) {
-        throw new Error('CFF table has too many fonts in \'FontSet\' - count of fonts NameIndex.length = ' + topDictArray.length);
-    }
-
-    var topDict = topDictArray[0];
-    font.tables.cff.topDict = topDict;
-
-    if (topDict._privateDict) {
-        font.defaultWidthX = topDict._privateDict.defaultWidthX;
-        font.nominalWidthX = topDict._privateDict.nominalWidthX;
-    }
-
-    if (topDict.ros[0] !== undefined && topDict.ros[1] !== undefined) {
-        font.isCIDFont = true;
-    }
-
-    if (font.isCIDFont) {
-        var fdArrayOffset = topDict.fdArray;
-        var fdSelectOffset = topDict.fdSelect;
-        if (fdArrayOffset === 0 || fdSelectOffset === 0) {
-            throw new Error('Font is marked as a CID font, but FDArray and/or FDSelect information is missing');
-        }
-        fdArrayOffset += start;
-        var fdArrayIndex = parseCFFIndex(data, fdArrayOffset);
-        var fdArray = gatherCFFTopDicts(data, start, fdArrayIndex.objects, stringIndex.objects);
-        topDict._fdArray = fdArray;
-        fdSelectOffset += start;
-        topDict._fdSelect = parseCFFFDSelect(data, fdSelectOffset, font.numGlyphs, fdArray.length);
-    }
-
-    var privateDictOffset = start + topDict.private[1];
-    var privateDict = parseCFFPrivateDict(data, privateDictOffset, topDict.private[0], stringIndex.objects);
-    font.defaultWidthX = privateDict.defaultWidthX;
-    font.nominalWidthX = privateDict.nominalWidthX;
-
-    if (privateDict.subrs !== 0) {
-        var subrOffset = privateDictOffset + privateDict.subrs;
-        var subrIndex = parseCFFIndex(data, subrOffset);
-        font.subrs = subrIndex.objects;
-        font.subrsBias = calcCFFSubroutineBias(font.subrs);
-    } else {
-        font.subrs = [];
-        font.subrsBias = 0;
-    }
-
-    // Offsets in the top dict are relative to the beginning of the CFF data, so add the CFF start offset.
-    var charStringsIndex;
-    if (opt.lowMemory) {
-        charStringsIndex = parseCFFIndexLowMemory(data, start + topDict.charStrings);
-        font.nGlyphs = charStringsIndex.offsets.length;
-    } else {
-        charStringsIndex = parseCFFIndex(data, start + topDict.charStrings);
-        font.nGlyphs = charStringsIndex.objects.length;
-    }
-
-    var charset = parseCFFCharset(data, start + topDict.charset, font.nGlyphs, stringIndex.objects);
-    if (topDict.encoding === 0) {
-        // Standard encoding
-        font.cffEncoding = new CffEncoding(cffStandardEncoding, charset);
-    } else if (topDict.encoding === 1) {
-        // Expert encoding
-        font.cffEncoding = new CffEncoding(cffExpertEncoding, charset);
-    } else {
-        font.cffEncoding = parseCFFEncoding(data, start + topDict.encoding, charset);
-    }
-
-    // Prefer the CMAP encoding to the CFF encoding.
-    font.encoding = font.encoding || font.cffEncoding;
-
-    font.glyphs = new glyphset.GlyphSet(font);
-    if (opt.lowMemory) {
-        font._push = function(i) {
-            var charString = getCffIndexObject(i, charStringsIndex.offsets, data, start + topDict.charStrings);
-            font.glyphs.push(i, glyphset.cffGlyphLoader(font, i, parseCFFCharstring, charString));
-        };
-    } else {
-        for (var i = 0; i < font.nGlyphs; i += 1) {
-            var charString = charStringsIndex.objects[i];
-            font.glyphs.push(i, glyphset.cffGlyphLoader(font, i, parseCFFCharstring, charString));
-        }
-    }
-}
-
-// Convert a string to a String ID (SID).
-// The list of strings is modified in place.
-function encodeString(s, strings) {
-    var sid;
-
-    // Is the string in the CFF standard strings?
-    var i = cffStandardStrings.indexOf(s);
-    if (i >= 0) {
-        sid = i;
-    }
-
-    // Is the string already in the string index?
-    i = strings.indexOf(s);
-    if (i >= 0) {
-        sid = i + cffStandardStrings.length;
-    } else {
-        sid = cffStandardStrings.length + strings.length;
-        strings.push(s);
-    }
-
-    return sid;
-}
-
-function makeHeader() {
-    return new table.Record('Header', [
-        {name: 'major', type: 'Card8', value: 1},
-        {name: 'minor', type: 'Card8', value: 0},
-        {name: 'hdrSize', type: 'Card8', value: 4},
-        {name: 'major', type: 'Card8', value: 1}
-    ]);
-}
-
-function makeNameIndex(fontNames) {
-    var t = new table.Record('Name INDEX', [
-        {name: 'names', type: 'INDEX', value: []}
-    ]);
-    t.names = [];
-    for (var i = 0; i < fontNames.length; i += 1) {
-        t.names.push({name: 'name_' + i, type: 'NAME', value: fontNames[i]});
-    }
-
-    return t;
-}
-
-// Given a dictionary's metadata, create a DICT structure.
-function makeDict(meta, attrs, strings) {
-    var m = {};
-    for (var i = 0; i < meta.length; i += 1) {
-        var entry = meta[i];
-        var value = attrs[entry.name];
-        if (value !== undefined && !equals(value, entry.value)) {
-            if (entry.type === 'SID') {
-                value = encodeString(value, strings);
-            }
-
-            m[entry.op] = {name: entry.name, type: entry.type, value: value};
-        }
-    }
-
-    return m;
-}
-
-// The Top DICT houses the global font attributes.
-function makeTopDict(attrs, strings) {
-    var t = new table.Record('Top DICT', [
-        {name: 'dict', type: 'DICT', value: {}}
-    ]);
-    t.dict = makeDict(TOP_DICT_META, attrs, strings);
-    return t;
-}
-
-function makeTopDictIndex(topDict) {
-    var t = new table.Record('Top DICT INDEX', [
-        {name: 'topDicts', type: 'INDEX', value: []}
-    ]);
-    t.topDicts = [{name: 'topDict_0', type: 'TABLE', value: topDict}];
-    return t;
-}
-
-function makeStringIndex(strings) {
-    var t = new table.Record('String INDEX', [
-        {name: 'strings', type: 'INDEX', value: []}
-    ]);
-    t.strings = [];
-    for (var i = 0; i < strings.length; i += 1) {
-        t.strings.push({name: 'string_' + i, type: 'STRING', value: strings[i]});
-    }
-
-    return t;
-}
-
-function makeGlobalSubrIndex() {
-    // Currently we don't use subroutines.
-    return new table.Record('Global Subr INDEX', [
-        {name: 'subrs', type: 'INDEX', value: []}
-    ]);
-}
-
-function makeCharsets(glyphNames, strings) {
-    var t = new table.Record('Charsets', [
-        {name: 'format', type: 'Card8', value: 0}
-    ]);
-    for (var i = 0; i < glyphNames.length; i += 1) {
-        var glyphName = glyphNames[i];
-        var glyphSID = encodeString(glyphName, strings);
-        t.fields.push({name: 'glyph_' + i, type: 'SID', value: glyphSID});
-    }
-
-    return t;
-}
-
-function glyphToOps(glyph) {
-    var ops = [];
-    var path = glyph.path;
-    ops.push({name: 'width', type: 'NUMBER', value: glyph.advanceWidth});
-    var x = 0;
-    var y = 0;
-    for (var i = 0; i < path.commands.length; i += 1) {
-        var dx = (void 0);
-        var dy = (void 0);
-        var cmd = path.commands[i];
-        if (cmd.type === 'Q') {
-            // CFF only supports bézier curves, so convert the quad to a bézier.
-            var _13 = 1 / 3;
-            var _23 = 2 / 3;
-
-            // We're going to create a new command so we don't change the original path.
-            // Since all coordinates are relative, we round() them ASAP to avoid propagating errors.
-            cmd = {
-                type: 'C',
-                x: cmd.x,
-                y: cmd.y,
-                x1: Math.round(_13 * x + _23 * cmd.x1),
-                y1: Math.round(_13 * y + _23 * cmd.y1),
-                x2: Math.round(_13 * cmd.x + _23 * cmd.x1),
-                y2: Math.round(_13 * cmd.y + _23 * cmd.y1)
-            };
-        }
-
-        if (cmd.type === 'M') {
-            dx = Math.round(cmd.x - x);
-            dy = Math.round(cmd.y - y);
-            ops.push({name: 'dx', type: 'NUMBER', value: dx});
-            ops.push({name: 'dy', type: 'NUMBER', value: dy});
-            ops.push({name: 'rmoveto', type: 'OP', value: 21});
-            x = Math.round(cmd.x);
-            y = Math.round(cmd.y);
-        } else if (cmd.type === 'L') {
-            dx = Math.round(cmd.x - x);
-            dy = Math.round(cmd.y - y);
-            ops.push({name: 'dx', type: 'NUMBER', value: dx});
-            ops.push({name: 'dy', type: 'NUMBER', value: dy});
-            ops.push({name: 'rlineto', type: 'OP', value: 5});
-            x = Math.round(cmd.x);
-            y = Math.round(cmd.y);
-        } else if (cmd.type === 'C') {
-            var dx1 = Math.round(cmd.x1 - x);
-            var dy1 = Math.round(cmd.y1 - y);
-            var dx2 = Math.round(cmd.x2 - cmd.x1);
-            var dy2 = Math.round(cmd.y2 - cmd.y1);
-            dx = Math.round(cmd.x - cmd.x2);
-            dy = Math.round(cmd.y - cmd.y2);
-            ops.push({name: 'dx1', type: 'NUMBER', value: dx1});
-            ops.push({name: 'dy1', type: 'NUMBER', value: dy1});
-            ops.push({name: 'dx2', type: 'NUMBER', value: dx2});
-            ops.push({name: 'dy2', type: 'NUMBER', value: dy2});
-            ops.push({name: 'dx', type: 'NUMBER', value: dx});
-            ops.push({name: 'dy', type: 'NUMBER', value: dy});
-            ops.push({name: 'rrcurveto', type: 'OP', value: 8});
-            x = Math.round(cmd.x);
-            y = Math.round(cmd.y);
-        }
-
-        // Contours are closed automatically.
-    }
-
-    ops.push({name: 'endchar', type: 'OP', value: 14});
-    return ops;
-}
-
-function makeCharStringsIndex(glyphs) {
-    var t = new table.Record('CharStrings INDEX', [
-        {name: 'charStrings', type: 'INDEX', value: []}
-    ]);
-
-    for (var i = 0; i < glyphs.length; i += 1) {
-        var glyph = glyphs.get(i);
-        var ops = glyphToOps(glyph);
-        t.charStrings.push({name: glyph.name, type: 'CHARSTRING', value: ops});
-    }
-
-    return t;
-}
-
-function makePrivateDict(attrs, strings) {
-    var t = new table.Record('Private DICT', [
-        {name: 'dict', type: 'DICT', value: {}}
-    ]);
-    t.dict = makeDict(PRIVATE_DICT_META, attrs, strings);
-    return t;
-}
-
-function makeCFFTable(glyphs, options) {
-    var t = new table.Table('CFF ', [
-        {name: 'header', type: 'RECORD'},
-        {name: 'nameIndex', type: 'RECORD'},
-        {name: 'topDictIndex', type: 'RECORD'},
-        {name: 'stringIndex', type: 'RECORD'},
-        {name: 'globalSubrIndex', type: 'RECORD'},
-        {name: 'charsets', type: 'RECORD'},
-        {name: 'charStringsIndex', type: 'RECORD'},
-        {name: 'privateDict', type: 'RECORD'}
-    ]);
-
-    var fontScale = 1 / options.unitsPerEm;
-    // We use non-zero values for the offsets so that the DICT encodes them.
-    // This is important because the size of the Top DICT plays a role in offset calculation,
-    // and the size shouldn't change after we've written correct offsets.
-    var attrs = {
-        version: options.version,
-        fullName: options.fullName,
-        familyName: options.familyName,
-        weight: options.weightName,
-        fontBBox: options.fontBBox || [0, 0, 0, 0],
-        fontMatrix: [fontScale, 0, 0, fontScale, 0, 0],
-        charset: 999,
-        encoding: 0,
-        charStrings: 999,
-        private: [0, 999]
-    };
-
-    var privateAttrs = {};
-
-    var glyphNames = [];
-    var glyph;
-
-    // Skip first glyph (.notdef)
-    for (var i = 1; i < glyphs.length; i += 1) {
-        glyph = glyphs.get(i);
-        glyphNames.push(glyph.name);
-    }
-
-    var strings = [];
-
-    t.header = makeHeader();
-    t.nameIndex = makeNameIndex([options.postScriptName]);
-    var topDict = makeTopDict(attrs, strings);
-    t.topDictIndex = makeTopDictIndex(topDict);
-    t.globalSubrIndex = makeGlobalSubrIndex();
-    t.charsets = makeCharsets(glyphNames, strings);
-    t.charStringsIndex = makeCharStringsIndex(glyphs);
-    t.privateDict = makePrivateDict(privateAttrs, strings);
-
-    // Needs to come at the end, to encode all custom strings used in the font.
-    t.stringIndex = makeStringIndex(strings);
-
-    var startOffset = t.header.sizeOf() +
-        t.nameIndex.sizeOf() +
-        t.topDictIndex.sizeOf() +
-        t.stringIndex.sizeOf() +
-        t.globalSubrIndex.sizeOf();
-    attrs.charset = startOffset;
-
-    // We use the CFF standard encoding; proper encoding will be handled in cmap.
-    attrs.encoding = 0;
-    attrs.charStrings = attrs.charset + t.charsets.sizeOf();
-    attrs.private[1] = attrs.charStrings + t.charStringsIndex.sizeOf();
-
-    // Recreate the Top DICT INDEX with the correct offsets.
-    topDict = makeTopDict(attrs, strings);
-    t.topDictIndex = makeTopDictIndex(topDict);
-
-    return t;
-}
-
-var cff = { parse: parseCFFTable, make: makeCFFTable };
-
-// The `head` table contains global information about the font.
-
-// Parse the header `head` table
-function parseHeadTable(data, start) {
-    var head = {};
-    var p = new parse.Parser(data, start);
-    head.version = p.parseVersion();
-    head.fontRevision = Math.round(p.parseFixed() * 1000) / 1000;
-    head.checkSumAdjustment = p.parseULong();
-    head.magicNumber = p.parseULong();
-    check.argument(head.magicNumber === 0x5F0F3CF5, 'Font header has wrong magic number.');
-    head.flags = p.parseUShort();
-    head.unitsPerEm = p.parseUShort();
-    head.created = p.parseLongDateTime();
-    head.modified = p.parseLongDateTime();
-    head.xMin = p.parseShort();
-    head.yMin = p.parseShort();
-    head.xMax = p.parseShort();
-    head.yMax = p.parseShort();
-    head.macStyle = p.parseUShort();
-    head.lowestRecPPEM = p.parseUShort();
-    head.fontDirectionHint = p.parseShort();
-    head.indexToLocFormat = p.parseShort();
-    head.glyphDataFormat = p.parseShort();
-    return head;
-}
-
-function makeHeadTable(options) {
-    // Apple Mac timestamp epoch is 01/01/1904 not 01/01/1970
-    var timestamp = Math.round(new Date().getTime() / 1000) + 2082844800;
-    var createdTimestamp = timestamp;
-
-    if (options.createdTimestamp) {
-        createdTimestamp = options.createdTimestamp + 2082844800;
-    }
-
-    return new table.Table('head', [
-        {name: 'version', type: 'FIXED', value: 0x00010000},
-        {name: 'fontRevision', type: 'FIXED', value: 0x00010000},
-        {name: 'checkSumAdjustment', type: 'ULONG', value: 0},
-        {name: 'magicNumber', type: 'ULONG', value: 0x5F0F3CF5},
-        {name: 'flags', type: 'USHORT', value: 0},
-        {name: 'unitsPerEm', type: 'USHORT', value: 1000},
-        {name: 'created', type: 'LONGDATETIME', value: createdTimestamp},
-        {name: 'modified', type: 'LONGDATETIME', value: timestamp},
-        {name: 'xMin', type: 'SHORT', value: 0},
-        {name: 'yMin', type: 'SHORT', value: 0},
-        {name: 'xMax', type: 'SHORT', value: 0},
-        {name: 'yMax', type: 'SHORT', value: 0},
-        {name: 'macStyle', type: 'USHORT', value: 0},
-        {name: 'lowestRecPPEM', type: 'USHORT', value: 0},
-        {name: 'fontDirectionHint', type: 'SHORT', value: 2},
-        {name: 'indexToLocFormat', type: 'SHORT', value: 0},
-        {name: 'glyphDataFormat', type: 'SHORT', value: 0}
-    ], options);
-}
-
-var head = { parse: parseHeadTable, make: makeHeadTable };
-
-// The `hhea` table contains information for horizontal layout.
-
-// Parse the horizontal header `hhea` table
-function parseHheaTable(data, start) {
-    var hhea = {};
-    var p = new parse.Parser(data, start);
-    hhea.version = p.parseVersion();
-    hhea.ascender = p.parseShort();
-    hhea.descender = p.parseShort();
-    hhea.lineGap = p.parseShort();
-    hhea.advanceWidthMax = p.parseUShort();
-    hhea.minLeftSideBearing = p.parseShort();
-    hhea.minRightSideBearing = p.parseShort();
-    hhea.xMaxExtent = p.parseShort();
-    hhea.caretSlopeRise = p.parseShort();
-    hhea.caretSlopeRun = p.parseShort();
-    hhea.caretOffset = p.parseShort();
-    p.relativeOffset += 8;
-    hhea.metricDataFormat = p.parseShort();
-    hhea.numberOfHMetrics = p.parseUShort();
-    return hhea;
-}
-
-function makeHheaTable(options) {
-    return new table.Table('hhea', [
-        {name: 'version', type: 'FIXED', value: 0x00010000},
-        {name: 'ascender', type: 'FWORD', value: 0},
-        {name: 'descender', type: 'FWORD', value: 0},
-        {name: 'lineGap', type: 'FWORD', value: 0},
-        {name: 'advanceWidthMax', type: 'UFWORD', value: 0},
-        {name: 'minLeftSideBearing', type: 'FWORD', value: 0},
-        {name: 'minRightSideBearing', type: 'FWORD', value: 0},
-        {name: 'xMaxExtent', type: 'FWORD', value: 0},
-        {name: 'caretSlopeRise', type: 'SHORT', value: 1},
-        {name: 'caretSlopeRun', type: 'SHORT', value: 0},
-        {name: 'caretOffset', type: 'SHORT', value: 0},
-        {name: 'reserved1', type: 'SHORT', value: 0},
-        {name: 'reserved2', type: 'SHORT', value: 0},
-        {name: 'reserved3', type: 'SHORT', value: 0},
-        {name: 'reserved4', type: 'SHORT', value: 0},
-        {name: 'metricDataFormat', type: 'SHORT', value: 0},
-        {name: 'numberOfHMetrics', type: 'USHORT', value: 0}
-    ], options);
-}
-
-var hhea = { parse: parseHheaTable, make: makeHheaTable };
-
-// The `hmtx` table contains the horizontal metrics for all glyphs.
-
-function parseHmtxTableAll(data, start, numMetrics, numGlyphs, glyphs) {
-    var advanceWidth;
-    var leftSideBearing;
-    var p = new parse.Parser(data, start);
-    for (var i = 0; i < numGlyphs; i += 1) {
-        // If the font is monospaced, only one entry is needed. This last entry applies to all subsequent glyphs.
-        if (i < numMetrics) {
-            advanceWidth = p.parseUShort();
-            leftSideBearing = p.parseShort();
-        }
-
-        var glyph = glyphs.get(i);
-        glyph.advanceWidth = advanceWidth;
-        glyph.leftSideBearing = leftSideBearing;
-    }
-}
-
-function parseHmtxTableOnLowMemory(font, data, start, numMetrics, numGlyphs) {
-    font._hmtxTableData = {};
-
-    var advanceWidth;
-    var leftSideBearing;
-    var p = new parse.Parser(data, start);
-    for (var i = 0; i < numGlyphs; i += 1) {
-        // If the font is monospaced, only one entry is needed. This last entry applies to all subsequent glyphs.
-        if (i < numMetrics) {
-            advanceWidth = p.parseUShort();
-            leftSideBearing = p.parseShort();
-        }
-
-        font._hmtxTableData[i] = {
-            advanceWidth: advanceWidth,
-            leftSideBearing: leftSideBearing
-        };
-    }
-}
-
-// Parse the `hmtx` table, which contains the horizontal metrics for all glyphs.
-// This function augments the glyph array, adding the advanceWidth and leftSideBearing to each glyph.
-function parseHmtxTable(font, data, start, numMetrics, numGlyphs, glyphs, opt) {
-    if (opt.lowMemory)
-        { parseHmtxTableOnLowMemory(font, data, start, numMetrics, numGlyphs); }
-    else
-        { parseHmtxTableAll(data, start, numMetrics, numGlyphs, glyphs); }
-}
-
-function makeHmtxTable(glyphs) {
-    var t = new table.Table('hmtx', []);
-    for (var i = 0; i < glyphs.length; i += 1) {
-        var glyph = glyphs.get(i);
-        var advanceWidth = glyph.advanceWidth || 0;
-        var leftSideBearing = glyph.leftSideBearing || 0;
-        t.fields.push({name: 'advanceWidth_' + i, type: 'USHORT', value: advanceWidth});
-        t.fields.push({name: 'leftSideBearing_' + i, type: 'SHORT', value: leftSideBearing});
-    }
-
-    return t;
-}
-
-var hmtx = { parse: parseHmtxTable, make: makeHmtxTable };
-
-// The `ltag` table stores IETF BCP-47 language tags. It allows supporting
-
-function makeLtagTable(tags) {
-    var result = new table.Table('ltag', [
-        {name: 'version', type: 'ULONG', value: 1},
-        {name: 'flags', type: 'ULONG', value: 0},
-        {name: 'numTags', type: 'ULONG', value: tags.length}
-    ]);
-
-    var stringPool = '';
-    var stringPoolOffset = 12 + tags.length * 4;
-    for (var i = 0; i < tags.length; ++i) {
-        var pos = stringPool.indexOf(tags[i]);
-        if (pos < 0) {
-            pos = stringPool.length;
-            stringPool += tags[i];
-        }
-
-        result.fields.push({name: 'offset ' + i, type: 'USHORT', value: stringPoolOffset + pos});
-        result.fields.push({name: 'length ' + i, type: 'USHORT', value: tags[i].length});
-    }
-
-    result.fields.push({name: 'stringPool', type: 'CHARARRAY', value: stringPool});
-    return result;
-}
-
-function parseLtagTable(data, start) {
-    var p = new parse.Parser(data, start);
-    var tableVersion = p.parseULong();
-    check.argument(tableVersion === 1, 'Unsupported ltag table version.');
-    // The 'ltag' specification does not define any flags; skip the field.
-    p.skip('uLong', 1);
-    var numTags = p.parseULong();
-
-    var tags = [];
-    for (var i = 0; i < numTags; i++) {
-        var tag = '';
-        var offset = start + p.parseUShort();
-        var length = p.parseUShort();
-        for (var j = offset; j < offset + length; ++j) {
-            tag += String.fromCharCode(data.getInt8(j));
-        }
-
-        tags.push(tag);
-    }
-
-    return tags;
-}
-
-var ltag = { make: makeLtagTable, parse: parseLtagTable };
-
-// The `maxp` table establishes the memory requirements for the font.
-
-// Parse the maximum profile `maxp` table.
-function parseMaxpTable(data, start) {
-    var maxp = {};
-    var p = new parse.Parser(data, start);
-    maxp.version = p.parseVersion();
-    maxp.numGlyphs = p.parseUShort();
-    if (maxp.version === 1.0) {
-        maxp.maxPoints = p.parseUShort();
-        maxp.maxContours = p.parseUShort();
-        maxp.maxCompositePoints = p.parseUShort();
-        maxp.maxCompositeContours = p.parseUShort();
-        maxp.maxZones = p.parseUShort();
-        maxp.maxTwilightPoints = p.parseUShort();
-        maxp.maxStorage = p.parseUShort();
-        maxp.maxFunctionDefs = p.parseUShort();
-        maxp.maxInstructionDefs = p.parseUShort();
-        maxp.maxStackElements = p.parseUShort();
-        maxp.maxSizeOfInstructions = p.parseUShort();
-        maxp.maxComponentElements = p.parseUShort();
-        maxp.maxComponentDepth = p.parseUShort();
-    }
-
-    return maxp;
-}
-
-function makeMaxpTable(numGlyphs) {
-    return new table.Table('maxp', [
-        {name: 'version', type: 'FIXED', value: 0x00005000},
-        {name: 'numGlyphs', type: 'USHORT', value: numGlyphs}
-    ]);
-}
-
-var maxp = { parse: parseMaxpTable, make: makeMaxpTable };
-
-// The `name` naming table.
-
-// NameIDs for the name table.
-var nameTableNames = [
-    'copyright',              // 0
-    'fontFamily',             // 1
-    'fontSubfamily',          // 2
-    'uniqueID',               // 3
-    'fullName',               // 4
-    'version',                // 5
-    'postScriptName',         // 6
-    'trademark',              // 7
-    'manufacturer',           // 8
-    'designer',               // 9
-    'description',            // 10
-    'manufacturerURL',        // 11
-    'designerURL',            // 12
-    'license',                // 13
-    'licenseURL',             // 14
-    'reserved',               // 15
-    'preferredFamily',        // 16
-    'preferredSubfamily',     // 17
-    'compatibleFullName',     // 18
-    'sampleText',             // 19
-    'postScriptFindFontName', // 20
-    'wwsFamily',              // 21
-    'wwsSubfamily'            // 22
-];
-
-var macLanguages = {
-    0: 'en',
-    1: 'fr',
-    2: 'de',
-    3: 'it',
-    4: 'nl',
-    5: 'sv',
-    6: 'es',
-    7: 'da',
-    8: 'pt',
-    9: 'no',
-    10: 'he',
-    11: 'ja',
-    12: 'ar',
-    13: 'fi',
-    14: 'el',
-    15: 'is',
-    16: 'mt',
-    17: 'tr',
-    18: 'hr',
-    19: 'zh-Hant',
-    20: 'ur',
-    21: 'hi',
-    22: 'th',
-    23: 'ko',
-    24: 'lt',
-    25: 'pl',
-    26: 'hu',
-    27: 'es',
-    28: 'lv',
-    29: 'se',
-    30: 'fo',
-    31: 'fa',
-    32: 'ru',
-    33: 'zh',
-    34: 'nl-BE',
-    35: 'ga',
-    36: 'sq',
-    37: 'ro',
-    38: 'cz',
-    39: 'sk',
-    40: 'si',
-    41: 'yi',
-    42: 'sr',
-    43: 'mk',
-    44: 'bg',
-    45: 'uk',
-    46: 'be',
-    47: 'uz',
-    48: 'kk',
-    49: 'az-Cyrl',
-    50: 'az-Arab',
-    51: 'hy',
-    52: 'ka',
-    53: 'mo',
-    54: 'ky',
-    55: 'tg',
-    56: 'tk',
-    57: 'mn-CN',
-    58: 'mn',
-    59: 'ps',
-    60: 'ks',
-    61: 'ku',
-    62: 'sd',
-    63: 'bo',
-    64: 'ne',
-    65: 'sa',
-    66: 'mr',
-    67: 'bn',
-    68: 'as',
-    69: 'gu',
-    70: 'pa',
-    71: 'or',
-    72: 'ml',
-    73: 'kn',
-    74: 'ta',
-    75: 'te',
-    76: 'si',
-    77: 'my',
-    78: 'km',
-    79: 'lo',
-    80: 'vi',
-    81: 'id',
-    82: 'tl',
-    83: 'ms',
-    84: 'ms-Arab',
-    85: 'am',
-    86: 'ti',
-    87: 'om',
-    88: 'so',
-    89: 'sw',
-    90: 'rw',
-    91: 'rn',
-    92: 'ny',
-    93: 'mg',
-    94: 'eo',
-    128: 'cy',
-    129: 'eu',
-    130: 'ca',
-    131: 'la',
-    132: 'qu',
-    133: 'gn',
-    134: 'ay',
-    135: 'tt',
-    136: 'ug',
-    137: 'dz',
-    138: 'jv',
-    139: 'su',
-    140: 'gl',
-    141: 'af',
-    142: 'br',
-    143: 'iu',
-    144: 'gd',
-    145: 'gv',
-    146: 'ga',
-    147: 'to',
-    148: 'el-polyton',
-    149: 'kl',
-    150: 'az',
-    151: 'nn'
-};
-
-// MacOS language ID → MacOS script ID
-//
-// Note that the script ID is not sufficient to determine what encoding
-// to use in TrueType files. For some languages, MacOS used a modification
-// of a mainstream script. For example, an Icelandic name would be stored
-// with smRoman in the TrueType naming table, but the actual encoding
-// is a special Icelandic version of the normal Macintosh Roman encoding.
-// As another example, Inuktitut uses an 8-bit encoding for Canadian Aboriginal
-// Syllables but MacOS had run out of available script codes, so this was
-// done as a (pretty radical) "modification" of Ethiopic.
-//
-// http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt
-var macLanguageToScript = {
-    0: 0,  // langEnglish → smRoman
-    1: 0,  // langFrench → smRoman
-    2: 0,  // langGerman → smRoman
-    3: 0,  // langItalian → smRoman
-    4: 0,  // langDutch → smRoman
-    5: 0,  // langSwedish → smRoman
-    6: 0,  // langSpanish → smRoman
-    7: 0,  // langDanish → smRoman
-    8: 0,  // langPortuguese → smRoman
-    9: 0,  // langNorwegian → smRoman
-    10: 5,  // langHebrew → smHebrew
-    11: 1,  // langJapanese → smJapanese
-    12: 4,  // langArabic → smArabic
-    13: 0,  // langFinnish → smRoman
-    14: 6,  // langGreek → smGreek
-    15: 0,  // langIcelandic → smRoman (modified)
-    16: 0,  // langMaltese → smRoman
-    17: 0,  // langTurkish → smRoman (modified)
-    18: 0,  // langCroatian → smRoman (modified)
-    19: 2,  // langTradChinese → smTradChinese
-    20: 4,  // langUrdu → smArabic
-    21: 9,  // langHindi → smDevanagari
-    22: 21,  // langThai → smThai
-    23: 3,  // langKorean → smKorean
-    24: 29,  // langLithuanian → smCentralEuroRoman
-    25: 29,  // langPolish → smCentralEuroRoman
-    26: 29,  // langHungarian → smCentralEuroRoman
-    27: 29,  // langEstonian → smCentralEuroRoman
-    28: 29,  // langLatvian → smCentralEuroRoman
-    29: 0,  // langSami → smRoman
-    30: 0,  // langFaroese → smRoman (modified)
-    31: 4,  // langFarsi → smArabic (modified)
-    32: 7,  // langRussian → smCyrillic
-    33: 25,  // langSimpChinese → smSimpChinese
-    34: 0,  // langFlemish → smRoman
-    35: 0,  // langIrishGaelic → smRoman (modified)
-    36: 0,  // langAlbanian → smRoman
-    37: 0,  // langRomanian → smRoman (modified)
-    38: 29,  // langCzech → smCentralEuroRoman
-    39: 29,  // langSlovak → smCentralEuroRoman
-    40: 0,  // langSlovenian → smRoman (modified)
-    41: 5,  // langYiddish → smHebrew
-    42: 7,  // langSerbian → smCyrillic
-    43: 7,  // langMacedonian → smCyrillic
-    44: 7,  // langBulgarian → smCyrillic
-    45: 7,  // langUkrainian → smCyrillic (modified)
-    46: 7,  // langByelorussian → smCyrillic
-    47: 7,  // langUzbek → smCyrillic
-    48: 7,  // langKazakh → smCyrillic
-    49: 7,  // langAzerbaijani → smCyrillic
-    50: 4,  // langAzerbaijanAr → smArabic
-    51: 24,  // langArmenian → smArmenian
-    52: 23,  // langGeorgian → smGeorgian
-    53: 7,  // langMoldavian → smCyrillic
-    54: 7,  // langKirghiz → smCyrillic
-    55: 7,  // langTajiki → smCyrillic
-    56: 7,  // langTurkmen → smCyrillic
-    57: 27,  // langMongolian → smMongolian
-    58: 7,  // langMongolianCyr → smCyrillic
-    59: 4,  // langPashto → smArabic
-    60: 4,  // langKurdish → smArabic
-    61: 4,  // langKashmiri → smArabic
-    62: 4,  // langSindhi → smArabic
-    63: 26,  // langTibetan → smTibetan
-    64: 9,  // langNepali → smDevanagari
-    65: 9,  // langSanskrit → smDevanagari
-    66: 9,  // langMarathi → smDevanagari
-    67: 13,  // langBengali → smBengali
-    68: 13,  // langAssamese → smBengali
-    69: 11,  // langGujarati → smGujarati
-    70: 10,  // langPunjabi → smGurmukhi
-    71: 12,  // langOriya → smOriya
-    72: 17,  // langMalayalam → smMalayalam
-    73: 16,  // langKannada → smKannada
-    74: 14,  // langTamil → smTamil
-    75: 15,  // langTelugu → smTelugu
-    76: 18,  // langSinhalese → smSinhalese
-    77: 19,  // langBurmese → smBurmese
-    78: 20,  // langKhmer → smKhmer
-    79: 22,  // langLao → smLao
-    80: 30,  // langVietnamese → smVietnamese
-    81: 0,  // langIndonesian → smRoman
-    82: 0,  // langTagalog → smRoman
-    83: 0,  // langMalayRoman → smRoman
-    84: 4,  // langMalayArabic → smArabic
-    85: 28,  // langAmharic → smEthiopic
-    86: 28,  // langTigrinya → smEthiopic
-    87: 28,  // langOromo → smEthiopic
-    88: 0,  // langSomali → smRoman
-    89: 0,  // langSwahili → smRoman
-    90: 0,  // langKinyarwanda → smRoman
-    91: 0,  // langRundi → smRoman
-    92: 0,  // langNyanja → smRoman
-    93: 0,  // langMalagasy → smRoman
-    94: 0,  // langEsperanto → smRoman
-    128: 0,  // langWelsh → smRoman (modified)
-    129: 0,  // langBasque → smRoman
-    130: 0,  // langCatalan → smRoman
-    131: 0,  // langLatin → smRoman
-    132: 0,  // langQuechua → smRoman
-    133: 0,  // langGuarani → smRoman
-    134: 0,  // langAymara → smRoman
-    135: 7,  // langTatar → smCyrillic
-    136: 4,  // langUighur → smArabic
-    137: 26,  // langDzongkha → smTibetan
-    138: 0,  // langJavaneseRom → smRoman
-    139: 0,  // langSundaneseRom → smRoman
-    140: 0,  // langGalician → smRoman
-    141: 0,  // langAfrikaans → smRoman
-    142: 0,  // langBreton → smRoman (modified)
-    143: 28,  // langInuktitut → smEthiopic (modified)
-    144: 0,  // langScottishGaelic → smRoman (modified)
-    145: 0,  // langManxGaelic → smRoman (modified)
-    146: 0,  // langIrishGaelicScript → smRoman (modified)
-    147: 0,  // langTongan → smRoman
-    148: 6,  // langGreekAncient → smRoman
-    149: 0,  // langGreenlandic → smRoman
-    150: 0,  // langAzerbaijanRoman → smRoman
-    151: 0   // langNynorsk → smRoman
-};
-
-// While Microsoft indicates a region/country for all its language
-// IDs, we omit the region code if it's equal to the "most likely
-// region subtag" according to Unicode CLDR. For scripts, we omit
-// the subtag if it is equal to the Suppress-Script entry in the
-// IANA language subtag registry for IETF BCP 47.
-//
-// For example, Microsoft states that its language code 0x041A is
-// Croatian in Croatia. We transform this to the BCP 47 language code 'hr'
-// and not 'hr-HR' because Croatia is the default country for Croatian,
-// according to Unicode CLDR. As another example, Microsoft states
-// that 0x101A is Croatian (Latin) in Bosnia-Herzegovina. We transform
-// this to 'hr-BA' and not 'hr-Latn-BA' because Latin is the default script
-// for the Croatian language, according to IANA.
-//
-// http://www.unicode.org/cldr/charts/latest/supplemental/likely_subtags.html
-// http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
-var windowsLanguages = {
-    0x0436: 'af',
-    0x041C: 'sq',
-    0x0484: 'gsw',
-    0x045E: 'am',
-    0x1401: 'ar-DZ',
-    0x3C01: 'ar-BH',
-    0x0C01: 'ar',
-    0x0801: 'ar-IQ',
-    0x2C01: 'ar-JO',
-    0x3401: 'ar-KW',
-    0x3001: 'ar-LB',
-    0x1001: 'ar-LY',
-    0x1801: 'ary',
-    0x2001: 'ar-OM',
-    0x4001: 'ar-QA',
-    0x0401: 'ar-SA',
-    0x2801: 'ar-SY',
-    0x1C01: 'aeb',
-    0x3801: 'ar-AE',
-    0x2401: 'ar-YE',
-    0x042B: 'hy',
-    0x044D: 'as',
-    0x082C: 'az-Cyrl',
-    0x042C: 'az',
-    0x046D: 'ba',
-    0x042D: 'eu',
-    0x0423: 'be',
-    0x0845: 'bn',
-    0x0445: 'bn-IN',
-    0x201A: 'bs-Cyrl',
-    0x141A: 'bs',
-    0x047E: 'br',
-    0x0402: 'bg',
-    0x0403: 'ca',
-    0x0C04: 'zh-HK',
-    0x1404: 'zh-MO',
-    0x0804: 'zh',
-    0x1004: 'zh-SG',
-    0x0404: 'zh-TW',
-    0x0483: 'co',
-    0x041A: 'hr',
-    0x101A: 'hr-BA',
-    0x0405: 'cs',
-    0x0406: 'da',
-    0x048C: 'prs',
-    0x0465: 'dv',
-    0x0813: 'nl-BE',
-    0x0413: 'nl',
-    0x0C09: 'en-AU',
-    0x2809: 'en-BZ',
-    0x1009: 'en-CA',
-    0x2409: 'en-029',
-    0x4009: 'en-IN',
-    0x1809: 'en-IE',
-    0x2009: 'en-JM',
-    0x4409: 'en-MY',
-    0x1409: 'en-NZ',
-    0x3409: 'en-PH',
-    0x4809: 'en-SG',
-    0x1C09: 'en-ZA',
-    0x2C09: 'en-TT',
-    0x0809: 'en-GB',
-    0x0409: 'en',
-    0x3009: 'en-ZW',
-    0x0425: 'et',
-    0x0438: 'fo',
-    0x0464: 'fil',
-    0x040B: 'fi',
-    0x080C: 'fr-BE',
-    0x0C0C: 'fr-CA',
-    0x040C: 'fr',
-    0x140C: 'fr-LU',
-    0x180C: 'fr-MC',
-    0x100C: 'fr-CH',
-    0x0462: 'fy',
-    0x0456: 'gl',
-    0x0437: 'ka',
-    0x0C07: 'de-AT',
-    0x0407: 'de',
-    0x1407: 'de-LI',
-    0x1007: 'de-LU',
-    0x0807: 'de-CH',
-    0x0408: 'el',
-    0x046F: 'kl',
-    0x0447: 'gu',
-    0x0468: 'ha',
-    0x040D: 'he',
-    0x0439: 'hi',
-    0x040E: 'hu',
-    0x040F: 'is',
-    0x0470: 'ig',
-    0x0421: 'id',
-    0x045D: 'iu',
-    0x085D: 'iu-Latn',
-    0x083C: 'ga',
-    0x0434: 'xh',
-    0x0435: 'zu',
-    0x0410: 'it',
-    0x0810: 'it-CH',
-    0x0411: 'ja',
-    0x044B: 'kn',
-    0x043F: 'kk',
-    0x0453: 'km',
-    0x0486: 'quc',
-    0x0487: 'rw',
-    0x0441: 'sw',
-    0x0457: 'kok',
-    0x0412: 'ko',
-    0x0440: 'ky',
-    0x0454: 'lo',
-    0x0426: 'lv',
-    0x0427: 'lt',
-    0x082E: 'dsb',
-    0x046E: 'lb',
-    0x042F: 'mk',
-    0x083E: 'ms-BN',
-    0x043E: 'ms',
-    0x044C: 'ml',
-    0x043A: 'mt',
-    0x0481: 'mi',
-    0x047A: 'arn',
-    0x044E: 'mr',
-    0x047C: 'moh',
-    0x0450: 'mn',
-    0x0850: 'mn-CN',
-    0x0461: 'ne',
-    0x0414: 'nb',
-    0x0814: 'nn',
-    0x0482: 'oc',
-    0x0448: 'or',
-    0x0463: 'ps',
-    0x0415: 'pl',
-    0x0416: 'pt',
-    0x0816: 'pt-PT',
-    0x0446: 'pa',
-    0x046B: 'qu-BO',
-    0x086B: 'qu-EC',
-    0x0C6B: 'qu',
-    0x0418: 'ro',
-    0x0417: 'rm',
-    0x0419: 'ru',
-    0x243B: 'smn',
-    0x103B: 'smj-NO',
-    0x143B: 'smj',
-    0x0C3B: 'se-FI',
-    0x043B: 'se',
-    0x083B: 'se-SE',
-    0x203B: 'sms',
-    0x183B: 'sma-NO',
-    0x1C3B: 'sms',
-    0x044F: 'sa',
-    0x1C1A: 'sr-Cyrl-BA',
-    0x0C1A: 'sr',
-    0x181A: 'sr-Latn-BA',
-    0x081A: 'sr-Latn',
-    0x046C: 'nso',
-    0x0432: 'tn',
-    0x045B: 'si',
-    0x041B: 'sk',
-    0x0424: 'sl',
-    0x2C0A: 'es-AR',
-    0x400A: 'es-BO',
-    0x340A: 'es-CL',
-    0x240A: 'es-CO',
-    0x140A: 'es-CR',
-    0x1C0A: 'es-DO',
-    0x300A: 'es-EC',
-    0x440A: 'es-SV',
-    0x100A: 'es-GT',
-    0x480A: 'es-HN',
-    0x080A: 'es-MX',
-    0x4C0A: 'es-NI',
-    0x180A: 'es-PA',
-    0x3C0A: 'es-PY',
-    0x280A: 'es-PE',
-    0x500A: 'es-PR',
-
-    // Microsoft has defined two different language codes for
-    // “Spanish with modern sorting” and “Spanish with traditional
-    // sorting”. This makes sense for collation APIs, and it would be
-    // possible to express this in BCP 47 language tags via Unicode
-    // extensions (eg., es-u-co-trad is Spanish with traditional
-    // sorting). However, for storing names in fonts, the distinction
-    // does not make sense, so we give “es” in both cases.
-    0x0C0A: 'es',
-    0x040A: 'es',
-
-    0x540A: 'es-US',
-    0x380A: 'es-UY',
-    0x200A: 'es-VE',
-    0x081D: 'sv-FI',
-    0x041D: 'sv',
-    0x045A: 'syr',
-    0x0428: 'tg',
-    0x085F: 'tzm',
-    0x0449: 'ta',
-    0x0444: 'tt',
-    0x044A: 'te',
-    0x041E: 'th',
-    0x0451: 'bo',
-    0x041F: 'tr',
-    0x0442: 'tk',
-    0x0480: 'ug',
-    0x0422: 'uk',
-    0x042E: 'hsb',
-    0x0420: 'ur',
-    0x0843: 'uz-Cyrl',
-    0x0443: 'uz',
-    0x042A: 'vi',
-    0x0452: 'cy',
-    0x0488: 'wo',
-    0x0485: 'sah',
-    0x0478: 'ii',
-    0x046A: 'yo'
-};
-
-// Returns a IETF BCP 47 language code, for example 'zh-Hant'
-// for 'Chinese in the traditional script'.
-function getLanguageCode(platformID, languageID, ltag) {
-    switch (platformID) {
-        case 0:  // Unicode
-            if (languageID === 0xFFFF) {
-                return 'und';
-            } else if (ltag) {
-                return ltag[languageID];
-            }
-
-            break;
-
-        case 1:  // Macintosh
-            return macLanguages[languageID];
-
-        case 3:  // Windows
-            return windowsLanguages[languageID];
-    }
-
-    return undefined;
-}
-
-var utf16 = 'utf-16';
-
-// MacOS script ID → encoding. This table stores the default case,
-// which can be overridden by macLanguageEncodings.
-var macScriptEncodings = {
-    0: 'macintosh',           // smRoman
-    1: 'x-mac-japanese',      // smJapanese
-    2: 'x-mac-chinesetrad',   // smTradChinese
-    3: 'x-mac-korean',        // smKorean
-    6: 'x-mac-greek',         // smGreek
-    7: 'x-mac-cyrillic',      // smCyrillic
-    9: 'x-mac-devanagai',     // smDevanagari
-    10: 'x-mac-gurmukhi',     // smGurmukhi
-    11: 'x-mac-gujarati',     // smGujarati
-    12: 'x-mac-oriya',        // smOriya
-    13: 'x-mac-bengali',      // smBengali
-    14: 'x-mac-tamil',        // smTamil
-    15: 'x-mac-telugu',       // smTelugu
-    16: 'x-mac-kannada',      // smKannada
-    17: 'x-mac-malayalam',    // smMalayalam
-    18: 'x-mac-sinhalese',    // smSinhalese
-    19: 'x-mac-burmese',      // smBurmese
-    20: 'x-mac-khmer',        // smKhmer
-    21: 'x-mac-thai',         // smThai
-    22: 'x-mac-lao',          // smLao
-    23: 'x-mac-georgian',     // smGeorgian
-    24: 'x-mac-armenian',     // smArmenian
-    25: 'x-mac-chinesesimp',  // smSimpChinese
-    26: 'x-mac-tibetan',      // smTibetan
-    27: 'x-mac-mongolian',    // smMongolian
-    28: 'x-mac-ethiopic',     // smEthiopic
-    29: 'x-mac-ce',           // smCentralEuroRoman
-    30: 'x-mac-vietnamese',   // smVietnamese
-    31: 'x-mac-extarabic'     // smExtArabic
-};
-
-// MacOS language ID → encoding. This table stores the exceptional
-// cases, which override macScriptEncodings. For writing MacOS naming
-// tables, we need to emit a MacOS script ID. Therefore, we cannot
-// merge macScriptEncodings into macLanguageEncodings.
-//
-// http://unicode.org/Public/MAPPINGS/VENDORS/APPLE/Readme.txt
-var macLanguageEncodings = {
-    15: 'x-mac-icelandic',    // langIcelandic
-    17: 'x-mac-turkish',      // langTurkish
-    18: 'x-mac-croatian',     // langCroatian
-    24: 'x-mac-ce',           // langLithuanian
-    25: 'x-mac-ce',           // langPolish
-    26: 'x-mac-ce',           // langHungarian
-    27: 'x-mac-ce',           // langEstonian
-    28: 'x-mac-ce',           // langLatvian
-    30: 'x-mac-icelandic',    // langFaroese
-    37: 'x-mac-romanian',     // langRomanian
-    38: 'x-mac-ce',           // langCzech
-    39: 'x-mac-ce',           // langSlovak
-    40: 'x-mac-ce',           // langSlovenian
-    143: 'x-mac-inuit',       // langInuktitut
-    146: 'x-mac-gaelic'       // langIrishGaelicScript
-};
-
-function getEncoding(platformID, encodingID, languageID) {
-    switch (platformID) {
-        case 0:  // Unicode
-            return utf16;
-
-        case 1:  // Apple Macintosh
-            return macLanguageEncodings[languageID] || macScriptEncodings[encodingID];
-
-        case 3:  // Microsoft Windows
-            if (encodingID === 1 || encodingID === 10) {
-                return utf16;
-            }
-
-            break;
-    }
-
-    return undefined;
-}
-
-// Parse the naming `name` table.
-// FIXME: Format 1 additional fields are not supported yet.
-// ltag is the content of the `ltag' table, such as ['en', 'zh-Hans', 'de-CH-1904'].
-function parseNameTable(data, start, ltag) {
-    var name = {};
-    var p = new parse.Parser(data, start);
-    var format = p.parseUShort();
-    var count = p.parseUShort();
-    var stringOffset = p.offset + p.parseUShort();
-    for (var i = 0; i < count; i++) {
-        var platformID = p.parseUShort();
-        var encodingID = p.parseUShort();
-        var languageID = p.parseUShort();
-        var nameID = p.parseUShort();
-        var property = nameTableNames[nameID] || nameID;
-        var byteLength = p.parseUShort();
-        var offset = p.parseUShort();
-        var language = getLanguageCode(platformID, languageID, ltag);
-        var encoding = getEncoding(platformID, encodingID, languageID);
-        if (encoding !== undefined && language !== undefined) {
-            var text = (void 0);
-            if (encoding === utf16) {
-                text = decode.UTF16(data, stringOffset + offset, byteLength);
-            } else {
-                text = decode.MACSTRING(data, stringOffset + offset, byteLength, encoding);
-            }
-
-            if (text) {
-                var translations = name[property];
-                if (translations === undefined) {
-                    translations = name[property] = {};
-                }
-
-                translations[language] = text;
-            }
-        }
-    }
-
-    var langTagCount = 0;
-    if (format === 1) {
-        // FIXME: Also handle Microsoft's 'name' table 1.
-        langTagCount = p.parseUShort();
-    }
-
-    return name;
-}
-
-// {23: 'foo'} → {'foo': 23}
-// ['bar', 'baz'] → {'bar': 0, 'baz': 1}
-function reverseDict(dict) {
-    var result = {};
-    for (var key in dict) {
-        result[dict[key]] = parseInt(key);
-    }
-
-    return result;
-}
-
-function makeNameRecord(platformID, encodingID, languageID, nameID, length, offset) {
-    return new table.Record('NameRecord', [
-        {name: 'platformID', type: 'USHORT', value: platformID},
-        {name: 'encodingID', type: 'USHORT', value: encodingID},
-        {name: 'languageID', type: 'USHORT', value: languageID},
-        {name: 'nameID', type: 'USHORT', value: nameID},
-        {name: 'length', type: 'USHORT', value: length},
-        {name: 'offset', type: 'USHORT', value: offset}
-    ]);
-}
-
-// Finds the position of needle in haystack, or -1 if not there.
-// Like String.indexOf(), but for arrays.
-function findSubArray(needle, haystack) {
-    var needleLength = needle.length;
-    var limit = haystack.length - needleLength + 1;
-
-    loop:
-    for (var pos = 0; pos < limit; pos++) {
-        for (; pos < limit; pos++) {
-            for (var k = 0; k < needleLength; k++) {
-                if (haystack[pos + k] !== needle[k]) {
-                    continue loop;
-                }
-            }
-
-            return pos;
-        }
-    }
-
-    return -1;
-}
-
-function addStringToPool(s, pool) {
-    var offset = findSubArray(s, pool);
-    if (offset < 0) {
-        offset = pool.length;
-        var i = 0;
-        var len = s.length;
-        for (; i < len; ++i) {
-            pool.push(s[i]);
-        }
-
-    }
-
-    return offset;
-}
-
-function makeNameTable(names, ltag) {
-    var nameID;
-    var nameIDs = [];
-
-    var namesWithNumericKeys = {};
-    var nameTableIds = reverseDict(nameTableNames);
-    for (var key in names) {
-        var id = nameTableIds[key];
-        if (id === undefined) {
-            id = key;
-        }
-
-        nameID = parseInt(id);
-
-        if (isNaN(nameID)) {
-            throw new Error('Name table entry "' + key + '" does not exist, see nameTableNames for complete list.');
-        }
-
-        namesWithNumericKeys[nameID] = names[key];
-        nameIDs.push(nameID);
-    }
-
-    var macLanguageIds = reverseDict(macLanguages);
-    var windowsLanguageIds = reverseDict(windowsLanguages);
-
-    var nameRecords = [];
-    var stringPool = [];
-
-    for (var i = 0; i < nameIDs.length; i++) {
-        nameID = nameIDs[i];
-        var translations = namesWithNumericKeys[nameID];
-        for (var lang in translations) {
-            var text = translations[lang];
-
-            // For MacOS, we try to emit the name in the form that was introduced
-            // in the initial version of the TrueType spec (in the late 1980s).
-            // However, this can fail for various reasons: the requested BCP 47
-            // language code might not have an old-style Mac equivalent;
-            // we might not have a codec for the needed character encoding;
-            // or the name might contain characters that cannot be expressed
-            // in the old-style Macintosh encoding. In case of failure, we emit
-            // the name in a more modern fashion (Unicode encoding with BCP 47
-            // language tags) that is recognized by MacOS 10.5, released in 2009.
-            // If fonts were only read by operating systems, we could simply
-            // emit all names in the modern form; this would be much easier.
-            // However, there are many applications and libraries that read
-            // 'name' tables directly, and these will usually only recognize
-            // the ancient form (silently skipping the unrecognized names).
-            var macPlatform = 1;  // Macintosh
-            var macLanguage = macLanguageIds[lang];
-            var macScript = macLanguageToScript[macLanguage];
-            var macEncoding = getEncoding(macPlatform, macScript, macLanguage);
-            var macName = encode.MACSTRING(text, macEncoding);
-            if (macName === undefined) {
-                macPlatform = 0;  // Unicode
-                macLanguage = ltag.indexOf(lang);
-                if (macLanguage < 0) {
-                    macLanguage = ltag.length;
-                    ltag.push(lang);
-                }
-
-                macScript = 4;  // Unicode 2.0 and later
-                macName = encode.UTF16(text);
-            }
-
-            var macNameOffset = addStringToPool(macName, stringPool);
-            nameRecords.push(makeNameRecord(macPlatform, macScript, macLanguage,
-                                            nameID, macName.length, macNameOffset));
-
-            var winLanguage = windowsLanguageIds[lang];
-            if (winLanguage !== undefined) {
-                var winName = encode.UTF16(text);
-                var winNameOffset = addStringToPool(winName, stringPool);
-                nameRecords.push(makeNameRecord(3, 1, winLanguage,
-                                                nameID, winName.length, winNameOffset));
-            }
-        }
-    }
-
-    nameRecords.sort(function(a, b) {
-        return ((a.platformID - b.platformID) ||
-                (a.encodingID - b.encodingID) ||
-                (a.languageID - b.languageID) ||
-                (a.nameID - b.nameID));
-    });
-
-    var t = new table.Table('name', [
-        {name: 'format', type: 'USHORT', value: 0},
-        {name: 'count', type: 'USHORT', value: nameRecords.length},
-        {name: 'stringOffset', type: 'USHORT', value: 6 + nameRecords.length * 12}
-    ]);
-
-    for (var r = 0; r < nameRecords.length; r++) {
-        t.fields.push({name: 'record_' + r, type: 'RECORD', value: nameRecords[r]});
-    }
-
-    t.fields.push({name: 'strings', type: 'LITERAL', value: stringPool});
-    return t;
-}
-
-var _name = { parse: parseNameTable, make: makeNameTable };
-
-// The `OS/2` table contains metrics required in OpenType fonts.
-
-var unicodeRanges = [
-    {begin: 0x0000, end: 0x007F}, // Basic Latin
-    {begin: 0x0080, end: 0x00FF}, // Latin-1 Supplement
-    {begin: 0x0100, end: 0x017F}, // Latin Extended-A
-    {begin: 0x0180, end: 0x024F}, // Latin Extended-B
-    {begin: 0x0250, end: 0x02AF}, // IPA Extensions
-    {begin: 0x02B0, end: 0x02FF}, // Spacing Modifier Letters
-    {begin: 0x0300, end: 0x036F}, // Combining Diacritical Marks
-    {begin: 0x0370, end: 0x03FF}, // Greek and Coptic
-    {begin: 0x2C80, end: 0x2CFF}, // Coptic
-    {begin: 0x0400, end: 0x04FF}, // Cyrillic
-    {begin: 0x0530, end: 0x058F}, // Armenian
-    {begin: 0x0590, end: 0x05FF}, // Hebrew
-    {begin: 0xA500, end: 0xA63F}, // Vai
-    {begin: 0x0600, end: 0x06FF}, // Arabic
-    {begin: 0x07C0, end: 0x07FF}, // NKo
-    {begin: 0x0900, end: 0x097F}, // Devanagari
-    {begin: 0x0980, end: 0x09FF}, // Bengali
-    {begin: 0x0A00, end: 0x0A7F}, // Gurmukhi
-    {begin: 0x0A80, end: 0x0AFF}, // Gujarati
-    {begin: 0x0B00, end: 0x0B7F}, // Oriya
-    {begin: 0x0B80, end: 0x0BFF}, // Tamil
-    {begin: 0x0C00, end: 0x0C7F}, // Telugu
-    {begin: 0x0C80, end: 0x0CFF}, // Kannada
-    {begin: 0x0D00, end: 0x0D7F}, // Malayalam
-    {begin: 0x0E00, end: 0x0E7F}, // Thai
-    {begin: 0x0E80, end: 0x0EFF}, // Lao
-    {begin: 0x10A0, end: 0x10FF}, // Georgian
-    {begin: 0x1B00, end: 0x1B7F}, // Balinese
-    {begin: 0x1100, end: 0x11FF}, // Hangul Jamo
-    {begin: 0x1E00, end: 0x1EFF}, // Latin Extended Additional
-    {begin: 0x1F00, end: 0x1FFF}, // Greek Extended
-    {begin: 0x2000, end: 0x206F}, // General Punctuation
-    {begin: 0x2070, end: 0x209F}, // Superscripts And Subscripts
-    {begin: 0x20A0, end: 0x20CF}, // Currency Symbol
-    {begin: 0x20D0, end: 0x20FF}, // Combining Diacritical Marks For Symbols
-    {begin: 0x2100, end: 0x214F}, // Letterlike Symbols
-    {begin: 0x2150, end: 0x218F}, // Number Forms
-    {begin: 0x2190, end: 0x21FF}, // Arrows
-    {begin: 0x2200, end: 0x22FF}, // Mathematical Operators
-    {begin: 0x2300, end: 0x23FF}, // Miscellaneous Technical
-    {begin: 0x2400, end: 0x243F}, // Control Pictures
-    {begin: 0x2440, end: 0x245F}, // Optical Character Recognition
-    {begin: 0x2460, end: 0x24FF}, // Enclosed Alphanumerics
-    {begin: 0x2500, end: 0x257F}, // Box Drawing
-    {begin: 0x2580, end: 0x259F}, // Block Elements
-    {begin: 0x25A0, end: 0x25FF}, // Geometric Shapes
-    {begin: 0x2600, end: 0x26FF}, // Miscellaneous Symbols
-    {begin: 0x2700, end: 0x27BF}, // Dingbats
-    {begin: 0x3000, end: 0x303F}, // CJK Symbols And Punctuation
-    {begin: 0x3040, end: 0x309F}, // Hiragana
-    {begin: 0x30A0, end: 0x30FF}, // Katakana
-    {begin: 0x3100, end: 0x312F}, // Bopomofo
-    {begin: 0x3130, end: 0x318F}, // Hangul Compatibility Jamo
-    {begin: 0xA840, end: 0xA87F}, // Phags-pa
-    {begin: 0x3200, end: 0x32FF}, // Enclosed CJK Letters And Months
-    {begin: 0x3300, end: 0x33FF}, // CJK Compatibility
-    {begin: 0xAC00, end: 0xD7AF}, // Hangul Syllables
-    {begin: 0xD800, end: 0xDFFF}, // Non-Plane 0 *
-    {begin: 0x10900, end: 0x1091F}, // Phoenicia
-    {begin: 0x4E00, end: 0x9FFF}, // CJK Unified Ideographs
-    {begin: 0xE000, end: 0xF8FF}, // Private Use Area (plane 0)
-    {begin: 0x31C0, end: 0x31EF}, // CJK Strokes
-    {begin: 0xFB00, end: 0xFB4F}, // Alphabetic Presentation Forms
-    {begin: 0xFB50, end: 0xFDFF}, // Arabic Presentation Forms-A
-    {begin: 0xFE20, end: 0xFE2F}, // Combining Half Marks
-    {begin: 0xFE10, end: 0xFE1F}, // Vertical Forms
-    {begin: 0xFE50, end: 0xFE6F}, // Small Form Variants
-    {begin: 0xFE70, end: 0xFEFF}, // Arabic Presentation Forms-B
-    {begin: 0xFF00, end: 0xFFEF}, // Halfwidth And Fullwidth Forms
-    {begin: 0xFFF0, end: 0xFFFF}, // Specials
-    {begin: 0x0F00, end: 0x0FFF}, // Tibetan
-    {begin: 0x0700, end: 0x074F}, // Syriac
-    {begin: 0x0780, end: 0x07BF}, // Thaana
-    {begin: 0x0D80, end: 0x0DFF}, // Sinhala
-    {begin: 0x1000, end: 0x109F}, // Myanmar
-    {begin: 0x1200, end: 0x137F}, // Ethiopic
-    {begin: 0x13A0, end: 0x13FF}, // Cherokee
-    {begin: 0x1400, end: 0x167F}, // Unified Canadian Aboriginal Syllabics
-    {begin: 0x1680, end: 0x169F}, // Ogham
-    {begin: 0x16A0, end: 0x16FF}, // Runic
-    {begin: 0x1780, end: 0x17FF}, // Khmer
-    {begin: 0x1800, end: 0x18AF}, // Mongolian
-    {begin: 0x2800, end: 0x28FF}, // Braille Patterns
-    {begin: 0xA000, end: 0xA48F}, // Yi Syllables
-    {begin: 0x1700, end: 0x171F}, // Tagalog
-    {begin: 0x10300, end: 0x1032F}, // Old Italic
-    {begin: 0x10330, end: 0x1034F}, // Gothic
-    {begin: 0x10400, end: 0x1044F}, // Deseret
-    {begin: 0x1D000, end: 0x1D0FF}, // Byzantine Musical Symbols
-    {begin: 0x1D400, end: 0x1D7FF}, // Mathematical Alphanumeric Symbols
-    {begin: 0xFF000, end: 0xFFFFD}, // Private Use (plane 15)
-    {begin: 0xFE00, end: 0xFE0F}, // Variation Selectors
-    {begin: 0xE0000, end: 0xE007F}, // Tags
-    {begin: 0x1900, end: 0x194F}, // Limbu
-    {begin: 0x1950, end: 0x197F}, // Tai Le
-    {begin: 0x1980, end: 0x19DF}, // New Tai Lue
-    {begin: 0x1A00, end: 0x1A1F}, // Buginese
-    {begin: 0x2C00, end: 0x2C5F}, // Glagolitic
-    {begin: 0x2D30, end: 0x2D7F}, // Tifinagh
-    {begin: 0x4DC0, end: 0x4DFF}, // Yijing Hexagram Symbols
-    {begin: 0xA800, end: 0xA82F}, // Syloti Nagri
-    {begin: 0x10000, end: 0x1007F}, // Linear B Syllabary
-    {begin: 0x10140, end: 0x1018F}, // Ancient Greek Numbers
-    {begin: 0x10380, end: 0x1039F}, // Ugaritic
-    {begin: 0x103A0, end: 0x103DF}, // Old Persian
-    {begin: 0x10450, end: 0x1047F}, // Shavian
-    {begin: 0x10480, end: 0x104AF}, // Osmanya
-    {begin: 0x10800, end: 0x1083F}, // Cypriot Syllabary
-    {begin: 0x10A00, end: 0x10A5F}, // Kharoshthi
-    {begin: 0x1D300, end: 0x1D35F}, // Tai Xuan Jing Symbols
-    {begin: 0x12000, end: 0x123FF}, // Cuneiform
-    {begin: 0x1D360, end: 0x1D37F}, // Counting Rod Numerals
-    {begin: 0x1B80, end: 0x1BBF}, // Sundanese
-    {begin: 0x1C00, end: 0x1C4F}, // Lepcha
-    {begin: 0x1C50, end: 0x1C7F}, // Ol Chiki
-    {begin: 0xA880, end: 0xA8DF}, // Saurashtra
-    {begin: 0xA900, end: 0xA92F}, // Kayah Li
-    {begin: 0xA930, end: 0xA95F}, // Rejang
-    {begin: 0xAA00, end: 0xAA5F}, // Cham
-    {begin: 0x10190, end: 0x101CF}, // Ancient Symbols
-    {begin: 0x101D0, end: 0x101FF}, // Phaistos Disc
-    {begin: 0x102A0, end: 0x102DF}, // Carian
-    {begin: 0x1F030, end: 0x1F09F}  // Domino Tiles
-];
-
-function getUnicodeRange(unicode) {
-    for (var i = 0; i < unicodeRanges.length; i += 1) {
-        var range = unicodeRanges[i];
-        if (unicode >= range.begin && unicode < range.end) {
-            return i;
-        }
-    }
-
-    return -1;
-}
-
-// Parse the OS/2 and Windows metrics `OS/2` table
-function parseOS2Table(data, start) {
-    var os2 = {};
-    var p = new parse.Parser(data, start);
-    os2.version = p.parseUShort();
-    os2.xAvgCharWidth = p.parseShort();
-    os2.usWeightClass = p.parseUShort();
-    os2.usWidthClass = p.parseUShort();
-    os2.fsType = p.parseUShort();
-    os2.ySubscriptXSize = p.parseShort();
-    os2.ySubscriptYSize = p.parseShort();
-    os2.ySubscriptXOffset = p.parseShort();
-    os2.ySubscriptYOffset = p.parseShort();
-    os2.ySuperscriptXSize = p.parseShort();
-    os2.ySuperscriptYSize = p.parseShort();
-    os2.ySuperscriptXOffset = p.parseShort();
-    os2.ySuperscriptYOffset = p.parseShort();
-    os2.yStrikeoutSize = p.parseShort();
-    os2.yStrikeoutPosition = p.parseShort();
-    os2.sFamilyClass = p.parseShort();
-    os2.panose = [];
-    for (var i = 0; i < 10; i++) {
-        os2.panose[i] = p.parseByte();
-    }
-
-    os2.ulUnicodeRange1 = p.parseULong();
-    os2.ulUnicodeRange2 = p.parseULong();
-    os2.ulUnicodeRange3 = p.parseULong();
-    os2.ulUnicodeRange4 = p.parseULong();
-    os2.achVendID = String.fromCharCode(p.parseByte(), p.parseByte(), p.parseByte(), p.parseByte());
-    os2.fsSelection = p.parseUShort();
-    os2.usFirstCharIndex = p.parseUShort();
-    os2.usLastCharIndex = p.parseUShort();
-    os2.sTypoAscender = p.parseShort();
-    os2.sTypoDescender = p.parseShort();
-    os2.sTypoLineGap = p.parseShort();
-    os2.usWinAscent = p.parseUShort();
-    os2.usWinDescent = p.parseUShort();
-    if (os2.version >= 1) {
-        os2.ulCodePageRange1 = p.parseULong();
-        os2.ulCodePageRange2 = p.parseULong();
-    }
-
-    if (os2.version >= 2) {
-        os2.sxHeight = p.parseShort();
-        os2.sCapHeight = p.parseShort();
-        os2.usDefaultChar = p.parseUShort();
-        os2.usBreakChar = p.parseUShort();
-        os2.usMaxContent = p.parseUShort();
-    }
-
-    return os2;
-}
-
-function makeOS2Table(options) {
-    return new table.Table('OS/2', [
-        {name: 'version', type: 'USHORT', value: 0x0003},
-        {name: 'xAvgCharWidth', type: 'SHORT', value: 0},
-        {name: 'usWeightClass', type: 'USHORT', value: 0},
-        {name: 'usWidthClass', type: 'USHORT', value: 0},
-        {name: 'fsType', type: 'USHORT', value: 0},
-        {name: 'ySubscriptXSize', type: 'SHORT', value: 650},
-        {name: 'ySubscriptYSize', type: 'SHORT', value: 699},
-        {name: 'ySubscriptXOffset', type: 'SHORT', value: 0},
-        {name: 'ySubscriptYOffset', type: 'SHORT', value: 140},
-        {name: 'ySuperscriptXSize', type: 'SHORT', value: 650},
-        {name: 'ySuperscriptYSize', type: 'SHORT', value: 699},
-        {name: 'ySuperscriptXOffset', type: 'SHORT', value: 0},
-        {name: 'ySuperscriptYOffset', type: 'SHORT', value: 479},
-        {name: 'yStrikeoutSize', type: 'SHORT', value: 49},
-        {name: 'yStrikeoutPosition', type: 'SHORT', value: 258},
-        {name: 'sFamilyClass', type: 'SHORT', value: 0},
-        {name: 'bFamilyType', type: 'BYTE', value: 0},
-        {name: 'bSerifStyle', type: 'BYTE', value: 0},
-        {name: 'bWeight', type: 'BYTE', value: 0},
-        {name: 'bProportion', type: 'BYTE', value: 0},
-        {name: 'bContrast', type: 'BYTE', value: 0},
-        {name: 'bStrokeVariation', type: 'BYTE', value: 0},
-        {name: 'bArmStyle', type: 'BYTE', value: 0},
-        {name: 'bLetterform', type: 'BYTE', value: 0},
-        {name: 'bMidline', type: 'BYTE', value: 0},
-        {name: 'bXHeight', type: 'BYTE', value: 0},
-        {name: 'ulUnicodeRange1', type: 'ULONG', value: 0},
-        {name: 'ulUnicodeRange2', type: 'ULONG', value: 0},
-        {name: 'ulUnicodeRange3', type: 'ULONG', value: 0},
-        {name: 'ulUnicodeRange4', type: 'ULONG', value: 0},
-        {name: 'achVendID', type: 'CHARARRAY', value: 'XXXX'},
-        {name: 'fsSelection', type: 'USHORT', value: 0},
-        {name: 'usFirstCharIndex', type: 'USHORT', value: 0},
-        {name: 'usLastCharIndex', type: 'USHORT', value: 0},
-        {name: 'sTypoAscender', type: 'SHORT', value: 0},
-        {name: 'sTypoDescender', type: 'SHORT', value: 0},
-        {name: 'sTypoLineGap', type: 'SHORT', value: 0},
-        {name: 'usWinAscent', type: 'USHORT', value: 0},
-        {name: 'usWinDescent', type: 'USHORT', value: 0},
-        {name: 'ulCodePageRange1', type: 'ULONG', value: 0},
-        {name: 'ulCodePageRange2', type: 'ULONG', value: 0},
-        {name: 'sxHeight', type: 'SHORT', value: 0},
-        {name: 'sCapHeight', type: 'SHORT', value: 0},
-        {name: 'usDefaultChar', type: 'USHORT', value: 0},
-        {name: 'usBreakChar', type: 'USHORT', value: 0},
-        {name: 'usMaxContext', type: 'USHORT', value: 0}
-    ], options);
-}
-
-var os2 = { parse: parseOS2Table, make: makeOS2Table, unicodeRanges: unicodeRanges, getUnicodeRange: getUnicodeRange };
-
-// The `post` table stores additional PostScript information, such as glyph names.
-
-// Parse the PostScript `post` table
-function parsePostTable(data, start) {
-    var post = {};
-    var p = new parse.Parser(data, start);
-    post.version = p.parseVersion();
-    post.italicAngle = p.parseFixed();
-    post.underlinePosition = p.parseShort();
-    post.underlineThickness = p.parseShort();
-    post.isFixedPitch = p.parseULong();
-    post.minMemType42 = p.parseULong();
-    post.maxMemType42 = p.parseULong();
-    post.minMemType1 = p.parseULong();
-    post.maxMemType1 = p.parseULong();
-    switch (post.version) {
-        case 1:
-            post.names = standardNames.slice();
-            break;
-        case 2:
-            post.numberOfGlyphs = p.parseUShort();
-            post.glyphNameIndex = new Array(post.numberOfGlyphs);
-            for (var i = 0; i < post.numberOfGlyphs; i++) {
-                post.glyphNameIndex[i] = p.parseUShort();
-            }
-
-            post.names = [];
-            for (var i$1 = 0; i$1 < post.numberOfGlyphs; i$1++) {
-                if (post.glyphNameIndex[i$1] >= standardNames.length) {
-                    var nameLength = p.parseChar();
-                    post.names.push(p.parseString(nameLength));
-                }
-            }
-
-            break;
-        case 2.5:
-            post.numberOfGlyphs = p.parseUShort();
-            post.offset = new Array(post.numberOfGlyphs);
-            for (var i$2 = 0; i$2 < post.numberOfGlyphs; i$2++) {
-                post.offset[i$2] = p.parseChar();
-            }
-
-            break;
-    }
-    return post;
-}
-
-function makePostTable() {
-    return new table.Table('post', [
-        {name: 'version', type: 'FIXED', value: 0x00030000},
-        {name: 'italicAngle', type: 'FIXED', value: 0},
-        {name: 'underlinePosition', type: 'FWORD', value: 0},
-        {name: 'underlineThickness', type: 'FWORD', value: 0},
-        {name: 'isFixedPitch', type: 'ULONG', value: 0},
-        {name: 'minMemType42', type: 'ULONG', value: 0},
-        {name: 'maxMemType42', type: 'ULONG', value: 0},
-        {name: 'minMemType1', type: 'ULONG', value: 0},
-        {name: 'maxMemType1', type: 'ULONG', value: 0}
-    ]);
-}
-
-var post = { parse: parsePostTable, make: makePostTable };
-
-// The `GSUB` table contains ligatures, among other things.
-
-var subtableParsers = new Array(9);         // subtableParsers[0] is unused
-
-// https://www.microsoft.com/typography/OTSPEC/GSUB.htm#SS
-subtableParsers[1] = function parseLookup1() {
-    var start = this.offset + this.relativeOffset;
-    var substFormat = this.parseUShort();
-    if (substFormat === 1) {
-        return {
-            substFormat: 1,
-            coverage: this.parsePointer(Parser.coverage),
-            deltaGlyphId: this.parseUShort()
-        };
-    } else if (substFormat === 2) {
-        return {
-            substFormat: 2,
-            coverage: this.parsePointer(Parser.coverage),
-            substitute: this.parseOffset16List()
-        };
-    }
-    check.assert(false, '0x' + start.toString(16) + ': lookup type 1 format must be 1 or 2.');
-};
-
-// https://www.microsoft.com/typography/OTSPEC/GSUB.htm#MS
-subtableParsers[2] = function parseLookup2() {
-    var substFormat = this.parseUShort();
-    check.argument(substFormat === 1, 'GSUB Multiple Substitution Subtable identifier-format must be 1');
-    return {
-        substFormat: substFormat,
-        coverage: this.parsePointer(Parser.coverage),
-        sequences: this.parseListOfLists()
-    };
-};
-
-// https://www.microsoft.com/typography/OTSPEC/GSUB.htm#AS
-subtableParsers[3] = function parseLookup3() {
-    var substFormat = this.parseUShort();
-    check.argument(substFormat === 1, 'GSUB Alternate Substitution Subtable identifier-format must be 1');
-    return {
-        substFormat: substFormat,
-        coverage: this.parsePointer(Parser.coverage),
-        alternateSets: this.parseListOfLists()
-    };
-};
-
-// https://www.microsoft.com/typography/OTSPEC/GSUB.htm#LS
-subtableParsers[4] = function parseLookup4() {
-    var substFormat = this.parseUShort();
-    check.argument(substFormat === 1, 'GSUB ligature table identifier-format must be 1');
-    return {
-        substFormat: substFormat,
-        coverage: this.parsePointer(Parser.coverage),
-        ligatureSets: this.parseListOfLists(function() {
-            return {
-                ligGlyph: this.parseUShort(),
-                components: this.parseUShortList(this.parseUShort() - 1)
-            };
-        })
-    };
-};
-
-var lookupRecordDesc = {
-    sequenceIndex: Parser.uShort,
-    lookupListIndex: Parser.uShort
-};
-
-// https://www.microsoft.com/typography/OTSPEC/GSUB.htm#CSF
-subtableParsers[5] = function parseLookup5() {
-    var start = this.offset + this.relativeOffset;
-    var substFormat = this.parseUShort();
-
-    if (substFormat === 1) {
-        return {
-            substFormat: substFormat,
-            coverage: this.parsePointer(Parser.coverage),
-            ruleSets: this.parseListOfLists(function() {
-                var glyphCount = this.parseUShort();
-                var substCount = this.parseUShort();
-                return {
-                    input: this.parseUShortList(glyphCount - 1),
-                    lookupRecords: this.parseRecordList(substCount, lookupRecordDesc)
-                };
-            })
-        };
-    } else if (substFormat === 2) {
-        return {
-            substFormat: substFormat,
-            coverage: this.parsePointer(Parser.coverage),
-            classDef: this.parsePointer(Parser.classDef),
-            classSets: this.parseListOfLists(function() {
-                var glyphCount = this.parseUShort();
-                var substCount = this.parseUShort();
-                return {
-                    classes: this.parseUShortList(glyphCount - 1),
-                    lookupRecords: this.parseRecordList(substCount, lookupRecordDesc)
-                };
-            })
-        };
-    } else if (substFormat === 3) {
-        var glyphCount = this.parseUShort();
-        var substCount = this.parseUShort();
-        return {
-            substFormat: substFormat,
-            coverages: this.parseList(glyphCount, Parser.pointer(Parser.coverage)),
-            lookupRecords: this.parseRecordList(substCount, lookupRecordDesc)
-        };
-    }
-    check.assert(false, '0x' + start.toString(16) + ': lookup type 5 format must be 1, 2 or 3.');
-};
-
-// https://www.microsoft.com/typography/OTSPEC/GSUB.htm#CC
-subtableParsers[6] = function parseLookup6() {
-    var start = this.offset + this.relativeOffset;
-    var substFormat = this.parseUShort();
-    if (substFormat === 1) {
-        return {
-            substFormat: 1,
-            coverage: this.parsePointer(Parser.coverage),
-            chainRuleSets: this.parseListOfLists(function() {
-                return {
-                    backtrack: this.parseUShortList(),
-                    input: this.parseUShortList(this.parseShort() - 1),
-                    lookahead: this.parseUShortList(),
-                    lookupRecords: this.parseRecordList(lookupRecordDesc)
-                };
-            })
-        };
-    } else if (substFormat === 2) {
-        return {
-            substFormat: 2,
-            coverage: this.parsePointer(Parser.coverage),
-            backtrackClassDef: this.parsePointer(Parser.classDef),
-            inputClassDef: this.parsePointer(Parser.classDef),
-            lookaheadClassDef: this.parsePointer(Parser.classDef),
-            chainClassSet: this.parseListOfLists(function() {
-                return {
-                    backtrack: this.parseUShortList(),
-                    input: this.parseUShortList(this.parseShort() - 1),
-                    lookahead: this.parseUShortList(),
-                    lookupRecords: this.parseRecordList(lookupRecordDesc)
-                };
-            })
-        };
-    } else if (substFormat === 3) {
-        return {
-            substFormat: 3,
-            backtrackCoverage: this.parseList(Parser.pointer(Parser.coverage)),
-            inputCoverage: this.parseList(Parser.pointer(Parser.coverage)),
-            lookaheadCoverage: this.parseList(Parser.pointer(Parser.coverage)),
-            lookupRecords: this.parseRecordList(lookupRecordDesc)
-        };
-    }
-    check.assert(false, '0x' + start.toString(16) + ': lookup type 6 format must be 1, 2 or 3.');
-};
-
-// https://www.microsoft.com/typography/OTSPEC/GSUB.htm#ES
-subtableParsers[7] = function parseLookup7() {
-    // Extension Substitution subtable
-    var substFormat = this.parseUShort();
-    check.argument(substFormat === 1, 'GSUB Extension Substitution subtable identifier-format must be 1');
-    var extensionLookupType = this.parseUShort();
-    var extensionParser = new Parser(this.data, this.offset + this.parseULong());
-    return {
-        substFormat: 1,
-        lookupType: extensionLookupType,
-        extension: subtableParsers[extensionLookupType].call(extensionParser)
-    };
-};
-
-// https://www.microsoft.com/typography/OTSPEC/GSUB.htm#RCCS
-subtableParsers[8] = function parseLookup8() {
-    var substFormat = this.parseUShort();
-    check.argument(substFormat === 1, 'GSUB Reverse Chaining Contextual Single Substitution Subtable identifier-format must be 1');
-    return {
-        substFormat: substFormat,
-        coverage: this.parsePointer(Parser.coverage),
-        backtrackCoverage: this.parseList(Parser.pointer(Parser.coverage)),
-        lookaheadCoverage: this.parseList(Parser.pointer(Parser.coverage)),
-        substitutes: this.parseUShortList()
-    };
-};
-
-// https://www.microsoft.com/typography/OTSPEC/gsub.htm
-function parseGsubTable(data, start) {
-    start = start || 0;
-    var p = new Parser(data, start);
-    var tableVersion = p.parseVersion(1);
-    check.argument(tableVersion === 1 || tableVersion === 1.1, 'Unsupported GSUB table version.');
-    if (tableVersion === 1) {
-        return {
-            version: tableVersion,
-            scripts: p.parseScriptList(),
-            features: p.parseFeatureList(),
-            lookups: p.parseLookupList(subtableParsers)
-        };
-    } else {
-        return {
-            version: tableVersion,
-            scripts: p.parseScriptList(),
-            features: p.parseFeatureList(),
-            lookups: p.parseLookupList(subtableParsers),
-            variations: p.parseFeatureVariationsList()
-        };
-    }
-
-}
-
-// GSUB Writing //////////////////////////////////////////////
-var subtableMakers = new Array(9);
-
-subtableMakers[1] = function makeLookup1(subtable) {
-    if (subtable.substFormat === 1) {
-        return new table.Table('substitutionTable', [
-            {name: 'substFormat', type: 'USHORT', value: 1},
-            {name: 'coverage', type: 'TABLE', value: new table.Coverage(subtable.coverage)},
-            {name: 'deltaGlyphID', type: 'USHORT', value: subtable.deltaGlyphId}
-        ]);
-    } else {
-        return new table.Table('substitutionTable', [
-            {name: 'substFormat', type: 'USHORT', value: 2},
-            {name: 'coverage', type: 'TABLE', value: new table.Coverage(subtable.coverage)}
-        ].concat(table.ushortList('substitute', subtable.substitute)));
-    }
-};
-
-subtableMakers[2] = function makeLookup2(subtable) {
-    check.assert(subtable.substFormat === 1, 'Lookup type 2 substFormat must be 1.');
-    return new table.Table('substitutionTable', [
-        {name: 'substFormat', type: 'USHORT', value: 1},
-        {name: 'coverage', type: 'TABLE', value: new table.Coverage(subtable.coverage)}
-    ].concat(table.tableList('seqSet', subtable.sequences, function(sequenceSet) {
-        return new table.Table('sequenceSetTable', table.ushortList('sequence', sequenceSet));
-    })));
-};
-
-subtableMakers[3] = function makeLookup3(subtable) {
-    check.assert(subtable.substFormat === 1, 'Lookup type 3 substFormat must be 1.');
-    return new table.Table('substitutionTable', [
-        {name: 'substFormat', type: 'USHORT', value: 1},
-        {name: 'coverage', type: 'TABLE', value: new table.Coverage(subtable.coverage)}
-    ].concat(table.tableList('altSet', subtable.alternateSets, function(alternateSet) {
-        return new table.Table('alternateSetTable', table.ushortList('alternate', alternateSet));
-    })));
-};
-
-subtableMakers[4] = function makeLookup4(subtable) {
-    check.assert(subtable.substFormat === 1, 'Lookup type 4 substFormat must be 1.');
-    return new table.Table('substitutionTable', [
-        {name: 'substFormat', type: 'USHORT', value: 1},
-        {name: 'coverage', type: 'TABLE', value: new table.Coverage(subtable.coverage)}
-    ].concat(table.tableList('ligSet', subtable.ligatureSets, function(ligatureSet) {
-        return new table.Table('ligatureSetTable', table.tableList('ligature', ligatureSet, function(ligature) {
-            return new table.Table('ligatureTable',
-                [{name: 'ligGlyph', type: 'USHORT', value: ligature.ligGlyph}]
-                .concat(table.ushortList('component', ligature.components, ligature.components.length + 1))
-            );
-        }));
-    })));
-};
-
-subtableMakers[6] = function makeLookup6(subtable) {
-    if (subtable.substFormat === 1) {
-        var returnTable = new table.Table('chainContextTable', [
-            {name: 'substFormat', type: 'USHORT', value: subtable.substFormat},
-            {name: 'coverage', type: 'TABLE', value: new table.Coverage(subtable.coverage)}
-        ].concat(table.tableList('chainRuleSet', subtable.chainRuleSets, function(chainRuleSet) {
-            return new table.Table('chainRuleSetTable', table.tableList('chainRule', chainRuleSet, function(chainRule) {
-                var tableData = table.ushortList('backtrackGlyph', chainRule.backtrack, chainRule.backtrack.length)
-                    .concat(table.ushortList('inputGlyph', chainRule.input, chainRule.input.length + 1))
-                    .concat(table.ushortList('lookaheadGlyph', chainRule.lookahead, chainRule.lookahead.length))
-                    .concat(table.ushortList('substitution', [], chainRule.lookupRecords.length));
-
-                chainRule.lookupRecords.forEach(function (record, i) {
-                    tableData = tableData
-                        .concat({name: 'sequenceIndex' + i, type: 'USHORT', value: record.sequenceIndex})
-                        .concat({name: 'lookupListIndex' + i, type: 'USHORT', value: record.lookupListIndex});
-                });
-                return new table.Table('chainRuleTable', tableData);
-            }));
-        })));
-        return returnTable;
-    } else if (subtable.substFormat === 2) {
-        check.assert(false, 'lookup type 6 format 2 is not yet supported.');
-    } else if (subtable.substFormat === 3) {
-        var tableData = [
-            {name: 'substFormat', type: 'USHORT', value: subtable.substFormat} ];
-
-        tableData.push({name: 'backtrackGlyphCount', type: 'USHORT', value: subtable.backtrackCoverage.length});
-        subtable.backtrackCoverage.forEach(function (coverage, i) {
-            tableData.push({name: 'backtrackCoverage' + i, type: 'TABLE', value: new table.Coverage(coverage)});
-        });
-        tableData.push({name: 'inputGlyphCount', type: 'USHORT', value: subtable.inputCoverage.length});
-        subtable.inputCoverage.forEach(function (coverage, i) {
-            tableData.push({name: 'inputCoverage' + i, type: 'TABLE', value: new table.Coverage(coverage)});
-        });
-        tableData.push({name: 'lookaheadGlyphCount', type: 'USHORT', value: subtable.lookaheadCoverage.length});
-        subtable.lookaheadCoverage.forEach(function (coverage, i) {
-            tableData.push({name: 'lookaheadCoverage' + i, type: 'TABLE', value: new table.Coverage(coverage)});
-        });
-
-        tableData.push({name: 'substitutionCount', type: 'USHORT', value: subtable.lookupRecords.length});
-        subtable.lookupRecords.forEach(function (record, i) {
-            tableData = tableData
-                .concat({name: 'sequenceIndex' + i, type: 'USHORT', value: record.sequenceIndex})
-                .concat({name: 'lookupListIndex' + i, type: 'USHORT', value: record.lookupListIndex});
-        });
-
-        var returnTable$1 = new table.Table('chainContextTable', tableData);
-
-        return returnTable$1;
-    }
-
-    check.assert(false, 'lookup type 6 format must be 1, 2 or 3.');
-};
-
-function makeGsubTable(gsub) {
-    return new table.Table('GSUB', [
-        {name: 'version', type: 'ULONG', value: 0x10000},
-        {name: 'scripts', type: 'TABLE', value: new table.ScriptList(gsub.scripts)},
-        {name: 'features', type: 'TABLE', value: new table.FeatureList(gsub.features)},
-        {name: 'lookups', type: 'TABLE', value: new table.LookupList(gsub.lookups, subtableMakers)}
-    ]);
-}
-
-var gsub = { parse: parseGsubTable, make: makeGsubTable };
-
-// The `GPOS` table contains kerning pairs, among other things.
-
-// Parse the metadata `meta` table.
-// https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6meta.html
-function parseMetaTable(data, start) {
-    var p = new parse.Parser(data, start);
-    var tableVersion = p.parseULong();
-    check.argument(tableVersion === 1, 'Unsupported META table version.');
-    p.parseULong(); // flags - currently unused and set to 0
-    p.parseULong(); // tableOffset
-    var numDataMaps = p.parseULong();
-
-    var tags = {};
-    for (var i = 0; i < numDataMaps; i++) {
-        var tag = p.parseTag();
-        var dataOffset = p.parseULong();
-        var dataLength = p.parseULong();
-        var text = decode.UTF8(data, start + dataOffset, dataLength);
-
-        tags[tag] = text;
-    }
-    return tags;
-}
-
-function makeMetaTable(tags) {
-    var numTags = Object.keys(tags).length;
-    var stringPool = '';
-    var stringPoolOffset = 16 + numTags * 12;
-
-    var result = new table.Table('meta', [
-        {name: 'version', type: 'ULONG', value: 1},
-        {name: 'flags', type: 'ULONG', value: 0},
-        {name: 'offset', type: 'ULONG', value: stringPoolOffset},
-        {name: 'numTags', type: 'ULONG', value: numTags}
-    ]);
-
-    for (var tag in tags) {
-        var pos = stringPool.length;
-        stringPool += tags[tag];
-
-        result.fields.push({name: 'tag ' + tag, type: 'TAG', value: tag});
-        result.fields.push({name: 'offset ' + tag, type: 'ULONG', value: stringPoolOffset + pos});
-        result.fields.push({name: 'length ' + tag, type: 'ULONG', value: tags[tag].length});
-    }
-
-    result.fields.push({name: 'stringPool', type: 'CHARARRAY', value: stringPool});
-
-    return result;
-}
-
-var meta = { parse: parseMetaTable, make: makeMetaTable };
-
-// The `COLR` table adds support for multi-colored glyphs
-
-function parseColrTable(data, start) {
-    var p = new Parser(data, start);
-    var version = p.parseUShort();
-    check.argument(version === 0x0000, 'Only COLRv0 supported.');
-    var numBaseGlyphRecords = p.parseUShort();
-    var baseGlyphRecordsOffset = p.parseOffset32();
-    var layerRecordsOffset = p.parseOffset32();
-    var numLayerRecords = p.parseUShort();
-    p.relativeOffset = baseGlyphRecordsOffset;
-    var baseGlyphRecords = p.parseRecordList(numBaseGlyphRecords, {
-        glyphID: Parser.uShort,
-        firstLayerIndex: Parser.uShort,
-        numLayers: Parser.uShort,
-    });
-    p.relativeOffset = layerRecordsOffset;
-    var layerRecords = p.parseRecordList(numLayerRecords, {
-        glyphID: Parser.uShort,
-        paletteIndex: Parser.uShort
-    });
-
-    return {
-        version: version,
-        baseGlyphRecords: baseGlyphRecords,
-        layerRecords: layerRecords,
-    };
-}
-
-function makeColrTable(ref) {
-    var version = ref.version; if ( version === void 0 ) version = 0x0000;
-    var baseGlyphRecords = ref.baseGlyphRecords; if ( baseGlyphRecords === void 0 ) baseGlyphRecords = [];
-    var layerRecords = ref.layerRecords; if ( layerRecords === void 0 ) layerRecords = [];
-
-    check.argument(version === 0x0000, 'Only COLRv0 supported.');
-    var baseGlyphRecordsOffset = 14;
-    var layerRecordsOffset = baseGlyphRecordsOffset + (baseGlyphRecords.length * 6);
-    return new table.Table('COLR', [
-        { name: 'version', type: 'USHORT', value: version },
-        { name: 'numBaseGlyphRecords', type: 'USHORT', value: baseGlyphRecords.length },
-        { name: 'baseGlyphRecordsOffset', type: 'ULONG', value: baseGlyphRecordsOffset },
-        { name: 'layerRecordsOffset', type: 'ULONG', value: layerRecordsOffset },
-        { name: 'numLayerRecords', type: 'USHORT', value: layerRecords.length } ].concat( baseGlyphRecords.map(function (glyph, i) { return [
-            { name: 'glyphID_' + i, type: 'USHORT', value: glyph.glyphID },
-            { name: 'firstLayerIndex_' + i, type: 'USHORT', value: glyph.firstLayerIndex },
-            { name: 'numLayers_' + i, type: 'USHORT', value: glyph.numLayers } ]; }).flat(),
-        layerRecords.map(function (layer, i) { return [
-            { name: 'LayerGlyphID_' + i, type: 'USHORT', value: layer.glyphID },
-            { name: 'paletteIndex_' + i, type: 'USHORT', value: layer.paletteIndex } ]; }).flat() ));
-}
-
-var colr = { parse: parseColrTable, make: makeColrTable };
-
-// The `CPAL` define a contiguous list of colors (colorRecords)
-
-// Parse the header `head` table
-function parseCpalTable(data, start) {
-  var p = new Parser(data, start);
-  var version = p.parseShort();
-  var numPaletteEntries = p.parseShort();
-  var numPalettes = p.parseShort();
-  var numColorRecords = p.parseShort();
-  var colorRecordsArrayOffset = p.parseOffset32();
-  var colorRecordIndices = p.parseUShortList(numPalettes);
-  p.relativeOffset = colorRecordsArrayOffset;
-  var colorRecords = p.parseULongList(numColorRecords);
-  return {
-    version: version,
-    numPaletteEntries: numPaletteEntries,
-    colorRecords: colorRecords,
-    colorRecordIndices: colorRecordIndices,
-  };
-}
-
-function makeCpalTable(ref) {
-  var version = ref.version; if ( version === void 0 ) version = 0;
-  var numPaletteEntries = ref.numPaletteEntries; if ( numPaletteEntries === void 0 ) numPaletteEntries = 0;
-  var colorRecords = ref.colorRecords; if ( colorRecords === void 0 ) colorRecords = [];
-  var colorRecordIndices = ref.colorRecordIndices; if ( colorRecordIndices === void 0 ) colorRecordIndices = [0];
-
-  check.argument(version === 0, 'Only CPALv0 are supported.');
-  check.argument(colorRecords.length, 'No colorRecords given.');
-  check.argument(colorRecordIndices.length, 'No colorRecordIndices given.');
-  check.argument(!numPaletteEntries && colorRecordIndices.length == 1, 'Can\'t infer numPaletteEntries on multiple colorRecordIndices');
-  return new table.Table('CPAL', [
-    { name: 'version', type: 'USHORT', value: version },
-    { name: 'numPaletteEntries', type: 'USHORT', value: numPaletteEntries || colorRecords.length },
-    { name: 'numPalettes', type: 'USHORT', value: colorRecordIndices.length },
-    { name: 'numColorRecords', type: 'USHORT', value: colorRecords.length },
-    { name: 'colorRecordsArrayOffset', type: 'ULONG', value: 12 + 2 * colorRecordIndices.length } ].concat( colorRecordIndices.map(function (palette, i) { return ({ name: 'colorRecordIndices_' + i, type: 'USHORT', value: palette }); }),
-    colorRecords.map(function (color, i) { return ({ name: 'colorRecords_' + i, type: 'ULONG', value: color }); }) ));
-}
-
-var cpal = { parse: parseCpalTable, make: makeCpalTable };
-
-// The `sfnt` wrapper provides organization for the tables in the font.
-
-function log2(v) {
-    return Math.log(v) / Math.log(2) | 0;
-}
-
-function computeCheckSum(bytes) {
-    while (bytes.length % 4 !== 0) {
-        bytes.push(0);
-    }
-
-    var sum = 0;
-    for (var i = 0; i < bytes.length; i += 4) {
-        sum += (bytes[i] << 24) +
-            (bytes[i + 1] << 16) +
-            (bytes[i + 2] << 8) +
-            (bytes[i + 3]);
-    }
-
-    sum %= Math.pow(2, 32);
-    return sum;
-}
-
-function makeTableRecord(tag, checkSum, offset, length) {
-    return new table.Record('Table Record', [
-        {name: 'tag', type: 'TAG', value: tag !== undefined ? tag : ''},
-        {name: 'checkSum', type: 'ULONG', value: checkSum !== undefined ? checkSum : 0},
-        {name: 'offset', type: 'ULONG', value: offset !== undefined ? offset : 0},
-        {name: 'length', type: 'ULONG', value: length !== undefined ? length : 0}
-    ]);
-}
-
-function makeSfntTable(tables) {
-    var sfnt = new table.Table('sfnt', [
-        {name: 'version', type: 'TAG', value: 'OTTO'},
-        {name: 'numTables', type: 'USHORT', value: 0},
-        {name: 'searchRange', type: 'USHORT', value: 0},
-        {name: 'entrySelector', type: 'USHORT', value: 0},
-        {name: 'rangeShift', type: 'USHORT', value: 0}
-    ]);
-    sfnt.tables = tables;
-    sfnt.numTables = tables.length;
-    var highestPowerOf2 = Math.pow(2, log2(sfnt.numTables));
-    sfnt.searchRange = 16 * highestPowerOf2;
-    sfnt.entrySelector = log2(highestPowerOf2);
-    sfnt.rangeShift = sfnt.numTables * 16 - sfnt.searchRange;
-
-    var recordFields = [];
-    var tableFields = [];
-
-    var offset = sfnt.sizeOf() + (makeTableRecord().sizeOf() * sfnt.numTables);
-    while (offset % 4 !== 0) {
-        offset += 1;
-        tableFields.push({name: 'padding', type: 'BYTE', value: 0});
-    }
-
-    for (var i = 0; i < tables.length; i += 1) {
-        var t = tables[i];
-        check.argument(t.tableName.length === 4, 'Table name' + t.tableName + ' is invalid.');
-        var tableLength = t.sizeOf();
-        var tableRecord = makeTableRecord(t.tableName, computeCheckSum(t.encode()), offset, tableLength);
-        recordFields.push({name: tableRecord.tag + ' Table Record', type: 'RECORD', value: tableRecord});
-        tableFields.push({name: t.tableName + ' table', type: 'RECORD', value: t});
-        offset += tableLength;
-        check.argument(!isNaN(offset), 'Something went wrong calculating the offset.');
-        while (offset % 4 !== 0) {
-            offset += 1;
-            tableFields.push({name: 'padding', type: 'BYTE', value: 0});
-        }
-    }
-
-    // Table records need to be sorted alphabetically.
-    recordFields.sort(function(r1, r2) {
-        if (r1.value.tag > r2.value.tag) {
-            return 1;
-        } else {
-            return -1;
-        }
-    });
-
-    sfnt.fields = sfnt.fields.concat(recordFields);
-    sfnt.fields = sfnt.fields.concat(tableFields);
-    return sfnt;
-}
-
-// Get the metrics for a character. If the string has more than one character
-// this function returns metrics for the first available character.
-// You can provide optional fallback metrics if no characters are available.
-function metricsForChar(font, chars, notFoundMetrics) {
-    for (var i = 0; i < chars.length; i += 1) {
-        var glyphIndex = font.charToGlyphIndex(chars[i]);
-        if (glyphIndex > 0) {
-            var glyph = font.glyphs.get(glyphIndex);
-            return glyph.getMetrics();
-        }
-    }
-
-    return notFoundMetrics;
-}
-
-function average(vs) {
-    var sum = 0;
-    for (var i = 0; i < vs.length; i += 1) {
-        sum += vs[i];
-    }
-
-    return sum / vs.length;
-}
-
-// Convert the font object to a SFNT data structure.
-// This structure contains all the necessary tables and metadata to create a binary OTF file.
-function fontToSfntTable(font) {
-    var xMins = [];
-    var yMins = [];
-    var xMaxs = [];
-    var yMaxs = [];
-    var advanceWidths = [];
-    var leftSideBearings = [];
-    var rightSideBearings = [];
-    var firstCharIndex;
-    var lastCharIndex = 0;
-    var ulUnicodeRange1 = 0;
-    var ulUnicodeRange2 = 0;
-    var ulUnicodeRange3 = 0;
-    var ulUnicodeRange4 = 0;
-
-    for (var i = 0; i < font.glyphs.length; i += 1) {
-        var glyph = font.glyphs.get(i);
-        var unicode = glyph.unicode | 0;
-
-        if (isNaN(glyph.advanceWidth)) {
-            throw new Error('Glyph ' + glyph.name + ' (' + i + '): advanceWidth is not a number.');
-        }
-
-        if (firstCharIndex > unicode || firstCharIndex === undefined) {
-            // ignore .notdef char
-            if (unicode > 0) {
-                firstCharIndex = unicode;
-            }
-        }
-
-        if (lastCharIndex < unicode) {
-            lastCharIndex = unicode;
-        }
-
-        var position = os2.getUnicodeRange(unicode);
-        if (position < 32) {
-            ulUnicodeRange1 |= 1 << position;
-        } else if (position < 64) {
-            ulUnicodeRange2 |= 1 << position - 32;
-        } else if (position < 96) {
-            ulUnicodeRange3 |= 1 << position - 64;
-        } else if (position < 123) {
-            ulUnicodeRange4 |= 1 << position - 96;
-        } else {
-            throw new Error('Unicode ranges bits > 123 are reserved for internal usage');
-        }
-        // Skip non-important characters.
-        if (glyph.name === '.notdef') { continue; }
-        var metrics = glyph.getMetrics();
-        xMins.push(metrics.xMin);
-        yMins.push(metrics.yMin);
-        xMaxs.push(metrics.xMax);
-        yMaxs.push(metrics.yMax);
-        leftSideBearings.push(metrics.leftSideBearing);
-        rightSideBearings.push(metrics.rightSideBearing);
-        advanceWidths.push(glyph.advanceWidth);
-    }
-
-    var globals = {
-        xMin: Math.min.apply(null, xMins),
-        yMin: Math.min.apply(null, yMins),
-        xMax: Math.max.apply(null, xMaxs),
-        yMax: Math.max.apply(null, yMaxs),
-        advanceWidthMax: Math.max.apply(null, advanceWidths),
-        advanceWidthAvg: average(advanceWidths),
-        minLeftSideBearing: Math.min.apply(null, leftSideBearings),
-        maxLeftSideBearing: Math.max.apply(null, leftSideBearings),
-        minRightSideBearing: Math.min.apply(null, rightSideBearings)
-    };
-    globals.ascender = font.ascender;
-    globals.descender = font.descender;
-
-    var headTable = head.make({
-        flags: 3, // 00000011 (baseline for font at y=0; left sidebearing point at x=0)
-        unitsPerEm: font.unitsPerEm,
-        xMin: globals.xMin,
-        yMin: globals.yMin,
-        xMax: globals.xMax,
-        yMax: globals.yMax,
-        lowestRecPPEM: 3,
-        createdTimestamp: font.createdTimestamp
-    });
-
-    var hheaTable = hhea.make({
-        ascender: globals.ascender,
-        descender: globals.descender,
-        advanceWidthMax: globals.advanceWidthMax,
-        minLeftSideBearing: globals.minLeftSideBearing,
-        minRightSideBearing: globals.minRightSideBearing,
-        xMaxExtent: globals.maxLeftSideBearing + (globals.xMax - globals.xMin),
-        numberOfHMetrics: font.glyphs.length
-    });
-
-    var maxpTable = maxp.make(font.glyphs.length);
-
-    var os2Table = os2.make(Object.assign({
-        xAvgCharWidth: Math.round(globals.advanceWidthAvg),
-        usFirstCharIndex: firstCharIndex,
-        usLastCharIndex: lastCharIndex,
-        ulUnicodeRange1: ulUnicodeRange1,
-        ulUnicodeRange2: ulUnicodeRange2,
-        ulUnicodeRange3: ulUnicodeRange3,
-        ulUnicodeRange4: ulUnicodeRange4,
-        // See http://typophile.com/node/13081 for more info on vertical metrics.
-        // We get metrics for typical characters (such as "x" for xHeight).
-        // We provide some fallback characters if characters are unavailable: their
-        // ordering was chosen experimentally.
-        sTypoAscender: globals.ascender,
-        sTypoDescender: globals.descender,
-        sTypoLineGap: 0,
-        usWinAscent: globals.yMax,
-        usWinDescent: Math.abs(globals.yMin),
-        ulCodePageRange1: 1, // FIXME: hard-code Latin 1 support for now
-        sxHeight: metricsForChar(font, 'xyvw', {yMax: Math.round(globals.ascender / 2)}).yMax,
-        sCapHeight: metricsForChar(font, 'HIKLEFJMNTZBDPRAGOQSUVWXY', globals).yMax,
-        usDefaultChar: font.hasChar(' ') ? 32 : 0, // Use space as the default character, if available.
-        usBreakChar: font.hasChar(' ') ? 32 : 0, // Use space as the break character, if available.
-    }, font.tables.os2));
-
-    var hmtxTable = hmtx.make(font.glyphs);
-    var cmapTable = cmap.make(font.glyphs);
-
-    var englishFamilyName = font.getEnglishName('fontFamily');
-    var englishStyleName = font.getEnglishName('fontSubfamily');
-    var englishFullName = englishFamilyName + ' ' + englishStyleName;
-    var postScriptName = font.getEnglishName('postScriptName');
-    if (!postScriptName) {
-        postScriptName = englishFamilyName.replace(/\s/g, '') + '-' + englishStyleName;
-    }
-
-    var names = {};
-    for (var n in font.names) {
-        names[n] = font.names[n];
-    }
-
-    if (!names.uniqueID) {
-        names.uniqueID = {en: font.getEnglishName('manufacturer') + ':' + englishFullName};
-    }
-
-    if (!names.postScriptName) {
-        names.postScriptName = {en: postScriptName};
-    }
-
-    if (!names.preferredFamily) {
-        names.preferredFamily = font.names.fontFamily;
-    }
-
-    if (!names.preferredSubfamily) {
-        names.preferredSubfamily = font.names.fontSubfamily;
-    }
-
-    var languageTags = [];
-    var nameTable = _name.make(names, languageTags);
-    var ltagTable = (languageTags.length > 0 ? ltag.make(languageTags) : undefined);
-
-    var postTable = post.make();
-    var cffTable = cff.make(font.glyphs, {
-        version: font.getEnglishName('version'),
-        fullName: englishFullName,
-        familyName: englishFamilyName,
-        weightName: englishStyleName,
-        postScriptName: postScriptName,
-        unitsPerEm: font.unitsPerEm,
-        fontBBox: [0, globals.yMin, globals.ascender, globals.advanceWidthMax]
-    });
-
-    var metaTable = (font.metas && Object.keys(font.metas).length > 0) ? meta.make(font.metas) : undefined;
-
-    // The order does not matter because makeSfntTable() will sort them.
-    var tables = [headTable, hheaTable, maxpTable, os2Table, nameTable, cmapTable, postTable, cffTable, hmtxTable];
-    if (ltagTable) {
-        tables.push(ltagTable);
-    }
-    // Optional tables
-    if (font.tables.gsub) {
-        tables.push(gsub.make(font.tables.gsub));
-    }
-    if (font.tables.cpal) {
-        tables.push(cpal.make(font.tables.cpal));
-    }
-    if (font.tables.colr) {
-        tables.push(colr.make(font.tables.colr));
-    }
-    if (metaTable) {
-        tables.push(metaTable);
-    }
-
-    var sfntTable = makeSfntTable(tables);
-
-    // Compute the font's checkSum and store it in head.checkSumAdjustment.
-    var bytes = sfntTable.encode();
-    var checkSum = computeCheckSum(bytes);
-    var tableFields = sfntTable.fields;
-    var checkSumAdjusted = false;
-    for (var i$1 = 0; i$1 < tableFields.length; i$1 += 1) {
-        if (tableFields[i$1].name === 'head table') {
-            tableFields[i$1].value.checkSumAdjustment = 0xB1B0AFBA - checkSum;
-            checkSumAdjusted = true;
-            break;
-        }
-    }
-
-    if (!checkSumAdjusted) {
-        throw new Error('Could not find head table with checkSum to adjust.');
-    }
-
-    return sfntTable;
-}
-
-var sfnt = { make: makeSfntTable, fontToTable: fontToSfntTable, computeCheckSum: computeCheckSum };
-
-// The Layout object is the prototype of Substitution objects, and provides
-
-function searchTag(arr, tag) {
-    /* jshint bitwise: false */
-    var imin = 0;
-    var imax = arr.length - 1;
-    while (imin <= imax) {
-        var imid = (imin + imax) >>> 1;
-        var val = arr[imid].tag;
-        if (val === tag) {
-            return imid;
-        } else if (val < tag) {
-            imin = imid + 1;
-        } else { imax = imid - 1; }
-    }
-    // Not found: return -1-insertion point
-    return -imin - 1;
-}
-
-function binSearch(arr, value) {
-    /* jshint bitwise: false */
-    var imin = 0;
-    var imax = arr.length - 1;
-    while (imin <= imax) {
-        var imid = (imin + imax) >>> 1;
-        var val = arr[imid];
-        if (val === value) {
-            return imid;
-        } else if (val < value) {
-            imin = imid + 1;
-        } else { imax = imid - 1; }
-    }
-    // Not found: return -1-insertion point
-    return -imin - 1;
-}
-
-// binary search in a list of ranges (coverage, class definition)
-function searchRange(ranges, value) {
-    // jshint bitwise: false
-    var range;
-    var imin = 0;
-    var imax = ranges.length - 1;
-    while (imin <= imax) {
-        var imid = (imin + imax) >>> 1;
-        range = ranges[imid];
-        var start = range.start;
-        if (start === value) {
-            return range;
-        } else if (start < value) {
-            imin = imid + 1;
-        } else { imax = imid - 1; }
-    }
-    if (imin > 0) {
-        range = ranges[imin - 1];
-        if (value > range.end) { return 0; }
-        return range;
-    }
-}
-
-/**
- * @exports opentype.Layout
- * @class
- */
-function Layout(font, tableName) {
-    this.font = font;
-    this.tableName = tableName;
-}
-
-Layout.prototype = {
-
-    /**
-     * Binary search an object by "tag" property
-     * @instance
-     * @function searchTag
-     * @memberof opentype.Layout
-     * @param  {Array} arr
-     * @param  {string} tag
-     * @return {number}
-     */
-    searchTag: searchTag,
-
-    /**
-     * Binary search in a list of numbers
-     * @instance
-     * @function binSearch
-     * @memberof opentype.Layout
-     * @param  {Array} arr
-     * @param  {number} value
-     * @return {number}
-     */
-    binSearch: binSearch,
-
-    /**
-     * Get or create the Layout table (GSUB, GPOS etc).
-     * @param  {boolean} create - Whether to create a new one.
-     * @return {Object} The GSUB or GPOS table.
-     */
-    getTable: function(create) {
-        var layout = this.font.tables[this.tableName];
-        if (!layout && create) {
-            layout = this.font.tables[this.tableName] = this.createDefaultTable();
-        }
-        return layout;
-    },
-
-    /**
-     * Returns all scripts in the substitution table.
-     * @instance
-     * @return {Array}
-     */
-    getScriptNames: function() {
-        var layout = this.getTable();
-        if (!layout) { return []; }
-        return layout.scripts.map(function(script) {
-            return script.tag;
-        });
-    },
-
-    /**
-     * Returns the best bet for a script name.
-     * Returns 'DFLT' if it exists.
-     * If not, returns 'latn' if it exists.
-     * If neither exist, returns undefined.
-     */
-    getDefaultScriptName: function() {
-        var layout = this.getTable();
-        if (!layout) { return; }
-        var hasLatn = false;
-        for (var i = 0; i < layout.scripts.length; i++) {
-            var name = layout.scripts[i].tag;
-            if (name === 'DFLT') { return name; }
-            if (name === 'latn') { hasLatn = true; }
-        }
-        if (hasLatn) { return 'latn'; }
-    },
-
-    /**
-     * Returns all LangSysRecords in the given script.
-     * @instance
-     * @param {string} [script='DFLT']
-     * @param {boolean} create - forces the creation of this script table if it doesn't exist.
-     * @return {Object} An object with tag and script properties.
-     */
-    getScriptTable: function(script, create) {
-        var layout = this.getTable(create);
-        if (layout) {
-            script = script || 'DFLT';
-            var scripts = layout.scripts;
-            var pos = searchTag(layout.scripts, script);
-            if (pos >= 0) {
-                return scripts[pos].script;
-            } else if (create) {
-                var scr = {
-                    tag: script,
-                    script: {
-                        defaultLangSys: {reserved: 0, reqFeatureIndex: 0xffff, featureIndexes: []},
-                        langSysRecords: []
-                    }
-                };
-                scripts.splice(-1 - pos, 0, scr);
-                return scr.script;
-            }
-        }
-    },
-
-    /**
-     * Returns a language system table
-     * @instance
-     * @param {string} [script='DFLT']
-     * @param {string} [language='dlft']
-     * @param {boolean} create - forces the creation of this langSysTable if it doesn't exist.
-     * @return {Object}
-     */
-    getLangSysTable: function(script, language, create) {
-        var scriptTable = this.getScriptTable(script, create);
-        if (scriptTable) {
-            if (!language || language === 'dflt' || language === 'DFLT') {
-                return scriptTable.defaultLangSys;
-            }
-            var pos = searchTag(scriptTable.langSysRecords, language);
-            if (pos >= 0) {
-                return scriptTable.langSysRecords[pos].langSys;
-            } else if (create) {
-                var langSysRecord = {
-                    tag: language,
-                    langSys: {reserved: 0, reqFeatureIndex: 0xffff, featureIndexes: []}
-                };
-                scriptTable.langSysRecords.splice(-1 - pos, 0, langSysRecord);
-                return langSysRecord.langSys;
-            }
-        }
-    },
-
-    /**
-     * Get a specific feature table.
-     * @instance
-     * @param {string} [script='DFLT']
-     * @param {string} [language='dlft']
-     * @param {string} feature - One of the codes listed at https://www.microsoft.com/typography/OTSPEC/featurelist.htm
-     * @param {boolean} create - forces the creation of the feature table if it doesn't exist.
-     * @return {Object}
-     */
-    getFeatureTable: function(script, language, feature, create) {
-        var langSysTable = this.getLangSysTable(script, language, create);
-        if (langSysTable) {
-            var featureRecord;
-            var featIndexes = langSysTable.featureIndexes;
-            var allFeatures = this.font.tables[this.tableName].features;
-            // The FeatureIndex array of indices is in arbitrary order,
-            // even if allFeatures is sorted alphabetically by feature tag.
-            for (var i = 0; i < featIndexes.length; i++) {
-                featureRecord = allFeatures[featIndexes[i]];
-                if (featureRecord.tag === feature) {
-                    return featureRecord.feature;
-                }
-            }
-            if (create) {
-                var index = allFeatures.length;
-                // Automatic ordering of features would require to shift feature indexes in the script list.
-                check.assert(index === 0 || feature >= allFeatures[index - 1].tag, 'Features must be added in alphabetical order.');
-                featureRecord = {
-                    tag: feature,
-                    feature: { params: 0, lookupListIndexes: [] }
-                };
-                allFeatures.push(featureRecord);
-                featIndexes.push(index);
-                return featureRecord.feature;
-            }
-        }
-    },
-
-    /**
-     * Get the lookup tables of a given type for a script/language/feature.
-     * @instance
-     * @param {string} [script='DFLT']
-     * @param {string} [language='dlft']
-     * @param {string} feature - 4-letter feature code
-     * @param {number} lookupType - 1 to 9
-     * @param {boolean} create - forces the creation of the lookup table if it doesn't exist, with no subtables.
-     * @return {Object[]}
-     */
-    getLookupTables: function(script, language, feature, lookupType, create) {
-        var featureTable = this.getFeatureTable(script, language, feature, create);
-        var tables = [];
-        if (featureTable) {
-            var lookupTable;
-            var lookupListIndexes = featureTable.lookupListIndexes;
-            var allLookups = this.font.tables[this.tableName].lookups;
-            // lookupListIndexes are in no particular order, so use naive search.
-            for (var i = 0; i < lookupListIndexes.length; i++) {
-                lookupTable = allLookups[lookupListIndexes[i]];
-                if (lookupTable.lookupType === lookupType) {
-                    tables.push(lookupTable);
-                }
-            }
-            if (tables.length === 0 && create) {
-                lookupTable = {
-                    lookupType: lookupType,
-                    lookupFlag: 0,
-                    subtables: [],
-                    markFilteringSet: undefined
-                };
-                var index = allLookups.length;
-                allLookups.push(lookupTable);
-                lookupListIndexes.push(index);
-                return [lookupTable];
-            }
-        }
-        return tables;
-    },
-
-    /**
-     * Find a glyph in a class definition table
-     * https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#class-definition-table
-     * @param {object} classDefTable - an OpenType Layout class definition table
-     * @param {number} glyphIndex - the index of the glyph to find
-     * @returns {number} -1 if not found
-     */
-    getGlyphClass: function(classDefTable, glyphIndex) {
-        switch (classDefTable.format) {
-            case 1:
-                if (classDefTable.startGlyph <= glyphIndex && glyphIndex < classDefTable.startGlyph + classDefTable.classes.length) {
-                    return classDefTable.classes[glyphIndex - classDefTable.startGlyph];
-                }
-                return 0;
-            case 2:
-                var range = searchRange(classDefTable.ranges, glyphIndex);
-                return range ? range.classId : 0;
-        }
-    },
-
-    /**
-     * Find a glyph in a coverage table
-     * https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-table
-     * @param {object} coverageTable - an OpenType Layout coverage table
-     * @param {number} glyphIndex - the index of the glyph to find
-     * @returns {number} -1 if not found
-     */
-    getCoverageIndex: function(coverageTable, glyphIndex) {
-        switch (coverageTable.format) {
-            case 1:
-                var index = binSearch(coverageTable.glyphs, glyphIndex);
-                return index >= 0 ? index : -1;
-            case 2:
-                var range = searchRange(coverageTable.ranges, glyphIndex);
-                return range ? range.index + glyphIndex - range.start : -1;
-        }
-    },
-
-    /**
-     * Returns the list of glyph indexes of a coverage table.
-     * Format 1: the list is stored raw
-     * Format 2: compact list as range records.
-     * @instance
-     * @param  {Object} coverageTable
-     * @return {Array}
-     */
-    expandCoverage: function(coverageTable) {
-        if (coverageTable.format === 1) {
-            return coverageTable.glyphs;
-        } else {
-            var glyphs = [];
-            var ranges = coverageTable.ranges;
-            for (var i = 0; i < ranges.length; i++) {
-                var range = ranges[i];
-                var start = range.start;
-                var end = range.end;
-                for (var j = start; j <= end; j++) {
-                    glyphs.push(j);
-                }
-            }
-            return glyphs;
-        }
-    }
-
-};
-
-// The Position object provides utility methods to manipulate
-
-/**
- * @exports opentype.Position
- * @class
- * @extends opentype.Layout
- * @param {opentype.Font}
- * @constructor
- */
-function Position(font) {
-    Layout.call(this, font, 'gpos');
-}
-
-Position.prototype = Layout.prototype;
-
-/**
- * Init some data for faster and easier access later.
- */
-Position.prototype.init = function() {
-    var script = this.getDefaultScriptName();
-    this.defaultKerningTables = this.getKerningTables(script);
-};
-
-/**
- * Find a glyph pair in a list of lookup tables of type 2 and retrieve the xAdvance kerning value.
- *
- * @param {integer} leftIndex - left glyph index
- * @param {integer} rightIndex - right glyph index
- * @returns {integer}
- */
-Position.prototype.getKerningValue = function(kerningLookups, leftIndex, rightIndex) {
-    for (var i = 0; i < kerningLookups.length; i++) {
-        var subtables = kerningLookups[i].subtables;
-        for (var j = 0; j < subtables.length; j++) {
-            var subtable = subtables[j];
-            var covIndex = this.getCoverageIndex(subtable.coverage, leftIndex);
-            if (covIndex < 0) { continue; }
-            switch (subtable.posFormat) {
-                case 1:
-                    // Search Pair Adjustment Positioning Format 1
-                    var pairSet = subtable.pairSets[covIndex];
-                    for (var k = 0; k < pairSet.length; k++) {
-                        var pair = pairSet[k];
-                        if (pair.secondGlyph === rightIndex) {
-                            return pair.value1 && pair.value1.xAdvance || 0;
-                        }
-                    }
-                    break;      // left glyph found, not right glyph - try next subtable
-                case 2:
-                    // Search Pair Adjustment Positioning Format 2
-                    var class1 = this.getGlyphClass(subtable.classDef1, leftIndex);
-                    var class2 = this.getGlyphClass(subtable.classDef2, rightIndex);
-                    var pair$1 = subtable.classRecords[class1][class2];
-                    return pair$1.value1 && pair$1.value1.xAdvance || 0;
-            }
-        }
-    }
-    return 0;
-};
-
-/**
- * List all kerning lookup tables.
- *
- * @param {string} [script='DFLT'] - use font.position.getDefaultScriptName() for a better default value
- * @param {string} [language='dflt']
- * @return {object[]} The list of kerning lookup tables (may be empty), or undefined if there is no GPOS table (and we should use the kern table)
- */
-Position.prototype.getKerningTables = function(script, language) {
-    if (this.font.tables.gpos) {
-        return this.getLookupTables(script, language, 'kern', 2);
-    }
-};
-
-// The Substitution object provides utility methods to manipulate
-
-/**
- * @exports opentype.Substitution
- * @class
- * @extends opentype.Layout
- * @param {opentype.Font}
- * @constructor
- */
-function Substitution(font) {
-    Layout.call(this, font, 'gsub');
-}
-
-// Check if 2 arrays of primitives are equal.
-function arraysEqual(ar1, ar2) {
-    var n = ar1.length;
-    if (n !== ar2.length) { return false; }
-    for (var i = 0; i < n; i++) {
-        if (ar1[i] !== ar2[i]) { return false; }
-    }
-    return true;
-}
-
-// Find the first subtable of a lookup table in a particular format.
-function getSubstFormat(lookupTable, format, defaultSubtable) {
-    var subtables = lookupTable.subtables;
-    for (var i = 0; i < subtables.length; i++) {
-        var subtable = subtables[i];
-        if (subtable.substFormat === format) {
-            return subtable;
-        }
-    }
-    if (defaultSubtable) {
-        subtables.push(defaultSubtable);
-        return defaultSubtable;
-    }
-    return undefined;
-}
-
-Substitution.prototype = Layout.prototype;
-
-/**
- * Create a default GSUB table.
- * @return {Object} gsub - The GSUB table.
- */
-Substitution.prototype.createDefaultTable = function() {
-    // Generate a default empty GSUB table with just a DFLT script and dflt lang sys.
-    return {
-        version: 1,
-        scripts: [{
-            tag: 'DFLT',
-            script: {
-                defaultLangSys: { reserved: 0, reqFeatureIndex: 0xffff, featureIndexes: [] },
-                langSysRecords: []
-            }
-        }],
-        features: [],
-        lookups: []
-    };
-};
-
-/**
- * List all single substitutions (lookup type 1) for a given script, language, and feature.
- * @param {string} [script='DFLT']
- * @param {string} [language='dflt']
- * @param {string} feature - 4-character feature name ('aalt', 'salt', 'ss01'...)
- * @return {Array} substitutions - The list of substitutions.
- */
-Substitution.prototype.getSingle = function(feature, script, language) {
-    var substitutions = [];
-    var lookupTables = this.getLookupTables(script, language, feature, 1);
-    for (var idx = 0; idx < lookupTables.length; idx++) {
-        var subtables = lookupTables[idx].subtables;
-        for (var i = 0; i < subtables.length; i++) {
-            var subtable = subtables[i];
-            var glyphs = this.expandCoverage(subtable.coverage);
-            var j = (void 0);
-            if (subtable.substFormat === 1) {
-                var delta = subtable.deltaGlyphId;
-                for (j = 0; j < glyphs.length; j++) {
-                    var glyph = glyphs[j];
-                    substitutions.push({ sub: glyph, by: glyph + delta });
-                }
-            } else {
-                var substitute = subtable.substitute;
-                for (j = 0; j < glyphs.length; j++) {
-                    substitutions.push({ sub: glyphs[j], by: substitute[j] });
-                }
-            }
-        }
-    }
-    return substitutions;
-};
-
-/**
- * List all multiple substitutions (lookup type 2) for a given script, language, and feature.
- * @param {string} [script='DFLT']
- * @param {string} [language='dflt']
- * @param {string} feature - 4-character feature name ('ccmp', 'stch')
- * @return {Array} substitutions - The list of substitutions.
- */
-Substitution.prototype.getMultiple = function(feature, script, language) {
-    var substitutions = [];
-    var lookupTables = this.getLookupTables(script, language, feature, 2);
-    for (var idx = 0; idx < lookupTables.length; idx++) {
-        var subtables = lookupTables[idx].subtables;
-        for (var i = 0; i < subtables.length; i++) {
-            var subtable = subtables[i];
-            var glyphs = this.expandCoverage(subtable.coverage);
-            var j = (void 0);
-
-            for (j = 0; j < glyphs.length; j++) {
-                var glyph = glyphs[j];
-                var replacements = subtable.sequences[j];
-                substitutions.push({ sub: glyph, by: replacements });
-            }
-        }
-    }
-    return substitutions;
-};
-
-/**
- * List all alternates (lookup type 3) for a given script, language, and feature.
- * @param {string} [script='DFLT']
- * @param {string} [language='dflt']
- * @param {string} feature - 4-character feature name ('aalt', 'salt'...)
- * @return {Array} alternates - The list of alternates
- */
-Substitution.prototype.getAlternates = function(feature, script, language) {
-    var alternates = [];
-    var lookupTables = this.getLookupTables(script, language, feature, 3);
-    for (var idx = 0; idx < lookupTables.length; idx++) {
-        var subtables = lookupTables[idx].subtables;
-        for (var i = 0; i < subtables.length; i++) {
-            var subtable = subtables[i];
-            var glyphs = this.expandCoverage(subtable.coverage);
-            var alternateSets = subtable.alternateSets;
-            for (var j = 0; j < glyphs.length; j++) {
-                alternates.push({ sub: glyphs[j], by: alternateSets[j] });
-            }
-        }
-    }
-    return alternates;
-};
-
-/**
- * List all ligatures (lookup type 4) for a given script, language, and feature.
- * The result is an array of ligature objects like { sub: [ids], by: id }
- * @param {string} feature - 4-letter feature name ('liga', 'rlig', 'dlig'...)
- * @param {string} [script='DFLT']
- * @param {string} [language='dflt']
- * @return {Array} ligatures - The list of ligatures.
- */
-Substitution.prototype.getLigatures = function(feature, script, language) {
-    var ligatures = [];
-    var lookupTables = this.getLookupTables(script, language, feature, 4);
-    for (var idx = 0; idx < lookupTables.length; idx++) {
-        var subtables = lookupTables[idx].subtables;
-        for (var i = 0; i < subtables.length; i++) {
-            var subtable = subtables[i];
-            var glyphs = this.expandCoverage(subtable.coverage);
-            var ligatureSets = subtable.ligatureSets;
-            for (var j = 0; j < glyphs.length; j++) {
-                var startGlyph = glyphs[j];
-                var ligSet = ligatureSets[j];
-                for (var k = 0; k < ligSet.length; k++) {
-                    var lig = ligSet[k];
-                    ligatures.push({
-                        sub: [startGlyph].concat(lig.components),
-                        by: lig.ligGlyph
-                    });
-                }
-            }
-        }
-    }
-    return ligatures;
-};
-
-/**
- * Add or modify a single substitution (lookup type 1)
- * Format 2, more flexible, is always used.
- * @param {string} feature - 4-letter feature name ('liga', 'rlig', 'dlig'...)
- * @param {Object} substitution - { sub: id, by: id } (format 1 is not supported)
- * @param {string} [script='DFLT']
- * @param {string} [language='dflt']
- */
-Substitution.prototype.addSingle = function(feature, substitution, script, language) {
-    var lookupTable = this.getLookupTables(script, language, feature, 1, true)[0];
-    var subtable = getSubstFormat(lookupTable, 2, {                // lookup type 1 subtable, format 2, coverage format 1
-        substFormat: 2,
-        coverage: {format: 1, glyphs: []},
-        substitute: []
-    });
-    check.assert(subtable.coverage.format === 1, 'Single: unable to modify coverage table format ' + subtable.coverage.format);
-    var coverageGlyph = substitution.sub;
-    var pos = this.binSearch(subtable.coverage.glyphs, coverageGlyph);
-    if (pos < 0) {
-        pos = -1 - pos;
-        subtable.coverage.glyphs.splice(pos, 0, coverageGlyph);
-        subtable.substitute.splice(pos, 0, 0);
-    }
-    subtable.substitute[pos] = substitution.by;
-};
-
-/**
- * Add or modify a multiple substitution (lookup type 2)
- * @param {string} feature - 4-letter feature name ('ccmp', 'stch')
- * @param {Object} substitution - { sub: id, by: [id] } for format 2.
- * @param {string} [script='DFLT']
- * @param {string} [language='dflt']
- */
-Substitution.prototype.addMultiple = function(feature, substitution, script, language) {
-    check.assert(substitution.by instanceof Array && substitution.by.length > 1, 'Multiple: "by" must be an array of two or more ids');
-    var lookupTable = this.getLookupTables(script, language, feature, 2, true)[0];
-    var subtable = getSubstFormat(lookupTable, 1, {                // lookup type 2 subtable, format 1, coverage format 1
-        substFormat: 1,
-        coverage: {format: 1, glyphs: []},
-        sequences: []
-    });
-    check.assert(subtable.coverage.format === 1, 'Multiple: unable to modify coverage table format ' + subtable.coverage.format);
-    var coverageGlyph = substitution.sub;
-    var pos = this.binSearch(subtable.coverage.glyphs, coverageGlyph);
-    if (pos < 0) {
-        pos = -1 - pos;
-        subtable.coverage.glyphs.splice(pos, 0, coverageGlyph);
-        subtable.sequences.splice(pos, 0, 0);
-    }
-    subtable.sequences[pos] = substitution.by;
-};
-
-/**
- * Add or modify an alternate substitution (lookup type 3)
- * @param {string} feature - 4-letter feature name ('liga', 'rlig', 'dlig'...)
- * @param {Object} substitution - { sub: id, by: [ids] }
- * @param {string} [script='DFLT']
- * @param {string} [language='dflt']
- */
-Substitution.prototype.addAlternate = function(feature, substitution, script, language) {
-    var lookupTable = this.getLookupTables(script, language, feature, 3, true)[0];
-    var subtable = getSubstFormat(lookupTable, 1, {                // lookup type 3 subtable, format 1, coverage format 1
-        substFormat: 1,
-        coverage: {format: 1, glyphs: []},
-        alternateSets: []
-    });
-    check.assert(subtable.coverage.format === 1, 'Alternate: unable to modify coverage table format ' + subtable.coverage.format);
-    var coverageGlyph = substitution.sub;
-    var pos = this.binSearch(subtable.coverage.glyphs, coverageGlyph);
-    if (pos < 0) {
-        pos = -1 - pos;
-        subtable.coverage.glyphs.splice(pos, 0, coverageGlyph);
-        subtable.alternateSets.splice(pos, 0, 0);
-    }
-    subtable.alternateSets[pos] = substitution.by;
-};
-
-/**
- * Add a ligature (lookup type 4)
- * Ligatures with more components must be stored ahead of those with fewer components in order to be found
- * @param {string} feature - 4-letter feature name ('liga', 'rlig', 'dlig'...)
- * @param {Object} ligature - { sub: [ids], by: id }
- * @param {string} [script='DFLT']
- * @param {string} [language='dflt']
- */
-Substitution.prototype.addLigature = function(feature, ligature, script, language) {
-    var lookupTable = this.getLookupTables(script, language, feature, 4, true)[0];
-    var subtable = lookupTable.subtables[0];
-    if (!subtable) {
-        subtable = {                // lookup type 4 subtable, format 1, coverage format 1
-            substFormat: 1,
-            coverage: { format: 1, glyphs: [] },
-            ligatureSets: []
-        };
-        lookupTable.subtables[0] = subtable;
-    }
-    check.assert(subtable.coverage.format === 1, 'Ligature: unable to modify coverage table format ' + subtable.coverage.format);
-    var coverageGlyph = ligature.sub[0];
-    var ligComponents = ligature.sub.slice(1);
-    var ligatureTable = {
-        ligGlyph: ligature.by,
-        components: ligComponents
-    };
-    var pos = this.binSearch(subtable.coverage.glyphs, coverageGlyph);
-    if (pos >= 0) {
-        // ligatureSet already exists
-        var ligatureSet = subtable.ligatureSets[pos];
-        for (var i = 0; i < ligatureSet.length; i++) {
-            // If ligature already exists, return.
-            if (arraysEqual(ligatureSet[i].components, ligComponents)) {
-                return;
-            }
-        }
-        // ligature does not exist: add it.
-        ligatureSet.push(ligatureTable);
-    } else {
-        // Create a new ligatureSet and add coverage for the first glyph.
-        pos = -1 - pos;
-        subtable.coverage.glyphs.splice(pos, 0, coverageGlyph);
-        subtable.ligatureSets.splice(pos, 0, [ligatureTable]);
-    }
-};
-
-/**
- * List all feature data for a given script and language.
- * @param {string} feature - 4-letter feature name
- * @param {string} [script='DFLT']
- * @param {string} [language='dflt']
- * @return {Array} substitutions - The list of substitutions.
- */
-Substitution.prototype.getFeature = function(feature, script, language) {
-    if (/ss\d\d/.test(feature)) {
-        // ss01 - ss20
-        return this.getSingle(feature, script, language);
-    }
-    switch (feature) {
-        case 'aalt':
-        case 'salt':
-            return this.getSingle(feature, script, language)
-                    .concat(this.getAlternates(feature, script, language));
-        case 'dlig':
-        case 'liga':
-        case 'rlig':
-            return this.getLigatures(feature, script, language);
-        case 'ccmp':
-            return this.getMultiple(feature, script, language)
-                .concat(this.getLigatures(feature, script, language));
-        case 'stch':
-            return this.getMultiple(feature, script, language);
-    }
-    return undefined;
-};
-
-/**
- * Add a substitution to a feature for a given script and language.
- * @param {string} feature - 4-letter feature name
- * @param {Object} sub - the substitution to add (an object like { sub: id or [ids], by: id or [ids] })
- * @param {string} [script='DFLT']
- * @param {string} [language='dflt']
- */
-Substitution.prototype.add = function(feature, sub, script, language) {
-    if (/ss\d\d/.test(feature)) {
-        // ss01 - ss20
-        return this.addSingle(feature, sub, script, language);
-    }
-    switch (feature) {
-        case 'aalt':
-        case 'salt':
-            if (typeof sub.by === 'number') {
-                return this.addSingle(feature, sub, script, language);
-            }
-            return this.addAlternate(feature, sub, script, language);
-        case 'dlig':
-        case 'liga':
-        case 'rlig':
-            return this.addLigature(feature, sub, script, language);
-        case 'ccmp':
-            if (sub.by instanceof Array) {
-                return this.addMultiple(feature, sub, script, language);
-            }
-            return this.addLigature(feature, sub, script, language);
-    }
-    return undefined;
-};
-
-function checkArgument(expression, message) {
-    if (!expression) {
-        throw message;
-    }
-}
-
-// The `glyf` table describes the glyphs in TrueType outline format.
-
-// Parse the coordinate data for a glyph.
-function parseGlyphCoordinate(p, flag, previousValue, shortVectorBitMask, sameBitMask) {
-    var v;
-    if ((flag & shortVectorBitMask) > 0) {
-        // The coordinate is 1 byte long.
-        v = p.parseByte();
-        // The `same` bit is re-used for short values to signify the sign of the value.
-        if ((flag & sameBitMask) === 0) {
-            v = -v;
-        }
-
-        v = previousValue + v;
-    } else {
-        //  The coordinate is 2 bytes long.
-        // If the `same` bit is set, the coordinate is the same as the previous coordinate.
-        if ((flag & sameBitMask) > 0) {
-            v = previousValue;
-        } else {
-            // Parse the coordinate as a signed 16-bit delta value.
-            v = previousValue + p.parseShort();
-        }
-    }
-
-    return v;
-}
-
-// Parse a TrueType glyph.
-function parseGlyph(glyph, data, start) {
-    var p = new parse.Parser(data, start);
-    glyph.numberOfContours = p.parseShort();
-    glyph._xMin = p.parseShort();
-    glyph._yMin = p.parseShort();
-    glyph._xMax = p.parseShort();
-    glyph._yMax = p.parseShort();
-    var flags;
-    var flag;
-
-    if (glyph.numberOfContours > 0) {
-        // This glyph is not a composite.
-        var endPointIndices = glyph.endPointIndices = [];
-        for (var i = 0; i < glyph.numberOfContours; i += 1) {
-            endPointIndices.push(p.parseUShort());
-        }
-
-        glyph.instructionLength = p.parseUShort();
-        glyph.instructions = [];
-        for (var i$1 = 0; i$1 < glyph.instructionLength; i$1 += 1) {
-            glyph.instructions.push(p.parseByte());
-        }
-
-        var numberOfCoordinates = endPointIndices[endPointIndices.length - 1] + 1;
-        flags = [];
-        for (var i$2 = 0; i$2 < numberOfCoordinates; i$2 += 1) {
-            flag = p.parseByte();
-            flags.push(flag);
-            // If bit 3 is set, we repeat this flag n times, where n is the next byte.
-            if ((flag & 8) > 0) {
-                var repeatCount = p.parseByte();
-                for (var j = 0; j < repeatCount; j += 1) {
-                    flags.push(flag);
-                    i$2 += 1;
-                }
-            }
-        }
-
-        check.argument(flags.length === numberOfCoordinates, 'Bad flags.');
-
-        if (endPointIndices.length > 0) {
-            var points = [];
-            var point;
-            // X/Y coordinates are relative to the previous point, except for the first point which is relative to 0,0.
-            if (numberOfCoordinates > 0) {
-                for (var i$3 = 0; i$3 < numberOfCoordinates; i$3 += 1) {
-                    flag = flags[i$3];
-                    point = {};
-                    point.onCurve = !!(flag & 1);
-                    point.lastPointOfContour = endPointIndices.indexOf(i$3) >= 0;
-                    points.push(point);
-                }
-
-                var px = 0;
-                for (var i$4 = 0; i$4 < numberOfCoordinates; i$4 += 1) {
-                    flag = flags[i$4];
-                    point = points[i$4];
-                    point.x = parseGlyphCoordinate(p, flag, px, 2, 16);
-                    px = point.x;
-                }
-
-                var py = 0;
-                for (var i$5 = 0; i$5 < numberOfCoordinates; i$5 += 1) {
-                    flag = flags[i$5];
-                    point = points[i$5];
-                    point.y = parseGlyphCoordinate(p, flag, py, 4, 32);
-                    py = point.y;
-                }
-            }
-
-            glyph.points = points;
-        } else {
-            glyph.points = [];
-        }
-    } else if (glyph.numberOfContours === 0) {
-        glyph.points = [];
-    } else {
-        glyph.isComposite = true;
-        glyph.points = [];
-        glyph.components = [];
-        var moreComponents = true;
-        while (moreComponents) {
-            flags = p.parseUShort();
-            var component = {
-                glyphIndex: p.parseUShort(),
-                xScale: 1,
-                scale01: 0,
-                scale10: 0,
-                yScale: 1,
-                dx: 0,
-                dy: 0
-            };
-            if ((flags & 1) > 0) {
-                // The arguments are words
-                if ((flags & 2) > 0) {
-                    // values are offset
-                    component.dx = p.parseShort();
-                    component.dy = p.parseShort();
-                } else {
-                    // values are matched points
-                    component.matchedPoints = [p.parseUShort(), p.parseUShort()];
-                }
-
-            } else {
-                // The arguments are bytes
-                if ((flags & 2) > 0) {
-                    // values are offset
-                    component.dx = p.parseChar();
-                    component.dy = p.parseChar();
-                } else {
-                    // values are matched points
-                    component.matchedPoints = [p.parseByte(), p.parseByte()];
-                }
-            }
-
-            if ((flags & 8) > 0) {
-                // We have a scale
-                component.xScale = component.yScale = p.parseF2Dot14();
-            } else if ((flags & 64) > 0) {
-                // We have an X / Y scale
-                component.xScale = p.parseF2Dot14();
-                component.yScale = p.parseF2Dot14();
-            } else if ((flags & 128) > 0) {
-                // We have a 2x2 transformation
-                component.xScale = p.parseF2Dot14();
-                component.scale01 = p.parseF2Dot14();
-                component.scale10 = p.parseF2Dot14();
-                component.yScale = p.parseF2Dot14();
-            }
-
-            glyph.components.push(component);
-            moreComponents = !!(flags & 32);
-        }
-        if (flags & 0x100) {
-            // We have instructions
-            glyph.instructionLength = p.parseUShort();
-            glyph.instructions = [];
-            for (var i$6 = 0; i$6 < glyph.instructionLength; i$6 += 1) {
-                glyph.instructions.push(p.parseByte());
-            }
-        }
-    }
-}
-
-// Transform an array of points and return a new array.
-function transformPoints(points, transform) {
-    var newPoints = [];
-    for (var i = 0; i < points.length; i += 1) {
-        var pt = points[i];
-        var newPt = {
-            x: transform.xScale * pt.x + transform.scale01 * pt.y + transform.dx,
-            y: transform.scale10 * pt.x + transform.yScale * pt.y + transform.dy,
-            onCurve: pt.onCurve,
-            lastPointOfContour: pt.lastPointOfContour
-        };
-        newPoints.push(newPt);
-    }
-
-    return newPoints;
-}
-
-function getContours(points) {
-    var contours = [];
-    var currentContour = [];
-    for (var i = 0; i < points.length; i += 1) {
-        var pt = points[i];
-        currentContour.push(pt);
-        if (pt.lastPointOfContour) {
-            contours.push(currentContour);
-            currentContour = [];
-        }
-    }
-
-    check.argument(currentContour.length === 0, 'There are still points left in the current contour.');
-    return contours;
-}
-
-// Convert the TrueType glyph outline to a Path.
-function getPath(points) {
-    var p = new Path();
-    if (!points) {
-        return p;
-    }
-
-    var contours = getContours(points);
-
-    for (var contourIndex = 0; contourIndex < contours.length; ++contourIndex) {
-        var contour = contours[contourIndex];
-
-        var prev = null;
-        var curr = contour[contour.length - 1];
-        var next = contour[0];
-
-        if (curr.onCurve) {
-            p.moveTo(curr.x, curr.y);
-        } else {
-            if (next.onCurve) {
-                p.moveTo(next.x, next.y);
-            } else {
-                // If both first and last points are off-curve, start at their middle.
-                var start = {x: (curr.x + next.x) * 0.5, y: (curr.y + next.y) * 0.5};
-                p.moveTo(start.x, start.y);
-            }
-        }
-
-        for (var i = 0; i < contour.length; ++i) {
-            prev = curr;
-            curr = next;
-            next = contour[(i + 1) % contour.length];
-
-            if (curr.onCurve) {
-                // This is a straight line.
-                p.lineTo(curr.x, curr.y);
-            } else {
-                var prev2 = prev;
-                var next2 = next;
-
-                if (!prev.onCurve) {
-                    prev2 = { x: (curr.x + prev.x) * 0.5, y: (curr.y + prev.y) * 0.5 };
-                }
-
-                if (!next.onCurve) {
-                    next2 = { x: (curr.x + next.x) * 0.5, y: (curr.y + next.y) * 0.5 };
-                }
-
-                p.quadraticCurveTo(curr.x, curr.y, next2.x, next2.y);
-            }
-        }
-
-        p.closePath();
-    }
-    return p;
-}
-
-function buildPath(glyphs, glyph) {
-    if (glyph.isComposite) {
-        for (var j = 0; j < glyph.components.length; j += 1) {
-            var component = glyph.components[j];
-            var componentGlyph = glyphs.get(component.glyphIndex);
-            // Force the ttfGlyphLoader to parse the glyph.
-            componentGlyph.getPath();
-            if (componentGlyph.points) {
-                var transformedPoints = (void 0);
-                if (component.matchedPoints === undefined) {
-                    // component positioned by offset
-                    transformedPoints = transformPoints(componentGlyph.points, component);
-                } else {
-                    // component positioned by matched points
-                    if ((component.matchedPoints[0] > glyph.points.length - 1) ||
-                        (component.matchedPoints[1] > componentGlyph.points.length - 1)) {
-                        throw Error('Matched points out of range in ' + glyph.name);
-                    }
-                    var firstPt = glyph.points[component.matchedPoints[0]];
-                    var secondPt = componentGlyph.points[component.matchedPoints[1]];
-                    var transform = {
-                        xScale: component.xScale, scale01: component.scale01,
-                        scale10: component.scale10, yScale: component.yScale,
-                        dx: 0, dy: 0
-                    };
-                    secondPt = transformPoints([secondPt], transform)[0];
-                    transform.dx = firstPt.x - secondPt.x;
-                    transform.dy = firstPt.y - secondPt.y;
-                    transformedPoints = transformPoints(componentGlyph.points, transform);
-                }
-                glyph.points = glyph.points.concat(transformedPoints);
-            }
-        }
-    }
-
-    return getPath(glyph.points);
-}
-
-function parseGlyfTableAll(data, start, loca, font) {
-    var glyphs = new glyphset.GlyphSet(font);
-
-    // The last element of the loca table is invalid.
-    for (var i = 0; i < loca.length - 1; i += 1) {
-        var offset = loca[i];
-        var nextOffset = loca[i + 1];
-        if (offset !== nextOffset) {
-            glyphs.push(i, glyphset.ttfGlyphLoader(font, i, parseGlyph, data, start + offset, buildPath));
-        } else {
-            glyphs.push(i, glyphset.glyphLoader(font, i));
-        }
-    }
-
-    return glyphs;
-}
-
-function parseGlyfTableOnLowMemory(data, start, loca, font) {
-    var glyphs = new glyphset.GlyphSet(font);
-
-    font._push = function(i) {
-        var offset = loca[i];
-        var nextOffset = loca[i + 1];
-        if (offset !== nextOffset) {
-            glyphs.push(i, glyphset.ttfGlyphLoader(font, i, parseGlyph, data, start + offset, buildPath));
-        } else {
-            glyphs.push(i, glyphset.glyphLoader(font, i));
-        }
-    };
-
-    return glyphs;
-}
-
-// Parse all the glyphs according to the offsets from the `loca` table.
-function parseGlyfTable(data, start, loca, font, opt) {
-    if (opt.lowMemory)
-        { return parseGlyfTableOnLowMemory(data, start, loca, font); }
-    else
-        { return parseGlyfTableAll(data, start, loca, font); }
-}
-
-var glyf = { getPath: getPath, parse: parseGlyfTable};
-
-/* A TrueType font hinting interpreter.
-*
-* (c) 2017 Axel Kittenberger
-*
-* This interpreter has been implemented according to this documentation:
-* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM05/Chap5.html
-*
-* According to the documentation F24DOT6 values are used for pixels.
-* That means calculation is 1/64 pixel accurate and uses integer operations.
-* However, Javascript has floating point operations by default and only
-* those are available. One could make a case to simulate the 1/64 accuracy
-* exactly by truncating after every division operation
-* (for example with << 0) to get pixel exactly results as other TrueType
-* implementations. It may make sense since some fonts are pixel optimized
-* by hand using DELTAP instructions. The current implementation doesn't
-* and rather uses full floating point precision.
-*
-* xScale, yScale and rotation is currently ignored.
-*
-* A few non-trivial instructions are missing as I didn't encounter yet
-* a font that used them to test a possible implementation.
-*
-* Some fonts seem to use undocumented features regarding the twilight zone.
-* Only some of them are implemented as they were encountered.
-*
-* The exports.DEBUG statements are removed on the minified distribution file.
-*/
-
-var instructionTable;
-var exec;
-var execGlyph;
-var execComponent;
-
-/*
-* Creates a hinting object.
-*
-* There ought to be exactly one
-* for each truetype font that is used for hinting.
-*/
-function Hinting(font) {
-    // the font this hinting object is for
-    this.font = font;
-
-    this.getCommands = function (hPoints) {
-        return glyf.getPath(hPoints).commands;
-    };
-
-    // cached states
-    this._fpgmState  =
-    this._prepState  =
-        undefined;
-
-    // errorState
-    // 0 ... all okay
-    // 1 ... had an error in a glyf,
-    //       continue working but stop spamming
-    //       the console
-    // 2 ... error at prep, stop hinting at this ppem
-    // 3 ... error at fpeg, stop hinting for this font at all
-    this._errorState = 0;
-}
-
-/*
-* Not rounding.
-*/
-function roundOff(v) {
-    return v;
-}
-
-/*
-* Rounding to grid.
-*/
-function roundToGrid(v) {
-    //Rounding in TT is supposed to "symmetrical around zero"
-    return Math.sign(v) * Math.round(Math.abs(v));
-}
-
-/*
-* Rounding to double grid.
-*/
-function roundToDoubleGrid(v) {
-    return Math.sign(v) * Math.round(Math.abs(v * 2)) / 2;
-}
-
-/*
-* Rounding to half grid.
-*/
-function roundToHalfGrid(v) {
-    return Math.sign(v) * (Math.round(Math.abs(v) + 0.5) - 0.5);
-}
-
-/*
-* Rounding to up to grid.
-*/
-function roundUpToGrid(v) {
-    return Math.sign(v) * Math.ceil(Math.abs(v));
-}
-
-/*
-* Rounding to down to grid.
-*/
-function roundDownToGrid(v) {
-    return Math.sign(v) * Math.floor(Math.abs(v));
-}
-
-/*
-* Super rounding.
-*/
-var roundSuper = function (v) {
-    var period = this.srPeriod;
-    var phase = this.srPhase;
-    var threshold = this.srThreshold;
-    var sign = 1;
-
-    if (v < 0) {
-        v = -v;
-        sign = -1;
-    }
-
-    v += threshold - phase;
-
-    v = Math.trunc(v / period) * period;
-
-    v += phase;
-
-    // according to http://xgridfit.sourceforge.net/round.html
-    if (v < 0) { return phase * sign; }
-
-    return v * sign;
-};
-
-/*
-* Unit vector of x-axis.
-*/
-var xUnitVector = {
-    x: 1,
-
-    y: 0,
-
-    axis: 'x',
-
-    // Gets the projected distance between two points.
-    // o1/o2 ... if true, respective original position is used.
-    distance: function (p1, p2, o1, o2) {
-        return (o1 ? p1.xo : p1.x) - (o2 ? p2.xo : p2.x);
-    },
-
-    // Moves point p so the moved position has the same relative
-    // position to the moved positions of rp1 and rp2 than the
-    // original positions had.
-    //
-    // See APPENDIX on INTERPOLATE at the bottom of this file.
-    interpolate: function (p, rp1, rp2, pv) {
-        var do1;
-        var do2;
-        var doa1;
-        var doa2;
-        var dm1;
-        var dm2;
-        var dt;
-
-        if (!pv || pv === this) {
-            do1 = p.xo - rp1.xo;
-            do2 = p.xo - rp2.xo;
-            dm1 = rp1.x - rp1.xo;
-            dm2 = rp2.x - rp2.xo;
-            doa1 = Math.abs(do1);
-            doa2 = Math.abs(do2);
-            dt = doa1 + doa2;
-
-            if (dt === 0) {
-                p.x = p.xo + (dm1 + dm2) / 2;
-                return;
-            }
-
-            p.x = p.xo + (dm1 * doa2 + dm2 * doa1) / dt;
-            return;
-        }
-
-        do1 = pv.distance(p, rp1, true, true);
-        do2 = pv.distance(p, rp2, true, true);
-        dm1 = pv.distance(rp1, rp1, false, true);
-        dm2 = pv.distance(rp2, rp2, false, true);
-        doa1 = Math.abs(do1);
-        doa2 = Math.abs(do2);
-        dt = doa1 + doa2;
-
-        if (dt === 0) {
-            xUnitVector.setRelative(p, p, (dm1 + dm2) / 2, pv, true);
-            return;
-        }
-
-        xUnitVector.setRelative(p, p, (dm1 * doa2 + dm2 * doa1) / dt, pv, true);
-    },
-
-    // Slope of line normal to this
-    normalSlope: Number.NEGATIVE_INFINITY,
-
-    // Sets the point 'p' relative to point 'rp'
-    // by the distance 'd'.
-    //
-    // See APPENDIX on SETRELATIVE at the bottom of this file.
-    //
-    // p   ... point to set
-    // rp  ... reference point
-    // d   ... distance on projection vector
-    // pv  ... projection vector (undefined = this)
-    // org ... if true, uses the original position of rp as reference.
-    setRelative: function (p, rp, d, pv, org) {
-        if (!pv || pv === this) {
-            p.x = (org ? rp.xo : rp.x) + d;
-            return;
-        }
-
-        var rpx = org ? rp.xo : rp.x;
-        var rpy = org ? rp.yo : rp.y;
-        var rpdx = rpx + d * pv.x;
-        var rpdy = rpy + d * pv.y;
-
-        p.x = rpdx + (p.y - rpdy) / pv.normalSlope;
-    },
-
-    // Slope of vector line.
-    slope: 0,
-
-    // Touches the point p.
-    touch: function (p) {
-        p.xTouched = true;
-    },
-
-    // Tests if a point p is touched.
-    touched: function (p) {
-        return p.xTouched;
-    },
-
-    // Untouches the point p.
-    untouch: function (p) {
-        p.xTouched = false;
-    }
-};
-
-/*
-* Unit vector of y-axis.
-*/
-var yUnitVector = {
-    x: 0,
-
-    y: 1,
-
-    axis: 'y',
-
-    // Gets the projected distance between two points.
-    // o1/o2 ... if true, respective original position is used.
-    distance: function (p1, p2, o1, o2) {
-        return (o1 ? p1.yo : p1.y) - (o2 ? p2.yo : p2.y);
-    },
-
-    // Moves point p so the moved position has the same relative
-    // position to the moved positions of rp1 and rp2 than the
-    // original positions had.
-    //
-    // See APPENDIX on INTERPOLATE at the bottom of this file.
-    interpolate: function (p, rp1, rp2, pv) {
-        var do1;
-        var do2;
-        var doa1;
-        var doa2;
-        var dm1;
-        var dm2;
-        var dt;
-
-        if (!pv || pv === this) {
-            do1 = p.yo - rp1.yo;
-            do2 = p.yo - rp2.yo;
-            dm1 = rp1.y - rp1.yo;
-            dm2 = rp2.y - rp2.yo;
-            doa1 = Math.abs(do1);
-            doa2 = Math.abs(do2);
-            dt = doa1 + doa2;
-
-            if (dt === 0) {
-                p.y = p.yo + (dm1 + dm2) / 2;
-                return;
-            }
-
-            p.y = p.yo + (dm1 * doa2 + dm2 * doa1) / dt;
-            return;
-        }
-
-        do1 = pv.distance(p, rp1, true, true);
-        do2 = pv.distance(p, rp2, true, true);
-        dm1 = pv.distance(rp1, rp1, false, true);
-        dm2 = pv.distance(rp2, rp2, false, true);
-        doa1 = Math.abs(do1);
-        doa2 = Math.abs(do2);
-        dt = doa1 + doa2;
-
-        if (dt === 0) {
-            yUnitVector.setRelative(p, p, (dm1 + dm2) / 2, pv, true);
-            return;
-        }
-
-        yUnitVector.setRelative(p, p, (dm1 * doa2 + dm2 * doa1) / dt, pv, true);
-    },
-
-    // Slope of line normal to this.
-    normalSlope: 0,
-
-    // Sets the point 'p' relative to point 'rp'
-    // by the distance 'd'
-    //
-    // See APPENDIX on SETRELATIVE at the bottom of this file.
-    //
-    // p   ... point to set
-    // rp  ... reference point
-    // d   ... distance on projection vector
-    // pv  ... projection vector (undefined = this)
-    // org ... if true, uses the original position of rp as reference.
-    setRelative: function (p, rp, d, pv, org) {
-        if (!pv || pv === this) {
-            p.y = (org ? rp.yo : rp.y) + d;
-            return;
-        }
-
-        var rpx = org ? rp.xo : rp.x;
-        var rpy = org ? rp.yo : rp.y;
-        var rpdx = rpx + d * pv.x;
-        var rpdy = rpy + d * pv.y;
-
-        p.y = rpdy + pv.normalSlope * (p.x - rpdx);
-    },
-
-    // Slope of vector line.
-    slope: Number.POSITIVE_INFINITY,
-
-    // Touches the point p.
-    touch: function (p) {
-        p.yTouched = true;
-    },
-
-    // Tests if a point p is touched.
-    touched: function (p) {
-        return p.yTouched;
-    },
-
-    // Untouches the point p.
-    untouch: function (p) {
-        p.yTouched = false;
-    }
-};
-
-Object.freeze(xUnitVector);
-Object.freeze(yUnitVector);
-
-/*
-* Creates a unit vector that is not x- or y-axis.
-*/
-function UnitVector(x, y) {
-    this.x = x;
-    this.y = y;
-    this.axis = undefined;
-    this.slope = y / x;
-    this.normalSlope = -x / y;
-    Object.freeze(this);
-}
-
-/*
-* Gets the projected distance between two points.
-* o1/o2 ... if true, respective original position is used.
-*/
-UnitVector.prototype.distance = function(p1, p2, o1, o2) {
-    return (
-        this.x * xUnitVector.distance(p1, p2, o1, o2) +
-        this.y * yUnitVector.distance(p1, p2, o1, o2)
-    );
-};
-
-/*
-* Moves point p so the moved position has the same relative
-* position to the moved positions of rp1 and rp2 than the
-* original positions had.
-*
-* See APPENDIX on INTERPOLATE at the bottom of this file.
-*/
-UnitVector.prototype.interpolate = function(p, rp1, rp2, pv) {
-    var dm1;
-    var dm2;
-    var do1;
-    var do2;
-    var doa1;
-    var doa2;
-    var dt;
-
-    do1 = pv.distance(p, rp1, true, true);
-    do2 = pv.distance(p, rp2, true, true);
-    dm1 = pv.distance(rp1, rp1, false, true);
-    dm2 = pv.distance(rp2, rp2, false, true);
-    doa1 = Math.abs(do1);
-    doa2 = Math.abs(do2);
-    dt = doa1 + doa2;
-
-    if (dt === 0) {
-        this.setRelative(p, p, (dm1 + dm2) / 2, pv, true);
-        return;
-    }
-
-    this.setRelative(p, p, (dm1 * doa2 + dm2 * doa1) / dt, pv, true);
-};
-
-/*
-* Sets the point 'p' relative to point 'rp'
-* by the distance 'd'
-*
-* See APPENDIX on SETRELATIVE at the bottom of this file.
-*
-* p   ...  point to set
-* rp  ... reference point
-* d   ... distance on projection vector
-* pv  ... projection vector (undefined = this)
-* org ... if true, uses the original position of rp as reference.
-*/
-UnitVector.prototype.setRelative = function(p, rp, d, pv, org) {
-    pv = pv || this;
-
-    var rpx = org ? rp.xo : rp.x;
-    var rpy = org ? rp.yo : rp.y;
-    var rpdx = rpx + d * pv.x;
-    var rpdy = rpy + d * pv.y;
-
-    var pvns = pv.normalSlope;
-    var fvs = this.slope;
-
-    var px = p.x;
-    var py = p.y;
-
-    p.x = (fvs * px - pvns * rpdx + rpdy - py) / (fvs - pvns);
-    p.y = fvs * (p.x - px) + py;
-};
-
-/*
-* Touches the point p.
-*/
-UnitVector.prototype.touch = function(p) {
-    p.xTouched = true;
-    p.yTouched = true;
-};
-
-/*
-* Returns a unit vector with x/y coordinates.
-*/
-function getUnitVector(x, y) {
-    var d = Math.sqrt(x * x + y * y);
-
-    x /= d;
-    y /= d;
-
-    if (x === 1 && y === 0) { return xUnitVector; }
-    else if (x === 0 && y === 1) { return yUnitVector; }
-    else { return new UnitVector(x, y); }
-}
-
-/*
-* Creates a point in the hinting engine.
-*/
-function HPoint(
-    x,
-    y,
-    lastPointOfContour,
-    onCurve
-) {
-    this.x = this.xo = Math.round(x * 64) / 64; // hinted x value and original x-value
-    this.y = this.yo = Math.round(y * 64) / 64; // hinted y value and original y-value
-
-    this.lastPointOfContour = lastPointOfContour;
-    this.onCurve = onCurve;
-    this.prevPointOnContour = undefined;
-    this.nextPointOnContour = undefined;
-    this.xTouched = false;
-    this.yTouched = false;
-
-    Object.preventExtensions(this);
-}
-
-/*
-* Returns the next touched point on the contour.
-*
-* v  ... unit vector to test touch axis.
-*/
-HPoint.prototype.nextTouched = function(v) {
-    var p = this.nextPointOnContour;
-
-    while (!v.touched(p) && p !== this) { p = p.nextPointOnContour; }
-
-    return p;
-};
-
-/*
-* Returns the previous touched point on the contour
-*
-* v  ... unit vector to test touch axis.
-*/
-HPoint.prototype.prevTouched = function(v) {
-    var p = this.prevPointOnContour;
-
-    while (!v.touched(p) && p !== this) { p = p.prevPointOnContour; }
-
-    return p;
-};
-
-/*
-* The zero point.
-*/
-var HPZero = Object.freeze(new HPoint(0, 0));
-
-/*
-* The default state of the interpreter.
-*
-* Note: Freezing the defaultState and then deriving from it
-* makes the V8 Javascript engine going awkward,
-* so this is avoided, albeit the defaultState shouldn't
-* ever change.
-*/
-var defaultState = {
-    cvCutIn: 17 / 16,    // control value cut in
-    deltaBase: 9,
-    deltaShift: 0.125,
-    loop: 1,             // loops some instructions
-    minDis: 1,           // minimum distance
-    autoFlip: true
-};
-
-/*
-* The current state of the interpreter.
-*
-* env  ... 'fpgm' or 'prep' or 'glyf'
-* prog ... the program
-*/
-function State(env, prog) {
-    this.env = env;
-    this.stack = [];
-    this.prog = prog;
-
-    switch (env) {
-        case 'glyf' :
-            this.zp0 = this.zp1 = this.zp2 = 1;
-            this.rp0 = this.rp1 = this.rp2 = 0;
-            /* fall through */
-        case 'prep' :
-            this.fv = this.pv = this.dpv = xUnitVector;
-            this.round = roundToGrid;
-    }
-}
-
-/*
-* Executes a glyph program.
-*
-* This does the hinting for each glyph.
-*
-* Returns an array of moved points.
-*
-* glyph: the glyph to hint
-* ppem: the size the glyph is rendered for
-*/
-Hinting.prototype.exec = function(glyph, ppem) {
-    if (typeof ppem !== 'number') {
-        throw new Error('Point size is not a number!');
-    }
-
-    // Received a fatal error, don't do any hinting anymore.
-    if (this._errorState > 2) { return; }
-
-    var font = this.font;
-    var prepState = this._prepState;
-
-    if (!prepState || prepState.ppem !== ppem) {
-        var fpgmState = this._fpgmState;
-
-        if (!fpgmState) {
-            // Executes the fpgm state.
-            // This is used by fonts to define functions.
-            State.prototype = defaultState;
-
-            fpgmState =
-            this._fpgmState =
-                new State('fpgm', font.tables.fpgm);
-
-            fpgmState.funcs = [ ];
-            fpgmState.font = font;
-
-            if (exports.DEBUG) {
-                console.log('---EXEC FPGM---');
-                fpgmState.step = -1;
-            }
-
-            try {
-                exec(fpgmState);
-            } catch (e) {
-                console.log('Hinting error in FPGM:' + e);
-                this._errorState = 3;
-                return;
-            }
-        }
-
-        // Executes the prep program for this ppem setting.
-        // This is used by fonts to set cvt values
-        // depending on to be rendered font size.
-
-        State.prototype = fpgmState;
-        prepState =
-        this._prepState =
-            new State('prep', font.tables.prep);
-
-        prepState.ppem = ppem;
-
-        // Creates a copy of the cvt table
-        // and scales it to the current ppem setting.
-        var oCvt = font.tables.cvt;
-        if (oCvt) {
-            var cvt = prepState.cvt = new Array(oCvt.length);
-            var scale = ppem / font.unitsPerEm;
-            for (var c = 0; c < oCvt.length; c++) {
-                cvt[c] = oCvt[c] * scale;
-            }
-        } else {
-            prepState.cvt = [];
-        }
-
-        if (exports.DEBUG) {
-            console.log('---EXEC PREP---');
-            prepState.step = -1;
-        }
-
-        try {
-            exec(prepState);
-        } catch (e) {
-            if (this._errorState < 2) {
-                console.log('Hinting error in PREP:' + e);
-            }
-            this._errorState = 2;
-        }
-    }
-
-    if (this._errorState > 1) { return; }
-
-    try {
-        return execGlyph(glyph, prepState);
-    } catch (e) {
-        if (this._errorState < 1) {
-            console.log('Hinting error:' + e);
-            console.log('Note: further hinting errors are silenced');
-        }
-        this._errorState = 1;
-        return undefined;
-    }
-};
-
-/*
-* Executes the hinting program for a glyph.
-*/
-execGlyph = function(glyph, prepState) {
-    // original point positions
-    var xScale = prepState.ppem / prepState.font.unitsPerEm;
-    var yScale = xScale;
-    var components = glyph.components;
-    var contours;
-    var gZone;
-    var state;
-
-    State.prototype = prepState;
-    if (!components) {
-        state = new State('glyf', glyph.instructions);
-        if (exports.DEBUG) {
-            console.log('---EXEC GLYPH---');
-            state.step = -1;
-        }
-        execComponent(glyph, state, xScale, yScale);
-        gZone = state.gZone;
-    } else {
-        var font = prepState.font;
-        gZone = [];
-        contours = [];
-        for (var i = 0; i < components.length; i++) {
-            var c = components[i];
-            var cg = font.glyphs.get(c.glyphIndex);
-
-            state = new State('glyf', cg.instructions);
-
-            if (exports.DEBUG) {
-                console.log('---EXEC COMP ' + i + '---');
-                state.step = -1;
-            }
-
-            execComponent(cg, state, xScale, yScale);
-            // appends the computed points to the result array
-            // post processes the component points
-            var dx = Math.round(c.dx * xScale);
-            var dy = Math.round(c.dy * yScale);
-            var gz = state.gZone;
-            var cc = state.contours;
-            for (var pi = 0; pi < gz.length; pi++) {
-                var p = gz[pi];
-                p.xTouched = p.yTouched = false;
-                p.xo = p.x = p.x + dx;
-                p.yo = p.y = p.y + dy;
-            }
-
-            var gLen = gZone.length;
-            gZone.push.apply(gZone, gz);
-            for (var j = 0; j < cc.length; j++) {
-                contours.push(cc[j] + gLen);
-            }
-        }
-
-        if (glyph.instructions && !state.inhibitGridFit) {
-            // the composite has instructions on its own
-            state = new State('glyf', glyph.instructions);
-
-            state.gZone = state.z0 = state.z1 = state.z2 = gZone;
-
-            state.contours = contours;
-
-            // note: HPZero cannot be used here, since
-            //       the point might be modified
-            gZone.push(
-                new HPoint(0, 0),
-                new HPoint(Math.round(glyph.advanceWidth * xScale), 0)
-            );
-
-            if (exports.DEBUG) {
-                console.log('---EXEC COMPOSITE---');
-                state.step = -1;
-            }
-
-            exec(state);
-
-            gZone.length -= 2;
-        }
-    }
-
-    return gZone;
-};
-
-/*
-* Executes the hinting program for a component of a multi-component glyph
-* or of the glyph itself for a non-component glyph.
-*/
-execComponent = function(glyph, state, xScale, yScale)
-{
-    var points = glyph.points || [];
-    var pLen = points.length;
-    var gZone = state.gZone = state.z0 = state.z1 = state.z2 = [];
-    var contours = state.contours = [];
-
-    // Scales the original points and
-    // makes copies for the hinted points.
-    var cp; // current point
-    for (var i = 0; i < pLen; i++) {
-        cp = points[i];
-
-        gZone[i] = new HPoint(
-            cp.x * xScale,
-            cp.y * yScale,
-            cp.lastPointOfContour,
-            cp.onCurve
-        );
-    }
-
-    // Chain links the contours.
-    var sp; // start point
-    var np; // next point
-
-    for (var i$1 = 0; i$1 < pLen; i$1++) {
-        cp = gZone[i$1];
-
-        if (!sp) {
-            sp = cp;
-            contours.push(i$1);
-        }
-
-        if (cp.lastPointOfContour) {
-            cp.nextPointOnContour = sp;
-            sp.prevPointOnContour = cp;
-            sp = undefined;
-        } else {
-            np = gZone[i$1 + 1];
-            cp.nextPointOnContour = np;
-            np.prevPointOnContour = cp;
-        }
-    }
-
-    if (state.inhibitGridFit) { return; }
-
-    if (exports.DEBUG) {
-        console.log('PROCESSING GLYPH', state.stack);
-        for (var i$2 = 0; i$2 < pLen; i$2++) {
-            console.log(i$2, gZone[i$2].x, gZone[i$2].y);
-        }
-    }
-
-    gZone.push(
-        new HPoint(0, 0),
-        new HPoint(Math.round(glyph.advanceWidth * xScale), 0)
-    );
-
-    exec(state);
-
-    // Removes the extra points.
-    gZone.length -= 2;
-
-    if (exports.DEBUG) {
-        console.log('FINISHED GLYPH', state.stack);
-        for (var i$3 = 0; i$3 < pLen; i$3++) {
-            console.log(i$3, gZone[i$3].x, gZone[i$3].y);
-        }
-    }
-};
-
-/*
-* Executes the program loaded in state.
-*/
-exec = function(state) {
-    var prog = state.prog;
-
-    if (!prog) { return; }
-
-    var pLen = prog.length;
-    var ins;
-
-    for (state.ip = 0; state.ip < pLen; state.ip++) {
-        if (exports.DEBUG) { state.step++; }
-        ins = instructionTable[prog[state.ip]];
-
-        if (!ins) {
-            throw new Error(
-                'unknown instruction: 0x' +
-                Number(prog[state.ip]).toString(16)
-            );
-        }
-
-        ins(state);
-
-        // very extensive debugging for each step
-        /*
-        if (exports.DEBUG) {
-            var da;
-            if (state.gZone) {
-                da = [];
-                for (let i = 0; i < state.gZone.length; i++)
-                {
-                    da.push(i + ' ' +
-                        state.gZone[i].x * 64 + ' ' +
-                        state.gZone[i].y * 64 + ' ' +
-                        (state.gZone[i].xTouched ? 'x' : '') +
-                        (state.gZone[i].yTouched ? 'y' : '')
-                    );
-                }
-                console.log('GZ', da);
-            }
-
-            if (state.tZone) {
-                da = [];
-                for (let i = 0; i < state.tZone.length; i++) {
-                    da.push(i + ' ' +
-                        state.tZone[i].x * 64 + ' ' +
-                        state.tZone[i].y * 64 + ' ' +
-                        (state.tZone[i].xTouched ? 'x' : '') +
-                        (state.tZone[i].yTouched ? 'y' : '')
-                    );
-                }
-                console.log('TZ', da);
-            }
-
-            if (state.stack.length > 10) {
-                console.log(
-                    state.stack.length,
-                    '...', state.stack.slice(state.stack.length - 10)
-                );
-            } else {
-                console.log(state.stack.length, state.stack);
-            }
-        }
-        */
-    }
-};
-
-/*
-* Initializes the twilight zone.
-*
-* This is only done if a SZPx instruction
-* refers to the twilight zone.
-*/
-function initTZone(state)
-{
-    var tZone = state.tZone = new Array(state.gZone.length);
-
-    // no idea if this is actually correct...
-    for (var i = 0; i < tZone.length; i++)
-    {
-        tZone[i] = new HPoint(0, 0);
-    }
-}
-
-/*
-* Skips the instruction pointer ahead over an IF/ELSE block.
-* handleElse .. if true breaks on matching ELSE
-*/
-function skip(state, handleElse)
-{
-    var prog = state.prog;
-    var ip = state.ip;
-    var nesting = 1;
-    var ins;
-
-    do {
-        ins = prog[++ip];
-        if (ins === 0x58) // IF
-            { nesting++; }
-        else if (ins === 0x59) // EIF
-            { nesting--; }
-        else if (ins === 0x40) // NPUSHB
-            { ip += prog[ip + 1] + 1; }
-        else if (ins === 0x41) // NPUSHW
-            { ip += 2 * prog[ip + 1] + 1; }
-        else if (ins >= 0xB0 && ins <= 0xB7) // PUSHB
-            { ip += ins - 0xB0 + 1; }
-        else if (ins >= 0xB8 && ins <= 0xBF) // PUSHW
-            { ip += (ins - 0xB8 + 1) * 2; }
-        else if (handleElse && nesting === 1 && ins === 0x1B) // ELSE
-            { break; }
-    } while (nesting > 0);
-
-    state.ip = ip;
-}
-
-/*----------------------------------------------------------*
-*          And then a lot of instructions...                *
-*----------------------------------------------------------*/
-
-// SVTCA[a] Set freedom and projection Vectors To Coordinate Axis
-// 0x00-0x01
-function SVTCA(v, state) {
-    if (exports.DEBUG) { console.log(state.step, 'SVTCA[' + v.axis + ']'); }
-
-    state.fv = state.pv = state.dpv = v;
-}
-
-// SPVTCA[a] Set Projection Vector to Coordinate Axis
-// 0x02-0x03
-function SPVTCA(v, state) {
-    if (exports.DEBUG) { console.log(state.step, 'SPVTCA[' + v.axis + ']'); }
-
-    state.pv = state.dpv = v;
-}
-
-// SFVTCA[a] Set Freedom Vector to Coordinate Axis
-// 0x04-0x05
-function SFVTCA(v, state) {
-    if (exports.DEBUG) { console.log(state.step, 'SFVTCA[' + v.axis + ']'); }
-
-    state.fv = v;
-}
-
-// SPVTL[a] Set Projection Vector To Line
-// 0x06-0x07
-function SPVTL(a, state) {
-    var stack = state.stack;
-    var p2i = stack.pop();
-    var p1i = stack.pop();
-    var p2 = state.z2[p2i];
-    var p1 = state.z1[p1i];
-
-    if (exports.DEBUG) { console.log('SPVTL[' + a + ']', p2i, p1i); }
-
-    var dx;
-    var dy;
-
-    if (!a) {
-        dx = p1.x - p2.x;
-        dy = p1.y - p2.y;
-    } else {
-        dx = p2.y - p1.y;
-        dy = p1.x - p2.x;
-    }
-
-    state.pv = state.dpv = getUnitVector(dx, dy);
-}
-
-// SFVTL[a] Set Freedom Vector To Line
-// 0x08-0x09
-function SFVTL(a, state) {
-    var stack = state.stack;
-    var p2i = stack.pop();
-    var p1i = stack.pop();
-    var p2 = state.z2[p2i];
-    var p1 = state.z1[p1i];
-
-    if (exports.DEBUG) { console.log('SFVTL[' + a + ']', p2i, p1i); }
-
-    var dx;
-    var dy;
-
-    if (!a) {
-        dx = p1.x - p2.x;
-        dy = p1.y - p2.y;
-    } else {
-        dx = p2.y - p1.y;
-        dy = p1.x - p2.x;
-    }
-
-    state.fv = getUnitVector(dx, dy);
-}
-
-// SPVFS[] Set Projection Vector From Stack
-// 0x0A
-function SPVFS(state) {
-    var stack = state.stack;
-    var y = stack.pop();
-    var x = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SPVFS[]', y, x); }
-
-    state.pv = state.dpv = getUnitVector(x, y);
-}
-
-// SFVFS[] Set Freedom Vector From Stack
-// 0x0B
-function SFVFS(state) {
-    var stack = state.stack;
-    var y = stack.pop();
-    var x = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SPVFS[]', y, x); }
-
-    state.fv = getUnitVector(x, y);
-}
-
-// GPV[] Get Projection Vector
-// 0x0C
-function GPV(state) {
-    var stack = state.stack;
-    var pv = state.pv;
-
-    if (exports.DEBUG) { console.log(state.step, 'GPV[]'); }
-
-    stack.push(pv.x * 0x4000);
-    stack.push(pv.y * 0x4000);
-}
-
-// GFV[] Get Freedom Vector
-// 0x0C
-function GFV(state) {
-    var stack = state.stack;
-    var fv = state.fv;
-
-    if (exports.DEBUG) { console.log(state.step, 'GFV[]'); }
-
-    stack.push(fv.x * 0x4000);
-    stack.push(fv.y * 0x4000);
-}
-
-// SFVTPV[] Set Freedom Vector To Projection Vector
-// 0x0E
-function SFVTPV(state) {
-    state.fv = state.pv;
-
-    if (exports.DEBUG) { console.log(state.step, 'SFVTPV[]'); }
-}
-
-// ISECT[] moves point p to the InterSECTion of two lines
-// 0x0F
-function ISECT(state)
-{
-    var stack = state.stack;
-    var pa0i = stack.pop();
-    var pa1i = stack.pop();
-    var pb0i = stack.pop();
-    var pb1i = stack.pop();
-    var pi = stack.pop();
-    var z0 = state.z0;
-    var z1 = state.z1;
-    var pa0 = z0[pa0i];
-    var pa1 = z0[pa1i];
-    var pb0 = z1[pb0i];
-    var pb1 = z1[pb1i];
-    var p = state.z2[pi];
-
-    if (exports.DEBUG) { console.log('ISECT[], ', pa0i, pa1i, pb0i, pb1i, pi); }
-
-    // math from
-    // en.wikipedia.org/wiki/Line%E2%80%93line_intersection#Given_two_points_on_each_line
-
-    var x1 = pa0.x;
-    var y1 = pa0.y;
-    var x2 = pa1.x;
-    var y2 = pa1.y;
-    var x3 = pb0.x;
-    var y3 = pb0.y;
-    var x4 = pb1.x;
-    var y4 = pb1.y;
-
-    var div = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
-    var f1 = x1 * y2 - y1 * x2;
-    var f2 = x3 * y4 - y3 * x4;
-
-    p.x = (f1 * (x3 - x4) - f2 * (x1 - x2)) / div;
-    p.y = (f1 * (y3 - y4) - f2 * (y1 - y2)) / div;
-}
-
-// SRP0[] Set Reference Point 0
-// 0x10
-function SRP0(state) {
-    state.rp0 = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SRP0[]', state.rp0); }
-}
-
-// SRP1[] Set Reference Point 1
-// 0x11
-function SRP1(state) {
-    state.rp1 = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SRP1[]', state.rp1); }
-}
-
-// SRP1[] Set Reference Point 2
-// 0x12
-function SRP2(state) {
-    state.rp2 = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SRP2[]', state.rp2); }
-}
-
-// SZP0[] Set Zone Pointer 0
-// 0x13
-function SZP0(state) {
-    var n = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SZP0[]', n); }
-
-    state.zp0 = n;
-
-    switch (n) {
-        case 0:
-            if (!state.tZone) { initTZone(state); }
-            state.z0 = state.tZone;
-            break;
-        case 1 :
-            state.z0 = state.gZone;
-            break;
-        default :
-            throw new Error('Invalid zone pointer');
-    }
-}
-
-// SZP1[] Set Zone Pointer 1
-// 0x14
-function SZP1(state) {
-    var n = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SZP1[]', n); }
-
-    state.zp1 = n;
-
-    switch (n) {
-        case 0:
-            if (!state.tZone) { initTZone(state); }
-            state.z1 = state.tZone;
-            break;
-        case 1 :
-            state.z1 = state.gZone;
-            break;
-        default :
-            throw new Error('Invalid zone pointer');
-    }
-}
-
-// SZP2[] Set Zone Pointer 2
-// 0x15
-function SZP2(state) {
-    var n = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SZP2[]', n); }
-
-    state.zp2 = n;
-
-    switch (n) {
-        case 0:
-            if (!state.tZone) { initTZone(state); }
-            state.z2 = state.tZone;
-            break;
-        case 1 :
-            state.z2 = state.gZone;
-            break;
-        default :
-            throw new Error('Invalid zone pointer');
-    }
-}
-
-// SZPS[] Set Zone PointerS
-// 0x16
-function SZPS(state) {
-    var n = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SZPS[]', n); }
-
-    state.zp0 = state.zp1 = state.zp2 = n;
-
-    switch (n) {
-        case 0:
-            if (!state.tZone) { initTZone(state); }
-            state.z0 = state.z1 = state.z2 = state.tZone;
-            break;
-        case 1 :
-            state.z0 = state.z1 = state.z2 = state.gZone;
-            break;
-        default :
-            throw new Error('Invalid zone pointer');
-    }
-}
-
-// SLOOP[] Set LOOP variable
-// 0x17
-function SLOOP(state) {
-    state.loop = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SLOOP[]', state.loop); }
-}
-
-// RTG[] Round To Grid
-// 0x18
-function RTG(state) {
-    if (exports.DEBUG) { console.log(state.step, 'RTG[]'); }
-
-    state.round = roundToGrid;
-}
-
-// RTHG[] Round To Half Grid
-// 0x19
-function RTHG(state) {
-    if (exports.DEBUG) { console.log(state.step, 'RTHG[]'); }
-
-    state.round = roundToHalfGrid;
-}
-
-// SMD[] Set Minimum Distance
-// 0x1A
-function SMD(state) {
-    var d = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SMD[]', d); }
-
-    state.minDis = d / 0x40;
-}
-
-// ELSE[] ELSE clause
-// 0x1B
-function ELSE(state) {
-    // This instruction has been reached by executing a then branch
-    // so it just skips ahead until matching EIF.
-    //
-    // In case the IF was negative the IF[] instruction already
-    // skipped forward over the ELSE[]
-
-    if (exports.DEBUG) { console.log(state.step, 'ELSE[]'); }
-
-    skip(state, false);
-}
-
-// JMPR[] JuMP Relative
-// 0x1C
-function JMPR(state) {
-    var o = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'JMPR[]', o); }
-
-    // A jump by 1 would do nothing.
-    state.ip += o - 1;
-}
-
-// SCVTCI[] Set Control Value Table Cut-In
-// 0x1D
-function SCVTCI(state) {
-    var n = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SCVTCI[]', n); }
-
-    state.cvCutIn = n / 0x40;
-}
-
-// DUP[] DUPlicate top stack element
-// 0x20
-function DUP(state) {
-    var stack = state.stack;
-
-    if (exports.DEBUG) { console.log(state.step, 'DUP[]'); }
-
-    stack.push(stack[stack.length - 1]);
-}
-
-// POP[] POP top stack element
-// 0x21
-function POP(state) {
-    if (exports.DEBUG) { console.log(state.step, 'POP[]'); }
-
-    state.stack.pop();
-}
-
-// CLEAR[] CLEAR the stack
-// 0x22
-function CLEAR(state) {
-    if (exports.DEBUG) { console.log(state.step, 'CLEAR[]'); }
-
-    state.stack.length = 0;
-}
-
-// SWAP[] SWAP the top two elements on the stack
-// 0x23
-function SWAP(state) {
-    var stack = state.stack;
-
-    var a = stack.pop();
-    var b = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SWAP[]'); }
-
-    stack.push(a);
-    stack.push(b);
-}
-
-// DEPTH[] DEPTH of the stack
-// 0x24
-function DEPTH(state) {
-    var stack = state.stack;
-
-    if (exports.DEBUG) { console.log(state.step, 'DEPTH[]'); }
-
-    stack.push(stack.length);
-}
-
-// LOOPCALL[] LOOPCALL function
-// 0x2A
-function LOOPCALL(state) {
-    var stack = state.stack;
-    var fn = stack.pop();
-    var c = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'LOOPCALL[]', fn, c); }
-
-    // saves callers program
-    var cip = state.ip;
-    var cprog = state.prog;
-
-    state.prog = state.funcs[fn];
-
-    // executes the function
-    for (var i = 0; i < c; i++) {
-        exec(state);
-
-        if (exports.DEBUG) { console.log(
-            ++state.step,
-            i + 1 < c ? 'next loopcall' : 'done loopcall',
-            i
-        ); }
-    }
-
-    // restores the callers program
-    state.ip = cip;
-    state.prog = cprog;
-}
-
-// CALL[] CALL function
-// 0x2B
-function CALL(state) {
-    var fn = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'CALL[]', fn); }
-
-    // saves callers program
-    var cip = state.ip;
-    var cprog = state.prog;
-
-    state.prog = state.funcs[fn];
-
-    // executes the function
-    exec(state);
-
-    // restores the callers program
-    state.ip = cip;
-    state.prog = cprog;
-
-    if (exports.DEBUG) { console.log(++state.step, 'returning from', fn); }
-}
-
-// CINDEX[] Copy the INDEXed element to the top of the stack
-// 0x25
-function CINDEX(state) {
-    var stack = state.stack;
-    var k = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'CINDEX[]', k); }
-
-    // In case of k == 1, it copies the last element after popping
-    // thus stack.length - k.
-    stack.push(stack[stack.length - k]);
-}
-
-// MINDEX[] Move the INDEXed element to the top of the stack
-// 0x26
-function MINDEX(state) {
-    var stack = state.stack;
-    var k = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'MINDEX[]', k); }
-
-    stack.push(stack.splice(stack.length - k, 1)[0]);
-}
-
-// FDEF[] Function DEFinition
-// 0x2C
-function FDEF(state) {
-    if (state.env !== 'fpgm') { throw new Error('FDEF not allowed here'); }
-    var stack = state.stack;
-    var prog = state.prog;
-    var ip = state.ip;
-
-    var fn = stack.pop();
-    var ipBegin = ip;
-
-    if (exports.DEBUG) { console.log(state.step, 'FDEF[]', fn); }
-
-    while (prog[++ip] !== 0x2D){ }
-
-    state.ip = ip;
-    state.funcs[fn] = prog.slice(ipBegin + 1, ip);
-}
-
-// MDAP[a] Move Direct Absolute Point
-// 0x2E-0x2F
-function MDAP(round, state) {
-    var pi = state.stack.pop();
-    var p = state.z0[pi];
-    var fv = state.fv;
-    var pv = state.pv;
-
-    if (exports.DEBUG) { console.log(state.step, 'MDAP[' + round + ']', pi); }
-
-    var d = pv.distance(p, HPZero);
-
-    if (round) { d = state.round(d); }
-
-    fv.setRelative(p, HPZero, d, pv);
-    fv.touch(p);
-
-    state.rp0 = state.rp1 = pi;
-}
-
-// IUP[a] Interpolate Untouched Points through the outline
-// 0x30
-function IUP(v, state) {
-    var z2 = state.z2;
-    var pLen = z2.length - 2;
-    var cp;
-    var pp;
-    var np;
-
-    if (exports.DEBUG) { console.log(state.step, 'IUP[' + v.axis + ']'); }
-
-    for (var i = 0; i < pLen; i++) {
-        cp = z2[i]; // current point
-
-        // if this point has been touched go on
-        if (v.touched(cp)) { continue; }
-
-        pp = cp.prevTouched(v);
-
-        // no point on the contour has been touched?
-        if (pp === cp) { continue; }
-
-        np = cp.nextTouched(v);
-
-        if (pp === np) {
-            // only one point on the contour has been touched
-            // so simply moves the point like that
-
-            v.setRelative(cp, cp, v.distance(pp, pp, false, true), v, true);
-        }
-
-        v.interpolate(cp, pp, np, v);
-    }
-}
-
-// SHP[] SHift Point using reference point
-// 0x32-0x33
-function SHP(a, state) {
-    var stack = state.stack;
-    var rpi = a ? state.rp1 : state.rp2;
-    var rp = (a ? state.z0 : state.z1)[rpi];
-    var fv = state.fv;
-    var pv = state.pv;
-    var loop = state.loop;
-    var z2 = state.z2;
-
-    while (loop--)
-    {
-        var pi = stack.pop();
-        var p = z2[pi];
-
-        var d = pv.distance(rp, rp, false, true);
-        fv.setRelative(p, p, d, pv);
-        fv.touch(p);
-
-        if (exports.DEBUG) {
-            console.log(
-                state.step,
-                (state.loop > 1 ?
-                   'loop ' + (state.loop - loop) + ': ' :
-                   ''
-                ) +
-                'SHP[' + (a ? 'rp1' : 'rp2') + ']', pi
-            );
-        }
-    }
-
-    state.loop = 1;
-}
-
-// SHC[] SHift Contour using reference point
-// 0x36-0x37
-function SHC(a, state) {
-    var stack = state.stack;
-    var rpi = a ? state.rp1 : state.rp2;
-    var rp = (a ? state.z0 : state.z1)[rpi];
-    var fv = state.fv;
-    var pv = state.pv;
-    var ci = stack.pop();
-    var sp = state.z2[state.contours[ci]];
-    var p = sp;
-
-    if (exports.DEBUG) { console.log(state.step, 'SHC[' + a + ']', ci); }
-
-    var d = pv.distance(rp, rp, false, true);
-
-    do {
-        if (p !== rp) { fv.setRelative(p, p, d, pv); }
-        p = p.nextPointOnContour;
-    } while (p !== sp);
-}
-
-// SHZ[] SHift Zone using reference point
-// 0x36-0x37
-function SHZ(a, state) {
-    var stack = state.stack;
-    var rpi = a ? state.rp1 : state.rp2;
-    var rp = (a ? state.z0 : state.z1)[rpi];
-    var fv = state.fv;
-    var pv = state.pv;
-
-    var e = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SHZ[' + a + ']', e); }
-
-    var z;
-    switch (e) {
-        case 0 : z = state.tZone; break;
-        case 1 : z = state.gZone; break;
-        default : throw new Error('Invalid zone');
-    }
-
-    var p;
-    var d = pv.distance(rp, rp, false, true);
-    var pLen = z.length - 2;
-    for (var i = 0; i < pLen; i++)
-    {
-        p = z[i];
-        fv.setRelative(p, p, d, pv);
-        //if (p !== rp) fv.setRelative(p, p, d, pv);
-    }
-}
-
-// SHPIX[] SHift point by a PIXel amount
-// 0x38
-function SHPIX(state) {
-    var stack = state.stack;
-    var loop = state.loop;
-    var fv = state.fv;
-    var d = stack.pop() / 0x40;
-    var z2 = state.z2;
-
-    while (loop--) {
-        var pi = stack.pop();
-        var p = z2[pi];
-
-        if (exports.DEBUG) {
-            console.log(
-                state.step,
-                (state.loop > 1 ? 'loop ' + (state.loop - loop) + ': ' : '') +
-                'SHPIX[]', pi, d
-            );
-        }
-
-        fv.setRelative(p, p, d);
-        fv.touch(p);
-    }
-
-    state.loop = 1;
-}
-
-// IP[] Interpolate Point
-// 0x39
-function IP(state) {
-    var stack = state.stack;
-    var rp1i = state.rp1;
-    var rp2i = state.rp2;
-    var loop = state.loop;
-    var rp1 = state.z0[rp1i];
-    var rp2 = state.z1[rp2i];
-    var fv = state.fv;
-    var pv = state.dpv;
-    var z2 = state.z2;
-
-    while (loop--) {
-        var pi = stack.pop();
-        var p = z2[pi];
-
-        if (exports.DEBUG) {
-            console.log(
-                state.step,
-                (state.loop > 1 ? 'loop ' + (state.loop - loop) + ': ' : '') +
-                'IP[]', pi, rp1i, '<->', rp2i
-            );
-        }
-
-        fv.interpolate(p, rp1, rp2, pv);
-
-        fv.touch(p);
-    }
-
-    state.loop = 1;
-}
-
-// MSIRP[a] Move Stack Indirect Relative Point
-// 0x3A-0x3B
-function MSIRP(a, state) {
-    var stack = state.stack;
-    var d = stack.pop() / 64;
-    var pi = stack.pop();
-    var p = state.z1[pi];
-    var rp0 = state.z0[state.rp0];
-    var fv = state.fv;
-    var pv = state.pv;
-
-    fv.setRelative(p, rp0, d, pv);
-    fv.touch(p);
-
-    if (exports.DEBUG) { console.log(state.step, 'MSIRP[' + a + ']', d, pi); }
-
-    state.rp1 = state.rp0;
-    state.rp2 = pi;
-    if (a) { state.rp0 = pi; }
-}
-
-// ALIGNRP[] Align to reference point.
-// 0x3C
-function ALIGNRP(state) {
-    var stack = state.stack;
-    var rp0i = state.rp0;
-    var rp0 = state.z0[rp0i];
-    var loop = state.loop;
-    var fv = state.fv;
-    var pv = state.pv;
-    var z1 = state.z1;
-
-    while (loop--) {
-        var pi = stack.pop();
-        var p = z1[pi];
-
-        if (exports.DEBUG) {
-            console.log(
-                state.step,
-                (state.loop > 1 ? 'loop ' + (state.loop - loop) + ': ' : '') +
-                'ALIGNRP[]', pi
-            );
-        }
-
-        fv.setRelative(p, rp0, 0, pv);
-        fv.touch(p);
-    }
-
-    state.loop = 1;
-}
-
-// RTG[] Round To Double Grid
-// 0x3D
-function RTDG(state) {
-    if (exports.DEBUG) { console.log(state.step, 'RTDG[]'); }
-
-    state.round = roundToDoubleGrid;
-}
-
-// MIAP[a] Move Indirect Absolute Point
-// 0x3E-0x3F
-function MIAP(round, state) {
-    var stack = state.stack;
-    var n = stack.pop();
-    var pi = stack.pop();
-    var p = state.z0[pi];
-    var fv = state.fv;
-    var pv = state.pv;
-    var cv = state.cvt[n];
-
-    if (exports.DEBUG) {
-        console.log(
-            state.step,
-            'MIAP[' + round + ']',
-            n, '(', cv, ')', pi
-        );
-    }
-
-    var d = pv.distance(p, HPZero);
-
-    if (round) {
-        if (Math.abs(d - cv) < state.cvCutIn) { d = cv; }
-
-        d = state.round(d);
-    }
-
-    fv.setRelative(p, HPZero, d, pv);
-
-    if (state.zp0 === 0) {
-        p.xo = p.x;
-        p.yo = p.y;
-    }
-
-    fv.touch(p);
-
-    state.rp0 = state.rp1 = pi;
-}
-
-// NPUSB[] PUSH N Bytes
-// 0x40
-function NPUSHB(state) {
-    var prog = state.prog;
-    var ip = state.ip;
-    var stack = state.stack;
-
-    var n = prog[++ip];
-
-    if (exports.DEBUG) { console.log(state.step, 'NPUSHB[]', n); }
-
-    for (var i = 0; i < n; i++) { stack.push(prog[++ip]); }
-
-    state.ip = ip;
-}
-
-// NPUSHW[] PUSH N Words
-// 0x41
-function NPUSHW(state) {
-    var ip = state.ip;
-    var prog = state.prog;
-    var stack = state.stack;
-    var n = prog[++ip];
-
-    if (exports.DEBUG) { console.log(state.step, 'NPUSHW[]', n); }
-
-    for (var i = 0; i < n; i++) {
-        var w = (prog[++ip] << 8) | prog[++ip];
-        if (w & 0x8000) { w = -((w ^ 0xffff) + 1); }
-        stack.push(w);
-    }
-
-    state.ip = ip;
-}
-
-// WS[] Write Store
-// 0x42
-function WS(state) {
-    var stack = state.stack;
-    var store = state.store;
-
-    if (!store) { store = state.store = []; }
-
-    var v = stack.pop();
-    var l = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'WS', v, l); }
-
-    store[l] = v;
-}
-
-// RS[] Read Store
-// 0x43
-function RS(state) {
-    var stack = state.stack;
-    var store = state.store;
-
-    var l = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'RS', l); }
-
-    var v = (store && store[l]) || 0;
-
-    stack.push(v);
-}
-
-// WCVTP[] Write Control Value Table in Pixel units
-// 0x44
-function WCVTP(state) {
-    var stack = state.stack;
-
-    var v = stack.pop();
-    var l = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'WCVTP', v, l); }
-
-    state.cvt[l] = v / 0x40;
-}
-
-// RCVT[] Read Control Value Table entry
-// 0x45
-function RCVT(state) {
-    var stack = state.stack;
-    var cvte = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'RCVT', cvte); }
-
-    stack.push(state.cvt[cvte] * 0x40);
-}
-
-// GC[] Get Coordinate projected onto the projection vector
-// 0x46-0x47
-function GC(a, state) {
-    var stack = state.stack;
-    var pi = stack.pop();
-    var p = state.z2[pi];
-
-    if (exports.DEBUG) { console.log(state.step, 'GC[' + a + ']', pi); }
-
-    stack.push(state.dpv.distance(p, HPZero, a, false) * 0x40);
-}
-
-// MD[a] Measure Distance
-// 0x49-0x4A
-function MD(a, state) {
-    var stack = state.stack;
-    var pi2 = stack.pop();
-    var pi1 = stack.pop();
-    var p2 = state.z1[pi2];
-    var p1 = state.z0[pi1];
-    var d = state.dpv.distance(p1, p2, a, a);
-
-    if (exports.DEBUG) { console.log(state.step, 'MD[' + a + ']', pi2, pi1, '->', d); }
-
-    state.stack.push(Math.round(d * 64));
-}
-
-// MPPEM[] Measure Pixels Per EM
-// 0x4B
-function MPPEM(state) {
-    if (exports.DEBUG) { console.log(state.step, 'MPPEM[]'); }
-    state.stack.push(state.ppem);
-}
-
-// FLIPON[] set the auto FLIP Boolean to ON
-// 0x4D
-function FLIPON(state) {
-    if (exports.DEBUG) { console.log(state.step, 'FLIPON[]'); }
-    state.autoFlip = true;
-}
-
-// LT[] Less Than
-// 0x50
-function LT(state) {
-    var stack = state.stack;
-    var e2 = stack.pop();
-    var e1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'LT[]', e2, e1); }
-
-    stack.push(e1 < e2 ? 1 : 0);
-}
-
-// LTEQ[] Less Than or EQual
-// 0x53
-function LTEQ(state) {
-    var stack = state.stack;
-    var e2 = stack.pop();
-    var e1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'LTEQ[]', e2, e1); }
-
-    stack.push(e1 <= e2 ? 1 : 0);
-}
-
-// GTEQ[] Greater Than
-// 0x52
-function GT(state) {
-    var stack = state.stack;
-    var e2 = stack.pop();
-    var e1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'GT[]', e2, e1); }
-
-    stack.push(e1 > e2 ? 1 : 0);
-}
-
-// GTEQ[] Greater Than or EQual
-// 0x53
-function GTEQ(state) {
-    var stack = state.stack;
-    var e2 = stack.pop();
-    var e1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'GTEQ[]', e2, e1); }
-
-    stack.push(e1 >= e2 ? 1 : 0);
-}
-
-// EQ[] EQual
-// 0x54
-function EQ(state) {
-    var stack = state.stack;
-    var e2 = stack.pop();
-    var e1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'EQ[]', e2, e1); }
-
-    stack.push(e2 === e1 ? 1 : 0);
-}
-
-// NEQ[] Not EQual
-// 0x55
-function NEQ(state) {
-    var stack = state.stack;
-    var e2 = stack.pop();
-    var e1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'NEQ[]', e2, e1); }
-
-    stack.push(e2 !== e1 ? 1 : 0);
-}
-
-// ODD[] ODD
-// 0x56
-function ODD(state) {
-    var stack = state.stack;
-    var n = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'ODD[]', n); }
-
-    stack.push(Math.trunc(n) % 2 ? 1 : 0);
-}
-
-// EVEN[] EVEN
-// 0x57
-function EVEN(state) {
-    var stack = state.stack;
-    var n = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'EVEN[]', n); }
-
-    stack.push(Math.trunc(n) % 2 ? 0 : 1);
-}
-
-// IF[] IF test
-// 0x58
-function IF(state) {
-    var test = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'IF[]', test); }
-
-    // if test is true it just continues
-    // if not the ip is skipped until matching ELSE or EIF
-    if (!test) {
-        skip(state, true);
-
-        if (exports.DEBUG) { console.log(state.step,  'EIF[]'); }
-    }
-}
-
-// EIF[] End IF
-// 0x59
-function EIF(state) {
-    // this can be reached normally when
-    // executing an else branch.
-    // -> just ignore it
-
-    if (exports.DEBUG) { console.log(state.step, 'EIF[]'); }
-}
-
-// AND[] logical AND
-// 0x5A
-function AND(state) {
-    var stack = state.stack;
-    var e2 = stack.pop();
-    var e1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'AND[]', e2, e1); }
-
-    stack.push(e2 && e1 ? 1 : 0);
-}
-
-// OR[] logical OR
-// 0x5B
-function OR(state) {
-    var stack = state.stack;
-    var e2 = stack.pop();
-    var e1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'OR[]', e2, e1); }
-
-    stack.push(e2 || e1 ? 1 : 0);
-}
-
-// NOT[] logical NOT
-// 0x5C
-function NOT(state) {
-    var stack = state.stack;
-    var e = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'NOT[]', e); }
-
-    stack.push(e ? 0 : 1);
-}
-
-// DELTAP1[] DELTA exception P1
-// DELTAP2[] DELTA exception P2
-// DELTAP3[] DELTA exception P3
-// 0x5D, 0x71, 0x72
-function DELTAP123(b, state) {
-    var stack = state.stack;
-    var n = stack.pop();
-    var fv = state.fv;
-    var pv = state.pv;
-    var ppem = state.ppem;
-    var base = state.deltaBase + (b - 1) * 16;
-    var ds = state.deltaShift;
-    var z0 = state.z0;
-
-    if (exports.DEBUG) { console.log(state.step, 'DELTAP[' + b + ']', n, stack); }
-
-    for (var i = 0; i < n; i++) {
-        var pi = stack.pop();
-        var arg = stack.pop();
-        var appem = base + ((arg & 0xF0) >> 4);
-        if (appem !== ppem) { continue; }
-
-        var mag = (arg & 0x0F) - 8;
-        if (mag >= 0) { mag++; }
-        if (exports.DEBUG) { console.log(state.step, 'DELTAPFIX', pi, 'by', mag * ds); }
-
-        var p = z0[pi];
-        fv.setRelative(p, p, mag * ds, pv);
-    }
-}
-
-// SDB[] Set Delta Base in the graphics state
-// 0x5E
-function SDB(state) {
-    var stack = state.stack;
-    var n = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SDB[]', n); }
-
-    state.deltaBase = n;
-}
-
-// SDS[] Set Delta Shift in the graphics state
-// 0x5F
-function SDS(state) {
-    var stack = state.stack;
-    var n = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SDS[]', n); }
-
-    state.deltaShift = Math.pow(0.5, n);
-}
-
-// ADD[] ADD
-// 0x60
-function ADD(state) {
-    var stack = state.stack;
-    var n2 = stack.pop();
-    var n1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'ADD[]', n2, n1); }
-
-    stack.push(n1 + n2);
-}
-
-// SUB[] SUB
-// 0x61
-function SUB(state) {
-    var stack = state.stack;
-    var n2 = stack.pop();
-    var n1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SUB[]', n2, n1); }
-
-    stack.push(n1 - n2);
-}
-
-// DIV[] DIV
-// 0x62
-function DIV(state) {
-    var stack = state.stack;
-    var n2 = stack.pop();
-    var n1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'DIV[]', n2, n1); }
-
-    stack.push(n1 * 64 / n2);
-}
-
-// MUL[] MUL
-// 0x63
-function MUL(state) {
-    var stack = state.stack;
-    var n2 = stack.pop();
-    var n1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'MUL[]', n2, n1); }
-
-    stack.push(n1 * n2 / 64);
-}
-
-// ABS[] ABSolute value
-// 0x64
-function ABS(state) {
-    var stack = state.stack;
-    var n = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'ABS[]', n); }
-
-    stack.push(Math.abs(n));
-}
-
-// NEG[] NEGate
-// 0x65
-function NEG(state) {
-    var stack = state.stack;
-    var n = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'NEG[]', n); }
-
-    stack.push(-n);
-}
-
-// FLOOR[] FLOOR
-// 0x66
-function FLOOR(state) {
-    var stack = state.stack;
-    var n = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'FLOOR[]', n); }
-
-    stack.push(Math.floor(n / 0x40) * 0x40);
-}
-
-// CEILING[] CEILING
-// 0x67
-function CEILING(state) {
-    var stack = state.stack;
-    var n = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'CEILING[]', n); }
-
-    stack.push(Math.ceil(n / 0x40) * 0x40);
-}
-
-// ROUND[ab] ROUND value
-// 0x68-0x6B
-function ROUND(dt, state) {
-    var stack = state.stack;
-    var n = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'ROUND[]'); }
-
-    stack.push(state.round(n / 0x40) * 0x40);
-}
-
-// WCVTF[] Write Control Value Table in Funits
-// 0x70
-function WCVTF(state) {
-    var stack = state.stack;
-    var v = stack.pop();
-    var l = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'WCVTF[]', v, l); }
-
-    state.cvt[l] = v * state.ppem / state.font.unitsPerEm;
-}
-
-// DELTAC1[] DELTA exception C1
-// DELTAC2[] DELTA exception C2
-// DELTAC3[] DELTA exception C3
-// 0x73, 0x74, 0x75
-function DELTAC123(b, state) {
-    var stack = state.stack;
-    var n = stack.pop();
-    var ppem = state.ppem;
-    var base = state.deltaBase + (b - 1) * 16;
-    var ds = state.deltaShift;
-
-    if (exports.DEBUG) { console.log(state.step, 'DELTAC[' + b + ']', n, stack); }
-
-    for (var i = 0; i < n; i++) {
-        var c = stack.pop();
-        var arg = stack.pop();
-        var appem = base + ((arg & 0xF0) >> 4);
-        if (appem !== ppem) { continue; }
-
-        var mag = (arg & 0x0F) - 8;
-        if (mag >= 0) { mag++; }
-
-        var delta = mag * ds;
-
-        if (exports.DEBUG) { console.log(state.step, 'DELTACFIX', c, 'by', delta); }
-
-        state.cvt[c] += delta;
-    }
-}
-
-// SROUND[] Super ROUND
-// 0x76
-function SROUND(state) {
-    var n = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'SROUND[]', n); }
-
-    state.round = roundSuper;
-
-    var period;
-
-    switch (n & 0xC0) {
-        case 0x00:
-            period = 0.5;
-            break;
-        case 0x40:
-            period = 1;
-            break;
-        case 0x80:
-            period = 2;
-            break;
-        default:
-            throw new Error('invalid SROUND value');
-    }
-
-    state.srPeriod = period;
-
-    switch (n & 0x30) {
-        case 0x00:
-            state.srPhase = 0;
-            break;
-        case 0x10:
-            state.srPhase = 0.25 * period;
-            break;
-        case 0x20:
-            state.srPhase = 0.5  * period;
-            break;
-        case 0x30:
-            state.srPhase = 0.75 * period;
-            break;
-        default: throw new Error('invalid SROUND value');
-    }
-
-    n &= 0x0F;
-
-    if (n === 0) { state.srThreshold = 0; }
-    else { state.srThreshold = (n / 8 - 0.5) * period; }
-}
-
-// S45ROUND[] Super ROUND 45 degrees
-// 0x77
-function S45ROUND(state) {
-    var n = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'S45ROUND[]', n); }
-
-    state.round = roundSuper;
-
-    var period;
-
-    switch (n & 0xC0) {
-        case 0x00:
-            period = Math.sqrt(2) / 2;
-            break;
-        case 0x40:
-            period = Math.sqrt(2);
-            break;
-        case 0x80:
-            period = 2 * Math.sqrt(2);
-            break;
-        default:
-            throw new Error('invalid S45ROUND value');
-    }
-
-    state.srPeriod = period;
-
-    switch (n & 0x30) {
-        case 0x00:
-            state.srPhase = 0;
-            break;
-        case 0x10:
-            state.srPhase = 0.25 * period;
-            break;
-        case 0x20:
-            state.srPhase = 0.5  * period;
-            break;
-        case 0x30:
-            state.srPhase = 0.75 * period;
-            break;
-        default:
-            throw new Error('invalid S45ROUND value');
-    }
-
-    n &= 0x0F;
-
-    if (n === 0) { state.srThreshold = 0; }
-    else { state.srThreshold = (n / 8 - 0.5) * period; }
-}
-
-// ROFF[] Round Off
-// 0x7A
-function ROFF(state) {
-    if (exports.DEBUG) { console.log(state.step, 'ROFF[]'); }
-
-    state.round = roundOff;
-}
-
-// RUTG[] Round Up To Grid
-// 0x7C
-function RUTG(state) {
-    if (exports.DEBUG) { console.log(state.step, 'RUTG[]'); }
-
-    state.round = roundUpToGrid;
-}
-
-// RDTG[] Round Down To Grid
-// 0x7D
-function RDTG(state) {
-    if (exports.DEBUG) { console.log(state.step, 'RDTG[]'); }
-
-    state.round = roundDownToGrid;
-}
-
-// SCANCTRL[] SCAN conversion ConTRoL
-// 0x85
-function SCANCTRL(state) {
-    var n = state.stack.pop();
-
-    // ignored by opentype.js
-
-    if (exports.DEBUG) { console.log(state.step, 'SCANCTRL[]', n); }
-}
-
-// SDPVTL[a] Set Dual Projection Vector To Line
-// 0x86-0x87
-function SDPVTL(a, state) {
-    var stack = state.stack;
-    var p2i = stack.pop();
-    var p1i = stack.pop();
-    var p2 = state.z2[p2i];
-    var p1 = state.z1[p1i];
-
-    if (exports.DEBUG) { console.log(state.step, 'SDPVTL[' + a + ']', p2i, p1i); }
-
-    var dx;
-    var dy;
-
-    if (!a) {
-        dx = p1.x - p2.x;
-        dy = p1.y - p2.y;
-    } else {
-        dx = p2.y - p1.y;
-        dy = p1.x - p2.x;
-    }
-
-    state.dpv = getUnitVector(dx, dy);
-}
-
-// GETINFO[] GET INFOrmation
-// 0x88
-function GETINFO(state) {
-    var stack = state.stack;
-    var sel = stack.pop();
-    var r = 0;
-
-    if (exports.DEBUG) { console.log(state.step, 'GETINFO[]', sel); }
-
-    // v35 as in no subpixel hinting
-    if (sel & 0x01) { r = 35; }
-
-    // TODO rotation and stretch currently not supported
-    // and thus those GETINFO are always 0.
-
-    // opentype.js is always gray scaling
-    if (sel & 0x20) { r |= 0x1000; }
-
-    stack.push(r);
-}
-
-// ROLL[] ROLL the top three stack elements
-// 0x8A
-function ROLL(state) {
-    var stack = state.stack;
-    var a = stack.pop();
-    var b = stack.pop();
-    var c = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'ROLL[]'); }
-
-    stack.push(b);
-    stack.push(a);
-    stack.push(c);
-}
-
-// MAX[] MAXimum of top two stack elements
-// 0x8B
-function MAX(state) {
-    var stack = state.stack;
-    var e2 = stack.pop();
-    var e1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'MAX[]', e2, e1); }
-
-    stack.push(Math.max(e1, e2));
-}
-
-// MIN[] MINimum of top two stack elements
-// 0x8C
-function MIN(state) {
-    var stack = state.stack;
-    var e2 = stack.pop();
-    var e1 = stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'MIN[]', e2, e1); }
-
-    stack.push(Math.min(e1, e2));
-}
-
-// SCANTYPE[] SCANTYPE
-// 0x8D
-function SCANTYPE(state) {
-    var n = state.stack.pop();
-    // ignored by opentype.js
-    if (exports.DEBUG) { console.log(state.step, 'SCANTYPE[]', n); }
-}
-
-// INSTCTRL[] INSTCTRL
-// 0x8D
-function INSTCTRL(state) {
-    var s = state.stack.pop();
-    var v = state.stack.pop();
-
-    if (exports.DEBUG) { console.log(state.step, 'INSTCTRL[]', s, v); }
-
-    switch (s) {
-        case 1 : state.inhibitGridFit = !!v; return;
-        case 2 : state.ignoreCvt = !!v; return;
-        default: throw new Error('invalid INSTCTRL[] selector');
-    }
-}
-
-// PUSHB[abc] PUSH Bytes
-// 0xB0-0xB7
-function PUSHB(n, state) {
-    var stack = state.stack;
-    var prog = state.prog;
-    var ip = state.ip;
-
-    if (exports.DEBUG) { console.log(state.step, 'PUSHB[' + n + ']'); }
-
-    for (var i = 0; i < n; i++) { stack.push(prog[++ip]); }
-
-    state.ip = ip;
-}
-
-// PUSHW[abc] PUSH Words
-// 0xB8-0xBF
-function PUSHW(n, state) {
-    var ip = state.ip;
-    var prog = state.prog;
-    var stack = state.stack;
-
-    if (exports.DEBUG) { console.log(state.ip, 'PUSHW[' + n + ']'); }
-
-    for (var i = 0; i < n; i++) {
-        var w = (prog[++ip] << 8) | prog[++ip];
-        if (w & 0x8000) { w = -((w ^ 0xffff) + 1); }
-        stack.push(w);
-    }
-
-    state.ip = ip;
-}
-
-// MDRP[abcde] Move Direct Relative Point
-// 0xD0-0xEF
-// (if indirect is 0)
-//
-// and
-//
-// MIRP[abcde] Move Indirect Relative Point
-// 0xE0-0xFF
-// (if indirect is 1)
-
-function MDRP_MIRP(indirect, setRp0, keepD, ro, dt, state) {
-    var stack = state.stack;
-    var cvte = indirect && stack.pop();
-    var pi = stack.pop();
-    var rp0i = state.rp0;
-    var rp = state.z0[rp0i];
-    var p = state.z1[pi];
-
-    var md = state.minDis;
-    var fv = state.fv;
-    var pv = state.dpv;
-    var od; // original distance
-    var d; // moving distance
-    var sign; // sign of distance
-    var cv;
-
-    d = od = pv.distance(p, rp, true, true);
-    sign = d >= 0 ? 1 : -1; // Math.sign would be 0 in case of 0
-
-    // TODO consider autoFlip
-    d = Math.abs(d);
-
-    if (indirect) {
-        cv = state.cvt[cvte];
-
-        if (ro && Math.abs(d - cv) < state.cvCutIn) { d = cv; }
-    }
-
-    if (keepD && d < md) { d = md; }
-
-    if (ro) { d = state.round(d); }
-
-    fv.setRelative(p, rp, sign * d, pv);
-    fv.touch(p);
-
-    if (exports.DEBUG) {
-        console.log(
-            state.step,
-            (indirect ? 'MIRP[' : 'MDRP[') +
-            (setRp0 ? 'M' : 'm') +
-            (keepD ? '>' : '_') +
-            (ro ? 'R' : '_') +
-            (dt === 0 ? 'Gr' : (dt === 1 ? 'Bl' : (dt === 2 ? 'Wh' : ''))) +
-            ']',
-            indirect ?
-                cvte + '(' + state.cvt[cvte] + ',' +  cv + ')' :
-                '',
-            pi,
-            '(d =', od, '->', sign * d, ')'
-        );
-    }
-
-    state.rp1 = state.rp0;
-    state.rp2 = pi;
-    if (setRp0) { state.rp0 = pi; }
-}
-
-/*
-* The instruction table.
-*/
-instructionTable = [
-    /* 0x00 */ SVTCA.bind(undefined, yUnitVector),
-    /* 0x01 */ SVTCA.bind(undefined, xUnitVector),
-    /* 0x02 */ SPVTCA.bind(undefined, yUnitVector),
-    /* 0x03 */ SPVTCA.bind(undefined, xUnitVector),
-    /* 0x04 */ SFVTCA.bind(undefined, yUnitVector),
-    /* 0x05 */ SFVTCA.bind(undefined, xUnitVector),
-    /* 0x06 */ SPVTL.bind(undefined, 0),
-    /* 0x07 */ SPVTL.bind(undefined, 1),
-    /* 0x08 */ SFVTL.bind(undefined, 0),
-    /* 0x09 */ SFVTL.bind(undefined, 1),
-    /* 0x0A */ SPVFS,
-    /* 0x0B */ SFVFS,
-    /* 0x0C */ GPV,
-    /* 0x0D */ GFV,
-    /* 0x0E */ SFVTPV,
-    /* 0x0F */ ISECT,
-    /* 0x10 */ SRP0,
-    /* 0x11 */ SRP1,
-    /* 0x12 */ SRP2,
-    /* 0x13 */ SZP0,
-    /* 0x14 */ SZP1,
-    /* 0x15 */ SZP2,
-    /* 0x16 */ SZPS,
-    /* 0x17 */ SLOOP,
-    /* 0x18 */ RTG,
-    /* 0x19 */ RTHG,
-    /* 0x1A */ SMD,
-    /* 0x1B */ ELSE,
-    /* 0x1C */ JMPR,
-    /* 0x1D */ SCVTCI,
-    /* 0x1E */ undefined,   // TODO SSWCI
-    /* 0x1F */ undefined,   // TODO SSW
-    /* 0x20 */ DUP,
-    /* 0x21 */ POP,
-    /* 0x22 */ CLEAR,
-    /* 0x23 */ SWAP,
-    /* 0x24 */ DEPTH,
-    /* 0x25 */ CINDEX,
-    /* 0x26 */ MINDEX,
-    /* 0x27 */ undefined,   // TODO ALIGNPTS
-    /* 0x28 */ undefined,
-    /* 0x29 */ undefined,   // TODO UTP
-    /* 0x2A */ LOOPCALL,
-    /* 0x2B */ CALL,
-    /* 0x2C */ FDEF,
-    /* 0x2D */ undefined,   // ENDF (eaten by FDEF)
-    /* 0x2E */ MDAP.bind(undefined, 0),
-    /* 0x2F */ MDAP.bind(undefined, 1),
-    /* 0x30 */ IUP.bind(undefined, yUnitVector),
-    /* 0x31 */ IUP.bind(undefined, xUnitVector),
-    /* 0x32 */ SHP.bind(undefined, 0),
-    /* 0x33 */ SHP.bind(undefined, 1),
-    /* 0x34 */ SHC.bind(undefined, 0),
-    /* 0x35 */ SHC.bind(undefined, 1),
-    /* 0x36 */ SHZ.bind(undefined, 0),
-    /* 0x37 */ SHZ.bind(undefined, 1),
-    /* 0x38 */ SHPIX,
-    /* 0x39 */ IP,
-    /* 0x3A */ MSIRP.bind(undefined, 0),
-    /* 0x3B */ MSIRP.bind(undefined, 1),
-    /* 0x3C */ ALIGNRP,
-    /* 0x3D */ RTDG,
-    /* 0x3E */ MIAP.bind(undefined, 0),
-    /* 0x3F */ MIAP.bind(undefined, 1),
-    /* 0x40 */ NPUSHB,
-    /* 0x41 */ NPUSHW,
-    /* 0x42 */ WS,
-    /* 0x43 */ RS,
-    /* 0x44 */ WCVTP,
-    /* 0x45 */ RCVT,
-    /* 0x46 */ GC.bind(undefined, 0),
-    /* 0x47 */ GC.bind(undefined, 1),
-    /* 0x48 */ undefined,   // TODO SCFS
-    /* 0x49 */ MD.bind(undefined, 0),
-    /* 0x4A */ MD.bind(undefined, 1),
-    /* 0x4B */ MPPEM,
-    /* 0x4C */ undefined,   // TODO MPS
-    /* 0x4D */ FLIPON,
-    /* 0x4E */ undefined,   // TODO FLIPOFF
-    /* 0x4F */ undefined,   // TODO DEBUG
-    /* 0x50 */ LT,
-    /* 0x51 */ LTEQ,
-    /* 0x52 */ GT,
-    /* 0x53 */ GTEQ,
-    /* 0x54 */ EQ,
-    /* 0x55 */ NEQ,
-    /* 0x56 */ ODD,
-    /* 0x57 */ EVEN,
-    /* 0x58 */ IF,
-    /* 0x59 */ EIF,
-    /* 0x5A */ AND,
-    /* 0x5B */ OR,
-    /* 0x5C */ NOT,
-    /* 0x5D */ DELTAP123.bind(undefined, 1),
-    /* 0x5E */ SDB,
-    /* 0x5F */ SDS,
-    /* 0x60 */ ADD,
-    /* 0x61 */ SUB,
-    /* 0x62 */ DIV,
-    /* 0x63 */ MUL,
-    /* 0x64 */ ABS,
-    /* 0x65 */ NEG,
-    /* 0x66 */ FLOOR,
-    /* 0x67 */ CEILING,
-    /* 0x68 */ ROUND.bind(undefined, 0),
-    /* 0x69 */ ROUND.bind(undefined, 1),
-    /* 0x6A */ ROUND.bind(undefined, 2),
-    /* 0x6B */ ROUND.bind(undefined, 3),
-    /* 0x6C */ undefined,   // TODO NROUND[ab]
-    /* 0x6D */ undefined,   // TODO NROUND[ab]
-    /* 0x6E */ undefined,   // TODO NROUND[ab]
-    /* 0x6F */ undefined,   // TODO NROUND[ab]
-    /* 0x70 */ WCVTF,
-    /* 0x71 */ DELTAP123.bind(undefined, 2),
-    /* 0x72 */ DELTAP123.bind(undefined, 3),
-    /* 0x73 */ DELTAC123.bind(undefined, 1),
-    /* 0x74 */ DELTAC123.bind(undefined, 2),
-    /* 0x75 */ DELTAC123.bind(undefined, 3),
-    /* 0x76 */ SROUND,
-    /* 0x77 */ S45ROUND,
-    /* 0x78 */ undefined,   // TODO JROT[]
-    /* 0x79 */ undefined,   // TODO JROF[]
-    /* 0x7A */ ROFF,
-    /* 0x7B */ undefined,
-    /* 0x7C */ RUTG,
-    /* 0x7D */ RDTG,
-    /* 0x7E */ POP, // actually SANGW, supposed to do only a pop though
-    /* 0x7F */ POP, // actually AA, supposed to do only a pop though
-    /* 0x80 */ undefined,   // TODO FLIPPT
-    /* 0x81 */ undefined,   // TODO FLIPRGON
-    /* 0x82 */ undefined,   // TODO FLIPRGOFF
-    /* 0x83 */ undefined,
-    /* 0x84 */ undefined,
-    /* 0x85 */ SCANCTRL,
-    /* 0x86 */ SDPVTL.bind(undefined, 0),
-    /* 0x87 */ SDPVTL.bind(undefined, 1),
-    /* 0x88 */ GETINFO,
-    /* 0x89 */ undefined,   // TODO IDEF
-    /* 0x8A */ ROLL,
-    /* 0x8B */ MAX,
-    /* 0x8C */ MIN,
-    /* 0x8D */ SCANTYPE,
-    /* 0x8E */ INSTCTRL,
-    /* 0x8F */ undefined,
-    /* 0x90 */ undefined,
-    /* 0x91 */ undefined,
-    /* 0x92 */ undefined,
-    /* 0x93 */ undefined,
-    /* 0x94 */ undefined,
-    /* 0x95 */ undefined,
-    /* 0x96 */ undefined,
-    /* 0x97 */ undefined,
-    /* 0x98 */ undefined,
-    /* 0x99 */ undefined,
-    /* 0x9A */ undefined,
-    /* 0x9B */ undefined,
-    /* 0x9C */ undefined,
-    /* 0x9D */ undefined,
-    /* 0x9E */ undefined,
-    /* 0x9F */ undefined,
-    /* 0xA0 */ undefined,
-    /* 0xA1 */ undefined,
-    /* 0xA2 */ undefined,
-    /* 0xA3 */ undefined,
-    /* 0xA4 */ undefined,
-    /* 0xA5 */ undefined,
-    /* 0xA6 */ undefined,
-    /* 0xA7 */ undefined,
-    /* 0xA8 */ undefined,
-    /* 0xA9 */ undefined,
-    /* 0xAA */ undefined,
-    /* 0xAB */ undefined,
-    /* 0xAC */ undefined,
-    /* 0xAD */ undefined,
-    /* 0xAE */ undefined,
-    /* 0xAF */ undefined,
-    /* 0xB0 */ PUSHB.bind(undefined, 1),
-    /* 0xB1 */ PUSHB.bind(undefined, 2),
-    /* 0xB2 */ PUSHB.bind(undefined, 3),
-    /* 0xB3 */ PUSHB.bind(undefined, 4),
-    /* 0xB4 */ PUSHB.bind(undefined, 5),
-    /* 0xB5 */ PUSHB.bind(undefined, 6),
-    /* 0xB6 */ PUSHB.bind(undefined, 7),
-    /* 0xB7 */ PUSHB.bind(undefined, 8),
-    /* 0xB8 */ PUSHW.bind(undefined, 1),
-    /* 0xB9 */ PUSHW.bind(undefined, 2),
-    /* 0xBA */ PUSHW.bind(undefined, 3),
-    /* 0xBB */ PUSHW.bind(undefined, 4),
-    /* 0xBC */ PUSHW.bind(undefined, 5),
-    /* 0xBD */ PUSHW.bind(undefined, 6),
-    /* 0xBE */ PUSHW.bind(undefined, 7),
-    /* 0xBF */ PUSHW.bind(undefined, 8),
-    /* 0xC0 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 0, 0),
-    /* 0xC1 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 0, 1),
-    /* 0xC2 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 0, 2),
-    /* 0xC3 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 0, 3),
-    /* 0xC4 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 1, 0),
-    /* 0xC5 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 1, 1),
-    /* 0xC6 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 1, 2),
-    /* 0xC7 */ MDRP_MIRP.bind(undefined, 0, 0, 0, 1, 3),
-    /* 0xC8 */ MDRP_MIRP.bind(undefined, 0, 0, 1, 0, 0),
-    /* 0xC9 */ MDRP_MIRP.bind(undefined, 0, 0, 1, 0, 1),
-    /* 0xCA */ MDRP_MIRP.bind(undefined, 0, 0, 1, 0, 2),
-    /* 0xCB */ MDRP_MIRP.bind(undefined, 0, 0, 1, 0, 3),
-    /* 0xCC */ MDRP_MIRP.bind(undefined, 0, 0, 1, 1, 0),
-    /* 0xCD */ MDRP_MIRP.bind(undefined, 0, 0, 1, 1, 1),
-    /* 0xCE */ MDRP_MIRP.bind(undefined, 0, 0, 1, 1, 2),
-    /* 0xCF */ MDRP_MIRP.bind(undefined, 0, 0, 1, 1, 3),
-    /* 0xD0 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 0, 0),
-    /* 0xD1 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 0, 1),
-    /* 0xD2 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 0, 2),
-    /* 0xD3 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 0, 3),
-    /* 0xD4 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 1, 0),
-    /* 0xD5 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 1, 1),
-    /* 0xD6 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 1, 2),
-    /* 0xD7 */ MDRP_MIRP.bind(undefined, 0, 1, 0, 1, 3),
-    /* 0xD8 */ MDRP_MIRP.bind(undefined, 0, 1, 1, 0, 0),
-    /* 0xD9 */ MDRP_MIRP.bind(undefined, 0, 1, 1, 0, 1),
-    /* 0xDA */ MDRP_MIRP.bind(undefined, 0, 1, 1, 0, 2),
-    /* 0xDB */ MDRP_MIRP.bind(undefined, 0, 1, 1, 0, 3),
-    /* 0xDC */ MDRP_MIRP.bind(undefined, 0, 1, 1, 1, 0),
-    /* 0xDD */ MDRP_MIRP.bind(undefined, 0, 1, 1, 1, 1),
-    /* 0xDE */ MDRP_MIRP.bind(undefined, 0, 1, 1, 1, 2),
-    /* 0xDF */ MDRP_MIRP.bind(undefined, 0, 1, 1, 1, 3),
-    /* 0xE0 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 0, 0),
-    /* 0xE1 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 0, 1),
-    /* 0xE2 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 0, 2),
-    /* 0xE3 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 0, 3),
-    /* 0xE4 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 1, 0),
-    /* 0xE5 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 1, 1),
-    /* 0xE6 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 1, 2),
-    /* 0xE7 */ MDRP_MIRP.bind(undefined, 1, 0, 0, 1, 3),
-    /* 0xE8 */ MDRP_MIRP.bind(undefined, 1, 0, 1, 0, 0),
-    /* 0xE9 */ MDRP_MIRP.bind(undefined, 1, 0, 1, 0, 1),
-    /* 0xEA */ MDRP_MIRP.bind(undefined, 1, 0, 1, 0, 2),
-    /* 0xEB */ MDRP_MIRP.bind(undefined, 1, 0, 1, 0, 3),
-    /* 0xEC */ MDRP_MIRP.bind(undefined, 1, 0, 1, 1, 0),
-    /* 0xED */ MDRP_MIRP.bind(undefined, 1, 0, 1, 1, 1),
-    /* 0xEE */ MDRP_MIRP.bind(undefined, 1, 0, 1, 1, 2),
-    /* 0xEF */ MDRP_MIRP.bind(undefined, 1, 0, 1, 1, 3),
-    /* 0xF0 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 0, 0),
-    /* 0xF1 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 0, 1),
-    /* 0xF2 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 0, 2),
-    /* 0xF3 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 0, 3),
-    /* 0xF4 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 1, 0),
-    /* 0xF5 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 1, 1),
-    /* 0xF6 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 1, 2),
-    /* 0xF7 */ MDRP_MIRP.bind(undefined, 1, 1, 0, 1, 3),
-    /* 0xF8 */ MDRP_MIRP.bind(undefined, 1, 1, 1, 0, 0),
-    /* 0xF9 */ MDRP_MIRP.bind(undefined, 1, 1, 1, 0, 1),
-    /* 0xFA */ MDRP_MIRP.bind(undefined, 1, 1, 1, 0, 2),
-    /* 0xFB */ MDRP_MIRP.bind(undefined, 1, 1, 1, 0, 3),
-    /* 0xFC */ MDRP_MIRP.bind(undefined, 1, 1, 1, 1, 0),
-    /* 0xFD */ MDRP_MIRP.bind(undefined, 1, 1, 1, 1, 1),
-    /* 0xFE */ MDRP_MIRP.bind(undefined, 1, 1, 1, 1, 2),
-    /* 0xFF */ MDRP_MIRP.bind(undefined, 1, 1, 1, 1, 3)
-];
-
-/*****************************
-  Mathematical Considerations
-******************************
-
-fv ... refers to freedom vector
-pv ... refers to projection vector
-rp ... refers to reference point
-p  ... refers to to point being operated on
-d  ... refers to distance
-
-SETRELATIVE:
-============
-
-case freedom vector == x-axis:
-------------------------------
-
-                        (pv)
-                     .-'
-              rpd .-'
-               .-*
-          d .-'90°'
-         .-'       '
-      .-'           '
-   *-'               ' b
-  rp                  '
-                       '
-                        '
-            p *----------*-------------- (fv)
-                          pm
-
-  rpdx = rpx + d * pv.x
-  rpdy = rpy + d * pv.y
-
-  equation of line b
-
-   y - rpdy = pvns * (x- rpdx)
-
-   y = p.y
-
-   x = rpdx + ( p.y - rpdy ) / pvns
-
-
-case freedom vector == y-axis:
-------------------------------
-
-    * pm
-    |\
-    | \
-    |  \
-    |   \
-    |    \
-    |     \
-    |      \
-    |       \
-    |        \
-    |         \ b
-    |          \
-    |           \
-    |            \    .-' (pv)
-    |         90° \.-'
-    |           .-'* rpd
-    |        .-'
-    *     *-'  d
-    p     rp
-
-  rpdx = rpx + d * pv.x
-  rpdy = rpy + d * pv.y
-
-  equation of line b:
-           pvns ... normal slope to pv
-
-   y - rpdy = pvns * (x - rpdx)
-
-   x = p.x
-
-   y = rpdy +  pvns * (p.x - rpdx)
-
-
-
-generic case:
--------------
-
-
-                              .'(fv)
-                            .'
-                          .* pm
-                        .' !
-                      .'    .
-                    .'      !
-                  .'         . b
-                .'           !
-               *              .
-              p               !
-                         90°   .    ... (pv)
-                           ...-*-'''
-                  ...---'''    rpd
-         ...---'''   d
-   *--'''
-  rp
-
-    rpdx = rpx + d * pv.x
-    rpdy = rpy + d * pv.y
-
- equation of line b:
-    pvns... normal slope to pv
-
-    y - rpdy = pvns * (x - rpdx)
-
- equation of freedom vector line:
-    fvs ... slope of freedom vector (=fy/fx)
-
-    y - py = fvs * (x - px)
-
-
-  on pm both equations are true for same x/y
-
-    y - rpdy = pvns * (x - rpdx)
-
-    y - py = fvs * (x - px)
-
-  form to y and set equal:
-
-    pvns * (x - rpdx) + rpdy = fvs * (x - px) + py
-
-  expand:
-
-    pvns * x - pvns * rpdx + rpdy = fvs * x - fvs * px + py
-
-  switch:
-
-    fvs * x - fvs * px + py = pvns * x - pvns * rpdx + rpdy
-
-  solve for x:
-
-    fvs * x - pvns * x = fvs * px - pvns * rpdx - py + rpdy
-
-
-
-          fvs * px - pvns * rpdx + rpdy - py
-    x =  -----------------------------------
-                 fvs - pvns
-
-  and:
-
-    y = fvs * (x - px) + py
-
-
-
-INTERPOLATE:
-============
-
-Examples of point interpolation.
-
-The weight of the movement of the reference point gets bigger
-the further the other reference point is away, thus the safest
-option (that is avoiding 0/0 divisions) is to weight the
-original distance of the other point by the sum of both distances.
-
-If the sum of both distances is 0, then move the point by the
-arithmetic average of the movement of both reference points.
-
-
-
-
-           (+6)
-    rp1o *---->*rp1
-         .     .                          (+12)
-         .     .                  rp2o *---------->* rp2
-         .     .                       .           .
-         .     .                       .           .
-         .    10          20           .           .
-         |.........|...................|           .
-               .   .                               .
-               .   . (+8)                          .
-                po *------>*p                      .
-               .           .                       .
-               .    12     .          24           .
-               |...........|.......................|
-                                  36
-
-
--------
-
-
-
-           (+10)
-    rp1o *-------->*rp1
-         .         .                      (-10)
-         .         .              rp2 *<---------* rpo2
-         .         .                   .         .
-         .         .                   .         .
-         .    10   .          30       .         .
-         |.........|.............................|
-                   .                   .
-                   . (+5)              .
-                po *--->* p            .
-                   .    .              .
-                   .    .   20         .
-                   |....|..............|
-                     5        15
-
-
--------
-
-
-           (+10)
-    rp1o *-------->*rp1
-         .         .
-         .         .
-    rp2o *-------->*rp2
-
-
-                               (+10)
-                          po *-------->* p
-
--------
-
-
-           (+10)
-    rp1o *-------->*rp1
-         .         .
-         .         .(+30)
-    rp2o *---------------------------->*rp2
-
-
-                                        (+25)
-                          po *----------------------->* p
-
-
-
-vim: set ts=4 sw=4 expandtab:
-*****/
-
-/**
- * Converts a string into a list of tokens.
- */
-
-/**
- * Create a new token
- * @param {string} char a single char
- */
-function Token(char) {
-    this.char = char;
-    this.state = {};
-    this.activeState = null;
-}
-
-/**
- * Create a new context range
- * @param {number} startIndex range start index
- * @param {number} endOffset range end index offset
- * @param {string} contextName owner context name
- */
-function ContextRange(startIndex, endOffset, contextName) {
-    this.contextName = contextName;
-    this.startIndex = startIndex;
-    this.endOffset = endOffset;
-}
-
-/**
- * Check context start and end
- * @param {string} contextName a unique context name
- * @param {function} checkStart a predicate function the indicates a context's start
- * @param {function} checkEnd a predicate function the indicates a context's end
- */
-function ContextChecker(contextName, checkStart, checkEnd) {
-    this.contextName = contextName;
-    this.openRange = null;
-    this.ranges = [];
-    this.checkStart = checkStart;
-    this.checkEnd = checkEnd;
-}
-
-/**
- * @typedef ContextParams
- * @type Object
- * @property {array} context context items
- * @property {number} currentIndex current item index
- */
-
-/**
- * Create a context params
- * @param {array} context a list of items
- * @param {number} currentIndex current item index
- */
-function ContextParams(context, currentIndex) {
-    this.context = context;
-    this.index = currentIndex;
-    this.length = context.length;
-    this.current = context[currentIndex];
-    this.backtrack = context.slice(0, currentIndex);
-    this.lookahead = context.slice(currentIndex + 1);
-}
-
-/**
- * Create an event instance
- * @param {string} eventId event unique id
- */
-function Event(eventId) {
-    this.eventId = eventId;
-    this.subscribers = [];
-}
-
-/**
- * Initialize a core events and auto subscribe required event handlers
- * @param {any} events an object that enlists core events handlers
- */
-function initializeCoreEvents(events) {
-    var this$1 = this;
-
-    var coreEvents = [
-        'start', 'end', 'next', 'newToken', 'contextStart',
-        'contextEnd', 'insertToken', 'removeToken', 'removeRange',
-        'replaceToken', 'replaceRange', 'composeRUD', 'updateContextsRanges'
-    ];
-
-    coreEvents.forEach(function (eventId) {
-        Object.defineProperty(this$1.events, eventId, {
-            value: new Event(eventId)
-        });
-    });
-
-    if (!!events) {
-        coreEvents.forEach(function (eventId) {
-            var event = events[eventId];
-            if (typeof event === 'function') {
-                this$1.events[eventId].subscribe(event);
-            }
-        });
-    }
-    var requiresContextUpdate = [
-        'insertToken', 'removeToken', 'removeRange',
-        'replaceToken', 'replaceRange', 'composeRUD'
-    ];
-    requiresContextUpdate.forEach(function (eventId) {
-        this$1.events[eventId].subscribe(
-            this$1.updateContextsRanges
-        );
-    });
-}
-
-/**
- * Converts a string into a list of tokens
- * @param {any} events tokenizer core events
- */
-function Tokenizer(events) {
-    this.tokens = [];
-    this.registeredContexts = {};
-    this.contextCheckers = [];
-    this.events = {};
-    this.registeredModifiers = [];
-
-    initializeCoreEvents.call(this, events);
-}
-
-/**
- * Sets the state of a token, usually called by a state modifier.
- * @param {string} key state item key
- * @param {any} value state item value
- */
-Token.prototype.setState = function(key, value) {
-    this.state[key] = value;
-    this.activeState = { key: key, value: this.state[key] };
-    return this.activeState;
-};
-
-Token.prototype.getState = function (stateId) {
-    return this.state[stateId] || null;
-};
-
-/**
- * Checks if an index exists in the tokens list.
- * @param {number} index token index
- */
-Tokenizer.prototype.inboundIndex = function(index) {
-    return index >= 0 && index < this.tokens.length;
-};
-
-/**
- * Compose and apply a list of operations (replace, update, delete)
- * @param {array} RUDs replace, update and delete operations
- * TODO: Perf. Optimization (lengthBefore === lengthAfter ? dispatch once)
- */
-Tokenizer.prototype.composeRUD = function (RUDs) {
-    var this$1 = this;
-
-    var silent = true;
-    var state = RUDs.map(function (RUD) { return (
-        this$1[RUD[0]].apply(this$1, RUD.slice(1).concat(silent))
-    ); });
-    var hasFAILObject = function (obj) { return (
-        typeof obj === 'object' &&
-        obj.hasOwnProperty('FAIL')
-    ); };
-    if (state.every(hasFAILObject)) {
-        return {
-            FAIL: "composeRUD: one or more operations hasn't completed successfully",
-            report: state.filter(hasFAILObject)
-        };
-    }
-    this.dispatch('composeRUD', [state.filter(function (op) { return !hasFAILObject(op); })]);
-};
-
-/**
- * Replace a range of tokens with a list of tokens
- * @param {number} startIndex range start index
- * @param {number} offset range offset
- * @param {token} tokens a list of tokens to replace
- * @param {boolean} silent dispatch events and update context ranges
- */
-Tokenizer.prototype.replaceRange = function (startIndex, offset, tokens, silent) {
-    offset = offset !== null ? offset : this.tokens.length;
-    var isTokenType = tokens.every(function (token) { return token instanceof Token; });
-    if (!isNaN(startIndex) && this.inboundIndex(startIndex) && isTokenType) {
-        var replaced = this.tokens.splice.apply(
-            this.tokens, [startIndex, offset].concat(tokens)
-        );
-        if (!silent) { this.dispatch('replaceToken', [startIndex, offset, tokens]); }
-        return [replaced, tokens];
-    } else {
-        return { FAIL: 'replaceRange: invalid tokens or startIndex.' };
-    }
-};
-
-/**
- * Replace a token with another token
- * @param {number} index token index
- * @param {token} token a token to replace
- * @param {boolean} silent dispatch events and update context ranges
- */
-Tokenizer.prototype.replaceToken = function (index, token, silent) {
-    if (!isNaN(index) && this.inboundIndex(index) && token instanceof Token) {
-        var replaced = this.tokens.splice(index, 1, token);
-        if (!silent) { this.dispatch('replaceToken', [index, token]); }
-        return [replaced[0], token];
-    } else {
-        return { FAIL: 'replaceToken: invalid token or index.' };
-    }
-};
-
-/**
- * Removes a range of tokens
- * @param {number} startIndex range start index
- * @param {number} offset range offset
- * @param {boolean} silent dispatch events and update context ranges
- */
-Tokenizer.prototype.removeRange = function(startIndex, offset, silent) {
-    offset = !isNaN(offset) ? offset : this.tokens.length;
-    var tokens = this.tokens.splice(startIndex, offset);
-    if (!silent) { this.dispatch('removeRange', [tokens, startIndex, offset]); }
-    return tokens;
-};
-
-/**
- * Remove a token at a certain index
- * @param {number} index token index
- * @param {boolean} silent dispatch events and update context ranges
- */
-Tokenizer.prototype.removeToken = function(index, silent) {
-    if (!isNaN(index) && this.inboundIndex(index)) {
-        var token = this.tokens.splice(index, 1);
-        if (!silent) { this.dispatch('removeToken', [token, index]); }
-        return token;
-    } else {
-        return { FAIL: 'removeToken: invalid token index.' };
-    }
-};
-
-/**
- * Insert a list of tokens at a certain index
- * @param {array} tokens a list of tokens to insert
- * @param {number} index insert the list of tokens at index
- * @param {boolean} silent dispatch events and update context ranges
- */
-Tokenizer.prototype.insertToken = function (tokens, index, silent) {
-    var tokenType = tokens.every(
-        function (token) { return token instanceof Token; }
-    );
-    if (tokenType) {
-        this.tokens.splice.apply(
-            this.tokens, [index, 0].concat(tokens)
-        );
-        if (!silent) { this.dispatch('insertToken', [tokens, index]); }
-        return tokens;
-    } else {
-        return { FAIL: 'insertToken: invalid token(s).' };
-    }
-};
-
-/**
- * A state modifier that is called on 'newToken' event
- * @param {string} modifierId state modifier id
- * @param {function} condition a predicate function that returns true or false
- * @param {function} modifier a function to update token state
- */
-Tokenizer.prototype.registerModifier = function(modifierId, condition, modifier) {
-    this.events.newToken.subscribe(function(token, contextParams) {
-        var conditionParams = [token, contextParams];
-        var canApplyModifier = (
-            condition === null ||
-            condition.apply(this, conditionParams) === true
-        );
-        var modifierParams = [token, contextParams];
-        if (canApplyModifier) {
-            var newStateValue = modifier.apply(this, modifierParams);
-            token.setState(modifierId, newStateValue);
-        }
-    });
-    this.registeredModifiers.push(modifierId);
-};
-
-/**
- * Subscribe a handler to an event
- * @param {function} eventHandler an event handler function
- */
-Event.prototype.subscribe = function (eventHandler) {
-    if (typeof eventHandler === 'function') {
-        return ((this.subscribers.push(eventHandler)) - 1);
-    } else {
-        return { FAIL: ("invalid '" + (this.eventId) + "' event handler")};
-    }
-};
-
-/**
- * Unsubscribe an event handler
- * @param {string} subsId subscription id
- */
-Event.prototype.unsubscribe = function (subsId) {
-    this.subscribers.splice(subsId, 1);
-};
-
-/**
- * Sets context params current value index
- * @param {number} index context params current value index
- */
-ContextParams.prototype.setCurrentIndex = function(index) {
-    this.index = index;
-    this.current = this.context[index];
-    this.backtrack = this.context.slice(0, index);
-    this.lookahead = this.context.slice(index + 1);
-};
-
-/**
- * Get an item at an offset from the current value
- * example (current value is 3):
- *  1    2   [3]   4    5   |   items values
- * -2   -1    0    1    2   |   offset values
- * @param {number} offset an offset from current value index
- */
-ContextParams.prototype.get = function (offset) {
-    switch (true) {
-        case (offset === 0):
-            return this.current;
-        case (offset < 0 && Math.abs(offset) <= this.backtrack.length):
-            return this.backtrack.slice(offset)[0];
-        case (offset > 0 && offset <= this.lookahead.length):
-            return this.lookahead[offset - 1];
-        default:
-            return null;
-    }
-};
-
-/**
- * Converts a context range into a string value
- * @param {contextRange} range a context range
- */
-Tokenizer.prototype.rangeToText = function (range) {
-    if (range instanceof ContextRange) {
-        return (
-            this.getRangeTokens(range)
-                .map(function (token) { return token.char; }).join('')
-        );
-    }
-};
-
-/**
- * Converts all tokens into a string
- */
-Tokenizer.prototype.getText = function () {
-    return this.tokens.map(function (token) { return token.char; }).join('');
-};
-
-/**
- * Get a context by name
- * @param {string} contextName context name to get
- */
-Tokenizer.prototype.getContext = function (contextName) {
-    var context = this.registeredContexts[contextName];
-    return !!context ? context : null;
-};
-
-/**
- * Subscribes a new event handler to an event
- * @param {string} eventName event name to subscribe to
- * @param {function} eventHandler a function to be invoked on event
- */
-Tokenizer.prototype.on = function(eventName, eventHandler) {
-    var event = this.events[eventName];
-    if (!!event) {
-        return event.subscribe(eventHandler);
-    } else {
-        return null;
-    }
-};
-
-/**
- * Dispatches an event
- * @param {string} eventName event name
- * @param {any} args event handler arguments
- */
-Tokenizer.prototype.dispatch = function(eventName, args) {
-    var this$1 = this;
-
-    var event = this.events[eventName];
-    if (event instanceof Event) {
-        event.subscribers.forEach(function (subscriber) {
-            subscriber.apply(this$1, args || []);
-        });
-    }
-};
-
-/**
- * Register a new context checker
- * @param {string} contextName a unique context name
- * @param {function} contextStartCheck a predicate function that returns true on context start
- * @param {function} contextEndCheck  a predicate function that returns true on context end
- * TODO: call tokenize on registration to update context ranges with the new context.
- */
-Tokenizer.prototype.registerContextChecker = function(contextName, contextStartCheck, contextEndCheck) {
-    if (!!this.getContext(contextName)) { return {
-        FAIL:
-        ("context name '" + contextName + "' is already registered.")
-    }; }
-    if (typeof contextStartCheck !== 'function') { return {
-        FAIL:
-        "missing context start check."
-    }; }
-    if (typeof contextEndCheck !== 'function') { return {
-        FAIL:
-        "missing context end check."
-    }; }
-    var contextCheckers = new ContextChecker(
-        contextName, contextStartCheck, contextEndCheck
-    );
-    this.registeredContexts[contextName] = contextCheckers;
-    this.contextCheckers.push(contextCheckers);
-    return contextCheckers;
-};
-
-/**
- * Gets a context range tokens
- * @param {contextRange} range a context range
- */
-Tokenizer.prototype.getRangeTokens = function(range) {
-    var endIndex = range.startIndex + range.endOffset;
-    return [].concat(
-        this.tokens
-            .slice(range.startIndex, endIndex)
-    );
-};
-
-/**
- * Gets the ranges of a context
- * @param {string} contextName context name
- */
-Tokenizer.prototype.getContextRanges = function(contextName) {
-    var context = this.getContext(contextName);
-    if (!!context) {
-        return context.ranges;
-    } else {
-        return { FAIL: ("context checker '" + contextName + "' is not registered.") };
-    }
-};
-
-/**
- * Resets context ranges to run context update
- */
-Tokenizer.prototype.resetContextsRanges = function () {
-    var registeredContexts = this.registeredContexts;
-    for (var contextName in registeredContexts) {
-        if (registeredContexts.hasOwnProperty(contextName)) {
-            var context = registeredContexts[contextName];
-            context.ranges = [];
-        }
-    }
-};
-
-/**
- * Updates context ranges
- */
-Tokenizer.prototype.updateContextsRanges = function () {
-    this.resetContextsRanges();
-    var chars = this.tokens.map(function (token) { return token.char; });
-    for (var i = 0; i < chars.length; i++) {
-        var contextParams = new ContextParams(chars, i);
-        this.runContextCheck(contextParams);
-    }
-    this.dispatch('updateContextsRanges', [this.registeredContexts]);
-};
-
-/**
- * Sets the end offset of an open range
- * @param {number} offset range end offset
- * @param {string} contextName context name
- */
-Tokenizer.prototype.setEndOffset = function (offset, contextName) {
-    var startIndex = this.getContext(contextName).openRange.startIndex;
-    var range = new ContextRange(startIndex, offset, contextName);
-    var ranges = this.getContext(contextName).ranges;
-    range.rangeId = contextName + "." + (ranges.length);
-    ranges.push(range);
-    this.getContext(contextName).openRange = null;
-    return range;
-};
-
-/**
- * Runs a context check on the current context
- * @param {contextParams} contextParams current context params
- */
-Tokenizer.prototype.runContextCheck = function(contextParams) {
-    var this$1 = this;
-
-    var index = contextParams.index;
-    this.contextCheckers.forEach(function (contextChecker) {
-        var contextName = contextChecker.contextName;
-        var openRange = this$1.getContext(contextName).openRange;
-        if (!openRange && contextChecker.checkStart(contextParams)) {
-            openRange = new ContextRange(index, null, contextName);
-            this$1.getContext(contextName).openRange = openRange;
-            this$1.dispatch('contextStart', [contextName, index]);
-        }
-        if (!!openRange && contextChecker.checkEnd(contextParams)) {
-            var offset = (index - openRange.startIndex) + 1;
-            var range = this$1.setEndOffset(offset, contextName);
-            this$1.dispatch('contextEnd', [contextName, range]);
-        }
-    });
-};
-
-/**
- * Converts a text into a list of tokens
- * @param {string} text a text to tokenize
- */
-Tokenizer.prototype.tokenize = function (text) {
-    this.tokens = [];
-    this.resetContextsRanges();
-    var chars = Array.from(text);
-    this.dispatch('start');
-    for (var i = 0; i < chars.length; i++) {
-        var char = chars[i];
-        var contextParams = new ContextParams(chars, i);
-        this.dispatch('next', [contextParams]);
-        this.runContextCheck(contextParams);
-        var token = new Token(char);
-        this.tokens.push(token);
-        this.dispatch('newToken', [token, contextParams]);
-    }
-    this.dispatch('end', [this.tokens]);
-    return this.tokens;
-};
-
-// ╭─┄┄┄────────────────────────┄─────────────────────────────────────────────╮
-// ┊ Character Class Assertions ┊ Checks if a char belongs to a certain class ┊
-// ╰─╾──────────────────────────┄─────────────────────────────────────────────╯
-// jscs:disable maximumLineLength
-/**
- * Check if a char is Arabic
- * @param {string} c a single char
- */
-function isArabicChar(c) {
-    return /[\u0600-\u065F\u066A-\u06D2\u06FA-\u06FF]/.test(c);
-}
-
-/**
- * Check if a char is an isolated arabic char
- * @param {string} c a single char
- */
-function isIsolatedArabicChar(char) {
-    return /[\u0630\u0690\u0621\u0631\u0661\u0671\u0622\u0632\u0672\u0692\u06C2\u0623\u0673\u0693\u06C3\u0624\u0694\u06C4\u0625\u0675\u0695\u06C5\u06E5\u0676\u0696\u06C6\u0627\u0677\u0697\u06C7\u0648\u0688\u0698\u06C8\u0689\u0699\u06C9\u068A\u06CA\u066B\u068B\u06CB\u068C\u068D\u06CD\u06FD\u068E\u06EE\u06FE\u062F\u068F\u06CF\u06EF]/.test(char);
-}
-
-/**
- * Check if a char is an Arabic Tashkeel char
- * @param {string} c a single char
- */
-function isTashkeelArabicChar(char) {
-    return /[\u0600-\u0605\u060C-\u060E\u0610-\u061B\u061E\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED]/.test(char);
-}
-
-/**
- * Check if a char is Latin
- * @param {string} c a single char
- */
-function isLatinChar(c) {
-    return /[A-z]/.test(c);
-}
-
-/**
- * Check if a char is whitespace char
- * @param {string} c a single char
- */
-function isWhiteSpace(c) {
-    return /\s/.test(c);
-}
-
-/**
- * Query a feature by some of it's properties to lookup a glyph substitution.
- */
-
-/**
- * Create feature query instance
- * @param {Font} font opentype font instance
- */
-function FeatureQuery(font) {
-    this.font = font;
-    this.features = {};
-}
-
-/**
- * @typedef SubstitutionAction
- * @type Object
- * @property {number} id substitution type
- * @property {string} tag feature tag
- * @property {any} substitution substitution value(s)
- */
-
-/**
- * Create a substitution action instance
- * @param {SubstitutionAction} action
- */
-function SubstitutionAction(action) {
-    this.id = action.id;
-    this.tag = action.tag;
-    this.substitution = action.substitution;
-}
-
-/**
- * Lookup a coverage table
- * @param {number} glyphIndex glyph index
- * @param {CoverageTable} coverage coverage table
- */
-function lookupCoverage(glyphIndex, coverage) {
-    if (!glyphIndex) { return -1; }
-    switch (coverage.format) {
-        case 1:
-            return coverage.glyphs.indexOf(glyphIndex);
-
-        case 2:
-            var ranges = coverage.ranges;
-            for (var i = 0; i < ranges.length; i++) {
-                var range = ranges[i];
-                if (glyphIndex >= range.start && glyphIndex <= range.end) {
-                    var offset = glyphIndex - range.start;
-                    return range.index + offset;
-                }
-            }
-            break;
-        default:
-            return -1; // not found
-    }
-    return -1;
-}
-
-/**
- * Handle a single substitution - format 1
- * @param {ContextParams} contextParams context params to lookup
- */
-function singleSubstitutionFormat1(glyphIndex, subtable) {
-    var substituteIndex = lookupCoverage(glyphIndex, subtable.coverage);
-    if (substituteIndex === -1) { return null; }
-    return glyphIndex + subtable.deltaGlyphId;
-}
-
-/**
- * Handle a single substitution - format 2
- * @param {ContextParams} contextParams context params to lookup
- */
-function singleSubstitutionFormat2(glyphIndex, subtable) {
-    var substituteIndex = lookupCoverage(glyphIndex, subtable.coverage);
-    if (substituteIndex === -1) { return null; }
-    return subtable.substitute[substituteIndex];
-}
-
-/**
- * Lookup a list of coverage tables
- * @param {any} coverageList a list of coverage tables
- * @param {ContextParams} contextParams context params to lookup
- */
-function lookupCoverageList(coverageList, contextParams) {
-    var lookupList = [];
-    for (var i = 0; i < coverageList.length; i++) {
-        var coverage = coverageList[i];
-        var glyphIndex = contextParams.current;
-        glyphIndex = Array.isArray(glyphIndex) ? glyphIndex[0] : glyphIndex;
-        var lookupIndex = lookupCoverage(glyphIndex, coverage);
-        if (lookupIndex !== -1) {
-            lookupList.push(lookupIndex);
-        }
-    }
-    if (lookupList.length !== coverageList.length) { return -1; }
-    return lookupList;
-}
-
-/**
- * Handle chaining context substitution - format 3
- * @param {ContextParams} contextParams context params to lookup
- */
-function chainingSubstitutionFormat3(contextParams, subtable) {
-    var lookupsCount = (
-        subtable.inputCoverage.length +
-        subtable.lookaheadCoverage.length +
-        subtable.backtrackCoverage.length
-    );
-    if (contextParams.context.length < lookupsCount) { return []; }
-    // INPUT LOOKUP //
-    var inputLookups = lookupCoverageList(
-        subtable.inputCoverage, contextParams
-    );
-    if (inputLookups === -1) { return []; }
-    // LOOKAHEAD LOOKUP //
-    var lookaheadOffset = subtable.inputCoverage.length - 1;
-    if (contextParams.lookahead.length < subtable.lookaheadCoverage.length) { return []; }
-    var lookaheadContext = contextParams.lookahead.slice(lookaheadOffset);
-    while (lookaheadContext.length && isTashkeelArabicChar(lookaheadContext[0].char)) {
-        lookaheadContext.shift();
-    }
-    var lookaheadParams = new ContextParams(lookaheadContext, 0);
-    var lookaheadLookups = lookupCoverageList(
-        subtable.lookaheadCoverage, lookaheadParams
-    );
-    // BACKTRACK LOOKUP //
-    var backtrackContext = [].concat(contextParams.backtrack);
-    backtrackContext.reverse();
-    while (backtrackContext.length && isTashkeelArabicChar(backtrackContext[0].char)) {
-        backtrackContext.shift();
-    }
-    if (backtrackContext.length < subtable.backtrackCoverage.length) { return []; }
-    var backtrackParams = new ContextParams(backtrackContext, 0);
-    var backtrackLookups = lookupCoverageList(
-        subtable.backtrackCoverage, backtrackParams
-    );
-    var contextRulesMatch = (
-        inputLookups.length === subtable.inputCoverage.length &&
-        lookaheadLookups.length === subtable.lookaheadCoverage.length &&
-        backtrackLookups.length === subtable.backtrackCoverage.length
-    );
-    var substitutions = [];
-    if (contextRulesMatch) {
-        for (var i = 0; i < subtable.lookupRecords.length; i++) {
-            var lookupRecord = subtable.lookupRecords[i];
-            var lookupListIndex = lookupRecord.lookupListIndex;
-            var lookupTable = this.getLookupByIndex(lookupListIndex);
-            for (var s = 0; s < lookupTable.subtables.length; s++) {
-                var subtable$1 = lookupTable.subtables[s];
-                var lookup = this.getLookupMethod(lookupTable, subtable$1);
-                var substitutionType = this.getSubstitutionType(lookupTable, subtable$1);
-                if (substitutionType === '12') {
-                    for (var n = 0; n < inputLookups.length; n++) {
-                        var glyphIndex = contextParams.get(n);
-                        var substitution = lookup(glyphIndex);
-                        if (substitution) { substitutions.push(substitution); }
-                    }
-                }
-            }
-        }
-    }
-    return substitutions;
-}
-
-/**
- * Handle ligature substitution - format 1
- * @param {ContextParams} contextParams context params to lookup
- */
-function ligatureSubstitutionFormat1(contextParams, subtable) {
-    // COVERAGE LOOKUP //
-    var glyphIndex = contextParams.current;
-    var ligSetIndex = lookupCoverage(glyphIndex, subtable.coverage);
-    if (ligSetIndex === -1) { return null; }
-    // COMPONENTS LOOKUP
-    // (!) note, components are ordered in the written direction.
-    var ligature;
-    var ligatureSet = subtable.ligatureSets[ligSetIndex];
-    for (var s = 0; s < ligatureSet.length; s++) {
-        ligature = ligatureSet[s];
-        for (var l = 0; l < ligature.components.length; l++) {
-            var lookaheadItem = contextParams.lookahead[l];
-            var component = ligature.components[l];
-            if (lookaheadItem !== component) { break; }
-            if (l === ligature.components.length - 1) { return ligature; }
-        }
-    }
-    return null;
-}
-
-/**
- * Handle decomposition substitution - format 1
- * @param {number} glyphIndex glyph index
- * @param {any} subtable subtable
- */
-function decompositionSubstitutionFormat1(glyphIndex, subtable) {
-    var substituteIndex = lookupCoverage(glyphIndex, subtable.coverage);
-    if (substituteIndex === -1) { return null; }
-    return subtable.sequences[substituteIndex];
-}
-
-/**
- * Get default script features indexes
- */
-FeatureQuery.prototype.getDefaultScriptFeaturesIndexes = function () {
-    var scripts = this.font.tables.gsub.scripts;
-    for (var s = 0; s < scripts.length; s++) {
-        var script = scripts[s];
-        if (script.tag === 'DFLT') { return (
-            script.script.defaultLangSys.featureIndexes
-        ); }
-    }
-    return [];
-};
-
-/**
- * Get feature indexes of a specific script
- * @param {string} scriptTag script tag
- */
-FeatureQuery.prototype.getScriptFeaturesIndexes = function(scriptTag) {
-    var tables = this.font.tables;
-    if (!tables.gsub) { return []; }
-    if (!scriptTag) { return this.getDefaultScriptFeaturesIndexes(); }
-    var scripts = this.font.tables.gsub.scripts;
-    for (var i = 0; i < scripts.length; i++) {
-        var script = scripts[i];
-        if (script.tag === scriptTag && script.script.defaultLangSys) {
-            return script.script.defaultLangSys.featureIndexes;
-        } else {
-            var langSysRecords = script.langSysRecords;
-            if (!!langSysRecords) {
-                for (var j = 0; j < langSysRecords.length; j++) {
-                    var langSysRecord = langSysRecords[j];
-                    if (langSysRecord.tag === scriptTag) {
-                        var langSys = langSysRecord.langSys;
-                        return langSys.featureIndexes;
-                    }
-                }
-            }
-        }
-    }
-    return this.getDefaultScriptFeaturesIndexes();
-};
-
-/**
- * Map a feature tag to a gsub feature
- * @param {any} features gsub features
- * @param {string} scriptTag script tag
- */
-FeatureQuery.prototype.mapTagsToFeatures = function (features, scriptTag) {
-    var tags = {};
-    for (var i = 0; i < features.length; i++) {
-        var tag = features[i].tag;
-        var feature = features[i].feature;
-        tags[tag] = feature;
-    }
-    this.features[scriptTag].tags = tags;
-};
-
-/**
- * Get features of a specific script
- * @param {string} scriptTag script tag
- */
-FeatureQuery.prototype.getScriptFeatures = function (scriptTag) {
-    var features = this.features[scriptTag];
-    if (this.features.hasOwnProperty(scriptTag)) { return features; }
-    var featuresIndexes = this.getScriptFeaturesIndexes(scriptTag);
-    if (!featuresIndexes) { return null; }
-    var gsub = this.font.tables.gsub;
-    features = featuresIndexes.map(function (index) { return gsub.features[index]; });
-    this.features[scriptTag] = features;
-    this.mapTagsToFeatures(features, scriptTag);
-    return features;
-};
-
-/**
- * Get substitution type
- * @param {any} lookupTable lookup table
- * @param {any} subtable subtable
- */
-FeatureQuery.prototype.getSubstitutionType = function(lookupTable, subtable) {
-    var lookupType = lookupTable.lookupType.toString();
-    var substFormat = subtable.substFormat.toString();
-    return lookupType + substFormat;
-};
-
-/**
- * Get lookup method
- * @param {any} lookupTable lookup table
- * @param {any} subtable subtable
- */
-FeatureQuery.prototype.getLookupMethod = function(lookupTable, subtable) {
-    var this$1 = this;
-
-    var substitutionType = this.getSubstitutionType(lookupTable, subtable);
-    switch (substitutionType) {
-        case '11':
-            return function (glyphIndex) { return singleSubstitutionFormat1.apply(
-                this$1, [glyphIndex, subtable]
-            ); };
-        case '12':
-            return function (glyphIndex) { return singleSubstitutionFormat2.apply(
-                this$1, [glyphIndex, subtable]
-            ); };
-        case '63':
-            return function (contextParams) { return chainingSubstitutionFormat3.apply(
-                this$1, [contextParams, subtable]
-            ); };
-        case '41':
-            return function (contextParams) { return ligatureSubstitutionFormat1.apply(
-                this$1, [contextParams, subtable]
-            ); };
-        case '21':
-            return function (glyphIndex) { return decompositionSubstitutionFormat1.apply(
-                this$1, [glyphIndex, subtable]
-            ); };
-        default:
-            throw new Error(
-                "lookupType: " + (lookupTable.lookupType) + " - " +
-                "substFormat: " + (subtable.substFormat) + " " +
-                "is not yet supported"
-            );
-    }
-};
-
-/**
- * [ LOOKUP TYPES ]
- * -------------------------------
- * Single                        1;
- * Multiple                      2;
- * Alternate                     3;
- * Ligature                      4;
- * Context                       5;
- * ChainingContext               6;
- * ExtensionSubstitution         7;
- * ReverseChainingContext        8;
- * -------------------------------
- *
- */
-
-/**
- * @typedef FQuery
- * @type Object
- * @param {string} tag feature tag
- * @param {string} script feature script
- * @param {ContextParams} contextParams context params
- */
-
-/**
- * Lookup a feature using a query parameters
- * @param {FQuery} query feature query
- */
-FeatureQuery.prototype.lookupFeature = function (query) {
-    var contextParams = query.contextParams;
-    var currentIndex = contextParams.index;
-    var feature = this.getFeature({
-        tag: query.tag, script: query.script
-    });
-    if (!feature) { return new Error(
-        "font '" + (this.font.names.fullName.en) + "' " +
-        "doesn't support feature '" + (query.tag) + "' " +
-        "for script '" + (query.script) + "'."
-    ); }
-    var lookups = this.getFeatureLookups(feature);
-    var substitutions = [].concat(contextParams.context);
-    for (var l = 0; l < lookups.length; l++) {
-        var lookupTable = lookups[l];
-        var subtables = this.getLookupSubtables(lookupTable);
-        for (var s = 0; s < subtables.length; s++) {
-            var subtable = subtables[s];
-            var substType = this.getSubstitutionType(lookupTable, subtable);
-            var lookup = this.getLookupMethod(lookupTable, subtable);
-            var substitution = (void 0);
-            switch (substType) {
-                case '11':
-                    substitution = lookup(contextParams.current);
-                    if (substitution) {
-                        substitutions.splice(currentIndex, 1, new SubstitutionAction({
-                            id: 11, tag: query.tag, substitution: substitution
-                        }));
-                    }
-                    break;
-                case '12':
-                    substitution = lookup(contextParams.current);
-                    if (substitution) {
-                        substitutions.splice(currentIndex, 1, new SubstitutionAction({
-                            id: 12, tag: query.tag, substitution: substitution
-                        }));
-                    }
-                    break;
-                case '63':
-                    substitution = lookup(contextParams);
-                    if (Array.isArray(substitution) && substitution.length) {
-                        substitutions.splice(currentIndex, 1, new SubstitutionAction({
-                            id: 63, tag: query.tag, substitution: substitution
-                        }));
-                    }
-                    break;
-                case '41':
-                    substitution = lookup(contextParams);
-                    if (substitution) {
-                        substitutions.splice(currentIndex, 1, new SubstitutionAction({
-                            id: 41, tag: query.tag, substitution: substitution
-                        }));
-                    }
-                    break;
-                case '21':
-                    substitution = lookup(contextParams.current);
-                    if (substitution) {
-                        substitutions.splice(currentIndex, 1, new SubstitutionAction({
-                            id: 21, tag: query.tag, substitution: substitution
-                        }));
-                    }
-                    break;
-            }
-            contextParams = new ContextParams(substitutions, currentIndex);
-            if (Array.isArray(substitution) && !substitution.length) { continue; }
-            substitution = null;
-        }
-    }
-    return substitutions.length ? substitutions : null;
-};
-
-/**
- * Checks if a font supports a specific features
- * @param {FQuery} query feature query object
- */
-FeatureQuery.prototype.supports = function (query) {
-    if (!query.script) { return false; }
-    this.getScriptFeatures(query.script);
-    var supportedScript = this.features.hasOwnProperty(query.script);
-    if (!query.tag) { return supportedScript; }
-    var supportedFeature = (
-        this.features[query.script].some(function (feature) { return feature.tag === query.tag; })
-    );
-    return supportedScript && supportedFeature;
-};
-
-/**
- * Get lookup table subtables
- * @param {any} lookupTable lookup table
- */
-FeatureQuery.prototype.getLookupSubtables = function (lookupTable) {
-    return lookupTable.subtables || null;
-};
-
-/**
- * Get lookup table by index
- * @param {number} index lookup table index
- */
-FeatureQuery.prototype.getLookupByIndex = function (index) {
-    var lookups = this.font.tables.gsub.lookups;
-    return lookups[index] || null;
-};
-
-/**
- * Get lookup tables for a feature
- * @param {string} feature
- */
-FeatureQuery.prototype.getFeatureLookups = function (feature) {
-    // TODO: memoize
-    return feature.lookupListIndexes.map(this.getLookupByIndex.bind(this));
-};
-
-/**
- * Query a feature by it's properties
- * @param {any} query an object that describes the properties of a query
- */
-FeatureQuery.prototype.getFeature = function getFeature(query) {
-    if (!this.font) { return { FAIL: "No font was found"}; }
-    if (!this.features.hasOwnProperty(query.script)) {
-        this.getScriptFeatures(query.script);
-    }
-    var scriptFeatures = this.features[query.script];
-    if (!scriptFeatures) { return (
-        { FAIL: ("No feature for script " + (query.script))}
-    ); }
-    if (!scriptFeatures.tags[query.tag]) { return null; }
-    return this.features[query.script].tags[query.tag];
-};
-
-/**
- * Arabic word context checkers
- */
-
-function arabicWordStartCheck(contextParams) {
-    var char = contextParams.current;
-    var prevChar = contextParams.get(-1);
-    return (
-        // ? arabic first char
-        (prevChar === null && isArabicChar(char)) ||
-        // ? arabic char preceded with a non arabic char
-        (!isArabicChar(prevChar) && isArabicChar(char))
-    );
-}
-
-function arabicWordEndCheck(contextParams) {
-    var nextChar = contextParams.get(1);
-    return (
-        // ? last arabic char
-        (nextChar === null) ||
-        // ? next char is not arabic
-        (!isArabicChar(nextChar))
-    );
-}
-
-var arabicWordCheck = {
-    startCheck: arabicWordStartCheck,
-    endCheck: arabicWordEndCheck
-};
-
-/**
- * Arabic sentence context checkers
- */
-
-function arabicSentenceStartCheck(contextParams) {
-    var char = contextParams.current;
-    var prevChar = contextParams.get(-1);
-    return (
-        // ? an arabic char preceded with a non arabic char
-        (isArabicChar(char) || isTashkeelArabicChar(char)) &&
-        !isArabicChar(prevChar)
-    );
-}
-
-function arabicSentenceEndCheck(contextParams) {
-    var nextChar = contextParams.get(1);
-    switch (true) {
-        case nextChar === null:
-            return true;
-        case (!isArabicChar(nextChar) && !isTashkeelArabicChar(nextChar)):
-            var nextIsWhitespace = isWhiteSpace(nextChar);
-            if (!nextIsWhitespace) { return true; }
-            if (nextIsWhitespace) {
-                var arabicCharAhead = false;
-                arabicCharAhead = (
-                    contextParams.lookahead.some(
-                        function (c) { return isArabicChar(c) || isTashkeelArabicChar(c); }
-                    )
-                );
-                if (!arabicCharAhead) { return true; }
-            }
-            break;
-        default:
-            return false;
-    }
-}
-
-var arabicSentenceCheck = {
-    startCheck: arabicSentenceStartCheck,
-    endCheck: arabicSentenceEndCheck
-};
-
-/**
- * Apply single substitution format 1
- * @param {Array} substitutions substitutions
- * @param {any} tokens a list of tokens
- * @param {number} index token index
- */
-function singleSubstitutionFormat1$1(action, tokens, index) {
-    tokens[index].setState(action.tag, action.substitution);
-}
-
-/**
- * Apply single substitution format 2
- * @param {Array} substitutions substitutions
- * @param {any} tokens a list of tokens
- * @param {number} index token index
- */
-function singleSubstitutionFormat2$1(action, tokens, index) {
-    tokens[index].setState(action.tag, action.substitution);
-}
-
-/**
- * Apply chaining context substitution format 3
- * @param {Array} substitutions substitutions
- * @param {any} tokens a list of tokens
- * @param {number} index token index
- */
-function chainingSubstitutionFormat3$1(action, tokens, index) {
-    action.substitution.forEach(function (subst, offset) {
-        var token = tokens[index + offset];
-        token.setState(action.tag, subst);
-    });
-}
-
-/**
- * Apply ligature substitution format 1
- * @param {Array} substitutions substitutions
- * @param {any} tokens a list of tokens
- * @param {number} index token index
- */
-function ligatureSubstitutionFormat1$1(action, tokens, index) {
-    var token = tokens[index];
-    token.setState(action.tag, action.substitution.ligGlyph);
-    var compsCount = action.substitution.components.length;
-    for (var i = 0; i < compsCount; i++) {
-        token = tokens[index + i + 1];
-        token.setState('deleted', true);
-    }
-}
-
-/**
- * Supported substitutions
- */
-var SUBSTITUTIONS = {
-    11: singleSubstitutionFormat1$1,
-    12: singleSubstitutionFormat2$1,
-    63: chainingSubstitutionFormat3$1,
-    41: ligatureSubstitutionFormat1$1
-};
-
-/**
- * Apply substitutions to a list of tokens
- * @param {Array} substitutions substitutions
- * @param {any} tokens a list of tokens
- * @param {number} index token index
- */
-function applySubstitution(action, tokens, index) {
-    if (action instanceof SubstitutionAction && SUBSTITUTIONS[action.id]) {
-        SUBSTITUTIONS[action.id](action, tokens, index);
-    }
-}
-
-/**
- * Apply Arabic presentation forms to a range of tokens
- */
-
-/**
- * Check if a char can be connected to it's preceding char
- * @param {ContextParams} charContextParams context params of a char
- */
-function willConnectPrev(charContextParams) {
-    var backtrack = [].concat(charContextParams.backtrack);
-    for (var i = backtrack.length - 1; i >= 0; i--) {
-        var prevChar = backtrack[i];
-        var isolated = isIsolatedArabicChar(prevChar);
-        var tashkeel = isTashkeelArabicChar(prevChar);
-        if (!isolated && !tashkeel) { return true; }
-        if (isolated) { return false; }
-    }
-    return false;
-}
-
-/**
- * Check if a char can be connected to it's proceeding char
- * @param {ContextParams} charContextParams context params of a char
- */
-function willConnectNext(charContextParams) {
-    if (isIsolatedArabicChar(charContextParams.current)) { return false; }
-    for (var i = 0; i < charContextParams.lookahead.length; i++) {
-        var nextChar = charContextParams.lookahead[i];
-        var tashkeel = isTashkeelArabicChar(nextChar);
-        if (!tashkeel) { return true; }
-    }
-    return false;
-}
-
-/**
- * Apply arabic presentation forms to a list of tokens
- * @param {ContextRange} range a range of tokens
- */
-function arabicPresentationForms(range) {
-    var this$1 = this;
-
-    var script = 'arab';
-    var tags = this.featuresTags[script];
-    var tokens = this.tokenizer.getRangeTokens(range);
-    if (tokens.length === 1) { return; }
-    var contextParams = new ContextParams(
-        tokens.map(function (token) { return token.getState('glyphIndex'); }
-    ), 0);
-    var charContextParams = new ContextParams(
-        tokens.map(function (token) { return token.char; }
-    ), 0);
-    tokens.forEach(function (token, index) {
-        if (isTashkeelArabicChar(token.char)) { return; }
-        contextParams.setCurrentIndex(index);
-        charContextParams.setCurrentIndex(index);
-        var CONNECT = 0; // 2 bits 00 (10: can connect next) (01: can connect prev)
-        if (willConnectPrev(charContextParams)) { CONNECT |= 1; }
-        if (willConnectNext(charContextParams)) { CONNECT |= 2; }
-        var tag;
-        switch (CONNECT) {
-            case 1: (tag = 'fina'); break;
-            case 2: (tag = 'init'); break;
-            case 3: (tag = 'medi'); break;
-        }
-        if (tags.indexOf(tag) === -1) { return; }
-        var substitutions = this$1.query.lookupFeature({
-            tag: tag, script: script, contextParams: contextParams
-        });
-        if (substitutions instanceof Error) { return console.info(substitutions.message); }
-        substitutions.forEach(function (action, index) {
-            if (action instanceof SubstitutionAction) {
-                applySubstitution(action, tokens, index);
-                contextParams.context[index] = action.substitution;
-            }
-        });
-    });
-}
-
-/**
- * Apply Arabic required ligatures feature to a range of tokens
- */
-
-/**
- * Update context params
- * @param {any} tokens a list of tokens
- * @param {number} index current item index
- */
-function getContextParams(tokens, index) {
-    var context = tokens.map(function (token) { return token.activeState.value; });
-    return new ContextParams(context, index || 0);
-}
-
-/**
- * Apply Arabic required ligatures to a context range
- * @param {ContextRange} range a range of tokens
- */
-function arabicRequiredLigatures(range) {
-    var this$1 = this;
-
-    var script = 'arab';
-    var tokens = this.tokenizer.getRangeTokens(range);
-    var contextParams = getContextParams(tokens);
-    contextParams.context.forEach(function (glyphIndex, index) {
-        contextParams.setCurrentIndex(index);
-        var substitutions = this$1.query.lookupFeature({
-            tag: 'rlig', script: script, contextParams: contextParams
-        });
-        if (substitutions.length) {
-            substitutions.forEach(
-                function (action) { return applySubstitution(action, tokens, index); }
-            );
-            contextParams = getContextParams(tokens);
-        }
-    });
-}
-
-/**
- * Latin word context checkers
- */
-
-function latinWordStartCheck(contextParams) {
-    var char = contextParams.current;
-    var prevChar = contextParams.get(-1);
-    return (
-        // ? latin first char
-        (prevChar === null && isLatinChar(char)) ||
-        // ? latin char preceded with a non latin char
-        (!isLatinChar(prevChar) && isLatinChar(char))
-    );
-}
-
-function latinWordEndCheck(contextParams) {
-    var nextChar = contextParams.get(1);
-    return (
-        // ? last latin char
-        (nextChar === null) ||
-        // ? next char is not latin
-        (!isLatinChar(nextChar))
-    );
-}
-
-var latinWordCheck = {
-    startCheck: latinWordStartCheck,
-    endCheck: latinWordEndCheck
-};
-
-/**
- * Apply Latin ligature feature to a range of tokens
- */
-
-/**
- * Update context params
- * @param {any} tokens a list of tokens
- * @param {number} index current item index
- */
-function getContextParams$1(tokens, index) {
-    var context = tokens.map(function (token) { return token.activeState.value; });
-    return new ContextParams(context, index || 0);
-}
-
-/**
- * Apply Arabic required ligatures to a context range
- * @param {ContextRange} range a range of tokens
- */
-function latinLigature(range) {
-    var this$1 = this;
-
-    var script = 'latn';
-    var tokens = this.tokenizer.getRangeTokens(range);
-    var contextParams = getContextParams$1(tokens);
-    contextParams.context.forEach(function (glyphIndex, index) {
-        contextParams.setCurrentIndex(index);
-        var substitutions = this$1.query.lookupFeature({
-            tag: 'liga', script: script, contextParams: contextParams
-        });
-        if (substitutions.length) {
-            substitutions.forEach(
-                function (action) { return applySubstitution(action, tokens, index); }
-            );
-            contextParams = getContextParams$1(tokens);
-        }
-    });
-}
-
-/**
- * Infer bidirectional properties for a given text and apply
- * the corresponding layout rules.
- */
-
-/**
- * Create Bidi. features
- * @param {string} baseDir text base direction. value either 'ltr' or 'rtl'
- */
-function Bidi(baseDir) {
-    this.baseDir = baseDir || 'ltr';
-    this.tokenizer = new Tokenizer();
-    this.featuresTags = {};
-}
-
-/**
- * Sets Bidi text
- * @param {string} text a text input
- */
-Bidi.prototype.setText = function (text) {
-    this.text = text;
-};
-
-/**
- * Store essential context checks:
- * arabic word check for applying gsub features
- * arabic sentence check for adjusting arabic layout
- */
-Bidi.prototype.contextChecks = ({
-    latinWordCheck: latinWordCheck,
-    arabicWordCheck: arabicWordCheck,
-    arabicSentenceCheck: arabicSentenceCheck
-});
-
-/**
- * Register arabic word check
- */
-function registerContextChecker(checkId) {
-    var check = this.contextChecks[(checkId + "Check")];
-    return this.tokenizer.registerContextChecker(
-        checkId, check.startCheck, check.endCheck
-    );
-}
-
-/**
- * Perform pre tokenization procedure then
- * tokenize text input
- */
-function tokenizeText() {
-    registerContextChecker.call(this, 'latinWord');
-    registerContextChecker.call(this, 'arabicWord');
-    registerContextChecker.call(this, 'arabicSentence');
-    return this.tokenizer.tokenize(this.text);
-}
-
-/**
- * Reverse arabic sentence layout
- * TODO: check base dir before applying adjustments - priority low
- */
-function reverseArabicSentences() {
-    var this$1 = this;
-
-    var ranges = this.tokenizer.getContextRanges('arabicSentence');
-    ranges.forEach(function (range) {
-        var rangeTokens = this$1.tokenizer.getRangeTokens(range);
-        this$1.tokenizer.replaceRange(
-            range.startIndex,
-            range.endOffset,
-            rangeTokens.reverse()
-        );
-    });
-}
-
-/**
- * Register supported features tags
- * @param {script} script script tag
- * @param {Array} tags features tags list
- */
-Bidi.prototype.registerFeatures = function (script, tags) {
-    var this$1 = this;
-
-    var supportedTags = tags.filter(
-        function (tag) { return this$1.query.supports({script: script, tag: tag}); }
-    );
-    if (!this.featuresTags.hasOwnProperty(script)) {
-        this.featuresTags[script] = supportedTags;
-    } else {
-        this.featuresTags[script] =
-        this.featuresTags[script].concat(supportedTags);
-    }
-};
-
-/**
- * Apply GSUB features
- * @param {Array} tagsList a list of features tags
- * @param {string} script a script tag
- * @param {Font} font opentype font instance
- */
-Bidi.prototype.applyFeatures = function (font, features) {
-    if (!font) { throw new Error(
-        'No valid font was provided to apply features'
-    ); }
-    if (!this.query) { this.query = new FeatureQuery(font); }
-    for (var f = 0; f < features.length; f++) {
-        var feature = features[f];
-        if (!this.query.supports({script: feature.script})) { continue; }
-        this.registerFeatures(feature.script, feature.tags);
-    }
-};
-
-/**
- * Register a state modifier
- * @param {string} modifierId state modifier id
- * @param {function} condition a predicate function that returns true or false
- * @param {function} modifier a modifier function to set token state
- */
-Bidi.prototype.registerModifier = function (modifierId, condition, modifier) {
-    this.tokenizer.registerModifier(modifierId, condition, modifier);
-};
-
-/**
- * Check if 'glyphIndex' is registered
- */
-function checkGlyphIndexStatus() {
-    if (this.tokenizer.registeredModifiers.indexOf('glyphIndex') === -1) {
-        throw new Error(
-            'glyphIndex modifier is required to apply ' +
-            'arabic presentation features.'
-        );
-    }
-}
-
-/**
- * Apply arabic presentation forms features
- */
-function applyArabicPresentationForms() {
-    var this$1 = this;
-
-    var script = 'arab';
-    if (!this.featuresTags.hasOwnProperty(script)) { return; }
-    checkGlyphIndexStatus.call(this);
-    var ranges = this.tokenizer.getContextRanges('arabicWord');
-    ranges.forEach(function (range) {
-        arabicPresentationForms.call(this$1, range);
-    });
-}
-
-/**
- * Apply required arabic ligatures
- */
-function applyArabicRequireLigatures() {
-    var this$1 = this;
-
-    var script = 'arab';
-    if (!this.featuresTags.hasOwnProperty(script)) { return; }
-    var tags = this.featuresTags[script];
-    if (tags.indexOf('rlig') === -1) { return; }
-    checkGlyphIndexStatus.call(this);
-    var ranges = this.tokenizer.getContextRanges('arabicWord');
-    ranges.forEach(function (range) {
-        arabicRequiredLigatures.call(this$1, range);
-    });
-}
-
-/**
- * Apply required arabic ligatures
- */
-function applyLatinLigatures() {
-    var this$1 = this;
-
-    var script = 'latn';
-    if (!this.featuresTags.hasOwnProperty(script)) { return; }
-    var tags = this.featuresTags[script];
-    if (tags.indexOf('liga') === -1) { return; }
-    checkGlyphIndexStatus.call(this);
-    var ranges = this.tokenizer.getContextRanges('latinWord');
-    ranges.forEach(function (range) {
-        latinLigature.call(this$1, range);
-    });
-}
-
-/**
- * Check if a context is registered
- * @param {string} contextId context id
- */
-Bidi.prototype.checkContextReady = function (contextId) {
-    return !!this.tokenizer.getContext(contextId);
-};
-
-/**
- * Apply features to registered contexts
- */
-Bidi.prototype.applyFeaturesToContexts = function () {
-    if (this.checkContextReady('arabicWord')) {
-        applyArabicPresentationForms.call(this);
-        applyArabicRequireLigatures.call(this);
-    }
-    if (this.checkContextReady('latinWord')) {
-        applyLatinLigatures.call(this);
-    }
-    if (this.checkContextReady('arabicSentence')) {
-        reverseArabicSentences.call(this);
-    }
-};
-
-/**
- * process text input
- * @param {string} text an input text
- */
-Bidi.prototype.processText = function(text) {
-    if (!this.text || this.text !== text) {
-        this.setText(text);
-        tokenizeText.call(this);
-        this.applyFeaturesToContexts();
-    }
-};
-
-/**
- * Process a string of text to identify and adjust
- * bidirectional text entities.
- * @param {string} text input text
- */
-Bidi.prototype.getBidiText = function (text) {
-    this.processText(text);
-    return this.tokenizer.getText();
-};
-
-/**
- * Get the current state index of each token
- * @param {text} text an input text
- */
-Bidi.prototype.getTextGlyphs = function (text) {
-    this.processText(text);
-    var indexes = [];
-    for (var i = 0; i < this.tokenizer.tokens.length; i++) {
-        var token = this.tokenizer.tokens[i];
-        if (token.state.deleted) { continue; }
-        var index = token.activeState.value;
-        indexes.push(Array.isArray(index) ? index[0] : index);
-    }
-    return indexes;
-};
-
-// The Font object
-
-/**
- * @typedef FontOptions
- * @type Object
- * @property {Boolean} empty - whether to create a new empty font
- * @property {string} familyName
- * @property {string} styleName
- * @property {string=} fullName
- * @property {string=} postScriptName
- * @property {string=} designer
- * @property {string=} designerURL
- * @property {string=} manufacturer
- * @property {string=} manufacturerURL
- * @property {string=} license
- * @property {string=} licenseURL
- * @property {string=} version
- * @property {string=} description
- * @property {string=} copyright
- * @property {string=} trademark
- * @property {Number} unitsPerEm
- * @property {Number} ascender
- * @property {Number} descender
- * @property {Number} createdTimestamp
- * @property {string=} weightClass
- * @property {string=} widthClass
- * @property {string=} fsSelection
- */
-
-/**
- * A Font represents a loaded OpenType font file.
- * It contains a set of glyphs and methods to draw text on a drawing context,
- * or to get a path representing the text.
- * @exports opentype.Font
- * @class
- * @param {FontOptions}
- * @constructor
- */
-function Font(options) {
-    options = options || {};
-    options.tables = options.tables || {};
-
-    if (!options.empty) {
-        // Check that we've provided the minimum set of names.
-        checkArgument(options.familyName, 'When creating a new Font object, familyName is required.');
-        checkArgument(options.styleName, 'When creating a new Font object, styleName is required.');
-        checkArgument(options.unitsPerEm, 'When creating a new Font object, unitsPerEm is required.');
-        checkArgument(options.ascender, 'When creating a new Font object, ascender is required.');
-        checkArgument(options.descender <= 0, 'When creating a new Font object, negative descender value is required.');
-
-        // OS X will complain if the names are empty, so we put a single space everywhere by default.
-        this.names = {
-            fontFamily: {en: options.familyName || ' '},
-            fontSubfamily: {en: options.styleName || ' '},
-            fullName: {en: options.fullName || options.familyName + ' ' + options.styleName},
-            // postScriptName may not contain any whitespace
-            postScriptName: {en: options.postScriptName || (options.familyName + options.styleName).replace(/\s/g, '')},
-            designer: {en: options.designer || ' '},
-            designerURL: {en: options.designerURL || ' '},
-            manufacturer: {en: options.manufacturer || ' '},
-            manufacturerURL: {en: options.manufacturerURL || ' '},
-            license: {en: options.license || ' '},
-            licenseURL: {en: options.licenseURL || ' '},
-            version: {en: options.version || 'Version 0.1'},
-            description: {en: options.description || ' '},
-            copyright: {en: options.copyright || ' '},
-            trademark: {en: options.trademark || ' '}
-        };
-        this.unitsPerEm = options.unitsPerEm || 1000;
-        this.ascender = options.ascender;
-        this.descender = options.descender;
-        this.createdTimestamp = options.createdTimestamp;
-        this.tables = Object.assign(options.tables, {
-            os2: Object.assign({
-                usWeightClass: options.weightClass || this.usWeightClasses.MEDIUM,
-                usWidthClass: options.widthClass || this.usWidthClasses.MEDIUM,
-                fsSelection: options.fsSelection || this.fsSelectionValues.REGULAR,
-            }, options.tables.os2)
-        });
-    }
-
-    this.supported = true; // Deprecated: parseBuffer will throw an error if font is not supported.
-    this.glyphs = new glyphset.GlyphSet(this, options.glyphs || []);
-    this.encoding = new DefaultEncoding(this);
-    this.position = new Position(this);
-    this.substitution = new Substitution(this);
-    this.tables = this.tables || {};
-
-    // needed for low memory mode only.
-    this._push = null;
-    this._hmtxTableData = {};
-
-    Object.defineProperty(this, 'hinting', {
-        get: function() {
-            if (this._hinting) { return this._hinting; }
-            if (this.outlinesFormat === 'truetype') {
-                return (this._hinting = new Hinting(this));
-            }
-        }
-    });
-}
-
-/**
- * Check if the font has a glyph for the given character.
- * @param  {string}
- * @return {Boolean}
- */
-Font.prototype.hasChar = function(c) {
-    return this.encoding.charToGlyphIndex(c) !== null;
-};
-
-/**
- * Convert the given character to a single glyph index.
- * Note that this function assumes that there is a one-to-one mapping between
- * the given character and a glyph; for complex scripts this might not be the case.
- * @param  {string}
- * @return {Number}
- */
-Font.prototype.charToGlyphIndex = function(s) {
-    return this.encoding.charToGlyphIndex(s);
-};
-
-/**
- * Convert the given character to a single Glyph object.
- * Note that this function assumes that there is a one-to-one mapping between
- * the given character and a glyph; for complex scripts this might not be the case.
- * @param  {string}
- * @return {opentype.Glyph}
- */
-Font.prototype.charToGlyph = function(c) {
-    var glyphIndex = this.charToGlyphIndex(c);
-    var glyph = this.glyphs.get(glyphIndex);
-    if (!glyph) {
-        // .notdef
-        glyph = this.glyphs.get(0);
-    }
-
-    return glyph;
-};
-
-/**
- * Update features
- * @param {any} options features options
- */
-Font.prototype.updateFeatures = function (options) {
-    // TODO: update all features options not only 'latn'.
-    return this.defaultRenderOptions.features.map(function (feature) {
-        if (feature.script === 'latn') {
-            return {
-                script: 'latn',
-                tags: feature.tags.filter(function (tag) { return options[tag]; })
-            };
-        } else {
-            return feature;
-        }
-    });
-};
-
-/**
- * Convert the given text to a list of Glyph objects.
- * Note that there is no strict one-to-one mapping between characters and
- * glyphs, so the list of returned glyphs can be larger or smaller than the
- * length of the given string.
- * @param  {string}
- * @param  {GlyphRenderOptions} [options]
- * @return {opentype.Glyph[]}
- */
-Font.prototype.stringToGlyphs = function(s, options) {
-    var this$1 = this;
-
-
-    var bidi = new Bidi();
-
-    // Create and register 'glyphIndex' state modifier
-    var charToGlyphIndexMod = function (token) { return this$1.charToGlyphIndex(token.char); };
-    bidi.registerModifier('glyphIndex', null, charToGlyphIndexMod);
-
-    // roll-back to default features
-    var features = options ?
-    this.updateFeatures(options.features) :
-    this.defaultRenderOptions.features;
-
-    bidi.applyFeatures(this, features);
-
-    var indexes = bidi.getTextGlyphs(s);
-
-    var length = indexes.length;
-
-    // convert glyph indexes to glyph objects
-    var glyphs = new Array(length);
-    var notdef = this.glyphs.get(0);
-    for (var i = 0; i < length; i += 1) {
-        glyphs[i] = this.glyphs.get(indexes[i]) || notdef;
-    }
-    return glyphs;
-};
-
-/**
- * @param  {string}
- * @return {Number}
- */
-Font.prototype.nameToGlyphIndex = function(name) {
-    return this.glyphNames.nameToGlyphIndex(name);
-};
-
-/**
- * @param  {string}
- * @return {opentype.Glyph}
- */
-Font.prototype.nameToGlyph = function(name) {
-    var glyphIndex = this.nameToGlyphIndex(name);
-    var glyph = this.glyphs.get(glyphIndex);
-    if (!glyph) {
-        // .notdef
-        glyph = this.glyphs.get(0);
-    }
-
-    return glyph;
-};
-
-/**
- * @param  {Number}
- * @return {String}
- */
-Font.prototype.glyphIndexToName = function(gid) {
-    if (!this.glyphNames.glyphIndexToName) {
-        return '';
-    }
-
-    return this.glyphNames.glyphIndexToName(gid);
-};
-
-/**
- * Retrieve the value of the kerning pair between the left glyph (or its index)
- * and the right glyph (or its index). If no kerning pair is found, return 0.
- * The kerning value gets added to the advance width when calculating the spacing
- * between glyphs.
- * For GPOS kerning, this method uses the default script and language, which covers
- * most use cases. To have greater control, use font.position.getKerningValue .
- * @param  {opentype.Glyph} leftGlyph
- * @param  {opentype.Glyph} rightGlyph
- * @return {Number}
- */
-Font.prototype.getKerningValue = function(leftGlyph, rightGlyph) {
-    leftGlyph = leftGlyph.index || leftGlyph;
-    rightGlyph = rightGlyph.index || rightGlyph;
-    var gposKerning = this.position.defaultKerningTables;
-    if (gposKerning) {
-        return this.position.getKerningValue(gposKerning, leftGlyph, rightGlyph);
-    }
-    // "kern" table
-    return this.kerningPairs[leftGlyph + ',' + rightGlyph] || 0;
-};
-
-/**
- * @typedef GlyphRenderOptions
- * @type Object
- * @property {string} [script] - script used to determine which features to apply. By default, 'DFLT' or 'latn' is used.
- *                               See https://www.microsoft.com/typography/otspec/scripttags.htm
- * @property {string} [language='dflt'] - language system used to determine which features to apply.
- *                                        See https://www.microsoft.com/typography/developers/opentype/languagetags.aspx
- * @property {boolean} [kerning=true] - whether to include kerning values
- * @property {object} [features] - OpenType Layout feature tags. Used to enable or disable the features of the given script/language system.
- *                                 See https://www.microsoft.com/typography/otspec/featuretags.htm
- */
-Font.prototype.defaultRenderOptions = {
-    kerning: true,
-    features: [
-        /**
-         * these 4 features are required to render Arabic text properly
-         * and shouldn't be turned off when rendering arabic text.
-         */
-        { script: 'arab', tags: ['init', 'medi', 'fina', 'rlig'] },
-        { script: 'latn', tags: ['liga', 'rlig'] }
-    ]
-};
-
-/**
- * Helper function that invokes the given callback for each glyph in the given text.
- * The callback gets `(glyph, x, y, fontSize, options)`.* @param  {string} text
- * @param {string} text - The text to apply.
- * @param  {number} [x=0] - Horizontal position of the beginning of the text.
- * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
- * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- * @param  {GlyphRenderOptions=} options
- * @param  {Function} callback
- */
-Font.prototype.forEachGlyph = function(text, x, y, fontSize, options, callback) {
-    x = x !== undefined ? x : 0;
-    y = y !== undefined ? y : 0;
-    fontSize = fontSize !== undefined ? fontSize : 72;
-    options = Object.assign({}, this.defaultRenderOptions, options);
-    var fontScale = 1 / this.unitsPerEm * fontSize;
-    var glyphs = this.stringToGlyphs(text, options);
-    var kerningLookups;
-    if (options.kerning) {
-        var script = options.script || this.position.getDefaultScriptName();
-        kerningLookups = this.position.getKerningTables(script, options.language);
-    }
-    for (var i = 0; i < glyphs.length; i += 1) {
-        var glyph = glyphs[i];
-        callback.call(this, glyph, x, y, fontSize, options);
-        if (glyph.advanceWidth) {
-            x += glyph.advanceWidth * fontScale;
-        }
-
-        if (options.kerning && i < glyphs.length - 1) {
-            // We should apply position adjustment lookups in a more generic way.
-            // Here we only use the xAdvance value.
-            var kerningValue = kerningLookups ?
-                  this.position.getKerningValue(kerningLookups, glyph.index, glyphs[i + 1].index) :
-                  this.getKerningValue(glyph, glyphs[i + 1]);
-            x += kerningValue * fontScale;
-        }
-
-        if (options.letterSpacing) {
-            x += options.letterSpacing * fontSize;
-        } else if (options.tracking) {
-            x += (options.tracking / 1000) * fontSize;
-        }
-    }
-    return x;
-};
-
-/**
- * Create a Path object that represents the given text.
- * @param  {string} text - The text to create.
- * @param  {number} [x=0] - Horizontal position of the beginning of the text.
- * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
- * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- * @param  {GlyphRenderOptions=} options
- * @return {opentype.Path}
- */
-Font.prototype.getPath = function(text, x, y, fontSize, options) {
-    var fullPath = new Path();
-    this.forEachGlyph(text, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
-        var glyphPath = glyph.getPath(gX, gY, gFontSize, options, this);
-        fullPath.extend(glyphPath);
-    });
-    return fullPath;
-};
-
-/**
- * Create an array of Path objects that represent the glyphs of a given text.
- * @param  {string} text - The text to create.
- * @param  {number} [x=0] - Horizontal position of the beginning of the text.
- * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
- * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- * @param  {GlyphRenderOptions=} options
- * @return {opentype.Path[]}
- */
-Font.prototype.getPaths = function(text, x, y, fontSize, options) {
-    var glyphPaths = [];
-    this.forEachGlyph(text, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
-        var glyphPath = glyph.getPath(gX, gY, gFontSize, options, this);
-        glyphPaths.push(glyphPath);
-    });
-
-    return glyphPaths;
-};
-
-/**
- * Returns the advance width of a text.
- *
- * This is something different than Path.getBoundingBox() as for example a
- * suffixed whitespace increases the advanceWidth but not the bounding box
- * or an overhanging letter like a calligraphic 'f' might have a quite larger
- * bounding box than its advance width.
- *
- * This corresponds to canvas2dContext.measureText(text).width
- *
- * @param  {string} text - The text to create.
- * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- * @param  {GlyphRenderOptions=} options
- * @return advance width
- */
-Font.prototype.getAdvanceWidth = function(text, fontSize, options) {
-    return this.forEachGlyph(text, 0, 0, fontSize, options, function() {});
-};
-
-/**
- * Draw the text on the given drawing context.
- * @param  {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
- * @param  {string} text - The text to create.
- * @param  {number} [x=0] - Horizontal position of the beginning of the text.
- * @param  {number} [y=0] - Vertical position of the *baseline* of the text.
- * @param  {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- * @param  {GlyphRenderOptions=} options
- */
-Font.prototype.draw = function(ctx, text, x, y, fontSize, options) {
-    this.getPath(text, x, y, fontSize, options).draw(ctx);
-};
-
-/**
- * Draw the points of all glyphs in the text.
- * On-curve points will be drawn in blue, off-curve points will be drawn in red.
- * @param {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
- * @param {string} text - The text to create.
- * @param {number} [x=0] - Horizontal position of the beginning of the text.
- * @param {number} [y=0] - Vertical position of the *baseline* of the text.
- * @param {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- * @param {GlyphRenderOptions=} options
- */
-Font.prototype.drawPoints = function(ctx, text, x, y, fontSize, options) {
-    this.forEachGlyph(text, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
-        glyph.drawPoints(ctx, gX, gY, gFontSize);
-    });
-};
-
-/**
- * Draw lines indicating important font measurements for all glyphs in the text.
- * Black lines indicate the origin of the coordinate system (point 0,0).
- * Blue lines indicate the glyph bounding box.
- * Green line indicates the advance width of the glyph.
- * @param {CanvasRenderingContext2D} ctx - A 2D drawing context, like Canvas.
- * @param {string} text - The text to create.
- * @param {number} [x=0] - Horizontal position of the beginning of the text.
- * @param {number} [y=0] - Vertical position of the *baseline* of the text.
- * @param {number} [fontSize=72] - Font size in pixels. We scale the glyph units by `1 / unitsPerEm * fontSize`.
- * @param {GlyphRenderOptions=} options
- */
-Font.prototype.drawMetrics = function(ctx, text, x, y, fontSize, options) {
-    this.forEachGlyph(text, x, y, fontSize, options, function(glyph, gX, gY, gFontSize) {
-        glyph.drawMetrics(ctx, gX, gY, gFontSize);
-    });
-};
-
-/**
- * @param  {string}
- * @return {string}
- */
-Font.prototype.getEnglishName = function(name) {
-    var translations = this.names[name];
-    if (translations) {
-        return translations.en;
-    }
-};
-
-/**
- * Validate
- */
-Font.prototype.validate = function() {
-    var _this = this;
-
-    function assert(predicate, message) {
-    }
-
-    function assertNamePresent(name) {
-        var englishName = _this.getEnglishName(name);
-        assert(englishName && englishName.trim().length > 0);
-    }
-
-    // Identification information
-    assertNamePresent('fontFamily');
-    assertNamePresent('weightName');
-    assertNamePresent('manufacturer');
-    assertNamePresent('copyright');
-    assertNamePresent('version');
-
-    // Dimension information
-    assert(this.unitsPerEm > 0);
-};
-
-/**
- * Convert the font object to a SFNT data structure.
- * This structure contains all the necessary tables and metadata to create a binary OTF file.
- * @return {opentype.Table}
- */
-Font.prototype.toTables = function() {
-    return sfnt.fontToTable(this);
-};
-/**
- * @deprecated Font.toBuffer is deprecated. Use Font.toArrayBuffer instead.
- */
-Font.prototype.toBuffer = function() {
-    console.warn('Font.toBuffer is deprecated. Use Font.toArrayBuffer instead.');
-    return this.toArrayBuffer();
-};
-/**
- * Converts a `opentype.Font` into an `ArrayBuffer`
- * @return {ArrayBuffer}
- */
-Font.prototype.toArrayBuffer = function() {
-    var sfntTable = this.toTables();
-    var bytes = sfntTable.encode();
-    var buffer = new ArrayBuffer(bytes.length);
-    var intArray = new Uint8Array(buffer);
-    for (var i = 0; i < bytes.length; i++) {
-        intArray[i] = bytes[i];
-    }
-
-    return buffer;
-};
-
-/**
- * Initiate a download of the OpenType font.
- */
-Font.prototype.download = function(fileName) {
-    var familyName = this.getEnglishName('fontFamily');
-    var styleName = this.getEnglishName('fontSubfamily');
-    fileName = fileName || familyName.replace(/\s/g, '') + '-' + styleName + '.otf';
-    var arrayBuffer = this.toArrayBuffer();
-
-    window.URL = window.URL || window.webkitURL;
-
-    if (window.URL) {
-        var dataView = new DataView(arrayBuffer);
-        var blob = new Blob([dataView], {type: 'font/opentype'});
-
-        var link = document.createElement('a');
-        link.href = window.URL.createObjectURL(blob);
-        link.download = fileName;
-
-        var event = document.createEvent('MouseEvents');
-        event.initEvent('click', true, false);
-        link.dispatchEvent(event);
-    } else {
-        console.warn('Font file could not be downloaded. Try using a different browser.');
-    }
-};
-/**
- * @private
- */
-Font.prototype.fsSelectionValues = {
-    ITALIC:              0x001, //1
-    UNDERSCORE:          0x002, //2
-    NEGATIVE:            0x004, //4
-    OUTLINED:            0x008, //8
-    STRIKEOUT:           0x010, //16
-    BOLD:                0x020, //32
-    REGULAR:             0x040, //64
-    USER_TYPO_METRICS:   0x080, //128
-    WWS:                 0x100, //256
-    OBLIQUE:             0x200  //512
-};
-
-/**
- * @private
- */
-Font.prototype.usWidthClasses = {
-    ULTRA_CONDENSED: 1,
-    EXTRA_CONDENSED: 2,
-    CONDENSED: 3,
-    SEMI_CONDENSED: 4,
-    MEDIUM: 5,
-    SEMI_EXPANDED: 6,
-    EXPANDED: 7,
-    EXTRA_EXPANDED: 8,
-    ULTRA_EXPANDED: 9
-};
-
-/**
- * @private
- */
-Font.prototype.usWeightClasses = {
-    THIN: 100,
-    EXTRA_LIGHT: 200,
-    LIGHT: 300,
-    NORMAL: 400,
-    MEDIUM: 500,
-    SEMI_BOLD: 600,
-    BOLD: 700,
-    EXTRA_BOLD: 800,
-    BLACK:    900
-};
-
-// The `fvar` table stores font variation axes and instances.
-
-function addName(name, names) {
-    var nameString = JSON.stringify(name);
-    var nameID = 256;
-    for (var nameKey in names) {
-        var n = parseInt(nameKey);
-        if (!n || n < 256) {
-            continue;
-        }
-
-        if (JSON.stringify(names[nameKey]) === nameString) {
-            return n;
-        }
-
-        if (nameID <= n) {
-            nameID = n + 1;
-        }
-    }
-
-    names[nameID] = name;
-    return nameID;
-}
-
-function makeFvarAxis(n, axis, names) {
-    var nameID = addName(axis.name, names);
-    return [
-        {name: 'tag_' + n, type: 'TAG', value: axis.tag},
-        {name: 'minValue_' + n, type: 'FIXED', value: axis.minValue << 16},
-        {name: 'defaultValue_' + n, type: 'FIXED', value: axis.defaultValue << 16},
-        {name: 'maxValue_' + n, type: 'FIXED', value: axis.maxValue << 16},
-        {name: 'flags_' + n, type: 'USHORT', value: 0},
-        {name: 'nameID_' + n, type: 'USHORT', value: nameID}
-    ];
-}
-
-function parseFvarAxis(data, start, names) {
-    var axis = {};
-    var p = new parse.Parser(data, start);
-    axis.tag = p.parseTag();
-    axis.minValue = p.parseFixed();
-    axis.defaultValue = p.parseFixed();
-    axis.maxValue = p.parseFixed();
-    p.skip('uShort', 1);  // reserved for flags; no values defined
-    axis.name = names[p.parseUShort()] || {};
-    return axis;
-}
-
-function makeFvarInstance(n, inst, axes, names) {
-    var nameID = addName(inst.name, names);
-    var fields = [
-        {name: 'nameID_' + n, type: 'USHORT', value: nameID},
-        {name: 'flags_' + n, type: 'USHORT', value: 0}
-    ];
-
-    for (var i = 0; i < axes.length; ++i) {
-        var axisTag = axes[i].tag;
-        fields.push({
-            name: 'axis_' + n + ' ' + axisTag,
-            type: 'FIXED',
-            value: inst.coordinates[axisTag] << 16
-        });
-    }
-
-    return fields;
-}
-
-function parseFvarInstance(data, start, axes, names) {
-    var inst = {};
-    var p = new parse.Parser(data, start);
-    inst.name = names[p.parseUShort()] || {};
-    p.skip('uShort', 1);  // reserved for flags; no values defined
-
-    inst.coordinates = {};
-    for (var i = 0; i < axes.length; ++i) {
-        inst.coordinates[axes[i].tag] = p.parseFixed();
-    }
-
-    return inst;
-}
-
-function makeFvarTable(fvar, names) {
-    var result = new table.Table('fvar', [
-        {name: 'version', type: 'ULONG', value: 0x10000},
-        {name: 'offsetToData', type: 'USHORT', value: 0},
-        {name: 'countSizePairs', type: 'USHORT', value: 2},
-        {name: 'axisCount', type: 'USHORT', value: fvar.axes.length},
-        {name: 'axisSize', type: 'USHORT', value: 20},
-        {name: 'instanceCount', type: 'USHORT', value: fvar.instances.length},
-        {name: 'instanceSize', type: 'USHORT', value: 4 + fvar.axes.length * 4}
-    ]);
-    result.offsetToData = result.sizeOf();
-
-    for (var i = 0; i < fvar.axes.length; i++) {
-        result.fields = result.fields.concat(makeFvarAxis(i, fvar.axes[i], names));
-    }
-
-    for (var j = 0; j < fvar.instances.length; j++) {
-        result.fields = result.fields.concat(makeFvarInstance(j, fvar.instances[j], fvar.axes, names));
-    }
-
-    return result;
-}
-
-function parseFvarTable(data, start, names) {
-    var p = new parse.Parser(data, start);
-    var tableVersion = p.parseULong();
-    check.argument(tableVersion === 0x00010000, 'Unsupported fvar table version.');
-    var offsetToData = p.parseOffset16();
-    // Skip countSizePairs.
-    p.skip('uShort', 1);
-    var axisCount = p.parseUShort();
-    var axisSize = p.parseUShort();
-    var instanceCount = p.parseUShort();
-    var instanceSize = p.parseUShort();
-
-    var axes = [];
-    for (var i = 0; i < axisCount; i++) {
-        axes.push(parseFvarAxis(data, start + offsetToData + i * axisSize, names));
-    }
-
-    var instances = [];
-    var instanceStart = start + offsetToData + axisCount * axisSize;
-    for (var j = 0; j < instanceCount; j++) {
-        instances.push(parseFvarInstance(data, instanceStart + j * instanceSize, axes, names));
-    }
-
-    return {axes: axes, instances: instances};
-}
-
-var fvar = { make: makeFvarTable, parse: parseFvarTable };
-
-// The `GDEF` table contains various glyph properties
-
-var attachList = function() {
-    return {
-        coverage: this.parsePointer(Parser.coverage),
-        attachPoints: this.parseList(Parser.pointer(Parser.uShortList))
-    };
-};
-
-var caretValue = function() {
-    var format = this.parseUShort();
-    check.argument(format === 1 || format === 2 || format === 3,
-        'Unsupported CaretValue table version.');
-    if (format === 1) {
-        return { coordinate: this.parseShort() };
-    } else if (format === 2) {
-        return { pointindex: this.parseShort() };
-    } else if (format === 3) {
-        // Device / Variation Index tables unsupported
-        return { coordinate: this.parseShort() };
-    }
-};
-
-var ligGlyph = function() {
-    return this.parseList(Parser.pointer(caretValue));
-};
-
-var ligCaretList = function() {
-    return {
-        coverage: this.parsePointer(Parser.coverage),
-        ligGlyphs: this.parseList(Parser.pointer(ligGlyph))
-    };
-};
-
-var markGlyphSets = function() {
-    this.parseUShort(); // Version
-    return this.parseList(Parser.pointer(Parser.coverage));
-};
-
-function parseGDEFTable(data, start) {
-    start = start || 0;
-    var p = new Parser(data, start);
-    var tableVersion = p.parseVersion(1);
-    check.argument(tableVersion === 1 || tableVersion === 1.2 || tableVersion === 1.3,
-        'Unsupported GDEF table version.');
-    var gdef = {
-        version: tableVersion,
-        classDef: p.parsePointer(Parser.classDef),
-        attachList: p.parsePointer(attachList),
-        ligCaretList: p.parsePointer(ligCaretList),
-        markAttachClassDef: p.parsePointer(Parser.classDef)
-    };
-    if (tableVersion >= 1.2) {
-        gdef.markGlyphSets = p.parsePointer(markGlyphSets);
-    }
-    return gdef;
-}
-var gdef = { parse: parseGDEFTable };
-
-// The `GPOS` table contains kerning pairs, among other things.
-
-var subtableParsers$1 = new Array(10);         // subtableParsers[0] is unused
-
-// https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-1-single-adjustment-positioning-subtable
-// this = Parser instance
-subtableParsers$1[1] = function parseLookup1() {
-    var start = this.offset + this.relativeOffset;
-    var posformat = this.parseUShort();
-    if (posformat === 1) {
-        return {
-            posFormat: 1,
-            coverage: this.parsePointer(Parser.coverage),
-            value: this.parseValueRecord()
-        };
-    } else if (posformat === 2) {
-        return {
-            posFormat: 2,
-            coverage: this.parsePointer(Parser.coverage),
-            values: this.parseValueRecordList()
-        };
-    }
-    check.assert(false, '0x' + start.toString(16) + ': GPOS lookup type 1 format must be 1 or 2.');
-};
-
-// https://docs.microsoft.com/en-us/typography/opentype/spec/gpos#lookup-type-2-pair-adjustment-positioning-subtable
-subtableParsers$1[2] = function parseLookup2() {
-    var start = this.offset + this.relativeOffset;
-    var posFormat = this.parseUShort();
-    check.assert(posFormat === 1 || posFormat === 2, '0x' + start.toString(16) + ': GPOS lookup type 2 format must be 1 or 2.');
-    var coverage = this.parsePointer(Parser.coverage);
-    var valueFormat1 = this.parseUShort();
-    var valueFormat2 = this.parseUShort();
-    if (posFormat === 1) {
-        // Adjustments for Glyph Pairs
-        return {
-            posFormat: posFormat,
-            coverage: coverage,
-            valueFormat1: valueFormat1,
-            valueFormat2: valueFormat2,
-            pairSets: this.parseList(Parser.pointer(Parser.list(function() {
-                return {        // pairValueRecord
-                    secondGlyph: this.parseUShort(),
-                    value1: this.parseValueRecord(valueFormat1),
-                    value2: this.parseValueRecord(valueFormat2)
-                };
-            })))
-        };
-    } else if (posFormat === 2) {
-        var classDef1 = this.parsePointer(Parser.classDef);
-        var classDef2 = this.parsePointer(Parser.classDef);
-        var class1Count = this.parseUShort();
-        var class2Count = this.parseUShort();
-        return {
-            // Class Pair Adjustment
-            posFormat: posFormat,
-            coverage: coverage,
-            valueFormat1: valueFormat1,
-            valueFormat2: valueFormat2,
-            classDef1: classDef1,
-            classDef2: classDef2,
-            class1Count: class1Count,
-            class2Count: class2Count,
-            classRecords: this.parseList(class1Count, Parser.list(class2Count, function() {
-                return {
-                    value1: this.parseValueRecord(valueFormat1),
-                    value2: this.parseValueRecord(valueFormat2)
-                };
-            }))
-        };
-    }
-};
-
-subtableParsers$1[3] = function parseLookup3() { return { error: 'GPOS Lookup 3 not supported' }; };
-subtableParsers$1[4] = function parseLookup4() { return { error: 'GPOS Lookup 4 not supported' }; };
-subtableParsers$1[5] = function parseLookup5() { return { error: 'GPOS Lookup 5 not supported' }; };
-subtableParsers$1[6] = function parseLookup6() { return { error: 'GPOS Lookup 6 not supported' }; };
-subtableParsers$1[7] = function parseLookup7() { return { error: 'GPOS Lookup 7 not supported' }; };
-subtableParsers$1[8] = function parseLookup8() { return { error: 'GPOS Lookup 8 not supported' }; };
-subtableParsers$1[9] = function parseLookup9() { return { error: 'GPOS Lookup 9 not supported' }; };
-
-// https://docs.microsoft.com/en-us/typography/opentype/spec/gpos
-function parseGposTable(data, start) {
-    start = start || 0;
-    var p = new Parser(data, start);
-    var tableVersion = p.parseVersion(1);
-    check.argument(tableVersion === 1 || tableVersion === 1.1, 'Unsupported GPOS table version ' + tableVersion);
-
-    if (tableVersion === 1) {
-        return {
-            version: tableVersion,
-            scripts: p.parseScriptList(),
-            features: p.parseFeatureList(),
-            lookups: p.parseLookupList(subtableParsers$1)
-        };
-    } else {
-        return {
-            version: tableVersion,
-            scripts: p.parseScriptList(),
-            features: p.parseFeatureList(),
-            lookups: p.parseLookupList(subtableParsers$1),
-            variations: p.parseFeatureVariationsList()
-        };
-    }
-
-}
-
-// GPOS Writing //////////////////////////////////////////////
-// NOT SUPPORTED
-var subtableMakers$1 = new Array(10);
-
-function makeGposTable(gpos) {
-    return new table.Table('GPOS', [
-        {name: 'version', type: 'ULONG', value: 0x10000},
-        {name: 'scripts', type: 'TABLE', value: new table.ScriptList(gpos.scripts)},
-        {name: 'features', type: 'TABLE', value: new table.FeatureList(gpos.features)},
-        {name: 'lookups', type: 'TABLE', value: new table.LookupList(gpos.lookups, subtableMakers$1)}
-    ]);
-}
-
-var gpos = { parse: parseGposTable, make: makeGposTable };
-
-// The `kern` table contains kerning pairs.
-
-function parseWindowsKernTable(p) {
-    var pairs = {};
-    // Skip nTables.
-    p.skip('uShort');
-    var subtableVersion = p.parseUShort();
-    check.argument(subtableVersion === 0, 'Unsupported kern sub-table version.');
-    // Skip subtableLength, subtableCoverage
-    p.skip('uShort', 2);
-    var nPairs = p.parseUShort();
-    // Skip searchRange, entrySelector, rangeShift.
-    p.skip('uShort', 3);
-    for (var i = 0; i < nPairs; i += 1) {
-        var leftIndex = p.parseUShort();
-        var rightIndex = p.parseUShort();
-        var value = p.parseShort();
-        pairs[leftIndex + ',' + rightIndex] = value;
-    }
-    return pairs;
-}
-
-function parseMacKernTable(p) {
-    var pairs = {};
-    // The Mac kern table stores the version as a fixed (32 bits) but we only loaded the first 16 bits.
-    // Skip the rest.
-    p.skip('uShort');
-    var nTables = p.parseULong();
-    //check.argument(nTables === 1, 'Only 1 subtable is supported (got ' + nTables + ').');
-    if (nTables > 1) {
-        console.warn('Only the first kern subtable is supported.');
-    }
-    p.skip('uLong');
-    var coverage = p.parseUShort();
-    var subtableVersion = coverage & 0xFF;
-    p.skip('uShort');
-    if (subtableVersion === 0) {
-        var nPairs = p.parseUShort();
-        // Skip searchRange, entrySelector, rangeShift.
-        p.skip('uShort', 3);
-        for (var i = 0; i < nPairs; i += 1) {
-            var leftIndex = p.parseUShort();
-            var rightIndex = p.parseUShort();
-            var value = p.parseShort();
-            pairs[leftIndex + ',' + rightIndex] = value;
-        }
-    }
-    return pairs;
-}
-
-// Parse the `kern` table which contains kerning pairs.
-function parseKernTable(data, start) {
-    var p = new parse.Parser(data, start);
-    var tableVersion = p.parseUShort();
-    if (tableVersion === 0) {
-        return parseWindowsKernTable(p);
-    } else if (tableVersion === 1) {
-        return parseMacKernTable(p);
-    } else {
-        throw new Error('Unsupported kern table version (' + tableVersion + ').');
-    }
-}
-
-var kern = { parse: parseKernTable };
-
-// The `loca` table stores the offsets to the locations of the glyphs in the font.
-
-// Parse the `loca` table. This table stores the offsets to the locations of the glyphs in the font,
-// relative to the beginning of the glyphData table.
-// The number of glyphs stored in the `loca` table is specified in the `maxp` table (under numGlyphs)
-// The loca table has two versions: a short version where offsets are stored as uShorts, and a long
-// version where offsets are stored as uLongs. The `head` table specifies which version to use
-// (under indexToLocFormat).
-function parseLocaTable(data, start, numGlyphs, shortVersion) {
-    var p = new parse.Parser(data, start);
-    var parseFn = shortVersion ? p.parseUShort : p.parseULong;
-    // There is an extra entry after the last index element to compute the length of the last glyph.
-    // That's why we use numGlyphs + 1.
-    var glyphOffsets = [];
-    for (var i = 0; i < numGlyphs + 1; i += 1) {
-        var glyphOffset = parseFn.call(p);
-        if (shortVersion) {
-            // The short table version stores the actual offset divided by 2.
-            glyphOffset *= 2;
-        }
-
-        glyphOffsets.push(glyphOffset);
-    }
-
-    return glyphOffsets;
-}
-
-var loca = { parse: parseLocaTable };
-
-// opentype.js
-
-/**
- * The opentype library.
- * @namespace opentype
- */
-
-// File loaders /////////////////////////////////////////////////////////
-
-/**
- * Loads a font from a URL. The callback throws an error message as the first parameter if it fails
- * and the font as an ArrayBuffer in the second parameter if it succeeds.
- * @param  {string} url - The URL of the font file.
- * @param  {Function} callback - The function to call when the font load completes
- */
-function loadFromUrl(url, callback) {
-    var request = new XMLHttpRequest();
-    request.open('get', url, true);
-    request.responseType = 'arraybuffer';
-    request.onload = function() {
-        if (request.response) {
-            return callback(null, request.response);
-        } else {
-            return callback('Font could not be loaded: ' + request.statusText);
-        }
-    };
-
-    request.onerror = function () {
-        callback('Font could not be loaded');
-    };
-
-    request.send();
-}
-
-// Table Directory Entries //////////////////////////////////////////////
-/**
- * Parses OpenType table entries.
- * @param  {DataView}
- * @param  {Number}
- * @return {Object[]}
- */
-function parseOpenTypeTableEntries(data, numTables) {
-    var tableEntries = [];
-    var p = 12;
-    for (var i = 0; i < numTables; i += 1) {
-        var tag = parse.getTag(data, p);
-        var checksum = parse.getULong(data, p + 4);
-        var offset = parse.getULong(data, p + 8);
-        var length = parse.getULong(data, p + 12);
-        tableEntries.push({tag: tag, checksum: checksum, offset: offset, length: length, compression: false});
-        p += 16;
-    }
-
-    return tableEntries;
-}
-
-/**
- * Parses WOFF table entries.
- * @param  {DataView}
- * @param  {Number}
- * @return {Object[]}
- */
-function parseWOFFTableEntries(data, numTables) {
-    var tableEntries = [];
-    var p = 44; // offset to the first table directory entry.
-    for (var i = 0; i < numTables; i += 1) {
-        var tag = parse.getTag(data, p);
-        var offset = parse.getULong(data, p + 4);
-        var compLength = parse.getULong(data, p + 8);
-        var origLength = parse.getULong(data, p + 12);
-        var compression = (void 0);
-        if (compLength < origLength) {
-            compression = 'WOFF';
-        } else {
-            compression = false;
-        }
-
-        tableEntries.push({tag: tag, offset: offset, compression: compression,
-            compressedLength: compLength, length: origLength});
-        p += 20;
-    }
-
-    return tableEntries;
-}
-
-/**
- * @typedef TableData
- * @type Object
- * @property {DataView} data - The DataView
- * @property {number} offset - The data offset.
- */
-
-/**
- * @param  {DataView}
- * @param  {Object}
- * @return {TableData}
- */
-function uncompressTable(data, tableEntry) {
-    if (tableEntry.compression === 'WOFF') {
-        var inBuffer = new Uint8Array(data.buffer, tableEntry.offset + 2, tableEntry.compressedLength - 2);
-        var outBuffer = new Uint8Array(tableEntry.length);
-        tinyInflate(inBuffer, outBuffer);
-        if (outBuffer.byteLength !== tableEntry.length) {
-            throw new Error('Decompression error: ' + tableEntry.tag + ' decompressed length doesn\'t match recorded length');
-        }
-
-        var view = new DataView(outBuffer.buffer, 0);
-        return {data: view, offset: 0};
-    } else {
-        return {data: data, offset: tableEntry.offset};
-    }
-}
-
-// Public API ///////////////////////////////////////////////////////////
-
-/**
- * Parse the OpenType file data (as an ArrayBuffer) and return a Font object.
- * Throws an error if the font could not be parsed.
- * @param  {ArrayBuffer}
- * @param  {Object} opt - options for parsing
- * @return {opentype.Font}
- */
-function parseBuffer(buffer, opt) {
-    opt = (opt === undefined || opt === null) ?  {} : opt;
-
-    var indexToLocFormat;
-    var ltagTable;
-
-    // Since the constructor can also be called to create new fonts from scratch, we indicate this
-    // should be an empty font that we'll fill with our own data.
-    var font = new Font({empty: true});
-
-    // OpenType fonts use big endian byte ordering.
-    // We can't rely on typed array view types, because they operate with the endianness of the host computer.
-    // Instead we use DataViews where we can specify endianness.
-    var data = new DataView(buffer, 0);
-    var numTables;
-    var tableEntries = [];
-    var signature = parse.getTag(data, 0);
-    if (signature === String.fromCharCode(0, 1, 0, 0) || signature === 'true' || signature === 'typ1') {
-        font.outlinesFormat = 'truetype';
-        numTables = parse.getUShort(data, 4);
-        tableEntries = parseOpenTypeTableEntries(data, numTables);
-    } else if (signature === 'OTTO') {
-        font.outlinesFormat = 'cff';
-        numTables = parse.getUShort(data, 4);
-        tableEntries = parseOpenTypeTableEntries(data, numTables);
-    } else if (signature === 'wOFF') {
-        var flavor = parse.getTag(data, 4);
-        if (flavor === String.fromCharCode(0, 1, 0, 0)) {
-            font.outlinesFormat = 'truetype';
-        } else if (flavor === 'OTTO') {
-            font.outlinesFormat = 'cff';
-        } else {
-            throw new Error('Unsupported OpenType flavor ' + signature);
-        }
-
-        numTables = parse.getUShort(data, 12);
-        tableEntries = parseWOFFTableEntries(data, numTables);
-    } else {
-        throw new Error('Unsupported OpenType signature ' + signature);
-    }
-
-    var cffTableEntry;
-    var fvarTableEntry;
-    var glyfTableEntry;
-    var gdefTableEntry;
-    var gposTableEntry;
-    var gsubTableEntry;
-    var hmtxTableEntry;
-    var kernTableEntry;
-    var locaTableEntry;
-    var nameTableEntry;
-    var metaTableEntry;
-    var p;
-
-    for (var i = 0; i < numTables; i += 1) {
-        var tableEntry = tableEntries[i];
-        var table = (void 0);
-        switch (tableEntry.tag) {
-            case 'cmap':
-                table = uncompressTable(data, tableEntry);
-                font.tables.cmap = cmap.parse(table.data, table.offset);
-                font.encoding = new CmapEncoding(font.tables.cmap);
-                break;
-            case 'cvt ' :
-                table = uncompressTable(data, tableEntry);
-                p = new parse.Parser(table.data, table.offset);
-                font.tables.cvt = p.parseShortList(tableEntry.length / 2);
-                break;
-            case 'fvar':
-                fvarTableEntry = tableEntry;
-                break;
-            case 'fpgm' :
-                table = uncompressTable(data, tableEntry);
-                p = new parse.Parser(table.data, table.offset);
-                font.tables.fpgm = p.parseByteList(tableEntry.length);
-                break;
-            case 'head':
-                table = uncompressTable(data, tableEntry);
-                font.tables.head = head.parse(table.data, table.offset);
-                font.unitsPerEm = font.tables.head.unitsPerEm;
-                indexToLocFormat = font.tables.head.indexToLocFormat;
-                break;
-            case 'hhea':
-                table = uncompressTable(data, tableEntry);
-                font.tables.hhea = hhea.parse(table.data, table.offset);
-                font.ascender = font.tables.hhea.ascender;
-                font.descender = font.tables.hhea.descender;
-                font.numberOfHMetrics = font.tables.hhea.numberOfHMetrics;
-                break;
-            case 'hmtx':
-                hmtxTableEntry = tableEntry;
-                break;
-            case 'ltag':
-                table = uncompressTable(data, tableEntry);
-                ltagTable = ltag.parse(table.data, table.offset);
-                break;
-            case 'COLR':
-                table = uncompressTable(data, tableEntry);
-                font.tables.colr = colr.parse(table.data, table.offset);
-                break;
-            case 'CPAL':
-                table = uncompressTable(data, tableEntry);
-                font.tables.cpal = cpal.parse(table.data, table.offset);
-                break;
-            case 'maxp':
-                table = uncompressTable(data, tableEntry);
-                font.tables.maxp = maxp.parse(table.data, table.offset);
-                font.numGlyphs = font.tables.maxp.numGlyphs;
-                break;
-            case 'name':
-                nameTableEntry = tableEntry;
-                break;
-            case 'OS/2':
-                table = uncompressTable(data, tableEntry);
-                font.tables.os2 = os2.parse(table.data, table.offset);
-                break;
-            case 'post':
-                table = uncompressTable(data, tableEntry);
-                font.tables.post = post.parse(table.data, table.offset);
-                font.glyphNames = new GlyphNames(font.tables.post);
-                break;
-            case 'prep' :
-                table = uncompressTable(data, tableEntry);
-                p = new parse.Parser(table.data, table.offset);
-                font.tables.prep = p.parseByteList(tableEntry.length);
-                break;
-            case 'glyf':
-                glyfTableEntry = tableEntry;
-                break;
-            case 'loca':
-                locaTableEntry = tableEntry;
-                break;
-            case 'CFF ':
-                cffTableEntry = tableEntry;
-                break;
-            case 'kern':
-                kernTableEntry = tableEntry;
-                break;
-            case 'GDEF':
-                gdefTableEntry = tableEntry;
-                break;
-            case 'GPOS':
-                gposTableEntry = tableEntry;
-                break;
-            case 'GSUB':
-                gsubTableEntry = tableEntry;
-                break;
-            case 'meta':
-                metaTableEntry = tableEntry;
-                break;
-        }
-    }
-
-    var nameTable = uncompressTable(data, nameTableEntry);
-    font.tables.name = _name.parse(nameTable.data, nameTable.offset, ltagTable);
-    font.names = font.tables.name;
-
-    if (glyfTableEntry && locaTableEntry) {
-        var shortVersion = indexToLocFormat === 0;
-        var locaTable = uncompressTable(data, locaTableEntry);
-        var locaOffsets = loca.parse(locaTable.data, locaTable.offset, font.numGlyphs, shortVersion);
-        var glyfTable = uncompressTable(data, glyfTableEntry);
-        font.glyphs = glyf.parse(glyfTable.data, glyfTable.offset, locaOffsets, font, opt);
-    } else if (cffTableEntry) {
-        var cffTable = uncompressTable(data, cffTableEntry);
-        cff.parse(cffTable.data, cffTable.offset, font, opt);
-    } else {
-        throw new Error('Font doesn\'t contain TrueType or CFF outlines.');
-    }
-
-    var hmtxTable = uncompressTable(data, hmtxTableEntry);
-    hmtx.parse(font, hmtxTable.data, hmtxTable.offset, font.numberOfHMetrics, font.numGlyphs, font.glyphs, opt);
-    addGlyphNames(font, opt);
-
-    if (kernTableEntry) {
-        var kernTable = uncompressTable(data, kernTableEntry);
-        font.kerningPairs = kern.parse(kernTable.data, kernTable.offset);
-    } else {
-        font.kerningPairs = {};
-    }
-
-    if (gdefTableEntry) {
-        var gdefTable = uncompressTable(data, gdefTableEntry);
-        font.tables.gdef = gdef.parse(gdefTable.data, gdefTable.offset);
-    }
-
-    if (gposTableEntry) {
-        var gposTable = uncompressTable(data, gposTableEntry);
-        font.tables.gpos = gpos.parse(gposTable.data, gposTable.offset);
-        font.position.init();
-    }
-
-    if (gsubTableEntry) {
-        var gsubTable = uncompressTable(data, gsubTableEntry);
-        font.tables.gsub = gsub.parse(gsubTable.data, gsubTable.offset);
-    }
-
-    if (fvarTableEntry) {
-        var fvarTable = uncompressTable(data, fvarTableEntry);
-        font.tables.fvar = fvar.parse(fvarTable.data, fvarTable.offset, font.names);
-    }
-
-    if (metaTableEntry) {
-        var metaTable = uncompressTable(data, metaTableEntry);
-        font.tables.meta = meta.parse(metaTable.data, metaTable.offset);
-        font.metas = font.tables.meta;
-    }
-
-    return font;
-}
-
-/**
- * Asynchronously load the font from a URL or a filesystem. When done, call the callback
- * with two arguments `(err, font)`. The `err` will be null on success,
- * the `font` is a Font object.
- * We use the node.js callback convention so that
- * opentype.js can integrate with frameworks like async.js.
- * @alias opentype.load
- * @param  {string} url - The URL of the font to load.
- * @param  {Function} callback - The callback.
- */
-function load(url, callback, opt) {
-    opt = (opt === undefined || opt === null) ?  {} : opt;
-
-    return new Promise(function (resolve, reject) {
-        loadFromUrl(url, function(err, arrayBuffer) {
-            if (err) {
-                if (callback) {
-                    return callback(err);
-                } else {
-                    reject(err);
-                }
-            }
-            var font;
-            try {
-                font = parseBuffer(arrayBuffer, opt);
-            } catch (e) {
-                if (callback) {
-                    return callback(e, null);
-                } else {
-                    reject(e);
-                }
-            }
-            if (callback) {
-                return callback(null, font);
-            } else {
-                resolve(font);
-            }
-        });
-    });
-}
-
-var opentype = /*#__PURE__*/Object.freeze({
-	__proto__: null,
-	Font: Font,
-	Glyph: Glyph,
-	Path: Path,
-	BoundingBox: BoundingBox,
-	_parse: parse,
-	parse: parseBuffer,
-	load: load,
-});
-
-export default opentype;
-export { BoundingBox, Font, Glyph, Path, parse as _parse, load, parseBuffer as parse };

+ 1 - 1
examples/jsm/loaders/LottieLoader.js

@@ -6,7 +6,7 @@ import {
 	SRGBColorSpace
 } from 'three';
 
-import lottie from '../libs/lottie_canvas.module.js';
+import lottie from 'https://cdn.jsdelivr.net/npm/lottie-web@5.13.0/+esm';
 
 /**
  * A loader for the Lottie texture animation format.

+ 1 - 1
examples/jsm/loaders/TTFLoader.js

@@ -2,7 +2,7 @@ import {
 	FileLoader,
 	Loader
 } from 'three';
-import opentype from '../libs/opentype.module.js';
+import opentype from 'https://cdn.jsdelivr.net/npm/opentype.js@1.3.4/+esm';
 
 /**
  * A loader for the TTF format.

+ 15 - 8
examples/jsm/physics/AmmoPhysics.js

@@ -1,13 +1,13 @@
+const AMMO_PATH = 'https://cdn.jsdelivr.net/gh/kripken/ammo.js@79190a1f03845794b1bba1777f30037349967658/builds/ammo.wasm.js';
+
 /**
  * @classdesc Can be used to include Ammo.js as a Physics engine into
- * `three.js` apps. Make sure to include `ammo.wasm.js` first:
- * ```
- * <script src="jsm/libs/ammo.wasm.js"></script>
- * ```
- * It is then possible to initialize the API via:
+ * `three.js` apps. The API can be initialized via:
  * ```js
  * const physics = await AmmoPhysics();
  * ```
+ * The component automatically imports Ammo.js from a CDN so make sure
+ * to use the component with an active Internet connection.
  *
  * @name AmmoPhysics
  * @class
@@ -16,10 +16,17 @@
  */
 async function AmmoPhysics() {
 
-	if ( 'Ammo' in window === false ) {
+	if ( typeof Ammo === 'undefined' ) {
 
-		console.error( 'AmmoPhysics: Couldn\'t find Ammo.js' );
-		return;
+		await new Promise( ( resolve, reject ) => {
+
+			const script = document.createElement( 'script' );
+			script.src = AMMO_PATH;
+			script.onload = resolve;
+			script.onerror = reject;
+			document.head.appendChild( script );
+
+		} );
 
 	}
 

+ 27 - 23
examples/jsm/tsl/display/SSGINode.js

@@ -139,7 +139,7 @@ class SSGINode extends TempNode {
 		 * Makes the sample distance in screen space instead of world-space (helps having more detail up close).
 		 *
 		 * @type {UniformNode<bool>}
-		 * @default false
+		 * @default true
 		 */
 		this.useScreenSpaceSampling = uniform( true, 'bool' );
 
@@ -435,29 +435,15 @@ class SSGINode extends TempNode {
 			]
 		} );
 
-		const horizonSampling = Fn( ( [ directionIsRight, RADIUS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ] ) => {
+		const horizonSampling = Fn( ( [ directionIsRight, stepRadius, radiusVS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ] ) => {
 
 			const STEP_COUNT = this.stepCount.toConst();
 			const EXP_FACTOR = this.expFactor.toConst();
 			const THICKNESS = this.thickness.toConst();
 			const BACKFACE_LIGHTING = this.backfaceLighting.toConst();
 
-			const stepRadius = float( 0 );
-
-			If( this.useScreenSpaceSampling.equal( true ), () => {
-
-				stepRadius.assign( RADIUS.mul( this._resolution.x.div( 2 ) ).div( float( 16 ) ) ); // SSRT3 has a bug where stepRadius is divided by STEP_COUNT twice; fix here
-
-			} ).Else( () => {
-
-				stepRadius.assign( max( RADIUS.mul( this._halfProjScale ).div( viewPosition.z.negate() ), float( STEP_COUNT ) ) ); // Port note: viewZ is negative so a negate is required
-
-			} );
-
-			stepRadius.divAssign( float( STEP_COUNT ).add( 1 ) );
-			const radiusVS = max( 1, float( STEP_COUNT.sub( 1 ) ) ).mul( stepRadius );
-			const uvDirection = directionIsRight.equal( true ).select( vec2( 1, - 1 ), vec2( - 1, 1 ) ); // Port note: Because of different uv conventions, uv-y has a different sign
-			const samplingDirection = directionIsRight.equal( true ).select( 1, - 1 );
+			const uvDirection = directionIsRight.select( vec2( 1, - 1 ), vec2( - 1, 1 ) ); // Port note: Because of different uv conventions, uv-y has a different sign
+			const samplingDirection = directionIsRight.select( 1, - 1 );
 
 			const color = vec3( 0 );
 
@@ -475,13 +461,13 @@ class SSGINode extends TempNode {
 
 				const sampleViewPosition = getViewPosition( sampleUV, sampleDepth( sampleUV ), this._cameraProjectionMatrixInverse ).toConst();
 				const pixelToSample = sampleViewPosition.sub( viewPosition ).normalize().toConst();
-				const linearThicknessMultiplier = this.useLinearThickness.equal( true ).select( sampleViewPosition.z.negate().div( this._cameraFar ).clamp().mul( 100 ), float( 1 ) );
+				const linearThicknessMultiplier = this.useLinearThickness.select( sampleViewPosition.z.negate().div( this._cameraFar ).clamp().mul( 100 ), float( 1 ) );
 				const pixelToSampleBackface = normalize( sampleViewPosition.sub( linearThicknessMultiplier.mul( viewDir ).mul( THICKNESS ) ).sub( viewPosition ) );
 
 				let frontBackHorizon = vec2( dot( pixelToSample, viewDir ), dot( pixelToSampleBackface, viewDir ) );
 				frontBackHorizon = GTAOFastAcos( clamp( frontBackHorizon, - 1, 1 ) );
 				frontBackHorizon = clamp( div( mul( samplingDirection, frontBackHorizon.negate() ).sub( n.sub( HALF_PI ) ), PI ) ); // Port note: subtract half pi instead of adding it
-				frontBackHorizon = directionIsRight.equal( true ).select( frontBackHorizon.yx, frontBackHorizon.xy ); // Front/Back get inverted depending on angle
+				frontBackHorizon = directionIsRight.select( frontBackHorizon.yx, frontBackHorizon.xy ); // Front/Back get inverted depending on angle
 
 				// inline ComputeOccludedBitfield() for easier debugging
 
@@ -529,7 +515,7 @@ class SSGINode extends TempNode {
 
 			} );
 
-			return vec3( color );
+			return color;
 
 		} );
 
@@ -554,10 +540,28 @@ class SSGINode extends TempNode {
 			const color = vec3( 0 );
 
 			const ROTATION_COUNT = this.sliceCount.toConst();
+			const STEP_COUNT = this.stepCount.toConst();
 			const AO_INTENSITY = this.aoIntensity.toConst();
 			const GI_INTENSITY = this.giIntensity.toConst();
 			const RADIUS = this.radius.toConst();
 
+			const stepRadius = float( 0 ).toVar();
+
+			If( this.useScreenSpaceSampling, () => {
+
+				stepRadius.assign( RADIUS.mul( this._resolution.x.div( 2 ) ).div( float( 16 ) ) ); // SSRT3 has a bug where stepRadius is divided by STEP_COUNT twice; fix here
+
+			} ).Else( () => {
+
+				stepRadius.assign( max( RADIUS.mul( this._halfProjScale ).div( viewPosition.z.negate() ), float( STEP_COUNT ) ) ); // Port note: viewZ is negative so a negate is required
+
+			} );
+
+			stepRadius.divAssign( float( STEP_COUNT ).add( 1 ) );
+			const radiusVS = max( 1, float( STEP_COUNT.sub( 1 ) ) ).mul( stepRadius ).toConst();
+
+			//
+
 			Loop( { start: uint( 0 ), end: ROTATION_COUNT, type: 'uint', condition: '<' }, ( { i } ) => {
 
 				const rotationAngle = mul( float( i ).add( noiseDirection ).add( this._temporalDirection ), PI.div( float( ROTATION_COUNT ) ) ).toConst();
@@ -574,8 +578,8 @@ class SSGINode extends TempNode {
 
 				globalOccludedBitfield.assign( 0 );
 
-				color.addAssign( horizonSampling( bool( true ), RADIUS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ) );
-				color.addAssign( horizonSampling( bool( false ), RADIUS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ) );
+				color.addAssign( horizonSampling( bool( true ), stepRadius, radiusVS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ) );
+				color.addAssign( horizonSampling( bool( false ), stepRadius, radiusVS, viewPosition, slideDirTexelSize, initialRayStep, uvNode, viewDir, viewNormal, n ) );
 
 				ao.addAssign( float( countOneBits( globalOccludedBitfield ) ).div( float( MAX_RAY ) ) );
 

+ 1 - 1
examples/jsm/tsl/lighting/ClusteredLightsNode.js

@@ -212,7 +212,7 @@ class ClusteredLightsNode extends LightsNode {
 
 		for ( const light of lights ) {
 
-			if ( light.isPointLight === true ) {
+			if ( light.isPointLight === true && light.castShadow !== true ) {
 
 				clusteredLights[ clusteredIndex ++ ] = light;
 

+ 3 - 3
examples/misc_exporter_draco.html

@@ -15,7 +15,7 @@
 			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - exporter - draco
 		</div>
 
-		<script src="jsm/libs/draco/draco_encoder.js"></script>
+		<script src="https://cdn.jsdelivr.net/gh/google/draco@1.5.7/javascript/draco_encoder.js"></script>
 
 		<script type="importmap">
 			{
@@ -131,9 +131,9 @@
 
 			}
 
-			function exportFile() {
+			async function exportFile() {
 
-				const result = exporter.parse( mesh );
+				const result = await exporter.parseAsync( mesh );
 				saveArrayBuffer( result, 'file.drc' );
 
 			}

+ 1 - 1
examples/physics_ammo_break.html

@@ -19,7 +19,7 @@
 	<div id="info">Physics threejs demo with convex objects breaking in real time<br />Press mouse to throw balls and move the camera.</div>
 	<div id="container"></div>
 
-	<script src="jsm/libs/ammo.wasm.js"></script>
+	<script src="https://cdn.jsdelivr.net/gh/kripken/ammo.js@79190a1f03845794b1bba1777f30037349967658/builds/ammo.wasm.js"></script>
 
 	<script type="importmap">
 		{

+ 1 - 1
examples/physics_ammo_cloth.html

@@ -18,7 +18,7 @@
 		<div id="info">Ammo.js physics soft body cloth demo<br>Press Q or A to move the arm.</div>
 		<div id="container"></div>
 
-		<script src="jsm/libs/ammo.wasm.js"></script>
+		<script src="https://cdn.jsdelivr.net/gh/kripken/ammo.js@79190a1f03845794b1bba1777f30037349967658/builds/ammo.wasm.js"></script>
 
 		<script type="importmap">
 			{

+ 0 - 2
examples/physics_ammo_instancing.html

@@ -16,8 +16,6 @@
 			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> physics - ammo.js instancing
 		</div>
 
-		<script src="jsm/libs/ammo.wasm.js"></script>
-
 		<script type="importmap">
 			{
 				"imports": {

+ 1 - 1
examples/physics_ammo_rope.html

@@ -18,7 +18,7 @@
 	<div id="info">Ammo.js physics soft body rope demo<br>Press Q or A to move the arm.</div>
 	<div id="container"></div>
 
-	<script src="jsm/libs/ammo.wasm.js"></script>
+	<script src="https://cdn.jsdelivr.net/gh/kripken/ammo.js@79190a1f03845794b1bba1777f30037349967658/builds/ammo.wasm.js"></script>
 
 	<script type="importmap">
 		{

+ 1 - 1
examples/physics_ammo_terrain.html

@@ -19,7 +19,7 @@
 		<div id="container"></div>
 		<div id="info">Ammo.js physics terrain heightfield demo</div>
 
-		<script src="jsm/libs/ammo.wasm.js"></script>
+		<script src="https://cdn.jsdelivr.net/gh/kripken/ammo.js@79190a1f03845794b1bba1777f30037349967658/builds/ammo.wasm.js"></script>
 
 		<script type="importmap">
 			{

+ 1 - 1
examples/physics_ammo_volume.html

@@ -21,7 +21,7 @@
 		</div>
 		<div id="container"></div>
 
-		<script src="jsm/libs/ammo.wasm.js"></script>
+		<script src="https://cdn.jsdelivr.net/gh/kripken/ammo.js@79190a1f03845794b1bba1777f30037349967658/builds/ammo.wasm.js"></script>
 
 		<script type="importmap">
 			{

BIN
examples/screenshots/webgl_tsl_shadowmap.jpg


BIN
examples/screenshots/webgpu_lights_clustered.jpg


BIN
examples/screenshots/webgpu_modifier_curve.jpg


BIN
examples/screenshots/webgpu_shadowmap.jpg


+ 151 - 174
examples/webgpu_lights_clustered.html

@@ -38,29 +38,34 @@
 		<script type="module">
 
 			import * as THREE from 'three/webgpu';
-			import { pass, uniform, vec3, float, mix, step, uv, instancedBufferAttribute } from 'three/tsl';
+			import { instancedBufferAttribute, pass, uniform, vec3, float, mix, step } from 'three/tsl';
 
 			import { ClusteredLighting } from 'three/addons/lighting/ClusteredLighting.js';
 
 			import { Inspector } from 'three/addons/inspector/Inspector.js';
 
 			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
-			import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
+			import { SkyMesh } from 'three/addons/objects/SkyMesh.js';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 
-			const MODEL_INDEX_URL = 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/model-index.json';
-			const SAMPLE_ASSETS_BASE_URL = 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Assets/main/Models/';
+			const GRID = 30; // GRID x GRID spheres
+			const SPACING = 5;
+			const RADIUS = 0.5;
+			const WAVE_HEIGHT = 4;
+			const BIG_RADIUS = 6;
+			const BASE_POWER = 45;
 
-			let camera, scene, renderer,
-				lights, lightDummy,
-				lightPositionAttribute,
-				controls,
-				scenePass, clusterInfluence, debugZSliceNode,
-				lighting,
-				maxCount,
-				count,
-				renderPipeline;
+			let camera, scene, renderer, controls, spheresMesh, lighting;
+			let renderPipeline, scenePass, clusterInfluence, debugZSliceNode;
+
+			const balls = [];
+			const dummy = new THREE.Object3D();
+
+			const params = {
+				intensity: 1,
+				animate: true
+			};
 
 			init();
 
@@ -74,260 +79,232 @@
 
 				}
 
-				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.1, 70 );
-				camera.position.set( - 10, 5, 0 );
+				camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 20000 );
+				camera.position.set( 36, 18, 36 );
 
 				scene = new THREE.Scene();
-				scene.fog = new THREE.Fog( 0x111111, 30, 80 );
-				scene.background = new THREE.Color( 0x111111 );
 
-				maxCount = 1000;
-				count = 700;
+				renderer = new THREE.WebGPURenderer( { antialias: true } );
+				renderer.setPixelRatio( window.devicePixelRatio );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+				renderer.setAnimationLoop( animate );
+				renderer.toneMapping = THREE.NeutralToneMapping;
+				renderer.toneMappingExposure = 1;
+				lighting = new ClusteredLighting();
+				renderer.lighting = lighting; // set lighting system
+				renderer.inspector = new Inspector();
+				document.body.appendChild( renderer.domElement );
 
-				// sponza
+				await renderer.init();
 
-				const loader = new GLTFLoader();
-				const modelURL = await getSponzaModelURL();
-				const gltf = await loader.loadAsync( modelURL );
-				const model = gltf.scene;
+				// a physical sky drives the backdrop and the image-based lighting; the
+				// sun sits just below the horizon for an almost-night mood
 
-				model.traverse( ( child ) => {
+				const sky = new SkyMesh();
+				sky.scale.setScalar( 10000 );
+				sky.turbidity.value = 10;
+				sky.rayleigh.value = 3;
+				sky.mieCoefficient.value = 0.005;
+				sky.mieDirectionalG.value = 0.7;
 
-					if ( child.isLight && child.parent ) child.parent.remove( child );
+				const sun = new THREE.Vector3().setFromSphericalCoords(
+					1,
+					THREE.MathUtils.degToRad( 92 ), // elevation: 2° below the horizon (almost night)
+					THREE.MathUtils.degToRad( 225 ) // azimuth
+				);
+				sky.sunPosition.value.copy( sun );
 
-				} );
+				scene.add( sky );
 
-				scene.add( model );
+				// the sun sits below the horizon, so keep its disc hidden; bake the sky
+				// into an environment map for the faint ambient colour it still casts
 
-				const box = new THREE.Box3().setFromObject( model );
-				const modelSize = box.getSize( new THREE.Vector3() );
-				const modelCenter = box.getCenter( new THREE.Vector3() );
+				const pmremGenerator = new THREE.PMREMGenerator( renderer );
 
-				const lightPositions = new Float32Array( maxCount * 3 );
-				const lightColors = new Float32Array( maxCount * 3 );
+				sky.showSunDisc.value = false;
+				scene.environment = pmremGenerator.fromScene( scene ).texture;
+				scene.environmentIntensity = 0.75;
 
-				lightPositionAttribute = new THREE.InstancedBufferAttribute( lightPositions, 3 );
-				lightPositionAttribute.setUsage( THREE.DynamicDrawUsage );
+				// ground
 
-				const lightColorAttribute = new THREE.InstancedBufferAttribute( lightColors, 3 );
+				const ground = new THREE.Mesh(
+					new THREE.PlaneGeometry( 1000, 1000 ).rotateX( - Math.PI / 2 ),
+					new THREE.MeshStandardNodeMaterial( { color: 0x2a2a2a, roughness: 0.6, metalness: 0 } )
+				);
+				scene.add( ground );
 
-				// Physical 1/r² point-source falloff (Plummer profile): I = peak * r0² / ( r² + r0² )
-				// Subtract the value at r = 0.5 so the soft tail reaches exactly 0 at the sprite edge.
-				const coreRadius = 0.02;
-				const peak = 16;
-				const r0sq = coreRadius * coreRadius;
-				const edgeBias = r0sq / ( 0.25 + r0sq );
+				// four big spheres in the middle for the surrounding lights to play across
 
-				const offset = uv().sub( 0.5 );
-				const r2 = offset.dot( offset );
-				const glow = float( r0sq ).div( r2.add( r0sq ) ).sub( edgeBias ).max( 0 ).mul( peak );
+				const bigPositions = [
+					new THREE.Vector3( - 9, BIG_RADIUS, - 9 ),
+					new THREE.Vector3( 9, BIG_RADIUS, - 9 ),
+					new THREE.Vector3( - 9, BIG_RADIUS, 9 ),
+					new THREE.Vector3( 9, BIG_RADIUS, 9 )
+				];
 
-				const spriteMaterial = new THREE.SpriteNodeMaterial( {
-					transparent: true,
-					depthWrite: false,
-					blending: THREE.AdditiveBlending
-				} );
-				spriteMaterial.positionNode = instancedBufferAttribute( lightPositionAttribute );
-				spriteMaterial.colorNode = glow.mul( instancedBufferAttribute( lightColorAttribute ) );
-				spriteMaterial.scaleNode = uniform( 0.2 );
+				const bigGeometry = new THREE.SphereGeometry( BIG_RADIUS, 64, 32 );
+				const bigMaterial = new THREE.MeshStandardNodeMaterial( { color: 0xdddddd, roughness: 0.5, metalness: 0 } );
 
-				lightDummy = new THREE.Sprite( spriteMaterial );
-				lightDummy.count = count;
-				lightDummy.frustumCulled = false;
-				scene.add( lightDummy );
+				for ( const position of bigPositions ) {
 
-				// lights
+					const bigSphere = new THREE.Mesh( bigGeometry, bigMaterial );
+					bigSphere.position.copy( position );
+					scene.add( bigSphere );
 
-				lights = new THREE.Group();
-				scene.add( lights );
+				}
 
-				const addLight = ( hexColor, power = 10, distance = 1 ) => {
+				// a grid of coloured spheres drawn as a single InstancedMesh; each is
+				// unlit in its own colour and holds a matching point light at its centre
 
-					const light = new THREE.PointLight( hexColor, 1, distance );
-					light.position.set(
-						modelCenter.x + ( Math.random() - 0.5 ) * modelSize.x * 0.7,
-						( box.min.y + Math.random() * modelSize.y * 0.7 ) + 0.4,
-						modelCenter.z + ( Math.random() - 0.5 ) * modelSize.z * 0.5
-					);
+				const maxCount = GRID * GRID;
+				const colorAttribute = new THREE.InstancedBufferAttribute( new Float32Array( maxCount * 3 ), 3 );
 
-					light.power = power;
-					light.userData.fixedPosition = light.position.clone();
-					light.visible = ( lights.children.length < count );
+				const material = new THREE.MeshBasicNodeMaterial();
+				material.colorNode = instancedBufferAttribute( colorAttribute );
 
-					const i = lights.children.length;
-					lightPositions[ i * 3 + 0 ] = light.position.x;
-					lightPositions[ i * 3 + 1 ] = light.position.y;
-					lightPositions[ i * 3 + 2 ] = light.position.z;
+				spheresMesh = new THREE.InstancedMesh( new THREE.SphereGeometry( RADIUS, 32, 16 ), material, maxCount );
+				spheresMesh.instanceMatrix.setUsage( THREE.DynamicDrawUsage );
+				scene.add( spheresMesh );
 
-					lights.add( light );
+				const color = new THREE.Color();
+				const span = ( GRID - 1 ) * SPACING;
 
-					return light;
+				let i = 0;
 
-				};
+				for ( let ix = 0; ix < GRID; ix ++ ) {
 
-				const color = new THREE.Color();
+					for ( let iz = 0; iz < GRID; iz ++ ) {
 
-				for ( let i = 0; i < maxCount; i ++ ) {
+						const x = ix * SPACING - span / 2;
+						const z = iz * SPACING - span / 2;
 
-					const hex = ( Math.random() * 0x888888 ) + 0x888888;
+						// leave a clearing where a big sphere sits
+						if ( bigPositions.some( ( position ) => Math.hypot( x - position.x, z - position.z ) < BIG_RADIUS + 1 ) ) continue;
 
-					color.setHex( hex );
-					lightColors[ i * 3 + 0 ] = color.r;
-					lightColors[ i * 3 + 1 ] = color.g;
-					lightColors[ i * 3 + 2 ] = color.b;
+						const phase = ( ix + iz ) * 0.5;
 
-					addLight( hex );
+						dummy.position.set( x, RADIUS, z );
+						dummy.updateMatrix();
+						spheresMesh.setMatrixAt( i, dummy.matrix );
 
-				}
+						color.setHSL( ( ix * GRID + iz ) / ( GRID * GRID ), 1.0, 0.5 );
+						colorAttribute.setXYZ( i, color.r, color.g, color.b );
 
-				//
+						const light = new THREE.PointLight( color, 1, 9 );
+						light.power = BASE_POWER;
+						light.position.set( x, RADIUS, z );
+						scene.add( light );
 
-				const lightAmbient = new THREE.AmbientLight( 0xffffff, .1 );
-				scene.add( lightAmbient );
+						balls.push( { x, z, phase, light } );
 
-				// renderer
+						i ++;
 
-				lighting = new ClusteredLighting(); // ( maxLights = 1024, tileSize = 32, zSlices = 24, maxLightsPerCluster = 64 )
+					}
 
-				renderer = new THREE.WebGPURenderer( { antialias: true } );
-				renderer.setPixelRatio( window.devicePixelRatio );
-				renderer.setSize( window.innerWidth, window.innerHeight );
-				renderer.setAnimationLoop( animate );
-				renderer.lighting = lighting; // set lighting system
-				renderer.toneMapping = THREE.NeutralToneMapping;
-				renderer.toneMappingExposure = 1.5;
-				renderer.inspector = new Inspector();
-				document.body.appendChild( renderer.domElement );
+				}
+
+				spheresMesh.count = i;
 
 				// controls
 
 				controls = new OrbitControls( camera, renderer.domElement );
-				controls.target.set( 0, 5, 0 );
-				controls.maxDistance = 60;
+				controls.enableDamping = true;
+				controls.target.set( 0, 6, 0 );
+				controls.maxPolarAngle = Math.PI * 0.49;
+				controls.minDistance = 4;
+				controls.maxDistance = 400;
 				controls.update();
 
-				// events
-
-				window.addEventListener( 'resize', onWindowResize );
-
-				// post processing
+				// post-processing: a debug overlay that tints each screen tile by how many
+				// lights its cluster holds, for the selected depth slice
 
 				scenePass = pass( scene, camera );
 				clusterInfluence = uniform( 0 );
 
-				renderPipeline = new THREE.RenderPipeline( renderer );
+				// the large far plane spreads the exponential z-slices out, so the orb
+				// field falls around slices 7–11; default into that range
+				debugZSliceNode = uniform( 10, 'int' );
 
-				debugZSliceNode = uniform( 15, 'int' );
+				renderPipeline = new THREE.RenderPipeline( renderer );
 
 				updatePostProcessing();
 
 				// gui
 
 				const gui = renderer.inspector.createParameters( 'Settings' );
+				gui.add( params, 'intensity', 0, 3 ).name( 'light intensity' ).onChange( ( value ) => {
 
-				const params = {
-					count
-				};
+					for ( const ball of balls ) ball.light.power = BASE_POWER * value;
 
-				gui.add( params, 'count', 0, maxCount, 1 ).name( 'light count' ).onChange( ( value ) => {
+				} );
+				gui.add( params, 'animate' );
+				gui.add( clusterInfluence, 'value', 0, .7 ).name( 'lights per tile' );
+				gui.add( debugZSliceNode, 'value', 0, lighting.zSlices - 1, 1 ).name( 'z-slice' );
 
-					lightDummy.count = value;
+				// events
 
-					for ( let i = 0; i < lights.children.length; i ++ ) {
+				window.addEventListener( 'resize', onWindowResize );
 
-						lights.children[ i ].visible = ( i < value );
+			}
 
-					}
+			function onWindowResize() {
 
-				} );
+				camera.aspect = window.innerWidth / window.innerHeight;
+				camera.updateProjectionMatrix();
 
-				gui.add( clusterInfluence, 'value', 0, .7 ).name( 'lights per tile' );
-				gui.add( debugZSliceNode, 'value', 0, lighting.zSlices - 1, 1 ).name( 'z-slice' );
+				renderer.setSize( window.innerWidth, window.innerHeight );
+
+				updatePostProcessing();
 
 			}
 
 			function updatePostProcessing() {
 
-				// cluster light count debug overlay; needs to be updated every time the renderer size changes
+				// the overlay samples the cluster grid at the current resolution, so it
+				// is rebuilt whenever the renderer size changes
 
 				const lightingNode = lighting.getNode( scene ).setSize( window.innerWidth * window.devicePixelRatio, window.innerHeight * window.devicePixelRatio );
 
-				// Calculate a color mapping based on the actual number of lights directly affecting the cluster.
-				// We map between 0 and maxLightsPerCluster to a gradient
+				// map the light count of each cluster ( 0 … maxLightsPerCluster ) to a
+				// blue → green → red gradient
 				const lightCount = lightingNode.getClusterLightCount( debugZSliceNode );
 				const heatmap = float( lightCount ).div( float( lighting.maxLightsPerCluster ) );
 
-				// Gradient mapping: Blue (0.0) -> Green (0.5) -> Red (1.0)
 				let heatColor = mix( vec3( 0.0, 0.0, 1.0 ), vec3( 0.0, 1.0, 0.0 ), heatmap.mul( 2.0 ).saturate() );
 				heatColor = mix( heatColor, vec3( 1.0, 0.0, 0.0 ), heatmap.sub( 0.5 ).mul( 2.0 ).saturate() );
 
-				// Blend the heatmap over the original scene based on the slider value
-				// The `step` drops opacity to 0.0 if there are strictly no lights in the cluster
+				// blend the heatmap over the scene by the slider amount; step() keeps
+				// empty clusters transparent
 				const finalInfluence = clusterInfluence.mul( step( 0.0001, heatmap ) );
 				renderPipeline.outputNode = mix( scenePass, heatColor, finalInfluence );
 				renderPipeline.needsUpdate = true;
 
 			}
 
-			async function getSponzaModelURL() {
-
-				const response = await fetch( MODEL_INDEX_URL );
-				const models = await response.json();
-				const sponzaInfo = models.find( ( model ) => model.name === 'Sponza' );
-
-				if ( ! sponzaInfo ) {
-
-					throw new Error( 'Sponza entry was not found in the glTF sample model index.' );
-
-				}
-
-				const variants = sponzaInfo.variants || {};
-				const variantName = variants[ 'glTF-Binary' ] || variants[ 'glTF' ] || variants[ 'glTF-Embedded' ] || Object.values( variants )[ 0 ];
-
-				if ( ! variantName ) {
-
-					throw new Error( 'Sponza has no supported glTF variant in the model index.' );
-
-				}
-
-				const variantFolder = variantName.endsWith( '.glb' ) ? 'glTF-Binary' : 'glTF';
-				return `${ SAMPLE_ASSETS_BASE_URL }${ sponzaInfo.name }/${ variantFolder }/${ variantName }`;
-
-			}
-
-			function onWindowResize() {
-
-				camera.aspect = window.innerWidth / window.innerHeight;
-				camera.updateProjectionMatrix();
+			function animate() {
 
-				renderer.setSize( window.innerWidth, window.innerHeight );
+				if ( params.animate === true ) {
 
-				updatePostProcessing();
+					const time = performance.now() / 1000;
 
-			}
+					for ( let i = 0; i < balls.length; i ++ ) {
 
-			function animate() {
-
-				const time = performance.now() / 1000;
-				const positions = lightPositionAttribute.array;
+						const ball = balls[ i ];
+						const y = RADIUS + ( 0.5 + 0.5 * Math.sin( time * 1.5 + ball.phase ) ) * WAVE_HEIGHT;
 
-				for ( let i = 0; i < lights.children.length; i ++ ) {
+						dummy.position.set( ball.x, y, ball.z );
+						dummy.updateMatrix();
+						spheresMesh.setMatrixAt( i, dummy.matrix );
 
-					const light = lights.children[ i ];
-					const lightTime = ( time * 0.5 ) + light.id;
+						ball.light.position.y = y;
 
-					light.position.copy( light.userData.fixedPosition );
-					light.position.x += Math.sin( lightTime * 0.7 ) * 1.5;
-					light.position.y += Math.cos( lightTime * 0.5 ) * .3;
-					light.position.z += Math.cos( lightTime * 0.3 ) * 1.5;
+					}
 
-					positions[ i * 3 + 0 ] = light.position.x;
-					positions[ i * 3 + 1 ] = light.position.y;
-					positions[ i * 3 + 2 ] = light.position.z;
+					spheresMesh.instanceMatrix.needsUpdate = true;
 
 				}
 
-				lightPositionAttribute.needsUpdate = true;
+				controls.update();
 
 				renderPipeline.render();
 

+ 0 - 26
src/materials/nodes/Line2NodeMaterial.js

@@ -620,32 +620,6 @@ class Line2NodeMaterial extends NodeMaterial {
 
 	}
 
-	/**
-	 * Copies the properties of the given material to this instance.
-	 *
-	 * @param {Line2NodeMaterial} source - The material to copy.
-	 * @return {Line2NodeMaterial} A reference to this material.
-	 */
-	copy( source ) {
-
-		super.copy( source );
-
-		this.vertexColors = source.vertexColors;
-		this.dashOffset = source.dashOffset;
-
-		this.offsetNode = source.offsetNode;
-		this.dashScaleNode = source.dashScaleNode;
-		this.dashSizeNode = source.dashSizeNode;
-		this.gapSizeNode = source.gapSizeNode;
-
-		this._useDash = source._useDash;
-		this._useAlphaToCoverage = source._useAlphaToCoverage;
-		this._useWorldUnits = source._useWorldUnits;
-
-		return this;
-
-	}
-
 }
 
 export default Line2NodeMaterial;

+ 0 - 9
src/materials/nodes/MeshPhongNodeMaterial.js

@@ -127,15 +127,6 @@ class MeshPhongNodeMaterial extends NodeMaterial {
 
 	}
 
-	copy( source ) {
-
-		this.shininessNode = source.shininessNode;
-		this.specularNode = source.specularNode;
-
-		return super.copy( source );
-
-	}
-
 }
 
 export default MeshPhongNodeMaterial;

+ 0 - 30
src/materials/nodes/MeshPhysicalNodeMaterial.js

@@ -486,36 +486,6 @@ class MeshPhysicalNodeMaterial extends MeshStandardNodeMaterial {
 
 	}
 
-	copy( source ) {
-
-		this.clearcoatNode = source.clearcoatNode;
-		this.clearcoatRoughnessNode = source.clearcoatRoughnessNode;
-		this.clearcoatNormalNode = source.clearcoatNormalNode;
-
-		this.sheenNode = source.sheenNode;
-		this.sheenRoughnessNode = source.sheenRoughnessNode;
-
-		this.iridescenceNode = source.iridescenceNode;
-		this.iridescenceIORNode = source.iridescenceIORNode;
-		this.iridescenceThicknessNode = source.iridescenceThicknessNode;
-
-		this.specularIntensityNode = source.specularIntensityNode;
-		this.specularColorNode = source.specularColorNode;
-
-		this.iorNode = source.iorNode;
-
-		this.transmissionNode = source.transmissionNode;
-		this.thicknessNode = source.thicknessNode;
-		this.attenuationDistanceNode = source.attenuationDistanceNode;
-		this.attenuationColorNode = source.attenuationColorNode;
-		this.dispersionNode = source.dispersionNode;
-
-		this.anisotropyNode = source.anisotropyNode;
-
-		return super.copy( source );
-
-	}
-
 }
 
 export default MeshPhysicalNodeMaterial;

+ 0 - 13
src/materials/nodes/MeshSSSNodeMaterial.js

@@ -157,19 +157,6 @@ class MeshSSSNodeMaterial extends MeshPhysicalNodeMaterial {
 
 	}
 
-	copy( source ) {
-
-		this.thicknessColorNode = source.thicknessColorNode;
-		this.thicknessDistortionNode = source.thicknessDistortionNode;
-		this.thicknessAmbientNode = source.thicknessAmbientNode;
-		this.thicknessAttenuationNode = source.thicknessAttenuationNode;
-		this.thicknessPowerNode = source.thicknessPowerNode;
-		this.thicknessScaleNode = source.thicknessScaleNode;
-
-		return super.copy( source );
-
-	}
-
 }
 
 export default MeshSSSNodeMaterial;

+ 0 - 11
src/materials/nodes/MeshStandardNodeMaterial.js

@@ -171,17 +171,6 @@ class MeshStandardNodeMaterial extends NodeMaterial {
 
 	}
 
-	copy( source ) {
-
-		this.emissiveNode = source.emissiveNode;
-
-		this.metalnessNode = source.metalnessNode;
-		this.roughnessNode = source.roughnessNode;
-
-		return super.copy( source );
-
-	}
-
 }
 
 export default MeshStandardNodeMaterial;

+ 68 - 28
src/materials/nodes/NodeMaterial.js

@@ -1157,6 +1157,26 @@ class NodeMaterial extends Material {
 	/**
 	 * Setups the output node.
 	 *
+	 * This method can be implemented by derived materials to extend the functionality
+	 * of the material's output or replace it altogether.
+	 *
+	 * ```js
+	 * class ColoredShadowMaterial extends MeshPhongNodeMaterial {
+	 *   constructor( parameters ) {
+	 *     super( parameters );
+	 *     this._shadeColor = uniform( new Color( parameters.shadeColor ?? 0xff0000 ) );
+	 *   }
+	 *
+	 *   setupOutput( builder, outputNode ) {
+	 *	   // Modify the native output of the MeshPhongNodeMaterial fragment shader
+	 *     const brightness = min( outputNode.r, 1.0 );
+	 *     const mixedColor = mix( this._shadeColor, diffuseColor.rgb, brightness );
+	 *	   // Return new output back into NodeMaterial flow
+	 *     return super.setupOutput( builder, vec4( mixedColor, outputNode.a ) );
+	 *   }
+	 * }
+	 * ```
+	 *
 	 * @param {NodeBuilder} builder - The current node builder.
 	 * @param {Node<vec4>} outputNode - The existing output node.
 	 * @return {Node<vec4>} The output node.
@@ -1213,8 +1233,7 @@ class NodeMaterial extends Material {
 
 		for ( const key in descriptors ) {
 
-			if ( Object.getOwnPropertyDescriptor( this.constructor.prototype, key ) === undefined &&
-			     descriptors[ key ].get !== undefined ) {
+			if ( Object.getOwnPropertyDescriptor( this.constructor.prototype, key ) === undefined && descriptors[ key ].get !== undefined ) {
 
 				Object.defineProperty( this.constructor.prototype, key, descriptors[ key ] );
 
@@ -1288,44 +1307,65 @@ class NodeMaterial extends Material {
 	}
 
 	/**
-	 * Copies the properties of the given node material to this instance.
+	 * Copies the common properties of the given material to this instance.
 	 *
-	 * @param {NodeMaterial} source - The material to copy.
+	 * @param {Material} source - The material to copy.
 	 * @return {NodeMaterial} A reference to this node material.
 	 */
 	copy( source ) {
 
-		this.lightsNode = source.lightsNode;
-		this.envNode = source.envNode;
-		this.aoNode = source.aoNode;
+		const descriptors = Object.getOwnPropertyDescriptors( this.constructor.prototype );
+
+		for ( const property in descriptors ) {
 
-		this.colorNode = source.colorNode;
-		this.normalNode = source.normalNode;
-		this.opacityNode = source.opacityNode;
-		this.backdropNode = source.backdropNode;
-		this.backdropAlphaNode = source.backdropAlphaNode;
-		this.alphaTestNode = source.alphaTestNode;
-		this.maskNode = source.maskNode;
-		this.maskShadowNode = source.maskShadowNode;
+			if ( descriptors[ property ].set !== undefined && source[ property ] !== undefined ) {
 
-		this.positionNode = source.positionNode;
-		this.geometryNode = source.geometryNode;
+				const value = source[ property ];
+
+				if ( this[ property ] && this[ property ].copy !== undefined ) {
+
+					this[ property ].copy( value );
+
+				} else {
+
+					this[ property ] = value;
+
+				}
+
+			}
+
+		}
 
-		this.depthNode = source.depthNode;
-		this.receivedShadowPositionNode = source.receivedShadowPositionNode;
-		this.castShadowPositionNode = source.castShadowPositionNode;
-		this.receivedShadowNode = source.receivedShadowNode;
-		this.castShadowNode = source.castShadowNode;
+		for ( const property in this ) {
 
-		this.outputNode = source.outputNode;
-		this.mrtNode = source.mrtNode;
+			// Skip internal/private properties (starting with '_'), flags (starting with 'is' + uppercase),
+			// and properties that are handled separately or should not be copied (id, uuid, version, type, userData, clippingPlanes).
+
+			if ( /^(?:is[A-Z]|_)|^(?:id|uuid|version|type|userData|clippingPlanes)$/.test( property ) ) continue;
+
+			if ( this[ property ] !== undefined && source[ property ] !== undefined ) {
+
+				const value = source[ property ];
+
+				if ( this[ property ] && this[ property ].copy !== undefined ) {
+
+					this[ property ].copy( value );
+
+				} else {
+
+					this[ property ] = value;
+
+				}
+
+			}
+
+		}
 
-		this.fragmentNode = source.fragmentNode;
-		this.vertexNode = source.vertexNode;
+		this.clippingPlanes = source.clippingPlanes ? source.clippingPlanes.map( ( plane ) => plane.clone() ) : null;
 
-		this.contextNode = source.contextNode;
+		this.userData = JSON.parse( JSON.stringify( source.userData ) );
 
-		return super.copy( source );
+		return this;
 
 	}
 

+ 0 - 10
src/materials/nodes/SpriteNodeMaterial.js

@@ -148,16 +148,6 @@ class SpriteNodeMaterial extends NodeMaterial {
 
 	}
 
-	copy( source ) {
-
-		this.positionNode = source.positionNode;
-		this.rotationNode = source.rotationNode;
-		this.scaleNode = source.scaleNode;
-
-		return super.copy( source );
-
-	}
-
 	/**
 	 * Whether to use size attenuation or not.
 	 *

+ 5 - 1
src/nodes/accessors/Position.js

@@ -33,7 +33,11 @@ export const clipSpace = /*@__PURE__*/ ( Fn( ( builder ) => {
 export const positionGeometry = /*@__PURE__*/ attribute( 'position', 'vec3' );
 
 /**
- * TSL object that represents the vertex position in local space of the current rendered object.
+ * TSL object that represents the transformed vertex position in local space of the current rendered object.
+ *
+ * The term "transformed" indicates that an object or material's properties, such as skinning, batch,
+ * instancing, or displacement mapping, will change the vertex position of the node when present.
+ * To use the pre-transformed local space position of the object, use {@link positionGeometry}.
  *
  * @tsl
  * @type {AttributeNode<vec3>}

+ 30 - 17
src/nodes/core/OverrideContextNode.js

@@ -2,11 +2,16 @@ import ContextNode from './ContextNode.js';
 import { addMethodChaining } from '../tsl/TSLCore.js';
 
 /**
- * A context node that overrides a target node within another node using a callback function.
+ * A specialized context node designed to override specific target nodes within a
+ * node sub-graph or flow. This allows replacing specific inputs (e.g., normal
+ * and position vectors) dynamically during compilation for a specific flow node,
+ * without having to reconstruct or duplicate the source nodes.
  *
  * ```js
+ * // Method chaining example:
  * node.overrideNode( positionLocal, () => positionLocal.add( vec3( 1, 0, 0 ) ) );
- * // or
+ *
+ * // Context assignment example:
  * material.contextNode = overrideNode( positionLocal, () => positionLocal.add( vec3( 1, 0, 0 ) ) );
  * ```
  *
@@ -14,6 +19,13 @@ import { addMethodChaining } from '../tsl/TSLCore.js';
  */
 class OverrideContextNode extends ContextNode {
 
+	/**
+	 * Returns the type of the node.
+	 *
+	 * @type {string}
+	 * @readonly
+	 * @static
+	 */
 	static get type() {
 
 		return 'OverrideContextNode';
@@ -23,8 +35,8 @@ class OverrideContextNode extends ContextNode {
 	/**
 	 * Constructs a new override context node.
 	 *
-	 * @param {Map<Node, Function>} overrideNodes - A map containing target nodes to override and their respective override callback functions.
-	 * @param {Node} [flowNode=null] - The node whose context should be modified.
+	 * @param {Map<Node, Function>} overrideNodes - A map mapping target nodes to their respective override callback functions.
+	 * @param {Node|null} [flowNode=null] - The node whose context should be modified.
 	 */
 	constructor( overrideNodes, flowNode = null ) {
 
@@ -44,9 +56,10 @@ class OverrideContextNode extends ContextNode {
 	}
 
 	/**
-	 * Gathers the context data from all parent context nodes.
+	 * Gathers the context data from all parent context nodes by traversing the hierarchy,
+	 * merging the `overrideNodes` maps from all encountered `OverrideContextNode` instances.
 	 *
-	 * @return {Object} The gathered context data.
+	 * @return {Object} The gathered context data, containing the merged `overrideNodes` map.
 	 */
 	getFlowContextData() {
 
@@ -76,18 +89,18 @@ class OverrideContextNode extends ContextNode {
 export default OverrideContextNode;
 
 /**
- * Creates an OverrideContextNode that overrides a target node within a callback function.
+ * TSL function for creating an `OverrideContextNode` to override a single target node.
  *
  * ```js
- * material.contextNode = overrideNode( positionLocal, () => positionLocal.add( vec3( 1, 0, 0 ) ) );
+ * material.contextNode = overrideNode( positionLocal, ( builder ) => positionLocal.add( vec3( 1, 0, 0 ) ) );
  * ```
  *
  * @tsl
  * @function
- * @param {Node} targetNode - The target node to override.
- * @param {Function|Node} [callback=null] - A callback function that returns the overriding node, or the overriding node itself.
- * @param {Node} [flowNode=null] - An optional flow node.
- * @return {OverrideContextNode} The created OverrideContextNode.
+ * @param {Node} targetNode - The target node that should be overridden.
+ * @param {Function|Node|null} [callback=null] - A callback function returning the overriding node (which receives the builder as its argument), or the overriding node itself.
+ * @param {Node|null} [flowNode=null] - The node whose context should be modified.
+ * @return {OverrideContextNode} The created override context node.
  */
 export function overrideNode( targetNode, callback = null, flowNode = null ) {
 
@@ -106,20 +119,20 @@ export function overrideNode( targetNode, callback = null, flowNode = null ) {
 addMethodChaining( 'overrideNode', ( flowNode, node, callback ) => overrideNode( node, callback, flowNode ) );
 
 /**
- * Creates an OverrideContextNode that overrides multiple target nodes.
+ * TSL function for creating an `OverrideContextNode` to override multiple target nodes.
  *
  * ```js
  * material.contextNode = overrideNodes( [
  * 	[ positionView, customPositionView ],
- * 	[ positionViewDirection, customPositionViewDirection ]
+ * 	[ positionViewDirection, ( builder ) => customPositionViewDirection ]
  * ] );
  * ```
  *
  * @tsl
  * @function
- * @param {Map|Array} overrides - The overrides mapping target nodes to callback functions or overriding nodes.
- * @param {Node} [flowNode=null] - An optional flow node.
- * @return {OverrideContextNode} The created OverrideContextNode.
+ * @param {Map<Node, (Function|Node)>|Array<Array<Node|Function|Node>>} overrides - The overrides mapping target nodes to callback functions or overriding nodes.
+ * @param {Node|null} [flowNode=null] - The node whose context should be modified.
+ * @return {OverrideContextNode} The created override context node.
  */
 export function overrideNodes( overrides, flowNode = null ) {
 

+ 2 - 2
src/nodes/lighting/ShadowNode.js

@@ -48,7 +48,7 @@ export const getShadowRenderObjectFunction = ( renderer, shadow, shadowType, use
 
 	if ( renderObjectFunction === undefined || ( renderObjectFunction.shadowType !== shadowType || renderObjectFunction.useVelocity !== useVelocity ) ) {
 
-		renderObjectFunction = ( object, scene, _camera, geometry, material, group, ...params ) => {
+		renderObjectFunction = ( object, scene, _camera, geometry, material, group, lightsNode, clippingContext, passId ) => {
 
 			if ( object.castShadow === true || ( object.receiveShadow && shadowType === VSMShadowMap ) ) {
 
@@ -60,7 +60,7 @@ export const getShadowRenderObjectFunction = ( renderer, shadow, shadowType, use
 
 				object.onBeforeShadow( renderer, object, _camera, shadow.camera, geometry, scene.overrideMaterial, group );
 
-				renderer.renderObject( object, scene, _camera, geometry, material, group, ...params );
+				renderer.renderObject( object, scene, _camera, geometry, material, group, lightsNode, clippingContext, passId );
 
 				object.onAfterShadow( renderer, object, _camera, shadow.camera, geometry, scene.overrideMaterial, group );
 

+ 15 - 7
src/renderers/common/RenderObject.js

@@ -1,37 +1,45 @@
 import { hash, hashString } from '../../nodes/core/NodeUtils.js';
 
 let _id = 0;
+const _protoKeysCache = new WeakMap();
 
 function getKeys( obj ) {
 
 	const keys = Object.keys( obj );
 
-	let proto = Object.getPrototypeOf( obj );
+	let protoKeys = _protoKeysCache.get( obj.constructor );
 
-	while ( proto ) {
+	if ( protoKeys === undefined ) {
 
-		const descriptors = Object.getOwnPropertyDescriptors( proto );
+		protoKeys = [];
+		let proto = Object.getPrototypeOf( obj );
 
-		for ( const key in descriptors ) {
+		while ( proto ) {
 
-			if ( descriptors[ key ] !== undefined ) {
+			const descriptors = Object.getOwnPropertyDescriptors( proto );
+
+			for ( const key in descriptors ) {
 
 				const descriptor = descriptors[ key ];
 
 				if ( descriptor && typeof descriptor.get === 'function' ) {
 
-					keys.push( key );
+					protoKeys.push( key );
 
 				}
 
 			}
 
+			proto = Object.getPrototypeOf( proto );
+
 		}
 
-		proto = Object.getPrototypeOf( proto );
+		_protoKeysCache.set( obj.constructor, protoKeys );
 
 	}
 
+	for ( let i = 0; i < protoKeys.length; i ++ ) keys.push( protoKeys[ i ] );
+
 	return keys;
 
 }

+ 1 - 2
src/renderers/common/Renderer.js

@@ -1036,12 +1036,11 @@ class Renderer {
 			renderObject.drawRange = item.object.geometry.drawRange;
 			renderObject.group = item.group;
 
-			this._geometries.updateForRender( renderObject );
-
 			// Use async node building to yield to main thread
 			await this._nodes.getForRenderAsync( renderObject );
 
 			this._nodes.updateBefore( renderObject );
+			this._geometries.updateForRender( renderObject );
 			this._nodes.updateForRender( renderObject );
 			this._bindings.updateForRender( renderObject );
 

+ 7 - 1
src/renderers/common/nodes/NodeManager.js

@@ -3,7 +3,7 @@ import ChainMap from '../ChainMap.js';
 import NodeBuilderState from './NodeBuilderState.js';
 import NodeMaterial from '../../../materials/nodes/NodeMaterial.js';
 import { cubeMapNode } from '../../../nodes/utils/CubeMapNode.js';
-import { NodeFrame, StackTrace } from '../../../nodes/Nodes.js';
+import { NodeFrame, NodeUpdateType, StackTrace } from '../../../nodes/Nodes.js';
 import { renderGroup, cubeTexture, texture, fog, rangeFogFactor, densityFogFactor, reference, pmremTexture, screenUV, uniform } from '../../../nodes/TSL.js';
 import { builtin } from '../../../nodes/accessors/BuiltinNode.js';
 
@@ -115,6 +115,12 @@ class NodeManager extends DataMap {
 
 		const groupNode = nodeUniformsGroup.groupNode;
 
+		// groups that are updated per object always require an update so no further checks are needed
+
+		if ( groupNode.updateType === NodeUpdateType.OBJECT ) return true;
+
+		// check for update
+
 		_chainKeys[ 0 ] = groupNode;
 		_chainKeys[ 1 ] = nodeUniformsGroup;
 

+ 13 - 1
src/renderers/webgl-fallback/utils/WebGLTextureUtils.js

@@ -638,7 +638,19 @@ class WebGLTextureUtils {
 
 			if ( typeof gl.texElementImage2D === 'function' ) {
 
-				gl.texElementImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, options.image );
+				if ( gl.texElementImage2D.length === 3 ) {
+
+					// Chrome 150+
+
+					gl.texElementImage2D( gl.TEXTURE_2D, gl.RGBA8, options.image );
+
+				} else {
+
+					// Chrome 138 - 149
+
+					gl.texElementImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, options.image );
+
+				}
 
 			}
 

+ 18 - 5
src/renderers/webgl/WebGLTextures.js

@@ -1295,12 +1295,25 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 					}
 
-					const level = 0;
-					const internalFormat = _gl.RGBA;
-					const srcFormat = _gl.RGBA;
-					const srcType = _gl.UNSIGNED_BYTE;
+					if ( _gl.texElementImage2D.length === 3 ) {
+
+						// Chrome 150+
+
+						_gl.texElementImage2D( _gl.TEXTURE_2D, _gl.RGBA8, image );
+
+					} else {
+
+						// Chrome 138 - 149
+
+						const level = 0;
+						const internalFormat = _gl.RGBA;
+						const srcFormat = _gl.RGBA;
+						const srcType = _gl.UNSIGNED_BYTE;
+
+						_gl.texElementImage2D( _gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image );
+
+					}
 
-					_gl.texElementImage2D( _gl.TEXTURE_2D, level, internalFormat, srcFormat, srcType, image );
 					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.LINEAR );
 					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
 					_gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );

+ 24 - 5
src/renderers/webgpu/WebGPUBackend.js

@@ -1578,6 +1578,7 @@ class WebGPUBackend extends Backend {
 
 		groupGPU.cmdEncoderGPU = this.device.createCommandEncoder( _commandEncoderDescriptor );
 		groupGPU.passEncoderGPU = groupGPU.cmdEncoderGPU.beginComputePass( _computePassDescriptor );
+		groupGPU.currentPipeline = null;
 
 		_commandEncoderDescriptor.reset();
 		_computePassDescriptor.reset();
@@ -1599,13 +1600,19 @@ class WebGPUBackend extends Backend {
 	compute( computeGroup, computeNode, bindings, pipeline, dispatchSize = null ) {
 
 		const computeNodeData = this.get( computeNode );
-		const { passEncoderGPU } = this.get( computeGroup );
+		const groupGPU = this.get( computeGroup );
+		const { passEncoderGPU } = groupGPU;
 
 		// pipeline
 
 		const pipelineGPU = this.get( pipeline ).pipeline;
 
-		this.pipelineUtils.setPipeline( passEncoderGPU, pipelineGPU );
+		if ( groupGPU.currentPipeline !== pipelineGPU ) {
+
+			passEncoderGPU.setPipeline( pipelineGPU );
+			groupGPU.currentPipeline = pipelineGPU;
+
+		}
 
 		// bind groups
 
@@ -1727,17 +1734,26 @@ class WebGPUBackend extends Backend {
 		const hasIndex = ( index !== null );
 
 		// pipeline
-		this.pipelineUtils.setPipeline( passEncoderGPU, pipelineGPU );
-		currentSets.pipeline = pipelineGPU;
+
+		if ( currentSets.pipeline !== pipelineGPU ) {
+
+			passEncoderGPU.setPipeline( pipelineGPU );
+			currentSets.pipeline = pipelineGPU;
+
+		}
 
 		// bind groups
+
 		const currentBindingGroups = currentSets.bindingGroups;
+
 		for ( let i = 0, l = bindings.length; i < l; i ++ ) {
 
 			const bindGroup = bindings[ i ];
-			const bindingsData = this.get( bindGroup );
+
 			if ( currentBindingGroups[ i ] !== bindGroup.id ) {
 
+				const bindingsData = this.get( bindGroup );
+
 				passEncoderGPU.setBindGroup( i, bindingsData.group );
 				currentBindingGroups[ i ] = bindGroup.id;
 
@@ -2042,6 +2058,7 @@ class WebGPUBackend extends Backend {
 		const colorFormat = utils.getCurrentColorFormat( renderObject.context );
 		const depthStencilFormat = utils.getCurrentDepthStencilFormat( renderObject.context );
 		const primitiveTopology = utils.getPrimitiveTopology( object, material );
+		const frontFaceCW = ( object.isMesh && object.matrixWorld.determinant() < 0 );
 
 		let needsUpdate = false;
 
@@ -2057,6 +2074,7 @@ class WebGPUBackend extends Backend {
 			data.sampleCount !== sampleCount || data.colorSpace !== colorSpace ||
 			data.colorFormat !== colorFormat || data.depthStencilFormat !== depthStencilFormat ||
 			data.primitiveTopology !== primitiveTopology ||
+			data.frontFaceCW !== frontFaceCW ||
 			data.clippingContextCacheKey !== renderObject.clippingContextCacheKey
 		) {
 
@@ -2075,6 +2093,7 @@ class WebGPUBackend extends Backend {
 			data.colorFormat = colorFormat;
 			data.depthStencilFormat = depthStencilFormat;
 			data.primitiveTopology = primitiveTopology;
+			data.frontFaceCW = frontFaceCW;
 			data.clippingContextCacheKey = renderObject.clippingContextCacheKey;
 
 			needsUpdate = true;

+ 65 - 17
src/renderers/webgpu/utils/WebGPUAttributeUtils.js

@@ -108,25 +108,55 @@ class WebGPUAttributeUtils {
 
 			bufferAttribute.array = array;
 
+			let paddedItemSize;
+
 			if ( ( bufferAttribute.isStorageBufferAttribute || bufferAttribute.isStorageInstancedBufferAttribute ) && bufferAttribute.itemSize === 3 ) {
 
-				array = new array.constructor( bufferAttribute.count * 4 );
+				// WGSL does not support packed vec3 data in storage buffers, pad to vec4
+
+				paddedItemSize = 4;
+
+			} else if ( bufferAttribute.itemSize > 1 && ( bufferAttribute.itemSize * array.BYTES_PER_ELEMENT ) % 4 !== 0 ) {
+
+				// arrayStride must be a multiple of 4
+
+				const byteStride = bufferAttribute.itemSize * array.BYTES_PER_ELEMENT;
+
+				paddedItemSize = ( Math.floor( ( byteStride + 3 ) / 4 ) * 4 ) / array.BYTES_PER_ELEMENT;
+
+			}
+
+			if ( paddedItemSize !== undefined ) {
+
+				const itemSize = bufferAttribute.itemSize;
+
+				const paddedArray = new array.constructor( bufferAttribute.count * paddedItemSize );
 
 				for ( let i = 0; i < bufferAttribute.count; i ++ ) {
 
-					array.set( bufferAttribute.array.subarray( i * 3, i * 3 + 3 ), i * 4 );
+					paddedArray.set( array.subarray( i * itemSize, i * itemSize + itemSize ), i * paddedItemSize );
 
 				}
 
-				// Update BufferAttribute
-				bufferAttribute.itemSize = 4;
-				bufferAttribute.array = array;
+				if ( bufferAttribute.isStorageBufferAttribute || bufferAttribute.isStorageInstancedBufferAttribute ) {
+
+					// update the storage attribute so storage bindings access the padded layout
+
+					bufferAttribute.itemSize = paddedItemSize;
+					bufferAttribute.array = paddedArray;
+
+				}
 
-				bufferData._force3to4BytesAlignment = true;
+				array = paddedArray;
+
+				// save the original and padded item size so buffer updates can apply the same padding
+
+				bufferData._itemSize = itemSize;
+				bufferData._paddedItemSize = paddedItemSize;
 
 			}
 
-			// ensure 4 byte alignment
+			// total buffer size must be a multiple of 4
 			const byteLength = array.byteLength;
 			const size = byteLength + ( ( 4 - ( byteLength % 4 ) ) % 4 );
 
@@ -166,18 +196,28 @@ class WebGPUAttributeUtils {
 
 		let array = bufferAttribute.array;
 
-		//  if storage buffer ensure 4 byte alignment
-		if ( bufferData._force3to4BytesAlignment === true ) {
+		const itemSize = bufferData._itemSize;
+		const paddedItemSize = bufferData._paddedItemSize;
+
+		if ( paddedItemSize !== undefined ) {
+
+			// if the attribute data were padded on upload, apply the same padding on updates.
 
-			array = new array.constructor( bufferAttribute.count * 4 );
+			array = new array.constructor( bufferAttribute.count * paddedItemSize );
 
 			for ( let i = 0; i < bufferAttribute.count; i ++ ) {
 
-				array.set( bufferAttribute.array.subarray( i * 3, i * 3 + 3 ), i * 4 );
+				array.set( bufferAttribute.array.subarray( i * itemSize, i * itemSize + itemSize ), i * paddedItemSize );
 
 			}
 
-			bufferAttribute.array = array;
+			if ( bufferAttribute.isStorageBufferAttribute || bufferAttribute.isStorageInstancedBufferAttribute ) {
+
+				// keep the storage attribute in sync with the padded layout
+
+				bufferAttribute.array = array;
+
+			}
 
 		}
 
@@ -205,12 +245,12 @@ class WebGPUAttributeUtils {
 				const range = updateRanges[ i ];
 				let dataOffset, size;
 
-				if ( bufferData._force3to4BytesAlignment === true ) {
+				if ( paddedItemSize !== undefined ) {
 
-					const vertexStart = Math.floor( range.start / 3 );
-					const vertexCount = Math.ceil( range.count / 3 );
-					dataOffset = vertexStart * 4 * byteOffsetFactor;
-					size = vertexCount * 4 * byteOffsetFactor;
+					const vertexStart = Math.floor( range.start / itemSize );
+					const vertexCount = Math.ceil( ( range.start + range.count ) / itemSize ) - vertexStart;
+					dataOffset = vertexStart * paddedItemSize * byteOffsetFactor;
+					size = vertexCount * paddedItemSize * byteOffsetFactor;
 
 				} else {
 
@@ -271,6 +311,14 @@ class WebGPUAttributeUtils {
 					arrayStride = geometryAttribute.itemSize * bytesPerElement;
 					stepMode = geometryAttribute.isInstancedBufferAttribute ? GPUInputStepMode.Instance : GPUInputStepMode.Vertex;
 
+					if ( geometryAttribute.itemSize > 1 && arrayStride % 4 !== 0 ) {
+
+						// packed attribute data are padded per vertex on upload
+
+						arrayStride = Math.floor( ( arrayStride + 3 ) / 4 ) * 4;
+
+					}
+
 				}
 
 				// patch for INT16 and UINT16

+ 18 - 32
src/renderers/webgpu/utils/WebGPUPipelineUtils.js

@@ -48,35 +48,6 @@ class WebGPUPipelineUtils {
 		 */
 		this.backend = backend;
 
-		/**
-		 * A Weak Map that tracks the active pipeline for render or compute passes.
-		 *
-		 * @private
-		 * @type {WeakMap<(GPURenderPassEncoder|GPUComputePassEncoder),(GPURenderPipeline|GPUComputePipeline)>}
-		 */
-		this._activePipelines = new WeakMap();
-
-	}
-
-	/**
-	 * Sets the given pipeline for the given pass. The method makes sure to only set the
-	 * pipeline when necessary.
-	 *
-	 * @param {(GPURenderPassEncoder|GPUComputePassEncoder)} pass - The pass encoder.
-	 * @param {(GPURenderPipeline|GPUComputePipeline)} pipeline - The pipeline.
-	 */
-	setPipeline( pass, pipeline ) {
-
-		const currentPipeline = this._activePipelines.get( pass );
-
-		if ( currentPipeline !== pipeline ) {
-
-			pass.setPipeline( pipeline );
-
-			this._activePipelines.set( pass, pipeline );
-
-		}
-
 	}
 
 	/**
@@ -314,10 +285,11 @@ class WebGPUPipelineUtils {
 				try {
 
 					let asyncError = null;
+					let pipelinePromise = null;
 
 					try {
 
-						pipelineData.pipeline = await device.createRenderPipelineAsync( _renderPipelineDescriptor );
+						pipelinePromise = device.createRenderPipelineAsync( _renderPipelineDescriptor );
 
 					} catch ( err ) {
 
@@ -325,6 +297,22 @@ class WebGPUPipelineUtils {
 
 					}
 
+					_renderPipelineDescriptor.reset();
+
+					if ( pipelinePromise !== null ) {
+
+						try {
+
+							pipelineData.pipeline = await pipelinePromise;
+
+						} catch ( err ) {
+
+							asyncError = err;
+
+						}
+
+					}
+
 					const errorScope = await device.popErrorScope();
 
 					if ( errorScope !== null || asyncError !== null ) {
@@ -340,8 +328,6 @@ class WebGPUPipelineUtils {
 
 				} finally {
 
-					_renderPipelineDescriptor.reset();
-
 					// Guarantee resolution so `compileAsync`'s Promise.all cannot hang on an
 					// unexpected throw from any await above.
 					resolve();

+ 23 - 4
src/renderers/webgpu/utils/WebGPUTextureUtils.js

@@ -648,10 +648,29 @@ class WebGPUTextureUtils {
 			const width = textureDescriptorGPU.size.width;
 			const height = textureDescriptorGPU.size.height;
 
-			device.queue.copyElementImageToTexture(
-				image, width, height,
-				{ texture: textureData.texture }
-			);
+			if ( device.queue.copyElementImageToTexture.length === 2 ) {
+
+				// Chrome 150+
+
+				device.queue.copyElementImageToTexture(
+					{ source: image },
+					{
+						destination: { texture: textureData.texture },
+						width: width,
+						height: height
+					}
+				);
+
+			} else {
+
+				// Chrome 138 - 149
+
+				device.queue.copyElementImageToTexture(
+					image, width, height,
+					{ texture: textureData.texture }
+				);
+
+			}
 
 			if ( texture.flipY ) {
 

+ 16 - 1
src/renderers/webgpu/utils/WebGPUUtils.js

@@ -24,6 +24,15 @@ class WebGPUUtils {
 		 */
 		this.backend = backend;
 
+		/**
+		 * Caches the preferred canvas format.
+		 *
+		 * @private
+		 * @type {?string}
+		 * @default null
+		 */
+		this._preferredCanvasFormat = null;
+
 	}
 
 	/**
@@ -248,7 +257,13 @@ class WebGPUUtils {
 
 		if ( bufferType === undefined ) {
 
-			return navigator.gpu.getPreferredCanvasFormat();
+			if ( this._preferredCanvasFormat === null ) {
+
+				this._preferredCanvasFormat = navigator.gpu.getPreferredCanvasFormat();
+
+			}
+
+			return this._preferredCanvasFormat;
 
 		} else if ( bufferType === UnsignedByteType ) {
 

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

粤ICP备19079148号