static/js/terrain/terrain3.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 isEven = exports.isEven = function isEven(n) {
    return 0 == n % 2;
};
var isOdd = exports.isOdd = function isOdd(n) {
    return 1 == n % 2;
};
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 dsInitCorners = exports.dsInitCorners = function dsInitCorners(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 dsSquare = exports.dsSquare = function dsSquare(heightmap, x, y, radius, spread) {
    return function () {
        var newHeightø1 = jitter(average4(heightmapGet(heightmap, x - radius, y - radius), heightmapGet(heightmap, x - radius, y + radius), heightmapGet(heightmap, x + radius, y - radius), heightmapGet(heightmap, x + radius, y + radius)), spread);
        return heightmapSet(heightmap, x, y, newHeightø1);
    }.call(this);
};
var dsDiamond = exports.dsDiamond = function dsDiamond(heightmap, x, y, radius, spread) {
    return function () {
        var newHeightø1 = jitter(safeAverage(heightmapGetSafe(heightmap, x - radius, y), heightmapGetSafe(heightmap, x + radius, y), heightmapGetSafe(heightmap, x, y - radius), heightmapGetSafe(heightmap, x, y + radius)), spread);
        return heightmapSet(heightmap, x, y, newHeightø1);
    }.call(this);
};
var dsSquares = exports.dsSquares = function dsSquares(heightmap, radius, spread) {
    return function () {
        var start8ø1 = radius;
        var end9ø1 = heightmapResolution(heightmap);
        var stride7ø1 = 2 * radius;
        return function loop() {
            var recur = loop;
            var xø1 = start8ø1;
            do {
                recur = xø1 < end9ø1 ? (function () {
                    (function loop() {
                        var recur = loop;
                        var yø1 = start8ø1;
                        do {
                            recur = yø1 < end9ø1 ? (function () {
                                (function () {
                                    return dsSquare(heightmap, xø1, yø1, radius, spread);
                                })();
                                return loop[0] = yø1 + stride7ø1, loop;
                            })() : void 0;
                        } while (yø1 = loop[0], recur === loop);
                        return recur;
                    }.call(this));
                    return loop[0] = xø1 + stride7ø1, loop;
                })() : void 0;
            } while (xø1 = loop[0], recur === loop);
            return recur;
        }.call(this);
    }.call(this);
};
var dsDiamonds = exports.dsDiamonds = function dsDiamonds(heightmap, radius, spread) {
    return function () {
        var sizeø1 = heightmapResolution(heightmap);
        return function () {
            var start11ø1 = 0;
            var end12ø1 = sizeø1;
            var stride10ø1 = radius;
            return function loop() {
                var recur = loop;
                var yø1 = start11ø1;
                do {
                    recur = yø1 < end12ø1 ? (function () {
                        (function () {
                            return function () {
                                var shiftø1 = isEven(yø1 / radius) ? radius : 0;
                                return function () {
                                    var start14ø1 = shiftø1;
                                    var end15ø1 = sizeø1;
                                    var stride13ø1 = 2 * radius;
                                    return function loop() {
                                        var recur = loop;
                                        var xø1 = start14ø1;
                                        do {
                                            recur = xø1 < end15ø1 ? (function () {
                                                (function () {
                                                    return dsDiamond(heightmap, xø1, yø1, radius, spread);
                                                })();
                                                return loop[0] = xø1 + stride13ø1, loop;
                                            })() : void 0;
                                        } while (xø1 = loop[0], recur === loop);
                                        return recur;
                                    }.call(this);
                                }.call(this);
                            }.call(this);
                        })();
                        return loop[0] = yø1 + stride10ø1, loop;
                    })() : void 0;
                } while (yø1 = loop[0], recur === loop);
                return recur;
            }.call(this);
        }.call(this);
    }.call(this);
};
var diamondSquare = exports.diamondSquare = function diamondSquare(heightmap) {
    return function () {
        var initialSpreadø1 = 0.3;
        var spreadReductionø1 = 0.5;
        var centerø1 = heightmapCenterIndex(heightmap);
        var sizeø1 = heightmap.shape[0];
        dsInitCorners(heightmap);
        (function loop() {
            var recur = loop;
            var radiusø1 = centerø1;
            var spreadø1 = initialSpreadø1;
            do {
                recur = radiusø1 >= 1 ? (function () {
                    dsSquares(heightmap, radiusø1, spreadø1);
                    dsDiamonds(heightmap, radiusø1, spreadø1);
                    return loop[0] = radiusø1 / 2, loop[1] = spreadø1 * spreadReductionø1, loop;
                })() : void 0;
            } while (radiusø1 = loop[0], spreadø1 = loop[1], recur === loop);
            return recur;
        }.call(this));
        return normalize(heightmap);
    }.call(this);
};
var diamondSquare1 = exports.diamondSquare1 = function diamondSquare1(heightmap) {
    dsInitCorners(heightmap);
    return normalize(heightmap);
};
var diamondSquare2 = exports.diamondSquare2 = function diamondSquare2(heightmap) {
    return function () {
        var initialSpreadø1 = 0.3;
        var spreadReductionø1 = 0.5;
        var centerø1 = heightmapCenterIndex(heightmap);
        var sizeø1 = heightmap.shape[0];
        dsInitCorners(heightmap);
        dsSquares(heightmap, centerø1, initialSpreadø1);
        return normalize(heightmap);
    }.call(this);
};
var diamondSquare3 = exports.diamondSquare3 = function diamondSquare3(heightmap) {
    return function () {
        var initialSpreadø1 = 0.3;
        var spreadReductionø1 = 0.5;
        var centerø1 = heightmapCenterIndex(heightmap);
        var sizeø1 = heightmap.shape[0];
        dsInitCorners(heightmap);
        dsSquares(heightmap, centerø1, initialSpreadø1);
        dsDiamonds(heightmap, centerø1, initialSpreadø1);
        dsSquares(heightmap, centerø1 / 2, spreadReductionø1 * initialSpreadø1);
        dsDiamonds(heightmap, centerø1 / 2, spreadReductionø1 * initialSpreadø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 makeDemo = exports.makeDemo = function makeDemo(elementId, algorithm, size) {
    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(size);
            console.log('Generating terrain...');
            (function () {
                var G__16ø1 = new Date().getTime();
                var G__18ø1 = (function () {
                    return algorithm(heightmapø1);
                })();
                var G__17ø1 = new Date().getTime();
                console.log('Elapsed time: ' + (G__17ø1 - G__16ø1) + 'ms.');
                return G__18ø1;
            }.call(this));
            console.log('Rebuilding geometry...');
            (function () {
                var G__19ø1 = new Date().getTime();
                var G__21ø1 = (function () {
                    geometry = makeGeometry(heightmapø1);
                    return updateGeometry(geometry, heightmapø1);
                })();
                var G__20ø1 = new Date().getTime();
                console.log('Elapsed time: ' + (G__20ø1 - G__19ø1) + 'ms.');
                return G__21ø1;
            }.call(this));
            console.log('Rebuilding plane...');
            return function () {
                var G__22ø1 = new Date().getTime();
                var G__24ø1 = (function () {
                    scene.remove(plane);
                    plane = makePlane(geometry);
                    return scene.add(plane);
                })();
                var G__23ø1 = new Date().getTime();
                console.log('Elapsed time: ' + (G__23ø1 - G__22ø1) + 'ms.');
                return G__24ø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 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__25ø1 = new Date().getTime();
                var G__27ø1 = (function () {
                    return diamondSquare(heightmapø1);
                })();
                var G__26ø1 = new Date().getTime();
                console.log('Elapsed time: ' + (G__26ø1 - G__25ø1) + 'ms.');
                return G__27ø1;
            }.call(this));
            console.log('Rebuilding geometry...');
            (function () {
                var G__28ø1 = new Date().getTime();
                var G__30ø1 = (function () {
                    geometry = makeGeometry(heightmapø1);
                    return updateGeometry(geometry, heightmapø1);
                })();
                var G__29ø1 = new Date().getTime();
                console.log('Elapsed time: ' + (G__29ø1 - G__28ø1) + 'ms.');
                return G__30ø1;
            }.call(this));
            console.log('Rebuilding plane...');
            return function () {
                var G__31ø1 = new Date().getTime();
                var G__33ø1 = (function () {
                    scene.remove(plane);
                    plane = makePlane(geometry);
                    return scene.add(plane);
                })();
                var G__32ø1 = new Date().getTime();
                console.log('Elapsed time: ' + (G__32ø1 - G__31ø1) + 'ms.');
                return G__33ø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() {
    makeDemo('demo-1', diamondSquare1, 2);
    makeDemo('demo-2', diamondSquare2, 4);
    makeDemo('demo-3', diamondSquare3, 4);
    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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Vzci9sb2NhbC9saWIvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIm1lZGlhL2pzL3dpc3AvYW5vbnltb3VzLndpc3AiLCJub2RlX21vZHVsZXMvaW90YS1hcnJheS9pb3RhLmpzIiwibm9kZV9tb2R1bGVzL2lzLWJ1ZmZlci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9uZGFycmF5L25kYXJyYXkuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0lDQUEsSUFBQyxJLEdBQUQ7QUFBQSxRQUFBLEUsRUFBSSxNQUFKO0FBQUEsUUFBQSxHLEVBQUEsSyxDQUFBO0FBQUEsTTs7O0FBS0EsSUFBSyxLQUFBLEdBQUEsT0FBQSxDQUFBLEtBQUEsR0FBTSxHQUFYLEM7QUFDQSxJQUFLLE1BQUEsR0FBQSxPQUFBLENBQUEsTUFBQSxHQUFPLEdBQVosQztBQUNBLElBQUssU0FBQSxHQUFBLE9BQUEsQ0FBQSxTQUFBLEcsSUFBTCxDO0FBQ0EsSUFBSyxjQUFBLEdBQUEsT0FBQSxDQUFBLGNBQUEsR0FBZ0IsR0FBckIsQztBQUNBLElBQUssYUFBQSxHQUFBLE9BQUEsQ0FBQSxhQUFBLEdBQWUsRUFBcEIsQztBQUNBLElBQUssV0FBQSxHQUFBLE9BQUEsQ0FBQSxXQUFBLEdBQWEsR0FBbEIsQzs7OztBQW9CQSxJQUFNLEdBQUEsR0FBQSxPQUFBLENBQUEsR0FBQSxHQUFOLFNBQU0sR0FBTixDQUFXLENBQVgsRUFDRTtBQUFBLFdBQUcsQ0FBSCxHQUFLLENBQUw7QUFBQSxDQURGLEM7QUFHQSxJQUFNLEdBQUEsR0FBQSxPQUFBLENBQUEsR0FBQSxHQUFOLFNBQU0sR0FBTixDQUFXLENBQVgsRUFDRTtBQUFBLFdBQUcsQ0FBSCxHQUFLLENBQUw7QUFBQSxDQURGLEM7Ozs7Ozs7OztBQXdFQSxJQUFNLFFBQUEsR0FBQSxPQUFBLENBQUEsUUFBQSxHQUFOLFNBQU0sUUFBTixD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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIihucyBkZW1vXG4gICg6cmVxdWlyZSBbbmRhcnJheV0pKVxuXG5cbjsgQ29uc3RhbnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWYgd2lkdGggNjEwKVxuKGRlZiBoZWlnaHQgNDAwKVxuKGRlZiB3aXJlZnJhbWUgdHJ1ZSlcbihkZWYgd2lyZWZyYW1lLXdpZHRoIDEuMilcbihkZWYgdGVycmFpbi1oZWlnaHQgNTApXG4oZGVmIHRlcnJhaW4tc2l6ZSAxMDApXG5cbjsgR2VuZXJhbCBVdGlsaXRpZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZtYWNybyB3aGVuIFtjb25kaXRpb24gJiBib2R5XVxuICBgKGlmIH5jb25kaXRpb25cbiAgICAgKGRvIH5AYm9keSkpKVxuXG4oZGVmbWFjcm8gd2hlbi1ub3QgW2NvbmRpdGlvbiAmIGJvZHldXG4gIGAod2hlbiAobm90IH5jb25kaXRpb24pXG4gICAgIH5AYm9keSkpXG5cbihkZWZtYWNybyAtPiBbJiBvcGVyYXRpb25zXVxuICAocmVkdWNlXG4gICAgKGZuIFtmb3JtIG9wZXJhdGlvbl1cbiAgICAgIChjb25zIChmaXJzdCBvcGVyYXRpb24pXG4gICAgICAgICAgICAoY29ucyBmb3JtIChyZXN0IG9wZXJhdGlvbikpKSlcbiAgICAoZmlyc3Qgb3BlcmF0aW9ucylcbiAgICAocmVzdCBvcGVyYXRpb25zKSkpXG5cblxuKGRlZm4gaW5jIFt4XVxuICAoKyB4IDEpKVxuXG4oZGVmbiBkZWMgW3hdXG4gICgtIHggMSkpXG5cblxuKGRlZm1hY3JvIGRvLXRpbWVzIFt2YXJuYW1lIGxpbWl0ICYgYm9keV1cbiAgKGxldCBbZW5kIChnZW5zeW0pXVxuICAgIGAobGV0IFt+ZW5kIH5saW1pdF1cbiAgICAgICAobG9vcCBbfnZhcm5hbWUgMF1cbiAgICAgICAgICh3aGVuICg8IH52YXJuYW1lIH5lbmQpXG4gICAgICAgICAgIH5AYm9keVxuICAgICAgICAgICAocmVjdXIgKGluYyB+dmFybmFtZSkpKSkpKSlcblxuKGRlZm1hY3JvIGRvLXN0cmlkZSBbdmFybmFtZXMgc3RhcnQtZm9ybSBlbmQtZm9ybSBzdHJpZGUtZm9ybSAmIGJvZHldXG4gIChsZXQgW3N0cmlkZSAoZ2Vuc3ltIFwic3RyaWRlXCIpXG4gICAgICAgIHN0YXJ0IChnZW5zeW0gXCJzdGFydFwiKVxuICAgICAgICBlbmQgKGdlbnN5bSBcImVuZFwiKVxuICAgICAgICBidWlsZCAoZm4gYnVpbGQgW3ZhcnNdXG4gICAgICAgICAgICAgICAgKGlmIChlbXB0eT8gdmFycylcbiAgICAgICAgICAgICAgICAgIGAoZG8gfkBib2R5KVxuICAgICAgICAgICAgICAgICAgKGxldCBbdmFybmFtZSAoZmlyc3QgdmFycyldXG4gICAgICAgICAgICAgICAgICAgIGAobG9vcCBbfnZhcm5hbWUgfnN0YXJ0XVxuICAgICAgICAgICAgICAgICAgICAgICAod2hlbiAoPCB+dmFybmFtZSB+ZW5kKVxuICAgICAgICAgICAgICAgICAgICAgICAgIH4oYnVpbGQgKHJlc3QgdmFycykpXG4gICAgICAgICAgICAgICAgICAgICAgICAgKHJlY3VyICgrIH52YXJuYW1lIH5zdHJpZGUpKSkpKSkpXVxuICAgIDsgRml4IHRoZSBudW1iZXJzIG9uY2Ugb3V0c2lkZSB0aGUgbmVzdGVkIGxvb3BzLFxuICAgIDsgYW5kIHRoZW4gYnVpbGQgdGhlIGd1dHMuXG4gICAgYChsZXQgW35zdGFydCB+c3RhcnQtZm9ybVxuICAgICAgICAgICB+ZW5kIH5lbmQtZm9ybVxuICAgICAgICAgICB+c3RyaWRlIH5zdHJpZGUtZm9ybV1cbiAgICAgICB+KGJ1aWxkIHZhcm5hbWVzKSkpKVxuXG5cbihkZWZtYWNybyBkby1uZGFycmF5IFt2YXJzIGFycmF5LWZvcm0gJiBib2R5XVxuICAobGV0IFthcnJheS12YXIgKGdlbnN5bSBcImFycmF5XCIpXG4gICAgICAgIGJ1aWxkIChmbiBidWlsZCBbdmFycyBuXVxuICAgICAgICAgICAgICAgIChpZiAoZW1wdHk/IHZhcnMpXG4gICAgICAgICAgICAgICAgICBgKGRvIH5AYm9keSlcbiAgICAgICAgICAgICAgICAgIGAoZG8tdGltZXMgfihmaXJzdCB2YXJzKSAoYWdldCAoLi1zaGFwZSB+YXJyYXktdmFyKSB+bilcbiAgICAgICAgICAgICAgICAgICAgIH4oYnVpbGQgKHJlc3QgdmFycykgKGluYyBuKSkpKSldXG4gICAgYChsZXQgW35hcnJheS12YXIgfmFycmF5LWZvcm1dXG4gICAgICAgfihidWlsZCB2YXJzIDApKSkpXG5cbihkZWZtYWNybyBkby1uZGFycmF5LWVsIFtlbGVtZW50IGFycmF5LWZvcm0gJiBib2R5XVxuICAobGV0IFtpbmRleCAoZ2Vuc3ltIFwiaW5kZXhcIilcbiAgICAgICAgYXJyYXkgKGdlbnN5bSBcImFycmF5XCIpXVxuICAgIGAobGV0IFt+YXJyYXkgfmFycmF5LWZvcm1dXG4gICAgICAgKGRvLXRpbWVzIH5pbmRleCAoLi1sZW5ndGggKC4tZGF0YSB+YXJyYXkpKVxuICAgICAgICAgKGxldCBbfmVsZW1lbnQgKGFnZXQgKC4tZGF0YSB+YXJyYXkpIH5pbmRleCldXG4gICAgICAgICAgIH5AYm9keSkpKSkpXG5cblxuKGRlZm1hY3JvIGluYyEgW3BsYWNlXVxuICBgKHNldCEgfnBsYWNlIChpbmMgfnBsYWNlKSkpXG5cbihkZWZtYWNybyBhZGQhIFtwbGFjZSBhbW91bnRdXG4gIGAoc2V0ISB+cGxhY2UgKCsgfnBsYWNlIH5hbW91bnQpKSlcblxuXG4oZGVmbWFjcm8gbCBbJiBmb3Jtc11cbiAgYChjb25zb2xlLmxvZyB+QGZvcm1zKSlcblxuKGRlZm1hY3JvIHRpbWUgWyYgYm9keV1cbiAgKGxldCBbc3RhcnQgKGdlbnN5bSlcbiAgICAgICAgZW5kIChnZW5zeW0pXG4gICAgICAgIHJlc3VsdCAoZ2Vuc3ltKV1cbiAgICBgKGxldCBbfnN0YXJ0ICguZ2V0VGltZSAobmV3IERhdGUpKVxuICAgICAgICAgICB+cmVzdWx0IChkbyB+QGJvZHkpXG4gICAgICAgICAgIH5lbmQgKC5nZXRUaW1lIChuZXcgRGF0ZSkpXVxuICAgICAgIChsICgrIFwiRWxhcHNlZCB0aW1lOiBcIiAoLSB+ZW5kIH5zdGFydCkgXCJtcy5cIikpXG4gICAgICAgfnJlc3VsdCkpKVxuXG5cbihkZWZuIG1pZHBvaW50IFthIGJdXG4gICgvICgrIGEgYikgMikpXG5cbihkZWZuIGF2ZXJhZ2UyIFthIGJdXG4gICgvICgrIGEgYikgMikpXG5cbihkZWZuIGF2ZXJhZ2U0IFthIGIgYyBkXVxuICAoLyAoKyBhIGIgYyBkKSA0KSlcblxuKGRlZm4gc2FmZS1hdmVyYWdlIFthIGIgYyBkXVxuICAobGV0IFt0b3RhbCAwIGNvdW50IDBdXG4gICAgKHdoZW4gYSAoYWRkISB0b3RhbCBhKSAoaW5jISBjb3VudCkpXG4gICAgKHdoZW4gYiAoYWRkISB0b3RhbCBiKSAoaW5jISBjb3VudCkpXG4gICAgKHdoZW4gYyAoYWRkISB0b3RhbCBjKSAoaW5jISBjb3VudCkpXG4gICAgKHdoZW4gZCAoYWRkISB0b3RhbCBkKSAoaW5jISBjb3VudCkpXG4gICAgKC8gdG90YWwgY291bnQpKSlcblxuXG4oZGVmbiBldmVuPyBbbl1cbiAgKD09IDAgKG1vZCBuIDIpKSlcblxuKGRlZm4gb2RkPyBbbl1cbiAgKD09IDEgKG1vZCBuIDIpKSlcblxuXG47IFJhbmRvbW5lc3MgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbiByYW5kIFtdXG4gIChNYXRoLnJhbmRvbSkpXG5cbihkZWZuIHJhbmQtYXJvdW5kLXplcm8gW3NwcmVhZF1cbiAgKC0gKCogc3ByZWFkIChyYW5kKSAyKSBzcHJlYWQpKVxuXG4oZGVmbiBqaXR0ZXIgW3ZhbHVlIHNwcmVhZF1cbiAgKCsgdmFsdWUgKHJhbmQtYXJvdW5kLXplcm8gc3ByZWFkKSkpXG5cblxuOyBIZWlnaHRtYXAgSGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZm4gaGVpZ2h0bWFwLXJlc29sdXRpb24gW2hlaWdodG1hcF1cbiAgKGFnZXQgaGVpZ2h0bWFwLnNoYXBlIDApKVxuXG4oZGVmbiBoZWlnaHRtYXAtbGFzdC1pbmRleCBbaGVpZ2h0bWFwXVxuICAoZGVjIChoZWlnaHRtYXAtcmVzb2x1dGlvbiBoZWlnaHRtYXApKSlcblxuKGRlZm4gaGVpZ2h0bWFwLWNlbnRlci1pbmRleCBbaGVpZ2h0bWFwXVxuICAobWlkcG9pbnQgMCAoaGVpZ2h0bWFwLWxhc3QtaW5kZXggaGVpZ2h0bWFwKSkpXG5cblxuKGRlZm4gaGVpZ2h0bWFwLWdldCBbaGVpZ2h0bWFwIHggeV1cbiAgKC5nZXQgaGVpZ2h0bWFwIHggeSkpXG5cbihkZWZuIGhlaWdodG1hcC1nZXQtc2FmZSBbaGVpZ2h0bWFwIHggeV1cbiAgKGxldCBbbGFzdCAoaGVpZ2h0bWFwLWxhc3QtaW5kZXggaGVpZ2h0bWFwKV1cbiAgICAod2hlbiAoYW5kICg8PSAwIHggbGFzdClcbiAgICAgICAgICAgICAgICg8PSAwIHkgbGFzdCkpXG4gICAgICAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgeCB5KSkpKVxuXG4oZGVmbiBoZWlnaHRtYXAtc2V0ISBbaGVpZ2h0bWFwIHggeSB2YWxdXG4gICguc2V0IGhlaWdodG1hcCB4IHkgdmFsKSlcblxuKGRlZm4gaGVpZ2h0bWFwLXNldC1pZi11bnNldCEgW2hlaWdodG1hcCB4IHkgdmFsXVxuICAod2hlbiAoPT0gMCAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgeCB5KSlcbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIHggeSB2YWwpKSlcblxuXG4oZGVmbiBub3JtYWxpemUgW2hlaWdodG1hcF1cbiAgKGxldCBbbWF4ICgtIEluZmluaXR5KVxuICAgICAgICBtaW4gSW5maW5pdHldXG4gICAgKGRvLW5kYXJyYXktZWwgZWwgaGVpZ2h0bWFwXG4gICAgICAod2hlbiAoPCBtYXggZWwpIChzZXQhIG1heCBlbCkpXG4gICAgICAod2hlbiAoPiBtaW4gZWwpIChzZXQhIG1pbiBlbCkpKVxuICAgIChsZXQgW3NwYW4gKC0gbWF4IG1pbildXG4gICAgICAoZG8tbmRhcnJheSBbeCB5XSBoZWlnaHRtYXBcbiAgICAgICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCB4IHlcbiAgICAgICAgICAgICAgICAgICAgICAgICgvICgtIChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCB4IHkpIG1pbilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW4pKSkpKSlcblxuXG4oZGVmbiBtYWtlLWhlaWdodG1hcCBbZXhwb25lbnRdXG4gIChsZXQgW3Jlc29sdXRpb24gKCsgKE1hdGgucG93IDIgZXhwb25lbnQpIDEpXVxuICAgIChsZXQgW2hlaWdodG1hcCAobmRhcnJheSAobmV3IEZsb2F0NjRBcnJheSAoKiByZXNvbHV0aW9uIHJlc29sdXRpb24pKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcmVzb2x1dGlvbiByZXNvbHV0aW9uXSldXG4gICAgICAoc2V0ISBoZWlnaHRtYXAuZXhwb25lbnQgZXhwb25lbnQpXG4gICAgICAoc2V0ISBoZWlnaHRtYXAucmVzb2x1dGlvbiByZXNvbHV0aW9uKVxuICAgICAgKHNldCEgaGVpZ2h0bWFwLmxhc3QgKGRlYyByZXNvbHV0aW9uKSlcbiAgICAgIGhlaWdodG1hcCkpKVxuXG5cbihkZWZuIHRvcC1sZWZ0LWNvcm5lciBbaGVpZ2h0bWFwXVxuICAobGV0IFtjZW50ZXIgKGhlaWdodG1hcC1jZW50ZXItaW5kZXggaGVpZ2h0bWFwKV1cbiAgICAoLT4gaGVpZ2h0bWFwXG4gICAgICAoLmxvIDAgMClcbiAgICAgICguaGkgKGluYyBjZW50ZXIpIChpbmMgY2VudGVyKSkpKSlcblxuKGRlZm4gdG9wLXJpZ2h0LWNvcm5lciBbaGVpZ2h0bWFwXVxuICAobGV0IFtjZW50ZXIgKGhlaWdodG1hcC1jZW50ZXItaW5kZXggaGVpZ2h0bWFwKV1cbiAgICAoLT4gaGVpZ2h0bWFwXG4gICAgICAoLmxvIGNlbnRlciAwKVxuICAgICAgKC5oaSAoaW5jIGNlbnRlcikgKGluYyBjZW50ZXIpKSkpKVxuXG4oZGVmbiBib3R0b20tbGVmdC1jb3JuZXIgW2hlaWdodG1hcF1cbiAgKGxldCBbY2VudGVyIChoZWlnaHRtYXAtY2VudGVyLWluZGV4IGhlaWdodG1hcCldXG4gICAgKC0+IGhlaWdodG1hcFxuICAgICAgKC5sbyAwIGNlbnRlcilcbiAgICAgICguaGkgKGluYyBjZW50ZXIpIChpbmMgY2VudGVyKSkpKSlcblxuKGRlZm4gYm90dG9tLXJpZ2h0LWNvcm5lciBbaGVpZ2h0bWFwXVxuICAobGV0IFtjZW50ZXIgKGhlaWdodG1hcC1jZW50ZXItaW5kZXggaGVpZ2h0bWFwKV1cbiAgICAoLT4gaGVpZ2h0bWFwXG4gICAgICAoLmxvIGNlbnRlciBjZW50ZXIpXG4gICAgICAoLmhpIChpbmMgY2VudGVyKSAoaW5jIGNlbnRlcikpKSkpXG5cblxuOyBEaWFtb25kLVNxdWFyZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuKGRlZm4gZHMtaW5pdC1jb3JuZXJzIFtoZWlnaHRtYXBdXG4gIChsZXQgW2xhc3QgKGhlaWdodG1hcC1sYXN0LWluZGV4IGhlaWdodG1hcCldXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCAwICAgIDAgICAgKHJhbmQpKVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgMCAgICBsYXN0IChyYW5kKSlcbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIGxhc3QgMCAgICAocmFuZCkpXG4gICAgKGhlaWdodG1hcC1zZXQhIGhlaWdodG1hcCBsYXN0IGxhc3QgKHJhbmQpKSkpXG5cbihkZWZuIGRzLXNxdWFyZSBbaGVpZ2h0bWFwIHggeSByYWRpdXMgc3ByZWFkXVxuICAobGV0IFtuZXctaGVpZ2h0IChqaXR0ZXJcbiAgICAgICAgICAgICAgICAgICAgIChhdmVyYWdlNFxuICAgICAgICAgICAgICAgICAgICAgICAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgKC0geCByYWRpdXMpICgtIHkgcmFkaXVzKSlcbiAgICAgICAgICAgICAgICAgICAgICAgKGhlaWdodG1hcC1nZXQgaGVpZ2h0bWFwICgtIHggcmFkaXVzKSAoKyB5IHJhZGl1cykpXG4gICAgICAgICAgICAgICAgICAgICAgIChoZWlnaHRtYXAtZ2V0IGhlaWdodG1hcCAoKyB4IHJhZGl1cykgKC0geSByYWRpdXMpKVxuICAgICAgICAgICAgICAgICAgICAgICAoaGVpZ2h0bWFwLWdldCBoZWlnaHRtYXAgKCsgeCByYWRpdXMpICgrIHkgcmFkaXVzKSkpXG4gICAgICAgICAgICAgICAgICAgICBzcHJlYWQpXVxuICAgIChoZWlnaHRtYXAtc2V0ISBoZWlnaHRtYXAgeCB5IG5ldy1oZWlnaHQpKSlcblxuKGRlZm4gZHMtZGlhbW9uZCBbaGVpZ2h0bWFwIHggeSByYWRpdXMgc3ByZWFkXVxuICAobGV0IFtuZXctaGVpZ2h0IChqaXR0ZXJcbiAgICAgICAgICAgICAgICAgICAgIChzYWZlLWF2ZXJhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgKGhlaWdodG1hcC1nZXQtc2FmZSBoZWlnaHRtYXAgKC0geCByYWRpdXMpIHkpXG4gICAgICAgICAgICAgICAgICAgICAgIChoZWlnaHRtYXAtZ2V0LXNhZmUgaGVpZ2h0bWFwICgrIHggcmFkaXVzKSB5KVxuICAgICAgICAgICAgICAgICAgICAgICAoaGVpZ2h0bWFwLWdldC1zYWZlIGhlaWdodG1hcCB4ICgtIHkgcmFkaXVzKSlcbiAgICAgICAgICAgICAgICAgICAgICAgKGhlaWdodG1hcC1nZXQtc2FmZSBoZWlnaHRtYXAgeCAoKyB5IHJhZGl1cykpKVxuICAgICAgICAgICAgICAgICAgICAgc3ByZWFkKV1cbiAgICAoaGVpZ2h0bWFwLXNldCEgaGVpZ2h0bWFwIHggeSBuZXctaGVpZ2h0KSkpXG5cblxuKGRlZm4gZHMtc3F1YXJlcyBbaGVpZ2h0bWFwIHJhZGl1cyBzcHJlYWRdXG4gIChkby1zdHJpZGUgW3ggeV0gcmFkaXVzIChoZWlnaHRtYXAtcmVzb2x1dGlvbiBoZWlnaHRtYXApICgqIDIgcmFkaXVzKVxuICAgIChkcy1zcXVhcmUgaGVpZ2h0bWFwIHggeSByYWRpdXMgc3ByZWFkKSkpXG5cbihkZWZuIGRzLWRpYW1vbmRzIFtoZWlnaHRtYXAgcmFkaXVzIHNwcmVhZF1cbiAgKGxldCBbc2l6ZSAoaGVpZ2h0bWFwLXJlc29sdXRpb24gaGVpZ2h0bWFwKV1cbiAgICAoZG8tc3RyaWRlIFt5XSAwIHNpemUgcmFkaXVzXG4gICAgICAobGV0IFtzaGlmdCAoaWYgKGV2ZW4/ICgvIHkgcmFkaXVzKSkgcmFkaXVzIDApXVxuICAgICAgICAoZG8tc3RyaWRlIFt4XSBzaGlmdCBzaXplICgqIDIgcmFkaXVzKVxuICAgICAgICAgIChkcy1kaWFtb25kIGhlaWdodG1hcCB4IHkgcmFkaXVzIHNwcmVhZCkpKSkpKVxuXG4oZGVmbiBkaWFtb25kLXNxdWFyZSBbaGVpZ2h0bWFwXVxuICAobGV0IFtpbml0aWFsLXNwcmVhZCAwLjNcbiAgICAgICAgc3ByZWFkLXJlZHVjdGlvbiAwLjVcbiAgICAgICAgY2VudGVyIChoZWlnaHRtYXAtY2VudGVyLWluZGV4IGhlaWdodG1hcClcbiAgICAgICAgc2l6ZSAoYWdldCBoZWlnaHRtYXAuc2hhcGUgMCldXG4gICAgKGRzLWluaXQtY29ybmVycyBoZWlnaHRtYXApXG4gICAgKGxvb3AgW3JhZGl1cyBjZW50ZXJcbiAgICAgICAgICAgc3ByZWFkIGluaXRpYWwtc3ByZWFkXVxuICAgICAgKHdoZW4gKD49IHJhZGl1cyAxKVxuICAgICAgICAoZHMtc3F1YXJlcyBoZWlnaHRtYXAgcmFkaXVzIHNwcmVhZClcbiAgICAgICAgKGRzLWRpYW1vbmRzIGhlaWdodG1hcCByYWRpdXMgc3ByZWFkKVxuICAgICAgICAocmVjdXIgKC8gcmFkaXVzIDIpXG4gICAgICAgICAgICAgICAoKiBzcHJlYWQgc3ByZWFkLXJlZHVjdGlvbikpKSlcbiAgICAobm9ybWFsaXplIGhlaWdodG1hcCkpKVxuXG5cbihkZWZuIGRpYW1vbmQtc3F1YXJlLTEgW2hlaWdodG1hcF1cbiAgKGRzLWluaXQtY29ybmVycyBoZWlnaHRtYXApXG4gIChub3JtYWxpemUgaGVpZ2h0bWFwKSlcblxuKGRlZm4gZGlhbW9uZC1zcXVhcmUtMiBbaGVpZ2h0bWFwXVxuICAobGV0IFtpbml0aWFsLXNwcmVhZCAwLjNcbiAgICAgICAgc3ByZWFkLXJlZHVjdGlvbiAwLjVcbiAgICAgICAgY2VudGVyIChoZWlnaHRtYXAtY2VudGVyLWluZGV4IGhlaWdodG1hcClcbiAgICAgICAgc2l6ZSAoYWdldCBoZWlnaHRtYXAuc2hhcGUgMCldXG4gICAgKGRzLWluaXQtY29ybmVycyBoZWlnaHRtYXApXG4gICAgKGRzLXNxdWFyZXMgaGVpZ2h0bWFwIGNlbnRlciBpbml0aWFsLXNwcmVhZClcbiAgICAobm9ybWFsaXplIGhlaWdodG1hcCkpKVxuXG4oZGVmbiBkaWFtb25kLXNxdWFyZS0zIFtoZWlnaHRtYXBdXG4gIChsZXQgW2luaXRpYWwtc3ByZWFkIDAuM1xuICAgICAgICBzcHJlYWQtcmVkdWN0aW9uIDAuNVxuICAgICAgICBjZW50ZXIgKGhlaWdodG1hcC1jZW50ZXItaW5kZXggaGVpZ2h0bWFwKVxuICAgICAgICBzaXplIChhZ2V0IGhlaWdodG1hcC5zaGFwZSAwKV1cbiAgICAoZHMtaW5pdC1jb3JuZXJzIGhlaWdodG1hcClcbiAgICAoZHMtc3F1YXJlcyBoZWlnaHRtYXAgY2VudGVyIGluaXRpYWwtc3ByZWFkKVxuICAgIChkcy1kaWFtb25kcyBoZWlnaHRtYXAgY2VudGVyIGluaXRpYWwtc3ByZWFkKVxuICAgIChkcy1zcXVhcmVzIGhlaWdodG1hcCAoLyBjZW50ZXIgMikgKCogc3ByZWFkLXJlZHVjdGlvbiBpbml0aWFsLXNwcmVhZCkpXG4gICAgKGRzLWRpYW1vbmRzIGhlaWdodG1hcCAoLyBjZW50ZXIgMikgKCogc3ByZWFkLXJlZHVjdGlvbiBpbml0aWFsLXNwcmVhZCkpXG4gICAgKG5vcm1hbGl6ZSBoZWlnaHRtYXApKSlcblxuXG47IFRocmVlLmpzIEhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4oZGVmbiBtYWtlLWRpcmVjdGlvbmFsLWxpZ2h0IFtdXG4gIChsZXQgW2xpZ2h0IChuZXcgVEhSRUUuRGlyZWN0aW9uYWxMaWdodCAweGZmZmZmZiAxKV1cbiAgICAobGlnaHQucG9zaXRpb24uc2V0IDEwMCAwIDE1MClcbiAgICBsaWdodCkpXG5cbihkZWZuIG1ha2UtY2FtZXJhIFtdXG4gIChsZXQgW2NhbWVyYSAobmV3IFRIUkVFLlBlcnNwZWN0aXZlQ2FtZXJhXG4gICAgICAgICAgICAgICAgICAgIDU1LFxuICAgICAgICAgICAgICAgICAgICAoLyB3aWR0aCBoZWlnaHQpXG4gICAgICAgICAgICAgICAgICAgIDAuMSxcbiAgICAgICAgICAgICAgICAgICAgMTAwMCldXG4gICAgKGNhbWVyYS5wb3NpdGlvbi5zZXQgMCAtMTAwIDE1MClcbiAgICBjYW1lcmEpKVxuXG4oZGVmbiBtYWtlLXJlbmRlcmVyIFtdXG4gIChsZXQgW3JlbmRlcmVyIChuZXcgVEhSRUUuV2ViR0xSZW5kZXJlciB7OmFudGlhbGlhcyBmYWxzZX0pXVxuICAgIChyZW5kZXJlci5zZXRDbGVhckNvbG9yIDB4ZmZmZmZmKVxuICAgIChyZW5kZXJlci5zZXRTaXplIHdpZHRoIGhlaWdodClcbiAgICAocmVuZGVyZXIuc2V0UGl4ZWxSYXRpbyAyKVxuICAgIHJlbmRlcmVyKSlcblxuKGRlZm4gbWFrZS1nZW9tZXRyeSBbaGVpZ2h0bWFwXVxuICAobGV0IFtyZXNvbHV0aW9uIChhZ2V0IGhlaWdodG1hcC5zaGFwZSAwKVxuICAgICAgICBnZW9tZXRyeSAobmV3IFRIUkVFLlBsYW5lR2VvbWV0cnlcbiAgICAgICAgICAgICAgICAgICAgICB0ZXJyYWluLXNpemVcbiAgICAgICAgICAgICAgICAgICAgICB0ZXJyYWluLXNpemVcbiAgICAgICAgICAgICAgICAgICAgICAoLSByZXNvbHV0aW9uIDEpXG4gICAgICAgICAgICAgICAgICAgICAgKC0gcmVzb2x1dGlvbiAxKSldXG4gICAgZ2VvbWV0cnkpKVxuXG4oZGVmbiBtYWtlLWNvbnRyb2xzIFtjYW1lcmEgcmVuZGVyZXJdXG4gIChsZXQgW2NvbnRyb2xzIChuZXcgVEhSRUUuVHJhY2tiYWxsQ29udHJvbHMgY2FtZXJhIHJlbmRlcmVyLmRvbUVsZW1lbnQpXVxuICAgIChzZXQhIGNvbnRyb2xzLnJvdGF0ZVNwZWVkIDEuNClcbiAgICAoc2V0ISBjb250cm9scy56b29tU3BlZWQgMC41KVxuICAgIChzZXQhIGNvbnRyb2xzLnN0YXRpY01vdmluZyB0cnVlKVxuICAgIChzZXQhIGNvbnRyb2xzLmR5bmFtaWNEYW1waW5nRmFjdG9yIDAuMylcbiAgICBjb250cm9scykpXG5cbihkZWZuIG1ha2UtcGxhbmUgW2dlb21ldHJ5XVxuICAobGV0IFttYXRlcmlhbCAobmV3IFRIUkVFLk1lc2hMYW1iZXJ0TWF0ZXJpYWxcbiAgICAgICAgICAgICAgICAgICAgICB7OndpcmVmcmFtZSB3aXJlZnJhbWVcbiAgICAgICAgICAgICAgICAgICAgICAgOndpcmVmcmFtZUxpbmV3aWR0aCB3aXJlZnJhbWUtd2lkdGhcbiAgICAgICAgICAgICAgICAgICAgICAgOmNvbG9yIDB4MDBiYjAwfSldXG4gICAgKG5ldyBUSFJFRS5NZXNoIGdlb21ldHJ5IG1hdGVyaWFsKSkpXG5cblxuKGRlZm4gYXR0YWNoLXRvLWRvbSBbcmVuZGVyZXIgZWwtbmFtZSByZWZyZXNoLWZuXVxuICAobGV0IFtjb250YWluZXIgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkIGVsLW5hbWUpXG4gICAgICAgIHNldHRpbmdzIChkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwiZGl2XCIpXG4gICAgICAgIHJlZnJlc2gtYnV0dG9uIChkb2N1bWVudC5jcmVhdGVFbGVtZW50IFwiYnV0dG9uXCIpXG4gICAgICAgIGJ1dHRvbi10ZXh0IChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSBcIlJlZnJlc2hcIilcbiAgICAgICAgY2FuY2VsLXNjcm9sbCAoZm4gW2VdICgucHJldmVudERlZmF1bHQgZSkpXVxuICAgIChzZXQhIHJlZnJlc2gtYnV0dG9uLm9uY2xpY2sgcmVmcmVzaC1mbilcbiAgICAoc2V0ISByZW5kZXJlci5kb21FbGVtZW50Lm9ubW91c2V3aGVlbCBjYW5jZWwtc2Nyb2xsKVxuICAgIChyZW5kZXJlci5kb21FbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIgXCJNb3pNb3VzZVBpeGVsU2Nyb2xsXCIgY2FuY2VsLXNjcm9sbCBmYWxzZSlcbiAgICAoLmFwcGVuZENoaWxkIHJlZnJlc2gtYnV0dG9uIGJ1dHRvbi10ZXh0KVxuICAgICguYXBwZW5kQ2hpbGQgY29udGFpbmVyIHJlbmRlcmVyLmRvbUVsZW1lbnQpXG4gICAgKC5hcHBlbmRDaGlsZCBjb250YWluZXIgc2V0dGluZ3MpXG4gICAgKC5hcHBlbmRDaGlsZCBzZXR0aW5ncyByZWZyZXNoLWJ1dHRvbikpKVxuXG5cbihkZWZuIHVwZGF0ZS1nZW9tZXRyeSBbZ2VvbWV0cnkgaGVpZ2h0bWFwXVxuICAobG9vcCBbaSAwXVxuICAgIChpZiAoPCBpIGdlb21ldHJ5LnZlcnRpY2VzLmxlbmd0aClcbiAgICAgIChkbyAoc2V0ISAoLi16IChhZ2V0IGdlb21ldHJ5LnZlcnRpY2VzIGkpKVxuICAgICAgICAgICAgICAgICgqIHRlcnJhaW4taGVpZ2h0IChhZ2V0ICguLWRhdGEgaGVpZ2h0bWFwKSBpKSkpXG4gICAgICAgIChyZWN1ciAoKyBpIDEpKSkpKVxuICAoZ2VvbWV0cnkuY29tcHV0ZVZlcnRleE5vcm1hbHMpXG4gIGdlb21ldHJ5KVxuXG5cbjsgTWFpbiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbihkZWZuIG1ha2UtZGVtbyBbZWxlbWVudC1pZCBhbGdvcml0aG0gc2l6ZV1cbiAgKGRlZiBzY2VuZSAobmV3IFRIUkVFLlNjZW5lKSlcbiAgKHNjZW5lLmFkZCAobmV3IFRIUkVFLkF4aXNIZWxwZXIgMTAwKSlcblxuICAoZGVmIGNsb2NrIChuZXcgVEhSRUUuQ2xvY2spKVxuICAoZGVmIGNhbWVyYSAobWFrZS1jYW1lcmEpKVxuICAoZGVmIHJlbmRlcmVyIChtYWtlLXJlbmRlcmVyKSlcblxuICAoZGVmIGdlb21ldHJ5KVxuICAoZGVmIHBsYW5lKVxuXG4gIChzY2VuZS5hZGQgKG1ha2UtZGlyZWN0aW9uYWwtbGlnaHQpKVxuICAoc2NlbmUuYWRkIChuZXcgVEhSRUUuQW1iaWVudExpZ2h0IDB4ZmZmZmZmIDAuMDUpKVxuXG4gIChkZWZuIHJlZnJlc2ggW11cbiAgICAobGV0IFtoZWlnaHRtYXAgKG1ha2UtaGVpZ2h0bWFwIHNpemUpXVxuICAgICAgKGwgXCJHZW5lcmF0aW5nIHRlcnJhaW4uLi5cIilcbiAgICAgICh0aW1lIChhbGdvcml0aG0gaGVpZ2h0bWFwKSlcblxuICAgICAgKGwgXCJSZWJ1aWxkaW5nIGdlb21ldHJ5Li4uXCIpXG4gICAgICAodGltZVxuICAgICAgICAoc2V0ISBnZW9tZXRyeSAobWFrZS1nZW9tZXRyeSBoZWlnaHRtYXApKVxuICAgICAgICAodXBkYXRlLWdlb21ldHJ5IGdlb21ldHJ5IGhlaWdodG1hcCkpXG5cbiAgICAgIChsIFwiUmVidWlsZGluZyBwbGFuZS4uLlwiKVxuICAgICAgKHRpbWVcbiAgICAgICAgKHNjZW5lLnJlbW92ZSBwbGFuZSlcbiAgICAgICAgKHNldCEgcGxhbmUgKG1ha2UtcGxhbmUgZ2VvbWV0cnkpKVxuICAgICAgICAoc2NlbmUuYWRkIHBsYW5lKSkpKVxuXG4gIChhdHRhY2gtdG8tZG9tIHJlbmRlcmVyIGVsZW1lbnQtaWQgcmVmcmVzaClcbiAgKGRlZiBjb250cm9scyAobWFrZS1jb250cm9scyBjYW1lcmEgcmVuZGVyZXIpKVxuXG4gIChkZWZuIHJlbmRlciBbXVxuICAgIChsZXQgW2RlbHRhIChjbG9jay5nZXREZWx0YSldXG4gICAgICAocmVxdWVzdEFuaW1hdGlvbkZyYW1lIHJlbmRlcilcbiAgICAgICgudXBkYXRlIGNvbnRyb2xzIGRlbHRhKVxuICAgICAgKHJlbmRlcmVyLnJlbmRlciBzY2VuZSBjYW1lcmEpKSlcblxuICAocmVmcmVzaClcbiAgKHJlbmRlcilcblxuICBuaWwpXG5cbihkZWZuIG1ha2UtZmluYWwgW2VsZW1lbnQtaWRdXG4gIChkZWYgc2NlbmUgKG5ldyBUSFJFRS5TY2VuZSkpXG4gIChzY2VuZS5hZGQgKG5ldyBUSFJFRS5BeGlzSGVscGVyIDEwMCkpXG5cbiAgKGRlZiBjbG9jayAobmV3IFRIUkVFLkNsb2NrKSlcbiAgKGRlZiBjYW1lcmEgKG1ha2UtY2FtZXJhKSlcbiAgKGRlZiByZW5kZXJlciAobWFrZS1yZW5kZXJlcikpXG5cbiAgKGRlZiBnZW9tZXRyeSlcbiAgKGRlZiBwbGFuZSlcblxuICAoc2NlbmUuYWRkIChtYWtlLWRpcmVjdGlvbmFsLWxpZ2h0KSlcbiAgKHNjZW5lLmFkZCAobmV3IFRIUkVFLkFtYmllbnRMaWdodCAweGZmZmZmZiAwLjA1KSlcblxuICAoZGVmbiByZWZyZXNoIFtdXG4gICAgKGxldCBbaGVpZ2h0bWFwIChtYWtlLWhlaWdodG1hcCA2KV1cbiAgICAgIChsIFwiR2VuZXJhdGluZyB0ZXJyYWluLi4uXCIpXG4gICAgICAodGltZSAoZGlhbW9uZC1zcXVhcmUgaGVpZ2h0bWFwKSlcblxuICAgICAgKGwgXCJSZWJ1aWxkaW5nIGdlb21ldHJ5Li4uXCIpXG4gICAgICAodGltZVxuICAgICAgICAoc2V0ISBnZW9tZXRyeSAobWFrZS1nZW9tZXRyeSBoZWlnaHRtYXApKVxuICAgICAgICAodXBkYXRlLWdlb21ldHJ5IGdlb21ldHJ5IGhlaWdodG1hcCkpXG5cbiAgICAgIChsIFwiUmVidWlsZGluZyBwbGFuZS4uLlwiKVxuICAgICAgKHRpbWVcbiAgICAgICAgKHNjZW5lLnJlbW92ZSBwbGFuZSlcbiAgICAgICAgKHNldCEgcGxhbmUgKG1ha2UtcGxhbmUgZ2VvbWV0cnkpKVxuICAgICAgICAoc2NlbmUuYWRkIHBsYW5lKSkpKVxuXG4gIChhdHRhY2gtdG8tZG9tIHJlbmRlcmVyIGVsZW1lbnQtaWQgcmVmcmVzaClcbiAgKGRlZiBjb250cm9scyAobWFrZS1jb250cm9scyBjYW1lcmEgcmVuZGVyZXIpKVxuXG4gIChkZWZuIHJlbmRlciBbXVxuICAgIChsZXQgW2RlbHRhIChjbG9jay5nZXREZWx0YSldXG4gICAgICAocmVxdWVzdEFuaW1hdGlvbkZyYW1lIHJlbmRlcilcbiAgICAgICgudXBkYXRlIGNvbnRyb2xzIGRlbHRhKVxuICAgICAgKHJlbmRlcmVyLnJlbmRlciBzY2VuZSBjYW1lcmEpKSlcblxuICAocmVmcmVzaClcbiAgKHJlbmRlcilcblxuICBuaWwpXG5cbihkZWZuIHJ1biBbXVxuICAobWFrZS1kZW1vIFwiZGVtby0xXCIgZGlhbW9uZC1zcXVhcmUtMSAyKVxuICAobWFrZS1kZW1vIFwiZGVtby0yXCIgZGlhbW9uZC1zcXVhcmUtMiA0KVxuICAobWFrZS1kZW1vIFwiZGVtby0zXCIgZGlhbW9uZC1zcXVhcmUtMyA0KVxuICAobWFrZS1maW5hbCBcImRlbW8tZmluYWxcIikpXG5cbigkIHJ1bilcblxuXG47IHZpbTogbHcrPWRvLXRpbWVzIGx3Kz1kby1uZXN0ZWQgOlxuIiwiXCJ1c2Ugc3RyaWN0XCJcblxuZnVuY3Rpb24gaW90YShuKSB7XG4gIHZhciByZXN1bHQgPSBuZXcgQXJyYXkobilcbiAgZm9yKHZhciBpPTA7IGk8bjsgKytpKSB7XG4gICAgcmVzdWx0W2ldID0gaVxuICB9XG4gIHJldHVybiByZXN1bHRcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpb3RhIiwiLyoqXG4gKiBEZXRlcm1pbmUgaWYgYW4gb2JqZWN0IGlzIEJ1ZmZlclxuICpcbiAqIEF1dGhvcjogICBGZXJvc3MgQWJvdWtoYWRpamVoIDxmZXJvc3NAZmVyb3NzLm9yZz4gPGh0dHA6Ly9mZXJvc3Mub3JnPlxuICogTGljZW5zZTogIE1JVFxuICpcbiAqIGBucG0gaW5zdGFsbCBpcy1idWZmZXJgXG4gKi9cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqKSB7XG4gIHJldHVybiAhIShvYmogIT0gbnVsbCAmJlxuICAgIChvYmouX2lzQnVmZmVyIHx8IC8vIEZvciBTYWZhcmkgNS03IChtaXNzaW5nIE9iamVjdC5wcm90b3R5cGUuY29uc3RydWN0b3IpXG4gICAgICAob2JqLmNvbnN0cnVjdG9yICYmXG4gICAgICB0eXBlb2Ygb2JqLmNvbnN0cnVjdG9yLmlzQnVmZmVyID09PSAnZnVuY3Rpb24nICYmXG4gICAgICBvYmouY29uc3RydWN0b3IuaXNCdWZmZXIob2JqKSlcbiAgICApKVxufVxuIiwidmFyIGlvdGEgPSByZXF1aXJlKFwiaW90YS1hcnJheVwiKVxudmFyIGlzQnVmZmVyID0gcmVxdWlyZShcImlzLWJ1ZmZlclwiKVxuXG52YXIgaGFzVHlwZWRBcnJheXMgID0gKCh0eXBlb2YgRmxvYXQ2NEFycmF5KSAhPT0gXCJ1bmRlZmluZWRcIilcblxuZnVuY3Rpb24gY29tcGFyZTFzdChhLCBiKSB7XG4gIHJldHVybiBhWzBdIC0gYlswXVxufVxuXG5mdW5jdGlvbiBvcmRlcigpIHtcbiAgdmFyIHN0cmlkZSA9IHRoaXMuc3RyaWRlXG4gIHZhciB0ZXJtcyA9IG5ldyBBcnJheShzdHJpZGUubGVuZ3RoKVxuICB2YXIgaVxuICBmb3IoaT0wOyBpPHRlcm1zLmxlbmd0aDsgKytpKSB7XG4gICAgdGVybXNbaV0gPSBbTWF0aC5hYnMoc3RyaWRlW2ldKSwgaV1cbiAgfVxuICB0ZXJtcy5zb3J0KGNvbXBhcmUxc3QpXG4gIHZhciByZXN1bHQgPSBuZXcgQXJyYXkodGVybXMubGVuZ3RoKVxuICBmb3IoaT0wOyBpPHJlc3VsdC5sZW5ndGg7ICsraSkge1xuICAgIHJlc3VsdFtpXSA9IHRlcm1zW2ldWzFdXG4gIH1cbiAgcmV0dXJuIHJlc3VsdFxufVxuXG5mdW5jdGlvbiBjb21waWxlQ29uc3RydWN0b3IoZHR5cGUsIGRpbWVuc2lvbikge1xuICB2YXIgY2xhc3NOYW1lID0gW1wiVmlld1wiLCBkaW1lbnNpb24sIFwiZFwiLCBkdHlwZV0uam9pbihcIlwiKVxuICBpZihkaW1lbnNpb24gPCAwKSB7XG4gICAgY2xhc3NOYW1lID0gXCJWaWV3X05pbFwiICsgZHR5cGVcbiAgfVxuICB2YXIgdXNlR2V0dGVycyA9IChkdHlwZSA9PT0gXCJnZW5lcmljXCIpXG5cbiAgaWYoZGltZW5zaW9uID09PSAtMSkge1xuICAgIC8vU3BlY2lhbCBjYXNlIGZvciB0cml2aWFsIGFycmF5c1xuICAgIHZhciBjb2RlID1cbiAgICAgIFwiZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiKGEpe3RoaXMuZGF0YT1hO307XFxcbnZhciBwcm90bz1cIitjbGFzc05hbWUrXCIucHJvdG90eXBlO1xcXG5wcm90by5kdHlwZT0nXCIrZHR5cGUrXCInO1xcXG5wcm90by5pbmRleD1mdW5jdGlvbigpe3JldHVybiAtMX07XFxcbnByb3RvLnNpemU9MDtcXFxucHJvdG8uZGltZW5zaW9uPS0xO1xcXG5wcm90by5zaGFwZT1wcm90by5zdHJpZGU9cHJvdG8ub3JkZXI9W107XFxcbnByb3RvLmxvPXByb3RvLmhpPXByb3RvLnRyYW5zcG9zZT1wcm90by5zdGVwPVxcXG5mdW5jdGlvbigpe3JldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKHRoaXMuZGF0YSk7fTtcXFxucHJvdG8uZ2V0PXByb3RvLnNldD1mdW5jdGlvbigpe307XFxcbnByb3RvLnBpY2s9ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH07XFxcbnJldHVybiBmdW5jdGlvbiBjb25zdHJ1Y3RfXCIrY2xhc3NOYW1lK1wiKGEpe3JldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKGEpO31cIlxuICAgIHZhciBwcm9jZWR1cmUgPSBuZXcgRnVuY3Rpb24oY29kZSlcbiAgICByZXR1cm4gcHJvY2VkdXJlKClcbiAgfSBlbHNlIGlmKGRpbWVuc2lvbiA9PT0gMCkge1xuICAgIC8vU3BlY2lhbCBjYXNlIGZvciAwZCBhcnJheXNcbiAgICB2YXIgY29kZSA9XG4gICAgICBcImZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIihhLGQpIHtcXFxudGhpcy5kYXRhID0gYTtcXFxudGhpcy5vZmZzZXQgPSBkXFxcbn07XFxcbnZhciBwcm90bz1cIitjbGFzc05hbWUrXCIucHJvdG90eXBlO1xcXG5wcm90by5kdHlwZT0nXCIrZHR5cGUrXCInO1xcXG5wcm90by5pbmRleD1mdW5jdGlvbigpe3JldHVybiB0aGlzLm9mZnNldH07XFxcbnByb3RvLmRpbWVuc2lvbj0wO1xcXG5wcm90by5zaXplPTE7XFxcbnByb3RvLnNoYXBlPVxcXG5wcm90by5zdHJpZGU9XFxcbnByb3RvLm9yZGVyPVtdO1xcXG5wcm90by5sbz1cXFxucHJvdG8uaGk9XFxcbnByb3RvLnRyYW5zcG9zZT1cXFxucHJvdG8uc3RlcD1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfY29weSgpIHtcXFxucmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIodGhpcy5kYXRhLHRoaXMub2Zmc2V0KVxcXG59O1xcXG5wcm90by5waWNrPWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9waWNrKCl7XFxcbnJldHVybiBUcml2aWFsQXJyYXkodGhpcy5kYXRhKTtcXFxufTtcXFxucHJvdG8udmFsdWVPZj1wcm90by5nZXQ9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX2dldCgpe1xcXG5yZXR1cm4gXCIrKHVzZUdldHRlcnMgPyBcInRoaXMuZGF0YS5nZXQodGhpcy5vZmZzZXQpXCIgOiBcInRoaXMuZGF0YVt0aGlzLm9mZnNldF1cIikrXG5cIn07XFxcbnByb3RvLnNldD1mdW5jdGlvbiBcIitjbGFzc05hbWUrXCJfc2V0KHYpe1xcXG5yZXR1cm4gXCIrKHVzZUdldHRlcnMgPyBcInRoaXMuZGF0YS5zZXQodGhpcy5vZmZzZXQsdilcIiA6IFwidGhpcy5kYXRhW3RoaXMub2Zmc2V0XT12XCIpK1wiXFxcbn07XFxcbnJldHVybiBmdW5jdGlvbiBjb25zdHJ1Y3RfXCIrY2xhc3NOYW1lK1wiKGEsYixjLGQpe3JldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKGEsZCl9XCJcbiAgICB2YXIgcHJvY2VkdXJlID0gbmV3IEZ1bmN0aW9uKFwiVHJpdmlhbEFycmF5XCIsIGNvZGUpXG4gICAgcmV0dXJuIHByb2NlZHVyZShDQUNIRURfQ09OU1RSVUNUT1JTW2R0eXBlXVswXSlcbiAgfVxuXG4gIHZhciBjb2RlID0gW1wiJ3VzZSBzdHJpY3QnXCJdXG5cbiAgLy9DcmVhdGUgY29uc3RydWN0b3IgZm9yIHZpZXdcbiAgdmFyIGluZGljZXMgPSBpb3RhKGRpbWVuc2lvbilcbiAgdmFyIGFyZ3MgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7IHJldHVybiBcImlcIitpIH0pXG4gIHZhciBpbmRleF9zdHIgPSBcInRoaXMub2Zmc2V0K1wiICsgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgICByZXR1cm4gXCJ0aGlzLnN0cmlkZVtcIiArIGkgKyBcIl0qaVwiICsgaVxuICAgICAgfSkuam9pbihcIitcIilcbiAgdmFyIHNoYXBlQXJnID0gaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwiYlwiK2lcbiAgICB9KS5qb2luKFwiLFwiKVxuICB2YXIgc3RyaWRlQXJnID0gaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwiY1wiK2lcbiAgICB9KS5qb2luKFwiLFwiKVxuICBjb2RlLnB1c2goXG4gICAgXCJmdW5jdGlvbiBcIitjbGFzc05hbWUrXCIoYSxcIiArIHNoYXBlQXJnICsgXCIsXCIgKyBzdHJpZGVBcmcgKyBcIixkKXt0aGlzLmRhdGE9YVwiLFxuICAgICAgXCJ0aGlzLnNoYXBlPVtcIiArIHNoYXBlQXJnICsgXCJdXCIsXG4gICAgICBcInRoaXMuc3RyaWRlPVtcIiArIHN0cmlkZUFyZyArIFwiXVwiLFxuICAgICAgXCJ0aGlzLm9mZnNldD1kfDB9XCIsXG4gICAgXCJ2YXIgcHJvdG89XCIrY2xhc3NOYW1lK1wiLnByb3RvdHlwZVwiLFxuICAgIFwicHJvdG8uZHR5cGU9J1wiK2R0eXBlK1wiJ1wiLFxuICAgIFwicHJvdG8uZGltZW5zaW9uPVwiK2RpbWVuc2lvbilcblxuICAvL3ZpZXcuc2l6ZTpcbiAgY29kZS5wdXNoKFwiT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb3RvLCdzaXplJyx7Z2V0OmZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9zaXplKCl7XFxcbnJldHVybiBcIitpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7IHJldHVybiBcInRoaXMuc2hhcGVbXCIraStcIl1cIiB9KS5qb2luKFwiKlwiKSxcblwifX0pXCIpXG5cbiAgLy92aWV3Lm9yZGVyOlxuICBpZihkaW1lbnNpb24gPT09IDEpIHtcbiAgICBjb2RlLnB1c2goXCJwcm90by5vcmRlcj1bMF1cIilcbiAgfSBlbHNlIHtcbiAgICBjb2RlLnB1c2goXCJPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvdG8sJ29yZGVyJyx7Z2V0OlwiKVxuICAgIGlmKGRpbWVuc2lvbiA8IDQpIHtcbiAgICAgIGNvZGUucHVzaChcImZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9vcmRlcigpe1wiKVxuICAgICAgaWYoZGltZW5zaW9uID09PSAyKSB7XG4gICAgICAgIGNvZGUucHVzaChcInJldHVybiAoTWF0aC5hYnModGhpcy5zdHJpZGVbMF0pPk1hdGguYWJzKHRoaXMuc3RyaWRlWzFdKSk/WzEsMF06WzAsMV19fSlcIilcbiAgICAgIH0gZWxzZSBpZihkaW1lbnNpb24gPT09IDMpIHtcbiAgICAgICAgY29kZS5wdXNoKFxuXCJ2YXIgczA9TWF0aC5hYnModGhpcy5zdHJpZGVbMF0pLHMxPU1hdGguYWJzKHRoaXMuc3RyaWRlWzFdKSxzMj1NYXRoLmFicyh0aGlzLnN0cmlkZVsyXSk7XFxcbmlmKHMwPnMxKXtcXFxuaWYoczE+czIpe1xcXG5yZXR1cm4gWzIsMSwwXTtcXFxufWVsc2UgaWYoczA+czIpe1xcXG5yZXR1cm4gWzEsMiwwXTtcXFxufWVsc2V7XFxcbnJldHVybiBbMSwwLDJdO1xcXG59XFxcbn1lbHNlIGlmKHMwPnMyKXtcXFxucmV0dXJuIFsyLDAsMV07XFxcbn1lbHNlIGlmKHMyPnMxKXtcXFxucmV0dXJuIFswLDEsMl07XFxcbn1lbHNle1xcXG5yZXR1cm4gWzAsMiwxXTtcXFxufX19KVwiKVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlLnB1c2goXCJPUkRFUn0pXCIpXG4gICAgfVxuICB9XG5cbiAgLy92aWV3LnNldChpMCwgLi4uLCB2KTpcbiAgY29kZS5wdXNoKFxuXCJwcm90by5zZXQ9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX3NldChcIithcmdzLmpvaW4oXCIsXCIpK1wiLHYpe1wiKVxuICBpZih1c2VHZXR0ZXJzKSB7XG4gICAgY29kZS5wdXNoKFwicmV0dXJuIHRoaXMuZGF0YS5zZXQoXCIraW5kZXhfc3RyK1wiLHYpfVwiKVxuICB9IGVsc2Uge1xuICAgIGNvZGUucHVzaChcInJldHVybiB0aGlzLmRhdGFbXCIraW5kZXhfc3RyK1wiXT12fVwiKVxuICB9XG5cbiAgLy92aWV3LmdldChpMCwgLi4uKTpcbiAgY29kZS5wdXNoKFwicHJvdG8uZ2V0PWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9nZXQoXCIrYXJncy5qb2luKFwiLFwiKStcIil7XCIpXG4gIGlmKHVzZUdldHRlcnMpIHtcbiAgICBjb2RlLnB1c2goXCJyZXR1cm4gdGhpcy5kYXRhLmdldChcIitpbmRleF9zdHIrXCIpfVwiKVxuICB9IGVsc2Uge1xuICAgIGNvZGUucHVzaChcInJldHVybiB0aGlzLmRhdGFbXCIraW5kZXhfc3RyK1wiXX1cIilcbiAgfVxuXG4gIC8vdmlldy5pbmRleDpcbiAgY29kZS5wdXNoKFxuICAgIFwicHJvdG8uaW5kZXg9ZnVuY3Rpb24gXCIrY2xhc3NOYW1lK1wiX2luZGV4KFwiLCBhcmdzLmpvaW4oKSwgXCIpe3JldHVybiBcIitpbmRleF9zdHIrXCJ9XCIpXG5cbiAgLy92aWV3LmhpKCk6XG4gIGNvZGUucHVzaChcInByb3RvLmhpPWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9oaShcIithcmdzLmpvaW4oXCIsXCIpK1wiKXtyZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIih0aGlzLmRhdGEsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFtcIih0eXBlb2YgaVwiLGksXCIhPT0nbnVtYmVyJ3x8aVwiLGksXCI8MCk/dGhpcy5zaGFwZVtcIiwgaSwgXCJdOmlcIiwgaSxcInwwXCJdLmpvaW4oXCJcIilcbiAgICB9KS5qb2luKFwiLFwiKStcIixcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJ0aGlzLnN0cmlkZVtcIitpICsgXCJdXCJcbiAgICB9KS5qb2luKFwiLFwiKStcIix0aGlzLm9mZnNldCl9XCIpXG5cbiAgLy92aWV3LmxvKCk6XG4gIHZhciBhX3ZhcnMgPSBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7IHJldHVybiBcImFcIitpK1wiPXRoaXMuc2hhcGVbXCIraStcIl1cIiB9KVxuICB2YXIgY192YXJzID0gaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkgeyByZXR1cm4gXCJjXCIraStcIj10aGlzLnN0cmlkZVtcIitpK1wiXVwiIH0pXG4gIGNvZGUucHVzaChcInByb3RvLmxvPWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9sbyhcIithcmdzLmpvaW4oXCIsXCIpK1wiKXt2YXIgYj10aGlzLm9mZnNldCxkPTAsXCIrYV92YXJzLmpvaW4oXCIsXCIpK1wiLFwiK2NfdmFycy5qb2luKFwiLFwiKSlcbiAgZm9yKHZhciBpPTA7IGk8ZGltZW5zaW9uOyArK2kpIHtcbiAgICBjb2RlLnB1c2goXG5cImlmKHR5cGVvZiBpXCIraStcIj09PSdudW1iZXInJiZpXCIraStcIj49MCl7XFxcbmQ9aVwiK2krXCJ8MDtcXFxuYis9Y1wiK2krXCIqZDtcXFxuYVwiK2krXCItPWR9XCIpXG4gIH1cbiAgY29kZS5wdXNoKFwicmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIodGhpcy5kYXRhLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcImFcIitpXG4gICAgfSkuam9pbihcIixcIikrXCIsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwiY1wiK2lcbiAgICB9KS5qb2luKFwiLFwiKStcIixiKX1cIilcblxuICAvL3ZpZXcuc3RlcCgpOlxuICBjb2RlLnB1c2goXCJwcm90by5zdGVwPWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9zdGVwKFwiK2FyZ3Muam9pbihcIixcIikrXCIpe3ZhciBcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJhXCIraStcIj10aGlzLnNoYXBlW1wiK2krXCJdXCJcbiAgICB9KS5qb2luKFwiLFwiKStcIixcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJiXCIraStcIj10aGlzLnN0cmlkZVtcIitpK1wiXVwiXG4gICAgfSkuam9pbihcIixcIikrXCIsYz10aGlzLm9mZnNldCxkPTAsY2VpbD1NYXRoLmNlaWxcIilcbiAgZm9yKHZhciBpPTA7IGk8ZGltZW5zaW9uOyArK2kpIHtcbiAgICBjb2RlLnB1c2goXG5cImlmKHR5cGVvZiBpXCIraStcIj09PSdudW1iZXInKXtcXFxuZD1pXCIraStcInwwO1xcXG5pZihkPDApe1xcXG5jKz1iXCIraStcIiooYVwiK2krXCItMSk7XFxcbmFcIitpK1wiPWNlaWwoLWFcIitpK1wiL2QpXFxcbn1lbHNle1xcXG5hXCIraStcIj1jZWlsKGFcIitpK1wiL2QpXFxcbn1cXFxuYlwiK2krXCIqPWRcXFxufVwiKVxuICB9XG4gIGNvZGUucHVzaChcInJldHVybiBuZXcgXCIrY2xhc3NOYW1lK1wiKHRoaXMuZGF0YSxcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJhXCIgKyBpXG4gICAgfSkuam9pbihcIixcIikrXCIsXCIrXG4gICAgaW5kaWNlcy5tYXAoZnVuY3Rpb24oaSkge1xuICAgICAgcmV0dXJuIFwiYlwiICsgaVxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLGMpfVwiKVxuXG4gIC8vdmlldy50cmFuc3Bvc2UoKTpcbiAgdmFyIHRTaGFwZSA9IG5ldyBBcnJheShkaW1lbnNpb24pXG4gIHZhciB0U3RyaWRlID0gbmV3IEFycmF5KGRpbWVuc2lvbilcbiAgZm9yKHZhciBpPTA7IGk8ZGltZW5zaW9uOyArK2kpIHtcbiAgICB0U2hhcGVbaV0gPSBcImFbaVwiK2krXCJdXCJcbiAgICB0U3RyaWRlW2ldID0gXCJiW2lcIitpK1wiXVwiXG4gIH1cbiAgY29kZS5wdXNoKFwicHJvdG8udHJhbnNwb3NlPWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl90cmFuc3Bvc2UoXCIrYXJncytcIil7XCIrXG4gICAgYXJncy5tYXAoZnVuY3Rpb24obixpZHgpIHsgcmV0dXJuIG4gKyBcIj0oXCIgKyBuICsgXCI9PT11bmRlZmluZWQ/XCIgKyBpZHggKyBcIjpcIiArIG4gKyBcInwwKVwifSkuam9pbihcIjtcIiksXG4gICAgXCJ2YXIgYT10aGlzLnNoYXBlLGI9dGhpcy5zdHJpZGU7cmV0dXJuIG5ldyBcIitjbGFzc05hbWUrXCIodGhpcy5kYXRhLFwiK3RTaGFwZS5qb2luKFwiLFwiKStcIixcIit0U3RyaWRlLmpvaW4oXCIsXCIpK1wiLHRoaXMub2Zmc2V0KX1cIilcblxuICAvL3ZpZXcucGljaygpOlxuICBjb2RlLnB1c2goXCJwcm90by5waWNrPWZ1bmN0aW9uIFwiK2NsYXNzTmFtZStcIl9waWNrKFwiK2FyZ3MrXCIpe3ZhciBhPVtdLGI9W10sYz10aGlzLm9mZnNldFwiKVxuICBmb3IodmFyIGk9MDsgaTxkaW1lbnNpb247ICsraSkge1xuICAgIGNvZGUucHVzaChcImlmKHR5cGVvZiBpXCIraStcIj09PSdudW1iZXInJiZpXCIraStcIj49MCl7Yz0oYyt0aGlzLnN0cmlkZVtcIitpK1wiXSppXCIraStcIil8MH1lbHNle2EucHVzaCh0aGlzLnNoYXBlW1wiK2krXCJdKTtiLnB1c2godGhpcy5zdHJpZGVbXCIraStcIl0pfVwiKVxuICB9XG4gIGNvZGUucHVzaChcInZhciBjdG9yPUNUT1JfTElTVFthLmxlbmd0aCsxXTtyZXR1cm4gY3Rvcih0aGlzLmRhdGEsYSxiLGMpfVwiKVxuXG4gIC8vQWRkIHJldHVybiBzdGF0ZW1lbnRcbiAgY29kZS5wdXNoKFwicmV0dXJuIGZ1bmN0aW9uIGNvbnN0cnVjdF9cIitjbGFzc05hbWUrXCIoZGF0YSxzaGFwZSxzdHJpZGUsb2Zmc2V0KXtyZXR1cm4gbmV3IFwiK2NsYXNzTmFtZStcIihkYXRhLFwiK1xuICAgIGluZGljZXMubWFwKGZ1bmN0aW9uKGkpIHtcbiAgICAgIHJldHVybiBcInNoYXBlW1wiK2krXCJdXCJcbiAgICB9KS5qb2luKFwiLFwiKStcIixcIitcbiAgICBpbmRpY2VzLm1hcChmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gXCJzdHJpZGVbXCIraStcIl1cIlxuICAgIH0pLmpvaW4oXCIsXCIpK1wiLG9mZnNldCl9XCIpXG5cbiAgLy9Db21waWxlIHByb2NlZHVyZVxuICB2YXIgcHJvY2VkdXJlID0gbmV3IEZ1bmN0aW9uKFwiQ1RPUl9MSVNUXCIsIFwiT1JERVJcIiwgY29kZS5qb2luKFwiXFxuXCIpKVxuICByZXR1cm4gcHJvY2VkdXJlKENBQ0hFRF9DT05TVFJVQ1RPUlNbZHR5cGVdLCBvcmRlcilcbn1cblxuZnVuY3Rpb24gYXJyYXlEVHlwZShkYXRhKSB7XG4gIGlmKGlzQnVmZmVyKGRhdGEpKSB7XG4gICAgcmV0dXJuIFwiYnVmZmVyXCJcbiAgfVxuICBpZihoYXNUeXBlZEFycmF5cykge1xuICAgIHN3aXRjaChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZGF0YSkpIHtcbiAgICAgIGNhc2UgXCJbb2JqZWN0IEZsb2F0NjRBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwiZmxvYXQ2NFwiXG4gICAgICBjYXNlIFwiW29iamVjdCBGbG9hdDMyQXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcImZsb2F0MzJcIlxuICAgICAgY2FzZSBcIltvYmplY3QgSW50OEFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJpbnQ4XCJcbiAgICAgIGNhc2UgXCJbb2JqZWN0IEludDE2QXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcImludDE2XCJcbiAgICAgIGNhc2UgXCJbb2JqZWN0IEludDMyQXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcImludDMyXCJcbiAgICAgIGNhc2UgXCJbb2JqZWN0IFVpbnQ4QXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcInVpbnQ4XCJcbiAgICAgIGNhc2UgXCJbb2JqZWN0IFVpbnQxNkFycmF5XVwiOlxuICAgICAgICByZXR1cm4gXCJ1aW50MTZcIlxuICAgICAgY2FzZSBcIltvYmplY3QgVWludDMyQXJyYXldXCI6XG4gICAgICAgIHJldHVybiBcInVpbnQzMlwiXG4gICAgICBjYXNlIFwiW29iamVjdCBVaW50OENsYW1wZWRBcnJheV1cIjpcbiAgICAgICAgcmV0dXJuIFwidWludDhfY2xhbXBlZFwiXG4gICAgfVxuICB9XG4gIGlmKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICByZXR1cm4gXCJhcnJheVwiXG4gIH1cbiAgcmV0dXJuIFwiZ2VuZXJpY1wiXG59XG5cbnZhciBDQUNIRURfQ09OU1RSVUNUT1JTID0ge1xuICBcImZsb2F0MzJcIjpbXSxcbiAgXCJmbG9hdDY0XCI6W10sXG4gIFwiaW50OFwiOltdLFxuICBcImludDE2XCI6W10sXG4gIFwiaW50MzJcIjpbXSxcbiAgXCJ1aW50OFwiOltdLFxuICBcInVpbnQxNlwiOltdLFxuICBcInVpbnQzMlwiOltdLFxuICBcImFycmF5XCI6W10sXG4gIFwidWludDhfY2xhbXBlZFwiOltdLFxuICBcImJ1ZmZlclwiOltdLFxuICBcImdlbmVyaWNcIjpbXVxufVxuXG47KGZ1bmN0aW9uKCkge1xuICBmb3IodmFyIGlkIGluIENBQ0hFRF9DT05TVFJVQ1RPUlMpIHtcbiAgICBDQUNIRURfQ09OU1RSVUNUT1JTW2lkXS5wdXNoKGNvbXBpbGVDb25zdHJ1Y3RvcihpZCwgLTEpKVxuICB9XG59KTtcblxuZnVuY3Rpb24gd3JhcHBlZE5EQXJyYXlDdG9yKGRhdGEsIHNoYXBlLCBzdHJpZGUsIG9mZnNldCkge1xuICBpZihkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICB2YXIgY3RvciA9IENBQ0hFRF9DT05TVFJVQ1RPUlMuYXJyYXlbMF1cbiAgICByZXR1cm4gY3RvcihbXSlcbiAgfSBlbHNlIGlmKHR5cGVvZiBkYXRhID09PSBcIm51bWJlclwiKSB7XG4gICAgZGF0YSA9IFtkYXRhXVxuICB9XG4gIGlmKHNoYXBlID09PSB1bmRlZmluZWQpIHtcbiAgICBzaGFwZSA9IFsgZGF0YS5sZW5ndGggXVxuICB9XG4gIHZhciBkID0gc2hhcGUubGVuZ3RoXG4gIGlmKHN0cmlkZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgc3RyaWRlID0gbmV3IEFycmF5KGQpXG4gICAgZm9yKHZhciBpPWQtMSwgc3o9MTsgaT49MDsgLS1pKSB7XG4gICAgICBzdHJpZGVbaV0gPSBzelxuICAgICAgc3ogKj0gc2hhcGVbaV1cbiAgICB9XG4gIH1cbiAgaWYob2Zmc2V0ID09PSB1bmRlZmluZWQpIHtcbiAgICBvZmZzZXQgPSAwXG4gICAgZm9yKHZhciBpPTA7IGk8ZDsgKytpKSB7XG4gICAgICBpZihzdHJpZGVbaV0gPCAwKSB7XG4gICAgICAgIG9mZnNldCAtPSAoc2hhcGVbaV0tMSkqc3RyaWRlW2ldXG4gICAgICB9XG4gICAgfVxuICB9XG4gIHZhciBkdHlwZSA9IGFycmF5RFR5cGUoZGF0YSlcbiAgdmFyIGN0b3JfbGlzdCA9IENBQ0hFRF9DT05TVFJVQ1RPUlNbZHR5cGVdXG4gIHdoaWxlKGN0b3JfbGlzdC5sZW5ndGggPD0gZCsxKSB7XG4gICAgY3Rvcl9saXN0LnB1c2goY29tcGlsZUNvbnN0cnVjdG9yKGR0eXBlLCBjdG9yX2xpc3QubGVuZ3RoLTEpKVxuICB9XG4gIHZhciBjdG9yID0gY3Rvcl9saXN0W2QrMV1cbiAgcmV0dXJuIGN0b3IoZGF0YSwgc2hhcGUsIHN0cmlkZSwgb2Zmc2V0KVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHdyYXBwZWROREFycmF5Q3RvclxuIl19