You've already forked zepto
mirror of
https://openbeagle.org/beagleconnect/zepto.git
synced 2026-09-07 21:16:59 +00:00
4718 lines
301 KiB
HTML
4718 lines
301 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: 0.4rem 0.4rem 0.4rem 0;
|
|
}
|
|
|
|
.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: 3px;
|
|
}
|
|
|
|
.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: 0.4rem 0.4rem 0.4rem 0;
|
|
}
|
|
|
|
.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 {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
background-color: white;
|
|
transition: background-color 0.3s;
|
|
min-height: 100%;
|
|
}
|
|
|
|
#top {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: flex-end;
|
|
align-items: center;
|
|
}
|
|
|
|
#topdivider {
|
|
border-bottom: 2px solid black;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.dark #topdivider {
|
|
border-bottom: 2px solid #ccc;
|
|
}
|
|
|
|
#topdivider>div {
|
|
position: relative;
|
|
}
|
|
|
|
#toptoggle {
|
|
cursor: pointer;
|
|
user-select: none;
|
|
position: absolute;
|
|
padding: 0.1rem 0.3rem;
|
|
top: -0.4rem;
|
|
left: -1rem;
|
|
font-size: 1.4rem;
|
|
line-height: 60%;
|
|
border: 1px solid black;
|
|
border-radius: 1rem;
|
|
background-color: #fff;
|
|
z-index: 100;
|
|
}
|
|
|
|
.flipped {
|
|
transform: rotate(0.5turn);
|
|
}
|
|
|
|
.dark #toptoggle {
|
|
border: 1px solid #fff;
|
|
background-color: #222;
|
|
}
|
|
|
|
#fileinfodiv {
|
|
flex: 20rem 1 0;
|
|
overflow: auto;
|
|
}
|
|
|
|
#bomcontrols {
|
|
display: flex;
|
|
flex-direction: row-reverse;
|
|
}
|
|
|
|
#bomcontrols>* {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
#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;
|
|
}
|
|
|
|
.help-link {
|
|
border: 1px solid #0278a4;
|
|
padding-inline: 0.3rem;
|
|
border-radius: 3px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.dark .help-link {
|
|
border: 1px solid #00b9fd;
|
|
}
|
|
|
|
.bom-color {
|
|
width: 20%;
|
|
}
|
|
|
|
.color-column input {
|
|
width: 1.6rem;
|
|
height: 1rem;
|
|
border: 1px solid black;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
}
|
|
|
|
/* removes default styling from input color element */
|
|
::-webkit-color-swatch {
|
|
border: none;
|
|
}
|
|
|
|
::-webkit-color-swatch-wrapper {
|
|
padding: 0;
|
|
}
|
|
|
|
::-moz-color-swatch,
|
|
::-moz-focus-inner {
|
|
border: none;
|
|
}
|
|
|
|
::-moz-focus-inner {
|
|
padding: 0;
|
|
}
|
|
|
|
</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": "none", "redraw_on_drag": true, "board_rotation": 0, "checkboxes": "Sourced,Placed", "bom_view": "left-right", "layer_view": "FB", "offset_back_rotation": false, "kicad_text_formatting": true, "mark_when_checked": "", "fields": ["Value", "Footprint"]}
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
var pcbdata = JSON.parse(LZString.decompressFromBase64("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s6gtR9IABqi4d6Yousi7SaWwRGi4MAKAAkeiR6LgBggGahJIASAJwAYAD+ABj4IACNgOIAkHqDAHYAxABwsNdT20EnPQP0/yiii8yLrItfhlKLnTzBNW56Govyi0KAiovAgBGcKotsAHqLJIDhi1qLfZ3AgPGLBoth5OocZEDfqeIAZosWi2AAVouq/jaLdosOi5YATovAgK6LU4Dei0KL+9x+gGmL9wCSi4LtIYuptWGLmouRi9qLSosxi8UAqou0pfqLLYtOAFGLXYvqiwGL6Yvz+CaL2Yvmi5aLh2niAIWL9ouOi86LbADli8GAlYuHfSRZ/ovii3WLdmkNiy80TYuyixGLTgD+ACgAaICJANWAAIBtgAx9XwBhJMqLnYtxi92LCYu9izUA/YvXi4OLa4tfHBmLo4tsADmLE4vUhYMA04vFi8EApYsuiyAAEhFLi1jE+KWRBM4AQ4vri4Q00ouvfc2Lu4v3i22L0YveQLGLuos3i4mLrYvJiwOL+osQSy+LI4s6eEAMH4t5i5OLbAA/i7OLZYuASxWLWZGBZZsyRpKri4GL9YtfhjKLPgB3ix94CEviAB2LKYuoS8xLIAAPiyhLT4uGi3hLbvhZi++L44uES1+LU4u2izOLJYtziyAAC4vLAMBLwyrYRMsStYuugPRL0EuhizuLSYvGlWxLSEtXi7xLPYtwSyxLGEuPi1hLz4vRnK+LeEumiyJL+Yt/oSRLUktkS0BLlEtVi/yylBTgS6ZLQYubi2BLBLNMSwZL3EusS2wA7EuYS7eLPks8S6mL2EtmS7hLQksgAARL1ksFkrZLf4vSS7JLoADySx9S9tC0SxKLG4sMSzBLGkvoS1pL/ks6SxxL6otcSyFLqEthS0aLgksLNFFLVktESyAAcUttAP+L84vkS4uLjkvrSEitYEvKSyEAqkuNi15LTQBFS35Ll4sFS/pLmks6i6FLpktlS5mLFUvRS9VLtUsWAPVLMkuNS3JLzUsgS3QiQoLtS+5LmUvqS95LQ0vti/lLgUtoS32LfUsjS/xL5kuRS5NLYkvESxJLv4t1SwlL80tJS4tLjiyd9mlLkEuOQGpL24ubSzlLOosBS8ZLQUtbSwNLCYulSwJL40v4S1VLZ0s1SxdLpEsAS/b4uYD5gMQAUAAY+N+LF0tOAI2AU4BYi7iLddgEi6gAMgC3Sxj4k5CLeCeB8u2Ui9SLy8LxgBSAwqaPS20AWMmsACKLdNX8ZbyLKIACi96LW36LeKHQNYv/S0lUYJiTeoyze0s1AMeLbYCGAngASQBji7mLMUseQtNLpYtuix6LlGMMy8ShZpVB1GTL0Zxsy2K0/6Gcy1xLPMuIS0lA/MvAgKdL9tnwy0WLpEsOS9jLs/gyy52Jrkv8SwrLfoAueiJ6b0t7i2AAJ4tqy6aAGsuCy5+L2sviS7rLdkv6y/e6jNS0RSwM7UtQeMGL5ssMs5bLPUs+S6rL2kvqywLLwktCy1NLYMtuyxRLBsu1eqqsXEByy3rwUotCgt1LzgAqyzbLvMuFeA7LEctOy8R5OsuSS/FLN0ski+QEi3ivQEnLwgApy4xLQcv6QCHLeUthy5rLwMvOy+dLrstFy5DLXYsSAAWAsMtwiy7L9ouIy5dQKMs1AAAAInCw6MtEi0ylJIvVXicaSmSg+ATLWZE0i6C5/XobeoyLpkuUosGLkQsEs7TL/ItQegzLd5IWejT4K8tHS6CEW+jVy+nLwcsHi0eLmcvAgGeLvIBSGtOdfMvhy5VLkcsgy6LLjYDiy0QAnotPdQtLBsu9wRokuxpyy/39bvizAmnLXMtsAPuLh4t5gFfLI50Ys7EDKYNrEjnLT8t5y9aL0cttyzmAHctdy3DLvcv+AP3LyMtgANiLNQBlgAQAiABogEyLTIsBABAAFICJSAAAggAAoniYwICEi5jLk8szYnT0qORgS9WAVIvzy5BQfgQ7+EvL1cxGgu1Lh03o0BpAhVgs5CD4m8uE+HTLPcvXi53LMMuYKy3Lfcs1AEjLwYCDy2wAAABKaMtsAIwrxIsMy5REbNUHy2Arc8sY+AvLpgRLyyeyTQBhS2vLDYsby7SzW8v0y5RLkqQzeHE+QAw+yxuAQCv+yzOcsEu1yxfLkCu2y9ArAu2JAvXL9suPy1rL+ctYK3rLhPgSy16LDiuyOKnR/8uHy+mL7iuny6AroPg+K3XL6LMBK5XLQSvrAAgroSvIK63LV0vkS1DLsiuFgNIroMtFizgrKit4K04AhCvEK6Qr5CuUK3aAVCsAAMKZoAwrGMs6Kw4r/Ah71C5A+MucK8Yr+FGXqXSLRFQslHLLUpRRBVKLOMI4go56pQB2K2UreYAlK93LwQAFy9grSisDy9UrNQDNK5dTWisdKxPLlYsURtKCFIv9K5YAJivEyw/oLMury68z1isyi3MrwQBYy1dAMXiHKwkrAhTGix2dICsqy2krUCtgK5Szt8sXiw/LjcvPy83L5SuFy4Ur78ufy3NAlYvTeE8rFiujS1DtZEDAK7SzVsvcy58rfivfK6OdZED5EtkrkEC5K03LYSsKK5dLM0tvy2grMisYK2UrP4uVK8sAqisgAK0r7Svjy9/LDRpQ4EoRQoIcK9SL3KhnK8vLMKusi1YrspQcyyJ6tyttAPcrHQzqNOdYACtwqyfL1MuBy2fL3isQK+krN8sYq38r2cshK7ir+Ssgq4SrgEuRKx/LkssOK2mkTKuiq68rCKvq7ZKrKSvgK5fLqKsZK5MgmKvwK0qrgKt4q8CrBKtiy8SrKEuLK/IrdqsUq5iLGyvqK6PLOyt0q4KrwmxkxWois8vHK8EApyvDKxyrJsuWANyriaA3K5Ir28t3K5PLpPnwBNhAoqu1eOKrG0s1y0KAJqu+K6eLPysYq6HLwSsAq0grBYsoK6CrGqvgq7HLxkBkoUuFtQyuKymrbyuIq+mre4soq9mr6KuBK1arBauiS0Crr8tFK+grcitkqwjLayu4K/grbAD1gOB6XqsgANoreyuOSwcrixHMq0YrJytsq6Gr5ivhq8EAkau13ErLfKsxq/Yr2MvjDWZanfErS/9LKYOpq+ur6XrGq02r18s5q7AroIRtq47LHau2q12rYKtaq9uruxp+MSKrzysvi8fLdauGqyerHysyq18r5qvni+/g98uKq+2rwsu4nPerjqsLK6SryytYK26rs8tDq9SrY6sTq/SrHEBjlnYMFZhHK6yrddaLq4rL7UurqzYrnisdQzHkUitxq5WLUpSVQ0DEeqtJK1lLSKtgK2er/isWqwqrDcs3q6BrPxz3q6Wrj6tXQKwo5Gs4a/9L+qseKyJcXisZq3RraKswK2+AQGtMa7nLt6sqq/arRKvFK1BrbQArK7BrVKvNK7wAtKtMKwzL6oLTfhhr88sLq5SA5ytyy3hrk3oUgBJ6/KtWAMwreH3bhhcr/Et8a5N6icCCa42rv6tmq3KrWHXia/mrzGtRywUraqsPq9ErBsvqgn2A/ezLq18cNmt01XZr2UsOa6arzauia5ar/yvuay/LxateaxBr0MulK9Br+KtKax6rIABqK9sr46u7K8hrUKUArQmifQwsqz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uVi1Bbhli4WwIU+Fv/mzibT5vSmyubyxtlm+2bYxubm9hbh2K0W18c9Fuxm4ObTFvLmyBb6Fvrm5hbnhvUWykwv5s1TAxbRFtLm6JrLFuHG+Rb7Fsbm1hbXZszqzWblpv8W4+bxFvPm6hboFsXm6grnFsoW+pbOZt9mzJbhZtOa8xbwlsGmxhblFsOK9ERuqumWx6bMZv5mwJbOltWW3pbIlt3qxObV5vhm45bPZsCFGZbWluHm3JbdpvWW27r3lscW75brpsmWwFbXxxBW65b2luhW/6bnls2W6JbdlsGy4zA5WI8W/LLcFvmW0hbultYqymbaVuRWypbYZsLoP5b5psJW69L3psWWx1rKVtFW2ebJVsP65ebYZtSgFvi3pxVW85b/ZsEa4hbQ5seW41baFvNW5AbrVvxq3bre6saW3mbNVsFmwVbA1sOmysbyltiWwzrbisRYpGbXKuQYNzr7+sHm9ab7ltCW/PIqVsRWy1bhlvRWytb7cYBa64rO/iIEDJbZ+syG9frl+vDS4QbvZt3mzwbY5t9a3Yb6htfm+l0a5FrW2Hkl1t9ANdbfUsAG4VL+BtX68vr8VvPW4dbI1tFyx9bJ1s1orMNF1tu+LUM21vMG6ebphvA2+Yb1+v/S16AkUAvW++bi1tQG4lLgosdTN9boqt/W0jbD5sg2x9Lt1vsGyjbFhtRmxDbIxulW2obT+sum6dbxUYIGwIUZNsA27Pr1NtmG7TbmNv02xiruNtgW3arBNvFywzLWVvMsTlb8RvSW8FbO1vJW8BbB1uM20dboKsom5Lb0FtSW/Obctv1m4Jb8lvhW8rbUNuq21+b6tsIQprb95u9W7Vbs1tCW0rba5tM2xlbxkAm24pwZtsEWy0bVtt62zbbSlvjm1FbYZsm21prOZt8W4lbIVtFm3Nbo5t4217bZVtjWywpqptOW7Wb2tuLm8Hb1tuDW/pbtlsxyw4bSysk6+SrVxuA60QrwOsNK+DrnBBHa5OrURsd4KhR9H0vG20AFIAw/hAUfCuXIjlblX5kxIVY4mQ9W0P4Jet8iy6rROuOG84b1Jvba04AzSu068nr5mu94m4LLOuvGyVr7xsc220Ahmt01a3bZesAmw4r6oK1FBPb0ZzBax1SeutuWwrbvyv627bbKttea4qbvlvqgosAS9vDzUerkuthawBbG9vyq1vbnttvW2Mbadsuq5nb3dsA6/BraitQ696rMOsGy/GQReQc4Mzr5dsWACGrpWtLq+VrXxtrq6fbpmthm5/bk9wKLkfbK1sn247rrtv9W/NrXWtkWwtb4dsnG3vb4DvM7fY0vStNa/Cr8Ftr20lbCdtRax7bKDs32xWbd9sx64orj9vx604AaiuVw2/b9xt7gPEbNVpxg5nrxWuLy/pr6OtT26vb1WsRGyRrDitMO3HcmCA4O7A7+Jz4O0HblluIO8Q7bFuoOxEr2Rtlq1+bTDvofNg7OZu1qwarLduEW3Vb0JsWq1I7r1sR66nb32vp25SbpOulizSbmyv4i/Q7Rdu1G9VcMxpmmyPbFdtvGxw7cVuPa8A7+GvqOzyLBOvl6/srdRvTyx8b1muYm6I7Gjtu251rjGuKWyQ7ejtty+g7gou2UAsSMpKUa7g7gevwO7rbwTtX22E76ZuoK+Q7G2sP2yY7PdsEKznb9Sug640rvAC0K4wQQ8uF26pbKCVMQEJSaMDPG0GrFdukqexYt2tOA0vbWwPrfO2aahLqS6ZrGTsZ2/2rVDuuGzUAaisUAGU7YZt6K/6rZdu1O3/bDjtla5YrFWvfG2EbPDv8m5EbEKPgilWrwjufq0P4rWvy24Q7MJtJ215bO9tK63I7HGsdw6K6ozurO2o75IAbOzrbu1tEOzs7w1tVG/o7Zxud25cbvTvKa3Q7dOvv2w8btyK0GRdAdjsTO2PbjjsPa1w7U2u/G23biztCq587+KPmmyvbQLt9W0k7DGspO9I7pDtoOwc7uRszpH34KFgQu64rULvgm4k7VzvJOzo7YduIu5HrXTtGO1k7yitP273bgzt3G5Y7KGsuvPsSDECsm6Pb7DtTO58bq+SzO9uLYDuCi2RrdLsBq5i7/jsCa2fbjFu4u3C7+Lsi2/1rcPiDa4Pr26tca9y70ttiq2s74vg4uxfbLmsiuwZbqtvEu13b2Tvku8PL/dseG5PL5BI54wYrrDtXa387zLvrWy47zRvAu7PbYZuJmpBVhrs1qx+rZztJG4E7CDtRa4BrKrsp2xE7yLsW696LpctxK3a7B6sOu/BbFzvx2xI7rrtwK6Hborsdm+q7Tzuau9Q7w8tJ67q7XjsuYthwDLv2O9QmdIu28EvbpeisAKXofJsgu3w726sdc0WRsrvOWy7bAruyW1s7vJAhO3Cbtzshm27LkTuQq5hwxbuiq6W7+Vsuu5kruAPzWwi74TtG21hbUKuKYiW7bvhluzC7Qrt34PC7ujtpO727nhtFuwO7LbtDu227sLtju+676Vv3O+Sb5xsau2S7cbtsAEDr+Ttg600rEOs0K0M7RNth/vDrqbu/O0ySEwBLyy9kt0wAu/eYYJKC7X+xuOugOx47Rjsd24Y7G7vk6zQ7F2hUu75bKlBf2yw7Pzv/2+PbBmszOyA7cDuWu/8bwzv1a4I7dzMYm/E709vOu4u7t8vLu3bb9bteu5K7DRogOso7Tjugm/B73DuKu5W7+Js3O5DbdzvpOwY799s9O7G7fTtsANTrDJvvO3kbZLOeND/b4zuV24aQGbuGkJzroIQt2MXr8zv5u547jkv8CLg0nfN+691b8FuoG8arQxs1uyR7dbueu+K7ORveuwJ7q9zW6yJ72uv6Gxo7knv6m9J7FFtoe3J78jtYW5lYLPQA9B/rdusB6yFrBhsSe+UboTvdu5O7CWucWwZ7ynvbG/7rIBBqe4MblntSewbbpHtqu+R7FDurK8876WtqK+Y7bzsMOx+EpuQnOzU7mGtMu4A70zvmu1lLHLs+u8D4qdFJqyo7fLsKu+W7mjvHm62rEbuqu7vb6Hsomy/NYXs4ezA78rtZgCO7SrsLa1l7Hrteew8777sxu5u71HsgADiLlLsWO1ebefOfUCuL4XvFaw7slICGiEvb7IvYAJyLzdvnO+EbCzsFuwcAO/Tte047n+vIG+s7yRviO/Vb54vNm2jbg0v822Db4UtWG8obkbuZGxDLDbuUS8cLAJI0S9sbh+viG1+rkhs3WyYbbBt82/tLBBsKGyvr3Btae/jbdksw2ynrefPFwKBLcstOkDm7ipnkALN7GNtA28t7V3ug249bdYvPS2BL19s9u2qrT3sly4gmKnpHAO974eROkBa7p+uA27zb6Nsre0D7KktJFOTgwtvZe7NLhNs+u9D7SpSiG89L03tDe4RbZ3tCgEt7C+sA+w9bN3s4S+t72PuVexD7LNubmy97tqJ+i4d7ehs/G0j7PNvne79LchvAG7T7a3tKGwz7K7vQ28z7LXsE+2yJ0RJ0G8T7DBsne+W75PusG3z791tL6+j7QvuAyyL7qHti+9Ab4xus+7ciZpsy+8GLcvsze2T7yPu8+63rlNuq+4L7Y0tvi9vbhttM+zr7LPuS+6jGRPtG+8d7Jvune2b7FPsXe6j71PtW+yZLRBv0+/d7MjuPe+L7z3tz9HrRrvseS4j73puK+zUAlPv8+9d7AfuKGxr7wfuEu6H7jvsS+9Pqzksg+Ib70ftc+7H7XvtK+xb7GNurezb7Fktp++D7uPvi27t7EftWJEpLuhuy++77pPue+zz73vvK+5b7fPuWG8L7lfs2e9X7ZJtvuxR7set+e/BrO7sg63u7RTtDyyprCbuMmw4rBfRrpFWBzVnwVYB7UxUKKjXbrUVw+0pQW1RGiyGCeOu8e7Pb0btUm3NLpjvbu3k74/uFO7Qr/ADNK9+7zXvPe1tgzHk0IYdxyxIr+zDwlWihq9yaOILtS50CmrrlSyTwg3s8ADPb/xuH+8Y7kHon+yAAY/t5200rU/uMAIe7P7thm1EpRGFXwe6kkQsv+zVyOevkEkbZcPtzgRfUhVjb6Qk7EHvt20lrNXtH+6AHOTtsAPtrh2twB5brXYhq66vNZ7sUgPcmIUqUgOWQSBwa625Ly+XpVLV43WrKKHg7+/tAB957mTuUe6QHWrun+3Ur5/vUK1P7GsBHu427BEDbWtQBmhpADC/76gTvpDXbW8AjQF/7IigYIHObc3D7SQh77ju8OyTrg/s+e04Awgdbu+AHZ/uQB5P7KmulO1QHlYuL6dQZKAI9BB17xrt7QzCENduYB+jr/eiDkpmLo8TREs+7Bgevu0QHQ/uUO8f7ZAfmB2IHlgdUK1P7ByDSB/Zb5hBRofQHsnoDme/7pbyRCxoH62LEjLgHptF7+/oHI3uGB0EHxgc1AKYH9XsQBwU7EgfNKxcAsQe+a+tAJ9lkGYThKAe/2zSLyMATBCkH8zRw+6xIBpi/+0oh+HsEB/MrBQeCB8P7oQciB+EHudtlB1AH1/u3G7f7FevgYA/70IGTSCNAqAdHNKYrGAetEQ9rMGLJiYVYFsTN+wAHfAeEB9HrAwchB8UHVKulBxP7zStUK5+A0ksD20yblXqiJeil9Ad1srIy7HulOvDbmuvNFFv8rbrz7Ba7nTsCB907gwegB4MA7gB+AEyAfgDEi9YABADWAEP4MktgABIALIDNKyj4eMAni9gAAABaYAB2ANYAKADXy2AAxMAEACWAjKUY8AEAZYCBewCAKAB4AOTAXAAmB9CHLIDgeigA5CvUACgA/gBQACmLFMBCgEec/Xp0AMJ6LJW0pUSArQAgAJyQ46skh8SLqACkQENcCGuNAE5AtPjUq9srS/jUq+Y7fkzUq017RmLUq3Q7JQS0+DNLfduNAOtUqofUq5MHAFyp+GqHr9vDRFqHaiteq2/4GWuaKwkEGWvmO1aMGWsKh9KHtDsah2qEGWuv22t0GWs3++a0RofbK9hkRoeTB5ekWocjyxqHYPXk+CAAQ8uaK6oEfofbK7TggYczS/SbYodhnHqHIAC0e40AjdIJhzTrYofnMfGHI6teq3GHGpwNe16rb5wNe5or0pzxh3iLjQAi+DNLjXtJh+mHOYeJ62KHIpo+AIQrdgAOAGNAO/h1lPAU8kBQwDm78YBbVBAUysSBZMdMysCsAI5kF+SjlLB07+tkepSLn2ugAIoAJYtwh0QARADwAMoAaAAegMCAAAAKxAAAABLQhxAA9ovwAGQAS4dCAPAAK4ecLngAeADwAAAAavaLYIcAgKyVgwCfy+WHFOsAACoUgBTr64cUgPwAK4fAgDiLj4fPh6+H74dZGyAAddh/i2orNCs2B2wALMAgRwuHLCS7h114VMB5i7SlQICDAMXlf4v8CAAA0sCAaiuQR1cA0EdaoLBH1gDwR/+HAKN/i05AaIDSS80rmEe6ANhHpDBwR9jA/4fk1URHJEfAgGRH7qQUR6/gVEd4RzRHgwCqa8hHRwBoR+IAGEfMR5RHuEf4R4MAF2jxS+B6VIBQwGorwIAswORHgkfURwhH4gBOQCWLxEekR7JHrEdCRxxHikd3hyAAGIREAKpHAkfqR/JH/4fLh3+LuUC8R+orakcwR0ZHt4eDO3+L1OvwABTrK4ePh6uHD4cU65MsxkeER3VLs4fzh4uHWqCrhxuHW4c7h3uHWqCHh8eHp4frh/SHzIso+H4AjOW3h3RHdUtfh0+HL4dvhx+H4gCJRz+HKUfGR1xHdUsYhOZHGWuWRzhH1keKR6JHdUtUwI5HVMCKACzAAAD0O2vPh2or64fgelJH4gBlRyuHFUcUgAAAivWAAABy8iODABIgykeKAHpHjEcFR2xHwkfiAEXQ3EdkAHlH/EdQR4ZH7EcKR2wAUUAli6hH6EcjRxpHC0cAR0hHOUeKAAxH4gBMR7NHVkfzR/+HwiDLRzxHq0cGR4dHY0eLR/FHM0sqR8NHF0eFR0dHfUfZR7dHO0f6RwdHj0dXRwBHJUczS+B6LMC0m7AHYEcQRw9Ho0eaR2wAtOAli1Qrais7a+JH9STTh+IAUMcwx5XbhAT/h/Ijk0fTR2tHRUfgxx8edkdU6w5HTkcPhy5HbkdKR4MAckCnR1NH50cfR6DHG0e+gDOH8IcLh3uHy4fiAGuHRACbhyiAQUf7h6FHZzAnh+eHl4d0pbFHFKWNgMScoodrgBKHWyuNANKHzSuyhxaHzSsKh6aHFQcah7qHOYfqhzm7RYfKxzqHUYfUqwaHasdBh8aHjQCmhxorjQAWhwF7SYfGx7aHEof2hzm7jocv2xqHx4Suh0mHG0Hxh5lrYoeOxzmHNxtih1wU8Yf+hzm7mschhxqH2YdBh0PLEYf9gFqHMYcnAAHHM0uJhxyLjofU64WHVYdBh5mHjQARx7mHYod6+AWHYoeaxyWHQTXlh017cURahzWHJwB1hw1LyysIi9FH8ADAhxIAdYAUpUQrJIfwAMTAM4sMpaj4NQDEwGPpRwDDIEAAA="))
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/* 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 saveBomTable(output) {
|
|
var text = '';
|
|
for (var node of bomhead.childNodes[0].childNodes) {
|
|
if (node.firstChild) {
|
|
var name = node.firstChild.nodeValue ?? "";
|
|
text += (output == 'csv' ? `"${name}"` : name);
|
|
}
|
|
if (node != bomhead.childNodes[0].lastChild) {
|
|
text += (output == 'csv' ? ',' : '\t');
|
|
}
|
|
}
|
|
text += '\n';
|
|
for (var row of bombody.childNodes) {
|
|
for (var cell of row.childNodes) {
|
|
let val = '';
|
|
for (var node of cell.childNodes) {
|
|
if (node.nodeName == "INPUT") {
|
|
if (node.checked) {
|
|
val += '✓';
|
|
}
|
|
} else if ((node.nodeName == "MARK") || (node.nodeName == "A")) {
|
|
val += node.firstChild.nodeValue;
|
|
} else {
|
|
val += node.nodeValue;
|
|
}
|
|
}
|
|
if (output == 'csv') {
|
|
val = val.replace(/\"/g, '\"\"'); // pair of double-quote characters
|
|
if (isNumeric(val)) {
|
|
val = +val; // use number
|
|
} else {
|
|
val = `"${val}"`; // enclosed within double-quote
|
|
}
|
|
}
|
|
text += val;
|
|
if (cell != row.lastChild) {
|
|
text += (output == 'csv' ? ',' : '\t');
|
|
}
|
|
}
|
|
text += '\n';
|
|
}
|
|
|
|
if (output != 'clipboard') {
|
|
// To file: csv or txt
|
|
var blob = new Blob([text], {
|
|
type: `text/${output}`
|
|
});
|
|
saveFile(`${pcbdata.metadata.title}.${output}`, blob);
|
|
} else {
|
|
// To clipboard
|
|
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 isNumeric(str) {
|
|
/* https://stackoverflow.com/a/175787 */
|
|
return (typeof str != "string" ? false : !isNaN(str) && !isNaN(parseFloat(str)));
|
|
}
|
|
|
|
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,
|
|
valueAltRegex: 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"] = {};
|
|
var allList = getBomListByLayer('FB').flat();
|
|
for (var id in pcbdata.bom.fields) {
|
|
var ref_key = allList.find(item => item[1] == Number(id)) || [];
|
|
pcbdata.bom.parsedValues[id] = parseValue(pcbdata.bom.fields[id][index], ref_key[0] || '');
|
|
}
|
|
}
|
|
}
|
|
|
|
function parseValue(val, ref) {
|
|
var inferUnit = (unit, ref) => {
|
|
if (unit) {
|
|
unit = unit.toLowerCase();
|
|
if (unit == 'Ω' || unit == "ohm" || unit == "ohms") {
|
|
unit = 'r';
|
|
}
|
|
return unit[0];
|
|
}
|
|
|
|
var resarr = /^([a-z]+)\d+$/i.exec(ref);
|
|
switch (Array.isArray(resarr) && resarr[1].toLowerCase()) {
|
|
case "c": return 'f';
|
|
case "l": return 'h';
|
|
case "r":
|
|
case "rv": return 'r';
|
|
}
|
|
return null;
|
|
};
|
|
val = val.replace(/,/g, "");
|
|
var match = units.valueRegex.exec(val);
|
|
if (Array.isArray(match)) {
|
|
var unit = inferUnit(match[3], ref);
|
|
var val_i = parseFloat(match[1]);
|
|
if (!unit) return null;
|
|
if (match[2]) {
|
|
val_i = val_i * units.getMultiplier(match[2]);
|
|
}
|
|
return {
|
|
val: val_i,
|
|
unit: unit,
|
|
extra: match[4],
|
|
}
|
|
}
|
|
|
|
match = units.valueAltRegex.exec(val);
|
|
if (Array.isArray(match) && (match[1] || match[4])) {
|
|
var unit = inferUnit(match[2], ref);
|
|
var val_i = parseFloat(match[1] + "." + match[4]);
|
|
if (!unit) return null;
|
|
if (match[3]) {
|
|
val_i = val_i * units.getMultiplier(match[3]);
|
|
}
|
|
return {
|
|
val: val_i,
|
|
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 resetSettings() {
|
|
if (!confirm(
|
|
`This will reset all checkbox states and other settings.\n\n` +
|
|
`Press OK if you want to continue.`)) {
|
|
return;
|
|
}
|
|
if (storage) {
|
|
var keys = [];
|
|
for (var i = 0; i < storage.length; i++) {
|
|
var key = storage.key(i);
|
|
if (key.startsWith(storagePrefix)) keys.push(key);
|
|
}
|
|
for (var key of keys) storage.removeItem(key);
|
|
}
|
|
location.reload();
|
|
}
|
|
|
|
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;
|
|
setHighlightRowOnClick(settings.highlightRowOnClick);
|
|
document.getElementById("highlightRowOnClickCheckbox").checked = settings.highlightRowOnClick;
|
|
setDarkMode(settings.darkMode);
|
|
document.getElementById("darkmodeCheckbox").checked = settings.darkMode;
|
|
setHighlightPin1(settings.highlightpin1);
|
|
document.forms.highlightpin1.highlightpin1.value = settings.highlightpin1;
|
|
writeStorage("boardRotation", settings.boardRotation);
|
|
document.getElementById("boardRotation").value = settings.boardRotation / 5;
|
|
document.getElementById("rotationDegree").textContent = settings.boardRotation;
|
|
setOffsetBackRotation(settings.offsetBackRotation);
|
|
document.getElementById("offsetBackRotationCheckbox").checked = settings.offsetBackRotation;
|
|
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: "FB",
|
|
bomlayout: "left-right",
|
|
bommode: "grouped",
|
|
checkboxes: [],
|
|
checkboxStoredRefs: {},
|
|
darkMode: false,
|
|
highlightpin1: "none",
|
|
redrawOnDrag: true,
|
|
boardRotation: 0,
|
|
offsetBackRotation: false,
|
|
renderPads: true,
|
|
renderReferences: true,
|
|
renderValues: true,
|
|
renderSilkscreen: true,
|
|
renderFabrication: true,
|
|
renderDnpOutline: false,
|
|
renderTracks: true,
|
|
renderZones: true,
|
|
columnOrder: [],
|
|
hiddenColumns: [],
|
|
netColors: {},
|
|
}
|
|
|
|
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 (settings.bommode == "netlist" && !pcbdata.nets) {
|
|
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;
|
|
|
|
var highlightpin1 = readStorage("highlightpin1") || config.highlight_pin1;
|
|
if (highlightpin1 === "false") highlightpin1 = "none";
|
|
if (highlightpin1 === "true") highlightpin1 = "all";
|
|
setHighlightPin1(highlightpin1);
|
|
document.forms.highlightpin1.highlightpin1.value = highlightpin1;
|
|
|
|
settings.markWhenChecked = readStorage("markWhenChecked");
|
|
if (settings.markWhenChecked == null) {
|
|
settings.markWhenChecked = config.mark_when_checked;
|
|
}
|
|
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("highlightRowOnClick", false, "highlightRowOnClickCheckbox", setHighlightRowOnClick);
|
|
initBooleanSetting("darkmode", config.dark_mode, "darkmodeCheckbox", setDarkMode);
|
|
|
|
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;
|
|
initBooleanSetting("offsetBackRotation", config.offset_back_rotation, "offsetBackRotationCheckbox", setOffsetBackRotation);
|
|
|
|
settings.netColors = JSON.parse(readStorage("netColors")) || {};
|
|
}
|
|
|
|
// 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";
|
|
if ("svgpath" in text) {
|
|
if ("thickness" in text) {
|
|
ctx.lineWidth = text.thickness;
|
|
ctx.stroke(new Path2D(text.svgpath));
|
|
} else if ("fillrule" in text) {
|
|
ctx.fill(new Path2D(text.svgpath), text.fillrule);
|
|
}
|
|
ctx.restore();
|
|
return;
|
|
}
|
|
ctx.lineWidth = text.thickness;
|
|
if ("polygons" in text) {
|
|
ctx.fill(getPolygonsPath(text));
|
|
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 (config.kicad_text_formatting) {
|
|
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 if (pad.drillshape == "rect") {
|
|
ctx.fill(getChamferedRectPath(pad.drillsize, 0, 0, 0));
|
|
} 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.lineWidth = 3 / scalefactor;
|
|
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);
|
|
}
|
|
}
|
|
ctx.lineWidth = 3 / scalefactor;
|
|
// 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 == "all" ||
|
|
settings.highlightpin1 == "selected" && highlight)) {
|
|
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, defaultColor, highlight) {
|
|
ctx = canvas.getContext("2d");
|
|
ctx.lineCap = "round";
|
|
|
|
var hasHole = (track) => (
|
|
'drillsize' in track &&
|
|
track.start[0] == track.end[0] &&
|
|
track.start[1] == track.end[1]);
|
|
|
|
// First draw tracks and tented vias
|
|
for (var track of pcbdata.tracks[layer]) {
|
|
if (highlight && highlightedNet != track.net) continue;
|
|
if (!hasHole(track)) {
|
|
ctx.strokeStyle = highlight ? defaultColor : settings.netColors[track.net] || defaultColor;
|
|
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();
|
|
}
|
|
}
|
|
// Second pass to draw untented vias
|
|
var style = getComputedStyle(topmostdiv);
|
|
var holeColor = style.getPropertyValue('--pad-hole-color')
|
|
|
|
for (var track of pcbdata.tracks[layer]) {
|
|
if (highlight && highlightedNet != track.net) continue;
|
|
if (hasHole(track)) {
|
|
ctx.strokeStyle = highlight ? defaultColor : settings.netColors[track.net] || defaultColor;
|
|
ctx.lineWidth = track.width;
|
|
ctx.beginPath();
|
|
ctx.moveTo(...track.start);
|
|
ctx.lineTo(...track.end);
|
|
ctx.stroke();
|
|
ctx.strokeStyle = holeColor;
|
|
ctx.lineWidth = track.drillsize;
|
|
ctx.lineTo(...track.end);
|
|
ctx.stroke();
|
|
}
|
|
}
|
|
}
|
|
|
|
function drawZones(canvas, layer, defaultColor, highlight) {
|
|
ctx = canvas.getContext("2d");
|
|
ctx.lineJoin = "round";
|
|
for (var zone of pcbdata.zones[layer]) {
|
|
if (highlight && highlightedNet != zone.net) continue;
|
|
ctx.strokeStyle = highlight ? defaultColor : settings.netColors[zone.net] || defaultColor;
|
|
ctx.fillStyle = highlight ? defaultColor : settings.netColors[zone.net] || defaultColor;
|
|
if (!zone.path2d) {
|
|
zone.path2d = getPolygonsPath(zone);
|
|
}
|
|
ctx.fill(zone.path2d, zone.fillrule || "nonzero");
|
|
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.renderZones) {
|
|
var zoneColor = style.getPropertyValue(highlight ? '--zone-color-highlight' : '--zone-color');
|
|
drawZones(canvas, layer, zoneColor, highlight);
|
|
}
|
|
if (settings.renderTracks) {
|
|
var trackColor = style.getPropertyValue(highlight ? '--track-color-highlight' : '--track-color');
|
|
drawTracks(canvas, layer, trackColor, 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);
|
|
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 + (flip && settings.offsetBackRotation ? - 180 : 0)));
|
|
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, flip) {
|
|
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 + (flip && settings.offsetBackRotation ? - 180 : 0)));
|
|
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 flip = (layerdict.layer === "B");
|
|
var bbox = applyRotation(pcbdata.edges_bbox, flip);
|
|
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;
|
|
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;
|
|
var flip = layerdict.layer === "B";
|
|
if (flip) {
|
|
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 + (flip && settings.offsetBackRotation ? - 180 : 0));
|
|
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 setOffsetBackRotation(value) {
|
|
settings.offsetBackRotation = value;
|
|
writeStorage("offsetBackRotation", value);
|
|
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("user-select");
|
|
|
|
// 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();
|
|
if (initDone) {
|
|
populateBomTable();
|
|
}
|
|
}
|
|
|
|
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 setHighlightRowOnClick(value) {
|
|
settings.highlightRowOnClick = value;
|
|
writeStorage("highlightRowOnClick", value);
|
|
if (initDone) {
|
|
populateBomTable();
|
|
}
|
|
}
|
|
|
|
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 createCheckboxHandlers(input, checkbox, references, row) {
|
|
var clickHandler = () => {
|
|
refsSet = getStoredCheckboxRefs(checkbox);
|
|
var markWhenChecked = settings.markWhenChecked == checkbox;
|
|
eventArgs = {
|
|
checkbox: checkbox,
|
|
refs: references,
|
|
}
|
|
if (input.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);
|
|
}
|
|
|
|
return [
|
|
(e) => {
|
|
clickHandler();
|
|
},
|
|
(e) => {
|
|
e.preventDefault();
|
|
if (row.onmousemove) row.onmousemove();
|
|
},
|
|
(e) => {
|
|
e.preventDefault();
|
|
input.checked = !input.checked;
|
|
input.indeterminate = false;
|
|
clickHandler();
|
|
}
|
|
];
|
|
}
|
|
|
|
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 updateNetColors() {
|
|
writeStorage("netColors", JSON.stringify(settings.netColors));
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function netColorChangeHandler(net) {
|
|
return (event) => {
|
|
settings.netColors[net] = event.target.value;
|
|
updateNetColors();
|
|
}
|
|
}
|
|
|
|
function netColorRightClick(net) {
|
|
return (event) => {
|
|
if (event.button == 2) {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
var style = getComputedStyle(topmostdiv);
|
|
var defaultNetColor = style.getPropertyValue('--track-color').trim();
|
|
event.target.value = defaultNetColor;
|
|
delete settings.netColors[net];
|
|
updateNetColors();
|
|
}
|
|
}
|
|
}
|
|
|
|
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 (String(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 getBomListByLayer(layer) {
|
|
switch (layer) {
|
|
case 'F': return pcbdata.bom.F.slice();
|
|
case 'B': return pcbdata.bom.B.slice();
|
|
case 'FB': return pcbdata.bom.both.slice();
|
|
}
|
|
return [];
|
|
}
|
|
|
|
function getSelectedBomList() {
|
|
if (settings.bommode == "netlist") {
|
|
return pcbdata.nets.slice();
|
|
}
|
|
var out = getBomListByLayer(settings.canvaslayout);
|
|
|
|
if (settings.bommode == "ungrouped") {
|
|
// expand bom table
|
|
var expandedTable = [];
|
|
for (var bomentry of out) {
|
|
for (var ref of bomentry) {
|
|
expandedTable.push([ref]);
|
|
}
|
|
}
|
|
return expandedTable;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
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") {
|
|
tr.appendChild(createColumnHeader("Net name", "bom-netname", (a, b) => {
|
|
if (a > b) return -1;
|
|
if (a < b) return 1;
|
|
return 0;
|
|
}));
|
|
tr.appendChild(createColumnHeader("Color", "bom-color", (a, b) => {
|
|
return 0;
|
|
}));
|
|
} 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][0] != b[i][0]) 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) {
|
|
const urlRegex = /^(https?:\/\/[^\s\/$.?#][^\s]*|file:\/\/([a-zA-Z]:|\/)[^\x00]+)$/;
|
|
while (bom.firstChild) {
|
|
bom.removeChild(bom.firstChild);
|
|
}
|
|
highlightHandlers = [];
|
|
footprintIndexToHandler = {};
|
|
netsToHandler = {};
|
|
currentHighlightedRowId = null;
|
|
var first = true;
|
|
var style = getComputedStyle(topmostdiv);
|
|
var defaultNetColor = style.getPropertyValue('--track-color').trim();
|
|
|
|
bomtable = getSelectedBomList();
|
|
|
|
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);
|
|
var color = settings.netColors[netname] || defaultNetColor;
|
|
td = document.createElement("TD");
|
|
var colorBox = document.createElement("INPUT");
|
|
colorBox.type = "color";
|
|
colorBox.value = color;
|
|
colorBox.onchange = netColorChangeHandler(netname);
|
|
colorBox.onmouseup = netColorRightClick(netname);
|
|
colorBox.oncontextmenu = (e) => e.preventDefault();
|
|
td.appendChild(colorBox);
|
|
td.classList.add("color-column");
|
|
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, td.ontouchstart, td.ontouchend] = createCheckboxHandlers(input, 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");
|
|
var output = new Array();
|
|
for (let item of valueSet) {
|
|
const visible = highlightFilter(String(item));
|
|
if (typeof item === 'string' && item.match(urlRegex)) {
|
|
output.push(`<a href="${item}" target="_blank">${visible}</a>`);
|
|
} else {
|
|
output.push(visible);
|
|
}
|
|
}
|
|
td.innerHTML = output.join(", ");
|
|
tr.appendChild(td);
|
|
}
|
|
});
|
|
}
|
|
bom.appendChild(tr);
|
|
var handler = createRowHighlightHandler(tr.id, references, netname);
|
|
if (settings.highlightRowOnClick) {
|
|
tr.onmousedown = handler;
|
|
} else {
|
|
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("topmostdiv").style.height = "";
|
|
document.getElementById("topmostdiv").style.display = "block";
|
|
break;
|
|
case 'top-bottom':
|
|
document.getElementById("tb-btn").classList.add("depressed");
|
|
document.getElementById("frontcanvas").style.display = "";
|
|
document.getElementById("backcanvas").style.display = "";
|
|
document.getElementById("topmostdiv").style.height = "100%";
|
|
document.getElementById("topmostdiv").style.display = "flex";
|
|
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("topmostdiv").style.height = "100%";
|
|
document.getElementById("topmostdiv").style.display = "flex";
|
|
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 childNum = checkboxnum + settings.columnOrder.indexOf("checkboxes");
|
|
var checkbox = bomrow.childNodes[childNum].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 childNum = checkboxnum + 1 + settings.columnOrder.indexOf("checkboxes");
|
|
var checkbox = bomrow.childNodes[childNum].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) + "%)";
|
|
}
|
|
|
|
function constrain(number, min, max) {
|
|
return Math.min(Math.max(parseInt(number), min), max);
|
|
}
|
|
|
|
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;
|
|
case "ArrowLeft":
|
|
case "ArrowRight":
|
|
if (document.activeElement.type != "text") {
|
|
e.preventDefault();
|
|
let boardRotationElement = document.getElementById("boardRotation")
|
|
settings.boardRotation = parseInt(boardRotationElement.value); // degrees / 5
|
|
if (e.key == "ArrowLeft") {
|
|
settings.boardRotation += 3; // 15 degrees
|
|
}
|
|
else {
|
|
settings.boardRotation -= 3;
|
|
}
|
|
settings.boardRotation = constrain(settings.boardRotation, boardRotationElement.min, boardRotationElement.max);
|
|
boardRotationElement.value = settings.boardRotation
|
|
setBoardRotation(settings.boardRotation);
|
|
}
|
|
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";
|
|
}
|
|
|
|
function topToggle() {
|
|
var top = document.getElementById("top");
|
|
var toptoggle = document.getElementById("toptoggle");
|
|
if (top.style.display === "none") {
|
|
top.style.display = "flex";
|
|
toptoggle.classList.remove("flipped");
|
|
} else {
|
|
top.style.display = "none";
|
|
toptoggle.classList.add("flipped");
|
|
}
|
|
}
|
|
|
|
window.onload = function (e) {
|
|
initRender();
|
|
initStorage();
|
|
initDefaults();
|
|
initUtils();
|
|
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 id="fileinfodiv">
|
|
<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 id="bomcontrols">
|
|
<div class="hideonprint menu">
|
|
<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="highlightRowOnClickCheckbox" type="checkbox" checked onchange="setHighlightRowOnClick(this.checked)">
|
|
Highlight row on click
|
|
</label>
|
|
<label class="menu-label">
|
|
<input id="dragCheckbox" type="checkbox" checked onchange="setRedrawOnDrag(this.checked)">
|
|
Continuous redraw on drag
|
|
</label>
|
|
<label class="menu-label">
|
|
Highlight first pin
|
|
<form id="highlightpin1">
|
|
<div class="flexbox">
|
|
<label>
|
|
<input type="radio" name="highlightpin1" value="none" onchange="setHighlightPin1('none')">
|
|
None
|
|
</label>
|
|
<label>
|
|
<input type="radio" name="highlightpin1" value="all" onchange="setHighlightPin1('all')">
|
|
All
|
|
</label>
|
|
<label>
|
|
<input type="radio" name="highlightpin1" value="selected" onchange="setHighlightPin1('selected')">
|
|
Selected
|
|
</label>
|
|
</div>
|
|
</form>
|
|
</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">
|
|
<input id="offsetBackRotationCheckbox" type="checkbox" onchange="setOffsetBackRotation(this.checked)">
|
|
Offset back rotation
|
|
</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>
|
|
<a target="blank" title="Mouse and keyboard help" href="https://github.com/openscopeproject/InteractiveHtmlBom/wiki/Usage#bom-page-mouse-actions" style="text-decoration: none;"><label class="help-link">?</label></a>
|
|
</span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="button-container hideonprint">
|
|
<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">
|
|
<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">
|
|
<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">
|
|
<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">
|
|
<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>
|
|
<button class="savebtn" onclick="resetSettings()">Reset</button>
|
|
</div>
|
|
</div>
|
|
<div class="menu-label">
|
|
<span style="margin-left: 5px;">Save bom table as</span>
|
|
<div class="flexbox">
|
|
<button class="savebtn" onclick="saveBomTable('csv')">csv</button>
|
|
<button class="savebtn" onclick="saveBomTable('txt')">txt</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="topdivider">
|
|
<div class="hideonprint">
|
|
<div id="toptoggle" onclick="topToggle()">︽</div>
|
|
</div>
|
|
</div>
|
|
<div id="bot" class="split" style="flex: 1 1">
|
|
<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="saveBomTable('clipboard')"></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>
|