1P<!DOCTYPE html> 2<html lang="nl"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Octopus Kermisattractie Simulator - Operator View</title> 7
7<script type="importmap"> 8 { 9 "imports": { 10 "three": "https://unpkg.com/[email protected]/build/three.module.js", 11 "three/examples/jsm/": "https://unpkg.com/[email protected]/examples/jsm/" 12 } 13 } 14 </script>
14 15 <style> 16 * { 17 margin: 0; 18 padding: 0; 19 box-sizing: border-box; 20 } 21 22 body { 23 font-family: 'Arial', sans-serif; 24 background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); 25 overflow: hidden; 26 color: white; 27 } 28 29 #loading-screen { 30 position: fixed; 31 top: 0; 32 left: 0; 33 width: 100vw; 34 height: 100vh; 35 background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%); 36 display: flex; 37 flex-direction: column; 38 justify-content: center; 39 align-items: center; 40 z-index: 9999; 41 transition: opacity 0.5s ease-out; 42 } 43 44 #loading-screen.hidden { 45 opacity: 0; 46 pointer-events: none; 47 } 48 49 .loading-spinner { 50 width: 60px; 51 height: 60px; 52 border: 4px solid rgba(255, 107, 53, 0.2);
53 border-top: 4px solid #ff6b35; 54 border-radius: 50%; 55 animation: spin 1s linear infinite; 56 margin-bottom: 20px; 57 } 58 59 @keyframes spin { 60 0% { transform: rotate(0deg); } 61 100% { transform: rotate(360deg); } 62 } 63 64 .loading-text { 65 color: #ff6b35; 66 font-size: 20px; 67 font-weight: bold; 68 margin-bottom: 10px; 69 } 70 71 .loading-details { 72 color: rgba(255, 255, 255, 0.6); 73 font-size: 14px; 74 } 75 76 #canvas-container { 77 width: 100vw; 78 height: 100vh; 79 position: relative; 80 } 81 82 #control-panel { 83 position: absolute; 84 top: 10px; 85 left: 10px; 86 background: rgba(0, 0, 0, 0.8); 87 border: 2px solid #ff6b35; 88 border-radius: 10px; 89 padding: 12px; 90 min-width: 320px; 91 max-width: 400px; 92 backdrop-filter: blur(10px); 93 box-shadow: 0 8px 32px rgba(255, 107, 53, 0.3); 94 } 95 96 .control-group { 97 margin-bottom: 12px; 98 } 99 100 .control-group h2 { 101 color: #ff6b35; 102 font-size: 14px; 103 margin-bottom: 6px; 104 border-bottom: 1px solid #ff6b35; 105 padding-bottom: 3px; 106 } 107 108 .button-group { 109 display: flex; 110 gap: 10px; 111 flex-wrap: wrap; 112 } 113 114 .button-group.visitor-buttons button { 115 flex: 1 1 calc(33.33% - 10px); 116 min-width: 70px; 117 padding: 6px 8px; 118 font-size: 11px; 119 } 120 121 button { 122 background: linear-gradient(135deg, #ff6b35 0%, #f7931e 100%); 123 color: white; 124 border: none; 125 padding: 8px 12px; 126 border-radius: 6px; 127 cursor: pointer; 128 font-size: 12px; 129 font-weight: bold; 130 transition: all 0.3s; 131 box-shadow: 0 4px 15px rgba(255, 107, 53, 0.4); 132 } 133 134 button:hover { 135 transform: translateY(-2px); 136 box-shadow: 0 6px 20px rgba(255, 107, 53, 0.6); 137 } 138 139 button:active { 140 transform: translateY(0); 141 } 142 143 button.active { 144 background: linear-gradient(135deg, #00d4aa 0%, #00b894 100%); 145 box-shadow: 0 4px 15px rgba(0, 212, 170, 0.4); 146 } 147 148 button.stop { 149 background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%); 150 } 151 152 /* Toggle Switch Style */ 153 .toggle-row { 154 display: flex; 155 gap: 10px; 156 flex-wrap: nowrap; 157 justify-content: space-between; 158 } 159 160 .toggle-switch { 161 position: relative; 162 display: inline-flex; 163 flex-direction: column; 164 align-items: center; 165 width: 118px; 166 gap: 6px; 167 padding: 8px 6px; 168 background: transparent; 169 border: none; 170 cursor: pointer; 171 } 172 .toggle-switch .switch-label { 173 color: #ddd; 174 font-size: 11px; 175 text-align: center; 176 letter-spacing: 0.3px; 177 } 178 .toggle-switch .switch-knob { 179 position: relative; 180 width: 64px; 181 height: 64px; 182 border-radius: 50%; 183 background: radial-gradient(circle at 30% 30%, #666, #222 65%, #0d0d0d 100%); 184 border: 2px solid #444; 185 box-shadow: inset 0 1px 2px rgba(255,255,255,0.08), 0 4px 12px rgba(0,0,0,0.45); 186 transition: transform 0.3s, box-shadow 0.3s; 187 } 188 .toggle-switch .switch-pointer { 189 position: absolute; 190 width: 4px; 191 height: 20px; 192 background: #ff6b35; 193 top: 8px; 194 left: 50%; 195 transform-origin: center 26px; 196 transform: translateX(-50%) rotate(-110deg); 197 border-radius: 2px; 198 box-shadow: 0 0 10px rgba(255,107,53,0.6); 199 } 200 .toggle-switch .switch-ticks { 201 position: absolute; 202 inset: 4px;
203 pointer-events: none; 204 } 205 .toggle-switch .switch-ticks span { 206 position: absolute; 207 width: 6px; 208 height: 2px; 209 background: #777; 210 top: 6px; 211 left: 50%; 212 transform-origin: center 24px; 213 border-radius: 2px; 214 } 215 .switch-state { 216 position: absolute; 217 font-size: 10px; 218 color: #ddd; 219 letter-spacing: 0.4px; 220 text-shadow: 0 1px 2px rgba(0,0,0,0.6); 221 pointer-events: none; 222 } 223 .switch-state.left { 224 left: -6px; 225 top: 65%; 226 transform: translateY(-50%); 227 } 228 .switch-state.right { 229 right: -6px; 230 top: 35%; 231 transform: translateY(-50%); 232 } 233 .switch-state.mid { 234 left: 50%; 235 top: 20%; 236 transform: translate(-50%, -50%); 237 } 238 .toggle-switch.active .switch-knob { 239 box-shadow: inset 0 1px 2px rgba(255,255,255,0.12), 0 4px 14px rgba(255,107,53,0.55); 240 } 241 .toggle-switch.active .switch-pointer { 242 transform: translateX(-50%) rotate(70deg); 243 } 244 245 .slider-control { 246 margin: 8px 0; 247 } 248 .slider-control label { 249 display: block; 250 margin-bottom: 6px; 251 font-size: 11px; 252 color: #ddd; 253 } 254 255 .value-display { display: none; } 256 257 /* Rotary knob style */ 258 .rotary-wrap { 259 display: flex; 260 align-items: center; 261 gap: 10px; 262 } 263 .rotary { 264 width: 72px; 265 height: 72px; 266 border-radius: 50%; 267 background: radial-gradient(circle at 30% 30%, #555, #1a1a1a 60%, #0d0d0d 100%); 268 border: 2px solid #444; 269 position: relative; 270 box-shadow: inset 0 1px 2px rgba(255,255,255,0.08), 0 4px 12px rgba(0,0,0,0.45); 271 cursor: pointer; 272 } 273 .rotary::after { 274 content: ''; 275 position: absolute; 276 inset: 12px; 277 border-radius: 50%; 278 background: radial-gradient(circle at 30% 30%, #777, #222 70%, #111 100%); 279 } 280 .rotary-pointer { 281 position: absolute; 282 width: 4px; 283 height: 24px; 284 background: #ff6b35; 285 top: 6px; 286 left: 50%; 287 transform-origin: center 30px; 288 transform: translateX(-50%) rotate(-135deg); 289 border-radius: 2px; 290 box-shadow: 0 0 10px rgba(255,107,53,0.6); 291 z-index: 2; 292 } 293 294 .knob-grid { 295 display: flex; 296 gap: 10px; 297 flex-wrap: nowrap; 298 justify-content: space-between; 299 } 300 .rotary-block { 301 display: flex; 302 flex-direction: column; 303 align-items: center; 304 width: 118px; 305 gap: 6px; 306 } 307 .step-row { 308 display: flex; 309 gap: 6px; 310 margin-top: 4px; 311 justify-content: center; 312 } 313 .step-dot { 314 width: 14px; 315 height: 14px; 316 border-radius: 50%; 317 border: 1px solid #555; 318 background: linear-gradient(135deg, #2a2a2a 0%, #111 100%); 319 box-shadow: inset 0 1px 2px rgba(255,255,255,0.08), 0 2px 6px rgba(0,0,0,0.4); 320 cursor: pointer; 321 padding: 0; 322 } 323 .step-dot.active { 324 background: linear-gradient(135deg, #ff6b35 0%, #f7931e 100%); 325 border-color: #ff8c4a; 326 box-shadow: 0 2px 8px rgba(255,107,53,0.45); 327 } 328 .rotary-label { 329 font-size: 11px; 330 color: #ddd; 331 letter-spacing: 0.5px; 332 } 333 .rotary-ticks { 334 position: absolute; 335 inset: 4px; 336 pointer-events: none; 337 } 338 .rotary-ticks span { 339 position: absolute; 340 width: 6px; 341 height: 2px; 342 background: #777; 343 top: 6px; 344 left: 50%; 345 transform-origin: center 30px; 346 border-radius: 2px; 347 } 348 349 .value-display { 350 display: inline-block; 351 background: #333; 352 padding: 2px 8px; 353 border-radius: 4px; 354 margin-left: 6px; 355 font-weight: bold; 356 font-size: 11px; 357 color: #ff6b35; 358 } 359 360 #status-panel { 361 position: absolute; 362 top: 10px; 363 right: 10px; 364 background: rgba(0, 0, 0, 0.8); 365 border: 2px solid #00d4aa; 366 border-radius: 10px; 367 padding: 12px; 368 min-width: 200px; 369 backdrop-filter: blur(10px); 370 box-shadow: 0 8px 32px rgba(0, 212, 170, 0.3); 371 } 372 373 .status-item { 374 display: flex; 375 justify-content: space-between; 376 margin: 6px 0; 377 font-size: 11px; 378 } 379 380 .status-label { 381 color: #aaa; 382 } 383 384 .status-value { 385 color: #00d4aa; 386 font-weight: bold; 387 } 388 389 .visitor-queue { 390 margin-top: 10px; 391 padding-top: 10px; 392 border-top: 1px solid #444; 393 } 394 395 .mic-button { 396 width: 100%; 397 padding: 12px; 398 font-size: 14px; 399 background: linear-gradient(135deg, #9b59b6 0%, #8e44ad 100%); 400 box-shadow: 0 4px 15px rgba(155, 89, 182, 0.4); 401 display: flex; 402 align-items: center; 403 justify-content: center; 404 gap: 8px; 405 margin-bottom: 10px; 406 } 407 408 .mic-button:hover { 409 box-shadow: 0 6px 20px rgba(155, 89, 182, 0.6); 410 } 411 412 .mic-button.active { 413 background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%); 414 box-shadow: 0 4px 15px rgba(231, 76, 60, 0.6); 415 animation: pulse-mic 1s infinite; 416 } 417 418 @keyframes pulse-mic { 419 0%, 100% { transform: scale(1); } 420 50% { transform: scale(1.02); } 421 } 422 423 .sound-buttons { 424 display: grid; 425 grid-template-columns: repeat(4, minmax(70px, 1fr)); 426 gap: 8px; 427 } 428 .sound-buttons .small-button { 429 padding: 6px 10px; 430 font-size: 11px; 431 min-width: 70px; 432 } 433 434 .visitor-icon { 435 display: inline-block;
436 width: 20px; 437 height: 20px; 438 margin: 2px; 439 background: #ff6b35; 440 border-radius: 50%; 441 position: relative; 442 animation: pulse 2s infinite; 443 } 444 445 @keyframes pulse { 446 0%, 100% { opacity: 1; } 447 50% { opacity: 0.6; } 448 } 449 450 .emergency-stop { 451 background: #e74c3c !important; 452 font-size: 13px; 453 padding: 10px; 454 margin-top: 10px; 455 animation: emergency-blink 1s infinite; 456 } 457 458 @keyframes emergency-blink { 459 0%, 100% { opacity: 1; } 460 50% { opacity: 0.7; } 461 } 462 463 #info-display { 464 position: absolute; 465 bottom: 10px; 466 left: 10px; 467 background: rgba(0, 0, 0, 0.7); 468 padding: 6px 10px; 469 border-radius: 6px; 470 font-size: 10px; 471 color: #aaa; 472 } 473 </style> 474</head> 475<body> 476 <div id="loading-screen"> 477 <div class="loading-spinner"></div> 478 <div class="loading-text">Octopus wordt geladen...</div> 479 <div class="loading-details" id="loading-details">Initialiseren...</div> 480 </div> 481 <div id="canvas-container"></div> 482 483 <div id="control-panel"> 484 <div class="control-group"> 485 <h2>â¡ HOOFDSCHAKELAAR</h2> 486 <div class="toggle-row" style="margin-bottom: 10px;"> 487 <div id="powerBtn" class="toggle-switch stop"> 488 <div class="switch-state left">UIT</div> 489 <div class="switch-state right">AAN</div> 490 <div class="switch-knob"> 491 <div class="switch-pointer"></div> 492 <div class="switch-ticks"> 493 <span style="transform: translateX(-50%) rotate(-110deg);"></span> 494 <span style="transform: translateX(-50%) rotate(70deg);"></span> 495 </div> 496 </div> 497 <span class="switch-label">Stroom</span> 498 </div> 499 <div id="startBtn" class="toggle-switch"> 500 <div class="switch-state left">STOP</div> 501 <div class="switch-state right">START</div> 502 <div class="switch-knob"> 503 <div class="switch-pointer"></div> 504 <div class="switch-ticks"> 505 <span style="transform: translateX(-50%) rotate(-110deg);"></span> 506 <span style="transform: translateX(-50%) rotate(70deg);"></span> 507 </div> 508 </div> 509 <span class="switch-label">Start</span> 510 </div> 511 </div> 512 </div> 513 514 <div class="control-group"> 515 <h2>ð¥ BEZOEKERS</h2> 516 <div class="button-group visitor-buttons"> 517 <button id="addVisitorBtn">+ Bezoeker</button> 518 <button id="boardBtn">Instappen</button> 519 <button id="exitBtn">Uitstappen</button> 520 </div> 521 </div> 522 523 <div class="control-group"> 524 <h2>ð BEDIENING</h2> 525 <div class="toggle-row"> 526 <div id="restraintBtn" class="toggle-switch"> 527 <div class="switch-state left">LOS</div> 528 <div class="switch-state right">VAST</div> 529 <div class="switch-knob"> 530 <div class="switch-pointer"></div> 531 <div class="switch-ticks"> 532 <span style="transform: translateX(-50%) rotate(-110deg);"></span> 533 <span style="transform: translateX(-50%) rotate(70deg);"></span> 534 </div> 535 </div> 536 <span class="switch-label">Beugels</span> 537 </div> 538 <div id="liftBtn" class="toggle-switch"> 539 <div class="switch-state left">OML</div> 540 <div class="switch-state right">OMH</div> 541 <div class="switch-knob"> 542 <div class="switch-pointer"></div> 543 <div class="switch-ticks">
544 <span style="transform: translateX(-50%) rotate(-110deg);"></span> 545 <span style="transform: translateX(-50%) rotate(70deg);"></span> 546 </div> 547 </div> 548 <span class="switch-label">Armen</span> 549 </div> 550 <div id="gondolaLockBtn" class="toggle-switch active"> 551 <div class="switch-state left">LOS</div> 552 <div class="switch-state right">VAST</div> 553 <div class="switch-knob"> 554 <div class="switch-pointer"></div> 555 <div class="switch-ticks"> 556 <span style="transform: translateX(-50%) rotate(-110deg);"></span> 557 <span style="transform: translateX(-50%) rotate(70deg);"></span> 558 </div> 559 </div> 560 <span class="switch-label">Gondels</span> 561 </div> 562 </div> 563 </div> 564 565 <div class="control-group"> 566 <h2>âï¸ SNELHEID</h2> 567 <div class="knob-grid"> 568 <div class="rotary-block"> 569 <div class="rotary-label">Molen</div> 570 <div class="rotary" id="mainSpeedKnob" data-type="main"> 571 <div class="rotary-pointer"></div> 572 <div class="rotary-ticks"> 573 <span style="transform: translateX(-50%) rotate(-120deg);"></span> 574 <span style="transform: translateX(-50%) rotate(-60deg);"></span> 575 <span style="transform: translateX(-50%) rotate(0deg);"></span> 576 <span style="transform: translateX(-50%) rotate(60deg);"></span> 577 <span style="transform: translateX(-50%) rotate(120deg);"></span> 578 </div> 579 </div> 580 <div class="step-row" aria-label="Molen snelheidsstappen"> 581 <button class="step-dot" data-type="main" data-value="0" aria-label="0%"></button> 582 <button class="step-dot" data-type="main" data-value="25" aria-label="25%"></button> 583 <button class="step-dot" data-type="main" data-value="50" aria-label="50%"></button> 584 <button class="step-dot" data-type="main" data-value="75" aria-label="75%"></button> 585 <button class="step-dot" data-type="main" data-value="100" aria-label="100%"></button> 586 </div> 587 </div> 588 <div class="rotary-block"> 589 <div class="rotary-label">Kruis</div> 590 <div class="rotary" id="crossSpeedKnob" data-type="cross"> 591 <div class="rotary-pointer"></div> 592 <div class="rotary-ticks"> 593 <span style="transform: translateX(-50%) rotate(-120deg);"></span> 594 <span style="transform: translateX(-50%) rotate(-60deg);"></span> 595 <span style="transform: translateX(-50%) rotate(0deg);"></span> 596 <span style="transform: translateX(-50%) rotate(60deg);"></span> 597 <span style="transform: translateX(-50%) rotate(120deg);"></span> 598 </div> 599 </div> 600 <div class="step-row" aria-label="Kruis snelheidsstappen"> 601 <button class="step-dot" data-type="cross" data-value="0" aria-label="0%"></button> 602 <button class="step-dot" data-type="cross" data-value="25" aria-label="25%"></button> 603 <button class="step-dot" data-type="cross" data-value="50" aria-label="50%"></button> 604 <button class="step-dot" data-type="cross" data-value="75" aria-label="75%"></button> 605 <button class="step-dot" data-type="cross" data-value="100" aria-label="100%"></button> 606 </div> 607 </div> 608 <div class="rotary-block"> 609 <div class="rotary-label">Golf</div> 610 <div class="rotary" id="waveSpeedKnob" data-type="wave"> 611 <div class="rotary-pointer"></div> 612 <div class="rotary-ticks">
613 <span style="transform: translateX(-50%) rotate(-120deg);"></span> 614 <span style="transform: translateX(-50%) rotate(0deg);"></span> 615 <span style="transform: translateX(-50%) rotate(120deg);"></span> 616 </div> 617 </div> 618 <div class="step-row" aria-label="Golf snelheidsstappen"> 619 <button class="step-dot" data-type="wave" data-value="0" aria-label="0%"></button> 620 <button class="step-dot" data-type="wave" data-value="25" aria-label="25%"></button> 621 <button class="step-dot" data-type="wave" data-value="40" aria-label="40%"></button> 622 </div> 623 </div> 624 </div> 625 </div> 626 627 <div class="control-group"> 628 <h2>ð¡ VERLICHTING</h2> 629 <div class="toggle-row"> 630 <div id="lightsSwitch" class="toggle-switch"> 631 <div class="switch-state left">UIT</div> 632 <div class="switch-state right">AAN</div> 633 <div class="switch-knob"> 634 <div class="switch-pointer"></div> 635 <div class="switch-ticks"> 636 <span style="transform: translateX(-50%) rotate(-110deg);"></span> 637 <span style="transform: translateX(-50%) rotate(70deg);"></span> 638 </div> 639 </div> 640 <span class="switch-label">Verlichting</span> 641 </div> 642 <div id="lightModeSwitch" class="toggle-switch"> 643 <div class="switch-state left">P</div> 644 <div class="switch-state mid">R</div> 645 <div class="switch-state right">C</div> 646 <div class="switch-knob"> 647 <div class="switch-pointer"></div> 648 <div class="switch-ticks"> 649 <span style="transform: translateX(-50%) rotate(-90deg);"></span> 650 <span style="transform: translateX(-50%) rotate(0deg);"></span> 651 <span style="transform: translateX(-50%) rotate(90deg);"></span> 652 </div> 653 </div> 654 <span class="switch-label">Modus</span> 655 </div> 656 </div> 657 </div> 658 659 <div class="control-group"> 660 <h2>ð· CAMERA VIEW</h2> 661 <div class="button-group" style="gap:10px; flex-wrap:wrap;"> 662 <button id="cameraViewBtn">ð¥ STANDAARD</button> 663 <button id="dayNightBtn">ð NACHT</button> 664 </div> 665 </div> 666 667 <div class="control-group"> 668 <h2>â¡ KWALITEIT</h2> 669 <div class="button-group" style="gap:10px; flex-wrap:wrap;"> 670 <button id="qualityHighBtn" class="active">ð¨ HOOG</button> 671 <button id="qualityMedBtn">âï¸ MIDDEN</button> 672 <button id="qualityLowBtn">â¡ LAAG</button> 673 <button id="qualityUltraLowBtn">ð ULTRA</button> 674 </div> 675 </div> 676 677 <div class="control-group"> 678 <h2>ð SOUND</h2> 679 <button id="micBtn" class="mic-button">ð¤ OMROEP (ingedrukt houden)</button> 680 <div class="sound-buttons"> 681 <button class="small-button" id="sound1Btn">Sound 1</button> 682 <button class="small-button" id="sound2Btn">Sound 2</button> 683 <button class="small-button" id="sound3Btn">Sound 3</button> 684 <button class="small-button" id="sound4Btn">Sound 4</button> 685 <button class="small-button" id="sound5Btn">Sound 5</button> 686 <button class="small-button" id="sound6Btn">Sound 6</button> 687 <button class="small-button" id="sound7Btn">Sound 7</button> 688 <button class="small-button" id="sound8Btn">Sound 8</button> 689 </div> 690 </div> 691 </div> 692 693 <div id="status-panel"> 694 <h2 style="color: #00d4aa; margin-bottom: 15px;">ð STATUS</h2> 695 <div class="status-item">
696 <span class="status-label">Status:</span> 697 <span class="status-value" id="rideStatus">GESTOPT</span> 698 </div> 699 <div class="status-item"> 700 <span class="status-label">RPM:</span> 701 <span class="status-value" id="rpmDisplay">0</span> 702 </div> 703 <div class="status-item"> 704 <span class="status-label">G-kracht (onride):</span> 705 <span class="status-value" id="gForceValue">1.0</span> 706 </div> 707 <div class="status-item"> 708 <span class="status-label">Bezoekers aan boord:</span> 709 <span class="status-value" id="ridersCount">0</span> 710 </div> 711 <div class="status-item"> 712 <span class="status-label">Ritten vandaag:</span> 713 <span class="status-value" id="ridesCount">0</span> 714 </div> 715 <div class="status-item"> 716 <span class="status-label">â±ï¸ Ritduur:</span> 717 <span class="status-value" id="rideTimer" style="color: #ffcc00;">0:00</span> 718 </div> 719 720 <div class="visitor-queue"> 721 <div style="color: #aaa; margin-bottom: 10px;">Wachtrij:</div> 722 <div id="queueDisplay"></div> 723 </div> 724 725 <div style="margin-top: 12px;"> 726 <button id="helpBtn" style="width: 100%; font-size: 11px; padding: 6px 8px;">â Hulp & Instructies</button> 727 </div> 728 </div> 729 730 <div id="info-display"> 731 ð® Camera: Muisbeweging | Zoom: Scrollwiel | Pan: Rechtermuisknop 732 </div> 733 <div id="error-display" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: red; background: rgba(0,0,0,0.8); padding: 20px; display: none; z-index: 9999;"></div> 734 735
735<script> 736 window.onerror = function(message, source, lineno, colno, error) { 737 const errorDisplay = document.getElementById('error-display'); 738 errorDisplay.style.display = 'block'; 739 errorDisplay.innerHTML = `<h3>Error:</h3><p>${message}</p><p>Line: ${lineno}</p>`; 740 console.error(error); 741 }; 742 </script>
742 743
743<script type="module" src="octopus.js"></script>
743 744</body> 745</html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.