|
<!DOCTYPE html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<script src="https://d3js.org/d3.v3.min.js"></script> |
|
<style> |
|
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } |
|
</style> |
|
</head> |
|
|
|
<body> |
|
<script> |
|
|
|
(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){ |
|
/** |
|
* d3-sankey Copyright Mike Bostock |
|
* |
|
* Source repository: https://github.com/d3/d3-sankey |
|
* |
|
* Minor local modifications: |
|
* - Stable sorting https://github.com/d3/d3-sankey/pull/19 (irrelevant here) |
|
* - Inlining code here so it works with d3 v3.* |
|
* - Replacing the relaxation loop with a rAF |
|
* - Overriding alpha decay and iteration limit check with a half-sine curve |
|
*/ |
|
|
|
// var d3 = require('d3'); |
|
var nest = d3.nest; |
|
var interpolateNumber = d3.interpolateNumber; |
|
var ascending = d3.ascending; |
|
var min = d3.min; |
|
var sum = d3.sum; |
|
|
|
module.exports = function() { |
|
var sankey = {}, |
|
nodeWidth = 24, |
|
nodePadding = 8, |
|
size = [1, 1], |
|
nodes = [], |
|
links = []; |
|
|
|
sankey.nodeWidth = function(_) { |
|
if (!arguments.length) return nodeWidth; |
|
nodeWidth = +_; |
|
return sankey; |
|
}; |
|
|
|
sankey.nodePadding = function(_) { |
|
if (!arguments.length) return nodePadding; |
|
nodePadding = +_; |
|
return sankey; |
|
}; |
|
|
|
sankey.nodes = function(_) { |
|
if (!arguments.length) return nodes; |
|
nodes = _; |
|
return sankey; |
|
}; |
|
|
|
sankey.links = function(_) { |
|
if (!arguments.length) return links; |
|
links = _; |
|
return sankey; |
|
}; |
|
|
|
sankey.size = function(_) { |
|
if (!arguments.length) return size; |
|
size = _; |
|
return sankey; |
|
}; |
|
|
|
sankey.layout = function(iterations, callback) { |
|
computeNodeLinks(); |
|
computeNodeValues(); |
|
computeNodeBreadths(); |
|
computeNodeDepths(iterations, callback); |
|
}; |
|
|
|
sankey.relayout = function() { |
|
computeLinkDepths(); |
|
return sankey; |
|
}; |
|
|
|
sankey.link = function() { |
|
var curvature = .5; |
|
|
|
function link(d) { |
|
var x0 = d.source.x + d.source.dx, |
|
x1 = d.target.x, |
|
xi = interpolateNumber(x0, x1), |
|
x2 = xi(curvature), |
|
x3 = xi(1 - curvature), |
|
y0 = d.source.y + d.sy + d.dy / 2, |
|
y1 = d.target.y + d.ty + d.dy / 2; |
|
return "M" + x0 + "," + y0 |
|
+ "C" + x2 + "," + y0 |
|
+ " " + x3 + "," + y1 |
|
+ " " + x1 + "," + y1; |
|
} |
|
|
|
link.curvature = function(_) { |
|
if (!arguments.length) return curvature; |
|
curvature = +_; |
|
return link; |
|
}; |
|
|
|
return link; |
|
}; |
|
|
|
// Populate the sourceLinks and targetLinks for each node. |
|
// Also, if the source and target are not objects, assume they are indices. |
|
function computeNodeLinks() { |
|
nodes.forEach(function(node) { |
|
node.sourceLinks = []; |
|
node.targetLinks = []; |
|
}); |
|
links.forEach(function(link, i) { |
|
var source = link.source, |
|
target = link.target; |
|
if (typeof source === "number") source = link.source = nodes[link.source]; |
|
if (typeof target === "number") target = link.target = nodes[link.target]; |
|
link.originalIndex = i; |
|
source.sourceLinks.push(link); |
|
target.targetLinks.push(link); |
|
}); |
|
} |
|
|
|
// Compute the value (size) of each node by summing the associated links. |
|
function computeNodeValues() { |
|
nodes.forEach(function(node) { |
|
node.value = Math.max( |
|
sum(node.sourceLinks, value), |
|
sum(node.targetLinks, value) |
|
); |
|
}); |
|
} |
|
|
|
// Iteratively assign the breadth (x-position) for each node. |
|
// Nodes are assigned the maximum breadth of incoming neighbors plus one; |
|
// nodes with no incoming links are assigned breadth zero, while |
|
// nodes with no outgoing links are assigned the maximum breadth. |
|
function computeNodeBreadths() { |
|
var remainingNodes = nodes, |
|
nextNodes, |
|
x = 0; |
|
|
|
while (remainingNodes.length) { |
|
nextNodes = []; |
|
remainingNodes.forEach(function(node) { |
|
node.x = x; |
|
node.dx = nodeWidth; |
|
node.sourceLinks.forEach(function(link) { |
|
if (nextNodes.indexOf(link.target) < 0) { |
|
nextNodes.push(link.target); |
|
} |
|
}); |
|
}); |
|
remainingNodes = nextNodes; |
|
++x; |
|
} |
|
|
|
// |
|
moveSinksRight(x); |
|
scaleNodeBreadths((size[0] - nodeWidth) / (x - 1)); |
|
} |
|
|
|
// function moveSourcesRight() { |
|
// nodes.forEach(function(node) { |
|
// if (!node.targetLinks.length) { |
|
// node.x = min(node.sourceLinks, function(d) { return d.target.x; }) - 1; |
|
// } |
|
// }); |
|
// } |
|
|
|
function moveSinksRight(x) { |
|
nodes.forEach(function(node) { |
|
if (!node.sourceLinks.length) { |
|
node.x = x - 1; |
|
} |
|
}); |
|
} |
|
|
|
function scaleNodeBreadths(kx) { |
|
nodes.forEach(function(node) { |
|
node.x *= kx; |
|
}); |
|
} |
|
|
|
function computeNodeDepths(iterations, callback) { |
|
var nodesByBreadth = nest() |
|
.key(function(d) { return d.x; }) |
|
.sortKeys(ascending) |
|
.entries(nodes) |
|
.map(function(d) { return d.values; }); |
|
|
|
// |
|
initializeNodeDepth(); |
|
resolveCollisions(); |
|
|
|
window.requestAnimationFrame(function render(t) { |
|
|
|
var alpha = Math.pow(Math.sin(t / 3000), 2); |
|
|
|
relaxRightToLeft(alpha); |
|
resolveCollisions(); |
|
relaxLeftToRight(alpha); |
|
resolveCollisions(); |
|
computeLinkDepths(); |
|
callback(sankey); |
|
|
|
if(t / 3000 < Math.PI) { |
|
window.requestAnimationFrame(render); |
|
} |
|
|
|
}); |
|
|
|
function initializeNodeDepth() { |
|
var ky = min(nodesByBreadth, function(nodes) { |
|
return (size[1] - (nodes.length - 1) * nodePadding) / sum(nodes, value); |
|
}); |
|
|
|
nodesByBreadth.forEach(function(nodes) { |
|
nodes.forEach(function(node, i) { |
|
node.y = i; |
|
node.dy = node.value * ky; |
|
}); |
|
}); |
|
|
|
links.forEach(function(link) { |
|
link.dy = link.value * ky; |
|
}); |
|
} |
|
|
|
function relaxLeftToRight(alpha) { |
|
nodesByBreadth.forEach(function(nodes) { |
|
nodes.forEach(function(node) { |
|
if (node.targetLinks.length) { |
|
var y = sum(node.targetLinks, weightedSource) / sum(node.targetLinks, value); |
|
node.y += (y - center(node)) * alpha; |
|
} |
|
}); |
|
}); |
|
|
|
function weightedSource(link) { |
|
return center(link.source) * link.value; |
|
} |
|
} |
|
|
|
function relaxRightToLeft(alpha) { |
|
nodesByBreadth.slice().reverse().forEach(function(nodes) { |
|
nodes.forEach(function(node) { |
|
if (node.sourceLinks.length) { |
|
var y = sum(node.sourceLinks, weightedTarget) / sum(node.sourceLinks, value); |
|
node.y += (y - center(node)) * alpha; |
|
} |
|
}); |
|
}); |
|
|
|
function weightedTarget(link) { |
|
return center(link.target) * link.value; |
|
} |
|
} |
|
|
|
function resolveCollisions() { |
|
nodesByBreadth.forEach(function(nodes) { |
|
var node, |
|
dy, |
|
y0 = 0, |
|
n = nodes.length, |
|
i; |
|
|
|
// Push any overlapping nodes down. |
|
nodes.sort(ascendingDepth); |
|
for (i = 0; i < n; ++i) { |
|
node = nodes[i]; |
|
dy = y0 - node.y; |
|
if (dy > 0) node.y += dy; |
|
y0 = node.y + node.dy + nodePadding; |
|
} |
|
|
|
// If the bottommost node goes outside the bounds, push it back up. |
|
dy = y0 - nodePadding - size[1]; |
|
if (dy > 0) { |
|
y0 = node.y -= dy; |
|
|
|
// Push any overlapping nodes back up. |
|
for (i = n - 2; i >= 0; --i) { |
|
node = nodes[i]; |
|
dy = node.y + node.dy + nodePadding - y0; |
|
if (dy > 0) node.y -= dy; |
|
y0 = node.y; |
|
} |
|
} |
|
}); |
|
} |
|
|
|
function ascendingDepth(a, b) { |
|
return a.y - b.y; |
|
} |
|
} |
|
|
|
function computeLinkDepths() { |
|
nodes.forEach(function(node) { |
|
node.sourceLinks.sort(ascendingTargetDepth); |
|
node.targetLinks.sort(ascendingSourceDepth); |
|
}); |
|
nodes.forEach(function(node) { |
|
var sy = 0, ty = 0; |
|
node.sourceLinks.forEach(function(link) { |
|
link.sy = sy; |
|
sy += link.dy; |
|
}); |
|
node.targetLinks.forEach(function(link) { |
|
link.ty = ty; |
|
ty += link.dy; |
|
}); |
|
}); |
|
|
|
function ascendingSourceDepth(a, b) { |
|
return (a.source.y - b.source.y) || (a.originalIndex - b.originalIndex); |
|
} |
|
|
|
function ascendingTargetDepth(a, b) { |
|
return (a.target.y - b.target.y) || (a.originalIndex - b.originalIndex); |
|
} |
|
} |
|
|
|
function center(node) { |
|
return node.y + node.dy / 2; |
|
} |
|
|
|
function value(link) { |
|
return link.value; |
|
} |
|
|
|
return sankey; |
|
} |
|
|
|
},{}],2:[function(require,module,exports){ |
|
/** |
|
* Direct source: https://bost.ocks.org/mike/sankey/ by Mike Bostock |
|
* Ultimate source: Department of Energy & Climate Change, Tom Counsell |
|
* http://tamc.github.io/Sankey/ |
|
*/ |
|
|
|
module.exports = { |
|
"nodes":[ |
|
{"name":"Agricultural 'waste'"}, |
|
{"name":"Bio-conversion"}, |
|
{"name":"Liquid"}, |
|
{"name":"Losses"}, |
|
{"name":"Solid"}, |
|
{"name":"Gas"}, |
|
{"name":"Biofuel imports"}, |
|
{"name":"Biomass imports"}, |
|
{"name":"Coal imports"}, |
|
{"name":"Coal"}, |
|
{"name":"Coal reserves"}, |
|
{"name":"District heating"}, |
|
{"name":"Industry"}, |
|
{"name":"Heating and cooling - commercial"}, |
|
{"name":"Heating and cooling - homes"}, |
|
{"name":"Electricity grid"}, |
|
{"name":"Over generation / exports"}, |
|
{"name":"H2 conversion"}, |
|
{"name":"Road transport"}, |
|
{"name":"Agriculture"}, |
|
{"name":"Rail transport"}, |
|
{"name":"Lighting & appliances - commercial"}, |
|
{"name":"Lighting & appliances - homes"}, |
|
{"name":"Gas imports"}, |
|
{"name":"Ngas"}, |
|
{"name":"Gas reserves"}, |
|
{"name":"Thermal generation"}, |
|
{"name":"Geothermal"}, |
|
{"name":"H2"}, |
|
{"name":"Hydro"}, |
|
{"name":"International shipping"}, |
|
{"name":"Domestic aviation"}, |
|
{"name":"International aviation"}, |
|
{"name":"National navigation"}, |
|
{"name":"Marine algae"}, |
|
{"name":"Nuclear"}, |
|
{"name":"Oil imports"}, |
|
{"name":"Oil"}, |
|
{"name":"Oil reserves"}, |
|
{"name":"Other waste"}, |
|
{"name":"Pumped heat"}, |
|
{"name":"Solar PV"}, |
|
{"name":"Solar Thermal"}, |
|
{"name":"Solar"}, |
|
{"name":"Tidal"}, |
|
{"name":"UK land based bioenergy"}, |
|
{"name":"Wave"}, |
|
{"name":"Wind"} |
|
], |
|
"links":[ |
|
{"source":0,"target":1,"value":124.729}, |
|
{"source":1,"target":2,"value":0.597}, |
|
{"source":1,"target":3,"value":26.862}, |
|
{"source":1,"target":4,"value":280.322}, |
|
{"source":1,"target":5,"value":81.144}, |
|
{"source":6,"target":2,"value":35}, |
|
{"source":7,"target":4,"value":35}, |
|
{"source":8,"target":9,"value":11.606}, |
|
{"source":10,"target":9,"value":63.965}, |
|
{"source":9,"target":4,"value":75.571}, |
|
{"source":11,"target":12,"value":10.639}, |
|
{"source":11,"target":13,"value":22.505}, |
|
{"source":11,"target":14,"value":46.184}, |
|
{"source":15,"target":16,"value":104.453}, |
|
{"source":15,"target":14,"value":113.726}, |
|
{"source":15,"target":17,"value":27.14}, |
|
{"source":15,"target":12,"value":342.165}, |
|
{"source":15,"target":18,"value":37.797}, |
|
{"source":15,"target":19,"value":4.412}, |
|
{"source":15,"target":13,"value":40.858}, |
|
{"source":15,"target":3,"value":56.691}, |
|
{"source":15,"target":20,"value":7.863}, |
|
{"source":15,"target":21,"value":90.008}, |
|
{"source":15,"target":22,"value":93.494}, |
|
{"source":23,"target":24,"value":40.719}, |
|
{"source":25,"target":24,"value":82.233}, |
|
{"source":5,"target":13,"value":0.129}, |
|
{"source":5,"target":3,"value":1.401}, |
|
{"source":5,"target":26,"value":151.891}, |
|
{"source":5,"target":19,"value":2.096}, |
|
{"source":5,"target":12,"value":48.58}, |
|
{"source":27,"target":15,"value":7.013}, |
|
{"source":17,"target":28,"value":20.897}, |
|
{"source":17,"target":3,"value":6.242}, |
|
{"source":28,"target":18,"value":20.897}, |
|
{"source":29,"target":15,"value":6.995}, |
|
{"source":2,"target":12,"value":121.066}, |
|
{"source":2,"target":30,"value":128.69}, |
|
{"source":2,"target":18,"value":135.835}, |
|
{"source":2,"target":31,"value":14.458}, |
|
{"source":2,"target":32,"value":206.267}, |
|
{"source":2,"target":19,"value":3.64}, |
|
{"source":2,"target":33,"value":33.218}, |
|
{"source":2,"target":20,"value":4.413}, |
|
{"source":34,"target":1,"value":14.375}, |
|
{"source":24,"target":5,"value":122.952}, |
|
{"source":35,"target":26,"value":839.978}, |
|
{"source":36,"target":37,"value":504.287}, |
|
{"source":38,"target":37,"value":107.703}, |
|
{"source":37,"target":2,"value":611.99}, |
|
{"source":39,"target":4,"value":56.587}, |
|
{"source":39,"target":1,"value":77.81}, |
|
{"source":40,"target":14,"value":193.026}, |
|
{"source":40,"target":13,"value":70.672}, |
|
{"source":41,"target":15,"value":59.901}, |
|
{"source":42,"target":14,"value":19.263}, |
|
{"source":43,"target":42,"value":19.263}, |
|
{"source":43,"target":41,"value":59.901}, |
|
{"source":4,"target":19,"value":0.882}, |
|
{"source":4,"target":26,"value":400.12}, |
|
{"source":4,"target":12,"value":46.477}, |
|
{"source":26,"target":15,"value":525.531}, |
|
{"source":26,"target":3,"value":787.129}, |
|
{"source":26,"target":11,"value":79.329}, |
|
{"source":44,"target":15,"value":9.452}, |
|
{"source":45,"target":1,"value":182.01}, |
|
{"source":46,"target":15,"value":19.013}, |
|
{"source":47,"target":15,"value":289.366} |
|
] |
|
}; |
|
|
|
},{}],3:[function(require,module,exports){ |
|
/** |
|
* Copyright 2012-2017, Plotly, Inc. |
|
* All rights reserved. |
|
* |
|
* This source code is licensed under the MIT license found in the |
|
* LICENSE file in the root directory of this source tree. |
|
*/ |
|
|
|
//var d3 = require('d3'); |
|
var d3sankey = require('./d3-sankey'); |
|
|
|
var data = require('./energy'); |
|
|
|
var width = 800; |
|
var height = 500; |
|
var margin = { |
|
l: 20, |
|
t: 20, |
|
r: 200, |
|
b: 20 |
|
}; |
|
|
|
var c = { |
|
nodeTextOffset: 5, |
|
nodeWidth: 15, |
|
nodePadding: 14, |
|
sankeyIterations: 700, |
|
vertical: false, |
|
nodeOpacity: 0.7, |
|
nodeSalientOpacity: 1, |
|
linkOpacity: 0.2, |
|
linkSalientOpacity: 0.4 |
|
}; |
|
|
|
function keyFun(d) {return d.key;} |
|
|
|
function repeat(d) {return [d];} |
|
|
|
function noop() {} |
|
|
|
function viewModel(sankey) { |
|
|
|
return { |
|
key: 0, |
|
translateX: margin.l, |
|
translateY: margin.t, |
|
dragLength: c.vertical ? width : height, |
|
nodes: sankey.nodes(), |
|
links: sankey.links(), |
|
sankey: sankey |
|
}; |
|
} |
|
|
|
function render(svg, callbacks) { |
|
return function(sankey) { |
|
|
|
var dragInProgress = false; |
|
var hovered = false; |
|
|
|
function attachPointerEvents(selection, eventSet) { |
|
selection |
|
.on('mouseover', function (d) { |
|
if (!dragInProgress) { |
|
eventSet.hover(this, d); |
|
hovered = [this, d]; |
|
} |
|
}) |
|
.on('mouseout', function (d) { |
|
if (!dragInProgress) { |
|
eventSet.unhover(this, d); |
|
hovered = false; |
|
} |
|
}) |
|
.on('click', function (d) { |
|
if (hovered) { |
|
eventSet.unhover(this, d); |
|
hovered = false; |
|
} |
|
if (!dragInProgress) { |
|
eventSet.select(this, d); |
|
} |
|
}); |
|
} |
|
|
|
function linkPath(d) { |
|
return d.sankey.link()(d.link); |
|
} |
|
|
|
var colorer = d3.scale.category20(); |
|
|
|
var sankey = svg.selectAll('.sankey') |
|
.data([viewModel(sankey)], keyFun); |
|
|
|
sankey.enter() |
|
.append('g') |
|
.classed('sankey', true) |
|
.attr('overflow', 'visible') |
|
.style('box-sizing', 'content-box') |
|
.style('position', 'absolute') |
|
.style('left', 0) |
|
.style('overflow', 'visible') |
|
.style('shape-rendering', 'geometricPrecision') |
|
.style('pointer-events', 'auto') |
|
.style('box-sizing', 'content-box'); |
|
|
|
sankey |
|
.attr('transform', function(d) { |
|
return 'translate(' + d.translateX + ',' + d.translateY + ')'; |
|
}); |
|
|
|
var sankeyLinks = sankey.selectAll('.sankeyLinks') |
|
.data(repeat, keyFun); |
|
|
|
sankeyLinks.enter() |
|
.append('g') |
|
.classed('sankeyLinks', true) |
|
.style('transform', c.vertical ? 'matrix(0,1,1,0,0,0)' : 'matrix(1,0,0,1,0,0)') |
|
.style('fill', 'none') |
|
.style('stroke', 'black') |
|
.style('stroke-opacity', c.linkOpacity); |
|
|
|
var sankeyLink = sankeyLinks.selectAll('.sankeyPath') |
|
.data(function(d) { |
|
return d.sankey.links().map(function(l) { |
|
return { |
|
link: l, |
|
sankey: d.sankey |
|
}; |
|
}); |
|
}); |
|
|
|
sankeyLink.enter() |
|
.append('path') |
|
.classed('sankeyPath', true) |
|
.call(attachPointerEvents, callbacks.linkEvents); |
|
|
|
sankeyLink |
|
.attr('d', linkPath) |
|
.style('stroke-width', function(d) {return Math.max(1, d.link.dy);}); |
|
|
|
var sankeyNodes = sankey.selectAll('.sankeyNodes') |
|
.data(repeat, keyFun); |
|
|
|
sankeyNodes.enter() |
|
.append('g') |
|
.style('shape-rendering', 'crispEdges') |
|
.classed('sankeyNodes', true); |
|
|
|
var sankeyNode = sankeyNodes.selectAll('.sankeyNode') |
|
.data(function(d) { |
|
return d.sankey.nodes().map(function(l) { |
|
return { |
|
node: l, |
|
sankey: d.sankey, |
|
model: d |
|
}; |
|
}); |
|
}, function(d) {return d.node.name;}); |
|
|
|
sankeyNode.enter() |
|
.append('g') |
|
.classed('sankeyNode', true) |
|
.call(d3.behavior.drag() |
|
.origin(function(d) {return c.vertical ? {x: d.node.y} : d.node;}) |
|
.on('dragstart', function(d) { |
|
d.node.dragStartLocation = c.vertical ? d3.event.x : d3.event.y; |
|
this.parentNode.appendChild(this); |
|
dragInProgress = true; |
|
if(hovered) { |
|
//callbacks.nodeEvents.unhover.apply(0, hovered); |
|
hovered = false; |
|
} |
|
}) |
|
.on('drag', function(d) { |
|
if(c.vertical) { |
|
d.node.y = Math.max(0, Math.min(d.model.dragLength - d.node.dy, d3.event.x)); |
|
d3.select(this).style('transform', 'translate(' + d.node.y + 'px,' + d.node.x + 'px)'); |
|
} else { |
|
d.node.y = Math.max(0, Math.min(d.model.dragLength - d.node.dy, d3.event.y)); |
|
d3.select(this).style('transform', 'translate(' + d.node.x + 'px,' + d.node.y + 'px)'); |
|
} |
|
|
|
d.sankey.relayout(); |
|
sankeyLink.attr('d', linkPath); |
|
} |
|
) |
|
.on('dragend', function() { |
|
dragInProgress = false; |
|
})); |
|
|
|
sankeyNode |
|
.style('transform', c.vertical ? |
|
function(d) {return 'translate(' + (Math.floor(d.node.y) - 0.5) + 'px, ' + (Math.floor(d.node.x) + 0.5) + 'px)';} : |
|
function(d) {return 'translate(' + (Math.floor(d.node.x) - 0.5) + 'px, ' + (Math.floor(d.node.y) + 0.5) + 'px)';}); |
|
|
|
var nodeRect = sankeyNode.selectAll('.nodeRect') |
|
.data(repeat); |
|
|
|
nodeRect.enter() |
|
.append('rect') |
|
.classed('nodeRect', true) |
|
.style('shape-rendering', 'crispEdges') |
|
.style('fill', function(d) {return colorer(d.sankey.nodes().indexOf(d.node));}) |
|
.style('stroke-width', 0.5) |
|
.style('stroke', 'black') |
|
.style('stroke-opacity', 1) |
|
.style('fill-opacity', c.nodeOpacity) |
|
.call(attachPointerEvents, callbacks.nodeEvents); |
|
|
|
nodeRect // ceil, +/-0.5 and crispEdges is wizardry for consistent border width on all 4 sides |
|
.attr(c.vertical ? 'height' : 'width', function(d) {return Math.ceil(d.node.dx + 0.5);}) |
|
.attr(c.vertical ? 'width' : 'height', function(d) {return Math.ceil(d.node.dy - 0.5);}); |
|
|
|
var nodeLabel = sankeyNode.selectAll('.nodeLabel') |
|
.data(repeat); |
|
|
|
nodeLabel.enter() |
|
.append('text') |
|
.classed('nodeLabel', true); |
|
|
|
nodeLabel |
|
.attr('x', function(d) {return c.vertical ? d.node.dy / 2 : d.node.dx + c.nodeTextOffset;}) |
|
.attr('y', function(d) {return c.vertical ? d.node.dx / 2 : d.node.dy / 2;}) |
|
.text(function(d) {return d.node.name;}) |
|
.attr('alignment-baseline', 'middle') |
|
.attr('text-anchor', c.vertical ? 'middle' : 'start') |
|
.style('font-family', 'sans-serif') |
|
.style('font-size', '10px'); |
|
}; |
|
}; |
|
|
|
var svg = d3.select('body').append('svg') |
|
.attr('width', width + margin.l + margin.r) |
|
.attr('height', height + margin.t + margin.b); |
|
|
|
var renderer = render(svg, { |
|
linkEvents: { |
|
hover: function(e, l) { |
|
d3.selectAll('.nodeRect') |
|
.filter(function(n) {return n.node.name === l.link.source.name || n.node.name === l.link.target.name;}) |
|
.style('fill-opacity', c.nodeSalientOpacity); |
|
d3.select(e).style('stroke-opacity', c.linkSalientOpacity); |
|
}, |
|
unhover: function(e, d) { |
|
d3.selectAll('.nodeRect').style('fill-opacity', c.nodeOpacity); |
|
d3.select(e).style('stroke-opacity', c.linkOpacity); |
|
}, |
|
select: noop |
|
}, |
|
nodeEvents: { |
|
hover: function(e, n) { |
|
d3.selectAll('.sankeyPath') |
|
.filter(function(l) {return n.node.name === l.link.source.name || n.node.name === l.link.target.name;}) |
|
.style('stroke-opacity', c.linkSalientOpacity); |
|
d3.select(e).style('fill-opacity', c.nodeSalientOpacity); |
|
}, |
|
unhover: function(e, d) { |
|
d3.selectAll('.sankeyPath').style('stroke-opacity', c.linkOpacity); |
|
d3.select(e).style('fill-opacity', c.nodeOpacity); |
|
}, |
|
select: noop |
|
} |
|
}); |
|
|
|
d3sankey() |
|
.size(c.vertical ? [height, width]: [width, height]) |
|
.nodeWidth(c.nodeWidth) |
|
.nodePadding(c.nodePadding) |
|
.nodes(data.nodes) |
|
.links(data.links) |
|
.layout(c.sankeyIterations, renderer); |
|
},{"./d3-sankey":1,"./energy":2}]},{},[3]) |
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Vzci9sb2NhbC9saWIvbm9kZV9tb2R1bGVzL2J1ZG8vbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsImQzLXNhbmtleS5qcyIsImVuZXJneS5qcyIsImluZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25VQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIi8qKlxuICogZDMtc2Fua2V5IENvcHlyaWdodCBNaWtlIEJvc3RvY2tcbiAqXG4gKiBTb3VyY2UgcmVwb3NpdG9yeTogaHR0cHM6Ly9naXRodWIuY29tL2QzL2QzLXNhbmtleVxuICpcbiAqIE1pbm9yIGxvY2FsIG1vZGlmaWNhdGlvbnM6XG4gKiAgICAtIFN0YWJsZSBzb3J0aW5nIGh0dHBzOi8vZ2l0aHViLmNvbS9kMy9kMy1zYW5rZXkvcHVsbC8xOSAoaXJyZWxldmFudCBoZXJlKVxuICogICAgLSBJbmxpbmluZyBjb2RlIGhlcmUgc28gaXQgd29ya3Mgd2l0aCBkMyB2My4qXG4gKiAgICAtIFJlcGxhY2luZyB0aGUgcmVsYXhhdGlvbiBsb29wIHdpdGggYSByQUZcbiAqICAgIC0gT3ZlcnJpZGluZyBhbHBoYSBkZWNheSBhbmQgaXRlcmF0aW9uIGxpbWl0IGNoZWNrIHdpdGggYSBoYWxmLXNpbmUgY3VydmVcbiAqL1xuXG4vLyB2YXIgZDMgPSByZXF1aXJlKCdkMycpO1xudmFyIG5lc3QgPSBkMy5uZXN0O1xudmFyIGludGVycG9sYXRlTnVtYmVyID0gZDMuaW50ZXJwb2xhdGVOdW1iZXI7XG52YXIgYXNjZW5kaW5nID0gZDMuYXNjZW5kaW5nO1xudmFyIG1pbiA9IGQzLm1pbjtcbnZhciBzdW0gPSBkMy5zdW07XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzYW5rZXkgPSB7fSxcbiAgICAgIG5vZGVXaWR0aCA9IDI0LFxuICAgICAgbm9kZVBhZGRpbmcgPSA4LFxuICAgICAgc2l6ZSA9IFsxLCAxXSxcbiAgICAgIG5vZGVzID0gW10sXG4gICAgICBsaW5rcyA9IFtdO1xuXG4gIHNhbmtleS5ub2RlV2lkdGggPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbm9kZVdpZHRoO1xuICAgIG5vZGVXaWR0aCA9ICtfO1xuICAgIHJldHVybiBzYW5rZXk7XG4gIH07XG5cbiAgc2Fua2V5Lm5vZGVQYWRkaW5nID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIG5vZGVQYWRkaW5nO1xuICAgIG5vZGVQYWRkaW5nID0gK187XG4gICAgcmV0dXJuIHNhbmtleTtcbiAgfTtcblxuICBzYW5rZXkubm9kZXMgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gbm9kZXM7XG4gICAgbm9kZXMgPSBfO1xuICAgIHJldHVybiBzYW5rZXk7XG4gIH07XG5cbiAgc2Fua2V5LmxpbmtzID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxpbmtzO1xuICAgIGxpbmtzID0gXztcbiAgICByZXR1cm4gc2Fua2V5O1xuICB9O1xuXG4gIHNhbmtleS5zaXplID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHNpemU7XG4gICAgc2l6ZSA9IF87XG4gICAgcmV0dXJuIHNhbmtleTtcbiAgfTtcblxuICBzYW5rZXkubGF5b3V0ID0gZnVuY3Rpb24oaXRlcmF0aW9ucywgY2FsbGJhY2spIHtcbiAgICBjb21wdXRlTm9kZUxpbmtzKCk7XG4gICAgY29tcHV0ZU5vZGVWYWx1ZXMoKTtcbiAgICBjb21wdXRlTm9kZUJyZWFkdGhzKCk7XG4gICAgY29tcHV0ZU5vZGVEZXB0aHMoaXRlcmF0aW9ucywgY2FsbGJhY2spO1xuICB9O1xuXG4gIHNhbmtleS5yZWxheW91dCA9IGZ1bmN0aW9uKCkge1xuICAgIGNvbXB1dGVMaW5rRGVwdGhzKCk7XG4gICAgcmV0dXJuIHNhbmtleTtcbiAgfTtcblxuICBzYW5rZXkubGluayA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBjdXJ2YXR1cmUgPSAuNTtcblxuICAgIGZ1bmN0aW9uIGxpbmsoZCkge1xuICAgICAgdmFyIHgwID0gZC5zb3VyY2UueCArIGQuc291cmNlLmR4LFxuICAgICAgICAgIHgxID0gZC50YXJnZXQueCxcbiAgICAgICAgICB4aSA9IGludGVycG9sYXRlTnVtYmVyKHgwLCB4MSksXG4gICAgICAgICAgeDIgPSB4aShjdXJ2YXR1cmUpLFxuICAgICAgICAgIHgzID0geGkoMSAtIGN1cnZhdHVyZSksXG4gICAgICAgICAgeTAgPSBkLnNvdXJjZS55ICsgZC5zeSArIGQuZHkgLyAyLFxuICAgICAgICAgIHkxID0gZC50YXJnZXQueSArIGQudHkgKyBkLmR5IC8gMjtcbiAgICAgIHJldHVybiBcIk1cIiArIHgwICsgXCIsXCIgKyB5MFxuICAgICAgICArIFwiQ1wiICsgeDIgKyBcIixcIiArIHkwXG4gICAgICAgICsgXCIgXCIgKyB4MyArIFwiLFwiICsgeTFcbiAgICAgICAgKyBcIiBcIiArIHgxICsgXCIsXCIgKyB5MTtcbiAgICB9XG5cbiAgICBsaW5rLmN1cnZhdHVyZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGN1cnZhdHVyZTtcbiAgICAgIGN1cnZhdHVyZSA9ICtfO1xuICAgICAgcmV0dXJuIGxpbms7XG4gICAgfTtcblxuICAgIHJldHVybiBsaW5rO1xuICB9O1xuXG4gIC8vIFBvcHVsYXRlIHRoZSBzb3VyY2VMaW5rcyBhbmQgdGFyZ2V0TGlua3MgZm9yIGVhY2ggbm9kZS5cbiAgLy8gQWxzbywgaWYgdGhlIHNvdXJjZSBhbmQgdGFyZ2V0IGFyZSBub3Qgb2JqZWN0cywgYXNzdW1lIHRoZXkgYXJlIGluZGljZXMuXG4gIGZ1bmN0aW9uIGNvbXB1dGVOb2RlTGlua3MoKSB7XG4gICAgbm9kZXMuZm9yRWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgICBub2RlLnNvdXJjZUxpbmtzID0gW107XG4gICAgICBub2RlLnRhcmdldExpbmtzID0gW107XG4gICAgfSk7XG4gICAgbGlua3MuZm9yRWFjaChmdW5jdGlvbihsaW5rLCBpKSB7XG4gICAgICB2YXIgc291cmNlID0gbGluay5zb3VyY2UsXG4gICAgICAgICAgdGFyZ2V0ID0gbGluay50YXJnZXQ7XG4gICAgICBpZiAodHlwZW9mIHNvdXJjZSA9PT0gXCJudW1iZXJcIikgc291cmNlID0gbGluay5zb3VyY2UgPSBub2Rlc1tsaW5rLnNvdXJjZV07XG4gICAgICBpZiAodHlwZW9mIHRhcmdldCA9PT0gXCJudW1iZXJcIikgdGFyZ2V0ID0gbGluay50YXJnZXQgPSBub2Rlc1tsaW5rLnRhcmdldF07XG4gICAgICBsaW5rLm9yaWdpbmFsSW5kZXggPSBpO1xuICAgICAgc291cmNlLnNvdXJjZUxpbmtzLnB1c2gobGluayk7XG4gICAgICB0YXJnZXQudGFyZ2V0TGlua3MucHVzaChsaW5rKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIENvbXB1dGUgdGhlIHZhbHVlIChzaXplKSBvZiBlYWNoIG5vZGUgYnkgc3VtbWluZyB0aGUgYXNzb2NpYXRlZCBsaW5rcy5cbiAgZnVuY3Rpb24gY29tcHV0ZU5vZGVWYWx1ZXMoKSB7XG4gICAgbm9kZXMuZm9yRWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgICBub2RlLnZhbHVlID0gTWF0aC5tYXgoXG4gICAgICAgIHN1bShub2RlLnNvdXJjZUxpbmtzLCB2YWx1ZSksXG4gICAgICAgIHN1bShub2RlLnRhcmdldExpbmtzLCB2YWx1ZSlcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBJdGVyYXRpdmVseSBhc3NpZ24gdGhlIGJyZWFkdGggKHgtcG9zaXRpb24pIGZvciBlYWNoIG5vZGUuXG4gIC8vIE5vZGVzIGFyZSBhc3NpZ25lZCB0aGUgbWF4aW11bSBicmVhZHRoIG9mIGluY29taW5nIG5laWdoYm9ycyBwbHVzIG9uZTtcbiAgLy8gbm9kZXMgd2l0aCBubyBpbmNvbWluZyBsaW5rcyBhcmUgYXNzaWduZWQgYnJlYWR0aCB6ZXJvLCB3aGlsZVxuICAvLyBub2RlcyB3aXRoIG5vIG91dGdvaW5nIGxpbmtzIGFyZSBhc3NpZ25lZCB0aGUgbWF4aW11bSBicmVhZHRoLlxuICBmdW5jdGlvbiBjb21wdXRlTm9kZUJyZWFkdGhzKCkge1xuICAgIHZhciByZW1haW5pbmdOb2RlcyA9IG5vZGVzLFxuICAgICAgICBuZXh0Tm9kZXMsXG4gICAgICAgIHggPSAwO1xuXG4gICAgd2hpbGUgKHJlbWFpbmluZ05vZGVzLmxlbmd0aCkge1xuICAgICAgbmV4dE5vZGVzID0gW107XG4gICAgICByZW1haW5pbmdOb2Rlcy5mb3JFYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgbm9kZS54ID0geDtcbiAgICAgICAgbm9kZS5keCA9IG5vZGVXaWR0aDtcbiAgICAgICAgbm9kZS5zb3VyY2VMaW5rcy5mb3JFYWNoKGZ1bmN0aW9uKGxpbmspIHtcbiAgICAgICAgICBpZiAobmV4dE5vZGVzLmluZGV4T2YobGluay50YXJnZXQpIDwgMCkge1xuICAgICAgICAgICAgbmV4dE5vZGVzLnB1c2gobGluay50YXJnZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIHJlbWFpbmluZ05vZGVzID0gbmV4dE5vZGVzO1xuICAgICAgKyt4O1xuICAgIH1cblxuICAgIC8vXG4gICAgbW92ZVNpbmtzUmlnaHQoeCk7XG4gICAgc2NhbGVOb2RlQnJlYWR0aHMoKHNpemVbMF0gLSBub2RlV2lkdGgpIC8gKHggLSAxKSk7XG4gIH1cblxuICAvLyBmdW5jdGlvbiBtb3ZlU291cmNlc1JpZ2h0KCkge1xuICAvLyAgIG5vZGVzLmZvckVhY2goZnVuY3Rpb24obm9kZSkge1xuICAvLyAgICAgaWYgKCFub2RlLnRhcmdldExpbmtzLmxlbmd0aCkge1xuICAvLyAgICAgICBub2RlLnggPSBtaW4obm9kZS5zb3VyY2VMaW5rcywgZnVuY3Rpb24oZCkgeyByZXR1cm4gZC50YXJnZXQueDsgfSkgLSAxO1xuICAvLyAgICAgfVxuICAvLyAgIH0pO1xuICAvLyB9XG5cbiAgZnVuY3Rpb24gbW92ZVNpbmtzUmlnaHQoeCkge1xuICAgIG5vZGVzLmZvckVhY2goZnVuY3Rpb24obm9kZSkge1xuICAgICAgaWYgKCFub2RlLnNvdXJjZUxpbmtzLmxlbmd0aCkge1xuICAgICAgICBub2RlLnggPSB4IC0gMTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNjYWxlTm9kZUJyZWFkdGhzKGt4KSB7XG4gICAgbm9kZXMuZm9yRWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgICBub2RlLnggKj0ga3g7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBjb21wdXRlTm9kZURlcHRocyhpdGVyYXRpb25zLCBjYWxsYmFjaykge1xuICAgIHZhciBub2Rlc0J5QnJlYWR0aCA9IG5lc3QoKVxuICAgICAgLmtleShmdW5jdGlvbihkKSB7IHJldHVybiBkLng7IH0pXG4gICAgICAuc29ydEtleXMoYXNjZW5kaW5nKVxuICAgICAgLmVudHJpZXMobm9kZXMpXG4gICAgICAubWFwKGZ1bmN0aW9uKGQpIHsgcmV0dXJuIGQudmFsdWVzOyB9KTtcblxuICAgIC8vXG4gICAgaW5pdGlhbGl6ZU5vZGVEZXB0aCgpO1xuICAgIHJlc29sdmVDb2xsaXNpb25zKCk7XG5cbiAgICB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uIHJlbmRlcih0KSB7XG5cbiAgICAgIHZhciBhbHBoYSA9IE1hdGgucG93KE1hdGguc2luKHQgLyAzMDAwKSwgMik7XG5cbiAgICAgIHJlbGF4UmlnaHRUb0xlZnQoYWxwaGEpO1xuICAgICAgcmVzb2x2ZUNvbGxpc2lvbnMoKTtcbiAgICAgIHJlbGF4TGVmdFRvUmlnaHQoYWxwaGEpO1xuICAgICAgcmVzb2x2ZUNvbGxpc2lvbnMoKTtcbiAgICAgIGNvbXB1dGVMaW5rRGVwdGhzKCk7XG4gICAgICBjYWxsYmFjayhzYW5rZXkpO1xuXG4gICAgICBpZih0IC8gMzAwMCA8IE1hdGguUEkpIHtcbiAgICAgICAgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShyZW5kZXIpO1xuICAgICAgfVxuXG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBpbml0aWFsaXplTm9kZURlcHRoKCkge1xuICAgICAgdmFyIGt5ID0gbWluKG5vZGVzQnlCcmVhZHRoLCBmdW5jdGlvbihub2Rlcykge1xuICAgICAgICByZXR1cm4gKHNpemVbMV0gLSAobm9kZXMubGVuZ3RoIC0gMSkgKiBub2RlUGFkZGluZykgLyBzdW0obm9kZXMsIHZhbHVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBub2Rlc0J5QnJlYWR0aC5mb3JFYWNoKGZ1bmN0aW9uKG5vZGVzKSB7XG4gICAgICAgIG5vZGVzLmZvckVhY2goZnVuY3Rpb24obm9kZSwgaSkge1xuICAgICAgICAgIG5vZGUueSA9IGk7XG4gICAgICAgICAgbm9kZS5keSA9IG5vZGUudmFsdWUgKiBreTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgbGlua3MuZm9yRWFjaChmdW5jdGlvbihsaW5rKSB7XG4gICAgICAgIGxpbmsuZHkgPSBsaW5rLnZhbHVlICoga3k7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByZWxheExlZnRUb1JpZ2h0KGFscGhhKSB7XG4gICAgICBub2Rlc0J5QnJlYWR0aC5mb3JFYWNoKGZ1bmN0aW9uKG5vZGVzKSB7XG4gICAgICAgIG5vZGVzLmZvckVhY2goZnVuY3Rpb24obm9kZSkge1xuICAgICAgICAgIGlmIChub2RlLnRhcmdldExpbmtzLmxlbmd0aCkge1xuICAgICAgICAgICAgdmFyIHkgPSBzdW0obm9kZS50YXJnZXRMaW5rcywgd2VpZ2h0ZWRTb3VyY2UpIC8gc3VtKG5vZGUudGFyZ2V0TGlua3MsIHZhbHVlKTtcbiAgICAgICAgICAgIG5vZGUueSArPSAoeSAtIGNlbnRlcihub2RlKSkgKiBhbHBoYTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIGZ1bmN0aW9uIHdlaWdodGVkU291cmNlKGxpbmspIHtcbiAgICAgICAgcmV0dXJuIGNlbnRlcihsaW5rLnNvdXJjZSkgKiBsaW5rLnZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbGF4UmlnaHRUb0xlZnQoYWxwaGEpIHtcbiAgICAgIG5vZGVzQnlCcmVhZHRoLnNsaWNlKCkucmV2ZXJzZSgpLmZvckVhY2goZnVuY3Rpb24obm9kZXMpIHtcbiAgICAgICAgbm9kZXMuZm9yRWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgICAgICAgaWYgKG5vZGUuc291cmNlTGlua3MubGVuZ3RoKSB7XG4gICAgICAgICAgICB2YXIgeSA9IHN1bShub2RlLnNvdXJjZUxpbmtzLCB3ZWlnaHRlZFRhcmdldCkgLyBzdW0obm9kZS5zb3VyY2VMaW5rcywgdmFsdWUpO1xuICAgICAgICAgICAgbm9kZS55ICs9ICh5IC0gY2VudGVyKG5vZGUpKSAqIGFscGhhO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgZnVuY3Rpb24gd2VpZ2h0ZWRUYXJnZXQobGluaykge1xuICAgICAgICByZXR1cm4gY2VudGVyKGxpbmsudGFyZ2V0KSAqIGxpbmsudmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmVzb2x2ZUNvbGxpc2lvbnMoKSB7XG4gICAgICBub2Rlc0J5QnJlYWR0aC5mb3JFYWNoKGZ1bmN0aW9uKG5vZGVzKSB7XG4gICAgICAgIHZhciBub2RlLFxuICAgICAgICAgICAgZHksXG4gICAgICAgICAgICB5MCA9IDAsXG4gICAgICAgICAgICBuID0gbm9kZXMubGVuZ3RoLFxuICAgICAgICAgICAgaTtcblxuICAgICAgICAvLyBQdXNoIGFueSBvdmVybGFwcGluZyBub2RlcyBkb3duLlxuICAgICAgICBub2Rlcy5zb3J0KGFzY2VuZGluZ0RlcHRoKTtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgICAgIG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgICBkeSA9IHkwIC0gbm9kZS55O1xuICAgICAgICAgIGlmIChkeSA+IDApIG5vZGUueSArPSBkeTtcbiAgICAgICAgICB5MCA9IG5vZGUueSArIG5vZGUuZHkgKyBub2RlUGFkZGluZztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElmIHRoZSBib3R0b21tb3N0IG5vZGUgZ29lcyBvdXRzaWRlIHRoZSBib3VuZHMsIHB1c2ggaXQgYmFjayB1cC5cbiAgICAgICAgZHkgPSB5MCAtIG5vZGVQYWRkaW5nIC0gc2l6ZVsxXTtcbiAgICAgICAgaWYgKGR5ID4gMCkge1xuICAgICAgICAgIHkwID0gbm9kZS55IC09IGR5O1xuXG4gICAgICAgICAgLy8gUHVzaCBhbnkgb3ZlcmxhcHBpbmcgbm9kZXMgYmFjayB1cC5cbiAgICAgICAgICBmb3IgKGkgPSBuIC0gMjsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgICAgIG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgICAgIGR5ID0gbm9kZS55ICsgbm9kZS5keSArIG5vZGVQYWRkaW5nIC0geTA7XG4gICAgICAgICAgICBpZiAoZHkgPiAwKSBub2RlLnkgLT0gZHk7XG4gICAgICAgICAgICB5MCA9IG5vZGUueTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFzY2VuZGluZ0RlcHRoKGEsIGIpIHtcbiAgICAgIHJldHVybiBhLnkgLSBiLnk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY29tcHV0ZUxpbmtEZXB0aHMoKSB7XG4gICAgbm9kZXMuZm9yRWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgICBub2RlLnNvdXJjZUxpbmtzLnNvcnQoYXNjZW5kaW5nVGFyZ2V0RGVwdGgpO1xuICAgICAgbm9kZS50YXJnZXRMaW5rcy5zb3J0KGFzY2VuZGluZ1NvdXJjZURlcHRoKTtcbiAgICB9KTtcbiAgICBub2Rlcy5mb3JFYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHZhciBzeSA9IDAsIHR5ID0gMDtcbiAgICAgIG5vZGUuc291cmNlTGlua3MuZm9yRWFjaChmdW5jdGlvbihsaW5rKSB7XG4gICAgICAgIGxpbmsuc3kgPSBzeTtcbiAgICAgICAgc3kgKz0gbGluay5keTtcbiAgICAgIH0pO1xuICAgICAgbm9kZS50YXJnZXRMaW5rcy5mb3JFYWNoKGZ1bmN0aW9uKGxpbmspIHtcbiAgICAgICAgbGluay50eSA9IHR5O1xuICAgICAgICB0eSArPSBsaW5rLmR5O1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBmdW5jdGlvbiBhc2NlbmRpbmdTb3VyY2VEZXB0aChhLCBiKSB7XG4gICAgICByZXR1cm4gKGEuc291cmNlLnkgLSBiLnNvdXJjZS55KSB8fCAoYS5vcmlnaW5hbEluZGV4IC0gYi5vcmlnaW5hbEluZGV4KTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhc2NlbmRpbmdUYXJnZXREZXB0aChhLCBiKSB7XG4gICAgICByZXR1cm4gKGEudGFyZ2V0LnkgLSBiLnRhcmdldC55KSB8fCAoYS5vcmlnaW5hbEluZGV4IC0gYi5vcmlnaW5hbEluZGV4KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjZW50ZXIobm9kZSkge1xuICAgIHJldHVybiBub2RlLnkgKyBub2RlLmR5IC8gMjtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZhbHVlKGxpbmspIHtcbiAgICByZXR1cm4gbGluay52YWx1ZTtcbiAgfVxuXG4gIHJldHVybiBzYW5rZXk7XG59XG4iLCIvKipcbiAqIERpcmVjdCBzb3VyY2U6IGh0dHBzOi8vYm9zdC5vY2tzLm9yZy9taWtlL3NhbmtleS8gYnkgTWlrZSBCb3N0b2NrXG4gKiBVbHRpbWF0ZSBzb3VyY2U6IERlcGFydG1lbnQgb2YgRW5lcmd5ICYgQ2xpbWF0ZSBDaGFuZ2UsIFRvbSBDb3Vuc2VsbFxuICogICAgICAgICAgICAgICAgICBodHRwOi8vdGFtYy5naXRodWIuaW8vU2Fua2V5L1xuICovXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBcIm5vZGVzXCI6W1xuICAgIHtcIm5hbWVcIjpcIkFncmljdWx0dXJhbCAnd2FzdGUnXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkJpby1jb252ZXJzaW9uXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkxpcXVpZFwifSxcbiAgICB7XCJuYW1lXCI6XCJMb3NzZXNcIn0sXG4gICAge1wibmFtZVwiOlwiU29saWRcIn0sXG4gICAge1wibmFtZVwiOlwiR2FzXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkJpb2Z1ZWwgaW1wb3J0c1wifSxcbiAgICB7XCJuYW1lXCI6XCJCaW9tYXNzIGltcG9ydHNcIn0sXG4gICAge1wibmFtZVwiOlwiQ29hbCBpbXBvcnRzXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkNvYWxcIn0sXG4gICAge1wibmFtZVwiOlwiQ29hbCByZXNlcnZlc1wifSxcbiAgICB7XCJuYW1lXCI6XCJEaXN0cmljdCBoZWF0aW5nXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkluZHVzdHJ5XCJ9LFxuICAgIHtcIm5hbWVcIjpcIkhlYXRpbmcgYW5kIGNvb2xpbmcgLSBjb21tZXJjaWFsXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkhlYXRpbmcgYW5kIGNvb2xpbmcgLSBob21lc1wifSxcbiAgICB7XCJuYW1lXCI6XCJFbGVjdHJpY2l0eSBncmlkXCJ9LFxuICAgIHtcIm5hbWVcIjpcIk92ZXIgZ2VuZXJhdGlvbiAvIGV4cG9ydHNcIn0sXG4gICAge1wibmFtZVwiOlwiSDIgY29udmVyc2lvblwifSxcbiAgICB7XCJuYW1lXCI6XCJSb2FkIHRyYW5zcG9ydFwifSxcbiAgICB7XCJuYW1lXCI6XCJBZ3JpY3VsdHVyZVwifSxcbiAgICB7XCJuYW1lXCI6XCJSYWlsIHRyYW5zcG9ydFwifSxcbiAgICB7XCJuYW1lXCI6XCJMaWdodGluZyAmIGFwcGxpYW5jZXMgLSBjb21tZXJjaWFsXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkxpZ2h0aW5nICYgYXBwbGlhbmNlcyAtIGhvbWVzXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkdhcyBpbXBvcnRzXCJ9LFxuICAgIHtcIm5hbWVcIjpcIk5nYXNcIn0sXG4gICAge1wibmFtZVwiOlwiR2FzIHJlc2VydmVzXCJ9LFxuICAgIHtcIm5hbWVcIjpcIlRoZXJtYWwgZ2VuZXJhdGlvblwifSxcbiAgICB7XCJuYW1lXCI6XCJHZW90aGVybWFsXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkgyXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkh5ZHJvXCJ9LFxuICAgIHtcIm5hbWVcIjpcIkludGVybmF0aW9uYWwgc2hpcHBpbmdcIn0sXG4gICAge1wibmFtZVwiOlwiRG9tZXN0aWMgYXZpYXRpb25cIn0sXG4gICAge1wibmFtZVwiOlwiSW50ZXJuYXRpb25hbCBhdmlhdGlvblwifSxcbiAgICB7XCJuYW1lXCI6XCJOYXRpb25hbCBuYXZpZ2F0aW9uXCJ9LFxuICAgIHtcIm5hbWVcIjpcIk1hcmluZSBhbGdhZVwifSxcbiAgICB7XCJuYW1lXCI6XCJOdWNsZWFyXCJ9LFxuICAgIHtcIm5hbWVcIjpcIk9pbCBpbXBvcnRzXCJ9LFxuICAgIHtcIm5hbWVcIjpcIk9pbFwifSxcbiAgICB7XCJuYW1lXCI6XCJPaWwgcmVzZXJ2ZXNcIn0sXG4gICAge1wibmFtZVwiOlwiT3RoZXIgd2FzdGVcIn0sXG4gICAge1wibmFtZVwiOlwiUHVtcGVkIGhlYXRcIn0sXG4gICAge1wibmFtZVwiOlwiU29sYXIgUFZcIn0sXG4gICAge1wibmFtZVwiOlwiU29sYXIgVGhlcm1hbFwifSxcbiAgICB7XCJuYW1lXCI6XCJTb2xhclwifSxcbiAgICB7XCJuYW1lXCI6XCJUaWRhbFwifSxcbiAgICB7XCJuYW1lXCI6XCJVSyBsYW5kIGJhc2VkIGJpb2VuZXJneVwifSxcbiAgICB7XCJuYW1lXCI6XCJXYXZlXCJ9LFxuICAgIHtcIm5hbWVcIjpcIldpbmRcIn1cbiAgXSxcbiAgXCJsaW5rc1wiOltcbiAgICB7XCJzb3VyY2VcIjowLFwidGFyZ2V0XCI6MSxcInZhbHVlXCI6MTI0LjcyOX0sXG4gICAge1wic291cmNlXCI6MSxcInRhcmdldFwiOjIsXCJ2YWx1ZVwiOjAuNTk3fSxcbiAgICB7XCJzb3VyY2VcIjoxLFwidGFyZ2V0XCI6MyxcInZhbHVlXCI6MjYuODYyfSxcbiAgICB7XCJzb3VyY2VcIjoxLFwidGFyZ2V0XCI6NCxcInZhbHVlXCI6MjgwLjMyMn0sXG4gICAge1wic291cmNlXCI6MSxcInRhcmdldFwiOjUsXCJ2YWx1ZVwiOjgxLjE0NH0sXG4gICAge1wic291cmNlXCI6NixcInRhcmdldFwiOjIsXCJ2YWx1ZVwiOjM1fSxcbiAgICB7XCJzb3VyY2VcIjo3LFwidGFyZ2V0XCI6NCxcInZhbHVlXCI6MzV9LFxuICAgIHtcInNvdXJjZVwiOjgsXCJ0YXJnZXRcIjo5LFwidmFsdWVcIjoxMS42MDZ9LFxuICAgIHtcInNvdXJjZVwiOjEwLFwidGFyZ2V0XCI6OSxcInZhbHVlXCI6NjMuOTY1fSxcbiAgICB7XCJzb3VyY2VcIjo5LFwidGFyZ2V0XCI6NCxcInZhbHVlXCI6NzUuNTcxfSxcbiAgICB7XCJzb3VyY2VcIjoxMSxcInRhcmdldFwiOjEyLFwidmFsdWVcIjoxMC42Mzl9LFxuICAgIHtcInNvdXJjZVwiOjExLFwidGFyZ2V0XCI6MTMsXCJ2YWx1ZVwiOjIyLjUwNX0sXG4gICAge1wic291cmNlXCI6MTEsXCJ0YXJnZXRcIjoxNCxcInZhbHVlXCI6NDYuMTg0fSxcbiAgICB7XCJzb3VyY2VcIjoxNSxcInRhcmdldFwiOjE2LFwidmFsdWVcIjoxMDQuNDUzfSxcbiAgICB7XCJzb3VyY2VcIjoxNSxcInRhcmdldFwiOjE0LFwidmFsdWVcIjoxMTMuNzI2fSxcbiAgICB7XCJzb3VyY2VcIjoxNSxcInRhcmdldFwiOjE3LFwidmFsdWVcIjoyNy4xNH0sXG4gICAge1wic291cmNlXCI6MTUsXCJ0YXJnZXRcIjoxMixcInZhbHVlXCI6MzQyLjE2NX0sXG4gICAge1wic291cmNlXCI6MTUsXCJ0YXJnZXRcIjoxOCxcInZhbHVlXCI6MzcuNzk3fSxcbiAgICB7XCJzb3VyY2VcIjoxNSxcInRhcmdldFwiOjE5LFwidmFsdWVcIjo0LjQxMn0sXG4gICAge1wic291cmNlXCI6MTUsXCJ0YXJnZXRcIjoxMyxcInZhbHVlXCI6NDAuODU4fSxcbiAgICB7XCJzb3VyY2VcIjoxNSxcInRhcmdldFwiOjMsXCJ2YWx1ZVwiOjU2LjY5MX0sXG4gICAge1wic291cmNlXCI6MTUsXCJ0YXJnZXRcIjoyMCxcInZhbHVlXCI6Ny44NjN9LFxuICAgIHtcInNvdXJjZVwiOjE1LFwidGFyZ2V0XCI6MjEsXCJ2YWx1ZVwiOjkwLjAwOH0sXG4gICAge1wic291cmNlXCI6MTUsXCJ0YXJnZXRcIjoyMixcInZhbHVlXCI6OTMuNDk0fSxcbiAgICB7XCJzb3VyY2VcIjoyMyxcInRhcmdldFwiOjI0LFwidmFsdWVcIjo0MC43MTl9LFxuICAgIHtcInNvdXJjZVwiOjI1LFwidGFyZ2V0XCI6MjQsXCJ2YWx1ZVwiOjgyLjIzM30sXG4gICAge1wic291cmNlXCI6NSxcInRhcmdldFwiOjEzLFwidmFsdWVcIjowLjEyOX0sXG4gICAge1wic291cmNlXCI6NSxcInRhcmdldFwiOjMsXCJ2YWx1ZVwiOjEuNDAxfSxcbiAgICB7XCJzb3VyY2VcIjo1LFwidGFyZ2V0XCI6MjYsXCJ2YWx1ZVwiOjE1MS44OTF9LFxuICAgIHtcInNvdXJjZVwiOjUsXCJ0YXJnZXRcIjoxOSxcInZhbHVlXCI6Mi4wOTZ9LFxuICAgIHtcInNvdXJjZVwiOjUsXCJ0YXJnZXRcIjoxMixcInZhbHVlXCI6NDguNTh9LFxuICAgIHtcInNvdXJjZVwiOjI3LFwidGFyZ2V0XCI6MTUsXCJ2YWx1ZVwiOjcuMDEzfSxcbiAgICB7XCJzb3VyY2VcIjoxNyxcInRhcmdldFwiOjI4LFwidmFsdWVcIjoyMC44OTd9LFxuICAgIHtcInNvdXJjZVwiOjE3LFwidGFyZ2V0XCI6MyxcInZhbHVlXCI6Ni4yNDJ9LFxuICAgIHtcInNvdXJjZVwiOjI4LFwidGFyZ2V0XCI6MTgsXCJ2YWx1ZVwiOjIwLjg5N30sXG4gICAge1wic291cmNlXCI6MjksXCJ0YXJnZXRcIjoxNSxcInZhbHVlXCI6Ni45OTV9LFxuICAgIHtcInNvdXJjZVwiOjIsXCJ0YXJnZXRcIjoxMixcInZhbHVlXCI6MTIxLjA2Nn0sXG4gICAge1wic291cmNlXCI6MixcInRhcmdldFwiOjMwLFwidmFsdWVcIjoxMjguNjl9LFxuICAgIHtcInNvdXJjZVwiOjIsXCJ0YXJnZXRcIjoxOCxcInZhbHVlXCI6MTM1LjgzNX0sXG4gICAge1wic291cmNlXCI6MixcInRhcmdldFwiOjMxLFwidmFsdWVcIjoxNC40NTh9LFxuICAgIHtcInNvdXJjZVwiOjIsXCJ0YXJnZXRcIjozMixcInZhbHVlXCI6MjA2LjI2N30sXG4gICAge1wic291cmNlXCI6MixcInRhcmdldFwiOjE5LFwidmFsdWVcIjozLjY0fSxcbiAgICB7XCJzb3VyY2VcIjoyLFwidGFyZ2V0XCI6MzMsXCJ2YWx1ZVwiOjMzLjIxOH0sXG4gICAge1wic291cmNlXCI6MixcInRhcmdldFwiOjIwLFwidmFsdWVcIjo0LjQxM30sXG4gICAge1wic291cmNlXCI6MzQsXCJ0YXJnZXRcIjoxLFwidmFsdWVcIjoxNC4zNzV9LFxuICAgIHtcInNvdXJjZVwiOjI0LFwidGFyZ2V0XCI6NSxcInZhbHVlXCI6MTIyLjk1Mn0sXG4gICAge1wic291cmNlXCI6MzUsXCJ0YXJnZXRcIjoyNixcInZhbHVlXCI6ODM5Ljk3OH0sXG4gICAge1wic291cmNlXCI6MzYsXCJ0YXJnZXRcIjozNyxcInZhbHVlXCI6NTA0LjI4N30sXG4gICAge1wic291cmNlXCI6MzgsXCJ0YXJnZXRcIjozNyxcInZhbHVlXCI6MTA3LjcwM30sXG4gICAge1wic291cmNlXCI6MzcsXCJ0YXJnZXRcIjoyLFwidmFsdWVcIjo2MTEuOTl9LFxuICAgIHtcInNvdXJjZVwiOjM5LFwidGFyZ2V0XCI6NCxcInZhbHVlXCI6NTYuNTg3fSxcbiAgICB7XCJzb3VyY2VcIjozOSxcInRhcmdldFwiOjEsXCJ2YWx1ZVwiOjc3LjgxfSxcbiAgICB7XCJzb3VyY2VcIjo0MCxcInRhcmdldFwiOjE0LFwidmFsdWVcIjoxOTMuMDI2fSxcbiAgICB7XCJzb3VyY2VcIjo0MCxcInRhcmdldFwiOjEzLFwidmFsdWVcIjo3MC42NzJ9LFxuICAgIHtcInNvdXJjZVwiOjQxLFwidGFyZ2V0XCI6MTUsXCJ2YWx1ZVwiOjU5LjkwMX0sXG4gICAge1wic291cmNlXCI6NDIsXCJ0YXJnZXRcIjoxNCxcInZhbHVlXCI6MTkuMjYzfSxcbiAgICB7XCJzb3VyY2VcIjo0MyxcInRhcmdldFwiOjQyLFwidmFsdWVcIjoxOS4yNjN9LFxuICAgIHtcInNvdXJjZVwiOjQzLFwidGFyZ2V0XCI6NDEsXCJ2YWx1ZVwiOjU5LjkwMX0sXG4gICAge1wic291cmNlXCI6NCxcInRhcmdldFwiOjE5LFwidmFsdWVcIjowLjg4Mn0sXG4gICAge1wic291cmNlXCI6NCxcInRhcmdldFwiOjI2LFwidmFsdWVcIjo0MDAuMTJ9LFxuICAgIHtcInNvdXJjZVwiOjQsXCJ0YXJnZXRcIjoxMixcInZhbHVlXCI6NDYuNDc3fSxcbiAgICB7XCJzb3VyY2VcIjoyNixcInRhcmdldFwiOjE1LFwidmFsdWVcIjo1MjUuNTMxfSxcbiAgICB7XCJzb3VyY2VcIjoyNixcInRhcmdldFwiOjMsXCJ2YWx1ZVwiOjc4Ny4xMjl9LFxuICAgIHtcInNvdXJjZVwiOjI2LFwidGFyZ2V0XCI6MTEsXCJ2YWx1ZVwiOjc5LjMyOX0sXG4gICAge1wic291cmNlXCI6NDQsXCJ0YXJnZXRcIjoxNSxcInZhbHVlXCI6OS40NTJ9LFxuICAgIHtcInNvdXJjZVwiOjQ1LFwidGFyZ2V0XCI6MSxcInZhbHVlXCI6MTgyLjAxfSxcbiAgICB7XCJzb3VyY2VcIjo0NixcInRhcmdldFwiOjE1LFwidmFsdWVcIjoxOS4wMTN9LFxuICAgIHtcInNvdXJjZVwiOjQ3LFwidGFyZ2V0XCI6MTUsXCJ2YWx1ZVwiOjI4OS4zNjZ9XG4gIF1cbn07XG4iLCIvKipcbiAqIENvcHlyaWdodCAyMDEyLTIwMTcsIFBsb3RseSwgSW5jLlxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqL1xuXG4vL3ZhciBkMyA9IHJlcXVpcmUoJ2QzJyk7XG52YXIgZDNzYW5rZXkgPSByZXF1aXJlKCcuL2QzLXNhbmtleScpO1xuXG52YXIgZGF0YSA9IHJlcXVpcmUoJy4vZW5lcmd5Jyk7XG5cbnZhciB3aWR0aCA9IDk2MDtcbnZhciBoZWlnaHQgPSA1MDA7XG52YXIgbWFyZ2luID0ge1xuICBsOiAyMCxcbiAgdDogMjAsXG4gIHI6IDIwMCxcbiAgYjogMjBcbn07XG5cbnZhciBjID0ge1xuICBub2RlVGV4dE9mZnNldDogNSxcbiAgbm9kZVdpZHRoOiAxNSxcbiAgbm9kZVBhZGRpbmc6IDE0LFxuICBzYW5rZXlJdGVyYXRpb25zOiA3MDAsXG4gIHZlcnRpY2FsOiBmYWxzZSxcbiAgbm9kZU9wYWNpdHk6IDAuNyxcbiAgbm9kZVNhbGllbnRPcGFjaXR5OiAxLFxuICBsaW5rT3BhY2l0eTogMC4yLFxuICBsaW5rU2FsaWVudE9wYWNpdHk6IDAuNFxufTtcblxuZnVuY3Rpb24ga2V5RnVuKGQpIHtyZXR1cm4gZC5rZXk7fVxuXG5mdW5jdGlvbiByZXBlYXQoZCkge3JldHVybiBbZF07fVxuXG5mdW5jdGlvbiBub29wKCkge31cblxuZnVuY3Rpb24gdmlld01vZGVsKHNhbmtleSkge1xuXG4gIHJldHVybiB7XG4gICAga2V5OiAwLFxuICAgIHRyYW5zbGF0ZVg6IG1hcmdpbi5sLFxuICAgIHRyYW5zbGF0ZVk6IG1hcmdpbi50LFxuICAgIGRyYWdMZW5ndGg6IGMudmVydGljYWwgPyB3aWR0aCA6IGhlaWdodCxcbiAgICBub2Rlczogc2Fua2V5Lm5vZGVzKCksXG4gICAgbGlua3M6IHNhbmtleS5saW5rcygpLFxuICAgIHNhbmtleTogc2Fua2V5XG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlbmRlcihzdmcsIGNhbGxiYWNrcykge1xuICByZXR1cm4gZnVuY3Rpb24oc2Fua2V5KSB7XG5cbiAgICB2YXIgZHJhZ0luUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgICB2YXIgaG92ZXJlZCA9IGZhbHNlO1xuXG4gICAgZnVuY3Rpb24gYXR0YWNoUG9pbnRlckV2ZW50cyhzZWxlY3Rpb24sIGV2ZW50U2V0KSB7XG4gICAgICBzZWxlY3Rpb25cbiAgICAgICAgLm9uKCdtb3VzZW92ZXInLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgIGlmICghZHJhZ0luUHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGV2ZW50U2V0LmhvdmVyKHRoaXMsIGQpO1xuICAgICAgICAgICAgaG92ZXJlZCA9IFt0aGlzLCBkXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pXG4gICAgICAgIC5vbignbW91c2VvdXQnLCBmdW5jdGlvbiAoZCkge1xuICAgICAgICAgIGlmICghZHJhZ0luUHJvZ3Jlc3MpIHtcbiAgICAgICAgICAgIGV2ZW50U2V0LnVuaG92ZXIodGhpcywgZCk7XG4gICAgICAgICAgICBob3ZlcmVkID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgICAub24oJ2NsaWNrJywgZnVuY3Rpb24gKGQpIHtcbiAgICAgICAgICBpZiAoaG92ZXJlZCkge1xuICAgICAgICAgICAgZXZlbnRTZXQudW5ob3Zlcih0aGlzLCBkKTtcbiAgICAgICAgICAgIGhvdmVyZWQgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKCFkcmFnSW5Qcm9ncmVzcykge1xuICAgICAgICAgICAgZXZlbnRTZXQuc2VsZWN0KHRoaXMsIGQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGlua1BhdGgoZCkge1xuICAgICAgcmV0dXJuIGQuc2Fua2V5LmxpbmsoKShkLmxpbmspO1xuICAgIH1cblxuICAgIHZhciBjb2xvcmVyID0gZDMuc2NhbGUuY2F0ZWdvcnkyMCgpO1xuXG4gICAgdmFyIHNhbmtleSA9IHN2Zy5zZWxlY3RBbGwoJy5zYW5rZXknKVxuICAgICAgLmRhdGEoW3ZpZXdNb2RlbChzYW5rZXkpXSwga2V5RnVuKTtcblxuICAgIHNhbmtleS5lbnRlcigpXG4gICAgICAuYXBwZW5kKCdnJylcbiAgICAgIC5jbGFzc2VkKCdzYW5rZXknLCB0cnVlKVxuICAgICAgLmF0dHIoJ292ZXJmbG93JywgJ3Zpc2libGUnKVxuICAgICAgLnN0eWxlKCdib3gtc2l6aW5nJywgJ2NvbnRlbnQtYm94JylcbiAgICAgIC5zdHlsZSgncG9zaXRpb24nLCAnYWJzb2x1dGUnKVxuICAgICAgLnN0eWxlKCdsZWZ0JywgMClcbiAgICAgIC5zdHlsZSgnb3ZlcmZsb3cnLCAndmlzaWJsZScpXG4gICAgICAuc3R5bGUoJ3NoYXBlLXJlbmRlcmluZycsICdnZW9tZXRyaWNQcmVjaXNpb24nKVxuICAgICAgLnN0eWxlKCdwb2ludGVyLWV2ZW50cycsICdhdXRvJylcbiAgICAgIC5zdHlsZSgnYm94LXNpemluZycsICdjb250ZW50LWJveCcpO1xuXG4gICAgc2Fua2V5XG4gICAgICAuYXR0cigndHJhbnNmb3JtJywgZnVuY3Rpb24oZCkge1xuICAgICAgICByZXR1cm4gJ3RyYW5zbGF0ZSgnICsgZC50cmFuc2xhdGVYICsgJywnICsgZC50cmFuc2xhdGVZICsgJyknO1xuICAgICAgfSk7XG5cbiAgICB2YXIgc2Fua2V5TGlua3MgPSBzYW5rZXkuc2VsZWN0QWxsKCcuc2Fua2V5TGlua3MnKVxuICAgICAgLmRhdGEocmVwZWF0LCBrZXlGdW4pO1xuXG4gICAgc2Fua2V5TGlua3MuZW50ZXIoKVxuICAgICAgLmFwcGVuZCgnZycpXG4gICAgICAuY2xhc3NlZCgnc2Fua2V5TGlua3MnLCB0cnVlKVxuICAgICAgLnN0eWxlKCd0cmFuc2Zvcm0nLCBjLnZlcnRpY2FsID8gJ21hdHJpeCgwLDEsMSwwLDAsMCknIDogJ21hdHJpeCgxLDAsMCwxLDAsMCknKVxuICAgICAgLnN0eWxlKCdmaWxsJywgJ25vbmUnKVxuICAgICAgLnN0eWxlKCdzdHJva2UnLCAnYmxhY2snKVxuICAgICAgLnN0eWxlKCdzdHJva2Utb3BhY2l0eScsIGMubGlua09wYWNpdHkpO1xuXG4gICAgdmFyIHNhbmtleUxpbmsgPSBzYW5rZXlMaW5rcy5zZWxlY3RBbGwoJy5zYW5rZXlQYXRoJylcbiAgICAgIC5kYXRhKGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgcmV0dXJuIGQuc2Fua2V5LmxpbmtzKCkubWFwKGZ1bmN0aW9uKGwpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbGluazogbCxcbiAgICAgICAgICAgIHNhbmtleTogZC5zYW5rZXlcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgc2Fua2V5TGluay5lbnRlcigpXG4gICAgICAuYXBwZW5kKCdwYXRoJylcbiAgICAgIC5jbGFzc2VkKCdzYW5rZXlQYXRoJywgdHJ1ZSlcbiAgICAgIC5jYWxsKGF0dGFjaFBvaW50ZXJFdmVudHMsIGNhbGxiYWNrcy5saW5rRXZlbnRzKTtcblxuICAgIHNhbmtleUxpbmtcbiAgICAgIC5hdHRyKCdkJywgbGlua1BhdGgpXG4gICAgICAuc3R5bGUoJ3N0cm9rZS13aWR0aCcsIGZ1bmN0aW9uKGQpIHtyZXR1cm4gTWF0aC5tYXgoMSwgZC5saW5rLmR5KTt9KTtcblxuICAgIHZhciBzYW5rZXlOb2RlcyA9IHNhbmtleS5zZWxlY3RBbGwoJy5zYW5rZXlOb2RlcycpXG4gICAgICAuZGF0YShyZXBlYXQsIGtleUZ1bik7XG5cbiAgICBzYW5rZXlOb2Rlcy5lbnRlcigpXG4gICAgICAuYXBwZW5kKCdnJylcbiAgICAgIC5zdHlsZSgnc2hhcGUtcmVuZGVyaW5nJywgJ2NyaXNwRWRnZXMnKVxuICAgICAgLmNsYXNzZWQoJ3NhbmtleU5vZGVzJywgdHJ1ZSk7XG5cbiAgICB2YXIgc2Fua2V5Tm9kZSA9IHNhbmtleU5vZGVzLnNlbGVjdEFsbCgnLnNhbmtleU5vZGUnKVxuICAgICAgLmRhdGEoZnVuY3Rpb24oZCkge1xuICAgICAgICByZXR1cm4gZC5zYW5rZXkubm9kZXMoKS5tYXAoZnVuY3Rpb24obCkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBub2RlOiBsLFxuICAgICAgICAgICAgc2Fua2V5OiBkLnNhbmtleSxcbiAgICAgICAgICAgIG1vZGVsOiBkXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICB9LCBmdW5jdGlvbihkKSB7cmV0dXJuIGQubm9kZS5uYW1lO30pO1xuXG4gICAgc2Fua2V5Tm9kZS5lbnRlcigpXG4gICAgICAuYXBwZW5kKCdnJylcbiAgICAgIC5jbGFzc2VkKCdzYW5rZXlOb2RlJywgdHJ1ZSlcbiAgICAgIC5jYWxsKGQzLmJlaGF2aW9yLmRyYWcoKVxuICAgICAgICAub3JpZ2luKGZ1bmN0aW9uKGQpIHtyZXR1cm4gYy52ZXJ0aWNhbCA/IHt4OiBkLm5vZGUueX0gOiBkLm5vZGU7fSlcbiAgICAgICAgLm9uKCdkcmFnc3RhcnQnLCBmdW5jdGlvbihkKSB7XG4gICAgICAgICAgZC5ub2RlLmRyYWdTdGFydExvY2F0aW9uID0gYy52ZXJ0aWNhbCA/IGQzLmV2ZW50LnggOiBkMy5ldmVudC55O1xuICAgICAgICAgIHRoaXMucGFyZW50Tm9kZS5hcHBlbmRDaGlsZCh0aGlzKTtcbiAgICAgICAgICBkcmFnSW5Qcm9ncmVzcyA9IHRydWU7XG4gICAgICAgICAgaWYoaG92ZXJlZCkge1xuICAgICAgICAgICAgLy9jYWxsYmFja3Mubm9kZUV2ZW50cy51bmhvdmVyLmFwcGx5KDAsIGhvdmVyZWQpO1xuICAgICAgICAgICAgaG92ZXJlZCA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICAgLm9uKCdkcmFnJywgZnVuY3Rpb24oZCkge1xuICAgICAgICAgICAgaWYoYy52ZXJ0aWNhbCkge1xuICAgICAgICAgICAgICBkLm5vZGUueSA9IE1hdGgubWF4KDAsIE1hdGgubWluKGQubW9kZWwuZHJhZ0xlbmd0aCAtIGQubm9kZS5keSwgZDMuZXZlbnQueCkpO1xuICAgICAgICAgICAgICBkMy5zZWxlY3QodGhpcykuc3R5bGUoJ3RyYW5zZm9ybScsICd0cmFuc2xhdGUoJyArIGQubm9kZS55ICsgJ3B4LCcgKyBkLm5vZGUueCArICdweCknKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGQubm9kZS55ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oZC5tb2RlbC5kcmFnTGVuZ3RoIC0gZC5ub2RlLmR5LCBkMy5ldmVudC55KSk7XG4gICAgICAgICAgICAgIGQzLnNlbGVjdCh0aGlzKS5zdHlsZSgndHJhbnNmb3JtJywgJ3RyYW5zbGF0ZSgnICsgZC5ub2RlLnggKyAncHgsJyArIGQubm9kZS55ICsgJ3B4KScpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBkLnNhbmtleS5yZWxheW91dCgpO1xuICAgICAgICAgICAgc2Fua2V5TGluay5hdHRyKCdkJywgbGlua1BhdGgpO1xuICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgICAgICAub24oJ2RyYWdlbmQnLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBkcmFnSW5Qcm9ncmVzcyA9IGZhbHNlO1xuICAgICAgICB9KSk7XG5cbiAgICBzYW5rZXlOb2RlXG4gICAgICAuc3R5bGUoJ3RyYW5zZm9ybScsIGMudmVydGljYWwgP1xuICAgICAgICBmdW5jdGlvbihkKSB7cmV0dXJuICd0cmFuc2xhdGUoJyArIChNYXRoLmZsb29yKGQubm9kZS55KSAtIDAuNSkgKyAncHgsICcgKyAoTWF0aC5mbG9vcihkLm5vZGUueCkgKyAwLjUpICsgJ3B4KSc7fSA6XG4gICAgICAgIGZ1bmN0aW9uKGQpIHtyZXR1cm4gJ3RyYW5zbGF0ZSgnICsgKE1hdGguZmxvb3IoZC5ub2RlLngpIC0gMC41KSArICdweCwgJyArIChNYXRoLmZsb29yKGQubm9kZS55KSArIDAuNSkgKyAncHgpJzt9KTtcblxuICAgIHZhciBub2RlUmVjdCA9IHNhbmtleU5vZGUuc2VsZWN0QWxsKCcubm9kZVJlY3QnKVxuICAgICAgLmRhdGEocmVwZWF0KTtcblxuICAgIG5vZGVSZWN0LmVudGVyKClcbiAgICAgIC5hcHBlbmQoJ3JlY3QnKVxuICAgICAgLmNsYXNzZWQoJ25vZGVSZWN0JywgdHJ1ZSlcbiAgICAgIC5zdHlsZSgnc2hhcGUtcmVuZGVyaW5nJywgJ2NyaXNwRWRnZXMnKVxuICAgICAgLnN0eWxlKCdmaWxsJywgZnVuY3Rpb24oZCkge3JldHVybiBjb2xvcmVyKGQuc2Fua2V5Lm5vZGVzKCkuaW5kZXhPZihkLm5vZGUpKTt9KVxuICAgICAgLnN0eWxlKCdzdHJva2Utd2lkdGgnLCAwLjUpXG4gICAgICAuc3R5bGUoJ3N0cm9rZScsICdibGFjaycpXG4gICAgICAuc3R5bGUoJ3N0cm9rZS1vcGFjaXR5JywgMSlcbiAgICAgIC5zdHlsZSgnZmlsbC1vcGFjaXR5JywgYy5ub2RlT3BhY2l0eSlcbiAgICAgIC5jYWxsKGF0dGFjaFBvaW50ZXJFdmVudHMsIGNhbGxiYWNrcy5ub2RlRXZlbnRzKTtcblxuICAgIG5vZGVSZWN0IC8vIGNlaWwsICsvLTAuNSBhbmQgY3Jpc3BFZGdlcyBpcyB3aXphcmRyeSBmb3IgY29uc2lzdGVudCBib3JkZXIgd2lkdGggb24gYWxsIDQgc2lkZXNcbiAgICAgIC5hdHRyKGMudmVydGljYWwgPyAnaGVpZ2h0JyA6ICd3aWR0aCcsIGZ1bmN0aW9uKGQpIHtyZXR1cm4gTWF0aC5jZWlsKGQubm9kZS5keCArIDAuNSk7fSlcbiAgICAgIC5hdHRyKGMudmVydGljYWwgPyAnd2lkdGgnIDogJ2hlaWdodCcsIGZ1bmN0aW9uKGQpIHtyZXR1cm4gTWF0aC5jZWlsKGQubm9kZS5keSAtIDAuNSk7fSk7XG5cbiAgICB2YXIgbm9kZUxhYmVsID0gc2Fua2V5Tm9kZS5zZWxlY3RBbGwoJy5ub2RlTGFiZWwnKVxuICAgICAgLmRhdGEocmVwZWF0KTtcblxuICAgIG5vZGVMYWJlbC5lbnRlcigpXG4gICAgICAuYXBwZW5kKCd0ZXh0JylcbiAgICAgIC5jbGFzc2VkKCdub2RlTGFiZWwnLCB0cnVlKTtcblxuICAgIG5vZGVMYWJlbFxuICAgICAgLmF0dHIoJ3gnLCBmdW5jdGlvbihkKSB7cmV0dXJuIGMudmVydGljYWwgPyBkLm5vZGUuZHkgLyAyIDogZC5ub2RlLmR4ICsgYy5ub2RlVGV4dE9mZnNldDt9KVxuICAgICAgLmF0dHIoJ3knLCBmdW5jdGlvbihkKSB7cmV0dXJuIGMudmVydGljYWwgPyBkLm5vZGUuZHggLyAyIDogZC5ub2RlLmR5IC8gMjt9KVxuICAgICAgLnRleHQoZnVuY3Rpb24oZCkge3JldHVybiBkLm5vZGUubmFtZTt9KVxuICAgICAgLmF0dHIoJ2FsaWdubWVudC1iYXNlbGluZScsICdtaWRkbGUnKVxuICAgICAgLmF0dHIoJ3RleHQtYW5jaG9yJywgYy52ZXJ0aWNhbCA/ICdtaWRkbGUnIDogJ3N0YXJ0JylcbiAgICAgIC5zdHlsZSgnZm9udC1mYW1pbHknLCAnc2Fucy1zZXJpZicpXG4gICAgICAuc3R5bGUoJ2ZvbnQtc2l6ZScsICcxMHB4Jyk7XG4gIH07XG59O1xuXG52YXIgc3ZnID0gZDMuc2VsZWN0KCdib2R5JykuYXBwZW5kKCdzdmcnKVxuICAuYXR0cignd2lkdGgnLCB3aWR0aCArIG1hcmdpbi5sICsgbWFyZ2luLnIpXG4gIC5hdHRyKCdoZWlnaHQnLCBoZWlnaHQgKyBtYXJnaW4udCArIG1hcmdpbi5iKTtcblxudmFyIHJlbmRlcmVyID0gcmVuZGVyKHN2Zywge1xuICBsaW5rRXZlbnRzOiB7XG4gICAgaG92ZXI6IGZ1bmN0aW9uKGUsIGwpIHtcbiAgICAgIGQzLnNlbGVjdEFsbCgnLm5vZGVSZWN0JylcbiAgICAgICAgLmZpbHRlcihmdW5jdGlvbihuKSB7cmV0dXJuIG4ubm9kZS5uYW1lID09PSBsLmxpbmsuc291cmNlLm5hbWUgfHwgbi5ub2RlLm5hbWUgPT09IGwubGluay50YXJnZXQubmFtZTt9KVxuICAgICAgICAuc3R5bGUoJ2ZpbGwtb3BhY2l0eScsIGMubm9kZVNhbGllbnRPcGFjaXR5KTtcbiAgICAgIGQzLnNlbGVjdChlKS5zdHlsZSgnc3Ryb2tlLW9wYWNpdHknLCBjLmxpbmtTYWxpZW50T3BhY2l0eSk7XG4gICAgfSxcbiAgICB1bmhvdmVyOiBmdW5jdGlvbihlLCBkKSB7XG4gICAgICBkMy5zZWxlY3RBbGwoJy5ub2RlUmVjdCcpLnN0eWxlKCdmaWxsLW9wYWNpdHknLCBjLm5vZGVPcGFjaXR5KTtcbiAgICAgIGQzLnNlbGVjdChlKS5zdHlsZSgnc3Ryb2tlLW9wYWNpdHknLCBjLmxpbmtPcGFjaXR5KTtcbiAgICB9LFxuICAgIHNlbGVjdDogbm9vcFxuICB9LFxuICBub2RlRXZlbnRzOiB7XG4gICAgaG92ZXI6IGZ1bmN0aW9uKGUsIG4pIHtcbiAgICAgIGQzLnNlbGVjdEFsbCgnLnNhbmtleVBhdGgnKVxuICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uKGwpIHtyZXR1cm4gbi5ub2RlLm5hbWUgPT09IGwubGluay5zb3VyY2UubmFtZSB8fCBuLm5vZGUubmFtZSA9PT0gbC5saW5rLnRhcmdldC5uYW1lO30pXG4gICAgICAgIC5zdHlsZSgnc3Ryb2tlLW9wYWNpdHknLCBjLmxpbmtTYWxpZW50T3BhY2l0eSk7XG4gICAgICBkMy5zZWxlY3QoZSkuc3R5bGUoJ2ZpbGwtb3BhY2l0eScsIGMubm9kZVNhbGllbnRPcGFjaXR5KTtcbiAgICB9LFxuICAgIHVuaG92ZXI6IGZ1bmN0aW9uKGUsIGQpIHtcbiAgICAgIGQzLnNlbGVjdEFsbCgnLnNhbmtleVBhdGgnKS5zdHlsZSgnc3Ryb2tlLW9wYWNpdHknLCBjLmxpbmtPcGFjaXR5KTtcbiAgICAgIGQzLnNlbGVjdChlKS5zdHlsZSgnZmlsbC1vcGFjaXR5JywgYy5ub2RlT3BhY2l0eSk7XG4gICAgfSxcbiAgICBzZWxlY3Q6IG5vb3BcbiAgfVxufSk7XG5cbmQzc2Fua2V5KClcbiAgLnNpemUoYy52ZXJ0aWNhbCA/IFtoZWlnaHQsIHdpZHRoXTogW3dpZHRoLCBoZWlnaHRdKVxuICAubm9kZVdpZHRoKGMubm9kZVdpZHRoKVxuICAubm9kZVBhZGRpbmcoYy5ub2RlUGFkZGluZylcbiAgLm5vZGVzKGRhdGEubm9kZXMpXG4gIC5saW5rcyhkYXRhLmxpbmtzKVxuICAubGF5b3V0KGMuc2Fua2V5SXRlcmF0aW9ucywgcmVuZGVyZXIpOyJdfQ== |
|
|
|
|
|
</script> |
|
</body> |