Top secrets sources NedoPC ngs

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <style type="text/css">
        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;
        }
    </style>
</head>

<body>
    <div id="divtopmost" class="divtopmost">
        <div id="divtop">
            <div style="float: right; height: 100%;">
                <!-- prefs menu -->
                <div class="prefs_menu" style="float: right; top: 8px;">
                    <button class="prefs_menubtn"></button>
                    <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 for="cbDisplayAssy">Assembly</label>
                            </label>
                            <label class="prefs_menu_label">
                                <input id="cbDisplaySilk" type="checkbox" onchange="setDisplaySilk(this.checked)" checked>
                                <label for="cbDisplaySilk">Silkscreen</label>
                            </label>
                            <label class="prefs_menu_label">
                                <input id="cbDisplayNets" type="checkbox" onchange="setDisplayNets(this.checked)" checked>
                                <label for="cbDisplayNets">Nets</label>
                            </label>
                            <label class="prefs_menu_label">
                                <input id="cbDisplayCopperPours" type="checkbox" onchange="setDisplayCopperPours(this.checked)">
                                <label for="cbDisplayCopperPours">Copper Pours</label>
                            </label>
                            <label class="prefs_menu_label">
                                <input id="cbDisplayFiducials" type="checkbox" onchange="setDisplayFiducials(this.checked)" checked>
                                <label for="cbDisplayFiducials">Fiducials</label>
                            </label>
                            <label class="prefs_menu_label">
                                <input id="cbDisplayPads" type="checkbox" onchange="setDisplayPads(this.checked)" checked>
                                <label for="cbDisplayPads">Pads</label>
                            </label>
                            <label class="prefs_menu_label">
                                <input id="cbDisplayVias" type="checkbox" onchange="setDisplayVias(this.checked)" checked>
                                <label for="cbDisplayVias">Vias</label>
                            </label>
                            <label class="prefs_menu_label">
                                <input id="cbDisplaySuppliers" type="checkbox" onchange="setDisplaySuppliers(this.checked)" checked>
                                <label for="cbDisplaySuppliers">Suppliers</label>
                            </label>
                        </div>
                        <!-- board rotation -->
                        <div class="prefs_menu_label">
                            <label>
                                <span>Board rotation</span><span style="float: right;"><span id="boardRotationDegree">0</span>&deg;</span>
                                <input id="boardRotation" class="slider" type="range" min="-36" max="36" value="0" oninput="setBoardRotation(this.value)" onchange="setBoardRotation(this.value)">
                            </label>
                        </div>
                        <div class="prefs_menu_label">
                            <label><span id="version" class="version"></span></label>
                        </div>
                    </div>
                </div>
                <!-- 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>
                </div>
                <!-- 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>
                </div>
                <!-- 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>
            </div>
            <div id="boardinfo" style="height: 100%; overflow: auto;">
                <table class="boardinfo">
                    <tbody>
                        <tr>
                            <td id="board_name" class="title"></td>
                        </tr>
                        <tr>
                            <td id="assembly_variant" class="variant"></td>
                        </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <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 -->
                <table class="bom">
                    <thead id="tblhead">
                        <tr>
                            <th class="numcol"></th>
                            <th class="bom-checkbox">Placed</th>
                            <th>Reference(s)</th>
                            <th>Name</th>
                            <th class="value">Value</th>
                            <th>Pattern</th>
                            <th class="quantity">Quantity</th>
                        </tr>
                    </thead>
                    <tbody id="tblbody">
                        <tr id="bomrow1">
                            <td>1</td>
                            <td><input type="checkbox" /></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <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>
                </div>
                <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>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <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