ultimatedarktower 2.5.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  var UART_SERVICE_UUID, UART_TX_CHARACTERISTIC_UUID, UART_RX_CHARACTERISTIC_UUID, TOWER_DEVICE_NAME, DIS_SERVICE_UUID, DIS_MANUFACTURER_NAME_UUID, DIS_MODEL_NUMBER_UUID, DIS_SERIAL_NUMBER_UUID, DIS_HARDWARE_REVISION_UUID, DIS_FIRMWARE_REVISION_UUID, DIS_SOFTWARE_REVISION_UUID, DIS_SYSTEM_ID_UUID, DIS_IEEE_REGULATORY_UUID, DIS_PNP_ID_UUID, TOWER_COMMAND_PACKET_SIZE, TOWER_STATE_DATA_SIZE, TOWER_COMMAND_HEADER_SIZE, TOWER_STATE_RESPONSE_MIN_LENGTH, TOWER_STATE_DATA_OFFSET, TOWER_COMMAND_TYPE_TOWER_STATE, DEFAULT_CONNECTION_MONITORING_FREQUENCY, DEFAULT_CONNECTION_MONITORING_TIMEOUT, DEFAULT_BATTERY_HEARTBEAT_TIMEOUT, BATTERY_STATUS_FREQUENCY, DEFAULT_RETRY_SEND_COMMAND_MAX, TOWER_SIDES_COUNT, TOWER_COMMANDS, TC, DRUM_PACKETS, GLYPHS, AUDIO_COMMAND_POS, SKULL_DROP_COUNT_POS, drumPositionCmds, LIGHT_EFFECTS, TOWER_LIGHT_SEQUENCES, TOWER_MESSAGES, VOLTAGE_LEVELS, TOWER_LAYERS, RING_LIGHT_POSITIONS, LEDGE_BASE_LIGHT_POSITIONS, LED_CHANNEL_LOOKUP, LAYER_TO_POSITION, LIGHT_INDEX_TO_DIRECTION, STATE_DATA_LENGTH, TOWER_AUDIO_LIBRARY, VOLUME_DESCRIPTIONS, VOLUME_ICONS;
31
31
  var init_udtConstants = __esm({
32
32
  "src/udtConstants.ts"() {
33
+ "use strict";
33
34
  UART_SERVICE_UUID = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
34
35
  UART_TX_CHARACTERISTIC_UUID = "6e400002-b5a3-f393-e0a9-e50e24dcca9e";
35
36
  UART_RX_CHARACTERISTIC_UUID = "6e400003-b5a3-f393-e0a9-e50e24dcca9e";
@@ -361,160 +362,11 @@ var init_udtConstants = __esm({
361
362
  }
362
363
  });
363
364
 
364
- // src/udtTowerState.ts
365
- var udtTowerState_exports = {};
366
- __export(udtTowerState_exports, {
367
- LAYER_TO_POSITION: () => LAYER_TO_POSITION,
368
- LEDGE_BASE_LIGHT_POSITIONS: () => LEDGE_BASE_LIGHT_POSITIONS,
369
- LED_CHANNEL_LOOKUP: () => LED_CHANNEL_LOOKUP,
370
- LIGHT_INDEX_TO_DIRECTION: () => LIGHT_INDEX_TO_DIRECTION,
371
- RING_LIGHT_POSITIONS: () => RING_LIGHT_POSITIONS,
372
- STATE_DATA_LENGTH: () => STATE_DATA_LENGTH,
373
- TOWER_LAYERS: () => TOWER_LAYERS,
374
- isCalibrated: () => isCalibrated,
375
- rtdt_pack_state: () => rtdt_pack_state,
376
- rtdt_unpack_state: () => rtdt_unpack_state
377
- });
378
- function rtdt_unpack_state(data) {
379
- const state = {
380
- drum: [
381
- { jammed: false, calibrated: false, position: 0, playSound: false, reverse: false },
382
- { jammed: false, calibrated: false, position: 0, playSound: false, reverse: false },
383
- { jammed: false, calibrated: false, position: 0, playSound: false, reverse: false }
384
- ],
385
- layer: [
386
- { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
387
- { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
388
- { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
389
- { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
390
- { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
391
- { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] }
392
- ],
393
- audio: { sample: 0, loop: false, volume: 0 },
394
- beam: { count: 0, fault: false },
395
- led_sequence: 0
396
- };
397
- state.drum[0].jammed = !!(data[0] & 8);
398
- state.drum[0].calibrated = !!(data[0] & 16);
399
- state.drum[1].jammed = !!(data[1] & 1);
400
- state.drum[1].calibrated = !!(data[1] & 2);
401
- state.drum[2].jammed = !!(data[1] & 32);
402
- state.drum[2].calibrated = !!(data[1] & 64);
403
- state.drum[0].position = (data[0] & 6) >> 1;
404
- state.drum[1].position = (data[0] & 192) >> 6;
405
- state.drum[2].position = (data[1] & 24) >> 3;
406
- state.drum[0].playSound = !!(data[0] & 1);
407
- state.drum[1].playSound = !!(data[0] & 32);
408
- state.drum[2].playSound = !!(data[1] & 4);
409
- state.layer[0].light[0].effect = (data[2] & 224) >> 5;
410
- state.layer[0].light[0].loop = !!(data[2] & 16);
411
- state.layer[0].light[1].effect = (data[2] & 14) >> 1;
412
- state.layer[0].light[1].loop = !!(data[2] & 1);
413
- state.layer[0].light[2].effect = (data[3] & 224) >> 5;
414
- state.layer[0].light[2].loop = !!(data[3] & 16);
415
- state.layer[0].light[3].effect = (data[3] & 14) >> 1;
416
- state.layer[0].light[3].loop = !!(data[3] & 1);
417
- state.layer[1].light[0].effect = (data[4] & 224) >> 5;
418
- state.layer[1].light[0].loop = !!(data[4] & 16);
419
- state.layer[1].light[1].effect = (data[4] & 14) >> 1;
420
- state.layer[1].light[1].loop = !!(data[4] & 1);
421
- state.layer[1].light[2].effect = (data[5] & 224) >> 5;
422
- state.layer[1].light[2].loop = !!(data[5] & 16);
423
- state.layer[1].light[3].effect = (data[5] & 14) >> 1;
424
- state.layer[1].light[3].loop = !!(data[5] & 1);
425
- state.layer[2].light[0].effect = (data[6] & 224) >> 5;
426
- state.layer[2].light[0].loop = !!(data[6] & 16);
427
- state.layer[2].light[1].effect = (data[6] & 14) >> 1;
428
- state.layer[2].light[1].loop = !!(data[6] & 1);
429
- state.layer[2].light[2].effect = (data[7] & 224) >> 5;
430
- state.layer[2].light[2].loop = !!(data[7] & 16);
431
- state.layer[2].light[3].effect = (data[7] & 14) >> 1;
432
- state.layer[2].light[3].loop = !!(data[7] & 1);
433
- state.layer[3].light[0].effect = (data[8] & 224) >> 5;
434
- state.layer[3].light[0].loop = !!(data[8] & 16);
435
- state.layer[3].light[1].effect = (data[8] & 14) >> 1;
436
- state.layer[3].light[1].loop = !!(data[8] & 1);
437
- state.layer[3].light[2].effect = (data[9] & 224) >> 5;
438
- state.layer[3].light[2].loop = !!(data[9] & 16);
439
- state.layer[3].light[3].effect = (data[9] & 14) >> 1;
440
- state.layer[3].light[3].loop = !!(data[9] & 1);
441
- state.layer[4].light[0].effect = (data[10] & 224) >> 5;
442
- state.layer[4].light[0].loop = !!(data[10] & 16);
443
- state.layer[4].light[1].effect = (data[10] & 14) >> 1;
444
- state.layer[4].light[1].loop = !!(data[10] & 1);
445
- state.layer[4].light[2].effect = (data[11] & 224) >> 5;
446
- state.layer[4].light[2].loop = !!(data[11] & 16);
447
- state.layer[4].light[3].effect = (data[11] & 14) >> 1;
448
- state.layer[4].light[3].loop = !!(data[11] & 1);
449
- state.layer[5].light[0].effect = (data[12] & 224) >> 5;
450
- state.layer[5].light[0].loop = !!(data[12] & 16);
451
- state.layer[5].light[1].effect = (data[12] & 14) >> 1;
452
- state.layer[5].light[1].loop = !!(data[12] & 1);
453
- state.layer[5].light[2].effect = (data[13] & 224) >> 5;
454
- state.layer[5].light[2].loop = !!(data[13] & 16);
455
- state.layer[5].light[3].effect = (data[13] & 14) >> 1;
456
- state.layer[5].light[3].loop = !!(data[13] & 1);
457
- state.audio.sample = data[14] & 127;
458
- state.audio.loop = !!(data[14] & 128);
459
- state.beam.count = data[15] << 8 | data[16];
460
- state.beam.fault = !!(data[17] & 1);
461
- state.drum[0].reverse = !!(data[17] & 2);
462
- state.drum[1].reverse = !!(data[17] & 4);
463
- state.drum[2].reverse = !!(data[17] & 8);
464
- state.audio.volume = (data[17] & 240) >> 4;
465
- state.led_sequence = data[18];
466
- return state;
467
- }
468
- function rtdt_pack_state(data, len, state) {
469
- if (!data || len < STATE_DATA_LENGTH)
470
- return false;
471
- data.fill(0, 0, STATE_DATA_LENGTH);
472
- data[0] |= (state.drum[0].playSound ? 1 : 0) | (state.drum[0].position & 3) << 1 | (state.drum[0].jammed ? 1 : 0) << 3 | (state.drum[0].calibrated ? 1 : 0) << 4 | (state.drum[1].playSound ? 1 : 0) << 5 | (state.drum[1].position & 3) << 6;
473
- data[1] |= (state.drum[1].jammed ? 1 : 0) | (state.drum[1].calibrated ? 1 : 0) << 1 | (state.drum[2].playSound ? 1 : 0) << 2 | (state.drum[2].position & 3) << 3 | (state.drum[2].jammed ? 1 : 0) << 5 | (state.drum[2].calibrated ? 1 : 0) << 6;
474
- data[2] |= state.layer[0].light[0].effect << 5 | (state.layer[0].light[0].loop ? 1 : 0) << 4;
475
- data[2] |= state.layer[0].light[1].effect << 1 | (state.layer[0].light[1].loop ? 1 : 0);
476
- data[3] |= state.layer[0].light[2].effect << 5 | (state.layer[0].light[2].loop ? 1 : 0) << 4;
477
- data[3] |= state.layer[0].light[3].effect << 1 | (state.layer[0].light[3].loop ? 1 : 0);
478
- data[4] |= state.layer[1].light[0].effect << 5 | (state.layer[1].light[0].loop ? 1 : 0) << 4;
479
- data[4] |= state.layer[1].light[1].effect << 1 | (state.layer[1].light[1].loop ? 1 : 0);
480
- data[5] |= state.layer[1].light[2].effect << 5 | (state.layer[1].light[2].loop ? 1 : 0) << 4;
481
- data[5] |= state.layer[1].light[3].effect << 1 | (state.layer[1].light[3].loop ? 1 : 0);
482
- data[6] |= state.layer[2].light[0].effect << 5 | (state.layer[2].light[0].loop ? 1 : 0) << 4;
483
- data[6] |= state.layer[2].light[1].effect << 1 | (state.layer[2].light[1].loop ? 1 : 0);
484
- data[7] |= state.layer[2].light[2].effect << 5 | (state.layer[2].light[2].loop ? 1 : 0) << 4;
485
- data[7] |= state.layer[2].light[3].effect << 1 | (state.layer[2].light[3].loop ? 1 : 0);
486
- data[8] |= state.layer[3].light[0].effect << 5 | (state.layer[3].light[0].loop ? 1 : 0) << 4;
487
- data[8] |= state.layer[3].light[1].effect << 1 | (state.layer[3].light[1].loop ? 1 : 0);
488
- data[9] |= state.layer[3].light[2].effect << 5 | (state.layer[3].light[2].loop ? 1 : 0) << 4;
489
- data[9] |= state.layer[3].light[3].effect << 1 | (state.layer[3].light[3].loop ? 1 : 0);
490
- data[10] |= state.layer[4].light[0].effect << 5 | (state.layer[4].light[0].loop ? 1 : 0) << 4;
491
- data[10] |= state.layer[4].light[1].effect << 1 | (state.layer[4].light[1].loop ? 1 : 0);
492
- data[11] |= state.layer[4].light[2].effect << 5 | (state.layer[4].light[2].loop ? 1 : 0) << 4;
493
- data[11] |= state.layer[4].light[3].effect << 1 | (state.layer[4].light[3].loop ? 1 : 0);
494
- data[12] |= state.layer[5].light[0].effect << 5 | (state.layer[5].light[0].loop ? 1 : 0) << 4;
495
- data[12] |= state.layer[5].light[1].effect << 1 | (state.layer[5].light[1].loop ? 1 : 0);
496
- data[13] |= state.layer[5].light[2].effect << 5 | (state.layer[5].light[2].loop ? 1 : 0) << 4;
497
- data[13] |= state.layer[5].light[3].effect << 1 | (state.layer[5].light[3].loop ? 1 : 0);
498
- data[14] = state.audio.sample | (state.audio.loop ? 1 : 0) << 7;
499
- data[15] = state.beam.count >> 8;
500
- data[16] = state.beam.count & 255;
501
- data[17] = state.audio.volume << 4 | (state.beam.fault ? 1 : 0) | (state.drum[0].reverse ? 1 : 0) << 1 | (state.drum[1].reverse ? 1 : 0) << 2 | (state.drum[2].reverse ? 1 : 0) << 3;
502
- data[18] = state.led_sequence;
503
- return true;
504
- }
505
- function isCalibrated(state) {
506
- return state.drum.every((drum) => drum.calibrated);
507
- }
508
- var init_udtTowerState = __esm({
509
- "src/udtTowerState.ts"() {
510
- init_udtConstants();
511
- }
512
- });
513
-
514
365
  // src/udtBluetoothAdapter.ts
515
366
  var BluetoothError, BluetoothConnectionError, BluetoothDeviceNotFoundError, BluetoothUserCancelledError, BluetoothTimeoutError;
516
367
  var init_udtBluetoothAdapter = __esm({
517
368
  "src/udtBluetoothAdapter.ts"() {
369
+ "use strict";
518
370
  BluetoothError = class extends Error {
519
371
  constructor(message, originalError) {
520
372
  super(message);
@@ -557,6 +409,7 @@ __export(WebBluetoothAdapter_exports, {
557
409
  var WebBluetoothAdapter;
558
410
  var init_WebBluetoothAdapter = __esm({
559
411
  "src/adapters/WebBluetoothAdapter.ts"() {
412
+ "use strict";
560
413
  init_udtConstants();
561
414
  init_udtBluetoothAdapter();
562
415
  WebBluetoothAdapter = class {
@@ -719,6 +572,7 @@ __export(NodeBluetoothAdapter_exports, {
719
572
  var noble, NodeBluetoothAdapter;
720
573
  var init_NodeBluetoothAdapter = __esm({
721
574
  "src/adapters/NodeBluetoothAdapter.ts"() {
575
+ "use strict";
722
576
  init_udtBluetoothAdapter();
723
577
  init_udtConstants();
724
578
  try {
@@ -1003,7 +857,139 @@ var init_NodeBluetoothAdapter = __esm({
1003
857
 
1004
858
  // src/UltimateDarkTower.ts
1005
859
  init_udtConstants();
1006
- init_udtTowerState();
860
+
861
+ // src/udtTowerState.ts
862
+ init_udtConstants();
863
+ function rtdt_unpack_state(data) {
864
+ const state = {
865
+ drum: [
866
+ { jammed: false, calibrated: false, position: 0, playSound: false, reverse: false },
867
+ { jammed: false, calibrated: false, position: 0, playSound: false, reverse: false },
868
+ { jammed: false, calibrated: false, position: 0, playSound: false, reverse: false }
869
+ ],
870
+ layer: [
871
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
872
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
873
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
874
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
875
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] },
876
+ { light: [{ effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }, { effect: 0, loop: false }] }
877
+ ],
878
+ audio: { sample: 0, loop: false, volume: 0 },
879
+ beam: { count: 0, fault: false },
880
+ led_sequence: 0
881
+ };
882
+ state.drum[0].jammed = !!(data[0] & 8);
883
+ state.drum[0].calibrated = !!(data[0] & 16);
884
+ state.drum[1].jammed = !!(data[1] & 1);
885
+ state.drum[1].calibrated = !!(data[1] & 2);
886
+ state.drum[2].jammed = !!(data[1] & 32);
887
+ state.drum[2].calibrated = !!(data[1] & 64);
888
+ state.drum[0].position = (data[0] & 6) >> 1;
889
+ state.drum[1].position = (data[0] & 192) >> 6;
890
+ state.drum[2].position = (data[1] & 24) >> 3;
891
+ state.drum[0].playSound = !!(data[0] & 1);
892
+ state.drum[1].playSound = !!(data[0] & 32);
893
+ state.drum[2].playSound = !!(data[1] & 4);
894
+ state.layer[0].light[0].effect = (data[2] & 224) >> 5;
895
+ state.layer[0].light[0].loop = !!(data[2] & 16);
896
+ state.layer[0].light[1].effect = (data[2] & 14) >> 1;
897
+ state.layer[0].light[1].loop = !!(data[2] & 1);
898
+ state.layer[0].light[2].effect = (data[3] & 224) >> 5;
899
+ state.layer[0].light[2].loop = !!(data[3] & 16);
900
+ state.layer[0].light[3].effect = (data[3] & 14) >> 1;
901
+ state.layer[0].light[3].loop = !!(data[3] & 1);
902
+ state.layer[1].light[0].effect = (data[4] & 224) >> 5;
903
+ state.layer[1].light[0].loop = !!(data[4] & 16);
904
+ state.layer[1].light[1].effect = (data[4] & 14) >> 1;
905
+ state.layer[1].light[1].loop = !!(data[4] & 1);
906
+ state.layer[1].light[2].effect = (data[5] & 224) >> 5;
907
+ state.layer[1].light[2].loop = !!(data[5] & 16);
908
+ state.layer[1].light[3].effect = (data[5] & 14) >> 1;
909
+ state.layer[1].light[3].loop = !!(data[5] & 1);
910
+ state.layer[2].light[0].effect = (data[6] & 224) >> 5;
911
+ state.layer[2].light[0].loop = !!(data[6] & 16);
912
+ state.layer[2].light[1].effect = (data[6] & 14) >> 1;
913
+ state.layer[2].light[1].loop = !!(data[6] & 1);
914
+ state.layer[2].light[2].effect = (data[7] & 224) >> 5;
915
+ state.layer[2].light[2].loop = !!(data[7] & 16);
916
+ state.layer[2].light[3].effect = (data[7] & 14) >> 1;
917
+ state.layer[2].light[3].loop = !!(data[7] & 1);
918
+ state.layer[3].light[0].effect = (data[8] & 224) >> 5;
919
+ state.layer[3].light[0].loop = !!(data[8] & 16);
920
+ state.layer[3].light[1].effect = (data[8] & 14) >> 1;
921
+ state.layer[3].light[1].loop = !!(data[8] & 1);
922
+ state.layer[3].light[2].effect = (data[9] & 224) >> 5;
923
+ state.layer[3].light[2].loop = !!(data[9] & 16);
924
+ state.layer[3].light[3].effect = (data[9] & 14) >> 1;
925
+ state.layer[3].light[3].loop = !!(data[9] & 1);
926
+ state.layer[4].light[0].effect = (data[10] & 224) >> 5;
927
+ state.layer[4].light[0].loop = !!(data[10] & 16);
928
+ state.layer[4].light[1].effect = (data[10] & 14) >> 1;
929
+ state.layer[4].light[1].loop = !!(data[10] & 1);
930
+ state.layer[4].light[2].effect = (data[11] & 224) >> 5;
931
+ state.layer[4].light[2].loop = !!(data[11] & 16);
932
+ state.layer[4].light[3].effect = (data[11] & 14) >> 1;
933
+ state.layer[4].light[3].loop = !!(data[11] & 1);
934
+ state.layer[5].light[0].effect = (data[12] & 224) >> 5;
935
+ state.layer[5].light[0].loop = !!(data[12] & 16);
936
+ state.layer[5].light[1].effect = (data[12] & 14) >> 1;
937
+ state.layer[5].light[1].loop = !!(data[12] & 1);
938
+ state.layer[5].light[2].effect = (data[13] & 224) >> 5;
939
+ state.layer[5].light[2].loop = !!(data[13] & 16);
940
+ state.layer[5].light[3].effect = (data[13] & 14) >> 1;
941
+ state.layer[5].light[3].loop = !!(data[13] & 1);
942
+ state.audio.sample = data[14] & 127;
943
+ state.audio.loop = !!(data[14] & 128);
944
+ state.beam.count = data[15] << 8 | data[16];
945
+ state.beam.fault = !!(data[17] & 1);
946
+ state.drum[0].reverse = !!(data[17] & 2);
947
+ state.drum[1].reverse = !!(data[17] & 4);
948
+ state.drum[2].reverse = !!(data[17] & 8);
949
+ state.audio.volume = (data[17] & 240) >> 4;
950
+ state.led_sequence = data[18];
951
+ return state;
952
+ }
953
+ function rtdt_pack_state(data, len, state) {
954
+ if (!data || len < STATE_DATA_LENGTH)
955
+ return false;
956
+ data.fill(0, 0, STATE_DATA_LENGTH);
957
+ data[0] |= (state.drum[0].playSound ? 1 : 0) | (state.drum[0].position & 3) << 1 | (state.drum[0].jammed ? 1 : 0) << 3 | (state.drum[0].calibrated ? 1 : 0) << 4 | (state.drum[1].playSound ? 1 : 0) << 5 | (state.drum[1].position & 3) << 6;
958
+ data[1] |= (state.drum[1].jammed ? 1 : 0) | (state.drum[1].calibrated ? 1 : 0) << 1 | (state.drum[2].playSound ? 1 : 0) << 2 | (state.drum[2].position & 3) << 3 | (state.drum[2].jammed ? 1 : 0) << 5 | (state.drum[2].calibrated ? 1 : 0) << 6;
959
+ data[2] |= state.layer[0].light[0].effect << 5 | (state.layer[0].light[0].loop ? 1 : 0) << 4;
960
+ data[2] |= state.layer[0].light[1].effect << 1 | (state.layer[0].light[1].loop ? 1 : 0);
961
+ data[3] |= state.layer[0].light[2].effect << 5 | (state.layer[0].light[2].loop ? 1 : 0) << 4;
962
+ data[3] |= state.layer[0].light[3].effect << 1 | (state.layer[0].light[3].loop ? 1 : 0);
963
+ data[4] |= state.layer[1].light[0].effect << 5 | (state.layer[1].light[0].loop ? 1 : 0) << 4;
964
+ data[4] |= state.layer[1].light[1].effect << 1 | (state.layer[1].light[1].loop ? 1 : 0);
965
+ data[5] |= state.layer[1].light[2].effect << 5 | (state.layer[1].light[2].loop ? 1 : 0) << 4;
966
+ data[5] |= state.layer[1].light[3].effect << 1 | (state.layer[1].light[3].loop ? 1 : 0);
967
+ data[6] |= state.layer[2].light[0].effect << 5 | (state.layer[2].light[0].loop ? 1 : 0) << 4;
968
+ data[6] |= state.layer[2].light[1].effect << 1 | (state.layer[2].light[1].loop ? 1 : 0);
969
+ data[7] |= state.layer[2].light[2].effect << 5 | (state.layer[2].light[2].loop ? 1 : 0) << 4;
970
+ data[7] |= state.layer[2].light[3].effect << 1 | (state.layer[2].light[3].loop ? 1 : 0);
971
+ data[8] |= state.layer[3].light[0].effect << 5 | (state.layer[3].light[0].loop ? 1 : 0) << 4;
972
+ data[8] |= state.layer[3].light[1].effect << 1 | (state.layer[3].light[1].loop ? 1 : 0);
973
+ data[9] |= state.layer[3].light[2].effect << 5 | (state.layer[3].light[2].loop ? 1 : 0) << 4;
974
+ data[9] |= state.layer[3].light[3].effect << 1 | (state.layer[3].light[3].loop ? 1 : 0);
975
+ data[10] |= state.layer[4].light[0].effect << 5 | (state.layer[4].light[0].loop ? 1 : 0) << 4;
976
+ data[10] |= state.layer[4].light[1].effect << 1 | (state.layer[4].light[1].loop ? 1 : 0);
977
+ data[11] |= state.layer[4].light[2].effect << 5 | (state.layer[4].light[2].loop ? 1 : 0) << 4;
978
+ data[11] |= state.layer[4].light[3].effect << 1 | (state.layer[4].light[3].loop ? 1 : 0);
979
+ data[12] |= state.layer[5].light[0].effect << 5 | (state.layer[5].light[0].loop ? 1 : 0) << 4;
980
+ data[12] |= state.layer[5].light[1].effect << 1 | (state.layer[5].light[1].loop ? 1 : 0);
981
+ data[13] |= state.layer[5].light[2].effect << 5 | (state.layer[5].light[2].loop ? 1 : 0) << 4;
982
+ data[13] |= state.layer[5].light[3].effect << 1 | (state.layer[5].light[3].loop ? 1 : 0);
983
+ data[14] = state.audio.sample | (state.audio.loop ? 1 : 0) << 7;
984
+ data[15] = state.beam.count >> 8;
985
+ data[16] = state.beam.count & 255;
986
+ data[17] = state.audio.volume << 4 | (state.beam.fault ? 1 : 0) | (state.drum[0].reverse ? 1 : 0) << 1 | (state.drum[1].reverse ? 1 : 0) << 2 | (state.drum[2].reverse ? 1 : 0) << 3;
987
+ data[18] = state.led_sequence;
988
+ return true;
989
+ }
990
+ function isCalibrated(state) {
991
+ return state.drum.every((drum) => drum.calibrated);
992
+ }
1007
993
 
1008
994
  // src/udtHelpers.ts
1009
995
  init_udtConstants();
@@ -1134,10 +1120,28 @@ var DOMOutput = class {
1134
1120
  write(level, message, timestamp) {
1135
1121
  if (!this.container) return;
1136
1122
  this.allEntries.push({ level, message, timestamp });
1123
+ let removedEntries = false;
1137
1124
  while (this.allEntries.length > this.maxLines) {
1138
1125
  this.allEntries.shift();
1126
+ removedEntries = true;
1127
+ }
1128
+ if (removedEntries) {
1129
+ this.refreshDisplay();
1130
+ return;
1131
+ }
1132
+ const enabledLevels = this.getEnabledLevelsFromCheckboxes();
1133
+ if (enabledLevels.has(level)) {
1134
+ const textFilter = this.getTextFilter();
1135
+ if (!textFilter || message.toLowerCase().includes(textFilter.toLowerCase())) {
1136
+ const timeStr = timestamp.toLocaleTimeString();
1137
+ const logLine = document.createElement("div");
1138
+ logLine.className = `log-line log-${level}`;
1139
+ logLine.textContent = `[${timeStr}] ${message}`;
1140
+ this.container.appendChild(logLine);
1141
+ this.container.scrollTop = this.container.scrollHeight;
1142
+ this.updateBufferSizeDisplay();
1143
+ }
1139
1144
  }
1140
- this.refreshDisplay();
1141
1145
  }
1142
1146
  refreshDisplay() {
1143
1147
  if (!this.container) return;
@@ -1237,6 +1241,9 @@ var Logger = class _Logger {
1237
1241
  addOutput(output) {
1238
1242
  this.outputs.push(output);
1239
1243
  }
1244
+ clearOutputs() {
1245
+ this.outputs = [];
1246
+ }
1240
1247
  setMinLevel(level) {
1241
1248
  this.enabledLevels = /* @__PURE__ */ new Set([level]);
1242
1249
  }
@@ -1403,7 +1410,7 @@ var TowerResponseProcessor = class {
1403
1410
  const cmdKey = cmdKeys.find((key) => TOWER_MESSAGES[key].value === cmdValue);
1404
1411
  if (!cmdKey) {
1405
1412
  logger.warn(`Unknown command received from tower: ${cmdValue} (0x${cmdValue.toString(16)})`, "TowerResponseProcessor");
1406
- return { cmdKey: void 0, command: { name: "Unknown Command", value: cmdValue } };
1413
+ return { cmdKey: void 0, command: { name: "Unknown Command", value: cmdValue, critical: false } };
1407
1414
  }
1408
1415
  const command = TOWER_MESSAGES[cmdKey];
1409
1416
  return { cmdKey, command };
@@ -1446,12 +1453,11 @@ var TowerResponseProcessor = class {
1446
1453
  * @returns {boolean} Whether this response should be logged
1447
1454
  */
1448
1455
  shouldLogResponse(cmdKey, logConfig) {
1449
- const logAll = logConfig["LOG_ALL"];
1450
- let canLogThisResponse = logConfig[cmdKey] || logAll;
1451
1456
  if (!cmdKey) {
1452
- canLogThisResponse = true;
1457
+ return true;
1453
1458
  }
1454
- return canLogThisResponse;
1459
+ const logAll = logConfig["LOG_ALL"];
1460
+ return logConfig[cmdKey] || logAll;
1455
1461
  }
1456
1462
  /**
1457
1463
  * Checks if a command is a battery response type.
@@ -1471,9 +1477,6 @@ var TowerResponseProcessor = class {
1471
1477
  }
1472
1478
  };
1473
1479
 
1474
- // src/udtBleConnection.ts
1475
- init_udtTowerState();
1476
-
1477
1480
  // src/udtBluetoothAdapterFactory.ts
1478
1481
  var BluetoothPlatform = /* @__PURE__ */ ((BluetoothPlatform3) => {
1479
1482
  BluetoothPlatform3["WEB"] = "web";
@@ -1549,11 +1552,11 @@ var UdtBleConnection = class {
1549
1552
  // When true, verifies connection before triggering disconnection on heartbeat timeout
1550
1553
  // Tower state
1551
1554
  this.towerSkullDropCount = -1;
1552
- this.lastBatteryNotification = 0;
1555
+ this.lastBatteryLog = 0;
1553
1556
  this.lastBatteryPercentage = "";
1554
- this.batteryNotifyFrequency = 15 * 1e3;
1555
- this.batteryNotifyOnValueChangeOnly = false;
1556
- this.batteryNotifyEnabled = true;
1557
+ this.batteryLogFrequency = 15 * 1e3;
1558
+ this.batteryLogOnChangeOnly = false;
1559
+ this.batteryLogEnabled = true;
1557
1560
  // Device information
1558
1561
  this.deviceInformation = {};
1559
1562
  // Logging configuration
@@ -1632,7 +1635,7 @@ var UdtBleConnection = class {
1632
1635
  this.lastSuccessfulCommand = Date.now();
1633
1636
  const { cmdKey } = this.responseProcessor.getTowerCommand(receivedData[0]);
1634
1637
  const isBattery = this.responseProcessor.isBatteryResponse(cmdKey);
1635
- const shouldLogCommand = this.logTowerResponses && this.responseProcessor.shouldLogResponse(cmdKey, this.logTowerResponseConfig) && (!isBattery || this.batteryNotifyEnabled);
1638
+ const shouldLogCommand = this.logTowerResponses && this.responseProcessor.shouldLogResponse(cmdKey, this.logTowerResponseConfig) && !isBattery;
1636
1639
  if (shouldLogCommand) {
1637
1640
  this.logger.info(`${cmdKey}`, "[UDT][BLE][RCVD]");
1638
1641
  }
@@ -1647,14 +1650,14 @@ var UdtBleConnection = class {
1647
1650
  const millivolts = getMilliVoltsFromTowerResponse(receivedData);
1648
1651
  const batteryPercentage = milliVoltsToPercentage(millivolts);
1649
1652
  const didBatteryLevelChange = this.lastBatteryPercentage !== "" && this.lastBatteryPercentage !== batteryPercentage;
1650
- const batteryNotifyFrequencyPassed = Date.now() - this.lastBatteryNotification >= this.batteryNotifyFrequency;
1651
- const shouldNotify = this.batteryNotifyEnabled && (this.batteryNotifyOnValueChangeOnly ? didBatteryLevelChange || this.lastBatteryPercentage === "" : batteryNotifyFrequencyPassed);
1652
- if (shouldNotify) {
1653
+ const batteryLogFrequencyPassed = Date.now() - this.lastBatteryLog >= this.batteryLogFrequency;
1654
+ const shouldLog = this.batteryLogEnabled && (this.batteryLogOnChangeOnly ? didBatteryLevelChange || this.lastBatteryPercentage === "" : batteryLogFrequencyPassed);
1655
+ if (shouldLog) {
1653
1656
  this.logger.info(`${this.responseProcessor.commandToString(receivedData).join(" ")}`, "[UDT][BLE]");
1654
- this.lastBatteryNotification = Date.now();
1657
+ this.lastBatteryLog = Date.now();
1655
1658
  this.lastBatteryPercentage = batteryPercentage;
1656
- this.callbacks.onBatteryLevelNotify(millivolts);
1657
1659
  }
1660
+ this.callbacks.onBatteryLevelNotify(millivolts);
1658
1661
  } else {
1659
1662
  if (this.callbacks.onTowerResponse) {
1660
1663
  this.callbacks.onTowerResponse(receivedData);
@@ -1844,7 +1847,6 @@ var UdtBleConnection = class {
1844
1847
 
1845
1848
  // src/udtCommandFactory.ts
1846
1849
  init_udtConstants();
1847
- init_udtTowerState();
1848
1850
  var UdtCommandFactory = class {
1849
1851
  /**
1850
1852
  * Creates a rotation command packet for positioning tower drums.
@@ -1866,8 +1868,7 @@ var UdtCommandFactory = class {
1866
1868
  */
1867
1869
  createSoundCommand(soundIndex) {
1868
1870
  const soundCommand = new Uint8Array(TOWER_COMMAND_PACKET_SIZE);
1869
- const sound = Number("0x" + Number(soundIndex).toString(16).padStart(2, "0"));
1870
- soundCommand[AUDIO_COMMAND_POS] = sound;
1871
+ soundCommand[AUDIO_COMMAND_POS] = soundIndex & 255;
1871
1872
  return soundCommand;
1872
1873
  }
1873
1874
  /**
@@ -1887,7 +1888,7 @@ var UdtCommandFactory = class {
1887
1888
  * @returns 20-byte command packet (command type + 19-byte state data)
1888
1889
  */
1889
1890
  createStatefulCommand(currentState, modifications) {
1890
- const newState = currentState ? { ...currentState } : this.createEmptyTowerState();
1891
+ const newState = currentState ? this.deepCopyTowerState(currentState) : this.createEmptyTowerState();
1891
1892
  if (modifications.drum) {
1892
1893
  modifications.drum.forEach((drum, index) => {
1893
1894
  if (drum && newState.drum[index]) {
@@ -1929,17 +1930,10 @@ var UdtCommandFactory = class {
1929
1930
  * @returns 20-byte command packet
1930
1931
  */
1931
1932
  createStatefulLEDCommand(currentState, layerIndex, lightIndex, effect, loop = false) {
1932
- const modifications = {};
1933
- if (!modifications.layer) {
1934
- modifications.layer = [];
1935
- }
1936
- if (!modifications.layer[layerIndex]) {
1937
- modifications.layer[layerIndex] = { light: [] };
1938
- }
1939
- if (!modifications.layer[layerIndex].light) {
1940
- modifications.layer[layerIndex].light = [];
1941
- }
1942
- modifications.layer[layerIndex].light[lightIndex] = { effect, loop };
1933
+ const layer = [];
1934
+ layer[layerIndex] = { light: [] };
1935
+ layer[layerIndex].light[lightIndex] = { effect, loop };
1936
+ const modifications = { layer };
1943
1937
  modifications.audio = { sample: 0, loop: false, volume: 0 };
1944
1938
  return this.createStatefulCommand(currentState, modifications);
1945
1939
  }
@@ -2033,17 +2027,15 @@ var UdtCommandFactory = class {
2033
2027
  * @returns 20-byte command packet
2034
2028
  */
2035
2029
  createStatefulDrumCommand(currentState, drumIndex, position, playSound = false) {
2036
- const modifications = {};
2037
- if (!modifications.drum) {
2038
- modifications.drum = [];
2039
- }
2040
- modifications.drum[drumIndex] = {
2030
+ const drum = [];
2031
+ drum[drumIndex] = {
2041
2032
  jammed: false,
2042
2033
  calibrated: true,
2043
2034
  position,
2044
2035
  playSound,
2045
2036
  reverse: false
2046
2037
  };
2038
+ const modifications = { drum };
2047
2039
  modifications.audio = { sample: 0, loop: false, volume: 0 };
2048
2040
  return this.createStatefulCommand(currentState, modifications);
2049
2041
  }
@@ -2087,6 +2079,22 @@ var UdtCommandFactory = class {
2087
2079
  led_sequence: 0
2088
2080
  };
2089
2081
  }
2082
+ /**
2083
+ * Creates a deep copy of a TowerState to avoid mutating the original.
2084
+ * @param state - The tower state to copy
2085
+ * @returns A new TowerState with all nested objects copied
2086
+ */
2087
+ deepCopyTowerState(state) {
2088
+ return {
2089
+ drum: state.drum.map((d) => ({ ...d })),
2090
+ layer: state.layer.map((l) => ({
2091
+ light: l.light.map((lt) => ({ ...lt }))
2092
+ })),
2093
+ audio: { ...state.audio },
2094
+ beam: { ...state.beam },
2095
+ led_sequence: state.led_sequence
2096
+ };
2097
+ }
2090
2098
  //#endregion
2091
2099
  };
2092
2100
 
@@ -2170,9 +2178,10 @@ var CommandQueue = class {
2170
2178
  if (this.currentCommand) {
2171
2179
  const { description, id } = this.currentCommand;
2172
2180
  this.logger.warn(`Command timeout after ${this.timeoutMs}ms: ${description || id}`, "[UDT]");
2173
- this.currentCommand.resolve();
2181
+ const reject = this.currentCommand.reject;
2174
2182
  this.currentCommand = null;
2175
2183
  this.isProcessing = false;
2184
+ reject(new Error(`Command timeout after ${this.timeoutMs}ms: ${description || id}`));
2176
2185
  this.processNext();
2177
2186
  }
2178
2187
  }
@@ -2254,7 +2263,7 @@ var UdtTowerCommands = class {
2254
2263
  this.deps.bleConnection.lastSuccessfulCommand = Date.now();
2255
2264
  } catch (error) {
2256
2265
  this.deps.logger.error(`command send error: ${error}`, "[UDT][CMD]");
2257
- const errorMsg = error?.message ?? new String(error);
2266
+ const errorMsg = error?.message ?? String(error);
2258
2267
  const wasCancelled = errorMsg.includes("User cancelled");
2259
2268
  const maxRetriesReached = this.deps.retrySendCommandCount.value >= this.deps.retrySendCommandMax;
2260
2269
  const isDisconnected = errorMsg.includes("Cannot read properties of null") || errorMsg.includes("GATT Server is disconnected") || errorMsg.includes("Device is not connected") || errorMsg.includes("BluetoothConnectionError") || !this.deps.bleConnection.isConnected;
@@ -2266,9 +2275,9 @@ var UdtTowerCommands = class {
2266
2275
  if (!maxRetriesReached && this.deps.bleConnection.isConnected && !wasCancelled) {
2267
2276
  this.deps.logger.info(`retrying tower command attempt ${this.deps.retrySendCommandCount.value + 1}`, "[UDT][CMD]");
2268
2277
  this.deps.retrySendCommandCount.value++;
2269
- setTimeout(() => {
2270
- this.sendTowerCommandDirect(command);
2271
- }, 250 * this.deps.retrySendCommandCount.value);
2278
+ const delay = 250 * this.deps.retrySendCommandCount.value;
2279
+ await new Promise((resolve) => setTimeout(resolve, delay));
2280
+ return await this.sendTowerCommandDirect(command);
2272
2281
  } else {
2273
2282
  this.deps.retrySendCommandCount.value = 0;
2274
2283
  }
@@ -2316,9 +2325,13 @@ var UdtTowerCommands = class {
2316
2325
  this.deps.logDetail && this.deps.logger.debug(`Light Parameter ${JSON.stringify(lights)}`, "[UDT][CMD]");
2317
2326
  this.deps.logger.info("Sending light commands", "[UDT][CMD]");
2318
2327
  const layerCommands = this.mapLightsToLayerCommands(lights);
2319
- for (const { layerIndex, lightIndex, effect } of layerCommands) {
2320
- await this.setLEDStateful(layerIndex, lightIndex, effect);
2328
+ const currentState = this.deps.getCurrentTowerState();
2329
+ for (const { layerIndex, lightIndex, effect, loop } of layerCommands) {
2330
+ currentState.layer[layerIndex].light[lightIndex] = { effect, loop };
2321
2331
  }
2332
+ const command = this.deps.commandFactory.createStatefulCommand(currentState, {});
2333
+ this.deps.setTowerState(currentState, "lights");
2334
+ await this.sendTowerCommand(command, "lights");
2322
2335
  }
2323
2336
  /**
2324
2337
  * Maps the Lights object to layer/light index commands for setLEDStateful.
@@ -2332,7 +2345,7 @@ var UdtTowerCommands = class {
2332
2345
  const layerIndex = this.getTowerLayerForLevel(doorwayLight.level);
2333
2346
  const lightIndex = this.getLightIndexForSide(doorwayLight.position);
2334
2347
  const effect = LIGHT_EFFECTS[doorwayLight.style] || LIGHT_EFFECTS.off;
2335
- commands.push({ layerIndex, lightIndex, effect, loop: true });
2348
+ commands.push({ layerIndex, lightIndex, effect, loop: effect !== LIGHT_EFFECTS.off });
2336
2349
  }
2337
2350
  }
2338
2351
  if (lights.ledge) {
@@ -2340,7 +2353,7 @@ var UdtTowerCommands = class {
2340
2353
  const layerIndex = TOWER_LAYERS.LEDGE;
2341
2354
  const lightIndex = this.getLedgeLightIndexForSide(ledgeLight.position);
2342
2355
  const effect = LIGHT_EFFECTS[ledgeLight.style] || LIGHT_EFFECTS.off;
2343
- commands.push({ layerIndex, lightIndex, effect, loop: false });
2356
+ commands.push({ layerIndex, lightIndex, effect, loop: effect !== LIGHT_EFFECTS.off });
2344
2357
  }
2345
2358
  }
2346
2359
  if (lights.base) {
@@ -2348,7 +2361,7 @@ var UdtTowerCommands = class {
2348
2361
  const layerIndex = baseLight.position.level === "top" || baseLight.position.level === "b" ? TOWER_LAYERS.BASE2 : TOWER_LAYERS.BASE1;
2349
2362
  const lightIndex = this.getBaseLightIndexForSide(baseLight.position.side);
2350
2363
  const effect = LIGHT_EFFECTS[baseLight.style] || LIGHT_EFFECTS.off;
2351
- commands.push({ layerIndex, lightIndex, effect, loop: false });
2364
+ commands.push({ layerIndex, lightIndex, effect, loop: effect !== LIGHT_EFFECTS.off });
2352
2365
  }
2353
2366
  }
2354
2367
  return commands;
@@ -2554,8 +2567,7 @@ var UdtTowerCommands = class {
2554
2567
  };
2555
2568
  const command = this.deps.commandFactory.createStatefulCommand(currentState, modifications);
2556
2569
  await this.sendTowerCommand(command, "resetTowerSkullCount");
2557
- const updatedState = { ...currentState };
2558
- updatedState.beam.count = 0;
2570
+ const updatedState = { ...currentState, beam: { ...currentState.beam, count: 0 } };
2559
2571
  this.deps.setTowerState(updatedState, "resetTowerSkullCount");
2560
2572
  }
2561
2573
  /**
@@ -2985,23 +2997,23 @@ var UltimateDarkTower = class {
2985
2997
  return this.previousBatteryPercentage;
2986
2998
  }
2987
2999
  // Getter/setter methods for connection configuration
2988
- get batteryNotifyFrequency() {
2989
- return this.bleConnection.batteryNotifyFrequency;
3000
+ get batteryLogFrequency() {
3001
+ return this.bleConnection.batteryLogFrequency;
2990
3002
  }
2991
- set batteryNotifyFrequency(value) {
2992
- this.bleConnection.batteryNotifyFrequency = value;
3003
+ set batteryLogFrequency(value) {
3004
+ this.bleConnection.batteryLogFrequency = value;
2993
3005
  }
2994
- get batteryNotifyOnValueChangeOnly() {
2995
- return this.bleConnection.batteryNotifyOnValueChangeOnly;
3006
+ get batteryLogOnChangeOnly() {
3007
+ return this.bleConnection.batteryLogOnChangeOnly;
2996
3008
  }
2997
- set batteryNotifyOnValueChangeOnly(value) {
2998
- this.bleConnection.batteryNotifyOnValueChangeOnly = value;
3009
+ set batteryLogOnChangeOnly(value) {
3010
+ this.bleConnection.batteryLogOnChangeOnly = value;
2999
3011
  }
3000
- get batteryNotifyEnabled() {
3001
- return this.bleConnection.batteryNotifyEnabled;
3012
+ get batteryLogEnabled() {
3013
+ return this.bleConnection.batteryLogEnabled;
3002
3014
  }
3003
- set batteryNotifyEnabled(value) {
3004
- this.bleConnection.batteryNotifyEnabled = value;
3015
+ set batteryLogEnabled(value) {
3016
+ this.bleConnection.batteryLogEnabled = value;
3005
3017
  }
3006
3018
  get logTowerResponses() {
3007
3019
  return this.bleConnection.logTowerResponses;
@@ -3185,11 +3197,10 @@ var UltimateDarkTower = class {
3185
3197
  * @returns Promise that resolves when the command is sent
3186
3198
  */
3187
3199
  async sendTowerState(towerState) {
3188
- const { rtdt_pack_state: rtdt_pack_state2 } = await Promise.resolve().then(() => (init_udtTowerState(), udtTowerState_exports));
3189
3200
  const stateToSend = { ...towerState };
3190
3201
  stateToSend.audio = { sample: 0, loop: false, volume: 0 };
3191
3202
  const stateData = new Uint8Array(TOWER_STATE_DATA_SIZE);
3192
- const success = rtdt_pack_state2(stateData, TOWER_STATE_DATA_SIZE, stateToSend);
3203
+ const success = rtdt_pack_state(stateData, TOWER_STATE_DATA_SIZE, stateToSend);
3193
3204
  if (!success) {
3194
3205
  throw new Error("Failed to pack tower state data");
3195
3206
  }
@@ -3217,11 +3228,9 @@ var UltimateDarkTower = class {
3217
3228
  * @param stateData - The 19-byte state data from tower response
3218
3229
  */
3219
3230
  updateTowerStateFromResponse(stateData) {
3220
- Promise.resolve().then(() => (init_udtTowerState(), udtTowerState_exports)).then(({ rtdt_unpack_state: rtdt_unpack_state2 }) => {
3221
- const newState = rtdt_unpack_state2(stateData);
3222
- newState.audio = { sample: 0, loop: false, volume: this.currentTowerState.audio.volume };
3223
- this.setTowerState(newState, "tower response");
3224
- });
3231
+ const newState = rtdt_unpack_state(stateData);
3232
+ newState.audio = { sample: 0, loop: false, volume: this.currentTowerState.audio.volume };
3233
+ this.setTowerState(newState, "tower response");
3225
3234
  }
3226
3235
  //#endregion
3227
3236
  /**
@@ -3449,7 +3458,7 @@ var UltimateDarkTower = class {
3449
3458
  * @param {LogOutput[]} outputs - Array of log outputs to use (e.g., ConsoleOutput, DOMOutput)
3450
3459
  */
3451
3460
  setLoggerOutputs(outputs) {
3452
- this.logger.outputs = [];
3461
+ this.logger.clearOutputs();
3453
3462
  outputs.forEach((output) => this.logger.addOutput(output));
3454
3463
  }
3455
3464
  /**
@@ -3547,7 +3556,6 @@ var UltimateDarkTower_default = UltimateDarkTower;
3547
3556
  // src/index.ts
3548
3557
  init_udtConstants();
3549
3558
  init_udtBluetoothAdapter();
3550
- init_udtTowerState();
3551
3559
  var index_default = UltimateDarkTower_default;
3552
3560
  export {
3553
3561
  AUDIO_COMMAND_POS,