blob: d1c9b354582b7de00de86d886c5c0346859c6c51 [file] [log] [blame]
Sylvain Munaut1599a582020-09-14 10:45:06 +02001<!DOCTYPE html>
2<html lang="en">
3
4<head>
5 <meta charset="UTF-8">
6 <meta name="viewport" content="width=device-width, initial-scale=1.0">
7 <title>Interactive BOM for KiCAD</title>
8 <style type="text/css">
9:root {
10 --pcb-edge-color: black;
11 --pad-color: #878787;
12 --pad-color-highlight: #D04040;
13 --pin1-outline-color: #ffb629;
14 --pin1-outline-color-highlight: #b4ff03;
15 --silkscreen-edge-color: #aa4;
16 --silkscreen-polygon-color: #4aa;
17 --silkscreen-text-color: #4aa;
18 --fabrication-edge-color: #907651;
19 --fabrication-polygon-color: #907651;
20 --fabrication-text-color: #a27c24;
21 --track-color: #def5f1;
22 --track-color-highlight: #D04040;
23 --zone-color: #def5f1;
24 --zone-color-highlight: #d0404080;
25}
26
27html, body {
28 margin: 0px;
29 height: 100%;
30 font-family: Verdana, sans-serif;
31}
32
33.dark.topmostdiv {
34 --pcb-edge-color: #eee;
35 --pad-color: #808080;
36 --pin1-outline-color: #ffa800;
37 --pin1-outline-color-highlight: #ccff00;
38 --track-color: #42524f;
39 --zone-color: #42524f;
40 background-color: #252c30;
41 color: #eee;
42}
43
44button {
45 background-color: #eee;
46 border: 1px solid #888;
47 color: black;
48 height: 44px;
49 width: 44px;
50 text-align: center;
51 text-decoration: none;
52 display: inline-block;
53 font-size: 14px;
54 font-weight: bolder;
55}
56
57.dark button {
58 /* This will be inverted */
59 background-color: #c3b7b5;
60}
61
62button.depressed {
63 background-color: #0a0;
64 color: white;
65}
66
67.dark button.depressed {
68 /* This will be inverted */
69 background-color: #b3b;
70}
71
72button:focus {
73 outline: 0;
74}
75
76button#tb-btn {
77 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");
78}
79
80button#lr-btn {
81 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");
82}
83
84button#bom-btn {
85 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");
86}
87
88button#bom-grouped-btn {
89 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");
90}
91
92button#bom-ungrouped-btn {
93 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");
94}
95
96button#bom-netlist-btn {
97 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");
98}
99
100button#copy {
101 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");
102 background-position: 6px 6px;
103 background-repeat: no-repeat;
104 background-size: 26px 26px;
105 border-radius: 6px;
106 height: 40px;
107 width: 40px;
108 margin: 10px 5px;
109}
110
111button#copy:active {
112 box-shadow: inset 0px 0px 5px #6c6c6c;
113}
114
115textarea.clipboard-temp {
116 position: fixed;
117 top: 0;
118 left: 0;
119 width: 2em;
120 height: 2em;
121 padding: 0;
122 border: None;
123 outline: None;
124 box-shadow: None;
125 background: transparent;
126}
127
128.left-most-button {
129 border-right: 0;
130 border-top-left-radius: 6px;
131 border-bottom-left-radius: 6px;
132}
133
134.middle-button {
135 border-right: 0;
136}
137
138.right-most-button {
139 border-top-right-radius: 6px;
140 border-bottom-right-radius: 6px;
141}
142
143.button-container {
144 font-size: 0;
145 margin: 10px 10px 10px 0px;
146}
147
148.dark .button-container {
149 filter: invert(1);
150}
151
152.button-container button {
153 background-size: 32px 32px;
154 background-position: 5px 5px;
155 background-repeat: no-repeat;
156}
157
158@media print {
159 .hideonprint {
160 display: none;
161 }
162}
163
164canvas {
165 cursor: crosshair;
166}
167
168canvas:active {
169 cursor: grabbing;
170}
171
172.fileinfo {
173 width: 100%;
174 max-width: 1000px;
175 border: none;
176 padding: 5px;
177}
178
179.fileinfo .title {
180 font-size: 20pt;
181 font-weight: bold;
182}
183
184.fileinfo td {
185 overflow: hidden;
186 white-space: nowrap;
187 max-width: 1px;
188 width: 50%;
189 text-overflow: ellipsis;
190}
191
192.bom {
193 border-collapse: collapse;
194 font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
195 font-size: 10pt;
196 table-layout: fixed;
197 width: 100%;
198 margin-top: 1px;
199}
200
201.bom th, .bom td {
202 border: 1px solid black;
203 padding: 5px;
204 word-wrap: break-word;
205 text-align: center;
206 position: relative;
207}
208
209.dark .bom th, .dark .bom td {
210 border: 1px solid #777;
211}
212
213.bom th {
214 background-color: #CCCCCC;
215 background-clip: padding-box;
216}
217
218.dark .bom th {
219 background-color: #3b4749;
220}
221
222.bom tr.highlighted:nth-child(n) {
223 background-color: #cfc;
224}
225
226.dark .bom tr.highlighted:nth-child(n) {
227 background-color: #226022;
228}
229
230.bom tr:nth-child(even) {
231 background-color: #f2f2f2;
232}
233
234.dark .bom tr:nth-child(even) {
235 background-color: #313b40;
236}
237
238.bom tr.checked {
239 color: #aaa;
240}
241
242.dark .bom tr.checked {
243 color: #666;
244}
245
246.bom tr {
247 transition: background-color 0.2s;
248}
249
250.bom .numCol {
251 width: 25px;
252}
253
254.bom .Description {
255 width: 10%;
256}
257
258.bom .Part {
259 width: 10%;
260}
261
262.bom .Value {
263 width: 15%;
264}
265
266.bom .Quantity {
267 width: 65px;
268}
269
270.bom th .sortmark {
271 position: absolute;
272 right: 1px;
273 top: 1px;
274 margin-top: -5px;
275 border-width: 5px;
276 border-style: solid;
277 border-color: transparent transparent #221 transparent;
278 transform-origin: 50% 85%;
279 transition: opacity 0.2s, transform 0.4s;
280}
281
282.dark .bom th .sortmark {
283 filter: invert(1);
284}
285
286.bom th .sortmark.none {
287 opacity: 0;
288}
289
290.bom th .sortmark.desc {
291 transform: rotate(180deg);
292}
293
294.bom th:hover .sortmark.none {
295 opacity: 0.5;
296}
297
298.bom .bom-checkbox {
299 width: 30px;
300 position: relative;
301 user-select: none;
302 -moz-user-select: none;
303}
304
305.bom .bom-checkbox:before {
306 content: "";
307 position: absolute;
308 border-width: 15px;
309 border-style: solid;
310 border-color: #51829f transparent transparent transparent;
311 visibility: hidden;
312 top: -15px;
313}
314
315.bom .bom-checkbox:after {
316 content: "Double click to set/unset all";
317 position: absolute;
318 color: white;
319 top: -35px;
320 left: -26px;
321 background: #51829f;
322 padding: 5px 15px;
323 border-radius: 8px;
324 white-space: nowrap;
325 visibility: hidden;
326}
327
328.bom .bom-checkbox:hover:before, .bom .bom-checkbox:hover:after {
329 visibility: visible;
330 transition: visibility 0.2s linear 1s;
331}
332
333.split {
334 -webkit-box-sizing: border-box;
335 -moz-box-sizing: border-box;
336 box-sizing: border-box;
337 overflow-y: auto;
338 overflow-x: hidden;
339 background-color: inherit;
340}
341
342.split.split-horizontal, .gutter.gutter-horizontal {
343 height: 100%;
344 float: left;
345}
346
347.gutter {
348 background-color: #ddd;
349 background-repeat: no-repeat;
350 background-position: 50%;
351 transition: background-color 0.3s;
352}
353
354.dark .gutter {
355 background-color: #777;
356}
357
358.gutter.gutter-horizontal {
359 background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
360 cursor: ew-resize;
361 width: 5px;
362}
363
364.gutter.gutter-vertical {
365 background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=');
366 cursor: ns-resize;
367 height: 5px;
368}
369
370.searchbox {
371 float: left;
372 height: 40px;
373 margin: 10px 5px;
374 padding: 12px 32px;
375 font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
376 font-size: 18px;
377 box-sizing: border-box;
378 border: 1px solid #888;
379 border-radius: 6px;
380 outline: none;
381 background-color: #eee;
382 transition: background-color 0.2s, border 0.2s;
383 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==');
384 background-position: 10px 10px;
385 background-repeat: no-repeat;
386}
387
388.dark .searchbox {
389 background-color: #111;
390 color: #eee;
391}
392
393.searchbox::placeholder {
394 color: #ccc;
395}
396
397.dark .searchbox::placeholder {
398 color: #666;
399}
400
401.filter {
402 width: calc(60% - 64px);
403}
404
405.reflookup {
406 width: calc(40% - 10px);
407}
408
409input[type=text]:focus {
410 background-color: white;
411 border: 1px solid #333;
412}
413
414.dark input[type=text]:focus {
415 background-color: #333;
416 border: 1px solid #ccc;
417}
418
419mark.highlight {
420 background-color: #5050ff;
421 color: #fff;
422 padding: 2px;
423 border-radius: 6px;
424}
425
426.dark mark.highlight {
427 background-color: #76a6da;
428 color: #111;
429}
430
431.menubtn {
432 background-color: white;
433 border: none;
434 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");
435 background-position: center;
436 background-repeat: no-repeat;
437}
438
439.statsbtn {
440 background-color: white;
441 border: none;
442 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");
443 background-position: center;
444 background-repeat: no-repeat;
445}
446
447.iobtn {
448 background-color: white;
449 border: none;
450 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");
451 background-position: center;
452 background-repeat: no-repeat;
453}
454
455.dark .statsbtn, .dark .savebtn, .dark .menubtn, .dark .iobtn {
456 filter: invert(1);
457}
458
459.flexbox {
460 display: flex;
461 align-items: center;
462 justify-content: space-between;
463 width: 100%;
464}
465
466.savebtn {
467 background-color: #d6d6d6;
468 width: auto;
469 height: 30px;
470 flex-grow: 1;
471 margin: 5px;
472 border-radius: 4px;
473}
474
475.savebtn:active {
476 background-color: #0a0;
477 color: white;
478}
479
480.dark .savebtn:active {
481 /* This will be inverted */
482 background-color: #b3b;
483}
484
485.stats {
486 border-collapse: collapse;
487 font-size: 12pt;
488 table-layout: fixed;
489 width: 100%;
490 min-width: 450px;
491}
492
493.dark .stats td {
494 border: 1px solid #bbb;
495}
496
497.stats td {
498 border: 1px solid black;
499 padding: 5px;
500 word-wrap: break-word;
501 text-align: center;
502 position: relative;
503}
504
505#checkbox-stats div {
506 position: absolute;
507 left: 0;
508 top: 0;
509 height: 100%;
510 width: 100%;
511 display: flex;
512 align-items: center;
513 justify-content: center;
514}
515
516#checkbox-stats .bar {
517 background-color: rgba(28, 251, 0, 0.6);
518}
519
520.menu {
521 position: relative;
522 display: inline-block;
523 margin: 10px 10px 10px 0px;
524}
525
526.menu-content {
527 display: none;
528 position: absolute;
529 background-color: white;
530 right: 0;
531 min-width: 300px;
532 box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
533 z-index: 100;
534 padding: 8px;
535}
536
537.dark .menu-content {
538 background-color: #111;
539}
540
541.menu:hover .menu-content {
542 display: block;
543}
544
545.menu:hover .menubtn, .menu:hover .iobtn, .menu:hover .statsbtn {
546 background-color: #eee;
547}
548
549.menu-label {
550 display: inline-block;
551 padding: 8px;
552 border: 1px solid #ccc;
553 border-top: 0;
554 width: calc(100% - 18px);
555}
556
557.menu-label-top {
558 border-top: 1px solid #ccc;
559}
560
561.menu-textbox {
562 float: left;
563 height: 24px;
564 margin: 10px 5px;
565 padding: 5px 5px;
566 font-family: Consolas, "DejaVu Sans Mono", Monaco, monospace;
567 font-size: 14px;
568 box-sizing: border-box;
569 border: 1px solid #888;
570 border-radius: 4px;
571 outline: none;
572 background-color: #eee;
573 transition: background-color 0.2s, border 0.2s;
574 width: calc(100% - 10px);
575}
576
577.menu-textbox.invalid, .dark .menu-textbox.invalid {
578 color: red;
579}
580
581.dark .menu-textbox {
582 background-color: #222;
583 color: #eee;
584}
585
586.radio-container {
587 margin: 4px;
588}
589
590.topmostdiv {
591 width: 100%;
592 height: 100%;
593 background-color: white;
594 transition: background-color 0.3s;
595}
596
597#top {
598 height: 78px;
599 border-bottom: 2px solid black;
600}
601
602.dark #top {
603 border-bottom: 2px solid #ccc;
604}
605
606#dbg {
607 display: block;
608}
609
610::-webkit-scrollbar {
611 width: 8px;
612}
613
614::-webkit-scrollbar-track {
615 background: #aaa;
616}
617
618::-webkit-scrollbar-thumb {
619 background: #666;
620 border-radius: 3px;
621}
622
623::-webkit-scrollbar-thumb:hover {
624 background: #555;
625}
626
627.slider {
628 -webkit-appearance: none;
629 width: 100%;
630 margin: 3px 0;
631 padding: 0;
632 outline: none;
633 opacity: 0.7;
634 -webkit-transition: .2s;
635 transition: opacity .2s;
636 border-radius: 3px;
637}
638
639.slider:hover {
640 opacity: 1;
641}
642
643.slider:focus {
644 outline: none;
645}
646
647.slider::-webkit-slider-runnable-track {
648 -webkit-appearance: none;
649 width: 100%;
650 height: 8px;
651 background: #d3d3d3;
652 border-radius: 3px;
653 border: none;
654}
655
656.slider::-webkit-slider-thumb {
657 -webkit-appearance: none;
658 width: 15px;
659 height: 15px;
660 border-radius: 50%;
661 background: #0a0;
662 cursor: pointer;
663 margin-top: -4px;
664}
665
666.dark .slider::-webkit-slider-thumb {
667 background: #3d3;
668}
669
670.slider::-moz-range-thumb {
671 width: 15px;
672 height: 15px;
673 border-radius: 50%;
674 background: #0a0;
675 cursor: pointer;
676}
677
678.slider::-moz-range-track {
679 height: 8px;
680 background: #d3d3d3;
681 border-radius: 3px;
682}
683
684.dark .slider::-moz-range-thumb {
685 background: #3d3;
686}
687
688.slider::-ms-track {
689 width: 100%;
690 height: 8px;
691 border-width: 3px 0;
692 background: transparent;
693 border-color: transparent;
694 color: transparent;
695 transition: opacity .2s;
696}
697
698.slider::-ms-fill-lower {
699 background: #d3d3d3;
700 border: none;
701 border-radius: 3px;
702}
703
704.slider::-ms-fill-upper {
705 background: #d3d3d3;
706 border: none;
707 border-radius: 3px;
708}
709
710.slider::-ms-thumb {
711 width: 15px;
712 height: 15px;
713 border-radius: 50%;
714 background: #0a0;
715 cursor: pointer;
716 margin: 0;
717}
718
719.shameless-plug {
720 font-size: 0.8em;
721 text-align: center;
722 display: block;
723}
724
725a {
726 color: #0278a4;
727}
728
729.dark a {
730 color: #00b9fd;
731}
732
733#frontcanvas, #backcanvas {
734 touch-action: none;
735}
736
737
738 </style>
739 <script type="text/javascript" >
740///////////////////////////////////////////////
741/*
742 Split.js - v1.3.5
743 MIT License
744 https://github.com/nathancahill/Split.js
745*/
746!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}}});
747
748///////////////////////////////////////////////
749
750///////////////////////////////////////////////
751// Copyright (c) 2013 Pieroxy <pieroxy@pieroxy.net>
752// This work is free. You can redistribute it and/or modify it
753// under the terms of the WTFPL, Version 2
754// For more information see LICENSE.txt or http://www.wtfpl.net/
755//
756// For more information, the home page:
757// http://pieroxy.net/blog/pages/lz-string/testing.html
758//
759// LZ-based compression algorithm, version 1.4.4
760var 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});
761///////////////////////////////////////////////
762
763///////////////////////////////////////////////
764/*!
765 * PEP v0.4.3 | https://github.com/jquery/PEP
766 * Copyright jQuery Foundation and other contributors | http://jquery.org/license
767 */
768!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);
769for(var d,e=2;e<m.length;e++)d=m[e],c[d]=b[d]||n[e];c.buttons=b.buttons||0;
770var 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}})}
771var 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++)
772b.register.call(b,a)},unregister:function(a){for(var b,c=this.eventSourceList.length,d=0;d<c&&(b=this.eventSourceList[d]);d++)
773b.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){
774for(var b=a;b.parentNode;)b=b.parentNode;
775return 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);
776return 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){
777//
778this.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))},
779installOnLoad: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){
780var b=x(a,this.findElements,this);
781return 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){}
782var 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:[],
783isEventSimulatedFromTouch: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++){
784var 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);
7850!==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];
786c.buttons=b?b.buttons&~d:0,a.buttons=c.buttons}H.set(this.POINTER_ID,a),
787c.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),
788Q(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),
789Q(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);
790d&&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){
791(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,
792c.altKey=b.altKey,c.ctrlKey=b.ctrlKey,c.metaKey=b.metaKey,c.shiftKey=b.shiftKey;
793var 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))},
794shouldScroll:function(a){if(this.firstXY){var b,c=a.currentTarget._scrollType;if("none"===c)
795b=!1;else if("XY"===c)
796b=!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]);
797b=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},
798vacuumTouches:function(a){var b=a.touches;
799if(R.size>=b.length){var c=[];R.forEach(function(a,d){
800if(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);
801if(c){var d=c.out,e=c.outTarget;u.move(b),d&&e!==b.target&&(d.relatedTarget=b.target,b.relatedTarget=e,
802d.target=e,b.target?(u.leaveOut(d),u.enterOver(b)):(
803b.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)},
804dedupSynthMouse:function(a){var b=N.lastTouches,c=a.changedTouches[0];
805if(this.isPrimaryTouch(c)){
806var 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});
807
808///////////////////////////////////////////////
809
810///////////////////////////////////////////////
811var config = {"dark_mode": true, "show_pads": true, "show_fabrication": true, "show_silkscreen": true, "highlight_pin1": true, "redraw_on_drag": true, "board_rotation": 0, "checkboxes": "Sourced,Placed", "bom_view": "left-right", "layer_view": "F", "extra_fields": []}
812///////////////////////////////////////////////
813
814///////////////////////////////////////////////
815var pcbdata = JSON.parse(LZString.decompressFromBase64("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"))
816///////////////////////////////////////////////
817
818///////////////////////////////////////////////
819/* Utility functions */
820
821var storagePrefix = 'KiCad_HTML_BOM__' + pcbdata.metadata.title + '__' +
822 pcbdata.metadata.revision + '__#';
823var storage;
824
825function initStorage(key) {
826 try {
827 window.localStorage.getItem("blank");
828 storage = window.localStorage;
829 } catch (e) {
830 // localStorage not available
831 }
832 if (!storage) {
833 try {
834 window.sessionStorage.getItem("blank");
835 storage = window.sessionStorage;
836 } catch (e) {
837 // sessionStorage also not available
838 }
839 }
840}
841
842function readStorage(key) {
843 if (storage) {
844 return storage.getItem(storagePrefix + key);
845 } else {
846 return null;
847 }
848}
849
850function writeStorage(key, value) {
851 if (storage) {
852 storage.setItem(storagePrefix + key, value);
853 }
854}
855
856function fancyDblClickHandler(el, onsingle, ondouble) {
857 return function() {
858 if (el.getAttribute("data-dblclick") == null) {
859 el.setAttribute("data-dblclick", 1);
860 setTimeout(function() {
861 if (el.getAttribute("data-dblclick") == 1) {
862 onsingle();
863 }
864 el.removeAttribute("data-dblclick");
865 }, 200);
866 } else {
867 el.removeAttribute("data-dblclick");
868 ondouble();
869 }
870 }
871}
872
873function smoothScrollToRow(rowid) {
874 document.getElementById(rowid).scrollIntoView({
875 behavior: "smooth",
876 block: "center",
877 inline: "nearest"
878 });
879}
880
881function focusInputField(input) {
882 input.scrollIntoView(false);
883 input.focus();
884 input.select();
885}
886
887function copyToClipboard() {
888 var text = '';
889 for (var node of bomhead.childNodes[0].childNodes) {
890 if (node.firstChild) {
891 text = text + node.firstChild.nodeValue;
892 }
893 if (node != bomhead.childNodes[0].lastChild) {
894 text += '\t';
895 }
896 }
897 text += '\n';
898 for (var row of bombody.childNodes) {
899 for (var cell of row.childNodes) {
900 for (var node of cell.childNodes) {
901 if (node.nodeName == "INPUT") {
902 if (node.checked) {
903 text = text + '✓';
904 }
905 } else if (node.nodeName == "MARK") {
906 text = text + node.firstChild.nodeValue;
907 } else {
908 text = text + node.nodeValue;
909 }
910 }
911 if (cell != row.lastChild) {
912 text += '\t';
913 }
914 }
915 text += '\n';
916 }
917 var textArea = document.createElement("textarea");
918 textArea.classList.add('clipboard-temp');
919 textArea.value = text;
920
921 document.body.appendChild(textArea);
922 textArea.focus();
923 textArea.select();
924
925 try {
926 if (document.execCommand('copy')) {
927 console.log('Bom copied to clipboard.');
928 }
929 } catch (err) {
930 console.log('Can not copy to clipboard.');
931 }
932
933 document.body.removeChild(textArea);
934}
935
936function removeGutterNode(node) {
937 for (var i = 0; i < node.childNodes.length; i++) {
938 if (node.childNodes[i].classList &&
939 node.childNodes[i].classList.contains("gutter")) {
940 node.removeChild(node.childNodes[i]);
941 break;
942 }
943 }
944}
945
946function cleanGutters() {
947 removeGutterNode(document.getElementById("bot"));
948 removeGutterNode(document.getElementById("canvasdiv"));
949}
950
951var units = {
952 prefixes: {
953 giga: ["G", "g", "giga", "Giga", "GIGA"],
954 mega: ["M", "mega", "Mega", "MEGA"],
955 kilo: ["K", "k", "kilo", "Kilo", "KILO"],
956 milli: ["m", "milli", "Milli", "MILLI"],
957 micro: ["U", "u", "micro", "Micro", "MICRO", "μ", "µ"], // different utf8 μ
958 nano: ["N", "n", "nano", "Nano", "NANO"],
959 pico: ["P", "p", "pico", "Pico", "PICO"],
960 },
961 unitsShort: ["R", "r", "Ω", "F", "f", "H", "h"],
962 unitsLong: [
963 "OHM", "Ohm", "ohm", "ohms",
964 "FARAD", "Farad", "farad",
965 "HENRY", "Henry", "henry"
966 ],
967 getMultiplier: function(s) {
968 if (this.prefixes.giga.includes(s)) return 1e9;
969 if (this.prefixes.mega.includes(s)) return 1e6;
970 if (this.prefixes.kilo.includes(s)) return 1e3;
971 if (this.prefixes.milli.includes(s)) return 1e-3;
972 if (this.prefixes.micro.includes(s)) return 1e-6;
973 if (this.prefixes.nano.includes(s)) return 1e-9;
974 if (this.prefixes.pico.includes(s)) return 1e-12;
975 return 1;
976 },
977 valueRegex: null,
978}
979
980function initUtils() {
981 var allPrefixes = units.prefixes.giga
982 .concat(units.prefixes.mega)
983 .concat(units.prefixes.kilo)
984 .concat(units.prefixes.milli)
985 .concat(units.prefixes.micro)
986 .concat(units.prefixes.nano)
987 .concat(units.prefixes.pico);
988 var allUnits = units.unitsShort.concat(units.unitsLong);
989 units.valueRegex = new RegExp("^([0-9\.]+)" +
990 "\\s*(" + allPrefixes.join("|") + ")?" +
991 "(" + allUnits.join("|") + ")?" +
992 "(\\b.*)?$", "");
993 units.valueAltRegex = new RegExp("^([0-9]*)" +
994 "(" + units.unitsShort.join("|") + ")?" +
995 "([GgMmKkUuNnPp])?" +
996 "([0-9]*)" +
997 "(\\b.*)?$", "");
998 for (var bom_type of ["both", "F", "B"]) {
999 for (var row of pcbdata.bom[bom_type]) {
1000 row.push(parseValue(row[1], row[3][0][0]));
1001 }
1002 }
1003}
1004
1005function parseValue(val, ref) {
1006 var inferUnit = (unit, ref) => {
1007 if (unit) {
1008 unit = unit.toLowerCase();
1009 if (unit == 'Ω' || unit == "ohm" || unit == "ohms") {
1010 unit = 'r';
1011 }
1012 unit = unit[0];
1013 } else {
1014 ref = /^([a-z]+)\d+$/i.exec(ref);
1015 if (ref) {
1016 ref = ref[1].toLowerCase();
1017 if (ref == "c") unit = 'f';
1018 else if (ref == "l") unit = 'h';
1019 else if (ref == "r" || ref == "rv") unit = 'r';
1020 else unit = null;
1021 }
1022 }
1023 return unit;
1024 };
1025 val = val.replace(/,/g, "");
1026 var match = units.valueRegex.exec(val);
1027 var unit;
1028 if (match) {
1029 val = parseFloat(match[1]);
1030 if (match[2]) {
1031 val = val * units.getMultiplier(match[2]);
1032 }
1033 unit = inferUnit(match[3], ref);
1034 if (!unit) return null;
1035 else return {
1036 val: val,
1037 unit: unit,
1038 extra: match[4],
1039 }
1040 }
1041 match = units.valueAltRegex.exec(val);
1042 if (match && (match[1] || match[4])) {
1043 val = parseFloat(match[1] + "." + match[4]);
1044 if (match[3]) {
1045 val = val * units.getMultiplier(match[3]);
1046 }
1047 unit = inferUnit(match[2], ref);
1048 if (!unit) return null;
1049 else return {
1050 val: val,
1051 unit: unit,
1052 extra: match[5],
1053 }
1054 }
1055 return null;
1056}
1057
1058function valueCompare(a, b, stra, strb) {
1059 if (a === null && b === null) {
1060 // Failed to parse both values, compare them as strings.
1061 if (stra != strb) return stra > strb ? 1 : -1;
1062 else return 0;
1063 } else if (a === null) {
1064 return 1;
1065 } else if (b === null) {
1066 return -1;
1067 } else {
1068 if (a.unit != b.unit) return a.unit > b.unit ? 1 : -1;
1069 else if (a.val != b.val) return a.val > b.val ? 1 : -1;
1070 else if (a.extra != b.extra) return a.extra > b.extra ? 1 : -1;
1071 else return 0;
1072 }
1073}
1074
1075function validateSaveImgDimension(element) {
1076 var valid = false;
1077 var intValue = 0;
1078 if (/^[1-9]\d*$/.test(element.value)) {
1079 intValue = parseInt(element.value);
1080 if (intValue <= 16000) {
1081 valid = true;
1082 }
1083 }
1084 if (valid) {
1085 element.classList.remove("invalid");
1086 } else {
1087 element.classList.add("invalid");
1088 }
1089 return intValue;
1090}
1091
1092function saveImage(layer) {
1093 var width = validateSaveImgDimension(document.getElementById("render-save-width"));
1094 var height = validateSaveImgDimension(document.getElementById("render-save-height"));
1095 var bgcolor = null;
1096 if (!document.getElementById("render-save-transparent").checked) {
1097 var style = getComputedStyle(topmostdiv);
1098 bgcolor = style.getPropertyValue("background-color");
1099 }
1100 if (!width || !height) return;
1101
1102 // Prepare image
1103 var canvas = document.createElement("canvas");
1104 var layerdict = {
1105 transform: {
1106 x: 0,
1107 y: 0,
1108 s: 1,
1109 panx: 0,
1110 pany: 0,
1111 zoom: 1,
1112 },
1113 bg: canvas,
1114 fab: canvas,
1115 silk: canvas,
1116 highlight: canvas,
1117 layer: layer,
1118 }
1119 // Do the rendering
1120 recalcLayerScale(layerdict, width, height);
1121 prepareLayer(layerdict);
1122 clearCanvas(canvas, bgcolor);
1123 drawBackground(layerdict, false);
1124 drawHighlightsOnLayer(layerdict, false);
1125
1126 // Save image
1127 var imgdata = canvas.toDataURL("image/png");
1128
1129 var filename = pcbdata.metadata.title;
1130 if (pcbdata.metadata.revision) {
1131 filename += `.${pcbdata.metadata.revision}`;
1132 }
1133 filename += `.${layer}.png`;
1134 saveFile(filename, dataURLtoBlob(imgdata));
1135}
1136
1137function saveSettings() {
1138 var data = {
1139 type: "InteractiveHtmlBom settings",
1140 version: 1,
1141 pcbmetadata: pcbdata.metadata,
1142 settings: settings,
1143 }
1144 var blob = new Blob([JSON.stringify(data, null, 4)], {type: "application/json"});
1145 saveFile(`${pcbdata.metadata.title}.settings.json`, blob);
1146}
1147
1148function loadSettings() {
1149 var input = document.createElement("input");
1150 input.type = "file";
1151 input.accept = ".settings.json";
1152 input.onchange = function(e) {
1153 var file = e.target.files[0];
1154 var reader = new FileReader();
1155 reader.onload = readerEvent => {
1156 var content = readerEvent.target.result;
1157 var newSettings;
1158 try {
1159 newSettings = JSON.parse(content);
1160 } catch(e) {
1161 alert("Selected file is not InteractiveHtmlBom settings file.");
1162 return;
1163 }
1164 if (newSettings.type != "InteractiveHtmlBom settings") {
1165 alert("Selected file is not InteractiveHtmlBom settings file.");
1166 return;
1167 }
1168 var metadataMatches = newSettings.hasOwnProperty("pcbmetadata");
1169 if (metadataMatches) {
1170 for (var k in pcbdata.metadata) {
1171 if (!newSettings.pcbmetadata.hasOwnProperty(k) || newSettings.pcbmetadata[k] != pcbdata.metadata[k]) {
1172 metadataMatches = false;
1173 }
1174 }
1175 }
1176 if (!metadataMatches) {
1177 var currentMetadata = JSON.stringify(pcbdata.metadata, null, 4);
1178 var fileMetadata = JSON.stringify(newSettings.pcbmetadata, null, 4);
1179 if (!confirm(
1180 `Settins file metadata does not match current metadata.\n\n` +
1181 `Page metadata:\n${currentMetadata}\n\n` +
1182 `Settings file metadata:\n${fileMetadata}\n\n` +
1183 `Press OK if you would like to import settings anyway.`)) {
1184 return;
1185 }
1186 }
1187 overwriteSettings(newSettings.settings);
1188 }
1189 reader.readAsText(file, 'UTF-8');
1190 }
1191 input.click();
1192}
1193
1194function overwriteSettings(newSettings) {
1195 initDone = false;
1196 Object.assign(settings, newSettings);
1197 writeStorage("bomlayout", settings.bomlayout);
1198 writeStorage("bommode", settings.bommode);
1199 writeStorage("canvaslayout", settings.canvaslayout);
1200 writeStorage("bomCheckboxes", settings.checkboxes.join(","));
1201 document.getElementById("bomCheckboxes").value = settings.checkboxes.join(",");
1202 for (var checkbox of settings.checkboxes) {
1203 writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
1204 }
1205 writeStorage("darkenWhenChecked", settings.darkenWhenChecked);
1206 padsVisible(settings.renderPads);
1207 document.getElementById("padsCheckbox").checked = settings.renderPads;
1208 fabricationVisible(settings.renderFabrication);
1209 document.getElementById("fabricationCheckbox").checked = settings.renderFabrication;
1210 silkscreenVisible(settings.renderSilkscreen);
1211 document.getElementById("silkscreenCheckbox").checked = settings.renderSilkscreen;
1212 referencesVisible(settings.renderReferences);
1213 document.getElementById("referencesCheckbox").checked = settings.renderReferences;
1214 valuesVisible(settings.renderValues);
1215 document.getElementById("valuesCheckbox").checked = settings.renderValues;
1216 tracksVisible(settings.renderTracks);
1217 document.getElementById("tracksCheckbox").checked = settings.renderTracks;
1218 zonesVisible(settings.renderZones);
1219 document.getElementById("zonesCheckbox").checked = settings.renderZones;
1220 dnpOutline(settings.renderDnpOutline);
1221 document.getElementById("dnpOutlineCheckbox").checked = settings.renderDnpOutline;
1222 setRedrawOnDrag(settings.redrawOnDrag);
1223 document.getElementById("dragCheckbox").checked = settings.redrawOnDrag;
1224 setDarkMode(settings.darkMode);
1225 document.getElementById("darkmodeCheckbox").checked = settings.darkMode;
1226 setHighlightPin1(settings.highlightpin1);
1227 document.getElementById("highlightpin1Checkbox").checked = settings.highlightpin1;
1228 writeStorage("boardRotation", settings.boardRotation);
1229 document.getElementById("boardRotation").value = settings.boardRotation / 5;
1230 document.getElementById("rotationDegree").textContent = settings.boardRotation;
1231 initDone = true;
1232 prepCheckboxes();
1233 changeBomLayout(settings.bomlayout);
1234}
1235
1236function saveFile(filename, blob) {
1237 var link = document.createElement("a");
1238 var objurl = URL.createObjectURL(blob);
1239 link.download = filename;
1240 link.href = objurl;
1241 link.click();
1242}
1243
1244function dataURLtoBlob(dataurl) {
1245 var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
1246 bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
1247 while(n--){
1248 u8arr[n] = bstr.charCodeAt(n);
1249 }
1250 return new Blob([u8arr], {type:mime});
1251}
1252
1253var settings = {
1254 canvaslayout: "default",
1255 bomlayout: "default",
1256 bommode: "grouped",
1257 checkboxes: [],
1258 checkboxStoredRefs: {},
1259 darkMode: false,
1260 highlightpin1: false,
1261 redrawOnDrag: true,
1262 boardRotation: 0,
1263 renderPads: true,
1264 renderReferences: true,
1265 renderValues: true,
1266 renderSilkscreen: true,
1267 renderFabrication: true,
1268 renderDnpOutline: false,
1269 renderTracks: true,
1270 renderZones: true,
1271}
1272
1273function initDefaults() {
1274 settings.bomlayout = readStorage("bomlayout");
1275 if (settings.bomlayout === null) {
1276 settings.bomlayout = config.bom_view;
1277 }
1278 if (!['bom-only', 'left-right', 'top-bottom'].includes(settings.bomlayout)) {
1279 settings.bomlayout = config.bom_view;
1280 }
1281 settings.bommode = readStorage("bommode");
1282 if (settings.bommode === null) {
1283 settings.bommode = "grouped";
1284 }
1285 if (!["grouped", "ungrouped", "netlist"].includes(settings.bommode)) {
1286 settings.bommode = "grouped";
1287 }
1288 settings.canvaslayout = readStorage("canvaslayout");
1289 if (settings.canvaslayout === null) {
1290 settings.canvaslayout = config.layer_view;
1291 }
1292 var bomCheckboxes = readStorage("bomCheckboxes");
1293 if (bomCheckboxes === null) {
1294 bomCheckboxes = config.checkboxes;
1295 }
1296 settings.checkboxes = bomCheckboxes.split(",").filter((e) => e);
1297 document.getElementById("bomCheckboxes").value = bomCheckboxes;
1298
1299 settings.darkenWhenChecked = readStorage("darkenWhenChecked") || "";
1300 populateDarkenWhenCheckedOptions();
1301
1302 function initBooleanSetting(storageString, def, elementId, func) {
1303 var b = readStorage(storageString);
1304 if (b === null) {
1305 b = def;
1306 } else {
1307 b = (b == "true");
1308 }
1309 document.getElementById(elementId).checked = b;
1310 func(b);
1311 }
1312
1313 initBooleanSetting("padsVisible", config.show_pads, "padsCheckbox", padsVisible);
1314 initBooleanSetting("fabricationVisible", config.show_fabrication, "fabricationCheckbox", fabricationVisible);
1315 initBooleanSetting("silkscreenVisible", config.show_silkscreen, "silkscreenCheckbox", silkscreenVisible);
1316 initBooleanSetting("referencesVisible", true, "referencesCheckbox", referencesVisible);
1317 initBooleanSetting("valuesVisible", true, "valuesCheckbox", valuesVisible);
1318 if ("tracks" in pcbdata) {
1319 initBooleanSetting("tracksVisible", true, "tracksCheckbox", tracksVisible);
1320 initBooleanSetting("zonesVisible", true, "zonesCheckbox", zonesVisible);
1321 } else {
1322 document.getElementById("tracksAndZonesCheckboxes").style.display = "none";
1323 tracksVisible(false);
1324 zonesVisible(false);
1325 }
1326 initBooleanSetting("dnpOutline", false, "dnpOutlineCheckbox", dnpOutline);
1327 initBooleanSetting("redrawOnDrag", config.redraw_on_drag, "dragCheckbox", setRedrawOnDrag);
1328 initBooleanSetting("darkmode", config.dark_mode, "darkmodeCheckbox", setDarkMode);
1329 initBooleanSetting("highlightpin1", config.highlight_pin1, "highlightpin1Checkbox", setHighlightPin1);
1330 settings.boardRotation = readStorage("boardRotation");
1331 if (settings.boardRotation === null) {
1332 settings.boardRotation = config.board_rotation * 5;
1333 } else {
1334 settings.boardRotation = parseInt(settings.boardRotation);
1335 }
1336 document.getElementById("boardRotation").value = settings.boardRotation / 5;
1337 document.getElementById("rotationDegree").textContent = settings.boardRotation;
1338}
1339
1340// Helper classes for user js callbacks.
1341
1342const IBOM_EVENT_TYPES = {
1343 ALL: "all",
1344 HIGHLIGHT_EVENT: "highlightEvent",
1345 CHECKBOX_CHANGE_EVENT: "checkboxChangeEvent",
1346 BOM_BODY_CHANGE_EVENT: "bomBodyChangeEvent",
1347}
1348
1349const EventHandler = {
1350 callbacks: {},
1351 init: function() {
1352 for (eventType of Object.values(IBOM_EVENT_TYPES))
1353 this.callbacks[eventType] = [];
1354 },
1355 registerCallback: function(eventType, callback) {
1356 this.callbacks[eventType].push(callback);
1357 },
1358 emitEvent: function(eventType, eventArgs) {
1359 event = {
1360 eventType: eventType,
1361 args: eventArgs,
1362 }
1363 var callback;
1364 for(callback of this.callbacks[eventType])
1365 callback(event);
1366 for(callback of this.callbacks[IBOM_EVENT_TYPES.ALL])
1367 callback(event);
1368 }
1369}
1370EventHandler.init();
1371
1372///////////////////////////////////////////////
1373
1374///////////////////////////////////////////////
1375/* PCB rendering code */
1376
1377var emptyContext2d = document.createElement("canvas").getContext("2d");
1378
1379function deg2rad(deg) {
1380 return deg * Math.PI / 180;
1381}
1382
1383function calcFontPoint(linepoint, text, offsetx, offsety, tilt) {
1384 var point = [
1385 linepoint[0] * text.width + offsetx,
1386 linepoint[1] * text.height + offsety
1387 ];
1388 // This approximates pcbnew behavior with how text tilts depending on horizontal justification
1389 point[0] -= (linepoint[1] + 0.5 * (1 + text.horiz_justify)) * text.height * tilt;
1390 return point;
1391}
1392
1393function drawtext(ctx, text, color, flip) {
1394 if ("ref" in text && !settings.renderReferences) return;
1395 if ("val" in text && !settings.renderValues) return;
1396 ctx.save();
1397 ctx.fillStyle = color;
1398 ctx.strokeStyle = color;
1399 ctx.lineCap = "round";
1400 ctx.lineJoin = "round";
1401 ctx.lineWidth = text.thickness;
1402 if (text.svgpath) {
1403 ctx.stroke(new Path2D(text.svgpath));
1404 ctx.restore();
1405 return;
1406 }
1407 ctx.translate(...text.pos);
1408 ctx.translate(text.thickness * 0.5, 0);
1409 var angle = -text.angle;
1410 if (text.attr.includes("mirrored")) {
1411 ctx.scale(-1, 1);
1412 angle = -angle;
1413 }
1414 var tilt = 0;
1415 if (text.attr.includes("italic")) {
1416 tilt = 0.125;
1417 }
1418 var interline = (text.height * 1.5 + text.thickness) / 2;
1419 var txt = text.text.split("\n");
1420 // KiCad ignores last empty line.
1421 if (txt[txt.length - 1] == '') txt.pop();
1422 ctx.rotate(deg2rad(angle));
1423 for (var i in txt) {
1424 var offsety = (-(txt.length - 1) + i * 2) * interline + text.height / 2;
1425 var lineWidth = text.thickness + interline * tilt;
1426 for (var j = 0; j < txt[i].length; j++) {
1427 if (txt[i][j] == '\t') {
1428 var fourSpaces = 4 * pcbdata.font_data[' '].w * text.width;
1429 lineWidth += fourSpaces - lineWidth % fourSpaces;
1430 } else {
1431 if (txt[i][j] == '~') {
1432 j++;
1433 if (j == txt[i].length)
1434 break;
1435 }
1436 lineWidth += pcbdata.font_data[txt[i][j]].w * text.width;
1437 }
1438 }
1439 var offsetx = 0;
1440 switch (text.horiz_justify) {
1441 case -1:
1442 // Justify left, do nothing
1443 break;
1444 case 0:
1445 // Justify center
1446 offsetx -= lineWidth / 2;
1447 break;
1448 case 1:
1449 // Justify right
1450 offsetx -= lineWidth;
1451 break;
1452 }
1453 var inOverbar = false;
1454 for (var j = 0; j < txt[i].length; j++) {
1455 if (txt[i][j] == '\t') {
1456 var fourSpaces = 4 * pcbdata.font_data[' '].w * text.width;
1457 offsetx += fourSpaces - offsetx % fourSpaces;
1458 continue;
1459 } else if (txt[i][j] == '~') {
1460 j++;
1461 if (j == txt[i].length)
1462 break;
1463 if (txt[i][j] != '~') {
1464 inOverbar = !inOverbar;
1465 }
1466 }
1467 var glyph = pcbdata.font_data[txt[i][j]];
1468 if (inOverbar) {
1469 var overbarStart = [offsetx, -text.height * 1.4 + offsety];
1470 var overbarEnd = [offsetx + text.width * glyph.w, overbarStart[1]];
1471
1472 if (!lastHadOverbar) {
1473 overbarStart[0] += text.height * 1.4 * tilt;
1474 lastHadOverbar = true;
1475 }
1476 ctx.beginPath();
1477 ctx.moveTo(...overbarStart);
1478 ctx.lineTo(...overbarEnd);
1479 ctx.stroke();
1480 } else {
1481 lastHadOverbar = false;
1482 }
1483 for (var line of glyph.l) {
1484 ctx.beginPath();
1485 ctx.moveTo(...calcFontPoint(line[0], text, offsetx, offsety, tilt));
1486 for (var k = 1; k < line.length; k++) {
1487 ctx.lineTo(...calcFontPoint(line[k], text, offsetx, offsety, tilt));
1488 }
1489 ctx.stroke();
1490 }
1491 offsetx += glyph.w * text.width;
1492 }
1493 }
1494 ctx.restore();
1495}
1496
1497function drawedge(ctx, scalefactor, edge, color) {
1498 ctx.strokeStyle = color;
1499 ctx.lineWidth = Math.max(1 / scalefactor, edge.width);
1500 ctx.lineCap = "round";
1501 if (edge.svgpath) {
1502 ctx.stroke(new Path2D(edge.svgpath));
1503 } else {
1504 ctx.beginPath();
1505 if (edge.type == "segment") {
1506 ctx.moveTo(...edge.start);
1507 ctx.lineTo(...edge.end);
1508 }
1509 if (edge.type == "arc") {
1510 ctx.arc(
1511 ...edge.start,
1512 edge.radius,
1513 deg2rad(edge.startangle),
1514 deg2rad(edge.endangle));
1515 }
1516 if (edge.type == "circle") {
1517 ctx.arc(
1518 ...edge.start,
1519 edge.radius,
1520 0, 2 * Math.PI);
1521 ctx.closePath();
1522 }
1523 if (edge.type == "curve") {
1524 ctx.moveTo(...edge.start);
1525 ctx.bezierCurveTo(...edge.cpa, ...edge.cpb, ...edge.end);
1526 }
1527 ctx.stroke();
1528 }
1529}
1530
1531function getChamferedRectPath(size, radius, chamfpos, chamfratio) {
1532 // chamfpos is a bitmask, left = 1, right = 2, bottom left = 4, bottom right = 8
1533 var path = new Path2D();
1534 var width = size[0];
1535 var height = size[1];
1536 var x = width * -0.5;
1537 var y = height * -0.5;
1538 var chamfOffset = Math.min(width, height) * chamfratio;
1539 path.moveTo(x, 0);
1540 if (chamfpos & 4) {
1541 path.lineTo(x, y + height - chamfOffset);
1542 path.lineTo(x + chamfOffset, y + height);
1543 path.lineTo(0, y + height);
1544 } else {
1545 path.arcTo(x, y + height, x + width, y + height, radius);
1546 }
1547 if (chamfpos & 8) {
1548 path.lineTo(x + width - chamfOffset, y + height);
1549 path.lineTo(x + width, y + height - chamfOffset);
1550 path.lineTo(x + width, 0);
1551 } else {
1552 path.arcTo(x + width, y + height, x + width, y, radius);
1553 }
1554 if (chamfpos & 2) {
1555 path.lineTo(x + width, y + chamfOffset);
1556 path.lineTo(x + width - chamfOffset, y);
1557 path.lineTo(0, y);
1558 } else {
1559 path.arcTo(x + width, y, x, y, radius);
1560 }
1561 if (chamfpos & 1) {
1562 path.lineTo(x + chamfOffset, y);
1563 path.lineTo(x, y + chamfOffset);
1564 path.lineTo(x, 0);
1565 } else {
1566 path.arcTo(x, y, x, y + height, radius);
1567 }
1568 path.closePath();
1569 return path;
1570}
1571
1572function getOblongPath(size) {
1573 return getChamferedRectPath(size, Math.min(size[0], size[1]) / 2, 0, 0);
1574}
1575
1576function getPolygonsPath(shape) {
1577 if (shape.path2d) {
1578 return shape.path2d;
1579 }
1580 if (shape.svgpath) {
1581 shape.path2d = new Path2D(shape.svgpath);
1582 } else {
1583 var path = new Path2D();
1584 for (var polygon of shape.polygons) {
1585 path.moveTo(...polygon[0]);
1586 for (var i = 1; i < polygon.length; i++) {
1587 path.lineTo(...polygon[i]);
1588 }
1589 path.closePath();
1590 }
1591 shape.path2d = path;
1592 }
1593 return shape.path2d;
1594}
1595
1596function drawPolygonShape(ctx, shape, color) {
1597 ctx.save();
1598 ctx.fillStyle = color;
1599 if (!shape.svgpath) {
1600 ctx.translate(...shape.pos);
1601 ctx.rotate(deg2rad(-shape.angle));
1602 }
1603 ctx.fill(getPolygonsPath(shape));
1604 ctx.restore();
1605}
1606
1607function drawDrawing(ctx, layer, scalefactor, drawing, color) {
1608 if (["segment", "arc", "circle", "curve"].includes(drawing.type)) {
1609 drawedge(ctx, scalefactor, drawing, color);
1610 } else if (drawing.type == "polygon") {
1611 drawPolygonShape(ctx, drawing, color);
1612 } else {
1613 drawtext(ctx, drawing, color, layer == "B");
1614 }
1615}
1616
1617function getCirclePath(radius) {
1618 var path = new Path2D();
1619 path.arc(0, 0, radius, 0, 2 * Math.PI);
1620 path.closePath();
1621 return path;
1622}
1623
1624function getCachedPadPath(pad) {
1625 if (!pad.path2d) {
1626 // if path2d is not set, build one and cache it on pad object
1627 if (pad.shape == "rect") {
1628 pad.path2d = new Path2D();
1629 pad.path2d.rect(...pad.size.map(c => -c * 0.5), ...pad.size);
1630 } else if (pad.shape == "oval") {
1631 pad.path2d = getOblongPath(pad.size);
1632 } else if (pad.shape == "circle") {
1633 pad.path2d = getCirclePath(pad.size[0] / 2);
1634 } else if (pad.shape == "roundrect") {
1635 pad.path2d = getChamferedRectPath(pad.size, pad.radius, 0, 0);
1636 } else if (pad.shape == "chamfrect") {
1637 pad.path2d = getChamferedRectPath(pad.size, pad.radius, pad.chamfpos, pad.chamfratio)
1638 } else if (pad.shape == "custom") {
1639 pad.path2d = getPolygonsPath(pad);
1640 }
1641 }
1642 return pad.path2d;
1643}
1644
1645function drawPad(ctx, pad, color, outline, hole) {
1646 ctx.save();
1647 ctx.translate(...pad.pos);
1648 ctx.rotate(deg2rad(pad.angle));
1649 if (pad.offset) {
1650 ctx.translate(...pad.offset);
1651 }
1652 ctx.fillStyle = color;
1653 ctx.strokeStyle = color;
1654 var path = getCachedPadPath(pad);
1655 if (outline) {
1656 ctx.stroke(path);
1657 } else {
1658 ctx.fill(path);
1659 }
1660 if (pad.type == "th" && hole) {
1661 if (pad.offset) {
1662 ctx.translate(-pad.offset[0], -pad.offset[1]);
1663 }
1664 ctx.fillStyle = "#CCCCCC";
1665 if (pad.drillshape == "oblong") {
1666 ctx.fill(getOblongPath(pad.drillsize));
1667 } else {
1668 ctx.fill(getCirclePath(pad.drillsize[0] / 2));
1669 }
1670 }
1671 ctx.restore();
1672}
1673
1674function drawModule(ctx, layer, scalefactor, module, padcolor, outlinecolor, highlight, outline) {
1675 if (highlight) {
1676 // draw bounding box
1677 if (module.layer == layer) {
1678 ctx.save();
1679 ctx.globalAlpha = 0.2;
1680 ctx.translate(...module.bbox.pos);
1681 ctx.rotate(deg2rad(-module.bbox.angle));
1682 ctx.translate(...module.bbox.relpos);
1683 ctx.fillStyle = padcolor;
1684 ctx.fillRect(0, 0, ...module.bbox.size);
1685 ctx.globalAlpha = 1;
1686 ctx.strokeStyle = padcolor;
1687 ctx.strokeRect(0, 0, ...module.bbox.size);
1688 ctx.restore();
1689 }
1690 }
1691 // draw drawings
1692 for (var drawing of module.drawings) {
1693 if (drawing.layer == layer) {
1694 drawDrawing(ctx, layer, scalefactor, drawing.drawing, padcolor);
1695 }
1696 }
1697 // draw pads
1698 if (settings.renderPads) {
1699 for (var pad of module.pads) {
1700 if (pad.layers.includes(layer)) {
1701 drawPad(ctx, pad, padcolor, outline, true);
1702 if (pad.pin1 && settings.highlightpin1) {
1703 drawPad(ctx, pad, outlinecolor, true, false);
1704 }
1705 }
1706 }
1707 }
1708}
1709
1710function drawEdgeCuts(canvas, scalefactor) {
1711 var ctx = canvas.getContext("2d");
1712 var edgecolor = getComputedStyle(topmostdiv).getPropertyValue('--pcb-edge-color');
1713 for (var edge of pcbdata.edges) {
1714 drawedge(ctx, scalefactor, edge, edgecolor);
1715 }
1716}
1717
1718function drawModules(canvas, layer, scalefactor, highlight) {
1719 var ctx = canvas.getContext("2d");
1720 ctx.lineWidth = 3 / scalefactor;
1721 var style = getComputedStyle(topmostdiv);
1722 var padcolor = style.getPropertyValue('--pad-color');
1723 var outlinecolor = style.getPropertyValue('--pin1-outline-color');
1724 if (highlight) {
1725 padcolor = style.getPropertyValue('--pad-color-highlight');
1726 outlinecolor = style.getPropertyValue('--pin1-outline-color-highlight');
1727 }
1728 for (var i = 0; i < pcbdata.modules.length; i++) {
1729 var mod = pcbdata.modules[i];
1730 var outline = settings.renderDnpOutline && pcbdata.bom.skipped.includes(i);
1731 if (!highlight || highlightedModules.includes(i)) {
1732 drawModule(ctx, layer, scalefactor, mod, padcolor, outlinecolor, highlight, outline);
1733 }
1734 }
1735}
1736
1737function drawBgLayer(layername, canvas, layer, scalefactor, edgeColor, polygonColor, textColor) {
1738 var ctx = canvas.getContext("2d");
1739 for (var d of pcbdata[layername][layer]) {
1740 if (["segment", "arc", "circle", "curve"].includes(d.type)) {
1741 drawedge(ctx, scalefactor, d, edgeColor);
1742 } else if (d.type == "polygon") {
1743 drawPolygonShape(ctx, d, polygonColor);
1744 } else {
1745 drawtext(ctx, d, textColor, layer == "B");
1746 }
1747 }
1748}
1749
1750function drawTracks(canvas, layer, color, highlight) {
1751 ctx = canvas.getContext("2d");
1752 ctx.strokeStyle = color;
1753 ctx.lineCap = "round";
1754 for(var track of pcbdata.tracks[layer]) {
1755 if (highlight && highlightedNet != track.net) continue;
1756 ctx.lineWidth = track.width;
1757 ctx.beginPath();
1758 ctx.moveTo(...track.start);
1759 ctx.lineTo(...track.end);
1760 ctx.stroke();
1761 }
1762}
1763
1764function drawZones(canvas, layer, color, highlight) {
1765 ctx = canvas.getContext("2d");
1766 ctx.strokeStyle = color;
1767 ctx.fillStyle = color;
1768 ctx.lineJoin = "round";
1769 for(var zone of pcbdata.zones[layer]) {
1770 if (!zone.path2d) {
1771 zone.path2d = getPolygonsPath(zone);
1772 }
1773 if (highlight && highlightedNet != zone.net) continue;
1774 ctx.lineWidth = zone.width ? zone.width : 0;
1775 ctx.fill(zone.path2d);
1776 ctx.stroke(zone.path2d);
1777 }
1778}
1779
1780function clearCanvas(canvas, color = null) {
1781 var ctx = canvas.getContext("2d");
1782 ctx.save();
1783 ctx.setTransform(1, 0, 0, 1, 0, 0);
1784 if (color) {
1785 ctx.fillStyle = color;
1786 ctx.fillRect(0, 0, canvas.width, canvas.height);
1787 } else {
1788 ctx.clearRect(0, 0, canvas.width, canvas.height);
1789 }
1790 ctx.restore();
1791}
1792
1793function drawNets(canvas, layer, highlight) {
1794 var style = getComputedStyle(topmostdiv);
1795 if (settings.renderTracks) {
1796 var trackColor = style.getPropertyValue(highlight ? '--track-color-highlight' : '--track-color');
1797 drawTracks(canvas, layer, trackColor, highlight);
1798 }
1799 if (settings.renderZones) {
1800 var zoneColor = style.getPropertyValue(highlight ? '--zone-color-highlight' : '--zone-color');
1801 drawZones(canvas, layer, zoneColor, highlight);
1802 }
1803 if (highlight && settings.renderPads) {
1804 var padColor = style.getPropertyValue('--pad-color-highlight');
1805 var ctx = canvas.getContext("2d");
1806 for (var mod of pcbdata.modules) {
1807 // draw pads
1808 for (var pad of mod.pads) {
1809 if (highlightedNet != pad.net) continue;
1810 if (pad.layers.includes(layer)) {
1811 drawPad(ctx, pad, padColor, false, true);
1812 }
1813 }
1814 }
1815 }
1816}
1817
1818function drawHighlightsOnLayer(canvasdict, clear = true) {
1819 if (clear) {
1820 clearCanvas(canvasdict.highlight);
1821 }
1822 if (highlightedModules.length > 0) {
1823 drawModules(canvasdict.highlight, canvasdict.layer,
1824 canvasdict.transform.s * canvasdict.transform.zoom, true);
1825 }
1826 if (highlightedNet !== null) {
1827 drawNets(canvasdict.highlight, canvasdict.layer, true);
1828 }
1829}
1830
1831function drawHighlights() {
1832 drawHighlightsOnLayer(allcanvas.front);
1833 drawHighlightsOnLayer(allcanvas.back);
1834}
1835
1836function drawBackground(canvasdict, clear = true) {
1837 if (clear) {
1838 clearCanvas(canvasdict.bg);
1839 clearCanvas(canvasdict.fab);
1840 clearCanvas(canvasdict.silk);
1841 }
1842
1843 drawNets(canvasdict.bg, canvasdict.layer, false);
1844 drawModules(canvasdict.bg, canvasdict.layer,
1845 canvasdict.transform.s * canvasdict.transform.zoom, false);
1846
1847 drawEdgeCuts(canvasdict.bg, canvasdict.transform.s);
1848
1849 var style = getComputedStyle(topmostdiv);
1850 var edgeColor = style.getPropertyValue('--silkscreen-edge-color');
1851 var polygonColor = style.getPropertyValue('--silkscreen-polygon-color');
1852 var textColor = style.getPropertyValue('--silkscreen-text-color');
1853 if (settings.renderSilkscreen) {
1854 drawBgLayer(
1855 "silkscreen", canvasdict.silk, canvasdict.layer,
1856 canvasdict.transform.s * canvasdict.transform.zoom,
1857 edgeColor, polygonColor, textColor);
1858 }
1859 edgeColor = style.getPropertyValue('--fabrication-edge-color');
1860 polygonColor = style.getPropertyValue('--fabrication-polygon-color');
1861 textColor = style.getPropertyValue('--fabrication-text-color');
1862 if (settings.renderFabrication) {
1863 drawBgLayer(
1864 "fabrication", canvasdict.fab, canvasdict.layer,
1865 canvasdict.transform.s * canvasdict.transform.zoom,
1866 edgeColor, polygonColor, textColor);
1867 }
1868}
1869
1870function prepareCanvas(canvas, flip, transform) {
1871 var ctx = canvas.getContext("2d");
1872 ctx.setTransform(1, 0, 0, 1, 0, 0);
1873 var fontsize = 1.55;
1874 ctx.scale(transform.zoom, transform.zoom);
1875 ctx.translate(transform.panx, transform.pany);
1876 if (flip) {
1877 ctx.scale(-1, 1);
1878 }
1879 ctx.translate(transform.x, transform.y);
1880 ctx.rotate(deg2rad(settings.boardRotation));
1881 ctx.scale(transform.s, transform.s);
1882}
1883
1884function prepareLayer(canvasdict) {
1885 var flip = (canvasdict.layer == "B");
1886 for (var c of ["bg", "fab", "silk", "highlight"]) {
1887 prepareCanvas(canvasdict[c], flip, canvasdict.transform);
1888 }
1889}
1890
1891function rotateVector(v, angle) {
1892 angle = deg2rad(angle);
1893 return [
1894 v[0] * Math.cos(angle) - v[1] * Math.sin(angle),
1895 v[0] * Math.sin(angle) + v[1] * Math.cos(angle)
1896 ];
1897}
1898
1899function applyRotation(bbox) {
1900 var corners = [
1901 [bbox.minx, bbox.miny],
1902 [bbox.minx, bbox.maxy],
1903 [bbox.maxx, bbox.miny],
1904 [bbox.maxx, bbox.maxy],
1905 ];
1906 corners = corners.map((v) => rotateVector(v, settings.boardRotation));
1907 return {
1908 minx: corners.reduce((a, v) => Math.min(a, v[0]), Infinity),
1909 miny: corners.reduce((a, v) => Math.min(a, v[1]), Infinity),
1910 maxx: corners.reduce((a, v) => Math.max(a, v[0]), -Infinity),
1911 maxy: corners.reduce((a, v) => Math.max(a, v[1]), -Infinity),
1912 }
1913}
1914
1915function recalcLayerScale(layerdict, width, height) {
1916 var bbox = applyRotation(pcbdata.edges_bbox);
1917 var scalefactor = 0.98 * Math.min(
1918 width / (bbox.maxx - bbox.minx),
1919 height / (bbox.maxy - bbox.miny)
1920 );
1921 if (scalefactor < 0.1) {
1922 scalefactor = 1;
1923 }
1924 layerdict.transform.s = scalefactor;
1925 var flip = (layerdict.layer == "B");
1926 if (flip) {
1927 layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor + width) * 0.5;
1928 } else {
1929 layerdict.transform.x = -((bbox.maxx + bbox.minx) * scalefactor - width) * 0.5;
1930 }
1931 layerdict.transform.y = -((bbox.maxy + bbox.miny) * scalefactor - height) * 0.5;
1932 for (var c of ["bg", "fab", "silk", "highlight"]) {
1933 canvas = layerdict[c];
1934 canvas.width = width;
1935 canvas.height = height;
1936 canvas.style.width = (width / devicePixelRatio) + "px";
1937 canvas.style.height = (height / devicePixelRatio) + "px";
1938 }
1939}
1940
1941function redrawCanvas(layerdict) {
1942 prepareLayer(layerdict);
1943 drawBackground(layerdict);
1944 drawHighlightsOnLayer(layerdict);
1945}
1946
1947function resizeCanvas(layerdict) {
1948 var canvasdivid = {
1949 "F": "frontcanvas",
1950 "B": "backcanvas"
1951 } [layerdict.layer];
1952 var width = document.getElementById(canvasdivid).clientWidth * devicePixelRatio;
1953 var height = document.getElementById(canvasdivid).clientHeight * devicePixelRatio;
1954 recalcLayerScale(layerdict, width, height);
1955 redrawCanvas(layerdict);
1956}
1957
1958function resizeAll() {
1959 resizeCanvas(allcanvas.front);
1960 resizeCanvas(allcanvas.back);
1961}
1962
1963function pointWithinDistanceToSegment(x, y, x1, y1, x2, y2, d) {
1964 var A = x - x1;
1965 var B = y - y1;
1966 var C = x2 - x1;
1967 var D = y2 - y1;
1968
1969 var dot = A * C + B * D;
1970 var len_sq = C * C + D * D;
1971 var dx, dy;
1972 if (len_sq == 0) {
1973 // start and end of the segment coincide
1974 dx = x - x1;
1975 dy = y - y1;
1976 } else {
1977 var param = dot / len_sq;
1978 var xx, yy;
1979 if (param < 0) {
1980 xx = x1;
1981 yy = y1;
1982 } else if (param > 1) {
1983 xx = x2;
1984 yy = y2;
1985 } else {
1986 xx = x1 + param * C;
1987 yy = y1 + param * D;
1988 }
1989 dx = x - xx;
1990 dy = y - yy;
1991 }
1992 return dx * dx + dy * dy <= d * d;
1993}
1994
1995function pointWithinPad(x, y, pad) {
1996 var v = [x - pad.pos[0], y - pad.pos[1]];
1997 v = rotateVector(v, -pad.angle);
1998 if (pad.offset) {
1999 v[0] -= pad.offset[0];
2000 v[1] -= pad.offset[1];
2001 }
2002 return emptyContext2d.isPointInPath(getCachedPadPath(pad), ...v);
2003}
2004
2005function netHitScan(layer, x, y) {
2006 // Check track segments
2007 if (settings.renderTracks && pcbdata.tracks) {
2008 for(var track of pcbdata.tracks[layer]) {
2009 if (pointWithinDistanceToSegment(x, y, ...track.start, ...track.end, track.width / 2)) {
2010 return track.net;
2011 }
2012 }
2013 }
2014 // Check pads
2015 if (settings.renderPads) {
2016 for (var mod of pcbdata.modules) {
2017 for(var pad of mod.pads) {
2018 if (pad.layers.includes(layer) && pointWithinPad(x, y, pad)) {
2019 return pad.net;
2020 }
2021 }
2022 }
2023 }
2024 return null;
2025}
2026
2027function pointWithinModuleBbox(x, y, bbox) {
2028 var v = [x - bbox.pos[0], y - bbox.pos[1]];
2029 v = rotateVector(v, bbox.angle);
2030 return bbox.relpos[0] <= v[0] && v[0] <= bbox.relpos[0] + bbox.size[0] &&
2031 bbox.relpos[1] <= v[1] && v[1] <= bbox.relpos[1] + bbox.size[1];
2032}
2033
2034function bboxHitScan(layer, x, y) {
2035 var result = [];
2036 for (var i = 0; i < pcbdata.modules.length; i++) {
2037 var module = pcbdata.modules[i];
2038 if (module.layer == layer) {
2039 if (pointWithinModuleBbox(x, y, module.bbox)) {
2040 result.push(i);
2041 }
2042 }
2043 }
2044 return result;
2045}
2046
2047function handlePointerDown(e, layerdict) {
2048 if (e.button != 0 && e.button != 1) {
2049 return;
2050 }
2051 e.preventDefault();
2052 e.stopPropagation();
2053
2054 if (!e.hasOwnProperty("offsetX")) {
2055 // The polyfill doesn't set this properly
2056 e.offsetX = e.pageX - e.currentTarget.offsetLeft;
2057 e.offsetY = e.pageY - e.currentTarget.offsetTop;
2058 }
2059
2060 layerdict.pointerStates[e.pointerId] = {
2061 distanceTravelled: 0,
2062 lastX: e.offsetX,
2063 lastY: e.offsetY,
2064 downTime: Date.now(),
2065 };
2066}
2067
2068function handleMouseClick(e, layerdict) {
2069 if (!e.hasOwnProperty("offsetX")) {
2070 // The polyfill doesn't set this properly
2071 e.offsetX = e.pageX - e.currentTarget.offsetLeft;
2072 e.offsetY = e.pageY - e.currentTarget.offsetTop;
2073 }
2074
2075 var x = e.offsetX;
2076 var y = e.offsetY;
2077 var t = layerdict.transform;
2078 if (layerdict.layer == "B") {
2079 x = (devicePixelRatio * x / t.zoom - t.panx + t.x) / -t.s;
2080 } else {
2081 x = (devicePixelRatio * x / t.zoom - t.panx - t.x) / t.s;
2082 }
2083 y = (devicePixelRatio * y / t.zoom - t.y - t.pany) / t.s;
2084 var v = rotateVector([x, y], -settings.boardRotation);
2085 if ("nets" in pcbdata) {
2086 var net = netHitScan(layerdict.layer, ...v);
2087 if (net !== highlightedNet) {
2088 netClicked(net);
2089 }
2090 }
2091 if (highlightedNet === null) {
2092 var modules = bboxHitScan(layerdict.layer, ...v);
2093 if (modules.length > 0) {
2094 modulesClicked(modules);
2095 }
2096 }
2097}
2098
2099function handlePointerLeave(e, layerdict) {
2100 e.preventDefault();
2101 e.stopPropagation();
2102
2103 if (!settings.redrawOnDrag) {
2104 redrawCanvas(layerdict);
2105 }
2106
2107 delete layerdict.pointerStates[e.pointerId];
2108}
2109
2110function resetTransform(layerdict) {
2111 layerdict.transform.panx = 0;
2112 layerdict.transform.pany = 0;
2113 layerdict.transform.zoom = 1;
2114 redrawCanvas(layerdict);
2115}
2116
2117function handlePointerUp(e, layerdict) {
2118 if (!e.hasOwnProperty("offsetX")) {
2119 // The polyfill doesn't set this properly
2120 e.offsetX = e.pageX - e.currentTarget.offsetLeft;
2121 e.offsetY = e.pageY - e.currentTarget.offsetTop;
2122 }
2123
2124 e.preventDefault();
2125 e.stopPropagation();
2126
2127 if (e.button == 2) {
2128 // Reset pan and zoom on right click.
2129 resetTransform(layerdict);
2130 layerdict.anotherPointerTapped = false;
2131 return;
2132 }
2133
2134 // We haven't necessarily had a pointermove event since the interaction started, so make sure we update this now
2135 var ptr = layerdict.pointerStates[e.pointerId];
2136 ptr.distanceTravelled += Math.abs(e.offsetX - ptr.lastX) + Math.abs(e.offsetY - ptr.lastY);
2137
2138 if (e.button == 0 && ptr.distanceTravelled < 10 && Date.now() - ptr.downTime <= 500) {
2139 if (Object.keys(layerdict.pointerStates).length == 1) {
2140 if (layerdict.anotherPointerTapped) {
2141 // This is the second pointer coming off of a two-finger tap
2142 resetTransform(layerdict);
2143 } else {
2144 // This is just a regular tap
2145 handleMouseClick(e, layerdict);
2146 }
2147 layerdict.anotherPointerTapped = false;
2148 } else {
2149 // This is the first finger coming off of what could become a two-finger tap
2150 layerdict.anotherPointerTapped = true;
2151 }
2152 } else {
2153 if (!settings.redrawOnDrag) {
2154 redrawCanvas(layerdict);
2155 }
2156 layerdict.anotherPointerTapped = false;
2157 }
2158
2159 delete layerdict.pointerStates[e.pointerId];
2160}
2161
2162function handlePointerMove(e, layerdict) {
2163 if (!layerdict.pointerStates.hasOwnProperty(e.pointerId)) {
2164 return;
2165 }
2166 e.preventDefault();
2167 e.stopPropagation();
2168
2169 if (!e.hasOwnProperty("offsetX")) {
2170 // The polyfill doesn't set this properly
2171 e.offsetX = e.pageX - e.currentTarget.offsetLeft;
2172 e.offsetY = e.pageY - e.currentTarget.offsetTop;
2173 }
2174
2175 var thisPtr = layerdict.pointerStates[e.pointerId];
2176
2177 var dx = e.offsetX - thisPtr.lastX;
2178 var dy = e.offsetY - thisPtr.lastY;
2179
2180 // If this number is low on pointer up, we count the action as a click
2181 thisPtr.distanceTravelled += Math.abs(dx) + Math.abs(dy);
2182
2183 if (Object.keys(layerdict.pointerStates).length == 1) {
2184 // This is a simple drag
2185 layerdict.transform.panx += devicePixelRatio * dx / layerdict.transform.zoom;
2186 layerdict.transform.pany += devicePixelRatio * dy / layerdict.transform.zoom;
2187 } else if (Object.keys(layerdict.pointerStates).length == 2) {
2188 var otherPtr = Object.values(layerdict.pointerStates).filter((ptr) => ptr != thisPtr)[0];
2189
2190 var oldDist = Math.sqrt(Math.pow(thisPtr.lastX - otherPtr.lastX, 2) + Math.pow(thisPtr.lastY - otherPtr.lastY, 2));
2191 var newDist = Math.sqrt(Math.pow(e.offsetX - otherPtr.lastX, 2) + Math.pow(e.offsetY - otherPtr.lastY, 2));
2192
2193 var scaleFactor = newDist/oldDist;
2194
2195 if (scaleFactor != NaN) {
2196 layerdict.transform.zoom *= scaleFactor;
2197
2198 var zoomd = (1 - scaleFactor) / layerdict.transform.zoom;
2199 layerdict.transform.panx += devicePixelRatio * otherPtr.lastX * zoomd;
2200 layerdict.transform.pany += devicePixelRatio * otherPtr.lastY * zoomd;
2201 }
2202 }
2203
2204 thisPtr.lastX = e.offsetX;
2205 thisPtr.lastY = e.offsetY;
2206
2207 if (settings.redrawOnDrag) {
2208 redrawCanvas(layerdict);
2209 }
2210}
2211
2212function handleMouseWheel(e, layerdict) {
2213 e.preventDefault();
2214 e.stopPropagation();
2215 var t = layerdict.transform;
2216 var wheeldelta = e.deltaY;
2217 if (e.deltaMode == 1) {
2218 // FF only, scroll by lines
2219 wheeldelta *= 30;
2220 } else if (e.deltaMode == 2) {
2221 wheeldelta *= 300;
2222 }
2223 var m = Math.pow(1.1, -wheeldelta / 40);
2224 // Limit amount of zoom per tick.
2225 if (m > 2) {
2226 m = 2;
2227 } else if (m < 0.5) {
2228 m = 0.5;
2229 }
2230 t.zoom *= m;
2231 var zoomd = (1 - m) / t.zoom;
2232 t.panx += devicePixelRatio * e.offsetX * zoomd;
2233 t.pany += devicePixelRatio * e.offsetY * zoomd;
2234 redrawCanvas(layerdict);
2235}
2236
2237function addMouseHandlers(div, layerdict) {
2238 div.addEventListener("pointerdown", function(e) {
2239 handlePointerDown(e, layerdict);
2240 });
2241 div.addEventListener("pointermove", function(e) {
2242 handlePointerMove(e, layerdict);
2243 });
2244 div.addEventListener("pointerup", function(e) {
2245 handlePointerUp(e, layerdict);
2246 });
2247 var pointerleave = function(e) {
2248 handlePointerLeave(e, layerdict);
2249 }
2250 div.addEventListener("pointercancel", pointerleave);
2251 div.addEventListener("pointerleave", pointerleave);
2252 div.addEventListener("pointerout", pointerleave);
2253
2254 div.onwheel = function(e) {
2255 handleMouseWheel(e, layerdict);
2256 }
2257 for (var element of [div, layerdict.bg, layerdict.fab, layerdict.silk, layerdict.highlight]) {
2258 element.addEventListener("contextmenu", function(e) {
2259 e.preventDefault();
2260 }, false);
2261 }
2262}
2263
2264function setRedrawOnDrag(value) {
2265 settings.redrawOnDrag = value;
2266 writeStorage("redrawOnDrag", value);
2267}
2268
2269function setBoardRotation(value) {
2270 settings.boardRotation = value * 5;
2271 writeStorage("boardRotation", settings.boardRotation);
2272 document.getElementById("rotationDegree").textContent = settings.boardRotation;
2273 resizeAll();
2274}
2275
2276function initRender() {
2277 allcanvas = {
2278 front: {
2279 transform: {
2280 x: 0,
2281 y: 0,
2282 s: 1,
2283 panx: 0,
2284 pany: 0,
2285 zoom: 1,
2286 },
2287 pointerStates: {},
2288 anotherPointerTapped: false,
2289 bg: document.getElementById("F_bg"),
2290 fab: document.getElementById("F_fab"),
2291 silk: document.getElementById("F_slk"),
2292 highlight: document.getElementById("F_hl"),
2293 layer: "F",
2294 },
2295 back: {
2296 transform: {
2297 x: 0,
2298 y: 0,
2299 s: 1,
2300 panx: 0,
2301 pany: 0,
2302 zoom: 1,
2303 },
2304 pointerStates: {},
2305 anotherPointerTapped: false,
2306 bg: document.getElementById("B_bg"),
2307 fab: document.getElementById("B_fab"),
2308 silk: document.getElementById("B_slk"),
2309 highlight: document.getElementById("B_hl"),
2310 layer: "B",
2311 }
2312 };
2313 addMouseHandlers(document.getElementById("frontcanvas"), allcanvas.front);
2314 addMouseHandlers(document.getElementById("backcanvas"), allcanvas.back);
2315}
2316
2317///////////////////////////////////////////////
2318
2319///////////////////////////////////////////////
2320/* DOM manipulation and misc code */
2321
2322var bomsplit;
2323var canvassplit;
2324var initDone = false;
2325var bomSortFunction = null;
2326var currentSortColumn = null;
2327var currentSortOrder = null;
2328var currentHighlightedRowId;
2329var highlightHandlers = [];
2330var moduleIndexToHandler = {};
2331var netsToHandler = {};
2332var highlightedModules = [];
2333var highlightedNet = null;
2334var lastClicked;
2335
2336function dbg(html) {
2337 dbgdiv.innerHTML = html;
2338}
2339
2340function redrawIfInitDone() {
2341 if (initDone) {
2342 redrawCanvas(allcanvas.front);
2343 redrawCanvas(allcanvas.back);
2344 }
2345}
2346
2347function padsVisible(value) {
2348 writeStorage("padsVisible", value);
2349 settings.renderPads = value;
2350 redrawIfInitDone();
2351}
2352
2353function referencesVisible(value) {
2354 writeStorage("referencesVisible", value);
2355 settings.renderReferences = value;
2356 redrawIfInitDone();
2357}
2358
2359function valuesVisible(value) {
2360 writeStorage("valuesVisible", value);
2361 settings.renderValues = value;
2362 redrawIfInitDone();
2363}
2364
2365function tracksVisible(value) {
2366 writeStorage("tracksVisible", value);
2367 settings.renderTracks = value;
2368 redrawIfInitDone();
2369}
2370
2371function zonesVisible(value) {
2372 writeStorage("zonesVisible", value);
2373 settings.renderZones = value;
2374 redrawIfInitDone();
2375}
2376
2377function dnpOutline(value) {
2378 writeStorage("dnpOutline", value);
2379 settings.renderDnpOutline = value;
2380 redrawIfInitDone();
2381}
2382
2383function setDarkMode(value) {
2384 if (value) {
2385 topmostdiv.classList.add("dark");
2386 } else {
2387 topmostdiv.classList.remove("dark");
2388 }
2389 writeStorage("darkmode", value);
2390 settings.darkMode = value;
2391 redrawIfInitDone();
2392}
2393
2394function setFullscreen(value) {
2395 if (value) {
2396 document.documentElement.requestFullscreen();
2397 } else {
2398 document.exitFullscreen();
2399 }
2400}
2401
2402function fabricationVisible(value) {
2403 writeStorage("fabricationVisible", value);
2404 settings.renderFabrication = value;
2405 redrawIfInitDone();
2406}
2407
2408function silkscreenVisible(value) {
2409 writeStorage("silkscreenVisible", value);
2410 settings.renderSilkscreen = value;
2411 redrawIfInitDone();
2412}
2413
2414function setHighlightPin1(value) {
2415 writeStorage("highlightpin1", value);
2416 settings.highlightpin1 = value;
2417 redrawIfInitDone();
2418}
2419
2420function getStoredCheckboxRefs(checkbox) {
2421 function convert(ref) {
2422 var intref = parseInt(ref);
2423 if (isNaN(intref)) {
2424 for (var i = 0; i < pcbdata.modules.length; i++) {
2425 if (pcbdata.modules[i].ref == ref) {
2426 return i;
2427 }
2428 }
2429 return -1;
2430 } else {
2431 return intref;
2432 }
2433 }
2434 if (!(checkbox in settings.checkboxStoredRefs)) {
2435 var val = readStorage("checkbox_" + checkbox);
2436 settings.checkboxStoredRefs[checkbox] = val ? val : "";
2437 }
2438 if (!settings.checkboxStoredRefs[checkbox]) {
2439 return new Set();
2440 } else {
2441 return new Set(settings.checkboxStoredRefs[checkbox].split(",").map(r => convert(r)).filter(a => a >= 0));
2442 }
2443}
2444
2445function getCheckboxState(checkbox, references) {
2446 var storedRefsSet = getStoredCheckboxRefs(checkbox);
2447 var currentRefsSet = new Set(references.map(r => r[1]));
2448 // Get difference of current - stored
2449 var difference = new Set(currentRefsSet);
2450 for (ref of storedRefsSet) {
2451 difference.delete(ref);
2452 }
2453 if (difference.size == 0) {
2454 // All the current refs are stored
2455 return "checked";
2456 } else if (difference.size == currentRefsSet.size) {
2457 // None of the current refs are stored
2458 return "unchecked";
2459 } else {
2460 // Some of the refs are stored
2461 return "indeterminate";
2462 }
2463}
2464
2465function setBomCheckboxState(checkbox, element, references) {
2466 var state = getCheckboxState(checkbox, references);
2467 element.checked = (state == "checked");
2468 element.indeterminate = (state == "indeterminate");
2469}
2470
2471function createCheckboxChangeHandler(checkbox, references, row) {
2472 return function() {
2473 refsSet = getStoredCheckboxRefs(checkbox);
2474 var darkenWhenChecked = settings.darkenWhenChecked == checkbox;
2475 eventArgs = {
2476 checkbox: checkbox,
2477 refs: references,
2478 }
2479 if (this.checked) {
2480 // checkbox ticked
2481 for (var ref of references) {
2482 refsSet.add(ref[1]);
2483 }
2484 if (darkenWhenChecked) {
2485 row.classList.add("checked");
2486 }
2487 eventArgs.state = 'checked';
2488 } else {
2489 // checkbox unticked
2490 for (var ref of references) {
2491 refsSet.delete(ref[1]);
2492 }
2493 if (darkenWhenChecked) {
2494 row.classList.remove("checked");
2495 }
2496 eventArgs.state = 'unchecked';
2497 }
2498 settings.checkboxStoredRefs[checkbox] = [...refsSet].join(",");
2499 writeStorage("checkbox_" + checkbox, settings.checkboxStoredRefs[checkbox]);
2500 updateCheckboxStats(checkbox);
2501 EventHandler.emitEvent(IBOM_EVENT_TYPES.CHECKBOX_CHANGE_EVENT, eventArgs);
2502 }
2503}
2504
2505function clearHighlightedModules() {
2506 if (currentHighlightedRowId) {
2507 document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
2508 currentHighlightedRowId = null;
2509 highlightedModules = [];
2510 highlightedNet = null;
2511 }
2512}
2513
2514function createRowHighlightHandler(rowid, refs, net) {
2515 return function() {
2516 if (currentHighlightedRowId) {
2517 if (currentHighlightedRowId == rowid) {
2518 return;
2519 }
2520 document.getElementById(currentHighlightedRowId).classList.remove("highlighted");
2521 }
2522 document.getElementById(rowid).classList.add("highlighted");
2523 currentHighlightedRowId = rowid;
2524 highlightedModules = refs ? refs.map(r => r[1]) : [];
2525 highlightedNet = net;
2526 drawHighlights();
2527 EventHandler.emitEvent(
2528 IBOM_EVENT_TYPES.HIGHLIGHT_EVENT,
2529 {
2530 rowid: rowid,
2531 refs: refs,
2532 net: net
2533 });
2534 }
2535}
2536
2537function entryMatches(entry) {
2538 if (settings.bommode == "netlist") {
2539 // entry is just a net name
2540 return entry.toLowerCase().indexOf(filter) >= 0;
2541 }
2542 // check refs
2543 for (var ref of entry[3]) {
2544 if (ref[0].toLowerCase().indexOf(filter) >= 0) {
2545 return true;
2546 }
2547 }
2548 // check extra fields
2549 for (var i in config.extra_fields) {
2550 if (entry[4][i].toLowerCase().indexOf(filter) >= 0) {
2551 return true;
2552 }
2553 }
2554 // check value
2555 if (entry[1].toLowerCase().indexOf(filter) >= 0) {
2556 return true;
2557 }
2558 // check footprint
2559 if (entry[2].toLowerCase().indexOf(filter) >= 0) {
2560 return true;
2561 }
2562 return false;
2563}
2564
2565function findRefInEntry(entry) {
2566 return entry[3].filter(r => r[0].toLowerCase() == reflookup);
2567}
2568
2569function highlightFilter(s) {
2570 if (!filter) {
2571 return s;
2572 }
2573 var parts = s.toLowerCase().split(filter);
2574 if (parts.length == 1) {
2575 return s;
2576 }
2577 var r = "";
2578 var pos = 0;
2579 for (var i in parts) {
2580 if (i > 0) {
2581 r += '<mark class="highlight">' +
2582 s.substring(pos, pos + filter.length) +
2583 '</mark>';
2584 pos += filter.length;
2585 }
2586 r += s.substring(pos, pos + parts[i].length);
2587 pos += parts[i].length;
2588 }
2589 return r;
2590}
2591
2592function checkboxSetUnsetAllHandler(checkboxname) {
2593 return function() {
2594 var checkboxnum = 0;
2595 while (checkboxnum < settings.checkboxes.length &&
2596 settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
2597 checkboxnum++;
2598 }
2599 if (checkboxnum >= settings.checkboxes.length) {
2600 return;
2601 }
2602 var allset = true;
2603 var checkbox;
2604 var row;
2605 for (row of bombody.childNodes) {
2606 checkbox = row.childNodes[checkboxnum + 1].childNodes[0];
2607 if (!checkbox.checked || checkbox.indeterminate) {
2608 allset = false;
2609 break;
2610 }
2611 }
2612 for (row of bombody.childNodes) {
2613 checkbox = row.childNodes[checkboxnum + 1].childNodes[0];
2614 checkbox.checked = !allset;
2615 checkbox.indeterminate = false;
2616 checkbox.onchange();
2617 }
2618 }
2619}
2620
2621function createColumnHeader(name, cls, comparator) {
2622 var th = document.createElement("TH");
2623 th.innerHTML = name;
2624 th.classList.add(cls);
2625 th.style.cursor = "pointer";
2626 var span = document.createElement("SPAN");
2627 span.classList.add("sortmark");
2628 span.classList.add("none");
2629 th.appendChild(span);
2630 th.onclick = function() {
2631 if (currentSortColumn && this !== currentSortColumn) {
2632 // Currently sorted by another column
2633 currentSortColumn.childNodes[1].classList.remove(currentSortOrder);
2634 currentSortColumn.childNodes[1].classList.add("none");
2635 currentSortColumn = null;
2636 currentSortOrder = null;
2637 }
2638 if (currentSortColumn && this === currentSortColumn) {
2639 // Already sorted by this column
2640 if (currentSortOrder == "asc") {
2641 // Sort by this column, descending order
2642 bomSortFunction = function(a, b) {
2643 return -comparator(a, b);
2644 }
2645 currentSortColumn.childNodes[1].classList.remove("asc");
2646 currentSortColumn.childNodes[1].classList.add("desc");
2647 currentSortOrder = "desc";
2648 } else {
2649 // Unsort
2650 bomSortFunction = null;
2651 currentSortColumn.childNodes[1].classList.remove("desc");
2652 currentSortColumn.childNodes[1].classList.add("none");
2653 currentSortColumn = null;
2654 currentSortOrder = null;
2655 }
2656 } else {
2657 // Sort by this column, ascending order
2658 bomSortFunction = comparator;
2659 currentSortColumn = this;
2660 currentSortColumn.childNodes[1].classList.remove("none");
2661 currentSortColumn.childNodes[1].classList.add("asc");
2662 currentSortOrder = "asc";
2663 }
2664 populateBomBody();
2665 }
2666 return th;
2667}
2668
2669function populateBomHeader() {
2670 while (bomhead.firstChild) {
2671 bomhead.removeChild(bomhead.firstChild);
2672 }
2673 var tr = document.createElement("TR");
2674 var th = document.createElement("TH");
2675 th.classList.add("numCol");
2676 tr.appendChild(th);
2677 var checkboxCompareClosure = function(checkbox) {
2678 return (a, b) => {
2679 var stateA = getCheckboxState(checkbox, a[3]);
2680 var stateB = getCheckboxState(checkbox, b[3]);
2681 if (stateA > stateB) return -1;
2682 if (stateA < stateB) return 1;
2683 return 0;
2684 }
2685 }
2686 if (settings.bommode == "netlist") {
2687 th = createColumnHeader("Net name", "bom-netname", (a, b) => {
2688 if (a > b) return -1;
2689 if (a < b) return 1;
2690 return 0;
2691 });
2692 tr.appendChild(th);
2693 } else {
2694 for (var checkbox of settings.checkboxes) {
2695 th = createColumnHeader(
2696 checkbox, "bom-checkbox", checkboxCompareClosure(checkbox));
2697 th.onclick = fancyDblClickHandler(
2698 th, th.onclick.bind(th), checkboxSetUnsetAllHandler(checkbox));
2699 tr.appendChild(th);
2700 }
2701 tr.appendChild(createColumnHeader("References", "References", (a, b) => {
2702 var i = 0;
2703 while (i < a[3].length && i < b[3].length) {
2704 if (a[3][i] != b[3][i]) return a[3][i] > b[3][i] ? 1 : -1;
2705 i++;
2706 }
2707 return a[3].length - b[3].length;
2708 }));
2709 // Extra fields
2710 if (config.extra_fields.length > 0) {
2711 var extraFieldCompareClosure = function(fieldIndex) {
2712 return (a, b) => {
2713 var fa = a[4][fieldIndex];
2714 var fb = b[4][fieldIndex];
2715 if (fa != fb) return fa > fb ? 1 : -1;
2716 else return 0;
2717 }
2718 }
2719 for (var i in config.extra_fields) {
2720 tr.appendChild(createColumnHeader(
2721 config.extra_fields[i], "extra", extraFieldCompareClosure(i)));
2722 }
2723 }
2724 tr.appendChild(createColumnHeader("Value", "Value", (a, b) => {
2725 return valueCompare(a[5], b[5], a[1], b[1]);
2726 }));
2727 tr.appendChild(createColumnHeader("Footprint", "Footprint", (a, b) => {
2728 if (a[2] != b[2]) return a[2] > b[2] ? 1 : -1;
2729 else return 0;
2730 }));
2731 if (settings.bommode == "grouped") {
2732 tr.appendChild(createColumnHeader("Quantity", "Quantity", (a, b) => {
2733 return a[3].length - b[3].length;
2734 }));
2735 }
2736 }
2737 bomhead.appendChild(tr);
2738}
2739
2740function populateBomBody() {
2741 while (bom.firstChild) {
2742 bom.removeChild(bom.firstChild);
2743 }
2744 highlightHandlers = [];
2745 moduleIndexToHandler = {};
2746 netsToHandler = {};
2747 currentHighlightedRowId = null;
2748 var first = true;
2749 if (settings.bommode == "netlist") {
2750 bomtable = pcbdata.nets.slice();
2751 } else {
2752 switch (settings.canvaslayout) {
2753 case 'F':
2754 bomtable = pcbdata.bom.F.slice();
2755 break;
2756 case 'FB':
2757 bomtable = pcbdata.bom.both.slice();
2758 break;
2759 case 'B':
2760 bomtable = pcbdata.bom.B.slice();
2761 break;
2762 }
2763 if (settings.bommode == "ungrouped") {
2764 // expand bom table
2765 expandedTable = []
2766 for (var bomentry of bomtable) {
2767 for (var ref of bomentry[3]) {
2768 expandedTable.push([1, bomentry[1], bomentry[2], [ref], bomentry[4], bomentry[5]]);
2769 }
2770 }
2771 bomtable = expandedTable;
2772 }
2773 }
2774 if (bomSortFunction) {
2775 bomtable = bomtable.sort(bomSortFunction);
2776 }
2777 for (var i in bomtable) {
2778 var bomentry = bomtable[i];
2779 if (filter && !entryMatches(bomentry)) {
2780 continue;
2781 }
2782 var references = null;
2783 var netname = null;
2784 var tr = document.createElement("TR");
2785 var td = document.createElement("TD");
2786 var rownum = +i + 1;
2787 tr.id = "bomrow" + rownum;
2788 td.textContent = rownum;
2789 tr.appendChild(td);
2790 if (settings.bommode == "netlist") {
2791 netname = bomentry;
2792 td = document.createElement("TD");
2793 td.innerHTML = highlightFilter(netname ? netname : "&lt;no net&gt;");
2794 tr.appendChild(td);
2795 } else {
2796 if (reflookup) {
2797 references = findRefInEntry(bomentry);
2798 if (references.length == 0) {
2799 continue;
2800 }
2801 } else {
2802 references = bomentry[3];
2803 }
2804 // Checkboxes
2805 for (var checkbox of settings.checkboxes) {
2806 if (checkbox) {
2807 td = document.createElement("TD");
2808 var input = document.createElement("input");
2809 input.type = "checkbox";
2810 input.onchange = createCheckboxChangeHandler(checkbox, references, tr);
2811 setBomCheckboxState(checkbox, input, references);
2812 if (input.checked && settings.darkenWhenChecked == checkbox) {
2813 tr.classList.add("checked");
2814 }
2815 td.appendChild(input);
2816 tr.appendChild(td);
2817 }
2818 }
2819 // References
2820 td = document.createElement("TD");
2821 td.innerHTML = highlightFilter(references.map(r => r[0]).join(", "));
2822 tr.appendChild(td);
2823 // Extra fields
2824 for (var i in config.extra_fields) {
2825 td = document.createElement("TD");
2826 td.innerHTML = highlightFilter(bomentry[4][i]);
2827 tr.appendChild(td);
2828 }
2829 // Value
2830 td = document.createElement("TD");
2831 td.innerHTML = highlightFilter(bomentry[1]);
2832 tr.appendChild(td);
2833 // Footprint
2834 td = document.createElement("TD");
2835 td.innerHTML = highlightFilter(bomentry[2]);
2836 tr.appendChild(td);
2837 if (settings.bommode == "grouped") {
2838 // Quantity
2839 td = document.createElement("TD");
2840 td.textContent = bomentry[3].length;
2841 tr.appendChild(td);
2842 }
2843 }
2844 bom.appendChild(tr);
2845 var handler = createRowHighlightHandler(tr.id, references, netname);
2846 tr.onmousemove = handler;
2847 highlightHandlers.push({
2848 id: tr.id,
2849 handler: handler,
2850 });
2851 if (references !== null) {
2852 for (var refIndex of references.map(r => r[1])) {
2853 moduleIndexToHandler[refIndex] = handler;
2854 }
2855 }
2856 if (netname !== null) {
2857 netsToHandler[netname] = handler;
2858 }
2859 if ((filter || reflookup) && first) {
2860 handler();
2861 first = false;
2862 }
2863 }
2864 EventHandler.emitEvent(
2865 IBOM_EVENT_TYPES.BOM_BODY_CHANGE_EVENT,
2866 {
2867 filter: filter,
2868 reflookup: reflookup,
2869 checkboxes: settings.checkboxes,
2870 bommode: settings.bommode,
2871 });
2872}
2873
2874function highlightPreviousRow() {
2875 if (!currentHighlightedRowId) {
2876 highlightHandlers[highlightHandlers.length - 1].handler();
2877 } else {
2878 if (highlightHandlers.length > 1 &&
2879 highlightHandlers[0].id == currentHighlightedRowId) {
2880 highlightHandlers[highlightHandlers.length - 1].handler();
2881 } else {
2882 for (var i = 0; i < highlightHandlers.length - 1; i++) {
2883 if (highlightHandlers[i + 1].id == currentHighlightedRowId) {
2884 highlightHandlers[i].handler();
2885 break;
2886 }
2887 }
2888 }
2889 }
2890 smoothScrollToRow(currentHighlightedRowId);
2891}
2892
2893function highlightNextRow() {
2894 if (!currentHighlightedRowId) {
2895 highlightHandlers[0].handler();
2896 } else {
2897 if (highlightHandlers.length > 1 &&
2898 highlightHandlers[highlightHandlers.length - 1].id == currentHighlightedRowId) {
2899 highlightHandlers[0].handler();
2900 } else {
2901 for (var i = 1; i < highlightHandlers.length; i++) {
2902 if (highlightHandlers[i - 1].id == currentHighlightedRowId) {
2903 highlightHandlers[i].handler();
2904 break;
2905 }
2906 }
2907 }
2908 }
2909 smoothScrollToRow(currentHighlightedRowId);
2910}
2911
2912function populateBomTable() {
2913 populateBomHeader();
2914 populateBomBody();
2915}
2916
2917function modulesClicked(moduleIndexes) {
2918 var lastClickedIndex = moduleIndexes.indexOf(lastClicked);
2919 for (var i = 1; i <= moduleIndexes.length; i++) {
2920 var refIndex = moduleIndexes[(lastClickedIndex + i) % moduleIndexes.length];
2921 if (refIndex in moduleIndexToHandler) {
2922 lastClicked = refIndex;
2923 moduleIndexToHandler[refIndex]();
2924 smoothScrollToRow(currentHighlightedRowId);
2925 break;
2926 }
2927 }
2928}
2929
2930function netClicked(net) {
2931 if (net in netsToHandler) {
2932 netsToHandler[net]();
2933 smoothScrollToRow(currentHighlightedRowId);
2934 } else {
2935 clearHighlightedModules();
2936 highlightedNet = net;
2937 drawHighlights();
2938 }
2939}
2940
2941function updateFilter(input) {
2942 filter = input.toLowerCase();
2943 populateBomTable();
2944}
2945
2946function updateRefLookup(input) {
2947 reflookup = input.toLowerCase();
2948 populateBomTable();
2949}
2950
2951function changeCanvasLayout(layout) {
2952 document.getElementById("fl-btn").classList.remove("depressed");
2953 document.getElementById("fb-btn").classList.remove("depressed");
2954 document.getElementById("bl-btn").classList.remove("depressed");
2955 switch (layout) {
2956 case 'F':
2957 document.getElementById("fl-btn").classList.add("depressed");
2958 if (settings.bomlayout != "bom-only") {
2959 canvassplit.collapse(1);
2960 }
2961 break;
2962 case 'B':
2963 document.getElementById("bl-btn").classList.add("depressed");
2964 if (settings.bomlayout != "bom-only") {
2965 canvassplit.collapse(0);
2966 }
2967 break;
2968 default:
2969 document.getElementById("fb-btn").classList.add("depressed");
2970 if (settings.bomlayout != "bom-only") {
2971 canvassplit.setSizes([50, 50]);
2972 }
2973 }
2974 settings.canvaslayout = layout;
2975 writeStorage("canvaslayout", layout);
2976 resizeAll();
2977 changeBomMode(settings.bommode);
2978}
2979
2980function populateMetadata() {
2981 document.getElementById("title").innerHTML = pcbdata.metadata.title;
2982 document.getElementById("revision").innerHTML = "Rev: " + pcbdata.metadata.revision;
2983 document.getElementById("company").innerHTML = pcbdata.metadata.company;
2984 document.getElementById("filedate").innerHTML = pcbdata.metadata.date;
2985 if (pcbdata.metadata.title != "") {
2986 document.title = pcbdata.metadata.title + " BOM";
2987 }
2988 // Calculate board stats
2989 var fp_f = 0, fp_b = 0, pads_f = 0, pads_b = 0, pads_th = 0;
2990 for (var i = 0; i < pcbdata.modules.length; i++) {
2991 if (pcbdata.bom.skipped.includes(i)) continue;
2992 var mod = pcbdata.modules[i];
2993 if (mod.layer == "F") {
2994 fp_f++;
2995 } else {
2996 fp_b++;
2997 }
2998 for (var pad of mod.pads) {
2999 if (pad.type == "th") {
3000 pads_th++;
3001 } else {
3002 if (pad.layers.includes("F")) {
3003 pads_f++;
3004 }
3005 if (pad.layers.includes("B")) {
3006 pads_b++;
3007 }
3008 }
3009 }
3010 }
3011 document.getElementById("stats-components-front").innerHTML = fp_f;
3012 document.getElementById("stats-components-back").innerHTML = fp_b;
3013 document.getElementById("stats-components-total").innerHTML = fp_f + fp_b;
3014 document.getElementById("stats-groups-front").innerHTML = pcbdata.bom.F.length;
3015 document.getElementById("stats-groups-back").innerHTML = pcbdata.bom.B.length;
3016 document.getElementById("stats-groups-total").innerHTML = pcbdata.bom.both.length;
3017 document.getElementById("stats-smd-pads-front").innerHTML = pads_f;
3018 document.getElementById("stats-smd-pads-back").innerHTML = pads_b;
3019 document.getElementById("stats-smd-pads-total").innerHTML = pads_f + pads_b;
3020 document.getElementById("stats-th-pads").innerHTML = pads_th;
3021 // Update version string
3022 document.getElementById("github-link").innerHTML = "InteractiveHtmlBom&nbsp;" +
3023 /^v\d+\.\d+/.exec(pcbdata.ibom_version)[0];
3024}
3025
3026function changeBomLayout(layout) {
3027 document.getElementById("bom-btn").classList.remove("depressed");
3028 document.getElementById("lr-btn").classList.remove("depressed");
3029 document.getElementById("tb-btn").classList.remove("depressed");
3030 switch (layout) {
3031 case 'bom-only':
3032 document.getElementById("bom-btn").classList.add("depressed");
3033 if (bomsplit) {
3034 bomsplit.destroy();
3035 bomsplit = null;
3036 canvassplit.destroy();
3037 canvassplit = null;
3038 }
3039 document.getElementById("frontcanvas").style.display = "none";
3040 document.getElementById("backcanvas").style.display = "none";
3041 document.getElementById("bot").style.height = "";
3042 break;
3043 case 'top-bottom':
3044 document.getElementById("tb-btn").classList.add("depressed");
3045 document.getElementById("frontcanvas").style.display = "";
3046 document.getElementById("backcanvas").style.display = "";
3047 document.getElementById("bot").style.height = "calc(100% - 80px)";
3048 document.getElementById("bomdiv").classList.remove("split-horizontal");
3049 document.getElementById("canvasdiv").classList.remove("split-horizontal");
3050 document.getElementById("frontcanvas").classList.add("split-horizontal");
3051 document.getElementById("backcanvas").classList.add("split-horizontal");
3052 if (bomsplit) {
3053 bomsplit.destroy();
3054 bomsplit = null;
3055 canvassplit.destroy();
3056 canvassplit = null;
3057 }
3058 bomsplit = Split(['#bomdiv', '#canvasdiv'], {
3059 sizes: [50, 50],
3060 onDragEnd: resizeAll,
3061 direction: "vertical",
3062 gutterSize: 5
3063 });
3064 canvassplit = Split(['#frontcanvas', '#backcanvas'], {
3065 sizes: [50, 50],
3066 gutterSize: 5,
3067 onDragEnd: resizeAll
3068 });
3069 break;
3070 case 'left-right':
3071 document.getElementById("lr-btn").classList.add("depressed");
3072 document.getElementById("frontcanvas").style.display = "";
3073 document.getElementById("backcanvas").style.display = "";
3074 document.getElementById("bot").style.height = "calc(100% - 80px)";
3075 document.getElementById("bomdiv").classList.add("split-horizontal");
3076 document.getElementById("canvasdiv").classList.add("split-horizontal");
3077 document.getElementById("frontcanvas").classList.remove("split-horizontal");
3078 document.getElementById("backcanvas").classList.remove("split-horizontal");
3079 if (bomsplit) {
3080 bomsplit.destroy();
3081 bomsplit = null;
3082 canvassplit.destroy();
3083 canvassplit = null;
3084 }
3085 bomsplit = Split(['#bomdiv', '#canvasdiv'], {
3086 sizes: [50, 50],
3087 onDragEnd: resizeAll,
3088 gutterSize: 5
3089 });
3090 canvassplit = Split(['#frontcanvas', '#backcanvas'], {
3091 sizes: [50, 50],
3092 gutterSize: 5,
3093 direction: "vertical",
3094 onDragEnd: resizeAll
3095 });
3096 }
3097 settings.bomlayout = layout;
3098 writeStorage("bomlayout", layout);
3099 changeCanvasLayout(settings.canvaslayout);
3100}
3101
3102function changeBomMode(mode) {
3103 document.getElementById("bom-grouped-btn").classList.remove("depressed");
3104 document.getElementById("bom-ungrouped-btn").classList.remove("depressed");
3105 document.getElementById("bom-netlist-btn").classList.remove("depressed");
3106 switch (mode) {
3107 case 'grouped':
3108 document.getElementById("bom-grouped-btn").classList.add("depressed");
3109 break;
3110 case 'ungrouped':
3111 document.getElementById("bom-ungrouped-btn").classList.add("depressed");
3112 break;
3113 case 'netlist':
3114 document.getElementById("bom-netlist-btn").classList.add("depressed");
3115 }
3116 writeStorage("bommode", mode);
3117 if (mode != settings.bommode) {
3118 settings.bommode = mode;
3119 bomSortFunction = null;
3120 currentSortColumn = null;
3121 currentSortOrder = null;
3122 clearHighlightedModules();
3123 }
3124 populateBomTable();
3125}
3126
3127function focusFilterField() {
3128 focusInputField(document.getElementById("filter"));
3129}
3130
3131function focusRefLookupField() {
3132 focusInputField(document.getElementById("reflookup"));
3133}
3134
3135function toggleBomCheckbox(bomrowid, checkboxnum) {
3136 if (!bomrowid || checkboxnum > settings.checkboxes.length) {
3137 return;
3138 }
3139 var bomrow = document.getElementById(bomrowid);
3140 var checkbox = bomrow.childNodes[checkboxnum].childNodes[0];
3141 checkbox.checked = !checkbox.checked;
3142 checkbox.indeterminate = false;
3143 checkbox.onchange();
3144}
3145
3146function checkBomCheckbox(bomrowid, checkboxname) {
3147 var checkboxnum = 0;
3148 while (checkboxnum < settings.checkboxes.length &&
3149 settings.checkboxes[checkboxnum].toLowerCase() != checkboxname.toLowerCase()) {
3150 checkboxnum++;
3151 }
3152 if (!bomrowid || checkboxnum >= settings.checkboxes.length) {
3153 return;
3154 }
3155 var bomrow = document.getElementById(bomrowid);
3156 var checkbox = bomrow.childNodes[checkboxnum + 1].childNodes[0];
3157 checkbox.checked = true;
3158 checkbox.indeterminate = false;
3159 checkbox.onchange();
3160}
3161
3162function setBomCheckboxes(value) {
3163 writeStorage("bomCheckboxes", value);
3164 settings.checkboxes = value.split(",").filter((e) => e);
3165 prepCheckboxes();
3166 populateBomTable();
3167 populateDarkenWhenCheckedOptions();
3168}
3169
3170function setDarkenWhenChecked(value) {
3171 writeStorage("darkenWhenChecked", value);
3172 settings.darkenWhenChecked = value;
3173 populateBomTable();
3174}
3175
3176function prepCheckboxes() {
3177 var table = document.getElementById("checkbox-stats");
3178 while (table.childElementCount > 1) {
3179 table.removeChild(table.lastChild);
3180 }
3181 if (settings.checkboxes.length) {
3182 table.style.display = "";
3183 } else {
3184 table.style.display = "none";
3185 }
3186 for (var checkbox of settings.checkboxes) {
3187 var tr = document.createElement("TR");
3188 var td = document.createElement("TD");
3189 td.innerHTML = checkbox;
3190 tr.appendChild(td);
3191 td = document.createElement("TD");
3192 td.id = "checkbox-stats-" + checkbox;
3193 var progressbar = document.createElement("div");
3194 progressbar.classList.add("bar");
3195 td.appendChild(progressbar);
3196 var text = document.createElement("div");
3197 text.classList.add("text");
3198 td.appendChild(text);
3199 tr.appendChild(td);
3200 table.appendChild(tr);
3201 updateCheckboxStats(checkbox);
3202 }
3203}
3204
3205function populateDarkenWhenCheckedOptions() {
3206 var container = document.getElementById("darkenWhenCheckedContainer");
3207
3208 if (settings.checkboxes.length == 0) {
3209 container.parentElement.style.display = "none";
3210 return;
3211 }
3212
3213 container.innerHTML = '';
3214 container.parentElement.style.display = "inline-block";
3215
3216 function createOption(name, displayName) {
3217 var id = "darkenWhenChecked-" + name;
3218
3219 var div = document.createElement("div");
3220 div.classList.add("radio-container");
3221
3222 var input = document.createElement("input");
3223 input.type = "radio";
3224 input.name = "darkenWhenChecked";
3225 input.value = name;
3226 input.id = id;
3227 input.onchange = () => setDarkenWhenChecked(name);
3228 div.appendChild(input);
3229
3230 // Preserve the selected element when the checkboxes change
3231 if (name == settings.darkenWhenChecked) {
3232 input.checked = true;
3233 }
3234
3235 var label = document.createElement("label");
3236 label.innerHTML = displayName;
3237 label.htmlFor = id;
3238 div.appendChild(label);
3239
3240 container.appendChild(div);
3241 }
3242 createOption("", "None");
3243 for (var checkbox of settings.checkboxes) {
3244 createOption(checkbox, checkbox);
3245 }
3246}
3247
3248function updateCheckboxStats(checkbox) {
3249 var checked = getStoredCheckboxRefs(checkbox).size;
3250 var total = pcbdata.modules.length - pcbdata.bom.skipped.length;
3251 var percent = checked * 100.0 / total;
3252 var td = document.getElementById("checkbox-stats-" + checkbox);
3253 td.firstChild.style.width = percent + "%";
3254 td.lastChild.innerHTML = checked + "/" + total + " (" + Math.round(percent) + "%)";
3255}
3256
3257document.onkeydown = function(e) {
3258 switch (e.key) {
3259 case "n":
3260 if (document.activeElement.type == "text") {
3261 return;
3262 }
3263 if (currentHighlightedRowId !== null) {
3264 checkBomCheckbox(currentHighlightedRowId, "placed");
3265 highlightNextRow();
3266 e.preventDefault();
3267 }
3268 break;
3269 case "ArrowUp":
3270 highlightPreviousRow();
3271 e.preventDefault();
3272 break;
3273 case "ArrowDown":
3274 highlightNextRow();
3275 e.preventDefault();
3276 break;
3277 default:
3278 break;
3279 }
3280 if (e.altKey) {
3281 switch (e.key) {
3282 case "f":
3283 focusFilterField();
3284 e.preventDefault();
3285 break;
3286 case "r":
3287 focusRefLookupField();
3288 e.preventDefault();
3289 break;
3290 case "z":
3291 changeBomLayout("bom-only");
3292 e.preventDefault();
3293 break;
3294 case "x":
3295 changeBomLayout("left-right");
3296 e.preventDefault();
3297 break;
3298 case "c":
3299 changeBomLayout("top-bottom");
3300 e.preventDefault();
3301 break;
3302 case "v":
3303 changeCanvasLayout("F");
3304 e.preventDefault();
3305 break;
3306 case "b":
3307 changeCanvasLayout("FB");
3308 e.preventDefault();
3309 break;
3310 case "n":
3311 changeCanvasLayout("B");
3312 e.preventDefault();
3313 break;
3314 default:
3315 break;
3316 }
3317 if (e.key >= '1' && e.key <= '9') {
3318 toggleBomCheckbox(currentHighlightedRowId, parseInt(e.key));
3319 }
3320 }
3321}
3322
3323function hideNetlistButton() {
3324 document.getElementById("bom-ungrouped-btn").classList.remove("middle-button");
3325 document.getElementById("bom-ungrouped-btn").classList.add("right-most-button");
3326 document.getElementById("bom-netlist-btn").style.display = "none";
3327}
3328
3329window.onload = function(e) {
3330 initUtils();
3331 initRender();
3332 initStorage();
3333 initDefaults();
3334 cleanGutters();
3335 populateMetadata();
3336 dbgdiv = document.getElementById("dbg");
3337 bom = document.getElementById("bombody");
3338 bomhead = document.getElementById("bomhead");
3339 filter = "";
3340 reflookup = "";
3341 if (!("nets" in pcbdata)) {
3342 hideNetlistButton();
3343 }
3344 initDone = true;
3345 prepCheckboxes();
3346 // Triggers render
3347 changeBomLayout(settings.bomlayout);
3348
3349 // Users may leave fullscreen without touching the checkbox. Uncheck.
3350 document.addEventListener('fullscreenchange', () => {
3351 if (!document.fullscreenElement)
3352 document.getElementById('fullscreenCheckbox').checked = false;
3353 });
3354}
3355
3356window.onresize = resizeAll;
3357window.matchMedia("print").addListener(resizeAll);
3358
3359///////////////////////////////////////////////
3360
3361///////////////////////////////////////////////
3362
3363///////////////////////////////////////////////
3364 </script>
3365</head>
3366
3367<body>
3368
3369<div id="topmostdiv" class="topmostdiv">
3370 <div id="top">
3371 <div style="float: right; height: 100%;">
3372 <div class="hideonprint menu" style="float: right; top: 8px;">
3373 <button class="menubtn"></button>
3374 <div class="menu-content">
3375 <label class="menu-label menu-label-top" style="width: calc(50% - 18px)">
3376 <input id="darkmodeCheckbox" type="checkbox" onchange="setDarkMode(this.checked)">
3377 Dark mode
3378 </label><!-- This comment eats space! All of it!
3379 --><label class="menu-label menu-label-top" style="width: calc(50% - 17px); border-left: 0;">
3380 <input id="fullscreenCheckbox" type="checkbox" onchange="setFullscreen(this.checked)">
3381 Full Screen
3382 </label>
3383 <label class="menu-label" style="width: calc(50% - 18px)">
3384 <input id="fabricationCheckbox" type="checkbox" checked onchange="fabricationVisible(this.checked)">
3385 Fab layer
3386 </label><!-- This comment eats space! All of it!
3387 --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
3388 <input id="silkscreenCheckbox" type="checkbox" checked onchange="silkscreenVisible(this.checked)">
3389 Silkscreen
3390 </label>
3391 <label class="menu-label" style="width: calc(50% - 18px)">
3392 <input id="referencesCheckbox" type="checkbox" checked onchange="referencesVisible(this.checked)">
3393 References
3394 </label><!-- This comment eats space! All of it!
3395 --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
3396 <input id="valuesCheckbox" type="checkbox" checked onchange="valuesVisible(this.checked)">
3397 Values
3398 </label>
3399 <div id="tracksAndZonesCheckboxes">
3400 <label class="menu-label" style="width: calc(50% - 18px)">
3401 <input id="tracksCheckbox" type="checkbox" checked onchange="tracksVisible(this.checked)">
3402 Tracks
3403 </label><!-- This comment eats space! All of it!
3404 --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
3405 <input id="zonesCheckbox" type="checkbox" checked onchange="zonesVisible(this.checked)">
3406 Zones
3407 </label>
3408 </div>
3409 <label class="menu-label" style="width: calc(50% - 18px)">
3410 <input id="padsCheckbox" type="checkbox" checked onchange="padsVisible(this.checked)">
3411 Pads
3412 </label><!-- This comment eats space! All of it!
3413 --><label class="menu-label" style="width: calc(50% - 17px); border-left: 0;">
3414 <input id="dnpOutlineCheckbox" type="checkbox" checked onchange="dnpOutline(this.checked)">
3415 DNP outlined
3416 </label>
3417 <label class="menu-label">
3418 <input id="highlightpin1Checkbox" type="checkbox" onchange="setHighlightPin1(this.checked)">
3419 Highlight first pin
3420 </label>
3421 <label class="menu-label">
3422 <input id="dragCheckbox" type="checkbox" checked onchange="setRedrawOnDrag(this.checked)">
3423 Continuous redraw on drag
3424 </label>
3425 <label class="menu-label">
3426 <span>Board rotation</span>
3427 <span style="float: right"><span id="rotationDegree">0</span>&#176;</span>
3428 <input id="boardRotation" type="range" min="-36" max="36" value="0" class="slider" oninput="setBoardRotation(this.value)">
3429 </label>
3430 <label class="menu-label">
3431 <div style="margin-left: 5px">Bom checkboxes</div>
3432 <input id="bomCheckboxes" class="menu-textbox" type=text
3433 oninput="setBomCheckboxes(this.value)">
3434 </label>
3435 <label class="menu-label">
3436 <div style="margin-left: 5px">Darken when checked</div>
3437 <div id="darkenWhenCheckedContainer"></div>
3438 </label>
3439 <label class="menu-label">
3440 <span class="shameless-plug">
3441 <span>Created using</span>
3442 <a id="github-link" target="blank" href="https://github.com/openscopeproject/InteractiveHtmlBom">InteractiveHtmlBom</a>
3443 </span>
3444 </label>
3445 </div>
3446 </div>
3447 <div class="button-container hideonprint"
3448 style="float: right; position: relative; top: 8px">
3449 <button id="fl-btn" class="left-most-button" onclick="changeCanvasLayout('F')"
3450 title="Front only">F
3451 </button>
3452 <button id="fb-btn" class="middle-button" onclick="changeCanvasLayout('FB')"
3453 title="Front and Back">FB
3454 </button>
3455 <button id="bl-btn" class="right-most-button" onclick="changeCanvasLayout('B')"
3456 title="Back only">B
3457 </button>
3458 </div>
3459 <div class="button-container hideonprint"
3460 style="float: right; position: relative; top: 8px">
3461 <button id="bom-btn" class="left-most-button" onclick="changeBomLayout('bom-only')"
3462 title="BOM only"></button>
3463 <button id="lr-btn" class="middle-button" onclick="changeBomLayout('left-right')"
3464 title="BOM left, drawings right"></button>
3465 <button id="tb-btn" class="right-most-button" onclick="changeBomLayout('top-bottom')"
3466 title="BOM top, drawings bot"></button>
3467 </div>
3468 <div class="button-container hideonprint"
3469 style="float: right; position: relative; top: 8px">
3470 <button id="bom-grouped-btn" class="left-most-button" onclick="changeBomMode('grouped')"
3471 title="Grouped BOM"></button>
3472 <button id="bom-ungrouped-btn" class="middle-button" onclick="changeBomMode('ungrouped')"
3473 title="Ungrouped BOM"></button>
3474 <button id="bom-netlist-btn" class="right-most-button" onclick="changeBomMode('netlist')"
3475 title="Netlist"></button>
3476 </div>
3477 <div class="hideonprint menu" style="float: right; top: 8px;">
3478 <button class="statsbtn"></button>
3479 <div class="menu-content">
3480 <table class="stats">
3481 <tbody>
3482 <tr>
3483 <td width="40%">Board stats</td>
3484 <td>Front</td>
3485 <td>Back</td>
3486 <td>Total</td>
3487 </tr>
3488 <tr>
3489 <td>Components</td>
3490 <td id="stats-components-front">~</td>
3491 <td id="stats-components-back">~</td>
3492 <td id="stats-components-total">~</td>
3493 </tr>
3494 <tr>
3495 <td>Groups</td>
3496 <td id="stats-groups-front">~</td>
3497 <td id="stats-groups-back">~</td>
3498 <td id="stats-groups-total">~</td>
3499 </tr>
3500 <tr>
3501 <td>SMD pads</td>
3502 <td id="stats-smd-pads-front">~</td>
3503 <td id="stats-smd-pads-back">~</td>
3504 <td id="stats-smd-pads-total">~</td>
3505 </tr>
3506 <tr>
3507 <td>TH pads</td>
3508 <td colspan=3 id="stats-th-pads">~</td>
3509 </tr>
3510 </tbody>
3511 </table>
3512 <table class="stats">
3513 <col width="40%"/><col />
3514 <tbody id="checkbox-stats">
3515 <tr>
3516 <td colspan=2 style="border-top: 0">Checkboxes</td>
3517 </tr>
3518 </tbody>
3519 </table>
3520 </div>
3521 </div>
3522 <div class="hideonprint menu" style="float: right; top: 8px;">
3523 <button class="iobtn"></button>
3524 <div class="menu-content">
3525 <div class="menu-label menu-label-top">
3526 <div style="margin-left: 5px;">Save board image</div>
3527 <div class="flexbox">
3528 <input id="render-save-width" class="menu-textbox" type="text" value="1000" placeholder="Width"
3529 style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
3530 <span>X</span>
3531 <input id="render-save-height" class="menu-textbox" type="text" value="1000" placeholder="Height"
3532 style="flex-grow: 1; width: 50px;" oninput="validateSaveImgDimension(this)">
3533 </div>
3534 <label>
3535 <input id="render-save-transparent" type="checkbox">
3536 Transparent background
3537 </label>
3538 <div class="flexbox">
3539 <button class="savebtn" onclick="saveImage('F')">Front</button>
3540 <button class="savebtn" onclick="saveImage('B')">Back</button>
3541 </div>
3542 </div>
3543 <div class="menu-label">
3544 <span style="margin-left: 5px;">Config and checkbox state</span>
3545 <div class="flexbox">
3546 <button class="savebtn" onclick="saveSettings()">Export</button>
3547 <button class="savebtn" onclick="loadSettings()">Import</button>
3548 </div>
3549 </div>
3550 </div>
3551 </div>
3552 </div>
3553 <div id="fileinfodiv" style="overflow: auto;">
3554 <table class="fileinfo">
3555 <tbody>
3556 <tr>
3557 <td id="title" class="title" style="width: 70%">
3558 Title
3559 </td>
3560 <td id="revision" class="title" style="width: 30%">
3561 Revision
3562 </td>
3563 </tr>
3564 <tr>
3565 <td id="company">
3566 Company
3567 </td>
3568 <td id="filedate">
3569 Date
3570 </td>
3571 </tr>
3572 </tbody>
3573 </table>
3574 </div>
3575 </div>
3576 <div id="bot" class="split" style="height: calc(100% - 80px)">
3577 <div id="bomdiv" class="split split-horizontal">
3578 <div style="width: 100%">
3579 <input id="reflookup" class="textbox searchbox reflookup hideonprint" type="text" placeholder="Ref lookup"
3580 oninput="updateRefLookup(this.value)">
3581 <input id="filter" class="textbox searchbox filter hideonprint" type="text" placeholder="Filter"
3582 oninput="updateFilter(this.value)">
3583 <div class="button-container hideonprint" style="float: left; margin: 0;">
3584 <button id="copy" title="Copy bom table to clipboard"
3585 onclick="copyToClipboard()"></button>
3586 </div>
3587 </div>
3588 <div id="dbg"></div>
3589 <table class="bom">
3590 <thead id="bomhead">
3591 </thead>
3592 <tbody id="bombody">
3593 </tbody>
3594 </table>
3595 </div>
3596 <div id="canvasdiv" class="split split-horizontal">
3597 <div id="frontcanvas" class="split" touch-action="none" style="overflow: hidden">
3598 <div style="position: relative; width: 100%; height: 100%;">
3599 <canvas id="F_bg" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
3600 <canvas id="F_fab" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
3601 <canvas id="F_slk" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
3602 <canvas id="F_hl" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
3603 </div>
3604 </div>
3605 <div id="backcanvas" class="split" touch-action="none" style="overflow: hidden">
3606 <div style="position: relative; width: 100%; height: 100%;">
3607 <canvas id="B_bg" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
3608 <canvas id="B_fab" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
3609 <canvas id="B_slk" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
3610 <canvas id="B_hl" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
3611 </div>
3612 </div>
3613 </div>
3614 </div>
3615</div>
3616
3617</body>
3618
3619</html>