static/js/terrain/terrain2.js @ 578872d23f06 default tip

Links
author Steve Losh <steve@stevelosh.com>
date Mon, 09 Sep 2024 10:31:31 -0400
parents d20bad4b886f
children (none)
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
{
    var _ns_ = {
        id: 'demo',
        doc: void 0
    };
    var ndarray = require('ndarray');
}
var width = exports.width = 676;
var height = exports.height = 400;
var wireframe = exports.wireframe = true;
var wireframeWidth = exports.wireframeWidth = 1.2;
var terrainHeight = exports.terrainHeight = 50;
var terrainSize = exports.terrainSize = 100;
void 0;
void 0;
void 0;
var inc = exports.inc = function inc(x) {
    return x + 1;
};
var dec = exports.dec = function dec(x) {
    return x - 1;
};
void 0;
void 0;
void 0;
void 0;
void 0;
void 0;
void 0;
void 0;
var midpoint = exports.midpoint = function midpoint(a, b) {
    return (a + b) / 2;
};
var average2 = exports.average2 = function average2(a, b) {
    return (a + b) / 2;
};
var average4 = exports.average4 = function average4(a, b, c, d) {
    return (a + b + c + d) / 4;
};
var safeAverage = exports.safeAverage = function safeAverage(a, b, c, d) {
    return function () {
        var totalø1 = 0;
        var countø1 = 0;
        a ? (function () {
            totalø1 = totalø1 + a;
            return countø1 = inc(countø1);
        })() : void 0;
        b ? (function () {
            totalø1 = totalø1 + b;
            return countø1 = inc(countø1);
        })() : void 0;
        c ? (function () {
            totalø1 = totalø1 + c;
            return countø1 = inc(countø1);
        })() : void 0;
        d ? (function () {
            totalø1 = totalø1 + d;
            return countø1 = inc(countø1);
        })() : void 0;
        return totalø1 / countø1;
    }.call(this);
};
var rand = exports.rand = function rand() {
    return Math.random();
};
var randAroundZero = exports.randAroundZero = function randAroundZero(spread) {
    return spread * rand() * 2 - spread;
};
var jitter = exports.jitter = function jitter(value, spread) {
    return value + randAroundZero(spread);
};
var heightmapResolution = exports.heightmapResolution = function heightmapResolution(heightmap) {
    return heightmap.shape[0];
};
var heightmapLastIndex = exports.heightmapLastIndex = function heightmapLastIndex(heightmap) {
    return dec(heightmapResolution(heightmap));
};
var heightmapCenterIndex = exports.heightmapCenterIndex = function heightmapCenterIndex(heightmap) {
    return midpoint(0, heightmapLastIndex(heightmap));
};
var heightmapGet = exports.heightmapGet = function heightmapGet(heightmap, x, y) {
    return heightmap.get(x, y);
};
var heightmapGetSafe = exports.heightmapGetSafe = function heightmapGetSafe(heightmap, x, y) {
    return function () {
        var lastø1 = heightmapLastIndex(heightmap);
        return 0 <= x && x <= lastø1 && (0 <= y && y <= lastø1) ? (function () {
            return heightmapGet(heightmap, x, y);
        })() : void 0;
    }.call(this);
};
var heightmapSet = exports.heightmapSet = function heightmapSet(heightmap, x, y, val) {
    return heightmap.set(x, y, val);
};
var heightmapSetIfUnset = exports.heightmapSetIfUnset = function heightmapSetIfUnset(heightmap, x, y, val) {
    return 0 == heightmapGet(heightmap, x, y) ? (function () {
        return heightmapSet(heightmap, x, y, val);
    })() : void 0;
};
var normalize = exports.normalize = function normalize(heightmap) {
    return function () {
        var maxø1 = 0 - Infinity;
        var minø1 = Infinity;
        (function () {
            var array2ø1 = heightmap;
            return function () {
                var G__3ø1 = array2ø1.data.length;
                return function loop() {
                    var recur = loop;
                    var index1ø1 = 0;
                    do {
                        recur = index1ø1 < G__3ø1 ? (function () {
                            (function () {
                                var elø1 = array2ø1.data[index1ø1];
                                maxø1 < elø1 ? (function () {
                                    return maxø1 = elø1;
                                })() : void 0;
                                return minø1 > elø1 ? (function () {
                                    return minø1 = elø1;
                                })() : void 0;
                            }.call(this));
                            return loop[0] = inc(index1ø1), loop;
                        })() : void 0;
                    } while (index1ø1 = loop[0], recur === loop);
                    return recur;
                }.call(this);
            }.call(this);
        }.call(this));
        return function () {
            var spanø1 = maxø1 - minø1;
            return function () {
                var array4ø1 = heightmap;
                return function () {
                    var G__5ø1 = array4ø1.shape[0];
                    return function loop() {
                        var recur = loop;
                        var xø1 = 0;
                        do {
                            recur = xø1 < G__5ø1 ? (function () {
                                (function () {
                                    var G__6ø1 = array4ø1.shape[1];
                                    return function loop() {
                                        var recur = loop;
                                        var yø1 = 0;
                                        do {
                                            recur = yø1 < G__6ø1 ? (function () {
                                                (function () {
                                                    return heightmapSet(heightmap, xø1, yø1, (heightmapGet(heightmap, xø1, yø1) - minø1) / spanø1);
                                                })();
                                                return loop[0] = inc(yø1), loop;
                                            })() : void 0;
                                        } while (yø1 = loop[0], recur === loop);
                                        return recur;
                                    }.call(this);
                                }.call(this));
                                return loop[0] = inc(xø1), loop;
                            })() : void 0;
                        } while (xø1 = loop[0], recur === loop);
                        return recur;
                    }.call(this);
                }.call(this);
            }.call(this);
        }.call(this);
    }.call(this);
};
var makeHeightmap = exports.makeHeightmap = function makeHeightmap(exponent) {
    return function () {
        var resolutionø1 = Math.pow(2, exponent) + 1;
        return function () {
            var heightmapø1 = ndarray(new Float64Array(resolutionø1 * resolutionø1), [
                resolutionø1,
                resolutionø1
            ]);
            heightmapø1.exponent = exponent;
            heightmapø1.resolution = resolutionø1;
            heightmapø1.last = dec(resolutionø1);
            return heightmapø1;
        }.call(this);
    }.call(this);
};
var topLeftCorner = exports.topLeftCorner = function topLeftCorner(heightmap) {
    return function () {
        var centerø1 = heightmapCenterIndex(heightmap);
        return heightmap.lo(0, 0).hi(inc(centerø1), inc(centerø1));
    }.call(this);
};
var topRightCorner = exports.topRightCorner = function topRightCorner(heightmap) {
    return function () {
        var centerø1 = heightmapCenterIndex(heightmap);
        return heightmap.lo(centerø1, 0).hi(inc(centerø1), inc(centerø1));
    }.call(this);
};
var bottomLeftCorner = exports.bottomLeftCorner = function bottomLeftCorner(heightmap) {
    return function () {
        var centerø1 = heightmapCenterIndex(heightmap);
        return heightmap.lo(0, centerø1).hi(inc(centerø1), inc(centerø1));
    }.call(this);
};
var bottomRightCorner = exports.bottomRightCorner = function bottomRightCorner(heightmap) {
    return function () {
        var centerø1 = heightmapCenterIndex(heightmap);
        return heightmap.lo(centerø1, centerø1).hi(inc(centerø1), inc(centerø1));
    }.call(this);
};
var mpdInitCorners = exports.mpdInitCorners = function mpdInitCorners(heightmap) {
    return function () {
        var lastø1 = heightmapLastIndex(heightmap);
        heightmapSet(heightmap, 0, 0, rand());
        heightmapSet(heightmap, 0, lastø1, rand());
        heightmapSet(heightmap, lastø1, 0, rand());
        return heightmapSet(heightmap, lastø1, lastø1, rand());
    }.call(this);
};
var mpdDisplace = exports.mpdDisplace = function mpdDisplace(heightmap, spread, spreadReduction) {
    return function () {
        var lastø1 = heightmapLastIndex(heightmap);
        var cø1 = midpoint(0, lastø1);
        var bottomLeftø1 = heightmapGet(heightmap, 0, 0);
        var bottomRightø1 = heightmapGet(heightmap, lastø1, 0);
        var topLeftø1 = heightmapGet(heightmap, 0, lastø1);
        var topRightø1 = heightmapGet(heightmap, lastø1, lastø1);
        var topø1 = average2(topLeftø1, topRightø1);
        var leftø1 = average2(bottomLeftø1, topLeftø1);
        var bottomø1 = average2(bottomLeftø1, bottomRightø1);
        var rightø1 = average2(bottomRightø1, topRightø1);
        var centerø1 = average4(topø1, leftø1, bottomø1, rightø1);
        var nextSpreadø1 = spread * spreadReduction;
        heightmapSetIfUnset(heightmap, cø1, 0, jitter(bottomø1, spread));
        heightmapSetIfUnset(heightmap, cø1, lastø1, jitter(topø1, spread));
        heightmapSetIfUnset(heightmap, 0, cø1, jitter(leftø1, spread));
        heightmapSetIfUnset(heightmap, lastø1, cø1, jitter(rightø1, spread));
        heightmapSetIfUnset(heightmap, cø1, cø1, jitter(centerø1, spread));
        return !(3 == heightmapResolution(heightmap)) ? (function () {
            heightmapSetIfUnset(heightmap, cø1, 0, jitter(bottomø1, spread));
            heightmapSetIfUnset(heightmap, cø1, lastø1, jitter(topø1, spread));
            heightmapSetIfUnset(heightmap, 0, cø1, jitter(leftø1, spread));
            heightmapSetIfUnset(heightmap, lastø1, cø1, jitter(rightø1, spread));
            heightmapSetIfUnset(heightmap, cø1, cø1, jitter(centerø1, spread));
            mpdDisplace(topLeftCorner(heightmap), nextSpreadø1, spreadReduction);
            mpdDisplace(topRightCorner(heightmap), nextSpreadø1, spreadReduction);
            mpdDisplace(bottomLeftCorner(heightmap), nextSpreadø1, spreadReduction);
            return mpdDisplace(bottomRightCorner(heightmap), nextSpreadø1, spreadReduction);
        })() : void 0;
    }.call(this);
};
var midpointDisplacement = exports.midpointDisplacement = function midpointDisplacement(heightmap) {
    return function () {
        var initialSpreadø1 = 0.3;
        var spreadReductionø1 = 0.55;
        mpdInitCorners(heightmap);
        mpdDisplace(heightmap, initialSpreadø1, spreadReductionø1);
        return normalize(heightmap);
    }.call(this);
};
var makeDirectionalLight = exports.makeDirectionalLight = function makeDirectionalLight() {
    return function () {
        var lightø1 = new THREE.DirectionalLight(16777215, 1);
        lightø1.position.set(100, 0, 150);
        return lightø1;
    }.call(this);
};
var makeCamera = exports.makeCamera = function makeCamera() {
    return function () {
        var cameraø1 = new THREE.PerspectiveCamera(55, width / height, 0.1, 1000);
        cameraø1.position.set(0, -100, 150);
        return cameraø1;
    }.call(this);
};
var makeRenderer = exports.makeRenderer = function makeRenderer() {
    return function () {
        var rendererø1 = new THREE.WebGLRenderer({ 'antialias': false });
        rendererø1.setClearColor(16777215);
        rendererø1.setSize(width, height);
        rendererø1.setPixelRatio(2);
        return rendererø1;
    }.call(this);
};
var makeGeometry = exports.makeGeometry = function makeGeometry(heightmap) {
    return function () {
        var resolutionø1 = heightmap.shape[0];
        var geometryø1 = new THREE.PlaneGeometry(terrainSize, terrainSize, resolutionø1 - 1, resolutionø1 - 1);
        return geometryø1;
    }.call(this);
};
var makeControls = exports.makeControls = function makeControls(camera, renderer) {
    return function () {
        var controlsø1 = new THREE.TrackballControls(camera, renderer.domElement);
        controlsø1.rotateSpeed = 1.4;
        controlsø1.zoomSpeed = 0.5;
        controlsø1.staticMoving = true;
        controlsø1.dynamicDampingFactor = 0.3;
        return controlsø1;
    }.call(this);
};
var makePlane = exports.makePlane = function makePlane(geometry) {
    return function () {
        var materialø1 = new THREE.MeshLambertMaterial({
            'wireframe': wireframe,
            'wireframeLinewidth': wireframeWidth,
            'color': 47872
        });
        return new THREE.Mesh(geometry, materialø1);
    }.call(this);
};
var attachToDom = exports.attachToDom = function attachToDom(renderer, elName, refreshFn) {
    return function () {
        var containerø1 = document.getElementById(elName);
        var settingsø1 = document.createElement('div');
        var refreshButtonø1 = document.createElement('button');
        var buttonTextø1 = document.createTextNode('Refresh');
        var cancelScrollø1 = function (e) {
            return e.preventDefault();
        };
        refreshButtonø1.onclick = refreshFn;
        renderer.domElement.onmousewheel = cancelScrollø1;
        renderer.domElement.addEventListener('MozMousePixelScroll', cancelScrollø1, false);
        refreshButtonø1.appendChild(buttonTextø1);
        containerø1.appendChild(renderer.domElement);
        containerø1.appendChild(settingsø1);
        return settingsø1.appendChild(refreshButtonø1);
    }.call(this);
};
var updateGeometry = exports.updateGeometry = function updateGeometry(geometry, heightmap) {
    (function loop() {
        var recur = loop;
        var iø1 = 0;
        do {
            recur = iø1 < geometry.vertices.length ? (function () {
                geometry.vertices[iø1].z = terrainHeight * heightmap.data[iø1];
                return loop[0] = iø1 + 1, loop;
            })() : void 0;
        } while (iø1 = loop[0], recur === loop);
        return recur;
    }.call(this));
    geometry.computeVertexNormals();
    return geometry;
};
var makeFinal = exports.makeFinal = function makeFinal(elementId) {
    var scene = new THREE.Scene();
    scene.add(new THREE.AxisHelper(100));
    var clock = new THREE.Clock();
    var camera = makeCamera();
    var renderer = makeRenderer();
    var geometry = void 0;
    var plane = void 0;
    scene.add(makeDirectionalLight());
    scene.add(new THREE.AmbientLight(16777215, 0.05));
    var refresh = function refresh() {
        return function () {
            var heightmapø1 = makeHeightmap(6);
            console.log('Generating terrain...');
            (function () {
                var G__7ø1 = new Date().getTime();
                var G__9ø1 = (function () {
                    return midpointDisplacement(heightmapø1);
                })();
                var G__8ø1 = new Date().getTime();
                console.log('Elapsed time: ' + (G__8ø1 - G__7ø1) + 'ms.');
                return G__9ø1;
            }.call(this));
            console.log('Rebuilding geometry...');
            (function () {
                var G__10ø1 = new Date().getTime();
                var G__12ø1 = (function () {
                    geometry = makeGeometry(heightmapø1);
                    return updateGeometry(geometry, heightmapø1);
                })();
                var G__11ø1 = new Date().getTime();
                console.log('Elapsed time: ' + (G__11ø1 - G__10ø1) + 'ms.');
                return G__12ø1;
            }.call(this));
            console.log('Rebuilding plane...');
            return function () {
                var G__13ø1 = new Date().getTime();
                var G__15ø1 = (function () {
                    scene.remove(plane);
                    plane = makePlane(geometry);
                    return scene.add(plane);
                })();
                var G__14ø1 = new Date().getTime();
                console.log('Elapsed time: ' + (G__14ø1 - G__13ø1) + 'ms.');
                return G__15ø1;
            }.call(this);
        }.call(this);
    };
    attachToDom(renderer, elementId, refresh);
    var controls = makeControls(camera, renderer);
    var render = function render() {
        return function () {
            var deltaø1 = clock.getDelta();
            requestAnimationFrame(render);
            controls.update(deltaø1);
            return renderer.render(scene, camera);
        }.call(this);
    };
    refresh();
    render();
    return void 0;
};
var run = exports.run = function run() {
    return makeFinal('demo-final');
};
$(run);


},{"ndarray":4}],2:[function(require,module,exports){
"use strict"

function iota(n) {
  var result = new Array(n)
  for(var i=0; i<n; ++i) {
    result[i] = i
  }
  return result
}

module.exports = iota
},{}],3:[function(require,module,exports){
/**
 * Determine if an object is Buffer
 *
 * Author:   Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
 * License:  MIT
 *
 * `npm install is-buffer`
 */

module.exports = function (obj) {
  return !!(obj != null &&
    (obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
      (obj.constructor &&
      typeof obj.constructor.isBuffer === 'function' &&
      obj.constructor.isBuffer(obj))
    ))
}

},{}],4:[function(require,module,exports){
var iota = require("iota-array")
var isBuffer = require("is-buffer")

var hasTypedArrays  = ((typeof Float64Array) !== "undefined")

function compare1st(a, b) {
  return a[0] - b[0]
}

function order() {
  var stride = this.stride
  var terms = new Array(stride.length)
  var i
  for(i=0; i<terms.length; ++i) {
    terms[i] = [Math.abs(stride[i]), i]
  }
  terms.sort(compare1st)
  var result = new Array(terms.length)
  for(i=0; i<result.length; ++i) {
    result[i] = terms[i][1]
  }
  return result
}

function compileConstructor(dtype, dimension) {
  var className = ["View", dimension, "d", dtype].join("")
  if(dimension < 0) {
    className = "View_Nil" + dtype
  }
  var useGetters = (dtype === "generic")

  if(dimension === -1) {
    //Special case for trivial arrays
    var code =
      "function "+className+"(a){this.data=a;};\
var proto="+className+".prototype;\
proto.dtype='"+dtype+"';\
proto.index=function(){return -1};\
proto.size=0;\
proto.dimension=-1;\
proto.shape=proto.stride=proto.order=[];\
proto.lo=proto.hi=proto.transpose=proto.step=\
function(){return new "+className+"(this.data);};\
proto.get=proto.set=function(){};\
proto.pick=function(){return null};\
return function construct_"+className+"(a){return new "+className+"(a);}"
    var procedure = new Function(code)
    return procedure()
  } else if(dimension === 0) {
    //Special case for 0d arrays
    var code =
      "function "+className+"(a,d) {\
this.data = a;\
this.offset = d\
};\
var proto="+className+".prototype;\
proto.dtype='"+dtype+"';\
proto.index=function(){return this.offset};\
proto.dimension=0;\
proto.size=1;\
proto.shape=\
proto.stride=\
proto.order=[];\
proto.lo=\
proto.hi=\
proto.transpose=\
proto.step=function "+className+"_copy() {\
return new "+className+"(this.data,this.offset)\
};\
proto.pick=function "+className+"_pick(){\
return TrivialArray(this.data);\
};\
proto.valueOf=proto.get=function "+className+"_get(){\
return "+(useGetters ? "this.data.get(this.offset)" : "this.data[this.offset]")+
"};\
proto.set=function "+className+"_set(v){\
return "+(useGetters ? "this.data.set(this.offset,v)" : "this.data[this.offset]=v")+"\
};\
return function construct_"+className+"(a,b,c,d){return new "+className+"(a,d)}"
    var procedure = new Function("TrivialArray", code)
    return procedure(CACHED_CONSTRUCTORS[dtype][0])
  }

  var code = ["'use strict'"]

  //Create constructor for view
  var indices = iota(dimension)
  var args = indices.map(function(i) { return "i"+i })
  var index_str = "this.offset+" + indices.map(function(i) {
        return "this.stride[" + i + "]*i" + i
      }).join("+")
  var shapeArg = indices.map(function(i) {
      return "b"+i
    }).join(",")
  var strideArg = indices.map(function(i) {
      return "c"+i
    }).join(",")
  code.push(
    "function "+className+"(a," + shapeArg + "," + strideArg + ",d){this.data=a",
      "this.shape=[" + shapeArg + "]",
      "this.stride=[" + strideArg + "]",
      "this.offset=d|0}",
    "var proto="+className+".prototype",
    "proto.dtype='"+dtype+"'",
    "proto.dimension="+dimension)

  //view.size:
  code.push("Object.defineProperty(proto,'size',{get:function "+className+"_size(){\
return "+indices.map(function(i) { return "this.shape["+i+"]" }).join("*"),
"}})")

  //view.order:
  if(dimension === 1) {
    code.push("proto.order=[0]")
  } else {
    code.push("Object.defineProperty(proto,'order',{get:")
    if(dimension < 4) {
      code.push("function "+className+"_order(){")
      if(dimension === 2) {
        code.push("return (Math.abs(this.stride[0])>Math.abs(this.stride[1]))?[1,0]:[0,1]}})")
      } else if(dimension === 3) {
        code.push(
"var s0=Math.abs(this.stride[0]),s1=Math.abs(this.stride[1]),s2=Math.abs(this.stride[2]);\
if(s0>s1){\
if(s1>s2){\
return [2,1,0];\
}else if(s0>s2){\
return [1,2,0];\
}else{\
return [1,0,2];\
}\
}else if(s0>s2){\
return [2,0,1];\
}else if(s2>s1){\
return [0,1,2];\
}else{\
return [0,2,1];\
}}})")
      }
    } else {
      code.push("ORDER})")
    }
  }

  //view.set(i0, ..., v):
  code.push(
"proto.set=function "+className+"_set("+args.join(",")+",v){")
  if(useGetters) {
    code.push("return this.data.set("+index_str+",v)}")
  } else {
    code.push("return this.data["+index_str+"]=v}")
  }

  //view.get(i0, ...):
  code.push("proto.get=function "+className+"_get("+args.join(",")+"){")
  if(useGetters) {
    code.push("return this.data.get("+index_str+")}")
  } else {
    code.push("return this.data["+index_str+"]}")
  }

  //view.index:
  code.push(
    "proto.index=function "+className+"_index(", args.join(), "){return "+index_str+"}")

  //view.hi():
  code.push("proto.hi=function "+className+"_hi("+args.join(",")+"){return new "+className+"(this.data,"+
    indices.map(function(i) {
      return ["(typeof i",i,"!=='number'||i",i,"<0)?this.shape[", i, "]:i", i,"|0"].join("")
    }).join(",")+","+
    indices.map(function(i) {
      return "this.stride["+i + "]"
    }).join(",")+",this.offset)}")

  //view.lo():
  var a_vars = indices.map(function(i) { return "a"+i+"=this.shape["+i+"]" })
  var c_vars = indices.map(function(i) { return "c"+i+"=this.stride["+i+"]" })
  code.push("proto.lo=function "+className+"_lo("+args.join(",")+"){var b=this.offset,d=0,"+a_vars.join(",")+","+c_vars.join(","))
  for(var i=0; i<dimension; ++i) {
    code.push(
"if(typeof i"+i+"==='number'&&i"+i+">=0){\
d=i"+i+"|0;\
b+=c"+i+"*d;\
a"+i+"-=d}")
  }
  code.push("return new "+className+"(this.data,"+
    indices.map(function(i) {
      return "a"+i
    }).join(",")+","+
    indices.map(function(i) {
      return "c"+i
    }).join(",")+",b)}")

  //view.step():
  code.push("proto.step=function "+className+"_step("+args.join(",")+"){var "+
    indices.map(function(i) {
      return "a"+i+"=this.shape["+i+"]"
    }).join(",")+","+
    indices.map(function(i) {
      return "b"+i+"=this.stride["+i+"]"
    }).join(",")+",c=this.offset,d=0,ceil=Math.ceil")
  for(var i=0; i<dimension; ++i) {
    code.push(
"if(typeof i"+i+"==='number'){\
d=i"+i+"|0;\
if(d<0){\
c+=b"+i+"*(a"+i+"-1);\
a"+i+"=ceil(-a"+i+"/d)\
}else{\
a"+i+"=ceil(a"+i+"/d)\
}\
b"+i+"*=d\
}")
  }
  code.push("return new "+className+"(this.data,"+
    indices.map(function(i) {
      return "a" + i
    }).join(",")+","+
    indices.map(function(i) {
      return "b" + i
    }).join(",")+",c)}")

  //view.transpose():
  var tShape = new Array(dimension)
  var tStride = new Array(dimension)
  for(var i=0; i<dimension; ++i) {
    tShape[i] = "a[i"+i+"]"
    tStride[i] = "b[i"+i+"]"
  }
  code.push("proto.transpose=function "+className+"_transpose("+args+"){"+
    args.map(function(n,idx) { return n + "=(" + n + "===undefined?" + idx + ":" + n + "|0)"}).join(";"),
    "var a=this.shape,b=this.stride;return new "+className+"(this.data,"+tShape.join(",")+","+tStride.join(",")+",this.offset)}")

  //view.pick():
  code.push("proto.pick=function "+className+"_pick("+args+"){var a=[],b=[],c=this.offset")
  for(var i=0; i<dimension; ++i) {
    code.push("if(typeof i"+i+"==='number'&&i"+i+">=0){c=(c+this.stride["+i+"]*i"+i+")|0}else{a.push(this.shape["+i+"]);b.push(this.stride["+i+"])}")
  }
  code.push("var ctor=CTOR_LIST[a.length+1];return ctor(this.data,a,b,c)}")

  //Add return statement
  code.push("return function construct_"+className+"(data,shape,stride,offset){return new "+className+"(data,"+
    indices.map(function(i) {
      return "shape["+i+"]"
    }).join(",")+","+
    indices.map(function(i) {
      return "stride["+i+"]"
    }).join(",")+",offset)}")

  //Compile procedure
  var procedure = new Function("CTOR_LIST", "ORDER", code.join("\n"))
  return procedure(CACHED_CONSTRUCTORS[dtype], order)
}

function arrayDType(data) {
  if(isBuffer(data)) {
    return "buffer"
  }
  if(hasTypedArrays) {
    switch(Object.prototype.toString.call(data)) {
      case "[object Float64Array]":
        return "float64"
      case "[object Float32Array]":
        return "float32"
      case "[object Int8Array]":
        return "int8"
      case "[object Int16Array]":
        return "int16"
      case "[object Int32Array]":
        return "int32"
      case "[object Uint8Array]":
        return "uint8"
      case "[object Uint16Array]":
        return "uint16"
      case "[object Uint32Array]":
        return "uint32"
      case "[object Uint8ClampedArray]":
        return "uint8_clamped"
    }
  }
  if(Array.isArray(data)) {
    return "array"
  }
  return "generic"
}

var CACHED_CONSTRUCTORS = {
  "float32":[],
  "float64":[],
  "int8":[],
  "int16":[],
  "int32":[],
  "uint8":[],
  "uint16":[],
  "uint32":[],
  "array":[],
  "uint8_clamped":[],
  "buffer":[],
  "generic":[]
}

;(function() {
  for(var id in CACHED_CONSTRUCTORS) {
    CACHED_CONSTRUCTORS[id].push(compileConstructor(id, -1))
  }
});

function wrappedNDArrayCtor(data, shape, stride, offset) {
  if(data === undefined) {
    var ctor = CACHED_CONSTRUCTORS.array[0]
    return ctor([])
  } else if(typeof data === "number") {
    data = [data]
  }
  if(shape === undefined) {
    shape = [ data.length ]
  }
  var d = shape.length
  if(stride === undefined) {
    stride = new Array(d)
    for(var i=d-1, sz=1; i>=0; --i) {
      stride[i] = sz
      sz *= shape[i]
    }
  }
  if(offset === undefined) {
    offset = 0
    for(var i=0; i<d; ++i) {
      if(stride[i] < 0) {
        offset -= (shape[i]-1)*stride[i]
      }
    }
  }
  var dtype = arrayDType(data)
  var ctor_list = CACHED_CONSTRUCTORS[dtype]
  while(ctor_list.length <= d+1) {
    ctor_list.push(compileConstructor(dtype, ctor_list.length-1))
  }
  var ctor = ctor_list[d+1]
  return ctor(data, shape, stride, offset)
}

module.exports = wrappedNDArrayCtor

},{"iota-array":2,"is-buffer":3}]},{},[1])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Vzci9sb2NhbC9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIm1lZGlhL2pzL3dpc3AvYW5vbnltb3VzLndpc3AiLCJub2RlX21vZHVsZXMvaW90YS1hcnJheS9pb3RhLmpzIiwibm9kZV9tb2R1bGVzL2lzLWJ1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9uZGFycmF5L25kYXJyYXkuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0lDQUEsSUFBQyxJLEdBQUQ7QUFBQSxRQUFBLEUsRUFBSSxNQUFKO0FBQUEsUUFBQSxHLEVBQUEsSyxDQUFBO0FBQUEsTTs7O0FBSUEsSUFBSyxLQUFBLEdBQUEsT0FBQSxDQUFBLEtBQUEsR0FBTSxHQUFYLEM7QUFDQSxJQUFLLE1BQUEsR0FBQSxPQUFBLENBQUEsTUFBQSxHQUFPLEdBQVosQztBQUNBLElBQUssU0FBQSxHQUFBLE9BQUEsQ0FBQSxTQUFBLEcsSUFBTCxDO0FBQ0EsSUFBSyxjQUFBLEdBQUEsT0FBQSxDQUFBLGNBQUEsR0FBZ0IsR0FBckIsQztBQUNBLElBQUssYUFBQSxHQUFBLE9BQUEsQ0FBQSxhQUFBLEdBQWUsRUFBcEIsQztBQUNBLElBQUssV0FBQSxHQUFBLE9BQUEsQ0FBQSxXQUFBLEdBQWEsR0FBbEIsQzs7OztBQW9CQSxJQUFNLEdBQUEsR0FBQSxPQUFBLENBQUEsR0FBQSxHQUFOLFNBQU0sR0FBTixDQUFXLENBQVgsRUFDRTtBQUFBLFdBQUcsQ0FBSCxHQUFLLENBQUw7QUFBQSxDQURGLEM7QUFHQSxJQUFNLEdBQUEsR0FBQSxPQUFBLENBQUEsR0FBQSxHQUFOLFNBQU0sR0FBTixDQUFXLENBQVgsRUFDRTtBQUFBLFdBQUcsQ0FBSCxHQUFLLENBQUw7QUFBQSxDQURGLEM7Ozs7Ozs7OztBQXdFQSxJQUFNLFFBQUEsR0FBQSxPQUFBLENBQUEsUUFBQSxHQUFOLFNBQU0sUUFBTixD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QUFELENBQVksWUFBWjtBQUFBLENBREYsQztBQUdDLENBQUQsQ0FBRyxHQUFIOzs7O0FDcFhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIihucyBkZW1vXG4gICg6cmVxdWlyZSBbbmRhcnJheV0pKVxuXG47IENvbnN0YW50cyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmIHdpZHRoIDYxMClcbihkZWYgaGVpZ2h0IDQwMClcbihkZWYgd2lyZWZyYW1lIHRydWUpXG4oZGVmIHdpcmVmcmFtZS13aWR0aCAxLjIpXG4oZGVmIHRlcnJhaW4taGVpZ2h0IDUwKVxuKGRlZiB0ZXJyYWluLXNpemUgMTAwKVxuXG47IEdlbmVyYWwgVXRpbGl0aWVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbWFjcm8gd2hlbiBbY29uZGl0aW9uICYgYm9keV1cbiAgYChpZiB+Y29uZGl0aW9uXG4gICAgIChkbyB+QGJvZHkpKSlcblxuKGRlZm1hY3JvIHdoZW4tbm90IFtjb25kaXRpb24gJiBib2R5XVxuICBgKHdoZW4gKG5vdCB+Y29uZGl0aW9uKVxuICAgICB+QGJvZHkpKVxuXG4oZGVmbWFjcm8gLT4gWyYgb3BlcmF0aW9uc11cbiAgKHJlZHVjZVxuICAgIChmbiBbZm9ybSBvcGVyYXRpb25dXG4gICAgICAoY29ucyAoZmlyc3Qgb3BlcmF0aW9uKVxuICAgICAgICAgICAgKGNvbnMgZm9ybSAocmVzdCBvcGVyYXRpb24pKSkpXG4gICAgKGZpcnN0IG9wZXJhdGlvbnMpXG4gICAgKHJlc3Qgb3BlcmF0aW9ucykpKVxuXG5cbihkZWZuIGluYyBbeF1cbiAgKCsgeCAxKSlcblxuKGRlZm4gZGVjIFt4XVxuICAoLSB4IDEpKVxuXG5cbihkZWZtYWNybyBkby10aW1lcyBbdmFybmFtZSBsaW1pdCAmIGJvZHldXG4gIChsZXQgW2VuZCAoZ2Vuc3ltKV1cbiAgICBgKGxldCBbfmVuZCB+bGltaXRdXG4gICAgICAgKGxvb3AgW352YXJuYW1lIDBdXG4gICAgICAgICAod2hlbiAoPCB+dmFybmFtZSB+ZW5kKVxuICAgICAgICAgICB+QGJvZHlcbiAgICAgICAgICAgKHJlY3VyIChpbmMgfnZhcm5hbWUpKSkpKSkpXG5cbihkZWZtYWNybyBkby1zdHJpZGUgW3Zhcm5hbWVzIHN0YXJ0LWZvcm0gZW5kLWZvcm0gc3RyaWRlLWZvcm0gJiBib2R5XVxuICAobGV0IFtzdHJpZGUgKGdlbnN5bSBcInN0cmlkZVwiKVxuICAgICAgICBzdGFydCAoZ2Vuc3ltIFwic3RhcnRcIilcbiAgICAgICAgZW5kIChnZW5zeW0gXCJlbmRcIilcbiAgICAgICAgYnVpbGQgKGZuIGJ1aWxkIFt2YXJzXVxuICAgICAgICAgICAgICAgIChpZiAoZW1wdHk/IHZhcnMpXG4gICAgICAgICAgICAgICAgICBgKGRvIH5AYm9keSlcbiAgICAgICAgICAgICAgICAgIChsZXQgW3Zhcm5hbWUgKGZpcnN0IHZhcnMpXVxuICAgICAgICAgICAgICAgICAgICBgKGxvb3AgW352YXJuYW1lIH5zdGFydF1cbiAgICAgICAgICAgICAgICAgICAgICAgKHdoZW4gKDwgfnZhcm5hbWUgfmVuZClcbiAgICAgICAgICAgICAgICAgICAgICAgICB+KGJ1aWxkIChyZXN0IHZhcnMpKVxuICAgICAgICAgICAgICAgICAgICAgICAgIChyZWN1ciAoKyB+dmFybmFtZSB+c3RyaWRlKSkpKSkpKV1cbiAgICA7IEZpeCB0aGUgbnVtYmVycyBvbmNlIG91dHNpZGUgdGhlIG5lc3RlZCBsb29wcyxcbiAgICA7IGFuZCB0aGVuIGJ1aWxkIHRoZSBndXRzLlxuICAgIGAobGV0IFt+c3RhcnQgfnN0YXJ0LWZvcm1cbiAgICAgICAgICAgfmVuZCB+ZW5kLWZvcm1cbiAgICAgICAgICAgfnN0cmlkZSB+c3RyaWRlLWZvcm1dXG4gICAgICAgfihidWlsZCB2YXJuYW1lcykpKSlcblxuXG4oZGVmbWFjcm8gZG8tbmRhcnJheSBbdmFycyBhcnJheS1mb3JtICYgYm9keV1cbiAgKGxldCBbYXJyYXktdmFyIChnZW5zeW0gXCJhcnJheVwiKVxuICAgICAgICBidWlsZCAoZm4gYnVpbGQgW3ZhcnMgbl1cbiAgICAgICAgICAgICAgICAoaWYgKGVtcHR5PyB2YXJzKVxuICAgICAgICAgICAgICAgICAgYChkbyB+QGJvZHkpXG4gICAgICAgICAgICAgICAgICBgKGRvLXRpbWVzIH4oZmlyc3QgdmFycykgKGFnZXQgKC4tc2hhcGUgfmFycmF5LXZhcikgfm4pXG4gICAgICAgICAgICAgICAgICAgICB+KGJ1aWxkIChyZXN0IHZhcnMpIChpbmMgbikpKSkpXVxuICAgIGAobGV0IFt+YXJyYXktdmFyIH5hcnJheS1mb3JtXVxuICAgICAgIH4oYnVpbGQgdmFycyAwKSkpKVxuXG4oZGVmbWFjcm8gZG8tbmRhcnJheS1lbCBbZWxlbWVudCBhcnJheS1mb3JtICYgYm9keV1cbiAgKGxldCBbaW5kZXggKGdlbnN5bSBcImluZGV4XCIpXG4gICAgICAgIGFycmF5IChnZW5zeW0gXCJhcnJheVwiKV1cbiAgICBgKGxldCBbfmFycmF5IH5hcnJheS1mb3JtXVxuICAgICAgIChkby10aW1lcyB+aW5kZXggKC4tbGVuZ3RoICguLWRhdGEgfmFycmF5KSlcbiAgICAgICAgIChsZXQgW35lbGVtZW50IChhZ2V0ICguLWRhdGEgfmFycmF5KSB+aW5kZXgpXVxuICAgICAgICAgICB+QGJvZHkpKSkpKVxuXG5cbihkZWZtYWNybyBpbmMhIFtwbGFjZV1cbiAgYChzZXQhIH5wbGFjZSAoaW5jIH5wbGFjZSkpKVxuXG4oZGVmbWFjcm8gYWRkISBbcGxhY2UgYW1vdW50XVxuICBgKHNldCEgfnBsYWNlICgrIH5wbGFjZSB+YW1vdW50KSkpXG5cblxuKGRlZm1hY3JvIGwgWyYgZm9ybXNdXG4gIGAoY29uc29sZS5sb2cgfkBmb3JtcykpXG5cbihkZWZtYWNybyB0aW1lIFsmIGJvZHldXG4gIChsZXQgW3N0YXJ0IChnZW5zeW0pXG4gICAgICAgIGVuZCAoZ2Vuc3ltKVxuICAgICAgICByZXN1bHQgKGdlbnN5bSldXG4gICAgYChsZXQgW35zdGFydCAoLmdldFRpbWUgKG5ldyBEYXRlKSlcbiAgICAgICAgICAgfnJlc3VsdCAoZG8gfkBib2R5KVxuICAgICAgICAgICB+ZW5kICguZ2V0VGltZSAobmV3IERhdGUpKV1cbiAgICAgICAobCAoKyBcIkVsYXBzZWQgdGltZTogXCIgKC0gfmVuZCB+c3RhcnQpIFwibXMuXCIpKVxuICAgICAgIH5yZXN1bHQpKSlcblxuXG4oZGVmbiBtaWRwb2ludCBbYSBiXVxuICAoLyAoKyBhIGIpIDIpKVxuXG4oZGVmbiBhdmVyYWdlMiBbYSBiXVxuICAoLyAoKyBhIGIpIDIpKVxuXG4oZGVmbiBhdmVyYWdlNCBbYSBiIGMgZF1cbiAgKC8gKCsgYSBiIGMgZCkgNCkpXG5cbihkZWZuIHNhZmUtYXZlcmFnZSBbYSBiIGMgZF1cbiAgKGxldCBbdG90YWwgMCBjb3VudCAwXVxuICAgICh3aGVuIGEgKGFkZCEgdG90YWwgYSkgKGluYyEgY291bnQpKVxuICAgICh3aGVuIGIgKGFkZCEgdG90YWwgYikgKGluYyEgY291bnQpKVxuICAgICh3aGVuIGMgKGFkZCEgdG90YWwgYykgKGluYyEgY291bnQpKVxuICAgICh3aGVuIGQgKGFkZCEgdG90YWwgZCkgKGluYyEgY291bnQpKVxuICAgICgvIHRvdGFsIGNvdW50KSkpXG5cblxuOyBSYW5kb21uZXNzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZm4gcmFuZCBbXVxuICAoTWF0aC5yYW5kb20pKVxuXG4oZGVmbiByYW5kLWFyb3VuZC16ZXJvIFtzcHJlYWRdXG4gICgtICgqIHNwcmVhZCAocmFuZCkgMikgc3ByZWFkKSlcblxuKGRlZm4gaml0dGVyIFt2YWx1ZSBzcHJlYWRdXG4gICgrIHZhbHVlIChyYW5kLWFyb3VuZC16ZXJvIHNwcmVhZCkpKVxuXG5cbjsgSGVpZ2h0bWFwIEhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIGhlaWdodG1hcC1yZXNvbHV0aW9uIFtoZWlnaHRtYXBdXG4gIChhZ2V0IGhlaWdodG1hcC5zaGFwZSAwKSlcblxuKGRlZm4gaGVpZ2h0bWFwLWxhc3QtaW5kZXggW2hlaWdodG1hcF1cbiAgKGRlYyAoaGVpZ2h0bWFwLXJlc29sdXRpb24gaGVpZ2h0bWFwKSkpXG5cbihkZWZuIGhlaWdodG1hcC1jZW50ZXItaW5kZXggW2hlaWdodG1hcF1cbiAgKG1pZHBvaW50IDAgKGhlaWdodG1hcC1sYXN0LWluZGV4IGhlaWdodG1hcCkpKVxuXG5cbihkZWZuIGhlaWdodG1hcC1nZXQgW2hlaWdodG1hcCB4IHldXG4gICguZ2V0IGhlaWdodG1hcCB4IHkpKVxuXG4oZGVmbiBoZWlnaHRtYXAtZ2V0LXNhZmUgW2hlaWdodG1hcCB4IHldXG4gIChsZXQgW2xhc3QgKGhlaWdodG1hcC1sYXN0LWluZGV4IGhlaWdodG1hcCldXG4gICAgKHdoZW4gKGFuZCAoPD0gMCB4IGxhc3QpXG4gICAgICAgICAgICAgICAoPD0gMCB5IGxhc3QpKVxuICAgICAgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIHggeSkpKSlcblxuKGRlZm4gaGVpZ2h0bWFwLXNldCEgW2hlaWdodG1hcCB4IHkgdmFsXVxuICAoLnNldCBoZWlnaHRtYXAgeCB5IHZhbCkpXG5cbihkZWZuIGhlaWdodG1hcC1zZXQtaWYtdW5zZXQhIFtoZWlnaHRtYXAgeCB5IHZhbF1cbiAgKHdoZW4gKD09IDAgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIHggeSkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCB4IHkgdmFsKSkpXG5cblxuKGRlZm4gbm9ybWFsaXplIFtoZWlnaHRtYXBdXG4gIChsZXQgW21heCAoLSBJbmZpbml0eSlcbiAgICAgICAgbWluIEluZmluaXR5XVxuICAgIChkby1uZGFycmF5LWVsIGVsIGhlaWdodG1hcFxuICAgICAgKHdoZW4gKDwgbWF4IGVsKSAoc2V0ISBtYXggZWwpKVxuICAgICAgKHdoZW4gKD4gbWluIGVsKSAoc2V0ISBtaW4gZWwpKSlcbiAgICAobGV0IFtzcGFuICgtIG1heCBtaW4pXVxuICAgICAgKGRvLW5kYXJyYXkgW3ggeV0gaGVpZ2h0bWFwXG4gICAgICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgeCB5XG4gICAgICAgICAgICAgICAgICAgICAgICAoLyAoLSAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgeCB5KSBtaW4pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFuKSkpKSkpXG5cblxuKGRlZm4gbWFrZS1oZWlnaHRtYXAgW2V4cG9uZW50XVxuICAobGV0IFtyZXNvbHV0aW9uICgrIChNYXRoLnBvdyAyIGV4cG9uZW50KSAxKV1cbiAgICAobGV0IFtoZWlnaHRtYXAgKG5kYXJyYXkgKG5ldyBGbG9hdDY0QXJyYXkgKCogcmVzb2x1dGlvbiByZXNvbHV0aW9uKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3Jlc29sdXRpb24gcmVzb2x1dGlvbl0pXVxuICAgICAgKHNldCEgaGVpZ2h0bWFwLmV4cG9uZW50IGV4cG9uZW50KVxuICAgICAgKHNldCEgaGVpZ2h0bWFwLnJlc29sdXRpb24gcmVzb2x1dGlvbilcbiAgICAgIChzZXQhIGhlaWdodG1hcC5sYXN0IChkZWMgcmVzb2x1dGlvbikpXG4gICAgICBoZWlnaHRtYXApKSlcblxuXG4oZGVmbiB0b3AtbGVmdC1jb3JuZXIgW2hlaWdodG1hcF1cbiAgKGxldCBbY2VudGVyIChoZWlnaHRtYXAtY2VudGVyLWluZGV4IGhlaWdodG1hcCldXG4gICAgKC0+IGhlaWdodG1hcFxuICAgICAgKC5sbyAwIDApXG4gICAgICAoLmhpIChpbmMgY2VudGVyKSAoaW5jIGNlbnRlcikpKSkpXG5cbihkZWZuIHRvcC1yaWdodC1jb3JuZXIgW2hlaWdodG1hcF1cbiAgKGxldCBbY2VudGVyIChoZWlnaHRtYXAtY2VudGVyLWluZGV4IGhlaWdodG1hcCldXG4gICAgKC0+IGhlaWdodG1hcFxuICAgICAgKC5sbyBjZW50ZXIgMClcbiAgICAgICguaGkgKGluYyBjZW50ZXIpIChpbmMgY2VudGVyKSkpKSlcblxuKGRlZm4gYm90dG9tLWxlZnQtY29ybmVyIFtoZWlnaHRtYXBdXG4gIChsZXQgW2NlbnRlciAoaGVpZ2h0bWFwLWNlbnRlci1pbmRleCBoZWlnaHRtYXApXVxuICAgICgtPiBoZWlnaHRtYXBcbiAgICAgICgubG8gMCBjZW50ZXIpXG4gICAgICAoLmhpIChpbmMgY2VudGVyKSAoaW5jIGNlbnRlcikpKSkpXG5cbihkZWZuIGJvdHRvbS1yaWdodC1jb3JuZXIgW2hlaWdodG1hcF1cbiAgKGxldCBbY2VudGVyIChoZWlnaHRtYXAtY2VudGVyLWluZGV4IGhlaWdodG1hcCldXG4gICAgKC0+IGhlaWdodG1hcFxuICAgICAgKC5sbyBjZW50ZXIgY2VudGVyKVxuICAgICAgKC5oaSAoaW5jIGNlbnRlcikgKGluYyBjZW50ZXIpKSkpKVxuXG5cbjsgTWlkcG9pbnQgRGlzcGxhY2VtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIG1wZC1pbml0LWNvcm5lcnMgW2hlaWdodG1hcF1cbiAgKGxldCBbbGFzdCAoaGVpZ2h0bWFwLWxhc3QtaW5kZXggaGVpZ2h0bWFwKV1cbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIDAgICAgMCAgICAocmFuZCkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCAwICAgIGxhc3QgKHJhbmQpKVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgbGFzdCAwICAgIChyYW5kKSlcbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIGxhc3QgbGFzdCAocmFuZCkpKSlcblxuKGRlZm4gbXBkLWRpc3BsYWNlIFtoZWlnaHRtYXAgc3ByZWFkIHNwcmVhZC1yZWR1Y3Rpb25dXG4gIChsZXQgW2xhc3QgKGhlaWdodG1hcC1sYXN0LWluZGV4IGhlaWdodG1hcClcbiAgICAgICAgYyAobWlkcG9pbnQgMCBsYXN0KVxuXG4gICAgICAgIGJvdHRvbS1sZWZ0ICAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgMCAgICAwKVxuICAgICAgICBib3R0b20tcmlnaHQgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwIGxhc3QgMClcbiAgICAgICAgdG9wLWxlZnQgICAgIChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCAwICAgIGxhc3QpXG4gICAgICAgIHRvcC1yaWdodCAgICAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgbGFzdCBsYXN0KVxuXG4gICAgICAgIHRvcCAgICAoYXZlcmFnZTIgdG9wLWxlZnQgdG9wLXJpZ2h0KVxuICAgICAgICBsZWZ0ICAgKGF2ZXJhZ2UyIGJvdHRvbS1sZWZ0IHRvcC1sZWZ0KVxuICAgICAgICBib3R0b20gKGF2ZXJhZ2UyIGJvdHRvbS1sZWZ0IGJvdHRvbS1yaWdodClcbiAgICAgICAgcmlnaHQgIChhdmVyYWdlMiBib3R0b20tcmlnaHQgdG9wLXJpZ2h0KVxuICAgICAgICBjZW50ZXIgKGF2ZXJhZ2U0IHRvcCBsZWZ0IGJvdHRvbSByaWdodClcblxuICAgICAgICBuZXh0LXNwcmVhZCAoKiBzcHJlYWQgc3ByZWFkLXJlZHVjdGlvbildXG4gICAgKGhlaWdodG1hcC1zZXQtaWYtdW5zZXQhIGhlaWdodG1hcCBjICAgIDAgICAgKGppdHRlciBib3R0b20gc3ByZWFkKSlcbiAgICAoaGVpZ2h0bWFwLXNldC1pZi11bnNldCEgaGVpZ2h0bWFwIGMgICAgbGFzdCAoaml0dGVyIHRvcCBzcHJlYWQpKVxuICAgIChoZWlnaHRtYXAtc2V0LWlmLXVuc2V0ISBoZWlnaHRtYXAgMCAgICBjICAgIChqaXR0ZXIgbGVmdCBzcHJlYWQpKVxuICAgIChoZWlnaHRtYXAtc2V0LWlmLXVuc2V0ISBoZWlnaHRtYXAgbGFzdCBjICAgIChqaXR0ZXIgcmlnaHQgc3ByZWFkKSlcbiAgICAoaGVpZ2h0bWFwLXNldC1pZi11bnNldCEgaGVpZ2h0bWFwIGMgICAgYyAgICAoaml0dGVyIGNlbnRlciBzcHJlYWQpKVxuICAgICh3aGVuLW5vdCAoPT0gMyAoaGVpZ2h0bWFwLXJlc29sdXRpb24gaGVpZ2h0bWFwKSlcbiAgICAgIChtcGQtZGlzcGxhY2UgKHRvcC1sZWZ0LWNvcm5lciBoZWlnaHRtYXApIG5leHQtc3ByZWFkIHNwcmVhZC1yZWR1Y3Rpb24pXG4gICAgICAobXBkLWRpc3BsYWNlICh0b3AtcmlnaHQtY29ybmVyIGhlaWdodG1hcCkgbmV4dC1zcHJlYWQgc3ByZWFkLXJlZHVjdGlvbilcbiAgICAgIChtcGQtZGlzcGxhY2UgKGJvdHRvbS1sZWZ0LWNvcm5lciBoZWlnaHRtYXApIG5leHQtc3ByZWFkIHNwcmVhZC1yZWR1Y3Rpb24pXG4gICAgICAobXBkLWRpc3BsYWNlIChib3R0b20tcmlnaHQtY29ybmVyIGhlaWdodG1hcCkgbmV4dC1zcHJlYWQgc3ByZWFkLXJlZHVjdGlvbikpKSlcblxuKGRlZm4gbWlkcG9pbnQtZGlzcGxhY2VtZW50IFtoZWlnaHRtYXBdXG4gIChsZXQgW2luaXRpYWwtc3ByZWFkIDAuMyBcbiAgICAgICAgc3ByZWFkLXJlZHVjdGlvbiAwLjU1XVxuICAgIChtcGQtaW5pdC1jb3JuZXJzIGhlaWdodG1hcClcbiAgICAobXBkLWRpc3BsYWNlIGhlaWdodG1hcCBpbml0aWFsLXNwcmVhZCBzcHJlYWQtcmVkdWN0aW9uKVxuICAgIChub3JtYWxpemUgaGVpZ2h0bWFwKSkpXG5cblxuOyBUaHJlZS5qcyBIZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZm4gbWFrZS1kaXJlY3Rpb25hbC1saWdodCBbXVxuICAobGV0IFtsaWdodCAobmV3IFRIUkVFLkRpcmVjdGlvbmFsTGlnaHQgMHhmZmZmZmYgMSldXG4gICAgKGxpZ2h0LnBvc2l0aW9uLnNldCAxMDAgMCAxNTApXG4gICAgbGlnaHQpKVxuXG4oZGVmbiBtYWtlLWNhbWVyYSBbXVxuICAobGV0IFtjYW1lcmEgKG5ldyBUSFJFRS5QZXJzcGVjdGl2ZUNhbWVyYVxuICAgICAgICAgICAgICAgICAgICA1NSxcbiAgICAgICAgICAgICAgICAgICAgKC8gd2lkdGggaGVpZ2h0KVxuICAgICAgICAgICAgICAgICAgICAwLjEsXG4gICAgICAgICAgICAgICAgICAgIDEwMDApXVxuICAgIChjYW1lcmEucG9zaXRpb24uc2V0IDAgLTEwMCAxNTApXG4gICAgY2FtZXJhKSlcblxuKGRlZm4gbWFrZS1yZW5kZXJlciBbXVxuICAobGV0IFtyZW5kZXJlciAobmV3IFRIUkVFLldlYkdMUmVuZGVyZXIgezphbnRpYWxpYXMgZmFsc2V9KV1cbiAgICAocmVuZGVyZXIuc2V0Q2xlYXJDb2xvciAweGZmZmZmZilcbiAgICAocmVuZGVyZXIuc2V0U2l6ZSB3aWR0aCBoZWlnaHQpXG4gICAgKHJlbmRlcmVyLnNldFBpeGVsUmF0aW8gMilcbiAgICByZW5kZXJlcikpXG5cbihkZWZuIG1ha2UtZ2VvbWV0cnkgW2hlaWdodG1hcF1cbiAgKGxldCBbcmVzb2x1dGlvbiAoYWdldCBoZWlnaHRtYXAuc2hhcGUgMClcbiAgICAgICAgZ2VvbWV0cnkgKG5ldyBUSFJFRS5QbGFuZUdlb21ldHJ5XG4gICAgICAgICAgICAgICAgICAgICAgdGVycmFpbi1zaXplXG4gICAgICAgICAgICAgICAgICAgICAgdGVycmFpbi1zaXplXG4gICAgICAgICAgICAgICAgICAgICAgKC0gcmVzb2x1dGlvbiAxKVxuICAgICAgICAgICAgICAgICAgICAgICgtIHJlc29sdXRpb24gMSkpXVxuICAgIGdlb21ldHJ5KSlcblxuKGRlZm4gbWFrZS1jb250cm9scyBbY2FtZXJhIHJlbmRlcmVyXVxuICAobGV0IFtjb250cm9scyAobmV3IFRIUkVFLlRyYWNrYmFsbENvbnRyb2xzIGNhbWVyYSByZW5kZXJlci5kb21FbGVtZW50KV1cbiAgICAoc2V0ISBjb250cm9scy5yb3RhdGVTcGVlZCAxLjQpXG4gICAgKHNldCEgY29udHJvbHMuem9vbVNwZWVkIDAuNSlcbiAgICAoc2V0ISBjb250cm9scy5zdGF0aWNNb3ZpbmcgdHJ1ZSlcbiAgICAoc2V0ISBjb250cm9scy5keW5hbWljRGFtcGluZ0ZhY3RvciAwLjMpXG4gICAgY29udHJvbHMpKVxuXG4oZGVmbiBtYWtlLXBsYW5lIFtnZW9tZXRyeV1cbiAgKGxldCBbbWF0ZXJpYWwgKG5ldyBUSFJFRS5NZXNoTGFtYmVydE1hdGVyaWFsXG4gICAgICAgICAgICAgICAgICAgICAgezp3aXJlZnJhbWUgd2lyZWZyYW1lXG4gICAgICAgICAgICAgICAgICAgICAgIDp3aXJlZnJhbWVMaW5ld2lkdGggd2lyZWZyYW1lLXdpZHRoXG4gICAgICAgICAgICAgICAgICAgICAgIDpjb2xvciAweDAwYmIwMH0pXVxuICAgIChuZXcgVEhSRUUuTWVzaCBnZW9tZXRyeSBtYXRlcmlhbCkpKVxuXG5cbihkZWZuIGF0dGFjaC10by1kb20gW3JlbmRlcmVyIGVsLW5hbWUgcmVmcmVzaC1mbl1cbiAgKGxldCBbY29udGFpbmVyIChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCBlbC1uYW1lKVxuICAgICAgICBzZXR0aW5ncyAoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcImRpdlwiKVxuICAgICAgICByZWZyZXNoLWJ1dHRvbiAoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCBcImJ1dHRvblwiKVxuICAgICAgICBidXR0b24tdGV4dCAoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUgXCJSZWZyZXNoXCIpXG4gICAgICAgIGNhbmNlbC1zY3JvbGwgKGZuIFtlXSAoLnByZXZlbnREZWZhdWx0IGUpKV1cbiAgICAoc2V0ISByZWZyZXNoLWJ1dHRvbi5vbmNsaWNrIHJlZnJlc2gtZm4pXG4gICAgKHNldCEgcmVuZGVyZXIuZG9tRWxlbWVudC5vbm1vdXNld2hlZWwgY2FuY2VsLXNjcm9sbClcbiAgICAocmVuZGVyZXIuZG9tRWxlbWVudC5hZGRFdmVudExpc3RlbmVyIFwiTW96TW91c2VQaXhlbFNjcm9sbFwiIGNhbmNlbC1zY3JvbGwgZmFsc2UpXG4gICAgKC5hcHBlbmRDaGlsZCByZWZyZXNoLWJ1dHRvbiBidXR0b24tdGV4dClcbiAgICAoLmFwcGVuZENoaWxkIGNvbnRhaW5lciByZW5kZXJlci5kb21FbGVtZW50KVxuICAgICguYXBwZW5kQ2hpbGQgY29udGFpbmVyIHNldHRpbmdzKVxuICAgICguYXBwZW5kQ2hpbGQgc2V0dGluZ3MgcmVmcmVzaC1idXR0b24pKSlcblxuXG4oZGVmbiB1cGRhdGUtZ2VvbWV0cnkgW2dlb21ldHJ5IGhlaWdodG1hcF1cbiAgKGxvb3AgW2kgMF1cbiAgICAoaWYgKDwgaSBnZW9tZXRyeS52ZXJ0aWNlcy5sZW5ndGgpXG4gICAgICAoZG8gKHNldCEgKC4teiAoYWdldCBnZW9tZXRyeS52ZXJ0aWNlcyBpKSlcbiAgICAgICAgICAgICAgICAoKiB0ZXJyYWluLWhlaWdodCAoYWdldCAoLi1kYXRhIGhlaWdodG1hcCkgaSkpKVxuICAgICAgICAocmVjdXIgKCsgaSAxKSkpKSlcbiAgKGdlb21ldHJ5LmNvbXB1dGVWZXJ0ZXhOb3JtYWxzKVxuICBnZW9tZXRyeSlcblxuXG47IE1haW4gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbiBtYWtlLWZpbmFsIFtlbGVtZW50LWlkXVxuICAoZGVmIHNjZW5lIChuZXcgVEhSRUUuU2NlbmUpKVxuICAoc2NlbmUuYWRkIChuZXcgVEhSRUUuQXhpc0hlbHBlciAxMDApKVxuXG4gIChkZWYgY2xvY2sgKG5ldyBUSFJFRS5DbG9jaykpXG4gIChkZWYgY2FtZXJhIChtYWtlLWNhbWVyYSkpXG4gIChkZWYgcmVuZGVyZXIgKG1ha2UtcmVuZGVyZXIpKVxuXG4gIChkZWYgZ2VvbWV0cnkpXG4gIChkZWYgcGxhbmUpXG5cbiAgKHNjZW5lLmFkZCAobWFrZS1kaXJlY3Rpb25hbC1saWdodCkpXG4gIChzY2VuZS5hZGQgKG5ldyBUSFJFRS5BbWJpZW50TGlnaHQgMHhmZmZmZmYgMC4wNSkpXG5cbiAgKGRlZm4gcmVmcmVzaCBbXVxuICAgIChsZXQgW2hlaWdodG1hcCAobWFrZS1oZWlnaHRtYXAgNildXG4gICAgICAobCBcIkdlbmVyYXRpbmcgdGVycmFpbi4uLlwiKVxuICAgICAgKHRpbWUgKG1pZHBvaW50LWRpc3BsYWNlbWVudCBoZWlnaHRtYXApKVxuXG4gICAgICAobCBcIlJlYnVpbGRpbmcgZ2VvbWV0cnkuLi5cIilcbiAgICAgICh0aW1lXG4gICAgICAgIChzZXQhIGdlb21ldHJ5IChtYWtlLWdlb21ldHJ5IGhlaWdodG1hcCkpXG4gICAgICAgICh1cGRhdGUtZ2VvbWV0cnkgZ2VvbWV0cnkgaGVpZ2h0bWFwKSlcblxuICAgICAgKGwgXCJSZWJ1aWxkaW5nIHBsYW5lLi4uXCIpXG4gICAgICAodGltZVxuICAgICAgICAoc2NlbmUucmVtb3ZlIHBsYW5lKVxuICAgICAgICAoc2V0ISBwbGFuZSAobWFrZS1wbGFuZSBnZW9tZXRyeSkpXG4gICAgICAgIChzY2VuZS5hZGQgcGxhbmUpKSkpXG5cbiAgKGF0dGFjaC10by1kb20gcmVuZGVyZXIgZWxlbWVudC1pZCByZWZyZXNoKVxuICAoZGVmIGNvbnRyb2xzIChtYWtlLWNvbnRyb2xzIGNhbWVyYSByZW5kZXJlcikpXG5cbiAgKGRlZm4gcmVuZGVyIFtdXG4gICAgKGxldCBbZGVsdGEgKGNsb2NrLmdldERlbHRhKV1cbiAgICAgIChyZXF1ZXN0QW5pbWF0aW9uRnJhbWUgcmVuZGVyKVxuICAgICAgKC51cGRhdGUgY29udHJvbHMgZGVsdGEpXG4gICAgICAocmVuZGVyZXIucmVuZGVyIHNjZW5lIGNhbWVyYSkpKVxuXG4gIChyZWZyZXNoKVxuICAocmVuZGVyKVxuXG4gIG5pbClcblxuKGRlZm4gcnVuIFtdXG4gIChtYWtlLWZpbmFsIFwiZGVtby1maW5hbFwiKSlcblxuKCQgcnVuKVxuXG5cbjsgdmltOiBsdys9ZG8tdGltZXMgbHcrPWRvLW5lc3RlZCA6XG4iLCJcInVzZSBzdHJpY3RcIlxuXG5mdW5jdGlvbiBpb3RhKG4pIHtcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheShuKVxuICBmb3IodmFyIGk9MDsgaTxuOyArK2kpIHtcbiAgICByZXN1bHRbaV0gPSBpXG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlvdGEiLCIvKipcbiAqIERldGVybWluZSBpZiBhbiBvYmplY3QgaXMgQnVmZmVyXG4gKlxuICogQXV0aG9yOiAgIEZlcm9zcyBBYm91a2hhZGlqZWggPGZlcm9zc0BmZXJvc3Mub3JnPiA8aHR0cDovL2Zlcm9zcy5vcmc+XG4gKiBMaWNlbnNlOiAgTUlUXG4gKlxuICogYG5wbSBpbnN0YWxsIGlzLWJ1ZmZlcmBcbiAqL1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvYmopIHtcbiAgcmV0dXJuICEhKG9iaiAhPSBudWxsICYmXG4gICAgKG9iai5faXNCdWZmZXIgfHwgLy8gRm9yIFNhZmFyaSA1LTcgKG1pc3NpbmcgT2JqZWN0LnByb3RvdHlwZS5jb25zdHJ1Y3RvcilcbiAgICAgIChvYmouY29uc3RydWN0b3IgJiZcbiAgICAgIHR5cGVvZiBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIgPT09ICdmdW5jdGlvbicgJiZcbiAgICAgIG9iai5jb25zdHJ1Y3Rvci5pc0J1ZmZlcihvYmopKVxuICAgICkpXG59XG4iLCJ2YXIgaW90YSA9IHJlcXVpcmUoXCJpb3RhLWFycmF5XCIpXG52YXIgaXNCdWZmZXIgPSByZXF1aXJlKFwiaXMtYnVmZmVyXCIpXG5cbnZhciBoYXNUeXBlZEFycmF5cyAgPSAoKHR5cGVvZiBGbG9hdDY0QXJyYXkpICE9PSBcInVuZGVmaW5lZFwiKVxuXG5mdW5jdGlvbiBjb21wYXJlMXN0KGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gLSBiWzBdXG59XG5cbmZ1bmN0aW9uIG9yZGVyKCkge1xuICB2YXIgc3RyaWRlID0gdGhpcy5zdHJpZGVcbiAgdmFyIHRlcm1zID0gbmV3IEFycmF5KHN0cmlkZS5sZW5ndGgpXG4gIHZhciBpXG4gIGZvcihpPTA7IGk8dGVybXMubGVuZ3RoOyArK2kpIHtcbiAgICB0ZXJtc1tpXSA9IFtNYXRoLmFicyhzdHJpZGVbaV0pLCBpXVxuICB9XG4gIHRlcm1zLnNvcnQoY29tcGFyZTFzdClcbiAgdmFyIHJlc3VsdCA9IG5ldyBBcnJheSh0ZXJtcy5sZW5ndGgpXG4gIGZvcihpPTA7IGk8cmVzdWx0Lmxlbmd0aDsgKytpKSB7XG4gICAgcmVzdWx0W2ldID0gdGVybXNbaV1bMV1cbiAgfVxuICByZXR1cm4gcmVzdWx0XG59XG5cbmZ1bmN0aW9uIGNvbXBpbGVDb25zdHJ1Y3RvcihkdHlwZSwgZGltZW5zaW9uKSB7XG4gIHZhciBjbGFzc05hbWUgPSBbXCJWaWV3XCIsIGRpbWVuc2lvbiwgXCJkXCIsIGR0eXBlXS5qb2luKFwiXCIpXG4gIGlmKGRpbWVuc2lvbiA8IDApIHtcbiAgICBjbGFzc05hbWUgPSBcIlZpZXdfTmlsXCIgKyBkdHlwZVxuICB9XG4gIHZhciB1c2VHZXR0ZXJzID0gKGR0eXBlID09PSBcImdlbmVyaWNcIilcblxuICBpZihkaW1lbnNpb24gPT09IC0xKSB7XG4gICAgLy9TcGVjaWFsIGNhc2UgZm9yIHRyaXZpYWwgYXJyYXlzXG4gICAgdmFyIGNvZGUgPVxuICAgICAgXCJmdW5jdGlvbiBcIitjbGFzc05hbWUrXCIoYSl7dGhpcy5kYXRhPWE7fTtcXFxudmFyIHByb3RvPVwiK2NsYXNzTmFtZStcIi5wcm90b3R5cGU7XFxcbnByb3RvLmR0eXBlPSdcIitkdHlwZStcIic7XFxcbnByb3RvLmluZGV4PWZ1bmN0aW9uKCl7cmV0dXJuIC0xfTtcXFxucHJvdG8uc2l6ZT0wO1xcXG5wcm90by5kaW1lbnNpb249LTE7XFxcbnByb3RvLnNoYXBlPXByb3RvLnN0cmlkZT1wcm90by5vcmRlcj1bXTtcXFxucHJvdG8ubG89cHJvdG8uaGk9cHJvdG8udHJhbnNwb3NlPXByb3RvLnN0ZXA9XFxcbmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIodGhpcy5kYXRhKTt9O1xcXG5wcm90by5nZXQ9cHJvdG8uc2V0PWZ1bmN0aW9uKCl7fTtcXFxucHJvdG8ucGljaz1mdW5jdGlvbigpe3JldHVybiBudWxsfTtcXFxucmV0dXJuIGZ1bmN0aW9uIGNvbnN0cnVjdF9cIitjbGFzc05hbWUrXCIoYSl7cmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIoYSk7fVwiXG4gICAgdmFyIHByb2NlZHVyZSA9IG5ldyBGdW5jdGlvbihjb2RlKVxuICAgIHJldHVybiBwcm9jZWR1cmUoKVxuICB9IGVsc2UgaWYoZGltZW5zaW9uID09PSAwKSB7XG4gICAgLy9TcGVjaWFsIGNhc2UgZm9yIDBkIGFycmF5c1xuICAgIHZhciBjb2RlID1cbiAgICAgIFwiZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiKGEsZCkge1xcXG50aGlzLmRhdGEgPSBhO1xcXG50aGlzLm9mZnNldCA9IGRcXFxufTtcXFxudmFyIHByb3RvPVwiK2NsYXNzTmFtZStcIi5wcm90b3R5cGU7XFxcbnByb3RvLmR0eXBlPSdcIitkdHlwZStcIic7XFxcbnByb3RvLmluZGV4PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub2Zmc2V0fTtcXFxucHJvdG8uZGltZW5zaW9uPTA7XFxcbnByb3RvLnNpemU9MTtcXFxucHJvdG8uc2hhcGU9XFxcbnByb3RvLnN0cmlkZT1cXFxucHJvdG8ub3JkZXI9W107XFxcbnByb3RvLmxvPVxcXG5wcm90by5oaT1cXFxucHJvdG8udHJhbnNwb3NlPVxcXG5wcm90by5zdGVwPWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9jb3B5KCkge1xcXG5yZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIih0aGlzLmRhdGEsdGhpcy5vZmZzZXQpXFxcbn07XFxcbnByb3RvLnBpY2s9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3BpY2soKXtcXFxucmV0dXJuIFRyaXZpYWxBcnJheSh0aGlzLmRhdGEpO1xcXG59O1xcXG5wcm90by52YWx1ZU9mPXByb3RvLmdldD1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfZ2V0KCl7XFxcbnJldHVybiBcIisodXNlR2V0dGVycyA/IFwidGhpcy5kYXRhLmdldCh0aGlzLm9mZnNldClcIiA6IFwidGhpcy5kYXRhW3RoaXMub2Zmc2V0XVwiKStcblwifTtcXFxucHJvdG8uc2V0PWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9zZXQodil7XFxcbnJldHVybiBcIisodXNlR2V0dGVycyA/IFwidGhpcy5kYXRhLnNldCh0aGlzLm9mZnNldCx2KVwiIDogXCJ0aGlzLmRhdGFbdGhpcy5vZmZzZXRdPXZcIikrXCJcXFxufTtcXFxucmV0dXJuIGZ1bmN0aW9uIGNvbnN0cnVjdF9cIitjbGFzc05hbWUrXCIoYSxiLGMsZCl7cmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIoYSxkKX1cIlxuICAgIHZhciBwcm9jZWR1cmUgPSBuZXcgRnVuY3Rpb24oXCJUcml2aWFsQXJyYXlcIiwgY29kZSlcbiAgICByZXR1cm4gcHJvY2VkdXJlKENBQ0hFRF9DT05TVFJVQ1RPUlNbZHR5cGVdWzBdKVxuICB9XG5cbiAgdmFyIGNvZGUgPSBbXCIndXNlIHN0cmljdCdcIl1cblxuICAvL0NyZWF0ZSBjb25zdHJ1Y3RvciBmb3Igdmlld1xuICB2YXIgaW5kaWNlcyA9IGlvdGEoZGltZW5zaW9uKVxuICB2YXIgYXJncyA9IGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIFwiaVwiK2kgfSlcbiAgdmFyIGluZGV4X3N0ciA9IFwidGhpcy5vZmZzZXQrXCIgKyBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICAgIHJldHVybiBcInRoaXMuc3RyaWRlW1wiICsgaSArIFwiXSppXCIgKyBpXG4gICAgICB9KS5qb2luKFwiK1wiKVxuICB2YXIgc2hhcGVBcmcgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJiXCIraVxuICAgIH0pLmpvaW4oXCIsXCIpXG4gIHZhciBzdHJpZGVBcmcgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJjXCIraVxuICAgIH0pLmpvaW4oXCIsXCIpXG4gIGNvZGUucHVzaChcbiAgICBcImZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIihhLFwiICsgc2hhcGVBcmcgKyBcIixcIiArIHN0cmlkZUFyZyArIFwiLGQpe3RoaXMuZGF0YT1hXCIsXG4gICAgICBcInRoaXMuc2hhcGU9W1wiICsgc2hhcGVBcmcgKyBcIl1cIixcbiAgICAgIFwidGhpcy5zdHJpZGU9W1wiICsgc3RyaWRlQXJnICsgXCJdXCIsXG4gICAgICBcInRoaXMub2Zmc2V0PWR8MH1cIixcbiAgICBcInZhciBwcm90bz1cIitjbGFzc05hbWUrXCIucHJvdG90eXBlXCIsXG4gICAgXCJwcm90by5kdHlwZT0nXCIrZHR5cGUrXCInXCIsXG4gICAgXCJwcm90by5kaW1lbnNpb249XCIrZGltZW5zaW9uKVxuXG4gIC8vdmlldy5zaXplOlxuICBjb2RlLnB1c2goXCJPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvdG8sJ3NpemUnLHtnZXQ6ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3NpemUoKXtcXFxucmV0dXJuIFwiK2luZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIFwidGhpcy5zaGFwZVtcIitpK1wiXVwiIH0pLmpvaW4oXCIqXCIpLFxuXCJ9fSlcIilcblxuICAvL3ZpZXcub3JkZXI6XG4gIGlmKGRpbWVuc2lvbiA9PT0gMSkge1xuICAgIGNvZGUucHVzaChcInByb3RvLm9yZGVyPVswXVwiKVxuICB9IGVsc2Uge1xuICAgIGNvZGUucHVzaChcIk9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm90bywnb3JkZXInLHtnZXQ6XCIpXG4gICAgaWYoZGltZW5zaW9uIDwgNCkge1xuICAgICAgY29kZS5wdXNoKFwiZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX29yZGVyKCl7XCIpXG4gICAgICBpZihkaW1lbnNpb24gPT09IDIpIHtcbiAgICAgICAgY29kZS5wdXNoKFwicmV0dXJuIChNYXRoLmFicyh0aGlzLnN0cmlkZVswXSk+TWF0aC5hYnModGhpcy5zdHJpZGVbMV0pKT9bMSwwXTpbMCwxXX19KVwiKVxuICAgICAgfSBlbHNlIGlmKGRpbWVuc2lvbiA9PT0gMykge1xuICAgICAgICBjb2RlLnB1c2goXG5cInZhciBzMD1NYXRoLmFicyh0aGlzLnN0cmlkZVswXSksczE9TWF0aC5hYnModGhpcy5zdHJpZGVbMV0pLHMyPU1hdGguYWJzKHRoaXMuc3RyaWRlWzJdKTtcXFxuaWYoczA+czEpe1xcXG5pZihzMT5zMil7XFxcbnJldHVybiBbMiwxLDBdO1xcXG59ZWxzZSBpZihzMD5zMil7XFxcbnJldHVybiBbMSwyLDBdO1xcXG59ZWxzZXtcXFxucmV0dXJuIFsxLDAsMl07XFxcbn1cXFxufWVsc2UgaWYoczA+czIpe1xcXG5yZXR1cm4gWzIsMCwxXTtcXFxufWVsc2UgaWYoczI+czEpe1xcXG5yZXR1cm4gWzAsMSwyXTtcXFxufWVsc2V7XFxcbnJldHVybiBbMCwyLDFdO1xcXG59fX0pXCIpXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGUucHVzaChcIk9SREVSfSlcIilcbiAgICB9XG4gIH1cblxuICAvL3ZpZXcuc2V0KGkwLCAuLi4sIHYpOlxuICBjb2RlLnB1c2goXG5cInByb3RvLnNldD1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfc2V0KFwiK2FyZ3Muam9pbihcIixcIikrXCIsdil7XCIpXG4gIGlmKHVzZUdldHRlcnMpIHtcbiAgICBjb2RlLnB1c2goXCJyZXR1cm4gdGhpcy5kYXRhLnNldChcIitpbmRleF9zdHIrXCIsdil9XCIpXG4gIH0gZWxzZSB7XG4gICAgY29kZS5wdXNoKFwicmV0dXJuIHRoaXMuZGF0YVtcIitpbmRleF9zdHIrXCJdPXZ9XCIpXG4gIH1cblxuICAvL3ZpZXcuZ2V0KGkwLCAuLi4pOlxuICBjb2RlLnB1c2goXCJwcm90by5nZXQ9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX2dldChcIithcmdzLmpvaW4oXCIsXCIpK1wiKXtcIilcbiAgaWYodXNlR2V0dGVycykge1xuICAgIGNvZGUucHVzaChcInJldHVybiB0aGlzLmRhdGEuZ2V0KFwiK2luZGV4X3N0citcIil9XCIpXG4gIH0gZWxzZSB7XG4gICAgY29kZS5wdXNoKFwicmV0dXJuIHRoaXMuZGF0YVtcIitpbmRleF9zdHIrXCJdfVwiKVxuICB9XG5cbiAgLy92aWV3LmluZGV4OlxuICBjb2RlLnB1c2goXG4gICAgXCJwcm90by5pbmRleD1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfaW5kZXgoXCIsIGFyZ3Muam9pbigpLCBcIil7cmV0dXJuIFwiK2luZGV4X3N0citcIn1cIilcblxuICAvL3ZpZXcuaGkoKTpcbiAgY29kZS5wdXNoKFwicHJvdG8uaGk9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX2hpKFwiK2FyZ3Muam9pbihcIixcIikrXCIpe3JldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKHRoaXMuZGF0YSxcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gW1wiKHR5cGVvZiBpXCIsaSxcIiE9PSdudW1iZXInfHxpXCIsaSxcIjwwKT90aGlzLnNoYXBlW1wiLCBpLCBcIl06aVwiLCBpLFwifDBcIl0uam9pbihcIlwiKVxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcInRoaXMuc3RyaWRlW1wiK2kgKyBcIl1cIlxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLHRoaXMub2Zmc2V0KX1cIilcblxuICAvL3ZpZXcubG8oKTpcbiAgdmFyIGFfdmFycyA9IGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIFwiYVwiK2krXCI9dGhpcy5zaGFwZVtcIitpK1wiXVwiIH0pXG4gIHZhciBjX3ZhcnMgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7IHJldHVybiBcImNcIitpK1wiPXRoaXMuc3RyaWRlW1wiK2krXCJdXCIgfSlcbiAgY29kZS5wdXNoKFwicHJvdG8ubG89ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX2xvKFwiK2FyZ3Muam9pbihcIixcIikrXCIpe3ZhciBiPXRoaXMub2Zmc2V0LGQ9MCxcIithX3ZhcnMuam9pbihcIixcIikrXCIsXCIrY192YXJzLmpvaW4oXCIsXCIpKVxuICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xuICAgIGNvZGUucHVzaChcblwiaWYodHlwZW9mIGlcIitpK1wiPT09J251bWJlcicmJmlcIitpK1wiPj0wKXtcXFxuZD1pXCIraStcInwwO1xcXG5iKz1jXCIraStcIipkO1xcXG5hXCIraStcIi09ZH1cIilcbiAgfVxuICBjb2RlLnB1c2goXCJyZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIih0aGlzLmRhdGEsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwiYVwiK2lcbiAgICB9KS5qb2luKFwiLFwiKStcIixcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJjXCIraVxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLGIpfVwiKVxuXG4gIC8vdmlldy5zdGVwKCk6XG4gIGNvZGUucHVzaChcInByb3RvLnN0ZXA9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3N0ZXAoXCIrYXJncy5qb2luKFwiLFwiKStcIil7dmFyIFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImFcIitpK1wiPXRoaXMuc2hhcGVbXCIraStcIl1cIlxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImJcIitpK1wiPXRoaXMuc3RyaWRlW1wiK2krXCJdXCJcbiAgICB9KS5qb2luKFwiLFwiKStcIixjPXRoaXMub2Zmc2V0LGQ9MCxjZWlsPU1hdGguY2VpbFwiKVxuICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xuICAgIGNvZGUucHVzaChcblwiaWYodHlwZW9mIGlcIitpK1wiPT09J251bWJlcicpe1xcXG5kPWlcIitpK1wifDA7XFxcbmlmKGQ8MCl7XFxcbmMrPWJcIitpK1wiKihhXCIraStcIi0xKTtcXFxuYVwiK2krXCI9Y2VpbCgtYVwiK2krXCIvZClcXFxufWVsc2V7XFxcbmFcIitpK1wiPWNlaWwoYVwiK2krXCIvZClcXFxufVxcXG5iXCIraStcIio9ZFxcXG59XCIpXG4gIH1cbiAgY29kZS5wdXNoKFwicmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIodGhpcy5kYXRhLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImFcIiArIGlcbiAgICB9KS5qb2luKFwiLFwiKStcIixcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJiXCIgKyBpXG4gICAgfSkuam9pbihcIixcIikrXCIsYyl9XCIpXG5cbiAgLy92aWV3LnRyYW5zcG9zZSgpOlxuICB2YXIgdFNoYXBlID0gbmV3IEFycmF5KGRpbWVuc2lvbilcbiAgdmFyIHRTdHJpZGUgPSBuZXcgQXJyYXkoZGltZW5zaW9uKVxuICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xuICAgIHRTaGFwZVtpXSA9IFwiYVtpXCIraStcIl1cIlxuICAgIHRTdHJpZGVbaV0gPSBcImJbaVwiK2krXCJdXCJcbiAgfVxuICBjb2RlLnB1c2goXCJwcm90by50cmFuc3Bvc2U9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3RyYW5zcG9zZShcIithcmdzK1wiKXtcIitcbiAgICBhcmdzLm1hcChmdW5jdGlvbihuLGlkeCkgeyByZXR1cm4gbiArIFwiPShcIiArIG4gKyBcIj09PXVuZGVmaW5lZD9cIiArIGlkeCArIFwiOlwiICsgbiArIFwifDApXCJ9KS5qb2luKFwiO1wiKSxcbiAgICBcInZhciBhPXRoaXMuc2hhcGUsYj10aGlzLnN0cmlkZTtyZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIih0aGlzLmRhdGEsXCIrdFNoYXBlLmpvaW4oXCIsXCIpK1wiLFwiK3RTdHJpZGUuam9pbihcIixcIikrXCIsdGhpcy5vZmZzZXQpfVwiKVxuXG4gIC8vdmlldy5waWNrKCk6XG4gIGNvZGUucHVzaChcInByb3RvLnBpY2s9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3BpY2soXCIrYXJncytcIil7dmFyIGE9W10sYj1bXSxjPXRoaXMub2Zmc2V0XCIpXG4gIGZvcih2YXIgaT0wOyBpPGRpbWVuc2lvbjsgKytpKSB7XG4gICAgY29kZS5wdXNoKFwiaWYodHlwZW9mIGlcIitpK1wiPT09J251bWJlcicmJmlcIitpK1wiPj0wKXtjPShjK3RoaXMuc3RyaWRlW1wiK2krXCJdKmlcIitpK1wiKXwwfWVsc2V7YS5wdXNoKHRoaXMuc2hhcGVbXCIraStcIl0pO2IucHVzaCh0aGlzLnN0cmlkZVtcIitpK1wiXSl9XCIpXG4gIH1cbiAgY29kZS5wdXNoKFwidmFyIGN0b3I9Q1RPUl9MSVNUW2EubGVuZ3RoKzFdO3JldHVybiBjdG9yKHRoaXMuZGF0YSxhLGIsYyl9XCIpXG5cbiAgLy9BZGQgcmV0dXJuIHN0YXRlbWVudFxuICBjb2RlLnB1c2goXCJyZXR1cm4gZnVuY3Rpb24gY29uc3RydWN0X1wiK2NsYXNzTmFtZStcIihkYXRhLHNoYXBlLHN0cmlkZSxvZmZzZXQpe3JldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKGRhdGEsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwic2hhcGVbXCIraStcIl1cIlxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcInN0cmlkZVtcIitpK1wiXVwiXG4gICAgfSkuam9pbihcIixcIikrXCIsb2Zmc2V0KX1cIilcblxuICAvL0NvbXBpbGUgcHJvY2VkdXJlXG4gIHZhciBwcm9jZWR1cmUgPSBuZXcgRnVuY3Rpb24oXCJDVE9SX0xJU1RcIiwgXCJPUkRFUlwiLCBjb2RlLmpvaW4oXCJcXG5cIikpXG4gIHJldHVybiBwcm9jZWR1cmUoQ0FDSEVEX0NPTlNUUlVDVE9SU1tkdHlwZV0sIG9yZGVyKVxufVxuXG5mdW5jdGlvbiBhcnJheURUeXBlKGRhdGEpIHtcbiAgaWYoaXNCdWZmZXIoZGF0YSkpIHtcbiAgICByZXR1cm4gXCJidWZmZXJcIlxuICB9XG4gIGlmKGhhc1R5cGVkQXJyYXlzKSB7XG4gICAgc3dpdGNoKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChkYXRhKSkge1xuICAgICAgY2FzZSBcIltvYmplY3QgRmxvYXQ2NEFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJmbG9hdDY0XCJcbiAgICAgIGNhc2UgXCJbb2JqZWN0IEZsb2F0MzJBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwiZmxvYXQzMlwiXG4gICAgICBjYXNlIFwiW29iamVjdCBJbnQ4QXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcImludDhcIlxuICAgICAgY2FzZSBcIltvYmplY3QgSW50MTZBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwiaW50MTZcIlxuICAgICAgY2FzZSBcIltvYmplY3QgSW50MzJBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwiaW50MzJcIlxuICAgICAgY2FzZSBcIltvYmplY3QgVWludDhBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwidWludDhcIlxuICAgICAgY2FzZSBcIltvYmplY3QgVWludDE2QXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcInVpbnQxNlwiXG4gICAgICBjYXNlIFwiW29iamVjdCBVaW50MzJBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwidWludDMyXCJcbiAgICAgIGNhc2UgXCJbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJ1aW50OF9jbGFtcGVkXCJcbiAgICB9XG4gIH1cbiAgaWYoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgIHJldHVybiBcImFycmF5XCJcbiAgfVxuICByZXR1cm4gXCJnZW5lcmljXCJcbn1cblxudmFyIENBQ0hFRF9DT05TVFJVQ1RPUlMgPSB7XG4gIFwiZmxvYXQzMlwiOltdLFxuICBcImZsb2F0NjRcIjpbXSxcbiAgXCJpbnQ4XCI6W10sXG4gIFwiaW50MTZcIjpbXSxcbiAgXCJpbnQzMlwiOltdLFxuICBcInVpbnQ4XCI6W10sXG4gIFwidWludDE2XCI6W10sXG4gIFwidWludDMyXCI6W10sXG4gIFwiYXJyYXlcIjpbXSxcbiAgXCJ1aW50OF9jbGFtcGVkXCI6W10sXG4gIFwiYnVmZmVyXCI6W10sXG4gIFwiZ2VuZXJpY1wiOltdXG59XG5cbjsoZnVuY3Rpb24oKSB7XG4gIGZvcih2YXIgaWQgaW4gQ0FDSEVEX0NPTlNUUlVDVE9SUykge1xuICAgIENBQ0hFRF9DT05TVFJVQ1RPUlNbaWRdLnB1c2goY29tcGlsZUNvbnN0cnVjdG9yKGlkLCAtMSkpXG4gIH1cbn0pO1xuXG5mdW5jdGlvbiB3cmFwcGVkTkRBcnJheUN0b3IoZGF0YSwgc2hhcGUsIHN0cmlkZSwgb2Zmc2V0KSB7XG4gIGlmKGRhdGEgPT09IHVuZGVmaW5lZCkge1xuICAgIHZhciBjdG9yID0gQ0FDSEVEX0NPTlNUUlVDVE9SUy5hcnJheVswXVxuICAgIHJldHVybiBjdG9yKFtdKVxuICB9IGVsc2UgaWYodHlwZW9mIGRhdGEgPT09IFwibnVtYmVyXCIpIHtcbiAgICBkYXRhID0gW2RhdGFdXG4gIH1cbiAgaWYoc2hhcGUgPT09IHVuZGVmaW5lZCkge1xuICAgIHNoYXBlID0gWyBkYXRhLmxlbmd0aCBdXG4gIH1cbiAgdmFyIGQgPSBzaGFwZS5sZW5ndGhcbiAgaWYoc3RyaWRlID09PSB1bmRlZmluZWQpIHtcbiAgICBzdHJpZGUgPSBuZXcgQXJyYXkoZClcbiAgICBmb3IodmFyIGk9ZC0xLCBzej0xOyBpPj0wOyAtLWkpIHtcbiAgICAgIHN0cmlkZVtpXSA9IHN6XG4gICAgICBzeiAqPSBzaGFwZVtpXVxuICAgIH1cbiAgfVxuICBpZihvZmZzZXQgPT09IHVuZGVmaW5lZCkge1xuICAgIG9mZnNldCA9IDBcbiAgICBmb3IodmFyIGk9MDsgaTxkOyArK2kpIHtcbiAgICAgIGlmKHN0cmlkZVtpXSA8IDApIHtcbiAgICAgICAgb2Zmc2V0IC09IChzaGFwZVtpXS0xKSpzdHJpZGVbaV1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgdmFyIGR0eXBlID0gYXJyYXlEVHlwZShkYXRhKVxuICB2YXIgY3Rvcl9saXN0ID0gQ0FDSEVEX0NPTlNUUlVDVE9SU1tkdHlwZV1cbiAgd2hpbGUoY3Rvcl9saXN0Lmxlbmd0aCA8PSBkKzEpIHtcbiAgICBjdG9yX2xpc3QucHVzaChjb21waWxlQ29uc3RydWN0b3IoZHR5cGUsIGN0b3JfbGlzdC5sZW5ndGgtMSkpXG4gIH1cbiAgdmFyIGN0b3IgPSBjdG9yX2xpc3RbZCsxXVxuICByZXR1cm4gY3RvcihkYXRhLCBzaGFwZSwgc3RyaWRlLCBvZmZzZXQpXG59XG5cbm1vZHVsZS5leHBvcnRzID0gd3JhcHBlZE5EQXJyYXlDdG9yXG4iXX0=