@seatlayer/js 0.50.2 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +330 -245
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +330 -245
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -2659,6 +2659,10 @@ var DEFAULT_MAX_SELECTION2 = 10;
|
|
|
2659
2659
|
var EXTEND_PROMPT_MS = 6e4;
|
|
2660
2660
|
var MAX_3D_SEATS_DEFAULT = 6e4;
|
|
2661
2661
|
var MAX_3D_SECTION_PILLS = 12;
|
|
2662
|
+
function tfStatic(key, fallback) {
|
|
2663
|
+
const v = (0, import_core2.t)(key);
|
|
2664
|
+
return v === key ? fallback : v;
|
|
2665
|
+
}
|
|
2662
2666
|
function pointInPolygon(x, y, poly) {
|
|
2663
2667
|
let inside = false;
|
|
2664
2668
|
for (let i = 0, j = poly.length - 1; i < poly.length; j = i++) {
|
|
@@ -2833,11 +2837,30 @@ var CSS2 = (
|
|
|
2833
2837
|
.sl-picker[data-layout="narrow"] .sl-map{min-height:0;flex:1}
|
|
2834
2838
|
.sl-picker[data-layout="narrow"] .sl-side{width:100%;border-left:0;border-top:1px solid var(--sl-line);
|
|
2835
2839
|
flex:none;height:min(72%,480px);overflow:hidden;transition:height .3s cubic-bezier(.2,.8,.2,1);overscroll-behavior:contain}
|
|
2836
|
-
.sl-picker[data-layout="narrow"][data-sheet="open"][data-has-selection="false"] .sl-side{height:min(
|
|
2840
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"][data-has-selection="false"] .sl-side{height:min(380px,64%)}
|
|
2841
|
+
/* With the price list expanded the sheet takes the with-selection height so
|
|
2842
|
+
the tray (cart + best-seats) is never crushed under the fixed-size list. */
|
|
2843
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"][data-prices-open="true"] .sl-side{height:min(480px,74%)}
|
|
2837
2844
|
.sl-picker[data-layout="narrow"][data-sheet="peek"] .sl-side{height:76px;overflow:hidden}
|
|
2838
2845
|
.sl-picker[data-layout="narrow"][data-sheet="peek"] .sl-side > :not(.sl-sheet-head){display:none}
|
|
2839
|
-
.sl-picker[data-layout="narrow"] .sl-tray{flex:1;min-height:
|
|
2846
|
+
.sl-picker[data-layout="narrow"] .sl-tray{flex:1;min-height:96px;overflow-y:auto;overscroll-behavior:contain}
|
|
2847
|
+
.sl-picker[data-layout="narrow"][data-prices-open="true"] .sl-tray{min-height:48px}
|
|
2848
|
+
.sl-picker[data-layout="narrow"] .sl-prices{max-height:150px;overflow-y:auto;overscroll-behavior:contain}
|
|
2840
2849
|
.sl-picker[data-layout="narrow"] .sl-foot{position:static;background:var(--sl-bg)}
|
|
2850
|
+
/* NARROW FOOT SAYS EVERYTHING ONCE (owner report: with a hold the footer ate
|
|
2851
|
+
~190px and the ticket list got a sliver). The sheet head already carries
|
|
2852
|
+
"N tickets \xB7 $total" and the header pill already ticks the clock \u2014 so the
|
|
2853
|
+
total row hides, the secured note collapses to one compact line, and the
|
|
2854
|
+
badge tucks in. The tray gets the pixels; a thin scrollbar shows there is
|
|
2855
|
+
more to scroll. */
|
|
2856
|
+
.sl-picker[data-layout="narrow"] .sl-total{display:none}
|
|
2857
|
+
.sl-picker[data-layout="narrow"] .sl-foot{padding:8px 12px 8px}
|
|
2858
|
+
.sl-picker[data-layout="narrow"] .sl-hold-note{margin-bottom:6px;padding:5px 9px}
|
|
2859
|
+
.sl-picker[data-layout="narrow"] .sl-hold-note svg{display:none}
|
|
2860
|
+
.sl-picker[data-layout="narrow"] .sl-hold-note b{display:inline;margin-right:6px;font-size:11px}
|
|
2861
|
+
.sl-picker[data-layout="narrow"] .sl-hold-copy{display:inline;white-space:normal;font-size:10.5px}
|
|
2862
|
+
.sl-picker[data-layout="narrow"] .sl-powered{margin-top:4px;padding:2px 8px;font-size:11px}
|
|
2863
|
+
.sl-picker[data-layout="narrow"] .sl-tray{scrollbar-width:thin}
|
|
2841
2864
|
.sl-picker[data-layout="narrow"] .sl-foot.empty{display:none}
|
|
2842
2865
|
.sl-picker[data-layout="narrow"] .sl-sheet-head{order:0}
|
|
2843
2866
|
.sl-picker[data-layout="narrow"] .sl-seats-sec{display:none}
|
|
@@ -2845,6 +2868,7 @@ var CSS2 = (
|
|
|
2845
2868
|
.sl-picker[data-layout="narrow"] .sl-filtersec{order:3}
|
|
2846
2869
|
.sl-picker[data-layout="narrow"] .sl-filters{order:4}
|
|
2847
2870
|
.sl-picker[data-layout="narrow"] .sl-prices-sec{order:5}
|
|
2871
|
+
.sl-picker[data-layout="narrow"] .sl-prices-hint{order:6}
|
|
2848
2872
|
.sl-picker[data-layout="narrow"] .sl-pricef{order:6}
|
|
2849
2873
|
.sl-picker[data-layout="narrow"] .sl-prices{order:7}
|
|
2850
2874
|
.sl-picker[data-layout="narrow"] .sl-foot{order:8}
|
|
@@ -2852,6 +2876,7 @@ var CSS2 = (
|
|
|
2852
2876
|
.sl-picker[data-layout="narrow"] .sl-filtersec,
|
|
2853
2877
|
.sl-picker[data-layout="narrow"] .sl-filters,
|
|
2854
2878
|
.sl-picker[data-layout="narrow"] .sl-prices-sec,
|
|
2879
|
+
.sl-picker[data-layout="narrow"] .sl-prices-hint,
|
|
2855
2880
|
.sl-picker[data-layout="narrow"] .sl-prices{display:none!important}
|
|
2856
2881
|
.sl-picker[data-layout="narrow"][data-has-selection="true"] .sl-filtersec,
|
|
2857
2882
|
.sl-picker[data-layout="narrow"][data-has-selection="true"] .sl-filters,
|
|
@@ -2869,7 +2894,13 @@ var CSS2 = (
|
|
|
2869
2894
|
head is the tap/swipe toggle target (min 44px), so it reads as one control. */
|
|
2870
2895
|
.sl-sheet-head{display:none;flex-direction:column;justify-content:center;padding:6px 12px 8px;min-height:56px;
|
|
2871
2896
|
cursor:pointer;touch-action:none;user-select:none;-webkit-user-select:none;flex:none}
|
|
2872
|
-
.sl-picker[data-layout="narrow"] .sl-sheet-head{display:flex;min-height:
|
|
2897
|
+
.sl-picker[data-layout="narrow"] .sl-sheet-head{display:flex;min-height:52px;padding:3px 10px 5px}
|
|
2898
|
+
/* OPEN sheet: the head is context, not controls \u2014 the pill it carries at peek
|
|
2899
|
+
("Best seats"/"Continue") duplicates the card and CTA right below it, and
|
|
2900
|
+
every saved pixel is tray room (owner call 2026-08-14). */
|
|
2901
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-sheet-head{min-height:42px}
|
|
2902
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-sheet-bar{min-height:32px}
|
|
2903
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-sheet-peek .go{display:none}
|
|
2873
2904
|
.sl-picker[data-layout="narrow"][data-sheet="peek"] .sl-sheet-head{height:100%}
|
|
2874
2905
|
.sl-sheet-grab{width:36px;height:4px;border-radius:999px;background:var(--sl-muted);opacity:.55;margin:1px auto 5px}
|
|
2875
2906
|
.sl-sheet-bar{display:flex;align-items:center;gap:8px;min-height:44px}
|
|
@@ -2910,9 +2941,19 @@ var CSS2 = (
|
|
|
2910
2941
|
sheet brings it back, exactly like the filters row above. The tray hint comes
|
|
2911
2942
|
back with it: the first-time buyer on a phone needs the instruction more than
|
|
2912
2943
|
the desktop buyer, not less. */
|
|
2913
|
-
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-prices-sec{display:flex!important}
|
|
2914
|
-
|
|
2944
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"][data-prices-open="true"] .sl-prices-sec{display:flex!important}
|
|
2945
|
+
/* MOBILE SPACE BELONGS TO THE CART (owner call 2026-08-14): the price list is
|
|
2946
|
+
one tap away behind the "Ticket prices" row, not a permanent tenant. Zone
|
|
2947
|
+
flags and section taps already answer "what does it cost" in context. */
|
|
2948
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"][data-prices-open="true"] .sl-prices-hint{display:block!important}
|
|
2949
|
+
.sl-picker[data-layout="narrow"][data-sheet="open"][data-prices-open="true"] .sl-prices{display:flex!important}
|
|
2915
2950
|
.sl-picker[data-layout="narrow"][data-sheet="open"] .sl-tray-hint{display:block!important}
|
|
2951
|
+
/* The row reads as the toggle it is on narrow: chevron + pointer. */
|
|
2952
|
+
.sl-picker[data-layout="narrow"] .sl-prices-sec{cursor:pointer}
|
|
2953
|
+
.sl-picker[data-layout="narrow"] .sl-prices-sec::after{content:'';width:8px;height:8px;flex:none;margin-left:auto;
|
|
2954
|
+
border-right:2px solid var(--sl-muted);border-bottom:2px solid var(--sl-muted);
|
|
2955
|
+
transform:rotate(45deg);transition:transform .2s cubic-bezier(.2,.8,.2,1)}
|
|
2956
|
+
.sl-picker[data-layout="narrow"][data-prices-open="true"] .sl-prices-sec::after{transform:rotate(-135deg)}
|
|
2916
2957
|
.sl-cbbtn{width:32px;height:32px;border-radius:999px;background:var(--sl-surface);border:1px solid var(--sl-line);
|
|
2917
2958
|
color:var(--sl-text);display:flex;align-items:center;justify-content:center;transition:border-color .15s}
|
|
2918
2959
|
.sl-cbbtn:hover{border-color:var(--sl-muted)}
|
|
@@ -2931,7 +2972,13 @@ var CSS2 = (
|
|
|
2931
2972
|
.sl-sec{padding:14px 14px 4px;font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--sl-muted);font-weight:700}
|
|
2932
2973
|
.sl-prices-sec{display:flex;align-items:center;justify-content:space-between;gap:10px;padding-top:13px}
|
|
2933
2974
|
.sl-price-select{min-height:32px;max-width:130px;padding:5px 28px 5px 9px;border:1px solid var(--sl-line);border-radius:9px;
|
|
2934
|
-
background:var(--sl-surface);color:var(--sl-text);font:inherit;font-size:11px;font-weight:750;letter-spacing:0;text-transform:none}
|
|
2975
|
+
background-color:var(--sl-surface);color:var(--sl-text);font:inherit;font-size:11px;font-weight:750;letter-spacing:0;text-transform:none}
|
|
2976
|
+
/* One sentence that teaches the whole colour code \u2014 a first-time buyer sees
|
|
2977
|
+
"Head Tables \xB7 $165" and coloured dots with nothing connecting them. Gone
|
|
2978
|
+
the moment they have seats (they've learned it) and while sales are closed. */
|
|
2979
|
+
.sl-prices-hint{padding:0 14px 7px;font-size:11px;line-height:1.45;color:var(--sl-muted)}
|
|
2980
|
+
.sl-picker[data-has-selection="true"] .sl-prices-hint,
|
|
2981
|
+
.sl-picker[data-sales-closed="true"] .sl-prices-hint{display:none}
|
|
2935
2982
|
.sl-prices{display:flex;flex-direction:column;padding:4px 14px 8px;border-bottom:1px solid var(--sl-line)}
|
|
2936
2983
|
.sl-prices-sec,.sl-prices,.sl-seats-sec{flex:none}
|
|
2937
2984
|
.sl-price-row{display:flex;align-items:center;gap:7px;min-height:28px;font-size:12px;
|
|
@@ -3091,11 +3138,11 @@ var CSS2 = (
|
|
|
3091
3138
|
color:var(--sl-text);font-size:17px;font-weight:700;display:flex;align-items:center;justify-content:center;transition:border-color .15s}
|
|
3092
3139
|
.sl-zoom button:hover{border-color:var(--sl-muted)}
|
|
3093
3140
|
.sl-zoom svg{width:14px;height:14px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
3094
|
-
/* Full-screen promotion
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
region beside Map|3D
|
|
3098
|
-
|
|
3141
|
+
/* Full-screen promotion: the capability existed (native + iOS overlay +
|
|
3142
|
+
framed-host paths) but hid as the 4th unlabelled glyph in a corner stack \u2014
|
|
3143
|
+
even the owner could not pick it out. dockLayoutChrome docks the SAME
|
|
3144
|
+
button into the top-right region beside Map|3D on EVERY layout and this
|
|
3145
|
+
class dresses it as a labelled pill. */
|
|
3099
3146
|
.sl-zfs-lbl{display:none}
|
|
3100
3147
|
.sl-fs-pill.sl-fs-pill{display:inline-flex;align-items:center;justify-content:center;width:auto;min-height:40px;height:auto;
|
|
3101
3148
|
padding:0 13px;gap:6px;border-radius:999px;font-size:11px;font-weight:800;
|
|
@@ -3103,6 +3150,16 @@ var CSS2 = (
|
|
|
3103
3150
|
.sl-fs-pill.sl-fs-pill:hover{border-color:var(--sl-muted)}
|
|
3104
3151
|
.sl-fs-pill svg{width:14px;height:14px;stroke:currentColor;stroke-width:2;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
3105
3152
|
.sl-fs-pill .sl-zfs-lbl{display:inline;letter-spacing:.02em;white-space:nowrap}
|
|
3153
|
+
/* In the header, icons carry it (owner call): square Full screen glyph, and
|
|
3154
|
+
on narrow a price-tag toggle that opens the sheet with the list expanded. */
|
|
3155
|
+
.sl-head .sl-fs-pill{min-height:34px;min-width:34px;width:34px;padding:0;flex:none}
|
|
3156
|
+
.sl-head .sl-fs-pill .sl-zfs-lbl{display:none}
|
|
3157
|
+
.sl-prices-btn{display:none;align-items:center;justify-content:center;width:34px;min-height:34px;flex:none;
|
|
3158
|
+
border-radius:999px;background:var(--sl-surface);border:1px solid var(--sl-line);color:var(--sl-text);transition:border-color .15s}
|
|
3159
|
+
.sl-prices-btn:hover{border-color:var(--sl-muted)}
|
|
3160
|
+
.sl-prices-btn svg{width:15px;height:15px;stroke:currentColor;stroke-width:1.8;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
3161
|
+
.sl-prices-btn[aria-pressed="true"]{background:var(--sl-accent);color:var(--sl-accent-ink);border-color:transparent}
|
|
3162
|
+
.sl-picker[data-layout="narrow"] .sl-prices-btn{display:inline-flex}
|
|
3106
3163
|
|
|
3107
3164
|
/* toast + boot states (toast flows in the bottom-center region) */
|
|
3108
3165
|
.sl-toast{transform:translateY(6px) scale(.98);max-width:100%;
|
|
@@ -3230,8 +3287,21 @@ var CSS2 = (
|
|
|
3230
3287
|
.sl-confirm-add svg{width:16px;height:16px;stroke:currentColor;stroke-width:2.8;fill:none;stroke-linecap:round;stroke-linejoin:round}
|
|
3231
3288
|
.sl-confirm-cancel{background:color-mix(in srgb,var(--sl-line) 44%,transparent)!important;border:1px solid var(--sl-line)!important;color:var(--sl-muted)!important}
|
|
3232
3289
|
.sl-confirm-cancel:hover{color:var(--sl-text)}
|
|
3233
|
-
.sl-picker[data-layout="narrow"] .sl-confirm{left:50%!important;top:auto!important;bottom:14px;width:min(
|
|
3290
|
+
.sl-picker[data-layout="narrow"] .sl-confirm{left:50%!important;top:auto!important;bottom:14px;width:min(310px,calc(100% - 24px));
|
|
3234
3291
|
transform:translateX(-50%);animation:slConfirmMobileIn .24s cubic-bezier(.2,.8,.2,1) both}
|
|
3292
|
+
/* Phone-size confirm card (owner call 2026-08-14): same content \u2014 identity,
|
|
3293
|
+
price band, view photo, 3D link \u2014 on a tighter grid. The values stay large
|
|
3294
|
+
enough to double-check against the map; buttons keep tap-size. */
|
|
3295
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-field{padding:9px 9px 8px}
|
|
3296
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-value{font-size:15px}
|
|
3297
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-cat{padding:8px 10px}
|
|
3298
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-cat-name{font-size:12.5px}
|
|
3299
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-price{font-size:15px}
|
|
3300
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-body{padding:9px 10px 10px}
|
|
3301
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-thumbwrap{height:62px;margin-bottom:6px}
|
|
3302
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-3d{margin-top:7px;padding:6px}
|
|
3303
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-row{margin-top:8px}
|
|
3304
|
+
.sl-picker[data-layout="narrow"] .sl-confirm-row button{min-height:42px}
|
|
3235
3305
|
|
|
3236
3306
|
/* Atomic whole/variable-table chooser. Lives inside the widget so the same
|
|
3237
3307
|
accessible dialog works in inline, modal, desktop and 390px mobile hosts. */
|
|
@@ -3307,8 +3377,11 @@ var CSS2 = (
|
|
|
3307
3377
|
.sl-ba-premium.on{color:var(--sl-premium-ink);background:linear-gradient(135deg,#f0cf6b,#e0b23f);border-color:transparent;
|
|
3308
3378
|
box-shadow:0 6px 16px color-mix(in srgb,var(--sl-premium) 26%,transparent)}
|
|
3309
3379
|
.sl-ba-premium.on .star{color:#5a4410}
|
|
3310
|
-
.sl-ba select
|
|
3311
|
-
|
|
3380
|
+
.sl-ba select,.sl-price-select{appearance:none;-webkit-appearance:none;
|
|
3381
|
+
background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23949ca9' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
3382
|
+
background-repeat:no-repeat;background-position:right 10px center}
|
|
3383
|
+
.sl-ba select{background-color:var(--sl-surface);color:var(--sl-text);border:1px solid var(--sl-line);border-radius:8px;
|
|
3384
|
+
font:inherit;font-size:11px;padding:7px 26px 7px 8px;min-width:0;width:100%;max-width:none}
|
|
3312
3385
|
.sl-ba-qty{display:flex;align-items:center;gap:7px;padding:3px;border:1px solid var(--sl-line);border-radius:9px;background:var(--sl-surface)}
|
|
3313
3386
|
.sl-ba-qty button{width:25px;height:25px;border-radius:7px;background:color-mix(in srgb,var(--sl-line) 35%,transparent);border:0;
|
|
3314
3387
|
font-size:14px;font-weight:800;display:flex;align-items:center;justify-content:center}
|
|
@@ -3338,9 +3411,23 @@ var CSS2 = (
|
|
|
3338
3411
|
.sl-picker[data-layout="narrow"] .sl-ba-copy{display:none}
|
|
3339
3412
|
.sl-picker[data-layout="narrow"] .sl-ba-copy .wide{display:none}
|
|
3340
3413
|
.sl-picker[data-layout="narrow"] .sl-ba-copy .narrow{display:inline}
|
|
3341
|
-
.sl-picker[data-layout="narrow"] .sl-ba
|
|
3414
|
+
.sl-picker[data-layout="narrow"] .sl-ba{grid-template-columns:auto minmax(0,1fr)}
|
|
3415
|
+
.sl-picker[data-layout="narrow"] .sl-ba select{grid-column:1/-1;min-height:38px}
|
|
3342
3416
|
.sl-picker[data-layout="narrow"] .sl-ba-qty button{width:30px;height:30px}
|
|
3343
|
-
|
|
3417
|
+
/* Quantity and Go share ONE row: a full-width row holding only "\u2212 2 +" was
|
|
3418
|
+
dead space, and the Find button still gets the lion's share. */
|
|
3419
|
+
.sl-picker[data-layout="narrow"] .sl-ba-qty{grid-column:1}
|
|
3420
|
+
.sl-picker[data-layout="narrow"] .sl-ba-go{grid-column:2;min-height:40px}
|
|
3421
|
+
/* Re-entry to best-available once the cart has seats (the card yields its
|
|
3422
|
+
space to chips, but the accelerator must stay reachable) + the quiet way
|
|
3423
|
+
back out of a reopened card. */
|
|
3424
|
+
.sl-ba-reopen{align-self:flex-start;display:inline-flex;align-items:center;gap:6px;min-height:32px;padding:5px 12px;margin-top:2px;
|
|
3425
|
+
border:1px dashed color-mix(in srgb,var(--sl-accent) 40%,var(--sl-line));border-radius:999px;
|
|
3426
|
+
color:var(--sl-accent);font-size:11.5px;font-weight:750;transition:border-color .15s,background .15s}
|
|
3427
|
+
.sl-ba-reopen:hover,.sl-ba-reopen:focus-visible{background:color-mix(in srgb,var(--sl-accent) 8%,transparent)}
|
|
3428
|
+
.sl-ba-back{grid-column:1/-1;justify-self:start;min-height:30px;padding:3px 0;color:var(--sl-muted);
|
|
3429
|
+
font-size:11px;font-weight:700;text-decoration:underline;text-underline-offset:3px;transition:color .15s}
|
|
3430
|
+
.sl-ba-back:hover,.sl-ba-back:focus-visible{color:var(--sl-text)}
|
|
3344
3431
|
|
|
3345
3432
|
/* Sales-closed is a designed state, not a set of disables: one statement in
|
|
3346
3433
|
the tray where the buying flow was, carrying the event's own date so the
|
|
@@ -3359,9 +3446,9 @@ var CSS2 = (
|
|
|
3359
3446
|
(the cart chip's remove/view rail) instead get real height on narrow. */
|
|
3360
3447
|
@media (pointer:coarse){
|
|
3361
3448
|
.sl-zoom button,.sl-cbbtn,.sl-close,.sl-ga-qty button,.sl-ba-qty button,.sl-price-more,
|
|
3362
|
-
.sl-hold-change,.sl-seccard-x,.sl-fs-pill,.sl-side-toggle{position:relative}
|
|
3449
|
+
.sl-hold-change,.sl-seccard-x,.sl-fs-pill,.sl-side-toggle,.sl-ba-reopen{position:relative}
|
|
3363
3450
|
.sl-zoom button::after,.sl-cbbtn::after,.sl-close::after,.sl-ga-qty button::after,.sl-ba-qty button::after,
|
|
3364
|
-
.sl-price-more::after,.sl-hold-change::after,.sl-seccard-x::after,.sl-fs-pill::after,.sl-side-toggle::after{
|
|
3451
|
+
.sl-price-more::after,.sl-hold-change::after,.sl-seccard-x::after,.sl-fs-pill::after,.sl-side-toggle::after,.sl-ba-reopen::after{
|
|
3365
3452
|
content:'';position:absolute;top:50%;left:50%;width:max(100%,44px);height:max(100%,44px);
|
|
3366
3453
|
transform:translate(-50%,-50%)}
|
|
3367
3454
|
/* The chip rail stacks remove over view in ~53px \u2014 pseudo-targets would
|
|
@@ -3464,12 +3551,6 @@ var CSS2 = (
|
|
|
3464
3551
|
border-radius:999px;font:700 11.5px/1 inherit;color:#eef1f8;background:rgba(12,18,32,.86);
|
|
3465
3552
|
border:1px solid rgba(150,165,205,.45);backdrop-filter:blur(6px);cursor:pointer}
|
|
3466
3553
|
.sl-view3d-nav select:focus-visible{outline:2px solid var(--sl-accent);outline-offset:2px}
|
|
3467
|
-
.sl-view3d-nav .sl-view3d-locator{display:grid;grid-template-columns:minmax(150px,1.25fr) minmax(110px,.8fr) minmax(105px,.7fr) auto;
|
|
3468
|
-
width:min(720px,100%);overflow:visible}
|
|
3469
|
-
.sl-view3d-nav.is-seat-focused .sl-view3d-locator{display:none}
|
|
3470
|
-
.sl-view3d-locator select{width:100%;min-width:0}
|
|
3471
|
-
.sl-picker[data-layout="narrow"] .sl-view3d-nav .sl-view3d-locator{display:flex;width:100%;overflow-x:auto}
|
|
3472
|
-
.sl-picker[data-layout="narrow"] .sl-view3d-locator select{flex:0 0 155px}
|
|
3473
3554
|
/* On phones the library owns the bottom edge for seat/panorama/overview actions.
|
|
3474
3555
|
Keep venue navigation in a separate top rail so those control families never
|
|
3475
3556
|
stack over one another. */
|
|
@@ -3479,9 +3560,6 @@ var CSS2 = (
|
|
|
3479
3560
|
.sl-picker[data-layout="narrow"] .sl-view3d-nav.is-open{left:12px;top:68px;max-width:calc(100% - 24px);padding:8px;
|
|
3480
3561
|
border:1px solid rgba(150,165,205,.35);border-radius:14px;background:rgba(8,12,22,.9);backdrop-filter:blur(10px)}
|
|
3481
3562
|
.sl-picker[data-layout="narrow"] .sl-view3d-nav.is-open>div{display:flex}
|
|
3482
|
-
.sl-picker[data-layout="narrow"] .sl-view3d-nav.is-open .sl-view3d-locator{display:grid;grid-template-columns:1fr 1fr;width:100%;overflow:visible}
|
|
3483
|
-
.sl-picker[data-layout="narrow"] .sl-view3d-nav.is-open .sl-view3d-locator select{width:100%;min-width:0;flex:auto}
|
|
3484
|
-
.sl-picker[data-layout="narrow"] .sl-view3d-nav.is-open .sl-view3d-locator button{width:100%}
|
|
3485
3563
|
/* Seat-eye is a decision state, not another venue-navigation state. Once the
|
|
3486
3564
|
buyer arrives, clear the floor/area/locator rails and the module's duplicate
|
|
3487
3565
|
Overview action. The picker-owned Back button becomes the one predictable
|
|
@@ -3907,6 +3985,15 @@ var SeatPicker = class _SeatPicker {
|
|
|
3907
3985
|
this.baZone = "";
|
|
3908
3986
|
/** "★ Best seats" premium quick-pick toggle — biases best-available to premium seats. */
|
|
3909
3987
|
this.baPremium = false;
|
|
3988
|
+
/**
|
|
3989
|
+
* The buyer re-opened the best-seats form with seats already in the cart
|
|
3990
|
+
* ("I picked one, actually find us three together"). The card normally
|
|
3991
|
+
* yields this space to the ticket chips the moment anything is selected —
|
|
3992
|
+
* which removed the accelerator at exactly the moment a one-handed phone
|
|
3993
|
+
* buyer wants it. Cleared when the cart empties, a hold lands, or the
|
|
3994
|
+
* buyer backs out.
|
|
3995
|
+
*/
|
|
3996
|
+
this.baReopen = false;
|
|
3910
3997
|
this.bestAvailableConfirm = false;
|
|
3911
3998
|
this.releasingHold = false;
|
|
3912
3999
|
/** Event sales window is closed (read-only load state / live close). */
|
|
@@ -3984,6 +4071,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
3984
4071
|
/** Wide-layout ticket panel collapsed (map owns the full width). */
|
|
3985
4072
|
this.sideCollapsed = false;
|
|
3986
4073
|
this.sideToggleEl = null;
|
|
4074
|
+
this.pricesBtnEl = null;
|
|
3987
4075
|
/** True once we've asked the host page to pin us fullscreen (framed, no native). */
|
|
3988
4076
|
this.framedFs = false;
|
|
3989
4077
|
/** Last height (px) posted to a host frame; dedupes redundant reports. */
|
|
@@ -4096,7 +4184,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4096
4184
|
if (this.tableDialog?.physicalSeatIds.includes(seat.id)) this.dismissTableDialog();
|
|
4097
4185
|
},
|
|
4098
4186
|
onSelectionLimit: () => {
|
|
4099
|
-
this.toast(
|
|
4187
|
+
this.toast((0, import_core2.t)("picker.maxTicketsForOrder", { count: this.maxTickets }), "warning");
|
|
4100
4188
|
},
|
|
4101
4189
|
onViewChange: () => {
|
|
4102
4190
|
this.reanchorConfirm();
|
|
@@ -4212,8 +4300,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
4212
4300
|
return `<span class="sl-cx-mark" role="img" aria-label="${title}" title="${title}">\u25D0</span>`;
|
|
4213
4301
|
}
|
|
4214
4302
|
wheelchairProvisionLabel(type) {
|
|
4215
|
-
if (type === "no-seat") return "Empty wheelchair space";
|
|
4216
|
-
if (type === "seat-present") return "Accessible physical seat";
|
|
4303
|
+
if (type === "no-seat") return this.tf("picker.emptyWheelchairSpace", "Empty wheelchair space");
|
|
4304
|
+
if (type === "seat-present") return this.tf("picker.accessiblePhysicalSeat", "Accessible physical seat");
|
|
4217
4305
|
return "";
|
|
4218
4306
|
}
|
|
4219
4307
|
wheelchairConfirmHtml(type) {
|
|
@@ -4294,9 +4382,9 @@ var SeatPicker = class _SeatPicker {
|
|
|
4294
4382
|
const hideEventDetails = this.eventDetailsHidden && !active;
|
|
4295
4383
|
this.root?.setAttribute("data-event-details-hidden", String(hideEventDetails));
|
|
4296
4384
|
this.els.zfs?.setAttribute("aria-pressed", String(active));
|
|
4297
|
-
this.els.zfs?.setAttribute("title", active ? "Exit full screen" : "Full screen");
|
|
4385
|
+
this.els.zfs?.setAttribute("title", active ? this.tf("picker.exitFullScreen", "Exit full screen") : this.tf("picker.fullScreen", "Full screen"));
|
|
4298
4386
|
const zfsLabel = this.els.zfs?.querySelector(".sl-zfs-lbl");
|
|
4299
|
-
if (zfsLabel) zfsLabel.textContent = active ? "Exit full screen" : "Full screen";
|
|
4387
|
+
if (zfsLabel) zfsLabel.textContent = active ? this.tf("picker.exitFullScreen", "Exit full screen") : this.tf("picker.fullScreen", "Full screen");
|
|
4300
4388
|
this.view3dEl?.querySelector(".sl-view3d-fs")?.setAttribute("aria-pressed", String(active));
|
|
4301
4389
|
}
|
|
4302
4390
|
/**
|
|
@@ -4361,7 +4449,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4361
4449
|
frame.className = "sl-modal-frame";
|
|
4362
4450
|
frame.setAttribute("role", "dialog");
|
|
4363
4451
|
frame.setAttribute("aria-modal", "true");
|
|
4364
|
-
frame.setAttribute("aria-label", "Seat selection");
|
|
4452
|
+
frame.setAttribute("aria-label", tfStatic("picker.seatSelection", "Seat selection"));
|
|
4365
4453
|
frame.tabIndex = -1;
|
|
4366
4454
|
scrim.appendChild(frame);
|
|
4367
4455
|
document.body.appendChild(scrim);
|
|
@@ -4521,7 +4609,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4521
4609
|
<svg viewBox="0 0 24 24" aria-hidden="true"><rect x="5" y="11" width="14" height="9" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/></svg>
|
|
4522
4610
|
<span data-ref="closedPillText"></span>
|
|
4523
4611
|
</span>
|
|
4524
|
-
<button type="button" class="sl-close" data-ref="close" aria-label="Close">
|
|
4612
|
+
<button type="button" class="sl-close" data-ref="close" aria-label="${this.tf("picker.close", "Close")}">
|
|
4525
4613
|
<svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
|
|
4526
4614
|
</button>
|
|
4527
4615
|
</div>
|
|
@@ -4529,17 +4617,17 @@ var SeatPicker = class _SeatPicker {
|
|
|
4529
4617
|
<div class="sl-map">
|
|
4530
4618
|
<div class="sl-map-host" data-ref="map"></div>
|
|
4531
4619
|
<div class="sl-zoom" data-ref="zoom">
|
|
4532
|
-
<button type="button" aria-label="Zoom in" title="Zoom in" data-ref="zin">+</button>
|
|
4533
|
-
<button type="button" aria-label="Zoom out" title="Zoom out" data-ref="zout">\u2212</button>
|
|
4534
|
-
<button type="button" aria-label="Fit to screen" title="Fit to screen" data-ref="zfit">
|
|
4620
|
+
<button type="button" aria-label="${this.tf("picker.zoomIn", "Zoom in")}" title="${this.tf("picker.zoomIn", "Zoom in")}" data-ref="zin">+</button>
|
|
4621
|
+
<button type="button" aria-label="${this.tf("picker.zoomOut", "Zoom out")}" title="${this.tf("picker.zoomOut", "Zoom out")}" data-ref="zout">\u2212</button>
|
|
4622
|
+
<button type="button" aria-label="${this.tf("picker.fitToScreen", "Fit to screen")}" title="${this.tf("picker.fitToScreen", "Fit to screen")}" data-ref="zfit">
|
|
4535
4623
|
<svg viewBox="0 0 24 24"><path d="M8 3H5a2 2 0 0 0-2 2v3M16 3h3a2 2 0 0 1 2 2v3M8 21H5a2 2 0 0 1-2-2v-3M16 21h3a2 2 0 0 0 2-2v-3"/></svg>
|
|
4536
4624
|
</button>
|
|
4537
|
-
<button type="button" aria-label="Full screen" title="Full screen" aria-pressed="false" data-ref="zfs">
|
|
4625
|
+
<button type="button" aria-label="${this.tf("picker.fullScreen", "Full screen")}" title="${this.tf("picker.fullScreen", "Full screen")}" aria-pressed="false" data-ref="zfs">
|
|
4538
4626
|
<svg viewBox="0 0 24 24"><path d="M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7"/></svg>
|
|
4539
|
-
<span class="sl-zfs-lbl" aria-hidden="true"
|
|
4627
|
+
<span class="sl-zfs-lbl" aria-hidden="true">${this.tf("picker.fullScreen", "Full screen")}</span>
|
|
4540
4628
|
</button>
|
|
4541
4629
|
</div>
|
|
4542
|
-
<div class="sl-boot" data-ref="boot"><span class="sl-boot-spin"></span
|
|
4630
|
+
<div class="sl-boot" data-ref="boot"><span class="sl-boot-spin"></span>${this.tf("picker.loadingSeatMap", "Loading seat map\u2026")}</div>
|
|
4543
4631
|
<div class="sl-toast" data-ref="toast" role="status" aria-live="polite"></div>
|
|
4544
4632
|
</div>
|
|
4545
4633
|
<div class="sl-side" data-ref="side">
|
|
@@ -4547,24 +4635,25 @@ var SeatPicker = class _SeatPicker {
|
|
|
4547
4635
|
<div class="sl-sheet-grab"></div>
|
|
4548
4636
|
<div class="sl-sheet-bar">
|
|
4549
4637
|
<div class="sl-sheet-peek" data-ref="peek"></div>
|
|
4550
|
-
<button type="button" class="sl-sheet-toggle" data-ref="sheetToggle" aria-label="Open ticket panel" aria-expanded="false">
|
|
4638
|
+
<button type="button" class="sl-sheet-toggle" data-ref="sheetToggle" aria-label="${this.tf("picker.openTicketPanel", "Open ticket panel")}" aria-expanded="false">
|
|
4551
4639
|
<svg viewBox="0 0 24 24"><path d="M6 15l6-6 6 6"/></svg>
|
|
4552
4640
|
</button>
|
|
4553
4641
|
</div>
|
|
4554
4642
|
</div>
|
|
4555
|
-
<div class="sl-sec sl-filtersec" data-ref="filtersSec"
|
|
4643
|
+
<div class="sl-sec sl-filtersec" data-ref="filtersSec">${this.tf("picker.filters", "Filters")}</div>
|
|
4556
4644
|
<div class="sl-filters" data-ref="filters"></div>
|
|
4557
4645
|
<div class="sl-offer" data-ref="offer" role="status" aria-live="polite"></div>
|
|
4558
|
-
<div class="sl-sec sl-prices-sec" data-ref="pricesSec"><span
|
|
4646
|
+
<div class="sl-sec sl-prices-sec" data-ref="pricesSec"><span>${this.tf("picker.ticketPrices", "Ticket prices")}</span></div>
|
|
4647
|
+
<div class="sl-prices-hint" data-ref="pricesHint"></div>
|
|
4559
4648
|
<div class="sl-prices" data-ref="prices"></div>
|
|
4560
|
-
<div class="sl-live" data-ref="live" role="status" aria-live="polite"><span class="dot" aria-hidden="true"></span><span data-ref="liveText"
|
|
4561
|
-
<div class="sl-sec sl-seats-sec"><span
|
|
4649
|
+
<div class="sl-live" data-ref="live" role="status" aria-live="polite"><span class="dot" aria-hidden="true"></span><span data-ref="liveText">${this.tf("picker.liveAvailability", "Live availability \u2014 seats update in real time")}</span></div>
|
|
4650
|
+
<div class="sl-sec sl-seats-sec"><span>${this.tf("picker.yourSeats", "Your seats")}</span><span class="sl-seat-summary" data-ref="seatSummary"></span></div>
|
|
4562
4651
|
<div class="sl-tray" data-ref="tray"></div>
|
|
4563
4652
|
<div class="sl-foot" data-ref="foot">
|
|
4564
4653
|
<div class="sl-hold-note" data-ref="holdNote" role="status" aria-live="polite">
|
|
4565
4654
|
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 6L9 17l-5-5"/></svg>
|
|
4566
|
-
<span><b data-ref="holdTitle"
|
|
4567
|
-
<button type="button" class="sl-hold-change" data-ref="holdChange" aria-label="Release held tickets and choose different seats"
|
|
4655
|
+
<span><b data-ref="holdTitle">${this.tf("picker.seatsSecured", "Seats secured")}</b><span class="sl-hold-copy" data-ref="holdCopy">${this.tf("picker.notChargedYet", "You won\u2019t be charged yet.")}</span></span>
|
|
4656
|
+
<button type="button" class="sl-hold-change" data-ref="holdChange" aria-label="${this.tf("picker.releaseHeldTickets", "Release held tickets and choose different seats")}">${this.tf("picker.change", "Change")}</button>
|
|
4568
4657
|
</div>
|
|
4569
4658
|
<div class="sl-total"><span data-ref="count"></span><b data-ref="total"></b></div>
|
|
4570
4659
|
<button type="button" class="sl-cta" data-ref="cta" disabled></button>
|
|
@@ -4615,7 +4704,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4615
4704
|
const setSheet = (open) => {
|
|
4616
4705
|
root.dataset.sheet = open ? "open" : "peek";
|
|
4617
4706
|
toggle?.setAttribute("aria-expanded", String(open));
|
|
4618
|
-
toggle?.setAttribute("aria-label", open ? "Collapse ticket panel" : "Open ticket panel");
|
|
4707
|
+
toggle?.setAttribute("aria-label", open ? this.tf("picker.collapseTicketPanel", "Collapse ticket panel") : this.tf("picker.openTicketPanel", "Open ticket panel"));
|
|
4619
4708
|
};
|
|
4620
4709
|
setSheet(root.dataset.sheet === "open");
|
|
4621
4710
|
toggle?.addEventListener("click", (e) => {
|
|
@@ -4661,6 +4750,39 @@ var SeatPicker = class _SeatPicker {
|
|
|
4661
4750
|
head.releasePointerCapture?.(e.pointerId);
|
|
4662
4751
|
});
|
|
4663
4752
|
}
|
|
4753
|
+
const togglePrices = () => {
|
|
4754
|
+
if (this.root?.dataset.layout !== "narrow") return;
|
|
4755
|
+
const open = this.root.getAttribute("data-prices-open") === "true";
|
|
4756
|
+
this.root.setAttribute("data-prices-open", String(!open));
|
|
4757
|
+
this.els.pricesSec?.setAttribute("aria-expanded", String(!open));
|
|
4758
|
+
this.pricesBtnEl?.setAttribute("aria-pressed", String(!open));
|
|
4759
|
+
if (!open && this.root.dataset.sheet !== "open") {
|
|
4760
|
+
this.root.dataset.sheet = "open";
|
|
4761
|
+
const sheetToggle = this.els.sheetToggle;
|
|
4762
|
+
sheetToggle?.setAttribute("aria-expanded", "true");
|
|
4763
|
+
sheetToggle?.setAttribute("aria-label", "Collapse ticket panel");
|
|
4764
|
+
}
|
|
4765
|
+
};
|
|
4766
|
+
this.els.pricesSec?.addEventListener("click", (e) => {
|
|
4767
|
+
if (e.target.closest("select,button")) return;
|
|
4768
|
+
togglePrices();
|
|
4769
|
+
});
|
|
4770
|
+
this.els.pricesSec?.addEventListener("keydown", (e) => {
|
|
4771
|
+
if (e.key !== "Enter" && e.key !== " ") return;
|
|
4772
|
+
if (e.target.closest("select,button")) return;
|
|
4773
|
+
e.preventDefault();
|
|
4774
|
+
togglePrices();
|
|
4775
|
+
});
|
|
4776
|
+
const pricesBtn = document.createElement("button");
|
|
4777
|
+
pricesBtn.type = "button";
|
|
4778
|
+
pricesBtn.className = "sl-prices-btn";
|
|
4779
|
+
pricesBtn.setAttribute("aria-label", this.tf("picker.ticketPrices", "Ticket prices"));
|
|
4780
|
+
pricesBtn.setAttribute("title", this.tf("picker.ticketPrices", "Ticket prices"));
|
|
4781
|
+
pricesBtn.setAttribute("aria-pressed", "false");
|
|
4782
|
+
pricesBtn.innerHTML = '<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20.6 13.4 13.4 20.6a2 2 0 0 1-2.8 0L3 13V5a2 2 0 0 1 2-2h8l7.6 7.6a2 2 0 0 1 0 2.8z"/><circle cx="7.5" cy="7.5" r="1.3"/></svg>';
|
|
4783
|
+
pricesBtn.addEventListener("click", () => togglePrices());
|
|
4784
|
+
this.els.headInfo?.parentElement?.insertBefore(pricesBtn, this.els.hold ?? null);
|
|
4785
|
+
this.pricesBtnEl = pricesBtn;
|
|
4664
4786
|
this.tipEl = document.createElement("div");
|
|
4665
4787
|
this.tipEl.setAttribute("role", "tooltip");
|
|
4666
4788
|
this.tipEl.className = "sl-tip";
|
|
@@ -4678,7 +4800,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4678
4800
|
const info = await this.controller.render(canvasHost);
|
|
4679
4801
|
if (this.destroyed) return this;
|
|
4680
4802
|
if (!info) {
|
|
4681
|
-
this.els.boot.innerHTML =
|
|
4803
|
+
this.els.boot.innerHTML = `<div class="sl-boot-title">${this.tf("picker.mapDidNotLoad", "The seat map didn\u2019t load")}</div><div>${this.tf("picker.checkConnection", "Check your connection and try again.")}</div><button type="button" class="sl-boot-retry">${this.tf("picker.accessRetry", "Try again")}</button>`;
|
|
4682
4804
|
this.els.boot.querySelector("button").addEventListener("click", () => {
|
|
4683
4805
|
const container = this.opts.container;
|
|
4684
4806
|
const opts = this.opts;
|
|
@@ -4713,6 +4835,12 @@ var SeatPicker = class _SeatPicker {
|
|
|
4713
4835
|
const when = info.startsAt ? formatWhen(info.startsAt, info.timezone ?? null, this.opts.locale) : "";
|
|
4714
4836
|
this.eventWhenText = when || null;
|
|
4715
4837
|
this.els.meta.textContent = [info.venue, when].filter(Boolean).join(" \xB7 ");
|
|
4838
|
+
if (this.els.pricesHint) {
|
|
4839
|
+
this.els.pricesHint.textContent = this.tf(
|
|
4840
|
+
"picker.priceHint",
|
|
4841
|
+
"Colours on the map are ticket types \u2014 tap one below to show just those seats."
|
|
4842
|
+
);
|
|
4843
|
+
}
|
|
4716
4844
|
this.buildBadge(chartTheme);
|
|
4717
4845
|
const present = /* @__PURE__ */ new Set();
|
|
4718
4846
|
let hasLimitedView = false;
|
|
@@ -4739,7 +4867,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4739
4867
|
const mk = (key, label) => `<button type="button" class="sl-chip-f${key === "all" ? " on" : ""}" data-a11y="1" data-f="${key}">${label}</button>`;
|
|
4740
4868
|
chips.insertAdjacentHTML(
|
|
4741
4869
|
"beforeend",
|
|
4742
|
-
mk("all", "All seats") + import_core2.ACCESSIBILITY_TYPES.filter(({ key }) => present.has(key)).map(({ key, short, icon }) => mk(key, `${icon} ${short}`)).join("")
|
|
4870
|
+
mk("all", this.tf("picker.allSeats", "All seats")) + import_core2.ACCESSIBILITY_TYPES.filter(({ key }) => present.has(key)).map(({ key, short, icon }) => mk(key, `${icon} ${short}`)).join("")
|
|
4743
4871
|
);
|
|
4744
4872
|
const active = /* @__PURE__ */ new Set();
|
|
4745
4873
|
const syncChips = () => {
|
|
@@ -4785,7 +4913,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4785
4913
|
cb.type = "button";
|
|
4786
4914
|
cb.className = "sl-cbbtn";
|
|
4787
4915
|
this.cbEl = cb;
|
|
4788
|
-
cb.setAttribute("aria-label", "Toggle colorblind-friendly colors");
|
|
4916
|
+
cb.setAttribute("aria-label", this.tf("picker.toggleColorblindColors", "Toggle colorblind-friendly colors"));
|
|
4789
4917
|
cb.setAttribute("aria-pressed", String(this.cbSafe));
|
|
4790
4918
|
cb.innerHTML = '<svg viewBox="0 0 24 24"><path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg>';
|
|
4791
4919
|
this.els.zfit.parentElement.appendChild(cb);
|
|
@@ -4871,8 +4999,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
4871
4999
|
if (!btn) return;
|
|
4872
5000
|
const collapsed = this.sideCollapsed;
|
|
4873
5001
|
btn.setAttribute("aria-expanded", String(!collapsed));
|
|
4874
|
-
btn.setAttribute("aria-label", collapsed ? "Show the ticket panel" : "Hide the ticket panel");
|
|
4875
|
-
btn.innerHTML = collapsed ?
|
|
5002
|
+
btn.setAttribute("aria-label", collapsed ? this.tf("picker.showTicketPanel", "Show the ticket panel") : this.tf("picker.hideTicketPanel", "Hide the ticket panel"));
|
|
5003
|
+
btn.innerHTML = collapsed ? `<svg viewBox="0 0 24 24"><path d="M15 6l-6 6 6 6"/></svg><span>${this.tf("picker.tickets", "Tickets")}</span>` : `<svg viewBox="0 0 24 24"><path d="M9 6l6 6-6 6"/></svg><span>${this.tf("picker.hidePanel", "Hide panel")}</span>`;
|
|
4876
5004
|
}
|
|
4877
5005
|
/**
|
|
4878
5006
|
* Collapse or reopen the wide-layout ticket panel in place (host-drivable —
|
|
@@ -4898,13 +5026,24 @@ var SeatPicker = class _SeatPicker {
|
|
|
4898
5026
|
const narrow = this.root?.dataset.layout === "narrow";
|
|
4899
5027
|
this.applyPanelCollapsed();
|
|
4900
5028
|
const zfs = this.els.zfs;
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
5029
|
+
const head = this.els.headInfo?.parentElement;
|
|
5030
|
+
if (zfs && head && zfs.parentElement !== head) {
|
|
5031
|
+
zfs.classList.add("sl-fs-pill");
|
|
5032
|
+
head.insertBefore(zfs, this.els.hold ?? null);
|
|
5033
|
+
}
|
|
5034
|
+
const pricesSec = this.els.pricesSec;
|
|
5035
|
+
if (pricesSec) {
|
|
5036
|
+
if (narrow) {
|
|
5037
|
+
pricesSec.setAttribute("role", "button");
|
|
5038
|
+
pricesSec.tabIndex = 0;
|
|
5039
|
+
pricesSec.setAttribute(
|
|
5040
|
+
"aria-expanded",
|
|
5041
|
+
String(this.root?.getAttribute("data-prices-open") === "true")
|
|
5042
|
+
);
|
|
5043
|
+
} else {
|
|
5044
|
+
pricesSec.removeAttribute("role");
|
|
5045
|
+
pricesSec.removeAttribute("aria-expanded");
|
|
5046
|
+
pricesSec.tabIndex = -1;
|
|
4908
5047
|
}
|
|
4909
5048
|
}
|
|
4910
5049
|
const filters = this.els.filters;
|
|
@@ -4931,7 +5070,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4931
5070
|
this.extendEl = el2;
|
|
4932
5071
|
this.els.extendTxt = el2.querySelector('[data-ref="extendTxt"]');
|
|
4933
5072
|
this.els.extendBtn = el2.querySelector('[data-ref="extendBtn"]');
|
|
4934
|
-
this.els.extendBtn.textContent = "Add time";
|
|
5073
|
+
this.els.extendBtn.textContent = this.tf("picker.addTime", "Add time");
|
|
4935
5074
|
this.els.extendBtn.addEventListener("click", () => void this.handleExtend());
|
|
4936
5075
|
}
|
|
4937
5076
|
/** Success overlay + onBooked fire when the held seats settle to booked. */
|
|
@@ -4940,7 +5079,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4940
5079
|
el2.className = "sl-booked";
|
|
4941
5080
|
el2.setAttribute("role", "status");
|
|
4942
5081
|
el2.setAttribute("aria-live", "polite");
|
|
4943
|
-
el2.innerHTML = `<div class="sl-booked-badge"><svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg></div><div class="sl-booked-title"
|
|
5082
|
+
el2.innerHTML = `<div class="sl-booked-badge"><svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg></div><div class="sl-booked-title">${this.tf("picker.allSetTitle", "You're all set")}</div><div class="sl-booked-sub" data-ref="bookedSub"></div>`;
|
|
4944
5083
|
this.root.appendChild(el2);
|
|
4945
5084
|
this.bookedEl = el2;
|
|
4946
5085
|
this.els.bookedSub = el2.querySelector('[data-ref="bookedSub"]');
|
|
@@ -4951,8 +5090,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
4951
5090
|
* host `messages` override (which makes `t()` return the override, not the key).
|
|
4952
5091
|
*/
|
|
4953
5092
|
tf(key, fallback) {
|
|
4954
|
-
|
|
4955
|
-
return v === key ? fallback : v;
|
|
5093
|
+
return tfStatic(key, fallback);
|
|
4956
5094
|
}
|
|
4957
5095
|
/** Sold-out overlay — an informational state with no unavailable action. */
|
|
4958
5096
|
buildSoldoutOverlay() {
|
|
@@ -5137,7 +5275,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
5137
5275
|
}
|
|
5138
5276
|
canAddTicket() {
|
|
5139
5277
|
if (this.totalTicketCount() < this.maxTickets) return true;
|
|
5140
|
-
this.toast(
|
|
5278
|
+
this.toast((0, import_core2.t)("picker.maxTicketsForOrder", { count: this.maxTickets }), "warning");
|
|
5141
5279
|
return false;
|
|
5142
5280
|
}
|
|
5143
5281
|
pendingGATotal(gaAreas) {
|
|
@@ -5160,21 +5298,21 @@ var SeatPicker = class _SeatPicker {
|
|
|
5160
5298
|
}
|
|
5161
5299
|
if (this.confirmSeat || this.tableDialog && !this.tableDialogHeld) {
|
|
5162
5300
|
cta.disabled = true;
|
|
5163
|
-
cta.textContent = this.tableDialog ? "Confirm your table" : "Confirm or cancel this seat";
|
|
5301
|
+
cta.textContent = this.tableDialog ? this.tf("picker.confirmYourTable", "Confirm your table") : this.tf("picker.confirmOrCancelSeat", "Confirm or cancel this seat");
|
|
5164
5302
|
return;
|
|
5165
5303
|
}
|
|
5166
5304
|
if (this.ctaPhase === "holding") {
|
|
5167
5305
|
cta.disabled = true;
|
|
5168
|
-
cta.innerHTML =
|
|
5306
|
+
cta.innerHTML = `<span class="sl-cta-spin" aria-hidden="true"></span>${this.tf("picker.securingSeats", "Securing your seats\u2026")}`;
|
|
5169
5307
|
return;
|
|
5170
5308
|
}
|
|
5171
5309
|
if (this.ctaPhase === "checkout") {
|
|
5172
5310
|
cta.disabled = true;
|
|
5173
|
-
cta.innerHTML =
|
|
5311
|
+
cta.innerHTML = `<span class="sl-cta-spin" aria-hidden="true"></span>${this.tf("picker.openingCheckout", "Opening secure checkout\u2026")}`;
|
|
5174
5312
|
return;
|
|
5175
5313
|
}
|
|
5176
5314
|
cta.disabled = count === 0;
|
|
5177
|
-
cta.textContent = this.hold ? pending ?
|
|
5315
|
+
cta.textContent = this.hold ? pending ? (0, import_core2.t)("picker.secureMoreAndCheckout", { count: pending }) : this.tf("picker.continueToCheckout", "Continue to checkout") : count ? this.tf("picker.holdSeatsAndCheckout", "Hold seats & checkout") : this.tf("picker.selectSeats", "Select seats");
|
|
5178
5316
|
}
|
|
5179
5317
|
setCtaPhase(phase) {
|
|
5180
5318
|
this.ctaPhase = phase;
|
|
@@ -5235,7 +5373,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
5235
5373
|
this.syncTray();
|
|
5236
5374
|
this.emitHoldChange();
|
|
5237
5375
|
this.opts.onHoldRestored?.(restored, restored.seats ?? [], this.buildHandoff(restored));
|
|
5238
|
-
if (automatic) this.toast("Your held tickets have been restored.", "success");
|
|
5376
|
+
if (automatic) this.toast(this.tf("picker.heldTicketsRestored", "Your held tickets have been restored."), "success");
|
|
5239
5377
|
return restored;
|
|
5240
5378
|
} catch (error) {
|
|
5241
5379
|
const status = error?.status;
|
|
@@ -5453,8 +5591,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
5453
5591
|
if (bands.length < 2) return;
|
|
5454
5592
|
const select = document.createElement("select");
|
|
5455
5593
|
select.className = "sl-price-select";
|
|
5456
|
-
select.setAttribute("aria-label", "Filter and focus seats by price");
|
|
5457
|
-
select.innerHTML = `<option value="all"
|
|
5594
|
+
select.setAttribute("aria-label", this.tf("picker.filterAndFocusByPrice", "Filter and focus seats by price"));
|
|
5595
|
+
select.innerHTML = `<option value="all">${this.tf("picker.allPrices", "All prices")}</option>` + bands.map((band) => `<option value="${band.id}">${band.label}</option>`).join("");
|
|
5458
5596
|
this.els.pricesSec.appendChild(select);
|
|
5459
5597
|
select.addEventListener("change", () => {
|
|
5460
5598
|
const band = bands.find((candidate) => candidate.id === select.value);
|
|
@@ -5481,8 +5619,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
5481
5619
|
const projection = document.createElement("div");
|
|
5482
5620
|
projection.className = "sl-projection";
|
|
5483
5621
|
projection.setAttribute("role", "group");
|
|
5484
|
-
projection.setAttribute("aria-label", "Venue view");
|
|
5485
|
-
projection.innerHTML =
|
|
5622
|
+
projection.setAttribute("aria-label", this.tf("picker.venueView", "Venue view"));
|
|
5623
|
+
projection.innerHTML = `<button type="button" data-view="map" aria-pressed="true" title="${this.tf("picker.flat2dMap", "Flat 2D map")}">${this.tf("picker.map", "Map")}</button><button type="button" data-view="venue3d" aria-pressed="false" title="${this.tf("picker.interactive3dVenueView", "Interactive 3D venue view")}">3D</button>`;
|
|
5486
5624
|
projection.querySelectorAll("button").forEach((button) => {
|
|
5487
5625
|
button.addEventListener("click", () => {
|
|
5488
5626
|
this.setBuyerView(button.dataset.view);
|
|
@@ -5605,6 +5743,10 @@ var SeatPicker = class _SeatPicker {
|
|
|
5605
5743
|
renderSectionCard(summary) {
|
|
5606
5744
|
if (!this.els.map) return;
|
|
5607
5745
|
this.secCardEl?.remove();
|
|
5746
|
+
if (this.root?.dataset.layout === "narrow" && (this.hold || this.committedSelection().length || this.pendingGACount())) {
|
|
5747
|
+
this.lastSection = null;
|
|
5748
|
+
return;
|
|
5749
|
+
}
|
|
5608
5750
|
const paid = summary.categories.length ? summary.categories.map((c) => this.paidPrice(c.key, null, c.price)) : [summary.priceMin, summary.priceMax];
|
|
5609
5751
|
const paidMin = Math.min(...paid);
|
|
5610
5752
|
const paidMax = Math.max(...paid);
|
|
@@ -5705,13 +5847,13 @@ var SeatPicker = class _SeatPicker {
|
|
|
5705
5847
|
}
|
|
5706
5848
|
const cat = this.controller.doc?.categories.find((c) => c.key === seat.categoryKey);
|
|
5707
5849
|
const status = this.controller.getStatus(seat.id) ?? "free";
|
|
5708
|
-
const statusText = status === "free" ? "available" : status === "held" ? "on hold" : "taken";
|
|
5850
|
+
const statusText = status === "free" ? this.tf("picker.statusAvailable", "available") : status === "held" ? this.tf("picker.statusOnHold", "on hold") : this.tf("picker.statusTaken2", "taken");
|
|
5709
5851
|
const price = cat ? this.catPrice(cat) : void 0;
|
|
5710
5852
|
const table = this.controller.tableSelection(seat.id);
|
|
5711
5853
|
const details = table ?? this.controller.seatDetails(seat.id);
|
|
5712
5854
|
const typeWord = this.rowTypeWord(details);
|
|
5713
5855
|
const buyerName = details?.rowLabel ?? details?.displayLabel ?? seat.displayLabel ?? seat.label;
|
|
5714
|
-
const identity = table ? `${typeWord} ${buyerName}, ${table.bookingMode === "variable" ?
|
|
5856
|
+
const identity = table ? `${typeWord} ${buyerName}, ${table.bookingMode === "variable" ? (0, import_core2.t)("picker.minToMaxGuests", { min: table.minOccupancy, max: table.maxOccupancy }) : (0, import_core2.t)("picker.capacityGuests", { count: table.capacity })}` : details?.objectType === "booth" ? `${typeWord} ${buyerName}` : details?.objectType === "table" ? `${typeWord} ${buyerName}, ${(0, import_core2.t)("picker.seatNumberLower", { label: details.seatNumber ?? seat.label })}` : (0, import_core2.t)("picker.seatLabel", { label: details?.displayLabel ?? seat.displayLabel ?? seat.label });
|
|
5715
5857
|
this.srEl.textContent = `${identity}, ${cat?.label ?? seat.categoryKey}${price != null ? `, ${this.money(price)}` : ""}, ${statusText}`;
|
|
5716
5858
|
}
|
|
5717
5859
|
// ---- atomic table confirmation / guest quantity ---------------------------
|
|
@@ -5732,7 +5874,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
5732
5874
|
const typeWord = this.rowTypeWord(table);
|
|
5733
5875
|
const el2 = document.createElement("div");
|
|
5734
5876
|
el2.className = "sl-table-scrim";
|
|
5735
|
-
el2.innerHTML = `<section class="sl-table-dialog" role="dialog" aria-modal="true" aria-labelledby="sl-table-title" aria-describedby="sl-table-copy"><div class="sl-table-head"><div class="sl-table-eyebrow">${esc(variable ?
|
|
5877
|
+
el2.innerHTML = `<section class="sl-table-dialog" role="dialog" aria-modal="true" aria-labelledby="sl-table-title" aria-describedby="sl-table-copy"><div class="sl-table-head"><div class="sl-table-eyebrow">${esc(variable ? (0, import_core2.t)("picker.flexiblePartyTypeWord", { typeWord }) : (0, import_core2.t)("picker.wholeTypeWord", { typeWord }))}</div><h2 class="sl-table-title" id="sl-table-title">${esc(table.displayLabel ?? table.label)}</h2><p class="sl-table-copy" id="sl-table-copy">${variable ? this.tf("picker.chooseGuestsCopy", "Choose how many guests will sit together. This table is held exclusively for your party.") : (0, import_core2.t)("picker.allPlacesBookedTogether", { count: table.capacity })}</p></div><div class="sl-table-body"><div class="sl-table-summary"><span>${esc(cat?.label ?? table.categoryKey)}</span><b data-table-unit>${(0, import_core2.t)("picker.perGuestPrice", { price: this.money(this.paidPrice(table.categoryKey, table.tierId ?? null, table.price)) })}</b><span class="muted">${this.tf("picker.tableCapacity", "Table capacity")}</span><span>${(0, import_core2.t)("picker.guestsCount", { count: table.capacity })}</span><span class="muted">${this.tf("picker.total", "Total")}</span><b data-table-total></b></div>` + (variable ? `<label class="sl-table-qtylabel" id="sl-table-qty-label">${this.tf("picker.numberOfGuests", "Number of guests")}</label><div class="sl-table-stepper" role="group" aria-labelledby="sl-table-qty-label"><button type="button" data-table-step="-1" aria-label="${this.tf("picker.fewerGuests", "Fewer guests")}">\u2212</button><output aria-live="polite" data-table-qty>${table.quantity}</output><button type="button" data-table-step="1" aria-label="${this.tf("picker.moreGuests", "More guests")}">+</button></div><div class="sl-table-range">${(0, import_core2.t)("picker.chooseMinMaxGuests", { min: table.minOccupancy, max: table.maxOccupancy })}</div>` : `<input type="hidden" data-table-qty value="${table.capacity}">`) + `<div class="sl-table-actions"><button type="button" class="sl-table-cancel">${(0, import_core2.t)("common.cancel")}</button><button type="button" class="sl-table-confirm">${held ? this.tf("picker.updateTable", "Update table") : variable ? this.tf("picker.selectTable", "Select table") : this.tf("picker.selectWholeTable", "Select whole table")}</button></div></div></section>`;
|
|
5736
5878
|
this.root.appendChild(el2);
|
|
5737
5879
|
this.tableDialogEl = el2;
|
|
5738
5880
|
this.renderTableDialogState();
|
|
@@ -5791,17 +5933,17 @@ var SeatPicker = class _SeatPicker {
|
|
|
5791
5933
|
const button = this.tableDialogEl?.querySelector(".sl-table-confirm");
|
|
5792
5934
|
if (button) {
|
|
5793
5935
|
button.disabled = true;
|
|
5794
|
-
button.textContent = held ? "Updating\u2026" : "Selecting\u2026";
|
|
5936
|
+
button.textContent = held ? this.tf("picker.updatingEllipsis", "Updating\u2026") : this.tf("picker.selectingEllipsis", "Selecting\u2026");
|
|
5795
5937
|
}
|
|
5796
5938
|
if (held) {
|
|
5797
5939
|
try {
|
|
5798
5940
|
const updated = await this.controller.replaceTableQuantity(table.label, table.quantity, this.opts.holdTtlMs);
|
|
5799
5941
|
if (!updated) {
|
|
5800
|
-
this.toast("That guest count could not be secured. Your current table hold is unchanged.", "warning");
|
|
5942
|
+
this.toast(this.tf("picker.guestCountCouldNotBeSecured", "That guest count could not be secured. Your current table hold is unchanged."), "warning");
|
|
5801
5943
|
this.renderTableDialogState();
|
|
5802
5944
|
if (button) {
|
|
5803
5945
|
button.disabled = false;
|
|
5804
|
-
button.textContent = "Update table";
|
|
5946
|
+
button.textContent = this.tf("picker.updateTable", "Update table");
|
|
5805
5947
|
}
|
|
5806
5948
|
return;
|
|
5807
5949
|
}
|
|
@@ -5815,13 +5957,13 @@ var SeatPicker = class _SeatPicker {
|
|
|
5815
5957
|
this.dismissTableDialog();
|
|
5816
5958
|
this.syncTray();
|
|
5817
5959
|
this.emitHoldChange();
|
|
5818
|
-
this.toast(
|
|
5960
|
+
this.toast((0, import_core2.t)("picker.tableUpdatedForGuests", { label: table.label, count: table.quantity }), "success");
|
|
5819
5961
|
} catch (error) {
|
|
5820
5962
|
this.opts.onError?.(error);
|
|
5821
|
-
this.toast("That guest count is no longer available. Your current hold is unchanged.", "error");
|
|
5963
|
+
this.toast(this.tf("picker.guestCountNoLongerAvailable", "That guest count is no longer available. Your current hold is unchanged."), "error");
|
|
5822
5964
|
if (button) {
|
|
5823
5965
|
button.disabled = false;
|
|
5824
|
-
button.textContent = "Update table";
|
|
5966
|
+
button.textContent = this.tf("picker.updateTable", "Update table");
|
|
5825
5967
|
}
|
|
5826
5968
|
}
|
|
5827
5969
|
return;
|
|
@@ -5829,7 +5971,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
5829
5971
|
if (!this.controller.setTableQuantity(table.label, table.quantity)) {
|
|
5830
5972
|
if (button) {
|
|
5831
5973
|
button.disabled = false;
|
|
5832
|
-
button.textContent = table.bookingMode === "variable" ? "Select table" : "Select whole table";
|
|
5974
|
+
button.textContent = table.bookingMode === "variable" ? this.tf("picker.selectTable", "Select table") : this.tf("picker.selectWholeTable", "Select whole table");
|
|
5833
5975
|
}
|
|
5834
5976
|
return;
|
|
5835
5977
|
}
|
|
@@ -5875,16 +6017,16 @@ var SeatPicker = class _SeatPicker {
|
|
|
5875
6017
|
'"': """
|
|
5876
6018
|
})[char]);
|
|
5877
6019
|
const identityFields = [
|
|
5878
|
-
details?.sectionLabel ? `<div class="sl-confirm-field"><span class="sl-confirm-key"
|
|
6020
|
+
details?.sectionLabel ? `<div class="sl-confirm-field"><span class="sl-confirm-key">${this.tf("picker.section", "Section")}</span><span class="sl-confirm-value">${safe(details.sectionLabel)}</span></div>` : "",
|
|
5879
6021
|
details?.rowLabel || details?.objectType === "booth" ? `<div class="sl-confirm-field"><span class="sl-confirm-key">${safe(this.rowTypeWord(details))}</span><span class="sl-confirm-value">${safe(this.rowShort(details) ?? details?.displayLabel ?? seat.displayLabel ?? seat.label)}</span></div>` : "",
|
|
5880
|
-
details?.objectType !== "booth" ? `<div class="sl-confirm-field"><span class="sl-confirm-key"
|
|
6022
|
+
details?.objectType !== "booth" ? `<div class="sl-confirm-field"><span class="sl-confirm-key">${this.tf("picker.seat", "Seat")}</span><span class="sl-confirm-value">${safe(details?.seatNumber ?? details?.displayLabel ?? seat.displayLabel ?? seat.label)}</span></div>` : ""
|
|
5881
6023
|
].filter(Boolean).join("");
|
|
5882
6024
|
const el2 = document.createElement("div");
|
|
5883
6025
|
el2.className = "sl-confirm";
|
|
5884
6026
|
el2.setAttribute("role", "dialog");
|
|
5885
|
-
el2.setAttribute("aria-label",
|
|
6027
|
+
el2.setAttribute("aria-label", (0, import_core2.t)("picker.confirmSeatLabel", { label: seat.label }));
|
|
5886
6028
|
el2.style.setProperty("--sl-cat", cat?.color ?? "#6e7bff");
|
|
5887
|
-
el2.innerHTML = `<div class="sl-confirm-grid">` + identityFields + `</div><div class="sl-confirm-cat"><span class="sl-dot" style="background:${cat?.color ?? "#6e7bff"}"></span><span class="sl-confirm-cat-name">${safe(details?.categoryLabel ?? cat?.label ?? seat.categoryKey)}</span>` + (price != null ? `<span class="sl-confirm-price">${this.money(price)}</span>` : "") + `</div><div class="sl-confirm-body">` + this.wheelchairConfirmHtml(details?.wheelchairSpaceType) + this.commercialConfirmHtml(seat.commercial) + (this.seatViewEnabled() && this.buyerView !== "venue3d" ? this.confirmThumbHtml(seat) : "") + (this.buyerView === "venue3d" ? `${this.seatConfidenceConfirmHtml(seat, `${details?.displayLabel ?? seat.displayLabel ?? seat.label} \xB7 ${price == null ? this.tf("picker.priceNotSupplied", "Price not supplied") : this.money(price)}`)}<div class="sl-confirm-inspect-row">${this.view3dCompareConfirmHtml(seat)}${this.see3dConfirmHtml()}</div>` : this.see3dConfirmHtml()) + `<div class="sl-confirm-row"><button type="button" class="sl-confirm-cancel"
|
|
6029
|
+
el2.innerHTML = `<div class="sl-confirm-grid">` + identityFields + `</div><div class="sl-confirm-cat"><span class="sl-dot" style="background:${cat?.color ?? "#6e7bff"}"></span><span class="sl-confirm-cat-name">${safe(details?.categoryLabel ?? cat?.label ?? seat.categoryKey)}</span>` + (price != null ? `<span class="sl-confirm-price">${this.money(price)}</span>` : "") + `</div><div class="sl-confirm-body">` + this.wheelchairConfirmHtml(details?.wheelchairSpaceType) + this.commercialConfirmHtml(seat.commercial) + (this.seatViewEnabled() && this.buyerView !== "venue3d" ? this.confirmThumbHtml(seat) : "") + (this.buyerView === "venue3d" ? `${this.seatConfidenceConfirmHtml(seat, `${details?.displayLabel ?? seat.displayLabel ?? seat.label} \xB7 ${price == null ? this.tf("picker.priceNotSupplied", "Price not supplied") : this.money(price)}`)}<div class="sl-confirm-inspect-row">${this.view3dCompareConfirmHtml(seat)}${this.see3dConfirmHtml()}</div>` : this.see3dConfirmHtml()) + `<div class="sl-confirm-row"><button type="button" class="sl-confirm-cancel">${(0, import_core2.t)("common.cancel")}</button><button type="button" class="sl-confirm-add"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M5 12.5l4 4L19 7"/></svg>${this.tf("picker.select", "Select")}</button></div></div>`;
|
|
5888
6030
|
this.els.map.appendChild(el2);
|
|
5889
6031
|
this.confirmEl = el2;
|
|
5890
6032
|
const thumb = el2.querySelector(".sl-confirm-thumb");
|
|
@@ -6037,7 +6179,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6037
6179
|
el2.className = "sl-view";
|
|
6038
6180
|
el2.setAttribute("role", "dialog");
|
|
6039
6181
|
el2.setAttribute("aria-label", (0, import_core2.t)("picker.viewFromSeat", { label: seat.label }));
|
|
6040
|
-
el2.innerHTML = `<div class="sl-view-head"><span class="sl-view-title">${(0, import_core2.t)("picker.viewFromSeat", { label: seat.label })}</span><span class="sl-view-cap">${caption}</span><button type="button" class="sl-view-x" aria-label="Close"><svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button></div><div class="sl-view-pano"><span class="sl-view-badge">${real ? (0, import_core2.t)("picker.real360") : (0, import_core2.t)("picker.preview")}</span><span class="sl-view-hint"
|
|
6182
|
+
el2.innerHTML = `<div class="sl-view-head"><span class="sl-view-title">${(0, import_core2.t)("picker.viewFromSeat", { label: seat.label })}</span><span class="sl-view-cap">${caption}</span><button type="button" class="sl-view-x" aria-label="${this.tf("picker.close", "Close")}"><svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button></div><div class="sl-view-pano"><span class="sl-view-badge">${real ? (0, import_core2.t)("picker.real360") : (0, import_core2.t)("picker.preview")}</span><span class="sl-view-hint">${this.tf("picker.dragToLookAround", "Drag to look around \xB7 scroll to zoom")}</span></div>`;
|
|
6041
6183
|
this.root.appendChild(el2);
|
|
6042
6184
|
this.viewEl = el2;
|
|
6043
6185
|
const pano = el2.querySelector(".sl-view-pano");
|
|
@@ -6233,27 +6375,27 @@ var SeatPicker = class _SeatPicker {
|
|
|
6233
6375
|
copy.className = "sl-offer-copy";
|
|
6234
6376
|
const kicker = document.createElement("span");
|
|
6235
6377
|
kicker.className = "sl-offer-kicker";
|
|
6236
|
-
kicker.textContent = active ? "Current ticket offer" : "Upcoming ticket offer";
|
|
6378
|
+
kicker.textContent = active ? this.tf("picker.currentTicketOffer", "Current ticket offer") : this.tf("picker.upcomingTicketOffer", "Upcoming ticket offer");
|
|
6237
6379
|
const name = document.createElement("strong");
|
|
6238
6380
|
name.className = "sl-offer-name";
|
|
6239
|
-
name.textContent = offer.name || (active ? "Current offer" : "Scheduled offer");
|
|
6381
|
+
name.textContent = offer.name || (active ? this.tf("picker.currentOffer", "Current offer") : this.tf("picker.scheduledOffer", "Scheduled offer"));
|
|
6240
6382
|
const line = document.createElement("span");
|
|
6241
6383
|
line.className = "sl-offer-line";
|
|
6242
6384
|
const facts = [];
|
|
6243
6385
|
if (active && availability.fromPrice != null) facts.push(this.money(availability.fromPrice / 100));
|
|
6244
|
-
if (active && offer.remaining != null) facts.push(
|
|
6245
|
-
if (active && offer.endsAt != null) facts.push(
|
|
6246
|
-
if (upcoming?.startsAt != null) facts.push(
|
|
6386
|
+
if (active && offer.remaining != null) facts.push((0, import_core2.t)("picker.offerRemainingAvailable", { count: offer.remaining }));
|
|
6387
|
+
if (active && offer.endsAt != null) facts.push((0, import_core2.t)("picker.offerUntil", { time: formatWhen(offer.endsAt, this.eventTimezone, this.opts.locale) }));
|
|
6388
|
+
if (upcoming?.startsAt != null) facts.push((0, import_core2.t)("picker.offerStarts", { time: formatWhen(upcoming.startsAt, this.eventTimezone, this.opts.locale) }));
|
|
6247
6389
|
line.textContent = facts.join(" \xB7 ");
|
|
6248
6390
|
copy.append(kicker, name, line);
|
|
6249
6391
|
const info = document.createElement("details");
|
|
6250
6392
|
info.className = "sl-offer-info";
|
|
6251
6393
|
const summary = document.createElement("summary");
|
|
6252
|
-
summary.setAttribute("aria-label",
|
|
6394
|
+
summary.setAttribute("aria-label", (0, import_core2.t)("picker.howOfferWorks", { name: name.textContent ?? "" }));
|
|
6253
6395
|
summary.textContent = "i";
|
|
6254
6396
|
const detail = document.createElement("div");
|
|
6255
6397
|
detail.className = "sl-offer-detail";
|
|
6256
|
-
detail.textContent = active ?
|
|
6398
|
+
detail.textContent = active ? this.tf("picker.offerDetailActive", "This price applies automatically to eligible seats. Tickets in active carts temporarily reduce the available quantity; released or expired holds return it. When the offer ends, the next matching offer or normal ticket price takes over.") : this.tf("picker.offerDetailUpcoming", "Tickets are available at their normal price now. This scheduled offer will apply automatically to eligible seats when it starts.");
|
|
6257
6399
|
info.append(summary, detail);
|
|
6258
6400
|
main.append(copy, info);
|
|
6259
6401
|
host.replaceChildren(main);
|
|
@@ -6289,8 +6431,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
6289
6431
|
const previous = offer?.previousPrice != null && offer.previousPrice > offer.price ? offer.previousPrice : null;
|
|
6290
6432
|
const active = this.focusedCatKey === c.key;
|
|
6291
6433
|
const dim = this.priceBandKeys != null && !this.priceBandKeys.has(c.key);
|
|
6292
|
-
return `<div class="sl-price-row${dim ? " sl-dim" : ""}${active ? " sl-active" : ""}" data-cat="${escapeOption(c.key)}" role="button" tabindex="0" aria-pressed="${active}" title="${escapeOption(active ? "Show all seats" :
|
|
6293
|
-
}).join("") + (overflow > 1 ? `<button type="button" class="sl-price-more" aria-expanded="${!collapsed}">` + (collapsed ?
|
|
6434
|
+
return `<div class="sl-price-row${dim ? " sl-dim" : ""}${active ? " sl-active" : ""}" data-cat="${escapeOption(c.key)}" role="button" tabindex="0" aria-pressed="${active}" title="${escapeOption(active ? this.tf("picker.showAllSeats", "Show all seats") : (0, import_core2.t)("picker.showLabelSeatsOnMap", { label: c.label }))}"><span class="sl-dot" style="background:${escapeOption(c.color)}"></span><span class="sl-price-label">${escapeOption(c.label)}` + (offer?.offerName ? `<small class="sl-price-offer">${escapeOption(offer.offerName)}</small>` : "") + `</span><span class="sl-price-left">${(0, import_core2.tCount)("picker.leftCount", left[c.key] ?? 0)}</span>` + (previous != null ? `<span class="sl-price-was">${escapeOption(this.money(previous))}</span>` : "") + (price != null ? `<span class="sl-price-amt">${this.money(price)}</span>` : "") + `</div>`;
|
|
6435
|
+
}).join("") + (overflow > 1 ? `<button type="button" class="sl-price-more" aria-expanded="${!collapsed}">` + (collapsed ? (0, import_core2.t)("picker.showAllTicketTypes", { count: doc.categories.length }) : this.tf("picker.showFewer", "Show fewer")) + `</button>` : "") + `<div class="sl-status-key" aria-label="${this.tf("picker.seatStatusLegend", "Seat status legend")}"><span class="sl-status-item"><i class="sl-status-icon" aria-hidden="true"><svg viewBox="0 0 24 24"><rect x="5" y="10" width="14" height="10" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg></i>${this.tf("picker.temporarilyHeld", "Temporarily held")}</span><span class="sl-status-item"><i class="sl-status-icon sold" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M7 17L17 7"/></svg></i>${this.tf("picker.sold", "Sold")}</span></div>`;
|
|
6294
6436
|
this.els.prices.querySelectorAll(".sl-price-row").forEach((row) => {
|
|
6295
6437
|
row.addEventListener("mouseenter", () => this.controller.getRenderer()?.setCategoryHighlight?.(row.dataset.cat ?? null));
|
|
6296
6438
|
row.addEventListener("mouseleave", () => this.controller.getRenderer()?.setCategoryHighlight?.(null));
|
|
@@ -6348,7 +6490,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6348
6490
|
const now = left[cat.key] ?? 0;
|
|
6349
6491
|
if (before === void 0 || now >= before) continue;
|
|
6350
6492
|
const taken = before - now;
|
|
6351
|
-
textEl.textContent =
|
|
6493
|
+
textEl.textContent = (0, import_core2.tCount)("picker.seatsJustTakenInCategory", taken, { label: cat.label, left: now });
|
|
6352
6494
|
this.els.live?.classList.remove("on");
|
|
6353
6495
|
void this.els.live?.offsetWidth;
|
|
6354
6496
|
this.els.live?.classList.add("on");
|
|
@@ -6366,12 +6508,17 @@ var SeatPicker = class _SeatPicker {
|
|
|
6366
6508
|
const gone = this.controller.getSelection().filter((s) => !ownLabels.has(s.label) && (this.controller.getStatus(s.id) ?? "free") !== "free");
|
|
6367
6509
|
if (!gone.length) return;
|
|
6368
6510
|
this.controller.deselect(gone.map((s) => s.id));
|
|
6369
|
-
this.toast(
|
|
6511
|
+
this.toast((0, import_core2.t)("picker.seatJustTakenByAnother", { label: gone[0].label }), "error");
|
|
6370
6512
|
}
|
|
6371
6513
|
syncTray() {
|
|
6372
6514
|
if (!this.els.tray) return;
|
|
6373
6515
|
this.updateSelectionCapacity();
|
|
6374
6516
|
const seats = this.committedSelection();
|
|
6517
|
+
if (this.root?.dataset.layout === "narrow" && this.secCardEl && (this.hold || seats.length || this.pendingGACount())) {
|
|
6518
|
+
this.secCardEl.remove();
|
|
6519
|
+
this.secCardEl = null;
|
|
6520
|
+
this.lastSection = null;
|
|
6521
|
+
}
|
|
6375
6522
|
const gaAreas = this.controller.getGAAreas();
|
|
6376
6523
|
const heldItems = this.hold?.items ?? [];
|
|
6377
6524
|
const parts = [];
|
|
@@ -6382,18 +6529,22 @@ var SeatPicker = class _SeatPicker {
|
|
|
6382
6529
|
`<div class="sl-closed-note" role="status"><b>${this.tf("picker.salesClosedPill", "Sales are closed")}</b><span>${this.tf("picker.salesClosedCopy", "Ticket sales for this event have ended.")}${closedWhen}</span></div>`
|
|
6383
6530
|
);
|
|
6384
6531
|
} else if (!seats.length && !heldItems.length && !gaAreas.length) {
|
|
6385
|
-
parts.push(`<div class="sl-tray-hint"
|
|
6532
|
+
parts.push(`<div class="sl-tray-hint">${this.tf("picker.trayHintTapOrBest", "Tap a seat on the map, or let us pick the best available for you.")}</div>`);
|
|
6386
6533
|
} else if (!seats.length && !heldItems.length) {
|
|
6387
|
-
parts.push(`<div class="sl-tray-hint"
|
|
6534
|
+
parts.push(`<div class="sl-tray-hint">${this.tf("picker.trayHintTapOrStanding", "Tap a seat on the map \u2014 or grab standing tickets below.")}</div>`);
|
|
6388
6535
|
}
|
|
6389
6536
|
const noPicks = !seats.length && !heldItems.length && !this.pendingGACount();
|
|
6390
|
-
if (
|
|
6537
|
+
if (noPicks) this.baReopen = false;
|
|
6538
|
+
if (!this.salesClosed && !this.hold && (noPicks || this.baReopen || this.bestAvailableBusy || this.bestAvailableConfirm)) {
|
|
6391
6539
|
const cats = this.controller.doc?.categories ?? [];
|
|
6392
6540
|
const zones = this.controller.getBestAvailableZones();
|
|
6393
6541
|
if (this.baZone && !zones.some((zone) => zone.id === this.baZone)) this.baZone = "";
|
|
6394
|
-
parts.push(this.bestAvailableConfirm ? `<div class="sl-ba" role="alert"><div class="sl-ba-title"><span class="spark" aria-hidden="true">\u2726</span
|
|
6542
|
+
parts.push(this.bestAvailableConfirm ? `<div class="sl-ba" role="alert"><div class="sl-ba-title"><span class="spark" aria-hidden="true">\u2726</span>${this.tf("picker.replaceCurrentChoices", "Replace your current choices?")}</div><div class="sl-ba-replace"><b>${(0, import_core2.t)("picker.willFindSeatsTogether", { count: this.baQty })}</b><span>${this.tf("picker.manualTicketsRemovedNote", "Your manually selected tickets will be removed only after a new group is secured.")}</span></div><div class="sl-ba-actions"><button type="button" data-ba-cancel>${this.tf("picker.keepMine", "Keep mine")}</button><button type="button" class="replace" data-ba-replace>${this.tf("picker.findNewSeats", "Find new seats")}</button></div></div>` : `<div class="sl-ba"><div class="sl-ba-title"><span class="spark" aria-hidden="true">\u2726</span>${this.tf("picker.findBestSeatsTogether", "Find the best seats together")}</div><div class="sl-ba-copy"><span class="wide">${this.tf("picker.willChooseClosestGroup", "We\u2019ll choose the closest available group for you.")}</span><span class="narrow">${this.tf("picker.closestGroupChosenInstantly", "Closest available group, chosen instantly.")}</span></div>` + // Premium quick-pick — present only when the chart actually has premium
|
|
6395
6543
|
// seats (same present-only philosophy as the a11y filter chips).
|
|
6396
|
-
(this.controller.hasPremiumSeats() ? `<button type="button" class="sl-ba-premium${this.baPremium ? " on" : ""}" data-ba-premium aria-pressed="${this.baPremium ? "true" : "false"}"><span class="star" aria-hidden="true">\u2605</span>${this.tf("picker.bestSeatsPremium", "Best seats")}</button>` : "") + (cats.length > 1 ? `<select aria-label="Preferred ticket type" data-ba-cat><option value=""
|
|
6544
|
+
(this.controller.hasPremiumSeats() ? `<button type="button" class="sl-ba-premium${this.baPremium ? " on" : ""}" data-ba-premium aria-pressed="${this.baPremium ? "true" : "false"}"><span class="star" aria-hidden="true">\u2605</span>${this.tf("picker.bestSeatsPremium", "Best seats")}</button>` : "") + (cats.length > 1 ? `<select aria-label="${this.tf("picker.preferredTicketType", "Preferred ticket type")}" data-ba-cat><option value="">${this.tf("picker.anyTicketType", "Any ticket type")}</option>` + cats.map((c) => `<option value="${c.key}"${this.baCat === c.key ? " selected" : ""}>${c.label}</option>`).join("") + `</select>` : `<span aria-hidden="true"></span>`) + (zones.length ? `<select aria-label="${this.tf("picker.preferredVenueZone", "Preferred venue zone")}" data-ba-zone><option value="">${this.tf("picker.anyVenueZone", "Any venue zone")}</option>` + zones.map((zone) => `<option value="${escapeOption(zone.id)}"${this.baZone === zone.id ? " selected" : ""}>${escapeOption(zone.label)}</option>`).join("") + `</select>` : "") + `<div class="sl-ba-qty"><button type="button" data-ba="-1" aria-label="${this.tf("picker.fewerSeats", "Fewer seats")}">\u2212</button><span>${this.baQty}</span><button type="button" data-ba="1" aria-label="${this.tf("picker.moreSeats", "More seats")}">+</button></div><button type="button" class="sl-ba-go${this.bestAvailableBusy ? " sl-busy" : ""}"${this.bestAvailableBusy ? " disabled" : ""}>` + (this.bestAvailableBusy ? `<span class="sl-ba-spin" aria-hidden="true"></span>${this.tf("picker.findingBestSeats", "Finding the best seats\u2026")}` : (0, import_core2.tCount)("picker.findBestSeatsCount", this.baQty)) + `</button>` + // Reopened over an existing selection: the buyer needs the way back
|
|
6545
|
+
// stated as plainly as the way forward (Go routes through the
|
|
6546
|
+
// "Replace your current choices?" confirm, so nothing is lost yet).
|
|
6547
|
+
(this.baReopen ? `<button type="button" class="sl-ba-back" data-ba-close>${this.tf("picker.keepMyPicks", "Keep my picks")}</button>` : "") + `</div>`);
|
|
6397
6548
|
}
|
|
6398
6549
|
const idGrid = (seatId, label, objectType, quantity = 1, objectId, identity) => {
|
|
6399
6550
|
const esc = (value) => String(value ?? "\u2014").replace(/[&<>"]/g, (char) => ({
|
|
@@ -6405,21 +6556,21 @@ var SeatPicker = class _SeatPicker {
|
|
|
6405
6556
|
const d = seatId ? this.controller.seatDetails(seatId) : null;
|
|
6406
6557
|
const area = objectType === "ga" ? gaAreas.find((candidate) => candidate.id === objectId) : void 0;
|
|
6407
6558
|
const effectiveType = objectType === "ga" ? "ga" : d?.objectType ?? objectType;
|
|
6408
|
-
const typeWord = identity?.displayType?.trim() || d?.displayType?.trim() || area?.displayType?.trim() || (effectiveType === "table" ? "Table" : effectiveType === "booth" ? "Booth" : effectiveType === "ga" ? "General admission" : "Row");
|
|
6559
|
+
const typeWord = identity?.displayType?.trim() || d?.displayType?.trim() || area?.displayType?.trim() || (effectiveType === "table" ? this.tf("picker.table", "Table") : effectiveType === "booth" ? this.tf("picker.booth", "Booth") : effectiveType === "ga" ? this.tf("picker.generalAdmission", "General admission") : this.tf("picker.row", "Row"));
|
|
6409
6560
|
const buyerName = identity?.rowLabel ?? identity?.displayLabel ?? d?.rowLabel ?? d?.displayLabel ?? area?.displayLabel ?? area?.label ?? label;
|
|
6410
6561
|
if (effectiveType === "table" && identity?.bookingMode) {
|
|
6411
|
-
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(buyerName)}</span></span><span class="fld mid"><span class="sl-chip-eb"
|
|
6562
|
+
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(buyerName)}</span></span><span class="fld mid"><span class="sl-chip-eb">${this.tf("picker.guests", "Guests")}</span><span class="val">${quantity}</span></span></div>`;
|
|
6412
6563
|
}
|
|
6413
6564
|
if (effectiveType === "ga") {
|
|
6414
|
-
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(buyerName)}</span></span>` + (quantity > 1 ? `<span class="fld mid"><span class="sl-chip-eb"
|
|
6565
|
+
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(buyerName)}</span></span>` + (quantity > 1 ? `<span class="fld mid"><span class="sl-chip-eb">${this.tf("picker.tickets", "Tickets")}</span><span class="val">${quantity}</span></span>` : "") + `</div>`;
|
|
6415
6566
|
}
|
|
6416
6567
|
if (effectiveType === "booth") {
|
|
6417
|
-
return `<div class="sl-chip-id">` + (d?.sectionLabel ? `<span class="fld sec"><span class="sl-chip-eb"
|
|
6568
|
+
return `<div class="sl-chip-id">` + (d?.sectionLabel ? `<span class="fld sec"><span class="sl-chip-eb">${this.tf("picker.section", "Section")}</span><span class="val">${esc(d.sectionLabel)}</span></span>` : "") + `<span class="fld mid"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(buyerName)}</span></span></div>`;
|
|
6418
6569
|
}
|
|
6419
6570
|
if (!d?.sectionLabel && !d?.rowLabel && !d?.seatNumber) {
|
|
6420
|
-
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb"
|
|
6571
|
+
return `<div class="sl-chip-id"><span class="fld sec"><span class="sl-chip-eb">${this.tf("picker.seat", "Seat")}</span><span class="val">${esc(buyerName)}</span></span></div>`;
|
|
6421
6572
|
}
|
|
6422
|
-
return `<div class="sl-chip-id">` + (d.sectionLabel ? `<span class="fld sec"><span class="sl-chip-eb"
|
|
6573
|
+
return `<div class="sl-chip-id">` + (d.sectionLabel ? `<span class="fld sec"><span class="sl-chip-eb">${this.tf("picker.section", "Section")}</span><span class="val">${esc(d.sectionLabel)}</span></span>` : "") + (d.rowLabel ? `<span class="fld mid"><span class="sl-chip-eb">${esc(typeWord)}</span><span class="val">${esc(this.rowShort(d))}</span></span>` : "") + (d.seatNumber ? `<span class="fld mid"><span class="sl-chip-eb">${this.tf("picker.seat", "Seat")}</span><span class="val">${esc(d.seatNumber)}</span></span>` : "") + `</div>`;
|
|
6423
6574
|
};
|
|
6424
6575
|
const iconRail = (rmAria, viewLabel) => `<div class="sl-chip-rail"><button type="button" class="rm" aria-label="${rmAria}"><svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg></button>` + (viewLabel ? `<button type="button" class="view" data-view-label="${viewLabel}" aria-label="${(0, import_core2.t)("picker.viewFromSeat", { label: viewLabel })}"><svg viewBox="0 0 24 24"><path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7S1 12 1 12z"/><circle cx="12" cy="12" r="3"/></svg></button>` : "") + `</div>`;
|
|
6425
6576
|
for (const item of heldItems) {
|
|
@@ -6431,7 +6582,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6431
6582
|
const table = item.objectType === "table" ? this.controller.tableSelection(item.label) : null;
|
|
6432
6583
|
const canView2 = this.seatViewEnabled() && !!heldSeat && item.objectType !== "table";
|
|
6433
6584
|
parts.push(
|
|
6434
|
-
`<div class="sl-chip sl-held${this.lastTrayKeys.has(itemKey) ? "" : " sl-enter"}" data-key="${itemKey}" data-held="${encodeURIComponent(item.label)}"${heldSeat ? ` data-locate="${heldSeat.id}"` : ""}><div class="sl-chip-main">` + idGrid(heldSeat?.id ?? null, item.label, item.objectType, item.quantity ?? 1, item.objectId, table ?? void 0) + `<div class="sl-chip-sub"><span class="sl-ticket-state held" aria-label="Held for you" title="Held for you"><svg viewBox="0 0 24 24"><rect x="5" y="10" width="14" height="10" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg></span><span class="cat">${cat?.label ?? item.categoryKey}${tierName ? ` \xB7 ${tierName}` : ""}</span>` + (table?.bookingMode === "variable" ? `<button type="button" class="sl-table-edit" data-table-edit="${encodeURIComponent(item.label)}">${item.quantity ?? 1}
|
|
6585
|
+
`<div class="sl-chip sl-held${this.lastTrayKeys.has(itemKey) ? "" : " sl-enter"}" data-key="${itemKey}" data-held="${encodeURIComponent(item.label)}"${heldSeat ? ` data-locate="${heldSeat.id}"` : ""}><div class="sl-chip-main">` + idGrid(heldSeat?.id ?? null, item.label, item.objectType, item.quantity ?? 1, item.objectId, table ?? void 0) + `<div class="sl-chip-sub"><span class="sl-ticket-state held" aria-label="${this.tf("picker.heldForYou", "Held for you")}" title="${this.tf("picker.heldForYou", "Held for you")}"><svg viewBox="0 0 24 24"><rect x="5" y="10" width="14" height="10" rx="2"/><path d="M8 10V7a4 4 0 0 1 8 0v3"/></svg></span><span class="cat">${cat?.label ?? item.categoryKey}${tierName ? ` \xB7 ${tierName}` : ""}</span>` + (table?.bookingMode === "variable" ? `<button type="button" class="sl-table-edit" data-table-edit="${encodeURIComponent(item.label)}">${(0, import_core2.t)("picker.guestsCountEdit", { count: item.quantity ?? 1 })}</button>` : "") + this.wheelchairChipMarker(heldSeat?.wheelchairSpaceType) + this.commercialChipMarker(heldSeat?.commercial) + `<span class="amt">${this.money(this.paidPrice(item.categoryKey, item.tierId, item.unitPrice) * (item.quantity ?? 1))}</span></div></div>` + iconRail((0, import_core2.t)("picker.removeHeldTicketLabel", { label: item.label }), canView2 ? item.label : null) + `</div>`
|
|
6435
6586
|
);
|
|
6436
6587
|
}
|
|
6437
6588
|
const heldLabels = new Set(heldItems.map((item) => item.label));
|
|
@@ -6442,13 +6593,18 @@ var SeatPicker = class _SeatPicker {
|
|
|
6442
6593
|
const cat = this.controller.doc?.categories.find((c) => c.key === s.categoryKey);
|
|
6443
6594
|
const tierSelect = s.tiers && s.tiers.length ? `<select class="tier" data-tier="${s.id}" aria-label="${(0, import_core2.t)("picker.ticketTierFor", { label: s.label })}">` + s.tiers.map((ti) => `<option value="${ti.id}"${ti.id === s.tierId ? " selected" : ""}>${ti.name} \xB7 ${this.money(this.paidPrice(s.categoryKey, ti.id, ti.price))}</option>`).join("") + `</select>` : "";
|
|
6444
6595
|
parts.push(
|
|
6445
|
-
`<div class="sl-chip${this.lastTrayKeys.has(itemKey) ? "" : " sl-enter"}" data-key="${itemKey}" data-seat="${s.id}" data-locate="${s.id}"><div class="sl-chip-main">` + idGrid(s.id, s.label, s.objectType, s.quantity ?? 1, s.objectId, s) + `<div class="sl-chip-sub"><span class="sl-ticket-state" aria-label="Selected" title="Selected"><svg viewBox="0 0 24 24"><path d="M5 12l4 4L19 6"/></svg></span><span class="cat">${cat?.label ?? s.categoryKey}</span>` + (s.objectType === "table" && s.bookingMode === "variable" ? `<button type="button" class="sl-table-edit" data-table-edit="${encodeURIComponent(s.label)}">${s.quantity ?? 1}
|
|
6596
|
+
`<div class="sl-chip${this.lastTrayKeys.has(itemKey) ? "" : " sl-enter"}" data-key="${itemKey}" data-seat="${s.id}" data-locate="${s.id}"><div class="sl-chip-main">` + idGrid(s.id, s.label, s.objectType, s.quantity ?? 1, s.objectId, s) + `<div class="sl-chip-sub"><span class="sl-ticket-state" aria-label="${this.tf("picker.selected", "Selected")}" title="${this.tf("picker.selected", "Selected")}"><svg viewBox="0 0 24 24"><path d="M5 12l4 4L19 6"/></svg></span><span class="cat">${cat?.label ?? s.categoryKey}</span>` + (s.objectType === "table" && s.bookingMode === "variable" ? `<button type="button" class="sl-table-edit" data-table-edit="${encodeURIComponent(s.label)}">${(0, import_core2.t)("picker.guestsCountEdit", { count: s.quantity ?? 1 })}</button>` : "") + `${this.wheelchairChipMarker(s.wheelchairSpaceType)}${this.commercialChipMarker(s.commercial)}${tierSelect}<span class="amt">${this.money(this.paidPrice(s.categoryKey, s.tierId ?? null, s.price) * (s.quantity ?? 1))}</span></div></div>` + iconRail((0, import_core2.t)("picker.removeSeatLabel", { label: s.label }), canView && s.objectType !== "table" ? s.label : null) + `</div>`
|
|
6446
6597
|
);
|
|
6447
6598
|
}
|
|
6448
6599
|
for (const area of gaAreas) {
|
|
6449
6600
|
const qty = this.gaQty.get(area.id) ?? 0;
|
|
6450
6601
|
parts.push(
|
|
6451
|
-
`<div class="sl-ga" data-ga="${area.id}"><div class="sl-ga-info"><div class="sl-ga-name">${area.displayLabel ?? area.label}</div><div class="sl-ga-sub">${area.displayType ?? "General admission"} \xB7 ${this.money(this.paidPrice(area.categoryKey, null, area.price))} \xB7 ${area.available}
|
|
6602
|
+
`<div class="sl-ga" data-ga="${area.id}"><div class="sl-ga-info"><div class="sl-ga-name">${area.displayLabel ?? area.label}</div><div class="sl-ga-sub">${area.displayType ?? this.tf("picker.generalAdmission", "General admission")} \xB7 ${this.money(this.paidPrice(area.categoryKey, null, area.price))} \xB7 ${(0, import_core2.tCount)("picker.leftCount", area.available)}</div></div><div class="sl-ga-qty"><button type="button" data-d="-1" aria-label="${this.tf("picker.fewer", "Fewer")}">\u2212</button><span>${qty}</span><button type="button" data-d="1" aria-label="${this.tf("picker.more", "More")}">+</button></div></div>`
|
|
6603
|
+
);
|
|
6604
|
+
}
|
|
6605
|
+
if (!this.salesClosed && !this.hold && !noPicks && !this.baReopen && !this.bestAvailableBusy && !this.bestAvailableConfirm) {
|
|
6606
|
+
parts.push(
|
|
6607
|
+
`<button type="button" class="sl-ba-reopen" data-ba-reopen><span aria-hidden="true">\u2726</span>${this.tf("picker.findTogetherInstead", "Find seats together instead")}</button>`
|
|
6452
6608
|
);
|
|
6453
6609
|
}
|
|
6454
6610
|
this.els.tray.innerHTML = parts.join("");
|
|
@@ -6483,6 +6639,16 @@ var SeatPicker = class _SeatPicker {
|
|
|
6483
6639
|
this.syncTray();
|
|
6484
6640
|
this.els.tray.querySelector(".sl-ba-go")?.focus();
|
|
6485
6641
|
});
|
|
6642
|
+
this.els.tray.querySelector("[data-ba-reopen]")?.addEventListener("click", () => {
|
|
6643
|
+
this.baReopen = true;
|
|
6644
|
+
this.syncTray();
|
|
6645
|
+
this.els.tray.querySelector(".sl-ba-go")?.focus();
|
|
6646
|
+
});
|
|
6647
|
+
this.els.tray.querySelector("[data-ba-close]")?.addEventListener("click", () => {
|
|
6648
|
+
this.baReopen = false;
|
|
6649
|
+
this.syncTray();
|
|
6650
|
+
this.els.tray.querySelector("[data-ba-reopen]")?.focus();
|
|
6651
|
+
});
|
|
6486
6652
|
this.els.tray.querySelector("[data-ba-replace]")?.addEventListener("click", () => {
|
|
6487
6653
|
this.bestAvailableConfirm = false;
|
|
6488
6654
|
void this.bestAvailable(this.baQty, this.baCat || void 0, { preferPremium: this.baPremium, zoneId: this.baZone || void 0 });
|
|
@@ -6495,15 +6661,15 @@ var SeatPicker = class _SeatPicker {
|
|
|
6495
6661
|
return;
|
|
6496
6662
|
}
|
|
6497
6663
|
const id = chip.dataset.seat;
|
|
6498
|
-
const label = this.controller.getSelection().find((sel) => sel.id === id)?.label ?? "Seat";
|
|
6664
|
+
const label = this.controller.getSelection().find((sel) => sel.id === id)?.label ?? this.tf("picker.seat", "Seat");
|
|
6499
6665
|
const remove = () => {
|
|
6500
6666
|
this.controller.deselect([id]);
|
|
6501
|
-
this.toast(
|
|
6502
|
-
label: "Undo",
|
|
6667
|
+
this.toast((0, import_core2.t)("picker.labelRemoved", { label }), "neutral", {
|
|
6668
|
+
label: this.tf("picker.undo", "Undo"),
|
|
6503
6669
|
onClick: () => {
|
|
6504
6670
|
const restored = this.controller.select([id]);
|
|
6505
6671
|
this.toast(
|
|
6506
|
-
restored.length ?
|
|
6672
|
+
restored.length ? (0, import_core2.t)("picker.labelRestored", { label }) : (0, import_core2.t)("picker.labelNoLongerAvailable", { label }),
|
|
6507
6673
|
restored.length ? "success" : "warning"
|
|
6508
6674
|
);
|
|
6509
6675
|
}
|
|
@@ -6575,31 +6741,31 @@ var SeatPicker = class _SeatPicker {
|
|
|
6575
6741
|
const pendingCount = this.pendingSelectionCount();
|
|
6576
6742
|
const previousCount = this.lastTrayCount;
|
|
6577
6743
|
const previousTotal = this.lastTrayTotal;
|
|
6578
|
-
this.els.count.textContent = count ?
|
|
6744
|
+
this.els.count.textContent = count ? (0, import_core2.tCount)("picker.ticketsCount", count) : this.tf("picker.noSeatsSelected", "No seats selected");
|
|
6579
6745
|
this.els.total.textContent = count ? this.money(total) : "";
|
|
6580
6746
|
this.root?.setAttribute("data-has-selection", String(count > 0));
|
|
6581
6747
|
this.root?.setAttribute(
|
|
6582
6748
|
"data-ba-active",
|
|
6583
|
-
String(this.bestAvailableConfirm || this.bestAvailableBusy)
|
|
6749
|
+
String(this.bestAvailableConfirm || this.bestAvailableBusy || this.baReopen)
|
|
6584
6750
|
);
|
|
6585
6751
|
this.els.foot?.classList.toggle("empty", count === 0);
|
|
6586
6752
|
if (this.els.seatSummary) {
|
|
6587
|
-
this.els.seatSummary.textContent = count ?
|
|
6753
|
+
this.els.seatSummary.textContent = count ? (0, import_core2.tCount)("picker.seatsSelectedCount", count) : "";
|
|
6588
6754
|
}
|
|
6589
6755
|
this.syncCta(count, pendingCount);
|
|
6590
6756
|
if (this.hold) {
|
|
6591
6757
|
const securedCount = heldCount || this.hold.seats?.length || 0;
|
|
6592
6758
|
if (this.els.holdTitle) {
|
|
6593
|
-
this.els.holdTitle.textContent =
|
|
6759
|
+
this.els.holdTitle.textContent = (0, import_core2.t)("picker.securedCount", { count: securedCount });
|
|
6594
6760
|
}
|
|
6595
6761
|
if (this.els.holdCopy) {
|
|
6596
6762
|
this.holdCopyPending = pendingCount > 0;
|
|
6597
|
-
this.els.holdCopy.textContent = pendingCount ?
|
|
6763
|
+
this.els.holdCopy.textContent = pendingCount ? (0, import_core2.t)("picker.moreSelectedCount", { count: pendingCount }) : this.holdReassuranceText();
|
|
6598
6764
|
}
|
|
6599
6765
|
const change = this.els.holdChange;
|
|
6600
6766
|
if (change) {
|
|
6601
6767
|
change.disabled = this.releasingHold;
|
|
6602
|
-
change.textContent = this.releasingHold ? "Releasing\u2026" : "Change";
|
|
6768
|
+
change.textContent = this.releasingHold ? this.tf("picker.releasingEllipsis", "Releasing\u2026") : this.tf("picker.change", "Change");
|
|
6603
6769
|
}
|
|
6604
6770
|
}
|
|
6605
6771
|
if (count !== previousCount) this.animateOnce(this.els.count, "sl-value-pop", 380);
|
|
@@ -6624,21 +6790,21 @@ var SeatPicker = class _SeatPicker {
|
|
|
6624
6790
|
renderPeek(count, total, pendingCount) {
|
|
6625
6791
|
if (!this.els.peek) return;
|
|
6626
6792
|
if (count && this.ctaPhase === "holding") {
|
|
6627
|
-
this.els.peek.innerHTML = `<span
|
|
6793
|
+
this.els.peek.innerHTML = `<span>${this.tf("picker.securingSeats", "Securing your seats\u2026")}</span>`;
|
|
6628
6794
|
return;
|
|
6629
6795
|
}
|
|
6630
6796
|
if (count && this.ctaPhase === "checkout") {
|
|
6631
|
-
this.els.peek.innerHTML = `<span
|
|
6797
|
+
this.els.peek.innerHTML = `<span>${(0, import_core2.t)("picker.peekSecured", { count, total: this.money(total) })}</span>`;
|
|
6632
6798
|
return;
|
|
6633
6799
|
}
|
|
6634
6800
|
if (count) {
|
|
6635
|
-
const
|
|
6636
|
-
this.els.peek.innerHTML = `<span>${
|
|
6801
|
+
const toCheckout = !!this.hold;
|
|
6802
|
+
this.els.peek.innerHTML = `<span>${(0, import_core2.tCount)("picker.peekTicketsTotal", count, { total: this.money(total) })}</span><button type="button" class="go sl-sheet-go" data-act="${toCheckout ? "checkout" : "open"}">${this.hold ? pendingCount ? this.tf("picker.secureMore", "Secure more") : this.tf("picker.continue", "Continue") : this.tf("picker.review", "Review")}</button>`;
|
|
6637
6803
|
} else if (this.salesClosed) {
|
|
6638
6804
|
this.els.peek.innerHTML = `<span>${this.tf("picker.salesClosedPill", "Sales are closed")}</span>`;
|
|
6639
6805
|
} else {
|
|
6640
6806
|
const prices = (this.controller.doc?.categories ?? []).map((c) => this.catPrice(c)).filter((p) => p != null);
|
|
6641
|
-
this.els.peek.innerHTML = (prices.length ? `<span
|
|
6807
|
+
this.els.peek.innerHTML = (prices.length ? `<span>${(0, import_core2.t)("picker.peekFromPrice", { price: this.money(Math.min(...prices)) })}</span>` : `<span>${this.tf("picker.pickYourSeats", "Pick your seats")}</span>`) + `<button type="button" class="go sl-sheet-go" data-act="open">${this.tf("picker.bestSeatsStar", "\u2726 Best seats")}</button>`;
|
|
6642
6808
|
}
|
|
6643
6809
|
}
|
|
6644
6810
|
async removeHeldLabel(label, chip) {
|
|
@@ -6651,7 +6817,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6651
6817
|
const preserveAcrossNavigation = this.handedOff;
|
|
6652
6818
|
const released = await this.controller.releaseLabels([label]);
|
|
6653
6819
|
if (!released) {
|
|
6654
|
-
this.toast(
|
|
6820
|
+
this.toast((0, import_core2.t)("picker.couldNotRemoveLabel", { label }), "error");
|
|
6655
6821
|
return false;
|
|
6656
6822
|
}
|
|
6657
6823
|
const remaining = this.controller.currentHold();
|
|
@@ -6667,7 +6833,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6667
6833
|
}
|
|
6668
6834
|
this.syncTray();
|
|
6669
6835
|
this.emitHoldChange();
|
|
6670
|
-
this.toast(
|
|
6836
|
+
this.toast((0, import_core2.t)("picker.labelRemovedFromHold", { label }), "success");
|
|
6671
6837
|
return true;
|
|
6672
6838
|
} finally {
|
|
6673
6839
|
this.releasingLabels.delete(label);
|
|
@@ -6681,23 +6847,23 @@ var SeatPicker = class _SeatPicker {
|
|
|
6681
6847
|
const button = this.els.holdChange;
|
|
6682
6848
|
if (button) {
|
|
6683
6849
|
button.disabled = true;
|
|
6684
|
-
button.textContent = "Releasing\u2026";
|
|
6850
|
+
button.textContent = this.tf("picker.releasingEllipsis", "Releasing\u2026");
|
|
6685
6851
|
}
|
|
6686
6852
|
try {
|
|
6687
6853
|
await this.release();
|
|
6688
|
-
if (!this.hold) this.toast("Held tickets released. Choose your new seats.", "success");
|
|
6854
|
+
if (!this.hold) this.toast(this.tf("picker.heldTicketsReleased", "Held tickets released. Choose your new seats."), "success");
|
|
6689
6855
|
} finally {
|
|
6690
6856
|
this.releasingHold = false;
|
|
6691
6857
|
if (button?.isConnected) {
|
|
6692
6858
|
button.disabled = false;
|
|
6693
|
-
button.textContent = "Change";
|
|
6859
|
+
button.textContent = this.tf("picker.change", "Change");
|
|
6694
6860
|
}
|
|
6695
6861
|
}
|
|
6696
6862
|
}
|
|
6697
6863
|
async handleCta() {
|
|
6698
6864
|
if (this.salesClosed) return;
|
|
6699
6865
|
if (this.totalTicketCount() > this.maxTickets) {
|
|
6700
|
-
this.toast(
|
|
6866
|
+
this.toast((0, import_core2.t)("picker.removeTicketsUntilOrFewer", { count: this.maxTickets }), "warning");
|
|
6701
6867
|
return;
|
|
6702
6868
|
}
|
|
6703
6869
|
const committed = this.committedSelection();
|
|
@@ -6723,7 +6889,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6723
6889
|
hold = h ? { holdId: h.holdId, expiresAt: h.expiresAt, seats: h.seats, items: h.items } : hold;
|
|
6724
6890
|
}
|
|
6725
6891
|
if (!hold) {
|
|
6726
|
-
this.toast("One or more seats were just taken. Please pick again.", "error");
|
|
6892
|
+
this.toast(this.tf("picker.seatsJustTaken", "One or more seats were just taken. Please pick again."), "error");
|
|
6727
6893
|
this.setCtaPhase("idle");
|
|
6728
6894
|
this.syncTray();
|
|
6729
6895
|
return;
|
|
@@ -6740,7 +6906,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6740
6906
|
const problem = err;
|
|
6741
6907
|
const labels = (problem.conflicts ?? []).map((conflict) => conflict.label).filter(Boolean).slice(0, 3);
|
|
6742
6908
|
if (problem.reason === "event_closed") this.setSalesClosed(true);
|
|
6743
|
-
const message = problem.reason === "event_closed" ? "Seat sales have closed for this event." : labels.length ?
|
|
6909
|
+
const message = problem.reason === "event_closed" ? this.tf("picker.seatSalesClosedForEvent", "Seat sales have closed for this event.") : labels.length ? labels.length === 1 ? (0, import_core2.t)("picker.labelsNoLongerAvailable.one", { labels: labels.join(", ") }) : (0, import_core2.t)("picker.labelsNoLongerAvailable.other", { labels: labels.join(", ") }) : this.tf("picker.seatsJustTaken", "One or more seats were just taken. Please pick again.");
|
|
6744
6910
|
this.toast(message, "error");
|
|
6745
6911
|
this.setCtaPhase("idle");
|
|
6746
6912
|
} finally {
|
|
@@ -6754,14 +6920,14 @@ var SeatPicker = class _SeatPicker {
|
|
|
6754
6920
|
const ms = Math.max(0, this.holdExpiresAt - Date.now());
|
|
6755
6921
|
const m = Math.floor(ms / 6e4);
|
|
6756
6922
|
const s = String(Math.floor(ms % 6e4 / 1e3)).padStart(2, "0");
|
|
6757
|
-
return
|
|
6923
|
+
return (0, import_core2.t)("picker.holdReassurance", { time: `${m}:${s}` });
|
|
6758
6924
|
}
|
|
6759
6925
|
startHoldTimer(expiresAt) {
|
|
6760
6926
|
this.stopHoldTimer();
|
|
6761
6927
|
this.holdExpiresAt = expiresAt;
|
|
6762
6928
|
if (this.hold) this.rememberHold(this.hold);
|
|
6763
6929
|
const pill = this.els.hold;
|
|
6764
|
-
pill.innerHTML =
|
|
6930
|
+
pill.innerHTML = `<span class="sl-hold-dot" aria-hidden="true"></span><span>${this.tf("picker.held", "Held")}</span><span class="sl-hold-time" data-ref="holdTime"></span>`;
|
|
6765
6931
|
const time = pill.querySelector('[data-ref="holdTime"]');
|
|
6766
6932
|
this.els.holdNote?.classList.add("on");
|
|
6767
6933
|
const tick = () => {
|
|
@@ -6794,7 +6960,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6794
6960
|
const totalSecs = Math.ceil(ms / 1e3);
|
|
6795
6961
|
const m = Math.floor(totalSecs / 60);
|
|
6796
6962
|
const s = String(totalSecs % 60).padStart(2, "0");
|
|
6797
|
-
this.els.extendTxt.innerHTML =
|
|
6963
|
+
this.els.extendTxt.innerHTML = (0, import_core2.t)("picker.seatsHeldForNeedMoreTime", { time: `${m}:${s}` });
|
|
6798
6964
|
this.extendEl.classList.add("on");
|
|
6799
6965
|
} else {
|
|
6800
6966
|
this.extendEl.classList.remove("on");
|
|
@@ -6804,7 +6970,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6804
6970
|
const btn = this.els.extendBtn;
|
|
6805
6971
|
btn.disabled = true;
|
|
6806
6972
|
const prev = btn.textContent;
|
|
6807
|
-
btn.textContent = "Adding\u2026";
|
|
6973
|
+
btn.textContent = this.tf("picker.addingEllipsis", "Adding\u2026");
|
|
6808
6974
|
try {
|
|
6809
6975
|
const h = await this.controller.extendHold(this.opts.holdTtlMs);
|
|
6810
6976
|
if (h) {
|
|
@@ -6813,13 +6979,13 @@ var SeatPicker = class _SeatPicker {
|
|
|
6813
6979
|
this.extendEl?.classList.remove("on");
|
|
6814
6980
|
this.rememberHold(this.hold);
|
|
6815
6981
|
this.emitHoldChange();
|
|
6816
|
-
this.toast("More time added \u2014 your seats are still held.", "success");
|
|
6982
|
+
this.toast(this.tf("picker.moreTimeAdded", "More time added \u2014 your seats are still held."), "success");
|
|
6817
6983
|
} else {
|
|
6818
|
-
this.toast("Couldn't add more time \u2014 please head to checkout now.", "warning");
|
|
6984
|
+
this.toast(this.tf("picker.couldNotAddMoreTime", "Couldn't add more time \u2014 please head to checkout now."), "warning");
|
|
6819
6985
|
}
|
|
6820
6986
|
} catch (err) {
|
|
6821
6987
|
this.opts.onError?.(err);
|
|
6822
|
-
this.toast("Couldn't add more time \u2014 please head to checkout now.", "warning");
|
|
6988
|
+
this.toast(this.tf("picker.couldNotAddMoreTime", "Couldn't add more time \u2014 please head to checkout now."), "warning");
|
|
6823
6989
|
} finally {
|
|
6824
6990
|
btn.disabled = false;
|
|
6825
6991
|
btn.textContent = prev;
|
|
@@ -6846,7 +7012,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6846
7012
|
this.forgetHold();
|
|
6847
7013
|
const n = handoff.lineItems.reduce((sum, i) => sum + i.quantity, 0);
|
|
6848
7014
|
if (this.els.bookedSub) {
|
|
6849
|
-
this.els.bookedSub.innerHTML = `<span class="sl-booked-seats">${n} ${
|
|
7015
|
+
this.els.bookedSub.innerHTML = `<span class="sl-booked-seats">${(0, import_core2.tCount)("picker.ticketsCount", n)}</span> ${this.tf("picker.confirmedAndOnWay", "confirmed. A confirmation is on its way.")}`;
|
|
6850
7016
|
}
|
|
6851
7017
|
this.bookedEl?.classList.add("on");
|
|
6852
7018
|
this.opts.onBooked?.(handoff);
|
|
@@ -6928,7 +7094,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
6928
7094
|
({ mountCheckout: mountCheckout2 } = await loadHostedCheckout());
|
|
6929
7095
|
} catch (err) {
|
|
6930
7096
|
this.opts.onError?.(err);
|
|
6931
|
-
this.toast("Checkout could not be opened. Your seats are still held \u2014 please try again.", "error");
|
|
7097
|
+
this.toast(this.tf("picker.checkoutCouldNotBeOpened", "Checkout could not be opened. Your seats are still held \u2014 please try again."), "error");
|
|
6932
7098
|
this.setCtaPhase("idle");
|
|
6933
7099
|
return;
|
|
6934
7100
|
}
|
|
@@ -7043,9 +7209,9 @@ var SeatPicker = class _SeatPicker {
|
|
|
7043
7209
|
rowTypeWord(details) {
|
|
7044
7210
|
const authored = details?.displayType?.trim() || details?.rowType?.trim();
|
|
7045
7211
|
if (authored) return authored;
|
|
7046
|
-
if (details?.objectType === "table") return "Table";
|
|
7047
|
-
if (details?.objectType === "booth") return "Booth";
|
|
7048
|
-
return "Row";
|
|
7212
|
+
if (details?.objectType === "table") return this.tf("picker.table", "Table");
|
|
7213
|
+
if (details?.objectType === "booth") return this.tf("picker.booth", "Booth");
|
|
7214
|
+
return this.tf("picker.row", "Row");
|
|
7049
7215
|
}
|
|
7050
7216
|
rowShort(details) {
|
|
7051
7217
|
const row = details?.rowLabel;
|
|
@@ -7068,7 +7234,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7068
7234
|
const isGroupedTable = details.objectType === "table" && !!details.bookingMode;
|
|
7069
7235
|
const isBooth = details.objectType === "booth";
|
|
7070
7236
|
const hasLoc = details.sectionLabel || details.rowLabel || details.seatNumber;
|
|
7071
|
-
const grid = isGroupedTable ? `<div class="sl-tip-grid"><div class="sl-tip-field"><span class="sl-tip-key">${esc(this.rowTypeWord(details))}</span><span class="sl-tip-val">${esc(details.rowLabel ?? details.displayLabel ?? details.label)}</span></div><div class="sl-tip-field"><span class="sl-tip-key"
|
|
7237
|
+
const grid = isGroupedTable ? `<div class="sl-tip-grid"><div class="sl-tip-field"><span class="sl-tip-key">${esc(this.rowTypeWord(details))}</span><span class="sl-tip-val">${esc(details.rowLabel ?? details.displayLabel ?? details.label)}</span></div><div class="sl-tip-field"><span class="sl-tip-key">${this.tf("picker.guests", "Guests")}</span><span class="sl-tip-val">${details.bookingMode === "variable" ? `${details.minOccupancy}\u2013${details.maxOccupancy}` : details.capacity}</span></div></div>` : isBooth ? `<div class="sl-tip-grid">` + (details.sectionLabel ? `<div class="sl-tip-field"><span class="sl-tip-key">${this.tf("picker.section", "Section")}</span><span class="sl-tip-val">${esc(details.sectionLabel)}</span></div>` : "") + `<div class="sl-tip-field"><span class="sl-tip-key">${esc(this.rowTypeWord(details))}</span><span class="sl-tip-val">${esc(details.rowLabel ?? details.displayLabel ?? details.label)}</span></div></div>` : hasLoc ? `<div class="sl-tip-grid">` + (details.sectionLabel ? `<div class="sl-tip-field"><span class="sl-tip-key">${this.tf("picker.section", "Section")}</span><span class="sl-tip-val">${esc(details.sectionLabel)}</span></div>` : "") + (details.rowLabel ? `<div class="sl-tip-field"><span class="sl-tip-key">${esc(this.rowTypeWord(details))}</span><span class="sl-tip-val">${esc(this.rowShort(details))}</span></div>` : "") + (details.seatNumber ? `<div class="sl-tip-field"><span class="sl-tip-key">${this.tf("picker.seat", "Seat")}</span><span class="sl-tip-val">${esc(details.seatNumber)}</span></div>` : "") + `</div>` : `<div class="sl-tip-grid one"><div class="sl-tip-field"><span class="sl-tip-key">${this.tf("picker.seat", "Seat")}</span><span class="sl-tip-val">${esc(details.displayLabel ?? details.label)}</span></div></div>`;
|
|
7072
7238
|
const statusLine = details.status === "free" ? "" : `<div class="sl-tip-status">${details.status === "held" ? (0, import_core2.t)("map.statusHeld") : (0, import_core2.t)("map.statusTaken")}</div>`;
|
|
7073
7239
|
const limited = this.limitedViewLabel(details.commercial);
|
|
7074
7240
|
const cxLine = limited ? `<div class="sl-tip-cx"><span class="g" aria-hidden="true">\u25D0</span>${esc(limited)}</div>` : "";
|
|
@@ -7359,7 +7525,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7359
7525
|
const identity = details?.displayLabel ?? seat.displayLabel ?? seat.label;
|
|
7360
7526
|
const section = details?.sectionLabel;
|
|
7361
7527
|
const row = this.rowShort(details);
|
|
7362
|
-
const location2 = [section, row ?
|
|
7528
|
+
const location2 = [section, row ? (0, import_core2.t)("picker.rowLabel", { label: row }) : null, identity].filter(Boolean).join(" \xB7 ");
|
|
7363
7529
|
const copy = status === "held" ? {
|
|
7364
7530
|
title: this.tf("picker.temporarilyHeld", "Temporarily held"),
|
|
7365
7531
|
message: this.tf("picker.heldSeatExplanation", "Another buyer is holding this seat. It may become available again.")
|
|
@@ -7455,7 +7621,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7455
7621
|
chip = document.createElement("div");
|
|
7456
7622
|
chip.className = "sl-view3d-compare-saved";
|
|
7457
7623
|
chip.setAttribute("role", "group");
|
|
7458
|
-
chip.setAttribute("aria-label", "Saved seat comparison");
|
|
7624
|
+
chip.setAttribute("aria-label", this.tf("picker.savedSeatComparison", "Saved seat comparison"));
|
|
7459
7625
|
const main2 = document.createElement("button");
|
|
7460
7626
|
main2.type = "button";
|
|
7461
7627
|
main2.className = "main";
|
|
@@ -7467,7 +7633,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7467
7633
|
clear.type = "button";
|
|
7468
7634
|
clear.className = "clear";
|
|
7469
7635
|
clear.textContent = "\xD7";
|
|
7470
|
-
clear.setAttribute("aria-label", "Clear saved seat comparison");
|
|
7636
|
+
clear.setAttribute("aria-label", this.tf("picker.clearSavedSeatComparison", "Clear saved seat comparison"));
|
|
7471
7637
|
clear.addEventListener("click", () => this.clearView3dComparison());
|
|
7472
7638
|
chip.append(main2, clear);
|
|
7473
7639
|
overlay.appendChild(chip);
|
|
@@ -7476,8 +7642,8 @@ var SeatPicker = class _SeatPicker {
|
|
|
7476
7642
|
const count = this.view3dCompareSeatIds.length;
|
|
7477
7643
|
const main = chip.querySelector(".main");
|
|
7478
7644
|
if (main) {
|
|
7479
|
-
main.textContent = count > 1 ?
|
|
7480
|
-
main.setAttribute("aria-label", count > 1 ?
|
|
7645
|
+
main.textContent = count > 1 ? (0, import_core2.t)("picker.compareCount", { count }) : this.tf("picker.oneSeatSaved", "1 seat saved");
|
|
7646
|
+
main.setAttribute("aria-label", count > 1 ? (0, import_core2.t)("picker.openComparisonOfSeats", { count }) : this.tf("picker.oneSeatSavedChooseAnother", "One seat saved; choose another to compare"));
|
|
7481
7647
|
}
|
|
7482
7648
|
}
|
|
7483
7649
|
view3dComparisonSnapshot(seatId) {
|
|
@@ -7754,8 +7920,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7754
7920
|
const wantFloors = floors.length > 1;
|
|
7755
7921
|
const wantZones = zones.length > 1;
|
|
7756
7922
|
const wantSections = sections.length > 1;
|
|
7757
|
-
|
|
7758
|
-
if (!wantFloors && !wantZones && !wantSections && !wantLocator) return;
|
|
7923
|
+
if (!wantFloors && !wantZones && !wantSections) return;
|
|
7759
7924
|
const nav = document.createElement("div");
|
|
7760
7925
|
nav.className = "sl-view3d-nav";
|
|
7761
7926
|
const finderToggle = document.createElement("button");
|
|
@@ -7765,7 +7930,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7765
7930
|
const setFinderOpen = (open) => {
|
|
7766
7931
|
nav.classList.toggle("is-open", open);
|
|
7767
7932
|
finderToggle.setAttribute("aria-expanded", String(open));
|
|
7768
|
-
finderToggle.textContent = open ? "Close
|
|
7933
|
+
finderToggle.textContent = open ? this.tf("picker.closeVenueNav", "Close") : wantFloors && (wantZones || wantSections) ? this.tf("picker.levelsAndAreas", "Levels & areas") : wantFloors ? this.tf("picker.levels", "Levels") : this.tf("picker.areas", "Areas");
|
|
7769
7934
|
};
|
|
7770
7935
|
finderToggle.addEventListener("click", () => setFinderOpen(!nav.classList.contains("is-open")));
|
|
7771
7936
|
nav.addEventListener("keydown", (event) => {
|
|
@@ -7802,7 +7967,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7802
7967
|
row.appendChild(b);
|
|
7803
7968
|
};
|
|
7804
7969
|
add(this.tf("picker.allLevels", "All levels"), null);
|
|
7805
|
-
for (const f of floors) add(f.label ||
|
|
7970
|
+
for (const f of floors) add(f.label || (0, import_core2.t)("picker.levelNumber", { number: f.index + 1 }), f.index);
|
|
7806
7971
|
nav.appendChild(row);
|
|
7807
7972
|
}
|
|
7808
7973
|
if (wantZones || wantSections) {
|
|
@@ -7845,86 +8010,6 @@ var SeatPicker = class _SeatPicker {
|
|
|
7845
8010
|
}
|
|
7846
8011
|
nav.appendChild(row);
|
|
7847
8012
|
}
|
|
7848
|
-
if (wantLocator) {
|
|
7849
|
-
const locator = document.createElement("div");
|
|
7850
|
-
locator.className = "sl-view3d-locator";
|
|
7851
|
-
locator.setAttribute("role", "group");
|
|
7852
|
-
locator.setAttribute("aria-label", "Find an exact seat in 3D");
|
|
7853
|
-
const sectionSelect = document.createElement("select");
|
|
7854
|
-
sectionSelect.setAttribute("aria-label", "Choose section in 3D");
|
|
7855
|
-
const rowSelect = document.createElement("select");
|
|
7856
|
-
rowSelect.setAttribute("aria-label", "Choose row in 3D");
|
|
7857
|
-
const seatSelect = document.createElement("select");
|
|
7858
|
-
seatSelect.setAttribute("aria-label", "Choose seat in 3D");
|
|
7859
|
-
const view = document.createElement("button");
|
|
7860
|
-
view.type = "button";
|
|
7861
|
-
view.textContent = "Inspect seat";
|
|
7862
|
-
view.disabled = true;
|
|
7863
|
-
const fill = (select, placeholder, entries) => {
|
|
7864
|
-
select.replaceChildren();
|
|
7865
|
-
const first = document.createElement("option");
|
|
7866
|
-
first.value = "";
|
|
7867
|
-
first.textContent = placeholder;
|
|
7868
|
-
select.appendChild(first);
|
|
7869
|
-
for (const entry of entries) {
|
|
7870
|
-
const option = document.createElement("option");
|
|
7871
|
-
option.value = entry.id;
|
|
7872
|
-
option.textContent = entry.label;
|
|
7873
|
-
select.appendChild(option);
|
|
7874
|
-
}
|
|
7875
|
-
select.value = "";
|
|
7876
|
-
};
|
|
7877
|
-
fill(sectionSelect, "1. Section", allSections.map((section) => ({
|
|
7878
|
-
id: section.id,
|
|
7879
|
-
label: `${section.label} \xB7 ${section.seatCount.toLocaleString()} seats`
|
|
7880
|
-
})));
|
|
7881
|
-
fill(rowSelect, "2. Row", []);
|
|
7882
|
-
fill(seatSelect, "3. Seat", []);
|
|
7883
|
-
rowSelect.disabled = true;
|
|
7884
|
-
seatSelect.disabled = true;
|
|
7885
|
-
sectionSelect.addEventListener("change", () => {
|
|
7886
|
-
const sectionId = sectionSelect.value;
|
|
7887
|
-
view.disabled = true;
|
|
7888
|
-
fill(seatSelect, "3. Seat", []);
|
|
7889
|
-
seatSelect.disabled = true;
|
|
7890
|
-
if (!sectionId || !handle.focusSection(sectionId)) {
|
|
7891
|
-
fill(rowSelect, "2. Row", []);
|
|
7892
|
-
rowSelect.disabled = true;
|
|
7893
|
-
return;
|
|
7894
|
-
}
|
|
7895
|
-
const rows = handle.rows(sectionId);
|
|
7896
|
-
fill(rowSelect, "2. Row", rows.map((row) => ({
|
|
7897
|
-
id: row.id,
|
|
7898
|
-
label: `${row.label} \xB7 ${row.seatCount} seats`
|
|
7899
|
-
})));
|
|
7900
|
-
rowSelect.disabled = rows.length === 0;
|
|
7901
|
-
});
|
|
7902
|
-
rowSelect.addEventListener("change", () => {
|
|
7903
|
-
const rowId = rowSelect.value;
|
|
7904
|
-
view.disabled = true;
|
|
7905
|
-
if (!rowId || !handle.focusRow(rowId)) {
|
|
7906
|
-
fill(seatSelect, "3. Seat", []);
|
|
7907
|
-
seatSelect.disabled = true;
|
|
7908
|
-
return;
|
|
7909
|
-
}
|
|
7910
|
-
const seats = handle.seatsInRow(rowId);
|
|
7911
|
-
fill(seatSelect, "3. Seat", seats);
|
|
7912
|
-
seatSelect.disabled = seats.length === 0;
|
|
7913
|
-
});
|
|
7914
|
-
seatSelect.addEventListener("change", () => {
|
|
7915
|
-
const seatId = seatSelect.value;
|
|
7916
|
-
view.disabled = !seatId;
|
|
7917
|
-
});
|
|
7918
|
-
view.addEventListener("click", () => {
|
|
7919
|
-
const seatId = seatSelect.value;
|
|
7920
|
-
if (seatId) {
|
|
7921
|
-
setFinderOpen(false);
|
|
7922
|
-
this.onView3dSeatPick(seatId);
|
|
7923
|
-
}
|
|
7924
|
-
});
|
|
7925
|
-
locator.append(sectionSelect, rowSelect, seatSelect, view);
|
|
7926
|
-
nav.appendChild(locator);
|
|
7927
|
-
}
|
|
7928
8013
|
overlay.appendChild(nav);
|
|
7929
8014
|
}
|
|
7930
8015
|
async enter3d(flySeatId) {
|
|
@@ -7940,7 +8025,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7940
8025
|
const overlay = document.createElement("div");
|
|
7941
8026
|
overlay.className = "sl-view3d";
|
|
7942
8027
|
overlay.setAttribute("role", "group");
|
|
7943
|
-
overlay.setAttribute("aria-label", "Interactive 3D venue view");
|
|
8028
|
+
overlay.setAttribute("aria-label", this.tf("picker.interactive3dVenueView", "Interactive 3D venue view"));
|
|
7944
8029
|
const back = document.createElement("button");
|
|
7945
8030
|
back.type = "button";
|
|
7946
8031
|
back.className = "sl-view3d-back";
|
|
@@ -7966,7 +8051,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
7966
8051
|
fullscreen.type = "button";
|
|
7967
8052
|
fullscreen.className = "sl-view3d-fs";
|
|
7968
8053
|
fullscreen.textContent = "\u26F6";
|
|
7969
|
-
fullscreen.setAttribute("aria-label", "Full screen");
|
|
8054
|
+
fullscreen.setAttribute("aria-label", this.tf("picker.fullScreen", "Full screen"));
|
|
7970
8055
|
fullscreen.setAttribute("aria-pressed", String(!!document.fullscreenElement || this.fsFallback || this.framedFs));
|
|
7971
8056
|
fullscreen.addEventListener("click", () => this.toggleFullscreen());
|
|
7972
8057
|
overlay.appendChild(fullscreen);
|
|
@@ -8003,7 +8088,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
8003
8088
|
onSeatInspect: (id) => this.onView3dSeatPick(id),
|
|
8004
8089
|
onSectionFocusChange: (sectionId) => {
|
|
8005
8090
|
const select = overlay.querySelector(
|
|
8006
|
-
'select[
|
|
8091
|
+
'select[data-locator="section"]'
|
|
8007
8092
|
);
|
|
8008
8093
|
const next = sectionId ?? "";
|
|
8009
8094
|
if (!select || select.value === next) return;
|
|
@@ -8100,7 +8185,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
8100
8185
|
if (button) {
|
|
8101
8186
|
button.disabled = true;
|
|
8102
8187
|
button.classList.add("sl-busy");
|
|
8103
|
-
button.innerHTML =
|
|
8188
|
+
button.innerHTML = `<span class="sl-ba-spin" aria-hidden="true"></span>${this.tf("picker.findingEllipsis", "Finding\u2026")}`;
|
|
8104
8189
|
}
|
|
8105
8190
|
try {
|
|
8106
8191
|
const h = await this.controller.bestAvailable(qty, categoryKey, { ...opts, ttlMs: this.opts.holdTtlMs });
|
|
@@ -8122,7 +8207,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
8122
8207
|
} catch (err) {
|
|
8123
8208
|
this.opts.onError?.(err);
|
|
8124
8209
|
const reason = err?.reason;
|
|
8125
|
-
const message = reason === "not_enough_together" ?
|
|
8210
|
+
const message = reason === "not_enough_together" ? (0, import_core2.t)("picker.couldNotFindSeatsTogether", { count: qty }) : reason === "sold_out" ? this.tf("picker.ticketTypeSoldOut", "That ticket type is sold out. Try another ticket type.") : reason === "event_closed" ? this.tf("picker.seatSalesClosedForEvent", "Seat sales have closed for this event.") : this.tf("picker.seatsNoLongerAvailableTryAnother", "Those seats are no longer available. Try another quantity or ticket type.");
|
|
8126
8211
|
this.toast(message, "error");
|
|
8127
8212
|
return null;
|
|
8128
8213
|
} finally {
|
|
@@ -8151,7 +8236,7 @@ var SeatPicker = class _SeatPicker {
|
|
|
8151
8236
|
}
|
|
8152
8237
|
}
|
|
8153
8238
|
if (!released) {
|
|
8154
|
-
this.toast("Couldn't release your tickets. Your hold is unchanged.", "error");
|
|
8239
|
+
this.toast(this.tf("picker.couldNotReleaseTickets", "Couldn't release your tickets. Your hold is unchanged."), "error");
|
|
8155
8240
|
return;
|
|
8156
8241
|
}
|
|
8157
8242
|
this.hold = null;
|