You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
4670 lines
316 KiB
4670 lines
316 KiB
<!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;
|
|
}
|
|
|
|
#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;
|
|
}
|
|
/* #bomhead {
|
|
position: sticky;
|
|
top: 0px;
|
|
z-index: 1;
|
|
} */
|
|
</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": true, "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, "fields": ["Value", "Footprint", "Disti", "Disti_No", "Man", "Man_No"]}
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
var pcbdata = JSON.parse(LZString.decompressFromBase64("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wB2DdhyTg2hDcHuXg334GYNow2D0lGACw2j9c0N0VwJDef17HXpDet12Q3QAHkN7fXFDdYAZQ3d9ZdfToxoDcH1xDJ6AEb1gzVdDch1xg334Gn1g9JvZjMNkAA7DZ4NqI3WAGsNgQ3jDfMNng2HDc91qihltbMRFw3l9eyNmQ2ntaIAF7WVtS8NgwAJtaUNybWVDcl8WHZfQI0N2IBvaDQNx7Xm9exAPQ2jcGSNkABUjcEN7hZ4jcSNkQ3Oje6N9I2EjeEN0Q30gBGIRvWVgXN1l/W3Dbj1hqhyjcqN3w3qjf8Npd5IuGg63rBgjY8AJo262xaNzA3a23oNjo2DDasN/g2ejbiN1oAuDYsNwY2TjeGN/o2xjfyACY2RdamNqPWZjdj1q3Z5jfwN7vXCDeWNovWLems+eo3NjcaNn4AD9daNz/pIjaONlI3rjdiN+wo+jdGNq42bDYuNzI2PdfuNukFX9UkNl4239fcN9433tYINqo3iDYiKMOhniUuwBo37jdS+NQaQTckAdo3LDYhN+E3WADON2w3YTfBNro3ITYRNkQ2sjc8AHI34GDyN6Y3XDdeN/HXHsgWNnw2QAD8Nn42IiglcQ4kWigBNkk2wjdoNlvXKTbhNtI2oTY4N842MjYGNxk2hjfpN+w2kTal0XI2bSSkN3k2P9f5Nj42FDa+NvE36oRwyWCxZkzuNyxhpTbF1to2wTbSKdU2TDasAGE3LjbVN5k2VTbuN7U3OTd1N9E3CjcxNw03sTc+N3E2ajcwcEnZZGslN602RdfCNrA37TdhyR03aTehN5U2RjddNh033TeTNxE2h9YjhKXQ0TZ5NjE25jYDN0bWcTaWN003SMSuK5j8IzdCNqM2ZTbtN7XX5TdONxM2NTaSNt02aTfTN1k2tTY5N7M38jdf1v038zbkNo03vDZNNkM2JpvFN55lD9aRNyM2yTb2Nug25TebNhU2nTffgF02mzdTNls3bjbZNr03Oze5Ngo32TZkNrE3CzaDN4s2QzdmqQk3EkArN0k2tCanN2U3YzcMNuc2EzaVNxs3VTeXNm83Wzc9Njs2qKBzNrc2HtYNNvs3AzeNN4M2VjaB4eXlduMlN7Y3gTYvNms3x9dnN+s27zZZNqk2mTZXN0Y22Tdf1SY2Ubj1NvM23jYLNrfWKjcFN4U2IDbvyaiGreMlNssjqDaJXCI3azcgt4Y26TZgtus2bjYQt8c37BYxXLs3ZjfQt7829zd/Ng83/zbvudFqCLbHN+vWwgC/Uas3QTbItx82oLdMNpM3bjeot+82rTfot40LULZ7Nt42E9eJ1yYAU9b/1zfWADZp15bVubV+FUA3UAEZ1kU3zmTIohYovOlgNrnWDACr1/94+dfINtk3hdc61sC3vOJwN6XX+zawt742IDY5NLR4myxfNk/WVtfJNq83ojcD1mI2Q9ZR1wntTdcX13M25Ld2N23WSjft1xy2d9b0tz5lSexylSU3zRGW1zXWZ7h8tqwY/LZv1gK2RXHnN5+An9c3N7s3tzcxNhS2f9eUt1gB/9Yz1wA2NLZy1lmThADANvEAIDfasZz0YDY51uA2edZr1hrWeLcoNhvWRdcClWy2ue3stvA2fzYHNks3SrAUeZXXOrZX10HWvLb6ttK3D0gyt4PWrBiN11qA0dcf1yPXZLcKtuPXijdKNw4cBTectky3trCQONnWJreyNqa2UrdrbWa3Ydf11ha3D0iWtsPW0QAX1xi39Tfj1rg3FLeT1jwBU9fe1tS2s9Y0t7PX8IAPSOq2mdZd1x6o2trL1lq2TLbMt3nXa9cIt7q2bLd91ga3ebUG16K2e9f/Nl5cQbcSt4fXprd91i/XGTcutoPWZ9dD1+/XbzYjKPK3njdCtja2E3nCAdfWyjaRtva2gbdXqNG3jrfZNzy2zrcHbC635rfxtwK2gg2Ctx620Lfx14q2Sdd/1sq3VLYqt9S36ChAAbPWJawBt2K236xoaUG2K9cMACG32rf51xm3rLab1ma229fCADvWEbd2tka3dZf0eUC2PLeStivIsbf0NyfWrrY5t7K2ibfPSEm31rc/NqbWqbZ2tmm3dbbgXBm3n4DXNjG2WbfF1iC2zbbxt2/WCbaCth638raYtvm2XrZKt962VLc+tkW3vrbFtgABlAAB1TQRarZ0twvWIDbQJbbkaDapGeW2PAFX6XYpoBgxxSU2ryiSACsjSLdPudvXcDe1tp22ajc0ZYNtDxikt/95yUb6tg43YLf8tq22Xshtt303ybfCth23dzcwtmK2IDbRZcNta7cQtvh8G7ZLt7G3ttcyt1u3crbWtju27ba2tqK2hractka3q7d9bXDMKzfrtvq8x7dNtmHXJ7e5toO2nrZ7tgg2RrYHthiiBkHXt+QBR7ZjNoS2d7eutwO3SbY/N1fXnraEN163BbcRtyO3WAEz1vEBadZyAf63k7fAN/a3WKrd19nWs7e512rXoBihtlW2YbbVtku34bdiATw3K7f/N0tpo6OJNr3XMbavt722r9fNtv23ObZWtzop27bJtue3KbcitjfXF7b7tgB2ziyat9G3TreNt9B3x7cwd322sreWt8PXVrZCth+2dzf5tpS3w7aFt9+2JtdFtqwBfrcsspO2Ctf/t4vWoJyi6OW3WrbAdiy3iTdVt3q2YHbLthy3SHeRt6W2E7AUeA233beZtmh39jZnNn22W7Zutu/WA7ZYdnm2wrbX14h3qbaUd2m3C8gCsV22jcA0do22BLYpNtm3r9eut47XLbb3t++2Crbttz/WRjZft0q237fT1j+3KrbFtnLWKAF/t4R36rf2tiVYgHcztyR3q9fAdjq23baRN2R3f1nkdzW3y7bgd/x3e7eUdiA3HoOQdqh37HdtNwS2MHasAXG29Hdcdph37raMd/e3ebdMd7a3D7c+N3W3Lm2idxJ2h9eodhx2m7c6N0p3d7fKdu62craNwfB22HaKt0O2Bbb8d8q3Anb4d9+AgDYAABUTtvLW/7Yid4vX1AG3eZq2QHdMt1hDedYCGSU2XNWaNkOAHHZ61hR3BrdYt4a2ajYUtbPpLLbotn2ktHYh16+2mDfn6YwAUADwAGN47gGruR3Z2TZeKtXR3gAe19e4vnaRgZdFTLbrBYJBXCl57PShMPnq12uJVoULO6n56tdqIEtFhqlI8d4B6tZHwKOBltdygJpAEXedZIYgIviVPLSF0Xbrc6mhcXchtjO3qtYxdmOx4neHQVrBcXaRdnIp6tdRdlDFoXc8sdq2FVvXuMF2lMFWhPnWzsChdgF3TwCVt353MPlgGPnXeXc+dn4ALLaFdl4qRXb7udx3bbcft+e2SHaOdpe2TnaWd6r517cb1q52aBgut3e277aldnc2MLaPthV2qyOh5xm2GGBRdvZ3ZrYWAO52Hnaedqu5ogFed/l3gXfVAPl2yCm5d+J2MEntdoV3wXYHydl3VsGp+D5cS0Xq1pl2IQGmSBCBXChpd/5hAARJd895oXaFy71263LBdgN28XaJd9k2bM3PebF2KXbyAQN3kXfgYWl2w3bE9WF3E1u+d5MhgoXgYe/Jo3Y+wJ127Xb+dn52QXaFdn2lmXeRaj528gBpdwl383bCAcV3agE1d2e3H7e8d7/WRna4dzJ2vra/tjS2AAE1Znfz1+Z3AbcLySXVyyKMtsG3K9YQjDZ2Ada2dvh9uhQcdnpBYHaMATJ3dXcQduFbcNmUoCs2BCjMGk23DjYnt2+2qnY8d4O3anYXtuV2yHaBt6ZJ30kx6Yk3JaEb1lJ3UrZud6I2NXdPdrV3/TZYtrJ3LHb5PMFpXpaHtui393dInQ93m7ffdvB2Z7YIdzt2dXYadvV2qVvpXEtTDXfOHA92X3eKdt92T3Yg91h3PHc7djh23rdiAD62And4d6O3+HbEgMJ3dLdTt9qN6twkd8G22redd853eLYF2WG30HbXd+B2LHeXt2Epx1l2Nw22NddVd8C26HZKd9m3sHbcd9t2oPaKNoh26nZg9403l7dUbTj2iV2490/XtHacdrB3GHbn1qe3+ncg9wZ25jdw91+2xnaI9gd2xbez16UAyPZTt/a2ciUX3FZ3YnfMtiB2Wna6thz4mPcU9jW3rAC1tjJ2dbartjj2ZYJQdj23ePaKd/j3fLecdi23lrb6d2AABnew9sT3rAG7tyT3jnf/N+PBOYPK12x32zc0d9p2dHfodsp3brcJtyV2O3fYd4Z3OHfw9iO3CPc/tjLWqrYpAYz2RHYndnSpfdpLbGd2Fbdo96R3obbs96B3mPYOdiu22PZqNsWZRMMA91p2CnfJNjp2cbcE9lT3UdeYdzD3jHc7ti93ZXZ/dka3/xlMFDr2Qda69xu3kvYE9/z2hPYqdoL2QvfPdp+2fHbDt3L3uHfy9oJ2rADp1mq25nfCd8d2++nK9jC1gHcs9pt36Pds9xj2GvfOtxz2+tcUdq93snYAd60Ber2m9ya3ZvdA9zp2+vcWtgx3bIRW9jT3QvfcNmV3zHae9393RryfgM73GbdQdz23k3m3thb3lPd+9/23/vbU94L3AfbW9rt3E9Z7drb2+3ajt/T29vdI9oR3yPf2t4G3mnaW1VZ3Fbbo9mR2oHbkdxr20nce98b3Wvbndsn2Xzbadwp3HHdfd9K3Fvf69ih2Afaw9tb2Qfcdtlr2UbedZSh3ofcglhT3pzaU9hh2kfZwdwb3ibfR9g+3tPdGd4W3xneI99+BfrYO90d2jvelt04Jvlk/yc72aPakd6z34vYY9lV3n3e611d2mvZc9h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JOrE65jsJOi47sTkuONE9KTxpOXE8CTvRON4/yT7hOvbeQTrpOok8cTu+OgY+NjnJOBk5sD6hPsjemj6pOeE9GT9JPuk4mTmJOpk7Zj7BO73aSTjR2Uk8KTiJOJI8Oj0xPtE6aT9Wt30itsbMPX4/rjlRO547GTkpP1k7KTs5PYyI5j/4Ahk9uT+hOwE4cTk5P/Y4CTk+On4+R2S8OIY4vjoxO+E4yThpPDY/KT0+PBdiHDnuO349BTqRO1k5+TqBOoU83uQFOrk60N4BOOk6KTo5P7o/ijpxOWE6ID/SPgg8uToBPsY/CTumPVk/GT5FOTo+eTwtSLk7rDslOtY5qTu5OqU4eTmlOj476Tz8OSU8ZTuFObk4RT5uOkU8yT05OuU5HWeOP0U6ZTvuORk8kTwVPqU+FT35Pyk8VEBlPYU/Pj+FOKU9lj+5Pvk/lTlFO6U4SZcsiVU9Cj65OsU9sTnFOiE6FTiFPBE91ThAOJU75T41PUk7UTvcPjk+1T2lPRU5ejhxO8k7aT8ROBU/sTp1OLU/8TxVO1Y5hToFOk45BT9VPvE6+T31P8U8mT1mPiA4bBoNOMU5nj+1O6k/BTqNONk5jT1r3C7fjTyVOPk86TtlOtU79TrJPdU5nBrNPbU/JT7FPDk7NTuVOC05FTolO2o+VXUlPS0+ZT5ZOZU59TvFPCY+Xj2JOabcyDsmPTV12T9s3uo5zTz4POg9iDpc34g6fN3oO43gEKXx0f48LT2QPbg5ctzNOT+Bfj+N3B07HTkS3nTZHT9wPrzZ6NidOV9anTxWDSE87TudPNg/TDxdPxQ/F9gdOw4479q/3nzZ0D5833bf3TsnzD082T7tOTAfJj2cnPPcvTsNO4Lcv9hs2Pg7XT3v2MzcnT5bWn0+YTo9OMg/nTkn3M0+GQdG2v0/LT7dOKLb/T6/3Tg90D9s3H08GDyFOu08gzoG2/tcGTi9PjXe/T69OkM9vTlDP707QzkDOMM8tT49OcLbPD0rWl08/TgjP4M+ONls2b0/Et0jPd0+yN9DOO05fT7DOpXrGcOaYGM8zdq9O0zdYz7v2AM6WDofWuM8zjhVOsM5PT2sP+M9bEQTPcE8IzkTPiM7YzodOyM8kzijPuM9Zj19O4rbGcGDP8M6EzlTOWM7UzsTOEM4kz4DP4GFAzglPwM5uDuTOSfdFDgKVYM8Yzk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e56QEpX+ABH14ur+ABhl5ZtEQA5Z6IAZTeY7eRXugApneIAeABU4ERXwoA8AEednDe91+EABHBbl7xUPVfi15AAFTexgHU319eRQHKX4QBhl9+FRkBeACcrnO2ta8ZADP2AAC1V+joAQd3V+jGXkHBqN5lX7fWpECbXxVejl//X9tfWAB9XrteQABuXqRBCN4HXkAASN5HX8W2x14nXuLh/l+nX6jfHV+31ygAL14VXzDeTl8Y30zfmN6S3jle1sXyX1LebN4y3sjfqABy34rf8t6iXpNeit4oAZ1e6l7K3j1e4t+CX3Dful9Y3sdeEN4g3iZeoN+43mDfo143z9jfBN4TXqJf618637rff1/o38rf+t4S34Dfht9m3sbfON7S3njfpt+y17bekN4qX2delt5/X7LXet7bXr1f4t6A3obeVADY3/je417m33bebN/23uDfA14E3nbeKl6/XzreSt7TX1be+t+u3gbezN+7XzWfat/q355eh18y3h5eK14o35kp8l7a31gBZB52Xv7fm14B3q7fAN8G3vNewd56QOreHl/7Xhreod6a38de4d9a3rZeRN4tnpwANN5YgNAB7QEvX4gAM/bAAG/pRtd8X2nfeAAXXnytjN/gAAAA1UbXeZ9FnqXuD0iF34QAtl/C3io30N9K39HfsN5u3rHfQd4C33tf8d6439Leid4VX7Le4d+rXqjfhAB/tuXWRQGGXhJfOUCoAAAB6bPW6AAAADQPSAABFDYAEl4JrugB1+jmXqZ34ABUANAAVAC53qZ2FxC53h3epADQAKQAud7GX5oBRtcUAWwBud4IAEQB9ABF3iPeZZ5F32oAjQE+1sgBUd+i3t1fYt6B3jbful5q39xA8d4m35Xey19V32Hffl/j3xHeQAFRH2jeet6l3ireZd5B3pLett8e3sDedt6z3t7e+N4+3p7evt5j307fxd8bXjDey9/W327fsd/l3gjfFd7S3xrfc9/I3qteVACnXrZeft4qN91xZgE73mLeGN+732Xfqt7FX+CBM94J3yHec99HXvPeAYHyXvsBvjeLAOPeKAAT3y7fpd+B3qrebl/B3gffCd433rLet9/h3wve0IE+1rLWqd68XsgBad6193TeiAEZ35neRgFZ39kAOd9nILnfed6fSNm1Bd8j3kAAhd+BX7Zft9YAAPwPSR9IiAAIAM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"))
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/* 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) {
|
|
text += (output == 'csv' ? `"${node.firstChild.nodeValue}"` : node.firstChild.nodeValue);
|
|
}
|
|
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,
|
|
}
|
|
|
|
function initUtils() {
|
|
var allPrefixes = units.prefixes.giga
|
|
.concat(units.prefixes.mega)
|
|
.concat(units.prefixes.kilo)
|
|
.concat(units.prefixes.milli)
|
|
.concat(units.prefixes.micro)
|
|
.concat(units.prefixes.nano)
|
|
.concat(units.prefixes.pico);
|
|
var allUnits = units.unitsShort.concat(units.unitsLong);
|
|
units.valueRegex = new RegExp("^([0-9\.]+)" +
|
|
"\\s*(" + allPrefixes.join("|") + ")?" +
|
|
"(" + allUnits.join("|") + ")?" +
|
|
"(\\b.*)?$", "");
|
|
units.valueAltRegex = new RegExp("^([0-9]*)" +
|
|
"(" + units.unitsShort.join("|") + ")?" +
|
|
"([GgMmKkUuNnPp])?" +
|
|
"([0-9]*)" +
|
|
"(\\b.*)?$", "");
|
|
if (config.fields.includes("Value")) {
|
|
var index = config.fields.indexOf("Value");
|
|
pcbdata.bom["parsedValues"] = {};
|
|
for (var id in pcbdata.bom.fields) {
|
|
pcbdata.bom.parsedValues[id] = parseValue(pcbdata.bom.fields[id][index])
|
|
}
|
|
}
|
|
}
|
|
|
|
function parseValue(val, ref) {
|
|
var inferUnit = (unit, ref) => {
|
|
if (unit) {
|
|
unit = unit.toLowerCase();
|
|
if (unit == 'Ω' || unit == "ohm" || unit == "ohms") {
|
|
unit = 'r';
|
|
}
|
|
unit = unit[0];
|
|
} else {
|
|
ref = /^([a-z]+)\d+$/i.exec(ref);
|
|
if (ref) {
|
|
ref = ref[1].toLowerCase();
|
|
if (ref == "c") unit = 'f';
|
|
else if (ref == "l") unit = 'h';
|
|
else if (ref == "r" || ref == "rv") unit = 'r';
|
|
else unit = null;
|
|
}
|
|
}
|
|
return unit;
|
|
};
|
|
val = val.replace(/,/g, "");
|
|
var match = units.valueRegex.exec(val);
|
|
var unit;
|
|
if (match) {
|
|
val = parseFloat(match[1]);
|
|
if (match[2]) {
|
|
val = val * units.getMultiplier(match[2]);
|
|
}
|
|
unit = inferUnit(match[3], ref);
|
|
if (!unit) return null;
|
|
else return {
|
|
val: val,
|
|
unit: unit,
|
|
extra: match[4],
|
|
}
|
|
}
|
|
match = units.valueAltRegex.exec(val);
|
|
if (match && (match[1] || match[4])) {
|
|
val = parseFloat(match[1] + "." + match[4]);
|
|
if (match[3]) {
|
|
val = val * units.getMultiplier(match[3]);
|
|
}
|
|
unit = inferUnit(match[2], ref);
|
|
if (!unit) return null;
|
|
else return {
|
|
val: val,
|
|
unit: unit,
|
|
extra: match[5],
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function valueCompare(a, b, stra, strb) {
|
|
if (a === null && b === null) {
|
|
// Failed to parse both values, compare them as strings.
|
|
if (stra != strb) return stra > strb ? 1 : -1;
|
|
else return 0;
|
|
} else if (a === null) {
|
|
return 1;
|
|
} else if (b === null) {
|
|
return -1;
|
|
} else {
|
|
if (a.unit != b.unit) return a.unit > b.unit ? 1 : -1;
|
|
else if (a.val != b.val) return a.val > b.val ? 1 : -1;
|
|
else if (a.extra != b.extra) return a.extra > b.extra ? 1 : -1;
|
|
else return 0;
|
|
}
|
|
}
|
|
|
|
function validateSaveImgDimension(element) {
|
|
var valid = false;
|
|
var intValue = 0;
|
|
if (/^[1-9]\d*$/.test(element.value)) {
|
|
intValue = parseInt(element.value);
|
|
if (intValue <= 16000) {
|
|
valid = true;
|
|
}
|
|
}
|
|
if (valid) {
|
|
element.classList.remove("invalid");
|
|
} else {
|
|
element.classList.add("invalid");
|
|
}
|
|
return intValue;
|
|
}
|
|
|
|
function saveImage(layer) {
|
|
var width = validateSaveImgDimension(document.getElementById("render-save-width"));
|
|
var height = validateSaveImgDimension(document.getElementById("render-save-height"));
|
|
var bgcolor = null;
|
|
if (!document.getElementById("render-save-transparent").checked) {
|
|
var style = getComputedStyle(topmostdiv);
|
|
bgcolor = style.getPropertyValue("background-color");
|
|
}
|
|
if (!width || !height) return;
|
|
|
|
// Prepare image
|
|
var canvas = document.createElement("canvas");
|
|
var layerdict = {
|
|
transform: {
|
|
x: 0,
|
|
y: 0,
|
|
s: 1,
|
|
panx: 0,
|
|
pany: 0,
|
|
zoom: 1,
|
|
},
|
|
bg: canvas,
|
|
fab: canvas,
|
|
silk: canvas,
|
|
highlight: canvas,
|
|
layer: layer,
|
|
}
|
|
// Do the rendering
|
|
recalcLayerScale(layerdict, width, height);
|
|
prepareLayer(layerdict);
|
|
clearCanvas(canvas, bgcolor);
|
|
drawBackground(layerdict, false);
|
|
drawHighlightsOnLayer(layerdict, false);
|
|
|
|
// Save image
|
|
var imgdata = canvas.toDataURL("image/png");
|
|
|
|
var filename = pcbdata.metadata.title;
|
|
if (pcbdata.metadata.revision) {
|
|
filename += `.${pcbdata.metadata.revision}`;
|
|
}
|
|
filename += `.${layer}.png`;
|
|
saveFile(filename, dataURLtoBlob(imgdata));
|
|
}
|
|
|
|
function saveSettings() {
|
|
var data = {
|
|
type: "InteractiveHtmlBom settings",
|
|
version: 1,
|
|
pcbmetadata: pcbdata.metadata,
|
|
settings: settings,
|
|
}
|
|
var blob = new Blob([JSON.stringify(data, null, 4)], {
|
|
type: "application/json"
|
|
});
|
|
saveFile(`${pcbdata.metadata.title}.settings.json`, blob);
|
|
}
|
|
|
|
function loadSettings() {
|
|
var input = document.createElement("input");
|
|
input.type = "file";
|
|
input.accept = ".settings.json";
|
|
input.onchange = function (e) {
|
|
var file = e.target.files[0];
|
|
var reader = new FileReader();
|
|
reader.onload = readerEvent => {
|
|
var content = readerEvent.target.result;
|
|
var newSettings;
|
|
try {
|
|
newSettings = JSON.parse(content);
|
|
} catch (e) {
|
|
alert("Selected file is not InteractiveHtmlBom settings file.");
|
|
return;
|
|
}
|
|
if (newSettings.type != "InteractiveHtmlBom settings") {
|
|
alert("Selected file is not InteractiveHtmlBom settings file.");
|
|
return;
|
|
}
|
|
var metadataMatches = newSettings.hasOwnProperty("pcbmetadata");
|
|
if (metadataMatches) {
|
|
for (var k in pcbdata.metadata) {
|
|
if (!newSettings.pcbmetadata.hasOwnProperty(k) || newSettings.pcbmetadata[k] != pcbdata.metadata[k]) {
|
|
metadataMatches = false;
|
|
}
|
|
}
|
|
}
|
|
if (!metadataMatches) {
|
|
var currentMetadata = JSON.stringify(pcbdata.metadata, null, 4);
|
|
var fileMetadata = JSON.stringify(newSettings.pcbmetadata, null, 4);
|
|
if (!confirm(
|
|
`Settins file metadata does not match current metadata.\n\n` +
|
|
`Page metadata:\n${currentMetadata}\n\n` +
|
|
`Settings file metadata:\n${fileMetadata}\n\n` +
|
|
`Press OK if you would like to import settings anyway.`)) {
|
|
return;
|
|
}
|
|
}
|
|
overwriteSettings(newSettings.settings);
|
|
}
|
|
reader.readAsText(file, 'UTF-8');
|
|
}
|
|
input.click();
|
|
}
|
|
|
|
function 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;
|
|
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") || "";
|
|
populateMarkWhenCheckedOptions();
|
|
|
|
function initBooleanSetting(storageString, def, elementId, func) {
|
|
var b = readStorage(storageString);
|
|
if (b === null) {
|
|
b = def;
|
|
} else {
|
|
b = (b == "true");
|
|
}
|
|
document.getElementById(elementId).checked = b;
|
|
func(b);
|
|
}
|
|
|
|
initBooleanSetting("padsVisible", config.show_pads, "padsCheckbox", padsVisible);
|
|
initBooleanSetting("fabricationVisible", config.show_fabrication, "fabricationCheckbox", fabricationVisible);
|
|
initBooleanSetting("silkscreenVisible", config.show_silkscreen, "silkscreenCheckbox", silkscreenVisible);
|
|
initBooleanSetting("referencesVisible", true, "referencesCheckbox", referencesVisible);
|
|
initBooleanSetting("valuesVisible", true, "valuesCheckbox", valuesVisible);
|
|
if ("tracks" in pcbdata) {
|
|
initBooleanSetting("tracksVisible", true, "tracksCheckbox", tracksVisible);
|
|
initBooleanSetting("zonesVisible", true, "zonesCheckbox", zonesVisible);
|
|
} else {
|
|
document.getElementById("tracksAndZonesCheckboxes").style.display = "none";
|
|
tracksVisible(false);
|
|
zonesVisible(false);
|
|
}
|
|
initBooleanSetting("dnpOutline", false, "dnpOutlineCheckbox", dnpOutline);
|
|
initBooleanSetting("redrawOnDrag", config.redraw_on_drag, "dragCheckbox", setRedrawOnDrag);
|
|
initBooleanSetting("darkmode", config.dark_mode, "darkmodeCheckbox", setDarkMode);
|
|
|
|
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";
|
|
ctx.lineWidth = text.thickness;
|
|
if ("svgpath" in text) {
|
|
ctx.stroke(new Path2D(text.svgpath));
|
|
ctx.restore();
|
|
return;
|
|
}
|
|
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 {
|
|
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("userSelect");
|
|
|
|
// Remove listeners
|
|
document.removeEventListener('mousemove', mouseMoveHandler);
|
|
document.removeEventListener('mouseup', mouseUpHandler);
|
|
|
|
if (wasDragged) {
|
|
// Redraw whole BOM
|
|
populateBomTable();
|
|
}
|
|
}
|
|
|
|
const mouseMoveHandler = function(e) {
|
|
// Notice the dragging
|
|
wasDragged = true;
|
|
|
|
// Make the dragged element visible
|
|
draggingElement.style.removeProperty("display");
|
|
|
|
// Set elements position to mouse position
|
|
draggingElement.style.left = `${e.screenX - xOffset}px`;
|
|
draggingElement.style.top = `${e.screenY - yOffset}px`;
|
|
|
|
// Forced redrawing of BOM table
|
|
if (forcePopulation) {
|
|
forcePopulation = false;
|
|
// Copy array
|
|
phe = Array.from(placeHolderElements);
|
|
// populate BOM table again
|
|
populateBomHeader(dragName, phe);
|
|
populateBomBody(dragName, phe);
|
|
}
|
|
|
|
// Set up array of hidden columns
|
|
var hiddenColumns = Array.from(settings.hiddenColumns);
|
|
// In the ungrouped mode, quantity don't exist
|
|
if (settings.bommode === "ungrouped")
|
|
hiddenColumns.push("Quantity");
|
|
// If no checkbox fields can be found, we consider them hidden
|
|
if (settings.checkboxes.length == 0)
|
|
hiddenColumns.push("checkboxes");
|
|
|
|
// Get table headers and group them into checkboxes, extrafields and normal headers
|
|
const bh = document.getElementById("bomhead");
|
|
headers = Array.from(bh.querySelectorAll("th"))
|
|
headers.shift() // numCol is not part of the columnOrder
|
|
headerGroups = []
|
|
lastCompoundClass = null;
|
|
for (i = 0; i < settings.columnOrder.length; i++) {
|
|
cElem = settings.columnOrder[i];
|
|
if (hiddenColumns.includes(cElem)) {
|
|
// Hidden columns appear as a dummy element
|
|
headerGroups.push([]);
|
|
continue;
|
|
}
|
|
elem = headers.filter(e => getColumnOrderName(e) === cElem)[0];
|
|
if (elem.classList.contains("bom-checkbox")) {
|
|
if (lastCompoundClass === "bom-checkbox") {
|
|
cbGroup = headerGroups.pop();
|
|
cbGroup.push(elem);
|
|
headerGroups.push(cbGroup);
|
|
} else {
|
|
lastCompoundClass = "bom-checkbox";
|
|
headerGroups.push([elem])
|
|
}
|
|
} else {
|
|
headerGroups.push([elem])
|
|
}
|
|
}
|
|
|
|
// Copy settings.columnOrder
|
|
var columns = Array.from(settings.columnOrder)
|
|
|
|
// Set up array with indices of hidden columns
|
|
var hiddenIndices = hiddenColumns.map(e => settings.columnOrder.indexOf(e));
|
|
var dragIndex = columns.indexOf(dragName);
|
|
var swapIndex = dragIndex;
|
|
var swapDone = false;
|
|
|
|
// Check if the current dragged element is swapable with the left or right element
|
|
if (dragIndex > 0) {
|
|
// Get left headers boundingbox
|
|
swapIndex = dragIndex - 1;
|
|
while (hiddenIndices.includes(swapIndex) && swapIndex > 0)
|
|
swapIndex--;
|
|
if (!hiddenIndices.includes(swapIndex)) {
|
|
box = getBoundingClientRectFromMultiple(headerGroups[swapIndex]);
|
|
if (e.clientX < box.left + window.scrollX + (box.width / 2)) {
|
|
swapElement = columns[dragIndex];
|
|
columns.splice(dragIndex, 1);
|
|
columns.splice(swapIndex, 0, swapElement);
|
|
forcePopulation = true;
|
|
swapDone = true;
|
|
}
|
|
}
|
|
}
|
|
if ((!swapDone) && dragIndex < headerGroups.length - 1) {
|
|
// Get right headers boundingbox
|
|
swapIndex = dragIndex + 1;
|
|
while (hiddenIndices.includes(swapIndex))
|
|
swapIndex++;
|
|
if (swapIndex < headerGroups.length) {
|
|
box = getBoundingClientRectFromMultiple(headerGroups[swapIndex]);
|
|
if (e.clientX > box.left + window.scrollX + (box.width / 2)) {
|
|
swapElement = columns[dragIndex];
|
|
columns.splice(dragIndex, 1);
|
|
columns.splice(swapIndex, 0, swapElement);
|
|
forcePopulation = true;
|
|
swapDone = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Write back change to storage
|
|
if (swapDone) {
|
|
settings.columnOrder = columns
|
|
writeStorage("columnOrder", JSON.stringify(columns));
|
|
}
|
|
|
|
}
|
|
|
|
const mouseDownHandler = function(e) {
|
|
var target = e.target;
|
|
if (target.tagName.toLowerCase() != "td")
|
|
target = target.parentElement;
|
|
|
|
// Used to check if a dragging has ever happened
|
|
wasDragged = false;
|
|
|
|
// Create new element which will be displayed as the dragged column
|
|
draggingElement = document.createElement("div")
|
|
draggingElement.classList.add("dragging");
|
|
draggingElement.style.display = "none";
|
|
draggingElement.style.position = "absolute";
|
|
draggingElement.style.overflow = "hidden";
|
|
|
|
// Get bomhead and bombody elements
|
|
const bh = document.getElementById("bomhead");
|
|
const bb = document.getElementById("bombody");
|
|
|
|
// Get all compound headers for the current column
|
|
var compoundHeaders;
|
|
if (target.classList.contains("bom-checkbox")) {
|
|
compoundHeaders = Array.from(bh.querySelectorAll("th.bom-checkbox"));
|
|
} else {
|
|
compoundHeaders = [target];
|
|
}
|
|
|
|
// Create new table which will display the column
|
|
var newTable = document.createElement("table");
|
|
newTable.classList.add("bom");
|
|
newTable.style.background = "white";
|
|
draggingElement.append(newTable);
|
|
|
|
// Create new header element
|
|
var newHeader = document.createElement("thead");
|
|
newTable.append(newHeader);
|
|
|
|
// Set up array for storing all placeholder elements
|
|
placeHolderElements = [];
|
|
|
|
// Add all compound headers to the new thead element and placeholders
|
|
compoundHeaders.forEach(function(h) {
|
|
clone = cloneElementWithDimensions(h);
|
|
newHeader.append(clone);
|
|
placeHolderElements.push(clone);
|
|
});
|
|
|
|
// Create new body element
|
|
var newBody = document.createElement("tbody");
|
|
newTable.append(newBody);
|
|
|
|
// Get indices for compound headers
|
|
var idxs = compoundHeaders.map(e => getBomTableHeaderIndex(e));
|
|
|
|
// For each row in the BOM body...
|
|
var rows = bb.querySelectorAll("tr");
|
|
rows.forEach(function(row) {
|
|
// ..get the cells for the compound column
|
|
const tds = row.querySelectorAll("td");
|
|
var copytds = idxs.map(i => tds[i]);
|
|
// Add them to the new element and the placeholders
|
|
var newRow = document.createElement("tr");
|
|
copytds.forEach(function(td) {
|
|
clone = cloneElementWithDimensions(td);
|
|
newRow.append(clone);
|
|
placeHolderElements.push(clone);
|
|
});
|
|
newBody.append(newRow);
|
|
});
|
|
|
|
// Compute width for compound header
|
|
var width = compoundHeaders.reduce((acc, x) => acc + x.clientWidth, 0);
|
|
draggingElement.style.width = `${width}px`;
|
|
|
|
// Insert the new dragging element and disable selection on BOM
|
|
bom.insertBefore(draggingElement, null);
|
|
bom.style.userSelect = "none";
|
|
|
|
// Determine the mouse position offset
|
|
xOffset = e.screenX - compoundHeaders.reduce((acc, x) => Math.min(acc, x.offsetLeft), compoundHeaders[0].offsetLeft);
|
|
yOffset = e.screenY - compoundHeaders[0].offsetTop;
|
|
|
|
// Get name for the column in settings.columnOrder
|
|
dragName = getColumnOrderName(target);
|
|
|
|
// Change text and class for placeholder elements
|
|
placeHolderElements = placeHolderElements.map(function(e) {
|
|
newElem = cloneElementWithDimensions(e);
|
|
newElem.textContent = "";
|
|
newElem.classList.add("placeholder");
|
|
return newElem;
|
|
});
|
|
|
|
// On next mouse move, the whole BOM needs to be redrawn to show the placeholders
|
|
forcePopulation = true;
|
|
|
|
// Add listeners for move and up on mouse
|
|
document.addEventListener('mousemove', mouseMoveHandler);
|
|
document.addEventListener('mouseup', mouseUpHandler);
|
|
}
|
|
|
|
// In netlist mode, there is nothing to reorder
|
|
if (settings.bommode === "netlist")
|
|
return;
|
|
|
|
// Add mouseDownHandler to every column except the numCol
|
|
bom.querySelectorAll("th")
|
|
.forEach(function(head) {
|
|
if (!head.classList.contains("numCol")) {
|
|
head.onmousedown = mouseDownHandler;
|
|
}
|
|
});
|
|
|
|
}
|
|
|
|
function getBoundingClientRectFromMultiple(elements) {
|
|
var elems = Array.from(elements);
|
|
|
|
if (elems.length == 0)
|
|
return null;
|
|
|
|
var box = elems.shift()
|
|
.getBoundingClientRect();
|
|
|
|
elems.forEach(function(elem) {
|
|
var elembox = elem.getBoundingClientRect();
|
|
box.left = Math.min(elembox.left, box.left);
|
|
box.top = Math.min(elembox.top, box.top);
|
|
box.width += elembox.width;
|
|
box.height = Math.max(elembox.height, box.height);
|
|
});
|
|
|
|
return box;
|
|
}
|
|
|
|
function cloneElementWithDimensions(elem) {
|
|
var newElem = elem.cloneNode(true);
|
|
newElem.style.height = window.getComputedStyle(elem).height;
|
|
newElem.style.width = window.getComputedStyle(elem).width;
|
|
return newElem;
|
|
}
|
|
|
|
function getBomTableHeaderIndex(elem) {
|
|
const bh = document.getElementById('bomhead');
|
|
const ths = Array.from(bh.querySelectorAll("th"));
|
|
return ths.indexOf(elem);
|
|
}
|
|
|
|
function getColumnOrderName(elem) {
|
|
var cname = elem.getAttribute("col_name");
|
|
if (cname === "bom-checkbox")
|
|
return "checkboxes";
|
|
else
|
|
return cname;
|
|
}
|
|
|
|
function resizableGrid(tablehead) {
|
|
var cols = tablehead.firstElementChild.children;
|
|
var rowWidth = tablehead.offsetWidth;
|
|
|
|
for (var i = 1; i < cols.length; i++) {
|
|
if (cols[i].classList.contains("bom-checkbox"))
|
|
continue;
|
|
cols[i].style.width = ((cols[i].clientWidth - paddingDiff(cols[i])) * 100 / rowWidth) + '%';
|
|
}
|
|
|
|
for (var i = 1; i < cols.length - 1; i++) {
|
|
var div = document.createElement('div');
|
|
div.className = "column-width-handle";
|
|
cols[i].appendChild(div);
|
|
setListeners(div);
|
|
}
|
|
|
|
function setListeners(div) {
|
|
var startX, curCol, nxtCol, curColWidth, nxtColWidth, rowWidth;
|
|
|
|
div.addEventListener('mousedown', function(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
curCol = e.target.parentElement;
|
|
nxtCol = curCol.nextElementSibling;
|
|
startX = e.pageX;
|
|
|
|
var padding = paddingDiff(curCol);
|
|
|
|
rowWidth = curCol.parentElement.offsetWidth;
|
|
curColWidth = curCol.clientWidth - padding;
|
|
nxtColWidth = nxtCol.clientWidth - padding;
|
|
});
|
|
|
|
document.addEventListener('mousemove', function(e) {
|
|
if (startX) {
|
|
var diffX = e.pageX - startX;
|
|
diffX = -Math.min(-diffX, curColWidth - 20);
|
|
diffX = Math.min(diffX, nxtColWidth - 20);
|
|
|
|
curCol.style.width = ((curColWidth + diffX) * 100 / rowWidth) + '%';
|
|
nxtCol.style.width = ((nxtColWidth - diffX) * 100 / rowWidth) + '%';
|
|
console.log(`${curColWidth + nxtColWidth} ${(curColWidth + diffX) * 100 / rowWidth + (nxtColWidth - diffX) * 100 / rowWidth}`);
|
|
}
|
|
});
|
|
|
|
document.addEventListener('mouseup', function(e) {
|
|
curCol = undefined;
|
|
nxtCol = undefined;
|
|
startX = undefined;
|
|
nxtColWidth = undefined;
|
|
curColWidth = undefined
|
|
});
|
|
}
|
|
|
|
function paddingDiff(col) {
|
|
|
|
if (getStyleVal(col, 'box-sizing') == 'border-box') {
|
|
return 0;
|
|
}
|
|
|
|
var padLeft = getStyleVal(col, 'padding-left');
|
|
var padRight = getStyleVal(col, 'padding-right');
|
|
return (parseInt(padLeft) + parseInt(padRight));
|
|
|
|
}
|
|
|
|
function getStyleVal(elm, css) {
|
|
return (window.getComputedStyle(elm, null).getPropertyValue(css))
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
/* DOM manipulation and misc code */
|
|
|
|
var bomsplit;
|
|
var canvassplit;
|
|
var initDone = false;
|
|
var bomSortFunction = null;
|
|
var currentSortColumn = null;
|
|
var currentSortOrder = null;
|
|
var currentHighlightedRowId;
|
|
var highlightHandlers = [];
|
|
var footprintIndexToHandler = {};
|
|
var netsToHandler = {};
|
|
var markedFootprints = new Set();
|
|
var highlightedFootprints = [];
|
|
var highlightedNet = null;
|
|
var lastClicked;
|
|
|
|
function dbg(html) {
|
|
dbgdiv.innerHTML = html;
|
|
}
|
|
|
|
function redrawIfInitDone() {
|
|
if (initDone) {
|
|
redrawCanvas(allcanvas.front);
|
|
redrawCanvas(allcanvas.back);
|
|
}
|
|
}
|
|
|
|
function padsVisible(value) {
|
|
writeStorage("padsVisible", value);
|
|
settings.renderPads = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function referencesVisible(value) {
|
|
writeStorage("referencesVisible", value);
|
|
settings.renderReferences = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function valuesVisible(value) {
|
|
writeStorage("valuesVisible", value);
|
|
settings.renderValues = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function tracksVisible(value) {
|
|
writeStorage("tracksVisible", value);
|
|
settings.renderTracks = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function zonesVisible(value) {
|
|
writeStorage("zonesVisible", value);
|
|
settings.renderZones = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function dnpOutline(value) {
|
|
writeStorage("dnpOutline", value);
|
|
settings.renderDnpOutline = value;
|
|
redrawIfInitDone();
|
|
}
|
|
|
|
function setDarkMode(value) {
|
|
if (value) {
|
|
topmostdiv.classList.add("dark");
|
|
} else {
|
|
topmostdiv.classList.remove("dark");
|
|
}
|
|
writeStorage("darkmode", value);
|
|
settings.darkMode = value;
|
|
redrawIfInitDone();
|
|
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 getStoredCheckboxRefs(checkbox) {
|
|
function convert(ref) {
|
|
var intref = parseInt(ref);
|
|
if (isNaN(intref)) {
|
|
for (var i = 0; i < pcbdata.footprints.length; i++) {
|
|
if (pcbdata.footprints[i].ref == ref) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
} else {
|
|
return intref;
|
|
}
|
|
}
|
|
if (!(checkbox in settings.checkboxStoredRefs)) {
|
|
var val = readStorage("checkbox_" + checkbox);
|
|
settings.checkboxStoredRefs[checkbox] = val ? val : "";
|
|
}
|
|
if (!settings.checkboxStoredRefs[checkbox]) {
|
|
return new Set();
|
|
} else {
|
|
return new Set(settings.checkboxStoredRefs[checkbox].split(",").map(r => convert(r)).filter(a => a >= 0));
|
|
}
|
|
}
|
|
|
|
function getCheckboxState(checkbox, references) {
|
|
var storedRefsSet = getStoredCheckboxRefs(checkbox);
|
|
var currentRefsSet = new Set(references.map(r => r[1]));
|
|
// Get difference of current - stored
|
|
var difference = new Set(currentRefsSet);
|
|
for (ref of storedRefsSet) {
|
|
difference.delete(ref);
|
|
}
|
|
if (difference.size == 0) {
|
|
// All the current refs are stored
|
|
return "checked";
|
|
} else if (difference.size == currentRefsSet.size) {
|
|
// None of the current refs are stored
|
|
return "unchecked";
|
|
} else {
|
|
// Some of the refs are stored
|
|
return "indeterminate";
|
|
}
|
|
}
|
|
|
|
function setBomCheckboxState(checkbox, element, references) {
|
|
var state = getCheckboxState(checkbox, references);
|
|
element.checked = (state == "checked");
|
|
element.indeterminate = (state == "indeterminate");
|
|
}
|
|
|
|
function createCheckboxChangeHandler(checkbox, references, row) {
|
|
return function () {
|
|
refsSet = getStoredCheckboxRefs(checkbox);
|
|
var markWhenChecked = settings.markWhenChecked == checkbox;
|
|
eventArgs = {
|
|
checkbox: checkbox,
|
|
refs: references,
|
|
}
|
|
if (this.checked) {
|
|
// checkbox ticked
|
|
for (var ref of references) {
|
|
refsSet.add(ref[1]);
|
|
}
|
|
if (markWhenChecked) {
|
|
row.classList.add("checked");
|
|
for (var ref of references) {
|
|
markedFootprints.add(ref[1]);
|
|
}
|
|
drawHighlights();
|
|
}
|
|
eventArgs.state = 'checked';
|
|
} else {
|
|
// checkbox unticked
|
|
for (var ref of references) {
|
|
refsSet.delete(ref[1]);
|
|
}
|
|
if (markWhenChecked) {
|
|
row.classList.remove("checked");
|
|
for (var ref of references) {
|
|
markedFootprints.delete(ref[1]);
|
|
}
|
|
drawHighlights();
|
|
}
|
|
eventArgs.state = 'unchecked';
|
|
}
|
|
settings.checkboxStoredRefs[checkbox] = [...refsSet].join(",");
|
|
writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
|
|
updateCheckboxStats(checkbox);
|
|
EventHandler.emitEvent(IBOM_EVENT_TYPES.CHECKBOX_CHANGE_EVENT, eventArgs);
|
|
}
|
|
}
|
|
|
|
function clearHighlightedFootprints() {
|
|
if (currentHighlightedRowId) {
|
|
document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
|
|
currentHighlightedRowId = null;
|
|
highlightedFootprints = [];
|
|
highlightedNet = null;
|
|
}
|
|
}
|
|
|
|
function createRowHighlightHandler(rowid, refs, net) {
|
|
return function () {
|
|
if (currentHighlightedRowId) {
|
|
if (currentHighlightedRowId == rowid) {
|
|
return;
|
|
}
|
|
document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
|
|
}
|
|
document.getElementById(rowid).classList.add("highlighted");
|
|
currentHighlightedRowId = rowid;
|
|
highlightedFootprints = refs ? refs.map(r => r[1]) : [];
|
|
highlightedNet = net;
|
|
drawHighlights();
|
|
EventHandler.emitEvent(
|
|
IBOM_EVENT_TYPES.HIGHLIGHT_EVENT, {
|
|
rowid: rowid,
|
|
refs: refs,
|
|
net: net
|
|
});
|
|
}
|
|
}
|
|
|
|
function 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 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] != b[i]) return compareRefs(a[i][0], b[i][0]);
|
|
i++;
|
|
}
|
|
return a.length - b.length;
|
|
}));
|
|
} else if (column === "Value") {
|
|
tr.appendChild(createColumnHeader("Value", "value", (a, b) => {
|
|
var ra = a[0][1], rb = b[0][1];
|
|
return valueCompare(
|
|
pcbdata.bom.parsedValues[ra], pcbdata.bom.parsedValues[rb],
|
|
pcbdata.bom.fields[ra][valueIndex], pcbdata.bom.fields[rb][valueIndex]);
|
|
}));
|
|
return;
|
|
} else if (column === "Footprint") {
|
|
tr.appendChild(createColumnHeader(
|
|
"Footprint", "footprint", stringFieldCompareClosure(footprintIndex)));
|
|
} else if (column === "Quantity" && settings.bommode == "grouped") {
|
|
tr.appendChild(createColumnHeader("Quantity", "quantity", (a, b) => {
|
|
return a.length - b.length;
|
|
}));
|
|
} else {
|
|
// Other fields
|
|
var i = config.fields.indexOf(column);
|
|
if (i < 0)
|
|
return;
|
|
tr.appendChild(createColumnHeader(
|
|
column, `field${i + 1}`, stringFieldCompareClosure(i)));
|
|
}
|
|
});
|
|
}
|
|
bomhead.appendChild(tr);
|
|
}
|
|
|
|
function populateBomBody(placeholderColumn = null, placeHolderElements = null) {
|
|
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();
|
|
if (settings.bommode == "netlist") {
|
|
bomtable = pcbdata.nets.slice();
|
|
} else {
|
|
switch (settings.canvaslayout) {
|
|
case 'F':
|
|
bomtable = pcbdata.bom.F.slice();
|
|
break;
|
|
case 'FB':
|
|
bomtable = pcbdata.bom.both.slice();
|
|
break;
|
|
case 'B':
|
|
bomtable = pcbdata.bom.B.slice();
|
|
break;
|
|
}
|
|
if (settings.bommode == "ungrouped") {
|
|
// expand bom table
|
|
expandedTable = []
|
|
for (var bomentry of bomtable) {
|
|
for (var ref of bomentry) {
|
|
expandedTable.push([ref]);
|
|
}
|
|
}
|
|
bomtable = expandedTable;
|
|
}
|
|
}
|
|
if (bomSortFunction) {
|
|
bomtable = bomtable.sort(bomSortFunction);
|
|
}
|
|
for (var i in bomtable) {
|
|
var bomentry = bomtable[i];
|
|
if (filter && !entryMatches(bomentry)) {
|
|
continue;
|
|
}
|
|
var references = null;
|
|
var netname = null;
|
|
var tr = document.createElement("TR");
|
|
var td = document.createElement("TD");
|
|
var rownum = +i + 1;
|
|
tr.id = "bomrow" + rownum;
|
|
td.textContent = rownum;
|
|
tr.appendChild(td);
|
|
if (settings.bommode == "netlist") {
|
|
netname = bomentry;
|
|
td = document.createElement("TD");
|
|
td.innerHTML = highlightFilter(netname ? netname : "<no net>");
|
|
tr.appendChild(td);
|
|
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 = createCheckboxChangeHandler(checkbox, references, tr);
|
|
setBomCheckboxState(checkbox, input, references);
|
|
if (input.checked && settings.markWhenChecked == checkbox) {
|
|
tr.classList.add("checked");
|
|
}
|
|
td.appendChild(input);
|
|
tr.appendChild(td);
|
|
}
|
|
}
|
|
} else if (column === "References") {
|
|
td = document.createElement("TD");
|
|
td.innerHTML = highlightFilter(references.map(r => r[0]).join(", "));
|
|
tr.appendChild(td);
|
|
} else if (column === "Quantity" && settings.bommode == "grouped") {
|
|
// Quantity
|
|
td = document.createElement("TD");
|
|
td.textContent = references.length;
|
|
tr.appendChild(td);
|
|
} else {
|
|
// All the other fields
|
|
var field_index = config.fields.indexOf(column)
|
|
if (field_index < 0)
|
|
return;
|
|
var valueSet = new Set();
|
|
references.map(r => r[1]).forEach((id) => valueSet.add(pcbdata.bom.fields[id][field_index]));
|
|
td = document.createElement("TD");
|
|
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);
|
|
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 checkbox = bomrow.childNodes[checkboxnum].childNodes[0];
|
|
checkbox.checked = !checkbox.checked;
|
|
checkbox.indeterminate = false;
|
|
checkbox.onchange();
|
|
}
|
|
|
|
function checkBomCheckbox(bomrowid, checkboxname) {
|
|
var checkboxnum = 0;
|
|
while (checkboxnum < settings.checkboxes.length &&
|
|
settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
|
|
checkboxnum++;
|
|
}
|
|
if (!bomrowid || checkboxnum >= settings.checkboxes.length) {
|
|
return;
|
|
}
|
|
var bomrow = document.getElementById(bomrowid);
|
|
var checkbox = bomrow.childNodes[checkboxnum + 1].childNodes[0];
|
|
checkbox.checked = true;
|
|
checkbox.indeterminate = false;
|
|
checkbox.onchange();
|
|
}
|
|
|
|
function setBomCheckboxes(value) {
|
|
writeStorage("bomCheckboxes", value);
|
|
settings.checkboxes = value.split(",").map((e) => e.trim()).filter((e) => e);
|
|
prepCheckboxes();
|
|
populateMarkWhenCheckedOptions();
|
|
setMarkWhenChecked(settings.markWhenChecked);
|
|
}
|
|
|
|
function setMarkWhenChecked(value) {
|
|
writeStorage("markWhenChecked", value);
|
|
settings.markWhenChecked = value;
|
|
markedFootprints.clear();
|
|
for (var ref of (value ? getStoredCheckboxRefs(value) : [])) {
|
|
markedFootprints.add(ref);
|
|
}
|
|
populateBomTable();
|
|
drawHighlights();
|
|
}
|
|
|
|
function prepCheckboxes() {
|
|
var table = document.getElementById("checkbox-stats");
|
|
while (table.childElementCount > 1) {
|
|
table.removeChild(table.lastChild);
|
|
}
|
|
if (settings.checkboxes.length) {
|
|
table.style.display = "";
|
|
} else {
|
|
table.style.display = "none";
|
|
}
|
|
for (var checkbox of settings.checkboxes) {
|
|
var tr = document.createElement("TR");
|
|
var td = document.createElement("TD");
|
|
td.innerHTML = checkbox;
|
|
tr.appendChild(td);
|
|
td = document.createElement("TD");
|
|
td.id = "checkbox-stats-" + checkbox;
|
|
var progressbar = document.createElement("div");
|
|
progressbar.classList.add("bar");
|
|
td.appendChild(progressbar);
|
|
var text = document.createElement("div");
|
|
text.classList.add("text");
|
|
td.appendChild(text);
|
|
tr.appendChild(td);
|
|
table.appendChild(tr);
|
|
updateCheckboxStats(checkbox);
|
|
}
|
|
}
|
|
|
|
function populateMarkWhenCheckedOptions() {
|
|
var container = document.getElementById("markWhenCheckedContainer");
|
|
|
|
if (settings.checkboxes.length == 0) {
|
|
container.parentElement.style.display = "none";
|
|
return;
|
|
}
|
|
|
|
container.innerHTML = '';
|
|
container.parentElement.style.display = "inline-block";
|
|
|
|
function createOption(name, displayName) {
|
|
var id = "markWhenChecked-" + name;
|
|
|
|
var div = document.createElement("div");
|
|
div.classList.add("radio-container");
|
|
|
|
var input = document.createElement("input");
|
|
input.type = "radio";
|
|
input.name = "markWhenChecked";
|
|
input.value = name;
|
|
input.id = id;
|
|
input.onchange = () => setMarkWhenChecked(name);
|
|
div.appendChild(input);
|
|
|
|
// Preserve the selected element when the checkboxes change
|
|
if (name == settings.markWhenChecked) {
|
|
input.checked = true;
|
|
}
|
|
|
|
var label = document.createElement("label");
|
|
label.innerHTML = displayName;
|
|
label.htmlFor = id;
|
|
div.appendChild(label);
|
|
|
|
container.appendChild(div);
|
|
}
|
|
createOption("", "None");
|
|
for (var checkbox of settings.checkboxes) {
|
|
createOption(checkbox, checkbox);
|
|
}
|
|
}
|
|
|
|
function updateCheckboxStats(checkbox) {
|
|
var checked = getStoredCheckboxRefs(checkbox).size;
|
|
var total = pcbdata.footprints.length - pcbdata.bom.skipped.length;
|
|
var percent = checked * 100.0 / total;
|
|
var td = document.getElementById("checkbox-stats-" + checkbox);
|
|
td.firstChild.style.width = percent + "%";
|
|
td.lastChild.innerHTML = checked + "/" + total + " (" + Math.round(percent) + "%)";
|
|
}
|
|
|
|
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) {
|
|
initUtils();
|
|
initRender();
|
|
initStorage();
|
|
initDefaults();
|
|
cleanGutters();
|
|
populateMetadata();
|
|
dbgdiv = document.getElementById("dbg");
|
|
bom = document.getElementById("bombody");
|
|
bomhead = document.getElementById("bomhead");
|
|
filter = "";
|
|
reflookup = "";
|
|
if (!("nets" in pcbdata)) {
|
|
hideNetlistButton();
|
|
}
|
|
initDone = true;
|
|
setBomCheckboxes(document.getElementById("bomCheckboxes").value);
|
|
// Triggers render
|
|
changeBomLayout(settings.bomlayout);
|
|
|
|
// Users may leave fullscreen without touching the checkbox. Uncheck.
|
|
document.addEventListener('fullscreenchange', () => {
|
|
if (!document.fullscreenElement)
|
|
document.getElementById('fullscreenCheckbox').checked = false;
|
|
});
|
|
}
|
|
|
|
window.onresize = resizeAll;
|
|
window.matchMedia("print").addListener(resizeAll);
|
|
|
|
///////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////
|
|
// EventHandler.registerCallback(IBOM_EVENT_TYPES.BOM_BODY_CHANGE_EVENT, () => {
|
|
// for(var tr of bom.childNodes) {
|
|
// tr.onclick = tr.onmousemove;
|
|
// tr.onmousemove = null;
|
|
// };
|
|
// });
|
|
|
|
///////////////////////////////////////////////
|
|
</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="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>
|