@pixiv/three-vrm 2.1.2 → 3.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -11
- package/lib/nodes/index.cjs +510 -0
- package/lib/nodes/index.min.cjs +10 -0
- package/lib/nodes/index.module.js +478 -0
- package/lib/nodes/index.module.min.js +10 -0
- package/lib/three-vrm.cjs +6175 -0
- package/lib/three-vrm.min.cjs +959 -0
- package/lib/three-vrm.module.js +6043 -6794
- package/lib/three-vrm.module.min.js +923 -19
- package/package.json +29 -25
- package/types/VRMUtils/removeUnnecessaryJoints.d.ts +11 -1
- package/types/nodes/index.d.ts +1 -0
- package/lib/three-vrm.js +0 -6974
- package/lib/three-vrm.min.js +0 -54
- package/ts3.4/types/VRM.d.ts +0 -39
- package/ts3.4/types/VRMLoaderPlugin.d.ts +0 -31
- package/ts3.4/types/VRMLoaderPluginOptions.d.ts +0 -32
- package/ts3.4/types/VRMParameters.d.ts +0 -12
- package/ts3.4/types/VRMUtils/deepDispose.d.ts +0 -2
- package/ts3.4/types/VRMUtils/index.d.ts +0 -11
- package/ts3.4/types/VRMUtils/removeUnnecessaryJoints.d.ts +0 -9
- package/ts3.4/types/VRMUtils/removeUnnecessaryVertices.d.ts +0 -12
- package/ts3.4/types/VRMUtils/rotateVRM0.d.ts +0 -7
- package/ts3.4/types/index.d.ts +0 -9
- package/ts3.4/types/utils/Matrix4InverseCache.d.ts +0 -28
- package/ts3.4/types/utils/mat4InvertCompat.d.ts +0 -8
- package/ts3.4/types/utils/math.d.ts +0 -40
- package/ts3.4/types/utils/quatInvertCompat.d.ts +0 -8
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/*! (c) 2019-2024 pixiv Inc. - https://github.com/pixiv/three-vrm/blob/release/LICENSE */
|
|
2
|
+
"use strict";var z=Object.create;var M=Object.defineProperty;var B=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var q=Object.getPrototypeOf,K=Object.prototype.hasOwnProperty;var Z=(e,t)=>{for(var i in t)M(e,i,{get:t[i],enumerable:!0})},W=(e,t,i,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let l of j(t))!K.call(e,l)&&l!==i&&M(e,l,{get:()=>t[l],enumerable:!(a=B(t,l))||a.enumerable});return e};var h=(e,t,i)=>(i=e!=null?z(q(e)):{},W(t||!e||!e.__esModule?M(i,"default",{value:e,enumerable:!0}):i,e)),$=e=>W(M({},"__esModule",{value:!0}),e);var _e={};Z(_e,{MToonAnimatedUVNode:()=>D,MToonLightingModel:()=>k,MToonNodeMaterial:()=>Ce});module.exports=$(_e);var I=h(require("three"),1),n=h(require("three/addons/nodes/Nodes.js"),1),r=h(require("three/addons/nodes/Nodes.js"),1),s=h(require("three/addons/nodes/Nodes.js"),1),d=h(require("three/addons/nodes/Nodes.js"),1),m=h(require("three"),1),o=h(require("three/addons/nodes/Nodes.js"),1),c=h(require("three/addons/nodes/Nodes.js"),1);var O=parseInt(I.REVISION,10);O<161&&console.warn(`MToonNodeMaterial requires Three.js r161 or higher (You are using r${O}). This would not work correctly.`);var G=r.materialReference("color","color"),J=r.materialReference("map","texture"),Q=r.materialReference("normalMap","texture"),ee=r.materialReference("normalScale","vec2"),te=r.materialReference("emissive","color"),ie=r.materialReference("emissiveIntensity","float"),oe=r.materialReference("emissiveMap","texture"),re=r.materialReference("shadeColorFactor","color"),ae=r.materialReference("shadingShiftFactor","float"),U=r.materialReference("shadeMultiplyTexture","texture"),se=r.materialReference("shadeMultiplyTextureScale","float"),le=r.materialReference("shadingToonyFactor","float"),ne=r.materialReference("rimLightingMixFactor","float"),de=r.materialReference("rimMultiplyTexture","texture"),me=r.materialReference("matcapFactor","color"),ue=r.materialReference("matcapTexture","texture"),he=r.materialReference("parametricRimColorFactor","color"),ce=r.materialReference("parametricRimLiftFactor","float"),pe=r.materialReference("parametricRimFresnelPowerFactor","float"),Ne=r.materialReference("outlineWidthMultiplyTexture","texture"),fe=r.materialReference("outlineWidthFactor","float"),b=r.materialReference("outlineColorFactor","color"),ve=r.materialReference("outlineLightingMixFactor","float"),ge=r.materialReference("uvAnimationMaskTexture","texture"),Me=r.materialReference("uvAnimationScrollXOffset","float"),xe=r.materialReference("uvAnimationScrollYOffset","float"),Re=r.materialReference("uvAnimationRotationPhase","float"),D=class extends n.TempNode{constructor(e){super("vec2"),this.hasMaskTexture=e}setup(){let e=1;this.hasMaskTexture&&(e=n.vec4(ge).context({getUV:()=>n.uv()}).r);let t=n.uv(),i=Re.mul(e),a=n.cos(i),l=n.sin(i);t=t.sub(n.vec2(.5,.5)),t=t.mul(n.mat2(a,l,l.negate(),a)),t=t.add(n.vec2(.5,.5));let u=n.vec2(Me,xe).mul(e);return t=t.add(u),t.temp("AnimatedUV")}},H=d.nodeImmutable(d.PropertyNode,"vec3").temp("ShadeColor"),Y=d.nodeImmutable(d.PropertyNode,"float").temp("ShadingShift"),X=d.nodeImmutable(d.PropertyNode,"float").temp("ShadingToony"),x=d.nodeImmutable(d.PropertyNode,"float").temp("RimLightingMix"),R=d.nodeImmutable(d.PropertyNode,"vec3").temp("RimMultiply"),T=d.nodeImmutable(d.PropertyNode,"vec3").temp("matcap"),S=d.nodeImmutable(d.PropertyNode,"vec3").temp("ParametricRim"),Te=s.tslFn(({a:e,b:t,t:i})=>{let a=i.sub(e),l=t.sub(e);return a.div(l).clamp()}),Se=s.tslFn(({dotNL:e})=>{let i=s.float(1).sub(X),a=e.add(Y);return a=Te({a:i.negate(),b:i,t:a}),a=a.mul(1),a}),Fe=s.tslFn(({shading:e,lightColor:t})=>{let i=s.mix(H,s.diffuseColor,e);return t.mul(s.BRDF_Lambert({diffuseColor:i}))}),k=class extends s.LightingModel{constructor(){super()}direct({lightDirection:e,lightColor:t,reflectedLight:i}){let a=s.transformedNormalView.dot(e).clamp(-1,1),l=Se({dotNL:a});i.directDiffuse.assign(i.directDiffuse.add(Fe({shading:l,lightColor:t}))),i.directSpecular.assign(i.directSpecular.add(S.add(T).mul(R).mul(s.mix(s.vec3(0),s.BRDF_Lambert({diffuseColor:t}),x))))}indirectDiffuse({irradiance:e,reflectedLight:t}){t.indirectDiffuse.assign(t.indirectDiffuse.add(e.mul(s.BRDF_Lambert({diffuseColor:s.diffuseColor}))))}indirectSpecular({reflectedLight:e}){e.indirectSpecular.assign(e.indirectSpecular.add(S.add(T).mul(R).mul(s.mix(s.vec3(1),s.vec3(0),x))))}},v={None:"none",WorldCoordinates:"worldCoordinates",ScreenCoordinates:"screenCoordinates"},ye=c.tslFn(({parametricRimLift:e,parametricRimFresnelPower:t,parametricRimColor:i})=>{let a=c.modelViewPosition.normalize(),l=c.transformedNormalView.dot(a.negate());return c.float(1).sub(l).add(e).clamp().pow(t).mul(i)}),Ce=class extends o.NodeMaterial{customProgramCacheKey(){let e=super.customProgramCacheKey();return e+=`isOutline:${this.isOutline},`,e}get isMToonNodeMaterial(){return!0}constructor(e={}){super(),e.transparentWithZWrite&&(e.depthWrite=!0),delete e.transparentWithZWrite,delete e.giEqualizationFactor,delete e.v0CompatShade,delete e.debugMode,this.emissiveNode=null,this.lights=!0,this.color=new m.Color(1,1,1),this.map=null,this.emissive=new m.Color(0,0,0),this.emissiveIntensity=1,this.emissiveMap=null,this.normalMap=null,this.normalScale=new m.Vector2(1,1),this.shadeColorFactor=new m.Color(0,0,0),this.shadeMultiplyTexture=null,this.shadingShiftFactor=0,this.shadingShiftTexture=null,this.shadingShiftTextureScale=1,this.shadingToonyFactor=.9,this.rimLightingMixFactor=1,this.rimMultiplyTexture=null,this.matcapFactor=new m.Color(1,1,1),this.matcapTexture=null,this.parametricRimColorFactor=new m.Color(0,0,0),this.parametricRimLiftFactor=0,this.parametricRimFresnelPowerFactor=5,this.outlineWidthMode=v.None,this.outlineWidthMultiplyTexture=null,this.outlineWidthFactor=0,this.outlineColorFactor=new m.Color(0,0,0),this.outlineLightingMixFactor=1,this.uvAnimationScrollXSpeedFactor=0,this.uvAnimationScrollYSpeedFactor=0,this.uvAnimationRotationSpeedFactor=0,this.uvAnimationMaskTexture=null,this.shadeColorNode=null,this.shadingShiftNode=null,this.shadingToonyNode=null,this.rimLightingMixNode=null,this.rimMultiplyNode=null,this.matcapNode=null,this.parametricRimColorNode=null,this.parametricRimLiftNode=null,this.parametricRimFresnelPowerNode=null,this.uvAnimationScrollXOffset=0,this.uvAnimationScrollYOffset=0,this.uvAnimationRotationPhase=0,this.isOutline=!1,this._animatedUVNode=null,this.setValues(e)}setupLightingModel(){return new k}setup(e){var t;this._animatedUVNode=new D((t=this.uvAnimationMaskTexture&&this.uvAnimationMaskTexture.isTexture===!0)!=null?t:!1),super.setup(e)}setupDiffuseColor(e){let t=null;if(this.colorNode==null){if(t=G,this.map&&this.map.isTexture===!0){let i=J.context({getUV:()=>this._animatedUVNode});t=t.mul(i)}this.colorNode=t}this.vertexColors===!0&&e.geometry.hasAttribute("color")&&(console.warn("MToonNodeMaterial: MToon ignores vertex colors. Consider using a model without vertex colors instead."),this.vertexColors=!1),super.setupDiffuseColor(e),parseInt(m.REVISION,10)<166&&this.transparent===!1&&this.blending===m.NormalBlending&&this.alphaToCoverage===!1&&o.diffuseColor.a.assign(1),this.colorNode===t&&(this.colorNode=null)}setupVariants({stack:e}){e.assign(H,this._setupShadeColorNode()),e.assign(Y,this._setupShadingShiftNode()),e.assign(X,this._setupShadingToonyNode()),e.assign(x,this._setupRimLightingMixNode()),e.assign(R,this._setupRimMultiplyNode()),e.assign(T,this._setupMatcapNode()),e.assign(S,this._setupParametricRimNode())}setupNormal(e){let t=this.normalNode;if(this.normalNode==null){if(this.normalNode=o.materialNormal,this.normalMap&&this.normalMap.isTexture===!0){let i=Q.context({getUV:()=>this._animatedUVNode});this.normalNode=i.normalMap(ee)}this.isOutline&&(this.normalNode=this.normalNode.negate())}super.setupNormal(e),this.normalNode=t}setupLighting(e){let t=null;if(this.emissiveNode==null){if(t=te.mul(ie),this.emissiveMap&&this.emissiveMap.isTexture===!0){let a=oe.context({getUV:()=>this._animatedUVNode});t=t.mul(a)}this.emissiveNode=t}let i=super.setupLighting(e);return this.emissiveNode===t&&(this.emissiveNode=null),i}setupOutput(e,t){return this.isOutline&&this.outlineWidthMode!==v.None&&(t=o.vec4(o.mix(b,t.xyz.mul(b),ve),t.w)),super.setupOutput(e,t)}setupPosition(e){var t,i;let a=this.positionNode;if(this.isOutline&&this.outlineWidthMode!==v.None){(t=this.positionNode)!=null||(this.positionNode=o.positionLocal);let u=o.normalLocal.normalize(),p=fe;if(this.outlineWidthMultiplyTexture&&this.outlineWidthMultiplyTexture.isTexture===!0){let N=Ne.context({getUV:()=>this._animatedUVNode});p=p.mul(N)}let g=o.length(o.modelNormalMatrix.mul(u)),f=p.mul(g).mul(u);if(this.outlineWidthMode===v.WorldCoordinates)this.positionNode=this.positionNode.add(f);else if(this.outlineWidthMode===v.ScreenCoordinates){let N=o.cameraProjectionMatrix.element(1).element(1);this.positionNode=this.positionNode.add(f.div(N).mul(o.positionView.z.negate()))}(i=this.positionNode)!=null||(this.positionNode=o.positionLocal)}let l=super.setupPosition(e);return l.z.add(l.w.mul(1e-6)),this.positionNode=a,l}copy(e){var t,i,a,l,u,p,g,f,N,F,y,C,_,L,w,P,A,V,E;return this.color.copy(e.color),this.map=(t=e.map)!=null?t:null,this.emissive.copy(e.emissive),this.emissiveIntensity=e.emissiveIntensity,this.emissiveMap=(i=e.emissiveMap)!=null?i:null,this.normalMap=(a=e.normalMap)!=null?a:null,this.normalScale.copy(e.normalScale),this.shadeColorFactor.copy(e.shadeColorFactor),this.shadeMultiplyTexture=(l=e.shadeMultiplyTexture)!=null?l:null,this.shadingShiftFactor=e.shadingShiftFactor,this.shadingShiftTexture=(u=e.shadingShiftTexture)!=null?u:null,this.shadingShiftTextureScale=e.shadingShiftTextureScale,this.shadingToonyFactor=e.shadingToonyFactor,this.rimLightingMixFactor=e.rimLightingMixFactor,this.rimMultiplyTexture=(p=e.rimMultiplyTexture)!=null?p:null,this.matcapFactor.copy(e.matcapFactor),this.matcapTexture=(g=e.matcapTexture)!=null?g:null,this.parametricRimColorFactor.copy(e.parametricRimColorFactor),this.parametricRimLiftFactor=e.parametricRimLiftFactor,this.parametricRimFresnelPowerFactor=e.parametricRimFresnelPowerFactor,this.outlineWidthMode=e.outlineWidthMode,this.outlineWidthMultiplyTexture=(f=e.outlineWidthMultiplyTexture)!=null?f:null,this.outlineWidthFactor=e.outlineWidthFactor,this.outlineColorFactor.copy(e.outlineColorFactor),this.outlineLightingMixFactor=e.outlineLightingMixFactor,this.uvAnimationScrollXSpeedFactor=e.uvAnimationScrollXSpeedFactor,this.uvAnimationScrollYSpeedFactor=e.uvAnimationScrollYSpeedFactor,this.uvAnimationRotationSpeedFactor=e.uvAnimationRotationSpeedFactor,this.uvAnimationMaskTexture=(N=e.uvAnimationMaskTexture)!=null?N:null,this.shadeColorNode=(F=e.shadeColorNode)!=null?F:null,this.shadingShiftNode=(y=e.shadingShiftNode)!=null?y:null,this.shadingToonyNode=(C=e.shadingToonyNode)!=null?C:null,this.rimLightingMixNode=(_=e.rimLightingMixNode)!=null?_:null,this.rimMultiplyNode=(L=e.rimMultiplyNode)!=null?L:null,this.matcapNode=(w=e.matcapNode)!=null?w:null,this.parametricRimColorNode=(P=e.parametricRimColorNode)!=null?P:null,this.parametricRimLiftNode=(A=e.parametricRimLiftNode)!=null?A:null,this.parametricRimFresnelPowerNode=(V=e.parametricRimFresnelPowerNode)!=null?V:null,this.isOutline=(E=e.isOutline)!=null?E:null,super.copy(e)}update(e){this.uvAnimationScrollXOffset+=e*this.uvAnimationScrollXSpeedFactor,this.uvAnimationScrollYOffset+=e*this.uvAnimationScrollYSpeedFactor,this.uvAnimationRotationPhase+=e*this.uvAnimationRotationSpeedFactor}_setupShadeColorNode(){if(this.shadeColorNode!=null)return o.vec3(this.shadeColorNode);let e=re;if(this.shadeMultiplyTexture&&this.shadeMultiplyTexture.isTexture===!0){let t=U.context({getUV:()=>this._animatedUVNode});e=e.mul(t)}return e}_setupShadingShiftNode(){if(this.shadingShiftNode!=null)return o.float(this.shadingShiftNode);let e=ae;if(this.shadingShiftTexture&&this.shadingShiftTexture.isTexture===!0){let t=U.context({getUV:()=>this._animatedUVNode});e=e.add(t.mul(se))}return e}_setupShadingToonyNode(){return this.shadingToonyNode!=null?o.float(this.shadingToonyNode):le}_setupRimLightingMixNode(){return this.rimLightingMixNode!=null?o.float(this.rimLightingMixNode):ne}_setupRimMultiplyNode(){return this.rimMultiplyNode!=null?o.vec3(this.rimMultiplyNode):this.rimMultiplyTexture&&this.rimMultiplyTexture.isTexture===!0?de.context({getUV:()=>this._animatedUVNode}):o.vec3(1)}_setupMatcapNode(){return this.matcapNode!=null?o.vec3(this.matcapNode):this.matcapTexture&&this.matcapTexture.isTexture===!0?ue.context({getUV:()=>o.matcapUV.mul(1,-1).add(0,1)}).mul(me):o.vec3(0)}_setupParametricRimNode(){let e=this.parametricRimColorNode!=null?o.vec3(this.parametricRimColorNode):he,t=this.parametricRimLiftNode!=null?o.float(this.parametricRimLiftNode):ce,i=this.parametricRimFresnelPowerNode!=null?o.float(this.parametricRimFresnelPowerNode):pe;return ye({parametricRimLift:t,parametricRimFresnelPower:i,parametricRimColor:e})}};
|
|
3
|
+
/*!
|
|
4
|
+
* @pixiv/three-vrm-materials-mtoon v3.0.0-beta.1
|
|
5
|
+
* MToon (toon material) module for @pixiv/three-vrm
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2019-2024 pixiv Inc.
|
|
8
|
+
* @pixiv/three-vrm-materials-mtoon is distributed under MIT License
|
|
9
|
+
* https://github.com/pixiv/three-vrm/blob/release/LICENSE
|
|
10
|
+
*/
|
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* @pixiv/three-vrm v3.0.0-beta.1
|
|
3
|
+
* VRM file loader for three.js.
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) 2019-2024 pixiv Inc.
|
|
6
|
+
* @pixiv/three-vrm is distributed under MIT License
|
|
7
|
+
* https://github.com/pixiv/three-vrm/blob/release/LICENSE
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ../three-vrm-materials-mtoon/lib/nodes/index.module.js
|
|
11
|
+
import * as THREE from "three";
|
|
12
|
+
import * as Nodes2 from "three/addons/nodes/Nodes.js";
|
|
13
|
+
import * as Nodes from "three/addons/nodes/Nodes.js";
|
|
14
|
+
import * as Nodes4 from "three/addons/nodes/Nodes.js";
|
|
15
|
+
import * as Nodes3 from "three/addons/nodes/Nodes.js";
|
|
16
|
+
import * as THREE2 from "three";
|
|
17
|
+
import * as Nodes6 from "three/addons/nodes/Nodes.js";
|
|
18
|
+
import * as Nodes5 from "three/addons/nodes/Nodes.js";
|
|
19
|
+
var threeRevision = parseInt(THREE.REVISION, 10);
|
|
20
|
+
if (threeRevision < 161) {
|
|
21
|
+
console.warn(
|
|
22
|
+
`MToonNodeMaterial requires Three.js r161 or higher (You are using r${threeRevision}). This would not work correctly.`
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
var refColor = Nodes.materialReference("color", "color");
|
|
26
|
+
var refMap = Nodes.materialReference("map", "texture");
|
|
27
|
+
var refNormalMap = Nodes.materialReference("normalMap", "texture");
|
|
28
|
+
var refNormalScale = Nodes.materialReference("normalScale", "vec2");
|
|
29
|
+
var refEmissive = Nodes.materialReference("emissive", "color");
|
|
30
|
+
var refEmissiveIntensity = Nodes.materialReference("emissiveIntensity", "float");
|
|
31
|
+
var refEmissiveMap = Nodes.materialReference("emissiveMap", "texture");
|
|
32
|
+
var refShadeColorFactor = Nodes.materialReference("shadeColorFactor", "color");
|
|
33
|
+
var refShadingShiftFactor = Nodes.materialReference("shadingShiftFactor", "float");
|
|
34
|
+
var refShadeMultiplyTexture = Nodes.materialReference("shadeMultiplyTexture", "texture");
|
|
35
|
+
var refShadeMultiplyTextureScale = Nodes.materialReference("shadeMultiplyTextureScale", "float");
|
|
36
|
+
var refShadingToonyFactor = Nodes.materialReference("shadingToonyFactor", "float");
|
|
37
|
+
var refRimLightingMixFactor = Nodes.materialReference("rimLightingMixFactor", "float");
|
|
38
|
+
var refRimMultiplyTexture = Nodes.materialReference("rimMultiplyTexture", "texture");
|
|
39
|
+
var refMatcapFactor = Nodes.materialReference("matcapFactor", "color");
|
|
40
|
+
var refMatcapTexture = Nodes.materialReference("matcapTexture", "texture");
|
|
41
|
+
var refParametricRimColorFactor = Nodes.materialReference("parametricRimColorFactor", "color");
|
|
42
|
+
var refParametricRimLiftFactor = Nodes.materialReference("parametricRimLiftFactor", "float");
|
|
43
|
+
var refParametricRimFresnelPowerFactor = Nodes.materialReference("parametricRimFresnelPowerFactor", "float");
|
|
44
|
+
var refOutlineWidthMultiplyTexture = Nodes.materialReference("outlineWidthMultiplyTexture", "texture");
|
|
45
|
+
var refOutlineWidthFactor = Nodes.materialReference("outlineWidthFactor", "float");
|
|
46
|
+
var refOutlineColorFactor = Nodes.materialReference("outlineColorFactor", "color");
|
|
47
|
+
var refOutlineLightingMixFactor = Nodes.materialReference("outlineLightingMixFactor", "float");
|
|
48
|
+
var refUVAnimationMaskTexture = Nodes.materialReference("uvAnimationMaskTexture", "texture");
|
|
49
|
+
var refUVAnimationScrollXOffset = Nodes.materialReference("uvAnimationScrollXOffset", "float");
|
|
50
|
+
var refUVAnimationScrollYOffset = Nodes.materialReference("uvAnimationScrollYOffset", "float");
|
|
51
|
+
var refUVAnimationRotationPhase = Nodes.materialReference("uvAnimationRotationPhase", "float");
|
|
52
|
+
var MToonAnimatedUVNode = class extends Nodes2.TempNode {
|
|
53
|
+
constructor(hasMaskTexture) {
|
|
54
|
+
super("vec2");
|
|
55
|
+
this.hasMaskTexture = hasMaskTexture;
|
|
56
|
+
}
|
|
57
|
+
setup() {
|
|
58
|
+
let uvAnimationMask = 1;
|
|
59
|
+
if (this.hasMaskTexture) {
|
|
60
|
+
uvAnimationMask = Nodes2.vec4(refUVAnimationMaskTexture).context({ getUV: () => Nodes2.uv() }).r;
|
|
61
|
+
}
|
|
62
|
+
let uv2 = Nodes2.uv();
|
|
63
|
+
const phase = refUVAnimationRotationPhase.mul(uvAnimationMask);
|
|
64
|
+
const c = Nodes2.cos(phase);
|
|
65
|
+
const s = Nodes2.sin(phase);
|
|
66
|
+
uv2 = uv2.sub(Nodes2.vec2(0.5, 0.5));
|
|
67
|
+
uv2 = uv2.mul(Nodes2.mat2(c, s, s.negate(), c));
|
|
68
|
+
uv2 = uv2.add(Nodes2.vec2(0.5, 0.5));
|
|
69
|
+
const scroll = Nodes2.vec2(refUVAnimationScrollXOffset, refUVAnimationScrollYOffset).mul(uvAnimationMask);
|
|
70
|
+
uv2 = uv2.add(scroll);
|
|
71
|
+
return uv2.temp("AnimatedUV");
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
var shadeColor = Nodes3.nodeImmutable(Nodes3.PropertyNode, "vec3").temp("ShadeColor");
|
|
75
|
+
var shadingShift = Nodes3.nodeImmutable(Nodes3.PropertyNode, "float").temp("ShadingShift");
|
|
76
|
+
var shadingToony = Nodes3.nodeImmutable(Nodes3.PropertyNode, "float").temp("ShadingToony");
|
|
77
|
+
var rimLightingMix = Nodes3.nodeImmutable(Nodes3.PropertyNode, "float").temp("RimLightingMix");
|
|
78
|
+
var rimMultiply = Nodes3.nodeImmutable(Nodes3.PropertyNode, "vec3").temp("RimMultiply");
|
|
79
|
+
var matcap = Nodes3.nodeImmutable(Nodes3.PropertyNode, "vec3").temp("matcap");
|
|
80
|
+
var parametricRim = Nodes3.nodeImmutable(Nodes3.PropertyNode, "vec3").temp("ParametricRim");
|
|
81
|
+
var linearstep = Nodes4.tslFn(
|
|
82
|
+
({
|
|
83
|
+
a,
|
|
84
|
+
b,
|
|
85
|
+
t
|
|
86
|
+
}) => {
|
|
87
|
+
const top = t.sub(a);
|
|
88
|
+
const bottom = b.sub(a);
|
|
89
|
+
return top.div(bottom).clamp();
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
var getShading = Nodes4.tslFn(({ dotNL }) => {
|
|
93
|
+
const shadow = 1;
|
|
94
|
+
const feather = Nodes4.float(1).sub(shadingToony);
|
|
95
|
+
let shading = dotNL.add(shadingShift);
|
|
96
|
+
shading = linearstep({
|
|
97
|
+
a: feather.negate(),
|
|
98
|
+
b: feather,
|
|
99
|
+
t: shading
|
|
100
|
+
});
|
|
101
|
+
shading = shading.mul(shadow);
|
|
102
|
+
return shading;
|
|
103
|
+
});
|
|
104
|
+
var getDiffuse = Nodes4.tslFn(
|
|
105
|
+
({
|
|
106
|
+
shading,
|
|
107
|
+
lightColor
|
|
108
|
+
}) => {
|
|
109
|
+
const diffuseColor3 = Nodes4.mix(shadeColor, Nodes4.diffuseColor, shading);
|
|
110
|
+
const col = lightColor.mul(Nodes4.BRDF_Lambert({ diffuseColor: diffuseColor3 }));
|
|
111
|
+
return col;
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
var MToonLightingModel = class extends Nodes4.LightingModel {
|
|
115
|
+
constructor() {
|
|
116
|
+
super();
|
|
117
|
+
}
|
|
118
|
+
direct({ lightDirection, lightColor, reflectedLight }) {
|
|
119
|
+
const dotNL = Nodes4.transformedNormalView.dot(lightDirection).clamp(-1, 1);
|
|
120
|
+
const shading = getShading({
|
|
121
|
+
dotNL
|
|
122
|
+
});
|
|
123
|
+
reflectedLight.directDiffuse.assign(
|
|
124
|
+
reflectedLight.directDiffuse.add(
|
|
125
|
+
getDiffuse({
|
|
126
|
+
shading,
|
|
127
|
+
lightColor
|
|
128
|
+
})
|
|
129
|
+
)
|
|
130
|
+
);
|
|
131
|
+
reflectedLight.directSpecular.assign(
|
|
132
|
+
reflectedLight.directSpecular.add(
|
|
133
|
+
parametricRim.add(matcap).mul(rimMultiply).mul(Nodes4.mix(Nodes4.vec3(0), Nodes4.BRDF_Lambert({ diffuseColor: lightColor }), rimLightingMix))
|
|
134
|
+
)
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
indirectDiffuse({ irradiance, reflectedLight }) {
|
|
138
|
+
reflectedLight.indirectDiffuse.assign(
|
|
139
|
+
reflectedLight.indirectDiffuse.add(
|
|
140
|
+
irradiance.mul(
|
|
141
|
+
Nodes4.BRDF_Lambert({
|
|
142
|
+
diffuseColor: Nodes4.diffuseColor
|
|
143
|
+
})
|
|
144
|
+
)
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
indirectSpecular({ reflectedLight }) {
|
|
149
|
+
reflectedLight.indirectSpecular.assign(
|
|
150
|
+
reflectedLight.indirectSpecular.add(
|
|
151
|
+
parametricRim.add(matcap).mul(rimMultiply).mul(Nodes4.mix(Nodes4.vec3(1), Nodes4.vec3(0), rimLightingMix))
|
|
152
|
+
)
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
var MToonMaterialOutlineWidthMode = {
|
|
157
|
+
None: "none",
|
|
158
|
+
WorldCoordinates: "worldCoordinates",
|
|
159
|
+
ScreenCoordinates: "screenCoordinates"
|
|
160
|
+
};
|
|
161
|
+
var mtoonParametricRim = Nodes5.tslFn(
|
|
162
|
+
({
|
|
163
|
+
parametricRimLift,
|
|
164
|
+
parametricRimFresnelPower,
|
|
165
|
+
parametricRimColor
|
|
166
|
+
}) => {
|
|
167
|
+
const viewDir = Nodes5.modelViewPosition.normalize();
|
|
168
|
+
const dotNV = Nodes5.transformedNormalView.dot(viewDir.negate());
|
|
169
|
+
const rim = Nodes5.float(1).sub(dotNV).add(parametricRimLift).clamp().pow(parametricRimFresnelPower);
|
|
170
|
+
return rim.mul(parametricRimColor);
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
var MToonNodeMaterial = class extends Nodes6.NodeMaterial {
|
|
174
|
+
customProgramCacheKey() {
|
|
175
|
+
let cacheKey = super.customProgramCacheKey();
|
|
176
|
+
cacheKey += `isOutline:${this.isOutline},`;
|
|
177
|
+
return cacheKey;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Readonly boolean that indicates this is a {@link MToonNodeMaterial}.
|
|
181
|
+
*/
|
|
182
|
+
get isMToonNodeMaterial() {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
constructor(parameters = {}) {
|
|
186
|
+
super();
|
|
187
|
+
if (parameters.transparentWithZWrite) {
|
|
188
|
+
parameters.depthWrite = true;
|
|
189
|
+
}
|
|
190
|
+
delete parameters.transparentWithZWrite;
|
|
191
|
+
delete parameters.giEqualizationFactor;
|
|
192
|
+
delete parameters.v0CompatShade;
|
|
193
|
+
delete parameters.debugMode;
|
|
194
|
+
this.emissiveNode = null;
|
|
195
|
+
this.lights = true;
|
|
196
|
+
this.color = new THREE2.Color(1, 1, 1);
|
|
197
|
+
this.map = null;
|
|
198
|
+
this.emissive = new THREE2.Color(0, 0, 0);
|
|
199
|
+
this.emissiveIntensity = 1;
|
|
200
|
+
this.emissiveMap = null;
|
|
201
|
+
this.normalMap = null;
|
|
202
|
+
this.normalScale = new THREE2.Vector2(1, 1);
|
|
203
|
+
this.shadeColorFactor = new THREE2.Color(0, 0, 0);
|
|
204
|
+
this.shadeMultiplyTexture = null;
|
|
205
|
+
this.shadingShiftFactor = 0;
|
|
206
|
+
this.shadingShiftTexture = null;
|
|
207
|
+
this.shadingShiftTextureScale = 1;
|
|
208
|
+
this.shadingToonyFactor = 0.9;
|
|
209
|
+
this.rimLightingMixFactor = 1;
|
|
210
|
+
this.rimMultiplyTexture = null;
|
|
211
|
+
this.matcapFactor = new THREE2.Color(1, 1, 1);
|
|
212
|
+
this.matcapTexture = null;
|
|
213
|
+
this.parametricRimColorFactor = new THREE2.Color(0, 0, 0);
|
|
214
|
+
this.parametricRimLiftFactor = 0;
|
|
215
|
+
this.parametricRimFresnelPowerFactor = 5;
|
|
216
|
+
this.outlineWidthMode = MToonMaterialOutlineWidthMode.None;
|
|
217
|
+
this.outlineWidthMultiplyTexture = null;
|
|
218
|
+
this.outlineWidthFactor = 0;
|
|
219
|
+
this.outlineColorFactor = new THREE2.Color(0, 0, 0);
|
|
220
|
+
this.outlineLightingMixFactor = 1;
|
|
221
|
+
this.uvAnimationScrollXSpeedFactor = 0;
|
|
222
|
+
this.uvAnimationScrollYSpeedFactor = 0;
|
|
223
|
+
this.uvAnimationRotationSpeedFactor = 0;
|
|
224
|
+
this.uvAnimationMaskTexture = null;
|
|
225
|
+
this.shadeColorNode = null;
|
|
226
|
+
this.shadingShiftNode = null;
|
|
227
|
+
this.shadingToonyNode = null;
|
|
228
|
+
this.rimLightingMixNode = null;
|
|
229
|
+
this.rimMultiplyNode = null;
|
|
230
|
+
this.matcapNode = null;
|
|
231
|
+
this.parametricRimColorNode = null;
|
|
232
|
+
this.parametricRimLiftNode = null;
|
|
233
|
+
this.parametricRimFresnelPowerNode = null;
|
|
234
|
+
this.uvAnimationScrollXOffset = 0;
|
|
235
|
+
this.uvAnimationScrollYOffset = 0;
|
|
236
|
+
this.uvAnimationRotationPhase = 0;
|
|
237
|
+
this.isOutline = false;
|
|
238
|
+
this._animatedUVNode = null;
|
|
239
|
+
this.setValues(parameters);
|
|
240
|
+
}
|
|
241
|
+
setupLightingModel() {
|
|
242
|
+
return new MToonLightingModel();
|
|
243
|
+
}
|
|
244
|
+
setup(builder) {
|
|
245
|
+
var _a;
|
|
246
|
+
this._animatedUVNode = new MToonAnimatedUVNode(
|
|
247
|
+
(_a = this.uvAnimationMaskTexture && this.uvAnimationMaskTexture.isTexture === true) != null ? _a : false
|
|
248
|
+
);
|
|
249
|
+
super.setup(builder);
|
|
250
|
+
}
|
|
251
|
+
setupDiffuseColor(builder) {
|
|
252
|
+
let tempColorNode = null;
|
|
253
|
+
if (this.colorNode == null) {
|
|
254
|
+
tempColorNode = refColor;
|
|
255
|
+
if (this.map && this.map.isTexture === true) {
|
|
256
|
+
const map = refMap.context({ getUV: () => this._animatedUVNode });
|
|
257
|
+
tempColorNode = tempColorNode.mul(map);
|
|
258
|
+
}
|
|
259
|
+
this.colorNode = tempColorNode;
|
|
260
|
+
}
|
|
261
|
+
if (this.vertexColors === true && builder.geometry.hasAttribute("color")) {
|
|
262
|
+
console.warn(
|
|
263
|
+
"MToonNodeMaterial: MToon ignores vertex colors. Consider using a model without vertex colors instead."
|
|
264
|
+
);
|
|
265
|
+
this.vertexColors = false;
|
|
266
|
+
}
|
|
267
|
+
super.setupDiffuseColor(builder);
|
|
268
|
+
if (parseInt(THREE2.REVISION, 10) < 166) {
|
|
269
|
+
if (this.transparent === false && this.blending === THREE2.NormalBlending && this.alphaToCoverage === false) {
|
|
270
|
+
Nodes6.diffuseColor.a.assign(1);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (this.colorNode === tempColorNode) {
|
|
274
|
+
this.colorNode = null;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
setupVariants({ stack }) {
|
|
278
|
+
stack.assign(shadeColor, this._setupShadeColorNode());
|
|
279
|
+
stack.assign(shadingShift, this._setupShadingShiftNode());
|
|
280
|
+
stack.assign(shadingToony, this._setupShadingToonyNode());
|
|
281
|
+
stack.assign(rimLightingMix, this._setupRimLightingMixNode());
|
|
282
|
+
stack.assign(rimMultiply, this._setupRimMultiplyNode());
|
|
283
|
+
stack.assign(matcap, this._setupMatcapNode());
|
|
284
|
+
stack.assign(parametricRim, this._setupParametricRimNode());
|
|
285
|
+
}
|
|
286
|
+
setupNormal(builder) {
|
|
287
|
+
const tempNormalNode = this.normalNode;
|
|
288
|
+
if (this.normalNode == null) {
|
|
289
|
+
this.normalNode = Nodes6.materialNormal;
|
|
290
|
+
if (this.normalMap && this.normalMap.isTexture === true) {
|
|
291
|
+
const map = refNormalMap.context({ getUV: () => this._animatedUVNode });
|
|
292
|
+
this.normalNode = map.normalMap(refNormalScale);
|
|
293
|
+
}
|
|
294
|
+
if (this.isOutline) {
|
|
295
|
+
this.normalNode = this.normalNode.negate();
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
super.setupNormal(builder);
|
|
299
|
+
this.normalNode = tempNormalNode;
|
|
300
|
+
}
|
|
301
|
+
setupLighting(builder) {
|
|
302
|
+
let tempEmissiveNode = null;
|
|
303
|
+
if (this.emissiveNode == null) {
|
|
304
|
+
tempEmissiveNode = refEmissive.mul(refEmissiveIntensity);
|
|
305
|
+
if (this.emissiveMap && this.emissiveMap.isTexture === true) {
|
|
306
|
+
const map = refEmissiveMap.context({ getUV: () => this._animatedUVNode });
|
|
307
|
+
tempEmissiveNode = tempEmissiveNode.mul(map);
|
|
308
|
+
}
|
|
309
|
+
this.emissiveNode = tempEmissiveNode;
|
|
310
|
+
}
|
|
311
|
+
const ret = super.setupLighting(builder);
|
|
312
|
+
if (this.emissiveNode === tempEmissiveNode) {
|
|
313
|
+
this.emissiveNode = null;
|
|
314
|
+
}
|
|
315
|
+
return ret;
|
|
316
|
+
}
|
|
317
|
+
setupOutput(builder, outputNode) {
|
|
318
|
+
if (this.isOutline && this.outlineWidthMode !== MToonMaterialOutlineWidthMode.None) {
|
|
319
|
+
outputNode = Nodes6.vec4(
|
|
320
|
+
Nodes6.mix(refOutlineColorFactor, outputNode.xyz.mul(refOutlineColorFactor), refOutlineLightingMixFactor),
|
|
321
|
+
outputNode.w
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
return super.setupOutput(builder, outputNode);
|
|
325
|
+
}
|
|
326
|
+
setupPosition(builder) {
|
|
327
|
+
var _a, _b;
|
|
328
|
+
const tempPositionNode = this.positionNode;
|
|
329
|
+
if (this.isOutline && this.outlineWidthMode !== MToonMaterialOutlineWidthMode.None) {
|
|
330
|
+
(_a = this.positionNode) != null ? _a : this.positionNode = Nodes6.positionLocal;
|
|
331
|
+
const normalLocal2 = Nodes6.normalLocal.normalize();
|
|
332
|
+
let width = refOutlineWidthFactor;
|
|
333
|
+
if (this.outlineWidthMultiplyTexture && this.outlineWidthMultiplyTexture.isTexture === true) {
|
|
334
|
+
const map = refOutlineWidthMultiplyTexture.context({ getUV: () => this._animatedUVNode });
|
|
335
|
+
width = width.mul(map);
|
|
336
|
+
}
|
|
337
|
+
const worldNormalLength = Nodes6.length(Nodes6.modelNormalMatrix.mul(normalLocal2));
|
|
338
|
+
const outlineOffset = width.mul(worldNormalLength).mul(normalLocal2);
|
|
339
|
+
if (this.outlineWidthMode === MToonMaterialOutlineWidthMode.WorldCoordinates) {
|
|
340
|
+
this.positionNode = this.positionNode.add(outlineOffset);
|
|
341
|
+
} else if (this.outlineWidthMode === MToonMaterialOutlineWidthMode.ScreenCoordinates) {
|
|
342
|
+
const clipScale = Nodes6.cameraProjectionMatrix.element(1).element(1);
|
|
343
|
+
this.positionNode = this.positionNode.add(outlineOffset.div(clipScale).mul(Nodes6.positionView.z.negate()));
|
|
344
|
+
}
|
|
345
|
+
(_b = this.positionNode) != null ? _b : this.positionNode = Nodes6.positionLocal;
|
|
346
|
+
}
|
|
347
|
+
const ret = super.setupPosition(builder);
|
|
348
|
+
ret.z.add(ret.w.mul(1e-6));
|
|
349
|
+
this.positionNode = tempPositionNode;
|
|
350
|
+
return ret;
|
|
351
|
+
}
|
|
352
|
+
copy(source) {
|
|
353
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
|
|
354
|
+
this.color.copy(source.color);
|
|
355
|
+
this.map = (_a = source.map) != null ? _a : null;
|
|
356
|
+
this.emissive.copy(source.emissive);
|
|
357
|
+
this.emissiveIntensity = source.emissiveIntensity;
|
|
358
|
+
this.emissiveMap = (_b = source.emissiveMap) != null ? _b : null;
|
|
359
|
+
this.normalMap = (_c = source.normalMap) != null ? _c : null;
|
|
360
|
+
this.normalScale.copy(source.normalScale);
|
|
361
|
+
this.shadeColorFactor.copy(source.shadeColorFactor);
|
|
362
|
+
this.shadeMultiplyTexture = (_d = source.shadeMultiplyTexture) != null ? _d : null;
|
|
363
|
+
this.shadingShiftFactor = source.shadingShiftFactor;
|
|
364
|
+
this.shadingShiftTexture = (_e = source.shadingShiftTexture) != null ? _e : null;
|
|
365
|
+
this.shadingShiftTextureScale = source.shadingShiftTextureScale;
|
|
366
|
+
this.shadingToonyFactor = source.shadingToonyFactor;
|
|
367
|
+
this.rimLightingMixFactor = source.rimLightingMixFactor;
|
|
368
|
+
this.rimMultiplyTexture = (_f = source.rimMultiplyTexture) != null ? _f : null;
|
|
369
|
+
this.matcapFactor.copy(source.matcapFactor);
|
|
370
|
+
this.matcapTexture = (_g = source.matcapTexture) != null ? _g : null;
|
|
371
|
+
this.parametricRimColorFactor.copy(source.parametricRimColorFactor);
|
|
372
|
+
this.parametricRimLiftFactor = source.parametricRimLiftFactor;
|
|
373
|
+
this.parametricRimFresnelPowerFactor = source.parametricRimFresnelPowerFactor;
|
|
374
|
+
this.outlineWidthMode = source.outlineWidthMode;
|
|
375
|
+
this.outlineWidthMultiplyTexture = (_h = source.outlineWidthMultiplyTexture) != null ? _h : null;
|
|
376
|
+
this.outlineWidthFactor = source.outlineWidthFactor;
|
|
377
|
+
this.outlineColorFactor.copy(source.outlineColorFactor);
|
|
378
|
+
this.outlineLightingMixFactor = source.outlineLightingMixFactor;
|
|
379
|
+
this.uvAnimationScrollXSpeedFactor = source.uvAnimationScrollXSpeedFactor;
|
|
380
|
+
this.uvAnimationScrollYSpeedFactor = source.uvAnimationScrollYSpeedFactor;
|
|
381
|
+
this.uvAnimationRotationSpeedFactor = source.uvAnimationRotationSpeedFactor;
|
|
382
|
+
this.uvAnimationMaskTexture = (_i = source.uvAnimationMaskTexture) != null ? _i : null;
|
|
383
|
+
this.shadeColorNode = (_j = source.shadeColorNode) != null ? _j : null;
|
|
384
|
+
this.shadingShiftNode = (_k = source.shadingShiftNode) != null ? _k : null;
|
|
385
|
+
this.shadingToonyNode = (_l = source.shadingToonyNode) != null ? _l : null;
|
|
386
|
+
this.rimLightingMixNode = (_m = source.rimLightingMixNode) != null ? _m : null;
|
|
387
|
+
this.rimMultiplyNode = (_n = source.rimMultiplyNode) != null ? _n : null;
|
|
388
|
+
this.matcapNode = (_o = source.matcapNode) != null ? _o : null;
|
|
389
|
+
this.parametricRimColorNode = (_p = source.parametricRimColorNode) != null ? _p : null;
|
|
390
|
+
this.parametricRimLiftNode = (_q = source.parametricRimLiftNode) != null ? _q : null;
|
|
391
|
+
this.parametricRimFresnelPowerNode = (_r = source.parametricRimFresnelPowerNode) != null ? _r : null;
|
|
392
|
+
this.isOutline = (_s = source.isOutline) != null ? _s : null;
|
|
393
|
+
return super.copy(source);
|
|
394
|
+
}
|
|
395
|
+
update(delta) {
|
|
396
|
+
this.uvAnimationScrollXOffset += delta * this.uvAnimationScrollXSpeedFactor;
|
|
397
|
+
this.uvAnimationScrollYOffset += delta * this.uvAnimationScrollYSpeedFactor;
|
|
398
|
+
this.uvAnimationRotationPhase += delta * this.uvAnimationRotationSpeedFactor;
|
|
399
|
+
}
|
|
400
|
+
_setupShadeColorNode() {
|
|
401
|
+
if (this.shadeColorNode != null) {
|
|
402
|
+
return Nodes6.vec3(this.shadeColorNode);
|
|
403
|
+
}
|
|
404
|
+
let shadeColorNode = refShadeColorFactor;
|
|
405
|
+
if (this.shadeMultiplyTexture && this.shadeMultiplyTexture.isTexture === true) {
|
|
406
|
+
const map = refShadeMultiplyTexture.context({ getUV: () => this._animatedUVNode });
|
|
407
|
+
shadeColorNode = shadeColorNode.mul(map);
|
|
408
|
+
}
|
|
409
|
+
return shadeColorNode;
|
|
410
|
+
}
|
|
411
|
+
_setupShadingShiftNode() {
|
|
412
|
+
if (this.shadingShiftNode != null) {
|
|
413
|
+
return Nodes6.float(this.shadingShiftNode);
|
|
414
|
+
}
|
|
415
|
+
let shadingShiftNode = refShadingShiftFactor;
|
|
416
|
+
if (this.shadingShiftTexture && this.shadingShiftTexture.isTexture === true) {
|
|
417
|
+
const map = refShadeMultiplyTexture.context({ getUV: () => this._animatedUVNode });
|
|
418
|
+
shadingShiftNode = shadingShiftNode.add(map.mul(refShadeMultiplyTextureScale));
|
|
419
|
+
}
|
|
420
|
+
return shadingShiftNode;
|
|
421
|
+
}
|
|
422
|
+
_setupShadingToonyNode() {
|
|
423
|
+
if (this.shadingToonyNode != null) {
|
|
424
|
+
return Nodes6.float(this.shadingToonyNode);
|
|
425
|
+
}
|
|
426
|
+
return refShadingToonyFactor;
|
|
427
|
+
}
|
|
428
|
+
_setupRimLightingMixNode() {
|
|
429
|
+
if (this.rimLightingMixNode != null) {
|
|
430
|
+
return Nodes6.float(this.rimLightingMixNode);
|
|
431
|
+
}
|
|
432
|
+
return refRimLightingMixFactor;
|
|
433
|
+
}
|
|
434
|
+
_setupRimMultiplyNode() {
|
|
435
|
+
if (this.rimMultiplyNode != null) {
|
|
436
|
+
return Nodes6.vec3(this.rimMultiplyNode);
|
|
437
|
+
}
|
|
438
|
+
if (this.rimMultiplyTexture && this.rimMultiplyTexture.isTexture === true) {
|
|
439
|
+
const map = refRimMultiplyTexture.context({ getUV: () => this._animatedUVNode });
|
|
440
|
+
return map;
|
|
441
|
+
}
|
|
442
|
+
return Nodes6.vec3(1);
|
|
443
|
+
}
|
|
444
|
+
_setupMatcapNode() {
|
|
445
|
+
if (this.matcapNode != null) {
|
|
446
|
+
return Nodes6.vec3(this.matcapNode);
|
|
447
|
+
}
|
|
448
|
+
if (this.matcapTexture && this.matcapTexture.isTexture === true) {
|
|
449
|
+
const map = refMatcapTexture.context({ getUV: () => Nodes6.matcapUV.mul(1, -1).add(0, 1) });
|
|
450
|
+
return map.mul(refMatcapFactor);
|
|
451
|
+
}
|
|
452
|
+
return Nodes6.vec3(0);
|
|
453
|
+
}
|
|
454
|
+
_setupParametricRimNode() {
|
|
455
|
+
const parametricRimColor = this.parametricRimColorNode != null ? Nodes6.vec3(this.parametricRimColorNode) : refParametricRimColorFactor;
|
|
456
|
+
const parametricRimLift = this.parametricRimLiftNode != null ? Nodes6.float(this.parametricRimLiftNode) : refParametricRimLiftFactor;
|
|
457
|
+
const parametricRimFresnelPower = this.parametricRimFresnelPowerNode != null ? Nodes6.float(this.parametricRimFresnelPowerNode) : refParametricRimFresnelPowerFactor;
|
|
458
|
+
return mtoonParametricRim({
|
|
459
|
+
parametricRimLift,
|
|
460
|
+
parametricRimFresnelPower,
|
|
461
|
+
parametricRimColor
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
export {
|
|
466
|
+
MToonAnimatedUVNode,
|
|
467
|
+
MToonLightingModel,
|
|
468
|
+
MToonNodeMaterial
|
|
469
|
+
};
|
|
470
|
+
/*!
|
|
471
|
+
* @pixiv/three-vrm-materials-mtoon v3.0.0-beta.1
|
|
472
|
+
* MToon (toon material) module for @pixiv/three-vrm
|
|
473
|
+
*
|
|
474
|
+
* Copyright (c) 2019-2024 pixiv Inc.
|
|
475
|
+
* @pixiv/three-vrm-materials-mtoon is distributed under MIT License
|
|
476
|
+
* https://github.com/pixiv/three-vrm/blob/release/LICENSE
|
|
477
|
+
*/
|
|
478
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vdGhyZWUtdnJtLW1hdGVyaWFscy1tdG9vbi9zcmMvbm9kZXMvd2FybmluZ0lmUHJlMTYxLnRzIiwgIi4uLy4uLy4uL3RocmVlLXZybS1tYXRlcmlhbHMtbXRvb24vc3JjL25vZGVzL01Ub29uQW5pbWF0ZWRVVk5vZGUudHMiLCAiLi4vLi4vLi4vdGhyZWUtdnJtLW1hdGVyaWFscy1tdG9vbi9zcmMvbm9kZXMvbWF0ZXJpYWxSZWZlcmVuY2VzLnRzIiwgIi4uLy4uLy4uL3RocmVlLXZybS1tYXRlcmlhbHMtbXRvb24vc3JjL25vZGVzL01Ub29uTGlnaHRpbmdNb2RlbC50cyIsICIuLi8uLi8uLi90aHJlZS12cm0tbWF0ZXJpYWxzLW10b29uL3NyYy9ub2Rlcy9pbW11dGFibGVOb2Rlcy50cyIsICIuLi8uLi8uLi90aHJlZS12cm0tbWF0ZXJpYWxzLW10b29uL3NyYy9ub2Rlcy9NVG9vbk5vZGVNYXRlcmlhbC50cyIsICIuLi8uLi8uLi90aHJlZS12cm0tbWF0ZXJpYWxzLW10b29uL3NyYy9NVG9vbk1hdGVyaWFsT3V0bGluZVdpZHRoTW9kZS50cyIsICIuLi8uLi8uLi90aHJlZS12cm0tbWF0ZXJpYWxzLW10b29uL3NyYy9ub2Rlcy9tdG9vblBhcmFtZXRyaWNSaW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8vIFRoaXMgbW9kdWxlIHdpbGwgYmUgaW1wb3J0ZWQgYXQgdGhlIGJlZ2lubmluZyBvZiBgdGhyZWUtdnJtLW1hdGVyaWFscy1tdG9vbi9ub2Rlc2Bcbi8vIElmIHRoZSB2ZXJzaW9uIG9mIFRocmVlLmpzIGlzIGxlc3MgdGhhbiByMTYxLCBpdCB3aWxsIHdhcm4gdGhhdCBpdCBpcyBub3Qgc3VwcG9ydGVkXG5cbmltcG9ydCAqIGFzIFRIUkVFIGZyb20gJ3RocmVlJztcblxuY29uc3QgdGhyZWVSZXZpc2lvbiA9IHBhcnNlSW50KFRIUkVFLlJFVklTSU9OLCAxMCk7XG5pZiAodGhyZWVSZXZpc2lvbiA8IDE2MSkge1xuICBjb25zb2xlLndhcm4oXG4gICAgYE1Ub29uTm9kZU1hdGVyaWFsIHJlcXVpcmVzIFRocmVlLmpzIHIxNjEgb3IgaGlnaGVyIChZb3UgYXJlIHVzaW5nIHIke3RocmVlUmV2aXNpb259KS4gVGhpcyB3b3VsZCBub3Qgd29yayBjb3JyZWN0bHkuYCxcbiAgKTtcbn1cbiIsICJpbXBvcnQgKiBhcyBOb2RlcyBmcm9tICd0aHJlZS9hZGRvbnMvbm9kZXMvTm9kZXMuanMnO1xuaW1wb3J0IHtcbiAgcmVmVVZBbmltYXRpb25NYXNrVGV4dHVyZSxcbiAgcmVmVVZBbmltYXRpb25Sb3RhdGlvblBoYXNlLFxuICByZWZVVkFuaW1hdGlvblNjcm9sbFhPZmZzZXQsXG4gIHJlZlVWQW5pbWF0aW9uU2Nyb2xsWU9mZnNldCxcbn0gZnJvbSAnLi9tYXRlcmlhbFJlZmVyZW5jZXMnO1xuXG5leHBvcnQgY2xhc3MgTVRvb25BbmltYXRlZFVWTm9kZSBleHRlbmRzIE5vZGVzLlRlbXBOb2RlIHtcbiAgcHVibGljIHJlYWRvbmx5IGhhc01hc2tUZXh0dXJlOiBib29sZWFuO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihoYXNNYXNrVGV4dHVyZTogYm9vbGVhbikge1xuICAgIHN1cGVyKCd2ZWMyJyk7XG5cbiAgICB0aGlzLmhhc01hc2tUZXh0dXJlID0gaGFzTWFza1RleHR1cmU7XG4gIH1cblxuICBwdWJsaWMgc2V0dXAoKTogTm9kZXMuU2hhZGVyTm9kZU9iamVjdDxOb2Rlcy5WYXJOb2RlPiB7XG4gICAgbGV0IHV2QW5pbWF0aW9uTWFzazogTm9kZXMuTm9kZVJlcHJlc2VudGF0aW9uID0gMS4wO1xuXG4gICAgaWYgKHRoaXMuaGFzTWFza1RleHR1cmUpIHtcbiAgICAgIHV2QW5pbWF0aW9uTWFzayA9IE5vZGVzLnZlYzQocmVmVVZBbmltYXRpb25NYXNrVGV4dHVyZSkuY29udGV4dCh7IGdldFVWOiAoKSA9PiBOb2Rlcy51digpIH0pLnI7XG4gICAgfVxuXG4gICAgbGV0IHV2OiBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLlN3aXp6YWJsZT4gPSBOb2Rlcy51digpO1xuXG4gICAgLy8gcm90YXRlXG4gICAgY29uc3QgcGhhc2UgPSByZWZVVkFuaW1hdGlvblJvdGF0aW9uUGhhc2UubXVsKHV2QW5pbWF0aW9uTWFzayk7XG5cbiAgICAvLyBXT1JLQVJPVU5EOiBOb2Rlcy5yb3RhdGVVViBjYXVzZXMgYW4gaXNzdWUgd2l0aCB0aGUgbWFzayB0ZXh0dXJlXG4gICAgLy8gV2UgYXJlIGdvaW5nIHRvIHNwaW4gdXNpbmcgYSAxMDAlIG9yZ2FuaWMgaGFuZG1hZGUgcm90YXRpb24gbWF0cml4XG4gICAgLy8gdXYgPSBOb2Rlcy5yb3RhdGVVVih1diwgcGhhc2UsIE5vZGVzLnZlYzIoMC41LCAwLjUpKTtcblxuICAgIGNvbnN0IGMgPSBOb2Rlcy5jb3MocGhhc2UpO1xuICAgIGNvbnN0IHMgPSBOb2Rlcy5zaW4ocGhhc2UpO1xuICAgIHV2ID0gdXYuc3ViKE5vZGVzLnZlYzIoMC41LCAwLjUpKTtcbiAgICB1diA9IHV2Lm11bChOb2Rlcy5tYXQyKGMsIHMsIHMubmVnYXRlKCksIGMpKTtcbiAgICB1diA9IHV2LmFkZChOb2Rlcy52ZWMyKDAuNSwgMC41KSk7XG5cbiAgICAvLyBzY3JvbGxcbiAgICBjb25zdCBzY3JvbGwgPSBOb2Rlcy52ZWMyKHJlZlVWQW5pbWF0aW9uU2Nyb2xsWE9mZnNldCwgcmVmVVZBbmltYXRpb25TY3JvbGxZT2Zmc2V0KS5tdWwodXZBbmltYXRpb25NYXNrKTtcbiAgICB1diA9IHV2LmFkZChzY3JvbGwpO1xuXG4gICAgcmV0dXJuIHV2LnRlbXAoJ0FuaW1hdGVkVVYnKTtcbiAgfVxufVxuIiwgImltcG9ydCAqIGFzIE5vZGVzIGZyb20gJ3RocmVlL2FkZG9ucy9ub2Rlcy9Ob2Rlcy5qcyc7XG5cbmV4cG9ydCBjb25zdCByZWZDb2xvciA9IE5vZGVzLm1hdGVyaWFsUmVmZXJlbmNlKCdjb2xvcicsICdjb2xvcicpO1xuZXhwb3J0IGNvbnN0IHJlZk1hcCA9IE5vZGVzLm1hdGVyaWFsUmVmZXJlbmNlKCdtYXAnLCAndGV4dHVyZScpO1xuZXhwb3J0IGNvbnN0IHJlZk5vcm1hbE1hcCA9IE5vZGVzLm1hdGVyaWFsUmVmZXJlbmNlKCdub3JtYWxNYXAnLCAndGV4dHVyZScpO1xuZXhwb3J0IGNvbnN0IHJlZk5vcm1hbFNjYWxlID0gTm9kZXMubWF0ZXJpYWxSZWZlcmVuY2UoJ25vcm1hbFNjYWxlJywgJ3ZlYzInKTtcbmV4cG9ydCBjb25zdCByZWZFbWlzc2l2ZSA9IE5vZGVzLm1hdGVyaWFsUmVmZXJlbmNlKCdlbWlzc2l2ZScsICdjb2xvcicpO1xuZXhwb3J0IGNvbnN0IHJlZkVtaXNzaXZlSW50ZW5zaXR5ID0gTm9kZXMubWF0ZXJpYWxSZWZlcmVuY2UoJ2VtaXNzaXZlSW50ZW5zaXR5JywgJ2Zsb2F0Jyk7XG5leHBvcnQgY29uc3QgcmVmRW1pc3NpdmVNYXAgPSBOb2Rlcy5tYXRlcmlhbFJlZmVyZW5jZSgnZW1pc3NpdmVNYXAnLCAndGV4dHVyZScpO1xuXG5leHBvcnQgY29uc3QgcmVmU2hhZGVDb2xvckZhY3RvciA9IE5vZGVzLm1hdGVyaWFsUmVmZXJlbmNlKCdzaGFkZUNvbG9yRmFjdG9yJywgJ2NvbG9yJyk7XG5leHBvcnQgY29uc3QgcmVmU2hhZGluZ1NoaWZ0RmFjdG9yID0gTm9kZXMubWF0ZXJpYWxSZWZlcmVuY2UoJ3NoYWRpbmdTaGlmdEZhY3RvcicsICdmbG9hdCcpO1xuZXhwb3J0IGNvbnN0IHJlZlNoYWRlTXVsdGlwbHlUZXh0dXJlID0gTm9kZXMubWF0ZXJpYWxSZWZlcmVuY2UoJ3NoYWRlTXVsdGlwbHlUZXh0dXJlJywgJ3RleHR1cmUnKTtcbmV4cG9ydCBjb25zdCByZWZTaGFkZU11bHRpcGx5VGV4dHVyZVNjYWxlID0gTm9kZXMubWF0ZXJpYWxSZWZlcmVuY2UoJ3NoYWRlTXVsdGlwbHlUZXh0dXJlU2NhbGUnLCAnZmxvYXQnKTtcbmV4cG9ydCBjb25zdCByZWZTaGFkaW5nVG9vbnlGYWN0b3IgPSBOb2Rlcy5tYXRlcmlhbFJlZmVyZW5jZSgnc2hhZGluZ1Rvb255RmFjdG9yJywgJ2Zsb2F0Jyk7XG5leHBvcnQgY29uc3QgcmVmUmltTGlnaHRpbmdNaXhGYWN0b3IgPSBOb2Rlcy5tYXRlcmlhbFJlZmVyZW5jZSgncmltTGlnaHRpbmdNaXhGYWN0b3InLCAnZmxvYXQnKTtcbmV4cG9ydCBjb25zdCByZWZSaW1NdWx0aXBseVRleHR1cmUgPSBOb2Rlcy5tYXRlcmlhbFJlZmVyZW5jZSgncmltTXVsdGlwbHlUZXh0dXJlJywgJ3RleHR1cmUnKTtcbmV4cG9ydCBjb25zdCByZWZNYXRjYXBGYWN0b3IgPSBOb2Rlcy5tYXRlcmlhbFJlZmVyZW5jZSgnbWF0Y2FwRmFjdG9yJywgJ2NvbG9yJyk7XG5leHBvcnQgY29uc3QgcmVmTWF0Y2FwVGV4dHVyZSA9IE5vZGVzLm1hdGVyaWFsUmVmZXJlbmNlKCdtYXRjYXBUZXh0dXJlJywgJ3RleHR1cmUnKTtcbmV4cG9ydCBjb25zdCByZWZQYXJhbWV0cmljUmltQ29sb3JGYWN0b3IgPSBOb2Rlcy5tYXRlcmlhbFJlZmVyZW5jZSgncGFyYW1ldHJpY1JpbUNvbG9yRmFjdG9yJywgJ2NvbG9yJyk7XG5leHBvcnQgY29uc3QgcmVmUGFyYW1ldHJpY1JpbUxpZnRGYWN0b3IgPSBOb2Rlcy5tYXRlcmlhbFJlZmVyZW5jZSgncGFyYW1ldHJpY1JpbUxpZnRGYWN0b3InLCAnZmxvYXQnKTtcbmV4cG9ydCBjb25zdCByZWZQYXJhbWV0cmljUmltRnJlc25lbFBvd2VyRmFjdG9yID0gTm9kZXMubWF0ZXJpYWxSZWZlcmVuY2UoJ3BhcmFtZXRyaWNSaW1GcmVzbmVsUG93ZXJGYWN0b3InLCAnZmxvYXQnKTtcbmV4cG9ydCBjb25zdCByZWZPdXRsaW5lV2lkdGhNdWx0aXBseVRleHR1cmUgPSBOb2Rlcy5tYXRlcmlhbFJlZmVyZW5jZSgnb3V0bGluZVdpZHRoTXVsdGlwbHlUZXh0dXJlJywgJ3RleHR1cmUnKTtcbmV4cG9ydCBjb25zdCByZWZPdXRsaW5lV2lkdGhGYWN0b3IgPSBOb2Rlcy5tYXRlcmlhbFJlZmVyZW5jZSgnb3V0bGluZVdpZHRoRmFjdG9yJywgJ2Zsb2F0Jyk7XG5leHBvcnQgY29uc3QgcmVmT3V0bGluZUNvbG9yRmFjdG9yID0gTm9kZXMubWF0ZXJpYWxSZWZlcmVuY2UoJ291dGxpbmVDb2xvckZhY3RvcicsICdjb2xvcicpO1xuZXhwb3J0IGNvbnN0IHJlZk91dGxpbmVMaWdodGluZ01peEZhY3RvciA9IE5vZGVzLm1hdGVyaWFsUmVmZXJlbmNlKCdvdXRsaW5lTGlnaHRpbmdNaXhGYWN0b3InLCAnZmxvYXQnKTtcbmV4cG9ydCBjb25zdCByZWZVVkFuaW1hdGlvbk1hc2tUZXh0dXJlID0gTm9kZXMubWF0ZXJpYWxSZWZlcmVuY2UoJ3V2QW5pbWF0aW9uTWFza1RleHR1cmUnLCAndGV4dHVyZScpO1xuXG5leHBvcnQgY29uc3QgcmVmVVZBbmltYXRpb25TY3JvbGxYT2Zmc2V0ID0gTm9kZXMubWF0ZXJpYWxSZWZlcmVuY2UoJ3V2QW5pbWF0aW9uU2Nyb2xsWE9mZnNldCcsICdmbG9hdCcpO1xuZXhwb3J0IGNvbnN0IHJlZlVWQW5pbWF0aW9uU2Nyb2xsWU9mZnNldCA9IE5vZGVzLm1hdGVyaWFsUmVmZXJlbmNlKCd1dkFuaW1hdGlvblNjcm9sbFlPZmZzZXQnLCAnZmxvYXQnKTtcbmV4cG9ydCBjb25zdCByZWZVVkFuaW1hdGlvblJvdGF0aW9uUGhhc2UgPSBOb2Rlcy5tYXRlcmlhbFJlZmVyZW5jZSgndXZBbmltYXRpb25Sb3RhdGlvblBoYXNlJywgJ2Zsb2F0Jyk7XG4iLCAiaW1wb3J0ICogYXMgTm9kZXMgZnJvbSAndGhyZWUvYWRkb25zL25vZGVzL05vZGVzLmpzJztcbmltcG9ydCB7XG4gIG1hdGNhcCxcbiAgcGFyYW1ldHJpY1JpbSxcbiAgcmltTGlnaHRpbmdNaXgsXG4gIHJpbU11bHRpcGx5LFxuICBzaGFkZUNvbG9yLFxuICBzaGFkaW5nU2hpZnQsXG4gIHNoYWRpbmdUb29ueSxcbn0gZnJvbSAnLi9pbW11dGFibGVOb2Rlcyc7XG5cbi8vIFRPRE86IDAlIGNvbmZpZGVuY2UgYWJvdXQgZnVuY3Rpb24gdHlwZXMuXG5cbmNvbnN0IGxpbmVhcnN0ZXAgPSBOb2Rlcy50c2xGbihcbiAgKHtcbiAgICBhLFxuICAgIGIsXG4gICAgdCxcbiAgfToge1xuICAgIGE6IE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT47XG4gICAgYjogTm9kZXMuU2hhZGVyTm9kZU9iamVjdDxOb2Rlcy5Ob2RlPjtcbiAgICB0OiBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+O1xuICB9KSA9PiB7XG4gICAgY29uc3QgdG9wID0gdC5zdWIoYSk7XG4gICAgY29uc3QgYm90dG9tID0gYi5zdWIoYSk7XG4gICAgcmV0dXJuIHRvcC5kaXYoYm90dG9tKS5jbGFtcCgpO1xuICB9LFxuKTtcblxuLyoqXG4gKiBDb252ZXJ0IE5kb3RMIGludG8gdG9vbiBzaGFkaW5nIGZhY3RvciB1c2luZyBzaGFkaW5nU2hpZnQgYW5kIHNoYWRpbmdUb29ueVxuICovXG5jb25zdCBnZXRTaGFkaW5nID0gTm9kZXMudHNsRm4oKHsgZG90TkwgfTogeyBkb3ROTDogTm9kZXMuU2hhZGVyTm9kZU9iamVjdDxOb2Rlcy5Ob2RlPiB9KSA9PiB7XG4gIGNvbnN0IHNoYWRvdyA9IDEuMDsgLy8gVE9ET1xuXG4gIGNvbnN0IGZlYXRoZXIgPSBOb2Rlcy5mbG9hdCgxLjApLnN1YihzaGFkaW5nVG9vbnkpO1xuXG4gIGxldCBzaGFkaW5nOiBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+ID0gZG90TkwuYWRkKHNoYWRpbmdTaGlmdCk7XG4gIHNoYWRpbmcgPSBsaW5lYXJzdGVwKHtcbiAgICBhOiBmZWF0aGVyLm5lZ2F0ZSgpLFxuICAgIGI6IGZlYXRoZXIsXG4gICAgdDogc2hhZGluZyxcbiAgfSk7XG4gIHNoYWRpbmcgPSBzaGFkaW5nLm11bChzaGFkb3cpO1xuICByZXR1cm4gc2hhZGluZztcbn0pO1xuXG4vKipcbiAqIE1peCBkaWZmdXNlQ29sb3IgYW5kIHNoYWRlQ29sb3IgdXNpbmcgc2hhZGluZyBmYWN0b3IgYW5kIGxpZ2h0IGNvbG9yXG4gKi9cbmNvbnN0IGdldERpZmZ1c2UgPSBOb2Rlcy50c2xGbihcbiAgKHtcbiAgICBzaGFkaW5nLFxuICAgIGxpZ2h0Q29sb3IsXG4gIH06IHtcbiAgICBzaGFkaW5nOiBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+O1xuICAgIGxpZ2h0Q29sb3I6IE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT47XG4gIH0pID0+IHtcbiAgICBjb25zdCBkaWZmdXNlQ29sb3IgPSBOb2Rlcy5taXgoc2hhZGVDb2xvciwgTm9kZXMuZGlmZnVzZUNvbG9yLCBzaGFkaW5nKTtcbiAgICBjb25zdCBjb2wgPSBsaWdodENvbG9yLm11bChOb2Rlcy5CUkRGX0xhbWJlcnQoeyBkaWZmdXNlQ29sb3IgfSkpO1xuXG4gICAgcmV0dXJuIGNvbDtcbiAgfSxcbik7XG5cbmV4cG9ydCBjbGFzcyBNVG9vbkxpZ2h0aW5nTW9kZWwgZXh0ZW5kcyBOb2Rlcy5MaWdodGluZ01vZGVsIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuXG4gIGRpcmVjdCh7IGxpZ2h0RGlyZWN0aW9uLCBsaWdodENvbG9yLCByZWZsZWN0ZWRMaWdodCB9OiBOb2Rlcy5MaWdodGluZ01vZGVsRGlyZWN0SW5wdXQpIHtcbiAgICBjb25zdCBkb3ROTCA9IE5vZGVzLnRyYW5zZm9ybWVkTm9ybWFsVmlldy5kb3QobGlnaHREaXJlY3Rpb24pLmNsYW1wKC0xLjAsIDEuMCk7XG5cbiAgICAvLyB0b29uIGRpZmZ1c2VcbiAgICBjb25zdCBzaGFkaW5nID0gZ2V0U2hhZGluZyh7XG4gICAgICBkb3ROTCxcbiAgICB9KTtcblxuICAgIC8vIFVuYWJsZSB0byB1c2UgYGFkZEFzc2lnbmAgaW4gdGhlIGN1cnJlbnQgQHR5cGVzL3RocmVlLCB3ZSB1c2UgYGFzc2lnbmAgYW5kIGBhZGRgIGluc3RlYWRcbiAgICAvLyBUT0RPOiBGaXggdGhlIGBhZGRBc3NpZ25gIGlzc3VlIGZyb20gdGhlIGBAdHlwZXMvdGhyZWVgIHNpZGVcblxuICAgIChyZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlIGFzIE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT4pLmFzc2lnbihcbiAgICAgIChyZWZsZWN0ZWRMaWdodC5kaXJlY3REaWZmdXNlIGFzIE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT4pLmFkZChcbiAgICAgICAgZ2V0RGlmZnVzZSh7XG4gICAgICAgICAgc2hhZGluZyxcbiAgICAgICAgICBsaWdodENvbG9yOiBsaWdodENvbG9yIGFzIE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT4sXG4gICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApO1xuXG4gICAgLy8gcmltXG4gICAgKHJlZmxlY3RlZExpZ2h0LmRpcmVjdFNwZWN1bGFyIGFzIE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT4pLmFzc2lnbihcbiAgICAgIChyZWZsZWN0ZWRMaWdodC5kaXJlY3RTcGVjdWxhciBhcyBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+KS5hZGQoXG4gICAgICAgIHBhcmFtZXRyaWNSaW1cbiAgICAgICAgICAuYWRkKG1hdGNhcClcbiAgICAgICAgICAubXVsKHJpbU11bHRpcGx5KVxuICAgICAgICAgIC5tdWwoTm9kZXMubWl4KE5vZGVzLnZlYzMoMC4wKSwgTm9kZXMuQlJERl9MYW1iZXJ0KHsgZGlmZnVzZUNvbG9yOiBsaWdodENvbG9yIH0pLCByaW1MaWdodGluZ01peCkpLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgaW5kaXJlY3REaWZmdXNlKHsgaXJyYWRpYW5jZSwgcmVmbGVjdGVkTGlnaHQgfTogTm9kZXMuTGlnaHRpbmdNb2RlbEluZGlyZWN0SW5wdXQpIHtcbiAgICAvLyBpbmRpcmVjdCBpcnJhZGlhbmNlXG4gICAgKHJlZmxlY3RlZExpZ2h0LmluZGlyZWN0RGlmZnVzZSBhcyBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+KS5hc3NpZ24oXG4gICAgICAocmVmbGVjdGVkTGlnaHQuaW5kaXJlY3REaWZmdXNlIGFzIE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT4pLmFkZChcbiAgICAgICAgKGlycmFkaWFuY2UgYXMgTm9kZXMuU2hhZGVyTm9kZU9iamVjdDxOb2Rlcy5Ob2RlPikubXVsKFxuICAgICAgICAgIE5vZGVzLkJSREZfTGFtYmVydCh7XG4gICAgICAgICAgICBkaWZmdXNlQ29sb3I6IE5vZGVzLmRpZmZ1c2VDb2xvcixcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgICksXG4gICAgKTtcbiAgfVxuXG4gIGluZGlyZWN0U3BlY3VsYXIoeyByZWZsZWN0ZWRMaWdodCB9OiBOb2Rlcy5MaWdodGluZ01vZGVsSW5kaXJlY3RJbnB1dCkge1xuICAgIC8vIHJpbVxuICAgIChyZWZsZWN0ZWRMaWdodC5pbmRpcmVjdFNwZWN1bGFyIGFzIE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT4pLmFzc2lnbihcbiAgICAgIChyZWZsZWN0ZWRMaWdodC5pbmRpcmVjdFNwZWN1bGFyIGFzIE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT4pLmFkZChcbiAgICAgICAgcGFyYW1ldHJpY1JpbVxuICAgICAgICAgIC5hZGQobWF0Y2FwKVxuICAgICAgICAgIC5tdWwocmltTXVsdGlwbHkpXG4gICAgICAgICAgLm11bChOb2Rlcy5taXgoTm9kZXMudmVjMygxLjApLCBOb2Rlcy52ZWMzKDAuMCksIHJpbUxpZ2h0aW5nTWl4KSksXG4gICAgICApLFxuICAgICk7XG4gIH1cbn1cbiIsICJpbXBvcnQgKiBhcyBOb2RlcyBmcm9tICd0aHJlZS9hZGRvbnMvbm9kZXMvTm9kZXMuanMnO1xuXG5leHBvcnQgY29uc3Qgc2hhZGVDb2xvciA9IE5vZGVzLm5vZGVJbW11dGFibGUoTm9kZXMuUHJvcGVydHlOb2RlLCAndmVjMycpLnRlbXAoJ1NoYWRlQ29sb3InKTtcbmV4cG9ydCBjb25zdCBzaGFkaW5nU2hpZnQgPSBOb2Rlcy5ub2RlSW1tdXRhYmxlKE5vZGVzLlByb3BlcnR5Tm9kZSwgJ2Zsb2F0JykudGVtcCgnU2hhZGluZ1NoaWZ0Jyk7XG5leHBvcnQgY29uc3Qgc2hhZGluZ1Rvb255ID0gTm9kZXMubm9kZUltbXV0YWJsZShOb2Rlcy5Qcm9wZXJ0eU5vZGUsICdmbG9hdCcpLnRlbXAoJ1NoYWRpbmdUb29ueScpO1xuZXhwb3J0IGNvbnN0IHJpbUxpZ2h0aW5nTWl4ID0gTm9kZXMubm9kZUltbXV0YWJsZShOb2Rlcy5Qcm9wZXJ0eU5vZGUsICdmbG9hdCcpLnRlbXAoJ1JpbUxpZ2h0aW5nTWl4Jyk7XG5leHBvcnQgY29uc3QgcmltTXVsdGlwbHkgPSBOb2Rlcy5ub2RlSW1tdXRhYmxlKE5vZGVzLlByb3BlcnR5Tm9kZSwgJ3ZlYzMnKS50ZW1wKCdSaW1NdWx0aXBseScpO1xuZXhwb3J0IGNvbnN0IG1hdGNhcCA9IE5vZGVzLm5vZGVJbW11dGFibGUoTm9kZXMuUHJvcGVydHlOb2RlLCAndmVjMycpLnRlbXAoJ21hdGNhcCcpO1xuZXhwb3J0IGNvbnN0IHBhcmFtZXRyaWNSaW0gPSBOb2Rlcy5ub2RlSW1tdXRhYmxlKE5vZGVzLlByb3BlcnR5Tm9kZSwgJ3ZlYzMnKS50ZW1wKCdQYXJhbWV0cmljUmltJyk7XG4iLCAiaW1wb3J0ICogYXMgVEhSRUUgZnJvbSAndGhyZWUnO1xuaW1wb3J0ICogYXMgTm9kZXMgZnJvbSAndGhyZWUvYWRkb25zL25vZGVzL05vZGVzLmpzJztcblxuaW1wb3J0IHR5cGUgeyBNVG9vbk1hdGVyaWFsIH0gZnJvbSAnLi4vTVRvb25NYXRlcmlhbCc7XG5pbXBvcnQgeyBNVG9vbkxpZ2h0aW5nTW9kZWwgfSBmcm9tICcuL01Ub29uTGlnaHRpbmdNb2RlbCc7XG5pbXBvcnQge1xuICByaW1MaWdodGluZ01peCxcbiAgbWF0Y2FwLFxuICBzaGFkZUNvbG9yLFxuICBzaGFkaW5nU2hpZnQsXG4gIHNoYWRpbmdUb29ueSxcbiAgcmltTXVsdGlwbHksXG4gIHBhcmFtZXRyaWNSaW0sXG59IGZyb20gJy4vaW1tdXRhYmxlTm9kZXMnO1xuaW1wb3J0IHtcbiAgcmVmQ29sb3IsXG4gIHJlZkVtaXNzaXZlLFxuICByZWZFbWlzc2l2ZUludGVuc2l0eSxcbiAgcmVmRW1pc3NpdmVNYXAsXG4gIHJlZk1hcCxcbiAgcmVmTWF0Y2FwRmFjdG9yLFxuICByZWZNYXRjYXBUZXh0dXJlLFxuICByZWZOb3JtYWxNYXAsXG4gIHJlZk5vcm1hbFNjYWxlLFxuICByZWZPdXRsaW5lQ29sb3JGYWN0b3IsXG4gIHJlZk91dGxpbmVMaWdodGluZ01peEZhY3RvcixcbiAgcmVmT3V0bGluZVdpZHRoRmFjdG9yLFxuICByZWZPdXRsaW5lV2lkdGhNdWx0aXBseVRleHR1cmUsXG4gIHJlZlBhcmFtZXRyaWNSaW1Db2xvckZhY3RvcixcbiAgcmVmUGFyYW1ldHJpY1JpbUZyZXNuZWxQb3dlckZhY3RvcixcbiAgcmVmUGFyYW1ldHJpY1JpbUxpZnRGYWN0b3IsXG4gIHJlZlJpbUxpZ2h0aW5nTWl4RmFjdG9yLFxuICByZWZSaW1NdWx0aXBseVRleHR1cmUsXG4gIHJlZlNoYWRlQ29sb3JGYWN0b3IsXG4gIHJlZlNoYWRlTXVsdGlwbHlUZXh0dXJlLFxuICByZWZTaGFkZU11bHRpcGx5VGV4dHVyZVNjYWxlLFxuICByZWZTaGFkaW5nU2hpZnRGYWN0b3IsXG4gIHJlZlNoYWRpbmdUb29ueUZhY3Rvcixcbn0gZnJvbSAnLi9tYXRlcmlhbFJlZmVyZW5jZXMnO1xuaW1wb3J0IHsgTVRvb25BbmltYXRlZFVWTm9kZSB9IGZyb20gJy4vTVRvb25BbmltYXRlZFVWTm9kZSc7XG5pbXBvcnQgeyBNVG9vbk1hdGVyaWFsT3V0bGluZVdpZHRoTW9kZSB9IGZyb20gJy4uL01Ub29uTWF0ZXJpYWxPdXRsaW5lV2lkdGhNb2RlJztcbmltcG9ydCB7IE1Ub29uTm9kZU1hdGVyaWFsUGFyYW1ldGVycyB9IGZyb20gJy4vTVRvb25Ob2RlTWF0ZXJpYWxQYXJhbWV0ZXJzJztcbmltcG9ydCB7IG10b29uUGFyYW1ldHJpY1JpbSB9IGZyb20gJy4vbXRvb25QYXJhbWV0cmljUmltJztcbi8vIGltcG9ydCBwaG9uZ0xpZ2h0aW5nTW9kZWwgZnJvbSAndGhyZWUvYWRkb25zL25vZGVzL2Z1bmN0aW9ucy9QaG9uZ0xpZ2h0aW5nTW9kZWwuanMnO1xuLy8gaW1wb3J0IHsgZmxvYXQgfSBmcm9tICcuLi9zaGFkZXJub2RlL1NoYWRlck5vZGUuanMnO1xuXG4vKipcbiAqIE1Ub29uIGlzIGEgbWF0ZXJpYWwgc3BlY2lmaWNhdGlvbiB0aGF0IGhhcyB2YXJpb3VzIGZlYXR1cmVzLlxuICogVGhlIHNwZWMgYW5kIGltcGxlbWVudGF0aW9uIGFyZSBvcmlnaW5hbGx5IGZvdW5kZWQgZm9yIFVuaXR5IGVuZ2luZSBhbmQgdGhpcyBpcyBhIHBvcnQgb2YgdGhlIG1hdGVyaWFsLlxuICpcbiAqIFRoaXMgbWF0ZXJpYWwgaXMgYSBOb2RlTWF0ZXJpYWwgdmFyaWFudCBvZiB7QGxpbmsgTVRvb25NYXRlcmlhbH0uXG4gKlxuICogU2VlOiBodHRwczovL2dpdGh1Yi5jb20vU2FudGFyaC9NVG9vblxuICovXG5leHBvcnQgY2xhc3MgTVRvb25Ob2RlTWF0ZXJpYWwgZXh0ZW5kcyBOb2Rlcy5Ob2RlTWF0ZXJpYWwge1xuICBwdWJsaWMgZW1pc3NpdmVOb2RlOiBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+IHwgbnVsbDtcblxuICBwdWJsaWMgY29sb3I6IFRIUkVFLkNvbG9yO1xuICBwdWJsaWMgbWFwOiBUSFJFRS5UZXh0dXJlIHwgbnVsbDtcbiAgcHVibGljIGVtaXNzaXZlOiBUSFJFRS5Db2xvcjtcbiAgcHVibGljIGVtaXNzaXZlSW50ZW5zaXR5OiBudW1iZXI7XG4gIHB1YmxpYyBlbWlzc2l2ZU1hcDogVEhSRUUuVGV4dHVyZSB8IG51bGw7XG4gIHB1YmxpYyBub3JtYWxNYXA6IFRIUkVFLlRleHR1cmUgfCBudWxsO1xuICBwdWJsaWMgbm9ybWFsU2NhbGU6IFRIUkVFLlZlY3RvcjI7XG5cbiAgcHVibGljIHNoYWRlQ29sb3JGYWN0b3I6IFRIUkVFLkNvbG9yO1xuICBwdWJsaWMgc2hhZGVNdWx0aXBseVRleHR1cmU6IFRIUkVFLlRleHR1cmUgfCBudWxsO1xuICBwdWJsaWMgc2hhZGluZ1NoaWZ0RmFjdG9yOiBudW1iZXI7XG4gIHB1YmxpYyBzaGFkaW5nU2hpZnRUZXh0dXJlOiBUSFJFRS5UZXh0dXJlIHwgbnVsbDtcbiAgcHVibGljIHNoYWRpbmdTaGlmdFRleHR1cmVTY2FsZTogbnVtYmVyO1xuICBwdWJsaWMgc2hhZGluZ1Rvb255RmFjdG9yOiBudW1iZXI7XG4gIHB1YmxpYyByaW1MaWdodGluZ01peEZhY3RvcjogbnVtYmVyO1xuICBwdWJsaWMgcmltTXVsdGlwbHlUZXh0dXJlOiBUSFJFRS5UZXh0dXJlIHwgbnVsbDtcbiAgcHVibGljIG1hdGNhcEZhY3RvcjogVEhSRUUuQ29sb3I7XG4gIHB1YmxpYyBtYXRjYXBUZXh0dXJlOiBUSFJFRS5UZXh0dXJlIHwgbnVsbDtcbiAgcHVibGljIHBhcmFtZXRyaWNSaW1Db2xvckZhY3RvcjogVEhSRUUuQ29sb3I7XG4gIHB1YmxpYyBwYXJhbWV0cmljUmltTGlmdEZhY3RvcjogbnVtYmVyO1xuICBwdWJsaWMgcGFyYW1ldHJpY1JpbUZyZXNuZWxQb3dlckZhY3RvcjogbnVtYmVyO1xuICBwdWJsaWMgb3V0bGluZVdpZHRoTW9kZTogTVRvb25NYXRlcmlhbE91dGxpbmVXaWR0aE1vZGU7XG4gIHB1YmxpYyBvdXRsaW5lV2lkdGhNdWx0aXBseVRleHR1cmU6IFRIUkVFLlRleHR1cmUgfCBudWxsO1xuICBwdWJsaWMgb3V0bGluZVdpZHRoRmFjdG9yOiBudW1iZXI7XG4gIHB1YmxpYyBvdXRsaW5lQ29sb3JGYWN0b3I6IFRIUkVFLkNvbG9yO1xuICBwdWJsaWMgb3V0bGluZUxpZ2h0aW5nTWl4RmFjdG9yOiBudW1iZXI7XG4gIHB1YmxpYyB1dkFuaW1hdGlvblNjcm9sbFhTcGVlZEZhY3RvcjogbnVtYmVyO1xuICBwdWJsaWMgdXZBbmltYXRpb25TY3JvbGxZU3BlZWRGYWN0b3I6IG51bWJlcjtcbiAgcHVibGljIHV2QW5pbWF0aW9uUm90YXRpb25TcGVlZEZhY3RvcjogbnVtYmVyO1xuICBwdWJsaWMgdXZBbmltYXRpb25NYXNrVGV4dHVyZTogVEhSRUUuVGV4dHVyZSB8IG51bGw7XG5cbiAgcHVibGljIHNoYWRlQ29sb3JOb2RlOiBOb2Rlcy5Td2l6emFibGUgfCBudWxsO1xuICBwdWJsaWMgc2hhZGluZ1NoaWZ0Tm9kZTogTm9kZXMuTm9kZSB8IG51bGw7XG4gIHB1YmxpYyBzaGFkaW5nVG9vbnlOb2RlOiBOb2Rlcy5Ob2RlIHwgbnVsbDtcbiAgcHVibGljIHJpbUxpZ2h0aW5nTWl4Tm9kZTogTm9kZXMuTm9kZSB8IG51bGw7XG4gIHB1YmxpYyByaW1NdWx0aXBseU5vZGU6IE5vZGVzLk5vZGUgfCBudWxsO1xuICBwdWJsaWMgbWF0Y2FwTm9kZTogTm9kZXMuTm9kZSB8IG51bGw7XG4gIHB1YmxpYyBwYXJhbWV0cmljUmltQ29sb3JOb2RlOiBOb2Rlcy5Td2l6emFibGUgfCBudWxsO1xuICBwdWJsaWMgcGFyYW1ldHJpY1JpbUxpZnROb2RlOiBOb2Rlcy5Ob2RlIHwgbnVsbDtcbiAgcHVibGljIHBhcmFtZXRyaWNSaW1GcmVzbmVsUG93ZXJOb2RlOiBOb2Rlcy5Ob2RlIHwgbnVsbDtcblxuICBwdWJsaWMgdXZBbmltYXRpb25TY3JvbGxYT2Zmc2V0OiBudW1iZXI7XG4gIHB1YmxpYyB1dkFuaW1hdGlvblNjcm9sbFlPZmZzZXQ6IG51bWJlcjtcbiAgcHVibGljIHV2QW5pbWF0aW9uUm90YXRpb25QaGFzZTogbnVtYmVyO1xuXG4gIHB1YmxpYyBpc091dGxpbmU6IGJvb2xlYW47XG5cbiAgcHJpdmF0ZSBfYW5pbWF0ZWRVVk5vZGU6IE1Ub29uQW5pbWF0ZWRVVk5vZGUgfCBudWxsO1xuXG4gIHB1YmxpYyBjdXN0b21Qcm9ncmFtQ2FjaGVLZXkoKTogc3RyaW5nIHtcbiAgICBsZXQgY2FjaGVLZXkgPSBzdXBlci5jdXN0b21Qcm9ncmFtQ2FjaGVLZXkoKTtcblxuICAgIGNhY2hlS2V5ICs9IGBpc091dGxpbmU6JHt0aGlzLmlzT3V0bGluZX0sYDtcblxuICAgIHJldHVybiBjYWNoZUtleTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkb25seSBib29sZWFuIHRoYXQgaW5kaWNhdGVzIHRoaXMgaXMgYSB7QGxpbmsgTVRvb25Ob2RlTWF0ZXJpYWx9LlxuICAgKi9cbiAgcHVibGljIGdldCBpc01Ub29uTm9kZU1hdGVyaWFsKCk6IHRydWUge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHBhcmFtZXRlcnM6IE1Ub29uTm9kZU1hdGVyaWFsUGFyYW1ldGVycyA9IHt9KSB7XG4gICAgc3VwZXIoKTtcblxuICAgIGlmIChwYXJhbWV0ZXJzLnRyYW5zcGFyZW50V2l0aFpXcml0ZSkge1xuICAgICAgcGFyYW1ldGVycy5kZXB0aFdyaXRlID0gdHJ1ZTtcbiAgICB9XG4gICAgZGVsZXRlIHBhcmFtZXRlcnMudHJhbnNwYXJlbnRXaXRoWldyaXRlO1xuXG4gICAgLy8gYE1Ub29uTWF0ZXJpYWxMb2FkZXJQbHVnaW5gIGFzc2lnbnMgdGhlc2UgcGFyYW1ldGVycyB0byB0aGUgbWF0ZXJpYWxcbiAgICAvLyBIb3dldmVyLCBgTVRvb25Ob2RlTWF0ZXJpYWxgIGRvZXMgbm90IHN1cHBvcnQgdGhlc2UgcGFyYW1ldGVyc1xuICAgIC8vIHNvIHdlIGRlbGV0ZSB0aGVtIGhlcmUgdG8gc3VwcHJlc3Mgd2FybmluZ3NcbiAgICBkZWxldGUgKHBhcmFtZXRlcnMgYXMgYW55KS5naUVxdWFsaXphdGlvbkZhY3RvcjtcbiAgICBkZWxldGUgKHBhcmFtZXRlcnMgYXMgYW55KS52MENvbXBhdFNoYWRlO1xuICAgIGRlbGV0ZSAocGFyYW1ldGVycyBhcyBhbnkpLmRlYnVnTW9kZTtcblxuICAgIHRoaXMuZW1pc3NpdmVOb2RlID0gbnVsbDtcblxuICAgIHRoaXMubGlnaHRzID0gdHJ1ZTtcblxuICAgIHRoaXMuY29sb3IgPSBuZXcgVEhSRUUuQ29sb3IoMS4wLCAxLjAsIDEuMCk7XG4gICAgdGhpcy5tYXAgPSBudWxsO1xuICAgIHRoaXMuZW1pc3NpdmUgPSBuZXcgVEhSRUUuQ29sb3IoMC4wLCAwLjAsIDAuMCk7XG4gICAgdGhpcy5lbWlzc2l2ZUludGVuc2l0eSA9IDEuMDtcbiAgICB0aGlzLmVtaXNzaXZlTWFwID0gbnVsbDtcbiAgICB0aGlzLm5vcm1hbE1hcCA9IG51bGw7XG4gICAgdGhpcy5ub3JtYWxTY2FsZSA9IG5ldyBUSFJFRS5WZWN0b3IyKDEuMCwgMS4wKTtcbiAgICB0aGlzLnNoYWRlQ29sb3JGYWN0b3IgPSBuZXcgVEhSRUUuQ29sb3IoMC4wLCAwLjAsIDAuMCk7XG4gICAgdGhpcy5zaGFkZU11bHRpcGx5VGV4dHVyZSA9IG51bGw7XG4gICAgdGhpcy5zaGFkaW5nU2hpZnRGYWN0b3IgPSAwLjA7XG4gICAgdGhpcy5zaGFkaW5nU2hpZnRUZXh0dXJlID0gbnVsbDtcbiAgICB0aGlzLnNoYWRpbmdTaGlmdFRleHR1cmVTY2FsZSA9IDEuMDtcbiAgICB0aGlzLnNoYWRpbmdUb29ueUZhY3RvciA9IDAuOTtcbiAgICB0aGlzLnJpbUxpZ2h0aW5nTWl4RmFjdG9yID0gMS4wO1xuICAgIHRoaXMucmltTXVsdGlwbHlUZXh0dXJlID0gbnVsbDtcbiAgICB0aGlzLm1hdGNhcEZhY3RvciA9IG5ldyBUSFJFRS5Db2xvcigxLjAsIDEuMCwgMS4wKTtcbiAgICB0aGlzLm1hdGNhcFRleHR1cmUgPSBudWxsO1xuICAgIHRoaXMucGFyYW1ldHJpY1JpbUNvbG9yRmFjdG9yID0gbmV3IFRIUkVFLkNvbG9yKDAuMCwgMC4wLCAwLjApO1xuICAgIHRoaXMucGFyYW1ldHJpY1JpbUxpZnRGYWN0b3IgPSAwLjA7XG4gICAgdGhpcy5wYXJhbWV0cmljUmltRnJlc25lbFBvd2VyRmFjdG9yID0gNS4wO1xuICAgIHRoaXMub3V0bGluZVdpZHRoTW9kZSA9IE1Ub29uTWF0ZXJpYWxPdXRsaW5lV2lkdGhNb2RlLk5vbmU7XG4gICAgdGhpcy5vdXRsaW5lV2lkdGhNdWx0aXBseVRleHR1cmUgPSBudWxsO1xuICAgIHRoaXMub3V0bGluZVdpZHRoRmFjdG9yID0gMC4wO1xuICAgIHRoaXMub3V0bGluZUNvbG9yRmFjdG9yID0gbmV3IFRIUkVFLkNvbG9yKDAuMCwgMC4wLCAwLjApO1xuICAgIHRoaXMub3V0bGluZUxpZ2h0aW5nTWl4RmFjdG9yID0gMS4wO1xuICAgIHRoaXMudXZBbmltYXRpb25TY3JvbGxYU3BlZWRGYWN0b3IgPSAwLjA7XG4gICAgdGhpcy51dkFuaW1hdGlvblNjcm9sbFlTcGVlZEZhY3RvciA9IDAuMDtcbiAgICB0aGlzLnV2QW5pbWF0aW9uUm90YXRpb25TcGVlZEZhY3RvciA9IDAuMDtcbiAgICB0aGlzLnV2QW5pbWF0aW9uTWFza1RleHR1cmUgPSBudWxsO1xuXG4gICAgdGhpcy5zaGFkZUNvbG9yTm9kZSA9IG51bGw7XG4gICAgdGhpcy5zaGFkaW5nU2hpZnROb2RlID0gbnVsbDtcbiAgICB0aGlzLnNoYWRpbmdUb29ueU5vZGUgPSBudWxsO1xuICAgIHRoaXMucmltTGlnaHRpbmdNaXhOb2RlID0gbnVsbDtcbiAgICB0aGlzLnJpbU11bHRpcGx5Tm9kZSA9IG51bGw7XG4gICAgdGhpcy5tYXRjYXBOb2RlID0gbnVsbDtcbiAgICB0aGlzLnBhcmFtZXRyaWNSaW1Db2xvck5vZGUgPSBudWxsO1xuICAgIHRoaXMucGFyYW1ldHJpY1JpbUxpZnROb2RlID0gbnVsbDtcbiAgICB0aGlzLnBhcmFtZXRyaWNSaW1GcmVzbmVsUG93ZXJOb2RlID0gbnVsbDtcblxuICAgIHRoaXMudXZBbmltYXRpb25TY3JvbGxYT2Zmc2V0ID0gMC4wO1xuICAgIHRoaXMudXZBbmltYXRpb25TY3JvbGxZT2Zmc2V0ID0gMC4wO1xuICAgIHRoaXMudXZBbmltYXRpb25Sb3RhdGlvblBoYXNlID0gMC4wO1xuXG4gICAgdGhpcy5pc091dGxpbmUgPSBmYWxzZTtcblxuICAgIHRoaXMuX2FuaW1hdGVkVVZOb2RlID0gbnVsbDtcblxuICAgIHRoaXMuc2V0VmFsdWVzKHBhcmFtZXRlcnMpO1xuICB9XG5cbiAgcHVibGljIHNldHVwTGlnaHRpbmdNb2RlbCgvKmJ1aWxkZXIqLyk6IE1Ub29uTGlnaHRpbmdNb2RlbCB7XG4gICAgcmV0dXJuIG5ldyBNVG9vbkxpZ2h0aW5nTW9kZWwoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXR1cChidWlsZGVyOiBOb2Rlcy5Ob2RlQnVpbGRlcik6IHZvaWQge1xuICAgIHRoaXMuX2FuaW1hdGVkVVZOb2RlID0gbmV3IE1Ub29uQW5pbWF0ZWRVVk5vZGUoXG4gICAgICAodGhpcy51dkFuaW1hdGlvbk1hc2tUZXh0dXJlICYmIHRoaXMudXZBbmltYXRpb25NYXNrVGV4dHVyZS5pc1RleHR1cmUgPT09IHRydWUpID8/IGZhbHNlLFxuICAgICk7XG5cbiAgICBzdXBlci5zZXR1cChidWlsZGVyKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXR1cERpZmZ1c2VDb2xvcihidWlsZGVyOiBOb2Rlcy5Ob2RlQnVpbGRlcik6IHZvaWQge1xuICAgIC8vIHdlIG11c3QgYXBwbHkgdXYgc2Nyb2xsIHRvIHRoZSBtYXBcbiAgICAvLyB0aGlzLmNvbG9yTm9kZSB3aWxsIGJlIHVzZWQgaW4gc3VwZXIuc2V0dXBEaWZmdXNlQ29sb3IoKSBzbyB3ZSB0ZW1wb3JhcmlseSByZXBsYWNlIGl0XG4gICAgbGV0IHRlbXBDb2xvck5vZGU6IE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT4gfCBudWxsID0gbnVsbDtcblxuICAgIGlmICh0aGlzLmNvbG9yTm9kZSA9PSBudWxsKSB7XG4gICAgICB0ZW1wQ29sb3JOb2RlID0gcmVmQ29sb3I7XG5cbiAgICAgIGlmICh0aGlzLm1hcCAmJiB0aGlzLm1hcC5pc1RleHR1cmUgPT09IHRydWUpIHtcbiAgICAgICAgY29uc3QgbWFwID0gcmVmTWFwLmNvbnRleHQoeyBnZXRVVjogKCkgPT4gdGhpcy5fYW5pbWF0ZWRVVk5vZGUgfSk7XG4gICAgICAgIHRlbXBDb2xvck5vZGUgPSB0ZW1wQ29sb3JOb2RlLm11bChtYXApO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmNvbG9yTm9kZSA9IHRlbXBDb2xvck5vZGU7XG4gICAgfVxuXG4gICAgLy8gTVRvb24gbXVzdCBpZ25vcmUgdmVydGV4IGNvbG9yIGJ5IHNwZWNcbiAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS92cm0tYy92cm0tc3BlY2lmaWNhdGlvbi9ibG9iLzQyYzBhOTBlNmI0YjcxMDM1MjU2OTk3OGYxNDk4MGU5ZmM5NGIyNWQvc3BlY2lmaWNhdGlvbi9WUk1DX21hdGVyaWFsc19tdG9vbi0xLjAvUkVBRE1FLm1kI3ZlcnRleC1jb2xvcnNcbiAgICBpZiAodGhpcy52ZXJ0ZXhDb2xvcnMgPT09IHRydWUgJiYgYnVpbGRlci5nZW9tZXRyeS5oYXNBdHRyaWJ1dGUoJ2NvbG9yJykpIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgJ01Ub29uTm9kZU1hdGVyaWFsOiBNVG9vbiBpZ25vcmVzIHZlcnRleCBjb2xvcnMuIENvbnNpZGVyIHVzaW5nIGEgbW9kZWwgd2l0aG91dCB2ZXJ0ZXggY29sb3JzIGluc3RlYWQuJyxcbiAgICAgICk7XG4gICAgICB0aGlzLnZlcnRleENvbG9ycyA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8vIHRoZSBvcmRpbmFyeSBkaWZmdXNlQ29sb3Igc2V0dXBcbiAgICBzdXBlci5zZXR1cERpZmZ1c2VDb2xvcihidWlsZGVyKTtcblxuICAgIC8vIENPTVBBVDogcHJlLXIxNjZcbiAgICAvLyBTZXQgYWxwaGEgdG8gMSBpZiBpdCBpcyBvcGFxdWVcbiAgICAvLyBBZGRyZXNzZWQgaW4gVGhyZWUuanMgcjE2NiBidXQgd2UgbGVhdmUgaXQgaGVyZSBmb3IgY29tcGF0aWJpbGl0eVxuICAgIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL21yZG9vYi90aHJlZS5qcy9wdWxsLzI4NjQ2XG4gICAgaWYgKHBhcnNlSW50KFRIUkVFLlJFVklTSU9OLCAxMCkgPCAxNjYpIHtcbiAgICAgIGlmICh0aGlzLnRyYW5zcGFyZW50ID09PSBmYWxzZSAmJiB0aGlzLmJsZW5kaW5nID09PSBUSFJFRS5Ob3JtYWxCbGVuZGluZyAmJiB0aGlzLmFscGhhVG9Db3ZlcmFnZSA9PT0gZmFsc2UpIHtcbiAgICAgICAgTm9kZXMuZGlmZnVzZUNvbG9yLmEuYXNzaWduKDEuMCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gcmV2ZXJ0IHRoZSBjb2xvck5vZGVcbiAgICBpZiAodGhpcy5jb2xvck5vZGUgPT09IHRlbXBDb2xvck5vZGUpIHtcbiAgICAgIHRoaXMuY29sb3JOb2RlID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc2V0dXBWYXJpYW50cyh7IHN0YWNrIH06IE5vZGVzLk5vZGVCdWlsZGVyKTogdm9pZCB7XG4gICAgc3RhY2suYXNzaWduKHNoYWRlQ29sb3IsIHRoaXMuX3NldHVwU2hhZGVDb2xvck5vZGUoKSk7XG4gICAgc3RhY2suYXNzaWduKHNoYWRpbmdTaGlmdCwgdGhpcy5fc2V0dXBTaGFkaW5nU2hpZnROb2RlKCkpO1xuICAgIHN0YWNrLmFzc2lnbihzaGFkaW5nVG9vbnksIHRoaXMuX3NldHVwU2hhZGluZ1Rvb255Tm9kZSgpKTtcbiAgICBzdGFjay5hc3NpZ24ocmltTGlnaHRpbmdNaXgsIHRoaXMuX3NldHVwUmltTGlnaHRpbmdNaXhOb2RlKCkpO1xuICAgIHN0YWNrLmFzc2lnbihyaW1NdWx0aXBseSwgdGhpcy5fc2V0dXBSaW1NdWx0aXBseU5vZGUoKSk7XG4gICAgc3RhY2suYXNzaWduKG1hdGNhcCwgdGhpcy5fc2V0dXBNYXRjYXBOb2RlKCkpO1xuICAgIHN0YWNrLmFzc2lnbihwYXJhbWV0cmljUmltLCB0aGlzLl9zZXR1cFBhcmFtZXRyaWNSaW1Ob2RlKCkpO1xuICB9XG5cbiAgcHVibGljIHNldHVwTm9ybWFsKGJ1aWxkZXI6IE5vZGVzLk5vZGVCdWlsZGVyKTogdm9pZCB7XG4gICAgLy8gd2UgbXVzdCBhcHBseSB1diBzY3JvbGwgdG8gdGhlIG5vcm1hbE1hcFxuICAgIC8vIHRoaXMubm9ybWFsTm9kZSB3aWxsIGJlIHVzZWQgaW4gc3VwZXIuc2V0dXBOb3JtYWwoKSBzbyB3ZSB0ZW1wb3JhcmlseSByZXBsYWNlIGl0XG4gICAgY29uc3QgdGVtcE5vcm1hbE5vZGU6IE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT4gfCBudWxsID0gdGhpcy5ub3JtYWxOb2RlO1xuXG4gICAgaWYgKHRoaXMubm9ybWFsTm9kZSA9PSBudWxsKSB7XG4gICAgICB0aGlzLm5vcm1hbE5vZGUgPSBOb2Rlcy5tYXRlcmlhbE5vcm1hbDtcblxuICAgICAgaWYgKHRoaXMubm9ybWFsTWFwICYmIHRoaXMubm9ybWFsTWFwLmlzVGV4dHVyZSA9PT0gdHJ1ZSkge1xuICAgICAgICBjb25zdCBtYXAgPSByZWZOb3JtYWxNYXAuY29udGV4dCh7IGdldFVWOiAoKSA9PiB0aGlzLl9hbmltYXRlZFVWTm9kZSB9KTtcbiAgICAgICAgdGhpcy5ub3JtYWxOb2RlID0gbWFwLm5vcm1hbE1hcChyZWZOb3JtYWxTY2FsZSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLmlzT3V0bGluZSkge1xuICAgICAgICB0aGlzLm5vcm1hbE5vZGUgPSB0aGlzLm5vcm1hbE5vZGUubmVnYXRlKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gdGhlIG9yZGluYXJ5IG5vcm1hbCBzZXR1cFxuICAgIHN1cGVyLnNldHVwTm9ybWFsKGJ1aWxkZXIpO1xuXG4gICAgLy8gcmV2ZXJ0IHRoZSBub3JtYWxOb2RlXG4gICAgdGhpcy5ub3JtYWxOb2RlID0gdGVtcE5vcm1hbE5vZGU7XG4gIH1cblxuICBwdWJsaWMgc2V0dXBMaWdodGluZyhidWlsZGVyOiBOb2Rlcy5Ob2RlQnVpbGRlcik6IE5vZGVzLk5vZGUge1xuICAgIC8vIHdlIG11c3QgYXBwbHkgdXYgc2Nyb2xsIHRvIHRoZSBlbWlzc2l2ZU1hcFxuICAgIC8vIHRoaXMuZW1pc3NpdmVOb2RlIHdpbGwgYmUgdXNlZCBpbiBzdXBlci5zZXR1cExpZ2h0aW5nKCkgc28gd2UgdGVtcG9yYXJpbHkgcmVwbGFjZSBpdFxuICAgIGxldCB0ZW1wRW1pc3NpdmVOb2RlOiBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+IHwgbnVsbCA9IG51bGw7XG5cbiAgICBpZiAodGhpcy5lbWlzc2l2ZU5vZGUgPT0gbnVsbCkge1xuICAgICAgdGVtcEVtaXNzaXZlTm9kZSA9IHJlZkVtaXNzaXZlLm11bChyZWZFbWlzc2l2ZUludGVuc2l0eSk7XG5cbiAgICAgIGlmICh0aGlzLmVtaXNzaXZlTWFwICYmIHRoaXMuZW1pc3NpdmVNYXAuaXNUZXh0dXJlID09PSB0cnVlKSB7XG4gICAgICAgIGNvbnN0IG1hcCA9IHJlZkVtaXNzaXZlTWFwLmNvbnRleHQoeyBnZXRVVjogKCkgPT4gdGhpcy5fYW5pbWF0ZWRVVk5vZGUgfSk7XG4gICAgICAgIHRlbXBFbWlzc2l2ZU5vZGUgPSB0ZW1wRW1pc3NpdmVOb2RlLm11bChtYXApO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmVtaXNzaXZlTm9kZSA9IHRlbXBFbWlzc2l2ZU5vZGU7XG4gICAgfVxuXG4gICAgLy8gdGhlIG9yZGluYXJ5IGxpZ2h0aW5nIHNldHVwXG4gICAgY29uc3QgcmV0ID0gc3VwZXIuc2V0dXBMaWdodGluZyhidWlsZGVyKTtcblxuICAgIC8vIHJldmVydCB0aGUgZW1pc3NpdmVOb2RlXG4gICAgaWYgKHRoaXMuZW1pc3NpdmVOb2RlID09PSB0ZW1wRW1pc3NpdmVOb2RlKSB7XG4gICAgICB0aGlzLmVtaXNzaXZlTm9kZSA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIHB1YmxpYyBzZXR1cE91dHB1dChcbiAgICBidWlsZGVyOiBOb2Rlcy5Ob2RlQnVpbGRlcixcbiAgICBvdXRwdXROb2RlOiBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+LFxuICApOiBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+IHtcbiAgICAvLyBtaXggb3Igc2V0IG91dGxpbmUgY29sb3JcbiAgICBpZiAodGhpcy5pc091dGxpbmUgJiYgdGhpcy5vdXRsaW5lV2lkdGhNb2RlICE9PSBNVG9vbk1hdGVyaWFsT3V0bGluZVdpZHRoTW9kZS5Ob25lKSB7XG4gICAgICBvdXRwdXROb2RlID0gTm9kZXMudmVjNChcbiAgICAgICAgTm9kZXMubWl4KHJlZk91dGxpbmVDb2xvckZhY3Rvciwgb3V0cHV0Tm9kZS54eXoubXVsKHJlZk91dGxpbmVDb2xvckZhY3RvciksIHJlZk91dGxpbmVMaWdodGluZ01peEZhY3RvciksXG4gICAgICAgIG91dHB1dE5vZGUudyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gdGhlIG9yZGluYXJ5IG91dHB1dCBzZXR1cFxuICAgIHJldHVybiBzdXBlci5zZXR1cE91dHB1dChidWlsZGVyLCBvdXRwdXROb2RlKSBhcyBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+O1xuICB9XG5cbiAgcHVibGljIHNldHVwUG9zaXRpb24oYnVpbGRlcjogTm9kZXMuTm9kZUJ1aWxkZXIpOiBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+IHtcbiAgICAvLyB3ZSBtdXN0IGFwcGx5IG91dGxpbmUgcG9zaXRpb24gb2Zmc2V0XG4gICAgLy8gdGhpcy5wb3NpdGlvbk5vZGUgd2lsbCBiZSB1c2VkIGluIHN1cGVyLnNldHVwUG9zaXRpb24oKSBzbyB3ZSB0ZW1wb3JhcmlseSByZXBsYWNlIGl0XG4gICAgY29uc3QgdGVtcFBvc2l0aW9uTm9kZTogTm9kZXMuU2hhZGVyTm9kZU9iamVjdDxOb2Rlcy5Ob2RlPiB8IG51bGwgPSB0aGlzLnBvc2l0aW9uTm9kZTtcblxuICAgIGlmICh0aGlzLmlzT3V0bGluZSAmJiB0aGlzLm91dGxpbmVXaWR0aE1vZGUgIT09IE1Ub29uTWF0ZXJpYWxPdXRsaW5lV2lkdGhNb2RlLk5vbmUpIHtcbiAgICAgIHRoaXMucG9zaXRpb25Ob2RlID8/PSBOb2Rlcy5wb3NpdGlvbkxvY2FsO1xuXG4gICAgICBjb25zdCBub3JtYWxMb2NhbCA9IE5vZGVzLm5vcm1hbExvY2FsLm5vcm1hbGl6ZSgpO1xuXG4gICAgICBsZXQgd2lkdGg6IE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT4gPSByZWZPdXRsaW5lV2lkdGhGYWN0b3I7XG5cbiAgICAgIGlmICh0aGlzLm91dGxpbmVXaWR0aE11bHRpcGx5VGV4dHVyZSAmJiB0aGlzLm91dGxpbmVXaWR0aE11bHRpcGx5VGV4dHVyZS5pc1RleHR1cmUgPT09IHRydWUpIHtcbiAgICAgICAgY29uc3QgbWFwID0gcmVmT3V0bGluZVdpZHRoTXVsdGlwbHlUZXh0dXJlLmNvbnRleHQoeyBnZXRVVjogKCkgPT4gdGhpcy5fYW5pbWF0ZWRVVk5vZGUgfSk7XG4gICAgICAgIHdpZHRoID0gd2lkdGgubXVsKG1hcCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHdvcmxkTm9ybWFsTGVuZ3RoID0gTm9kZXMubGVuZ3RoKE5vZGVzLm1vZGVsTm9ybWFsTWF0cml4Lm11bChub3JtYWxMb2NhbCkpO1xuICAgICAgY29uc3Qgb3V0bGluZU9mZnNldCA9IHdpZHRoLm11bCh3b3JsZE5vcm1hbExlbmd0aCkubXVsKG5vcm1hbExvY2FsKTtcblxuICAgICAgaWYgKHRoaXMub3V0bGluZVdpZHRoTW9kZSA9PT0gTVRvb25NYXRlcmlhbE91dGxpbmVXaWR0aE1vZGUuV29ybGRDb29yZGluYXRlcykge1xuICAgICAgICB0aGlzLnBvc2l0aW9uTm9kZSA9IHRoaXMucG9zaXRpb25Ob2RlLmFkZChvdXRsaW5lT2Zmc2V0KTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5vdXRsaW5lV2lkdGhNb2RlID09PSBNVG9vbk1hdGVyaWFsT3V0bGluZVdpZHRoTW9kZS5TY3JlZW5Db29yZGluYXRlcykge1xuICAgICAgICBjb25zdCBjbGlwU2NhbGUgPSBOb2Rlcy5jYW1lcmFQcm9qZWN0aW9uTWF0cml4LmVsZW1lbnQoMSkuZWxlbWVudCgxKTtcblxuICAgICAgICB0aGlzLnBvc2l0aW9uTm9kZSA9IHRoaXMucG9zaXRpb25Ob2RlLmFkZChvdXRsaW5lT2Zmc2V0LmRpdihjbGlwU2NhbGUpLm11bChOb2Rlcy5wb3NpdGlvblZpZXcuei5uZWdhdGUoKSkpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnBvc2l0aW9uTm9kZSA/Pz0gTm9kZXMucG9zaXRpb25Mb2NhbDtcbiAgICB9XG5cbiAgICAvLyB0aGUgb3JkaW5hcnkgcG9zaXRpb24gc2V0dXBcbiAgICBjb25zdCByZXQgPSBzdXBlci5zZXR1cFBvc2l0aW9uKGJ1aWxkZXIpIGFzIE5vZGVzLlNoYWRlck5vZGVPYmplY3Q8Tm9kZXMuTm9kZT47XG5cbiAgICAvLyBhbnRpIHotZmlnaHRpbmdcbiAgICAvLyBUT0RPOiBXZSBtaWdodCB3YW50IHRvIGFkZHJlc3MgdGhpcyB2aWEgZ2xQb2x5Z29uT2Zmc2V0IGluc3RlYWQ/XG4gICAgcmV0LnouYWRkKHJldC53Lm11bCgxZS02KSk7XG5cbiAgICAvLyByZXZlcnQgdGhlIHBvc2l0aW9uTm9kZVxuICAgIHRoaXMucG9zaXRpb25Ob2RlID0gdGVtcFBvc2l0aW9uTm9kZTtcblxuICAgIHJldHVybiByZXQ7XG4gIH1cblxuICBwdWJsaWMgY29weShzb3VyY2U6IE1Ub29uTm9kZU1hdGVyaWFsKTogdGhpcyB7XG4gICAgdGhpcy5jb2xvci5jb3B5KHNvdXJjZS5jb2xvcik7XG4gICAgdGhpcy5tYXAgPSBzb3VyY2UubWFwID8/IG51bGw7XG4gICAgdGhpcy5lbWlzc2l2ZS5jb3B5KHNvdXJjZS5lbWlzc2l2ZSk7XG4gICAgdGhpcy5lbWlzc2l2ZUludGVuc2l0eSA9IHNvdXJjZS5lbWlzc2l2ZUludGVuc2l0eTtcbiAgICB0aGlzLmVtaXNzaXZlTWFwID0gc291cmNlLmVtaXNzaXZlTWFwID8/IG51bGw7XG4gICAgdGhpcy5ub3JtYWxNYXAgPSBzb3VyY2Uubm9ybWFsTWFwID8/IG51bGw7XG4gICAgdGhpcy5ub3JtYWxTY2FsZS5jb3B5KHNvdXJjZS5ub3JtYWxTY2FsZSk7XG5cbiAgICB0aGlzLnNoYWRlQ29sb3JGYWN0b3IuY29weShzb3VyY2Uuc2hhZGVDb2xvckZhY3Rvcik7XG4gICAgdGhpcy5zaGFkZU11bHRpcGx5VGV4dHVyZSA9IHNvdXJjZS5zaGFkZU11bHRpcGx5VGV4dHVyZSA/PyBudWxsO1xuICAgIHRoaXMuc2hhZGluZ1NoaWZ0RmFjdG9yID0gc291cmNlLnNoYWRpbmdTaGlmdEZhY3RvcjtcbiAgICB0aGlzLnNoYWRpbmdTaGlmdFRleHR1cmUgPSBzb3VyY2Uuc2hhZGluZ1NoaWZ0VGV4dHVyZSA/PyBudWxsO1xuICAgIHRoaXMuc2hhZGluZ1NoaWZ0VGV4dHVyZVNjYWxlID0gc291cmNlLnNoYWRpbmdTaGlmdFRleHR1cmVTY2FsZTtcbiAgICB0aGlzLnNoYWRpbmdUb29ueUZhY3RvciA9IHNvdXJjZS5zaGFkaW5nVG9vbnlGYWN0b3I7XG4gICAgdGhpcy5yaW1MaWdodGluZ01peEZhY3RvciA9IHNvdXJjZS5yaW1MaWdodGluZ01peEZhY3RvcjtcbiAgICB0aGlzLnJpbU11bHRpcGx5VGV4dHVyZSA9IHNvdXJjZS5yaW1NdWx0aXBseVRleHR1cmUgPz8gbnVsbDtcbiAgICB0aGlzLm1hdGNhcEZhY3Rvci5jb3B5KHNvdXJjZS5tYXRjYXBGYWN0b3IpO1xuICAgIHRoaXMubWF0Y2FwVGV4dHVyZSA9IHNvdXJjZS5tYXRjYXBUZXh0dXJlID8/IG51bGw7XG4gICAgdGhpcy5wYXJhbWV0cmljUmltQ29sb3JGYWN0b3IuY29weShzb3VyY2UucGFyYW1ldHJpY1JpbUNvbG9yRmFjdG9yKTtcbiAgICB0aGlzLnBhcmFtZXRyaWNSaW1MaWZ0RmFjdG9yID0gc291cmNlLnBhcmFtZXRyaWNSaW1MaWZ0RmFjdG9yO1xuICAgIHRoaXMucGFyYW1ldHJpY1JpbUZyZXNuZWxQb3dlckZhY3RvciA9IHNvdXJjZS5wYXJhbWV0cmljUmltRnJlc25lbFBvd2VyRmFjdG9yO1xuICAgIHRoaXMub3V0bGluZVdpZHRoTW9kZSA9IHNvdXJjZS5vdXRsaW5lV2lkdGhNb2RlO1xuICAgIHRoaXMub3V0bGluZVdpZHRoTXVsdGlwbHlUZXh0dXJlID0gc291cmNlLm91dGxpbmVXaWR0aE11bHRpcGx5VGV4dHVyZSA/PyBudWxsO1xuICAgIHRoaXMub3V0bGluZVdpZHRoRmFjdG9yID0gc291cmNlLm91dGxpbmVXaWR0aEZhY3RvcjtcbiAgICB0aGlzLm91dGxpbmVDb2xvckZhY3Rvci5jb3B5KHNvdXJjZS5vdXRsaW5lQ29sb3JGYWN0b3IpO1xuICAgIHRoaXMub3V0bGluZUxpZ2h0aW5nTWl4RmFjdG9yID0gc291cmNlLm91dGxpbmVMaWdodGluZ01peEZhY3RvcjtcbiAgICB0aGlzLnV2QW5pbWF0aW9uU2Nyb2xsWFNwZWVkRmFjdG9yID0gc291cmNlLnV2QW5pbWF0aW9uU2Nyb2xsWFNwZWVkRmFjdG9yO1xuICAgIHRoaXMudXZBbmltYXRpb25TY3JvbGxZU3BlZWRGYWN0b3IgPSBzb3VyY2UudXZBbmltYXRpb25TY3JvbGxZU3BlZWRGYWN0b3I7XG4gICAgdGhpcy51dkFuaW1hdGlvblJvdGF0aW9uU3BlZWRGYWN0b3IgPSBzb3VyY2UudXZBbmltYXRpb25Sb3RhdGlvblNwZWVkRmFjdG9yO1xuICAgIHRoaXMudXZBbmltYXRpb25NYXNrVGV4dHVyZSA9IHNvdXJjZS51dkFuaW1hdGlvbk1hc2tUZXh0dXJlID8/IG51bGw7XG5cbiAgICB0aGlzLnNoYWRlQ29sb3JOb2RlID0gc291cmNlLnNoYWRlQ29sb3JOb2RlID8/IG51bGw7XG4gICAgdGhpcy5zaGFkaW5nU2hpZnROb2RlID0gc291cmNlLnNoYWRpbmdTaGlmdE5vZGUgPz8gbnVsbDtcbiAgICB0aGlzLnNoYWRpbmdUb29ueU5vZGUgPSBzb3VyY2Uuc2hhZGluZ1Rvb255Tm9kZSA/PyBudWxsO1xuICAgIHRoaXMucmltTGlnaHRpbmdNaXhOb2RlID0gc291cmNlLnJpbUxpZ2h0aW5nTWl4Tm9kZSA/PyBudWxsO1xuICAgIHRoaXMucmltTXVsdGlwbHlOb2RlID0gc291cmNlLnJpbU11bHRpcGx5Tm9kZSA/PyBudWxsO1xuICAgIHRoaXMubWF0Y2FwTm9kZSA9IHNvdXJjZS5tYXRjYXBOb2RlID8/IG51bGw7XG4gICAgdGhpcy5wYXJhbWV0cmljUmltQ29sb3JOb2RlID0gc291cmNlLnBhcmFtZXRyaWNSaW1Db2xvck5vZGUgPz8gbnVsbDtcbiAgICB0aGlzLnBhcmFtZXRyaWNSaW1MaWZ0Tm9kZSA9IHNvdXJjZS5wYXJhbWV0cmljUmltTGlmdE5vZGUgPz8gbnVsbDtcbiAgICB0aGlzLnBhcmFtZXRyaWNSaW1GcmVzbmVsUG93ZXJOb2RlID0gc291cmNlLnBhcmFtZXRyaWNSaW1GcmVzbmVsUG93ZXJOb2RlID8/IG51bGw7XG5cbiAgICB0aGlzLmlzT3V0bGluZSA9IHNvdXJjZS5pc091dGxpbmUgPz8gbnVsbDtcblxuICAgIHJldHVybiBzdXBlci5jb3B5KHNvdXJjZSk7XG4gIH1cblxuICBwdWJsaWMgdXBkYXRlKGRlbHRhOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnV2QW5pbWF0aW9uU2Nyb2xsWE9mZnNldCArPSBkZWx0YSAqIHRoaXMudXZBbmltYXRpb25TY3JvbGxYU3BlZWRGYWN0b3I7XG4gICAgdGhpcy51dkFuaW1hdGlvblNjcm9sbFlPZmZzZXQgKz0gZGVsdGEgKiB0aGlzLnV2QW5pbWF0aW9uU2Nyb2xsWVNwZWVkRmFjdG9yO1xuICAgIHRoaXMudXZBbmltYXRpb25Sb3RhdGlvblBoYXNlICs9IGRlbHRhICogdGhpcy51dkFuaW1hdGlvblJvdGF0aW9uU3BlZWRGYWN0b3I7XG4gIH1cblxuICBwcml2YXRlIF9zZXR1cFNoYWRlQ29sb3JOb2RlKCk6IE5vZGVzLlN3aXp6YWJsZSB7XG4gICAgaWYgKHRoaXMuc2hhZGVDb2xvck5vZGUgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIE5vZGVzLnZlYzModGhpcy5zaGFkZUNvbG9yTm9kZSk7XG4gICAgfVxuXG4gICAgbGV0IHNoYWRlQ29sb3JOb2RlOiBOb2Rlcy5TaGFkZXJOb2RlT2JqZWN0PE5vZGVzLk5vZGU+ID0gcmVmU2hhZGVDb2xvckZhY3RvcjtcblxuICAgIGlmICh0aGlzLnNoYWRlTXVsdGlwbHlUZXh0dXJlICYmIHRoaXMuc2hhZGVNdWx0aXBseVRleHR1cmUuaXNUZXh0dXJlID09PSB0cnVlKSB7XG4gICAgICBjb25zdCBtYXAgPSByZWZTaGFkZU11bHRpcGx5VGV4dHVyZS5jb250ZXh0KHsgZ2V0VVY6ICgpID0+IHRoaXMuX2FuaW1hdGVkVVZOb2RlIH0pO1xuICAgICAgc2hhZGVDb2xvck5vZGUgPSBzaGFkZUNvbG9yTm9kZS5tdWwobWFwKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2hhZGVDb2xvck5vZGU7XG4gIH1cblxuICBwcml2YXRlIF9zZXR1cFNoYWRpbmdTaGlmdE5vZGUoKTogTm9kZXMuTm9kZSB7XG4gICAgaWYgKHRoaXMuc2hhZGluZ1NoaWZ0Tm9kZSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gTm9kZXMuZmxvYXQodGhpcy5zaGFkaW5nU2hpZnROb2RlKTtcbiAgICB9XG5cbiAgICBsZXQgc2hhZGluZ1NoaWZ0Tm9kZTogTm9kZXMuU2hhZGVyTm9kZU9iamVjdDxOb2Rlcy5Ob2RlPiA9IHJlZlNoYWRpbmdTaGlmdEZhY3RvcjtcblxuICAgIGlmICh0aGlzLnNoYWRpbmdTaGlmdFRleHR1cmUgJiYgdGhpcy5zaGFkaW5nU2hpZnRUZXh0dXJlLmlzVGV4dHVyZSA9PT0gdHJ1ZSkge1xuICAgICAgY29uc3QgbWFwID0gcmVmU2hhZGVNdWx0aXBseVRleHR1cmUuY29udGV4dCh7IGdldFVWOiAoKSA9PiB0aGlzLl9hbmltYXRlZFVWTm9kZSB9KTtcbiAgICAgIHNoYWRpbmdTaGlmdE5vZGUgPSBzaGFkaW5nU2hpZnROb2RlLmFkZChtYXAubXVsKHJlZlNoYWRlTXVsdGlwbHlUZXh0dXJlU2NhbGUpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2hhZGluZ1NoaWZ0Tm9kZTtcbiAgfVxuXG4gIHByaXZhdGUgX3NldHVwU2hhZGluZ1Rvb255Tm9kZSgpOiBOb2Rlcy5Ob2RlIHtcbiAgICBpZiAodGhpcy5zaGFkaW5nVG9vbnlOb2RlICE9IG51bGwpIHtcbiAgICAgIHJldHVybiBOb2Rlcy5mbG9hdCh0aGlzLnNoYWRpbmdUb29ueU5vZGUpO1xuICAgIH1cblxuICAgIHJldHVybiByZWZTaGFkaW5nVG9vbnlGYWN0b3I7XG4gIH1cblxuICBwcml2YXRlIF9zZXR1cFJpbUxpZ2h0aW5nTWl4Tm9kZSgpOiBOb2Rlcy5Ob2RlIHtcbiAgICBpZiAodGhpcy5yaW1MaWdodGluZ01peE5vZGUgIT0gbnVsbCkge1xuICAgICAgcmV0dXJuIE5vZGVzLmZsb2F0KHRoaXMucmltTGlnaHRpbmdNaXhOb2RlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVmUmltTGlnaHRpbmdNaXhGYWN0b3I7XG4gIH1cblxuICBwcml2YXRlIF9zZXR1cFJpbU11bHRpcGx5Tm9kZSgpOiBOb2Rlcy5Td2l6emFibGUge1xuICAgIGlmICh0aGlzLnJpbU11bHRpcGx5Tm9kZSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gTm9kZXMudmVjMyh0aGlzLnJpbU11bHRpcGx5Tm9kZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucmltTXVsdGlwbHlUZXh0dXJlICYmIHRoaXMucmltTXVsdGlwbHlUZXh0dXJlLmlzVGV4dHVyZSA9PT0gdHJ1ZSkge1xuICAgICAgY29uc3QgbWFwID0gcmVmUmltTXVsdGlwbHlUZXh0dXJlLmNvbnRleHQoeyBnZXRVVjogKCkgPT4gdGhpcy5fYW5pbWF0ZWRVVk5vZGUgfSk7XG4gICAgICByZXR1cm4gbWFwO1xuICAgIH1cblxuICAgIHJldHVybiBOb2Rlcy52ZWMzKDEuMCk7XG4gIH1cblxuICBwcml2YXRlIF9zZXR1cE1hdGNhcE5vZGUoKTogTm9kZXMuU3dpenphYmxlIHtcbiAgICBpZiAodGhpcy5tYXRjYXBOb2RlICE9IG51bGwpIHtcbiAgICAgIHJldHVybiBOb2Rlcy52ZWMzKHRoaXMubWF0Y2FwTm9kZSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWF0Y2FwVGV4dHVyZSAmJiB0aGlzLm1hdGNhcFRleHR1cmUuaXNUZXh0dXJlID09PSB0cnVlKSB7XG4gICAgICBjb25zdCBtYXAgPSByZWZNYXRjYXBUZXh0dXJlLmNvbnRleHQoeyBnZXRVVjogKCkgPT4gTm9kZXMubWF0Y2FwVVYubXVsKDEuMCwgLTEuMCkuYWRkKDAuMCwgMS4wKSB9KTtcbiAgICAgIHJldHVybiBtYXAubXVsKHJlZk1hdGNhcEZhY3Rvcik7XG4gICAgfVxuXG4gICAgcmV0dXJuIE5vZGVzLnZlYzMoMC4wKTtcbiAgfVxuXG4gIHByaXZhdGUgX3NldHVwUGFyYW1ldHJpY1JpbU5vZGUoKTogTm9kZXMuU3dpenphYmxlIHtcbiAgICBjb25zdCBwYXJhbWV0cmljUmltQ29sb3IgPVxuICAgICAgdGhpcy5wYXJhbWV0cmljUmltQ29sb3JOb2RlICE9IG51bGwgPyBOb2Rlcy52ZWMzKHRoaXMucGFyYW1ldHJpY1JpbUNvbG9yTm9kZSkgOiByZWZQYXJhbWV0cmljUmltQ29sb3JGYWN0b3I7XG5cbiAgICBjb25zdCBwYXJhbWV0cmljUmltTGlmdCA9XG4gICAgICB0aGlzLnBhcmFtZXRyaWNSaW1MaWZ0Tm9kZSAhPSBudWxsID8gTm9kZXMuZmxvYXQodGhpcy5wYXJhbWV0cmljUmltTGlmdE5vZGUpIDogcmVmUGFyYW1ldHJpY1JpbUxpZnRGYWN0b3I7XG5cbiAgICBjb25zdCBwYXJhbWV0cmljUmltRnJlc25lbFBvd2VyID1cbiAgICAgIHRoaXMucGFyYW1ldHJpY1JpbUZyZXNuZWxQb3dlck5vZGUgIT0gbnVsbFxuICAgICAgICA/IE5vZGVzLmZsb2F0KHRoaXMucGFyYW1ldHJpY1JpbUZyZXNuZWxQb3dlck5vZGUpXG4gICAgICAgIDogcmVmUGFyYW1ldHJpY1JpbUZyZXNuZWxQb3dlckZhY3RvcjtcblxuICAgIHJldHVybiBtdG9vblBhcmFtZXRyaWNSaW0oe1xuICAgICAgcGFyYW1ldHJpY1JpbUxpZnQsXG4gICAgICBwYXJhbWV0cmljUmltRnJlc25lbFBvd2VyLFxuICAgICAgcGFyYW1ldHJpY1JpbUNvbG9yLFxuICAgIH0pO1xuICB9XG59XG4iLCAiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uICovXG5cbmV4cG9ydCBjb25zdCBNVG9vbk1hdGVyaWFsT3V0bGluZVdpZHRoTW9kZSA9IHtcbiAgTm9uZTogJ25vbmUnLFxuICBXb3JsZENvb3JkaW5hdGVzOiAnd29ybGRDb29yZGluYXRlcycsXG4gIFNjcmVlbkNvb3JkaW5hdGVzOiAnc2NyZWVuQ29vcmRpbmF0ZXMnLFxufSBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgTVRvb25NYXRlcmlhbE91dGxpbmVXaWR0aE1vZGUgPVxuICB0eXBlb2YgTVRvb25NYXRlcmlhbE91dGxpbmVXaWR0aE1vZGVba2V5b2YgdHlwZW9mIE1Ub29uTWF0ZXJpYWxPdXRsaW5lV2lkdGhNb2RlXTtcbiIsICJpbXBvcnQgKiBhcyBOb2RlcyBmcm9tICd0aHJlZS9hZGRvbnMvbm9kZXMvTm9kZXMuanMnO1xuXG5leHBvcnQgY29uc3QgbXRvb25QYXJhbWV0cmljUmltID0gTm9kZXMudHNsRm4oXG4gICh7XG4gICAgcGFyYW1ldHJpY1JpbUxpZnQsXG4gICAgcGFyYW1ldHJpY1JpbUZyZXNuZWxQb3dlcixcbiAgICBwYXJhbWV0cmljUmltQ29sb3IsXG4gIH06IHtcbiAgICBwYXJhbWV0cmljUmltTGlmdDogTm9kZXMuTm9kZVJlcHJlc2VudGF0aW9uO1xuICAgIHBhcmFtZXRyaWNSaW1GcmVzbmVsUG93ZXI6IE5vZGVzLk5vZGVSZXByZXNlbnRhdGlvbjtcbiAgICBwYXJhbWV0cmljUmltQ29sb3I6IE5vZGVzLk5vZGVSZXByZXNlbnRhdGlvbjtcbiAgfSkgPT4ge1xuICAgIGNvbnN0IHZpZXdEaXIgPSBOb2Rlcy5tb2RlbFZpZXdQb3NpdGlvbi5ub3JtYWxpemUoKTtcbiAgICBjb25zdCBkb3ROViA9IE5vZGVzLnRyYW5zZm9ybWVkTm9ybWFsVmlldy5kb3Qodmlld0Rpci5uZWdhdGUoKSk7XG5cbiAgICBjb25zdCByaW0gPSBOb2Rlcy5mbG9hdCgxLjApLnN1Yihkb3ROVikuYWRkKHBhcmFtZXRyaWNSaW1MaWZ0KS5jbGFtcCgpLnBvdyhwYXJhbWV0cmljUmltRnJlc25lbFBvd2VyKTtcblxuICAgIHJldHVybiByaW0ubXVsKHBhcmFtZXRyaWNSaW1Db2xvcik7XG4gIH0sXG4pO1xuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7OztBQUdBLFlBQVksV0FBVztBQ0h2QixZQUFZQSxZQUFXO0FDQXZCLFlBQVksV0FBVztBQ0F2QixZQUFZQSxZQUFXO0FDQXZCLFlBQVlBLFlBQVc7QUNBdkIsWUFBWUMsWUFBVztBQUN2QixZQUFZRCxZQUFXO0FFRHZCLFlBQVlBLFlBQVc7QVBLdkIsSUFBTSxnQkFBZ0IsU0FBZSxnQkFBVSxFQUFFO0FBQ2pELElBQUksZ0JBQWdCLEtBQUs7QUFDdkIsVUFBUTtJQUNOLHNFQUFzRSxhQUFhO0VBQ3JGO0FBQ0Y7QUVSTyxJQUFNLFdBQWlCLHdCQUFrQixTQUFTLE9BQU87QUFDekQsSUFBTSxTQUFlLHdCQUFrQixPQUFPLFNBQVM7QUFDdkQsSUFBTSxlQUFxQix3QkFBa0IsYUFBYSxTQUFTO0FBQ25FLElBQU0saUJBQXVCLHdCQUFrQixlQUFlLE1BQU07QUFDcEUsSUFBTSxjQUFvQix3QkFBa0IsWUFBWSxPQUFPO0FBQy9ELElBQU0sdUJBQTZCLHdCQUFrQixxQkFBcUIsT0FBTztBQUNqRixJQUFNLGlCQUF1Qix3QkFBa0IsZUFBZSxTQUFTO0FBRXZFLElBQU0sc0JBQTRCLHdCQUFrQixvQkFBb0IsT0FBTztBQUMvRSxJQUFNLHdCQUE4Qix3QkFBa0Isc0JBQXNCLE9BQU87QUFDbkYsSUFBTSwwQkFBZ0Msd0JBQWtCLHdCQUF3QixTQUFTO0FBQ3pGLElBQU0sK0JBQXFDLHdCQUFrQiw2QkFBNkIsT0FBTztBQUNqRyxJQUFNLHdCQUE4Qix3QkFBa0Isc0JBQXNCLE9BQU87QUFDbkYsSUFBTSwwQkFBZ0Msd0JBQWtCLHdCQUF3QixPQUFPO0FBQ3ZGLElBQU0sd0JBQThCLHdCQUFrQixzQkFBc0IsU0FBUztBQUNyRixJQUFNLGtCQUF3Qix3QkFBa0IsZ0JBQWdCLE9BQU87QUFDdkUsSUFBTSxtQkFBeUIsd0JBQWtCLGlCQUFpQixTQUFTO0FB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
|