@c15t/dev-tools 2.0.0-rc.3 → 2.0.0-rc.4

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/components/panel.d.ts.map +1 -1
  3. package/dist/components/tabs.d.ts.map +1 -1
  4. package/dist/components/ui.d.ts +8 -0
  5. package/dist/components/ui.d.ts.map +1 -1
  6. package/dist/core/debug-bundle.d.ts +14 -0
  7. package/dist/core/debug-bundle.d.ts.map +1 -0
  8. package/dist/core/devtools.d.ts.map +1 -1
  9. package/dist/core/panel-renderer.d.ts +5 -0
  10. package/dist/core/panel-renderer.d.ts.map +1 -1
  11. package/dist/core/state-manager.d.ts.map +1 -1
  12. package/dist/core/store-connector.d.ts +16 -0
  13. package/dist/core/store-connector.d.ts.map +1 -1
  14. package/dist/core/store-instrumentation.d.ts +13 -0
  15. package/dist/core/store-instrumentation.d.ts.map +1 -0
  16. package/dist/index.cjs +1681 -905
  17. package/dist/index.js +1680 -904
  18. package/dist/panels/actions.d.ts +1 -0
  19. package/dist/panels/actions.d.ts.map +1 -1
  20. package/dist/panels/consents.d.ts.map +1 -1
  21. package/dist/panels/events.d.ts.map +1 -1
  22. package/dist/panels/iab.d.ts.map +1 -1
  23. package/dist/panels/location.d.ts.map +1 -1
  24. package/dist/panels/scripts.d.ts.map +1 -1
  25. package/dist/react.cjs +1610 -748
  26. package/dist/react.js +1610 -748
  27. package/dist/tanstack.cjs +1565 -532
  28. package/dist/tanstack.js +1565 -532
  29. package/dist/utils/preference-trigger.d.ts.map +1 -1
  30. package/dist/version.d.ts +1 -1
  31. package/package.json +9 -9
  32. package/tsconfig.json +9 -1
  33. package/dist/__tests__/components/ui.test.d.ts +0 -2
  34. package/dist/__tests__/components/ui.test.d.ts.map +0 -1
  35. package/dist/__tests__/core/override-storage.test.d.ts +0 -2
  36. package/dist/__tests__/core/override-storage.test.d.ts.map +0 -1
  37. package/dist/__tests__/core/renderer.test.d.ts +0 -2
  38. package/dist/__tests__/core/renderer.test.d.ts.map +0 -1
  39. package/dist/__tests__/core/reset-consents.test.d.ts +0 -2
  40. package/dist/__tests__/core/reset-consents.test.d.ts.map +0 -1
  41. package/dist/__tests__/core/state-manager.test.d.ts +0 -2
  42. package/dist/__tests__/core/state-manager.test.d.ts.map +0 -1
  43. package/dist/__tests__/core/store-connector.test.d.ts +0 -2
  44. package/dist/__tests__/core/store-connector.test.d.ts.map +0 -1
  45. package/dist/__tests__/panels/dom-scanner.test.d.ts +0 -2
  46. package/dist/__tests__/panels/dom-scanner.test.d.ts.map +0 -1
  47. package/dist/__tests__/panels/events.test.d.ts +0 -2
  48. package/dist/__tests__/panels/events.test.d.ts.map +0 -1
  49. package/dist/__tests__/panels/iab.test.d.ts +0 -2
  50. package/dist/__tests__/panels/iab.test.d.ts.map +0 -1
  51. package/dist/__tests__/panels/scripts.test.d.ts +0 -2
  52. package/dist/__tests__/panels/scripts.test.d.ts.map +0 -1
  53. package/dist/__tests__/utils/preference-trigger.test.d.ts +0 -2
  54. package/dist/__tests__/utils/preference-trigger.test.d.ts.map +0 -1
package/dist/index.cjs CHANGED
@@ -260,21 +260,21 @@ var __webpack_modules__ = {
260
260
  module.id,
261
261
  `.toggle-bPZtik {
262
262
  border-radius: var(--c15t-radius-full, 9999px);
263
- background-color: var(--c15t-switch-track, #ccc);
263
+ background-color: var(--c15t-switch-track, #d9d9d9);
264
264
  cursor: pointer;
265
- width: 36px;
266
- height: 20px;
267
- transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
265
+ width: 2rem;
266
+ height: 1.25rem;
267
+ transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
268
268
  border: none;
269
269
  align-items: center;
270
- padding: 0;
270
+ padding: .125rem;
271
271
  display: inline-flex;
272
272
  position: relative;
273
273
  }
274
274
 
275
275
  .toggle-bPZtik:focus-visible {
276
- outline: 2px solid var(--c15t-primary, #335cff);
277
- outline-offset: 2px;
276
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
277
+ outline: none;
278
278
  }
279
279
 
280
280
  .toggleActive-Ldlasg {
@@ -284,16 +284,16 @@ var __webpack_modules__ = {
284
284
  .toggleThumb-hjGfoX {
285
285
  border-radius: var(--c15t-radius-full, 9999px);
286
286
  background-color: var(--c15t-switch-thumb, #fff);
287
- width: 16px;
288
- height: 16px;
289
- transition: transform var(--c15t-duration-fast, .1s) var(--c15t-easing-spring, cubic-bezier(.34, 1.56, .64, 1));
287
+ width: .75rem;
288
+ height: .75rem;
289
+ box-shadow: 0 0 0 1px var(--c15t-border, #e3e3e3);
290
+ transition: transform var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
290
291
  position: absolute;
291
292
  left: 2px;
292
- box-shadow: 0 1px 2px #0003;
293
293
  }
294
294
 
295
295
  .toggleActive-Ldlasg .toggleThumb-hjGfoX {
296
- transform: translateX(16px);
296
+ transform: translateX(1rem);
297
297
  }
298
298
 
299
299
  .toggle-bPZtik:disabled, .toggleDisabled-ZcD8nZ {
@@ -306,13 +306,14 @@ var __webpack_modules__ = {
306
306
  }
307
307
 
308
308
  .badge-yA0giZ {
309
- border-radius: var(--c15t-radius-sm, .25rem);
309
+ border-radius: var(--c15t-radius-full, 9999px);
310
310
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
311
311
  font-weight: var(--c15t-font-weight-medium, 500);
312
+ line-height: var(--c15t-line-height-tight, 1.25);
312
313
  white-space: nowrap;
314
+ justify-content: center;
313
315
  align-items: center;
314
- padding: 2px 6px;
315
- line-height: 1;
316
+ padding: .1875rem .4375rem;
316
317
  display: inline-flex;
317
318
  }
318
319
 
@@ -345,35 +346,36 @@ var __webpack_modules__ = {
345
346
  justify-content: center;
346
347
  align-items: center;
347
348
  gap: var(--c15t-space-xs, .25rem);
348
- border: 1px solid var(--c15t-border, #e3e3e3);
349
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
349
350
  border-radius: var(--c15t-radius-md, .5rem);
350
- background-color: var(--c15t-surface, #fff);
351
- min-height: 30px;
351
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
352
+ min-height: 2rem;
352
353
  color: var(--c15t-text, #171717);
353
- font-family: inherit;
354
- font-size: 12px;
354
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
355
+ font-size: var(--c15t-font-size-sm, .875rem);
355
356
  font-weight: var(--c15t-font-weight-medium, 500);
357
+ line-height: var(--c15t-line-height-tight, 1.25);
358
+ box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000000d);
356
359
  cursor: pointer;
357
360
  transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
358
- padding: 5px 10px;
359
- line-height: 1;
361
+ padding: .375rem .625rem;
360
362
  display: inline-flex;
361
- box-shadow: 0 1px 1px #0000000a;
362
363
  }
363
364
 
364
365
  .btn-evRVlh:hover {
365
- background-color: var(--c15t-surface-hover, #f7f7f7);
366
+ background-color: var(--c15t-devtools-surface-subtle, #f7f7f7);
366
367
  border-color: var(--c15t-border-hover, #c9c9c9);
367
- box-shadow: 0 2px 6px #00000014;
368
+ box-shadow: var(--c15t-shadow-md, 0 4px 12px #00000014);
368
369
  }
369
370
 
370
371
  .btn-evRVlh:focus-visible {
371
- outline: 2px solid var(--c15t-primary, #335cff);
372
- outline-offset: 1px;
372
+ box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000000d), 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
373
+ outline: none;
373
374
  }
374
375
 
375
376
  .btn-evRVlh:active {
376
- box-shadow: 0 1px 2px #00000014;
377
+ box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000000d);
378
+ transform: scale(.98);
377
379
  }
378
380
 
379
381
  .btn-evRVlh:disabled {
@@ -386,6 +388,7 @@ var __webpack_modules__ = {
386
388
  background-color: var(--c15t-primary, #335cff);
387
389
  border-color: var(--c15t-primary, #335cff);
388
390
  color: var(--c15t-text-on-primary, #fff);
391
+ box-shadow: none;
389
392
  }
390
393
 
391
394
  .btnPrimary-dA6nqY:hover {
@@ -397,6 +400,7 @@ var __webpack_modules__ = {
397
400
  background-color: var(--c15t-devtools-badge-error, #ef4343);
398
401
  border-color: var(--c15t-devtools-badge-error, #ef4343);
399
402
  color: var(--c15t-text-on-primary, #fff);
403
+ box-shadow: none;
400
404
  }
401
405
 
402
406
  .btnDanger-eDnqOX:hover {
@@ -405,10 +409,10 @@ var __webpack_modules__ = {
405
409
  }
406
410
 
407
411
  .btnSmall-TjXoqZ {
412
+ min-height: 1.75rem;
413
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
408
414
  border-radius: var(--c15t-radius-sm, .375rem);
409
- min-height: 26px;
410
- padding: 3px 8px;
411
- font-size: 11px;
415
+ padding: .25rem .5rem;
412
416
  }
413
417
 
414
418
  .btnIcon-fiYQAh {
@@ -418,19 +422,22 @@ var __webpack_modules__ = {
418
422
  }
419
423
 
420
424
  .input-IeTcCs {
421
- width: 100%;
422
- padding: var(--c15t-space-xs, .25rem) var(--c15t-space-sm, .5rem);
423
- border: 1px solid var(--c15t-border, #e3e3e3);
425
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
424
426
  border-radius: var(--c15t-radius-md, .5rem);
425
- background-color: var(--c15t-surface, #fff);
427
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
428
+ width: 100%;
429
+ min-height: 2rem;
426
430
  color: var(--c15t-text, #171717);
427
- font-family: inherit;
428
- font-size: var(--c15t-font-size-sm, .875rem);
429
- transition: border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
431
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
432
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
433
+ line-height: var(--c15t-line-height-tight, 1.25);
434
+ transition: border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
435
+ padding: .375rem .625rem;
430
436
  }
431
437
 
432
438
  .input-IeTcCs:focus {
433
- border-color: var(--c15t-primary, #335cff);
439
+ border-color: var(--c15t-devtools-focus-ring, #335cff);
440
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--c15t-devtools-focus-ring, #335cff) 25%, transparent);
434
441
  outline: none;
435
442
  }
436
443
 
@@ -439,30 +446,35 @@ var __webpack_modules__ = {
439
446
  }
440
447
 
441
448
  .inputSmall-pJyXcL {
442
- padding: 2px var(--c15t-space-xs, .25rem);
449
+ min-height: 1.625rem;
443
450
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
451
+ padding: .25rem .4375rem;
444
452
  }
445
453
 
446
454
  .select-byJ1WM {
447
- width: 100%;
448
- padding: var(--c15t-space-xs, .25rem) var(--c15t-space-sm, .5rem);
449
- border: 1px solid var(--c15t-border, #e3e3e3);
455
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
450
456
  border-radius: var(--c15t-radius-md, .5rem);
451
- background-color: var(--c15t-surface, #fff);
457
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
458
+ width: 100%;
459
+ min-height: 2rem;
452
460
  color: var(--c15t-text, #171717);
453
- font-family: inherit;
461
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
454
462
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
463
+ line-height: var(--c15t-line-height-tight, 1.25);
455
464
  cursor: pointer;
465
+ transition: border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
466
+ padding: .375rem .625rem;
456
467
  }
457
468
 
458
469
  .select-byJ1WM:focus {
459
- border-color: var(--c15t-primary, #335cff);
470
+ border-color: var(--c15t-devtools-focus-ring, #335cff);
471
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--c15t-devtools-focus-ring, #335cff) 25%, transparent);
460
472
  outline: none;
461
473
  }
462
474
 
463
475
  .grid-LlrmEz {
464
476
  gap: var(--c15t-space-sm, .5rem);
465
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-md, 1rem);
477
+ padding: var(--c15t-space-md, 1rem);
466
478
  display: grid;
467
479
  }
468
480
 
@@ -475,42 +487,51 @@ var __webpack_modules__ = {
475
487
  }
476
488
 
477
489
  .gridCard-Qm5xxI {
478
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-md, .75rem);
479
- border: 1px solid var(--c15t-border, #e3e3e3);
480
- border-radius: var(--c15t-radius-md, .5rem);
481
- background-color: var(--c15t-surface, #fff);
482
- transition: border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
483
490
  justify-content: space-between;
484
491
  align-items: center;
492
+ gap: var(--c15t-space-sm, .5rem);
493
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
494
+ border-radius: var(--c15t-radius-md, .5rem);
495
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
496
+ min-height: 2.75rem;
497
+ box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000000d);
498
+ transition: border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
499
+ padding: .5625rem .75rem;
485
500
  display: flex;
486
501
  }
487
502
 
488
503
  .gridCard-Qm5xxI:hover {
489
504
  border-color: var(--c15t-border-hover, #c9c9c9);
505
+ background-color: var(--c15t-devtools-surface-subtle, #fafafa);
490
506
  }
491
507
 
492
508
  .gridCardTitle-HjXETp {
493
509
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
494
510
  font-weight: var(--c15t-font-weight-medium, 500);
495
511
  color: var(--c15t-text, #171717);
512
+ line-height: var(--c15t-line-height-tight, 1.25);
496
513
  }
497
514
 
498
515
  .listItem-XUKGIo {
499
- padding: var(--c15t-space-xs, .25rem) var(--c15t-space-md, 1rem);
500
- border-bottom: 1px solid var(--c15t-border, #e3e3e3);
501
516
  justify-content: space-between;
502
517
  align-items: center;
518
+ gap: var(--c15t-space-sm, .5rem);
519
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
520
+ border-radius: var(--c15t-radius-md, .5rem);
521
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
522
+ margin-bottom: .375rem;
523
+ padding: .625rem .75rem;
503
524
  display: flex;
504
525
  }
505
526
 
506
527
  .listItem-XUKGIo:last-child {
507
- border-bottom: none;
528
+ margin-bottom: 0;
508
529
  }
509
530
 
510
531
  .listItemContent-WDBF1N {
511
532
  flex-direction: column;
512
533
  flex: 1;
513
- gap: 2px;
534
+ gap: .1875rem;
514
535
  min-width: 0;
515
536
  display: flex;
516
537
  }
@@ -524,6 +545,7 @@ var __webpack_modules__ = {
524
545
  .listItemDescription-E6JHyZ {
525
546
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
526
547
  color: var(--c15t-text-muted, #737373);
548
+ line-height: var(--c15t-line-height-tight, 1.25);
527
549
  text-overflow: ellipsis;
528
550
  white-space: nowrap;
529
551
  overflow: hidden;
@@ -537,8 +559,8 @@ var __webpack_modules__ = {
537
559
  }
538
560
 
539
561
  .section-a197cB {
540
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-md, 1rem);
541
- border-bottom: 1px solid var(--c15t-border, #e3e3e3);
562
+ border-bottom: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
563
+ padding: .75rem 1rem;
542
564
  }
543
565
 
544
566
  .section-a197cB:last-child {
@@ -546,9 +568,10 @@ var __webpack_modules__ = {
546
568
  }
547
569
 
548
570
  .sectionHeader-Xcljcw {
549
- margin-bottom: var(--c15t-space-sm, .5rem);
550
571
  justify-content: space-between;
551
572
  align-items: center;
573
+ gap: .5rem;
574
+ margin-bottom: .625rem;
552
575
  display: flex;
553
576
  }
554
577
 
@@ -557,47 +580,49 @@ var __webpack_modules__ = {
557
580
  font-weight: var(--c15t-font-weight-semibold, 600);
558
581
  color: var(--c15t-text-muted, #737373);
559
582
  text-transform: uppercase;
560
- letter-spacing: .5px;
583
+ letter-spacing: .04em;
561
584
  }
562
585
 
563
586
  .overrideField-keNdpJ {
564
587
  flex-direction: column;
565
- gap: 3px;
588
+ gap: .3125rem;
566
589
  margin-bottom: 0;
567
590
  display: flex;
568
591
  }
569
592
 
570
593
  .overrideLabel-ApMoTw {
594
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
595
+ font-weight: var(--c15t-font-weight-semibold, 600);
571
596
  color: var(--c15t-text-muted, #737373);
572
- font-size: 11px;
573
- font-weight: 600;
597
+ line-height: var(--c15t-line-height-tight, 1.25);
574
598
  }
575
599
 
576
600
  .overrideHint-yCfwGt {
577
- color: var(--c15t-devtools-text-muted, #737373);
578
- margin-top: 6px;
579
- font-size: 11px;
601
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
602
+ color: var(--c15t-text-muted, #737373);
603
+ line-height: var(--c15t-line-height-tight, 1.25);
604
+ margin-top: .5rem;
580
605
  }
581
606
 
582
607
  .overrideActions-imdcn7 {
583
- border-top: 1px dashed var(--c15t-border, #e3e3e3);
608
+ border-top: 1px dashed var(--c15t-devtools-border-strong, #e3e3e3);
584
609
  justify-content: space-between;
585
610
  align-items: center;
586
- gap: 8px;
587
- margin-top: 8px;
588
- padding-top: 8px;
611
+ gap: .5rem;
612
+ margin-top: .625rem;
613
+ padding-top: .625rem;
589
614
  display: flex;
590
615
  }
591
616
 
592
617
  .overrideActionButtons-gYOx1e {
593
618
  flex-wrap: wrap;
594
- gap: 6px;
619
+ gap: .375rem;
595
620
  display: flex;
596
621
  }
597
622
 
598
623
  .overrideStatus-sty_qS {
624
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
599
625
  color: var(--c15t-text-muted, #737373);
600
- font-size: 11px;
601
626
  }
602
627
 
603
628
  .overrideStatusDirty-OUdDMw {
@@ -605,9 +630,10 @@ var __webpack_modules__ = {
605
630
  }
606
631
 
607
632
  .infoRow-RlB_0h {
608
- padding: var(--c15t-space-xs, .25rem) 0;
609
633
  justify-content: space-between;
610
634
  align-items: center;
635
+ gap: .5rem;
636
+ padding: .25rem 0;
611
637
  display: flex;
612
638
  }
613
639
 
@@ -620,6 +646,7 @@ var __webpack_modules__ = {
620
646
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
621
647
  font-weight: var(--c15t-font-weight-medium, 500);
622
648
  color: var(--c15t-text, #171717);
649
+ font-variant-numeric: tabular-nums;
623
650
  font-family: ui-monospace, Cascadia Code, Source Code Pro, Menlo, Consolas, DejaVu Sans Mono, monospace;
624
651
  }
625
652
 
@@ -630,18 +657,27 @@ var __webpack_modules__ = {
630
657
  flex-direction: column;
631
658
  justify-content: center;
632
659
  align-items: center;
660
+ gap: .375rem;
633
661
  display: flex;
634
662
  }
635
663
 
636
664
  .emptyStateIcon-WHFkX8 {
665
+ opacity: .55;
637
666
  width: 32px;
638
667
  height: 32px;
639
- margin-bottom: var(--c15t-space-sm, .5rem);
640
- opacity: .5;
641
668
  }
642
669
 
643
670
  .emptyStateText-TaLvAJ {
644
671
  font-size: var(--c15t-font-size-sm, .875rem);
672
+ line-height: var(--c15t-line-height-normal, 1.5);
673
+ }
674
+
675
+ .disconnectedState-dOtZBG {
676
+ padding: var(--c15t-space-xl, 2rem);
677
+ text-align: center;
678
+ font-size: var(--c15t-font-size-sm, .875rem);
679
+ color: var(--c15t-text-muted, #737373);
680
+ line-height: var(--c15t-line-height-normal, 1.5);
645
681
  }
646
682
 
647
683
  @media (prefers-reduced-motion: reduce) {
@@ -708,7 +744,8 @@ var __webpack_modules__ = {
708
744
  infoValue: "infoValue-flMl_e",
709
745
  emptyState: "emptyState-QcmzTQ",
710
746
  emptyStateIcon: "emptyStateIcon-WHFkX8",
711
- emptyStateText: "emptyStateText-TaLvAJ"
747
+ emptyStateText: "emptyStateText-TaLvAJ",
748
+ disconnectedState: "disconnectedState-dOtZBG"
712
749
  };
713
750
  const __rspack_default_export = ___CSS_LOADER_EXPORT___;
714
751
  },
@@ -737,9 +774,9 @@ var __webpack_modules__ = {
737
774
  .floatingButton-Gw8MtJ {
738
775
  width: var(--c15t-devtools-button-size, 40px);
739
776
  height: var(--c15t-devtools-button-size, 40px);
740
- border: 1px solid var(--c15t-border, #e3e3e3);
777
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
741
778
  border-radius: var(--c15t-radius-full, 9999px);
742
- background-color: var(--c15t-surface, #fff);
779
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
743
780
  box-shadow: var(--c15t-shadow-lg, 0 10px 15px -3px #0000001a, 0 4px 6px -4px #0000001a);
744
781
  cursor: grab;
745
782
  z-index: var(--c15t-devtools-z-index, 99999);
@@ -767,13 +804,13 @@ var __webpack_modules__ = {
767
804
  }
768
805
 
769
806
  .floatingButton-Gw8MtJ:focus-visible {
770
- outline: 2px solid var(--c15t-primary, #335cff);
771
- outline-offset: 2px;
807
+ box-shadow: var(--c15t-shadow-lg, 0 8px 24px #0000001f), 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
808
+ outline: none;
772
809
  }
773
810
 
774
811
  .floatingButton-Gw8MtJ:active {
775
812
  cursor: grabbing;
776
- transform: scale(1.02);
813
+ transform: scale(.98);
777
814
  }
778
815
 
779
816
  .floatingButtonIcon-cHWefk {
@@ -814,6 +851,7 @@ var __webpack_modules__ = {
814
851
 
815
852
  .backdrop-LhVMB5 {
816
853
  background-color: var(--c15t-overlay, #00000080);
854
+ backdrop-filter: blur(1px);
817
855
  z-index: calc(var(--c15t-devtools-z-index, 99999) + 1);
818
856
  position: fixed;
819
857
  inset: 0;
@@ -822,10 +860,10 @@ var __webpack_modules__ = {
822
860
  .panel-jtWove {
823
861
  width: var(--c15t-devtools-panel-width, 480px);
824
862
  max-height: var(--c15t-devtools-panel-max-height, 560px);
825
- background-color: var(--c15t-surface, #fff);
826
- border: 1px solid var(--c15t-border, #e3e3e3);
863
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
864
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
827
865
  border-radius: var(--c15t-radius-lg, .75rem);
828
- box-shadow: var(--c15t-shadow-lg, 0 8px 24px #0000001f);
866
+ box-shadow: var(--c15t-shadow-lg, 0 10px 28px #00000029);
829
867
  z-index: calc(var(--c15t-devtools-z-index, 99999) + 2);
830
868
  flex-direction: column;
831
869
  display: flex;
@@ -858,11 +896,11 @@ var __webpack_modules__ = {
858
896
  }
859
897
 
860
898
  .header-xluoTr {
861
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-md, 1rem);
862
- border-bottom: 1px solid var(--c15t-border, #e3e3e3);
899
+ border-bottom: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
863
900
  background-color: var(--c15t-devtools-surface-muted, #f5f5f5);
864
901
  justify-content: space-between;
865
902
  align-items: center;
903
+ padding: .6875rem .875rem;
866
904
  display: flex;
867
905
  }
868
906
 
@@ -871,6 +909,7 @@ var __webpack_modules__ = {
871
909
  gap: var(--c15t-space-sm, .5rem);
872
910
  font-size: var(--c15t-font-size-sm, .875rem);
873
911
  font-weight: var(--c15t-font-weight-semibold, 600);
912
+ line-height: var(--c15t-line-height-tight, 1.25);
874
913
  color: var(--c15t-text, #171717);
875
914
  display: flex;
876
915
  }
@@ -882,9 +921,9 @@ var __webpack_modules__ = {
882
921
  }
883
922
 
884
923
  .closeButton-Yto0Nb {
885
- border-radius: var(--c15t-radius-sm, .25rem);
886
- width: 28px;
887
- height: 28px;
924
+ border-radius: var(--c15t-radius-md, .5rem);
925
+ width: 2rem;
926
+ height: 2rem;
888
927
  color: var(--c15t-text-muted, #737373);
889
928
  cursor: pointer;
890
929
  transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
@@ -897,13 +936,13 @@ var __webpack_modules__ = {
897
936
  }
898
937
 
899
938
  .closeButton-Yto0Nb:hover {
900
- background-color: var(--c15t-surface-hover, #f7f7f7);
939
+ background-color: var(--c15t-devtools-surface-subtle, #f7f7f7);
901
940
  color: var(--c15t-text, #171717);
902
941
  }
903
942
 
904
943
  .closeButton-Yto0Nb:focus-visible {
905
- outline: 2px solid var(--c15t-primary, #335cff);
906
- outline-offset: 1px;
944
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
945
+ outline: none;
907
946
  }
908
947
 
909
948
  .closeButtonIcon-fVlR1I {
@@ -911,33 +950,71 @@ var __webpack_modules__ = {
911
950
  height: 16px;
912
951
  }
913
952
 
953
+ .inlineActionButton-Ky8BmN {
954
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
955
+ border-radius: var(--c15t-radius-sm, .375rem);
956
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
957
+ min-height: 1.625rem;
958
+ color: var(--c15t-text, #171717);
959
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
960
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
961
+ font-weight: var(--c15t-font-weight-medium, 500);
962
+ line-height: var(--c15t-line-height-tight, 1.25);
963
+ cursor: pointer;
964
+ transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
965
+ justify-content: center;
966
+ align-items: center;
967
+ padding: .25rem .5rem;
968
+ display: inline-flex;
969
+ }
970
+
971
+ .inlineActionButton-Ky8BmN:hover {
972
+ background-color: var(--c15t-devtools-surface-subtle, #f7f7f7);
973
+ border-color: var(--c15t-border-hover, #c9c9c9);
974
+ }
975
+
976
+ .inlineActionButton-Ky8BmN:focus-visible {
977
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
978
+ outline: none;
979
+ }
980
+
914
981
  .content-yDMYfG {
982
+ scrollbar-gutter: stable;
915
983
  overscroll-behavior: contain;
916
984
  -webkit-overflow-scrolling: touch;
985
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
917
986
  flex: auto;
918
987
  min-height: 200px;
919
- overflow: hidden auto;
988
+ overflow: hidden scroll;
920
989
  }
921
990
 
922
991
  .footer-ESbmwQ {
923
- padding: var(--c15t-space-xs, .25rem) var(--c15t-space-md, 1rem);
924
- border-top: 1px solid var(--c15t-border, #e3e3e3);
992
+ border-top: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
925
993
  background-color: var(--c15t-devtools-surface-muted, #f5f5f5);
926
994
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
927
995
  color: var(--c15t-text-muted, #737373);
928
996
  justify-content: space-between;
929
997
  align-items: center;
998
+ gap: .5rem;
999
+ padding: .5rem .75rem;
930
1000
  display: flex;
931
1001
  }
932
1002
 
933
1003
  .footerStatus-rlb99A {
934
1004
  align-items: center;
935
- gap: var(--c15t-space-xs, .25rem);
1005
+ gap: .375rem;
1006
+ min-width: 0;
936
1007
  display: flex;
937
1008
  }
938
1009
 
1010
+ .footerMeta-Vdtxdk {
1011
+ opacity: .75;
1012
+ white-space: nowrap;
1013
+ }
1014
+
939
1015
  .statusDot-hYJoej {
940
1016
  border-radius: var(--c15t-radius-full, 9999px);
1017
+ flex-shrink: 0;
941
1018
  width: 6px;
942
1019
  height: 6px;
943
1020
  }
@@ -976,6 +1053,7 @@ var __webpack_modules__ = {
976
1053
  font-size: var(--c15t-font-size-sm, .875rem);
977
1054
  color: var(--c15t-text-muted, #737373);
978
1055
  max-width: 280px;
1056
+ line-height: var(--c15t-line-height-normal, 1.5);
979
1057
  }
980
1058
 
981
1059
  @media (prefers-reduced-motion: reduce) {
@@ -992,17 +1070,17 @@ var __webpack_modules__ = {
992
1070
  }
993
1071
 
994
1072
  .dropdownMenu-aKK18l {
995
- min-width: 200px;
996
- padding: var(--c15t-space-xs, .25rem);
997
- border: 1px solid var(--c15t-border, #e3e3e3);
1073
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
998
1074
  border-radius: var(--c15t-radius-lg, .75rem);
999
- background-color: var(--c15t-surface, #fff);
1075
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
1076
+ min-width: 200px;
1000
1077
  box-shadow: var(--c15t-shadow-lg, 0 8px 24px #0000001f);
1001
1078
  z-index: calc(var(--c15t-devtools-z-index, 99999) + 1);
1002
1079
  opacity: 0;
1003
1080
  transform-origin: 0 100%;
1004
1081
  pointer-events: none;
1005
1082
  transition: opacity var(--c15t-duration-fast, .1s) var(--c15t-easing-out, cubic-bezier(.215, .61, .355, 1)), transform var(--c15t-duration-fast, .1s) var(--c15t-easing-out, cubic-bezier(.215, .61, .355, 1));
1083
+ padding: .375rem;
1006
1084
  position: fixed;
1007
1085
  transform: scale(.95)translateY(8px);
1008
1086
  }
@@ -1030,34 +1108,35 @@ var __webpack_modules__ = {
1030
1108
  }
1031
1109
 
1032
1110
  .menuItem-kBbHRP {
1033
- align-items: center;
1034
- gap: var(--c15t-space-sm, .5rem);
1035
- width: 100%;
1036
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-md, .75rem);
1037
1111
  border-radius: var(--c15t-radius-md, .5rem);
1112
+ width: 100%;
1038
1113
  color: var(--c15t-text, #171717);
1039
- font-size: var(--c15t-font-size-sm, .875rem);
1114
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
1040
1115
  font-weight: var(--c15t-font-weight-medium, 500);
1116
+ line-height: var(--c15t-line-height-tight, 1.25);
1041
1117
  text-align: left;
1042
1118
  cursor: pointer;
1043
1119
  transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1044
1120
  background: none;
1045
1121
  border: none;
1122
+ align-items: center;
1123
+ gap: .625rem;
1124
+ padding: .5rem .625rem;
1046
1125
  display: flex;
1047
1126
  }
1048
1127
 
1049
1128
  .menuItem-kBbHRP:hover {
1050
- background-color: var(--c15t-surface-hover, #f2f2f2);
1129
+ background-color: var(--c15t-devtools-surface-subtle, #f2f2f2);
1051
1130
  }
1052
1131
 
1053
1132
  .menuItem-kBbHRP:focus-visible {
1054
- outline: 2px solid var(--c15t-primary, #335cff);
1055
- outline-offset: -2px;
1133
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
1134
+ outline: none;
1056
1135
  }
1057
1136
 
1058
1137
  .menuItemIcon-P3pP5K {
1059
- width: 20px;
1060
- height: 20px;
1138
+ width: 1rem;
1139
+ height: 1rem;
1061
1140
  color: var(--c15t-text-muted, #737373);
1062
1141
  flex-shrink: 0;
1063
1142
  }
@@ -1070,6 +1149,7 @@ var __webpack_modules__ = {
1070
1149
  font-size: var(--c15t-devtools-font-size-xs, .75rem);
1071
1150
  color: var(--c15t-text-muted, #737373);
1072
1151
  font-weight: var(--c15t-font-weight-normal, 400);
1152
+ margin-top: .125rem;
1073
1153
  }
1074
1154
 
1075
1155
  .menuItemContent-hBlruV {
@@ -1085,8 +1165,8 @@ var __webpack_modules__ = {
1085
1165
  .menuItemToggleTrack-gDp_f3 {
1086
1166
  background-color: var(--c15t-switch-track, #d9d9d9);
1087
1167
  border-radius: var(--c15t-radius-full, 9999px);
1088
- width: 36px;
1089
- height: 20px;
1168
+ width: 2rem;
1169
+ height: 1.25rem;
1090
1170
  transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1091
1171
  position: relative;
1092
1172
  }
@@ -1094,21 +1174,22 @@ var __webpack_modules__ = {
1094
1174
  .menuItemToggleThumb-ioqqyc {
1095
1175
  background-color: var(--c15t-switch-thumb, #fff);
1096
1176
  border-radius: var(--c15t-radius-full, 9999px);
1097
- width: 16px;
1098
- height: 16px;
1099
- box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000001a);
1177
+ width: .75rem;
1178
+ height: .75rem;
1179
+ box-shadow: 0 0 0 1px var(--c15t-border, #e3e3e3);
1100
1180
  transition: transform var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1101
1181
  position: absolute;
1102
- top: 2px;
1182
+ top: 50%;
1103
1183
  left: 2px;
1184
+ transform: translateY(-50%);
1104
1185
  }
1105
1186
 
1106
1187
  .menuItemToggleChecked-K3BPtk .menuItemToggleTrack-gDp_f3 {
1107
- background-color: var(--c15t-switch-track-checked, #335cff);
1188
+ background-color: var(--c15t-switch-track-active, #335cff);
1108
1189
  }
1109
1190
 
1110
1191
  .menuItemToggleChecked-K3BPtk .menuItemToggleThumb-ioqqyc {
1111
- transform: translateX(16px);
1192
+ transform: translate(1rem, -50%);
1112
1193
  }
1113
1194
 
1114
1195
  .menuDivider-JIBdhU {
@@ -1144,9 +1225,11 @@ var __webpack_modules__ = {
1144
1225
  headerLogo: "headerLogo-PxJ_w1",
1145
1226
  closeButton: "closeButton-Yto0Nb",
1146
1227
  closeButtonIcon: "closeButtonIcon-fVlR1I",
1228
+ inlineActionButton: "inlineActionButton-Ky8BmN",
1147
1229
  content: "content-yDMYfG",
1148
1230
  footer: "footer-ESbmwQ",
1149
1231
  footerStatus: "footerStatus-rlb99A",
1232
+ footerMeta: "footerMeta-Vdtxdk",
1150
1233
  statusDot: "statusDot-hYJoej",
1151
1234
  statusConnected: "statusConnected-hPSUgS",
1152
1235
  statusDisconnected: "statusDisconnected-HIpcee",
@@ -1185,62 +1268,63 @@ var __webpack_modules__ = {
1185
1268
  ___CSS_LOADER_EXPORT___.push([
1186
1269
  module.id,
1187
1270
  `.tabList-IyuiBE {
1271
+ border-bottom: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
1272
+ background-color: var(--c15t-devtools-surface-subtle, #fafafa);
1188
1273
  align-items: center;
1189
- gap: var(--c15t-space-xs, .25rem);
1190
- padding: var(--c15t-space-sm, .5rem) var(--c15t-space-sm, .5rem);
1191
- border-bottom: 1px solid var(--c15t-border, #e3e3e3);
1192
- background-color: var(--c15t-surface, #fff);
1193
- scrollbar-width: none;
1194
- -ms-overflow-style: none;
1195
- scroll-padding-inline-end: var(--c15t-space-sm, .5rem);
1274
+ gap: .375rem;
1275
+ padding: .75rem;
1196
1276
  display: flex;
1197
- overflow-x: auto;
1198
1277
  }
1199
1278
 
1200
- .tabList-IyuiBE:after {
1201
- content: "";
1202
- flex: 0 0 var(--c15t-space-sm, .5rem);
1203
- }
1204
-
1205
- .tabList-IyuiBE::-webkit-scrollbar {
1206
- display: none;
1279
+ .tabStrip-_KrWe4 {
1280
+ align-items: center;
1281
+ gap: var(--c15t-space-xs, .25rem);
1282
+ flex: auto;
1283
+ min-width: 0;
1284
+ display: flex;
1285
+ overflow: hidden;
1207
1286
  }
1208
1287
 
1209
1288
  .tab-yfDEqg {
1210
- align-items: center;
1211
- gap: var(--c15t-space-xs, .25rem);
1212
1289
  border-radius: var(--c15t-radius-md, .5rem);
1290
+ min-height: 1.875rem;
1213
1291
  color: var(--c15t-text-muted, #737373);
1214
- font-family: inherit;
1215
- font-size: 11px;
1292
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
1293
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
1216
1294
  font-weight: var(--c15t-font-weight-medium, 500);
1295
+ line-height: var(--c15t-line-height-tight, 1.25);
1217
1296
  cursor: pointer;
1218
1297
  white-space: nowrap;
1219
- transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1298
+ transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), box-shadow var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1220
1299
  background-color: #0000;
1221
- border: none;
1222
- padding: 3px 7px;
1300
+ border: 1px solid #0000;
1301
+ flex-shrink: 0;
1302
+ align-items: center;
1303
+ gap: .375rem;
1304
+ padding: .25rem .625rem;
1223
1305
  display: flex;
1224
1306
  }
1225
1307
 
1226
1308
  .tab-yfDEqg:hover {
1227
- background-color: var(--c15t-surface-hover, #f7f7f7);
1309
+ background-color: var(--c15t-devtools-surface-muted, #f7f7f7);
1228
1310
  color: var(--c15t-text, #171717);
1229
1311
  }
1230
1312
 
1231
1313
  .tab-yfDEqg:focus-visible {
1232
- outline: 2px solid var(--c15t-primary, #335cff);
1233
- outline-offset: 1px;
1314
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
1315
+ outline: none;
1234
1316
  }
1235
1317
 
1236
1318
  .tabActive-r4hing {
1237
- background-color: var(--c15t-primary, #335cff);
1238
- color: var(--c15t-text-on-primary, #fff);
1319
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
1320
+ border-color: var(--c15t-devtools-border-strong, #e3e3e3);
1321
+ color: var(--c15t-text, #171717);
1322
+ box-shadow: var(--c15t-shadow-sm, 0 1px 2px #0000000d);
1239
1323
  }
1240
1324
 
1241
1325
  .tabActive-r4hing:hover {
1242
- background-color: var(--c15t-primary-hover, #03f);
1243
- color: var(--c15t-text-on-primary, #fff);
1326
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
1327
+ color: var(--c15t-text, #171717);
1244
1328
  }
1245
1329
 
1246
1330
  .tabIcon-U9tnu0 {
@@ -1249,6 +1333,131 @@ var __webpack_modules__ = {
1249
1333
  height: 14px;
1250
1334
  }
1251
1335
 
1336
+ .tabHidden-HBXYSd {
1337
+ display: none;
1338
+ }
1339
+
1340
+ .overflowContainer-TTw9DO {
1341
+ flex-shrink: 0;
1342
+ position: relative;
1343
+ }
1344
+
1345
+ .overflowContainerHidden-sQa_XZ {
1346
+ display: none;
1347
+ }
1348
+
1349
+ .overflowButton-tKq4FF {
1350
+ border-radius: var(--c15t-radius-md, .5rem);
1351
+ width: 1.875rem;
1352
+ height: 1.875rem;
1353
+ color: var(--c15t-text-muted, #737373);
1354
+ cursor: pointer;
1355
+ transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), border-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1356
+ background-color: #0000;
1357
+ border: 1px solid #0000;
1358
+ justify-content: center;
1359
+ align-items: center;
1360
+ padding: 0;
1361
+ display: inline-flex;
1362
+ }
1363
+
1364
+ .overflowButton-tKq4FF:hover {
1365
+ background-color: var(--c15t-devtools-surface-muted, #f7f7f7);
1366
+ color: var(--c15t-text, #171717);
1367
+ }
1368
+
1369
+ .overflowButton-tKq4FF:focus-visible {
1370
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
1371
+ outline: none;
1372
+ }
1373
+
1374
+ .overflowButtonIcon-FSurfC {
1375
+ justify-content: center;
1376
+ align-items: center;
1377
+ width: 14px;
1378
+ height: 14px;
1379
+ display: inline-flex;
1380
+ }
1381
+
1382
+ .overflowMenu-TST0eZ {
1383
+ border: 1px solid var(--c15t-devtools-border-strong, #e3e3e3);
1384
+ border-radius: var(--c15t-radius-md, .5rem);
1385
+ background-color: var(--c15t-devtools-surface-elevated, #fff);
1386
+ min-width: 10rem;
1387
+ box-shadow: var(--c15t-shadow-md, 0 4px 12px #00000014);
1388
+ opacity: 0;
1389
+ transform-origin: 100% 0;
1390
+ pointer-events: none;
1391
+ z-index: 10;
1392
+ transition: opacity var(--c15t-duration-fast, .1s) var(--c15t-easing-out, cubic-bezier(.215, .61, .355, 1)), transform var(--c15t-duration-fast, .1s) var(--c15t-easing-out, cubic-bezier(.215, .61, .355, 1));
1393
+ flex-direction: column;
1394
+ gap: .125rem;
1395
+ padding: .3125rem;
1396
+ display: flex;
1397
+ position: absolute;
1398
+ top: calc(100% + .375rem);
1399
+ right: 0;
1400
+ transform: translateY(-4px)scale(.98);
1401
+ }
1402
+
1403
+ .overflowMenu-TST0eZ[data-state="open"] {
1404
+ opacity: 1;
1405
+ pointer-events: auto;
1406
+ transform: translateY(0)scale(1);
1407
+ }
1408
+
1409
+ .overflowItem-y5Pz7k {
1410
+ border-radius: var(--c15t-radius-sm, .375rem);
1411
+ min-height: 1.75rem;
1412
+ color: var(--c15t-text, #171717);
1413
+ font-family: var(--c15t-font-family, system-ui, -apple-system, sans-serif);
1414
+ font-size: var(--c15t-devtools-font-size-xs, .75rem);
1415
+ font-weight: var(--c15t-font-weight-medium, 500);
1416
+ line-height: var(--c15t-line-height-tight, 1.25);
1417
+ text-align: left;
1418
+ cursor: pointer;
1419
+ white-space: nowrap;
1420
+ transition: background-color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1)), color var(--c15t-duration-fast, .1s) var(--c15t-easing, cubic-bezier(.4, 0, .2, 1));
1421
+ background-color: #0000;
1422
+ border: none;
1423
+ align-items: center;
1424
+ gap: .5rem;
1425
+ padding: .3125rem .5rem;
1426
+ display: inline-flex;
1427
+ }
1428
+
1429
+ .overflowItem-y5Pz7k:hover {
1430
+ background-color: var(--c15t-devtools-surface-subtle, #fafafa);
1431
+ }
1432
+
1433
+ .overflowItem-y5Pz7k:focus-visible {
1434
+ box-shadow: 0 0 0 2px var(--c15t-devtools-focus-ring, #335cff);
1435
+ outline: none;
1436
+ }
1437
+
1438
+ .overflowItemActive-mzVG1T {
1439
+ background-color: var(--c15t-devtools-accent-soft, #ebefff);
1440
+ color: var(--c15t-text, #171717);
1441
+ }
1442
+
1443
+ .overflowItemDisabled-dcHX3K {
1444
+ opacity: .5;
1445
+ cursor: not-allowed;
1446
+ }
1447
+
1448
+ .overflowItemIcon-fz291V {
1449
+ flex-shrink: 0;
1450
+ justify-content: center;
1451
+ align-items: center;
1452
+ width: 14px;
1453
+ height: 14px;
1454
+ display: inline-flex;
1455
+ }
1456
+
1457
+ .overflowItemHidden-k4aawi {
1458
+ display: none;
1459
+ }
1460
+
1252
1461
  .tabDisabled-lDuv5l {
1253
1462
  opacity: .5;
1254
1463
  cursor: not-allowed;
@@ -1269,7 +1478,7 @@ var __webpack_modules__ = {
1269
1478
  }
1270
1479
 
1271
1480
  @media (prefers-reduced-motion: reduce) {
1272
- .tab-yfDEqg {
1481
+ .tab-yfDEqg, .overflowButton-tKq4FF, .overflowMenu-TST0eZ, .overflowItem-y5Pz7k {
1273
1482
  transition: none;
1274
1483
  }
1275
1484
  }
@@ -1285,9 +1494,21 @@ var __webpack_modules__ = {
1285
1494
  ]);
1286
1495
  ___CSS_LOADER_EXPORT___.locals = {
1287
1496
  tabList: "tabList-IyuiBE",
1497
+ tabStrip: "tabStrip-_KrWe4",
1288
1498
  tab: "tab-yfDEqg",
1289
1499
  tabActive: "tabActive-r4hing",
1290
1500
  tabIcon: "tabIcon-U9tnu0",
1501
+ tabHidden: "tabHidden-HBXYSd",
1502
+ overflowContainer: "overflowContainer-TTw9DO",
1503
+ overflowContainerHidden: "overflowContainerHidden-sQa_XZ",
1504
+ overflowButton: "overflowButton-tKq4FF",
1505
+ overflowButtonIcon: "overflowButtonIcon-FSurfC",
1506
+ overflowMenu: "overflowMenu-TST0eZ",
1507
+ overflowItem: "overflowItem-y5Pz7k",
1508
+ overflowItemActive: "overflowItemActive-mzVG1T",
1509
+ overflowItemDisabled: "overflowItemDisabled-dcHX3K",
1510
+ overflowItemIcon: "overflowItemIcon-fz291V",
1511
+ overflowItemHidden: "overflowItemHidden-k4aawi",
1291
1512
  tabDisabled: "tabDisabled-lDuv5l",
1292
1513
  tabPanel: "tabPanel-QKO8FX",
1293
1514
  tabPanelActive: "tabPanelActive-mrNlGE"
@@ -1311,6 +1532,15 @@ var __webpack_modules__ = {
1311
1532
  --c15t-devtools-button-size: 40px;
1312
1533
  --c15t-devtools-z-index: 99999;
1313
1534
  --c15t-devtools-surface-muted: var(--c15t-surface-hover, #f7f7f7);
1535
+ --c15t-devtools-surface-subtle: #fafafa;
1536
+ --c15t-devtools-surface-elevated: var(--c15t-surface, #fff);
1537
+ --c15t-devtools-border-strong: var(--c15t-border, #e3e3e3);
1538
+ --c15t-devtools-code-surface: #f7f7f7;
1539
+ --c15t-devtools-accent-soft: #ebefff;
1540
+ --c15t-devtools-focus-ring: var(--c15t-primary, #335cff);
1541
+ --c15t-devtools-text-muted: var(--c15t-text-muted, #737373);
1542
+ --c15t-devtools-font-size-sm: var(--c15t-font-size-sm, .875rem);
1543
+ --c15t-surface-muted: var(--c15t-devtools-surface-muted, #f7f7f7);
1314
1544
  --c15t-devtools-font-size-xs: .75rem;
1315
1545
  --c15t-devtools-badge-success: #21c45d;
1316
1546
  --c15t-devtools-badge-success-bg: #e4fbed;
@@ -1324,8 +1554,37 @@ var __webpack_modules__ = {
1324
1554
  --c15t-devtools-badge-neutral-bg: #f0f0f0;
1325
1555
  }
1326
1556
 
1557
+ :is(:global(.c15t-light), :global(.light)) {
1558
+ --c15t-devtools-surface-muted: var(--c15t-surface-hover, #f7f7f7);
1559
+ --c15t-devtools-surface-subtle: #fafafa;
1560
+ --c15t-devtools-surface-elevated: var(--c15t-surface, #fff);
1561
+ --c15t-devtools-border-strong: var(--c15t-border, #e3e3e3);
1562
+ --c15t-devtools-code-surface: #f7f7f7;
1563
+ --c15t-devtools-accent-soft: #ebefff;
1564
+ --c15t-devtools-badge-success-bg: #e4fbed;
1565
+ --c15t-devtools-badge-error-bg: #fde7e7;
1566
+ --c15t-devtools-badge-warning-bg: #fef7dc;
1567
+ --c15t-devtools-badge-info-bg: #dcebfe;
1568
+ --c15t-devtools-badge-neutral-bg: #f0f0f0;
1569
+ }
1570
+
1571
+ @supports (color: color-mix(in srgb, white, black)) {
1572
+ :root {
1573
+ --c15t-devtools-surface-muted: color-mix(in srgb, var(--c15t-surface-hover, #f7f7f7) 85%, var(--c15t-surface, #fff));
1574
+ --c15t-devtools-surface-subtle: color-mix(in srgb, var(--c15t-surface-hover, #f7f7f7) 55%, var(--c15t-surface, #fff));
1575
+ --c15t-devtools-border-strong: color-mix(in srgb, var(--c15t-border, #e3e3e3) 80%, var(--c15t-text-muted, #737373));
1576
+ --c15t-devtools-code-surface: color-mix(in srgb, var(--c15t-surface-hover, #f7f7f7) 70%, var(--c15t-surface, #fff));
1577
+ --c15t-devtools-accent-soft: color-mix(in srgb, var(--c15t-primary, #335cff) 12%, transparent);
1578
+ }
1579
+ }
1580
+
1327
1581
  :is(:global(.c15t-dark), :global(.dark)) {
1328
1582
  --c15t-devtools-surface-muted: var(--c15t-surface-hover, #292929);
1583
+ --c15t-devtools-surface-subtle: #242424;
1584
+ --c15t-devtools-surface-elevated: var(--c15t-surface, #1a1a1a);
1585
+ --c15t-devtools-border-strong: var(--c15t-border, #3d3d3d);
1586
+ --c15t-devtools-code-surface: #212121;
1587
+ --c15t-devtools-accent-soft: #335cff33;
1329
1588
  --c15t-devtools-badge-success-bg: #21c45d33;
1330
1589
  --c15t-devtools-badge-error-bg: #ef434333;
1331
1590
  --c15t-devtools-badge-warning-bg: #f59f0a33;
@@ -1334,8 +1593,13 @@ var __webpack_modules__ = {
1334
1593
  }
1335
1594
 
1336
1595
  @media (prefers-color-scheme: dark) {
1337
- :root {
1596
+ :global(:root:not(.light):not(.c15t-light)) {
1338
1597
  --c15t-devtools-surface-muted: var(--c15t-surface-hover, #292929);
1598
+ --c15t-devtools-surface-subtle: #242424;
1599
+ --c15t-devtools-surface-elevated: var(--c15t-surface, #1a1a1a);
1600
+ --c15t-devtools-border-strong: var(--c15t-border, #3d3d3d);
1601
+ --c15t-devtools-code-surface: #212121;
1602
+ --c15t-devtools-accent-soft: #335cff33;
1339
1603
  --c15t-devtools-badge-success-bg: #21c45d33;
1340
1604
  --c15t-devtools-badge-error-bg: #ef434333;
1341
1605
  --c15t-devtools-badge-warning-bg: #f59f0a33;
@@ -1863,7 +2127,7 @@ var __webpack_exports__ = {};
1863
2127
  type: options.type ?? 'button'
1864
2128
  });
1865
2129
  }
1866
- function span(options = {}) {
2130
+ function renderer_span(options = {}) {
1867
2131
  return createElement({
1868
2132
  ...options,
1869
2133
  tag: 'span'
@@ -1942,7 +2206,8 @@ var __webpack_exports__ = {};
1942
2206
  panel_module_options.insertStyleElement = insertStyleElement_default();
1943
2207
  injectStylesIntoStyleTag_default()(panel_module.A, panel_module_options);
1944
2208
  const styles_panel_module = panel_module.A && panel_module.A.locals ? panel_module.A.locals : void 0;
1945
- const PREFERENCE_TRIGGER_SELECTORS = '[data-c15t-trigger], [aria-label*="privacy settings"], [aria-label*="preference"]';
2209
+ const PREFERENCE_TRIGGER_SELECTORS = '[data-c15t-trigger], [aria-label*="privacy settings" i], [aria-label*="preference" i]';
2210
+ const PREVIOUS_DISPLAY_ATTR = 'data-c15t-devtools-prev-display';
1946
2211
  function detectPreferenceTrigger() {
1947
2212
  const triggers = document.querySelectorAll(PREFERENCE_TRIGGER_SELECTORS);
1948
2213
  return triggers.length > 0;
@@ -1952,7 +2217,19 @@ var __webpack_exports__ = {};
1952
2217
  }
1953
2218
  function setPreferenceTriggerVisibility(visible) {
1954
2219
  const elements = getPreferenceTriggerElements();
1955
- for (const el of elements)el.style.display = visible ? '' : 'none';
2220
+ for (const el of elements){
2221
+ if (visible) {
2222
+ const previousDisplay = el.getAttribute(PREVIOUS_DISPLAY_ATTR);
2223
+ if (null === previousDisplay) el.style.removeProperty('display');
2224
+ else {
2225
+ el.style.display = previousDisplay;
2226
+ el.removeAttribute(PREVIOUS_DISPLAY_ATTR);
2227
+ }
2228
+ continue;
2229
+ }
2230
+ if (!el.hasAttribute(PREVIOUS_DISPLAY_ATTR)) el.setAttribute(PREVIOUS_DISPLAY_ATTR, el.style.display);
2231
+ el.style.display = 'none';
2232
+ }
1956
2233
  }
1957
2234
  function getPreferenceCenterOpener(namespace = 'c15tStore') {
1958
2235
  const win = window;
@@ -1965,7 +2242,7 @@ var __webpack_exports__ = {};
1965
2242
  }
1966
2243
  return null;
1967
2244
  }
1968
- const version = '2.0.0-rc.3';
2245
+ const version = '2.0.0-rc.4';
1969
2246
  const DEVTOOLS_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 446 445" aria-label="c15t">
1970
2247
  <path fill="currentColor" d="M223.178.313c39.064 0 70.732 31.668 70.732 70.732-.001 39.064-31.668 70.731-70.732 70.731-12.181 0-23.642-3.079-33.649-8.502l-55.689 55.689a70.267 70.267 0 0 1 5.574 13.441h167.531c8.695-29.217 35.762-50.523 67.804-50.523 39.064 0 70.731 31.668 70.731 70.732s-31.668 70.732-70.731 70.732c-32.042 0-59.108-21.306-67.803-50.523H139.413a70.417 70.417 0 0 1-7.888 17.396l54.046 54.046c10.893-6.851 23.786-10.815 37.605-10.815 39.064 0 70.732 31.669 70.732 70.733 0 39.064-31.668 70.731-70.732 70.731s-70.732-31.667-70.732-70.731c0-10.518 2.296-20.499 6.414-29.471l-57.78-57.78c-8.972 4.117-18.952 6.414-29.47 6.414-39.063 0-70.731-31.668-70.732-70.732 0-39.064 31.669-70.732 70.733-70.732 12.18 0 23.642 3.079 33.649 8.502l55.688-55.688c-5.423-10.007-8.502-21.469-8.502-33.65 0-39.064 31.668-70.733 70.732-70.733Zm0 343.555c-16.742 0-30.314 13.572-30.314 30.314 0 16.741 13.572 30.313 30.314 30.313s30.314-13.572 30.314-30.313c0-16.742-13.572-30.314-30.314-30.314ZM71.611 192.299c-16.742 0-30.315 13.572-30.315 30.314s13.573 30.314 30.315 30.314c16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314Zm303.138 0c-16.729 0-30.294 13.551-30.315 30.275l.001.039-.001.038c.021 16.725 13.586 30.276 30.315 30.276 16.741 0 30.313-13.572 30.313-30.314 0-16.741-13.572-30.314-30.313-30.314ZM223.178 40.73c-16.742 0-30.314 13.573-30.314 30.315s13.573 30.313 30.314 30.313c16.742 0 30.313-13.572 30.314-30.313 0-16.742-13.572-30.314-30.314-30.315Z"/>
1971
2248
  </svg>`;
@@ -2046,7 +2323,7 @@ var __webpack_exports__ = {};
2046
2323
  const labelContainer = renderer_div({
2047
2324
  className: styles_panel_module.menuItemContent ?? ''
2048
2325
  });
2049
- const label = span({
2326
+ const label = renderer_span({
2050
2327
  className: styles_panel_module.menuItemLabel ?? '',
2051
2328
  text: item.label
2052
2329
  });
@@ -2168,6 +2445,11 @@ var __webpack_exports__ = {};
2168
2445
  return styles_panel_module.positionTopLeft ?? '';
2169
2446
  }
2170
2447
  }
2448
+ function formatRetryDelay(delayMs) {
2449
+ if (null === delayMs) return 'n/a';
2450
+ if (delayMs < 1000) return `${delayMs}ms`;
2451
+ return `${(delayMs / 1000).toFixed(1)}s`;
2452
+ }
2171
2453
  function createPanel(options) {
2172
2454
  const { stateManager, storeConnector, onRenderContent, namespace = 'c15tStore', enableUnifiedMode = true } = options;
2173
2455
  let removePortal = null;
@@ -2299,7 +2581,7 @@ var __webpack_exports__ = {};
2299
2581
  }));
2300
2582
  return logoWrapper;
2301
2583
  })(),
2302
- span({
2584
+ renderer_span({
2303
2585
  text: 'c15t DevTools'
2304
2586
  })
2305
2587
  ]
@@ -2343,38 +2625,41 @@ var __webpack_exports__ = {};
2343
2625
  const isConnected = storeConnector.isConnected();
2344
2626
  const storeState = storeConnector.getState();
2345
2627
  const isLoading = storeState?.isLoadingConsentInfo ?? false;
2628
+ const diagnostics = storeConnector.getDiagnostics();
2346
2629
  const statusChildren = [
2347
- span({
2630
+ renderer_span({
2348
2631
  className: `${styles_panel_module.statusDot} ${isConnected ? styles_panel_module.statusConnected : styles_panel_module.statusDisconnected}`
2349
2632
  }),
2350
- span({
2633
+ renderer_span({
2351
2634
  text: isConnected ? 'Connected' : 'Disconnected'
2352
2635
  })
2353
2636
  ];
2354
- if (isLoading) statusChildren.push(span({
2355
- style: {
2356
- marginLeft: '4px',
2357
- opacity: '0.7'
2358
- },
2637
+ if (isLoading) statusChildren.push(renderer_span({
2638
+ className: styles_panel_module.footerMeta,
2359
2639
  text: '\u00b7 Fetching /init\u2026'
2360
2640
  }));
2641
+ else if (!isConnected) statusChildren.push(renderer_span({
2642
+ className: styles_panel_module.footerMeta,
2643
+ text: `· ${diagnostics.namespace} · retry ${diagnostics.reconnectAttempts} · next ${formatRetryDelay(diagnostics.nextRetryInMs)}`
2644
+ }));
2361
2645
  footerElement.appendChild(renderer_div({
2362
2646
  className: styles_panel_module.footerStatus,
2363
2647
  children: statusChildren
2364
2648
  }));
2365
2649
  if (!isConnected) footerElement.appendChild(renderer_button({
2366
- className: styles_panel_module.closeButton,
2650
+ className: styles_panel_module.inlineActionButton,
2367
2651
  text: 'Retry',
2368
2652
  onClick: ()=>{
2369
2653
  storeConnector.retryConnection();
2370
2654
  }
2371
2655
  }));
2372
- footerElement.appendChild(span({
2656
+ footerElement.appendChild(renderer_span({
2373
2657
  text: `v${version}`
2374
2658
  }));
2375
2659
  }
2376
2660
  function renderErrorState(container) {
2377
2661
  clearElement(container);
2662
+ const diagnostics = storeConnector.getDiagnostics();
2378
2663
  const errorState = renderer_div({
2379
2664
  className: styles_panel_module.errorState,
2380
2665
  children: [
@@ -2396,8 +2681,25 @@ var __webpack_exports__ = {};
2396
2681
  className: styles_panel_module.errorMessage,
2397
2682
  text: 'c15t consent manager is not initialized. Make sure you have set up the ConsentManagerProvider in your app.'
2398
2683
  }),
2684
+ renderer_div({
2685
+ className: styles_panel_module.errorMessage,
2686
+ style: {
2687
+ marginTop: '4px',
2688
+ fontSize: 'var(--c15t-devtools-font-size-xs)'
2689
+ },
2690
+ text: `Namespace: ${diagnostics.namespace} · Retries: ${diagnostics.reconnectAttempts} · Next retry: ${formatRetryDelay(diagnostics.nextRetryInMs)}`
2691
+ }),
2692
+ diagnostics.lastError ? renderer_div({
2693
+ className: styles_panel_module.errorMessage,
2694
+ style: {
2695
+ marginTop: '4px',
2696
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
2697
+ color: 'var(--c15t-text-muted)'
2698
+ },
2699
+ text: `Last error: ${diagnostics.lastError}`
2700
+ }) : null,
2399
2701
  renderer_button({
2400
- className: styles_panel_module.closeButton,
2702
+ className: styles_panel_module.inlineActionButton,
2401
2703
  text: 'Retry Connection',
2402
2704
  onClick: ()=>{
2403
2705
  storeConnector.retryConnection();
@@ -2460,6 +2762,10 @@ var __webpack_exports__ = {};
2460
2762
  if (contentContainer) if (storeConnector.isConnected()) onRenderContent(contentContainer);
2461
2763
  else renderErrorState(contentContainer);
2462
2764
  });
2765
+ const unsubscribeDiagnostics = storeConnector.subscribeDiagnostics(()=>{
2766
+ updateFooter();
2767
+ if (contentContainer && !storeConnector.isConnected()) renderErrorState(contentContainer);
2768
+ });
2463
2769
  container.appendChild(floatingButton);
2464
2770
  removePortal = createPortal(container);
2465
2771
  return {
@@ -2469,6 +2775,7 @@ var __webpack_exports__ = {};
2469
2775
  destroy: ()=>{
2470
2776
  unsubscribeState();
2471
2777
  unsubscribeStore();
2778
+ unsubscribeDiagnostics();
2472
2779
  if (dropdownMenu) {
2473
2780
  dropdownMenu.destroy();
2474
2781
  dropdownMenu = null;
@@ -2517,6 +2824,11 @@ var __webpack_exports__ = {};
2517
2824
  const EVENTS_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2518
2825
  <path d="M12 20h9"></path>
2519
2826
  <path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"></path>
2827
+ </svg>`;
2828
+ const MORE_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
2829
+ <circle cx="12" cy="5" r="1.75"></circle>
2830
+ <circle cx="12" cy="12" r="1.75"></circle>
2831
+ <circle cx="12" cy="19" r="1.75"></circle>
2520
2832
  </svg>`;
2521
2833
  const TABS = [
2522
2834
  {
@@ -2553,12 +2865,56 @@ var __webpack_exports__ = {};
2553
2865
  function createTabs(options) {
2554
2866
  const { onTabChange, disabledTabs = [] } = options;
2555
2867
  let activeTab = options.activeTab;
2868
+ let isOverflowMenuOpen = false;
2869
+ let visibleTabIds = [];
2870
+ let hiddenTabIds = [];
2556
2871
  const tabButtons = new Map();
2872
+ const overflowButtons = new Map();
2557
2873
  const tabList = renderer_div({
2558
- className: styles_tabs_module.tabList,
2874
+ className: styles_tabs_module.tabList
2875
+ });
2876
+ const tabStrip = renderer_div({
2877
+ className: styles_tabs_module.tabStrip,
2559
2878
  role: 'tablist',
2560
2879
  ariaLabel: 'DevTools tabs'
2561
2880
  });
2881
+ tabList.appendChild(tabStrip);
2882
+ const overflowMenu = renderer_div({
2883
+ className: styles_tabs_module.overflowMenu,
2884
+ role: 'menu',
2885
+ ariaLabel: 'All tabs'
2886
+ });
2887
+ overflowMenu.dataset.state = 'closed';
2888
+ const overflowButton = renderer_button({
2889
+ className: styles_tabs_module.overflowButton,
2890
+ ariaLabel: 'More tabs',
2891
+ ariaExpanded: 'false',
2892
+ onClick: ()=>toggleOverflowMenu(),
2893
+ onKeyDown: (e)=>{
2894
+ if ('ArrowDown' === e.key || 'Enter' === e.key || ' ' === e.key) {
2895
+ e.preventDefault();
2896
+ openOverflowMenu();
2897
+ focusFirstEnabledOverflowItem();
2898
+ }
2899
+ }
2900
+ });
2901
+ overflowButton.setAttribute('aria-haspopup', 'menu');
2902
+ const overflowIcon = renderer_div({
2903
+ className: styles_tabs_module.overflowButtonIcon
2904
+ });
2905
+ overflowIcon.appendChild(createSvgElement(MORE_ICON, {
2906
+ width: 14,
2907
+ height: 14
2908
+ }));
2909
+ overflowButton.appendChild(overflowIcon);
2910
+ const overflowContainer = renderer_div({
2911
+ className: styles_tabs_module.overflowContainer,
2912
+ children: [
2913
+ overflowButton,
2914
+ overflowMenu
2915
+ ]
2916
+ });
2917
+ tabList.appendChild(overflowContainer);
2562
2918
  for (const tab of TABS){
2563
2919
  const isActive = tab.id === activeTab;
2564
2920
  const isDisabled = disabledTabs.includes(tab.id);
@@ -2572,6 +2928,7 @@ var __webpack_exports__ = {};
2572
2928
  disabled: isDisabled,
2573
2929
  onClick: ()=>{
2574
2930
  if (!isDisabled) {
2931
+ closeOverflowMenu();
2575
2932
  setActiveTab(tab.id);
2576
2933
  onTabChange(tab.id);
2577
2934
  }
@@ -2588,12 +2945,189 @@ var __webpack_exports__ = {};
2588
2945
  tabButton.appendChild(iconWrapper);
2589
2946
  tabButton.appendChild(document.createTextNode(tab.label));
2590
2947
  tabButtons.set(tab.id, tabButton);
2591
- tabList.appendChild(tabButton);
2948
+ tabStrip.appendChild(tabButton);
2949
+ const overflowItem = renderer_button({
2950
+ className: `${styles_tabs_module.overflowItem} ${isActive ? styles_tabs_module.overflowItemActive : ''} ${isDisabled ? styles_tabs_module.overflowItemDisabled : ''}`,
2951
+ role: 'menuitemradio',
2952
+ ariaChecked: isActive ? 'true' : 'false',
2953
+ disabled: isDisabled,
2954
+ onClick: ()=>{
2955
+ if (!isDisabled) {
2956
+ setActiveTab(tab.id);
2957
+ onTabChange(tab.id);
2958
+ closeOverflowMenu();
2959
+ tabButtons.get(tab.id)?.focus();
2960
+ }
2961
+ },
2962
+ onKeyDown: (e)=>handleOverflowKeyDown(e, tab.id)
2963
+ });
2964
+ const overflowItemIcon = renderer_div({
2965
+ className: styles_tabs_module.overflowItemIcon
2966
+ });
2967
+ overflowItemIcon.appendChild(createSvgElement(tab.icon, {
2968
+ width: 14,
2969
+ height: 14
2970
+ }));
2971
+ overflowItem.appendChild(overflowItemIcon);
2972
+ overflowItem.appendChild(document.createTextNode(tab.label));
2973
+ overflowButtons.set(tab.id, overflowItem);
2974
+ overflowMenu.appendChild(overflowItem);
2592
2975
  }
2593
- function handleKeyDown(e, currentTab) {
2594
- const tabIds = TABS.map((t)=>t.id);
2595
- const enabledTabIds = tabIds.filter((id)=>!disabledTabs.includes(id));
2596
- const currentIndex = enabledTabIds.indexOf(currentTab);
2976
+ function applyActiveState(tab) {
2977
+ for (const [tabId, tabButton] of tabButtons){
2978
+ const isActive = tabId === tab;
2979
+ if (styles_tabs_module.tabActive) tabButton.classList.toggle(styles_tabs_module.tabActive, isActive);
2980
+ tabButton.setAttribute('aria-selected', isActive ? 'true' : 'false');
2981
+ tabButton.tabIndex = isActive ? 0 : -1;
2982
+ }
2983
+ for (const [tabId, overflowItem] of overflowButtons){
2984
+ const isActive = tabId === tab;
2985
+ if (styles_tabs_module.overflowItemActive) overflowItem.classList.toggle(styles_tabs_module.overflowItemActive, isActive);
2986
+ overflowItem.setAttribute('aria-checked', isActive ? 'true' : 'false');
2987
+ }
2988
+ }
2989
+ function updateVisibleTabs() {
2990
+ const allTabIds = TABS.map((t)=>t.id);
2991
+ const iabEnabled = !disabledTabs.includes('iab');
2992
+ const preferredSecondTab = iabEnabled ? 'iab' : 'consents';
2993
+ const overflowSecondTab = iabEnabled ? 'consents' : 'iab';
2994
+ const showOverflowSecondTabInStrip = activeTab === overflowSecondTab;
2995
+ const stripSecondTab = showOverflowSecondTabInStrip ? overflowSecondTab : preferredSecondTab;
2996
+ const forcedOverflowTab = showOverflowSecondTabInStrip ? preferredSecondTab : overflowSecondTab;
2997
+ const layoutTabIds = [
2998
+ 'location',
2999
+ stripSecondTab,
3000
+ "scripts",
3001
+ 'actions',
3002
+ 'events',
3003
+ forcedOverflowTab
3004
+ ];
3005
+ const forcedOverflowTabIds = new Set();
3006
+ forcedOverflowTabIds.add(forcedOverflowTab);
3007
+ for (const [index, tabId] of layoutTabIds.entries()){
3008
+ const tabButton = tabButtons.get(tabId);
3009
+ if (tabButton) tabButton.style.order = String(index);
3010
+ const overflowItem = overflowButtons.get(tabId);
3011
+ if (overflowItem) overflowItem.style.order = String(index);
3012
+ }
3013
+ for (const tabId of allTabIds){
3014
+ const tabButton = tabButtons.get(tabId);
3015
+ if (tabButton && styles_tabs_module.tabHidden) tabButton.classList.remove(styles_tabs_module.tabHidden);
3016
+ }
3017
+ if (styles_tabs_module.overflowContainerHidden) overflowContainer.classList.remove(styles_tabs_module.overflowContainerHidden);
3018
+ const stripGap = Number.parseFloat(getComputedStyle(tabStrip).gap || '0');
3019
+ const calculateVisibleTabs = (availableWidth)=>{
3020
+ if (availableWidth <= 0) return [];
3021
+ const nextVisible = [];
3022
+ let usedWidth = 0;
3023
+ for (const tabId of layoutTabIds){
3024
+ if (forcedOverflowTabIds.has(tabId)) continue;
3025
+ const tabButton = tabButtons.get(tabId);
3026
+ if (!tabButton) continue;
3027
+ const width = tabButton.getBoundingClientRect().width;
3028
+ const nextUsed = 0 === nextVisible.length ? width : usedWidth + stripGap + width;
3029
+ if (nextUsed <= availableWidth) {
3030
+ nextVisible.push(tabId);
3031
+ usedWidth = nextUsed;
3032
+ } else break;
3033
+ }
3034
+ return nextVisible;
3035
+ };
3036
+ const measureStripWidth = ()=>tabStrip.getBoundingClientRect().width;
3037
+ const showOverflowContainer = ()=>{
3038
+ if (styles_tabs_module.overflowContainerHidden) overflowContainer.classList.remove(styles_tabs_module.overflowContainerHidden);
3039
+ };
3040
+ const hideOverflowContainer = ()=>{
3041
+ if (styles_tabs_module.overflowContainerHidden) overflowContainer.classList.add(styles_tabs_module.overflowContainerHidden);
3042
+ };
3043
+ const measureVisibleWidth = (tabIds)=>{
3044
+ let width = 0;
3045
+ for (const [index, tabId] of tabIds.entries()){
3046
+ const tabButton = tabButtons.get(tabId);
3047
+ if (tabButton) {
3048
+ width += tabButton.getBoundingClientRect().width;
3049
+ if (index > 0) width += stripGap;
3050
+ }
3051
+ }
3052
+ return width;
3053
+ };
3054
+ if (0 === forcedOverflowTabIds.size) {
3055
+ hideOverflowContainer();
3056
+ const visibleWithoutOverflow = calculateVisibleTabs(measureStripWidth());
3057
+ if (visibleWithoutOverflow.length === layoutTabIds.length) visibleTabIds = visibleWithoutOverflow;
3058
+ else {
3059
+ showOverflowContainer();
3060
+ visibleTabIds = calculateVisibleTabs(measureStripWidth());
3061
+ }
3062
+ } else {
3063
+ showOverflowContainer();
3064
+ const withOverflow = calculateVisibleTabs(measureStripWidth());
3065
+ visibleTabIds = withOverflow.length > 0 ? withOverflow : [
3066
+ activeTab
3067
+ ];
3068
+ }
3069
+ if (!visibleTabIds.includes(activeTab) && !disabledTabs.includes(activeTab)) if (visibleTabIds.length > 0) visibleTabIds[visibleTabIds.length - 1] = activeTab;
3070
+ else visibleTabIds = [
3071
+ activeTab
3072
+ ];
3073
+ visibleTabIds = [
3074
+ ...new Set(visibleTabIds)
3075
+ ];
3076
+ const maxStripWidth = measureStripWidth();
3077
+ while(visibleTabIds.length > 1 && measureVisibleWidth(visibleTabIds) > maxStripWidth + 0.5){
3078
+ let removeIndex = visibleTabIds.length - 1;
3079
+ if (visibleTabIds[removeIndex] === activeTab) removeIndex = Math.max(0, removeIndex - 1);
3080
+ visibleTabIds.splice(removeIndex, 1);
3081
+ }
3082
+ hiddenTabIds = layoutTabIds.filter((tabId)=>!visibleTabIds.includes(tabId) || forcedOverflowTabIds.has(tabId) && tabId !== activeTab);
3083
+ for (const tabId of allTabIds){
3084
+ const tabButton = tabButtons.get(tabId);
3085
+ if (tabButton) {
3086
+ if (styles_tabs_module.tabHidden) tabButton.classList.toggle(styles_tabs_module.tabHidden, hiddenTabIds.includes(tabId));
3087
+ }
3088
+ }
3089
+ for (const tabId of allTabIds){
3090
+ const overflowItem = overflowButtons.get(tabId);
3091
+ if (overflowItem) {
3092
+ if (styles_tabs_module.overflowItemHidden) overflowItem.classList.toggle(styles_tabs_module.overflowItemHidden, !hiddenTabIds.includes(tabId));
3093
+ }
3094
+ }
3095
+ if (styles_tabs_module.overflowContainerHidden) overflowContainer.classList.toggle(styles_tabs_module.overflowContainerHidden, 0 === hiddenTabIds.length);
3096
+ if (0 === hiddenTabIds.length) closeOverflowMenu();
3097
+ }
3098
+ function focusFirstEnabledOverflowItem() {
3099
+ const firstEnabled = hiddenTabIds.find((tabId)=>!disabledTabs.includes(tabId));
3100
+ if (firstEnabled) overflowButtons.get(firstEnabled)?.focus();
3101
+ }
3102
+ function openOverflowMenu() {
3103
+ if (isOverflowMenuOpen || 0 === hiddenTabIds.length) return;
3104
+ isOverflowMenuOpen = true;
3105
+ overflowMenu.dataset.state = 'open';
3106
+ overflowButton.setAttribute('aria-expanded', 'true');
3107
+ document.addEventListener('click', handleOutsideClick);
3108
+ document.addEventListener('keydown', handleEscapeKey);
3109
+ }
3110
+ function closeOverflowMenu() {
3111
+ if (!isOverflowMenuOpen) return;
3112
+ isOverflowMenuOpen = false;
3113
+ overflowMenu.dataset.state = 'closed';
3114
+ overflowButton.setAttribute('aria-expanded', 'false');
3115
+ document.removeEventListener('click', handleOutsideClick);
3116
+ document.removeEventListener('keydown', handleEscapeKey);
3117
+ }
3118
+ function toggleOverflowMenu() {
3119
+ if (isOverflowMenuOpen) closeOverflowMenu();
3120
+ else openOverflowMenu();
3121
+ }
3122
+ function handleOutsideClick(e) {
3123
+ if (!overflowContainer.contains(e.target)) closeOverflowMenu();
3124
+ }
3125
+ function handleEscapeKey(e) {
3126
+ if ('Escape' === e.key) closeOverflowMenu();
3127
+ }
3128
+ function handleKeyDown(e, currentTab) {
3129
+ const enabledTabIds = visibleTabIds.filter((tabId)=>!disabledTabs.includes(tabId));
3130
+ const currentIndex = enabledTabIds.indexOf(currentTab);
2597
3131
  let newIndex = currentIndex;
2598
3132
  switch(e.key){
2599
3133
  case 'ArrowLeft':
@@ -2619,23 +3153,152 @@ var __webpack_exports__ = {};
2619
3153
  tabButtons.get(newTab)?.focus();
2620
3154
  }
2621
3155
  }
3156
+ function handleOverflowKeyDown(e, currentTab) {
3157
+ const enabledTabIds = hiddenTabIds.filter((tabId)=>!disabledTabs.includes(tabId));
3158
+ const currentIndex = enabledTabIds.indexOf(currentTab);
3159
+ if ('Escape' === e.key) {
3160
+ e.preventDefault();
3161
+ closeOverflowMenu();
3162
+ overflowButton.focus();
3163
+ return;
3164
+ }
3165
+ let newIndex = currentIndex;
3166
+ switch(e.key){
3167
+ case 'ArrowDown':
3168
+ newIndex = (currentIndex + 1) % enabledTabIds.length;
3169
+ break;
3170
+ case 'ArrowUp':
3171
+ newIndex = currentIndex > 0 ? currentIndex - 1 : enabledTabIds.length - 1;
3172
+ break;
3173
+ default:
3174
+ return;
3175
+ }
3176
+ e.preventDefault();
3177
+ const newTab = enabledTabIds[newIndex];
3178
+ if (newTab) overflowButtons.get(newTab)?.focus();
3179
+ }
2622
3180
  function setActiveTab(tab) {
2623
3181
  activeTab = tab;
2624
- for (const [tabId, tabButton] of tabButtons){
2625
- const isActive = tabId === tab;
2626
- if (styles_tabs_module.tabActive) tabButton.classList.toggle(styles_tabs_module.tabActive, isActive);
2627
- tabButton.setAttribute('aria-selected', isActive ? 'true' : 'false');
2628
- tabButton.tabIndex = isActive ? 0 : -1;
2629
- }
3182
+ applyActiveState(tab);
3183
+ updateVisibleTabs();
2630
3184
  }
3185
+ const handleWindowResize = ()=>{
3186
+ updateVisibleTabs();
3187
+ };
3188
+ let resizeObserver = null;
3189
+ if ('undefined' != typeof ResizeObserver) {
3190
+ resizeObserver = new ResizeObserver(()=>{
3191
+ updateVisibleTabs();
3192
+ });
3193
+ resizeObserver.observe(tabList);
3194
+ } else window.addEventListener('resize', handleWindowResize);
3195
+ applyActiveState(activeTab);
3196
+ requestAnimationFrame(()=>{
3197
+ updateVisibleTabs();
3198
+ });
2631
3199
  return {
2632
3200
  element: tabList,
2633
3201
  setActiveTab,
2634
3202
  destroy: ()=>{
3203
+ closeOverflowMenu();
3204
+ if (resizeObserver) {
3205
+ resizeObserver.disconnect();
3206
+ resizeObserver = null;
3207
+ } else window.removeEventListener('resize', handleWindowResize);
2635
3208
  tabButtons.clear();
3209
+ overflowButtons.clear();
2636
3210
  }
2637
3211
  };
2638
3212
  }
3213
+ function createDebugBundle(payload) {
3214
+ const { namespace, devToolsState, connection, recentEvents, storeState } = payload;
3215
+ const bundle = {
3216
+ generatedAt: new Date().toISOString(),
3217
+ namespace,
3218
+ devToolsState,
3219
+ connection,
3220
+ recentEvents,
3221
+ storeState,
3222
+ overrides: storeState?.overrides ?? null,
3223
+ iab: storeState?.iab ? {
3224
+ tcString: (storeState?.iab).tcString ?? null,
3225
+ purposeCount: Object.keys((storeState?.iab).purposeConsents ?? {}).length,
3226
+ vendorCount: Object.keys((storeState?.iab).vendorConsents ?? {}).length
3227
+ } : null
3228
+ };
3229
+ return JSON.stringify(bundle, null, 2);
3230
+ }
3231
+ function sanitizeStoreState(state) {
3232
+ if (!state) return null;
3233
+ try {
3234
+ return JSON.parse(JSON.stringify(state, (_key, value)=>'function' == typeof value ? void 0 : value));
3235
+ } catch {
3236
+ return {
3237
+ error: 'Unable to serialize store state'
3238
+ };
3239
+ }
3240
+ }
3241
+ function downloadDebugBundle(content) {
3242
+ const blob = new Blob([
3243
+ content
3244
+ ], {
3245
+ type: 'application/json'
3246
+ });
3247
+ const url = URL.createObjectURL(blob);
3248
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
3249
+ const anchor = document.createElement('a');
3250
+ anchor.href = url;
3251
+ anchor.download = `c15t-debug-bundle-${timestamp}.json`;
3252
+ anchor.click();
3253
+ URL.revokeObjectURL(url);
3254
+ }
3255
+ const DEVTOOLS_OVERRIDES_STORAGE_KEY = 'c15t-devtools-overrides';
3256
+ function normalizeStringValue(value) {
3257
+ if ('string' != typeof value) return;
3258
+ const normalized = value.trim();
3259
+ return normalized.length > 0 ? normalized : void 0;
3260
+ }
3261
+ function normalizeBooleanValue(value) {
3262
+ return 'boolean' == typeof value ? value : void 0;
3263
+ }
3264
+ function normalizeOverrides(value) {
3265
+ if (!value || 'object' != typeof value) return null;
3266
+ const source = value;
3267
+ const overrides = {
3268
+ country: normalizeStringValue(source.country),
3269
+ region: normalizeStringValue(source.region),
3270
+ language: normalizeStringValue(source.language),
3271
+ gpc: normalizeBooleanValue(source.gpc)
3272
+ };
3273
+ return hasPersistedOverrides(overrides) ? overrides : null;
3274
+ }
3275
+ function hasPersistedOverrides(overrides) {
3276
+ return Boolean(overrides.country || overrides.region || overrides.language || void 0 !== overrides.gpc);
3277
+ }
3278
+ function loadPersistedOverrides(storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
3279
+ if ('undefined' == typeof window) return null;
3280
+ try {
3281
+ const stored = localStorage.getItem(storageKey);
3282
+ if (!stored) return null;
3283
+ const parsed = JSON.parse(stored);
3284
+ return normalizeOverrides(parsed);
3285
+ } catch {
3286
+ return null;
3287
+ }
3288
+ }
3289
+ function persistOverrides(overrides, storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
3290
+ if ('undefined' == typeof window) return;
3291
+ try {
3292
+ if (!hasPersistedOverrides(overrides)) return void localStorage.removeItem(storageKey);
3293
+ localStorage.setItem(storageKey, JSON.stringify(overrides));
3294
+ } catch {}
3295
+ }
3296
+ function clearPersistedOverrides(storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
3297
+ if ('undefined' == typeof window) return;
3298
+ try {
3299
+ localStorage.removeItem(storageKey);
3300
+ } catch {}
3301
+ }
2639
3302
  var components_module = __webpack_require__("../../node_modules/.bun/@rsbuild+core@1.6.12/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles/components.module.css");
2640
3303
  var components_module_options = {};
2641
3304
  components_module_options.styleTagTransform = styleTagTransform_default();
@@ -2672,7 +3335,7 @@ var __webpack_exports__ = {};
2672
3335
  info: styles_components_module.badgeInfo,
2673
3336
  neutral: styles_components_module.badgeNeutral
2674
3337
  }[variant];
2675
- return span({
3338
+ return renderer_span({
2676
3339
  className: `${styles_components_module.badge} ${variantClass}`,
2677
3340
  text
2678
3341
  });
@@ -2703,31 +3366,19 @@ var __webpack_exports__ = {};
2703
3366
  btn.appendChild(document.createTextNode(text));
2704
3367
  return btn;
2705
3368
  }
2706
- function createListItem(options) {
2707
- const { title, description, actions = [] } = options;
2708
- const content = renderer_div({
2709
- className: styles_components_module.listItemContent,
2710
- children: [
2711
- span({
2712
- className: styles_components_module.listItemTitle,
2713
- text: title
2714
- }),
2715
- description ? span({
2716
- className: styles_components_module.listItemDescription,
2717
- text: description
2718
- }) : null
2719
- ]
2720
- });
2721
- const actionsContainer = renderer_div({
2722
- className: styles_components_module.listItemActions,
2723
- children: actions
2724
- });
2725
- return renderer_div({
2726
- className: styles_components_module.listItem,
2727
- children: [
2728
- content,
2729
- actionsContainer
2730
- ]
3369
+ function createInput(options) {
3370
+ const { value, placeholder, ariaLabel, small = false, onInput } = options;
3371
+ const sizeClass = small ? styles_components_module.inputSmall : '';
3372
+ return input({
3373
+ className: `${styles_components_module.input} ${sizeClass}`.trim(),
3374
+ type: 'text',
3375
+ value,
3376
+ placeholder,
3377
+ ariaLabel,
3378
+ onInput: (event)=>{
3379
+ const target = event.target;
3380
+ onInput?.(target?.value ?? '');
3381
+ }
2731
3382
  });
2732
3383
  }
2733
3384
  function createSection(options) {
@@ -2735,7 +3386,7 @@ var __webpack_exports__ = {};
2735
3386
  const header = renderer_div({
2736
3387
  className: styles_components_module.sectionHeader,
2737
3388
  children: [
2738
- span({
3389
+ renderer_span({
2739
3390
  className: styles_components_module.sectionTitle,
2740
3391
  text: title
2741
3392
  }),
@@ -2755,11 +3406,11 @@ var __webpack_exports__ = {};
2755
3406
  return renderer_div({
2756
3407
  className: styles_components_module.infoRow,
2757
3408
  children: [
2758
- span({
3409
+ renderer_span({
2759
3410
  className: styles_components_module.infoLabel,
2760
3411
  text: label
2761
3412
  }),
2762
- span({
3413
+ renderer_span({
2763
3414
  className: styles_components_module.infoValue,
2764
3415
  text: value
2765
3416
  })
@@ -2779,7 +3430,7 @@ var __webpack_exports__ = {};
2779
3430
  }));
2780
3431
  children.push(iconWrapper);
2781
3432
  }
2782
- children.push(span({
3433
+ children.push(renderer_span({
2783
3434
  className: styles_components_module.emptyStateText,
2784
3435
  text
2785
3436
  }));
@@ -2799,7 +3450,7 @@ var __webpack_exports__ = {};
2799
3450
  function createGridCard(options) {
2800
3451
  const { title, action } = options;
2801
3452
  const children = [
2802
- span({
3453
+ renderer_span({
2803
3454
  className: styles_components_module.gridCardTitle,
2804
3455
  text: title
2805
3456
  })
@@ -2810,6 +3461,18 @@ var __webpack_exports__ = {};
2810
3461
  children
2811
3462
  });
2812
3463
  }
3464
+ function createDisconnectedState(message = 'Store not connected') {
3465
+ return renderer_div({
3466
+ className: styles_components_module.disconnectedState,
3467
+ style: {
3468
+ padding: '24px',
3469
+ textAlign: 'center',
3470
+ color: 'var(--c15t-text-muted)',
3471
+ fontSize: 'var(--c15t-devtools-font-size-sm)'
3472
+ },
3473
+ text: message
3474
+ });
3475
+ }
2813
3476
  const REFRESH_ICON = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
2814
3477
  <path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path>
2815
3478
  <path d="M21 3v5h-5"></path>
@@ -2838,18 +3501,10 @@ var __webpack_exports__ = {};
2838
3501
  <line x1="12" y1="19" x2="20" y2="19"></line>
2839
3502
  </svg>`;
2840
3503
  function renderActionsPanel(container, options) {
2841
- const { getState, onResetConsents, onRefetchBanner, onShowBanner, onOpenPreferences, onCopyState } = options;
3504
+ const { getState, onResetConsents, onRefetchBanner, onShowBanner, onOpenPreferences, onCopyState, onExportDebugBundle } = options;
2842
3505
  clearElement(container);
2843
3506
  const state = getState();
2844
- if (!state) return void container.appendChild(renderer_div({
2845
- style: {
2846
- padding: '24px',
2847
- textAlign: 'center',
2848
- color: 'var(--c15t-text-muted)',
2849
- fontSize: 'var(--c15t-devtools-font-size-sm)'
2850
- },
2851
- text: 'Store not connected'
2852
- }));
3507
+ if (!state) return void container.appendChild(createDisconnectedState());
2853
3508
  const actionCards = [
2854
3509
  createActionCard({
2855
3510
  icon: actions_EYE_ICON,
@@ -2870,6 +3525,12 @@ var __webpack_exports__ = {};
2870
3525
  icon: COPY_ICON,
2871
3526
  label: 'Copy State',
2872
3527
  onClick: onCopyState
3528
+ }),
3529
+ createActionCard({
3530
+ icon: REFRESH_ICON,
3531
+ label: 'Export Debug',
3532
+ onClick: ()=>onExportDebugBundle?.(),
3533
+ disabled: !onExportDebugBundle
2873
3534
  })
2874
3535
  ];
2875
3536
  const grid = createGrid({
@@ -2907,7 +3568,7 @@ var __webpack_exports__ = {};
2907
3568
  },
2908
3569
  children: [
2909
3570
  createIconWrapper(TERMINAL_ICON, 14),
2910
- span({
3571
+ renderer_span({
2911
3572
  style: {
2912
3573
  fontSize: 'var(--c15t-devtools-font-size-xs)',
2913
3574
  fontWeight: '600',
@@ -2930,10 +3591,10 @@ var __webpack_exports__ = {};
2930
3591
  color: 'var(--c15t-text-muted)'
2931
3592
  },
2932
3593
  children: [
2933
- span({
3594
+ renderer_span({
2934
3595
  text: `window.${getNamespace(state)}.getState()`
2935
3596
  }),
2936
- span({
3597
+ renderer_span({
2937
3598
  text: 'window.__c15tDevTools.open()'
2938
3599
  })
2939
3600
  ]
@@ -2943,7 +3604,7 @@ var __webpack_exports__ = {};
2943
3604
  container.appendChild(consoleSection);
2944
3605
  }
2945
3606
  function createActionCard(options) {
2946
- const { icon, label, onClick } = options;
3607
+ const { icon, label, onClick, disabled = false } = options;
2947
3608
  const card = renderer_div({
2948
3609
  className: styles_components_module.gridCard ?? '',
2949
3610
  style: {
@@ -2954,11 +3615,12 @@ var __webpack_exports__ = {};
2954
3615
  gap: '6px',
2955
3616
  padding: '16px 8px',
2956
3617
  cursor: 'pointer',
2957
- transition: 'background-color var(--c15t-duration-fast) var(--c15t-easing)'
3618
+ transition: 'background-color var(--c15t-duration-fast) var(--c15t-easing)',
3619
+ opacity: disabled ? '0.55' : '1'
2958
3620
  },
2959
3621
  children: [
2960
3622
  createIconWrapper(icon, 20),
2961
- span({
3623
+ renderer_span({
2962
3624
  style: {
2963
3625
  fontSize: 'var(--c15t-devtools-font-size-xs)',
2964
3626
  fontWeight: '500',
@@ -2969,13 +3631,15 @@ var __webpack_exports__ = {};
2969
3631
  })
2970
3632
  ]
2971
3633
  });
2972
- card.addEventListener('click', onClick);
2973
- card.addEventListener('mouseenter', ()=>{
2974
- card.style.backgroundColor = 'var(--c15t-surface-hover)';
2975
- });
2976
- card.addEventListener('mouseleave', ()=>{
2977
- card.style.backgroundColor = '';
2978
- });
3634
+ if (!disabled) {
3635
+ card.addEventListener('click', onClick);
3636
+ card.addEventListener('mouseenter', ()=>{
3637
+ card.style.backgroundColor = 'var(--c15t-surface-hover)';
3638
+ });
3639
+ card.addEventListener('mouseleave', ()=>{
3640
+ card.style.backgroundColor = '';
3641
+ });
3642
+ }
2979
3643
  return card;
2980
3644
  }
2981
3645
  function createIconWrapper(icon, size) {
@@ -2996,19 +3660,12 @@ var __webpack_exports__ = {};
2996
3660
  function getNamespace(state) {
2997
3661
  return state.config?.meta?.namespace || 'c15tStore';
2998
3662
  }
3663
+ const consentSearchByContainer = new WeakMap();
2999
3664
  function renderConsentsPanel(container, options) {
3000
3665
  const { getState, onConsentChange, onSave, onAcceptAll, onRejectAll, onReset } = options;
3001
3666
  clearElement(container);
3002
3667
  const state = getState();
3003
- if (!state) return void container.appendChild(renderer_div({
3004
- style: {
3005
- padding: '24px',
3006
- textAlign: 'center',
3007
- color: 'var(--c15t-text-muted)',
3008
- fontSize: 'var(--c15t-devtools-font-size-sm)'
3009
- },
3010
- text: 'Store not connected'
3011
- }));
3668
+ if (!state) return void container.appendChild(createDisconnectedState());
3012
3669
  const isIabMode = 'iab' === state.model;
3013
3670
  const savedConsents = state.consents || {};
3014
3671
  const selectedConsents = state.selectedConsents || {};
@@ -3022,15 +3679,40 @@ var __webpack_exports__ = {};
3022
3679
  ct.name,
3023
3680
  ct
3024
3681
  ]));
3682
+ const searchQuery = consentSearchByContainer.get(container) ?? '';
3025
3683
  const consentEntries = Object.entries(displayConsents);
3026
- if (0 === consentEntries.length) container.appendChild(renderer_div({
3684
+ const filteredConsentEntries = consentEntries.filter(([name])=>{
3685
+ if (!searchQuery) return true;
3686
+ const consentType = consentTypeMap.get(name);
3687
+ const displayName = consentType?.name || name;
3688
+ return `${name} ${displayName}`.toLowerCase().includes(searchQuery);
3689
+ });
3690
+ const showSearchInput = consentEntries.length > 4;
3691
+ if (showSearchInput) container.appendChild(renderer_div({
3692
+ style: {
3693
+ padding: '8px 0 10px'
3694
+ },
3695
+ children: [
3696
+ createInput({
3697
+ value: searchQuery,
3698
+ placeholder: 'Filter consents…',
3699
+ ariaLabel: 'Filter consents',
3700
+ small: true,
3701
+ onInput: (value)=>{
3702
+ consentSearchByContainer.set(container, value.trim().toLowerCase());
3703
+ renderConsentsPanel(container, options);
3704
+ }
3705
+ })
3706
+ ]
3707
+ }));
3708
+ if (0 === filteredConsentEntries.length) container.appendChild(renderer_div({
3027
3709
  style: {
3028
3710
  padding: '24px',
3029
3711
  textAlign: 'center',
3030
3712
  color: 'var(--c15t-devtools-text-muted)',
3031
3713
  fontSize: 'var(--c15t-devtools-font-size-sm)'
3032
3714
  },
3033
- text: 'No consents configured'
3715
+ text: 0 === consentEntries.length ? 'No consents configured' : 'No matching consents'
3034
3716
  }));
3035
3717
  else {
3036
3718
  if (isIabMode) {
@@ -3048,7 +3730,7 @@ var __webpack_exports__ = {};
3048
3730
  container.appendChild(iabNotice);
3049
3731
  }
3050
3732
  const gridCards = [];
3051
- for (const [name, value] of consentEntries){
3733
+ for (const [name, value] of filteredConsentEntries){
3052
3734
  const consentType = consentTypeMap.get(name);
3053
3735
  const isNecessary = 'necessary' === name;
3054
3736
  const displayName = consentType?.name || name;
@@ -3138,7 +3820,7 @@ var __webpack_exports__ = {};
3138
3820
  gap: '8px'
3139
3821
  },
3140
3822
  children: [
3141
- span({
3823
+ renderer_span({
3142
3824
  style: {
3143
3825
  fontSize: 'var(--c15t-devtools-font-size-xs)',
3144
3826
  color: 'var(--c15t-devtools-badge-warning)'
@@ -3152,7 +3834,7 @@ var __webpack_exports__ = {};
3152
3834
  onClick: onSave
3153
3835
  })
3154
3836
  ]
3155
- }) : span({
3837
+ }) : renderer_span({
3156
3838
  style: {
3157
3839
  fontSize: 'var(--c15t-devtools-font-size-xs)',
3158
3840
  color: 'var(--c15t-text-muted)'
@@ -3166,15 +3848,26 @@ var __webpack_exports__ = {};
3166
3848
  function formatConsentName(name) {
3167
3849
  return name.replace(/_/g, ' ').replace(/\b\w/g, (l)=>l.toUpperCase());
3168
3850
  }
3169
- let activeFilter = 'all';
3170
- let selectedEventId = null;
3851
+ const panelStateByContainer = new WeakMap();
3852
+ function getPanelState(container) {
3853
+ const existing = panelStateByContainer.get(container);
3854
+ if (existing) return existing;
3855
+ const initialState = {
3856
+ activeFilter: 'all',
3857
+ selectedEventId: null,
3858
+ searchQuery: ''
3859
+ };
3860
+ panelStateByContainer.set(container, initialState);
3861
+ return initialState;
3862
+ }
3171
3863
  function renderEventsPanel(container, options) {
3172
3864
  const { getEvents, onClear } = options;
3865
+ const panelState = getPanelState(container);
3173
3866
  clearElement(container);
3174
3867
  const allEvents = getEvents();
3175
- const events = allEvents.filter((event)=>matchesFilter(event, activeFilter));
3176
- if (!events.some((event)=>event.id === selectedEventId)) selectedEventId = events[0]?.id ?? null;
3177
- const selectedEvent = events.find((event)=>event.id === selectedEventId) ?? null;
3868
+ const events = allEvents.filter((event)=>matchesFilter(event, panelState.activeFilter)).filter((event)=>matchesSearch(event, panelState.searchQuery));
3869
+ if (!events.some((event)=>event.id === panelState.selectedEventId)) panelState.selectedEventId = events[0]?.id ?? null;
3870
+ const selectedEvent = events.find((event)=>event.id === panelState.selectedEventId) ?? null;
3178
3871
  const header = renderer_div({
3179
3872
  style: {
3180
3873
  display: 'flex',
@@ -3184,7 +3877,7 @@ var __webpack_exports__ = {};
3184
3877
  gap: '8px'
3185
3878
  },
3186
3879
  children: [
3187
- span({
3880
+ renderer_span({
3188
3881
  style: {
3189
3882
  fontSize: 'var(--c15t-devtools-font-size-xs)',
3190
3883
  fontWeight: '600',
@@ -3210,7 +3903,7 @@ var __webpack_exports__ = {};
3210
3903
  small: true,
3211
3904
  onClick: ()=>{
3212
3905
  onClear();
3213
- selectedEventId = null;
3906
+ panelState.selectedEventId = null;
3214
3907
  renderEventsPanel(container, options);
3215
3908
  }
3216
3909
  })
@@ -3226,12 +3919,30 @@ var __webpack_exports__ = {};
3226
3919
  gap: '6px',
3227
3920
  padding: '0 16px 8px'
3228
3921
  },
3229
- children: EVENT_FILTERS.map((filter)=>createFilterButton(filter, filter === activeFilter, ()=>{
3230
- activeFilter = filter;
3231
- selectedEventId = null;
3922
+ children: EVENT_FILTERS.map((filter)=>createFilterButton(filter, filter === panelState.activeFilter, ()=>{
3923
+ panelState.activeFilter = filter;
3924
+ panelState.selectedEventId = null;
3232
3925
  renderEventsPanel(container, options);
3233
3926
  }))
3234
3927
  }));
3928
+ container.appendChild(renderer_div({
3929
+ style: {
3930
+ padding: '0 16px 8px'
3931
+ },
3932
+ children: [
3933
+ createInput({
3934
+ value: panelState.searchQuery,
3935
+ placeholder: 'Search events…',
3936
+ ariaLabel: 'Search events',
3937
+ small: true,
3938
+ onInput: (value)=>{
3939
+ panelState.searchQuery = value.trim().toLowerCase();
3940
+ panelState.selectedEventId = null;
3941
+ renderEventsPanel(container, options);
3942
+ }
3943
+ })
3944
+ ]
3945
+ }));
3235
3946
  const eventList = renderer_div({
3236
3947
  style: {
3237
3948
  display: 'flex',
@@ -3251,8 +3962,8 @@ var __webpack_exports__ = {};
3251
3962
  },
3252
3963
  text: 'No events match this filter'
3253
3964
  }));
3254
- else for (const event of events)eventList.appendChild(createEventItem(event, event.id === selectedEventId, ()=>{
3255
- selectedEventId = event.id;
3965
+ else for (const event of events)eventList.appendChild(createEventItem(event, event.id === panelState.selectedEventId, ()=>{
3966
+ panelState.selectedEventId = event.id;
3256
3967
  renderEventsPanel(container, options);
3257
3968
  }));
3258
3969
  container.appendChild(eventList);
@@ -3280,6 +3991,11 @@ var __webpack_exports__ = {};
3280
3991
  if ('network' === filter) return 'network' === event.type;
3281
3992
  return 'iab' === event.type;
3282
3993
  }
3994
+ function matchesSearch(event, query) {
3995
+ if (!query) return true;
3996
+ const haystack = `${event.type} ${event.message} ${JSON.stringify(event.data ?? {})}`;
3997
+ return haystack.toLowerCase().includes(query);
3998
+ }
3283
3999
  function createPayloadSection(event) {
3284
4000
  const payload = event?.data ? JSON.stringify(event.data, null, 2) : null;
3285
4001
  return renderer_div({
@@ -3332,7 +4048,7 @@ var __webpack_exports__ = {};
3332
4048
  },
3333
4049
  onClick: onSelect,
3334
4050
  children: [
3335
- span({
4051
+ renderer_span({
3336
4052
  style: {
3337
4053
  color,
3338
4054
  fontSize: '8px',
@@ -3340,7 +4056,7 @@ var __webpack_exports__ = {};
3340
4056
  },
3341
4057
  text: icon
3342
4058
  }),
3343
- span({
4059
+ renderer_span({
3344
4060
  style: {
3345
4061
  color: 'var(--c15t-text-muted)',
3346
4062
  fontFamily: 'monospace',
@@ -3349,7 +4065,7 @@ var __webpack_exports__ = {};
3349
4065
  },
3350
4066
  text: time
3351
4067
  }),
3352
- span({
4068
+ renderer_span({
3353
4069
  style: {
3354
4070
  color: 'var(--c15t-text)',
3355
4071
  flex: '1'
@@ -3417,38 +4133,15 @@ var __webpack_exports__ = {};
3417
4133
  return 'var(--c15t-text-muted)';
3418
4134
  }
3419
4135
  }
4136
+ const iabSearchByContainer = new WeakMap();
3420
4137
  function renderIabPanel(container, options) {
3421
4138
  const { getState, onSetPurposeConsent, onSetVendorConsent, onSetSpecialFeatureOptIn, onAcceptAll, onRejectAll, onSave, onReset } = options;
3422
4139
  clearElement(container);
3423
4140
  const state = getState();
3424
- if (!state) return void container.appendChild(renderer_div({
3425
- style: {
3426
- padding: '24px',
3427
- textAlign: 'center',
3428
- color: 'var(--c15t-text-muted)',
3429
- fontSize: 'var(--c15t-devtools-font-size-sm)'
3430
- },
3431
- text: 'Store not connected'
3432
- }));
3433
- if ('iab' !== state.model) return void container.appendChild(renderer_div({
3434
- style: {
3435
- padding: '24px',
3436
- textAlign: 'center',
3437
- color: 'var(--c15t-text-muted)',
3438
- fontSize: 'var(--c15t-devtools-font-size-sm)'
3439
- },
3440
- text: 'IAB TCF mode is not configured'
3441
- }));
4141
+ if (!state) return void container.appendChild(createDisconnectedState());
4142
+ if ('iab' !== state.model) return void container.appendChild(createDisconnectedState('IAB TCF mode is not configured'));
3442
4143
  const iabState = state.iab;
3443
- if (!iabState) return void container.appendChild(renderer_div({
3444
- style: {
3445
- padding: '24px',
3446
- textAlign: 'center',
3447
- color: 'var(--c15t-text-muted)',
3448
- fontSize: 'var(--c15t-devtools-font-size-sm)'
3449
- },
3450
- text: 'IAB state not available'
3451
- }));
4144
+ if (!iabState) return void container.appendChild(createDisconnectedState('IAB state not available'));
3452
4145
  const tcString = iabState.tcString;
3453
4146
  const tcStringSection = createSection({
3454
4147
  title: 'TC String',
@@ -3480,9 +4173,30 @@ var __webpack_exports__ = {};
3480
4173
  });
3481
4174
  container.appendChild(tcStringSection);
3482
4175
  const gvl = iabState.gvl;
4176
+ const searchQuery = iabSearchByContainer.get(container) ?? '';
4177
+ container.appendChild(createSection({
4178
+ title: 'Filter',
4179
+ children: [
4180
+ createInput({
4181
+ value: searchQuery,
4182
+ placeholder: 'Filter purposes or vendors…',
4183
+ ariaLabel: 'Filter IAB purposes and vendors',
4184
+ small: true,
4185
+ onInput: (value)=>{
4186
+ iabSearchByContainer.set(container, value.trim().toLowerCase());
4187
+ renderIabPanel(container, options);
4188
+ }
4189
+ })
4190
+ ]
4191
+ }));
3483
4192
  const purposeConsents = iabState.purposeConsents || {};
3484
4193
  const purposes = gvl?.purposes || {};
3485
- const purposeEntries = Object.entries(purposeConsents);
4194
+ const purposeEntries = Object.entries(purposeConsents).filter(([purposeId])=>{
4195
+ if (!searchQuery) return true;
4196
+ const purposeInfo = purposes[purposeId];
4197
+ const purposeName = purposeInfo?.name || `Purpose ${purposeId}`;
4198
+ return `${purposeId} ${purposeName}`.toLowerCase().includes(searchQuery);
4199
+ });
3486
4200
  if (purposeEntries.length > 0) {
3487
4201
  const purposeList = renderer_div({
3488
4202
  style: {
@@ -3510,7 +4224,12 @@ var __webpack_exports__ = {};
3510
4224
  }
3511
4225
  const specialFeatureOptIns = iabState.specialFeatureOptIns || {};
3512
4226
  const specialFeatures = gvl?.specialFeatures || {};
3513
- const specialFeatureEntries = Object.entries(specialFeatureOptIns);
4227
+ const specialFeatureEntries = Object.entries(specialFeatureOptIns).filter(([featureId])=>{
4228
+ if (!searchQuery) return true;
4229
+ const featureInfo = specialFeatures[featureId];
4230
+ const featureName = featureInfo?.name || `Special Feature ${featureId}`;
4231
+ return `${featureId} ${featureName}`.toLowerCase().includes(searchQuery);
4232
+ });
3514
4233
  if (specialFeatureEntries.length > 0) {
3515
4234
  const specialFeatureList = renderer_div({
3516
4235
  style: {
@@ -3538,7 +4257,12 @@ var __webpack_exports__ = {};
3538
4257
  }
3539
4258
  const vendorConsents = iabState.vendorConsents || {};
3540
4259
  const vendors = gvl?.vendors || {};
3541
- const vendorEntries = Object.entries(vendorConsents);
4260
+ const vendorEntries = Object.entries(vendorConsents).filter(([vendorId])=>{
4261
+ if (!searchQuery) return true;
4262
+ const vendorInfo = vendors[vendorId];
4263
+ const vendorName = vendorInfo?.name || `Vendor ${vendorId}`;
4264
+ return `${vendorId} ${vendorName}`.toLowerCase().includes(searchQuery);
4265
+ });
3542
4266
  const iabVendors = [];
3543
4267
  const customVendors = [];
3544
4268
  for (const [vendorId, consent] of vendorEntries){
@@ -3664,7 +4388,7 @@ var __webpack_exports__ = {};
3664
4388
  borderBottom: '1px solid var(--c15t-border)'
3665
4389
  },
3666
4390
  children: [
3667
- span({
4391
+ renderer_span({
3668
4392
  style: {
3669
4393
  color: 'var(--c15t-text)',
3670
4394
  overflow: 'hidden',
@@ -3718,7 +4442,7 @@ var __webpack_exports__ = {};
3718
4442
  marginRight: '8px'
3719
4443
  },
3720
4444
  children: [
3721
- 'custom' === type ? span({
4445
+ 'custom' === type ? renderer_span({
3722
4446
  style: {
3723
4447
  fontSize: '9px',
3724
4448
  padding: '1px 4px',
@@ -3729,7 +4453,7 @@ var __webpack_exports__ = {};
3729
4453
  },
3730
4454
  text: 'CUSTOM'
3731
4455
  }) : null,
3732
- span({
4456
+ renderer_span({
3733
4457
  style: {
3734
4458
  color: 'var(--c15t-text)',
3735
4459
  overflow: 'hidden',
@@ -3761,15 +4485,7 @@ var __webpack_exports__ = {};
3761
4485
  const { getState, onApplyOverrides, onClearOverrides } = options;
3762
4486
  clearElement(container);
3763
4487
  const state = getState();
3764
- if (!state) return void container.appendChild(renderer_div({
3765
- style: {
3766
- padding: '24px',
3767
- textAlign: 'center',
3768
- color: 'var(--c15t-text-muted)',
3769
- fontSize: 'var(--c15t-devtools-font-size-sm)'
3770
- },
3771
- text: 'Store not connected'
3772
- }));
4488
+ if (!state) return void container.appendChild(createDisconnectedState());
3773
4489
  const locationInfo = state.locationInfo;
3774
4490
  const overrides = state.overrides;
3775
4491
  const translationConfig = state.translationConfig;
@@ -3809,7 +4525,7 @@ var __webpack_exports__ = {};
3809
4525
  selectOptions: GPC_OPTIONS,
3810
4526
  value: initialDraft.gpc
3811
4527
  });
3812
- const formStatus = span({
4528
+ const formStatus = renderer_span({
3813
4529
  className: styles_components_module.overrideStatus,
3814
4530
  text: 'In sync'
3815
4531
  });
@@ -3855,7 +4571,7 @@ var __webpack_exports__ = {};
3855
4571
  title: 'Override Settings',
3856
4572
  children: [
3857
4573
  overrideFieldsGrid,
3858
- span({
4574
+ renderer_span({
3859
4575
  className: styles_components_module.overrideHint,
3860
4576
  text: 'GPC override only affects opt-out or unregulated jurisdictions.'
3861
4577
  }),
@@ -3943,7 +4659,7 @@ var __webpack_exports__ = {};
3943
4659
  element: renderer_div({
3944
4660
  className: styles_components_module.overrideField,
3945
4661
  children: [
3946
- span({
4662
+ renderer_span({
3947
4663
  className: styles_components_module.overrideLabel,
3948
4664
  text: label
3949
4665
  }),
@@ -3964,7 +4680,7 @@ var __webpack_exports__ = {};
3964
4680
  element: renderer_div({
3965
4681
  className: styles_components_module.overrideField,
3966
4682
  children: [
3967
- span({
4683
+ renderer_span({
3968
4684
  className: styles_components_module.overrideLabel,
3969
4685
  text: label
3970
4686
  }),
@@ -4175,14 +4891,14 @@ var __webpack_exports__ = {};
4175
4891
  gap: '1px'
4176
4892
  },
4177
4893
  children: [
4178
- span({
4894
+ renderer_span({
4179
4895
  style: {
4180
4896
  fontSize: 'var(--c15t-devtools-font-size-xs)',
4181
4897
  color: 'var(--c15t-text-muted)'
4182
4898
  },
4183
4899
  text: label
4184
4900
  }),
4185
- span({
4901
+ renderer_span({
4186
4902
  style: {
4187
4903
  fontSize: 'var(--c15t-font-size-sm)',
4188
4904
  fontWeight: '500',
@@ -4358,21 +5074,21 @@ var __webpack_exports__ = {};
4358
5074
  borderBottom: '1px solid var(--c15t-border)'
4359
5075
  },
4360
5076
  children: [
4361
- span({
5077
+ renderer_span({
4362
5078
  style: {
4363
5079
  color: iconColor,
4364
5080
  flexShrink: '0'
4365
5081
  },
4366
5082
  text: icon
4367
5083
  }),
4368
- span({
5084
+ renderer_span({
4369
5085
  style: {
4370
5086
  color: 'var(--c15t-text-muted)',
4371
5087
  flexShrink: '0'
4372
5088
  },
4373
5089
  text: `${resource.type}:`
4374
5090
  }),
4375
- span({
5091
+ renderer_span({
4376
5092
  style: {
4377
5093
  fontWeight: '500',
4378
5094
  color: 'var(--c15t-text)',
@@ -4418,23 +5134,37 @@ var __webpack_exports__ = {};
4418
5134
  <polyline points="16 18 22 12 16 6"></polyline>
4419
5135
  <polyline points="8 6 2 12 8 18"></polyline>
4420
5136
  </svg>`;
5137
+ const scriptsSearchByContainer = new WeakMap();
4421
5138
  function renderScriptsPanel(container, options) {
4422
5139
  const { getState, getEvents } = options;
4423
5140
  clearElement(container);
4424
5141
  const state = getState();
4425
- if (!state) return void container.appendChild(renderer_div({
4426
- style: {
4427
- padding: '24px',
4428
- textAlign: 'center',
4429
- color: 'var(--c15t-text-muted)',
4430
- fontSize: 'var(--c15t-devtools-font-size-sm)'
4431
- },
4432
- text: 'Store not connected'
4433
- }));
5142
+ if (!state) return void container.appendChild(createDisconnectedState());
4434
5143
  const scripts = state.scripts || [];
4435
5144
  const loadedScripts = state.loadedScripts || {};
4436
5145
  const networkBlocker = state.networkBlocker;
4437
5146
  const events = getEvents?.() ?? [];
5147
+ const searchQuery = scriptsSearchByContainer.get(container) ?? '';
5148
+ const filteredScripts = scripts.filter((script)=>{
5149
+ if (!searchQuery) return true;
5150
+ const category = 'string' == typeof script.category ? script.category : JSON.stringify(script.category);
5151
+ return `${script.id} ${category}`.toLowerCase().includes(searchQuery);
5152
+ });
5153
+ if (scripts.length > 4) container.appendChild(createSection({
5154
+ title: 'Filter',
5155
+ children: [
5156
+ createInput({
5157
+ value: searchQuery,
5158
+ placeholder: "Filter scripts…",
5159
+ ariaLabel: "Filter scripts",
5160
+ small: true,
5161
+ onInput: (value)=>{
5162
+ scriptsSearchByContainer.set(container, value.trim().toLowerCase());
5163
+ renderScriptsPanel(container, options);
5164
+ }
5165
+ })
5166
+ ]
5167
+ }));
4438
5168
  if (0 === scripts.length) {
4439
5169
  const scriptsSection = createSection({
4440
5170
  title: 'Configured Scripts',
@@ -4451,10 +5181,19 @@ var __webpack_exports__ = {};
4451
5181
  style: {
4452
5182
  display: 'flex',
4453
5183
  flexDirection: 'column',
4454
- gap: '4px'
5184
+ borderTop: '1px solid var(--c15t-border)',
5185
+ borderBottom: '1px solid var(--c15t-border)'
4455
5186
  }
4456
5187
  });
4457
- for (const script of scripts){
5188
+ if (0 === filteredScripts.length) scriptsList.appendChild(renderer_div({
5189
+ style: {
5190
+ padding: '10px 0',
5191
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5192
+ color: 'var(--c15t-text-muted)'
5193
+ },
5194
+ text: "No matching scripts"
5195
+ }));
5196
+ for (const script of filteredScripts){
4458
5197
  const scriptId = script.id;
4459
5198
  const isLoaded = true === loadedScripts[scriptId];
4460
5199
  const category = script.category;
@@ -4478,20 +5217,67 @@ var __webpack_exports__ = {};
4478
5217
  text: status.charAt(0).toUpperCase() + status.slice(1),
4479
5218
  variant: statusVariant
4480
5219
  });
4481
- const item = createListItem({
4482
- title: scriptId,
4483
- description: `Category: ${categoryDisplay}`,
4484
- actions: [
4485
- badge
4486
- ]
4487
- });
4488
- scriptsList.appendChild(item);
4489
- }
4490
- const scriptsSection = createSection({
4491
- title: `Configured Scripts (${scripts.length})`,
4492
- children: [
4493
- scriptsList
4494
- ]
5220
+ const row = renderer_div({
5221
+ style: {
5222
+ display: 'flex',
5223
+ alignItems: 'center',
5224
+ justifyContent: 'space-between',
5225
+ gap: '8px',
5226
+ padding: '8px 0',
5227
+ borderBottom: '1px solid var(--c15t-border)'
5228
+ },
5229
+ children: [
5230
+ renderer_div({
5231
+ style: {
5232
+ display: 'flex',
5233
+ flexDirection: 'column',
5234
+ gap: '2px',
5235
+ minWidth: '0',
5236
+ flex: '1'
5237
+ },
5238
+ children: [
5239
+ renderer_div({
5240
+ style: {
5241
+ fontSize: 'var(--c15t-font-size-sm)',
5242
+ fontWeight: '500',
5243
+ color: 'var(--c15t-text)',
5244
+ overflow: 'hidden',
5245
+ textOverflow: 'ellipsis',
5246
+ whiteSpace: 'nowrap'
5247
+ },
5248
+ text: scriptId
5249
+ }),
5250
+ renderer_div({
5251
+ style: {
5252
+ fontSize: 'var(--c15t-devtools-font-size-xs)',
5253
+ color: 'var(--c15t-text-muted)',
5254
+ overflow: 'hidden',
5255
+ textOverflow: 'ellipsis',
5256
+ whiteSpace: 'nowrap'
5257
+ },
5258
+ text: `Category: ${categoryDisplay}`
5259
+ })
5260
+ ]
5261
+ }),
5262
+ renderer_div({
5263
+ style: {
5264
+ flexShrink: '0'
5265
+ },
5266
+ children: [
5267
+ badge
5268
+ ]
5269
+ })
5270
+ ]
5271
+ });
5272
+ scriptsList.appendChild(row);
5273
+ }
5274
+ const lastRow = scriptsList.lastElementChild;
5275
+ if (lastRow) lastRow.style.borderBottom = 'none';
5276
+ const scriptsSection = createSection({
5277
+ title: `Configured Scripts (${filteredScripts.length}/${scripts.length})`,
5278
+ children: [
5279
+ scriptsList
5280
+ ]
4495
5281
  });
4496
5282
  container.appendChild(scriptsSection);
4497
5283
  }
@@ -4630,53 +5416,6 @@ var __webpack_exports__ = {};
4630
5416
  if (text.length <= maxLength) return text;
4631
5417
  return `${text.slice(0, maxLength - 3)}...`;
4632
5418
  }
4633
- const DEVTOOLS_OVERRIDES_STORAGE_KEY = 'c15t-devtools-overrides';
4634
- function normalizeStringValue(value) {
4635
- if ('string' != typeof value) return;
4636
- const normalized = value.trim();
4637
- return normalized.length > 0 ? normalized : void 0;
4638
- }
4639
- function normalizeBooleanValue(value) {
4640
- return 'boolean' == typeof value ? value : void 0;
4641
- }
4642
- function normalizeOverrides(value) {
4643
- if (!value || 'object' != typeof value) return null;
4644
- const source = value;
4645
- const overrides = {
4646
- country: normalizeStringValue(source.country),
4647
- region: normalizeStringValue(source.region),
4648
- language: normalizeStringValue(source.language),
4649
- gpc: normalizeBooleanValue(source.gpc)
4650
- };
4651
- return hasPersistedOverrides(overrides) ? overrides : null;
4652
- }
4653
- function hasPersistedOverrides(overrides) {
4654
- return Boolean(overrides.country || overrides.region || overrides.language || void 0 !== overrides.gpc);
4655
- }
4656
- function loadPersistedOverrides(storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
4657
- if ('undefined' == typeof window) return null;
4658
- try {
4659
- const stored = localStorage.getItem(storageKey);
4660
- if (!stored) return null;
4661
- const parsed = JSON.parse(stored);
4662
- return normalizeOverrides(parsed);
4663
- } catch {
4664
- return null;
4665
- }
4666
- }
4667
- function persistOverrides(overrides, storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
4668
- if ('undefined' == typeof window) return;
4669
- try {
4670
- if (!hasPersistedOverrides(overrides)) return void localStorage.removeItem(storageKey);
4671
- localStorage.setItem(storageKey, JSON.stringify(overrides));
4672
- } catch {}
4673
- }
4674
- function clearPersistedOverrides(storageKey = DEVTOOLS_OVERRIDES_STORAGE_KEY) {
4675
- if ('undefined' == typeof window) return;
4676
- try {
4677
- localStorage.removeItem(storageKey);
4678
- } catch {}
4679
- }
4680
5419
  const STORAGE_KEYS = {
4681
5420
  C15T: 'c15t',
4682
5421
  PENDING_SYNC: 'c15t:pending-consent-sync',
@@ -4713,7 +5452,222 @@ var __webpack_exports__ = {};
4713
5452
  message: 'All consents reset (storage cleared)'
4714
5453
  });
4715
5454
  }
5455
+ function createPanelRenderer(config) {
5456
+ const { storeConnector, stateManager, enableEventLogging = true, onPersistOverrides, onClearPersistedOverrides, onCopyState, onExportDebugBundle } = config;
5457
+ const getStoreState = ()=>storeConnector.getState();
5458
+ const logEvent = (type, message, data)=>{
5459
+ if (enableEventLogging) stateManager.addEvent({
5460
+ type,
5461
+ message,
5462
+ data
5463
+ });
5464
+ };
5465
+ const resetConsents = async ()=>{
5466
+ const store = storeConnector.getStore();
5467
+ if (store) await resetAllConsents(store, enableEventLogging ? stateManager : void 0);
5468
+ };
5469
+ const renderPanel = (container, tab)=>{
5470
+ switch(tab){
5471
+ case 'consents':
5472
+ renderConsentsPanel(container, {
5473
+ getState: getStoreState,
5474
+ onConsentChange: (name, value)=>{
5475
+ const store = storeConnector.getStore();
5476
+ if (store) {
5477
+ const consentName = String(name);
5478
+ store.getState().setSelectedConsent(consentName, value);
5479
+ logEvent('info', `${consentName} toggled to ${value} (not saved)`, {
5480
+ name: consentName,
5481
+ value
5482
+ });
5483
+ }
5484
+ },
5485
+ onSave: ()=>{
5486
+ const store = storeConnector.getStore();
5487
+ if (store) {
5488
+ store.getState().saveConsents('custom');
5489
+ logEvent('consent_save', 'Saved consent preferences');
5490
+ }
5491
+ },
5492
+ onAcceptAll: ()=>{
5493
+ const store = storeConnector.getStore();
5494
+ if (store) {
5495
+ store.getState().saveConsents('all');
5496
+ logEvent('consent_save', 'Accepted all consents');
5497
+ }
5498
+ },
5499
+ onRejectAll: ()=>{
5500
+ const store = storeConnector.getStore();
5501
+ if (store) {
5502
+ store.getState().saveConsents('necessary');
5503
+ logEvent('consent_save', 'Rejected all optional consents');
5504
+ }
5505
+ },
5506
+ onReset: resetConsents
5507
+ });
5508
+ break;
5509
+ case 'location':
5510
+ renderLocationPanel(container, {
5511
+ getState: getStoreState,
5512
+ onApplyOverrides: async (overrides)=>{
5513
+ const store = storeConnector.getStore();
5514
+ if (store) {
5515
+ await store.getState().setOverrides({
5516
+ country: overrides.country,
5517
+ region: overrides.region,
5518
+ language: overrides.language,
5519
+ gpc: overrides.gpc
5520
+ });
5521
+ logEvent('info', 'Overrides updated', {
5522
+ country: overrides.country,
5523
+ region: overrides.region,
5524
+ language: overrides.language,
5525
+ gpc: overrides.gpc
5526
+ });
5527
+ onPersistOverrides?.({
5528
+ country: overrides.country,
5529
+ region: overrides.region,
5530
+ language: overrides.language,
5531
+ gpc: overrides.gpc
5532
+ });
5533
+ }
5534
+ },
5535
+ onClearOverrides: async ()=>{
5536
+ const store = storeConnector.getStore();
5537
+ if (store) {
5538
+ await store.getState().setOverrides({
5539
+ country: void 0,
5540
+ region: void 0,
5541
+ language: void 0,
5542
+ gpc: void 0
5543
+ });
5544
+ logEvent('info', 'Overrides cleared');
5545
+ onClearPersistedOverrides?.();
5546
+ }
5547
+ }
5548
+ });
5549
+ break;
5550
+ case "scripts":
5551
+ renderScriptsPanel(container, {
5552
+ getState: getStoreState,
5553
+ getEvents: ()=>stateManager.getState().eventLog
5554
+ });
5555
+ break;
5556
+ case 'iab':
5557
+ renderIabPanel(container, {
5558
+ getState: getStoreState,
5559
+ onSetPurposeConsent: (purposeId, value)=>{
5560
+ const iab = storeConnector.getStore()?.getState().iab;
5561
+ if (!iab) return;
5562
+ iab.setPurposeConsent(purposeId, value);
5563
+ logEvent('iab', `IAB purpose ${purposeId} set to ${value}`);
5564
+ },
5565
+ onSetVendorConsent: (vendorId, value)=>{
5566
+ const iab = storeConnector.getStore()?.getState().iab;
5567
+ if (!iab) return;
5568
+ iab.setVendorConsent(vendorId, value);
5569
+ logEvent('iab', `IAB vendor ${vendorId} set to ${value}`);
5570
+ },
5571
+ onSetSpecialFeatureOptIn: (featureId, value)=>{
5572
+ const iab = storeConnector.getStore()?.getState().iab;
5573
+ if (!iab) return;
5574
+ iab.setSpecialFeatureOptIn(featureId, value);
5575
+ logEvent('iab', `IAB feature ${featureId} set to ${value}`);
5576
+ },
5577
+ onAcceptAll: ()=>{
5578
+ const iab = storeConnector.getStore()?.getState().iab;
5579
+ if (!iab) return;
5580
+ iab.acceptAll();
5581
+ logEvent('iab', 'IAB accept all selected');
5582
+ },
5583
+ onRejectAll: ()=>{
5584
+ const iab = storeConnector.getStore()?.getState().iab;
5585
+ if (!iab) return;
5586
+ iab.rejectAll();
5587
+ logEvent('iab', 'IAB reject all selected');
5588
+ },
5589
+ onSave: ()=>{
5590
+ const iab = storeConnector.getStore()?.getState().iab;
5591
+ if (!iab) return;
5592
+ iab.save().then(()=>logEvent('iab', 'IAB preferences saved')).catch((error)=>{
5593
+ logEvent('error', `Failed to save IAB preferences: ${String(error)}`);
5594
+ });
5595
+ },
5596
+ onReset: resetConsents
5597
+ });
5598
+ break;
5599
+ case 'events':
5600
+ renderEventsPanel(container, {
5601
+ getEvents: ()=>stateManager.getState().eventLog,
5602
+ onClear: ()=>{
5603
+ stateManager.clearEventLog();
5604
+ logEvent('info', 'Event log cleared');
5605
+ }
5606
+ });
5607
+ break;
5608
+ case 'actions':
5609
+ renderActionsPanel(container, {
5610
+ getState: getStoreState,
5611
+ onResetConsents: resetConsents,
5612
+ onRefetchBanner: async ()=>{
5613
+ const store = storeConnector.getStore();
5614
+ if (store) {
5615
+ await store.getState().initConsentManager();
5616
+ logEvent('info', 'Banner data refetched');
5617
+ }
5618
+ },
5619
+ onShowBanner: ()=>{
5620
+ const store = storeConnector.getStore();
5621
+ if (store) {
5622
+ store.getState().setActiveUI('banner', {
5623
+ force: true
5624
+ });
5625
+ logEvent('info', 'Banner shown');
5626
+ }
5627
+ },
5628
+ onOpenPreferences: ()=>{
5629
+ const store = storeConnector.getStore();
5630
+ if (store) {
5631
+ store.getState().setActiveUI('dialog');
5632
+ logEvent('info', 'Preferences dialog opened');
5633
+ }
5634
+ },
5635
+ onCopyState: ()=>{
5636
+ const state = getStoreState();
5637
+ if (state) if (onCopyState) {
5638
+ const result = onCopyState(state);
5639
+ if (result instanceof Promise) result.then((ok)=>{
5640
+ logEvent(ok ? 'info' : 'error', ok ? 'State copied to clipboard' : 'Failed to copy state');
5641
+ }).catch(()=>{
5642
+ logEvent('error', 'Failed to copy state');
5643
+ });
5644
+ else logEvent(result ? 'info' : 'error', result ? 'State copied to clipboard' : 'Failed to copy state');
5645
+ } else navigator.clipboard.writeText(JSON.stringify(state, null, 2)).then(()=>{
5646
+ logEvent('info', 'State copied to clipboard');
5647
+ }).catch(()=>{
5648
+ logEvent('error', 'Failed to copy state');
5649
+ });
5650
+ },
5651
+ onExportDebugBundle: onExportDebugBundle ? ()=>{
5652
+ try {
5653
+ onExportDebugBundle();
5654
+ logEvent('info', 'Debug bundle exported');
5655
+ } catch {
5656
+ logEvent('error', 'Failed to export debug bundle');
5657
+ }
5658
+ } : void 0
5659
+ });
5660
+ break;
5661
+ }
5662
+ };
5663
+ return {
5664
+ renderPanel,
5665
+ getStoreState,
5666
+ resetConsents
5667
+ };
5668
+ }
4716
5669
  const STORAGE_KEY = 'c15t-devtools-events';
5670
+ const ACTIVE_TAB_STORAGE_KEY = 'c15t-devtools-active-tab';
4717
5671
  function loadPersistedEvents() {
4718
5672
  if ('undefined' == typeof window) return [];
4719
5673
  try {
@@ -4728,11 +5682,29 @@ var __webpack_exports__ = {};
4728
5682
  sessionStorage.setItem(STORAGE_KEY, JSON.stringify(events));
4729
5683
  } catch {}
4730
5684
  }
5685
+ function isDevToolsTab(value) {
5686
+ return 'consents' === value || 'location' === value || "scripts" === value || 'iab' === value || 'events' === value || 'actions' === value;
5687
+ }
5688
+ function loadPersistedActiveTab() {
5689
+ if ('undefined' == typeof window) return null;
5690
+ try {
5691
+ const stored = localStorage.getItem(ACTIVE_TAB_STORAGE_KEY);
5692
+ if (isDevToolsTab(stored)) return stored;
5693
+ } catch {}
5694
+ return null;
5695
+ }
5696
+ function persistActiveTab(tab) {
5697
+ if ('undefined' == typeof window) return;
5698
+ try {
5699
+ localStorage.setItem(ACTIVE_TAB_STORAGE_KEY, tab);
5700
+ } catch {}
5701
+ }
4731
5702
  function createStateManager(initialState = {}) {
4732
5703
  const persistedEvents = loadPersistedEvents();
5704
+ const persistedActiveTab = loadPersistedActiveTab();
4733
5705
  let state = {
4734
5706
  isOpen: false,
4735
- activeTab: 'location',
5707
+ activeTab: persistedActiveTab ?? 'location',
4736
5708
  position: 'bottom-right',
4737
5709
  isConnected: false,
4738
5710
  eventLog: persistedEvents,
@@ -4773,6 +5745,7 @@ var __webpack_exports__ = {};
4773
5745
  setState({
4774
5746
  activeTab: tab
4775
5747
  });
5748
+ persistActiveTab(tab);
4776
5749
  },
4777
5750
  setPosition: (position)=>{
4778
5751
  setState({
@@ -4818,22 +5791,52 @@ var __webpack_exports__ = {};
4818
5791
  let reconnectAttempts = 0;
4819
5792
  let hasNotifiedDisconnect = false;
4820
5793
  const listeners = new Set();
5794
+ const diagnosticsListeners = new Set();
5795
+ let diagnostics = {
5796
+ namespace,
5797
+ reconnectAttempts: 0,
5798
+ nextRetryInMs: null,
5799
+ lastError: null,
5800
+ isPolling: false,
5801
+ disconnectNotified: false
5802
+ };
4821
5803
  const INITIAL_RETRY_DELAY_MS = 100;
4822
5804
  const MAX_RETRY_DELAY_MS = 2000;
4823
5805
  const DISCONNECT_NOTIFY_ATTEMPTS = 5;
5806
+ function updateDiagnostics(partial, notify = true) {
5807
+ diagnostics = {
5808
+ ...diagnostics,
5809
+ ...partial
5810
+ };
5811
+ if (!notify) return;
5812
+ for (const listener of diagnosticsListeners)listener(diagnostics);
5813
+ }
4824
5814
  function clearReconnectTimer() {
4825
5815
  if (reconnectTimeout) {
4826
5816
  clearTimeout(reconnectTimeout);
4827
5817
  reconnectTimeout = null;
5818
+ updateDiagnostics({
5819
+ isPolling: false,
5820
+ nextRetryInMs: null
5821
+ });
4828
5822
  }
4829
5823
  }
4830
5824
  function resetReconnectState() {
4831
5825
  reconnectAttempts = 0;
4832
5826
  hasNotifiedDisconnect = false;
5827
+ updateDiagnostics({
5828
+ reconnectAttempts: 0,
5829
+ nextRetryInMs: null,
5830
+ lastError: null,
5831
+ disconnectNotified: false
5832
+ });
4833
5833
  }
4834
5834
  function notifyDisconnectedOnce() {
4835
5835
  if (hasNotifiedDisconnect) return;
4836
5836
  hasNotifiedDisconnect = true;
5837
+ updateDiagnostics({
5838
+ disconnectNotified: true
5839
+ });
4837
5840
  onDisconnect?.();
4838
5841
  }
4839
5842
  function tryConnect() {
@@ -4854,16 +5857,31 @@ var __webpack_exports__ = {};
4854
5857
  onConnect?.(currentState, store);
4855
5858
  clearReconnectTimer();
4856
5859
  resetReconnectState();
5860
+ updateDiagnostics({
5861
+ lastError: null
5862
+ });
4857
5863
  return true;
4858
5864
  }
5865
+ updateDiagnostics({
5866
+ lastError: `Store "${namespace}" not found on window`
5867
+ });
4859
5868
  return false;
4860
5869
  }
4861
5870
  function scheduleReconnect(immediate = false) {
4862
5871
  if (store || reconnectTimeout) return;
4863
5872
  const delay = immediate ? 0 : Math.min(INITIAL_RETRY_DELAY_MS * 2 ** Math.min(reconnectAttempts, 5), MAX_RETRY_DELAY_MS);
5873
+ updateDiagnostics({
5874
+ isPolling: true,
5875
+ nextRetryInMs: delay,
5876
+ reconnectAttempts
5877
+ });
4864
5878
  reconnectTimeout = setTimeout(()=>{
4865
5879
  reconnectTimeout = null;
4866
5880
  reconnectAttempts++;
5881
+ updateDiagnostics({
5882
+ reconnectAttempts,
5883
+ nextRetryInMs: null
5884
+ });
4867
5885
  if (tryConnect()) return;
4868
5886
  if (reconnectAttempts >= DISCONNECT_NOTIFY_ATTEMPTS) notifyDisconnectedOnce();
4869
5887
  scheduleReconnect();
@@ -4885,6 +5903,14 @@ var __webpack_exports__ = {};
4885
5903
  listeners.delete(listener);
4886
5904
  };
4887
5905
  },
5906
+ getDiagnostics: ()=>diagnostics,
5907
+ subscribeDiagnostics: (listener)=>{
5908
+ diagnosticsListeners.add(listener);
5909
+ listener(diagnostics);
5910
+ return ()=>{
5911
+ diagnosticsListeners.delete(listener);
5912
+ };
5913
+ },
4888
5914
  retryConnection: ()=>{
4889
5915
  if (store) return;
4890
5916
  resetReconnectState();
@@ -4898,6 +5924,7 @@ var __webpack_exports__ = {};
4898
5924
  }
4899
5925
  store = null;
4900
5926
  listeners.clear();
5927
+ diagnosticsListeners.clear();
4901
5928
  }
4902
5929
  };
4903
5930
  }
@@ -4910,13 +5937,140 @@ var __webpack_exports__ = {};
4910
5937
  function isC15tStoreAvailable(namespace = 'c15tStore') {
4911
5938
  return null !== getC15tStore(namespace);
4912
5939
  }
4913
- var tokens = __webpack_require__("../../node_modules/.bun/@rsbuild+core@1.6.12/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles/tokens.css");
4914
- var tokens_options = {};
4915
- tokens_options.styleTagTransform = styleTagTransform_default();
4916
- tokens_options.setAttributes = setAttributesWithoutAttributes_default();
4917
- tokens_options.insert = insertBySelector_default().bind(null, "head");
4918
- tokens_options.domAPI = styleDomAPI_default();
4919
- tokens_options.insertStyleElement = insertStyleElement_default();
5940
+ const REGISTRY_KEY = '__c15tDevToolsInstrumentationRegistry';
5941
+ let fallbackRegistry = null;
5942
+ function getRegistry() {
5943
+ if ('undefined' == typeof window) {
5944
+ if (!fallbackRegistry) fallbackRegistry = new Map();
5945
+ return fallbackRegistry;
5946
+ }
5947
+ const host = window;
5948
+ const existing = host[REGISTRY_KEY];
5949
+ if (existing) return existing;
5950
+ const registry = new Map();
5951
+ host[REGISTRY_KEY] = registry;
5952
+ return registry;
5953
+ }
5954
+ function getBlockedRequestMessage(payload) {
5955
+ const data = payload;
5956
+ const method = 'string' == typeof data?.method ? data.method.toUpperCase() : 'REQUEST';
5957
+ const url = 'string' == typeof data?.url ? data.url : 'unknown-url';
5958
+ return `Network blocked: ${method} ${url}`;
5959
+ }
5960
+ function emitEvent(entry, event) {
5961
+ for (const listener of entry.listeners)listener(event);
5962
+ }
5963
+ function ensureNetworkBlockerWrapped(entry) {
5964
+ const blocker = entry.store.getState().networkBlocker;
5965
+ if (!blocker) return;
5966
+ if (blocker.onRequestBlocked === entry.wrappedNetworkBlockedCallback) return;
5967
+ entry.originalNetworkBlockedCallback = blocker.onRequestBlocked;
5968
+ entry.wrappedNetworkBlockedCallback = (payload)=>{
5969
+ emitEvent(entry, {
5970
+ type: 'network',
5971
+ message: getBlockedRequestMessage(payload),
5972
+ data: payload
5973
+ });
5974
+ if ('function' == typeof entry.originalNetworkBlockedCallback) entry.originalNetworkBlockedCallback(payload);
5975
+ };
5976
+ entry.store.getState().setNetworkBlocker({
5977
+ ...blocker,
5978
+ onRequestBlocked: entry.wrappedNetworkBlockedCallback
5979
+ });
5980
+ }
5981
+ function restoreInstrumentation(entry) {
5982
+ entry.stopWatchingStore?.();
5983
+ entry.stopWatchingStore = null;
5984
+ const state = entry.store.getState();
5985
+ state.setCallback('onBannerFetched', entry.originalCallbacks.onBannerFetched);
5986
+ state.setCallback('onConsentSet', entry.originalCallbacks.onConsentSet);
5987
+ state.setCallback('onError', entry.originalCallbacks.onError);
5988
+ state.setCallback('onBeforeConsentRevocationReload', entry.originalCallbacks.onBeforeConsentRevocationReload);
5989
+ const blocker = state.networkBlocker;
5990
+ if (blocker && blocker.onRequestBlocked === entry.wrappedNetworkBlockedCallback) state.setNetworkBlocker({
5991
+ ...blocker,
5992
+ onRequestBlocked: entry.originalNetworkBlockedCallback
5993
+ });
5994
+ entry.wrappedNetworkBlockedCallback = null;
5995
+ }
5996
+ function createInstrumentationEntry(store) {
5997
+ const entry = {
5998
+ store,
5999
+ listeners: new Set(),
6000
+ originalCallbacks: {
6001
+ ...store.getState().callbacks
6002
+ },
6003
+ originalNetworkBlockedCallback: store.getState().networkBlocker?.onRequestBlocked,
6004
+ wrappedNetworkBlockedCallback: null,
6005
+ stopWatchingStore: null
6006
+ };
6007
+ store.getState().setCallback('onBannerFetched', (payload)=>{
6008
+ const jurisdiction = payload.jurisdiction;
6009
+ emitEvent(entry, {
6010
+ type: 'info',
6011
+ message: `Banner fetched: ${String(jurisdiction)}`,
6012
+ data: payload
6013
+ });
6014
+ if ('function' == typeof entry.originalCallbacks.onBannerFetched) entry.originalCallbacks.onBannerFetched(payload);
6015
+ });
6016
+ store.getState().setCallback('onConsentSet', (payload)=>{
6017
+ emitEvent(entry, {
6018
+ type: 'consent_set',
6019
+ message: 'Consent preferences updated',
6020
+ data: payload
6021
+ });
6022
+ if ('function' == typeof entry.originalCallbacks.onConsentSet) entry.originalCallbacks.onConsentSet(payload);
6023
+ });
6024
+ store.getState().setCallback('onError', (payload)=>{
6025
+ const errorMessage = payload.error;
6026
+ emitEvent(entry, {
6027
+ type: 'error',
6028
+ message: `Error: ${String(errorMessage)}`,
6029
+ data: payload
6030
+ });
6031
+ if ('function' == typeof entry.originalCallbacks.onError) entry.originalCallbacks.onError(payload);
6032
+ });
6033
+ store.getState().setCallback('onBeforeConsentRevocationReload', (payload)=>{
6034
+ emitEvent(entry, {
6035
+ type: 'info',
6036
+ message: 'Consent revocation - page will reload',
6037
+ data: payload
6038
+ });
6039
+ if ('function' == typeof entry.originalCallbacks.onBeforeConsentRevocationReload) entry.originalCallbacks.onBeforeConsentRevocationReload(payload);
6040
+ });
6041
+ ensureNetworkBlockerWrapped(entry);
6042
+ entry.stopWatchingStore = store.subscribe(()=>{
6043
+ ensureNetworkBlockerWrapped(entry);
6044
+ });
6045
+ return entry;
6046
+ }
6047
+ function registerStoreInstrumentation(options) {
6048
+ const { namespace, store, onEvent } = options;
6049
+ const registry = getRegistry();
6050
+ let entry = registry.get(namespace);
6051
+ if (!entry || entry.store !== store) {
6052
+ if (entry) restoreInstrumentation(entry);
6053
+ entry = createInstrumentationEntry(store);
6054
+ registry.set(namespace, entry);
6055
+ }
6056
+ entry.listeners.add(onEvent);
6057
+ return ()=>{
6058
+ const current = registry.get(namespace);
6059
+ if (!current) return;
6060
+ current.listeners.delete(onEvent);
6061
+ if (0 === current.listeners.size) {
6062
+ restoreInstrumentation(current);
6063
+ registry.delete(namespace);
6064
+ }
6065
+ };
6066
+ }
6067
+ var tokens = __webpack_require__("../../node_modules/.bun/@rsbuild+core@1.6.12/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles/tokens.css");
6068
+ var tokens_options = {};
6069
+ tokens_options.styleTagTransform = styleTagTransform_default();
6070
+ tokens_options.setAttributes = setAttributesWithoutAttributes_default();
6071
+ tokens_options.insert = insertBySelector_default().bind(null, "head");
6072
+ tokens_options.domAPI = styleDomAPI_default();
6073
+ tokens_options.insertStyleElement = insertStyleElement_default();
4920
6074
  injectStylesIntoStyleTag_default()(tokens.A, tokens_options);
4921
6075
  tokens.A && tokens.A.locals && tokens.A.locals;
4922
6076
  const PANEL_HEIGHT_TRANSITION = 'height var(--c15t-duration-normal, 200ms) var(--c15t-easing, cubic-bezier(0.4, 0, 0.2, 1))';
@@ -4933,12 +6087,6 @@ var __webpack_exports__ = {};
4933
6087
  function persistedOverridesEqual(a, b) {
4934
6088
  return a.country === b.country && a.region === b.region && a.language === b.language && a.gpc === b.gpc;
4935
6089
  }
4936
- function getBlockedRequestMessage(payload) {
4937
- const data = payload;
4938
- const method = 'string' == typeof data?.method ? data.method.toUpperCase() : 'REQUEST';
4939
- const url = 'string' == typeof data?.url ? data.url : 'unknown-url';
4940
- return `Network blocked: ${method} ${url}`;
4941
- }
4942
6090
  function prefersReducedMotion() {
4943
6091
  return 'undefined' != typeof window && 'function' == typeof window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
4944
6092
  }
@@ -4999,74 +6147,43 @@ var __webpack_exports__ = {};
4999
6147
  destroy: clearAnimationState
5000
6148
  };
5001
6149
  }
6150
+ function createStateCopy(state) {
6151
+ return {
6152
+ consents: state.consents,
6153
+ selectedConsents: state.selectedConsents,
6154
+ consentInfo: state.consentInfo,
6155
+ locationInfo: state.locationInfo,
6156
+ model: state.model,
6157
+ overrides: state.overrides,
6158
+ scripts: state.scripts?.map((script)=>({
6159
+ id: script.id
6160
+ })),
6161
+ loadedScripts: state.loadedScripts
6162
+ };
6163
+ }
5002
6164
  function createDevTools(options = {}) {
5003
6165
  const { namespace = 'c15tStore', position = 'bottom-right', defaultOpen = false } = options;
5004
6166
  const stateManager = createStateManager({
5005
6167
  position,
5006
6168
  isOpen: defaultOpen
5007
6169
  });
5008
- let originalCallbacks = {};
5009
- let originalNetworkBlockedCallback;
5010
- let hasWrappedNetworkBlockerCallback = false;
6170
+ let detachInstrumentation = null;
5011
6171
  const storeConnector = createStoreConnector({
5012
6172
  namespace,
5013
- onConnect: (state, store)=>{
6173
+ onConnect: (_state, store)=>{
6174
+ detachInstrumentation?.();
6175
+ detachInstrumentation = registerStoreInstrumentation({
6176
+ namespace,
6177
+ store,
6178
+ onEvent: (event)=>{
6179
+ stateManager.addEvent(event);
6180
+ }
6181
+ });
5014
6182
  stateManager.setConnected(true);
5015
6183
  stateManager.addEvent({
5016
6184
  type: 'info',
5017
6185
  message: 'Connected to c15tStore'
5018
6186
  });
5019
- originalCallbacks = {
5020
- ...state.callbacks
5021
- };
5022
- store.getState().setCallback('onBannerFetched', (payload)=>{
5023
- stateManager.addEvent({
5024
- type: 'info',
5025
- message: `Banner fetched: ${String(payload.jurisdiction)}`,
5026
- data: payload
5027
- });
5028
- if ('function' == typeof originalCallbacks.onBannerFetched) originalCallbacks.onBannerFetched(payload);
5029
- });
5030
- store.getState().setCallback('onConsentSet', (payload)=>{
5031
- stateManager.addEvent({
5032
- type: 'consent_set',
5033
- message: 'Consent preferences updated',
5034
- data: payload
5035
- });
5036
- if ('function' == typeof originalCallbacks.onConsentSet) originalCallbacks.onConsentSet(payload);
5037
- });
5038
- store.getState().setCallback('onError', (payload)=>{
5039
- stateManager.addEvent({
5040
- type: 'error',
5041
- message: `Error: ${payload.error}`,
5042
- data: payload
5043
- });
5044
- if ('function' == typeof originalCallbacks.onError) originalCallbacks.onError(payload);
5045
- });
5046
- store.getState().setCallback('onBeforeConsentRevocationReload', (payload)=>{
5047
- stateManager.addEvent({
5048
- type: 'info',
5049
- message: 'Consent revocation - page will reload',
5050
- data: payload
5051
- });
5052
- if ('function' == typeof originalCallbacks.onBeforeConsentRevocationReload) originalCallbacks.onBeforeConsentRevocationReload(payload);
5053
- });
5054
- const currentNetworkBlocker = store.getState().networkBlocker;
5055
- if (currentNetworkBlocker && !hasWrappedNetworkBlockerCallback) {
5056
- originalNetworkBlockedCallback = currentNetworkBlocker.onRequestBlocked;
5057
- hasWrappedNetworkBlockerCallback = true;
5058
- store.getState().setNetworkBlocker({
5059
- ...currentNetworkBlocker,
5060
- onRequestBlocked: (payload)=>{
5061
- stateManager.addEvent({
5062
- type: 'network',
5063
- message: getBlockedRequestMessage(payload),
5064
- data: payload
5065
- });
5066
- if ('function' == typeof originalNetworkBlockedCallback) originalNetworkBlockedCallback(payload);
5067
- }
5068
- });
5069
- }
5070
6187
  const persistedOverrides = loadPersistedOverrides();
5071
6188
  if (persistedOverrides) {
5072
6189
  const currentOverrides = normalizeOverridesForPersistence(store.getState().overrides);
@@ -5096,6 +6213,8 @@ var __webpack_exports__ = {};
5096
6213
  },
5097
6214
  onDisconnect: ()=>{
5098
6215
  stateManager.setConnected(false);
6216
+ detachInstrumentation?.();
6217
+ detachInstrumentation = null;
5099
6218
  stateManager.addEvent({
5100
6219
  type: 'error',
5101
6220
  message: 'Disconnected from c15tStore'
@@ -5103,6 +6222,31 @@ var __webpack_exports__ = {};
5103
6222
  },
5104
6223
  onStateChange: ()=>{}
5105
6224
  });
6225
+ const panelRenderer = createPanelRenderer({
6226
+ storeConnector,
6227
+ stateManager,
6228
+ enableEventLogging: true,
6229
+ onPersistOverrides: persistOverrides,
6230
+ onClearPersistedOverrides: clearPersistedOverrides,
6231
+ onCopyState: async (state)=>{
6232
+ try {
6233
+ await navigator.clipboard.writeText(JSON.stringify(createStateCopy(state), null, 2));
6234
+ return true;
6235
+ } catch {
6236
+ return false;
6237
+ }
6238
+ },
6239
+ onExportDebugBundle: ()=>{
6240
+ const bundle = createDebugBundle({
6241
+ namespace,
6242
+ devToolsState: stateManager.getState(),
6243
+ connection: storeConnector.getDiagnostics(),
6244
+ recentEvents: stateManager.getState().eventLog.slice(0, 100),
6245
+ storeState: sanitizeStoreState(storeConnector.getState())
6246
+ });
6247
+ downloadDebugBundle(bundle);
6248
+ }
6249
+ });
5106
6250
  let tabsInstance = null;
5107
6251
  const panelHeightAnimator = createPanelHeightAnimator();
5108
6252
  const panelInstance = createPanel({
@@ -5110,19 +6254,24 @@ var __webpack_exports__ = {};
5110
6254
  storeConnector,
5111
6255
  namespace,
5112
6256
  onRenderContent: (container)=>{
5113
- renderContent(container, stateManager, storeConnector);
6257
+ renderContent(container);
5114
6258
  }
5115
6259
  });
5116
- function renderContent(container, stateManager, storeConnector) {
6260
+ function renderContent(container) {
5117
6261
  const panel = container.parentElement;
5118
6262
  const previousPanelHeight = panel?.getBoundingClientRect().height ?? 0;
5119
6263
  clearElement(container);
5120
6264
  const storeState = storeConnector.getState();
5121
6265
  const disabledTabs = [];
5122
6266
  if (!storeState || 'iab' !== storeState.model) disabledTabs.push('iab');
6267
+ let currentActiveTab = stateManager.getState().activeTab;
6268
+ if (disabledTabs.includes(currentActiveTab)) {
6269
+ stateManager.setActiveTab('consents');
6270
+ currentActiveTab = 'consents';
6271
+ }
5123
6272
  if (tabsInstance) tabsInstance.destroy();
5124
6273
  tabsInstance = createTabs({
5125
- activeTab: stateManager.getState().activeTab,
6274
+ activeTab: currentActiveTab,
5126
6275
  onTabChange: (tab)=>{
5127
6276
  stateManager.setActiveTab(tab);
5128
6277
  },
@@ -5137,284 +6286,9 @@ var __webpack_exports__ = {};
5137
6286
  }
5138
6287
  });
5139
6288
  container.appendChild(panelContent);
5140
- const state = stateManager.getState();
5141
- const getStoreState = ()=>storeConnector.getState();
5142
- switch(state.activeTab){
5143
- case 'consents':
5144
- renderConsentsPanel(panelContent, {
5145
- getState: getStoreState,
5146
- onConsentChange: (name, value)=>{
5147
- const store = storeConnector.getStore();
5148
- if (store) {
5149
- const consentName = String(name);
5150
- store.getState().setSelectedConsent(consentName, value);
5151
- stateManager.addEvent({
5152
- type: 'info',
5153
- message: `${consentName} toggled to ${value} (not saved)`,
5154
- data: {
5155
- name: consentName,
5156
- value
5157
- }
5158
- });
5159
- }
5160
- },
5161
- onSave: ()=>{
5162
- const store = storeConnector.getStore();
5163
- if (store) {
5164
- store.getState().saveConsents('custom');
5165
- stateManager.addEvent({
5166
- type: 'consent_save',
5167
- message: 'Saved consent preferences'
5168
- });
5169
- }
5170
- },
5171
- onAcceptAll: ()=>{
5172
- const store = storeConnector.getStore();
5173
- if (store) {
5174
- store.getState().saveConsents('all');
5175
- stateManager.addEvent({
5176
- type: 'consent_save',
5177
- message: 'Accepted all consents'
5178
- });
5179
- }
5180
- },
5181
- onRejectAll: ()=>{
5182
- const store = storeConnector.getStore();
5183
- if (store) {
5184
- store.getState().saveConsents('necessary');
5185
- stateManager.addEvent({
5186
- type: 'consent_save',
5187
- message: 'Rejected all optional consents'
5188
- });
5189
- }
5190
- },
5191
- onReset: async ()=>{
5192
- const store = storeConnector.getStore();
5193
- if (store) await resetAllConsents(store, stateManager);
5194
- }
5195
- });
5196
- break;
5197
- case 'location':
5198
- renderLocationPanel(panelContent, {
5199
- getState: getStoreState,
5200
- onApplyOverrides: async (overrides)=>{
5201
- const store = storeConnector.getStore();
5202
- if (store) {
5203
- await store.getState().setOverrides({
5204
- country: overrides.country,
5205
- region: overrides.region,
5206
- language: overrides.language,
5207
- gpc: overrides.gpc
5208
- });
5209
- persistOverrides({
5210
- country: overrides.country,
5211
- region: overrides.region,
5212
- language: overrides.language,
5213
- gpc: overrides.gpc
5214
- });
5215
- stateManager.addEvent({
5216
- type: 'info',
5217
- message: 'Overrides updated',
5218
- data: {
5219
- country: overrides.country,
5220
- region: overrides.region,
5221
- language: overrides.language,
5222
- gpc: overrides.gpc
5223
- }
5224
- });
5225
- }
5226
- },
5227
- onClearOverrides: async ()=>{
5228
- const store = storeConnector.getStore();
5229
- if (store) {
5230
- await store.getState().setOverrides({
5231
- country: void 0,
5232
- region: void 0,
5233
- language: void 0,
5234
- gpc: void 0
5235
- });
5236
- clearPersistedOverrides();
5237
- stateManager.addEvent({
5238
- type: 'info',
5239
- message: 'Overrides cleared'
5240
- });
5241
- }
5242
- }
5243
- });
5244
- break;
5245
- case "scripts":
5246
- renderScriptsPanel(panelContent, {
5247
- getState: getStoreState,
5248
- getEvents: ()=>stateManager.getState().eventLog
5249
- });
5250
- break;
5251
- case 'iab':
5252
- renderIabPanel(panelContent, {
5253
- getState: getStoreState,
5254
- onSetPurposeConsent: (purposeId, value)=>{
5255
- const iab = storeConnector.getStore()?.getState().iab;
5256
- if (!iab) return;
5257
- iab.setPurposeConsent(purposeId, value);
5258
- stateManager.addEvent({
5259
- type: 'iab',
5260
- message: `IAB purpose ${purposeId} set to ${value}`,
5261
- data: {
5262
- purposeId,
5263
- value
5264
- }
5265
- });
5266
- },
5267
- onSetVendorConsent: (vendorId, value)=>{
5268
- const iab = storeConnector.getStore()?.getState().iab;
5269
- if (!iab) return;
5270
- iab.setVendorConsent(vendorId, value);
5271
- stateManager.addEvent({
5272
- type: 'iab',
5273
- message: `IAB vendor ${vendorId} set to ${value}`,
5274
- data: {
5275
- vendorId,
5276
- value
5277
- }
5278
- });
5279
- },
5280
- onSetSpecialFeatureOptIn: (featureId, value)=>{
5281
- const iab = storeConnector.getStore()?.getState().iab;
5282
- if (!iab) return;
5283
- iab.setSpecialFeatureOptIn(featureId, value);
5284
- stateManager.addEvent({
5285
- type: 'iab',
5286
- message: `IAB feature ${featureId} set to ${value}`,
5287
- data: {
5288
- featureId,
5289
- value
5290
- }
5291
- });
5292
- },
5293
- onAcceptAll: ()=>{
5294
- const iab = storeConnector.getStore()?.getState().iab;
5295
- if (!iab) return;
5296
- iab.acceptAll();
5297
- stateManager.addEvent({
5298
- type: 'iab',
5299
- message: 'IAB accept all selected'
5300
- });
5301
- },
5302
- onRejectAll: ()=>{
5303
- const iab = storeConnector.getStore()?.getState().iab;
5304
- if (!iab) return;
5305
- iab.rejectAll();
5306
- stateManager.addEvent({
5307
- type: 'iab',
5308
- message: 'IAB reject all selected'
5309
- });
5310
- },
5311
- onSave: ()=>{
5312
- const iab = storeConnector.getStore()?.getState().iab;
5313
- if (!iab) return;
5314
- iab.save().then(()=>{
5315
- stateManager.addEvent({
5316
- type: 'iab',
5317
- message: 'IAB preferences saved'
5318
- });
5319
- }).catch((error)=>{
5320
- stateManager.addEvent({
5321
- type: 'error',
5322
- message: `Failed to save IAB preferences: ${String(error)}`
5323
- });
5324
- });
5325
- },
5326
- onReset: async ()=>{
5327
- const store = storeConnector.getStore();
5328
- if (store) await resetAllConsents(store, stateManager);
5329
- }
5330
- });
5331
- break;
5332
- case 'events':
5333
- renderEventsPanel(panelContent, {
5334
- getEvents: ()=>stateManager.getState().eventLog,
5335
- onClear: ()=>{
5336
- stateManager.clearEventLog();
5337
- stateManager.addEvent({
5338
- type: 'info',
5339
- message: 'Event log cleared'
5340
- });
5341
- }
5342
- });
5343
- break;
5344
- case 'actions':
5345
- renderActionsPanel(panelContent, {
5346
- getState: getStoreState,
5347
- onResetConsents: async ()=>{
5348
- const store = storeConnector.getStore();
5349
- if (store) await resetAllConsents(store, stateManager);
5350
- },
5351
- onRefetchBanner: async ()=>{
5352
- const store = storeConnector.getStore();
5353
- if (store) {
5354
- await store.getState().initConsentManager();
5355
- stateManager.addEvent({
5356
- type: 'info',
5357
- message: 'Banner data refetched'
5358
- });
5359
- }
5360
- },
5361
- onShowBanner: ()=>{
5362
- const store = storeConnector.getStore();
5363
- if (store) {
5364
- store.getState().setActiveUI('banner', {
5365
- force: true
5366
- });
5367
- stateManager.addEvent({
5368
- type: 'info',
5369
- message: 'Banner shown'
5370
- });
5371
- }
5372
- },
5373
- onOpenPreferences: ()=>{
5374
- const store = storeConnector.getStore();
5375
- if (store) {
5376
- store.getState().setActiveUI('dialog');
5377
- stateManager.addEvent({
5378
- type: 'info',
5379
- message: 'Preference center opened'
5380
- });
5381
- }
5382
- },
5383
- onCopyState: ()=>{
5384
- const state = storeConnector.getState();
5385
- if (state) {
5386
- const stateCopy = {
5387
- consents: state.consents,
5388
- consentInfo: state.consentInfo,
5389
- locationInfo: state.locationInfo,
5390
- model: state.model,
5391
- overrides: state.overrides,
5392
- scripts: state.scripts?.map((s)=>({
5393
- id: s.id
5394
- })),
5395
- loadedScripts: state.loadedScripts
5396
- };
5397
- navigator.clipboard.writeText(JSON.stringify(stateCopy, null, 2)).then(()=>{
5398
- stateManager.addEvent({
5399
- type: 'info',
5400
- message: 'State copied to clipboard'
5401
- });
5402
- }).catch(()=>{
5403
- stateManager.addEvent({
5404
- type: 'error',
5405
- message: 'Failed to copy state'
5406
- });
5407
- });
5408
- }
5409
- }
5410
- });
5411
- break;
5412
- }
6289
+ panelRenderer.renderPanel(panelContent, currentActiveTab);
5413
6290
  if (panel) panelHeightAnimator.animate(panel, previousPanelHeight);
5414
6291
  }
5415
- storeConnector.subscribe(()=>{
5416
- panelInstance.update();
5417
- });
5418
6292
  const instance = {
5419
6293
  open: ()=>stateManager.setOpen(true),
5420
6294
  close: ()=>stateManager.setOpen(false),
@@ -5428,20 +6302,8 @@ var __webpack_exports__ = {};
5428
6302
  };
5429
6303
  },
5430
6304
  destroy: ()=>{
5431
- const store = storeConnector.getStore();
5432
- if (store) {
5433
- store.getState().setCallback('onBannerFetched', originalCallbacks.onBannerFetched);
5434
- store.getState().setCallback('onConsentSet', originalCallbacks.onConsentSet);
5435
- store.getState().setCallback('onError', originalCallbacks.onError);
5436
- store.getState().setCallback('onBeforeConsentRevocationReload', originalCallbacks.onBeforeConsentRevocationReload);
5437
- if (hasWrappedNetworkBlockerCallback) {
5438
- const currentNetworkBlocker = store.getState().networkBlocker;
5439
- if (currentNetworkBlocker) store.getState().setNetworkBlocker({
5440
- ...currentNetworkBlocker,
5441
- onRequestBlocked: originalNetworkBlockedCallback
5442
- });
5443
- }
5444
- }
6305
+ detachInstrumentation?.();
6306
+ detachInstrumentation = null;
5445
6307
  panelHeightAnimator.destroy();
5446
6308
  tabsInstance?.destroy();
5447
6309
  panelInstance.destroy();
@@ -5455,31 +6317,20 @@ var __webpack_exports__ = {};
5455
6317
  }
5456
6318
  function createDevToolsPanel(options) {
5457
6319
  const { namespace = 'c15tStore' } = options;
5458
- let originalEmbeddedNetworkBlockedCallback;
5459
- let hasWrappedEmbeddedNetworkBlocker = false;
6320
+ let detachInstrumentation = null;
5460
6321
  const stateManager = createStateManager({
5461
6322
  isOpen: true
5462
6323
  });
5463
6324
  const storeConnector = createStoreConnector({
5464
6325
  namespace,
5465
6326
  onConnect: (state, store)=>{
6327
+ detachInstrumentation?.();
6328
+ detachInstrumentation = registerStoreInstrumentation({
6329
+ namespace,
6330
+ store,
6331
+ onEvent: (event)=>stateManager.addEvent(event)
6332
+ });
5466
6333
  stateManager.setConnected(true);
5467
- const currentNetworkBlocker = state.networkBlocker;
5468
- if (currentNetworkBlocker && !hasWrappedEmbeddedNetworkBlocker) {
5469
- originalEmbeddedNetworkBlockedCallback = currentNetworkBlocker.onRequestBlocked;
5470
- hasWrappedEmbeddedNetworkBlocker = true;
5471
- store.getState().setNetworkBlocker({
5472
- ...currentNetworkBlocker,
5473
- onRequestBlocked: (payload)=>{
5474
- stateManager.addEvent({
5475
- type: 'network',
5476
- message: getBlockedRequestMessage(payload),
5477
- data: payload
5478
- });
5479
- if ('function' == typeof originalEmbeddedNetworkBlockedCallback) originalEmbeddedNetworkBlockedCallback(payload);
5480
- }
5481
- });
5482
- }
5483
6334
  const persistedOverrides = loadPersistedOverrides();
5484
6335
  if (persistedOverrides) {
5485
6336
  const currentOverrides = normalizeOverridesForPersistence(state.overrides);
@@ -5491,7 +6342,36 @@ var __webpack_exports__ = {};
5491
6342
  });
5492
6343
  }
5493
6344
  },
5494
- onDisconnect: ()=>stateManager.setConnected(false)
6345
+ onDisconnect: ()=>{
6346
+ stateManager.setConnected(false);
6347
+ detachInstrumentation?.();
6348
+ detachInstrumentation = null;
6349
+ }
6350
+ });
6351
+ const panelRenderer = createPanelRenderer({
6352
+ storeConnector,
6353
+ stateManager,
6354
+ enableEventLogging: false,
6355
+ onPersistOverrides: persistOverrides,
6356
+ onClearPersistedOverrides: clearPersistedOverrides,
6357
+ onCopyState: async (state)=>{
6358
+ try {
6359
+ await navigator.clipboard.writeText(JSON.stringify(createStateCopy(state), null, 2));
6360
+ return true;
6361
+ } catch {
6362
+ return false;
6363
+ }
6364
+ },
6365
+ onExportDebugBundle: ()=>{
6366
+ const bundle = createDebugBundle({
6367
+ namespace,
6368
+ devToolsState: stateManager.getState(),
6369
+ connection: storeConnector.getDiagnostics(),
6370
+ recentEvents: stateManager.getState().eventLog.slice(0, 100),
6371
+ storeState: sanitizeStoreState(storeConnector.getState())
6372
+ });
6373
+ downloadDebugBundle(bundle);
6374
+ }
5495
6375
  });
5496
6376
  const container = renderer_div({
5497
6377
  style: {
@@ -5512,140 +6392,42 @@ var __webpack_exports__ = {};
5512
6392
  }
5513
6393
  });
5514
6394
  function renderActivePanel() {
5515
- const state = stateManager.getState();
5516
- const getStoreState = ()=>storeConnector.getState();
5517
- switch(state.activeTab){
5518
- case 'consents':
5519
- renderConsentsPanel(contentArea, {
5520
- getState: getStoreState,
5521
- onConsentChange: (name, value)=>{
5522
- storeConnector.getStore()?.getState().setSelectedConsent(name, value);
5523
- },
5524
- onSave: ()=>{
5525
- storeConnector.getStore()?.getState().saveConsents('custom');
5526
- },
5527
- onAcceptAll: ()=>{
5528
- storeConnector.getStore()?.getState().saveConsents('all');
5529
- },
5530
- onRejectAll: ()=>{
5531
- storeConnector.getStore()?.getState().saveConsents('necessary');
5532
- },
5533
- onReset: async ()=>{
5534
- const store = storeConnector.getStore();
5535
- if (store) await resetAllConsents(store);
5536
- }
5537
- });
5538
- break;
5539
- case 'location':
5540
- renderLocationPanel(contentArea, {
5541
- getState: getStoreState,
5542
- onApplyOverrides: async (overrides)=>{
5543
- const store = storeConnector.getStore();
5544
- if (store) {
5545
- await store.getState().setOverrides({
5546
- country: overrides.country,
5547
- region: overrides.region,
5548
- language: overrides.language,
5549
- gpc: overrides.gpc
5550
- });
5551
- persistOverrides({
5552
- country: overrides.country,
5553
- region: overrides.region,
5554
- language: overrides.language,
5555
- gpc: overrides.gpc
5556
- });
5557
- }
5558
- },
5559
- onClearOverrides: async ()=>{
5560
- await storeConnector.getStore()?.getState().setOverrides({
5561
- country: void 0,
5562
- region: void 0,
5563
- language: void 0,
5564
- gpc: void 0
5565
- });
5566
- clearPersistedOverrides();
5567
- }
5568
- });
5569
- break;
5570
- case "scripts":
5571
- renderScriptsPanel(contentArea, {
5572
- getState: getStoreState,
5573
- getEvents: ()=>stateManager.getState().eventLog
5574
- });
5575
- break;
5576
- case 'iab':
5577
- renderIabPanel(contentArea, {
5578
- getState: getStoreState,
5579
- onSetPurposeConsent: (purposeId, value)=>{
5580
- storeConnector.getStore()?.getState().iab?.setPurposeConsent(purposeId, value);
5581
- },
5582
- onSetVendorConsent: (vendorId, value)=>{
5583
- storeConnector.getStore()?.getState().iab?.setVendorConsent(vendorId, value);
5584
- },
5585
- onSetSpecialFeatureOptIn: (featureId, value)=>{
5586
- storeConnector.getStore()?.getState().iab?.setSpecialFeatureOptIn(featureId, value);
5587
- },
5588
- onAcceptAll: ()=>{
5589
- storeConnector.getStore()?.getState().iab?.acceptAll();
5590
- },
5591
- onRejectAll: ()=>{
5592
- storeConnector.getStore()?.getState().iab?.rejectAll();
5593
- },
5594
- onSave: ()=>{
5595
- storeConnector.getStore()?.getState().iab?.save();
5596
- },
5597
- onReset: async ()=>{
5598
- const store = storeConnector.getStore();
5599
- if (store) await resetAllConsents(store);
5600
- }
5601
- });
5602
- break;
5603
- case 'events':
5604
- renderEventsPanel(contentArea, {
5605
- getEvents: ()=>stateManager.getState().eventLog,
5606
- onClear: ()=>{
5607
- stateManager.clearEventLog();
5608
- }
5609
- });
5610
- break;
5611
- case 'actions':
5612
- renderActionsPanel(contentArea, {
5613
- getState: getStoreState,
5614
- onResetConsents: async ()=>{
5615
- const store = storeConnector.getStore();
5616
- if (store) await resetAllConsents(store);
5617
- },
5618
- onRefetchBanner: async ()=>{
5619
- await storeConnector.getStore()?.getState().initConsentManager();
5620
- },
5621
- onShowBanner: ()=>{
5622
- storeConnector.getStore()?.getState().setActiveUI('banner', {
5623
- force: true
5624
- });
5625
- },
5626
- onOpenPreferences: ()=>{
5627
- storeConnector.getStore()?.getState().setActiveUI('dialog');
5628
- },
5629
- onCopyState: ()=>{
5630
- const state = storeConnector.getState();
5631
- if (state) navigator.clipboard.writeText(JSON.stringify(state, null, 2));
5632
- }
5633
- });
5634
- break;
6395
+ const activeTab = syncTabs();
6396
+ panelRenderer.renderPanel(contentArea, activeTab);
6397
+ }
6398
+ let tabsInstance = null;
6399
+ let iabDisabled = true;
6400
+ function getDisabledTabs() {
6401
+ const disabledTabs = [];
6402
+ const storeState = storeConnector.getState();
6403
+ if (!storeState || 'iab' !== storeState.model) disabledTabs.push('iab');
6404
+ return disabledTabs;
6405
+ }
6406
+ function syncTabs() {
6407
+ const disabledTabs = getDisabledTabs();
6408
+ const nextIabDisabled = disabledTabs.includes('iab');
6409
+ let activeTab = stateManager.getState().activeTab;
6410
+ if (disabledTabs.includes(activeTab)) {
6411
+ activeTab = 'consents';
6412
+ stateManager.setActiveTab(activeTab);
6413
+ }
6414
+ if (tabsInstance && iabDisabled === nextIabDisabled) tabsInstance.setActiveTab(activeTab);
6415
+ else {
6416
+ tabsInstance?.destroy();
6417
+ tabsInstance = createTabs({
6418
+ activeTab,
6419
+ onTabChange: (tab)=>{
6420
+ stateManager.setActiveTab(tab);
6421
+ renderActivePanel();
6422
+ },
6423
+ disabledTabs
6424
+ });
6425
+ iabDisabled = nextIabDisabled;
6426
+ if (!tabsInstance.element.parentElement) container.appendChild(tabsInstance.element);
5635
6427
  }
6428
+ return activeTab;
5636
6429
  }
5637
- const storeState = storeConnector.getState();
5638
- const disabledTabs = [];
5639
- if (!storeState || 'iab' !== storeState.model) disabledTabs.push('iab');
5640
- const tabsInstance = createTabs({
5641
- activeTab: stateManager.getState().activeTab,
5642
- onTabChange: (tab)=>{
5643
- stateManager.setActiveTab(tab);
5644
- renderActivePanel();
5645
- },
5646
- disabledTabs
5647
- });
5648
- container.appendChild(tabsInstance.element);
6430
+ syncTabs();
5649
6431
  container.appendChild(contentArea);
5650
6432
  renderActivePanel();
5651
6433
  const unsubscribe = storeConnector.subscribe(()=>{
@@ -5654,16 +6436,10 @@ var __webpack_exports__ = {};
5654
6436
  return {
5655
6437
  element: container,
5656
6438
  destroy: ()=>{
5657
- const store = storeConnector.getStore();
5658
- if (store && hasWrappedEmbeddedNetworkBlocker) {
5659
- const currentNetworkBlocker = store.getState().networkBlocker;
5660
- if (currentNetworkBlocker) store.getState().setNetworkBlocker({
5661
- ...currentNetworkBlocker,
5662
- onRequestBlocked: originalEmbeddedNetworkBlockedCallback
5663
- });
5664
- }
6439
+ detachInstrumentation?.();
6440
+ detachInstrumentation = null;
5665
6441
  unsubscribe();
5666
- tabsInstance.destroy();
6442
+ tabsInstance?.destroy();
5667
6443
  storeConnector.destroy();
5668
6444
  stateManager.destroy();
5669
6445
  }