<!DOCTYPE html>
<
meta name="viewport" content="width=device-width, initial-scale=1.0">
html,
body {
margin: 0px;
height: 100%;
font-family: Verdana, sans-serif;
}
.divtopmost {
width: 100%;
height: 100%;
background-color: #eee;
color: #252c30;
}
.split {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow-y: auto;
overflow-x: hidden;
background-color: inherit;
}
.gutter {
background-color: #ddd;
background-repeat: no-repeat;
background-position: 50%;
transition: background-color 0.3s;
}
.split.split-horizontal {
height: 100%;
float: left;
}
.gutter.gutter-horizontal {
height: 100%;
float: left;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
cursor: col-resize;
}
.gutter.gutter-vertical {
width: 100%;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=');
cursor: row-resize;
}
#divtop {
height: 78px;
border-bottom: 2px solid black;
}
.boardinfo {
width: 100%;
height: 100%;
border: none;
padding: 5px;
}
.boardinfo td {
overflow: hidden;
white-space: nowrap;
width: 50%;
text-align: center;
text-overflow: ellipsis;
}
.boardinfo .title {
font-size: 20pt;
font-weight: bold;
}
.boardinfo .variant {
font-size: 14pt;
color: #888;
display: none;
}
/* bom table */
.bom {
border-collapse: collapse;
font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
font-size: 10pt;
table-layout: fixed;
width: 100%;
margin-top: 1px;
}
.bom th,
.bom td {
border: 1px solid black;
padding: 5px;
word-wrap: break-word;
text-align: center;
position: relative;
}
.bom th {
background-color: #CCCCCC;
background-clip: padding-box;
cursor: pointer;
}
.bom tr {
transition: background-color 0.2s;
}
.bom tr:nth-child(even) {
background-color: #f2f2f2;
}
.bom tr.active:nth-child(n) {
background-color: #00abff;
color: #eee;
font-weight: bold;
}
.bom tr.active:nth-child(even) {
background-color: #00abff;
color: #eee;
font-weight: bold;
}
.bom .active {
background-color: #00abff;
color: #eee;
font-weight: bold;
}
.bom tr.checked {
color: #aaa;
}
.bom .numcol {
width: 25px;
}
.bom .bom-checkbox {
width: 50px;
position: relative;
user-select: none;
-moz-user-select: none;
}
.bom .bom-checkbox:before {
content: "";
position: absolute;
border-width: 15px;
border-style: solid;
border-color: #51829f transparent transparent transparent;
visibility: hidden;
top: -15px;
}
.bom .bom-checkbox:after {
content: "Double click to set/unset all";
position: absolute;
color: white;
top: -35px;
left: -26px;
background: #51829f;
padding: 5px 15px;
border-radius: 8px;
white-space: nowrap;
visibility: hidden;
}
.bom .value {
width: 15%;
}
.bom .quantity {
width: 65px;
}
.bom .placed {
font-size: 8pt;
color: #b87333;
display: inline;
}
/* prefs menu */
.prefs_menu {
position: relative;
display: inline-block;
margin: 10px 10px 10px 0px;
}
.prefs_menu:hover {
display: block;
background-color: #eee;
}
.prefs_menubtn {
background-color: white;
border: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 20 20'%3E%3Cpath fill='none' d='M0 0h20v20H0V0z'/%3E%3Cpath d='M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z'/%3E%3C/svg%3E%0A");
background-position: center;
background-repeat: no-repeat;
}
.prefs_menu_content {
display: none;
position: absolute;
background-color: white;
right: 0;
min-width: 300px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 100;
padding: 8px;
}
.prefs_menu:hover .prefs_menubtn {
background-color: #eee;
}
.prefs_menu:hover .prefs_menu_content {
display: block;
}
.prefs_menu_label {
display: inline-block;
padding: 8px;
border: 1px solid #ccc;
border-top: 0;
width: calc(100% - 18px);
}
.prefs_menu_label_top {
border-top: 1px solid #ccc;
}
.version {
float: right;
font-size: 10pt;
color: #888;
}
.slider {
width: 100%;
}
/* buttons menu */
.button_container {
font-size: 0;
margin: 10px 10px 10px 0px;
}
button {
background-color: #eee;
border: 1px solid #888;
color: black;
height: 44px;
width: 44px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
font-weight: bolder;
}
button:focus {
outline: 0;
}
button.selected {
background-color: #007bff;
color: white;
}
.button_container button {
background-size: 32px 32px;
background-position: 5px 5px;
background-repeat: no-repeat;
}
.left_most_button {
border-right: 0;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
.middle_button {
border-right: 0;
}
.right_most_button {
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
/* canvas */
canvas {
cursor: crosshair;
}
canvas:active {
cursor: grabbing;
}
/* nets */
.net_inverse {
text-decoration: overline;
}
<
div id="divtopmost" class="divtopmost">
<
div style="float: right; height: 100%;">
<!-- prefs menu -->
<
div class="prefs_menu" style="float: right; top: 8px;">
<
div class="prefs_menu_content">
<!-- display -->
<
div class="prefs_menu_label prefs_menu_label_top">
<
div style="text-align: center; margin-bottom: 4px;">Display<
/div>
<
label class="prefs_menu_label prefs_menu_label_top">
<
input id="cbDisplayAssy" type="checkbox" onchange="setDisplayAssy(this.checked)" checked>
<
label class="prefs_menu_label">
<
input id="cbDisplaySilk" type="checkbox" onchange="setDisplaySilk(this.checked)" checked>
<
label class="prefs_menu_label">
<
input id="cbDisplayNets" type="checkbox" onchange="setDisplayNets(this.checked)" checked>
<
label class="prefs_menu_label">
<
input id="cbDisplayCopperPours" type="checkbox" onchange="setDisplayCopperPours(this.checked)">
<
label for="cbDisplayCopperPours">Copper Pours<
/label>
<
label class="prefs_menu_label">
<
input id="cbDisplayFiducials" type="checkbox" onchange="setDisplayFiducials(this.checked)" checked>
<
label class="prefs_menu_label">
<
input id="cbDisplayPads" type="checkbox" onchange="setDisplayPads(this.checked)" checked>
<
label class="prefs_menu_label">
<
input id="cbDisplayVias" type="checkbox" onchange="setDisplayVias(this.checked)" checked>
<
label class="prefs_menu_label">
<
input id="cbDisplaySuppliers" type="checkbox" onchange="setDisplaySuppliers(this.checked)" checked>
<!-- board rotation -->
<
div class="prefs_menu_label">
<
input id="boardRotation" class="slider" type="range" min
="-36" max
="36" value="0" oninput
="setBoardRotation(this.value)" onchange="setBoardRotation(this.value)">
<
div class="prefs_menu_label">
<!-- canvas layout menu -->
<
div class="button_container" style="float: right; position: relative; top: 8px">
<
button id="btnCanvasTop" class="left_most_button" onclick="changeCanvasLayout('T')" title="Top Only">T<
/button>
<
button id="btnCanvasTopBottom" class="middle_button selected" onclick="changeCanvasLayout('TB')" title="Top and Bottom">TB<
/button>
<
button id="btnCanvasBottom" class="right_most_button" onclick="changeCanvasLayout('B')" title="Bottom Only">B<
/button>
<!-- bom layout menu -->
<
div class="button_container" style="float: right; position: relative; top: 8px">
<
button id="btnBOMOnly" class="left_most_button" onclick="changeBOMLayout('bom-only')" title="BOM Only">BOM<
/button>
<
button id="btnBOMLeftRight" class="middle_button" onclick="changeBOMLayout('left-right')" title="BOM - Left, Drawing - Right">LR<
/button>
<
button id="btnBOMTopBottom" class="right_most_button" onclick="changeBOMLayout('top-bottom')" title="BOM - Top, Drawing - Bottom">TB<
/button>
<!-- bom group menu -->
<
div class="button_container" style="float: right; position: relative; top: 8px">
<
button id="btnGUngroup" class="left_most_button selected" onclick="changeBomGroup('U')" title="Ungroup">U<
/button>
<
button id="btnGNetlist" class="middle_button" onclick="changeBomGroup('NL')" title="Netlist">NL<
/button>
<
button id="btnGName" class="middle_button" onclick="changeBomGroup('N')" title="Component Name">N<
/button>
<
button id="btnGNameValue" class="middle_button" onclick="changeBomGroup('NV')" title="Component Name and Value">NV<
/button>
<
button id="btnGNamePattern" class="middle_button" onclick="changeBomGroup('NP')" title="Component Name and Pattern">NP<
/button>
<
button id="btnGNameValuePattern" class="right_most_button" onclick="changeBomGroup('NVP')" title="Component Name, Value and Pattern">NVP<
/button>
<
div id="boardinfo" style="height: 100%; overflow: auto;">
<
table class="boardinfo">
<
td id="board_name" class="title"><
/td>
<
td id="assembly_variant" class="variant"><
/td>
<
div id="divbottom" class="split" style="height: calc(100% - 80px);">
<
div id="divbom" class="split split-horizontal" style="width: calc(50% - 3px);">
<!-- search -->
<
div style="width: 100%;"><
/div>
<!-- table -->
<
th class="bom-checkbox">Placed<
/th>
<
th class="value">Value<
/th>
<
th class="quantity">Quantity<
/th>
<
div class="gutter gutter-horizontal" style="width: 6px;"><
/div>
<
div id="divcanvas" class="split split-horizontal" style="width: calc(50% - 3px);">
<
div id="topcanvas" class="split" touch-
action="none" style="overflow: hidden; height: calc(50% - 3px);">
<
div style="position: relative; width: 100%; height: 100%;">
<canvas id="topBG" style="position: absolute; left: 0px; top: 0px; z-index: 0; width: 800px; height: 600px;" width="800" height="600"></canvas>
<canvas id="topSILK" style="position: absolute; left: 0px; top: 0px; z-index: 1; width: 800px; height: 600px;" width="800" height="600"></canvas>
<canvas id="topASSY" style="position: absolute; left: 0px; top: 0px; z-index: 2; width: 800px; height: 600px;" width="800" height="600"></canvas>
<canvas id="topHL" style="position: absolute; left: 0px; top: 0px; z-index: 3; width: 800px; height: 600px;" width="800" height="600"></canvas>
<
div class="gutter gutter-vertical" style="height: 6px;"><
/div>
<
div id="bottomcanvas" class="split" touch-
action="none" style="overflow: hidden; height: calc(50% - 3px);">
<
div style="position: relative; width: 100%; height: 100%;">
<canvas id="bottomBG" style="position: absolute; left: 0px; top: 0px; z-index: 0; width: 800px; height: 600px;" width="800" height="600"></canvas>
<canvas id="bottomSILK" style="position: absolute; left: 0px; top: 0px; z-index: 1; width: 800px; height: 600px;" width="800" height="600"></canvas>
<canvas id="bottomASSY" style="position: absolute; left: 0px; top: 0px; z-index: 2; width: 800px; height: 600px;" width="800" height="600"></canvas>
<canvas id="bottomHL" style="position: absolute; left: 0px; top: 0px; z-index: 3; width: 800px; height: 600px;" width="800" height="600"></canvas>
<
script type="text/javascript">
/*--- 3D party ---*/
/* Split.js - v1.6.2 MIT License https://github.com/nathancahill/Split.js */
! function(e, t) {
"object" == typeof exports && "undefined" != typeof module ? module.exports = t() : "function" == typeof define && define.amd ? define(t) : (e = e || self).Split = t()
}(this, (function() {
"use strict";
var e = "undefined" != typeof window ? window : null,
t = null === e,
n = t ? void 0 : e.document,
i = function() {
return !1
},
r = t ? "calc" : ["", "-webkit-", "-moz-", "-o-"].filter((function(e) {
var t = n.createElement("div");
return t.style.cssText = "width:" + e + "calc(9px)", !!t.style.length
})).shift() + "calc",
s = function(e) {
return "string" == typeof e || e instanceof String
},
o = function(e) {
if (s(e)) {
var t = n.querySelector(e);
if (!t) throw new Error("Selector " + e + " did not match a DOM element");
return t
}
return e
},
a = function(e, t, n) {
var i = e[t];
return void 0 !== i ? i : n
},
u = function(e, t, n, i) {
if (t) {
if ("end" === i) return 0;
if ("center" === i) return e / 2
} else if (n) {
if ("start" === i) return 0;
if ("center" === i) return e / 2
}
return e
},
l = function(e, t) {
var i = n.createElement("div");
return i.className = "gutter gutter-" + t, i
},
c = function(e, t, n) {
var i = {};
return s(t) ? i[e] = t : i[e] = r + "(" + t + "% - " + n + "px)", i
},
h = function(e, t) {
var n;
return (n = {})[e] = t + "px", n
};
return function(r, s) {
if (void 0 === s && (s = {}), t) return {};
var d, f, v, m, g, p, y = r;
Array.from && (y = Array.from(y));
var z = o(y[0]).parentNode,
b = getComputedStyle ? getComputedStyle(z) : null,
E = b ? b.flexDirection : null,
S = a(s, "sizes") || y.map((function() {
return 100 / y.length
})),
L = a(s, "minSize", 100),
_ = Array.isArray(L) ? L : y.map((function() {
return L
})),
w = a(s, "expandToMin", !1),
k = a(s, "gutterSize", 10),
x = a(s, "gutterAlign", "center"),
C = a(s, "snapOffset", 30),
M = a(s, "dragInterval", 1),
U = a(s, "direction", "horizontal"),
O = a(s, "cursor", "horizontal" === U ? "col-resize" : "row-resize"),
D = a(s, "gutter", l),
A = a(s, "elementStyle", c),
B = a(s, "gutterStyle", h);
function j(e, t, n, i) {
var r = A(d, t, n, i);
Object.keys(r).forEach((function(t) {
e.style[t] = r[t]
}))
}
function F() {
return p.map((function(e) {
return e.size
}))
}
function R(e) {
return "touches" in e ? e.touches[0][f] : e[f]
}
function T(e) {
var t = p[this.a],
n = p[this.b],
i = t.size + n.size;
t.size = e / this.size * i, n.size = i - e / this.size * i, j(t.element, t.size, this._b, t.i), j(n.element, n.size, this._c, n.i)
}
function N(e) {
var t, n = p[this.a],
r = p[this.b];
this.dragging && (t = R(e) - this.start + (this._b - this.dragOffset), M > 1 && (t = Math.round(t / M) * M), t <= n.minSize + C + this._b ? t = n.minSize + this._b : t >= this.size - (r.minSize + C + this._c) && (t = this.size - (r.minSize + this._c)), T.call(this, t), a(s, "onDrag", i)(F()))
}
function q() {
var e = p[this.a].element,
t = p[this.b].element,
n = e.getBoundingClientRect(),
i = t.getBoundingClientRect();
this.size = n[d] + i[d] + this._b + this._c, this.start = n[v], this.end = n[m]
}
function H(e) {
var t = function(e) {
if (!getComputedStyle) return null;
var t = getComputedStyle(e);
if (!t) return null;
var n = e[g];
return 0 === n ? null : n -= "horizontal" === U ? parseFloat(t.paddingLeft) + parseFloat(t.paddingRight) : parseFloat(t.paddingTop) + parseFloat(t.paddingBottom)
}(z);
if (null === t) return e;
if (_.reduce((function(e, t) {
return e + t
}), 0) > t) return e;
var n = 0,
i = [],
r = e.map((function(r, s) {
var o = t * r / 100,
a = u(k, 0 === s, s === e.length - 1, x),
l = _[s] + a;
return o < l ? (n += l - o, i.push(0), l) : (i.push(o - l), o)
}));
return 0 === n ? e : r.map((function(e, r) {
var s = e;
if (n > 0 && i[r] - n > 0) {
var o = Math.min(n, i[r] - n);
n -= o, s = e - o
}
return s / t * 100
}))
}
function I() {
var t = p[this.a].element,
r = p[this.b].element;
this.dragging && a(s, "onDragEnd", i)(F()), this.dragging = !1, e.removeEventListener("mouseup", this.stop), e.removeEventListener("touchend", this.stop), e.removeEventListener("touchcancel", this.stop), e.removeEventListener("mousemove", this.move), e.removeEventListener("touchmove", this.move), this.stop = null, this.move = null, t.removeEventListener("selectstart", i), t.removeEventListener("dragstart", i), r.removeEventListener("selectstart", i), r.removeEventListener("dragstart", i), t.style.userSelect = "", t.style.webkitUserSelect = "", t.style.MozUserSelect = "", t.style.pointerEvents = "", r.style.userSelect = "", r.style.webkitUserSelect = "", r.style.MozUserSelect = "", r.style.pointerEvents = "", this.gutter.style.cursor = "", this.parent.style.cursor = "", n.body.style.cursor = ""
}
function W(t) {
if (!("button" in t) || 0 === t.button) {
var r = p[this.a].element,
o = p[this.b].element;
this.dragging || a(s, "onDragStart", i)(F()), t.preventDefault(), this.dragging = !0, this.move = N.bind(this), this.stop = I.bind(this), e.addEventListener("mouseup", this.stop), e.addEventListener("touchend", this.stop), e.addEventListener("touchcancel", this.stop), e.addEventListener("mousemove", this.move), e.addEventListener("touchmove", this.move), r.addEventListener("selectstart", i), r.addEventListener("dragstart", i), o.addEventListener("selectstart", i), o.addEventListener("dragstart", i), r.style.userSelect = "none", r.style.webkitUserSelect = "none", r.style.MozUserSelect = "none", r.style.pointerEvents = "none", o.style.userSelect = "none", o.style.webkitUserSelect = "none", o.style.MozUserSelect = "none", o.style.pointerEvents = "none", this.gutter.style.cursor = O, this.parent.style.cursor = O, n.body.style.cursor = O, q.call(this), this.dragOffset = R(t) - this.end
}
}
"horizontal" === U ? (d = "width", f = "clientX", v = "left", m = "right", g = "clientWidth") : "vertical" === U && (d = "height", f = "clientY", v = "top", m = "bottom", g = "clientHeight"), S = H(S);
var X = [];
function Y(e) {
var t = e.i === X.length,
n = t ? X[e.i - 1] : X[e.i];
q.call(n);
var i = t ? n.size - e.minSize - n._c : e.minSize + n._b;
T.call(n, i)
}
return (p = y.map((function(e, t) {
var n, i = {
element: o(e),
size: S[t],
minSize: _[t],
i: t
};
if (t > 0 && ((n = {
a: t - 1,
b: t,
dragging: !1,
direction: U,
parent: z
})._b = u(k, t - 1 == 0, !1, x), n._c = u(k, !1, t === y.length - 1, x), "row-reverse" === E || "column-reverse" === E)) {
var r = n.a;
n.a = n.b, n.b = r
}
if (t > 0) {
var s = D(t, U, i.element);
! function(e, t, n) {
var i = B(d, t, n);
Object.keys(i).forEach((function(t) {
e.style[t] = i[t]
}))
}(s, k, t), n._a = W.bind(n), s.addEventListener("mousedown", n._a), s.addEventListener("touchstart", n._a), z.insertBefore(s, i.element), n.gutter = s
}
return j(i.element, i.size, u(k, 0 === t, t === y.length - 1, x), t), t > 0 && X.push(n), i
}))).forEach((function(e) {
var t = e.element.getBoundingClientRect()[d];
t < e.minSize && (w ? Y(e) : e.minSize = t)
})), {
setSizes: function(e) {
var t = H(e);
t.forEach((function(e, n) {
if (n > 0) {
var i = X[n - 1],
r = p[i.a],
s = p[i.b];
r.size = t[n - 1], s.size = e, j(r.element, r.size, i._b, r.i), j(s.element, s.size, i._c, s.i)
}
}))
},
getSizes: F,
collapse: function(e) {
Y(p[e])
},
destroy: function(e, t) {
X.forEach((function(n) {
if (!0 !== t ? n.parent.removeChild(n.gutter) : (n.gutter.removeEventListener("mousedown", n._a), n.gutter.removeEventListener("touchstart", n._a)), !0 !== e) {
var i = A(d, n.a.size, n._b);
Object.keys(i).forEach((function(e) {
p[n.a].element.style[e] = "", p[n.b].element.style[e] = ""
}))
}
}))
},
parent: z,
pairs: X
}
}
}));
// Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>
// This work is free. You can redistribute it and/or modify it
// under the terms of the WTFPL, Version 2
// For more information see LICENSE.txt or http://www.wtfpl.net/
// For more information, the home page:
// http://pieroxy.net/blog/pages/lz-string/testing.html
// LZ-based compression algorithm, version 1.4.4
var LZString = function() {
function o(o, r) {
if (!t[o]) {
t[o] = {};
for (var n = 0; n < o.length; n++) t[o][o.charAt(n)] = n
}
return t[o][r]
}
var r = String.fromCharCode,
n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",
t = {},
i = {
compressToBase64: function(o) {
if (null == o) return "";
var r = i._compress(o, 6, function(o) {
return n.charAt(o)
});
switch (r.length % 4) {
default:
case 0:
return r;
case 1:
return r + "===";
case 2:
return r + "==";
case 3:
return r + "="
}
},
decompressFromBase64: function(r) {
return null == r ? "" : "" == r ? null : i._decompress(r.length, 32, function(e) {
return o(n, r.charAt(e))
})
},
compressToUTF16: function(o) {
return null == o ? "" : i._compress(o, 15, function(o) {
return r(o + 32)
}) + " "
},
decompressFromUTF16: function(o) {
return null == o ? "" : "" == o ? null : i._decompress(o.length, 16384, function(r) {
return o.charCodeAt(r) - 32
})
},
compressToUint8Array: function(o) {
for (var r = i.compress(o), n = new Uint8Array(2 * r.length), e = 0, t = r.length; t > e; e++) {
var s = r.charCodeAt(e);
n[2 * e] = s >>> 8, n[2 * e + 1] = s % 256
}
return n
},
decompressFromUint8Array: function(o) {
if (null === o || void 0 === o) return i.decompress(o);
for (var n = new Array(o.length / 2), e = 0, t = n.length; t > e; e++) n[e] = 256 * o[2 * e] + o[2 * e + 1];
var s = [];
return n.forEach(function(o) {
s.push(r(o))
}), i.decompress(s.join(""))
},
compressToEncodedURIComponent: function(o) {
return null == o ? "" : i._compress(o, 6, function(o) {
return e.charAt(o)
})
},
decompressFromEncodedURIComponent: function(r) {
return null == r ? "" : "" == r ? null : (r = r.replace(/ /g, "+"), i._decompress(r.length, 32, function(n) {
return o(e, r.charAt(n))
}))
},
compress: function(o) {
return i._compress(o, 16, function(o) {
return r(o)
})
},
_compress: function(o, r, n) {
if (null == o) return "";
var e, t, i, s = {},
p = {},
u = "",
c = "",
a = "",
l = 2,
f = 3,
h = 2,
d = [],
m = 0,
v = 0;
for (i = 0; i < o.length; i += 1)
if (u = o.charAt(i), Object.prototype.hasOwnProperty.call(s, u) || (s[u] = f++, p[u] = !0), c = a + u, Object.prototype.hasOwnProperty.call(s, c)) a = c;
else {
if (Object.prototype.hasOwnProperty.call(p, a)) {
if (a.charCodeAt(0) < 256) {
for (e = 0; h > e; e++) m <<= 1, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++;
for (t = a.charCodeAt(0), e = 0; 8 > e; e++) m = m << 1 | 1 & t, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++, t >>= 1
} else {
for (t = 1, e = 0; h > e; e++) m = m << 1 | t, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++, t = 0;
for (t = a.charCodeAt(0), e = 0; 16 > e; e++) m = m << 1 | 1 & t, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++, t >>= 1
}
l--, 0 == l && (l = Math.pow(2, h), h++), delete p[a]
} else
for (t = s[a], e = 0; h > e; e++) m = m << 1 | 1 & t, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++, t >>= 1;
l--, 0 == l && (l = Math.pow(2, h), h++), s[c] = f++, a = String(u)
}
if ("" !== a) {
if (Object.prototype.hasOwnProperty.call(p, a)) {
if (a.charCodeAt(0) < 256) {
for (e = 0; h > e; e++) m <<= 1, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++;
for (t = a.charCodeAt(0), e = 0; 8 > e; e++) m = m << 1 | 1 & t, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++, t >>= 1
} else {
for (t = 1, e = 0; h > e; e++) m = m << 1 | t, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++, t = 0;
for (t = a.charCodeAt(0), e = 0; 16 > e; e++) m = m << 1 | 1 & t, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++, t >>= 1
}
l--, 0 == l && (l = Math.pow(2, h), h++), delete p[a]
} else
for (t = s[a], e = 0; h > e; e++) m = m << 1 | 1 & t, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++, t >>= 1;
l--, 0 == l && (l = Math.pow(2, h), h++)
}
for (t = 2, e = 0; h > e; e++) m = m << 1 | 1 & t, v == r - 1 ? (v = 0, d.push(n(m)), m = 0) : v++, t >>= 1;
for (;;) {
if (m <<= 1, v == r - 1) {
d.push(n(m));
break
}
v++
}
return d.join("")
},
decompress: function(o) {
return null == o ? "" : "" == o ? null : i._decompress(o.length, 32768, function(r) {
return o.charCodeAt(r)
})
},
_decompress: function(o, n, e) {
var t, i, s, p, u, c, a, l, f = [],
h = 4,
d = 4,
m = 3,
v = "",
w = [],
A = {
val: e(0),
position: n,
index: 1
};
for (i = 0; 3 > i; i += 1) f[i] = i;
for (p = 0, c = Math.pow(2, 2), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
switch (t = p) {
case 0:
for (p = 0, c = Math.pow(2, 8), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
l = r(p);
break;
case 1:
for (p = 0, c = Math.pow(2, 16), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
l = r(p);
break;
case 2:
return ""
}
for (f[3] = l, s = l, w.push(l);;) {
if (A.index > o) return "";
for (p = 0, c = Math.pow(2, m), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
switch (l = p) {
case 0:
for (p = 0, c = Math.pow(2, 8), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
f[d++] = r(p), l = d - 1, h--;
break;
case 1:
for (p = 0, c = Math.pow(2, 16), a = 1; a != c;) u = A.val & A.position, A.position >>= 1, 0 == A.position && (A.position = n, A.val = e(A.index++)), p |= (u > 0 ? 1 : 0) * a, a <<= 1;
f[d++] = r(p), l = d - 1, h--;
break;
case 2:
return w.join("")
}
if (0 == h && (h = Math.pow(2, m), m++), f[l]) v = f[l];
else {
if (l !== d) return null;
v = s + s.charAt(0)
}
w.push(v), f[d++] = s + v.charAt(0), h--, s = v, 0 == h && (h = Math.pow(2, m), m++)
}
}
};
return i
}();
"function" == typeof define && define.amd ? define(function() {
return LZString
}) : "undefined" != typeof module && null != module && (module.exports = LZString);
// canvas polyfill
(function(_0x58f57c, _0x2fa52d) {
if (_0x58f57c == undefined) {
_0x58f57c = _0x2fa52d('canvas')['Context2d'];
}
if (_0x58f57c['prototype']['ellipse'] == undefined) {
_0x58f57c['prototype']['ellipse'] = function(_0x251577, _0x4bf590, _0x3e8b2e, _0x2e7f82, _0x73bb7e, _0x102d04, _0x223dfa, _0x5270a4) {
this['save']();
this['translate'](_0x251577, _0x4bf590);
this['rotate'](_0x73bb7e);
this['scale'](_0x3e8b2e, _0x2e7f82);
this['arc'](0x0, 0x0, 0x1, _0x102d04, _0x223dfa, _0x5270a4);
this['restore']();
};
}
if (typeof Path2D !== 'function' || typeof new Path2D()['addPath'] !== 'function') {
(function() {
parser = function() {
function _0x222e3c(_0x4a67da, _0x23272f) {
function _0x5dcaef() {
this['constructor'] = _0x4a67da;
}
_0x5dcaef['prototype'] = _0x23272f['prototype'];
_0x4a67da['prototype'] = new _0x5dcaef();
}
function _0x4cc4a9(_0x128787, _0x229f0e, _0x18f31a, _0x39d3f2, _0x400682, _0x436a2b) {
this['message'] = _0x128787;
this['expected'] = _0x229f0e;
this['found'] = _0x18f31a;
this['offset'] = _0x39d3f2;
this['line'] = _0x400682;
this['column'] = _0x436a2b;
this['name'] = 'SyntaxError';
}
_0x222e3c(_0x4cc4a9, Error);
function _0x4b296c(_0x3a6242) {
var _0xf95720 = arguments['length'] > 0x1 ? arguments[0x1] : {},
_0x4e763b = {},
_0x520ba4 = {
'svg_path': _0x19a2be
},
_0x3c91de = _0x19a2be,
_0x56093a = _0x4e763b,
_0x4c69bd = [],
_0x375d49 = null,
_0x46920b = function(_0x1e3596) {
return _0x65b89a;
},
_0x1f3890 = /^[Mm]/,
_0x5cb2e6 = {
'type': 'class',
'value': '[Mm]',
'description': '[Mm]'
},
_0x24a516 = function(_0x472687, _0x3a73b5) {
var _0x1798ed = _0x472687;
if (_0x52dd75) {
_0x1798ed = 'M';
_0x52dd75 = ![];
}
_0x65b89a['push']({
'type': 'moveTo',
'args': _0x17d776(_0x1798ed, _0x3a73b5[0x0])
});
for (var _0x2881fb = 0x1; _0x2881fb < _0x3a73b5['length']; _0x2881fb++) {
_0x65b89a['push']({
'type': 'lineTo',
'args': _0x17d776(_0x472687, _0x3a73b5[_0x2881fb])
});
}
},
_0x5e38d7 = function(_0x5cb700, _0x5cd47f) {
return _0x4ab5ce(_0x5cb700, _0x5cd47f);
},
_0x387727 = /^[Zz]/,
_0x2868a8 = {
'type': 'class',
'value': '[Zz]',
'description': '[Zz]'
},
_0x594869 = function() {
_0x65b89a['push']({
'type': 'closePath',
'args': []
});
},
_0x589f3b = /^[Ll]/,
_0x2d2081 = {
'type': 'class',
'value': '[Ll]',
'description': '[Ll]'
},
_0x50849d = function(_0x6f1c73, _0x4201ff) {
for (var _0x1ab8fa = 0x0; _0x1ab8fa < _0x4201ff['length']; _0x1ab8fa++) {
_0x65b89a['push']({
'type': 'lineTo',
'args': _0x17d776(_0x6f1c73, _0x4201ff[_0x1ab8fa])
});
}
},
_0x4c4628 = /^[Hh]/,
_0x36aa8b = {
'type': 'class',
'value': '[Hh]',
'description': '[Hh]'
},
_0x487dce = function(_0x2be630, _0x27cbf1) {
for (var _0x3497a6 = 0x0; _0x3497a6 < _0x27cbf1['length']; _0x3497a6++) {
_0x65b89a['push']({
'type': 'lineTo',
'args': _0x1134cf(_0x2be630, _0x27cbf1[_0x3497a6])
});
}
},
_0x2f8fdc = /^[Vv]/,
_0x391e28 = {
'type': 'class',
'value': '[Vv]',
'description': '[Vv]'
},
_0x2fb111 = function(_0x4a057b, _0x5752df) {
for (var _0x1d8aa8 = 0x0; _0x1d8aa8 < _0x5752df['length']; _0x1d8aa8++) {
_0x65b89a['push']({
'type': 'lineTo',
'args': _0x5b73e4(_0x4a057b, _0x5752df[_0x1d8aa8])
});
}
},
_0x4a4882 = /^[Cc]/,
_0x1371ac = {
'type': 'class',
'value': '[Cc]',
'description': '[Cc]'
},
_0x51b1f6 = function(_0x591e86, _0x47c797) {
for (var _0x414596 = 0x0; _0x414596 < _0x47c797['length']; _0x414596++) {
_0x65b89a['push']({
'type': 'bezierCurveTo',
'args': _0x54e14f(_0x591e86, _0x47c797[_0x414596])
});
}
},
_0xe1e1 = function(_0x503c00, _0x3cb31d, _0x4fcedc) {
return _0x503c00['concat'](_0x3cb31d, _0x4fcedc);
},
_0x3c0d2e = /^[Ss]/,
_0x394135 = {
'type': 'class',
'value': '[Ss]',
'description': '[Ss]'
},
_0x4aa6f7 = function(_0xbe6c5c, _0xfe5f70) {
for (var _0x1ad248 = 0x0; _0x1ad248 < _0xfe5f70['length']; _0x1ad248++) {
_0x65b89a['push']({
'type': 'bezierCurveTo',
'args': _0x2d262a()['concat'](_0x54e14f(_0xbe6c5c, _0xfe5f70[_0x1ad248]))
});
}
},
_0x30c615 = function(_0x7d0b66, _0x20da34) {
return _0x7d0b66['concat'](_0x20da34);
},
_0x3a67c6 = /^[Qq]/,
_0x85b933 = {
'type': 'class',
'value': '[Qq]',
'description': '[Qq]'
},
_0x3ceb0a = function(_0x50f7bd, _0x497820) {
for (var _0x50f9ef = 0x0; _0x50f9ef < _0x497820['length']; _0x50f9ef++) {
_0x65b89a['push']({
'type': 'quadraticCurveTo',
'args': _0x54e14f(_0x50f7bd, _0x497820[_0x50f9ef])
});
}
},
_0x543bea = /^[Tt]/,
_0x16de6e = {
'type': 'class',
'value': '[Tt]',
'description': '[Tt]'
},
_0x207488 = function(_0x301f77, _0x27fec5) {
for (var _0xacff90 = 0x0; _0xacff90 < _0x27fec5['length']; _0xacff90++) {
var _0x5a46f5 = _0x2d262a();
_0x65b89a['push']({
'type': 'quadraticCurveTo',
'args': _0x5a46f5['concat'](_0x54e14f(_0x301f77, _0x27fec5[_0xacff90]))
});
_0x594746 = _0x5a46f5['slice'](0x0);
}
},
_0xd18715 = /^[Aa]/,
_0x30a6b0 = {
'type': 'class',
'value': '[Aa]',
'description': '[Aa]'
},
_0xbeac27 = function(_0x2ee17b, _0x33cbf9) {
for (var _0x56c3b5 = 0x0; _0x56c3b5 < _0x33cbf9['length']; _0x56c3b5++) {
var _0x1c894f = [_0x5b0427['slice']()];
var _0x1b27e1 = [_0x17d776(_0x2ee17b, _0x33cbf9[_0x56c3b5]['slice'](-0x2))];
absArgs = _0x1c894f['concat'](_0x33cbf9[_0x56c3b5]['slice'](0x0, -0x2), _0x1b27e1);
_0x42a62a['apply'](this, absArgs);
}
},
_0x2cbb71 = function(_0x7dca7a, _0x218490, _0x59acec, _0x3327e6, _0x497542, _0x1953dc) {
return [parseFloat(_0x7dca7a), parseFloat(_0x218490), parseFloat(_0x4eee96(_0x59acec)['join']('')), parseInt(_0x3327e6), parseInt(_0x497542), _0x1953dc[0x0], _0x1953dc[0x1]];
},
_0x201fa4 = function(_0x2ea5f3, _0x3e9760) {
return [_0x2ea5f3, _0x3e9760];
},
_0x5a72e5 = function(_0x49c77a) {
return parseFloat(_0x4eee96(_0x49c77a)['join'](''));
},
_0x444dd7 = '0',
_0x44e46d = {
'type': 'literal',
'value': '0',
'description': '\x220\x22'
},
_0x8b2ec9 = '1',
_0x2bab45 = {
'type': 'literal',
'value': '1',
'description': '\x221\x22'
},
_0x5b6dde = ',',
_0x3d3d23 = {
'type': 'literal',
'value': ',',
'description': '\x22,\x22'
},
_0x57d0b1 = '.',
_0x3e764 = {
'type': 'literal',
'value': '.',
'description': '\x22.\x22'
},
_0x1e3f99 = /^[eE]/,
_0x1123fe = {
'type': 'class',
'value': '[eE]',
'description': '[eE]'
},
_0x59832c = '+',
_0x423117 = {
'type': 'literal',
'value': '+',
'description': '\x22+\x22'
},
_0xf5aaab = '-',
_0x198f27 = {
'type': 'literal',
'value': '-',
'description': '\x22-\x22'
},
_0x1d19eb = /^[0-9]/,
_0x2a6cc4 = {
'type': 'class',
'value': '[0-9]',
'description': '[0-9]'
},
_0x3a87d5 = function(_0x48bf53) {
return _0x48bf53['join']('');
},
_0x15ce60 = /^[ \t\n\r]/,
_0x41f84b = {
'type': 'class',
'value': '[\x20\x5ct\x5cn\x5cr]',
'description': '[\x20\x5ct\x5cn\x5cr]'
},
_0x3e408e = 0x0,
_0x55bc2f = 0x0,
_0x5f2f07 = 0x0,
_0x482c66 = {
'line': 0x1,
'column': 0x1,
'seenCR': ![]
},
_0x7dbbe5 = 0x0,
_0x1fda2f = [],
_0x15e012 = 0x0,
_0x2bfff2;
if ('startRule' in _0xf95720) {
if (!(_0xf95720['startRule'] in _0x520ba4)) {
throw new Error('Can\x27t\x20start\x20parsing\x20from\x20rule\x20\x22' + _0xf95720['startRule'] + '\x22.');
}
_0x3c91de = _0x520ba4[_0xf95720['startRule']];
}
function _0x55e6ee() {
return _0x3a6242['substring'](_0x55bc2f, _0x3e408e);
}
function _0x34aa85() {
return _0x55bc2f;
}
function _0x83f5f7() {
return _0x3d95d5(_0x55bc2f)['line'];
}
function _0x299bb3() {
return _0x3d95d5(_0x55bc2f)['column'];
}
function _0x5f591f(_0x3c65e8) {
throw _0x2f901a(null, [{
'type': 'other',
'description': _0x3c65e8
}], _0x55bc2f);
}
function _0x5038a9(_0x1ed506) {
throw _0x2f901a(_0x1ed506, null, _0x55bc2f);
}
function _0x3d95d5(_0x4f850f) {
function _0x122f48(_0x20a115, _0x56c31b, _0x20288c) {
var _0x448ad8, _0x62a2a1;
for (_0x448ad8 = _0x56c31b; _0x448ad8 < _0x20288c; _0x448ad8++) {
_0x62a2a1 = _0x3a6242['charAt'](_0x448ad8);
if (_0x62a2a1 === '\x0a') {
if (!_0x20a115['seenCR']) {
_0x20a115['line']++;
}
_0x20a115['column'] = 0x1;
_0x20a115['seenCR'] = ![];
} else if (_0x62a2a1 === '\x0d' || _0x62a2a1 === '\u2028' || _0x62a2a1 === '\u2029') {
_0x20a115['line']++;
_0x20a115['column'] = 0x1;
_0x20a115['seenCR'] = !![];
} else {
_0x20a115['column']++;
_0x20a115['seenCR'] = ![];
}
}
}
if (_0x5f2f07 !== _0x4f850f) {
if (_0x5f2f07 > _0x4f850f) {
_0x5f2f07 = 0x0;
_0x482c66 = {
'line': 0x1,
'column': 0x1,
'seenCR': ![]
};
}
_0x122f48(_0x482c66, _0x5f2f07, _0x4f850f);
_0x5f2f07 = _0x4f850f;
}
return _0x482c66;
}
function _0x569314(_0x1bd4d0) {
if (_0x3e408e < _0x7dbbe5) {
return;
}
if (_0x3e408e > _0x7dbbe5) {
_0x7dbbe5 = _0x3e408e;
_0x1fda2f = [];
}
_0x1fda2f['push'](_0x1bd4d0);
}
function _0x2f901a(_0x13e6a0, _0xf91d3e, _0x3c913f) {
function _0x2e97b2(_0x24c9dd) {
var _0xba4eba = 0x1;
_0x24c9dd['sort'](function(_0x15643f, _0x7b7e06) {
if (_0x15643f['description'] < _0x7b7e06['description']) {
return -0x1;
} else if (_0x15643f['description'] > _0x7b7e06['description']) {
return 0x1;
} else {
return 0x0;
}
});
while (_0xba4eba < _0x24c9dd['length']) {
if (_0x24c9dd[_0xba4eba - 0x1] === _0x24c9dd[_0xba4eba]) {
_0x24c9dd['splice'](_0xba4eba, 0x1);
} else {
_0xba4eba++;
}
}
}
function _0x208340(_0x31e3aa, _0x2d3db5) {
function _0x1f97e3(_0x12ebdf) {
function _0x1a1dba(_0x4783bd) {
return _0x4783bd['charCodeAt'](0x0)['toString'](0x10)['toUpperCase']();
}
return _0x12ebdf['replace'](/\\/g, '\x5c\x5c')['replace'](/"/g, '\x5c\x22')['replace'](/\x08/g, '\x5cb')['replace'](/\t/g, '\x5ct')['replace'](/\n/g, '\x5cn')['replace'](/\f/g, '\x5cf')['replace'](/\r/g, '\x5cr')['replace'](/[\x00-\x07\x0B\x0E\x0F]/g, function(_0x4d0809) {
return '\x5cx0' + _0x1a1dba(_0x4d0809);
})['replace'](/[\x10-\x1F\x80-\xFF]/g, function(_0xf5b428) {
return '\x5cx' + _0x1a1dba(_0xf5b428);
})['replace'](/[\u0180-\u0FFF]/g, function(_0x25ab64) {
return '\x5cu0' + _0x1a1dba(_0x25ab64);
})['replace'](/[\u1080-\uFFFF]/g, function(_0x23b97b) {
return '\x5cu' + _0x1a1dba(_0x23b97b);
});
}
var _0x280d62 = new Array(_0x31e3aa['length']),
_0x1be497, _0x350d25, _0xc094de;
for (_0xc094de = 0x0; _0xc094de < _0x31e3aa['length']; _0xc094de++) {
_0x280d62[_0xc094de] = _0x31e3aa[_0xc094de]['description'];
}
_0x1be497 = _0x31e3aa['length'] > 0x1 ? _0x280d62['slice'](0x0, -0x1)['join'](',\x20') + '\x20or\x20' + _0x280d62[_0x31e3aa['length'] - 0x1] : _0x280d62[0x0];
_0x350d25 = _0x2d3db5 ? '\x22' + _0x1f97e3(_0x2d3db5) + '\x22' : 'end\x20of\x20input';
return 'Expected\x20' + _0x1be497 + '\x20but\x20' + _0x350d25 + '\x20found.';
}
var _0x28c2cf = _0x3d95d5(_0x3c913f),
_0x3a7d1a = _0x3c913f < _0x3a6242['length'] ? _0x3a6242['charAt'](_0x3c913f) : null;
if (_0xf91d3e !== null) {
_0x2e97b2(_0xf91d3e);
}
return new _0x4cc4a9(_0x13e6a0 !== null ? _0x13e6a0 : _0x208340(_0xf91d3e, _0x3a7d1a), _0xf91d3e, _0x3a7d1a, _0x3c913f, _0x28c2cf['line'], _0x28c2cf['column']);
}
function _0x19a2be() {
var _0xce07fa, _0x4a404b, _0x27603b, _0x5a3f6a, _0x1e5b9e;
_0xce07fa = _0x3e408e;
_0x4a404b = [];
_0x27603b = _0x553f5b();
while (_0x27603b !== _0x4e763b) {
_0x4a404b['push'](_0x27603b);
_0x27603b = _0x553f5b();
}
if (_0x4a404b !== _0x4e763b) {
_0x27603b = _0x3b76e1();
if (_0x27603b === _0x4e763b) {
_0x27603b = _0x375d49;
}
if (_0x27603b !== _0x4e763b) {
_0x5a3f6a = [];
_0x1e5b9e = _0x553f5b();
while (_0x1e5b9e !== _0x4e763b) {
_0x5a3f6a['push'](_0x1e5b9e);
_0x1e5b9e = _0x553f5b();
}
if (_0x5a3f6a !== _0x4e763b) {
_0x55bc2f = _0xce07fa;
_0x4a404b = _0x46920b(_0x27603b);
_0xce07fa = _0x4a404b;
} else {
_0x3e408e = _0xce07fa;
_0xce07fa = _0x56093a;
}
} else {
_0x3e408e = _0xce07fa;
_0xce07fa = _0x56093a;
}
} else {
_0x3e408e = _0xce07fa;
_0xce07fa = _0x56093a;
}
return _0xce07fa;
}
function _0x3b76e1() {
var _0x35b597, _0x3e84a3, _0x1f9f3d, _0x105cd4, _0x55d3ab;
_0x35b597 = _0x3e408e;
_0x3e84a3 = _0x1da102();
if (_0x3e84a3 !== _0x4e763b) {
_0x1f9f3d = _0x3e408e;
_0x105cd4 = [];
_0x55d3ab = _0x553f5b();
while (_0x55d3ab !== _0x4e763b) {
_0x105cd4['push'](_0x55d3ab);
_0x55d3ab = _0x553f5b();
}
if (_0x105cd4 !== _0x4e763b) {
_0x55d3ab = _0x3b76e1();
if (_0x55d3ab !== _0x4e763b) {
_0x105cd4 = [_0x105cd4, _0x55d3ab];
_0x1f9f3d = _0x105cd4;
} else {
_0x3e408e = _0x1f9f3d;
_0x1f9f3d = _0x56093a;
}
} else {
_0x3e408e = _0x1f9f3d;
_0x1f9f3d = _0x56093a;
}
if (_0x1f9f3d === _0x4e763b) {
_0x1f9f3d = _0x375d49;
}
if (_0x1f9f3d !== _0x4e763b) {
_0x3e84a3 = [_0x3e84a3, _0x1f9f3d];
_0x35b597 = _0x3e84a3;
} else {
_0x3e408e = _0x35b597;
_0x35b597 = _0x56093a;
}
} else {
_0x3e408e = _0x35b597;
_0x35b597 = _0x56093a;
}
return _0x35b597;
}
function _0x1da102() {
var _0x3876a5, _0x233bbe, _0x1c2791, _0x4e689d, _0x22482a;
_0x3876a5 = _0x3e408e;
_0x233bbe = _0x893e26();
if (_0x233bbe !== _0x4e763b) {
_0x1c2791 = _0x3e408e;
_0x4e689d = [];
_0x22482a = _0x553f5b();
while (_0x22482a !== _0x4e763b) {
_0x4e689d['push'](_0x22482a);
_0x22482a = _0x553f5b();
}
if (_0x4e689d !== _0x4e763b) {
_0x22482a = _0x12b906();
if (_0x22482a !== _0x4e763b) {
_0x4e689d = [_0x4e689d, _0x22482a];
_0x1c2791 = _0x4e689d;
} else {
_0x3e408e = _0x1c2791;
_0x1c2791 = _0x56093a;
}
} else {
_0x3e408e = _0x1c2791;
_0x1c2791 = _0x56093a;
}
if (_0x1c2791 === _0x4e763b) {
_0x1c2791 = _0x375d49;
}
if (_0x1c2791 !== _0x4e763b) {
_0x233bbe = [_0x233bbe, _0x1c2791];
_0x3876a5 = _0x233bbe;
} else {
_0x3e408e = _0x3876a5;
_0x3876a5 = _0x56093a;
}
} else {
_0x3e408e = _0x3876a5;
_0x3876a5 = _0x56093a;
}
return _0x3876a5;
}
function _0x12b906() {
var _0x470592, _0x4f49fa, _0x527996, _0xdffd8d, _0x564644;
_0x470592 = _0x3e408e;
_0x4f49fa = _0x2ef62e();
if (_0x4f49fa !== _0x4e763b) {
_0x527996 = _0x3e408e;
_0xdffd8d = [];
_0x564644 = _0x553f5b();
while (_0x564644 !== _0x4e763b) {
_0xdffd8d['push'](_0x564644);
_0x564644 = _0x553f5b();
}
if (_0xdffd8d !== _0x4e763b) {
_0x564644 = _0x12b906();
if (_0x564644 !== _0x4e763b) {
_0xdffd8d = [_0xdffd8d, _0x564644];
_0x527996 = _0xdffd8d;
} else {
_0x3e408e = _0x527996;
_0x527996 = _0x56093a;
}
} else {
_0x3e408e = _0x527996;
_0x527996 = _0x56093a;
}
if (_0x527996 === _0x4e763b) {
_0x527996 = _0x375d49;
}
if (_0x527996 !== _0x4e763b) {
_0x4f49fa = [_0x4f49fa, _0x527996];
_0x470592 = _0x4f49fa;
} else {
_0x3e408e = _0x470592;
_0x470592 = _0x56093a;
}
} else {
_0x3e408e = _0x470592;
_0x470592 = _0x56093a;
}
return _0x470592;
}
function _0x2ef62e() {
var _0x61ef5c;
_0x61ef5c = _0xf830c1();
if (_0x61ef5c === _0x4e763b) {
_0x61ef5c = _0x4e4f13();
if (_0x61ef5c === _0x4e763b) {
_0x61ef5c = _0x5e3341();
if (_0x61ef5c === _0x4e763b) {
_0x61ef5c = _0x5804f9();
if (_0x61ef5c === _0x4e763b) {
_0x61ef5c = _0x1fa3d9();
if (_0x61ef5c === _0x4e763b) {
_0x61ef5c = _0x3bb24f();
if (_0x61ef5c === _0x4e763b) {
_0x61ef5c = _0x1d0640();
if (_0x61ef5c === _0x4e763b) {
_0x61ef5c = _0x348547();
if (_0x61ef5c === _0x4e763b) {
_0x61ef5c = _0x553067();
}
}
}
}
}
}
}
}
return _0x61ef5c;
}
function _0x893e26() {
var _0x381238, _0x436b86, _0x2b7c21, _0x41077d;
_0x381238 = _0x3e408e;
if (_0x1f3890['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x436b86 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x436b86 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x5cb2e6);
}
}
if (_0x436b86 !== _0x4e763b) {
_0x2b7c21 = [];
_0x41077d = _0x553f5b();
while (_0x41077d !== _0x4e763b) {
_0x2b7c21['push'](_0x41077d);
_0x41077d = _0x553f5b();
}
if (_0x2b7c21 !== _0x4e763b) {
_0x41077d = _0x4fc8de();
if (_0x41077d !== _0x4e763b) {
_0x55bc2f = _0x381238;
_0x436b86 = _0x24a516(_0x436b86, _0x41077d);
_0x381238 = _0x436b86;
} else {
_0x3e408e = _0x381238;
_0x381238 = _0x56093a;
}
} else {
_0x3e408e = _0x381238;
_0x381238 = _0x56093a;
}
} else {
_0x3e408e = _0x381238;
_0x381238 = _0x56093a;
}
return _0x381238;
}
function _0x4fc8de() {
var _0x580c45, _0x3f7f44, _0x2ace55, _0x21a7f1, _0xe4cd2b;
_0x580c45 = _0x3e408e;
_0x3f7f44 = _0x38a50a();
if (_0x3f7f44 !== _0x4e763b) {
_0x2ace55 = _0x3e408e;
_0x21a7f1 = _0x5bbfe4();
if (_0x21a7f1 === _0x4e763b) {
_0x21a7f1 = _0x375d49;
}
if (_0x21a7f1 !== _0x4e763b) {
_0xe4cd2b = _0x26c904();
if (_0xe4cd2b !== _0x4e763b) {
_0x21a7f1 = [_0x21a7f1, _0xe4cd2b];
_0x2ace55 = _0x21a7f1;
} else {
_0x3e408e = _0x2ace55;
_0x2ace55 = _0x56093a;
}
} else {
_0x3e408e = _0x2ace55;
_0x2ace55 = _0x56093a;
}
if (_0x2ace55 === _0x4e763b) {
_0x2ace55 = _0x375d49;
}
if (_0x2ace55 !== _0x4e763b) {
_0x55bc2f = _0x580c45;
_0x3f7f44 = _0x5e38d7(_0x3f7f44, _0x2ace55);
_0x580c45 = _0x3f7f44;
} else {
_0x3e408e = _0x580c45;
_0x580c45 = _0x56093a;
}
} else {
_0x3e408e = _0x580c45;
_0x580c45 = _0x56093a;
}
return _0x580c45;
}
function _0xf830c1() {
var _0x4a09ef, _0x3814c5;
_0x4a09ef = _0x3e408e;
if (_0x387727['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x3814c5 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x3814c5 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x2868a8);
}
}
if (_0x3814c5 !== _0x4e763b) {
_0x55bc2f = _0x4a09ef;
_0x3814c5 = _0x594869();
}
_0x4a09ef = _0x3814c5;
return _0x4a09ef;
}
function _0x4e4f13() {
var _0x334609, _0xb49ef9, _0x341763, _0x5aa41b;
_0x334609 = _0x3e408e;
if (_0x589f3b['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0xb49ef9 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0xb49ef9 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x2d2081);
}
}
if (_0xb49ef9 !== _0x4e763b) {
_0x341763 = [];
_0x5aa41b = _0x553f5b();
while (_0x5aa41b !== _0x4e763b) {
_0x341763['push'](_0x5aa41b);
_0x5aa41b = _0x553f5b();
}
if (_0x341763 !== _0x4e763b) {
_0x5aa41b = _0x26c904();
if (_0x5aa41b !== _0x4e763b) {
_0x55bc2f = _0x334609;
_0xb49ef9 = _0x50849d(_0xb49ef9, _0x5aa41b);
_0x334609 = _0xb49ef9;
} else {
_0x3e408e = _0x334609;
_0x334609 = _0x56093a;
}
} else {
_0x3e408e = _0x334609;
_0x334609 = _0x56093a;
}
} else {
_0x3e408e = _0x334609;
_0x334609 = _0x56093a;
}
return _0x334609;
}
function _0x26c904() {
var _0x4a15e6, _0x4a995b, _0x27d7c7, _0x2e38ab, _0x4563fc;
_0x4a15e6 = _0x3e408e;
_0x4a995b = _0x38a50a();
if (_0x4a995b !== _0x4e763b) {
_0x27d7c7 = _0x3e408e;
_0x2e38ab = _0x5bbfe4();
if (_0x2e38ab === _0x4e763b) {
_0x2e38ab = _0x375d49;
}
if (_0x2e38ab !== _0x4e763b) {
_0x4563fc = _0x26c904();
if (_0x4563fc !== _0x4e763b) {
_0x2e38ab = [_0x2e38ab, _0x4563fc];
_0x27d7c7 = _0x2e38ab;
} else {
_0x3e408e = _0x27d7c7;
_0x27d7c7 = _0x56093a;
}
} else {
_0x3e408e = _0x27d7c7;
_0x27d7c7 = _0x56093a;
}
if (_0x27d7c7 === _0x4e763b) {
_0x27d7c7 = _0x375d49;
}
if (_0x27d7c7 !== _0x4e763b) {
_0x55bc2f = _0x4a15e6;
_0x4a995b = _0x5e38d7(_0x4a995b, _0x27d7c7);
_0x4a15e6 = _0x4a995b;
} else {
_0x3e408e = _0x4a15e6;
_0x4a15e6 = _0x56093a;
}
} else {
_0x3e408e = _0x4a15e6;
_0x4a15e6 = _0x56093a;
}
return _0x4a15e6;
}
function _0x5e3341() {
var _0xf3e26, _0x5c6a34, _0x304759, _0x4e8cd7;
_0xf3e26 = _0x3e408e;
if (_0x4c4628['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x5c6a34 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x5c6a34 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x36aa8b);
}
}
if (_0x5c6a34 !== _0x4e763b) {
_0x304759 = [];
_0x4e8cd7 = _0x553f5b();
while (_0x4e8cd7 !== _0x4e763b) {
_0x304759['push'](_0x4e8cd7);
_0x4e8cd7 = _0x553f5b();
}
if (_0x304759 !== _0x4e763b) {
_0x4e8cd7 = _0x2920d4();
if (_0x4e8cd7 !== _0x4e763b) {
_0x55bc2f = _0xf3e26;
_0x5c6a34 = _0x487dce(_0x5c6a34, _0x4e8cd7);
_0xf3e26 = _0x5c6a34;
} else {
_0x3e408e = _0xf3e26;
_0xf3e26 = _0x56093a;
}
} else {
_0x3e408e = _0xf3e26;
_0xf3e26 = _0x56093a;
}
} else {
_0x3e408e = _0xf3e26;
_0xf3e26 = _0x56093a;
}
return _0xf3e26;
}
function _0x2920d4() {
var _0x837728, _0x486290, _0x427e42, _0x48f743, _0xa4edad;
_0x837728 = _0x3e408e;
_0x486290 = _0x462d74();
if (_0x486290 !== _0x4e763b) {
_0x427e42 = _0x3e408e;
_0x48f743 = _0x5bbfe4();
if (_0x48f743 === _0x4e763b) {
_0x48f743 = _0x375d49;
}
if (_0x48f743 !== _0x4e763b) {
_0xa4edad = _0x2920d4();
if (_0xa4edad !== _0x4e763b) {
_0x48f743 = [_0x48f743, _0xa4edad];
_0x427e42 = _0x48f743;
} else {
_0x3e408e = _0x427e42;
_0x427e42 = _0x56093a;
}
} else {
_0x3e408e = _0x427e42;
_0x427e42 = _0x56093a;
}
if (_0x427e42 === _0x4e763b) {
_0x427e42 = _0x375d49;
}
if (_0x427e42 !== _0x4e763b) {
_0x55bc2f = _0x837728;
_0x486290 = _0x5e38d7(_0x486290, _0x427e42);
_0x837728 = _0x486290;
} else {
_0x3e408e = _0x837728;
_0x837728 = _0x56093a;
}
} else {
_0x3e408e = _0x837728;
_0x837728 = _0x56093a;
}
return _0x837728;
}
function _0x5804f9() {
var _0x8965a, _0xf28695, _0x3aa646, _0x431142;
_0x8965a = _0x3e408e;
if (_0x2f8fdc['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0xf28695 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0xf28695 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x391e28);
}
}
if (_0xf28695 !== _0x4e763b) {
_0x3aa646 = [];
_0x431142 = _0x553f5b();
while (_0x431142 !== _0x4e763b) {
_0x3aa646['push'](_0x431142);
_0x431142 = _0x553f5b();
}
if (_0x3aa646 !== _0x4e763b) {
_0x431142 = _0x2920d4();
if (_0x431142 !== _0x4e763b) {
_0x55bc2f = _0x8965a;
_0xf28695 = _0x2fb111(_0xf28695, _0x431142);
_0x8965a = _0xf28695;
} else {
_0x3e408e = _0x8965a;
_0x8965a = _0x56093a;
}
} else {
_0x3e408e = _0x8965a;
_0x8965a = _0x56093a;
}
} else {
_0x3e408e = _0x8965a;
_0x8965a = _0x56093a;
}
return _0x8965a;
}
function _0x1fa3d9() {
var _0x2bd81b, _0x4ead37, _0xb9e94a, _0x1f1d21;
_0x2bd81b = _0x3e408e;
if (_0x4a4882['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x4ead37 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x4ead37 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x1371ac);
}
}
if (_0x4ead37 !== _0x4e763b) {
_0xb9e94a = [];
_0x1f1d21 = _0x553f5b();
while (_0x1f1d21 !== _0x4e763b) {
_0xb9e94a['push'](_0x1f1d21);
_0x1f1d21 = _0x553f5b();
}
if (_0xb9e94a !== _0x4e763b) {
_0x1f1d21 = _0x49f3cf();
if (_0x1f1d21 !== _0x4e763b) {
_0x55bc2f = _0x2bd81b;
_0x4ead37 = _0x51b1f6(_0x4ead37, _0x1f1d21);
_0x2bd81b = _0x4ead37;
} else {
_0x3e408e = _0x2bd81b;
_0x2bd81b = _0x56093a;
}
} else {
_0x3e408e = _0x2bd81b;
_0x2bd81b = _0x56093a;
}
} else {
_0x3e408e = _0x2bd81b;
_0x2bd81b = _0x56093a;
}
return _0x2bd81b;
}
function _0x49f3cf() {
var _0xe5c33a, _0x477328, _0x119ce9, _0xdf5b04, _0x57237e;
_0xe5c33a = _0x3e408e;
_0x477328 = _0x1a31ff();
if (_0x477328 !== _0x4e763b) {
_0x119ce9 = _0x3e408e;
_0xdf5b04 = _0x5bbfe4();
if (_0xdf5b04 === _0x4e763b) {
_0xdf5b04 = _0x375d49;
}
if (_0xdf5b04 !== _0x4e763b) {
_0x57237e = _0x49f3cf();
if (_0x57237e !== _0x4e763b) {
_0xdf5b04 = [_0xdf5b04, _0x57237e];
_0x119ce9 = _0xdf5b04;
} else {
_0x3e408e = _0x119ce9;
_0x119ce9 = _0x56093a;
}
} else {
_0x3e408e = _0x119ce9;
_0x119ce9 = _0x56093a;
}
if (_0x119ce9 === _0x4e763b) {
_0x119ce9 = _0x375d49;
}
if (_0x119ce9 !== _0x4e763b) {
_0x55bc2f = _0xe5c33a;
_0x477328 = _0x5e38d7(_0x477328, _0x119ce9);
_0xe5c33a = _0x477328;
} else {
_0x3e408e = _0xe5c33a;
_0xe5c33a = _0x56093a;
}
} else {
_0x3e408e = _0xe5c33a;
_0xe5c33a = _0x56093a;
}
return _0xe5c33a;
}
function _0x1a31ff() {
var _0x2c770d, _0x25f1f8, _0x1b91ba, _0x12ee28, _0x425af4, _0x2feeef;
_0x2c770d = _0x3e408e;
_0x25f1f8 = _0x38a50a();
if (_0x25f1f8 !== _0x4e763b) {
_0x1b91ba = _0x5bbfe4();
if (_0x1b91ba === _0x4e763b) {
_0x1b91ba = _0x375d49;
}
if (_0x1b91ba !== _0x4e763b) {
_0x12ee28 = _0x38a50a();
if (_0x12ee28 !== _0x4e763b) {
_0x425af4 = _0x5bbfe4();
if (_0x425af4 === _0x4e763b) {
_0x425af4 = _0x375d49;
}
if (_0x425af4 !== _0x4e763b) {
_0x2feeef = _0x38a50a();
if (_0x2feeef !== _0x4e763b) {
_0x55bc2f = _0x2c770d;
_0x25f1f8 = _0xe1e1(_0x25f1f8, _0x12ee28, _0x2feeef);
_0x2c770d = _0x25f1f8;
} else {
_0x3e408e = _0x2c770d;
_0x2c770d = _0x56093a;
}
} else {
_0x3e408e = _0x2c770d;
_0x2c770d = _0x56093a;
}
} else {
_0x3e408e = _0x2c770d;
_0x2c770d = _0x56093a;
}
} else {
_0x3e408e = _0x2c770d;
_0x2c770d = _0x56093a;
}
} else {
_0x3e408e = _0x2c770d;
_0x2c770d = _0x56093a;
}
return _0x2c770d;
}
function _0x3bb24f() {
var _0x1efc96, _0x3533a4, _0x5baf6a, _0x3eaabf;
_0x1efc96 = _0x3e408e;
if (_0x3c0d2e['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x3533a4 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x3533a4 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x394135);
}
}
if (_0x3533a4 !== _0x4e763b) {
_0x5baf6a = [];
_0x3eaabf = _0x553f5b();
while (_0x3eaabf !== _0x4e763b) {
_0x5baf6a['push'](_0x3eaabf);
_0x3eaabf = _0x553f5b();
}
if (_0x5baf6a !== _0x4e763b) {
_0x3eaabf = _0x1effcd();
if (_0x3eaabf !== _0x4e763b) {
_0x55bc2f = _0x1efc96;
_0x3533a4 = _0x4aa6f7(_0x3533a4, _0x3eaabf);
_0x1efc96 = _0x3533a4;
} else {
_0x3e408e = _0x1efc96;
_0x1efc96 = _0x56093a;
}
} else {
_0x3e408e = _0x1efc96;
_0x1efc96 = _0x56093a;
}
} else {
_0x3e408e = _0x1efc96;
_0x1efc96 = _0x56093a;
}
return _0x1efc96;
}
function _0x1effcd() {
var _0xd15e3b, _0x2e6edc, _0x560d2e, _0x3d4eec, _0x5b4cfd;
_0xd15e3b = _0x3e408e;
_0x2e6edc = _0x52a948();
if (_0x2e6edc !== _0x4e763b) {
_0x560d2e = _0x3e408e;
_0x3d4eec = _0x5bbfe4();
if (_0x3d4eec === _0x4e763b) {
_0x3d4eec = _0x375d49;
}
if (_0x3d4eec !== _0x4e763b) {
_0x5b4cfd = _0x1effcd();
if (_0x5b4cfd !== _0x4e763b) {
_0x3d4eec = [_0x3d4eec, _0x5b4cfd];
_0x560d2e = _0x3d4eec;
} else {
_0x3e408e = _0x560d2e;
_0x560d2e = _0x56093a;
}
} else {
_0x3e408e = _0x560d2e;
_0x560d2e = _0x56093a;
}
if (_0x560d2e === _0x4e763b) {
_0x560d2e = _0x375d49;
}
if (_0x560d2e !== _0x4e763b) {
_0x55bc2f = _0xd15e3b;
_0x2e6edc = _0x5e38d7(_0x2e6edc, _0x560d2e);
_0xd15e3b = _0x2e6edc;
} else {
_0x3e408e = _0xd15e3b;
_0xd15e3b = _0x56093a;
}
} else {
_0x3e408e = _0xd15e3b;
_0xd15e3b = _0x56093a;
}
return _0xd15e3b;
}
function _0x52a948() {
var _0x8789b3, _0x4f9331, _0x132a7a, _0x181899;
_0x8789b3 = _0x3e408e;
_0x4f9331 = _0x38a50a();
if (_0x4f9331 !== _0x4e763b) {
_0x132a7a = _0x5bbfe4();
if (_0x132a7a === _0x4e763b) {
_0x132a7a = _0x375d49;
}
if (_0x132a7a !== _0x4e763b) {
_0x181899 = _0x38a50a();
if (_0x181899 !== _0x4e763b) {
_0x55bc2f = _0x8789b3;
_0x4f9331 = _0x30c615(_0x4f9331, _0x181899);
_0x8789b3 = _0x4f9331;
} else {
_0x3e408e = _0x8789b3;
_0x8789b3 = _0x56093a;
}
} else {
_0x3e408e = _0x8789b3;
_0x8789b3 = _0x56093a;
}
} else {
_0x3e408e = _0x8789b3;
_0x8789b3 = _0x56093a;
}
return _0x8789b3;
}
function _0x1d0640() {
var _0x4bc9ab, _0x599d9a, _0x49718b, _0x23fc95;
_0x4bc9ab = _0x3e408e;
if (_0x3a67c6['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x599d9a = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x599d9a = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x85b933);
}
}
if (_0x599d9a !== _0x4e763b) {
_0x49718b = [];
_0x23fc95 = _0x553f5b();
while (_0x23fc95 !== _0x4e763b) {
_0x49718b['push'](_0x23fc95);
_0x23fc95 = _0x553f5b();
}
if (_0x49718b !== _0x4e763b) {
_0x23fc95 = _0x525db0();
if (_0x23fc95 !== _0x4e763b) {
_0x55bc2f = _0x4bc9ab;
_0x599d9a = _0x3ceb0a(_0x599d9a, _0x23fc95);
_0x4bc9ab = _0x599d9a;
} else {
_0x3e408e = _0x4bc9ab;
_0x4bc9ab = _0x56093a;
}
} else {
_0x3e408e = _0x4bc9ab;
_0x4bc9ab = _0x56093a;
}
} else {
_0x3e408e = _0x4bc9ab;
_0x4bc9ab = _0x56093a;
}
return _0x4bc9ab;
}
function _0x525db0() {
var _0x58bd8f, _0x27e03c, _0x102d08, _0x59fdd8, _0xa8edd;
_0x58bd8f = _0x3e408e;
_0x27e03c = _0x48e64d();
if (_0x27e03c !== _0x4e763b) {
_0x102d08 = _0x3e408e;
_0x59fdd8 = _0x5bbfe4();
if (_0x59fdd8 === _0x4e763b) {
_0x59fdd8 = _0x375d49;
}
if (_0x59fdd8 !== _0x4e763b) {
_0xa8edd = _0x525db0();
if (_0xa8edd !== _0x4e763b) {
_0x59fdd8 = [_0x59fdd8, _0xa8edd];
_0x102d08 = _0x59fdd8;
} else {
_0x3e408e = _0x102d08;
_0x102d08 = _0x56093a;
}
} else {
_0x3e408e = _0x102d08;
_0x102d08 = _0x56093a;
}
if (_0x102d08 === _0x4e763b) {
_0x102d08 = _0x375d49;
}
if (_0x102d08 !== _0x4e763b) {
_0x55bc2f = _0x58bd8f;
_0x27e03c = _0x5e38d7(_0x27e03c, _0x102d08);
_0x58bd8f = _0x27e03c;
} else {
_0x3e408e = _0x58bd8f;
_0x58bd8f = _0x56093a;
}
} else {
_0x3e408e = _0x58bd8f;
_0x58bd8f = _0x56093a;
}
return _0x58bd8f;
}
function _0x48e64d() {
var _0x5986f2, _0x42674d, _0x3d238c, _0x4fc37e;
_0x5986f2 = _0x3e408e;
_0x42674d = _0x38a50a();
if (_0x42674d !== _0x4e763b) {
_0x3d238c = _0x5bbfe4();
if (_0x3d238c === _0x4e763b) {
_0x3d238c = _0x375d49;
}
if (_0x3d238c !== _0x4e763b) {
_0x4fc37e = _0x38a50a();
if (_0x4fc37e !== _0x4e763b) {
_0x55bc2f = _0x5986f2;
_0x42674d = _0x30c615(_0x42674d, _0x4fc37e);
_0x5986f2 = _0x42674d;
} else {
_0x3e408e = _0x5986f2;
_0x5986f2 = _0x56093a;
}
} else {
_0x3e408e = _0x5986f2;
_0x5986f2 = _0x56093a;
}
} else {
_0x3e408e = _0x5986f2;
_0x5986f2 = _0x56093a;
}
return _0x5986f2;
}
function _0x348547() {
var _0x5a90a2, _0x15ac19, _0x5d1d81, _0x2bfd38;
_0x5a90a2 = _0x3e408e;
if (_0x543bea['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x15ac19 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x15ac19 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x16de6e);
}
}
if (_0x15ac19 !== _0x4e763b) {
_0x5d1d81 = [];
_0x2bfd38 = _0x553f5b();
while (_0x2bfd38 !== _0x4e763b) {
_0x5d1d81['push'](_0x2bfd38);
_0x2bfd38 = _0x553f5b();
}
if (_0x5d1d81 !== _0x4e763b) {
_0x2bfd38 = _0x18fab1();
if (_0x2bfd38 !== _0x4e763b) {
_0x55bc2f = _0x5a90a2;
_0x15ac19 = _0x207488(_0x15ac19, _0x2bfd38);
_0x5a90a2 = _0x15ac19;
} else {
_0x3e408e = _0x5a90a2;
_0x5a90a2 = _0x56093a;
}
} else {
_0x3e408e = _0x5a90a2;
_0x5a90a2 = _0x56093a;
}
} else {
_0x3e408e = _0x5a90a2;
_0x5a90a2 = _0x56093a;
}
return _0x5a90a2;
}
function _0x18fab1() {
var _0x4ce267, _0x2c1571, _0x536ee2, _0x33dfbc, _0x36236f;
_0x4ce267 = _0x3e408e;
_0x2c1571 = _0x38a50a();
if (_0x2c1571 !== _0x4e763b) {
_0x536ee2 = _0x3e408e;
_0x33dfbc = _0x5bbfe4();
if (_0x33dfbc === _0x4e763b) {
_0x33dfbc = _0x375d49;
}
if (_0x33dfbc !== _0x4e763b) {
_0x36236f = _0x18fab1();
if (_0x36236f !== _0x4e763b) {
_0x33dfbc = [_0x33dfbc, _0x36236f];
_0x536ee2 = _0x33dfbc;
} else {
_0x3e408e = _0x536ee2;
_0x536ee2 = _0x56093a;
}
} else {
_0x3e408e = _0x536ee2;
_0x536ee2 = _0x56093a;
}
if (_0x536ee2 === _0x4e763b) {
_0x536ee2 = _0x375d49;
}
if (_0x536ee2 !== _0x4e763b) {
_0x55bc2f = _0x4ce267;
_0x2c1571 = _0x5e38d7(_0x2c1571, _0x536ee2);
_0x4ce267 = _0x2c1571;
} else {
_0x3e408e = _0x4ce267;
_0x4ce267 = _0x56093a;
}
} else {
_0x3e408e = _0x4ce267;
_0x4ce267 = _0x56093a;
}
return _0x4ce267;
}
function _0x553067() {
var _0x241dc9, _0x3a69e5, _0x52a19f, _0x5ed547;
_0x241dc9 = _0x3e408e;
if (_0xd18715['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x3a69e5 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x3a69e5 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x30a6b0);
}
}
if (_0x3a69e5 !== _0x4e763b) {
_0x52a19f = [];
_0x5ed547 = _0x553f5b();
while (_0x5ed547 !== _0x4e763b) {
_0x52a19f['push'](_0x5ed547);
_0x5ed547 = _0x553f5b();
}
if (_0x52a19f !== _0x4e763b) {
_0x5ed547 = _0x21d7c9();
if (_0x5ed547 !== _0x4e763b) {
_0x55bc2f = _0x241dc9;
_0x3a69e5 = _0xbeac27(_0x3a69e5, _0x5ed547);
_0x241dc9 = _0x3a69e5;
} else {
_0x3e408e = _0x241dc9;
_0x241dc9 = _0x56093a;
}
} else {
_0x3e408e = _0x241dc9;
_0x241dc9 = _0x56093a;
}
} else {
_0x3e408e = _0x241dc9;
_0x241dc9 = _0x56093a;
}
return _0x241dc9;
}
function _0x21d7c9() {
var _0x2f2dca, _0x2b58d6, _0x17db3e, _0x795ed1, _0x3cc0de;
_0x2f2dca = _0x3e408e;
_0x2b58d6 = _0x4eedd3();
if (_0x2b58d6 !== _0x4e763b) {
_0x17db3e = _0x3e408e;
_0x795ed1 = _0x5bbfe4();
if (_0x795ed1 === _0x4e763b) {
_0x795ed1 = _0x375d49;
}
if (_0x795ed1 !== _0x4e763b) {
_0x3cc0de = _0x21d7c9();
if (_0x3cc0de !== _0x4e763b) {
_0x795ed1 = [_0x795ed1, _0x3cc0de];
_0x17db3e = _0x795ed1;
} else {
_0x3e408e = _0x17db3e;
_0x17db3e = _0x56093a;
}
} else {
_0x3e408e = _0x17db3e;
_0x17db3e = _0x56093a;
}
if (_0x17db3e === _0x4e763b) {
_0x17db3e = _0x375d49;
}
if (_0x17db3e !== _0x4e763b) {
_0x55bc2f = _0x2f2dca;
_0x2b58d6 = _0x5e38d7(_0x2b58d6, _0x17db3e);
_0x2f2dca = _0x2b58d6;
} else {
_0x3e408e = _0x2f2dca;
_0x2f2dca = _0x56093a;
}
} else {
_0x3e408e = _0x2f2dca;
_0x2f2dca = _0x56093a;
}
return _0x2f2dca;
}
function _0x4eedd3() {
var _0x10205c, _0x280c0a, _0x436886, _0x3c8efd, _0x5d6240, _0x151e7d, _0x5e6210, _0x525f36, _0x167195, _0x451acb, _0x4e74a4, _0x460bfa;
_0x10205c = _0x3e408e;
_0x280c0a = _0x442fed();
if (_0x280c0a !== _0x4e763b) {
_0x436886 = _0x5bbfe4();
if (_0x436886 === _0x4e763b) {
_0x436886 = _0x375d49;
}
if (_0x436886 !== _0x4e763b) {
_0x3c8efd = _0x442fed();
if (_0x3c8efd !== _0x4e763b) {
_0x5d6240 = _0x5bbfe4();
if (_0x5d6240 === _0x4e763b) {
_0x5d6240 = _0x375d49;
}
if (_0x5d6240 !== _0x4e763b) {
_0x151e7d = _0x33fb0d();
if (_0x151e7d !== _0x4e763b) {
_0x5e6210 = _0x5bbfe4();
if (_0x5e6210 !== _0x4e763b) {
_0x525f36 = _0x15076b();
if (_0x525f36 !== _0x4e763b) {
_0x167195 = _0x5bbfe4();
if (_0x167195 === _0x4e763b) {
_0x167195 = _0x375d49;
}
if (_0x167195 !== _0x4e763b) {
_0x451acb = _0x15076b();
if (_0x451acb !== _0x4e763b) {
_0x4e74a4 = _0x5bbfe4();
if (_0x4e74a4 === _0x4e763b) {
_0x4e74a4 = _0x375d49;
}
if (_0x4e74a4 !== _0x4e763b) {
_0x460bfa = _0x38a50a();
if (_0x460bfa !== _0x4e763b) {
_0x55bc2f = _0x10205c;
_0x280c0a = _0x2cbb71(_0x280c0a, _0x3c8efd, _0x151e7d, _0x525f36, _0x451acb, _0x460bfa);
_0x10205c = _0x280c0a;
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
} else {
_0x3e408e = _0x10205c;
_0x10205c = _0x56093a;
}
return _0x10205c;
}
function _0x38a50a() {
var _0x28b05c, _0x15aa6a, _0x27e6b7, _0x36c52b;
_0x28b05c = _0x3e408e;
_0x15aa6a = _0x462d74();
if (_0x15aa6a !== _0x4e763b) {
_0x27e6b7 = _0x5bbfe4();
if (_0x27e6b7 === _0x4e763b) {
_0x27e6b7 = _0x375d49;
}
if (_0x27e6b7 !== _0x4e763b) {
_0x36c52b = _0x462d74();
if (_0x36c52b !== _0x4e763b) {
_0x55bc2f = _0x28b05c;
_0x15aa6a = _0x201fa4(_0x15aa6a, _0x36c52b);
_0x28b05c = _0x15aa6a;
} else {
_0x3e408e = _0x28b05c;
_0x28b05c = _0x56093a;
}
} else {
_0x3e408e = _0x28b05c;
_0x28b05c = _0x56093a;
}
} else {
_0x3e408e = _0x28b05c;
_0x28b05c = _0x56093a;
}
return _0x28b05c;
}
function _0x462d74() {
var _0x4e23cc, _0x3d1d23;
_0x4e23cc = _0x3e408e;
_0x3d1d23 = _0x33fb0d();
if (_0x3d1d23 !== _0x4e763b) {
_0x55bc2f = _0x4e23cc;
_0x3d1d23 = _0x5a72e5(_0x3d1d23);
}
_0x4e23cc = _0x3d1d23;
return _0x4e23cc;
}
function _0x442fed() {
var _0x5b5bca;
_0x5b5bca = _0x1aacaf();
if (_0x5b5bca === _0x4e763b) {
_0x5b5bca = _0x501b81();
}
return _0x5b5bca;
}
function _0x33fb0d() {
var _0x150415, _0xe8558, _0x34fdae;
_0x150415 = _0x3e408e;
_0xe8558 = _0x48a226();
if (_0xe8558 === _0x4e763b) {
_0xe8558 = _0x375d49;
}
if (_0xe8558 !== _0x4e763b) {
_0x34fdae = _0x1aacaf();
if (_0x34fdae !== _0x4e763b) {
_0xe8558 = [_0xe8558, _0x34fdae];
_0x150415 = _0xe8558;
} else {
_0x3e408e = _0x150415;
_0x150415 = _0x56093a;
}
} else {
_0x3e408e = _0x150415;
_0x150415 = _0x56093a;
}
if (_0x150415 === _0x4e763b) {
_0x150415 = _0x3e408e;
_0xe8558 = _0x48a226();
if (_0xe8558 === _0x4e763b) {
_0xe8558 = _0x375d49;
}
if (_0xe8558 !== _0x4e763b) {
_0x34fdae = _0x501b81();
if (_0x34fdae !== _0x4e763b) {
_0xe8558 = [_0xe8558, _0x34fdae];
_0x150415 = _0xe8558;
} else {
_0x3e408e = _0x150415;
_0x150415 = _0x56093a;
}
} else {
_0x3e408e = _0x150415;
_0x150415 = _0x56093a;
}
}
return _0x150415;
}
function _0x15076b() {
var _0x1961e0;
if (_0x3a6242['charCodeAt'](_0x3e408e) === 0x30) {
_0x1961e0 = _0x444dd7;
_0x3e408e++;
} else {
_0x1961e0 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x44e46d);
}
}
if (_0x1961e0 === _0x4e763b) {
if (_0x3a6242['charCodeAt'](_0x3e408e) === 0x31) {
_0x1961e0 = _0x8b2ec9;
_0x3e408e++;
} else {
_0x1961e0 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x2bab45);
}
}
}
return _0x1961e0;
}
function _0x5bbfe4() {
var _0x1b120d, _0x19a767, _0x218bca, _0x4c8546, _0x4e4c52;
_0x1b120d = _0x3e408e;
_0x19a767 = [];
_0x218bca = _0x553f5b();
if (_0x218bca !== _0x4e763b) {
while (_0x218bca !== _0x4e763b) {
_0x19a767['push'](_0x218bca);
_0x218bca = _0x553f5b();
}
} else {
_0x19a767 = _0x56093a;
}
if (_0x19a767 !== _0x4e763b) {
_0x218bca = _0x177a0e();
if (_0x218bca === _0x4e763b) {
_0x218bca = _0x375d49;
}
if (_0x218bca !== _0x4e763b) {
_0x4c8546 = [];
_0x4e4c52 = _0x553f5b();
while (_0x4e4c52 !== _0x4e763b) {
_0x4c8546['push'](_0x4e4c52);
_0x4e4c52 = _0x553f5b();
}
if (_0x4c8546 !== _0x4e763b) {
_0x19a767 = [_0x19a767, _0x218bca, _0x4c8546];
_0x1b120d = _0x19a767;
} else {
_0x3e408e = _0x1b120d;
_0x1b120d = _0x56093a;
}
} else {
_0x3e408e = _0x1b120d;
_0x1b120d = _0x56093a;
}
} else {
_0x3e408e = _0x1b120d;
_0x1b120d = _0x56093a;
}
if (_0x1b120d === _0x4e763b) {
_0x1b120d = _0x3e408e;
_0x19a767 = _0x177a0e();
if (_0x19a767 !== _0x4e763b) {
_0x218bca = [];
_0x4c8546 = _0x553f5b();
while (_0x4c8546 !== _0x4e763b) {
_0x218bca['push'](_0x4c8546);
_0x4c8546 = _0x553f5b();
}
if (_0x218bca !== _0x4e763b) {
_0x19a767 = [_0x19a767, _0x218bca];
_0x1b120d = _0x19a767;
} else {
_0x3e408e = _0x1b120d;
_0x1b120d = _0x56093a;
}
} else {
_0x3e408e = _0x1b120d;
_0x1b120d = _0x56093a;
}
}
return _0x1b120d;
}
function _0x177a0e() {
var _0x48f3b1;
if (_0x3a6242['charCodeAt'](_0x3e408e) === 0x2c) {
_0x48f3b1 = _0x5b6dde;
_0x3e408e++;
} else {
_0x48f3b1 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x3d3d23);
}
}
return _0x48f3b1;
}
function _0x1aacaf() {
var _0x1d3f41, _0x56163c, _0x5baf4d;
_0x1d3f41 = _0x3e408e;
_0x56163c = _0x1f553a();
if (_0x56163c !== _0x4e763b) {
_0x5baf4d = _0x22dc18();
if (_0x5baf4d === _0x4e763b) {
_0x5baf4d = _0x375d49;
}
if (_0x5baf4d !== _0x4e763b) {
_0x56163c = [_0x56163c, _0x5baf4d];
_0x1d3f41 = _0x56163c;
} else {
_0x3e408e = _0x1d3f41;
_0x1d3f41 = _0x56093a;
}
} else {
_0x3e408e = _0x1d3f41;
_0x1d3f41 = _0x56093a;
}
if (_0x1d3f41 === _0x4e763b) {
_0x1d3f41 = _0x3e408e;
_0x56163c = _0x501b81();
if (_0x56163c !== _0x4e763b) {
_0x5baf4d = _0x22dc18();
if (_0x5baf4d !== _0x4e763b) {
_0x56163c = [_0x56163c, _0x5baf4d];
_0x1d3f41 = _0x56163c;
} else {
_0x3e408e = _0x1d3f41;
_0x1d3f41 = _0x56093a;
}
} else {
_0x3e408e = _0x1d3f41;
_0x1d3f41 = _0x56093a;
}
}
return _0x1d3f41;
}
function _0x1f553a() {
var _0x28b12e, _0x3867ef, _0x4227d4, _0x28fdd3;
_0x28b12e = _0x3e408e;
_0x3867ef = _0x501b81();
if (_0x3867ef === _0x4e763b) {
_0x3867ef = _0x375d49;
}
if (_0x3867ef !== _0x4e763b) {
if (_0x3a6242['charCodeAt'](_0x3e408e) === 0x2e) {
_0x4227d4 = _0x57d0b1;
_0x3e408e++;
} else {
_0x4227d4 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x3e764);
}
}
if (_0x4227d4 !== _0x4e763b) {
_0x28fdd3 = _0x501b81();
if (_0x28fdd3 !== _0x4e763b) {
_0x3867ef = [_0x3867ef, _0x4227d4, _0x28fdd3];
_0x28b12e = _0x3867ef;
} else {
_0x3e408e = _0x28b12e;
_0x28b12e = _0x56093a;
}
} else {
_0x3e408e = _0x28b12e;
_0x28b12e = _0x56093a;
}
} else {
_0x3e408e = _0x28b12e;
_0x28b12e = _0x56093a;
}
if (_0x28b12e === _0x4e763b) {
_0x28b12e = _0x3e408e;
_0x3867ef = _0x501b81();
if (_0x3867ef !== _0x4e763b) {
if (_0x3a6242['charCodeAt'](_0x3e408e) === 0x2e) {
_0x4227d4 = _0x57d0b1;
_0x3e408e++;
} else {
_0x4227d4 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x3e764);
}
}
if (_0x4227d4 !== _0x4e763b) {
_0x3867ef = [_0x3867ef, _0x4227d4];
_0x28b12e = _0x3867ef;
} else {
_0x3e408e = _0x28b12e;
_0x28b12e = _0x56093a;
}
} else {
_0x3e408e = _0x28b12e;
_0x28b12e = _0x56093a;
}
}
return _0x28b12e;
}
function _0x22dc18() {
var _0x10eb16, _0x746fd4, _0x2bd004, _0x402e7e;
_0x10eb16 = _0x3e408e;
if (_0x1e3f99['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x746fd4 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x746fd4 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x1123fe);
}
}
if (_0x746fd4 !== _0x4e763b) {
_0x2bd004 = _0x48a226();
if (_0x2bd004 === _0x4e763b) {
_0x2bd004 = _0x375d49;
}
if (_0x2bd004 !== _0x4e763b) {
_0x402e7e = _0x501b81();
if (_0x402e7e !== _0x4e763b) {
_0x746fd4 = [_0x746fd4, _0x2bd004, _0x402e7e];
_0x10eb16 = _0x746fd4;
} else {
_0x3e408e = _0x10eb16;
_0x10eb16 = _0x56093a;
}
} else {
_0x3e408e = _0x10eb16;
_0x10eb16 = _0x56093a;
}
} else {
_0x3e408e = _0x10eb16;
_0x10eb16 = _0x56093a;
}
return _0x10eb16;
}
function _0x48a226() {
var _0x30442e;
if (_0x3a6242['charCodeAt'](_0x3e408e) === 0x2b) {
_0x30442e = _0x59832c;
_0x3e408e++;
} else {
_0x30442e = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x423117);
}
}
if (_0x30442e === _0x4e763b) {
if (_0x3a6242['charCodeAt'](_0x3e408e) === 0x2d) {
_0x30442e = _0xf5aaab;
_0x3e408e++;
} else {
_0x30442e = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x198f27);
}
}
}
return _0x30442e;
}
function _0x501b81() {
var _0x3405a5, _0x388e32, _0x5cddad;
_0x3405a5 = _0x3e408e;
_0x388e32 = [];
if (_0x1d19eb['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x5cddad = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x5cddad = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x2a6cc4);
}
}
if (_0x5cddad !== _0x4e763b) {
while (_0x5cddad !== _0x4e763b) {
_0x388e32['push'](_0x5cddad);
if (_0x1d19eb['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x5cddad = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x5cddad = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x2a6cc4);
}
}
}
} else {
_0x388e32 = _0x56093a;
}
if (_0x388e32 !== _0x4e763b) {
_0x55bc2f = _0x3405a5;
_0x388e32 = _0x3a87d5(_0x388e32);
}
_0x3405a5 = _0x388e32;
return _0x3405a5;
}
function _0x553f5b() {
var _0x52f7d4;
if (_0x15ce60['test'](_0x3a6242['charAt'](_0x3e408e))) {
_0x52f7d4 = _0x3a6242['charAt'](_0x3e408e);
_0x3e408e++;
} else {
_0x52f7d4 = _0x4e763b;
if (_0x15e012 === 0x0) {
_0x569314(_0x41f84b);
}
}
return _0x52f7d4;
}
var _0x5b0427 = [0x0, 0x0];
var _0x594746 = [0x0, 0x0];
var _0x65b89a = [];
var _0x52dd75 = !![];
var _0x5d45c1 = '';
function _0x4eee96(_0x1918a7) {
var _0x1c220a = [];
for (var _0x4a2cee = 0x0; _0x4a2cee < _0x1918a7['length']; _0x4a2cee++) {
if (_0x1918a7[_0x4a2cee] instanceof Array) {
_0x1c220a['push']['apply'](_0x1c220a, _0x4eee96(_0x1918a7[_0x4a2cee]));
} else {
_0x1c220a['push'](_0x1918a7[_0x4a2cee]);
}
}
return _0x1c220a;
}
function _0x17d776(_0x345c90, _0xb69db9) {
if ('mlazhvcsqt' ['indexOf'](_0x345c90) === -0x1) {
_0x5b0427 = _0xb69db9;
} else {
_0x5b0427[0x0] += _0xb69db9[0x0];
_0x5b0427[0x1] += _0xb69db9[0x1];
}
_0x5d45c1 = _0x345c90;
return _0x5b0427['slice'](0x0);
}
function _0x54e14f(_0xa6104a, _0x4c5d11) {
var _0x5f1573 = [];
var _0x4e994b = _0x5b0427['slice'](0x0);
for (var _0x34ce1a = 0x0; _0x34ce1a < _0x4c5d11['length']; _0x34ce1a += 0x2) {
_0x5b0427 = _0x4e994b['slice'](0x0);
var _0x4d36b1 = _0x17d776(_0xa6104a, _0x4c5d11['slice'](_0x34ce1a, _0x34ce1a + 0x2));
_0x5f1573 = _0x5f1573['concat'](_0x4d36b1);
if (_0x34ce1a == _0x4c5d11['length'] - 0x4) {
_0x594746 = _0x4d36b1['slice'](0x0);
}
}
return _0x5f1573;
}
function _0x2d262a() {
if ('CcSsQqTt' ['indexOf'](_0x5d45c1) == -0x1) {
_0x594746 = _0x5b0427['slice'](0x0);
}
var _0x5b7767 = [0x0, 0x0];
_0x5b7767[0x0] = 0x2 * _0x5b0427[0x0] - _0x594746[0x0];
_0x5b7767[0x1] = 0x2 * _0x5b0427[0x1] - _0x594746[0x1];
return _0x5b7767;
}
function _0x1134cf(_0x1c0b52, _0x9a24a2) {
var _0x3a4723 = [_0x9a24a2, 0x0];
if (_0x1c0b52 == 'H') {
_0x3a4723[0x1] = _0x5b0427[0x1];
}
return _0x17d776(_0x1c0b52, _0x3a4723);
}
function _0x5b73e4(_0x4d8f29, _0x1b987c) {
var _0x185519 = [0x0, _0x1b987c];
if (_0x4d8f29 == 'V') {
_0x185519[0x0] = _0x5b0427[0x0];
}
return _0x17d776(_0x4d8f29, _0x185519);
}
function _0x4ab5ce(_0x4c167f, _0x141977) {
var _0x5e13bc = [_0x4c167f];
if (_0x141977 && _0x141977['length'] > 0x1) {
var _0x1c60a4 = _0x141977[0x1];
for (var _0x4ffc46 = 0x0; _0x4ffc46 < _0x1c60a4['length']; _0x4ffc46++) {
_0x5e13bc['push'](_0x1c60a4[_0x4ffc46]);
}
}
return _0x5e13bc;
}
function _0x2c59c9(_0x453315) {
return Math['sqrt'](Math['pow'](_0x453315[0x0], 0x2) + Math['pow'](_0x453315[0x1], 0x2));
}
function _0x1aad7e(_0x4299a0, _0x477caf) {
return _0x4299a0[0x0] * _0x477caf[0x0] + _0x4299a0[0x1] * _0x477caf[0x1];
}
function _0x51383e(_0x301135, _0xec8df7) {
return _0x1aad7e(_0x301135, _0xec8df7) / (_0x2c59c9(_0x301135) * _0x2c59c9(_0xec8df7));
}
function _0x557f60(_0x6e3356, _0x38de63, _0x5d8dfd) {
return Math['min'](Math['max'](val, _0x38de63), _0x5d8dfd);
}
function _0x9d88b2(_0xd6f2ed, _0x432d82) {
var _0x303e2d = 0x1;
if (_0xd6f2ed[0x0] * _0x432d82[0x1] - _0xd6f2ed[0x1] * _0x432d82[0x0] < 0x0) {
_0x303e2d = -0x1;
}
return _0x303e2d * Math['acos'](_0x557f60(_0x51383e(_0xd6f2ed, _0x432d82)), -0x1, 0x1);
}
function _0x43f6bd(_0x48ff4c, _0x36fea1) {
var _0x7f4d28 = Math['cos'](_0x36fea1);
var _0x39169d = Math['sin'](_0x36fea1);
return [_0x7f4d28 * _0x48ff4c[0x0] + _0x39169d * _0x48ff4c[0x1], -0x1 * _0x39169d * _0x48ff4c[0x0] + _0x7f4d28 * _0x48ff4c[0x1]];
}
function _0x509b55(_0x34f713, _0x4e3e24) {
var _0x40eef2 = Math['cos'](_0x4e3e24);
var _0x1235bb = Math['sin'](_0x4e3e24);
return [_0x40eef2 * _0x34f713[0x0] - _0x1235bb * _0x34f713[0x1], _0x1235bb * _0x34f713[0x0] + _0x40eef2 * _0x34f713[0x1]];
}
function _0xbc7bed(_0x4b40bc, _0x4a4bb7) {
return [(_0x4b40bc[0x0] - _0x4a4bb7[0x0]) / 0x2, (_0x4b40bc[0x1] - _0x4a4bb7[0x1]) / 0x2];
}
function _0x54dfbe(_0x58fa17, _0xfc0dbd) {
return [(_0x58fa17[0x0] + _0xfc0dbd[0x0]) / 0x2, (_0x58fa17[0x1] + _0xfc0dbd[0x1]) / 0x2];
}
function _0x1d52fe(_0x5517ff, _0x40781b) {
return [_0x5517ff[0x0] * _0x40781b[0x0], _0x5517ff[0x1] * _0x40781b[0x1]];
}
function _0x5d5519(_0x1ff7e9, _0x5b95b2) {
return [_0x1ff7e9 * _0x5b95b2[0x0], _0x1ff7e9 * _0x5b95b2[0x1]];
}
function _0x23f816(_0x4fd0e5, _0x426b2a) {
return [_0x4fd0e5[0x0] + _0x426b2a[0x0], _0x4fd0e5[0x1] + _0x426b2a[0x1]];
}
function _0x42a62a(_0x53c84b, _0x197350, _0x2ebbee, _0x498c53, _0x122b93, _0x281ee8, _0x455437) {
if (_0x197350 == 0x0 || _0x2ebbee == 0x0) {
_0x65b89a['push']({
'type': 'lineTo',
'args': _0x455437
});
return;
}
var _0x498c53 = _0x498c53 * (Math['PI'] / 0xb4);
_0x197350 = Math['abs'](_0x197350);
_0x2ebbee = Math['abs'](_0x2ebbee);
var _0x52e608 = _0x43f6bd(_0xbc7bed(_0x53c84b, _0x455437), _0x498c53);
var _0x3648b4 = _0x1d52fe(_0x52e608, _0x52e608);
var _0x5bceb0 = Math['pow'](_0x197350, 0x2);
var _0x23b38 = Math['pow'](_0x2ebbee, 0x2);
var _0x51edaf = Math['sqrt'](_0x3648b4[0x0] / _0x5bceb0 + _0x3648b4[0x1] / _0x23b38);
if (_0x51edaf > 0x1) {
_0x197350 *= _0x51edaf;
_0x2ebbee *= _0x51edaf;
_0x5bceb0 = Math['pow'](_0x197350, 0x2);
_0x23b38 = Math['pow'](_0x2ebbee, 0x2);
}
var _0x1c2ee5 = Math['sqrt'](Math['abs'](_0x5bceb0 * _0x23b38 - _0x5bceb0 * _0x3648b4[0x1] - _0x23b38 * _0x3648b4[0x0]) / (_0x5bceb0 * _0x3648b4[0x1] + _0x23b38 * _0x3648b4[0x0]));
if (_0x122b93 == _0x281ee8) {
_0x1c2ee5 *= -0x1;
}
var _0x514190 = _0x5d5519(_0x1c2ee5, [_0x197350 * _0x52e608[0x1] / _0x2ebbee, -_0x2ebbee * _0x52e608[0x0] / _0x197350]);
var _0x35530e = _0x23f816(_0x509b55(_0x514190, _0x498c53), _0x54dfbe(_0x53c84b, _0x455437));
var _0x29cd1d = [(_0x52e608[0x0] - _0x514190[0x0]) / _0x197350, (_0x52e608[0x1] - _0x514190[0x1]) / _0x2ebbee];
var _0x248328 = [(-0x1 * _0x52e608[0x0] - _0x514190[0x0]) / _0x197350, (-0x1 * _0x52e608[0x1] - _0x514190[0x1]) / _0x2ebbee];
var _0x552567 = _0x9d88b2([0x1, 0x0], _0x29cd1d);
var _0x253710 = _0x9d88b2(_0x29cd1d, _0x248328);
var _0x48c1bb = _0x552567;
var _0x3da7fc = _0x552567 + _0x253710;
_0x65b89a['push']({
'type': 'save',
'args': []
}, {
'type': 'translate',
'args': [_0x35530e[0x0], _0x35530e[0x1]]
}, {
'type': 'rotate',
'args': [_0x498c53]
}, {
'type': 'scale',
'args': [_0x197350, _0x2ebbee]
}, {
'type': 'arc',
'args': [0x0, 0x0, 0x1, _0x48c1bb, _0x3da7fc, 0x1 - _0x281ee8]
}, {
'type': 'restore',
'args': []
});
}
_0x2bfff2 = _0x3c91de();
if (_0x2bfff2 !== _0x4e763b && _0x3e408e === _0x3a6242['length']) {
return _0x2bfff2;
} else {
if (_0x2bfff2 !== _0x4e763b && _0x3e408e < _0x3a6242['length']) {
_0x569314({
'type': 'end',
'description': 'end\x20of\x20input'
});
}
throw _0x2f901a(null, _0x1fda2f, _0x7dbbe5);
}
}
return {
'SyntaxError': _0x4cc4a9,
'parse': _0x4b296c
};
}();
function _0x2e7f39(_0x6b1952) {
this['ops_'] = [];
if (_0x6b1952 == undefined) {
return;
}
if (typeof _0x6b1952 == 'string') {
try {
this['ops_'] = parser['parse'](_0x6b1952);
} catch (_0x3cea62) {}
} else if (_0x6b1952['hasOwnProperty']('ops_')) {
this['ops_'] = _0x6b1952['ops_']['slice'](0x0);
} else {
throw 'Error:\x20' + typeof _0x6b1952 + 'is\x20not\x20a\x20valid\x20argument\x20to\x20Path';
}
};
var _0x12bf09 = ['closePath', 'moveTo', 'lineTo', 'quadraticCurveTo', 'bezierCurveTo', 'rect', 'arc', 'arcTo', 'ellipse', 'isPointInPath', 'isPointInStroke'];
function _0x3591e3(_0x4b537b) {
return function() {
this['ops_']['push']({
'type': _0x4b537b,
'args': Array['prototype']['slice']['call'](arguments, 0x0)
});
};
}
for (var _0x4136da = 0x0; _0x4136da < _0x12bf09['length']; _0x4136da++) {
var _0x513083 = _0x12bf09[_0x4136da];
_0x2e7f39['prototype'][_0x513083] = _0x3591e3(_0x513083);
}
_0x2e7f39['prototype']['addPath'] = function(_0x13e45b, _0xe33f76) {
var _0x4f6995 = ![];
if (_0xe33f76 && _0xe33f76['a'] != undefined && _0xe33f76['b'] != undefined && _0xe33f76['c'] != undefined && _0xe33f76['d'] != undefined && _0xe33f76['e'] != undefined && _0xe33f76['f'] != undefined) {
_0x4f6995 = !![];
this['ops_']['push']({
'type': 'save',
'args': []
});
this['ops_']['push']({
'type': 'transform',
'args': [_0xe33f76['a'], _0xe33f76['b'], _0xe33f76['c'], _0xe33f76['d'], _0xe33f76['e'], _0xe33f76['f']]
});
}
this['ops_'] = this['ops_']['concat'](_0x13e45b['ops_']);
if (_0x4f6995) {
this['ops_']['push']({
'type': 'restore',
'args': []
});
}
};
original_fill = _0x58f57c['prototype']['fill'];
original_stroke = _0x58f57c['prototype']['stroke'];
original_clip = _0x58f57c['prototype']['clip'];
original_is_point_in_path = _0x58f57c['prototype']['isPointInPath'];
original_is_point_in_stroke = _0x58f57c['prototype']['isPointInStroke'];
_0x58f57c['prototype']['fill'] = function(_0x158a44) {
if (_0x158a44 instanceof _0x2e7f39) {
this['beginPath']();
for (var _0x2583d1 = 0x0, _0x5aeabc = _0x158a44['ops_']['length']; _0x2583d1 < _0x5aeabc; _0x2583d1++) {
var _0x2535d2 = _0x158a44['ops_'][_0x2583d1];
_0x58f57c['prototype'][_0x2535d2['type']]['apply'](this, _0x2535d2['args']);
}
original_fill['apply'](this, Array['prototype']['slice']['call'](arguments, 0x1));
} else {
original_fill['apply'](this, arguments);
}
};
_0x58f57c['prototype']['stroke'] = function(_0x320e56) {
if (_0x320e56 instanceof _0x2e7f39) {
this['beginPath']();
for (var _0xfda099 = 0x0, _0x22e51f = _0x320e56['ops_']['length']; _0xfda099 < _0x22e51f; _0xfda099++) {
var _0x436be2 = _0x320e56['ops_'][_0xfda099];
_0x58f57c['prototype'][_0x436be2['type']]['apply'](this, _0x436be2['args']);
}
original_stroke['call'](this);
} else {
original_stroke['call'](this);
}
};
_0x58f57c['prototype']['clip'] = function(_0xc86e0c) {
if (_0xc86e0c instanceof _0x2e7f39) {
this['beginPath']();
for (var _0x433230 = 0x0, _0x48690b = _0xc86e0c['ops_']['length']; _0x433230 < _0x48690b; _0x433230++) {
var _0x5d0d8b = _0xc86e0c['ops_'][_0x433230];
_0x58f57c['prototype'][_0x5d0d8b['type']]['apply'](this, _0x5d0d8b['args']);
}
original_clip['apply'](this, Array['prototype']['slice']['call'](arguments, 0x1));
} else {
original_clip['apply'](this, arguments);
}
};
_0x58f57c['prototype']['isPointInPath'] = function(_0x5671bb) {
if (_0x5671bb instanceof _0x2e7f39) {
this['beginPath']();
for (var _0x5294d4 = 0x0, _0xd14329 = _0x5671bb['ops_']['length']; _0x5294d4 < _0xd14329; _0x5294d4++) {
var _0x2c16dd = _0x5671bb['ops_'][_0x5294d4];
_0x58f57c['prototype'][_0x2c16dd['type']]['apply'](this, _0x2c16dd['args']);
}
return original_is_point_in_path['apply'](this, Array['prototype']['slice']['call'](arguments, 0x1));
} else {
return original_is_point_in_path['apply'](this, arguments);
}
};
_0x58f57c['prototype']['isPointInStroke'] = function(_0x114ae3) {
if (_0x114ae3 instanceof _0x2e7f39) {
this['beginPath']();
for (var _0x170512 = 0x0, _0x5c0abe = _0x114ae3['ops_']['length']; _0x170512 < _0x5c0abe; _0x170512++) {
var _0x82d3b8 = _0x114ae3['ops_'][_0x170512];
_0x58f57c['prototype'][_0x82d3b8['type']]['apply'](this, _0x82d3b8['args']);
}
return original_is_point_in_stroke['apply'](this, Array['prototype']['slice']['call'](arguments, 0x1));
} else {
return original_is_point_in_stroke['apply'](this, arguments);
}
};
Path2D = _0x2e7f39;
}());
}
}(typeof CanvasRenderingContext2D === 'undefined' ? undefined : CanvasRenderingContext2D, typeof require === 'undefined' ? undefined : require));
// Array.find polyfill
!Array['prototype']['find'] && Object['defineProperty'](Array['prototype'], 'find', {
'value': function(_0x55bea1) {
if (this == null) throw new TypeError('\x22this\x22\x20is\x20null\x20or\x20not\x20defined');
var _0x2bea3f = Object(this),
_0x52404e = _0x2bea3f['length'] >>> 0x0;
if (typeof _0x55bea1 !== 'function') throw new TypeError('predicate\x20must\x20be\x20a\x20function');
var _0x5e3137 = arguments[0x1],
_0x559983 = 0x0;
while (_0x559983 < _0x52404e) {
var _0x51d569 = _0x2bea3f[_0x559983];
if (_0x55bea1['call'](_0x5e3137, _0x51d569, _0x559983, _0x2bea3f)) return _0x51d569;
_0x559983++;
}
return undefined;
},
'configurable': !![],
'writable': !![]
});
/*----- functions -----*/
// utils
function deg2rad(deg) {
return deg * Math.PI / 180.0;
}
function rotateVectorRad(v, rad) {
return [
v[0] * Math.cos(rad) - v[1] * Math.sin(rad),
v[0] * Math.sin(rad) + v[1] * Math.cos(rad)
];
}
function rotateVectorDeg(v, deg) {
var rad = deg2rad(deg);
return rotateVectorRad(v, rad);
}
function applyRotationRad(bbox, rad) {
var corners = [
[bbox.minx, bbox.miny],
[bbox.minx, bbox.maxy],
[bbox.maxx, bbox.miny],
[bbox.maxx, bbox.maxy]
];
corners = corners.map(function(v) {
return rotateVectorRad(v, rad);
});
return {
minx: corners.reduce(function(a, v) {
return Math.min(a, v[0]);
}, Infinity),
miny: corners.reduce(function(a, v) {
return Math.min(a, v[1]);
}, Infinity),
maxx: corners.reduce(function(a, v) {
return Math.max(a, v[0]);
}, -Infinity),
maxy: corners.reduce(function(a, v) {
return Math.max(a, v[1]);
}, -Infinity),
}
}
function applyRotationDeg(bbox, deg) {
var rad = deg2rad(deg);
return applyRotationRad(bbox, rad);
}
// canvas painter
const painter = {
ctx: null,
save: function() {
this.ctx.save();
},
restore: function() {
this.ctx.restore();
},
clear: function(w, h, color) {
this.save();
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
if (color) {
this.ctx.fillStyle = color;
this.ctx.fillRect(0, 0, w, h);
} else {
this.ctx.clearRect(0, 0, w, h);
}
this.restore();
},
line: function(x1, y1, x2, y2, lw, color) {
this.save();
this.setLineCapAndJoin();
this.ctx.strokeStyle = color;
this.ctx.lineWidth = lw;
this.ctx.beginPath();
this.ctx.moveTo(x1, y1);
this.ctx.lineTo(x2, y2);
this.ctx.stroke();
this.restore();
},
strokeArc: function(cx, cy, radius, startAngle, stopAngle, ccw, lw, color) {
this.save();
this.setLineCapAndJoin();
this.ctx.strokeStyle = color;
this.ctx.lineWidth = lw;
this.ctx.beginPath();
this.ctx.arc(cx, cy, radius, startAngle, stopAngle, ccw);
this.ctx.stroke();
this.restore();
},
closedArc: function(cx, cy, radius, startAngle, stopAngle, ccw, lw, color) {
this.save();
this.setLineCapAndJoin();
this.ctx.strokeStyle = color;
this.ctx.lineWidth = lw;
this.ctx.beginPath();
this.ctx.arc(cx, cy, radius, startAngle, stopAngle, ccw);
this.ctx.closePath();
this.ctx.stroke();
this.restore();
},
fillArc: function(cx, cy, radius, startAngle, stopAngle, ccw, color) {
this.save();
this.setLineCapAndJoin();
this.ctx.fillStyle = color;
this.ctx.beginPath();
this.ctx.arc(cx, cy, radius, startAngle, stopAngle, ccw);
this.ctx.fill();
this.restore();
},
strokeEllipse: function(x, y, radiusX, radiusY, rotation, lw, color) {
this.save();
this.setLineCapAndJoin();
this.ctx.strokeStyle = color;
this.ctx.lineWidth = lw;
this.ctx.beginPath();
this.ctx.ellipse(x, y, radiusX, radiusY, rotation, 0, 2 * Math.PI, false);
this.ctx.stroke();
this.restore();
},
fillEllipse: function(x, y, radiusX, radiusY, rotation, color) {
this.save();
this.setLineCapAndJoin();
this.ctx.fillStyle = color;
this.ctx.beginPath();
this.ctx.ellipse(x, y, radiusX, radiusY, rotation, 0, 2 * Math.PI, false);
this.ctx.fill();
this.restore();
},
strokeObround: function(x, y, width, height, rotation, lw, color) {
if (width === height) {
this.strokeEllipse(x, y, width / 2, height / 2, rotation, lw, color);
} else {
this.save();
this.ctx.translate(x, y);
if (rotation !== null) {
this.ctx.rotate(rotation);
}
this.strokePath(this.getObroundPath(width, height), lw, color);
this.restore();
}
},
fillObround: function(x, y, width, height, rotation, color) {
if (width === height) {
this.fillEllipse(x, y, width / 2, height / 2, rotation, color);
} else {
this.save();
this.ctx.translate(x, y);
if (rotation !== null) {
this.ctx.rotate(rotation);
}
this.fillPath(this.getObroundPath(width, height), color);
this.restore();
}
},
strokeRect: function(x, y, width, height, crad, rotation, lw, color) {
if (crad < 0.001) {
this.save();
this.setLineCapAndJoin();
this.ctx.strokeStyle = color;
this.ctx.lineWidth = lw;
this.ctx.translate(x, y);
if (rotation !== null) {
this.ctx.rotate(rotation);
}
this.ctx.beginPath();
this.ctx.rect(-width / 2, -height / 2, width, height);
this.ctx.stroke();
this.restore();
} else if (crad > 49.99) {
this.strokeObround(x, y, width, height, rotation, lw, color);
} else {
this.save();
this.ctx.translate(x, y);
if (rotation !== null) {
this.ctx.rotate(rotation);
}
this.strokePath(this.getRoundedRectPath(width, height, crad), lw, color);
this.restore();
}
},
fillRect: function(x, y, width, height, crad, rotation, color) {
if (crad < 0.001) {
this.save();
this.setLineCapAndJoin();
this.ctx.fillStyle = color;
this.ctx.translate(x, y);
if (rotation !== null) {
this.ctx.rotate(rotation);
}
this.ctx.beginPath();
this.ctx.rect(-width / 2, -height / 2, width, height);
this.ctx.fill();
this.restore();
} else if (crad > 49.99) {
this.fillObround(x, y, width, height, rotation, color);
} else {
this.save();
this.ctx.translate(x, y);
if (rotation !== null) {
this.ctx.rotate(rotation);
}
this.fillPath(this.getRoundedRectPath(width, height, crad), color);
this.restore();
}
},
strokeDShape: function(x, y, width, height, lw, color) {
this.save();
this.ctx.translate(x, y);
this.strokePath(this.getDShapePath(width, height));
this.restore();
},
fillDShape: function(x, y, width, height, color) {
this.save();
this.ctx.translate(x, y);
this.fillPath(this.getDShapePath(width, height), color);
this.restore();
},
strokePath: function(path, lw, color) {
this.save();
this.setLineCapAndJoin();
this.ctx.strokeStyle = color;
this.ctx.lineWidth = lw;
this.ctx.stroke(path);
this.restore();
},
fillPath: function(path, color) {
this.save();
this.setLineCapAndJoin();
this.ctx.fillStyle = color;
this.ctx.fill(path);
this.restore();
},
setLineCapAndJoin: function() {
this.ctx.lineCap = "round";
this.ctx.lineJoin = "round";
},
padZero: function(str, len) {
len = len || 2;
var zeros = new Array(len).join('0');
return (zeros + str).slice(-len);
},
invertColor: function(hex, bw) {
if (hex.indexOf('#') === 0) {
hex = hex.slice(1);
}
// convert 3-digit hex to 6-digits.
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
if (hex.length !== 6) {
throw new Error('Invalid HEX color.');
}
var r = parseInt(hex.slice(0, 2), 16);
var g = parseInt(hex.slice(2, 4), 16);
var b = parseInt(hex.slice(4, 6), 16);
if (bw) {
return (r * 0.299 + g * 0.587 + b * 0.114) > 186 ? '#000000' : '#FFFFFF';
}
// invert color components
r = (255 - r).toString(16);
g = (255 - g).toString(16);
b = (255 - b).toString(16);
// pad each with zeros and return
return "#" + this.padZero(r) + this.padZero(g) + this.padZero(b);
},
getObroundPath: function(width, height) {
var r, d;
var path = new Path2D();
if (width > height) {
r = height / 2;
d = width / 2;
path.arc(-d + r, 0, r, Math.PI / 2, 1.5 * Math.PI, false);
path.lineTo(d - r, -r);
path.arc(d - r, 0, r, 1.5 * Math.PI, Math.PI / 2, false);
} else {
r = width / 2;
d = height / 2;
path.arc(0, d - r, r, 0, Math.PI, false);
path.lineTo(-r, -d + r);
path.arc(0, -d + r, r, Math.PI, 0, false);
}
path.closePath();
return path;
},
getRoundedRectPath: function(width, height, crad) {
var hw = width / 2;
var hh = height / 2;
var r = Math.min(width, height) * crad / 100;
var path = new Path2D();
path.arc(-hw + r, -hh + r, r, Math.PI, 1.5 * Math.PI, false);
path.lineTo(hw - r, -hh);
path.arc(hw - r, -hh + r, r, 1.5 * Math.PI / 2, 0, false);
path.lineTo(hw, hh - r);
path.arc(hw - r, hh - r, r, 0, Math.PI / 2, false);
path.lineTo(-hw + r, hh);
path.arc(-hw + r, hh - r, r, Math.PI / 2, Math.PI, false);
path.closePath();
return path;
},
getDShapePath: function(width, height) {
var hw = width / 2;
var hh = height / 2;
var r = hw;
var y0 = hh - r;
var path = new Path2D();
if (y0 < 0) {
path.ellipse(0, 0, r, r + y0, 0, Math.PI, 0, false);
} else {
path.ellipse(0, 0, r, r, 0, Math.PI, 0, false);
}
path.lineTo(hw, hh);
path.lineTo(-hw, hh);
path.closePath();
return path;
}
}
// storage
function initStorage() {
try {
window.localStorage.getItem("blank");
storage = window.localStorage;
} catch (e) {
// localStorage not available
}
if (!storage) {
try {
window.sessionStorage.getItem("blank");
storage = window.sessionStorage;
} catch (e) {
// sessionStorage also not available
}
}
}
function readStorage(key) {
if (storage) {
return JSON.parse(storage.getItem(storagePrefix + key));
} else {
return null;
}
}
function writeStorage(key, value) {
if (storage) {
storage.setItem(storagePrefix + key, JSON.stringify(value));
}
}
// defaults
function initDefaults() {
var tmp;
// settings
// bom layout
tmp = readStorage("bom_layout");
if (tmp !== null) {
settings.bom_layout = tmp;
}
// bom gorup
tmp = readStorage("bom_group");
if (tmp !== null) {
settings.bom_group = tmp;
}
// canvas layout
tmp = readStorage("canvas_layout");
if (tmp !== null) {
settings.canvas_layout = tmp;
}
// draw assy
tmp = readStorage("draw_assy");
if (tmp !== null) {
settings.draw_assy = tmp;
}
// draw silk
tmp = readStorage("draw_silk");
if (tmp !== null) {
settings.draw_silk = tmp;
}
// draw nets
tmp = readStorage("draw_nets");
if (tmp !== null) {
settings.draw_nets = tmp;
}
// draw copper pours
tmp = readStorage("draw_copper_pours");
if (tmp !== null) {
settings.draw_copper_pours = tmp;
}
// draw fiducials
tmp = readStorage("draw_fiducials");
if (tmp !== null) {
settings.draw_fiducials = tmp;
} else {
settings.draw_fiducials = pcbdata.board.show_fiducials;
}
// draw pads
tmp = readStorage("draw_pads");
if (tmp !== null) {
settings.draw_pads = tmp;
}
// draw vias
tmp = readStorage("draw_vias");
if (tmp !== null) {
settings.draw_vias = tmp;
}
// show suppliers
tmp = readStorage("show_suppliers");
if (tmp !== null) {
settings.show_suppliers = tmp;
}
// board rotation angle
tmp = readStorage("board_rotation");
if (tmp !== null) {
settings.board_rotation = tmp;
}
// placed
tmp = readStorage("placed");
settings.placed = [];
if (tmp !== null) {
settings.placed = tmp;
}
// document
var text = pcbdata.metadata.title + pcbdata.metadata.board_name;
if (pcbdata.metadata.variant !== "") {
text += " :: " + pcbdata.metadata.variant;
}
document.title = text;
document.getElementById("board_name").innerHTML = pcbdata.metadata.board_name;
if (pcbdata.metadata.variant !== "") {
var elem = document.getElementById("assembly_variant");
elem.innerHTML = "Assembly variant: " + pcbdata.metadata.variant;
elem.style.display = "table-cell";
}
document.getElementById('version').innerHTML = "version " + pcbdata.metadata.version;
}
function writeAll() {
// settings
Object.keys(settings).forEach(function(name) {
writeStorage(name, settings[name]);
});
}
// render with events
function initRender() {
["topcanvas", "bottomcanvas"].forEach(function(name) {
var div = document.getElementById(name);
div.style.backgroundColor = pcbdata.board.bgcolor;
var canvas = canvases[name];
var trsf = canvas.trsf;
// context menu
[div, canvas.bg, canvas.silk, canvas.assy, canvas.hl].forEach(function(elem) {
elem.addEventListener("contextmenu", function(e) {
e.preventDefault();
}, false);
});
// mouse down, move, up
var isDown = false;
div.addEventListener("pointerdown", function(e) {
e.preventDefault();
e.stopPropagation();
isDown = true;
canvas.pstate[e.pointerId] = {
lastX: e.offsetX,
lastY: e.offsetY,
down: e.button
};
});
div.addEventListener("pointermove", function(e) {
if (canvas.pstate.hasOwnProperty(e.pointerId)) {
if (canvas.pstate[e.pointerId].down == 2) {
return;
}
e.preventDefault();
e.stopPropagation();
var dx = e.offsetX - canvas.pstate[e.pointerId].lastX;
var dy = e.offsetY - canvas.pstate[e.pointerId].lastY;
canvas.pstate[e.pointerId] = {
lastX: e.offsetX,
lastY: e.offsetY
};
// simple drag
trsf.panx += devicePixelRatio * dx / trsf.zoom;
trsf.pany += devicePixelRatio * dy / trsf.zoom;
redrawCanvas(canvas);
}
});
div.addEventListener("pointerup", function(e) {
e.preventDefault();
e.stopPropagation();
delete canvas.pstate[e.pointerId];
// reset transformation by right click
if (e.button === 2) {
trsf.panx = 0;
trsf.pany = 0;
trsf.zoom = 1;
}
redrawCanvas(canvas);
isDown = false;
});
// mouse wheel (zoom)
div.addEventListener("wheel", function(e) {
e.preventDefault();
e.stopPropagation();
if (isDown) {
return;
}
var wheeldelta = e.deltaY;
// Firefox
if (e.deltaMode == 1) { // The delta values are specified in lines.
wheeldelta *= 30;
} else if (e.deltaMode == 2) { // The delta values are specified in pages.
wheeldelta *= 300;
}
var m = Math.pow(1.1, -wheeldelta / 40);
// limit amount of zoom per tick.
if (m > 2) {
m = 2;
} else if (m < 0.5) {
m = 0.5;
}
trsf.zoom *= m;
var zoomd = (1 - m) / trsf.zoom;
trsf.panx += devicePixelRatio * e.offsetX * zoomd;
trsf.pany += devicePixelRatio * e.offsetY * zoomd;
redrawCanvas(canvas);
});
});
}
// layouts
function getGutterNode(node) {
for (var i = 0; i < node.childNodes.length; i++) {
if (node.childNodes[i].classList && node.childNodes[i].classList.contains("gutter")) {
return node.childNodes[i];
}
}
}
function removeGutterNode(node) {
node.removeChild(getGutterNode(node));
}
function removeGutters() {
removeGutterNode(document.getElementById("divbottom"));
removeGutterNode(document.getElementById("divcanvas"));
}
function destorySplitters() {
if (bomsplit) {
bomsplit.destroy();
bomsplit = null;
canvassplit.destroy();
canvassplit = null;
}
}
function changeBOMLayout(bomLayout) {
Object.keys(bomButtons).forEach(function(btnName) {
bomButtons[btnName].classList.remove("selected");
});
switch (bomLayout) {
case "bom-only":
bomButtons.btnBOMOnly.classList.add("selected");
document.getElementById("topcanvas").classList.remove("split-horizontal");
document.getElementById("bottomcanvas").classList.remove("split-horizontal");
document.getElementById("topcanvas").style.display = "none";
document.getElementById("bottomcanvas").style.display = "none";
document.getElementById("divbom").classList.remove("split-horizontal");
document.getElementById("divbom").style.width = "";
destorySplitters();
break;
case "top-bottom":
bomButtons.btnBOMTopBottom.classList.add("selected");
document.getElementById("divbom").classList.remove("split-horizontal");
document.getElementById("divbom").style.width = "";
document.getElementById("divbom").style.height = "";
document.getElementById("divcanvas").classList.remove("split-horizontal");
document.getElementById("divcanvas").style.width = "";
document.getElementById("divcanvas").style.height = "";
document.getElementById("topcanvas").style.display = "";
document.getElementById("topcanvas").classList.add("split-horizontal");
document.getElementById("topcanvas").style.width = "";
document.getElementById("topcanvas").style.height = "";
document.getElementById("bottomcanvas").style.display = "";
document.getElementById("bottomcanvas").classList.add("split-horizontal");
document.getElementById("bottomcanvas").style.width = "";
document.getElementById("bottomcanvas").style.height = "";
destorySplitters();
bomsplit = Split(["#divbom", "#divcanvas"], {
sizes: [50, 50],
gutterSize: 6,
direction: "vertical",
onDragEnd: resizeAll
});
canvassplit = Split(["#topcanvas", "#bottomcanvas"], {
sizes: [50, 50],
gutterSize: 6,
direction: "horizontal",
onDragEnd: resizeAll
});
break;
case "left-right":
bomButtons.btnBOMLeftRight.classList.add("selected");
document.getElementById("topcanvas").style.display = "";
document.getElementById("bottomcanvas").style.display = "";
document.getElementById("topcanvas").classList.remove("split-horizontal");
document.getElementById("bottomcanvas").classList.remove("split-horizontal");
document.getElementById("divbom").classList.add("split-horizontal");
document.getElementById("divcanvas").classList.add("split-horizontal");
destorySplitters();
bomsplit = Split(["#divbom", "#divcanvas"], {
sizes: [50, 50],
gutterSize: 6,
direction: "horizontal",
onDragEnd: resizeAll
});
canvassplit = Split(["#topcanvas", "#bottomcanvas"], {
sizes: [50, 50],
gutterSize: 6,
direction: "vertical",
onDragEnd: resizeAll
});
break;
default:
return;
}
settings.bom_layout = bomLayout;
changeCanvasLayout(settings.canvas_layout);
}
function changeCanvasLayout(canvasLayout) {
Object.keys(canvasButtons).forEach(function(btnName) {
canvasButtons[btnName].classList.remove("selected");
});
switch (canvasLayout) {
case "T":
canvasButtons.btnT.classList.add("selected");
if (settings.bom_layout !== "bom-only") {
canvassplit.collapse(1);
}
break;
case "B":
canvasButtons.btnB.classList.add("selected");
if (settings.bom_layout !== "bom-only") {
canvassplit.collapse(0);
}
break;
case "TB":
default:
canvasButtons.btnTB.classList.add("selected");
if (settings.bom_layout !== "bom-only") {
canvassplit.setSizes([50, 50]);
}
}
if (settings.canvas_layout !== canvasLayout) {
selectedComps = [];
}
settings.canvas_layout = canvasLayout;
resizeAll();
changeBomGroup(settings.bom_group);
}
// bom group
function changeBomGroup(group) {
Object.keys(groupButtons).forEach(function(btnName) {
groupButtons[btnName].classList.remove("selected");
});
switch (group) {
case "U":
default:
groupButtons.btnU.classList.add("selected");
groupFilter = filterGUngroup;
break;
case "NL":
groupButtons.btnNL.classList.add("selected");
groupFilter = null;
break;
case "N":
groupButtons.btnN.classList.add("selected");
groupFilter = filterGName;
break;
case "NV":
groupButtons.btnNV.classList.add("selected");
groupFilter = filterGNameValue;
break;
case "NP":
groupButtons.btnNP.classList.add("selected");
groupFilter = filterGNamePattern;
break;
case "NVP":
groupButtons.btnNVP.classList.add("selected");
groupFilter = filterGNameValuePattern;
break;
}
if (group !== settings.bom_group) {
settings.bom_group = group;
selectedComps = [];
selectedNet = null;
lastActive = null;
//bomSortFunction = null;
//currentSortColumn = null;
//currentSortOrder = null;
clearCanvas(canvases.topcanvas.hl, null);
clearCanvas(canvases.bottomcanvas.hl, null);
}
populateBomTable();
}
// bom table
function populateBomTable() {
total = {};
totalCount = {};
populateBomTableHeader();
populateBomTableBody();
var currencies = Object.keys(total);
if (settings.bom_group !== 'NL' && currencies.length > 0) {
var cols = ['6', '3'];
if (settings.bom_group == 'U') {
cols[0] = '5';
}
// first currency
var tr = document.createElement('tr');
// "Total"
var td = document.createElement('td');
td.setAttribute('colspan', cols[0]);
td.innerHTML = '<strong>Total</strong>';
tr.appendChild(td);
// total quantity
td = document.createElement('td');
td.innerHTML = '<strong>' + pcbdata.components.slice().length + '</strong>';
tr.appendChild(td);
if (settings.show_suppliers) {
// supplier, price, order link
td = document.createElement('td');
td.setAttribute('colspan', cols[1]);
tr.appendChild(td);
}
bomtblbody.appendChild(tr);
// other currencies
if (settings.show_suppliers) {
for (var i = 0; i < currencies.length; ++i) {
tr = document.createElement('tr');
td = document.createElement('td');
td.setAttribute('colspan', cols[0]);
tr.appendChild(td);
// total quantity
td = document.createElement('td');
td.innerHTML = totalCount[currencies[i]];
tr.appendChild(td);
// supplier, price, order link
td = document.createElement('td');
td.setAttribute('colspan', cols[1]);
td.innerHTML = '<strong>' + total[currencies[i]] + ' ' + currencies[i] + '</strong>';
tr.appendChild(td);
bomtblbody.appendChild(tr);
}
}
}
}
// bom table: header
function makeColumnHeader(name, cssName) {
var th = document.createElement("th");
th.innerHTML = name;
if (cssName !== null) {
th.classList.add(cssName);
}
return th;
}
function populateBomTableHeader() {
while (bomtblhead.firstChild) {
bomtblhead.removeChild(bomtblhead.firstChild);
}
var tr = document.createElement("tr");
// number
var th = document.createElement("th");
th.classList.add("numcol");
tr.appendChild(th);
if (settings.bom_group === "NL") {
th = makeColumnHeader("Net name", null);
tr.appendChild(th);
} else {
// checkbox
tr.appendChild(makeColumnHeader("Placed", "bom-checkbox"));
// preferences
tr.appendChild(makeColumnHeader("Reference(s)", null));
// component name
tr.appendChild(makeColumnHeader("Name", null));
// value
tr.appendChild(makeColumnHeader("Value", "value"));
// pattern
tr.appendChild(makeColumnHeader("Pattern", null));
// quantity
if (settings.bom_group !== "U") {
tr.appendChild(makeColumnHeader("Quantity", "quantity"));
}
// suppliers
if (settings.show_suppliers == true) {
// supplier
tr.appendChild(makeColumnHeader("Supplier", null));
// price
tr.appendChild(makeColumnHeader("Price", null));
// link
tr.appendChild(makeColumnHeader("Order Link", null));
}
}
bomtblhead.appendChild(tr);
}
// bom table: body
function tildFilter(netName) {
var prevInv = false;
var sb = [];
var tmp = netName.split("").map(function(token) {
if (token !== "~" || prevInv) {
if (token === "~" && prevInv) {
sb.pop();
}
sb.push(token);
prevInv = false;
return "-";
} else {
prevInv = true;
sb.push("!");
return "!";
}
});
var res = sb.join("");
var matches = res.match(/(!\w+)/g);
for (var i in matches) {
var n = +i;
var match = matches[n];
var ss = match.substring(1);
res = res.replace(match, "<
span class='net_inverse'>
" + ss + "<
/span>
");
}
return res;
}
function calcCount(currency, quantity) {
if (totalCount.hasOwnProperty(currency)) {
totalCount[currency] = totalCount[currency] + quantity;
} else {
totalCount[currency] = quantity;
}
}
function calcTotal(currency, qantity, price) {
curr_total = qantity * price;
if (total.hasOwnProperty(currency)) {
total[currency] = total[currency] + curr_total;
} else {
total[currency] = curr_total;
}
calcCount(currency, qantity);
}
const filterGUngroup = function(comps) {
var res = [];
for (var i in comps) {
var c = comps[+i];
var supplier = '';
var currency = '';
var price = 0;
var link = '';
if (c.hasOwnProperty('supplier')) {
supplier = c.supplier;
currency = c.currency;
price = c.price['gu'];
link = c.link;
calcTotal(currency, 1, price);
}
res.push([c.refdes, c.name, c.value, c.pattern, 1, supplier, currency, price, link]);
}
return res;
}
const filterGName = function(comps) {
var res = [];
var skip = [];
for (var i in comps) {
if (skip.indexOf(+i) < 0) {
var comp = comps[+i];
var group = comps.filter(function(c, index) {
if (skip.indexOf(index) < 0 && c["name"] === comp["name"]) {
skip.push(index);
return true;
}
});
var refs = group.map(function(c) {
return c["refdes"];
}).join(", ");
var name = comp["name"];
var value = group.map(function(c) {
return c["value"];
}).join(", ");
var pattern = group.map(function(c) {
return c["pattern"];
}).join(", ");
var quantity = group.length;
var supplier = '';
var currency = '';
var price = 0;
var link = '';
if (comp.hasOwnProperty('supplier')) {
supplier = comp.supplier;
currency = comp.currency;
price = comp.price['gn'];
link = comp.link;
calcTotal(currency, quantity, price);
}
res.push([refs, name, value, pattern, quantity, supplier, currency, price, link]);
}
}
return res;
}
const filterGNameValue = function(comps) {
var res = [];
var skip = [];
for (var i in comps) {
if (skip.indexOf(+i) < 0) {
var comp = comps[+i];
var group = comps.filter(function(c, index) {
if (skip.indexOf(index) < 0 && c["name"] === comp["name"] && c["value"] === comp["value"]) {
skip.push(index);
return true;
}
});
var refs = group.map(function(c) {
return c["refdes"];
}).join(", ");
var name = comp["name"];
var value = comp["value"];
var pattern = group.map(function(c) {
return c["pattern"];
}).join(", ");
var quantity = group.length;
var supplier = '';
var currency = '';
var price = 0;
var link = '';
if (comp.hasOwnProperty('supplier')) {
supplier = comp.supplier;
currency = comp.currency;
price = comp.price['gnv'];
link = comp.link;
calcTotal(currency, quantity, price);
}
res.push([refs, name, value, pattern, quantity, supplier, currency, price, link]);
}
}
return res;
}
const filterGNamePattern = function(comps) {
var res = [];
var skip = [];
for (var i in comps) {
if (skip.indexOf(+i) < 0) {
var comp = comps[+i];
var group = comps.filter(function(c, index) {
if (skip.indexOf(index) < 0 && c["name"] === comp["name"] && c["pattern"] === comp["pattern"]) {
skip.push(index);
return true;
}
});
var refs = group.map(function(c) {
return c["refdes"];
}).join(", ");
var name = comp["name"];
var value = group.map(function(c) {
return c["value"];
}).join(", ");
var pattern = comp["pattern"];
var quantity = group.length;
var supplier = '';
var currency = '';
var price = 0;
var link = '';
if (comp.hasOwnProperty('supplier')) {
supplier = comp.supplier;
currency = comp.currency;
price = comp.price['gnp'];
link = comp.link;
calcTotal(currency, quantity, price);
}
res.push([refs, name, value, pattern, quantity, supplier, currency, price, link]);
}
}
return res;
}
const filterGNameValuePattern = function(comps) {
var res = [];
var skip = [];
for (var i in comps) {
if (skip.indexOf(+i) < 0) {
var comp = comps[+i];
var group = comps.filter(function(c, index) {
if (skip.indexOf(index) < 0 && c["name"] === comp["name"] && c["value"] === comp["value"] && c["pattern"] === comp["pattern"]) {
skip.push(index);
return true;
}
});
var refs = group.map(function(c) {
return c["refdes"];
}).join(", ");
var name = comp["name"];
var value = comp["value"];
var pattern = comp["pattern"];
var quantity = group.length;
var pattern = comp["pattern"];
var quantity = group.length;
var supplier = '';
var currency = '';
var price = 0;
var link = '';
if (comp.hasOwnProperty('supplier')) {
supplier = comp.supplier;
currency = comp.currency;
price = comp.price['gnp'];
link = comp.link;
calcTotal(currency, quantity, price);
}
res.push([refs, name, value, pattern, quantity, supplier, currency, price, link]);
}
}
return res;
}
function populateNetBody() {
var rownum = 0;
for (var i in pcbdata.nets) {
rownum++;
if (pcbdata.nets[rownum - 1].name === "None") {
return;
}
var tr = document.createElement("tr");
tr.id = "bomrow" + rownum;
var td = document.createElement("td");
td.textContent = rownum.toString();
tr.appendChild(td);
td = document.createElement("td");
td.innerHTML = tildFilter(pcbdata.nets[rownum - 1].name);
tr.appendChild(td);
bomtblbody.appendChild(tr);
// mouse events
tr.addEventListener("mouseenter", function(e) {
if (lastActive !== null) {
lastActive.classList.remove("active");
}
e.currentTarget.classList.add("active");
selectedNet = Number(e.currentTarget.childNodes[0].innerHTML) - 1;
drawHLNet();
});
tr.addEventListener("mouseleave", function(e) {
lastActive = e.currentTarget;
})
}
}
function stylizeRefDes(refdes) {
return '<p class="placed">' + refdes + '</p>';
}
function cleanRefDes(refdesWithStyle) {
var a = refdesWithStyle.replace('<p class="placed">', '');
var b = a.replace('</p>', '');
return b;
}
function replaceRefDes(elem_td, refs) {
var k = 0;
var data = '';
for (var i = 0; i < refs.length; ++i) {
var pre = ', ';
if (i == 0) {
pre = '';
}
if (settings.placed.indexOf(refs[i]) !== -1) {
k++;
data += pre + stylizeRefDes(refs[i]);
} else {
data += pre + refs[i];
}
}
elem_td.innerHTML = data;
return (k == refs.length);
}
function populateComponentsBody() {
var comps = pcbdata.components.slice();
switch (settings.canvas_layout) {
case "T":
comps = comps.filter(function(comp) {
return comp.lay === "T";
});
break;
case "B":
comps = comps.filter(function(comp) {
return comp.lay === "B";
});
break;
case "TB":
break;
default:
return;
}
// groupping
if (groupFilter === null) {
return;
}
var groupped = groupFilter(comps);
// create rows
for (var i in groupped) {
var group = groupped[+i];
var tr = document.createElement("tr");
// number
var td = document.createElement("td");
td.innerHTML = (+i + 1).toString();
tr.appendChild(td);
// placed
td = document.createElement("td");
var cb = document.createElement("input");
cb.type = "checkbox";
cb.setAttribute('id', (+i + 1).toString());
cb.onclick = function() {
var elem_refs = document.getElementById('refs_' + this.id);
var refs = elem_refs.innerHTML.split(', ');
for (var j = 0; j < refs.length; ++j) {
refs[j] = cleanRefDes(refs[j]);
}
if (this.checked) {
refs.forEach(function(ref) {
if (settings.placed.indexOf(ref) == -1) {
settings.placed.push(ref);
}
});
} else {
refs.forEach(function(ref) {
var j = settings.placed.indexOf(ref);
if (j != -1) {
settings.placed.splice(j, 1);
}
});
}
replaceRefDes(elem_refs, refs);
}
td.appendChild(cb);
tr.appendChild(td);
// refdes
td = document.createElement("td");
td.setAttribute('id', 'refs_' + (+i + 1).toString());
var refs = group[0].split(', ');
cb.checked = replaceRefDes(td, refs);
tr.appendChild(td);
// name
td = document.createElement("td");
td.innerHTML = group[1];
tr.appendChild(td);
// value
td = document.createElement("td");
td.innerHTML = group[2];
tr.appendChild(td);
// pattern
td = document.createElement("td");
td.innerHTML = group[3];
tr.appendChild(td);
// quantity
if (settings.bom_group !== "U") {
td = document.createElement("td");
td.innerHTML = group[4];
tr.appendChild(td);
}
// suppliers
if (settings.show_suppliers == true) {
// supplier
td = document.createElement("td");
td.innerHTML = group[5];
tr.appendChild(td);
// currency + price
td = document.createElement("td");
if (group[7] > 0) {
td.innerHTML = group[7] + ' ' + group[6];
}
tr.appendChild(td);
// link
td = document.createElement("td");
if (group[8] !== '') {
td.innerHTML = '<a href="' + group[8] + '" target="_blank">Visit Site</a>';
}
tr.appendChild(td);
}
bomtblbody.appendChild(tr);
// mouse events
tr.addEventListener("mouseenter", function(e) {
if (lastActive !== null) {
lastActive.classList.remove("active");
}
e.currentTarget.classList.add("active");
selectedComps = [];
var refs = e.currentTarget.childNodes[2].innerHTML.split(", ");
for (var j = 0; j < refs.length; ++j) {
refs[j] = cleanRefDes(refs[j]);
}
while (refs.length > 0) {
selectedComps.push(pcbdata.components.find(function(comp) {
return comp.refdes === refs[0];
}));
refs.shift();
}
drawComponentsBB(selectedComps);
});
tr.addEventListener("mouseleave", function(e) {
lastActive = e.currentTarget;
});
}
}
function populateBomTableBody() {
var rowname = null;
if (settings.bom_group === "NL" && lastActive !== null) {
rowname = lastActive.id;
}
while (bomtblbody.firstChild) {
bomtblbody.removeChild(bomtblbody.firstChild);
}
if (settings.bom_group === "NL") {
populateNetBody();
if (rowname !== null) {
lastActive = document.getElementById(rowname);
lastActive.classList.add("active");
}
} else {
populateComponentsBody();
}
}
// canvas
function recalcLayerScale(dict, width, height) {
if (!initDone) {
return;
}
var bbox = applyRotationDeg(pcbdata.board.bound_box, settings.board_rotation);
var scaleFactor = 0.98 * Math.min(width / (bbox.maxx - bbox.minx), height / (bbox.maxy - bbox.miny));
if (scaleFactor < 0.1) {
scaleFactor = 1;
}
dict.trsf.scale = scaleFactor;
var flip = (dict.layer == "B");
if (flip) {
dict.trsf.x = -((bbox.maxx + bbox.minx) * scaleFactor + width) * 0.5;
} else {
dict.trsf.x = -((bbox.maxx + bbox.minx) * scaleFactor - width) * 0.5;
}
dict.trsf.y = -((bbox.maxy + bbox.miny) * scaleFactor - height) * 0.5;
// setup canvas size
cnames.forEach(function(c) {
var canvas = dict[c];
canvas.width = width;
canvas.height = height;
canvas.style.width = (width / devicePixelRatio) + "px";
canvas.style.height = (height / devicePixelRatio) + "px";
});
}
function prepareCanvas(canvas, flip, trsf) {
var ctx = canvas.getContext("2d");
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.scale(trsf.zoom, trsf.zoom);
ctx.translate(trsf.panx, trsf.pany);
if (flip) {
ctx.scale(-1, 1);
}
ctx.translate(trsf.x, trsf.y);
ctx.rotate(deg2rad(settings.board_rotation));
ctx.scale(trsf.scale, trsf.scale);
}
function prepareLayer(dict) {
var flip = (dict.layer == "B");
cnames.forEach(function(c) {
prepareCanvas(dict[c], flip, dict.trsf);
});
}
function clearCanvas(canvas, color) {
painter.ctx = canvas.getContext("2d");
painter.clear(canvas.width, canvas.height, color);
}
// shapes
function drawShape(ctx, shape, color) {
painter.ctx = ctx;
var rotation = null;
if (shape.hasOwnProperty("angle")) {
rotation = -shape.angle;
}
switch (shape.tp) {
case "line":
painter.line(shape.point[0], shape.point[1], shape.point[2], shape.point[3], shape.lw, color);
break;
case "arc":
painter.strokeArc(shape.point[0], shape.point[1], shape.point[2], shape.point[3], shape.point[4], shape.point[5], shape.lw, color);
break;
case "closedarc":
painter.closedArc(shape.point[0], shape.point[1], shape.point[2], shape.point[3], shape.point[4], shape.point[5], shape.lw, color);
break;
case 'fillarc':
painter.fillArc(shape.point[0], shape.point[1], shape.point[2], shape.point[3], shape.point[4], shape.point[5], color);
break;
case "rect":
painter.strokeRect(shape.point[0], shape.point[1], shape.point[2], shape.point[3], 0, rotation, shape.lw, color);
break;
case "fillrect":
painter.fillRect(shape.point[0], shape.point[1], shape.point[2], shape.point[3], 0, rotation, color);
break;
case "obround":
painter.strokeObround(shape.point[0], shape.point[1], shape.point[2], shape.point[3], rotation, shape.lw, color);
break;
case "fillobround":
painter.fillObround(shape.point[0], shape.point[1], shape.point[2], shape.point[3], rotation, color);
break;
case "text":
var s = 1.0; //3*25.4/96;
painter.save();
painter.ctx.translate(shape.x, shape.y);
painter.ctx.rotate(-shape.angle);
painter.ctx.scale(s, s);
shape.svg.forEach(function(data) {
var path = new Path2D(data);
if (shape.lw > 0) {
painter.strokePath(path, shape.lw, color);
} else {
painter.fillPath(path, color);
}
});
painter.restore();
break;
case "polyline":
case "polygon":
var pts = shape.point.slice();
var path = new Path2D();
path.moveTo(pts[0], pts[1]);
pts.shift();
pts.shift();
while (pts.length > 0) {
path.lineTo(pts[0], pts[1]);
pts.shift();
pts.shift();
}
if (shape.tp === "polyline") {
painter.strokePath(path, shape.lw, color);
} else {
path.closePath();
painter.fillPath(path, color);
}
break;
}
}
// canvas: draw components
function drawPads(canvas, pads, padColor, layer, tp) {
var ltp = pcbdata.board[layer].tp;
var ring = pcbdata.board[layer].ring;
painter.ctx = canvas.getContext("2d");
pads.forEach(function(pad) {
var offx = 0;
var offy = 0;
if (!pad.surface) {
offx = pad.offx;
offy = pad.offy;
}
var via = (tp === "svias" || tp === "dvias");
var block = !pad.surface && ((layer === 'T' && pad.blockTop) || (layer === 'B' && pad.blockBottom));
painter.save();
painter.ctx.translate(pad.x, pad.y);
painter.ctx.rotate(-pad.angle); // ccw to cw
painter.ctx.translate(offx, offy);
if (!block) {
if (ltp === "signal" || pad.surface || via) {
switch (pad.ctype) {
case "ellipse":
painter.fillEllipse(0, 0, pad.width / 2, pad.height / 2, 0, padColor);
break;
case "obround":
painter.fillObround(0, 0, pad.width, pad.height, 0, padColor);
break;
case "rect":
painter.fillRect(0, 0, pad.width, pad.height, pad.crad, 0, padColor);
break;
case "dshape":
painter.fillDShape(0, 0, pad.width, pad.height, padColor);
break;
case "polygon":
var path = new Path2D();
var pts = pad.point.slice();
path.moveTo(pts[0], pts[1]);
pts.shift();
pts.shift();
while (pts.length > 0) {
path.lineTo(pts[0], pts[1]);
pts.shift();
pts.shift();
}
path.closePath();
painter.fillPath(path, padColor);
break;
default:
break;
}
} else if (ltp === "pads" && !pad.surface) {
var minv = Math.min(pad.width, pad.height);
painter.fillObround(0, 0, minv, minv, 0, padColor);
} else if (ltp === "ring" && !pad.surface) {
var diam = Infinity;
switch (pad.htype) {
case "round":
diam = pad.ctw + ring * 2;
break;
case "obround":
diam = Math.min(pad.ctw, pad.cth) + ring * 2;
break;
case "rect":
diam = Math.hypot(pad.ctw, pad.cth) + ring * 2;
break;
default:
break;
}
if (isFinite(diam)) {
painter.fillObround(0, 0, diam, diam, 0, padColor);
}
}
}
if (!pad.surface) {
painter.ctx.translate(-offx, -offy);
if (!(via && block)) {
switch (pad.htype) {
case "round":
painter.fillEllipse(0, 0, pad.ctw / 2, pad.ctw / 2, 0, pcbdata.board.bgcolor);
break;
case "obround":
painter.fillObround(0, 0, pad.ctw, pad.cth, 0, pcbdata.board.bgcolor);
break;
case "rect":
painter.fillRect(0, 0, pad.ctw, pad.cth, -1, 0, pcbdata.board.bgcolor);
break;
default:
break;
}
}
}
painter.restore();
});
}
function drawComponents(tp, canvas, layer) {
var padColor = pcbdata.colors[layer].pads;
pcbdata[tp].forEach(function(comp) {
var pads = comp.pads.filter(function(pad) {
if (pad.surface) {
return comp.lay === layer && !pad.sided;
} else {
return true;
}
});
drawPads(canvas, pads, padColor, layer, tp);
if (comp.hasOwnProperty("holes") && comp.holes.length > 0) {
painter.ctx = canvas.getContext("2d");
var pts = comp.holes.slice();
while (pts.length > 0) {
painter.fillEllipse(pts[0], pts[1], pts[2], pts[2], 0, pcbdata.board.bgcolor);
pts = pts.slice(3);
}
}
if (comp.hasOwnProperty("shapes")) {
var shapes = comp.shapes.filter(function(shape) {
return shape.lay === layer;
});
var ctx = canvas.getContext("2d");
ctx.save();
ctx.translate(comp.x, comp.y);
ctx.rotate(-comp.angle);
shapes.forEach(function(shape) {
drawShape(ctx, shape, padColor);
});
ctx.restore();
}
});
}
function drawComponentsBB(comps) {
clearCanvas(canvases.topcanvas.hl, null);
clearCanvas(canvases.bottomcanvas.hl, null);
comps.forEach(function(comp) {
var cname = {
"T": "topcanvas",
"B": "bottomcanvas"
}[comp.lay];
var canvas = canvases[cname].hl;
var lw = 1.27 / canvases[cname].trsf.zoom;
var rbb = applyRotationRad(comp.bound_box, comp.angle);
var x = (comp.bound_box.minx + comp.bound_box.maxx) / 2;
var y = (comp.bound_box.miny + comp.bound_box.maxy) / 2;
var w = rbb.maxx - rbb.minx;
var h = rbb.maxy - rbb.miny;
painter.ctx = canvas.getContext("2d");
painter.save();
painter.ctx.translate(x, y);
painter.ctx.rotate(comp.rotate);
painter.strokeRect(0, 0, w, h, 0, 0, lw, hlColor);
painter.restore();
});
}
// canvas: mounting holes
function drawMTHoles(canvas) {
pcbdata.mtholes.forEach(function(hole) {
var pts = hole.point.slice();
painter.ctx = canvas.getContext("2d");
while (pts.length > 0) {
painter.fillEllipse(pts[0], pts[1], pts[2], pts[2], 0, pcbdata.board.bgcolor);
pts = pts.slice(3);
}
});
}
// canvas: draw board outline
function drawBoardOutline(canvas, scale) {
var color = pcbdata.board.color;
var ctx = canvas.getContext("2d");
// edges
pcbdata.board.outline.forEach(function(shape) {
var lw = null;
if (shape.hasOwnProperty("lw")) {
lw = shape.lw;
shape.lw = Math.max(1.27 / scale, lw);
}
drawShape(ctx, shape, color);
if (lw !== null) {
shape.lw = lw;
}
});
var shapes = [];
// holes
shapes = pcbdata.board.cutout.filter(function(shape) {
return !shape.hasOwnProperty("lw");
});
shapes.forEach(function(shape) {
drawShape(ctx, shape, pcbdata.board.bgcolor);
});
// edges
shapes = pcbdata.board.cutout.filter(function(shape) {
return shape.hasOwnProperty("lw");
});
shapes.forEach(function(shape) {
var lw = shape.lw;
shape.lw = Math.max(1.27 / scale, lw);
drawShape(ctx, shape, color);
shape.lw = lw;
});
}
// canvas: draw nets
function drawNetPlains(canvas, plains, color) {
var cxt = canvas.getContext("2d");
plains.forEach(function(plain) {
plain.lines.forEach(function(line, index) {
var lw = null;
if (index > 0 && index < plain.lines.length - 1 && line.hasOwnProperty("lw")) {
lw = line.lw;
line.lw -= (lw - 4 * Math.round(lw * 100 / 4 + 0.5) / 100) * 8;
}
drawShape(cxt, line, color);
if (lw) {
line.lw = lw;
}
});
});
}
function drawNetHLPlains(canvas, plains, color, zoom) {
painter.ctx = canvas.getContext("2d");
var lw = 1.27 / zoom
plains.forEach(function(plain) {
var pts = plain.contour.point.slice();
var path = new Path2D();
path.moveTo(pts[0], pts[1]);
pts.shift();
pts.shift();
while (pts.length > 0) {
path.lineTo(pts[0], pts[1]);
pts.shift();
pts.shift();
}
path.closePath();
painter.strokePath(path, lw, color);
});
}
function drawNetLines(canvas, lines, color) {
var ctx = canvas.getContext("2d");
lines.forEach(function(line) {
drawShape(ctx, line, color);
});
}
function drawNets(canvas, layer, color) {
if (!("nets" in pcbdata))
return;
pcbdata.nets.forEach(function(net) {
if (!("lines" in net))
return;
var lines = net.lines.filter(function(line) {
return line.lay === layer;
});
drawNetLines(canvas, lines, color);
});
}
function drawPlains(canvas, layer, color) {
if (!("nets" in pcbdata))
return;
pcbdata.nets.forEach(function(net) {
var plains = net.plains.filter(function(plain) {
return plain.lay === layer;
});
drawNetPlains(canvas, plains, color);
});
}
function drawHLNet() {
var net = pcbdata.nets[selectedNet];
["T", "B"].forEach(function(layer) {
var cname = {
"T": "topcanvas",
"B": "bottomcanvas"
}[layer];
var canvas = canvases[cname].hl;
clearCanvas(canvas, null);
// lines
if (settings.draw_nets && ("lines" in net)) {
var lines = net.lines.filter(function(line) {
return line.lay == layer;
});
drawNetLines(canvas, lines, hlColor);
}
// plains
if ("plains" in net) {
var plains = [];
plains = net.plains.filter(function(plain) {
return plain.lay === layer;
});
drawNetHLPlains(canvas, plains, hlPlainColor, canvases[cname].trsf.zoom);
}
// free shapes
if ("freeshapes" in pcbdata) {
var freeshapes = [];
freeshapes = pcbdata.freeshapes.filter(function(shape) {
return (shape.lay === layer && shape.net === selectedNet);
});
freeshapes.forEach(function(shape) {
var ctx = canvas.getContext("2d");
drawShape(ctx, shape, hlColor);
});
}
// pads
var comps = [];
if (settings.draw_pads) {
comps.push("components");
comps.push("freepads");
}
if (settings.draw_fiducials) {
comps.push("fiducials");
}
if (settings.draw_vias) {
comps.push("sviases");
comps.push("dviases");
}
comps.forEach(function(tp) {
if (pcbdata[tp] === undefined) {
return;
}
pcbdata[tp].forEach(function(comp) {
var pads = comp.pads.filter(function(pad) {
if (pad.net === selectedNet) {
if (pad.surface) {
return (comp.lay === layer && !pad.sided);
} else {
return true;
}
} else {
return false;
}
});
if (pads.length > 0) {
drawPads(canvas, pads, hlColor, layer, tp);
}
});
});
});
}
// canvas: draw background layers
function drawBack(dict, clear) {
if (clear) {
clearCanvas(dict.bg, null);
clearCanvas(dict.silk, null);
clearCanvas(dict.assy, null);
}
var color = pcbdata.colors[dict.layer].pads;
if (settings.draw_nets) {
drawNets(dict.bg, dict.layer, color);
}
if (settings.draw_copper_pours) {
drawPlains(dict.bg, dict.layer, color);
}
// draw free shapes
var freeshapes = pcbdata.freeshapes.filter(function(shape) {
return shape.lay === dict.layer;
});
freeshapes.forEach(function(shape) {
var ctx = dict.bg.getContext("2d");
drawShape(ctx, shape, color);
});
// components, free pads, fiducials, viases
var comps = [];
if (settings.draw_pads) {
comps.push("components");
comps.push("freepads");
}
if (settings.draw_fiducials) {
comps.push("fiducials");
}
if (settings.draw_vias) {
comps.push("svias");
comps.push("dvias");
}
comps.forEach(function(tp) {
drawComponents(tp, dict.bg, dict.layer);
});
drawMTHoles(dict.bg);
drawBoardOutline(dict.bg, dict.trsf.zoom);
// silk
if (settings.draw_silk) {
var shapes = pcbdata.silk.filter(function(shape) {
return (shape.lay === dict.layer);
});
var ctx = dict.silk.getContext("2d");
shapes.forEach(function(shape) {
drawShape(ctx, shape, pcbdata.colors[dict.layer].silk);
});
}
// assy
if (settings.draw_assy) {
var ctx = dict.assy.getContext("2d");
var assyColor = pcbdata.colors[dict.layer].assy;
var shapes = pcbdata.assy.filter(function(shape) {
return (shape.lay === dict.layer);
});
shapes.forEach(function(shape) {
drawShape(ctx, shape, assyColor);
});
if (pcbdata.board.pads_on_assy) {
comps = [];
comps.push("components");
comps.push("freepads");
comps.push("fiducials");
comps.forEach(function(tp) {
pcbdata[tp].forEach(function(comp) {
var pads = comp.pads.filter(function(pad) {
if (pad.surface) {
return comp.lay === dict.layer && !pad.sided;
} else {
return true;
}
});
drawPads(dict.assy, pads, assyColor, dict.layer, tp);
});
});
}
}
}
// canvas: draw highlight on layer
function drawHLOnLayer(dict) {
if (selectedComps.length > 0) {
drawComponentsBB(selectedComps);
}
if (selectedNet !== null && selectedNet < pcbdata.nets.length) {
drawHLNet();
}
}
function redrawCanvas(dict) {
prepareLayer(dict);
drawBack(dict, true);
drawHLOnLayer(dict);
}
function redrawIfInitDone() {
if (initDone) {
redrawCanvas(canvases.topcanvas);
redrawCanvas(canvases.bottomcanvas);
}
}
// resizers
function resizeCanvas(dict) {
var divcanvasid = {
"T": "topcanvas",
"B": "bottomcanvas"
}[dict.layer];
var divcanvas = document.getElementById(divcanvasid);
var width = divcanvas.clientWidth * devicePixelRatio;
var height = divcanvas.clientHeight * devicePixelRatio;
recalcLayerScale(dict, width, height);
redrawCanvas(dict);
}
function resizeAll() {
resizeCanvas(canvases.topcanvas);
resizeCanvas(canvases.bottomcanvas);
}
/*----- prefs functions -----*/
function setDisplayAssy(val) {
settings.draw_assy = val;
setTimeout(function() {
redrawIfInitDone();
}, 20);
}
function setDisplaySilk(val) {
settings.draw_silk = val;
setTimeout(function() {
redrawIfInitDone();
}, 20);
}
function setDisplayNets(val) {
settings.draw_nets = val;
setTimeout(function() {
redrawIfInitDone();
}, 20);
}
function setDisplayCopperPours(val) {
settings.draw_copper_pours = val;
setTimeout(function() {
redrawIfInitDone();
}, 20);
}
function setDisplayFiducials(val) {
settings.draw_fiducials = val;
setTimeout(function() {
redrawIfInitDone();
}, 20);
}
function setDisplayPads(val) {
settings.draw_pads = val;
setTimeout(function() {
redrawIfInitDone();
}, 20);
}
function setDisplayVias(val) {
settings.draw_vias = val;
setTimeout(function() {
redrawIfInitDone();
}, 20);
}
function setDisplaySuppliers(val) {
settings.show_suppliers = val;
setTimeout(function() {
// switch bom group
changeBomGroup(settings.bom_group);
}, 20);
}
function setBoardRotation(degree) {
settings.board_rotation = degree * 5;
document.getElementById("boardRotationDegree").textContent = settings.board_rotation.toString();
setTimeout(function() {
resizeAll();
}, 20);
}
function setupPrefs() {
// setup prefs checkboxes
document.getElementById("cbDisplayAssy").checked = settings.draw_assy;
document.getElementById("cbDisplaySilk").checked = settings.draw_silk;
document.getElementById("cbDisplayNets").checked = settings.draw_nets;
document.getElementById("cbDisplayCopperPours").checked = settings.draw_copper_pours;
document.getElementById("cbDisplayFiducials").checked = settings.draw_fiducials;
document.getElementById("cbDisplayPads").checked = settings.draw_pads;
document.getElementById("cbDisplayVias").checked = settings.draw_vias;
document.getElementById("cbDisplaySuppliers").checked = settings.show_suppliers;
// board rotation slider
document.getElementById("boardRotation").value = (settings.board_rotation / 5.0).toString();
document.getElementById("boardRotationDegree").textContent = settings.board_rotation.toString();
}
/*----- event handlers -----*/
// window events
function onWindowLoadHandler(e) {
try {
var bin = "";
pcbdata = JSON.parse(LZString.decompressFromBase64(bin));
storagePrefix = "DipTrace_BOM_" + pcbdata.metadata.board_name + "__#";
initStorage();
initDefaults();
writeAll();
initRender();
setupPrefs();
removeGutters();
// hide Netlist button, if no nets
hideNetListBnt = !("nets" in pcbdata) || (pcbdata.nets.length == 1 && pcbdata.nets[0].name === 'None')
if (hideNetListBnt) {
if (settings.bom_group === "NL") {
settings.bom_group = "U";
}
document.getElementById("btnGNetlist").style.display = "none";
}
initDone = true;
// switch bom layout
changeBOMLayout(settings.bom_layout);
} catch (e) {
var ediv = document.createElement("div");
ediv.innerHTML = "<
h2 style='text-align: center; color: red;'>PCB
data is incorrect or corrupted.<
/h2>
";
document.body.insertBefore(ediv, document.body.childNodes[0]);
}
}
function onWindowResizeHandler(e) {
resizeAll();
}
function onWindowBeforeUnload(e) {
writeAll();
}
/*----- entry point -----*/
// variables
var initDone = false;
var pcbdata = null;
var storagePrefix = null;
var storage = null;
var lastActive = null;
var selectedComps = [];
var selectedNet = null;
var hlColor = "#df4056";
var hlPlainColor = "#ed6f15";
var settings = {
bom_layout: "left-right",
bom_group: "U",
canvas_layout: "TB",
draw_silk: true,
draw_assy: false,
draw_nets: true,
draw_copper_pours: false,
draw_fiducials: true,
draw_pads: true,
draw_vias: true,
show_suppliers: true,
board_rotation: 0,
placed: null
}
var bomsplit;
var canvassplit;
var cnames = ["bg", "silk", "assy", "hl"];
var canvases = {
topcanvas: {
layer: "T",
bg: document.getElementById("topBG"),
silk: document.getElementById("topSILK"),
assy: document.getElementById("topASSY"),
hl: document.getElementById("topHL"),
trsf: {
x: 0,
y: 0,
scale: 1,
panx: 0,
pany: 0,
zoom: 1
},
pstate: {}
},
bottomcanvas: {
layer: "B",
bg: document.getElementById("bottomBG"),
silk: document.getElementById("bottomSILK"),
assy: document.getElementById("bottomASSY"),
hl: document.getElementById("bottomHL"),
trsf: {
x: 0,
y: 0,
scale: 1,
panx: 0,
pany: 0,
zoom: 1
},
pstate: {}
}
};
var canvasButtons = {
btnT: document.getElementById("btnCanvasTop"),
btnTB: document.getElementById("btnCanvasTopBottom"),
btnB: document.getElementById("btnCanvasBottom")
}
var bomButtons = {
btnBOMOnly: document.getElementById("btnBOMOnly"),
btnBOMLeftRight: document.getElementById("btnBOMLeftRight"),
btnBOMTopBottom: document.getElementById("btnBOMTopBottom")
};
var groupButtons = {
btnU: document.getElementById("btnGUngroup"),
btnNL: document.getElementById("btnGNetlist"),
btnN: document.getElementById("btnGName"),
btnNV: document.getElementById("btnGNameValue"),
btnNP: document.getElementById("btnGNamePattern"),
btnNVP: document.getElementById("btnGNameValuePattern")
};
var bomtblhead = document.getElementById("tblhead");
var bomtblbody = document.getElementById("tblbody");
var groupFilter = null;
var total = {};
var totalCount = {};
// window events
window.addEventListener("load", onWindowLoadHandler);
window.addEventListener("resize", onWindowResizeHandler);
window.addEventListener("beforeunload", onWindowBeforeUnload);
</script>
</body>
</htm