Hackpad/pcb/v0.3/bom/ibom.html

4443 lines
273 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive BOM for KiCAD</title>
<style type="text/css">
:root {
--pcb-edge-color: black;
--pad-color: #878787;
--pad-hole-color: #CCCCCC;
--pad-color-highlight: #D04040;
--pad-color-highlight-both: #D0D040;
--pad-color-highlight-marked: #44a344;
--pin1-outline-color: #ffb629;
--pin1-outline-color-highlight: #ffb629;
--pin1-outline-color-highlight-both: #fcbb39;
--pin1-outline-color-highlight-marked: #fdbe41;
--silkscreen-edge-color: #aa4;
--silkscreen-polygon-color: #4aa;
--silkscreen-text-color: #4aa;
--fabrication-edge-color: #907651;
--fabrication-polygon-color: #907651;
--fabrication-text-color: #a27c24;
--track-color: #def5f1;
--track-color-highlight: #D04040;
--zone-color: #def5f1;
--zone-color-highlight: #d0404080;
}
html,
body {
margin: 0px;
height: 100%;
font-family: Verdana, sans-serif;
}
.dark.topmostdiv {
--pcb-edge-color: #eee;
--pad-color: #808080;
--pin1-outline-color: #ffa800;
--pin1-outline-color-highlight: #ccff00;
--track-color: #42524f;
--zone-color: #42524f;
background-color: #252c30;
color: #eee;
}
button {
background-color: #eee;
border: 1px solid #888;
color: black;
height: 44px;
width: 44px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
font-weight: bolder;
}
.dark button {
/* This will be inverted */
background-color: #c3b7b5;
}
button.depressed {
background-color: #0a0;
color: white;
}
.dark button.depressed {
/* This will be inverted */
background-color: #b3b;
}
button:focus {
outline: 0;
}
button#tb-btn {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' fill='none' stroke='%23000' stroke-width='.4' stroke-linejoin='round'/%3E%3Cpath d='M1.32 290.12h5.82M1.32 291.45h5.82' fill='none' stroke='%23000' stroke-width='.4'/%3E%3Cpath d='M4.37 292.5v4.23M.26 292.63H8.2' fill='none' stroke='%23000' stroke-width='.3'/%3E%3Ctext font-weight='700' font-size='3.17' font-family='sans-serif'%3E%3Ctspan x='1.35' y='295.73'%3EF%3C/tspan%3E%3Ctspan x='5.03' y='295.68'%3EB%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A");
}
button#lr-btn {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' fill='none' stroke='%23000' stroke-width='.4' stroke-linejoin='round'/%3E%3Cpath d='M1.06 290.12H3.7m-2.64 1.33H3.7m-2.64 1.32H3.7m-2.64 1.3H3.7m-2.64 1.33H3.7' fill='none' stroke='%23000' stroke-width='.4'/%3E%3Cpath d='M4.37 288.8v7.94m0-4.11h3.96' fill='none' stroke='%23000' stroke-width='.3'/%3E%3Ctext font-weight='700' font-size='3.17' font-family='sans-serif'%3E%3Ctspan x='5.11' y='291.96'%3EF%3C/tspan%3E%3Ctspan x='5.03' y='295.68'%3EB%3C/tspan%3E%3C/text%3E%3C/g%3E%3C/svg%3E%0A");
}
button#bom-btn {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8.47 8.47'%3E%3Crect transform='translate(0 -288.53)' ry='1.17' y='288.8' x='.27' height='7.94' width='7.94' fill='%23f9f9f9'/%3E%3Cg transform='translate(0 -288.53)' fill='none' stroke='%23000' stroke-width='.4'%3E%3Crect width='7.94' height='7.94' x='.27' y='288.8' ry='1.17' stroke-linejoin='round'/%3E%3Cpath d='M1.59 290.12h5.29M1.59 291.45h5.33M1.59 292.75h5.33M1.59 294.09h5.33M1.59 295.41h5.33'/%3E%3C/g%3E%3C/svg%3E");
}
button#bom-grouped-btn {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg stroke='%23000' stroke-linejoin='round' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-linecap='square' stroke-width='2' d='M6 10h4m4 0h5m4 0h3M6.1 22h3m3.9 0h5m4 0h4m-16-8h4m4 0h4'/%3E%3Cpath stroke-linecap='null' d='M5 17.5h22M5 26.6h22M5 5.5h22'/%3E%3C/g%3E%3C/svg%3E");
}
button#bom-ungrouped-btn {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg stroke='%23000' stroke-linejoin='round' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-linecap='square' stroke-width='2' d='M6 10h4m-4 8h3m-3 8h4'/%3E%3Cpath stroke-linecap='null' d='M5 13.5h22m-22 8h22M5 5.5h22'/%3E%3C/g%3E%3C/svg%3E");
}
button#bom-netlist-btn {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='32' height='32'%3E%3Cg fill='none' stroke='%23000' class='layer'%3E%3Crect width='29' height='29' x='1.5' y='1.5' stroke-width='2' fill='%23fff' rx='5' ry='5'/%3E%3Cpath stroke-width='2' d='M6 26l6-6v-8m13.8-6.3l-6 6v8'/%3E%3Ccircle cx='11.8' cy='9.5' r='2.8' stroke-width='2'/%3E%3Ccircle cx='19.8' cy='22.8' r='2.8' stroke-width='2'/%3E%3C/g%3E%3C/svg%3E");
}
button#copy {
background-image: url("data:image/svg+xml,%3Csvg height='48' viewBox='0 0 48 48' width='48' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0 0h48v48h-48z' fill='none'/%3E%3Cpath d='M32 2h-24c-2.21 0-4 1.79-4 4v28h4v-28h24v-4zm6 8h-22c-2.21 0-4 1.79-4 4v28c0 2.21 1.79 4 4 4h22c2.21 0 4-1.79 4-4v-28c0-2.21-1.79-4-4-4zm0 32h-22v-28h22v28z'/%3E%3C/svg%3E");
background-position: 6px 6px;
background-repeat: no-repeat;
background-size: 26px 26px;
border-radius: 6px;
height: 40px;
width: 40px;
margin: 10px 5px;
}
button#copy:active {
box-shadow: inset 0px 0px 5px #6c6c6c;
}
textarea.clipboard-temp {
position: fixed;
top: 0;
left: 0;
width: 2em;
height: 2em;
padding: 0;
border: None;
outline: None;
box-shadow: None;
background: transparent;
}
.left-most-button {
border-right: 0;
border-top-left-radius: 6px;
border-bottom-left-radius: 6px;
}
.middle-button {
border-right: 0;
}
.right-most-button {
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
}
.button-container {
font-size: 0;
margin: 10px 10px 10px 0px;
}
.dark .button-container {
filter: invert(1);
}
.button-container button {
background-size: 32px 32px;
background-position: 5px 5px;
background-repeat: no-repeat;
}
@media print {
.hideonprint {
display: none;
}
}
canvas {
cursor: crosshair;
}
canvas:active {
cursor: grabbing;
}
.fileinfo {
width: 100%;
max-width: 1000px;
border: none;
padding: 5px;
}
.fileinfo .title {
font-size: 20pt;
font-weight: bold;
}
.fileinfo td {
overflow: hidden;
white-space: nowrap;
max-width: 1px;
width: 50%;
text-overflow: ellipsis;
}
.bom {
border-collapse: collapse;
font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
font-size: 10pt;
table-layout: fixed;
width: 100%;
margin-top: 1px;
position: relative;
}
.bom th,
.bom td {
border: 1px solid black;
padding: 5px;
word-wrap: break-word;
text-align: center;
position: relative;
}
.dark .bom th,
.dark .bom td {
border: 1px solid #777;
}
.bom th {
background-color: #CCCCCC;
background-clip: padding-box;
}
.dark .bom th {
background-color: #3b4749;
}
.bom tr.highlighted:nth-child(n) {
background-color: #cfc;
}
.dark .bom tr.highlighted:nth-child(n) {
background-color: #226022;
}
.bom tr:nth-child(even) {
background-color: #f2f2f2;
}
.dark .bom tr:nth-child(even) {
background-color: #313b40;
}
.bom tr.checked {
color: #1cb53d;
}
.dark .bom tr.checked {
color: #2cce54;
}
.bom tr {
transition: background-color 0.2s;
}
.bom .numCol {
width: 30px;
}
.bom .value {
width: 15%;
}
.bom .quantity {
width: 65px;
}
.bom th .sortmark {
position: absolute;
right: 1px;
top: 1px;
margin-top: -5px;
border-width: 5px;
border-style: solid;
border-color: transparent transparent #221 transparent;
transform-origin: 50% 85%;
transition: opacity 0.2s, transform 0.4s;
}
.dark .bom th .sortmark {
filter: invert(1);
}
.bom th .sortmark.none {
opacity: 0;
}
.bom th .sortmark.desc {
transform: rotate(180deg);
}
.bom th:hover .sortmark.none {
opacity: 0.5;
}
.bom .bom-checkbox {
width: 30px;
position: relative;
user-select: none;
-moz-user-select: none;
}
.bom .bom-checkbox:before {
content: "";
position: absolute;
border-width: 15px;
border-style: solid;
border-color: #51829f transparent transparent transparent;
visibility: hidden;
top: -15px;
}
.bom .bom-checkbox:after {
content: "Double click to set/unset all";
position: absolute;
color: white;
top: -35px;
left: -26px;
background: #51829f;
padding: 5px 15px;
border-radius: 8px;
white-space: nowrap;
visibility: hidden;
}
.bom .bom-checkbox:hover:before,
.bom .bom-checkbox:hover:after {
visibility: visible;
transition: visibility 0.2s linear 1s;
}
.split {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow-y: auto;
overflow-x: hidden;
background-color: inherit;
}
.split.split-horizontal,
.gutter.gutter-horizontal {
height: 100%;
float: left;
}
.gutter {
background-color: #ddd;
background-repeat: no-repeat;
background-position: 50%;
transition: background-color 0.3s;
}
.dark .gutter {
background-color: #777;
}
.gutter.gutter-horizontal {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
cursor: ew-resize;
width: 5px;
}
.gutter.gutter-vertical {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=');
cursor: ns-resize;
height: 5px;
}
.searchbox {
float: left;
height: 40px;
margin: 10px 5px;
padding: 12px 32px;
font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
font-size: 18px;
box-sizing: border-box;
border: 1px solid #888;
border-radius: 6px;
outline: none;
background-color: #eee;
transition: background-color 0.2s, border 0.2s;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABNklEQVQ4T8XSMUvDQBQH8P/LElFa/AIZHcTBQSz0I/gFstTBRR2KUC4ldDxw7h0Bl3RRUATxi4iiODgoiLNrbQYp5J6cpJJqomkX33Z37/14d/dIa33MzDuYI4johOI4XhyNRteO46zNYjDzAxE1yBZprVeZ+QbAUhXEGJMA2Ox2u4+fQIa0mPmsCgCgJYQ4t7lfgF0opQYAdv9ABkKI/UnOFCClXKjX61cA1osQY8x9kiRNKeV7IWA3oyhaSdP0FkAtjxhj3hzH2RBCPOf3pzqYHCilfAAX+URm9oMguPzeWSGQvUcMYC8rOBJCHBRdqxTo9/vbRHRqi8bj8XKv1xvODbiuW2u32/bvf0SlDv4XYOY7z/Mavu+nM1+BmQ+NMc0wDF/LprP0DbTWW0T00ul0nn4b7Q87+X4Qmfiq2wAAAABJRU5ErkJggg==');
background-position: 10px 10px;
background-repeat: no-repeat;
}
.dark .searchbox {
background-color: #111;
color: #eee;
}
.searchbox::placeholder {
color: #ccc;
}
.dark .searchbox::placeholder {
color: #666;
}
.filter {
width: calc(60% - 64px);
}
.reflookup {
width: calc(40% - 10px);
}
input[type=text]:focus {
background-color: white;
border: 1px solid #333;
}
.dark input[type=text]:focus {
background-color: #333;
border: 1px solid #ccc;
}
mark.highlight {
background-color: #5050ff;
color: #fff;
padding: 2px;
border-radius: 6px;
}
.dark mark.highlight {
background-color: #76a6da;
color: #111;
}
.menubtn {
background-color: white;
border: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36' viewBox='0 0 20 20'%3E%3Cpath fill='none' d='M0 0h20v20H0V0z'/%3E%3Cpath d='M15.95 10.78c.03-.25.05-.51.05-.78s-.02-.53-.06-.78l1.69-1.32c.15-.12.19-.34.1-.51l-1.6-2.77c-.1-.18-.31-.24-.49-.18l-1.99.8c-.42-.32-.86-.58-1.35-.78L12 2.34c-.03-.2-.2-.34-.4-.34H8.4c-.2 0-.36.14-.39.34l-.3 2.12c-.49.2-.94.47-1.35.78l-1.99-.8c-.18-.07-.39 0-.49.18l-1.6 2.77c-.1.18-.06.39.1.51l1.69 1.32c-.04.25-.07.52-.07.78s.02.53.06.78L2.37 12.1c-.15.12-.19.34-.1.51l1.6 2.77c.1.18.31.24.49.18l1.99-.8c.42.32.86.58 1.35.78l.3 2.12c.04.2.2.34.4.34h3.2c.2 0 .37-.14.39-.34l.3-2.12c.49-.2.94-.47 1.35-.78l1.99.8c.18.07.39 0 .49-.18l1.6-2.77c.1-.18.06-.39-.1-.51l-1.67-1.32zM10 13c-1.65 0-3-1.35-3-3s1.35-3 3-3 3 1.35 3 3-1.35 3-3 3z'/%3E%3C/svg%3E%0A");
background-position: center;
background-repeat: no-repeat;
}
.statsbtn {
background-color: white;
border: none;
background-image: url("data:image/svg+xml,%3Csvg width='36' height='36' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4 6h28v24H4V6zm0 8h28v8H4m9-16v24h10V5.8' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;
}
.iobtn {
background-color: white;
border: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='36' height='36'%3E%3Cpath fill='none' stroke='%23000' stroke-width='2' d='M3 33v-7l6.8-7h16.5l6.7 7v7H3zM3.2 26H33M21 9l5-5.9 5 6h-2.5V15h-5V9H21zm-4.9 0l-5 6-5-6h2.5V3h5v6h2.5z'/%3E%3Cpath fill='none' stroke='%23000' d='M6.1 29.5H10'/%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;
}
.visbtn {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath fill='none' stroke='%23333' d='M2.5 4.5h5v15h-5zM9.5 4.5h5v15h-5zM16.5 4.5h5v15h-5z'/%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;
padding: 15px;
}
#vismenu-content {
left: 0px;
font-family: Verdana, sans-serif;
}
.dark .statsbtn,
.dark .savebtn,
.dark .menubtn,
.dark .iobtn,
.dark .visbtn {
filter: invert(1);
}
.flexbox {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
}
.savebtn {
background-color: #d6d6d6;
width: auto;
height: 30px;
flex-grow: 1;
margin: 5px;
border-radius: 4px;
}
.savebtn:active {
background-color: #0a0;
color: white;
}
.dark .savebtn:active {
/* This will be inverted */
background-color: #b3b;
}
.stats {
border-collapse: collapse;
font-size: 12pt;
table-layout: fixed;
width: 100%;
min-width: 450px;
}
.dark .stats td {
border: 1px solid #bbb;
}
.stats td {
border: 1px solid black;
padding: 5px;
word-wrap: break-word;
text-align: center;
position: relative;
}
#checkbox-stats div {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#checkbox-stats .bar {
background-color: rgba(28, 251, 0, 0.6);
}
.menu {
position: relative;
display: inline-block;
margin: 10px 10px 10px 0px;
}
.menu-content {
font-size: 12pt !important;
text-align: left !important;
font-weight: normal !important;
display: none;
position: absolute;
background-color: white;
right: 0;
min-width: 300px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 100;
padding: 8px;
}
.dark .menu-content {
background-color: #111;
}
.menu:hover .menu-content {
display: block;
}
.menu:hover .menubtn,
.menu:hover .iobtn,
.menu:hover .statsbtn {
background-color: #eee;
}
.menu-label {
display: inline-block;
padding: 8px;
border: 1px solid #ccc;
border-top: 0;
width: calc(100% - 18px);
}
.menu-label-top {
border-top: 1px solid #ccc;
}
.menu-textbox {
float: left;
height: 24px;
margin: 10px 5px;
padding: 5px 5px;
font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
font-size: 14px;
box-sizing: border-box;
border: 1px solid #888;
border-radius: 4px;
outline: none;
background-color: #eee;
transition: background-color 0.2s, border 0.2s;
width: calc(100% - 10px);
}
.menu-textbox.invalid,
.dark .menu-textbox.invalid {
color: red;
}
.dark .menu-textbox {
background-color: #222;
color: #eee;
}
.radio-container {
margin: 4px;
}
.topmostdiv {
width: 100%;
height: 100%;
background-color: white;
transition: background-color 0.3s;
}
#top {
height: 78px;
border-bottom: 2px solid black;
}
.dark #top {
border-bottom: 2px solid #ccc;
}
#dbg {
display: block;
}
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #aaa;
}
::-webkit-scrollbar-thumb {
background: #666;
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: #555;
}
.slider {
-webkit-appearance: none;
width: 100%;
margin: 3px 0;
padding: 0;
outline: none;
opacity: 0.7;
-webkit-transition: .2s;
transition: opacity .2s;
border-radius: 3px;
}
.slider:hover {
opacity: 1;
}
.slider:focus {
outline: none;
}
.slider::-webkit-slider-runnable-track {
-webkit-appearance: none;
width: 100%;
height: 8px;
background: #d3d3d3;
border-radius: 3px;
border: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
width: 15px;
height: 15px;
border-radius: 50%;
background: #0a0;
cursor: pointer;
margin-top: -4px;
}
.dark .slider::-webkit-slider-thumb {
background: #3d3;
}
.slider::-moz-range-thumb {
width: 15px;
height: 15px;
border-radius: 50%;
background: #0a0;
cursor: pointer;
}
.slider::-moz-range-track {
height: 8px;
background: #d3d3d3;
border-radius: 3px;
}
.dark .slider::-moz-range-thumb {
background: #3d3;
}
.slider::-ms-track {
width: 100%;
height: 8px;
border-width: 3px 0;
background: transparent;
border-color: transparent;
color: transparent;
transition: opacity .2s;
}
.slider::-ms-fill-lower {
background: #d3d3d3;
border: none;
border-radius: 3px;
}
.slider::-ms-fill-upper {
background: #d3d3d3;
border: none;
border-radius: 3px;
}
.slider::-ms-thumb {
width: 15px;
height: 15px;
border-radius: 50%;
background: #0a0;
cursor: pointer;
margin: 0;
}
.shameless-plug {
font-size: 0.8em;
text-align: center;
display: block;
}
a {
color: #0278a4;
}
.dark a {
color: #00b9fd;
}
#frontcanvas,
#backcanvas {
touch-action: none;
}
.placeholder {
border: 1px dashed #9f9fda !important;
background-color: #edf2f7 !important;
}
.dragging {
z-index: 999;
}
.dark .dragging>table>tbody>tr {
background-color: #252c30;
}
.dark .placeholder {
filter: invert(1);
}
.column-spacer {
top: 0;
left: 0;
width: calc(100% - 4px);
position: absolute;
cursor: pointer;
user-select: none;
height: 100%;
}
.column-width-handle {
top: 0;
right: 0;
width: 4px;
position: absolute;
cursor: col-resize;
user-select: none;
height: 100%;
}
.column-width-handle:hover {
background-color: #4f99bd;
}
.help-link {
border: 1px solid #0278a4;
padding-inline: 0.3rem;
border-radius: 3px;
cursor: pointer;
}
.dark .help-link {
border: 1px solid #00b9fd;
}
</style>
<script type="text/javascript" >
///////////////////////////////////////////////
/*
Split.js - v1.3.5
MIT License
https://github.com/nathancahill/Split.js
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Split=t()}(this,function(){"use strict";var e=window,t=e.document,n="addEventListener",i="removeEventListener",r="getBoundingClientRect",s=function(){return!1},o=e.attachEvent&&!e[n],a=["","-webkit-","-moz-","-o-"].filter(function(e){var n=t.createElement("div");return n.style.cssText="width:"+e+"calc(9px)",!!n.style.length}).shift()+"calc",l=function(e){return"string"==typeof e||e instanceof String?t.querySelector(e):e};return function(u,c){function z(e,t,n){var i=A(y,t,n);Object.keys(i).forEach(function(t){return e.style[t]=i[t]})}function h(e,t){var n=B(y,t);Object.keys(n).forEach(function(t){return e.style[t]=n[t]})}function f(e){var t=E[this.a],n=E[this.b],i=t.size+n.size;t.size=e/this.size*i,n.size=i-e/this.size*i,z(t.element,t.size,this.aGutterSize),z(n.element,n.size,this.bGutterSize)}function m(e){var t;this.dragging&&((t="touches"in e?e.touches[0][b]-this.start:e[b]-this.start)<=E[this.a].minSize+M+this.aGutterSize?t=E[this.a].minSize+this.aGutterSize:t>=this.size-(E[this.b].minSize+M+this.bGutterSize)&&(t=this.size-(E[this.b].minSize+this.bGutterSize)),f.call(this,t),c.onDrag&&c.onDrag())}function g(){var e=E[this.a].element,t=E[this.b].element;this.size=e[r]()[y]+t[r]()[y]+this.aGutterSize+this.bGutterSize,this.start=e[r]()[G]}function d(){var t=this,n=E[t.a].element,r=E[t.b].element;t.dragging&&c.onDragEnd&&c.onDragEnd(),t.dragging=!1,e[i]("mouseup",t.stop),e[i]("touchend",t.stop),e[i]("touchcancel",t.stop),t.parent[i]("mousemove",t.move),t.parent[i]("touchmove",t.move),delete t.stop,delete t.move,n[i]("selectstart",s),n[i]("dragstart",s),r[i]("selectstart",s),r[i]("dragstart",s),n.style.userSelect="",n.style.webkitUserSelect="",n.style.MozUserSelect="",n.style.pointerEvents="",r.style.userSelect="",r.style.webkitUserSelect="",r.style.MozUserSelect="",r.style.pointerEvents="",t.gutter.style.cursor="",t.parent.style.cursor=""}function S(t){var i=this,r=E[i.a].element,o=E[i.b].element;!i.dragging&&c.onDragStart&&c.onDragStart(),t.preventDefault(),i.dragging=!0,i.move=m.bind(i),i.stop=d.bind(i),e[n]("mouseup",i.stop),e[n]("touchend",i.stop),e[n]("touchcancel",i.stop),i.parent[n]("mousemove",i.move),i.parent[n]("touchmove",i.move),r[n]("selectstart",s),r[n]("dragstart",s),o[n]("selectstart",s),o[n]("dragstart",s),r.style.userSelect="none",r.style.webkitUserSelect="none",r.style.MozUserSelect="none",r.style.pointerEvents="none",o.style.userSelect="none",o.style.webkitUserSelect="none",o.style.MozUserSelect="none",o.style.pointerEvents="none",i.gutter.style.cursor=j,i.parent.style.cursor=j,g.call(i)}function v(e){e.forEach(function(t,n){if(n>0){var i=F[n-1],r=E[i.a],s=E[i.b];r.size=e[n-1],s.size=t,z(r.element,r.size,i.aGutterSize),z(s.element,s.size,i.bGutterSize)}})}function p(){F.forEach(function(e){e.parent.removeChild(e.gutter),E[e.a].element.style[y]="",E[e.b].element.style[y]=""})}void 0===c&&(c={});var y,b,G,E,w=l(u[0]).parentNode,D=e.getComputedStyle(w).flexDirection,U=c.sizes||u.map(function(){return 100/u.length}),k=void 0!==c.minSize?c.minSize:100,x=Array.isArray(k)?k:u.map(function(){return k}),L=void 0!==c.gutterSize?c.gutterSize:10,M=void 0!==c.snapOffset?c.snapOffset:30,O=c.direction||"horizontal",j=c.cursor||("horizontal"===O?"ew-resize":"ns-resize"),C=c.gutter||function(e,n){var i=t.createElement("div");return i.className="gutter gutter-"+n,i},A=c.elementStyle||function(e,t,n){var i={};return"string"==typeof t||t instanceof String?i[e]=t:i[e]=o?t+"%":a+"("+t+"% - "+n+"px)",i},B=c.gutterStyle||function(e,t){return n={},n[e]=t+"px",n;var n};"horizontal"===O?(y="width","clientWidth",b="clientX",G="left","paddingLeft"):"vertical"===O&&(y="height","clientHeight",b="clientY",G="top","paddingTop");var F=[];return E=u.map(function(e,t){var i,s={element:l(e),size:U[t],minSize:x[t]};if(t>0&&(i={a:t-1,b:t,dragging:!1,isFirst:1===t,isLast:t===u.length-1,direction:O,parent:w},i.aGutterSize=L,i.bGutterSize=L,i.isFirst&&(i.aGutterSize=L/2),i.isLast&&(i.bGutterSize=L/2),"row-reverse"===D||"column-reverse"===D)){var a=i.a;i.a=i.b,i.b=a}if(!o&&t>0){var c=C(t,O);h(c,L),c[n]("mousedown",S.bind(i)),c[n]("touchstart",S.bind(i)),w.insertBefore(c,s.element),i.gutter=c}0===t||t===u.length-1?z(s.element,s.size,L/2):z(s.element,s.size,L);var f=s.element[r]()[y];return f<s.minSize&&(s.minSize=f),t>0&&F.push(i),s}),o?{setSizes:v,destroy:p}:{setSizes:v,getSizes:function(){return E.map(function(e){return e.size})},collapse:function(e){if(e===F.length){var t=F[e-1];g.call(t),o||f.call(t,t.size-t.bGutterSize)}else{var n=F[e];g.call(n),o||f.call(n,n.aGutterSize)}},destroy:p}}});
///////////////////////////////////////////////
///////////////////////////////////////////////
// Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>
// This work is free. You can redistribute it and/or modify it
// under the terms of the WTFPL, Version 2
// For more information see LICENSE.txt or http://www.wtfpl.net/
//
// For more information, the home page:
// http://pieroxy.net/blog/pages/lz-string/testing.html
//
// LZ-based compression algorithm, version 1.4.4
var LZString=function(){var o=String.fromCharCode,i={};var n={decompressFromBase64:function(o){return null==o?"":""==o?null:n._decompress(o.length,32,function(n){return function(o,n){if(!i[o]){i[o]={};for(var t=0;t<o.length;t++)i[o][o.charAt(t)]=t}return i[o][n]}("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",o.charAt(n))})},_decompress:function(i,n,t){var r,e,a,s,p,u,l,f=[],c=4,d=4,h=3,v="",g=[],m={val:t(0),position:n,index:1};for(r=0;r<3;r+=1)f[r]=r;for(a=0,p=Math.pow(2,2),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;l=o(a);break;case 2:return""}for(f[3]=l,e=l,g.push(l);;){if(m.index>i)return"";for(a=0,p=Math.pow(2,h),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;switch(l=a){case 0:for(a=0,p=Math.pow(2,8),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 1:for(a=0,p=Math.pow(2,16),u=1;u!=p;)s=m.val&m.position,m.position>>=1,0==m.position&&(m.position=n,m.val=t(m.index++)),a|=(s>0?1:0)*u,u<<=1;f[d++]=o(a),l=d-1,c--;break;case 2:return g.join("")}if(0==c&&(c=Math.pow(2,h),h++),f[l])v=f[l];else{if(l!==d)return null;v=e+e.charAt(0)}g.push(v),f[d++]=e+v.charAt(0),e=v,0==--c&&(c=Math.pow(2,h),h++)}}};return n}();"function"==typeof define&&define.amd?define(function(){return LZString}):"undefined"!=typeof module&&null!=module?module.exports=LZString:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return LZString});
///////////////////////////////////////////////
///////////////////////////////////////////////
/*!
* PEP v0.4.3 | https://github.com/jquery/PEP
* Copyright jQuery Foundation and other contributors | http://jquery.org/license
*/
!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.PointerEventsPolyfill=b()}(this,function(){"use strict";function a(a,b){b=b||Object.create(null);var c=document.createEvent("Event");c.initEvent(a,b.bubbles||!1,b.cancelable||!1);
for(var d,e=2;e<m.length;e++)d=m[e],c[d]=b[d]||n[e];c.buttons=b.buttons||0;
var f=0;return f=b.pressure&&c.buttons?b.pressure:c.buttons?.5:0,c.x=c.clientX,c.y=c.clientY,c.pointerId=b.pointerId||0,c.width=b.width||0,c.height=b.height||0,c.pressure=f,c.tiltX=b.tiltX||0,c.tiltY=b.tiltY||0,c.twist=b.twist||0,c.tangentialPressure=b.tangentialPressure||0,c.pointerType=b.pointerType||"",c.hwTimestamp=b.hwTimestamp||0,c.isPrimary=b.isPrimary||!1,c}function b(){this.array=[],this.size=0}function c(a,b,c,d){this.addCallback=a.bind(d),this.removeCallback=b.bind(d),this.changedCallback=c.bind(d),A&&(this.observer=new A(this.mutationWatcher.bind(this)))}function d(a){return"body /shadow-deep/ "+e(a)}function e(a){return'[touch-action="'+a+'"]'}function f(a){return"{ -ms-touch-action: "+a+"; touch-action: "+a+"; }"}function g(){if(F){D.forEach(function(a){String(a)===a?(E+=e(a)+f(a)+"\n",G&&(E+=d(a)+f(a)+"\n")):(E+=a.selectors.map(e)+f(a.rule)+"\n",G&&(E+=a.selectors.map(d)+f(a.rule)+"\n"))});var a=document.createElement("style");a.textContent=E,document.head.appendChild(a)}}function h(){if(!window.PointerEvent){if(window.PointerEvent=a,window.navigator.msPointerEnabled){var b=window.navigator.msMaxTouchPoints;Object.defineProperty(window.navigator,"maxTouchPoints",{value:b,enumerable:!0}),u.registerSource("ms",_)}else Object.defineProperty(window.navigator,"maxTouchPoints",{value:0,enumerable:!0}),u.registerSource("mouse",N),void 0!==window.ontouchstart&&u.registerSource("touch",V);u.register(document)}}function i(a){if(!u.pointermap.has(a)){var b=new Error("InvalidPointerId");throw b.name="InvalidPointerId",b}}function j(a){for(var b=a.parentNode;b&&b!==a.ownerDocument;)b=b.parentNode;if(!b){var c=new Error("InvalidStateError");throw c.name="InvalidStateError",c}}function k(a){var b=u.pointermap.get(a);return 0!==b.buttons}function l(){window.Element&&!Element.prototype.setPointerCapture&&Object.defineProperties(Element.prototype,{setPointerCapture:{value:W},releasePointerCapture:{value:X},hasPointerCapture:{value:Y}})}
var m=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","pageX","pageY"],n=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0],o=window.Map&&window.Map.prototype.forEach,p=o?Map:b;b.prototype={set:function(a,b){return void 0===b?this["delete"](a):(this.has(a)||this.size++,void(this.array[a]=b))},has:function(a){return void 0!==this.array[a]},"delete":function(a){this.has(a)&&(delete this.array[a],this.size--)},get:function(a){return this.array[a]},clear:function(){this.array.length=0,this.size=0},forEach:function(a,b){return this.array.forEach(function(c,d){a.call(b,c,d,this)},this)}};var q=["bubbles","cancelable","view","detail","screenX","screenY","clientX","clientY","ctrlKey","altKey","shiftKey","metaKey","button","relatedTarget","buttons","pointerId","width","height","pressure","tiltX","tiltY","pointerType","hwTimestamp","isPrimary","type","target","currentTarget","which","pageX","pageY","timeStamp"],r=[!1,!1,null,null,0,0,0,0,!1,!1,!1,!1,0,null,0,0,0,0,0,0,0,"",0,!1,"",null,null,0,0,0,0],s={pointerover:1,pointerout:1,pointerenter:1,pointerleave:1},t="undefined"!=typeof SVGElementInstance,u={pointermap:new p,eventMap:Object.create(null),captureInfo:Object.create(null),eventSources:Object.create(null),eventSourceList:[],registerSource:function(a,b){var c=b,d=c.events;d&&(d.forEach(function(a){c[a]&&(this.eventMap[a]=c[a].bind(c))},this),this.eventSources[a]=c,this.eventSourceList.push(c))},register:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++)
b.register.call(b,a)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++)
b.unregister.call(b,a)},contains:function(a,b){try{return a.contains(b)}catch(c){return!1}},down:function(a){a.bubbles=!0,this.fireEvent("pointerdown",a)},move:function(a){a.bubbles=!0,this.fireEvent("pointermove",a)},up:function(a){a.bubbles=!0,this.fireEvent("pointerup",a)},enter:function(a){a.bubbles=!1,this.fireEvent("pointerenter",a)},leave:function(a){a.bubbles=!1,this.fireEvent("pointerleave",a)},over:function(a){a.bubbles=!0,this.fireEvent("pointerover",a)},out:function(a){a.bubbles=!0,this.fireEvent("pointerout",a)},cancel:function(a){a.bubbles=!0,this.fireEvent("pointercancel",a)},leaveOut:function(a){this.out(a),this.propagate(a,this.leave,!1)},enterOver:function(a){this.over(a),this.propagate(a,this.enter,!0)},eventHandler:function(a){if(!a._handledByPE){var b=a.type,c=this.eventMap&&this.eventMap[b];c&&c(a),a._handledByPE=!0}},listen:function(a,b){b.forEach(function(b){this.addEvent(a,b)},this)},unlisten:function(a,b){b.forEach(function(b){this.removeEvent(a,b)},this)},addEvent:function(a,b){a.addEventListener(b,this.boundHandler)},removeEvent:function(a,b){a.removeEventListener(b,this.boundHandler)},makeEvent:function(b,c){this.captureInfo[c.pointerId]&&(c.relatedTarget=null);var d=new a(b,c);return c.preventDefault&&(d.preventDefault=c.preventDefault),d._target=d._target||c.target,d},fireEvent:function(a,b){var c=this.makeEvent(a,b);return this.dispatchEvent(c)},cloneEvent:function(a){for(var b,c=Object.create(null),d=0;d<q.length;d++)b=q[d],c[b]=a[b]||r[d],!t||"target"!==b&&"relatedTarget"!==b||c[b]instanceof SVGElementInstance&&(c[b]=c[b].correspondingUseElement);return a.preventDefault&&(c.preventDefault=function(){a.preventDefault()}),c},getTarget:function(a){var b=this.captureInfo[a.pointerId];return b?a._target!==b&&a.type in s?void 0:b:a._target},propagate:function(a,b,c){for(var d=a.target,e=[];d!==document&&!d.contains(a.relatedTarget);) if(e.push(d),d=d.parentNode,!d)return;c&&e.reverse(),e.forEach(function(c){a.target=c,b.call(this,a)},this)},setCapture:function(b,c,d){this.captureInfo[b]&&this.releaseCapture(b,d),this.captureInfo[b]=c,this.implicitRelease=this.releaseCapture.bind(this,b,d),document.addEventListener("pointerup",this.implicitRelease),document.addEventListener("pointercancel",this.implicitRelease);var e=new a("gotpointercapture");e.pointerId=b,e._target=c,d||this.asyncDispatchEvent(e)},releaseCapture:function(b,c){var d=this.captureInfo[b];if(d){this.captureInfo[b]=void 0,document.removeEventListener("pointerup",this.implicitRelease),document.removeEventListener("pointercancel",this.implicitRelease);var e=new a("lostpointercapture");e.pointerId=b,e._target=d,c||this.asyncDispatchEvent(e)}},dispatchEvent:/*scope.external.dispatchEvent || */function(a){var b=this.getTarget(a);if(b)return b.dispatchEvent(a)},asyncDispatchEvent:function(a){requestAnimationFrame(this.dispatchEvent.bind(this,a))}};u.boundHandler=u.eventHandler.bind(u);var v={shadow:function(a){if(a)return a.shadowRoot||a.webkitShadowRoot},canTarget:function(a){return a&&Boolean(a.elementFromPoint)},targetingShadow:function(a){var b=this.shadow(a);if(this.canTarget(b))return b},olderShadow:function(a){var b=a.olderShadowRoot;if(!b){var c=a.querySelector("shadow");c&&(b=c.olderShadowRoot)}return b},allShadows:function(a){for(var b=[],c=this.shadow(a);c;)b.push(c),c=this.olderShadow(c);return b},searchRoot:function(a,b,c){if(a){var d,e,f=a.elementFromPoint(b,c);for(e=this.targetingShadow(f);e;){if(d=e.elementFromPoint(b,c)){var g=this.targetingShadow(d);return this.searchRoot(g,b,c)||d} e=this.olderShadow(e)} return f}},owner:function(a){
for(var b=a;b.parentNode;)b=b.parentNode;
return b.nodeType!==Node.DOCUMENT_NODE&&b.nodeType!==Node.DOCUMENT_FRAGMENT_NODE&&(b=document),b},findTarget:function(a){var b=a.clientX,c=a.clientY,d=this.owner(a.target);
return d.elementFromPoint(b,c)||(d=document),this.searchRoot(d,b,c)}},w=Array.prototype.forEach.call.bind(Array.prototype.forEach),x=Array.prototype.map.call.bind(Array.prototype.map),y=Array.prototype.slice.call.bind(Array.prototype.slice),z=Array.prototype.filter.call.bind(Array.prototype.filter),A=window.MutationObserver||window.WebKitMutationObserver,B="[touch-action]",C={subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0,attributeFilter:["touch-action"]};c.prototype={watchSubtree:function(a){
//
this.observer&&v.canTarget(a)&&this.observer.observe(a,C)},enableOnSubtree:function(a){this.watchSubtree(a),a===document&&"complete"!==document.readyState?this.installOnLoad():this.installNewSubtree(a)},installNewSubtree:function(a){w(this.findElements(a),this.addElement,this)},findElements:function(a){return a.querySelectorAll?a.querySelectorAll(B):[]},removeElement:function(a){this.removeCallback(a)},addElement:function(a){this.addCallback(a)},elementChanged:function(a,b){this.changedCallback(a,b)},concatLists:function(a,b){return a.concat(y(b))},
installOnLoad:function(){document.addEventListener("readystatechange",function(){"complete"===document.readyState&&this.installNewSubtree(document)}.bind(this))},isElement:function(a){return a.nodeType===Node.ELEMENT_NODE},flattenMutationTree:function(a){
var b=x(a,this.findElements,this);
return b.push(z(a,this.isElement)),b.reduce(this.concatLists,[])},mutationWatcher:function(a){a.forEach(this.mutationHandler,this)},mutationHandler:function(a){if("childList"===a.type){var b=this.flattenMutationTree(a.addedNodes);b.forEach(this.addElement,this);var c=this.flattenMutationTree(a.removedNodes);c.forEach(this.removeElement,this)}else"attributes"===a.type&&this.elementChanged(a.target,a.oldValue)}};var D=["none","auto","pan-x","pan-y",{rule:"pan-x pan-y",selectors:["pan-x pan-y","pan-y pan-x"]}],E="",F=window.PointerEvent||window.MSPointerEvent,G=!window.ShadowDOMPolyfill&&document.head.createShadowRoot,H=u.pointermap,I=25,J=[1,4,2,8,16],K=!1;try{K=1===new MouseEvent("test",{buttons:1}).buttons}catch(L){}
var M,N={POINTER_ID:1,POINTER_TYPE:"mouse",events:["mousedown","mousemove","mouseup","mouseover","mouseout"],register:function(a){u.listen(a,this.events)},unregister:function(a){u.unlisten(a,this.events)},lastTouches:[],
isEventSimulatedFromTouch:function(a){for(var b,c=this.lastTouches,d=a.clientX,e=a.clientY,f=0,g=c.length;f<g&&(b=c[f]);f++){
var h=Math.abs(d-b.x),i=Math.abs(e-b.y);if(h<=I&&i<=I)return!0}},prepareEvent:function(a){var b=u.cloneEvent(a),c=b.preventDefault;return b.preventDefault=function(){a.preventDefault(),c()},b.pointerId=this.POINTER_ID,b.isPrimary=!0,b.pointerType=this.POINTER_TYPE,b},prepareButtonsForMove:function(a,b){var c=H.get(this.POINTER_ID);
0!==b.which&&c?a.buttons=c.buttons:a.buttons=0,b.buttons=a.buttons},mousedown:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=H.get(this.POINTER_ID),c=this.prepareEvent(a);K||(c.buttons=J[c.button],b&&(c.buttons|=b.buttons),a.buttons=c.buttons),H.set(this.POINTER_ID,a),b&&0!==b.buttons?u.move(c):u.down(c)}},mousemove:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,H.set(this.POINTER_ID,a),u.move(b)}},mouseup:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=H.get(this.POINTER_ID),c=this.prepareEvent(a);if(!K){var d=J[c.button];
c.buttons=b?b.buttons&~d:0,a.buttons=c.buttons}H.set(this.POINTER_ID,a),
c.buttons&=~J[c.button],0===c.buttons?u.up(c):u.move(c)}},mouseover:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,H.set(this.POINTER_ID,a),u.enterOver(b)}},mouseout:function(a){if(!this.isEventSimulatedFromTouch(a)){var b=this.prepareEvent(a);K||this.prepareButtonsForMove(b,a),b.button=-1,u.leaveOut(b)}},cancel:function(a){var b=this.prepareEvent(a);u.cancel(b),this.deactivateMouse()},deactivateMouse:function(){H["delete"](this.POINTER_ID)}},O=u.captureInfo,P=v.findTarget.bind(v),Q=v.allShadows.bind(v),R=u.pointermap,S=2500,T=200,U="touch-action",V={events:["touchstart","touchmove","touchend","touchcancel"],register:function(a){M.enableOnSubtree(a)},unregister:function(){},elementAdded:function(a){var b=a.getAttribute(U),c=this.touchActionToScrollType(b);c&&(a._scrollType=c,u.listen(a,this.events),
Q(a).forEach(function(a){a._scrollType=c,u.listen(a,this.events)},this))},elementRemoved:function(a){a._scrollType=void 0,u.unlisten(a,this.events),
Q(a).forEach(function(a){a._scrollType=void 0,u.unlisten(a,this.events)},this)},elementChanged:function(a,b){var c=a.getAttribute(U),d=this.touchActionToScrollType(c),e=this.touchActionToScrollType(b);
d&&e?(a._scrollType=d,Q(a).forEach(function(a){a._scrollType=d},this)):e?this.elementRemoved(a):d&&this.elementAdded(a)},scrollTypes:{EMITTER:"none",XSCROLLER:"pan-x",YSCROLLER:"pan-y",SCROLLER:/^(?:pan-x pan-y)|(?:pan-y pan-x)|auto$/},touchActionToScrollType:function(a){var b=a,c=this.scrollTypes;return"none"===b?"none":b===c.XSCROLLER?"X":b===c.YSCROLLER?"Y":c.SCROLLER.exec(b)?"XY":void 0},POINTER_TYPE:"touch",firstTouch:null,isPrimaryTouch:function(a){return this.firstTouch===a.identifier},setPrimaryTouch:function(a){
(0===R.size||1===R.size&&R.has(1))&&(this.firstTouch=a.identifier,this.firstXY={X:a.clientX,Y:a.clientY},this.scrolling=!1,this.cancelResetClickCount())},removePrimaryPointer:function(a){a.isPrimary&&(this.firstTouch=null,this.firstXY=null,this.resetClickCount())},clickCount:0,resetId:null,resetClickCount:function(){var a=function(){this.clickCount=0,this.resetId=null}.bind(this);this.resetId=setTimeout(a,T)},cancelResetClickCount:function(){this.resetId&&clearTimeout(this.resetId)},typeToButtons:function(a){var b=0;return"touchstart"!==a&&"touchmove"!==a||(b=1),b},touchToPointer:function(a){var b=this.currentTouchEvent,c=u.cloneEvent(a),d=c.pointerId=a.identifier+2;c.target=O[d]||P(c),c.bubbles=!0,c.cancelable=!0,c.detail=this.clickCount,c.button=0,c.buttons=this.typeToButtons(b.type),c.width=2*(a.radiusX||a.webkitRadiusX||0),c.height=2*(a.radiusY||a.webkitRadiusY||0),c.pressure=a.force||a.webkitForce||.5,c.isPrimary=this.isPrimaryTouch(a),c.pointerType=this.POINTER_TYPE,
c.altKey=b.altKey,c.ctrlKey=b.ctrlKey,c.metaKey=b.metaKey,c.shiftKey=b.shiftKey;
var e=this;return c.preventDefault=function(){e.scrolling=!1,e.firstXY=null,b.preventDefault()},c},processTouches:function(a,b){var c=a.changedTouches;this.currentTouchEvent=a;for(var d,e=0;e<c.length;e++)d=c[e],b.call(this,this.touchToPointer(d))},
shouldScroll:function(a){if(this.firstXY){var b,c=a.currentTarget._scrollType;if("none"===c)
b=!1;else if("XY"===c)
b=!0;else{var d=a.changedTouches[0],e=c,f="Y"===c?"X":"Y",g=Math.abs(d["client"+e]-this.firstXY[e]),h=Math.abs(d["client"+f]-this.firstXY[f]);
b=g>=h}return this.firstXY=null,b}},findTouch:function(a,b){for(var c,d=0,e=a.length;d<e&&(c=a[d]);d++)if(c.identifier===b)return!0},
vacuumTouches:function(a){var b=a.touches;
if(R.size>=b.length){var c=[];R.forEach(function(a,d){
if(1!==d&&!this.findTouch(b,d-2)){var e=a.out;c.push(e)}},this),c.forEach(this.cancelOut,this)}},touchstart:function(a){this.vacuumTouches(a),this.setPrimaryTouch(a.changedTouches[0]),this.dedupSynthMouse(a),this.scrolling||(this.clickCount++,this.processTouches(a,this.overDown))},overDown:function(a){R.set(a.pointerId,{target:a.target,out:a,outTarget:a.target}),u.enterOver(a),u.down(a)},touchmove:function(a){this.scrolling||(this.shouldScroll(a)?(this.scrolling=!0,this.touchcancel(a)):(a.preventDefault(),this.processTouches(a,this.moveOverOut)))},moveOverOut:function(a){var b=a,c=R.get(b.pointerId);
if(c){var d=c.out,e=c.outTarget;u.move(b),d&&e!==b.target&&(d.relatedTarget=b.target,b.relatedTarget=e,
d.target=e,b.target?(u.leaveOut(d),u.enterOver(b)):(
b.target=e,b.relatedTarget=null,this.cancelOut(b))),c.out=b,c.outTarget=b.target}},touchend:function(a){this.dedupSynthMouse(a),this.processTouches(a,this.upOut)},upOut:function(a){this.scrolling||(u.up(a),u.leaveOut(a)),this.cleanUpPointer(a)},touchcancel:function(a){this.processTouches(a,this.cancelOut)},cancelOut:function(a){u.cancel(a),u.leaveOut(a),this.cleanUpPointer(a)},cleanUpPointer:function(a){R["delete"](a.pointerId),this.removePrimaryPointer(a)},
dedupSynthMouse:function(a){var b=N.lastTouches,c=a.changedTouches[0];
if(this.isPrimaryTouch(c)){
var d={x:c.clientX,y:c.clientY};b.push(d);var e=function(a,b){var c=a.indexOf(b);c>-1&&a.splice(c,1)}.bind(null,b,d);setTimeout(e,S)}}};M=new c(V.elementAdded,V.elementRemoved,V.elementChanged,V);var W,X,Y,Z=u.pointermap,$=window.MSPointerEvent&&"number"==typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE,_={events:["MSPointerDown","MSPointerMove","MSPointerUp","MSPointerOut","MSPointerOver","MSPointerCancel","MSGotPointerCapture","MSLostPointerCapture"],register:function(a){u.listen(a,this.events)},unregister:function(a){u.unlisten(a,this.events)},POINTER_TYPES:["","unavailable","touch","pen","mouse"],prepareEvent:function(a){var b=a;return $&&(b=u.cloneEvent(a),b.pointerType=this.POINTER_TYPES[a.pointerType]),b},cleanup:function(a){Z["delete"](a)},MSPointerDown:function(a){Z.set(a.pointerId,a);var b=this.prepareEvent(a);u.down(b)},MSPointerMove:function(a){var b=this.prepareEvent(a);u.move(b)},MSPointerUp:function(a){var b=this.prepareEvent(a);u.up(b),this.cleanup(a.pointerId)},MSPointerOut:function(a){var b=this.prepareEvent(a);u.leaveOut(b)},MSPointerOver:function(a){var b=this.prepareEvent(a);u.enterOver(b)},MSPointerCancel:function(a){var b=this.prepareEvent(a);u.cancel(b),this.cleanup(a.pointerId)},MSLostPointerCapture:function(a){var b=u.makeEvent("lostpointercapture",a);u.dispatchEvent(b)},MSGotPointerCapture:function(a){var b=u.makeEvent("gotpointercapture",a);u.dispatchEvent(b)}},aa=window.navigator;aa.msPointerEnabled?(W=function(a){i(a),j(this),k(a)&&(u.setCapture(a,this,!0),this.msSetPointerCapture(a))},X=function(a){i(a),u.releaseCapture(a,!0),this.msReleasePointerCapture(a)}):(W=function(a){i(a),j(this),k(a)&&u.setCapture(a,this)},X=function(a){i(a),u.releaseCapture(a)}),Y=function(a){return!!u.captureInfo[a]},g(),h(),l();var ba={dispatcher:u,Installer:c,PointerEvent:a,PointerMap:p,targetFinding:v};return ba});
///////////////////////////////////////////////
///////////////////////////////////////////////
var config = {"dark_mode": false, "show_pads": true, "show_fabrication": false, "show_silkscreen": true, "highlight_pin1": false, "redraw_on_drag": true, "board_rotation": 0, "checkboxes": "Sourced,Placed", "bom_view": "left-right", "layer_view": "FB", "offset_back_rotation": false, "kicad_text_formatting": true, "fields": ["Value", "Footprint"]}
///////////////////////////////////////////////
///////////////////////////////////////////////
var pcbdata = JSON.parse(LZString.decompressFromBase64("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VE5U7lduV1fRyVZ2VClWtFeeAXlVwgP2Vp5WDleeVIGCXlQBAAVX5VeCViVW1FaFVpVUrFR5YlVXRVdVVE1UEVaCV0lX/lUlVBpV7lalVOeJ+FRpVYFXdVQxVckRn9KZgQuCBVWxVxJVIVeCcRJW7kHWV6FWKgFNVepVlVWJVxpWSVfNVTxUclSRVyVXyVRpcFFVOAAKVQpUbVRlV4FW+VUxVPNAKsAdVG5XsVUqVJ1XcVWFVZJX8VZFVc1W8VSAAt1USVVVVD1WJFRaVu5UpVV2VilW/FcpVDpVOleIALpVulUcuulUgAGoVgpWGVf6V6lyziedg9xWdglZVtgA2VVYVvcA2FUFVjlWuFUdUKZX6gGmVnlXfVd5VmVX2VL3KVPhXlWOV9lUJVckVo1WPle8Vq5VfFYJVMNUS1T+VdVULVSNVbZXLVWjVrVVpVe1VXNWdVSeVZ5XdhBTVAtWsVRuVhVU7lWNVnKAy1RVVUtX3VbDVtVVSVQVVDVUcVU1VL1UtVW9V8JVq1YiVP1VbVd4gVOAh5brVhZXy1SLVitXFVeWVJtWrFVdVtZU1VeKZ8VXDVb7VD5VK1a9VLRWq1U0AHVU2AF1VWtVBaqu6hUYXILBV3tWOFexVx1UzladVENUalVDVwdUxVRqVeFXMlebVRFVPVaMGQFWrVfqAn1U0VerVidWa1T1V3YTKOd0EMpVt1ULVtgAg1ZxVYNWPQPnVfFValQJVVJVRVddVuFXiVWXViNVBVTJVPdXR1Q7VsdU5BEpVKlU41ewAeNVaVQTVDVZE1RwW7ADaFWTV2tXQxc2Jg1U8gKYV5hUxlSZidlUPFQ5VzlVJlc5VbNVXgBzVY07rVS7V3NW/VbzVL+pe4IfVF9XC1TUVftVpFeLVodWLlWbVk9WB1R5Y4dXHIM8VAFWo1THVRxXO1b2VGtU+VbzV+9W5VUSlndWbFTbVRVW/1f3V5VVB1YA101VLFcA1MNX1VVuVttVY+M1V5FVO1fHVDdVJ1c3VvwYn2MAQSDXLwZ/VEdXf1VHV/tVPlbNVmFX7ANhVM1XhVasVoDXNlZHVgFUrVejVbVUUNU/VcDU81eTVOVQdosh+HZBA1VnVR1XPVbnVKFXjVaJVhdU4NaPVolWl1QQ10lWV1e8g1dXCNQAgH1VUVV9VYjWN1fA1DmIsVc2JUoYzYPBV3dX/mCRiKpU8VedVajXD1dLVN1VaNeXVOjXT6pA1c9VHFYvV2NVqVbjVGlX41R6VG9UAAMoAAOqaFdvVfpW6FeeVxi7bbLCuopCWVeYVgx4+UrBScZWOFYPE25WooCRidPzuVemVlDUbINtVJZDQrux4opDwVcig0+pFBHT8mDVeACgABQAUoIsg7gAcoDvBJyJ9YHgAOYD21WQ1fYSUVdRVD/4J1aEVJTU5ELtcwpDgVIw1Y/h32EcQNTUB1WVV9TWNNaMgYAAtNe8QsIViIrOwnTWKgPo1KtUL1ZjVS9WBNSvVwTVr1aE17jBE1XVWO9VxNRbqUCLptkYVBZULicfVEZWn1dGVDNWxlUzVV9VOVW4Vt9VKgPfVcICgAIM1TdXDNdUwZRIxFbc1KDX8Ncw1pZXqIGw1PDWTVeo1IdXsNZPVRFWLVaLVs9U9NXHVvzVFNeY1lzUbwV7VQ1WoNUQ16DWuVX/V8LXQ1ebV+DWeNdbV+LWG1d01q1XpVc/VbtWSlWwIcezAtdeVoLUEski1P9WEtZg1cZFF1dw1sVW8Nb+VTDUllT41qLVrVX81mLXXFSjonwbp1SI6mdVd1Qo1owYONco1xtU3VS41OpUj1XC1mjXj1do1j1XblVXVQjXbNbXVxjX11aY1VDXDNX2IQLXPIJY1uLUKlU9V9jX9OI41mDUXVRw1b5XqtcXVBpUeNQi1XjXz2paV+rWO1baVuzUBNRcA6lUdFSE1OlUb1QAAIsYAioDnNcZVErWwEL1QEGrk0Ck1EZVkKNeSFTVmlXUwTQrk0CRi4JKeFezVHlUP1WK1EjWXNfG1pgzk0FPVJNj9CEUEm2BQtW4AzTUcoDy1eDX/1XFVArVj+DSy2aJbNX61hjV11QM1GLUAtaW1vZzltYdV8DLVtXMwdTVLNQ217GAbNdS1BjURFT21jmBitf21qinoqBfArLUrAM/isZUkYjW1RLX2wPW1l1VTtV01KLU11VeA87W0tXA1S7UkxP9QY+ynUFPVryZCAKO1szU7QHu1zrWcoNO1R7WztWe1ZjUXtb1Qnu5DtcDVxJU/gA+1tbX7AM+1Q9W/IG+1cNW+tfPVn7Wmtd3q1TC9UK+of7VPFZW1K4BAdTu1fLUwta41pLXNtfy1ctWOFUD8vtgdtVB1fjUBtRMg+zWP1UEVobVNAITVahVbwjE1RlVNAFi1kIUeah/V1NUn1c81Z9XPNWu1zNXJlWLVBTWc1Sa1/zVwdbAQFrVZMcg1EzVgtUK1RtUW1ZLVWHVANTh1IDWttZJ1EDWkNTS1MDVHleI1L9XnlVc1dGqsdZk1IxVoNVS1M5WPtdC1+7Vydbg1MnWy1VbVBnWUtXbV77XbNTB1QnUMtdOOunV5VWu14DVLVaw16HUvldg15nUaNRh12rWCtSp1M7UOdep1m1XJ1XNqkrV1UnB+u9astdnVijXFVXnVKjWQ1YPVJLXydWPVd1WetTq1HFV6tcrVXbVztUa1vbWCdeK1c2rmtXRq1jVyNXK1trWVMA414NXJdQXVqXWNtbDV8NUT1RZ1FdXeNap1H7X+NWR1QbVBNSG1RzVhtSc1ahVxyTG1jHUp1Yg1/sAEOnc1NNUXAHTVnHWWFdx1bzUs1SLsXnX8dYW1GLXFtSnVb9X50FN17nXstSw1GDX1dd+VptV+dRq1AXXktUF1nnWdtdB1YXWu1RF1+OATdeHAu3USdZuVWoLENeaOh3XKtcS1TXVktVl1NnVvdUVV13XQNaI1sDVmNZt16aK0NdrgfxDsOta1bLUK1Qd1nLVHdVg1mHVqtW41xLV8NXD1AjXCtWp1IPUadWD1WnXa1VI1+dATQBpycXXytQSV1YBJdV91qjWNdbC1brVw1R61bXVetZyVIXX5dYa1/TULtRt1BPW/Bla1u1ibYHPQtjXEVXa1hJV1ddT1KXUYVWB1WFWutby1JdVatRd1YDUo1Z11DnXddapVvXUHNf117ADaVdR1EbU+lfR1u9UStdVQ5zB8EEmIybXWVam1hVqstZm189rZtf04ubVuVfm1hTXFdeD1mzCG9e6Ap7T+iBW1z+I29WXA27Xjtcs1L7VcNU216PVKdT2E7bVK9Wz1J7WFdZz1xXUAta71eTBPBmT1I7XgnL71SPWgdes1h7WQdXl189Xs9SY1oPVDNXB1cfX+njDI+nVgNXe1m7X9OCn1YvUgdRO1ZnXgdRn1QPXlHH01ufV49fn1kpUrUErUGVbudWX1aHV+9ZO11WAQdQ31IFW3dd5VsfV2EEB4VRGJ9e8SPfWp9TX1L7WwAAP1xHUHlcP1mnX0tdp1hfWb5A0ElTCe9U2G0/VV9cd1vnWo9dh1wfV4dab4YfWs9dB1KvXL1RR1mlWa9evVJzWRtbr1IACjdQGVpXW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DloOGg9aD7ABVQn2V4bWKgESDYTUBg5G1kEDwAFIABADlHm8Aaxgxg/qDMoNyg0IdbwAZKkWDcYPBg0aDZYPiADhAXRWpg+IA6YOZg09AOYNoAHmD9C5vAFG1KYNpgx6DLYPZg7mD+YN1g4qDnVXig+aDV+Dxg6WDIoM6g51VjYPrXX2DWYMRAG2DHYMig6aDo4PKg7GDFoPVg4mDIAAYTT2DTYMLg62Dg4Odg3WD0YOzg72DGYOLg8uDQ4PsAKr9+4Pzg5eDR4PtgzeDu4OFg+eDB4OPgwODz4Mng7eDFYPvgw+D/YNLg8eDCoMsg+uDeoNVgyWDNYMKg6KDRNUbg8WDVoPGg+IAYd33g6Ddh4NfgyuDbwBJfZWDW4OQQzuDPGYoQ82DV4PAQ5hDtoNgQ+ODaoO4Q4hD7AAb3QRDaENAQ9+DCoPJg51VYYNyFSEAXADtXUQA5gMQAEEVHoMVAPYA7gBRVSxDPQDsQ5xDKADcQ14A1YPtXQAAwsYA7V2FomE1fEMCQ/AAAABqQRXqA+4AdC7wAAAAEjzgeADeA5hDb4Nig3BDEEMIQ7WD1EN/g0ZD4EM4Q6ZDPVVYvX2VDoP1NZfgW+D1NYqADkMoAE5DCyAoALZDI4OJ1XODqEOfgwf82oMzg00DahWPtK08AACSfoPhQ4qAhIMeg6FDFuiX4JFD4UOOg8/gUkNSQ7QA8ADXwGgA18B6Q46DNAJ6Q4WiaYC+AAQAVIOngNqDa4O+QxeDgEO2Q6RDIUNhQ4lDUUMxQyn9oYP1Q0lDKUNpQxlDWUM5Q3gAeUPbzAVDRUMlQ9SDtkNng3VDCUNJQ01D6YPxQweADUPJQw6DqUPpQ5lDmIDZQ5iAuUMOg/lDeACFQ8VDpUM5gNqDhkMgAC1DY0ONQ+IAsUMHQ9NDbUNzQx1Di0NMAMtDTACrQ+tDm0ODQ2VD4gAaQF0Vp0MRQ0dD7AAnQ1ND70OzQ/NDnUNLQ91DvUMaAP1DW0NDQyaDoEOjQ2dDH0MgAF9DrUNRQ+1DC0NdQytDPUNrQ31DG0MDQ9tDPVXpAK9D30MzQxNDcUNww79Dl0NIw7dDKMP3QxjDYMPiAOQQOMOEw/jDb0MzQwjD/0PXQ4DDqMPAw+jDoMNPQ+wA2IJ2g7jD40PHQ81DvMPwwxdDiMMAw8jDQMOkww9DmMMmg7VD+0OCw9FD/MOTQ4TDjMNXQzdDd0Now5LDlMNcwyNDssO0wwrDBMOHQ0TDIsPMw2LDrMMSwxTDnMMgAHOANMMGw3TDcsPKwyTDasNswxrDFsNNgNbDUMPyw59DAsNKw8LDTMOqw2TD6sPmwztDVMMWQzrDNsN6w/TD50N/QyrDLMPkwxzDQcPsAHDgbsM/Q7bD3sNRww7D/sNOw4HDPVU3wF0V3oNwAPYADoMoAMQAHKB5w0EAhcPFw46DeQCag8oAaACxgHpD2cM+Q6HD7sMpwwbD9sOiw6TD4sMgw49D8cMgAKkADYNVQ4uD2cMVQ6DdA8NPQJcV0hWjTqUEAQOog0kDGhVQgKEDahUdghED3pUPA7PDawOzwwkDC8MpA7PD6QOzw1kDs8P1g3UKqQPE1QUDCEBFAy0D2QPE1WUDGQPE1ZUDB8M1A9EDxNX1AzuApoD7QxE1BQNI6t0DkTXRNV0DdwNg3Q8D0wPPA/0DbwP9Ax8D/QNfA9sDvwOAg5G1AIPgg8CD4INlA8iDEIM0pD690INnw5G1cIMEuDiDgQP4g2jeXsA9A50DLwO+vXiVSCMjA4cDPOCxA9MDQ4Cog1QjswPoI0l9eJXQI+B9U130I2sDLwObA1OV2wPxALsDGwMHAxsDxwPbA1i9eJXnA56AlwP9A+Dd2xW3A6/DkbVIgxsDqINXAxiD4INYg96ABIMp/Wn9nQNFHF1OaYDygPYA8ADKA8EAuhXSFfVdFgPwAEfgpxWDTisgA0GwEMoAMUpAAAA"))
///////////////////////////////////////////////
///////////////////////////////////////////////
/* 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 overwriteSettings(newSettings) {
initDone = false;
Object.assign(settings, newSettings);
writeStorage("bomlayout", settings.bomlayout);
writeStorage("bommode", settings.bommode);
writeStorage("canvaslayout", settings.canvaslayout);
writeStorage("bomCheckboxes", settings.checkboxes.join(","));
document.getElementById("bomCheckboxes").value = settings.checkboxes.join(",");
for (var checkbox of settings.checkboxes) {
writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
}
writeStorage("markWhenChecked", settings.markWhenChecked);
padsVisible(settings.renderPads);
document.getElementById("padsCheckbox").checked = settings.renderPads;
fabricationVisible(settings.renderFabrication);
document.getElementById("fabricationCheckbox").checked = settings.renderFabrication;
silkscreenVisible(settings.renderSilkscreen);
document.getElementById("silkscreenCheckbox").checked = settings.renderSilkscreen;
referencesVisible(settings.renderReferences);
document.getElementById("referencesCheckbox").checked = settings.renderReferences;
valuesVisible(settings.renderValues);
document.getElementById("valuesCheckbox").checked = settings.renderValues;
tracksVisible(settings.renderTracks);
document.getElementById("tracksCheckbox").checked = settings.renderTracks;
zonesVisible(settings.renderZones);
document.getElementById("zonesCheckbox").checked = settings.renderZones;
dnpOutline(settings.renderDnpOutline);
document.getElementById("dnpOutlineCheckbox").checked = settings.renderDnpOutline;
setRedrawOnDrag(settings.redrawOnDrag);
document.getElementById("dragCheckbox").checked = settings.redrawOnDrag;
setDarkMode(settings.darkMode);
document.getElementById("darkmodeCheckbox").checked = settings.darkMode;
setHighlightPin1(settings.highlightpin1);
document.getElementById("highlightpin1Checkbox").checked = settings.highlightpin1;
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: "default",
bomlayout: "default",
bommode: "grouped",
checkboxes: [],
checkboxStoredRefs: {},
darkMode: false,
highlightpin1: false,
redrawOnDrag: true,
boardRotation: 0,
offsetBackRotation: false,
renderPads: true,
renderReferences: true,
renderValues: true,
renderSilkscreen: true,
renderFabrication: true,
renderDnpOutline: false,
renderTracks: true,
renderZones: true,
columnOrder: [],
hiddenColumns: []
}
function initDefaults() {
settings.bomlayout = readStorage("bomlayout");
if (settings.bomlayout === null) {
settings.bomlayout = config.bom_view;
}
if (!['bom-only', 'left-right', 'top-bottom'].includes(settings.bomlayout)) {
settings.bomlayout = config.bom_view;
}
settings.bommode = readStorage("bommode");
if (settings.bommode === null) {
settings.bommode = "grouped";
}
if (!["grouped", "ungrouped", "netlist"].includes(settings.bommode)) {
settings.bommode = "grouped";
}
settings.canvaslayout = readStorage("canvaslayout");
if (settings.canvaslayout === null) {
settings.canvaslayout = config.layer_view;
}
var bomCheckboxes = readStorage("bomCheckboxes");
if (bomCheckboxes === null) {
bomCheckboxes = config.checkboxes;
}
settings.checkboxes = bomCheckboxes.split(",").filter((e) => e);
document.getElementById("bomCheckboxes").value = bomCheckboxes;
settings.markWhenChecked = readStorage("markWhenChecked") || "";
populateMarkWhenCheckedOptions();
function initBooleanSetting(storageString, def, elementId, func) {
var b = readStorage(storageString);
if (b === null) {
b = def;
} else {
b = (b == "true");
}
document.getElementById(elementId).checked = b;
func(b);
}
initBooleanSetting("padsVisible", config.show_pads, "padsCheckbox", padsVisible);
initBooleanSetting("fabricationVisible", config.show_fabrication, "fabricationCheckbox", fabricationVisible);
initBooleanSetting("silkscreenVisible", config.show_silkscreen, "silkscreenCheckbox", silkscreenVisible);
initBooleanSetting("referencesVisible", true, "referencesCheckbox", referencesVisible);
initBooleanSetting("valuesVisible", true, "valuesCheckbox", valuesVisible);
if ("tracks" in pcbdata) {
initBooleanSetting("tracksVisible", true, "tracksCheckbox", tracksVisible);
initBooleanSetting("zonesVisible", true, "zonesCheckbox", zonesVisible);
} else {
document.getElementById("tracksAndZonesCheckboxes").style.display = "none";
tracksVisible(false);
zonesVisible(false);
}
initBooleanSetting("dnpOutline", false, "dnpOutlineCheckbox", dnpOutline);
initBooleanSetting("redrawOnDrag", config.redraw_on_drag, "dragCheckbox", setRedrawOnDrag);
initBooleanSetting("darkmode", config.dark_mode, "darkmodeCheckbox", setDarkMode);
initBooleanSetting("highlightpin1", config.highlight_pin1, "highlightpin1Checkbox", setHighlightPin1);
var fields = ["checkboxes", "References"].concat(config.fields).concat(["Quantity"]);
var hcols = JSON.parse(readStorage("hiddenColumns"));
if (hcols === null) {
hcols = [];
}
settings.hiddenColumns = hcols.filter(e => fields.includes(e));
var cord = JSON.parse(readStorage("columnOrder"));
if (cord === null) {
cord = fields;
} else {
cord = cord.filter(e => fields.includes(e));
if (cord.length != fields.length)
cord = fields;
}
settings.columnOrder = cord;
settings.boardRotation = readStorage("boardRotation");
if (settings.boardRotation === null) {
settings.boardRotation = config.board_rotation * 5;
} else {
settings.boardRotation = parseInt(settings.boardRotation);
}
document.getElementById("boardRotation").value = settings.boardRotation / 5;
document.getElementById("rotationDegree").textContent = settings.boardRotation;
initBooleanSetting("offsetBackRotation", config.offset_back_rotation, "offsetBackRotationCheckbox", setOffsetBackRotation);
}
// 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) {
drawPad(ctx, pad, colors.outline, true);
}
}
}
for (var pad of footprint.pads) {
drawPadHole(ctx, pad, colors.padHole);
}
}
}
function drawEdgeCuts(canvas, scalefactor) {
var ctx = canvas.getContext("2d");
var edgecolor = getComputedStyle(topmostdiv).getPropertyValue('--pcb-edge-color');
for (var edge of pcbdata.edges) {
drawDrawing(ctx, scalefactor, edge, edgecolor);
}
}
function drawFootprints(canvas, layer, scalefactor, highlight) {
var ctx = canvas.getContext("2d");
ctx.lineWidth = 3 / scalefactor;
var style = getComputedStyle(topmostdiv);
var colors = {
pad: style.getPropertyValue('--pad-color'),
padHole: style.getPropertyValue('--pad-hole-color'),
outline: style.getPropertyValue('--pin1-outline-color'),
}
for (var i = 0; i < pcbdata.footprints.length; i++) {
var mod = pcbdata.footprints[i];
var outline = settings.renderDnpOutline && pcbdata.bom.skipped.includes(i);
var h = highlightedFootprints.includes(i);
var d = markedFootprints.has(i);
if (highlight) {
if(h && d) {
colors.pad = style.getPropertyValue('--pad-color-highlight-both');
colors.outline = style.getPropertyValue('--pin1-outline-color-highlight-both');
} else if (h) {
colors.pad = style.getPropertyValue('--pad-color-highlight');
colors.outline = style.getPropertyValue('--pin1-outline-color-highlight');
} else if (d) {
colors.pad = style.getPropertyValue('--pad-color-highlight-marked');
colors.outline = style.getPropertyValue('--pin1-outline-color-highlight-marked');
}
}
if( h || d || !highlight) {
drawFootprint(ctx, layer, scalefactor, mod, colors, highlight, outline);
}
}
}
function drawBgLayer(layername, canvas, layer, scalefactor, edgeColor, polygonColor, textColor) {
var ctx = canvas.getContext("2d");
for (var d of pcbdata.drawings[layername][layer]) {
if (["segment", "arc", "circle", "curve", "rect"].includes(d.type)) {
drawedge(ctx, scalefactor, d, edgeColor);
} else if (d.type == "polygon") {
drawPolygonShape(ctx, scalefactor, d, polygonColor);
} else {
drawText(ctx, d, textColor);
}
}
}
function drawTracks(canvas, layer, color, highlight) {
ctx = canvas.getContext("2d");
ctx.strokeStyle = color;
ctx.lineCap = "round";
for (var track of pcbdata.tracks[layer]) {
if (highlight && highlightedNet != track.net) continue;
ctx.lineWidth = track.width;
ctx.beginPath();
if ('radius' in track) {
ctx.arc(
...track.center,
track.radius,
deg2rad(track.startangle),
deg2rad(track.endangle));
} else {
ctx.moveTo(...track.start);
ctx.lineTo(...track.end);
}
ctx.stroke();
}
}
function drawZones(canvas, layer, color, highlight) {
ctx = canvas.getContext("2d");
ctx.strokeStyle = color;
ctx.fillStyle = color;
ctx.lineJoin = "round";
for (var zone of pcbdata.zones[layer]) {
if (!zone.path2d) {
zone.path2d = getPolygonsPath(zone);
}
if (highlight && highlightedNet != zone.net) continue;
ctx.fill(zone.path2d, 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.renderTracks) {
var trackColor = style.getPropertyValue(highlight ? '--track-color-highlight' : '--track-color');
drawTracks(canvas, layer, trackColor, highlight);
}
if (settings.renderZones) {
var zoneColor = style.getPropertyValue(highlight ? '--zone-color-highlight' : '--zone-color');
drawZones(canvas, layer, zoneColor, highlight);
}
if (highlight && settings.renderPads) {
var padColor = style.getPropertyValue('--pad-color-highlight');
var padHoleColor = style.getPropertyValue('--pad-hole-color');
var ctx = canvas.getContext("2d");
for (var footprint of pcbdata.footprints) {
// draw pads
var padDrawn = false;
for (var pad of footprint.pads) {
if (highlightedNet != pad.net) continue;
if (pad.layers.includes(layer)) {
drawPad(ctx, pad, padColor, false);
padDrawn = true;
}
}
if (padDrawn) {
// redraw all pad holes because some pads may overlap
for (var pad of footprint.pads) {
drawPadHole(ctx, pad, padHoleColor);
}
}
}
}
}
function drawHighlightsOnLayer(canvasdict, clear = true) {
if (clear) {
clearCanvas(canvasdict.highlight);
}
if (markedFootprints.size > 0 || highlightedFootprints.length > 0) {
drawFootprints(canvasdict.highlight, canvasdict.layer,
canvasdict.transform.s * canvasdict.transform.zoom, true);
}
if (highlightedNet !== null) {
drawNets(canvasdict.highlight, canvasdict.layer, true);
}
}
function drawHighlights() {
drawHighlightsOnLayer(allcanvas.front);
drawHighlightsOnLayer(allcanvas.back);
}
function drawBackground(canvasdict, clear = true) {
if (clear) {
clearCanvas(canvasdict.bg);
clearCanvas(canvasdict.fab);
clearCanvas(canvasdict.silk);
}
drawNets(canvasdict.bg, canvasdict.layer, false);
drawFootprints(canvasdict.bg, canvasdict.layer,
canvasdict.transform.s * canvasdict.transform.zoom, false);
drawEdgeCuts(canvasdict.bg, canvasdict.transform.s * canvasdict.transform.zoom);
var style = getComputedStyle(topmostdiv);
var edgeColor = style.getPropertyValue('--silkscreen-edge-color');
var polygonColor = style.getPropertyValue('--silkscreen-polygon-color');
var textColor = style.getPropertyValue('--silkscreen-text-color');
if (settings.renderSilkscreen) {
drawBgLayer(
"silkscreen", canvasdict.silk, canvasdict.layer,
canvasdict.transform.s * canvasdict.transform.zoom,
edgeColor, polygonColor, textColor);
}
edgeColor = style.getPropertyValue('--fabrication-edge-color');
polygonColor = style.getPropertyValue('--fabrication-polygon-color');
textColor = style.getPropertyValue('--fabrication-text-color');
if (settings.renderFabrication) {
drawBgLayer(
"fabrication", canvasdict.fab, canvasdict.layer,
canvasdict.transform.s * canvasdict.transform.zoom,
edgeColor, polygonColor, textColor);
}
}
function prepareCanvas(canvas, flip, transform) {
var ctx = canvas.getContext("2d");
ctx.setTransform(1, 0, 0, 1, 0, 0);
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();
}
function setShowBOMColumn(field, value) {
if (field === "references") {
var rl = document.getElementById("reflookup");
rl.disabled = !value;
if (!value) {
rl.value = "";
updateRefLookup("");
}
}
var n = settings.hiddenColumns.indexOf(field);
if (value) {
if (n != -1) {
settings.hiddenColumns.splice(n, 1);
}
} else {
if (n == -1) {
settings.hiddenColumns.push(field);
}
}
writeStorage("hiddenColumns", JSON.stringify(settings.hiddenColumns));
if (initDone) {
populateBomTable();
}
redrawIfInitDone();
}
function setFullscreen(value) {
if (value) {
document.documentElement.requestFullscreen();
} else {
document.exitFullscreen();
}
}
function fabricationVisible(value) {
writeStorage("fabricationVisible", value);
settings.renderFabrication = value;
redrawIfInitDone();
}
function silkscreenVisible(value) {
writeStorage("silkscreenVisible", value);
settings.renderSilkscreen = value;
redrawIfInitDone();
}
function setHighlightPin1(value) {
writeStorage("highlightpin1", value);
settings.highlightpin1 = value;
redrawIfInitDone();
}
function getStoredCheckboxRefs(checkbox) {
function convert(ref) {
var intref = parseInt(ref);
if (isNaN(intref)) {
for (var i = 0; i < pcbdata.footprints.length; i++) {
if (pcbdata.footprints[i].ref == ref) {
return i;
}
}
return -1;
} else {
return intref;
}
}
if (!(checkbox in settings.checkboxStoredRefs)) {
var val = readStorage("checkbox_" + checkbox);
settings.checkboxStoredRefs[checkbox] = val ? val : "";
}
if (!settings.checkboxStoredRefs[checkbox]) {
return new Set();
} else {
return new Set(settings.checkboxStoredRefs[checkbox].split(",").map(r => convert(r)).filter(a => a >= 0));
}
}
function getCheckboxState(checkbox, references) {
var storedRefsSet = getStoredCheckboxRefs(checkbox);
var currentRefsSet = new Set(references.map(r => r[1]));
// Get difference of current - stored
var difference = new Set(currentRefsSet);
for (ref of storedRefsSet) {
difference.delete(ref);
}
if (difference.size == 0) {
// All the current refs are stored
return "checked";
} else if (difference.size == currentRefsSet.size) {
// None of the current refs are stored
return "unchecked";
} else {
// Some of the refs are stored
return "indeterminate";
}
}
function setBomCheckboxState(checkbox, element, references) {
var state = getCheckboxState(checkbox, references);
element.checked = (state == "checked");
element.indeterminate = (state == "indeterminate");
}
function createCheckboxChangeHandler(checkbox, references, row) {
return function () {
refsSet = getStoredCheckboxRefs(checkbox);
var markWhenChecked = settings.markWhenChecked == checkbox;
eventArgs = {
checkbox: checkbox,
refs: references,
}
if (this.checked) {
// checkbox ticked
for (var ref of references) {
refsSet.add(ref[1]);
}
if (markWhenChecked) {
row.classList.add("checked");
for (var ref of references) {
markedFootprints.add(ref[1]);
}
drawHighlights();
}
eventArgs.state = 'checked';
} else {
// checkbox unticked
for (var ref of references) {
refsSet.delete(ref[1]);
}
if (markWhenChecked) {
row.classList.remove("checked");
for (var ref of references) {
markedFootprints.delete(ref[1]);
}
drawHighlights();
}
eventArgs.state = 'unchecked';
}
settings.checkboxStoredRefs[checkbox] = [...refsSet].join(",");
writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
updateCheckboxStats(checkbox);
EventHandler.emitEvent(IBOM_EVENT_TYPES.CHECKBOX_CHANGE_EVENT, eventArgs);
}
}
function clearHighlightedFootprints() {
if (currentHighlightedRowId) {
document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
currentHighlightedRowId = null;
highlightedFootprints = [];
highlightedNet = null;
}
}
function createRowHighlightHandler(rowid, refs, net) {
return function () {
if (currentHighlightedRowId) {
if (currentHighlightedRowId == rowid) {
return;
}
document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
}
document.getElementById(rowid).classList.add("highlighted");
currentHighlightedRowId = rowid;
highlightedFootprints = refs ? refs.map(r => r[1]) : [];
highlightedNet = net;
drawHighlights();
EventHandler.emitEvent(
IBOM_EVENT_TYPES.HIGHLIGHT_EVENT, {
rowid: rowid,
refs: refs,
net: net
});
}
}
function entryMatches(entry) {
if (settings.bommode == "netlist") {
// entry is just a net name
return entry.toLowerCase().indexOf(filter) >= 0;
}
// check refs
if (!settings.hiddenColumns.includes("references")) {
for (var ref of entry) {
if (ref[0].toLowerCase().indexOf(filter) >= 0) {
return true;
}
}
}
// check fields
for (var i in config.fields) {
var f = config.fields[i];
if (!settings.hiddenColumns.includes(f)) {
for (var ref of entry) {
if (pcbdata.bom.fields[ref[1]][i].toLowerCase().indexOf(filter) >= 0) {
return true;
}
}
}
}
return false;
}
function findRefInEntry(entry) {
return entry.filter(r => r[0].toLowerCase() == reflookup);
}
function highlightFilter(s) {
if (!filter) {
return s;
}
var parts = s.toLowerCase().split(filter);
if (parts.length == 1) {
return s;
}
var r = "";
var pos = 0;
for (var i in parts) {
if (i > 0) {
r += '<mark class="highlight">' +
s.substring(pos, pos + filter.length) +
'</mark>';
pos += filter.length;
}
r += s.substring(pos, pos + parts[i].length);
pos += parts[i].length;
}
return r;
}
function checkboxSetUnsetAllHandler(checkboxname) {
return function () {
var checkboxnum = 0;
while (checkboxnum < settings.checkboxes.length &&
settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
checkboxnum++;
}
if (checkboxnum >= settings.checkboxes.length) {
return;
}
var allset = true;
var checkbox;
var row;
for (row of bombody.childNodes) {
checkbox = row.childNodes[checkboxnum + 1].childNodes[0];
if (!checkbox.checked || checkbox.indeterminate) {
allset = false;
break;
}
}
for (row of bombody.childNodes) {
checkbox = row.childNodes[checkboxnum + 1].childNodes[0];
checkbox.checked = !allset;
checkbox.indeterminate = false;
checkbox.onchange();
}
}
}
function createColumnHeader(name, cls, comparator, is_checkbox = false) {
var th = document.createElement("TH");
th.innerHTML = name;
th.classList.add(cls);
if (is_checkbox)
th.setAttribute("col_name", "bom-checkbox");
else
th.setAttribute("col_name", name);
var span = document.createElement("SPAN");
span.classList.add("sortmark");
span.classList.add("none");
th.appendChild(span);
var spacer = document.createElement("div");
spacer.className = "column-spacer";
th.appendChild(spacer);
spacer.onclick = function () {
if (currentSortColumn && th !== currentSortColumn) {
// Currently sorted by another column
currentSortColumn.childNodes[1].classList.remove(currentSortOrder);
currentSortColumn.childNodes[1].classList.add("none");
currentSortColumn = null;
currentSortOrder = null;
}
if (currentSortColumn && th === currentSortColumn) {
// Already sorted by this column
if (currentSortOrder == "asc") {
// Sort by this column, descending order
bomSortFunction = function (a, b) {
return -comparator(a, b);
}
currentSortColumn.childNodes[1].classList.remove("asc");
currentSortColumn.childNodes[1].classList.add("desc");
currentSortOrder = "desc";
} else {
// Unsort
bomSortFunction = null;
currentSortColumn.childNodes[1].classList.remove("desc");
currentSortColumn.childNodes[1].classList.add("none");
currentSortColumn = null;
currentSortOrder = null;
}
} else {
// Sort by this column, ascending order
bomSortFunction = comparator;
currentSortColumn = th;
currentSortColumn.childNodes[1].classList.remove("none");
currentSortColumn.childNodes[1].classList.add("asc");
currentSortOrder = "asc";
}
populateBomBody();
}
if (is_checkbox) {
spacer.onclick = fancyDblClickHandler(
spacer, spacer.onclick, checkboxSetUnsetAllHandler(name));
}
return th;
}
function populateBomHeader(placeHolderColumn = null, placeHolderElements = null) {
while (bomhead.firstChild) {
bomhead.removeChild(bomhead.firstChild);
}
var tr = document.createElement("TR");
var th = document.createElement("TH");
th.classList.add("numCol");
var vismenu = document.createElement("div");
vismenu.id = "vismenu";
vismenu.classList.add("menu");
var visbutton = document.createElement("div");
visbutton.classList.add("visbtn");
visbutton.classList.add("hideonprint");
var viscontent = document.createElement("div");
viscontent.classList.add("menu-content");
viscontent.id = "vismenu-content";
settings.columnOrder.forEach(column => {
if (typeof column !== "string")
return;
// Skip empty columns
if (column === "checkboxes" && settings.checkboxes.length == 0)
return;
else if (column === "Quantity" && settings.bommode == "ungrouped")
return;
var label = document.createElement("label");
label.classList.add("menu-label");
var input = document.createElement("input");
input.classList.add("visibility_checkbox");
input.type = "checkbox";
input.onchange = function (e) {
setShowBOMColumn(column, e.target.checked)
};
input.checked = !(settings.hiddenColumns.includes(column));
label.appendChild(input);
if (column.length > 0)
label.append(column[0].toUpperCase() + column.slice(1));
viscontent.appendChild(label);
});
viscontent.childNodes[0].classList.add("menu-label-top");
vismenu.appendChild(visbutton);
if (settings.bommode != "netlist") {
vismenu.appendChild(viscontent);
th.appendChild(vismenu);
}
tr.appendChild(th);
var checkboxCompareClosure = function (checkbox) {
return (a, b) => {
var stateA = getCheckboxState(checkbox, a);
var stateB = getCheckboxState(checkbox, b);
if (stateA > stateB) return -1;
if (stateA < stateB) return 1;
return 0;
}
}
var stringFieldCompareClosure = function (fieldIndex) {
return (a, b) => {
var fa = pcbdata.bom.fields[a[0][1]][fieldIndex];
var fb = pcbdata.bom.fields[b[0][1]][fieldIndex];
if (fa != fb) return fa > fb ? 1 : -1;
else return 0;
}
}
var referenceRegex = /(?<prefix>[^0-9]+)(?<number>[0-9]+)/;
var compareRefs = (a, b) => {
var ra = referenceRegex.exec(a);
var rb = referenceRegex.exec(b);
if (ra === null || rb === null) {
if (a != b) return a > b ? 1 : -1;
return 0;
} else {
if (ra.groups.prefix != rb.groups.prefix) {
return ra.groups.prefix > rb.groups.prefix ? 1 : -1;
}
if (ra.groups.number != rb.groups.number) {
return parseInt(ra.groups.number) > parseInt(rb.groups.number) ? 1 : -1;
}
return 0;
}
}
if (settings.bommode == "netlist") {
th = createColumnHeader("Net name", "bom-netname", (a, b) => {
if (a > b) return -1;
if (a < b) return 1;
return 0;
});
tr.appendChild(th);
} else {
// Filter hidden columns
var columns = settings.columnOrder.filter(e => !settings.hiddenColumns.includes(e));
var valueIndex = config.fields.indexOf("Value");
var footprintIndex = config.fields.indexOf("Footprint");
columns.forEach((column) => {
if (column === placeHolderColumn) {
var n = 1;
if (column === "checkboxes")
n = settings.checkboxes.length;
for (i = 0; i < n; i++) {
td = placeHolderElements.shift();
tr.appendChild(td);
}
return;
} else if (column === "checkboxes") {
for (var checkbox of settings.checkboxes) {
th = createColumnHeader(
checkbox, "bom-checkbox", checkboxCompareClosure(checkbox), true);
tr.appendChild(th);
}
} else if (column === "References") {
tr.appendChild(createColumnHeader("References", "references", (a, b) => {
var i = 0;
while (i < a.length && i < b.length) {
if (a[i] != b[i]) return compareRefs(a[i][0], b[i][0]);
i++;
}
return a.length - b.length;
}));
} else if (column === "Value") {
tr.appendChild(createColumnHeader("Value", "value", (a, b) => {
var ra = a[0][1], rb = b[0][1];
return valueCompare(
pcbdata.bom.parsedValues[ra], pcbdata.bom.parsedValues[rb],
pcbdata.bom.fields[ra][valueIndex], pcbdata.bom.fields[rb][valueIndex]);
}));
return;
} else if (column === "Footprint") {
tr.appendChild(createColumnHeader(
"Footprint", "footprint", stringFieldCompareClosure(footprintIndex)));
} else if (column === "Quantity" && settings.bommode == "grouped") {
tr.appendChild(createColumnHeader("Quantity", "quantity", (a, b) => {
return a.length - b.length;
}));
} else {
// Other fields
var i = config.fields.indexOf(column);
if (i < 0)
return;
tr.appendChild(createColumnHeader(
column, `field${i + 1}`, stringFieldCompareClosure(i)));
}
});
}
bomhead.appendChild(tr);
}
function populateBomBody(placeholderColumn = null, placeHolderElements = null) {
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;
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 : "&lt;no net&gt;");
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(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&nbsp;" +
/^v\d+\.\d+/.exec(pcbdata.ibom_version)[0];
}
function changeBomLayout(layout) {
document.getElementById("bom-btn").classList.remove("depressed");
document.getElementById("lr-btn").classList.remove("depressed");
document.getElementById("tb-btn").classList.remove("depressed");
switch (layout) {
case 'bom-only':
document.getElementById("bom-btn").classList.add("depressed");
if (bomsplit) {
bomsplit.destroy();
bomsplit = null;
canvassplit.destroy();
canvassplit = null;
}
document.getElementById("frontcanvas").style.display = "none";
document.getElementById("backcanvas").style.display = "none";
document.getElementById("bot").style.height = "";
break;
case 'top-bottom':
document.getElementById("tb-btn").classList.add("depressed");
document.getElementById("frontcanvas").style.display = "";
document.getElementById("backcanvas").style.display = "";
document.getElementById("bot").style.height = "calc(100% - 80px)";
document.getElementById("bomdiv").classList.remove("split-horizontal");
document.getElementById("canvasdiv").classList.remove("split-horizontal");
document.getElementById("frontcanvas").classList.add("split-horizontal");
document.getElementById("backcanvas").classList.add("split-horizontal");
if (bomsplit) {
bomsplit.destroy();
bomsplit = null;
canvassplit.destroy();
canvassplit = null;
}
bomsplit = Split(['#bomdiv', '#canvasdiv'], {
sizes: [50, 50],
onDragEnd: resizeAll,
direction: "vertical",
gutterSize: 5
});
canvassplit = Split(['#frontcanvas', '#backcanvas'], {
sizes: [50, 50],
gutterSize: 5,
onDragEnd: resizeAll
});
break;
case 'left-right':
document.getElementById("lr-btn").classList.add("depressed");
document.getElementById("frontcanvas").style.display = "";
document.getElementById("backcanvas").style.display = "";
document.getElementById("bot").style.height = "calc(100% - 80px)";
document.getElementById("bomdiv").classList.add("split-horizontal");
document.getElementById("canvasdiv").classList.add("split-horizontal");
document.getElementById("frontcanvas").classList.remove("split-horizontal");
document.getElementById("backcanvas").classList.remove("split-horizontal");
if (bomsplit) {
bomsplit.destroy();
bomsplit = null;
canvassplit.destroy();
canvassplit = null;
}
bomsplit = Split(['#bomdiv', '#canvasdiv'], {
sizes: [50, 50],
onDragEnd: resizeAll,
gutterSize: 5
});
canvassplit = Split(['#frontcanvas', '#backcanvas'], {
sizes: [50, 50],
gutterSize: 5,
direction: "vertical",
onDragEnd: resizeAll
});
}
settings.bomlayout = layout;
writeStorage("bomlayout", layout);
changeCanvasLayout(settings.canvaslayout);
}
function changeBomMode(mode) {
document.getElementById("bom-grouped-btn").classList.remove("depressed");
document.getElementById("bom-ungrouped-btn").classList.remove("depressed");
document.getElementById("bom-netlist-btn").classList.remove("depressed");
var chkbxs = document.getElementsByClassName("visibility_checkbox");
switch (mode) {
case 'grouped':
document.getElementById("bom-grouped-btn").classList.add("depressed");
for (var i = 0; i < chkbxs.length; i++) {
chkbxs[i].disabled = false;
}
break;
case 'ungrouped':
document.getElementById("bom-ungrouped-btn").classList.add("depressed");
for (var i = 0; i < chkbxs.length; i++) {
chkbxs[i].disabled = false;
}
break;
case 'netlist':
document.getElementById("bom-netlist-btn").classList.add("depressed");
for (var i = 0; i < chkbxs.length; i++) {
chkbxs[i].disabled = true;
}
}
writeStorage("bommode", mode);
if (mode != settings.bommode) {
settings.bommode = mode;
bomSortFunction = null;
currentSortColumn = null;
currentSortOrder = null;
clearHighlightedFootprints();
}
populateBomTable();
}
function focusFilterField() {
focusInputField(document.getElementById("filter"));
}
function focusRefLookupField() {
focusInputField(document.getElementById("reflookup"));
}
function toggleBomCheckbox(bomrowid, checkboxnum) {
if (!bomrowid || checkboxnum > settings.checkboxes.length) {
return;
}
var bomrow = document.getElementById(bomrowid);
var checkbox = bomrow.childNodes[checkboxnum].childNodes[0];
checkbox.checked = !checkbox.checked;
checkbox.indeterminate = false;
checkbox.onchange();
}
function checkBomCheckbox(bomrowid, checkboxname) {
var checkboxnum = 0;
while (checkboxnum < settings.checkboxes.length &&
settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
checkboxnum++;
}
if (!bomrowid || checkboxnum >= settings.checkboxes.length) {
return;
}
var bomrow = document.getElementById(bomrowid);
var checkbox = bomrow.childNodes[checkboxnum + 1].childNodes[0];
checkbox.checked = true;
checkbox.indeterminate = false;
checkbox.onchange();
}
function setBomCheckboxes(value) {
writeStorage("bomCheckboxes", value);
settings.checkboxes = value.split(",").map((e) => e.trim()).filter((e) => e);
prepCheckboxes();
populateMarkWhenCheckedOptions();
setMarkWhenChecked(settings.markWhenChecked);
}
function setMarkWhenChecked(value) {
writeStorage("markWhenChecked", value);
settings.markWhenChecked = value;
markedFootprints.clear();
for (var ref of (value ? getStoredCheckboxRefs(value) : [])) {
markedFootprints.add(ref);
}
populateBomTable();
drawHighlights();
}
function prepCheckboxes() {
var table = document.getElementById("checkbox-stats");
while (table.childElementCount > 1) {
table.removeChild(table.lastChild);
}
if (settings.checkboxes.length) {
table.style.display = "";
} else {
table.style.display = "none";
}
for (var checkbox of settings.checkboxes) {
var tr = document.createElement("TR");
var td = document.createElement("TD");
td.innerHTML = checkbox;
tr.appendChild(td);
td = document.createElement("TD");
td.id = "checkbox-stats-" + checkbox;
var progressbar = document.createElement("div");
progressbar.classList.add("bar");
td.appendChild(progressbar);
var text = document.createElement("div");
text.classList.add("text");
td.appendChild(text);
tr.appendChild(td);
table.appendChild(tr);
updateCheckboxStats(checkbox);
}
}
function populateMarkWhenCheckedOptions() {
var container = document.getElementById("markWhenCheckedContainer");
if (settings.checkboxes.length == 0) {
container.parentElement.style.display = "none";
return;
}
container.innerHTML = '';
container.parentElement.style.display = "inline-block";
function createOption(name, displayName) {
var id = "markWhenChecked-" + name;
var div = document.createElement("div");
div.classList.add("radio-container");
var input = document.createElement("input");
input.type = "radio";
input.name = "markWhenChecked";
input.value = name;
input.id = id;
input.onchange = () => setMarkWhenChecked(name);
div.appendChild(input);
// Preserve the selected element when the checkboxes change
if (name == settings.markWhenChecked) {
input.checked = true;
}
var label = document.createElement("label");
label.innerHTML = displayName;
label.htmlFor = id;
div.appendChild(label);
container.appendChild(div);
}
createOption("", "None");
for (var checkbox of settings.checkboxes) {
createOption(checkbox, checkbox);
}
}
function updateCheckboxStats(checkbox) {
var checked = getStoredCheckboxRefs(checkbox).size;
var total = pcbdata.footprints.length - pcbdata.bom.skipped.length;
var percent = checked * 100.0 / total;
var td = document.getElementById("checkbox-stats-" + checkbox);
td.firstChild.style.width = percent + "%";
td.lastChild.innerHTML = checked + "/" + total + " (" + Math.round(percent) + "%)";
}
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";
}
window.onload = function (e) {
initUtils();
initRender();
initStorage();
initDefaults();
cleanGutters();
populateMetadata();
dbgdiv = document.getElementById("dbg");
bom = document.getElementById("bombody");
bomhead = document.getElementById("bomhead");
filter = "";
reflookup = "";
if (!("nets" in pcbdata)) {
hideNetlistButton();
}
initDone = true;
setBomCheckboxes(document.getElementById("bomCheckboxes").value);
// Triggers render
changeBomLayout(settings.bomlayout);
// Users may leave fullscreen without touching the checkbox. Uncheck.
document.addEventListener('fullscreenchange', () => {
if (!document.fullscreenElement)
document.getElementById('fullscreenCheckbox').checked = false;
});
}
window.onresize = resizeAll;
window.matchMedia("print").addListener(resizeAll);
///////////////////////////////////////////////
///////////////////////////////////////////////
///////////////////////////////////////////////
</script>
</head>
<body>
<div id="topmostdiv" class="topmostdiv">
<div id="top">
<div style="float: right; height: 100%;">
<div class="hideonprint menu" style="float: right; top: 8px;">
<button class="menubtn"></button>
<div class="menu-content">
<label class="menu-label menu-label-top" style="width: calc(50% - 18px)">
<input id="darkmodeCheckbox" type="checkbox" onchange="setDarkMode(this.checked)">
Dark mode
</label><!-- This comment eats space! All of it!
--><label class="menu-label menu-label-top" style="width: calc(50% - 17px); border-left: 0;">
<input id="fullscreenCheckbox" type="checkbox" onchange="setFullscreen(this.checked)">
Full Screen
</label>
<label class="menu-label" style="width: calc(50% - 18px)">
<input id="fabricationCheckbox" type="checkbox" checked onchange="fabricationVisible(this.checked)">
Fab layer
</label><!-- This comment eats space! All of it!
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
<input id="silkscreenCheckbox" type="checkbox" checked onchange="silkscreenVisible(this.checked)">
Silkscreen
</label>
<label class="menu-label" style="width: calc(50% - 18px)">
<input id="referencesCheckbox" type="checkbox" checked onchange="referencesVisible(this.checked)">
References
</label><!-- This comment eats space! All of it!
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
<input id="valuesCheckbox" type="checkbox" checked onchange="valuesVisible(this.checked)">
Values
</label>
<div id="tracksAndZonesCheckboxes">
<label class="menu-label" style="width: calc(50% - 18px)">
<input id="tracksCheckbox" type="checkbox" checked onchange="tracksVisible(this.checked)">
Tracks
</label><!-- This comment eats space! All of it!
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
<input id="zonesCheckbox" type="checkbox" checked onchange="zonesVisible(this.checked)">
Zones
</label>
</div>
<label class="menu-label" style="width: calc(50% - 18px)">
<input id="padsCheckbox" type="checkbox" checked onchange="padsVisible(this.checked)">
Pads
</label><!-- This comment eats space! All of it!
--><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
<input id="dnpOutlineCheckbox" type="checkbox" checked onchange="dnpOutline(this.checked)">
DNP outlined
</label>
<label class="menu-label">
<input id="highlightpin1Checkbox" type="checkbox" onchange="setHighlightPin1(this.checked)">
Highlight first pin
</label>
<label class="menu-label">
<input id="dragCheckbox" type="checkbox" checked onchange="setRedrawOnDrag(this.checked)">
Continuous redraw on drag
</label>
<label class="menu-label">
<span>Board rotation</span>
<span style="float: right"><span id="rotationDegree">0</span>&#176;</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"
style="float: right; position: relative; top: 8px">
<button id="fl-btn" class="left-most-button" onclick="changeCanvasLayout('F')"
title="Front only">F
</button>
<button id="fb-btn" class="middle-button" onclick="changeCanvasLayout('FB')"
title="Front and Back">FB
</button>
<button id="bl-btn" class="right-most-button" onclick="changeCanvasLayout('B')"
title="Back only">B
</button>
</div>
<div class="button-container hideonprint"
style="float: right; position: relative; top: 8px">
<button id="bom-btn" class="left-most-button" onclick="changeBomLayout('bom-only')"
title="BOM only"></button>
<button id="lr-btn" class="middle-button" onclick="changeBomLayout('left-right')"
title="BOM left, drawings right"></button>
<button id="tb-btn" class="right-most-button" onclick="changeBomLayout('top-bottom')"
title="BOM top, drawings bot"></button>
</div>
<div class="button-container hideonprint"
style="float: right; position: relative; top: 8px">
<button id="bom-grouped-btn" class="left-most-button" onclick="changeBomMode('grouped')"
title="Grouped BOM"></button>
<button id="bom-ungrouped-btn" class="middle-button" onclick="changeBomMode('ungrouped')"
title="Ungrouped BOM"></button>
<button id="bom-netlist-btn" class="right-most-button" onclick="changeBomMode('netlist')"
title="Netlist"></button>
</div>
<div class="hideonprint menu" style="float: right; top: 8px;">
<button class="statsbtn"></button>
<div class="menu-content">
<table class="stats">
<tbody>
<tr>
<td width="40%">Board stats</td>
<td>Front</td>
<td>Back</td>
<td>Total</td>
</tr>
<tr>
<td>Components</td>
<td id="stats-components-front">~</td>
<td id="stats-components-back">~</td>
<td id="stats-components-total">~</td>
</tr>
<tr>
<td>Groups</td>
<td id="stats-groups-front">~</td>
<td id="stats-groups-back">~</td>
<td id="stats-groups-total">~</td>
</tr>
<tr>
<td>SMD pads</td>
<td id="stats-smd-pads-front">~</td>
<td id="stats-smd-pads-back">~</td>
<td id="stats-smd-pads-total">~</td>
</tr>
<tr>
<td>TH pads</td>
<td colspan=3 id="stats-th-pads">~</td>
</tr>
</tbody>
</table>
<table class="stats">
<col width="40%"/><col />
<tbody id="checkbox-stats">
<tr>
<td colspan=2 style="border-top: 0">Checkboxes</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="hideonprint menu" style="float: right; top: 8px;">
<button class="iobtn"></button>
<div class="menu-content">
<div class="menu-label menu-label-top">
<div style="margin-left: 5px;">Save board image</div>
<div class="flexbox">
<input id="render-save-width" class="menu-textbox" type="text" value="1000" placeholder="Width"
style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
<span>X</span>
<input id="render-save-height" class="menu-textbox" type="text" value="1000" placeholder="Height"
style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
</div>
<label>
<input id="render-save-transparent" type="checkbox">
Transparent background
</label>
<div class="flexbox">
<button class="savebtn" onclick="saveImage('F')">Front</button>
<button class="savebtn" onclick="saveImage('B')">Back</button>
</div>
</div>
<div class="menu-label">
<span style="margin-left: 5px;">Config and checkbox state</span>
<div class="flexbox">
<button class="savebtn" onclick="saveSettings()">Export</button>
<button class="savebtn" onclick="loadSettings()">Import</button>
</div>
</div>
<div 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 id="fileinfodiv" style="overflow: auto;">
<table class="fileinfo">
<tbody>
<tr>
<td id="title" class="title" style="width: 70%">
Title
</td>
<td id="revision" class="title" style="width: 30%">
Revision
</td>
</tr>
<tr>
<td id="company">
Company
</td>
<td id="filedate">
Date
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="bot" class="split" style="height: calc(100% - 80px)">
<div id="bomdiv" class="split split-horizontal">
<div style="width: 100%">
<input id="reflookup" class="textbox searchbox reflookup hideonprint" type="text" placeholder="Ref lookup"
oninput="updateRefLookup(this.value)">
<input id="filter" class="textbox searchbox filter hideonprint" type="text" placeholder="Filter"
oninput="updateFilter(this.value)">
<div class="button-container hideonprint" style="float: left; margin: 0;">
<button id="copy" title="Copy bom table to clipboard"
onclick="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>