mirror of
https://github.com/skot/bitaxe.git
synced 2025-03-27 10:12:55 +01:00
4346 lines
295 KiB
HTML
4346 lines
295 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Interactive BOM for KiCAD</title>
|
|
<style type="text/css">
|
|
:root {
|
|
--pcb-edge-color: black;
|
|
--pad-color: #878787;
|
|
--pad-hole-color: #CCCCCC;
|
|
--pad-color-highlight: #D04040;
|
|
--pad-color-highlight-both: #D0D040;
|
|
--pad-color-highlight-marked: #44a344;
|
|
--pin1-outline-color: #ffb629;
|
|
--pin1-outline-color-highlight: #ffb629;
|
|
--pin1-outline-color-highlight-both: #fcbb39;
|
|
--pin1-outline-color-highlight-marked: #fdbe41;
|
|
--silkscreen-edge-color: #aa4;
|
|
--silkscreen-polygon-color: #4aa;
|
|
--silkscreen-text-color: #4aa;
|
|
--fabrication-edge-color: #907651;
|
|
--fabrication-polygon-color: #907651;
|
|
--fabrication-text-color: #a27c24;
|
|
--track-color: #def5f1;
|
|
--track-color-highlight: #D04040;
|
|
--zone-color: #def5f1;
|
|
--zone-color-highlight: #d0404080;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
margin: 0px;
|
|
height: 100%;
|
|
font-family: Verdana, sans-serif;
|
|
}
|
|
|
|
.dark.topmostdiv {
|
|
--pcb-edge-color: #eee;
|
|
--pad-color: #808080;
|
|
--pin1-outline-color: #ffa800;
|
|
--pin1-outline-color-highlight: #ccff00;
|
|
--track-color: #42524f;
|
|
--zone-color: #42524f;
|
|
background-color: #252c30;
|
|
color: #eee;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
.dark button {
|
|
/* This will be inverted */
|
|
background-color: #c3b7b5;
|
|
}
|
|
|
|
button.depressed {
|
|
background-color: #0a0;
|
|
color: white;
|
|
}
|
|
|
|
.dark button.depressed {
|
|
/* This will be inverted */
|
|
background-color: #b3b;
|
|
}
|
|
|
|
button:focus {
|
|
outline: 0;
|
|
}
|
|
|
|
button#tb-btn {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' fill='none' stroke='%23000' stroke-width='.4' stroke-linejoin='round'/%3E%3Cpath d='M1.32 290.12h5.82M1.32 291.45h5.82' fill='none' stroke='%23000' stroke-width='.4'/%3E%3Cpath d='M4.37 292.5v4.23M.26 292.63H8.2' fill='none' stroke='%23000' stroke-width='.3'/%3E%3Ctext font-weight='700' font-size='3.17' font-family='sans-serif'%3E%3Ctspan x='1.35' y='295.73'%3EF%3C/tspan%3E%3Ctspan x='5.03' y='295.68'%3EB%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A");
|
|
}
|
|
|
|
button#lr-btn {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' fill='none' stroke='%23000' stroke-width='.4' stroke-linejoin='round'/%3E%3Cpath d='M1.06 290.12H3.7m-2.64 1.33H3.7m-2.64 1.32H3.7m-2.64 1.3H3.7m-2.64 1.33H3.7' fill='none' stroke='%23000' stroke-width='.4'/%3E%3Cpath d='M4.37 288.8v7.94m0-4.11h3.96' fill='none' stroke='%23000' stroke-width='.3'/%3E%3Ctext font-weight='700' font-size='3.17' font-family='sans-serif'%3E%3Ctspan x='5.11' y='291.96'%3EF%3C/tspan%3E%3Ctspan x='5.03' y='295.68'%3EB%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A");
|
|
}
|
|
|
|
button#bom-btn {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)' fill='none' stroke='%23000' stroke-width='.4'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' stroke-linejoin='round'/%3E%3Cpath d='M1.59 290.12h5.29M1.59 291.45h5.33M1.59 292.75h5.33M1.59 294.09h5.33M1.59 295.41h5.33'/%3E%3C/g%3E%3C/svg%3E");
|
|
}
|
|
|
|
button#bom-grouped-btn {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg stroke='%23000' stroke-linejoin='round' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-linecap='square' stroke-width='2' d='M6 10h4m4 0h5m4 0h3M6.1 22h3m3.9 0h5m4 0h4m-16-8h4m4 0h4'/%3E%3Cpath stroke-linecap='null' d='M5 17.5h22M5 26.6h22M5 5.5h22'/%3E%3C/g%3E%3C/svg%3E");
|
|
}
|
|
|
|
button#bom-ungrouped-btn {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg stroke='%23000' stroke-linejoin='round' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-linecap='square' stroke-width='2' d='M6 10h4m-4 8h3m-3 8h4'/%3E%3Cpath stroke-linecap='null' d='M5 13.5h22m-22 8h22M5 5.5h22'/%3E%3C/g%3E%3C/svg%3E");
|
|
}
|
|
|
|
button#bom-netlist-btn {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg fill='none' stroke='%23000' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-width='2' d='M6 26l6-6v-8m13.8-6.3l-6 6v8'/%3E%3Ccircle cx='11.8' cy='9.5' r='2.8' stroke-width='2'/%3E%3Ccircle cx='19.8' cy='22.8' r='2.8' stroke-width='2'/%3E%3C/g%3E%3C/svg%3E");
|
|
}
|
|
|
|
button#copy {
|
|
background-image: url("data:image/svg+xml,%3Csvg height='48' viewBox='0 0 48 48' width='48' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h48v48h-48z' fill='none'/%3E%3Cpath d='M32 2h-24c-2.21 0-4 1.79-4 4v28h4v-28h24v-4zm6 8h-22c-2.21 0-4 1.79-4 4v28c0 2.21 1.79 4 4 4h22c2.21 0 4-1.79 4-4v-28c0-2.21-1.79-4-4-4zm0 32h-22v-28h22v28z'/%3E%3C/svg%3E");
|
|
background-position: 6px 6px;
|
|
background-repeat: no-repeat;
|
|
background-size: 26px 26px;
|
|
border-radius: 6px;
|
|
height: 40px;
|
|
width: 40px;
|
|
margin: 10px 5px;
|
|
}
|
|
|
|
button#copy:active {
|
|
box-shadow: inset 0px 0px 5px #6c6c6c;
|
|
}
|
|
|
|
textarea.clipboard-temp {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 2em;
|
|
height: 2em;
|
|
padding: 0;
|
|
border: None;
|
|
outline: None;
|
|
box-shadow: None;
|
|
background: transparent;
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
.button-container {
|
|
font-size: 0;
|
|
margin: 10px 10px 10px 0px;
|
|
}
|
|
|
|
.dark .button-container {
|
|
filter: invert(1);
|
|
}
|
|
|
|
.button-container button {
|
|
background-size: 32px 32px;
|
|
background-position: 5px 5px;
|
|
background-repeat: no-repeat;
|
|
}
|
|
|
|
@media print {
|
|
.hideonprint {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
canvas {
|
|
cursor: crosshair;
|
|
}
|
|
|
|
canvas:active {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
.fileinfo {
|
|
width: 100%;
|
|
max-width: 1000px;
|
|
border: none;
|
|
padding: 5px;
|
|
}
|
|
|
|
.fileinfo .title {
|
|
font-size: 20pt;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.fileinfo td {
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
max-width: 1px;
|
|
width: 50%;
|
|
text-overflow: ellipsis;
|
|
}
|
|
|
|
.bom {
|
|
border-collapse: collapse;
|
|
font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
|
|
font-size: 10pt;
|
|
table-layout: fixed;
|
|
width: 100%;
|
|
margin-top: 1px;
|
|
position: relative;
|
|
}
|
|
|
|
.bom th,
|
|
.bom td {
|
|
border: 1px solid black;
|
|
padding: 5px;
|
|
word-wrap: break-word;
|
|
text-align: center;
|
|
position: relative;
|
|
}
|
|
|
|
.dark .bom th,
|
|
.dark .bom td {
|
|
border: 1px solid #777;
|
|
}
|
|
|
|
.bom th {
|
|
background-color: #CCCCCC;
|
|
background-clip: padding-box;
|
|
}
|
|
|
|
.dark .bom th {
|
|
background-color: #3b4749;
|
|
}
|
|
|
|
.bom tr.highlighted:nth-child(n) {
|
|
background-color: #cfc;
|
|
}
|
|
|
|
.dark .bom tr.highlighted:nth-child(n) {
|
|
background-color: #226022;
|
|
}
|
|
|
|
.bom tr:nth-child(even) {
|
|
background-color: #f2f2f2;
|
|
}
|
|
|
|
.dark .bom tr:nth-child(even) {
|
|
background-color: #313b40;
|
|
}
|
|
|
|
.bom tr.checked {
|
|
color: #1cb53d;
|
|
}
|
|
|
|
.dark .bom tr.checked {
|
|
color: #2cce54;
|
|
}
|
|
|
|
.bom tr {
|
|
transition: background-color 0.2s;
|
|
}
|
|
|
|
.bom .numCol {
|
|
width: 30px;
|
|
}
|
|
|
|
.bom .value {
|
|
width: 15%;
|
|
}
|
|
|
|
.bom .quantity {
|
|
width: 65px;
|
|
}
|
|
|
|
.bom th .sortmark {
|
|
position: absolute;
|
|
right: 1px;
|
|
top: 1px;
|
|
margin-top: -5px;
|
|
border-width: 5px;
|
|
border-style: solid;
|
|
border-color: transparent transparent #221 transparent;
|
|
transform-origin: 50% 85%;
|
|
transition: opacity 0.2s, transform 0.4s;
|
|
}
|
|
|
|
.dark .bom th .sortmark {
|
|
filter: invert(1);
|
|
}
|
|
|
|
.bom th .sortmark.none {
|
|
opacity: 0;
|
|
}
|
|
|
|
.bom th .sortmark.desc {
|
|
transform: rotate(180deg);
|
|
}
|
|
|
|
.bom th:hover .sortmark.none {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.bom .bom-checkbox {
|
|
width: 30px;
|
|
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 .bom-checkbox:hover:before,
|
|
.bom .bom-checkbox:hover:after {
|
|
visibility: visible;
|
|
transition: visibility 0.2s linear 1s;
|
|
}
|
|
|
|
.split {
|
|
-webkit-box-sizing: border-box;
|
|
-moz-box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
overflow-y: auto;
|
|
overflow-x: hidden;
|
|
background-color: inherit;
|
|
}
|
|
|
|
.split.split-horizontal,
|
|
.gutter.gutter-horizontal {
|
|
height: 100%;
|
|
float: left;
|
|
}
|
|
|
|
.gutter {
|
|
background-color: #ddd;
|
|
background-repeat: no-repeat;
|
|
background-position: 50%;
|
|
transition: background-color 0.3s;
|
|
}
|
|
|
|
.dark .gutter {
|
|
background-color: #777;
|
|
}
|
|
|
|
.gutter.gutter-horizontal {
|
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
|
|
cursor: ew-resize;
|
|
width: 5px;
|
|
}
|
|
|
|
.gutter.gutter-vertical {
|
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=');
|
|
cursor: ns-resize;
|
|
height: 5px;
|
|
}
|
|
|
|
.searchbox {
|
|
float: left;
|
|
height: 40px;
|
|
margin: 10px 5px;
|
|
padding: 12px 32px;
|
|
font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
|
|
font-size: 18px;
|
|
box-sizing: border-box;
|
|
border: 1px solid #888;
|
|
border-radius: 6px;
|
|
outline: none;
|
|
background-color: #eee;
|
|
transition: background-color 0.2s, border 0.2s;
|
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABNklEQVQ4T8XSMUvDQBQH8P/LElFa/AIZHcTBQSz0I/gFstTBRR2KUC4ldDxw7h0Bl3RRUATxi4iiODgoiLNrbQYp5J6cpJJqomkX33Z37/14d/dIa33MzDuYI4johOI4XhyNRteO46zNYjDzAxE1yBZprVeZ+QbAUhXEGJMA2Ox2u4+fQIa0mPmsCgCgJYQ4t7lfgF0opQYAdv9ABkKI/UnOFCClXKjX61cA1osQY8x9kiRNKeV7IWA3oyhaSdP0FkAtjxhj3hzH2RBCPOf3pzqYHCilfAAX+URm9oMguPzeWSGQvUcMYC8rOBJCHBRdqxTo9/vbRHRqi8bj8XKv1xvODbiuW2u32/bvf0SlDv4XYOY7z/Mavu+nM1+BmQ+NMc0wDF/LprP0DbTWW0T00ul0nn4b7Q87+X4Qmfiq2wAAAABJRU5ErkJggg==');
|
|
background-position: 10px 10px;
|
|
background-repeat: no-repeat;
|
|
}
|
|
|
|
.dark .searchbox {
|
|
background-color: #111;
|
|
color: #eee;
|
|
}
|
|
|
|
.searchbox::placeholder {
|
|
color: #ccc;
|
|
}
|
|
|
|
.dark .searchbox::placeholder {
|
|
color: #666;
|
|
}
|
|
|
|
.filter {
|
|
width: calc(60% - 64px);
|
|
}
|
|
|
|
.reflookup {
|
|
width: calc(40% - 10px);
|
|
}
|
|
|
|
input[type=text]:focus {
|
|
background-color: white;
|
|
border: 1px solid #333;
|
|
}
|
|
|
|
.dark input[type=text]:focus {
|
|
background-color: #333;
|
|
border: 1px solid #ccc;
|
|
}
|
|
|
|
mark.highlight {
|
|
background-color: #5050ff;
|
|
color: #fff;
|
|
padding: 2px;
|
|
border-radius: 6px;
|
|
}
|
|
|
|
.dark mark.highlight {
|
|
background-color: #76a6da;
|
|
color: #111;
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
.statsbtn {
|
|
background-color: white;
|
|
border: none;
|
|
background-image: url("data:image/svg+xml,%3Csvg width='36' height='36' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 6h28v24H4V6zm0 8h28v8H4m9-16v24h10V5.8' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E");
|
|
background-position: center;
|
|
background-repeat: no-repeat;
|
|
}
|
|
|
|
.iobtn {
|
|
background-color: white;
|
|
border: none;
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' d='M3 33v-7l6.8-7h16.5l6.7 7v7H3zM3.2 26H33M21 9l5-5.9 5 6h-2.5V15h-5V9H21zm-4.9 0l-5 6-5-6h2.5V3h5v6h2.5z'/%3E%3Cpath fill='none' stroke='%23000' d='M6.1 29.5H10'/%3E%3C/svg%3E");
|
|
background-position: center;
|
|
background-repeat: no-repeat;
|
|
}
|
|
|
|
.visbtn {
|
|
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath fill='none' stroke='%23333' d='M2.5 4.5h5v15h-5zM9.5 4.5h5v15h-5zM16.5 4.5h5v15h-5z'/%3E%3C/svg%3E");
|
|
background-position: center;
|
|
background-repeat: no-repeat;
|
|
padding: 15px;
|
|
}
|
|
|
|
#vismenu-content {
|
|
left: 0px;
|
|
font-family: Verdana, sans-serif;
|
|
}
|
|
|
|
.dark .statsbtn,
|
|
.dark .savebtn,
|
|
.dark .menubtn,
|
|
.dark .iobtn,
|
|
.dark .visbtn {
|
|
filter: invert(1);
|
|
}
|
|
|
|
.flexbox {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
width: 100%;
|
|
}
|
|
|
|
.savebtn {
|
|
background-color: #d6d6d6;
|
|
width: auto;
|
|
height: 30px;
|
|
flex-grow: 1;
|
|
margin: 5px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.savebtn:active {
|
|
background-color: #0a0;
|
|
color: white;
|
|
}
|
|
|
|
.dark .savebtn:active {
|
|
/* This will be inverted */
|
|
background-color: #b3b;
|
|
}
|
|
|
|
.stats {
|
|
border-collapse: collapse;
|
|
font-size: 12pt;
|
|
table-layout: fixed;
|
|
width: 100%;
|
|
min-width: 450px;
|
|
}
|
|
|
|
.dark .stats td {
|
|
border: 1px solid #bbb;
|
|
}
|
|
|
|
.stats td {
|
|
border: 1px solid black;
|
|
padding: 5px;
|
|
word-wrap: break-word;
|
|
text-align: center;
|
|
position: relative;
|
|
}
|
|
|
|
#checkbox-stats div {
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
height: 100%;
|
|
width: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
#checkbox-stats .bar {
|
|
background-color: rgba(28, 251, 0, 0.6);
|
|
}
|
|
|
|
.menu {
|
|
position: relative;
|
|
display: inline-block;
|
|
margin: 10px 10px 10px 0px;
|
|
}
|
|
|
|
.menu-content {
|
|
font-size: 12pt !important;
|
|
text-align: left !important;
|
|
font-weight: normal !important;
|
|
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;
|
|
}
|
|
|
|
.dark .menu-content {
|
|
background-color: #111;
|
|
}
|
|
|
|
.menu:hover .menu-content {
|
|
display: block;
|
|
}
|
|
|
|
.menu:hover .menubtn,
|
|
.menu:hover .iobtn,
|
|
.menu:hover .statsbtn {
|
|
background-color: #eee;
|
|
}
|
|
|
|
.menu-label {
|
|
display: inline-block;
|
|
padding: 8px;
|
|
border: 1px solid #ccc;
|
|
border-top: 0;
|
|
width: calc(100% - 18px);
|
|
}
|
|
|
|
.menu-label-top {
|
|
border-top: 1px solid #ccc;
|
|
}
|
|
|
|
.menu-textbox {
|
|
float: left;
|
|
height: 24px;
|
|
margin: 10px 5px;
|
|
padding: 5px 5px;
|
|
font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
|
|
font-size: 14px;
|
|
box-sizing: border-box;
|
|
border: 1px solid #888;
|
|
border-radius: 4px;
|
|
outline: none;
|
|
background-color: #eee;
|
|
transition: background-color 0.2s, border 0.2s;
|
|
width: calc(100% - 10px);
|
|
}
|
|
|
|
.menu-textbox.invalid,
|
|
.dark .menu-textbox.invalid {
|
|
color: red;
|
|
}
|
|
|
|
.dark .menu-textbox {
|
|
background-color: #222;
|
|
color: #eee;
|
|
}
|
|
|
|
.radio-container {
|
|
margin: 4px;
|
|
}
|
|
|
|
.topmostdiv {
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: white;
|
|
transition: background-color 0.3s;
|
|
}
|
|
|
|
#top {
|
|
height: 78px;
|
|
border-bottom: 2px solid black;
|
|
}
|
|
|
|
.dark #top {
|
|
border-bottom: 2px solid #ccc;
|
|
}
|
|
|
|
#dbg {
|
|
display: block;
|
|
}
|
|
|
|
::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
|
|
::-webkit-scrollbar-track {
|
|
background: #aaa;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb {
|
|
background: #666;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
::-webkit-scrollbar-thumb:hover {
|
|
background: #555;
|
|
}
|
|
|
|
.slider {
|
|
-webkit-appearance: none;
|
|
width: 100%;
|
|
margin: 3px 0;
|
|
padding: 0;
|
|
outline: none;
|
|
opacity: 0.7;
|
|
-webkit-transition: .2s;
|
|
transition: opacity .2s;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.slider:hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
.slider:focus {
|
|
outline: none;
|
|
}
|
|
|
|
.slider::-webkit-slider-runnable-track {
|
|
-webkit-appearance: none;
|
|
width: 100%;
|
|
height: 8px;
|
|
background: #d3d3d3;
|
|
border-radius: 3px;
|
|
border: none;
|
|
}
|
|
|
|
.slider::-webkit-slider-thumb {
|
|
-webkit-appearance: none;
|
|
width: 15px;
|
|
height: 15px;
|
|
border-radius: 50%;
|
|
background: #0a0;
|
|
cursor: pointer;
|
|
margin-top: -4px;
|
|
}
|
|
|
|
.dark .slider::-webkit-slider-thumb {
|
|
background: #3d3;
|
|
}
|
|
|
|
.slider::-moz-range-thumb {
|
|
width: 15px;
|
|
height: 15px;
|
|
border-radius: 50%;
|
|
background: #0a0;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.slider::-moz-range-track {
|
|
height: 8px;
|
|
background: #d3d3d3;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.dark .slider::-moz-range-thumb {
|
|
background: #3d3;
|
|
}
|
|
|
|
.slider::-ms-track {
|
|
width: 100%;
|
|
height: 8px;
|
|
border-width: 3px 0;
|
|
background: transparent;
|
|
border-color: transparent;
|
|
color: transparent;
|
|
transition: opacity .2s;
|
|
}
|
|
|
|
.slider::-ms-fill-lower {
|
|
background: #d3d3d3;
|
|
border: none;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.slider::-ms-fill-upper {
|
|
background: #d3d3d3;
|
|
border: none;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.slider::-ms-thumb {
|
|
width: 15px;
|
|
height: 15px;
|
|
border-radius: 50%;
|
|
background: #0a0;
|
|
cursor: pointer;
|
|
margin: 0;
|
|
}
|
|
|
|
.shameless-plug {
|
|
font-size: 0.8em;
|
|
text-align: center;
|
|
display: block;
|
|
}
|
|
|
|
a {
|
|
color: #0278a4;
|
|
}
|
|
|
|
.dark a {
|
|
color: #00b9fd;
|
|
}
|
|
|
|
#frontcanvas,
|
|
#backcanvas {
|
|
touch-action: none;
|
|
}
|
|
|
|
.placeholder {
|
|
border: 1px dashed #9f9fda !important;
|
|
background-color: #edf2f7 !important;
|
|
}
|
|
|
|
.dragging {
|
|
z-index: 999;
|
|
}
|
|
|
|
.dark .dragging>table>tbody>tr {
|
|
background-color: #252c30;
|
|
}
|
|
|
|
.dark .placeholder {
|
|
filter: invert(1);
|
|
}
|
|
|
|
.column-spacer {
|
|
top: 0;
|
|
left: 0;
|
|
width: calc(100% - 4px);
|
|
position: absolute;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
height: 100%;
|
|
}
|
|
|
|
.column-width-handle {
|
|
top: 0;
|
|
right: 0;
|
|
width: 4px;
|
|
position: absolute;
|
|
cursor: col-resize;
|
|
user-select: none;
|
|
height: 100%;
|
|
}
|
|
|
|
.column-width-handle:hover {
|
|
background-color: #4f99bd;
|
|
}
|
|
|
|
|
|
</style>
|
|
<script type="text/javascript" >
|
|
///////////////////////////////////////////////
|
|
/*
|
|
Split.js - v1.3.5
|
|
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.Split=t()}(this,function(){"use strict";var e=window,t=e.document,n="addEventListener",i="removeEventListener",r="getBoundingClientRect",s=function(){return!1},o=e.attachEvent&&!e[n],a=["","-webkit-","-moz-","-o-"].filter(function(e){var n=t.createElement("div");return n.style.cssText="width:"+e+"calc(9px)",!!n.style.length}).shift()+"calc",l=function(e){return"string"==typeof e||e instanceof String?t.querySelector(e):e};return function(u,c){function z(e,t,n){var i=A(y,t,n);Object.keys(i).forEach(function(t){return e.style[t]=i[t]})}function h(e,t){var n=B(y,t);Object.keys(n).forEach(function(t){return e.style[t]=n[t]})}function f(e){var t=E[this.a],n=E[this.b],i=t.size+n.size;t.size=e/this.size*i,n.size=i-e/this.size*i,z(t.element,t.size,this.aGutterSize),z(n.element,n.size,this.bGutterSize)}function m(e){var t;this.dragging&&((t="touches"in e?e.touches[0][b]-this.start:e[b]-this.start)<=E[this.a].minSize+M+this.aGutterSize?t=E[this.a].minSize+this.aGutterSize:t>=this.size-(E[this.b].minSize+M+this.bGutterSize)&&(t=this.size-(E[this.b].minSize+this.bGutterSize)),f.call(this,t),c.onDrag&&c.onDrag())}function g(){var e=E[this.a].element,t=E[this.b].element;this.size=e[r]()[y]+t[r]()[y]+this.aGutterSize+this.bGutterSize,this.start=e[r]()[G]}function d(){var t=this,n=E[t.a].element,r=E[t.b].element;t.dragging&&c.onDragEnd&&c.onDragEnd(),t.dragging=!1,e[i]("mouseup",t.stop),e[i]("touchend",t.stop),e[i]("touchcancel",t.stop),t.parent[i]("mousemove",t.move),t.parent[i]("touchmove",t.move),delete t.stop,delete t.move,n[i]("selectstart",s),n[i]("dragstart",s),r[i]("selectstart",s),r[i]("dragstart",s),n.style.userSelect="",n.style.webkitUserSelect="",n.style.MozUserSelect="",n.style.pointerEvents="",r.style.userSelect="",r.style.webkitUserSelect="",r.style.MozUserSelect="",r.style.pointerEvents="",t.gutter.style.cursor="",t.parent.style.cursor=""}function S(t){var i=this,r=E[i.a].element,o=E[i.b].element;!i.dragging&&c.onDragStart&&c.onDragStart(),t.preventDefault(),i.dragging=!0,i.move=m.bind(i),i.stop=d.bind(i),e[n]("mouseup",i.stop),e[n]("touchend",i.stop),e[n]("touchcancel",i.stop),i.parent[n]("mousemove",i.move),i.parent[n]("touchmove",i.move),r[n]("selectstart",s),r[n]("dragstart",s),o[n]("selectstart",s),o[n]("dragstart",s),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",i.gutter.style.cursor=j,i.parent.style.cursor=j,g.call(i)}function v(e){e.forEach(function(t,n){if(n>0){var i=F[n-1],r=E[i.a],s=E[i.b];r.size=e[n-1],s.size=t,z(r.element,r.size,i.aGutterSize),z(s.element,s.size,i.bGutterSize)}})}function p(){F.forEach(function(e){e.parent.removeChild(e.gutter),E[e.a].element.style[y]="",E[e.b].element.style[y]=""})}void 0===c&&(c={});var y,b,G,E,w=l(u[0]).parentNode,D=e.getComputedStyle(w).flexDirection,U=c.sizes||u.map(function(){return 100/u.length}),k=void 0!==c.minSize?c.minSize:100,x=Array.isArray(k)?k:u.map(function(){return k}),L=void 0!==c.gutterSize?c.gutterSize:10,M=void 0!==c.snapOffset?c.snapOffset:30,O=c.direction||"horizontal",j=c.cursor||("horizontal"===O?"ew-resize":"ns-resize"),C=c.gutter||function(e,n){var i=t.createElement("div");return i.className="gutter gutter-"+n,i},A=c.elementStyle||function(e,t,n){var i={};return"string"==typeof t||t instanceof String?i[e]=t:i[e]=o?t+"%":a+"("+t+"% - "+n+"px)",i},B=c.gutterStyle||function(e,t){return n={},n[e]=t+"px",n;var n};"horizontal"===O?(y="width","clientWidth",b="clientX",G="left","paddingLeft"):"vertical"===O&&(y="height","clientHeight",b="clientY",G="top","paddingTop");var F=[];return E=u.map(function(e,t){var i,s={element:l(e),size:U[t],minSize:x[t]};if(t>0&&(i={a:t-1,b:t,dragging:!1,isFirst:1===t,isLast:t===u.length-1,direction:O,parent:w},i.aGutterSize=L,i.bGutterSize=L,i.isFirst&&(i.aGutterSize=L/2),i.isLast&&(i.bGutterSize=L/2),"row-reverse"===D||"column-reverse"===D)){var a=i.a;i.a=i.b,i.b=a}if(!o&&t>0){var c=C(t,O);h(c,L),c[n]("mousedown",S.bind(i)),c[n]("touchstart",S.bind(i)),w.insertBefore(c,s.element),i.gutter=c}0===t||t===u.length-1?z(s.element,s.size,L/2):z(s.element,s.size,L);var f=s.element[r]()[y];return f<s.minSize&&(s.minSize=f),t>0&&F.push(i),s}),o?{setSizes:v,destroy:p}:{setSizes:v,getSizes:function(){return E.map(function(e){return e.size})},collapse:function(e){if(e===F.length){var t=F[e-1];g.call(t),o||f.call(t,t.size-t.bGutterSize)}else{var n=F[e];g.call(n),o||f.call(n,n.aGutterSize)}},destroy:p}}});
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
// 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(){var o=String.fromCharCode,i={};var n={decompressFromBase64:function(o){return null==o?"":""==o?null:n._decompress(o.length,32,function(n){return function(o,n){if(!i[o]){i[o]={};for(var t=0;t<o.length;t++)i[o][o.charAt(t)]=t}return i[o][n]}("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",o.charAt(n))})},_decompress:function(i,n,t){var r,e,a,s,p,u,l,f=[],c=4,d=4,h=3,v="",g=[],m={val:t(0),position:n,index:1};for(r=0;r<3;r+=1)f[r]=r;for(a=0,p=Math.pow(2,2),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 2:return""}for(f[3]=l,e=l,g.push(l);;){if(m.index>i)return"";for(a=0,p=Math.pow(2,h),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(l=a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 2:return g.join("")}if(0==c&&(c=Math.pow(2,h),h++),f[l])v=f[l];else{if(l!==d)return null;v=e+e.charAt(0)}g.push(v),f[d++]=e+v.charAt(0),e=v,0==--c&&(c=Math.pow(2,h),h++)}}};return n}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module?module.exports=LZString:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return LZString});
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/*!
|
|
* PEP v0.4.3 | https://github.com/jquery/PEP
|
|
* Copyright jQuery Foundation and other contributors | http://jquery.org/license
|
|
*/
|
|
!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.PointerEventsPolyfill=b()}(this,function(){"use strict";function a(a,b){b=b||Object.create(null);var c=document.createEvent("Event");c.initEvent(a,b.bubbles||!1,b.cancelable||!1);
|
|
for(var d,e=2;e<m.length;e++)d=m[e],c[d]=b[d]||n[e];c.buttons=b.buttons||0;
|
|
var f=0;return f=b.pressure&&c.buttons?b.pressure:c.buttons?.5:0,c.x=c.clientX,c.y=c.clientY,c.pointerId=b.pointerId||0,c.width=b.width||0,c.height=b.height||0,c.pressure=f,c.tiltX=b.tiltX||0,c.tiltY=b.tiltY||0,c.twist=b.twist||0,c.tangentialPressure=b.tangentialPressure||0,c.pointerType=b.pointerType||"",c.hwTimestamp=b.hwTimestamp||0,c.isPrimary=b.isPrimary||!1,c}function b(){this.array=[],this.size=0}function c(a,b,c,d){this.addCallback=a.bind(d),this.removeCallback=b.bind(d),this.changedCallback=c.bind(d),A&&(this.observer=new A(this.mutationWatcher.bind(this)))}function d(a){return"body /shadow-deep/ "+e(a)}function e(a){return'[touch-action="'+a+'"]'}function f(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+"; }"}function g(){if(F){D.forEach(function(a){String(a)===a?(E+=e(a)+f(a)+"\n",G&&(E+=d(a)+f(a)+"\n")):(E+=a.selectors.map(e)+f(a.rule)+"\n",G&&(E+=a.selectors.map(d)+f(a.rule)+"\n"))});var a=document.createElement("style");a.textContent=E,document.head.appendChild(a)}}function h(){if(!window.PointerEvent){if(window.PointerEvent=a,window.navigator.msPointerEnabled){var b=window.navigator.msMaxTouchPoints;Object.defineProperty(window.navigator,"maxTouchPoints",{value:b,enumerable:!0}),u.registerSource("ms",_)}else Object.defineProperty(window.navigator,"maxTouchPoints",{value:0,enumerable:!0}),u.registerSource("mouse",N),void 0!==window.ontouchstart&&u.registerSource("touch",V);u.register(document)}}function i(a){if(!u.pointermap.has(a)){var b=new Error("InvalidPointerId");throw b.name="InvalidPointerId",b}}function j(a){for(var b=a.parentNode;b&&b!==a.ownerDocument;)b=b.parentNode;if(!b){var c=new Error("InvalidStateError");throw c.name="InvalidStateError",c}}function k(a){var b=u.pointermap.get(a);return 0!==b.buttons}function l(){window.Element&&!Element.prototype.setPointerCapture&&Object.defineProperties(Element.prototype,{setPointerCapture:{value:W},releasePointerCapture:{value:X},hasPointerCapture:{value:Y}})}
|
|
var m=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","pageX","pageY"],n=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0],o=window.Map&&window.Map.prototype.forEach,p=o?Map:b;b.prototype={set:function(a,b){return void 0===b?this["delete"](a):(this.has(a)||this.size++,void(this.array[a]=b))},has:function(a){return void 0!==this.array[a]},"delete":function(a){this.has(a)&&(delete this.array[a],this.size--)},get:function(a){return this.array[a]},clear:function(){this.array.length=0,this.size=0},forEach:function(a,b){return this.array.forEach(function(c,d){a.call(b,c,d,this)},this)}};var q=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which","pageX","pageY","timeStamp"],r=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0],s={pointerover:1,pointerout:1,pointerenter:1,pointerleave:1},t="undefined"!=typeof SVGElementInstance,u={pointermap:new p,eventMap:Object.create(null),captureInfo:Object.create(null),eventSources:Object.create(null),eventSourceList:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},register:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++)
|
|
b.register.call(b,a)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++)
|
|
b.unregister.call(b,a)},contains:function(a,b){try{return a.contains(b)}catch(c){return!1}},down:function(a){a.bubbles=!0,this.fireEvent("pointerdown",a)},move:function(a){a.bubbles=!0,this.fireEvent("pointermove",a)},up:function(a){a.bubbles=!0,this.fireEvent("pointerup",a)},enter:function(a){a.bubbles=!1,this.fireEvent("pointerenter",a)},leave:function(a){a.bubbles=!1,this.fireEvent("pointerleave",a)},over:function(a){a.bubbles=!0,this.fireEvent("pointerover",a)},out:function(a){a.bubbles=!0,this.fireEvent("pointerout",a)},cancel:function(a){a.bubbles=!0,this.fireEvent("pointercancel",a)},leaveOut:function(a){this.out(a),this.propagate(a,this.leave,!1)},enterOver:function(a){this.over(a),this.propagate(a,this.enter,!0)},eventHandler:function(a){if(!a._handledByPE){var b=a.type,c=this.eventMap&&this.eventMap[b];c&&c(a),a._handledByPE=!0}},listen:function(a,b){b.forEach(function(b){this.addEvent(a,b)},this)},unlisten:function(a,b){b.forEach(function(b){this.removeEvent(a,b)},this)},addEvent:function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(b,c){this.captureInfo[c.pointerId]&&(c.relatedTarget=null);var d=new a(b,c);return c.preventDefault&&(d.preventDefault=c.preventDefault),d._target=d._target||c.target,d},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var b,c=Object.create(null),d=0;d<q.length;d++)b=q[d],c[b]=a[b]||r[d],!t||"target"!==b&&"relatedTarget"!==b||c[b]instanceof SVGElementInstance&&(c[b]=c[b].correspondingUseElement);return a.preventDefault&&(c.preventDefault=function(){a.preventDefault()}),c},getTarget:function(a){var b=this.captureInfo[a.pointerId];return b?a._target!==b&&a.type in s?void 0:b:a._target},propagate:function(a,b,c){for(var d=a.target,e=[];d!==document&&!d.contains(a.relatedTarget);) if(e.push(d),d=d.parentNode,!d)return;c&&e.reverse(),e.forEach(function(c){a.target=c,b.call(this,a)},this)},setCapture:function(b,c,d){this.captureInfo[b]&&this.releaseCapture(b,d),this.captureInfo[b]=c,this.implicitRelease=this.releaseCapture.bind(this,b,d),document.addEventListener("pointerup",this.implicitRelease),document.addEventListener("pointercancel",this.implicitRelease);var e=new a("gotpointercapture");e.pointerId=b,e._target=c,d||this.asyncDispatchEvent(e)},releaseCapture:function(b,c){var d=this.captureInfo[b];if(d){this.captureInfo[b]=void 0,document.removeEventListener("pointerup",this.implicitRelease),document.removeEventListener("pointercancel",this.implicitRelease);var e=new a("lostpointercapture");e.pointerId=b,e._target=d,c||this.asyncDispatchEvent(e)}},dispatchEvent:/*scope.external.dispatchEvent || */function(a){var b=this.getTarget(a);if(b)return b.dispatchEvent(a)},asyncDispatchEvent:function(a){requestAnimationFrame(this.dispatchEvent.bind(this,a))}};u.boundHandler=u.eventHandler.bind(u);var v={shadow:function(a){if(a)return a.shadowRoot||a.webkitShadowRoot},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);if(this.canTarget(b))return b},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){if(a){var d,e,f=a.elementFromPoint(b,c);for(e=this.targetingShadow(f);e;){if(d=e.elementFromPoint(b,c)){var g=this.targetingShadow(d);return this.searchRoot(g,b,c)||d} e=this.olderShadow(e)} return f}},owner:function(a){
|
|
for(var b=a;b.parentNode;)b=b.parentNode;
|
|
return b.nodeType!==Node.DOCUMENT_NODE&&b.nodeType!==Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){var b=a.clientX,c=a.clientY,d=this.owner(a.target);
|
|
return d.elementFromPoint(b,c)||(d=document),this.searchRoot(d,b,c)}},w=Array.prototype.forEach.call.bind(Array.prototype.forEach),x=Array.prototype.map.call.bind(Array.prototype.map),y=Array.prototype.slice.call.bind(Array.prototype.slice),z=Array.prototype.filter.call.bind(Array.prototype.filter),A=window.MutationObserver||window.WebKitMutationObserver,B="[touch-action]",C={subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0,attributeFilter:["touch-action"]};c.prototype={watchSubtree:function(a){
|
|
//
|
|
this.observer&&v.canTarget(a)&&this.observer.observe(a,C)},enableOnSubtree:function(a){this.watchSubtree(a),a===document&&"complete"!==document.readyState?this.installOnLoad():this.installNewSubtree(a)},installNewSubtree:function(a){w(this.findElements(a),this.addElement,this)},findElements:function(a){return a.querySelectorAll?a.querySelectorAll(B):[]},removeElement:function(a){this.removeCallback(a)},addElement:function(a){this.addCallback(a)},elementChanged:function(a,b){this.changedCallback(a,b)},concatLists:function(a,b){return a.concat(y(b))},
|
|
installOnLoad:function(){document.addEventListener("readystatechange",function(){"complete"===document.readyState&&this.installNewSubtree(document)}.bind(this))},isElement:function(a){return a.nodeType===Node.ELEMENT_NODE},flattenMutationTree:function(a){
|
|
var b=x(a,this.findElements,this);
|
|
return b.push(z(a,this.isElement)),b.reduce(this.concatLists,[])},mutationWatcher:function(a){a.forEach(this.mutationHandler,this)},mutationHandler:function(a){if("childList"===a.type){var b=this.flattenMutationTree(a.addedNodes);b.forEach(this.addElement,this);var c=this.flattenMutationTree(a.removedNodes);c.forEach(this.removeElement,this)}else"attributes"===a.type&&this.elementChanged(a.target,a.oldValue)}};var D=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]}],E="",F=window.PointerEvent||window.MSPointerEvent,G=!window.ShadowDOMPolyfill&&document.head.createShadowRoot,H=u.pointermap,I=25,J=[1,4,2,8,16],K=!1;try{K=1===new MouseEvent("test",{buttons:1}).buttons}catch(L){}
|
|
var M,N={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup","mouseover","mouseout"],register:function(a){u.listen(a,this.events)},unregister:function(a){u.unlisten(a,this.events)},lastTouches:[],
|
|
isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,d=a.clientX,e=a.clientY,f=0,g=c.length;f<g&&(b=c[f]);f++){
|
|
var h=Math.abs(d-b.x),i=Math.abs(e-b.y);if(h<=I&&i<=I)return!0}},prepareEvent:function(a){var b=u.cloneEvent(a),c=b.preventDefault;return b.preventDefault=function(){a.preventDefault(),c()},b.pointerId=this.POINTER_ID,b.isPrimary=!0,b.pointerType=this.POINTER_TYPE,b},prepareButtonsForMove:function(a,b){var c=H.get(this.POINTER_ID);
|
|
0!==b.which&&c?a.buttons=c.buttons:a.buttons=0,b.buttons=a.buttons},mousedown:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=H.get(this.POINTER_ID),c=this.prepareEvent(a);K||(c.buttons=J[c.button],b&&(c.buttons|=b.buttons),a.buttons=c.buttons),H.set(this.POINTER_ID,a),b&&0!==b.buttons?u.move(c):u.down(c)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,H.set(this.POINTER_ID,a),u.move(b)}},mouseup:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=H.get(this.POINTER_ID),c=this.prepareEvent(a);if(!K){var d=J[c.button];
|
|
c.buttons=b?b.buttons&~d:0,a.buttons=c.buttons}H.set(this.POINTER_ID,a),
|
|
c.buttons&=~J[c.button],0===c.buttons?u.up(c):u.move(c)}},mouseover:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,H.set(this.POINTER_ID,a),u.enterOver(b)}},mouseout:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,u.leaveOut(b)}},cancel:function(a){var b=this.prepareEvent(a);u.cancel(b),this.deactivateMouse()},deactivateMouse:function(){H["delete"](this.POINTER_ID)}},O=u.captureInfo,P=v.findTarget.bind(v),Q=v.allShadows.bind(v),R=u.pointermap,S=2500,T=200,U="touch-action",V={events:["touchstart","touchmove","touchend","touchcancel"],register:function(a){M.enableOnSubtree(a)},unregister:function(){},elementAdded:function(a){var b=a.getAttribute(U),c=this.touchActionToScrollType(b);c&&(a._scrollType=c,u.listen(a,this.events),
|
|
Q(a).forEach(function(a){a._scrollType=c,u.listen(a,this.events)},this))},elementRemoved:function(a){a._scrollType=void 0,u.unlisten(a,this.events),
|
|
Q(a).forEach(function(a){a._scrollType=void 0,u.unlisten(a,this.events)},this)},elementChanged:function(a,b){var c=a.getAttribute(U),d=this.touchActionToScrollType(c),e=this.touchActionToScrollType(b);
|
|
d&&e?(a._scrollType=d,Q(a).forEach(function(a){a._scrollType=d},this)):e?this.elementRemoved(a):d&&this.elementAdded(a)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y",SCROLLER:/^(?:pan-x pan-y)|(?:pan-y pan-x)|auto$/},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return"none"===b?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":c.SCROLLER.exec(b)?"XY":void 0},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){
|
|
(0===R.size||1===R.size&&R.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.scrolling=!1,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,T)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return"touchstart"!==a&&"touchmove"!==a||(b=1),b},touchToPointer:function(a){var b=this.currentTouchEvent,c=u.cloneEvent(a),d=c.pointerId=a.identifier+2;c.target=O[d]||P(c),c.bubbles=!0,c.cancelable=!0,c.detail=this.clickCount,c.button=0,c.buttons=this.typeToButtons(b.type),c.width=2*(a.radiusX||a.webkitRadiusX||0),c.height=2*(a.radiusY||a.webkitRadiusY||0),c.pressure=a.force||a.webkitForce||.5,c.isPrimary=this.isPrimaryTouch(a),c.pointerType=this.POINTER_TYPE,
|
|
c.altKey=b.altKey,c.ctrlKey=b.ctrlKey,c.metaKey=b.metaKey,c.shiftKey=b.shiftKey;
|
|
var e=this;return c.preventDefault=function(){e.scrolling=!1,e.firstXY=null,b.preventDefault()},c},processTouches:function(a,b){var c=a.changedTouches;this.currentTouchEvent=a;for(var d,e=0;e<c.length;e++)d=c[e],b.call(this,this.touchToPointer(d))},
|
|
shouldScroll:function(a){if(this.firstXY){var b,c=a.currentTarget._scrollType;if("none"===c)
|
|
b=!1;else if("XY"===c)
|
|
b=!0;else{var d=a.changedTouches[0],e=c,f="Y"===c?"X":"Y",g=Math.abs(d["client"+e]-this.firstXY[e]),h=Math.abs(d["client"+f]-this.firstXY[f]);
|
|
b=g>=h}return this.firstXY=null,b}},findTouch:function(a,b){for(var c,d=0,e=a.length;d<e&&(c=a[d]);d++)if(c.identifier===b)return!0},
|
|
vacuumTouches:function(a){var b=a.touches;
|
|
if(R.size>=b.length){var c=[];R.forEach(function(a,d){
|
|
if(1!==d&&!this.findTouch(b,d-2)){var e=a.out;c.push(e)}},this),c.forEach(this.cancelOut,this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.overDown))},overDown:function(a){R.set(a.pointerId,{target:a.target,out:a,outTarget:a.target}),u.enterOver(a),u.down(a)},touchmove:function(a){this.scrolling||(this.shouldScroll(a)?(this.scrolling=!0,this.touchcancel(a)):(a.preventDefault(),this.processTouches(a,this.moveOverOut)))},moveOverOut:function(a){var b=a,c=R.get(b.pointerId);
|
|
if(c){var d=c.out,e=c.outTarget;u.move(b),d&&e!==b.target&&(d.relatedTarget=b.target,b.relatedTarget=e,
|
|
d.target=e,b.target?(u.leaveOut(d),u.enterOver(b)):(
|
|
b.target=e,b.relatedTarget=null,this.cancelOut(b))),c.out=b,c.outTarget=b.target}},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.upOut)},upOut:function(a){this.scrolling||(u.up(a),u.leaveOut(a)),this.cleanUpPointer(a)},touchcancel:function(a){this.processTouches(a,this.cancelOut)},cancelOut:function(a){u.cancel(a),u.leaveOut(a),this.cleanUpPointer(a)},cleanUpPointer:function(a){R["delete"](a.pointerId),this.removePrimaryPointer(a)},
|
|
dedupSynthMouse:function(a){var b=N.lastTouches,c=a.changedTouches[0];
|
|
if(this.isPrimaryTouch(c)){
|
|
var d={x:c.clientX,y:c.clientY};b.push(d);var e=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,b,d);setTimeout(e,S)}}};M=new c(V.elementAdded,V.elementRemoved,V.elementChanged,V);var W,X,Y,Z=u.pointermap,$=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,_={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerOut","MSPointerOver","MSPointerCancel","MSGotPointerCapture","MSLostPointerCapture"],register:function(a){u.listen(a,this.events)},unregister:function(a){u.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var b=a;return $&&(b=u.cloneEvent(a),b.pointerType=this.POINTER_TYPES[a.pointerType]),b},cleanup:function(a){Z["delete"](a)},MSPointerDown:function(a){Z.set(a.pointerId,a);var b=this.prepareEvent(a);u.down(b)},MSPointerMove:function(a){var b=this.prepareEvent(a);u.move(b)},MSPointerUp:function(a){var b=this.prepareEvent(a);u.up(b),this.cleanup(a.pointerId)},MSPointerOut:function(a){var b=this.prepareEvent(a);u.leaveOut(b)},MSPointerOver:function(a){var b=this.prepareEvent(a);u.enterOver(b)},MSPointerCancel:function(a){var b=this.prepareEvent(a);u.cancel(b),this.cleanup(a.pointerId)},MSLostPointerCapture:function(a){var b=u.makeEvent("lostpointercapture",a);u.dispatchEvent(b)},MSGotPointerCapture:function(a){var b=u.makeEvent("gotpointercapture",a);u.dispatchEvent(b)}},aa=window.navigator;aa.msPointerEnabled?(W=function(a){i(a),j(this),k(a)&&(u.setCapture(a,this,!0),this.msSetPointerCapture(a))},X=function(a){i(a),u.releaseCapture(a,!0),this.msReleasePointerCapture(a)}):(W=function(a){i(a),j(this),k(a)&&u.setCapture(a,this)},X=function(a){i(a),u.releaseCapture(a)}),Y=function(a){return!!u.captureInfo[a]},g(),h(),l();var ba={dispatcher:u,Installer:c,PointerEvent:a,PointerMap:p,targetFinding:v};return ba});
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
var config = {"dark_mode": false, "show_pads": true, "show_fabrication": false, "show_silkscreen": true, "highlight_pin1": false, "redraw_on_drag": true, "board_rotation": 0, "checkboxes": "Sourced,Placed", "bom_view": "left-right", "layer_view": "FB", "fields": ["Value", "Footprint"]}
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
var pcbdata = JSON.parse(LZString.decompressFromBase64("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7AAxaYuZ/VnsWeuZ/NnbmZFJ+dmfBkXZlFnQKb8Z1WmtqcCZwmhcaftZn5nPyYip51nHgABZsdmLqYnZlZnvABuphYm42Y5pyFnYQH6ED4pTKdTZhFmPqbVpL6namZ+prehnGdOJtxmymcZZ8GmmWbV4f9mB+nENKem5SA4ABGmfWaRp95m1/j2p7wAMabyprGmoKbHqfGmH1VQ54mmMObrZulmnWcppp9nRGdOp2mmNKeEZt9mpWe8AV/Gv2f0pn9mE2dvnATAu1mVZ+FmNeWyZpFmNWanp1qns2e3ZvNmpaZbZhDm3XET6Xjmy2b8pq1ntqe5Zu1nJqd7pu9mB6fVJx9mhGaNZxanwSY9Zl1hfsnk54ZnyAivZnln/WYHZwNmqOZDZkVn5mcWZ4FmoYU4AKwnKSY2ZyqnLBKWbZFQNWcyZ1VnBOdAJ81mDifcFdFndWa2puMmYOdxZqTn/yfc54lR/ac1Zo0n2WdaJvMnlOfGZ7inaWeyp6jmfyZ05mWmIudKaal6jObSJhLm+2fM5j0BB2fU546m6OdFZuznlmZY5nEAmabnJ79nNma45pZhwGRBAADR9mbTZuFkwmStFU9m/gAhxE4BGQA23ELmDWfcZkEmZafg5panvZua5p7ZamYeIScUGmdM5lTn0ab6ATGnSOaI53GmSOdKAKemWKYw0tTn62fvZwemtOebZjLnhCdG5kUnhPljUL/ANuZImSSVFOdGZ5GmUACptXDmcQHw50NnCOY1p1bm0ZVI5wmnNua+ZQhnBWaRlIYBymeO5tzKfanrZc7nPucu52SVYydM5u7n2VQe5q0nFuYI55bnXuY+Z57mPuZhJr7n4Lx+54NntOeG5o7nOAAhp7cDfSxB5iSncmQh567moefu5z5nHufh5lHn1uZW55Hm1uYu5scAtucx54dmDuZx5sGm8eek5pChd/DO54nmZuch531nvAGh5jOVYeebgahn3udp5pHmcOYR59bmweaZ577mBWax559mGOaBZyrmHOa9JkQA5WdpJh4InW3YYVrmEWdDJjNnamdE544mgua5AVsgJOYLZnpmOttNZxjI9ea7ZpKme2arZ21mkudvZnbmNOabZ/7nGWb6pllnsKGdbXLmTSd7Zl3ma2ZpZqZnUues50dmVefHZyVn1ecMZ8FmXOdMZkXB5Gir0YTR9eY15Fdnt2SFp43nHGc3ZqDnqAixZlAnDWfZ5rnn6dhT5tWBfGZSZC9nRqcF5oJmb2dU5lnnduc05mjmR2bmZ8NnX2Zj58kmhQC159CnwaT/7M+m4Wfqp1kmvCez57VmxOatZ3NnQuf3Z73m9OcDIVgx/+wd54amTWCD53anKeYs5lLnyabS5rpni+buZyVFoCABhfvmYubqZ8tml+ed5lfnkubD5jfmI+db5l9mmOY750FnY2Y45+rnaSemHe4xZhzT5qWkfObZJzNnR+dN58WnJ+ck5w7nW2czUACBX+eOgPgxBmcd5zDm56fGp/tmiucs58Pmvyeb5tnnC2dpJvUn8jCuMBfm4uYRJmvmqWdF52ABiufd50rnZmbUpqPn2+cnJ6Vn90G75hVnhRwqcd/nEWd857/mAuZ1Zv/nBudg58LmTWdoAHMxRRy652LnvWcU5ubnXefr5xXmG2cQF9Lnt+Zn5q+gN9AD5/gWcBbM5vAWCBas5lvmSBeiZ8VmlmcjZydnquYf52dn0KdKRN8weSDoFhkcOuZW+Mjn8+T0wbx45CYG53dmi+aFJwHnv8djUX8x3zCm58HmU7NbiG7mz+Y+UJ7mGebp56XmaecZ59bkrgAb5j3n9ua95qTnbBfQpn/hKwEcFngX/GRJ5lwXgufJ5mHnV+bF5pbnJeew5k2QGebl5/wWL+bCZoVnleZUFxjmJWfIF1jmpACoFo0s750w8FNn+OY/5hqmhOb853YUs2d/58Tn/+at541n6KdNZ++dypAgFxfnsBaw5v1n5BfgFy/nRBa35lAX0Kf05joXpBYrZpTmCuf6F9fmchav55QWxWYKFtQXmOfV51/H2aaf5nvmaBZMXByUgOYE5moWGBZH5pgWx+YrZ4pmrBaG5kYXqBYDABhgfZy6FrAW1ad6FmAXCufwFgYW5haGFl1nABa5553AReFHpCYXXmYeF5pnYBeeF2YXfuaUF+jn8hdV59QX32ZxAOPnBjDq51znnmWo6VpwDBZsZzPm7GZE5nPmt2atZ04XC+fOF63m7Bc5OFpwCqgr5rGkq+ZM52QXgmaEFodnG+f+ZsrnbOdUF+znO+ZnZzjn8Rd75mJMdhaqF+gWv+cOF2AnjhaHmC3nmhYPZotnZ+Zo6G4XCae7ZwPnT+b6FpIWgReyF37m3haip6fn6KZjgXDo8ql+Fskpl+alF8/nKOfD50EXyufpFtXn5iec5uEXE+e0iDsxnCfZFwfn1WbqFk3mYybJ5gvmcWan59gWgebNFnWJVqbFFyAXFOfbJ4PnARYUFhAWH2aQFkIWPhYi5l0XwDDVF1uIvRfcFykWSuZmZ0Nnr+dIF2/mihehFlmnaucf5+EXYQGaMKBgA4gH56xmM+e1pNEX12YxFvPm9Wct5wUW7BYJ8TMWM4gu589nZ6ZtZtIW8fDd5qzn5Rd1FukWlhYZF0FmkmYT5lJmpeEq5XeHkRc/54fnohZtF9qmsRftFvdmABfEFm4mZGpgvMMXL2dkF+bna2e25xsX/RbEFi4XUmdew6cXMBb4FyYWBBZD5gNngRaV52kW2+YTFqNnOAFZppkWNhcsE0hBH/GPEbMXVWYNpVdnhafUOXPnzmbtFndmcRbYFoMWaifrDFPn4Lz8F+Rk8udM5hentad1p3zKzWUjprBmwmadZdBnHMvL5K2nvqkNYW2ma+QLwGjJtGWdp8vk3abHpD2nzeW9p8mZ5GUtUiunM2QPR8OkCIlUNeOm4GBfp7Bnw6dAZUukk6c/OTwmyWWnpZOnXWRoyNOn/6V48V8w9aWzp0iW86c8J26hMUQ3pLlRX6Vx6ABZb4yrp+oULxtrp+HhyyAbpoShcGbXp1um5JcrpWNkcGfwZqMXCBdKJgMXxxdXF3cojtknGCSmVaYAl8kWtaaXp0CWrS3bpnpcytlNp09APEhbphuBz4yW4V+ldzUPpgRlgWX9ZWBYNpEn5R3BZFzlZH4Eb6ZUCMZFOJYfp8gUaJefp/jBX6a2UH+nTok/p8+nv6dV5QCQTGVCcdZBfaeQ4F/AXJZ+BaBnTMZMZJ/7ohj/mWBmBGWiMf0AbaaMOuSWUGYtp/KWTacolw1ho6ZwZ8qXC2R+YVSXWme1Fy/nmxaL50knaRfEZ8Yd2to8p78XxkXvEWRnsNLa2thnP6S4Z1RnGGWUZ0/lW5R4ZzRm2ebal4gXaGb9J+hnxyJ0l68W+patZ1GlRwHkZyxM56V/5PzBFSHGluShJpf65TRmKuchFqrnOAEMZkfxtBbc51ek6KmRF3MXDmczZrChMRZOF0cXrBbxFunChQlulpwXqxagF2sX56br5xqXFxb9Fvbnm+byFxYWIRZWF+YnLpeZFj6WFbn88QDmORddrNWlYUzXZmEnh5D3J3nlJhcsF98Wwuc/FoHm4ZZu2B4xM2d0wZ6X4ubm5lAAMgAaALinEBl0wLUWgZcGF5cXhhfeltzmCZdGyToWCxZJlosWtqYjFpQmKZaplpLmaZcmgBsWdRbBlk6XIZfbF6GWLxcTZ/zxy+aXZtNn+xfDJ7kXuSeHFitmJ+dYF3GWJxfxF4tnVcFll6IXxRcU5jUXHhZmF2UXg2abF5AXmZeeZZUWdZcrF90XuhdbiQ2WARaeF30XmpdFl/UXTpfV51mn2OaulxhnpGdDidOJkRfvF1EXUZc+TEWnnxdJFtlgSxcVF7/GLIbPEf2WnBYMl36Wdqfnp4yWQJfkhv5lwJel4EqXM5dql0qX+NXT5OCWEGcQl1uUHacwl4UAZ43QlyYx3acUUT2nT6RwlzCW/aYIl0LciJeDp0iW6UHIlsKXKpYol9PkeGdolhOnY6fTppiWaJY/QdOn2JeblLiXc6csINNlNglTpB0GhJfLp0SW6gnElziFLafV/Am5kuUbpxSX/0IUl2qWlJcfp3eWGpYXFwIX7SbNlwMXNZbHpz/hY5eTieOWZ6cTl7lmgJZMltOWwJZnAFunLJfyl6yX5OSxkB+cj1Qclg+mJ3rPVVyWT6fV/HaWL6e8l33lr6a/p9nQthRrCPOXzWR7l0KXb+Td/HHGBRUUUFwmz1VYgDqg4pb/p8+mAGegIIBmv2jEZdKX+uQgZgRlspegZmtDdZY/J+BmipaGILOXzaZgV9BnqpYql7uWu6Z3ljumD5dD5pqW5hZalobnZpdjFsRmFpYkZrqWpGcApmKAr5bWlvraFGeGllRn7E22l/aWlJVgHDRmCmWx53hWbOY6lzcChFa5p32XRFeYuHzLH5d23EaWZFbGl0aWJpYUV/hmlFbFlu/mdKZnJrQWYZe2ZqwxRujabLzm02cdITcnTAEfFn4Y9yYSFJoX1ZcdFvGWyxbkML+RFacyF1inZubnFwQXAZaPljSWVxYtl2EB7Fa5aIJW0eckptinXBZ3Fn0WXhZBF82XWhbLF4ynAleDl0Cm7yeSV+IWwld3FtfmTZdZ50+XtJcQ5rYoVmCxkfSX8KdCV/4XcBelF52WuFcyV3TnJxbkMbVQzhj/F9mwGlegFx2XjZc4VkEXXZdbFg0X2xdKF1dUPMosBAUFdheqFofnFZcHFhoXbRZelt8WHRa0lmJXgBYU2CIEZxer5xpW5BeaV9JXTZcZl94Wz5csElzgtlYTgHZWyRb2V+cWOFfplrhWRlYhlyxWEmcMACZXtIjTIc0W+xf2FrkXFlZ/55ZXCKcjlp0X/SY+V10WrlaqAHmWjZYOV/cWRBeOVhUWgVY+lkFXQxc3F4/mySghVgZWoVbKVgcnuFfjFwoWTxZfx+yA3lZ/7SbIPCLllg3n02dqFxgWeRcaF8fn+RZ8V9ZWsldGF4UW7sCZFZFWFOcmFh2WmlbplyJX6WbhVvxX0Katl5lW6hf1l9lXJRchVrlXhBaxVx5Xo+cTFxznlAEJVsT43ZmURr5X5leRZw/mhxYxZ98ZsRbWVloX2ldpJ3zRcOnqJ24WtxZP51JWnZcOVmFWQZeiVhlWzldKpA1W3RZhJ4VWTVeKVtJXoVclVw8Wb+dxVjQXOABlZlMXvZaFHScivlOVVq0XKVeVljVXzea1VscWdVcy5mfnsOSnIsFXK2dNVwZX7lblF2FXsecqVox4a4BoKPOXD+cdV9UXRVfRV8VWqRZxJqVWyBbxVsFn1hbTFlTB3KMmKFb4nFbJVhWXVVfRFv5WVZeg5ulWo1bdZq8rELhDA+NWphe9Fs1XXVaCFzSX21aAFjNWFNTj4HtXE1YxVoZWDxbmlvUXRlfdlp/HWacllytXTyB3SFyGA5cqFB6XamdDl0mX2KcBVvlW3ObXVyrA6lf/Ftsn8uY1plOXl6ZZm2BWmFY6ZqCWwKboV2CWVAngl/9C6uSQlkuXUJfLljelK5cwl6uXsJfPRXCXrG3GcRuW+9Gbl+xEQ6bd/BOmu5cT5KiXKpf7l/+k25fol2iXwJCHl1iWvadHlrOmVuG4lyeW5WULpmeWS6bnlkzUF5dMFyuka6ZXl+um16Y3l1hWLJZ5FajX71ZUlq4BhZYZly1WmZetV0GlUYGuKPDpr5dPVz0Xz1ZL0S9XTJfZw8yWdGVfl/sn35e3puyXv5f3pwtl/RD/l81kAFe35IBXPJbeQIBlfJYgVu+nFNWgVtBmY6eg1jOWEFfUCJBWP6dQV81l0FaZVAYV4pf/pzYJcFaZLfBW0pYK8DKXiFbPVUhXUJeaGExkCpcLl4qWc5fuaMqXIJcYVqqXqJbqlzeXM5fYVvcXMVeLV91WPxeWFjnm+FfmlsSHJGcPV/FAU+ZqZtaWBpfTsxSHdMA8ZcaXMteMVp+lDpYmlpRWZpYnJ9qWBFc6l1zL/SaPV1aWK2fWliRWtpekViAdZFeMVg6XTFaICY6W3ZfFlnSmrCe9JzsXf2cE2VvBnCaDJjkXDeYpVpWXAuYaV/dXTlbMZ7qp/PE5QHtW0Vc5VpjXXhdTVtpXo1bcyqNtgvEb2VlXjOfBVvjXNRYW14ZWItfBF6VW8VcMZ2wnbFahZ2ipJij459cn7peOZ7Pmnpa5lpOZVlcjV0sWqqYu1kUJiRZeZnoX+levZ5Hm9taOVljWqaYO18GWjta9Vr0nYRdTFk0XnqDemKQJbBNvF+WXvlYHFtVWllZbVvdWBRajlkSnodaEU2bWdtbFVv7WLVab5q1XdVYx16wScaCNyHNWPRcmFubX9lcLV6MWcqZLV48XQdbj531WztYxICeoblj6aUlX0+c3V27XFlfu1l8WVlfG19NXO1DZ1kEAp6m+lyvmaxaTlnGnftbUlpcWAddo52dWWxaeVmVWQAESZo0WIda7FypoexchEINWjed+Vo4XqVdVl2lWzhci1oXXbQx+UHXXNtad5ydWadfUlnlW01Y2VxyFeY2JUJsmrdYlFm3W8dbdVxXWjxc9VqEXZVdO1qWWQKD/EM8Q94DoFpGXQJhRlm8n0ZYEALIYAVbR1+FWWZaMhMpTLOSR1zmX+dbJlucW+ZaXAAWXiJlplz3XB1cJ1lbX/SeD1l1go+VT1ySBd1fDFnHWLSaz16mXc9aFl2XWRZaB1ixWVdc618HW/VZUwaPJcOmkhutW9hZVV4TmCxebVsNWwrlel3EW2Nb/Zsihu9byVi1m2VadVm5XwlcPliVWC9dY1onXYqajHH1xpIaNVlFX7ZfzV+bXG9Zdl5vW2teeV6NmwkHlVnfd0NK+ZXvW5leDVkbXmBYF5p7W3pfH1tXg0NJF4AZnbZbuF7mXq9b31iJWl9ePlpbWKlcd1g7o84GqZ6fXeBe31z/WPdf31h5XD9fnV9rWXlfPFldWkKBwYDzmLRayZhHWFlaR1ofWzefICbGXtVZe1tznkDeJUKEmt9dn11FWv9ep1/PW/9fl1h3Wn9Zi8MOc/ZftVyUnjVbINyA2f9aLVogWYtbnV5XW8VdZp9XWO9faU4bFH+nXVznWpaUDlvMXQDaJpnHBK9aKVh/Wx9dX1sxm9MWn6Y9XuNdO6XjXAJYE1vRWhNcwZ7OXfNdoVmCXLaefVwuW31eLl+UhS5bQl79WxrP65GXR/1ee8euX8JfTpwOmf6ZMUCDWyJegZhiW9Nb81+DWvacQ1kKWENZ7YZiXKkHjFNiW1sDHlrDWJ5fOQXDXp5YEltg0y6aI1rmaxJZk1iSXyNeklyjXZJbo19emgtfo1vBnGNagNlNXqDeW1jtWBZkENg0A9JZUN/xmWDaMlxenU5cGlyRXhNYyNt+WE0A/lnen7Jek10jWLNg3phTXJOVPp4BWvJdU18BWYpcgV++nw5hvVp+ngpajp8KXDNbktaKW0Fdil8zWsFbQVnBXkpeAZghX7NaIV4iBIGb/AMhXDnAoV8hxuQA81mhWvNcfV2hW/NYglmDXAtbo1+qWcjbYN2nXchaB18cWVFfyptRXnKPi1hQ3ijaS18OWp6Q2lwTX0tYMV+rWjFcMVkxXA2ymlgrXT5YeNuZmnjfMEpaW6lPZJd43PCNS1ixcM7Ia1gE29pca1+RWgTaOl8xWj9db1mxXA9cgIPSVt6F114bX9dapV/5X8+dkN03XADYGEoIZQeYdVinW/he+1ig3cjf+1gnWV9aL1nQXM1Z8GGk2mDfAN3ZWGTduV0LXp1eHZ+nXfdbOlkAAAAE0vZZZ12EhzDCgoM4Yr9dXZK35X6Wb7TNm7GXU2rGlPziBbMbX49YPV87WsanE0fMXaTcMZOxmM9fn1kpW4BYHVqg2WTZOVoXW9lyI6Zvl5OeNNio3TTZdVsLWqKYAN2g3O1E50O03jBff1/zWz1dYNxfX2Df4p9035DYxIL035DEskh02PjdzJgM27le5V243vdY9VqLWVdefx9vWpTcTs9pES6EJNg4XiTdDV7A31LnJNjWWbTdt56Pge1Y5Vxk3rjbt1zfnrTcANthgyOhtlw02P9ZzJ8s3+TdKVwU2vdc4NpXWQdb91kABWaYD1xA2PXHnGXqXktdFiQbXJhofF7dWnxekNkZmI1cf10M3tIhwwLcZlDeiFlinVDcp18g375eqNtLWUaQzl+9WzaeNphCXUGYMNqkAjDYakWAcP1adpr9XXaZ/Vqw2XjRr5OuXfafsN/+lHDfwFEiWB5bol2DXmFfGNuDXoNcYlj83Rje8N/w3UNaCN9DWQjcw19yZwjfzp6woojddpwSXGGXnl+I3F5cSN5eW96VXl9plbUDSNo6mX5do1rC3Tjcjp/eWrjcDNm43G2eCF+lX5zYcimts9xlKNlc2wKejNqnXNzavVoaW6je3lsTXGjYk1r+WP5x/lmTX2jaPpjAxAFY8l8+nejavp+Jh1NYCl4PIgpbPVOBWxjd01xBXLDWQV885G5VM1n+mJaHmNkzXFjfkZFKWQGcIV8Bn1jZIVqBmXNbyl/smqFYQlzzXIJf0Nw42TjZ0Ns43d5YuN7ummTaFNu43ldeK1uLWNFfY1xc2qLZvFqrX4Tf1pxRnJOSy1prWATdy15rXctZBN+42itcV1iE35IcmHQc2lzcq16GlvLZXp2Om6tb4ZgUU5FfUZjE3z8Zb147WWabTN3E3JhD4QGe4RDfENic3edYr1h7XXGbbV/A2oWZmmS7Wb6CrFiXXb5e8Fk2RKDaiVmHBhTeTNng2K1ch1pCgVZkiFuC4ircMF7dlOucP5nrmzBbmHCuJZzbkNkbnOeYi53q29BY21mi3Yhb6Vv6XcdY8wTwWJebvlt7mCacSV+XmMed/11q2azdrJsIXLxfEcPq2FrcP56bmsaTiFmc3ZBeF5wrn1rZe5usXxee2tp5ndrYCF/a26dZgN7g3QddZp5nW8rZXeimgDGBrmWZWOaW51rPnohZ3V8q2I5e1NibWWwDH+/SVfZjKN6M31DaqNxi3aje0Nvc3b1eglo8296UMNm2njDfPN0w3P1c1DCw3biFvNmuXp6QA1uw3gNYcNp6wnDbfNvw2oNY7lr83fzfwt1m3INbgYLw3a5cHlxOnh5eCNzOnNNbCN/+keJanl/iXYLZiNjxkELeCIhI3SNaSN1C2KNfXlzC3V6ewtjemxwBstyS3sjaTV+M2SLaHVqq3K5gvlhG3Y5h6V8o37hYZNhi3vjZ3N5+Wt5dE1j8nxNfklyTXOLdaNxygeLZcl4+nFNYEttBWhLZ8l/o2ZjcGNzTWJLZGNrm2PDYmNuS2jNcUt2Y2gggs17BWrNaWN2zX/5e0t9xxdLac1/S2nadc1uBm9jeoVpBnsbZ81u9XLLYwZmqXcLeC1wi24zY+thM3Ozdal8K3Ozcitmo3JhyYZw23w5iq1mrWpR1+NlK3stcCtlE30Tfy18/HCtZEZiK2StfUVsrXhFcBtzxhY5l0Vmo3atdSt1E2dpd0wAK2pFZa1zE3YDeP171W/rcQNukmPOcz+bM2flcwNg3XSTeLFmG2bTbJpde3FLhINrbXrWal1gtWWrft1go2R1c7UPUmdpjMWE+3JdcS5s02ZRfbN8LXEzZxVjq3GdaMZnE2BzeuWUXXSedHN67WwbYNNzkm+dY+Nya2KTY9Nxr92dYbNp5mfpZkFvZWKRcrNuXWrTYV18u2kzbbFjrXcrcQN2wyUDc3txHWm1Z3tlHWUldH1qB3yLfpwAERkVGIN302eTfICKnXWzfNN102Drd5V2G3lcCodhg3sddjNgU3k1ZnVjB3P7awdl5Wurc11nTZ38E8yq7W0Df7160XkdeH1qoBcDee19HXLxbQIKLmcSEft/03nVf7V5h2r7ZDNtk2lHbEdnLm3dbUNjR2tbdLt+YWwReB10tXQdbBZs/XOURvKyxmxzYbVgfW8mawNlgWTdaLNwA2lams8cekJ1eMdqdXeHfx1z3myLd0dy2XiemO2Iunydbtl2cXnTc0dt+2ODZs5n3Wv7Z7NuPnNee61hrmkcHr2fSVKheAdo5nwbaR18B3XHZxl3xW2HfSdsR36iA+1k22onbNtgGWiLarNnW2Ima+t7s3RTcSZmx3+wCOEVKW4dfrV9A3G1cH14h3ZHctYQXXKTdUwNp2uTZJZ5g3TbZWti+37LepF0i3h1c+F3ZxhnZ8d6J2THaDNz62P7cO1yx2ezcSZhA3urZCOvjUJWBBtobWcze3tkk2SHc1Vsh33HY9Nn0ABImi0Ms3d9YrNmp3UHcCd2Z27mZJPa52bGFud7h22zf8djs34ncwdsZWOtcdgM/Wj2lguFUD5TcOdre2iHZOdvp21Zbcdop2zdaFan5R3fA+d3x3bdcedmZ29bc71kuhPYjqt2h3SDZ31z52mHdidmMXfnYEd/53vAFZp3+3urbrt/UxmLjBd8c2g5cfFqQ2obf6d/e3ADZjlkS50kHsuY23kbcqN4CW0bfTljG2Dzbwth9XzLfzlvG2EJYJtwNsLzccoK83i6ZvNogJrDfvNqm3HzZpt5826bdfNmWl3zaZt9w3tDZ1dqS3ALb7l9m2EJhTpliWQLdrljDXBbYgt4W2cNYLpmC3i6bgt2I2RJcQtkjX3GxQt/OW0LZklw2BMjfqNwu2sjcC1kLWvne1tk+WgncKNqlgDbZpdrl3glbXN+k2JncJoDQ3x7afltW3rbZwt2222Lfttji2bFy4tto3nJf/lt22ujaU1wS2VNeEt3nkTNf8lqBWA7bZt5m2RjZktgzXQ7amN4zXxKAkIzBXQ9ejtpKWNLeWNuzWwGcTtrKWU7dylnY2MKpSgTO3G5TNp0V3c7YC1043h6RYV313LjeWd4i3sVY1lsE3+FZctwe3NFcApiN2sxcbt1hnJFaStye3kTfMFvd30rfnt7u3QTcrt1RX+7eeN1y2wwF9l9d3rreKJzaXm7f+Nv42/LZy1ju257ZCtzK2sTbxVqwntnZEd1AhgDcpuLJ3JHZv13M3Rte8V2F2Q3Zvt53BYgBMrRZ2+TYX1ku2VnerN1h2zdfMGaD3AEFg92N37nYQ9ud32rcEdpMW+DfTN+nCSGRFCAbXsnZKtvJ2yrfT1sk2BnY9NpE1CrZothB3txfJF6p3sPdqdpsXcPbJd6NnckBsd8exClOwpul3HHekdlx2wPcKdiD25nZ5AHD8JDdzV8Z3z7e/1h53gZbQdmg2KHbSWPj2pPbpNr7XMPcYd1+3vnfft/h31nYZ1pJ2jGeXVnZ3nEia5m3IJHeXZkB2JDY3Z6c2KrfA9553emeNeDSIOsHKdnl2kHZY9nh2g3dTVjj2F1bKp4z3f3creeGXAPe85rp2nHdRZ3p38zZZdyq3FHd1NiQ4EYgw92T2sPc890x3g3Yc9jrbMdCC9hL3n7ZdNol3Vnb09ix2DPdFNsFnJTf+t6FnVcCRFAh2MDchdvM2c2eN10T20vdpJ23mzxR9Nxs2xna2pls34PeS9xD26ndZN0N38rYEiZr21Pcid5s27na09lpX9tbWdgr2RTdj5oxmSvdwdzMNjfi41jp2udZyd0B2HGfydkT28DZi9kXAFvbiAE35xdZJFp+2mrfrFqZ3l9cB1yb2sre/t4R2etdQ0jf5VcHQ5IB2cxas9x6XKPYgd8524XcpNnZnN/nZlxJXGPZjdxL3kHfk95jXFPZ89uA2kxb3gGx2S4xT5+om6XZu13J30RY29kcXCzY+9y53/42h9xg2z2YatxB2qnZl1lB2FPZpFi73P3Z+tn92bvctmdyh8pFhZx73VWfa5oa2WvZDl88RUcEAd1tX7PYB5ma3twIslMGoOCD55q62jvb7V0XmHrcR5p62Uhb/F5nmUvf/1sT3jrcYZglN0CA4ti63nBd59+TA7rf596nmvBal59IWNreCV0X3uvaU96a2QAHx5tzKOfZPhLsYnBaWtxq3buYp59qQBfdSF/6X6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AHdAFmniABupsAA0gGwJ+AAaADczsgB3057cL9OAADVsCbnT/wB2VSuAU/Ws05EADjOS09szpJm4M5kzlDP3QFoz2TP5M9wzwzOM09YzpNOzM9EzzgBlgCEJ9jOCs4zTwTP8s8Sz/jOis/EzjROnM5czgLPRhxkATzOiAG8z3zOz08azi9O2aekIMLOIs/RlDOUYs5UzyrPvVaSzkzPhs9jT6rO7M8sz4FPUs5oz2bO5M7AzxjPss7IAJTOZADfx3jOqs/MzkAAmk6IzmzPJs7aTlLP0M9kz9LP5s6yz5jOrgBKFuLPhM9szygXd0/3Tw9Pj09PT89Pv066AX9P3QHvTx9Pn09PTt9OP06YAL9Or09ezyAB/08Az4DOsg9Az8DPRAEgznLOLs4qz6FP5s5Ozo7PMM8WzhTOVs6Mz7bPas+2zswhiM9V1lmn4AAsDqcmAAEFKgDi4dhPYkHgAAABpMABME8qAUQOGM4cwNAAzVC/Tm6mmgAgAD7OzCYuzobOQAGuz/bOxs5AANnOn08ezvzOL04Bzm9Peif5zr7PX066z8xh/s5/ToHOAM7PT0HOGgHBziAAIM/OztbPps7kgJtPIWnezjtOu04EgctOo07Yz+LOys/LTxNOuc+sz3NPbM4huDbORs8mz5gASs5EAdwA9s62zzqAhCe5zl3PYc9KzzbPCs5AAIQAhCfFzwXOz0+Fz2XOxc/uzgXOX098AH7Ppc7wAF7PRc+BzhXOQM4gARbPVc+hzmQBhi12zy3O7c95zjLO0s5kAHPP6M+Rz5bPVs84AFYAHc/dzn3P4gCEJ/PPpM8RzgvPsM6LztHP6kDdzi3Px09sz8cQ+05EAbHOrCdxz/HOic5Jz0mkaAApzqnOtCZpzunP+MAZz3uAmc5Zz/nO6ybtQErOu87bzitOjc/Lz2fPPc4XzybOLAH9zsPOJc6Dz2PO3s7vT7fPA86jzz9OY85Fz39P486AzxPPk88hztXPOABpnDPPW843z3nONoA/AG6mICfdAAAANZ/GrCYAAcS6RF/O/QGPAFgAWafegUtPZ841zr3Pbc62zjyAt84fTh7OI8+ezs/Pb084AAPOI8+Pzv7PT85Dzi/PFc4PTpPOIc5EAKHPUc57Ts3Pq84RzqjOkc/rz2/OQAC0gIQnHM6IAZzPXM6azzgAWs7azx9P/M7czrrOQs5jz8LOigH6zntO8s75zw/OEC+DzwHPQ87gL8PPvs6lzk/O987lzkHOr8/wLwgvi8+oLpfPaKcgLibPoC9hz0gu889OzwvOqC6UgZvPs0+dzn3OYUHnzowue095ztQuRM57TjXOtC/OlnQvKC9TzzgBhQFMLzPOts8+pEdPDC9cLn3OI4BcLx/O3C4EL1Auns5EL0XP3s6ELyQv30+jzmQu/0/lzy/Owc7wLlXOb88cLkABDYF8LkjPJs7qQKvP4c+0L2vOFs4cLoguh04xzywvbM7VgTIuci7ILqTOzs6SLyGAHc6dzrwu6ydzAB3OEs6gLn3OgoFKL8gu5s5yLyov8i6nTkgusi7sLzovdC6SL02A2i6kz8ovMs8GL7ovOAHmgWgv6s8YLlMWWC58ztgvGs6YAYLOes+4LvrOos4GzqdOVC7hzsovsi/aL3Iuls6oLpkARi+Oz/YuKi4mLpQuKsFSL1XXbM5a2uLOmi/ULlovs876L3YuDi66Lq4uIC80AOovt0/Iz2imukURQMHkdc4AAORhgFmmRHA/ziEvhQFJpJgB9GZFKSEvNAGBLusmYgCEJgEu9GFbTttPQS7IAcEvNAARLkQAP8+hLqQA4S5hgPEukS7+54QmrS3ET9pPLE+kTkZOrCfkTpxOlE5jMfRO1E8ZLrrWBADZLxbYXxZ0T+5OPE8xJf2dLE/MTyRPEmcJTuFPEmdsT6mhYk/Kpg+hFE5cT5ZObCayTxROvE7FL15XyQCCTxbZ9DjRTtXWZk8lLgVOrCYiTlpPOteiTi1O4k5mT4UvQtL1AN1PHk7AgNJOpk+Kzk4BMU5lZ3JORk4KTtJPJE5lZ25MzQIyTiHB0OcqT2VmTgCmTt/HA6XyTppOTgBaTtYX2k/DL4tPN2cqTygXRafqlgVPrHfUwYpPhk5DLsZOpk8mT/JOTE+WTsFmJA+ZpL0mv2fOEdZPVk8dLilP9/AyT7ZOHeS9JvZODU7BZo5Ocy6sTs5P8Vc4iQ2YUk8W2OFOKSeFT2sv2S/34FJOUA/eTgVPPk8rAflPrk9+TyQxiU9JTnFPkxeFTyRO1mayT2cu5U9hT4lPEU8xTk7W0k5aTi6XhU9XLnK2xk6nL1UuESEZTwlOqU5JTwFPty4pT+IBGU5pTs8vFtgZTtFO4+aNF5lPyU9ZThcuLS4oV8lPYRZnju8veU8BTkcuwk89l4VOWk9ZpsVPZE4lTkx4QK4hTmVPwK/lT8CujRcvVQVPbkw8gcCvm7CgsWJPtU5OAXVPSU4NTq1OZk9kT21P0OftTgVPHU7GT51PXU4NTj1PRaa9TwiufU9uZMFHKS6NTj/BcK+adp/AaK4vxxjBAaTkz7BPZACPAC/HuA51p+ABHwA8ZzGUgaRxAR8BQ4FoAQSAgAAA="))
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/* Utility functions */
|
|
|
|
var storagePrefix = 'KiCad_HTML_BOM__' + pcbdata.metadata.title + '__' +
|
|
pcbdata.metadata.revision + '__#';
|
|
var storage;
|
|
|
|
function initStorage(key) {
|
|
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 storage.getItem(storagePrefix + key);
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function writeStorage(key, value) {
|
|
if (storage) {
|
|
storage.setItem(storagePrefix + key, value);
|
|
}
|
|
}
|
|
|
|
function fancyDblClickHandler(el, onsingle, ondouble) {
|
|
return function() {
|
|
if (el.getAttribute("data-dblclick") == null) {
|
|
el.setAttribute("data-dblclick", 1);
|
|
setTimeout(function() {
|
|
if (el.getAttribute("data-dblclick") == 1) {
|
|
onsingle();
|
|
}
|
|
el.removeAttribute("data-dblclick");
|
|
}, 200);
|
|
} else {
|
|
el.removeAttribute("data-dblclick");
|
|
ondouble();
|
|
}
|
|
}
|
|
}
|
|
|
|
function smoothScrollToRow(rowid) {
|
|
document.getElementById(rowid).scrollIntoView({
|
|
behavior: "smooth",
|
|
block: "center",
|
|
inline: "nearest"
|
|
});
|
|
}
|
|
|
|
function focusInputField(input) {
|
|
input.scrollIntoView(false);
|
|
input.focus();
|
|
input.select();
|
|
}
|
|
|
|
function copyToClipboard() {
|
|
var text = '';
|
|
for (var node of bomhead.childNodes[0].childNodes) {
|
|
if (node.firstChild) {
|
|
text = text + node.firstChild.nodeValue;
|
|
}
|
|
if (node != bomhead.childNodes[0].lastChild) {
|
|
text += '\t';
|
|
}
|
|
}
|
|
text += '\n';
|
|
for (var row of bombody.childNodes) {
|
|
for (var cell of row.childNodes) {
|
|
for (var node of cell.childNodes) {
|
|
if (node.nodeName == "INPUT") {
|
|
if (node.checked) {
|
|
text = text + '✓';
|
|
}
|
|
} else if (node.nodeName == "MARK") {
|
|
text = text + node.firstChild.nodeValue;
|
|
} else {
|
|
text = text + node.nodeValue;
|
|
}
|
|
}
|
|
if (cell != row.lastChild) {
|
|
text += '\t';
|
|
}
|
|
}
|
|
text += '\n';
|
|
}
|
|
var textArea = document.createElement("textarea");
|
|
textArea.classList.add('clipboard-temp');
|
|
textArea.value = text;
|
|
|
|
document.body.appendChild(textArea);
|
|
textArea.focus();
|
|
textArea.select();
|
|
|
|
try {
|
|
if (document.execCommand('copy')) {
|
|
console.log('Bom copied to clipboard.');
|
|
}
|
|
} catch (err) {
|
|
console.log('Can not copy to clipboard.');
|
|
}
|
|
|
|
document.body.removeChild(textArea);
|
|
}
|
|
|
|
function removeGutterNode(node) {
|
|
for (var i = 0; i < node.childNodes.length; i++) {
|
|
if (node.childNodes[i].classList &&
|
|
node.childNodes[i].classList.contains("gutter")) {
|
|
node.removeChild(node.childNodes[i]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function cleanGutters() {
|
|
removeGutterNode(document.getElementById("bot"));
|
|
removeGutterNode(document.getElementById("canvasdiv"));
|
|
}
|
|
|
|
var units = {
|
|
prefixes: {
|
|
giga: ["G", "g", "giga", "Giga", "GIGA"],
|
|
mega: ["M", "mega", "Mega", "MEGA"],
|
|
kilo: ["K", "k", "kilo", "Kilo", "KILO"],
|
|
milli: ["m", "milli", "Milli", "MILLI"],
|
|
micro: ["U", "u", "micro", "Micro", "MICRO", "μ", "µ"], // different utf8 μ
|
|
nano: ["N", "n", "nano", "Nano", "NANO"],
|
|
pico: ["P", "p", "pico", "Pico", "PICO"],
|
|
},
|
|
unitsShort: ["R", "r", "Ω", "F", "f", "H", "h"],
|
|
unitsLong: [
|
|
"OHM", "Ohm", "ohm", "ohms",
|
|
"FARAD", "Farad", "farad",
|
|
"HENRY", "Henry", "henry"
|
|
],
|
|
getMultiplier: function(s) {
|
|
if (this.prefixes.giga.includes(s)) return 1e9;
|
|
if (this.prefixes.mega.includes(s)) return 1e6;
|
|
if (this.prefixes.kilo.includes(s)) return 1e3;
|
|
if (this.prefixes.milli.includes(s)) return 1e-3;
|
|
if (this.prefixes.micro.includes(s)) return 1e-6;
|
|
if (this.prefixes.nano.includes(s)) return 1e-9;
|
|
if (this.prefixes.pico.includes(s)) return 1e-12;
|
|
return 1;
|
|
},
|
|
valueRegex: null,
|
|
}
|
|
|
|
function initUtils() {
|
|
var allPrefixes = units.prefixes.giga
|
|
.concat(units.prefixes.mega)
|
|
.concat(units.prefixes.kilo)
|
|
.concat(units.prefixes.milli)
|
|
.concat(units.prefixes.micro)
|
|
.concat(units.prefixes.nano)
|
|
.concat(units.prefixes.pico);
|
|
var allUnits = units.unitsShort.concat(units.unitsLong);
|
|
units.valueRegex = new RegExp("^([0-9\.]+)" +
|
|
"\\s*(" + allPrefixes.join("|") + ")?" +
|
|
"(" + allUnits.join("|") + ")?" +
|
|
"(\\b.*)?$", "");
|
|
units.valueAltRegex = new RegExp("^([0-9]*)" +
|
|
"(" + units.unitsShort.join("|") + ")?" +
|
|
"([GgMmKkUuNnPp])?" +
|
|
"([0-9]*)" +
|
|
"(\\b.*)?$", "");
|
|
if (config.fields.includes("Value")) {
|
|
var index = config.fields.indexOf("Value");
|
|
pcbdata.bom["parsedValues"] = {};
|
|
for (var id in pcbdata.bom.fields) {
|
|
pcbdata.bom.parsedValues[id] = parseValue(pcbdata.bom.fields[id][index])
|
|
}
|
|
}
|
|
}
|
|
|
|
function parseValue(val, ref) {
|
|
var inferUnit = (unit, ref) => {
|
|
if (unit) {
|
|
unit = unit.toLowerCase();
|
|
if (unit == 'Ω' || unit == "ohm" || unit == "ohms") {
|
|
unit = 'r';
|
|
}
|
|
unit = unit[0];
|
|
} else {
|
|
ref = /^([a-z]+)\d+$/i.exec(ref);
|
|
if (ref) {
|
|
ref = ref[1].toLowerCase();
|
|
if (ref == "c") unit = 'f';
|
|
else if (ref == "l") unit = 'h';
|
|
else if (ref == "r" || ref == "rv") unit = 'r';
|
|
else unit = null;
|
|
}
|
|
}
|
|
return unit;
|
|
};
|
|
val = val.replace(/,/g, "");
|
|
var match = units.valueRegex.exec(val);
|
|
var unit;
|
|
if (match) {
|
|
val = parseFloat(match[1]);
|
|
if (match[2]) {
|
|
val = val * units.getMultiplier(match[2]);
|
|
}
|
|
unit = inferUnit(match[3], ref);
|
|
if (!unit) return null;
|
|
else return {
|
|
val: val,
|
|
unit: unit,
|
|
extra: match[4],
|
|
}
|
|
}
|
|
match = units.valueAltRegex.exec(val);
|
|
if (match && (match[1] || match[4])) {
|
|
val = parseFloat(match[1] + "." + match[4]);
|
|
if (match[3]) {
|
|
val = val * units.getMultiplier(match[3]);
|
|
}
|
|
unit = inferUnit(match[2], ref);
|
|
if (!unit) return null;
|
|
else return {
|
|
val: val,
|
|
unit: unit,
|
|
extra: match[5],
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function valueCompare(a, b, stra, strb) {
|
|
if (a === null && b === null) {
|
|
// Failed to parse both values, compare them as strings.
|
|
if (stra != strb) return stra > strb ? 1 : -1;
|
|
else return 0;
|
|
} else if (a === null) {
|
|
return 1;
|
|
} else if (b === null) {
|
|
return -1;
|
|
} else {
|
|
if (a.unit != b.unit) return a.unit > b.unit ? 1 : -1;
|
|
else if (a.val != b.val) return a.val > b.val ? 1 : -1;
|
|
else if (a.extra != b.extra) return a.extra > b.extra ? 1 : -1;
|
|
else return 0;
|
|
}
|
|
}
|
|
|
|
function validateSaveImgDimension(element) {
|
|
var valid = false;
|
|
var intValue = 0;
|
|
if (/^[1-9]\d*$/.test(element.value)) {
|
|
intValue = parseInt(element.value);
|
|
if (intValue <= 16000) {
|
|
valid = true;
|
|
}
|
|
}
|
|
if (valid) {
|
|
element.classList.remove("invalid");
|
|
} else {
|
|
element.classList.add("invalid");
|
|
}
|
|
return intValue;
|
|
}
|
|
|
|
function saveImage(layer) {
|
|
var width = validateSaveImgDimension(document.getElementById("render-save-width"));
|
|
var height = validateSaveImgDimension(document.getElementById("render-save-height"));
|
|
var bgcolor = null;
|
|
if (!document.getElementById("render-save-transparent").checked) {
|
|
var style = getComputedStyle(topmostdiv);
|
|
bgcolor = style.getPropertyValue("background-color");
|
|
}
|
|
if (!width || !height) return;
|
|
|
|
// Prepare image
|
|
var canvas = document.createElement("canvas");
|
|
var layerdict = {
|
|
transform: {
|
|
x: 0,
|
|
y: 0,
|
|
s: 1,
|
|
panx: 0,
|
|
pany: 0,
|
|
zoom: 1,
|
|
},
|
|
bg: canvas,
|
|
fab: canvas,
|
|
silk: canvas,
|
|
highlight: canvas,
|
|
layer: layer,
|
|
}
|
|
// Do the rendering
|
|
recalcLayerScale(layerdict, width, height);
|
|
prepareLayer(layerdict);
|
|
clearCanvas(canvas, bgcolor);
|
|
drawBackground(layerdict, false);
|
|
drawHighlightsOnLayer(layerdict, false);
|
|
|
|
// Save image
|
|
var imgdata = canvas.toDataURL("image/png");
|
|
|
|
var filename = pcbdata.metadata.title;
|
|
if (pcbdata.metadata.revision) {
|
|
filename += `.${pcbdata.metadata.revision}`;
|
|
}
|
|
filename += `.${layer}.png`;
|
|
saveFile(filename, dataURLtoBlob(imgdata));
|
|
}
|
|
|
|
function saveSettings() {
|
|
var data = {
|
|
type: "InteractiveHtmlBom settings",
|
|
version: 1,
|
|
pcbmetadata: pcbdata.metadata,
|
|
settings: settings,
|
|
}
|
|
var blob = new Blob([JSON.stringify(data, null, 4)], {
|
|
type: "application/json"
|
|
});
|
|
saveFile(`${pcbdata.metadata.title}.settings.json`, blob);
|
|
}
|
|
|
|
function loadSettings() {
|
|
var input = document.createElement("input");
|
|
input.type = "file";
|
|
input.accept = ".settings.json";
|
|
input.onchange = function(e) {
|
|
var file = e.target.files[0];
|
|
var reader = new FileReader();
|
|
reader.onload = readerEvent => {
|
|
var content = readerEvent.target.result;
|
|
var newSettings;
|
|
try {
|
|
newSettings = JSON.parse(content);
|
|
} catch (e) {
|
|
alert("Selected file is not InteractiveHtmlBom settings file.");
|
|
return;
|
|
}
|
|
if (newSettings.type != "InteractiveHtmlBom settings") {
|
|
alert("Selected file is not InteractiveHtmlBom settings file.");
|
|
return;
|
|
}
|
|
var metadataMatches = newSettings.hasOwnProperty("pcbmetadata");
|
|
if (metadataMatches) {
|
|
for (var k in pcbdata.metadata) {
|
|
if (!newSettings.pcbmetadata.hasOwnProperty(k) || newSettings.pcbmetadata[k] != pcbdata.metadata[k]) {
|
|
metadataMatches = false;
|
|
}
|
|
}
|
|
}
|
|
if (!metadataMatches) {
|
|
var currentMetadata = JSON.stringify(pcbdata.metadata, null, 4);
|
|
var fileMetadata = JSON.stringify(newSettings.pcbmetadata, null, 4);
|
|
if (!confirm(
|
|
`Settins file metadata does not match current metadata.\n\n` +
|
|
`Page metadata:\n${currentMetadata}\n\n` +
|
|
`Settings file metadata:\n${fileMetadata}\n\n` +
|
|
`Press OK if you would like to import settings anyway.`)) {
|
|
return;
|
|
}
|
|
}
|
|
overwriteSettings(newSettings.settings);
|
|
}
|
|
reader.readAsText(file, 'UTF-8');
|
|
}
|
|
input.click();
|
|
}
|
|
|
|
function overwriteSettings(newSettings) {
|
|
initDone = false;
|
|
Object.assign(settings, newSettings);
|
|
writeStorage("bomlayout", settings.bomlayout);
|
|
writeStorage("bommode", settings.bommode);
|
|
writeStorage("canvaslayout", settings.canvaslayout);
|
|
writeStorage("bomCheckboxes", settings.checkboxes.join(","));
|
|
document.getElementById("bomCheckboxes").value = settings.checkboxes.join(",");
|
|
for (var checkbox of settings.checkboxes) {
|
|
writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
|
|
}
|
|
writeStorage("markWhenChecked", settings.markWhenChecked);
|
|
padsVisible(settings.renderPads);
|
|
document.getElementById("padsCheckbox").checked = settings.renderPads;
|
|
fabricationVisible(settings.renderFabrication);
|
|
document.getElementById("fabricationCheckbox").checked = settings.renderFabrication;
|
|
silkscreenVisible(settings.renderSilkscreen);
|
|
document.getElementById("silkscreenCheckbox").checked = settings.renderSilkscreen;
|
|
referencesVisible(settings.renderReferences);
|
|
document.getElementById("referencesCheckbox").checked = settings.renderReferences;
|
|
valuesVisible(settings.renderValues);
|
|
document.getElementById("valuesCheckbox").checked = settings.renderValues;
|
|
tracksVisible(settings.renderTracks);
|
|
document.getElementById("tracksCheckbox").checked = settings.renderTracks;
|
|
zonesVisible(settings.renderZones);
|
|
document.getElementById("zonesCheckbox").checked = settings.renderZones;
|
|
dnpOutline(settings.renderDnpOutline);
|
|
document.getElementById("dnpOutlineCheckbox").checked = settings.renderDnpOutline;
|
|
setRedrawOnDrag(settings.redrawOnDrag);
|
|
document.getElementById("dragCheckbox").checked = settings.redrawOnDrag;
|
|
setDarkMode(settings.darkMode);
|
|
document.getElementById("darkmodeCheckbox").checked = settings.darkMode;
|
|
setHighlightPin1(settings.highlightpin1);
|
|
document.getElementById("highlightpin1Checkbox").checked = settings.highlightpin1;
|
|
showFootprints(settings.show_footprints);
|
|
writeStorage("boardRotation", settings.boardRotation);
|
|
document.getElementById("boardRotation").value = settings.boardRotation / 5;
|
|
document.getElementById("rotationDegree").textContent = settings.boardRotation;
|
|
initDone = true;
|
|
prepCheckboxes();
|
|
changeBomLayout(settings.bomlayout);
|
|
}
|
|
|
|
function saveFile(filename, blob) {
|
|
var link = document.createElement("a");
|
|
var objurl = URL.createObjectURL(blob);
|
|
link.download = filename;
|
|
link.href = objurl;
|
|
link.click();
|
|
}
|
|
|
|
function dataURLtoBlob(dataurl) {
|
|
var arr = dataurl.split(','),
|
|
mime = arr[0].match(/:(.*?);/)[1],
|
|
bstr = atob(arr[1]),
|
|
n = bstr.length,
|
|
u8arr = new Uint8Array(n);
|
|
while (n--) {
|
|
u8arr[n] = bstr.charCodeAt(n);
|
|
}
|
|
return new Blob([u8arr], {
|
|
type: mime
|
|
});
|
|
}
|
|
|
|
var settings = {
|
|
canvaslayout: "default",
|
|
bomlayout: "default",
|
|
bommode: "grouped",
|
|
checkboxes: [],
|
|
checkboxStoredRefs: {},
|
|
darkMode: false,
|
|
highlightpin1: false,
|
|
redrawOnDrag: true,
|
|
boardRotation: 0,
|
|
renderPads: true,
|
|
renderReferences: true,
|
|
renderValues: true,
|
|
renderSilkscreen: true,
|
|
renderFabrication: true,
|
|
renderDnpOutline: false,
|
|
renderTracks: true,
|
|
renderZones: true,
|
|
columnOrder: [],
|
|
hiddenColumns: [],
|
|
}
|
|
|
|
function initDefaults() {
|
|
settings.bomlayout = readStorage("bomlayout");
|
|
if (settings.bomlayout === null) {
|
|
settings.bomlayout = config.bom_view;
|
|
}
|
|
if (!['bom-only', 'left-right', 'top-bottom'].includes(settings.bomlayout)) {
|
|
settings.bomlayout = config.bom_view;
|
|
}
|
|
settings.bommode = readStorage("bommode");
|
|
if (settings.bommode === null) {
|
|
settings.bommode = "grouped";
|
|
}
|
|
if (!["grouped", "ungrouped", "netlist"].includes(settings.bommode)) {
|
|
settings.bommode = "grouped";
|
|
}
|
|
settings.canvaslayout = readStorage("canvaslayout");
|
|
if (settings.canvaslayout === null) {
|
|
settings.canvaslayout = config.layer_view;
|
|
}
|
|
var bomCheckboxes = readStorage("bomCheckboxes");
|
|
if (bomCheckboxes === null) {
|
|
bomCheckboxes = config.checkboxes;
|
|
}
|
|
settings.checkboxes = bomCheckboxes.split(",").filter((e) => e);
|
|
document.getElementById("bomCheckboxes").value = bomCheckboxes;
|
|
|
|
settings.markWhenChecked = readStorage("markWhenChecked") || "";
|
|
populateMarkWhenCheckedOptions();
|
|
|
|
function initBooleanSetting(storageString, def, elementId, func) {
|
|
var b = readStorage(storageString);
|
|
if (b === null) {
|
|
b = def;
|
|
} else {
|
|
b = (b == "true");
|
|
}
|
|
document.getElementById(elementId).checked = b;
|
|
func(b);
|
|
}
|
|
|
|
initBooleanSetting("padsVisible", config.show_pads, "padsCheckbox", padsVisible);
|
|
initBooleanSetting("fabricationVisible", config.show_fabrication, "fabricationCheckbox", fabricationVisible);
|
|
initBooleanSetting("silkscreenVisible", config.show_silkscreen, "silkscreenCheckbox", silkscreenVisible);
|
|
initBooleanSetting("referencesVisible", true, "referencesCheckbox", referencesVisible);
|
|
initBooleanSetting("valuesVisible", true, "valuesCheckbox", valuesVisible);
|
|
if ("tracks" in pcbdata) {
|
|
initBooleanSetting("tracksVisible", true, "tracksCheckbox", tracksVisible);
|
|
initBooleanSetting("zonesVisible", true, "zonesCheckbox", zonesVisible);
|
|
} else {
|
|
document.getElementById("tracksAndZonesCheckboxes").style.display = "none";
|
|
tracksVisible(false);
|
|
zonesVisible(false);
|
|
}
|
|
initBooleanSetting("dnpOutline", false, "dnpOutlineCheckbox", dnpOutline);
|
|
initBooleanSetting("redrawOnDrag", config.redraw_on_drag, "dragCheckbox", setRedrawOnDrag);
|
|
initBooleanSetting("darkmode", config.dark_mode, "darkmodeCheckbox", setDarkMode);
|
|
initBooleanSetting("highlightpin1", config.highlight_pin1, "highlightpin1Checkbox", setHighlightPin1);
|
|
|
|
var fields = ["checkboxes", "References"].concat(config.fields).concat(["Quantity"]);
|
|
var hcols = JSON.parse(readStorage("hiddenColumns"));
|
|
if (hcols === null) {
|
|
hcols = [];
|
|
}
|
|
settings.hiddenColumns = hcols.filter(e => fields.includes(e));
|
|
|
|
var cord = JSON.parse(readStorage("columnOrder"));
|
|
if (cord === null) {
|
|
cord = fields;
|
|
} else {
|
|
cord = cord.filter(e => fields.includes(e));
|
|
if (cord.length != fields.length)
|
|
cord = fields;
|
|
}
|
|
settings.columnOrder = cord;
|
|
|
|
settings.boardRotation = readStorage("boardRotation");
|
|
if (settings.boardRotation === null) {
|
|
settings.boardRotation = config.board_rotation * 5;
|
|
} else {
|
|
settings.boardRotation = parseInt(settings.boardRotation);
|
|
}
|
|
document.getElementById("boardRotation").value = settings.boardRotation / 5;
|
|
document.getElementById("rotationDegree").textContent = settings.boardRotation;
|
|
}
|
|
|
|
// Helper classes for user js callbacks.
|
|
|
|
const IBOM_EVENT_TYPES = {
|
|
ALL: "all",
|
|
HIGHLIGHT_EVENT: "highlightEvent",
|
|
CHECKBOX_CHANGE_EVENT: "checkboxChangeEvent",
|
|
BOM_BODY_CHANGE_EVENT: "bomBodyChangeEvent",
|
|
}
|
|
|
|
const EventHandler = {
|
|
callbacks: {},
|
|
init: function() {
|
|
for (eventType of Object.values(IBOM_EVENT_TYPES))
|
|
this.callbacks[eventType] = [];
|
|
},
|
|
registerCallback: function(eventType, callback) {
|
|
this.callbacks[eventType].push(callback);
|
|
},
|
|
emitEvent: function(eventType, eventArgs) {
|
|
event = {
|
|
eventType: eventType,
|
|
args: eventArgs,
|
|
}
|
|
var callback;
|
|
for (callback of this.callbacks[eventType])
|
|
callback(event);
|
|
for (callback of this.callbacks[IBOM_EVENT_TYPES.ALL])
|
|
callback(event);
|
|
}
|
|
}
|
|
EventHandler.init();
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/* PCB rendering code */
|
|
|
|
var emptyContext2d = document.createElement("canvas").getContext("2d");
|
|
|
|
function deg2rad(deg) {
|
|
return deg * Math.PI / 180;
|
|
}
|
|
|
|
function calcFontPoint(linepoint, text, offsetx, offsety, tilt) {
|
|
var point = [
|
|
linepoint[0] * text.width + offsetx,
|
|
linepoint[1] * text.height + offsety
|
|
];
|
|
// This approximates pcbnew behavior with how text tilts depending on horizontal justification
|
|
point[0] -= (linepoint[1] + 0.5 * (1 + text.justify[0])) * text.height * tilt;
|
|
return point;
|
|
}
|
|
|
|
function drawText(ctx, text, color) {
|
|
if ("ref" in text && !settings.renderReferences) return;
|
|
if ("val" in text && !settings.renderValues) return;
|
|
ctx.save();
|
|
ctx.fillStyle = color;
|
|
ctx.strokeStyle = color;
|
|
ctx.lineCap = "round";
|
|
ctx.lineJoin = "round";
|
|
ctx.lineWidth = text.thickness;
|
|
if ("svgpath" in text) {
|
|
ctx.stroke(new Path2D(text.svgpath));
|
|
ctx.restore();
|
|
return;
|
|
}
|
|
ctx.translate(...text.pos);
|
|
ctx.translate(text.thickness * 0.5, 0);
|
|
var angle = -text.angle;
|
|
if (text.attr.includes("mirrored")) {
|
|
ctx.scale(-1, 1);
|
|
angle = -angle;
|
|
}
|
|
var tilt = 0;
|
|
if (text.attr.includes("italic")) {
|
|
tilt = 0.125;
|
|
}
|
|
var interline = text.height * 1.5 + text.thickness;
|
|
var txt = text.text.split("\n");
|
|
// KiCad ignores last empty line.
|
|
if (txt[txt.length - 1] == '') txt.pop();
|
|
ctx.rotate(deg2rad(angle));
|
|
var offsety = (1 - text.justify[1]) / 2 * text.height; // One line offset
|
|
offsety -= (txt.length - 1) * (text.justify[1] + 1) / 2 * interline; // Multiline offset
|
|
for (var i in txt) {
|
|
var lineWidth = text.thickness + interline / 2 * tilt;
|
|
for (var j = 0; j < txt[i].length; j++) {
|
|
if (txt[i][j] == '\t') {
|
|
var fourSpaces = 4 * pcbdata.font_data[' '].w * text.width;
|
|
lineWidth += fourSpaces - lineWidth % fourSpaces;
|
|
} else {
|
|
if (txt[i][j] == '~') {
|
|
j++;
|
|
if (j == txt[i].length)
|
|
break;
|
|
}
|
|
lineWidth += pcbdata.font_data[txt[i][j]].w * text.width;
|
|
}
|
|
}
|
|
var offsetx = -lineWidth * (text.justify[0] + 1) / 2;
|
|
var inOverbar = false;
|
|
for (var j = 0; j < txt[i].length; j++) {
|
|
if (txt[i][j] == '\t') {
|
|
var fourSpaces = 4 * pcbdata.font_data[' '].w * text.width;
|
|
offsetx += fourSpaces - offsetx % fourSpaces;
|
|
continue;
|
|
} else if (txt[i][j] == '~') {
|
|
j++;
|
|
if (j == txt[i].length)
|
|
break;
|
|
if (txt[i][j] != '~') {
|
|
inOverbar = !inOverbar;
|
|
}
|
|
}
|
|
var glyph = pcbdata.font_data[txt[i][j]];
|
|
if (inOverbar) {
|
|
var overbarStart = [offsetx, -text.height * 1.4 + offsety];
|
|
var overbarEnd = [offsetx + text.width * glyph.w, overbarStart[1]];
|
|
|
|
if (!lastHadOverbar) {
|
|
overbarStart[0] += text.height * 1.4 * tilt;
|
|
lastHadOverbar = true;
|
|
}
|
|
ctx.beginPath();
|
|
ctx.moveTo(...overbarStart);
|
|
ctx.lineTo(...overbarEnd);
|
|
ctx.stroke();
|
|
} else {
|
|
lastHadOverbar = false;
|
|
}
|
|
for (var line of glyph.l) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(...calcFontPoint(line[0], text, offsetx, offsety, tilt));
|
|
for (var k = 1; k < line.length; k++) {
|
|
ctx.lineTo(...calcFontPoint(line[k], text, offsetx, offsety, tilt));
|
|
}
|
|
ctx.stroke();
|
|
}
|
|
offsetx += glyph.w * text.width;
|
|
}
|
|
offsety += interline;
|
|
}
|
|
ctx.restore();
|
|
}
|
|
|
|
function drawedge(ctx, scalefactor, edge, color) {
|
|
ctx.strokeStyle = color;
|
|
ctx.fillStyle = color;
|
|
ctx.lineWidth = Math.max(1 / scalefactor, edge.width);
|
|
ctx.lineCap = "round";
|
|
ctx.lineJoin = "round";
|
|
if ("svgpath" in edge) {
|
|
ctx.stroke(new Path2D(edge.svgpath));
|
|
} else {
|
|
ctx.beginPath();
|
|
if (edge.type == "segment") {
|
|
ctx.moveTo(...edge.start);
|
|
ctx.lineTo(...edge.end);
|
|
}
|
|
if (edge.type == "rect") {
|
|
ctx.moveTo(...edge.start);
|
|
ctx.lineTo(edge.start[0], edge.end[1]);
|
|
ctx.lineTo(...edge.end);
|
|
ctx.lineTo(edge.end[0], edge.start[1]);
|
|
ctx.lineTo(...edge.start);
|
|
}
|
|
if (edge.type == "arc") {
|
|
ctx.arc(
|
|
...edge.start,
|
|
edge.radius,
|
|
deg2rad(edge.startangle),
|
|
deg2rad(edge.endangle));
|
|
}
|
|
if (edge.type == "circle") {
|
|
ctx.arc(
|
|
...edge.start,
|
|
edge.radius,
|
|
0, 2 * Math.PI);
|
|
ctx.closePath();
|
|
}
|
|
if (edge.type == "curve") {
|
|
ctx.moveTo(...edge.start);
|
|
ctx.bezierCurveTo(...edge.cpa, ...edge.cpb, ...edge.end);
|
|
}
|
|
if("filled" in edge && edge.filled)
|
|
ctx.fill();
|
|
else
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
|
|
function getChamferedRectPath(size, radius, chamfpos, chamfratio) {
|
|
// chamfpos is a bitmask, left = 1, right = 2, bottom left = 4, bottom right = 8
|
|
var path = new Path2D();
|
|
var width = size[0];
|
|
var height = size[1];
|
|
var x = width * -0.5;
|
|
var y = height * -0.5;
|
|
var chamfOffset = Math.min(width, height) * chamfratio;
|
|
path.moveTo(x, 0);
|
|
if (chamfpos & 4) {
|
|
path.lineTo(x, y + height - chamfOffset);
|
|
path.lineTo(x + chamfOffset, y + height);
|
|
path.lineTo(0, y + height);
|
|
} else {
|
|
path.arcTo(x, y + height, x + width, y + height, radius);
|
|
}
|
|
if (chamfpos & 8) {
|
|
path.lineTo(x + width - chamfOffset, y + height);
|
|
path.lineTo(x + width, y + height - chamfOffset);
|
|
path.lineTo(x + width, 0);
|
|
} else {
|
|
path.arcTo(x + width, y + height, x + width, y, radius);
|
|
}
|
|
if (chamfpos & 2) {
|
|
path.lineTo(x + width, y + chamfOffset);
|
|
path.lineTo(x + width - chamfOffset, y);
|
|
path.lineTo(0, y);
|
|
} else {
|
|
path.arcTo(x + width, y, x, y, radius);
|
|
}
|
|
if (chamfpos & 1) {
|
|
path.lineTo(x + chamfOffset, y);
|
|
path.lineTo(x, y + chamfOffset);
|
|
path.lineTo(x, 0);
|
|
} else {
|
|
path.arcTo(x, y, x, y + height, radius);
|
|
}
|
|
path.closePath();
|
|
return path;
|
|
}
|
|
|
|
function getOblongPath(size) {
|
|
return getChamferedRectPath(size, Math.min(size[0], size[1]) / 2, 0, 0);
|
|
}
|
|
|
|
function getPolygonsPath(shape) {
|
|
if (shape.path2d) {
|
|
return shape.path2d;
|
|
}
|
|
if ("svgpath" in shape) {
|
|
shape.path2d = new Path2D(shape.svgpath);
|
|
} else {
|
|
var path = new Path2D();
|
|
for (var polygon of shape.polygons) {
|
|
path.moveTo(...polygon[0]);
|
|
for (var i = 1; i < polygon.length; i++) {
|
|
path.lineTo(...polygon[i]);
|
|
}
|
|
path.closePath();
|
|
}
|
|
shape.path2d = path;
|
|
}
|
|
return shape.path2d;
|
|
}
|
|
|
|
function drawPolygonShape(ctx, scalefactor, shape, color) {
|
|
ctx.save();
|
|
if (!("svgpath" in shape)) {
|
|
ctx.translate(...shape.pos);
|
|
ctx.rotate(deg2rad(-shape.angle));
|
|
}
|
|
if("filled" in shape && !shape.filled) {
|
|
ctx.strokeStyle = color;
|
|
ctx.lineWidth = Math.max(1 / scalefactor, shape.width);
|
|
ctx.lineCap = "round";
|
|
ctx.lineJoin = "round";
|
|
ctx.stroke(getPolygonsPath(shape));
|
|
} else {
|
|
ctx.fillStyle = color;
|
|
ctx.fill(getPolygonsPath(shape));
|
|
}
|
|
ctx.restore();
|
|
}
|
|
|
|
function drawDrawing(ctx, scalefactor, drawing, color) {
|
|
if (["segment", "arc", "circle", "curve", "rect"].includes(drawing.type)) {
|
|
drawedge(ctx, scalefactor, drawing, color);
|
|
} else if (drawing.type == "polygon") {
|
|
drawPolygonShape(ctx, scalefactor, drawing, color);
|
|
} else {
|
|
drawText(ctx, drawing, color);
|
|
}
|
|
}
|
|
|
|
function getCirclePath(radius) {
|
|
var path = new Path2D();
|
|
path.arc(0, 0, radius, 0, 2 * Math.PI);
|
|
path.closePath();
|
|
return path;
|
|
}
|
|
|
|
function getCachedPadPath(pad) {
|
|
if (!pad.path2d) {
|
|
// if path2d is not set, build one and cache it on pad object
|
|
if (pad.shape == "rect") {
|
|
pad.path2d = new Path2D();
|
|
pad.path2d.rect(...pad.size.map(c => -c * 0.5), ...pad.size);
|
|
} else if (pad.shape == "oval") {
|
|
pad.path2d = getOblongPath(pad.size);
|
|
} else if (pad.shape == "circle") {
|
|
pad.path2d = getCirclePath(pad.size[0] / 2);
|
|
} else if (pad.shape == "roundrect") {
|
|
pad.path2d = getChamferedRectPath(pad.size, pad.radius, 0, 0);
|
|
} else if (pad.shape == "chamfrect") {
|
|
pad.path2d = getChamferedRectPath(pad.size, pad.radius, pad.chamfpos, pad.chamfratio)
|
|
} else if (pad.shape == "custom") {
|
|
pad.path2d = getPolygonsPath(pad);
|
|
}
|
|
}
|
|
return pad.path2d;
|
|
}
|
|
|
|
function drawPad(ctx, pad, color, outline) {
|
|
ctx.save();
|
|
ctx.translate(...pad.pos);
|
|
ctx.rotate(deg2rad(pad.angle));
|
|
if (pad.offset) {
|
|
ctx.translate(...pad.offset);
|
|
}
|
|
ctx.fillStyle = color;
|
|
ctx.strokeStyle = color;
|
|
var path = getCachedPadPath(pad);
|
|
if (outline) {
|
|
ctx.stroke(path);
|
|
} else {
|
|
ctx.fill(path);
|
|
}
|
|
ctx.restore();
|
|
}
|
|
|
|
function drawPadHole(ctx, pad, padHoleColor) {
|
|
if (pad.type != "th") return;
|
|
ctx.save();
|
|
ctx.translate(...pad.pos);
|
|
ctx.rotate(deg2rad(pad.angle));
|
|
ctx.fillStyle = padHoleColor;
|
|
if (pad.drillshape == "oblong") {
|
|
ctx.fill(getOblongPath(pad.drillsize));
|
|
} else {
|
|
ctx.fill(getCirclePath(pad.drillsize[0] / 2));
|
|
}
|
|
ctx.restore();
|
|
}
|
|
|
|
function drawFootprint(ctx, layer, scalefactor, footprint, colors, highlight, outline) {
|
|
if (highlight) {
|
|
// draw bounding box
|
|
if (footprint.layer == layer) {
|
|
ctx.save();
|
|
ctx.globalAlpha = 0.2;
|
|
ctx.translate(...footprint.bbox.pos);
|
|
ctx.rotate(deg2rad(-footprint.bbox.angle));
|
|
ctx.translate(...footprint.bbox.relpos);
|
|
ctx.fillStyle = colors.pad;
|
|
ctx.fillRect(0, 0, ...footprint.bbox.size);
|
|
ctx.globalAlpha = 1;
|
|
ctx.strokeStyle = colors.pad;
|
|
ctx.strokeRect(0, 0, ...footprint.bbox.size);
|
|
ctx.restore();
|
|
}
|
|
}
|
|
// draw drawings
|
|
for (var drawing of footprint.drawings) {
|
|
if (drawing.layer == layer) {
|
|
drawDrawing(ctx, scalefactor, drawing.drawing, colors.pad);
|
|
}
|
|
}
|
|
// draw pads
|
|
if (settings.renderPads) {
|
|
for (var pad of footprint.pads) {
|
|
if (pad.layers.includes(layer)) {
|
|
drawPad(ctx, pad, colors.pad, outline);
|
|
if (pad.pin1 && settings.highlightpin1) {
|
|
drawPad(ctx, pad, colors.outline, true);
|
|
}
|
|
}
|
|
}
|
|
for (var pad of footprint.pads) {
|
|
drawPadHole(ctx, pad, colors.padHole);
|
|
}
|
|
}
|
|
}
|
|
|
|
function drawEdgeCuts(canvas, scalefactor) {
|
|
var ctx = canvas.getContext("2d");
|
|
var edgecolor = getComputedStyle(topmostdiv).getPropertyValue('--pcb-edge-color');
|
|
for (var edge of pcbdata.edges) {
|
|
drawDrawing(ctx, scalefactor, edge, edgecolor);
|
|
}
|
|
}
|
|
|
|
function drawFootprints(canvas, layer, scalefactor, highlight) {
|
|
var ctx = canvas.getContext("2d");
|
|
ctx.lineWidth = 3 / scalefactor;
|
|
var style = getComputedStyle(topmostdiv);
|
|
|
|
var colors = {
|
|
pad: style.getPropertyValue('--pad-color'),
|
|
padHole: style.getPropertyValue('--pad-hole-color'),
|
|
outline: style.getPropertyValue('--pin1-outline-color'),
|
|
}
|
|
|
|
for (var i = 0; i < pcbdata.footprints.length; i++) {
|
|
var mod = pcbdata.footprints[i];
|
|
var outline = settings.renderDnpOutline && pcbdata.bom.skipped.includes(i);
|
|
var h = highlightedFootprints.includes(i);
|
|
var d = markedFootprints.has(i);
|
|
if (highlight) {
|
|
if(h && d) {
|
|
colors.pad = style.getPropertyValue('--pad-color-highlight-both');
|
|
colors.outline = style.getPropertyValue('--pin1-outline-color-highlight-both');
|
|
} else if (h) {
|
|
colors.pad = style.getPropertyValue('--pad-color-highlight');
|
|
colors.outline = style.getPropertyValue('--pin1-outline-color-highlight');
|
|
} else if (d) {
|
|
colors.pad = style.getPropertyValue('--pad-color-highlight-marked');
|
|
colors.outline = style.getPropertyValue('--pin1-outline-color-highlight-marked');
|
|
}
|
|
}
|
|
if( h || d || !highlight) {
|
|
drawFootprint(ctx, layer, scalefactor, mod, colors, highlight, outline);
|
|
}
|
|
}
|
|
}
|
|
|
|
function drawBgLayer(layername, canvas, layer, scalefactor, edgeColor, polygonColor, textColor) {
|
|
var ctx = canvas.getContext("2d");
|
|
for (var d of pcbdata.drawings[layername][layer]) {
|
|
if (["segment", "arc", "circle", "curve", "rect"].includes(d.type)) {
|
|
drawedge(ctx, scalefactor, d, edgeColor);
|
|
} else if (d.type == "polygon") {
|
|
drawPolygonShape(ctx, scalefactor, d, polygonColor);
|
|
} else {
|
|
drawText(ctx, d, textColor);
|
|
}
|
|
}
|
|
}
|
|
|
|
function drawTracks(canvas, layer, color, highlight) {
|
|
ctx = canvas.getContext("2d");
|
|
ctx.strokeStyle = color;
|
|
ctx.lineCap = "round";
|
|
for (var track of pcbdata.tracks[layer]) {
|
|
if (highlight && highlightedNet != track.net) continue;
|
|
ctx.lineWidth = track.width;
|
|
ctx.beginPath();
|
|
if ('radius' in track) {
|
|
ctx.arc(
|
|
...track.center,
|
|
track.radius,
|
|
deg2rad(track.startangle),
|
|
deg2rad(track.endangle));
|
|
} else {
|
|
ctx.moveTo(...track.start);
|
|
ctx.lineTo(...track.end);
|
|
}
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
|
|
function drawZones(canvas, layer, color, highlight) {
|
|
ctx = canvas.getContext("2d");
|
|
ctx.strokeStyle = color;
|
|
ctx.fillStyle = color;
|
|
ctx.lineJoin = "round";
|
|
for (var zone of pcbdata.zones[layer]) {
|
|
if (!zone.path2d) {
|
|
zone.path2d = getPolygonsPath(zone);
|
|
}
|
|
if (highlight && highlightedNet != zone.net) continue;
|
|
ctx.fill(zone.path2d);
|
|
if (zone.width > 0) {
|
|
ctx.lineWidth = zone.width;
|
|
ctx.stroke(zone.path2d);
|
|
}
|
|
}
|
|
}
|
|
|
|
function clearCanvas(canvas, color = null) {
|
|
var ctx = canvas.getContext("2d");
|
|
ctx.save();
|
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
if (color) {
|
|
ctx.fillStyle = color;
|
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
|
} else {
|
|
if (!window.matchMedia("print").matches)
|
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
}
|
|
ctx.restore();
|
|
}
|
|
|
|
function drawNets(canvas, layer, highlight) {
|
|
var style = getComputedStyle(topmostdiv);
|
|
if (settings.renderTracks) {
|
|
var trackColor = style.getPropertyValue(highlight ? '--track-color-highlight' : '--track-color');
|
|
drawTracks(canvas, layer, trackColor, highlight);
|
|
}
|
|
if (settings.renderZones) {
|
|
var zoneColor = style.getPropertyValue(highlight ? '--zone-color-highlight' : '--zone-color');
|
|
drawZones(canvas, layer, zoneColor, highlight);
|
|
}
|
|
if (highlight && settings.renderPads) {
|
|
var padColor = style.getPropertyValue('--pad-color-highlight');
|
|
var padHoleColor = style.getPropertyValue('--pad-hole-color');
|
|
var ctx = canvas.getContext("2d");
|
|
for (var footprint of pcbdata.footprints) {
|
|
// draw pads
|
|
var padDrawn = false;
|
|
for (var pad of footprint.pads) {
|
|
if (highlightedNet != pad.net) continue;
|
|
if (pad.layers.includes(layer)) {
|
|
drawPad(ctx, pad, padColor, false);
|
|
padDrawn = true;
|
|
}
|
|
}
|
|
if (padDrawn) {
|
|
// redraw all pad holes because some pads may overlap
|
|
for (var pad of footprint.pads) {
|
|
drawPadHole(ctx, pad, padHoleColor);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function drawHighlightsOnLayer(canvasdict, clear = true) {
|
|
if (clear) {
|
|
clearCanvas(canvasdict.highlight);
|
|
}
|
|
if (markedFootprints.size > 0 || highlightedFootprints.length > 0) {
|
|
drawFootprints(canvasdict.highlight, canvasdict.layer,
|
|
canvasdict.transform.s * canvasdict.transform.zoom, true);
|
|
}
|
|
if (highlightedNet !== null) {
|
|
drawNets(canvasdict.highlight, canvasdict.layer, true);
|
|
}
|
|
}
|
|
|
|
function drawHighlights() {
|
|
drawHighlightsOnLayer(allcanvas.front);
|
|
drawHighlightsOnLayer(allcanvas.back);
|
|
}
|
|
|
|
function drawBackground(canvasdict, clear = true) {
|
|
if (clear) {
|
|
clearCanvas(canvasdict.bg);
|
|
clearCanvas(canvasdict.fab);
|
|
clearCanvas(canvasdict.silk);
|
|
}
|
|
|
|
drawNets(canvasdict.bg, canvasdict.layer, false);
|
|
drawFootprints(canvasdict.bg, canvasdict.layer,
|
|
canvasdict.transform.s * canvasdict.transform.zoom, false);
|
|
|
|
drawEdgeCuts(canvasdict.bg, canvasdict.transform.s * canvasdict.transform.zoom);
|
|
|
|
var style = getComputedStyle(topmostdiv);
|
|
var edgeColor = style.getPropertyValue('--silkscreen-edge-color');
|
|
var polygonColor = style.getPropertyValue('--silkscreen-polygon-color');
|
|
var textColor = style.getPropertyValue('--silkscreen-text-color');
|
|
if (settings.renderSilkscreen) {
|
|
drawBgLayer(
|
|
"silkscreen", canvasdict.silk, canvasdict.layer,
|
|
canvasdict.transform.s * canvasdict.transform.zoom,
|
|
edgeColor, polygonColor, textColor);
|
|
}
|
|
edgeColor = style.getPropertyValue('--fabrication-edge-color');
|
|
polygonColor = style.getPropertyValue('--fabrication-polygon-color');
|
|
textColor = style.getPropertyValue('--fabrication-text-color');
|
|
if (settings.renderFabrication) {
|
|
drawBgLayer(
|
|
"fabrication", canvasdict.fab, canvasdict.layer,
|
|
canvasdict.transform.s * canvasdict.transform.zoom,
|
|
edgeColor, polygonColor, textColor);
|
|
}
|
|
}
|
|
|
|
function prepareCanvas(canvas, flip, transform) {
|
|
var ctx = canvas.getContext("2d");
|
|
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
var fontsize = 1.55;
|
|
ctx.scale(transform.zoom, transform.zoom);
|
|
ctx.translate(transform.panx, transform.pany);
|
|
if (flip) {
|
|
ctx.scale(-1, 1);
|
|
}
|
|
ctx.translate(transform.x, transform.y);
|
|
ctx.rotate(deg2rad(settings.boardRotation));
|
|
ctx.scale(transform.s, transform.s);
|
|
}
|
|
|
|
function prepareLayer(canvasdict) {
|
|
var flip = (canvasdict.layer == "B");
|
|
for (var c of ["bg", "fab", "silk", "highlight"]) {
|
|
prepareCanvas(canvasdict[c], flip, canvasdict.transform);
|
|
}
|
|
}
|
|
|
|
function rotateVector(v, angle) {
|
|
angle = deg2rad(angle);
|
|
return [
|
|
v[0] * Math.cos(angle) - v[1] * Math.sin(angle),
|
|
v[0] * Math.sin(angle) + v[1] * Math.cos(angle)
|
|
];
|
|
}
|
|
|
|
function applyRotation(bbox) {
|
|
var corners = [
|
|
[bbox.minx, bbox.miny],
|
|
[bbox.minx, bbox.maxy],
|
|
[bbox.maxx, bbox.miny],
|
|
[bbox.maxx, bbox.maxy],
|
|
];
|
|
corners = corners.map((v) => rotateVector(v, settings.boardRotation));
|
|
return {
|
|
minx: corners.reduce((a, v) => Math.min(a, v[0]), Infinity),
|
|
miny: corners.reduce((a, v) => Math.min(a, v[1]), Infinity),
|
|
maxx: corners.reduce((a, v) => Math.max(a, v[0]), -Infinity),
|
|
maxy: corners.reduce((a, v) => Math.max(a, v[1]), -Infinity),
|
|
}
|
|
}
|
|
|
|
function recalcLayerScale(layerdict, width, height) {
|
|
var bbox = applyRotation(pcbdata.edges_bbox);
|
|
var scalefactor = 0.98 * Math.min(
|
|
width / (bbox.maxx - bbox.minx),
|
|
height / (bbox.maxy - bbox.miny)
|
|
);
|
|
if (scalefactor < 0.1) {
|
|
scalefactor = 1;
|
|
}
|
|
layerdict.transform.s = scalefactor;
|
|
var flip = (layerdict.layer == "B");
|
|
if (flip) {
|
|
layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor + width) * 0.5;
|
|
} else {
|
|
layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor - width) * 0.5;
|
|
}
|
|
layerdict.transform.y = -((bbox.maxy + bbox.miny) * scalefactor - height) * 0.5;
|
|
for (var c of ["bg", "fab", "silk", "highlight"]) {
|
|
canvas = layerdict[c];
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
canvas.style.width = (width / devicePixelRatio) + "px";
|
|
canvas.style.height = (height / devicePixelRatio) + "px";
|
|
}
|
|
}
|
|
|
|
function redrawCanvas(layerdict) {
|
|
prepareLayer(layerdict);
|
|
drawBackground(layerdict);
|
|
drawHighlightsOnLayer(layerdict);
|
|
}
|
|
|
|
function resizeCanvas(layerdict) {
|
|
var canvasdivid = {
|
|
"F": "frontcanvas",
|
|
"B": "backcanvas"
|
|
} [layerdict.layer];
|
|
var width = document.getElementById(canvasdivid).clientWidth * devicePixelRatio;
|
|
var height = document.getElementById(canvasdivid).clientHeight * devicePixelRatio;
|
|
recalcLayerScale(layerdict, width, height);
|
|
redrawCanvas(layerdict);
|
|
}
|
|
|
|
function resizeAll() {
|
|
resizeCanvas(allcanvas.front);
|
|
resizeCanvas(allcanvas.back);
|
|
}
|
|
|
|
function pointWithinDistanceToSegment(x, y, x1, y1, x2, y2, d) {
|
|
var A = x - x1;
|
|
var B = y - y1;
|
|
var C = x2 - x1;
|
|
var D = y2 - y1;
|
|
|
|
var dot = A * C + B * D;
|
|
var len_sq = C * C + D * D;
|
|
var dx, dy;
|
|
if (len_sq == 0) {
|
|
// start and end of the segment coincide
|
|
dx = x - x1;
|
|
dy = y - y1;
|
|
} else {
|
|
var param = dot / len_sq;
|
|
var xx, yy;
|
|
if (param < 0) {
|
|
xx = x1;
|
|
yy = y1;
|
|
} else if (param > 1) {
|
|
xx = x2;
|
|
yy = y2;
|
|
} else {
|
|
xx = x1 + param * C;
|
|
yy = y1 + param * D;
|
|
}
|
|
dx = x - xx;
|
|
dy = y - yy;
|
|
}
|
|
return dx * dx + dy * dy <= d * d;
|
|
}
|
|
|
|
function modulo(n, mod) {
|
|
return ((n % mod) + mod) % mod;
|
|
}
|
|
|
|
function pointWithinDistanceToArc(x, y, xc, yc, radius, startangle, endangle, d) {
|
|
var dx = x - xc;
|
|
var dy = y - yc;
|
|
var r_sq = dx * dx + dy * dy;
|
|
var rmin = Math.max(0, radius - d);
|
|
var rmax = radius + d;
|
|
|
|
if (r_sq < rmin * rmin || r_sq > rmax * rmax)
|
|
return false;
|
|
|
|
var angle1 = modulo(deg2rad(startangle), 2 * Math.PI);
|
|
var dx1 = xc + radius * Math.cos(angle1) - x;
|
|
var dy1 = yc + radius * Math.sin(angle1) - y;
|
|
if (dx1 * dx1 + dy1 * dy1 <= d * d)
|
|
return true;
|
|
|
|
var angle2 = modulo(deg2rad(endangle), 2 * Math.PI);
|
|
var dx2 = xc + radius * Math.cos(angle2) - x;
|
|
var dy2 = yc + radius * Math.sin(angle2) - y;
|
|
if (dx2 * dx2 + dy2 * dy2 <= d * d)
|
|
return true;
|
|
|
|
var angle = modulo(Math.atan2(dy, dx), 2 * Math.PI);
|
|
if (angle1 > angle2)
|
|
return (angle >= angle2 || angle <= angle1);
|
|
else
|
|
return (angle >= angle1 && angle <= angle2);
|
|
}
|
|
|
|
function pointWithinPad(x, y, pad) {
|
|
var v = [x - pad.pos[0], y - pad.pos[1]];
|
|
v = rotateVector(v, -pad.angle);
|
|
if (pad.offset) {
|
|
v[0] -= pad.offset[0];
|
|
v[1] -= pad.offset[1];
|
|
}
|
|
return emptyContext2d.isPointInPath(getCachedPadPath(pad), ...v);
|
|
}
|
|
|
|
function netHitScan(layer, x, y) {
|
|
// Check track segments
|
|
if (settings.renderTracks && pcbdata.tracks) {
|
|
for (var track of pcbdata.tracks[layer]) {
|
|
if ('radius' in track) {
|
|
if (pointWithinDistanceToArc(x, y, ...track.center, track.radius, track.startangle, track.endangle, track.width / 2)) {
|
|
return track.net;
|
|
}
|
|
} else {
|
|
if (pointWithinDistanceToSegment(x, y, ...track.start, ...track.end, track.width / 2)) {
|
|
return track.net;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Check pads
|
|
if (settings.renderPads) {
|
|
for (var footprint of pcbdata.footprints) {
|
|
for (var pad of footprint.pads) {
|
|
if (pad.layers.includes(layer) && pointWithinPad(x, y, pad)) {
|
|
return pad.net;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function pointWithinFootprintBbox(x, y, bbox) {
|
|
var v = [x - bbox.pos[0], y - bbox.pos[1]];
|
|
v = rotateVector(v, bbox.angle);
|
|
return bbox.relpos[0] <= v[0] && v[0] <= bbox.relpos[0] + bbox.size[0] &&
|
|
bbox.relpos[1] <= v[1] && v[1] <= bbox.relpos[1] + bbox.size[1];
|
|
}
|
|
|
|
function bboxHitScan(layer, x, y) {
|
|
var result = [];
|
|
for (var i = 0; i < pcbdata.footprints.length; i++) {
|
|
var footprint = pcbdata.footprints[i];
|
|
if (footprint.layer == layer) {
|
|
if (pointWithinFootprintBbox(x, y, footprint.bbox)) {
|
|
result.push(i);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function handlePointerDown(e, layerdict) {
|
|
if (e.button != 0 && e.button != 1) {
|
|
return;
|
|
}
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
if (!e.hasOwnProperty("offsetX")) {
|
|
// The polyfill doesn't set this properly
|
|
e.offsetX = e.pageX - e.currentTarget.offsetLeft;
|
|
e.offsetY = e.pageY - e.currentTarget.offsetTop;
|
|
}
|
|
|
|
layerdict.pointerStates[e.pointerId] = {
|
|
distanceTravelled: 0,
|
|
lastX: e.offsetX,
|
|
lastY: e.offsetY,
|
|
downTime: Date.now(),
|
|
};
|
|
}
|
|
|
|
function handleMouseClick(e, layerdict) {
|
|
if (!e.hasOwnProperty("offsetX")) {
|
|
// The polyfill doesn't set this properly
|
|
e.offsetX = e.pageX - e.currentTarget.offsetLeft;
|
|
e.offsetY = e.pageY - e.currentTarget.offsetTop;
|
|
}
|
|
|
|
var x = e.offsetX;
|
|
var y = e.offsetY;
|
|
var t = layerdict.transform;
|
|
if (layerdict.layer == "B") {
|
|
x = (devicePixelRatio * x / t.zoom - t.panx + t.x) / -t.s;
|
|
} else {
|
|
x = (devicePixelRatio * x / t.zoom - t.panx - t.x) / t.s;
|
|
}
|
|
y = (devicePixelRatio * y / t.zoom - t.y - t.pany) / t.s;
|
|
var v = rotateVector([x, y], -settings.boardRotation);
|
|
if ("nets" in pcbdata) {
|
|
var net = netHitScan(layerdict.layer, ...v);
|
|
if (net !== highlightedNet) {
|
|
netClicked(net);
|
|
}
|
|
}
|
|
if (highlightedNet === null) {
|
|
var footprints = bboxHitScan(layerdict.layer, ...v);
|
|
if (footprints.length > 0) {
|
|
footprintsClicked(footprints);
|
|
}
|
|
}
|
|
}
|
|
|
|
function handlePointerLeave(e, layerdict) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
if (!settings.redrawOnDrag) {
|
|
redrawCanvas(layerdict);
|
|
}
|
|
|
|
delete layerdict.pointerStates[e.pointerId];
|
|
}
|
|
|
|
function resetTransform(layerdict) {
|
|
layerdict.transform.panx = 0;
|
|
layerdict.transform.pany = 0;
|
|
layerdict.transform.zoom = 1;
|
|
redrawCanvas(layerdict);
|
|
}
|
|
|
|
function handlePointerUp(e, layerdict) {
|
|
if (!e.hasOwnProperty("offsetX")) {
|
|
// The polyfill doesn't set this properly
|
|
e.offsetX = e.pageX - e.currentTarget.offsetLeft;
|
|
e.offsetY = e.pageY - e.currentTarget.offsetTop;
|
|
}
|
|
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
if (e.button == 2) {
|
|
// Reset pan and zoom on right click.
|
|
resetTransform(layerdict);
|
|
layerdict.anotherPointerTapped = false;
|
|
return;
|
|
}
|
|
|
|
// We haven't necessarily had a pointermove event since the interaction started, so make sure we update this now
|
|
var ptr = layerdict.pointerStates[e.pointerId];
|
|
ptr.distanceTravelled += Math.abs(e.offsetX - ptr.lastX) + Math.abs(e.offsetY - ptr.lastY);
|
|
|
|
if (e.button == 0 && ptr.distanceTravelled < 10 && Date.now() - ptr.downTime <= 500) {
|
|
if (Object.keys(layerdict.pointerStates).length == 1) {
|
|
if (layerdict.anotherPointerTapped) {
|
|
// This is the second pointer coming off of a two-finger tap
|
|
resetTransform(layerdict);
|
|
} else {
|
|
// This is just a regular tap
|
|
handleMouseClick(e, layerdict);
|
|
}
|
|
layerdict.anotherPointerTapped = false;
|
|
} else {
|
|
// This is the first finger coming off of what could become a two-finger tap
|
|
layerdict.anotherPointerTapped = true;
|
|
}
|
|
} else {
|
|
if (!settings.redrawOnDrag) {
|
|
redrawCanvas(layerdict);
|
|
}
|
|
layerdict.anotherPointerTapped = false;
|
|
}
|
|
|
|
delete layerdict.pointerStates[e.pointerId];
|
|
}
|
|
|
|
function handlePointerMove(e, layerdict) {
|
|
if (!layerdict.pointerStates.hasOwnProperty(e.pointerId)) {
|
|
return;
|
|
}
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
if (!e.hasOwnProperty("offsetX")) {
|
|
// The polyfill doesn't set this properly
|
|
e.offsetX = e.pageX - e.currentTarget.offsetLeft;
|
|
e.offsetY = e.pageY - e.currentTarget.offsetTop;
|
|
}
|
|
|
|
var thisPtr = layerdict.pointerStates[e.pointerId];
|
|
|
|
var dx = e.offsetX - thisPtr.lastX;
|
|
var dy = e.offsetY - thisPtr.lastY;
|
|
|
|
// If this number is low on pointer up, we count the action as a click
|
|
thisPtr.distanceTravelled += Math.abs(dx) + Math.abs(dy);
|
|
|
|
if (Object.keys(layerdict.pointerStates).length == 1) {
|
|
// This is a simple drag
|
|
layerdict.transform.panx += devicePixelRatio * dx / layerdict.transform.zoom;
|
|
layerdict.transform.pany += devicePixelRatio * dy / layerdict.transform.zoom;
|
|
} else if (Object.keys(layerdict.pointerStates).length == 2) {
|
|
var otherPtr = Object.values(layerdict.pointerStates).filter((ptr) => ptr != thisPtr)[0];
|
|
|
|
var oldDist = Math.sqrt(Math.pow(thisPtr.lastX - otherPtr.lastX, 2) + Math.pow(thisPtr.lastY - otherPtr.lastY, 2));
|
|
var newDist = Math.sqrt(Math.pow(e.offsetX - otherPtr.lastX, 2) + Math.pow(e.offsetY - otherPtr.lastY, 2));
|
|
|
|
var scaleFactor = newDist / oldDist;
|
|
|
|
if (scaleFactor != NaN) {
|
|
layerdict.transform.zoom *= scaleFactor;
|
|
|
|
var zoomd = (1 - scaleFactor) / layerdict.transform.zoom;
|
|
layerdict.transform.panx += devicePixelRatio * otherPtr.lastX * zoomd;
|
|
layerdict.transform.pany += devicePixelRatio * otherPtr.lastY * zoomd;
|
|
}
|
|
}
|
|
|
|
thisPtr.lastX = e.offsetX;
|
|
thisPtr.lastY = e.offsetY;
|
|
|
|
if (settings.redrawOnDrag) {
|
|
redrawCanvas(layerdict);
|
|
}
|
|
}
|
|
|
|
function handleMouseWheel(e, layerdict) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
var t = layerdict.transform;
|
|
var wheeldelta = e.deltaY;
|
|
if (e.deltaMode == 1) {
|
|
// FF only, scroll by lines
|
|
wheeldelta *= 30;
|
|
} else if (e.deltaMode == 2) {
|
|
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;
|
|
}
|
|
t.zoom *= m;
|
|
var zoomd = (1 - m) / t.zoom;
|
|
t.panx += devicePixelRatio * e.offsetX * zoomd;
|
|
t.pany += devicePixelRatio * e.offsetY * zoomd;
|
|
redrawCanvas(layerdict);
|
|
}
|
|
|
|
function addMouseHandlers(div, layerdict) {
|
|
div.addEventListener("pointerdown", function(e) {
|
|
handlePointerDown(e, layerdict);
|
|
});
|
|
div.addEventListener("pointermove", function(e) {
|
|
handlePointerMove(e, layerdict);
|
|
});
|
|
div.addEventListener("pointerup", function(e) {
|
|
handlePointerUp(e, layerdict);
|
|
});
|
|
var pointerleave = function(e) {
|
|
handlePointerLeave(e, layerdict);
|
|
}
|
|
div.addEventListener("pointercancel", pointerleave);
|
|
div.addEventListener("pointerleave", pointerleave);
|
|
div.addEventListener("pointerout", pointerleave);
|
|
|
|
div.onwheel = function(e) {
|
|
handleMouseWheel(e, layerdict);
|
|
}
|
|
for (var element of [div, layerdict.bg, layerdict.fab, layerdict.silk, layerdict.highlight]) {
|
|
element.addEventListener("contextmenu", function(e) {
|
|
e.preventDefault();
|
|
}, false);
|
|
}
|
|
}
|
|
|
|
function setRedrawOnDrag(value) {
|
|
settings.redrawOnDrag = value;
|
|
writeStorage("redrawOnDrag", value);
|
|
}
|
|
|
|
function setBoardRotation(value) {
|
|
settings.boardRotation = value * 5;
|
|
writeStorage("boardRotation", settings.boardRotation);
|
|
document.getElementById("rotationDegree").textContent = settings.boardRotation;
|
|
resizeAll();
|
|
}
|
|
|
|
function initRender() {
|
|
allcanvas = {
|
|
front: {
|
|
transform: {
|
|
x: 0,
|
|
y: 0,
|
|
s: 1,
|
|
panx: 0,
|
|
pany: 0,
|
|
zoom: 1,
|
|
},
|
|
pointerStates: {},
|
|
anotherPointerTapped: false,
|
|
bg: document.getElementById("F_bg"),
|
|
fab: document.getElementById("F_fab"),
|
|
silk: document.getElementById("F_slk"),
|
|
highlight: document.getElementById("F_hl"),
|
|
layer: "F",
|
|
},
|
|
back: {
|
|
transform: {
|
|
x: 0,
|
|
y: 0,
|
|
s: 1,
|
|
panx: 0,
|
|
pany: 0,
|
|
zoom: 1,
|
|
},
|
|
pointerStates: {},
|
|
anotherPointerTapped: false,
|
|
bg: document.getElementById("B_bg"),
|
|
fab: document.getElementById("B_fab"),
|
|
silk: document.getElementById("B_slk"),
|
|
highlight: document.getElementById("B_hl"),
|
|
layer: "B",
|
|
}
|
|
};
|
|
addMouseHandlers(document.getElementById("frontcanvas"), allcanvas.front);
|
|
addMouseHandlers(document.getElementById("backcanvas"), allcanvas.back);
|
|
}
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/*
|
|
* Table reordering via Drag'n'Drop
|
|
* Inspired by: https://htmldom.dev/drag-and-drop-table-column
|
|
*/
|
|
|
|
function setBomHandlers() {
|
|
|
|
const bom = document.getElementById('bomtable');
|
|
|
|
let dragName;
|
|
let placeHolderElements;
|
|
let draggingElement;
|
|
let forcePopulation;
|
|
let xOffset;
|
|
let yOffset;
|
|
let wasDragged;
|
|
|
|
const mouseUpHandler = function(e) {
|
|
// Delete dragging element
|
|
draggingElement.remove();
|
|
|
|
// Make BOM selectable again
|
|
bom.style.removeProperty("userSelect");
|
|
|
|
// Remove listeners
|
|
document.removeEventListener('mousemove', mouseMoveHandler);
|
|
document.removeEventListener('mouseup', mouseUpHandler);
|
|
|
|
if (wasDragged) {
|
|
// Redraw whole BOM
|
|
populateBomTable();
|
|
}
|
|
}
|
|
|
|
const mouseMoveHandler = function(e) {
|
|
// Notice the dragging
|
|
wasDragged = true;
|
|
|
|
// Make the dragged element visible
|
|
draggingElement.style.removeProperty("display");
|
|
|
|
// Set elements position to mouse position
|
|
draggingElement.style.left = `${e.screenX - xOffset}px`;
|
|
draggingElement.style.top = `${e.screenY - yOffset}px`;
|
|
|
|
// Forced redrawing of BOM table
|
|
if (forcePopulation) {
|
|
forcePopulation = false;
|
|
// Copy array
|
|
phe = Array.from(placeHolderElements);
|
|
// populate BOM table again
|
|
populateBomHeader(dragName, phe);
|
|
populateBomBody(dragName, phe);
|
|
}
|
|
|
|
// Set up array of hidden columns
|
|
var hiddenColumns = Array.from(settings.hiddenColumns);
|
|
// In the ungrouped mode, quantity don't exist
|
|
if (settings.bommode === "ungrouped")
|
|
hiddenColumns.push("Quantity");
|
|
// If no checkbox fields can be found, we consider them hidden
|
|
if (settings.checkboxes.length == 0)
|
|
hiddenColumns.push("checkboxes");
|
|
|
|
// Get table headers and group them into checkboxes, extrafields and normal headers
|
|
const bh = document.getElementById("bomhead");
|
|
headers = Array.from(bh.querySelectorAll("th"))
|
|
headers.shift() // numCol is not part of the columnOrder
|
|
headerGroups = []
|
|
lastCompoundClass = null;
|
|
for (i = 0; i < settings.columnOrder.length; i++) {
|
|
cElem = settings.columnOrder[i];
|
|
if (hiddenColumns.includes(cElem)) {
|
|
// Hidden columns appear as a dummy element
|
|
headerGroups.push([]);
|
|
continue;
|
|
}
|
|
elem = headers.filter(e => getColumnOrderName(e) === cElem)[0];
|
|
if (elem.classList.contains("bom-checkbox")) {
|
|
if (lastCompoundClass === "bom-checkbox") {
|
|
cbGroup = headerGroups.pop();
|
|
cbGroup.push(elem);
|
|
headerGroups.push(cbGroup);
|
|
} else {
|
|
lastCompoundClass = "bom-checkbox";
|
|
headerGroups.push([elem])
|
|
}
|
|
} else {
|
|
headerGroups.push([elem])
|
|
}
|
|
}
|
|
|
|
// Copy settings.columnOrder
|
|
var columns = Array.from(settings.columnOrder)
|
|
|
|
// Set up array with indices of hidden columns
|
|
var hiddenIndices = hiddenColumns.map(e => settings.columnOrder.indexOf(e));
|
|
var dragIndex = columns.indexOf(dragName);
|
|
var swapIndex = dragIndex;
|
|
var swapDone = false;
|
|
|
|
// Check if the current dragged element is swapable with the left or right element
|
|
if (dragIndex > 0) {
|
|
// Get left headers boundingbox
|
|
swapIndex = dragIndex - 1;
|
|
while (hiddenIndices.includes(swapIndex) && swapIndex > 0)
|
|
swapIndex--;
|
|
if (!hiddenIndices.includes(swapIndex)) {
|
|
box = getBoundingClientRectFromMultiple(headerGroups[swapIndex]);
|
|
if (e.clientX < box.left + window.scrollX + (box.width / 2)) {
|
|
swapElement = columns[dragIndex];
|
|
columns.splice(dragIndex, 1);
|
|
columns.splice(swapIndex, 0, swapElement);
|
|
forcePopulation = true;
|
|
swapDone = true;
|
|
}
|
|
}
|
|
}
|
|
if ((!swapDone) && dragIndex < headerGroups.length - 1) {
|
|
// Get right headers boundingbox
|
|
swapIndex = dragIndex + 1;
|
|
while (hiddenIndices.includes(swapIndex))
|
|
swapIndex++;
|
|
if (swapIndex < headerGroups.length) {
|
|
box = getBoundingClientRectFromMultiple(headerGroups[swapIndex]);
|
|
if (e.clientX > box.left + window.scrollX + (box.width / 2)) {
|
|
swapElement = columns[dragIndex];
|
|
columns.splice(dragIndex, 1);
|
|
columns.splice(swapIndex, 0, swapElement);
|
|
forcePopulation = true;
|
|
swapDone = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Write back change to storage
|
|
if (swapDone) {
|
|
settings.columnOrder = columns
|
|
writeStorage("columnOrder", JSON.stringify(columns));
|
|
}
|
|
|
|
}
|
|
|
|
const mouseDownHandler = function(e) {
|
|
var target = e.target;
|
|
if (target.tagName.toLowerCase() != "td")
|
|
target = target.parentElement;
|
|
|
|
// Used to check if a dragging has ever happened
|
|
wasDragged = false;
|
|
|
|
// Create new element which will be displayed as the dragged column
|
|
draggingElement = document.createElement("div")
|
|
draggingElement.classList.add("dragging");
|
|
draggingElement.style.display = "none";
|
|
draggingElement.style.position = "absolute";
|
|
draggingElement.style.overflow = "hidden";
|
|
|
|
// Get bomhead and bombody elements
|
|
const bh = document.getElementById("bomhead");
|
|
const bb = document.getElementById("bombody");
|
|
|
|
// Get all compound headers for the current column
|
|
var compoundHeaders;
|
|
if (target.classList.contains("bom-checkbox")) {
|
|
compoundHeaders = Array.from(bh.querySelectorAll("th.bom-checkbox"));
|
|
} else {
|
|
compoundHeaders = [target];
|
|
}
|
|
|
|
// Create new table which will display the column
|
|
var newTable = document.createElement("table");
|
|
newTable.classList.add("bom");
|
|
newTable.style.background = "white";
|
|
draggingElement.append(newTable);
|
|
|
|
// Create new header element
|
|
var newHeader = document.createElement("thead");
|
|
newTable.append(newHeader);
|
|
|
|
// Set up array for storing all placeholder elements
|
|
placeHolderElements = [];
|
|
|
|
// Add all compound headers to the new thead element and placeholders
|
|
compoundHeaders.forEach(function(h) {
|
|
clone = cloneElementWithDimensions(h);
|
|
newHeader.append(clone);
|
|
placeHolderElements.push(clone);
|
|
});
|
|
|
|
// Create new body element
|
|
var newBody = document.createElement("tbody");
|
|
newTable.append(newBody);
|
|
|
|
// Get indices for compound headers
|
|
var idxs = compoundHeaders.map(e => getBomTableHeaderIndex(e));
|
|
|
|
// For each row in the BOM body...
|
|
var rows = bb.querySelectorAll("tr");
|
|
rows.forEach(function(row) {
|
|
// ..get the cells for the compound column
|
|
const tds = row.querySelectorAll("td");
|
|
var copytds = idxs.map(i => tds[i]);
|
|
// Add them to the new element and the placeholders
|
|
var newRow = document.createElement("tr");
|
|
copytds.forEach(function(td) {
|
|
clone = cloneElementWithDimensions(td);
|
|
newRow.append(clone);
|
|
placeHolderElements.push(clone);
|
|
});
|
|
newBody.append(newRow);
|
|
});
|
|
|
|
// Compute width for compound header
|
|
var width = compoundHeaders.reduce((acc, x) => acc + x.clientWidth, 0);
|
|
draggingElement.style.width = `${width}px`;
|
|
|
|
// Insert the new dragging element and disable selection on BOM
|
|
bom.insertBefore(draggingElement, null);
|
|
bom.style.userSelect = "none";
|
|
|
|
// Determine the mouse position offset
|
|
xOffset = e.screenX - compoundHeaders.reduce((acc, x) => Math.min(acc, x.offsetLeft), compoundHeaders[0].offsetLeft);
|
|
yOffset = e.screenY - compoundHeaders[0].offsetTop;
|
|
|
|
// Get name for the column in settings.columnOrder
|
|
dragName = getColumnOrderName(target);
|
|
|
|
// Change text and class for placeholder elements
|
|
placeHolderElements = placeHolderElements.map(function(e) {
|
|
newElem = cloneElementWithDimensions(e);
|
|
newElem.textContent = "";
|
|
newElem.classList.add("placeholder");
|
|
return newElem;
|
|
});
|
|
|
|
// On next mouse move, the whole BOM needs to be redrawn to show the placeholders
|
|
forcePopulation = true;
|
|
|
|
// Add listeners for move and up on mouse
|
|
document.addEventListener('mousemove', mouseMoveHandler);
|
|
document.addEventListener('mouseup', mouseUpHandler);
|
|
}
|
|
|
|
// In netlist mode, there is nothing to reorder
|
|
if (settings.bommode === "netlist")
|
|
return;
|
|
|
|
// Add mouseDownHandler to every column except the numCol
|
|
bom.querySelectorAll("th")
|
|
.forEach(function(head) {
|
|
if (!head.classList.contains("numCol")) {
|
|
head.onmousedown = mouseDownHandler;
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
function getBoundingClientRectFromMultiple(elements) {
|
|
var elems = Array.from(elements);
|
|
|
|
if (elems.length == 0)
|
|
return null;
|
|
|
|
var box = elems.shift()
|
|
.getBoundingClientRect();
|
|
|
|
elems.forEach(function(elem) {
|
|
var elembox = elem.getBoundingClientRect();
|
|
box.left = Math.min(elembox.left, box.left);
|
|
box.top = Math.min(elembox.top, box.top);
|
|
box.width += elembox.width;
|
|
box.height = Math.max(elembox.height, box.height);
|
|
});
|
|
|
|
return box;
|
|
}
|
|
|
|
function cloneElementWithDimensions(elem) {
|
|
var newElem = elem.cloneNode(true);
|
|
newElem.style.height = window.getComputedStyle(elem).height;
|
|
newElem.style.width = window.getComputedStyle(elem).width;
|
|
return newElem;
|
|
}
|
|
|
|
function getBomTableHeaderIndex(elem) {
|
|
const bh = document.getElementById('bomhead');
|
|
const ths = Array.from(bh.querySelectorAll("th"));
|
|
return ths.indexOf(elem);
|
|
}
|
|
|
|
function getColumnOrderName(elem) {
|
|
var cname = elem.getAttribute("col_name");
|
|
if (cname === "bom-checkbox")
|
|
return "checkboxes";
|
|
else
|
|
return cname;
|
|
}
|
|
|
|
function resizableGrid(tablehead) {
|
|
var cols = tablehead.firstElementChild.children;
|
|
var rowWidth = tablehead.offsetWidth;
|
|
|
|
for (var i = 1; i < cols.length; i++) {
|
|
if (cols[i].classList.contains("bom-checkbox"))
|
|
continue;
|
|
cols[i].style.width = ((cols[i].clientWidth - paddingDiff(cols[i])) * 100 / rowWidth) + '%';
|
|
}
|
|
|
|
for (var i = 1; i < cols.length - 1; i++) {
|
|
var div = document.createElement('div');
|
|
div.className = "column-width-handle";
|
|
cols[i].appendChild(div);
|
|
setListeners(div);
|
|
}
|
|
|
|
function setListeners(div) {
|
|
var startX, curCol, nxtCol, curColWidth, nxtColWidth, rowWidth;
|
|
|
|
div.addEventListener('mousedown', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
curCol = e.target.parentElement;
|
|
nxtCol = curCol.nextElementSibling;
|
|
startX = e.pageX;
|
|
|
|
var padding = paddingDiff(curCol);
|
|
|
|
rowWidth = curCol.parentElement.offsetWidth;
|
|
curColWidth = curCol.clientWidth - padding;
|
|
nxtColWidth = nxtCol.clientWidth - padding;
|
|
});
|
|
|
|
document.addEventListener('mousemove', function(e) {
|
|
if (startX) {
|
|
var diffX = e.pageX - startX;
|
|
diffX = -Math.min(-diffX, curColWidth - 20);
|
|
diffX = Math.min(diffX, nxtColWidth - 20);
|
|
|
|
curCol.style.width = ((curColWidth + diffX) * 100 / rowWidth) + '%';
|
|
nxtCol.style.width = ((nxtColWidth - diffX) * 100 / rowWidth) + '%';
|
|
console.log(`${curColWidth + nxtColWidth} ${(curColWidth + diffX) * 100 / rowWidth + (nxtColWidth - diffX) * 100 / rowWidth}`);
|
|
}
|
|
});
|
|
|
|
document.addEventListener('mouseup', function(e) {
|
|
curCol = undefined;
|
|
nxtCol = undefined;
|
|
startX = undefined;
|
|
nxtColWidth = undefined;
|
|
curColWidth = undefined
|
|
});
|
|
}
|
|
|
|
function paddingDiff(col) {
|
|
|
|
if (getStyleVal(col, 'box-sizing') == 'border-box') {
|
|
return 0;
|
|
}
|
|
|
|
var padLeft = getStyleVal(col, 'padding-left');
|
|
var padRight = getStyleVal(col, 'padding-right');
|
|
return (parseInt(padLeft) + parseInt(padRight));
|
|
|
|
}
|
|
|
|
function getStyleVal(elm, css) {
|
|
return (window.getComputedStyle(elm, null).getPropertyValue(css))
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/* DOM manipulation and misc code */
|
|
|
|
var bomsplit;
|
|
var canvassplit;
|
|
var initDone = false;
|
|
var bomSortFunction = null;
|
|
var currentSortColumn = null;
|
|
var currentSortOrder = null;
|
|
var currentHighlightedRowId;
|
|
var highlightHandlers = [];
|
|
var footprintIndexToHandler = {};
|
|
var netsToHandler = {};
|
|
var markedFootprints = new Set();
|
|
var highlightedFootprints = [];
|
|
var highlightedNet = null;
|
|
var lastClicked;
|
|
|
|
function dbg(html) {
|
|
dbgdiv.innerHTML = html;
|
|
}
|
|
|
|
function redrawIfInitDone() {
|
|
if (initDone) {
|
|
redrawCanvas(allcanvas.front);
|
|
redrawCanvas(allcanvas.back);
|
|
}
|
|
}
|
|
|
|
function padsVisible(value) {
|
|
writeStorage("padsVisible", value);
|
|
settings.renderPads = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function referencesVisible(value) {
|
|
writeStorage("referencesVisible", value);
|
|
settings.renderReferences = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function valuesVisible(value) {
|
|
writeStorage("valuesVisible", value);
|
|
settings.renderValues = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function tracksVisible(value) {
|
|
writeStorage("tracksVisible", value);
|
|
settings.renderTracks = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function zonesVisible(value) {
|
|
writeStorage("zonesVisible", value);
|
|
settings.renderZones = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function dnpOutline(value) {
|
|
writeStorage("dnpOutline", value);
|
|
settings.renderDnpOutline = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function setDarkMode(value) {
|
|
if (value) {
|
|
topmostdiv.classList.add("dark");
|
|
} else {
|
|
topmostdiv.classList.remove("dark");
|
|
}
|
|
writeStorage("darkmode", value);
|
|
settings.darkMode = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function setShowBOMColumn(field, value) {
|
|
if (field === "references") {
|
|
var rl = document.getElementById("reflookup");
|
|
rl.disabled = !value;
|
|
if (!value) {
|
|
rl.value = "";
|
|
updateRefLookup("");
|
|
}
|
|
}
|
|
|
|
var n = settings.hiddenColumns.indexOf(field);
|
|
if (value) {
|
|
if (n != -1) {
|
|
settings.hiddenColumns.splice(n, 1);
|
|
}
|
|
} else {
|
|
if (n == -1) {
|
|
settings.hiddenColumns.push(field);
|
|
}
|
|
}
|
|
|
|
writeStorage("hiddenColumns", JSON.stringify(settings.hiddenColumns));
|
|
|
|
if (initDone) {
|
|
populateBomTable();
|
|
}
|
|
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
|
|
function setFullscreen(value) {
|
|
if (value) {
|
|
document.documentElement.requestFullscreen();
|
|
} else {
|
|
document.exitFullscreen();
|
|
}
|
|
}
|
|
|
|
function fabricationVisible(value) {
|
|
writeStorage("fabricationVisible", value);
|
|
settings.renderFabrication = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function silkscreenVisible(value) {
|
|
writeStorage("silkscreenVisible", value);
|
|
settings.renderSilkscreen = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function setHighlightPin1(value) {
|
|
writeStorage("highlightpin1", value);
|
|
settings.highlightpin1 = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function getStoredCheckboxRefs(checkbox) {
|
|
function convert(ref) {
|
|
var intref = parseInt(ref);
|
|
if (isNaN(intref)) {
|
|
for (var i = 0; i < pcbdata.footprints.length; i++) {
|
|
if (pcbdata.footprints[i].ref == ref) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
} else {
|
|
return intref;
|
|
}
|
|
}
|
|
if (!(checkbox in settings.checkboxStoredRefs)) {
|
|
var val = readStorage("checkbox_" + checkbox);
|
|
settings.checkboxStoredRefs[checkbox] = val ? val : "";
|
|
}
|
|
if (!settings.checkboxStoredRefs[checkbox]) {
|
|
return new Set();
|
|
} else {
|
|
return new Set(settings.checkboxStoredRefs[checkbox].split(",").map(r => convert(r)).filter(a => a >= 0));
|
|
}
|
|
}
|
|
|
|
function getCheckboxState(checkbox, references) {
|
|
var storedRefsSet = getStoredCheckboxRefs(checkbox);
|
|
var currentRefsSet = new Set(references.map(r => r[1]));
|
|
// Get difference of current - stored
|
|
var difference = new Set(currentRefsSet);
|
|
for (ref of storedRefsSet) {
|
|
difference.delete(ref);
|
|
}
|
|
if (difference.size == 0) {
|
|
// All the current refs are stored
|
|
return "checked";
|
|
} else if (difference.size == currentRefsSet.size) {
|
|
// None of the current refs are stored
|
|
return "unchecked";
|
|
} else {
|
|
// Some of the refs are stored
|
|
return "indeterminate";
|
|
}
|
|
}
|
|
|
|
function setBomCheckboxState(checkbox, element, references) {
|
|
var state = getCheckboxState(checkbox, references);
|
|
element.checked = (state == "checked");
|
|
element.indeterminate = (state == "indeterminate");
|
|
}
|
|
|
|
function createCheckboxChangeHandler(checkbox, references, row) {
|
|
return function () {
|
|
refsSet = getStoredCheckboxRefs(checkbox);
|
|
var markWhenChecked = settings.markWhenChecked == checkbox;
|
|
eventArgs = {
|
|
checkbox: checkbox,
|
|
refs: references,
|
|
}
|
|
if (this.checked) {
|
|
// checkbox ticked
|
|
for (var ref of references) {
|
|
refsSet.add(ref[1]);
|
|
}
|
|
if (markWhenChecked) {
|
|
row.classList.add("checked");
|
|
for (var ref of references) {
|
|
markedFootprints.add(ref[1]);
|
|
}
|
|
drawHighlights();
|
|
}
|
|
eventArgs.state = 'checked';
|
|
} else {
|
|
// checkbox unticked
|
|
for (var ref of references) {
|
|
refsSet.delete(ref[1]);
|
|
}
|
|
if (markWhenChecked) {
|
|
row.classList.remove("checked");
|
|
for (var ref of references) {
|
|
markedFootprints.delete(ref[1]);
|
|
}
|
|
drawHighlights();
|
|
}
|
|
eventArgs.state = 'unchecked';
|
|
}
|
|
settings.checkboxStoredRefs[checkbox] = [...refsSet].join(",");
|
|
writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
|
|
updateCheckboxStats(checkbox);
|
|
EventHandler.emitEvent(IBOM_EVENT_TYPES.CHECKBOX_CHANGE_EVENT, eventArgs);
|
|
}
|
|
}
|
|
|
|
function clearHighlightedFootprints() {
|
|
if (currentHighlightedRowId) {
|
|
document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
|
|
currentHighlightedRowId = null;
|
|
highlightedFootprints = [];
|
|
highlightedNet = null;
|
|
}
|
|
}
|
|
|
|
function createRowHighlightHandler(rowid, refs, net) {
|
|
return function () {
|
|
if (currentHighlightedRowId) {
|
|
if (currentHighlightedRowId == rowid) {
|
|
return;
|
|
}
|
|
document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
|
|
}
|
|
document.getElementById(rowid).classList.add("highlighted");
|
|
currentHighlightedRowId = rowid;
|
|
highlightedFootprints = refs ? refs.map(r => r[1]) : [];
|
|
highlightedNet = net;
|
|
drawHighlights();
|
|
EventHandler.emitEvent(
|
|
IBOM_EVENT_TYPES.HIGHLIGHT_EVENT, {
|
|
rowid: rowid,
|
|
refs: refs,
|
|
net: net
|
|
});
|
|
}
|
|
}
|
|
|
|
function entryMatches(entry) {
|
|
if (settings.bommode == "netlist") {
|
|
// entry is just a net name
|
|
return entry.toLowerCase().indexOf(filter) >= 0;
|
|
}
|
|
// check refs
|
|
if (!settings.hiddenColumns.includes("references")) {
|
|
for (var ref of entry) {
|
|
if (ref[0].toLowerCase().indexOf(filter) >= 0) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
// check fields
|
|
for (var i in config.fields) {
|
|
var f = config.fields[i];
|
|
if (!settings.hiddenColumns.includes(f)) {
|
|
for (var ref of entry) {
|
|
if (pcbdata.bom.fields[ref[1]][i].toLowerCase().indexOf(filter) >= 0) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function findRefInEntry(entry) {
|
|
return entry.filter(r => r[0].toLowerCase() == reflookup);
|
|
}
|
|
|
|
function highlightFilter(s) {
|
|
if (!filter) {
|
|
return s;
|
|
}
|
|
var parts = s.toLowerCase().split(filter);
|
|
if (parts.length == 1) {
|
|
return s;
|
|
}
|
|
var r = "";
|
|
var pos = 0;
|
|
for (var i in parts) {
|
|
if (i > 0) {
|
|
r += '<mark class="highlight">' +
|
|
s.substring(pos, pos + filter.length) +
|
|
'</mark>';
|
|
pos += filter.length;
|
|
}
|
|
r += s.substring(pos, pos + parts[i].length);
|
|
pos += parts[i].length;
|
|
}
|
|
return r;
|
|
}
|
|
|
|
function checkboxSetUnsetAllHandler(checkboxname) {
|
|
return function () {
|
|
var checkboxnum = 0;
|
|
while (checkboxnum < settings.checkboxes.length &&
|
|
settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
|
|
checkboxnum++;
|
|
}
|
|
if (checkboxnum >= settings.checkboxes.length) {
|
|
return;
|
|
}
|
|
var allset = true;
|
|
var checkbox;
|
|
var row;
|
|
for (row of bombody.childNodes) {
|
|
checkbox = row.childNodes[checkboxnum + 1].childNodes[0];
|
|
if (!checkbox.checked || checkbox.indeterminate) {
|
|
allset = false;
|
|
break;
|
|
}
|
|
}
|
|
for (row of bombody.childNodes) {
|
|
checkbox = row.childNodes[checkboxnum + 1].childNodes[0];
|
|
checkbox.checked = !allset;
|
|
checkbox.indeterminate = false;
|
|
checkbox.onchange();
|
|
}
|
|
}
|
|
}
|
|
|
|
function createColumnHeader(name, cls, comparator, is_checkbox = false) {
|
|
var th = document.createElement("TH");
|
|
th.innerHTML = name;
|
|
th.classList.add(cls);
|
|
if (is_checkbox)
|
|
th.setAttribute("col_name", "bom-checkbox");
|
|
else
|
|
th.setAttribute("col_name", name);
|
|
var span = document.createElement("SPAN");
|
|
span.classList.add("sortmark");
|
|
span.classList.add("none");
|
|
th.appendChild(span);
|
|
var spacer = document.createElement("div");
|
|
spacer.className = "column-spacer";
|
|
th.appendChild(spacer);
|
|
spacer.onclick = function () {
|
|
if (currentSortColumn && th !== currentSortColumn) {
|
|
// Currently sorted by another column
|
|
currentSortColumn.childNodes[1].classList.remove(currentSortOrder);
|
|
currentSortColumn.childNodes[1].classList.add("none");
|
|
currentSortColumn = null;
|
|
currentSortOrder = null;
|
|
}
|
|
if (currentSortColumn && th === currentSortColumn) {
|
|
// Already sorted by this column
|
|
if (currentSortOrder == "asc") {
|
|
// Sort by this column, descending order
|
|
bomSortFunction = function (a, b) {
|
|
return -comparator(a, b);
|
|
}
|
|
currentSortColumn.childNodes[1].classList.remove("asc");
|
|
currentSortColumn.childNodes[1].classList.add("desc");
|
|
currentSortOrder = "desc";
|
|
} else {
|
|
// Unsort
|
|
bomSortFunction = null;
|
|
currentSortColumn.childNodes[1].classList.remove("desc");
|
|
currentSortColumn.childNodes[1].classList.add("none");
|
|
currentSortColumn = null;
|
|
currentSortOrder = null;
|
|
}
|
|
} else {
|
|
// Sort by this column, ascending order
|
|
bomSortFunction = comparator;
|
|
currentSortColumn = th;
|
|
currentSortColumn.childNodes[1].classList.remove("none");
|
|
currentSortColumn.childNodes[1].classList.add("asc");
|
|
currentSortOrder = "asc";
|
|
}
|
|
populateBomBody();
|
|
}
|
|
if (is_checkbox) {
|
|
spacer.onclick = fancyDblClickHandler(
|
|
spacer, spacer.onclick, checkboxSetUnsetAllHandler(name));
|
|
}
|
|
return th;
|
|
}
|
|
|
|
function populateBomHeader(placeHolderColumn = null, placeHolderElements = null) {
|
|
while (bomhead.firstChild) {
|
|
bomhead.removeChild(bomhead.firstChild);
|
|
}
|
|
var tr = document.createElement("TR");
|
|
var th = document.createElement("TH");
|
|
th.classList.add("numCol");
|
|
|
|
var vismenu = document.createElement("div");
|
|
vismenu.id = "vismenu";
|
|
vismenu.classList.add("menu");
|
|
|
|
var visbutton = document.createElement("div");
|
|
visbutton.classList.add("visbtn");
|
|
visbutton.classList.add("hideonprint");
|
|
|
|
var viscontent = document.createElement("div");
|
|
viscontent.classList.add("menu-content");
|
|
viscontent.id = "vismenu-content";
|
|
|
|
settings.columnOrder.forEach(column => {
|
|
if (typeof column !== "string")
|
|
return;
|
|
|
|
// Skip empty columns
|
|
if (column === "checkboxes" && settings.checkboxes.length == 0)
|
|
return;
|
|
else if (column === "Quantity" && settings.bommode == "ungrouped")
|
|
return;
|
|
|
|
var label = document.createElement("label");
|
|
label.classList.add("menu-label");
|
|
|
|
var input = document.createElement("input");
|
|
input.classList.add("visibility_checkbox");
|
|
input.type = "checkbox";
|
|
input.onchange = function (e) {
|
|
setShowBOMColumn(column, e.target.checked)
|
|
};
|
|
input.checked = !(settings.hiddenColumns.includes(column));
|
|
|
|
label.appendChild(input);
|
|
if (column.length > 0)
|
|
label.append(column[0].toUpperCase() + column.slice(1));
|
|
|
|
viscontent.appendChild(label);
|
|
});
|
|
|
|
viscontent.childNodes[0].classList.add("menu-label-top");
|
|
|
|
vismenu.appendChild(visbutton);
|
|
if (settings.bommode != "netlist") {
|
|
vismenu.appendChild(viscontent);
|
|
th.appendChild(vismenu);
|
|
}
|
|
tr.appendChild(th);
|
|
|
|
var checkboxCompareClosure = function (checkbox) {
|
|
return (a, b) => {
|
|
var stateA = getCheckboxState(checkbox, a);
|
|
var stateB = getCheckboxState(checkbox, b);
|
|
if (stateA > stateB) return -1;
|
|
if (stateA < stateB) return 1;
|
|
return 0;
|
|
}
|
|
}
|
|
var stringFieldCompareClosure = function (fieldIndex) {
|
|
return (a, b) => {
|
|
var fa = pcbdata.bom.fields[a[0][1]][fieldIndex];
|
|
var fb = pcbdata.bom.fields[b[0][1]][fieldIndex];
|
|
if (fa != fb) return fa > fb ? 1 : -1;
|
|
else return 0;
|
|
}
|
|
}
|
|
var referenceRegex = /(?<prefix>[^0-9]+)(?<number>[0-9]+)/;
|
|
var compareRefs = (a, b) => {
|
|
var ra = referenceRegex.exec(a);
|
|
var rb = referenceRegex.exec(b);
|
|
if (ra === null || rb === null) {
|
|
if (a != b) return a > b ? 1 : -1;
|
|
return 0;
|
|
} else {
|
|
if (ra.groups.prefix != rb.groups.prefix) {
|
|
return ra.groups.prefix > rb.groups.prefix ? 1 : -1;
|
|
}
|
|
if (ra.groups.number != rb.groups.number) {
|
|
return parseInt(ra.groups.number) > parseInt(rb.groups.number) ? 1 : -1;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
if (settings.bommode == "netlist") {
|
|
th = createColumnHeader("Net name", "bom-netname", (a, b) => {
|
|
if (a > b) return -1;
|
|
if (a < b) return 1;
|
|
return 0;
|
|
});
|
|
tr.appendChild(th);
|
|
} else {
|
|
// Filter hidden columns
|
|
var columns = settings.columnOrder.filter(e => !settings.hiddenColumns.includes(e));
|
|
var valueIndex = config.fields.indexOf("Value");
|
|
var footprintIndex = config.fields.indexOf("Footprint");
|
|
columns.forEach((column) => {
|
|
if (column === placeHolderColumn) {
|
|
var n = 1;
|
|
if (column === "checkboxes")
|
|
n = settings.checkboxes.length;
|
|
for (i = 0; i < n; i++) {
|
|
td = placeHolderElements.shift();
|
|
tr.appendChild(td);
|
|
}
|
|
return;
|
|
} else if (column === "checkboxes") {
|
|
for (var checkbox of settings.checkboxes) {
|
|
th = createColumnHeader(
|
|
checkbox, "bom-checkbox", checkboxCompareClosure(checkbox), true);
|
|
tr.appendChild(th);
|
|
}
|
|
} else if (column === "References") {
|
|
tr.appendChild(createColumnHeader("References", "references", (a, b) => {
|
|
var i = 0;
|
|
while (i < a.length && i < b.length) {
|
|
if (a[i] != b[i]) return compareRefs(a[i][0], b[i][0]);
|
|
i++;
|
|
}
|
|
return a.length - b.length;
|
|
}));
|
|
} else if (column === "Value") {
|
|
tr.appendChild(createColumnHeader("Value", "value", (a, b) => {
|
|
var ra = a[0][1], rb = b[0][1];
|
|
return valueCompare(
|
|
pcbdata.bom.parsedValues[ra], pcbdata.bom.parsedValues[rb],
|
|
pcbdata.bom.fields[ra][valueIndex], pcbdata.bom.fields[rb][valueIndex]);
|
|
}));
|
|
return;
|
|
} else if (column === "Footprint") {
|
|
tr.appendChild(createColumnHeader(
|
|
"Footprint", "footprint", stringFieldCompareClosure(footprintIndex)));
|
|
} else if (column === "Quantity" && settings.bommode == "grouped") {
|
|
tr.appendChild(createColumnHeader("Quantity", "quantity", (a, b) => {
|
|
return a.length - b.length;
|
|
}));
|
|
} else {
|
|
// Other fields
|
|
var i = config.fields.indexOf(column);
|
|
if (i < 0)
|
|
return;
|
|
tr.appendChild(createColumnHeader(
|
|
column, `field${i + 1}`, stringFieldCompareClosure(i)));
|
|
}
|
|
});
|
|
}
|
|
bomhead.appendChild(tr);
|
|
}
|
|
|
|
function populateBomBody(placeholderColumn = null, placeHolderElements = null) {
|
|
while (bom.firstChild) {
|
|
bom.removeChild(bom.firstChild);
|
|
}
|
|
highlightHandlers = [];
|
|
footprintIndexToHandler = {};
|
|
netsToHandler = {};
|
|
currentHighlightedRowId = null;
|
|
var first = true;
|
|
if (settings.bommode == "netlist") {
|
|
bomtable = pcbdata.nets.slice();
|
|
} else {
|
|
switch (settings.canvaslayout) {
|
|
case 'F':
|
|
bomtable = pcbdata.bom.F.slice();
|
|
break;
|
|
case 'FB':
|
|
bomtable = pcbdata.bom.both.slice();
|
|
break;
|
|
case 'B':
|
|
bomtable = pcbdata.bom.B.slice();
|
|
break;
|
|
}
|
|
if (settings.bommode == "ungrouped") {
|
|
// expand bom table
|
|
expandedTable = []
|
|
for (var bomentry of bomtable) {
|
|
for (var ref of bomentry) {
|
|
expandedTable.push([ref]);
|
|
}
|
|
}
|
|
bomtable = expandedTable;
|
|
}
|
|
}
|
|
if (bomSortFunction) {
|
|
bomtable = bomtable.sort(bomSortFunction);
|
|
}
|
|
for (var i in bomtable) {
|
|
var bomentry = bomtable[i];
|
|
if (filter && !entryMatches(bomentry)) {
|
|
continue;
|
|
}
|
|
var references = null;
|
|
var netname = null;
|
|
var tr = document.createElement("TR");
|
|
var td = document.createElement("TD");
|
|
var rownum = +i + 1;
|
|
tr.id = "bomrow" + rownum;
|
|
td.textContent = rownum;
|
|
tr.appendChild(td);
|
|
if (settings.bommode == "netlist") {
|
|
netname = bomentry;
|
|
td = document.createElement("TD");
|
|
td.innerHTML = highlightFilter(netname ? netname : "<no net>");
|
|
tr.appendChild(td);
|
|
} else {
|
|
if (reflookup) {
|
|
references = findRefInEntry(bomentry);
|
|
if (references.length == 0) {
|
|
continue;
|
|
}
|
|
} else {
|
|
references = bomentry;
|
|
}
|
|
// Filter hidden columns
|
|
var columns = settings.columnOrder.filter(e => !settings.hiddenColumns.includes(e));
|
|
columns.forEach((column) => {
|
|
if (column === placeholderColumn) {
|
|
var n = 1;
|
|
if (column === "checkboxes")
|
|
n = settings.checkboxes.length;
|
|
for (i = 0; i < n; i++) {
|
|
td = placeHolderElements.shift();
|
|
tr.appendChild(td);
|
|
}
|
|
return;
|
|
} else if (column === "checkboxes") {
|
|
for (var checkbox of settings.checkboxes) {
|
|
if (checkbox) {
|
|
td = document.createElement("TD");
|
|
var input = document.createElement("input");
|
|
input.type = "checkbox";
|
|
input.onchange = createCheckboxChangeHandler(checkbox, references, tr);
|
|
setBomCheckboxState(checkbox, input, references);
|
|
if (input.checked && settings.markWhenChecked == checkbox) {
|
|
tr.classList.add("checked");
|
|
}
|
|
td.appendChild(input);
|
|
tr.appendChild(td);
|
|
}
|
|
}
|
|
} else if (column === "References") {
|
|
td = document.createElement("TD");
|
|
td.innerHTML = highlightFilter(references.map(r => r[0]).join(", "));
|
|
tr.appendChild(td);
|
|
} else if (column === "Quantity" && settings.bommode == "grouped") {
|
|
// Quantity
|
|
td = document.createElement("TD");
|
|
td.textContent = references.length;
|
|
tr.appendChild(td);
|
|
} else {
|
|
// All the other fields
|
|
var field_index = config.fields.indexOf(column)
|
|
if (field_index < 0)
|
|
return;
|
|
var valueSet = new Set();
|
|
references.map(r => r[1]).forEach((id) => valueSet.add(pcbdata.bom.fields[id][field_index]));
|
|
td = document.createElement("TD");
|
|
td.innerHTML = highlightFilter(Array.from(valueSet).join(", "));
|
|
tr.appendChild(td);
|
|
}
|
|
});
|
|
}
|
|
bom.appendChild(tr);
|
|
var handler = createRowHighlightHandler(tr.id, references, netname);
|
|
tr.onmousemove = handler;
|
|
highlightHandlers.push({
|
|
id: tr.id,
|
|
handler: handler,
|
|
});
|
|
if (references !== null) {
|
|
for (var refIndex of references.map(r => r[1])) {
|
|
footprintIndexToHandler[refIndex] = handler;
|
|
}
|
|
}
|
|
if (netname !== null) {
|
|
netsToHandler[netname] = handler;
|
|
}
|
|
if ((filter || reflookup) && first) {
|
|
handler();
|
|
first = false;
|
|
}
|
|
}
|
|
EventHandler.emitEvent(
|
|
IBOM_EVENT_TYPES.BOM_BODY_CHANGE_EVENT, {
|
|
filter: filter,
|
|
reflookup: reflookup,
|
|
checkboxes: settings.checkboxes,
|
|
bommode: settings.bommode,
|
|
});
|
|
}
|
|
|
|
function highlightPreviousRow() {
|
|
if (!currentHighlightedRowId) {
|
|
highlightHandlers[highlightHandlers.length - 1].handler();
|
|
} else {
|
|
if (highlightHandlers.length > 1 &&
|
|
highlightHandlers[0].id == currentHighlightedRowId) {
|
|
highlightHandlers[highlightHandlers.length - 1].handler();
|
|
} else {
|
|
for (var i = 0; i < highlightHandlers.length - 1; i++) {
|
|
if (highlightHandlers[i + 1].id == currentHighlightedRowId) {
|
|
highlightHandlers[i].handler();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
smoothScrollToRow(currentHighlightedRowId);
|
|
}
|
|
|
|
function highlightNextRow() {
|
|
if (!currentHighlightedRowId) {
|
|
highlightHandlers[0].handler();
|
|
} else {
|
|
if (highlightHandlers.length > 1 &&
|
|
highlightHandlers[highlightHandlers.length - 1].id == currentHighlightedRowId) {
|
|
highlightHandlers[0].handler();
|
|
} else {
|
|
for (var i = 1; i < highlightHandlers.length; i++) {
|
|
if (highlightHandlers[i - 1].id == currentHighlightedRowId) {
|
|
highlightHandlers[i].handler();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
smoothScrollToRow(currentHighlightedRowId);
|
|
}
|
|
|
|
function populateBomTable() {
|
|
populateBomHeader();
|
|
populateBomBody();
|
|
setBomHandlers();
|
|
resizableGrid(bomhead);
|
|
}
|
|
|
|
function footprintsClicked(footprintIndexes) {
|
|
var lastClickedIndex = footprintIndexes.indexOf(lastClicked);
|
|
for (var i = 1; i <= footprintIndexes.length; i++) {
|
|
var refIndex = footprintIndexes[(lastClickedIndex + i) % footprintIndexes.length];
|
|
if (refIndex in footprintIndexToHandler) {
|
|
lastClicked = refIndex;
|
|
footprintIndexToHandler[refIndex]();
|
|
smoothScrollToRow(currentHighlightedRowId);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
function netClicked(net) {
|
|
if (net in netsToHandler) {
|
|
netsToHandler[net]();
|
|
smoothScrollToRow(currentHighlightedRowId);
|
|
} else {
|
|
clearHighlightedFootprints();
|
|
highlightedNet = net;
|
|
drawHighlights();
|
|
}
|
|
}
|
|
|
|
function updateFilter(input) {
|
|
filter = input.toLowerCase();
|
|
populateBomTable();
|
|
}
|
|
|
|
function updateRefLookup(input) {
|
|
reflookup = input.toLowerCase();
|
|
populateBomTable();
|
|
}
|
|
|
|
function changeCanvasLayout(layout) {
|
|
document.getElementById("fl-btn").classList.remove("depressed");
|
|
document.getElementById("fb-btn").classList.remove("depressed");
|
|
document.getElementById("bl-btn").classList.remove("depressed");
|
|
switch (layout) {
|
|
case 'F':
|
|
document.getElementById("fl-btn").classList.add("depressed");
|
|
if (settings.bomlayout != "bom-only") {
|
|
canvassplit.collapse(1);
|
|
}
|
|
break;
|
|
case 'B':
|
|
document.getElementById("bl-btn").classList.add("depressed");
|
|
if (settings.bomlayout != "bom-only") {
|
|
canvassplit.collapse(0);
|
|
}
|
|
break;
|
|
default:
|
|
document.getElementById("fb-btn").classList.add("depressed");
|
|
if (settings.bomlayout != "bom-only") {
|
|
canvassplit.setSizes([50, 50]);
|
|
}
|
|
}
|
|
settings.canvaslayout = layout;
|
|
writeStorage("canvaslayout", layout);
|
|
resizeAll();
|
|
changeBomMode(settings.bommode);
|
|
}
|
|
|
|
function populateMetadata() {
|
|
document.getElementById("title").innerHTML = pcbdata.metadata.title;
|
|
document.getElementById("revision").innerHTML = "Rev: " + pcbdata.metadata.revision;
|
|
document.getElementById("company").innerHTML = pcbdata.metadata.company;
|
|
document.getElementById("filedate").innerHTML = pcbdata.metadata.date;
|
|
if (pcbdata.metadata.title != "") {
|
|
document.title = pcbdata.metadata.title + " BOM";
|
|
}
|
|
// Calculate board stats
|
|
var fp_f = 0,
|
|
fp_b = 0,
|
|
pads_f = 0,
|
|
pads_b = 0,
|
|
pads_th = 0;
|
|
for (var i = 0; i < pcbdata.footprints.length; i++) {
|
|
if (pcbdata.bom.skipped.includes(i)) continue;
|
|
var mod = pcbdata.footprints[i];
|
|
if (mod.layer == "F") {
|
|
fp_f++;
|
|
} else {
|
|
fp_b++;
|
|
}
|
|
for (var pad of mod.pads) {
|
|
if (pad.type == "th") {
|
|
pads_th++;
|
|
} else {
|
|
if (pad.layers.includes("F")) {
|
|
pads_f++;
|
|
}
|
|
if (pad.layers.includes("B")) {
|
|
pads_b++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
document.getElementById("stats-components-front").innerHTML = fp_f;
|
|
document.getElementById("stats-components-back").innerHTML = fp_b;
|
|
document.getElementById("stats-components-total").innerHTML = fp_f + fp_b;
|
|
document.getElementById("stats-groups-front").innerHTML = pcbdata.bom.F.length;
|
|
document.getElementById("stats-groups-back").innerHTML = pcbdata.bom.B.length;
|
|
document.getElementById("stats-groups-total").innerHTML = pcbdata.bom.both.length;
|
|
document.getElementById("stats-smd-pads-front").innerHTML = pads_f;
|
|
document.getElementById("stats-smd-pads-back").innerHTML = pads_b;
|
|
document.getElementById("stats-smd-pads-total").innerHTML = pads_f + pads_b;
|
|
document.getElementById("stats-th-pads").innerHTML = pads_th;
|
|
// Update version string
|
|
document.getElementById("github-link").innerHTML = "InteractiveHtmlBom " +
|
|
/^v\d+\.\d+/.exec(pcbdata.ibom_version)[0];
|
|
}
|
|
|
|
function changeBomLayout(layout) {
|
|
document.getElementById("bom-btn").classList.remove("depressed");
|
|
document.getElementById("lr-btn").classList.remove("depressed");
|
|
document.getElementById("tb-btn").classList.remove("depressed");
|
|
switch (layout) {
|
|
case 'bom-only':
|
|
document.getElementById("bom-btn").classList.add("depressed");
|
|
if (bomsplit) {
|
|
bomsplit.destroy();
|
|
bomsplit = null;
|
|
canvassplit.destroy();
|
|
canvassplit = null;
|
|
}
|
|
document.getElementById("frontcanvas").style.display = "none";
|
|
document.getElementById("backcanvas").style.display = "none";
|
|
document.getElementById("bot").style.height = "";
|
|
break;
|
|
case 'top-bottom':
|
|
document.getElementById("tb-btn").classList.add("depressed");
|
|
document.getElementById("frontcanvas").style.display = "";
|
|
document.getElementById("backcanvas").style.display = "";
|
|
document.getElementById("bot").style.height = "calc(100% - 80px)";
|
|
document.getElementById("bomdiv").classList.remove("split-horizontal");
|
|
document.getElementById("canvasdiv").classList.remove("split-horizontal");
|
|
document.getElementById("frontcanvas").classList.add("split-horizontal");
|
|
document.getElementById("backcanvas").classList.add("split-horizontal");
|
|
if (bomsplit) {
|
|
bomsplit.destroy();
|
|
bomsplit = null;
|
|
canvassplit.destroy();
|
|
canvassplit = null;
|
|
}
|
|
bomsplit = Split(['#bomdiv', '#canvasdiv'], {
|
|
sizes: [50, 50],
|
|
onDragEnd: resizeAll,
|
|
direction: "vertical",
|
|
gutterSize: 5
|
|
});
|
|
canvassplit = Split(['#frontcanvas', '#backcanvas'], {
|
|
sizes: [50, 50],
|
|
gutterSize: 5,
|
|
onDragEnd: resizeAll
|
|
});
|
|
break;
|
|
case 'left-right':
|
|
document.getElementById("lr-btn").classList.add("depressed");
|
|
document.getElementById("frontcanvas").style.display = "";
|
|
document.getElementById("backcanvas").style.display = "";
|
|
document.getElementById("bot").style.height = "calc(100% - 80px)";
|
|
document.getElementById("bomdiv").classList.add("split-horizontal");
|
|
document.getElementById("canvasdiv").classList.add("split-horizontal");
|
|
document.getElementById("frontcanvas").classList.remove("split-horizontal");
|
|
document.getElementById("backcanvas").classList.remove("split-horizontal");
|
|
if (bomsplit) {
|
|
bomsplit.destroy();
|
|
bomsplit = null;
|
|
canvassplit.destroy();
|
|
canvassplit = null;
|
|
}
|
|
bomsplit = Split(['#bomdiv', '#canvasdiv'], {
|
|
sizes: [50, 50],
|
|
onDragEnd: resizeAll,
|
|
gutterSize: 5
|
|
});
|
|
canvassplit = Split(['#frontcanvas', '#backcanvas'], {
|
|
sizes: [50, 50],
|
|
gutterSize: 5,
|
|
direction: "vertical",
|
|
onDragEnd: resizeAll
|
|
});
|
|
}
|
|
settings.bomlayout = layout;
|
|
writeStorage("bomlayout", layout);
|
|
changeCanvasLayout(settings.canvaslayout);
|
|
}
|
|
|
|
function changeBomMode(mode) {
|
|
document.getElementById("bom-grouped-btn").classList.remove("depressed");
|
|
document.getElementById("bom-ungrouped-btn").classList.remove("depressed");
|
|
document.getElementById("bom-netlist-btn").classList.remove("depressed");
|
|
var chkbxs = document.getElementsByClassName("visibility_checkbox");
|
|
|
|
switch (mode) {
|
|
case 'grouped':
|
|
document.getElementById("bom-grouped-btn").classList.add("depressed");
|
|
for (var i = 0; i < chkbxs.length; i++) {
|
|
chkbxs[i].disabled = false;
|
|
}
|
|
break;
|
|
case 'ungrouped':
|
|
document.getElementById("bom-ungrouped-btn").classList.add("depressed");
|
|
for (var i = 0; i < chkbxs.length; i++) {
|
|
chkbxs[i].disabled = false;
|
|
}
|
|
break;
|
|
case 'netlist':
|
|
document.getElementById("bom-netlist-btn").classList.add("depressed");
|
|
for (var i = 0; i < chkbxs.length; i++) {
|
|
chkbxs[i].disabled = true;
|
|
}
|
|
}
|
|
|
|
writeStorage("bommode", mode);
|
|
if (mode != settings.bommode) {
|
|
settings.bommode = mode;
|
|
bomSortFunction = null;
|
|
currentSortColumn = null;
|
|
currentSortOrder = null;
|
|
clearHighlightedFootprints();
|
|
}
|
|
populateBomTable();
|
|
}
|
|
|
|
function focusFilterField() {
|
|
focusInputField(document.getElementById("filter"));
|
|
}
|
|
|
|
function focusRefLookupField() {
|
|
focusInputField(document.getElementById("reflookup"));
|
|
}
|
|
|
|
function toggleBomCheckbox(bomrowid, checkboxnum) {
|
|
if (!bomrowid || checkboxnum > settings.checkboxes.length) {
|
|
return;
|
|
}
|
|
var bomrow = document.getElementById(bomrowid);
|
|
var checkbox = bomrow.childNodes[checkboxnum].childNodes[0];
|
|
checkbox.checked = !checkbox.checked;
|
|
checkbox.indeterminate = false;
|
|
checkbox.onchange();
|
|
}
|
|
|
|
function checkBomCheckbox(bomrowid, checkboxname) {
|
|
var checkboxnum = 0;
|
|
while (checkboxnum < settings.checkboxes.length &&
|
|
settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
|
|
checkboxnum++;
|
|
}
|
|
if (!bomrowid || checkboxnum >= settings.checkboxes.length) {
|
|
return;
|
|
}
|
|
var bomrow = document.getElementById(bomrowid);
|
|
var checkbox = bomrow.childNodes[checkboxnum + 1].childNodes[0];
|
|
checkbox.checked = true;
|
|
checkbox.indeterminate = false;
|
|
checkbox.onchange();
|
|
}
|
|
|
|
function setBomCheckboxes(value) {
|
|
writeStorage("bomCheckboxes", value);
|
|
settings.checkboxes = value.split(",").map((e) => e.trim()).filter((e) => e);
|
|
prepCheckboxes();
|
|
populateMarkWhenCheckedOptions();
|
|
setMarkWhenChecked(settings.markWhenChecked);
|
|
}
|
|
|
|
function setMarkWhenChecked(value) {
|
|
writeStorage("markWhenChecked", value);
|
|
settings.markWhenChecked = value;
|
|
markedFootprints.clear();
|
|
for (var ref of (value ? getStoredCheckboxRefs(value) : [])) {
|
|
markedFootprints.add(ref);
|
|
}
|
|
populateBomTable();
|
|
drawHighlights();
|
|
}
|
|
|
|
function prepCheckboxes() {
|
|
var table = document.getElementById("checkbox-stats");
|
|
while (table.childElementCount > 1) {
|
|
table.removeChild(table.lastChild);
|
|
}
|
|
if (settings.checkboxes.length) {
|
|
table.style.display = "";
|
|
} else {
|
|
table.style.display = "none";
|
|
}
|
|
for (var checkbox of settings.checkboxes) {
|
|
var tr = document.createElement("TR");
|
|
var td = document.createElement("TD");
|
|
td.innerHTML = checkbox;
|
|
tr.appendChild(td);
|
|
td = document.createElement("TD");
|
|
td.id = "checkbox-stats-" + checkbox;
|
|
var progressbar = document.createElement("div");
|
|
progressbar.classList.add("bar");
|
|
td.appendChild(progressbar);
|
|
var text = document.createElement("div");
|
|
text.classList.add("text");
|
|
td.appendChild(text);
|
|
tr.appendChild(td);
|
|
table.appendChild(tr);
|
|
updateCheckboxStats(checkbox);
|
|
}
|
|
}
|
|
|
|
function populateMarkWhenCheckedOptions() {
|
|
var container = document.getElementById("markWhenCheckedContainer");
|
|
|
|
if (settings.checkboxes.length == 0) {
|
|
container.parentElement.style.display = "none";
|
|
return;
|
|
}
|
|
|
|
container.innerHTML = '';
|
|
container.parentElement.style.display = "inline-block";
|
|
|
|
function createOption(name, displayName) {
|
|
var id = "markWhenChecked-" + name;
|
|
|
|
var div = document.createElement("div");
|
|
div.classList.add("radio-container");
|
|
|
|
var input = document.createElement("input");
|
|
input.type = "radio";
|
|
input.name = "markWhenChecked";
|
|
input.value = name;
|
|
input.id = id;
|
|
input.onchange = () => setMarkWhenChecked(name);
|
|
div.appendChild(input);
|
|
|
|
// Preserve the selected element when the checkboxes change
|
|
if (name == settings.markWhenChecked) {
|
|
input.checked = true;
|
|
}
|
|
|
|
var label = document.createElement("label");
|
|
label.innerHTML = displayName;
|
|
label.htmlFor = id;
|
|
div.appendChild(label);
|
|
|
|
container.appendChild(div);
|
|
}
|
|
createOption("", "None");
|
|
for (var checkbox of settings.checkboxes) {
|
|
createOption(checkbox, checkbox);
|
|
}
|
|
}
|
|
|
|
function updateCheckboxStats(checkbox) {
|
|
var checked = getStoredCheckboxRefs(checkbox).size;
|
|
var total = pcbdata.footprints.length - pcbdata.bom.skipped.length;
|
|
var percent = checked * 100.0 / total;
|
|
var td = document.getElementById("checkbox-stats-" + checkbox);
|
|
td.firstChild.style.width = percent + "%";
|
|
td.lastChild.innerHTML = checked + "/" + total + " (" + Math.round(percent) + "%)";
|
|
}
|
|
|
|
document.onkeydown = function (e) {
|
|
switch (e.key) {
|
|
case "n":
|
|
if (document.activeElement.type == "text") {
|
|
return;
|
|
}
|
|
if (currentHighlightedRowId !== null) {
|
|
checkBomCheckbox(currentHighlightedRowId, "placed");
|
|
highlightNextRow();
|
|
e.preventDefault();
|
|
}
|
|
break;
|
|
case "ArrowUp":
|
|
highlightPreviousRow();
|
|
e.preventDefault();
|
|
break;
|
|
case "ArrowDown":
|
|
highlightNextRow();
|
|
e.preventDefault();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (e.altKey) {
|
|
switch (e.key) {
|
|
case "f":
|
|
focusFilterField();
|
|
e.preventDefault();
|
|
break;
|
|
case "r":
|
|
focusRefLookupField();
|
|
e.preventDefault();
|
|
break;
|
|
case "z":
|
|
changeBomLayout("bom-only");
|
|
e.preventDefault();
|
|
break;
|
|
case "x":
|
|
changeBomLayout("left-right");
|
|
e.preventDefault();
|
|
break;
|
|
case "c":
|
|
changeBomLayout("top-bottom");
|
|
e.preventDefault();
|
|
break;
|
|
case "v":
|
|
changeCanvasLayout("F");
|
|
e.preventDefault();
|
|
break;
|
|
case "b":
|
|
changeCanvasLayout("FB");
|
|
e.preventDefault();
|
|
break;
|
|
case "n":
|
|
changeCanvasLayout("B");
|
|
e.preventDefault();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
if (e.key >= '1' && e.key <= '9') {
|
|
toggleBomCheckbox(currentHighlightedRowId, parseInt(e.key));
|
|
e.preventDefault();
|
|
}
|
|
}
|
|
}
|
|
|
|
function hideNetlistButton() {
|
|
document.getElementById("bom-ungrouped-btn").classList.remove("middle-button");
|
|
document.getElementById("bom-ungrouped-btn").classList.add("right-most-button");
|
|
document.getElementById("bom-netlist-btn").style.display = "none";
|
|
}
|
|
|
|
window.onload = function (e) {
|
|
initUtils();
|
|
initRender();
|
|
initStorage();
|
|
initDefaults();
|
|
cleanGutters();
|
|
populateMetadata();
|
|
dbgdiv = document.getElementById("dbg");
|
|
bom = document.getElementById("bombody");
|
|
bomhead = document.getElementById("bomhead");
|
|
filter = "";
|
|
reflookup = "";
|
|
if (!("nets" in pcbdata)) {
|
|
hideNetlistButton();
|
|
}
|
|
initDone = true;
|
|
setBomCheckboxes(document.getElementById("bomCheckboxes").value);
|
|
// Triggers render
|
|
changeBomLayout(settings.bomlayout);
|
|
|
|
// Users may leave fullscreen without touching the checkbox. Uncheck.
|
|
document.addEventListener('fullscreenchange', () => {
|
|
if (!document.fullscreenElement)
|
|
document.getElementById('fullscreenCheckbox').checked = false;
|
|
});
|
|
}
|
|
|
|
window.onresize = resizeAll;
|
|
window.matchMedia("print").addListener(resizeAll);
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
</script>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="topmostdiv" class="topmostdiv">
|
|
<div id="top">
|
|
<div style="float: right; height: 100%;">
|
|
<div class="hideonprint menu" style="float: right; top: 8px;">
|
|
<button class="menubtn"></button>
|
|
<div class="menu-content">
|
|
<label class="menu-label menu-label-top" style="width: calc(50% - 18px)">
|
|
<input id="darkmodeCheckbox" type="checkbox" onchange="setDarkMode(this.checked)">
|
|
Dark mode
|
|
</label><!-- This comment eats space! All of it!
|
|
--><label class="menu-label menu-label-top" style="width: calc(50% - 17px); border-left: 0;">
|
|
<input id="fullscreenCheckbox" type="checkbox" onchange="setFullscreen(this.checked)">
|
|
Full Screen
|
|
</label>
|
|
<label class="menu-label" style="width: calc(50% - 18px)">
|
|
<input id="fabricationCheckbox" type="checkbox" checked onchange="fabricationVisible(this.checked)">
|
|
Fab layer
|
|
</label><!-- This comment eats space! All of it!
|
|
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
|
|
<input id="silkscreenCheckbox" type="checkbox" checked onchange="silkscreenVisible(this.checked)">
|
|
Silkscreen
|
|
</label>
|
|
<label class="menu-label" style="width: calc(50% - 18px)">
|
|
<input id="referencesCheckbox" type="checkbox" checked onchange="referencesVisible(this.checked)">
|
|
References
|
|
</label><!-- This comment eats space! All of it!
|
|
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
|
|
<input id="valuesCheckbox" type="checkbox" checked onchange="valuesVisible(this.checked)">
|
|
Values
|
|
</label>
|
|
<div id="tracksAndZonesCheckboxes">
|
|
<label class="menu-label" style="width: calc(50% - 18px)">
|
|
<input id="tracksCheckbox" type="checkbox" checked onchange="tracksVisible(this.checked)">
|
|
Tracks
|
|
</label><!-- This comment eats space! All of it!
|
|
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
|
|
<input id="zonesCheckbox" type="checkbox" checked onchange="zonesVisible(this.checked)">
|
|
Zones
|
|
</label>
|
|
</div>
|
|
<label class="menu-label" style="width: calc(50% - 18px)">
|
|
<input id="padsCheckbox" type="checkbox" checked onchange="padsVisible(this.checked)">
|
|
Pads
|
|
</label><!-- This comment eats space! All of it!
|
|
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
|
|
<input id="dnpOutlineCheckbox" type="checkbox" checked onchange="dnpOutline(this.checked)">
|
|
DNP outlined
|
|
</label>
|
|
<label class="menu-label">
|
|
<input id="highlightpin1Checkbox" type="checkbox" onchange="setHighlightPin1(this.checked)">
|
|
Highlight first pin
|
|
</label>
|
|
<label class="menu-label">
|
|
<input id="dragCheckbox" type="checkbox" checked onchange="setRedrawOnDrag(this.checked)">
|
|
Continuous redraw on drag
|
|
</label>
|
|
<label class="menu-label">
|
|
<span>Board rotation</span>
|
|
<span style="float: right"><span id="rotationDegree">0</span>°</span>
|
|
<input id="boardRotation" type="range" min="-36" max="36" value="0" class="slider" oninput="setBoardRotation(this.value)">
|
|
</label>
|
|
<label class="menu-label">
|
|
<div style="margin-left: 5px">Bom checkboxes</div>
|
|
<input id="bomCheckboxes" class="menu-textbox" type=text
|
|
oninput="setBomCheckboxes(this.value)">
|
|
</label>
|
|
<label class="menu-label">
|
|
<div style="margin-left: 5px">Mark when checked</div>
|
|
<div id="markWhenCheckedContainer"></div>
|
|
</label>
|
|
<label class="menu-label">
|
|
<span class="shameless-plug">
|
|
<span>Created using</span>
|
|
<a id="github-link" target="blank" href="https://github.com/openscopeproject/InteractiveHtmlBom">InteractiveHtmlBom</a>
|
|
</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="button-container hideonprint"
|
|
style="float: right; position: relative; top: 8px">
|
|
<button id="fl-btn" class="left-most-button" onclick="changeCanvasLayout('F')"
|
|
title="Front only">F
|
|
</button>
|
|
<button id="fb-btn" class="middle-button" onclick="changeCanvasLayout('FB')"
|
|
title="Front and Back">FB
|
|
</button>
|
|
<button id="bl-btn" class="right-most-button" onclick="changeCanvasLayout('B')"
|
|
title="Back only">B
|
|
</button>
|
|
</div>
|
|
<div class="button-container hideonprint"
|
|
style="float: right; position: relative; top: 8px">
|
|
<button id="bom-btn" class="left-most-button" onclick="changeBomLayout('bom-only')"
|
|
title="BOM only"></button>
|
|
<button id="lr-btn" class="middle-button" onclick="changeBomLayout('left-right')"
|
|
title="BOM left, drawings right"></button>
|
|
<button id="tb-btn" class="right-most-button" onclick="changeBomLayout('top-bottom')"
|
|
title="BOM top, drawings bot"></button>
|
|
</div>
|
|
<div class="button-container hideonprint"
|
|
style="float: right; position: relative; top: 8px">
|
|
<button id="bom-grouped-btn" class="left-most-button" onclick="changeBomMode('grouped')"
|
|
title="Grouped BOM"></button>
|
|
<button id="bom-ungrouped-btn" class="middle-button" onclick="changeBomMode('ungrouped')"
|
|
title="Ungrouped BOM"></button>
|
|
<button id="bom-netlist-btn" class="right-most-button" onclick="changeBomMode('netlist')"
|
|
title="Netlist"></button>
|
|
</div>
|
|
<div class="hideonprint menu" style="float: right; top: 8px;">
|
|
<button class="statsbtn"></button>
|
|
<div class="menu-content">
|
|
<table class="stats">
|
|
<tbody>
|
|
<tr>
|
|
<td width="40%">Board stats</td>
|
|
<td>Front</td>
|
|
<td>Back</td>
|
|
<td>Total</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Components</td>
|
|
<td id="stats-components-front">~</td>
|
|
<td id="stats-components-back">~</td>
|
|
<td id="stats-components-total">~</td>
|
|
</tr>
|
|
<tr>
|
|
<td>Groups</td>
|
|
<td id="stats-groups-front">~</td>
|
|
<td id="stats-groups-back">~</td>
|
|
<td id="stats-groups-total">~</td>
|
|
</tr>
|
|
<tr>
|
|
<td>SMD pads</td>
|
|
<td id="stats-smd-pads-front">~</td>
|
|
<td id="stats-smd-pads-back">~</td>
|
|
<td id="stats-smd-pads-total">~</td>
|
|
</tr>
|
|
<tr>
|
|
<td>TH pads</td>
|
|
<td colspan=3 id="stats-th-pads">~</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<table class="stats">
|
|
<col width="40%"/><col />
|
|
<tbody id="checkbox-stats">
|
|
<tr>
|
|
<td colspan=2 style="border-top: 0">Checkboxes</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="hideonprint menu" style="float: right; top: 8px;">
|
|
<button class="iobtn"></button>
|
|
<div class="menu-content">
|
|
<div class="menu-label menu-label-top">
|
|
<div style="margin-left: 5px;">Save board image</div>
|
|
<div class="flexbox">
|
|
<input id="render-save-width" class="menu-textbox" type="text" value="1000" placeholder="Width"
|
|
style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
|
|
<span>X</span>
|
|
<input id="render-save-height" class="menu-textbox" type="text" value="1000" placeholder="Height"
|
|
style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
|
|
</div>
|
|
<label>
|
|
<input id="render-save-transparent" type="checkbox">
|
|
Transparent background
|
|
</label>
|
|
<div class="flexbox">
|
|
<button class="savebtn" onclick="saveImage('F')">Front</button>
|
|
<button class="savebtn" onclick="saveImage('B')">Back</button>
|
|
</div>
|
|
</div>
|
|
<div class="menu-label">
|
|
<span style="margin-left: 5px;">Config and checkbox state</span>
|
|
<div class="flexbox">
|
|
<button class="savebtn" onclick="saveSettings()">Export</button>
|
|
<button class="savebtn" onclick="loadSettings()">Import</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="fileinfodiv" style="overflow: auto;">
|
|
<table class="fileinfo">
|
|
<tbody>
|
|
<tr>
|
|
<td id="title" class="title" style="width: 70%">
|
|
Title
|
|
</td>
|
|
<td id="revision" class="title" style="width: 30%">
|
|
Revision
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td id="company">
|
|
Company
|
|
</td>
|
|
<td id="filedate">
|
|
Date
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div id="bot" class="split" style="height: calc(100% - 80px)">
|
|
<div id="bomdiv" class="split split-horizontal">
|
|
<div style="width: 100%">
|
|
<input id="reflookup" class="textbox searchbox reflookup hideonprint" type="text" placeholder="Ref lookup"
|
|
oninput="updateRefLookup(this.value)">
|
|
<input id="filter" class="textbox searchbox filter hideonprint" type="text" placeholder="Filter"
|
|
oninput="updateFilter(this.value)">
|
|
<div class="button-container hideonprint" style="float: left; margin: 0;">
|
|
<button id="copy" title="Copy bom table to clipboard"
|
|
onclick="copyToClipboard()"></button>
|
|
</div>
|
|
</div>
|
|
<div id="dbg"></div>
|
|
<table class="bom" id="bomtable">
|
|
<thead id="bomhead">
|
|
</thead>
|
|
<tbody id="bombody">
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div id="canvasdiv" class="split split-horizontal">
|
|
<div id="frontcanvas" class="split" touch-action="none" style="overflow: hidden">
|
|
<div style="position: relative; width: 100%; height: 100%;">
|
|
<canvas id="F_bg" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
|
|
<canvas id="F_fab" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
|
|
<canvas id="F_slk" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
|
|
<canvas id="F_hl" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
|
|
</div>
|
|
</div>
|
|
<div id="backcanvas" class="split" touch-action="none" style="overflow: hidden">
|
|
<div style="position: relative; width: 100%; height: 100%;">
|
|
<canvas id="B_bg" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
|
|
<canvas id="B_fab" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
|
|
<canvas id="B_slk" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
|
|
<canvas id="B_hl" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</body>
|
|
|
|
</html>
|