@interncom/diplomatic 0.12.9 → 0.12.10
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/dist/cli/index.mjs +2 -2
- package/dist/cli/shared/crypto/enclave.d.ts +5 -5
- package/dist/web/identity/pairPackage.d.ts +2 -3
- package/dist/web/index.d.ts +5 -8
- package/dist/web/index.mjs +1 -1
- package/dist/web/passkey/prf-store.d.ts +0 -2
- package/dist/web/passkey/seed.d.ts +0 -2
- package/dist/web/shared/crypto/enclave.d.ts +5 -5
- package/dist/web/stores/idb/seed.d.ts +1 -3
- package/dist/web/worker.mjs +1 -1
- package/package.json +1 -1
package/dist/web/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function AV(Z){let X=Z.length,W=0,V=0;while(V<X){let l=Z.charCodeAt(V++);if((l&4294967168)===0){W++;continue}else if((l&4294965248)===0)W+=2;else{if(l>=55296&&l<=56319){if(V<X){let K=Z.charCodeAt(V);if((K&64512)===56320)++V,l=((l&1023)<<10)+(K&1023)+65536}}if((l&4294901760)===0)W+=3;else W+=4}}return W}function I0(Z,X,W){let V=Z.length,l=W,K=0;while(K<V){let G=Z.charCodeAt(K++);if((G&4294967168)===0){X[l++]=G;continue}else if((G&4294965248)===0)X[l++]=G>>6&31|192;else{if(G>=55296&&G<=56319){if(K<V){let m=Z.charCodeAt(K);if((m&64512)===56320)++K,G=((G&1023)<<10)+(m&1023)+65536}}if((G&4294901760)===0)X[l++]=G>>12&15|224,X[l++]=G>>6&63|128;else X[l++]=G>>18&7|240,X[l++]=G>>12&63|128,X[l++]=G>>6&63|128}X[l++]=G&63|128}}var L0=new TextEncoder,p0=50;function Q0(Z,X,W){L0.encodeInto(Z,X.subarray(W))}function oV(Z,X,W){if(Z.length>p0)Q0(Z,X,W);else I0(Z,X,W)}var y0=4096;function PW(Z,X,W){let V=X,l=V+W,K=[],G="";while(V<l){let m=Z[V++];if((m&128)===0)K.push(m);else if((m&224)===192){let R=Z[V++]&63;K.push((m&31)<<6|R)}else if((m&240)===224){let R=Z[V++]&63,J=Z[V++]&63;K.push((m&31)<<12|R<<6|J)}else if((m&248)===240){let R=Z[V++]&63,J=Z[V++]&63,C=Z[V++]&63,F=(m&7)<<18|R<<12|J<<6|C;if(F>65535)F-=65536,K.push(F>>>10&1023|55296),F=56320|F&1023;K.push(F)}else K.push(m);if(K.length>=y0)G+=String.fromCharCode(...K),K.length=0}if(K.length>0)G+=String.fromCharCode(...K);return G}var z0=new TextDecoder,x0=200;function N0(Z,X,W){let V=Z.subarray(X,X+W);return z0.decode(V)}function vV(Z,X,W){if(W>x0)return N0(Z,X,W);else return PW(Z,X,W)}class tZ{type;data;constructor(Z,X){this.type=Z,this.data=X}}class XZ extends Error{constructor(Z){super(Z);let X=Object.create(XZ.prototype);Object.setPrototypeOf(this,X),Object.defineProperty(this,"name",{configurable:!0,enumerable:!1,value:XZ.name})}}var eZ=4294967295;function $V(Z,X,W){let V=W/4294967296,l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function jX(Z,X,W){let V=Math.floor(W/4294967296),l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function wX(Z,X){let W=Z.getInt32(X),V=Z.getUint32(X+4);return W*4294967296+V}function fV(Z,X){let W=Z.getUint32(X),V=Z.getUint32(X+4);return W*4294967296+V}var M0=-1,g0=4294967295,S0=17179869183;function H0({sec:Z,nsec:X}){if(Z>=0&&X>=0&&Z<=S0)if(X===0&&Z<=g0){let W=new Uint8Array(4);return new DataView(W.buffer).setUint32(0,Z),W}else{let W=Z/4294967296,V=Z&4294967295,l=new Uint8Array(8),K=new DataView(l.buffer);return K.setUint32(0,X<<2|W&3),K.setUint32(4,V),l}else{let W=new Uint8Array(12),V=new DataView(W.buffer);return V.setUint32(0,X),jX(V,4,Z),W}}function h0(Z){let X=Z.getTime(),W=Math.floor(X/1000),V=(X-W*1000)*1e6,l=Math.floor(V/1e9);return{sec:W+l,nsec:V-l*1e9}}function P0(Z){if(Z instanceof Date){let X=h0(Z);return H0(X)}else return null}function U0(Z){let X=new DataView(Z.buffer,Z.byteOffset,Z.byteLength);switch(Z.byteLength){case 4:{let W=X.getUint32(0),V=0;return{sec:W,nsec:0}}case 8:{let W=X.getUint32(0),V=X.getUint32(4),l=(W&3)*4294967296+V,K=W>>>2;return{sec:l,nsec:K}}case 12:{let W=wX(X,4),V=X.getUint32(0);return{sec:W,nsec:V}}default:throw new XZ(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${Z.length}`)}}function i0(Z){let X=U0(Z);return new Date(X.sec*1000+X.nsec/1e6)}var qV={type:M0,encode:P0,decode:i0};class ZX{static defaultCodec=new ZX;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(qV)}register({type:Z,encode:X,decode:W}){if(Z>=0)this.encoders[Z]=X,this.decoders[Z]=W;else{let V=-1-Z;this.builtInEncoders[V]=X,this.builtInDecoders[V]=W}}tryToEncode(Z,X){for(let W=0;W<this.builtInEncoders.length;W++){let V=this.builtInEncoders[W];if(V!=null){let l=V(Z,X);if(l!=null){let K=-1-W;return new tZ(K,l)}}}for(let W=0;W<this.encoders.length;W++){let V=this.encoders[W];if(V!=null){let l=V(Z,X);if(l!=null)return new tZ(W,l)}}if(Z instanceof tZ)return Z;return null}decode(Z,X,W){let V=X<0?this.builtInDecoders[-1-X]:this.decoders[X];if(V)return V(Z,X,W);else return new tZ(X,Z)}}function u0(Z){return Z instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&Z instanceof SharedArrayBuffer}function cX(Z){if(Z instanceof Uint8Array)return Z;else if(ArrayBuffer.isView(Z))return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength);else if(u0(Z))return new Uint8Array(Z);else return Uint8Array.from(Z)}var O0=100,E0=2048;class DX{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??ZX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.maxDepth=Z?.maxDepth??O0,this.initialBufferSize=Z?.initialBufferSize??E0,this.sortKeys=Z?.sortKeys??!1,this.forceFloat32=Z?.forceFloat32??!1,this.ignoreUndefined=Z?.ignoreUndefined??!1,this.forceIntegerToFloat=Z?.forceIntegerToFloat??!1,this.pos=0,this.view=new DataView(new ArrayBuffer(this.initialBufferSize)),this.bytes=new Uint8Array(this.view.buffer)}clone(){return new DX({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,maxDepth:this.maxDepth,initialBufferSize:this.initialBufferSize,sortKeys:this.sortKeys,forceFloat32:this.forceFloat32,ignoreUndefined:this.ignoreUndefined,forceIntegerToFloat:this.forceIntegerToFloat})}reinitializeState(){this.pos=0}encodeSharedRef(Z){if(this.entered)return this.clone().encodeSharedRef(Z);try{return this.entered=!0,this.reinitializeState(),this.doEncode(Z,1),this.bytes.subarray(0,this.pos)}finally{this.entered=!1}}encode(Z){if(this.entered)return this.clone().encode(Z);try{return this.entered=!0,this.reinitializeState(),this.doEncode(Z,1),this.bytes.slice(0,this.pos)}finally{this.entered=!1}}doEncode(Z,X){if(X>this.maxDepth)throw Error(`Too deep objects in depth ${X}`);if(Z==null)this.encodeNil();else if(typeof Z==="boolean")this.encodeBoolean(Z);else if(typeof Z==="number")if(!this.forceIntegerToFloat)this.encodeNumber(Z);else this.encodeNumberAsFloat(Z);else if(typeof Z==="string")this.encodeString(Z);else if(this.useBigInt64&&typeof Z==="bigint")this.encodeBigInt64(Z);else this.encodeObject(Z,X)}ensureBufferSizeToWrite(Z){let X=this.pos+Z;if(this.view.byteLength<X)this.resizeBuffer(X*2)}resizeBuffer(Z){let X=new ArrayBuffer(Z),W=new Uint8Array(X),V=new DataView(X);W.set(this.bytes),this.view=V,this.bytes=W}encodeNil(){this.writeU8(192)}encodeBoolean(Z){if(Z===!1)this.writeU8(194);else this.writeU8(195)}encodeNumber(Z){if(!this.forceIntegerToFloat&&Number.isSafeInteger(Z))if(Z>=0)if(Z<128)this.writeU8(Z);else if(Z<256)this.writeU8(204),this.writeU8(Z);else if(Z<65536)this.writeU8(205),this.writeU16(Z);else if(Z<4294967296)this.writeU8(206),this.writeU32(Z);else if(!this.useBigInt64)this.writeU8(207),this.writeU64(Z);else this.encodeNumberAsFloat(Z);else if(Z>=-32)this.writeU8(224|Z+32);else if(Z>=-128)this.writeU8(208),this.writeI8(Z);else if(Z>=-32768)this.writeU8(209),this.writeI16(Z);else if(Z>=-2147483648)this.writeU8(210),this.writeI32(Z);else if(!this.useBigInt64)this.writeU8(211),this.writeI64(Z);else this.encodeNumberAsFloat(Z);else this.encodeNumberAsFloat(Z)}encodeNumberAsFloat(Z){if(this.forceFloat32)this.writeU8(202),this.writeF32(Z);else this.writeU8(203),this.writeF64(Z)}encodeBigInt64(Z){if(Z>=BigInt(0))this.writeU8(207),this.writeBigUint64(Z);else this.writeU8(211),this.writeBigInt64(Z)}writeStringHeader(Z){if(Z<32)this.writeU8(160+Z);else if(Z<256)this.writeU8(217),this.writeU8(Z);else if(Z<65536)this.writeU8(218),this.writeU16(Z);else if(Z<4294967296)this.writeU8(219),this.writeU32(Z);else throw Error(`Too long string: ${Z} bytes in UTF-8`)}encodeString(Z){let W=AV(Z);this.ensureBufferSizeToWrite(5+W),this.writeStringHeader(W),oV(Z,this.bytes,this.pos),this.pos+=W}encodeObject(Z,X){let W=this.extensionCodec.tryToEncode(Z,this.context);if(W!=null)this.encodeExtension(W);else if(Array.isArray(Z))this.encodeArray(Z,X);else if(ArrayBuffer.isView(Z))this.encodeBinary(Z);else if(typeof Z==="object")this.encodeMap(Z,X);else throw Error(`Unrecognized object: ${Object.prototype.toString.apply(Z)}`)}encodeBinary(Z){let X=Z.byteLength;if(X<256)this.writeU8(196),this.writeU8(X);else if(X<65536)this.writeU8(197),this.writeU16(X);else if(X<4294967296)this.writeU8(198),this.writeU32(X);else throw Error(`Too large binary: ${X}`);let W=cX(Z);this.writeU8a(W)}encodeArray(Z,X){let W=Z.length;if(W<16)this.writeU8(144+W);else if(W<65536)this.writeU8(220),this.writeU16(W);else if(W<4294967296)this.writeU8(221),this.writeU32(W);else throw Error(`Too large array: ${W}`);for(let V of Z)this.doEncode(V,X+1)}countWithoutUndefined(Z,X){let W=0;for(let V of X)if(Z[V]!==void 0)W++;return W}encodeMap(Z,X){let W=Object.keys(Z);if(this.sortKeys)W.sort();let V=this.ignoreUndefined?this.countWithoutUndefined(Z,W):W.length;if(V<16)this.writeU8(128+V);else if(V<65536)this.writeU8(222),this.writeU16(V);else if(V<4294967296)this.writeU8(223),this.writeU32(V);else throw Error(`Too large map object: ${V}`);for(let l of W){let K=Z[l];if(!(this.ignoreUndefined&&K===void 0))this.encodeString(l),this.doEncode(K,X+1)}}encodeExtension(Z){if(typeof Z.data==="function"){let W=Z.data(this.pos+6),V=W.length;if(V>=4294967296)throw Error(`Too large extension object: ${V}`);this.writeU8(201),this.writeU32(V),this.writeI8(Z.type),this.writeU8a(W);return}let X=Z.data.length;if(X===1)this.writeU8(212);else if(X===2)this.writeU8(213);else if(X===4)this.writeU8(214);else if(X===8)this.writeU8(215);else if(X===16)this.writeU8(216);else if(X<256)this.writeU8(199),this.writeU8(X);else if(X<65536)this.writeU8(200),this.writeU16(X);else if(X<4294967296)this.writeU8(201),this.writeU32(X);else throw Error(`Too large extension object: ${X}`);this.writeI8(Z.type),this.writeU8a(Z.data)}writeU8(Z){this.ensureBufferSizeToWrite(1),this.view.setUint8(this.pos,Z),this.pos++}writeU8a(Z){let X=Z.length;this.ensureBufferSizeToWrite(X),this.bytes.set(Z,this.pos),this.pos+=X}writeI8(Z){this.ensureBufferSizeToWrite(1),this.view.setInt8(this.pos,Z),this.pos++}writeU16(Z){this.ensureBufferSizeToWrite(2),this.view.setUint16(this.pos,Z),this.pos+=2}writeI16(Z){this.ensureBufferSizeToWrite(2),this.view.setInt16(this.pos,Z),this.pos+=2}writeU32(Z){this.ensureBufferSizeToWrite(4),this.view.setUint32(this.pos,Z),this.pos+=4}writeI32(Z){this.ensureBufferSizeToWrite(4),this.view.setInt32(this.pos,Z),this.pos+=4}writeF32(Z){this.ensureBufferSizeToWrite(4),this.view.setFloat32(this.pos,Z),this.pos+=4}writeF64(Z){this.ensureBufferSizeToWrite(8),this.view.setFloat64(this.pos,Z),this.pos+=8}writeU64(Z){this.ensureBufferSizeToWrite(8),$V(this.view,this.pos,Z),this.pos+=8}writeI64(Z){this.ensureBufferSizeToWrite(8),jX(this.view,this.pos,Z),this.pos+=8}writeBigUint64(Z){this.ensureBufferSizeToWrite(8),this.view.setBigUint64(this.pos,Z),this.pos+=8}writeBigInt64(Z){this.ensureBufferSizeToWrite(8),this.view.setBigInt64(this.pos,Z),this.pos+=8}}function wZ(Z,X){return new DX(X).encodeSharedRef(Z)}function AX(Z){return`${Z<0?"-":""}0x${Math.abs(Z).toString(16).padStart(2,"0")}`}var B0=16,j0=16;class UW{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(Z=B0,X=j0){this.maxKeyLength=Z,this.maxLengthPerKey=X,this.caches=[];for(let W=0;W<this.maxKeyLength;W++)this.caches.push([])}canBeCached(Z){return Z>0&&Z<=this.maxKeyLength}find(Z,X,W){let V=this.caches[W-1];Z:for(let l of V){let K=l.bytes;for(let G=0;G<W;G++)if(K[G]!==Z[X+G])continue Z;return l.str}return null}store(Z,X){let W=this.caches[Z.length-1],V={bytes:Z,str:X};if(W.length>=this.maxLengthPerKey)W[Math.random()*W.length|0]=V;else W.push(V)}decode(Z,X,W){let V=this.find(Z,X,W);if(V!=null)return this.hit++,V;this.miss++;let l=PW(Z,X,W),K=Uint8Array.prototype.slice.call(Z,X,X+W);return this.store(K,l),l}}var iW="array",IX="map_key",_V="map_value",w0=(Z)=>{if(typeof Z==="string"||typeof Z==="number")return Z;throw new XZ("The type of key must be string or number but "+typeof Z)};class aV{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(Z){let X=this.getUninitializedStateFromPool();X.type=iW,X.position=0,X.size=Z,X.array=Array(Z)}pushMapState(Z){let X=this.getUninitializedStateFromPool();X.type=IX,X.readCount=0,X.size=Z,X.map={}}getUninitializedStateFromPool(){if(this.stackHeadPosition++,this.stackHeadPosition===this.stack.length){let Z={type:void 0,size:0,array:void 0,position:0,readCount:0,map:void 0,key:null};this.stack.push(Z)}return this.stack[this.stackHeadPosition]}release(Z){if(this.stack[this.stackHeadPosition]!==Z)throw Error("Invalid stack state. Released state is not on top of the stack.");if(Z.type===iW){let W=Z;W.size=0,W.array=void 0,W.position=0,W.type=void 0}if(Z.type===IX||Z.type===_V){let W=Z;W.size=0,W.map=void 0,W.readCount=0,W.type=void 0}this.stackHeadPosition--}reset(){this.stack.length=0,this.stackHeadPosition=-1}}var kX=-1,uW=new DataView(new ArrayBuffer(0)),D0=new Uint8Array(uW.buffer);try{uW.getInt8(0)}catch(Z){if(!(Z instanceof RangeError))throw Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access")}var nV=RangeError("Insufficient data"),A0=new UW;class oX{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=uW;bytes=D0;headByte=kX;stack=new aV;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??ZX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.rawStrings=Z?.rawStrings??!1,this.maxStrLength=Z?.maxStrLength??eZ,this.maxBinLength=Z?.maxBinLength??eZ,this.maxArrayLength=Z?.maxArrayLength??eZ,this.maxMapLength=Z?.maxMapLength??eZ,this.maxExtLength=Z?.maxExtLength??eZ,this.keyDecoder=Z?.keyDecoder!==void 0?Z.keyDecoder:A0,this.mapKeyConverter=Z?.mapKeyConverter??w0}clone(){return new oX({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,rawStrings:this.rawStrings,maxStrLength:this.maxStrLength,maxBinLength:this.maxBinLength,maxArrayLength:this.maxArrayLength,maxMapLength:this.maxMapLength,maxExtLength:this.maxExtLength,keyDecoder:this.keyDecoder})}reinitializeState(){this.totalPos=0,this.headByte=kX,this.stack.reset()}setBuffer(Z){let X=cX(Z);this.bytes=X,this.view=new DataView(X.buffer,X.byteOffset,X.byteLength),this.pos=0}appendBuffer(Z){if(this.headByte===kX&&!this.hasRemaining(1))this.setBuffer(Z);else{let X=this.bytes.subarray(this.pos),W=cX(Z),V=new Uint8Array(X.length+W.length);V.set(X),V.set(W,X.length),this.setBuffer(V)}}hasRemaining(Z){return this.view.byteLength-this.pos>=Z}createExtraByteError(Z){let{view:X,pos:W}=this;return RangeError(`Extra ${X.byteLength-W} of ${X.byteLength} byte(s) found at buffer[${Z}]`)}decode(Z){if(this.entered)return this.clone().decode(Z);try{this.entered=!0,this.reinitializeState(),this.setBuffer(Z);let X=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return X}finally{this.entered=!1}}*decodeMulti(Z){if(this.entered){yield*this.clone().decodeMulti(Z);return}try{this.entered=!0,this.reinitializeState(),this.setBuffer(Z);while(this.hasRemaining(1))yield this.doDecodeSync()}finally{this.entered=!1}}async decodeAsync(Z){if(this.entered)return this.clone().decodeAsync(Z);try{this.entered=!0;let X=!1,W;for await(let G of Z){if(X)throw this.entered=!1,this.createExtraByteError(this.totalPos);this.appendBuffer(G);try{W=this.doDecodeSync(),X=!0}catch(m){if(!(m instanceof RangeError))throw m}this.totalPos+=this.pos}if(X){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return W}let{headByte:V,pos:l,totalPos:K}=this;throw RangeError(`Insufficient data in parsing ${AX(V)} at ${K} (${l} in the current buffer)`)}finally{this.entered=!1}}decodeArrayStream(Z){return this.decodeMultiAsync(Z,!0)}decodeStream(Z){return this.decodeMultiAsync(Z,!1)}async*decodeMultiAsync(Z,X){if(this.entered){yield*this.clone().decodeMultiAsync(Z,X);return}try{this.entered=!0;let W=X,V=-1;for await(let l of Z){if(X&&V===0)throw this.createExtraByteError(this.totalPos);if(this.appendBuffer(l),W)V=this.readArraySize(),W=!1,this.complete();try{while(!0)if(yield this.doDecodeSync(),--V===0)break}catch(K){if(!(K instanceof RangeError))throw K}this.totalPos+=this.pos}}finally{this.entered=!1}}doDecodeSync(){Z:while(!0){let Z=this.readHeadByte(),X;if(Z>=224)X=Z-256;else if(Z<192)if(Z<128)X=Z;else if(Z<144){let V=Z-128;if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z<160){let V=Z-144;if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else{let V=Z-160;X=this.decodeString(V,0)}else if(Z===192)X=null;else if(Z===194)X=!1;else if(Z===195)X=!0;else if(Z===202)X=this.readF32();else if(Z===203)X=this.readF64();else if(Z===204)X=this.readU8();else if(Z===205)X=this.readU16();else if(Z===206)X=this.readU32();else if(Z===207)if(this.useBigInt64)X=this.readU64AsBigInt();else X=this.readU64();else if(Z===208)X=this.readI8();else if(Z===209)X=this.readI16();else if(Z===210)X=this.readI32();else if(Z===211)if(this.useBigInt64)X=this.readI64AsBigInt();else X=this.readI64();else if(Z===217){let V=this.lookU8();X=this.decodeString(V,1)}else if(Z===218){let V=this.lookU16();X=this.decodeString(V,2)}else if(Z===219){let V=this.lookU32();X=this.decodeString(V,4)}else if(Z===220){let V=this.readU16();if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else if(Z===221){let V=this.readU32();if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else if(Z===222){let V=this.readU16();if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z===223){let V=this.readU32();if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z===196){let V=this.lookU8();X=this.decodeBinary(V,1)}else if(Z===197){let V=this.lookU16();X=this.decodeBinary(V,2)}else if(Z===198){let V=this.lookU32();X=this.decodeBinary(V,4)}else if(Z===212)X=this.decodeExtension(1,0);else if(Z===213)X=this.decodeExtension(2,0);else if(Z===214)X=this.decodeExtension(4,0);else if(Z===215)X=this.decodeExtension(8,0);else if(Z===216)X=this.decodeExtension(16,0);else if(Z===199){let V=this.lookU8();X=this.decodeExtension(V,1)}else if(Z===200){let V=this.lookU16();X=this.decodeExtension(V,2)}else if(Z===201){let V=this.lookU32();X=this.decodeExtension(V,4)}else throw new XZ(`Unrecognized type byte: ${AX(Z)}`);this.complete();let W=this.stack;while(W.length>0){let V=W.top();if(V.type===iW)if(V.array[V.position]=X,V.position++,V.position===V.size)X=V.array,W.release(V);else continue Z;else if(V.type===IX){if(X==="__proto__")throw new XZ("The key __proto__ is not allowed");V.key=this.mapKeyConverter(X),V.type=_V;continue Z}else if(V.map[V.key]=X,V.readCount++,V.readCount===V.size)X=V.map,W.release(V);else{V.key=null,V.type=IX;continue Z}}return X}}readHeadByte(){if(this.headByte===kX)this.headByte=this.readU8();return this.headByte}complete(){this.headByte=kX}readArraySize(){let Z=this.readHeadByte();switch(Z){case 220:return this.readU16();case 221:return this.readU32();default:if(Z<160)return Z-144;else throw new XZ(`Unrecognized array type byte: ${AX(Z)}`)}}pushMapState(Z){if(Z>this.maxMapLength)throw new XZ(`Max length exceeded: map length (${Z}) > maxMapLengthLength (${this.maxMapLength})`);this.stack.pushMapState(Z)}pushArrayState(Z){if(Z>this.maxArrayLength)throw new XZ(`Max length exceeded: array length (${Z}) > maxArrayLength (${this.maxArrayLength})`);this.stack.pushArrayState(Z)}decodeString(Z,X){if(!this.rawStrings||this.stateIsMapKey())return this.decodeUtf8String(Z,X);return this.decodeBinary(Z,X)}decodeUtf8String(Z,X){if(Z>this.maxStrLength)throw new XZ(`Max length exceeded: UTF-8 byte length (${Z}) > maxStrLength (${this.maxStrLength})`);if(this.bytes.byteLength<this.pos+X+Z)throw nV;let W=this.pos+X,V;if(this.stateIsMapKey()&&this.keyDecoder?.canBeCached(Z))V=this.keyDecoder.decode(this.bytes,W,Z);else V=vV(this.bytes,W,Z);return this.pos+=X+Z,V}stateIsMapKey(){if(this.stack.length>0)return this.stack.top().type===IX;return!1}decodeBinary(Z,X){if(Z>this.maxBinLength)throw new XZ(`Max length exceeded: bin length (${Z}) > maxBinLength (${this.maxBinLength})`);if(!this.hasRemaining(Z+X))throw nV;let W=this.pos+X,V=this.bytes.subarray(W,W+Z);return this.pos+=X+Z,V}decodeExtension(Z,X){if(Z>this.maxExtLength)throw new XZ(`Max length exceeded: ext length (${Z}) > maxExtLength (${this.maxExtLength})`);let W=this.view.getInt8(this.pos+X),V=this.decodeBinary(Z,X+1);return this.extensionCodec.decode(V,W,this.context)}lookU8(){return this.view.getUint8(this.pos)}lookU16(){return this.view.getUint16(this.pos)}lookU32(){return this.view.getUint32(this.pos)}readU8(){let Z=this.view.getUint8(this.pos);return this.pos++,Z}readI8(){let Z=this.view.getInt8(this.pos);return this.pos++,Z}readU16(){let Z=this.view.getUint16(this.pos);return this.pos+=2,Z}readI16(){let Z=this.view.getInt16(this.pos);return this.pos+=2,Z}readU32(){let Z=this.view.getUint32(this.pos);return this.pos+=4,Z}readI32(){let Z=this.view.getInt32(this.pos);return this.pos+=4,Z}readU64(){let Z=fV(this.view,this.pos);return this.pos+=8,Z}readI64(){let Z=wX(this.view,this.pos);return this.pos+=8,Z}readU64AsBigInt(){let Z=this.view.getBigUint64(this.pos);return this.pos+=8,Z}readI64AsBigInt(){let Z=this.view.getBigInt64(this.pos);return this.pos+=8,Z}readF32(){let Z=this.view.getFloat32(this.pos);return this.pos+=4,Z}readF64(){let Z=this.view.getFloat64(this.pos);return this.pos+=8,Z}}function OW(Z,X){return new oX(X).decode(Z)}class SZ{listeners=new Map;addEventListener(Z,X){let W=this.listeners.get(Z);if(!W)W=new Set,this.listeners.set(Z,W);return W.add(X),()=>{this.removeEventListener(Z,X)}}removeEventListener(Z,X){let W=this.listeners.get(Z);if(W){if(W.delete(X),W.size===0)this.listeners.delete(Z)}}emit(Z,X){let W=this.listeners.get(Z);if(W){let V=Array.from(W);for(let l of V)l(X)}}emitAll(Z){let X=Array.from(this.listeners.keys());for(let W of X)this.emit(W,Z)}}class bZ{getter;static eventName="update";emitter;constructor(Z){this.getter=Z;this.emitter=new SZ}get=()=>this.getter();async emit(){let Z=await this.getter();queueMicrotask(()=>this.emitter.emit(bZ.eventName,Z))}listen(Z){return this.emitter.addEventListener(bZ.eventName,Z),()=>{this.emitter.removeEventListener(bZ.eventName,Z)}}}var HZ=64;var rV=32,hZ=8;var vX=32;var sV=30000,tV=512,x;((y)=>{y[y.Success=0]="Success";y[y.InvalidSignature=3]="InvalidSignature";y[y.ClockOutOfSync=4]="ClockOutOfSync";y[y.UserNotRegistered=5]="UserNotRegistered";y[y.ServerMisconfigured=6]="ServerMisconfigured";y[y.MissingBody=7]="MissingBody";y[y.ExtraBodyContent=8]="ExtraBodyContent";y[y.MissingParam=9]="MissingParam";y[y.InvalidParam=10]="InvalidParam";y[y.InvalidRequest=11]="InvalidRequest";y[y.InternalError=12]="InternalError";y[y.NotFound=13]="NotFound";y[y.InvalidMessage=14]="InvalidMessage";y[y.NoChange=15]="NoChange";y[y.DatabaseClosed=16]="DatabaseClosed";y[y.StorageError=17]="StorageError";y[y.DatabaseError=18]="DatabaseError";y[y.HashMismatch=19]="HashMismatch";y[y.DecryptionError=20]="DecryptionError";y[y.NotImplemented=21]="NotImplemented";y[y.MissingSeed=22]="MissingSeed";y[y.OutOfBounds=23]="OutOfBounds";y[y.HostError=24]="HostError";y[y.CommunicationError=25]="CommunicationError";y[y.VarLimitExceeded=26]="VarLimitExceeded";y[y.InvalidResponse=27]="InvalidResponse";y[y.ConnectionClosed=28]="ConnectionClosed"})(x||={});function d(Z){return[Z,0]}function Y(Z){return[void 0,Z]}function o0(Z){if(Z<0)console.info("N",Z),console.trace();if(typeof Z!=="bigint")Z=BigInt(Z);if(Z<0n)return Y(10);let X=[];while(Z>0n){let W=Number(Z&0x7fn);if(Z>>=7n,Z>0n)X.push(W|128);else X.push(W)}if(X.length===0)return d(new Uint8Array([0]));if(X.length>8)return Y(26);return d(new Uint8Array(X))}function v0(Z,X=0){let W=0n,V=0,l=X;while(!0){if(l>=Z.length)return Y(14);let K=Z[l++];if(K===void 0)return Y(14);if(W|=BigInt(K&127)<<BigInt(V),(K&128)===0){if(l-X>8)return Y(26);return d({value:W>0x1fffffffffffffn?W:Number(W),bytesRead:l-X})}if(V+=7,V>=56)return Y(26)}}class P{data;pos=0;constructor(Z){this.data=Z}static async fromResponse(Z){let X=await Z.arrayBuffer(),W=new Uint8Array(X);return new P(W)}readBigInt(){if(this.pos+8>this.data.length)return Y(7);let Z=new DataView(this.data.buffer,this.data.byteOffset+this.pos).getBigUint64(0,!1);return this.pos+=8,d(Z)}readDate(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return d(new Date(Z))}readVarInt(){let[Z,X]=v0(this.data,this.pos);if(X!==0)return Y(X);this.pos+=Z.bytesRead;let W=Z.value;return d(typeof W==="bigint"?Number(W):W)}readVarString(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);let l=new TextDecoder().decode(W);return d(l)}readBytes(Z){if(Z<0)return Y(10);if(this.pos+Z>this.data.length)return Y(23);let X=this.data.slice(this.pos,this.pos+Z);return this.pos+=Z,d(X)}readVarBytes(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return this.readBytes(Z)}readStruct(Z){return Z.decode(this)}readStructs(Z){let X=[];while(!this.done()){let[W,V]=this.readStruct(Z);if(V!==0)return Y(V);X.push(W)}return d(X)}readBytesSeq(Z){let X=[];while(!this.done()){let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);X.push(W)}return d(X)}done(){return this.pos>=this.data.length}consumed(){return this.pos}}class U{parts=[];writeBigInt(Z){let X=new Uint8Array(8);new DataView(X.buffer).setBigUint64(0,Z,!1),this.parts.push(X)}writeDate(Z){let X=Z.getTime();return this.writeVarInt(X)}writeVarInt(Z){let[X,W]=o0(Z);if(W!==0)return W;return this.parts.push(X),0}writeVarString(Z){let X=new TextEncoder().encode(Z),W=this.writeVarInt(X.length);if(W!==0)return W;return this.writeBytes(X),0}prependBytes(Z){this.parts.unshift(Z.slice())}writeBytes(Z){this.parts.push(Z.slice())}writeVarBytes(Z){let X=this.writeVarInt(Z.length);if(X!==0)return X;return this.writeBytes(Z),0}writeStruct(Z,X){return Z.encode(this,X)}writeStructs(Z,X){for(let W of X){let V=this.writeStruct(Z,W);if(V!==0)return V}return 0}writeBytesSeq(Z){for(let X of Z)this.writeBytes(X)}result(){let Z=this.parts.reduce((V,l)=>V+l.length,0),X=new Uint8Array(Z),W=0;for(let V of this.parts)X.set(V,W),W+=V.length;return X}*scan(){for(let Z of this.parts)yield Z}}async function EW(Z,X){let W=new U,V=W.writeDate(X);if(V!==0)return Y(V);let l=W.result(),K=await Z.sign(l);return d({pubKey:Z.publicKey,sig:K,timestamp:X})}async function PZ(Z,X,W){let V=W.now().getTime(),l=Z.timestamp.getTime();if(Math.abs(V-l)>sV)return 4;let G=new U;G.writeDate(Z.timestamp);let m=G.result();if(!await X.checkSigEd25519(Z.sig,m,Z.pubKey))return 3;return 0}var r={encode(Z,X){let W=Z.writeVarBytes(X.id);if(W!==0)return W;let V=Z.writeDate(X.ts);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let[V,l]=Z.readDate();if(l!==0)return Y(l);return d({id:X,ts:V})}};function XX(Z){let X=new U,W=X.writeStruct(r,Z);if(W!==0)return Y(W);let V=X.result();return d(V)}async function $0(Z){return XX({id:Z,ts:new Date(0)})}var RZ={encode(Z,X){let W=Z.writeVarBytes(X.eid);if(W!==0)return W;let V=Z.writeVarInt(X.off);if(V!==0)return V;let l=Z.writeVarInt(X.ctr);if(l!==0)return l;let K=Z.writeVarInt(X.len);if(K!==0)return K;if(X.hsh)Z.writeBytes(X.hsh);return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let V=new P(X),[,l]=r.decode(V);if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let[m,R]=Z.readVarInt();if(R!==0)return Y(R);let[J,C]=Z.readVarInt();if(C!==0)return Y(C);let F;if(J>0){let[b,T]=Z.readBytes(vX);if(T!==0)return Y(T);F=b}return d({eid:X,off:K,ctr:m,len:J,hsh:F})}};function mZ(Z){return Array.from(Z).map((W)=>W.toString(16).padStart(2,"0")).join("")}function WX(Z){if(Z.length%2!==0)throw Error("Invalid hex string");let X=new Uint8Array(Z.length/2);for(let W=0;W<Z.length;W+=2)X[W/2]=Number.parseInt(Z.substr(W,2),16);return X}function n(Z,X){if(Z===X)return!0;if(Z.byteLength!==X.byteLength)return!1;return Z.every((W,V)=>W===X[V])}var S;if(typeof Uint8Array.prototype.toBase64==="function")S=(Z)=>Z.toBase64();else S=(Z)=>btoa(String.fromCharCode(...Z));var e;if(typeof Uint8Array.fromBase64==="function")e=(Z)=>Uint8Array.fromBase64(Z);else e=(Z)=>Uint8Array.from(atob(Z),(X)=>X.charCodeAt(0));function BW(Z){return S(Z).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function jW(Z){let X=Z.length%4===0?"":"=".repeat(4-Z.length%4),W=Z.replace(/-/g,"+").replace(/_/g,"/")+X;return e(W)}function LX(Z,X){let W=new Uint8Array(Z.length+X.length);return W.set(Z,0),W.set(X,Z.length),W}function eV(Z,X,W){return W.checkSigEd25519(Z.sig,Z.headCph,X)}async function Zl(Z,X,W,V){let l;if(Z.bod&&Z.len>0)l=await W.blake3(Z.bod);let K=new U,G=RZ.encode(K,{...Z,hsh:l});if(G!==0)return Y(G);let m=K.result(),R=await X.kdmFor(m),J=V.deriveCipher(R,"encrypt"),C=await J.encrypt(m),F=Z.bod?await J.encrypt(Z.bod):new Uint8Array(0),b=await X.sign(C);return d({sig:b,kdm:R,headCph:C,bodyCph:F})}async function wW(Z,X,W,V,l){let K=new P(Z),[G,m]=RZ.decode(K);if(m!==0)return Y(14);let R;try{R=X&&X.length>0?await W.decrypt(X):void 0}catch{return Y(20)}let J=G.hsh&&R===void 0,C=G.hsh===void 0&&R!==void 0;if(J||C)return Y(19);if(G.hsh&&R){let b=await V.blake3(R);if(!n(b,G.hsh))return Y(19)}let F=l??await V.blake3(Z);return d({msgHead:G,bod:R,headHash:F})}class LZ{now(){return new Date}}function Xl(Z,X,W,V){let l=X.getTime()-Z.getTime(),K=W.getTime()-V.getTime();return(l+K)/2}var pX={encode(Z,X){if(Z.writeVarInt(X.quota),X.quota>0){if(X.usage===void 0)return 9;Z.writeVarInt(X.usage)}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let V;if(X>0){let[l,K]=Z.readVarInt();if(K!==0)return Y(K);V=l}return d({quota:X,usage:V})}};var DW={encode(Z,X){Z.writeBytes(new Uint8Array([X.status]));let W=Z.writeDate(X.timeRcvd);if(W!==0)return W;let V=Z.writeDate(X.timeSent);if(V!==0)return V;let l=Z.writeVarInt(X.subscription.term);if(l!==0)return l;let K=Z.writeVarInt(X.subscription.elapsed);if(K!==0)return K;let G=Z.writeStruct(pX,X.subscription.stat);if(G!==0)return G;let m=Z.writeStruct(pX,X.subscription.dyn);if(m!==0)return m;return 0},decode(Z){let[X,W]=Z.readBytes(1);if(W!==0)return Y(W);let V=X[0],[l,K]=Z.readDate();if(K!==0)return Y(K);let[G,m]=Z.readDate();if(m!==0)return Y(m);let[R,J]=Z.readVarInt();if(J!==0)return Y(J);let[C,F]=Z.readVarInt();if(F!==0)return Y(F);let[b,T]=Z.readStruct(pX);if(T!==0)return Y(T);let[c,k]=Z.readStruct(pX);if(k!==0)return Y(k);return d({status:V,timeRcvd:l,timeSent:G,subscription:{term:R,elapsed:C,stat:b,dyn:c}})}};var AW={encode(Z,X){let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarInt(X.seq);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let[V,l]=Z.readVarInt();if(l!==0)return Y(l);return d({headCph:X,seq:V})}};var YZ={encode(Z,X){Z.writeBytes(X.pubKey),Z.writeBytes(X.sig);let W=Z.writeDate(X.timestamp);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readBytes(rV);if(W!==0)return Y(W);let[V,l]=Z.readBytes(HZ);if(l!==0)return Y(l);let[K,G]=Z.readDate();if(G!==0)return Y(G);return d({pubKey:X,sig:V,timestamp:K})}};var Wl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(YZ,W);if(K!==0)return K;for(let G of V)l.writeVarInt(G);return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(YZ);if(m!==0)return m;let R=await PZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);if(F!==0)return F;if(!C)return 5;let[b,T]=X.readVarInt();if(T!==0)return T;if(!X.done())return 8;let[c,k]=await K.listHeads(J,b);if(k!==0)return k;return W.writeStructs(AW,c)},decodeResp(Z){return Z.readStructs(AW)}};var oW={encode(Z,X){Z.writeVarInt(X.seq);let W=Z.writeVarBytes(X.bodyCph);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);return d({seq:X,bodyCph:V})}};var Vl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(YZ,W);if(K!==0)return K;for(let G of V){let m=l.writeVarInt(G);if(m!==0)return m}return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(YZ);if(m!==0)return m;let R=await PZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);if(F!==0)return F;if(!C)return 5;let b=[];while(!X.done()){let[k,I]=X.readVarInt();if(I!==0)return I;b.push(k)}console.info(`PULL: ${b.length} bags`);let[T,c]=await K.getBodies(J,b);if(c!==0)return c;if(!T)return 17;for(let{seq:k,bodyCph:I}of T){let Q={seq:k,bodyCph:I},p=W.writeStruct(oW,Q);if(p!==0)return p}return 0},decodeResp(Z){return Z.readStructs(oW)}};var vW={encode(Z,X){Z.writeBytes(X.sig),Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarBytes(X.bodyCph);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readBytes(HZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(hZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);let[m,R]=Z.readVarBytes();if(R!==0)return Y(R);return d({sig:X,kdm:V,headCph:K,bodyCph:m})}};var $X={encode(Z,X){let W=Z.writeVarInt(X.seq);if(W!==0)return W;let V=Z.writeVarBytes(X.headCph);if(V!==0)return V;let l=X.bodyCph?X.bodyCph.length:0,K=Z.writeVarInt(l);if(K!==0)return K;if(l>0){if(!X.bodyCph)return 10;Z.writeBytes(X.bodyCph)}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let m;if(K>0){let[R,J]=Z.readBytes(K);if(J!==0)return Y(J);m=R}return d({seq:X,headCph:V,bodyCph:m})}};var fX={encode(Z,X){Z.writeBytes(X.sig),Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readBytes(HZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(hZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return d({sig:X,kdm:V,headCph:K})}};var qX={encode(Z,X){if(Z.writeVarInt(X.idx),Z.writeBytes(new Uint8Array([X.status])),X.status===0)Z.writeVarInt(X.seq);return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readBytes(1);if(l!==0)return Y(l);let K=V[0];if(K!==0)return d({idx:X,status:K});let[G,m]=Z.readVarInt();if(m!==0)return Y(m);return d({idx:X,status:K,seq:G})}};var ll={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(YZ,W);if(K!==0)return K;let G=l.writeStructs(vW,V);if(G!==0)return G;return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K,notifier:G}=Z,[m,R]=X.readStruct(YZ);if(R!==0)return R;let J=await PZ(m,l,V);if(J!==0)return J;let{pubKey:C}=m,[F,b]=await K.hasUser(C);if(b!==0)return b;if(!F)return 5;let[T,c]=X.readStructs(vW);if(c!==0)return c;console.info(`PUSH: ${T.length} bags`);let k=[],I=[];for(let L=0;L<T.length;L++){let M=T[L];if(!await eV(M,C,l)){let E={idx:L,status:3},O=W.writeStruct(qX,E);if(O!==0)return O;continue}k.push(L),I.push(M)}let[Q,p]=await K.setBags(C,I);if(p!==0)return p;if(!Q||Q.length!==I.length)return 17;let z=[];for(let L=0;L<I.length;L++){let M=I[L],h=k[L],E=Q[L],O=new U,i=O.writeStruct(fX,M);if(i!==0)return i;let j=O.result(),y={seq:E,headCph:j};if(T.length===1&&M.bodyCph.length<=tV)y.bodyCph=M.bodyCph;z.push(y);let A={idx:h,status:0,seq:E},v=W.writeStruct(qX,A);if(v!==0)return v}if(z.length>0){let L=new U,M=L.writeStructs($X,z);if(M!==0)return M;let h=L.result();await Promise.resolve(G.push(C,h))}return 0},decodeResp(Z){return Z.readStructs(qX)}};var Kl={async encodeReq(Z,X,W,V,l){return l.writeStruct(YZ,W)},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(YZ);if(m!==0)return m;let R=await PZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G;if(!X.done())return 8;let[C,F]=await K.addUser(J);if(F!==0)return F;return 0},decodeResp(Z){return d(void 0)}};class $W{url;websocket;constructor(Z){this.url=Z}connected(){return this.websocket!==void 0&&this.websocket.readyState===WebSocket.OPEN}async connect(Z,X,W=()=>{},V=()=>{}){let{url:l}=this;if(this.websocket)this.websocket.close(),this.websocket=void 0;let K=new U;K.writeStruct(YZ,Z);let G=K.result(),m=mZ(G);return l.searchParams.set("t",m),this.websocket=new WebSocket(l),this.websocket.binaryType="arraybuffer",this.websocket.onopen=()=>{console.log("CONNECTED"),V()},this.websocket.onclose=()=>{console.log("DISCONNECTED"),this.websocket=void 0,W()},this.websocket.onmessage=(R)=>{let J=new Uint8Array(R.data);X(J)},this.websocket.onerror=(R)=>{console.log(`ERROR: ${JSON.stringify(R)}`),this.websocket=void 0,W()},Promise.resolve(0)}disconnect(){this.websocket?.close(),this.websocket=void 0}}var s={user:{path:"/user",endpoint:Kl,name:0},push:{path:"/push",endpoint:ll,name:2},peek:{path:"/peek",endpoint:Wl,name:1},pull:{path:"/pull",endpoint:Vl,name:3}},f0={0:s.user,2:s.push,1:s.peek,3:s.pull},mR={[s.user.path]:s.user,[s.push.path]:s.push,[s.peek.path]:s.peek,[s.pull.path]:s.pull};class fW{url;listener;constructor(Z){this.url=Z;this.listener=new $W(Z)}async call(Z,X){let{path:W}=f0[Z],V=new URL(W,this.url);try{return await q0(V,X)}catch{return Y(25)}}}var nX=(Z)=>{return new fW(Z.handle)};async function q0(Z,X){let W=await fetch(Z,{method:"POST",body:X.result().slice()});if(!W.ok)return Y(24);let V=await P.fromResponse(W);return d(V)}class _X{enclave;crypto;host;clock;transport;updateHostMeta;constructor(Z,X,W,V,l,K){this.enclave=Z;this.crypto=X;this.host=W;this.clock=V;this.transport=l;this.updateHostMeta=K}async call(Z,X){let{clock:W,transport:V}=this,{endpoint:l,name:K}=Z,G=await this.identity(),m=W.now(),[R,J]=await EW(G,m);if(J!==0)return Y(J);let C=new U,F=await l.encodeReq(this,G,R,X,C);if(F!==0)return Y(F);let b=W.now(),[T,c]=await V.call(K,C),k=W.now();if(c!==0)return Y(c);let[I,Q]=T.readStruct(DW);if(Q!==0)return Y(Q);if(I.status!==0)return Y(I.status);let z={clockOffset:Xl(b,I.timeRcvd,I.timeSent,k),subscription:I.subscription},L=await this.updateHostMeta(z);if(L!==0)return Y(L);return l.decodeResp(T)}identity=()=>{let{host:Z,enclave:X}=this;return X.deriveIdentity(Z.label,Z.idx??0)};seal=async(Z)=>{let{crypto:X,enclave:W}=this,V=await this.identity();return Zl(Z,V,X,W)};register=()=>this.call(s.user,[]);peek=(Z)=>this.call(s.peek,[Z]);push=(Z)=>this.call(s.push,Z);pull=(Z)=>this.call(s.pull,Z);listen=async(Z,X,W)=>{let{clock:V,transport:l}=this,{listener:K}=l,G=await this.identity(),m=V.now(),[R,J]=await EW(G,m);if(J!==0)return J;return await K.connect(R,Z,X,W)};isConnected(){let Z=this.transport?.listener;if(Z&&typeof Z.connected==="function")return Z.connected();return!0}closeListener(){this.transport?.listener?.disconnect()}}var qW={encode(Z,X){let W=Z.writeVarString(X.lbl);if(W!==0)return W;let V=Z.writeVarInt(X.idx);if(V!==0)return V;let l=Z.writeVarInt(X.num);if(l!==0)return l;return Z.writeBytes(X.hsh),Z.writeBytes(X.sig),0},decode(Z){let[X,W]=Z.readVarString();if(W!==0)return Y(W);let[V,l]=Z.readVarInt();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let[m,R]=Z.readBytes(vX);if(R!==0)return Y(R);let[J,C]=Z.readBytes(HZ);if(C!==0)return Y(C);return d({lbl:X,idx:V,num:K,hsh:m,sig:J})}};var nW={encode(Z,X){let W=Z.writeStruct(qW,X.head);if(W!==0)return W;let V=Z.writeVarBytes(X.indexEnc);if(V!==0)return V;let l=Z.writeVarBytes(X.bodyEnc);if(l!==0)return l;return 0},decode(Z){let[X,W]=Z.readStruct(qW);if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return d({head:X,indexEnc:V,bodyEnc:K})}};var _W={encode(Z,X){Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarInt(X.lenBody);if(V!==0)return V;if(X.lenBody>0&&X.offBody!==void 0){let l=Z.writeVarInt(X.offBody);if(l!==0)return l}return 0},decode(Z){let[X,W]=Z.readBytes(hZ);if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let m;if(K>0){let[R,J]=Z.readVarInt();if(J!==0)return Y(J);m=R}return d({kdm:X,headCph:V,lenBody:K,offBody:m})}};async function Gl(Z,X,W,V,l){let K=await l.deriveIdentity(Z,X),G=new U,m=new U,R=0,J=0;for(let Q of W){let p=new U,z=p.writeStruct(RZ,Q.head);if(z!==0)return Y(z);let L=p.result(),M=await K.kdmFor(L),h=l.deriveCipher(M,"encrypt"),E=await h.encrypt(L),O=Q.body?await h.encrypt(Q.body):new Uint8Array(0),i=Q.head.len>0&&Q.head.hsh!==void 0?O.length:0,j={kdm:M,headCph:E,lenBody:i,offBody:i>0?J:void 0},y=G.writeStruct(_W,j);if(y!==0)return Y(y);if(Q.body)m.writeBytes(O),J+=O.length;R++}let C=m.result(),F=G.result(),b=await V.blake3(F),T=await K.sign(b),c={lbl:Z,idx:X,num:R,hsh:b,sig:T},k=new U;k.writeStruct(nW,{head:c,indexEnc:F,bodyEnc:C});let I=k.result();return d(I)}async function ml(Z,X,W){let[V,l]=nW.decode(new P(Z));if(l!==0)return Y(l);let{head:K,indexEnc:G,bodyEnc:m}=V,R=await W.deriveIdentity(K.lbl,K.idx);if(!await X.checkSigEd25519(K.sig,K.hsh,R.publicKey))return Y(3);let C=await X.blake3(G);if(!n(C,K.hsh))return Y(19);let F=new P(G),b=[];for(let c=0;c<K.num;c++){let[k,I]=F.readStruct(_W);if(I!==0)return Y(I);b.push(k)}if(b.length!==K.num)return Y(14);let T=[];for(let c of b){let k=W.deriveCipher(c.kdm,"decrypt"),I;try{I=await k.decrypt(c.headCph)}catch{return Y(20)}let[Q,p]=RZ.decode(new P(I));if(p!==0)return Y(p);let z;if(c.lenBody>0&&c.offBody!==void 0){if(Q.hsh===void 0)return Y(14);let L=m.slice(c.offBody,c.offBody+c.lenBody);try{z=await k.decrypt(L)}catch{return Y(20)}let M=await X.blake3(z);if(!n(M,Q.hsh))return Y(19)}T.push({head:Q,body:z})}return d(T)}async function Yl({now:Z,bod:X,crypto:W}){let V=await W.genRandomBytes(8),l=new U,K=l.writeStruct(r,{id:V,ts:Z});if(K!==0)return Y(K);let G=l.result();return aX({now:Z,eid:G,ctr:0,bod:X,crypto:W})}async function aX({now:Z,eid:X,ctr:W,bod:V,crypto:l}){let K=new P(X),[G,m]=r.decode(K);if(m!==0)return Y(m);let R=Z.getTime()-G.ts.getTime(),J,C=V?.length??0;if(V&&C>0)J=await l.blake3(V);return d({eid:X,off:R,ctr:W,len:C,hsh:J})}function Rl(Z,X){let W=Z.length<X.length?Z.length:X.length;for(let V=0;V<W;V++)if(Z[V]!==X[V])return Z[V]-X[V];return Z.length-X.length}async function VX(Z,X){let W=Array.from(Z);W.sort(Rl);let V=0;for(let G of W)V+=G.length;let l=new Uint8Array(V),K=0;for(let G of W)l.set(G,K),K+=G.length;return X.blake3(l)}function Jl(Z){let X=new U,W=X.writeVarBytes(Z.eid);if(W!==0)return Y(W);let V=X.writeDate(Z.updatedAt);if(V!==0)return Y(V);let l=X.writeVarInt(Z.ctr);if(l!==0)return Y(l);return d(X.result())}async function QX(Z,X){let W=[];for(let V of Z){let[l,K]=Jl(V);if(K!==0||!l)return Y(K);W.push(l)}return d(await VX(W,X))}var ZJ=Symbol("MasterSeed"),XJ=Symbol("SealedMasterKey"),dZ=32,aW=24+dZ+16;function WZ(Z){if(Z.byteLength!==dZ)return Y(10);return d(Z)}function pZ(Z){if(Z.byteLength!==aW)return Y(10);return d(Z)}var VJ=Symbol("EntityID");function Cl(Z){return"type"in Z}var lJ=Symbol("DerivationSeed"),KJ=Symbol("PublicKey"),GJ=Symbol("PrivateKey"),mJ=Symbol("HostSpecificKeyPair"),YJ=Symbol("Hash");function n0(Z){if(!Z)return!1;if(typeof Z!=="object")return!1;if("body"in Z===!1)return!1;if("type"in Z===!1)return!1;return!0}function _0(Z){if(!Z.bod||Z.bod.length===0){let V={off:Z.off,ctr:Z.ctr,eid:Z.eid};return d(V)}let X=OW(Z.bod);if(n0(X)===!1)return console.warn("msg body invalid",X),Y(14);let W={off:Z.off,ctr:Z.ctr,eid:Z.eid,gid:X.gid,pid:X.pid,tags:X.tags,type:X.type,body:X.body};return d(W)}class yX{applier;emitter=new SZ;clearer;onDirtyEids;cacheDriven;peerIngest;constructor(Z,X,W,V){this.applier=Z;this.clearer=X,this.onDirtyEids=W,this.cacheDriven=V?.cacheDriven??!1,this.peerIngest=V?.peerIngest}apply=async(Z)=>{let X=[],W=[];for(let m of Z){let[R,J]=_0(m);if(W.push(J),J!==0)continue;X.push(R)}let{stats:V,types:l,eids:K}=await this.applier(X),G=[];for(let m=0;m<Z.length;m++){let R=W[m],J=V[m];if(R!==0){G.push(R);continue}if(J!==0){G.push(J);continue}G.push(0)}if(!this.cacheDriven)for(let m of l)this.emitter.emit(m,null);if(K.length>0)this.onDirtyEids?.(K);return G};clear=async()=>{let Z=await this.clearer();if(Z!==0)return Z;return this.emitter.emitAll(null),Z};notify=(Z)=>{for(let X of Z)this.emitter.emit(X,null)};refresh=async(Z)=>{if(this.peerIngest){await this.peerIngest(Z);return}};on=(Z,X)=>{this.emitter.addEventListener(Z,X)};off=(Z,X)=>{this.emitter.removeEventListener(Z,X)}}var rW={apply:async function(Z){return Z.map(()=>0)},clear:async function(){return 0},notify:function(Z){},refresh:async function(Z){},on:function(Z,X){},off:function(Z,X){}};var f="entities",rX="entity_type_created_at",tW="entity_type_updated_at",eW="entity_type_group_id",ZV="entity_type_parent_id",lX="entity_tags",Fl="db",dl=13;function a0(Z){return"typ"in Z}function r0(Z){let X={bod:Z.body,crd:Z.createdAt,...Z.ctr!==0?{ctr:Z.ctr}:{},eid:S(Z.eid),gid:Z.gid,pid:Z.pid?S(Z.pid):void 0,tgs:Z.tags,typ:Z.type,upd:Z.updatedAt};if(X.gid===void 0)delete X.gid;if(X.pid===void 0)delete X.pid;if(X.tgs===void 0)delete X.tgs;if(X.ctr===void 0)delete X.ctr;return X}function s0(Z){if(!D(Z))return{eid:S(Z.eid),upd:Z.updatedAt,...Z.ctr!==0?{ctr:Z.ctr}:{}};return r0(Z)}function KX(Z){return{body:Z.bod,createdAt:Z.crd,updatedAt:Z.upd,ctr:Z.ctr??0,type:Z.typ,eid:e(Z.eid),gid:Z.gid,pid:Z.pid?e(Z.pid):void 0,...Z.tgs!==void 0?{tags:Z.tgs}:{}}}function sW(Z){if(a0(Z))return KX(Z);return{eid:e(Z.eid),updatedAt:Z.upd,ctr:Z.ctr??0}}class XV{db;opening;async init(){await this.ensureDb()}async ensureDb(){if(this.db)return this.db;if(this.opening)return this.opening;return this.opening=e0().then((Z)=>{return Z.onversionchange=()=>{if(Z.close(),this.db===Z)this.db=void 0},this.db=Z,this.opening=void 0,Z},(Z)=>{throw this.opening=void 0,Z}),this.opening}apply=async(Z)=>{let X=new Set,W=[],V;try{V=await this.ensureDb()}catch{return{stats:Z.map(()=>16),types:X,eids:W}}let l=V.transaction(f,"readwrite"),K=l.objectStore(f);return new Promise((G)=>{let m=Array(Z.length).fill(0);if(Z.length<1){G({stats:[],types:X,eids:W});return}l.oncomplete=()=>{G({stats:m,types:X,eids:W})},l.onerror=()=>{for(let J=0;J<m.length;J++)if(m[J]===void 0)m[J]=18;G({stats:m,types:X,eids:W})};let R=new Map;for(let J=0;J<Z.length;J++){let C=Z[J],F=S(C.eid),b={op:C,index:J},T=R.get(F);if(T)T.push(b);else R.set(F,[b])}for(let[J,C]of R){if(C.length<1)continue;let F=K.get(J);F.onsuccess=()=>{let b=F.result,T=b?sW(b):void 0,c=!1;for(let{op:k,index:I}of C){let[Q,p]=GX(T,k);if(p!==0){m[I]=p;continue}if(Q===void 0){m[I]=12;continue}c=!0;for(let z of mX(T,Q))X.add(z);T=Q}if(c)W.push(C[0].op.eid);if(T){let k=K.put(s0(T));k.onerror=(I)=>{I.preventDefault();for(let{index:Q}of C)m[Q]=18}}},F.onerror=()=>{for(let{index:b}of C)m[b]=18}}})};async clear(){let Z;try{Z=await this.ensureDb()}catch{return 16}let X=Z.transaction(f,"readwrite"),W=X.objectStore(f);return new Promise((V)=>{X.oncomplete=()=>V(0),X.onerror=()=>V(18),W.clear()})}async getRow(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let W=S(Z),l=X.transaction(f,"readonly").objectStore(f);return new Promise((K)=>{let G=l.get(W);G.onsuccess=()=>{let m=G.result;if(!m)K(d(void 0));else K(d(sW(m)))},G.onerror=()=>K(Y(18))})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!D(X))return d(void 0);return d(X)}async getAllOfTypeUpdatedBetween(Z,X,W){let V;try{V=await this.ensureDb()}catch{return Y(16)}let K=V.transaction(f,"readonly").objectStore(f).index(tW);return new Promise((G)=>{let m=K.getAll(IDBKeyRange.bound([Z,X],[Z,W]));m.onsuccess=()=>{let R=m.result;G(d(R.map(KX)))},m.onerror=()=>G(Y(18))})}async getGroupMembers(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(f,"readonly").objectStore(f).index(eW);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z,X]));G.onsuccess=()=>{let m=G.result;K(d(m.map(KX)))},G.onerror=()=>K(Y(18))})}async getAllOfType(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(f,"readonly").objectStore(f).index(rX);return new Promise((l)=>{let K=V.getAll(IDBKeyRange.bound([Z],[Z,[]]));K.onsuccess=()=>{let G=K.result;l(d(G.map(KX)))},K.onerror=()=>l(Y(18))})}async getByTag(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(f,"readonly").objectStore(f).index(lX);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only(X));G.onsuccess=()=>{let R=G.result.filter((J)=>J.typ===Z).map(KX);K(d(R))},G.onerror=()=>K(Y(18))})}async getAllEntities(Z){if("pid"in Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let W=S(Z.pid),l=X.transaction(f,"readonly").objectStore(f).index(ZV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z.type,W]));G.onsuccess=()=>{let R=G.result.map(KX);K(d(R))},G.onerror=()=>K(Y(18))})}else if("gid"in Z)return await this.getGroupMembers(Z.type,Z.gid);else if("tag"in Z)return await this.getByTag(Z.type,Z.tag);else if("updatedBetween"in Z)return await this.getAllOfTypeUpdatedBetween(Z.type,Z.updatedBetween.start,Z.updatedBetween.end);return await this.getAllOfType(Z.type)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return d(X)}async countEntities({type:Z}){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(f,"readonly").objectStore(f).index(rX);return new Promise((l)=>{let K=IDBKeyRange.bound([Z],[Z,[]]),G=V.count(K);G.onsuccess=()=>l(d(G.result)),G.onerror=()=>l(Y(18))})}async checksum(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(f,"readonly").objectStore(f),l=[];return new Promise((K)=>{let G=V.openCursor();G.onsuccess=()=>{let m=G.result;if(m){let R=m.value;l.push(zX(sW(R))),m.continue()}else QX(l,Z).then(K)},G.onerror=()=>K(Y(18))})}}function t0(Z,X){if(!Z.objectStoreNames.contains(f))Z.createObjectStore(f,{keyPath:"eid",autoIncrement:!1});let W=X.objectStore(f);if(!W.indexNames.contains(rX))W.createIndex(rX,["typ","crd"],{unique:!1});if(!W.indexNames.contains(tW))W.createIndex(tW,["typ","upd"],{unique:!1});if(!W.indexNames.contains(eW))W.createIndex(eW,["typ","gid"],{unique:!1});if(!W.indexNames.contains(ZV))W.createIndex(ZV,["typ","pid"],{unique:!1});if(W.indexNames.contains(lX)){if(W.index(lX).keyPath!=="tgs")W.deleteIndex(lX)}if(!W.indexNames.contains(lX))W.createIndex(lX,"tgs",{unique:!1,multiEntry:!0})}function e0(){return new Promise((Z,X)=>{let W=indexedDB.open(Fl,dl);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!l){X(Error("Transaction is null during EntDB upgrade"));return}try{t0(V,l)}catch(K){X(K instanceof Error?K:Error(String(K)))}},W.onblocked=()=>{console.warn(`[DIPLOMATIC] EntDB IDB upgrade blocked (${Fl} → v${dl}); waiting for other connections to close`)},W.onsuccess=()=>Z(W.result),W.onerror=()=>X(W.error??Error("EntDB IndexedDB open failed"))})}async function bl(){let Z=new XV;return await Z.init(),Z}class sX{ents=new Map;useIndex;byType=new Map;byTypePid=new Map;byTypeGid=new Map;byTypeTag=new Map;constructor(Z=[],X){this.useIndex=X?.indexes!==!1;for(let W of Z)this.put(W)}put(Z){let X=S(Z.eid),W=this.ents.get(X);if(W!==void 0&&D(W))this.unindex(X,W);if(this.ents.set(X,Z),D(Z))this.index(X,Z)}del(Z){let X=this.ents.get(Z);if(X===void 0)return;if(D(X))this.unindex(Z,X);this.ents.delete(Z)}index(Z,X){if(!this.useIndex)return;let W=this.byType.get(X.type);if(!W)W=new Map,this.byType.set(X.type,W);if(W.set(Z,X),X.pid){let V=S(X.pid),l=this.byTypePid.get(X.type);if(!l)l=new Map,this.byTypePid.set(X.type,l);let K=l.get(V);if(!K)K=new Map,l.set(V,K);K.set(Z,X)}if(typeof X.gid==="string"){let V=this.byTypeGid.get(X.type);if(!V)V=new Map,this.byTypeGid.set(X.type,V);let l=V.get(X.gid);if(!l)l=new Map,V.set(X.gid,l);l.set(Z,X)}if(X.tags){let V=this.byTypeTag.get(X.type);if(!V)V=new Map,this.byTypeTag.set(X.type,V);for(let l of X.tags){let K=V.get(l);if(!K)K=new Map,V.set(l,K);K.set(Z,X)}}}unindex(Z,X){if(!this.useIndex)return;let W=this.byType.get(X.type);if(W){if(W.delete(Z),W.size===0)this.byType.delete(X.type)}if(X.pid){let V=S(X.pid),l=this.byTypePid.get(X.type),K=l?.get(V);if(K){if(K.delete(Z),K.size===0)l?.delete(V)}if(l&&l.size===0)this.byTypePid.delete(X.type)}if(typeof X.gid==="string"){let V=this.byTypeGid.get(X.type),l=V?.get(X.gid);if(l){if(l.delete(Z),l.size===0)V?.delete(X.gid)}if(V&&V.size===0)this.byTypeGid.delete(X.type)}if(X.tags){let V=this.byTypeTag.get(X.type);if(V){for(let l of X.tags){let K=V.get(l);if(K){if(K.delete(Z),K.size===0)V.delete(l)}}if(V.size===0)this.byTypeTag.delete(X.type)}}}clearIndexes(){this.byType.clear(),this.byTypePid.clear(),this.byTypeGid.clear(),this.byTypeTag.clear()}bucketList(Z){if(!Z||Z.size===0)return[];let X=[];for(let W of Z.values())X.push(W);return X}async apply(Z){let X=new Set,W=[],V=[];for(let l of Z){let K=S(l.eid),G=this.ents.get(K),[m,R]=GX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of mX(G,m))X.add(J);this.put(m),W.push(l.eid),V.push(0)}return{stats:V,types:X,eids:W}}async clear(){return this.ents.clear(),this.clearIndexes(),0}async getRow(Z){let X=S(Z),W=this.ents.get(X);return d(W)}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!D(X))return d(void 0);return d(X)}async getAllEntities({type:Z,gid:X,pid:W,tag:V,updatedBetween:l}){if(this.useIndex){if(W!==void 0){let G=S(W);return d(this.bucketList(this.byTypePid.get(Z)?.get(G)))}if(X!==void 0)return d(this.bucketList(this.byTypeGid.get(Z)?.get(X)));if(V!==void 0)return d(this.bucketList(this.byTypeTag.get(Z)?.get(V)));if(l!==void 0){let G=[],m=this.byType.get(Z);if(m){for(let R of m.values())if(R.updatedAt>=l.start&&R.updatedAt<=l.end)G.push(R)}return d(G)}return d(this.bucketList(this.byType.get(Z)))}let K=[];if(W!==void 0){for(let G of this.ents.values())if(D(G)&&G.type===Z&&G.pid&&n(G.pid,W))K.push(G)}else if(X!==void 0){for(let G of this.ents.values())if(D(G)&&G.type===Z&&(typeof G.gid==="string"&&G.gid===X))K.push(G)}else if(V!==void 0){for(let G of this.ents.values())if(D(G)&&G.type===Z&&G.tags&&G.tags.includes(V))K.push(G)}else if(l!==void 0){for(let G of this.ents.values())if(D(G)&&G.type===Z&&G.updatedAt>=l.start&&G.updatedAt<=l.end)K.push(G)}else for(let G of this.ents.values())if(D(G)&&G.type===Z)K.push(G);return d(K)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return d(X)}async countEntities({type:Z}){if(this.useIndex)return d(this.byType.get(Z)?.size??0);let X=0;for(let W of this.ents.values())if(D(W)&&W.type===Z)X+=1;return d(X)}async checksum(Z){let X=[];for(let W of this.ents.values())X.push(zX(W));return QX(X,Z)}}async function WV(Z){let X=await bl();if(Z?.cache===!1)return X;return new xX(X,void 0,{indexes:Z?.indexes})}class xX{mem;durable;warmed=new Set;listeners=new Set;chain=Promise.resolve();constructor(Z,X,W){if(this.durable=Z,this.mem=new sX(X??[],{indexes:W?.indexes}),X)for(let V of X)this.warmed.add(V.type)}subscribe(Z){return this.listeners.add(Z),()=>{this.listeners.delete(Z)}}emit(Z){if(Z.size<1)return;for(let X of this.listeners)X(Z)}run(Z){let X=this.chain.then(Z,Z);return this.chain=X.then(()=>{return},()=>{return}),X}apply(Z){return this.run(async()=>{await this.pullEids(Z.map((K)=>K.eid));let X=KK(this.mem,Z);this.emit(X.types);let W=await this.durable.apply(Z),{changed:V,status:l}=await this.pullEids(Z.map((K)=>K.eid));if(this.emit(V),l!==0)return{stats:Z.map(()=>l),types:W.types,eids:W.eids};return W})}clear(){return this.run(async()=>{let Z=await this.durable.clear();if(Z!==0)return Z;let X=this.mem.ents.size>0;return await this.mem.clear(),this.warmed.clear(),0})}ingestFromDurable(Z){return this.run(async()=>{let{changed:X,status:W}=await this.pullEids(Z);return this.emit(X),W})}async pullEids(Z){let X=new Set,W=new Set;for(let V of Z){let l=S(V);if(W.has(l))continue;W.add(l);let K=this.mem.ents.get(l),[G,m]=await this.durable.getRow(V);if(m!==0)return{changed:X,status:m};if(G){if(this.mem.put(G),!K||!ZK(K,G)){if(D(G))X.add(G.type);if(K!==void 0&&D(K))X.add(K.type)}}else if(K!==void 0){if(this.mem.del(l),D(K))X.add(K.type)}}return{changed:X,status:0}}async warmType(Z){if(this.warmed.has(Z))return 0;let[X,W]=await this.durable.getEntities({type:Z});if(W!==0)return W;if(X)for(let V of X){let l=S(V.eid),K=this.mem.ents.get(l);if(!K||lK(V,K))this.mem.put(V)}return this.warmed.add(Z),0}async getRow(Z){let X=S(Z);if(this.mem.ents.has(X))return this.mem.getRow(Z);return this.run(async()=>{if(this.mem.ents.has(X))return this.mem.getRow(Z);let[W,V]=await this.durable.getRow(Z);if(V!==0)return Y(V);if(W)this.mem.put(W);return d(W)})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!D(X))return d(void 0);return d(X)}async getEntities(Z){if(!this.warmed.has(Z.type)){let X=await this.run(()=>this.warmType(Z.type));if(X!==0)return Y(X)}return this.mem.getEntities(Z)}async countEntities({type:Z}){if(!this.warmed.has(Z)){let X=await this.run(()=>this.warmType(Z));if(X!==0)return Y(X)}return this.mem.countEntities({type:Z})}async checksum(Z){return this.durable.checksum(Z)}}function ZK(Z,X){if(D(Z)!==D(X))return!1;if(Z.ctr!==X.ctr)return!1;if(Z.updatedAt.getTime()!==X.updatedAt.getTime())return!1;if(!n(Z.eid,X.eid))return!1;if(!D(Z)||!D(X))return!0;if(Z.createdAt.getTime()!==X.createdAt.getTime())return!1;if(Z.type!==X.type)return!1;if(Z.gid!==X.gid)return!1;if(!WK(Z.pid,X.pid))return!1;if(!XK(Z.tags,X.tags))return!1;return VK(Z.body,X.body)}function XK(Z,X){if(Z===X)return!0;if(Z===void 0||X===void 0)return!1;if(Z.length!==X.length)return!1;for(let W=0;W<Z.length;W++)if(Z[W]!==X[W])return!1;return!0}function WK(Z,X){if(Z===void 0&&X===void 0)return!0;if(Z===void 0||X===void 0)return!1;return n(Z,X)}function VK(Z,X){if(Object.is(Z,X))return!0;if(Z instanceof Uint8Array&&X instanceof Uint8Array)return n(Z,X);if(Z instanceof Date&&X instanceof Date)return Z.getTime()===X.getTime();try{return n(wZ(Z),wZ(X))}catch{return!1}}function lK(Z,X){let W=Z.updatedAt.getTime(),V=X.updatedAt.getTime();if(W!==V)return W>V;return Z.ctr>X.ctr}function KK(Z,X){let W=new Set,V=[];for(let l of X){let K=S(l.eid),G=Z.ents.get(K),[m,R]=GX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of mX(G,m))W.add(J);Z.put(m),V.push(0)}return{stats:V,types:W}}function tX(Z){if(Z instanceof xX){let X=new yX((W)=>Z.apply(W),()=>Z.clear(),void 0,{cacheDriven:!0,peerIngest:async(W)=>{await Z.ingestFromDurable(W)}});return Z.subscribe((W)=>X.notify(W)),X}return new yX((X)=>Z.apply(X),()=>Z.clear())}function D(Z){return"type"in Z}function GK(Z){return!D(Z)}function Tl(Z){if(!Array.isArray(Z)||Z.length===0)return;let X=new Set,W=[];for(let V of Z){if(typeof V!=="string"||V.length===0)continue;if(X.has(V))continue;X.add(V),W.push(V)}return W.length>0?W:void 0}function zX(Z){return{eid:Z.eid,ctr:Z.ctr,updatedAt:Z.updatedAt}}function VV(Z){let X=new P(Z.eid),[W,V]=X.readStruct(r);if(V!==0)return Y(V);return d({eid:Z.eid,ctr:Z.ctr,updatedAt:new Date(W.ts.getTime()+Z.off)})}function GX(Z,X){let W=new P(X.eid),[V,l]=W.readStruct(r);if(l!==0)return Y(l);let K=new Date(V.ts.getTime()+X.off);if(Z!==void 0&&K<=Z.updatedAt)return Y(15);if(Cl(X)){let G=Tl(X.tags);return d({eid:X.eid,gid:X.gid,pid:X.pid,...G!==void 0?{tags:G}:{},type:X.type,createdAt:V.ts,updatedAt:K,ctr:X.ctr,body:X.body})}return d({eid:X.eid,updatedAt:K,ctr:X.ctr})}function mX(Z,X){let W=new Set;if(Z!==void 0&&D(Z))W.add(Z.type);if(D(X))W.add(X.type);return[...W]}var mK={getEnt:async()=>Y(21),getRow:async()=>Y(21),getEntities:async(Z)=>Y(21),countEntities:async()=>Y(21),checksum:async()=>Y(21),apply:async(Z)=>({stats:Z.map(()=>21),types:new Set,eids:[]}),clear:async()=>21};class eX{inflight=null;again=!1;run(Z){if(this.again=!0,this.inflight)return this.inflight;return this.inflight=this.drain(Z),this.inflight}async flush(){if(!this.inflight)return;try{await this.inflight}catch{}}async drain(Z){try{this.again=!1;let X=await Z();while(this.again)this.again=!1,X=await Z();return X}finally{this.inflight=null}}}var ZW=100;class NX{timer=null;delayMs;work;tail=new eX;constructor(Z,X){this.delayMs=Z<0?0:Z,this.work=X}schedule(){if(this.delayMs<=0){this.fire();return}if(this.timer!==null)clearTimeout(this.timer);this.timer=setTimeout(()=>{this.timer=null,this.fire()},this.delayMs)}async flush(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null,this.fire();await this.tail.flush()}cancel(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null}fire(){return this.tail.run(this.work)}}function cl(Z){let X=new P(Z.eid),[W,V]=r.decode(X);if(V!==0)return;return W.ts.getTime()+Z.off}function YK(Z,X){let W=cl(Z),V=cl(X);if(W===void 0&&V===void 0)return 0;if(W===void 0)return 1;if(V===void 0)return-1;if(V!==W)return V-W;return X.ctr-Z.ctr}function YX(Z,X){return Z.slice().sort((W,V)=>YK(X(W),X(V)))}var DZ={phase:"idle"},RX=50;function XW(Z,X,W){if(Z<=0||X<=0)return!1;if(Z===1||Z===X)return!0;return Z%W===0}function WW(Z,X){if(typeof navigator.msSaveOrOpenBlob==="function"){navigator.msSaveOrOpenBlob(Z,X);return}let W=URL.createObjectURL(Z),V=document.createElement("a");V.href=W,V.download=X,document.body.appendChild(V),V.click(),document.body.removeChild(V),URL.revokeObjectURL(W)}function kl(Z,X,W){let V=[],l=[],K=0;for(let G of Z){let m=X(G);if(l.length>0&&K+m>W)V.push(l),l=[],K=0;if(l.push(G),K+=m,K>=W)V.push(l),l=[],K=0}if(l.length>0)V.push(l);return V}async function lV(Z,X,W){let V=Z.length;if(V<1)return[];let l=Array(V),K=0,G=Math.min(Math.max(1,X),V),m=async()=>{while(!0){let J=K;if(K+=1,J>=V)return;l[J]=await W(Z[J],J)}},R=[];for(let J=0;J<G;J++)R.push(m());return await Promise.all(R),l}async function VW(Z,X,W,V){let l=new P(Z.headCph),[K,G]=l.readStruct(fX);if(G!==0)return Y(G);let{sig:m,kdm:R,headCph:J}=K;if(!await V.checkSigEd25519(m,J,X))return Y(3);let F=W.deriveCipher(R,"decrypt"),b;try{b=await F.decrypt(J)}catch{return Y(20)}return d({kdm:R,headEnc:b})}var QZ="f",UZ="t",TZ="e";function RK(Z){return Z===QZ||Z===UZ||Z===TZ}function JX(Z){if(Z===!0||Z===UZ)return UZ;if(Z===TZ)return TZ;return QZ}function JK(Z){return JX(Z.apld)===QZ}function KV(Z){return Z!==0&&Z!==15&&Z!==18&&Z!==17}function AZ(Z,X,W){if(Z.apld=X,X===TZ&&W!==void 0)Z.err=W;else delete Z.err}async function iZ(Z,X,W,V){let l=V?.body!==!1,K=JX(X.apld),G=X.body,m=G?.length??0,R;if(l&&G&&m>0)R=await W.blake3(G);let J={eid:X.eid,off:X.off??0,ctr:X.ctr??0,len:m,hsh:R},C={hash:Z,head:J,apld:K};if(l&&G!==void 0)C.body=G;if(K===TZ&&X.err!==void 0)C.err=X.err;return C}var GV=1048576,mV=1048576,Ll=64;function CK(Z){return Z.sig.length+Z.kdm.length+Z.headCph.length+Z.bodyCph.length}async function FK(Z,X,W,V,l){if(V.length<1)return 0;let[K,G]=await Z.push(V);if(G!==0)return G;if(!K)return 27;for(let R of K){if(R.status!==0){console.error("push err",R);continue}let J=l[R.idx];if(!J){console.error("no hash",R);continue}await X.uploads.deq(W,[J])}let m=await X.hosts.get(W);if(m){let R=m.lastSeq,J=R,C=[];for(let F of K)if(F.status===0)C.push(F.seq);C.sort((F,b)=>F-b);for(let F of C)if(F===R+1)R=F;if(R>J)await X.hosts.touch(W,R)}return 0}async function Il(Z,X){if(X.length<1)return d([]);let W=new Map,V=[];for(let m of X)W.set(m.seq,m),V.push(m.seq);let[l,K]=await Z.pull(V);if(K!==0)return Y(K);if(!l)return Y(27);let G=[];for(let{seq:m,bodyCph:R}of l){let J=W.get(m);if(!J)continue;G.push({dl:J,bodyCph:R})}return d(G)}async function dK(Z,X,W,V){if(V.length<1)return d({parts:[],hashes:[]});let l=[],K=[],G=[],m=new Map;for(let{dl:J,bodyCph:C}of V){let{head:F,kdm:b,seq:T,host:c}=J,[k,I]=await pl(J,W);if(I!==0||!k){let i=m.get(c)??[];i.push(T),m.set(c,i);continue}let{headEnc:Q,headEncHash:p}=k,z=X.deriveCipher(b,"decrypt"),[L,M]=await wW(Q,C,z,W,p);if(M!==0||!L){let i=m.get(c)??[];i.push(T),m.set(c,i);continue}let h={head:F,body:L.bod},E=L.headHash;G.push({key:E,data:zl(h)}),l.push(h),K.push(E);let O=m.get(c)??[];O.push(T),m.set(c,O)}let R=await Z.messages.add(G);for(let[J,C]of m)await Z.downloads.deq(J,C);for(let J=0;J<R.length;J++){let C=R[J];if(C!==0&&C!==15)console.error("ERR storing",x[C],"for message",J)}return d({parts:l,hashes:K})}async function pl(Z,X){let W=Z.headEnc;if(!W){let l=new U,K=l.writeStruct(RZ,Z.head);if(K!==0)return Y(K);W=l.result()}if(Z.headEncHash)return d({headEnc:W,headEncHash:Z.headEncHash});let V=await X.blake3(W);return d({headEnc:W,headEncHash:V})}async function Ql(Z,X,W){let V=new Set;for(let G of X)V.add(S(G));if(V.size<1)return;let l=Array.from(await Z.downloads.list());if(l.length<1)return;let K=new Map;for(let G of l){let m;if(G.headEncHash)m=S(G.headEncHash);else{let[J,C]=await pl(G,W);if(C!==0||!J)continue;m=S(J.headEncHash)}if(!V.has(m))continue;let R=K.get(G.host)??[];R.push(G.seq),K.set(G.host,R)}for(let[G,m]of K)await Z.downloads.deq(G,m)}async function YV({conn:Z,store:X,enclave:W,host:V,crypto:l,onProgress:K,peekProgressEvery:G,peekConcurrency:m}){let R=await Z.identity(),J=[],[C,F]=await Z.peek(V.lastSeq);if(F!==0)return F;let b=C.length,T=G??RX,c=m??Ll;if(K&&b>0)K({phase:"peek",host:V.label,done:0,total:b});let k=0,I=await lV(C,c,async(p)=>{let[z,L]=await VW(p,R.publicKey,W,l),M;if(L!==0||!z)M={ok:!1,seq:p.seq,stat:L};else{let h=await l.blake3(z.headEnc);M={ok:!0,seq:p.seq,kdm:z.kdm,headEnc:z.headEnc,headEncHash:h}}if(k+=1,K&&XW(k,b,T))K({phase:"peek",host:V.label,done:k,total:b});return M}),Q=new Set;for(let p of I){if(!p.ok){console.error("peek: decrypting item head",p.stat);continue}let z=S(p.headEncHash);if(await X.messages.has(p.headEncHash)){console.info("peek: local msg; skip download, deq upload"),await X.uploads.deq(V.label,[p.headEncHash]),await X.downloads.deq(V.label,[p.seq]);continue}if(Q.has(z)){await X.downloads.deq(V.label,[p.seq]);continue}let M=new P(p.headEnc),[h,E]=M.readStruct(RZ);if(E!==0){console.error("peek: reading item head",E);continue}Q.add(z),J.push({kdm:p.kdm,head:h,seq:p.seq,host:V.label,headEnc:p.headEnc,headEncHash:p.headEncHash})}if(await X.downloads.enq(J),C.length>0){let p=Math.max(...C.map((z)=>z.seq));await X.hosts.recordStats(V.label,{lastSeq:p})}if(K)K({phase:"peek",host:V.label,done:b,total:b});return 0}async function yl({conn:Z,store:X,host:W,maxPushBytes:V,onProgress:l}){let K=V??GV,G=await X.uploads.list(W.label),m=G.length,R=0;if(l&&m>0)l({phase:"push",host:W.label,done:0,total:m});let J=[],C=[],F=0,b=async()=>{if(J.length<1)return 0;let T=J.length,c=await FK(Z,X,W.label,J,C);if(J=[],C=[],F=0,c===0){if(R+=T,l)l({phase:"push",host:W.label,done:R,total:m})}return c};for(let T of G){let c=await X.messages.get(T);if(!c){R+=1;continue}let k={...c.head,bod:c.body},[I,Q]=await Z.seal(k);if(Q!==0)return Q;if(!I)return 12;let p=CK(I);if(J.length>0&&F+p>K){let z=await b();if(z!==0)return z}if(J.push(I),C.push(T),F+=p,F>=K){let z=await b();if(z!==0)return z}}return b()}async function RV({conn:Z,store:X,enclave:W,host:V,crypto:l,maxPullBytes:K,onProgress:G},m){let R=K??mV,J=await X.downloads.list(),C=Array.from(J).filter((I)=>I.host===V.label);if(C.length<1)return 15;let F=YX(C,(I)=>I.head),b=kl(F,(I)=>I.head.len,R),T=F.length,c=0;if(G)G({phase:"pull",host:V.label,done:0,total:T});let k=Il(Z,b[0]);for(let I=0;I<b.length;I++){let[Q,p]=await k;if(p!==0||!Q)return p;if(c+=b[I].length,G)G({phase:"pull",host:V.label,done:c,total:T});let z=b[I+1];if(z)k=Il(Z,z);if(G)G({phase:"open",host:V.label,done:c,total:T});let L=YX(Q,(h)=>h.dl.head),[,M]=await dK(X,W,l,L);if(M!==0)return M;if(m){if(G)G({phase:"exec",host:V.label,done:c,total:T});await m()}}return 0}function zl({head:Z,body:X}){let W={eid:Z.eid,body:X,apld:QZ};if(Z.off!==0)W.off=Z.off;if(Z.ctr!==0)W.ctr=Z.ctr;return W}async function xl(Z,{conn:X,store:W,enclave:V,host:l,crypto:K,onProgress:G},m){let R=l.label,J=await X.identity(),C=new P(Z),[F,b]=C.readStructs($X);if(b!==0){console.error("Failed decoding notif",x[b]);return}let T=!1,k=(await W.hosts.get(R))?.lastSeq,I=[],Q=!1;for(let L of F){let[M,h]=await VW({seq:L.seq,headCph:L.headCph},J.publicKey,V,K);if(h!==0){console.error("Failed decrypting notif",x[h]);continue}let E=await K.blake3(M.headEnc);if(await W.messages.has(E))continue;let O=new P(M.headEnc),[i,j]=O.readStruct(RZ);if(j!==0){console.error("Failed to parse head",x[j]);continue}if(!L.bodyCph&&i.len>0)Q=!0,await W.downloads.enq([{seq:L.seq,host:R,kdm:M.kdm,head:i,headEnc:M.headEnc,headEncHash:E}]);else I.push({...M,head:i,bodyCph:L.bodyCph,headEncHash:E});if(k===void 0||L.seq!==k+1)console.log("out of seq",L.seq,k),T=!0;else k=L.seq}if(k!==void 0)await W.hosts.touch(l.label,k);let p=[];for(let L of I){let M=V.deriveCipher(L.kdm,"decrypt"),[h,E]=await wW(L.headEnc,L.bodyCph,M,K);if(E!==0){console.error("Failed to open body",x[E]);continue}p.push({key:L.headEncHash,data:zl({head:L.head,body:h.bod})})}let z=await W.messages.add(p);for(let L=0;L<z.length;L++){let M=z[L];if(M!==0&&M!==15)console.error("ERR storing",x[M],"for message",L)}if(G&&p.length>0)G({phase:"open",host:l.label,done:p.length,total:p.length});if(T||Q||p.length>0)m()}async function JV(Z,X={}){let W=X.pull!==!1,V=X.push===!0,{conn:l,store:K,enclave:G,host:m,crypto:R,onProgress:J,peekProgressEvery:C,peekConcurrency:F}=Z,b=await l.identity(),[T,c]=await l.peek(0);if(c!==0)return Y(c);let k=T.length,I=C??RX,Q=F??Ll;if(J&&k>0)J({phase:"peek",host:m.label,done:0,total:k});let p=0,z=await lV(T,Q,async(H)=>{let[B,u]=await VW(H,b.publicKey,G,R),w;if(u!==0||!B)w={ok:!1,seq:H.seq,stat:u};else{let g=await R.blake3(B.headEnc);w={ok:!0,seq:H.seq,kdm:B.kdm,headEnc:B.headEnc,headEncHash:g}}if(p+=1,J&&XW(p,k,I))J({phase:"peek",host:m.label,done:p,total:k});return w}),L=new Map;for(let H of z){if(!H.ok)continue;let B=S(H.headEncHash),u=L.get(B);if(u)u.count+=1;else L.set(B,{hash:H.headEncHash,count:1,sample:H})}let M=0,h=[];for(let H of L.values()){if(H.count>1)M+=H.count-1;h.push(H.hash)}let E=T.length,O=L.size,i=await VX(h,R),j=[],y=0;for(let H of L.values()){if(await K.messages.has(H.hash)){await K.uploads.deq(m.label,[H.hash]);continue}if(y+=1,!W)continue;let u=H.sample,w=new P(u.headEnc),[g,q]=w.readStruct(RZ);if(q!==0){console.error("reconcile: reading msg header",q);continue}j.push({kdm:u.kdm,head:g,seq:u.seq,host:m.label,headEnc:u.headEnc,headEncHash:u.headEncHash})}if(j.length>0)await K.downloads.enq(j);let A=0;if(V){let H=await K.messages.listKeys(),B=new Set(L.keys()),u=[];for(let w of H)if(!B.has(S(w)))A+=1,u.push(w);if(u.length>0)await K.uploads.enq(m.label,u)}else{let H=await K.messages.listKeys(),B=new Set(L.keys());for(let u of H)if(!B.has(S(u)))A+=1}let v=T.length>0?Math.max(...T.map((H)=>H.seq)):0;if(await K.hosts.recordStats(m.label,{setLastSeq:v}),J)J({phase:"peek",host:m.label,done:k,total:k});return d({msgcheck:i,numBags:E,uniqueMsgs:O,numDupes:M,missingLocal:y,missingHost:A})}class oZ{clock;state;store;transport;crypto;forceSkewHandlingByDefault;onScheduleSync;connections=new Map;applyChain=Promise.resolve();syncRuns=new eX;clientState;xferState;maxPushBytes;maxPullBytes;peekProgressEvery=RX;lastProgress=DZ;scheduledSync;constructor(Z,X,W,V,l,K=!0,G=GV,m=mV,R){this.clock=Z;this.state=X;this.store=W;this.transport=V;this.crypto=l;this.forceSkewHandlingByDefault=K;this.onScheduleSync=R;this.maxPushBytes=G,this.maxPullBytes=m,this.clientState=new bZ(()=>this.getClientState()),this.xferState=new bZ(()=>this.getXferState()),this.scheduledSync=new NX(ZW,async()=>{try{console.info("Running scheduled sync"),await this.sync()}catch(J){console.error("Debounced sync failed:",J)}})}emitProgress=(Z)=>{this.lastProgress=Z,this.xferState.emit()};async setSeed(Z,X){await this.store.seed.save(Z,X),this.clientState.emit()}async getClientState(){let{store:Z,connections:X}=this,W=await Z.seed.load(),V=await Z.hosts.list(),l=!1;for(let K of X.values())if(K.isConnected()){l=!0;break}return{hasSeed:W!==void 0,hasHost:Array.from(V).length>0,connected:l}}async getXferState(){let{uploads:Z,downloads:X}=this.store,W=await Z.count();return{numDownloads:await X.count(),numUploads:W,progress:this.lastProgress}}apply=(Z,X)=>{return this.enqueueApplyJob(()=>this.doApply(Z,X))};async doApply(Z,X={enqueueUpload:!0,triggerUpload:!0}){let W=[],V=[];for(let{head:K,body:G}of Z){let m=new U;m.writeStruct(RZ,K);let R=m.result(),J=await this.crypto.blake3(R),C={eid:K.eid,body:G,apld:QZ};if(K.off!==0)C.off=K.off;if(K.ctr!==0)C.ctr=K.ctr;W.push(J),V.push({key:J,data:C})}await this.store.messages.add(V),await Ql(this.store,W,this.crypto);let l=await this.doApplyHashes(W);if(X.enqueueUpload){let K=[];for(let G=0;G<W.length;G++){let m=l[G];if(m===0||m===15)K.push(W[G])}if(K.length>0){let G=await this.store.hosts.list();for(let m of G)await this.store.uploads.enq(m.label,K);this.xferState.emit()}}if(X.triggerUpload)this.scheduleSync();return l}enqueueApplyJob(Z){let X=this.applyChain.then(Z,Z);return this.applyChain=X.then(()=>{return},()=>{return}),X}drainApplyQueue(){return this.enqueueApplyJob(()=>this.doDrainApplyQueue())}async doDrainApplyQueue(){let Z=await this.store.messages.list({apld:QZ});if(Z.length<1)return[];let X=YX(Z,(W)=>W.head);return this.applyStored(X)}applyHashes=(Z)=>{return this.enqueueApplyJob(()=>this.doApplyHashes(Z))};async doApplyHashes(Z){let X=[];for(let l of Z){let K=await this.store.messages.get(l);if(K)X.push(K)}let W=await this.applyStored(X),V=new Map;for(let l=0;l<X.length;l++)V.set(S(X[l].hash),W[l]??12);return Z.map((l)=>V.get(S(l))??13)}async applyStored(Z){if(Z.length<1)return[];let X=Z.map((K)=>({...K.head,bod:K.body})),W=await this.state.apply(X),V=[],l=[];for(let K=0;K<Z.length;K++){let G=W[K];if(G===0||G===15)V.push(Z[K].hash);else if(G!==void 0&&KV(G))l.push({key:Z[K].hash,err:G})}if(V.length>0)await this.store.messages.markApplied(V);if(l.length>0)await this.store.messages.markFailed(l);return W}async insertRaw(Z){let{clock:X,crypto:W}=this,[V,l]=await Yl({now:X.now(),bod:Z,crypto:W});if(l!==0)return Y(l);let G=(await this.apply([{head:V,body:Z}]))[0];if(G!==0&&G!==15)return Y(G??12);return d(V)}async makeUpdate(Z,X){let{clock:W,crypto:V}=this,l=W.now();if(Z.updatedAt.getTime()>l.getTime())return Y(4);let K=Z.ctr+1,[G,m]=await aX({now:l,eid:Z.eid,ctr:K,bod:X,crypto:V});if(m!==0)return Y(m);return d({head:G,body:X})}async updateWithSkew(Z,X,W){if(W===!1)return Y(4);let{clock:V,crypto:l}=this,K=V.now(),G=new P(Z.eid),[m,R]=G.readStruct(r);if(R!==0)return Y(R);let J=Z.updatedAt.getTime()-m.ts.getTime(),C={eid:Z.eid,off:J+1,ctr:Z.ctr+1,len:0},b=(await this.apply([{head:C,body:void 0}]))[0];if(b!==0&&b!==15)return Y(b??12);if(X===void 0)return d(C);let[T,c]=XX({id:m.id,ts:K});if(c!==0)return Y(c);let[k,I]=await aX({now:K,eid:T,ctr:0,bod:X,crypto:l});if(I!==0)return Y(I);let p=(await this.apply([{head:k,body:X}]))[0];if(p!==0&&p!==15)return Y(p??12);return d(k)}async updateRaw(Z,X,W=this.forceSkewHandlingByDefault){if(Z.updatedAt.getTime()>this.clock.now().getTime())return this.updateWithSkew(Z,X,W);return this.enqueueApplyJob(async()=>{let[V,l]=await this.makeUpdate(Z,X);if(l!==0)return Y(l);let G=(await this.doApply([V]))[0];if(G!==0&&G!==15)return Y(G??12);return d(V.head)})}async insert(Z){let{body:X,type:W,gid:V,pid:l,tags:K}=Z,m=wZ({body:X,type:W,gid:V,pid:l,tags:K});return this.insertRaw(m)}async update(Z){let{prior:X,body:W,type:V,gid:l,pid:K,tags:G,force:m}=Z,J=wZ({body:W,type:V,gid:l,pid:K,tags:G});return this.updateRaw(X,J,m??this.forceSkewHandlingByDefault)}async delete(Z){let X=Z.force??!0;if("prior"in Z)return this.updateRaw(Z.prior,void 0,X);let[W,V]=await this.revFromArchive(Z.eid);if(V!==0)return Y(V);return this.updateRaw(W,void 0,X)}async revFromArchive(Z){let X=await this.store.messages.last(Z);if(X)return VV(X.head);let W=new P(Z),[V,l]=W.readStruct(r);if(l!==0)return Y(l);return d({eid:Z,ctr:-1,updatedAt:V.ts})}async genEID(Z){let{clock:X,crypto:W}=this,V=X.now();if(Z!==void 0)return XX({id:Z,ts:V});let l=await W.genRandomBytes(8);return XX({id:l,ts:V})}sync(){return this.syncRuns.run(()=>this.doSync())}async doSync(){let{connections:Z,crypto:X,store:W}=this,V=await W.seed.load();if(!V)return 22;await this.drainApplyQueue();for(let[l,K]of Z){let G=await W.hosts.get(l);if(!G)continue;let m={conn:K,store:W,enclave:V,host:G,crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},R=await YV(m);if(R!==0)return console.error(`Failed to peek: ${R}`),this.emitProgress({phase:"idle"}),R;this.xferState.emit();let J=await yl(m);if(J!==0)return console.error(`Failed to push: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await RV(m,async()=>{await this.drainApplyQueue()});if(C!==0&&C!==15)return console.error(`Failed to pull: ${C}`),this.emitProgress({phase:"idle"}),C;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async rebuild(Z){if(this.scheduledSync.cancel(),await this.syncRuns.flush(),Z?.checkHost??!0){let W=await this.repull();if(W!==0)return W}return this.enqueueApplyJob(()=>this.replay())}async msgcheck(){let Z=await this.store.messages.listKeys();return VX(Z,this.crypto)}listMsgs(Z){return this.store.messages.list(Z)}countMsgs(Z){return this.store.messages.count(Z)}async reconcile(Z,X){this.scheduledSync.cancel(),await this.syncRuns.flush();let{connections:W,crypto:V,store:l}=this,K=await l.seed.load();if(!K)return Y(22);let G=await l.hosts.get(Z);if(!G)return Y(13);let m=W.get(Z);if(!m||!m.isConnected()){if(await this.connectToHost(G,!1,!1),G=await l.hosts.get(Z),!G)return Y(13);m=W.get(Z)}if(!m)return Y(12);let R={conn:m,store:l,enclave:K,crypto:V,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},[J,C]=await JV({...R,host:G},X);if(this.xferState.emit(),C!==0)return this.emitProgress({phase:"idle"}),Y(C);if(!J)return this.emitProgress({phase:"idle"}),Y(12);if(X?.sync===!1)return this.emitProgress({phase:"idle"}),d(J);let F=await this.sync();if(F!==0)return Y(F);let b=await l.hosts.get(Z);if(!b)return Y(13);let[T,c]=await JV({...R,host:b},{pull:!1,push:!1});if(this.xferState.emit(),this.emitProgress({phase:"idle"}),c!==0)return Y(c);if(!T)return Y(12);return d(T)}async repull(){let{connections:Z,crypto:X,store:W}=this,V=await W.seed.load();if(!V)return 22;let l=Array.from(await W.hosts.list());if(l.length<1)return 0;for(let K of l){let G=Z.get(K.label);if(!G||!G.isConnected())await this.connectToHost(K,!1,!1)}for(let[K,G]of Z){let m=await W.hosts.get(K);if(!m)continue;let R={conn:G,store:W,enclave:V,host:{...m,lastSeq:0},crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},J=await YV(R);if(J!==0)return console.error(`rebuild: failed to peek: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await RV(R);if(C!==0&&C!==15)return console.error(`rebuild: failed to pull: ${C}`),this.emitProgress({phase:"idle"}),C;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async replay(){let Z=await this.state.clear();if(Z!==0)return Z;let X=await this.store.messages.list(),W=YX(X,(K)=>K.head),V=W.length;if(V<1)return this.emitProgress({phase:"idle"}),0;let l=0;while(l<W.length){let K=0,G=0,m=l;for(let J=l;J<W.length&&G<100&&K<102400;J++)K+=W[J].head.len,G++,m=J+1;let R=W.slice(l,m);await this.applyStored(R),this.emitProgress({phase:"exec",done:m,total:V}),l=m}return this.emitProgress({phase:"idle"}),0}async wipe(Z){let X=Z?.msgs!==!1,W=Z?.ents!==!1,V=Z?.meta!==!1,l=Z?.seed===!0;this.scheduledSync.cancel(),await this.disconnect(),await this.syncRuns.flush();let{store:K}=this;if(V)await K.hosts.wipe(),await K.uploads.wipe(),await K.downloads.wipe();if(X)await K.messages.wipe();if(l)await K.seed.wipe();if(W)await this.state.clear();this.lastProgress=DZ,this.clientState.emit(),this.xferState.emit()}import=async(Z,X)=>{let{crypto:W,store:V}=this,l=X?.onProgress,K=await V.seed.load();if(!K)return 22;console.time("import: decoding file...");let G=await Z.bytes(),[m,R]=await ml(G,W,K);if(R!==0)return R;console.timeEnd("import: decoding file...");let J=0;while(J<m.length){let C=0,F=0,b=J;for(let k=J;k<m.length&&F<100&&C<102400;k++)C+=m[k].head.len,F++,b=k+1;let T=m.slice(J,b);console.time(`import: applying [${J}, ${b}]`);let c=await this.apply(T,{enqueueUpload:!0,triggerUpload:!1});console.timeEnd(`import: applying [${J}, ${b}]`);for(let k=0;k<T.length;k++){let I=c[k];if(I!==0&&I!==15)console.warn(`failed to import msg ${J+k}: ${x[I]}`)}if(l)queueMicrotask(()=>l(b,m.length,0));this.emitProgress({phase:"import",done:b,total:m.length}),J=b}return this.scheduleSync(),this.emitProgress({phase:"idle"}),0};scheduleSync=()=>{if(this.onScheduleSync){this.onScheduleSync();return}this.scheduledSync.schedule()};async exportBytes(){let{crypto:Z,store:X}=this,W=await X.seed.load();if(!W)return Y(22);let V=await X.messages.list();return Gl("export",0,V,Z,W)}async export(Z){let[X,W]=await this.exportBytes();if(W!==0)return W;if(!X)return 12;let V=new Blob([X.slice()]);return WW(V,Z),0}async link(Z,X=!0){if(await this.store.hosts.add(Z),this.clientState.emit(),X){let W=await this.store.hosts.get(Z.label);if(W)await this.connectToHost(W)}}async unlink(Z){await this.store.hosts.del(Z),this.clientState.emit()}async hosts(){return Array.from(await this.store.hosts.list())}connectToHost=async(Z,X=!0,W=!0)=>{let{clock:V,connections:l,crypto:K,store:G,transport:m}=this,R=l.get(Z.label);if(R){if(R.isConnected())return;try{R.closeListener()}catch{}l.delete(Z.label)}let J=await G.seed.load();if(!J)return;console.info(`Connecting to ${Z.handle} (${Z.label})`);let C=new _X(J,K,Z,V,m(Z),(F)=>G.hosts.set(Z.label,F));if(await C.register(),X)await C.listen(async(F)=>{let b={conn:C,store:G,enclave:J,host:Z,crypto:K,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery};return xl(F,b,this.scheduleSync)},()=>this.clientState.emit(),()=>this.clientState.emit());if(l.set(Z.label,C),this.clientState.emit(),W)this.scheduleSync()};async connect(Z=!0,X=!0){let{connectToHost:W,scheduleSync:V,store:l}=this;if(!await l.seed.load())return;await this.drainApplyQueue();let G=await l.hosts.list();for(let m of G)await W(m,Z,!1);if(X)V()}disconnect=async()=>{for(let Z of this.connections.values())try{Z.closeListener()}catch{}this.connections.clear(),this.clientState.emit()}}var vZ=typeof globalThis==="object"&&"crypto"in globalThis?globalThis.crypto:void 0;function lW(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function CV(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function _(Z,...X){if(!CV(Z))throw Error("Uint8Array expected");if(X.length>0&&!X.includes(Z.length))throw Error("Uint8Array expected of length "+X+", got length="+Z.length)}function FV(Z,X=!0){if(Z.destroyed)throw Error("Hash instance has been destroyed");if(X&&Z.finished)throw Error("Hash#digest() has already been called")}function Nl(Z,X){_(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function dV(Z){if(typeof Z!=="boolean")throw Error(`boolean expected, not ${Z}`)}/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */var yZ=(Z)=>new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4));var bK=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!bK)throw Error("Non little-endian hardware is not supported");function TK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function KW(Z){if(typeof Z==="string")Z=TK(Z);else if(CV(Z))Z=GW(Z);else throw Error("Uint8Array expected, got "+typeof Z);return Z}function Ml(Z,X){if(X==null||typeof X!=="object")throw Error("options must be defined");return Object.assign(Z,X)}function gl(Z,X){if(Z.length!==X.length)return!1;let W=0;for(let V=0;V<Z.length;V++)W|=Z[V]^X[V];return W===0}var Sl=(Z,X)=>{function W(V,...l){if(_(V),Z.nonceLength!==void 0){let C=l[0];if(!C)throw Error("nonce / iv required");if(Z.varSizeNonce)_(C);else _(C,Z.nonceLength)}let K=Z.tagLength;if(K&&l[1]!==void 0)_(l[1]);let G=X(V,...l),m=(C,F)=>{if(F!==void 0){if(C!==2)throw Error("cipher output not supported");_(F)}},R=!1;return{encrypt(C,F){if(R)throw Error("cannot encrypt() twice with same key + nonce");return R=!0,_(C),m(G.encrypt.length,F),G.encrypt(C,F)},decrypt(C,F){if(_(C),K&&C.length<K)throw Error("invalid ciphertext length: smaller than tagLength="+K);return m(G.decrypt.length,F),G.decrypt(C,F)}}}return Object.assign(W,Z),W};function bV(Z,X,W=!0){if(X===void 0)return new Uint8Array(Z);if(X.length!==Z)throw Error("invalid output length, expected "+Z+", got: "+X.length);if(W&&!cK(X))throw Error("invalid output, must be aligned");return X}function cK(Z){return Z.byteOffset%4===0}function GW(Z){return Uint8Array.from(Z)}function cZ(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function mW(Z=32){if(vZ&&typeof vZ.getRandomValues==="function")return vZ.getRandomValues(new Uint8Array(Z));if(vZ&&typeof vZ.randomBytes==="function")return vZ.randomBytes(Z);throw Error("crypto.getRandomValues must be defined")}var hl=(Z)=>Uint8Array.from(Z.split("").map((X)=>X.charCodeAt(0))),kK=hl("expand 16-byte k"),IK=hl("expand 32-byte k"),LK=yZ(kK),pK=yZ(IK);function N(Z,X){return Z<<X|Z>>>32-X}function TV(Z){return Z.byteOffset%4===0}var YW=64,QK=16,Pl=4294967295,Hl=new Uint32Array;function yK(Z,X,W,V,l,K,G,m){let R=l.length,J=new Uint8Array(YW),C=yZ(J),F=TV(l)&&TV(K),b=F?yZ(l):Hl,T=F?yZ(K):Hl;for(let c=0;c<R;G++){if(Z(X,W,V,C,G,m),G>=Pl)throw Error("arx: counter overflow");let k=Math.min(YW,R-c);if(F&&k===YW){let I=c/4;if(c%4!==0)throw Error("arx: invalid block position");for(let Q=0,p;Q<QK;Q++)p=I+Q,T[p]=b[p]^C[Q];c+=YW;continue}for(let I=0,Q;I<k;I++)Q=c+I,K[Q]=l[Q]^J[I];c+=k}}function Ul(Z,X){let{allowShortKeys:W,extendNonceFn:V,counterLength:l,counterRight:K,rounds:G}=Ml({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},X);if(typeof Z!=="function")throw Error("core must be a function");return lW(l),lW(G),dV(K),dV(W),(m,R,J,C,F=0)=>{_(m),_(R),_(J);let b=J.length;if(C===void 0)C=new Uint8Array(b);if(_(C),lW(F),F<0||F>=Pl)throw Error("arx: counter overflow");if(C.length<b)throw Error(`arx: output (${C.length}) is shorter than data (${b})`);let T=[],c=m.length,k,I;if(c===32)T.push(k=GW(m)),I=pK;else if(c===16&&W)k=new Uint8Array(32),k.set(m),k.set(m,16),I=LK,T.push(k);else throw Error(`arx: invalid 32-byte key, got length=${c}`);if(!TV(R))T.push(R=GW(R));let Q=yZ(k);if(V){if(R.length!==24)throw Error("arx: extended nonce must be 24 bytes");V(I,Q,yZ(R.subarray(0,16)),Q),R=R.subarray(16)}let p=16-l;if(p!==R.length)throw Error(`arx: nonce must be ${p} or 16 bytes`);if(p!==12){let L=new Uint8Array(12);L.set(R,K?0:12-R.length),R=L,T.push(R)}let z=yZ(R);return yK(Z,I,Q,z,J,C,F,G),cZ(...T),C}}var t=(Z,X)=>Z[X++]&255|(Z[X++]&255)<<8;class il{constructor(Z){this.blockLen=16,this.outputLen=16,this.buffer=new Uint8Array(16),this.r=new Uint16Array(10),this.h=new Uint16Array(10),this.pad=new Uint16Array(8),this.pos=0,this.finished=!1,Z=KW(Z),_(Z,32);let X=t(Z,0),W=t(Z,2),V=t(Z,4),l=t(Z,6),K=t(Z,8),G=t(Z,10),m=t(Z,12),R=t(Z,14);this.r[0]=X&8191,this.r[1]=(X>>>13|W<<3)&8191,this.r[2]=(W>>>10|V<<6)&7939,this.r[3]=(V>>>7|l<<9)&8191,this.r[4]=(l>>>4|K<<12)&255,this.r[5]=K>>>1&8190,this.r[6]=(K>>>14|G<<2)&8191,this.r[7]=(G>>>11|m<<5)&8065,this.r[8]=(m>>>8|R<<8)&8191,this.r[9]=R>>>5&127;for(let J=0;J<8;J++)this.pad[J]=t(Z,16+2*J)}process(Z,X,W=!1){let V=W?0:2048,{h:l,r:K}=this,G=K[0],m=K[1],R=K[2],J=K[3],C=K[4],F=K[5],b=K[6],T=K[7],c=K[8],k=K[9],I=t(Z,X+0),Q=t(Z,X+2),p=t(Z,X+4),z=t(Z,X+6),L=t(Z,X+8),M=t(Z,X+10),h=t(Z,X+12),E=t(Z,X+14),O=l[0]+(I&8191),i=l[1]+((I>>>13|Q<<3)&8191),j=l[2]+((Q>>>10|p<<6)&8191),y=l[3]+((p>>>7|z<<9)&8191),A=l[4]+((z>>>4|L<<12)&8191),v=l[5]+(L>>>1&8191),H=l[6]+((L>>>14|M<<2)&8191),B=l[7]+((M>>>11|h<<5)&8191),u=l[8]+((h>>>8|E<<8)&8191),w=l[9]+(E>>>5|V),g=0,q=g+O*G+i*(5*k)+j*(5*c)+y*(5*T)+A*(5*b);g=q>>>13,q&=8191,q+=v*(5*F)+H*(5*C)+B*(5*J)+u*(5*R)+w*(5*m),g+=q>>>13,q&=8191;let ZZ=g+O*m+i*G+j*(5*k)+y*(5*c)+A*(5*T);g=ZZ>>>13,ZZ&=8191,ZZ+=v*(5*b)+H*(5*F)+B*(5*C)+u*(5*J)+w*(5*R),g+=ZZ>>>13,ZZ&=8191;let GZ=g+O*R+i*m+j*G+y*(5*k)+A*(5*c);g=GZ>>>13,GZ&=8191,GZ+=v*(5*T)+H*(5*b)+B*(5*F)+u*(5*C)+w*(5*J),g+=GZ>>>13,GZ&=8191;let $=g+O*J+i*R+j*m+y*G+A*(5*k);g=$>>>13,$&=8191,$+=v*(5*c)+H*(5*T)+B*(5*b)+u*(5*F)+w*(5*C),g+=$>>>13,$&=8191;let IZ=g+O*C+i*J+j*R+y*m+A*G;g=IZ>>>13,IZ&=8191,IZ+=v*(5*k)+H*(5*c)+B*(5*T)+u*(5*b)+w*(5*F),g+=IZ>>>13,IZ&=8191;let nZ=g+O*F+i*C+j*J+y*R+A*m;g=nZ>>>13,nZ&=8191,nZ+=v*G+H*(5*k)+B*(5*c)+u*(5*T)+w*(5*b),g+=nZ>>>13,nZ&=8191;let _Z=g+O*b+i*F+j*C+y*J+A*R;g=_Z>>>13,_Z&=8191,_Z+=v*m+H*G+B*(5*k)+u*(5*c)+w*(5*T),g+=_Z>>>13,_Z&=8191;let aZ=g+O*T+i*b+j*F+y*C+A*J;g=aZ>>>13,aZ&=8191,aZ+=v*R+H*m+B*G+u*(5*k)+w*(5*c),g+=aZ>>>13,aZ&=8191;let rZ=g+O*c+i*T+j*b+y*F+A*C;g=rZ>>>13,rZ&=8191,rZ+=v*J+H*R+B*m+u*G+w*(5*k),g+=rZ>>>13,rZ&=8191;let sZ=g+O*k+i*c+j*T+y*b+A*F;g=sZ>>>13,sZ&=8191,sZ+=v*C+H*J+B*R+u*m+w*G,g+=sZ>>>13,sZ&=8191,g=(g<<2)+g|0,g=g+q|0,q=g&8191,g=g>>>13,ZZ+=g,l[0]=q,l[1]=ZZ,l[2]=GZ,l[3]=$,l[4]=IZ,l[5]=nZ,l[6]=_Z,l[7]=aZ,l[8]=rZ,l[9]=sZ}finalize(){let{h:Z,pad:X}=this,W=new Uint16Array(10),V=Z[1]>>>13;Z[1]&=8191;for(let G=2;G<10;G++)Z[G]+=V,V=Z[G]>>>13,Z[G]&=8191;Z[0]+=V*5,V=Z[0]>>>13,Z[0]&=8191,Z[1]+=V,V=Z[1]>>>13,Z[1]&=8191,Z[2]+=V,W[0]=Z[0]+5,V=W[0]>>>13,W[0]&=8191;for(let G=1;G<10;G++)W[G]=Z[G]+V,V=W[G]>>>13,W[G]&=8191;W[9]-=8192;let l=(V^1)-1;for(let G=0;G<10;G++)W[G]&=l;l=~l;for(let G=0;G<10;G++)Z[G]=Z[G]&l|W[G];Z[0]=(Z[0]|Z[1]<<13)&65535,Z[1]=(Z[1]>>>3|Z[2]<<10)&65535,Z[2]=(Z[2]>>>6|Z[3]<<7)&65535,Z[3]=(Z[3]>>>9|Z[4]<<4)&65535,Z[4]=(Z[4]>>>12|Z[5]<<1|Z[6]<<14)&65535,Z[5]=(Z[6]>>>2|Z[7]<<11)&65535,Z[6]=(Z[7]>>>5|Z[8]<<8)&65535,Z[7]=(Z[8]>>>8|Z[9]<<5)&65535;let K=Z[0]+X[0];Z[0]=K&65535;for(let G=1;G<8;G++)K=(Z[G]+X[G]|0)+(K>>>16)|0,Z[G]=K&65535;cZ(W)}update(Z){FV(this);let{buffer:X,blockLen:W}=this;Z=KW(Z);let V=Z.length;for(let l=0;l<V;){let K=Math.min(W-this.pos,V-l);if(K===W){for(;W<=V-l;l+=W)this.process(Z,l);continue}if(X.set(Z.subarray(l,l+K),this.pos),this.pos+=K,l+=K,this.pos===W)this.process(X,0,!1),this.pos=0}return this}destroy(){cZ(this.h,this.r,this.buffer,this.pad)}digestInto(Z){FV(this),Nl(Z,this),this.finished=!0;let{buffer:X,h:W}=this,{pos:V}=this;if(V){X[V++]=1;for(;V<16;V++)X[V]=0;this.process(X,0,!0)}this.finalize();let l=0;for(let K=0;K<8;K++)Z[l++]=W[K]>>>0,Z[l++]=W[K]>>>8;return Z}digest(){let{buffer:Z,outputLen:X}=this;this.digestInto(Z);let W=Z.slice(0,X);return this.destroy(),W}}function zK(Z){let X=(V,l)=>Z(l).update(KW(V)).digest(),W=Z(new Uint8Array(32));return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var cV=zK((Z)=>new il(Z));function xK(Z,X,W,V,l,K=20){let G=Z[0],m=X[0],R=X[1],J=X[2],C=X[3],F=Z[1],b=W[0],T=W[1],c=l,k=0,I=Z[2],Q=X[4],p=X[5],z=X[6],L=X[7],M=Z[3],h=G,E=m,O=R,i=J,j=C,y=F,A=b,v=T,H=c,B=k,u=I,w=Q,g=p,q=z,ZZ=L,GZ=M;for(let IZ=0;IZ<K;IZ+=2)j^=N(h+g|0,7),H^=N(j+h|0,9),g^=N(H+j|0,13),h^=N(g+H|0,18),B^=N(y+E|0,7),q^=N(B+y|0,9),E^=N(q+B|0,13),y^=N(E+q|0,18),ZZ^=N(u+A|0,7),O^=N(ZZ+u|0,9),A^=N(O+ZZ|0,13),u^=N(A+O|0,18),i^=N(GZ+w|0,7),v^=N(i+GZ|0,9),w^=N(v+i|0,13),GZ^=N(w+v|0,18),E^=N(h+i|0,7),O^=N(E+h|0,9),i^=N(O+E|0,13),h^=N(i+O|0,18),A^=N(y+j|0,7),v^=N(A+y|0,9),j^=N(v+A|0,13),y^=N(j+v|0,18),w^=N(u+B|0,7),H^=N(w+u|0,9),B^=N(H+w|0,13),u^=N(B+H|0,18),g^=N(GZ+ZZ|0,7),q^=N(g+GZ|0,9),ZZ^=N(q+g|0,13),GZ^=N(ZZ+q|0,18);let $=0;V[$++]=G+h|0,V[$++]=m+E|0,V[$++]=R+O|0,V[$++]=J+i|0,V[$++]=C+j|0,V[$++]=F+y|0,V[$++]=b+A|0,V[$++]=T+v|0,V[$++]=c+H|0,V[$++]=k+B|0,V[$++]=I+u|0,V[$++]=Q+w|0,V[$++]=p+g|0,V[$++]=z+q|0,V[$++]=L+ZZ|0,V[$++]=M+GZ|0}function NK(Z,X,W,V){let l=Z[0],K=X[0],G=X[1],m=X[2],R=X[3],J=Z[1],C=W[0],F=W[1],b=W[2],T=W[3],c=Z[2],k=X[4],I=X[5],Q=X[6],p=X[7],z=Z[3];for(let M=0;M<20;M+=2)R^=N(l+I|0,7),b^=N(R+l|0,9),I^=N(b+R|0,13),l^=N(I+b|0,18),T^=N(J+K|0,7),Q^=N(T+J|0,9),K^=N(Q+T|0,13),J^=N(K+Q|0,18),p^=N(c+C|0,7),G^=N(p+c|0,9),C^=N(G+p|0,13),c^=N(C+G|0,18),m^=N(z+k|0,7),F^=N(m+z|0,9),k^=N(F+m|0,13),z^=N(k+F|0,18),K^=N(l+m|0,7),G^=N(K+l|0,9),m^=N(G+K|0,13),l^=N(m+G|0,18),C^=N(J+R|0,7),F^=N(C+J|0,9),R^=N(F+C|0,13),J^=N(R+F|0,18),k^=N(c+T|0,7),b^=N(k+c|0,9),T^=N(b+k|0,13),c^=N(T+b|0,18),I^=N(z+p|0,7),Q^=N(I+z|0,9),p^=N(Q+I|0,13),z^=N(p+Q|0,18);let L=0;V[L++]=l,V[L++]=J,V[L++]=c,V[L++]=z,V[L++]=C,V[L++]=F,V[L++]=b,V[L++]=T}var kV=Ul(xK,{counterRight:!0,extendNonceFn:NK}),IV=Sl({blockSize:64,nonceLength:24,tagLength:16},(Z,X)=>{return{encrypt(W,V){V=bV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32);V.set(W,32),cZ(l),kV(Z,X,V,V);let G=cV(K,l);return V.set(G,16),cZ(V.subarray(0,16),G),V.subarray(16)},decrypt(W,V){_(W),V=bV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32,48),G=V.subarray(48);V.set(W,32),cZ(l);let m=kV(Z,X,l,l),R=cV(G,m);if(!gl(K,R))throw Error("invalid tag");return kV(Z,X,V.subarray(16),V.subarray(16)),cZ(l,K,R),G}}});/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function MK(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function MX(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function $Z(Z,...X){if(!MK(Z))throw Error("Uint8Array expected");if(X.length>0&&!X.includes(Z.length))throw Error("Uint8Array expected of length "+X+", got length="+Z.length)}function gX(Z,X=!0){if(Z.destroyed)throw Error("Hash instance has been destroyed");if(X&&Z.finished)throw Error("Hash#digest() has already been called")}function RW(Z,X){$Z(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function ul(Z){return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength)}function CX(Z){return new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4))}function FX(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function SX(Z,X){return Z<<32-X|Z>>>X}var Ol=(()=>new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68)();function El(Z){return Z<<24&4278190080|Z<<8&16711680|Z>>>8&65280|Z>>>24&255}var Bl=Ol?(Z)=>Z:(Z)=>El(Z);function gK(Z){for(let X=0;X<Z.length;X++)Z[X]=El(Z[X]);return Z}var VZ=Ol?(Z)=>Z:gK;function SK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function dX(Z){if(typeof Z==="string")Z=SK(Z);return $Z(Z),Z}class LV{}function jl(Z){let X=(V,l)=>Z(l).update(dX(V)).digest(),W=Z({});return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var wl=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var JW=BigInt(4294967295),Dl=BigInt(32);function pV(Z,X=!1){if(X)return{h:Number(Z&JW),l:Number(Z>>Dl&JW)};return{h:Number(Z>>Dl&JW)|0,l:Number(Z&JW)|0}}function zZ(Z,X,W,V,l){return Z=Z+X+l|0,V=SX(V^Z,16),W=W+V|0,X=SX(X^W,12),{a:Z,b:X,c:W,d:V}}function xZ(Z,X,W,V,l){return Z=Z+X+l|0,V=SX(V^Z,8),W=W+V|0,X=SX(X^W,7),{a:Z,b:X,c:W,d:V}}class QV extends LV{constructor(Z,X){super();this.finished=!1,this.destroyed=!1,this.length=0,this.pos=0,MX(Z),MX(X),this.blockLen=Z,this.outputLen=X,this.buffer=new Uint8Array(Z),this.buffer32=CX(this.buffer)}update(Z){gX(this),Z=dX(Z),$Z(Z);let{blockLen:X,buffer:W,buffer32:V}=this,l=Z.length,K=Z.byteOffset,G=Z.buffer;for(let m=0;m<l;){if(this.pos===X)VZ(V),this.compress(V,0,!1),VZ(V),this.pos=0;let R=Math.min(X-this.pos,l-m),J=K+m;if(R===X&&!(J%4)&&m+R<l){let C=new Uint32Array(G,J,Math.floor((l-m)/4));VZ(C);for(let F=0;m+X<l;F+=V.length,m+=X)this.length+=X,this.compress(C,F,!1);VZ(C);continue}W.set(Z.subarray(m,m+R),this.pos),this.pos+=R,this.length+=R,m+=R}return this}digestInto(Z){gX(this),RW(Z,this);let{pos:X,buffer32:W}=this;this.finished=!0,FX(this.buffer.subarray(X)),VZ(W),this.compress(W,0,!0),VZ(W);let V=CX(Z);this.get().forEach((l,K)=>V[K]=Bl(l))}digest(){let{buffer:Z,outputLen:X}=this;this.digestInto(Z);let W=Z.slice(0,X);return this.destroy(),W}_cloneInto(Z){let{buffer:X,length:W,finished:V,destroyed:l,outputLen:K,pos:G}=this;return Z||(Z=new this.constructor({dkLen:K})),Z.set(...this.get()),Z.buffer.set(X),Z.destroyed=l,Z.finished=V,Z.length=W,Z.pos=G,Z.outputLen=K,Z}clone(){return this._cloneInto()}}function yV(Z,X,W,V,l,K,G,m,R,J,C,F,b,T,c,k,I,Q,p,z){let L=0;for(let M=0;M<V;M++)({a:l,b:R,c:b,d:I}=zZ(l,R,b,I,W[X+Z[L++]])),{a:l,b:R,c:b,d:I}=xZ(l,R,b,I,W[X+Z[L++]]),{a:K,b:J,c:T,d:Q}=zZ(K,J,T,Q,W[X+Z[L++]]),{a:K,b:J,c:T,d:Q}=xZ(K,J,T,Q,W[X+Z[L++]]),{a:G,b:C,c,d:p}=zZ(G,C,c,p,W[X+Z[L++]]),{a:G,b:C,c,d:p}=xZ(G,C,c,p,W[X+Z[L++]]),{a:m,b:F,c:k,d:z}=zZ(m,F,k,z,W[X+Z[L++]]),{a:m,b:F,c:k,d:z}=xZ(m,F,k,z,W[X+Z[L++]]),{a:l,b:J,c,d:z}=zZ(l,J,c,z,W[X+Z[L++]]),{a:l,b:J,c,d:z}=xZ(l,J,c,z,W[X+Z[L++]]),{a:K,b:C,c:k,d:I}=zZ(K,C,k,I,W[X+Z[L++]]),{a:K,b:C,c:k,d:I}=xZ(K,C,k,I,W[X+Z[L++]]),{a:G,b:F,c:b,d:Q}=zZ(G,F,b,Q,W[X+Z[L++]]),{a:G,b:F,c:b,d:Q}=xZ(G,F,b,Q,W[X+Z[L++]]),{a:m,b:R,c:T,d:p}=zZ(m,R,T,p,W[X+Z[L++]]),{a:m,b:R,c:T,d:p}=xZ(m,R,T,p,W[X+Z[L++]]);return{v0:l,v1:K,v2:G,v3:m,v4:R,v5:J,v6:C,v7:F,v8:b,v9:T,v10:c,v11:k,v12:I,v13:Q,v14:p,v15:z}}var kZ={CHUNK_START:1,CHUNK_END:2,PARENT:4,ROOT:8,KEYED_HASH:16,DERIVE_KEY_CONTEXT:32,DERIVE_KEY_MATERIAL:64},NZ=wl.slice(),Al=(()=>{let Z=Array.from({length:16},(V,l)=>l),X=(V)=>[2,6,3,10,7,0,4,13,1,11,12,5,9,14,15,8].map((l)=>V[l]),W=[];for(let V=0,l=Z;V<7;V++,l=X(l))W.push(...l);return Uint8Array.from(W)})();class zV extends QV{constructor(Z={},X=0){super(64,Z.dkLen===void 0?32:Z.dkLen);this.chunkPos=0,this.chunksDone=0,this.flags=0,this.stack=[],this.posOut=0,this.bufferOut32=new Uint32Array(16),this.chunkOut=0,this.enableXOF=!0;let{key:W,context:V}=Z,l=V!==void 0;if(W!==void 0){if(l)throw Error('Only "key" or "context" can be specified at same time');let K=dX(W).slice();$Z(K,32),this.IV=CX(K),VZ(this.IV),this.flags=X|kZ.KEYED_HASH}else if(l){let K=dX(V),G=new zV({dkLen:32},kZ.DERIVE_KEY_CONTEXT).update(K).digest();this.IV=CX(G),VZ(this.IV),this.flags=X|kZ.DERIVE_KEY_MATERIAL}else this.IV=NZ.slice(),this.flags=X;this.state=this.IV.slice(),this.bufferOut=ul(this.bufferOut32)}get(){return[]}set(){}b2Compress(Z,X,W,V=0){let{state:l,pos:K}=this,{h:G,l:m}=pV(BigInt(Z),!0),{v0:R,v1:J,v2:C,v3:F,v4:b,v5:T,v6:c,v7:k,v8:I,v9:Q,v10:p,v11:z,v12:L,v13:M,v14:h,v15:E}=yV(Al,V,W,7,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],NZ[0],NZ[1],NZ[2],NZ[3],G,m,K,X);l[0]=R^I,l[1]=J^Q,l[2]=C^p,l[3]=F^z,l[4]=b^L,l[5]=T^M,l[6]=c^h,l[7]=k^E}compress(Z,X=0,W=!1){let V=this.flags;if(!this.chunkPos)V|=kZ.CHUNK_START;if(this.chunkPos===15||W)V|=kZ.CHUNK_END;if(!W)this.pos=this.blockLen;if(this.b2Compress(this.chunksDone,V,Z,X),this.chunkPos+=1,this.chunkPos===16||W){let l=this.state;this.state=this.IV.slice();for(let K,G=this.chunksDone+1;W||!(G&1);G>>=1){if(!(K=this.stack.pop()))break;this.buffer32.set(K,0),this.buffer32.set(l,8),this.pos=this.blockLen,this.b2Compress(0,this.flags|kZ.PARENT,this.buffer32,0),l=this.state,this.state=this.IV.slice()}this.chunksDone++,this.chunkPos=0,this.stack.push(l)}this.pos=0}_cloneInto(Z){Z=super._cloneInto(Z);let{IV:X,flags:W,state:V,chunkPos:l,posOut:K,chunkOut:G,stack:m,chunksDone:R}=this;return Z.state.set(V.slice()),Z.stack=m.map((J)=>Uint32Array.from(J)),Z.IV.set(X),Z.flags=W,Z.chunkPos=l,Z.chunksDone=R,Z.posOut=K,Z.chunkOut=G,Z.enableXOF=this.enableXOF,Z.bufferOut32.set(this.bufferOut32),Z}destroy(){this.destroyed=!0,FX(this.state,this.buffer32,this.IV,this.bufferOut32),FX(...this.stack)}b2CompressOut(){let{state:Z,pos:X,flags:W,buffer32:V,bufferOut32:l}=this,{h:K,l:G}=pV(BigInt(this.chunkOut++));VZ(V);let{v0:m,v1:R,v2:J,v3:C,v4:F,v5:b,v6:T,v7:c,v8:k,v9:I,v10:Q,v11:p,v12:z,v13:L,v14:M,v15:h}=yV(Al,0,V,7,Z[0],Z[1],Z[2],Z[3],Z[4],Z[5],Z[6],Z[7],NZ[0],NZ[1],NZ[2],NZ[3],G,K,X,W);l[0]=m^k,l[1]=R^I,l[2]=J^Q,l[3]=C^p,l[4]=F^z,l[5]=b^L,l[6]=T^M,l[7]=c^h,l[8]=Z[0]^k,l[9]=Z[1]^I,l[10]=Z[2]^Q,l[11]=Z[3]^p,l[12]=Z[4]^z,l[13]=Z[5]^L,l[14]=Z[6]^M,l[15]=Z[7]^h,VZ(V),VZ(l),this.posOut=0}finish(){if(this.finished)return;this.finished=!0,FX(this.buffer.subarray(this.pos));let Z=this.flags|kZ.ROOT;if(this.stack.length)Z|=kZ.PARENT,VZ(this.buffer32),this.compress(this.buffer32,0,!0),VZ(this.buffer32),this.chunksDone=0,this.pos=this.blockLen;else Z|=(!this.chunkPos?kZ.CHUNK_START:0)|kZ.CHUNK_END;this.flags=Z,this.b2CompressOut()}writeInto(Z){gX(this,!1),$Z(Z),this.finish();let{blockLen:X,bufferOut:W}=this;for(let V=0,l=Z.length;V<l;){if(this.posOut>=X)this.b2CompressOut();let K=Math.min(X-this.posOut,l-V);Z.set(W.subarray(this.posOut,this.posOut+K),V),this.posOut+=K,V+=K}return Z}xofInto(Z){if(!this.enableXOF)throw Error("XOF is not possible after digest call");return this.writeInto(Z)}xof(Z){return MX(Z),this.xofInto(new Uint8Array(Z))}digestInto(Z){if(RW(Z,this),this.finished)throw Error("digest() was already called");return this.enableXOF=!1,this.writeInto(Z),this.destroy(),Z}digest(){return this.digestInto(new Uint8Array(this.outputLen))}}var ol=jl((Z)=>new zV(Z));var xV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function vl(Z){let X=new Uint8Array(xV.length+32);return X.set(xV),X.set(Z.subarray(0,32),xV.length),X}function $l(Z){return typeof Z==="string"?new TextEncoder().encode(Z):Z}function bX(Z){let X=new ArrayBuffer(Z.byteLength);return new Uint8Array(X).set(Z),X}class NV{verifyKeys=new Map;async genRandomBytes(Z){return mW(Z)}async gen256BitSecureRandomSeed(){return mW(32)}async encryptXSalsa20Poly1305Combined(Z,X){let W=mW(24),l=IV(X,W).encrypt(Z);return new Uint8Array([...W,...l])}async decryptXSalsa20Poly1305Combined(Z,X){let W=Z.slice(0,24),V=Z.slice(24);return IV(X,W).decrypt(V)}async deriveEd25519KeyPair(Z){let X=Z,W=vl(X),V=bX(W),l;try{let J=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!0,["sign"]);l=await globalThis.crypto.subtle.exportKey("jwk",J)}finally{W.fill(0),new Uint8Array(V).fill(0)}if(typeof l.x!=="string")throw Error("Ed25519 JWK missing x");let K=l.x;l.d=void 0;let G=await globalThis.crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:K},{name:"Ed25519"},!0,["verify"]),m=new Uint8Array(await globalThis.crypto.subtle.exportKey("raw",G));this.verifyKeys.set(mZ(m),G);let R=new Uint8Array(64);return R.set(X,0),R.set(m,32),{keyType:"ed25519",privateKey:R,publicKey:m}}async importSignKey(Z){let X=Z.subarray(0,32),W=vl(X),V=bX(W);try{return await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!1,["sign"])}finally{W.fill(0),new Uint8Array(V).fill(0)}}async importVerifyKey(Z){let X=mZ(Z),W=this.verifyKeys.get(X);if(W)return W;let V=await globalThis.crypto.subtle.importKey("raw",bX(Z),{name:"Ed25519"},!1,["verify"]);return this.verifyKeys.set(X,V),V}async signEd25519(Z,X){let W=$l(Z),V=await this.importSignKey(X),l=await globalThis.crypto.subtle.sign({name:"Ed25519"},V,bX(W));return new Uint8Array(l)}async checkSigEd25519(Z,X,W){let V=$l(X);try{let l=await this.importVerifyKey(W);return await globalThis.crypto.subtle.verify({name:"Ed25519"},l,bX(Z),bX(V))}catch{return!1}}async blake3(Z){return ol(Z)}}var HK=new NV,MZ=HK;import{useEffect as SW,useState as OV}from"react";class MV{db;constructor(Z){this.db=Z}async enq(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(JZ,"readwrite"),V=W.objectStore(JZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=`${G.host}:${G.seq}`;V.put(G,m)}})}async deq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(JZ,"readwrite"),l=V.objectStore(JZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=`${Z}:${m}`;l.delete(R)}})}async list(){let X=this.db.transaction(JZ,"readonly").objectStore(JZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async count(){let X=this.db.transaction(JZ,"readonly").objectStore(JZ);return new Promise((W,V)=>{let l=X.count();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(JZ,"readwrite"),X=Z.objectStore(JZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}function fl(Z){return{label:Z.label,handle:new URL(Z.handle),idx:Z.idx,lastSeq:Z.lastSeq||0,clockOffset:Z.clockOffset,subscription:Z.subscription}}function hK(Z,X){let W={...Z};if(X.setLastSeq!==void 0)W.lastSeq=X.setLastSeq;else if(X.lastSeq!==void 0){let V=W.lastSeq||0;if(X.lastSeq>V)W.lastSeq=X.lastSeq}return delete W.numBags,delete W.numDupes,W}class gV{db;constructor(Z){this.db=Z}async add(Z){let X=await this.get(Z.label),W=X!==void 0&&X.handle.href===Z.handle.href&&(X.idx??0)===(Z.idx??0);return this.put({...Z,lastSeq:W?X.lastSeq:0,clockOffset:W?X.clockOffset:void 0,subscription:W?X.subscription:void 0})}async put(Z){let X={...Z,handle:Z.handle.toString(),lastSeq:Z.lastSeq??0},W=this.db.transaction(lZ,"readwrite"),V=W.objectStore(lZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error),V.put(X)})}async touch(Z,X){return this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.db.transaction(lZ,"readwrite"),V=W.objectStore(lZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);let G=V.get(Z);G.onsuccess=()=>{let m=G.result;if(!m)return;V.put(hK(m,X))}})}async get(Z){let W=this.db.transaction(lZ,"readonly").objectStore(lZ);return new Promise((V,l)=>{let K=W.get(Z);K.onsuccess=()=>{let G=K.result;if(!G)V(void 0);else V(fl(G))},K.onerror=()=>l(K.error)})}async set(Z,X){let W=await this.get(Z);if(!W)return 13;try{return await this.put({...W,...X}),0}catch{return 18}}async del(Z){let X=this.db.transaction(lZ,"readwrite"),W=X.objectStore(lZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}async list(){let X=this.db.transaction(lZ,"readonly").objectStore(lZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>{let K=l.result;W(K.map(fl))},l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(lZ,"readwrite"),X=Z.objectStore(lZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}class SV{crypto;db;constructor(Z,X){this.crypto=X;this.db=Z}async add(Z){let X=this.db.transaction(o,"readwrite"),W=X.objectStore(o);return new Promise((V)=>{if(Z.length===0){V([]);return}let l=Array(Z.length).fill(0);X.oncomplete=()=>V(l),X.onerror=()=>{for(let K=0;K<l.length;K++)l[K]=18;V(l)};for(let K=0;K<Z.length;K++){let{key:G,data:m}=Z[K],R=S(G),J=W.put(m,R);J.onerror=(C)=>{C.preventDefault(),l[K]=18}}})}async del(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(o,"readwrite"),V=W.objectStore(o);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=S(G);V.delete(m)}})}async get(Z){let W=this.db.transaction(o,"readonly").objectStore(o);return new Promise((V,l)=>{let K=S(Z),G=W.get(K);G.onsuccess=async()=>{let m=G.result;if(m)V(await iZ(Z,m,this.crypto));else V(void 0)},G.onerror=()=>l(G.error)})}async has(Z){return await this.get(Z)!==void 0}async list(Z){let X=Z?.apld,W=Z?.body!==!1,l=this.db.transaction(o,"readonly").objectStore(o);return new Promise((K,G)=>{let m=[],R=X===void 0?l.openCursor():l.index(HX).openCursor(IDBKeyRange.only(X));R.onsuccess=(J)=>{let C=J.target.result;if(C){let F=X===void 0?C.key:C.primaryKey,b=C.value;m.push({hash:e(F),data:b}),C.continue()}else Promise.all(m.map(({hash:F,data:b})=>iZ(F,b,this.crypto,{body:W}))).then(K).catch(G)},R.onerror=()=>G(R.error)})}async count(Z){let W=this.db.transaction(o,"readonly").objectStore(o);return new Promise((V,l)=>{let K=Z===void 0?W.count():W.index(HX).count(IDBKeyRange.only(Z));K.onsuccess=()=>V(K.result),K.onerror=()=>l(K.error)})}async listKeys(){let X=this.db.transaction(o,"readonly").objectStore(o);return new Promise((W,V)=>{let l=[],K=X.openKeyCursor();K.onsuccess=(G)=>{let m=G.target.result;if(m)l.push(e(m.key)),m.continue();else W(l)},K.onerror=()=>V(K.error)})}async last(Z){let W=this.db.transaction(o,"readonly").objectStore(o);return new Promise((V,l)=>{let K,G=W.openCursor();G.onsuccess=async(m)=>{let R=m.target.result;if(R){let{key:J,value:C}=R;if(n(Z,C.eid)){if(!K||(C.ctr??0)>(K.data.ctr??0)||(C.ctr??0)===(K.data.ctr??0)&&(C.off??0)>(K.data.off??0))K={key:J,data:C}}R.continue()}else if(K){let J=e(K.key);V(await iZ(J,K.data,this.crypto))}else V(void 0)},G.onerror=()=>l(G.error)})}async markApplied(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(o,"readwrite"),V=W.objectStore(o);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=S(G),R=V.get(m);R.onsuccess=()=>{let J=R.result;if(!J)return;AZ(J,UZ),V.put(J,m)},R.onerror=(J)=>{J.preventDefault()}}})}async markFailed(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(o,"readwrite"),V=W.objectStore(o);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let{key:G,err:m}of X){let R=S(G),J=V.get(R);J.onsuccess=()=>{let C=J.result;if(!C)return;AZ(C,TZ,m),V.put(C,R)},J.onerror=(C)=>{C.preventDefault()}}})}async wipe(){let Z=this.db.transaction(o,"readwrite"),X=Z.objectStore(o);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var fZ={encode(Z,X){let W=Z.writeVarString(X.handle);if(W!==0)return W;let V=Z.writeVarString(X.label);if(V!==0)return V;return Z.writeVarInt(X.idx??0)},decode(Z){let[X,W]=Z.readVarString();if(W!==0)return Y(W);let[V,l]=Z.readVarString();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);return d({handle:X,label:V,idx:K})}};var CW=1,HV={encode(Z,X){if(X.v!==CW)return 10;let[,W]=WZ(X.masterSeed);if(W!==0)return W;let V=Z.writeVarInt(X.v);if(V!==0)return V;Z.writeBytes(X.masterSeed);let l=Z.writeVarInt(X.hosts.length);if(l!==0)return l;for(let K of X.hosts){let G=Z.writeStruct(fZ,K);if(G!==0)return G}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X!==CW)return Y(14);let[V,l]=Z.readBytes(dZ);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=WZ(V);if(G!==0)return Y(G);if(K===void 0)return Y(14);let[m,R]=Z.readVarInt();if(R!==0)return Y(R);if(m===void 0||m<0)return Y(10);let J=[];for(let C=0;C<m;C++){let[F,b]=Z.readStruct(fZ);if(b!==0)return Y(b);if(F===void 0)return Y(14);J.push(F)}return d({v:CW,masterSeed:K,hosts:J})}};function ql(Z,X){let[W,V]=WZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(10);let[l,K]=WZ(W.slice());if(K!==0)return Y(K);if(l===void 0)return Y(10);return d({v:CW,masterSeed:l,hosts:X.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))})}var FW={encode(Z,X){let[,W]=WZ(X.masterSeed);if(W!==0)return W;Z.writeBytes(X.masterSeed);let V=Z.writeVarInt(X.hosts.length);if(V!==0)return V;for(let l of X.hosts){let K=Z.writeStruct(fZ,l);if(K!==0)return K}return 0},decode(Z){let[X,W]=Z.readBytes(dZ);if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=WZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);if(K===void 0||K<0)return Y(10);let m=[];for(let R=0;R<K;R++){let[J,C]=Z.readStruct(fZ);if(C!==0)return Y(C);if(J===void 0)return Y(14);m.push(J)}return d({masterSeed:V,hosts:m})}};function gZ(Z){let X=new Uint8Array(Z);if(Z>0)crypto.getRandomValues(X);return X}var uZ=32,nl=-7,_l=-8,al=-257,hX=[{type:"public-key",alg:nl},{type:"public-key",alg:_l},{type:"public-key",alg:al}];function dW(Z){return Z.trim().toLowerCase().replace(/\.$/,"")||"localhost"}function OZ(Z){let X=new Uint8Array(Z.byteLength);return X.set(Z),X.buffer}function rl(Z){if(Z instanceof ArrayBuffer)return new Uint8Array(Z).slice();return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength).slice()}function EZ(Z){if(Z?.rpId!==void 0)return d(Z.rpId);if(typeof location>"u")return Y(9);return d(dW(location.hostname))}function BZ(){if(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")return 24;return 0}function jZ(Z){if(Z===null||Z.type!=="public-key"||!("rawId"in Z)||typeof Z.getClientExtensionResults!=="function")return Y(27);return d(Z)}async function PX(Z){if(typeof PublicKeyCredential>"u")return!1;let X=PublicKeyCredential.getClientCapabilities;if(typeof X!=="function")return!0;let W=await X.call(PublicKeyCredential);if(Z in W)return W[Z]===!0;return!0}function sl(){return PX("extension:largeBlob")}async function bW(Z){let X=BZ();if(X!==0)return Y(X);let[W,V]=EZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-seed",K={residentKey:"required",requireResidentKey:!0,userVerification:"required"};if(Z?.authenticatorAttachment!==void 0)K.authenticatorAttachment=Z.authenticatorAttachment;let G={largeBlob:{support:"required"}},m;try{m=await navigator.credentials.create({publicKey:{challenge:gZ(uZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:gZ(16),name:l,displayName:l},pubKeyCredParams:hX,authenticatorSelection:K,extensions:G}})}catch{return Y(24)}let[R,J]=jZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);if(R.getClientExtensionResults().largeBlob?.supported!==!0)return Y(24);return d(new Uint8Array(R.rawId))}async function UX(Z,X,W){let V=BZ();if(V!==0)return V;let[l,K]=EZ(W);if(K!==0)return K;if(l===void 0)return 9;let G={largeBlob:{write:OZ(X)}},m;try{m=await navigator.credentials.get({publicKey:{challenge:gZ(uZ),rpId:l,allowCredentials:[{type:"public-key",id:OZ(Z)}],userVerification:"required",extensions:G}})}catch{return 24}let[R,J]=jZ(m);if(J!==0)return J;if(R===void 0)return 27;if(R.getClientExtensionResults().largeBlob?.written!==!0)return 24;return 0}async function TW(Z,X){let W=BZ();if(W!==0)return Y(W);let[V,l]=EZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(9);let K={largeBlob:{read:!0}},G;try{let b={challenge:gZ(uZ),rpId:V,userVerification:"required",extensions:K};if(Z!==void 0)b.allowCredentials=[{type:"public-key",id:OZ(Z)}];G=await navigator.credentials.get({publicKey:b})}catch{return Y(24)}let[m,R]=jZ(G);if(R!==0)return Y(R);if(m===void 0)return Y(27);let C=m.getClientExtensionResults().largeBlob;if(C===void 0||C.blob===void 0)return Y(7);let F=rl(C.blob);if(F.byteLength===0)return Y(7);return d({blob:F,credId:new Uint8Array(m.rawId)})}var iX=new TextEncoder().encode("diplomatic.prf.v1"),hV=32;async function PK(){return PX("extension:prf")}async function tl(Z){let X=BZ();if(X!==0)return Y(X);let[W,V]=EZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-prf",K={residentKey:"required",requireResidentKey:!0,userVerification:"required",authenticatorAttachment:Z?.authenticatorAttachment??"platform"},G;try{G=await navigator.credentials.create({publicKey:{challenge:gZ(uZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:gZ(16),name:l,displayName:l},pubKeyCredParams:hX,authenticatorSelection:K,extensions:{prf:{}}}})}catch{return Y(24)}let[m,R]=jZ(G);if(R!==0)return Y(R);if(m===void 0)return Y(27);let J=m.getClientExtensionResults();return d({credId:new Uint8Array(m.rawId),prfEnabled:J.prf?.enabled===!0})}async function uX(Z){let X=BZ();if(X!==0)return Y(X);let[W,V]=EZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.salt??iX,K=OZ(l),G={challenge:gZ(uZ),rpId:W,userVerification:"required",extensions:{prf:{eval:{first:K}}}};if(Z?.credId!==void 0)G.allowCredentials=[{type:"public-key",id:OZ(Z.credId)}];let m;try{m=await navigator.credentials.get({publicKey:G})}catch{return Y(24)}let[R,J]=jZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);let C=R.getClientExtensionResults().prf?.results;if(C?.first===void 0)return Y(7);let F=C.first,b=F instanceof ArrayBuffer?new Uint8Array(F):new Uint8Array(F.buffer,F.byteOffset,F.byteLength),T=b.byteLength>=hV?b.slice(0,hV):b;if(T.byteLength!==hV)return Y(27);return d({prf:T,credId:new Uint8Array(R.rawId)})}var cW="dmFyIHcwPTY0O3ZhciBXSj0zMixUMD04O3ZhciBIJD0zMjt2YXIgR0o9MzAwMDAseko9NTEyLEQ7KCh3KT0+e3dbdy5TdWNjZXNzPTBdPSJTdWNjZXNzIjt3W3cuSW52YWxpZFNpZ25hdHVyZT0zXT0iSW52YWxpZFNpZ25hdHVyZSI7d1t3LkNsb2NrT3V0T2ZTeW5jPTRdPSJDbG9ja091dE9mU3luYyI7d1t3LlVzZXJOb3RSZWdpc3RlcmVkPTVdPSJVc2VyTm90UmVnaXN0ZXJlZCI7d1t3LlNlcnZlck1pc2NvbmZpZ3VyZWQ9Nl09IlNlcnZlck1pc2NvbmZpZ3VyZWQiO3dbdy5NaXNzaW5nQm9keT03XT0iTWlzc2luZ0JvZHkiO3dbdy5FeHRyYUJvZHlDb250ZW50PThdPSJFeHRyYUJvZHlDb250ZW50Ijt3W3cuTWlzc2luZ1BhcmFtPTldPSJNaXNzaW5nUGFyYW0iO3dbdy5JbnZhbGlkUGFyYW09MTBdPSJJbnZhbGlkUGFyYW0iO3dbdy5JbnZhbGlkUmVxdWVzdD0xMV09IkludmFsaWRSZXF1ZXN0Ijt3W3cuSW50ZXJuYWxFcnJvcj0xMl09IkludGVybmFsRXJyb3IiO3dbdy5Ob3RGb3VuZD0xM109Ik5vdEZvdW5kIjt3W3cuSW52YWxpZE1lc3NhZ2U9MTRdPSJJbnZhbGlkTWVzc2FnZSI7d1t3Lk5vQ2hhbmdlPTE1XT0iTm9DaGFuZ2UiO3dbdy5EYXRhYmFzZUNsb3NlZD0xNl09IkRhdGFiYXNlQ2xvc2VkIjt3W3cuU3RvcmFnZUVycm9yPTE3XT0iU3RvcmFnZUVycm9yIjt3W3cuRGF0YWJhc2VFcnJvcj0xOF09IkRhdGFiYXNlRXJyb3IiO3dbdy5IYXNoTWlzbWF0Y2g9MTldPSJIYXNoTWlzbWF0Y2giO3dbdy5EZWNyeXB0aW9uRXJyb3I9MjBdPSJEZWNyeXB0aW9uRXJyb3IiO3dbdy5Ob3RJbXBsZW1lbnRlZD0yMV09Ik5vdEltcGxlbWVudGVkIjt3W3cuTWlzc2luZ1NlZWQ9MjJdPSJNaXNzaW5nU2VlZCI7d1t3Lk91dE9mQm91bmRzPTIzXT0iT3V0T2ZCb3VuZHMiO3dbdy5Ib3N0RXJyb3I9MjRdPSJIb3N0RXJyb3IiO3dbdy5Db21tdW5pY2F0aW9uRXJyb3I9MjVdPSJDb21tdW5pY2F0aW9uRXJyb3IiO3dbdy5WYXJMaW1pdEV4Y2VlZGVkPTI2XT0iVmFyTGltaXRFeGNlZWRlZCI7d1t3LkludmFsaWRSZXNwb25zZT0yN109IkludmFsaWRSZXNwb25zZSI7d1t3LkNvbm5lY3Rpb25DbG9zZWQ9MjhdPSJDb25uZWN0aW9uQ2xvc2VkIn0pKER8fD17fSk7ZnVuY3Rpb24gS0ooJCl7aWYoISR8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuITE7aWYoISgib3AiaW4gJCl8fCEoImlkImluICQpKXJldHVybiExO3JldHVybiB0eXBlb2YgJC5vcD09PSJzdHJpbmciJiZ0eXBlb2YgJC5pZD09PSJudW1iZXIifWZ1bmN0aW9uIEZKKCQpe2xldCBaPSQubGVuZ3RoLEo9MCxRPTA7d2hpbGUoUTxaKXtsZXQgWD0kLmNoYXJDb2RlQXQoUSsrKTtpZigoWCY0Mjk0OTY3MTY4KT09PTApe0orKztjb250aW51ZX1lbHNlIGlmKChYJjQyOTQ5NjUyNDgpPT09MClKKz0yO2Vsc2V7aWYoWD49NTUyOTYmJlg8PTU2MzE5KXtpZihRPFope2xldCBZPSQuY2hhckNvZGVBdChRKTtpZigoWSY2NDUxMik9PT01NjMyMCkrK1EsWD0oKFgmMTAyMyk8PDEwKSsoWSYxMDIzKSs2NTUzNn19aWYoKFgmNDI5NDkwMTc2MCk9PT0wKUorPTM7ZWxzZSBKKz00fX1yZXR1cm4gSn1mdW5jdGlvbiB5USgkLFosSil7bGV0IFE9JC5sZW5ndGgsWD1KLFk9MDt3aGlsZShZPFEpe2xldCBWPSQuY2hhckNvZGVBdChZKyspO2lmKChWJjQyOTQ5NjcxNjgpPT09MCl7WltYKytdPVY7Y29udGludWV9ZWxzZSBpZigoViY0Mjk0OTY1MjQ4KT09PTApWltYKytdPVY+PjYmMzF8MTkyO2Vsc2V7aWYoVj49NTUyOTYmJlY8PTU2MzE5KXtpZihZPFEpe2xldCBXPSQuY2hhckNvZGVBdChZKTtpZigoVyY2NDUxMik9PT01NjMyMCkrK1ksVj0oKFYmMTAyMyk8PDEwKSsoVyYxMDIzKSs2NTUzNn19aWYoKFYmNDI5NDkwMTc2MCk9PT0wKVpbWCsrXT1WPj4xMiYxNXwyMjQsWltYKytdPVY+PjYmNjN8MTI4O2Vsc2UgWltYKytdPVY+PjE4Jjd8MjQwLFpbWCsrXT1WPj4xMiY2M3wxMjgsWltYKytdPVY+PjYmNjN8MTI4fVpbWCsrXT1WJjYzfDEyOH19dmFyIGhRPW5ldyBUZXh0RW5jb2RlcixpUT01MDtmdW5jdGlvbiBsUSgkLFosSil7aFEuZW5jb2RlSW50bygkLFouc3ViYXJyYXkoSikpfWZ1bmN0aW9uIE5KKCQsWixKKXtpZigkLmxlbmd0aD5pUSlsUSgkLFosSik7ZWxzZSB5USgkLFosSil9dmFyIHVRPTQwOTY7ZnVuY3Rpb24gZSQoJCxaLEope2xldCBRPVosWD1RK0osWT1bXSxWPSIiO3doaWxlKFE8WCl7bGV0IFc9JFtRKytdO2lmKChXJjEyOCk9PT0wKVkucHVzaChXKTtlbHNlIGlmKChXJjIyNCk9PT0xOTIpe2xldCB6PSRbUSsrXSY2MztZLnB1c2goKFcmMzEpPDw2fHopfWVsc2UgaWYoKFcmMjQwKT09PTIyNCl7bGV0IHo9JFtRKytdJjYzLEs9JFtRKytdJjYzO1kucHVzaCgoVyYzMSk8PDEyfHo8PDZ8Syl9ZWxzZSBpZigoVyYyNDgpPT09MjQwKXtsZXQgej0kW1ErK10mNjMsSz0kW1ErK10mNjMsRj0kW1ErK10mNjMsTj0oVyY3KTw8MTh8ejw8MTJ8Szw8NnxGO2lmKE4+NjU1MzUpTi09NjU1MzYsWS5wdXNoKE4+Pj4xMCYxMDIzfDU1Mjk2KSxOPTU2MzIwfE4mMTAyMztZLnB1c2goTil9ZWxzZSBZLnB1c2goVyk7aWYoWS5sZW5ndGg+PXVRKVYrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uWSksWS5sZW5ndGg9MH1pZihZLmxlbmd0aD4wKVYrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uWSk7cmV0dXJuIFZ9dmFyIHBRPW5ldyBUZXh0RGVjb2RlcixjUT0yMDA7ZnVuY3Rpb24gblEoJCxaLEope2xldCBRPSQuc3ViYXJyYXkoWixaK0opO3JldHVybiBwUS5kZWNvZGUoUSl9ZnVuY3Rpb24gUkooJCxaLEope2lmKEo+Y1EpcmV0dXJuIG5RKCQsWixKKTtlbHNlIHJldHVybiBlJCgkLFosSil9Y2xhc3MgdTB7dHlwZTtkYXRhO2NvbnN0cnVjdG9yKCQsWil7dGhpcy50eXBlPSQsdGhpcy5kYXRhPVp9fWNsYXNzIHQgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcigkKXtzdXBlcigkKTtsZXQgWj1PYmplY3QuY3JlYXRlKHQucHJvdG90eXBlKTtPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcyxaKSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibmFtZSIse2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiExLHZhbHVlOnQubmFtZX0pfX12YXIgcDA9NDI5NDk2NzI5NTtmdW5jdGlvbiBPSigkLFosSil7bGV0IFE9Si80Mjk0OTY3Mjk2LFg9SjskLnNldFVpbnQzMihaLFEpLCQuc2V0VWludDMyKForNCxYKX1mdW5jdGlvbiBNJCgkLFosSil7bGV0IFE9TWF0aC5mbG9vcihKLzQyOTQ5NjcyOTYpLFg9SjskLnNldFVpbnQzMihaLFEpLCQuc2V0VWludDMyKForNCxYKX1mdW5jdGlvbiBJJCgkLFope2xldCBKPSQuZ2V0SW50MzIoWiksUT0kLmdldFVpbnQzMihaKzQpO3JldHVybiBKKjQyOTQ5NjcyOTYrUX1mdW5jdGlvbiBVSigkLFope2xldCBKPSQuZ2V0VWludDMyKFopLFE9JC5nZXRVaW50MzIoWis0KTtyZXR1cm4gSio0Mjk0OTY3Mjk2K1F9dmFyIGRRPS0xLHJRPTQyOTQ5NjcyOTUsb1E9MTcxNzk4NjkxODM7ZnVuY3Rpb24gYVEoe3NlYzokLG5zZWM6Wn0pe2lmKCQ+PTAmJlo+PTAmJiQ8PW9RKWlmKFo9PT0wJiYkPD1yUSl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoNCk7cmV0dXJuIG5ldyBEYXRhVmlldyhKLmJ1ZmZlcikuc2V0VWludDMyKDAsJCksSn1lbHNle2xldCBKPSQvNDI5NDk2NzI5NixRPSQmNDI5NDk2NzI5NSxYPW5ldyBVaW50OEFycmF5KDgpLFk9bmV3IERhdGFWaWV3KFguYnVmZmVyKTtyZXR1cm4gWS5zZXRVaW50MzIoMCxaPDwyfEomMyksWS5zZXRVaW50MzIoNCxRKSxYfWVsc2V7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoMTIpLFE9bmV3IERhdGFWaWV3KEouYnVmZmVyKTtyZXR1cm4gUS5zZXRVaW50MzIoMCxaKSxNJChRLDQsJCksSn19ZnVuY3Rpb24gc1EoJCl7bGV0IFo9JC5nZXRUaW1lKCksSj1NYXRoLmZsb29yKFovMTAwMCksUT0oWi1KKjEwMDApKjFlNixYPU1hdGguZmxvb3IoUS8xZTkpO3JldHVybntzZWM6SitYLG5zZWM6US1YKjFlOX19ZnVuY3Rpb24gdFEoJCl7aWYoJCBpbnN0YW5jZW9mIERhdGUpe2xldCBaPXNRKCQpO3JldHVybiBhUShaKX1lbHNlIHJldHVybiBudWxsfWZ1bmN0aW9uIGVRKCQpe2xldCBaPW5ldyBEYXRhVmlldygkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKTtzd2l0Y2goJC5ieXRlTGVuZ3RoKXtjYXNlIDQ6e2xldCBKPVouZ2V0VWludDMyKDApLFE9MDtyZXR1cm57c2VjOkosbnNlYzowfX1jYXNlIDg6e2xldCBKPVouZ2V0VWludDMyKDApLFE9Wi5nZXRVaW50MzIoNCksWD0oSiYzKSo0Mjk0OTY3Mjk2K1EsWT1KPj4+MjtyZXR1cm57c2VjOlgsbnNlYzpZfX1jYXNlIDEyOntsZXQgSj1JJChaLDQpLFE9Wi5nZXRVaW50MzIoMCk7cmV0dXJue3NlYzpKLG5zZWM6UX19ZGVmYXVsdDp0aHJvdyBuZXcgdChgVW5yZWNvZ25pemVkIGRhdGEgc2l6ZSBmb3IgdGltZXN0YW1wIChleHBlY3RlZCA0LCA4LCBvciAxMik6ICR7JC5sZW5ndGh9YCl9fWZ1bmN0aW9uICRYKCQpe2xldCBaPWVRKCQpO3JldHVybiBuZXcgRGF0ZShaLnNlYyoxMDAwK1oubnNlYy8xZTYpfXZhciBxSj17dHlwZTpkUSxlbmNvZGU6dFEsZGVjb2RlOiRYfTtjbGFzcyBjMHtzdGF0aWMgZGVmYXVsdENvZGVjPW5ldyBjMDtfX2JyYW5kO2J1aWx0SW5FbmNvZGVycz1bXTtidWlsdEluRGVjb2RlcnM9W107ZW5jb2RlcnM9W107ZGVjb2RlcnM9W107Y29uc3RydWN0b3IoKXt0aGlzLnJlZ2lzdGVyKHFKKX1yZWdpc3Rlcih7dHlwZTokLGVuY29kZTpaLGRlY29kZTpKfSl7aWYoJD49MCl0aGlzLmVuY29kZXJzWyRdPVosdGhpcy5kZWNvZGVyc1skXT1KO2Vsc2V7bGV0IFE9LTEtJDt0aGlzLmJ1aWx0SW5FbmNvZGVyc1tRXT1aLHRoaXMuYnVpbHRJbkRlY29kZXJzW1FdPUp9fXRyeVRvRW5jb2RlKCQsWil7Zm9yKGxldCBKPTA7Sjx0aGlzLmJ1aWx0SW5FbmNvZGVycy5sZW5ndGg7SisrKXtsZXQgUT10aGlzLmJ1aWx0SW5FbmNvZGVyc1tKXTtpZihRIT1udWxsKXtsZXQgWD1RKCQsWik7aWYoWCE9bnVsbCl7bGV0IFk9LTEtSjtyZXR1cm4gbmV3IHUwKFksWCl9fX1mb3IobGV0IEo9MDtKPHRoaXMuZW5jb2RlcnMubGVuZ3RoO0orKyl7bGV0IFE9dGhpcy5lbmNvZGVyc1tKXTtpZihRIT1udWxsKXtsZXQgWD1RKCQsWik7aWYoWCE9bnVsbClyZXR1cm4gbmV3IHUwKEosWCl9fWlmKCQgaW5zdGFuY2VvZiB1MClyZXR1cm4gJDtyZXR1cm4gbnVsbH1kZWNvZGUoJCxaLEope2xldCBRPVo8MD90aGlzLmJ1aWx0SW5EZWNvZGVyc1stMS1aXTp0aGlzLmRlY29kZXJzW1pdO2lmKFEpcmV0dXJuIFEoJCxaLEopO2Vsc2UgcmV0dXJuIG5ldyB1MChaLCQpfX1mdW5jdGlvbiBaWCgkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHx0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXI8InUiJiYkIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXJ9ZnVuY3Rpb24gUSQoJCl7aWYoJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuICQ7ZWxzZSBpZihBcnJheUJ1ZmZlci5pc1ZpZXcoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpO2Vsc2UgaWYoWlgoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpO2Vsc2UgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX12YXIgSlg9MTAwLFFYPTIwNDg7Y2xhc3MgQyR7ZXh0ZW5zaW9uQ29kZWM7Y29udGV4dDt1c2VCaWdJbnQ2NDttYXhEZXB0aDtpbml0aWFsQnVmZmVyU2l6ZTtzb3J0S2V5cztmb3JjZUZsb2F0MzI7aWdub3JlVW5kZWZpbmVkO2ZvcmNlSW50ZWdlclRvRmxvYXQ7cG9zO3ZpZXc7Ynl0ZXM7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9jMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5tYXhEZXB0aD0kPy5tYXhEZXB0aD8/SlgsdGhpcy5pbml0aWFsQnVmZmVyU2l6ZT0kPy5pbml0aWFsQnVmZmVyU2l6ZT8/UVgsdGhpcy5zb3J0S2V5cz0kPy5zb3J0S2V5cz8/ITEsdGhpcy5mb3JjZUZsb2F0MzI9JD8uZm9yY2VGbG9hdDMyPz8hMSx0aGlzLmlnbm9yZVVuZGVmaW5lZD0kPy5pZ25vcmVVbmRlZmluZWQ/PyExLHRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdD0kPy5mb3JjZUludGVnZXJUb0Zsb2F0Pz8hMSx0aGlzLnBvcz0wLHRoaXMudmlldz1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKHRoaXMuaW5pdGlhbEJ1ZmZlclNpemUpKSx0aGlzLmJ5dGVzPW5ldyBVaW50OEFycmF5KHRoaXMudmlldy5idWZmZXIpfWNsb25lKCl7cmV0dXJuIG5ldyBDJCh7ZXh0ZW5zaW9uQ29kZWM6dGhpcy5leHRlbnNpb25Db2RlYyxjb250ZXh0OnRoaXMuY29udGV4dCx1c2VCaWdJbnQ2NDp0aGlzLnVzZUJpZ0ludDY0LG1heERlcHRoOnRoaXMubWF4RGVwdGgsaW5pdGlhbEJ1ZmZlclNpemU6dGhpcy5pbml0aWFsQnVmZmVyU2l6ZSxzb3J0S2V5czp0aGlzLnNvcnRLZXlzLGZvcmNlRmxvYXQzMjp0aGlzLmZvcmNlRmxvYXQzMixpZ25vcmVVbmRlZmluZWQ6dGhpcy5pZ25vcmVVbmRlZmluZWQsZm9yY2VJbnRlZ2VyVG9GbG9hdDp0aGlzLmZvcmNlSW50ZWdlclRvRmxvYXR9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMucG9zPTB9ZW5jb2RlU2hhcmVkUmVmKCQpe2lmKHRoaXMuZW50ZXJlZClyZXR1cm4gdGhpcy5jbG9uZSgpLmVuY29kZVNoYXJlZFJlZigkKTt0cnl7cmV0dXJuIHRoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5kb0VuY29kZSgkLDEpLHRoaXMuYnl0ZXMuc3ViYXJyYXkoMCx0aGlzLnBvcyl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWVuY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmNvZGUoJCk7dHJ5e3JldHVybiB0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuZG9FbmNvZGUoJCwxKSx0aGlzLmJ5dGVzLnNsaWNlKDAsdGhpcy5wb3MpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kb0VuY29kZSgkLFope2lmKFo+dGhpcy5tYXhEZXB0aCl0aHJvdyBFcnJvcihgVG9vIGRlZXAgb2JqZWN0cyBpbiBkZXB0aCAke1p9YCk7aWYoJD09bnVsbCl0aGlzLmVuY29kZU5pbCgpO2Vsc2UgaWYodHlwZW9mICQ9PT0iYm9vbGVhbiIpdGhpcy5lbmNvZGVCb29sZWFuKCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ibnVtYmVyIilpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0KXRoaXMuZW5jb2RlTnVtYmVyKCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ic3RyaW5nIil0aGlzLmVuY29kZVN0cmluZygkKTtlbHNlIGlmKHRoaXMudXNlQmlnSW50NjQmJnR5cGVvZiAkPT09ImJpZ2ludCIpdGhpcy5lbmNvZGVCaWdJbnQ2NCgkKTtlbHNlIHRoaXMuZW5jb2RlT2JqZWN0KCQsWil9ZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoJCl7bGV0IFo9dGhpcy5wb3MrJDtpZih0aGlzLnZpZXcuYnl0ZUxlbmd0aDxaKXRoaXMucmVzaXplQnVmZmVyKFoqMil9cmVzaXplQnVmZmVyKCQpe2xldCBaPW5ldyBBcnJheUJ1ZmZlcigkKSxKPW5ldyBVaW50OEFycmF5KFopLFE9bmV3IERhdGFWaWV3KFopO0ouc2V0KHRoaXMuYnl0ZXMpLHRoaXMudmlldz1RLHRoaXMuYnl0ZXM9Sn1lbmNvZGVOaWwoKXt0aGlzLndyaXRlVTgoMTkyKX1lbmNvZGVCb29sZWFuKCQpe2lmKCQ9PT0hMSl0aGlzLndyaXRlVTgoMTk0KTtlbHNlIHRoaXMud3JpdGVVOCgxOTUpfWVuY29kZU51bWJlcigkKXtpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0JiZOdW1iZXIuaXNTYWZlSW50ZWdlcigkKSlpZigkPj0wKWlmKCQ8MTI4KXRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8MjU2KXRoaXMud3JpdGVVOCgyMDQpLHRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8NjU1MzYpdGhpcy53cml0ZVU4KDIwNSksdGhpcy53cml0ZVUxNigkKTtlbHNlIGlmKCQ8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjA2KSx0aGlzLndyaXRlVTMyKCQpO2Vsc2UgaWYoIXRoaXMudXNlQmlnSW50NjQpdGhpcy53cml0ZVU4KDIwNyksdGhpcy53cml0ZVU2NCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIGlmKCQ+PS0zMil0aGlzLndyaXRlVTgoMjI0fCQrMzIpO2Vsc2UgaWYoJD49LTEyOCl0aGlzLndyaXRlVTgoMjA4KSx0aGlzLndyaXRlSTgoJCk7ZWxzZSBpZigkPj0tMzI3NjgpdGhpcy53cml0ZVU4KDIwOSksdGhpcy53cml0ZUkxNigkKTtlbHNlIGlmKCQ+PS0yMTQ3NDgzNjQ4KXRoaXMud3JpdGVVOCgyMTApLHRoaXMud3JpdGVJMzIoJCk7ZWxzZSBpZighdGhpcy51c2VCaWdJbnQ2NCl0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlSTY0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpfWVuY29kZU51bWJlckFzRmxvYXQoJCl7aWYodGhpcy5mb3JjZUZsb2F0MzIpdGhpcy53cml0ZVU4KDIwMiksdGhpcy53cml0ZUYzMigkKTtlbHNlIHRoaXMud3JpdGVVOCgyMDMpLHRoaXMud3JpdGVGNjQoJCl9ZW5jb2RlQmlnSW50NjQoJCl7aWYoJD49QmlnSW50KDApKXRoaXMud3JpdGVVOCgyMDcpLHRoaXMud3JpdGVCaWdVaW50NjQoJCk7ZWxzZSB0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlQmlnSW50NjQoJCl9d3JpdGVTdHJpbmdIZWFkZXIoJCl7aWYoJDwzMil0aGlzLndyaXRlVTgoMTYwKyQpO2Vsc2UgaWYoJDwyNTYpdGhpcy53cml0ZVU4KDIxNyksdGhpcy53cml0ZVU4KCQpO2Vsc2UgaWYoJDw2NTUzNil0aGlzLndyaXRlVTgoMjE4KSx0aGlzLndyaXRlVTE2KCQpO2Vsc2UgaWYoJDw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMTkpLHRoaXMud3JpdGVVMzIoJCk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxvbmcgc3RyaW5nOiAkeyR9IGJ5dGVzIGluIFVURi04YCl9ZW5jb2RlU3RyaW5nKCQpe2xldCBKPUZKKCQpO3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNStKKSx0aGlzLndyaXRlU3RyaW5nSGVhZGVyKEopLE5KKCQsdGhpcy5ieXRlcyx0aGlzLnBvcyksdGhpcy5wb3MrPUp9ZW5jb2RlT2JqZWN0KCQsWil7bGV0IEo9dGhpcy5leHRlbnNpb25Db2RlYy50cnlUb0VuY29kZSgkLHRoaXMuY29udGV4dCk7aWYoSiE9bnVsbCl0aGlzLmVuY29kZUV4dGVuc2lvbihKKTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoJCkpdGhpcy5lbmNvZGVBcnJheSgkLFopO2Vsc2UgaWYoQXJyYXlCdWZmZXIuaXNWaWV3KCQpKXRoaXMuZW5jb2RlQmluYXJ5KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ib2JqZWN0Iil0aGlzLmVuY29kZU1hcCgkLFopO2Vsc2UgdGhyb3cgRXJyb3IoYFVucmVjb2duaXplZCBvYmplY3Q6ICR7T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5hcHBseSgkKX1gKX1lbmNvZGVCaW5hcnkoJCl7bGV0IFo9JC5ieXRlTGVuZ3RoO2lmKFo8MjU2KXRoaXMud3JpdGVVOCgxOTYpLHRoaXMud3JpdGVVOChaKTtlbHNlIGlmKFo8NjU1MzYpdGhpcy53cml0ZVU4KDE5NyksdGhpcy53cml0ZVUxNihaKTtlbHNlIGlmKFo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMTk4KSx0aGlzLndyaXRlVTMyKFopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBiaW5hcnk6ICR7Wn1gKTtsZXQgSj1RJCgkKTt0aGlzLndyaXRlVThhKEopfWVuY29kZUFycmF5KCQsWil7bGV0IEo9JC5sZW5ndGg7aWYoSjwxNil0aGlzLndyaXRlVTgoMTQ0K0opO2Vsc2UgaWYoSjw2NTUzNil0aGlzLndyaXRlVTgoMjIwKSx0aGlzLndyaXRlVTE2KEopO2Vsc2UgaWYoSjw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjEpLHRoaXMud3JpdGVVMzIoSik7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIGFycmF5OiAke0p9YCk7Zm9yKGxldCBRIG9mICQpdGhpcy5kb0VuY29kZShRLForMSl9Y291bnRXaXRob3V0VW5kZWZpbmVkKCQsWil7bGV0IEo9MDtmb3IobGV0IFEgb2YgWilpZigkW1FdIT09dm9pZCAwKUorKztyZXR1cm4gSn1lbmNvZGVNYXAoJCxaKXtsZXQgSj1PYmplY3Qua2V5cygkKTtpZih0aGlzLnNvcnRLZXlzKUouc29ydCgpO2xldCBRPXRoaXMuaWdub3JlVW5kZWZpbmVkP3RoaXMuY291bnRXaXRob3V0VW5kZWZpbmVkKCQsSik6Si5sZW5ndGg7aWYoUTwxNil0aGlzLndyaXRlVTgoMTI4K1EpO2Vsc2UgaWYoUTw2NTUzNil0aGlzLndyaXRlVTgoMjIyKSx0aGlzLndyaXRlVTE2KFEpO2Vsc2UgaWYoUTw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjMpLHRoaXMud3JpdGVVMzIoUSk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIG1hcCBvYmplY3Q6ICR7UX1gKTtmb3IobGV0IFggb2YgSil7bGV0IFk9JFtYXTtpZighKHRoaXMuaWdub3JlVW5kZWZpbmVkJiZZPT09dm9pZCAwKSl0aGlzLmVuY29kZVN0cmluZyhYKSx0aGlzLmRvRW5jb2RlKFksWisxKX19ZW5jb2RlRXh0ZW5zaW9uKCQpe2lmKHR5cGVvZiAkLmRhdGE9PT0iZnVuY3Rpb24iKXtsZXQgSj0kLmRhdGEodGhpcy5wb3MrNiksUT1KLmxlbmd0aDtpZihRPj00Mjk0OTY3Mjk2KXRocm93IEVycm9yKGBUb28gbGFyZ2UgZXh0ZW5zaW9uIG9iamVjdDogJHtRfWApO3RoaXMud3JpdGVVOCgyMDEpLHRoaXMud3JpdGVVMzIoUSksdGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YShKKTtyZXR1cm59bGV0IFo9JC5kYXRhLmxlbmd0aDtpZihaPT09MSl0aGlzLndyaXRlVTgoMjEyKTtlbHNlIGlmKFo9PT0yKXRoaXMud3JpdGVVOCgyMTMpO2Vsc2UgaWYoWj09PTQpdGhpcy53cml0ZVU4KDIxNCk7ZWxzZSBpZihaPT09OCl0aGlzLndyaXRlVTgoMjE1KTtlbHNlIGlmKFo9PT0xNil0aGlzLndyaXRlVTgoMjE2KTtlbHNlIGlmKFo8MjU2KXRoaXMud3JpdGVVOCgxOTkpLHRoaXMud3JpdGVVOChaKTtlbHNlIGlmKFo8NjU1MzYpdGhpcy53cml0ZVU4KDIwMCksdGhpcy53cml0ZVUxNihaKTtlbHNlIGlmKFo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjAxKSx0aGlzLndyaXRlVTMyKFopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBleHRlbnNpb24gb2JqZWN0OiAke1p9YCk7dGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YSgkLmRhdGEpfXdyaXRlVTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0VWludDgodGhpcy5wb3MsJCksdGhpcy5wb3MrK313cml0ZVU4YSgkKXtsZXQgWj0kLmxlbmd0aDt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKFopLHRoaXMuYnl0ZXMuc2V0KCQsdGhpcy5wb3MpLHRoaXMucG9zKz1afXdyaXRlSTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0SW50OCh0aGlzLnBvcywkKSx0aGlzLnBvcysrfXdyaXRlVTE2KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMiksdGhpcy52aWV3LnNldFVpbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZUkxNigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDIpLHRoaXMudmlldy5zZXRJbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZVUzMigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDQpLHRoaXMudmlldy5zZXRVaW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVJMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0SW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVGMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0RmxvYXQzMih0aGlzLnBvcywkKSx0aGlzLnBvcys9NH13cml0ZUY2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRGbG9hdDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlVTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksT0oodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlSTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksTSQodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlQmlnVWludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ1VpbnQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUJpZ0ludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ0ludDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fX1mdW5jdGlvbiBfMCgkLFope3JldHVybiBuZXcgQyQoWikuZW5jb2RlU2hhcmVkUmVmKCQpfWZ1bmN0aW9uIFAkKCQpe3JldHVybmAkeyQ8MD8iLSI6IiJ9MHgke01hdGguYWJzKCQpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCIwIil9YH12YXIgWFg9MTYsWVg9MTY7Y2xhc3MgJFp7aGl0PTA7bWlzcz0wO2NhY2hlczttYXhLZXlMZW5ndGg7bWF4TGVuZ3RoUGVyS2V5O2NvbnN0cnVjdG9yKCQ9WFgsWj1ZWCl7dGhpcy5tYXhLZXlMZW5ndGg9JCx0aGlzLm1heExlbmd0aFBlcktleT1aLHRoaXMuY2FjaGVzPVtdO2ZvcihsZXQgSj0wO0o8dGhpcy5tYXhLZXlMZW5ndGg7SisrKXRoaXMuY2FjaGVzLnB1c2goW10pfWNhbkJlQ2FjaGVkKCQpe3JldHVybiAkPjAmJiQ8PXRoaXMubWF4S2V5TGVuZ3RofWZpbmQoJCxaLEope2xldCBRPXRoaXMuY2FjaGVzW0otMV07JDpmb3IobGV0IFggb2YgUSl7bGV0IFk9WC5ieXRlcztmb3IobGV0IFY9MDtWPEo7VisrKWlmKFlbVl0hPT0kW1orVl0pY29udGludWUgJDtyZXR1cm4gWC5zdHJ9cmV0dXJuIG51bGx9c3RvcmUoJCxaKXtsZXQgSj10aGlzLmNhY2hlc1skLmxlbmd0aC0xXSxRPXtieXRlczokLHN0cjpafTtpZihKLmxlbmd0aD49dGhpcy5tYXhMZW5ndGhQZXJLZXkpSltNYXRoLnJhbmRvbSgpKkoubGVuZ3RofDBdPVE7ZWxzZSBKLnB1c2goUSl9ZGVjb2RlKCQsWixKKXtsZXQgUT10aGlzLmZpbmQoJCxaLEopO2lmKFEhPW51bGwpcmV0dXJuIHRoaXMuaGl0KyssUTt0aGlzLm1pc3MrKztsZXQgWD1lJCgkLFosSiksWT1VaW50OEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCQsWixaK0opO3JldHVybiB0aGlzLnN0b3JlKFksWCksWH19dmFyIFpaPSJhcnJheSIsWSQ9Im1hcF9rZXkiLE1KPSJtYXBfdmFsdWUiLFZYPSgkKT0+e2lmKHR5cGVvZiAkPT09InN0cmluZyJ8fHR5cGVvZiAkPT09Im51bWJlciIpcmV0dXJuICQ7dGhyb3cgbmV3IHQoIlRoZSB0eXBlIG9mIGtleSBtdXN0IGJlIHN0cmluZyBvciBudW1iZXIgYnV0ICIrdHlwZW9mICQpfTtjbGFzcyBJSntzdGFjaz1bXTtzdGFja0hlYWRQb3NpdGlvbj0tMTtnZXQgbGVuZ3RoKCl7cmV0dXJuIHRoaXMuc3RhY2tIZWFkUG9zaXRpb24rMX10b3AoKXtyZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1wdXNoQXJyYXlTdGF0ZSgkKXtsZXQgWj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Wi50eXBlPVpaLFoucG9zaXRpb249MCxaLnNpemU9JCxaLmFycmF5PUFycmF5KCQpfXB1c2hNYXBTdGF0ZSgkKXtsZXQgWj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Wi50eXBlPVkkLFoucmVhZENvdW50PTAsWi5zaXplPSQsWi5tYXA9e319Z2V0VW5pbml0aWFsaXplZFN0YXRlRnJvbVBvb2woKXtpZih0aGlzLnN0YWNrSGVhZFBvc2l0aW9uKyssdGhpcy5zdGFja0hlYWRQb3NpdGlvbj09PXRoaXMuc3RhY2subGVuZ3RoKXtsZXQgJD17dHlwZTp2b2lkIDAsc2l6ZTowLGFycmF5OnZvaWQgMCxwb3NpdGlvbjowLHJlYWRDb3VudDowLG1hcDp2b2lkIDAsa2V5Om51bGx9O3RoaXMuc3RhY2sucHVzaCgkKX1yZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1yZWxlYXNlKCQpe2lmKHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl0hPT0kKXRocm93IEVycm9yKCJJbnZhbGlkIHN0YWNrIHN0YXRlLiBSZWxlYXNlZCBzdGF0ZSBpcyBub3Qgb24gdG9wIG9mIHRoZSBzdGFjay4iKTtpZigkLnR5cGU9PT1aWil7bGV0IEo9JDtKLnNpemU9MCxKLmFycmF5PXZvaWQgMCxKLnBvc2l0aW9uPTAsSi50eXBlPXZvaWQgMH1pZigkLnR5cGU9PT1ZJHx8JC50eXBlPT09TUope2xldCBKPSQ7Si5zaXplPTAsSi5tYXA9dm9pZCAwLEoucmVhZENvdW50PTAsSi50eXBlPXZvaWQgMH10aGlzLnN0YWNrSGVhZFBvc2l0aW9uLS19cmVzZXQoKXt0aGlzLnN0YWNrLmxlbmd0aD0wLHRoaXMuc3RhY2tIZWFkUG9zaXRpb249LTF9fXZhciBYJD0tMSxKWj1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDApKSxXWD1uZXcgVWludDhBcnJheShKWi5idWZmZXIpO3RyeXtKWi5nZXRJbnQ4KDApfWNhdGNoKCQpe2lmKCEoJCBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IEVycm9yKCJUaGlzIG1vZHVsZSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IEphdmFTY3JpcHQgZW5naW5lIGJlY2F1c2UgRGF0YVZpZXcgZG9lcyBub3QgdGhyb3cgUmFuZ2VFcnJvciBvbiBvdXQtb2YtYm91bmRzIGFjY2VzcyIpfXZhciBISj1SYW5nZUVycm9yKCJJbnN1ZmZpY2llbnQgZGF0YSIpLEdYPW5ldyAkWjtjbGFzcyB3JHtleHRlbnNpb25Db2RlYztjb250ZXh0O3VzZUJpZ0ludDY0O3Jhd1N0cmluZ3M7bWF4U3RyTGVuZ3RoO21heEJpbkxlbmd0aDttYXhBcnJheUxlbmd0aDttYXhNYXBMZW5ndGg7bWF4RXh0TGVuZ3RoO2tleURlY29kZXI7bWFwS2V5Q29udmVydGVyO3RvdGFsUG9zPTA7cG9zPTA7dmlldz1KWjtieXRlcz1XWDtoZWFkQnl0ZT1YJDtzdGFjaz1uZXcgSUo7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9jMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5yYXdTdHJpbmdzPSQ/LnJhd1N0cmluZ3M/PyExLHRoaXMubWF4U3RyTGVuZ3RoPSQ/Lm1heFN0ckxlbmd0aD8/cDAsdGhpcy5tYXhCaW5MZW5ndGg9JD8ubWF4QmluTGVuZ3RoPz9wMCx0aGlzLm1heEFycmF5TGVuZ3RoPSQ/Lm1heEFycmF5TGVuZ3RoPz9wMCx0aGlzLm1heE1hcExlbmd0aD0kPy5tYXhNYXBMZW5ndGg/P3AwLHRoaXMubWF4RXh0TGVuZ3RoPSQ/Lm1heEV4dExlbmd0aD8/cDAsdGhpcy5rZXlEZWNvZGVyPSQ/LmtleURlY29kZXIhPT12b2lkIDA/JC5rZXlEZWNvZGVyOkdYLHRoaXMubWFwS2V5Q29udmVydGVyPSQ/Lm1hcEtleUNvbnZlcnRlcj8/Vlh9Y2xvbmUoKXtyZXR1cm4gbmV3IHckKHtleHRlbnNpb25Db2RlYzp0aGlzLmV4dGVuc2lvbkNvZGVjLGNvbnRleHQ6dGhpcy5jb250ZXh0LHVzZUJpZ0ludDY0OnRoaXMudXNlQmlnSW50NjQscmF3U3RyaW5nczp0aGlzLnJhd1N0cmluZ3MsbWF4U3RyTGVuZ3RoOnRoaXMubWF4U3RyTGVuZ3RoLG1heEJpbkxlbmd0aDp0aGlzLm1heEJpbkxlbmd0aCxtYXhBcnJheUxlbmd0aDp0aGlzLm1heEFycmF5TGVuZ3RoLG1heE1hcExlbmd0aDp0aGlzLm1heE1hcExlbmd0aCxtYXhFeHRMZW5ndGg6dGhpcy5tYXhFeHRMZW5ndGgsa2V5RGVjb2Rlcjp0aGlzLmtleURlY29kZXJ9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMudG90YWxQb3M9MCx0aGlzLmhlYWRCeXRlPVgkLHRoaXMuc3RhY2sucmVzZXQoKX1zZXRCdWZmZXIoJCl7bGV0IFo9USQoJCk7dGhpcy5ieXRlcz1aLHRoaXMudmlldz1uZXcgRGF0YVZpZXcoWi5idWZmZXIsWi5ieXRlT2Zmc2V0LFouYnl0ZUxlbmd0aCksdGhpcy5wb3M9MH1hcHBlbmRCdWZmZXIoJCl7aWYodGhpcy5oZWFkQnl0ZT09PVgkJiYhdGhpcy5oYXNSZW1haW5pbmcoMSkpdGhpcy5zZXRCdWZmZXIoJCk7ZWxzZXtsZXQgWj10aGlzLmJ5dGVzLnN1YmFycmF5KHRoaXMucG9zKSxKPVEkKCQpLFE9bmV3IFVpbnQ4QXJyYXkoWi5sZW5ndGgrSi5sZW5ndGgpO1Euc2V0KFopLFEuc2V0KEosWi5sZW5ndGgpLHRoaXMuc2V0QnVmZmVyKFEpfX1oYXNSZW1haW5pbmcoJCl7cmV0dXJuIHRoaXMudmlldy5ieXRlTGVuZ3RoLXRoaXMucG9zPj0kfWNyZWF0ZUV4dHJhQnl0ZUVycm9yKCQpe2xldHt2aWV3OloscG9zOkp9PXRoaXM7cmV0dXJuIFJhbmdlRXJyb3IoYEV4dHJhICR7Wi5ieXRlTGVuZ3RoLUp9IG9mICR7Wi5ieXRlTGVuZ3RofSBieXRlKHMpIGZvdW5kIGF0IGJ1ZmZlclskeyR9XWApfWRlY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGUoJCk7dHJ5e3RoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5zZXRCdWZmZXIoJCk7bGV0IFo9dGhpcy5kb0RlY29kZVN5bmMoKTtpZih0aGlzLmhhc1JlbWFpbmluZygxKSl0aHJvdyB0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMucG9zKTtyZXR1cm4gWn1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19KmRlY29kZU11bHRpKCQpe2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpKCQpO3JldHVybn10cnl7dGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLnNldEJ1ZmZlcigkKTt3aGlsZSh0aGlzLmhhc1JlbWFpbmluZygxKSl5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1hc3luYyBkZWNvZGVBc3luYygkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGVBc3luYygkKTt0cnl7dGhpcy5lbnRlcmVkPSEwO2xldCBaPSExLEo7Zm9yIGF3YWl0KGxldCBWIG9mICQpe2lmKFopdGhyb3cgdGhpcy5lbnRlcmVkPSExLHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7dGhpcy5hcHBlbmRCdWZmZXIoVik7dHJ5e0o9dGhpcy5kb0RlY29kZVN5bmMoKSxaPSEwfWNhdGNoKFcpe2lmKCEoVyBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IFd9dGhpcy50b3RhbFBvcys9dGhpcy5wb3N9aWYoWil7aWYodGhpcy5oYXNSZW1haW5pbmcoMSkpdGhyb3cgdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnRvdGFsUG9zKTtyZXR1cm4gSn1sZXR7aGVhZEJ5dGU6USxwb3M6WCx0b3RhbFBvczpZfT10aGlzO3Rocm93IFJhbmdlRXJyb3IoYEluc3VmZmljaWVudCBkYXRhIGluIHBhcnNpbmcgJHtQJChRKX0gYXQgJHtZfSAoJHtYfSBpbiB0aGUgY3VycmVudCBidWZmZXIpYCl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRlY29kZUFycmF5U3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMCl9ZGVjb2RlU3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMSl9YXN5bmMqZGVjb2RlTXVsdGlBc3luYygkLFope2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpQXN5bmMoJCxaKTtyZXR1cm59dHJ5e3RoaXMuZW50ZXJlZD0hMDtsZXQgSj1aLFE9LTE7Zm9yIGF3YWl0KGxldCBYIG9mICQpe2lmKFomJlE9PT0wKXRocm93IHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7aWYodGhpcy5hcHBlbmRCdWZmZXIoWCksSilRPXRoaXMucmVhZEFycmF5U2l6ZSgpLEo9ITEsdGhpcy5jb21wbGV0ZSgpO3RyeXt3aGlsZSghMClpZih5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpLC0tUT09PTApYnJlYWt9Y2F0Y2goWSl7aWYoIShZIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikpdGhyb3cgWX10aGlzLnRvdGFsUG9zKz10aGlzLnBvc319ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRvRGVjb2RlU3luYygpeyQ6d2hpbGUoITApe2xldCAkPXRoaXMucmVhZEhlYWRCeXRlKCksWjtpZigkPj0yMjQpWj0kLTI1NjtlbHNlIGlmKCQ8MTkyKWlmKCQ8MTI4KVo9JDtlbHNlIGlmKCQ8MTQ0KXtsZXQgUT0kLTEyODtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBaPXt9fWVsc2UgaWYoJDwxNjApe2xldCBRPSQtMTQ0O2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNle2xldCBRPSQtMTYwO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwwKX1lbHNlIGlmKCQ9PT0xOTIpWj1udWxsO2Vsc2UgaWYoJD09PTE5NClaPSExO2Vsc2UgaWYoJD09PTE5NSlaPSEwO2Vsc2UgaWYoJD09PTIwMilaPXRoaXMucmVhZEYzMigpO2Vsc2UgaWYoJD09PTIwMylaPXRoaXMucmVhZEY2NCgpO2Vsc2UgaWYoJD09PTIwNClaPXRoaXMucmVhZFU4KCk7ZWxzZSBpZigkPT09MjA1KVo9dGhpcy5yZWFkVTE2KCk7ZWxzZSBpZigkPT09MjA2KVo9dGhpcy5yZWFkVTMyKCk7ZWxzZSBpZigkPT09MjA3KWlmKHRoaXMudXNlQmlnSW50NjQpWj10aGlzLnJlYWRVNjRBc0JpZ0ludCgpO2Vsc2UgWj10aGlzLnJlYWRVNjQoKTtlbHNlIGlmKCQ9PT0yMDgpWj10aGlzLnJlYWRJOCgpO2Vsc2UgaWYoJD09PTIwOSlaPXRoaXMucmVhZEkxNigpO2Vsc2UgaWYoJD09PTIxMClaPXRoaXMucmVhZEkzMigpO2Vsc2UgaWYoJD09PTIxMSlpZih0aGlzLnVzZUJpZ0ludDY0KVo9dGhpcy5yZWFkSTY0QXNCaWdJbnQoKTtlbHNlIFo9dGhpcy5yZWFkSTY0KCk7ZWxzZSBpZigkPT09MjE3KXtsZXQgUT10aGlzLmxvb2tVOCgpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwxKX1lbHNlIGlmKCQ9PT0yMTgpe2xldCBRPXRoaXMubG9va1UxNigpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwyKX1lbHNlIGlmKCQ9PT0yMTkpe2xldCBRPXRoaXMubG9va1UzMigpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSw0KX1lbHNlIGlmKCQ9PT0yMjApe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNlIGlmKCQ9PT0yMjEpe2xldCBRPXRoaXMucmVhZFUzMigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNlIGlmKCQ9PT0yMjIpe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hNYXBTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIFo9e319ZWxzZSBpZigkPT09MjIzKXtsZXQgUT10aGlzLnJlYWRVMzIoKTtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBaPXt9fWVsc2UgaWYoJD09PTE5Nil7bGV0IFE9dGhpcy5sb29rVTgoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsMSl9ZWxzZSBpZigkPT09MTk3KXtsZXQgUT10aGlzLmxvb2tVMTYoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsMil9ZWxzZSBpZigkPT09MTk4KXtsZXQgUT10aGlzLmxvb2tVMzIoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsNCl9ZWxzZSBpZigkPT09MjEyKVo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMSwwKTtlbHNlIGlmKCQ9PT0yMTMpWj10aGlzLmRlY29kZUV4dGVuc2lvbigyLDApO2Vsc2UgaWYoJD09PTIxNClaPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDQsMCk7ZWxzZSBpZigkPT09MjE1KVo9dGhpcy5kZWNvZGVFeHRlbnNpb24oOCwwKTtlbHNlIGlmKCQ9PT0yMTYpWj10aGlzLmRlY29kZUV4dGVuc2lvbigxNiwwKTtlbHNlIGlmKCQ9PT0xOTkpe2xldCBRPXRoaXMubG9va1U4KCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDEpfWVsc2UgaWYoJD09PTIwMCl7bGV0IFE9dGhpcy5sb29rVTE2KCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDIpfWVsc2UgaWYoJD09PTIwMSl7bGV0IFE9dGhpcy5sb29rVTMyKCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDQpfWVsc2UgdGhyb3cgbmV3IHQoYFVucmVjb2duaXplZCB0eXBlIGJ5dGU6ICR7UCQoJCl9YCk7dGhpcy5jb21wbGV0ZSgpO2xldCBKPXRoaXMuc3RhY2s7d2hpbGUoSi5sZW5ndGg+MCl7bGV0IFE9Si50b3AoKTtpZihRLnR5cGU9PT1aWilpZihRLmFycmF5W1EucG9zaXRpb25dPVosUS5wb3NpdGlvbisrLFEucG9zaXRpb249PT1RLnNpemUpWj1RLmFycmF5LEoucmVsZWFzZShRKTtlbHNlIGNvbnRpbnVlICQ7ZWxzZSBpZihRLnR5cGU9PT1ZJCl7aWYoWj09PSJfX3Byb3RvX18iKXRocm93IG5ldyB0KCJUaGUga2V5IF9fcHJvdG9fXyBpcyBub3QgYWxsb3dlZCIpO1Eua2V5PXRoaXMubWFwS2V5Q29udmVydGVyKFopLFEudHlwZT1NSjtjb250aW51ZSAkfWVsc2UgaWYoUS5tYXBbUS5rZXldPVosUS5yZWFkQ291bnQrKyxRLnJlYWRDb3VudD09PVEuc2l6ZSlaPVEubWFwLEoucmVsZWFzZShRKTtlbHNle1Eua2V5PW51bGwsUS50eXBlPVkkO2NvbnRpbnVlICR9fXJldHVybiBafX1yZWFkSGVhZEJ5dGUoKXtpZih0aGlzLmhlYWRCeXRlPT09WCQpdGhpcy5oZWFkQnl0ZT10aGlzLnJlYWRVOCgpO3JldHVybiB0aGlzLmhlYWRCeXRlfWNvbXBsZXRlKCl7dGhpcy5oZWFkQnl0ZT1YJH1yZWFkQXJyYXlTaXplKCl7bGV0ICQ9dGhpcy5yZWFkSGVhZEJ5dGUoKTtzd2l0Y2goJCl7Y2FzZSAyMjA6cmV0dXJuIHRoaXMucmVhZFUxNigpO2Nhc2UgMjIxOnJldHVybiB0aGlzLnJlYWRVMzIoKTtkZWZhdWx0OmlmKCQ8MTYwKXJldHVybiAkLTE0NDtlbHNlIHRocm93IG5ldyB0KGBVbnJlY29nbml6ZWQgYXJyYXkgdHlwZSBieXRlOiAke1AkKCQpfWApfX1wdXNoTWFwU3RhdGUoJCl7aWYoJD50aGlzLm1heE1hcExlbmd0aCl0aHJvdyBuZXcgdChgTWF4IGxlbmd0aCBleGNlZWRlZDogbWFwIGxlbmd0aCAoJHskfSkgPiBtYXhNYXBMZW5ndGhMZW5ndGggKCR7dGhpcy5tYXhNYXBMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaE1hcFN0YXRlKCQpfXB1c2hBcnJheVN0YXRlKCQpe2lmKCQ+dGhpcy5tYXhBcnJheUxlbmd0aCl0aHJvdyBuZXcgdChgTWF4IGxlbmd0aCBleGNlZWRlZDogYXJyYXkgbGVuZ3RoICgkeyR9KSA+IG1heEFycmF5TGVuZ3RoICgke3RoaXMubWF4QXJyYXlMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaEFycmF5U3RhdGUoJCl9ZGVjb2RlU3RyaW5nKCQsWil7aWYoIXRoaXMucmF3U3RyaW5nc3x8dGhpcy5zdGF0ZUlzTWFwS2V5KCkpcmV0dXJuIHRoaXMuZGVjb2RlVXRmOFN0cmluZygkLFopO3JldHVybiB0aGlzLmRlY29kZUJpbmFyeSgkLFopfWRlY29kZVV0ZjhTdHJpbmcoJCxaKXtpZigkPnRoaXMubWF4U3RyTGVuZ3RoKXRocm93IG5ldyB0KGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBVVEYtOCBieXRlIGxlbmd0aCAoJHskfSkgPiBtYXhTdHJMZW5ndGggKCR7dGhpcy5tYXhTdHJMZW5ndGh9KWApO2lmKHRoaXMuYnl0ZXMuYnl0ZUxlbmd0aDx0aGlzLnBvcytaKyQpdGhyb3cgSEo7bGV0IEo9dGhpcy5wb3MrWixRO2lmKHRoaXMuc3RhdGVJc01hcEtleSgpJiZ0aGlzLmtleURlY29kZXI/LmNhbkJlQ2FjaGVkKCQpKVE9dGhpcy5rZXlEZWNvZGVyLmRlY29kZSh0aGlzLmJ5dGVzLEosJCk7ZWxzZSBRPVJKKHRoaXMuYnl0ZXMsSiwkKTtyZXR1cm4gdGhpcy5wb3MrPVorJCxRfXN0YXRlSXNNYXBLZXkoKXtpZih0aGlzLnN0YWNrLmxlbmd0aD4wKXJldHVybiB0aGlzLnN0YWNrLnRvcCgpLnR5cGU9PT1ZJDtyZXR1cm4hMX1kZWNvZGVCaW5hcnkoJCxaKXtpZigkPnRoaXMubWF4QmluTGVuZ3RoKXRocm93IG5ldyB0KGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBiaW4gbGVuZ3RoICgkeyR9KSA+IG1heEJpbkxlbmd0aCAoJHt0aGlzLm1heEJpbkxlbmd0aH0pYCk7aWYoIXRoaXMuaGFzUmVtYWluaW5nKCQrWikpdGhyb3cgSEo7bGV0IEo9dGhpcy5wb3MrWixRPXRoaXMuYnl0ZXMuc3ViYXJyYXkoSixKKyQpO3JldHVybiB0aGlzLnBvcys9WiskLFF9ZGVjb2RlRXh0ZW5zaW9uKCQsWil7aWYoJD50aGlzLm1heEV4dExlbmd0aCl0aHJvdyBuZXcgdChgTWF4IGxlbmd0aCBleGNlZWRlZDogZXh0IGxlbmd0aCAoJHskfSkgPiBtYXhFeHRMZW5ndGggKCR7dGhpcy5tYXhFeHRMZW5ndGh9KWApO2xldCBKPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zK1opLFE9dGhpcy5kZWNvZGVCaW5hcnkoJCxaKzEpO3JldHVybiB0aGlzLmV4dGVuc2lvbkNvZGVjLmRlY29kZShRLEosdGhpcy5jb250ZXh0KX1sb29rVTgoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKX1sb29rVTE2KCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50MTYodGhpcy5wb3MpfWxvb2tVMzIoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyl9cmVhZFU4KCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRJOCgpe2xldCAkPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRVMTYoKXtsZXQgJD10aGlzLnZpZXcuZ2V0VWludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkSTE2KCl7bGV0ICQ9dGhpcy52aWV3LmdldEludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkVTMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZEkzMigpe2xldCAkPXRoaXMudmlldy5nZXRJbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZFU2NCgpe2xldCAkPVVKKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NCgpe2xldCAkPUkkKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZFU2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ0ludDY0KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTgsJH1yZWFkRjMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldEZsb2F0MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRGNjQoKXtsZXQgJD10aGlzLnZpZXcuZ2V0RmxvYXQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9fWZ1bmN0aW9uIFFaKCQsWil7cmV0dXJuIG5ldyB3JChaKS5kZWNvZGUoJCl9Y2xhc3MgViR7bGlzdGVuZXJzPW5ldyBNYXA7YWRkRXZlbnRMaXN0ZW5lcigkLFope2xldCBKPXRoaXMubGlzdGVuZXJzLmdldCgkKTtpZighSilKPW5ldyBTZXQsdGhpcy5saXN0ZW5lcnMuc2V0KCQsSik7cmV0dXJuIEouYWRkKFopLCgpPT57dGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCQsWil9fXJlbW92ZUV2ZW50TGlzdGVuZXIoJCxaKXtsZXQgSj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoSil7aWYoSi5kZWxldGUoWiksSi5zaXplPT09MCl0aGlzLmxpc3RlbmVycy5kZWxldGUoJCl9fWVtaXQoJCxaKXtsZXQgSj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoSil7bGV0IFE9QXJyYXkuZnJvbShKKTtmb3IobGV0IFggb2YgUSlYKFopfX1lbWl0QWxsKCQpe2xldCBaPUFycmF5LmZyb20odGhpcy5saXN0ZW5lcnMua2V5cygpKTtmb3IobGV0IEogb2YgWil0aGlzLmVtaXQoSiwkKX19Y2xhc3MgTDB7Z2V0dGVyO3N0YXRpYyBldmVudE5hbWU9InVwZGF0ZSI7ZW1pdHRlcjtjb25zdHJ1Y3RvcigkKXt0aGlzLmdldHRlcj0kO3RoaXMuZW1pdHRlcj1uZXcgViR9Z2V0PSgpPT50aGlzLmdldHRlcigpO2FzeW5jIGVtaXQoKXtsZXQgJD1hd2FpdCB0aGlzLmdldHRlcigpO3F1ZXVlTWljcm90YXNrKCgpPT50aGlzLmVtaXR0ZXIuZW1pdChMMC5ldmVudE5hbWUsJCkpfWxpc3RlbigkKXtyZXR1cm4gdGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoTDAuZXZlbnROYW1lLCQpLCgpPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoTDAuZXZlbnROYW1lLCQpfX19ZnVuY3Rpb24gUigkKXtyZXR1cm5bJCwwXX1mdW5jdGlvbiBHKCQpe3JldHVyblt2b2lkIDAsJF19ZnVuY3Rpb24gelgoJCl7aWYoJDwwKWNvbnNvbGUuaW5mbygiTiIsJCksY29uc29sZS50cmFjZSgpO2lmKHR5cGVvZiAkIT09ImJpZ2ludCIpJD1CaWdJbnQoJCk7aWYoJDwwbilyZXR1cm4gRygxMCk7bGV0IFo9W107d2hpbGUoJD4wbil7bGV0IEo9TnVtYmVyKCQmMHg3Zm4pO2lmKCQ+Pj03biwkPjBuKVoucHVzaChKfDEyOCk7ZWxzZSBaLnB1c2goSil9aWYoWi5sZW5ndGg9PT0wKXJldHVybiBSKG5ldyBVaW50OEFycmF5KFswXSkpO2lmKFoubGVuZ3RoPjgpcmV0dXJuIEcoMjYpO3JldHVybiBSKG5ldyBVaW50OEFycmF5KFopKX1mdW5jdGlvbiBLWCgkLFo9MCl7bGV0IEo9MG4sUT0wLFg9Wjt3aGlsZSghMCl7aWYoWD49JC5sZW5ndGgpcmV0dXJuIEcoMTQpO2xldCBZPSRbWCsrXTtpZihZPT09dm9pZCAwKXJldHVybiBHKDE0KTtpZihKfD1CaWdJbnQoWSYxMjcpPDxCaWdJbnQoUSksKFkmMTI4KT09PTApe2lmKFgtWj44KXJldHVybiBHKDI2KTtyZXR1cm4gUih7dmFsdWU6Sj4weDFmZmZmZmZmZmZmZmZmbj9KOk51bWJlcihKKSxieXRlc1JlYWQ6WC1afSl9aWYoUSs9NyxRPj01NilyZXR1cm4gRygyNil9fWNsYXNzIG17ZGF0YTtwb3M9MDtjb25zdHJ1Y3RvcigkKXt0aGlzLmRhdGE9JH1zdGF0aWMgYXN5bmMgZnJvbVJlc3BvbnNlKCQpe2xldCBaPWF3YWl0ICQuYXJyYXlCdWZmZXIoKSxKPW5ldyBVaW50OEFycmF5KFopO3JldHVybiBuZXcgbShKKX1yZWFkQmlnSW50KCl7aWYodGhpcy5wb3MrOD50aGlzLmRhdGEubGVuZ3RoKXJldHVybiBHKDcpO2xldCAkPW5ldyBEYXRhVmlldyh0aGlzLmRhdGEuYnVmZmVyLHRoaXMuZGF0YS5ieXRlT2Zmc2V0K3RoaXMucG9zKS5nZXRCaWdVaW50NjQoMCwhMSk7cmV0dXJuIHRoaXMucG9zKz04LFIoJCl9cmVhZERhdGUoKXtsZXRbJCxaXT10aGlzLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gUihuZXcgRGF0ZSgkKSl9cmVhZFZhckludCgpe2xldFskLFpdPUtYKHRoaXMuZGF0YSx0aGlzLnBvcyk7aWYoWiE9PTApcmV0dXJuIEcoWik7dGhpcy5wb3MrPSQuYnl0ZXNSZWFkO2xldCBKPSQudmFsdWU7cmV0dXJuIFIodHlwZW9mIEo9PT0iYmlnaW50Ij9OdW1iZXIoSik6Sil9cmVhZFZhclN0cmluZygpe2xldFskLFpdPXRoaXMucmVhZFZhckludCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtKLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBYPW5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShKKTtyZXR1cm4gUihYKX1yZWFkQnl0ZXMoJCl7aWYoJDwwKXJldHVybiBHKDEwKTtpZih0aGlzLnBvcyskPnRoaXMuZGF0YS5sZW5ndGgpcmV0dXJuIEcoMjMpO2xldCBaPXRoaXMuZGF0YS5zbGljZSh0aGlzLnBvcyx0aGlzLnBvcyskKTtyZXR1cm4gdGhpcy5wb3MrPSQsUihaKX1yZWFkVmFyQnl0ZXMoKXtsZXRbJCxaXT10aGlzLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gdGhpcy5yZWFkQnl0ZXMoJCl9cmVhZFN0cnVjdCgkKXtyZXR1cm4gJC5kZWNvZGUodGhpcyl9cmVhZFN0cnVjdHMoJCl7bGV0IFo9W107d2hpbGUoIXRoaXMuZG9uZSgpKXtsZXRbSixRXT10aGlzLnJlYWRTdHJ1Y3QoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7Wi5wdXNoKEopfXJldHVybiBSKFopfXJlYWRCeXRlc1NlcSgkKXtsZXQgWj1bXTt3aGlsZSghdGhpcy5kb25lKCkpe2xldFtKLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO1oucHVzaChKKX1yZXR1cm4gUihaKX1kb25lKCl7cmV0dXJuIHRoaXMucG9zPj10aGlzLmRhdGEubGVuZ3RofWNvbnN1bWVkKCl7cmV0dXJuIHRoaXMucG9zfX1jbGFzcyBTe3BhcnRzPVtdO3dyaXRlQmlnSW50KCQpe2xldCBaPW5ldyBVaW50OEFycmF5KDgpO25ldyBEYXRhVmlldyhaLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsJCwhMSksdGhpcy5wYXJ0cy5wdXNoKFopfXdyaXRlRGF0ZSgkKXtsZXQgWj0kLmdldFRpbWUoKTtyZXR1cm4gdGhpcy53cml0ZVZhckludChaKX13cml0ZVZhckludCgkKXtsZXRbWixKXT16WCgkKTtpZihKIT09MClyZXR1cm4gSjtyZXR1cm4gdGhpcy5wYXJ0cy5wdXNoKFopLDB9d3JpdGVWYXJTdHJpbmcoJCl7bGV0IFo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpLEo9dGhpcy53cml0ZVZhckludChaLmxlbmd0aCk7aWYoSiE9PTApcmV0dXJuIEo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcyhaKSwwfXByZXBlbmRCeXRlcygkKXt0aGlzLnBhcnRzLnVuc2hpZnQoJC5zbGljZSgpKX13cml0ZUJ5dGVzKCQpe3RoaXMucGFydHMucHVzaCgkLnNsaWNlKCkpfXdyaXRlVmFyQnl0ZXMoJCl7bGV0IFo9dGhpcy53cml0ZVZhckludCgkLmxlbmd0aCk7aWYoWiE9PTApcmV0dXJuIFo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcygkKSwwfXdyaXRlU3RydWN0KCQsWil7cmV0dXJuICQuZW5jb2RlKHRoaXMsWil9d3JpdGVTdHJ1Y3RzKCQsWil7Zm9yKGxldCBKIG9mIFope2xldCBRPXRoaXMud3JpdGVTdHJ1Y3QoJCxKKTtpZihRIT09MClyZXR1cm4gUX1yZXR1cm4gMH13cml0ZUJ5dGVzU2VxKCQpe2ZvcihsZXQgWiBvZiAkKXRoaXMud3JpdGVCeXRlcyhaKX1yZXN1bHQoKXtsZXQgJD10aGlzLnBhcnRzLnJlZHVjZSgoUSxYKT0+UStYLmxlbmd0aCwwKSxaPW5ldyBVaW50OEFycmF5KCQpLEo9MDtmb3IobGV0IFEgb2YgdGhpcy5wYXJ0cylaLnNldChRLEopLEorPVEubGVuZ3RoO3JldHVybiBafSpzY2FuKCl7Zm9yKGxldCAkIG9mIHRoaXMucGFydHMpeWllbGQgJH19YXN5bmMgZnVuY3Rpb24gWFooJCxaKXtsZXQgSj1uZXcgUyxRPUoud3JpdGVEYXRlKFopO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBYPUoucmVzdWx0KCksWT1hd2FpdCAkLnNpZ24oWCk7cmV0dXJuIFIoe3B1YktleTokLnB1YmxpY0tleSxzaWc6WSx0aW1lc3RhbXA6Wn0pfWFzeW5jIGZ1bmN0aW9uIGowKCQsWixKKXtsZXQgUT1KLm5vdygpLmdldFRpbWUoKSxYPSQudGltZXN0YW1wLmdldFRpbWUoKTtpZihNYXRoLmFicyhRLVgpPkdKKXJldHVybiA0O2xldCBWPW5ldyBTO1Yud3JpdGVEYXRlKCQudGltZXN0YW1wKTtsZXQgVz1WLnJlc3VsdCgpO2lmKCFhd2FpdCBaLmNoZWNrU2lnRWQyNTUxOSgkLnNpZyxXLCQucHViS2V5KSlyZXR1cm4gMztyZXR1cm4gMH12YXIgWDA9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmlkKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlRGF0ZShaLnRzKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZFZhckJ5dGVzKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsWF09JC5yZWFkRGF0ZSgpO2lmKFghPT0wKXJldHVybiBHKFgpO3JldHVybiBSKHtpZDpaLHRzOlF9KX19O2Z1bmN0aW9uIFQkKCQpe2xldCBaPW5ldyBTLEo9Wi53cml0ZVN0cnVjdChYMCwkKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXQgUT1aLnJlc3VsdCgpO3JldHVybiBSKFEpfXZhciBWMD17ZW5jb2RlKCQsWil7bGV0IEo9JC53cml0ZVZhckJ5dGVzKFouZWlkKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFySW50KFoub2ZmKTtpZihRIT09MClyZXR1cm4gUTtsZXQgWD0kLndyaXRlVmFySW50KFouY3RyKTtpZihYIT09MClyZXR1cm4gWDtsZXQgWT0kLndyaXRlVmFySW50KFoubGVuKTtpZihZIT09MClyZXR1cm4gWTtpZihaLmhzaCkkLndyaXRlQnl0ZXMoWi5oc2gpO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFyQnl0ZXMoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXQgUT1uZXcgbShaKSxbLFhdPVgwLmRlY29kZShRKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbWSxWXT0kLnJlYWRWYXJJbnQoKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXRbVyx6XT0kLnJlYWRWYXJJbnQoKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXRbSyxGXT0kLnJlYWRWYXJJbnQoKTtpZihGIT09MClyZXR1cm4gRyhGKTtsZXQgTjtpZihLPjApe2xldFtPLFVdPSQucmVhZEJ5dGVzKEgkKTtpZihVIT09MClyZXR1cm4gRyhVKTtOPU99cmV0dXJuIFIoe2VpZDpaLG9mZjpZLGN0cjpXLGxlbjpLLGhzaDpOfSl9fTtmdW5jdGlvbiBOMCgkKXtyZXR1cm4gQXJyYXkuZnJvbSgkKS5tYXAoKEopPT5KLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCIwIikpLmpvaW4oIiIpfWZ1bmN0aW9uIENKKCQpe2lmKCQubGVuZ3RoJTIhPT0wKXRocm93IEVycm9yKCJJbnZhbGlkIGhleCBzdHJpbmciKTtsZXQgWj1uZXcgVWludDhBcnJheSgkLmxlbmd0aC8yKTtmb3IobGV0IEo9MDtKPCQubGVuZ3RoO0orPTIpWltKLzJdPU51bWJlci5wYXJzZUludCgkLnN1YnN0cihKLDIpLDE2KTtyZXR1cm4gWn1mdW5jdGlvbiBhKCQsWil7aWYoJD09PVopcmV0dXJuITA7aWYoJC5ieXRlTGVuZ3RoIT09Wi5ieXRlTGVuZ3RoKXJldHVybiExO3JldHVybiAkLmV2ZXJ5KChKLFEpPT5KPT09WltRXSl9dmFyIEI7aWYodHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLnRvQmFzZTY0PT09ImZ1bmN0aW9uIilCPSgkKT0+JC50b0Jhc2U2NCgpO2Vsc2UgQj0oJCk9PmJ0b2EoU3RyaW5nLmZyb21DaGFyQ29kZSguLi4kKSk7dmFyIEYwO2lmKHR5cGVvZiBVaW50OEFycmF5LmZyb21CYXNlNjQ9PT0iZnVuY3Rpb24iKUYwPSgkKT0+VWludDhBcnJheS5mcm9tQmFzZTY0KCQpO2Vsc2UgRjA9KCQpPT5VaW50OEFycmF5LmZyb20oYXRvYigkKSwoWik9PlouY2hhckNvZGVBdCgwKSk7ZnVuY3Rpb24gVyQoJCxaKXtsZXQgSj1uZXcgVWludDhBcnJheSgkLmxlbmd0aCtaLmxlbmd0aCk7cmV0dXJuIEouc2V0KCQsMCksSi5zZXQoWiwkLmxlbmd0aCksSn1mdW5jdGlvbiBQSigkLFosSil7cmV0dXJuIEouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLCQuaGVhZENwaCxaKX1hc3luYyBmdW5jdGlvbiB3SigkLFosSixRKXtsZXQgWDtpZigkLmJvZCYmJC5sZW4+MClYPWF3YWl0IEouYmxha2UzKCQuYm9kKTtsZXQgWT1uZXcgUyxWPVYwLmVuY29kZShZLHsuLi4kLGhzaDpYfSk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0IFc9WS5yZXN1bHQoKSx6PWF3YWl0IFoua2RtRm9yKFcpLEs9US5kZXJpdmVDaXBoZXIoeiwiZW5jcnlwdCIpLEY9YXdhaXQgSy5lbmNyeXB0KFcpLE49JC5ib2Q/YXdhaXQgSy5lbmNyeXB0KCQuYm9kKTpuZXcgVWludDhBcnJheSgwKSxPPWF3YWl0IFouc2lnbihGKTtyZXR1cm4gUih7c2lnOk8sa2RtOnosaGVhZENwaDpGLGJvZHlDcGg6Tn0pfWFzeW5jIGZ1bmN0aW9uIFlaKCQsWixKLFEsWCl7bGV0IFk9bmV3IG0oJCksW1YsV109VjAuZGVjb2RlKFkpO2lmKFchPT0wKXJldHVybiBHKDE0KTtsZXQgejt0cnl7ej1aJiZaLmxlbmd0aD4wP2F3YWl0IEouZGVjcnlwdChaKTp2b2lkIDB9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldCBLPVYuaHNoJiZ6PT09dm9pZCAwLEY9Vi5oc2g9PT12b2lkIDAmJnohPT12b2lkIDA7aWYoS3x8RilyZXR1cm4gRygxOSk7aWYoVi5oc2gmJnope2xldCBPPWF3YWl0IFEuYmxha2UzKHopO2lmKCFhKE8sVi5oc2gpKXJldHVybiBHKDE5KX1sZXQgTj1YPz9hd2FpdCBRLmJsYWtlMygkKTtyZXR1cm4gUih7bXNnSGVhZDpWLGJvZDp6LGhlYWRIYXNoOk59KX1jbGFzcyBWWntub3coKXtyZXR1cm4gbmV3IERhdGV9fWZ1bmN0aW9uIFRKKCQsWixKLFEpe2xldCBYPVouZ2V0VGltZSgpLSQuZ2V0VGltZSgpLFk9Si5nZXRUaW1lKCktUS5nZXRUaW1lKCk7cmV0dXJuKFgrWSkvMn12YXIgRyQ9e2VuY29kZSgkLFope2lmKCQud3JpdGVWYXJJbnQoWi5xdW90YSksWi5xdW90YT4wKXtpZihaLnVzYWdlPT09dm9pZCAwKXJldHVybiA5OyQud3JpdGVWYXJJbnQoWi51c2FnZSl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXQgUTtpZihaPjApe2xldFtYLFldPSQucmVhZFZhckludCgpO2lmKFkhPT0wKXJldHVybiBHKFkpO1E9WH1yZXR1cm4gUih7cXVvdGE6Wix1c2FnZTpRfSl9fTt2YXIgV1o9e2VuY29kZSgkLFopeyQud3JpdGVCeXRlcyhuZXcgVWludDhBcnJheShbWi5zdGF0dXNdKSk7bGV0IEo9JC53cml0ZURhdGUoWi50aW1lUmN2ZCk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZURhdGUoWi50aW1lU2VudCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFg9JC53cml0ZVZhckludChaLnN1YnNjcmlwdGlvbi50ZXJtKTtpZihYIT09MClyZXR1cm4gWDtsZXQgWT0kLndyaXRlVmFySW50KFouc3Vic2NyaXB0aW9uLmVsYXBzZWQpO2lmKFkhPT0wKXJldHVybiBZO2xldCBWPSQud3JpdGVTdHJ1Y3QoRyQsWi5zdWJzY3JpcHRpb24uc3RhdCk7aWYoViE9PTApcmV0dXJuIFY7bGV0IFc9JC53cml0ZVN0cnVjdChHJCxaLnN1YnNjcmlwdGlvbi5keW4pO2lmKFchPT0wKXJldHVybiBXO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkQnl0ZXMoMSk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0IFE9WlswXSxbWCxZXT0kLnJlYWREYXRlKCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsV109JC5yZWFkRGF0ZSgpO2lmKFchPT0wKXJldHVybiBHKFcpO2xldFt6LEtdPSQucmVhZFZhckludCgpO2lmKEshPT0wKXJldHVybiBHKEspO2xldFtGLE5dPSQucmVhZFZhckludCgpO2lmKE4hPT0wKXJldHVybiBHKE4pO2xldFtPLFVdPSQucmVhZFN0cnVjdChHJCk7aWYoVSE9PTApcmV0dXJuIEcoVSk7bGV0W3EsSF09JC5yZWFkU3RydWN0KEckKTtpZihIIT09MClyZXR1cm4gRyhIKTtyZXR1cm4gUih7c3RhdHVzOlEsdGltZVJjdmQ6WCx0aW1lU2VudDpWLHN1YnNjcmlwdGlvbjp7dGVybTp6LGVsYXBzZWQ6RixzdGF0Ok8sZHluOnF9fSl9fTt2YXIgR1o9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmhlYWRDcGgpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJJbnQoWi5zZXEpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFyQnl0ZXMoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gUih7aGVhZENwaDpaLHNlcTpRfSl9fTt2YXIgWTA9e2VuY29kZSgkLFopeyQud3JpdGVCeXRlcyhaLnB1YktleSksJC53cml0ZUJ5dGVzKFouc2lnKTtsZXQgSj0kLndyaXRlRGF0ZShaLnRpbWVzdGFtcCk7aWYoSiE9PTApcmV0dXJuIEo7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRCeXRlcyhXSik7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsWF09JC5yZWFkQnl0ZXModzApO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtZLFZdPSQucmVhZERhdGUoKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gUih7cHViS2V5Olosc2lnOlEsdGltZXN0YW1wOll9KX19O3ZhciBqSj17YXN5bmMgZW5jb2RlUmVxKCQsWixKLFEsWCl7bGV0IFk9WC53cml0ZVN0cnVjdChZMCxKKTtpZihZIT09MClyZXR1cm4gWTtmb3IobGV0IFYgb2YgUSlYLndyaXRlVmFySW50KFYpO3JldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxaLEope2xldHtjbG9jazpRLGNyeXB0bzpYLHN0b3JhZ2U6WX09JCxbVixXXT1aLnJlYWRTdHJ1Y3QoWTApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IGowKFYsWCxRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVYsW0YsTl09YXdhaXQgWS5oYXNVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO2lmKCFGKXJldHVybiA1O2xldFtPLFVdPVoucmVhZFZhckludCgpO2lmKFUhPT0wKXJldHVybiBVO2lmKCFaLmRvbmUoKSlyZXR1cm4gODtsZXRbcSxIXT1hd2FpdCBZLmxpc3RIZWFkcyhLLE8pO2lmKEghPT0wKXJldHVybiBIO3JldHVybiBKLndyaXRlU3RydWN0cyhHWixxKX0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyhHWil9fTt2YXIgelo9e2VuY29kZSgkLFopeyQud3JpdGVWYXJJbnQoWi5zZXEpO2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmJvZHlDcGgpO2lmKEohPT0wKXJldHVybiBKO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gUih7c2VxOlosYm9keUNwaDpRfSl9fTt2YXIgREo9e2FzeW5jIGVuY29kZVJlcSgkLFosSixRLFgpe2xldCBZPVgud3JpdGVTdHJ1Y3QoWTAsSik7aWYoWSE9PTApcmV0dXJuIFk7Zm9yKGxldCBWIG9mIFEpe2xldCBXPVgud3JpdGVWYXJJbnQoVik7aWYoVyE9PTApcmV0dXJuIFd9cmV0dXJuIDB9LGFzeW5jIGhhbmRsZVJlcSgkLFosSil7bGV0e2Nsb2NrOlEsY3J5cHRvOlgsc3RvcmFnZTpZfT0kLFtWLFddPVoucmVhZFN0cnVjdChZMCk7aWYoVyE9PTApcmV0dXJuIFc7bGV0IHo9YXdhaXQgajAoVixYLFEpO2lmKHohPT0wKXJldHVybiB6O2xldHtwdWJLZXk6S309VixbRixOXT1hd2FpdCBZLmhhc1VzZXIoSyk7aWYoTiE9PTApcmV0dXJuIE47aWYoIUYpcmV0dXJuIDU7bGV0IE89W107d2hpbGUoIVouZG9uZSgpKXtsZXRbSCxNXT1aLnJlYWRWYXJJbnQoKTtpZihNIT09MClyZXR1cm4gTTtPLnB1c2goSCl9Y29uc29sZS5pbmZvKGBQVUxMOiAke08ubGVuZ3RofSBiYWdzYCk7bGV0W1UscV09YXdhaXQgWS5nZXRCb2RpZXMoSyxPKTtpZihxIT09MClyZXR1cm4gcTtpZighVSlyZXR1cm4gMTc7Zm9yKGxldHtzZXE6SCxib2R5Q3BoOk19b2YgVSl7bGV0IFA9e3NlcTpILGJvZHlDcGg6TX0sQz1KLndyaXRlU3RydWN0KHpaLFApO2lmKEMhPT0wKXJldHVybiBDfXJldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiAkLnJlYWRTdHJ1Y3RzKHpaKX19O3ZhciBLWj17ZW5jb2RlKCQsWil7JC53cml0ZUJ5dGVzKFouc2lnKSwkLndyaXRlQnl0ZXMoWi5rZG0pO2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmhlYWRDcGgpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJCeXRlcyhaLmJvZHlDcGgpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkQnl0ZXModzApO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPSQucmVhZEJ5dGVzKFQwKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbWSxWXT0kLnJlYWRWYXJCeXRlcygpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtXLHpdPSQucmVhZFZhckJ5dGVzKCk7aWYoeiE9PTApcmV0dXJuIEcoeik7cmV0dXJuIFIoe3NpZzpaLGtkbTpRLGhlYWRDcGg6WSxib2R5Q3BoOld9KX19O3ZhciBqJD17ZW5jb2RlKCQsWil7bGV0IEo9JC53cml0ZVZhckludChaLnNlcSk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZVZhckJ5dGVzKFouaGVhZENwaCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFg9Wi5ib2R5Q3BoP1ouYm9keUNwaC5sZW5ndGg6MCxZPSQud3JpdGVWYXJJbnQoWCk7aWYoWSE9PTApcmV0dXJuIFk7aWYoWD4wKXtpZighWi5ib2R5Q3BoKXJldHVybiAxMDskLndyaXRlQnl0ZXMoWi5ib2R5Q3BoKX1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZFZhckludCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPSQucmVhZFZhckJ5dGVzKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0W1ksVl09JC5yZWFkVmFySW50KCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0IFc7aWYoWT4wKXtsZXRbeixLXT0kLnJlYWRCeXRlcyhZKTtpZihLIT09MClyZXR1cm4gRyhLKTtXPXp9cmV0dXJuIFIoe3NlcTpaLGhlYWRDcGg6USxib2R5Q3BoOld9KX19O3ZhciBEJD17ZW5jb2RlKCQsWil7JC53cml0ZUJ5dGVzKFouc2lnKSwkLndyaXRlQnl0ZXMoWi5rZG0pO2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmhlYWRDcGgpO2lmKEohPT0wKXJldHVybiBKO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkQnl0ZXModzApO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPSQucmVhZEJ5dGVzKFQwKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbWSxWXT0kLnJlYWRWYXJCeXRlcygpO2lmKFYhPT0wKXJldHVybiBHKFYpO3JldHVybiBSKHtzaWc6WixrZG06USxoZWFkQ3BoOll9KX19O3ZhciBBJD17ZW5jb2RlKCQsWil7aWYoJC53cml0ZVZhckludChaLmlkeCksJC53cml0ZUJ5dGVzKG5ldyBVaW50OEFycmF5KFtaLnN0YXR1c10pKSxaLnN0YXR1cz09PTApJC53cml0ZVZhckludChaLnNlcSk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxYXT0kLnJlYWRCeXRlcygxKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXQgWT1RWzBdO2lmKFkhPT0wKXJldHVybiBSKHtpZHg6WixzdGF0dXM6WX0pO2xldFtWLFddPSQucmVhZFZhckludCgpO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBSKHtpZHg6WixzdGF0dXM6WSxzZXE6Vn0pfX07dmFyIEFKPXthc3luYyBlbmNvZGVSZXEoJCxaLEosUSxYKXtsZXQgWT1YLndyaXRlU3RydWN0KFkwLEopO2lmKFkhPT0wKXJldHVybiBZO2xldCBWPVgud3JpdGVTdHJ1Y3RzKEtaLFEpO2lmKFYhPT0wKXJldHVybiBWO3JldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxaLEope2xldHtjbG9jazpRLGNyeXB0bzpYLHN0b3JhZ2U6WSxub3RpZmllcjpWfT0kLFtXLHpdPVoucmVhZFN0cnVjdChZMCk7aWYoeiE9PTApcmV0dXJuIHo7bGV0IEs9YXdhaXQgajAoVyxYLFEpO2lmKEshPT0wKXJldHVybiBLO2xldHtwdWJLZXk6Rn09VyxbTixPXT1hd2FpdCBZLmhhc1VzZXIoRik7aWYoTyE9PTApcmV0dXJuIE87aWYoIU4pcmV0dXJuIDU7bGV0W1UscV09Wi5yZWFkU3RydWN0cyhLWik7aWYocSE9PTApcmV0dXJuIHE7Y29uc29sZS5pbmZvKGBQVVNIOiAke1UubGVuZ3RofSBiYWdzYCk7bGV0IEg9W10sTT1bXTtmb3IobGV0IEk9MDtJPFUubGVuZ3RoO0krKyl7bGV0IEE9VVtJXTtpZighYXdhaXQgUEooQSxGLFgpKXtsZXQgZz17aWR4Okksc3RhdHVzOjN9LGY9Si53cml0ZVN0cnVjdChBJCxnKTtpZihmIT09MClyZXR1cm4gZjtjb250aW51ZX1ILnB1c2goSSksTS5wdXNoKEEpfWxldFtQLENdPWF3YWl0IFkuc2V0QmFncyhGLE0pO2lmKEMhPT0wKXJldHVybiBDO2lmKCFQfHxQLmxlbmd0aCE9PU0ubGVuZ3RoKXJldHVybiAxNztsZXQgVD1bXTtmb3IobGV0IEk9MDtJPE0ubGVuZ3RoO0krKyl7bGV0IEE9TVtJXSx4PUhbSV0sZz1QW0ldLGY9bmV3IFMsaz1mLndyaXRlU3RydWN0KEQkLEEpO2lmKGshPT0wKXJldHVybiBrO2xldCBiPWYucmVzdWx0KCksdz17c2VxOmcsaGVhZENwaDpifTtpZihVLmxlbmd0aD09PTEmJkEuYm9keUNwaC5sZW5ndGg8PXpKKXcuYm9keUNwaD1BLmJvZHlDcGg7VC5wdXNoKHcpO2xldCBpPXtpZHg6eCxzdGF0dXM6MCxzZXE6Z30sdT1KLndyaXRlU3RydWN0KEEkLGkpO2lmKHUhPT0wKXJldHVybiB1fWlmKFQubGVuZ3RoPjApe2xldCBJPW5ldyBTLEE9SS53cml0ZVN0cnVjdHMoaiQsVCk7aWYoQSE9PTApcmV0dXJuIEE7bGV0IHg9SS5yZXN1bHQoKTthd2FpdCBQcm9taXNlLnJlc29sdmUoVi5wdXNoKEYseCkpfXJldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiAkLnJlYWRTdHJ1Y3RzKEEkKX19O3ZhciBfSj17YXN5bmMgZW5jb2RlUmVxKCQsWixKLFEsWCl7cmV0dXJuIFgud3JpdGVTdHJ1Y3QoWTAsSil9LGFzeW5jIGhhbmRsZVJlcSgkLFosSil7bGV0e2Nsb2NrOlEsY3J5cHRvOlgsc3RvcmFnZTpZfT0kLFtWLFddPVoucmVhZFN0cnVjdChZMCk7aWYoVyE9PTApcmV0dXJuIFc7bGV0IHo9YXdhaXQgajAoVixYLFEpO2lmKHohPT0wKXJldHVybiB6O2xldHtwdWJLZXk6S309VjtpZighWi5kb25lKCkpcmV0dXJuIDg7bGV0W0YsTl09YXdhaXQgWS5hZGRVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO3JldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiBSKHZvaWQgMCl9fTtjbGFzcyBGWnt1cmw7d2Vic29ja2V0O2NvbnN0cnVjdG9yKCQpe3RoaXMudXJsPSR9Y29ubmVjdGVkKCl7cmV0dXJuIHRoaXMud2Vic29ja2V0IT09dm9pZCAwJiZ0aGlzLndlYnNvY2tldC5yZWFkeVN0YXRlPT09V2ViU29ja2V0Lk9QRU59YXN5bmMgY29ubmVjdCgkLFosSj0oKT0+e30sUT0oKT0+e30pe2xldHt1cmw6WH09dGhpcztpZih0aGlzLndlYnNvY2tldCl0aGlzLndlYnNvY2tldC5jbG9zZSgpLHRoaXMud2Vic29ja2V0PXZvaWQgMDtsZXQgWT1uZXcgUztZLndyaXRlU3RydWN0KFkwLCQpO2xldCBWPVkucmVzdWx0KCksVz1OMChWKTtyZXR1cm4gWC5zZWFyY2hQYXJhbXMuc2V0KCJ0IixXKSx0aGlzLndlYnNvY2tldD1uZXcgV2ViU29ja2V0KFgpLHRoaXMud2Vic29ja2V0LmJpbmFyeVR5cGU9ImFycmF5YnVmZmVyIix0aGlzLndlYnNvY2tldC5vbm9wZW49KCk9Pntjb25zb2xlLmxvZygiQ09OTkVDVEVEIiksUSgpfSx0aGlzLndlYnNvY2tldC5vbmNsb3NlPSgpPT57Y29uc29sZS5sb2coIkRJU0NPTk5FQ1RFRCIpLHRoaXMud2Vic29ja2V0PXZvaWQgMCxKKCl9LHRoaXMud2Vic29ja2V0Lm9ubWVzc2FnZT0oeik9PntsZXQgSz1uZXcgVWludDhBcnJheSh6LmRhdGEpO1ooSyl9LHRoaXMud2Vic29ja2V0Lm9uZXJyb3I9KHopPT57Y29uc29sZS5sb2coYEVSUk9SOiAke0pTT04uc3RyaW5naWZ5KHopfWApLHRoaXMud2Vic29ja2V0PXZvaWQgMCxKKCl9LFByb21pc2UucmVzb2x2ZSgwKX1kaXNjb25uZWN0KCl7dGhpcy53ZWJzb2NrZXQ/LmNsb3NlKCksdGhpcy53ZWJzb2NrZXQ9dm9pZCAwfX12YXIgcj17dXNlcjp7cGF0aDoiL3VzZXIiLGVuZHBvaW50Ol9KLG5hbWU6MH0scHVzaDp7cGF0aDoiL3B1c2giLGVuZHBvaW50OkFKLG5hbWU6Mn0scGVlazp7cGF0aDoiL3BlZWsiLGVuZHBvaW50OmpKLG5hbWU6MX0scHVsbDp7cGF0aDoiL3B1bGwiLGVuZHBvaW50OkRKLG5hbWU6M319LEZYPXswOnIudXNlciwyOnIucHVzaCwxOnIucGVlaywzOnIucHVsbH0sTVc9e1tyLnVzZXIucGF0aF06ci51c2VyLFtyLnB1c2gucGF0aF06ci5wdXNoLFtyLnBlZWsucGF0aF06ci5wZWVrLFtyLnB1bGwucGF0aF06ci5wdWxsfTtjbGFzcyBMSnt1cmw7bGlzdGVuZXI7Y29uc3RydWN0b3IoJCl7dGhpcy51cmw9JDt0aGlzLmxpc3RlbmVyPW5ldyBGWigkKX1hc3luYyBjYWxsKCQsWil7bGV0e3BhdGg6Sn09RlhbJF0sUT1uZXcgVVJMKEosdGhpcy51cmwpO3RyeXtyZXR1cm4gYXdhaXQgTlgoUSxaKX1jYXRjaHtyZXR1cm4gRygyNSl9fX12YXIgeEo9KCQpPT57cmV0dXJuIG5ldyBMSigkLmhhbmRsZSl9O2FzeW5jIGZ1bmN0aW9uIE5YKCQsWil7bGV0IEo9YXdhaXQgZmV0Y2goJCx7bWV0aG9kOiJQT1NUIixib2R5OloucmVzdWx0KCkuc2xpY2UoKX0pO2lmKCFKLm9rKXJldHVybiBHKDI0KTtsZXQgUT1hd2FpdCBtLmZyb21SZXNwb25zZShKKTtyZXR1cm4gUihRKX1jbGFzcyBfJHtlbmNsYXZlO2NyeXB0bztob3N0O2Nsb2NrO3RyYW5zcG9ydDt1cGRhdGVIb3N0TWV0YTtjb25zdHJ1Y3RvcigkLFosSixRLFgsWSl7dGhpcy5lbmNsYXZlPSQ7dGhpcy5jcnlwdG89Wjt0aGlzLmhvc3Q9Sjt0aGlzLmNsb2NrPVE7dGhpcy50cmFuc3BvcnQ9WDt0aGlzLnVwZGF0ZUhvc3RNZXRhPVl9YXN5bmMgY2FsbCgkLFope2xldHtjbG9jazpKLHRyYW5zcG9ydDpRfT10aGlzLHtlbmRwb2ludDpYLG5hbWU6WX09JCxWPWF3YWl0IHRoaXMuaWRlbnRpdHkoKSxXPUoubm93KCksW3osS109YXdhaXQgWFooVixXKTtpZihLIT09MClyZXR1cm4gRyhLKTtsZXQgRj1uZXcgUyxOPWF3YWl0IFguZW5jb2RlUmVxKHRoaXMsVix6LFosRik7aWYoTiE9PTApcmV0dXJuIEcoTik7bGV0IE89Si5ub3coKSxbVSxxXT1hd2FpdCBRLmNhbGwoWSxGKSxIPUoubm93KCk7aWYocSE9PTApcmV0dXJuIEcocSk7bGV0W00sUF09VS5yZWFkU3RydWN0KFdaKTtpZihQIT09MClyZXR1cm4gRyhQKTtpZihNLnN0YXR1cyE9PTApcmV0dXJuIEcoTS5zdGF0dXMpO2xldCBUPXtjbG9ja09mZnNldDpUSihPLE0udGltZVJjdmQsTS50aW1lU2VudCxIKSxzdWJzY3JpcHRpb246TS5zdWJzY3JpcHRpb259LEk9YXdhaXQgdGhpcy51cGRhdGVIb3N0TWV0YShUKTtpZihJIT09MClyZXR1cm4gRyhJKTtyZXR1cm4gWC5kZWNvZGVSZXNwKFUpfWlkZW50aXR5PSgpPT57bGV0e2hvc3Q6JCxlbmNsYXZlOlp9PXRoaXM7cmV0dXJuIFouZGVyaXZlSWRlbnRpdHkoJC5sYWJlbCwkLmlkeD8/MCl9O3NlYWw9YXN5bmMoJCk9PntsZXR7Y3J5cHRvOlosZW5jbGF2ZTpKfT10aGlzLFE9YXdhaXQgdGhpcy5pZGVudGl0eSgpO3JldHVybiB3SigkLFEsWixKKX07cmVnaXN0ZXI9KCk9PnRoaXMuY2FsbChyLnVzZXIsW10pO3BlZWs9KCQpPT50aGlzLmNhbGwoci5wZWVrLFskXSk7cHVzaD0oJCk9PnRoaXMuY2FsbChyLnB1c2gsJCk7cHVsbD0oJCk9PnRoaXMuY2FsbChyLnB1bGwsJCk7bGlzdGVuPWFzeW5jKCQsWixKKT0+e2xldHtjbG9jazpRLHRyYW5zcG9ydDpYfT10aGlzLHtsaXN0ZW5lcjpZfT1YLFY9YXdhaXQgdGhpcy5pZGVudGl0eSgpLFc9US5ub3coKSxbeixLXT1hd2FpdCBYWihWLFcpO2lmKEshPT0wKXJldHVybiBLO3JldHVybiBhd2FpdCBZLmNvbm5lY3QoeiwkLFosSil9O2lzQ29ubmVjdGVkKCl7bGV0ICQ9dGhpcy50cmFuc3BvcnQ/Lmxpc3RlbmVyO2lmKCQmJnR5cGVvZiAkLmNvbm5lY3RlZD09PSJmdW5jdGlvbiIpcmV0dXJuICQuY29ubmVjdGVkKCk7cmV0dXJuITB9Y2xvc2VMaXN0ZW5lcigpe3RoaXMudHJhbnNwb3J0Py5saXN0ZW5lcj8uZGlzY29ubmVjdCgpfX12YXIgTlo9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVWYXJTdHJpbmcoWi5sYmwpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJJbnQoWi5pZHgpO2lmKFEhPT0wKXJldHVybiBRO2xldCBYPSQud3JpdGVWYXJJbnQoWi5udW0pO2lmKFghPT0wKXJldHVybiBYO3JldHVybiAkLndyaXRlQnl0ZXMoWi5oc2gpLCQud3JpdGVCeXRlcyhaLnNpZyksMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZFZhclN0cmluZygpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtZLFZdPSQucmVhZFZhckludCgpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtXLHpdPSQucmVhZEJ5dGVzKEgkKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXRbSyxGXT0kLnJlYWRCeXRlcyh3MCk7aWYoRiE9PTApcmV0dXJuIEcoRik7cmV0dXJuIFIoe2xibDpaLGlkeDpRLG51bTpZLGhzaDpXLHNpZzpLfSl9fTt2YXIgUlo9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVTdHJ1Y3QoTlosWi5oZWFkKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFyQnl0ZXMoWi5pbmRleEVuYyk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFg9JC53cml0ZVZhckJ5dGVzKFouYm9keUVuYyk7aWYoWCE9PTApcmV0dXJuIFg7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRTdHJ1Y3QoTlopO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPSQucmVhZFZhckJ5dGVzKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0W1ksVl09JC5yZWFkVmFyQnl0ZXMoKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gUih7aGVhZDpaLGluZGV4RW5jOlEsYm9keUVuYzpZfSl9fTt2YXIgT1o9e2VuY29kZSgkLFopeyQud3JpdGVCeXRlcyhaLmtkbSk7bGV0IEo9JC53cml0ZVZhckJ5dGVzKFouaGVhZENwaCk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZVZhckludChaLmxlbkJvZHkpO2lmKFEhPT0wKXJldHVybiBRO2lmKFoubGVuQm9keT4wJiZaLm9mZkJvZHkhPT12b2lkIDApe2xldCBYPSQud3JpdGVWYXJJbnQoWi5vZmZCb2R5KTtpZihYIT09MClyZXR1cm4gWH1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZEJ5dGVzKFQwKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxYXT0kLnJlYWRWYXJCeXRlcygpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtZLFZdPSQucmVhZFZhckludCgpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldCBXO2lmKFk+MCl7bGV0W3osS109JC5yZWFkVmFySW50KCk7aWYoSyE9PTApcmV0dXJuIEcoSyk7Vz16fXJldHVybiBSKHtrZG06WixoZWFkQ3BoOlEsbGVuQm9keTpZLG9mZkJvZHk6V30pfX07YXN5bmMgZnVuY3Rpb24gQkooJCxaLEosUSxYKXtsZXQgWT1hd2FpdCBYLmRlcml2ZUlkZW50aXR5KCQsWiksVj1uZXcgUyxXPW5ldyBTLHo9MCxLPTA7Zm9yKGxldCBQIG9mIEope2xldCBDPW5ldyBTLFQ9Qy53cml0ZVN0cnVjdChWMCxQLmhlYWQpO2lmKFQhPT0wKXJldHVybiBHKFQpO2xldCBJPUMucmVzdWx0KCksQT1hd2FpdCBZLmtkbUZvcihJKSx4PVguZGVyaXZlQ2lwaGVyKEEsImVuY3J5cHQiKSxnPWF3YWl0IHguZW5jcnlwdChJKSxmPVAuYm9keT9hd2FpdCB4LmVuY3J5cHQoUC5ib2R5KTpuZXcgVWludDhBcnJheSgwKSxrPVAuaGVhZC5sZW4+MCYmUC5oZWFkLmhzaCE9PXZvaWQgMD9mLmxlbmd0aDowLGI9e2tkbTpBLGhlYWRDcGg6ZyxsZW5Cb2R5Omssb2ZmQm9keTprPjA/Szp2b2lkIDB9LHc9Vi53cml0ZVN0cnVjdChPWixiKTtpZih3IT09MClyZXR1cm4gRyh3KTtpZihQLmJvZHkpVy53cml0ZUJ5dGVzKGYpLEsrPWYubGVuZ3RoO3orK31sZXQgRj1XLnJlc3VsdCgpLE49Vi5yZXN1bHQoKSxPPWF3YWl0IFEuYmxha2UzKE4pLFU9YXdhaXQgWS5zaWduKE8pLHE9e2xibDokLGlkeDpaLG51bTp6LGhzaDpPLHNpZzpVfSxIPW5ldyBTO0gud3JpdGVTdHJ1Y3QoUlose2hlYWQ6cSxpbmRleEVuYzpOLGJvZHlFbmM6Rn0pO2xldCBNPUgucmVzdWx0KCk7cmV0dXJuIFIoTSl9YXN5bmMgZnVuY3Rpb24ga0ooJCxaLEope2xldFtRLFhdPVJaLmRlY29kZShuZXcgbSgkKSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0e2hlYWQ6WSxpbmRleEVuYzpWLGJvZHlFbmM6V309USx6PWF3YWl0IEouZGVyaXZlSWRlbnRpdHkoWS5sYmwsWS5pZHgpO2lmKCFhd2FpdCBaLmNoZWNrU2lnRWQyNTUxOShZLnNpZyxZLmhzaCx6LnB1YmxpY0tleSkpcmV0dXJuIEcoMyk7bGV0IEY9YXdhaXQgWi5ibGFrZTMoVik7aWYoIWEoRixZLmhzaCkpcmV0dXJuIEcoMTkpO2xldCBOPW5ldyBtKFYpLE89W107Zm9yKGxldCBxPTA7cTxZLm51bTtxKyspe2xldFtILE1dPU4ucmVhZFN0cnVjdChPWik7aWYoTSE9PTApcmV0dXJuIEcoTSk7Ty5wdXNoKEgpfWlmKE8ubGVuZ3RoIT09WS5udW0pcmV0dXJuIEcoMTQpO2xldCBVPVtdO2ZvcihsZXQgcSBvZiBPKXtsZXQgSD1KLmRlcml2ZUNpcGhlcihxLmtkbSwiZGVjcnlwdCIpLE07dHJ5e009YXdhaXQgSC5kZWNyeXB0KHEuaGVhZENwaCl9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldFtQLENdPVYwLmRlY29kZShuZXcgbShNKSk7aWYoQyE9PTApcmV0dXJuIEcoQyk7bGV0IFQ7aWYocS5sZW5Cb2R5PjAmJnEub2ZmQm9keSE9PXZvaWQgMCl7aWYoUC5oc2g9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldCBJPVcuc2xpY2UocS5vZmZCb2R5LHEub2ZmQm9keStxLmxlbkJvZHkpO3RyeXtUPWF3YWl0IEguZGVjcnlwdChJKX1jYXRjaHtyZXR1cm4gRygyMCl9bGV0IEE9YXdhaXQgWi5ibGFrZTMoVCk7aWYoIWEoQSxQLmhzaCkpcmV0dXJuIEcoMTkpfVUucHVzaCh7aGVhZDpQLGJvZHk6VH0pfXJldHVybiBSKFUpfWFzeW5jIGZ1bmN0aW9uIEVKKHtub3c6JCxib2Q6WixjcnlwdG86Sn0pe2xldCBRPWF3YWl0IEouZ2VuUmFuZG9tQnl0ZXMoOCksWD1uZXcgUyxZPVgud3JpdGVTdHJ1Y3QoWDAse2lkOlEsdHM6JH0pO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBWPVgucmVzdWx0KCk7cmV0dXJuIEwkKHtub3c6JCxlaWQ6VixjdHI6MCxib2Q6WixjcnlwdG86Sn0pfWFzeW5jIGZ1bmN0aW9uIEwkKHtub3c6JCxlaWQ6WixjdHI6Sixib2Q6USxjcnlwdG86WH0pe2xldCBZPW5ldyBtKFopLFtWLFddPVgwLmRlY29kZShZKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXQgej0kLmdldFRpbWUoKS1WLnRzLmdldFRpbWUoKSxLLEY9UT8ubGVuZ3RoPz8wO2lmKFEmJkY+MClLPWF3YWl0IFguYmxha2UzKFEpO3JldHVybiBSKHtlaWQ6WixvZmY6eixjdHI6SixsZW46Rixoc2g6S30pfWZ1bmN0aW9uIFJYKCQsWil7bGV0IEo9JC5sZW5ndGg8Wi5sZW5ndGg/JC5sZW5ndGg6Wi5sZW5ndGg7Zm9yKGxldCBRPTA7UTxKO1ErKylpZigkW1FdIT09WltRXSlyZXR1cm4gJFtRXS1aW1FdO3JldHVybiAkLmxlbmd0aC1aLmxlbmd0aH1hc3luYyBmdW5jdGlvbiB6JCgkLFope2xldCBKPUFycmF5LmZyb20oJCk7Si5zb3J0KFJYKTtsZXQgUT0wO2ZvcihsZXQgViBvZiBKKVErPVYubGVuZ3RoO2xldCBYPW5ldyBVaW50OEFycmF5KFEpLFk9MDtmb3IobGV0IFYgb2YgSilYLnNldChWLFkpLFkrPVYubGVuZ3RoO3JldHVybiBaLmJsYWtlMyhYKX1mdW5jdGlvbiBPWCgkKXtsZXQgWj1uZXcgUyxKPVoud3JpdGVWYXJCeXRlcygkLmVpZCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0IFE9Wi53cml0ZURhdGUoJC51cGRhdGVkQXQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBYPVoud3JpdGVWYXJJbnQoJC5jdHIpO2lmKFghPT0wKXJldHVybiBHKFgpO3JldHVybiBSKFoucmVzdWx0KCkpfWFzeW5jIGZ1bmN0aW9uIHgkKCQsWil7bGV0IEo9W107Zm9yKGxldCBRIG9mICQpe2xldFtYLFldPU9YKFEpO2lmKFkhPT0wfHwhWClyZXR1cm4gRyhZKTtKLnB1c2goWCl9cmV0dXJuIFIoYXdhaXQgeiQoSixaKSl9dmFyIEZHPVN5bWJvbCgiTWFzdGVyU2VlZCIpLE5HPVN5bWJvbCgiU2VhbGVkTWFzdGVyS2V5IiksUjA9MzIsZko9MjQrUjArMTY7ZnVuY3Rpb24gZSgkKXtpZigkLmJ5dGVMZW5ndGghPT1SMClyZXR1cm4gRygxMCk7cmV0dXJuIFIoJCl9ZnVuY3Rpb24gRDAoJCl7aWYoJC5ieXRlTGVuZ3RoIT09ZkopcmV0dXJuIEcoMTApO3JldHVybiBSKCQpfXZhciBPRz1TeW1ib2woIkVudGl0eUlEIik7ZnVuY3Rpb24gZ0ooJCl7cmV0dXJuInR5cGUiaW4gJH12YXIgVUc9U3ltYm9sKCJEZXJpdmF0aW9uU2VlZCIpLHFHPVN5bWJvbCgiUHVibGljS2V5IiksSEc9U3ltYm9sKCJQcml2YXRlS2V5IiksTUc9U3ltYm9sKCJIb3N0U3BlY2lmaWNLZXlQYWlyIiksSUc9U3ltYm9sKCJIYXNoIik7ZnVuY3Rpb24gVVgoJCl7aWYoISQpcmV0dXJuITE7aWYodHlwZW9mICQhPT0ib2JqZWN0IilyZXR1cm4hMTtpZigiYm9keSJpbiAkPT09ITEpcmV0dXJuITE7aWYoInR5cGUiaW4gJD09PSExKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIHFYKCQpe2lmKCEkLmJvZHx8JC5ib2QubGVuZ3RoPT09MCl7bGV0IFE9e29mZjokLm9mZixjdHI6JC5jdHIsZWlkOiQuZWlkfTtyZXR1cm4gUihRKX1sZXQgWj1RWigkLmJvZCk7aWYoVVgoWik9PT0hMSlyZXR1cm4gY29uc29sZS53YXJuKCJtc2cgYm9keSBpbnZhbGlkIixaKSxHKDE0KTtsZXQgSj17b2ZmOiQub2ZmLGN0cjokLmN0cixlaWQ6JC5laWQsZ2lkOlouZ2lkLHBpZDpaLnBpZCx0YWdzOloudGFncyx0eXBlOloudHlwZSxib2R5OlouYm9keX07cmV0dXJuIFIoSil9Y2xhc3MgQiR7YXBwbGllcjtlbWl0dGVyPW5ldyBWJDtjbGVhcmVyO29uRGlydHlFaWRzO2NhY2hlRHJpdmVuO3BlZXJJbmdlc3Q7Y29uc3RydWN0b3IoJCxaLEosUSl7dGhpcy5hcHBsaWVyPSQ7dGhpcy5jbGVhcmVyPVosdGhpcy5vbkRpcnR5RWlkcz1KLHRoaXMuY2FjaGVEcml2ZW49UT8uY2FjaGVEcml2ZW4/PyExLHRoaXMucGVlckluZ2VzdD1RPy5wZWVySW5nZXN0fWFwcGx5PWFzeW5jKCQpPT57bGV0IFo9W10sSj1bXTtmb3IobGV0IFcgb2YgJCl7bGV0W3osS109cVgoVyk7aWYoSi5wdXNoKEspLEshPT0wKWNvbnRpbnVlO1oucHVzaCh6KX1sZXR7c3RhdHM6USx0eXBlczpYLGVpZHM6WX09YXdhaXQgdGhpcy5hcHBsaWVyKFopLFY9W107Zm9yKGxldCBXPTA7VzwkLmxlbmd0aDtXKyspe2xldCB6PUpbV10sSz1RW1ddO2lmKHohPT0wKXtWLnB1c2goeik7Y29udGludWV9aWYoSyE9PTApe1YucHVzaChLKTtjb250aW51ZX1WLnB1c2goMCl9aWYoIXRoaXMuY2FjaGVEcml2ZW4pZm9yKGxldCBXIG9mIFgpdGhpcy5lbWl0dGVyLmVtaXQoVyxudWxsKTtpZihZLmxlbmd0aD4wKXRoaXMub25EaXJ0eUVpZHM/LihZKTtyZXR1cm4gVn07Y2xlYXI9YXN5bmMoKT0+e2xldCAkPWF3YWl0IHRoaXMuY2xlYXJlcigpO2lmKCQhPT0wKXJldHVybiAkO3JldHVybiB0aGlzLmVtaXR0ZXIuZW1pdEFsbChudWxsKSwkfTtub3RpZnk9KCQpPT57Zm9yKGxldCBaIG9mICQpdGhpcy5lbWl0dGVyLmVtaXQoWixudWxsKX07cmVmcmVzaD1hc3luYygkKT0+e2lmKHRoaXMucGVlckluZ2VzdCl7YXdhaXQgdGhpcy5wZWVySW5nZXN0KCQpO3JldHVybn19O29uPSgkLFopPT57dGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoJCxaKX07b2ZmPSgkLFopPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJCxaKX19dmFyIGM9ImVudGl0aWVzIixrJD0iZW50aXR5X3R5cGVfY3JlYXRlZF9hdCIscVo9ImVudGl0eV90eXBlX3VwZGF0ZWRfYXQiLEhaPSJlbnRpdHlfdHlwZV9ncm91cF9pZCIsTVo9ImVudGl0eV90eXBlX3BhcmVudF9pZCIsbjA9ImVudGl0eV90YWdzIixtSj0iZGIiLFNKPTEzO2Z1bmN0aW9uIEhYKCQpe3JldHVybiJ0eXAiaW4gJH1mdW5jdGlvbiBNWCgkKXtsZXQgWj17Ym9kOiQuYm9keSxjcmQ6JC5jcmVhdGVkQXQsLi4uJC5jdHIhPT0wP3tjdHI6JC5jdHJ9Ont9LGVpZDpCKCQuZWlkKSxnaWQ6JC5naWQscGlkOiQucGlkP0IoJC5waWQpOnZvaWQgMCx0Z3M6JC50YWdzLHR5cDokLnR5cGUsdXBkOiQudXBkYXRlZEF0fTtpZihaLmdpZD09PXZvaWQgMClkZWxldGUgWi5naWQ7aWYoWi5waWQ9PT12b2lkIDApZGVsZXRlIFoucGlkO2lmKFoudGdzPT09dm9pZCAwKWRlbGV0ZSBaLnRncztpZihaLmN0cj09PXZvaWQgMClkZWxldGUgWi5jdHI7cmV0dXJuIFp9ZnVuY3Rpb24gSVgoJCl7aWYoIWgoJCkpcmV0dXJue2VpZDpCKCQuZWlkKSx1cGQ6JC51cGRhdGVkQXQsLi4uJC5jdHIhPT0wP3tjdHI6JC5jdHJ9Ont9fTtyZXR1cm4gTVgoJCl9ZnVuY3Rpb24gZDAoJCl7cmV0dXJue2JvZHk6JC5ib2QsY3JlYXRlZEF0OiQuY3JkLHVwZGF0ZWRBdDokLnVwZCxjdHI6JC5jdHI/PzAsdHlwZTokLnR5cCxlaWQ6RjAoJC5laWQpLGdpZDokLmdpZCxwaWQ6JC5waWQ/RjAoJC5waWQpOnZvaWQgMCwuLi4kLnRncyE9PXZvaWQgMD97dGFnczokLnRnc306e319fWZ1bmN0aW9uIFVaKCQpe2lmKEhYKCQpKXJldHVybiBkMCgkKTtyZXR1cm57ZWlkOkYwKCQuZWlkKSx1cGRhdGVkQXQ6JC51cGQsY3RyOiQuY3RyPz8wfX1jbGFzcyB2SntkYjtvcGVuaW5nO2FzeW5jIGluaXQoKXthd2FpdCB0aGlzLmVuc3VyZURiKCl9YXN5bmMgZW5zdXJlRGIoKXtpZih0aGlzLmRiKXJldHVybiB0aGlzLmRiO2lmKHRoaXMub3BlbmluZylyZXR1cm4gdGhpcy5vcGVuaW5nO3JldHVybiB0aGlzLm9wZW5pbmc9UFgoKS50aGVuKCgkKT0+e3JldHVybiAkLm9udmVyc2lvbmNoYW5nZT0oKT0+e2lmKCQuY2xvc2UoKSx0aGlzLmRiPT09JCl0aGlzLmRiPXZvaWQgMH0sdGhpcy5kYj0kLHRoaXMub3BlbmluZz12b2lkIDAsJH0sKCQpPT57dGhyb3cgdGhpcy5vcGVuaW5nPXZvaWQgMCwkfSksdGhpcy5vcGVuaW5nfWFwcGx5PWFzeW5jKCQpPT57bGV0IFo9bmV3IFNldCxKPVtdLFE7dHJ5e1E9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybntzdGF0czokLm1hcCgoKT0+MTYpLHR5cGVzOlosZWlkczpKfX1sZXQgWD1RLnRyYW5zYWN0aW9uKGMsInJlYWR3cml0ZSIpLFk9WC5vYmplY3RTdG9yZShjKTtyZXR1cm4gbmV3IFByb21pc2UoKFYpPT57bGV0IFc9QXJyYXkoJC5sZW5ndGgpLmZpbGwoMCk7aWYoJC5sZW5ndGg8MSl7Vih7c3RhdHM6W10sdHlwZXM6WixlaWRzOkp9KTtyZXR1cm59WC5vbmNvbXBsZXRlPSgpPT57Vih7c3RhdHM6Vyx0eXBlczpaLGVpZHM6Sn0pfSxYLm9uZXJyb3I9KCk9Pntmb3IobGV0IEs9MDtLPFcubGVuZ3RoO0srKylpZihXW0tdPT09dm9pZCAwKVdbS109MTg7Vih7c3RhdHM6Vyx0eXBlczpaLGVpZHM6Sn0pfTtsZXQgej1uZXcgTWFwO2ZvcihsZXQgSz0wO0s8JC5sZW5ndGg7SysrKXtsZXQgRj0kW0tdLE49QihGLmVpZCksTz17b3A6RixpbmRleDpLfSxVPXouZ2V0KE4pO2lmKFUpVS5wdXNoKE8pO2Vsc2Ugei5zZXQoTixbT10pfWZvcihsZXRbSyxGXW9mIHope2lmKEYubGVuZ3RoPDEpY29udGludWU7bGV0IE49WS5nZXQoSyk7Ti5vbnN1Y2Nlc3M9KCk9PntsZXQgTz1OLnJlc3VsdCxVPU8/VVooTyk6dm9pZCAwLHE9ITE7Zm9yKGxldHtvcDpILGluZGV4Ok19b2YgRil7bGV0W1AsQ109cjAoVSxIKTtpZihDIT09MCl7V1tNXT1DO2NvbnRpbnVlfWlmKFA9PT12b2lkIDApe1dbTV09MTI7Y29udGludWV9cT0hMDtmb3IobGV0IFQgb2YgbzAoVSxQKSlaLmFkZChUKTtVPVB9aWYocSlKLnB1c2goRlswXS5vcC5laWQpO2lmKFUpe2xldCBIPVkucHV0KElYKFUpKTtILm9uZXJyb3I9KE0pPT57TS5wcmV2ZW50RGVmYXVsdCgpO2ZvcihsZXR7aW5kZXg6UH1vZiBGKVdbUF09MTh9fX0sTi5vbmVycm9yPSgpPT57Zm9yKGxldHtpbmRleDpPfW9mIEYpV1tPXT0xOH19fSl9O2FzeW5jIGNsZWFyKCl7bGV0ICQ7dHJ5eyQ9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiAxNn1sZXQgWj0kLnRyYW5zYWN0aW9uKGMsInJlYWR3cml0ZSIpLEo9Wi5vYmplY3RTdG9yZShjKTtyZXR1cm4gbmV3IFByb21pc2UoKFEpPT57Wi5vbmNvbXBsZXRlPSgpPT5RKDApLFoub25lcnJvcj0oKT0+USgxOCksSi5jbGVhcigpfSl9YXN5bmMgZ2V0Um93KCQpe2xldCBaO3RyeXtaPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IEo9QigkKSxYPVoudHJhbnNhY3Rpb24oYywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShjKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFY9WC5nZXQoSik7Vi5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1WLnJlc3VsdDtpZighVylZKFIodm9pZCAwKSk7ZWxzZSBZKFIoVVooVykpKX0sVi5vbmVycm9yPSgpPT5ZKEcoMTgpKX0pfWFzeW5jIGdldEVudCgkKXtsZXRbWixKXT1hd2FpdCB0aGlzLmdldFJvdygkKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwfHwhaChaKSlyZXR1cm4gUih2b2lkIDApO3JldHVybiBSKFopfWFzeW5jIGdldEFsbE9mVHlwZVVwZGF0ZWRCZXR3ZWVuKCQsWixKKXtsZXQgUTt0cnl7UT1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBZPVEudHJhbnNhY3Rpb24oYywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShjKS5pbmRleChxWik7cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBXPVkuZ2V0QWxsKElEQktleVJhbmdlLmJvdW5kKFskLFpdLFskLEpdKSk7Vy5vbnN1Y2Nlc3M9KCk9PntsZXQgej1XLnJlc3VsdDtWKFIoei5tYXAoZDApKSl9LFcub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBnZXRHcm91cE1lbWJlcnMoJCxaKXtsZXQgSjt0cnl7Sj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBYPUoudHJhbnNhY3Rpb24oYywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShjKS5pbmRleChIWik7cmV0dXJuIG5ldyBQcm9taXNlKChZKT0+e2xldCBWPVguZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoWyQsWl0pKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVYucmVzdWx0O1koUihXLm1hcChkMCkpKX0sVi5vbmVycm9yPSgpPT5ZKEcoMTgpKX0pfWFzeW5jIGdldEFsbE9mVHlwZSgkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBRPVoudHJhbnNhY3Rpb24oYywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShjKS5pbmRleChrJCk7cmV0dXJuIG5ldyBQcm9taXNlKChYKT0+e2xldCBZPVEuZ2V0QWxsKElEQktleVJhbmdlLmJvdW5kKFskXSxbJCxbXV0pKTtZLm9uc3VjY2Vzcz0oKT0+e2xldCBWPVkucmVzdWx0O1goUihWLm1hcChkMCkpKX0sWS5vbmVycm9yPSgpPT5YKEcoMTgpKX0pfWFzeW5jIGdldEJ5VGFnKCQsWil7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgWD1KLnRyYW5zYWN0aW9uKGMsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoYykuaW5kZXgobjApO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgVj1YLmdldEFsbChJREJLZXlSYW5nZS5vbmx5KFopKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCB6PVYucmVzdWx0LmZpbHRlcigoSyk9PksudHlwPT09JCkubWFwKGQwKTtZKFIoeikpfSxWLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9YXN5bmMgZ2V0QWxsRW50aXRpZXMoJCl7aWYoInBpZCJpbiAkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBKPUIoJC5waWQpLFg9Wi50cmFuc2FjdGlvbihjLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGMpLmluZGV4KE1aKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFY9WC5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShbJC50eXBlLEpdKSk7Vi5vbnN1Y2Nlc3M9KCk9PntsZXQgej1WLnJlc3VsdC5tYXAoZDApO1koUih6KSl9LFYub25lcnJvcj0oKT0+WShHKDE4KSl9KX1lbHNlIGlmKCJnaWQiaW4gJClyZXR1cm4gYXdhaXQgdGhpcy5nZXRHcm91cE1lbWJlcnMoJC50eXBlLCQuZ2lkKTtlbHNlIGlmKCJ0YWciaW4gJClyZXR1cm4gYXdhaXQgdGhpcy5nZXRCeVRhZygkLnR5cGUsJC50YWcpO2Vsc2UgaWYoInVwZGF0ZWRCZXR3ZWVuImluICQpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0QWxsT2ZUeXBlVXBkYXRlZEJldHdlZW4oJC50eXBlLCQudXBkYXRlZEJldHdlZW4uc3RhcnQsJC51cGRhdGVkQmV0d2Vlbi5lbmQpO3JldHVybiBhd2FpdCB0aGlzLmdldEFsbE9mVHlwZSgkLnR5cGUpfWFzeW5jIGdldEVudGl0aWVzKCQpe2xldFtaLEpdPWF3YWl0IHRoaXMuZ2V0QWxsRW50aXRpZXMoJCk7aWYoSiE9PTApcmV0dXJuIEcoSik7cmV0dXJuIFIoWil9YXN5bmMgY291bnRFbnRpdGllcyh7dHlwZTokfSl7bGV0IFo7dHJ5e1o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgUT1aLnRyYW5zYWN0aW9uKGMsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoYykuaW5kZXgoayQpO3JldHVybiBuZXcgUHJvbWlzZSgoWCk9PntsZXQgWT1JREJLZXlSYW5nZS5ib3VuZChbJF0sWyQsW11dKSxWPVEuY291bnQoWSk7Vi5vbnN1Y2Nlc3M9KCk9PlgoUihWLnJlc3VsdCkpLFYub25lcnJvcj0oKT0+WChHKDE4KSl9KX1hc3luYyBjaGVja3N1bSgkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBRPVoudHJhbnNhY3Rpb24oYywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShjKSxYPVtdO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgVj1RLm9wZW5DdXJzb3IoKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVYucmVzdWx0O2lmKFcpe2xldCB6PVcudmFsdWU7WC5wdXNoKEUkKFVaKHopKSksVy5jb250aW51ZSgpfWVsc2UgeCQoWCwkKS50aGVuKFkpfSxWLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9fWZ1bmN0aW9uIENYKCQsWil7aWYoISQub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhjKSkkLmNyZWF0ZU9iamVjdFN0b3JlKGMse2tleVBhdGg6ImVpZCIsYXV0b0luY3JlbWVudDohMX0pO2xldCBKPVoub2JqZWN0U3RvcmUoYyk7aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhrJCkpSi5jcmVhdGVJbmRleChrJCxbInR5cCIsImNyZCJdLHt1bmlxdWU6ITF9KTtpZighSi5pbmRleE5hbWVzLmNvbnRhaW5zKHFaKSlKLmNyZWF0ZUluZGV4KHFaLFsidHlwIiwidXBkIl0se3VuaXF1ZTohMX0pO2lmKCFKLmluZGV4TmFtZXMuY29udGFpbnMoSFopKUouY3JlYXRlSW5kZXgoSFosWyJ0eXAiLCJnaWQiXSx7dW5pcXVlOiExfSk7aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhNWikpSi5jcmVhdGVJbmRleChNWixbInR5cCIsInBpZCJdLHt1bmlxdWU6ITF9KTtpZihKLmluZGV4TmFtZXMuY29udGFpbnMobjApKXtpZihKLmluZGV4KG4wKS5rZXlQYXRoIT09InRncyIpSi5kZWxldGVJbmRleChuMCl9aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhuMCkpSi5jcmVhdGVJbmRleChuMCwidGdzIix7dW5pcXVlOiExLG11bHRpRW50cnk6ITB9KX1mdW5jdGlvbiBQWCgpe3JldHVybiBuZXcgUHJvbWlzZSgoJCxaKT0+e2xldCBKPWluZGV4ZWREQi5vcGVuKG1KLFNKKTtKLm9udXBncmFkZW5lZWRlZD0oKT0+e2xldHtyZXN1bHQ6USx0cmFuc2FjdGlvbjpYfT1KO2lmKCFYKXtaKEVycm9yKCJUcmFuc2FjdGlvbiBpcyBudWxsIGR1cmluZyBFbnREQiB1cGdyYWRlIikpO3JldHVybn10cnl7Q1goUSxYKX1jYXRjaChZKXtaKFkgaW5zdGFuY2VvZiBFcnJvcj9ZOkVycm9yKFN0cmluZyhZKSkpfX0sSi5vbmJsb2NrZWQ9KCk9Pntjb25zb2xlLndhcm4oYFtESVBMT01BVElDXSBFbnREQiBJREIgdXBncmFkZSBibG9ja2VkICgke21KfSDihpIgdiR7U0p9KTsgd2FpdGluZyBmb3Igb3RoZXIgY29ubmVjdGlvbnMgdG8gY2xvc2VgKX0sSi5vbnN1Y2Nlc3M9KCk9PiQoSi5yZXN1bHQpLEoub25lcnJvcj0oKT0+WihKLmVycm9yPz9FcnJvcigiRW50REIgSW5kZXhlZERCIG9wZW4gZmFpbGVkIikpfSl9YXN5bmMgZnVuY3Rpb24gYkooKXtsZXQgJD1uZXcgdko7cmV0dXJuIGF3YWl0ICQuaW5pdCgpLCR9Y2xhc3MgSVp7ZW50cz1uZXcgTWFwO3VzZUluZGV4O2J5VHlwZT1uZXcgTWFwO2J5VHlwZVBpZD1uZXcgTWFwO2J5VHlwZUdpZD1uZXcgTWFwO2J5VHlwZVRhZz1uZXcgTWFwO2NvbnN0cnVjdG9yKCQ9W10sWil7dGhpcy51c2VJbmRleD1aPy5pbmRleGVzIT09ITE7Zm9yKGxldCBKIG9mICQpdGhpcy5wdXQoSil9cHV0KCQpe2xldCBaPUIoJC5laWQpLEo9dGhpcy5lbnRzLmdldChaKTtpZihKIT09dm9pZCAwJiZoKEopKXRoaXMudW5pbmRleChaLEopO2lmKHRoaXMuZW50cy5zZXQoWiwkKSxoKCQpKXRoaXMuaW5kZXgoWiwkKX1kZWwoJCl7bGV0IFo9dGhpcy5lbnRzLmdldCgkKTtpZihaPT09dm9pZCAwKXJldHVybjtpZihoKFopKXRoaXMudW5pbmRleCgkLFopO3RoaXMuZW50cy5kZWxldGUoJCl9aW5kZXgoJCxaKXtpZighdGhpcy51c2VJbmRleClyZXR1cm47bGV0IEo9dGhpcy5ieVR5cGUuZ2V0KFoudHlwZSk7aWYoIUopSj1uZXcgTWFwLHRoaXMuYnlUeXBlLnNldChaLnR5cGUsSik7aWYoSi5zZXQoJCxaKSxaLnBpZCl7bGV0IFE9QihaLnBpZCksWD10aGlzLmJ5VHlwZVBpZC5nZXQoWi50eXBlKTtpZighWClYPW5ldyBNYXAsdGhpcy5ieVR5cGVQaWQuc2V0KFoudHlwZSxYKTtsZXQgWT1YLmdldChRKTtpZighWSlZPW5ldyBNYXAsWC5zZXQoUSxZKTtZLnNldCgkLFopfWlmKHR5cGVvZiBaLmdpZD09PSJzdHJpbmciKXtsZXQgUT10aGlzLmJ5VHlwZUdpZC5nZXQoWi50eXBlKTtpZighUSlRPW5ldyBNYXAsdGhpcy5ieVR5cGVHaWQuc2V0KFoudHlwZSxRKTtsZXQgWD1RLmdldChaLmdpZCk7aWYoIVgpWD1uZXcgTWFwLFEuc2V0KFouZ2lkLFgpO1guc2V0KCQsWil9aWYoWi50YWdzKXtsZXQgUT10aGlzLmJ5VHlwZVRhZy5nZXQoWi50eXBlKTtpZighUSlRPW5ldyBNYXAsdGhpcy5ieVR5cGVUYWcuc2V0KFoudHlwZSxRKTtmb3IobGV0IFggb2YgWi50YWdzKXtsZXQgWT1RLmdldChYKTtpZighWSlZPW5ldyBNYXAsUS5zZXQoWCxZKTtZLnNldCgkLFopfX19dW5pbmRleCgkLFope2lmKCF0aGlzLnVzZUluZGV4KXJldHVybjtsZXQgSj10aGlzLmJ5VHlwZS5nZXQoWi50eXBlKTtpZihKKXtpZihKLmRlbGV0ZSgkKSxKLnNpemU9PT0wKXRoaXMuYnlUeXBlLmRlbGV0ZShaLnR5cGUpfWlmKFoucGlkKXtsZXQgUT1CKFoucGlkKSxYPXRoaXMuYnlUeXBlUGlkLmdldChaLnR5cGUpLFk9WD8uZ2V0KFEpO2lmKFkpe2lmKFkuZGVsZXRlKCQpLFkuc2l6ZT09PTApWD8uZGVsZXRlKFEpfWlmKFgmJlguc2l6ZT09PTApdGhpcy5ieVR5cGVQaWQuZGVsZXRlKFoudHlwZSl9aWYodHlwZW9mIFouZ2lkPT09InN0cmluZyIpe2xldCBRPXRoaXMuYnlUeXBlR2lkLmdldChaLnR5cGUpLFg9UT8uZ2V0KFouZ2lkKTtpZihYKXtpZihYLmRlbGV0ZSgkKSxYLnNpemU9PT0wKVE/LmRlbGV0ZShaLmdpZCl9aWYoUSYmUS5zaXplPT09MCl0aGlzLmJ5VHlwZUdpZC5kZWxldGUoWi50eXBlKX1pZihaLnRhZ3Mpe2xldCBRPXRoaXMuYnlUeXBlVGFnLmdldChaLnR5cGUpO2lmKFEpe2ZvcihsZXQgWCBvZiBaLnRhZ3Mpe2xldCBZPVEuZ2V0KFgpO2lmKFkpe2lmKFkuZGVsZXRlKCQpLFkuc2l6ZT09PTApUS5kZWxldGUoWCl9fWlmKFEuc2l6ZT09PTApdGhpcy5ieVR5cGVUYWcuZGVsZXRlKFoudHlwZSl9fX1jbGVhckluZGV4ZXMoKXt0aGlzLmJ5VHlwZS5jbGVhcigpLHRoaXMuYnlUeXBlUGlkLmNsZWFyKCksdGhpcy5ieVR5cGVHaWQuY2xlYXIoKSx0aGlzLmJ5VHlwZVRhZy5jbGVhcigpfWJ1Y2tldExpc3QoJCl7aWYoISR8fCQuc2l6ZT09PTApcmV0dXJuW107bGV0IFo9W107Zm9yKGxldCBKIG9mICQudmFsdWVzKCkpWi5wdXNoKEopO3JldHVybiBafWFzeW5jIGFwcGx5KCQpe2xldCBaPW5ldyBTZXQsSj1bXSxRPVtdO2ZvcihsZXQgWCBvZiAkKXtsZXQgWT1CKFguZWlkKSxWPXRoaXMuZW50cy5nZXQoWSksW1csel09cjAoVixYKTtpZih6IT09MCl7US5wdXNoKHopO2NvbnRpbnVlfWlmKFc9PT12b2lkIDApe1EucHVzaCgxMik7Y29udGludWV9Zm9yKGxldCBLIG9mIG8wKFYsVykpWi5hZGQoSyk7dGhpcy5wdXQoVyksSi5wdXNoKFguZWlkKSxRLnB1c2goMCl9cmV0dXJue3N0YXRzOlEsdHlwZXM6WixlaWRzOkp9fWFzeW5jIGNsZWFyKCl7cmV0dXJuIHRoaXMuZW50cy5jbGVhcigpLHRoaXMuY2xlYXJJbmRleGVzKCksMH1hc3luYyBnZXRSb3coJCl7bGV0IFo9QigkKSxKPXRoaXMuZW50cy5nZXQoWik7cmV0dXJuIFIoSil9YXN5bmMgZ2V0RW50KCQpe2xldFtaLEpdPWF3YWl0IHRoaXMuZ2V0Um93KCQpO2lmKEohPT0wKXJldHVybiBHKEopO2lmKFo9PT12b2lkIDB8fCFoKFopKXJldHVybiBSKHZvaWQgMCk7cmV0dXJuIFIoWil9YXN5bmMgZ2V0QWxsRW50aXRpZXMoe3R5cGU6JCxnaWQ6WixwaWQ6Six0YWc6USx1cGRhdGVkQmV0d2VlbjpYfSl7aWYodGhpcy51c2VJbmRleCl7aWYoSiE9PXZvaWQgMCl7bGV0IFY9QihKKTtyZXR1cm4gUih0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGVQaWQuZ2V0KCQpPy5nZXQoVikpKX1pZihaIT09dm9pZCAwKXJldHVybiBSKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZUdpZC5nZXQoJCk/LmdldChaKSkpO2lmKFEhPT12b2lkIDApcmV0dXJuIFIodGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlVGFnLmdldCgkKT8uZ2V0KFEpKSk7aWYoWCE9PXZvaWQgMCl7bGV0IFY9W10sVz10aGlzLmJ5VHlwZS5nZXQoJCk7aWYoVyl7Zm9yKGxldCB6IG9mIFcudmFsdWVzKCkpaWYoei51cGRhdGVkQXQ+PVguc3RhcnQmJnoudXBkYXRlZEF0PD1YLmVuZClWLnB1c2goeil9cmV0dXJuIFIoVil9cmV0dXJuIFIodGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlLmdldCgkKSkpfWxldCBZPVtdO2lmKEohPT12b2lkIDApe2ZvcihsZXQgViBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaChWKSYmVi50eXBlPT09JCYmVi5waWQmJmEoVi5waWQsSikpWS5wdXNoKFYpfWVsc2UgaWYoWiE9PXZvaWQgMCl7Zm9yKGxldCBWIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihoKFYpJiZWLnR5cGU9PT0kJiYodHlwZW9mIFYuZ2lkPT09InN0cmluZyImJlYuZ2lkPT09WikpWS5wdXNoKFYpfWVsc2UgaWYoUSE9PXZvaWQgMCl7Zm9yKGxldCBWIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihoKFYpJiZWLnR5cGU9PT0kJiZWLnRhZ3MmJlYudGFncy5pbmNsdWRlcyhRKSlZLnB1c2goVil9ZWxzZSBpZihYIT09dm9pZCAwKXtmb3IobGV0IFYgb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGgoVikmJlYudHlwZT09PSQmJlYudXBkYXRlZEF0Pj1YLnN0YXJ0JiZWLnVwZGF0ZWRBdDw9WC5lbmQpWS5wdXNoKFYpfWVsc2UgZm9yKGxldCBWIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihoKFYpJiZWLnR5cGU9PT0kKVkucHVzaChWKTtyZXR1cm4gUihZKX1hc3luYyBnZXRFbnRpdGllcygkKXtsZXRbWixKXT1hd2FpdCB0aGlzLmdldEFsbEVudGl0aWVzKCQpO2lmKEohPT0wKXJldHVybiBHKEopO3JldHVybiBSKFopfWFzeW5jIGNvdW50RW50aXRpZXMoe3R5cGU6JH0pe2lmKHRoaXMudXNlSW5kZXgpcmV0dXJuIFIodGhpcy5ieVR5cGUuZ2V0KCQpPy5zaXplPz8wKTtsZXQgWj0wO2ZvcihsZXQgSiBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaChKKSYmSi50eXBlPT09JClaKz0xO3JldHVybiBSKFopfWFzeW5jIGNoZWNrc3VtKCQpe2xldCBaPVtdO2ZvcihsZXQgSiBvZiB0aGlzLmVudHMudmFsdWVzKCkpWi5wdXNoKEUkKEopKTtyZXR1cm4geCQoWiwkKX19YXN5bmMgZnVuY3Rpb24geUooJCl7bGV0IFo9YXdhaXQgYkooKTtpZigkPy5jYWNoZT09PSExKXJldHVybiBaO3JldHVybiBuZXcgQ1ooWix2b2lkIDAse2luZGV4ZXM6JD8uaW5kZXhlc30pfWNsYXNzIENae21lbTtkdXJhYmxlO3dhcm1lZD1uZXcgU2V0O2xpc3RlbmVycz1uZXcgU2V0O2NoYWluPVByb21pc2UucmVzb2x2ZSgpO2NvbnN0cnVjdG9yKCQsWixKKXtpZih0aGlzLmR1cmFibGU9JCx0aGlzLm1lbT1uZXcgSVooWj8/W10se2luZGV4ZXM6Sj8uaW5kZXhlc30pLFopZm9yKGxldCBRIG9mIFopdGhpcy53YXJtZWQuYWRkKFEudHlwZSl9c3Vic2NyaWJlKCQpe3JldHVybiB0aGlzLmxpc3RlbmVycy5hZGQoJCksKCk9Pnt0aGlzLmxpc3RlbmVycy5kZWxldGUoJCl9fWVtaXQoJCl7aWYoJC5zaXplPDEpcmV0dXJuO2ZvcihsZXQgWiBvZiB0aGlzLmxpc3RlbmVycylaKCQpfXJ1bigkKXtsZXQgWj10aGlzLmNoYWluLnRoZW4oJCwkKTtyZXR1cm4gdGhpcy5jaGFpbj1aLnRoZW4oKCk9PntyZXR1cm59LCgpPT57cmV0dXJufSksWn1hcHBseSgkKXtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2F3YWl0IHRoaXMucHVsbEVpZHMoJC5tYXAoKFkpPT5ZLmVpZCkpO2xldCBaPV9YKHRoaXMubWVtLCQpO3RoaXMuZW1pdChaLnR5cGVzKTtsZXQgSj1hd2FpdCB0aGlzLmR1cmFibGUuYXBwbHkoJCkse2NoYW5nZWQ6USxzdGF0dXM6WH09YXdhaXQgdGhpcy5wdWxsRWlkcygkLm1hcCgoWSk9PlkuZWlkKSk7aWYodGhpcy5lbWl0KFEpLFghPT0wKXJldHVybntzdGF0czokLm1hcCgoKT0+WCksdHlwZXM6Si50eXBlcyxlaWRzOkouZWlkc307cmV0dXJuIEp9KX1jbGVhcigpe3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57bGV0ICQ9YXdhaXQgdGhpcy5kdXJhYmxlLmNsZWFyKCk7aWYoJCE9PTApcmV0dXJuICQ7bGV0IFo9dGhpcy5tZW0uZW50cy5zaXplPjA7cmV0dXJuIGF3YWl0IHRoaXMubWVtLmNsZWFyKCksdGhpcy53YXJtZWQuY2xlYXIoKSwwfSl9aW5nZXN0RnJvbUR1cmFibGUoJCl7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9PntsZXR7Y2hhbmdlZDpaLHN0YXR1czpKfT1hd2FpdCB0aGlzLnB1bGxFaWRzKCQpO3JldHVybiB0aGlzLmVtaXQoWiksSn0pfWFzeW5jIHB1bGxFaWRzKCQpe2xldCBaPW5ldyBTZXQsSj1uZXcgU2V0O2ZvcihsZXQgUSBvZiAkKXtsZXQgWD1CKFEpO2lmKEouaGFzKFgpKWNvbnRpbnVlO0ouYWRkKFgpO2xldCBZPXRoaXMubWVtLmVudHMuZ2V0KFgpLFtWLFddPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRSb3coUSk7aWYoVyE9PTApcmV0dXJue2NoYW5nZWQ6WixzdGF0dXM6V307aWYoVil7aWYodGhpcy5tZW0ucHV0KFYpLCFZfHwhd1goWSxWKSl7aWYoaChWKSlaLmFkZChWLnR5cGUpO2lmKFkhPT12b2lkIDAmJmgoWSkpWi5hZGQoWS50eXBlKX19ZWxzZSBpZihZIT09dm9pZCAwKXtpZih0aGlzLm1lbS5kZWwoWCksaChZKSlaLmFkZChZLnR5cGUpfX1yZXR1cm57Y2hhbmdlZDpaLHN0YXR1czowfX1hc3luYyB3YXJtVHlwZSgkKXtpZih0aGlzLndhcm1lZC5oYXMoJCkpcmV0dXJuIDA7bGV0W1osSl09YXdhaXQgdGhpcy5kdXJhYmxlLmdldEVudGl0aWVzKHt0eXBlOiR9KTtpZihKIT09MClyZXR1cm4gSjtpZihaKWZvcihsZXQgUSBvZiBaKXtsZXQgWD1CKFEuZWlkKSxZPXRoaXMubWVtLmVudHMuZ2V0KFgpO2lmKCFZfHxBWChRLFkpKXRoaXMubWVtLnB1dChRKX1yZXR1cm4gdGhpcy53YXJtZWQuYWRkKCQpLDB9YXN5bmMgZ2V0Um93KCQpe2xldCBaPUIoJCk7aWYodGhpcy5tZW0uZW50cy5oYXMoWikpcmV0dXJuIHRoaXMubWVtLmdldFJvdygkKTtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2lmKHRoaXMubWVtLmVudHMuaGFzKFopKXJldHVybiB0aGlzLm1lbS5nZXRSb3coJCk7bGV0W0osUV09YXdhaXQgdGhpcy5kdXJhYmxlLmdldFJvdygkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKKXRoaXMubWVtLnB1dChKKTtyZXR1cm4gUihKKX0pfWFzeW5jIGdldEVudCgkKXtsZXRbWixKXT1hd2FpdCB0aGlzLmdldFJvdygkKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwfHwhaChaKSlyZXR1cm4gUih2b2lkIDApO3JldHVybiBSKFopfWFzeW5jIGdldEVudGl0aWVzKCQpe2lmKCF0aGlzLndhcm1lZC5oYXMoJC50eXBlKSl7bGV0IFo9YXdhaXQgdGhpcy5ydW4oKCk9PnRoaXMud2FybVR5cGUoJC50eXBlKSk7aWYoWiE9PTApcmV0dXJuIEcoWil9cmV0dXJuIHRoaXMubWVtLmdldEVudGl0aWVzKCQpfWFzeW5jIGNvdW50RW50aXRpZXMoe3R5cGU6JH0pe2lmKCF0aGlzLndhcm1lZC5oYXMoJCkpe2xldCBaPWF3YWl0IHRoaXMucnVuKCgpPT50aGlzLndhcm1UeXBlKCQpKTtpZihaIT09MClyZXR1cm4gRyhaKX1yZXR1cm4gdGhpcy5tZW0uY291bnRFbnRpdGllcyh7dHlwZTokfSl9YXN5bmMgY2hlY2tzdW0oJCl7cmV0dXJuIHRoaXMuZHVyYWJsZS5jaGVja3N1bSgkKX19ZnVuY3Rpb24gd1goJCxaKXtpZihoKCQpIT09aChaKSlyZXR1cm4hMTtpZigkLmN0ciE9PVouY3RyKXJldHVybiExO2lmKCQudXBkYXRlZEF0LmdldFRpbWUoKSE9PVoudXBkYXRlZEF0LmdldFRpbWUoKSlyZXR1cm4hMTtpZighYSgkLmVpZCxaLmVpZCkpcmV0dXJuITE7aWYoIWgoJCl8fCFoKFopKXJldHVybiEwO2lmKCQuY3JlYXRlZEF0LmdldFRpbWUoKSE9PVouY3JlYXRlZEF0LmdldFRpbWUoKSlyZXR1cm4hMTtpZigkLnR5cGUhPT1aLnR5cGUpcmV0dXJuITE7aWYoJC5naWQhPT1aLmdpZClyZXR1cm4hMTtpZighalgoJC5waWQsWi5waWQpKXJldHVybiExO2lmKCFUWCgkLnRhZ3MsWi50YWdzKSlyZXR1cm4hMTtyZXR1cm4gRFgoJC5ib2R5LFouYm9keSl9ZnVuY3Rpb24gVFgoJCxaKXtpZigkPT09WilyZXR1cm4hMDtpZigkPT09dm9pZCAwfHxaPT09dm9pZCAwKXJldHVybiExO2lmKCQubGVuZ3RoIT09Wi5sZW5ndGgpcmV0dXJuITE7Zm9yKGxldCBKPTA7SjwkLmxlbmd0aDtKKyspaWYoJFtKXSE9PVpbSl0pcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24galgoJCxaKXtpZigkPT09dm9pZCAwJiZaPT09dm9pZCAwKXJldHVybiEwO2lmKCQ9PT12b2lkIDB8fFo9PT12b2lkIDApcmV0dXJuITE7cmV0dXJuIGEoJCxaKX1mdW5jdGlvbiBEWCgkLFope2lmKE9iamVjdC5pcygkLFopKXJldHVybiEwO2lmKCQgaW5zdGFuY2VvZiBVaW50OEFycmF5JiZaIGluc3RhbmNlb2YgVWludDhBcnJheSlyZXR1cm4gYSgkLFopO2lmKCQgaW5zdGFuY2VvZiBEYXRlJiZaIGluc3RhbmNlb2YgRGF0ZSlyZXR1cm4gJC5nZXRUaW1lKCk9PT1aLmdldFRpbWUoKTt0cnl7cmV0dXJuIGEoXzAoJCksXzAoWikpfWNhdGNoe3JldHVybiExfX1mdW5jdGlvbiBBWCgkLFope2xldCBKPSQudXBkYXRlZEF0LmdldFRpbWUoKSxRPVoudXBkYXRlZEF0LmdldFRpbWUoKTtpZihKIT09USlyZXR1cm4gSj5RO3JldHVybiAkLmN0cj5aLmN0cn1mdW5jdGlvbiBfWCgkLFope2xldCBKPW5ldyBTZXQsUT1bXTtmb3IobGV0IFggb2YgWil7bGV0IFk9QihYLmVpZCksVj0kLmVudHMuZ2V0KFkpLFtXLHpdPXIwKFYsWCk7aWYoeiE9PTApe1EucHVzaCh6KTtjb250aW51ZX1pZihXPT09dm9pZCAwKXtRLnB1c2goMTIpO2NvbnRpbnVlfWZvcihsZXQgSyBvZiBvMChWLFcpKUouYWRkKEspOyQucHV0KFcpLFEucHVzaCgwKX1yZXR1cm57c3RhdHM6USx0eXBlczpKfX1mdW5jdGlvbiBoKCQpe3JldHVybiJ0eXBlImluICR9ZnVuY3Rpb24gTFgoJCl7aWYoIUFycmF5LmlzQXJyYXkoJCl8fCQubGVuZ3RoPT09MClyZXR1cm47bGV0IFo9bmV3IFNldCxKPVtdO2ZvcihsZXQgUSBvZiAkKXtpZih0eXBlb2YgUSE9PSJzdHJpbmcifHxRLmxlbmd0aD09PTApY29udGludWU7aWYoWi5oYXMoUSkpY29udGludWU7Wi5hZGQoUSksSi5wdXNoKFEpfXJldHVybiBKLmxlbmd0aD4wP0o6dm9pZCAwfWZ1bmN0aW9uIEUkKCQpe3JldHVybntlaWQ6JC5laWQsY3RyOiQuY3RyLHVwZGF0ZWRBdDokLnVwZGF0ZWRBdH19ZnVuY3Rpb24gaEooJCl7bGV0IFo9bmV3IG0oJC5laWQpLFtKLFFdPVoucmVhZFN0cnVjdChYMCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7cmV0dXJuIFIoe2VpZDokLmVpZCxjdHI6JC5jdHIsdXBkYXRlZEF0Om5ldyBEYXRlKEoudHMuZ2V0VGltZSgpKyQub2ZmKX0pfWZ1bmN0aW9uIHIwKCQsWil7bGV0IEo9bmV3IG0oWi5laWQpLFtRLFhdPUoucmVhZFN0cnVjdChYMCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFk9bmV3IERhdGUoUS50cy5nZXRUaW1lKCkrWi5vZmYpO2lmKCQhPT12b2lkIDAmJlk8PSQudXBkYXRlZEF0KXJldHVybiBHKDE1KTtpZihnSihaKSl7bGV0IFY9TFgoWi50YWdzKTtyZXR1cm4gUih7ZWlkOlouZWlkLGdpZDpaLmdpZCxwaWQ6Wi5waWQsLi4uViE9PXZvaWQgMD97dGFnczpWfTp7fSx0eXBlOloudHlwZSxjcmVhdGVkQXQ6US50cyx1cGRhdGVkQXQ6WSxjdHI6Wi5jdHIsYm9keTpaLmJvZHl9KX1yZXR1cm4gUih7ZWlkOlouZWlkLHVwZGF0ZWRBdDpZLGN0cjpaLmN0cn0pfWZ1bmN0aW9uIG8wKCQsWil7bGV0IEo9bmV3IFNldDtpZigkIT09dm9pZCAwJiZoKCQpKUouYWRkKCQudHlwZSk7aWYoaChaKSlKLmFkZChaLnR5cGUpO3JldHVyblsuLi5KXX1jbGFzcyBmJHtpbmZsaWdodD1udWxsO2FnYWluPSExO3J1bigkKXtpZih0aGlzLmFnYWluPSEwLHRoaXMuaW5mbGlnaHQpcmV0dXJuIHRoaXMuaW5mbGlnaHQ7cmV0dXJuIHRoaXMuaW5mbGlnaHQ9dGhpcy5kcmFpbigkKSx0aGlzLmluZmxpZ2h0fWFzeW5jIGZsdXNoKCl7aWYoIXRoaXMuaW5mbGlnaHQpcmV0dXJuO3RyeXthd2FpdCB0aGlzLmluZmxpZ2h0fWNhdGNoe319YXN5bmMgZHJhaW4oJCl7dHJ5e3RoaXMuYWdhaW49ITE7bGV0IFo9YXdhaXQgJCgpO3doaWxlKHRoaXMuYWdhaW4pdGhpcy5hZ2Fpbj0hMSxaPWF3YWl0ICQoKTtyZXR1cm4gWn1maW5hbGx5e3RoaXMuaW5mbGlnaHQ9bnVsbH19fXZhciBpSj0xMDA7Y2xhc3MgUFp7dGltZXI9bnVsbDtkZWxheU1zO3dvcms7dGFpbD1uZXcgZiQ7Y29uc3RydWN0b3IoJCxaKXt0aGlzLmRlbGF5TXM9JDwwPzA6JCx0aGlzLndvcms9Wn1zY2hlZHVsZSgpe2lmKHRoaXMuZGVsYXlNczw9MCl7dGhpcy5maXJlKCk7cmV0dXJufWlmKHRoaXMudGltZXIhPT1udWxsKWNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTt0aGlzLnRpbWVyPXNldFRpbWVvdXQoKCk9Pnt0aGlzLnRpbWVyPW51bGwsdGhpcy5maXJlKCl9LHRoaXMuZGVsYXlNcyl9YXN5bmMgZmx1c2goKXtpZih0aGlzLnRpbWVyIT09bnVsbCljbGVhclRpbWVvdXQodGhpcy50aW1lciksdGhpcy50aW1lcj1udWxsLHRoaXMuZmlyZSgpO2F3YWl0IHRoaXMudGFpbC5mbHVzaCgpfWNhbmNlbCgpe2lmKHRoaXMudGltZXIhPT1udWxsKWNsZWFyVGltZW91dCh0aGlzLnRpbWVyKSx0aGlzLnRpbWVyPW51bGx9ZmlyZSgpe3JldHVybiB0aGlzLnRhaWwucnVuKHRoaXMud29yayl9fWZ1bmN0aW9uIGxKKCQpe2xldCBaPW5ldyBtKCQuZWlkKSxbSixRXT1YMC5kZWNvZGUoWik7aWYoUSE9PTApcmV0dXJuO3JldHVybiBKLnRzLmdldFRpbWUoKSskLm9mZn1mdW5jdGlvbiB4WCgkLFope2xldCBKPWxKKCQpLFE9bEooWik7aWYoSj09PXZvaWQgMCYmUT09PXZvaWQgMClyZXR1cm4gMDtpZihKPT09dm9pZCAwKXJldHVybiAxO2lmKFE9PT12b2lkIDApcmV0dXJuLTE7aWYoUSE9PUopcmV0dXJuIFEtSjtyZXR1cm4gWi5jdHItJC5jdHJ9ZnVuY3Rpb24gYTAoJCxaKXtyZXR1cm4gJC5zbGljZSgpLnNvcnQoKEosUSk9PnhYKFooSiksWihRKSkpfXZhciB3Wj17cGhhc2U6ImlkbGUifSxLJD01MDtmdW5jdGlvbiBUWigkLFosSil7aWYoJDw9MHx8Wjw9MClyZXR1cm4hMTtpZigkPT09MXx8JD09PVopcmV0dXJuITA7cmV0dXJuICQlSj09PTB9ZnVuY3Rpb24gdUooJCxaKXtpZih0eXBlb2YgbmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2I9PT0iZnVuY3Rpb24iKXtuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYigkLFopO3JldHVybn1sZXQgSj1VUkwuY3JlYXRlT2JqZWN0VVJMKCQpLFE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpO1EuaHJlZj1KLFEuZG93bmxvYWQ9Wixkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKFEpLFEuY2xpY2soKSxkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKFEpLFVSTC5yZXZva2VPYmplY3RVUkwoSil9ZnVuY3Rpb24gcEooJCxaLEope2xldCBRPVtdLFg9W10sWT0wO2ZvcihsZXQgViBvZiAkKXtsZXQgVz1aKFYpO2lmKFgubGVuZ3RoPjAmJlkrVz5KKVEucHVzaChYKSxYPVtdLFk9MDtpZihYLnB1c2goViksWSs9VyxZPj1KKVEucHVzaChYKSxYPVtdLFk9MH1pZihYLmxlbmd0aD4wKVEucHVzaChYKTtyZXR1cm4gUX1hc3luYyBmdW5jdGlvbiBqWigkLFosSil7bGV0IFE9JC5sZW5ndGg7aWYoUTwxKXJldHVybltdO2xldCBYPUFycmF5KFEpLFk9MCxWPU1hdGgubWluKE1hdGgubWF4KDEsWiksUSksVz1hc3luYygpPT57d2hpbGUoITApe2xldCBLPVk7aWYoWSs9MSxLPj1RKXJldHVybjtYW0tdPWF3YWl0IEooJFtLXSxLKX19LHo9W107Zm9yKGxldCBLPTA7SzxWO0srKyl6LnB1c2goVygpKTtyZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwoeiksWH1hc3luYyBmdW5jdGlvbiBnJCgkLFosSixRKXtsZXQgWD1uZXcgbSgkLmhlYWRDcGgpLFtZLFZdPVgucmVhZFN0cnVjdChEJCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0e3NpZzpXLGtkbTp6LGhlYWRDcGg6S309WTtpZighYXdhaXQgUS5jaGVja1NpZ0VkMjU1MTkoVyxLLFopKXJldHVybiBHKDMpO2xldCBOPUouZGVyaXZlQ2lwaGVyKHosImRlY3J5cHQiKSxPO3RyeXtPPWF3YWl0IE4uZGVjcnlwdChLKX1jYXRjaHtyZXR1cm4gRygyMCl9cmV0dXJuIFIoe2tkbTp6LGhlYWRFbmM6T30pfXZhciB0MD0iZiIsbSQ9InQiLHMwPSJlIjtmdW5jdGlvbiBCWCgkKXtpZigkPT09ITB8fCQ9PT1tJClyZXR1cm4gbSQ7aWYoJD09PXMwKXJldHVybiBzMDtyZXR1cm4gdDB9ZnVuY3Rpb24gY0ooJCl7cmV0dXJuICQhPT0wJiYkIT09MTUmJiQhPT0xOCYmJCE9PTE3fWZ1bmN0aW9uIERaKCQsWixKKXtpZigkLmFwbGQ9WixaPT09czAmJkohPT12b2lkIDApJC5lcnI9SjtlbHNlIGRlbGV0ZSAkLmVycn1hc3luYyBmdW5jdGlvbiBTJCgkLFosSixRKXtsZXQgWD1RPy5ib2R5IT09ITEsWT1CWChaLmFwbGQpLFY9Wi5ib2R5LFc9Vj8ubGVuZ3RoPz8wLHo7aWYoWCYmViYmVz4wKXo9YXdhaXQgSi5ibGFrZTMoVik7bGV0IEs9e2VpZDpaLmVpZCxvZmY6Wi5vZmY/PzAsY3RyOlouY3RyPz8wLGxlbjpXLGhzaDp6fSxGPXtoYXNoOiQsaGVhZDpLLGFwbGQ6WX07aWYoWCYmViE9PXZvaWQgMClGLmJvZHk9VjtpZihZPT09czAmJlouZXJyIT09dm9pZCAwKUYuZXJyPVouZXJyO3JldHVybiBGfXZhciBBWj0xMDQ4NTc2LF9aPTEwNDg1NzYsZEo9NjQ7ZnVuY3Rpb24ga1goJCl7cmV0dXJuICQuc2lnLmxlbmd0aCskLmtkbS5sZW5ndGgrJC5oZWFkQ3BoLmxlbmd0aCskLmJvZHlDcGgubGVuZ3RofWFzeW5jIGZ1bmN0aW9uIEVYKCQsWixKLFEsWCl7aWYoUS5sZW5ndGg8MSlyZXR1cm4gMDtsZXRbWSxWXT1hd2FpdCAkLnB1c2goUSk7aWYoViE9PTApcmV0dXJuIFY7aWYoIVkpcmV0dXJuIDI3O2ZvcihsZXQgeiBvZiBZKXtpZih6LnN0YXR1cyE9PTApe2NvbnNvbGUuZXJyb3IoInB1c2ggZXJyIix6KTtjb250aW51ZX1sZXQgSz1YW3ouaWR4XTtpZighSyl7Y29uc29sZS5lcnJvcigibm8gaGFzaCIseik7Y29udGludWV9YXdhaXQgWi51cGxvYWRzLmRlcShKLFtLXSl9bGV0IFc9YXdhaXQgWi5ob3N0cy5nZXQoSik7aWYoVyl7bGV0IHo9Vy5sYXN0U2VxLEs9eixGPVtdO2ZvcihsZXQgTiBvZiBZKWlmKE4uc3RhdHVzPT09MClGLnB1c2goTi5zZXEpO0Yuc29ydCgoTixPKT0+Ti1PKTtmb3IobGV0IE4gb2YgRilpZihOPT09eisxKXo9TjtpZih6PkspYXdhaXQgWi5ob3N0cy50b3VjaChKLHopfXJldHVybiAwfWFzeW5jIGZ1bmN0aW9uIG5KKCQsWil7aWYoWi5sZW5ndGg8MSlyZXR1cm4gUihbXSk7bGV0IEo9bmV3IE1hcCxRPVtdO2ZvcihsZXQgVyBvZiBaKUouc2V0KFcuc2VxLFcpLFEucHVzaChXLnNlcSk7bGV0W1gsWV09YXdhaXQgJC5wdWxsKFEpO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKCFYKXJldHVybiBHKDI3KTtsZXQgVj1bXTtmb3IobGV0e3NlcTpXLGJvZHlDcGg6en1vZiBYKXtsZXQgSz1KLmdldChXKTtpZighSyljb250aW51ZTtWLnB1c2goe2RsOkssYm9keUNwaDp6fSl9cmV0dXJuIFIoVil9YXN5bmMgZnVuY3Rpb24gZlgoJCxaLEosUSl7aWYoUS5sZW5ndGg8MSlyZXR1cm4gUih7cGFydHM6W10saGFzaGVzOltdfSk7bGV0IFg9W10sWT1bXSxWPVtdLFc9bmV3IE1hcDtmb3IobGV0e2RsOkssYm9keUNwaDpGfW9mIFEpe2xldHtoZWFkOk4sa2RtOk8sc2VxOlUsaG9zdDpxfT1LLFtILE1dPWF3YWl0IHJKKEssSik7aWYoTSE9PTB8fCFIKXtsZXQgaz1XLmdldChxKT8/W107ay5wdXNoKFUpLFcuc2V0KHEsayk7Y29udGludWV9bGV0e2hlYWRFbmM6UCxoZWFkRW5jSGFzaDpDfT1ILFQ9Wi5kZXJpdmVDaXBoZXIoTywiZGVjcnlwdCIpLFtJLEFdPWF3YWl0IFlaKFAsRixULEosQyk7aWYoQSE9PTB8fCFJKXtsZXQgaz1XLmdldChxKT8/W107ay5wdXNoKFUpLFcuc2V0KHEsayk7Y29udGludWV9bGV0IHg9e2hlYWQ6Tixib2R5OkkuYm9kfSxnPUkuaGVhZEhhc2g7Vi5wdXNoKHtrZXk6ZyxkYXRhOnNKKHgpfSksWC5wdXNoKHgpLFkucHVzaChnKTtsZXQgZj1XLmdldChxKT8/W107Zi5wdXNoKFUpLFcuc2V0KHEsZil9bGV0IHo9YXdhaXQgJC5tZXNzYWdlcy5hZGQoVik7Zm9yKGxldFtLLEZdb2YgVylhd2FpdCAkLmRvd25sb2Fkcy5kZXEoSyxGKTtmb3IobGV0IEs9MDtLPHoubGVuZ3RoO0srKyl7bGV0IEY9eltLXTtpZihGIT09MCYmRiE9PTE1KWNvbnNvbGUuZXJyb3IoIkVSUiBzdG9yaW5nIixEW0ZdLCJmb3IgbWVzc2FnZSIsSyl9cmV0dXJuIFIoe3BhcnRzOlgsaGFzaGVzOll9KX1hc3luYyBmdW5jdGlvbiBySigkLFope2xldCBKPSQuaGVhZEVuYztpZighSil7bGV0IFg9bmV3IFMsWT1YLndyaXRlU3RydWN0KFYwLCQuaGVhZCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7Sj1YLnJlc3VsdCgpfWlmKCQuaGVhZEVuY0hhc2gpcmV0dXJuIFIoe2hlYWRFbmM6SixoZWFkRW5jSGFzaDokLmhlYWRFbmNIYXNofSk7bGV0IFE9YXdhaXQgWi5ibGFrZTMoSik7cmV0dXJuIFIoe2hlYWRFbmM6SixoZWFkRW5jSGFzaDpRfSl9YXN5bmMgZnVuY3Rpb24gb0ooJCxaLEope2xldCBRPW5ldyBTZXQ7Zm9yKGxldCBWIG9mIFopUS5hZGQoQihWKSk7aWYoUS5zaXplPDEpcmV0dXJuO2xldCBYPUFycmF5LmZyb20oYXdhaXQgJC5kb3dubG9hZHMubGlzdCgpKTtpZihYLmxlbmd0aDwxKXJldHVybjtsZXQgWT1uZXcgTWFwO2ZvcihsZXQgViBvZiBYKXtsZXQgVztpZihWLmhlYWRFbmNIYXNoKVc9QihWLmhlYWRFbmNIYXNoKTtlbHNle2xldFtLLEZdPWF3YWl0IHJKKFYsSik7aWYoRiE9PTB8fCFLKWNvbnRpbnVlO1c9QihLLmhlYWRFbmNIYXNoKX1pZighUS5oYXMoVykpY29udGludWU7bGV0IHo9WS5nZXQoVi5ob3N0KT8/W107ei5wdXNoKFYuc2VxKSxZLnNldChWLmhvc3Qseil9Zm9yKGxldFtWLFddb2YgWSlhd2FpdCAkLmRvd25sb2Fkcy5kZXEoVixXKX1hc3luYyBmdW5jdGlvbiBMWih7Y29ubjokLHN0b3JlOlosZW5jbGF2ZTpKLGhvc3Q6USxjcnlwdG86WCxvblByb2dyZXNzOlkscGVla1Byb2dyZXNzRXZlcnk6VixwZWVrQ29uY3VycmVuY3k6V30pe2xldCB6PWF3YWl0ICQuaWRlbnRpdHkoKSxLPVtdLFtGLE5dPWF3YWl0ICQucGVlayhRLmxhc3RTZXEpO2lmKE4hPT0wKXJldHVybiBOO2xldCBPPUYubGVuZ3RoLFU9Vj8/SyQscT1XPz9kSjtpZihZJiZPPjApWSh7cGhhc2U6InBlZWsiLGhvc3Q6US5sYWJlbCxkb25lOjAsdG90YWw6T30pO2xldCBIPTAsTT1hd2FpdCBqWihGLHEsYXN5bmMoQyk9PntsZXRbVCxJXT1hd2FpdCBnJChDLHoucHVibGljS2V5LEosWCksQTtpZihJIT09MHx8IVQpQT17b2s6ITEsc2VxOkMuc2VxLHN0YXQ6SX07ZWxzZXtsZXQgeD1hd2FpdCBYLmJsYWtlMyhULmhlYWRFbmMpO0E9e29rOiEwLHNlcTpDLnNlcSxrZG06VC5rZG0saGVhZEVuYzpULmhlYWRFbmMsaGVhZEVuY0hhc2g6eH19aWYoSCs9MSxZJiZUWihILE8sVSkpWSh7cGhhc2U6InBlZWsiLGhvc3Q6US5sYWJlbCxkb25lOkgsdG90YWw6T30pO3JldHVybiBBfSksUD1uZXcgU2V0O2ZvcihsZXQgQyBvZiBNKXtpZighQy5vayl7Y29uc29sZS5lcnJvcigicGVlazogZGVjcnlwdGluZyBpdGVtIGhlYWQiLEMuc3RhdCk7Y29udGludWV9bGV0IFQ9QihDLmhlYWRFbmNIYXNoKTtpZihhd2FpdCBaLm1lc3NhZ2VzLmhhcyhDLmhlYWRFbmNIYXNoKSl7Y29uc29sZS5pbmZvKCJwZWVrOiBsb2NhbCBtc2c7IHNraXAgZG93bmxvYWQsIGRlcSB1cGxvYWQiKSxhd2FpdCBaLnVwbG9hZHMuZGVxKFEubGFiZWwsW0MuaGVhZEVuY0hhc2hdKSxhd2FpdCBaLmRvd25sb2Fkcy5kZXEoUS5sYWJlbCxbQy5zZXFdKTtjb250aW51ZX1pZihQLmhhcyhUKSl7YXdhaXQgWi5kb3dubG9hZHMuZGVxKFEubGFiZWwsW0Muc2VxXSk7Y29udGludWV9bGV0IEE9bmV3IG0oQy5oZWFkRW5jKSxbeCxnXT1BLnJlYWRTdHJ1Y3QoVjApO2lmKGchPT0wKXtjb25zb2xlLmVycm9yKCJwZWVrOiByZWFkaW5nIGl0ZW0gaGVhZCIsZyk7Y29udGludWV9UC5hZGQoVCksSy5wdXNoKHtrZG06Qy5rZG0saGVhZDp4LHNlcTpDLnNlcSxob3N0OlEubGFiZWwsaGVhZEVuYzpDLmhlYWRFbmMsaGVhZEVuY0hhc2g6Qy5oZWFkRW5jSGFzaH0pfWlmKGF3YWl0IFouZG93bmxvYWRzLmVucShLKSxGLmxlbmd0aD4wKXtsZXQgQz1NYXRoLm1heCguLi5GLm1hcCgoVCk9PlQuc2VxKSk7YXdhaXQgWi5ob3N0cy5yZWNvcmRTdGF0cyhRLmxhYmVsLHtsYXN0U2VxOkN9KX1pZihZKVkoe3BoYXNlOiJwZWVrIixob3N0OlEubGFiZWwsZG9uZTpPLHRvdGFsOk99KTtyZXR1cm4gMH1hc3luYyBmdW5jdGlvbiBhSih7Y29ubjokLHN0b3JlOlosaG9zdDpKLG1heFB1c2hCeXRlczpRLG9uUHJvZ3Jlc3M6WH0pe2xldCBZPVE/P0FaLFY9YXdhaXQgWi51cGxvYWRzLmxpc3QoSi5sYWJlbCksVz1WLmxlbmd0aCx6PTA7aWYoWCYmVz4wKVgoe3BoYXNlOiJwdXNoIixob3N0OkoubGFiZWwsZG9uZTowLHRvdGFsOld9KTtsZXQgSz1bXSxGPVtdLE49MCxPPWFzeW5jKCk9PntpZihLLmxlbmd0aDwxKXJldHVybiAwO2xldCBVPUsubGVuZ3RoLHE9YXdhaXQgRVgoJCxaLEoubGFiZWwsSyxGKTtpZihLPVtdLEY9W10sTj0wLHE9PT0wKXtpZih6Kz1VLFgpWCh7cGhhc2U6InB1c2giLGhvc3Q6Si5sYWJlbCxkb25lOnosdG90YWw6V30pfXJldHVybiBxfTtmb3IobGV0IFUgb2YgVil7bGV0IHE9YXdhaXQgWi5tZXNzYWdlcy5nZXQoVSk7aWYoIXEpe3orPTE7Y29udGludWV9bGV0IEg9ey4uLnEuaGVhZCxib2Q6cS5ib2R5fSxbTSxQXT1hd2FpdCAkLnNlYWwoSCk7aWYoUCE9PTApcmV0dXJuIFA7aWYoIU0pcmV0dXJuIDEyO2xldCBDPWtYKE0pO2lmKEsubGVuZ3RoPjAmJk4rQz5ZKXtsZXQgVD1hd2FpdCBPKCk7aWYoVCE9PTApcmV0dXJuIFR9aWYoSy5wdXNoKE0pLEYucHVzaChVKSxOKz1DLE4+PVkpe2xldCBUPWF3YWl0IE8oKTtpZihUIT09MClyZXR1cm4gVH19cmV0dXJuIE8oKX1hc3luYyBmdW5jdGlvbiB4Wih7Y29ubjokLHN0b3JlOlosZW5jbGF2ZTpKLGhvc3Q6USxjcnlwdG86WCxtYXhQdWxsQnl0ZXM6WSxvblByb2dyZXNzOlZ9LFcpe2xldCB6PVk/P19aLEs9YXdhaXQgWi5kb3dubG9hZHMubGlzdCgpLEY9QXJyYXkuZnJvbShLKS5maWx0ZXIoKE0pPT5NLmhvc3Q9PT1RLmxhYmVsKTtpZihGLmxlbmd0aDwxKXJldHVybiAxNTtsZXQgTj1hMChGLChNKT0+TS5oZWFkKSxPPXBKKE4sKE0pPT5NLmhlYWQubGVuLHopLFU9Ti5sZW5ndGgscT0wO2lmKFYpVih7cGhhc2U6InB1bGwiLGhvc3Q6US5sYWJlbCxkb25lOjAsdG90YWw6VX0pO2xldCBIPW5KKCQsT1swXSk7Zm9yKGxldCBNPTA7TTxPLmxlbmd0aDtNKyspe2xldFtQLENdPWF3YWl0IEg7aWYoQyE9PTB8fCFQKXJldHVybiBDO2lmKHErPU9bTV0ubGVuZ3RoLFYpVih7cGhhc2U6InB1bGwiLGhvc3Q6US5sYWJlbCxkb25lOnEsdG90YWw6VX0pO2xldCBUPU9bTSsxXTtpZihUKUg9bkooJCxUKTtpZihWKVYoe3BoYXNlOiJvcGVuIixob3N0OlEubGFiZWwsZG9uZTpxLHRvdGFsOlV9KTtsZXQgST1hMChQLCh4KT0+eC5kbC5oZWFkKSxbLEFdPWF3YWl0IGZYKFosSixYLEkpO2lmKEEhPT0wKXJldHVybiBBO2lmKFcpe2lmKFYpVih7cGhhc2U6ImV4ZWMiLGhvc3Q6US5sYWJlbCxkb25lOnEsdG90YWw6VX0pO2F3YWl0IFcoKX19cmV0dXJuIDB9ZnVuY3Rpb24gc0ooe2hlYWQ6JCxib2R5Olp9KXtsZXQgSj17ZWlkOiQuZWlkLGJvZHk6WixhcGxkOnQwfTtpZigkLm9mZiE9PTApSi5vZmY9JC5vZmY7aWYoJC5jdHIhPT0wKUouY3RyPSQuY3RyO3JldHVybiBKfWFzeW5jIGZ1bmN0aW9uIHRKKCQse2Nvbm46WixzdG9yZTpKLGVuY2xhdmU6USxob3N0OlgsY3J5cHRvOlksb25Qcm9ncmVzczpWfSxXKXtsZXQgej1YLmxhYmVsLEs9YXdhaXQgWi5pZGVudGl0eSgpLEY9bmV3IG0oJCksW04sT109Ri5yZWFkU3RydWN0cyhqJCk7aWYoTyE9PTApe2NvbnNvbGUuZXJyb3IoIkZhaWxlZCBkZWNvZGluZyBub3RpZiIsRFtPXSk7cmV0dXJufWxldCBVPSExLEg9KGF3YWl0IEouaG9zdHMuZ2V0KHopKT8ubGFzdFNlcSxNPVtdLFA9ITE7Zm9yKGxldCBJIG9mIE4pe2xldFtBLHhdPWF3YWl0IGckKHtzZXE6SS5zZXEsaGVhZENwaDpJLmhlYWRDcGh9LEsucHVibGljS2V5LFEsWSk7aWYoeCE9PTApe2NvbnNvbGUuZXJyb3IoIkZhaWxlZCBkZWNyeXB0aW5nIG5vdGlmIixEW3hdKTtjb250aW51ZX1sZXQgZz1hd2FpdCBZLmJsYWtlMyhBLmhlYWRFbmMpO2lmKGF3YWl0IEoubWVzc2FnZXMuaGFzKGcpKWNvbnRpbnVlO2xldCBmPW5ldyBtKEEuaGVhZEVuYyksW2ssYl09Zi5yZWFkU3RydWN0KFYwKTtpZihiIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIHRvIHBhcnNlIGhlYWQiLERbYl0pO2NvbnRpbnVlfWlmKCFJLmJvZHlDcGgmJmsubGVuPjApUD0hMCxhd2FpdCBKLmRvd25sb2Fkcy5lbnEoW3tzZXE6SS5zZXEsaG9zdDp6LGtkbTpBLmtkbSxoZWFkOmssaGVhZEVuYzpBLmhlYWRFbmMsaGVhZEVuY0hhc2g6Z31dKTtlbHNlIE0ucHVzaCh7Li4uQSxoZWFkOmssYm9keUNwaDpJLmJvZHlDcGgsaGVhZEVuY0hhc2g6Z30pO2lmKEg9PT12b2lkIDB8fEkuc2VxIT09SCsxKWNvbnNvbGUubG9nKCJvdXQgb2Ygc2VxIixJLnNlcSxIKSxVPSEwO2Vsc2UgSD1JLnNlcX1pZihIIT09dm9pZCAwKWF3YWl0IEouaG9zdHMudG91Y2goWC5sYWJlbCxIKTtsZXQgQz1bXTtmb3IobGV0IEkgb2YgTSl7bGV0IEE9US5kZXJpdmVDaXBoZXIoSS5rZG0sImRlY3J5cHQiKSxbeCxnXT1hd2FpdCBZWihJLmhlYWRFbmMsSS5ib2R5Q3BoLEEsWSk7aWYoZyE9PTApe2NvbnNvbGUuZXJyb3IoIkZhaWxlZCB0byBvcGVuIGJvZHkiLERbZ10pO2NvbnRpbnVlfUMucHVzaCh7a2V5OkkuaGVhZEVuY0hhc2gsZGF0YTpzSih7aGVhZDpJLmhlYWQsYm9keTp4LmJvZH0pfSl9bGV0IFQ9YXdhaXQgSi5tZXNzYWdlcy5hZGQoQyk7Zm9yKGxldCBJPTA7STxULmxlbmd0aDtJKyspe2xldCBBPVRbSV07aWYoQSE9PTAmJkEhPT0xNSljb25zb2xlLmVycm9yKCJFUlIgc3RvcmluZyIsRFtBXSwiZm9yIG1lc3NhZ2UiLEkpfWlmKFYmJkMubGVuZ3RoPjApVih7cGhhc2U6Im9wZW4iLGhvc3Q6WC5sYWJlbCxkb25lOkMubGVuZ3RoLHRvdGFsOkMubGVuZ3RofSk7aWYoVXx8UHx8Qy5sZW5ndGg+MClXKCl9YXN5bmMgZnVuY3Rpb24gQlooJCxaPXt9KXtsZXQgSj1aLnB1bGwhPT0hMSxRPVoucHVzaD09PSEwLHtjb25uOlgsc3RvcmU6WSxlbmNsYXZlOlYsaG9zdDpXLGNyeXB0bzp6LG9uUHJvZ3Jlc3M6SyxwZWVrUHJvZ3Jlc3NFdmVyeTpGLHBlZWtDb25jdXJyZW5jeTpOfT0kLE89YXdhaXQgWC5pZGVudGl0eSgpLFtVLHFdPWF3YWl0IFgucGVlaygwKTtpZihxIT09MClyZXR1cm4gRyhxKTtsZXQgSD1VLmxlbmd0aCxNPUY/P0skLFA9Tj8/ZEo7aWYoSyYmSD4wKUsoe3BoYXNlOiJwZWVrIixob3N0OlcubGFiZWwsZG9uZTowLHRvdGFsOkh9KTtsZXQgQz0wLFQ9YXdhaXQgalooVSxQLGFzeW5jKEwpPT57bGV0W3YsRV09YXdhaXQgZyQoTCxPLnB1YmxpY0tleSxWLHopLHk7aWYoRSE9PTB8fCF2KXk9e29rOiExLHNlcTpMLnNlcSxzdGF0OkV9O2Vsc2V7bGV0IF89YXdhaXQgei5ibGFrZTModi5oZWFkRW5jKTt5PXtvazohMCxzZXE6TC5zZXEsa2RtOnYua2RtLGhlYWRFbmM6di5oZWFkRW5jLGhlYWRFbmNIYXNoOl99fWlmKEMrPTEsSyYmVFooQyxILE0pKUsoe3BoYXNlOiJwZWVrIixob3N0OlcubGFiZWwsZG9uZTpDLHRvdGFsOkh9KTtyZXR1cm4geX0pLEk9bmV3IE1hcDtmb3IobGV0IEwgb2YgVCl7aWYoIUwub2spY29udGludWU7bGV0IHY9QihMLmhlYWRFbmNIYXNoKSxFPUkuZ2V0KHYpO2lmKEUpRS5jb3VudCs9MTtlbHNlIEkuc2V0KHYse2hhc2g6TC5oZWFkRW5jSGFzaCxjb3VudDoxLHNhbXBsZTpMfSl9bGV0IEE9MCx4PVtdO2ZvcihsZXQgTCBvZiBJLnZhbHVlcygpKXtpZihMLmNvdW50PjEpQSs9TC5jb3VudC0xO3gucHVzaChMLmhhc2gpfWxldCBnPVUubGVuZ3RoLGY9SS5zaXplLGs9YXdhaXQgeiQoeCx6KSxiPVtdLHc9MDtmb3IobGV0IEwgb2YgSS52YWx1ZXMoKSl7aWYoYXdhaXQgWS5tZXNzYWdlcy5oYXMoTC5oYXNoKSl7YXdhaXQgWS51cGxvYWRzLmRlcShXLmxhYmVsLFtMLmhhc2hdKTtjb250aW51ZX1pZih3Kz0xLCFKKWNvbnRpbnVlO2xldCBFPUwuc2FtcGxlLHk9bmV3IG0oRS5oZWFkRW5jKSxbXyxuXT15LnJlYWRTdHJ1Y3QoVjApO2lmKG4hPT0wKXtjb25zb2xlLmVycm9yKCJyZWNvbmNpbGU6IHJlYWRpbmcgbXNnIGhlYWRlciIsbik7Y29udGludWV9Yi5wdXNoKHtrZG06RS5rZG0saGVhZDpfLHNlcTpFLnNlcSxob3N0OlcubGFiZWwsaGVhZEVuYzpFLmhlYWRFbmMsaGVhZEVuY0hhc2g6RS5oZWFkRW5jSGFzaH0pfWlmKGIubGVuZ3RoPjApYXdhaXQgWS5kb3dubG9hZHMuZW5xKGIpO2xldCBpPTA7aWYoUSl7bGV0IEw9YXdhaXQgWS5tZXNzYWdlcy5saXN0S2V5cygpLHY9bmV3IFNldChJLmtleXMoKSksRT1bXTtmb3IobGV0IHkgb2YgTClpZighdi5oYXMoQih5KSkpaSs9MSxFLnB1c2goeSk7aWYoRS5sZW5ndGg+MClhd2FpdCBZLnVwbG9hZHMuZW5xKFcubGFiZWwsRSl9ZWxzZXtsZXQgTD1hd2FpdCBZLm1lc3NhZ2VzLmxpc3RLZXlzKCksdj1uZXcgU2V0KEkua2V5cygpKTtmb3IobGV0IEUgb2YgTClpZighdi5oYXMoQihFKSkpaSs9MX1sZXQgdT1VLmxlbmd0aD4wP01hdGgubWF4KC4uLlUubWFwKChMKT0+TC5zZXEpKTowO2lmKGF3YWl0IFkuaG9zdHMucmVjb3JkU3RhdHMoVy5sYWJlbCx7c2V0TGFzdFNlcTp1fSksSylLKHtwaGFzZToicGVlayIsaG9zdDpXLmxhYmVsLGRvbmU6SCx0b3RhbDpIfSk7cmV0dXJuIFIoe21zZ2NoZWNrOmssbnVtQmFnczpnLHVuaXF1ZU1zZ3M6ZixudW1EdXBlczpBLG1pc3NpbmdMb2NhbDp3LG1pc3NpbmdIb3N0Oml9KX1jbGFzcyBrWntjbG9jaztzdGF0ZTtzdG9yZTt0cmFuc3BvcnQ7Y3J5cHRvO2ZvcmNlU2tld0hhbmRsaW5nQnlEZWZhdWx0O29uU2NoZWR1bGVTeW5jO2Nvbm5lY3Rpb25zPW5ldyBNYXA7YXBwbHlDaGFpbj1Qcm9taXNlLnJlc29sdmUoKTtzeW5jUnVucz1uZXcgZiQ7Y2xpZW50U3RhdGU7eGZlclN0YXRlO21heFB1c2hCeXRlczttYXhQdWxsQnl0ZXM7cGVla1Byb2dyZXNzRXZlcnk9SyQ7bGFzdFByb2dyZXNzPXdaO3NjaGVkdWxlZFN5bmM7Y29uc3RydWN0b3IoJCxaLEosUSxYLFk9ITAsVj1BWixXPV9aLHope3RoaXMuY2xvY2s9JDt0aGlzLnN0YXRlPVo7dGhpcy5zdG9yZT1KO3RoaXMudHJhbnNwb3J0PVE7dGhpcy5jcnlwdG89WDt0aGlzLmZvcmNlU2tld0hhbmRsaW5nQnlEZWZhdWx0PVk7dGhpcy5vblNjaGVkdWxlU3luYz16O3RoaXMubWF4UHVzaEJ5dGVzPVYsdGhpcy5tYXhQdWxsQnl0ZXM9Vyx0aGlzLmNsaWVudFN0YXRlPW5ldyBMMCgoKT0+dGhpcy5nZXRDbGllbnRTdGF0ZSgpKSx0aGlzLnhmZXJTdGF0ZT1uZXcgTDAoKCk9PnRoaXMuZ2V0WGZlclN0YXRlKCkpLHRoaXMuc2NoZWR1bGVkU3luYz1uZXcgUFooaUosYXN5bmMoKT0+e3RyeXtjb25zb2xlLmluZm8oIlJ1bm5pbmcgc2NoZWR1bGVkIHN5bmMiKSxhd2FpdCB0aGlzLnN5bmMoKX1jYXRjaChLKXtjb25zb2xlLmVycm9yKCJEZWJvdW5jZWQgc3luYyBmYWlsZWQ6IixLKX19KX1lbWl0UHJvZ3Jlc3M9KCQpPT57dGhpcy5sYXN0UHJvZ3Jlc3M9JCx0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9O2FzeW5jIHNldFNlZWQoJCxaKXthd2FpdCB0aGlzLnN0b3JlLnNlZWQuc2F2ZSgkLFopLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpfWFzeW5jIGdldENsaWVudFN0YXRlKCl7bGV0e3N0b3JlOiQsY29ubmVjdGlvbnM6Wn09dGhpcyxKPWF3YWl0ICQuc2VlZC5sb2FkKCksUT1hd2FpdCAkLmhvc3RzLmxpc3QoKSxYPSExO2ZvcihsZXQgWSBvZiBaLnZhbHVlcygpKWlmKFkuaXNDb25uZWN0ZWQoKSl7WD0hMDticmVha31yZXR1cm57aGFzU2VlZDpKIT09dm9pZCAwLGhhc0hvc3Q6QXJyYXkuZnJvbShRKS5sZW5ndGg+MCxjb25uZWN0ZWQ6WH19YXN5bmMgZ2V0WGZlclN0YXRlKCl7bGV0e3VwbG9hZHM6JCxkb3dubG9hZHM6Wn09dGhpcy5zdG9yZSxKPWF3YWl0ICQuY291bnQoKTtyZXR1cm57bnVtRG93bmxvYWRzOmF3YWl0IFouY291bnQoKSxudW1VcGxvYWRzOkoscHJvZ3Jlc3M6dGhpcy5sYXN0UHJvZ3Jlc3N9fWFwcGx5PSgkLFopPT57cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvQXBwbHkoJCxaKSl9O2FzeW5jIGRvQXBwbHkoJCxaPXtlbnF1ZXVlVXBsb2FkOiEwLHRyaWdnZXJVcGxvYWQ6ITB9KXtsZXQgSj1bXSxRPVtdO2ZvcihsZXR7aGVhZDpZLGJvZHk6Vn1vZiAkKXtsZXQgVz1uZXcgUztXLndyaXRlU3RydWN0KFYwLFkpO2xldCB6PVcucmVzdWx0KCksSz1hd2FpdCB0aGlzLmNyeXB0by5ibGFrZTMoeiksRj17ZWlkOlkuZWlkLGJvZHk6VixhcGxkOnQwfTtpZihZLm9mZiE9PTApRi5vZmY9WS5vZmY7aWYoWS5jdHIhPT0wKUYuY3RyPVkuY3RyO0oucHVzaChLKSxRLnB1c2goe2tleTpLLGRhdGE6Rn0pfWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMuYWRkKFEpLGF3YWl0IG9KKHRoaXMuc3RvcmUsSix0aGlzLmNyeXB0byk7bGV0IFg9YXdhaXQgdGhpcy5kb0FwcGx5SGFzaGVzKEopO2lmKFouZW5xdWV1ZVVwbG9hZCl7bGV0IFk9W107Zm9yKGxldCBWPTA7VjxKLmxlbmd0aDtWKyspe2xldCBXPVhbVl07aWYoVz09PTB8fFc9PT0xNSlZLnB1c2goSltWXSl9aWYoWS5sZW5ndGg+MCl7bGV0IFY9YXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5saXN0KCk7Zm9yKGxldCBXIG9mIFYpYXdhaXQgdGhpcy5zdG9yZS51cGxvYWRzLmVucShXLmxhYmVsLFkpO3RoaXMueGZlclN0YXRlLmVtaXQoKX19aWYoWi50cmlnZ2VyVXBsb2FkKXRoaXMuc2NoZWR1bGVTeW5jKCk7cmV0dXJuIFh9ZW5xdWV1ZUFwcGx5Sm9iKCQpe2xldCBaPXRoaXMuYXBwbHlDaGFpbi50aGVuKCQsJCk7cmV0dXJuIHRoaXMuYXBwbHlDaGFpbj1aLnRoZW4oKCk9PntyZXR1cm59LCgpPT57cmV0dXJufSksWn1kcmFpbkFwcGx5UXVldWUoKXtyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMuZG9EcmFpbkFwcGx5UXVldWUoKSl9YXN5bmMgZG9EcmFpbkFwcGx5UXVldWUoKXtsZXQgJD1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3Qoe2FwbGQ6dDB9KTtpZigkLmxlbmd0aDwxKXJldHVybltdO2xldCBaPWEwKCQsKEopPT5KLmhlYWQpO3JldHVybiB0aGlzLmFwcGx5U3RvcmVkKFopfWFwcGx5SGFzaGVzPSgkKT0+e3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5kb0FwcGx5SGFzaGVzKCQpKX07YXN5bmMgZG9BcHBseUhhc2hlcygkKXtsZXQgWj1bXTtmb3IobGV0IFggb2YgJCl7bGV0IFk9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5nZXQoWCk7aWYoWSlaLnB1c2goWSl9bGV0IEo9YXdhaXQgdGhpcy5hcHBseVN0b3JlZChaKSxRPW5ldyBNYXA7Zm9yKGxldCBYPTA7WDxaLmxlbmd0aDtYKyspUS5zZXQoQihaW1hdLmhhc2gpLEpbWF0/PzEyKTtyZXR1cm4gJC5tYXAoKFgpPT5RLmdldChCKFgpKT8/MTMpfWFzeW5jIGFwcGx5U3RvcmVkKCQpe2lmKCQubGVuZ3RoPDEpcmV0dXJuW107bGV0IFo9JC5tYXAoKFkpPT4oey4uLlkuaGVhZCxib2Q6WS5ib2R5fSkpLEo9YXdhaXQgdGhpcy5zdGF0ZS5hcHBseShaKSxRPVtdLFg9W107Zm9yKGxldCBZPTA7WTwkLmxlbmd0aDtZKyspe2xldCBWPUpbWV07aWYoVj09PTB8fFY9PT0xNSlRLnB1c2goJFtZXS5oYXNoKTtlbHNlIGlmKFYhPT12b2lkIDAmJmNKKFYpKVgucHVzaCh7a2V5OiRbWV0uaGFzaCxlcnI6Vn0pfWlmKFEubGVuZ3RoPjApYXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5tYXJrQXBwbGllZChRKTtpZihYLmxlbmd0aD4wKWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubWFya0ZhaWxlZChYKTtyZXR1cm4gSn1hc3luYyBpbnNlcnRSYXcoJCl7bGV0e2Nsb2NrOlosY3J5cHRvOkp9PXRoaXMsW1EsWF09YXdhaXQgRUooe25vdzpaLm5vdygpLGJvZDokLGNyeXB0bzpKfSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFY9KGF3YWl0IHRoaXMuYXBwbHkoW3toZWFkOlEsYm9keTokfV0pKVswXTtpZihWIT09MCYmViE9PTE1KXJldHVybiBHKFY/PzEyKTtyZXR1cm4gUihRKX1hc3luYyBtYWtlVXBkYXRlKCQsWil7bGV0e2Nsb2NrOkosY3J5cHRvOlF9PXRoaXMsWD1KLm5vdygpO2lmKCQudXBkYXRlZEF0LmdldFRpbWUoKT5YLmdldFRpbWUoKSlyZXR1cm4gRyg0KTtsZXQgWT0kLmN0cisxLFtWLFddPWF3YWl0IEwkKHtub3c6WCxlaWQ6JC5laWQsY3RyOlksYm9kOlosY3J5cHRvOlF9KTtpZihXIT09MClyZXR1cm4gRyhXKTtyZXR1cm4gUih7aGVhZDpWLGJvZHk6Wn0pfWFzeW5jIHVwZGF0ZVdpdGhTa2V3KCQsWixKKXtpZihKPT09ITEpcmV0dXJuIEcoNCk7bGV0e2Nsb2NrOlEsY3J5cHRvOlh9PXRoaXMsWT1RLm5vdygpLFY9bmV3IG0oJC5laWQpLFtXLHpdPVYucmVhZFN0cnVjdChYMCk7aWYoeiE9PTApcmV0dXJuIEcoeik7bGV0IEs9JC51cGRhdGVkQXQuZ2V0VGltZSgpLVcudHMuZ2V0VGltZSgpLEY9e2VpZDokLmVpZCxvZmY6SysxLGN0cjokLmN0cisxLGxlbjowfSxPPShhd2FpdCB0aGlzLmFwcGx5KFt7aGVhZDpGLGJvZHk6dm9pZCAwfV0pKVswXTtpZihPIT09MCYmTyE9PTE1KXJldHVybiBHKE8/PzEyKTtpZihaPT09dm9pZCAwKXJldHVybiBSKEYpO2xldFtVLHFdPVQkKHtpZDpXLmlkLHRzOll9KTtpZihxIT09MClyZXR1cm4gRyhxKTtsZXRbSCxNXT1hd2FpdCBMJCh7bm93OlksZWlkOlUsY3RyOjAsYm9kOlosY3J5cHRvOlh9KTtpZihNIT09MClyZXR1cm4gRyhNKTtsZXQgQz0oYXdhaXQgdGhpcy5hcHBseShbe2hlYWQ6SCxib2R5Olp9XSkpWzBdO2lmKEMhPT0wJiZDIT09MTUpcmV0dXJuIEcoQz8/MTIpO3JldHVybiBSKEgpfWFzeW5jIHVwZGF0ZVJhdygkLFosSj10aGlzLmZvcmNlU2tld0hhbmRsaW5nQnlEZWZhdWx0KXtpZigkLnVwZGF0ZWRBdC5nZXRUaW1lKCk+dGhpcy5jbG9jay5ub3coKS5nZXRUaW1lKCkpcmV0dXJuIHRoaXMudXBkYXRlV2l0aFNrZXcoJCxaLEopO3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYihhc3luYygpPT57bGV0W1EsWF09YXdhaXQgdGhpcy5tYWtlVXBkYXRlKCQsWik7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFY9KGF3YWl0IHRoaXMuZG9BcHBseShbUV0pKVswXTtpZihWIT09MCYmViE9PTE1KXJldHVybiBHKFY/PzEyKTtyZXR1cm4gUihRLmhlYWQpfSl9YXN5bmMgaW5zZXJ0KCQpe2xldHtib2R5OlosdHlwZTpKLGdpZDpRLHBpZDpYLHRhZ3M6WX09JCxXPV8wKHtib2R5OlosdHlwZTpKLGdpZDpRLHBpZDpYLHRhZ3M6WX0pO3JldHVybiB0aGlzLmluc2VydFJhdyhXKX1hc3luYyB1cGRhdGUoJCl7bGV0e3ByaW9yOlosYm9keTpKLHR5cGU6USxnaWQ6WCxwaWQ6WSx0YWdzOlYsZm9yY2U6V309JCxLPV8wKHtib2R5OkosdHlwZTpRLGdpZDpYLHBpZDpZLHRhZ3M6Vn0pO3JldHVybiB0aGlzLnVwZGF0ZVJhdyhaLEssVz8/dGhpcy5mb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdCl9YXN5bmMgZGVsZXRlKCQpe2xldCBaPSQuZm9yY2U/PyEwO2lmKCJwcmlvciJpbiAkKXJldHVybiB0aGlzLnVwZGF0ZVJhdygkLnByaW9yLHZvaWQgMCxaKTtsZXRbSixRXT1hd2FpdCB0aGlzLnJldkZyb21BcmNoaXZlKCQuZWlkKTtpZihRIT09MClyZXR1cm4gRyhRKTtyZXR1cm4gdGhpcy51cGRhdGVSYXcoSix2b2lkIDAsWil9YXN5bmMgcmV2RnJvbUFyY2hpdmUoJCl7bGV0IFo9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5sYXN0KCQpO2lmKFopcmV0dXJuIGhKKFouaGVhZCk7bGV0IEo9bmV3IG0oJCksW1EsWF09Si5yZWFkU3RydWN0KFgwKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gUih7ZWlkOiQsY3RyOi0xLHVwZGF0ZWRBdDpRLnRzfSl9YXN5bmMgZ2VuRUlEKCQpe2xldHtjbG9jazpaLGNyeXB0bzpKfT10aGlzLFE9Wi5ub3coKTtpZigkIT09dm9pZCAwKXJldHVybiBUJCh7aWQ6JCx0czpRfSk7bGV0IFg9YXdhaXQgSi5nZW5SYW5kb21CeXRlcyg4KTtyZXR1cm4gVCQoe2lkOlgsdHM6UX0pfXN5bmMoKXtyZXR1cm4gdGhpcy5zeW5jUnVucy5ydW4oKCk9PnRoaXMuZG9TeW5jKCkpfWFzeW5jIGRvU3luYygpe2xldHtjb25uZWN0aW9uczokLGNyeXB0bzpaLHN0b3JlOkp9PXRoaXMsUT1hd2FpdCBKLnNlZWQubG9hZCgpO2lmKCFRKXJldHVybiAyMjthd2FpdCB0aGlzLmRyYWluQXBwbHlRdWV1ZSgpO2ZvcihsZXRbWCxZXW9mICQpe2xldCBWPWF3YWl0IEouaG9zdHMuZ2V0KFgpO2lmKCFWKWNvbnRpbnVlO2xldCBXPXtjb25uOlksc3RvcmU6SixlbmNsYXZlOlEsaG9zdDpWLGNyeXB0bzpaLG1heFB1c2hCeXRlczp0aGlzLm1heFB1c2hCeXRlcyxtYXhQdWxsQnl0ZXM6dGhpcy5tYXhQdWxsQnl0ZXMsb25Qcm9ncmVzczp0aGlzLmVtaXRQcm9ncmVzcyxwZWVrUHJvZ3Jlc3NFdmVyeTp0aGlzLnBlZWtQcm9ncmVzc0V2ZXJ5fSx6PWF3YWl0IExaKFcpO2lmKHohPT0wKXJldHVybiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcGVlazogJHt6fWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSx6O3RoaXMueGZlclN0YXRlLmVtaXQoKTtsZXQgSz1hd2FpdCBhSihXKTtpZihLIT09MClyZXR1cm4gY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHB1c2g6ICR7S31gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksSzt0aGlzLnhmZXJTdGF0ZS5lbWl0KCk7bGV0IEY9YXdhaXQgeFooVyxhc3luYygpPT57YXdhaXQgdGhpcy5kcmFpbkFwcGx5UXVldWUoKX0pO2lmKEYhPT0wJiZGIT09MTUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwdWxsOiAke0Z9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEY7dGhpcy54ZmVyU3RhdGUuZW1pdCgpfXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH1hc3luYyByZWJ1aWxkKCQpe2lmKHRoaXMuc2NoZWR1bGVkU3luYy5jYW5jZWwoKSxhd2FpdCB0aGlzLnN5bmNSdW5zLmZsdXNoKCksJD8uY2hlY2tIb3N0Pz8hMCl7bGV0IEo9YXdhaXQgdGhpcy5yZXB1bGwoKTtpZihKIT09MClyZXR1cm4gSn1yZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMucmVwbGF5KCkpfWFzeW5jIG1zZ2NoZWNrKCl7bGV0ICQ9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0S2V5cygpO3JldHVybiB6JCgkLHRoaXMuY3J5cHRvKX1saXN0TXNncygkKXtyZXR1cm4gdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0KCQpfWNvdW50TXNncygkKXtyZXR1cm4gdGhpcy5zdG9yZS5tZXNzYWdlcy5jb3VudCgkKX1hc3luYyByZWNvbmNpbGUoJCxaKXt0aGlzLnNjaGVkdWxlZFN5bmMuY2FuY2VsKCksYXdhaXQgdGhpcy5zeW5jUnVucy5mbHVzaCgpO2xldHtjb25uZWN0aW9uczpKLGNyeXB0bzpRLHN0b3JlOlh9PXRoaXMsWT1hd2FpdCBYLnNlZWQubG9hZCgpO2lmKCFZKXJldHVybiBHKDIyKTtsZXQgVj1hd2FpdCBYLmhvc3RzLmdldCgkKTtpZighVilyZXR1cm4gRygxMyk7bGV0IFc9Si5nZXQoJCk7aWYoIVd8fCFXLmlzQ29ubmVjdGVkKCkpe2lmKGF3YWl0IHRoaXMuY29ubmVjdFRvSG9zdChWLCExLCExKSxWPWF3YWl0IFguaG9zdHMuZ2V0KCQpLCFWKXJldHVybiBHKDEzKTtXPUouZ2V0KCQpfWlmKCFXKXJldHVybiBHKDEyKTtsZXQgej17Y29ubjpXLHN0b3JlOlgsZW5jbGF2ZTpZLGNyeXB0bzpRLG1heFB1c2hCeXRlczp0aGlzLm1heFB1c2hCeXRlcyxtYXhQdWxsQnl0ZXM6dGhpcy5tYXhQdWxsQnl0ZXMsb25Qcm9ncmVzczp0aGlzLmVtaXRQcm9ncmVzcyxwZWVrUHJvZ3Jlc3NFdmVyeTp0aGlzLnBlZWtQcm9ncmVzc0V2ZXJ5fSxbSyxGXT1hd2FpdCBCWih7Li4ueixob3N0OlZ9LFopO2lmKHRoaXMueGZlclN0YXRlLmVtaXQoKSxGIT09MClyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEcoRik7aWYoIUspcmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxHKDEyKTtpZihaPy5zeW5jPT09ITEpcmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxSKEspO2xldCBOPWF3YWl0IHRoaXMuc3luYygpO2lmKE4hPT0wKXJldHVybiBHKE4pO2xldCBPPWF3YWl0IFguaG9zdHMuZ2V0KCQpO2lmKCFPKXJldHVybiBHKDEzKTtsZXRbVSxxXT1hd2FpdCBCWih7Li4ueixob3N0Ok99LHtwdWxsOiExLHB1c2g6ITF9KTtpZih0aGlzLnhmZXJTdGF0ZS5lbWl0KCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLHEhPT0wKXJldHVybiBHKHEpO2lmKCFVKXJldHVybiBHKDEyKTtyZXR1cm4gUihVKX1hc3luYyByZXB1bGwoKXtsZXR7Y29ubmVjdGlvbnM6JCxjcnlwdG86WixzdG9yZTpKfT10aGlzLFE9YXdhaXQgSi5zZWVkLmxvYWQoKTtpZighUSlyZXR1cm4gMjI7bGV0IFg9QXJyYXkuZnJvbShhd2FpdCBKLmhvc3RzLmxpc3QoKSk7aWYoWC5sZW5ndGg8MSlyZXR1cm4gMDtmb3IobGV0IFkgb2YgWCl7bGV0IFY9JC5nZXQoWS5sYWJlbCk7aWYoIVZ8fCFWLmlzQ29ubmVjdGVkKCkpYXdhaXQgdGhpcy5jb25uZWN0VG9Ib3N0KFksITEsITEpfWZvcihsZXRbWSxWXW9mICQpe2xldCBXPWF3YWl0IEouaG9zdHMuZ2V0KFkpO2lmKCFXKWNvbnRpbnVlO2xldCB6PXtjb25uOlYsc3RvcmU6SixlbmNsYXZlOlEsaG9zdDp7Li4uVyxsYXN0U2VxOjB9LGNyeXB0bzpaLG1heFB1c2hCeXRlczp0aGlzLm1heFB1c2hCeXRlcyxtYXhQdWxsQnl0ZXM6dGhpcy5tYXhQdWxsQnl0ZXMsb25Qcm9ncmVzczp0aGlzLmVtaXRQcm9ncmVzcyxwZWVrUHJvZ3Jlc3NFdmVyeTp0aGlzLnBlZWtQcm9ncmVzc0V2ZXJ5fSxLPWF3YWl0IExaKHopO2lmKEshPT0wKXJldHVybiBjb25zb2xlLmVycm9yKGByZWJ1aWxkOiBmYWlsZWQgdG8gcGVlazogJHtLfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxLO3RoaXMueGZlclN0YXRlLmVtaXQoKTtsZXQgRj1hd2FpdCB4Wih6KTtpZihGIT09MCYmRiE9PTE1KXJldHVybiBjb25zb2xlLmVycm9yKGByZWJ1aWxkOiBmYWlsZWQgdG8gcHVsbDogJHtGfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxGO3RoaXMueGZlclN0YXRlLmVtaXQoKX1yZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9YXN5bmMgcmVwbGF5KCl7bGV0ICQ9YXdhaXQgdGhpcy5zdGF0ZS5jbGVhcigpO2lmKCQhPT0wKXJldHVybiAkO2xldCBaPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdCgpLEo9YTAoWiwoWSk9PlkuaGVhZCksUT1KLmxlbmd0aDtpZihRPDEpcmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwO2xldCBYPTA7d2hpbGUoWDxKLmxlbmd0aCl7bGV0IFk9MCxWPTAsVz1YO2ZvcihsZXQgSz1YO0s8Si5sZW5ndGgmJlY8MTAwJiZZPDEwMjQwMDtLKyspWSs9SltLXS5oZWFkLmxlbixWKyssVz1LKzE7bGV0IHo9Si5zbGljZShYLFcpO2F3YWl0IHRoaXMuYXBwbHlTdG9yZWQoeiksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJleGVjIixkb25lOlcsdG90YWw6UX0pLFg9V31yZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9YXN5bmMgd2lwZSgkKXtsZXQgWj0kPy5tc2dzIT09ITEsSj0kPy5lbnRzIT09ITEsUT0kPy5tZXRhIT09ITEsWD0kPy5zZWVkPT09ITA7dGhpcy5zY2hlZHVsZWRTeW5jLmNhbmNlbCgpLGF3YWl0IHRoaXMuZGlzY29ubmVjdCgpLGF3YWl0IHRoaXMuc3luY1J1bnMuZmx1c2goKTtsZXR7c3RvcmU6WX09dGhpcztpZihRKWF3YWl0IFkuaG9zdHMud2lwZSgpLGF3YWl0IFkudXBsb2Fkcy53aXBlKCksYXdhaXQgWS5kb3dubG9hZHMud2lwZSgpO2lmKFopYXdhaXQgWS5tZXNzYWdlcy53aXBlKCk7aWYoWClhd2FpdCBZLnNlZWQud2lwZSgpO2lmKEopYXdhaXQgdGhpcy5zdGF0ZS5jbGVhcigpO3RoaXMubGFzdFByb2dyZXNzPXdaLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLHRoaXMueGZlclN0YXRlLmVtaXQoKX1pbXBvcnQ9YXN5bmMoJCxaKT0+e2xldHtjcnlwdG86SixzdG9yZTpRfT10aGlzLFg9Wj8ub25Qcm9ncmVzcyxZPWF3YWl0IFEuc2VlZC5sb2FkKCk7aWYoIVkpcmV0dXJuIDIyO2NvbnNvbGUudGltZSgiaW1wb3J0OiBkZWNvZGluZyBmaWxlLi4uIik7bGV0IFY9YXdhaXQgJC5ieXRlcygpLFtXLHpdPWF3YWl0IGtKKFYsSixZKTtpZih6IT09MClyZXR1cm4gejtjb25zb2xlLnRpbWVFbmQoImltcG9ydDogZGVjb2RpbmcgZmlsZS4uLiIpO2xldCBLPTA7d2hpbGUoSzxXLmxlbmd0aCl7bGV0IEY9MCxOPTAsTz1LO2ZvcihsZXQgSD1LO0g8Vy5sZW5ndGgmJk48MTAwJiZGPDEwMjQwMDtIKyspRis9V1tIXS5oZWFkLmxlbixOKyssTz1IKzE7bGV0IFU9Vy5zbGljZShLLE8pO2NvbnNvbGUudGltZShgaW1wb3J0OiBhcHBseWluZyBbJHtLfSwgJHtPfV1gKTtsZXQgcT1hd2FpdCB0aGlzLmFwcGx5KFUse2VucXVldWVVcGxvYWQ6ITAsdHJpZ2dlclVwbG9hZDohMX0pO2NvbnNvbGUudGltZUVuZChgaW1wb3J0OiBhcHBseWluZyBbJHtLfSwgJHtPfV1gKTtmb3IobGV0IEg9MDtIPFUubGVuZ3RoO0grKyl7bGV0IE09cVtIXTtpZihNIT09MCYmTSE9PTE1KWNvbnNvbGUud2FybihgZmFpbGVkIHRvIGltcG9ydCBtc2cgJHtLK0h9OiAke0RbTV19YCl9aWYoWClxdWV1ZU1pY3JvdGFzaygoKT0+WChPLFcubGVuZ3RoLDApKTt0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImltcG9ydCIsZG9uZTpPLHRvdGFsOlcubGVuZ3RofSksSz1PfXJldHVybiB0aGlzLnNjaGVkdWxlU3luYygpLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfTtzY2hlZHVsZVN5bmM9KCk9PntpZih0aGlzLm9uU2NoZWR1bGVTeW5jKXt0aGlzLm9uU2NoZWR1bGVTeW5jKCk7cmV0dXJufXRoaXMuc2NoZWR1bGVkU3luYy5zY2hlZHVsZSgpfTthc3luYyBleHBvcnRCeXRlcygpe2xldHtjcnlwdG86JCxzdG9yZTpafT10aGlzLEo9YXdhaXQgWi5zZWVkLmxvYWQoKTtpZighSilyZXR1cm4gRygyMik7bGV0IFE9YXdhaXQgWi5tZXNzYWdlcy5saXN0KCk7cmV0dXJuIEJKKCJleHBvcnQiLDAsUSwkLEopfWFzeW5jIGV4cG9ydCgkKXtsZXRbWixKXT1hd2FpdCB0aGlzLmV4cG9ydEJ5dGVzKCk7aWYoSiE9PTApcmV0dXJuIEo7aWYoIVopcmV0dXJuIDEyO2xldCBRPW5ldyBCbG9iKFtaLnNsaWNlKCldKTtyZXR1cm4gdUooUSwkKSwwfWFzeW5jIGxpbmsoJCxaPSEwKXtpZihhd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmFkZCgkKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKSxaKXtsZXQgSj1hd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmdldCgkLmxhYmVsKTtpZihKKWF3YWl0IHRoaXMuY29ubmVjdFRvSG9zdChKKX19YXN5bmMgdW5saW5rKCQpe2F3YWl0IHRoaXMuc3RvcmUuaG9zdHMuZGVsKCQpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpfWFzeW5jIGhvc3RzKCl7cmV0dXJuIEFycmF5LmZyb20oYXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5saXN0KCkpfWNvbm5lY3RUb0hvc3Q9YXN5bmMoJCxaPSEwLEo9ITApPT57bGV0e2Nsb2NrOlEsY29ubmVjdGlvbnM6WCxjcnlwdG86WSxzdG9yZTpWLHRyYW5zcG9ydDpXfT10aGlzLHo9WC5nZXQoJC5sYWJlbCk7aWYoeil7aWYoei5pc0Nvbm5lY3RlZCgpKXJldHVybjt0cnl7ei5jbG9zZUxpc3RlbmVyKCl9Y2F0Y2h7fVguZGVsZXRlKCQubGFiZWwpfWxldCBLPWF3YWl0IFYuc2VlZC5sb2FkKCk7aWYoIUspcmV0dXJuO2NvbnNvbGUuaW5mbyhgQ29ubmVjdGluZyB0byAkeyQuaGFuZGxlfSAoJHskLmxhYmVsfSlgKTtsZXQgRj1uZXcgXyQoSyxZLCQsUSxXKCQpLChOKT0+Vi5ob3N0cy5zZXQoJC5sYWJlbCxOKSk7aWYoYXdhaXQgRi5yZWdpc3RlcigpLFopYXdhaXQgRi5saXN0ZW4oYXN5bmMoTik9PntsZXQgTz17Y29ubjpGLHN0b3JlOlYsZW5jbGF2ZTpLLGhvc3Q6JCxjcnlwdG86WSxtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX07cmV0dXJuIHRKKE4sTyx0aGlzLnNjaGVkdWxlU3luYyl9LCgpPT50aGlzLmNsaWVudFN0YXRlLmVtaXQoKSwoKT0+dGhpcy5jbGllbnRTdGF0ZS5lbWl0KCkpO2lmKFguc2V0KCQubGFiZWwsRiksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksSil0aGlzLnNjaGVkdWxlU3luYygpfTthc3luYyBjb25uZWN0KCQ9ITAsWj0hMCl7bGV0e2Nvbm5lY3RUb0hvc3Q6SixzY2hlZHVsZVN5bmM6USxzdG9yZTpYfT10aGlzO2lmKCFhd2FpdCBYLnNlZWQubG9hZCgpKXJldHVybjthd2FpdCB0aGlzLmRyYWluQXBwbHlRdWV1ZSgpO2xldCBWPWF3YWl0IFguaG9zdHMubGlzdCgpO2ZvcihsZXQgVyBvZiBWKWF3YWl0IEooVywkLCExKTtpZihaKVEoKX1kaXNjb25uZWN0PWFzeW5jKCk9Pntmb3IobGV0ICQgb2YgdGhpcy5jb25uZWN0aW9ucy52YWx1ZXMoKSl0cnl7JC5jbG9zZUxpc3RlbmVyKCl9Y2F0Y2h7fXRoaXMuY29ubmVjdGlvbnMuY2xlYXIoKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKX19dmFyIHgwPXR5cGVvZiBnbG9iYWxUaGlzPT09Im9iamVjdCImJiJjcnlwdG8iaW4gZ2xvYmFsVGhpcz9nbG9iYWxUaGlzLmNyeXB0bzp2b2lkIDA7ZnVuY3Rpb24gdiQoJCl7aWYoIU51bWJlci5pc1NhZmVJbnRlZ2VyKCQpfHwkPDApdGhyb3cgRXJyb3IoInBvc2l0aXZlIGludGVnZXIgZXhwZWN0ZWQsIGdvdCAiKyQpfWZ1bmN0aW9uIEVaKCQpe3JldHVybiAkIGluc3RhbmNlb2YgVWludDhBcnJheXx8QXJyYXlCdWZmZXIuaXNWaWV3KCQpJiYkLmNvbnN0cnVjdG9yLm5hbWU9PT0iVWludDhBcnJheSJ9ZnVuY3Rpb24gZCgkLC4uLlope2lmKCFFWigkKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCIpO2lmKFoubGVuZ3RoPjAmJiFaLmluY2x1ZGVzKCQubGVuZ3RoKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCBvZiBsZW5ndGggIitaKyIsIGdvdCBsZW5ndGg9IiskLmxlbmd0aCl9ZnVuY3Rpb24gZlooJCxaPSEwKXtpZigkLmRlc3Ryb3llZCl0aHJvdyBFcnJvcigiSGFzaCBpbnN0YW5jZSBoYXMgYmVlbiBkZXN0cm95ZWQiKTtpZihaJiYkLmZpbmlzaGVkKXRocm93IEVycm9yKCJIYXNoI2RpZ2VzdCgpIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkIil9ZnVuY3Rpb24gZUooJCxaKXtkKCQpO2xldCBKPVoub3V0cHV0TGVuO2lmKCQubGVuZ3RoPEopdGhyb3cgRXJyb3IoImRpZ2VzdEludG8oKSBleHBlY3RzIG91dHB1dCBidWZmZXIgb2YgbGVuZ3RoIGF0IGxlYXN0ICIrSil9ZnVuY3Rpb24gZ1ooJCl7aWYodHlwZW9mICQhPT0iYm9vbGVhbiIpdGhyb3cgRXJyb3IoYGJvb2xlYW4gZXhwZWN0ZWQsIG5vdCAkeyR9YCl9LyohIG5vYmxlLWNpcGhlcnMgLSBNSVQgTGljZW5zZSAoYykgMjAyMyBQYXVsIE1pbGxlciAocGF1bG1pbGxyLmNvbSkgKi92YXIgSDA9KCQpPT5uZXcgVWludDMyQXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LE1hdGguZmxvb3IoJC5ieXRlTGVuZ3RoLzQpKTt2YXIgZ1g9bmV3IFVpbnQ4QXJyYXkobmV3IFVpbnQzMkFycmF5KFsyODc0NTQwMjBdKS5idWZmZXIpWzBdPT09Njg7aWYoIWdYKXRocm93IEVycm9yKCJOb24gbGl0dGxlLWVuZGlhbiBoYXJkd2FyZSBpcyBub3Qgc3VwcG9ydGVkIik7ZnVuY3Rpb24gbVgoJCl7aWYodHlwZW9mICQhPT0ic3RyaW5nIil0aHJvdyBFcnJvcigic3RyaW5nIGV4cGVjdGVkIik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSl9ZnVuY3Rpb24gYiQoJCl7aWYodHlwZW9mICQ9PT0ic3RyaW5nIikkPW1YKCQpO2Vsc2UgaWYoRVooJCkpJD15JCgkKTtlbHNlIHRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkLCBnb3QgIit0eXBlb2YgJCk7cmV0dXJuICR9ZnVuY3Rpb24gJFEoJCxaKXtpZihaPT1udWxsfHx0eXBlb2YgWiE9PSJvYmplY3QiKXRocm93IEVycm9yKCJvcHRpb25zIG11c3QgYmUgZGVmaW5lZCIpO3JldHVybiBPYmplY3QuYXNzaWduKCQsWil9ZnVuY3Rpb24gWlEoJCxaKXtpZigkLmxlbmd0aCE9PVoubGVuZ3RoKXJldHVybiExO2xldCBKPTA7Zm9yKGxldCBRPTA7UTwkLmxlbmd0aDtRKyspSnw9JFtRXV5aW1FdO3JldHVybiBKPT09MH12YXIgSlE9KCQsWik9PntmdW5jdGlvbiBKKFEsLi4uWCl7aWYoZChRKSwkLm5vbmNlTGVuZ3RoIT09dm9pZCAwKXtsZXQgRj1YWzBdO2lmKCFGKXRocm93IEVycm9yKCJub25jZSAvIGl2IHJlcXVpcmVkIik7aWYoJC52YXJTaXplTm9uY2UpZChGKTtlbHNlIGQoRiwkLm5vbmNlTGVuZ3RoKX1sZXQgWT0kLnRhZ0xlbmd0aDtpZihZJiZYWzFdIT09dm9pZCAwKWQoWFsxXSk7bGV0IFY9WihRLC4uLlgpLFc9KEYsTik9PntpZihOIT09dm9pZCAwKXtpZihGIT09Mil0aHJvdyBFcnJvcigiY2lwaGVyIG91dHB1dCBub3Qgc3VwcG9ydGVkIik7ZChOKX19LHo9ITE7cmV0dXJue2VuY3J5cHQoRixOKXtpZih6KXRocm93IEVycm9yKCJjYW5ub3QgZW5jcnlwdCgpIHR3aWNlIHdpdGggc2FtZSBrZXkgKyBub25jZSIpO3JldHVybiB6PSEwLGQoRiksVyhWLmVuY3J5cHQubGVuZ3RoLE4pLFYuZW5jcnlwdChGLE4pfSxkZWNyeXB0KEYsTil7aWYoZChGKSxZJiZGLmxlbmd0aDxZKXRocm93IEVycm9yKCJpbnZhbGlkIGNpcGhlcnRleHQgbGVuZ3RoOiBzbWFsbGVyIHRoYW4gdGFnTGVuZ3RoPSIrWSk7cmV0dXJuIFcoVi5kZWNyeXB0Lmxlbmd0aCxOKSxWLmRlY3J5cHQoRixOKX19fXJldHVybiBPYmplY3QuYXNzaWduKEosJCksSn07ZnVuY3Rpb24gbVooJCxaLEo9ITApe2lmKFo9PT12b2lkIDApcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpO2lmKFoubGVuZ3RoIT09JCl0aHJvdyBFcnJvcigiaW52YWxpZCBvdXRwdXQgbGVuZ3RoLCBleHBlY3RlZCAiKyQrIiwgZ290OiAiK1oubGVuZ3RoKTtpZihKJiYhU1goWikpdGhyb3cgRXJyb3IoImludmFsaWQgb3V0cHV0LCBtdXN0IGJlIGFsaWduZWQiKTtyZXR1cm4gWn1mdW5jdGlvbiBTWCgkKXtyZXR1cm4gJC5ieXRlT2Zmc2V0JTQ9PT0wfWZ1bmN0aW9uIHkkKCQpe3JldHVybiBVaW50OEFycmF5LmZyb20oJCl9ZnVuY3Rpb24gTzAoLi4uJCl7Zm9yKGxldCBaPTA7WjwkLmxlbmd0aDtaKyspJFtaXS5maWxsKDApfWZ1bmN0aW9uIGgkKCQ9MzIpe2lmKHgwJiZ0eXBlb2YgeDAuZ2V0UmFuZG9tVmFsdWVzPT09ImZ1bmN0aW9uIilyZXR1cm4geDAuZ2V0UmFuZG9tVmFsdWVzKG5ldyBVaW50OEFycmF5KCQpKTtpZih4MCYmdHlwZW9mIHgwLnJhbmRvbUJ5dGVzPT09ImZ1bmN0aW9uIilyZXR1cm4geDAucmFuZG9tQnl0ZXMoJCk7dGhyb3cgRXJyb3IoImNyeXB0by5nZXRSYW5kb21WYWx1ZXMgbXVzdCBiZSBkZWZpbmVkIil9dmFyIFhRPSgkKT0+VWludDhBcnJheS5mcm9tKCQuc3BsaXQoIiIpLm1hcCgoWik9PlouY2hhckNvZGVBdCgwKSkpLHZYPVhRKCJleHBhbmQgMTYtYnl0ZSBrIiksYlg9WFEoImV4cGFuZCAzMi1ieXRlIGsiKSx5WD1IMCh2WCksaFg9SDAoYlgpO2Z1bmN0aW9uIGooJCxaKXtyZXR1cm4gJDw8WnwkPj4+MzItWn1mdW5jdGlvbiBTWigkKXtyZXR1cm4gJC5ieXRlT2Zmc2V0JTQ9PT0wfXZhciBpJD02NCxpWD0xNixZUT00Mjk0OTY3Mjk1LFFRPW5ldyBVaW50MzJBcnJheTtmdW5jdGlvbiBsWCgkLFosSixRLFgsWSxWLFcpe2xldCB6PVgubGVuZ3RoLEs9bmV3IFVpbnQ4QXJyYXkoaSQpLEY9SDAoSyksTj1TWihYKSYmU1ooWSksTz1OP0gwKFgpOlFRLFU9Tj9IMChZKTpRUTtmb3IobGV0IHE9MDtxPHo7VisrKXtpZigkKFosSixRLEYsVixXKSxWPj1ZUSl0aHJvdyBFcnJvcigiYXJ4OiBjb3VudGVyIG92ZXJmbG93Iik7bGV0IEg9TWF0aC5taW4oaSQsei1xKTtpZihOJiZIPT09aSQpe2xldCBNPXEvNDtpZihxJTQhPT0wKXRocm93IEVycm9yKCJhcng6IGludmFsaWQgYmxvY2sgcG9zaXRpb24iKTtmb3IobGV0IFA9MCxDO1A8aVg7UCsrKUM9TStQLFVbQ109T1tDXV5GW1BdO3ErPWkkO2NvbnRpbnVlfWZvcihsZXQgTT0wLFA7TTxIO00rKylQPXErTSxZW1BdPVhbUF1eS1tNXTtxKz1IfX1mdW5jdGlvbiBWUSgkLFope2xldHthbGxvd1Nob3J0S2V5czpKLGV4dGVuZE5vbmNlRm46USxjb3VudGVyTGVuZ3RoOlgsY291bnRlclJpZ2h0Olkscm91bmRzOlZ9PSRRKHthbGxvd1Nob3J0S2V5czohMSxjb3VudGVyTGVuZ3RoOjgsY291bnRlclJpZ2h0OiExLHJvdW5kczoyMH0sWik7aWYodHlwZW9mICQhPT0iZnVuY3Rpb24iKXRocm93IEVycm9yKCJjb3JlIG11c3QgYmUgYSBmdW5jdGlvbiIpO3JldHVybiB2JChYKSx2JChWKSxnWihZKSxnWihKKSwoVyx6LEssRixOPTApPT57ZChXKSxkKHopLGQoSyk7bGV0IE89Sy5sZW5ndGg7aWYoRj09PXZvaWQgMClGPW5ldyBVaW50OEFycmF5KE8pO2lmKGQoRiksdiQoTiksTjwwfHxOPj1ZUSl0aHJvdyBFcnJvcigiYXJ4OiBjb3VudGVyIG92ZXJmbG93Iik7aWYoRi5sZW5ndGg8Tyl0aHJvdyBFcnJvcihgYXJ4OiBvdXRwdXQgKCR7Ri5sZW5ndGh9KSBpcyBzaG9ydGVyIHRoYW4gZGF0YSAoJHtPfSlgKTtsZXQgVT1bXSxxPVcubGVuZ3RoLEgsTTtpZihxPT09MzIpVS5wdXNoKEg9eSQoVykpLE09aFg7ZWxzZSBpZihxPT09MTYmJkopSD1uZXcgVWludDhBcnJheSgzMiksSC5zZXQoVyksSC5zZXQoVywxNiksTT15WCxVLnB1c2goSCk7ZWxzZSB0aHJvdyBFcnJvcihgYXJ4OiBpbnZhbGlkIDMyLWJ5dGUga2V5LCBnb3QgbGVuZ3RoPSR7cX1gKTtpZighU1ooeikpVS5wdXNoKHo9eSQoeikpO2xldCBQPUgwKEgpO2lmKFEpe2lmKHoubGVuZ3RoIT09MjQpdGhyb3cgRXJyb3IoImFyeDogZXh0ZW5kZWQgbm9uY2UgbXVzdCBiZSAyNCBieXRlcyIpO1EoTSxQLEgwKHouc3ViYXJyYXkoMCwxNikpLFApLHo9ei5zdWJhcnJheSgxNil9bGV0IEM9MTYtWDtpZihDIT09ei5sZW5ndGgpdGhyb3cgRXJyb3IoYGFyeDogbm9uY2UgbXVzdCBiZSAke0N9IG9yIDE2IGJ5dGVzYCk7aWYoQyE9PTEyKXtsZXQgST1uZXcgVWludDhBcnJheSgxMik7SS5zZXQoeixZPzA6MTItei5sZW5ndGgpLHo9SSxVLnB1c2goeil9bGV0IFQ9SDAoeik7cmV0dXJuIGxYKCQsTSxQLFQsSyxGLE4sViksTzAoLi4uVSksRn19dmFyIG89KCQsWik9PiRbWisrXSYyNTV8KCRbWisrXSYyNTUpPDw4O2NsYXNzIFdRe2NvbnN0cnVjdG9yKCQpe3RoaXMuYmxvY2tMZW49MTYsdGhpcy5vdXRwdXRMZW49MTYsdGhpcy5idWZmZXI9bmV3IFVpbnQ4QXJyYXkoMTYpLHRoaXMucj1uZXcgVWludDE2QXJyYXkoMTApLHRoaXMuaD1uZXcgVWludDE2QXJyYXkoMTApLHRoaXMucGFkPW5ldyBVaW50MTZBcnJheSg4KSx0aGlzLnBvcz0wLHRoaXMuZmluaXNoZWQ9ITEsJD1iJCgkKSxkKCQsMzIpO2xldCBaPW8oJCwwKSxKPW8oJCwyKSxRPW8oJCw0KSxYPW8oJCw2KSxZPW8oJCw4KSxWPW8oJCwxMCksVz1vKCQsMTIpLHo9bygkLDE0KTt0aGlzLnJbMF09WiY4MTkxLHRoaXMuclsxXT0oWj4+PjEzfEo8PDMpJjgxOTEsdGhpcy5yWzJdPShKPj4+MTB8UTw8NikmNzkzOSx0aGlzLnJbM109KFE+Pj43fFg8PDkpJjgxOTEsdGhpcy5yWzRdPShYPj4+NHxZPDwxMikmMjU1LHRoaXMucls1XT1ZPj4+MSY4MTkwLHRoaXMucls2XT0oWT4+PjE0fFY8PDIpJjgxOTEsdGhpcy5yWzddPShWPj4+MTF8Vzw8NSkmODA2NSx0aGlzLnJbOF09KFc+Pj44fHo8PDgpJjgxOTEsdGhpcy5yWzldPXo+Pj41JjEyNztmb3IobGV0IEs9MDtLPDg7SysrKXRoaXMucGFkW0tdPW8oJCwxNisyKkspfXByb2Nlc3MoJCxaLEo9ITEpe2xldCBRPUo/MDoyMDQ4LHtoOlgscjpZfT10aGlzLFY9WVswXSxXPVlbMV0sej1ZWzJdLEs9WVszXSxGPVlbNF0sTj1ZWzVdLE89WVs2XSxVPVlbN10scT1ZWzhdLEg9WVs5XSxNPW8oJCxaKzApLFA9bygkLForMiksQz1vKCQsWis0KSxUPW8oJCxaKzYpLEk9bygkLForOCksQT1vKCQsWisxMCkseD1vKCQsWisxMiksZz1vKCQsWisxNCksZj1YWzBdKyhNJjgxOTEpLGs9WFsxXSsoKE0+Pj4xM3xQPDwzKSY4MTkxKSxiPVhbMl0rKChQPj4+MTB8Qzw8NikmODE5MSksdz1YWzNdKygoQz4+Pjd8VDw8OSkmODE5MSksaT1YWzRdKygoVD4+PjR8STw8MTIpJjgxOTEpLHU9WFs1XSsoST4+PjEmODE5MSksTD1YWzZdKygoST4+PjE0fEE8PDIpJjgxOTEpLHY9WFs3XSsoKEE+Pj4xMXx4PDw1KSY4MTkxKSxFPVhbOF0rKCh4Pj4+OHxnPDw4KSY4MTkxKSx5PVhbOV0rKGc+Pj41fFEpLF89MCxuPV8rZipWK2sqKDUqSCkrYiooNSpxKSt3Kig1KlUpK2kqKDUqTyk7Xz1uPj4+MTMsbiY9ODE5MSxuKz11Kig1Kk4pK0wqKDUqRikrdiooNSpLKStFKig1KnopK3kqKDUqVyksXys9bj4+PjEzLG4mPTgxOTE7bGV0IHM9XytmKlcraypWK2IqKDUqSCkrdyooNSpxKStpKig1KlUpO189cz4+PjEzLHMmPTgxOTEscys9dSooNSpPKStMKig1Kk4pK3YqKDUqRikrRSooNSpLKSt5Kig1KnopLF8rPXM+Pj4xMyxzJj04MTkxO2xldCBRMD1fK2YqeitrKlcrYipWK3cqKDUqSCkraSooNSpxKTtfPVEwPj4+MTMsUTAmPTgxOTEsUTArPXUqKDUqVSkrTCooNSpPKSt2Kig1Kk4pK0UqKDUqRikreSooNSpLKSxfKz1RMD4+PjEzLFEwJj04MTkxO2xldCBwPV8rZipLK2sqeitiKlcrdypWK2kqKDUqSCk7Xz1wPj4+MTMscCY9ODE5MSxwKz11Kig1KnEpK0wqKDUqVSkrdiooNSpPKStFKig1Kk4pK3kqKDUqRiksXys9cD4+PjEzLHAmPTgxOTE7bGV0IHEwPV8rZipGK2sqSytiKnordypXK2kqVjtfPXEwPj4+MTMscTAmPTgxOTEscTArPXUqKDUqSCkrTCooNSpxKSt2Kig1KlUpK0UqKDUqTykreSooNSpOKSxfKz1xMD4+PjEzLHEwJj04MTkxO2xldCBiMD1fK2YqTitrKkYrYipLK3cqeitpKlc7Xz1iMD4+PjEzLGIwJj04MTkxLGIwKz11KlYrTCooNSpIKSt2Kig1KnEpK0UqKDUqVSkreSooNSpPKSxfKz1iMD4+PjEzLGIwJj04MTkxO2xldCB5MD1fK2YqTytrKk4rYipGK3cqSytpKno7Xz15MD4+PjEzLHkwJj04MTkxLHkwKz11KlcrTCpWK3YqKDUqSCkrRSooNSpxKSt5Kig1KlUpLF8rPXkwPj4+MTMseTAmPTgxOTE7bGV0IGgwPV8rZipVK2sqTytiKk4rdypGK2kqSztfPWgwPj4+MTMsaDAmPTgxOTEsaDArPXUqeitMKlcrdipWK0UqKDUqSCkreSooNSpxKSxfKz1oMD4+PjEzLGgwJj04MTkxO2xldCBpMD1fK2YqcStrKlUrYipPK3cqTitpKkY7Xz1pMD4+PjEzLGkwJj04MTkxLGkwKz11KksrTCp6K3YqVytFKlYreSooNSpIKSxfKz1pMD4+PjEzLGkwJj04MTkxO2xldCBsMD1fK2YqSCtrKnErYipVK3cqTytpKk47Xz1sMD4+PjEzLGwwJj04MTkxLGwwKz11KkYrTCpLK3YqeitFKlcreSpWLF8rPWwwPj4+MTMsbDAmPTgxOTEsXz0oXzw8MikrX3wwLF89XytufDAsbj1fJjgxOTEsXz1fPj4+MTMscys9XyxYWzBdPW4sWFsxXT1zLFhbMl09UTAsWFszXT1wLFhbNF09cTAsWFs1XT1iMCxYWzZdPXkwLFhbN109aDAsWFs4XT1pMCxYWzldPWwwfWZpbmFsaXplKCl7bGV0e2g6JCxwYWQ6Wn09dGhpcyxKPW5ldyBVaW50MTZBcnJheSgxMCksUT0kWzFdPj4+MTM7JFsxXSY9ODE5MTtmb3IobGV0IFY9MjtWPDEwO1YrKykkW1ZdKz1RLFE9JFtWXT4+PjEzLCRbVl0mPTgxOTE7JFswXSs9USo1LFE9JFswXT4+PjEzLCRbMF0mPTgxOTEsJFsxXSs9USxRPSRbMV0+Pj4xMywkWzFdJj04MTkxLCRbMl0rPVEsSlswXT0kWzBdKzUsUT1KWzBdPj4+MTMsSlswXSY9ODE5MTtmb3IobGV0IFY9MTtWPDEwO1YrKylKW1ZdPSRbVl0rUSxRPUpbVl0+Pj4xMyxKW1ZdJj04MTkxO0pbOV0tPTgxOTI7bGV0IFg9KFFeMSktMTtmb3IobGV0IFY9MDtWPDEwO1YrKylKW1ZdJj1YO1g9flg7Zm9yKGxldCBWPTA7VjwxMDtWKyspJFtWXT0kW1ZdJlh8SltWXTskWzBdPSgkWzBdfCRbMV08PDEzKSY2NTUzNSwkWzFdPSgkWzFdPj4+M3wkWzJdPDwxMCkmNjU1MzUsJFsyXT0oJFsyXT4+PjZ8JFszXTw8NykmNjU1MzUsJFszXT0oJFszXT4+Pjl8JFs0XTw8NCkmNjU1MzUsJFs0XT0oJFs0XT4+PjEyfCRbNV08PDF8JFs2XTw8MTQpJjY1NTM1LCRbNV09KCRbNl0+Pj4yfCRbN108PDExKSY2NTUzNSwkWzZdPSgkWzddPj4+NXwkWzhdPDw4KSY2NTUzNSwkWzddPSgkWzhdPj4+OHwkWzldPDw1KSY2NTUzNTtsZXQgWT0kWzBdK1pbMF07JFswXT1ZJjY1NTM1O2ZvcihsZXQgVj0xO1Y8ODtWKyspWT0oJFtWXStaW1ZdfDApKyhZPj4+MTYpfDAsJFtWXT1ZJjY1NTM1O08wKEopfXVwZGF0ZSgkKXtmWih0aGlzKTtsZXR7YnVmZmVyOlosYmxvY2tMZW46Sn09dGhpczskPWIkKCQpO2xldCBRPSQubGVuZ3RoO2ZvcihsZXQgWD0wO1g8UTspe2xldCBZPU1hdGgubWluKEotdGhpcy5wb3MsUS1YKTtpZihZPT09Sil7Zm9yKDtKPD1RLVg7WCs9Sil0aGlzLnByb2Nlc3MoJCxYKTtjb250aW51ZX1pZihaLnNldCgkLnN1YmFycmF5KFgsWCtZKSx0aGlzLnBvcyksdGhpcy5wb3MrPVksWCs9WSx0aGlzLnBvcz09PUopdGhpcy5wcm9jZXNzKFosMCwhMSksdGhpcy5wb3M9MH1yZXR1cm4gdGhpc31kZXN0cm95KCl7TzAodGhpcy5oLHRoaXMucix0aGlzLmJ1ZmZlcix0aGlzLnBhZCl9ZGlnZXN0SW50bygkKXtmWih0aGlzKSxlSigkLHRoaXMpLHRoaXMuZmluaXNoZWQ9ITA7bGV0e2J1ZmZlcjpaLGg6Sn09dGhpcyx7cG9zOlF9PXRoaXM7aWYoUSl7WltRKytdPTE7Zm9yKDtRPDE2O1ErKylaW1FdPTA7dGhpcy5wcm9jZXNzKFosMCwhMCl9dGhpcy5maW5hbGl6ZSgpO2xldCBYPTA7Zm9yKGxldCBZPTA7WTw4O1krKykkW1grK109SltZXT4+PjAsJFtYKytdPUpbWV0+Pj44O3JldHVybiAkfWRpZ2VzdCgpe2xldHtidWZmZXI6JCxvdXRwdXRMZW46Wn09dGhpczt0aGlzLmRpZ2VzdEludG8oJCk7bGV0IEo9JC5zbGljZSgwLFopO3JldHVybiB0aGlzLmRlc3Ryb3koKSxKfX1mdW5jdGlvbiB1WCgkKXtsZXQgWj0oUSxYKT0+JChYKS51cGRhdGUoYiQoUSkpLmRpZ2VzdCgpLEo9JChuZXcgVWludDhBcnJheSgzMikpO3JldHVybiBaLm91dHB1dExlbj1KLm91dHB1dExlbixaLmJsb2NrTGVuPUouYmxvY2tMZW4sWi5jcmVhdGU9KFEpPT4kKFEpLFp9dmFyIHZaPXVYKCgkKT0+bmV3IFdRKCQpKTtmdW5jdGlvbiBwWCgkLFosSixRLFgsWT0yMCl7bGV0IFY9JFswXSxXPVpbMF0sej1aWzFdLEs9WlsyXSxGPVpbM10sTj0kWzFdLE89SlswXSxVPUpbMV0scT1YLEg9MCxNPSRbMl0sUD1aWzRdLEM9Wls1XSxUPVpbNl0sST1aWzddLEE9JFszXSx4PVYsZz1XLGY9eixrPUssYj1GLHc9TixpPU8sdT1VLEw9cSx2PUgsRT1NLHk9UCxfPUMsbj1ULHM9SSxRMD1BO2ZvcihsZXQgcTA9MDtxMDxZO3EwKz0yKWJePWooeCtffDAsNyksTF49aihiK3h8MCw5KSxfXj1qKEwrYnwwLDEzKSx4Xj1qKF8rTHwwLDE4KSx2Xj1qKHcrZ3wwLDcpLG5ePWoodit3fDAsOSksZ149aihuK3Z8MCwxMyksd149aihnK258MCwxOCksc149aihFK2l8MCw3KSxmXj1qKHMrRXwwLDkpLGlePWooZitzfDAsMTMpLEVePWooaStmfDAsMTgpLGtePWooUTAreXwwLDcpLHVePWooaytRMHwwLDkpLHlePWoodStrfDAsMTMpLFEwXj1qKHkrdXwwLDE4KSxnXj1qKHgra3wwLDcpLGZePWooZyt4fDAsOSksa149aihmK2d8MCwxMykseF49aihrK2Z8MCwxOCksaV49aih3K2J8MCw3KSx1Xj1qKGkrd3wwLDkpLGJePWoodStpfDAsMTMpLHdePWooYit1fDAsMTgpLHlePWooRSt2fDAsNyksTF49aih5K0V8MCw5KSx2Xj1qKEwreXwwLDEzKSxFXj1qKHYrTHwwLDE4KSxfXj1qKFEwK3N8MCw3KSxuXj1qKF8rUTB8MCw5KSxzXj1qKG4rX3wwLDEzKSxRMF49aihzK258MCwxOCk7bGV0IHA9MDtRW3ArK109Vit4fDAsUVtwKytdPVcrZ3wwLFFbcCsrXT16K2Z8MCxRW3ArK109SytrfDAsUVtwKytdPUYrYnwwLFFbcCsrXT1OK3d8MCxRW3ArK109TytpfDAsUVtwKytdPVUrdXwwLFFbcCsrXT1xK0x8MCxRW3ArK109SCt2fDAsUVtwKytdPU0rRXwwLFFbcCsrXT1QK3l8MCxRW3ArK109QytffDAsUVtwKytdPVQrbnwwLFFbcCsrXT1JK3N8MCxRW3ArK109QStRMHwwfWZ1bmN0aW9uIGNYKCQsWixKLFEpe2xldCBYPSRbMF0sWT1aWzBdLFY9WlsxXSxXPVpbMl0sej1aWzNdLEs9JFsxXSxGPUpbMF0sTj1KWzFdLE89SlsyXSxVPUpbM10scT0kWzJdLEg9Wls0XSxNPVpbNV0sUD1aWzZdLEM9Wls3XSxUPSRbM107Zm9yKGxldCBBPTA7QTwyMDtBKz0yKXpePWooWCtNfDAsNyksT149aih6K1h8MCw5KSxNXj1qKE8renwwLDEzKSxYXj1qKE0rT3wwLDE4KSxVXj1qKEsrWXwwLDcpLFBePWooVStLfDAsOSksWV49aihQK1V8MCwxMyksS149aihZK1B8MCwxOCksQ149aihxK0Z8MCw3KSxWXj1qKEMrcXwwLDkpLEZePWooVitDfDAsMTMpLHFePWooRitWfDAsMTgpLFdePWooVCtIfDAsNyksTl49aihXK1R8MCw5KSxIXj1qKE4rV3wwLDEzKSxUXj1qKEgrTnwwLDE4KSxZXj1qKFgrV3wwLDcpLFZePWooWStYfDAsOSksV149aihWK1l8MCwxMyksWF49aihXK1Z8MCwxOCksRl49aihLK3p8MCw3KSxOXj1qKEYrS3wwLDkpLHpePWooTitGfDAsMTMpLEtePWooeitOfDAsMTgpLEhePWoocStVfDAsNyksT149aihIK3F8MCw5KSxVXj1qKE8rSHwwLDEzKSxxXj1qKFUrT3wwLDE4KSxNXj1qKFQrQ3wwLDcpLFBePWooTStUfDAsOSksQ149aihQK018MCwxMyksVF49aihDK1B8MCwxOCk7bGV0IEk9MDtRW0krK109WCxRW0krK109SyxRW0krK109cSxRW0krK109VCxRW0krK109RixRW0krK109TixRW0krK109TyxRW0krK109VX12YXIgYlo9VlEocFgse2NvdW50ZXJSaWdodDohMCxleHRlbmROb25jZUZuOmNYfSkseVo9SlEoe2Jsb2NrU2l6ZTo2NCxub25jZUxlbmd0aDoyNCx0YWdMZW5ndGg6MTZ9LCgkLFopPT57cmV0dXJue2VuY3J5cHQoSixRKXtRPW1aKEoubGVuZ3RoKzMyLFEsITEpO2xldCBYPVEuc3ViYXJyYXkoMCwzMiksWT1RLnN1YmFycmF5KDMyKTtRLnNldChKLDMyKSxPMChYKSxiWigkLFosUSxRKTtsZXQgVj12WihZLFgpO3JldHVybiBRLnNldChWLDE2KSxPMChRLnN1YmFycmF5KDAsMTYpLFYpLFEuc3ViYXJyYXkoMTYpfSxkZWNyeXB0KEosUSl7ZChKKSxRPW1aKEoubGVuZ3RoKzMyLFEsITEpO2xldCBYPVEuc3ViYXJyYXkoMCwzMiksWT1RLnN1YmFycmF5KDMyLDQ4KSxWPVEuc3ViYXJyYXkoNDgpO1Euc2V0KEosMzIpLE8wKFgpO2xldCBXPWJaKCQsWixYLFgpLHo9dlooVixXKTtpZighWlEoWSx6KSl0aHJvdyBFcnJvcigiaW52YWxpZCB0YWciKTtyZXR1cm4gYlooJCxaLFEuc3ViYXJyYXkoMTYpLFEuc3ViYXJyYXkoMTYpKSxPMChYLFkseiksVn19fSk7LyohIG5vYmxlLWhhc2hlcyAtIE1JVCBMaWNlbnNlIChjKSAyMDIyIFBhdWwgTWlsbGVyIChwYXVsbWlsbHIuY29tKSAqL2Z1bmN0aW9uIG5YKCQpe3JldHVybiAkIGluc3RhbmNlb2YgVWludDhBcnJheXx8QXJyYXlCdWZmZXIuaXNWaWV3KCQpJiYkLmNvbnN0cnVjdG9yLm5hbWU9PT0iVWludDhBcnJheSJ9ZnVuY3Rpb24gRiQoJCl7aWYoIU51bWJlci5pc1NhZmVJbnRlZ2VyKCQpfHwkPDApdGhyb3cgRXJyb3IoInBvc2l0aXZlIGludGVnZXIgZXhwZWN0ZWQsIGdvdCAiKyQpfWZ1bmN0aW9uIEIwKCQsLi4uWil7aWYoIW5YKCQpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIik7aWYoWi5sZW5ndGg+MCYmIVouaW5jbHVkZXMoJC5sZW5ndGgpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIG9mIGxlbmd0aCAiK1orIiwgZ290IGxlbmd0aD0iKyQubGVuZ3RoKX1mdW5jdGlvbiBOJCgkLFo9ITApe2lmKCQuZGVzdHJveWVkKXRocm93IEVycm9yKCJIYXNoIGluc3RhbmNlIGhhcyBiZWVuIGRlc3Ryb3llZCIpO2lmKFomJiQuZmluaXNoZWQpdGhyb3cgRXJyb3IoIkhhc2gjZGlnZXN0KCkgaGFzIGFscmVhZHkgYmVlbiBjYWxsZWQiKX1mdW5jdGlvbiBsJCgkLFope0IwKCQpO2xldCBKPVoub3V0cHV0TGVuO2lmKCQubGVuZ3RoPEopdGhyb3cgRXJyb3IoImRpZ2VzdEludG8oKSBleHBlY3RzIG91dHB1dCBidWZmZXIgb2YgbGVuZ3RoIGF0IGxlYXN0ICIrSil9ZnVuY3Rpb24gR1EoJCl7cmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpfWZ1bmN0aW9uIGUwKCQpe3JldHVybiBuZXcgVWludDMyQXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LE1hdGguZmxvb3IoJC5ieXRlTGVuZ3RoLzQpKX1mdW5jdGlvbiAkJCguLi4kKXtmb3IobGV0IFo9MDtaPCQubGVuZ3RoO1orKykkW1pdLmZpbGwoMCl9ZnVuY3Rpb24gUiQoJCxaKXtyZXR1cm4gJDw8MzItWnwkPj4+Wn12YXIgelE9KCgpPT5uZXcgVWludDhBcnJheShuZXcgVWludDMyQXJyYXkoWzI4NzQ1NDAyMF0pLmJ1ZmZlcilbMF09PT02OCkoKTtmdW5jdGlvbiBLUSgkKXtyZXR1cm4gJDw8MjQmNDI3ODE5MDA4MHwkPDw4JjE2NzExNjgwfCQ+Pj44JjY1MjgwfCQ+Pj4yNCYyNTV9dmFyIEZRPXpRPygkKT0+JDooJCk9PktRKCQpO2Z1bmN0aW9uIGRYKCQpe2ZvcihsZXQgWj0wO1o8JC5sZW5ndGg7WisrKSRbWl09S1EoJFtaXSk7cmV0dXJuICR9dmFyICQwPXpRPygkKT0+JDpkWDtmdW5jdGlvbiByWCgkKXtpZih0eXBlb2YgJCE9PSJzdHJpbmciKXRocm93IEVycm9yKCJzdHJpbmcgZXhwZWN0ZWQiKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkobmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpKX1mdW5jdGlvbiBaJCgkKXtpZih0eXBlb2YgJD09PSJzdHJpbmciKSQ9clgoJCk7cmV0dXJuIEIwKCQpLCR9Y2xhc3MgaFp7fWZ1bmN0aW9uIE5RKCQpe2xldCBaPShRLFgpPT4kKFgpLnVwZGF0ZShaJChRKSkuZGlnZXN0KCksSj0kKHt9KTtyZXR1cm4gWi5vdXRwdXRMZW49Si5vdXRwdXRMZW4sWi5ibG9ja0xlbj1KLmJsb2NrTGVuLFouY3JlYXRlPShRKT0+JChRKSxafXZhciBSUT1VaW50MzJBcnJheS5mcm9tKFsxNzc5MDMzNzAzLDMxNDQxMzQyNzcsMTAxMzkwNDI0MiwyNzczNDgwNzYyLDEzNTk4OTMxMTksMjYwMDgyMjkyNCw1Mjg3MzQ2MzUsMTU0MTQ1OTIyNV0pO3ZhciB1JD1CaWdJbnQoNDI5NDk2NzI5NSksT1E9QmlnSW50KDMyKTtmdW5jdGlvbiBpWigkLFo9ITEpe2lmKFopcmV0dXJue2g6TnVtYmVyKCQmdSQpLGw6TnVtYmVyKCQ+Pk9RJnUkKX07cmV0dXJue2g6TnVtYmVyKCQ+Pk9RJnUkKXwwLGw6TnVtYmVyKCQmdSQpfDB9fWZ1bmN0aW9uIE0wKCQsWixKLFEsWCl7cmV0dXJuICQ9JCtaK1h8MCxRPVIkKFFeJCwxNiksSj1KK1F8MCxaPVIkKFpeSiwxMikse2E6JCxiOlosYzpKLGQ6UX19ZnVuY3Rpb24gSTAoJCxaLEosUSxYKXtyZXR1cm4gJD0kK1orWHwwLFE9UiQoUV4kLDgpLEo9SitRfDAsWj1SJChaXkosNykse2E6JCxiOlosYzpKLGQ6UX19Y2xhc3MgbFogZXh0ZW5kcyBoWntjb25zdHJ1Y3RvcigkLFope3N1cGVyKCk7dGhpcy5maW5pc2hlZD0hMSx0aGlzLmRlc3Ryb3llZD0hMSx0aGlzLmxlbmd0aD0wLHRoaXMucG9zPTAsRiQoJCksRiQoWiksdGhpcy5ibG9ja0xlbj0kLHRoaXMub3V0cHV0TGVuPVosdGhpcy5idWZmZXI9bmV3IFVpbnQ4QXJyYXkoJCksdGhpcy5idWZmZXIzMj1lMCh0aGlzLmJ1ZmZlcil9dXBkYXRlKCQpe04kKHRoaXMpLCQ9WiQoJCksQjAoJCk7bGV0e2Jsb2NrTGVuOlosYnVmZmVyOkosYnVmZmVyMzI6UX09dGhpcyxYPSQubGVuZ3RoLFk9JC5ieXRlT2Zmc2V0LFY9JC5idWZmZXI7Zm9yKGxldCBXPTA7VzxYOyl7aWYodGhpcy5wb3M9PT1aKSQwKFEpLHRoaXMuY29tcHJlc3MoUSwwLCExKSwkMChRKSx0aGlzLnBvcz0wO2xldCB6PU1hdGgubWluKFotdGhpcy5wb3MsWC1XKSxLPVkrVztpZih6PT09WiYmIShLJTQpJiZXK3o8WCl7bGV0IEY9bmV3IFVpbnQzMkFycmF5KFYsSyxNYXRoLmZsb29yKChYLVcpLzQpKTskMChGKTtmb3IobGV0IE49MDtXK1o8WDtOKz1RLmxlbmd0aCxXKz1aKXRoaXMubGVuZ3RoKz1aLHRoaXMuY29tcHJlc3MoRixOLCExKTskMChGKTtjb250aW51ZX1KLnNldCgkLnN1YmFycmF5KFcsVyt6KSx0aGlzLnBvcyksdGhpcy5wb3MrPXosdGhpcy5sZW5ndGgrPXosVys9en1yZXR1cm4gdGhpc31kaWdlc3RJbnRvKCQpe04kKHRoaXMpLGwkKCQsdGhpcyk7bGV0e3BvczpaLGJ1ZmZlcjMyOkp9PXRoaXM7dGhpcy5maW5pc2hlZD0hMCwkJCh0aGlzLmJ1ZmZlci5zdWJhcnJheShaKSksJDAoSiksdGhpcy5jb21wcmVzcyhKLDAsITApLCQwKEopO2xldCBRPWUwKCQpO3RoaXMuZ2V0KCkuZm9yRWFjaCgoWCxZKT0+UVtZXT1GUShYKSl9ZGlnZXN0KCl7bGV0e2J1ZmZlcjokLG91dHB1dExlbjpafT10aGlzO3RoaXMuZGlnZXN0SW50bygkKTtsZXQgSj0kLnNsaWNlKDAsWik7cmV0dXJuIHRoaXMuZGVzdHJveSgpLEp9X2Nsb25lSW50bygkKXtsZXR7YnVmZmVyOlosbGVuZ3RoOkosZmluaXNoZWQ6USxkZXN0cm95ZWQ6WCxvdXRwdXRMZW46WSxwb3M6Vn09dGhpcztyZXR1cm4gJHx8KCQ9bmV3IHRoaXMuY29uc3RydWN0b3Ioe2RrTGVuOll9KSksJC5zZXQoLi4udGhpcy5nZXQoKSksJC5idWZmZXIuc2V0KFopLCQuZGVzdHJveWVkPVgsJC5maW5pc2hlZD1RLCQubGVuZ3RoPUosJC5wb3M9ViwkLm91dHB1dExlbj1ZLCR9Y2xvbmUoKXtyZXR1cm4gdGhpcy5fY2xvbmVJbnRvKCl9fWZ1bmN0aW9uIHVaKCQsWixKLFEsWCxZLFYsVyx6LEssRixOLE8sVSxxLEgsTSxQLEMsVCl7bGV0IEk9MDtmb3IobGV0IEE9MDtBPFE7QSsrKSh7YTpYLGI6eixjOk8sZDpNfT1NMChYLHosTyxNLEpbWiskW0krK11dKSkse2E6WCxiOnosYzpPLGQ6TX09STAoWCx6LE8sTSxKW1orJFtJKytdXSkse2E6WSxiOkssYzpVLGQ6UH09TTAoWSxLLFUsUCxKW1orJFtJKytdXSkse2E6WSxiOkssYzpVLGQ6UH09STAoWSxLLFUsUCxKW1orJFtJKytdXSkse2E6VixiOkYsYzpxLGQ6Q309TTAoVixGLHEsQyxKW1orJFtJKytdXSkse2E6VixiOkYsYzpxLGQ6Q309STAoVixGLHEsQyxKW1orJFtJKytdXSkse2E6VyxiOk4sYzpILGQ6VH09TTAoVyxOLEgsVCxKW1orJFtJKytdXSkse2E6VyxiOk4sYzpILGQ6VH09STAoVyxOLEgsVCxKW1orJFtJKytdXSkse2E6WCxiOkssYzpxLGQ6VH09TTAoWCxLLHEsVCxKW1orJFtJKytdXSkse2E6WCxiOkssYzpxLGQ6VH09STAoWCxLLHEsVCxKW1orJFtJKytdXSkse2E6WSxiOkYsYzpILGQ6TX09TTAoWSxGLEgsTSxKW1orJFtJKytdXSkse2E6WSxiOkYsYzpILGQ6TX09STAoWSxGLEgsTSxKW1orJFtJKytdXSkse2E6VixiOk4sYzpPLGQ6UH09TTAoVixOLE8sUCxKW1orJFtJKytdXSkse2E6VixiOk4sYzpPLGQ6UH09STAoVixOLE8sUCxKW1orJFtJKytdXSkse2E6VyxiOnosYzpVLGQ6Q309TTAoVyx6LFUsQyxKW1orJFtJKytdXSkse2E6VyxiOnosYzpVLGQ6Q309STAoVyx6LFUsQyxKW1orJFtJKytdXSk7cmV0dXJue3YwOlgsdjE6WSx2MjpWLHYzOlcsdjQ6eix2NTpLLHY2OkYsdjc6Tix2ODpPLHY5OlUsdjEwOnEsdjExOkgsdjEyOk0sdjEzOlAsdjE0OkMsdjE1OlR9fXZhciBVMD17Q0hVTktfU1RBUlQ6MSxDSFVOS19FTkQ6MixQQVJFTlQ6NCxST09UOjgsS0VZRURfSEFTSDoxNixERVJJVkVfS0VZX0NPTlRFWFQ6MzIsREVSSVZFX0tFWV9NQVRFUklBTDo2NH0sQzA9UlEuc2xpY2UoKSxVUT0oKCk9PntsZXQgJD1BcnJheS5mcm9tKHtsZW5ndGg6MTZ9LChRLFgpPT5YKSxaPShRKT0+WzIsNiwzLDEwLDcsMCw0LDEzLDEsMTEsMTIsNSw5LDE0LDE1LDhdLm1hcCgoWCk9PlFbWF0pLEo9W107Zm9yKGxldCBRPTAsWD0kO1E8NztRKyssWD1aKFgpKUoucHVzaCguLi5YKTtyZXR1cm4gVWludDhBcnJheS5mcm9tKEopfSkoKTtjbGFzcyBwWiBleHRlbmRzIGxae2NvbnN0cnVjdG9yKCQ9e30sWj0wKXtzdXBlcig2NCwkLmRrTGVuPT09dm9pZCAwPzMyOiQuZGtMZW4pO3RoaXMuY2h1bmtQb3M9MCx0aGlzLmNodW5rc0RvbmU9MCx0aGlzLmZsYWdzPTAsdGhpcy5zdGFjaz1bXSx0aGlzLnBvc091dD0wLHRoaXMuYnVmZmVyT3V0MzI9bmV3IFVpbnQzMkFycmF5KDE2KSx0aGlzLmNodW5rT3V0PTAsdGhpcy5lbmFibGVYT0Y9ITA7bGV0e2tleTpKLGNvbnRleHQ6UX09JCxYPVEhPT12b2lkIDA7aWYoSiE9PXZvaWQgMCl7aWYoWCl0aHJvdyBFcnJvcignT25seSAia2V5IiBvciAiY29udGV4dCIgY2FuIGJlIHNwZWNpZmllZCBhdCBzYW1lIHRpbWUnKTtsZXQgWT1aJChKKS5zbGljZSgpO0IwKFksMzIpLHRoaXMuSVY9ZTAoWSksJDAodGhpcy5JViksdGhpcy5mbGFncz1afFUwLktFWUVEX0hBU0h9ZWxzZSBpZihYKXtsZXQgWT1aJChRKSxWPW5ldyBwWih7ZGtMZW46MzJ9LFUwLkRFUklWRV9LRVlfQ09OVEVYVCkudXBkYXRlKFkpLmRpZ2VzdCgpO3RoaXMuSVY9ZTAoViksJDAodGhpcy5JViksdGhpcy5mbGFncz1afFUwLkRFUklWRV9LRVlfTUFURVJJQUx9ZWxzZSB0aGlzLklWPUMwLnNsaWNlKCksdGhpcy5mbGFncz1aO3RoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpLHRoaXMuYnVmZmVyT3V0PUdRKHRoaXMuYnVmZmVyT3V0MzIpfWdldCgpe3JldHVybltdfXNldCgpe31iMkNvbXByZXNzKCQsWixKLFE9MCl7bGV0e3N0YXRlOlgscG9zOll9PXRoaXMse2g6VixsOld9PWlaKEJpZ0ludCgkKSwhMCkse3YwOnosdjE6Syx2MjpGLHYzOk4sdjQ6Tyx2NTpVLHY2OnEsdjc6SCx2ODpNLHY5OlAsdjEwOkMsdjExOlQsdjEyOkksdjEzOkEsdjE0OngsdjE1Omd9PXVaKFVRLFEsSiw3LFhbMF0sWFsxXSxYWzJdLFhbM10sWFs0XSxYWzVdLFhbNl0sWFs3XSxDMFswXSxDMFsxXSxDMFsyXSxDMFszXSxWLFcsWSxaKTtYWzBdPXpeTSxYWzFdPUteUCxYWzJdPUZeQyxYWzNdPU5eVCxYWzRdPU9eSSxYWzVdPVVeQSxYWzZdPXFeeCxYWzddPUheZ31jb21wcmVzcygkLFo9MCxKPSExKXtsZXQgUT10aGlzLmZsYWdzO2lmKCF0aGlzLmNodW5rUG9zKVF8PVUwLkNIVU5LX1NUQVJUO2lmKHRoaXMuY2h1bmtQb3M9PT0xNXx8SilRfD1VMC5DSFVOS19FTkQ7aWYoIUopdGhpcy5wb3M9dGhpcy5ibG9ja0xlbjtpZih0aGlzLmIyQ29tcHJlc3ModGhpcy5jaHVua3NEb25lLFEsJCxaKSx0aGlzLmNodW5rUG9zKz0xLHRoaXMuY2h1bmtQb3M9PT0xNnx8Sil7bGV0IFg9dGhpcy5zdGF0ZTt0aGlzLnN0YXRlPXRoaXMuSVYuc2xpY2UoKTtmb3IobGV0IFksVj10aGlzLmNodW5rc0RvbmUrMTtKfHwhKFYmMSk7Vj4+PTEpe2lmKCEoWT10aGlzLnN0YWNrLnBvcCgpKSlicmVhazt0aGlzLmJ1ZmZlcjMyLnNldChZLDApLHRoaXMuYnVmZmVyMzIuc2V0KFgsOCksdGhpcy5wb3M9dGhpcy5ibG9ja0xlbix0aGlzLmIyQ29tcHJlc3MoMCx0aGlzLmZsYWdzfFUwLlBBUkVOVCx0aGlzLmJ1ZmZlcjMyLDApLFg9dGhpcy5zdGF0ZSx0aGlzLnN0YXRlPXRoaXMuSVYuc2xpY2UoKX10aGlzLmNodW5rc0RvbmUrKyx0aGlzLmNodW5rUG9zPTAsdGhpcy5zdGFjay5wdXNoKFgpfXRoaXMucG9zPTB9X2Nsb25lSW50bygkKXskPXN1cGVyLl9jbG9uZUludG8oJCk7bGV0e0lWOlosZmxhZ3M6SixzdGF0ZTpRLGNodW5rUG9zOlgscG9zT3V0OlksY2h1bmtPdXQ6VixzdGFjazpXLGNodW5rc0RvbmU6en09dGhpcztyZXR1cm4gJC5zdGF0ZS5zZXQoUS5zbGljZSgpKSwkLnN0YWNrPVcubWFwKChLKT0+VWludDMyQXJyYXkuZnJvbShLKSksJC5JVi5zZXQoWiksJC5mbGFncz1KLCQuY2h1bmtQb3M9WCwkLmNodW5rc0RvbmU9eiwkLnBvc091dD1ZLCQuY2h1bmtPdXQ9ViwkLmVuYWJsZVhPRj10aGlzLmVuYWJsZVhPRiwkLmJ1ZmZlck91dDMyLnNldCh0aGlzLmJ1ZmZlck91dDMyKSwkfWRlc3Ryb3koKXt0aGlzLmRlc3Ryb3llZD0hMCwkJCh0aGlzLnN0YXRlLHRoaXMuYnVmZmVyMzIsdGhpcy5JVix0aGlzLmJ1ZmZlck91dDMyKSwkJCguLi50aGlzLnN0YWNrKX1iMkNvbXByZXNzT3V0KCl7bGV0e3N0YXRlOiQscG9zOlosZmxhZ3M6SixidWZmZXIzMjpRLGJ1ZmZlck91dDMyOlh9PXRoaXMse2g6WSxsOlZ9PWlaKEJpZ0ludCh0aGlzLmNodW5rT3V0KyspKTskMChRKTtsZXR7djA6Vyx2MTp6LHYyOkssdjM6Rix2NDpOLHY1Ok8sdjY6VSx2NzpxLHY4Okgsdjk6TSx2MTA6UCx2MTE6Qyx2MTI6VCx2MTM6SSx2MTQ6QSx2MTU6eH09dVooVVEsMCxRLDcsJFswXSwkWzFdLCRbMl0sJFszXSwkWzRdLCRbNV0sJFs2XSwkWzddLEMwWzBdLEMwWzFdLEMwWzJdLEMwWzNdLFYsWSxaLEopO1hbMF09V15ILFhbMV09el5NLFhbMl09S15QLFhbM109Rl5DLFhbNF09Tl5ULFhbNV09T15JLFhbNl09VV5BLFhbN109cV54LFhbOF09JFswXV5ILFhbOV09JFsxXV5NLFhbMTBdPSRbMl1eUCxYWzExXT0kWzNdXkMsWFsxMl09JFs0XV5ULFhbMTNdPSRbNV1eSSxYWzE0XT0kWzZdXkEsWFsxNV09JFs3XV54LCQwKFEpLCQwKFgpLHRoaXMucG9zT3V0PTB9ZmluaXNoKCl7aWYodGhpcy5maW5pc2hlZClyZXR1cm47dGhpcy5maW5pc2hlZD0hMCwkJCh0aGlzLmJ1ZmZlci5zdWJhcnJheSh0aGlzLnBvcykpO2xldCAkPXRoaXMuZmxhZ3N8VTAuUk9PVDtpZih0aGlzLnN0YWNrLmxlbmd0aCkkfD1VMC5QQVJFTlQsJDAodGhpcy5idWZmZXIzMiksdGhpcy5jb21wcmVzcyh0aGlzLmJ1ZmZlcjMyLDAsITApLCQwKHRoaXMuYnVmZmVyMzIpLHRoaXMuY2h1bmtzRG9uZT0wLHRoaXMucG9zPXRoaXMuYmxvY2tMZW47ZWxzZSAkfD0oIXRoaXMuY2h1bmtQb3M/VTAuQ0hVTktfU1RBUlQ6MCl8VTAuQ0hVTktfRU5EO3RoaXMuZmxhZ3M9JCx0aGlzLmIyQ29tcHJlc3NPdXQoKX13cml0ZUludG8oJCl7TiQodGhpcywhMSksQjAoJCksdGhpcy5maW5pc2goKTtsZXR7YmxvY2tMZW46WixidWZmZXJPdXQ6Sn09dGhpcztmb3IobGV0IFE9MCxYPSQubGVuZ3RoO1E8WDspe2lmKHRoaXMucG9zT3V0Pj1aKXRoaXMuYjJDb21wcmVzc091dCgpO2xldCBZPU1hdGgubWluKFotdGhpcy5wb3NPdXQsWC1RKTskLnNldChKLnN1YmFycmF5KHRoaXMucG9zT3V0LHRoaXMucG9zT3V0K1kpLFEpLHRoaXMucG9zT3V0Kz1ZLFErPVl9cmV0dXJuICR9eG9mSW50bygkKXtpZighdGhpcy5lbmFibGVYT0YpdGhyb3cgRXJyb3IoIlhPRiBpcyBub3QgcG9zc2libGUgYWZ0ZXIgZGlnZXN0IGNhbGwiKTtyZXR1cm4gdGhpcy53cml0ZUludG8oJCl9eG9mKCQpe3JldHVybiBGJCgkKSx0aGlzLnhvZkludG8obmV3IFVpbnQ4QXJyYXkoJCkpfWRpZ2VzdEludG8oJCl7aWYobCQoJCx0aGlzKSx0aGlzLmZpbmlzaGVkKXRocm93IEVycm9yKCJkaWdlc3QoKSB3YXMgYWxyZWFkeSBjYWxsZWQiKTtyZXR1cm4gdGhpcy5lbmFibGVYT0Y9ITEsdGhpcy53cml0ZUludG8oJCksdGhpcy5kZXN0cm95KCksJH1kaWdlc3QoKXtyZXR1cm4gdGhpcy5kaWdlc3RJbnRvKG5ldyBVaW50OEFycmF5KHRoaXMub3V0cHV0TGVuKSl9fXZhciBxUT1OUSgoJCk9Pm5ldyBwWigkKSk7dmFyIGNaPW5ldyBVaW50OEFycmF5KFs0OCw0NiwyLDEsMCw0OCw1LDYsMyw0MywxMDEsMTEyLDQsMzQsNCwzMl0pO2Z1bmN0aW9uIEhRKCQpe2xldCBaPW5ldyBVaW50OEFycmF5KGNaLmxlbmd0aCszMik7cmV0dXJuIFouc2V0KGNaKSxaLnNldCgkLnN1YmFycmF5KDAsMzIpLGNaLmxlbmd0aCksWn1mdW5jdGlvbiBNUSgkKXtyZXR1cm4gdHlwZW9mICQ9PT0ic3RyaW5nIj9uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCk6JH1mdW5jdGlvbiBKJCgkKXtsZXQgWj1uZXcgQXJyYXlCdWZmZXIoJC5ieXRlTGVuZ3RoKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWikuc2V0KCQpLFp9Y2xhc3Mgblp7dmVyaWZ5S2V5cz1uZXcgTWFwO2FzeW5jIGdlblJhbmRvbUJ5dGVzKCQpe3JldHVybiBoJCgkKX1hc3luYyBnZW4yNTZCaXRTZWN1cmVSYW5kb21TZWVkKCl7cmV0dXJuIGgkKDMyKX1hc3luYyBlbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKCQsWil7bGV0IEo9aCQoMjQpLFg9eVooWixKKS5lbmNyeXB0KCQpO3JldHVybiBuZXcgVWludDhBcnJheShbLi4uSiwuLi5YXSl9YXN5bmMgZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCgkLFope2xldCBKPSQuc2xpY2UoMCwyNCksUT0kLnNsaWNlKDI0KTtyZXR1cm4geVooWixKKS5kZWNyeXB0KFEpfWFzeW5jIGRlcml2ZUVkMjU1MTlLZXlQYWlyKCQpe2xldCBaPSQsSj1IUShaKSxRPUokKEopLFg7dHJ5e2xldCBLPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInBrY3M4IixRLHtuYW1lOiJFZDI1NTE5In0sITAsWyJzaWduIl0pO1g9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgiandrIixLKX1maW5hbGx5e0ouZmlsbCgwKSxuZXcgVWludDhBcnJheShRKS5maWxsKDApfWlmKHR5cGVvZiBYLnghPT0ic3RyaW5nIil0aHJvdyBFcnJvcigiRWQyNTUxOSBKV0sgbWlzc2luZyB4Iik7bGV0IFk9WC54O1guZD12b2lkIDA7bGV0IFY9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgiandrIix7a3R5OiJPS1AiLGNydjoiRWQyNTUxOSIseDpZfSx7bmFtZToiRWQyNTUxOSJ9LCEwLFsidmVyaWZ5Il0pLFc9bmV3IFVpbnQ4QXJyYXkoYXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgicmF3IixWKSk7dGhpcy52ZXJpZnlLZXlzLnNldChOMChXKSxWKTtsZXQgej1uZXcgVWludDhBcnJheSg2NCk7cmV0dXJuIHouc2V0KFosMCksei5zZXQoVywzMikse2tleVR5cGU6ImVkMjU1MTkiLHByaXZhdGVLZXk6eixwdWJsaWNLZXk6V319YXN5bmMgaW1wb3J0U2lnbktleSgkKXtsZXQgWj0kLnN1YmFycmF5KDAsMzIpLEo9SFEoWiksUT1KJChKKTt0cnl7cmV0dXJuIGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInBrY3M4IixRLHtuYW1lOiJFZDI1NTE5In0sITEsWyJzaWduIl0pfWZpbmFsbHl7Si5maWxsKDApLG5ldyBVaW50OEFycmF5KFEpLmZpbGwoMCl9fWFzeW5jIGltcG9ydFZlcmlmeUtleSgkKXtsZXQgWj1OMCgkKSxKPXRoaXMudmVyaWZ5S2V5cy5nZXQoWik7aWYoSilyZXR1cm4gSjtsZXQgUT1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJyYXciLEokKCQpLHtuYW1lOiJFZDI1NTE5In0sITEsWyJ2ZXJpZnkiXSk7cmV0dXJuIHRoaXMudmVyaWZ5S2V5cy5zZXQoWixRKSxRfWFzeW5jIHNpZ25FZDI1NTE5KCQsWil7bGV0IEo9TVEoJCksUT1hd2FpdCB0aGlzLmltcG9ydFNpZ25LZXkoWiksWD1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuc2lnbih7bmFtZToiRWQyNTUxOSJ9LFEsSiQoSikpO3JldHVybiBuZXcgVWludDhBcnJheShYKX1hc3luYyBjaGVja1NpZ0VkMjU1MTkoJCxaLEope2xldCBRPU1RKFopO3RyeXtsZXQgWD1hd2FpdCB0aGlzLmltcG9ydFZlcmlmeUtleShKKTtyZXR1cm4gYXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLnZlcmlmeSh7bmFtZToiRWQyNTUxOSJ9LFgsSiQoJCksSiQoUSkpfWNhdGNoe3JldHVybiExfX1hc3luYyBibGFrZTMoJCl7cmV0dXJuIHFRKCQpfX12YXIgb1g9bmV3IG5aLE8kPW9YO3ZhciBrMD17ZW5jb2RlKCQsWil7bGV0IEo9JC53cml0ZVZhclN0cmluZyhaLmhhbmRsZSk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZVZhclN0cmluZyhaLmxhYmVsKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gJC53cml0ZVZhckludChaLmlkeD8/MCl9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxYXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbWSxWXT0kLnJlYWRWYXJJbnQoKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gUih7aGFuZGxlOlosbGFiZWw6USxpZHg6WX0pfX07dmFyIHAkPTEsZFo9e2VuY29kZSgkLFope2lmKFoudiE9PXAkKXJldHVybiAxMDtsZXRbLEpdPWUoWi5tYXN0ZXJTZWVkKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFySW50KFoudik7aWYoUSE9PTApcmV0dXJuIFE7JC53cml0ZUJ5dGVzKFoubWFzdGVyU2VlZCk7bGV0IFg9JC53cml0ZVZhckludChaLmhvc3RzLmxlbmd0aCk7aWYoWCE9PTApcmV0dXJuIFg7Zm9yKGxldCBZIG9mIFouaG9zdHMpe2xldCBWPSQud3JpdGVTdHJ1Y3QoazAsWSk7aWYoViE9PTApcmV0dXJuIFZ9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaIT09cCQpcmV0dXJuIEcoMTQpO2xldFtRLFhdPSQucmVhZEJ5dGVzKFIwKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbWSxWXT1lKFEpO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFk9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldFtXLHpdPSQucmVhZFZhckludCgpO2lmKHohPT0wKXJldHVybiBHKHopO2lmKFc9PT12b2lkIDB8fFc8MClyZXR1cm4gRygxMCk7bGV0IEs9W107Zm9yKGxldCBGPTA7RjxXO0YrKyl7bGV0W04sT109JC5yZWFkU3RydWN0KGswKTtpZihPIT09MClyZXR1cm4gRyhPKTtpZihOPT09dm9pZCAwKXJldHVybiBHKDE0KTtLLnB1c2goTil9cmV0dXJuIFIoe3Y6cCQsbWFzdGVyU2VlZDpZLGhvc3RzOkt9KX19O2Z1bmN0aW9uIElRKCQsWil7bGV0W0osUV09ZSgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDEwKTtsZXRbWCxZXT1lKEouc2xpY2UoKSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoWD09PXZvaWQgMClyZXR1cm4gRygxMCk7cmV0dXJuIFIoe3Y6cCQsbWFzdGVyU2VlZDpYLGhvc3RzOloubWFwKChWKT0+KHtoYW5kbGU6Vi5oYW5kbGUsbGFiZWw6Vi5sYWJlbCxpZHg6Vi5pZHg/PzB9KSl9KX12YXIgclo9e2VuY29kZSgkLFope2xldFssSl09ZShaLm1hc3RlclNlZWQpO2lmKEohPT0wKXJldHVybiBKOyQud3JpdGVCeXRlcyhaLm1hc3RlclNlZWQpO2xldCBRPSQud3JpdGVWYXJJbnQoWi5ob3N0cy5sZW5ndGgpO2lmKFEhPT0wKXJldHVybiBRO2ZvcihsZXQgWCBvZiBaLmhvc3RzKXtsZXQgWT0kLndyaXRlU3RydWN0KGswLFgpO2lmKFkhPT0wKXJldHVybiBZfXJldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkQnl0ZXMoUjApO2lmKEohPT0wKXJldHVybiBHKEopO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldFtRLFhdPWUoWik7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1ksVl09JC5yZWFkVmFySW50KCk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMHx8WTwwKXJldHVybiBHKDEwKTtsZXQgVz1bXTtmb3IobGV0IHo9MDt6PFk7eisrKXtsZXRbSyxGXT0kLnJlYWRTdHJ1Y3QoazApO2lmKEYhPT0wKXJldHVybiBHKEYpO2lmKEs9PT12b2lkIDApcmV0dXJuIEcoMTQpO1cucHVzaChLKX1yZXR1cm4gUih7bWFzdGVyU2VlZDpRLGhvc3RzOld9KX19O2Z1bmN0aW9uIFAwKCQpe2xldCBaPW5ldyBVaW50OEFycmF5KCQpO2lmKCQ+MCljcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKFopO3JldHVybiBafXZhciBFMD0zMixhWD0tNyxzWD0tOCx0WD0tMjU3LGMkPVt7dHlwZToicHVibGljLWtleSIsYWxnOmFYfSx7dHlwZToicHVibGljLWtleSIsYWxnOnNYfSx7dHlwZToicHVibGljLWtleSIsYWxnOnRYfV07ZnVuY3Rpb24gZVgoJCl7cmV0dXJuICQudHJpbSgpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXC4kLywiIil8fCJsb2NhbGhvc3QifWZ1bmN0aW9uIGYwKCQpe2xldCBaPW5ldyBVaW50OEFycmF5KCQuYnl0ZUxlbmd0aCk7cmV0dXJuIFouc2V0KCQpLFouYnVmZmVyfWZ1bmN0aW9uIENRKCQpe2lmKCQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcilyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJCkuc2xpY2UoKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LCQuYnl0ZUxlbmd0aCkuc2xpY2UoKX1mdW5jdGlvbiBnMCgkKXtpZigkPy5ycElkIT09dm9pZCAwKXJldHVybiBSKCQucnBJZCk7aWYodHlwZW9mIGxvY2F0aW9uPiJ1IilyZXR1cm4gRyg5KTtyZXR1cm4gUihlWChsb2NhdGlvbi5ob3N0bmFtZSkpfWZ1bmN0aW9uIG0wKCl7aWYodHlwZW9mIG5hdmlnYXRvcj4idSJ8fCFuYXZpZ2F0b3IuY3JlZGVudGlhbHN8fHR5cGVvZiBQdWJsaWNLZXlDcmVkZW50aWFsPiJ1IilyZXR1cm4gMjQ7cmV0dXJuIDB9ZnVuY3Rpb24gUzAoJCl7aWYoJD09PW51bGx8fCQudHlwZSE9PSJwdWJsaWMta2V5Inx8ISgicmF3SWQiaW4gJCl8fHR5cGVvZiAkLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMhPT0iZnVuY3Rpb24iKXJldHVybiBHKDI3KTtyZXR1cm4gUigkKX1hc3luYyBmdW5jdGlvbiBQUSgkKXtsZXQgWj1tMCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtKLFFdPWcwKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoOSk7bGV0IFg9JD8udXNlck5hbWU/PyJkaXBsb21hdGljLXNlZWQiLFk9e3Jlc2lkZW50S2V5OiJyZXF1aXJlZCIscmVxdWlyZVJlc2lkZW50S2V5OiEwLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIn07aWYoJD8uYXV0aGVudGljYXRvckF0dGFjaG1lbnQhPT12b2lkIDApWS5hdXRoZW50aWNhdG9yQXR0YWNobWVudD0kLmF1dGhlbnRpY2F0b3JBdHRhY2htZW50O2xldCBWPXtsYXJnZUJsb2I6e3N1cHBvcnQ6InJlcXVpcmVkIn19LFc7dHJ5e1c9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmNyZWF0ZSh7cHVibGljS2V5OntjaGFsbGVuZ2U6UDAoRTApLHJwOntpZDpKLG5hbWU6JD8ucnBOYW1lPz8iRElQTE9NQVRJQyJ9LHVzZXI6e2lkOlAwKDE2KSxuYW1lOlgsZGlzcGxheU5hbWU6WH0scHViS2V5Q3JlZFBhcmFtczpjJCxhdXRoZW50aWNhdG9yU2VsZWN0aW9uOlksZXh0ZW5zaW9uczpWfX0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbeixLXT1TMChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtpZih6LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5sYXJnZUJsb2I/LnN1cHBvcnRlZCE9PSEwKXJldHVybiBHKDI0KTtyZXR1cm4gUihuZXcgVWludDhBcnJheSh6LnJhd0lkKSl9YXN5bmMgZnVuY3Rpb24gb1ooJCxaLEope2xldCBRPW0wKCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0W1gsWV09ZzAoSik7aWYoWSE9PTApcmV0dXJuIFk7aWYoWD09PXZvaWQgMClyZXR1cm4gOTtsZXQgVj17bGFyZ2VCbG9iOnt3cml0ZTpmMChaKX19LFc7dHJ5e1c9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmdldCh7cHVibGljS2V5OntjaGFsbGVuZ2U6UDAoRTApLHJwSWQ6WCxhbGxvd0NyZWRlbnRpYWxzOlt7dHlwZToicHVibGljLWtleSIsaWQ6ZjAoJCl9XSx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCIsZXh0ZW5zaW9uczpWfX0pfWNhdGNoe3JldHVybiAyNH1sZXRbeixLXT1TMChXKTtpZihLIT09MClyZXR1cm4gSztpZih6PT09dm9pZCAwKXJldHVybiAyNztpZih6LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5sYXJnZUJsb2I/LndyaXR0ZW4hPT0hMClyZXR1cm4gMjQ7cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gd1EoJCxaKXtsZXQgSj1tMCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPWcwKFopO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoOSk7bGV0IFk9e2xhcmdlQmxvYjp7cmVhZDohMH19LFY7dHJ5e2xldCBPPXtjaGFsbGVuZ2U6UDAoRTApLHJwSWQ6USx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCIsZXh0ZW5zaW9uczpZfTtpZigkIT09dm9pZCAwKU8uYWxsb3dDcmVkZW50aWFscz1be3R5cGU6InB1YmxpYy1rZXkiLGlkOmYwKCQpfV07Vj1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6T30pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbVyx6XT1TMChWKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgRj1XLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5sYXJnZUJsb2I7aWYoRj09PXZvaWQgMHx8Ri5ibG9iPT09dm9pZCAwKXJldHVybiBHKDcpO2xldCBOPUNRKEYuYmxvYik7aWYoTi5ieXRlTGVuZ3RoPT09MClyZXR1cm4gRyg3KTtyZXR1cm4gUih7YmxvYjpOLGNyZWRJZDpuZXcgVWludDhBcnJheShXLnJhd0lkKX0pfXZhciBuJD1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMucHJmLnYxIiksYVo9MzI7YXN5bmMgZnVuY3Rpb24gVFEoJCl7bGV0IFo9bTAoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbSixRXT1nMCgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDkpO2xldCBYPSQ/LnVzZXJOYW1lPz8iZGlwbG9tYXRpYy1wcmYiLFk9e3Jlc2lkZW50S2V5OiJyZXF1aXJlZCIscmVxdWlyZVJlc2lkZW50S2V5OiEwLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixhdXRoZW50aWNhdG9yQXR0YWNobWVudDokPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudD8/InBsYXRmb3JtIn0sVjt0cnl7Vj1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpQMChFMCkscnA6e2lkOkosbmFtZTokPy5ycE5hbWU/PyJESVBMT01BVElDIn0sdXNlcjp7aWQ6UDAoMTYpLG5hbWU6WCxkaXNwbGF5TmFtZTpYfSxwdWJLZXlDcmVkUGFyYW1zOmMkLGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246WSxleHRlbnNpb25zOntwcmY6e319fX0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbVyx6XT1TMChWKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgSz1XLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKTtyZXR1cm4gUih7Y3JlZElkOm5ldyBVaW50OEFycmF5KFcucmF3SWQpLHByZkVuYWJsZWQ6Sy5wcmY/LmVuYWJsZWQ9PT0hMH0pfWFzeW5jIGZ1bmN0aW9uIFUkKCQpe2xldCBaPW0wKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W0osUV09ZzAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgWD0kPy5zYWx0Pz9uJCxZPWYwKFgpLFY9e2NoYWxsZW5nZTpQMChFMCkscnBJZDpKLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixleHRlbnNpb25zOntwcmY6e2V2YWw6e2ZpcnN0Oll9fX19O2lmKCQ/LmNyZWRJZCE9PXZvaWQgMClWLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOiJwdWJsaWMta2V5IixpZDpmMCgkLmNyZWRJZCl9XTtsZXQgVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6Vn0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbeixLXT1TMChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgRj16LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5wcmY/LnJlc3VsdHM7aWYoRj8uZmlyc3Q9PT12b2lkIDApcmV0dXJuIEcoNyk7bGV0IE49Ri5maXJzdCxPPU4gaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcj9uZXcgVWludDhBcnJheShOKTpuZXcgVWludDhBcnJheShOLmJ1ZmZlcixOLmJ5dGVPZmZzZXQsTi5ieXRlTGVuZ3RoKSxVPU8uYnl0ZUxlbmd0aD49YVo/Ty5zbGljZSgwLGFaKTpPO2lmKFUuYnl0ZUxlbmd0aCE9PWFaKXJldHVybiBHKDI3KTtyZXR1cm4gUih7cHJmOlUsY3JlZElkOm5ldyBVaW50OEFycmF5KHoucmF3SWQpfSl9dmFyIGQkPSIiO3ZhciBvJD10eXBlb2YgZ2xvYmFsVGhpcy5Xb3JrZXI9PT0iZnVuY3Rpb24iP2dsb2JhbFRoaXMuV29ya2VyOnZvaWQgMCxzWj1vJD09PXZvaWQgMD92b2lkIDA6byQucHJvdG90eXBlLnBvc3RNZXNzYWdlLHIkO2Z1bmN0aW9uIFpZKCl7aWYodHlwZW9mIGQkIT09InN0cmluZyJ8fGQkLmxlbmd0aD09PTApdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSB3b3JrZXIgc291cmNlIG5vdCBlbWJlZGRlZDsgcnVuIHBrZyBidWlsZCBiZWZvcmUgc3Bhd24iKTtyZXR1cm4gYXRvYihkJCl9ZnVuY3Rpb24gSlkoKXtpZihyJCE9PXZvaWQgMClyZXR1cm4gciQ7bGV0ICQ9bmV3IEJsb2IoW1pZKCldLHt0eXBlOiJ0ZXh0L2phdmFzY3JpcHQifSk7cmV0dXJuIHIkPVVSTC5jcmVhdGVPYmplY3RVUkwoJCksciR9ZnVuY3Rpb24galEoKXtpZihvJD09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBzcGF3biBzeW5jIHdvcmtlciIpO3JldHVybiBuZXcgbyQoSlkoKSx7dHlwZToibW9kdWxlIn0pfWZ1bmN0aW9uIERRKCQsWixKKXtpZihzWj09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBwb3N0IHRvIHN5bmMgd29ya2VyIik7aWYoSiE9PXZvaWQgMCYmSi5sZW5ndGg+MClzWi5jYWxsKCQsWix7dHJhbnNmZXI6Sn0pO2Vsc2Ugc1ouY2FsbCgkLFopfXZhciBRWT1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMud3JhcC52MSIpLEFRPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgiZGlwbG9tYXRpYy5wYWlyLnYxIiksWFk9MzIsWVk9MTY7Y2xhc3MgVzB7I1o7IyQ7Y29uc3RydWN0b3IoJCxaKXt0aGlzLiNaPSQsdGhpcy4jJD1afXN0YXRpYyBhc3luYyBmcm9tUmFuZG9tKCQpe2xldCBaPWF3YWl0ICQuZ2VuMjU2Qml0U2VjdXJlUmFuZG9tU2VlZCgpLFtKLFFdPWUoWik7aWYoUSE9PTB8fEo9PT12b2lkIDApdGhyb3cgRXJyb3IoYGVuY2xhdmU6IGludmFsaWQgcmFuZG9tIHNlZWQgKCR7UX0pYCk7cmV0dXJuIG5ldyBXMChKLCQpfXN0YXRpYyBmcm9tQnl0ZXMoJCxaKXtsZXRbSixRXT1lKFopO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtYLFldPWUoSi5zbGljZSgpKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihYPT09dm9pZCAwKXJldHVybiBHKDEwKTtyZXR1cm4gUihuZXcgVzAoWCwkKSl9YXN5bmMgc2VhbFdpdGhQYXNza2V5KCQpe2xldCBaPSQ/LnNhbHQ/P24kLEo9JD8uY3JlZElkO2lmKEo9PT12b2lkIDAmJiQ/LmNyZWF0ZUNyZWRJZk5lZWRlZD09PSEwKXtsZXRbWSxWXT1hd2FpdCBUUSh7cnBJZDokPy5ycElkLHJwTmFtZTokPy5ycE5hbWUsdXNlck5hbWU6JD8udXNlck5hbWU/PyJkaXBsb21hdGljLXByZiJ9KTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDI0KTtpZighWS5wcmZFbmFibGVkKXJldHVybiBHKDI0KTtKPVkuY3JlZElkfWxldFtRLFhdPWF3YWl0IFUkKHtycElkOiQ/LnJwSWQscnBOYW1lOiQ/LnJwTmFtZSxjcmVkSWQ6SixzYWx0Olp9KTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbWSxWXT1hd2FpdCB0aGlzLiNKKFEucHJmKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gUih7c2VhbGVkTWFzdGVyOlksc2FsdDpaLnNsaWNlKCksY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXN0YXRpYyBhc3luYyB1bnNlYWxXaXRoUGFzc2tleSgkLFosSil7bGV0W1EsWF09YXdhaXQgVSQoe3JwSWQ6Si5ycElkLHJwTmFtZTpKLnJwTmFtZSxjcmVkSWQ6Si5jcmVkSWQsc2FsdDpKLnNhbHR9KTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbWSxWXT1hd2FpdCBXMC4jWCgkLFosUS5wcmYpO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFk9PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBSKHtlbmNsYXZlOlksY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fWFzeW5jIHBlcnNpc3RUb0xhcmdlQmxvYigkPVtdLFope2xldCBKPVo/LmNyZWRJZDtpZihKPT09dm9pZCAwKXtsZXRbWSxWXT1hd2FpdCBQUShaKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDI0KTtKPVl9bGV0W1EsWF09dGhpcy4jUSgkKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFk9YXdhaXQgb1ooSixRLFopO2lmKFkhPT0wKXJldHVybiBHKFkpO3JldHVybiBSKEopfWZpbmFsbHl7US5maWxsKDApfX1zdGF0aWMgYXN5bmMgZnJvbUxhcmdlQmxvYigkLFope2xldFtKLFFdPWF3YWl0IHdRKFo/LmNyZWRJZCxaKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtyZXR1cm4gVzAuI1koJCxKLmJsb2IsSi5jcmVkSWQpfWZpbmFsbHl7Si5ibG9iLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBjbGVhckxhcmdlQmxvYigkLFope3JldHVybiBvWigkLG5ldyBVaW50OEFycmF5KFIwKSxaKX1hc3luYyBzZWFsUGFpclBhY2thZ2VCb2R5KCQsWil7bGV0IEo9Wj8uc2FsdD8/biQsW1EsWF09YXdhaXQgVSQoe3JwSWQ6Wj8ucnBJZCxycE5hbWU6Wj8ucnBOYW1lLGNyZWRJZDpaPy5jcmVkSWQsc2FsdDpKfSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoUT09PXZvaWQgMClyZXR1cm4gRyg3KTt0cnl7bGV0W1ksVl09YXdhaXQgYSQodGhpcy4jJCxRLnByZixBUSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldFtXLHpdPWUodGhpcy4jWi5zbGljZSgpKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwKXJldHVybiBHKDEwKTtsZXQgSz17bWFzdGVyU2VlZDpXLGhvc3RzOiQubWFwKChxKT0+KHtoYW5kbGU6cS5oYW5kbGUsbGFiZWw6cS5sYWJlbCxpZHg6cS5pZHg/PzB9KSl9LEY9bmV3IFMsTj1GLndyaXRlU3RydWN0KHJaLEspO2lmKE4hPT0wKXJldHVybiBXLmZpbGwoMCksRyhOKTtsZXQgTz1GLnJlc3VsdCgpO1cuZmlsbCgwKTtsZXQgVTt0cnl7VT1hd2FpdCB0aGlzLiMkLmVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoTyxZKX1jYXRjaHtyZXR1cm4gTy5maWxsKDApLEcoMTIpfXJldHVybiBPLmZpbGwoMCksUih7Ym9keTpVLHNhbHQ6Si5zbGljZSgpLGNyZWRJZDpRLmNyZWRJZC5zbGljZSgpfSl9ZmluYWxseXtZLmZpbGwoMCl9fWZpbmFsbHl7US5wcmYuZmlsbCgwKX19c3RhdGljIGFzeW5jIG9wZW5QYWlyUGFja2FnZUJvZHkoJCxaLEope2xldFtRLFhdPWF3YWl0IFUkKHtycElkOkoucnBJZCxycE5hbWU6Si5ycE5hbWUsY3JlZElkOkouY3JlZElkLHNhbHQ6Si5zYWx0fSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoUT09PXZvaWQgMClyZXR1cm4gRyg3KTt0cnl7bGV0W1ksVl09YXdhaXQgYSQoJCxRLnByZixBUSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBXO3RyeXtXPWF3YWl0ICQuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChaLFkpfWNhdGNoe3JldHVybiBHKDIwKX1sZXQgej1uZXcgbShXKSxbSyxGXT16LnJlYWRTdHJ1Y3QoclopO2lmKFcuZmlsbCgwKSxGIT09MClyZXR1cm4gRyhGKTtpZihLPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbTixPXT1XMC5mcm9tQnl0ZXMoJCxLLm1hc3RlclNlZWQpO2lmKEsubWFzdGVyU2VlZC5maWxsKDApLE8hPT0wKXJldHVybiBHKE8pO2lmKE49PT12b2lkIDApcmV0dXJuIEcoMTIpO2xldFtVLHFdPWF3YWl0IE4uI0ooUS5wcmYpO2lmKHEhPT0wKXJldHVybiBHKHEpO2lmKFU9PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBSKHtlbmNsYXZlOk4saG9zdHM6Sy5ob3N0cy5tYXAoKEgpPT4oey4uLkh9KSksc2VhbGVkTWFzdGVyOlUsY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1kuZmlsbCgwKX19ZmluYWxseXtRLnByZi5maWxsKDApfX1zcGF3blN5bmNXb3JrZXIoJCl7bGV0IFo9alEoKSxKPXRoaXMuI1ouc2xpY2UoKTtyZXR1cm4gRFEoWix7aWQ6JC5pZCxvcDoic2V0U2VlZCIsc2VlZDpKLHBlcnNpc3Q6JC5wZXJzaXN0fSxbSi5idWZmZXJdKSxafWRlcml2ZUNpcGhlcigkLFope2xldCBKPSQuc2xpY2UoKSxRPShWKT0+dGhpcy4jRyhKLFYpLFg9KFYpPT50aGlzLiN6KEosVik7cmV0dXJue2VuY3J5cHQ6T2JqZWN0LmZyZWV6ZSh7ZW5jcnlwdDpRfSksZGVjcnlwdDpPYmplY3QuZnJlZXplKHtkZWNyeXB0Olh9KSxib3RoOk9iamVjdC5mcmVlemUoe2VuY3J5cHQ6USxkZWNyeXB0Olh9KX1bWl19YXN5bmMgZGVyaXZlSWRlbnRpdHkoJCxaPTApe2xldCBKPSQsUT1aLFg9YXdhaXQgdGhpcy4jVyhKLFEpLFk9WC5wdWJsaWNLZXk7cmV0dXJuIFgucHJpdmF0ZUtleS5maWxsKDApLE9iamVjdC5mcmVlemUoe3B1YmxpY0tleTpZLHNpZ246KFYpPT50aGlzLiNGKEosUSxWKSxrZG1Gb3I6KFYpPT50aGlzLiNOKEosUSxWKX0pfWFzeW5jI0ooJCl7bGV0W1osSl09YXdhaXQgYSQodGhpcy4jJCwkKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFE9YXdhaXQgdGhpcy4jJC5lbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKHRoaXMuI1osWik7cmV0dXJuIEQwKFEpfWNhdGNoe3JldHVybiBHKDEyKX1maW5hbGx5e1ouZmlsbCgwKX19c3RhdGljIGFzeW5jI1goJCxaLEope2xldFssUV09RDAoWik7aWYoUSE9PTApcmV0dXJuIEcoUSk7bGV0W1gsWV09YXdhaXQgYSQoJCxKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihYPT09dm9pZCAwKXJldHVybiBHKDEyKTtsZXQgVjt0cnl7dHJ5e1Y9YXdhaXQgJC5kZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKFosWCl9Y2F0Y2h7cmV0dXJuIEcoMjApfXJldHVybiBXMC5mcm9tQnl0ZXMoJCxWKX1maW5hbGx5e1guZmlsbCgwKSxWPy5maWxsKDApfX0jUSgkKXtsZXRbWixKXT1lKHRoaXMuI1ouc2xpY2UoKSk7aWYoSiE9PTApcmV0dXJuIEcoSik7aWYoWj09PXZvaWQgMClyZXR1cm4gRygxMCk7bGV0W1EsWF09SVEoWiwkKTtpZihaLmZpbGwoMCksWCE9PTApcmV0dXJuIEcoWCk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBZPW5ldyBTLFY9WS53cml0ZVN0cnVjdChkWixRKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gUihZLnJlc3VsdCgpKX1maW5hbGx5e1EubWFzdGVyU2VlZC5maWxsKDApfX1zdGF0aWMjWSgkLFosSil7aWYoWi5ieXRlTGVuZ3RoPT09MHx8Wi5ldmVyeSgoVik9PlY9PT0wKSlyZXR1cm4gRygyMik7aWYoWi5ieXRlTGVuZ3RoPT09UjApe2lmKFouZXZlcnkoKHopPT56PT09MCkpcmV0dXJuIEcoMjIpO2xldFtWLFddPVcwLmZyb21CeXRlcygkLFopO2lmKFchPT0wKXJldHVybiBHKFcpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBSKHtlbmNsYXZlOlYsaG9zdHM6W10sY3JlZElkOkp9KX1sZXQgUT1uZXcgbShaKSxbWCxZXT1RLnJlYWRTdHJ1Y3QoZFopO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFg9PT12b2lkIDApcmV0dXJuIEcoMTQpO3RyeXtpZihYLm1hc3RlclNlZWQuZXZlcnkoKHopPT56PT09MCkpcmV0dXJuIEcoMjIpO2xldFtWLFddPVcwLmZyb21CeXRlcygkLFgubWFzdGVyU2VlZCk7aWYoVyE9PTApcmV0dXJuIEcoVyk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIFIoe2VuY2xhdmU6Vixob3N0czpYLmhvc3RzLm1hcCgoeik9Pih7Li4uen0pKSxjcmVkSWQ6Sn0pfWZpbmFsbHl7WC5tYXN0ZXJTZWVkLmZpbGwoMCl9fWFzeW5jI0coJCxaKXtsZXQgSj1hd2FpdCB0aGlzLiNWKCQpO3RyeXtyZXR1cm4gYXdhaXQgdGhpcy4jJC5lbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKFosSil9ZmluYWxseXtKLmZpbGwoMCl9fWFzeW5jI3ooJCxaKXtsZXQgSj1hd2FpdCB0aGlzLiNWKCQpO3RyeXtyZXR1cm4gYXdhaXQgdGhpcy4jJC5kZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKFosSil9ZmluYWxseXtKLmZpbGwoMCl9fWFzeW5jI1YoJCl7cmV0dXJuIHRoaXMuIyQuYmxha2UzKFckKHRoaXMuI1osJCkpfWFzeW5jI0soJCxaKXtsZXQgSj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCksUT1uZXcgVWludDhBcnJheSg4KTtyZXR1cm4gbmV3IERhdGFWaWV3KFEuYnVmZmVyKS5zZXRCaWdVaW50NjQoMCxCaWdJbnQoWiksITEpLGF3YWl0IHRoaXMuI1YoVyQoSixRKSl9YXN5bmMjVygkLFope2xldCBKPWF3YWl0IHRoaXMuI0soJCxaKTt0cnl7cmV0dXJuIGF3YWl0IHRoaXMuIyQuZGVyaXZlRWQyNTUxOUtleVBhaXIoSil9ZmluYWxseXtKLmZpbGwoMCl9fWFzeW5jI0YoJCxaLEope2xldCBRPWF3YWl0IHRoaXMuI1coJCxaKTt0cnl7cmV0dXJuIGF3YWl0IHRoaXMuIyQuc2lnbkVkMjU1MTkoSixRLnByaXZhdGVLZXkpfWZpbmFsbHl7US5wcml2YXRlS2V5LmZpbGwoMCl9fWFzeW5jI04oJCxaLEope2xldCBRPWF3YWl0IHRoaXMuI1coJCxaKSxYPVckKFEucHJpdmF0ZUtleSxKKTtRLnByaXZhdGVLZXkuZmlsbCgwKTt0cnl7cmV0dXJuKGF3YWl0IHRoaXMuIyQuYmxha2UzKFgpKS5zbGljZSgwLFQwKX1maW5hbGx5e1guZmlsbCgwKX19fWFzeW5jIGZ1bmN0aW9uIGEkKCQsWixKPVFZKXtpZihaLmJ5dGVMZW5ndGg8WVkpcmV0dXJuIEcoMTApO2xldCBRPWF3YWl0ICQuYmxha2UzKFckKFosSikpO3JldHVybiBSKFEuc2xpY2UoMCxYWSkpfWNsYXNzIHRae2RiO2NvbnN0cnVjdG9yKCQpe3RoaXMuZGI9JH1hc3luYyBlbnEoJCl7bGV0IFo9Wy4uLiRdO2lmKFoubGVuZ3RoPT09MClyZXR1cm47bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihHMCwicmVhZHdyaXRlIiksUT1KLm9iamVjdFN0b3JlKEcwKTtyZXR1cm4gbmV3IFByb21pc2UoKFgsWSk9PntKLm9uY29tcGxldGU9KCk9PlgoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvcik7Zm9yKGxldCBWIG9mIFope2xldCBXPWAke1YuaG9zdH06JHtWLnNlcX1gO1EucHV0KFYsVyl9fSl9YXN5bmMgZGVxKCQsWil7bGV0IEo9Wy4uLlpdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFE9dGhpcy5kYi50cmFuc2FjdGlvbihHMCwicmVhZHdyaXRlIiksWD1RLm9iamVjdFN0b3JlKEcwKTtyZXR1cm4gbmV3IFByb21pc2UoKFksVik9PntRLm9uY29tcGxldGU9KCk9PlkoKSxRLm9uZXJyb3I9KCk9PlYoUS5lcnJvcik7Zm9yKGxldCBXIG9mIEope2xldCB6PWAkeyR9OiR7V31gO1guZGVsZXRlKHopfX0pfWFzeW5jIGxpc3QoKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKEcwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKEcwKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PntsZXQgWD1aLmdldEFsbCgpO1gub25zdWNjZXNzPSgpPT5KKFgucmVzdWx0KSxYLm9uZXJyb3I9KCk9PlEoWC5lcnJvcil9KX1hc3luYyBjb3VudCgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oRzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoRzApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBYPVouY291bnQoKTtYLm9uc3VjY2Vzcz0oKT0+SihYLnJlc3VsdCksWC5vbmVycm9yPSgpPT5RKFguZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oRzAsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZShHMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5KKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLFouY2xlYXIoKX0pfX1mdW5jdGlvbiBfUSgkKXtyZXR1cm57bGFiZWw6JC5sYWJlbCxoYW5kbGU6bmV3IFVSTCgkLmhhbmRsZSksaWR4OiQuaWR4LGxhc3RTZXE6JC5sYXN0U2VxfHwwLGNsb2NrT2Zmc2V0OiQuY2xvY2tPZmZzZXQsc3Vic2NyaXB0aW9uOiQuc3Vic2NyaXB0aW9ufX1mdW5jdGlvbiBWWSgkLFope2xldCBKPXsuLi4kfTtpZihaLnNldExhc3RTZXEhPT12b2lkIDApSi5sYXN0U2VxPVouc2V0TGFzdFNlcTtlbHNlIGlmKFoubGFzdFNlcSE9PXZvaWQgMCl7bGV0IFE9Si5sYXN0U2VxfHwwO2lmKFoubGFzdFNlcT5RKUoubGFzdFNlcT1aLmxhc3RTZXF9cmV0dXJuIGRlbGV0ZSBKLm51bUJhZ3MsZGVsZXRlIEoubnVtRHVwZXMsSn1jbGFzcyBlWntkYjtjb25zdHJ1Y3RvcigkKXt0aGlzLmRiPSR9YXN5bmMgYWRkKCQpe2xldCBaPWF3YWl0IHRoaXMuZ2V0KCQubGFiZWwpLEo9WiE9PXZvaWQgMCYmWi5oYW5kbGUuaHJlZj09PSQuaGFuZGxlLmhyZWYmJihaLmlkeD8/MCk9PT0oJC5pZHg/PzApO3JldHVybiB0aGlzLnB1dCh7Li4uJCxsYXN0U2VxOko/Wi5sYXN0U2VxOjAsY2xvY2tPZmZzZXQ6Sj9aLmNsb2NrT2Zmc2V0OnZvaWQgMCxzdWJzY3JpcHRpb246Sj9aLnN1YnNjcmlwdGlvbjp2b2lkIDB9KX1hc3luYyBwdXQoJCl7bGV0IFo9ey4uLiQsaGFuZGxlOiQuaGFuZGxlLnRvU3RyaW5nKCksbGFzdFNlcTokLmxhc3RTZXE/PzB9LEo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZHdyaXRlIiksUT1KLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFgsWSk9PntKLm9uY29tcGxldGU9KCk9PlgoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvciksUS5wdXQoWil9KX1hc3luYyB0b3VjaCgkLFope3JldHVybiB0aGlzLnJlY29yZFN0YXRzKCQse2xhc3RTZXE6Wn0pfWFzeW5jIHJlY29yZFN0YXRzKCQsWil7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZHdyaXRlIiksUT1KLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFgsWSk9PntKLm9uY29tcGxldGU9KCk9PlgoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvcik7bGV0IFY9US5nZXQoJCk7Vi5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1WLnJlc3VsdDtpZighVylyZXR1cm47US5wdXQoVlkoVyxaKSl9fSl9YXN5bmMgZ2V0KCQpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxYKT0+e2xldCBZPUouZ2V0KCQpO1kub25zdWNjZXNzPSgpPT57bGV0IFY9WS5yZXN1bHQ7aWYoIVYpUSh2b2lkIDApO2Vsc2UgUShfUShWKSl9LFkub25lcnJvcj0oKT0+WChZLmVycm9yKX0pfWFzeW5jIHNldCgkLFope2xldCBKPWF3YWl0IHRoaXMuZ2V0KCQpO2lmKCFKKXJldHVybiAxMzt0cnl7cmV0dXJuIGF3YWl0IHRoaXMucHV0KHsuLi5KLC4uLlp9KSwwfWNhdGNoe3JldHVybiAxOH19YXN5bmMgZGVsKCQpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWR3cml0ZSIpLEo9Wi5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFgpPT57Wi5vbmNvbXBsZXRlPSgpPT5RKCksWi5vbmVycm9yPSgpPT5YKFouZXJyb3IpLEouZGVsZXRlKCQpfSl9YXN5bmMgbGlzdCgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBYPVouZ2V0QWxsKCk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgWT1YLnJlc3VsdDtKKFkubWFwKF9RKSl9LFgub25lcnJvcj0oKT0+UShYLmVycm9yKX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxaPSQub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+eyQub25jb21wbGV0ZT0oKT0+SigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxaLmNsZWFyKCl9KX19Y2xhc3MgJEp7Y3J5cHRvO2RiO2NvbnN0cnVjdG9yKCQsWil7dGhpcy5jcnlwdG89Wjt0aGlzLmRiPSR9YXN5bmMgYWRkKCQpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24obCwicmVhZHdyaXRlIiksSj1aLm9iamVjdFN0b3JlKGwpO3JldHVybiBuZXcgUHJvbWlzZSgoUSk9PntpZigkLmxlbmd0aD09PTApe1EoW10pO3JldHVybn1sZXQgWD1BcnJheSgkLmxlbmd0aCkuZmlsbCgwKTtaLm9uY29tcGxldGU9KCk9PlEoWCksWi5vbmVycm9yPSgpPT57Zm9yKGxldCBZPTA7WTxYLmxlbmd0aDtZKyspWFtZXT0xODtRKFgpfTtmb3IobGV0IFk9MDtZPCQubGVuZ3RoO1krKyl7bGV0e2tleTpWLGRhdGE6V309JFtZXSx6PUIoViksSz1KLnB1dChXLHopO0sub25lcnJvcj0oRik9PntGLnByZXZlbnREZWZhdWx0KCksWFtZXT0xOH19fSl9YXN5bmMgZGVsKCQpe2xldCBaPVsuLi4kXTtpZihaLmxlbmd0aD09PTApcmV0dXJuO2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24obCwicmVhZHdyaXRlIiksUT1KLm9iamVjdFN0b3JlKGwpO3JldHVybiBuZXcgUHJvbWlzZSgoWCxZKT0+e0oub25jb21wbGV0ZT0oKT0+WCgpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtmb3IobGV0IFYgb2YgWil7bGV0IFc9QihWKTtRLmRlbGV0ZShXKX19KX1hc3luYyBnZXQoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihsLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGwpO3JldHVybiBuZXcgUHJvbWlzZSgoUSxYKT0+e2xldCBZPUIoJCksVj1KLmdldChZKTtWLm9uc3VjY2Vzcz1hc3luYygpPT57bGV0IFc9Vi5yZXN1bHQ7aWYoVylRKGF3YWl0IFMkKCQsVyx0aGlzLmNyeXB0bykpO2Vsc2UgUSh2b2lkIDApfSxWLm9uZXJyb3I9KCk9PlgoVi5lcnJvcil9KX1hc3luYyBoYXMoJCl7cmV0dXJuIGF3YWl0IHRoaXMuZ2V0KCQpIT09dm9pZCAwfWFzeW5jIGxpc3QoJCl7bGV0IFo9JD8uYXBsZCxKPSQ/LmJvZHkhPT0hMSxYPXRoaXMuZGIudHJhbnNhY3Rpb24obCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShsKTtyZXR1cm4gbmV3IFByb21pc2UoKFksVik9PntsZXQgVz1bXSx6PVo9PT12b2lkIDA/WC5vcGVuQ3Vyc29yKCk6WC5pbmRleChxJCkub3BlbkN1cnNvcihJREJLZXlSYW5nZS5vbmx5KFopKTt6Lm9uc3VjY2Vzcz0oSyk9PntsZXQgRj1LLnRhcmdldC5yZXN1bHQ7aWYoRil7bGV0IE49Wj09PXZvaWQgMD9GLmtleTpGLnByaW1hcnlLZXksTz1GLnZhbHVlO1cucHVzaCh7aGFzaDpGMChOKSxkYXRhOk99KSxGLmNvbnRpbnVlKCl9ZWxzZSBQcm9taXNlLmFsbChXLm1hcCgoe2hhc2g6TixkYXRhOk99KT0+UyQoTixPLHRoaXMuY3J5cHRvLHtib2R5Okp9KSkpLnRoZW4oWSkuY2F0Y2goVil9LHoub25lcnJvcj0oKT0+Vih6LmVycm9yKX0pfWFzeW5jIGNvdW50KCQpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24obCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShsKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWCk9PntsZXQgWT0kPT09dm9pZCAwP0ouY291bnQoKTpKLmluZGV4KHEkKS5jb3VudChJREJLZXlSYW5nZS5vbmx5KCQpKTtZLm9uc3VjY2Vzcz0oKT0+UShZLnJlc3VsdCksWS5vbmVycm9yPSgpPT5YKFkuZXJyb3IpfSl9YXN5bmMgbGlzdEtleXMoKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKGwsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57bGV0IFg9W10sWT1aLm9wZW5LZXlDdXJzb3IoKTtZLm9uc3VjY2Vzcz0oVik9PntsZXQgVz1WLnRhcmdldC5yZXN1bHQ7aWYoVylYLnB1c2goRjAoVy5rZXkpKSxXLmNvbnRpbnVlKCk7ZWxzZSBKKFgpfSxZLm9uZXJyb3I9KCk9PlEoWS5lcnJvcil9KX1hc3luYyBsYXN0KCQpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24obCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShsKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWCk9PntsZXQgWSxWPUoub3BlbkN1cnNvcigpO1Yub25zdWNjZXNzPWFzeW5jKFcpPT57bGV0IHo9Vy50YXJnZXQucmVzdWx0O2lmKHope2xldHtrZXk6Syx2YWx1ZTpGfT16O2lmKGEoJCxGLmVpZCkpe2lmKCFZfHwoRi5jdHI/PzApPihZLmRhdGEuY3RyPz8wKXx8KEYuY3RyPz8wKT09PShZLmRhdGEuY3RyPz8wKSYmKEYub2ZmPz8wKT4oWS5kYXRhLm9mZj8/MCkpWT17a2V5OkssZGF0YTpGfX16LmNvbnRpbnVlKCl9ZWxzZSBpZihZKXtsZXQgSz1GMChZLmtleSk7UShhd2FpdCBTJChLLFkuZGF0YSx0aGlzLmNyeXB0bykpfWVsc2UgUSh2b2lkIDApfSxWLm9uZXJyb3I9KCk9PlgoVi5lcnJvcil9KX1hc3luYyBtYXJrQXBwbGllZCgkKXtsZXQgWj1bLi4uJF07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKGwsInJlYWR3cml0ZSIpLFE9Si5vYmplY3RTdG9yZShsKTtyZXR1cm4gbmV3IFByb21pc2UoKFgsWSk9PntKLm9uY29tcGxldGU9KCk9PlgoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvcik7Zm9yKGxldCBWIG9mIFope2xldCBXPUIoViksej1RLmdldChXKTt6Lm9uc3VjY2Vzcz0oKT0+e2xldCBLPXoucmVzdWx0O2lmKCFLKXJldHVybjtEWihLLG0kKSxRLnB1dChLLFcpfSx6Lm9uZXJyb3I9KEspPT57Sy5wcmV2ZW50RGVmYXVsdCgpfX19KX1hc3luYyBtYXJrRmFpbGVkKCQpe2xldCBaPVsuLi4kXTtpZihaLmxlbmd0aD09PTApcmV0dXJuO2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24obCwicmVhZHdyaXRlIiksUT1KLm9iamVjdFN0b3JlKGwpO3JldHVybiBuZXcgUHJvbWlzZSgoWCxZKT0+e0oub25jb21wbGV0ZT0oKT0+WCgpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtmb3IobGV0e2tleTpWLGVycjpXfW9mIFope2xldCB6PUIoViksSz1RLmdldCh6KTtLLm9uc3VjY2Vzcz0oKT0+e2xldCBGPUsucmVzdWx0O2lmKCFGKXJldHVybjtEWihGLHMwLFcpLFEucHV0KEYseil9LEsub25lcnJvcj0oRik9PntGLnByZXZlbnREZWZhdWx0KCl9fX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKGwsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZShsKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PnskLm9uY29tcGxldGU9KCk9PkooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksWi5jbGVhcigpfSl9fWNsYXNzIFpKeyNaOyMkOyNKOyNYOyNRO2NvbnN0cnVjdG9yKCQpe2lmKHRoaXMuI1o9JC5jcnlwdG8sdGhpcy4jUT0kLnBlcnNpc3RNZXRhLHRoaXMuI1g9e3JwSWQ6JC5ycElkLHJwTmFtZTokLnJwTmFtZX0sJC5tZXRhIT09dm9pZCAwKXRoaXMuI0o9djAoJC5tZXRhKX1nZXQgbWV0YSgpe3JldHVybiB0aGlzLiNKPT09dm9pZCAwP3ZvaWQgMDp2MCh0aGlzLiNKKX1zZXRNZXRhKCQpe3RoaXMuI0o9JD09PXZvaWQgMD92b2lkIDA6djAoJCl9YXN5bmMgc2F2ZSgkLFope2lmKFo/LnBlcnNpc3Q9PT0hMClyZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoInByZi1zdG9yZTogdXNlIHdyYXBBbmRTYXZlKGVuY2xhdmUpIHRvIHBlcnNpc3Qgc2VhbGVkIG1hc3RlciIpKTtyZXR1cm4gdGhpcy4jJD0kLHRoaXMuIyR9YXN5bmMgd3JhcEFuZFNhdmUoJCxaKXtsZXRbSixRXT1hd2FpdCAkLnNlYWxXaXRoUGFzc2tleSh7Li4udGhpcy4jWCxzYWx0Olo/LnNhbHQsY3JlZElkOlo/LmNyZWRJZD8/dGhpcy4jSj8uY3JlZElkLGNyZWF0ZUNyZWRJZk5lZWRlZDpaPy5jcmVhdGVDcmVkSWZOZWVkZWQ/P1o/LmNyZWRJZD09PXZvaWQgMCx1c2VyTmFtZToiZGlwbG9tYXRpYy1wcmYifSk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0IFg9e3NlYWxlZE1hc3RlcjpKLnNlYWxlZE1hc3RlcixzYWx0Okouc2FsdCxjcmVkSWQ6Si5jcmVkSWR9O3JldHVybiB0aGlzLiNKPVgsdGhpcy4jJD0kLGF3YWl0IHRoaXMuI1EodjAoWCkpLFIodGhpcy4jJCl9YXN5bmMgbG9hZCgpe3JldHVybiB0aGlzLiMkfWFzeW5jIHVubG9jaygpe2xldCAkPXRoaXMuI0o7aWYoJD09PXZvaWQgMClyZXR1cm4gRygyMik7bGV0W1osSl09YXdhaXQgVzAudW5zZWFsV2l0aFBhc3NrZXkodGhpcy4jWiwkLnNlYWxlZE1hc3Rlcix7Li4udGhpcy4jWCxzYWx0OiQuc2FsdCxjcmVkSWQ6JC5jcmVkSWR9KTtpZihKIT09MClyZXR1cm4gRyhKKTtpZih0aGlzLiMkPVouZW5jbGF2ZSxaLmNyZWRJZC5ieXRlTGVuZ3RoPjAmJigkLmNyZWRJZD09PXZvaWQgMHx8IWEoJC5jcmVkSWQsWi5jcmVkSWQpKSl7bGV0IFE9e3NlYWxlZE1hc3RlcjokLnNlYWxlZE1hc3RlcixzYWx0OiQuc2FsdCxjcmVkSWQ6Wi5jcmVkSWQuc2xpY2UoKX07dGhpcy4jSj1RLGF3YWl0IHRoaXMuI1EodjAoUSkpfXJldHVybiBSKFouZW5jbGF2ZSl9YXN5bmMgYWRvcHRTZWFsZWQoJCxaKXtyZXR1cm4gdGhpcy4jSj12MChaKSx0aGlzLiMkPSQsYXdhaXQgdGhpcy4jUSh2MChaKSksUih0aGlzLiMkKX1hc3luYyB3aXBlKCl7dGhpcy4jJD12b2lkIDAsdGhpcy4jSj12b2lkIDAsYXdhaXQgdGhpcy4jUSh2b2lkIDApfX1mdW5jdGlvbiB2MCgkKXtsZXRbWixKXT1EMCgkLnNlYWxlZE1hc3Rlci5zbGljZSgpKTtyZXR1cm57c2VhbGVkTWFzdGVyOko9PT0wJiZaIT09dm9pZCAwP1o6JC5zZWFsZWRNYXN0ZXIsc2FsdDokLnNhbHQuc2xpY2UoKSxjcmVkSWQ6JC5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9fXZhciBXWT0iZGlwbG9tYXRpYy5waW4vIjtmdW5jdGlvbiBHWSgkKXtyZXR1cm4gV1krTjAoJCl9YXN5bmMgZnVuY3Rpb24gTFEoJCxaLEope2xldCBRPWF3YWl0IFouZGVyaXZlSWRlbnRpdHkoR1koSiksMCk7cmV0dXJuICQuYmxha2UzKFEucHVibGljS2V5KX1hc3luYyBmdW5jdGlvbiB4USgkLFope2xldCBKPWF3YWl0ICQuZ2VuMjU2Qml0U2VjdXJlUmFuZG9tU2VlZCgpLFE9YXdhaXQgTFEoJCxaLEopO3JldHVybntuOkosaDpRfX1hc3luYyBmdW5jdGlvbiBCUSgkLFosSil7bGV0IFE9YXdhaXQgTFEoJCxaLEoubik7cmV0dXJuIHpZKFEsSi5oKX1mdW5jdGlvbiBrUSgkKXtpZigkPT09dm9pZCAwfHwkPT09bnVsbHx8dHlwZW9mICQhPT0ib2JqZWN0IilyZXR1cm47bGV0IFo9JDtpZighKFoubiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpfHwhKFouaCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKXJldHVybjtpZihaLm4uYnl0ZUxlbmd0aDwxfHxaLmguYnl0ZUxlbmd0aDwxKXJldHVybjtyZXR1cm57bjpaLm4uc2xpY2UoKSxoOlouaC5zbGljZSgpfX1mdW5jdGlvbiBFUSgkKXtyZXR1cm57bjokLm4uc2xpY2UoKSxoOiQuaC5zbGljZSgpfX1mdW5jdGlvbiB6WSgkLFope2lmKCQuYnl0ZUxlbmd0aCE9PVouYnl0ZUxlbmd0aClyZXR1cm4hMTtsZXQgSj0wO2ZvcihsZXQgUT0wO1E8JC5ieXRlTGVuZ3RoO1ErKylKfD0kW1FdXlpbUV07cmV0dXJuIEo9PT0wfXZhciBzJD0icHJmTWV0YSIsSko9ImlkUGluIixmUT0iaWRQdWIiO2NsYXNzIFFKeyNaO2RiOyMkO2NvbnN0cnVjdG9yKCQsWil7dGhpcy5kYj0kLHRoaXMuIyQ9Wn1hc3luYyBzYXZlKCQsWil7cmV0dXJuIGF3YWl0IHRoaXMuI0ooJCksdGhpcy4jWj0kLHRoaXMuI1p9YXN5bmMgbG9hZCgpe3JldHVybiB0aGlzLiNafWFzeW5jIGNsZWFyU2Vzc2lvbigpe3RoaXMuI1o9dm9pZCAwfWFzeW5jIHdpcGUoKXt0aGlzLiNaPXZvaWQgMDtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKEowLCJyZWFkd3JpdGUiKSxaPSQub2JqZWN0U3RvcmUoSjApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+eyQub25jb21wbGV0ZT0oKT0+SigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxaLmRlbGV0ZShzJCksWi5kZWxldGUoSkopLFouZGVsZXRlKGZRKX0pfWFzeW5jIGxvYWRQcmZNZXRhKCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihKMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShKMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57bGV0IFg9Wi5nZXQocyQpO1gub25zdWNjZXNzPSgpPT57SihLWShYLnJlc3VsdCkpfSxYLm9uZXJyb3I9KCk9PlEoWC5lcnJvcil9KX1hc3luYyBwZXJzaXN0UHJmTWV0YSgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKEowLCJyZWFkd3JpdGUiKSxKPVoub2JqZWN0U3RvcmUoSjApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxYKT0+e2lmKFoub25jb21wbGV0ZT0oKT0+USgpLFoub25lcnJvcj0oKT0+WChaLmVycm9yKSwkPT09dm9pZCAwKXtKLmRlbGV0ZShzJCk7cmV0dXJufWxldCBZPXtzZWFsZWRNYXN0ZXI6JC5zZWFsZWRNYXN0ZXIuc2xpY2UoKSxzYWx0OiQuc2FsdC5zbGljZSgpLGNyZWRJZDokLmNyZWRJZD09PXZvaWQgMD92b2lkIDA6JC5jcmVkSWQuc2xpY2UoKX07Si5wdXQoWSxzJCl9KX1hc3luYyBoYXNQcmZNZXRhKCl7cmV0dXJuIGF3YWl0IHRoaXMubG9hZFByZk1ldGEoKSE9PXZvaWQgMH1hc3luYyBsYXN0UHJmQ3JlZElkKCl7bGV0ICQ9YXdhaXQgdGhpcy5sb2FkUHJmTWV0YSgpO3JldHVybiAkPy5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9YXN5bmMgb3BlblByZlN0b3JlKCQpe2xldCBaPWF3YWl0IHRoaXMubG9hZFByZk1ldGEoKTtyZXR1cm4gbmV3IFpKKHtjcnlwdG86JC5jcnlwdG8/P3RoaXMuIyQscnBJZDokLnJwSWQscnBOYW1lOiQucnBOYW1lLG1ldGE6WixwZXJzaXN0TWV0YTooSik9PnRoaXMucGVyc2lzdFByZk1ldGEoSil9KX1hc3luYyNKKCQpe2F3YWl0IHRoaXMuI1koZlEpO2xldCBaPWF3YWl0IHRoaXMuI1goKTtpZihaIT09dm9pZCAwKXtpZighYXdhaXQgQlEodGhpcy4jJCwkLFopKXRocm93IEVycm9yKCJbRElQTE9NQVRJQ10gc2VlZCBkb2VzIG5vdCBtYXRjaCB0aGlzIGRldmljZSdzIGlkZW50aXR5IChsb2NhbCBkYXRhIHdhcyBjcmVhdGVkIHdpdGggYSBkaWZmZXJlbnQgbWFzdGVyIHNlZWQpIik7cmV0dXJufWxldCBKPWF3YWl0IHhRKHRoaXMuIyQsJCk7YXdhaXQgdGhpcy4jUShKKX0jWCgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oSjAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoSjApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBYPVouZ2V0KEpKKTtYLm9uc3VjY2Vzcz0oKT0+SihrUShYLnJlc3VsdCkpLFgub25lcnJvcj0oKT0+UShYLmVycm9yKX0pfSNRKCQpe2xldCBaPUVRKCQpLEo9dGhpcy5kYi50cmFuc2FjdGlvbihKMCwicmVhZHdyaXRlIiksUT1KLm9iamVjdFN0b3JlKEowKTtyZXR1cm4gbmV3IFByb21pc2UoKFgsWSk9PntKLm9uY29tcGxldGU9KCk9PlgoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvciksUS5wdXQoWixKSil9KX0jWSgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKEowLCJyZWFkd3JpdGUiKSxKPVoub2JqZWN0U3RvcmUoSjApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxYKT0+e1oub25jb21wbGV0ZT0oKT0+USgpLFoub25lcnJvcj0oKT0+WChaLmVycm9yKSxKLmRlbGV0ZSgkKX0pfX1mdW5jdGlvbiBLWSgkKXtpZigkPT09dm9pZCAwfHwkPT09bnVsbHx8dHlwZW9mICQhPT0ib2JqZWN0IilyZXR1cm47bGV0IFo9JDtpZighKFouc2VhbGVkTWFzdGVyIGluc3RhbmNlb2YgVWludDhBcnJheSl8fCEoWi5zYWx0IGluc3RhbmNlb2YgVWludDhBcnJheSkpcmV0dXJuO2xldFtKLFFdPUQwKFouc2VhbGVkTWFzdGVyKTtpZihRIT09MHx8Sj09PXZvaWQgMClyZXR1cm47cmV0dXJue3NlYWxlZE1hc3RlcjpKLHNhbHQ6Wi5zYWx0LnNsaWNlKCksY3JlZElkOlouY3JlZElkIGluc3RhbmNlb2YgVWludDhBcnJheT9aLmNyZWRJZC5zbGljZSgpOnZvaWQgMH19Y2xhc3MgWEp7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGVucSgkLFope2xldCBKPVsuLi5aXTtpZihKLmxlbmd0aD09PTApcmV0dXJuO2xldCBRPXRoaXMuZGIudHJhbnNhY3Rpb24oejAsInJlYWR3cml0ZSIpLFg9US5vYmplY3RTdG9yZSh6MCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57US5vbmNvbXBsZXRlPSgpPT5ZKCksUS5vbmVycm9yPSgpPT5WKFEuZXJyb3IpO2ZvcihsZXQgVyBvZiBKKXtsZXQgej1OMChXKTtYLnB1dCh7aG9zdDokLGhhc2g6en0pfX0pfWFzeW5jIGRlcSgkLFope2xldCBKPVsuLi5aXTtpZihKLmxlbmd0aD09PTApcmV0dXJuO2xldCBRPXRoaXMuZGIudHJhbnNhY3Rpb24oejAsInJlYWR3cml0ZSIpLFg9US5vYmplY3RTdG9yZSh6MCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57US5vbmNvbXBsZXRlPSgpPT5ZKCksUS5vbmVycm9yPSgpPT5WKFEuZXJyb3IpO2ZvcihsZXQgVyBvZiBKKXtsZXQgej1OMChXKTtYLmRlbGV0ZShbJCx6XSl9fSl9YXN5bmMgbGlzdCgkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKHowLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHowKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWCk9PntsZXQgWT1KLmdldEFsbCgpO1kub25zdWNjZXNzPSgpPT57bGV0IFc9WS5yZXN1bHQuZmlsdGVyKCh6KT0+ei5ob3N0PT09JCkubWFwKCh6KT0+ei5oYXNoKTtRKFcubWFwKCh6KT0+Q0ooeikpKX0sWS5vbmVycm9yPSgpPT5YKFkuZXJyb3IpfSl9YXN5bmMgY291bnQoKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKHowLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHowKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PntsZXQgWD1aLmNvdW50KCk7WC5vbnN1Y2Nlc3M9KCk9PkooWC5yZXN1bHQpLFgub25lcnJvcj0oKT0+UShYLmVycm9yKX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKHowLCJyZWFkd3JpdGUiKSxaPSQub2JqZWN0U3RvcmUoejApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+eyQub25jb21wbGV0ZT0oKT0+SigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxaLmNsZWFyKCl9KX19dmFyIEowPSJzZWVkTWV0YSIsWjA9Imhvc3RzIix6MD0idXBsb2FkUXVldWUiLEcwPSJkb3dubG9hZFF1ZXVlIixsPSJtZXNzYWdlcyIscSQ9ImFwbGQiLGdRPTMsbVE9ImRpcGxvbWF0aWMtc3RvcmUtZGIiO2NsYXNzIFNRe3NlZWQ7aG9zdHM7dXBsb2Fkcztkb3dubG9hZHM7bWVzc2FnZXM7ZGI7Y29uc3RydWN0b3IoJCxaKXt0aGlzLmRiPSQsdGhpcy5zZWVkPW5ldyBRSigkLFopLHRoaXMuaG9zdHM9bmV3IGVaKCQpLHRoaXMudXBsb2Fkcz1uZXcgWEooJCksdGhpcy5kb3dubG9hZHM9bmV3IHRaKCQpLHRoaXMubWVzc2FnZXM9bmV3ICRKKCQsWil9YXN5bmMgd2lwZSgpe2F3YWl0IHRoaXMuaG9zdHMud2lwZSgpLGF3YWl0IHRoaXMudXBsb2Fkcy53aXBlKCksYXdhaXQgdGhpcy5kb3dubG9hZHMud2lwZSgpLGF3YWl0IHRoaXMubWVzc2FnZXMud2lwZSgpfX1hc3luYyBmdW5jdGlvbiBGWSgpe3JldHVybiBuZXcgUHJvbWlzZSgoJCxaKT0+e2xldCBKPWluZGV4ZWREQi5vcGVuKG1RLGdRKTtKLm9udXBncmFkZW5lZWRlZD0oKT0+e2xldHtyZXN1bHQ6USx0cmFuc2FjdGlvbjpYfT1KO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoSjApKVEuY3JlYXRlT2JqZWN0U3RvcmUoSjApO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoWjApKVEuY3JlYXRlT2JqZWN0U3RvcmUoWjAse2tleVBhdGg6ImxhYmVsIn0pO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoejApKVEuY3JlYXRlT2JqZWN0U3RvcmUoejAse2tleVBhdGg6WyJob3N0IiwiaGFzaCJdfSk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhHMCkpUS5jcmVhdGVPYmplY3RTdG9yZShHMCk7bGV0IFk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhsKSlZPVEuY3JlYXRlT2JqZWN0U3RvcmUobCk7ZWxzZXtpZighWCl0aHJvdyBFcnJvcigibWlzc2luZyB1cGdyYWRlIHRyYW5zYWN0aW9uIGZvciBtZXNzYWdlcyBzdG9yZSIpO1k9WC5vYmplY3RTdG9yZShsKX1pZighWS5pbmRleE5hbWVzLmNvbnRhaW5zKHEkKSlZLmNyZWF0ZUluZGV4KHEkLCJhcGxkIix7dW5pcXVlOiExfSl9LEoub25ibG9ja2VkPSgpPT57Y29uc29sZS53YXJuKGBbRElQTE9NQVRJQ10gcHJvdG9jb2wgc3RvcmUgSURCIHVwZ3JhZGUgYmxvY2tlZCAoJHttUX0g4oaSIHYke2dRfSk7IHdhaXRpbmcgZm9yIG90aGVyIGNvbm5lY3Rpb25zIHRvIGNsb3NlYCl9LEoub25zdWNjZXNzPSgpPT57bGV0IFE9Si5yZXN1bHQ7US5vbnZlcnNpb25jaGFuZ2U9KCk9PntRLmNsb3NlKCl9LCQoUSl9LEoub25lcnJvcj0oKT0+WihKLmVycm9yPz9FcnJvcigicHJvdG9jb2wgc3RvcmUgSW5kZXhlZERCIG9wZW4gZmFpbGVkIikpfSl9YXN5bmMgZnVuY3Rpb24gdlEoJCl7bGV0IFo9YXdhaXQgRlkoKTtpZih0eXBlb2YgbmF2aWdhdG9yPCJ1IiYmbmF2aWdhdG9yLnN0b3JhZ2U/LnBlcnNpc3QpdHJ5e2F3YWl0IFByb21pc2UucmFjZShbbmF2aWdhdG9yLnN0b3JhZ2UucGVyc2lzdCgpLG5ldyBQcm9taXNlKChKKT0+e3NldFRpbWVvdXQoKCk9PkooITEpLDIwMDApfSldKX1jYXRjaHt9cmV0dXJuIG5ldyBTUShaLCQpfWNsYXNzIFlKe2NsaWVudDtlbnREQjtwb3N0O3doZW5SZWFkeTtyZXNvbHZlUmVhZHk7cmVqZWN0UmVhZHk7Y29uc3RydWN0b3IoJCl7dGhpcy5wb3N0PSQsdGhpcy53aGVuUmVhZHk9bmV3IFByb21pc2UoKFosSik9Pnt0aGlzLnJlc29sdmVSZWFkeT1aLHRoaXMucmVqZWN0UmVhZHk9Sn0pfWFzeW5jIGluaXQoKXt0cnl7bGV0ICQ9YXdhaXQgdlEoTyQpLFo9YXdhaXQgeUooe2NhY2hlOiExfSksSj1uZXcgQiQoWi5hcHBseSwoKT0+Wi5jbGVhcigpLChZKT0+e2lmKFkubGVuZ3RoPDEpcmV0dXJuO3RoaXMucG9zdCh7a2luZDoiZGlydHkiLGVpZHM6WS5tYXAoKFYpPT5WLnNsaWNlKCkpfSl9KSxRPUouY2xlYXI7Si5jbGVhcj1hc3luYygpPT57bGV0IFk9YXdhaXQgUSgpO2lmKFk9PT0wKXRoaXMucG9zdCh7a2luZDoid2lwZWQifSk7cmV0dXJuIFl9O2xldCBYPW5ldyBrWihuZXcgVlosSiwkLHhKLE8kKTt0aGlzLmNsaWVudD1YLHRoaXMuZW50REI9WixYLmNsaWVudFN0YXRlLmxpc3RlbigoKT0+e3RoaXMuZW1pdENsaWVudFN0YXRlKCl9KSxYLnhmZXJTdGF0ZS5saXN0ZW4oKCk9Pnt0aGlzLmVtaXRYZmVyU3RhdGUoKX0pLGF3YWl0IHRoaXMuZW1pdFhmZXJTdGF0ZSgpLHRoaXMucG9zdCh7a2luZDoicmVhZHkifSksdGhpcy5tYXJrUmVhZHkoKX1jYXRjaCgkKXtsZXQgWj0kIGluc3RhbmNlb2YgRXJyb3I/JDpFcnJvcihTdHJpbmcoJCkpO3Rocm93IHRoaXMucG9zdCh7a2luZDoiaW5pdEVycm9yIixtZXNzYWdlOloubWVzc2FnZX0pLHRoaXMuZmFpbFJlYWR5KFopLFp9fW1hcmtSZWFkeSgpe2xldCAkPXRoaXMucmVzb2x2ZVJlYWR5O2lmKHRoaXMucmVzb2x2ZVJlYWR5PXZvaWQgMCx0aGlzLnJlamVjdFJlYWR5PXZvaWQgMCwkKSQoKX1mYWlsUmVhZHkoJCl7bGV0IFo9dGhpcy5yZWplY3RSZWFkeTtpZih0aGlzLnJlc29sdmVSZWFkeT12b2lkIDAsdGhpcy5yZWplY3RSZWFkeT12b2lkIDAsWilaKCQpfXJlcXVpcmVDbGllbnQoKXtpZighdGhpcy5jbGllbnQpdGhyb3cgRXJyb3IoIldvcmtlclJ1bnRpbWUgbm90IGluaXRpYWxpemVkIik7cmV0dXJuIHRoaXMuY2xpZW50fWFzeW5jIGVtaXRDbGllbnRTdGF0ZSgpe2xldCAkPXRoaXMuY2xpZW50O2lmKCEkKXJldHVybjtsZXQgWj1hd2FpdCAkLmNsaWVudFN0YXRlLmdldCgpO3RoaXMucG9zdCh7a2luZDoiY2xpZW50U3RhdGUiLGNvbm5lY3RlZDpaLmNvbm5lY3RlZH0pfWFzeW5jIGVtaXRYZmVyU3RhdGUoKXtsZXQgJD10aGlzLmNsaWVudDtpZighJClyZXR1cm47bGV0IFo9YXdhaXQgJC54ZmVyU3RhdGUuZ2V0KCk7dGhpcy5wb3N0KHtraW5kOiJ4ZmVyU3RhdGUiLHN0YXRlOlp9KX1ob3N0RnJvbVNlcmlhbGl6ZWQoJCl7cmV0dXJue2hhbmRsZTpuZXcgVVJMKCQuaGFuZGxlKSxsYWJlbDokLmxhYmVsLGlkeDokLmlkeH19YXN5bmMgaGFuZGxlKCQpe2F3YWl0IHRoaXMud2hlblJlYWR5O2xldCBaPXRoaXMucmVxdWlyZUNsaWVudCgpO3N3aXRjaCgkLm9wKXtjYXNlInBpbmciOnJldHVybiJwb25nIjtjYXNlInNldFNlZWQiOntsZXRbSixRXT1XMC5mcm9tQnl0ZXMoTyQsJC5zZWVkKTtpZihRIT09MHx8Sj09PXZvaWQgMCl0aHJvdyBuZXcgSzAoUSk7YXdhaXQgWi5zZXRTZWVkKEose3BlcnNpc3Q6JC5wZXJzaXN0fSk7cmV0dXJufWNhc2UibGluayI6e2F3YWl0IFoubGluayh0aGlzLmhvc3RGcm9tU2VyaWFsaXplZCgkLmhvc3QpLCQuY29ubmVjdD8/ITApO3JldHVybn1jYXNlInVubGluayI6e2F3YWl0IFoudW5saW5rKCQubGFiZWwpO3JldHVybn1jYXNlImNvbm5lY3QiOnthd2FpdCBaLmNvbm5lY3QoJC5saXN0ZW4/PyEwLCQuc3luYz8/ITApO3JldHVybn1jYXNlImRpc2Nvbm5lY3QiOnthd2FpdCBaLmRpc2Nvbm5lY3QoKTtyZXR1cm59Y2FzZSJzeW5jIjpyZXR1cm4gYXdhaXQgWi5zeW5jKCk7Y2FzZSJyZWJ1aWxkIjpyZXR1cm4gYXdhaXQgWi5yZWJ1aWxkKHtjaGVja0hvc3Q6JC5jaGVja0hvc3Q/PyEwfSk7Y2FzZSJyZWNvbmNpbGUiOntsZXRbSixRXT1hd2FpdCBaLnJlY29uY2lsZSgkLmhvc3RMYWJlbCx7cHVsbDokLnB1bGwscHVzaDokLnB1c2gsc3luYzokLnN5bmN9KTtpZihRIT09MCl0aHJvdyBuZXcgSzAoUSk7aWYoIUopdGhyb3cgbmV3IEswKDEyKTtyZXR1cm4gSn1jYXNlIm1zZ2NoZWNrIjpyZXR1cm4gYXdhaXQgWi5tc2djaGVjaygpO2Nhc2UiZW50Y2hlY2siOntsZXQgSj10aGlzLmVudERCO2lmKCFKKXRocm93IG5ldyBLMCgxMik7bGV0W1EsWF09YXdhaXQgSi5jaGVja3N1bShPJCk7aWYoWCE9PTApdGhyb3cgbmV3IEswKFgpO2lmKCFRKXRocm93IG5ldyBLMCgxMik7cmV0dXJuIFF9Y2FzZSJ3aXBlIjp7YXdhaXQgWi53aXBlKHttc2dzOiQubXNncyxlbnRzOiQuZW50cyxtZXRhOiQubWV0YSxzZWVkOiQuc2VlZH0pO3JldHVybn1jYXNlImltcG9ydCI6e2xldCBKPSQuYnl0ZXMuc2xpY2UoKSxRPW5ldyBCbG9iKFtKXSksWD1uZXcgRmlsZShbUV0sImltcG9ydC5kaXAiKTtyZXR1cm4gYXdhaXQgWi5pbXBvcnQoWCl9Y2FzZSJleHBvcnQiOntsZXRbSixRXT1hd2FpdCBaLmV4cG9ydEJ5dGVzKCk7aWYoUSE9PTApdGhyb3cgbmV3IEswKFEpO2lmKCFKKXRocm93IG5ldyBLMCgxMik7cmV0dXJuIEp9Y2FzZSJnZXRYZmVyU3RhdGUiOnJldHVybiBhd2FpdCBaLnhmZXJTdGF0ZS5nZXQoKTtkZWZhdWx0OntsZXQgSj0kO3Rocm93IEVycm9yKCJ1bmtub3duIHdvcmtlciBjb21tYW5kIil9fX19Y2xhc3MgSzAgZXh0ZW5kcyBFcnJvcntzdGF0dXM7Y29uc3RydWN0b3IoJCl7c3VwZXIoYFdvcmtlclN0YXR1c0Vycm9yOiAke0RbJF19YCk7dGhpcy5zdGF0dXM9JDt0aGlzLm5hbWU9IldvcmtlclN0YXR1c0Vycm9yIn19ZnVuY3Rpb24gdCQoJCxaKXtyZXR1cm57a2luZDoicmVwbHkiLGlkOiQsb2s6ITAscmVzdWx0Olp9fWZ1bmN0aW9uIFZKKCQsWil7cmV0dXJue2tpbmQ6InJlcGx5IixpZDokLG9rOiExLHN0YXR1czpafX12YXIgQTA9Z2xvYmFsVGhpcyxiUT1uZXcgWUooKCQsWik9PntpZihaJiZaLmxlbmd0aD4wKUEwLnBvc3RNZXNzYWdlKCQsWik7ZWxzZSBBMC5wb3N0TWVzc2FnZSgkKX0pO0EwLm9ubWVzc2FnZT0oJCk9PntsZXQgWj0kLmRhdGE7aWYoIUtKKFopKXJldHVybjtOWShaKX07YXN5bmMgZnVuY3Rpb24gTlkoJCl7dHJ5e2xldCBaPWF3YWl0IGJRLmhhbmRsZSgkKTtpZigoJC5vcD09PSJleHBvcnQifHwkLm9wPT09Im1zZ2NoZWNrInx8JC5vcD09PSJlbnRjaGVjayIpJiZaIGluc3RhbmNlb2YgVWludDhBcnJheSl7bGV0IEo9Wi5zbGljZSgpO0EwLnBvc3RNZXNzYWdlKHQkKCQuaWQsSiksW0ouYnVmZmVyXSk7cmV0dXJufWlmKCQub3A9PT0icmVjb25jaWxlIiYmWiYmdHlwZW9mIFo9PT0ib2JqZWN0IiYmIm1zZ2NoZWNrImluIFomJloubXNnY2hlY2sgaW5zdGFuY2VvZiBVaW50OEFycmF5KXtsZXQgSj1aLm1zZ2NoZWNrLnNsaWNlKCksUT17Li4uWixtc2djaGVjazpKfTtBMC5wb3N0TWVzc2FnZSh0JCgkLmlkLFEpLFtKLmJ1ZmZlcl0pO3JldHVybn1BMC5wb3N0TWVzc2FnZSh0JCgkLmlkLFopKX1jYXRjaChaKXtpZihaIGluc3RhbmNlb2YgSzApe0EwLnBvc3RNZXNzYWdlKFZKKCQuaWQsWi5zdGF0dXMpKTtyZXR1cm59Y29uc29sZS5lcnJvcigid29ya2VyIGNvbW1hbmQgZmFpbGVkIixaKSxBMC5wb3N0TWVzc2FnZShWSigkLmlkLDEyKSl9fWJRLmluaXQoKS5jYXRjaCgoJCk9Pntjb25zb2xlLmVycm9yKCJ3b3JrZXIgaW5pdCBmYWlsZWQiLCQpfSk7Cg==";var IW=typeof globalThis.Worker==="function"?globalThis.Worker:void 0,PV=IW===void 0?void 0:IW.prototype.postMessage,kW;function UK(){if(typeof cW!=="string"||cW.length===0)throw Error("[DIPLOMATIC] worker source not embedded; run pkg build before spawn");return atob(cW)}function iK(){if(kW!==void 0)return kW;let Z=new Blob([UK()],{type:"text/javascript"});return kW=URL.createObjectURL(Z),kW}function el(){if(IW===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot spawn sync worker");return new IW(iK(),{type:"module"})}function Z0(Z,X,W){if(PV===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot post to sync worker");if(W!==void 0&&W.length>0)PV.call(Z,X,{transfer:W});else PV.call(Z,X)}var uK=new TextEncoder().encode("diplomatic.wrap.v1"),X0=new TextEncoder().encode("diplomatic.pair.v1"),OK=32,EK=16;class a{#W;#Z;constructor(Z,X){this.#W=Z,this.#Z=X}static async fromRandom(Z){let X=await Z.gen256BitSecureRandomSeed(),[W,V]=WZ(X);if(V!==0||W===void 0)throw Error(`enclave: invalid random seed (${V})`);return new a(W,Z)}static fromBytes(Z,X){let[W,V]=WZ(X);if(V!==0)return Y(V);if(W===void 0)return Y(10);let[l,K]=WZ(W.slice());if(K!==0)return Y(K);if(l===void 0)return Y(10);return d(new a(l,Z))}async sealWithPasskey(Z){let X=Z?.salt??iX,W=Z?.credId;if(W===void 0&&Z?.createCredIfNeeded===!0){let[K,G]=await tl({rpId:Z?.rpId,rpName:Z?.rpName,userName:Z?.userName??"diplomatic-prf"});if(G!==0)return Y(G);if(K===void 0)return Y(24);if(!K.prfEnabled)return Y(24);W=K.credId}let[V,l]=await uX({rpId:Z?.rpId,rpName:Z?.rpName,credId:W,salt:X});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await this.#X(V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);return d({sealedMaster:K,salt:X.slice(),credId:V.credId.slice()})}finally{V.prf.fill(0)}}static async unsealWithPasskey(Z,X,W){let[V,l]=await uX({rpId:W.rpId,rpName:W.rpName,credId:W.credId,salt:W.salt});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await a.#l(Z,X,V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);return d({enclave:K,credId:V.credId.slice()})}finally{V.prf.fill(0)}}async persistToLargeBlob(Z=[],X){let W=X?.credId;if(W===void 0){let[K,G]=await bW(X);if(G!==0)return Y(G);if(K===void 0)return Y(24);W=K}let[V,l]=this.#V(Z);if(l!==0)return Y(l);if(V===void 0)return Y(12);try{let K=await UX(W,V,X);if(K!==0)return Y(K);return d(W)}finally{V.fill(0)}}static async fromLargeBlob(Z,X){let[W,V]=await TW(X?.credId,X);if(V!==0)return Y(V);if(W===void 0)return Y(7);try{return a.#K(Z,W.blob,W.credId)}finally{W.blob.fill(0)}}static async clearLargeBlob(Z,X){return UX(Z,new Uint8Array(dZ),X)}async sealPairPackageBody(Z,X){let W=X?.salt??iX,[V,l]=await uX({rpId:X?.rpId,rpName:X?.rpName,credId:X?.credId,salt:W});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await LW(this.#Z,V.prf,X0);if(G!==0)return Y(G);if(K===void 0)return Y(12);try{let[m,R]=WZ(this.#W.slice());if(R!==0)return Y(R);if(m===void 0)return Y(10);let J={masterSeed:m,hosts:Z.map((c)=>({handle:c.handle,label:c.label,idx:c.idx??0}))},C=new U,F=C.writeStruct(FW,J);if(F!==0)return m.fill(0),Y(F);let b=C.result();m.fill(0);let T;try{T=await this.#Z.encryptXSalsa20Poly1305Combined(b,K)}catch{return b.fill(0),Y(12)}return b.fill(0),d({body:T,salt:W.slice(),credId:V.credId.slice()})}finally{K.fill(0)}}finally{V.prf.fill(0)}}static async openPairPackageBody(Z,X,W){let[V,l]=await uX({rpId:W.rpId,rpName:W.rpName,credId:W.credId,salt:W.salt});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await LW(Z,V.prf,X0);if(G!==0)return Y(G);if(K===void 0)return Y(12);try{let m;try{m=await Z.decryptXSalsa20Poly1305Combined(X,K)}catch{return Y(20)}let R=new P(m),[J,C]=R.readStruct(FW);if(m.fill(0),C!==0)return Y(C);if(J===void 0)return Y(14);let[F,b]=a.fromBytes(Z,J.masterSeed);if(J.masterSeed.fill(0),b!==0)return Y(b);if(F===void 0)return Y(12);let[T,c]=await F.#X(V.prf);if(c!==0)return Y(c);if(T===void 0)return Y(12);return d({enclave:F,hosts:J.hosts.map((k)=>({...k})),sealedMaster:T,credId:V.credId.slice()})}finally{K.fill(0)}}finally{V.prf.fill(0)}}spawnSyncWorker(Z){let X=el(),W=this.#W.slice();return Z0(X,{id:Z.id,op:"setSeed",seed:W,persist:Z.persist},[W.buffer]),X}deriveCipher(Z,X){let W=Z.slice(),V=(G)=>this.#Y(W,G),l=(G)=>this.#R(W,G);return{encrypt:Object.freeze({encrypt:V}),decrypt:Object.freeze({decrypt:l}),both:Object.freeze({encrypt:V,decrypt:l})}[X]}async deriveIdentity(Z,X=0){let W=Z,V=X,l=await this.#m(W,V),K=l.publicKey;return l.privateKey.fill(0),Object.freeze({publicKey:K,sign:(G)=>this.#C(W,V,G),kdmFor:(G)=>this.#F(W,V,G)})}async#X(Z){let[X,W]=await LW(this.#Z,Z);if(W!==0)return Y(W);if(X===void 0)return Y(12);try{let V=await this.#Z.encryptXSalsa20Poly1305Combined(this.#W,X);return pZ(V)}catch{return Y(12)}finally{X.fill(0)}}static async#l(Z,X,W){let[,V]=pZ(X);if(V!==0)return Y(V);let[l,K]=await LW(Z,W);if(K!==0)return Y(K);if(l===void 0)return Y(12);let G;try{try{G=await Z.decryptXSalsa20Poly1305Combined(X,l)}catch{return Y(20)}return a.fromBytes(Z,G)}finally{l.fill(0),G?.fill(0)}}#V(Z){let[X,W]=WZ(this.#W.slice());if(W!==0)return Y(W);if(X===void 0)return Y(10);let[V,l]=ql(X,Z);if(X.fill(0),l!==0)return Y(l);if(V===void 0)return Y(12);try{let K=new U,G=K.writeStruct(HV,V);if(G!==0)return Y(G);return d(K.result())}finally{V.masterSeed.fill(0)}}static#K(Z,X,W){if(X.byteLength===0||X.every((G)=>G===0))return Y(22);if(X.byteLength===dZ){if(X.every((R)=>R===0))return Y(22);let[G,m]=a.fromBytes(Z,X);if(m!==0)return Y(m);if(G===void 0)return Y(12);return d({enclave:G,hosts:[],credId:W})}let V=new P(X),[l,K]=V.readStruct(HV);if(K!==0)return Y(K);if(l===void 0)return Y(14);try{if(l.masterSeed.every((R)=>R===0))return Y(22);let[G,m]=a.fromBytes(Z,l.masterSeed);if(m!==0)return Y(m);if(G===void 0)return Y(12);return d({enclave:G,hosts:l.hosts.map((R)=>({...R})),credId:W})}finally{l.masterSeed.fill(0)}}async#Y(Z,X){let W=await this.#G(Z);try{return await this.#Z.encryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#R(Z,X){let W=await this.#G(Z);try{return await this.#Z.decryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#G(Z){return this.#Z.blake3(LX(this.#W,Z))}async#J(Z,X){let W=new TextEncoder().encode(Z),V=new Uint8Array(8);return new DataView(V.buffer).setBigUint64(0,BigInt(X),!1),await this.#G(LX(W,V))}async#m(Z,X){let W=await this.#J(Z,X);try{return await this.#Z.deriveEd25519KeyPair(W)}finally{W.fill(0)}}async#C(Z,X,W){let V=await this.#m(Z,X);try{return await this.#Z.signEd25519(W,V.privateKey)}finally{V.privateKey.fill(0)}}async#F(Z,X,W){let V=await this.#m(Z,X),l=LX(V.privateKey,W);V.privateKey.fill(0);try{return(await this.#Z.blake3(l)).slice(0,hZ)}finally{l.fill(0)}}}async function LW(Z,X,W=uK){if(X.byteLength<EK)return Y(10);let V=await Z.blake3(LX(X,W));return d(V.slice(0,OK))}class pW{#W;#Z;#X;#l;#V;constructor(Z){if(this.#W=Z.crypto,this.#V=Z.persistMeta,this.#l={rpId:Z.rpId,rpName:Z.rpName},Z.meta!==void 0)this.#X=qZ(Z.meta)}get meta(){return this.#X===void 0?void 0:qZ(this.#X)}setMeta(Z){this.#X=Z===void 0?void 0:qZ(Z)}async save(Z,X){if(X?.persist===!0)return Promise.reject(Error("prf-store: use wrapAndSave(enclave) to persist sealed master"));return this.#Z=Z,this.#Z}async wrapAndSave(Z,X){let[W,V]=await Z.sealWithPasskey({...this.#l,salt:X?.salt,credId:X?.credId??this.#X?.credId,createCredIfNeeded:X?.createCredIfNeeded??X?.credId===void 0,userName:"diplomatic-prf"});if(V!==0)return Y(V);if(W===void 0)return Y(12);let l={sealedMaster:W.sealedMaster,salt:W.salt,credId:W.credId};return this.#X=l,this.#Z=Z,await this.#V(qZ(l)),d(this.#Z)}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await a.unsealWithPasskey(this.#W,Z.sealedMaster,{...this.#l,salt:Z.salt,credId:Z.credId});if(W!==0)return Y(W);if(this.#Z=X.enclave,X.credId.byteLength>0&&(Z.credId===void 0||!n(Z.credId,X.credId))){let V={sealedMaster:Z.sealedMaster,salt:Z.salt,credId:X.credId.slice()};this.#X=V,await this.#V(qZ(V))}return d(X.enclave)}async adoptSealed(Z,X){return this.#X=qZ(X),this.#Z=Z,await this.#V(qZ(X)),d(this.#Z)}async wipe(){this.#Z=void 0,this.#X=void 0,await this.#V(void 0)}}function qZ(Z){let[X,W]=pZ(Z.sealedMaster.slice());return{sealedMaster:W===0&&X!==void 0?X:Z.sealedMaster,salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()}}var BK="diplomatic.pin/";function jK(Z){return BK+mZ(Z)}async function W0(Z,X,W){let V=await X.deriveIdentity(jK(W),0);return Z.blake3(V.publicKey)}async function QW(Z,X){let W=await Z.gen256BitSecureRandomSeed(),V=await W0(Z,X,W);return{n:W,h:V}}async function yW(Z,X,W){let V=await W0(Z,X,W.n);return wK(V,W.h)}function V0(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.n instanceof Uint8Array)||!(X.h instanceof Uint8Array))return;if(X.n.byteLength<1||X.h.byteLength<1)return;return{n:X.n.slice(),h:X.h.slice()}}function zW(Z){return{n:Z.n.slice(),h:Z.h.slice()}}function wK(Z,X){if(Z.byteLength!==X.byteLength)return!1;let W=0;for(let V=0;V<Z.byteLength;V++)W|=Z[V]^X[V];return W===0}var xW="prfMeta",UV="idPin",l0="idPub";class NW{#W;db;#Z;constructor(Z,X){this.db=Z,this.#Z=X}async save(Z,X){return await this.#X(Z),this.#W=Z,this.#W}async load(){return this.#W}async clearSession(){this.#W=void 0}async wipe(){this.#W=void 0;let Z=this.db.transaction(KZ,"readwrite"),X=Z.objectStore(KZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.delete(xW),X.delete(UV),X.delete(l0)})}async loadPrfMeta(){let X=this.db.transaction(KZ,"readonly").objectStore(KZ);return new Promise((W,V)=>{let l=X.get(xW);l.onsuccess=()=>{W(DK(l.result))},l.onerror=()=>V(l.error)})}async persistPrfMeta(Z){let X=this.db.transaction(KZ,"readwrite"),W=X.objectStore(KZ);return new Promise((V,l)=>{if(X.oncomplete=()=>V(),X.onerror=()=>l(X.error),Z===void 0){W.delete(xW);return}let K={sealedMaster:Z.sealedMaster.slice(),salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()};W.put(K,xW)})}async hasPrfMeta(){return await this.loadPrfMeta()!==void 0}async lastPrfCredId(){let Z=await this.loadPrfMeta();return Z?.credId===void 0?void 0:Z.credId.slice()}async openPrfStore(Z){let X=await this.loadPrfMeta();return new pW({crypto:Z.crypto??this.#Z,rpId:Z.rpId,rpName:Z.rpName,meta:X,persistMeta:(W)=>this.persistPrfMeta(W)})}async#X(Z){await this.#K(l0);let X=await this.#l();if(X!==void 0){if(!await yW(this.#Z,Z,X))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)");return}let W=await QW(this.#Z,Z);await this.#V(W)}#l(){let X=this.db.transaction(KZ,"readonly").objectStore(KZ);return new Promise((W,V)=>{let l=X.get(UV);l.onsuccess=()=>W(V0(l.result)),l.onerror=()=>V(l.error)})}#V(Z){let X=zW(Z),W=this.db.transaction(KZ,"readwrite"),V=W.objectStore(KZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error),V.put(X,UV)})}#K(Z){let X=this.db.transaction(KZ,"readwrite"),W=X.objectStore(KZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}}function DK(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.sealedMaster instanceof Uint8Array)||!(X.salt instanceof Uint8Array))return;let[W,V]=pZ(X.sealedMaster);if(V!==0||W===void 0)return;return{sealedMaster:W,salt:X.salt.slice(),credId:X.credId instanceof Uint8Array?X.credId.slice():void 0}}class iV{db;constructor(Z){this.db=Z}async enq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(CZ,"readwrite"),l=V.objectStore(CZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=mZ(m);l.put({host:Z,hash:R})}})}async deq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(CZ,"readwrite"),l=V.objectStore(CZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=mZ(m);l.delete([Z,R])}})}async list(Z){let W=this.db.transaction(CZ,"readonly").objectStore(CZ);return new Promise((V,l)=>{let K=W.getAll();K.onsuccess=()=>{let m=K.result.filter((R)=>R.host===Z).map((R)=>R.hash);V(m.map((R)=>WX(R)))},K.onerror=()=>l(K.error)})}async count(){let X=this.db.transaction(CZ,"readonly").objectStore(CZ);return new Promise((W,V)=>{let l=X.count();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(CZ,"readwrite"),X=Z.objectStore(CZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var KZ="seedMeta",lZ="hosts",CZ="uploadQueue",JZ="downloadQueue",o="messages",HX="apld",K0=3,G0="diplomatic-store-db";class uV{seed;hosts;uploads;downloads;messages;db;constructor(Z,X){this.db=Z,this.seed=new NW(Z,X),this.hosts=new gV(Z),this.uploads=new iV(Z),this.downloads=new MV(Z),this.messages=new SV(Z,X)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}async function AK(){return new Promise((Z,X)=>{let W=indexedDB.open(G0,K0);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!V.objectStoreNames.contains(KZ))V.createObjectStore(KZ);if(!V.objectStoreNames.contains(lZ))V.createObjectStore(lZ,{keyPath:"label"});if(!V.objectStoreNames.contains(CZ))V.createObjectStore(CZ,{keyPath:["host","hash"]});if(!V.objectStoreNames.contains(JZ))V.createObjectStore(JZ);let K;if(!V.objectStoreNames.contains(o))K=V.createObjectStore(o);else{if(!l)throw Error("missing upgrade transaction for messages store");K=l.objectStore(o)}if(!K.indexNames.contains(HX))K.createIndex(HX,"apld",{unique:!1})},W.onblocked=()=>{console.warn(`[DIPLOMATIC] protocol store IDB upgrade blocked (${G0} → v${K0}); waiting for other connections to close`)},W.onsuccess=()=>{let V=W.result;V.onversionchange=()=>{V.close()},Z(V)},W.onerror=()=>X(W.error??Error("protocol store IndexedDB open failed"))})}async function MW(Z){let X=await AK();if(typeof navigator<"u"&&navigator.storage?.persist)try{await Promise.race([navigator.storage.persist(),new Promise((W)=>{setTimeout(()=>W(!1),2000)})])}catch{}return new uV(X,Z)}function m0(Z){if(!Z||typeof Z!=="object")return!1;if(!("kind"in Z))return!1;return typeof Z.kind==="string"}function Y0(Z){if(typeof Z!=="number")return;return Z}function oK(Z){if(!Z||typeof Z!=="object")return;if(!("phase"in Z))return;let X=vK(Z.phase);if(X===void 0)return;let W={phase:X};if("host"in Z&&typeof Z.host==="string")W.host=Z.host;if("done"in Z&&typeof Z.done==="number")W.done=Z.done;if("total"in Z&&typeof Z.total==="number")W.total=Z.total;if("bytesDone"in Z&&typeof Z.bytesDone==="number")W.bytesDone=Z.bytesDone;if("bytesTotal"in Z&&typeof Z.bytesTotal==="number")W.bytesTotal=Z.bytesTotal;return W}function vK(Z){if(Z==="peek"||Z==="pull"||Z==="open"||Z==="exec"||Z==="push"||Z==="import"||Z==="idle"||Z==="apply")return Z==="apply"?"exec":Z;return}function R0(Z){if(!Z||typeof Z!=="object")return;if(!("numUploads"in Z)||!("numDownloads"in Z))return;if(typeof Z.numUploads!=="number"||typeof Z.numDownloads!=="number")return;let X={phase:"idle"};if("progress"in Z){let W=oK(Z.progress);if(W===void 0)return;X=W}return{numUploads:Z.numUploads,numDownloads:Z.numDownloads,progress:X}}var FZ="[DIPLOMATIC]";class EX{worker;state;store;local;nextId=1;pending=new Map;readyTimeoutMs;scheduledSync;cachedClientState={hasSeed:!1,hasHost:!1,connected:!1};cachedXferState={numUploads:0,numDownloads:0,progress:DZ};clientState;xferState;constructor(Z,X,W,V,l){this.state=Z,this.store=X,this.readyTimeoutMs=l,this.clientState=new bZ(async()=>this.cachedClientState),this.xferState=new bZ(async()=>this.cachedXferState),this.scheduledSync=new NX(V,async()=>{if(!this.worker)return;try{await this.request({id:this.allocId(),op:"sync"})}catch(K){console.error(`${FZ} worker sync after local write failed`,K)}}),this.local=new oZ(W,Z,X,()=>{throw Error(`${FZ} local writer has no transport (use worker for network)`)},MZ,!0,void 0,void 0,()=>{this.scheduledSync.schedule()}),this.local.xferState.listen((K)=>{this.cachedXferState={numUploads:K.numUploads,numDownloads:K.numDownloads,progress:this.cachedXferState.progress},this.xferState.emit()})}bindWorker(Z){let X=this.worker;if(X){X.onmessage=null,X.onerror=null,X.onmessageerror=null;try{X.terminate()}catch{}}this.worker=Z,Z.onmessage=(W)=>{this.onMessage(W.data)},Z.onerror=(W)=>{console.error(`${FZ} worker error`,W),this.failPending(Error(`${FZ} worker failed to load`))},Z.onmessageerror=()=>{this.failPending(Error(`${FZ} worker message error`))}}failPending(Z){for(let[,X]of this.pending)X.reject(Z);this.pending.clear()}async flushScheduledSync(){await this.scheduledSync.flush()}static async open(Z,X,W={}){let V=W.clock??new LZ,l=W.syncDebounceMs??ZW,K=W.readyTimeoutMs??15000,G=new EX(Z,X,V,l,K);return await G.hydrateStateFromStore(X),G}async hydrateStateFromStore(Z){await this.loadSession(!1);let X=await Z.uploads.count(),W=await Z.downloads.count();this.cachedXferState={numUploads:X,numDownloads:W,progress:DZ}}async loadSession(Z){let X=await this.store.seed.load(),W=await this.store.hosts.list();this.cachedClientState={hasSeed:X!==void 0,hasHost:Array.from(W).length>0,connected:Z}}async pullRemoteXfer(){let Z=await this.request({id:this.allocId(),op:"getXferState"}),X=R0(Z);if(X!==void 0)this.cachedXferState=X}requireWorker(){if(!this.worker)throw Error(`${FZ} no sync worker; call setSeed first`);return this.worker}async ping(){if(await this.request({id:this.allocId(),op:"ping"})!=="pong")throw Error(`${FZ} worker ping failed`)}terminate(){this.scheduledSync.cancel();let Z=this.worker;if(this.worker=void 0,Z)try{Z.terminate()}catch{}this.failPending(Error(`${FZ} worker terminated`))}onMessage(Z){if(!m0(Z))return;let X=Z;switch(X.kind){case"ready":return;case"initError":{this.failPending(Error(`${FZ} worker init failed: ${X.message}`));return}case"clientState":{if(this.cachedClientState.connected===X.connected)return;this.cachedClientState={...this.cachedClientState,connected:X.connected},this.clientState.emit();return}case"xferState":{this.cachedXferState=X.state,this.xferState.emit();return}case"dirty":{this.state.refresh(X.eids.map(fK));return}case"wiped":{this.state.clear();return}case"reply":{let W=this.pending.get(X.id);if(!W)return;if(this.pending.delete(X.id),X.ok)W.resolve(X.result);else W.reject(new OX(X.status));return}default:return}}allocId(){let Z=this.nextId;return this.nextId+=1,Z}request(Z,X){let W=this.requireWorker();return new Promise((V,l)=>{if(this.pending.set(Z.id,{resolve:V,reject:l}),X&&X.length>0)W.postMessage(Z,X);else W.postMessage(Z)})}async requestStatus(Z,X){try{let W=await this.request(Z,X),V=Y0(W);if(V!==void 0)return V;return 0}catch(W){if(W instanceof OX)return W.status;return 12}}serializeHost(Z){return{handle:Z.handle.href,label:Z.label,idx:Z.idx??0}}async setSeed(Z,X){await this.local.setSeed(Z,X),await this.loadSession(!1),this.clientState.emit();let W=this.allocId(),V=this.readyTimeoutMs;await new Promise((l,K)=>{let G=void 0,m=(R)=>{if(G!==void 0)clearTimeout(G);R()};this.pending.set(W,{resolve:(R)=>m(()=>l(R)),reject:(R)=>m(()=>K(R))}),G=setTimeout(()=>{this.pending.delete(W),K(Error(`${FZ} setSeed worker timeout after ${V}ms`))},V);try{let R=Z.spawnSyncWorker({id:W,persist:X?.persist});this.bindWorker(R)}catch(R){if(this.pending.delete(W),G!==void 0)clearTimeout(G);K(R instanceof Error?R:Error(String(R)))}});try{await this.pullRemoteXfer()}catch{}}async link(Z,X=!0){await this.local.link(Z,!1),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),await this.request({id:this.allocId(),op:"link",host:this.serializeHost(Z),connect:X})}async unlink(Z){if(await this.local.unlink(Z),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),!this.worker)return;await this.request({id:this.allocId(),op:"unlink",label:Z})}async hosts(){return this.local.hosts()}async connect(Z=!0,X=!0){if(!this.worker)return;await this.request({id:this.allocId(),op:"connect",listen:Z,sync:X})}async disconnect(){if(!this.worker)return;await this.request({id:this.allocId(),op:"disconnect"})}async insertRaw(Z){return this.local.insertRaw(Z)}async updateRaw(Z,X,W){return this.local.updateRaw(Z,X,W)}async insert(Z){return this.local.insert(Z)}async update(Z){return this.local.update(Z)}async delete(Z){return this.local.delete(Z)}async genEID(Z){return this.local.genEID(Z)}async sync(){if(!this.worker)return 0;return this.requestStatus({id:this.allocId(),op:"sync"})}async rebuild(Z){return this.scheduledSync.cancel(),await this.scheduledSync.flush(),this.requestStatus({id:this.allocId(),op:"rebuild",checkHost:Z?.checkHost})}async listMsgs(Z){return this.local.listMsgs(Z)}async countMsgs(Z){return this.local.countMsgs(Z)}async reconcile(Z,X){try{let W=await this.request({id:this.allocId(),op:"reconcile",hostLabel:Z,pull:X?.pull,push:X?.push,sync:X?.sync});if(!$K(W))return Y(12);return d(W)}catch(W){if(W instanceof OX&&W.status!==0)return Y(W.status);return Y(12)}}async msgcheck(){let Z=await this.request({id:this.allocId(),op:"msgcheck"});if(!(Z instanceof Uint8Array))throw Error(`${FZ} msgcheck: expected Uint8Array`);return Z}async entcheck(){let Z=await this.request({id:this.allocId(),op:"entcheck"});if(!(Z instanceof Uint8Array))throw Error(`${FZ} entcheck: expected Uint8Array`);return Z}async wipe(Z){if(await this.local.wipe(Z),this.worker)await this.request({id:this.allocId(),op:"wipe",msgs:Z?.msgs,ents:Z?.ents,meta:Z?.meta,seed:Z?.seed});await this.hydrateStateFromStore(this.store),this.clientState.emit(),this.xferState.emit()}async import(Z){let X=new Uint8Array(await Z.arrayBuffer());return this.requestStatus({id:this.allocId(),op:"import",bytes:X},[X.buffer])}async export(Z,X){try{let W=await this.request({id:this.allocId(),op:"export"});if(!(W instanceof Uint8Array))return 12;let V=new Blob([W.slice()]);return WW(V,Z),0}catch(W){if(W instanceof OX)return W.status;return 12}}}class OX extends Error{status;constructor(Z){super(`WorkerReplyError: ${x[Z]}`);this.status=Z;this.name="WorkerReplyError"}}function $K(Z){if(!Z||typeof Z!=="object")return!1;let X=Z;return X.msgcheck instanceof Uint8Array&&X.msgcheck.length===32&&typeof X.numBags==="number"&&typeof X.numDupes==="number"}function fK(Z){return Z}var TX="[DIPLOMATIC]";async function gW(Z){let X=Z.clock??new LZ;if(Z.worker===!0&&qK(Z)!==void 0)throw Error(`${TX} worker path requires IndexedDB on both sides; do not pass store (got a custom store)`);if(Z.worker!==!0){console.info(`${TX} sync on main thread `+"(no worker — app did not request a worker)");let l=await J0(Z.store);return nK(X,Z.state,l)}if(typeof Worker>"u")throw Error(`${TX} worker: true but Worker API is unavailable`);let W=await J0(void 0),V=await EX.open(Z.state,W,{readyTimeoutMs:Z.readyTimeoutMs,clock:X,syncDebounceMs:Z.syncDebounceMs});return console.info(`${TX} worker-mode client open (sync Worker starts on setSeed via Enclave)`),{client:V,mode:"worker",dispose:()=>{console.info(`${TX} terminating sync worker`),V.terminate()}}}function qK(Z){if("store"in Z)return Z.store;return}async function nK(Z,X,W){let V=new oZ(Z,X,W,nX,MZ);return{client:V,mode:"main",dispose:()=>{V.disconnect()}}}async function J0(Z){if(Z!==void 0)return Z;if(typeof indexedDB>"u")throw Error(`${TX} IndexedDB is unavailable; pass store explicitly (e.g. new MemoryStore(crypto))`);return MW(MZ)}function _K(Z){let[X,W]=OV();return SW(()=>{async function V(){let K=await Z.clientState.get();W(K)}let l=Z.clientState.listen(V);return V(),()=>{l()}},[Z]),X}function aK(Z){let[X,W]=OV();return SW(()=>{async function V(){let K=await Z.xferState.get();W(K)}let l=Z.xferState.listen(V);return V(),()=>{l()}},[Z]),X}function rK(Z){SW(()=>{async function X(){try{if(!(await Z.clientState.get()).hasSeed)return;await Z.connect(),await Z.sync()}catch(K){console.error("reconnectAndSync failed",K)}}function W(){X()}function V(){if(typeof document<"u"&&document.visibilityState==="visible")X()}function l(){X()}if(globalThis.addEventListener("online",W),typeof document<"u")document.addEventListener("visibilitychange",V);return globalThis.addEventListener("focus",l),globalThis.addEventListener("pageshow",l),()=>{if(globalThis.removeEventListener("online",W),typeof document<"u")document.removeEventListener("visibilitychange",V);globalThis.removeEventListener("focus",l),globalThis.removeEventListener("pageshow",l)}},[Z])}function sK(Z={}){let X=Z.clock??new LZ,{seed:W,host:V,readyTimeoutMs:l}=Z,K=Z.worker===!0,G="store"in Z?Z.store:void 0,[m,R]=OV({stateMgr:rW});return SW(()=>{let J=!1,C;return(async()=>{let F=await WV();if(J)return;let b=tX(F),T=K?await gW({state:b,clock:X,worker:!0,readyTimeoutMs:l}):await gW({state:b,clock:X,store:G,readyTimeoutMs:l});if(J){T.dispose();return}C=T.dispose;let{client:c,mode:k}=T;if(W)await c.setSeed(W);if(V)await c.link(V);if(J){C();return}R({client:c,entDB:F,stateMgr:b,mode:k,error:void 0})})().catch((F)=>{let b=F instanceof Error?F:Error(String(F));if(console.error("[DIPLOMATIC] useClient init failed",b),!J)R((T)=>({...T,client:void 0,error:b}))}),()=>{J=!0,C?.()}},[X,W,V,K,G,l]),m}import{use as tK,useEffect as C0,useRef as eK,useState as ZG}from"react";function F0(Z,X,W){let[V,l]=ZG();return C0(()=>{async function K(){let G=await W();l(G)}return K(),Z.on(X,K),()=>{Z.off(X,K)}},[Z,X,W]),V}function XG(Z,X,W){let V=eK(W());return C0(()=>{async function l(){V.current=W()}return Z.on(X,l),()=>{Z.off(X,l)}},[Z,X,W]),tK(V.current)}function d0(Z,X){return`${Z}:${X}`}class EV{queue=new Map;async enq(Z){for(let X of Z){let W=d0(X.host,X.seq);this.queue.set(W,X)}}async deq(Z,X){for(let W of X){let V=d0(Z,W);this.queue.delete(V)}}async list(){let Z=[];for(let X of this.queue.values())Z.push(X);return Z}async count(){return this.queue.size}async wipe(){this.queue.clear()}}function WG(Z,X){if(X.setLastSeq!==void 0)Z.lastSeq=X.setLastSeq;else if(X.lastSeq!==void 0&&X.lastSeq>Z.lastSeq)Z.lastSeq=X.lastSeq}class BV{hosts=new Map;async add(Z){let X=this.hosts.get(Z.label),W=X!==void 0&&X.handle===Z.handle&&(X.idx??0)===(Z.idx??0),V={...Z,lastSeq:W?X.lastSeq:0,clockOffset:W?X.clockOffset:void 0,subscription:W?X.subscription:void 0};this.hosts.set(Z.label,V)}async touch(Z,X){await this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.hosts.get(Z);if(!W)return;WG(W,X),this.hosts.set(Z,{...W})}async get(Z){return this.hosts.get(Z)}async set(Z,X){let W=this.hosts.get(Z);if(!W)return 13;return this.hosts.set(Z,{...W,...X}),0}async del(Z){this.hosts.delete(Z)}async list(){return this.hosts.values()}async wipe(){this.hosts.clear()}}class jV{crypto;messages=new Map;constructor(Z){this.crypto=Z}async add(Z){let X=[];for(let{key:W,data:V}of Z)this.messages.set(S(W),V),X.push(0);return X}async del(Z){for(let X of Z)this.messages.delete(S(X))}async get(Z){let X=this.messages.get(S(Z));if(X)return await iZ(Z,X,this.crypto);return}async has(Z){return this.messages.has(S(Z))}async list(Z){let X=Z?.apld,W=Z?.body!==!1,V=[];for(let[l,K]of this.messages){if(X!==void 0&&JX(K.apld)!==X)continue;let G=e(l);V.push(await iZ(G,K,this.crypto,{body:W}))}return V}async count(Z){if(Z===void 0)return this.messages.size;let X=0;for(let W of this.messages.values())if(JX(W.apld)===Z)X++;return X}async listKeys(){let Z=[];for(let X of this.messages.keys())Z.push(e(X));return Z}async last(Z){let X;for(let[W,V]of this.messages){if(n(Z,V.eid)===!1)continue;let l=e(W);if(X===void 0)X={hash:l,data:V};else if((V.ctr??0)>(X.data.ctr??0)||(V.ctr??0)===(X.data.ctr??0)&&(V.off??0)>(X.data.off??0))X={hash:l,data:V}}if(X)return await iZ(X.hash,X.data,this.crypto);return}async markApplied(Z){for(let X of Z){let W=this.messages.get(S(X));if(!W)continue;AZ(W,UZ)}}async markFailed(Z){for(let{key:X,err:W}of Z){let V=this.messages.get(S(X));if(!V)continue;AZ(V,TZ,W)}}async wipe(){this.messages.clear()}}class wV{#W;#Z;#X;constructor(Z){this.#Z=Z}async save(Z,X){if(this.#X!==void 0){if(!await yW(this.#Z,Z,this.#X))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)")}else this.#X=await QW(this.#Z,Z);return this.#W=Z,this.#W}async load(){return this.#W}async wipe(){this.#W=void 0,this.#X=void 0}peekPin(){return this.#X===void 0?void 0:zW(this.#X)}}class DV{queue=new Map;async enq(Z,X){let W=this.queue.get(Z)||new Set;this.queue.set(Z,W);for(let V of X)W.add(mZ(V))}async deq(Z,X){let W=this.queue.get(Z);if(W)for(let V of X)W.delete(mZ(V))}async list(Z){let X=this.queue.get(Z);if(!X)return[];let W=[];for(let V of X)W.push(WX(V));return W}async count(){let Z=0;for(let X of this.queue.values())Z+=X.size;return Z}async wipe(){this.queue.clear()}}class b0{seed;hosts=new BV;uploads=new DV;downloads=new EV;messages;constructor(Z){this.seed=new wV(Z),this.messages=new jV(Z)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}class T0{singletonType;latest;latestOff=-1;emitter=new SZ;constructor(Z){this.singletonType=Z}async apply(Z){for(let X of Z){let W=new P(X.eid),[V,l]=W.readStruct(r);if(l!==0)continue;let K=new U;K.writeVarString(this.singletonType);let G=K.result();if(V.id.length===G.length&&V.id.every((m,R)=>m===G[R])){if(this.latest===void 0||X.off>this.latestOff)this.latestOff=X.off,this.latest=X.bod,this.emitter.emit(this.singletonType,null)}}return Z.map(()=>0)}clear=async()=>{return this.latest=void 0,this.latestOff=-1,this.emitter.emit(this.singletonType,null),0};notify=(Z)=>{for(let X of Z)if(X===this.singletonType)this.emitter.emit(this.singletonType,null)};refresh=async(Z)=>{this.notify([this.singletonType])};on=(Z,X)=>{this.emitter.addEventListener(Z,X)};off=(Z,X)=>{this.emitter.removeEventListener(Z,X)}}var c0={capable(){return sl()},async createCred(Z){return bW(Z)},async write(Z,X,W){return UX(Z,X,W)},async read(Z,X){let[W,V]=await TW(Z,X);if(V!==0||W===void 0)return Y(V);return d(W.blob)}};class k0{#W;#Z;#X;#l;#V;constructor(Z){if(this.#W=Z.crypto,this.#l=Z.rpId,this.#V=Z.rpName,Z.credId!==void 0)this.#X=Z.credId.slice()}get credId(){if(this.#X===void 0)return;return this.#X.slice()}setCredId(Z){this.#X=Z===void 0?void 0:Z.slice()}async save(Z,X){if(X?.persist!==!0)return this.#Z=Z,this.#Z;let[W,V]=await Z.persistToLargeBlob([],{rpId:this.#l,rpName:this.#V,credId:this.#X});if(V!==0||W===void 0)return Promise.reject(Error(`persistToLargeBlob status ${V}`));return this.#X=W,this.#Z=Z,this.#Z}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await a.fromLargeBlob(this.#W,{rpId:this.#l,rpName:this.#V,credId:Z});if(W!==0||X===void 0)return Y(W);return this.#Z=X.enclave,d(X.enclave)}async wipe(){let Z=this.#X;if(Z!==void 0){let X=await a.clearLargeBlob(Z,{rpId:this.#l});if(X!==0)return Promise.reject(Error(`clearLargeBlob status ${X}`))}this.#Z=void 0,this.#X=void 0}}var BX=1,HW={encode(Z,X){let W=Z.writeVarInt(X.v);if(W!==0)return W;let V=Z.writeVarBytes(X.salt);if(V!==0)return V;let l=Z.writeVarBytes(X.credId);if(l!==0)return l;return Z.writeVarBytes(X.body)},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);if(K===void 0)return Y(14);let[m,R]=Z.readVarBytes();if(R!==0)return Y(R);if(m===void 0)return Y(14);return d({v:X,salt:V,credId:K,body:m})}};var hW={PREFIX:"dip1:",VERSION:BX,async seal(Z,X,W,V){let[l,K]=await X.sealPairPackageBody(W,V);if(K!==0)return Y(K);if(l===void 0)return Y(12);let G=new U,m=G.writeStruct(HW,{v:BX,salt:l.salt,credId:l.credId,body:l.body});if(m!==0)return Y(m);return d(hW.PREFIX+BW(G.result()))},async open(Z,X,W){let V=X.trim();if(!V.startsWith(hW.PREFIX))return Y(10);let l;try{l=jW(V.slice(hW.PREFIX.length))}catch{return Y(10)}let K=new P(l),[G,m]=K.readStruct(HW);if(m!==0)return Y(m);if(G===void 0)return Y(14);if(G.v!==BX)return Y(14);let[R,J]=await a.openPairPackageBody(Z,G.body,{...W,salt:G.salt,credId:G.credId.byteLength>0?G.credId:void 0});if(J!==0)return Y(J);if(R===void 0)return Y(12);return d({enclave:R.enclave,hosts:R.hosts,salt:G.salt.slice(),credId:R.credId,sealedMaster:R.sealedMaster})}};async function hb(Z,X){let W=await MW(MZ),V=new oZ(new LZ,Z,W,nX,MZ);return{client:V,setSeed:async(K)=>{let[G,m]=a.fromBytes(MZ,WX(K));if(m!==0||G===void 0)throw Error(`invalid seed (${m})`);await W.seed.save(G),await W.hosts.add({handle:X,label:"host",idx:0}),await V.connect()}}}export{rK as useSyncOnResume,XG as useStateWatcherSuspense,F0 as useStateWatcher,aK as useClientXferState,_K as useClientState,sK as useClient,XW as shouldEmitItemProgress,AZ as setApld,VV as revFromHead,zX as revFromEntity,PK as prfCapable,MW as openIDBStore,WV as openEntDB,gW as openDiplomaticClient,rW as nullStateManager,mK as nullEntDB,Tl as normalizeTags,GK as isTombstone,KV as isTerminalApplyFailure,JK as isPendingApply,D as isLiveEnt,RK as isApldState,DZ as idleProgress,WX as htob,nX as hostHTTPTransport,hb as genWebClient,$0 as genSingletonEID,tX as entStateManager,Jl as encodeEntRev,r as eidCodec,dW as defaultWebAuthnRpId,RX as defaultPeekProgressEvery,MZ as crypto,Rl as cmpBytes,VX as checksumSet,QX as checksumEntRevs,mZ as btoh,BW as btob64url,S as btob64,jW as b64urltob,e as b64tob,pZ as asSealedMasterKey,JX as apldFromStored,EX as WorkerClient,SZ as TypedEventEmitter,oZ as SyncClient,x as Status,yX as StateManager,T0 as SingletonStateManager,aW as SEALED_MASTER_KEY_LEN,pW as PrfSeedStore,k0 as PasskeySeedStore,hW as PairPackage,b0 as MemoryStore,dZ as MASTER_SEED_LEN,c0 as LargeBlob,uV as IDBStore,NW as IDBSeedStore,fW as HTTPTransport,XV as EntIDB,sX as EntDBMemory,U as Encoder,a as Enclave,P as Decoder,iX as DEFAULT_PRF_SALT,LZ as Clock,xX as CachedEntDB,QZ as APLD_PENDING,TZ as APLD_ERROR,UZ as APLD_APPLIED};
|
|
1
|
+
function $V(Z){let X=Z.length,W=0,V=0;while(V<X){let l=Z.charCodeAt(V++);if((l&4294967168)===0){W++;continue}else if((l&4294965248)===0)W+=2;else{if(l>=55296&&l<=56319){if(V<X){let K=Z.charCodeAt(V);if((K&64512)===56320)++V,l=((l&1023)<<10)+(K&1023)+65536}}if((l&4294901760)===0)W+=3;else W+=4}}return W}function I0(Z,X,W){let V=Z.length,l=W,K=0;while(K<V){let G=Z.charCodeAt(K++);if((G&4294967168)===0){X[l++]=G;continue}else if((G&4294965248)===0)X[l++]=G>>6&31|192;else{if(G>=55296&&G<=56319){if(K<V){let m=Z.charCodeAt(K);if((m&64512)===56320)++K,G=((G&1023)<<10)+(m&1023)+65536}}if((G&4294901760)===0)X[l++]=G>>12&15|224,X[l++]=G>>6&63|128;else X[l++]=G>>18&7|240,X[l++]=G>>12&63|128,X[l++]=G>>6&63|128}X[l++]=G&63|128}}var Q0=new TextEncoder,p0=50;function y0(Z,X,W){Q0.encodeInto(Z,X.subarray(W))}function oV(Z,X,W){if(Z.length>p0)y0(Z,X,W);else I0(Z,X,W)}var z0=4096;function PW(Z,X,W){let V=X,l=V+W,K=[],G="";while(V<l){let m=Z[V++];if((m&128)===0)K.push(m);else if((m&224)===192){let R=Z[V++]&63;K.push((m&31)<<6|R)}else if((m&240)===224){let R=Z[V++]&63,J=Z[V++]&63;K.push((m&31)<<12|R<<6|J)}else if((m&248)===240){let R=Z[V++]&63,J=Z[V++]&63,C=Z[V++]&63,F=(m&7)<<18|R<<12|J<<6|C;if(F>65535)F-=65536,K.push(F>>>10&1023|55296),F=56320|F&1023;K.push(F)}else K.push(m);if(K.length>=z0)G+=String.fromCharCode(...K),K.length=0}if(K.length>0)G+=String.fromCharCode(...K);return G}var N0=new TextDecoder,x0=200;function g0(Z,X,W){let V=Z.subarray(X,X+W);return N0.decode(V)}function qV(Z,X,W){if(W>x0)return g0(Z,X,W);else return PW(Z,X,W)}class sZ{type;data;constructor(Z,X){this.type=Z,this.data=X}}class XZ extends Error{constructor(Z){super(Z);let X=Object.create(XZ.prototype);Object.setPrototypeOf(this,X),Object.defineProperty(this,"name",{configurable:!0,enumerable:!1,value:XZ.name})}}var tZ=4294967295;function fV(Z,X,W){let V=W/4294967296,l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function DX(Z,X,W){let V=Math.floor(W/4294967296),l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function AX(Z,X){let W=Z.getInt32(X),V=Z.getUint32(X+4);return W*4294967296+V}function nV(Z,X){let W=Z.getUint32(X),V=Z.getUint32(X+4);return W*4294967296+V}var M0=-1,H0=4294967295,h0=17179869183;function S0({sec:Z,nsec:X}){if(Z>=0&&X>=0&&Z<=h0)if(X===0&&Z<=H0){let W=new Uint8Array(4);return new DataView(W.buffer).setUint32(0,Z),W}else{let W=Z/4294967296,V=Z&4294967295,l=new Uint8Array(8),K=new DataView(l.buffer);return K.setUint32(0,X<<2|W&3),K.setUint32(4,V),l}else{let W=new Uint8Array(12),V=new DataView(W.buffer);return V.setUint32(0,X),DX(V,4,Z),W}}function P0(Z){let X=Z.getTime(),W=Math.floor(X/1000),V=(X-W*1000)*1e6,l=Math.floor(V/1e9);return{sec:W+l,nsec:V-l*1e9}}function U0(Z){if(Z instanceof Date){let X=P0(Z);return S0(X)}else return null}function u0(Z){let X=new DataView(Z.buffer,Z.byteOffset,Z.byteLength);switch(Z.byteLength){case 4:{let W=X.getUint32(0),V=0;return{sec:W,nsec:0}}case 8:{let W=X.getUint32(0),V=X.getUint32(4),l=(W&3)*4294967296+V,K=W>>>2;return{sec:l,nsec:K}}case 12:{let W=AX(X,4),V=X.getUint32(0);return{sec:W,nsec:V}}default:throw new XZ(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${Z.length}`)}}function i0(Z){let X=u0(Z);return new Date(X.sec*1000+X.nsec/1e6)}var _V={type:M0,encode:U0,decode:i0};class eZ{static defaultCodec=new eZ;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(_V)}register({type:Z,encode:X,decode:W}){if(Z>=0)this.encoders[Z]=X,this.decoders[Z]=W;else{let V=-1-Z;this.builtInEncoders[V]=X,this.builtInDecoders[V]=W}}tryToEncode(Z,X){for(let W=0;W<this.builtInEncoders.length;W++){let V=this.builtInEncoders[W];if(V!=null){let l=V(Z,X);if(l!=null){let K=-1-W;return new sZ(K,l)}}}for(let W=0;W<this.encoders.length;W++){let V=this.encoders[W];if(V!=null){let l=V(Z,X);if(l!=null)return new sZ(W,l)}}if(Z instanceof sZ)return Z;return null}decode(Z,X,W){let V=X<0?this.builtInDecoders[-1-X]:this.decoders[X];if(V)return V(Z,X,W);else return new sZ(X,Z)}}function O0(Z){return Z instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&Z instanceof SharedArrayBuffer}function kX(Z){if(Z instanceof Uint8Array)return Z;else if(ArrayBuffer.isView(Z))return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength);else if(O0(Z))return new Uint8Array(Z);else return Uint8Array.from(Z)}var j0=100,B0=2048;class vX{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??eZ.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.maxDepth=Z?.maxDepth??j0,this.initialBufferSize=Z?.initialBufferSize??B0,this.sortKeys=Z?.sortKeys??!1,this.forceFloat32=Z?.forceFloat32??!1,this.ignoreUndefined=Z?.ignoreUndefined??!1,this.forceIntegerToFloat=Z?.forceIntegerToFloat??!1,this.pos=0,this.view=new DataView(new ArrayBuffer(this.initialBufferSize)),this.bytes=new Uint8Array(this.view.buffer)}clone(){return new vX({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,maxDepth:this.maxDepth,initialBufferSize:this.initialBufferSize,sortKeys:this.sortKeys,forceFloat32:this.forceFloat32,ignoreUndefined:this.ignoreUndefined,forceIntegerToFloat:this.forceIntegerToFloat})}reinitializeState(){this.pos=0}encodeSharedRef(Z){if(this.entered)return this.clone().encodeSharedRef(Z);try{return this.entered=!0,this.reinitializeState(),this.doEncode(Z,1),this.bytes.subarray(0,this.pos)}finally{this.entered=!1}}encode(Z){if(this.entered)return this.clone().encode(Z);try{return this.entered=!0,this.reinitializeState(),this.doEncode(Z,1),this.bytes.slice(0,this.pos)}finally{this.entered=!1}}doEncode(Z,X){if(X>this.maxDepth)throw Error(`Too deep objects in depth ${X}`);if(Z==null)this.encodeNil();else if(typeof Z==="boolean")this.encodeBoolean(Z);else if(typeof Z==="number")if(!this.forceIntegerToFloat)this.encodeNumber(Z);else this.encodeNumberAsFloat(Z);else if(typeof Z==="string")this.encodeString(Z);else if(this.useBigInt64&&typeof Z==="bigint")this.encodeBigInt64(Z);else this.encodeObject(Z,X)}ensureBufferSizeToWrite(Z){let X=this.pos+Z;if(this.view.byteLength<X)this.resizeBuffer(X*2)}resizeBuffer(Z){let X=new ArrayBuffer(Z),W=new Uint8Array(X),V=new DataView(X);W.set(this.bytes),this.view=V,this.bytes=W}encodeNil(){this.writeU8(192)}encodeBoolean(Z){if(Z===!1)this.writeU8(194);else this.writeU8(195)}encodeNumber(Z){if(!this.forceIntegerToFloat&&Number.isSafeInteger(Z))if(Z>=0)if(Z<128)this.writeU8(Z);else if(Z<256)this.writeU8(204),this.writeU8(Z);else if(Z<65536)this.writeU8(205),this.writeU16(Z);else if(Z<4294967296)this.writeU8(206),this.writeU32(Z);else if(!this.useBigInt64)this.writeU8(207),this.writeU64(Z);else this.encodeNumberAsFloat(Z);else if(Z>=-32)this.writeU8(224|Z+32);else if(Z>=-128)this.writeU8(208),this.writeI8(Z);else if(Z>=-32768)this.writeU8(209),this.writeI16(Z);else if(Z>=-2147483648)this.writeU8(210),this.writeI32(Z);else if(!this.useBigInt64)this.writeU8(211),this.writeI64(Z);else this.encodeNumberAsFloat(Z);else this.encodeNumberAsFloat(Z)}encodeNumberAsFloat(Z){if(this.forceFloat32)this.writeU8(202),this.writeF32(Z);else this.writeU8(203),this.writeF64(Z)}encodeBigInt64(Z){if(Z>=BigInt(0))this.writeU8(207),this.writeBigUint64(Z);else this.writeU8(211),this.writeBigInt64(Z)}writeStringHeader(Z){if(Z<32)this.writeU8(160+Z);else if(Z<256)this.writeU8(217),this.writeU8(Z);else if(Z<65536)this.writeU8(218),this.writeU16(Z);else if(Z<4294967296)this.writeU8(219),this.writeU32(Z);else throw Error(`Too long string: ${Z} bytes in UTF-8`)}encodeString(Z){let W=$V(Z);this.ensureBufferSizeToWrite(5+W),this.writeStringHeader(W),oV(Z,this.bytes,this.pos),this.pos+=W}encodeObject(Z,X){let W=this.extensionCodec.tryToEncode(Z,this.context);if(W!=null)this.encodeExtension(W);else if(Array.isArray(Z))this.encodeArray(Z,X);else if(ArrayBuffer.isView(Z))this.encodeBinary(Z);else if(typeof Z==="object")this.encodeMap(Z,X);else throw Error(`Unrecognized object: ${Object.prototype.toString.apply(Z)}`)}encodeBinary(Z){let X=Z.byteLength;if(X<256)this.writeU8(196),this.writeU8(X);else if(X<65536)this.writeU8(197),this.writeU16(X);else if(X<4294967296)this.writeU8(198),this.writeU32(X);else throw Error(`Too large binary: ${X}`);let W=kX(Z);this.writeU8a(W)}encodeArray(Z,X){let W=Z.length;if(W<16)this.writeU8(144+W);else if(W<65536)this.writeU8(220),this.writeU16(W);else if(W<4294967296)this.writeU8(221),this.writeU32(W);else throw Error(`Too large array: ${W}`);for(let V of Z)this.doEncode(V,X+1)}countWithoutUndefined(Z,X){let W=0;for(let V of X)if(Z[V]!==void 0)W++;return W}encodeMap(Z,X){let W=Object.keys(Z);if(this.sortKeys)W.sort();let V=this.ignoreUndefined?this.countWithoutUndefined(Z,W):W.length;if(V<16)this.writeU8(128+V);else if(V<65536)this.writeU8(222),this.writeU16(V);else if(V<4294967296)this.writeU8(223),this.writeU32(V);else throw Error(`Too large map object: ${V}`);for(let l of W){let K=Z[l];if(!(this.ignoreUndefined&&K===void 0))this.encodeString(l),this.doEncode(K,X+1)}}encodeExtension(Z){if(typeof Z.data==="function"){let W=Z.data(this.pos+6),V=W.length;if(V>=4294967296)throw Error(`Too large extension object: ${V}`);this.writeU8(201),this.writeU32(V),this.writeI8(Z.type),this.writeU8a(W);return}let X=Z.data.length;if(X===1)this.writeU8(212);else if(X===2)this.writeU8(213);else if(X===4)this.writeU8(214);else if(X===8)this.writeU8(215);else if(X===16)this.writeU8(216);else if(X<256)this.writeU8(199),this.writeU8(X);else if(X<65536)this.writeU8(200),this.writeU16(X);else if(X<4294967296)this.writeU8(201),this.writeU32(X);else throw Error(`Too large extension object: ${X}`);this.writeI8(Z.type),this.writeU8a(Z.data)}writeU8(Z){this.ensureBufferSizeToWrite(1),this.view.setUint8(this.pos,Z),this.pos++}writeU8a(Z){let X=Z.length;this.ensureBufferSizeToWrite(X),this.bytes.set(Z,this.pos),this.pos+=X}writeI8(Z){this.ensureBufferSizeToWrite(1),this.view.setInt8(this.pos,Z),this.pos++}writeU16(Z){this.ensureBufferSizeToWrite(2),this.view.setUint16(this.pos,Z),this.pos+=2}writeI16(Z){this.ensureBufferSizeToWrite(2),this.view.setInt16(this.pos,Z),this.pos+=2}writeU32(Z){this.ensureBufferSizeToWrite(4),this.view.setUint32(this.pos,Z),this.pos+=4}writeI32(Z){this.ensureBufferSizeToWrite(4),this.view.setInt32(this.pos,Z),this.pos+=4}writeF32(Z){this.ensureBufferSizeToWrite(4),this.view.setFloat32(this.pos,Z),this.pos+=4}writeF64(Z){this.ensureBufferSizeToWrite(8),this.view.setFloat64(this.pos,Z),this.pos+=8}writeU64(Z){this.ensureBufferSizeToWrite(8),fV(this.view,this.pos,Z),this.pos+=8}writeI64(Z){this.ensureBufferSizeToWrite(8),DX(this.view,this.pos,Z),this.pos+=8}writeBigUint64(Z){this.ensureBufferSizeToWrite(8),this.view.setBigUint64(this.pos,Z),this.pos+=8}writeBigInt64(Z){this.ensureBufferSizeToWrite(8),this.view.setBigInt64(this.pos,Z),this.pos+=8}}function wZ(Z,X){return new vX(X).encodeSharedRef(Z)}function $X(Z){return`${Z<0?"-":""}0x${Math.abs(Z).toString(16).padStart(2,"0")}`}var E0=16,w0=16;class UW{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(Z=E0,X=w0){this.maxKeyLength=Z,this.maxLengthPerKey=X,this.caches=[];for(let W=0;W<this.maxKeyLength;W++)this.caches.push([])}canBeCached(Z){return Z>0&&Z<=this.maxKeyLength}find(Z,X,W){let V=this.caches[W-1];Z:for(let l of V){let K=l.bytes;for(let G=0;G<W;G++)if(K[G]!==Z[X+G])continue Z;return l.str}return null}store(Z,X){let W=this.caches[Z.length-1],V={bytes:Z,str:X};if(W.length>=this.maxLengthPerKey)W[Math.random()*W.length|0]=V;else W.push(V)}decode(Z,X,W){let V=this.find(Z,X,W);if(V!=null)return this.hit++,V;this.miss++;let l=PW(Z,X,W),K=Uint8Array.prototype.slice.call(Z,X,X+W);return this.store(K,l),l}}var uW="array",LX="map_key",rV="map_value",D0=(Z)=>{if(typeof Z==="string"||typeof Z==="number")return Z;throw new XZ("The type of key must be string or number but "+typeof Z)};class sV{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(Z){let X=this.getUninitializedStateFromPool();X.type=uW,X.position=0,X.size=Z,X.array=Array(Z)}pushMapState(Z){let X=this.getUninitializedStateFromPool();X.type=LX,X.readCount=0,X.size=Z,X.map={}}getUninitializedStateFromPool(){if(this.stackHeadPosition++,this.stackHeadPosition===this.stack.length){let Z={type:void 0,size:0,array:void 0,position:0,readCount:0,map:void 0,key:null};this.stack.push(Z)}return this.stack[this.stackHeadPosition]}release(Z){if(this.stack[this.stackHeadPosition]!==Z)throw Error("Invalid stack state. Released state is not on top of the stack.");if(Z.type===uW){let W=Z;W.size=0,W.array=void 0,W.position=0,W.type=void 0}if(Z.type===LX||Z.type===rV){let W=Z;W.size=0,W.map=void 0,W.readCount=0,W.type=void 0}this.stackHeadPosition--}reset(){this.stack.length=0,this.stackHeadPosition=-1}}var cX=-1,iW=new DataView(new ArrayBuffer(0)),A0=new Uint8Array(iW.buffer);try{iW.getInt8(0)}catch(Z){if(!(Z instanceof RangeError))throw Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access")}var aV=RangeError("Insufficient data"),v0=new UW;class oX{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=iW;bytes=A0;headByte=cX;stack=new sV;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??eZ.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.rawStrings=Z?.rawStrings??!1,this.maxStrLength=Z?.maxStrLength??tZ,this.maxBinLength=Z?.maxBinLength??tZ,this.maxArrayLength=Z?.maxArrayLength??tZ,this.maxMapLength=Z?.maxMapLength??tZ,this.maxExtLength=Z?.maxExtLength??tZ,this.keyDecoder=Z?.keyDecoder!==void 0?Z.keyDecoder:v0,this.mapKeyConverter=Z?.mapKeyConverter??D0}clone(){return new oX({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,rawStrings:this.rawStrings,maxStrLength:this.maxStrLength,maxBinLength:this.maxBinLength,maxArrayLength:this.maxArrayLength,maxMapLength:this.maxMapLength,maxExtLength:this.maxExtLength,keyDecoder:this.keyDecoder})}reinitializeState(){this.totalPos=0,this.headByte=cX,this.stack.reset()}setBuffer(Z){let X=kX(Z);this.bytes=X,this.view=new DataView(X.buffer,X.byteOffset,X.byteLength),this.pos=0}appendBuffer(Z){if(this.headByte===cX&&!this.hasRemaining(1))this.setBuffer(Z);else{let X=this.bytes.subarray(this.pos),W=kX(Z),V=new Uint8Array(X.length+W.length);V.set(X),V.set(W,X.length),this.setBuffer(V)}}hasRemaining(Z){return this.view.byteLength-this.pos>=Z}createExtraByteError(Z){let{view:X,pos:W}=this;return RangeError(`Extra ${X.byteLength-W} of ${X.byteLength} byte(s) found at buffer[${Z}]`)}decode(Z){if(this.entered)return this.clone().decode(Z);try{this.entered=!0,this.reinitializeState(),this.setBuffer(Z);let X=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return X}finally{this.entered=!1}}*decodeMulti(Z){if(this.entered){yield*this.clone().decodeMulti(Z);return}try{this.entered=!0,this.reinitializeState(),this.setBuffer(Z);while(this.hasRemaining(1))yield this.doDecodeSync()}finally{this.entered=!1}}async decodeAsync(Z){if(this.entered)return this.clone().decodeAsync(Z);try{this.entered=!0;let X=!1,W;for await(let G of Z){if(X)throw this.entered=!1,this.createExtraByteError(this.totalPos);this.appendBuffer(G);try{W=this.doDecodeSync(),X=!0}catch(m){if(!(m instanceof RangeError))throw m}this.totalPos+=this.pos}if(X){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return W}let{headByte:V,pos:l,totalPos:K}=this;throw RangeError(`Insufficient data in parsing ${$X(V)} at ${K} (${l} in the current buffer)`)}finally{this.entered=!1}}decodeArrayStream(Z){return this.decodeMultiAsync(Z,!0)}decodeStream(Z){return this.decodeMultiAsync(Z,!1)}async*decodeMultiAsync(Z,X){if(this.entered){yield*this.clone().decodeMultiAsync(Z,X);return}try{this.entered=!0;let W=X,V=-1;for await(let l of Z){if(X&&V===0)throw this.createExtraByteError(this.totalPos);if(this.appendBuffer(l),W)V=this.readArraySize(),W=!1,this.complete();try{while(!0)if(yield this.doDecodeSync(),--V===0)break}catch(K){if(!(K instanceof RangeError))throw K}this.totalPos+=this.pos}}finally{this.entered=!1}}doDecodeSync(){Z:while(!0){let Z=this.readHeadByte(),X;if(Z>=224)X=Z-256;else if(Z<192)if(Z<128)X=Z;else if(Z<144){let V=Z-128;if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z<160){let V=Z-144;if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else{let V=Z-160;X=this.decodeString(V,0)}else if(Z===192)X=null;else if(Z===194)X=!1;else if(Z===195)X=!0;else if(Z===202)X=this.readF32();else if(Z===203)X=this.readF64();else if(Z===204)X=this.readU8();else if(Z===205)X=this.readU16();else if(Z===206)X=this.readU32();else if(Z===207)if(this.useBigInt64)X=this.readU64AsBigInt();else X=this.readU64();else if(Z===208)X=this.readI8();else if(Z===209)X=this.readI16();else if(Z===210)X=this.readI32();else if(Z===211)if(this.useBigInt64)X=this.readI64AsBigInt();else X=this.readI64();else if(Z===217){let V=this.lookU8();X=this.decodeString(V,1)}else if(Z===218){let V=this.lookU16();X=this.decodeString(V,2)}else if(Z===219){let V=this.lookU32();X=this.decodeString(V,4)}else if(Z===220){let V=this.readU16();if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else if(Z===221){let V=this.readU32();if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else if(Z===222){let V=this.readU16();if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z===223){let V=this.readU32();if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z===196){let V=this.lookU8();X=this.decodeBinary(V,1)}else if(Z===197){let V=this.lookU16();X=this.decodeBinary(V,2)}else if(Z===198){let V=this.lookU32();X=this.decodeBinary(V,4)}else if(Z===212)X=this.decodeExtension(1,0);else if(Z===213)X=this.decodeExtension(2,0);else if(Z===214)X=this.decodeExtension(4,0);else if(Z===215)X=this.decodeExtension(8,0);else if(Z===216)X=this.decodeExtension(16,0);else if(Z===199){let V=this.lookU8();X=this.decodeExtension(V,1)}else if(Z===200){let V=this.lookU16();X=this.decodeExtension(V,2)}else if(Z===201){let V=this.lookU32();X=this.decodeExtension(V,4)}else throw new XZ(`Unrecognized type byte: ${$X(Z)}`);this.complete();let W=this.stack;while(W.length>0){let V=W.top();if(V.type===uW)if(V.array[V.position]=X,V.position++,V.position===V.size)X=V.array,W.release(V);else continue Z;else if(V.type===LX){if(X==="__proto__")throw new XZ("The key __proto__ is not allowed");V.key=this.mapKeyConverter(X),V.type=rV;continue Z}else if(V.map[V.key]=X,V.readCount++,V.readCount===V.size)X=V.map,W.release(V);else{V.key=null,V.type=LX;continue Z}}return X}}readHeadByte(){if(this.headByte===cX)this.headByte=this.readU8();return this.headByte}complete(){this.headByte=cX}readArraySize(){let Z=this.readHeadByte();switch(Z){case 220:return this.readU16();case 221:return this.readU32();default:if(Z<160)return Z-144;else throw new XZ(`Unrecognized array type byte: ${$X(Z)}`)}}pushMapState(Z){if(Z>this.maxMapLength)throw new XZ(`Max length exceeded: map length (${Z}) > maxMapLengthLength (${this.maxMapLength})`);this.stack.pushMapState(Z)}pushArrayState(Z){if(Z>this.maxArrayLength)throw new XZ(`Max length exceeded: array length (${Z}) > maxArrayLength (${this.maxArrayLength})`);this.stack.pushArrayState(Z)}decodeString(Z,X){if(!this.rawStrings||this.stateIsMapKey())return this.decodeUtf8String(Z,X);return this.decodeBinary(Z,X)}decodeUtf8String(Z,X){if(Z>this.maxStrLength)throw new XZ(`Max length exceeded: UTF-8 byte length (${Z}) > maxStrLength (${this.maxStrLength})`);if(this.bytes.byteLength<this.pos+X+Z)throw aV;let W=this.pos+X,V;if(this.stateIsMapKey()&&this.keyDecoder?.canBeCached(Z))V=this.keyDecoder.decode(this.bytes,W,Z);else V=qV(this.bytes,W,Z);return this.pos+=X+Z,V}stateIsMapKey(){if(this.stack.length>0)return this.stack.top().type===LX;return!1}decodeBinary(Z,X){if(Z>this.maxBinLength)throw new XZ(`Max length exceeded: bin length (${Z}) > maxBinLength (${this.maxBinLength})`);if(!this.hasRemaining(Z+X))throw aV;let W=this.pos+X,V=this.bytes.subarray(W,W+Z);return this.pos+=X+Z,V}decodeExtension(Z,X){if(Z>this.maxExtLength)throw new XZ(`Max length exceeded: ext length (${Z}) > maxExtLength (${this.maxExtLength})`);let W=this.view.getInt8(this.pos+X),V=this.decodeBinary(Z,X+1);return this.extensionCodec.decode(V,W,this.context)}lookU8(){return this.view.getUint8(this.pos)}lookU16(){return this.view.getUint16(this.pos)}lookU32(){return this.view.getUint32(this.pos)}readU8(){let Z=this.view.getUint8(this.pos);return this.pos++,Z}readI8(){let Z=this.view.getInt8(this.pos);return this.pos++,Z}readU16(){let Z=this.view.getUint16(this.pos);return this.pos+=2,Z}readI16(){let Z=this.view.getInt16(this.pos);return this.pos+=2,Z}readU32(){let Z=this.view.getUint32(this.pos);return this.pos+=4,Z}readI32(){let Z=this.view.getInt32(this.pos);return this.pos+=4,Z}readU64(){let Z=nV(this.view,this.pos);return this.pos+=8,Z}readI64(){let Z=AX(this.view,this.pos);return this.pos+=8,Z}readU64AsBigInt(){let Z=this.view.getBigUint64(this.pos);return this.pos+=8,Z}readI64AsBigInt(){let Z=this.view.getBigInt64(this.pos);return this.pos+=8,Z}readF32(){let Z=this.view.getFloat32(this.pos);return this.pos+=4,Z}readF64(){let Z=this.view.getFloat64(this.pos);return this.pos+=8,Z}}function OW(Z,X){return new oX(X).decode(Z)}class MZ{listeners=new Map;addEventListener(Z,X){let W=this.listeners.get(Z);if(!W)W=new Set,this.listeners.set(Z,W);return W.add(X),()=>{this.removeEventListener(Z,X)}}removeEventListener(Z,X){let W=this.listeners.get(Z);if(W){if(W.delete(X),W.size===0)this.listeners.delete(Z)}}emit(Z,X){let W=this.listeners.get(Z);if(W){let V=Array.from(W);for(let l of V)l(X)}}emitAll(Z){let X=Array.from(this.listeners.keys());for(let W of X)this.emit(W,Z)}}class TZ{getter;static eventName="update";emitter;constructor(Z){this.getter=Z;this.emitter=new MZ}get=()=>this.getter();async emit(){let Z=await this.getter();queueMicrotask(()=>this.emitter.emit(TZ.eventName,Z))}listen(Z){return this.emitter.addEventListener(TZ.eventName,Z),()=>{this.emitter.removeEventListener(TZ.eventName,Z)}}}var HZ=64;var tV=32,hZ=8;var qX=32;var eV=30000,Zl=512,N;((y)=>{y[y.Success=0]="Success";y[y.InvalidSignature=3]="InvalidSignature";y[y.ClockOutOfSync=4]="ClockOutOfSync";y[y.UserNotRegistered=5]="UserNotRegistered";y[y.ServerMisconfigured=6]="ServerMisconfigured";y[y.MissingBody=7]="MissingBody";y[y.ExtraBodyContent=8]="ExtraBodyContent";y[y.MissingParam=9]="MissingParam";y[y.InvalidParam=10]="InvalidParam";y[y.InvalidRequest=11]="InvalidRequest";y[y.InternalError=12]="InternalError";y[y.NotFound=13]="NotFound";y[y.InvalidMessage=14]="InvalidMessage";y[y.NoChange=15]="NoChange";y[y.DatabaseClosed=16]="DatabaseClosed";y[y.StorageError=17]="StorageError";y[y.DatabaseError=18]="DatabaseError";y[y.HashMismatch=19]="HashMismatch";y[y.DecryptionError=20]="DecryptionError";y[y.NotImplemented=21]="NotImplemented";y[y.MissingSeed=22]="MissingSeed";y[y.OutOfBounds=23]="OutOfBounds";y[y.HostError=24]="HostError";y[y.CommunicationError=25]="CommunicationError";y[y.VarLimitExceeded=26]="VarLimitExceeded";y[y.InvalidResponse=27]="InvalidResponse";y[y.ConnectionClosed=28]="ConnectionClosed"})(N||={});function d(Z){return[Z,0]}function Y(Z){return[void 0,Z]}function $0(Z){if(Z<0)console.info("N",Z),console.trace();if(typeof Z!=="bigint")Z=BigInt(Z);if(Z<0n)return Y(10);let X=[];while(Z>0n){let W=Number(Z&0x7fn);if(Z>>=7n,Z>0n)X.push(W|128);else X.push(W)}if(X.length===0)return d(new Uint8Array([0]));if(X.length>8)return Y(26);return d(new Uint8Array(X))}function o0(Z,X=0){let W=0n,V=0,l=X;while(!0){if(l>=Z.length)return Y(14);let K=Z[l++];if(K===void 0)return Y(14);if(W|=BigInt(K&127)<<BigInt(V),(K&128)===0){if(l-X>8)return Y(26);return d({value:W>0x1fffffffffffffn?W:Number(W),bytesRead:l-X})}if(V+=7,V>=56)return Y(26)}}class P{data;pos=0;constructor(Z){this.data=Z}static async fromResponse(Z){let X=await Z.arrayBuffer(),W=new Uint8Array(X);return new P(W)}readBigInt(){if(this.pos+8>this.data.length)return Y(7);let Z=new DataView(this.data.buffer,this.data.byteOffset+this.pos).getBigUint64(0,!1);return this.pos+=8,d(Z)}readDate(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return d(new Date(Z))}readVarInt(){let[Z,X]=o0(this.data,this.pos);if(X!==0)return Y(X);this.pos+=Z.bytesRead;let W=Z.value;return d(typeof W==="bigint"?Number(W):W)}readVarString(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);let l=new TextDecoder().decode(W);return d(l)}readBytes(Z){if(Z<0)return Y(10);if(this.pos+Z>this.data.length)return Y(23);let X=this.data.slice(this.pos,this.pos+Z);return this.pos+=Z,d(X)}readVarBytes(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return this.readBytes(Z)}readStruct(Z){return Z.decode(this)}readStructs(Z){let X=[];while(!this.done()){let[W,V]=this.readStruct(Z);if(V!==0)return Y(V);X.push(W)}return d(X)}readBytesSeq(Z){let X=[];while(!this.done()){let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);X.push(W)}return d(X)}done(){return this.pos>=this.data.length}consumed(){return this.pos}}class U{parts=[];writeBigInt(Z){let X=new Uint8Array(8);new DataView(X.buffer).setBigUint64(0,Z,!1),this.parts.push(X)}writeDate(Z){let X=Z.getTime();return this.writeVarInt(X)}writeVarInt(Z){let[X,W]=$0(Z);if(W!==0)return W;return this.parts.push(X),0}writeVarString(Z){let X=new TextEncoder().encode(Z),W=this.writeVarInt(X.length);if(W!==0)return W;return this.writeBytes(X),0}prependBytes(Z){this.parts.unshift(Z.slice())}writeBytes(Z){this.parts.push(Z.slice())}writeVarBytes(Z){let X=this.writeVarInt(Z.length);if(X!==0)return X;return this.writeBytes(Z),0}writeStruct(Z,X){return Z.encode(this,X)}writeStructs(Z,X){for(let W of X){let V=this.writeStruct(Z,W);if(V!==0)return V}return 0}writeBytesSeq(Z){for(let X of Z)this.writeBytes(X)}result(){let Z=this.parts.reduce((V,l)=>V+l.length,0),X=new Uint8Array(Z),W=0;for(let V of this.parts)X.set(V,W),W+=V.length;return X}*scan(){for(let Z of this.parts)yield Z}}async function jW(Z,X){let W=new U,V=W.writeDate(X);if(V!==0)return Y(V);let l=W.result(),K=await Z.sign(l);return d({pubKey:Z.publicKey,sig:K,timestamp:X})}async function SZ(Z,X,W){let V=W.now().getTime(),l=Z.timestamp.getTime();if(Math.abs(V-l)>eV)return 4;let G=new U;G.writeDate(Z.timestamp);let m=G.result();if(!await X.checkSigEd25519(Z.sig,m,Z.pubKey))return 3;return 0}var a={encode(Z,X){let W=Z.writeVarBytes(X.id);if(W!==0)return W;let V=Z.writeDate(X.ts);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let[V,l]=Z.readDate();if(l!==0)return Y(l);return d({id:X,ts:V})}};function ZX(Z){let X=new U,W=X.writeStruct(a,Z);if(W!==0)return Y(W);let V=X.result();return d(V)}async function q0(Z){return ZX({id:Z,ts:new Date(0)})}var JZ={encode(Z,X){let W=Z.writeVarBytes(X.eid);if(W!==0)return W;let V=Z.writeVarInt(X.off);if(V!==0)return V;let l=Z.writeVarInt(X.ctr);if(l!==0)return l;let K=Z.writeVarInt(X.len);if(K!==0)return K;if(X.hsh)Z.writeBytes(X.hsh);return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let V=new P(X),[,l]=a.decode(V);if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let[m,R]=Z.readVarInt();if(R!==0)return Y(R);let[J,C]=Z.readVarInt();if(C!==0)return Y(C);let F;if(J>0){let[b,T]=Z.readBytes(qX);if(T!==0)return Y(T);F=b}return d({eid:X,off:K,ctr:m,len:J,hsh:F})}};function YZ(Z){return Array.from(Z).map((W)=>W.toString(16).padStart(2,"0")).join("")}function IX(Z){if(Z.length%2!==0)throw Error("Invalid hex string");let X=new Uint8Array(Z.length/2);for(let W=0;W<Z.length;W+=2)X[W/2]=Number.parseInt(Z.substr(W,2),16);return X}function n(Z,X){if(Z===X)return!0;if(Z.byteLength!==X.byteLength)return!1;return Z.every((W,V)=>W===X[V])}var H;if(typeof Uint8Array.prototype.toBase64==="function")H=(Z)=>Z.toBase64();else H=(Z)=>btoa(String.fromCharCode(...Z));var e;if(typeof Uint8Array.fromBase64==="function")e=(Z)=>Uint8Array.fromBase64(Z);else e=(Z)=>Uint8Array.from(atob(Z),(X)=>X.charCodeAt(0));function BW(Z){return H(Z).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function EW(Z){let X=Z.length%4===0?"":"=".repeat(4-Z.length%4),W=Z.replace(/-/g,"+").replace(/_/g,"/")+X;return e(W)}function QX(Z,X){let W=new Uint8Array(Z.length+X.length);return W.set(Z,0),W.set(X,Z.length),W}function Xl(Z,X,W){return W.checkSigEd25519(Z.sig,Z.headCph,X)}async function Wl(Z,X,W,V){let l;if(Z.bod&&Z.len>0)l=await W.blake3(Z.bod);let K=new U,G=JZ.encode(K,{...Z,hsh:l});if(G!==0)return Y(G);let m=K.result(),R=await X.kdmFor(m),J=V.deriveCipher(R,"encrypt"),C=await J.encrypt(m),F=Z.bod?await J.encrypt(Z.bod):new Uint8Array(0),b=await X.sign(C);return d({sig:b,kdm:R,headCph:C,bodyCph:F})}async function wW(Z,X,W,V,l){let K=new P(Z),[G,m]=JZ.decode(K);if(m!==0)return Y(14);let R;try{R=X&&X.length>0?await W.decrypt(X):void 0}catch{return Y(20)}let J=G.hsh&&R===void 0,C=G.hsh===void 0&&R!==void 0;if(J||C)return Y(19);if(G.hsh&&R){let b=await V.blake3(R);if(!n(b,G.hsh))return Y(19)}let F=l??await V.blake3(Z);return d({msgHead:G,bod:R,headHash:F})}class PZ{now(){return new Date}}function Vl(Z,X,W,V){let l=X.getTime()-Z.getTime(),K=W.getTime()-V.getTime();return(l+K)/2}var pX={encode(Z,X){if(Z.writeVarInt(X.quota),X.quota>0){if(X.usage===void 0)return 9;Z.writeVarInt(X.usage)}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let V;if(X>0){let[l,K]=Z.readVarInt();if(K!==0)return Y(K);V=l}return d({quota:X,usage:V})}};var DW={encode(Z,X){Z.writeBytes(new Uint8Array([X.status]));let W=Z.writeDate(X.timeRcvd);if(W!==0)return W;let V=Z.writeDate(X.timeSent);if(V!==0)return V;let l=Z.writeVarInt(X.subscription.term);if(l!==0)return l;let K=Z.writeVarInt(X.subscription.elapsed);if(K!==0)return K;let G=Z.writeStruct(pX,X.subscription.stat);if(G!==0)return G;let m=Z.writeStruct(pX,X.subscription.dyn);if(m!==0)return m;return 0},decode(Z){let[X,W]=Z.readBytes(1);if(W!==0)return Y(W);let V=X[0],[l,K]=Z.readDate();if(K!==0)return Y(K);let[G,m]=Z.readDate();if(m!==0)return Y(m);let[R,J]=Z.readVarInt();if(J!==0)return Y(J);let[C,F]=Z.readVarInt();if(F!==0)return Y(F);let[b,T]=Z.readStruct(pX);if(T!==0)return Y(T);let[k,c]=Z.readStruct(pX);if(c!==0)return Y(c);return d({status:V,timeRcvd:l,timeSent:G,subscription:{term:R,elapsed:C,stat:b,dyn:k}})}};var AW={encode(Z,X){let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarInt(X.seq);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let[V,l]=Z.readVarInt();if(l!==0)return Y(l);return d({headCph:X,seq:V})}};var RZ={encode(Z,X){Z.writeBytes(X.pubKey),Z.writeBytes(X.sig);let W=Z.writeDate(X.timestamp);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readBytes(tV);if(W!==0)return Y(W);let[V,l]=Z.readBytes(HZ);if(l!==0)return Y(l);let[K,G]=Z.readDate();if(G!==0)return Y(G);return d({pubKey:X,sig:V,timestamp:K})}};var ll={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;for(let G of V)l.writeVarInt(G);return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await SZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);if(F!==0)return F;if(!C)return 5;let[b,T]=X.readVarInt();if(T!==0)return T;if(!X.done())return 8;let[k,c]=await K.listHeads(J,b);if(c!==0)return c;return W.writeStructs(AW,k)},decodeResp(Z){return Z.readStructs(AW)}};var vW={encode(Z,X){Z.writeVarInt(X.seq);let W=Z.writeVarBytes(X.bodyCph);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);return d({seq:X,bodyCph:V})}};var Kl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;for(let G of V){let m=l.writeVarInt(G);if(m!==0)return m}return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await SZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);if(F!==0)return F;if(!C)return 5;let b=[];while(!X.done()){let[c,L]=X.readVarInt();if(L!==0)return L;b.push(c)}console.info(`PULL: ${b.length} bags`);let[T,k]=await K.getBodies(J,b);if(k!==0)return k;if(!T)return 17;for(let{seq:c,bodyCph:L}of T){let p={seq:c,bodyCph:L},Q=W.writeStruct(vW,p);if(Q!==0)return Q}return 0},decodeResp(Z){return Z.readStructs(vW)}};var $W={encode(Z,X){Z.writeBytes(X.sig),Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarBytes(X.bodyCph);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readBytes(HZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(hZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);let[m,R]=Z.readVarBytes();if(R!==0)return Y(R);return d({sig:X,kdm:V,headCph:K,bodyCph:m})}};var fX={encode(Z,X){let W=Z.writeVarInt(X.seq);if(W!==0)return W;let V=Z.writeVarBytes(X.headCph);if(V!==0)return V;let l=X.bodyCph?X.bodyCph.length:0,K=Z.writeVarInt(l);if(K!==0)return K;if(l>0){if(!X.bodyCph)return 10;Z.writeBytes(X.bodyCph)}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let m;if(K>0){let[R,J]=Z.readBytes(K);if(J!==0)return Y(J);m=R}return d({seq:X,headCph:V,bodyCph:m})}};var nX={encode(Z,X){Z.writeBytes(X.sig),Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readBytes(HZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(hZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return d({sig:X,kdm:V,headCph:K})}};var _X={encode(Z,X){if(Z.writeVarInt(X.idx),Z.writeBytes(new Uint8Array([X.status])),X.status===0)Z.writeVarInt(X.seq);return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readBytes(1);if(l!==0)return Y(l);let K=V[0];if(K!==0)return d({idx:X,status:K});let[G,m]=Z.readVarInt();if(m!==0)return Y(m);return d({idx:X,status:K,seq:G})}};var Gl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;let G=l.writeStructs($W,V);if(G!==0)return G;return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K,notifier:G}=Z,[m,R]=X.readStruct(RZ);if(R!==0)return R;let J=await SZ(m,l,V);if(J!==0)return J;let{pubKey:C}=m,[F,b]=await K.hasUser(C);if(b!==0)return b;if(!F)return 5;let[T,k]=X.readStructs($W);if(k!==0)return k;console.info(`PUSH: ${T.length} bags`);let c=[],L=[];for(let I=0;I<T.length;I++){let g=T[I];if(!await Xl(g,C,l)){let j={idx:I,status:3},O=W.writeStruct(_X,j);if(O!==0)return O;continue}c.push(I),L.push(g)}let[p,Q]=await K.setBags(C,L);if(Q!==0)return Q;if(!p||p.length!==L.length)return 17;let z=[];for(let I=0;I<L.length;I++){let g=L[I],S=c[I],j=p[I],O=new U,u=O.writeStruct(nX,g);if(u!==0)return u;let E=O.result(),y={seq:j,headCph:E};if(T.length===1&&g.bodyCph.length<=Zl)y.bodyCph=g.bodyCph;z.push(y);let A={idx:S,status:0,seq:j},$=W.writeStruct(_X,A);if($!==0)return $}if(z.length>0){let I=new U,g=I.writeStructs(fX,z);if(g!==0)return g;let S=I.result();await Promise.resolve(G.push(C,S))}return 0},decodeResp(Z){return Z.readStructs(_X)}};var ml={async encodeReq(Z,X,W,V,l){return l.writeStruct(RZ,W)},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await SZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G;if(!X.done())return 8;let[C,F]=await K.addUser(J);if(F!==0)return F;return 0},decodeResp(Z){return d(void 0)}};class oW{url;websocket;constructor(Z){this.url=Z}connected(){return this.websocket!==void 0&&this.websocket.readyState===WebSocket.OPEN}async connect(Z,X,W=()=>{},V=()=>{}){let{url:l}=this;if(this.websocket)this.websocket.close(),this.websocket=void 0;let K=new U;K.writeStruct(RZ,Z);let G=K.result(),m=YZ(G);return l.searchParams.set("t",m),this.websocket=new WebSocket(l),this.websocket.binaryType="arraybuffer",this.websocket.onopen=()=>{console.log("CONNECTED"),V()},this.websocket.onclose=()=>{console.log("DISCONNECTED"),this.websocket=void 0,W()},this.websocket.onmessage=(R)=>{let J=new Uint8Array(R.data);X(J)},this.websocket.onerror=(R)=>{console.log(`ERROR: ${JSON.stringify(R)}`),this.websocket=void 0,W()},Promise.resolve(0)}disconnect(){this.websocket?.close(),this.websocket=void 0}}var r={user:{path:"/user",endpoint:ml,name:0},push:{path:"/push",endpoint:Gl,name:2},peek:{path:"/peek",endpoint:ll,name:1},pull:{path:"/pull",endpoint:Kl,name:3}},f0={0:r.user,2:r.push,1:r.peek,3:r.pull},YR={[r.user.path]:r.user,[r.push.path]:r.push,[r.peek.path]:r.peek,[r.pull.path]:r.pull};class qW{url;listener;constructor(Z){this.url=Z;this.listener=new oW(Z)}async call(Z,X){let{path:W}=f0[Z],V=new URL(W,this.url);try{return await n0(V,X)}catch{return Y(25)}}}var fW=(Z)=>{return new qW(Z.handle)};async function n0(Z,X){let W=await fetch(Z,{method:"POST",body:X.result().slice()});if(!W.ok)return Y(24);let V=await P.fromResponse(W);return d(V)}class aX{enclave;crypto;host;clock;transport;updateHostMeta;constructor(Z,X,W,V,l,K){this.enclave=Z;this.crypto=X;this.host=W;this.clock=V;this.transport=l;this.updateHostMeta=K}async call(Z,X){let{clock:W,transport:V}=this,{endpoint:l,name:K}=Z,G=await this.identity(),m=W.now(),[R,J]=await jW(G,m);if(J!==0)return Y(J);let C=new U,F=await l.encodeReq(this,G,R,X,C);if(F!==0)return Y(F);let b=W.now(),[T,k]=await V.call(K,C),c=W.now();if(k!==0)return Y(k);let[L,p]=T.readStruct(DW);if(p!==0)return Y(p);if(L.status!==0)return Y(L.status);let z={clockOffset:Vl(b,L.timeRcvd,L.timeSent,c),subscription:L.subscription},I=await this.updateHostMeta(z);if(I!==0)return Y(I);return l.decodeResp(T)}identity=()=>{let{host:Z,enclave:X}=this;return X.deriveIdentity(Z.label,Z.idx??0)};seal=async(Z)=>{let{crypto:X,enclave:W}=this,V=await this.identity();return Wl(Z,V,X,W)};register=()=>this.call(r.user,[]);peek=(Z)=>this.call(r.peek,[Z]);push=(Z)=>this.call(r.push,Z);pull=(Z)=>this.call(r.pull,Z);listen=async(Z,X,W)=>{let{clock:V,transport:l}=this,{listener:K}=l,G=await this.identity(),m=V.now(),[R,J]=await jW(G,m);if(J!==0)return J;return await K.connect(R,Z,X,W)};isConnected(){let Z=this.transport?.listener;if(Z&&typeof Z.connected==="function")return Z.connected();return!0}closeListener(){this.transport?.listener?.disconnect()}}var nW={encode(Z,X){let W=Z.writeVarString(X.lbl);if(W!==0)return W;let V=Z.writeVarInt(X.idx);if(V!==0)return V;let l=Z.writeVarInt(X.num);if(l!==0)return l;return Z.writeBytes(X.hsh),Z.writeBytes(X.sig),0},decode(Z){let[X,W]=Z.readVarString();if(W!==0)return Y(W);let[V,l]=Z.readVarInt();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let[m,R]=Z.readBytes(qX);if(R!==0)return Y(R);let[J,C]=Z.readBytes(HZ);if(C!==0)return Y(C);return d({lbl:X,idx:V,num:K,hsh:m,sig:J})}};var _W={encode(Z,X){let W=Z.writeStruct(nW,X.head);if(W!==0)return W;let V=Z.writeVarBytes(X.indexEnc);if(V!==0)return V;let l=Z.writeVarBytes(X.bodyEnc);if(l!==0)return l;return 0},decode(Z){let[X,W]=Z.readStruct(nW);if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return d({head:X,indexEnc:V,bodyEnc:K})}};var aW={encode(Z,X){Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarInt(X.lenBody);if(V!==0)return V;if(X.lenBody>0&&X.offBody!==void 0){let l=Z.writeVarInt(X.offBody);if(l!==0)return l}return 0},decode(Z){let[X,W]=Z.readBytes(hZ);if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let m;if(K>0){let[R,J]=Z.readVarInt();if(J!==0)return Y(J);m=R}return d({kdm:X,headCph:V,lenBody:K,offBody:m})}};async function Yl(Z,X,W,V,l){let K=await l.deriveIdentity(Z,X),G=new U,m=new U,R=0,J=0;for(let p of W){let Q=new U,z=Q.writeStruct(JZ,p.head);if(z!==0)return Y(z);let I=Q.result(),g=await K.kdmFor(I),S=l.deriveCipher(g,"encrypt"),j=await S.encrypt(I),O=p.body?await S.encrypt(p.body):new Uint8Array(0),u=p.head.len>0&&p.head.hsh!==void 0?O.length:0,E={kdm:g,headCph:j,lenBody:u,offBody:u>0?J:void 0},y=G.writeStruct(aW,E);if(y!==0)return Y(y);if(p.body)m.writeBytes(O),J+=O.length;R++}let C=m.result(),F=G.result(),b=await V.blake3(F),T=await K.sign(b),k={lbl:Z,idx:X,num:R,hsh:b,sig:T},c=new U;c.writeStruct(_W,{head:k,indexEnc:F,bodyEnc:C});let L=c.result();return d(L)}async function Rl(Z,X,W){let[V,l]=_W.decode(new P(Z));if(l!==0)return Y(l);let{head:K,indexEnc:G,bodyEnc:m}=V,R=await W.deriveIdentity(K.lbl,K.idx);if(!await X.checkSigEd25519(K.sig,K.hsh,R.publicKey))return Y(3);let C=await X.blake3(G);if(!n(C,K.hsh))return Y(19);let F=new P(G),b=[];for(let k=0;k<K.num;k++){let[c,L]=F.readStruct(aW);if(L!==0)return Y(L);b.push(c)}if(b.length!==K.num)return Y(14);let T=[];for(let k of b){let c=W.deriveCipher(k.kdm,"decrypt"),L;try{L=await c.decrypt(k.headCph)}catch{return Y(20)}let[p,Q]=JZ.decode(new P(L));if(Q!==0)return Y(Q);let z;if(k.lenBody>0&&k.offBody!==void 0){if(p.hsh===void 0)return Y(14);let I=m.slice(k.offBody,k.offBody+k.lenBody);try{z=await c.decrypt(I)}catch{return Y(20)}let g=await X.blake3(z);if(!n(g,p.hsh))return Y(19)}T.push({head:p,body:z})}return d(T)}async function Jl({now:Z,bod:X,crypto:W}){let V=await W.genRandomBytes(8),l=new U,K=l.writeStruct(a,{id:V,ts:Z});if(K!==0)return Y(K);let G=l.result();return rX({now:Z,eid:G,ctr:0,bod:X,crypto:W})}async function rX({now:Z,eid:X,ctr:W,bod:V,crypto:l}){let K=new P(X),[G,m]=a.decode(K);if(m!==0)return Y(m);let R=Z.getTime()-G.ts.getTime(),J,C=V?.length??0;if(V&&C>0)J=await l.blake3(V);return d({eid:X,off:R,ctr:W,len:C,hsh:J})}function Cl(Z,X){let W=Z.length<X.length?Z.length:X.length;for(let V=0;V<W;V++)if(Z[V]!==X[V])return Z[V]-X[V];return Z.length-X.length}async function XX(Z,X){let W=Array.from(Z);W.sort(Cl);let V=0;for(let G of W)V+=G.length;let l=new Uint8Array(V),K=0;for(let G of W)l.set(G,K),K+=G.length;return X.blake3(l)}function Fl(Z){let X=new U,W=X.writeVarBytes(Z.eid);if(W!==0)return Y(W);let V=X.writeDate(Z.updatedAt);if(V!==0)return Y(V);let l=X.writeVarInt(Z.ctr);if(l!==0)return Y(l);return d(X.result())}async function yX(Z,X){let W=[];for(let V of Z){let[l,K]=Fl(V);if(K!==0||!l)return Y(K);W.push(l)}return d(await XX(W,X))}var XJ=Symbol("MasterSeed"),WJ=Symbol("SealedMasterKey"),bZ=32,rW=24+bZ+16;function WZ(Z){if(Z.byteLength!==bZ)return Y(10);return d(Z)}function QZ(Z){if(Z.byteLength!==rW)return Y(10);return d(Z)}var lJ=Symbol("EntityID");function dl(Z){return"type"in Z}var KJ=Symbol("DerivationSeed"),GJ=Symbol("PublicKey"),mJ=Symbol("PrivateKey"),YJ=Symbol("HostSpecificKeyPair"),RJ=Symbol("Hash");function _0(Z){if(!Z)return!1;if(typeof Z!=="object")return!1;if("body"in Z===!1)return!1;if("type"in Z===!1)return!1;return!0}function a0(Z){if(!Z.bod||Z.bod.length===0){let V={off:Z.off,ctr:Z.ctr,eid:Z.eid};return d(V)}let X=OW(Z.bod);if(_0(X)===!1)return console.warn("msg body invalid",X),Y(14);let W={off:Z.off,ctr:Z.ctr,eid:Z.eid,gid:X.gid,pid:X.pid,tags:X.tags,type:X.type,body:X.body};return d(W)}class zX{applier;emitter=new MZ;clearer;onDirtyEids;cacheDriven;peerIngest;constructor(Z,X,W,V){this.applier=Z;this.clearer=X,this.onDirtyEids=W,this.cacheDriven=V?.cacheDriven??!1,this.peerIngest=V?.peerIngest}apply=async(Z)=>{let X=[],W=[];for(let m of Z){let[R,J]=a0(m);if(W.push(J),J!==0)continue;X.push(R)}let{stats:V,types:l,eids:K}=await this.applier(X),G=[];for(let m=0;m<Z.length;m++){let R=W[m],J=V[m];if(R!==0){G.push(R);continue}if(J!==0){G.push(J);continue}G.push(0)}if(!this.cacheDriven)for(let m of l)this.emitter.emit(m,null);if(K.length>0)this.onDirtyEids?.(K);return G};clear=async()=>{let Z=await this.clearer();if(Z!==0)return Z;return this.emitter.emitAll(null),Z};notify=(Z)=>{for(let X of Z)this.emitter.emit(X,null)};refresh=async(Z)=>{if(this.peerIngest){await this.peerIngest(Z);return}};on=(Z,X)=>{this.emitter.addEventListener(Z,X)};off=(Z,X)=>{this.emitter.removeEventListener(Z,X)}}var sW={apply:async function(Z){return Z.map(()=>0)},clear:async function(){return 0},notify:function(Z){},refresh:async function(Z){},on:function(Z,X){},off:function(Z,X){}};var q="entities",sX="entity_type_created_at",eW="entity_type_updated_at",ZV="entity_type_group_id",XV="entity_type_parent_id",WX="entity_tags",bl="db",Tl=13;function r0(Z){return"typ"in Z}function s0(Z){let X={bod:Z.body,crd:Z.createdAt,...Z.ctr!==0?{ctr:Z.ctr}:{},eid:H(Z.eid),gid:Z.gid,pid:Z.pid?H(Z.pid):void 0,tgs:Z.tags,typ:Z.type,upd:Z.updatedAt};if(X.gid===void 0)delete X.gid;if(X.pid===void 0)delete X.pid;if(X.tgs===void 0)delete X.tgs;if(X.ctr===void 0)delete X.ctr;return X}function t0(Z){if(!D(Z))return{eid:H(Z.eid),upd:Z.updatedAt,...Z.ctr!==0?{ctr:Z.ctr}:{}};return s0(Z)}function VX(Z){return{body:Z.bod,createdAt:Z.crd,updatedAt:Z.upd,ctr:Z.ctr??0,type:Z.typ,eid:e(Z.eid),gid:Z.gid,pid:Z.pid?e(Z.pid):void 0,...Z.tgs!==void 0?{tags:Z.tgs}:{}}}function tW(Z){if(r0(Z))return VX(Z);return{eid:e(Z.eid),updatedAt:Z.upd,ctr:Z.ctr??0}}class WV{db;opening;async init(){await this.ensureDb()}async ensureDb(){if(this.db)return this.db;if(this.opening)return this.opening;return this.opening=ZK().then((Z)=>{return Z.onversionchange=()=>{if(Z.close(),this.db===Z)this.db=void 0},this.db=Z,this.opening=void 0,Z},(Z)=>{throw this.opening=void 0,Z}),this.opening}apply=async(Z)=>{let X=new Set,W=[],V;try{V=await this.ensureDb()}catch{return{stats:Z.map(()=>16),types:X,eids:W}}let l=V.transaction(q,"readwrite"),K=l.objectStore(q);return new Promise((G)=>{let m=Array(Z.length).fill(0);if(Z.length<1){G({stats:[],types:X,eids:W});return}l.oncomplete=()=>{G({stats:m,types:X,eids:W})},l.onerror=()=>{for(let J=0;J<m.length;J++)if(m[J]===void 0)m[J]=18;G({stats:m,types:X,eids:W})};let R=new Map;for(let J=0;J<Z.length;J++){let C=Z[J],F=H(C.eid),b={op:C,index:J},T=R.get(F);if(T)T.push(b);else R.set(F,[b])}for(let[J,C]of R){if(C.length<1)continue;let F=K.get(J);F.onsuccess=()=>{let b=F.result,T=b?tW(b):void 0,k=!1;for(let{op:c,index:L}of C){let[p,Q]=lX(T,c);if(Q!==0){m[L]=Q;continue}if(p===void 0){m[L]=12;continue}k=!0;for(let z of KX(T,p))X.add(z);T=p}if(k)W.push(C[0].op.eid);if(T){let c=K.put(t0(T));c.onerror=(L)=>{L.preventDefault();for(let{index:p}of C)m[p]=18}}},F.onerror=()=>{for(let{index:b}of C)m[b]=18}}})};async clear(){let Z;try{Z=await this.ensureDb()}catch{return 16}let X=Z.transaction(q,"readwrite"),W=X.objectStore(q);return new Promise((V)=>{X.oncomplete=()=>V(0),X.onerror=()=>V(18),W.clear()})}async getRow(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let W=H(Z),l=X.transaction(q,"readonly").objectStore(q);return new Promise((K)=>{let G=l.get(W);G.onsuccess=()=>{let m=G.result;if(!m)K(d(void 0));else K(d(tW(m)))},G.onerror=()=>K(Y(18))})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!D(X))return d(void 0);return d(X)}async getAllOfTypeUpdatedBetween(Z,X,W){let V;try{V=await this.ensureDb()}catch{return Y(16)}let K=V.transaction(q,"readonly").objectStore(q).index(eW);return new Promise((G)=>{let m=K.getAll(IDBKeyRange.bound([Z,X],[Z,W]));m.onsuccess=()=>{let R=m.result;G(d(R.map(VX)))},m.onerror=()=>G(Y(18))})}async getGroupMembers(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(q,"readonly").objectStore(q).index(ZV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z,X]));G.onsuccess=()=>{let m=G.result;K(d(m.map(VX)))},G.onerror=()=>K(Y(18))})}async getAllOfType(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(q,"readonly").objectStore(q).index(sX);return new Promise((l)=>{let K=V.getAll(IDBKeyRange.bound([Z],[Z,[]]));K.onsuccess=()=>{let G=K.result;l(d(G.map(VX)))},K.onerror=()=>l(Y(18))})}async getByTag(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(q,"readonly").objectStore(q).index(WX);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only(X));G.onsuccess=()=>{let R=G.result.filter((J)=>J.typ===Z).map(VX);K(d(R))},G.onerror=()=>K(Y(18))})}async getAllEntities(Z){if("pid"in Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let W=H(Z.pid),l=X.transaction(q,"readonly").objectStore(q).index(XV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z.type,W]));G.onsuccess=()=>{let R=G.result.map(VX);K(d(R))},G.onerror=()=>K(Y(18))})}else if("gid"in Z)return await this.getGroupMembers(Z.type,Z.gid);else if("tag"in Z)return await this.getByTag(Z.type,Z.tag);else if("updatedBetween"in Z)return await this.getAllOfTypeUpdatedBetween(Z.type,Z.updatedBetween.start,Z.updatedBetween.end);return await this.getAllOfType(Z.type)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return d(X)}async countEntities({type:Z}){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(q,"readonly").objectStore(q).index(sX);return new Promise((l)=>{let K=IDBKeyRange.bound([Z],[Z,[]]),G=V.count(K);G.onsuccess=()=>l(d(G.result)),G.onerror=()=>l(Y(18))})}async checksum(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(q,"readonly").objectStore(q),l=[];return new Promise((K)=>{let G=V.openCursor();G.onsuccess=()=>{let m=G.result;if(m){let R=m.value;l.push(NX(tW(R))),m.continue()}else yX(l,Z).then(K)},G.onerror=()=>K(Y(18))})}}function e0(Z,X){if(!Z.objectStoreNames.contains(q))Z.createObjectStore(q,{keyPath:"eid",autoIncrement:!1});let W=X.objectStore(q);if(!W.indexNames.contains(sX))W.createIndex(sX,["typ","crd"],{unique:!1});if(!W.indexNames.contains(eW))W.createIndex(eW,["typ","upd"],{unique:!1});if(!W.indexNames.contains(ZV))W.createIndex(ZV,["typ","gid"],{unique:!1});if(!W.indexNames.contains(XV))W.createIndex(XV,["typ","pid"],{unique:!1});if(W.indexNames.contains(WX)){if(W.index(WX).keyPath!=="tgs")W.deleteIndex(WX)}if(!W.indexNames.contains(WX))W.createIndex(WX,"tgs",{unique:!1,multiEntry:!0})}function ZK(){return new Promise((Z,X)=>{let W=indexedDB.open(bl,Tl);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!l){X(Error("Transaction is null during EntDB upgrade"));return}try{e0(V,l)}catch(K){X(K instanceof Error?K:Error(String(K)))}},W.onblocked=()=>{console.warn(`[DIPLOMATIC] EntDB IDB upgrade blocked (${bl} → v${Tl}); waiting for other connections to close`)},W.onsuccess=()=>Z(W.result),W.onerror=()=>X(W.error??Error("EntDB IndexedDB open failed"))})}async function kl(){let Z=new WV;return await Z.init(),Z}class tX{ents=new Map;useIndex;byType=new Map;byTypePid=new Map;byTypeGid=new Map;byTypeTag=new Map;constructor(Z=[],X){this.useIndex=X?.indexes!==!1;for(let W of Z)this.put(W)}put(Z){let X=H(Z.eid),W=this.ents.get(X);if(W!==void 0&&D(W))this.unindex(X,W);if(this.ents.set(X,Z),D(Z))this.index(X,Z)}del(Z){let X=this.ents.get(Z);if(X===void 0)return;if(D(X))this.unindex(Z,X);this.ents.delete(Z)}index(Z,X){if(!this.useIndex)return;let W=this.byType.get(X.type);if(!W)W=new Map,this.byType.set(X.type,W);if(W.set(Z,X),X.pid){let V=H(X.pid),l=this.byTypePid.get(X.type);if(!l)l=new Map,this.byTypePid.set(X.type,l);let K=l.get(V);if(!K)K=new Map,l.set(V,K);K.set(Z,X)}if(typeof X.gid==="string"){let V=this.byTypeGid.get(X.type);if(!V)V=new Map,this.byTypeGid.set(X.type,V);let l=V.get(X.gid);if(!l)l=new Map,V.set(X.gid,l);l.set(Z,X)}if(X.tags){let V=this.byTypeTag.get(X.type);if(!V)V=new Map,this.byTypeTag.set(X.type,V);for(let l of X.tags){let K=V.get(l);if(!K)K=new Map,V.set(l,K);K.set(Z,X)}}}unindex(Z,X){if(!this.useIndex)return;let W=this.byType.get(X.type);if(W){if(W.delete(Z),W.size===0)this.byType.delete(X.type)}if(X.pid){let V=H(X.pid),l=this.byTypePid.get(X.type),K=l?.get(V);if(K){if(K.delete(Z),K.size===0)l?.delete(V)}if(l&&l.size===0)this.byTypePid.delete(X.type)}if(typeof X.gid==="string"){let V=this.byTypeGid.get(X.type),l=V?.get(X.gid);if(l){if(l.delete(Z),l.size===0)V?.delete(X.gid)}if(V&&V.size===0)this.byTypeGid.delete(X.type)}if(X.tags){let V=this.byTypeTag.get(X.type);if(V){for(let l of X.tags){let K=V.get(l);if(K){if(K.delete(Z),K.size===0)V.delete(l)}}if(V.size===0)this.byTypeTag.delete(X.type)}}}clearIndexes(){this.byType.clear(),this.byTypePid.clear(),this.byTypeGid.clear(),this.byTypeTag.clear()}bucketList(Z){if(!Z||Z.size===0)return[];let X=[];for(let W of Z.values())X.push(W);return X}async apply(Z){let X=new Set,W=[],V=[];for(let l of Z){let K=H(l.eid),G=this.ents.get(K),[m,R]=lX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of KX(G,m))X.add(J);this.put(m),W.push(l.eid),V.push(0)}return{stats:V,types:X,eids:W}}async clear(){return this.ents.clear(),this.clearIndexes(),0}async getRow(Z){let X=H(Z),W=this.ents.get(X);return d(W)}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!D(X))return d(void 0);return d(X)}async getAllEntities({type:Z,gid:X,pid:W,tag:V,updatedBetween:l}){if(this.useIndex){if(W!==void 0){let G=H(W);return d(this.bucketList(this.byTypePid.get(Z)?.get(G)))}if(X!==void 0)return d(this.bucketList(this.byTypeGid.get(Z)?.get(X)));if(V!==void 0)return d(this.bucketList(this.byTypeTag.get(Z)?.get(V)));if(l!==void 0){let G=[],m=this.byType.get(Z);if(m){for(let R of m.values())if(R.updatedAt>=l.start&&R.updatedAt<=l.end)G.push(R)}return d(G)}return d(this.bucketList(this.byType.get(Z)))}let K=[];if(W!==void 0){for(let G of this.ents.values())if(D(G)&&G.type===Z&&G.pid&&n(G.pid,W))K.push(G)}else if(X!==void 0){for(let G of this.ents.values())if(D(G)&&G.type===Z&&(typeof G.gid==="string"&&G.gid===X))K.push(G)}else if(V!==void 0){for(let G of this.ents.values())if(D(G)&&G.type===Z&&G.tags&&G.tags.includes(V))K.push(G)}else if(l!==void 0){for(let G of this.ents.values())if(D(G)&&G.type===Z&&G.updatedAt>=l.start&&G.updatedAt<=l.end)K.push(G)}else for(let G of this.ents.values())if(D(G)&&G.type===Z)K.push(G);return d(K)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return d(X)}async countEntities({type:Z}){if(this.useIndex)return d(this.byType.get(Z)?.size??0);let X=0;for(let W of this.ents.values())if(D(W)&&W.type===Z)X+=1;return d(X)}async checksum(Z){let X=[];for(let W of this.ents.values())X.push(NX(W));return yX(X,Z)}}async function VV(Z){let X=await kl();if(Z?.cache===!1)return X;return new xX(X,void 0,{indexes:Z?.indexes})}class xX{mem;durable;warmed=new Set;listeners=new Set;chain=Promise.resolve();constructor(Z,X,W){if(this.durable=Z,this.mem=new tX(X??[],{indexes:W?.indexes}),X)for(let V of X)this.warmed.add(V.type)}subscribe(Z){return this.listeners.add(Z),()=>{this.listeners.delete(Z)}}emit(Z){if(Z.size<1)return;for(let X of this.listeners)X(Z)}run(Z){let X=this.chain.then(Z,Z);return this.chain=X.then(()=>{return},()=>{return}),X}apply(Z){return this.run(async()=>{await this.pullEids(Z.map((K)=>K.eid));let X=GK(this.mem,Z);this.emit(X.types);let W=await this.durable.apply(Z),{changed:V,status:l}=await this.pullEids(Z.map((K)=>K.eid));if(this.emit(V),l!==0)return{stats:Z.map(()=>l),types:W.types,eids:W.eids};return W})}clear(){return this.run(async()=>{let Z=await this.durable.clear();if(Z!==0)return Z;let X=this.mem.ents.size>0;return await this.mem.clear(),this.warmed.clear(),0})}ingestFromDurable(Z){return this.run(async()=>{let{changed:X,status:W}=await this.pullEids(Z);return this.emit(X),W})}async pullEids(Z){let X=new Set,W=new Set;for(let V of Z){let l=H(V);if(W.has(l))continue;W.add(l);let K=this.mem.ents.get(l),[G,m]=await this.durable.getRow(V);if(m!==0)return{changed:X,status:m};if(G){if(this.mem.put(G),!K||!XK(K,G)){if(D(G))X.add(G.type);if(K!==void 0&&D(K))X.add(K.type)}}else if(K!==void 0){if(this.mem.del(l),D(K))X.add(K.type)}}return{changed:X,status:0}}async warmType(Z){if(this.warmed.has(Z))return 0;let[X,W]=await this.durable.getEntities({type:Z});if(W!==0)return W;if(X)for(let V of X){let l=H(V.eid),K=this.mem.ents.get(l);if(!K||KK(V,K))this.mem.put(V)}return this.warmed.add(Z),0}async getRow(Z){let X=H(Z);if(this.mem.ents.has(X))return this.mem.getRow(Z);return this.run(async()=>{if(this.mem.ents.has(X))return this.mem.getRow(Z);let[W,V]=await this.durable.getRow(Z);if(V!==0)return Y(V);if(W)this.mem.put(W);return d(W)})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!D(X))return d(void 0);return d(X)}async getEntities(Z){if(!this.warmed.has(Z.type)){let X=await this.run(()=>this.warmType(Z.type));if(X!==0)return Y(X)}return this.mem.getEntities(Z)}async countEntities({type:Z}){if(!this.warmed.has(Z)){let X=await this.run(()=>this.warmType(Z));if(X!==0)return Y(X)}return this.mem.countEntities({type:Z})}async checksum(Z){return this.durable.checksum(Z)}}function XK(Z,X){if(D(Z)!==D(X))return!1;if(Z.ctr!==X.ctr)return!1;if(Z.updatedAt.getTime()!==X.updatedAt.getTime())return!1;if(!n(Z.eid,X.eid))return!1;if(!D(Z)||!D(X))return!0;if(Z.createdAt.getTime()!==X.createdAt.getTime())return!1;if(Z.type!==X.type)return!1;if(Z.gid!==X.gid)return!1;if(!VK(Z.pid,X.pid))return!1;if(!WK(Z.tags,X.tags))return!1;return lK(Z.body,X.body)}function WK(Z,X){if(Z===X)return!0;if(Z===void 0||X===void 0)return!1;if(Z.length!==X.length)return!1;for(let W=0;W<Z.length;W++)if(Z[W]!==X[W])return!1;return!0}function VK(Z,X){if(Z===void 0&&X===void 0)return!0;if(Z===void 0||X===void 0)return!1;return n(Z,X)}function lK(Z,X){if(Object.is(Z,X))return!0;if(Z instanceof Uint8Array&&X instanceof Uint8Array)return n(Z,X);if(Z instanceof Date&&X instanceof Date)return Z.getTime()===X.getTime();try{return n(wZ(Z),wZ(X))}catch{return!1}}function KK(Z,X){let W=Z.updatedAt.getTime(),V=X.updatedAt.getTime();if(W!==V)return W>V;return Z.ctr>X.ctr}function GK(Z,X){let W=new Set,V=[];for(let l of X){let K=H(l.eid),G=Z.ents.get(K),[m,R]=lX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of KX(G,m))W.add(J);Z.put(m),V.push(0)}return{stats:V,types:W}}function eX(Z){if(Z instanceof xX){let X=new zX((W)=>Z.apply(W),()=>Z.clear(),void 0,{cacheDriven:!0,peerIngest:async(W)=>{await Z.ingestFromDurable(W)}});return Z.subscribe((W)=>X.notify(W)),X}return new zX((X)=>Z.apply(X),()=>Z.clear())}function D(Z){return"type"in Z}function mK(Z){return!D(Z)}function cl(Z){if(!Array.isArray(Z)||Z.length===0)return;let X=new Set,W=[];for(let V of Z){if(typeof V!=="string"||V.length===0)continue;if(X.has(V))continue;X.add(V),W.push(V)}return W.length>0?W:void 0}function NX(Z){return{eid:Z.eid,ctr:Z.ctr,updatedAt:Z.updatedAt}}function lV(Z){let X=new P(Z.eid),[W,V]=X.readStruct(a);if(V!==0)return Y(V);return d({eid:Z.eid,ctr:Z.ctr,updatedAt:new Date(W.ts.getTime()+Z.off)})}function lX(Z,X){let W=new P(X.eid),[V,l]=W.readStruct(a);if(l!==0)return Y(l);let K=new Date(V.ts.getTime()+X.off);if(Z!==void 0&&K<=Z.updatedAt)return Y(15);if(dl(X)){let G=cl(X.tags);return d({eid:X.eid,gid:X.gid,pid:X.pid,...G!==void 0?{tags:G}:{},type:X.type,createdAt:V.ts,updatedAt:K,ctr:X.ctr,body:X.body})}return d({eid:X.eid,updatedAt:K,ctr:X.ctr})}function KX(Z,X){let W=new Set;if(Z!==void 0&&D(Z))W.add(Z.type);if(D(X))W.add(X.type);return[...W]}var YK={getEnt:async()=>Y(21),getRow:async()=>Y(21),getEntities:async(Z)=>Y(21),countEntities:async()=>Y(21),checksum:async()=>Y(21),apply:async(Z)=>({stats:Z.map(()=>21),types:new Set,eids:[]}),clear:async()=>21};class ZW{inflight=null;again=!1;run(Z){if(this.again=!0,this.inflight)return this.inflight;return this.inflight=this.drain(Z),this.inflight}async flush(){if(!this.inflight)return;try{await this.inflight}catch{}}async drain(Z){try{this.again=!1;let X=await Z();while(this.again)this.again=!1,X=await Z();return X}finally{this.inflight=null}}}var XW=100;class gX{timer=null;delayMs;work;tail=new ZW;constructor(Z,X){this.delayMs=Z<0?0:Z,this.work=X}schedule(){if(this.delayMs<=0){this.fire();return}if(this.timer!==null)clearTimeout(this.timer);this.timer=setTimeout(()=>{this.timer=null,this.fire()},this.delayMs)}async flush(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null,this.fire();await this.tail.flush()}cancel(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null}fire(){return this.tail.run(this.work)}}function Ll(Z){let X=new P(Z.eid),[W,V]=a.decode(X);if(V!==0)return;return W.ts.getTime()+Z.off}function RK(Z,X){let W=Ll(Z),V=Ll(X);if(W===void 0&&V===void 0)return 0;if(W===void 0)return 1;if(V===void 0)return-1;if(V!==W)return V-W;return X.ctr-Z.ctr}function GX(Z,X){return Z.slice().sort((W,V)=>RK(X(W),X(V)))}var DZ={phase:"idle"},mX=50;function WW(Z,X,W){if(Z<=0||X<=0)return!1;if(Z===1||Z===X)return!0;return Z%W===0}function VW(Z,X){if(typeof navigator.msSaveOrOpenBlob==="function"){navigator.msSaveOrOpenBlob(Z,X);return}let W=URL.createObjectURL(Z),V=document.createElement("a");V.href=W,V.download=X,document.body.appendChild(V),V.click(),document.body.removeChild(V),URL.revokeObjectURL(W)}function Il(Z,X,W){let V=[],l=[],K=0;for(let G of Z){let m=X(G);if(l.length>0&&K+m>W)V.push(l),l=[],K=0;if(l.push(G),K+=m,K>=W)V.push(l),l=[],K=0}if(l.length>0)V.push(l);return V}async function KV(Z,X,W){let V=Z.length;if(V<1)return[];let l=Array(V),K=0,G=Math.min(Math.max(1,X),V),m=async()=>{while(!0){let J=K;if(K+=1,J>=V)return;l[J]=await W(Z[J],J)}},R=[];for(let J=0;J<G;J++)R.push(m());return await Promise.all(R),l}async function lW(Z,X,W,V){let l=new P(Z.headCph),[K,G]=l.readStruct(nX);if(G!==0)return Y(G);let{sig:m,kdm:R,headCph:J}=K;if(!await V.checkSigEd25519(m,J,X))return Y(3);let F=W.deriveCipher(R,"decrypt"),b;try{b=await F.decrypt(J)}catch{return Y(20)}return d({kdm:R,headEnc:b})}var pZ="f",UZ="t",kZ="e";function JK(Z){return Z===pZ||Z===UZ||Z===kZ}function YX(Z){if(Z===!0||Z===UZ)return UZ;if(Z===kZ)return kZ;return pZ}function CK(Z){return YX(Z.apld)===pZ}function GV(Z){return Z!==0&&Z!==15&&Z!==18&&Z!==17}function AZ(Z,X,W){if(Z.apld=X,X===kZ&&W!==void 0)Z.err=W;else delete Z.err}async function uZ(Z,X,W,V){let l=V?.body!==!1,K=YX(X.apld),G=X.body,m=G?.length??0,R;if(l&&G&&m>0)R=await W.blake3(G);let J={eid:X.eid,off:X.off??0,ctr:X.ctr??0,len:m,hsh:R},C={hash:Z,head:J,apld:K};if(l&&G!==void 0)C.body=G;if(K===kZ&&X.err!==void 0)C.err=X.err;return C}var mV=1048576,YV=1048576,pl=64;function FK(Z){return Z.sig.length+Z.kdm.length+Z.headCph.length+Z.bodyCph.length}async function dK(Z,X,W,V,l){if(V.length<1)return 0;let[K,G]=await Z.push(V);if(G!==0)return G;if(!K)return 27;for(let R of K){if(R.status!==0){console.error("push err",R);continue}let J=l[R.idx];if(!J){console.error("no hash",R);continue}await X.uploads.deq(W,[J])}let m=await X.hosts.get(W);if(m){let R=m.lastSeq,J=R,C=[];for(let F of K)if(F.status===0)C.push(F.seq);C.sort((F,b)=>F-b);for(let F of C)if(F===R+1)R=F;if(R>J)await X.hosts.touch(W,R)}return 0}async function Ql(Z,X){if(X.length<1)return d([]);let W=new Map,V=[];for(let m of X)W.set(m.seq,m),V.push(m.seq);let[l,K]=await Z.pull(V);if(K!==0)return Y(K);if(!l)return Y(27);let G=[];for(let{seq:m,bodyCph:R}of l){let J=W.get(m);if(!J)continue;G.push({dl:J,bodyCph:R})}return d(G)}async function bK(Z,X,W,V){if(V.length<1)return d({parts:[],hashes:[]});let l=[],K=[],G=[],m=new Map;for(let{dl:J,bodyCph:C}of V){let{head:F,kdm:b,seq:T,host:k}=J,[c,L]=await yl(J,W);if(L!==0||!c){let u=m.get(k)??[];u.push(T),m.set(k,u);continue}let{headEnc:p,headEncHash:Q}=c,z=X.deriveCipher(b,"decrypt"),[I,g]=await wW(p,C,z,W,Q);if(g!==0||!I){let u=m.get(k)??[];u.push(T),m.set(k,u);continue}let S={head:F,body:I.bod},j=I.headHash;G.push({key:j,data:xl(S)}),l.push(S),K.push(j);let O=m.get(k)??[];O.push(T),m.set(k,O)}let R=await Z.messages.add(G);for(let[J,C]of m)await Z.downloads.deq(J,C);for(let J=0;J<R.length;J++){let C=R[J];if(C!==0&&C!==15)console.error("ERR storing",N[C],"for message",J)}return d({parts:l,hashes:K})}async function yl(Z,X){let W=Z.headEnc;if(!W){let l=new U,K=l.writeStruct(JZ,Z.head);if(K!==0)return Y(K);W=l.result()}if(Z.headEncHash)return d({headEnc:W,headEncHash:Z.headEncHash});let V=await X.blake3(W);return d({headEnc:W,headEncHash:V})}async function zl(Z,X,W){let V=new Set;for(let G of X)V.add(H(G));if(V.size<1)return;let l=Array.from(await Z.downloads.list());if(l.length<1)return;let K=new Map;for(let G of l){let m;if(G.headEncHash)m=H(G.headEncHash);else{let[J,C]=await yl(G,W);if(C!==0||!J)continue;m=H(J.headEncHash)}if(!V.has(m))continue;let R=K.get(G.host)??[];R.push(G.seq),K.set(G.host,R)}for(let[G,m]of K)await Z.downloads.deq(G,m)}async function RV({conn:Z,store:X,enclave:W,host:V,crypto:l,onProgress:K,peekProgressEvery:G,peekConcurrency:m}){let R=await Z.identity(),J=[],[C,F]=await Z.peek(V.lastSeq);if(F!==0)return F;let b=C.length,T=G??mX,k=m??pl;if(K&&b>0)K({phase:"peek",host:V.label,done:0,total:b});let c=0,L=await KV(C,k,async(Q)=>{let[z,I]=await lW(Q,R.publicKey,W,l),g;if(I!==0||!z)g={ok:!1,seq:Q.seq,stat:I};else{let S=await l.blake3(z.headEnc);g={ok:!0,seq:Q.seq,kdm:z.kdm,headEnc:z.headEnc,headEncHash:S}}if(c+=1,K&&WW(c,b,T))K({phase:"peek",host:V.label,done:c,total:b});return g}),p=new Set;for(let Q of L){if(!Q.ok){console.error("peek: decrypting item head",Q.stat);continue}let z=H(Q.headEncHash);if(await X.messages.has(Q.headEncHash)){console.info("peek: local msg; skip download, deq upload"),await X.uploads.deq(V.label,[Q.headEncHash]),await X.downloads.deq(V.label,[Q.seq]);continue}if(p.has(z)){await X.downloads.deq(V.label,[Q.seq]);continue}let g=new P(Q.headEnc),[S,j]=g.readStruct(JZ);if(j!==0){console.error("peek: reading item head",j);continue}p.add(z),J.push({kdm:Q.kdm,head:S,seq:Q.seq,host:V.label,headEnc:Q.headEnc,headEncHash:Q.headEncHash})}if(await X.downloads.enq(J),C.length>0){let Q=Math.max(...C.map((z)=>z.seq));await X.hosts.recordStats(V.label,{lastSeq:Q})}if(K)K({phase:"peek",host:V.label,done:b,total:b});return 0}async function Nl({conn:Z,store:X,host:W,maxPushBytes:V,onProgress:l}){let K=V??mV,G=await X.uploads.list(W.label),m=G.length,R=0;if(l&&m>0)l({phase:"push",host:W.label,done:0,total:m});let J=[],C=[],F=0,b=async()=>{if(J.length<1)return 0;let T=J.length,k=await dK(Z,X,W.label,J,C);if(J=[],C=[],F=0,k===0){if(R+=T,l)l({phase:"push",host:W.label,done:R,total:m})}return k};for(let T of G){let k=await X.messages.get(T);if(!k){R+=1;continue}let c={...k.head,bod:k.body},[L,p]=await Z.seal(c);if(p!==0)return p;if(!L)return 12;let Q=FK(L);if(J.length>0&&F+Q>K){let z=await b();if(z!==0)return z}if(J.push(L),C.push(T),F+=Q,F>=K){let z=await b();if(z!==0)return z}}return b()}async function JV({conn:Z,store:X,enclave:W,host:V,crypto:l,maxPullBytes:K,onProgress:G},m){let R=K??YV,J=await X.downloads.list(),C=Array.from(J).filter((L)=>L.host===V.label);if(C.length<1)return 15;let F=GX(C,(L)=>L.head),b=Il(F,(L)=>L.head.len,R),T=F.length,k=0;if(G)G({phase:"pull",host:V.label,done:0,total:T});let c=Ql(Z,b[0]);for(let L=0;L<b.length;L++){let[p,Q]=await c;if(Q!==0||!p)return Q;if(k+=b[L].length,G)G({phase:"pull",host:V.label,done:k,total:T});let z=b[L+1];if(z)c=Ql(Z,z);if(G)G({phase:"open",host:V.label,done:k,total:T});let I=GX(p,(S)=>S.dl.head),[,g]=await bK(X,W,l,I);if(g!==0)return g;if(m){if(G)G({phase:"exec",host:V.label,done:k,total:T});await m()}}return 0}function xl({head:Z,body:X}){let W={eid:Z.eid,body:X,apld:pZ};if(Z.off!==0)W.off=Z.off;if(Z.ctr!==0)W.ctr=Z.ctr;return W}async function gl(Z,{conn:X,store:W,enclave:V,host:l,crypto:K,onProgress:G},m){let R=l.label,J=await X.identity(),C=new P(Z),[F,b]=C.readStructs(fX);if(b!==0){console.error("Failed decoding notif",N[b]);return}let T=!1,c=(await W.hosts.get(R))?.lastSeq,L=[],p=!1;for(let I of F){let[g,S]=await lW({seq:I.seq,headCph:I.headCph},J.publicKey,V,K);if(S!==0){console.error("Failed decrypting notif",N[S]);continue}let j=await K.blake3(g.headEnc);if(await W.messages.has(j))continue;let O=new P(g.headEnc),[u,E]=O.readStruct(JZ);if(E!==0){console.error("Failed to parse head",N[E]);continue}if(!I.bodyCph&&u.len>0)p=!0,await W.downloads.enq([{seq:I.seq,host:R,kdm:g.kdm,head:u,headEnc:g.headEnc,headEncHash:j}]);else L.push({...g,head:u,bodyCph:I.bodyCph,headEncHash:j});if(c===void 0||I.seq!==c+1)console.log("out of seq",I.seq,c),T=!0;else c=I.seq}if(c!==void 0)await W.hosts.touch(l.label,c);let Q=[];for(let I of L){let g=V.deriveCipher(I.kdm,"decrypt"),[S,j]=await wW(I.headEnc,I.bodyCph,g,K);if(j!==0){console.error("Failed to open body",N[j]);continue}Q.push({key:I.headEncHash,data:xl({head:I.head,body:S.bod})})}let z=await W.messages.add(Q);for(let I=0;I<z.length;I++){let g=z[I];if(g!==0&&g!==15)console.error("ERR storing",N[g],"for message",I)}if(G&&Q.length>0)G({phase:"open",host:l.label,done:Q.length,total:Q.length});if(T||p||Q.length>0)m()}async function CV(Z,X={}){let W=X.pull!==!1,V=X.push===!0,{conn:l,store:K,enclave:G,host:m,crypto:R,onProgress:J,peekProgressEvery:C,peekConcurrency:F}=Z,b=await l.identity(),[T,k]=await l.peek(0);if(k!==0)return Y(k);let c=T.length,L=C??mX,p=F??pl;if(J&&c>0)J({phase:"peek",host:m.label,done:0,total:c});let Q=0,z=await KV(T,p,async(h)=>{let[B,i]=await lW(h,b.publicKey,G,R),w;if(i!==0||!B)w={ok:!1,seq:h.seq,stat:i};else{let M=await R.blake3(B.headEnc);w={ok:!0,seq:h.seq,kdm:B.kdm,headEnc:B.headEnc,headEncHash:M}}if(Q+=1,J&&WW(Q,c,L))J({phase:"peek",host:m.label,done:Q,total:c});return w}),I=new Map;for(let h of z){if(!h.ok)continue;let B=H(h.headEncHash),i=I.get(B);if(i)i.count+=1;else I.set(B,{hash:h.headEncHash,count:1,sample:h})}let g=0,S=[];for(let h of I.values()){if(h.count>1)g+=h.count-1;S.push(h.hash)}let j=T.length,O=I.size,u=await XX(S,R),E=[],y=0;for(let h of I.values()){if(await K.messages.has(h.hash)){await K.uploads.deq(m.label,[h.hash]);continue}if(y+=1,!W)continue;let i=h.sample,w=new P(i.headEnc),[M,f]=w.readStruct(JZ);if(f!==0){console.error("reconcile: reading msg header",f);continue}E.push({kdm:i.kdm,head:M,seq:i.seq,host:m.label,headEnc:i.headEnc,headEncHash:i.headEncHash})}if(E.length>0)await K.downloads.enq(E);let A=0;if(V){let h=await K.messages.listKeys(),B=new Set(I.keys()),i=[];for(let w of h)if(!B.has(H(w)))A+=1,i.push(w);if(i.length>0)await K.uploads.enq(m.label,i)}else{let h=await K.messages.listKeys(),B=new Set(I.keys());for(let i of h)if(!B.has(H(i)))A+=1}let $=T.length>0?Math.max(...T.map((h)=>h.seq)):0;if(await K.hosts.recordStats(m.label,{setLastSeq:$}),J)J({phase:"peek",host:m.label,done:c,total:c});return d({msgcheck:u,numBags:j,uniqueMsgs:O,numDupes:g,missingLocal:y,missingHost:A})}class RX{clock;state;store;transport;crypto;forceSkewHandlingByDefault;onScheduleSync;connections=new Map;applyChain=Promise.resolve();syncRuns=new ZW;clientState;xferState;maxPushBytes;maxPullBytes;peekProgressEvery=mX;lastProgress=DZ;scheduledSync;constructor(Z,X,W,V,l,K=!0,G=mV,m=YV,R){this.clock=Z;this.state=X;this.store=W;this.transport=V;this.crypto=l;this.forceSkewHandlingByDefault=K;this.onScheduleSync=R;this.maxPushBytes=G,this.maxPullBytes=m,this.clientState=new TZ(()=>this.getClientState()),this.xferState=new TZ(()=>this.getXferState()),this.scheduledSync=new gX(XW,async()=>{try{console.info("Running scheduled sync"),await this.sync()}catch(J){console.error("Debounced sync failed:",J)}})}emitProgress=(Z)=>{this.lastProgress=Z,this.xferState.emit()};async setSeed(Z,X){await this.store.seed.save(Z,X),this.clientState.emit()}async getClientState(){let{store:Z,connections:X}=this,W=await Z.seed.load(),V=await Z.hosts.list(),l=!1;for(let K of X.values())if(K.isConnected()){l=!0;break}return{hasSeed:W!==void 0,hasHost:Array.from(V).length>0,connected:l}}async getXferState(){let{uploads:Z,downloads:X}=this.store,W=await Z.count();return{numDownloads:await X.count(),numUploads:W,progress:this.lastProgress}}apply=(Z,X)=>{return this.enqueueApplyJob(()=>this.doApply(Z,X))};async doApply(Z,X={enqueueUpload:!0,triggerUpload:!0}){let W=[],V=[];for(let{head:K,body:G}of Z){let m=new U;m.writeStruct(JZ,K);let R=m.result(),J=await this.crypto.blake3(R),C={eid:K.eid,body:G,apld:pZ};if(K.off!==0)C.off=K.off;if(K.ctr!==0)C.ctr=K.ctr;W.push(J),V.push({key:J,data:C})}await this.store.messages.add(V),await zl(this.store,W,this.crypto);let l=await this.doApplyHashes(W);if(X.enqueueUpload){let K=[];for(let G=0;G<W.length;G++){let m=l[G];if(m===0||m===15)K.push(W[G])}if(K.length>0){let G=await this.store.hosts.list();for(let m of G)await this.store.uploads.enq(m.label,K);this.xferState.emit()}}if(X.triggerUpload)this.scheduleSync();return l}enqueueApplyJob(Z){let X=this.applyChain.then(Z,Z);return this.applyChain=X.then(()=>{return},()=>{return}),X}drainApplyQueue(){return this.enqueueApplyJob(()=>this.doDrainApplyQueue())}async doDrainApplyQueue(){let Z=await this.store.messages.list({apld:pZ});if(Z.length<1)return[];let X=GX(Z,(W)=>W.head);return this.applyStored(X)}applyHashes=(Z)=>{return this.enqueueApplyJob(()=>this.doApplyHashes(Z))};async doApplyHashes(Z){let X=[];for(let l of Z){let K=await this.store.messages.get(l);if(K)X.push(K)}let W=await this.applyStored(X),V=new Map;for(let l=0;l<X.length;l++)V.set(H(X[l].hash),W[l]??12);return Z.map((l)=>V.get(H(l))??13)}async applyStored(Z){if(Z.length<1)return[];let X=Z.map((K)=>({...K.head,bod:K.body})),W=await this.state.apply(X),V=[],l=[];for(let K=0;K<Z.length;K++){let G=W[K];if(G===0||G===15)V.push(Z[K].hash);else if(G!==void 0&&GV(G))l.push({key:Z[K].hash,err:G})}if(V.length>0)await this.store.messages.markApplied(V);if(l.length>0)await this.store.messages.markFailed(l);return W}async insertRaw(Z){let{clock:X,crypto:W}=this,[V,l]=await Jl({now:X.now(),bod:Z,crypto:W});if(l!==0)return Y(l);let G=(await this.apply([{head:V,body:Z}]))[0];if(G!==0&&G!==15)return Y(G??12);return d(V)}async makeUpdate(Z,X){let{clock:W,crypto:V}=this,l=W.now();if(Z.updatedAt.getTime()>l.getTime())return Y(4);let K=Z.ctr+1,[G,m]=await rX({now:l,eid:Z.eid,ctr:K,bod:X,crypto:V});if(m!==0)return Y(m);return d({head:G,body:X})}async updateWithSkew(Z,X,W){if(W===!1)return Y(4);let{clock:V,crypto:l}=this,K=V.now(),G=new P(Z.eid),[m,R]=G.readStruct(a);if(R!==0)return Y(R);let J=Z.updatedAt.getTime()-m.ts.getTime(),C={eid:Z.eid,off:J+1,ctr:Z.ctr+1,len:0},b=(await this.apply([{head:C,body:void 0}]))[0];if(b!==0&&b!==15)return Y(b??12);if(X===void 0)return d(C);let[T,k]=ZX({id:m.id,ts:K});if(k!==0)return Y(k);let[c,L]=await rX({now:K,eid:T,ctr:0,bod:X,crypto:l});if(L!==0)return Y(L);let Q=(await this.apply([{head:c,body:X}]))[0];if(Q!==0&&Q!==15)return Y(Q??12);return d(c)}async updateRaw(Z,X,W=this.forceSkewHandlingByDefault){if(Z.updatedAt.getTime()>this.clock.now().getTime())return this.updateWithSkew(Z,X,W);return this.enqueueApplyJob(async()=>{let[V,l]=await this.makeUpdate(Z,X);if(l!==0)return Y(l);let G=(await this.doApply([V]))[0];if(G!==0&&G!==15)return Y(G??12);return d(V.head)})}async insert(Z){let{body:X,type:W,gid:V,pid:l,tags:K}=Z,m=wZ({body:X,type:W,gid:V,pid:l,tags:K});return this.insertRaw(m)}async update(Z){let{prior:X,body:W,type:V,gid:l,pid:K,tags:G,force:m}=Z,J=wZ({body:W,type:V,gid:l,pid:K,tags:G});return this.updateRaw(X,J,m??this.forceSkewHandlingByDefault)}async delete(Z){let X=Z.force??!0;if("prior"in Z)return this.updateRaw(Z.prior,void 0,X);let[W,V]=await this.revFromArchive(Z.eid);if(V!==0)return Y(V);return this.updateRaw(W,void 0,X)}async revFromArchive(Z){let X=await this.store.messages.last(Z);if(X)return lV(X.head);let W=new P(Z),[V,l]=W.readStruct(a);if(l!==0)return Y(l);return d({eid:Z,ctr:-1,updatedAt:V.ts})}async genEID(Z){let{clock:X,crypto:W}=this,V=X.now();if(Z!==void 0)return ZX({id:Z,ts:V});let l=await W.genRandomBytes(8);return ZX({id:l,ts:V})}sync(){return this.syncRuns.run(()=>this.doSync())}async doSync(){let{connections:Z,crypto:X,store:W}=this,V=await W.seed.load();if(!V)return 22;await this.drainApplyQueue();for(let[l,K]of Z){let G=await W.hosts.get(l);if(!G)continue;let m={conn:K,store:W,enclave:V,host:G,crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},R=await RV(m);if(R!==0)return console.error(`Failed to peek: ${R}`),this.emitProgress({phase:"idle"}),R;this.xferState.emit();let J=await Nl(m);if(J!==0)return console.error(`Failed to push: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await JV(m,async()=>{await this.drainApplyQueue()});if(C!==0&&C!==15)return console.error(`Failed to pull: ${C}`),this.emitProgress({phase:"idle"}),C;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async rebuild(Z){if(this.scheduledSync.cancel(),await this.syncRuns.flush(),Z?.checkHost??!0){let W=await this.repull();if(W!==0)return W}return this.enqueueApplyJob(()=>this.replay())}async msgcheck(){let Z=await this.store.messages.listKeys();return XX(Z,this.crypto)}listMsgs(Z){return this.store.messages.list(Z)}countMsgs(Z){return this.store.messages.count(Z)}async reconcile(Z,X){this.scheduledSync.cancel(),await this.syncRuns.flush();let{connections:W,crypto:V,store:l}=this,K=await l.seed.load();if(!K)return Y(22);let G=await l.hosts.get(Z);if(!G)return Y(13);let m=W.get(Z);if(!m||!m.isConnected()){if(await this.connectToHost(G,!1,!1),G=await l.hosts.get(Z),!G)return Y(13);m=W.get(Z)}if(!m)return Y(12);let R={conn:m,store:l,enclave:K,crypto:V,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},[J,C]=await CV({...R,host:G},X);if(this.xferState.emit(),C!==0)return this.emitProgress({phase:"idle"}),Y(C);if(!J)return this.emitProgress({phase:"idle"}),Y(12);if(X?.sync===!1)return this.emitProgress({phase:"idle"}),d(J);let F=await this.sync();if(F!==0)return Y(F);let b=await l.hosts.get(Z);if(!b)return Y(13);let[T,k]=await CV({...R,host:b},{pull:!1,push:!1});if(this.xferState.emit(),this.emitProgress({phase:"idle"}),k!==0)return Y(k);if(!T)return Y(12);return d(T)}async repull(){let{connections:Z,crypto:X,store:W}=this,V=await W.seed.load();if(!V)return 22;let l=Array.from(await W.hosts.list());if(l.length<1)return 0;for(let K of l){let G=Z.get(K.label);if(!G||!G.isConnected())await this.connectToHost(K,!1,!1)}for(let[K,G]of Z){let m=await W.hosts.get(K);if(!m)continue;let R={conn:G,store:W,enclave:V,host:{...m,lastSeq:0},crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},J=await RV(R);if(J!==0)return console.error(`rebuild: failed to peek: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await JV(R);if(C!==0&&C!==15)return console.error(`rebuild: failed to pull: ${C}`),this.emitProgress({phase:"idle"}),C;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async replay(){let Z=await this.state.clear();if(Z!==0)return Z;let X=await this.store.messages.list(),W=GX(X,(K)=>K.head),V=W.length;if(V<1)return this.emitProgress({phase:"idle"}),0;let l=0;while(l<W.length){let K=0,G=0,m=l;for(let J=l;J<W.length&&G<100&&K<102400;J++)K+=W[J].head.len,G++,m=J+1;let R=W.slice(l,m);await this.applyStored(R),this.emitProgress({phase:"exec",done:m,total:V}),l=m}return this.emitProgress({phase:"idle"}),0}async wipe(Z){let X=Z?.msgs!==!1,W=Z?.ents!==!1,V=Z?.meta!==!1,l=Z?.seed===!0;this.scheduledSync.cancel(),await this.disconnect(),await this.syncRuns.flush();let{store:K}=this;if(V)await K.hosts.wipe(),await K.uploads.wipe(),await K.downloads.wipe();if(X)await K.messages.wipe();if(l)await K.seed.wipe();if(W)await this.state.clear();this.lastProgress=DZ,this.clientState.emit(),this.xferState.emit()}import=async(Z,X)=>{let{crypto:W,store:V}=this,l=X?.onProgress,K=await V.seed.load();if(!K)return 22;console.time("import: decoding file...");let G=await Z.bytes(),[m,R]=await Rl(G,W,K);if(R!==0)return R;console.timeEnd("import: decoding file...");let J=0;while(J<m.length){let C=0,F=0,b=J;for(let c=J;c<m.length&&F<100&&C<102400;c++)C+=m[c].head.len,F++,b=c+1;let T=m.slice(J,b);console.time(`import: applying [${J}, ${b}]`);let k=await this.apply(T,{enqueueUpload:!0,triggerUpload:!1});console.timeEnd(`import: applying [${J}, ${b}]`);for(let c=0;c<T.length;c++){let L=k[c];if(L!==0&&L!==15)console.warn(`failed to import msg ${J+c}: ${N[L]}`)}if(l)queueMicrotask(()=>l(b,m.length,0));this.emitProgress({phase:"import",done:b,total:m.length}),J=b}return this.scheduleSync(),this.emitProgress({phase:"idle"}),0};scheduleSync=()=>{if(this.onScheduleSync){this.onScheduleSync();return}this.scheduledSync.schedule()};async exportBytes(){let{crypto:Z,store:X}=this,W=await X.seed.load();if(!W)return Y(22);let V=await X.messages.list();return Yl("export",0,V,Z,W)}async export(Z){let[X,W]=await this.exportBytes();if(W!==0)return W;if(!X)return 12;let V=new Blob([X.slice()]);return VW(V,Z),0}async link(Z,X=!0){if(await this.store.hosts.add(Z),this.clientState.emit(),X){let W=await this.store.hosts.get(Z.label);if(W)await this.connectToHost(W)}}async unlink(Z){await this.store.hosts.del(Z),this.clientState.emit()}async hosts(){return Array.from(await this.store.hosts.list())}connectToHost=async(Z,X=!0,W=!0)=>{let{clock:V,connections:l,crypto:K,store:G,transport:m}=this,R=l.get(Z.label);if(R){if(R.isConnected())return;try{R.closeListener()}catch{}l.delete(Z.label)}let J=await G.seed.load();if(!J)return;console.info(`Connecting to ${Z.handle} (${Z.label})`);let C=new aX(J,K,Z,V,m(Z),(F)=>G.hosts.set(Z.label,F));if(await C.register(),X)await C.listen(async(F)=>{let b={conn:C,store:G,enclave:J,host:Z,crypto:K,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery};return gl(F,b,this.scheduleSync)},()=>this.clientState.emit(),()=>this.clientState.emit());if(l.set(Z.label,C),this.clientState.emit(),W)this.scheduleSync()};async connect(Z=!0,X=!0){let{connectToHost:W,scheduleSync:V,store:l}=this;if(!await l.seed.load())return;await this.drainApplyQueue();let G=await l.hosts.list();for(let m of G)await W(m,Z,!1);if(X)V()}disconnect=async()=>{for(let Z of this.connections.values())try{Z.closeListener()}catch{}this.connections.clear(),this.clientState.emit()}}var vZ=typeof globalThis==="object"&&"crypto"in globalThis?globalThis.crypto:void 0;function KW(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function FV(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function _(Z,...X){if(!FV(Z))throw Error("Uint8Array expected");if(X.length>0&&!X.includes(Z.length))throw Error("Uint8Array expected of length "+X+", got length="+Z.length)}function dV(Z,X=!0){if(Z.destroyed)throw Error("Hash instance has been destroyed");if(X&&Z.finished)throw Error("Hash#digest() has already been called")}function Ml(Z,X){_(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function bV(Z){if(typeof Z!=="boolean")throw Error(`boolean expected, not ${Z}`)}/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */var yZ=(Z)=>new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4));var TK=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!TK)throw Error("Non little-endian hardware is not supported");function kK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function GW(Z){if(typeof Z==="string")Z=kK(Z);else if(FV(Z))Z=mW(Z);else throw Error("Uint8Array expected, got "+typeof Z);return Z}function Hl(Z,X){if(X==null||typeof X!=="object")throw Error("options must be defined");return Object.assign(Z,X)}function hl(Z,X){if(Z.length!==X.length)return!1;let W=0;for(let V=0;V<Z.length;V++)W|=Z[V]^X[V];return W===0}var Sl=(Z,X)=>{function W(V,...l){if(_(V),Z.nonceLength!==void 0){let C=l[0];if(!C)throw Error("nonce / iv required");if(Z.varSizeNonce)_(C);else _(C,Z.nonceLength)}let K=Z.tagLength;if(K&&l[1]!==void 0)_(l[1]);let G=X(V,...l),m=(C,F)=>{if(F!==void 0){if(C!==2)throw Error("cipher output not supported");_(F)}},R=!1;return{encrypt(C,F){if(R)throw Error("cannot encrypt() twice with same key + nonce");return R=!0,_(C),m(G.encrypt.length,F),G.encrypt(C,F)},decrypt(C,F){if(_(C),K&&C.length<K)throw Error("invalid ciphertext length: smaller than tagLength="+K);return m(G.decrypt.length,F),G.decrypt(C,F)}}}return Object.assign(W,Z),W};function TV(Z,X,W=!0){if(X===void 0)return new Uint8Array(Z);if(X.length!==Z)throw Error("invalid output length, expected "+Z+", got: "+X.length);if(W&&!cK(X))throw Error("invalid output, must be aligned");return X}function cK(Z){return Z.byteOffset%4===0}function mW(Z){return Uint8Array.from(Z)}function cZ(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function YW(Z=32){if(vZ&&typeof vZ.getRandomValues==="function")return vZ.getRandomValues(new Uint8Array(Z));if(vZ&&typeof vZ.randomBytes==="function")return vZ.randomBytes(Z);throw Error("crypto.getRandomValues must be defined")}var Ul=(Z)=>Uint8Array.from(Z.split("").map((X)=>X.charCodeAt(0))),LK=Ul("expand 16-byte k"),IK=Ul("expand 32-byte k"),QK=yZ(LK),pK=yZ(IK);function x(Z,X){return Z<<X|Z>>>32-X}function kV(Z){return Z.byteOffset%4===0}var RW=64,yK=16,ul=4294967295,Pl=new Uint32Array;function zK(Z,X,W,V,l,K,G,m){let R=l.length,J=new Uint8Array(RW),C=yZ(J),F=kV(l)&&kV(K),b=F?yZ(l):Pl,T=F?yZ(K):Pl;for(let k=0;k<R;G++){if(Z(X,W,V,C,G,m),G>=ul)throw Error("arx: counter overflow");let c=Math.min(RW,R-k);if(F&&c===RW){let L=k/4;if(k%4!==0)throw Error("arx: invalid block position");for(let p=0,Q;p<yK;p++)Q=L+p,T[Q]=b[Q]^C[p];k+=RW;continue}for(let L=0,p;L<c;L++)p=k+L,K[p]=l[p]^J[L];k+=c}}function il(Z,X){let{allowShortKeys:W,extendNonceFn:V,counterLength:l,counterRight:K,rounds:G}=Hl({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},X);if(typeof Z!=="function")throw Error("core must be a function");return KW(l),KW(G),bV(K),bV(W),(m,R,J,C,F=0)=>{_(m),_(R),_(J);let b=J.length;if(C===void 0)C=new Uint8Array(b);if(_(C),KW(F),F<0||F>=ul)throw Error("arx: counter overflow");if(C.length<b)throw Error(`arx: output (${C.length}) is shorter than data (${b})`);let T=[],k=m.length,c,L;if(k===32)T.push(c=mW(m)),L=pK;else if(k===16&&W)c=new Uint8Array(32),c.set(m),c.set(m,16),L=QK,T.push(c);else throw Error(`arx: invalid 32-byte key, got length=${k}`);if(!kV(R))T.push(R=mW(R));let p=yZ(c);if(V){if(R.length!==24)throw Error("arx: extended nonce must be 24 bytes");V(L,p,yZ(R.subarray(0,16)),p),R=R.subarray(16)}let Q=16-l;if(Q!==R.length)throw Error(`arx: nonce must be ${Q} or 16 bytes`);if(Q!==12){let I=new Uint8Array(12);I.set(R,K?0:12-R.length),R=I,T.push(R)}let z=yZ(R);return zK(Z,L,p,z,J,C,F,G),cZ(...T),C}}var s=(Z,X)=>Z[X++]&255|(Z[X++]&255)<<8;class Ol{constructor(Z){this.blockLen=16,this.outputLen=16,this.buffer=new Uint8Array(16),this.r=new Uint16Array(10),this.h=new Uint16Array(10),this.pad=new Uint16Array(8),this.pos=0,this.finished=!1,Z=GW(Z),_(Z,32);let X=s(Z,0),W=s(Z,2),V=s(Z,4),l=s(Z,6),K=s(Z,8),G=s(Z,10),m=s(Z,12),R=s(Z,14);this.r[0]=X&8191,this.r[1]=(X>>>13|W<<3)&8191,this.r[2]=(W>>>10|V<<6)&7939,this.r[3]=(V>>>7|l<<9)&8191,this.r[4]=(l>>>4|K<<12)&255,this.r[5]=K>>>1&8190,this.r[6]=(K>>>14|G<<2)&8191,this.r[7]=(G>>>11|m<<5)&8065,this.r[8]=(m>>>8|R<<8)&8191,this.r[9]=R>>>5&127;for(let J=0;J<8;J++)this.pad[J]=s(Z,16+2*J)}process(Z,X,W=!1){let V=W?0:2048,{h:l,r:K}=this,G=K[0],m=K[1],R=K[2],J=K[3],C=K[4],F=K[5],b=K[6],T=K[7],k=K[8],c=K[9],L=s(Z,X+0),p=s(Z,X+2),Q=s(Z,X+4),z=s(Z,X+6),I=s(Z,X+8),g=s(Z,X+10),S=s(Z,X+12),j=s(Z,X+14),O=l[0]+(L&8191),u=l[1]+((L>>>13|p<<3)&8191),E=l[2]+((p>>>10|Q<<6)&8191),y=l[3]+((Q>>>7|z<<9)&8191),A=l[4]+((z>>>4|I<<12)&8191),$=l[5]+(I>>>1&8191),h=l[6]+((I>>>14|g<<2)&8191),B=l[7]+((g>>>11|S<<5)&8191),i=l[8]+((S>>>8|j<<8)&8191),w=l[9]+(j>>>5|V),M=0,f=M+O*G+u*(5*c)+E*(5*k)+y*(5*T)+A*(5*b);M=f>>>13,f&=8191,f+=$*(5*F)+h*(5*C)+B*(5*J)+i*(5*R)+w*(5*m),M+=f>>>13,f&=8191;let ZZ=M+O*m+u*G+E*(5*c)+y*(5*k)+A*(5*T);M=ZZ>>>13,ZZ&=8191,ZZ+=$*(5*b)+h*(5*F)+B*(5*C)+i*(5*J)+w*(5*R),M+=ZZ>>>13,ZZ&=8191;let mZ=M+O*R+u*m+E*G+y*(5*c)+A*(5*k);M=mZ>>>13,mZ&=8191,mZ+=$*(5*T)+h*(5*b)+B*(5*F)+i*(5*C)+w*(5*J),M+=mZ>>>13,mZ&=8191;let o=M+O*J+u*R+E*m+y*G+A*(5*c);M=o>>>13,o&=8191,o+=$*(5*k)+h*(5*T)+B*(5*b)+i*(5*F)+w*(5*C),M+=o>>>13,o&=8191;let IZ=M+O*C+u*J+E*R+y*m+A*G;M=IZ>>>13,IZ&=8191,IZ+=$*(5*c)+h*(5*k)+B*(5*T)+i*(5*b)+w*(5*F),M+=IZ>>>13,IZ&=8191;let fZ=M+O*F+u*C+E*J+y*R+A*m;M=fZ>>>13,fZ&=8191,fZ+=$*G+h*(5*c)+B*(5*k)+i*(5*T)+w*(5*b),M+=fZ>>>13,fZ&=8191;let nZ=M+O*b+u*F+E*C+y*J+A*R;M=nZ>>>13,nZ&=8191,nZ+=$*m+h*G+B*(5*c)+i*(5*k)+w*(5*T),M+=nZ>>>13,nZ&=8191;let _Z=M+O*T+u*b+E*F+y*C+A*J;M=_Z>>>13,_Z&=8191,_Z+=$*R+h*m+B*G+i*(5*c)+w*(5*k),M+=_Z>>>13,_Z&=8191;let aZ=M+O*k+u*T+E*b+y*F+A*C;M=aZ>>>13,aZ&=8191,aZ+=$*J+h*R+B*m+i*G+w*(5*c),M+=aZ>>>13,aZ&=8191;let rZ=M+O*c+u*k+E*T+y*b+A*F;M=rZ>>>13,rZ&=8191,rZ+=$*C+h*J+B*R+i*m+w*G,M+=rZ>>>13,rZ&=8191,M=(M<<2)+M|0,M=M+f|0,f=M&8191,M=M>>>13,ZZ+=M,l[0]=f,l[1]=ZZ,l[2]=mZ,l[3]=o,l[4]=IZ,l[5]=fZ,l[6]=nZ,l[7]=_Z,l[8]=aZ,l[9]=rZ}finalize(){let{h:Z,pad:X}=this,W=new Uint16Array(10),V=Z[1]>>>13;Z[1]&=8191;for(let G=2;G<10;G++)Z[G]+=V,V=Z[G]>>>13,Z[G]&=8191;Z[0]+=V*5,V=Z[0]>>>13,Z[0]&=8191,Z[1]+=V,V=Z[1]>>>13,Z[1]&=8191,Z[2]+=V,W[0]=Z[0]+5,V=W[0]>>>13,W[0]&=8191;for(let G=1;G<10;G++)W[G]=Z[G]+V,V=W[G]>>>13,W[G]&=8191;W[9]-=8192;let l=(V^1)-1;for(let G=0;G<10;G++)W[G]&=l;l=~l;for(let G=0;G<10;G++)Z[G]=Z[G]&l|W[G];Z[0]=(Z[0]|Z[1]<<13)&65535,Z[1]=(Z[1]>>>3|Z[2]<<10)&65535,Z[2]=(Z[2]>>>6|Z[3]<<7)&65535,Z[3]=(Z[3]>>>9|Z[4]<<4)&65535,Z[4]=(Z[4]>>>12|Z[5]<<1|Z[6]<<14)&65535,Z[5]=(Z[6]>>>2|Z[7]<<11)&65535,Z[6]=(Z[7]>>>5|Z[8]<<8)&65535,Z[7]=(Z[8]>>>8|Z[9]<<5)&65535;let K=Z[0]+X[0];Z[0]=K&65535;for(let G=1;G<8;G++)K=(Z[G]+X[G]|0)+(K>>>16)|0,Z[G]=K&65535;cZ(W)}update(Z){dV(this);let{buffer:X,blockLen:W}=this;Z=GW(Z);let V=Z.length;for(let l=0;l<V;){let K=Math.min(W-this.pos,V-l);if(K===W){for(;W<=V-l;l+=W)this.process(Z,l);continue}if(X.set(Z.subarray(l,l+K),this.pos),this.pos+=K,l+=K,this.pos===W)this.process(X,0,!1),this.pos=0}return this}destroy(){cZ(this.h,this.r,this.buffer,this.pad)}digestInto(Z){dV(this),Ml(Z,this),this.finished=!0;let{buffer:X,h:W}=this,{pos:V}=this;if(V){X[V++]=1;for(;V<16;V++)X[V]=0;this.process(X,0,!0)}this.finalize();let l=0;for(let K=0;K<8;K++)Z[l++]=W[K]>>>0,Z[l++]=W[K]>>>8;return Z}digest(){let{buffer:Z,outputLen:X}=this;this.digestInto(Z);let W=Z.slice(0,X);return this.destroy(),W}}function NK(Z){let X=(V,l)=>Z(l).update(GW(V)).digest(),W=Z(new Uint8Array(32));return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var cV=NK((Z)=>new Ol(Z));function xK(Z,X,W,V,l,K=20){let G=Z[0],m=X[0],R=X[1],J=X[2],C=X[3],F=Z[1],b=W[0],T=W[1],k=l,c=0,L=Z[2],p=X[4],Q=X[5],z=X[6],I=X[7],g=Z[3],S=G,j=m,O=R,u=J,E=C,y=F,A=b,$=T,h=k,B=c,i=L,w=p,M=Q,f=z,ZZ=I,mZ=g;for(let IZ=0;IZ<K;IZ+=2)E^=x(S+M|0,7),h^=x(E+S|0,9),M^=x(h+E|0,13),S^=x(M+h|0,18),B^=x(y+j|0,7),f^=x(B+y|0,9),j^=x(f+B|0,13),y^=x(j+f|0,18),ZZ^=x(i+A|0,7),O^=x(ZZ+i|0,9),A^=x(O+ZZ|0,13),i^=x(A+O|0,18),u^=x(mZ+w|0,7),$^=x(u+mZ|0,9),w^=x($+u|0,13),mZ^=x(w+$|0,18),j^=x(S+u|0,7),O^=x(j+S|0,9),u^=x(O+j|0,13),S^=x(u+O|0,18),A^=x(y+E|0,7),$^=x(A+y|0,9),E^=x($+A|0,13),y^=x(E+$|0,18),w^=x(i+B|0,7),h^=x(w+i|0,9),B^=x(h+w|0,13),i^=x(B+h|0,18),M^=x(mZ+ZZ|0,7),f^=x(M+mZ|0,9),ZZ^=x(f+M|0,13),mZ^=x(ZZ+f|0,18);let o=0;V[o++]=G+S|0,V[o++]=m+j|0,V[o++]=R+O|0,V[o++]=J+u|0,V[o++]=C+E|0,V[o++]=F+y|0,V[o++]=b+A|0,V[o++]=T+$|0,V[o++]=k+h|0,V[o++]=c+B|0,V[o++]=L+i|0,V[o++]=p+w|0,V[o++]=Q+M|0,V[o++]=z+f|0,V[o++]=I+ZZ|0,V[o++]=g+mZ|0}function gK(Z,X,W,V){let l=Z[0],K=X[0],G=X[1],m=X[2],R=X[3],J=Z[1],C=W[0],F=W[1],b=W[2],T=W[3],k=Z[2],c=X[4],L=X[5],p=X[6],Q=X[7],z=Z[3];for(let g=0;g<20;g+=2)R^=x(l+L|0,7),b^=x(R+l|0,9),L^=x(b+R|0,13),l^=x(L+b|0,18),T^=x(J+K|0,7),p^=x(T+J|0,9),K^=x(p+T|0,13),J^=x(K+p|0,18),Q^=x(k+C|0,7),G^=x(Q+k|0,9),C^=x(G+Q|0,13),k^=x(C+G|0,18),m^=x(z+c|0,7),F^=x(m+z|0,9),c^=x(F+m|0,13),z^=x(c+F|0,18),K^=x(l+m|0,7),G^=x(K+l|0,9),m^=x(G+K|0,13),l^=x(m+G|0,18),C^=x(J+R|0,7),F^=x(C+J|0,9),R^=x(F+C|0,13),J^=x(R+F|0,18),c^=x(k+T|0,7),b^=x(c+k|0,9),T^=x(b+c|0,13),k^=x(T+b|0,18),L^=x(z+Q|0,7),p^=x(L+z|0,9),Q^=x(p+L|0,13),z^=x(Q+p|0,18);let I=0;V[I++]=l,V[I++]=J,V[I++]=k,V[I++]=z,V[I++]=C,V[I++]=F,V[I++]=b,V[I++]=T}var LV=il(xK,{counterRight:!0,extendNonceFn:gK}),IV=Sl({blockSize:64,nonceLength:24,tagLength:16},(Z,X)=>{return{encrypt(W,V){V=TV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32);V.set(W,32),cZ(l),LV(Z,X,V,V);let G=cV(K,l);return V.set(G,16),cZ(V.subarray(0,16),G),V.subarray(16)},decrypt(W,V){_(W),V=TV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32,48),G=V.subarray(48);V.set(W,32),cZ(l);let m=LV(Z,X,l,l),R=cV(G,m);if(!hl(K,R))throw Error("invalid tag");return LV(Z,X,V.subarray(16),V.subarray(16)),cZ(l,K,R),G}}});/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function MK(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function MX(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function $Z(Z,...X){if(!MK(Z))throw Error("Uint8Array expected");if(X.length>0&&!X.includes(Z.length))throw Error("Uint8Array expected of length "+X+", got length="+Z.length)}function HX(Z,X=!0){if(Z.destroyed)throw Error("Hash instance has been destroyed");if(X&&Z.finished)throw Error("Hash#digest() has already been called")}function JW(Z,X){$Z(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function jl(Z){return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength)}function JX(Z){return new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4))}function CX(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function hX(Z,X){return Z<<32-X|Z>>>X}var Bl=(()=>new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68)();function El(Z){return Z<<24&4278190080|Z<<8&16711680|Z>>>8&65280|Z>>>24&255}var wl=Bl?(Z)=>Z:(Z)=>El(Z);function HK(Z){for(let X=0;X<Z.length;X++)Z[X]=El(Z[X]);return Z}var VZ=Bl?(Z)=>Z:HK;function hK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function FX(Z){if(typeof Z==="string")Z=hK(Z);return $Z(Z),Z}class QV{}function Dl(Z){let X=(V,l)=>Z(l).update(FX(V)).digest(),W=Z({});return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var Al=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var CW=BigInt(4294967295),vl=BigInt(32);function pV(Z,X=!1){if(X)return{h:Number(Z&CW),l:Number(Z>>vl&CW)};return{h:Number(Z>>vl&CW)|0,l:Number(Z&CW)|0}}function zZ(Z,X,W,V,l){return Z=Z+X+l|0,V=hX(V^Z,16),W=W+V|0,X=hX(X^W,12),{a:Z,b:X,c:W,d:V}}function NZ(Z,X,W,V,l){return Z=Z+X+l|0,V=hX(V^Z,8),W=W+V|0,X=hX(X^W,7),{a:Z,b:X,c:W,d:V}}class yV extends QV{constructor(Z,X){super();this.finished=!1,this.destroyed=!1,this.length=0,this.pos=0,MX(Z),MX(X),this.blockLen=Z,this.outputLen=X,this.buffer=new Uint8Array(Z),this.buffer32=JX(this.buffer)}update(Z){HX(this),Z=FX(Z),$Z(Z);let{blockLen:X,buffer:W,buffer32:V}=this,l=Z.length,K=Z.byteOffset,G=Z.buffer;for(let m=0;m<l;){if(this.pos===X)VZ(V),this.compress(V,0,!1),VZ(V),this.pos=0;let R=Math.min(X-this.pos,l-m),J=K+m;if(R===X&&!(J%4)&&m+R<l){let C=new Uint32Array(G,J,Math.floor((l-m)/4));VZ(C);for(let F=0;m+X<l;F+=V.length,m+=X)this.length+=X,this.compress(C,F,!1);VZ(C);continue}W.set(Z.subarray(m,m+R),this.pos),this.pos+=R,this.length+=R,m+=R}return this}digestInto(Z){HX(this),JW(Z,this);let{pos:X,buffer32:W}=this;this.finished=!0,CX(this.buffer.subarray(X)),VZ(W),this.compress(W,0,!0),VZ(W);let V=JX(Z);this.get().forEach((l,K)=>V[K]=wl(l))}digest(){let{buffer:Z,outputLen:X}=this;this.digestInto(Z);let W=Z.slice(0,X);return this.destroy(),W}_cloneInto(Z){let{buffer:X,length:W,finished:V,destroyed:l,outputLen:K,pos:G}=this;return Z||(Z=new this.constructor({dkLen:K})),Z.set(...this.get()),Z.buffer.set(X),Z.destroyed=l,Z.finished=V,Z.length=W,Z.pos=G,Z.outputLen=K,Z}clone(){return this._cloneInto()}}function zV(Z,X,W,V,l,K,G,m,R,J,C,F,b,T,k,c,L,p,Q,z){let I=0;for(let g=0;g<V;g++)({a:l,b:R,c:b,d:L}=zZ(l,R,b,L,W[X+Z[I++]])),{a:l,b:R,c:b,d:L}=NZ(l,R,b,L,W[X+Z[I++]]),{a:K,b:J,c:T,d:p}=zZ(K,J,T,p,W[X+Z[I++]]),{a:K,b:J,c:T,d:p}=NZ(K,J,T,p,W[X+Z[I++]]),{a:G,b:C,c:k,d:Q}=zZ(G,C,k,Q,W[X+Z[I++]]),{a:G,b:C,c:k,d:Q}=NZ(G,C,k,Q,W[X+Z[I++]]),{a:m,b:F,c,d:z}=zZ(m,F,c,z,W[X+Z[I++]]),{a:m,b:F,c,d:z}=NZ(m,F,c,z,W[X+Z[I++]]),{a:l,b:J,c:k,d:z}=zZ(l,J,k,z,W[X+Z[I++]]),{a:l,b:J,c:k,d:z}=NZ(l,J,k,z,W[X+Z[I++]]),{a:K,b:C,c,d:L}=zZ(K,C,c,L,W[X+Z[I++]]),{a:K,b:C,c,d:L}=NZ(K,C,c,L,W[X+Z[I++]]),{a:G,b:F,c:b,d:p}=zZ(G,F,b,p,W[X+Z[I++]]),{a:G,b:F,c:b,d:p}=NZ(G,F,b,p,W[X+Z[I++]]),{a:m,b:R,c:T,d:Q}=zZ(m,R,T,Q,W[X+Z[I++]]),{a:m,b:R,c:T,d:Q}=NZ(m,R,T,Q,W[X+Z[I++]]);return{v0:l,v1:K,v2:G,v3:m,v4:R,v5:J,v6:C,v7:F,v8:b,v9:T,v10:k,v11:c,v12:L,v13:p,v14:Q,v15:z}}var LZ={CHUNK_START:1,CHUNK_END:2,PARENT:4,ROOT:8,KEYED_HASH:16,DERIVE_KEY_CONTEXT:32,DERIVE_KEY_MATERIAL:64},xZ=Al.slice(),$l=(()=>{let Z=Array.from({length:16},(V,l)=>l),X=(V)=>[2,6,3,10,7,0,4,13,1,11,12,5,9,14,15,8].map((l)=>V[l]),W=[];for(let V=0,l=Z;V<7;V++,l=X(l))W.push(...l);return Uint8Array.from(W)})();class NV extends yV{constructor(Z={},X=0){super(64,Z.dkLen===void 0?32:Z.dkLen);this.chunkPos=0,this.chunksDone=0,this.flags=0,this.stack=[],this.posOut=0,this.bufferOut32=new Uint32Array(16),this.chunkOut=0,this.enableXOF=!0;let{key:W,context:V}=Z,l=V!==void 0;if(W!==void 0){if(l)throw Error('Only "key" or "context" can be specified at same time');let K=FX(W).slice();$Z(K,32),this.IV=JX(K),VZ(this.IV),this.flags=X|LZ.KEYED_HASH}else if(l){let K=FX(V),G=new NV({dkLen:32},LZ.DERIVE_KEY_CONTEXT).update(K).digest();this.IV=JX(G),VZ(this.IV),this.flags=X|LZ.DERIVE_KEY_MATERIAL}else this.IV=xZ.slice(),this.flags=X;this.state=this.IV.slice(),this.bufferOut=jl(this.bufferOut32)}get(){return[]}set(){}b2Compress(Z,X,W,V=0){let{state:l,pos:K}=this,{h:G,l:m}=pV(BigInt(Z),!0),{v0:R,v1:J,v2:C,v3:F,v4:b,v5:T,v6:k,v7:c,v8:L,v9:p,v10:Q,v11:z,v12:I,v13:g,v14:S,v15:j}=zV($l,V,W,7,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],xZ[0],xZ[1],xZ[2],xZ[3],G,m,K,X);l[0]=R^L,l[1]=J^p,l[2]=C^Q,l[3]=F^z,l[4]=b^I,l[5]=T^g,l[6]=k^S,l[7]=c^j}compress(Z,X=0,W=!1){let V=this.flags;if(!this.chunkPos)V|=LZ.CHUNK_START;if(this.chunkPos===15||W)V|=LZ.CHUNK_END;if(!W)this.pos=this.blockLen;if(this.b2Compress(this.chunksDone,V,Z,X),this.chunkPos+=1,this.chunkPos===16||W){let l=this.state;this.state=this.IV.slice();for(let K,G=this.chunksDone+1;W||!(G&1);G>>=1){if(!(K=this.stack.pop()))break;this.buffer32.set(K,0),this.buffer32.set(l,8),this.pos=this.blockLen,this.b2Compress(0,this.flags|LZ.PARENT,this.buffer32,0),l=this.state,this.state=this.IV.slice()}this.chunksDone++,this.chunkPos=0,this.stack.push(l)}this.pos=0}_cloneInto(Z){Z=super._cloneInto(Z);let{IV:X,flags:W,state:V,chunkPos:l,posOut:K,chunkOut:G,stack:m,chunksDone:R}=this;return Z.state.set(V.slice()),Z.stack=m.map((J)=>Uint32Array.from(J)),Z.IV.set(X),Z.flags=W,Z.chunkPos=l,Z.chunksDone=R,Z.posOut=K,Z.chunkOut=G,Z.enableXOF=this.enableXOF,Z.bufferOut32.set(this.bufferOut32),Z}destroy(){this.destroyed=!0,CX(this.state,this.buffer32,this.IV,this.bufferOut32),CX(...this.stack)}b2CompressOut(){let{state:Z,pos:X,flags:W,buffer32:V,bufferOut32:l}=this,{h:K,l:G}=pV(BigInt(this.chunkOut++));VZ(V);let{v0:m,v1:R,v2:J,v3:C,v4:F,v5:b,v6:T,v7:k,v8:c,v9:L,v10:p,v11:Q,v12:z,v13:I,v14:g,v15:S}=zV($l,0,V,7,Z[0],Z[1],Z[2],Z[3],Z[4],Z[5],Z[6],Z[7],xZ[0],xZ[1],xZ[2],xZ[3],G,K,X,W);l[0]=m^c,l[1]=R^L,l[2]=J^p,l[3]=C^Q,l[4]=F^z,l[5]=b^I,l[6]=T^g,l[7]=k^S,l[8]=Z[0]^c,l[9]=Z[1]^L,l[10]=Z[2]^p,l[11]=Z[3]^Q,l[12]=Z[4]^z,l[13]=Z[5]^I,l[14]=Z[6]^g,l[15]=Z[7]^S,VZ(V),VZ(l),this.posOut=0}finish(){if(this.finished)return;this.finished=!0,CX(this.buffer.subarray(this.pos));let Z=this.flags|LZ.ROOT;if(this.stack.length)Z|=LZ.PARENT,VZ(this.buffer32),this.compress(this.buffer32,0,!0),VZ(this.buffer32),this.chunksDone=0,this.pos=this.blockLen;else Z|=(!this.chunkPos?LZ.CHUNK_START:0)|LZ.CHUNK_END;this.flags=Z,this.b2CompressOut()}writeInto(Z){HX(this,!1),$Z(Z),this.finish();let{blockLen:X,bufferOut:W}=this;for(let V=0,l=Z.length;V<l;){if(this.posOut>=X)this.b2CompressOut();let K=Math.min(X-this.posOut,l-V);Z.set(W.subarray(this.posOut,this.posOut+K),V),this.posOut+=K,V+=K}return Z}xofInto(Z){if(!this.enableXOF)throw Error("XOF is not possible after digest call");return this.writeInto(Z)}xof(Z){return MX(Z),this.xofInto(new Uint8Array(Z))}digestInto(Z){if(JW(Z,this),this.finished)throw Error("digest() was already called");return this.enableXOF=!1,this.writeInto(Z),this.destroy(),Z}digest(){return this.digestInto(new Uint8Array(this.outputLen))}}var ol=Dl((Z)=>new NV(Z));var xV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function ql(Z){let X=new Uint8Array(xV.length+32);return X.set(xV),X.set(Z.subarray(0,32),xV.length),X}function fl(Z){return typeof Z==="string"?new TextEncoder().encode(Z):Z}function dX(Z){let X=new ArrayBuffer(Z.byteLength);return new Uint8Array(X).set(Z),X}class SX{verifyKeys=new Map;async genRandomBytes(Z){return YW(Z)}async gen256BitSecureRandomSeed(){return YW(32)}async encryptXSalsa20Poly1305Combined(Z,X){let W=YW(24),l=IV(X,W).encrypt(Z);return new Uint8Array([...W,...l])}async decryptXSalsa20Poly1305Combined(Z,X){let W=Z.slice(0,24),V=Z.slice(24);return IV(X,W).decrypt(V)}async deriveEd25519KeyPair(Z){let X=Z,W=ql(X),V=dX(W),l;try{let J=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!0,["sign"]);l=await globalThis.crypto.subtle.exportKey("jwk",J)}finally{W.fill(0),new Uint8Array(V).fill(0)}if(typeof l.x!=="string")throw Error("Ed25519 JWK missing x");let K=l.x;l.d=void 0;let G=await globalThis.crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:K},{name:"Ed25519"},!0,["verify"]),m=new Uint8Array(await globalThis.crypto.subtle.exportKey("raw",G));this.verifyKeys.set(YZ(m),G);let R=new Uint8Array(64);return R.set(X,0),R.set(m,32),{keyType:"ed25519",privateKey:R,publicKey:m}}async importSignKey(Z){let X=Z.subarray(0,32),W=ql(X),V=dX(W);try{return await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!1,["sign"])}finally{W.fill(0),new Uint8Array(V).fill(0)}}async importVerifyKey(Z){let X=YZ(Z),W=this.verifyKeys.get(X);if(W)return W;let V=await globalThis.crypto.subtle.importKey("raw",dX(Z),{name:"Ed25519"},!1,["verify"]);return this.verifyKeys.set(X,V),V}async signEd25519(Z,X){let W=fl(Z),V=await this.importSignKey(X),l=await globalThis.crypto.subtle.sign({name:"Ed25519"},V,dX(W));return new Uint8Array(l)}async checkSigEd25519(Z,X,W){let V=fl(X);try{let l=await this.importVerifyKey(W);return await globalThis.crypto.subtle.verify({name:"Ed25519"},l,dX(Z),dX(V))}catch{return!1}}async blake3(Z){return ol(Z)}}var SK=new SX,bX=SK;import{useEffect as HW,useState as jV}from"react";class gV{db;constructor(Z){this.db=Z}async enq(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(CZ,"readwrite"),V=W.objectStore(CZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=`${G.host}:${G.seq}`;V.put(G,m)}})}async deq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(CZ,"readwrite"),l=V.objectStore(CZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=`${Z}:${m}`;l.delete(R)}})}async list(){let X=this.db.transaction(CZ,"readonly").objectStore(CZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async count(){let X=this.db.transaction(CZ,"readonly").objectStore(CZ);return new Promise((W,V)=>{let l=X.count();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(CZ,"readwrite"),X=Z.objectStore(CZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}function nl(Z){return{label:Z.label,handle:new URL(Z.handle),idx:Z.idx,lastSeq:Z.lastSeq||0,clockOffset:Z.clockOffset,subscription:Z.subscription}}function PK(Z,X){let W={...Z};if(X.setLastSeq!==void 0)W.lastSeq=X.setLastSeq;else if(X.lastSeq!==void 0){let V=W.lastSeq||0;if(X.lastSeq>V)W.lastSeq=X.lastSeq}return delete W.numBags,delete W.numDupes,W}class MV{db;constructor(Z){this.db=Z}async add(Z){let X=await this.get(Z.label),W=X!==void 0&&X.handle.href===Z.handle.href&&(X.idx??0)===(Z.idx??0);return this.put({...Z,lastSeq:W?X.lastSeq:0,clockOffset:W?X.clockOffset:void 0,subscription:W?X.subscription:void 0})}async put(Z){let X={...Z,handle:Z.handle.toString(),lastSeq:Z.lastSeq??0},W=this.db.transaction(lZ,"readwrite"),V=W.objectStore(lZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error),V.put(X)})}async touch(Z,X){return this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.db.transaction(lZ,"readwrite"),V=W.objectStore(lZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);let G=V.get(Z);G.onsuccess=()=>{let m=G.result;if(!m)return;V.put(PK(m,X))}})}async get(Z){let W=this.db.transaction(lZ,"readonly").objectStore(lZ);return new Promise((V,l)=>{let K=W.get(Z);K.onsuccess=()=>{let G=K.result;if(!G)V(void 0);else V(nl(G))},K.onerror=()=>l(K.error)})}async set(Z,X){let W=await this.get(Z);if(!W)return 13;try{return await this.put({...W,...X}),0}catch{return 18}}async del(Z){let X=this.db.transaction(lZ,"readwrite"),W=X.objectStore(lZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}async list(){let X=this.db.transaction(lZ,"readonly").objectStore(lZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>{let K=l.result;W(K.map(nl))},l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(lZ,"readwrite"),X=Z.objectStore(lZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}class HV{crypto;db;constructor(Z,X){this.crypto=X;this.db=Z}async add(Z){let X=this.db.transaction(v,"readwrite"),W=X.objectStore(v);return new Promise((V)=>{if(Z.length===0){V([]);return}let l=Array(Z.length).fill(0);X.oncomplete=()=>V(l),X.onerror=()=>{for(let K=0;K<l.length;K++)l[K]=18;V(l)};for(let K=0;K<Z.length;K++){let{key:G,data:m}=Z[K],R=H(G),J=W.put(m,R);J.onerror=(C)=>{C.preventDefault(),l[K]=18}}})}async del(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(v,"readwrite"),V=W.objectStore(v);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=H(G);V.delete(m)}})}async get(Z){let W=this.db.transaction(v,"readonly").objectStore(v);return new Promise((V,l)=>{let K=H(Z),G=W.get(K);G.onsuccess=async()=>{let m=G.result;if(m)V(await uZ(Z,m,this.crypto));else V(void 0)},G.onerror=()=>l(G.error)})}async has(Z){return await this.get(Z)!==void 0}async list(Z){let X=Z?.apld,W=Z?.body!==!1,l=this.db.transaction(v,"readonly").objectStore(v);return new Promise((K,G)=>{let m=[],R=X===void 0?l.openCursor():l.index(PX).openCursor(IDBKeyRange.only(X));R.onsuccess=(J)=>{let C=J.target.result;if(C){let F=X===void 0?C.key:C.primaryKey,b=C.value;m.push({hash:e(F),data:b}),C.continue()}else Promise.all(m.map(({hash:F,data:b})=>uZ(F,b,this.crypto,{body:W}))).then(K).catch(G)},R.onerror=()=>G(R.error)})}async count(Z){let W=this.db.transaction(v,"readonly").objectStore(v);return new Promise((V,l)=>{let K=Z===void 0?W.count():W.index(PX).count(IDBKeyRange.only(Z));K.onsuccess=()=>V(K.result),K.onerror=()=>l(K.error)})}async listKeys(){let X=this.db.transaction(v,"readonly").objectStore(v);return new Promise((W,V)=>{let l=[],K=X.openKeyCursor();K.onsuccess=(G)=>{let m=G.target.result;if(m)l.push(e(m.key)),m.continue();else W(l)},K.onerror=()=>V(K.error)})}async last(Z){let W=this.db.transaction(v,"readonly").objectStore(v);return new Promise((V,l)=>{let K,G=W.openCursor();G.onsuccess=async(m)=>{let R=m.target.result;if(R){let{key:J,value:C}=R;if(n(Z,C.eid)){if(!K||(C.ctr??0)>(K.data.ctr??0)||(C.ctr??0)===(K.data.ctr??0)&&(C.off??0)>(K.data.off??0))K={key:J,data:C}}R.continue()}else if(K){let J=e(K.key);V(await uZ(J,K.data,this.crypto))}else V(void 0)},G.onerror=()=>l(G.error)})}async markApplied(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(v,"readwrite"),V=W.objectStore(v);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=H(G),R=V.get(m);R.onsuccess=()=>{let J=R.result;if(!J)return;AZ(J,UZ),V.put(J,m)},R.onerror=(J)=>{J.preventDefault()}}})}async markFailed(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(v,"readwrite"),V=W.objectStore(v);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let{key:G,err:m}of X){let R=H(G),J=V.get(R);J.onsuccess=()=>{let C=J.result;if(!C)return;AZ(C,kZ,m),V.put(C,R)},J.onerror=(C)=>{C.preventDefault()}}})}async wipe(){let Z=this.db.transaction(v,"readwrite"),X=Z.objectStore(v);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var oZ={encode(Z,X){let W=Z.writeVarString(X.handle);if(W!==0)return W;let V=Z.writeVarString(X.label);if(V!==0)return V;return Z.writeVarInt(X.idx??0)},decode(Z){let[X,W]=Z.readVarString();if(W!==0)return Y(W);let[V,l]=Z.readVarString();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);return d({handle:X,label:V,idx:K})}};var FW=1,hV={encode(Z,X){if(X.v!==FW)return 10;let[,W]=WZ(X.masterSeed);if(W!==0)return W;let V=Z.writeVarInt(X.v);if(V!==0)return V;Z.writeBytes(X.masterSeed);let l=Z.writeVarInt(X.hosts.length);if(l!==0)return l;for(let K of X.hosts){let G=Z.writeStruct(oZ,K);if(G!==0)return G}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X!==FW)return Y(14);let[V,l]=Z.readBytes(bZ);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=WZ(V);if(G!==0)return Y(G);if(K===void 0)return Y(14);let[m,R]=Z.readVarInt();if(R!==0)return Y(R);if(m===void 0||m<0)return Y(10);let J=[];for(let C=0;C<m;C++){let[F,b]=Z.readStruct(oZ);if(b!==0)return Y(b);if(F===void 0)return Y(14);J.push(F)}return d({v:FW,masterSeed:K,hosts:J})}};function _l(Z,X){let[W,V]=WZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(10);let[l,K]=WZ(W.slice());if(K!==0)return Y(K);if(l===void 0)return Y(10);return d({v:FW,masterSeed:l,hosts:X.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))})}var dW={encode(Z,X){let[,W]=WZ(X.masterSeed);if(W!==0)return W;Z.writeBytes(X.masterSeed);let V=Z.writeVarInt(X.hosts.length);if(V!==0)return V;for(let l of X.hosts){let K=Z.writeStruct(oZ,l);if(K!==0)return K}return 0},decode(Z){let[X,W]=Z.readBytes(bZ);if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=WZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);if(K===void 0||K<0)return Y(10);let m=[];for(let R=0;R<K;R++){let[J,C]=Z.readStruct(oZ);if(C!==0)return Y(C);if(J===void 0)return Y(14);m.push(J)}return d({masterSeed:V,hosts:m})}};function gZ(Z){let X=new Uint8Array(Z);if(Z>0)crypto.getRandomValues(X);return X}var iZ=32,al=-7,rl=-8,sl=-257,UX=[{type:"public-key",alg:al},{type:"public-key",alg:rl},{type:"public-key",alg:sl}];function bW(Z){return Z.trim().toLowerCase().replace(/\.$/,"")||"localhost"}function OZ(Z){let X=new Uint8Array(Z.byteLength);return X.set(Z),X.buffer}function tl(Z){if(Z instanceof ArrayBuffer)return new Uint8Array(Z).slice();return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength).slice()}function jZ(Z){if(Z?.rpId!==void 0)return d(Z.rpId);if(typeof location>"u")return Y(9);return d(bW(location.hostname))}function BZ(){if(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")return 24;return 0}function EZ(Z){if(Z===null||Z.type!=="public-key"||!("rawId"in Z)||typeof Z.getClientExtensionResults!=="function")return Y(27);return d(Z)}async function uX(Z){if(typeof PublicKeyCredential>"u")return!1;let X=PublicKeyCredential.getClientCapabilities;if(typeof X!=="function")return!0;let W=await X.call(PublicKeyCredential);if(Z in W)return W[Z]===!0;return!0}function el(){return uX("extension:largeBlob")}async function TW(Z){let X=BZ();if(X!==0)return Y(X);let[W,V]=jZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-seed",K={residentKey:"required",requireResidentKey:!0,userVerification:"required"};if(Z?.authenticatorAttachment!==void 0)K.authenticatorAttachment=Z.authenticatorAttachment;let G={largeBlob:{support:"required"}},m;try{m=await navigator.credentials.create({publicKey:{challenge:gZ(iZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:gZ(16),name:l,displayName:l},pubKeyCredParams:UX,authenticatorSelection:K,extensions:G}})}catch{return Y(24)}let[R,J]=EZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);if(R.getClientExtensionResults().largeBlob?.supported!==!0)return Y(24);return d(new Uint8Array(R.rawId))}async function iX(Z,X,W){let V=BZ();if(V!==0)return V;let[l,K]=jZ(W);if(K!==0)return K;if(l===void 0)return 9;let G={largeBlob:{write:OZ(X)}},m;try{m=await navigator.credentials.get({publicKey:{challenge:gZ(iZ),rpId:l,allowCredentials:[{type:"public-key",id:OZ(Z)}],userVerification:"required",extensions:G}})}catch{return 24}let[R,J]=EZ(m);if(J!==0)return J;if(R===void 0)return 27;if(R.getClientExtensionResults().largeBlob?.written!==!0)return 24;return 0}async function kW(Z,X){let W=BZ();if(W!==0)return Y(W);let[V,l]=jZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(9);let K={largeBlob:{read:!0}},G;try{let b={challenge:gZ(iZ),rpId:V,userVerification:"required",extensions:K};if(Z!==void 0)b.allowCredentials=[{type:"public-key",id:OZ(Z)}];G=await navigator.credentials.get({publicKey:b})}catch{return Y(24)}let[m,R]=EZ(G);if(R!==0)return Y(R);if(m===void 0)return Y(27);let C=m.getClientExtensionResults().largeBlob;if(C===void 0||C.blob===void 0)return Y(7);let F=tl(C.blob);if(F.byteLength===0)return Y(7);return d({blob:F,credId:new Uint8Array(m.rawId)})}var OX=new TextEncoder().encode("diplomatic.prf.v1"),SV=32;async function UK(){return uX("extension:prf")}async function Z0(Z){let X=BZ();if(X!==0)return Y(X);let[W,V]=jZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-prf",K={residentKey:"required",requireResidentKey:!0,userVerification:"required",authenticatorAttachment:Z?.authenticatorAttachment??"platform"},G;try{G=await navigator.credentials.create({publicKey:{challenge:gZ(iZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:gZ(16),name:l,displayName:l},pubKeyCredParams:UX,authenticatorSelection:K,extensions:{prf:{}}}})}catch{return Y(24)}let[m,R]=EZ(G);if(R!==0)return Y(R);if(m===void 0)return Y(27);let J=m.getClientExtensionResults();return d({credId:new Uint8Array(m.rawId),prfEnabled:J.prf?.enabled===!0})}async function jX(Z){let X=BZ();if(X!==0)return Y(X);let[W,V]=jZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.salt??OX,K=OZ(l),G={challenge:gZ(iZ),rpId:W,userVerification:"required",extensions:{prf:{eval:{first:K}}}};if(Z?.credId!==void 0)G.allowCredentials=[{type:"public-key",id:OZ(Z.credId)}];let m;try{m=await navigator.credentials.get({publicKey:G})}catch{return Y(24)}let[R,J]=EZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);let C=R.getClientExtensionResults().prf?.results;if(C?.first===void 0)return Y(7);let F=C.first,b=F instanceof ArrayBuffer?new Uint8Array(F):new Uint8Array(F.buffer,F.byteOffset,F.byteLength),T=b.byteLength>=SV?b.slice(0,SV):b;if(T.byteLength!==SV)return Y(27);return d({prf:T,credId:new Uint8Array(R.rawId)})}var cW="dmFyIFQwPTY0O3ZhciBHSj0zMixqMD04O3ZhciBNJD0zMjt2YXIgeko9MzAwMDAsS0o9NTEyLEQ7KCh3KT0+e3dbdy5TdWNjZXNzPTBdPSJTdWNjZXNzIjt3W3cuSW52YWxpZFNpZ25hdHVyZT0zXT0iSW52YWxpZFNpZ25hdHVyZSI7d1t3LkNsb2NrT3V0T2ZTeW5jPTRdPSJDbG9ja091dE9mU3luYyI7d1t3LlVzZXJOb3RSZWdpc3RlcmVkPTVdPSJVc2VyTm90UmVnaXN0ZXJlZCI7d1t3LlNlcnZlck1pc2NvbmZpZ3VyZWQ9Nl09IlNlcnZlck1pc2NvbmZpZ3VyZWQiO3dbdy5NaXNzaW5nQm9keT03XT0iTWlzc2luZ0JvZHkiO3dbdy5FeHRyYUJvZHlDb250ZW50PThdPSJFeHRyYUJvZHlDb250ZW50Ijt3W3cuTWlzc2luZ1BhcmFtPTldPSJNaXNzaW5nUGFyYW0iO3dbdy5JbnZhbGlkUGFyYW09MTBdPSJJbnZhbGlkUGFyYW0iO3dbdy5JbnZhbGlkUmVxdWVzdD0xMV09IkludmFsaWRSZXF1ZXN0Ijt3W3cuSW50ZXJuYWxFcnJvcj0xMl09IkludGVybmFsRXJyb3IiO3dbdy5Ob3RGb3VuZD0xM109Ik5vdEZvdW5kIjt3W3cuSW52YWxpZE1lc3NhZ2U9MTRdPSJJbnZhbGlkTWVzc2FnZSI7d1t3Lk5vQ2hhbmdlPTE1XT0iTm9DaGFuZ2UiO3dbdy5EYXRhYmFzZUNsb3NlZD0xNl09IkRhdGFiYXNlQ2xvc2VkIjt3W3cuU3RvcmFnZUVycm9yPTE3XT0iU3RvcmFnZUVycm9yIjt3W3cuRGF0YWJhc2VFcnJvcj0xOF09IkRhdGFiYXNlRXJyb3IiO3dbdy5IYXNoTWlzbWF0Y2g9MTldPSJIYXNoTWlzbWF0Y2giO3dbdy5EZWNyeXB0aW9uRXJyb3I9MjBdPSJEZWNyeXB0aW9uRXJyb3IiO3dbdy5Ob3RJbXBsZW1lbnRlZD0yMV09Ik5vdEltcGxlbWVudGVkIjt3W3cuTWlzc2luZ1NlZWQ9MjJdPSJNaXNzaW5nU2VlZCI7d1t3Lk91dE9mQm91bmRzPTIzXT0iT3V0T2ZCb3VuZHMiO3dbdy5Ib3N0RXJyb3I9MjRdPSJIb3N0RXJyb3IiO3dbdy5Db21tdW5pY2F0aW9uRXJyb3I9MjVdPSJDb21tdW5pY2F0aW9uRXJyb3IiO3dbdy5WYXJMaW1pdEV4Y2VlZGVkPTI2XT0iVmFyTGltaXRFeGNlZWRlZCI7d1t3LkludmFsaWRSZXNwb25zZT0yN109IkludmFsaWRSZXNwb25zZSI7d1t3LkNvbm5lY3Rpb25DbG9zZWQ9MjhdPSJDb25uZWN0aW9uQ2xvc2VkIn0pKER8fD17fSk7ZnVuY3Rpb24gRkooJCl7aWYoISR8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuITE7aWYoISgib3AiaW4gJCl8fCEoImlkImluICQpKXJldHVybiExO3JldHVybiB0eXBlb2YgJC5vcD09PSJzdHJpbmciJiZ0eXBlb2YgJC5pZD09PSJudW1iZXIifWZ1bmN0aW9uIE5KKCQpe2xldCBaPSQubGVuZ3RoLEo9MCxRPTA7d2hpbGUoUTxaKXtsZXQgWD0kLmNoYXJDb2RlQXQoUSsrKTtpZigoWCY0Mjk0OTY3MTY4KT09PTApe0orKztjb250aW51ZX1lbHNlIGlmKChYJjQyOTQ5NjUyNDgpPT09MClKKz0yO2Vsc2V7aWYoWD49NTUyOTYmJlg8PTU2MzE5KXtpZihRPFope2xldCBZPSQuY2hhckNvZGVBdChRKTtpZigoWSY2NDUxMik9PT01NjMyMCkrK1EsWD0oKFgmMTAyMyk8PDEwKSsoWSYxMDIzKSs2NTUzNn19aWYoKFgmNDI5NDkwMTc2MCk9PT0wKUorPTM7ZWxzZSBKKz00fX1yZXR1cm4gSn1mdW5jdGlvbiBoUSgkLFosSil7bGV0IFE9JC5sZW5ndGgsWD1KLFk9MDt3aGlsZShZPFEpe2xldCBWPSQuY2hhckNvZGVBdChZKyspO2lmKChWJjQyOTQ5NjcxNjgpPT09MCl7WltYKytdPVY7Y29udGludWV9ZWxzZSBpZigoViY0Mjk0OTY1MjQ4KT09PTApWltYKytdPVY+PjYmMzF8MTkyO2Vsc2V7aWYoVj49NTUyOTYmJlY8PTU2MzE5KXtpZihZPFEpe2xldCBXPSQuY2hhckNvZGVBdChZKTtpZigoVyY2NDUxMik9PT01NjMyMCkrK1ksVj0oKFYmMTAyMyk8PDEwKSsoVyYxMDIzKSs2NTUzNn19aWYoKFYmNDI5NDkwMTc2MCk9PT0wKVpbWCsrXT1WPj4xMiYxNXwyMjQsWltYKytdPVY+PjYmNjN8MTI4O2Vsc2UgWltYKytdPVY+PjE4Jjd8MjQwLFpbWCsrXT1WPj4xMiY2M3wxMjgsWltYKytdPVY+PjYmNjN8MTI4fVpbWCsrXT1WJjYzfDEyOH19dmFyIGlRPW5ldyBUZXh0RW5jb2RlcixsUT01MDtmdW5jdGlvbiB1USgkLFosSil7aVEuZW5jb2RlSW50bygkLFouc3ViYXJyYXkoSikpfWZ1bmN0aW9uIFJKKCQsWixKKXtpZigkLmxlbmd0aD5sUSl1USgkLFosSik7ZWxzZSBoUSgkLFosSil9dmFyIHBRPTQwOTY7ZnVuY3Rpb24gWlooJCxaLEope2xldCBRPVosWD1RK0osWT1bXSxWPSIiO3doaWxlKFE8WCl7bGV0IFc9JFtRKytdO2lmKChXJjEyOCk9PT0wKVkucHVzaChXKTtlbHNlIGlmKChXJjIyNCk9PT0xOTIpe2xldCB6PSRbUSsrXSY2MztZLnB1c2goKFcmMzEpPDw2fHopfWVsc2UgaWYoKFcmMjQwKT09PTIyNCl7bGV0IHo9JFtRKytdJjYzLEs9JFtRKytdJjYzO1kucHVzaCgoVyYzMSk8PDEyfHo8PDZ8Syl9ZWxzZSBpZigoVyYyNDgpPT09MjQwKXtsZXQgej0kW1ErK10mNjMsSz0kW1ErK10mNjMsRj0kW1ErK10mNjMsTj0oVyY3KTw8MTh8ejw8MTJ8Szw8NnxGO2lmKE4+NjU1MzUpTi09NjU1MzYsWS5wdXNoKE4+Pj4xMCYxMDIzfDU1Mjk2KSxOPTU2MzIwfE4mMTAyMztZLnB1c2goTil9ZWxzZSBZLnB1c2goVyk7aWYoWS5sZW5ndGg+PXBRKVYrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uWSksWS5sZW5ndGg9MH1pZihZLmxlbmd0aD4wKVYrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uWSk7cmV0dXJuIFZ9dmFyIGNRPW5ldyBUZXh0RGVjb2RlcixuUT0yMDA7ZnVuY3Rpb24gZFEoJCxaLEope2xldCBRPSQuc3ViYXJyYXkoWixaK0opO3JldHVybiBjUS5kZWNvZGUoUSl9ZnVuY3Rpb24gT0ooJCxaLEope2lmKEo+blEpcmV0dXJuIGRRKCQsWixKKTtlbHNlIHJldHVybiBaWigkLFosSil9Y2xhc3MgcDB7dHlwZTtkYXRhO2NvbnN0cnVjdG9yKCQsWil7dGhpcy50eXBlPSQsdGhpcy5kYXRhPVp9fWNsYXNzIHQgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcigkKXtzdXBlcigkKTtsZXQgWj1PYmplY3QuY3JlYXRlKHQucHJvdG90eXBlKTtPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcyxaKSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibmFtZSIse2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiExLHZhbHVlOnQubmFtZX0pfX12YXIgYzA9NDI5NDk2NzI5NTtmdW5jdGlvbiBVSigkLFosSil7bGV0IFE9Si80Mjk0OTY3Mjk2LFg9SjskLnNldFVpbnQzMihaLFEpLCQuc2V0VWludDMyKForNCxYKX1mdW5jdGlvbiBJJCgkLFosSil7bGV0IFE9TWF0aC5mbG9vcihKLzQyOTQ5NjcyOTYpLFg9SjskLnNldFVpbnQzMihaLFEpLCQuc2V0VWludDMyKForNCxYKX1mdW5jdGlvbiBDJCgkLFope2xldCBKPSQuZ2V0SW50MzIoWiksUT0kLmdldFVpbnQzMihaKzQpO3JldHVybiBKKjQyOTQ5NjcyOTYrUX1mdW5jdGlvbiBxSigkLFope2xldCBKPSQuZ2V0VWludDMyKFopLFE9JC5nZXRVaW50MzIoWis0KTtyZXR1cm4gSio0Mjk0OTY3Mjk2K1F9dmFyIHJRPS0xLG9RPTQyOTQ5NjcyOTUsYVE9MTcxNzk4NjkxODM7ZnVuY3Rpb24gc1Eoe3NlYzokLG5zZWM6Wn0pe2lmKCQ+PTAmJlo+PTAmJiQ8PWFRKWlmKFo9PT0wJiYkPD1vUSl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoNCk7cmV0dXJuIG5ldyBEYXRhVmlldyhKLmJ1ZmZlcikuc2V0VWludDMyKDAsJCksSn1lbHNle2xldCBKPSQvNDI5NDk2NzI5NixRPSQmNDI5NDk2NzI5NSxYPW5ldyBVaW50OEFycmF5KDgpLFk9bmV3IERhdGFWaWV3KFguYnVmZmVyKTtyZXR1cm4gWS5zZXRVaW50MzIoMCxaPDwyfEomMyksWS5zZXRVaW50MzIoNCxRKSxYfWVsc2V7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoMTIpLFE9bmV3IERhdGFWaWV3KEouYnVmZmVyKTtyZXR1cm4gUS5zZXRVaW50MzIoMCxaKSxJJChRLDQsJCksSn19ZnVuY3Rpb24gdFEoJCl7bGV0IFo9JC5nZXRUaW1lKCksSj1NYXRoLmZsb29yKFovMTAwMCksUT0oWi1KKjEwMDApKjFlNixYPU1hdGguZmxvb3IoUS8xZTkpO3JldHVybntzZWM6SitYLG5zZWM6US1YKjFlOX19ZnVuY3Rpb24gZVEoJCl7aWYoJCBpbnN0YW5jZW9mIERhdGUpe2xldCBaPXRRKCQpO3JldHVybiBzUShaKX1lbHNlIHJldHVybiBudWxsfWZ1bmN0aW9uICRYKCQpe2xldCBaPW5ldyBEYXRhVmlldygkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKTtzd2l0Y2goJC5ieXRlTGVuZ3RoKXtjYXNlIDQ6e2xldCBKPVouZ2V0VWludDMyKDApLFE9MDtyZXR1cm57c2VjOkosbnNlYzowfX1jYXNlIDg6e2xldCBKPVouZ2V0VWludDMyKDApLFE9Wi5nZXRVaW50MzIoNCksWD0oSiYzKSo0Mjk0OTY3Mjk2K1EsWT1KPj4+MjtyZXR1cm57c2VjOlgsbnNlYzpZfX1jYXNlIDEyOntsZXQgSj1DJChaLDQpLFE9Wi5nZXRVaW50MzIoMCk7cmV0dXJue3NlYzpKLG5zZWM6UX19ZGVmYXVsdDp0aHJvdyBuZXcgdChgVW5yZWNvZ25pemVkIGRhdGEgc2l6ZSBmb3IgdGltZXN0YW1wIChleHBlY3RlZCA0LCA4LCBvciAxMik6ICR7JC5sZW5ndGh9YCl9fWZ1bmN0aW9uIFpYKCQpe2xldCBaPSRYKCQpO3JldHVybiBuZXcgRGF0ZShaLnNlYyoxMDAwK1oubnNlYy8xZTYpfXZhciBISj17dHlwZTpyUSxlbmNvZGU6ZVEsZGVjb2RlOlpYfTtjbGFzcyBuMHtzdGF0aWMgZGVmYXVsdENvZGVjPW5ldyBuMDtfX2JyYW5kO2J1aWx0SW5FbmNvZGVycz1bXTtidWlsdEluRGVjb2RlcnM9W107ZW5jb2RlcnM9W107ZGVjb2RlcnM9W107Y29uc3RydWN0b3IoKXt0aGlzLnJlZ2lzdGVyKEhKKX1yZWdpc3Rlcih7dHlwZTokLGVuY29kZTpaLGRlY29kZTpKfSl7aWYoJD49MCl0aGlzLmVuY29kZXJzWyRdPVosdGhpcy5kZWNvZGVyc1skXT1KO2Vsc2V7bGV0IFE9LTEtJDt0aGlzLmJ1aWx0SW5FbmNvZGVyc1tRXT1aLHRoaXMuYnVpbHRJbkRlY29kZXJzW1FdPUp9fXRyeVRvRW5jb2RlKCQsWil7Zm9yKGxldCBKPTA7Sjx0aGlzLmJ1aWx0SW5FbmNvZGVycy5sZW5ndGg7SisrKXtsZXQgUT10aGlzLmJ1aWx0SW5FbmNvZGVyc1tKXTtpZihRIT1udWxsKXtsZXQgWD1RKCQsWik7aWYoWCE9bnVsbCl7bGV0IFk9LTEtSjtyZXR1cm4gbmV3IHAwKFksWCl9fX1mb3IobGV0IEo9MDtKPHRoaXMuZW5jb2RlcnMubGVuZ3RoO0orKyl7bGV0IFE9dGhpcy5lbmNvZGVyc1tKXTtpZihRIT1udWxsKXtsZXQgWD1RKCQsWik7aWYoWCE9bnVsbClyZXR1cm4gbmV3IHAwKEosWCl9fWlmKCQgaW5zdGFuY2VvZiBwMClyZXR1cm4gJDtyZXR1cm4gbnVsbH1kZWNvZGUoJCxaLEope2xldCBRPVo8MD90aGlzLmJ1aWx0SW5EZWNvZGVyc1stMS1aXTp0aGlzLmRlY29kZXJzW1pdO2lmKFEpcmV0dXJuIFEoJCxaLEopO2Vsc2UgcmV0dXJuIG5ldyBwMChaLCQpfX1mdW5jdGlvbiBKWCgkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHx0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXI8InUiJiYkIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXJ9ZnVuY3Rpb24gWCQoJCl7aWYoJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuICQ7ZWxzZSBpZihBcnJheUJ1ZmZlci5pc1ZpZXcoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpO2Vsc2UgaWYoSlgoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpO2Vsc2UgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX12YXIgUVg9MTAwLFhYPTIwNDg7Y2xhc3MgUCR7ZXh0ZW5zaW9uQ29kZWM7Y29udGV4dDt1c2VCaWdJbnQ2NDttYXhEZXB0aDtpbml0aWFsQnVmZmVyU2l6ZTtzb3J0S2V5cztmb3JjZUZsb2F0MzI7aWdub3JlVW5kZWZpbmVkO2ZvcmNlSW50ZWdlclRvRmxvYXQ7cG9zO3ZpZXc7Ynl0ZXM7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9uMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5tYXhEZXB0aD0kPy5tYXhEZXB0aD8/UVgsdGhpcy5pbml0aWFsQnVmZmVyU2l6ZT0kPy5pbml0aWFsQnVmZmVyU2l6ZT8/WFgsdGhpcy5zb3J0S2V5cz0kPy5zb3J0S2V5cz8/ITEsdGhpcy5mb3JjZUZsb2F0MzI9JD8uZm9yY2VGbG9hdDMyPz8hMSx0aGlzLmlnbm9yZVVuZGVmaW5lZD0kPy5pZ25vcmVVbmRlZmluZWQ/PyExLHRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdD0kPy5mb3JjZUludGVnZXJUb0Zsb2F0Pz8hMSx0aGlzLnBvcz0wLHRoaXMudmlldz1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKHRoaXMuaW5pdGlhbEJ1ZmZlclNpemUpKSx0aGlzLmJ5dGVzPW5ldyBVaW50OEFycmF5KHRoaXMudmlldy5idWZmZXIpfWNsb25lKCl7cmV0dXJuIG5ldyBQJCh7ZXh0ZW5zaW9uQ29kZWM6dGhpcy5leHRlbnNpb25Db2RlYyxjb250ZXh0OnRoaXMuY29udGV4dCx1c2VCaWdJbnQ2NDp0aGlzLnVzZUJpZ0ludDY0LG1heERlcHRoOnRoaXMubWF4RGVwdGgsaW5pdGlhbEJ1ZmZlclNpemU6dGhpcy5pbml0aWFsQnVmZmVyU2l6ZSxzb3J0S2V5czp0aGlzLnNvcnRLZXlzLGZvcmNlRmxvYXQzMjp0aGlzLmZvcmNlRmxvYXQzMixpZ25vcmVVbmRlZmluZWQ6dGhpcy5pZ25vcmVVbmRlZmluZWQsZm9yY2VJbnRlZ2VyVG9GbG9hdDp0aGlzLmZvcmNlSW50ZWdlclRvRmxvYXR9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMucG9zPTB9ZW5jb2RlU2hhcmVkUmVmKCQpe2lmKHRoaXMuZW50ZXJlZClyZXR1cm4gdGhpcy5jbG9uZSgpLmVuY29kZVNoYXJlZFJlZigkKTt0cnl7cmV0dXJuIHRoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5kb0VuY29kZSgkLDEpLHRoaXMuYnl0ZXMuc3ViYXJyYXkoMCx0aGlzLnBvcyl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWVuY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmNvZGUoJCk7dHJ5e3JldHVybiB0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuZG9FbmNvZGUoJCwxKSx0aGlzLmJ5dGVzLnNsaWNlKDAsdGhpcy5wb3MpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kb0VuY29kZSgkLFope2lmKFo+dGhpcy5tYXhEZXB0aCl0aHJvdyBFcnJvcihgVG9vIGRlZXAgb2JqZWN0cyBpbiBkZXB0aCAke1p9YCk7aWYoJD09bnVsbCl0aGlzLmVuY29kZU5pbCgpO2Vsc2UgaWYodHlwZW9mICQ9PT0iYm9vbGVhbiIpdGhpcy5lbmNvZGVCb29sZWFuKCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ibnVtYmVyIilpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0KXRoaXMuZW5jb2RlTnVtYmVyKCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ic3RyaW5nIil0aGlzLmVuY29kZVN0cmluZygkKTtlbHNlIGlmKHRoaXMudXNlQmlnSW50NjQmJnR5cGVvZiAkPT09ImJpZ2ludCIpdGhpcy5lbmNvZGVCaWdJbnQ2NCgkKTtlbHNlIHRoaXMuZW5jb2RlT2JqZWN0KCQsWil9ZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoJCl7bGV0IFo9dGhpcy5wb3MrJDtpZih0aGlzLnZpZXcuYnl0ZUxlbmd0aDxaKXRoaXMucmVzaXplQnVmZmVyKFoqMil9cmVzaXplQnVmZmVyKCQpe2xldCBaPW5ldyBBcnJheUJ1ZmZlcigkKSxKPW5ldyBVaW50OEFycmF5KFopLFE9bmV3IERhdGFWaWV3KFopO0ouc2V0KHRoaXMuYnl0ZXMpLHRoaXMudmlldz1RLHRoaXMuYnl0ZXM9Sn1lbmNvZGVOaWwoKXt0aGlzLndyaXRlVTgoMTkyKX1lbmNvZGVCb29sZWFuKCQpe2lmKCQ9PT0hMSl0aGlzLndyaXRlVTgoMTk0KTtlbHNlIHRoaXMud3JpdGVVOCgxOTUpfWVuY29kZU51bWJlcigkKXtpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0JiZOdW1iZXIuaXNTYWZlSW50ZWdlcigkKSlpZigkPj0wKWlmKCQ8MTI4KXRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8MjU2KXRoaXMud3JpdGVVOCgyMDQpLHRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8NjU1MzYpdGhpcy53cml0ZVU4KDIwNSksdGhpcy53cml0ZVUxNigkKTtlbHNlIGlmKCQ8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjA2KSx0aGlzLndyaXRlVTMyKCQpO2Vsc2UgaWYoIXRoaXMudXNlQmlnSW50NjQpdGhpcy53cml0ZVU4KDIwNyksdGhpcy53cml0ZVU2NCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIGlmKCQ+PS0zMil0aGlzLndyaXRlVTgoMjI0fCQrMzIpO2Vsc2UgaWYoJD49LTEyOCl0aGlzLndyaXRlVTgoMjA4KSx0aGlzLndyaXRlSTgoJCk7ZWxzZSBpZigkPj0tMzI3NjgpdGhpcy53cml0ZVU4KDIwOSksdGhpcy53cml0ZUkxNigkKTtlbHNlIGlmKCQ+PS0yMTQ3NDgzNjQ4KXRoaXMud3JpdGVVOCgyMTApLHRoaXMud3JpdGVJMzIoJCk7ZWxzZSBpZighdGhpcy51c2VCaWdJbnQ2NCl0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlSTY0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpfWVuY29kZU51bWJlckFzRmxvYXQoJCl7aWYodGhpcy5mb3JjZUZsb2F0MzIpdGhpcy53cml0ZVU4KDIwMiksdGhpcy53cml0ZUYzMigkKTtlbHNlIHRoaXMud3JpdGVVOCgyMDMpLHRoaXMud3JpdGVGNjQoJCl9ZW5jb2RlQmlnSW50NjQoJCl7aWYoJD49QmlnSW50KDApKXRoaXMud3JpdGVVOCgyMDcpLHRoaXMud3JpdGVCaWdVaW50NjQoJCk7ZWxzZSB0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlQmlnSW50NjQoJCl9d3JpdGVTdHJpbmdIZWFkZXIoJCl7aWYoJDwzMil0aGlzLndyaXRlVTgoMTYwKyQpO2Vsc2UgaWYoJDwyNTYpdGhpcy53cml0ZVU4KDIxNyksdGhpcy53cml0ZVU4KCQpO2Vsc2UgaWYoJDw2NTUzNil0aGlzLndyaXRlVTgoMjE4KSx0aGlzLndyaXRlVTE2KCQpO2Vsc2UgaWYoJDw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMTkpLHRoaXMud3JpdGVVMzIoJCk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxvbmcgc3RyaW5nOiAkeyR9IGJ5dGVzIGluIFVURi04YCl9ZW5jb2RlU3RyaW5nKCQpe2xldCBKPU5KKCQpO3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNStKKSx0aGlzLndyaXRlU3RyaW5nSGVhZGVyKEopLFJKKCQsdGhpcy5ieXRlcyx0aGlzLnBvcyksdGhpcy5wb3MrPUp9ZW5jb2RlT2JqZWN0KCQsWil7bGV0IEo9dGhpcy5leHRlbnNpb25Db2RlYy50cnlUb0VuY29kZSgkLHRoaXMuY29udGV4dCk7aWYoSiE9bnVsbCl0aGlzLmVuY29kZUV4dGVuc2lvbihKKTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoJCkpdGhpcy5lbmNvZGVBcnJheSgkLFopO2Vsc2UgaWYoQXJyYXlCdWZmZXIuaXNWaWV3KCQpKXRoaXMuZW5jb2RlQmluYXJ5KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ib2JqZWN0Iil0aGlzLmVuY29kZU1hcCgkLFopO2Vsc2UgdGhyb3cgRXJyb3IoYFVucmVjb2duaXplZCBvYmplY3Q6ICR7T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5hcHBseSgkKX1gKX1lbmNvZGVCaW5hcnkoJCl7bGV0IFo9JC5ieXRlTGVuZ3RoO2lmKFo8MjU2KXRoaXMud3JpdGVVOCgxOTYpLHRoaXMud3JpdGVVOChaKTtlbHNlIGlmKFo8NjU1MzYpdGhpcy53cml0ZVU4KDE5NyksdGhpcy53cml0ZVUxNihaKTtlbHNlIGlmKFo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMTk4KSx0aGlzLndyaXRlVTMyKFopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBiaW5hcnk6ICR7Wn1gKTtsZXQgSj1YJCgkKTt0aGlzLndyaXRlVThhKEopfWVuY29kZUFycmF5KCQsWil7bGV0IEo9JC5sZW5ndGg7aWYoSjwxNil0aGlzLndyaXRlVTgoMTQ0K0opO2Vsc2UgaWYoSjw2NTUzNil0aGlzLndyaXRlVTgoMjIwKSx0aGlzLndyaXRlVTE2KEopO2Vsc2UgaWYoSjw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjEpLHRoaXMud3JpdGVVMzIoSik7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIGFycmF5OiAke0p9YCk7Zm9yKGxldCBRIG9mICQpdGhpcy5kb0VuY29kZShRLForMSl9Y291bnRXaXRob3V0VW5kZWZpbmVkKCQsWil7bGV0IEo9MDtmb3IobGV0IFEgb2YgWilpZigkW1FdIT09dm9pZCAwKUorKztyZXR1cm4gSn1lbmNvZGVNYXAoJCxaKXtsZXQgSj1PYmplY3Qua2V5cygkKTtpZih0aGlzLnNvcnRLZXlzKUouc29ydCgpO2xldCBRPXRoaXMuaWdub3JlVW5kZWZpbmVkP3RoaXMuY291bnRXaXRob3V0VW5kZWZpbmVkKCQsSik6Si5sZW5ndGg7aWYoUTwxNil0aGlzLndyaXRlVTgoMTI4K1EpO2Vsc2UgaWYoUTw2NTUzNil0aGlzLndyaXRlVTgoMjIyKSx0aGlzLndyaXRlVTE2KFEpO2Vsc2UgaWYoUTw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjMpLHRoaXMud3JpdGVVMzIoUSk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIG1hcCBvYmplY3Q6ICR7UX1gKTtmb3IobGV0IFggb2YgSil7bGV0IFk9JFtYXTtpZighKHRoaXMuaWdub3JlVW5kZWZpbmVkJiZZPT09dm9pZCAwKSl0aGlzLmVuY29kZVN0cmluZyhYKSx0aGlzLmRvRW5jb2RlKFksWisxKX19ZW5jb2RlRXh0ZW5zaW9uKCQpe2lmKHR5cGVvZiAkLmRhdGE9PT0iZnVuY3Rpb24iKXtsZXQgSj0kLmRhdGEodGhpcy5wb3MrNiksUT1KLmxlbmd0aDtpZihRPj00Mjk0OTY3Mjk2KXRocm93IEVycm9yKGBUb28gbGFyZ2UgZXh0ZW5zaW9uIG9iamVjdDogJHtRfWApO3RoaXMud3JpdGVVOCgyMDEpLHRoaXMud3JpdGVVMzIoUSksdGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YShKKTtyZXR1cm59bGV0IFo9JC5kYXRhLmxlbmd0aDtpZihaPT09MSl0aGlzLndyaXRlVTgoMjEyKTtlbHNlIGlmKFo9PT0yKXRoaXMud3JpdGVVOCgyMTMpO2Vsc2UgaWYoWj09PTQpdGhpcy53cml0ZVU4KDIxNCk7ZWxzZSBpZihaPT09OCl0aGlzLndyaXRlVTgoMjE1KTtlbHNlIGlmKFo9PT0xNil0aGlzLndyaXRlVTgoMjE2KTtlbHNlIGlmKFo8MjU2KXRoaXMud3JpdGVVOCgxOTkpLHRoaXMud3JpdGVVOChaKTtlbHNlIGlmKFo8NjU1MzYpdGhpcy53cml0ZVU4KDIwMCksdGhpcy53cml0ZVUxNihaKTtlbHNlIGlmKFo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjAxKSx0aGlzLndyaXRlVTMyKFopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBleHRlbnNpb24gb2JqZWN0OiAke1p9YCk7dGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YSgkLmRhdGEpfXdyaXRlVTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0VWludDgodGhpcy5wb3MsJCksdGhpcy5wb3MrK313cml0ZVU4YSgkKXtsZXQgWj0kLmxlbmd0aDt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKFopLHRoaXMuYnl0ZXMuc2V0KCQsdGhpcy5wb3MpLHRoaXMucG9zKz1afXdyaXRlSTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0SW50OCh0aGlzLnBvcywkKSx0aGlzLnBvcysrfXdyaXRlVTE2KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMiksdGhpcy52aWV3LnNldFVpbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZUkxNigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDIpLHRoaXMudmlldy5zZXRJbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZVUzMigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDQpLHRoaXMudmlldy5zZXRVaW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVJMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0SW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVGMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0RmxvYXQzMih0aGlzLnBvcywkKSx0aGlzLnBvcys9NH13cml0ZUY2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRGbG9hdDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlVTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksVUoodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlSTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksSSQodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlQmlnVWludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ1VpbnQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUJpZ0ludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ0ludDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fX1mdW5jdGlvbiBMMCgkLFope3JldHVybiBuZXcgUCQoWikuZW5jb2RlU2hhcmVkUmVmKCQpfWZ1bmN0aW9uIHckKCQpe3JldHVybmAkeyQ8MD8iLSI6IiJ9MHgke01hdGguYWJzKCQpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCIwIil9YH12YXIgWVg9MTYsVlg9MTY7Y2xhc3MgSlp7aGl0PTA7bWlzcz0wO2NhY2hlczttYXhLZXlMZW5ndGg7bWF4TGVuZ3RoUGVyS2V5O2NvbnN0cnVjdG9yKCQ9WVgsWj1WWCl7dGhpcy5tYXhLZXlMZW5ndGg9JCx0aGlzLm1heExlbmd0aFBlcktleT1aLHRoaXMuY2FjaGVzPVtdO2ZvcihsZXQgSj0wO0o8dGhpcy5tYXhLZXlMZW5ndGg7SisrKXRoaXMuY2FjaGVzLnB1c2goW10pfWNhbkJlQ2FjaGVkKCQpe3JldHVybiAkPjAmJiQ8PXRoaXMubWF4S2V5TGVuZ3RofWZpbmQoJCxaLEope2xldCBRPXRoaXMuY2FjaGVzW0otMV07JDpmb3IobGV0IFggb2YgUSl7bGV0IFk9WC5ieXRlcztmb3IobGV0IFY9MDtWPEo7VisrKWlmKFlbVl0hPT0kW1orVl0pY29udGludWUgJDtyZXR1cm4gWC5zdHJ9cmV0dXJuIG51bGx9c3RvcmUoJCxaKXtsZXQgSj10aGlzLmNhY2hlc1skLmxlbmd0aC0xXSxRPXtieXRlczokLHN0cjpafTtpZihKLmxlbmd0aD49dGhpcy5tYXhMZW5ndGhQZXJLZXkpSltNYXRoLnJhbmRvbSgpKkoubGVuZ3RofDBdPVE7ZWxzZSBKLnB1c2goUSl9ZGVjb2RlKCQsWixKKXtsZXQgUT10aGlzLmZpbmQoJCxaLEopO2lmKFEhPW51bGwpcmV0dXJuIHRoaXMuaGl0KyssUTt0aGlzLm1pc3MrKztsZXQgWD1aWigkLFosSiksWT1VaW50OEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCQsWixaK0opO3JldHVybiB0aGlzLnN0b3JlKFksWCksWH19dmFyIFFaPSJhcnJheSIsViQ9Im1hcF9rZXkiLElKPSJtYXBfdmFsdWUiLFdYPSgkKT0+e2lmKHR5cGVvZiAkPT09InN0cmluZyJ8fHR5cGVvZiAkPT09Im51bWJlciIpcmV0dXJuICQ7dGhyb3cgbmV3IHQoIlRoZSB0eXBlIG9mIGtleSBtdXN0IGJlIHN0cmluZyBvciBudW1iZXIgYnV0ICIrdHlwZW9mICQpfTtjbGFzcyBDSntzdGFjaz1bXTtzdGFja0hlYWRQb3NpdGlvbj0tMTtnZXQgbGVuZ3RoKCl7cmV0dXJuIHRoaXMuc3RhY2tIZWFkUG9zaXRpb24rMX10b3AoKXtyZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1wdXNoQXJyYXlTdGF0ZSgkKXtsZXQgWj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Wi50eXBlPVFaLFoucG9zaXRpb249MCxaLnNpemU9JCxaLmFycmF5PUFycmF5KCQpfXB1c2hNYXBTdGF0ZSgkKXtsZXQgWj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Wi50eXBlPVYkLFoucmVhZENvdW50PTAsWi5zaXplPSQsWi5tYXA9e319Z2V0VW5pbml0aWFsaXplZFN0YXRlRnJvbVBvb2woKXtpZih0aGlzLnN0YWNrSGVhZFBvc2l0aW9uKyssdGhpcy5zdGFja0hlYWRQb3NpdGlvbj09PXRoaXMuc3RhY2subGVuZ3RoKXtsZXQgJD17dHlwZTp2b2lkIDAsc2l6ZTowLGFycmF5OnZvaWQgMCxwb3NpdGlvbjowLHJlYWRDb3VudDowLG1hcDp2b2lkIDAsa2V5Om51bGx9O3RoaXMuc3RhY2sucHVzaCgkKX1yZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1yZWxlYXNlKCQpe2lmKHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl0hPT0kKXRocm93IEVycm9yKCJJbnZhbGlkIHN0YWNrIHN0YXRlLiBSZWxlYXNlZCBzdGF0ZSBpcyBub3Qgb24gdG9wIG9mIHRoZSBzdGFjay4iKTtpZigkLnR5cGU9PT1RWil7bGV0IEo9JDtKLnNpemU9MCxKLmFycmF5PXZvaWQgMCxKLnBvc2l0aW9uPTAsSi50eXBlPXZvaWQgMH1pZigkLnR5cGU9PT1WJHx8JC50eXBlPT09SUope2xldCBKPSQ7Si5zaXplPTAsSi5tYXA9dm9pZCAwLEoucmVhZENvdW50PTAsSi50eXBlPXZvaWQgMH10aGlzLnN0YWNrSGVhZFBvc2l0aW9uLS19cmVzZXQoKXt0aGlzLnN0YWNrLmxlbmd0aD0wLHRoaXMuc3RhY2tIZWFkUG9zaXRpb249LTF9fXZhciBZJD0tMSxYWj1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDApKSxHWD1uZXcgVWludDhBcnJheShYWi5idWZmZXIpO3RyeXtYWi5nZXRJbnQ4KDApfWNhdGNoKCQpe2lmKCEoJCBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IEVycm9yKCJUaGlzIG1vZHVsZSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IEphdmFTY3JpcHQgZW5naW5lIGJlY2F1c2UgRGF0YVZpZXcgZG9lcyBub3QgdGhyb3cgUmFuZ2VFcnJvciBvbiBvdXQtb2YtYm91bmRzIGFjY2VzcyIpfXZhciBNSj1SYW5nZUVycm9yKCJJbnN1ZmZpY2llbnQgZGF0YSIpLHpYPW5ldyBKWjtjbGFzcyBUJHtleHRlbnNpb25Db2RlYztjb250ZXh0O3VzZUJpZ0ludDY0O3Jhd1N0cmluZ3M7bWF4U3RyTGVuZ3RoO21heEJpbkxlbmd0aDttYXhBcnJheUxlbmd0aDttYXhNYXBMZW5ndGg7bWF4RXh0TGVuZ3RoO2tleURlY29kZXI7bWFwS2V5Q29udmVydGVyO3RvdGFsUG9zPTA7cG9zPTA7dmlldz1YWjtieXRlcz1HWDtoZWFkQnl0ZT1ZJDtzdGFjaz1uZXcgQ0o7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9uMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5yYXdTdHJpbmdzPSQ/LnJhd1N0cmluZ3M/PyExLHRoaXMubWF4U3RyTGVuZ3RoPSQ/Lm1heFN0ckxlbmd0aD8/YzAsdGhpcy5tYXhCaW5MZW5ndGg9JD8ubWF4QmluTGVuZ3RoPz9jMCx0aGlzLm1heEFycmF5TGVuZ3RoPSQ/Lm1heEFycmF5TGVuZ3RoPz9jMCx0aGlzLm1heE1hcExlbmd0aD0kPy5tYXhNYXBMZW5ndGg/P2MwLHRoaXMubWF4RXh0TGVuZ3RoPSQ/Lm1heEV4dExlbmd0aD8/YzAsdGhpcy5rZXlEZWNvZGVyPSQ/LmtleURlY29kZXIhPT12b2lkIDA/JC5rZXlEZWNvZGVyOnpYLHRoaXMubWFwS2V5Q29udmVydGVyPSQ/Lm1hcEtleUNvbnZlcnRlcj8/V1h9Y2xvbmUoKXtyZXR1cm4gbmV3IFQkKHtleHRlbnNpb25Db2RlYzp0aGlzLmV4dGVuc2lvbkNvZGVjLGNvbnRleHQ6dGhpcy5jb250ZXh0LHVzZUJpZ0ludDY0OnRoaXMudXNlQmlnSW50NjQscmF3U3RyaW5nczp0aGlzLnJhd1N0cmluZ3MsbWF4U3RyTGVuZ3RoOnRoaXMubWF4U3RyTGVuZ3RoLG1heEJpbkxlbmd0aDp0aGlzLm1heEJpbkxlbmd0aCxtYXhBcnJheUxlbmd0aDp0aGlzLm1heEFycmF5TGVuZ3RoLG1heE1hcExlbmd0aDp0aGlzLm1heE1hcExlbmd0aCxtYXhFeHRMZW5ndGg6dGhpcy5tYXhFeHRMZW5ndGgsa2V5RGVjb2Rlcjp0aGlzLmtleURlY29kZXJ9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMudG90YWxQb3M9MCx0aGlzLmhlYWRCeXRlPVkkLHRoaXMuc3RhY2sucmVzZXQoKX1zZXRCdWZmZXIoJCl7bGV0IFo9WCQoJCk7dGhpcy5ieXRlcz1aLHRoaXMudmlldz1uZXcgRGF0YVZpZXcoWi5idWZmZXIsWi5ieXRlT2Zmc2V0LFouYnl0ZUxlbmd0aCksdGhpcy5wb3M9MH1hcHBlbmRCdWZmZXIoJCl7aWYodGhpcy5oZWFkQnl0ZT09PVkkJiYhdGhpcy5oYXNSZW1haW5pbmcoMSkpdGhpcy5zZXRCdWZmZXIoJCk7ZWxzZXtsZXQgWj10aGlzLmJ5dGVzLnN1YmFycmF5KHRoaXMucG9zKSxKPVgkKCQpLFE9bmV3IFVpbnQ4QXJyYXkoWi5sZW5ndGgrSi5sZW5ndGgpO1Euc2V0KFopLFEuc2V0KEosWi5sZW5ndGgpLHRoaXMuc2V0QnVmZmVyKFEpfX1oYXNSZW1haW5pbmcoJCl7cmV0dXJuIHRoaXMudmlldy5ieXRlTGVuZ3RoLXRoaXMucG9zPj0kfWNyZWF0ZUV4dHJhQnl0ZUVycm9yKCQpe2xldHt2aWV3OloscG9zOkp9PXRoaXM7cmV0dXJuIFJhbmdlRXJyb3IoYEV4dHJhICR7Wi5ieXRlTGVuZ3RoLUp9IG9mICR7Wi5ieXRlTGVuZ3RofSBieXRlKHMpIGZvdW5kIGF0IGJ1ZmZlclskeyR9XWApfWRlY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGUoJCk7dHJ5e3RoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5zZXRCdWZmZXIoJCk7bGV0IFo9dGhpcy5kb0RlY29kZVN5bmMoKTtpZih0aGlzLmhhc1JlbWFpbmluZygxKSl0aHJvdyB0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMucG9zKTtyZXR1cm4gWn1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19KmRlY29kZU11bHRpKCQpe2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpKCQpO3JldHVybn10cnl7dGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLnNldEJ1ZmZlcigkKTt3aGlsZSh0aGlzLmhhc1JlbWFpbmluZygxKSl5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1hc3luYyBkZWNvZGVBc3luYygkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGVBc3luYygkKTt0cnl7dGhpcy5lbnRlcmVkPSEwO2xldCBaPSExLEo7Zm9yIGF3YWl0KGxldCBWIG9mICQpe2lmKFopdGhyb3cgdGhpcy5lbnRlcmVkPSExLHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7dGhpcy5hcHBlbmRCdWZmZXIoVik7dHJ5e0o9dGhpcy5kb0RlY29kZVN5bmMoKSxaPSEwfWNhdGNoKFcpe2lmKCEoVyBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IFd9dGhpcy50b3RhbFBvcys9dGhpcy5wb3N9aWYoWil7aWYodGhpcy5oYXNSZW1haW5pbmcoMSkpdGhyb3cgdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnRvdGFsUG9zKTtyZXR1cm4gSn1sZXR7aGVhZEJ5dGU6USxwb3M6WCx0b3RhbFBvczpZfT10aGlzO3Rocm93IFJhbmdlRXJyb3IoYEluc3VmZmljaWVudCBkYXRhIGluIHBhcnNpbmcgJHt3JChRKX0gYXQgJHtZfSAoJHtYfSBpbiB0aGUgY3VycmVudCBidWZmZXIpYCl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRlY29kZUFycmF5U3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMCl9ZGVjb2RlU3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMSl9YXN5bmMqZGVjb2RlTXVsdGlBc3luYygkLFope2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpQXN5bmMoJCxaKTtyZXR1cm59dHJ5e3RoaXMuZW50ZXJlZD0hMDtsZXQgSj1aLFE9LTE7Zm9yIGF3YWl0KGxldCBYIG9mICQpe2lmKFomJlE9PT0wKXRocm93IHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7aWYodGhpcy5hcHBlbmRCdWZmZXIoWCksSilRPXRoaXMucmVhZEFycmF5U2l6ZSgpLEo9ITEsdGhpcy5jb21wbGV0ZSgpO3RyeXt3aGlsZSghMClpZih5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpLC0tUT09PTApYnJlYWt9Y2F0Y2goWSl7aWYoIShZIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikpdGhyb3cgWX10aGlzLnRvdGFsUG9zKz10aGlzLnBvc319ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRvRGVjb2RlU3luYygpeyQ6d2hpbGUoITApe2xldCAkPXRoaXMucmVhZEhlYWRCeXRlKCksWjtpZigkPj0yMjQpWj0kLTI1NjtlbHNlIGlmKCQ8MTkyKWlmKCQ8MTI4KVo9JDtlbHNlIGlmKCQ8MTQ0KXtsZXQgUT0kLTEyODtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBaPXt9fWVsc2UgaWYoJDwxNjApe2xldCBRPSQtMTQ0O2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNle2xldCBRPSQtMTYwO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwwKX1lbHNlIGlmKCQ9PT0xOTIpWj1udWxsO2Vsc2UgaWYoJD09PTE5NClaPSExO2Vsc2UgaWYoJD09PTE5NSlaPSEwO2Vsc2UgaWYoJD09PTIwMilaPXRoaXMucmVhZEYzMigpO2Vsc2UgaWYoJD09PTIwMylaPXRoaXMucmVhZEY2NCgpO2Vsc2UgaWYoJD09PTIwNClaPXRoaXMucmVhZFU4KCk7ZWxzZSBpZigkPT09MjA1KVo9dGhpcy5yZWFkVTE2KCk7ZWxzZSBpZigkPT09MjA2KVo9dGhpcy5yZWFkVTMyKCk7ZWxzZSBpZigkPT09MjA3KWlmKHRoaXMudXNlQmlnSW50NjQpWj10aGlzLnJlYWRVNjRBc0JpZ0ludCgpO2Vsc2UgWj10aGlzLnJlYWRVNjQoKTtlbHNlIGlmKCQ9PT0yMDgpWj10aGlzLnJlYWRJOCgpO2Vsc2UgaWYoJD09PTIwOSlaPXRoaXMucmVhZEkxNigpO2Vsc2UgaWYoJD09PTIxMClaPXRoaXMucmVhZEkzMigpO2Vsc2UgaWYoJD09PTIxMSlpZih0aGlzLnVzZUJpZ0ludDY0KVo9dGhpcy5yZWFkSTY0QXNCaWdJbnQoKTtlbHNlIFo9dGhpcy5yZWFkSTY0KCk7ZWxzZSBpZigkPT09MjE3KXtsZXQgUT10aGlzLmxvb2tVOCgpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwxKX1lbHNlIGlmKCQ9PT0yMTgpe2xldCBRPXRoaXMubG9va1UxNigpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwyKX1lbHNlIGlmKCQ9PT0yMTkpe2xldCBRPXRoaXMubG9va1UzMigpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSw0KX1lbHNlIGlmKCQ9PT0yMjApe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNlIGlmKCQ9PT0yMjEpe2xldCBRPXRoaXMucmVhZFUzMigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNlIGlmKCQ9PT0yMjIpe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hNYXBTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIFo9e319ZWxzZSBpZigkPT09MjIzKXtsZXQgUT10aGlzLnJlYWRVMzIoKTtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBaPXt9fWVsc2UgaWYoJD09PTE5Nil7bGV0IFE9dGhpcy5sb29rVTgoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsMSl9ZWxzZSBpZigkPT09MTk3KXtsZXQgUT10aGlzLmxvb2tVMTYoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsMil9ZWxzZSBpZigkPT09MTk4KXtsZXQgUT10aGlzLmxvb2tVMzIoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsNCl9ZWxzZSBpZigkPT09MjEyKVo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMSwwKTtlbHNlIGlmKCQ9PT0yMTMpWj10aGlzLmRlY29kZUV4dGVuc2lvbigyLDApO2Vsc2UgaWYoJD09PTIxNClaPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDQsMCk7ZWxzZSBpZigkPT09MjE1KVo9dGhpcy5kZWNvZGVFeHRlbnNpb24oOCwwKTtlbHNlIGlmKCQ9PT0yMTYpWj10aGlzLmRlY29kZUV4dGVuc2lvbigxNiwwKTtlbHNlIGlmKCQ9PT0xOTkpe2xldCBRPXRoaXMubG9va1U4KCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDEpfWVsc2UgaWYoJD09PTIwMCl7bGV0IFE9dGhpcy5sb29rVTE2KCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDIpfWVsc2UgaWYoJD09PTIwMSl7bGV0IFE9dGhpcy5sb29rVTMyKCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDQpfWVsc2UgdGhyb3cgbmV3IHQoYFVucmVjb2duaXplZCB0eXBlIGJ5dGU6ICR7dyQoJCl9YCk7dGhpcy5jb21wbGV0ZSgpO2xldCBKPXRoaXMuc3RhY2s7d2hpbGUoSi5sZW5ndGg+MCl7bGV0IFE9Si50b3AoKTtpZihRLnR5cGU9PT1RWilpZihRLmFycmF5W1EucG9zaXRpb25dPVosUS5wb3NpdGlvbisrLFEucG9zaXRpb249PT1RLnNpemUpWj1RLmFycmF5LEoucmVsZWFzZShRKTtlbHNlIGNvbnRpbnVlICQ7ZWxzZSBpZihRLnR5cGU9PT1WJCl7aWYoWj09PSJfX3Byb3RvX18iKXRocm93IG5ldyB0KCJUaGUga2V5IF9fcHJvdG9fXyBpcyBub3QgYWxsb3dlZCIpO1Eua2V5PXRoaXMubWFwS2V5Q29udmVydGVyKFopLFEudHlwZT1JSjtjb250aW51ZSAkfWVsc2UgaWYoUS5tYXBbUS5rZXldPVosUS5yZWFkQ291bnQrKyxRLnJlYWRDb3VudD09PVEuc2l6ZSlaPVEubWFwLEoucmVsZWFzZShRKTtlbHNle1Eua2V5PW51bGwsUS50eXBlPVYkO2NvbnRpbnVlICR9fXJldHVybiBafX1yZWFkSGVhZEJ5dGUoKXtpZih0aGlzLmhlYWRCeXRlPT09WSQpdGhpcy5oZWFkQnl0ZT10aGlzLnJlYWRVOCgpO3JldHVybiB0aGlzLmhlYWRCeXRlfWNvbXBsZXRlKCl7dGhpcy5oZWFkQnl0ZT1ZJH1yZWFkQXJyYXlTaXplKCl7bGV0ICQ9dGhpcy5yZWFkSGVhZEJ5dGUoKTtzd2l0Y2goJCl7Y2FzZSAyMjA6cmV0dXJuIHRoaXMucmVhZFUxNigpO2Nhc2UgMjIxOnJldHVybiB0aGlzLnJlYWRVMzIoKTtkZWZhdWx0OmlmKCQ8MTYwKXJldHVybiAkLTE0NDtlbHNlIHRocm93IG5ldyB0KGBVbnJlY29nbml6ZWQgYXJyYXkgdHlwZSBieXRlOiAke3ckKCQpfWApfX1wdXNoTWFwU3RhdGUoJCl7aWYoJD50aGlzLm1heE1hcExlbmd0aCl0aHJvdyBuZXcgdChgTWF4IGxlbmd0aCBleGNlZWRlZDogbWFwIGxlbmd0aCAoJHskfSkgPiBtYXhNYXBMZW5ndGhMZW5ndGggKCR7dGhpcy5tYXhNYXBMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaE1hcFN0YXRlKCQpfXB1c2hBcnJheVN0YXRlKCQpe2lmKCQ+dGhpcy5tYXhBcnJheUxlbmd0aCl0aHJvdyBuZXcgdChgTWF4IGxlbmd0aCBleGNlZWRlZDogYXJyYXkgbGVuZ3RoICgkeyR9KSA+IG1heEFycmF5TGVuZ3RoICgke3RoaXMubWF4QXJyYXlMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaEFycmF5U3RhdGUoJCl9ZGVjb2RlU3RyaW5nKCQsWil7aWYoIXRoaXMucmF3U3RyaW5nc3x8dGhpcy5zdGF0ZUlzTWFwS2V5KCkpcmV0dXJuIHRoaXMuZGVjb2RlVXRmOFN0cmluZygkLFopO3JldHVybiB0aGlzLmRlY29kZUJpbmFyeSgkLFopfWRlY29kZVV0ZjhTdHJpbmcoJCxaKXtpZigkPnRoaXMubWF4U3RyTGVuZ3RoKXRocm93IG5ldyB0KGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBVVEYtOCBieXRlIGxlbmd0aCAoJHskfSkgPiBtYXhTdHJMZW5ndGggKCR7dGhpcy5tYXhTdHJMZW5ndGh9KWApO2lmKHRoaXMuYnl0ZXMuYnl0ZUxlbmd0aDx0aGlzLnBvcytaKyQpdGhyb3cgTUo7bGV0IEo9dGhpcy5wb3MrWixRO2lmKHRoaXMuc3RhdGVJc01hcEtleSgpJiZ0aGlzLmtleURlY29kZXI/LmNhbkJlQ2FjaGVkKCQpKVE9dGhpcy5rZXlEZWNvZGVyLmRlY29kZSh0aGlzLmJ5dGVzLEosJCk7ZWxzZSBRPU9KKHRoaXMuYnl0ZXMsSiwkKTtyZXR1cm4gdGhpcy5wb3MrPVorJCxRfXN0YXRlSXNNYXBLZXkoKXtpZih0aGlzLnN0YWNrLmxlbmd0aD4wKXJldHVybiB0aGlzLnN0YWNrLnRvcCgpLnR5cGU9PT1WJDtyZXR1cm4hMX1kZWNvZGVCaW5hcnkoJCxaKXtpZigkPnRoaXMubWF4QmluTGVuZ3RoKXRocm93IG5ldyB0KGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBiaW4gbGVuZ3RoICgkeyR9KSA+IG1heEJpbkxlbmd0aCAoJHt0aGlzLm1heEJpbkxlbmd0aH0pYCk7aWYoIXRoaXMuaGFzUmVtYWluaW5nKCQrWikpdGhyb3cgTUo7bGV0IEo9dGhpcy5wb3MrWixRPXRoaXMuYnl0ZXMuc3ViYXJyYXkoSixKKyQpO3JldHVybiB0aGlzLnBvcys9WiskLFF9ZGVjb2RlRXh0ZW5zaW9uKCQsWil7aWYoJD50aGlzLm1heEV4dExlbmd0aCl0aHJvdyBuZXcgdChgTWF4IGxlbmd0aCBleGNlZWRlZDogZXh0IGxlbmd0aCAoJHskfSkgPiBtYXhFeHRMZW5ndGggKCR7dGhpcy5tYXhFeHRMZW5ndGh9KWApO2xldCBKPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zK1opLFE9dGhpcy5kZWNvZGVCaW5hcnkoJCxaKzEpO3JldHVybiB0aGlzLmV4dGVuc2lvbkNvZGVjLmRlY29kZShRLEosdGhpcy5jb250ZXh0KX1sb29rVTgoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKX1sb29rVTE2KCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50MTYodGhpcy5wb3MpfWxvb2tVMzIoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyl9cmVhZFU4KCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRJOCgpe2xldCAkPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRVMTYoKXtsZXQgJD10aGlzLnZpZXcuZ2V0VWludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkSTE2KCl7bGV0ICQ9dGhpcy52aWV3LmdldEludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkVTMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZEkzMigpe2xldCAkPXRoaXMudmlldy5nZXRJbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZFU2NCgpe2xldCAkPXFKKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NCgpe2xldCAkPUMkKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZFU2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ0ludDY0KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTgsJH1yZWFkRjMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldEZsb2F0MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRGNjQoKXtsZXQgJD10aGlzLnZpZXcuZ2V0RmxvYXQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9fWZ1bmN0aW9uIFlaKCQsWil7cmV0dXJuIG5ldyBUJChaKS5kZWNvZGUoJCl9Y2xhc3MgVyR7bGlzdGVuZXJzPW5ldyBNYXA7YWRkRXZlbnRMaXN0ZW5lcigkLFope2xldCBKPXRoaXMubGlzdGVuZXJzLmdldCgkKTtpZighSilKPW5ldyBTZXQsdGhpcy5saXN0ZW5lcnMuc2V0KCQsSik7cmV0dXJuIEouYWRkKFopLCgpPT57dGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCQsWil9fXJlbW92ZUV2ZW50TGlzdGVuZXIoJCxaKXtsZXQgSj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoSil7aWYoSi5kZWxldGUoWiksSi5zaXplPT09MCl0aGlzLmxpc3RlbmVycy5kZWxldGUoJCl9fWVtaXQoJCxaKXtsZXQgSj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoSil7bGV0IFE9QXJyYXkuZnJvbShKKTtmb3IobGV0IFggb2YgUSlYKFopfX1lbWl0QWxsKCQpe2xldCBaPUFycmF5LmZyb20odGhpcy5saXN0ZW5lcnMua2V5cygpKTtmb3IobGV0IEogb2YgWil0aGlzLmVtaXQoSiwkKX19Y2xhc3MgeDB7Z2V0dGVyO3N0YXRpYyBldmVudE5hbWU9InVwZGF0ZSI7ZW1pdHRlcjtjb25zdHJ1Y3RvcigkKXt0aGlzLmdldHRlcj0kO3RoaXMuZW1pdHRlcj1uZXcgVyR9Z2V0PSgpPT50aGlzLmdldHRlcigpO2FzeW5jIGVtaXQoKXtsZXQgJD1hd2FpdCB0aGlzLmdldHRlcigpO3F1ZXVlTWljcm90YXNrKCgpPT50aGlzLmVtaXR0ZXIuZW1pdCh4MC5ldmVudE5hbWUsJCkpfWxpc3RlbigkKXtyZXR1cm4gdGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoeDAuZXZlbnROYW1lLCQpLCgpPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoeDAuZXZlbnROYW1lLCQpfX19ZnVuY3Rpb24gUigkKXtyZXR1cm5bJCwwXX1mdW5jdGlvbiBHKCQpe3JldHVyblt2b2lkIDAsJF19ZnVuY3Rpb24gS1goJCl7aWYoJDwwKWNvbnNvbGUuaW5mbygiTiIsJCksY29uc29sZS50cmFjZSgpO2lmKHR5cGVvZiAkIT09ImJpZ2ludCIpJD1CaWdJbnQoJCk7aWYoJDwwbilyZXR1cm4gRygxMCk7bGV0IFo9W107d2hpbGUoJD4wbil7bGV0IEo9TnVtYmVyKCQmMHg3Zm4pO2lmKCQ+Pj03biwkPjBuKVoucHVzaChKfDEyOCk7ZWxzZSBaLnB1c2goSil9aWYoWi5sZW5ndGg9PT0wKXJldHVybiBSKG5ldyBVaW50OEFycmF5KFswXSkpO2lmKFoubGVuZ3RoPjgpcmV0dXJuIEcoMjYpO3JldHVybiBSKG5ldyBVaW50OEFycmF5KFopKX1mdW5jdGlvbiBGWCgkLFo9MCl7bGV0IEo9MG4sUT0wLFg9Wjt3aGlsZSghMCl7aWYoWD49JC5sZW5ndGgpcmV0dXJuIEcoMTQpO2xldCBZPSRbWCsrXTtpZihZPT09dm9pZCAwKXJldHVybiBHKDE0KTtpZihKfD1CaWdJbnQoWSYxMjcpPDxCaWdJbnQoUSksKFkmMTI4KT09PTApe2lmKFgtWj44KXJldHVybiBHKDI2KTtyZXR1cm4gUih7dmFsdWU6Sj4weDFmZmZmZmZmZmZmZmZmbj9KOk51bWJlcihKKSxieXRlc1JlYWQ6WC1afSl9aWYoUSs9NyxRPj01NilyZXR1cm4gRygyNil9fWNsYXNzIG17ZGF0YTtwb3M9MDtjb25zdHJ1Y3RvcigkKXt0aGlzLmRhdGE9JH1zdGF0aWMgYXN5bmMgZnJvbVJlc3BvbnNlKCQpe2xldCBaPWF3YWl0ICQuYXJyYXlCdWZmZXIoKSxKPW5ldyBVaW50OEFycmF5KFopO3JldHVybiBuZXcgbShKKX1yZWFkQmlnSW50KCl7aWYodGhpcy5wb3MrOD50aGlzLmRhdGEubGVuZ3RoKXJldHVybiBHKDcpO2xldCAkPW5ldyBEYXRhVmlldyh0aGlzLmRhdGEuYnVmZmVyLHRoaXMuZGF0YS5ieXRlT2Zmc2V0K3RoaXMucG9zKS5nZXRCaWdVaW50NjQoMCwhMSk7cmV0dXJuIHRoaXMucG9zKz04LFIoJCl9cmVhZERhdGUoKXtsZXRbJCxaXT10aGlzLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gUihuZXcgRGF0ZSgkKSl9cmVhZFZhckludCgpe2xldFskLFpdPUZYKHRoaXMuZGF0YSx0aGlzLnBvcyk7aWYoWiE9PTApcmV0dXJuIEcoWik7dGhpcy5wb3MrPSQuYnl0ZXNSZWFkO2xldCBKPSQudmFsdWU7cmV0dXJuIFIodHlwZW9mIEo9PT0iYmlnaW50Ij9OdW1iZXIoSik6Sil9cmVhZFZhclN0cmluZygpe2xldFskLFpdPXRoaXMucmVhZFZhckludCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtKLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBYPW5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShKKTtyZXR1cm4gUihYKX1yZWFkQnl0ZXMoJCl7aWYoJDwwKXJldHVybiBHKDEwKTtpZih0aGlzLnBvcyskPnRoaXMuZGF0YS5sZW5ndGgpcmV0dXJuIEcoMjMpO2xldCBaPXRoaXMuZGF0YS5zbGljZSh0aGlzLnBvcyx0aGlzLnBvcyskKTtyZXR1cm4gdGhpcy5wb3MrPSQsUihaKX1yZWFkVmFyQnl0ZXMoKXtsZXRbJCxaXT10aGlzLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gdGhpcy5yZWFkQnl0ZXMoJCl9cmVhZFN0cnVjdCgkKXtyZXR1cm4gJC5kZWNvZGUodGhpcyl9cmVhZFN0cnVjdHMoJCl7bGV0IFo9W107d2hpbGUoIXRoaXMuZG9uZSgpKXtsZXRbSixRXT10aGlzLnJlYWRTdHJ1Y3QoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7Wi5wdXNoKEopfXJldHVybiBSKFopfXJlYWRCeXRlc1NlcSgkKXtsZXQgWj1bXTt3aGlsZSghdGhpcy5kb25lKCkpe2xldFtKLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO1oucHVzaChKKX1yZXR1cm4gUihaKX1kb25lKCl7cmV0dXJuIHRoaXMucG9zPj10aGlzLmRhdGEubGVuZ3RofWNvbnN1bWVkKCl7cmV0dXJuIHRoaXMucG9zfX1jbGFzcyBTe3BhcnRzPVtdO3dyaXRlQmlnSW50KCQpe2xldCBaPW5ldyBVaW50OEFycmF5KDgpO25ldyBEYXRhVmlldyhaLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsJCwhMSksdGhpcy5wYXJ0cy5wdXNoKFopfXdyaXRlRGF0ZSgkKXtsZXQgWj0kLmdldFRpbWUoKTtyZXR1cm4gdGhpcy53cml0ZVZhckludChaKX13cml0ZVZhckludCgkKXtsZXRbWixKXT1LWCgkKTtpZihKIT09MClyZXR1cm4gSjtyZXR1cm4gdGhpcy5wYXJ0cy5wdXNoKFopLDB9d3JpdGVWYXJTdHJpbmcoJCl7bGV0IFo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpLEo9dGhpcy53cml0ZVZhckludChaLmxlbmd0aCk7aWYoSiE9PTApcmV0dXJuIEo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcyhaKSwwfXByZXBlbmRCeXRlcygkKXt0aGlzLnBhcnRzLnVuc2hpZnQoJC5zbGljZSgpKX13cml0ZUJ5dGVzKCQpe3RoaXMucGFydHMucHVzaCgkLnNsaWNlKCkpfXdyaXRlVmFyQnl0ZXMoJCl7bGV0IFo9dGhpcy53cml0ZVZhckludCgkLmxlbmd0aCk7aWYoWiE9PTApcmV0dXJuIFo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcygkKSwwfXdyaXRlU3RydWN0KCQsWil7cmV0dXJuICQuZW5jb2RlKHRoaXMsWil9d3JpdGVTdHJ1Y3RzKCQsWil7Zm9yKGxldCBKIG9mIFope2xldCBRPXRoaXMud3JpdGVTdHJ1Y3QoJCxKKTtpZihRIT09MClyZXR1cm4gUX1yZXR1cm4gMH13cml0ZUJ5dGVzU2VxKCQpe2ZvcihsZXQgWiBvZiAkKXRoaXMud3JpdGVCeXRlcyhaKX1yZXN1bHQoKXtsZXQgJD10aGlzLnBhcnRzLnJlZHVjZSgoUSxYKT0+UStYLmxlbmd0aCwwKSxaPW5ldyBVaW50OEFycmF5KCQpLEo9MDtmb3IobGV0IFEgb2YgdGhpcy5wYXJ0cylaLnNldChRLEopLEorPVEubGVuZ3RoO3JldHVybiBafSpzY2FuKCl7Zm9yKGxldCAkIG9mIHRoaXMucGFydHMpeWllbGQgJH19YXN5bmMgZnVuY3Rpb24gVlooJCxaKXtsZXQgSj1uZXcgUyxRPUoud3JpdGVEYXRlKFopO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBYPUoucmVzdWx0KCksWT1hd2FpdCAkLnNpZ24oWCk7cmV0dXJuIFIoe3B1YktleTokLnB1YmxpY0tleSxzaWc6WSx0aW1lc3RhbXA6Wn0pfWFzeW5jIGZ1bmN0aW9uIEQwKCQsWixKKXtsZXQgUT1KLm5vdygpLmdldFRpbWUoKSxYPSQudGltZXN0YW1wLmdldFRpbWUoKTtpZihNYXRoLmFicyhRLVgpPnpKKXJldHVybiA0O2xldCBWPW5ldyBTO1Yud3JpdGVEYXRlKCQudGltZXN0YW1wKTtsZXQgVz1WLnJlc3VsdCgpO2lmKCFhd2FpdCBaLmNoZWNrU2lnRWQyNTUxOSgkLnNpZyxXLCQucHViS2V5KSlyZXR1cm4gMztyZXR1cm4gMH12YXIgWTA9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmlkKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlRGF0ZShaLnRzKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZFZhckJ5dGVzKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsWF09JC5yZWFkRGF0ZSgpO2lmKFghPT0wKXJldHVybiBHKFgpO3JldHVybiBSKHtpZDpaLHRzOlF9KX19O2Z1bmN0aW9uIGokKCQpe2xldCBaPW5ldyBTLEo9Wi53cml0ZVN0cnVjdChZMCwkKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXQgUT1aLnJlc3VsdCgpO3JldHVybiBSKFEpfXZhciBXMD17ZW5jb2RlKCQsWil7bGV0IEo9JC53cml0ZVZhckJ5dGVzKFouZWlkKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFySW50KFoub2ZmKTtpZihRIT09MClyZXR1cm4gUTtsZXQgWD0kLndyaXRlVmFySW50KFouY3RyKTtpZihYIT09MClyZXR1cm4gWDtsZXQgWT0kLndyaXRlVmFySW50KFoubGVuKTtpZihZIT09MClyZXR1cm4gWTtpZihaLmhzaCkkLndyaXRlQnl0ZXMoWi5oc2gpO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFyQnl0ZXMoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXQgUT1uZXcgbShaKSxbLFhdPVkwLmRlY29kZShRKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbWSxWXT0kLnJlYWRWYXJJbnQoKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXRbVyx6XT0kLnJlYWRWYXJJbnQoKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXRbSyxGXT0kLnJlYWRWYXJJbnQoKTtpZihGIT09MClyZXR1cm4gRyhGKTtsZXQgTjtpZihLPjApe2xldFtPLFVdPSQucmVhZEJ5dGVzKE0kKTtpZihVIT09MClyZXR1cm4gRyhVKTtOPU99cmV0dXJuIFIoe2VpZDpaLG9mZjpZLGN0cjpXLGxlbjpLLGhzaDpOfSl9fTtmdW5jdGlvbiBSMCgkKXtyZXR1cm4gQXJyYXkuZnJvbSgkKS5tYXAoKEopPT5KLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCIwIikpLmpvaW4oIiIpfWZ1bmN0aW9uIFBKKCQpe2lmKCQubGVuZ3RoJTIhPT0wKXRocm93IEVycm9yKCJJbnZhbGlkIGhleCBzdHJpbmciKTtsZXQgWj1uZXcgVWludDhBcnJheSgkLmxlbmd0aC8yKTtmb3IobGV0IEo9MDtKPCQubGVuZ3RoO0orPTIpWltKLzJdPU51bWJlci5wYXJzZUludCgkLnN1YnN0cihKLDIpLDE2KTtyZXR1cm4gWn1mdW5jdGlvbiBhKCQsWil7aWYoJD09PVopcmV0dXJuITA7aWYoJC5ieXRlTGVuZ3RoIT09Wi5ieXRlTGVuZ3RoKXJldHVybiExO3JldHVybiAkLmV2ZXJ5KChKLFEpPT5KPT09WltRXSl9dmFyIEI7aWYodHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLnRvQmFzZTY0PT09ImZ1bmN0aW9uIilCPSgkKT0+JC50b0Jhc2U2NCgpO2Vsc2UgQj0oJCk9PmJ0b2EoU3RyaW5nLmZyb21DaGFyQ29kZSguLi4kKSk7dmFyIE4wO2lmKHR5cGVvZiBVaW50OEFycmF5LmZyb21CYXNlNjQ9PT0iZnVuY3Rpb24iKU4wPSgkKT0+VWludDhBcnJheS5mcm9tQmFzZTY0KCQpO2Vsc2UgTjA9KCQpPT5VaW50OEFycmF5LmZyb20oYXRvYigkKSwoWik9PlouY2hhckNvZGVBdCgwKSk7ZnVuY3Rpb24gRyQoJCxaKXtsZXQgSj1uZXcgVWludDhBcnJheSgkLmxlbmd0aCtaLmxlbmd0aCk7cmV0dXJuIEouc2V0KCQsMCksSi5zZXQoWiwkLmxlbmd0aCksSn1mdW5jdGlvbiB3SigkLFosSil7cmV0dXJuIEouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLCQuaGVhZENwaCxaKX1hc3luYyBmdW5jdGlvbiBUSigkLFosSixRKXtsZXQgWDtpZigkLmJvZCYmJC5sZW4+MClYPWF3YWl0IEouYmxha2UzKCQuYm9kKTtsZXQgWT1uZXcgUyxWPVcwLmVuY29kZShZLHsuLi4kLGhzaDpYfSk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0IFc9WS5yZXN1bHQoKSx6PWF3YWl0IFoua2RtRm9yKFcpLEs9US5kZXJpdmVDaXBoZXIoeiwiZW5jcnlwdCIpLEY9YXdhaXQgSy5lbmNyeXB0KFcpLE49JC5ib2Q/YXdhaXQgSy5lbmNyeXB0KCQuYm9kKTpuZXcgVWludDhBcnJheSgwKSxPPWF3YWl0IFouc2lnbihGKTtyZXR1cm4gUih7c2lnOk8sa2RtOnosaGVhZENwaDpGLGJvZHlDcGg6Tn0pfWFzeW5jIGZ1bmN0aW9uIFdaKCQsWixKLFEsWCl7bGV0IFk9bmV3IG0oJCksW1YsV109VzAuZGVjb2RlKFkpO2lmKFchPT0wKXJldHVybiBHKDE0KTtsZXQgejt0cnl7ej1aJiZaLmxlbmd0aD4wP2F3YWl0IEouZGVjcnlwdChaKTp2b2lkIDB9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldCBLPVYuaHNoJiZ6PT09dm9pZCAwLEY9Vi5oc2g9PT12b2lkIDAmJnohPT12b2lkIDA7aWYoS3x8RilyZXR1cm4gRygxOSk7aWYoVi5oc2gmJnope2xldCBPPWF3YWl0IFEuYmxha2UzKHopO2lmKCFhKE8sVi5oc2gpKXJldHVybiBHKDE5KX1sZXQgTj1YPz9hd2FpdCBRLmJsYWtlMygkKTtyZXR1cm4gUih7bXNnSGVhZDpWLGJvZDp6LGhlYWRIYXNoOk59KX1jbGFzcyBHWntub3coKXtyZXR1cm4gbmV3IERhdGV9fWZ1bmN0aW9uIGpKKCQsWixKLFEpe2xldCBYPVouZ2V0VGltZSgpLSQuZ2V0VGltZSgpLFk9Si5nZXRUaW1lKCktUS5nZXRUaW1lKCk7cmV0dXJuKFgrWSkvMn12YXIgeiQ9e2VuY29kZSgkLFope2lmKCQud3JpdGVWYXJJbnQoWi5xdW90YSksWi5xdW90YT4wKXtpZihaLnVzYWdlPT09dm9pZCAwKXJldHVybiA5OyQud3JpdGVWYXJJbnQoWi51c2FnZSl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXQgUTtpZihaPjApe2xldFtYLFldPSQucmVhZFZhckludCgpO2lmKFkhPT0wKXJldHVybiBHKFkpO1E9WH1yZXR1cm4gUih7cXVvdGE6Wix1c2FnZTpRfSl9fTt2YXIgelo9e2VuY29kZSgkLFopeyQud3JpdGVCeXRlcyhuZXcgVWludDhBcnJheShbWi5zdGF0dXNdKSk7bGV0IEo9JC53cml0ZURhdGUoWi50aW1lUmN2ZCk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZURhdGUoWi50aW1lU2VudCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFg9JC53cml0ZVZhckludChaLnN1YnNjcmlwdGlvbi50ZXJtKTtpZihYIT09MClyZXR1cm4gWDtsZXQgWT0kLndyaXRlVmFySW50KFouc3Vic2NyaXB0aW9uLmVsYXBzZWQpO2lmKFkhPT0wKXJldHVybiBZO2xldCBWPSQud3JpdGVTdHJ1Y3QoeiQsWi5zdWJzY3JpcHRpb24uc3RhdCk7aWYoViE9PTApcmV0dXJuIFY7bGV0IFc9JC53cml0ZVN0cnVjdCh6JCxaLnN1YnNjcmlwdGlvbi5keW4pO2lmKFchPT0wKXJldHVybiBXO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkQnl0ZXMoMSk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0IFE9WlswXSxbWCxZXT0kLnJlYWREYXRlKCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsV109JC5yZWFkRGF0ZSgpO2lmKFchPT0wKXJldHVybiBHKFcpO2xldFt6LEtdPSQucmVhZFZhckludCgpO2lmKEshPT0wKXJldHVybiBHKEspO2xldFtGLE5dPSQucmVhZFZhckludCgpO2lmKE4hPT0wKXJldHVybiBHKE4pO2xldFtPLFVdPSQucmVhZFN0cnVjdCh6JCk7aWYoVSE9PTApcmV0dXJuIEcoVSk7bGV0W3EsSF09JC5yZWFkU3RydWN0KHokKTtpZihIIT09MClyZXR1cm4gRyhIKTtyZXR1cm4gUih7c3RhdHVzOlEsdGltZVJjdmQ6WCx0aW1lU2VudDpWLHN1YnNjcmlwdGlvbjp7dGVybTp6LGVsYXBzZWQ6RixzdGF0Ok8sZHluOnF9fSl9fTt2YXIgS1o9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmhlYWRDcGgpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJJbnQoWi5zZXEpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFyQnl0ZXMoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gUih7aGVhZENwaDpaLHNlcTpRfSl9fTt2YXIgVjA9e2VuY29kZSgkLFopeyQud3JpdGVCeXRlcyhaLnB1YktleSksJC53cml0ZUJ5dGVzKFouc2lnKTtsZXQgSj0kLndyaXRlRGF0ZShaLnRpbWVzdGFtcCk7aWYoSiE9PTApcmV0dXJuIEo7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRCeXRlcyhHSik7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsWF09JC5yZWFkQnl0ZXMoVDApO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtZLFZdPSQucmVhZERhdGUoKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gUih7cHViS2V5Olosc2lnOlEsdGltZXN0YW1wOll9KX19O3ZhciBESj17YXN5bmMgZW5jb2RlUmVxKCQsWixKLFEsWCl7bGV0IFk9WC53cml0ZVN0cnVjdChWMCxKKTtpZihZIT09MClyZXR1cm4gWTtmb3IobGV0IFYgb2YgUSlYLndyaXRlVmFySW50KFYpO3JldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxaLEope2xldHtjbG9jazpRLGNyeXB0bzpYLHN0b3JhZ2U6WX09JCxbVixXXT1aLnJlYWRTdHJ1Y3QoVjApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEQwKFYsWCxRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVYsW0YsTl09YXdhaXQgWS5oYXNVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO2lmKCFGKXJldHVybiA1O2xldFtPLFVdPVoucmVhZFZhckludCgpO2lmKFUhPT0wKXJldHVybiBVO2lmKCFaLmRvbmUoKSlyZXR1cm4gODtsZXRbcSxIXT1hd2FpdCBZLmxpc3RIZWFkcyhLLE8pO2lmKEghPT0wKXJldHVybiBIO3JldHVybiBKLndyaXRlU3RydWN0cyhLWixxKX0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyhLWil9fTt2YXIgRlo9e2VuY29kZSgkLFopeyQud3JpdGVWYXJJbnQoWi5zZXEpO2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmJvZHlDcGgpO2lmKEohPT0wKXJldHVybiBKO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gUih7c2VxOlosYm9keUNwaDpRfSl9fTt2YXIgQUo9e2FzeW5jIGVuY29kZVJlcSgkLFosSixRLFgpe2xldCBZPVgud3JpdGVTdHJ1Y3QoVjAsSik7aWYoWSE9PTApcmV0dXJuIFk7Zm9yKGxldCBWIG9mIFEpe2xldCBXPVgud3JpdGVWYXJJbnQoVik7aWYoVyE9PTApcmV0dXJuIFd9cmV0dXJuIDB9LGFzeW5jIGhhbmRsZVJlcSgkLFosSil7bGV0e2Nsb2NrOlEsY3J5cHRvOlgsc3RvcmFnZTpZfT0kLFtWLFddPVoucmVhZFN0cnVjdChWMCk7aWYoVyE9PTApcmV0dXJuIFc7bGV0IHo9YXdhaXQgRDAoVixYLFEpO2lmKHohPT0wKXJldHVybiB6O2xldHtwdWJLZXk6S309VixbRixOXT1hd2FpdCBZLmhhc1VzZXIoSyk7aWYoTiE9PTApcmV0dXJuIE47aWYoIUYpcmV0dXJuIDU7bGV0IE89W107d2hpbGUoIVouZG9uZSgpKXtsZXRbSCxNXT1aLnJlYWRWYXJJbnQoKTtpZihNIT09MClyZXR1cm4gTTtPLnB1c2goSCl9Y29uc29sZS5pbmZvKGBQVUxMOiAke08ubGVuZ3RofSBiYWdzYCk7bGV0W1UscV09YXdhaXQgWS5nZXRCb2RpZXMoSyxPKTtpZihxIT09MClyZXR1cm4gcTtpZighVSlyZXR1cm4gMTc7Zm9yKGxldHtzZXE6SCxib2R5Q3BoOk19b2YgVSl7bGV0IFA9e3NlcTpILGJvZHlDcGg6TX0sQz1KLndyaXRlU3RydWN0KEZaLFApO2lmKEMhPT0wKXJldHVybiBDfXJldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiAkLnJlYWRTdHJ1Y3RzKEZaKX19O3ZhciBOWj17ZW5jb2RlKCQsWil7JC53cml0ZUJ5dGVzKFouc2lnKSwkLndyaXRlQnl0ZXMoWi5rZG0pO2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmhlYWRDcGgpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJCeXRlcyhaLmJvZHlDcGgpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkQnl0ZXMoVDApO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPSQucmVhZEJ5dGVzKGowKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbWSxWXT0kLnJlYWRWYXJCeXRlcygpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtXLHpdPSQucmVhZFZhckJ5dGVzKCk7aWYoeiE9PTApcmV0dXJuIEcoeik7cmV0dXJuIFIoe3NpZzpaLGtkbTpRLGhlYWRDcGg6WSxib2R5Q3BoOld9KX19O3ZhciBEJD17ZW5jb2RlKCQsWil7bGV0IEo9JC53cml0ZVZhckludChaLnNlcSk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZVZhckJ5dGVzKFouaGVhZENwaCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFg9Wi5ib2R5Q3BoP1ouYm9keUNwaC5sZW5ndGg6MCxZPSQud3JpdGVWYXJJbnQoWCk7aWYoWSE9PTApcmV0dXJuIFk7aWYoWD4wKXtpZighWi5ib2R5Q3BoKXJldHVybiAxMDskLndyaXRlQnl0ZXMoWi5ib2R5Q3BoKX1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZFZhckludCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPSQucmVhZFZhckJ5dGVzKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0W1ksVl09JC5yZWFkVmFySW50KCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0IFc7aWYoWT4wKXtsZXRbeixLXT0kLnJlYWRCeXRlcyhZKTtpZihLIT09MClyZXR1cm4gRyhLKTtXPXp9cmV0dXJuIFIoe3NlcTpaLGhlYWRDcGg6USxib2R5Q3BoOld9KX19O3ZhciBBJD17ZW5jb2RlKCQsWil7JC53cml0ZUJ5dGVzKFouc2lnKSwkLndyaXRlQnl0ZXMoWi5rZG0pO2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmhlYWRDcGgpO2lmKEohPT0wKXJldHVybiBKO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkQnl0ZXMoVDApO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPSQucmVhZEJ5dGVzKGowKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbWSxWXT0kLnJlYWRWYXJCeXRlcygpO2lmKFYhPT0wKXJldHVybiBHKFYpO3JldHVybiBSKHtzaWc6WixrZG06USxoZWFkQ3BoOll9KX19O3ZhciBfJD17ZW5jb2RlKCQsWil7aWYoJC53cml0ZVZhckludChaLmlkeCksJC53cml0ZUJ5dGVzKG5ldyBVaW50OEFycmF5KFtaLnN0YXR1c10pKSxaLnN0YXR1cz09PTApJC53cml0ZVZhckludChaLnNlcSk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxYXT0kLnJlYWRCeXRlcygxKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXQgWT1RWzBdO2lmKFkhPT0wKXJldHVybiBSKHtpZHg6WixzdGF0dXM6WX0pO2xldFtWLFddPSQucmVhZFZhckludCgpO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBSKHtpZHg6WixzdGF0dXM6WSxzZXE6Vn0pfX07dmFyIF9KPXthc3luYyBlbmNvZGVSZXEoJCxaLEosUSxYKXtsZXQgWT1YLndyaXRlU3RydWN0KFYwLEopO2lmKFkhPT0wKXJldHVybiBZO2xldCBWPVgud3JpdGVTdHJ1Y3RzKE5aLFEpO2lmKFYhPT0wKXJldHVybiBWO3JldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxaLEope2xldHtjbG9jazpRLGNyeXB0bzpYLHN0b3JhZ2U6WSxub3RpZmllcjpWfT0kLFtXLHpdPVoucmVhZFN0cnVjdChWMCk7aWYoeiE9PTApcmV0dXJuIHo7bGV0IEs9YXdhaXQgRDAoVyxYLFEpO2lmKEshPT0wKXJldHVybiBLO2xldHtwdWJLZXk6Rn09VyxbTixPXT1hd2FpdCBZLmhhc1VzZXIoRik7aWYoTyE9PTApcmV0dXJuIE87aWYoIU4pcmV0dXJuIDU7bGV0W1UscV09Wi5yZWFkU3RydWN0cyhOWik7aWYocSE9PTApcmV0dXJuIHE7Y29uc29sZS5pbmZvKGBQVVNIOiAke1UubGVuZ3RofSBiYWdzYCk7bGV0IEg9W10sTT1bXTtmb3IobGV0IEk9MDtJPFUubGVuZ3RoO0krKyl7bGV0IEE9VVtJXTtpZighYXdhaXQgd0ooQSxGLFgpKXtsZXQgZz17aWR4Okksc3RhdHVzOjN9LGY9Si53cml0ZVN0cnVjdChfJCxnKTtpZihmIT09MClyZXR1cm4gZjtjb250aW51ZX1ILnB1c2goSSksTS5wdXNoKEEpfWxldFtQLENdPWF3YWl0IFkuc2V0QmFncyhGLE0pO2lmKEMhPT0wKXJldHVybiBDO2lmKCFQfHxQLmxlbmd0aCE9PU0ubGVuZ3RoKXJldHVybiAxNztsZXQgVD1bXTtmb3IobGV0IEk9MDtJPE0ubGVuZ3RoO0krKyl7bGV0IEE9TVtJXSx4PUhbSV0sZz1QW0ldLGY9bmV3IFMsaz1mLndyaXRlU3RydWN0KEEkLEEpO2lmKGshPT0wKXJldHVybiBrO2xldCBiPWYucmVzdWx0KCksdz17c2VxOmcsaGVhZENwaDpifTtpZihVLmxlbmd0aD09PTEmJkEuYm9keUNwaC5sZW5ndGg8PUtKKXcuYm9keUNwaD1BLmJvZHlDcGg7VC5wdXNoKHcpO2xldCBpPXtpZHg6eCxzdGF0dXM6MCxzZXE6Z30sdT1KLndyaXRlU3RydWN0KF8kLGkpO2lmKHUhPT0wKXJldHVybiB1fWlmKFQubGVuZ3RoPjApe2xldCBJPW5ldyBTLEE9SS53cml0ZVN0cnVjdHMoRCQsVCk7aWYoQSE9PTApcmV0dXJuIEE7bGV0IHg9SS5yZXN1bHQoKTthd2FpdCBQcm9taXNlLnJlc29sdmUoVi5wdXNoKEYseCkpfXJldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiAkLnJlYWRTdHJ1Y3RzKF8kKX19O3ZhciBMSj17YXN5bmMgZW5jb2RlUmVxKCQsWixKLFEsWCl7cmV0dXJuIFgud3JpdGVTdHJ1Y3QoVjAsSil9LGFzeW5jIGhhbmRsZVJlcSgkLFosSil7bGV0e2Nsb2NrOlEsY3J5cHRvOlgsc3RvcmFnZTpZfT0kLFtWLFddPVoucmVhZFN0cnVjdChWMCk7aWYoVyE9PTApcmV0dXJuIFc7bGV0IHo9YXdhaXQgRDAoVixYLFEpO2lmKHohPT0wKXJldHVybiB6O2xldHtwdWJLZXk6S309VjtpZighWi5kb25lKCkpcmV0dXJuIDg7bGV0W0YsTl09YXdhaXQgWS5hZGRVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO3JldHVybiAwfSxkZWNvZGVSZXNwKCQpe3JldHVybiBSKHZvaWQgMCl9fTtjbGFzcyBSWnt1cmw7d2Vic29ja2V0O2NvbnN0cnVjdG9yKCQpe3RoaXMudXJsPSR9Y29ubmVjdGVkKCl7cmV0dXJuIHRoaXMud2Vic29ja2V0IT09dm9pZCAwJiZ0aGlzLndlYnNvY2tldC5yZWFkeVN0YXRlPT09V2ViU29ja2V0Lk9QRU59YXN5bmMgY29ubmVjdCgkLFosSj0oKT0+e30sUT0oKT0+e30pe2xldHt1cmw6WH09dGhpcztpZih0aGlzLndlYnNvY2tldCl0aGlzLndlYnNvY2tldC5jbG9zZSgpLHRoaXMud2Vic29ja2V0PXZvaWQgMDtsZXQgWT1uZXcgUztZLndyaXRlU3RydWN0KFYwLCQpO2xldCBWPVkucmVzdWx0KCksVz1SMChWKTtyZXR1cm4gWC5zZWFyY2hQYXJhbXMuc2V0KCJ0IixXKSx0aGlzLndlYnNvY2tldD1uZXcgV2ViU29ja2V0KFgpLHRoaXMud2Vic29ja2V0LmJpbmFyeVR5cGU9ImFycmF5YnVmZmVyIix0aGlzLndlYnNvY2tldC5vbm9wZW49KCk9Pntjb25zb2xlLmxvZygiQ09OTkVDVEVEIiksUSgpfSx0aGlzLndlYnNvY2tldC5vbmNsb3NlPSgpPT57Y29uc29sZS5sb2coIkRJU0NPTk5FQ1RFRCIpLHRoaXMud2Vic29ja2V0PXZvaWQgMCxKKCl9LHRoaXMud2Vic29ja2V0Lm9ubWVzc2FnZT0oeik9PntsZXQgSz1uZXcgVWludDhBcnJheSh6LmRhdGEpO1ooSyl9LHRoaXMud2Vic29ja2V0Lm9uZXJyb3I9KHopPT57Y29uc29sZS5sb2coYEVSUk9SOiAke0pTT04uc3RyaW5naWZ5KHopfWApLHRoaXMud2Vic29ja2V0PXZvaWQgMCxKKCl9LFByb21pc2UucmVzb2x2ZSgwKX1kaXNjb25uZWN0KCl7dGhpcy53ZWJzb2NrZXQ/LmNsb3NlKCksdGhpcy53ZWJzb2NrZXQ9dm9pZCAwfX12YXIgcj17dXNlcjp7cGF0aDoiL3VzZXIiLGVuZHBvaW50OkxKLG5hbWU6MH0scHVzaDp7cGF0aDoiL3B1c2giLGVuZHBvaW50Ol9KLG5hbWU6Mn0scGVlazp7cGF0aDoiL3BlZWsiLGVuZHBvaW50OkRKLG5hbWU6MX0scHVsbDp7cGF0aDoiL3B1bGwiLGVuZHBvaW50OkFKLG5hbWU6M319LE5YPXswOnIudXNlciwyOnIucHVzaCwxOnIucGVlaywzOnIucHVsbH0sSVc9e1tyLnVzZXIucGF0aF06ci51c2VyLFtyLnB1c2gucGF0aF06ci5wdXNoLFtyLnBlZWsucGF0aF06ci5wZWVrLFtyLnB1bGwucGF0aF06ci5wdWxsfTtjbGFzcyB4Snt1cmw7bGlzdGVuZXI7Y29uc3RydWN0b3IoJCl7dGhpcy51cmw9JDt0aGlzLmxpc3RlbmVyPW5ldyBSWigkKX1hc3luYyBjYWxsKCQsWil7bGV0e3BhdGg6Sn09TlhbJF0sUT1uZXcgVVJMKEosdGhpcy51cmwpO3RyeXtyZXR1cm4gYXdhaXQgUlgoUSxaKX1jYXRjaHtyZXR1cm4gRygyNSl9fX12YXIgQko9KCQpPT57cmV0dXJuIG5ldyB4SigkLmhhbmRsZSl9O2FzeW5jIGZ1bmN0aW9uIFJYKCQsWil7bGV0IEo9YXdhaXQgZmV0Y2goJCx7bWV0aG9kOiJQT1NUIixib2R5OloucmVzdWx0KCkuc2xpY2UoKX0pO2lmKCFKLm9rKXJldHVybiBHKDI0KTtsZXQgUT1hd2FpdCBtLmZyb21SZXNwb25zZShKKTtyZXR1cm4gUihRKX1jbGFzcyBMJHtlbmNsYXZlO2NyeXB0bztob3N0O2Nsb2NrO3RyYW5zcG9ydDt1cGRhdGVIb3N0TWV0YTtjb25zdHJ1Y3RvcigkLFosSixRLFgsWSl7dGhpcy5lbmNsYXZlPSQ7dGhpcy5jcnlwdG89Wjt0aGlzLmhvc3Q9Sjt0aGlzLmNsb2NrPVE7dGhpcy50cmFuc3BvcnQ9WDt0aGlzLnVwZGF0ZUhvc3RNZXRhPVl9YXN5bmMgY2FsbCgkLFope2xldHtjbG9jazpKLHRyYW5zcG9ydDpRfT10aGlzLHtlbmRwb2ludDpYLG5hbWU6WX09JCxWPWF3YWl0IHRoaXMuaWRlbnRpdHkoKSxXPUoubm93KCksW3osS109YXdhaXQgVlooVixXKTtpZihLIT09MClyZXR1cm4gRyhLKTtsZXQgRj1uZXcgUyxOPWF3YWl0IFguZW5jb2RlUmVxKHRoaXMsVix6LFosRik7aWYoTiE9PTApcmV0dXJuIEcoTik7bGV0IE89Si5ub3coKSxbVSxxXT1hd2FpdCBRLmNhbGwoWSxGKSxIPUoubm93KCk7aWYocSE9PTApcmV0dXJuIEcocSk7bGV0W00sUF09VS5yZWFkU3RydWN0KHpaKTtpZihQIT09MClyZXR1cm4gRyhQKTtpZihNLnN0YXR1cyE9PTApcmV0dXJuIEcoTS5zdGF0dXMpO2xldCBUPXtjbG9ja09mZnNldDpqSihPLE0udGltZVJjdmQsTS50aW1lU2VudCxIKSxzdWJzY3JpcHRpb246TS5zdWJzY3JpcHRpb259LEk9YXdhaXQgdGhpcy51cGRhdGVIb3N0TWV0YShUKTtpZihJIT09MClyZXR1cm4gRyhJKTtyZXR1cm4gWC5kZWNvZGVSZXNwKFUpfWlkZW50aXR5PSgpPT57bGV0e2hvc3Q6JCxlbmNsYXZlOlp9PXRoaXM7cmV0dXJuIFouZGVyaXZlSWRlbnRpdHkoJC5sYWJlbCwkLmlkeD8/MCl9O3NlYWw9YXN5bmMoJCk9PntsZXR7Y3J5cHRvOlosZW5jbGF2ZTpKfT10aGlzLFE9YXdhaXQgdGhpcy5pZGVudGl0eSgpO3JldHVybiBUSigkLFEsWixKKX07cmVnaXN0ZXI9KCk9PnRoaXMuY2FsbChyLnVzZXIsW10pO3BlZWs9KCQpPT50aGlzLmNhbGwoci5wZWVrLFskXSk7cHVzaD0oJCk9PnRoaXMuY2FsbChyLnB1c2gsJCk7cHVsbD0oJCk9PnRoaXMuY2FsbChyLnB1bGwsJCk7bGlzdGVuPWFzeW5jKCQsWixKKT0+e2xldHtjbG9jazpRLHRyYW5zcG9ydDpYfT10aGlzLHtsaXN0ZW5lcjpZfT1YLFY9YXdhaXQgdGhpcy5pZGVudGl0eSgpLFc9US5ub3coKSxbeixLXT1hd2FpdCBWWihWLFcpO2lmKEshPT0wKXJldHVybiBLO3JldHVybiBhd2FpdCBZLmNvbm5lY3QoeiwkLFosSil9O2lzQ29ubmVjdGVkKCl7bGV0ICQ9dGhpcy50cmFuc3BvcnQ/Lmxpc3RlbmVyO2lmKCQmJnR5cGVvZiAkLmNvbm5lY3RlZD09PSJmdW5jdGlvbiIpcmV0dXJuICQuY29ubmVjdGVkKCk7cmV0dXJuITB9Y2xvc2VMaXN0ZW5lcigpe3RoaXMudHJhbnNwb3J0Py5saXN0ZW5lcj8uZGlzY29ubmVjdCgpfX12YXIgT1o9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVWYXJTdHJpbmcoWi5sYmwpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJJbnQoWi5pZHgpO2lmKFEhPT0wKXJldHVybiBRO2xldCBYPSQud3JpdGVWYXJJbnQoWi5udW0pO2lmKFghPT0wKXJldHVybiBYO3JldHVybiAkLndyaXRlQnl0ZXMoWi5oc2gpLCQud3JpdGVCeXRlcyhaLnNpZyksMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZFZhclN0cmluZygpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtZLFZdPSQucmVhZFZhckludCgpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtXLHpdPSQucmVhZEJ5dGVzKE0kKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXRbSyxGXT0kLnJlYWRCeXRlcyhUMCk7aWYoRiE9PTApcmV0dXJuIEcoRik7cmV0dXJuIFIoe2xibDpaLGlkeDpRLG51bTpZLGhzaDpXLHNpZzpLfSl9fTt2YXIgVVo9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVTdHJ1Y3QoT1osWi5oZWFkKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFyQnl0ZXMoWi5pbmRleEVuYyk7aWYoUSE9PTApcmV0dXJuIFE7bGV0IFg9JC53cml0ZVZhckJ5dGVzKFouYm9keUVuYyk7aWYoWCE9PTApcmV0dXJuIFg7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRTdHJ1Y3QoT1opO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPSQucmVhZFZhckJ5dGVzKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0W1ksVl09JC5yZWFkVmFyQnl0ZXMoKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gUih7aGVhZDpaLGluZGV4RW5jOlEsYm9keUVuYzpZfSl9fTt2YXIgcVo9e2VuY29kZSgkLFopeyQud3JpdGVCeXRlcyhaLmtkbSk7bGV0IEo9JC53cml0ZVZhckJ5dGVzKFouaGVhZENwaCk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZVZhckludChaLmxlbkJvZHkpO2lmKFEhPT0wKXJldHVybiBRO2lmKFoubGVuQm9keT4wJiZaLm9mZkJvZHkhPT12b2lkIDApe2xldCBYPSQud3JpdGVWYXJJbnQoWi5vZmZCb2R5KTtpZihYIT09MClyZXR1cm4gWH1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZEJ5dGVzKGowKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxYXT0kLnJlYWRWYXJCeXRlcygpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtZLFZdPSQucmVhZFZhckludCgpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldCBXO2lmKFk+MCl7bGV0W3osS109JC5yZWFkVmFySW50KCk7aWYoSyE9PTApcmV0dXJuIEcoSyk7Vz16fXJldHVybiBSKHtrZG06WixoZWFkQ3BoOlEsbGVuQm9keTpZLG9mZkJvZHk6V30pfX07YXN5bmMgZnVuY3Rpb24ga0ooJCxaLEosUSxYKXtsZXQgWT1hd2FpdCBYLmRlcml2ZUlkZW50aXR5KCQsWiksVj1uZXcgUyxXPW5ldyBTLHo9MCxLPTA7Zm9yKGxldCBQIG9mIEope2xldCBDPW5ldyBTLFQ9Qy53cml0ZVN0cnVjdChXMCxQLmhlYWQpO2lmKFQhPT0wKXJldHVybiBHKFQpO2xldCBJPUMucmVzdWx0KCksQT1hd2FpdCBZLmtkbUZvcihJKSx4PVguZGVyaXZlQ2lwaGVyKEEsImVuY3J5cHQiKSxnPWF3YWl0IHguZW5jcnlwdChJKSxmPVAuYm9keT9hd2FpdCB4LmVuY3J5cHQoUC5ib2R5KTpuZXcgVWludDhBcnJheSgwKSxrPVAuaGVhZC5sZW4+MCYmUC5oZWFkLmhzaCE9PXZvaWQgMD9mLmxlbmd0aDowLGI9e2tkbTpBLGhlYWRDcGg6ZyxsZW5Cb2R5Omssb2ZmQm9keTprPjA/Szp2b2lkIDB9LHc9Vi53cml0ZVN0cnVjdChxWixiKTtpZih3IT09MClyZXR1cm4gRyh3KTtpZihQLmJvZHkpVy53cml0ZUJ5dGVzKGYpLEsrPWYubGVuZ3RoO3orK31sZXQgRj1XLnJlc3VsdCgpLE49Vi5yZXN1bHQoKSxPPWF3YWl0IFEuYmxha2UzKE4pLFU9YXdhaXQgWS5zaWduKE8pLHE9e2xibDokLGlkeDpaLG51bTp6LGhzaDpPLHNpZzpVfSxIPW5ldyBTO0gud3JpdGVTdHJ1Y3QoVVose2hlYWQ6cSxpbmRleEVuYzpOLGJvZHlFbmM6Rn0pO2xldCBNPUgucmVzdWx0KCk7cmV0dXJuIFIoTSl9YXN5bmMgZnVuY3Rpb24gRUooJCxaLEope2xldFtRLFhdPVVaLmRlY29kZShuZXcgbSgkKSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0e2hlYWQ6WSxpbmRleEVuYzpWLGJvZHlFbmM6V309USx6PWF3YWl0IEouZGVyaXZlSWRlbnRpdHkoWS5sYmwsWS5pZHgpO2lmKCFhd2FpdCBaLmNoZWNrU2lnRWQyNTUxOShZLnNpZyxZLmhzaCx6LnB1YmxpY0tleSkpcmV0dXJuIEcoMyk7bGV0IEY9YXdhaXQgWi5ibGFrZTMoVik7aWYoIWEoRixZLmhzaCkpcmV0dXJuIEcoMTkpO2xldCBOPW5ldyBtKFYpLE89W107Zm9yKGxldCBxPTA7cTxZLm51bTtxKyspe2xldFtILE1dPU4ucmVhZFN0cnVjdChxWik7aWYoTSE9PTApcmV0dXJuIEcoTSk7Ty5wdXNoKEgpfWlmKE8ubGVuZ3RoIT09WS5udW0pcmV0dXJuIEcoMTQpO2xldCBVPVtdO2ZvcihsZXQgcSBvZiBPKXtsZXQgSD1KLmRlcml2ZUNpcGhlcihxLmtkbSwiZGVjcnlwdCIpLE07dHJ5e009YXdhaXQgSC5kZWNyeXB0KHEuaGVhZENwaCl9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldFtQLENdPVcwLmRlY29kZShuZXcgbShNKSk7aWYoQyE9PTApcmV0dXJuIEcoQyk7bGV0IFQ7aWYocS5sZW5Cb2R5PjAmJnEub2ZmQm9keSE9PXZvaWQgMCl7aWYoUC5oc2g9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldCBJPVcuc2xpY2UocS5vZmZCb2R5LHEub2ZmQm9keStxLmxlbkJvZHkpO3RyeXtUPWF3YWl0IEguZGVjcnlwdChJKX1jYXRjaHtyZXR1cm4gRygyMCl9bGV0IEE9YXdhaXQgWi5ibGFrZTMoVCk7aWYoIWEoQSxQLmhzaCkpcmV0dXJuIEcoMTkpfVUucHVzaCh7aGVhZDpQLGJvZHk6VH0pfXJldHVybiBSKFUpfWFzeW5jIGZ1bmN0aW9uIGZKKHtub3c6JCxib2Q6WixjcnlwdG86Sn0pe2xldCBRPWF3YWl0IEouZ2VuUmFuZG9tQnl0ZXMoOCksWD1uZXcgUyxZPVgud3JpdGVTdHJ1Y3QoWTAse2lkOlEsdHM6JH0pO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBWPVgucmVzdWx0KCk7cmV0dXJuIHgkKHtub3c6JCxlaWQ6VixjdHI6MCxib2Q6WixjcnlwdG86Sn0pfWFzeW5jIGZ1bmN0aW9uIHgkKHtub3c6JCxlaWQ6WixjdHI6Sixib2Q6USxjcnlwdG86WH0pe2xldCBZPW5ldyBtKFopLFtWLFddPVkwLmRlY29kZShZKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXQgej0kLmdldFRpbWUoKS1WLnRzLmdldFRpbWUoKSxLLEY9UT8ubGVuZ3RoPz8wO2lmKFEmJkY+MClLPWF3YWl0IFguYmxha2UzKFEpO3JldHVybiBSKHtlaWQ6WixvZmY6eixjdHI6SixsZW46Rixoc2g6S30pfWZ1bmN0aW9uIE9YKCQsWil7bGV0IEo9JC5sZW5ndGg8Wi5sZW5ndGg/JC5sZW5ndGg6Wi5sZW5ndGg7Zm9yKGxldCBRPTA7UTxKO1ErKylpZigkW1FdIT09WltRXSlyZXR1cm4gJFtRXS1aW1FdO3JldHVybiAkLmxlbmd0aC1aLmxlbmd0aH1hc3luYyBmdW5jdGlvbiBLJCgkLFope2xldCBKPUFycmF5LmZyb20oJCk7Si5zb3J0KE9YKTtsZXQgUT0wO2ZvcihsZXQgViBvZiBKKVErPVYubGVuZ3RoO2xldCBYPW5ldyBVaW50OEFycmF5KFEpLFk9MDtmb3IobGV0IFYgb2YgSilYLnNldChWLFkpLFkrPVYubGVuZ3RoO3JldHVybiBaLmJsYWtlMyhYKX1mdW5jdGlvbiBVWCgkKXtsZXQgWj1uZXcgUyxKPVoud3JpdGVWYXJCeXRlcygkLmVpZCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0IFE9Wi53cml0ZURhdGUoJC51cGRhdGVkQXQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBYPVoud3JpdGVWYXJJbnQoJC5jdHIpO2lmKFghPT0wKXJldHVybiBHKFgpO3JldHVybiBSKFoucmVzdWx0KCkpfWFzeW5jIGZ1bmN0aW9uIEIkKCQsWil7bGV0IEo9W107Zm9yKGxldCBRIG9mICQpe2xldFtYLFldPVVYKFEpO2lmKFkhPT0wfHwhWClyZXR1cm4gRyhZKTtKLnB1c2goWCl9cmV0dXJuIFIoYXdhaXQgSyQoSixaKSl9dmFyIE5HPVN5bWJvbCgiTWFzdGVyU2VlZCIpLFJHPVN5bWJvbCgiU2VhbGVkTWFzdGVyS2V5IiksTzA9MzIsZ0o9MjQrTzArMTY7ZnVuY3Rpb24gZSgkKXtpZigkLmJ5dGVMZW5ndGghPT1PMClyZXR1cm4gRygxMCk7cmV0dXJuIFIoJCl9ZnVuY3Rpb24gQTAoJCl7aWYoJC5ieXRlTGVuZ3RoIT09Z0opcmV0dXJuIEcoMTApO3JldHVybiBSKCQpfXZhciBVRz1TeW1ib2woIkVudGl0eUlEIik7ZnVuY3Rpb24gbUooJCl7cmV0dXJuInR5cGUiaW4gJH12YXIgcUc9U3ltYm9sKCJEZXJpdmF0aW9uU2VlZCIpLEhHPVN5bWJvbCgiUHVibGljS2V5IiksTUc9U3ltYm9sKCJQcml2YXRlS2V5IiksSUc9U3ltYm9sKCJIb3N0U3BlY2lmaWNLZXlQYWlyIiksQ0c9U3ltYm9sKCJIYXNoIik7ZnVuY3Rpb24gcVgoJCl7aWYoISQpcmV0dXJuITE7aWYodHlwZW9mICQhPT0ib2JqZWN0IilyZXR1cm4hMTtpZigiYm9keSJpbiAkPT09ITEpcmV0dXJuITE7aWYoInR5cGUiaW4gJD09PSExKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIEhYKCQpe2lmKCEkLmJvZHx8JC5ib2QubGVuZ3RoPT09MCl7bGV0IFE9e29mZjokLm9mZixjdHI6JC5jdHIsZWlkOiQuZWlkfTtyZXR1cm4gUihRKX1sZXQgWj1ZWigkLmJvZCk7aWYocVgoWik9PT0hMSlyZXR1cm4gY29uc29sZS53YXJuKCJtc2cgYm9keSBpbnZhbGlkIixaKSxHKDE0KTtsZXQgSj17b2ZmOiQub2ZmLGN0cjokLmN0cixlaWQ6JC5laWQsZ2lkOlouZ2lkLHBpZDpaLnBpZCx0YWdzOloudGFncyx0eXBlOloudHlwZSxib2R5OlouYm9keX07cmV0dXJuIFIoSil9Y2xhc3MgayR7YXBwbGllcjtlbWl0dGVyPW5ldyBXJDtjbGVhcmVyO29uRGlydHlFaWRzO2NhY2hlRHJpdmVuO3BlZXJJbmdlc3Q7Y29uc3RydWN0b3IoJCxaLEosUSl7dGhpcy5hcHBsaWVyPSQ7dGhpcy5jbGVhcmVyPVosdGhpcy5vbkRpcnR5RWlkcz1KLHRoaXMuY2FjaGVEcml2ZW49UT8uY2FjaGVEcml2ZW4/PyExLHRoaXMucGVlckluZ2VzdD1RPy5wZWVySW5nZXN0fWFwcGx5PWFzeW5jKCQpPT57bGV0IFo9W10sSj1bXTtmb3IobGV0IFcgb2YgJCl7bGV0W3osS109SFgoVyk7aWYoSi5wdXNoKEspLEshPT0wKWNvbnRpbnVlO1oucHVzaCh6KX1sZXR7c3RhdHM6USx0eXBlczpYLGVpZHM6WX09YXdhaXQgdGhpcy5hcHBsaWVyKFopLFY9W107Zm9yKGxldCBXPTA7VzwkLmxlbmd0aDtXKyspe2xldCB6PUpbV10sSz1RW1ddO2lmKHohPT0wKXtWLnB1c2goeik7Y29udGludWV9aWYoSyE9PTApe1YucHVzaChLKTtjb250aW51ZX1WLnB1c2goMCl9aWYoIXRoaXMuY2FjaGVEcml2ZW4pZm9yKGxldCBXIG9mIFgpdGhpcy5lbWl0dGVyLmVtaXQoVyxudWxsKTtpZihZLmxlbmd0aD4wKXRoaXMub25EaXJ0eUVpZHM/LihZKTtyZXR1cm4gVn07Y2xlYXI9YXN5bmMoKT0+e2xldCAkPWF3YWl0IHRoaXMuY2xlYXJlcigpO2lmKCQhPT0wKXJldHVybiAkO3JldHVybiB0aGlzLmVtaXR0ZXIuZW1pdEFsbChudWxsKSwkfTtub3RpZnk9KCQpPT57Zm9yKGxldCBaIG9mICQpdGhpcy5lbWl0dGVyLmVtaXQoWixudWxsKX07cmVmcmVzaD1hc3luYygkKT0+e2lmKHRoaXMucGVlckluZ2VzdCl7YXdhaXQgdGhpcy5wZWVySW5nZXN0KCQpO3JldHVybn19O29uPSgkLFopPT57dGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoJCxaKX07b2ZmPSgkLFopPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJCxaKX19dmFyIGM9ImVudGl0aWVzIixFJD0iZW50aXR5X3R5cGVfY3JlYXRlZF9hdCIsTVo9ImVudGl0eV90eXBlX3VwZGF0ZWRfYXQiLElaPSJlbnRpdHlfdHlwZV9ncm91cF9pZCIsQ1o9ImVudGl0eV90eXBlX3BhcmVudF9pZCIsZDA9ImVudGl0eV90YWdzIixTSj0iZGIiLHZKPTEzO2Z1bmN0aW9uIE1YKCQpe3JldHVybiJ0eXAiaW4gJH1mdW5jdGlvbiBJWCgkKXtsZXQgWj17Ym9kOiQuYm9keSxjcmQ6JC5jcmVhdGVkQXQsLi4uJC5jdHIhPT0wP3tjdHI6JC5jdHJ9Ont9LGVpZDpCKCQuZWlkKSxnaWQ6JC5naWQscGlkOiQucGlkP0IoJC5waWQpOnZvaWQgMCx0Z3M6JC50YWdzLHR5cDokLnR5cGUsdXBkOiQudXBkYXRlZEF0fTtpZihaLmdpZD09PXZvaWQgMClkZWxldGUgWi5naWQ7aWYoWi5waWQ9PT12b2lkIDApZGVsZXRlIFoucGlkO2lmKFoudGdzPT09dm9pZCAwKWRlbGV0ZSBaLnRncztpZihaLmN0cj09PXZvaWQgMClkZWxldGUgWi5jdHI7cmV0dXJuIFp9ZnVuY3Rpb24gQ1goJCl7aWYoIWgoJCkpcmV0dXJue2VpZDpCKCQuZWlkKSx1cGQ6JC51cGRhdGVkQXQsLi4uJC5jdHIhPT0wP3tjdHI6JC5jdHJ9Ont9fTtyZXR1cm4gSVgoJCl9ZnVuY3Rpb24gcjAoJCl7cmV0dXJue2JvZHk6JC5ib2QsY3JlYXRlZEF0OiQuY3JkLHVwZGF0ZWRBdDokLnVwZCxjdHI6JC5jdHI/PzAsdHlwZTokLnR5cCxlaWQ6TjAoJC5laWQpLGdpZDokLmdpZCxwaWQ6JC5waWQ/TjAoJC5waWQpOnZvaWQgMCwuLi4kLnRncyE9PXZvaWQgMD97dGFnczokLnRnc306e319fWZ1bmN0aW9uIEhaKCQpe2lmKE1YKCQpKXJldHVybiByMCgkKTtyZXR1cm57ZWlkOk4wKCQuZWlkKSx1cGRhdGVkQXQ6JC51cGQsY3RyOiQuY3RyPz8wfX1jbGFzcyBiSntkYjtvcGVuaW5nO2FzeW5jIGluaXQoKXthd2FpdCB0aGlzLmVuc3VyZURiKCl9YXN5bmMgZW5zdXJlRGIoKXtpZih0aGlzLmRiKXJldHVybiB0aGlzLmRiO2lmKHRoaXMub3BlbmluZylyZXR1cm4gdGhpcy5vcGVuaW5nO3JldHVybiB0aGlzLm9wZW5pbmc9d1goKS50aGVuKCgkKT0+e3JldHVybiAkLm9udmVyc2lvbmNoYW5nZT0oKT0+e2lmKCQuY2xvc2UoKSx0aGlzLmRiPT09JCl0aGlzLmRiPXZvaWQgMH0sdGhpcy5kYj0kLHRoaXMub3BlbmluZz12b2lkIDAsJH0sKCQpPT57dGhyb3cgdGhpcy5vcGVuaW5nPXZvaWQgMCwkfSksdGhpcy5vcGVuaW5nfWFwcGx5PWFzeW5jKCQpPT57bGV0IFo9bmV3IFNldCxKPVtdLFE7dHJ5e1E9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybntzdGF0czokLm1hcCgoKT0+MTYpLHR5cGVzOlosZWlkczpKfX1sZXQgWD1RLnRyYW5zYWN0aW9uKGMsInJlYWR3cml0ZSIpLFk9WC5vYmplY3RTdG9yZShjKTtyZXR1cm4gbmV3IFByb21pc2UoKFYpPT57bGV0IFc9QXJyYXkoJC5sZW5ndGgpLmZpbGwoMCk7aWYoJC5sZW5ndGg8MSl7Vih7c3RhdHM6W10sdHlwZXM6WixlaWRzOkp9KTtyZXR1cm59WC5vbmNvbXBsZXRlPSgpPT57Vih7c3RhdHM6Vyx0eXBlczpaLGVpZHM6Sn0pfSxYLm9uZXJyb3I9KCk9Pntmb3IobGV0IEs9MDtLPFcubGVuZ3RoO0srKylpZihXW0tdPT09dm9pZCAwKVdbS109MTg7Vih7c3RhdHM6Vyx0eXBlczpaLGVpZHM6Sn0pfTtsZXQgej1uZXcgTWFwO2ZvcihsZXQgSz0wO0s8JC5sZW5ndGg7SysrKXtsZXQgRj0kW0tdLE49QihGLmVpZCksTz17b3A6RixpbmRleDpLfSxVPXouZ2V0KE4pO2lmKFUpVS5wdXNoKE8pO2Vsc2Ugei5zZXQoTixbT10pfWZvcihsZXRbSyxGXW9mIHope2lmKEYubGVuZ3RoPDEpY29udGludWU7bGV0IE49WS5nZXQoSyk7Ti5vbnN1Y2Nlc3M9KCk9PntsZXQgTz1OLnJlc3VsdCxVPU8/SFooTyk6dm9pZCAwLHE9ITE7Zm9yKGxldHtvcDpILGluZGV4Ok19b2YgRil7bGV0W1AsQ109bzAoVSxIKTtpZihDIT09MCl7V1tNXT1DO2NvbnRpbnVlfWlmKFA9PT12b2lkIDApe1dbTV09MTI7Y29udGludWV9cT0hMDtmb3IobGV0IFQgb2YgYTAoVSxQKSlaLmFkZChUKTtVPVB9aWYocSlKLnB1c2goRlswXS5vcC5laWQpO2lmKFUpe2xldCBIPVkucHV0KENYKFUpKTtILm9uZXJyb3I9KE0pPT57TS5wcmV2ZW50RGVmYXVsdCgpO2ZvcihsZXR7aW5kZXg6UH1vZiBGKVdbUF09MTh9fX0sTi5vbmVycm9yPSgpPT57Zm9yKGxldHtpbmRleDpPfW9mIEYpV1tPXT0xOH19fSl9O2FzeW5jIGNsZWFyKCl7bGV0ICQ7dHJ5eyQ9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiAxNn1sZXQgWj0kLnRyYW5zYWN0aW9uKGMsInJlYWR3cml0ZSIpLEo9Wi5vYmplY3RTdG9yZShjKTtyZXR1cm4gbmV3IFByb21pc2UoKFEpPT57Wi5vbmNvbXBsZXRlPSgpPT5RKDApLFoub25lcnJvcj0oKT0+USgxOCksSi5jbGVhcigpfSl9YXN5bmMgZ2V0Um93KCQpe2xldCBaO3RyeXtaPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IEo9QigkKSxYPVoudHJhbnNhY3Rpb24oYywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShjKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFY9WC5nZXQoSik7Vi5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1WLnJlc3VsdDtpZighVylZKFIodm9pZCAwKSk7ZWxzZSBZKFIoSFooVykpKX0sVi5vbmVycm9yPSgpPT5ZKEcoMTgpKX0pfWFzeW5jIGdldEVudCgkKXtsZXRbWixKXT1hd2FpdCB0aGlzLmdldFJvdygkKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwfHwhaChaKSlyZXR1cm4gUih2b2lkIDApO3JldHVybiBSKFopfWFzeW5jIGdldEFsbE9mVHlwZVVwZGF0ZWRCZXR3ZWVuKCQsWixKKXtsZXQgUTt0cnl7UT1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBZPVEudHJhbnNhY3Rpb24oYywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShjKS5pbmRleChNWik7cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBXPVkuZ2V0QWxsKElEQktleVJhbmdlLmJvdW5kKFskLFpdLFskLEpdKSk7Vy5vbnN1Y2Nlc3M9KCk9PntsZXQgej1XLnJlc3VsdDtWKFIoei5tYXAocjApKSl9LFcub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBnZXRHcm91cE1lbWJlcnMoJCxaKXtsZXQgSjt0cnl7Sj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBYPUoudHJhbnNhY3Rpb24oYywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShjKS5pbmRleChJWik7cmV0dXJuIG5ldyBQcm9taXNlKChZKT0+e2xldCBWPVguZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoWyQsWl0pKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVYucmVzdWx0O1koUihXLm1hcChyMCkpKX0sVi5vbmVycm9yPSgpPT5ZKEcoMTgpKX0pfWFzeW5jIGdldEFsbE9mVHlwZSgkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBRPVoudHJhbnNhY3Rpb24oYywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShjKS5pbmRleChFJCk7cmV0dXJuIG5ldyBQcm9taXNlKChYKT0+e2xldCBZPVEuZ2V0QWxsKElEQktleVJhbmdlLmJvdW5kKFskXSxbJCxbXV0pKTtZLm9uc3VjY2Vzcz0oKT0+e2xldCBWPVkucmVzdWx0O1goUihWLm1hcChyMCkpKX0sWS5vbmVycm9yPSgpPT5YKEcoMTgpKX0pfWFzeW5jIGdldEJ5VGFnKCQsWil7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgWD1KLnRyYW5zYWN0aW9uKGMsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoYykuaW5kZXgoZDApO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgVj1YLmdldEFsbChJREJLZXlSYW5nZS5vbmx5KFopKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCB6PVYucmVzdWx0LmZpbHRlcigoSyk9PksudHlwPT09JCkubWFwKHIwKTtZKFIoeikpfSxWLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9YXN5bmMgZ2V0QWxsRW50aXRpZXMoJCl7aWYoInBpZCJpbiAkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBKPUIoJC5waWQpLFg9Wi50cmFuc2FjdGlvbihjLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGMpLmluZGV4KENaKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFY9WC5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShbJC50eXBlLEpdKSk7Vi5vbnN1Y2Nlc3M9KCk9PntsZXQgej1WLnJlc3VsdC5tYXAocjApO1koUih6KSl9LFYub25lcnJvcj0oKT0+WShHKDE4KSl9KX1lbHNlIGlmKCJnaWQiaW4gJClyZXR1cm4gYXdhaXQgdGhpcy5nZXRHcm91cE1lbWJlcnMoJC50eXBlLCQuZ2lkKTtlbHNlIGlmKCJ0YWciaW4gJClyZXR1cm4gYXdhaXQgdGhpcy5nZXRCeVRhZygkLnR5cGUsJC50YWcpO2Vsc2UgaWYoInVwZGF0ZWRCZXR3ZWVuImluICQpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0QWxsT2ZUeXBlVXBkYXRlZEJldHdlZW4oJC50eXBlLCQudXBkYXRlZEJldHdlZW4uc3RhcnQsJC51cGRhdGVkQmV0d2Vlbi5lbmQpO3JldHVybiBhd2FpdCB0aGlzLmdldEFsbE9mVHlwZSgkLnR5cGUpfWFzeW5jIGdldEVudGl0aWVzKCQpe2xldFtaLEpdPWF3YWl0IHRoaXMuZ2V0QWxsRW50aXRpZXMoJCk7aWYoSiE9PTApcmV0dXJuIEcoSik7cmV0dXJuIFIoWil9YXN5bmMgY291bnRFbnRpdGllcyh7dHlwZTokfSl7bGV0IFo7dHJ5e1o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgUT1aLnRyYW5zYWN0aW9uKGMsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoYykuaW5kZXgoRSQpO3JldHVybiBuZXcgUHJvbWlzZSgoWCk9PntsZXQgWT1JREJLZXlSYW5nZS5ib3VuZChbJF0sWyQsW11dKSxWPVEuY291bnQoWSk7Vi5vbnN1Y2Nlc3M9KCk9PlgoUihWLnJlc3VsdCkpLFYub25lcnJvcj0oKT0+WChHKDE4KSl9KX1hc3luYyBjaGVja3N1bSgkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBRPVoudHJhbnNhY3Rpb24oYywicmVhZG9ubHkiKS5vYmplY3RTdG9yZShjKSxYPVtdO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgVj1RLm9wZW5DdXJzb3IoKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVYucmVzdWx0O2lmKFcpe2xldCB6PVcudmFsdWU7WC5wdXNoKGYkKEhaKHopKSksVy5jb250aW51ZSgpfWVsc2UgQiQoWCwkKS50aGVuKFkpfSxWLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9fWZ1bmN0aW9uIFBYKCQsWil7aWYoISQub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhjKSkkLmNyZWF0ZU9iamVjdFN0b3JlKGMse2tleVBhdGg6ImVpZCIsYXV0b0luY3JlbWVudDohMX0pO2xldCBKPVoub2JqZWN0U3RvcmUoYyk7aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhFJCkpSi5jcmVhdGVJbmRleChFJCxbInR5cCIsImNyZCJdLHt1bmlxdWU6ITF9KTtpZighSi5pbmRleE5hbWVzLmNvbnRhaW5zKE1aKSlKLmNyZWF0ZUluZGV4KE1aLFsidHlwIiwidXBkIl0se3VuaXF1ZTohMX0pO2lmKCFKLmluZGV4TmFtZXMuY29udGFpbnMoSVopKUouY3JlYXRlSW5kZXgoSVosWyJ0eXAiLCJnaWQiXSx7dW5pcXVlOiExfSk7aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhDWikpSi5jcmVhdGVJbmRleChDWixbInR5cCIsInBpZCJdLHt1bmlxdWU6ITF9KTtpZihKLmluZGV4TmFtZXMuY29udGFpbnMoZDApKXtpZihKLmluZGV4KGQwKS5rZXlQYXRoIT09InRncyIpSi5kZWxldGVJbmRleChkMCl9aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhkMCkpSi5jcmVhdGVJbmRleChkMCwidGdzIix7dW5pcXVlOiExLG11bHRpRW50cnk6ITB9KX1mdW5jdGlvbiB3WCgpe3JldHVybiBuZXcgUHJvbWlzZSgoJCxaKT0+e2xldCBKPWluZGV4ZWREQi5vcGVuKFNKLHZKKTtKLm9udXBncmFkZW5lZWRlZD0oKT0+e2xldHtyZXN1bHQ6USx0cmFuc2FjdGlvbjpYfT1KO2lmKCFYKXtaKEVycm9yKCJUcmFuc2FjdGlvbiBpcyBudWxsIGR1cmluZyBFbnREQiB1cGdyYWRlIikpO3JldHVybn10cnl7UFgoUSxYKX1jYXRjaChZKXtaKFkgaW5zdGFuY2VvZiBFcnJvcj9ZOkVycm9yKFN0cmluZyhZKSkpfX0sSi5vbmJsb2NrZWQ9KCk9Pntjb25zb2xlLndhcm4oYFtESVBMT01BVElDXSBFbnREQiBJREIgdXBncmFkZSBibG9ja2VkICgke1NKfSDihpIgdiR7dkp9KTsgd2FpdGluZyBmb3Igb3RoZXIgY29ubmVjdGlvbnMgdG8gY2xvc2VgKX0sSi5vbnN1Y2Nlc3M9KCk9PiQoSi5yZXN1bHQpLEoub25lcnJvcj0oKT0+WihKLmVycm9yPz9FcnJvcigiRW50REIgSW5kZXhlZERCIG9wZW4gZmFpbGVkIikpfSl9YXN5bmMgZnVuY3Rpb24geUooKXtsZXQgJD1uZXcgYko7cmV0dXJuIGF3YWl0ICQuaW5pdCgpLCR9Y2xhc3MgUFp7ZW50cz1uZXcgTWFwO3VzZUluZGV4O2J5VHlwZT1uZXcgTWFwO2J5VHlwZVBpZD1uZXcgTWFwO2J5VHlwZUdpZD1uZXcgTWFwO2J5VHlwZVRhZz1uZXcgTWFwO2NvbnN0cnVjdG9yKCQ9W10sWil7dGhpcy51c2VJbmRleD1aPy5pbmRleGVzIT09ITE7Zm9yKGxldCBKIG9mICQpdGhpcy5wdXQoSil9cHV0KCQpe2xldCBaPUIoJC5laWQpLEo9dGhpcy5lbnRzLmdldChaKTtpZihKIT09dm9pZCAwJiZoKEopKXRoaXMudW5pbmRleChaLEopO2lmKHRoaXMuZW50cy5zZXQoWiwkKSxoKCQpKXRoaXMuaW5kZXgoWiwkKX1kZWwoJCl7bGV0IFo9dGhpcy5lbnRzLmdldCgkKTtpZihaPT09dm9pZCAwKXJldHVybjtpZihoKFopKXRoaXMudW5pbmRleCgkLFopO3RoaXMuZW50cy5kZWxldGUoJCl9aW5kZXgoJCxaKXtpZighdGhpcy51c2VJbmRleClyZXR1cm47bGV0IEo9dGhpcy5ieVR5cGUuZ2V0KFoudHlwZSk7aWYoIUopSj1uZXcgTWFwLHRoaXMuYnlUeXBlLnNldChaLnR5cGUsSik7aWYoSi5zZXQoJCxaKSxaLnBpZCl7bGV0IFE9QihaLnBpZCksWD10aGlzLmJ5VHlwZVBpZC5nZXQoWi50eXBlKTtpZighWClYPW5ldyBNYXAsdGhpcy5ieVR5cGVQaWQuc2V0KFoudHlwZSxYKTtsZXQgWT1YLmdldChRKTtpZighWSlZPW5ldyBNYXAsWC5zZXQoUSxZKTtZLnNldCgkLFopfWlmKHR5cGVvZiBaLmdpZD09PSJzdHJpbmciKXtsZXQgUT10aGlzLmJ5VHlwZUdpZC5nZXQoWi50eXBlKTtpZighUSlRPW5ldyBNYXAsdGhpcy5ieVR5cGVHaWQuc2V0KFoudHlwZSxRKTtsZXQgWD1RLmdldChaLmdpZCk7aWYoIVgpWD1uZXcgTWFwLFEuc2V0KFouZ2lkLFgpO1guc2V0KCQsWil9aWYoWi50YWdzKXtsZXQgUT10aGlzLmJ5VHlwZVRhZy5nZXQoWi50eXBlKTtpZighUSlRPW5ldyBNYXAsdGhpcy5ieVR5cGVUYWcuc2V0KFoudHlwZSxRKTtmb3IobGV0IFggb2YgWi50YWdzKXtsZXQgWT1RLmdldChYKTtpZighWSlZPW5ldyBNYXAsUS5zZXQoWCxZKTtZLnNldCgkLFopfX19dW5pbmRleCgkLFope2lmKCF0aGlzLnVzZUluZGV4KXJldHVybjtsZXQgSj10aGlzLmJ5VHlwZS5nZXQoWi50eXBlKTtpZihKKXtpZihKLmRlbGV0ZSgkKSxKLnNpemU9PT0wKXRoaXMuYnlUeXBlLmRlbGV0ZShaLnR5cGUpfWlmKFoucGlkKXtsZXQgUT1CKFoucGlkKSxYPXRoaXMuYnlUeXBlUGlkLmdldChaLnR5cGUpLFk9WD8uZ2V0KFEpO2lmKFkpe2lmKFkuZGVsZXRlKCQpLFkuc2l6ZT09PTApWD8uZGVsZXRlKFEpfWlmKFgmJlguc2l6ZT09PTApdGhpcy5ieVR5cGVQaWQuZGVsZXRlKFoudHlwZSl9aWYodHlwZW9mIFouZ2lkPT09InN0cmluZyIpe2xldCBRPXRoaXMuYnlUeXBlR2lkLmdldChaLnR5cGUpLFg9UT8uZ2V0KFouZ2lkKTtpZihYKXtpZihYLmRlbGV0ZSgkKSxYLnNpemU9PT0wKVE/LmRlbGV0ZShaLmdpZCl9aWYoUSYmUS5zaXplPT09MCl0aGlzLmJ5VHlwZUdpZC5kZWxldGUoWi50eXBlKX1pZihaLnRhZ3Mpe2xldCBRPXRoaXMuYnlUeXBlVGFnLmdldChaLnR5cGUpO2lmKFEpe2ZvcihsZXQgWCBvZiBaLnRhZ3Mpe2xldCBZPVEuZ2V0KFgpO2lmKFkpe2lmKFkuZGVsZXRlKCQpLFkuc2l6ZT09PTApUS5kZWxldGUoWCl9fWlmKFEuc2l6ZT09PTApdGhpcy5ieVR5cGVUYWcuZGVsZXRlKFoudHlwZSl9fX1jbGVhckluZGV4ZXMoKXt0aGlzLmJ5VHlwZS5jbGVhcigpLHRoaXMuYnlUeXBlUGlkLmNsZWFyKCksdGhpcy5ieVR5cGVHaWQuY2xlYXIoKSx0aGlzLmJ5VHlwZVRhZy5jbGVhcigpfWJ1Y2tldExpc3QoJCl7aWYoISR8fCQuc2l6ZT09PTApcmV0dXJuW107bGV0IFo9W107Zm9yKGxldCBKIG9mICQudmFsdWVzKCkpWi5wdXNoKEopO3JldHVybiBafWFzeW5jIGFwcGx5KCQpe2xldCBaPW5ldyBTZXQsSj1bXSxRPVtdO2ZvcihsZXQgWCBvZiAkKXtsZXQgWT1CKFguZWlkKSxWPXRoaXMuZW50cy5nZXQoWSksW1csel09bzAoVixYKTtpZih6IT09MCl7US5wdXNoKHopO2NvbnRpbnVlfWlmKFc9PT12b2lkIDApe1EucHVzaCgxMik7Y29udGludWV9Zm9yKGxldCBLIG9mIGEwKFYsVykpWi5hZGQoSyk7dGhpcy5wdXQoVyksSi5wdXNoKFguZWlkKSxRLnB1c2goMCl9cmV0dXJue3N0YXRzOlEsdHlwZXM6WixlaWRzOkp9fWFzeW5jIGNsZWFyKCl7cmV0dXJuIHRoaXMuZW50cy5jbGVhcigpLHRoaXMuY2xlYXJJbmRleGVzKCksMH1hc3luYyBnZXRSb3coJCl7bGV0IFo9QigkKSxKPXRoaXMuZW50cy5nZXQoWik7cmV0dXJuIFIoSil9YXN5bmMgZ2V0RW50KCQpe2xldFtaLEpdPWF3YWl0IHRoaXMuZ2V0Um93KCQpO2lmKEohPT0wKXJldHVybiBHKEopO2lmKFo9PT12b2lkIDB8fCFoKFopKXJldHVybiBSKHZvaWQgMCk7cmV0dXJuIFIoWil9YXN5bmMgZ2V0QWxsRW50aXRpZXMoe3R5cGU6JCxnaWQ6WixwaWQ6Six0YWc6USx1cGRhdGVkQmV0d2VlbjpYfSl7aWYodGhpcy51c2VJbmRleCl7aWYoSiE9PXZvaWQgMCl7bGV0IFY9QihKKTtyZXR1cm4gUih0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGVQaWQuZ2V0KCQpPy5nZXQoVikpKX1pZihaIT09dm9pZCAwKXJldHVybiBSKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZUdpZC5nZXQoJCk/LmdldChaKSkpO2lmKFEhPT12b2lkIDApcmV0dXJuIFIodGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlVGFnLmdldCgkKT8uZ2V0KFEpKSk7aWYoWCE9PXZvaWQgMCl7bGV0IFY9W10sVz10aGlzLmJ5VHlwZS5nZXQoJCk7aWYoVyl7Zm9yKGxldCB6IG9mIFcudmFsdWVzKCkpaWYoei51cGRhdGVkQXQ+PVguc3RhcnQmJnoudXBkYXRlZEF0PD1YLmVuZClWLnB1c2goeil9cmV0dXJuIFIoVil9cmV0dXJuIFIodGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlLmdldCgkKSkpfWxldCBZPVtdO2lmKEohPT12b2lkIDApe2ZvcihsZXQgViBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaChWKSYmVi50eXBlPT09JCYmVi5waWQmJmEoVi5waWQsSikpWS5wdXNoKFYpfWVsc2UgaWYoWiE9PXZvaWQgMCl7Zm9yKGxldCBWIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihoKFYpJiZWLnR5cGU9PT0kJiYodHlwZW9mIFYuZ2lkPT09InN0cmluZyImJlYuZ2lkPT09WikpWS5wdXNoKFYpfWVsc2UgaWYoUSE9PXZvaWQgMCl7Zm9yKGxldCBWIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihoKFYpJiZWLnR5cGU9PT0kJiZWLnRhZ3MmJlYudGFncy5pbmNsdWRlcyhRKSlZLnB1c2goVil9ZWxzZSBpZihYIT09dm9pZCAwKXtmb3IobGV0IFYgb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGgoVikmJlYudHlwZT09PSQmJlYudXBkYXRlZEF0Pj1YLnN0YXJ0JiZWLnVwZGF0ZWRBdDw9WC5lbmQpWS5wdXNoKFYpfWVsc2UgZm9yKGxldCBWIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihoKFYpJiZWLnR5cGU9PT0kKVkucHVzaChWKTtyZXR1cm4gUihZKX1hc3luYyBnZXRFbnRpdGllcygkKXtsZXRbWixKXT1hd2FpdCB0aGlzLmdldEFsbEVudGl0aWVzKCQpO2lmKEohPT0wKXJldHVybiBHKEopO3JldHVybiBSKFopfWFzeW5jIGNvdW50RW50aXRpZXMoe3R5cGU6JH0pe2lmKHRoaXMudXNlSW5kZXgpcmV0dXJuIFIodGhpcy5ieVR5cGUuZ2V0KCQpPy5zaXplPz8wKTtsZXQgWj0wO2ZvcihsZXQgSiBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaChKKSYmSi50eXBlPT09JClaKz0xO3JldHVybiBSKFopfWFzeW5jIGNoZWNrc3VtKCQpe2xldCBaPVtdO2ZvcihsZXQgSiBvZiB0aGlzLmVudHMudmFsdWVzKCkpWi5wdXNoKGYkKEopKTtyZXR1cm4gQiQoWiwkKX19YXN5bmMgZnVuY3Rpb24gaEooJCl7bGV0IFo9YXdhaXQgeUooKTtpZigkPy5jYWNoZT09PSExKXJldHVybiBaO3JldHVybiBuZXcgd1ooWix2b2lkIDAse2luZGV4ZXM6JD8uaW5kZXhlc30pfWNsYXNzIHdae21lbTtkdXJhYmxlO3dhcm1lZD1uZXcgU2V0O2xpc3RlbmVycz1uZXcgU2V0O2NoYWluPVByb21pc2UucmVzb2x2ZSgpO2NvbnN0cnVjdG9yKCQsWixKKXtpZih0aGlzLmR1cmFibGU9JCx0aGlzLm1lbT1uZXcgUFooWj8/W10se2luZGV4ZXM6Sj8uaW5kZXhlc30pLFopZm9yKGxldCBRIG9mIFopdGhpcy53YXJtZWQuYWRkKFEudHlwZSl9c3Vic2NyaWJlKCQpe3JldHVybiB0aGlzLmxpc3RlbmVycy5hZGQoJCksKCk9Pnt0aGlzLmxpc3RlbmVycy5kZWxldGUoJCl9fWVtaXQoJCl7aWYoJC5zaXplPDEpcmV0dXJuO2ZvcihsZXQgWiBvZiB0aGlzLmxpc3RlbmVycylaKCQpfXJ1bigkKXtsZXQgWj10aGlzLmNoYWluLnRoZW4oJCwkKTtyZXR1cm4gdGhpcy5jaGFpbj1aLnRoZW4oKCk9PntyZXR1cm59LCgpPT57cmV0dXJufSksWn1hcHBseSgkKXtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2F3YWl0IHRoaXMucHVsbEVpZHMoJC5tYXAoKFkpPT5ZLmVpZCkpO2xldCBaPUxYKHRoaXMubWVtLCQpO3RoaXMuZW1pdChaLnR5cGVzKTtsZXQgSj1hd2FpdCB0aGlzLmR1cmFibGUuYXBwbHkoJCkse2NoYW5nZWQ6USxzdGF0dXM6WH09YXdhaXQgdGhpcy5wdWxsRWlkcygkLm1hcCgoWSk9PlkuZWlkKSk7aWYodGhpcy5lbWl0KFEpLFghPT0wKXJldHVybntzdGF0czokLm1hcCgoKT0+WCksdHlwZXM6Si50eXBlcyxlaWRzOkouZWlkc307cmV0dXJuIEp9KX1jbGVhcigpe3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57bGV0ICQ9YXdhaXQgdGhpcy5kdXJhYmxlLmNsZWFyKCk7aWYoJCE9PTApcmV0dXJuICQ7bGV0IFo9dGhpcy5tZW0uZW50cy5zaXplPjA7cmV0dXJuIGF3YWl0IHRoaXMubWVtLmNsZWFyKCksdGhpcy53YXJtZWQuY2xlYXIoKSwwfSl9aW5nZXN0RnJvbUR1cmFibGUoJCl7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9PntsZXR7Y2hhbmdlZDpaLHN0YXR1czpKfT1hd2FpdCB0aGlzLnB1bGxFaWRzKCQpO3JldHVybiB0aGlzLmVtaXQoWiksSn0pfWFzeW5jIHB1bGxFaWRzKCQpe2xldCBaPW5ldyBTZXQsSj1uZXcgU2V0O2ZvcihsZXQgUSBvZiAkKXtsZXQgWD1CKFEpO2lmKEouaGFzKFgpKWNvbnRpbnVlO0ouYWRkKFgpO2xldCBZPXRoaXMubWVtLmVudHMuZ2V0KFgpLFtWLFddPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRSb3coUSk7aWYoVyE9PTApcmV0dXJue2NoYW5nZWQ6WixzdGF0dXM6V307aWYoVil7aWYodGhpcy5tZW0ucHV0KFYpLCFZfHwhVFgoWSxWKSl7aWYoaChWKSlaLmFkZChWLnR5cGUpO2lmKFkhPT12b2lkIDAmJmgoWSkpWi5hZGQoWS50eXBlKX19ZWxzZSBpZihZIT09dm9pZCAwKXtpZih0aGlzLm1lbS5kZWwoWCksaChZKSlaLmFkZChZLnR5cGUpfX1yZXR1cm57Y2hhbmdlZDpaLHN0YXR1czowfX1hc3luYyB3YXJtVHlwZSgkKXtpZih0aGlzLndhcm1lZC5oYXMoJCkpcmV0dXJuIDA7bGV0W1osSl09YXdhaXQgdGhpcy5kdXJhYmxlLmdldEVudGl0aWVzKHt0eXBlOiR9KTtpZihKIT09MClyZXR1cm4gSjtpZihaKWZvcihsZXQgUSBvZiBaKXtsZXQgWD1CKFEuZWlkKSxZPXRoaXMubWVtLmVudHMuZ2V0KFgpO2lmKCFZfHxfWChRLFkpKXRoaXMubWVtLnB1dChRKX1yZXR1cm4gdGhpcy53YXJtZWQuYWRkKCQpLDB9YXN5bmMgZ2V0Um93KCQpe2xldCBaPUIoJCk7aWYodGhpcy5tZW0uZW50cy5oYXMoWikpcmV0dXJuIHRoaXMubWVtLmdldFJvdygkKTtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2lmKHRoaXMubWVtLmVudHMuaGFzKFopKXJldHVybiB0aGlzLm1lbS5nZXRSb3coJCk7bGV0W0osUV09YXdhaXQgdGhpcy5kdXJhYmxlLmdldFJvdygkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKKXRoaXMubWVtLnB1dChKKTtyZXR1cm4gUihKKX0pfWFzeW5jIGdldEVudCgkKXtsZXRbWixKXT1hd2FpdCB0aGlzLmdldFJvdygkKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwfHwhaChaKSlyZXR1cm4gUih2b2lkIDApO3JldHVybiBSKFopfWFzeW5jIGdldEVudGl0aWVzKCQpe2lmKCF0aGlzLndhcm1lZC5oYXMoJC50eXBlKSl7bGV0IFo9YXdhaXQgdGhpcy5ydW4oKCk9PnRoaXMud2FybVR5cGUoJC50eXBlKSk7aWYoWiE9PTApcmV0dXJuIEcoWil9cmV0dXJuIHRoaXMubWVtLmdldEVudGl0aWVzKCQpfWFzeW5jIGNvdW50RW50aXRpZXMoe3R5cGU6JH0pe2lmKCF0aGlzLndhcm1lZC5oYXMoJCkpe2xldCBaPWF3YWl0IHRoaXMucnVuKCgpPT50aGlzLndhcm1UeXBlKCQpKTtpZihaIT09MClyZXR1cm4gRyhaKX1yZXR1cm4gdGhpcy5tZW0uY291bnRFbnRpdGllcyh7dHlwZTokfSl9YXN5bmMgY2hlY2tzdW0oJCl7cmV0dXJuIHRoaXMuZHVyYWJsZS5jaGVja3N1bSgkKX19ZnVuY3Rpb24gVFgoJCxaKXtpZihoKCQpIT09aChaKSlyZXR1cm4hMTtpZigkLmN0ciE9PVouY3RyKXJldHVybiExO2lmKCQudXBkYXRlZEF0LmdldFRpbWUoKSE9PVoudXBkYXRlZEF0LmdldFRpbWUoKSlyZXR1cm4hMTtpZighYSgkLmVpZCxaLmVpZCkpcmV0dXJuITE7aWYoIWgoJCl8fCFoKFopKXJldHVybiEwO2lmKCQuY3JlYXRlZEF0LmdldFRpbWUoKSE9PVouY3JlYXRlZEF0LmdldFRpbWUoKSlyZXR1cm4hMTtpZigkLnR5cGUhPT1aLnR5cGUpcmV0dXJuITE7aWYoJC5naWQhPT1aLmdpZClyZXR1cm4hMTtpZighRFgoJC5waWQsWi5waWQpKXJldHVybiExO2lmKCFqWCgkLnRhZ3MsWi50YWdzKSlyZXR1cm4hMTtyZXR1cm4gQVgoJC5ib2R5LFouYm9keSl9ZnVuY3Rpb24galgoJCxaKXtpZigkPT09WilyZXR1cm4hMDtpZigkPT09dm9pZCAwfHxaPT09dm9pZCAwKXJldHVybiExO2lmKCQubGVuZ3RoIT09Wi5sZW5ndGgpcmV0dXJuITE7Zm9yKGxldCBKPTA7SjwkLmxlbmd0aDtKKyspaWYoJFtKXSE9PVpbSl0pcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24gRFgoJCxaKXtpZigkPT09dm9pZCAwJiZaPT09dm9pZCAwKXJldHVybiEwO2lmKCQ9PT12b2lkIDB8fFo9PT12b2lkIDApcmV0dXJuITE7cmV0dXJuIGEoJCxaKX1mdW5jdGlvbiBBWCgkLFope2lmKE9iamVjdC5pcygkLFopKXJldHVybiEwO2lmKCQgaW5zdGFuY2VvZiBVaW50OEFycmF5JiZaIGluc3RhbmNlb2YgVWludDhBcnJheSlyZXR1cm4gYSgkLFopO2lmKCQgaW5zdGFuY2VvZiBEYXRlJiZaIGluc3RhbmNlb2YgRGF0ZSlyZXR1cm4gJC5nZXRUaW1lKCk9PT1aLmdldFRpbWUoKTt0cnl7cmV0dXJuIGEoTDAoJCksTDAoWikpfWNhdGNoe3JldHVybiExfX1mdW5jdGlvbiBfWCgkLFope2xldCBKPSQudXBkYXRlZEF0LmdldFRpbWUoKSxRPVoudXBkYXRlZEF0LmdldFRpbWUoKTtpZihKIT09USlyZXR1cm4gSj5RO3JldHVybiAkLmN0cj5aLmN0cn1mdW5jdGlvbiBMWCgkLFope2xldCBKPW5ldyBTZXQsUT1bXTtmb3IobGV0IFggb2YgWil7bGV0IFk9QihYLmVpZCksVj0kLmVudHMuZ2V0KFkpLFtXLHpdPW8wKFYsWCk7aWYoeiE9PTApe1EucHVzaCh6KTtjb250aW51ZX1pZihXPT09dm9pZCAwKXtRLnB1c2goMTIpO2NvbnRpbnVlfWZvcihsZXQgSyBvZiBhMChWLFcpKUouYWRkKEspOyQucHV0KFcpLFEucHVzaCgwKX1yZXR1cm57c3RhdHM6USx0eXBlczpKfX1mdW5jdGlvbiBoKCQpe3JldHVybiJ0eXBlImluICR9ZnVuY3Rpb24geFgoJCl7aWYoIUFycmF5LmlzQXJyYXkoJCl8fCQubGVuZ3RoPT09MClyZXR1cm47bGV0IFo9bmV3IFNldCxKPVtdO2ZvcihsZXQgUSBvZiAkKXtpZih0eXBlb2YgUSE9PSJzdHJpbmcifHxRLmxlbmd0aD09PTApY29udGludWU7aWYoWi5oYXMoUSkpY29udGludWU7Wi5hZGQoUSksSi5wdXNoKFEpfXJldHVybiBKLmxlbmd0aD4wP0o6dm9pZCAwfWZ1bmN0aW9uIGYkKCQpe3JldHVybntlaWQ6JC5laWQsY3RyOiQuY3RyLHVwZGF0ZWRBdDokLnVwZGF0ZWRBdH19ZnVuY3Rpb24gaUooJCl7bGV0IFo9bmV3IG0oJC5laWQpLFtKLFFdPVoucmVhZFN0cnVjdChZMCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7cmV0dXJuIFIoe2VpZDokLmVpZCxjdHI6JC5jdHIsdXBkYXRlZEF0Om5ldyBEYXRlKEoudHMuZ2V0VGltZSgpKyQub2ZmKX0pfWZ1bmN0aW9uIG8wKCQsWil7bGV0IEo9bmV3IG0oWi5laWQpLFtRLFhdPUoucmVhZFN0cnVjdChZMCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFk9bmV3IERhdGUoUS50cy5nZXRUaW1lKCkrWi5vZmYpO2lmKCQhPT12b2lkIDAmJlk8PSQudXBkYXRlZEF0KXJldHVybiBHKDE1KTtpZihtSihaKSl7bGV0IFY9eFgoWi50YWdzKTtyZXR1cm4gUih7ZWlkOlouZWlkLGdpZDpaLmdpZCxwaWQ6Wi5waWQsLi4uViE9PXZvaWQgMD97dGFnczpWfTp7fSx0eXBlOloudHlwZSxjcmVhdGVkQXQ6US50cyx1cGRhdGVkQXQ6WSxjdHI6Wi5jdHIsYm9keTpaLmJvZHl9KX1yZXR1cm4gUih7ZWlkOlouZWlkLHVwZGF0ZWRBdDpZLGN0cjpaLmN0cn0pfWZ1bmN0aW9uIGEwKCQsWil7bGV0IEo9bmV3IFNldDtpZigkIT09dm9pZCAwJiZoKCQpKUouYWRkKCQudHlwZSk7aWYoaChaKSlKLmFkZChaLnR5cGUpO3JldHVyblsuLi5KXX1jbGFzcyBnJHtpbmZsaWdodD1udWxsO2FnYWluPSExO3J1bigkKXtpZih0aGlzLmFnYWluPSEwLHRoaXMuaW5mbGlnaHQpcmV0dXJuIHRoaXMuaW5mbGlnaHQ7cmV0dXJuIHRoaXMuaW5mbGlnaHQ9dGhpcy5kcmFpbigkKSx0aGlzLmluZmxpZ2h0fWFzeW5jIGZsdXNoKCl7aWYoIXRoaXMuaW5mbGlnaHQpcmV0dXJuO3RyeXthd2FpdCB0aGlzLmluZmxpZ2h0fWNhdGNoe319YXN5bmMgZHJhaW4oJCl7dHJ5e3RoaXMuYWdhaW49ITE7bGV0IFo9YXdhaXQgJCgpO3doaWxlKHRoaXMuYWdhaW4pdGhpcy5hZ2Fpbj0hMSxaPWF3YWl0ICQoKTtyZXR1cm4gWn1maW5hbGx5e3RoaXMuaW5mbGlnaHQ9bnVsbH19fXZhciBsSj0xMDA7Y2xhc3MgVFp7dGltZXI9bnVsbDtkZWxheU1zO3dvcms7dGFpbD1uZXcgZyQ7Y29uc3RydWN0b3IoJCxaKXt0aGlzLmRlbGF5TXM9JDwwPzA6JCx0aGlzLndvcms9Wn1zY2hlZHVsZSgpe2lmKHRoaXMuZGVsYXlNczw9MCl7dGhpcy5maXJlKCk7cmV0dXJufWlmKHRoaXMudGltZXIhPT1udWxsKWNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTt0aGlzLnRpbWVyPXNldFRpbWVvdXQoKCk9Pnt0aGlzLnRpbWVyPW51bGwsdGhpcy5maXJlKCl9LHRoaXMuZGVsYXlNcyl9YXN5bmMgZmx1c2goKXtpZih0aGlzLnRpbWVyIT09bnVsbCljbGVhclRpbWVvdXQodGhpcy50aW1lciksdGhpcy50aW1lcj1udWxsLHRoaXMuZmlyZSgpO2F3YWl0IHRoaXMudGFpbC5mbHVzaCgpfWNhbmNlbCgpe2lmKHRoaXMudGltZXIhPT1udWxsKWNsZWFyVGltZW91dCh0aGlzLnRpbWVyKSx0aGlzLnRpbWVyPW51bGx9ZmlyZSgpe3JldHVybiB0aGlzLnRhaWwucnVuKHRoaXMud29yayl9fWZ1bmN0aW9uIHVKKCQpe2xldCBaPW5ldyBtKCQuZWlkKSxbSixRXT1ZMC5kZWNvZGUoWik7aWYoUSE9PTApcmV0dXJuO3JldHVybiBKLnRzLmdldFRpbWUoKSskLm9mZn1mdW5jdGlvbiBCWCgkLFope2xldCBKPXVKKCQpLFE9dUooWik7aWYoSj09PXZvaWQgMCYmUT09PXZvaWQgMClyZXR1cm4gMDtpZihKPT09dm9pZCAwKXJldHVybiAxO2lmKFE9PT12b2lkIDApcmV0dXJuLTE7aWYoUSE9PUopcmV0dXJuIFEtSjtyZXR1cm4gWi5jdHItJC5jdHJ9ZnVuY3Rpb24gczAoJCxaKXtyZXR1cm4gJC5zbGljZSgpLnNvcnQoKEosUSk9PkJYKFooSiksWihRKSkpfXZhciBqWj17cGhhc2U6ImlkbGUifSxGJD01MDtmdW5jdGlvbiBEWigkLFosSil7aWYoJDw9MHx8Wjw9MClyZXR1cm4hMTtpZigkPT09MXx8JD09PVopcmV0dXJuITA7cmV0dXJuICQlSj09PTB9ZnVuY3Rpb24gcEooJCxaKXtpZih0eXBlb2YgbmF2aWdhdG9yLm1zU2F2ZU9yT3BlbkJsb2I9PT0iZnVuY3Rpb24iKXtuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYigkLFopO3JldHVybn1sZXQgSj1VUkwuY3JlYXRlT2JqZWN0VVJMKCQpLFE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgiYSIpO1EuaHJlZj1KLFEuZG93bmxvYWQ9Wixkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKFEpLFEuY2xpY2soKSxkb2N1bWVudC5ib2R5LnJlbW92ZUNoaWxkKFEpLFVSTC5yZXZva2VPYmplY3RVUkwoSil9ZnVuY3Rpb24gY0ooJCxaLEope2xldCBRPVtdLFg9W10sWT0wO2ZvcihsZXQgViBvZiAkKXtsZXQgVz1aKFYpO2lmKFgubGVuZ3RoPjAmJlkrVz5KKVEucHVzaChYKSxYPVtdLFk9MDtpZihYLnB1c2goViksWSs9VyxZPj1KKVEucHVzaChYKSxYPVtdLFk9MH1pZihYLmxlbmd0aD4wKVEucHVzaChYKTtyZXR1cm4gUX1hc3luYyBmdW5jdGlvbiBBWigkLFosSil7bGV0IFE9JC5sZW5ndGg7aWYoUTwxKXJldHVybltdO2xldCBYPUFycmF5KFEpLFk9MCxWPU1hdGgubWluKE1hdGgubWF4KDEsWiksUSksVz1hc3luYygpPT57d2hpbGUoITApe2xldCBLPVk7aWYoWSs9MSxLPj1RKXJldHVybjtYW0tdPWF3YWl0IEooJFtLXSxLKX19LHo9W107Zm9yKGxldCBLPTA7SzxWO0srKyl6LnB1c2goVygpKTtyZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwoeiksWH1hc3luYyBmdW5jdGlvbiBtJCgkLFosSixRKXtsZXQgWD1uZXcgbSgkLmhlYWRDcGgpLFtZLFZdPVgucmVhZFN0cnVjdChBJCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0e3NpZzpXLGtkbTp6LGhlYWRDcGg6S309WTtpZighYXdhaXQgUS5jaGVja1NpZ0VkMjU1MTkoVyxLLFopKXJldHVybiBHKDMpO2xldCBOPUouZGVyaXZlQ2lwaGVyKHosImRlY3J5cHQiKSxPO3RyeXtPPWF3YWl0IE4uZGVjcnlwdChLKX1jYXRjaHtyZXR1cm4gRygyMCl9cmV0dXJuIFIoe2tkbTp6LGhlYWRFbmM6T30pfXZhciBlMD0iZiIsUyQ9InQiLHQwPSJlIjtmdW5jdGlvbiBrWCgkKXtpZigkPT09ITB8fCQ9PT1TJClyZXR1cm4gUyQ7aWYoJD09PXQwKXJldHVybiB0MDtyZXR1cm4gZTB9ZnVuY3Rpb24gbkooJCl7cmV0dXJuICQhPT0wJiYkIT09MTUmJiQhPT0xOCYmJCE9PTE3fWZ1bmN0aW9uIF9aKCQsWixKKXtpZigkLmFwbGQ9WixaPT09dDAmJkohPT12b2lkIDApJC5lcnI9SjtlbHNlIGRlbGV0ZSAkLmVycn1hc3luYyBmdW5jdGlvbiB2JCgkLFosSixRKXtsZXQgWD1RPy5ib2R5IT09ITEsWT1rWChaLmFwbGQpLFY9Wi5ib2R5LFc9Vj8ubGVuZ3RoPz8wLHo7aWYoWCYmViYmVz4wKXo9YXdhaXQgSi5ibGFrZTMoVik7bGV0IEs9e2VpZDpaLmVpZCxvZmY6Wi5vZmY/PzAsY3RyOlouY3RyPz8wLGxlbjpXLGhzaDp6fSxGPXtoYXNoOiQsaGVhZDpLLGFwbGQ6WX07aWYoWCYmViE9PXZvaWQgMClGLmJvZHk9VjtpZihZPT09dDAmJlouZXJyIT09dm9pZCAwKUYuZXJyPVouZXJyO3JldHVybiBGfXZhciBMWj0xMDQ4NTc2LHhaPTEwNDg1NzYscko9NjQ7ZnVuY3Rpb24gRVgoJCl7cmV0dXJuICQuc2lnLmxlbmd0aCskLmtkbS5sZW5ndGgrJC5oZWFkQ3BoLmxlbmd0aCskLmJvZHlDcGgubGVuZ3RofWFzeW5jIGZ1bmN0aW9uIGZYKCQsWixKLFEsWCl7aWYoUS5sZW5ndGg8MSlyZXR1cm4gMDtsZXRbWSxWXT1hd2FpdCAkLnB1c2goUSk7aWYoViE9PTApcmV0dXJuIFY7aWYoIVkpcmV0dXJuIDI3O2ZvcihsZXQgeiBvZiBZKXtpZih6LnN0YXR1cyE9PTApe2NvbnNvbGUuZXJyb3IoInB1c2ggZXJyIix6KTtjb250aW51ZX1sZXQgSz1YW3ouaWR4XTtpZighSyl7Y29uc29sZS5lcnJvcigibm8gaGFzaCIseik7Y29udGludWV9YXdhaXQgWi51cGxvYWRzLmRlcShKLFtLXSl9bGV0IFc9YXdhaXQgWi5ob3N0cy5nZXQoSik7aWYoVyl7bGV0IHo9Vy5sYXN0U2VxLEs9eixGPVtdO2ZvcihsZXQgTiBvZiBZKWlmKE4uc3RhdHVzPT09MClGLnB1c2goTi5zZXEpO0Yuc29ydCgoTixPKT0+Ti1PKTtmb3IobGV0IE4gb2YgRilpZihOPT09eisxKXo9TjtpZih6PkspYXdhaXQgWi5ob3N0cy50b3VjaChKLHopfXJldHVybiAwfWFzeW5jIGZ1bmN0aW9uIGRKKCQsWil7aWYoWi5sZW5ndGg8MSlyZXR1cm4gUihbXSk7bGV0IEo9bmV3IE1hcCxRPVtdO2ZvcihsZXQgVyBvZiBaKUouc2V0KFcuc2VxLFcpLFEucHVzaChXLnNlcSk7bGV0W1gsWV09YXdhaXQgJC5wdWxsKFEpO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKCFYKXJldHVybiBHKDI3KTtsZXQgVj1bXTtmb3IobGV0e3NlcTpXLGJvZHlDcGg6en1vZiBYKXtsZXQgSz1KLmdldChXKTtpZighSyljb250aW51ZTtWLnB1c2goe2RsOkssYm9keUNwaDp6fSl9cmV0dXJuIFIoVil9YXN5bmMgZnVuY3Rpb24gZ1goJCxaLEosUSl7aWYoUS5sZW5ndGg8MSlyZXR1cm4gUih7cGFydHM6W10saGFzaGVzOltdfSk7bGV0IFg9W10sWT1bXSxWPVtdLFc9bmV3IE1hcDtmb3IobGV0e2RsOkssYm9keUNwaDpGfW9mIFEpe2xldHtoZWFkOk4sa2RtOk8sc2VxOlUsaG9zdDpxfT1LLFtILE1dPWF3YWl0IG9KKEssSik7aWYoTSE9PTB8fCFIKXtsZXQgaz1XLmdldChxKT8/W107ay5wdXNoKFUpLFcuc2V0KHEsayk7Y29udGludWV9bGV0e2hlYWRFbmM6UCxoZWFkRW5jSGFzaDpDfT1ILFQ9Wi5kZXJpdmVDaXBoZXIoTywiZGVjcnlwdCIpLFtJLEFdPWF3YWl0IFdaKFAsRixULEosQyk7aWYoQSE9PTB8fCFJKXtsZXQgaz1XLmdldChxKT8/W107ay5wdXNoKFUpLFcuc2V0KHEsayk7Y29udGludWV9bGV0IHg9e2hlYWQ6Tixib2R5OkkuYm9kfSxnPUkuaGVhZEhhc2g7Vi5wdXNoKHtrZXk6ZyxkYXRhOnRKKHgpfSksWC5wdXNoKHgpLFkucHVzaChnKTtsZXQgZj1XLmdldChxKT8/W107Zi5wdXNoKFUpLFcuc2V0KHEsZil9bGV0IHo9YXdhaXQgJC5tZXNzYWdlcy5hZGQoVik7Zm9yKGxldFtLLEZdb2YgVylhd2FpdCAkLmRvd25sb2Fkcy5kZXEoSyxGKTtmb3IobGV0IEs9MDtLPHoubGVuZ3RoO0srKyl7bGV0IEY9eltLXTtpZihGIT09MCYmRiE9PTE1KWNvbnNvbGUuZXJyb3IoIkVSUiBzdG9yaW5nIixEW0ZdLCJmb3IgbWVzc2FnZSIsSyl9cmV0dXJuIFIoe3BhcnRzOlgsaGFzaGVzOll9KX1hc3luYyBmdW5jdGlvbiBvSigkLFope2xldCBKPSQuaGVhZEVuYztpZighSil7bGV0IFg9bmV3IFMsWT1YLndyaXRlU3RydWN0KFcwLCQuaGVhZCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7Sj1YLnJlc3VsdCgpfWlmKCQuaGVhZEVuY0hhc2gpcmV0dXJuIFIoe2hlYWRFbmM6SixoZWFkRW5jSGFzaDokLmhlYWRFbmNIYXNofSk7bGV0IFE9YXdhaXQgWi5ibGFrZTMoSik7cmV0dXJuIFIoe2hlYWRFbmM6SixoZWFkRW5jSGFzaDpRfSl9YXN5bmMgZnVuY3Rpb24gYUooJCxaLEope2xldCBRPW5ldyBTZXQ7Zm9yKGxldCBWIG9mIFopUS5hZGQoQihWKSk7aWYoUS5zaXplPDEpcmV0dXJuO2xldCBYPUFycmF5LmZyb20oYXdhaXQgJC5kb3dubG9hZHMubGlzdCgpKTtpZihYLmxlbmd0aDwxKXJldHVybjtsZXQgWT1uZXcgTWFwO2ZvcihsZXQgViBvZiBYKXtsZXQgVztpZihWLmhlYWRFbmNIYXNoKVc9QihWLmhlYWRFbmNIYXNoKTtlbHNle2xldFtLLEZdPWF3YWl0IG9KKFYsSik7aWYoRiE9PTB8fCFLKWNvbnRpbnVlO1c9QihLLmhlYWRFbmNIYXNoKX1pZighUS5oYXMoVykpY29udGludWU7bGV0IHo9WS5nZXQoVi5ob3N0KT8/W107ei5wdXNoKFYuc2VxKSxZLnNldChWLmhvc3Qseil9Zm9yKGxldFtWLFddb2YgWSlhd2FpdCAkLmRvd25sb2Fkcy5kZXEoVixXKX1hc3luYyBmdW5jdGlvbiBCWih7Y29ubjokLHN0b3JlOlosZW5jbGF2ZTpKLGhvc3Q6USxjcnlwdG86WCxvblByb2dyZXNzOlkscGVla1Byb2dyZXNzRXZlcnk6VixwZWVrQ29uY3VycmVuY3k6V30pe2xldCB6PWF3YWl0ICQuaWRlbnRpdHkoKSxLPVtdLFtGLE5dPWF3YWl0ICQucGVlayhRLmxhc3RTZXEpO2lmKE4hPT0wKXJldHVybiBOO2xldCBPPUYubGVuZ3RoLFU9Vj8/RiQscT1XPz9ySjtpZihZJiZPPjApWSh7cGhhc2U6InBlZWsiLGhvc3Q6US5sYWJlbCxkb25lOjAsdG90YWw6T30pO2xldCBIPTAsTT1hd2FpdCBBWihGLHEsYXN5bmMoQyk9PntsZXRbVCxJXT1hd2FpdCBtJChDLHoucHVibGljS2V5LEosWCksQTtpZihJIT09MHx8IVQpQT17b2s6ITEsc2VxOkMuc2VxLHN0YXQ6SX07ZWxzZXtsZXQgeD1hd2FpdCBYLmJsYWtlMyhULmhlYWRFbmMpO0E9e29rOiEwLHNlcTpDLnNlcSxrZG06VC5rZG0saGVhZEVuYzpULmhlYWRFbmMsaGVhZEVuY0hhc2g6eH19aWYoSCs9MSxZJiZEWihILE8sVSkpWSh7cGhhc2U6InBlZWsiLGhvc3Q6US5sYWJlbCxkb25lOkgsdG90YWw6T30pO3JldHVybiBBfSksUD1uZXcgU2V0O2ZvcihsZXQgQyBvZiBNKXtpZighQy5vayl7Y29uc29sZS5lcnJvcigicGVlazogZGVjcnlwdGluZyBpdGVtIGhlYWQiLEMuc3RhdCk7Y29udGludWV9bGV0IFQ9QihDLmhlYWRFbmNIYXNoKTtpZihhd2FpdCBaLm1lc3NhZ2VzLmhhcyhDLmhlYWRFbmNIYXNoKSl7Y29uc29sZS5pbmZvKCJwZWVrOiBsb2NhbCBtc2c7IHNraXAgZG93bmxvYWQsIGRlcSB1cGxvYWQiKSxhd2FpdCBaLnVwbG9hZHMuZGVxKFEubGFiZWwsW0MuaGVhZEVuY0hhc2hdKSxhd2FpdCBaLmRvd25sb2Fkcy5kZXEoUS5sYWJlbCxbQy5zZXFdKTtjb250aW51ZX1pZihQLmhhcyhUKSl7YXdhaXQgWi5kb3dubG9hZHMuZGVxKFEubGFiZWwsW0Muc2VxXSk7Y29udGludWV9bGV0IEE9bmV3IG0oQy5oZWFkRW5jKSxbeCxnXT1BLnJlYWRTdHJ1Y3QoVzApO2lmKGchPT0wKXtjb25zb2xlLmVycm9yKCJwZWVrOiByZWFkaW5nIGl0ZW0gaGVhZCIsZyk7Y29udGludWV9UC5hZGQoVCksSy5wdXNoKHtrZG06Qy5rZG0saGVhZDp4LHNlcTpDLnNlcSxob3N0OlEubGFiZWwsaGVhZEVuYzpDLmhlYWRFbmMsaGVhZEVuY0hhc2g6Qy5oZWFkRW5jSGFzaH0pfWlmKGF3YWl0IFouZG93bmxvYWRzLmVucShLKSxGLmxlbmd0aD4wKXtsZXQgQz1NYXRoLm1heCguLi5GLm1hcCgoVCk9PlQuc2VxKSk7YXdhaXQgWi5ob3N0cy5yZWNvcmRTdGF0cyhRLmxhYmVsLHtsYXN0U2VxOkN9KX1pZihZKVkoe3BoYXNlOiJwZWVrIixob3N0OlEubGFiZWwsZG9uZTpPLHRvdGFsOk99KTtyZXR1cm4gMH1hc3luYyBmdW5jdGlvbiBzSih7Y29ubjokLHN0b3JlOlosaG9zdDpKLG1heFB1c2hCeXRlczpRLG9uUHJvZ3Jlc3M6WH0pe2xldCBZPVE/P0xaLFY9YXdhaXQgWi51cGxvYWRzLmxpc3QoSi5sYWJlbCksVz1WLmxlbmd0aCx6PTA7aWYoWCYmVz4wKVgoe3BoYXNlOiJwdXNoIixob3N0OkoubGFiZWwsZG9uZTowLHRvdGFsOld9KTtsZXQgSz1bXSxGPVtdLE49MCxPPWFzeW5jKCk9PntpZihLLmxlbmd0aDwxKXJldHVybiAwO2xldCBVPUsubGVuZ3RoLHE9YXdhaXQgZlgoJCxaLEoubGFiZWwsSyxGKTtpZihLPVtdLEY9W10sTj0wLHE9PT0wKXtpZih6Kz1VLFgpWCh7cGhhc2U6InB1c2giLGhvc3Q6Si5sYWJlbCxkb25lOnosdG90YWw6V30pfXJldHVybiBxfTtmb3IobGV0IFUgb2YgVil7bGV0IHE9YXdhaXQgWi5tZXNzYWdlcy5nZXQoVSk7aWYoIXEpe3orPTE7Y29udGludWV9bGV0IEg9ey4uLnEuaGVhZCxib2Q6cS5ib2R5fSxbTSxQXT1hd2FpdCAkLnNlYWwoSCk7aWYoUCE9PTApcmV0dXJuIFA7aWYoIU0pcmV0dXJuIDEyO2xldCBDPUVYKE0pO2lmKEsubGVuZ3RoPjAmJk4rQz5ZKXtsZXQgVD1hd2FpdCBPKCk7aWYoVCE9PTApcmV0dXJuIFR9aWYoSy5wdXNoKE0pLEYucHVzaChVKSxOKz1DLE4+PVkpe2xldCBUPWF3YWl0IE8oKTtpZihUIT09MClyZXR1cm4gVH19cmV0dXJuIE8oKX1hc3luYyBmdW5jdGlvbiBrWih7Y29ubjokLHN0b3JlOlosZW5jbGF2ZTpKLGhvc3Q6USxjcnlwdG86WCxtYXhQdWxsQnl0ZXM6WSxvblByb2dyZXNzOlZ9LFcpe2xldCB6PVk/P3haLEs9YXdhaXQgWi5kb3dubG9hZHMubGlzdCgpLEY9QXJyYXkuZnJvbShLKS5maWx0ZXIoKE0pPT5NLmhvc3Q9PT1RLmxhYmVsKTtpZihGLmxlbmd0aDwxKXJldHVybiAxNTtsZXQgTj1zMChGLChNKT0+TS5oZWFkKSxPPWNKKE4sKE0pPT5NLmhlYWQubGVuLHopLFU9Ti5sZW5ndGgscT0wO2lmKFYpVih7cGhhc2U6InB1bGwiLGhvc3Q6US5sYWJlbCxkb25lOjAsdG90YWw6VX0pO2xldCBIPWRKKCQsT1swXSk7Zm9yKGxldCBNPTA7TTxPLmxlbmd0aDtNKyspe2xldFtQLENdPWF3YWl0IEg7aWYoQyE9PTB8fCFQKXJldHVybiBDO2lmKHErPU9bTV0ubGVuZ3RoLFYpVih7cGhhc2U6InB1bGwiLGhvc3Q6US5sYWJlbCxkb25lOnEsdG90YWw6VX0pO2xldCBUPU9bTSsxXTtpZihUKUg9ZEooJCxUKTtpZihWKVYoe3BoYXNlOiJvcGVuIixob3N0OlEubGFiZWwsZG9uZTpxLHRvdGFsOlV9KTtsZXQgST1zMChQLCh4KT0+eC5kbC5oZWFkKSxbLEFdPWF3YWl0IGdYKFosSixYLEkpO2lmKEEhPT0wKXJldHVybiBBO2lmKFcpe2lmKFYpVih7cGhhc2U6ImV4ZWMiLGhvc3Q6US5sYWJlbCxkb25lOnEsdG90YWw6VX0pO2F3YWl0IFcoKX19cmV0dXJuIDB9ZnVuY3Rpb24gdEooe2hlYWQ6JCxib2R5Olp9KXtsZXQgSj17ZWlkOiQuZWlkLGJvZHk6WixhcGxkOmUwfTtpZigkLm9mZiE9PTApSi5vZmY9JC5vZmY7aWYoJC5jdHIhPT0wKUouY3RyPSQuY3RyO3JldHVybiBKfWFzeW5jIGZ1bmN0aW9uIGVKKCQse2Nvbm46WixzdG9yZTpKLGVuY2xhdmU6USxob3N0OlgsY3J5cHRvOlksb25Qcm9ncmVzczpWfSxXKXtsZXQgej1YLmxhYmVsLEs9YXdhaXQgWi5pZGVudGl0eSgpLEY9bmV3IG0oJCksW04sT109Ri5yZWFkU3RydWN0cyhEJCk7aWYoTyE9PTApe2NvbnNvbGUuZXJyb3IoIkZhaWxlZCBkZWNvZGluZyBub3RpZiIsRFtPXSk7cmV0dXJufWxldCBVPSExLEg9KGF3YWl0IEouaG9zdHMuZ2V0KHopKT8ubGFzdFNlcSxNPVtdLFA9ITE7Zm9yKGxldCBJIG9mIE4pe2xldFtBLHhdPWF3YWl0IG0kKHtzZXE6SS5zZXEsaGVhZENwaDpJLmhlYWRDcGh9LEsucHVibGljS2V5LFEsWSk7aWYoeCE9PTApe2NvbnNvbGUuZXJyb3IoIkZhaWxlZCBkZWNyeXB0aW5nIG5vdGlmIixEW3hdKTtjb250aW51ZX1sZXQgZz1hd2FpdCBZLmJsYWtlMyhBLmhlYWRFbmMpO2lmKGF3YWl0IEoubWVzc2FnZXMuaGFzKGcpKWNvbnRpbnVlO2xldCBmPW5ldyBtKEEuaGVhZEVuYyksW2ssYl09Zi5yZWFkU3RydWN0KFcwKTtpZihiIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIHRvIHBhcnNlIGhlYWQiLERbYl0pO2NvbnRpbnVlfWlmKCFJLmJvZHlDcGgmJmsubGVuPjApUD0hMCxhd2FpdCBKLmRvd25sb2Fkcy5lbnEoW3tzZXE6SS5zZXEsaG9zdDp6LGtkbTpBLmtkbSxoZWFkOmssaGVhZEVuYzpBLmhlYWRFbmMsaGVhZEVuY0hhc2g6Z31dKTtlbHNlIE0ucHVzaCh7Li4uQSxoZWFkOmssYm9keUNwaDpJLmJvZHlDcGgsaGVhZEVuY0hhc2g6Z30pO2lmKEg9PT12b2lkIDB8fEkuc2VxIT09SCsxKWNvbnNvbGUubG9nKCJvdXQgb2Ygc2VxIixJLnNlcSxIKSxVPSEwO2Vsc2UgSD1JLnNlcX1pZihIIT09dm9pZCAwKWF3YWl0IEouaG9zdHMudG91Y2goWC5sYWJlbCxIKTtsZXQgQz1bXTtmb3IobGV0IEkgb2YgTSl7bGV0IEE9US5kZXJpdmVDaXBoZXIoSS5rZG0sImRlY3J5cHQiKSxbeCxnXT1hd2FpdCBXWihJLmhlYWRFbmMsSS5ib2R5Q3BoLEEsWSk7aWYoZyE9PTApe2NvbnNvbGUuZXJyb3IoIkZhaWxlZCB0byBvcGVuIGJvZHkiLERbZ10pO2NvbnRpbnVlfUMucHVzaCh7a2V5OkkuaGVhZEVuY0hhc2gsZGF0YTp0Sih7aGVhZDpJLmhlYWQsYm9keTp4LmJvZH0pfSl9bGV0IFQ9YXdhaXQgSi5tZXNzYWdlcy5hZGQoQyk7Zm9yKGxldCBJPTA7STxULmxlbmd0aDtJKyspe2xldCBBPVRbSV07aWYoQSE9PTAmJkEhPT0xNSljb25zb2xlLmVycm9yKCJFUlIgc3RvcmluZyIsRFtBXSwiZm9yIG1lc3NhZ2UiLEkpfWlmKFYmJkMubGVuZ3RoPjApVih7cGhhc2U6Im9wZW4iLGhvc3Q6WC5sYWJlbCxkb25lOkMubGVuZ3RoLHRvdGFsOkMubGVuZ3RofSk7aWYoVXx8UHx8Qy5sZW5ndGg+MClXKCl9YXN5bmMgZnVuY3Rpb24gRVooJCxaPXt9KXtsZXQgSj1aLnB1bGwhPT0hMSxRPVoucHVzaD09PSEwLHtjb25uOlgsc3RvcmU6WSxlbmNsYXZlOlYsaG9zdDpXLGNyeXB0bzp6LG9uUHJvZ3Jlc3M6SyxwZWVrUHJvZ3Jlc3NFdmVyeTpGLHBlZWtDb25jdXJyZW5jeTpOfT0kLE89YXdhaXQgWC5pZGVudGl0eSgpLFtVLHFdPWF3YWl0IFgucGVlaygwKTtpZihxIT09MClyZXR1cm4gRyhxKTtsZXQgSD1VLmxlbmd0aCxNPUY/P0YkLFA9Tj8/cko7aWYoSyYmSD4wKUsoe3BoYXNlOiJwZWVrIixob3N0OlcubGFiZWwsZG9uZTowLHRvdGFsOkh9KTtsZXQgQz0wLFQ9YXdhaXQgQVooVSxQLGFzeW5jKEwpPT57bGV0W3YsRV09YXdhaXQgbSQoTCxPLnB1YmxpY0tleSxWLHopLHk7aWYoRSE9PTB8fCF2KXk9e29rOiExLHNlcTpMLnNlcSxzdGF0OkV9O2Vsc2V7bGV0IF89YXdhaXQgei5ibGFrZTModi5oZWFkRW5jKTt5PXtvazohMCxzZXE6TC5zZXEsa2RtOnYua2RtLGhlYWRFbmM6di5oZWFkRW5jLGhlYWRFbmNIYXNoOl99fWlmKEMrPTEsSyYmRFooQyxILE0pKUsoe3BoYXNlOiJwZWVrIixob3N0OlcubGFiZWwsZG9uZTpDLHRvdGFsOkh9KTtyZXR1cm4geX0pLEk9bmV3IE1hcDtmb3IobGV0IEwgb2YgVCl7aWYoIUwub2spY29udGludWU7bGV0IHY9QihMLmhlYWRFbmNIYXNoKSxFPUkuZ2V0KHYpO2lmKEUpRS5jb3VudCs9MTtlbHNlIEkuc2V0KHYse2hhc2g6TC5oZWFkRW5jSGFzaCxjb3VudDoxLHNhbXBsZTpMfSl9bGV0IEE9MCx4PVtdO2ZvcihsZXQgTCBvZiBJLnZhbHVlcygpKXtpZihMLmNvdW50PjEpQSs9TC5jb3VudC0xO3gucHVzaChMLmhhc2gpfWxldCBnPVUubGVuZ3RoLGY9SS5zaXplLGs9YXdhaXQgSyQoeCx6KSxiPVtdLHc9MDtmb3IobGV0IEwgb2YgSS52YWx1ZXMoKSl7aWYoYXdhaXQgWS5tZXNzYWdlcy5oYXMoTC5oYXNoKSl7YXdhaXQgWS51cGxvYWRzLmRlcShXLmxhYmVsLFtMLmhhc2hdKTtjb250aW51ZX1pZih3Kz0xLCFKKWNvbnRpbnVlO2xldCBFPUwuc2FtcGxlLHk9bmV3IG0oRS5oZWFkRW5jKSxbXyxuXT15LnJlYWRTdHJ1Y3QoVzApO2lmKG4hPT0wKXtjb25zb2xlLmVycm9yKCJyZWNvbmNpbGU6IHJlYWRpbmcgbXNnIGhlYWRlciIsbik7Y29udGludWV9Yi5wdXNoKHtrZG06RS5rZG0saGVhZDpfLHNlcTpFLnNlcSxob3N0OlcubGFiZWwsaGVhZEVuYzpFLmhlYWRFbmMsaGVhZEVuY0hhc2g6RS5oZWFkRW5jSGFzaH0pfWlmKGIubGVuZ3RoPjApYXdhaXQgWS5kb3dubG9hZHMuZW5xKGIpO2xldCBpPTA7aWYoUSl7bGV0IEw9YXdhaXQgWS5tZXNzYWdlcy5saXN0S2V5cygpLHY9bmV3IFNldChJLmtleXMoKSksRT1bXTtmb3IobGV0IHkgb2YgTClpZighdi5oYXMoQih5KSkpaSs9MSxFLnB1c2goeSk7aWYoRS5sZW5ndGg+MClhd2FpdCBZLnVwbG9hZHMuZW5xKFcubGFiZWwsRSl9ZWxzZXtsZXQgTD1hd2FpdCBZLm1lc3NhZ2VzLmxpc3RLZXlzKCksdj1uZXcgU2V0KEkua2V5cygpKTtmb3IobGV0IEUgb2YgTClpZighdi5oYXMoQihFKSkpaSs9MX1sZXQgdT1VLmxlbmd0aD4wP01hdGgubWF4KC4uLlUubWFwKChMKT0+TC5zZXEpKTowO2lmKGF3YWl0IFkuaG9zdHMucmVjb3JkU3RhdHMoVy5sYWJlbCx7c2V0TGFzdFNlcTp1fSksSylLKHtwaGFzZToicGVlayIsaG9zdDpXLmxhYmVsLGRvbmU6SCx0b3RhbDpIfSk7cmV0dXJuIFIoe21zZ2NoZWNrOmssbnVtQmFnczpnLHVuaXF1ZU1zZ3M6ZixudW1EdXBlczpBLG1pc3NpbmdMb2NhbDp3LG1pc3NpbmdIb3N0Oml9KX1jbGFzcyBmWntjbG9jaztzdGF0ZTtzdG9yZTt0cmFuc3BvcnQ7Y3J5cHRvO2ZvcmNlU2tld0hhbmRsaW5nQnlEZWZhdWx0O29uU2NoZWR1bGVTeW5jO2Nvbm5lY3Rpb25zPW5ldyBNYXA7YXBwbHlDaGFpbj1Qcm9taXNlLnJlc29sdmUoKTtzeW5jUnVucz1uZXcgZyQ7Y2xpZW50U3RhdGU7eGZlclN0YXRlO21heFB1c2hCeXRlczttYXhQdWxsQnl0ZXM7cGVla1Byb2dyZXNzRXZlcnk9RiQ7bGFzdFByb2dyZXNzPWpaO3NjaGVkdWxlZFN5bmM7Y29uc3RydWN0b3IoJCxaLEosUSxYLFk9ITAsVj1MWixXPXhaLHope3RoaXMuY2xvY2s9JDt0aGlzLnN0YXRlPVo7dGhpcy5zdG9yZT1KO3RoaXMudHJhbnNwb3J0PVE7dGhpcy5jcnlwdG89WDt0aGlzLmZvcmNlU2tld0hhbmRsaW5nQnlEZWZhdWx0PVk7dGhpcy5vblNjaGVkdWxlU3luYz16O3RoaXMubWF4UHVzaEJ5dGVzPVYsdGhpcy5tYXhQdWxsQnl0ZXM9Vyx0aGlzLmNsaWVudFN0YXRlPW5ldyB4MCgoKT0+dGhpcy5nZXRDbGllbnRTdGF0ZSgpKSx0aGlzLnhmZXJTdGF0ZT1uZXcgeDAoKCk9PnRoaXMuZ2V0WGZlclN0YXRlKCkpLHRoaXMuc2NoZWR1bGVkU3luYz1uZXcgVFoobEosYXN5bmMoKT0+e3RyeXtjb25zb2xlLmluZm8oIlJ1bm5pbmcgc2NoZWR1bGVkIHN5bmMiKSxhd2FpdCB0aGlzLnN5bmMoKX1jYXRjaChLKXtjb25zb2xlLmVycm9yKCJEZWJvdW5jZWQgc3luYyBmYWlsZWQ6IixLKX19KX1lbWl0UHJvZ3Jlc3M9KCQpPT57dGhpcy5sYXN0UHJvZ3Jlc3M9JCx0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9O2FzeW5jIHNldFNlZWQoJCxaKXthd2FpdCB0aGlzLnN0b3JlLnNlZWQuc2F2ZSgkLFopLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpfWFzeW5jIGdldENsaWVudFN0YXRlKCl7bGV0e3N0b3JlOiQsY29ubmVjdGlvbnM6Wn09dGhpcyxKPWF3YWl0ICQuc2VlZC5sb2FkKCksUT1hd2FpdCAkLmhvc3RzLmxpc3QoKSxYPSExO2ZvcihsZXQgWSBvZiBaLnZhbHVlcygpKWlmKFkuaXNDb25uZWN0ZWQoKSl7WD0hMDticmVha31yZXR1cm57aGFzU2VlZDpKIT09dm9pZCAwLGhhc0hvc3Q6QXJyYXkuZnJvbShRKS5sZW5ndGg+MCxjb25uZWN0ZWQ6WH19YXN5bmMgZ2V0WGZlclN0YXRlKCl7bGV0e3VwbG9hZHM6JCxkb3dubG9hZHM6Wn09dGhpcy5zdG9yZSxKPWF3YWl0ICQuY291bnQoKTtyZXR1cm57bnVtRG93bmxvYWRzOmF3YWl0IFouY291bnQoKSxudW1VcGxvYWRzOkoscHJvZ3Jlc3M6dGhpcy5sYXN0UHJvZ3Jlc3N9fWFwcGx5PSgkLFopPT57cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvQXBwbHkoJCxaKSl9O2FzeW5jIGRvQXBwbHkoJCxaPXtlbnF1ZXVlVXBsb2FkOiEwLHRyaWdnZXJVcGxvYWQ6ITB9KXtsZXQgSj1bXSxRPVtdO2ZvcihsZXR7aGVhZDpZLGJvZHk6Vn1vZiAkKXtsZXQgVz1uZXcgUztXLndyaXRlU3RydWN0KFcwLFkpO2xldCB6PVcucmVzdWx0KCksSz1hd2FpdCB0aGlzLmNyeXB0by5ibGFrZTMoeiksRj17ZWlkOlkuZWlkLGJvZHk6VixhcGxkOmUwfTtpZihZLm9mZiE9PTApRi5vZmY9WS5vZmY7aWYoWS5jdHIhPT0wKUYuY3RyPVkuY3RyO0oucHVzaChLKSxRLnB1c2goe2tleTpLLGRhdGE6Rn0pfWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMuYWRkKFEpLGF3YWl0IGFKKHRoaXMuc3RvcmUsSix0aGlzLmNyeXB0byk7bGV0IFg9YXdhaXQgdGhpcy5kb0FwcGx5SGFzaGVzKEopO2lmKFouZW5xdWV1ZVVwbG9hZCl7bGV0IFk9W107Zm9yKGxldCBWPTA7VjxKLmxlbmd0aDtWKyspe2xldCBXPVhbVl07aWYoVz09PTB8fFc9PT0xNSlZLnB1c2goSltWXSl9aWYoWS5sZW5ndGg+MCl7bGV0IFY9YXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5saXN0KCk7Zm9yKGxldCBXIG9mIFYpYXdhaXQgdGhpcy5zdG9yZS51cGxvYWRzLmVucShXLmxhYmVsLFkpO3RoaXMueGZlclN0YXRlLmVtaXQoKX19aWYoWi50cmlnZ2VyVXBsb2FkKXRoaXMuc2NoZWR1bGVTeW5jKCk7cmV0dXJuIFh9ZW5xdWV1ZUFwcGx5Sm9iKCQpe2xldCBaPXRoaXMuYXBwbHlDaGFpbi50aGVuKCQsJCk7cmV0dXJuIHRoaXMuYXBwbHlDaGFpbj1aLnRoZW4oKCk9PntyZXR1cm59LCgpPT57cmV0dXJufSksWn1kcmFpbkFwcGx5UXVldWUoKXtyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMuZG9EcmFpbkFwcGx5UXVldWUoKSl9YXN5bmMgZG9EcmFpbkFwcGx5UXVldWUoKXtsZXQgJD1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3Qoe2FwbGQ6ZTB9KTtpZigkLmxlbmd0aDwxKXJldHVybltdO2xldCBaPXMwKCQsKEopPT5KLmhlYWQpO3JldHVybiB0aGlzLmFwcGx5U3RvcmVkKFopfWFwcGx5SGFzaGVzPSgkKT0+e3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5kb0FwcGx5SGFzaGVzKCQpKX07YXN5bmMgZG9BcHBseUhhc2hlcygkKXtsZXQgWj1bXTtmb3IobGV0IFggb2YgJCl7bGV0IFk9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5nZXQoWCk7aWYoWSlaLnB1c2goWSl9bGV0IEo9YXdhaXQgdGhpcy5hcHBseVN0b3JlZChaKSxRPW5ldyBNYXA7Zm9yKGxldCBYPTA7WDxaLmxlbmd0aDtYKyspUS5zZXQoQihaW1hdLmhhc2gpLEpbWF0/PzEyKTtyZXR1cm4gJC5tYXAoKFgpPT5RLmdldChCKFgpKT8/MTMpfWFzeW5jIGFwcGx5U3RvcmVkKCQpe2lmKCQubGVuZ3RoPDEpcmV0dXJuW107bGV0IFo9JC5tYXAoKFkpPT4oey4uLlkuaGVhZCxib2Q6WS5ib2R5fSkpLEo9YXdhaXQgdGhpcy5zdGF0ZS5hcHBseShaKSxRPVtdLFg9W107Zm9yKGxldCBZPTA7WTwkLmxlbmd0aDtZKyspe2xldCBWPUpbWV07aWYoVj09PTB8fFY9PT0xNSlRLnB1c2goJFtZXS5oYXNoKTtlbHNlIGlmKFYhPT12b2lkIDAmJm5KKFYpKVgucHVzaCh7a2V5OiRbWV0uaGFzaCxlcnI6Vn0pfWlmKFEubGVuZ3RoPjApYXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5tYXJrQXBwbGllZChRKTtpZihYLmxlbmd0aD4wKWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubWFya0ZhaWxlZChYKTtyZXR1cm4gSn1hc3luYyBpbnNlcnRSYXcoJCl7bGV0e2Nsb2NrOlosY3J5cHRvOkp9PXRoaXMsW1EsWF09YXdhaXQgZkooe25vdzpaLm5vdygpLGJvZDokLGNyeXB0bzpKfSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFY9KGF3YWl0IHRoaXMuYXBwbHkoW3toZWFkOlEsYm9keTokfV0pKVswXTtpZihWIT09MCYmViE9PTE1KXJldHVybiBHKFY/PzEyKTtyZXR1cm4gUihRKX1hc3luYyBtYWtlVXBkYXRlKCQsWil7bGV0e2Nsb2NrOkosY3J5cHRvOlF9PXRoaXMsWD1KLm5vdygpO2lmKCQudXBkYXRlZEF0LmdldFRpbWUoKT5YLmdldFRpbWUoKSlyZXR1cm4gRyg0KTtsZXQgWT0kLmN0cisxLFtWLFddPWF3YWl0IHgkKHtub3c6WCxlaWQ6JC5laWQsY3RyOlksYm9kOlosY3J5cHRvOlF9KTtpZihXIT09MClyZXR1cm4gRyhXKTtyZXR1cm4gUih7aGVhZDpWLGJvZHk6Wn0pfWFzeW5jIHVwZGF0ZVdpdGhTa2V3KCQsWixKKXtpZihKPT09ITEpcmV0dXJuIEcoNCk7bGV0e2Nsb2NrOlEsY3J5cHRvOlh9PXRoaXMsWT1RLm5vdygpLFY9bmV3IG0oJC5laWQpLFtXLHpdPVYucmVhZFN0cnVjdChZMCk7aWYoeiE9PTApcmV0dXJuIEcoeik7bGV0IEs9JC51cGRhdGVkQXQuZ2V0VGltZSgpLVcudHMuZ2V0VGltZSgpLEY9e2VpZDokLmVpZCxvZmY6SysxLGN0cjokLmN0cisxLGxlbjowfSxPPShhd2FpdCB0aGlzLmFwcGx5KFt7aGVhZDpGLGJvZHk6dm9pZCAwfV0pKVswXTtpZihPIT09MCYmTyE9PTE1KXJldHVybiBHKE8/PzEyKTtpZihaPT09dm9pZCAwKXJldHVybiBSKEYpO2xldFtVLHFdPWokKHtpZDpXLmlkLHRzOll9KTtpZihxIT09MClyZXR1cm4gRyhxKTtsZXRbSCxNXT1hd2FpdCB4JCh7bm93OlksZWlkOlUsY3RyOjAsYm9kOlosY3J5cHRvOlh9KTtpZihNIT09MClyZXR1cm4gRyhNKTtsZXQgQz0oYXdhaXQgdGhpcy5hcHBseShbe2hlYWQ6SCxib2R5Olp9XSkpWzBdO2lmKEMhPT0wJiZDIT09MTUpcmV0dXJuIEcoQz8/MTIpO3JldHVybiBSKEgpfWFzeW5jIHVwZGF0ZVJhdygkLFosSj10aGlzLmZvcmNlU2tld0hhbmRsaW5nQnlEZWZhdWx0KXtpZigkLnVwZGF0ZWRBdC5nZXRUaW1lKCk+dGhpcy5jbG9jay5ub3coKS5nZXRUaW1lKCkpcmV0dXJuIHRoaXMudXBkYXRlV2l0aFNrZXcoJCxaLEopO3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYihhc3luYygpPT57bGV0W1EsWF09YXdhaXQgdGhpcy5tYWtlVXBkYXRlKCQsWik7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFY9KGF3YWl0IHRoaXMuZG9BcHBseShbUV0pKVswXTtpZihWIT09MCYmViE9PTE1KXJldHVybiBHKFY/PzEyKTtyZXR1cm4gUihRLmhlYWQpfSl9YXN5bmMgaW5zZXJ0KCQpe2xldHtib2R5OlosdHlwZTpKLGdpZDpRLHBpZDpYLHRhZ3M6WX09JCxXPUwwKHtib2R5OlosdHlwZTpKLGdpZDpRLHBpZDpYLHRhZ3M6WX0pO3JldHVybiB0aGlzLmluc2VydFJhdyhXKX1hc3luYyB1cGRhdGUoJCl7bGV0e3ByaW9yOlosYm9keTpKLHR5cGU6USxnaWQ6WCxwaWQ6WSx0YWdzOlYsZm9yY2U6V309JCxLPUwwKHtib2R5OkosdHlwZTpRLGdpZDpYLHBpZDpZLHRhZ3M6Vn0pO3JldHVybiB0aGlzLnVwZGF0ZVJhdyhaLEssVz8/dGhpcy5mb3JjZVNrZXdIYW5kbGluZ0J5RGVmYXVsdCl9YXN5bmMgZGVsZXRlKCQpe2xldCBaPSQuZm9yY2U/PyEwO2lmKCJwcmlvciJpbiAkKXJldHVybiB0aGlzLnVwZGF0ZVJhdygkLnByaW9yLHZvaWQgMCxaKTtsZXRbSixRXT1hd2FpdCB0aGlzLnJldkZyb21BcmNoaXZlKCQuZWlkKTtpZihRIT09MClyZXR1cm4gRyhRKTtyZXR1cm4gdGhpcy51cGRhdGVSYXcoSix2b2lkIDAsWil9YXN5bmMgcmV2RnJvbUFyY2hpdmUoJCl7bGV0IFo9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5sYXN0KCQpO2lmKFopcmV0dXJuIGlKKFouaGVhZCk7bGV0IEo9bmV3IG0oJCksW1EsWF09Si5yZWFkU3RydWN0KFkwKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gUih7ZWlkOiQsY3RyOi0xLHVwZGF0ZWRBdDpRLnRzfSl9YXN5bmMgZ2VuRUlEKCQpe2xldHtjbG9jazpaLGNyeXB0bzpKfT10aGlzLFE9Wi5ub3coKTtpZigkIT09dm9pZCAwKXJldHVybiBqJCh7aWQ6JCx0czpRfSk7bGV0IFg9YXdhaXQgSi5nZW5SYW5kb21CeXRlcyg4KTtyZXR1cm4gaiQoe2lkOlgsdHM6UX0pfXN5bmMoKXtyZXR1cm4gdGhpcy5zeW5jUnVucy5ydW4oKCk9PnRoaXMuZG9TeW5jKCkpfWFzeW5jIGRvU3luYygpe2xldHtjb25uZWN0aW9uczokLGNyeXB0bzpaLHN0b3JlOkp9PXRoaXMsUT1hd2FpdCBKLnNlZWQubG9hZCgpO2lmKCFRKXJldHVybiAyMjthd2FpdCB0aGlzLmRyYWluQXBwbHlRdWV1ZSgpO2ZvcihsZXRbWCxZXW9mICQpe2xldCBWPWF3YWl0IEouaG9zdHMuZ2V0KFgpO2lmKCFWKWNvbnRpbnVlO2xldCBXPXtjb25uOlksc3RvcmU6SixlbmNsYXZlOlEsaG9zdDpWLGNyeXB0bzpaLG1heFB1c2hCeXRlczp0aGlzLm1heFB1c2hCeXRlcyxtYXhQdWxsQnl0ZXM6dGhpcy5tYXhQdWxsQnl0ZXMsb25Qcm9ncmVzczp0aGlzLmVtaXRQcm9ncmVzcyxwZWVrUHJvZ3Jlc3NFdmVyeTp0aGlzLnBlZWtQcm9ncmVzc0V2ZXJ5fSx6PWF3YWl0IEJaKFcpO2lmKHohPT0wKXJldHVybiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcGVlazogJHt6fWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSx6O3RoaXMueGZlclN0YXRlLmVtaXQoKTtsZXQgSz1hd2FpdCBzSihXKTtpZihLIT09MClyZXR1cm4gY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHB1c2g6ICR7S31gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksSzt0aGlzLnhmZXJTdGF0ZS5lbWl0KCk7bGV0IEY9YXdhaXQga1ooVyxhc3luYygpPT57YXdhaXQgdGhpcy5kcmFpbkFwcGx5UXVldWUoKX0pO2lmKEYhPT0wJiZGIT09MTUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwdWxsOiAke0Z9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEY7dGhpcy54ZmVyU3RhdGUuZW1pdCgpfXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH1hc3luYyByZWJ1aWxkKCQpe2lmKHRoaXMuc2NoZWR1bGVkU3luYy5jYW5jZWwoKSxhd2FpdCB0aGlzLnN5bmNSdW5zLmZsdXNoKCksJD8uY2hlY2tIb3N0Pz8hMCl7bGV0IEo9YXdhaXQgdGhpcy5yZXB1bGwoKTtpZihKIT09MClyZXR1cm4gSn1yZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMucmVwbGF5KCkpfWFzeW5jIG1zZ2NoZWNrKCl7bGV0ICQ9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0S2V5cygpO3JldHVybiBLJCgkLHRoaXMuY3J5cHRvKX1saXN0TXNncygkKXtyZXR1cm4gdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0KCQpfWNvdW50TXNncygkKXtyZXR1cm4gdGhpcy5zdG9yZS5tZXNzYWdlcy5jb3VudCgkKX1hc3luYyByZWNvbmNpbGUoJCxaKXt0aGlzLnNjaGVkdWxlZFN5bmMuY2FuY2VsKCksYXdhaXQgdGhpcy5zeW5jUnVucy5mbHVzaCgpO2xldHtjb25uZWN0aW9uczpKLGNyeXB0bzpRLHN0b3JlOlh9PXRoaXMsWT1hd2FpdCBYLnNlZWQubG9hZCgpO2lmKCFZKXJldHVybiBHKDIyKTtsZXQgVj1hd2FpdCBYLmhvc3RzLmdldCgkKTtpZighVilyZXR1cm4gRygxMyk7bGV0IFc9Si5nZXQoJCk7aWYoIVd8fCFXLmlzQ29ubmVjdGVkKCkpe2lmKGF3YWl0IHRoaXMuY29ubmVjdFRvSG9zdChWLCExLCExKSxWPWF3YWl0IFguaG9zdHMuZ2V0KCQpLCFWKXJldHVybiBHKDEzKTtXPUouZ2V0KCQpfWlmKCFXKXJldHVybiBHKDEyKTtsZXQgej17Y29ubjpXLHN0b3JlOlgsZW5jbGF2ZTpZLGNyeXB0bzpRLG1heFB1c2hCeXRlczp0aGlzLm1heFB1c2hCeXRlcyxtYXhQdWxsQnl0ZXM6dGhpcy5tYXhQdWxsQnl0ZXMsb25Qcm9ncmVzczp0aGlzLmVtaXRQcm9ncmVzcyxwZWVrUHJvZ3Jlc3NFdmVyeTp0aGlzLnBlZWtQcm9ncmVzc0V2ZXJ5fSxbSyxGXT1hd2FpdCBFWih7Li4ueixob3N0OlZ9LFopO2lmKHRoaXMueGZlclN0YXRlLmVtaXQoKSxGIT09MClyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEcoRik7aWYoIUspcmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxHKDEyKTtpZihaPy5zeW5jPT09ITEpcmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxSKEspO2xldCBOPWF3YWl0IHRoaXMuc3luYygpO2lmKE4hPT0wKXJldHVybiBHKE4pO2xldCBPPWF3YWl0IFguaG9zdHMuZ2V0KCQpO2lmKCFPKXJldHVybiBHKDEzKTtsZXRbVSxxXT1hd2FpdCBFWih7Li4ueixob3N0Ok99LHtwdWxsOiExLHB1c2g6ITF9KTtpZih0aGlzLnhmZXJTdGF0ZS5lbWl0KCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLHEhPT0wKXJldHVybiBHKHEpO2lmKCFVKXJldHVybiBHKDEyKTtyZXR1cm4gUihVKX1hc3luYyByZXB1bGwoKXtsZXR7Y29ubmVjdGlvbnM6JCxjcnlwdG86WixzdG9yZTpKfT10aGlzLFE9YXdhaXQgSi5zZWVkLmxvYWQoKTtpZighUSlyZXR1cm4gMjI7bGV0IFg9QXJyYXkuZnJvbShhd2FpdCBKLmhvc3RzLmxpc3QoKSk7aWYoWC5sZW5ndGg8MSlyZXR1cm4gMDtmb3IobGV0IFkgb2YgWCl7bGV0IFY9JC5nZXQoWS5sYWJlbCk7aWYoIVZ8fCFWLmlzQ29ubmVjdGVkKCkpYXdhaXQgdGhpcy5jb25uZWN0VG9Ib3N0KFksITEsITEpfWZvcihsZXRbWSxWXW9mICQpe2xldCBXPWF3YWl0IEouaG9zdHMuZ2V0KFkpO2lmKCFXKWNvbnRpbnVlO2xldCB6PXtjb25uOlYsc3RvcmU6SixlbmNsYXZlOlEsaG9zdDp7Li4uVyxsYXN0U2VxOjB9LGNyeXB0bzpaLG1heFB1c2hCeXRlczp0aGlzLm1heFB1c2hCeXRlcyxtYXhQdWxsQnl0ZXM6dGhpcy5tYXhQdWxsQnl0ZXMsb25Qcm9ncmVzczp0aGlzLmVtaXRQcm9ncmVzcyxwZWVrUHJvZ3Jlc3NFdmVyeTp0aGlzLnBlZWtQcm9ncmVzc0V2ZXJ5fSxLPWF3YWl0IEJaKHopO2lmKEshPT0wKXJldHVybiBjb25zb2xlLmVycm9yKGByZWJ1aWxkOiBmYWlsZWQgdG8gcGVlazogJHtLfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxLO3RoaXMueGZlclN0YXRlLmVtaXQoKTtsZXQgRj1hd2FpdCBrWih6KTtpZihGIT09MCYmRiE9PTE1KXJldHVybiBjb25zb2xlLmVycm9yKGByZWJ1aWxkOiBmYWlsZWQgdG8gcHVsbDogJHtGfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxGO3RoaXMueGZlclN0YXRlLmVtaXQoKX1yZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9YXN5bmMgcmVwbGF5KCl7bGV0ICQ9YXdhaXQgdGhpcy5zdGF0ZS5jbGVhcigpO2lmKCQhPT0wKXJldHVybiAkO2xldCBaPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdCgpLEo9czAoWiwoWSk9PlkuaGVhZCksUT1KLmxlbmd0aDtpZihRPDEpcmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwO2xldCBYPTA7d2hpbGUoWDxKLmxlbmd0aCl7bGV0IFk9MCxWPTAsVz1YO2ZvcihsZXQgSz1YO0s8Si5sZW5ndGgmJlY8MTAwJiZZPDEwMjQwMDtLKyspWSs9SltLXS5oZWFkLmxlbixWKyssVz1LKzE7bGV0IHo9Si5zbGljZShYLFcpO2F3YWl0IHRoaXMuYXBwbHlTdG9yZWQoeiksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJleGVjIixkb25lOlcsdG90YWw6UX0pLFg9V31yZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9YXN5bmMgd2lwZSgkKXtsZXQgWj0kPy5tc2dzIT09ITEsSj0kPy5lbnRzIT09ITEsUT0kPy5tZXRhIT09ITEsWD0kPy5zZWVkPT09ITA7dGhpcy5zY2hlZHVsZWRTeW5jLmNhbmNlbCgpLGF3YWl0IHRoaXMuZGlzY29ubmVjdCgpLGF3YWl0IHRoaXMuc3luY1J1bnMuZmx1c2goKTtsZXR7c3RvcmU6WX09dGhpcztpZihRKWF3YWl0IFkuaG9zdHMud2lwZSgpLGF3YWl0IFkudXBsb2Fkcy53aXBlKCksYXdhaXQgWS5kb3dubG9hZHMud2lwZSgpO2lmKFopYXdhaXQgWS5tZXNzYWdlcy53aXBlKCk7aWYoWClhd2FpdCBZLnNlZWQud2lwZSgpO2lmKEopYXdhaXQgdGhpcy5zdGF0ZS5jbGVhcigpO3RoaXMubGFzdFByb2dyZXNzPWpaLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLHRoaXMueGZlclN0YXRlLmVtaXQoKX1pbXBvcnQ9YXN5bmMoJCxaKT0+e2xldHtjcnlwdG86SixzdG9yZTpRfT10aGlzLFg9Wj8ub25Qcm9ncmVzcyxZPWF3YWl0IFEuc2VlZC5sb2FkKCk7aWYoIVkpcmV0dXJuIDIyO2NvbnNvbGUudGltZSgiaW1wb3J0OiBkZWNvZGluZyBmaWxlLi4uIik7bGV0IFY9YXdhaXQgJC5ieXRlcygpLFtXLHpdPWF3YWl0IEVKKFYsSixZKTtpZih6IT09MClyZXR1cm4gejtjb25zb2xlLnRpbWVFbmQoImltcG9ydDogZGVjb2RpbmcgZmlsZS4uLiIpO2xldCBLPTA7d2hpbGUoSzxXLmxlbmd0aCl7bGV0IEY9MCxOPTAsTz1LO2ZvcihsZXQgSD1LO0g8Vy5sZW5ndGgmJk48MTAwJiZGPDEwMjQwMDtIKyspRis9V1tIXS5oZWFkLmxlbixOKyssTz1IKzE7bGV0IFU9Vy5zbGljZShLLE8pO2NvbnNvbGUudGltZShgaW1wb3J0OiBhcHBseWluZyBbJHtLfSwgJHtPfV1gKTtsZXQgcT1hd2FpdCB0aGlzLmFwcGx5KFUse2VucXVldWVVcGxvYWQ6ITAsdHJpZ2dlclVwbG9hZDohMX0pO2NvbnNvbGUudGltZUVuZChgaW1wb3J0OiBhcHBseWluZyBbJHtLfSwgJHtPfV1gKTtmb3IobGV0IEg9MDtIPFUubGVuZ3RoO0grKyl7bGV0IE09cVtIXTtpZihNIT09MCYmTSE9PTE1KWNvbnNvbGUud2FybihgZmFpbGVkIHRvIGltcG9ydCBtc2cgJHtLK0h9OiAke0RbTV19YCl9aWYoWClxdWV1ZU1pY3JvdGFzaygoKT0+WChPLFcubGVuZ3RoLDApKTt0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImltcG9ydCIsZG9uZTpPLHRvdGFsOlcubGVuZ3RofSksSz1PfXJldHVybiB0aGlzLnNjaGVkdWxlU3luYygpLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfTtzY2hlZHVsZVN5bmM9KCk9PntpZih0aGlzLm9uU2NoZWR1bGVTeW5jKXt0aGlzLm9uU2NoZWR1bGVTeW5jKCk7cmV0dXJufXRoaXMuc2NoZWR1bGVkU3luYy5zY2hlZHVsZSgpfTthc3luYyBleHBvcnRCeXRlcygpe2xldHtjcnlwdG86JCxzdG9yZTpafT10aGlzLEo9YXdhaXQgWi5zZWVkLmxvYWQoKTtpZighSilyZXR1cm4gRygyMik7bGV0IFE9YXdhaXQgWi5tZXNzYWdlcy5saXN0KCk7cmV0dXJuIGtKKCJleHBvcnQiLDAsUSwkLEopfWFzeW5jIGV4cG9ydCgkKXtsZXRbWixKXT1hd2FpdCB0aGlzLmV4cG9ydEJ5dGVzKCk7aWYoSiE9PTApcmV0dXJuIEo7aWYoIVopcmV0dXJuIDEyO2xldCBRPW5ldyBCbG9iKFtaLnNsaWNlKCldKTtyZXR1cm4gcEooUSwkKSwwfWFzeW5jIGxpbmsoJCxaPSEwKXtpZihhd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmFkZCgkKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKSxaKXtsZXQgSj1hd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmdldCgkLmxhYmVsKTtpZihKKWF3YWl0IHRoaXMuY29ubmVjdFRvSG9zdChKKX19YXN5bmMgdW5saW5rKCQpe2F3YWl0IHRoaXMuc3RvcmUuaG9zdHMuZGVsKCQpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpfWFzeW5jIGhvc3RzKCl7cmV0dXJuIEFycmF5LmZyb20oYXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5saXN0KCkpfWNvbm5lY3RUb0hvc3Q9YXN5bmMoJCxaPSEwLEo9ITApPT57bGV0e2Nsb2NrOlEsY29ubmVjdGlvbnM6WCxjcnlwdG86WSxzdG9yZTpWLHRyYW5zcG9ydDpXfT10aGlzLHo9WC5nZXQoJC5sYWJlbCk7aWYoeil7aWYoei5pc0Nvbm5lY3RlZCgpKXJldHVybjt0cnl7ei5jbG9zZUxpc3RlbmVyKCl9Y2F0Y2h7fVguZGVsZXRlKCQubGFiZWwpfWxldCBLPWF3YWl0IFYuc2VlZC5sb2FkKCk7aWYoIUspcmV0dXJuO2NvbnNvbGUuaW5mbyhgQ29ubmVjdGluZyB0byAkeyQuaGFuZGxlfSAoJHskLmxhYmVsfSlgKTtsZXQgRj1uZXcgTCQoSyxZLCQsUSxXKCQpLChOKT0+Vi5ob3N0cy5zZXQoJC5sYWJlbCxOKSk7aWYoYXdhaXQgRi5yZWdpc3RlcigpLFopYXdhaXQgRi5saXN0ZW4oYXN5bmMoTik9PntsZXQgTz17Y29ubjpGLHN0b3JlOlYsZW5jbGF2ZTpLLGhvc3Q6JCxjcnlwdG86WSxtYXhQdXNoQnl0ZXM6dGhpcy5tYXhQdXNoQnl0ZXMsbWF4UHVsbEJ5dGVzOnRoaXMubWF4UHVsbEJ5dGVzLG9uUHJvZ3Jlc3M6dGhpcy5lbWl0UHJvZ3Jlc3MscGVla1Byb2dyZXNzRXZlcnk6dGhpcy5wZWVrUHJvZ3Jlc3NFdmVyeX07cmV0dXJuIGVKKE4sTyx0aGlzLnNjaGVkdWxlU3luYyl9LCgpPT50aGlzLmNsaWVudFN0YXRlLmVtaXQoKSwoKT0+dGhpcy5jbGllbnRTdGF0ZS5lbWl0KCkpO2lmKFguc2V0KCQubGFiZWwsRiksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksSil0aGlzLnNjaGVkdWxlU3luYygpfTthc3luYyBjb25uZWN0KCQ9ITAsWj0hMCl7bGV0e2Nvbm5lY3RUb0hvc3Q6SixzY2hlZHVsZVN5bmM6USxzdG9yZTpYfT10aGlzO2lmKCFhd2FpdCBYLnNlZWQubG9hZCgpKXJldHVybjthd2FpdCB0aGlzLmRyYWluQXBwbHlRdWV1ZSgpO2xldCBWPWF3YWl0IFguaG9zdHMubGlzdCgpO2ZvcihsZXQgVyBvZiBWKWF3YWl0IEooVywkLCExKTtpZihaKVEoKX1kaXNjb25uZWN0PWFzeW5jKCk9Pntmb3IobGV0ICQgb2YgdGhpcy5jb25uZWN0aW9ucy52YWx1ZXMoKSl0cnl7JC5jbG9zZUxpc3RlbmVyKCl9Y2F0Y2h7fXRoaXMuY29ubmVjdGlvbnMuY2xlYXIoKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKX19dmFyIEIwPXR5cGVvZiBnbG9iYWxUaGlzPT09Im9iamVjdCImJiJjcnlwdG8iaW4gZ2xvYmFsVGhpcz9nbG9iYWxUaGlzLmNyeXB0bzp2b2lkIDA7ZnVuY3Rpb24gYiQoJCl7aWYoIU51bWJlci5pc1NhZmVJbnRlZ2VyKCQpfHwkPDApdGhyb3cgRXJyb3IoInBvc2l0aXZlIGludGVnZXIgZXhwZWN0ZWQsIGdvdCAiKyQpfWZ1bmN0aW9uIGdaKCQpe3JldHVybiAkIGluc3RhbmNlb2YgVWludDhBcnJheXx8QXJyYXlCdWZmZXIuaXNWaWV3KCQpJiYkLmNvbnN0cnVjdG9yLm5hbWU9PT0iVWludDhBcnJheSJ9ZnVuY3Rpb24gZCgkLC4uLlope2lmKCFnWigkKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCIpO2lmKFoubGVuZ3RoPjAmJiFaLmluY2x1ZGVzKCQubGVuZ3RoKSl0aHJvdyBFcnJvcigiVWludDhBcnJheSBleHBlY3RlZCBvZiBsZW5ndGggIitaKyIsIGdvdCBsZW5ndGg9IiskLmxlbmd0aCl9ZnVuY3Rpb24gbVooJCxaPSEwKXtpZigkLmRlc3Ryb3llZCl0aHJvdyBFcnJvcigiSGFzaCBpbnN0YW5jZSBoYXMgYmVlbiBkZXN0cm95ZWQiKTtpZihaJiYkLmZpbmlzaGVkKXRocm93IEVycm9yKCJIYXNoI2RpZ2VzdCgpIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkIil9ZnVuY3Rpb24gJFEoJCxaKXtkKCQpO2xldCBKPVoub3V0cHV0TGVuO2lmKCQubGVuZ3RoPEopdGhyb3cgRXJyb3IoImRpZ2VzdEludG8oKSBleHBlY3RzIG91dHB1dCBidWZmZXIgb2YgbGVuZ3RoIGF0IGxlYXN0ICIrSil9ZnVuY3Rpb24gU1ooJCl7aWYodHlwZW9mICQhPT0iYm9vbGVhbiIpdGhyb3cgRXJyb3IoYGJvb2xlYW4gZXhwZWN0ZWQsIG5vdCAkeyR9YCl9LyohIG5vYmxlLWNpcGhlcnMgLSBNSVQgTGljZW5zZSAoYykgMjAyMyBQYXVsIE1pbGxlciAocGF1bG1pbGxyLmNvbSkgKi92YXIgTTA9KCQpPT5uZXcgVWludDMyQXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LE1hdGguZmxvb3IoJC5ieXRlTGVuZ3RoLzQpKTt2YXIgbVg9bmV3IFVpbnQ4QXJyYXkobmV3IFVpbnQzMkFycmF5KFsyODc0NTQwMjBdKS5idWZmZXIpWzBdPT09Njg7aWYoIW1YKXRocm93IEVycm9yKCJOb24gbGl0dGxlLWVuZGlhbiBoYXJkd2FyZSBpcyBub3Qgc3VwcG9ydGVkIik7ZnVuY3Rpb24gU1goJCl7aWYodHlwZW9mICQhPT0ic3RyaW5nIil0aHJvdyBFcnJvcigic3RyaW5nIGV4cGVjdGVkIik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSl9ZnVuY3Rpb24geSQoJCl7aWYodHlwZW9mICQ9PT0ic3RyaW5nIikkPVNYKCQpO2Vsc2UgaWYoZ1ooJCkpJD1oJCgkKTtlbHNlIHRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkLCBnb3QgIit0eXBlb2YgJCk7cmV0dXJuICR9ZnVuY3Rpb24gWlEoJCxaKXtpZihaPT1udWxsfHx0eXBlb2YgWiE9PSJvYmplY3QiKXRocm93IEVycm9yKCJvcHRpb25zIG11c3QgYmUgZGVmaW5lZCIpO3JldHVybiBPYmplY3QuYXNzaWduKCQsWil9ZnVuY3Rpb24gSlEoJCxaKXtpZigkLmxlbmd0aCE9PVoubGVuZ3RoKXJldHVybiExO2xldCBKPTA7Zm9yKGxldCBRPTA7UTwkLmxlbmd0aDtRKyspSnw9JFtRXV5aW1FdO3JldHVybiBKPT09MH12YXIgUVE9KCQsWik9PntmdW5jdGlvbiBKKFEsLi4uWCl7aWYoZChRKSwkLm5vbmNlTGVuZ3RoIT09dm9pZCAwKXtsZXQgRj1YWzBdO2lmKCFGKXRocm93IEVycm9yKCJub25jZSAvIGl2IHJlcXVpcmVkIik7aWYoJC52YXJTaXplTm9uY2UpZChGKTtlbHNlIGQoRiwkLm5vbmNlTGVuZ3RoKX1sZXQgWT0kLnRhZ0xlbmd0aDtpZihZJiZYWzFdIT09dm9pZCAwKWQoWFsxXSk7bGV0IFY9WihRLC4uLlgpLFc9KEYsTik9PntpZihOIT09dm9pZCAwKXtpZihGIT09Mil0aHJvdyBFcnJvcigiY2lwaGVyIG91dHB1dCBub3Qgc3VwcG9ydGVkIik7ZChOKX19LHo9ITE7cmV0dXJue2VuY3J5cHQoRixOKXtpZih6KXRocm93IEVycm9yKCJjYW5ub3QgZW5jcnlwdCgpIHR3aWNlIHdpdGggc2FtZSBrZXkgKyBub25jZSIpO3JldHVybiB6PSEwLGQoRiksVyhWLmVuY3J5cHQubGVuZ3RoLE4pLFYuZW5jcnlwdChGLE4pfSxkZWNyeXB0KEYsTil7aWYoZChGKSxZJiZGLmxlbmd0aDxZKXRocm93IEVycm9yKCJpbnZhbGlkIGNpcGhlcnRleHQgbGVuZ3RoOiBzbWFsbGVyIHRoYW4gdGFnTGVuZ3RoPSIrWSk7cmV0dXJuIFcoVi5kZWNyeXB0Lmxlbmd0aCxOKSxWLmRlY3J5cHQoRixOKX19fXJldHVybiBPYmplY3QuYXNzaWduKEosJCksSn07ZnVuY3Rpb24gdlooJCxaLEo9ITApe2lmKFo9PT12b2lkIDApcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpO2lmKFoubGVuZ3RoIT09JCl0aHJvdyBFcnJvcigiaW52YWxpZCBvdXRwdXQgbGVuZ3RoLCBleHBlY3RlZCAiKyQrIiwgZ290OiAiK1oubGVuZ3RoKTtpZihKJiYhdlgoWikpdGhyb3cgRXJyb3IoImludmFsaWQgb3V0cHV0LCBtdXN0IGJlIGFsaWduZWQiKTtyZXR1cm4gWn1mdW5jdGlvbiB2WCgkKXtyZXR1cm4gJC5ieXRlT2Zmc2V0JTQ9PT0wfWZ1bmN0aW9uIGgkKCQpe3JldHVybiBVaW50OEFycmF5LmZyb20oJCl9ZnVuY3Rpb24gVTAoLi4uJCl7Zm9yKGxldCBaPTA7WjwkLmxlbmd0aDtaKyspJFtaXS5maWxsKDApfWZ1bmN0aW9uIGkkKCQ9MzIpe2lmKEIwJiZ0eXBlb2YgQjAuZ2V0UmFuZG9tVmFsdWVzPT09ImZ1bmN0aW9uIilyZXR1cm4gQjAuZ2V0UmFuZG9tVmFsdWVzKG5ldyBVaW50OEFycmF5KCQpKTtpZihCMCYmdHlwZW9mIEIwLnJhbmRvbUJ5dGVzPT09ImZ1bmN0aW9uIilyZXR1cm4gQjAucmFuZG9tQnl0ZXMoJCk7dGhyb3cgRXJyb3IoImNyeXB0by5nZXRSYW5kb21WYWx1ZXMgbXVzdCBiZSBkZWZpbmVkIil9dmFyIFlRPSgkKT0+VWludDhBcnJheS5mcm9tKCQuc3BsaXQoIiIpLm1hcCgoWik9PlouY2hhckNvZGVBdCgwKSkpLGJYPVlRKCJleHBhbmQgMTYtYnl0ZSBrIikseVg9WVEoImV4cGFuZCAzMi1ieXRlIGsiKSxoWD1NMChiWCksaVg9TTAoeVgpO2Z1bmN0aW9uIGooJCxaKXtyZXR1cm4gJDw8WnwkPj4+MzItWn1mdW5jdGlvbiBiWigkKXtyZXR1cm4gJC5ieXRlT2Zmc2V0JTQ9PT0wfXZhciBsJD02NCxsWD0xNixWUT00Mjk0OTY3Mjk1LFhRPW5ldyBVaW50MzJBcnJheTtmdW5jdGlvbiB1WCgkLFosSixRLFgsWSxWLFcpe2xldCB6PVgubGVuZ3RoLEs9bmV3IFVpbnQ4QXJyYXkobCQpLEY9TTAoSyksTj1iWihYKSYmYlooWSksTz1OP00wKFgpOlhRLFU9Tj9NMChZKTpYUTtmb3IobGV0IHE9MDtxPHo7VisrKXtpZigkKFosSixRLEYsVixXKSxWPj1WUSl0aHJvdyBFcnJvcigiYXJ4OiBjb3VudGVyIG92ZXJmbG93Iik7bGV0IEg9TWF0aC5taW4obCQsei1xKTtpZihOJiZIPT09bCQpe2xldCBNPXEvNDtpZihxJTQhPT0wKXRocm93IEVycm9yKCJhcng6IGludmFsaWQgYmxvY2sgcG9zaXRpb24iKTtmb3IobGV0IFA9MCxDO1A8bFg7UCsrKUM9TStQLFVbQ109T1tDXV5GW1BdO3ErPWwkO2NvbnRpbnVlfWZvcihsZXQgTT0wLFA7TTxIO00rKylQPXErTSxZW1BdPVhbUF1eS1tNXTtxKz1IfX1mdW5jdGlvbiBXUSgkLFope2xldHthbGxvd1Nob3J0S2V5czpKLGV4dGVuZE5vbmNlRm46USxjb3VudGVyTGVuZ3RoOlgsY291bnRlclJpZ2h0Olkscm91bmRzOlZ9PVpRKHthbGxvd1Nob3J0S2V5czohMSxjb3VudGVyTGVuZ3RoOjgsY291bnRlclJpZ2h0OiExLHJvdW5kczoyMH0sWik7aWYodHlwZW9mICQhPT0iZnVuY3Rpb24iKXRocm93IEVycm9yKCJjb3JlIG11c3QgYmUgYSBmdW5jdGlvbiIpO3JldHVybiBiJChYKSxiJChWKSxTWihZKSxTWihKKSwoVyx6LEssRixOPTApPT57ZChXKSxkKHopLGQoSyk7bGV0IE89Sy5sZW5ndGg7aWYoRj09PXZvaWQgMClGPW5ldyBVaW50OEFycmF5KE8pO2lmKGQoRiksYiQoTiksTjwwfHxOPj1WUSl0aHJvdyBFcnJvcigiYXJ4OiBjb3VudGVyIG92ZXJmbG93Iik7aWYoRi5sZW5ndGg8Tyl0aHJvdyBFcnJvcihgYXJ4OiBvdXRwdXQgKCR7Ri5sZW5ndGh9KSBpcyBzaG9ydGVyIHRoYW4gZGF0YSAoJHtPfSlgKTtsZXQgVT1bXSxxPVcubGVuZ3RoLEgsTTtpZihxPT09MzIpVS5wdXNoKEg9aCQoVykpLE09aVg7ZWxzZSBpZihxPT09MTYmJkopSD1uZXcgVWludDhBcnJheSgzMiksSC5zZXQoVyksSC5zZXQoVywxNiksTT1oWCxVLnB1c2goSCk7ZWxzZSB0aHJvdyBFcnJvcihgYXJ4OiBpbnZhbGlkIDMyLWJ5dGUga2V5LCBnb3QgbGVuZ3RoPSR7cX1gKTtpZighYlooeikpVS5wdXNoKHo9aCQoeikpO2xldCBQPU0wKEgpO2lmKFEpe2lmKHoubGVuZ3RoIT09MjQpdGhyb3cgRXJyb3IoImFyeDogZXh0ZW5kZWQgbm9uY2UgbXVzdCBiZSAyNCBieXRlcyIpO1EoTSxQLE0wKHouc3ViYXJyYXkoMCwxNikpLFApLHo9ei5zdWJhcnJheSgxNil9bGV0IEM9MTYtWDtpZihDIT09ei5sZW5ndGgpdGhyb3cgRXJyb3IoYGFyeDogbm9uY2UgbXVzdCBiZSAke0N9IG9yIDE2IGJ5dGVzYCk7aWYoQyE9PTEyKXtsZXQgST1uZXcgVWludDhBcnJheSgxMik7SS5zZXQoeixZPzA6MTItei5sZW5ndGgpLHo9SSxVLnB1c2goeil9bGV0IFQ9TTAoeik7cmV0dXJuIHVYKCQsTSxQLFQsSyxGLE4sViksVTAoLi4uVSksRn19dmFyIG89KCQsWik9PiRbWisrXSYyNTV8KCRbWisrXSYyNTUpPDw4O2NsYXNzIEdRe2NvbnN0cnVjdG9yKCQpe3RoaXMuYmxvY2tMZW49MTYsdGhpcy5vdXRwdXRMZW49MTYsdGhpcy5idWZmZXI9bmV3IFVpbnQ4QXJyYXkoMTYpLHRoaXMucj1uZXcgVWludDE2QXJyYXkoMTApLHRoaXMuaD1uZXcgVWludDE2QXJyYXkoMTApLHRoaXMucGFkPW5ldyBVaW50MTZBcnJheSg4KSx0aGlzLnBvcz0wLHRoaXMuZmluaXNoZWQ9ITEsJD15JCgkKSxkKCQsMzIpO2xldCBaPW8oJCwwKSxKPW8oJCwyKSxRPW8oJCw0KSxYPW8oJCw2KSxZPW8oJCw4KSxWPW8oJCwxMCksVz1vKCQsMTIpLHo9bygkLDE0KTt0aGlzLnJbMF09WiY4MTkxLHRoaXMuclsxXT0oWj4+PjEzfEo8PDMpJjgxOTEsdGhpcy5yWzJdPShKPj4+MTB8UTw8NikmNzkzOSx0aGlzLnJbM109KFE+Pj43fFg8PDkpJjgxOTEsdGhpcy5yWzRdPShYPj4+NHxZPDwxMikmMjU1LHRoaXMucls1XT1ZPj4+MSY4MTkwLHRoaXMucls2XT0oWT4+PjE0fFY8PDIpJjgxOTEsdGhpcy5yWzddPShWPj4+MTF8Vzw8NSkmODA2NSx0aGlzLnJbOF09KFc+Pj44fHo8PDgpJjgxOTEsdGhpcy5yWzldPXo+Pj41JjEyNztmb3IobGV0IEs9MDtLPDg7SysrKXRoaXMucGFkW0tdPW8oJCwxNisyKkspfXByb2Nlc3MoJCxaLEo9ITEpe2xldCBRPUo/MDoyMDQ4LHtoOlgscjpZfT10aGlzLFY9WVswXSxXPVlbMV0sej1ZWzJdLEs9WVszXSxGPVlbNF0sTj1ZWzVdLE89WVs2XSxVPVlbN10scT1ZWzhdLEg9WVs5XSxNPW8oJCxaKzApLFA9bygkLForMiksQz1vKCQsWis0KSxUPW8oJCxaKzYpLEk9bygkLForOCksQT1vKCQsWisxMCkseD1vKCQsWisxMiksZz1vKCQsWisxNCksZj1YWzBdKyhNJjgxOTEpLGs9WFsxXSsoKE0+Pj4xM3xQPDwzKSY4MTkxKSxiPVhbMl0rKChQPj4+MTB8Qzw8NikmODE5MSksdz1YWzNdKygoQz4+Pjd8VDw8OSkmODE5MSksaT1YWzRdKygoVD4+PjR8STw8MTIpJjgxOTEpLHU9WFs1XSsoST4+PjEmODE5MSksTD1YWzZdKygoST4+PjE0fEE8PDIpJjgxOTEpLHY9WFs3XSsoKEE+Pj4xMXx4PDw1KSY4MTkxKSxFPVhbOF0rKCh4Pj4+OHxnPDw4KSY4MTkxKSx5PVhbOV0rKGc+Pj41fFEpLF89MCxuPV8rZipWK2sqKDUqSCkrYiooNSpxKSt3Kig1KlUpK2kqKDUqTyk7Xz1uPj4+MTMsbiY9ODE5MSxuKz11Kig1Kk4pK0wqKDUqRikrdiooNSpLKStFKig1KnopK3kqKDUqVyksXys9bj4+PjEzLG4mPTgxOTE7bGV0IHM9XytmKlcraypWK2IqKDUqSCkrdyooNSpxKStpKig1KlUpO189cz4+PjEzLHMmPTgxOTEscys9dSooNSpPKStMKig1Kk4pK3YqKDUqRikrRSooNSpLKSt5Kig1KnopLF8rPXM+Pj4xMyxzJj04MTkxO2xldCBYMD1fK2YqeitrKlcrYipWK3cqKDUqSCkraSooNSpxKTtfPVgwPj4+MTMsWDAmPTgxOTEsWDArPXUqKDUqVSkrTCooNSpPKSt2Kig1Kk4pK0UqKDUqRikreSooNSpLKSxfKz1YMD4+PjEzLFgwJj04MTkxO2xldCBwPV8rZipLK2sqeitiKlcrdypWK2kqKDUqSCk7Xz1wPj4+MTMscCY9ODE5MSxwKz11Kig1KnEpK0wqKDUqVSkrdiooNSpPKStFKig1Kk4pK3kqKDUqRiksXys9cD4+PjEzLHAmPTgxOTE7bGV0IEgwPV8rZipGK2sqSytiKnordypXK2kqVjtfPUgwPj4+MTMsSDAmPTgxOTEsSDArPXUqKDUqSCkrTCooNSpxKSt2Kig1KlUpK0UqKDUqTykreSooNSpOKSxfKz1IMD4+PjEzLEgwJj04MTkxO2xldCB5MD1fK2YqTitrKkYrYipLK3cqeitpKlc7Xz15MD4+PjEzLHkwJj04MTkxLHkwKz11KlYrTCooNSpIKSt2Kig1KnEpK0UqKDUqVSkreSooNSpPKSxfKz15MD4+PjEzLHkwJj04MTkxO2xldCBoMD1fK2YqTytrKk4rYipGK3cqSytpKno7Xz1oMD4+PjEzLGgwJj04MTkxLGgwKz11KlcrTCpWK3YqKDUqSCkrRSooNSpxKSt5Kig1KlUpLF8rPWgwPj4+MTMsaDAmPTgxOTE7bGV0IGkwPV8rZipVK2sqTytiKk4rdypGK2kqSztfPWkwPj4+MTMsaTAmPTgxOTEsaTArPXUqeitMKlcrdipWK0UqKDUqSCkreSooNSpxKSxfKz1pMD4+PjEzLGkwJj04MTkxO2xldCBsMD1fK2YqcStrKlUrYipPK3cqTitpKkY7Xz1sMD4+PjEzLGwwJj04MTkxLGwwKz11KksrTCp6K3YqVytFKlYreSooNSpIKSxfKz1sMD4+PjEzLGwwJj04MTkxO2xldCB1MD1fK2YqSCtrKnErYipVK3cqTytpKk47Xz11MD4+PjEzLHUwJj04MTkxLHUwKz11KkYrTCpLK3YqeitFKlcreSpWLF8rPXUwPj4+MTMsdTAmPTgxOTEsXz0oXzw8MikrX3wwLF89XytufDAsbj1fJjgxOTEsXz1fPj4+MTMscys9XyxYWzBdPW4sWFsxXT1zLFhbMl09WDAsWFszXT1wLFhbNF09SDAsWFs1XT15MCxYWzZdPWgwLFhbN109aTAsWFs4XT1sMCxYWzldPXUwfWZpbmFsaXplKCl7bGV0e2g6JCxwYWQ6Wn09dGhpcyxKPW5ldyBVaW50MTZBcnJheSgxMCksUT0kWzFdPj4+MTM7JFsxXSY9ODE5MTtmb3IobGV0IFY9MjtWPDEwO1YrKykkW1ZdKz1RLFE9JFtWXT4+PjEzLCRbVl0mPTgxOTE7JFswXSs9USo1LFE9JFswXT4+PjEzLCRbMF0mPTgxOTEsJFsxXSs9USxRPSRbMV0+Pj4xMywkWzFdJj04MTkxLCRbMl0rPVEsSlswXT0kWzBdKzUsUT1KWzBdPj4+MTMsSlswXSY9ODE5MTtmb3IobGV0IFY9MTtWPDEwO1YrKylKW1ZdPSRbVl0rUSxRPUpbVl0+Pj4xMyxKW1ZdJj04MTkxO0pbOV0tPTgxOTI7bGV0IFg9KFFeMSktMTtmb3IobGV0IFY9MDtWPDEwO1YrKylKW1ZdJj1YO1g9flg7Zm9yKGxldCBWPTA7VjwxMDtWKyspJFtWXT0kW1ZdJlh8SltWXTskWzBdPSgkWzBdfCRbMV08PDEzKSY2NTUzNSwkWzFdPSgkWzFdPj4+M3wkWzJdPDwxMCkmNjU1MzUsJFsyXT0oJFsyXT4+PjZ8JFszXTw8NykmNjU1MzUsJFszXT0oJFszXT4+Pjl8JFs0XTw8NCkmNjU1MzUsJFs0XT0oJFs0XT4+PjEyfCRbNV08PDF8JFs2XTw8MTQpJjY1NTM1LCRbNV09KCRbNl0+Pj4yfCRbN108PDExKSY2NTUzNSwkWzZdPSgkWzddPj4+NXwkWzhdPDw4KSY2NTUzNSwkWzddPSgkWzhdPj4+OHwkWzldPDw1KSY2NTUzNTtsZXQgWT0kWzBdK1pbMF07JFswXT1ZJjY1NTM1O2ZvcihsZXQgVj0xO1Y8ODtWKyspWT0oJFtWXStaW1ZdfDApKyhZPj4+MTYpfDAsJFtWXT1ZJjY1NTM1O1UwKEopfXVwZGF0ZSgkKXttWih0aGlzKTtsZXR7YnVmZmVyOlosYmxvY2tMZW46Sn09dGhpczskPXkkKCQpO2xldCBRPSQubGVuZ3RoO2ZvcihsZXQgWD0wO1g8UTspe2xldCBZPU1hdGgubWluKEotdGhpcy5wb3MsUS1YKTtpZihZPT09Sil7Zm9yKDtKPD1RLVg7WCs9Sil0aGlzLnByb2Nlc3MoJCxYKTtjb250aW51ZX1pZihaLnNldCgkLnN1YmFycmF5KFgsWCtZKSx0aGlzLnBvcyksdGhpcy5wb3MrPVksWCs9WSx0aGlzLnBvcz09PUopdGhpcy5wcm9jZXNzKFosMCwhMSksdGhpcy5wb3M9MH1yZXR1cm4gdGhpc31kZXN0cm95KCl7VTAodGhpcy5oLHRoaXMucix0aGlzLmJ1ZmZlcix0aGlzLnBhZCl9ZGlnZXN0SW50bygkKXttWih0aGlzKSwkUSgkLHRoaXMpLHRoaXMuZmluaXNoZWQ9ITA7bGV0e2J1ZmZlcjpaLGg6Sn09dGhpcyx7cG9zOlF9PXRoaXM7aWYoUSl7WltRKytdPTE7Zm9yKDtRPDE2O1ErKylaW1FdPTA7dGhpcy5wcm9jZXNzKFosMCwhMCl9dGhpcy5maW5hbGl6ZSgpO2xldCBYPTA7Zm9yKGxldCBZPTA7WTw4O1krKykkW1grK109SltZXT4+PjAsJFtYKytdPUpbWV0+Pj44O3JldHVybiAkfWRpZ2VzdCgpe2xldHtidWZmZXI6JCxvdXRwdXRMZW46Wn09dGhpczt0aGlzLmRpZ2VzdEludG8oJCk7bGV0IEo9JC5zbGljZSgwLFopO3JldHVybiB0aGlzLmRlc3Ryb3koKSxKfX1mdW5jdGlvbiBwWCgkKXtsZXQgWj0oUSxYKT0+JChYKS51cGRhdGUoeSQoUSkpLmRpZ2VzdCgpLEo9JChuZXcgVWludDhBcnJheSgzMikpO3JldHVybiBaLm91dHB1dExlbj1KLm91dHB1dExlbixaLmJsb2NrTGVuPUouYmxvY2tMZW4sWi5jcmVhdGU9KFEpPT4kKFEpLFp9dmFyIHlaPXBYKCgkKT0+bmV3IEdRKCQpKTtmdW5jdGlvbiBjWCgkLFosSixRLFgsWT0yMCl7bGV0IFY9JFswXSxXPVpbMF0sej1aWzFdLEs9WlsyXSxGPVpbM10sTj0kWzFdLE89SlswXSxVPUpbMV0scT1YLEg9MCxNPSRbMl0sUD1aWzRdLEM9Wls1XSxUPVpbNl0sST1aWzddLEE9JFszXSx4PVYsZz1XLGY9eixrPUssYj1GLHc9TixpPU8sdT1VLEw9cSx2PUgsRT1NLHk9UCxfPUMsbj1ULHM9SSxYMD1BO2ZvcihsZXQgSDA9MDtIMDxZO0gwKz0yKWJePWooeCtffDAsNyksTF49aihiK3h8MCw5KSxfXj1qKEwrYnwwLDEzKSx4Xj1qKF8rTHwwLDE4KSx2Xj1qKHcrZ3wwLDcpLG5ePWoodit3fDAsOSksZ149aihuK3Z8MCwxMyksd149aihnK258MCwxOCksc149aihFK2l8MCw3KSxmXj1qKHMrRXwwLDkpLGlePWooZitzfDAsMTMpLEVePWooaStmfDAsMTgpLGtePWooWDAreXwwLDcpLHVePWooaytYMHwwLDkpLHlePWoodStrfDAsMTMpLFgwXj1qKHkrdXwwLDE4KSxnXj1qKHgra3wwLDcpLGZePWooZyt4fDAsOSksa149aihmK2d8MCwxMykseF49aihrK2Z8MCwxOCksaV49aih3K2J8MCw3KSx1Xj1qKGkrd3wwLDkpLGJePWoodStpfDAsMTMpLHdePWooYit1fDAsMTgpLHlePWooRSt2fDAsNyksTF49aih5K0V8MCw5KSx2Xj1qKEwreXwwLDEzKSxFXj1qKHYrTHwwLDE4KSxfXj1qKFgwK3N8MCw3KSxuXj1qKF8rWDB8MCw5KSxzXj1qKG4rX3wwLDEzKSxYMF49aihzK258MCwxOCk7bGV0IHA9MDtRW3ArK109Vit4fDAsUVtwKytdPVcrZ3wwLFFbcCsrXT16K2Z8MCxRW3ArK109SytrfDAsUVtwKytdPUYrYnwwLFFbcCsrXT1OK3d8MCxRW3ArK109TytpfDAsUVtwKytdPVUrdXwwLFFbcCsrXT1xK0x8MCxRW3ArK109SCt2fDAsUVtwKytdPU0rRXwwLFFbcCsrXT1QK3l8MCxRW3ArK109QytffDAsUVtwKytdPVQrbnwwLFFbcCsrXT1JK3N8MCxRW3ArK109QStYMHwwfWZ1bmN0aW9uIG5YKCQsWixKLFEpe2xldCBYPSRbMF0sWT1aWzBdLFY9WlsxXSxXPVpbMl0sej1aWzNdLEs9JFsxXSxGPUpbMF0sTj1KWzFdLE89SlsyXSxVPUpbM10scT0kWzJdLEg9Wls0XSxNPVpbNV0sUD1aWzZdLEM9Wls3XSxUPSRbM107Zm9yKGxldCBBPTA7QTwyMDtBKz0yKXpePWooWCtNfDAsNyksT149aih6K1h8MCw5KSxNXj1qKE8renwwLDEzKSxYXj1qKE0rT3wwLDE4KSxVXj1qKEsrWXwwLDcpLFBePWooVStLfDAsOSksWV49aihQK1V8MCwxMyksS149aihZK1B8MCwxOCksQ149aihxK0Z8MCw3KSxWXj1qKEMrcXwwLDkpLEZePWooVitDfDAsMTMpLHFePWooRitWfDAsMTgpLFdePWooVCtIfDAsNyksTl49aihXK1R8MCw5KSxIXj1qKE4rV3wwLDEzKSxUXj1qKEgrTnwwLDE4KSxZXj1qKFgrV3wwLDcpLFZePWooWStYfDAsOSksV149aihWK1l8MCwxMyksWF49aihXK1Z8MCwxOCksRl49aihLK3p8MCw3KSxOXj1qKEYrS3wwLDkpLHpePWooTitGfDAsMTMpLEtePWooeitOfDAsMTgpLEhePWoocStVfDAsNyksT149aihIK3F8MCw5KSxVXj1qKE8rSHwwLDEzKSxxXj1qKFUrT3wwLDE4KSxNXj1qKFQrQ3wwLDcpLFBePWooTStUfDAsOSksQ149aihQK018MCwxMyksVF49aihDK1B8MCwxOCk7bGV0IEk9MDtRW0krK109WCxRW0krK109SyxRW0krK109cSxRW0krK109VCxRW0krK109RixRW0krK109TixRW0krK109TyxRW0krK109VX12YXIgaFo9V1EoY1gse2NvdW50ZXJSaWdodDohMCxleHRlbmROb25jZUZuOm5YfSksaVo9UVEoe2Jsb2NrU2l6ZTo2NCxub25jZUxlbmd0aDoyNCx0YWdMZW5ndGg6MTZ9LCgkLFopPT57cmV0dXJue2VuY3J5cHQoSixRKXtRPXZaKEoubGVuZ3RoKzMyLFEsITEpO2xldCBYPVEuc3ViYXJyYXkoMCwzMiksWT1RLnN1YmFycmF5KDMyKTtRLnNldChKLDMyKSxVMChYKSxoWigkLFosUSxRKTtsZXQgVj15WihZLFgpO3JldHVybiBRLnNldChWLDE2KSxVMChRLnN1YmFycmF5KDAsMTYpLFYpLFEuc3ViYXJyYXkoMTYpfSxkZWNyeXB0KEosUSl7ZChKKSxRPXZaKEoubGVuZ3RoKzMyLFEsITEpO2xldCBYPVEuc3ViYXJyYXkoMCwzMiksWT1RLnN1YmFycmF5KDMyLDQ4KSxWPVEuc3ViYXJyYXkoNDgpO1Euc2V0KEosMzIpLFUwKFgpO2xldCBXPWhaKCQsWixYLFgpLHo9eVooVixXKTtpZighSlEoWSx6KSl0aHJvdyBFcnJvcigiaW52YWxpZCB0YWciKTtyZXR1cm4gaFooJCxaLFEuc3ViYXJyYXkoMTYpLFEuc3ViYXJyYXkoMTYpKSxVMChYLFkseiksVn19fSk7LyohIG5vYmxlLWhhc2hlcyAtIE1JVCBMaWNlbnNlIChjKSAyMDIyIFBhdWwgTWlsbGVyIChwYXVsbWlsbHIuY29tKSAqL2Z1bmN0aW9uIGRYKCQpe3JldHVybiAkIGluc3RhbmNlb2YgVWludDhBcnJheXx8QXJyYXlCdWZmZXIuaXNWaWV3KCQpJiYkLmNvbnN0cnVjdG9yLm5hbWU9PT0iVWludDhBcnJheSJ9ZnVuY3Rpb24gTiQoJCl7aWYoIU51bWJlci5pc1NhZmVJbnRlZ2VyKCQpfHwkPDApdGhyb3cgRXJyb3IoInBvc2l0aXZlIGludGVnZXIgZXhwZWN0ZWQsIGdvdCAiKyQpfWZ1bmN0aW9uIGswKCQsLi4uWil7aWYoIWRYKCQpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIik7aWYoWi5sZW5ndGg+MCYmIVouaW5jbHVkZXMoJC5sZW5ndGgpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIG9mIGxlbmd0aCAiK1orIiwgZ290IGxlbmd0aD0iKyQubGVuZ3RoKX1mdW5jdGlvbiBSJCgkLFo9ITApe2lmKCQuZGVzdHJveWVkKXRocm93IEVycm9yKCJIYXNoIGluc3RhbmNlIGhhcyBiZWVuIGRlc3Ryb3llZCIpO2lmKFomJiQuZmluaXNoZWQpdGhyb3cgRXJyb3IoIkhhc2gjZGlnZXN0KCkgaGFzIGFscmVhZHkgYmVlbiBjYWxsZWQiKX1mdW5jdGlvbiB1JCgkLFope2swKCQpO2xldCBKPVoub3V0cHV0TGVuO2lmKCQubGVuZ3RoPEopdGhyb3cgRXJyb3IoImRpZ2VzdEludG8oKSBleHBlY3RzIG91dHB1dCBidWZmZXIgb2YgbGVuZ3RoIGF0IGxlYXN0ICIrSil9ZnVuY3Rpb24gelEoJCl7cmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpfWZ1bmN0aW9uICQkKCQpe3JldHVybiBuZXcgVWludDMyQXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LE1hdGguZmxvb3IoJC5ieXRlTGVuZ3RoLzQpKX1mdW5jdGlvbiBaJCguLi4kKXtmb3IobGV0IFo9MDtaPCQubGVuZ3RoO1orKykkW1pdLmZpbGwoMCl9ZnVuY3Rpb24gTyQoJCxaKXtyZXR1cm4gJDw8MzItWnwkPj4+Wn12YXIgS1E9KCgpPT5uZXcgVWludDhBcnJheShuZXcgVWludDMyQXJyYXkoWzI4NzQ1NDAyMF0pLmJ1ZmZlcilbMF09PT02OCkoKTtmdW5jdGlvbiBGUSgkKXtyZXR1cm4gJDw8MjQmNDI3ODE5MDA4MHwkPDw4JjE2NzExNjgwfCQ+Pj44JjY1MjgwfCQ+Pj4yNCYyNTV9dmFyIE5RPUtRPygkKT0+JDooJCk9PkZRKCQpO2Z1bmN0aW9uIHJYKCQpe2ZvcihsZXQgWj0wO1o8JC5sZW5ndGg7WisrKSRbWl09RlEoJFtaXSk7cmV0dXJuICR9dmFyICQwPUtRPygkKT0+JDpyWDtmdW5jdGlvbiBvWCgkKXtpZih0eXBlb2YgJCE9PSJzdHJpbmciKXRocm93IEVycm9yKCJzdHJpbmcgZXhwZWN0ZWQiKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkobmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpKX1mdW5jdGlvbiBKJCgkKXtpZih0eXBlb2YgJD09PSJzdHJpbmciKSQ9b1goJCk7cmV0dXJuIGswKCQpLCR9Y2xhc3MgbFp7fWZ1bmN0aW9uIFJRKCQpe2xldCBaPShRLFgpPT4kKFgpLnVwZGF0ZShKJChRKSkuZGlnZXN0KCksSj0kKHt9KTtyZXR1cm4gWi5vdXRwdXRMZW49Si5vdXRwdXRMZW4sWi5ibG9ja0xlbj1KLmJsb2NrTGVuLFouY3JlYXRlPShRKT0+JChRKSxafXZhciBPUT1VaW50MzJBcnJheS5mcm9tKFsxNzc5MDMzNzAzLDMxNDQxMzQyNzcsMTAxMzkwNDI0MiwyNzczNDgwNzYyLDEzNTk4OTMxMTksMjYwMDgyMjkyNCw1Mjg3MzQ2MzUsMTU0MTQ1OTIyNV0pO3ZhciBwJD1CaWdJbnQoNDI5NDk2NzI5NSksVVE9QmlnSW50KDMyKTtmdW5jdGlvbiB1WigkLFo9ITEpe2lmKFopcmV0dXJue2g6TnVtYmVyKCQmcCQpLGw6TnVtYmVyKCQ+PlVRJnAkKX07cmV0dXJue2g6TnVtYmVyKCQ+PlVRJnAkKXwwLGw6TnVtYmVyKCQmcCQpfDB9fWZ1bmN0aW9uIEkwKCQsWixKLFEsWCl7cmV0dXJuICQ9JCtaK1h8MCxRPU8kKFFeJCwxNiksSj1KK1F8MCxaPU8kKFpeSiwxMikse2E6JCxiOlosYzpKLGQ6UX19ZnVuY3Rpb24gQzAoJCxaLEosUSxYKXtyZXR1cm4gJD0kK1orWHwwLFE9TyQoUV4kLDgpLEo9SitRfDAsWj1PJChaXkosNykse2E6JCxiOlosYzpKLGQ6UX19Y2xhc3MgcFogZXh0ZW5kcyBsWntjb25zdHJ1Y3RvcigkLFope3N1cGVyKCk7dGhpcy5maW5pc2hlZD0hMSx0aGlzLmRlc3Ryb3llZD0hMSx0aGlzLmxlbmd0aD0wLHRoaXMucG9zPTAsTiQoJCksTiQoWiksdGhpcy5ibG9ja0xlbj0kLHRoaXMub3V0cHV0TGVuPVosdGhpcy5idWZmZXI9bmV3IFVpbnQ4QXJyYXkoJCksdGhpcy5idWZmZXIzMj0kJCh0aGlzLmJ1ZmZlcil9dXBkYXRlKCQpe1IkKHRoaXMpLCQ9SiQoJCksazAoJCk7bGV0e2Jsb2NrTGVuOlosYnVmZmVyOkosYnVmZmVyMzI6UX09dGhpcyxYPSQubGVuZ3RoLFk9JC5ieXRlT2Zmc2V0LFY9JC5idWZmZXI7Zm9yKGxldCBXPTA7VzxYOyl7aWYodGhpcy5wb3M9PT1aKSQwKFEpLHRoaXMuY29tcHJlc3MoUSwwLCExKSwkMChRKSx0aGlzLnBvcz0wO2xldCB6PU1hdGgubWluKFotdGhpcy5wb3MsWC1XKSxLPVkrVztpZih6PT09WiYmIShLJTQpJiZXK3o8WCl7bGV0IEY9bmV3IFVpbnQzMkFycmF5KFYsSyxNYXRoLmZsb29yKChYLVcpLzQpKTskMChGKTtmb3IobGV0IE49MDtXK1o8WDtOKz1RLmxlbmd0aCxXKz1aKXRoaXMubGVuZ3RoKz1aLHRoaXMuY29tcHJlc3MoRixOLCExKTskMChGKTtjb250aW51ZX1KLnNldCgkLnN1YmFycmF5KFcsVyt6KSx0aGlzLnBvcyksdGhpcy5wb3MrPXosdGhpcy5sZW5ndGgrPXosVys9en1yZXR1cm4gdGhpc31kaWdlc3RJbnRvKCQpe1IkKHRoaXMpLHUkKCQsdGhpcyk7bGV0e3BvczpaLGJ1ZmZlcjMyOkp9PXRoaXM7dGhpcy5maW5pc2hlZD0hMCxaJCh0aGlzLmJ1ZmZlci5zdWJhcnJheShaKSksJDAoSiksdGhpcy5jb21wcmVzcyhKLDAsITApLCQwKEopO2xldCBRPSQkKCQpO3RoaXMuZ2V0KCkuZm9yRWFjaCgoWCxZKT0+UVtZXT1OUShYKSl9ZGlnZXN0KCl7bGV0e2J1ZmZlcjokLG91dHB1dExlbjpafT10aGlzO3RoaXMuZGlnZXN0SW50bygkKTtsZXQgSj0kLnNsaWNlKDAsWik7cmV0dXJuIHRoaXMuZGVzdHJveSgpLEp9X2Nsb25lSW50bygkKXtsZXR7YnVmZmVyOlosbGVuZ3RoOkosZmluaXNoZWQ6USxkZXN0cm95ZWQ6WCxvdXRwdXRMZW46WSxwb3M6Vn09dGhpcztyZXR1cm4gJHx8KCQ9bmV3IHRoaXMuY29uc3RydWN0b3Ioe2RrTGVuOll9KSksJC5zZXQoLi4udGhpcy5nZXQoKSksJC5idWZmZXIuc2V0KFopLCQuZGVzdHJveWVkPVgsJC5maW5pc2hlZD1RLCQubGVuZ3RoPUosJC5wb3M9ViwkLm91dHB1dExlbj1ZLCR9Y2xvbmUoKXtyZXR1cm4gdGhpcy5fY2xvbmVJbnRvKCl9fWZ1bmN0aW9uIGNaKCQsWixKLFEsWCxZLFYsVyx6LEssRixOLE8sVSxxLEgsTSxQLEMsVCl7bGV0IEk9MDtmb3IobGV0IEE9MDtBPFE7QSsrKSh7YTpYLGI6eixjOk8sZDpNfT1JMChYLHosTyxNLEpbWiskW0krK11dKSkse2E6WCxiOnosYzpPLGQ6TX09QzAoWCx6LE8sTSxKW1orJFtJKytdXSkse2E6WSxiOkssYzpVLGQ6UH09STAoWSxLLFUsUCxKW1orJFtJKytdXSkse2E6WSxiOkssYzpVLGQ6UH09QzAoWSxLLFUsUCxKW1orJFtJKytdXSkse2E6VixiOkYsYzpxLGQ6Q309STAoVixGLHEsQyxKW1orJFtJKytdXSkse2E6VixiOkYsYzpxLGQ6Q309QzAoVixGLHEsQyxKW1orJFtJKytdXSkse2E6VyxiOk4sYzpILGQ6VH09STAoVyxOLEgsVCxKW1orJFtJKytdXSkse2E6VyxiOk4sYzpILGQ6VH09QzAoVyxOLEgsVCxKW1orJFtJKytdXSkse2E6WCxiOkssYzpxLGQ6VH09STAoWCxLLHEsVCxKW1orJFtJKytdXSkse2E6WCxiOkssYzpxLGQ6VH09QzAoWCxLLHEsVCxKW1orJFtJKytdXSkse2E6WSxiOkYsYzpILGQ6TX09STAoWSxGLEgsTSxKW1orJFtJKytdXSkse2E6WSxiOkYsYzpILGQ6TX09QzAoWSxGLEgsTSxKW1orJFtJKytdXSkse2E6VixiOk4sYzpPLGQ6UH09STAoVixOLE8sUCxKW1orJFtJKytdXSkse2E6VixiOk4sYzpPLGQ6UH09QzAoVixOLE8sUCxKW1orJFtJKytdXSkse2E6VyxiOnosYzpVLGQ6Q309STAoVyx6LFUsQyxKW1orJFtJKytdXSkse2E6VyxiOnosYzpVLGQ6Q309QzAoVyx6LFUsQyxKW1orJFtJKytdXSk7cmV0dXJue3YwOlgsdjE6WSx2MjpWLHYzOlcsdjQ6eix2NTpLLHY2OkYsdjc6Tix2ODpPLHY5OlUsdjEwOnEsdjExOkgsdjEyOk0sdjEzOlAsdjE0OkMsdjE1OlR9fXZhciBxMD17Q0hVTktfU1RBUlQ6MSxDSFVOS19FTkQ6MixQQVJFTlQ6NCxST09UOjgsS0VZRURfSEFTSDoxNixERVJJVkVfS0VZX0NPTlRFWFQ6MzIsREVSSVZFX0tFWV9NQVRFUklBTDo2NH0sUDA9T1Euc2xpY2UoKSxxUT0oKCk9PntsZXQgJD1BcnJheS5mcm9tKHtsZW5ndGg6MTZ9LChRLFgpPT5YKSxaPShRKT0+WzIsNiwzLDEwLDcsMCw0LDEzLDEsMTEsMTIsNSw5LDE0LDE1LDhdLm1hcCgoWCk9PlFbWF0pLEo9W107Zm9yKGxldCBRPTAsWD0kO1E8NztRKyssWD1aKFgpKUoucHVzaCguLi5YKTtyZXR1cm4gVWludDhBcnJheS5mcm9tKEopfSkoKTtjbGFzcyBuWiBleHRlbmRzIHBae2NvbnN0cnVjdG9yKCQ9e30sWj0wKXtzdXBlcig2NCwkLmRrTGVuPT09dm9pZCAwPzMyOiQuZGtMZW4pO3RoaXMuY2h1bmtQb3M9MCx0aGlzLmNodW5rc0RvbmU9MCx0aGlzLmZsYWdzPTAsdGhpcy5zdGFjaz1bXSx0aGlzLnBvc091dD0wLHRoaXMuYnVmZmVyT3V0MzI9bmV3IFVpbnQzMkFycmF5KDE2KSx0aGlzLmNodW5rT3V0PTAsdGhpcy5lbmFibGVYT0Y9ITA7bGV0e2tleTpKLGNvbnRleHQ6UX09JCxYPVEhPT12b2lkIDA7aWYoSiE9PXZvaWQgMCl7aWYoWCl0aHJvdyBFcnJvcignT25seSAia2V5IiBvciAiY29udGV4dCIgY2FuIGJlIHNwZWNpZmllZCBhdCBzYW1lIHRpbWUnKTtsZXQgWT1KJChKKS5zbGljZSgpO2swKFksMzIpLHRoaXMuSVY9JCQoWSksJDAodGhpcy5JViksdGhpcy5mbGFncz1afHEwLktFWUVEX0hBU0h9ZWxzZSBpZihYKXtsZXQgWT1KJChRKSxWPW5ldyBuWih7ZGtMZW46MzJ9LHEwLkRFUklWRV9LRVlfQ09OVEVYVCkudXBkYXRlKFkpLmRpZ2VzdCgpO3RoaXMuSVY9JCQoViksJDAodGhpcy5JViksdGhpcy5mbGFncz1afHEwLkRFUklWRV9LRVlfTUFURVJJQUx9ZWxzZSB0aGlzLklWPVAwLnNsaWNlKCksdGhpcy5mbGFncz1aO3RoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpLHRoaXMuYnVmZmVyT3V0PXpRKHRoaXMuYnVmZmVyT3V0MzIpfWdldCgpe3JldHVybltdfXNldCgpe31iMkNvbXByZXNzKCQsWixKLFE9MCl7bGV0e3N0YXRlOlgscG9zOll9PXRoaXMse2g6VixsOld9PXVaKEJpZ0ludCgkKSwhMCkse3YwOnosdjE6Syx2MjpGLHYzOk4sdjQ6Tyx2NTpVLHY2OnEsdjc6SCx2ODpNLHY5OlAsdjEwOkMsdjExOlQsdjEyOkksdjEzOkEsdjE0OngsdjE1Omd9PWNaKHFRLFEsSiw3LFhbMF0sWFsxXSxYWzJdLFhbM10sWFs0XSxYWzVdLFhbNl0sWFs3XSxQMFswXSxQMFsxXSxQMFsyXSxQMFszXSxWLFcsWSxaKTtYWzBdPXpeTSxYWzFdPUteUCxYWzJdPUZeQyxYWzNdPU5eVCxYWzRdPU9eSSxYWzVdPVVeQSxYWzZdPXFeeCxYWzddPUheZ31jb21wcmVzcygkLFo9MCxKPSExKXtsZXQgUT10aGlzLmZsYWdzO2lmKCF0aGlzLmNodW5rUG9zKVF8PXEwLkNIVU5LX1NUQVJUO2lmKHRoaXMuY2h1bmtQb3M9PT0xNXx8SilRfD1xMC5DSFVOS19FTkQ7aWYoIUopdGhpcy5wb3M9dGhpcy5ibG9ja0xlbjtpZih0aGlzLmIyQ29tcHJlc3ModGhpcy5jaHVua3NEb25lLFEsJCxaKSx0aGlzLmNodW5rUG9zKz0xLHRoaXMuY2h1bmtQb3M9PT0xNnx8Sil7bGV0IFg9dGhpcy5zdGF0ZTt0aGlzLnN0YXRlPXRoaXMuSVYuc2xpY2UoKTtmb3IobGV0IFksVj10aGlzLmNodW5rc0RvbmUrMTtKfHwhKFYmMSk7Vj4+PTEpe2lmKCEoWT10aGlzLnN0YWNrLnBvcCgpKSlicmVhazt0aGlzLmJ1ZmZlcjMyLnNldChZLDApLHRoaXMuYnVmZmVyMzIuc2V0KFgsOCksdGhpcy5wb3M9dGhpcy5ibG9ja0xlbix0aGlzLmIyQ29tcHJlc3MoMCx0aGlzLmZsYWdzfHEwLlBBUkVOVCx0aGlzLmJ1ZmZlcjMyLDApLFg9dGhpcy5zdGF0ZSx0aGlzLnN0YXRlPXRoaXMuSVYuc2xpY2UoKX10aGlzLmNodW5rc0RvbmUrKyx0aGlzLmNodW5rUG9zPTAsdGhpcy5zdGFjay5wdXNoKFgpfXRoaXMucG9zPTB9X2Nsb25lSW50bygkKXskPXN1cGVyLl9jbG9uZUludG8oJCk7bGV0e0lWOlosZmxhZ3M6SixzdGF0ZTpRLGNodW5rUG9zOlgscG9zT3V0OlksY2h1bmtPdXQ6VixzdGFjazpXLGNodW5rc0RvbmU6en09dGhpcztyZXR1cm4gJC5zdGF0ZS5zZXQoUS5zbGljZSgpKSwkLnN0YWNrPVcubWFwKChLKT0+VWludDMyQXJyYXkuZnJvbShLKSksJC5JVi5zZXQoWiksJC5mbGFncz1KLCQuY2h1bmtQb3M9WCwkLmNodW5rc0RvbmU9eiwkLnBvc091dD1ZLCQuY2h1bmtPdXQ9ViwkLmVuYWJsZVhPRj10aGlzLmVuYWJsZVhPRiwkLmJ1ZmZlck91dDMyLnNldCh0aGlzLmJ1ZmZlck91dDMyKSwkfWRlc3Ryb3koKXt0aGlzLmRlc3Ryb3llZD0hMCxaJCh0aGlzLnN0YXRlLHRoaXMuYnVmZmVyMzIsdGhpcy5JVix0aGlzLmJ1ZmZlck91dDMyKSxaJCguLi50aGlzLnN0YWNrKX1iMkNvbXByZXNzT3V0KCl7bGV0e3N0YXRlOiQscG9zOlosZmxhZ3M6SixidWZmZXIzMjpRLGJ1ZmZlck91dDMyOlh9PXRoaXMse2g6WSxsOlZ9PXVaKEJpZ0ludCh0aGlzLmNodW5rT3V0KyspKTskMChRKTtsZXR7djA6Vyx2MTp6LHYyOkssdjM6Rix2NDpOLHY1Ok8sdjY6VSx2NzpxLHY4Okgsdjk6TSx2MTA6UCx2MTE6Qyx2MTI6VCx2MTM6SSx2MTQ6QSx2MTU6eH09Y1oocVEsMCxRLDcsJFswXSwkWzFdLCRbMl0sJFszXSwkWzRdLCRbNV0sJFs2XSwkWzddLFAwWzBdLFAwWzFdLFAwWzJdLFAwWzNdLFYsWSxaLEopO1hbMF09V15ILFhbMV09el5NLFhbMl09S15QLFhbM109Rl5DLFhbNF09Tl5ULFhbNV09T15JLFhbNl09VV5BLFhbN109cV54LFhbOF09JFswXV5ILFhbOV09JFsxXV5NLFhbMTBdPSRbMl1eUCxYWzExXT0kWzNdXkMsWFsxMl09JFs0XV5ULFhbMTNdPSRbNV1eSSxYWzE0XT0kWzZdXkEsWFsxNV09JFs3XV54LCQwKFEpLCQwKFgpLHRoaXMucG9zT3V0PTB9ZmluaXNoKCl7aWYodGhpcy5maW5pc2hlZClyZXR1cm47dGhpcy5maW5pc2hlZD0hMCxaJCh0aGlzLmJ1ZmZlci5zdWJhcnJheSh0aGlzLnBvcykpO2xldCAkPXRoaXMuZmxhZ3N8cTAuUk9PVDtpZih0aGlzLnN0YWNrLmxlbmd0aCkkfD1xMC5QQVJFTlQsJDAodGhpcy5idWZmZXIzMiksdGhpcy5jb21wcmVzcyh0aGlzLmJ1ZmZlcjMyLDAsITApLCQwKHRoaXMuYnVmZmVyMzIpLHRoaXMuY2h1bmtzRG9uZT0wLHRoaXMucG9zPXRoaXMuYmxvY2tMZW47ZWxzZSAkfD0oIXRoaXMuY2h1bmtQb3M/cTAuQ0hVTktfU1RBUlQ6MCl8cTAuQ0hVTktfRU5EO3RoaXMuZmxhZ3M9JCx0aGlzLmIyQ29tcHJlc3NPdXQoKX13cml0ZUludG8oJCl7UiQodGhpcywhMSksazAoJCksdGhpcy5maW5pc2goKTtsZXR7YmxvY2tMZW46WixidWZmZXJPdXQ6Sn09dGhpcztmb3IobGV0IFE9MCxYPSQubGVuZ3RoO1E8WDspe2lmKHRoaXMucG9zT3V0Pj1aKXRoaXMuYjJDb21wcmVzc091dCgpO2xldCBZPU1hdGgubWluKFotdGhpcy5wb3NPdXQsWC1RKTskLnNldChKLnN1YmFycmF5KHRoaXMucG9zT3V0LHRoaXMucG9zT3V0K1kpLFEpLHRoaXMucG9zT3V0Kz1ZLFErPVl9cmV0dXJuICR9eG9mSW50bygkKXtpZighdGhpcy5lbmFibGVYT0YpdGhyb3cgRXJyb3IoIlhPRiBpcyBub3QgcG9zc2libGUgYWZ0ZXIgZGlnZXN0IGNhbGwiKTtyZXR1cm4gdGhpcy53cml0ZUludG8oJCl9eG9mKCQpe3JldHVybiBOJCgkKSx0aGlzLnhvZkludG8obmV3IFVpbnQ4QXJyYXkoJCkpfWRpZ2VzdEludG8oJCl7aWYodSQoJCx0aGlzKSx0aGlzLmZpbmlzaGVkKXRocm93IEVycm9yKCJkaWdlc3QoKSB3YXMgYWxyZWFkeSBjYWxsZWQiKTtyZXR1cm4gdGhpcy5lbmFibGVYT0Y9ITEsdGhpcy53cml0ZUludG8oJCksdGhpcy5kZXN0cm95KCksJH1kaWdlc3QoKXtyZXR1cm4gdGhpcy5kaWdlc3RJbnRvKG5ldyBVaW50OEFycmF5KHRoaXMub3V0cHV0TGVuKSl9fXZhciBIUT1SUSgoJCk9Pm5ldyBuWigkKSk7dmFyIGRaPW5ldyBVaW50OEFycmF5KFs0OCw0NiwyLDEsMCw0OCw1LDYsMyw0MywxMDEsMTEyLDQsMzQsNCwzMl0pO2Z1bmN0aW9uIE1RKCQpe2xldCBaPW5ldyBVaW50OEFycmF5KGRaLmxlbmd0aCszMik7cmV0dXJuIFouc2V0KGRaKSxaLnNldCgkLnN1YmFycmF5KDAsMzIpLGRaLmxlbmd0aCksWn1mdW5jdGlvbiBJUSgkKXtyZXR1cm4gdHlwZW9mICQ9PT0ic3RyaW5nIj9uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCk6JH1mdW5jdGlvbiBRJCgkKXtsZXQgWj1uZXcgQXJyYXlCdWZmZXIoJC5ieXRlTGVuZ3RoKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWikuc2V0KCQpLFp9Y2xhc3MgVSR7dmVyaWZ5S2V5cz1uZXcgTWFwO2FzeW5jIGdlblJhbmRvbUJ5dGVzKCQpe3JldHVybiBpJCgkKX1hc3luYyBnZW4yNTZCaXRTZWN1cmVSYW5kb21TZWVkKCl7cmV0dXJuIGkkKDMyKX1hc3luYyBlbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKCQsWil7bGV0IEo9aSQoMjQpLFg9aVooWixKKS5lbmNyeXB0KCQpO3JldHVybiBuZXcgVWludDhBcnJheShbLi4uSiwuLi5YXSl9YXN5bmMgZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCgkLFope2xldCBKPSQuc2xpY2UoMCwyNCksUT0kLnNsaWNlKDI0KTtyZXR1cm4gaVooWixKKS5kZWNyeXB0KFEpfWFzeW5jIGRlcml2ZUVkMjU1MTlLZXlQYWlyKCQpe2xldCBaPSQsSj1NUShaKSxRPVEkKEopLFg7dHJ5e2xldCBLPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInBrY3M4IixRLHtuYW1lOiJFZDI1NTE5In0sITAsWyJzaWduIl0pO1g9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgiandrIixLKX1maW5hbGx5e0ouZmlsbCgwKSxuZXcgVWludDhBcnJheShRKS5maWxsKDApfWlmKHR5cGVvZiBYLnghPT0ic3RyaW5nIil0aHJvdyBFcnJvcigiRWQyNTUxOSBKV0sgbWlzc2luZyB4Iik7bGV0IFk9WC54O1guZD12b2lkIDA7bGV0IFY9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgiandrIix7a3R5OiJPS1AiLGNydjoiRWQyNTUxOSIseDpZfSx7bmFtZToiRWQyNTUxOSJ9LCEwLFsidmVyaWZ5Il0pLFc9bmV3IFVpbnQ4QXJyYXkoYXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgicmF3IixWKSk7dGhpcy52ZXJpZnlLZXlzLnNldChSMChXKSxWKTtsZXQgej1uZXcgVWludDhBcnJheSg2NCk7cmV0dXJuIHouc2V0KFosMCksei5zZXQoVywzMikse2tleVR5cGU6ImVkMjU1MTkiLHByaXZhdGVLZXk6eixwdWJsaWNLZXk6V319YXN5bmMgaW1wb3J0U2lnbktleSgkKXtsZXQgWj0kLnN1YmFycmF5KDAsMzIpLEo9TVEoWiksUT1RJChKKTt0cnl7cmV0dXJuIGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInBrY3M4IixRLHtuYW1lOiJFZDI1NTE5In0sITEsWyJzaWduIl0pfWZpbmFsbHl7Si5maWxsKDApLG5ldyBVaW50OEFycmF5KFEpLmZpbGwoMCl9fWFzeW5jIGltcG9ydFZlcmlmeUtleSgkKXtsZXQgWj1SMCgkKSxKPXRoaXMudmVyaWZ5S2V5cy5nZXQoWik7aWYoSilyZXR1cm4gSjtsZXQgUT1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJyYXciLFEkKCQpLHtuYW1lOiJFZDI1NTE5In0sITEsWyJ2ZXJpZnkiXSk7cmV0dXJuIHRoaXMudmVyaWZ5S2V5cy5zZXQoWixRKSxRfWFzeW5jIHNpZ25FZDI1NTE5KCQsWil7bGV0IEo9SVEoJCksUT1hd2FpdCB0aGlzLmltcG9ydFNpZ25LZXkoWiksWD1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuc2lnbih7bmFtZToiRWQyNTUxOSJ9LFEsUSQoSikpO3JldHVybiBuZXcgVWludDhBcnJheShYKX1hc3luYyBjaGVja1NpZ0VkMjU1MTkoJCxaLEope2xldCBRPUlRKFopO3RyeXtsZXQgWD1hd2FpdCB0aGlzLmltcG9ydFZlcmlmeUtleShKKTtyZXR1cm4gYXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLnZlcmlmeSh7bmFtZToiRWQyNTUxOSJ9LFgsUSQoJCksUSQoUSkpfWNhdGNoe3JldHVybiExfX1hc3luYyBibGFrZTMoJCl7cmV0dXJuIEhRKCQpfX12YXIgYVg9bmV3IFUkLGMkPWFYO3ZhciBFMD17ZW5jb2RlKCQsWil7bGV0IEo9JC53cml0ZVZhclN0cmluZyhaLmhhbmRsZSk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZVZhclN0cmluZyhaLmxhYmVsKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gJC53cml0ZVZhckludChaLmlkeD8/MCl9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxYXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbWSxWXT0kLnJlYWRWYXJJbnQoKTtpZihWIT09MClyZXR1cm4gRyhWKTtyZXR1cm4gUih7aGFuZGxlOlosbGFiZWw6USxpZHg6WX0pfX07dmFyIG4kPTEsclo9e2VuY29kZSgkLFope2lmKFoudiE9PW4kKXJldHVybiAxMDtsZXRbLEpdPWUoWi5tYXN0ZXJTZWVkKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFySW50KFoudik7aWYoUSE9PTApcmV0dXJuIFE7JC53cml0ZUJ5dGVzKFoubWFzdGVyU2VlZCk7bGV0IFg9JC53cml0ZVZhckludChaLmhvc3RzLmxlbmd0aCk7aWYoWCE9PTApcmV0dXJuIFg7Zm9yKGxldCBZIG9mIFouaG9zdHMpe2xldCBWPSQud3JpdGVTdHJ1Y3QoRTAsWSk7aWYoViE9PTApcmV0dXJuIFZ9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaIT09biQpcmV0dXJuIEcoMTQpO2xldFtRLFhdPSQucmVhZEJ5dGVzKE8wKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbWSxWXT1lKFEpO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFk9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldFtXLHpdPSQucmVhZFZhckludCgpO2lmKHohPT0wKXJldHVybiBHKHopO2lmKFc9PT12b2lkIDB8fFc8MClyZXR1cm4gRygxMCk7bGV0IEs9W107Zm9yKGxldCBGPTA7RjxXO0YrKyl7bGV0W04sT109JC5yZWFkU3RydWN0KEUwKTtpZihPIT09MClyZXR1cm4gRyhPKTtpZihOPT09dm9pZCAwKXJldHVybiBHKDE0KTtLLnB1c2goTil9cmV0dXJuIFIoe3Y6biQsbWFzdGVyU2VlZDpZLGhvc3RzOkt9KX19O2Z1bmN0aW9uIENRKCQsWil7bGV0W0osUV09ZSgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDEwKTtsZXRbWCxZXT1lKEouc2xpY2UoKSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoWD09PXZvaWQgMClyZXR1cm4gRygxMCk7cmV0dXJuIFIoe3Y6biQsbWFzdGVyU2VlZDpYLGhvc3RzOloubWFwKChWKT0+KHtoYW5kbGU6Vi5oYW5kbGUsbGFiZWw6Vi5sYWJlbCxpZHg6Vi5pZHg/PzB9KSl9KX12YXIgb1o9e2VuY29kZSgkLFope2xldFssSl09ZShaLm1hc3RlclNlZWQpO2lmKEohPT0wKXJldHVybiBKOyQud3JpdGVCeXRlcyhaLm1hc3RlclNlZWQpO2xldCBRPSQud3JpdGVWYXJJbnQoWi5ob3N0cy5sZW5ndGgpO2lmKFEhPT0wKXJldHVybiBRO2ZvcihsZXQgWCBvZiBaLmhvc3RzKXtsZXQgWT0kLndyaXRlU3RydWN0KEUwLFgpO2lmKFkhPT0wKXJldHVybiBZfXJldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkQnl0ZXMoTzApO2lmKEohPT0wKXJldHVybiBHKEopO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldFtRLFhdPWUoWik7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1ksVl09JC5yZWFkVmFySW50KCk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMHx8WTwwKXJldHVybiBHKDEwKTtsZXQgVz1bXTtmb3IobGV0IHo9MDt6PFk7eisrKXtsZXRbSyxGXT0kLnJlYWRTdHJ1Y3QoRTApO2lmKEYhPT0wKXJldHVybiBHKEYpO2lmKEs9PT12b2lkIDApcmV0dXJuIEcoMTQpO1cucHVzaChLKX1yZXR1cm4gUih7bWFzdGVyU2VlZDpRLGhvc3RzOld9KX19O2Z1bmN0aW9uIHcwKCQpe2xldCBaPW5ldyBVaW50OEFycmF5KCQpO2lmKCQ+MCljcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKFopO3JldHVybiBafXZhciBmMD0zMixzWD0tNyx0WD0tOCxlWD0tMjU3LGQkPVt7dHlwZToicHVibGljLWtleSIsYWxnOnNYfSx7dHlwZToicHVibGljLWtleSIsYWxnOnRYfSx7dHlwZToicHVibGljLWtleSIsYWxnOmVYfV07ZnVuY3Rpb24gJFkoJCl7cmV0dXJuICQudHJpbSgpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXC4kLywiIil8fCJsb2NhbGhvc3QifWZ1bmN0aW9uIGcwKCQpe2xldCBaPW5ldyBVaW50OEFycmF5KCQuYnl0ZUxlbmd0aCk7cmV0dXJuIFouc2V0KCQpLFouYnVmZmVyfWZ1bmN0aW9uIFBRKCQpe2lmKCQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcilyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJCkuc2xpY2UoKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LCQuYnl0ZUxlbmd0aCkuc2xpY2UoKX1mdW5jdGlvbiBtMCgkKXtpZigkPy5ycElkIT09dm9pZCAwKXJldHVybiBSKCQucnBJZCk7aWYodHlwZW9mIGxvY2F0aW9uPiJ1IilyZXR1cm4gRyg5KTtyZXR1cm4gUigkWShsb2NhdGlvbi5ob3N0bmFtZSkpfWZ1bmN0aW9uIFMwKCl7aWYodHlwZW9mIG5hdmlnYXRvcj4idSJ8fCFuYXZpZ2F0b3IuY3JlZGVudGlhbHN8fHR5cGVvZiBQdWJsaWNLZXlDcmVkZW50aWFsPiJ1IilyZXR1cm4gMjQ7cmV0dXJuIDB9ZnVuY3Rpb24gdjAoJCl7aWYoJD09PW51bGx8fCQudHlwZSE9PSJwdWJsaWMta2V5Inx8ISgicmF3SWQiaW4gJCl8fHR5cGVvZiAkLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMhPT0iZnVuY3Rpb24iKXJldHVybiBHKDI3KTtyZXR1cm4gUigkKX1hc3luYyBmdW5jdGlvbiB3USgkKXtsZXQgWj1TMCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtKLFFdPW0wKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoOSk7bGV0IFg9JD8udXNlck5hbWU/PyJkaXBsb21hdGljLXNlZWQiLFk9e3Jlc2lkZW50S2V5OiJyZXF1aXJlZCIscmVxdWlyZVJlc2lkZW50S2V5OiEwLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIn07aWYoJD8uYXV0aGVudGljYXRvckF0dGFjaG1lbnQhPT12b2lkIDApWS5hdXRoZW50aWNhdG9yQXR0YWNobWVudD0kLmF1dGhlbnRpY2F0b3JBdHRhY2htZW50O2xldCBWPXtsYXJnZUJsb2I6e3N1cHBvcnQ6InJlcXVpcmVkIn19LFc7dHJ5e1c9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmNyZWF0ZSh7cHVibGljS2V5OntjaGFsbGVuZ2U6dzAoZjApLHJwOntpZDpKLG5hbWU6JD8ucnBOYW1lPz8iRElQTE9NQVRJQyJ9LHVzZXI6e2lkOncwKDE2KSxuYW1lOlgsZGlzcGxheU5hbWU6WH0scHViS2V5Q3JlZFBhcmFtczpkJCxhdXRoZW50aWNhdG9yU2VsZWN0aW9uOlksZXh0ZW5zaW9uczpWfX0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbeixLXT12MChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtpZih6LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5sYXJnZUJsb2I/LnN1cHBvcnRlZCE9PSEwKXJldHVybiBHKDI0KTtyZXR1cm4gUihuZXcgVWludDhBcnJheSh6LnJhd0lkKSl9YXN5bmMgZnVuY3Rpb24gYVooJCxaLEope2xldCBRPVMwKCk7aWYoUSE9PTApcmV0dXJuIFE7bGV0W1gsWV09bTAoSik7aWYoWSE9PTApcmV0dXJuIFk7aWYoWD09PXZvaWQgMClyZXR1cm4gOTtsZXQgVj17bGFyZ2VCbG9iOnt3cml0ZTpnMChaKX19LFc7dHJ5e1c9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmdldCh7cHVibGljS2V5OntjaGFsbGVuZ2U6dzAoZjApLHJwSWQ6WCxhbGxvd0NyZWRlbnRpYWxzOlt7dHlwZToicHVibGljLWtleSIsaWQ6ZzAoJCl9XSx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCIsZXh0ZW5zaW9uczpWfX0pfWNhdGNoe3JldHVybiAyNH1sZXRbeixLXT12MChXKTtpZihLIT09MClyZXR1cm4gSztpZih6PT09dm9pZCAwKXJldHVybiAyNztpZih6LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5sYXJnZUJsb2I/LndyaXR0ZW4hPT0hMClyZXR1cm4gMjQ7cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gVFEoJCxaKXtsZXQgSj1TMCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFhdPW0wKFopO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoOSk7bGV0IFk9e2xhcmdlQmxvYjp7cmVhZDohMH19LFY7dHJ5e2xldCBPPXtjaGFsbGVuZ2U6dzAoZjApLHJwSWQ6USx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCIsZXh0ZW5zaW9uczpZfTtpZigkIT09dm9pZCAwKU8uYWxsb3dDcmVkZW50aWFscz1be3R5cGU6InB1YmxpYy1rZXkiLGlkOmcwKCQpfV07Vj1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6T30pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbVyx6XT12MChWKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgRj1XLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5sYXJnZUJsb2I7aWYoRj09PXZvaWQgMHx8Ri5ibG9iPT09dm9pZCAwKXJldHVybiBHKDcpO2xldCBOPVBRKEYuYmxvYik7aWYoTi5ieXRlTGVuZ3RoPT09MClyZXR1cm4gRyg3KTtyZXR1cm4gUih7YmxvYjpOLGNyZWRJZDpuZXcgVWludDhBcnJheShXLnJhd0lkKX0pfXZhciByJD1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMucHJmLnYxIiksc1o9MzI7YXN5bmMgZnVuY3Rpb24galEoJCl7bGV0IFo9UzAoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbSixRXT1tMCgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDkpO2xldCBYPSQ/LnVzZXJOYW1lPz8iZGlwbG9tYXRpYy1wcmYiLFk9e3Jlc2lkZW50S2V5OiJyZXF1aXJlZCIscmVxdWlyZVJlc2lkZW50S2V5OiEwLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixhdXRoZW50aWNhdG9yQXR0YWNobWVudDokPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudD8/InBsYXRmb3JtIn0sVjt0cnl7Vj1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6e2NoYWxsZW5nZTp3MChmMCkscnA6e2lkOkosbmFtZTokPy5ycE5hbWU/PyJESVBMT01BVElDIn0sdXNlcjp7aWQ6dzAoMTYpLG5hbWU6WCxkaXNwbGF5TmFtZTpYfSxwdWJLZXlDcmVkUGFyYW1zOmQkLGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246WSxleHRlbnNpb25zOntwcmY6e319fX0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbVyx6XT12MChWKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgSz1XLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKTtyZXR1cm4gUih7Y3JlZElkOm5ldyBVaW50OEFycmF5KFcucmF3SWQpLHByZkVuYWJsZWQ6Sy5wcmY/LmVuYWJsZWQ9PT0hMH0pfWFzeW5jIGZ1bmN0aW9uIHEkKCQpe2xldCBaPVMwKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W0osUV09bTAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgWD0kPy5zYWx0Pz9yJCxZPWcwKFgpLFY9e2NoYWxsZW5nZTp3MChmMCkscnBJZDpKLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixleHRlbnNpb25zOntwcmY6e2V2YWw6e2ZpcnN0Oll9fX19O2lmKCQ/LmNyZWRJZCE9PXZvaWQgMClWLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOiJwdWJsaWMta2V5IixpZDpnMCgkLmNyZWRJZCl9XTtsZXQgVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6Vn0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbeixLXT12MChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgRj16LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5wcmY/LnJlc3VsdHM7aWYoRj8uZmlyc3Q9PT12b2lkIDApcmV0dXJuIEcoNyk7bGV0IE49Ri5maXJzdCxPPU4gaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcj9uZXcgVWludDhBcnJheShOKTpuZXcgVWludDhBcnJheShOLmJ1ZmZlcixOLmJ5dGVPZmZzZXQsTi5ieXRlTGVuZ3RoKSxVPU8uYnl0ZUxlbmd0aD49c1o/Ty5zbGljZSgwLHNaKTpPO2lmKFUuYnl0ZUxlbmd0aCE9PXNaKXJldHVybiBHKDI3KTtyZXR1cm4gUih7cHJmOlUsY3JlZElkOm5ldyBVaW50OEFycmF5KHoucmF3SWQpfSl9dmFyIG8kPSIiO3ZhciBzJD10eXBlb2YgZ2xvYmFsVGhpcy5Xb3JrZXI9PT0iZnVuY3Rpb24iP2dsb2JhbFRoaXMuV29ya2VyOnZvaWQgMCx0Wj1zJD09PXZvaWQgMD92b2lkIDA6cyQucHJvdG90eXBlLnBvc3RNZXNzYWdlLGEkO2Z1bmN0aW9uIEpZKCl7aWYodHlwZW9mIG8kIT09InN0cmluZyJ8fG8kLmxlbmd0aD09PTApdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSB3b3JrZXIgc291cmNlIG5vdCBlbWJlZGRlZDsgcnVuIHBrZyBidWlsZCBiZWZvcmUgc3Bhd24iKTtyZXR1cm4gYXRvYihvJCl9ZnVuY3Rpb24gUVkoKXtpZihhJCE9PXZvaWQgMClyZXR1cm4gYSQ7bGV0ICQ9bmV3IEJsb2IoW0pZKCldLHt0eXBlOiJ0ZXh0L2phdmFzY3JpcHQifSk7cmV0dXJuIGEkPVVSTC5jcmVhdGVPYmplY3RVUkwoJCksYSR9ZnVuY3Rpb24gRFEoKXtpZihzJD09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBzcGF3biBzeW5jIHdvcmtlciIpO3JldHVybiBuZXcgcyQoUVkoKSx7dHlwZToibW9kdWxlIn0pfWZ1bmN0aW9uIEFRKCQsWixKKXtpZih0Wj09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBwb3N0IHRvIHN5bmMgd29ya2VyIik7aWYoSiE9PXZvaWQgMCYmSi5sZW5ndGg+MCl0Wi5jYWxsKCQsWix7dHJhbnNmZXI6Sn0pO2Vsc2UgdFouY2FsbCgkLFopfXZhciBYWT1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMud3JhcC52MSIpLF9RPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgiZGlwbG9tYXRpYy5wYWlyLnYxIiksWVk9MzIsVlk9MTYsWjA9bmV3IFUkO2NsYXNzIEcweyMkO2NvbnN0cnVjdG9yKCQpe3RoaXMuIyQ9JH1zdGF0aWMgYXN5bmMgZnJvbVJhbmRvbSgpe2xldCAkPWF3YWl0IFowLmdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKSxbWixKXT1lKCQpO2lmKEohPT0wfHxaPT09dm9pZCAwKXRocm93IEVycm9yKGBlbmNsYXZlOiBpbnZhbGlkIHJhbmRvbSBzZWVkICgke0p9KWApO3JldHVybiBuZXcgRzAoWil9c3RhdGljIGZyb21CeXRlcygkKXtsZXRbWixKXT1lKCQpO2lmKEohPT0wKXJldHVybiBHKEopO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtRLFhdPWUoWi5zbGljZSgpKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEwKTtyZXR1cm4gUihuZXcgRzAoUSkpfWFzeW5jIHNlYWxXaXRoUGFzc2tleSgkKXtsZXQgWj0kPy5zYWx0Pz9yJCxKPSQ/LmNyZWRJZDtpZihKPT09dm9pZCAwJiYkPy5jcmVhdGVDcmVkSWZOZWVkZWQ9PT0hMCl7bGV0W1ksVl09YXdhaXQgalEoe3JwSWQ6JD8ucnBJZCxycE5hbWU6JD8ucnBOYW1lLHVzZXJOYW1lOiQ/LnVzZXJOYW1lPz8iZGlwbG9tYXRpYy1wcmYifSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMClyZXR1cm4gRygyNCk7aWYoIVkucHJmRW5hYmxlZClyZXR1cm4gRygyNCk7Sj1ZLmNyZWRJZH1sZXRbUSxYXT1hd2FpdCBxJCh7cnBJZDokPy5ycElkLHJwTmFtZTokPy5ycE5hbWUsY3JlZElkOkosc2FsdDpafSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoUT09PXZvaWQgMClyZXR1cm4gRyg3KTt0cnl7bGV0W1ksVl09YXdhaXQgdGhpcy4jWihRLnByZik7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIFIoe3NlYWxlZE1hc3RlcjpZLHNhbHQ6Wi5zbGljZSgpLGNyZWRJZDpRLmNyZWRJZC5zbGljZSgpfSl9ZmluYWxseXtRLnByZi5maWxsKDApfX1zdGF0aWMgYXN5bmMgdW5zZWFsV2l0aFBhc3NrZXkoJCxaKXtsZXRbSixRXT1hd2FpdCBxJCh7cnBJZDpaLnJwSWQscnBOYW1lOloucnBOYW1lLGNyZWRJZDpaLmNyZWRJZCxzYWx0Olouc2FsdH0pO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoNyk7dHJ5e2xldFtYLFldPWF3YWl0IEcwLiNRKCQsSi5wcmYpO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFg9PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBSKHtlbmNsYXZlOlgsY3JlZElkOkouY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e0oucHJmLmZpbGwoMCl9fWFzeW5jIHBlcnNpc3RUb0xhcmdlQmxvYigkPVtdLFope2xldCBKPVo/LmNyZWRJZDtpZihKPT09dm9pZCAwKXtsZXRbWSxWXT1hd2FpdCB3UShaKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDI0KTtKPVl9bGV0W1EsWF09dGhpcy4jSigkKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFk9YXdhaXQgYVooSixRLFopO2lmKFkhPT0wKXJldHVybiBHKFkpO3JldHVybiBSKEopfWZpbmFsbHl7US5maWxsKDApfX1zdGF0aWMgYXN5bmMgZnJvbUxhcmdlQmxvYigkKXtsZXRbWixKXT1hd2FpdCBUUSgkPy5jcmVkSWQsJCk7aWYoSiE9PTApcmV0dXJuIEcoSik7aWYoWj09PXZvaWQgMClyZXR1cm4gRyg3KTt0cnl7cmV0dXJuIEcwLiNYKFouYmxvYixaLmNyZWRJZCl9ZmluYWxseXtaLmJsb2IuZmlsbCgwKX19c3RhdGljIGFzeW5jIGNsZWFyTGFyZ2VCbG9iKCQsWil7cmV0dXJuIGFaKCQsbmV3IFVpbnQ4QXJyYXkoTzApLFopfWFzeW5jIHNlYWxQYWlyUGFja2FnZUJvZHkoJCxaKXtsZXQgSj1aPy5zYWx0Pz9yJCxbUSxYXT1hd2FpdCBxJCh7cnBJZDpaPy5ycElkLHJwTmFtZTpaPy5ycE5hbWUsY3JlZElkOlo/LmNyZWRJZCxzYWx0Okp9KTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbWSxWXT1hd2FpdCB0JChaMCxRLnByZixfUSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldFtXLHpdPWUodGhpcy4jJC5zbGljZSgpKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwKXJldHVybiBHKDEwKTtsZXQgSz17bWFzdGVyU2VlZDpXLGhvc3RzOiQubWFwKChxKT0+KHtoYW5kbGU6cS5oYW5kbGUsbGFiZWw6cS5sYWJlbCxpZHg6cS5pZHg/PzB9KSl9LEY9bmV3IFMsTj1GLndyaXRlU3RydWN0KG9aLEspO2lmKE4hPT0wKXJldHVybiBXLmZpbGwoMCksRyhOKTtsZXQgTz1GLnJlc3VsdCgpO1cuZmlsbCgwKTtsZXQgVTt0cnl7VT1hd2FpdCBaMC5lbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKE8sWSl9Y2F0Y2h7cmV0dXJuIE8uZmlsbCgwKSxHKDEyKX1yZXR1cm4gTy5maWxsKDApLFIoe2JvZHk6VSxzYWx0Okouc2xpY2UoKSxjcmVkSWQ6US5jcmVkSWQuc2xpY2UoKX0pfWZpbmFsbHl7WS5maWxsKDApfX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBvcGVuUGFpclBhY2thZ2VCb2R5KCQsWil7bGV0W0osUV09YXdhaXQgcSQoe3JwSWQ6Wi5ycElkLHJwTmFtZTpaLnJwTmFtZSxjcmVkSWQ6Wi5jcmVkSWQsc2FsdDpaLnNhbHR9KTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbWCxZXT1hd2FpdCB0JChaMCxKLnByZixfUSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoWD09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBWO3RyeXtWPWF3YWl0IFowLmRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoJCxYKX1jYXRjaHtyZXR1cm4gRygyMCl9bGV0IFc9bmV3IG0oViksW3osS109Vy5yZWFkU3RydWN0KG9aKTtpZihWLmZpbGwoMCksSyE9PTApcmV0dXJuIEcoSyk7aWYoej09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W0YsTl09RzAuZnJvbUJ5dGVzKHoubWFzdGVyU2VlZCk7aWYoei5tYXN0ZXJTZWVkLmZpbGwoMCksTiE9PTApcmV0dXJuIEcoTik7aWYoRj09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0W08sVV09YXdhaXQgRi4jWihKLnByZik7aWYoVSE9PTApcmV0dXJuIEcoVSk7aWYoTz09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIFIoe2VuY2xhdmU6Rixob3N0czp6Lmhvc3RzLm1hcCgocSk9Pih7Li4ucX0pKSxzZWFsZWRNYXN0ZXI6TyxjcmVkSWQ6Si5jcmVkSWQuc2xpY2UoKX0pfWZpbmFsbHl7WC5maWxsKDApfX1maW5hbGx5e0oucHJmLmZpbGwoMCl9fXNwYXduU3luY1dvcmtlcigkKXtsZXQgWj1EUSgpLEo9dGhpcy4jJC5zbGljZSgpO3JldHVybiBBUShaLHtpZDokLmlkLG9wOiJzZXRTZWVkIixzZWVkOkoscGVyc2lzdDokLnBlcnNpc3R9LFtKLmJ1ZmZlcl0pLFp9ZGVyaXZlQ2lwaGVyKCQsWil7bGV0IEo9JC5zbGljZSgpLFE9KFYpPT50aGlzLiNZKEosViksWD0oVik9PnRoaXMuI0coSixWKTtyZXR1cm57ZW5jcnlwdDpPYmplY3QuZnJlZXplKHtlbmNyeXB0OlF9KSxkZWNyeXB0Ok9iamVjdC5mcmVlemUoe2RlY3J5cHQ6WH0pLGJvdGg6T2JqZWN0LmZyZWV6ZSh7ZW5jcnlwdDpRLGRlY3J5cHQ6WH0pfVtaXX1hc3luYyBkZXJpdmVJZGVudGl0eSgkLFo9MCl7bGV0IEo9JCxRPVosWD1hd2FpdCB0aGlzLiNXKEosUSksWT1YLnB1YmxpY0tleTtyZXR1cm4gWC5wcml2YXRlS2V5LmZpbGwoMCksT2JqZWN0LmZyZWV6ZSh7cHVibGljS2V5Olksc2lnbjooVik9PnRoaXMuI0soSixRLFYpLGtkbUZvcjooVik9PnRoaXMuI0YoSixRLFYpfSl9YXN5bmMjWigkKXtsZXRbWixKXT1hd2FpdCB0JChaMCwkKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFE9YXdhaXQgWjAuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCh0aGlzLiMkLFopO3JldHVybiBBMChRKX1jYXRjaHtyZXR1cm4gRygxMil9ZmluYWxseXtaLmZpbGwoMCl9fXN0YXRpYyBhc3luYyNRKCQsWil7bGV0WyxKXT1BMCgkKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxYXT1hd2FpdCB0JChaMCxaKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTtsZXQgWTt0cnl7dHJ5e1k9YXdhaXQgWjAuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCgkLFEpfWNhdGNoe3JldHVybiBHKDIwKX1yZXR1cm4gRzAuZnJvbUJ5dGVzKFkpfWZpbmFsbHl7US5maWxsKDApLFk/LmZpbGwoMCl9fSNKKCQpe2xldFtaLEpdPWUodGhpcy4jJC5zbGljZSgpKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDEwKTtsZXRbUSxYXT1DUShaLCQpO2lmKFouZmlsbCgwKSxYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFk9bmV3IFMsVj1ZLndyaXRlU3RydWN0KHJaLFEpO2lmKFYhPT0wKXJldHVybiBHKFYpO3JldHVybiBSKFkucmVzdWx0KCkpfWZpbmFsbHl7US5tYXN0ZXJTZWVkLmZpbGwoMCl9fXN0YXRpYyNYKCQsWil7aWYoJC5ieXRlTGVuZ3RoPT09MHx8JC5ldmVyeSgoWSk9Plk9PT0wKSlyZXR1cm4gRygyMik7aWYoJC5ieXRlTGVuZ3RoPT09TzApe2lmKCQuZXZlcnkoKFcpPT5XPT09MCkpcmV0dXJuIEcoMjIpO2xldFtZLFZdPUcwLmZyb21CeXRlcygkKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gUih7ZW5jbGF2ZTpZLGhvc3RzOltdLGNyZWRJZDpafSl9bGV0IEo9bmV3IG0oJCksW1EsWF09Si5yZWFkU3RydWN0KHJaKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDE0KTt0cnl7aWYoUS5tYXN0ZXJTZWVkLmV2ZXJ5KChXKT0+Vz09PTApKXJldHVybiBHKDIyKTtsZXRbWSxWXT1HMC5mcm9tQnl0ZXMoUS5tYXN0ZXJTZWVkKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gUih7ZW5jbGF2ZTpZLGhvc3RzOlEuaG9zdHMubWFwKChXKT0+KHsuLi5XfSkpLGNyZWRJZDpafSl9ZmluYWxseXtRLm1hc3RlclNlZWQuZmlsbCgwKX19YXN5bmMjWSgkLFope2xldCBKPWF3YWl0IHRoaXMuI1YoJCk7dHJ5e3JldHVybiBhd2FpdCBaMC5lbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKFosSil9ZmluYWxseXtKLmZpbGwoMCl9fWFzeW5jI0coJCxaKXtsZXQgSj1hd2FpdCB0aGlzLiNWKCQpO3RyeXtyZXR1cm4gYXdhaXQgWjAuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChaLEopfWZpbmFsbHl7Si5maWxsKDApfX1hc3luYyNWKCQpe3JldHVybiBaMC5ibGFrZTMoRyQodGhpcy4jJCwkKSl9YXN5bmMjeigkLFope2xldCBKPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSxRPW5ldyBVaW50OEFycmF5KDgpO3JldHVybiBuZXcgRGF0YVZpZXcoUS5idWZmZXIpLnNldEJpZ1VpbnQ2NCgwLEJpZ0ludChaKSwhMSksYXdhaXQgdGhpcy4jVihHJChKLFEpKX1hc3luYyNXKCQsWil7bGV0IEo9YXdhaXQgdGhpcy4jeigkLFopO3RyeXtyZXR1cm4gYXdhaXQgWjAuZGVyaXZlRWQyNTUxOUtleVBhaXIoSil9ZmluYWxseXtKLmZpbGwoMCl9fWFzeW5jI0soJCxaLEope2xldCBRPWF3YWl0IHRoaXMuI1coJCxaKTt0cnl7cmV0dXJuIGF3YWl0IFowLnNpZ25FZDI1NTE5KEosUS5wcml2YXRlS2V5KX1maW5hbGx5e1EucHJpdmF0ZUtleS5maWxsKDApfX1hc3luYyNGKCQsWixKKXtsZXQgUT1hd2FpdCB0aGlzLiNXKCQsWiksWD1HJChRLnByaXZhdGVLZXksSik7US5wcml2YXRlS2V5LmZpbGwoMCk7dHJ5e3JldHVybihhd2FpdCBaMC5ibGFrZTMoWCkpLnNsaWNlKDAsajApfWZpbmFsbHl7WC5maWxsKDApfX19YXN5bmMgZnVuY3Rpb24gdCQoJCxaLEo9WFkpe2lmKFouYnl0ZUxlbmd0aDxWWSlyZXR1cm4gRygxMCk7bGV0IFE9YXdhaXQgJC5ibGFrZTMoRyQoWixKKSk7cmV0dXJuIFIoUS5zbGljZSgwLFlZKSl9Y2xhc3MgZVp7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGVucSgkKXtsZXQgWj1bLi4uJF07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKHowLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUoejApO3JldHVybiBuZXcgUHJvbWlzZSgoWCxZKT0+e0oub25jb21wbGV0ZT0oKT0+WCgpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtmb3IobGV0IFYgb2YgWil7bGV0IFc9YCR7Vi5ob3N0fToke1Yuc2VxfWA7US5wdXQoVixXKX19KX1hc3luYyBkZXEoJCxaKXtsZXQgSj1bLi4uWl07aWYoSi5sZW5ndGg9PT0wKXJldHVybjtsZXQgUT10aGlzLmRiLnRyYW5zYWN0aW9uKHowLCJyZWFkd3JpdGUiKSxYPVEub2JqZWN0U3RvcmUoejApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1Eub25jb21wbGV0ZT0oKT0+WSgpLFEub25lcnJvcj0oKT0+VihRLmVycm9yKTtmb3IobGV0IFcgb2YgSil7bGV0IHo9YCR7JH06JHtXfWA7WC5kZWxldGUoeil9fSl9YXN5bmMgbGlzdCgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oejAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoejApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBYPVouZ2V0QWxsKCk7WC5vbnN1Y2Nlc3M9KCk9PkooWC5yZXN1bHQpLFgub25lcnJvcj0oKT0+UShYLmVycm9yKX0pfWFzeW5jIGNvdW50KCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbih6MCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZSh6MCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57bGV0IFg9Wi5jb3VudCgpO1gub25zdWNjZXNzPSgpPT5KKFgucmVzdWx0KSxYLm9uZXJyb3I9KCk9PlEoWC5lcnJvcil9KX1hc3luYyB3aXBlKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbih6MCwicmVhZHdyaXRlIiksWj0kLm9iamVjdFN0b3JlKHowKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PnskLm9uY29tcGxldGU9KCk9PkooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksWi5jbGVhcigpfSl9fWZ1bmN0aW9uIExRKCQpe3JldHVybntsYWJlbDokLmxhYmVsLGhhbmRsZTpuZXcgVVJMKCQuaGFuZGxlKSxpZHg6JC5pZHgsbGFzdFNlcTokLmxhc3RTZXF8fDAsY2xvY2tPZmZzZXQ6JC5jbG9ja09mZnNldCxzdWJzY3JpcHRpb246JC5zdWJzY3JpcHRpb259fWZ1bmN0aW9uIFdZKCQsWil7bGV0IEo9ey4uLiR9O2lmKFouc2V0TGFzdFNlcSE9PXZvaWQgMClKLmxhc3RTZXE9Wi5zZXRMYXN0U2VxO2Vsc2UgaWYoWi5sYXN0U2VxIT09dm9pZCAwKXtsZXQgUT1KLmxhc3RTZXF8fDA7aWYoWi5sYXN0U2VxPlEpSi5sYXN0U2VxPVoubGFzdFNlcX1yZXR1cm4gZGVsZXRlIEoubnVtQmFncyxkZWxldGUgSi5udW1EdXBlcyxKfWNsYXNzICRKe2RiO2NvbnN0cnVjdG9yKCQpe3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IFo9YXdhaXQgdGhpcy5nZXQoJC5sYWJlbCksSj1aIT09dm9pZCAwJiZaLmhhbmRsZS5ocmVmPT09JC5oYW5kbGUuaHJlZiYmKFouaWR4Pz8wKT09PSgkLmlkeD8/MCk7cmV0dXJuIHRoaXMucHV0KHsuLi4kLGxhc3RTZXE6Sj9aLmxhc3RTZXE6MCxjbG9ja09mZnNldDpKP1ouY2xvY2tPZmZzZXQ6dm9pZCAwLHN1YnNjcmlwdGlvbjpKP1ouc3Vic2NyaXB0aW9uOnZvaWQgMH0pfWFzeW5jIHB1dCgkKXtsZXQgWj17Li4uJCxoYW5kbGU6JC5oYW5kbGUudG9TdHJpbmcoKSxsYXN0U2VxOiQubGFzdFNlcT8/MH0sSj10aGlzLmRiLnRyYW5zYWN0aW9uKEowLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUoSjApO3JldHVybiBuZXcgUHJvbWlzZSgoWCxZKT0+e0oub25jb21wbGV0ZT0oKT0+WCgpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKSxRLnB1dChaKX0pfWFzeW5jIHRvdWNoKCQsWil7cmV0dXJuIHRoaXMucmVjb3JkU3RhdHMoJCx7bGFzdFNlcTpafSl9YXN5bmMgcmVjb3JkU3RhdHMoJCxaKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKEowLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUoSjApO3JldHVybiBuZXcgUHJvbWlzZSgoWCxZKT0+e0oub25jb21wbGV0ZT0oKT0+WCgpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtsZXQgVj1RLmdldCgkKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVYucmVzdWx0O2lmKCFXKXJldHVybjtRLnB1dChXWShXLFopKX19KX1hc3luYyBnZXQoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihKMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShKMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFgpPT57bGV0IFk9Si5nZXQoJCk7WS5vbnN1Y2Nlc3M9KCk9PntsZXQgVj1ZLnJlc3VsdDtpZighVilRKHZvaWQgMCk7ZWxzZSBRKExRKFYpKX0sWS5vbmVycm9yPSgpPT5YKFkuZXJyb3IpfSl9YXN5bmMgc2V0KCQsWil7bGV0IEo9YXdhaXQgdGhpcy5nZXQoJCk7aWYoIUopcmV0dXJuIDEzO3RyeXtyZXR1cm4gYXdhaXQgdGhpcy5wdXQoey4uLkosLi4uWn0pLDB9Y2F0Y2h7cmV0dXJuIDE4fX1hc3luYyBkZWwoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihKMCwicmVhZHdyaXRlIiksSj1aLm9iamVjdFN0b3JlKEowKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWCk9PntaLm9uY29tcGxldGU9KCk9PlEoKSxaLm9uZXJyb3I9KCk9PlgoWi5lcnJvciksSi5kZWxldGUoJCl9KX1hc3luYyBsaXN0KCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihKMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShKMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57bGV0IFg9Wi5nZXRBbGwoKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBZPVgucmVzdWx0O0ooWS5tYXAoTFEpKX0sWC5vbmVycm9yPSgpPT5RKFguZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oSjAsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZShKMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5KKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLFouY2xlYXIoKX0pfX1jbGFzcyBaSntjcnlwdG87ZGI7Y29uc3RydWN0b3IoJCxaKXt0aGlzLmNyeXB0bz1aO3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihsLCJyZWFkd3JpdGUiKSxKPVoub2JqZWN0U3RvcmUobCk7cmV0dXJuIG5ldyBQcm9taXNlKChRKT0+e2lmKCQubGVuZ3RoPT09MCl7UShbXSk7cmV0dXJufWxldCBYPUFycmF5KCQubGVuZ3RoKS5maWxsKDApO1oub25jb21wbGV0ZT0oKT0+UShYKSxaLm9uZXJyb3I9KCk9Pntmb3IobGV0IFk9MDtZPFgubGVuZ3RoO1krKylYW1ldPTE4O1EoWCl9O2ZvcihsZXQgWT0wO1k8JC5sZW5ndGg7WSsrKXtsZXR7a2V5OlYsZGF0YTpXfT0kW1ldLHo9QihWKSxLPUoucHV0KFcseik7Sy5vbmVycm9yPShGKT0+e0YucHJldmVudERlZmF1bHQoKSxYW1ldPTE4fX19KX1hc3luYyBkZWwoJCl7bGV0IFo9Wy4uLiRdO2lmKFoubGVuZ3RoPT09MClyZXR1cm47bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihsLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUobCk7cmV0dXJuIG5ldyBQcm9taXNlKChYLFkpPT57Si5vbmNvbXBsZXRlPSgpPT5YKCksSi5vbmVycm9yPSgpPT5ZKEouZXJyb3IpO2ZvcihsZXQgViBvZiBaKXtsZXQgVz1CKFYpO1EuZGVsZXRlKFcpfX0pfWFzeW5jIGdldCgkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKGwsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFgpPT57bGV0IFk9QigkKSxWPUouZ2V0KFkpO1Yub25zdWNjZXNzPWFzeW5jKCk9PntsZXQgVz1WLnJlc3VsdDtpZihXKVEoYXdhaXQgdiQoJCxXLHRoaXMuY3J5cHRvKSk7ZWxzZSBRKHZvaWQgMCl9LFYub25lcnJvcj0oKT0+WChWLmVycm9yKX0pfWFzeW5jIGhhcygkKXtyZXR1cm4gYXdhaXQgdGhpcy5nZXQoJCkhPT12b2lkIDB9YXN5bmMgbGlzdCgkKXtsZXQgWj0kPy5hcGxkLEo9JD8uYm9keSE9PSExLFg9dGhpcy5kYi50cmFuc2FjdGlvbihsLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGwpO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e2xldCBXPVtdLHo9Wj09PXZvaWQgMD9YLm9wZW5DdXJzb3IoKTpYLmluZGV4KEgkKS5vcGVuQ3Vyc29yKElEQktleVJhbmdlLm9ubHkoWikpO3oub25zdWNjZXNzPShLKT0+e2xldCBGPUsudGFyZ2V0LnJlc3VsdDtpZihGKXtsZXQgTj1aPT09dm9pZCAwP0Yua2V5OkYucHJpbWFyeUtleSxPPUYudmFsdWU7Vy5wdXNoKHtoYXNoOk4wKE4pLGRhdGE6T30pLEYuY29udGludWUoKX1lbHNlIFByb21pc2UuYWxsKFcubWFwKCh7aGFzaDpOLGRhdGE6T30pPT52JChOLE8sdGhpcy5jcnlwdG8se2JvZHk6Sn0pKSkudGhlbihZKS5jYXRjaChWKX0sei5vbmVycm9yPSgpPT5WKHouZXJyb3IpfSl9YXN5bmMgY291bnQoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihsLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGwpO3JldHVybiBuZXcgUHJvbWlzZSgoUSxYKT0+e2xldCBZPSQ9PT12b2lkIDA/Si5jb3VudCgpOkouaW5kZXgoSCQpLmNvdW50KElEQktleVJhbmdlLm9ubHkoJCkpO1kub25zdWNjZXNzPSgpPT5RKFkucmVzdWx0KSxZLm9uZXJyb3I9KCk9PlgoWS5lcnJvcil9KX1hc3luYyBsaXN0S2V5cygpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24obCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShsKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PntsZXQgWD1bXSxZPVoub3BlbktleUN1cnNvcigpO1kub25zdWNjZXNzPShWKT0+e2xldCBXPVYudGFyZ2V0LnJlc3VsdDtpZihXKVgucHVzaChOMChXLmtleSkpLFcuY29udGludWUoKTtlbHNlIEooWCl9LFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfWFzeW5jIGxhc3QoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihsLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKGwpO3JldHVybiBuZXcgUHJvbWlzZSgoUSxYKT0+e2xldCBZLFY9Si5vcGVuQ3Vyc29yKCk7Vi5vbnN1Y2Nlc3M9YXN5bmMoVyk9PntsZXQgej1XLnRhcmdldC5yZXN1bHQ7aWYoeil7bGV0e2tleTpLLHZhbHVlOkZ9PXo7aWYoYSgkLEYuZWlkKSl7aWYoIVl8fChGLmN0cj8/MCk+KFkuZGF0YS5jdHI/PzApfHwoRi5jdHI/PzApPT09KFkuZGF0YS5jdHI/PzApJiYoRi5vZmY/PzApPihZLmRhdGEub2ZmPz8wKSlZPXtrZXk6SyxkYXRhOkZ9fXouY29udGludWUoKX1lbHNlIGlmKFkpe2xldCBLPU4wKFkua2V5KTtRKGF3YWl0IHYkKEssWS5kYXRhLHRoaXMuY3J5cHRvKSl9ZWxzZSBRKHZvaWQgMCl9LFYub25lcnJvcj0oKT0+WChWLmVycm9yKX0pfWFzeW5jIG1hcmtBcHBsaWVkKCQpe2xldCBaPVsuLi4kXTtpZihaLmxlbmd0aD09PTApcmV0dXJuO2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24obCwicmVhZHdyaXRlIiksUT1KLm9iamVjdFN0b3JlKGwpO3JldHVybiBuZXcgUHJvbWlzZSgoWCxZKT0+e0oub25jb21wbGV0ZT0oKT0+WCgpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtmb3IobGV0IFYgb2YgWil7bGV0IFc9QihWKSx6PVEuZ2V0KFcpO3oub25zdWNjZXNzPSgpPT57bGV0IEs9ei5yZXN1bHQ7aWYoIUspcmV0dXJuO19aKEssUyQpLFEucHV0KEssVyl9LHoub25lcnJvcj0oSyk9PntLLnByZXZlbnREZWZhdWx0KCl9fX0pfWFzeW5jIG1hcmtGYWlsZWQoJCl7bGV0IFo9Wy4uLiRdO2lmKFoubGVuZ3RoPT09MClyZXR1cm47bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihsLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUobCk7cmV0dXJuIG5ldyBQcm9taXNlKChYLFkpPT57Si5vbmNvbXBsZXRlPSgpPT5YKCksSi5vbmVycm9yPSgpPT5ZKEouZXJyb3IpO2ZvcihsZXR7a2V5OlYsZXJyOld9b2YgWil7bGV0IHo9QihWKSxLPVEuZ2V0KHopO0sub25zdWNjZXNzPSgpPT57bGV0IEY9Sy5yZXN1bHQ7aWYoIUYpcmV0dXJuO19aKEYsdDAsVyksUS5wdXQoRix6KX0sSy5vbmVycm9yPShGKT0+e0YucHJldmVudERlZmF1bHQoKX19fSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24obCwicmVhZHdyaXRlIiksWj0kLm9iamVjdFN0b3JlKGwpO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+eyQub25jb21wbGV0ZT0oKT0+SigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxaLmNsZWFyKCl9KX19Y2xhc3MgSkp7IyQ7I1o7I1E7I0o7Y29uc3RydWN0b3IoJCl7aWYodGhpcy4jSj0kLnBlcnNpc3RNZXRhLHRoaXMuI1E9e3JwSWQ6JC5ycElkLHJwTmFtZTokLnJwTmFtZX0sJC5tZXRhIT09dm9pZCAwKXRoaXMuI1o9YjAoJC5tZXRhKX1nZXQgbWV0YSgpe3JldHVybiB0aGlzLiNaPT09dm9pZCAwP3ZvaWQgMDpiMCh0aGlzLiNaKX1zZXRNZXRhKCQpe3RoaXMuI1o9JD09PXZvaWQgMD92b2lkIDA6YjAoJCl9YXN5bmMgc2F2ZSgkLFope2lmKFo/LnBlcnNpc3Q9PT0hMClyZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoInByZi1zdG9yZTogdXNlIHdyYXBBbmRTYXZlKGVuY2xhdmUpIHRvIHBlcnNpc3Qgc2VhbGVkIG1hc3RlciIpKTtyZXR1cm4gdGhpcy4jJD0kLHRoaXMuIyR9YXN5bmMgd3JhcEFuZFNhdmUoJCxaKXtsZXRbSixRXT1hd2FpdCAkLnNlYWxXaXRoUGFzc2tleSh7Li4udGhpcy4jUSxzYWx0Olo/LnNhbHQsY3JlZElkOlo/LmNyZWRJZD8/dGhpcy4jWj8uY3JlZElkLGNyZWF0ZUNyZWRJZk5lZWRlZDpaPy5jcmVhdGVDcmVkSWZOZWVkZWQ/P1o/LmNyZWRJZD09PXZvaWQgMCx1c2VyTmFtZToiZGlwbG9tYXRpYy1wcmYifSk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0IFg9e3NlYWxlZE1hc3RlcjpKLnNlYWxlZE1hc3RlcixzYWx0Okouc2FsdCxjcmVkSWQ6Si5jcmVkSWR9O3JldHVybiB0aGlzLiNaPVgsdGhpcy4jJD0kLGF3YWl0IHRoaXMuI0ooYjAoWCkpLFIodGhpcy4jJCl9YXN5bmMgbG9hZCgpe3JldHVybiB0aGlzLiMkfWFzeW5jIHVubG9jaygpe2xldCAkPXRoaXMuI1o7aWYoJD09PXZvaWQgMClyZXR1cm4gRygyMik7bGV0W1osSl09YXdhaXQgRzAudW5zZWFsV2l0aFBhc3NrZXkoJC5zZWFsZWRNYXN0ZXIsey4uLnRoaXMuI1Esc2FsdDokLnNhbHQsY3JlZElkOiQuY3JlZElkfSk7aWYoSiE9PTApcmV0dXJuIEcoSik7aWYodGhpcy4jJD1aLmVuY2xhdmUsWi5jcmVkSWQuYnl0ZUxlbmd0aD4wJiYoJC5jcmVkSWQ9PT12b2lkIDB8fCFhKCQuY3JlZElkLFouY3JlZElkKSkpe2xldCBRPXtzZWFsZWRNYXN0ZXI6JC5zZWFsZWRNYXN0ZXIsc2FsdDokLnNhbHQsY3JlZElkOlouY3JlZElkLnNsaWNlKCl9O3RoaXMuI1o9USxhd2FpdCB0aGlzLiNKKGIwKFEpKX1yZXR1cm4gUihaLmVuY2xhdmUpfWFzeW5jIGFkb3B0U2VhbGVkKCQsWil7cmV0dXJuIHRoaXMuI1o9YjAoWiksdGhpcy4jJD0kLGF3YWl0IHRoaXMuI0ooYjAoWikpLFIodGhpcy4jJCl9YXN5bmMgd2lwZSgpe3RoaXMuIyQ9dm9pZCAwLHRoaXMuI1o9dm9pZCAwLGF3YWl0IHRoaXMuI0oodm9pZCAwKX19ZnVuY3Rpb24gYjAoJCl7bGV0W1osSl09QTAoJC5zZWFsZWRNYXN0ZXIuc2xpY2UoKSk7cmV0dXJue3NlYWxlZE1hc3RlcjpKPT09MCYmWiE9PXZvaWQgMD9aOiQuc2VhbGVkTWFzdGVyLHNhbHQ6JC5zYWx0LnNsaWNlKCksY3JlZElkOiQuY3JlZElkPT09dm9pZCAwP3ZvaWQgMDokLmNyZWRJZC5zbGljZSgpfX12YXIgR1k9ImRpcGxvbWF0aWMucGluLyI7ZnVuY3Rpb24gelkoJCl7cmV0dXJuIEdZK1IwKCQpfWFzeW5jIGZ1bmN0aW9uIHhRKCQsWixKKXtsZXQgUT1hd2FpdCBaLmRlcml2ZUlkZW50aXR5KHpZKEopLDApO3JldHVybiAkLmJsYWtlMyhRLnB1YmxpY0tleSl9YXN5bmMgZnVuY3Rpb24gQlEoJCxaKXtsZXQgSj1hd2FpdCAkLmdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKSxRPWF3YWl0IHhRKCQsWixKKTtyZXR1cm57bjpKLGg6UX19YXN5bmMgZnVuY3Rpb24ga1EoJCxaLEope2xldCBRPWF3YWl0IHhRKCQsWixKLm4pO3JldHVybiBLWShRLEouaCl9ZnVuY3Rpb24gRVEoJCl7aWYoJD09PXZvaWQgMHx8JD09PW51bGx8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuO2xldCBaPSQ7aWYoIShaLm4gaW5zdGFuY2VvZiBVaW50OEFycmF5KXx8IShaLmggaW5zdGFuY2VvZiBVaW50OEFycmF5KSlyZXR1cm47aWYoWi5uLmJ5dGVMZW5ndGg8MXx8Wi5oLmJ5dGVMZW5ndGg8MSlyZXR1cm47cmV0dXJue246Wi5uLnNsaWNlKCksaDpaLmguc2xpY2UoKX19ZnVuY3Rpb24gZlEoJCl7cmV0dXJue246JC5uLnNsaWNlKCksaDokLmguc2xpY2UoKX19ZnVuY3Rpb24gS1koJCxaKXtpZigkLmJ5dGVMZW5ndGghPT1aLmJ5dGVMZW5ndGgpcmV0dXJuITE7bGV0IEo9MDtmb3IobGV0IFE9MDtRPCQuYnl0ZUxlbmd0aDtRKyspSnw9JFtRXV5aW1FdO3JldHVybiBKPT09MH12YXIgZSQ9InByZk1ldGEiLFFKPSJpZFBpbiIsZ1E9ImlkUHViIjtjbGFzcyBYSnsjJDtkYjsjWjtjb25zdHJ1Y3RvcigkLFope3RoaXMuZGI9JCx0aGlzLiNaPVp9YXN5bmMgc2F2ZSgkLFope3JldHVybiBhd2FpdCB0aGlzLiNRKCQpLHRoaXMuIyQ9JCx0aGlzLiMkfWFzeW5jIGxvYWQoKXtyZXR1cm4gdGhpcy4jJH1hc3luYyBjbGVhclNlc3Npb24oKXt0aGlzLiMkPXZvaWQgMH1hc3luYyB3aXBlKCl7dGhpcy4jJD12b2lkIDA7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZHdyaXRlIiksWj0kLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PnskLm9uY29tcGxldGU9KCk9PkooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksWi5kZWxldGUoZSQpLFouZGVsZXRlKFFKKSxaLmRlbGV0ZShnUSl9KX1hc3luYyBsb2FkUHJmTWV0YSgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBYPVouZ2V0KGUkKTtYLm9uc3VjY2Vzcz0oKT0+e0ooRlkoWC5yZXN1bHQpKX0sWC5vbmVycm9yPSgpPT5RKFguZXJyb3IpfSl9YXN5bmMgcGVyc2lzdFByZk1ldGEoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZHdyaXRlIiksSj1aLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWCk9PntpZihaLm9uY29tcGxldGU9KCk9PlEoKSxaLm9uZXJyb3I9KCk9PlgoWi5lcnJvciksJD09PXZvaWQgMCl7Si5kZWxldGUoZSQpO3JldHVybn1sZXQgWT17c2VhbGVkTWFzdGVyOiQuc2VhbGVkTWFzdGVyLnNsaWNlKCksc2FsdDokLnNhbHQuc2xpY2UoKSxjcmVkSWQ6JC5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9O0oucHV0KFksZSQpfSl9YXN5bmMgaGFzUHJmTWV0YSgpe3JldHVybiBhd2FpdCB0aGlzLmxvYWRQcmZNZXRhKCkhPT12b2lkIDB9YXN5bmMgbGFzdFByZkNyZWRJZCgpe2xldCAkPWF3YWl0IHRoaXMubG9hZFByZk1ldGEoKTtyZXR1cm4gJD8uY3JlZElkPT09dm9pZCAwP3ZvaWQgMDokLmNyZWRJZC5zbGljZSgpfWFzeW5jIG9wZW5QcmZTdG9yZSgkKXtsZXQgWj1hd2FpdCB0aGlzLmxvYWRQcmZNZXRhKCk7cmV0dXJuIG5ldyBKSih7cnBJZDokLnJwSWQscnBOYW1lOiQucnBOYW1lLG1ldGE6WixwZXJzaXN0TWV0YTooSik9PnRoaXMucGVyc2lzdFByZk1ldGEoSil9KX1hc3luYyNRKCQpe2F3YWl0IHRoaXMuI1koZ1EpO2xldCBaPWF3YWl0IHRoaXMuI0ooKTtpZihaIT09dm9pZCAwKXtpZighYXdhaXQga1EodGhpcy4jWiwkLFopKXRocm93IEVycm9yKCJbRElQTE9NQVRJQ10gc2VlZCBkb2VzIG5vdCBtYXRjaCB0aGlzIGRldmljZSdzIGlkZW50aXR5IChsb2NhbCBkYXRhIHdhcyBjcmVhdGVkIHdpdGggYSBkaWZmZXJlbnQgbWFzdGVyIHNlZWQpIik7cmV0dXJufWxldCBKPWF3YWl0IEJRKHRoaXMuI1osJCk7YXdhaXQgdGhpcy4jWChKKX0jSigpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBYPVouZ2V0KFFKKTtYLm9uc3VjY2Vzcz0oKT0+SihFUShYLnJlc3VsdCkpLFgub25lcnJvcj0oKT0+UShYLmVycm9yKX0pfSNYKCQpe2xldCBaPWZRKCQpLEo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZHdyaXRlIiksUT1KLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFgsWSk9PntKLm9uY29tcGxldGU9KCk9PlgoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvciksUS5wdXQoWixRSil9KX0jWSgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKFEwLCJyZWFkd3JpdGUiKSxKPVoub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxYKT0+e1oub25jb21wbGV0ZT0oKT0+USgpLFoub25lcnJvcj0oKT0+WChaLmVycm9yKSxKLmRlbGV0ZSgkKX0pfX1mdW5jdGlvbiBGWSgkKXtpZigkPT09dm9pZCAwfHwkPT09bnVsbHx8dHlwZW9mICQhPT0ib2JqZWN0IilyZXR1cm47bGV0IFo9JDtpZighKFouc2VhbGVkTWFzdGVyIGluc3RhbmNlb2YgVWludDhBcnJheSl8fCEoWi5zYWx0IGluc3RhbmNlb2YgVWludDhBcnJheSkpcmV0dXJuO2xldFtKLFFdPUEwKFouc2VhbGVkTWFzdGVyKTtpZihRIT09MHx8Sj09PXZvaWQgMClyZXR1cm47cmV0dXJue3NlYWxlZE1hc3RlcjpKLHNhbHQ6Wi5zYWx0LnNsaWNlKCksY3JlZElkOlouY3JlZElkIGluc3RhbmNlb2YgVWludDhBcnJheT9aLmNyZWRJZC5zbGljZSgpOnZvaWQgMH19Y2xhc3MgWUp7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGVucSgkLFope2xldCBKPVsuLi5aXTtpZihKLmxlbmd0aD09PTApcmV0dXJuO2xldCBRPXRoaXMuZGIudHJhbnNhY3Rpb24oSzAsInJlYWR3cml0ZSIpLFg9US5vYmplY3RTdG9yZShLMCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57US5vbmNvbXBsZXRlPSgpPT5ZKCksUS5vbmVycm9yPSgpPT5WKFEuZXJyb3IpO2ZvcihsZXQgVyBvZiBKKXtsZXQgej1SMChXKTtYLnB1dCh7aG9zdDokLGhhc2g6en0pfX0pfWFzeW5jIGRlcSgkLFope2xldCBKPVsuLi5aXTtpZihKLmxlbmd0aD09PTApcmV0dXJuO2xldCBRPXRoaXMuZGIudHJhbnNhY3Rpb24oSzAsInJlYWR3cml0ZSIpLFg9US5vYmplY3RTdG9yZShLMCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57US5vbmNvbXBsZXRlPSgpPT5ZKCksUS5vbmVycm9yPSgpPT5WKFEuZXJyb3IpO2ZvcihsZXQgVyBvZiBKKXtsZXQgej1SMChXKTtYLmRlbGV0ZShbJCx6XSl9fSl9YXN5bmMgbGlzdCgkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKEswKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWCk9PntsZXQgWT1KLmdldEFsbCgpO1kub25zdWNjZXNzPSgpPT57bGV0IFc9WS5yZXN1bHQuZmlsdGVyKCh6KT0+ei5ob3N0PT09JCkubWFwKCh6KT0+ei5oYXNoKTtRKFcubWFwKCh6KT0+UEooeikpKX0sWS5vbmVycm9yPSgpPT5YKFkuZXJyb3IpfSl9YXN5bmMgY291bnQoKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKEswKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PntsZXQgWD1aLmNvdW50KCk7WC5vbnN1Y2Nlc3M9KCk9PkooWC5yZXN1bHQpLFgub25lcnJvcj0oKT0+UShYLmVycm9yKX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkd3JpdGUiKSxaPSQub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+eyQub25jb21wbGV0ZT0oKT0+SigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxaLmNsZWFyKCl9KX19dmFyIFEwPSJzZWVkTWV0YSIsSjA9Imhvc3RzIixLMD0idXBsb2FkUXVldWUiLHowPSJkb3dubG9hZFF1ZXVlIixsPSJtZXNzYWdlcyIsSCQ9ImFwbGQiLG1RPTMsU1E9ImRpcGxvbWF0aWMtc3RvcmUtZGIiO2NsYXNzIHZRe3NlZWQ7aG9zdHM7dXBsb2Fkcztkb3dubG9hZHM7bWVzc2FnZXM7ZGI7Y29uc3RydWN0b3IoJCxaKXt0aGlzLmRiPSQsdGhpcy5zZWVkPW5ldyBYSigkLFopLHRoaXMuaG9zdHM9bmV3ICRKKCQpLHRoaXMudXBsb2Fkcz1uZXcgWUooJCksdGhpcy5kb3dubG9hZHM9bmV3IGVaKCQpLHRoaXMubWVzc2FnZXM9bmV3IFpKKCQsWil9YXN5bmMgd2lwZSgpe2F3YWl0IHRoaXMuaG9zdHMud2lwZSgpLGF3YWl0IHRoaXMudXBsb2Fkcy53aXBlKCksYXdhaXQgdGhpcy5kb3dubG9hZHMud2lwZSgpLGF3YWl0IHRoaXMubWVzc2FnZXMud2lwZSgpfX1hc3luYyBmdW5jdGlvbiBOWSgpe3JldHVybiBuZXcgUHJvbWlzZSgoJCxaKT0+e2xldCBKPWluZGV4ZWREQi5vcGVuKFNRLG1RKTtKLm9udXBncmFkZW5lZWRlZD0oKT0+e2xldHtyZXN1bHQ6USx0cmFuc2FjdGlvbjpYfT1KO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoUTApKVEuY3JlYXRlT2JqZWN0U3RvcmUoUTApO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoSjApKVEuY3JlYXRlT2JqZWN0U3RvcmUoSjAse2tleVBhdGg6ImxhYmVsIn0pO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoSzApKVEuY3JlYXRlT2JqZWN0U3RvcmUoSzAse2tleVBhdGg6WyJob3N0IiwiaGFzaCJdfSk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyh6MCkpUS5jcmVhdGVPYmplY3RTdG9yZSh6MCk7bGV0IFk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhsKSlZPVEuY3JlYXRlT2JqZWN0U3RvcmUobCk7ZWxzZXtpZighWCl0aHJvdyBFcnJvcigibWlzc2luZyB1cGdyYWRlIHRyYW5zYWN0aW9uIGZvciBtZXNzYWdlcyBzdG9yZSIpO1k9WC5vYmplY3RTdG9yZShsKX1pZighWS5pbmRleE5hbWVzLmNvbnRhaW5zKEgkKSlZLmNyZWF0ZUluZGV4KEgkLCJhcGxkIix7dW5pcXVlOiExfSl9LEoub25ibG9ja2VkPSgpPT57Y29uc29sZS53YXJuKGBbRElQTE9NQVRJQ10gcHJvdG9jb2wgc3RvcmUgSURCIHVwZ3JhZGUgYmxvY2tlZCAoJHtTUX0g4oaSIHYke21RfSk7IHdhaXRpbmcgZm9yIG90aGVyIGNvbm5lY3Rpb25zIHRvIGNsb3NlYCl9LEoub25zdWNjZXNzPSgpPT57bGV0IFE9Si5yZXN1bHQ7US5vbnZlcnNpb25jaGFuZ2U9KCk9PntRLmNsb3NlKCl9LCQoUSl9LEoub25lcnJvcj0oKT0+WihKLmVycm9yPz9FcnJvcigicHJvdG9jb2wgc3RvcmUgSW5kZXhlZERCIG9wZW4gZmFpbGVkIikpfSl9YXN5bmMgZnVuY3Rpb24gYlEoJCl7bGV0IFo9YXdhaXQgTlkoKTtpZih0eXBlb2YgbmF2aWdhdG9yPCJ1IiYmbmF2aWdhdG9yLnN0b3JhZ2U/LnBlcnNpc3QpdHJ5e2F3YWl0IFByb21pc2UucmFjZShbbmF2aWdhdG9yLnN0b3JhZ2UucGVyc2lzdCgpLG5ldyBQcm9taXNlKChKKT0+e3NldFRpbWVvdXQoKCk9PkooITEpLDIwMDApfSldKX1jYXRjaHt9cmV0dXJuIG5ldyB2UShaLCQpfWNsYXNzIFZKe2NsaWVudDtlbnREQjtwb3N0O3doZW5SZWFkeTtyZXNvbHZlUmVhZHk7cmVqZWN0UmVhZHk7Y29uc3RydWN0b3IoJCl7dGhpcy5wb3N0PSQsdGhpcy53aGVuUmVhZHk9bmV3IFByb21pc2UoKFosSik9Pnt0aGlzLnJlc29sdmVSZWFkeT1aLHRoaXMucmVqZWN0UmVhZHk9Sn0pfWFzeW5jIGluaXQoKXt0cnl7bGV0ICQ9YXdhaXQgYlEoYyQpLFo9YXdhaXQgaEooe2NhY2hlOiExfSksSj1uZXcgayQoWi5hcHBseSwoKT0+Wi5jbGVhcigpLChZKT0+e2lmKFkubGVuZ3RoPDEpcmV0dXJuO3RoaXMucG9zdCh7a2luZDoiZGlydHkiLGVpZHM6WS5tYXAoKFYpPT5WLnNsaWNlKCkpfSl9KSxRPUouY2xlYXI7Si5jbGVhcj1hc3luYygpPT57bGV0IFk9YXdhaXQgUSgpO2lmKFk9PT0wKXRoaXMucG9zdCh7a2luZDoid2lwZWQifSk7cmV0dXJuIFl9O2xldCBYPW5ldyBmWihuZXcgR1osSiwkLEJKLGMkKTt0aGlzLmNsaWVudD1YLHRoaXMuZW50REI9WixYLmNsaWVudFN0YXRlLmxpc3RlbigoKT0+e3RoaXMuZW1pdENsaWVudFN0YXRlKCl9KSxYLnhmZXJTdGF0ZS5saXN0ZW4oKCk9Pnt0aGlzLmVtaXRYZmVyU3RhdGUoKX0pLGF3YWl0IHRoaXMuZW1pdFhmZXJTdGF0ZSgpLHRoaXMucG9zdCh7a2luZDoicmVhZHkifSksdGhpcy5tYXJrUmVhZHkoKX1jYXRjaCgkKXtsZXQgWj0kIGluc3RhbmNlb2YgRXJyb3I/JDpFcnJvcihTdHJpbmcoJCkpO3Rocm93IHRoaXMucG9zdCh7a2luZDoiaW5pdEVycm9yIixtZXNzYWdlOloubWVzc2FnZX0pLHRoaXMuZmFpbFJlYWR5KFopLFp9fW1hcmtSZWFkeSgpe2xldCAkPXRoaXMucmVzb2x2ZVJlYWR5O2lmKHRoaXMucmVzb2x2ZVJlYWR5PXZvaWQgMCx0aGlzLnJlamVjdFJlYWR5PXZvaWQgMCwkKSQoKX1mYWlsUmVhZHkoJCl7bGV0IFo9dGhpcy5yZWplY3RSZWFkeTtpZih0aGlzLnJlc29sdmVSZWFkeT12b2lkIDAsdGhpcy5yZWplY3RSZWFkeT12b2lkIDAsWilaKCQpfXJlcXVpcmVDbGllbnQoKXtpZighdGhpcy5jbGllbnQpdGhyb3cgRXJyb3IoIldvcmtlclJ1bnRpbWUgbm90IGluaXRpYWxpemVkIik7cmV0dXJuIHRoaXMuY2xpZW50fWFzeW5jIGVtaXRDbGllbnRTdGF0ZSgpe2xldCAkPXRoaXMuY2xpZW50O2lmKCEkKXJldHVybjtsZXQgWj1hd2FpdCAkLmNsaWVudFN0YXRlLmdldCgpO3RoaXMucG9zdCh7a2luZDoiY2xpZW50U3RhdGUiLGNvbm5lY3RlZDpaLmNvbm5lY3RlZH0pfWFzeW5jIGVtaXRYZmVyU3RhdGUoKXtsZXQgJD10aGlzLmNsaWVudDtpZighJClyZXR1cm47bGV0IFo9YXdhaXQgJC54ZmVyU3RhdGUuZ2V0KCk7dGhpcy5wb3N0KHtraW5kOiJ4ZmVyU3RhdGUiLHN0YXRlOlp9KX1ob3N0RnJvbVNlcmlhbGl6ZWQoJCl7cmV0dXJue2hhbmRsZTpuZXcgVVJMKCQuaGFuZGxlKSxsYWJlbDokLmxhYmVsLGlkeDokLmlkeH19YXN5bmMgaGFuZGxlKCQpe2F3YWl0IHRoaXMud2hlblJlYWR5O2xldCBaPXRoaXMucmVxdWlyZUNsaWVudCgpO3N3aXRjaCgkLm9wKXtjYXNlInBpbmciOnJldHVybiJwb25nIjtjYXNlInNldFNlZWQiOntsZXRbSixRXT1HMC5mcm9tQnl0ZXMoJC5zZWVkKTtpZigkLnNlZWQuZmlsbCgwKSxRIT09MHx8Sj09PXZvaWQgMCl0aHJvdyBuZXcgRjAoUSk7YXdhaXQgWi5zZXRTZWVkKEose3BlcnNpc3Q6JC5wZXJzaXN0fSk7cmV0dXJufWNhc2UibGluayI6e2F3YWl0IFoubGluayh0aGlzLmhvc3RGcm9tU2VyaWFsaXplZCgkLmhvc3QpLCQuY29ubmVjdD8/ITApO3JldHVybn1jYXNlInVubGluayI6e2F3YWl0IFoudW5saW5rKCQubGFiZWwpO3JldHVybn1jYXNlImNvbm5lY3QiOnthd2FpdCBaLmNvbm5lY3QoJC5saXN0ZW4/PyEwLCQuc3luYz8/ITApO3JldHVybn1jYXNlImRpc2Nvbm5lY3QiOnthd2FpdCBaLmRpc2Nvbm5lY3QoKTtyZXR1cm59Y2FzZSJzeW5jIjpyZXR1cm4gYXdhaXQgWi5zeW5jKCk7Y2FzZSJyZWJ1aWxkIjpyZXR1cm4gYXdhaXQgWi5yZWJ1aWxkKHtjaGVja0hvc3Q6JC5jaGVja0hvc3Q/PyEwfSk7Y2FzZSJyZWNvbmNpbGUiOntsZXRbSixRXT1hd2FpdCBaLnJlY29uY2lsZSgkLmhvc3RMYWJlbCx7cHVsbDokLnB1bGwscHVzaDokLnB1c2gsc3luYzokLnN5bmN9KTtpZihRIT09MCl0aHJvdyBuZXcgRjAoUSk7aWYoIUopdGhyb3cgbmV3IEYwKDEyKTtyZXR1cm4gSn1jYXNlIm1zZ2NoZWNrIjpyZXR1cm4gYXdhaXQgWi5tc2djaGVjaygpO2Nhc2UiZW50Y2hlY2siOntsZXQgSj10aGlzLmVudERCO2lmKCFKKXRocm93IG5ldyBGMCgxMik7bGV0W1EsWF09YXdhaXQgSi5jaGVja3N1bShjJCk7aWYoWCE9PTApdGhyb3cgbmV3IEYwKFgpO2lmKCFRKXRocm93IG5ldyBGMCgxMik7cmV0dXJuIFF9Y2FzZSJ3aXBlIjp7YXdhaXQgWi53aXBlKHttc2dzOiQubXNncyxlbnRzOiQuZW50cyxtZXRhOiQubWV0YSxzZWVkOiQuc2VlZH0pO3JldHVybn1jYXNlImltcG9ydCI6e2xldCBKPSQuYnl0ZXMuc2xpY2UoKSxRPW5ldyBCbG9iKFtKXSksWD1uZXcgRmlsZShbUV0sImltcG9ydC5kaXAiKTtyZXR1cm4gYXdhaXQgWi5pbXBvcnQoWCl9Y2FzZSJleHBvcnQiOntsZXRbSixRXT1hd2FpdCBaLmV4cG9ydEJ5dGVzKCk7aWYoUSE9PTApdGhyb3cgbmV3IEYwKFEpO2lmKCFKKXRocm93IG5ldyBGMCgxMik7cmV0dXJuIEp9Y2FzZSJnZXRYZmVyU3RhdGUiOnJldHVybiBhd2FpdCBaLnhmZXJTdGF0ZS5nZXQoKTtkZWZhdWx0OntsZXQgSj0kO3Rocm93IEVycm9yKCJ1bmtub3duIHdvcmtlciBjb21tYW5kIil9fX19Y2xhc3MgRjAgZXh0ZW5kcyBFcnJvcntzdGF0dXM7Y29uc3RydWN0b3IoJCl7c3VwZXIoYFdvcmtlclN0YXR1c0Vycm9yOiAke0RbJF19YCk7dGhpcy5zdGF0dXM9JDt0aGlzLm5hbWU9IldvcmtlclN0YXR1c0Vycm9yIn19ZnVuY3Rpb24gJFooJCxaKXtyZXR1cm57a2luZDoicmVwbHkiLGlkOiQsb2s6ITAscmVzdWx0Olp9fWZ1bmN0aW9uIFdKKCQsWil7cmV0dXJue2tpbmQ6InJlcGx5IixpZDokLG9rOiExLHN0YXR1czpafX12YXIgXzA9Z2xvYmFsVGhpcyx5UT1uZXcgVkooKCQsWik9PntpZihaJiZaLmxlbmd0aD4wKV8wLnBvc3RNZXNzYWdlKCQsWik7ZWxzZSBfMC5wb3N0TWVzc2FnZSgkKX0pO18wLm9ubWVzc2FnZT0oJCk9PntsZXQgWj0kLmRhdGE7aWYoIUZKKFopKXJldHVybjtSWShaKX07YXN5bmMgZnVuY3Rpb24gUlkoJCl7dHJ5e2xldCBaPWF3YWl0IHlRLmhhbmRsZSgkKTtpZigoJC5vcD09PSJleHBvcnQifHwkLm9wPT09Im1zZ2NoZWNrInx8JC5vcD09PSJlbnRjaGVjayIpJiZaIGluc3RhbmNlb2YgVWludDhBcnJheSl7bGV0IEo9Wi5zbGljZSgpO18wLnBvc3RNZXNzYWdlKCRaKCQuaWQsSiksW0ouYnVmZmVyXSk7cmV0dXJufWlmKCQub3A9PT0icmVjb25jaWxlIiYmWiYmdHlwZW9mIFo9PT0ib2JqZWN0IiYmIm1zZ2NoZWNrImluIFomJloubXNnY2hlY2sgaW5zdGFuY2VvZiBVaW50OEFycmF5KXtsZXQgSj1aLm1zZ2NoZWNrLnNsaWNlKCksUT17Li4uWixtc2djaGVjazpKfTtfMC5wb3N0TWVzc2FnZSgkWigkLmlkLFEpLFtKLmJ1ZmZlcl0pO3JldHVybn1fMC5wb3N0TWVzc2FnZSgkWigkLmlkLFopKX1jYXRjaChaKXtpZihaIGluc3RhbmNlb2YgRjApe18wLnBvc3RNZXNzYWdlKFdKKCQuaWQsWi5zdGF0dXMpKTtyZXR1cm59Y29uc29sZS5lcnJvcigid29ya2VyIGNvbW1hbmQgZmFpbGVkIixaKSxfMC5wb3N0TWVzc2FnZShXSigkLmlkLDEyKSl9fXlRLmluaXQoKS5jYXRjaCgoJCk9Pntjb25zb2xlLmVycm9yKCJ3b3JrZXIgaW5pdCBmYWlsZWQiLCQpfSk7Cg==";var IW=typeof globalThis.Worker==="function"?globalThis.Worker:void 0,PV=IW===void 0?void 0:IW.prototype.postMessage,LW;function uK(){if(typeof cW!=="string"||cW.length===0)throw Error("[DIPLOMATIC] worker source not embedded; run pkg build before spawn");return atob(cW)}function iK(){if(LW!==void 0)return LW;let Z=new Blob([uK()],{type:"text/javascript"});return LW=URL.createObjectURL(Z),LW}function X0(){if(IW===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot spawn sync worker");return new IW(iK(),{type:"module"})}function W0(Z,X,W){if(PV===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot post to sync worker");if(W!==void 0&&W.length>0)PV.call(Z,X,{transfer:W});else PV.call(Z,X)}var OK=new TextEncoder().encode("diplomatic.wrap.v1"),V0=new TextEncoder().encode("diplomatic.pair.v1"),jK=32,BK=16,KZ=new SX;class t{#Z;constructor(Z){this.#Z=Z}static async fromRandom(){let Z=await KZ.gen256BitSecureRandomSeed(),[X,W]=WZ(Z);if(W!==0||X===void 0)throw Error(`enclave: invalid random seed (${W})`);return new t(X)}static fromBytes(Z){let[X,W]=WZ(Z);if(W!==0)return Y(W);if(X===void 0)return Y(10);let[V,l]=WZ(X.slice());if(l!==0)return Y(l);if(V===void 0)return Y(10);return d(new t(V))}async sealWithPasskey(Z){let X=Z?.salt??OX,W=Z?.credId;if(W===void 0&&Z?.createCredIfNeeded===!0){let[K,G]=await Z0({rpId:Z?.rpId,rpName:Z?.rpName,userName:Z?.userName??"diplomatic-prf"});if(G!==0)return Y(G);if(K===void 0)return Y(24);if(!K.prfEnabled)return Y(24);W=K.credId}let[V,l]=await jX({rpId:Z?.rpId,rpName:Z?.rpName,credId:W,salt:X});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await this.#X(V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);return d({sealedMaster:K,salt:X.slice(),credId:V.credId.slice()})}finally{V.prf.fill(0)}}static async unsealWithPasskey(Z,X){let[W,V]=await jX({rpId:X.rpId,rpName:X.rpName,credId:X.credId,salt:X.salt});if(V!==0)return Y(V);if(W===void 0)return Y(7);try{let[l,K]=await t.#W(Z,W.prf);if(K!==0)return Y(K);if(l===void 0)return Y(12);return d({enclave:l,credId:W.credId.slice()})}finally{W.prf.fill(0)}}async persistToLargeBlob(Z=[],X){let W=X?.credId;if(W===void 0){let[K,G]=await TW(X);if(G!==0)return Y(G);if(K===void 0)return Y(24);W=K}let[V,l]=this.#V(Z);if(l!==0)return Y(l);if(V===void 0)return Y(12);try{let K=await iX(W,V,X);if(K!==0)return Y(K);return d(W)}finally{V.fill(0)}}static async fromLargeBlob(Z){let[X,W]=await kW(Z?.credId,Z);if(W!==0)return Y(W);if(X===void 0)return Y(7);try{return t.#l(X.blob,X.credId)}finally{X.blob.fill(0)}}static async clearLargeBlob(Z,X){return iX(Z,new Uint8Array(bZ),X)}async sealPairPackageBody(Z,X){let W=X?.salt??OX,[V,l]=await jX({rpId:X?.rpId,rpName:X?.rpName,credId:X?.credId,salt:W});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await QW(KZ,V.prf,V0);if(G!==0)return Y(G);if(K===void 0)return Y(12);try{let[m,R]=WZ(this.#Z.slice());if(R!==0)return Y(R);if(m===void 0)return Y(10);let J={masterSeed:m,hosts:Z.map((k)=>({handle:k.handle,label:k.label,idx:k.idx??0}))},C=new U,F=C.writeStruct(dW,J);if(F!==0)return m.fill(0),Y(F);let b=C.result();m.fill(0);let T;try{T=await KZ.encryptXSalsa20Poly1305Combined(b,K)}catch{return b.fill(0),Y(12)}return b.fill(0),d({body:T,salt:W.slice(),credId:V.credId.slice()})}finally{K.fill(0)}}finally{V.prf.fill(0)}}static async openPairPackageBody(Z,X){let[W,V]=await jX({rpId:X.rpId,rpName:X.rpName,credId:X.credId,salt:X.salt});if(V!==0)return Y(V);if(W===void 0)return Y(7);try{let[l,K]=await QW(KZ,W.prf,V0);if(K!==0)return Y(K);if(l===void 0)return Y(12);try{let G;try{G=await KZ.decryptXSalsa20Poly1305Combined(Z,l)}catch{return Y(20)}let m=new P(G),[R,J]=m.readStruct(dW);if(G.fill(0),J!==0)return Y(J);if(R===void 0)return Y(14);let[C,F]=t.fromBytes(R.masterSeed);if(R.masterSeed.fill(0),F!==0)return Y(F);if(C===void 0)return Y(12);let[b,T]=await C.#X(W.prf);if(T!==0)return Y(T);if(b===void 0)return Y(12);return d({enclave:C,hosts:R.hosts.map((k)=>({...k})),sealedMaster:b,credId:W.credId.slice()})}finally{l.fill(0)}}finally{W.prf.fill(0)}}spawnSyncWorker(Z){let X=X0(),W=this.#Z.slice();return W0(X,{id:Z.id,op:"setSeed",seed:W,persist:Z.persist},[W.buffer]),X}deriveCipher(Z,X){let W=Z.slice(),V=(G)=>this.#K(W,G),l=(G)=>this.#Y(W,G);return{encrypt:Object.freeze({encrypt:V}),decrypt:Object.freeze({decrypt:l}),both:Object.freeze({encrypt:V,decrypt:l})}[X]}async deriveIdentity(Z,X=0){let W=Z,V=X,l=await this.#m(W,V),K=l.publicKey;return l.privateKey.fill(0),Object.freeze({publicKey:K,sign:(G)=>this.#J(W,V,G),kdmFor:(G)=>this.#C(W,V,G)})}async#X(Z){let[X,W]=await QW(KZ,Z);if(W!==0)return Y(W);if(X===void 0)return Y(12);try{let V=await KZ.encryptXSalsa20Poly1305Combined(this.#Z,X);return QZ(V)}catch{return Y(12)}finally{X.fill(0)}}static async#W(Z,X){let[,W]=QZ(Z);if(W!==0)return Y(W);let[V,l]=await QW(KZ,X);if(l!==0)return Y(l);if(V===void 0)return Y(12);let K;try{try{K=await KZ.decryptXSalsa20Poly1305Combined(Z,V)}catch{return Y(20)}return t.fromBytes(K)}finally{V.fill(0),K?.fill(0)}}#V(Z){let[X,W]=WZ(this.#Z.slice());if(W!==0)return Y(W);if(X===void 0)return Y(10);let[V,l]=_l(X,Z);if(X.fill(0),l!==0)return Y(l);if(V===void 0)return Y(12);try{let K=new U,G=K.writeStruct(hV,V);if(G!==0)return Y(G);return d(K.result())}finally{V.masterSeed.fill(0)}}static#l(Z,X){if(Z.byteLength===0||Z.every((K)=>K===0))return Y(22);if(Z.byteLength===bZ){if(Z.every((m)=>m===0))return Y(22);let[K,G]=t.fromBytes(Z);if(G!==0)return Y(G);if(K===void 0)return Y(12);return d({enclave:K,hosts:[],credId:X})}let W=new P(Z),[V,l]=W.readStruct(hV);if(l!==0)return Y(l);if(V===void 0)return Y(14);try{if(V.masterSeed.every((m)=>m===0))return Y(22);let[K,G]=t.fromBytes(V.masterSeed);if(G!==0)return Y(G);if(K===void 0)return Y(12);return d({enclave:K,hosts:V.hosts.map((m)=>({...m})),credId:X})}finally{V.masterSeed.fill(0)}}async#K(Z,X){let W=await this.#G(Z);try{return await KZ.encryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#Y(Z,X){let W=await this.#G(Z);try{return await KZ.decryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#G(Z){return KZ.blake3(QX(this.#Z,Z))}async#R(Z,X){let W=new TextEncoder().encode(Z),V=new Uint8Array(8);return new DataView(V.buffer).setBigUint64(0,BigInt(X),!1),await this.#G(QX(W,V))}async#m(Z,X){let W=await this.#R(Z,X);try{return await KZ.deriveEd25519KeyPair(W)}finally{W.fill(0)}}async#J(Z,X,W){let V=await this.#m(Z,X);try{return await KZ.signEd25519(W,V.privateKey)}finally{V.privateKey.fill(0)}}async#C(Z,X,W){let V=await this.#m(Z,X),l=QX(V.privateKey,W);V.privateKey.fill(0);try{return(await KZ.blake3(l)).slice(0,hZ)}finally{l.fill(0)}}}async function QW(Z,X,W=OK){if(X.byteLength<BK)return Y(10);let V=await Z.blake3(QX(X,W));return d(V.slice(0,jK))}class pW{#Z;#X;#W;#V;constructor(Z){if(this.#V=Z.persistMeta,this.#W={rpId:Z.rpId,rpName:Z.rpName},Z.meta!==void 0)this.#X=qZ(Z.meta)}get meta(){return this.#X===void 0?void 0:qZ(this.#X)}setMeta(Z){this.#X=Z===void 0?void 0:qZ(Z)}async save(Z,X){if(X?.persist===!0)return Promise.reject(Error("prf-store: use wrapAndSave(enclave) to persist sealed master"));return this.#Z=Z,this.#Z}async wrapAndSave(Z,X){let[W,V]=await Z.sealWithPasskey({...this.#W,salt:X?.salt,credId:X?.credId??this.#X?.credId,createCredIfNeeded:X?.createCredIfNeeded??X?.credId===void 0,userName:"diplomatic-prf"});if(V!==0)return Y(V);if(W===void 0)return Y(12);let l={sealedMaster:W.sealedMaster,salt:W.salt,credId:W.credId};return this.#X=l,this.#Z=Z,await this.#V(qZ(l)),d(this.#Z)}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await t.unsealWithPasskey(Z.sealedMaster,{...this.#W,salt:Z.salt,credId:Z.credId});if(W!==0)return Y(W);if(this.#Z=X.enclave,X.credId.byteLength>0&&(Z.credId===void 0||!n(Z.credId,X.credId))){let V={sealedMaster:Z.sealedMaster,salt:Z.salt,credId:X.credId.slice()};this.#X=V,await this.#V(qZ(V))}return d(X.enclave)}async adoptSealed(Z,X){return this.#X=qZ(X),this.#Z=Z,await this.#V(qZ(X)),d(this.#Z)}async wipe(){this.#Z=void 0,this.#X=void 0,await this.#V(void 0)}}function qZ(Z){let[X,W]=QZ(Z.sealedMaster.slice());return{sealedMaster:W===0&&X!==void 0?X:Z.sealedMaster,salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()}}var EK="diplomatic.pin/";function wK(Z){return EK+YZ(Z)}async function l0(Z,X,W){let V=await X.deriveIdentity(wK(W),0);return Z.blake3(V.publicKey)}async function yW(Z,X){let W=await Z.gen256BitSecureRandomSeed(),V=await l0(Z,X,W);return{n:W,h:V}}async function zW(Z,X,W){let V=await l0(Z,X,W.n);return DK(V,W.h)}function K0(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.n instanceof Uint8Array)||!(X.h instanceof Uint8Array))return;if(X.n.byteLength<1||X.h.byteLength<1)return;return{n:X.n.slice(),h:X.h.slice()}}function NW(Z){return{n:Z.n.slice(),h:Z.h.slice()}}function DK(Z,X){if(Z.byteLength!==X.byteLength)return!1;let W=0;for(let V=0;V<Z.byteLength;V++)W|=Z[V]^X[V];return W===0}var xW="prfMeta",UV="idPin",G0="idPub";class gW{#Z;db;#X;constructor(Z,X){this.db=Z,this.#X=X}async save(Z,X){return await this.#W(Z),this.#Z=Z,this.#Z}async load(){return this.#Z}async clearSession(){this.#Z=void 0}async wipe(){this.#Z=void 0;let Z=this.db.transaction(GZ,"readwrite"),X=Z.objectStore(GZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.delete(xW),X.delete(UV),X.delete(G0)})}async loadPrfMeta(){let X=this.db.transaction(GZ,"readonly").objectStore(GZ);return new Promise((W,V)=>{let l=X.get(xW);l.onsuccess=()=>{W(AK(l.result))},l.onerror=()=>V(l.error)})}async persistPrfMeta(Z){let X=this.db.transaction(GZ,"readwrite"),W=X.objectStore(GZ);return new Promise((V,l)=>{if(X.oncomplete=()=>V(),X.onerror=()=>l(X.error),Z===void 0){W.delete(xW);return}let K={sealedMaster:Z.sealedMaster.slice(),salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()};W.put(K,xW)})}async hasPrfMeta(){return await this.loadPrfMeta()!==void 0}async lastPrfCredId(){let Z=await this.loadPrfMeta();return Z?.credId===void 0?void 0:Z.credId.slice()}async openPrfStore(Z){let X=await this.loadPrfMeta();return new pW({rpId:Z.rpId,rpName:Z.rpName,meta:X,persistMeta:(W)=>this.persistPrfMeta(W)})}async#W(Z){await this.#K(G0);let X=await this.#V();if(X!==void 0){if(!await zW(this.#X,Z,X))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)");return}let W=await yW(this.#X,Z);await this.#l(W)}#V(){let X=this.db.transaction(GZ,"readonly").objectStore(GZ);return new Promise((W,V)=>{let l=X.get(UV);l.onsuccess=()=>W(K0(l.result)),l.onerror=()=>V(l.error)})}#l(Z){let X=NW(Z),W=this.db.transaction(GZ,"readwrite"),V=W.objectStore(GZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error),V.put(X,UV)})}#K(Z){let X=this.db.transaction(GZ,"readwrite"),W=X.objectStore(GZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}}function AK(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.sealedMaster instanceof Uint8Array)||!(X.salt instanceof Uint8Array))return;let[W,V]=QZ(X.sealedMaster);if(V!==0||W===void 0)return;return{sealedMaster:W,salt:X.salt.slice(),credId:X.credId instanceof Uint8Array?X.credId.slice():void 0}}class uV{db;constructor(Z){this.db=Z}async enq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(FZ,"readwrite"),l=V.objectStore(FZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=YZ(m);l.put({host:Z,hash:R})}})}async deq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(FZ,"readwrite"),l=V.objectStore(FZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=YZ(m);l.delete([Z,R])}})}async list(Z){let W=this.db.transaction(FZ,"readonly").objectStore(FZ);return new Promise((V,l)=>{let K=W.getAll();K.onsuccess=()=>{let m=K.result.filter((R)=>R.host===Z).map((R)=>R.hash);V(m.map((R)=>IX(R)))},K.onerror=()=>l(K.error)})}async count(){let X=this.db.transaction(FZ,"readonly").objectStore(FZ);return new Promise((W,V)=>{let l=X.count();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(FZ,"readwrite"),X=Z.objectStore(FZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var GZ="seedMeta",lZ="hosts",FZ="uploadQueue",CZ="downloadQueue",v="messages",PX="apld",m0=3,Y0="diplomatic-store-db";class iV{seed;hosts;uploads;downloads;messages;db;constructor(Z,X){this.db=Z,this.seed=new gW(Z,X),this.hosts=new MV(Z),this.uploads=new uV(Z),this.downloads=new gV(Z),this.messages=new HV(Z,X)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}async function vK(){return new Promise((Z,X)=>{let W=indexedDB.open(Y0,m0);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!V.objectStoreNames.contains(GZ))V.createObjectStore(GZ);if(!V.objectStoreNames.contains(lZ))V.createObjectStore(lZ,{keyPath:"label"});if(!V.objectStoreNames.contains(FZ))V.createObjectStore(FZ,{keyPath:["host","hash"]});if(!V.objectStoreNames.contains(CZ))V.createObjectStore(CZ);let K;if(!V.objectStoreNames.contains(v))K=V.createObjectStore(v);else{if(!l)throw Error("missing upgrade transaction for messages store");K=l.objectStore(v)}if(!K.indexNames.contains(PX))K.createIndex(PX,"apld",{unique:!1})},W.onblocked=()=>{console.warn(`[DIPLOMATIC] protocol store IDB upgrade blocked (${Y0} → v${m0}); waiting for other connections to close`)},W.onsuccess=()=>{let V=W.result;V.onversionchange=()=>{V.close()},Z(V)},W.onerror=()=>X(W.error??Error("protocol store IndexedDB open failed"))})}async function OV(Z){let X=await vK();if(typeof navigator<"u"&&navigator.storage?.persist)try{await Promise.race([navigator.storage.persist(),new Promise((W)=>{setTimeout(()=>W(!1),2000)})])}catch{}return new iV(X,Z)}function R0(Z){if(!Z||typeof Z!=="object")return!1;if(!("kind"in Z))return!1;return typeof Z.kind==="string"}function J0(Z){if(typeof Z!=="number")return;return Z}function $K(Z){if(!Z||typeof Z!=="object")return;if(!("phase"in Z))return;let X=oK(Z.phase);if(X===void 0)return;let W={phase:X};if("host"in Z&&typeof Z.host==="string")W.host=Z.host;if("done"in Z&&typeof Z.done==="number")W.done=Z.done;if("total"in Z&&typeof Z.total==="number")W.total=Z.total;if("bytesDone"in Z&&typeof Z.bytesDone==="number")W.bytesDone=Z.bytesDone;if("bytesTotal"in Z&&typeof Z.bytesTotal==="number")W.bytesTotal=Z.bytesTotal;return W}function oK(Z){if(Z==="peek"||Z==="pull"||Z==="open"||Z==="exec"||Z==="push"||Z==="import"||Z==="idle"||Z==="apply")return Z==="apply"?"exec":Z;return}function C0(Z){if(!Z||typeof Z!=="object")return;if(!("numUploads"in Z)||!("numDownloads"in Z))return;if(typeof Z.numUploads!=="number"||typeof Z.numDownloads!=="number")return;let X={phase:"idle"};if("progress"in Z){let W=$K(Z.progress);if(W===void 0)return;X=W}return{numUploads:Z.numUploads,numDownloads:Z.numDownloads,progress:X}}var dZ="[DIPLOMATIC]";class EX{worker;state;store;local;nextId=1;pending=new Map;readyTimeoutMs;scheduledSync;cachedClientState={hasSeed:!1,hasHost:!1,connected:!1};cachedXferState={numUploads:0,numDownloads:0,progress:DZ};clientState;xferState;constructor(Z,X,W,V,l){this.state=Z,this.store=X,this.readyTimeoutMs=l,this.clientState=new TZ(async()=>this.cachedClientState),this.xferState=new TZ(async()=>this.cachedXferState),this.scheduledSync=new gX(V,async()=>{if(!this.worker)return;try{await this.request({id:this.allocId(),op:"sync"})}catch(K){console.error(`${dZ} worker sync after local write failed`,K)}}),this.local=new RX(W,Z,X,()=>{throw Error(`${dZ} local writer has no transport (use worker for network)`)},bX,!0,void 0,void 0,()=>{this.scheduledSync.schedule()}),this.local.xferState.listen((K)=>{this.cachedXferState={numUploads:K.numUploads,numDownloads:K.numDownloads,progress:this.cachedXferState.progress},this.xferState.emit()})}bindWorker(Z){let X=this.worker;if(X){X.onmessage=null,X.onerror=null,X.onmessageerror=null;try{X.terminate()}catch{}}this.worker=Z,Z.onmessage=(W)=>{this.onMessage(W.data)},Z.onerror=(W)=>{console.error(`${dZ} worker error`,W),this.failPending(Error(`${dZ} worker failed to load`))},Z.onmessageerror=()=>{this.failPending(Error(`${dZ} worker message error`))}}failPending(Z){for(let[,X]of this.pending)X.reject(Z);this.pending.clear()}async flushScheduledSync(){await this.scheduledSync.flush()}static async open(Z,X,W={}){let V=W.clock??new PZ,l=W.syncDebounceMs??XW,K=W.readyTimeoutMs??15000,G=new EX(Z,X,V,l,K);return await G.hydrateStateFromStore(X),G}async hydrateStateFromStore(Z){await this.loadSession(!1);let X=await Z.uploads.count(),W=await Z.downloads.count();this.cachedXferState={numUploads:X,numDownloads:W,progress:DZ}}async loadSession(Z){let X=await this.store.seed.load(),W=await this.store.hosts.list();this.cachedClientState={hasSeed:X!==void 0,hasHost:Array.from(W).length>0,connected:Z}}async pullRemoteXfer(){let Z=await this.request({id:this.allocId(),op:"getXferState"}),X=C0(Z);if(X!==void 0)this.cachedXferState=X}requireWorker(){if(!this.worker)throw Error(`${dZ} no sync worker; call setSeed first`);return this.worker}async ping(){if(await this.request({id:this.allocId(),op:"ping"})!=="pong")throw Error(`${dZ} worker ping failed`)}terminate(){this.scheduledSync.cancel();let Z=this.worker;if(this.worker=void 0,Z)try{Z.terminate()}catch{}this.failPending(Error(`${dZ} worker terminated`))}onMessage(Z){if(!R0(Z))return;let X=Z;switch(X.kind){case"ready":return;case"initError":{this.failPending(Error(`${dZ} worker init failed: ${X.message}`));return}case"clientState":{if(this.cachedClientState.connected===X.connected)return;this.cachedClientState={...this.cachedClientState,connected:X.connected},this.clientState.emit();return}case"xferState":{this.cachedXferState=X.state,this.xferState.emit();return}case"dirty":{this.state.refresh(X.eids.map(fK));return}case"wiped":{this.state.clear();return}case"reply":{let W=this.pending.get(X.id);if(!W)return;if(this.pending.delete(X.id),X.ok)W.resolve(X.result);else W.reject(new BX(X.status));return}default:return}}allocId(){let Z=this.nextId;return this.nextId+=1,Z}request(Z,X){let W=this.requireWorker();return new Promise((V,l)=>{if(this.pending.set(Z.id,{resolve:V,reject:l}),X&&X.length>0)W.postMessage(Z,X);else W.postMessage(Z)})}async requestStatus(Z,X){try{let W=await this.request(Z,X),V=J0(W);if(V!==void 0)return V;return 0}catch(W){if(W instanceof BX)return W.status;return 12}}serializeHost(Z){return{handle:Z.handle.href,label:Z.label,idx:Z.idx??0}}async setSeed(Z,X){await this.local.setSeed(Z,X),await this.loadSession(!1),this.clientState.emit();let W=this.allocId(),V=this.readyTimeoutMs;await new Promise((l,K)=>{let G=void 0,m=(R)=>{if(G!==void 0)clearTimeout(G);R()};this.pending.set(W,{resolve:(R)=>m(()=>l(R)),reject:(R)=>m(()=>K(R))}),G=setTimeout(()=>{this.pending.delete(W),K(Error(`${dZ} setSeed worker timeout after ${V}ms`))},V);try{let R=Z.spawnSyncWorker({id:W,persist:X?.persist});this.bindWorker(R)}catch(R){if(this.pending.delete(W),G!==void 0)clearTimeout(G);K(R instanceof Error?R:Error(String(R)))}});try{await this.pullRemoteXfer()}catch{}}async link(Z,X=!0){await this.local.link(Z,!1),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),await this.request({id:this.allocId(),op:"link",host:this.serializeHost(Z),connect:X})}async unlink(Z){if(await this.local.unlink(Z),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),!this.worker)return;await this.request({id:this.allocId(),op:"unlink",label:Z})}async hosts(){return this.local.hosts()}async connect(Z=!0,X=!0){if(!this.worker)return;await this.request({id:this.allocId(),op:"connect",listen:Z,sync:X})}async disconnect(){if(!this.worker)return;await this.request({id:this.allocId(),op:"disconnect"})}async insertRaw(Z){return this.local.insertRaw(Z)}async updateRaw(Z,X,W){return this.local.updateRaw(Z,X,W)}async insert(Z){return this.local.insert(Z)}async update(Z){return this.local.update(Z)}async delete(Z){return this.local.delete(Z)}async genEID(Z){return this.local.genEID(Z)}async sync(){if(!this.worker)return 0;return this.requestStatus({id:this.allocId(),op:"sync"})}async rebuild(Z){return this.scheduledSync.cancel(),await this.scheduledSync.flush(),this.requestStatus({id:this.allocId(),op:"rebuild",checkHost:Z?.checkHost})}async listMsgs(Z){return this.local.listMsgs(Z)}async countMsgs(Z){return this.local.countMsgs(Z)}async reconcile(Z,X){try{let W=await this.request({id:this.allocId(),op:"reconcile",hostLabel:Z,pull:X?.pull,push:X?.push,sync:X?.sync});if(!qK(W))return Y(12);return d(W)}catch(W){if(W instanceof BX&&W.status!==0)return Y(W.status);return Y(12)}}async msgcheck(){let Z=await this.request({id:this.allocId(),op:"msgcheck"});if(!(Z instanceof Uint8Array))throw Error(`${dZ} msgcheck: expected Uint8Array`);return Z}async entcheck(){let Z=await this.request({id:this.allocId(),op:"entcheck"});if(!(Z instanceof Uint8Array))throw Error(`${dZ} entcheck: expected Uint8Array`);return Z}async wipe(Z){if(await this.local.wipe(Z),this.worker)await this.request({id:this.allocId(),op:"wipe",msgs:Z?.msgs,ents:Z?.ents,meta:Z?.meta,seed:Z?.seed});await this.hydrateStateFromStore(this.store),this.clientState.emit(),this.xferState.emit()}async import(Z){let X=new Uint8Array(await Z.arrayBuffer());return this.requestStatus({id:this.allocId(),op:"import",bytes:X},[X.buffer])}async export(Z,X){try{let W=await this.request({id:this.allocId(),op:"export"});if(!(W instanceof Uint8Array))return 12;let V=new Blob([W.slice()]);return VW(V,Z),0}catch(W){if(W instanceof BX)return W.status;return 12}}}class BX extends Error{status;constructor(Z){super(`WorkerReplyError: ${N[Z]}`);this.status=Z;this.name="WorkerReplyError"}}function qK(Z){if(!Z||typeof Z!=="object")return!1;let X=Z;return X.msgcheck instanceof Uint8Array&&X.msgcheck.length===32&&typeof X.numBags==="number"&&typeof X.numDupes==="number"}function fK(Z){return Z}var TX="[DIPLOMATIC]";async function MW(Z){let X=Z.clock??new PZ;if(Z.worker===!0&&nK(Z)!==void 0)throw Error(`${TX} worker path requires IndexedDB on both sides; do not pass store (got a custom store)`);if(Z.worker!==!0){console.info(`${TX} sync on main thread `+"(no worker — app did not request a worker)");let l=await F0(Z.store);return _K(X,Z.state,l)}if(typeof Worker>"u")throw Error(`${TX} worker: true but Worker API is unavailable`);let W=await F0(void 0),V=await EX.open(Z.state,W,{readyTimeoutMs:Z.readyTimeoutMs,clock:X,syncDebounceMs:Z.syncDebounceMs});return console.info(`${TX} worker-mode client open (sync Worker starts on setSeed via Enclave)`),{client:V,mode:"worker",dispose:()=>{console.info(`${TX} terminating sync worker`),V.terminate()}}}function nK(Z){if("store"in Z)return Z.store;return}async function _K(Z,X,W){let V=new RX(Z,X,W,fW,bX);return{client:V,mode:"main",dispose:()=>{V.disconnect()}}}async function F0(Z){if(Z!==void 0)return Z;if(typeof indexedDB>"u")throw Error(`${TX} IndexedDB is unavailable; pass store explicitly (e.g. new MemoryStore(crypto))`);return OV(bX)}function aK(Z){let[X,W]=jV();return HW(()=>{async function V(){let K=await Z.clientState.get();W(K)}let l=Z.clientState.listen(V);return V(),()=>{l()}},[Z]),X}function rK(Z){let[X,W]=jV();return HW(()=>{async function V(){let K=await Z.xferState.get();W(K)}let l=Z.xferState.listen(V);return V(),()=>{l()}},[Z]),X}function sK(Z){HW(()=>{async function X(){try{if(!(await Z.clientState.get()).hasSeed)return;await Z.connect(),await Z.sync()}catch(K){console.error("reconnectAndSync failed",K)}}function W(){X()}function V(){if(typeof document<"u"&&document.visibilityState==="visible")X()}function l(){X()}if(globalThis.addEventListener("online",W),typeof document<"u")document.addEventListener("visibilitychange",V);return globalThis.addEventListener("focus",l),globalThis.addEventListener("pageshow",l),()=>{if(globalThis.removeEventListener("online",W),typeof document<"u")document.removeEventListener("visibilitychange",V);globalThis.removeEventListener("focus",l),globalThis.removeEventListener("pageshow",l)}},[Z])}function tK(Z={}){let X=Z.clock??new PZ,{seed:W,host:V,readyTimeoutMs:l}=Z,K=Z.worker===!0,G="store"in Z?Z.store:void 0,[m,R]=jV({stateMgr:sW});return HW(()=>{let J=!1,C;return(async()=>{let F=await VV();if(J)return;let b=eX(F),T=K?await MW({state:b,clock:X,worker:!0,readyTimeoutMs:l}):await MW({state:b,clock:X,store:G,readyTimeoutMs:l});if(J){T.dispose();return}C=T.dispose;let{client:k,mode:c}=T;if(W)await k.setSeed(W);if(V)await k.link(V);if(J){C();return}R({client:k,entDB:F,stateMgr:b,mode:c,error:void 0})})().catch((F)=>{let b=F instanceof Error?F:Error(String(F));if(console.error("[DIPLOMATIC] useClient init failed",b),!J)R((T)=>({...T,client:void 0,error:b}))}),()=>{J=!0,C?.()}},[X,W,V,K,G,l]),m}import{use as eK,useEffect as d0,useRef as ZG,useState as XG}from"react";function b0(Z,X,W){let[V,l]=XG();return d0(()=>{async function K(){let G=await W();l(G)}return K(),Z.on(X,K),()=>{Z.off(X,K)}},[Z,X,W]),V}function WG(Z,X,W){let V=ZG(W());return d0(()=>{async function l(){V.current=W()}return Z.on(X,l),()=>{Z.off(X,l)}},[Z,X,W]),eK(V.current)}function T0(Z,X){return`${Z}:${X}`}class BV{queue=new Map;async enq(Z){for(let X of Z){let W=T0(X.host,X.seq);this.queue.set(W,X)}}async deq(Z,X){for(let W of X){let V=T0(Z,W);this.queue.delete(V)}}async list(){let Z=[];for(let X of this.queue.values())Z.push(X);return Z}async count(){return this.queue.size}async wipe(){this.queue.clear()}}function VG(Z,X){if(X.setLastSeq!==void 0)Z.lastSeq=X.setLastSeq;else if(X.lastSeq!==void 0&&X.lastSeq>Z.lastSeq)Z.lastSeq=X.lastSeq}class EV{hosts=new Map;async add(Z){let X=this.hosts.get(Z.label),W=X!==void 0&&X.handle===Z.handle&&(X.idx??0)===(Z.idx??0),V={...Z,lastSeq:W?X.lastSeq:0,clockOffset:W?X.clockOffset:void 0,subscription:W?X.subscription:void 0};this.hosts.set(Z.label,V)}async touch(Z,X){await this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.hosts.get(Z);if(!W)return;VG(W,X),this.hosts.set(Z,{...W})}async get(Z){return this.hosts.get(Z)}async set(Z,X){let W=this.hosts.get(Z);if(!W)return 13;return this.hosts.set(Z,{...W,...X}),0}async del(Z){this.hosts.delete(Z)}async list(){return this.hosts.values()}async wipe(){this.hosts.clear()}}class wV{crypto;messages=new Map;constructor(Z){this.crypto=Z}async add(Z){let X=[];for(let{key:W,data:V}of Z)this.messages.set(H(W),V),X.push(0);return X}async del(Z){for(let X of Z)this.messages.delete(H(X))}async get(Z){let X=this.messages.get(H(Z));if(X)return await uZ(Z,X,this.crypto);return}async has(Z){return this.messages.has(H(Z))}async list(Z){let X=Z?.apld,W=Z?.body!==!1,V=[];for(let[l,K]of this.messages){if(X!==void 0&&YX(K.apld)!==X)continue;let G=e(l);V.push(await uZ(G,K,this.crypto,{body:W}))}return V}async count(Z){if(Z===void 0)return this.messages.size;let X=0;for(let W of this.messages.values())if(YX(W.apld)===Z)X++;return X}async listKeys(){let Z=[];for(let X of this.messages.keys())Z.push(e(X));return Z}async last(Z){let X;for(let[W,V]of this.messages){if(n(Z,V.eid)===!1)continue;let l=e(W);if(X===void 0)X={hash:l,data:V};else if((V.ctr??0)>(X.data.ctr??0)||(V.ctr??0)===(X.data.ctr??0)&&(V.off??0)>(X.data.off??0))X={hash:l,data:V}}if(X)return await uZ(X.hash,X.data,this.crypto);return}async markApplied(Z){for(let X of Z){let W=this.messages.get(H(X));if(!W)continue;AZ(W,UZ)}}async markFailed(Z){for(let{key:X,err:W}of Z){let V=this.messages.get(H(X));if(!V)continue;AZ(V,kZ,W)}}async wipe(){this.messages.clear()}}class DV{#Z;#X;#W;constructor(Z){this.#X=Z}async save(Z,X){if(this.#W!==void 0){if(!await zW(this.#X,Z,this.#W))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)")}else this.#W=await yW(this.#X,Z);return this.#Z=Z,this.#Z}async load(){return this.#Z}async wipe(){this.#Z=void 0,this.#W=void 0}peekPin(){return this.#W===void 0?void 0:NW(this.#W)}}class AV{queue=new Map;async enq(Z,X){let W=this.queue.get(Z)||new Set;this.queue.set(Z,W);for(let V of X)W.add(YZ(V))}async deq(Z,X){let W=this.queue.get(Z);if(W)for(let V of X)W.delete(YZ(V))}async list(Z){let X=this.queue.get(Z);if(!X)return[];let W=[];for(let V of X)W.push(IX(V));return W}async count(){let Z=0;for(let X of this.queue.values())Z+=X.size;return Z}async wipe(){this.queue.clear()}}class k0{seed;hosts=new EV;uploads=new AV;downloads=new BV;messages;constructor(Z){this.seed=new DV(Z),this.messages=new wV(Z)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}class c0{singletonType;latest;latestOff=-1;emitter=new MZ;constructor(Z){this.singletonType=Z}async apply(Z){for(let X of Z){let W=new P(X.eid),[V,l]=W.readStruct(a);if(l!==0)continue;let K=new U;K.writeVarString(this.singletonType);let G=K.result();if(V.id.length===G.length&&V.id.every((m,R)=>m===G[R])){if(this.latest===void 0||X.off>this.latestOff)this.latestOff=X.off,this.latest=X.bod,this.emitter.emit(this.singletonType,null)}}return Z.map(()=>0)}clear=async()=>{return this.latest=void 0,this.latestOff=-1,this.emitter.emit(this.singletonType,null),0};notify=(Z)=>{for(let X of Z)if(X===this.singletonType)this.emitter.emit(this.singletonType,null)};refresh=async(Z)=>{this.notify([this.singletonType])};on=(Z,X)=>{this.emitter.addEventListener(Z,X)};off=(Z,X)=>{this.emitter.removeEventListener(Z,X)}}var vV={capable(){return el()},async createCred(Z){return TW(Z)},async write(Z,X,W){return iX(Z,X,W)},async read(Z,X){let[W,V]=await kW(Z,X);if(V!==0||W===void 0)return Y(V);return d(W.blob)}};class L0{#Z;#X;#W;#V;constructor(Z){if(this.#W=Z.rpId,this.#V=Z.rpName,Z.credId!==void 0)this.#X=Z.credId.slice()}get credId(){if(this.#X===void 0)return;return this.#X.slice()}setCredId(Z){this.#X=Z===void 0?void 0:Z.slice()}async save(Z,X){if(X?.persist!==!0)return this.#Z=Z,this.#Z;let[W,V]=await Z.persistToLargeBlob([],{rpId:this.#W,rpName:this.#V,credId:this.#X});if(V!==0||W===void 0)return Promise.reject(Error(`persistToLargeBlob status ${V}`));return this.#X=W,this.#Z=Z,this.#Z}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await t.fromLargeBlob({rpId:this.#W,rpName:this.#V,credId:Z});if(W!==0||X===void 0)return Y(W);return this.#Z=X.enclave,d(X.enclave)}async wipe(){let Z=this.#X;if(Z!==void 0){let X=await t.clearLargeBlob(Z,{rpId:this.#W});if(X!==0)return Promise.reject(Error(`clearLargeBlob status ${X}`))}this.#Z=void 0,this.#X=void 0}}var wX=1,hW={encode(Z,X){let W=Z.writeVarInt(X.v);if(W!==0)return W;let V=Z.writeVarBytes(X.salt);if(V!==0)return V;let l=Z.writeVarBytes(X.credId);if(l!==0)return l;return Z.writeVarBytes(X.body)},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);if(K===void 0)return Y(14);let[m,R]=Z.readVarBytes();if(R!==0)return Y(R);if(m===void 0)return Y(14);return d({v:X,salt:V,credId:K,body:m})}};var SW={PREFIX:"dip1:",VERSION:wX,async seal(Z,X,W){let[V,l]=await Z.sealPairPackageBody(X,W);if(l!==0)return Y(l);if(V===void 0)return Y(12);let K=new U,G=K.writeStruct(hW,{v:wX,salt:V.salt,credId:V.credId,body:V.body});if(G!==0)return Y(G);return d(SW.PREFIX+BW(K.result()))},async open(Z,X){let W=Z.trim();if(!W.startsWith(SW.PREFIX))return Y(10);let V;try{V=EW(W.slice(SW.PREFIX.length))}catch{return Y(10)}let l=new P(V),[K,G]=l.readStruct(hW);if(G!==0)return Y(G);if(K===void 0)return Y(14);if(K.v!==wX)return Y(14);let[m,R]=await t.openPairPackageBody(K.body,{...X,salt:K.salt,credId:K.credId.byteLength>0?K.credId:void 0});if(R!==0)return Y(R);if(m===void 0)return Y(12);return d({enclave:m.enclave,hosts:m.hosts,salt:K.salt.slice(),credId:m.credId,sealedMaster:m.sealedMaster})}};function Ub(){return vV.capable()}export{sK as useSyncOnResume,WG as useStateWatcherSuspense,b0 as useStateWatcher,rK as useClientXferState,aK as useClientState,tK as useClient,WW as shouldEmitItemProgress,AZ as setApld,lV as revFromHead,NX as revFromEntity,UK as prfCapable,OV as openIDBStore,VV as openEntDB,MW as openDiplomaticClient,sW as nullStateManager,YK as nullEntDB,cl as normalizeTags,Ub as largeBlobCapable,mK as isTombstone,GV as isTerminalApplyFailure,CK as isPendingApply,D as isLiveEnt,JK as isApldState,DZ as idleProgress,IX as htob,fW as hostHTTPTransport,q0 as genSingletonEID,eX as entStateManager,Fl as encodeEntRev,a as eidCodec,bW as defaultWebAuthnRpId,mX as defaultPeekProgressEvery,bX as crypto,Cl as cmpBytes,XX as checksumSet,yX as checksumEntRevs,YZ as btoh,BW as btob64url,H as btob64,EW as b64urltob,e as b64tob,QZ as asSealedMasterKey,YX as apldFromStored,EX as WorkerClient,MZ as TypedEventEmitter,RX as SyncClient,N as Status,zX as StateManager,c0 as SingletonStateManager,rW as SEALED_MASTER_KEY_LEN,pW as PrfSeedStore,L0 as PasskeySeedStore,SW as PairPackage,k0 as MemoryStore,bZ as MASTER_SEED_LEN,iV as IDBStore,gW as IDBSeedStore,qW as HTTPTransport,WV as EntIDB,tX as EntDBMemory,U as Encoder,t as Enclave,P as Decoder,OX as DEFAULT_PRF_SALT,PZ as Clock,xX as CachedEntDB,pZ as APLD_PENDING,kZ as APLD_ERROR,UZ as APLD_APPLIED};
|