{"version":3,"file":"MMDLoader.cjs","sources":["../../src/loaders/MMDLoader.js"],"sourcesContent":["import {\n  AddOperation,\n  AnimationClip,\n  Bone,\n  BufferGeometry,\n  Color,\n  CustomBlending,\n  DoubleSide,\n  DstAlphaFactor,\n  Euler,\n  FileLoader,\n  Float32BufferAttribute,\n  FrontSide,\n  Interpolant,\n  Loader,\n  LoaderUtils,\n  MeshToonMaterial,\n  MultiplyOperation,\n  NearestFilter,\n  NumberKeyframeTrack,\n  OneMinusSrcAlphaFactor,\n  Quaternion,\n  QuaternionKeyframeTrack,\n  RepeatWrapping,\n  Skeleton,\n  SkinnedMesh,\n  SrcAlphaFactor,\n  TextureLoader,\n  Uint16BufferAttribute,\n  Vector3,\n  VectorKeyframeTrack,\n} from 'three'\nimport { TGALoader } from '../loaders/TGALoader'\nimport { Parser } from '../libs/mmdparser'\n\n/**\n * Dependencies\n *  - mmd-parser https://github.com/takahirox/mmd-parser\n *  - TGALoader\n *  - OutlineEffect\n *\n * MMDLoader creates Three.js Objects from MMD resources as\n * PMD, PMX, VMD, and VPD files.\n *\n * PMD/PMX is a model data format, VMD is a motion data format\n * VPD is a posing data format used in MMD(Miku Miku Dance).\n *\n * MMD official site\n *  - https://sites.google.com/view/evpvp/\n *\n * PMD, VMD format (in Japanese)\n *  - http://blog.goo.ne.jp/torisu_tetosuki/e/209ad341d3ece2b1b4df24abf619d6e4\n *\n * PMX format\n *  - https://gist.github.com/felixjones/f8a06bd48f9da9a4539f\n *\n * TODO\n *  - light motion in vmd support.\n *  - SDEF support.\n *  - uv/material/bone morphing support.\n *  - more precise grant skinning support.\n *  - shadow support.\n */\n\n/**\n * @param {THREE.LoadingManager} manager\n */\nclass MMDLoader extends Loader {\n  constructor(manager) {\n    super(manager)\n\n    this.loader = new FileLoader(this.manager)\n\n    this.parser = null // lazy generation\n    this.meshBuilder = new MeshBuilder(this.manager)\n    this.animationBuilder = new AnimationBuilder()\n  }\n\n  /**\n   * @param {string} animationPath\n   * @return {MMDLoader}\n   */\n  setAnimationPath(animationPath) {\n    this.animationPath = animationPath\n    return this\n  }\n\n  // Load MMD assets as Three.js Object\n\n  /**\n   * Loads Model file (.pmd or .pmx) as a SkinnedMesh.\n   *\n   * @param {string} url - url to Model(.pmd or .pmx) file\n   * @param {function} onLoad\n   * @param {function} onProgress\n   * @param {function} onError\n   */\n  load(url, onLoad, onProgress, onError) {\n    const builder = this.meshBuilder.setCrossOrigin(this.crossOrigin)\n\n    // resource path\n\n    let resourcePath\n\n    if (this.resourcePath !== '') {\n      resourcePath = this.resourcePath\n    } else if (this.path !== '') {\n      resourcePath = this.path\n    } else {\n      resourcePath = LoaderUtils.extractUrlBase(url)\n    }\n\n    const modelExtension = this._extractExtension(url).toLowerCase()\n\n    // Should I detect by seeing header?\n    if (modelExtension !== 'pmd' && modelExtension !== 'pmx') {\n      if (onError) onError(new Error('THREE.MMDLoader: Unknown model file extension .' + modelExtension + '.'))\n\n      return\n    }\n\n    this[modelExtension === 'pmd' ? 'loadPMD' : 'loadPMX'](\n      url,\n      function (data) {\n        onLoad(builder.build(data, resourcePath, onProgress, onError))\n      },\n      onProgress,\n      onError,\n    )\n  }\n\n  /**\n   * Loads Motion file(s) (.vmd) as a AnimationClip.\n   * If two or more files are specified, they'll be merged.\n   *\n   * @param {string|Array<string>} url - url(s) to animation(.vmd) file(s)\n   * @param {SkinnedMesh|THREE.Camera} object - tracks will be fitting to this object\n   * @param {function} onLoad\n   * @param {function} onProgress\n   * @param {function} onError\n   */\n  loadAnimation(url, object, onLoad, onProgress, onError) {\n    const builder = this.animationBuilder\n\n    this.loadVMD(\n      url,\n      function (vmd) {\n        onLoad(object.isCamera ? builder.buildCameraAnimation(vmd) : builder.build(vmd, object))\n      },\n      onProgress,\n      onError,\n    )\n  }\n\n  /**\n   * Loads mode file and motion file(s) as an object containing\n   * a SkinnedMesh and a AnimationClip.\n   * Tracks of AnimationClip are fitting to the model.\n   *\n   * @param {string} modelUrl - url to Model(.pmd or .pmx) file\n   * @param {string|Array{string}} vmdUrl - url(s) to animation(.vmd) file\n   * @param {function} onLoad\n   * @param {function} onProgress\n   * @param {function} onError\n   */\n  loadWithAnimation(modelUrl, vmdUrl, onLoad, onProgress, onError) {\n    const scope = this\n\n    this.load(\n      modelUrl,\n      function (mesh) {\n        scope.loadAnimation(\n          vmdUrl,\n          mesh,\n          function (animation) {\n            onLoad({\n              mesh: mesh,\n              animation: animation,\n            })\n          },\n          onProgress,\n          onError,\n        )\n      },\n      onProgress,\n      onError,\n    )\n  }\n\n  // Load MMD assets as Object data parsed by MMDParser\n\n  /**\n   * Loads .pmd file as an Object.\n   *\n   * @param {string} url - url to .pmd file\n   * @param {function} onLoad\n   * @param {function} onProgress\n   * @param {function} onError\n   */\n  loadPMD(url, onLoad, onProgress, onError) {\n    const parser = this._getParser()\n\n    this.loader\n      .setMimeType(undefined)\n      .setPath(this.path)\n      .setResponseType('arraybuffer')\n      .setRequestHeader(this.requestHeader)\n      .setWithCredentials(this.withCredentials)\n      .load(\n        url,\n        function (buffer) {\n          onLoad(parser.parsePmd(buffer, true))\n        },\n        onProgress,\n        onError,\n      )\n  }\n\n  /**\n   * Loads .pmx file as an Object.\n   *\n   * @param {string} url - url to .pmx file\n   * @param {function} onLoad\n   * @param {function} onProgress\n   * @param {function} onError\n   */\n  loadPMX(url, onLoad, onProgress, onError) {\n    const parser = this._getParser()\n\n    this.loader\n      .setMimeType(undefined)\n      .setPath(this.path)\n      .setResponseType('arraybuffer')\n      .setRequestHeader(this.requestHeader)\n      .setWithCredentials(this.withCredentials)\n      .load(\n        url,\n        function (buffer) {\n          onLoad(parser.parsePmx(buffer, true))\n        },\n        onProgress,\n        onError,\n      )\n  }\n\n  /**\n   * Loads .vmd file as an Object. If two or more files are specified\n   * they'll be merged.\n   *\n   * @param {string|Array<string>} url - url(s) to .vmd file(s)\n   * @param {function} onLoad\n   * @param {function} onProgress\n   * @param {function} onError\n   */\n  loadVMD(url, onLoad, onProgress, onError) {\n    const urls = Array.isArray(url) ? url : [url]\n\n    const vmds = []\n    const vmdNum = urls.length\n\n    const parser = this._getParser()\n\n    this.loader\n      .setMimeType(undefined)\n      .setPath(this.animationPath)\n      .setResponseType('arraybuffer')\n      .setRequestHeader(this.requestHeader)\n      .setWithCredentials(this.withCredentials)\n\n    for (let i = 0, il = urls.length; i < il; i++) {\n      this.loader.load(\n        urls[i],\n        function (buffer) {\n          vmds.push(parser.parseVmd(buffer, true))\n\n          if (vmds.length === vmdNum) onLoad(parser.mergeVmds(vmds))\n        },\n        onProgress,\n        onError,\n      )\n    }\n  }\n\n  /**\n   * Loads .vpd file as an Object.\n   *\n   * @param {string} url - url to .vpd file\n   * @param {boolean} isUnicode\n   * @param {function} onLoad\n   * @param {function} onProgress\n   * @param {function} onError\n   */\n  loadVPD(url, isUnicode, onLoad, onProgress, onError) {\n    const parser = this._getParser()\n\n    this.loader\n      .setMimeType(isUnicode ? undefined : 'text/plain; charset=shift_jis')\n      .setPath(this.animationPath)\n      .setResponseType('text')\n      .setRequestHeader(this.requestHeader)\n      .setWithCredentials(this.withCredentials)\n      .load(\n        url,\n        function (text) {\n          onLoad(parser.parseVpd(text, true))\n        },\n        onProgress,\n        onError,\n      )\n  }\n\n  // private methods\n\n  _extractExtension(url) {\n    const index = url.lastIndexOf('.')\n    return index < 0 ? '' : url.slice(index + 1)\n  }\n\n  _getParser() {\n    if (this.parser === null) {\n      this.parser = new Parser()\n    }\n\n    return this.parser\n  }\n}\n\n// Utilities\n\n/*\n * base64 encoded defalut toon textures toon00.bmp - toon10.bmp.\n * We don't need to request external toon image files.\n * This idea is from http://www20.atpages.jp/katwat/three.js_r58/examples/mytest37/mmd.three.js\n */\nconst DEFAULT_TOON_TEXTURES = [\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAN0lEQVRYR+3WQREAMBACsZ5/bWiiMvgEBTt5cW37hjsBBAgQIECAwFwgyfYPCCBAgAABAgTWAh8aBHZBl14e8wAAAABJRU5ErkJggg==',\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAOUlEQVRYR+3WMREAMAwDsYY/yoDI7MLwIiP40+RJklfcCCBAgAABAgTqArfb/QMCCBAgQIAAgbbAB3z/e0F3js2cAAAAAElFTkSuQmCC',\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAN0lEQVRYR+3WQREAMBACsZ5/B5ilMvgEBTt5cW37hjsBBAgQIECAwFwgyfYPCCBAgAABAgTWAh81dWyx0gFwKAAAAABJRU5ErkJggg==',\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAOklEQVRYR+3WoREAMAwDsWb/UQtCy9wxTOQJ/oQ8SXKKGwEECBAgQIBAXeDt7f4BAQQIECBAgEBb4AOz8Hzx7WLY4wAAAABJRU5ErkJggg==',\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABPUlEQVRYR+1XwW7CMAy1+f9fZOMysSEOEweEOPRNdm3HbdOyIhAcklPrOs/PLy9RygBALxzcCDQFmgJNgaZAU6Ap0BR4PwX8gsRMVLssMRH5HcpzJEaWL7EVg9F1IHRlyqQohgVr4FGUlUcMJSjcUlDw0zvjeun70cLWmneoyf7NgBTQSniBTQQSuJAZsOnnaczjIMb5hCiuHKxokCrJfVnrctyZL0PkJAJe1HMil4nxeyi3Ypfn1kX51jpPvo/JeCNC4PhVdHdJw2XjBR8brF8PEIhNVn12AgP7uHsTBguBn53MUZCqv7Lp07Pn5k1Ro+uWmUNn7D+M57rtk7aG0Vo73xyF/fbFf0bPJjDXngnGocDTdFhygZjwUQrMNrDcmZlQT50VJ/g/UwNyHpu778+yW+/ksOz/BFo54P4AsUXMfRq7XWsAAAAASUVORK5CYII=',\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACMElEQVRYR+2Xv4pTQRTGf2dubhLdICiii2KnYKHVolhauKWPoGAnNr6BD6CvIVaihYuI2i1ia0BY0MZGRHQXjZj/mSPnnskfNWiWZUlzJ5k7M2cm833nO5Mziej2DWWJRUoCpQKlAntSQCqgw39/iUWAGmh37jrRnVsKlgpiqmkoGVABA7E57fvY+pJDdgKqF6HzFCSADkDq+F6AHABtQ+UMVE5D7zXod7fFNhTEckTbj5XQgHzNN+5tQvc5NG7C6BNkp6D3EmpXHDR+dQAjFLchW3VS9rlw3JBh+B7ys5Cf9z0GW1C/7P32AyBAOAz1q4jGliIH3YPuBnSfQX4OGreTIgEYQb/pBDtPnEQ4CivXYPAWBk13oHrB54yA9QuSn2H4AcKRpEILDt0BUzj+RLR1V5EqjD66NPRBVpLcQwjHoHYJOhsQv6U4mnzmrIXJCFr4LDwm/xBUoboG9XX4cc9VKdYoSA2yk5NQLJaKDUjTBoveG3Z2TElTxwjNK4M3LEZgUdDdruvcXzKBpStgp2NPiWi3ks9ZXxIoFVi+AvHLdc9TqtjL3/aYjpPlrzOcEnK62Szhimdd7xX232zFDTgtxezOu3WNMRLjiKgjtOhHVMd1loynVHvOgjuIIJMaELEqhJAV/RCSLbWTcfPFakFgFlALTRRvx+ok6Hlp/Q+v3fmx90bMyUzaEAhmM3KvHlXTL5DxnbGf/1M8RNNACLL5MNtPxP/mypJAqcDSFfgFhpYqWUzhTEAAAAAASUVORK5CYII=',\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',\n  'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAL0lEQVRYR+3QQREAAAzCsOFfNJPBJ1XQS9r2hsUAAQIECBAgQIAAAQIECBAgsBZ4MUx/ofm2I/kAAAAASUVORK5CYII=',\n]\n\n// Builders. They build Three.js object from Object data parsed by MMDParser.\n\n/**\n * @param {THREE.LoadingManager} manager\n */\nclass MeshBuilder {\n  constructor(manager) {\n    this.crossOrigin = 'anonymous'\n    this.geometryBuilder = new GeometryBuilder()\n    this.materialBuilder = new MaterialBuilder(manager)\n  }\n\n  /**\n   * @param {string} crossOrigin\n   * @return {MeshBuilder}\n   */\n  setCrossOrigin(crossOrigin) {\n    this.crossOrigin = crossOrigin\n    return this\n  }\n\n  /**\n   * @param {Object} data - parsed PMD/PMX data\n   * @param {string} resourcePath\n   * @param {function} onProgress\n   * @param {function} onError\n   * @return {SkinnedMesh}\n   */\n  build(data, resourcePath, onProgress, onError) {\n    const geometry = this.geometryBuilder.build(data)\n    const material = this.materialBuilder\n      .setCrossOrigin(this.crossOrigin)\n      .setResourcePath(resourcePath)\n      .build(data, geometry, onProgress, onError)\n\n    const mesh = new SkinnedMesh(geometry, material)\n\n    const skeleton = new Skeleton(initBones(mesh))\n    mesh.bind(skeleton)\n\n    // console.log( mesh ); // for console debug\n\n    return mesh\n  }\n}\n\n// TODO: Try to remove this function\n\nfunction initBones(mesh) {\n  const geometry = mesh.geometry\n\n  const bones = []\n\n  if (geometry && geometry.bones !== undefined) {\n    // first, create array of 'Bone' objects from geometry data\n\n    for (let i = 0, il = geometry.bones.length; i < il; i++) {\n      const gbone = geometry.bones[i]\n\n      // create new 'Bone' object\n\n      const bone = new Bone()\n      bones.push(bone)\n\n      // apply values\n\n      bone.name = gbone.name\n      bone.position.fromArray(gbone.pos)\n      bone.quaternion.fromArray(gbone.rotq)\n      if (gbone.scl !== undefined) bone.scale.fromArray(gbone.scl)\n    }\n\n    // second, create bone hierarchy\n\n    for (let i = 0, il = geometry.bones.length; i < il; i++) {\n      const gbone = geometry.bones[i]\n\n      if (gbone.parent !== -1 && gbone.parent !== null && bones[gbone.parent] !== undefined) {\n        // subsequent bones in the hierarchy\n\n        bones[gbone.parent].add(bones[i])\n      } else {\n        // topmost bone, immediate child of the skinned mesh\n\n        mesh.add(bones[i])\n      }\n    }\n  }\n\n  // now the bones are part of the scene graph and children of the skinned mesh.\n  // let's update the corresponding matrices\n\n  mesh.updateMatrixWorld(true)\n\n  return bones\n}\n\n//\n\nclass GeometryBuilder {\n  /**\n   * @param {Object} data - parsed PMD/PMX data\n   * @return {BufferGeometry}\n   */\n  build(data) {\n    // for geometry\n    const positions = []\n    const uvs = []\n    const normals = []\n\n    const indices = []\n\n    const groups = []\n\n    const bones = []\n    const skinIndices = []\n    const skinWeights = []\n\n    const morphTargets = []\n    const morphPositions = []\n\n    const iks = []\n    const grants = []\n\n    const rigidBodies = []\n    const constraints = []\n\n    // for work\n    let offset = 0\n    const boneTypeTable = {}\n\n    // positions, normals, uvs, skinIndices, skinWeights\n\n    for (let i = 0; i < data.metadata.vertexCount; i++) {\n      const v = data.vertices[i]\n\n      for (let j = 0, jl = v.position.length; j < jl; j++) {\n        positions.push(v.position[j])\n      }\n\n      for (let j = 0, jl = v.normal.length; j < jl; j++) {\n        normals.push(v.normal[j])\n      }\n\n      for (let j = 0, jl = v.uv.length; j < jl; j++) {\n        uvs.push(v.uv[j])\n      }\n\n      for (let j = 0; j < 4; j++) {\n        skinIndices.push(v.skinIndices.length - 1 >= j ? v.skinIndices[j] : 0.0)\n      }\n\n      for (let j = 0; j < 4; j++) {\n        skinWeights.push(v.skinWeights.length - 1 >= j ? v.skinWeights[j] : 0.0)\n      }\n    }\n\n    // indices\n\n    for (let i = 0; i < data.metadata.faceCount; i++) {\n      const face = data.faces[i]\n\n      for (let j = 0, jl = face.indices.length; j < jl; j++) {\n        indices.push(face.indices[j])\n      }\n    }\n\n    // groups\n\n    for (let i = 0; i < data.metadata.materialCount; i++) {\n      const material = data.materials[i]\n\n      groups.push({\n        offset: offset * 3,\n        count: material.faceCount * 3,\n      })\n\n      offset += material.faceCount\n    }\n\n    // bones\n\n    for (let i = 0; i < data.metadata.rigidBodyCount; i++) {\n      const body = data.rigidBodies[i]\n      let value = boneTypeTable[body.boneIndex]\n\n      // keeps greater number if already value is set without any special reasons\n      value = value === undefined ? body.type : Math.max(body.type, value)\n\n      boneTypeTable[body.boneIndex] = value\n    }\n\n    for (let i = 0; i < data.metadata.boneCount; i++) {\n      const boneData = data.bones[i]\n\n      const bone = {\n        index: i,\n        transformationClass: boneData.transformationClass,\n        parent: boneData.parentIndex,\n        name: boneData.name,\n        pos: boneData.position.slice(0, 3),\n        rotq: [0, 0, 0, 1],\n        scl: [1, 1, 1],\n        rigidBodyType: boneTypeTable[i] !== undefined ? boneTypeTable[i] : -1,\n      }\n\n      if (bone.parent !== -1) {\n        bone.pos[0] -= data.bones[bone.parent].position[0]\n        bone.pos[1] -= data.bones[bone.parent].position[1]\n        bone.pos[2] -= data.bones[bone.parent].position[2]\n      }\n\n      bones.push(bone)\n    }\n\n    // iks\n\n    // TODO: remove duplicated codes between PMD and PMX\n    if (data.metadata.format === 'pmd') {\n      for (let i = 0; i < data.metadata.ikCount; i++) {\n        const ik = data.iks[i]\n\n        const param = {\n          target: ik.target,\n          effector: ik.effector,\n          iteration: ik.iteration,\n          maxAngle: ik.maxAngle * 4,\n          links: [],\n        }\n\n        for (let j = 0, jl = ik.links.length; j < jl; j++) {\n          const link = {}\n          link.index = ik.links[j].index\n          link.enabled = true\n\n          if (data.bones[link.index].name.indexOf('ひざ') >= 0) {\n            link.limitation = new Vector3(1.0, 0.0, 0.0)\n          }\n\n          param.links.push(link)\n        }\n\n        iks.push(param)\n      }\n    } else {\n      for (let i = 0; i < data.metadata.boneCount; i++) {\n        const ik = data.bones[i].ik\n\n        if (ik === undefined) continue\n\n        const param = {\n          target: i,\n          effector: ik.effector,\n          iteration: ik.iteration,\n          maxAngle: ik.maxAngle,\n          links: [],\n        }\n\n        for (let j = 0, jl = ik.links.length; j < jl; j++) {\n          const link = {}\n          link.index = ik.links[j].index\n          link.enabled = true\n\n          if (ik.links[j].angleLimitation === 1) {\n            // Revert if rotationMin/Max doesn't work well\n            // link.limitation = new Vector3( 1.0, 0.0, 0.0 );\n\n            const rotationMin = ik.links[j].lowerLimitationAngle\n            const rotationMax = ik.links[j].upperLimitationAngle\n\n            // Convert Left to Right coordinate by myself because\n            // MMDParser doesn't convert. It's a MMDParser's bug\n\n            const tmp1 = -rotationMax[0]\n            const tmp2 = -rotationMax[1]\n            rotationMax[0] = -rotationMin[0]\n            rotationMax[1] = -rotationMin[1]\n            rotationMin[0] = tmp1\n            rotationMin[1] = tmp2\n\n            link.rotationMin = new Vector3().fromArray(rotationMin)\n            link.rotationMax = new Vector3().fromArray(rotationMax)\n          }\n\n          param.links.push(link)\n        }\n\n        iks.push(param)\n\n        // Save the reference even from bone data for efficiently\n        // simulating PMX animation system\n        bones[i].ik = param\n      }\n    }\n\n    // grants\n\n    if (data.metadata.format === 'pmx') {\n      // bone index -> grant entry map\n      const grantEntryMap = {}\n\n      for (let i = 0; i < data.metadata.boneCount; i++) {\n        const boneData = data.bones[i]\n        const grant = boneData.grant\n\n        if (grant === undefined) continue\n\n        const param = {\n          index: i,\n          parentIndex: grant.parentIndex,\n          ratio: grant.ratio,\n          isLocal: grant.isLocal,\n          affectRotation: grant.affectRotation,\n          affectPosition: grant.affectPosition,\n          transformationClass: boneData.transformationClass,\n        }\n\n        grantEntryMap[i] = { parent: null, children: [], param: param, visited: false }\n      }\n\n      const rootEntry = { parent: null, children: [], param: null, visited: false }\n\n      // Build a tree representing grant hierarchy\n\n      for (const boneIndex in grantEntryMap) {\n        const grantEntry = grantEntryMap[boneIndex]\n        const parentGrantEntry = grantEntryMap[grantEntry.parentIndex] || rootEntry\n\n        grantEntry.parent = parentGrantEntry\n        parentGrantEntry.children.push(grantEntry)\n      }\n\n      // Sort grant parameters from parents to children because\n      // grant uses parent's transform that parent's grant is already applied\n      // so grant should be applied in order from parents to children\n\n      function traverse(entry) {\n        if (entry.param) {\n          grants.push(entry.param)\n\n          // Save the reference even from bone data for efficiently\n          // simulating PMX animation system\n          bones[entry.param.index].grant = entry.param\n        }\n\n        entry.visited = true\n\n        for (let i = 0, il = entry.children.length; i < il; i++) {\n          const child = entry.children[i]\n\n          // Cut off a loop if exists. (Is a grant loop invalid?)\n          if (!child.visited) traverse(child)\n        }\n      }\n\n      traverse(rootEntry)\n    }\n\n    // morph\n\n    function updateAttributes(attribute, morph, ratio) {\n      for (let i = 0; i < morph.elementCount; i++) {\n        const element = morph.elements[i]\n\n        let index\n\n        if (data.metadata.format === 'pmd') {\n          index = data.morphs[0].elements[element.index].index\n        } else {\n          index = element.index\n        }\n\n        attribute.array[index * 3 + 0] += element.position[0] * ratio\n        attribute.array[index * 3 + 1] += element.position[1] * ratio\n        attribute.array[index * 3 + 2] += element.position[2] * ratio\n      }\n    }\n\n    for (let i = 0; i < data.metadata.morphCount; i++) {\n      const morph = data.morphs[i]\n      const params = { name: morph.name }\n\n      const attribute = new Float32BufferAttribute(data.metadata.vertexCount * 3, 3)\n      attribute.name = morph.name\n\n      for (let j = 0; j < data.metadata.vertexCount * 3; j++) {\n        attribute.array[j] = positions[j]\n      }\n\n      if (data.metadata.format === 'pmd') {\n        if (i !== 0) {\n          updateAttributes(attribute, morph, 1.0)\n        }\n      } else {\n        if (morph.type === 0) {\n          // group\n\n          for (let j = 0; j < morph.elementCount; j++) {\n            const morph2 = data.morphs[morph.elements[j].index]\n            const ratio = morph.elements[j].ratio\n\n            if (morph2.type === 1) {\n              updateAttributes(attribute, morph2, ratio)\n            } else {\n              // TODO: implement\n            }\n          }\n        } else if (morph.type === 1) {\n          // vertex\n\n          updateAttributes(attribute, morph, 1.0)\n        } else if (morph.type === 2) {\n          // bone\n          // TODO: implement\n        } else if (morph.type === 3) {\n          // uv\n          // TODO: implement\n        } else if (morph.type === 4) {\n          // additional uv1\n          // TODO: implement\n        } else if (morph.type === 5) {\n          // additional uv2\n          // TODO: implement\n        } else if (morph.type === 6) {\n          // additional uv3\n          // TODO: implement\n        } else if (morph.type === 7) {\n          // additional uv4\n          // TODO: implement\n        } else if (morph.type === 8) {\n          // material\n          // TODO: implement\n        }\n      }\n\n      morphTargets.push(params)\n      morphPositions.push(attribute)\n    }\n\n    // rigid bodies from rigidBodies field.\n\n    for (let i = 0; i < data.metadata.rigidBodyCount; i++) {\n      const rigidBody = data.rigidBodies[i]\n      const params = {}\n\n      for (const key in rigidBody) {\n        params[key] = rigidBody[key]\n      }\n\n      /*\n       * RigidBody position parameter in PMX seems global position\n       * while the one in PMD seems offset from corresponding bone.\n       * So unify being offset.\n       */\n      if (data.metadata.format === 'pmx') {\n        if (params.boneIndex !== -1) {\n          const bone = data.bones[params.boneIndex]\n          params.position[0] -= bone.position[0]\n          params.position[1] -= bone.position[1]\n          params.position[2] -= bone.position[2]\n        }\n      }\n\n      rigidBodies.push(params)\n    }\n\n    // constraints from constraints field.\n\n    for (let i = 0; i < data.metadata.constraintCount; i++) {\n      const constraint = data.constraints[i]\n      const params = {}\n\n      for (const key in constraint) {\n        params[key] = constraint[key]\n      }\n\n      const bodyA = rigidBodies[params.rigidBodyIndex1]\n      const bodyB = rigidBodies[params.rigidBodyIndex2]\n\n      // Refer to http://www20.atpages.jp/katwat/wp/?p=4135\n      if (bodyA.type !== 0 && bodyB.type === 2) {\n        if (\n          bodyA.boneIndex !== -1 &&\n          bodyB.boneIndex !== -1 &&\n          data.bones[bodyB.boneIndex].parentIndex === bodyA.boneIndex\n        ) {\n          bodyB.type = 1\n        }\n      }\n\n      constraints.push(params)\n    }\n\n    // build BufferGeometry.\n\n    const geometry = new BufferGeometry()\n\n    geometry.setAttribute('position', new Float32BufferAttribute(positions, 3))\n    geometry.setAttribute('normal', new Float32BufferAttribute(normals, 3))\n    geometry.setAttribute('uv', new Float32BufferAttribute(uvs, 2))\n    geometry.setAttribute('skinIndex', new Uint16BufferAttribute(skinIndices, 4))\n    geometry.setAttribute('skinWeight', new Float32BufferAttribute(skinWeights, 4))\n    geometry.setIndex(indices)\n\n    for (let i = 0, il = groups.length; i < il; i++) {\n      geometry.addGroup(groups[i].offset, groups[i].count, i)\n    }\n\n    geometry.bones = bones\n\n    geometry.morphTargets = morphTargets\n    geometry.morphAttributes.position = morphPositions\n    geometry.morphTargetsRelative = false\n\n    geometry.userData.MMD = {\n      bones: bones,\n      iks: iks,\n      grants: grants,\n      rigidBodies: rigidBodies,\n      constraints: constraints,\n      format: data.metadata.format,\n    }\n\n    geometry.computeBoundingSphere()\n\n    return geometry\n  }\n}\n\n//\n\n/**\n * @param {THREE.LoadingManager} manager\n */\nclass MaterialBuilder {\n  constructor(manager) {\n    this.manager = manager\n\n    this.textureLoader = new TextureLoader(this.manager)\n    this.tgaLoader = null // lazy generation\n\n    this.crossOrigin = 'anonymous'\n    this.resourcePath = undefined\n  }\n\n  /**\n   * @param {string} crossOrigin\n   * @return {MaterialBuilder}\n   */\n  setCrossOrigin(crossOrigin) {\n    this.crossOrigin = crossOrigin\n    return this\n  }\n\n  /**\n   * @param {string} resourcePath\n   * @return {MaterialBuilder}\n   */\n  setResourcePath(resourcePath) {\n    this.resourcePath = resourcePath\n    return this\n  }\n\n  /**\n   * @param {Object} data - parsed PMD/PMX data\n   * @param {BufferGeometry} geometry - some properties are dependend on geometry\n   * @param {function} onProgress\n   * @param {function} onError\n   * @return {Array<MeshToonMaterial>}\n   */\n  build(data, geometry /*, onProgress, onError */) {\n    const materials = []\n\n    const textures = {}\n\n    this.textureLoader.setCrossOrigin(this.crossOrigin)\n\n    // materials\n\n    for (let i = 0; i < data.metadata.materialCount; i++) {\n      const material = data.materials[i]\n\n      const params = { userData: {} }\n\n      if (material.name !== undefined) params.name = material.name\n\n      /*\n       * Color\n       *\n       * MMD         MeshToonMaterial\n       * diffuse  -  color\n       * ambient  -  emissive * a\n       *               (a = 1.0 without map texture or 0.2 with map texture)\n       *\n       * MeshToonMaterial doesn't have ambient. Set it to emissive instead.\n       * It'll be too bright if material has map texture so using coef 0.2.\n       */\n      params.color = new Color().fromArray(material.diffuse)\n      params.opacity = material.diffuse[3]\n      params.emissive = new Color().fromArray(material.ambient)\n      params.transparent = params.opacity !== 1.0\n\n      //\n\n      params.skinning = geometry.bones.length > 0 ? true : false\n      params.morphTargets = geometry.morphTargets.length > 0 ? true : false\n      params.fog = true\n\n      // blend\n\n      params.blending = CustomBlending\n      params.blendSrc = SrcAlphaFactor\n      params.blendDst = OneMinusSrcAlphaFactor\n      params.blendSrcAlpha = SrcAlphaFactor\n      params.blendDstAlpha = DstAlphaFactor\n\n      // side\n\n      if (data.metadata.format === 'pmx' && (material.flag & 0x1) === 1) {\n        params.side = DoubleSide\n      } else {\n        params.side = params.opacity === 1.0 ? FrontSide : DoubleSide\n      }\n\n      if (data.metadata.format === 'pmd') {\n        // map, envMap\n\n        if (material.fileName) {\n          const fileName = material.fileName\n          const fileNames = fileName.split('*')\n\n          // fileNames[ 0 ]: mapFileName\n          // fileNames[ 1 ]: envMapFileName( optional )\n\n          params.map = this._loadTexture(fileNames[0], textures)\n\n          if (fileNames.length > 1) {\n            const extension = fileNames[1].slice(-4).toLowerCase()\n\n            params.envMap = this._loadTexture(fileNames[1], textures)\n\n            params.combine = extension === '.sph' ? MultiplyOperation : AddOperation\n          }\n        }\n\n        // gradientMap\n\n        const toonFileName = material.toonIndex === -1 ? 'toon00.bmp' : data.toonTextures[material.toonIndex].fileName\n\n        params.gradientMap = this._loadTexture(toonFileName, textures, {\n          isToonTexture: true,\n          isDefaultToonTexture: this._isDefaultToonTexture(toonFileName),\n        })\n\n        // parameters for OutlineEffect\n\n        params.userData.outlineParameters = {\n          thickness: material.edgeFlag === 1 ? 0.003 : 0.0,\n          color: [0, 0, 0],\n          alpha: 1.0,\n          visible: material.edgeFlag === 1,\n        }\n      } else {\n        // map\n\n        if (material.textureIndex !== -1) {\n          params.map = this._loadTexture(data.textures[material.textureIndex], textures)\n        }\n\n        // envMap TODO: support m.envFlag === 3\n\n        if (material.envTextureIndex !== -1 && (material.envFlag === 1 || material.envFlag == 2)) {\n          params.envMap = this._loadTexture(data.textures[material.envTextureIndex], textures)\n\n          params.combine = material.envFlag === 1 ? MultiplyOperation : AddOperation\n        }\n\n        // gradientMap\n\n        let toonFileName, isDefaultToon\n\n        if (material.toonIndex === -1 || material.toonFlag !== 0) {\n          toonFileName = 'toon' + ('0' + (material.toonIndex + 1)).slice(-2) + '.bmp'\n          isDefaultToon = true\n        } else {\n          toonFileName = data.textures[material.toonIndex]\n          isDefaultToon = false\n        }\n\n        params.gradientMap = this._loadTexture(toonFileName, textures, {\n          isToonTexture: true,\n          isDefaultToonTexture: isDefaultToon,\n        })\n\n        // parameters for OutlineEffect\n        params.userData.outlineParameters = {\n          thickness: material.edgeSize / 300, // TODO: better calculation?\n          color: material.edgeColor.slice(0, 3),\n          alpha: material.edgeColor[3],\n          visible: (material.flag & 0x10) !== 0 && material.edgeSize > 0.0,\n        }\n      }\n\n      if (params.map !== undefined) {\n        if (!params.transparent) {\n          this._checkImageTransparency(params.map, geometry, i)\n        }\n\n        params.emissive.multiplyScalar(0.2)\n      }\n\n      materials.push(new MeshToonMaterial(params))\n    }\n\n    if (data.metadata.format === 'pmx') {\n      // set transparent true if alpha morph is defined.\n\n      function checkAlphaMorph(elements, materials) {\n        for (let i = 0, il = elements.length; i < il; i++) {\n          const element = elements[i]\n\n          if (element.index === -1) continue\n\n          const material = materials[element.index]\n\n          if (material.opacity !== element.diffuse[3]) {\n            material.transparent = true\n          }\n        }\n      }\n\n      for (let i = 0, il = data.morphs.length; i < il; i++) {\n        const morph = data.morphs[i]\n        const elements = morph.elements\n\n        if (morph.type === 0) {\n          for (let j = 0, jl = elements.length; j < jl; j++) {\n            const morph2 = data.morphs[elements[j].index]\n\n            if (morph2.type !== 8) continue\n\n            checkAlphaMorph(morph2.elements, materials)\n          }\n        } else if (morph.type === 8) {\n          checkAlphaMorph(elements, materials)\n        }\n      }\n    }\n\n    return materials\n  }\n\n  // private methods\n\n  _getTGALoader() {\n    if (this.tgaLoader === null) {\n      if (TGALoader === undefined) {\n        throw new Error('THREE.MMDLoader: Import TGALoader')\n      }\n\n      this.tgaLoader = new TGALoader(this.manager)\n    }\n\n    return this.tgaLoader\n  }\n\n  _isDefaultToonTexture(name) {\n    if (name.length !== 10) return false\n\n    return /toon(10|0[0-9])\\.bmp/.test(name)\n  }\n\n  _loadTexture(filePath, textures, params, onProgress, onError) {\n    params = params || {}\n\n    const scope = this\n\n    let fullPath\n\n    if (params.isDefaultToonTexture === true) {\n      let index\n\n      try {\n        index = parseInt(filePath.match(/toon([0-9]{2})\\.bmp$/)[1])\n      } catch (e) {\n        console.warn(\n          'THREE.MMDLoader: ' +\n            filePath +\n            ' seems like a ' +\n            'not right default texture path. Using toon00.bmp instead.',\n        )\n\n        index = 0\n      }\n\n      fullPath = DEFAULT_TOON_TEXTURES[index]\n    } else {\n      fullPath = this.resourcePath + filePath\n    }\n\n    if (textures[fullPath] !== undefined) return textures[fullPath]\n\n    let loader = this.manager.getHandler(fullPath)\n\n    if (loader === null) {\n      loader = filePath.slice(-4).toLowerCase() === '.tga' ? this._getTGALoader() : this.textureLoader\n    }\n\n    const texture = loader.load(\n      fullPath,\n      function (t) {\n        // MMD toon texture is Axis-Y oriented\n        // but Three.js gradient map is Axis-X oriented.\n        // So here replaces the toon texture image with the rotated one.\n        if (params.isToonTexture === true) {\n          t.image = scope._getRotatedImage(t.image)\n\n          t.magFilter = NearestFilter\n          t.minFilter = NearestFilter\n        }\n\n        t.flipY = false\n        t.wrapS = RepeatWrapping\n        t.wrapT = RepeatWrapping\n\n        for (let i = 0; i < texture.readyCallbacks.length; i++) {\n          texture.readyCallbacks[i](texture)\n        }\n\n        delete texture.readyCallbacks\n      },\n      onProgress,\n      onError,\n    )\n\n    texture.readyCallbacks = []\n\n    textures[fullPath] = texture\n\n    return texture\n  }\n\n  _getRotatedImage(image) {\n    const canvas = document.createElement('canvas')\n    const context = canvas.getContext('2d')\n\n    const width = image.width\n    const height = image.height\n\n    canvas.width = width\n    canvas.height = height\n\n    context.clearRect(0, 0, width, height)\n    context.translate(width / 2.0, height / 2.0)\n    context.rotate(0.5 * Math.PI) // 90.0 * Math.PI / 180.0\n    context.translate(-width / 2.0, -height / 2.0)\n    context.drawImage(image, 0, 0)\n\n    return context.getImageData(0, 0, width, height)\n  }\n\n  // Check if the partial image area used by the texture is transparent.\n  _checkImageTransparency(map, geometry, groupIndex) {\n    map.readyCallbacks.push(function (texture) {\n      // Is there any efficient ways?\n      function createImageData(image) {\n        const canvas = document.createElement('canvas')\n        canvas.width = image.width\n        canvas.height = image.height\n\n        const context = canvas.getContext('2d')\n        context.drawImage(image, 0, 0)\n\n        return context.getImageData(0, 0, canvas.width, canvas.height)\n      }\n\n      function detectImageTransparency(image, uvs, indices) {\n        const width = image.width\n        const height = image.height\n        const data = image.data\n        const threshold = 253\n\n        if (data.length / (width * height) !== 4) return false\n\n        for (let i = 0; i < indices.length; i += 3) {\n          const centerUV = { x: 0.0, y: 0.0 }\n\n          for (let j = 0; j < 3; j++) {\n            const index = indices[i * 3 + j]\n            const uv = { x: uvs[index * 2 + 0], y: uvs[index * 2 + 1] }\n\n            if (getAlphaByUv(image, uv) < threshold) return true\n\n            centerUV.x += uv.x\n            centerUV.y += uv.y\n          }\n\n          centerUV.x /= 3\n          centerUV.y /= 3\n\n          if (getAlphaByUv(image, centerUV) < threshold) return true\n        }\n\n        return false\n      }\n\n      /*\n       * This method expects\n       *   texture.flipY = false\n       *   texture.wrapS = RepeatWrapping\n       *   texture.wrapT = RepeatWrapping\n       * TODO: more precise\n       */\n      function getAlphaByUv(image, uv) {\n        const width = image.width\n        const height = image.height\n\n        let x = Math.round(uv.x * width) % width\n        let y = Math.round(uv.y * height) % height\n\n        if (x < 0) x += width\n        if (y < 0) y += height\n\n        const index = y * width + x\n\n        return image.data[index * 4 + 3]\n      }\n\n      const imageData = texture.image.data !== undefined ? texture.image : createImageData(texture.image)\n\n      const group = geometry.groups[groupIndex]\n\n      if (\n        detectImageTransparency(\n          imageData,\n          geometry.attributes.uv.array,\n          geometry.index.array.slice(group.start, group.start + group.count),\n        )\n      ) {\n        map.transparent = true\n      }\n    })\n  }\n}\n\n//\n\nclass AnimationBuilder {\n  /**\n   * @param {Object} vmd - parsed VMD data\n   * @param {SkinnedMesh} mesh - tracks will be fitting to mesh\n   * @return {AnimationClip}\n   */\n  build(vmd, mesh) {\n    // combine skeletal and morph animations\n\n    const tracks = this.buildSkeletalAnimation(vmd, mesh).tracks\n    const tracks2 = this.buildMorphAnimation(vmd, mesh).tracks\n\n    for (let i = 0, il = tracks2.length; i < il; i++) {\n      tracks.push(tracks2[i])\n    }\n\n    return new AnimationClip('', -1, tracks)\n  }\n\n  /**\n   * @param {Object} vmd - parsed VMD data\n   * @param {SkinnedMesh} mesh - tracks will be fitting to mesh\n   * @return {AnimationClip}\n   */\n  buildSkeletalAnimation(vmd, mesh) {\n    function pushInterpolation(array, interpolation, index) {\n      array.push(interpolation[index + 0] / 127) // x1\n      array.push(interpolation[index + 8] / 127) // x2\n      array.push(interpolation[index + 4] / 127) // y1\n      array.push(interpolation[index + 12] / 127) // y2\n    }\n\n    const tracks = []\n\n    const motions = {}\n    const bones = mesh.skeleton.bones\n    const boneNameDictionary = {}\n\n    for (let i = 0, il = bones.length; i < il; i++) {\n      boneNameDictionary[bones[i].name] = true\n    }\n\n    for (let i = 0; i < vmd.metadata.motionCount; i++) {\n      const motion = vmd.motions[i]\n      const boneName = motion.boneName\n\n      if (boneNameDictionary[boneName] === undefined) continue\n\n      motions[boneName] = motions[boneName] || []\n      motions[boneName].push(motion)\n    }\n\n    for (const key in motions) {\n      const array = motions[key]\n\n      array.sort(function (a, b) {\n        return a.frameNum - b.frameNum\n      })\n\n      const times = []\n      const positions = []\n      const rotations = []\n      const pInterpolations = []\n      const rInterpolations = []\n\n      const basePosition = mesh.skeleton.getBoneByName(key).position.toArray()\n\n      for (let i = 0, il = array.length; i < il; i++) {\n        const time = array[i].frameNum / 30\n        const position = array[i].position\n        const rotation = array[i].rotation\n        const interpolation = array[i].interpolation\n\n        times.push(time)\n\n        for (let j = 0; j < 3; j++) positions.push(basePosition[j] + position[j])\n        for (let j = 0; j < 4; j++) rotations.push(rotation[j])\n        for (let j = 0; j < 3; j++) pushInterpolation(pInterpolations, interpolation, j)\n\n        pushInterpolation(rInterpolations, interpolation, 3)\n      }\n\n      const targetName = '.bones[' + key + ']'\n\n      tracks.push(this._createTrack(targetName + '.position', VectorKeyframeTrack, times, positions, pInterpolations))\n      tracks.push(\n        this._createTrack(targetName + '.quaternion', QuaternionKeyframeTrack, times, rotations, rInterpolations),\n      )\n    }\n\n    return new AnimationClip('', -1, tracks)\n  }\n\n  /**\n   * @param {Object} vmd - parsed VMD data\n   * @param {SkinnedMesh} mesh - tracks will be fitting to mesh\n   * @return {AnimationClip}\n   */\n  buildMorphAnimation(vmd, mesh) {\n    const tracks = []\n\n    const morphs = {}\n    const morphTargetDictionary = mesh.morphTargetDictionary\n\n    for (let i = 0; i < vmd.metadata.morphCount; i++) {\n      const morph = vmd.morphs[i]\n      const morphName = morph.morphName\n\n      if (morphTargetDictionary[morphName] === undefined) continue\n\n      morphs[morphName] = morphs[morphName] || []\n      morphs[morphName].push(morph)\n    }\n\n    for (const key in morphs) {\n      const array = morphs[key]\n\n      array.sort(function (a, b) {\n        return a.frameNum - b.frameNum\n      })\n\n      const times = []\n      const values = []\n\n      for (let i = 0, il = array.length; i < il; i++) {\n        times.push(array[i].frameNum / 30)\n        values.push(array[i].weight)\n      }\n\n      tracks.push(new NumberKeyframeTrack('.morphTargetInfluences[' + morphTargetDictionary[key] + ']', times, values))\n    }\n\n    return new AnimationClip('', -1, tracks)\n  }\n\n  /**\n   * @param {Object} vmd - parsed VMD data\n   * @return {AnimationClip}\n   */\n  buildCameraAnimation(vmd) {\n    function pushVector3(array, vec) {\n      array.push(vec.x)\n      array.push(vec.y)\n      array.push(vec.z)\n    }\n\n    function pushQuaternion(array, q) {\n      array.push(q.x)\n      array.push(q.y)\n      array.push(q.z)\n      array.push(q.w)\n    }\n\n    function pushInterpolation(array, interpolation, index) {\n      array.push(interpolation[index * 4 + 0] / 127) // x1\n      array.push(interpolation[index * 4 + 1] / 127) // x2\n      array.push(interpolation[index * 4 + 2] / 127) // y1\n      array.push(interpolation[index * 4 + 3] / 127) // y2\n    }\n\n    const cameras = vmd.cameras === undefined ? [] : vmd.cameras.slice()\n\n    cameras.sort(function (a, b) {\n      return a.frameNum - b.frameNum\n    })\n\n    const times = []\n    const centers = []\n    const quaternions = []\n    const positions = []\n    const fovs = []\n\n    const cInterpolations = []\n    const qInterpolations = []\n    const pInterpolations = []\n    const fInterpolations = []\n\n    const quaternion = new Quaternion()\n    const euler = new Euler()\n    const position = new Vector3()\n    const center = new Vector3()\n\n    for (let i = 0, il = cameras.length; i < il; i++) {\n      const motion = cameras[i]\n\n      const time = motion.frameNum / 30\n      const pos = motion.position\n      const rot = motion.rotation\n      const distance = motion.distance\n      const fov = motion.fov\n      const interpolation = motion.interpolation\n\n      times.push(time)\n\n      position.set(0, 0, -distance)\n      center.set(pos[0], pos[1], pos[2])\n\n      euler.set(-rot[0], -rot[1], -rot[2])\n      quaternion.setFromEuler(euler)\n\n      position.add(center)\n      position.applyQuaternion(quaternion)\n\n      pushVector3(centers, center)\n      pushQuaternion(quaternions, quaternion)\n      pushVector3(positions, position)\n\n      fovs.push(fov)\n\n      for (let j = 0; j < 3; j++) {\n        pushInterpolation(cInterpolations, interpolation, j)\n      }\n\n      pushInterpolation(qInterpolations, interpolation, 3)\n\n      // use the same parameter for x, y, z axis.\n      for (let j = 0; j < 3; j++) {\n        pushInterpolation(pInterpolations, interpolation, 4)\n      }\n\n      pushInterpolation(fInterpolations, interpolation, 5)\n    }\n\n    const tracks = []\n\n    // I expect an object whose name 'target' exists under THREE.Camera\n    tracks.push(this._createTrack('target.position', VectorKeyframeTrack, times, centers, cInterpolations))\n\n    tracks.push(this._createTrack('.quaternion', QuaternionKeyframeTrack, times, quaternions, qInterpolations))\n    tracks.push(this._createTrack('.position', VectorKeyframeTrack, times, positions, pInterpolations))\n    tracks.push(this._createTrack('.fov', NumberKeyframeTrack, times, fovs, fInterpolations))\n\n    return new AnimationClip('', -1, tracks)\n  }\n\n  // private method\n\n  _createTrack(node, typedKeyframeTrack, times, values, interpolations) {\n    /*\n     * optimizes here not to let KeyframeTrackPrototype optimize\n     * because KeyframeTrackPrototype optimizes times and values but\n     * doesn't optimize interpolations.\n     */\n    if (times.length > 2) {\n      times = times.slice()\n      values = values.slice()\n      interpolations = interpolations.slice()\n\n      const stride = values.length / times.length\n      const interpolateStride = interpolations.length / times.length\n\n      let index = 1\n\n      for (let aheadIndex = 2, endIndex = times.length; aheadIndex < endIndex; aheadIndex++) {\n        for (let i = 0; i < stride; i++) {\n          if (\n            values[index * stride + i] !== values[(index - 1) * stride + i] ||\n            values[index * stride + i] !== values[aheadIndex * stride + i]\n          ) {\n            index++\n            break\n          }\n        }\n\n        if (aheadIndex > index) {\n          times[index] = times[aheadIndex]\n\n          for (let i = 0; i < stride; i++) {\n            values[index * stride + i] = values[aheadIndex * stride + i]\n          }\n\n          for (let i = 0; i < interpolateStride; i++) {\n            interpolations[index * interpolateStride + i] = interpolations[aheadIndex * interpolateStride + i]\n          }\n        }\n      }\n\n      times.length = index + 1\n      values.length = (index + 1) * stride\n      interpolations.length = (index + 1) * interpolateStride\n    }\n\n    const track = new typedKeyframeTrack(node, times, values)\n\n    track.createInterpolant = function InterpolantFactoryMethodCubicBezier(result) {\n      return new CubicBezierInterpolation(\n        this.times,\n        this.values,\n        this.getValueSize(),\n        result,\n        new Float32Array(interpolations),\n      )\n    }\n\n    return track\n  }\n}\n\n// interpolation\n\nclass CubicBezierInterpolation extends Interpolant {\n  constructor(parameterPositions, sampleValues, sampleSize, resultBuffer, params) {\n    super(parameterPositions, sampleValues, sampleSize, resultBuffer)\n\n    this.interpolationParams = params\n  }\n\n  interpolate_(i1, t0, t, t1) {\n    const result = this.resultBuffer\n    const values = this.sampleValues\n    const stride = this.valueSize\n    const params = this.interpolationParams\n\n    const offset1 = i1 * stride\n    const offset0 = offset1 - stride\n\n    // No interpolation if next key frame is in one frame in 30fps.\n    // This is from MMD animation spec.\n    // '1.5' is for precision loss. times are Float32 in Three.js Animation system.\n    const weight1 = t1 - t0 < (1 / 30) * 1.5 ? 0.0 : (t - t0) / (t1 - t0)\n\n    if (stride === 4) {\n      // Quaternion\n\n      const x1 = params[i1 * 4 + 0]\n      const x2 = params[i1 * 4 + 1]\n      const y1 = params[i1 * 4 + 2]\n      const y2 = params[i1 * 4 + 3]\n\n      const ratio = this._calculate(x1, x2, y1, y2, weight1)\n\n      Quaternion.slerpFlat(result, 0, values, offset0, values, offset1, ratio)\n    } else if (stride === 3) {\n      // Vector3\n\n      for (let i = 0; i !== stride; ++i) {\n        const x1 = params[i1 * 12 + i * 4 + 0]\n        const x2 = params[i1 * 12 + i * 4 + 1]\n        const y1 = params[i1 * 12 + i * 4 + 2]\n        const y2 = params[i1 * 12 + i * 4 + 3]\n\n        const ratio = this._calculate(x1, x2, y1, y2, weight1)\n\n        result[i] = values[offset0 + i] * (1 - ratio) + values[offset1 + i] * ratio\n      }\n    } else {\n      // Number\n\n      const x1 = params[i1 * 4 + 0]\n      const x2 = params[i1 * 4 + 1]\n      const y1 = params[i1 * 4 + 2]\n      const y2 = params[i1 * 4 + 3]\n\n      const ratio = this._calculate(x1, x2, y1, y2, weight1)\n\n      result[0] = values[offset0] * (1 - ratio) + values[offset1] * ratio\n    }\n\n    return result\n  }\n\n  _calculate(x1, x2, y1, y2, x) {\n    /*\n     * Cubic Bezier curves\n     *   https://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves\n     *\n     * B(t) = ( 1 - t ) ^ 3 * P0\n     *      + 3 * ( 1 - t ) ^ 2 * t * P1\n     *      + 3 * ( 1 - t ) * t^2 * P2\n     *      + t ^ 3 * P3\n     *      ( 0 <= t <= 1 )\n     *\n     * MMD uses Cubic Bezier curves for bone and camera animation interpolation.\n     *   http://d.hatena.ne.jp/edvakf/20111016/1318716097\n     *\n     *    x = ( 1 - t ) ^ 3 * x0\n     *      + 3 * ( 1 - t ) ^ 2 * t * x1\n     *      + 3 * ( 1 - t ) * t^2 * x2\n     *      + t ^ 3 * x3\n     *    y = ( 1 - t ) ^ 3 * y0\n     *      + 3 * ( 1 - t ) ^ 2 * t * y1\n     *      + 3 * ( 1 - t ) * t^2 * y2\n     *      + t ^ 3 * y3\n     *      ( x0 = 0, y0 = 0 )\n     *      ( x3 = 1, y3 = 1 )\n     *      ( 0 <= t, x1, x2, y1, y2 <= 1 )\n     *\n     * Here solves this equation with Bisection method,\n     *   https://en.wikipedia.org/wiki/Bisection_method\n     * gets t, and then calculate y.\n     *\n     * f(t) = 3 * ( 1 - t ) ^ 2 * t * x1\n     *      + 3 * ( 1 - t ) * t^2 * x2\n     *      + t ^ 3 - x = 0\n     *\n     * (Another option: Newton's method\n     *    https://en.wikipedia.org/wiki/Newton%27s_method)\n     */\n\n    let c = 0.5\n    let t = c\n    let s = 1.0 - t\n    const loop = 15\n    const eps = 1e-5\n    const math = Math\n\n    let sst3, stt3, ttt\n\n    for (let i = 0; i < loop; i++) {\n      sst3 = 3.0 * s * s * t\n      stt3 = 3.0 * s * t * t\n      ttt = t * t * t\n\n      const ft = sst3 * x1 + stt3 * x2 + ttt - x\n\n      if (math.abs(ft) < eps) break\n\n      c /= 2.0\n\n      t += ft < 0 ? c : -c\n      s = 1.0 - t\n    }\n\n    return sst3 * y1 + stt3 * y2 + ttt\n  }\n}\n\nexport { MMDLoader }\n"],"names":["Loader","FileLoader","LoaderUtils","Parser","SkinnedMesh","Skeleton","Bone","Vector3","Float32BufferAttribute","BufferGeometry","Uint16BufferAttribute","TextureLoader","Color","CustomBlending","SrcAlphaFactor","OneMinusSrcAlphaFactor","DstAlphaFactor","DoubleSide","FrontSide","MultiplyOperation","AddOperation","MeshToonMaterial","materials","TGALoader","NearestFilter","RepeatWrapping","AnimationClip","VectorKeyframeTrack","QuaternionKeyframeTrack","NumberKeyframeTrack","Quaternion","Euler","Interpolant"],"mappings":";;;;;AAmEA,MAAM,kBAAkBA,MAAAA,OAAO;AAAA,EAC7B,YAAY,SAAS;AACnB,UAAM,OAAO;AAEb,SAAK,SAAS,IAAIC,iBAAW,KAAK,OAAO;AAEzC,SAAK,SAAS;AACd,SAAK,cAAc,IAAI,YAAY,KAAK,OAAO;AAC/C,SAAK,mBAAmB,IAAI,iBAAkB;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMD,iBAAiB,eAAe;AAC9B,SAAK,gBAAgB;AACrB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYD,KAAK,KAAK,QAAQ,YAAY,SAAS;AACrC,UAAM,UAAU,KAAK,YAAY,eAAe,KAAK,WAAW;AAIhE,QAAI;AAEJ,QAAI,KAAK,iBAAiB,IAAI;AAC5B,qBAAe,KAAK;AAAA,IAC1B,WAAe,KAAK,SAAS,IAAI;AAC3B,qBAAe,KAAK;AAAA,IAC1B,OAAW;AACL,qBAAeC,MAAAA,YAAY,eAAe,GAAG;AAAA,IAC9C;AAED,UAAM,iBAAiB,KAAK,kBAAkB,GAAG,EAAE,YAAa;AAGhE,QAAI,mBAAmB,SAAS,mBAAmB,OAAO;AACxD,UAAI;AAAS,gBAAQ,IAAI,MAAM,oDAAoD,iBAAiB,GAAG,CAAC;AAExG;AAAA,IACD;AAED,SAAK,mBAAmB,QAAQ,YAAY,SAAS;AAAA,MACnD;AAAA,MACA,SAAU,MAAM;AACd,eAAO,QAAQ,MAAM,MAAM,cAAc,YAAY,OAAO,CAAC;AAAA,MAC9D;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYD,cAAc,KAAK,QAAQ,QAAQ,YAAY,SAAS;AACtD,UAAM,UAAU,KAAK;AAErB,SAAK;AAAA,MACH;AAAA,MACA,SAAU,KAAK;AACb,eAAO,OAAO,WAAW,QAAQ,qBAAqB,GAAG,IAAI,QAAQ,MAAM,KAAK,MAAM,CAAC;AAAA,MACxF;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaD,kBAAkB,UAAU,QAAQ,QAAQ,YAAY,SAAS;AAC/D,UAAM,QAAQ;AAEd,SAAK;AAAA,MACH;AAAA,MACA,SAAU,MAAM;AACd,cAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA,SAAU,WAAW;AACnB,mBAAO;AAAA,cACL;AAAA,cACA;AAAA,YACd,CAAa;AAAA,UACF;AAAA,UACD;AAAA,UACA;AAAA,QACD;AAAA,MACF;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAYD,QAAQ,KAAK,QAAQ,YAAY,SAAS;AACxC,UAAM,SAAS,KAAK,WAAY;AAEhC,SAAK,OACF,YAAY,MAAS,EACrB,QAAQ,KAAK,IAAI,EACjB,gBAAgB,aAAa,EAC7B,iBAAiB,KAAK,aAAa,EACnC,mBAAmB,KAAK,eAAe,EACvC;AAAA,MACC;AAAA,MACA,SAAU,QAAQ;AAChB,eAAO,OAAO,SAAS,QAAQ,IAAI,CAAC;AAAA,MACrC;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUD,QAAQ,KAAK,QAAQ,YAAY,SAAS;AACxC,UAAM,SAAS,KAAK,WAAY;AAEhC,SAAK,OACF,YAAY,MAAS,EACrB,QAAQ,KAAK,IAAI,EACjB,gBAAgB,aAAa,EAC7B,iBAAiB,KAAK,aAAa,EACnC,mBAAmB,KAAK,eAAe,EACvC;AAAA,MACC;AAAA,MACA,SAAU,QAAQ;AAChB,eAAO,OAAO,SAAS,QAAQ,IAAI,CAAC;AAAA,MACrC;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWD,QAAQ,KAAK,QAAQ,YAAY,SAAS;AACxC,UAAM,OAAO,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,GAAG;AAE5C,UAAM,OAAO,CAAE;AACf,UAAM,SAAS,KAAK;AAEpB,UAAM,SAAS,KAAK,WAAY;AAEhC,SAAK,OACF,YAAY,MAAS,EACrB,QAAQ,KAAK,aAAa,EAC1B,gBAAgB,aAAa,EAC7B,iBAAiB,KAAK,aAAa,EACnC,mBAAmB,KAAK,eAAe;AAE1C,aAAS,IAAI,GAAG,KAAK,KAAK,QAAQ,IAAI,IAAI,KAAK;AAC7C,WAAK,OAAO;AAAA,QACV,KAAK,CAAC;AAAA,QACN,SAAU,QAAQ;AAChB,eAAK,KAAK,OAAO,SAAS,QAAQ,IAAI,CAAC;AAEvC,cAAI,KAAK,WAAW;AAAQ,mBAAO,OAAO,UAAU,IAAI,CAAC;AAAA,QAC1D;AAAA,QACD;AAAA,QACA;AAAA,MACD;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWD,QAAQ,KAAK,WAAW,QAAQ,YAAY,SAAS;AACnD,UAAM,SAAS,KAAK,WAAY;AAEhC,SAAK,OACF,YAAY,YAAY,SAAY,+BAA+B,EACnE,QAAQ,KAAK,aAAa,EAC1B,gBAAgB,MAAM,EACtB,iBAAiB,KAAK,aAAa,EACnC,mBAAmB,KAAK,eAAe,EACvC;AAAA,MACC;AAAA,MACA,SAAU,MAAM;AACd,eAAO,OAAO,SAAS,MAAM,IAAI,CAAC;AAAA,MACnC;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAAA,EACJ;AAAA;AAAA,EAID,kBAAkB,KAAK;AACrB,UAAM,QAAQ,IAAI,YAAY,GAAG;AACjC,WAAO,QAAQ,IAAI,KAAK,IAAI,MAAM,QAAQ,CAAC;AAAA,EAC5C;AAAA,EAED,aAAa;AACX,QAAI,KAAK,WAAW,MAAM;AACxB,WAAK,SAAS,IAAIC,iBAAQ;AAAA,IAC3B;AAED,WAAO,KAAK;AAAA,EACb;AACH;AASA,MAAM,wBAAwB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAOA,MAAM,YAAY;AAAA,EAChB,YAAY,SAAS;AACnB,SAAK,cAAc;AACnB,SAAK,kBAAkB,IAAI,gBAAiB;AAC5C,SAAK,kBAAkB,IAAI,gBAAgB,OAAO;AAAA,EACnD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMD,eAAe,aAAa;AAC1B,SAAK,cAAc;AACnB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASD,MAAM,MAAM,cAAc,YAAY,SAAS;AAC7C,UAAM,WAAW,KAAK,gBAAgB,MAAM,IAAI;AAChD,UAAM,WAAW,KAAK,gBACnB,eAAe,KAAK,WAAW,EAC/B,gBAAgB,YAAY,EAC5B,MAAM,MAAM,UAAU,YAAY,OAAO;AAE5C,UAAM,OAAO,IAAIC,kBAAY,UAAU,QAAQ;AAE/C,UAAM,WAAW,IAAIC,MAAAA,SAAS,UAAU,IAAI,CAAC;AAC7C,SAAK,KAAK,QAAQ;AAIlB,WAAO;AAAA,EACR;AACH;AAIA,SAAS,UAAU,MAAM;AACvB,QAAM,WAAW,KAAK;AAEtB,QAAM,QAAQ,CAAE;AAEhB,MAAI,YAAY,SAAS,UAAU,QAAW;AAG5C,aAAS,IAAI,GAAG,KAAK,SAAS,MAAM,QAAQ,IAAI,IAAI,KAAK;AACvD,YAAM,QAAQ,SAAS,MAAM,CAAC;AAI9B,YAAM,OAAO,IAAIC,WAAM;AACvB,YAAM,KAAK,IAAI;AAIf,WAAK,OAAO,MAAM;AAClB,WAAK,SAAS,UAAU,MAAM,GAAG;AACjC,WAAK,WAAW,UAAU,MAAM,IAAI;AACpC,UAAI,MAAM,QAAQ;AAAW,aAAK,MAAM,UAAU,MAAM,GAAG;AAAA,IAC5D;AAID,aAAS,IAAI,GAAG,KAAK,SAAS,MAAM,QAAQ,IAAI,IAAI,KAAK;AACvD,YAAM,QAAQ,SAAS,MAAM,CAAC;AAE9B,UAAI,MAAM,WAAW,MAAM,MAAM,WAAW,QAAQ,MAAM,MAAM,MAAM,MAAM,QAAW;AAGrF,cAAM,MAAM,MAAM,EAAE,IAAI,MAAM,CAAC,CAAC;AAAA,MACxC,OAAa;AAGL,aAAK,IAAI,MAAM,CAAC,CAAC;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAKD,OAAK,kBAAkB,IAAI;AAE3B,SAAO;AACT;AAIA,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,EAKpB,MAAM,MAAM;AAEV,UAAM,YAAY,CAAE;AACpB,UAAM,MAAM,CAAE;AACd,UAAM,UAAU,CAAE;AAElB,UAAM,UAAU,CAAE;AAElB,UAAM,SAAS,CAAE;AAEjB,UAAM,QAAQ,CAAE;AAChB,UAAM,cAAc,CAAE;AACtB,UAAM,cAAc,CAAE;AAEtB,UAAM,eAAe,CAAE;AACvB,UAAM,iBAAiB,CAAE;AAEzB,UAAM,MAAM,CAAE;AACd,UAAM,SAAS,CAAE;AAEjB,UAAM,cAAc,CAAE;AACtB,UAAM,cAAc,CAAE;AAGtB,QAAI,SAAS;AACb,UAAM,gBAAgB,CAAE;AAIxB,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,aAAa,KAAK;AAClD,YAAM,IAAI,KAAK,SAAS,CAAC;AAEzB,eAAS,IAAI,GAAG,KAAK,EAAE,SAAS,QAAQ,IAAI,IAAI,KAAK;AACnD,kBAAU,KAAK,EAAE,SAAS,CAAC,CAAC;AAAA,MAC7B;AAED,eAAS,IAAI,GAAG,KAAK,EAAE,OAAO,QAAQ,IAAI,IAAI,KAAK;AACjD,gBAAQ,KAAK,EAAE,OAAO,CAAC,CAAC;AAAA,MACzB;AAED,eAAS,IAAI,GAAG,KAAK,EAAE,GAAG,QAAQ,IAAI,IAAI,KAAK;AAC7C,YAAI,KAAK,EAAE,GAAG,CAAC,CAAC;AAAA,MACjB;AAED,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,oBAAY,KAAK,EAAE,YAAY,SAAS,KAAK,IAAI,EAAE,YAAY,CAAC,IAAI,CAAG;AAAA,MACxE;AAED,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,oBAAY,KAAK,EAAE,YAAY,SAAS,KAAK,IAAI,EAAE,YAAY,CAAC,IAAI,CAAG;AAAA,MACxE;AAAA,IACF;AAID,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,WAAW,KAAK;AAChD,YAAM,OAAO,KAAK,MAAM,CAAC;AAEzB,eAAS,IAAI,GAAG,KAAK,KAAK,QAAQ,QAAQ,IAAI,IAAI,KAAK;AACrD,gBAAQ,KAAK,KAAK,QAAQ,CAAC,CAAC;AAAA,MAC7B;AAAA,IACF;AAID,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,eAAe,KAAK;AACpD,YAAM,WAAW,KAAK,UAAU,CAAC;AAEjC,aAAO,KAAK;AAAA,QACV,QAAQ,SAAS;AAAA,QACjB,OAAO,SAAS,YAAY;AAAA,MACpC,CAAO;AAED,gBAAU,SAAS;AAAA,IACpB;AAID,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,gBAAgB,KAAK;AACrD,YAAM,OAAO,KAAK,YAAY,CAAC;AAC/B,UAAI,QAAQ,cAAc,KAAK,SAAS;AAGxC,cAAQ,UAAU,SAAY,KAAK,OAAO,KAAK,IAAI,KAAK,MAAM,KAAK;AAEnE,oBAAc,KAAK,SAAS,IAAI;AAAA,IACjC;AAED,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,WAAW,KAAK;AAChD,YAAM,WAAW,KAAK,MAAM,CAAC;AAE7B,YAAM,OAAO;AAAA,QACX,OAAO;AAAA,QACP,qBAAqB,SAAS;AAAA,QAC9B,QAAQ,SAAS;AAAA,QACjB,MAAM,SAAS;AAAA,QACf,KAAK,SAAS,SAAS,MAAM,GAAG,CAAC;AAAA,QACjC,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;AAAA,QACjB,KAAK,CAAC,GAAG,GAAG,CAAC;AAAA,QACb,eAAe,cAAc,CAAC,MAAM,SAAY,cAAc,CAAC,IAAI;AAAA,MACpE;AAED,UAAI,KAAK,WAAW,IAAI;AACtB,aAAK,IAAI,CAAC,KAAK,KAAK,MAAM,KAAK,MAAM,EAAE,SAAS,CAAC;AACjD,aAAK,IAAI,CAAC,KAAK,KAAK,MAAM,KAAK,MAAM,EAAE,SAAS,CAAC;AACjD,aAAK,IAAI,CAAC,KAAK,KAAK,MAAM,KAAK,MAAM,EAAE,SAAS,CAAC;AAAA,MAClD;AAED,YAAM,KAAK,IAAI;AAAA,IAChB;AAKD,QAAI,KAAK,SAAS,WAAW,OAAO;AAClC,eAAS,IAAI,GAAG,IAAI,KAAK,SAAS,SAAS,KAAK;AAC9C,cAAM,KAAK,KAAK,IAAI,CAAC;AAErB,cAAM,QAAQ;AAAA,UACZ,QAAQ,GAAG;AAAA,UACX,UAAU,GAAG;AAAA,UACb,WAAW,GAAG;AAAA,UACd,UAAU,GAAG,WAAW;AAAA,UACxB,OAAO,CAAE;AAAA,QACV;AAED,iBAAS,IAAI,GAAG,KAAK,GAAG,MAAM,QAAQ,IAAI,IAAI,KAAK;AACjD,gBAAM,OAAO,CAAE;AACf,eAAK,QAAQ,GAAG,MAAM,CAAC,EAAE;AACzB,eAAK,UAAU;AAEf,cAAI,KAAK,MAAM,KAAK,KAAK,EAAE,KAAK,QAAQ,IAAI,KAAK,GAAG;AAClD,iBAAK,aAAa,IAAIC,MAAAA,QAAQ,GAAK,GAAK,CAAG;AAAA,UAC5C;AAED,gBAAM,MAAM,KAAK,IAAI;AAAA,QACtB;AAED,YAAI,KAAK,KAAK;AAAA,MACf;AAAA,IACP,OAAW;AACL,eAAS,IAAI,GAAG,IAAI,KAAK,SAAS,WAAW,KAAK;AAChD,cAAM,KAAK,KAAK,MAAM,CAAC,EAAE;AAEzB,YAAI,OAAO;AAAW;AAEtB,cAAM,QAAQ;AAAA,UACZ,QAAQ;AAAA,UACR,UAAU,GAAG;AAAA,UACb,WAAW,GAAG;AAAA,UACd,UAAU,GAAG;AAAA,UACb,OAAO,CAAE;AAAA,QACV;AAED,iBAAS,IAAI,GAAG,KAAK,GAAG,MAAM,QAAQ,IAAI,IAAI,KAAK;AACjD,gBAAM,OAAO,CAAE;AACf,eAAK,QAAQ,GAAG,MAAM,CAAC,EAAE;AACzB,eAAK,UAAU;AAEf,cAAI,GAAG,MAAM,CAAC,EAAE,oBAAoB,GAAG;AAIrC,kBAAM,cAAc,GAAG,MAAM,CAAC,EAAE;AAChC,kBAAM,cAAc,GAAG,MAAM,CAAC,EAAE;AAKhC,kBAAM,OAAO,CAAC,YAAY,CAAC;AAC3B,kBAAM,OAAO,CAAC,YAAY,CAAC;AAC3B,wBAAY,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,wBAAY,CAAC,IAAI,CAAC,YAAY,CAAC;AAC/B,wBAAY,CAAC,IAAI;AACjB,wBAAY,CAAC,IAAI;AAEjB,iBAAK,cAAc,IAAIA,MAAO,QAAA,EAAG,UAAU,WAAW;AACtD,iBAAK,cAAc,IAAIA,MAAO,QAAA,EAAG,UAAU,WAAW;AAAA,UACvD;AAED,gBAAM,MAAM,KAAK,IAAI;AAAA,QACtB;AAED,YAAI,KAAK,KAAK;AAId,cAAM,CAAC,EAAE,KAAK;AAAA,MACf;AAAA,IACF;AAID,QAAI,KAAK,SAAS,WAAW,OAAO;AAuClC,UAAS,WAAT,SAAkB,OAAO;AACvB,YAAI,MAAM,OAAO;AACf,iBAAO,KAAK,MAAM,KAAK;AAIvB,gBAAM,MAAM,MAAM,KAAK,EAAE,QAAQ,MAAM;AAAA,QACxC;AAED,cAAM,UAAU;AAEhB,iBAAS,IAAI,GAAG,KAAK,MAAM,SAAS,QAAQ,IAAI,IAAI,KAAK;AACvD,gBAAM,QAAQ,MAAM,SAAS,CAAC;AAG9B,cAAI,CAAC,MAAM;AAAS,qBAAS,KAAK;AAAA,QACnC;AAAA,MACF;AAtDD,YAAM,gBAAgB,CAAE;AAExB,eAAS,IAAI,GAAG,IAAI,KAAK,SAAS,WAAW,KAAK;AAChD,cAAM,WAAW,KAAK,MAAM,CAAC;AAC7B,cAAM,QAAQ,SAAS;AAEvB,YAAI,UAAU;AAAW;AAEzB,cAAM,QAAQ;AAAA,UACZ,OAAO;AAAA,UACP,aAAa,MAAM;AAAA,UACnB,OAAO,MAAM;AAAA,UACb,SAAS,MAAM;AAAA,UACf,gBAAgB,MAAM;AAAA,UACtB,gBAAgB,MAAM;AAAA,UACtB,qBAAqB,SAAS;AAAA,QAC/B;AAED,sBAAc,CAAC,IAAI,EAAE,QAAQ,MAAM,UAAU,CAAA,GAAI,OAAc,SAAS,MAAO;AAAA,MAChF;AAED,YAAM,YAAY,EAAE,QAAQ,MAAM,UAAU,CAAE,GAAE,OAAO,MAAM,SAAS,MAAO;AAI7E,iBAAW,aAAa,eAAe;AACrC,cAAM,aAAa,cAAc,SAAS;AAC1C,cAAM,mBAAmB,cAAc,WAAW,WAAW,KAAK;AAElE,mBAAW,SAAS;AACpB,yBAAiB,SAAS,KAAK,UAAU;AAAA,MAC1C;AAyBD,eAAS,SAAS;AAAA,IACnB;AAID,aAAS,iBAAiB,WAAW,OAAO,OAAO;AACjD,eAAS,IAAI,GAAG,IAAI,MAAM,cAAc,KAAK;AAC3C,cAAM,UAAU,MAAM,SAAS,CAAC;AAEhC,YAAI;AAEJ,YAAI,KAAK,SAAS,WAAW,OAAO;AAClC,kBAAQ,KAAK,OAAO,CAAC,EAAE,SAAS,QAAQ,KAAK,EAAE;AAAA,QACzD,OAAe;AACL,kBAAQ,QAAQ;AAAA,QACjB;AAED,kBAAU,MAAM,QAAQ,IAAI,CAAC,KAAK,QAAQ,SAAS,CAAC,IAAI;AACxD,kBAAU,MAAM,QAAQ,IAAI,CAAC,KAAK,QAAQ,SAAS,CAAC,IAAI;AACxD,kBAAU,MAAM,QAAQ,IAAI,CAAC,KAAK,QAAQ,SAAS,CAAC,IAAI;AAAA,MACzD;AAAA,IACF;AAED,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,YAAY,KAAK;AACjD,YAAM,QAAQ,KAAK,OAAO,CAAC;AAC3B,YAAM,SAAS,EAAE,MAAM,MAAM,KAAM;AAEnC,YAAM,YAAY,IAAIC,6BAAuB,KAAK,SAAS,cAAc,GAAG,CAAC;AAC7E,gBAAU,OAAO,MAAM;AAEvB,eAAS,IAAI,GAAG,IAAI,KAAK,SAAS,cAAc,GAAG,KAAK;AACtD,kBAAU,MAAM,CAAC,IAAI,UAAU,CAAC;AAAA,MACjC;AAED,UAAI,KAAK,SAAS,WAAW,OAAO;AAClC,YAAI,MAAM,GAAG;AACX,2BAAiB,WAAW,OAAO,CAAG;AAAA,QACvC;AAAA,MACT,OAAa;AACL,YAAI,MAAM,SAAS,GAAG;AAGpB,mBAAS,IAAI,GAAG,IAAI,MAAM,cAAc,KAAK;AAC3C,kBAAM,SAAS,KAAK,OAAO,MAAM,SAAS,CAAC,EAAE,KAAK;AAClD,kBAAM,QAAQ,MAAM,SAAS,CAAC,EAAE;AAEhC,gBAAI,OAAO,SAAS,GAAG;AACrB,+BAAiB,WAAW,QAAQ,KAAK;AAAA,YAG1C;AAAA,UACF;AAAA,QACX,WAAmB,MAAM,SAAS,GAAG;AAG3B,2BAAiB,WAAW,OAAO,CAAG;AAAA,QAChD,WAAmB,MAAM,SAAS;AAAG;AAAA,iBAGlB,MAAM,SAAS;AAAG;AAAA,iBAGlB,MAAM,SAAS;AAAG;AAAA,iBAGlB,MAAM,SAAS;AAAG;AAAA,iBAGlB,MAAM,SAAS;AAAG;AAAA,iBAGlB,MAAM,SAAS;AAAG;AAAA,iBAGlB,MAAM,SAAS;AAAG;AAAA,MAI9B;AAED,mBAAa,KAAK,MAAM;AACxB,qBAAe,KAAK,SAAS;AAAA,IAC9B;AAID,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,gBAAgB,KAAK;AACrD,YAAM,YAAY,KAAK,YAAY,CAAC;AACpC,YAAM,SAAS,CAAE;AAEjB,iBAAW,OAAO,WAAW;AAC3B,eAAO,GAAG,IAAI,UAAU,GAAG;AAAA,MAC5B;AAOD,UAAI,KAAK,SAAS,WAAW,OAAO;AAClC,YAAI,OAAO,cAAc,IAAI;AAC3B,gBAAM,OAAO,KAAK,MAAM,OAAO,SAAS;AACxC,iBAAO,SAAS,CAAC,KAAK,KAAK,SAAS,CAAC;AACrC,iBAAO,SAAS,CAAC,KAAK,KAAK,SAAS,CAAC;AACrC,iBAAO,SAAS,CAAC,KAAK,KAAK,SAAS,CAAC;AAAA,QACtC;AAAA,MACF;AAED,kBAAY,KAAK,MAAM;AAAA,IACxB;AAID,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,iBAAiB,KAAK;AACtD,YAAM,aAAa,KAAK,YAAY,CAAC;AACrC,YAAM,SAAS,CAAE;AAEjB,iBAAW,OAAO,YAAY;AAC5B,eAAO,GAAG,IAAI,WAAW,GAAG;AAAA,MAC7B;AAED,YAAM,QAAQ,YAAY,OAAO,eAAe;AAChD,YAAM,QAAQ,YAAY,OAAO,eAAe;AAGhD,UAAI,MAAM,SAAS,KAAK,MAAM,SAAS,GAAG;AACxC,YACE,MAAM,cAAc,MACpB,MAAM,cAAc,MACpB,KAAK,MAAM,MAAM,SAAS,EAAE,gBAAgB,MAAM,WAClD;AACA,gBAAM,OAAO;AAAA,QACd;AAAA,MACF;AAED,kBAAY,KAAK,MAAM;AAAA,IACxB;AAID,UAAM,WAAW,IAAIC,qBAAgB;AAErC,aAAS,aAAa,YAAY,IAAID,MAAAA,uBAAuB,WAAW,CAAC,CAAC;AAC1E,aAAS,aAAa,UAAU,IAAIA,MAAAA,uBAAuB,SAAS,CAAC,CAAC;AACtE,aAAS,aAAa,MAAM,IAAIA,MAAAA,uBAAuB,KAAK,CAAC,CAAC;AAC9D,aAAS,aAAa,aAAa,IAAIE,MAAAA,sBAAsB,aAAa,CAAC,CAAC;AAC5E,aAAS,aAAa,cAAc,IAAIF,MAAAA,uBAAuB,aAAa,CAAC,CAAC;AAC9E,aAAS,SAAS,OAAO;AAEzB,aAAS,IAAI,GAAG,KAAK,OAAO,QAAQ,IAAI,IAAI,KAAK;AAC/C,eAAS,SAAS,OAAO,CAAC,EAAE,QAAQ,OAAO,CAAC,EAAE,OAAO,CAAC;AAAA,IACvD;AAED,aAAS,QAAQ;AAEjB,aAAS,eAAe;AACxB,aAAS,gBAAgB,WAAW;AACpC,aAAS,uBAAuB;AAEhC,aAAS,SAAS,MAAM;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,KAAK,SAAS;AAAA,IACvB;AAED,aAAS,sBAAuB;AAEhC,WAAO;AAAA,EACR;AACH;AAOA,MAAM,gBAAgB;AAAA,EACpB,YAAY,SAAS;AACnB,SAAK,UAAU;AAEf,SAAK,gBAAgB,IAAIG,oBAAc,KAAK,OAAO;AACnD,SAAK,YAAY;AAEjB,SAAK,cAAc;AACnB,SAAK,eAAe;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMD,eAAe,aAAa;AAC1B,SAAK,cAAc;AACnB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA,EAMD,gBAAgB,cAAc;AAC5B,SAAK,eAAe;AACpB,WAAO;AAAA,EACR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASD,MAAM,MAAM,UAAqC;AAC/C,UAAM,YAAY,CAAE;AAEpB,UAAM,WAAW,CAAE;AAEnB,SAAK,cAAc,eAAe,KAAK,WAAW;AAIlD,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,eAAe,KAAK;AACpD,YAAM,WAAW,KAAK,UAAU,CAAC;AAEjC,YAAM,SAAS,EAAE,UAAU,GAAI;AAE/B,UAAI,SAAS,SAAS;AAAW,eAAO,OAAO,SAAS;AAaxD,aAAO,QAAQ,IAAIC,MAAAA,MAAO,EAAC,UAAU,SAAS,OAAO;AACrD,aAAO,UAAU,SAAS,QAAQ,CAAC;AACnC,aAAO,WAAW,IAAIA,MAAAA,MAAO,EAAC,UAAU,SAAS,OAAO;AACxD,aAAO,cAAc,OAAO,YAAY;AAIxC,aAAO,WAAW,SAAS,MAAM,SAAS,IAAI,OAAO;AACrD,aAAO,eAAe,SAAS,aAAa,SAAS,IAAI,OAAO;AAChE,aAAO,MAAM;AAIb,aAAO,WAAWC,MAAc;AAChC,aAAO,WAAWC,MAAc;AAChC,aAAO,WAAWC,MAAsB;AACxC,aAAO,gBAAgBD,MAAc;AACrC,aAAO,gBAAgBE,MAAc;AAIrC,UAAI,KAAK,SAAS,WAAW,UAAU,SAAS,OAAO,OAAS,GAAG;AACjE,eAAO,OAAOC,MAAU;AAAA,MAChC,OAAa;AACL,eAAO,OAAO,OAAO,YAAY,IAAMC,MAAS,YAAGD,MAAU;AAAA,MAC9D;AAED,UAAI,KAAK,SAAS,WAAW,OAAO;AAGlC,YAAI,SAAS,UAAU;AACrB,gBAAM,WAAW,SAAS;AAC1B,gBAAM,YAAY,SAAS,MAAM,GAAG;AAKpC,iBAAO,MAAM,KAAK,aAAa,UAAU,CAAC,GAAG,QAAQ;AAErD,cAAI,UAAU,SAAS,GAAG;AACxB,kBAAM,YAAY,UAAU,CAAC,EAAE,MAAM,EAAE,EAAE,YAAa;AAEtD,mBAAO,SAAS,KAAK,aAAa,UAAU,CAAC,GAAG,QAAQ;AAExD,mBAAO,UAAU,cAAc,SAASE,MAAiB,oBAAGC,MAAY;AAAA,UACzE;AAAA,QACF;AAID,cAAM,eAAe,SAAS,cAAc,KAAK,eAAe,KAAK,aAAa,SAAS,SAAS,EAAE;AAEtG,eAAO,cAAc,KAAK,aAAa,cAAc,UAAU;AAAA,UAC7D,eAAe;AAAA,UACf,sBAAsB,KAAK,sBAAsB,YAAY;AAAA,QACvE,CAAS;AAID,eAAO,SAAS,oBAAoB;AAAA,UAClC,WAAW,SAAS,aAAa,IAAI,OAAQ;AAAA,UAC7C,OAAO,CAAC,GAAG,GAAG,CAAC;AAAA,UACf,OAAO;AAAA,UACP,SAAS,SAAS,aAAa;AAAA,QAChC;AAAA,MACT,OAAa;AAGL,YAAI,SAAS,iBAAiB,IAAI;AAChC,iBAAO,MAAM,KAAK,aAAa,KAAK,SAAS,SAAS,YAAY,GAAG,QAAQ;AAAA,QAC9E;AAID,YAAI,SAAS,oBAAoB,OAAO,SAAS,YAAY,KAAK,SAAS,WAAW,IAAI;AACxF,iBAAO,SAAS,KAAK,aAAa,KAAK,SAAS,SAAS,eAAe,GAAG,QAAQ;AAEnF,iBAAO,UAAU,SAAS,YAAY,IAAID,MAAiB,oBAAGC,MAAY;AAAA,QAC3E;AAID,YAAI,cAAc;AAElB,YAAI,SAAS,cAAc,MAAM,SAAS,aAAa,GAAG;AACxD,yBAAe,UAAU,OAAO,SAAS,YAAY,IAAI,MAAM,EAAE,IAAI;AACrE,0BAAgB;AAAA,QAC1B,OAAe;AACL,yBAAe,KAAK,SAAS,SAAS,SAAS;AAC/C,0BAAgB;AAAA,QACjB;AAED,eAAO,cAAc,KAAK,aAAa,cAAc,UAAU;AAAA,UAC7D,eAAe;AAAA,UACf,sBAAsB;AAAA,QAChC,CAAS;AAGD,eAAO,SAAS,oBAAoB;AAAA,UAClC,WAAW,SAAS,WAAW;AAAA;AAAA,UAC/B,OAAO,SAAS,UAAU,MAAM,GAAG,CAAC;AAAA,UACpC,OAAO,SAAS,UAAU,CAAC;AAAA,UAC3B,UAAU,SAAS,OAAO,QAAU,KAAK,SAAS,WAAW;AAAA,QAC9D;AAAA,MACF;AAED,UAAI,OAAO,QAAQ,QAAW;AAC5B,YAAI,CAAC,OAAO,aAAa;AACvB,eAAK,wBAAwB,OAAO,KAAK,UAAU,CAAC;AAAA,QACrD;AAED,eAAO,SAAS,eAAe,GAAG;AAAA,MACnC;AAED,gBAAU,KAAK,IAAIC,MAAgB,iBAAC,MAAM,CAAC;AAAA,IAC5C;AAED,QAAI,KAAK,SAAS,WAAW,OAAO;AAGlC,UAAS,kBAAT,SAAyB,UAAUC,YAAW;AAC5C,iBAAS,IAAI,GAAG,KAAK,SAAS,QAAQ,IAAI,IAAI,KAAK;AACjD,gBAAM,UAAU,SAAS,CAAC;AAE1B,cAAI,QAAQ,UAAU;AAAI;AAE1B,gBAAM,WAAWA,WAAU,QAAQ,KAAK;AAExC,cAAI,SAAS,YAAY,QAAQ,QAAQ,CAAC,GAAG;AAC3C,qBAAS,cAAc;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAED,eAAS,IAAI,GAAG,KAAK,KAAK,OAAO,QAAQ,IAAI,IAAI,KAAK;AACpD,cAAM,QAAQ,KAAK,OAAO,CAAC;AAC3B,cAAM,WAAW,MAAM;AAEvB,YAAI,MAAM,SAAS,GAAG;AACpB,mBAAS,IAAI,GAAG,KAAK,SAAS,QAAQ,IAAI,IAAI,KAAK;AACjD,kBAAM,SAAS,KAAK,OAAO,SAAS,CAAC,EAAE,KAAK;AAE5C,gBAAI,OAAO,SAAS;AAAG;AAEvB,4BAAgB,OAAO,UAAU,SAAS;AAAA,UAC3C;AAAA,QACX,WAAmB,MAAM,SAAS,GAAG;AAC3B,0BAAgB,UAAU,SAAS;AAAA,QACpC;AAAA,MACF;AAAA,IACF;AAED,WAAO;AAAA,EACR;AAAA;AAAA,EAID,gBAAgB;AACd,QAAI,KAAK,cAAc,MAAM;AAC3B,UAAIC,UAAAA,cAAc,QAAW;AAC3B,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACpD;AAED,WAAK,YAAY,IAAIA,oBAAU,KAAK,OAAO;AAAA,IAC5C;AAED,WAAO,KAAK;AAAA,EACb;AAAA,EAED,sBAAsB,MAAM;AAC1B,QAAI,KAAK,WAAW;AAAI,aAAO;AAE/B,WAAO,uBAAuB,KAAK,IAAI;AAAA,EACxC;AAAA,EAED,aAAa,UAAU,UAAU,QAAQ,YAAY,SAAS;AAC5D,aAAS,UAAU,CAAE;AAErB,UAAM,QAAQ;AAEd,QAAI;AAEJ,QAAI,OAAO,yBAAyB,MAAM;AACxC,UAAI;AAEJ,UAAI;AACF,gBAAQ,SAAS,SAAS,MAAM,sBAAsB,EAAE,CAAC,CAAC;AAAA,MAC3D,SAAQ,GAAP;AACA,gBAAQ;AAAA,UACN,sBACE,WACA;AAAA,QAEH;AAED,gBAAQ;AAAA,MACT;AAED,iBAAW,sBAAsB,KAAK;AAAA,IAC5C,OAAW;AACL,iBAAW,KAAK,eAAe;AAAA,IAChC;AAED,QAAI,SAAS,QAAQ,MAAM;AAAW,aAAO,SAAS,QAAQ;AAE9D,QAAI,SAAS,KAAK,QAAQ,WAAW,QAAQ;AAE7C,QAAI,WAAW,MAAM;AACnB,eAAS,SAAS,MAAM,EAAE,EAAE,kBAAkB,SAAS,KAAK,cAAe,IAAG,KAAK;AAAA,IACpF;AAED,UAAM,UAAU,OAAO;AAAA,MACrB;AAAA,MACA,SAAU,GAAG;AAIX,YAAI,OAAO,kBAAkB,MAAM;AACjC,YAAE,QAAQ,MAAM,iBAAiB,EAAE,KAAK;AAExC,YAAE,YAAYC,MAAa;AAC3B,YAAE,YAAYA,MAAa;AAAA,QAC5B;AAED,UAAE,QAAQ;AACV,UAAE,QAAQC,MAAc;AACxB,UAAE,QAAQA,MAAc;AAExB,iBAAS,IAAI,GAAG,IAAI,QAAQ,eAAe,QAAQ,KAAK;AACtD,kBAAQ,eAAe,CAAC,EAAE,OAAO;AAAA,QAClC;AAED,eAAO,QAAQ;AAAA,MAChB;AAAA,MACD;AAAA,MACA;AAAA,IACD;AAED,YAAQ,iBAAiB,CAAE;AAE3B,aAAS,QAAQ,IAAI;AAErB,WAAO;AAAA,EACR;AAAA,EAED,iBAAiB,OAAO;AACtB,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,UAAM,UAAU,OAAO,WAAW,IAAI;AAEtC,UAAM,QAAQ,MAAM;AACpB,UAAM,SAAS,MAAM;AAErB,WAAO,QAAQ;AACf,WAAO,SAAS;AAEhB,YAAQ,UAAU,GAAG,GAAG,OAAO,MAAM;AACrC,YAAQ,UAAU,QAAQ,GAAK,SAAS,CAAG;AAC3C,YAAQ,OAAO,MAAM,KAAK,EAAE;AAC5B,YAAQ,UAAU,CAAC,QAAQ,GAAK,CAAC,SAAS,CAAG;AAC7C,YAAQ,UAAU,OAAO,GAAG,CAAC;AAE7B,WAAO,QAAQ,aAAa,GAAG,GAAG,OAAO,MAAM;AAAA,EAChD;AAAA;AAAA,EAGD,wBAAwB,KAAK,UAAU,YAAY;AACjD,QAAI,eAAe,KAAK,SAAU,SAAS;AAEzC,eAAS,gBAAgB,OAAO;AAC9B,cAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,eAAO,QAAQ,MAAM;AACrB,eAAO,SAAS,MAAM;AAEtB,cAAM,UAAU,OAAO,WAAW,IAAI;AACtC,gBAAQ,UAAU,OAAO,GAAG,CAAC;AAE7B,eAAO,QAAQ,aAAa,GAAG,GAAG,OAAO,OAAO,OAAO,MAAM;AAAA,MAC9D;AAED,eAAS,wBAAwB,OAAO,KAAK,SAAS;AACpD,cAAM,QAAQ,MAAM;AACpB,cAAM,SAAS,MAAM;AACrB,cAAM,OAAO,MAAM;AACnB,cAAM,YAAY;AAElB,YAAI,KAAK,UAAU,QAAQ,YAAY;AAAG,iBAAO;AAEjD,iBAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,GAAG;AAC1C,gBAAM,WAAW,EAAE,GAAG,GAAK,GAAG,EAAK;AAEnC,mBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,kBAAM,QAAQ,QAAQ,IAAI,IAAI,CAAC;AAC/B,kBAAM,KAAK,EAAE,GAAG,IAAI,QAAQ,IAAI,CAAC,GAAG,GAAG,IAAI,QAAQ,IAAI,CAAC,EAAG;AAE3D,gBAAI,aAAa,OAAO,EAAE,IAAI;AAAW,qBAAO;AAEhD,qBAAS,KAAK,GAAG;AACjB,qBAAS,KAAK,GAAG;AAAA,UAClB;AAED,mBAAS,KAAK;AACd,mBAAS,KAAK;AAEd,cAAI,aAAa,OAAO,QAAQ,IAAI;AAAW,mBAAO;AAAA,QACvD;AAED,eAAO;AAAA,MACR;AASD,eAAS,aAAa,OAAO,IAAI;AAC/B,cAAM,QAAQ,MAAM;AACpB,cAAM,SAAS,MAAM;AAErB,YAAI,IAAI,KAAK,MAAM,GAAG,IAAI,KAAK,IAAI;AACnC,YAAI,IAAI,KAAK,MAAM,GAAG,IAAI,MAAM,IAAI;AAEpC,YAAI,IAAI;AAAG,eAAK;AAChB,YAAI,IAAI;AAAG,eAAK;AAEhB,cAAM,QAAQ,IAAI,QAAQ;AAE1B,eAAO,MAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,MAChC;AAED,YAAM,YAAY,QAAQ,MAAM,SAAS,SAAY,QAAQ,QAAQ,gBAAgB,QAAQ,KAAK;AAElG,YAAM,QAAQ,SAAS,OAAO,UAAU;AAExC,UACE;AAAA,QACE;AAAA,QACA,SAAS,WAAW,GAAG;AAAA,QACvB,SAAS,MAAM,MAAM,MAAM,MAAM,OAAO,MAAM,QAAQ,MAAM,KAAK;AAAA,MAClE,GACD;AACA,YAAI,cAAc;AAAA,MACnB;AAAA,IACP,CAAK;AAAA,EACF;AACH;AAIA,MAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMrB,MAAM,KAAK,MAAM;AAGf,UAAM,SAAS,KAAK,uBAAuB,KAAK,IAAI,EAAE;AACtD,UAAM,UAAU,KAAK,oBAAoB,KAAK,IAAI,EAAE;AAEpD,aAAS,IAAI,GAAG,KAAK,QAAQ,QAAQ,IAAI,IAAI,KAAK;AAChD,aAAO,KAAK,QAAQ,CAAC,CAAC;AAAA,IACvB;AAED,WAAO,IAAIC,MAAAA,cAAc,IAAI,IAAI,MAAM;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOD,uBAAuB,KAAK,MAAM;AAChC,aAAS,kBAAkB,OAAO,eAAe,OAAO;AACtD,YAAM,KAAK,cAAc,QAAQ,CAAC,IAAI,GAAG;AACzC,YAAM,KAAK,cAAc,QAAQ,CAAC,IAAI,GAAG;AACzC,YAAM,KAAK,cAAc,QAAQ,CAAC,IAAI,GAAG;AACzC,YAAM,KAAK,cAAc,QAAQ,EAAE,IAAI,GAAG;AAAA,IAC3C;AAED,UAAM,SAAS,CAAE;AAEjB,UAAM,UAAU,CAAE;AAClB,UAAM,QAAQ,KAAK,SAAS;AAC5B,UAAM,qBAAqB,CAAE;AAE7B,aAAS,IAAI,GAAG,KAAK,MAAM,QAAQ,IAAI,IAAI,KAAK;AAC9C,yBAAmB,MAAM,CAAC,EAAE,IAAI,IAAI;AAAA,IACrC;AAED,aAAS,IAAI,GAAG,IAAI,IAAI,SAAS,aAAa,KAAK;AACjD,YAAM,SAAS,IAAI,QAAQ,CAAC;AAC5B,YAAM,WAAW,OAAO;AAExB,UAAI,mBAAmB,QAAQ,MAAM;AAAW;AAEhD,cAAQ,QAAQ,IAAI,QAAQ,QAAQ,KAAK,CAAE;AAC3C,cAAQ,QAAQ,EAAE,KAAK,MAAM;AAAA,IAC9B;AAED,eAAW,OAAO,SAAS;AACzB,YAAM,QAAQ,QAAQ,GAAG;AAEzB,YAAM,KAAK,SAAU,GAAG,GAAG;AACzB,eAAO,EAAE,WAAW,EAAE;AAAA,MAC9B,CAAO;AAED,YAAM,QAAQ,CAAE;AAChB,YAAM,YAAY,CAAE;AACpB,YAAM,YAAY,CAAE;AACpB,YAAM,kBAAkB,CAAE;AAC1B,YAAM,kBAAkB,CAAE;AAE1B,YAAM,eAAe,KAAK,SAAS,cAAc,GAAG,EAAE,SAAS,QAAS;AAExE,eAAS,IAAI,GAAG,KAAK,MAAM,QAAQ,IAAI,IAAI,KAAK;AAC9C,cAAM,OAAO,MAAM,CAAC,EAAE,WAAW;AACjC,cAAM,WAAW,MAAM,CAAC,EAAE;AAC1B,cAAM,WAAW,MAAM,CAAC,EAAE;AAC1B,cAAM,gBAAgB,MAAM,CAAC,EAAE;AAE/B,cAAM,KAAK,IAAI;AAEf,iBAAS,IAAI,GAAG,IAAI,GAAG;AAAK,oBAAU,KAAK,aAAa,CAAC,IAAI,SAAS,CAAC,CAAC;AACxE,iBAAS,IAAI,GAAG,IAAI,GAAG;AAAK,oBAAU,KAAK,SAAS,CAAC,CAAC;AACtD,iBAAS,IAAI,GAAG,IAAI,GAAG;AAAK,4BAAkB,iBAAiB,eAAe,CAAC;AAE/E,0BAAkB,iBAAiB,eAAe,CAAC;AAAA,MACpD;AAED,YAAM,aAAa,YAAY,MAAM;AAErC,aAAO,KAAK,KAAK,aAAa,aAAa,aAAaC,MAAAA,qBAAqB,OAAO,WAAW,eAAe,CAAC;AAC/G,aAAO;AAAA,QACL,KAAK,aAAa,aAAa,eAAeC,MAAAA,yBAAyB,OAAO,WAAW,eAAe;AAAA,MACzG;AAAA,IACF;AAED,WAAO,IAAIF,MAAAA,cAAc,IAAI,IAAI,MAAM;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOD,oBAAoB,KAAK,MAAM;AAC7B,UAAM,SAAS,CAAE;AAEjB,UAAM,SAAS,CAAE;AACjB,UAAM,wBAAwB,KAAK;AAEnC,aAAS,IAAI,GAAG,IAAI,IAAI,SAAS,YAAY,KAAK;AAChD,YAAM,QAAQ,IAAI,OAAO,CAAC;AAC1B,YAAM,YAAY,MAAM;AAExB,UAAI,sBAAsB,SAAS,MAAM;AAAW;AAEpD,aAAO,SAAS,IAAI,OAAO,SAAS,KAAK,CAAE;AAC3C,aAAO,SAAS,EAAE,KAAK,KAAK;AAAA,IAC7B;AAED,eAAW,OAAO,QAAQ;AACxB,YAAM,QAAQ,OAAO,GAAG;AAExB,YAAM,KAAK,SAAU,GAAG,GAAG;AACzB,eAAO,EAAE,WAAW,EAAE;AAAA,MAC9B,CAAO;AAED,YAAM,QAAQ,CAAE;AAChB,YAAM,SAAS,CAAE;AAEjB,eAAS,IAAI,GAAG,KAAK,MAAM,QAAQ,IAAI,IAAI,KAAK;AAC9C,cAAM,KAAK,MAAM,CAAC,EAAE,WAAW,EAAE;AACjC,eAAO,KAAK,MAAM,CAAC,EAAE,MAAM;AAAA,MAC5B;AAED,aAAO,KAAK,IAAIG,MAAmB,oBAAC,4BAA4B,sBAAsB,GAAG,IAAI,KAAK,OAAO,MAAM,CAAC;AAAA,IACjH;AAED,WAAO,IAAIH,MAAAA,cAAc,IAAI,IAAI,MAAM;AAAA,EACxC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMD,qBAAqB,KAAK;AACxB,aAAS,YAAY,OAAO,KAAK;AAC/B,YAAM,KAAK,IAAI,CAAC;AAChB,YAAM,KAAK,IAAI,CAAC;AAChB,YAAM,KAAK,IAAI,CAAC;AAAA,IACjB;AAED,aAAS,eAAe,OAAO,GAAG;AAChC,YAAM,KAAK,EAAE,CAAC;AACd,YAAM,KAAK,EAAE,CAAC;AACd,YAAM,KAAK,EAAE,CAAC;AACd,YAAM,KAAK,EAAE,CAAC;AAAA,IACf;AAED,aAAS,kBAAkB,OAAO,eAAe,OAAO;AACtD,YAAM,KAAK,cAAc,QAAQ,IAAI,CAAC,IAAI,GAAG;AAC7C,YAAM,KAAK,cAAc,QAAQ,IAAI,CAAC,IAAI,GAAG;AAC7C,YAAM,KAAK,cAAc,QAAQ,IAAI,CAAC,IAAI,GAAG;AAC7C,YAAM,KAAK,cAAc,QAAQ,IAAI,CAAC,IAAI,GAAG;AAAA,IAC9C;AAED,UAAM,UAAU,IAAI,YAAY,SAAY,CAAA,IAAK,IAAI,QAAQ,MAAO;AAEpE,YAAQ,KAAK,SAAU,GAAG,GAAG;AAC3B,aAAO,EAAE,WAAW,EAAE;AAAA,IAC5B,CAAK;AAED,UAAM,QAAQ,CAAE;AAChB,UAAM,UAAU,CAAE;AAClB,UAAM,cAAc,CAAE;AACtB,UAAM,YAAY,CAAE;AACpB,UAAM,OAAO,CAAE;AAEf,UAAM,kBAAkB,CAAE;AAC1B,UAAM,kBAAkB,CAAE;AAC1B,UAAM,kBAAkB,CAAE;AAC1B,UAAM,kBAAkB,CAAE;AAE1B,UAAM,aAAa,IAAII,iBAAY;AACnC,UAAM,QAAQ,IAAIC,YAAO;AACzB,UAAM,WAAW,IAAIxB,cAAS;AAC9B,UAAM,SAAS,IAAIA,cAAS;AAE5B,aAAS,IAAI,GAAG,KAAK,QAAQ,QAAQ,IAAI,IAAI,KAAK;AAChD,YAAM,SAAS,QAAQ,CAAC;AAExB,YAAM,OAAO,OAAO,WAAW;AAC/B,YAAM,MAAM,OAAO;AACnB,YAAM,MAAM,OAAO;AACnB,YAAM,WAAW,OAAO;AACxB,YAAM,MAAM,OAAO;AACnB,YAAM,gBAAgB,OAAO;AAE7B,YAAM,KAAK,IAAI;AAEf,eAAS,IAAI,GAAG,GAAG,CAAC,QAAQ;AAC5B,aAAO,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;AAEjC,YAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACnC,iBAAW,aAAa,KAAK;AAE7B,eAAS,IAAI,MAAM;AACnB,eAAS,gBAAgB,UAAU;AAEnC,kBAAY,SAAS,MAAM;AAC3B,qBAAe,aAAa,UAAU;AACtC,kBAAY,WAAW,QAAQ;AAE/B,WAAK,KAAK,GAAG;AAEb,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,0BAAkB,iBAAiB,eAAe,CAAC;AAAA,MACpD;AAED,wBAAkB,iBAAiB,eAAe,CAAC;AAGnD,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,0BAAkB,iBAAiB,eAAe,CAAC;AAAA,MACpD;AAED,wBAAkB,iBAAiB,eAAe,CAAC;AAAA,IACpD;AAED,UAAM,SAAS,CAAE;AAGjB,WAAO,KAAK,KAAK,aAAa,mBAAmBoB,MAAAA,qBAAqB,OAAO,SAAS,eAAe,CAAC;AAEtG,WAAO,KAAK,KAAK,aAAa,eAAeC,MAAAA,yBAAyB,OAAO,aAAa,eAAe,CAAC;AAC1G,WAAO,KAAK,KAAK,aAAa,aAAaD,MAAAA,qBAAqB,OAAO,WAAW,eAAe,CAAC;AAClG,WAAO,KAAK,KAAK,aAAa,QAAQE,MAAAA,qBAAqB,OAAO,MAAM,eAAe,CAAC;AAExF,WAAO,IAAIH,MAAAA,cAAc,IAAI,IAAI,MAAM;AAAA,EACxC;AAAA;AAAA,EAID,aAAa,MAAM,oBAAoB,OAAO,QAAQ,gBAAgB;AAMpE,QAAI,MAAM,SAAS,GAAG;AACpB,cAAQ,MAAM,MAAO;AACrB,eAAS,OAAO,MAAO;AACvB,uBAAiB,eAAe,MAAO;AAEvC,YAAM,SAAS,OAAO,SAAS,MAAM;AACrC,YAAM,oBAAoB,eAAe,SAAS,MAAM;AAExD,UAAI,QAAQ;AAEZ,eAAS,aAAa,GAAG,WAAW,MAAM,QAAQ,aAAa,UAAU,cAAc;AACrF,iBAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,cACE,OAAO,QAAQ,SAAS,CAAC,MAAM,QAAQ,QAAQ,KAAK,SAAS,CAAC,KAC9D,OAAO,QAAQ,SAAS,CAAC,MAAM,OAAO,aAAa,SAAS,CAAC,GAC7D;AACA;AACA;AAAA,UACD;AAAA,QACF;AAED,YAAI,aAAa,OAAO;AACtB,gBAAM,KAAK,IAAI,MAAM,UAAU;AAE/B,mBAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC/B,mBAAO,QAAQ,SAAS,CAAC,IAAI,OAAO,aAAa,SAAS,CAAC;AAAA,UAC5D;AAED,mBAAS,IAAI,GAAG,IAAI,mBAAmB,KAAK;AAC1C,2BAAe,QAAQ,oBAAoB,CAAC,IAAI,eAAe,aAAa,oBAAoB,CAAC;AAAA,UAClG;AAAA,QACF;AAAA,MACF;AAED,YAAM,SAAS,QAAQ;AACvB,aAAO,UAAU,QAAQ,KAAK;AAC9B,qBAAe,UAAU,QAAQ,KAAK;AAAA,IACvC;AAED,UAAM,QAAQ,IAAI,mBAAmB,MAAM,OAAO,MAAM;AAExD,UAAM,oBAAoB,SAAS,oCAAoC,QAAQ;AAC7E,aAAO,IAAI;AAAA,QACT,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK,aAAc;AAAA,QACnB;AAAA,QACA,IAAI,aAAa,cAAc;AAAA,MAChC;AAAA,IACF;AAED,WAAO;AAAA,EACR;AACH;AAIA,MAAM,iCAAiCM,MAAAA,YAAY;AAAA,EACjD,YAAY,oBAAoB,cAAc,YAAY,cAAc,QAAQ;AAC9E,UAAM,oBAAoB,cAAc,YAAY,YAAY;AAEhE,SAAK,sBAAsB;AAAA,EAC5B;AAAA,EAED,aAAa,IAAI,IAAI,GAAG,IAAI;AAC1B,UAAM,SAAS,KAAK;AACpB,UAAM,SAAS,KAAK;AACpB,UAAM,SAAS,KAAK;AACpB,UAAM,SAAS,KAAK;AAEpB,UAAM,UAAU,KAAK;AACrB,UAAM,UAAU,UAAU;AAK1B,UAAM,UAAU,KAAK,KAAM,IAAI,KAAM,MAAM,KAAO,IAAI,OAAO,KAAK;AAElE,QAAI,WAAW,GAAG;AAGhB,YAAM,KAAK,OAAO,KAAK,IAAI,CAAC;AAC5B,YAAM,KAAK,OAAO,KAAK,IAAI,CAAC;AAC5B,YAAM,KAAK,OAAO,KAAK,IAAI,CAAC;AAC5B,YAAM,KAAK,OAAO,KAAK,IAAI,CAAC;AAE5B,YAAM,QAAQ,KAAK,WAAW,IAAI,IAAI,IAAI,IAAI,OAAO;AAErDF,uBAAW,UAAU,QAAQ,GAAG,QAAQ,SAAS,QAAQ,SAAS,KAAK;AAAA,IAC7E,WAAe,WAAW,GAAG;AAGvB,eAAS,IAAI,GAAG,MAAM,QAAQ,EAAE,GAAG;AACjC,cAAM,KAAK,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC;AACrC,cAAM,KAAK,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC;AACrC,cAAM,KAAK,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC;AACrC,cAAM,KAAK,OAAO,KAAK,KAAK,IAAI,IAAI,CAAC;AAErC,cAAM,QAAQ,KAAK,WAAW,IAAI,IAAI,IAAI,IAAI,OAAO;AAErD,eAAO,CAAC,IAAI,OAAO,UAAU,CAAC,KAAK,IAAI,SAAS,OAAO,UAAU,CAAC,IAAI;AAAA,MACvE;AAAA,IACP,OAAW;AAGL,YAAM,KAAK,OAAO,KAAK,IAAI,CAAC;AAC5B,YAAM,KAAK,OAAO,KAAK,IAAI,CAAC;AAC5B,YAAM,KAAK,OAAO,KAAK,IAAI,CAAC;AAC5B,YAAM,KAAK,OAAO,KAAK,IAAI,CAAC;AAE5B,YAAM,QAAQ,KAAK,WAAW,IAAI,IAAI,IAAI,IAAI,OAAO;AAErD,aAAO,CAAC,IAAI,OAAO,OAAO,KAAK,IAAI,SAAS,OAAO,OAAO,IAAI;AAAA,IAC/D;AAED,WAAO;AAAA,EACR;AAAA,EAED,WAAW,IAAI,IAAI,IAAI,IAAI,GAAG;AAsC5B,QAAI,IAAI;AACR,QAAI,IAAI;AACR,QAAI,IAAI,IAAM;AACd,UAAM,OAAO;AACb,UAAM,MAAM;AACZ,UAAM,OAAO;AAEb,QAAI,MAAM,MAAM;AAEhB,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAO,IAAM,IAAI,IAAI;AACrB,aAAO,IAAM,IAAI,IAAI;AACrB,YAAM,IAAI,IAAI;AAEd,YAAM,KAAK,OAAO,KAAK,OAAO,KAAK,MAAM;AAEzC,UAAI,KAAK,IAAI,EAAE,IAAI;AAAK;AAExB,WAAK;AAEL,WAAK,KAAK,IAAI,IAAI,CAAC;AACnB,UAAI,IAAM;AAAA,IACX;AAED,WAAO,OAAO,KAAK,OAAO,KAAK;AAAA,EAChC;AACH;;"}