@seatlayer/js 0.97.0 → 0.99.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/{channelsMode-BOkMjgGL.d.cts → channelsMode-Ca7DQPt-.d.cts} +55 -1
- package/dist/{channelsMode-BOkMjgGL.d.ts → channelsMode-Ca7DQPt-.d.ts} +55 -1
- package/dist/channelsMode-YLBLFLZZ.js +1 -0
- package/dist/{chunk-DR5JXWLO.js → chunk-LLK5GY5O.js} +2 -2
- package/dist/chunk-UBFNMA7U.js +1 -0
- package/dist/index.cjs +25 -21
- package/dist/index.d.cts +54 -2
- package/dist/index.d.ts +54 -2
- package/dist/index.js +24 -20
- package/dist/manager.cjs +102 -91
- package/dist/manager.d.cts +2 -2
- package/dist/manager.d.ts +2 -2
- package/dist/manager.js +29 -18
- package/package.json +2 -2
- package/dist/channelsMode-YJO6FOPD.js +0 -1
- package/dist/chunk-RZ2VKZ44.js +0 -1
package/dist/manager.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BucketRow } from './channelsMode-
|
|
2
|
-
export {
|
|
1
|
+
import { B as BucketRow } from './channelsMode-Ca7DQPt-.cjs';
|
|
2
|
+
export { ah as ACCESS_LINK_DEFAULTS, A as AccessIntentForbidsDetails, a as AccessLinkRecord, b as AccessLinkReveal, c as AccessLinkState, d as AccessLinkStatus, e as AccessLinkStatusRecord, f as ArchiveBlockedDetails, g as AssignmentBuckets, h as AssignmentDropDetails, i as AssignmentResult, C as ChannelAccessIntent, j as ChannelAccessSummary, k as ChannelAllocationPage, l as ChannelAttribution, m as ChannelAuditEntry, n as ChannelAuditPage, o as ChannelCounts, p as ChannelListResult, q as ChannelPreviewProjection, r as ChannelRecord, s as ChannelReport, t as ChannelReportLinkRecord, u as ChannelReportLinkReveal, v as ChannelReportResult, w as ChannelReportRow, x as ChannelSeatStatus, y as ChannelState, z as ChannelsCapabilities, D as ChannelsClient, E as ChannelsMode, F as ChannelsModeHost, G as ChannelsRowView, H as ChannelsSeatView, I as ControlRoomActivityEntry, J as ControlRoomSectionMetric, K as ControlRoomSnapshot, L as EventCategoryAssignmentResult, M as EventScopedManageToken, N as EventTableBookingMode, O as EventTableBookingResult, P as IntentSwitchBlockedDetails, Q as InventoryBooking, R as InventoryBookingActivity, S as InventoryBookingDetail, U as InventoryBookingObject, V as InventoryBookingState, W as InventoryBookingsPage, X as InventoryBookingsQuery, Y as LogEntry, Z as LogPage, _ as ManageApi, $ as ManageApiError, ai as PUBLIC_CHANNEL_ID, aj as PUBLIC_CHANNEL_NAME, a0 as ReportByStatus, a1 as ReportCategoryMeta, a2 as ReportCategoryRow, a3 as ReportResult, a4 as SeatManager, a5 as SeatManagerActionResult, a6 as SeatManagerActivity, a7 as SeatManagerArea, a8 as SeatManagerCapability, a9 as SeatManagerCategoryPrice, aa as SeatManagerConnection, ab as SeatManagerFilteredSection, ac as SeatManagerMode, ad as SeatManagerOptions, ae as SeatManagerSelectionValidity, af as SeatManagerTallies, ag as SelectionSourceRow, ak as accessIntentDescription, al as accessIntentLabel, am as accessLine, an as accessLinkBadge, ao as accessLinkErrorCopy, ap as accessLinkIsLive, aq as accessLinkPolicyLines, ar as bucketRows, as as dropReviewRows, at as intentForbidsCopy, au as intentSwitchBlockedCopy, av as isPublicChannelId, aw as markerLetter, ax as markerOf, ay as mutationCount, az as needsMoveConfirmation, aA as planAssignment, aB as retryAfterCopy, aC as selectionSources, aD as stateBadge, aE as suggestMarker } from './channelsMode-Ca7DQPt-.cjs';
|
|
3
3
|
export { ExpandedSeat, SeatHoverDetails } from '@seatlayer/core';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/manager.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BucketRow } from './channelsMode-
|
|
2
|
-
export {
|
|
1
|
+
import { B as BucketRow } from './channelsMode-Ca7DQPt-.js';
|
|
2
|
+
export { ah as ACCESS_LINK_DEFAULTS, A as AccessIntentForbidsDetails, a as AccessLinkRecord, b as AccessLinkReveal, c as AccessLinkState, d as AccessLinkStatus, e as AccessLinkStatusRecord, f as ArchiveBlockedDetails, g as AssignmentBuckets, h as AssignmentDropDetails, i as AssignmentResult, C as ChannelAccessIntent, j as ChannelAccessSummary, k as ChannelAllocationPage, l as ChannelAttribution, m as ChannelAuditEntry, n as ChannelAuditPage, o as ChannelCounts, p as ChannelListResult, q as ChannelPreviewProjection, r as ChannelRecord, s as ChannelReport, t as ChannelReportLinkRecord, u as ChannelReportLinkReveal, v as ChannelReportResult, w as ChannelReportRow, x as ChannelSeatStatus, y as ChannelState, z as ChannelsCapabilities, D as ChannelsClient, E as ChannelsMode, F as ChannelsModeHost, G as ChannelsRowView, H as ChannelsSeatView, I as ControlRoomActivityEntry, J as ControlRoomSectionMetric, K as ControlRoomSnapshot, L as EventCategoryAssignmentResult, M as EventScopedManageToken, N as EventTableBookingMode, O as EventTableBookingResult, P as IntentSwitchBlockedDetails, Q as InventoryBooking, R as InventoryBookingActivity, S as InventoryBookingDetail, U as InventoryBookingObject, V as InventoryBookingState, W as InventoryBookingsPage, X as InventoryBookingsQuery, Y as LogEntry, Z as LogPage, _ as ManageApi, $ as ManageApiError, ai as PUBLIC_CHANNEL_ID, aj as PUBLIC_CHANNEL_NAME, a0 as ReportByStatus, a1 as ReportCategoryMeta, a2 as ReportCategoryRow, a3 as ReportResult, a4 as SeatManager, a5 as SeatManagerActionResult, a6 as SeatManagerActivity, a7 as SeatManagerArea, a8 as SeatManagerCapability, a9 as SeatManagerCategoryPrice, aa as SeatManagerConnection, ab as SeatManagerFilteredSection, ac as SeatManagerMode, ad as SeatManagerOptions, ae as SeatManagerSelectionValidity, af as SeatManagerTallies, ag as SelectionSourceRow, ak as accessIntentDescription, al as accessIntentLabel, am as accessLine, an as accessLinkBadge, ao as accessLinkErrorCopy, ap as accessLinkIsLive, aq as accessLinkPolicyLines, ar as bucketRows, as as dropReviewRows, at as intentForbidsCopy, au as intentSwitchBlockedCopy, av as isPublicChannelId, aw as markerLetter, ax as markerOf, ay as mutationCount, az as needsMoveConfirmation, aA as planAssignment, aB as retryAfterCopy, aC as selectionSources, aD as stateBadge, aE as suggestMarker } from './channelsMode-Ca7DQPt-.js';
|
|
3
3
|
export { ExpandedSeat, SeatHoverDetails } from '@seatlayer/core';
|
|
4
4
|
|
|
5
5
|
/**
|
package/dist/manager.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{s as _,t as K}from"./chunk-URLBBOTJ.js";import{A as
|
|
1
|
+
import{s as _,t as K}from"./chunk-URLBBOTJ.js";import{A as De,B as Ve,C as je,D as qe,E as Ne,F as _e,G as Ke,H as Ue,I as We,J as Ge,K as Ze,L as Ye,M as Xe,N as Qe,O as Je,P as et,Q as tt,R as st,S as it,T as ot,V as at,a as L,b as U,c as k,d as O,e as W,f as G,g as Z,h as Y,i as F,j as M,k as x,l as X,m as Q,n as J,o as ee,p as te,q as T,r as m,s as P,t as se,u as D,v as ze,w as Ie,x as Oe,y as Fe,z as Pe}from"./chunk-LLK5GY5O.js";import{d as I,f as N}from"./chunk-UBFNMA7U.js";import"./chunk-OSZ7DOEH.js";var ie={hold:"Held",release:"Released",expire:"Expired",book:"Booked",unbook:"Cancelled",block:"Blocked",unblock:"Unblocked"},C=class{constructor(e,t){this.host=e;this.fetchPage=t;this.closed=!1;this.busy=!1;this.generation=0;this.entries=[];this.next=null;this.summary=document.createElement("div");this.list=document.createElement("div");this.message=document.createElement("div");this.older=document.createElement("button");this.latest=document.createElement("button");e.className="slm-seat-history",this.summary.className="slm-history-counts",this.list.className="slm-history-list",this.list.setAttribute("role","region"),this.list.setAttribute("aria-label","Seat history"),this.list.tabIndex=0,this.message.className="slm-note",this.message.setAttribute("role","status"),this.older.className=this.latest.className="slm-btn ghost",this.older.textContent="Load older",this.older.hidden=!0,this.latest.textContent="New activity \xB7 Show latest",this.latest.hidden=!0,this.older.onclick=()=>{this.load(!0)},this.latest.onclick=()=>{this.list.scrollTop=0,this.latest.hidden=!0,this.load()},e.append(this.summary,this.latest,this.list,this.message,this.older),this.load()}destroy(){this.closed=!0,this.generation++}refresh(){this.busy||this.load(!1,!0)}async load(e=!1,t=!1){if(this.closed||this.busy||e&&!this.next)return;this.busy=!0,this.older.disabled=!0;let s=this.generation;t||(this.message.textContent="Loading history\u2026");try{let i=await this.fetchPage(e?this.next:void 0,this.action);if(this.closed||s!==this.generation)return;if(this.paintCounts(i),t&&this.entries.length&&i.entries[0]?.id!==this.entries[0]?.id&&this.list.scrollTop>24){this.latest.hidden=!1;return}let o=!t||i.entries[0]?.id!==this.entries[0]?.id;e?(this.entries=[...this.entries,...i.entries.filter(a=>!this.entries.some(l=>l.id===a.id))],this.next=i.nextBefore):o&&(this.entries=i.entries,this.next=i.nextBefore),o&&this.paintRows(),this.older.hidden=this.next===null,this.message.textContent=this.entries.length?"":"No recorded activity for this seat."}catch{if(!this.closed){this.message.textContent="History could not be loaded. ";let i=document.createElement("button");i.className="slm-btn ghost",i.textContent="Retry",i.onclick=()=>{this.load(e)},this.message.append(i)}}finally{this.busy=!1,this.older.disabled=!1}}paintCounts(e){let t=[{action:"",count:e.total},...e.counts];this.summary.replaceChildren(...t.map(({action:s,count:i})=>{let o=document.createElement("button");return o.type="button",o.textContent=s?`${ie[s]??s} ${i}`:`${i} changes`,o.setAttribute("aria-pressed",String((this.action??"")===s)),o.onclick=()=>{this.busy||(this.action=s||void 0,this.entries=[],this.next=null,this.list.scrollTop=0,this.latest.hidden=!0,this.load())},o}))}paintRows(){let e=this.list.scrollTop;this.list.replaceChildren(...this.entries.map(t=>{let s=document.createElement("div");s.className="slm-history-row",s.dataset.action=t.action;let i=document.createElement("time");i.dateTime=new Date(t.at).toISOString(),i.textContent=new Date(t.at).toLocaleString(void 0,{year:"numeric",month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit"}),i.title=new Date(t.at).toString();let o=document.createElement("strong");return o.textContent=ie[t.action]??t.action,s.append(i,o),s})),this.list.scrollTop=e}};var lt={held:"HOLD",booked:"BOOK",expired:"EXPIRE",released:"RELEASE",cancelled:"CANCEL",blocked:"BLOCK",unblocked:"ON SALE",available:"FREE"},oe={held:"Held",booked:"Booked",expired:"Hold expired",released:"Hold released",cancelled:"Booking cancelled",blocked:"Blocked",unblocked:"Back on sale",available:"Available again"},E=class{constructor(e,t,s){this.host=e;this.locate=s;this.items=[];this.shown=new Set;this.paused=!1;this.limit=100;this.signature="unrendered";this.abort=new AbortController;e.innerHTML='<button class="slm-new-activity" hidden></button><div class="slm-activity-list" role="region" aria-label="Recent activity" tabindex="0"></div><button class="slm-more-activity" hidden>Show more activity</button>',this.list=e.querySelector(".slm-activity-list"),this.newer=e.querySelector(".slm-new-activity"),this.more=e.querySelector(".slm-more-activity");let i={signal:this.abort.signal},o=()=>{this.paused=!1,this.signature="unrendered",this.list.scrollTop=0,this.render()};this.list.addEventListener("scroll",()=>{this.list.scrollTop>24&&(this.paused=!0)},i),this.list.addEventListener("focusin",()=>{this.paused=!0},i),this.list.addEventListener("toggle",a=>{a.target.open&&(this.paused=!0)},{...i,capture:!0}),this.newer.addEventListener("click",o,i),this.more.addEventListener("click",()=>{this.limit=200,this.signature="unrendered",this.render(!0)},i)}update(e){this.items=e,this.render()}render(e=!1){let t=this.items,s=t.filter(a=>!this.shown.has(a.id)).length;if(this.newer.hidden=!this.paused,this.newer.textContent=s?`${s} new activit${s===1?"y":"ies"} \xB7 Back to live`:"Reading earlier activity \xB7 Back to live",this.paused&&!e)return;let i=t.slice(0,this.limit),o=i.map(a=>`${a.id}:${a.verb}`).join("|");if(o!==this.signature){if(this.signature=o,this.shown=new Set(t.map(a=>a.id)),this.list.replaceChildren(),!i.length){let a=document.createElement("p");a.className="slm-activity-empty",a.textContent=this.items.length?"No activity matches these filters.":"Waiting for activity. Holds, bookings and releases will appear here.",this.list.append(a)}for(let a of i){let l=document.createElement("article");l.className="slm-activity-entry",l.dataset.status=a.status;let r=document.createElement("button");r.type="button",r.className="slm-activity-row";let c=`${oe[a.verb]??a.verb} \xB7 ${a.count} seat${a.count===1?"":"s"} \xB7 ${a.sectionLabels?.join(", ")||"Event inventory"} \xB7 ${a.labels.join(", ")} \xB7 ${new Date(a.at).toLocaleString()}`;r.title=`${c} \u2014 click to show seats on the map`,r.setAttribute("aria-label",`Show seats on map: ${c}`),r.addEventListener("click",()=>this.locate(a.id));let d=document.createElement("time");d.dateTime=new Date(a.at).toISOString(),d.textContent=new Date(a.at).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});let h=document.createElement("strong");h.textContent=lt[a.verb]??a.verb,h.title=oe[a.verb]??a.verb;let p=document.createElement("span");if(p.className="slm-activity-seats",p.textContent=a.labels.join(", "),r.append(d,h,p),l.append(r),a.count>1){let u=document.createElement("details");u.className="slm-activity-details";let g=document.createElement("summary");g.textContent="\u22EF",g.setAttribute("aria-label",`Show all ${a.count} seats`);let f=document.createElement("p");f.textContent=c,u.append(g,f),l.append(u)}this.list.append(l)}this.more.hidden=t.length<=this.limit}}destroy(){this.abort.abort()}};var R=class{constructor(e){this.host=e;this.moving=!1;this.space=!1;this.monitor=!1;this.selected=0;this.abort=new AbortController;let t=document.createElement("div");t.className="slm-navigation";let s=b=>`<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${b}</svg>`,i=s('<path d="M8 13V6a2 2 0 0 1 4 0v6-8a2 2 0 0 1 4 0v8-6a2 2 0 0 1 4 0v10c0 4-3 6-7 6-3 0-5-2-7-5l-3-4a2 2 0 0 1 3-2l2 2Z"/>'),o=s('<path d="m5 3 14 10-7 1-3 7-4-18Z"/>'),a=s('<circle cx="10.5" cy="10.5" r="6.5"/><path d="m16 16 5 5"/>'),l=s('<path d="M7 6h10M12 1v10M7 18h10"/>'),r=s('<rect x="3" y="4" width="18" height="16" rx="2"/><path d="M15 4v16"/>');t.innerHTML=`<div class="slm-navigation-tools" role="group" aria-label="Map navigation">
|
|
2
2
|
<button type="button" data-nav="move" aria-label="Move" aria-pressed="false" title="Drag to move the map; hold Space temporarily">${i}</button>
|
|
3
3
|
<button type="button" data-nav="select" aria-label="Select" aria-pressed="true" title="Drag to select seats \xB7 drag empty floor to move">${o}</button>
|
|
4
4
|
<button type="button" data-nav="search" aria-label="Search" title="Search seats, rows or sections" aria-expanded="false">${a}</button>
|
|
@@ -415,12 +415,23 @@ import{s as _,t as K}from"./chunk-URLBBOTJ.js";import{A as Ve,B as Pe,C as je,D
|
|
|
415
415
|
.slm-find-count{display:block;min-height:16px;margin-top:4px;font-size:11px;color:var(--slm-muted);font-variant-numeric:tabular-nums}
|
|
416
416
|
.slm-find-count:empty{display:none}
|
|
417
417
|
/* Reading aids in the bar (plan item 5, slice D): the bar's Find and the View menu. */
|
|
418
|
-
.slm-findbar{flex:0 1 250px;min-width:120px}
|
|
419
|
-
|
|
420
|
-
|
|
418
|
+
.slm-findbar{flex:0 1 250px;min-width:120px;max-width:250px}
|
|
419
|
+
/* The bar's box draws the frame, and the count sits inside it at the end of
|
|
420
|
+
the input \u2014 in the layout, so it never covers the controls or KPIs below.
|
|
421
|
+
The count may take the box's room but never demands it: clamped to one
|
|
422
|
+
line (not nowrap), its narrowest size is a word, so a crowded bar shrinks
|
|
423
|
+
it to "\u2026" rather than overflowing. Its title carries the whole sentence. */
|
|
424
|
+
.slm-findbar .slm-find{margin:0;display:flex;align-items:center;gap:6px;box-sizing:border-box;min-height:30px;padding:0 6px 0 0;
|
|
425
|
+
border:1px solid var(--slm-line);border-radius:8px;background:var(--slm-surface)}
|
|
426
|
+
.slm-findbar .slm-find:focus-within{outline:2px solid var(--slm-accent);outline-offset:1px;border-color:var(--slm-accent)}
|
|
427
|
+
.slm-findbar .slm-find .slm-input{flex:1 1 0;width:0;min-width:56px;min-height:28px;padding:4px 4px 4px 30px;border:0;border-radius:8px;
|
|
428
|
+
background:transparent;font-size:12px}
|
|
429
|
+
.slm-findbar .slm-find .slm-input:focus-visible{outline:none}
|
|
421
430
|
.slm-findbar .slm-find::before{left:10px;width:12px;height:12px}
|
|
422
|
-
.slm-findbar .slm-find-count{
|
|
423
|
-
|
|
431
|
+
.slm-findbar .slm-find-count{flex:0 1 auto;min-width:0;max-width:70%;min-height:0;margin:0;padding:2px 7px;border-radius:6px;
|
|
432
|
+
overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1;line-clamp:1;overflow-wrap:anywhere;
|
|
433
|
+
line-height:16px;background:var(--slm-tint);color:var(--slm-text);font-size:11px}
|
|
434
|
+
.slm-findbar .slm-find-count:empty{display:none}
|
|
424
435
|
.slm-view{position:relative;flex:none}
|
|
425
436
|
.slm-view > summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;min-height:30px;padding:5px 10px;border-radius:8px;font-size:12px;user-select:none}
|
|
426
437
|
.slm-view > summary::-webkit-details-marker{display:none}
|
|
@@ -441,7 +452,7 @@ import{s as _,t as K}from"./chunk-URLBBOTJ.js";import{A as Ve,B as Pe,C as je,D
|
|
|
441
452
|
.slm-view-label{flex:1;min-width:0}
|
|
442
453
|
.slm-view-kbd{flex:none;font:600 10.5px/1 var(--slm-mono,ui-monospace,monospace);color:var(--slm-muted);padding:3px 5px;border:1px solid var(--slm-line);border-radius:5px}
|
|
443
454
|
.slm-view-note{margin:4px 3px 2px;padding:6px 8px 2px;border-top:1px solid var(--slm-line);font-size:11px;line-height:1.4;color:var(--slm-muted)}
|
|
444
|
-
.slm.compact .slm-findbar{flex:1 1 100%;min-width:0}
|
|
455
|
+
.slm.compact .slm-findbar{flex:1 1 100%;min-width:0;max-width:none}
|
|
445
456
|
.slm-selnum{font-size:26px;font-weight:800;font-variant-numeric:tabular-nums}
|
|
446
457
|
.slm-sellabel{font-size:12px;color:var(--slm-muted);font-weight:600}
|
|
447
458
|
.slm-row{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
|
|
@@ -693,7 +704,7 @@ import{s as _,t as K}from"./chunk-URLBBOTJ.js";import{A as Ve,B as Pe,C as je,D
|
|
|
693
704
|
</button>`).join("")}
|
|
694
705
|
<div class="slm-view-note" data-ref="viewnote" hidden></div>
|
|
695
706
|
</div>
|
|
696
|
-
</details>`}function Te(n,e,t){let s=$(),i=!1;n.querySelectorAll("[data-view]").forEach(l=>{let r=l.dataset.view,c=e[r];l.setAttribute("aria-checked",String(c)),l.classList.toggle("on",c);let d=r==="channelColours"&&!t.channelColoursAvailable;l.disabled=d,l.setAttribute("aria-disabled",String(d)),!d&&c!==s[r]&&(i=!0)}),n.querySelector("summary")?.classList.toggle("away",i);let a=n.querySelector('[data-ref="viewnote"]');if(a){let l=[];t.channelColoursAvailable||l.push("Channel colours: open the Channels tool."),t.momentumLoading&&l.push("Booking momentum: loading the first snapshot\u2026"),a.hidden=!l.length,a.textContent=l.join(" ")}}import{UNGROUPED_ID as bt}from"@seatlayer/core";function
|
|
707
|
+
</details>`}function Te(n,e,t){let s=$(),i=!1;n.querySelectorAll("[data-view]").forEach(l=>{let r=l.dataset.view,c=e[r];l.setAttribute("aria-checked",String(c)),l.classList.toggle("on",c);let d=r==="channelColours"&&!t.channelColoursAvailable;l.disabled=d,l.setAttribute("aria-disabled",String(d)),!d&&c!==s[r]&&(i=!0)}),n.querySelector("summary")?.classList.toggle("away",i);let a=n.querySelector('[data-ref="viewnote"]');if(a){let l=[];t.channelColoursAvailable||l.push("Channel colours: open the Channels tool."),t.momentumLoading&&l.push("Booking momentum: loading the first snapshot\u2026"),a.hidden=!l.length,a.textContent=l.join(" ")}}import{UNGROUPED_ID as bt}from"@seatlayer/core";function V(n){return Object.entries(n).filter(([,e])=>e.mode==="closed").map(([e])=>e)}function H(n){let e=n.sectionsBase;if(!e)return{rows:[],hiddenSections:0,closedSections:0};let t=n.doc?.zones??[],s=new Map,i=[];for(let c of e.sections)if(c.zone&&t.some(d=>d.id===c.zone)){let d=s.get(c.zone)??[];d.push(c),s.set(c.zone,d)}else i.push(c);let o=[],a=0,l=0,r=(c,d,h,p=!1)=>{let u=n.availabilityRules[d.id]??null,g=n.effectiveClosed.has(d.id)||p,f=n.effectiveHidden.has(d.id)||h&&!g;c==="section"&&f&&(a+=1),c==="section"&&g&&(l+=1),o.push({kind:c,id:d.id,label:d.label,seatCount:d.seatCount,seatLabels:d.seatLabels,rule:u,hidden:f,closed:g,followsZone:c==="section"&&h})};for(let c of t){let d=s.get(c.id);if(!d||!d.length)continue;let h={id:c.id,label:c.label||"Zone",seatCount:d.reduce((g,f)=>g+f.seatCount,0),seatLabels:d.flatMap(g=>g.seatLabels)},p=!!n.availabilityRules[c.id],u=n.availabilityRules[c.id]?.mode==="closed";r("zone",h,!1);for(let g of d)r("section",g,p,u)}for(let c of i)r("section",c,!1);if(e.ungrouped){let c=e.ungrouped;r("section",{id:bt,label:c.label,seatCount:c.seatCount,seatLabels:c.seatLabels},!1)}return{rows:o,hiddenSections:a,closedSections:l}}function Ce(n,e){let t=W(n.rule),s=`slm-availrow${n.kind==="zone"?" zone":""}${n.hidden?" hidden":""}${n.closed?" closed":""}`,i=e?" disabled":"",o=[["open","Open","Available to buy"],["closed","Closed","Visible on the map, unavailable to buy"],["hidden","Hidden","Removed from the buyer map"],["timed","Scheduled reveal","Open at a specific date and time"],["threshold","Demand-based reveal","Open when sales reach a percentage"]],a=n.followsZone?'<span class="slm-availfollows">Follows zone</span>':`<details class="slm-availpicker" data-avail-picker>
|
|
697
708
|
<summary aria-label="Availability for ${m(n.label)}" ${e?'aria-disabled="true"':""}>${o.find(d=>d[0]===t)[1]}<span aria-hidden="true">\u2304</span></summary>
|
|
698
709
|
<div class="slm-availchoices" aria-label="Availability options for ${m(n.label)}">
|
|
699
710
|
${o.map(([d,h,p])=>`<button type="button" data-avail-id="${m(n.id)}" data-avail-value="${d}" aria-pressed="${t===d}"${i}><span><b>${h}</b><small>${p}</small></span><span aria-hidden="true">${t===d?"\u2713":""}</span></button>`).join("")}
|
|
@@ -712,16 +723,16 @@ import{s as _,t as K}from"./chunk-URLBBOTJ.js";import{A as Ve,B as Pe,C as je,D
|
|
|
712
723
|
</div>
|
|
713
724
|
${a}
|
|
714
725
|
${l}
|
|
715
|
-
</div>`}var Lt="https://api.seatlayer.io",H=200,Ae=16,$e=4,He=[{key:"watch",label:"Watch",tools:[{mode:"view",label:"Monitor",shortcut:"M",title:"Live board \u2014 inventory, activity and booking momentum. Read-only."},{mode:"inspect",label:"Inspect",shortcut:"I",title:"Click one seat to read its live status and booking context. Read-only."}]},{key:"manage",label:"Manage",tools:[{mode:"block",label:"Block",shortcut:"B",title:"Take seats off sale for this event, or put them back."},{mode:"sections",label:"Sections",shortcut:"S",title:"Open, close or hide sections for this event, on a schedule or on demand."},{mode:"categories",label:"Categories",shortcut:"G",title:"Move seats to a different price category for this event only."},{mode:"tables",label:"Tables",shortcut:"T",title:"Sell each table per chair or as one whole-table booking."},{mode:"channels",label:"Channels",shortcut:"C",title:"Allocate inventory to sales channels and share their links."}]},{key:"host",label:"Host tools",tools:[{mode:"select",label:"Select",shortcut:"X",title:"Select seats for your own back-office operation. The selection is handed to your app; nothing changes here."},{mode:"filterSections",label:"Filter",shortcut:"L",title:"Filter the map to one section for your own reporting."}]}],Mt=3;function Tt(n){let e=n?.status;return e===401||e===403}var Be=n=>`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${n}</svg>`,j={enter:Be('<path d="M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5"/>'),exit:Be('<path d="M9 4v5H4M20 9h-5V4M15 20v-5h5M4 15h5v5"/>')},Ct=Object.fromEntries(He.flatMap(n=>n.tools.map(e=>[e.shortcut.toLowerCase(),e.mode]))),q=class{constructor(e){this.els={};this.renderer=null;this.doc=null;this.selectObserver=null;this.seatHistoryPanel=null;this.activityPanel=null;this.navigation=null;this.movingMap=!1;this.marqueeShape="box";this.socketSnapshotSeen=!1;this.monitorRefreshTimer=null;this.themeMode=null;this.colorSchemeStop=null;this.inventoryModelVersion=1;this.selectableObjectLabels=new Set;this.lastSelectionLabels=new Set;this.selectionWasValid=null;this.initialSelectionApplied=!1;this.labelToId=new Map;this.labelToSeat=new Map;this.allIds=[];this.gaUnitLabelSet=new Set;this.tableChairIds=new Map;this.status=new Map;this.counts={held:0,booked:0,blocked:0};this.modelVersion=0;this.currency="USD";this.authoritativeCurrency=null;this.authoritativeGrossRevenue=0;this.revenueStatus="loading";this.revenueRequest=0;this.controlRoomSnapshot=null;this.serverBaseline=null;this.livePresence=null;this.liveGross=null;this.paintHandle=null;this.trendWindowMinutes=15;this.heatEnabled=!1;this.mapView=$();this.barFind=null;this.minimap=null;this.lastKpiValues=new Map;this.activeKpiDeltas=new Map;this.ws=null;this.reconnectTimer=null;this.attempt=0;this.closed=!1;this.connectionStatus="reconnecting";this.lastMessageAt=null;this.ready=!1;this.feed=[];this.feedTimer=null;this.toastTimer=null;this.liveEventTimer=null;this.kpiCleanupTimer=null;this.followLiveTimer=null;this.followSeatTimer=null;this.releaseAt=null;this.layoutObserver=null;this.chromeClearance=-1;this.chromeClearanceWidth=-1;this.tokenExpiresAt=null;this.tokenRefreshTimer=null;this.tokenRefreshInFlight=!1;this.tokenRefreshFailures=0;this.sessionEnded=!1;this.sectionByObject=new Map;this.sectionLabelById=new Map;this.sectionsBase=null;this.filteredSectionLabel=null;this.availabilityRules={};this.effectiveHidden=new Set;this.effectiveClosed=new Set;this.availabilitySaving=!1;this.lastSyncedAt=null;this.blockBrowse=!1;this.blockedQuery="";this.blockedSection="";this.blockedResultLimit=100;this.unblockAllConfirmTimer=null;this.channels=null;this.chooser=null;this.chooserDialog=null;this.categoryDifferences=null;this.channelCaps={view:!1,manage:!1};this.categoryCanManage=!1;this.tableCanManage=!1;this.tableBookingSaving=!1;this.channelCapabilityResolution=0;this.channelsLoading=null;this.onFullscreenChange=()=>{this.paintFullscreenButton(),this.updateContainerLayout(),this.renderer?.forceDraw()};this.onKeyDown=e=>{if(e.metaKey||e.ctrlKey||e.altKey||e.target?.matches('input,select,textarea,[contenteditable="true"]'))return;let s=e.key.toLowerCase(),i=e.shiftKey?xe(s):null;if(i){this.toggleMapView(i),e.preventDefault();return}if(s==="/"){let a=this.els.findbar?.querySelector("[data-ch-find-input]");a&&(a.focus(),a.select(),e.preventDefault());return}let o=Ct[s];if(o){if(!this.toolAvailable(o))return;this.setMode(o)}else if(s==="f")this.toggleFullscreen();else if(s==="escape"){let a=this.els.view;if(a?.open)a.open=!1,a.querySelector("summary")?.focus();else if(!this.channels?.handleBack())if(this.getSelection().length)this.clearSelection();else return}else return;e.preventDefault()};this.onRailClick=e=>{let t=e.target,s=t?.closest("[data-section-focus]");if(s?.dataset.sectionFocus){this.locateSection(s.dataset.sectionFocus);return}let i=t?.closest("[data-feed-id]");i?.dataset.feedId&&this.locateActivity(i.dataset.feedId)};this.typeKeyBySection=null;this.typeKeyBase=null;this.sectionOptions=[];O(e.token),this.assertSelectionOptions(e.maxSelectedObjects,e.numberOfPlacesToSelect),this.opts=e,this.key=e.eventKey,this.mode=e.mode??"view",this.selectableObjectLabels=new Set(e.selectableObjects??[]),this.categoryCanManage=new Set(e.capabilities??[]).has("event:categories:manage"),this.tableCanManage=new Set(e.capabilities??[]).has("event:tables:manage"),this.keepLive=e.keepLiveWhileHidden??!0,this.themeMode=e.themeMode??null,this.followLive=e.followLive??!1,this.currency=e.currency??"USD",this.tokenExpiresAt=e.tokenExpiresAt??null,this.api=new F(e.apiBase??Lt,e.token),this.organizerAssetUrls=new A(this.key,(t,s)=>this.withAuthRetry(()=>this.api.asset(t,s))),this.host=Y(e.container)}assertSelectionOptions(e,t){let s=i=>i===void 0||Number.isInteger(i)&&i>0;if(!s(e))throw new TypeError("maxSelectedObjects must be a positive integer");if(!s(t))throw new TypeError("numberOfPlacesToSelect must be a positive integer");if(e!==void 0&&t!==void 0&&e<t)throw new TypeError("maxSelectedObjects cannot be lower than numberOfPlacesToSelect")}async render(){ce(),this.buildChrome();try{let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1,this.doc=await this.organizerAssetUrls.prepareRendererChart(e.doc),this.authoritativeCurrency=e.event.currency??null,this.currency=this.authoritativeCurrency??this.opts.currency??this.currency,this.buildUnitUniverse(this.doc),this.buildRenderer(),this.buildSectionOptions(),this.settleMode();let[,t]=await Promise.all([this.resnapshot(),this.refreshControlRoom().catch(s=>this.opts.onError?.(s)),this.refreshAvailability()]);t?.activity?this.seedFeed(t.activity):this.api.log(this.key,{limit:24}).then(s=>this.seedFeed(s.entries)).catch(()=>{}),this.connect(),this.startFeedClock(),this.ready=!0,await this.resolveChannelCapabilities(),this.setMode(this.mode),this.applyInitialSelection(),this.scheduleTokenRefresh(),this.opts.onReady?.()}catch(e){this.fail(e)}return this}setMode(e){this.toolAvailable(e)||(e="view"),e==="channels"&&!this.channels&&this.ensureChannels();let t=e!==this.mode,s=this.mode==="channels",i=this.mode==="filterSections";this.mode=e,t&&e!=="view"&&this.setFollowLive(!1),!this.renderer&&this.doc?this.buildRenderer():this.updateRendererInteraction(),t&&(this.renderer?.clearSelection(),this.syncSelection()),s&&e!=="channels"&&this.channels?.leave(),t&&(this.highlightLabels(null),this.wireBarFind()),this.paintModeTabs(),this.paintRail(),this.paintMapViewMenu(),this.applyMapView(),this.applySectionCanvasTreatment(),i&&e!=="filterSections"&&this.renderer?.zoomToFit(),e==="channels"&&this.channels?.enter(),e==="select"&&this.applyInitialSelection(),t&&this.opts.onModeChange?.(e)}async resolveChannelCapabilities(){let e=++this.channelCapabilityResolution,t=this.opts.capabilities,s;if(t){let i=new Set(t);s={view:i.has("event:channels:view"),manage:i.has("event:channels:view")&&i.has("event:channels:manage")}}else s={view:!1,manage:!1};if(!s.view&&!t)try{await this.api.channels(this.key),s={view:!0,manage:!1}}catch{s={view:!1,manage:!1}}if(e===this.channelCapabilityResolution){if(this.channelCaps=s,!this.channelCaps.view){this.channels?.destroy(),this.channels=null,this.mode==="channels"?this.setMode("view"):this.paintModeTabs();return}this.channels?.setCapabilities(this.channelCaps),this.paintModeTabs()}}ensureChannels(){if(this.channelsLoading)return this.channelsLoading;if(this.channels)return Promise.resolve();let e=(async()=>{try{let t=await import("./channelsMode-YJO6FOPD.js");if(this.closed||!this.channelCaps.view||(this.channels||(de(t.CHANNELS_CSS),this.channels=new t.ChannelsMode(this.buildChannelsHost(),this.channelCaps),this.channels.onInteractionChange=()=>this.updateRendererInteraction()),this.mode!=="channels"))return;this.updateRendererInteraction(),this.paintRail(),this.channels.enter(),this.applyMapView(),this.paintMapViewMenu()}catch(t){if(this.closed)return;this.channelsLoading=null,this.mode==="channels"&&this.paintRail(),this.opts.onError?.(t)}})();return this.channelsLoading=e,e}buildChooserHost(){let e=s=>{let i=this.labelToSeat.get(s);return i?this.mode==="block"?this.isBlockSelectable(s):this.mode==="select"?this.canSelectObject(i):!0:!1};return{selectionLabels:()=>this.selectionLabels(),selectByLabels:s=>{this.selectByLabels(s)},clearSelection:()=>this.clearSelection(),selectSection:s=>{this.selectSection(s)},sections:()=>this.sectionOptions,labelsInSection:s=>(this.renderer?.getSelectableInSection(s)??[]).map(i=>i.label).filter(e),rows:()=>{let s=new Map((this.doc?.objects??[]).map(o=>[o.id,o])),i=new Map;for(let o of this.labelToSeat.values()){if(!e(o.label))continue;let a=s.get(o.rowId);if(!a||a.type!=="row"&&a.type!=="table")continue;let l=o.logicalRowId??o.rowId,r=this.sectionByObject.get(o.rowId)??v,c=i.get(l)??{id:l,label:a.type==="row"?a.segmentedRow?.displayLabel??a.displayLabel??a.label:a.displayLabel??a.label,sectionId:r,sectionLabel:this.sectionLabelById.get(r)??"Other seats",labels:[]};c.labels.push(o.label),i.set(l,c)}return[...i.values()].sort((o,a)=>o.sectionLabel.localeCompare(a.sectionLabel,void 0,{numeric:!0,sensitivity:"base"})||o.label.localeCompare(a.label,void 0,{numeric:!0,sensitivity:"base"}))},categories:()=>(this.doc?.categories??[]).map(s=>({key:s.key,label:s.label??s.key,color:s.color})),labelsInCategory:s=>[...this.labelToSeat.values()].filter(i=>i.categoryKey===s&&e(i.label)).map(i=>i.label),seats:()=>[...this.labelToSeat.values()].filter(s=>e(s.label)).map(s=>({label:s.label})),statusOf:s=>this.status.get(s)??(this.labelToSeat.has(s)?"free":void 0),sectionOfLabel:s=>{let i=this.labelToSeat.get(s);if(!i)return null;let o=this.sectionByObject.get(i.rowId)??v;return{id:o,label:this.sectionLabelById.get(o)??"Other seats"}},openDialog:(s,i)=>{this.chooserDialog=ae(this.root,s,i,{previous:this.chooserDialog,onClose:()=>{this.chooserDialog=null}})},closeDialog:()=>this.chooserDialog?.close(),highlight:s=>this.highlightLabels(s),...this.mode==="select"?{cap:this.selectionCap()}:{}}}wireBarFind(){let e=this.els.findbar;e&&(e.innerHTML=D({compact:!0}),this.barFind=new V({...this.buildChooserHost(),seats:()=>[...this.labelToSeat.values()].map(t=>({label:t.label})),frame:t=>this.frameLabels(t)}),this.barFind.wireFind(e,{enter:this.isChoosingTool()?"select":"frame"}))}isChoosingTool(){return this.isBulkSelectMode()||this.mode==="select"}frameLabels(e){let t=e.map(s=>this.labelToSeat.get(s)?.id).filter(s=>!!s);t.length&&(this.setFollowLive(!1),this.renderer?.focusSeats?.(t,{animate:!0}))}highlightLabels(e){if(!e){this.renderer?.setSeatHighlight?.(null);return}this.renderer?.setSeatHighlight?.(e.map(t=>this.labelToSeat.get(t)?.id).filter(t=>!!t))}toolChooser(){return this.chooserDialog?.close({restoreFocus:!1}),this.chooser=new V(this.buildChooserHost()),this.chooser}toolSelectionBar(e,t,s,i){return se({count:0,noun:"selected",breakdown:`<span class="slm-selactions"><button type="button" class="slm-linkbtn" data-ref="${i}">Select all</button></span>`,clearAttr:`data-ref="${s}"`}).replace('class="slm-selnum"',`class="slm-selnum" data-ref="${e}"`).replace('class="slm-sellabel"',`class="slm-sellabel" data-ref="${t}"`)}buildChannelsHost(){return{eventKey:this.key,api:this.api,rail:this.els.rail,mapLayer:this.root.querySelector(".slm-map"),pillLane:this.els.lane,root:this.root,seats:()=>[...this.labelToSeat.values()].map(e=>({id:e.id,label:e.label,x:e.x,y:e.y})),statusOf:e=>this.status.get(e)??(this.labelToSeat.has(e)?"free":void 0),selectionLabels:()=>this.selectionLabels(),selectByLabels:e=>{this.selectByLabels(e)},clearSelection:()=>this.clearSelection(),selectSection:e=>{this.selectSection(e)},sections:()=>this.sectionOptions,labelsInSection:e=>this.renderer?.getSelectableInSection(e).map(t=>t.label)??[],rows:()=>{let e=new Map((this.doc?.objects??[]).map(s=>[s.id,s])),t=new Map;for(let s of this.labelToSeat.values()){let i=e.get(s.rowId);if(!i||i.type!=="row"&&i.type!=="table")continue;let o=s.logicalRowId??s.rowId,a=this.sectionByObject.get(s.rowId)??v,l=t.get(o)??{id:o,label:i.type==="row"?i.segmentedRow?.displayLabel??i.displayLabel??i.label:i.displayLabel??i.label,sectionId:a,sectionLabel:this.sectionLabelById.get(a)??"Other seats",labels:[]};l.labels.push(s.label),t.set(o,l)}return[...t.values()].sort((s,i)=>s.sectionLabel.localeCompare(i.sectionLabel,void 0,{numeric:!0,sensitivity:"base"})||s.label.localeCompare(i.label,void 0,{numeric:!0,sensitivity:"base"}))},categories:()=>(this.doc?.categories??[]).map(e=>({key:e.key,label:e.label??e.key,color:e.color,price:e.price,tiers:e.tiers?.map(t=>({id:t.id,name:t.name,price:t.price}))})),labelsInCategory:e=>[...this.labelToSeat.entries()].filter(([,t])=>t.categoryKey===e).map(([t])=>t),sectionOfLabel:e=>{let t=this.labelToSeat.get(e);if(!t)return null;let s=this.sectionByObject.get(t.rowId)??v;return{id:s,label:this.sectionLabelById.get(s)??"Other seats"}},worldToScreen:e=>this.renderer?.worldToScreen(e)??null,seatPixelSize:()=>this.seatPixelSize(),isSeatDetail:()=>this.renderer?.getRung?.()==="seats",showSectionOverview:()=>{this.renderer?.clearSectionFocus(),this.renderer?.setRung?.("sections")},focusSection:e=>this.renderer?.focusSection(e),isCompact:()=>!!this.root?.classList.contains("compact"),setMapInert:e=>{this.mapHost.toggleAttribute("inert",e),this.mapHost.setAttribute("aria-hidden",String(e))},toast:(e,t)=>this.toast(e,t),onError:e=>this.opts.onError?.(e)}}seatPixelSize(){let e=this.renderer?.getVisibleWorldRect?.(),t=this.mapHost?.clientWidth??0;return!e?.width||!t?6:Math.max(3,t/e.width*18)}setHeatOverlay(e){this.heatEnabled=e,this.mapView.momentum!==e&&this.setMapView({momentum:e}),this.applyHeatOverlay(),this.paintHeatButton()}setMapView(e){let t={...this.mapView,...e};if(!Object.keys(t).some(o=>t[o]!==this.mapView[o]))return;let i=t.categoryColours!==this.mapView.categoryColours;this.mapView=t,ke(t),t.momentum!==this.heatEnabled&&this.setHeatOverlay(t.momentum),this.applyMapView(),this.paintMapViewMenu(),i&&(this.refreshBlockPaint(),this.paintMapChrome())}getColourBy(){return this.mapView.categoryColours?"type":"full"}setColourBy(e){this.setMapView({categoryColours:e==="type"})}getMapView(){return{...this.mapView}}toggleMapView(e){e==="channelColours"&&!this.channelColoursAvailable()||this.setMapView({[e]:!this.mapView[e]})}channelColoursAvailable(){return this.mode==="channels"&&this.channels!=null}applyMapView(){Le(this.mapView,{renderer:this.renderer,channelsOverlay:e=>this.channels?.setOverlayVisible(e)})}paintMapViewMenu(){let e=this.els.view;e&&Te(e,this.mapView,{channelColoursAvailable:this.channelColoursAvailable(),momentumLoading:this.mapView.momentum&&!this.controlRoomSnapshot})}setFollowLive(e){let t=this.followLive!==e;this.followLive=e,e||(this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=null,this.followSeatTimer=null),this.paintFollowLiveButton(),t&&this.opts.onFollowLiveChange?.(e)}setKeepLiveWhileHidden(e){this.keepLive=e??!0,this.opts.keepLiveWhileHidden=e}setCurrency(e){this.opts.currency=e,!this.authoritativeCurrency&&(this.currency=e??"USD",this.ready&&this.recomputeTallies())}setTheme(e){this.opts.theme=e,this.applyThemeVars()}applyThemeVars(){if(!this.root)return;let e=I(this.themeMode);for(let[t,s]of Object.entries(J(this.opts.theme,e)))this.root.style.setProperty(t,s);e?this.root.dataset.theme=e:delete this.root.dataset.theme}watchThemeMode(){this.colorSchemeStop?.(),this.colorSchemeStop=null,this.themeMode==="auto"&&(this.colorSchemeStop=N(()=>{this.closed||this.repaintForThemeMode()}))}repaintForThemeMode(){this.applyThemeVars();let e=this.renderer;if(!e||!this.doc)return;let t=e.getSelection().map(o=>o.id),s=e.getCameraPose(),i=e.getFocusedSection();e.setChart(this.themedDoc()),this.repaintAll(),this.applyHeatOverlay(),t.length&&e.select(t),i&&e.focusSection(i),e.setCameraPose(s),this.updateZoomHint()}setThemeMode(e){let t=e??null;this.closed||t===this.themeMode||(this.themeMode=t,this.opts.themeMode=t??void 0,this.watchThemeMode(),this.repaintForThemeMode())}getThemeMode(){return this.themeMode}themedDoc(){let e=this.doc,t=ee(I(this.themeMode));return t?{...e,theme:{...e.theme??{},background:t}}:e}setCapabilities(e){this.opts.capabilities=e,this.categoryCanManage=new Set(e??[]).has("event:categories:manage"),this.tableCanManage=new Set(e??[]).has("event:tables:manage"),!this.categoryCanManage&&this.mode==="categories"||!this.tableCanManage&&this.mode==="tables"?this.setMode("view"):this.paintModeTabs(),this.ready&&this.resolveChannelCapabilities()}setTokenRefresh(e){this.opts.onTokenRefresh=e,this.scheduleTokenRefresh()}setTrendWindow(e){let t=Number.isFinite(e)?Math.floor(e):15;return this.trendWindowMinutes=Math.max(5,Math.min(60,t)),this.paintTrendWindow(),this.refreshControlRoom()}async enterFullscreen(){!this.root?.requestFullscreen||this.isFullscreen()||(await this.root.requestFullscreen(),this.root.focus({preventScroll:!0}))}async exitFullscreen(){typeof document>"u"||!this.isFullscreen()||await document.exitFullscreen()}isFullscreen(){return typeof document<"u"&&document.fullscreenElement===this.root}toggleFullscreen(){(this.isFullscreen()?this.exitFullscreen():this.enterFullscreen()).catch(t=>this.opts.onError?.(t))}setToken(e,t){O(e),this.api.setToken(e),this.opts.token=e,this.opts.tokenExpiresAt=t,this.tokenExpiresAt=t??null,this.scheduleTokenRefresh(),this.ready&&this.resolveChannelCapabilities()}scheduleTokenRefresh(){this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.tokenRefreshTimer=null;let e=this.opts.onTokenRefresh,t=this.tokenExpiresAt;if(this.closed||!e||!t||!Number.isFinite(t))return;let s=t-Date.now(),i=Math.min(12e4,Math.max(3e4,s*.2)),o=Math.max(0,s-i);this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},o)}async rotateToken(){if(!(this.closed||this.sessionEnded||this.tokenRefreshInFlight||!this.opts.onTokenRefresh)){this.tokenRefreshInFlight=!0;try{let e=await this.opts.onTokenRefresh();if(!e?.token||!Number.isFinite(e.expiresAt))throw new Error("invalid_token_refresh_result");this.tokenRefreshFailures=0,this.setToken(e.token,e.expiresAt)}catch(e){this.opts.onError?.(e),this.tokenRefreshFailures+=1,!this.closed&&(this.tokenRefreshFailures>=Mt||Tt(e))?this.endSession():this.closed||(this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},3e4))}finally{this.tokenRefreshInFlight=!1}}}endSession(){if(this.sessionEnded)return;this.sessionEnded=!0,this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.tokenRefreshTimer=null,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.monitorRefreshTimer&&clearTimeout(this.monitorRefreshTimer),this.monitorRefreshTimer=null;let e=this.ws;if(this.ws=null,e){e.onclose=null;try{e.close()}catch{}}this.setLive(!1),this.paintSessionEnded()}async retrySession(){if(this.closed||!this.sessionEnded)return!this.sessionEnded;if(!this.opts.onTokenRefresh)return!1;this.sessionEnded=!1,this.tokenRefreshFailures=0;let e=this.root?.querySelector('[data-ref="ended"]');return e?.setAttribute("data-busy","true"),await this.rotateToken(),this.sessionEnded?(e?.removeAttribute("data-busy"),!1):(e?.remove(),this.attempt=0,this.connect(),!0)}paintSessionEnded(){let e=this.els.lane;if(!e||e.querySelector('[data-ref="ended"]'))return;let t=document.createElement("div");t.className="slm-ended",t.setAttribute("data-ref","ended"),t.setAttribute("role","alertdialog"),t.setAttribute("aria-labelledby","slm-ended-title"),t.innerHTML=`
|
|
726
|
+
</div>`}var Lt="https://api.seatlayer.io",B=200,Ae=16,$e=4,Be=[{key:"watch",label:"Watch",tools:[{mode:"view",label:"Monitor",shortcut:"M",title:"Live board \u2014 inventory, activity and booking momentum. Read-only."},{mode:"inspect",label:"Inspect",shortcut:"I",title:"Click one seat to read its live status and booking context. Read-only."}]},{key:"manage",label:"Manage",tools:[{mode:"block",label:"Block",shortcut:"B",title:"Take seats off sale for this event, or put them back."},{mode:"sections",label:"Sections",shortcut:"S",title:"Open, close or hide sections for this event, on a schedule or on demand."},{mode:"categories",label:"Categories",shortcut:"G",title:"Move seats to a different price category for this event only."},{mode:"tables",label:"Tables",shortcut:"T",title:"Sell each table per chair or as one whole-table booking."},{mode:"channels",label:"Channels",shortcut:"C",title:"Allocate inventory to sales channels and share their links."}]},{key:"host",label:"Host tools",tools:[{mode:"select",label:"Select",shortcut:"X",title:"Select seats for your own back-office operation. The selection is handed to your app; nothing changes here."},{mode:"filterSections",label:"Filter",shortcut:"L",title:"Filter the map to one section for your own reporting."}]}],Mt=3;function Tt(n){let e=n?.status;return e===401||e===403}var He=n=>`<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${n}</svg>`,j={enter:He('<path d="M4 9V4h5M15 4h5v5M20 15v5h-5M9 20H4v-5"/>'),exit:He('<path d="M9 4v5H4M20 9h-5V4M15 20v-5h5M4 15h5v5"/>')},Ct=Object.fromEntries(Be.flatMap(n=>n.tools.map(e=>[e.shortcut.toLowerCase(),e.mode]))),q=class{constructor(e){this.els={};this.renderer=null;this.doc=null;this.selectObserver=null;this.seatHistoryPanel=null;this.activityPanel=null;this.navigation=null;this.movingMap=!1;this.marqueeShape="box";this.socketSnapshotSeen=!1;this.monitorRefreshTimer=null;this.themeMode=null;this.colorSchemeStop=null;this.inventoryModelVersion=1;this.selectableObjectLabels=new Set;this.unavailableLabels=new Set;this.lastSelectionLabels=new Set;this.selectionWasValid=null;this.initialSelectionApplied=!1;this.labelToId=new Map;this.labelToSeat=new Map;this.allIds=[];this.gaUnitLabelSet=new Set;this.tableChairIds=new Map;this.status=new Map;this.counts={held:0,booked:0,blocked:0};this.modelVersion=0;this.currency="USD";this.authoritativeCurrency=null;this.authoritativeGrossRevenue=0;this.revenueStatus="loading";this.revenueRequest=0;this.controlRoomSnapshot=null;this.serverBaseline=null;this.livePresence=null;this.liveGross=null;this.paintHandle=null;this.trendWindowMinutes=15;this.heatEnabled=!1;this.mapView=$();this.barFind=null;this.minimap=null;this.lastKpiValues=new Map;this.activeKpiDeltas=new Map;this.ws=null;this.reconnectTimer=null;this.attempt=0;this.closed=!1;this.connectionStatus="reconnecting";this.lastMessageAt=null;this.ready=!1;this.feed=[];this.feedTimer=null;this.toastTimer=null;this.liveEventTimer=null;this.kpiCleanupTimer=null;this.followLiveTimer=null;this.followSeatTimer=null;this.releaseAt=null;this.layoutObserver=null;this.chromeClearance=-1;this.chromeClearanceWidth=-1;this.tokenExpiresAt=null;this.tokenRefreshTimer=null;this.tokenRefreshInFlight=!1;this.tokenRefreshFailures=0;this.sessionEnded=!1;this.sectionByObject=new Map;this.sectionLabelById=new Map;this.sectionsBase=null;this.filteredSectionLabel=null;this.availabilityRules={};this.effectiveHidden=new Set;this.effectiveClosed=new Set;this.availabilitySaving=!1;this.lastSyncedAt=null;this.blockBrowse=!1;this.blockedQuery="";this.blockedSection="";this.blockedResultLimit=100;this.unblockAllConfirmTimer=null;this.channels=null;this.chooser=null;this.chooserDialog=null;this.categoryDifferences=null;this.channelCaps={view:!1,manage:!1};this.categoryCanManage=!1;this.tableCanManage=!1;this.tableBookingSaving=!1;this.channelCapabilityResolution=0;this.channelsLoading=null;this.onFullscreenChange=()=>{this.paintFullscreenButton(),this.updateContainerLayout(),this.renderer?.forceDraw()};this.onKeyDown=e=>{if(e.metaKey||e.ctrlKey||e.altKey||e.target?.matches('input,select,textarea,[contenteditable="true"]'))return;let s=e.key.toLowerCase(),i=e.shiftKey?xe(s):null;if(i){this.toggleMapView(i),e.preventDefault();return}if(s==="/"){let a=this.els.findbar?.querySelector("[data-ch-find-input]");a&&(a.focus(),a.select(),e.preventDefault());return}let o=Ct[s];if(o){if(!this.toolAvailable(o))return;this.setMode(o)}else if(s==="f")this.toggleFullscreen();else if(s==="escape"){let a=this.els.view;if(a?.open)a.open=!1,a.querySelector("summary")?.focus();else if(!this.channels?.handleBack())if(this.getSelection().length)this.clearSelection();else return}else return;e.preventDefault()};this.onRailClick=e=>{let t=e.target,s=t?.closest("[data-section-focus]");if(s?.dataset.sectionFocus){this.locateSection(s.dataset.sectionFocus);return}let i=t?.closest("[data-feed-id]");i?.dataset.feedId&&this.locateActivity(i.dataset.feedId)};this.typeKeyBySection=null;this.typeKeyBase=null;this.sectionOptions=[];F(e.token),this.assertSelectionOptions(e.maxSelectedObjects,e.numberOfPlacesToSelect),this.opts=e,this.key=e.eventKey,this.mode=e.mode??"view",this.selectableObjectLabels=new Set(e.selectableObjects??[]),this.unavailableLabels=new Set(e.unavailableObjects??[]),this.categoryCanManage=new Set(e.capabilities??[]).has("event:categories:manage"),this.tableCanManage=new Set(e.capabilities??[]).has("event:tables:manage"),this.keepLive=e.keepLiveWhileHidden??!0,this.themeMode=e.themeMode??null,this.followLive=e.followLive??!1,this.currency=e.currency??"USD",this.tokenExpiresAt=e.tokenExpiresAt??null,this.api=new O(e.apiBase??Lt,e.token),this.organizerAssetUrls=new A(this.key,(t,s)=>this.withAuthRetry(()=>this.api.asset(t,s))),this.host=Y(e.container)}assertSelectionOptions(e,t){let s=i=>i===void 0||Number.isInteger(i)&&i>0;if(!s(e))throw new TypeError("maxSelectedObjects must be a positive integer");if(!s(t))throw new TypeError("numberOfPlacesToSelect must be a positive integer");if(e!==void 0&&t!==void 0&&e<t)throw new TypeError("maxSelectedObjects cannot be lower than numberOfPlacesToSelect")}async render(){ce(),this.buildChrome();try{let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1,this.doc=await this.organizerAssetUrls.prepareRendererChart(e.doc),this.authoritativeCurrency=e.event.currency??null,this.currency=this.authoritativeCurrency??this.opts.currency??this.currency,this.buildUnitUniverse(this.doc),this.buildRenderer(),this.buildSectionOptions(),this.settleMode();let[,t]=await Promise.all([this.resnapshot(),this.refreshControlRoom().catch(s=>this.opts.onError?.(s)),this.refreshAvailability()]);t?.activity?this.seedFeed(t.activity):this.api.log(this.key,{limit:24}).then(s=>this.seedFeed(s.entries)).catch(()=>{}),this.connect(),this.startFeedClock(),this.ready=!0,await this.resolveChannelCapabilities(),this.setMode(this.mode),this.applyInitialSelection(),this.scheduleTokenRefresh(),this.opts.onReady?.()}catch(e){this.fail(e)}return this}setMode(e){this.toolAvailable(e)||(e="view"),e==="channels"&&!this.channels&&this.ensureChannels();let t=e!==this.mode,s=this.mode==="channels",i=this.mode==="filterSections";this.mode=e,t&&e!=="view"&&this.setFollowLive(!1),!this.renderer&&this.doc?this.buildRenderer():this.updateRendererInteraction(),t&&(this.renderer?.clearSelection(),this.syncSelection()),s&&e!=="channels"&&this.channels?.leave(),t&&(this.highlightLabels(null),this.wireBarFind()),this.paintModeTabs(),this.paintRail(),this.paintMapViewMenu(),this.applyMapView(),this.applySectionCanvasTreatment(),i&&e!=="filterSections"&&this.renderer?.zoomToFit(),e==="channels"&&this.channels?.enter(),e==="select"&&this.applyInitialSelection(),t&&this.opts.onModeChange?.(e)}async resolveChannelCapabilities(){let e=++this.channelCapabilityResolution,t=this.opts.capabilities,s;if(t){let i=new Set(t);s={view:i.has("event:channels:view"),manage:i.has("event:channels:view")&&i.has("event:channels:manage")}}else s={view:!1,manage:!1};if(!s.view&&!t)try{await this.api.channels(this.key),s={view:!0,manage:!1}}catch{s={view:!1,manage:!1}}if(e===this.channelCapabilityResolution){if(this.channelCaps=s,!this.channelCaps.view){this.channels?.destroy(),this.channels=null,this.mode==="channels"?this.setMode("view"):this.paintModeTabs();return}this.channels?.setCapabilities(this.channelCaps),this.paintModeTabs()}}ensureChannels(){if(this.channelsLoading)return this.channelsLoading;if(this.channels)return Promise.resolve();let e=(async()=>{try{let t=await import("./channelsMode-YLBLFLZZ.js");if(this.closed||!this.channelCaps.view||(this.channels||(de(t.CHANNELS_CSS),this.channels=new t.ChannelsMode(this.buildChannelsHost(),this.channelCaps),this.channels.onInteractionChange=()=>this.updateRendererInteraction()),this.mode!=="channels"))return;this.updateRendererInteraction(),this.paintRail(),this.channels.enter(),this.applyMapView(),this.paintMapViewMenu()}catch(t){if(this.closed)return;this.channelsLoading=null,this.mode==="channels"&&this.paintRail(),this.opts.onError?.(t)}})();return this.channelsLoading=e,e}buildChooserHost(){let e=s=>{let i=this.labelToSeat.get(s);return i?this.mode==="block"?this.isBlockSelectable(s):this.mode==="select"?this.canSelectObject(i):!0:!1};return{selectionLabels:()=>this.selectionLabels(),selectByLabels:s=>{this.selectByLabels(s)},clearSelection:()=>this.clearSelection(),selectSection:s=>{this.selectSection(s)},sections:()=>this.sectionOptions,labelsInSection:s=>(this.renderer?.getSelectableInSection(s)??[]).map(i=>i.label).filter(e),rows:()=>{let s=new Map((this.doc?.objects??[]).map(o=>[o.id,o])),i=new Map;for(let o of this.labelToSeat.values()){if(!e(o.label))continue;let a=s.get(o.rowId);if(!a||a.type!=="row"&&a.type!=="table")continue;let l=o.logicalRowId??o.rowId,r=this.sectionByObject.get(o.rowId)??v,c=i.get(l)??{id:l,label:a.type==="row"?a.segmentedRow?.displayLabel??a.displayLabel??a.label:a.displayLabel??a.label,sectionId:r,sectionLabel:this.sectionLabelById.get(r)??"Other seats",labels:[]};c.labels.push(o.label),i.set(l,c)}return[...i.values()].sort((o,a)=>o.sectionLabel.localeCompare(a.sectionLabel,void 0,{numeric:!0,sensitivity:"base"})||o.label.localeCompare(a.label,void 0,{numeric:!0,sensitivity:"base"}))},categories:()=>(this.doc?.categories??[]).map(s=>({key:s.key,label:s.label??s.key,color:s.color})),labelsInCategory:s=>[...this.labelToSeat.values()].filter(i=>i.categoryKey===s&&e(i.label)).map(i=>i.label),seats:()=>[...this.labelToSeat.values()].filter(s=>e(s.label)).map(s=>({label:s.label})),statusOf:s=>this.status.get(s)??(this.labelToSeat.has(s)?"free":void 0),sectionOfLabel:s=>{let i=this.labelToSeat.get(s);if(!i)return null;let o=this.sectionByObject.get(i.rowId)??v;return{id:o,label:this.sectionLabelById.get(o)??"Other seats"}},openDialog:(s,i)=>{this.chooserDialog=ae(this.root,s,i,{previous:this.chooserDialog,onClose:()=>{this.chooserDialog=null}})},closeDialog:()=>this.chooserDialog?.close(),highlight:s=>this.highlightLabels(s),...this.mode==="select"?{cap:this.selectionCap()}:{}}}wireBarFind(){let e=this.els.findbar;e&&(e.innerHTML=P({compact:!0}),this.barFind=new D({...this.buildChooserHost(),seats:()=>[...this.labelToSeat.values()].map(t=>({label:t.label})),frame:t=>this.frameLabels(t)}),this.barFind.wireFind(e,{enter:this.isChoosingTool()?"select":"frame"}))}isChoosingTool(){return this.isBulkSelectMode()||this.mode==="select"}frameLabels(e){let t=e.map(s=>this.labelToSeat.get(s)?.id).filter(s=>!!s);t.length&&(this.setFollowLive(!1),this.renderer?.focusSeats?.(t,{animate:!0}))}highlightLabels(e){if(!e){this.renderer?.setSeatHighlight?.(null);return}this.renderer?.setSeatHighlight?.(e.map(t=>this.labelToSeat.get(t)?.id).filter(t=>!!t))}toolChooser(){return this.chooserDialog?.close({restoreFocus:!1}),this.chooser=new D(this.buildChooserHost()),this.chooser}toolSelectionBar(e,t,s,i){return se({count:0,noun:"selected",breakdown:`<span class="slm-selactions"><button type="button" class="slm-linkbtn" data-ref="${i}">Select all</button></span>`,clearAttr:`data-ref="${s}"`}).replace('class="slm-selnum"',`class="slm-selnum" data-ref="${e}"`).replace('class="slm-sellabel"',`class="slm-sellabel" data-ref="${t}"`)}buildChannelsHost(){return{eventKey:this.key,api:this.api,rail:this.els.rail,mapLayer:this.root.querySelector(".slm-map"),pillLane:this.els.lane,root:this.root,seats:()=>[...this.labelToSeat.values()].map(e=>({id:e.id,label:e.label,x:e.x,y:e.y})),statusOf:e=>this.status.get(e)??(this.labelToSeat.has(e)?"free":void 0),selectionLabels:()=>this.selectionLabels(),selectByLabels:e=>{this.selectByLabels(e)},clearSelection:()=>this.clearSelection(),selectSection:e=>{this.selectSection(e)},sections:()=>this.sectionOptions,labelsInSection:e=>this.renderer?.getSelectableInSection(e).map(t=>t.label)??[],rows:()=>{let e=new Map((this.doc?.objects??[]).map(s=>[s.id,s])),t=new Map;for(let s of this.labelToSeat.values()){let i=e.get(s.rowId);if(!i||i.type!=="row"&&i.type!=="table")continue;let o=s.logicalRowId??s.rowId,a=this.sectionByObject.get(s.rowId)??v,l=t.get(o)??{id:o,label:i.type==="row"?i.segmentedRow?.displayLabel??i.displayLabel??i.label:i.displayLabel??i.label,sectionId:a,sectionLabel:this.sectionLabelById.get(a)??"Other seats",labels:[]};l.labels.push(s.label),t.set(o,l)}return[...t.values()].sort((s,i)=>s.sectionLabel.localeCompare(i.sectionLabel,void 0,{numeric:!0,sensitivity:"base"})||s.label.localeCompare(i.label,void 0,{numeric:!0,sensitivity:"base"}))},categories:()=>(this.doc?.categories??[]).map(e=>({key:e.key,label:e.label??e.key,color:e.color,price:e.price,tiers:e.tiers?.map(t=>({id:t.id,name:t.name,price:t.price}))})),labelsInCategory:e=>[...this.labelToSeat.entries()].filter(([,t])=>t.categoryKey===e).map(([t])=>t),sectionOfLabel:e=>{let t=this.labelToSeat.get(e);if(!t)return null;let s=this.sectionByObject.get(t.rowId)??v;return{id:s,label:this.sectionLabelById.get(s)??"Other seats"}},worldToScreen:e=>this.renderer?.worldToScreen(e)??null,seatPixelSize:()=>this.seatPixelSize(),isSeatDetail:()=>this.renderer?.getRung?.()==="seats",showSectionOverview:()=>{this.renderer?.clearSectionFocus(),this.renderer?.setRung?.("sections")},focusSection:e=>this.renderer?.focusSection(e),isCompact:()=>!!this.root?.classList.contains("compact"),setMapInert:e=>{this.mapHost.toggleAttribute("inert",e),this.mapHost.setAttribute("aria-hidden",String(e))},toast:(e,t)=>this.toast(e,t),onError:e=>this.opts.onError?.(e)}}seatPixelSize(){let e=this.renderer?.getVisibleWorldRect?.(),t=this.mapHost?.clientWidth??0;return!e?.width||!t?6:Math.max(3,t/e.width*18)}setHeatOverlay(e){this.heatEnabled=e,this.mapView.momentum!==e&&this.setMapView({momentum:e}),this.applyHeatOverlay(),this.paintHeatButton()}setMapView(e){let t={...this.mapView,...e};if(!Object.keys(t).some(o=>t[o]!==this.mapView[o]))return;let i=t.categoryColours!==this.mapView.categoryColours;this.mapView=t,ke(t),t.momentum!==this.heatEnabled&&this.setHeatOverlay(t.momentum),this.applyMapView(),this.paintMapViewMenu(),i&&(this.refreshBlockPaint(),this.paintMapChrome())}getColourBy(){return this.mapView.categoryColours?"type":"full"}setColourBy(e){this.setMapView({categoryColours:e==="type"})}getMapView(){return{...this.mapView}}toggleMapView(e){e==="channelColours"&&!this.channelColoursAvailable()||this.setMapView({[e]:!this.mapView[e]})}channelColoursAvailable(){return this.mode==="channels"&&this.channels!=null}applyMapView(){Le(this.mapView,{renderer:this.renderer,channelsOverlay:e=>this.channels?.setOverlayVisible(e)})}paintMapViewMenu(){let e=this.els.view;e&&Te(e,this.mapView,{channelColoursAvailable:this.channelColoursAvailable(),momentumLoading:this.mapView.momentum&&!this.controlRoomSnapshot})}setFollowLive(e){let t=this.followLive!==e;this.followLive=e,e||(this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=null,this.followSeatTimer=null),this.paintFollowLiveButton(),t&&this.opts.onFollowLiveChange?.(e)}setKeepLiveWhileHidden(e){this.keepLive=e??!0,this.opts.keepLiveWhileHidden=e}setCurrency(e){this.opts.currency=e,!this.authoritativeCurrency&&(this.currency=e??"USD",this.ready&&this.recomputeTallies())}setTheme(e){this.opts.theme=e,this.applyThemeVars()}applyThemeVars(){if(!this.root)return;let e=I(this.themeMode);for(let[t,s]of Object.entries(J(this.opts.theme,e)))this.root.style.setProperty(t,s);e?this.root.dataset.theme=e:delete this.root.dataset.theme}watchThemeMode(){this.colorSchemeStop?.(),this.colorSchemeStop=null,this.themeMode==="auto"&&(this.colorSchemeStop=N(()=>{this.closed||this.repaintForThemeMode()}))}repaintForThemeMode(){this.applyThemeVars();let e=this.renderer;if(!e||!this.doc)return;let t=e.getSelection().map(o=>o.id),s=e.getCameraPose(),i=e.getFocusedSection();e.setChart(this.themedDoc()),this.repaintAll(),this.applyHeatOverlay(),t.length&&e.select(t),i&&e.focusSection(i),e.setCameraPose(s),this.updateZoomHint()}setThemeMode(e){let t=e??null;this.closed||t===this.themeMode||(this.themeMode=t,this.opts.themeMode=t??void 0,this.watchThemeMode(),this.repaintForThemeMode())}getThemeMode(){return this.themeMode}themedDoc(){let e=this.doc,t=ee(I(this.themeMode));return t?{...e,theme:{...e.theme??{},background:t}}:e}setCapabilities(e){this.opts.capabilities=e,this.categoryCanManage=new Set(e??[]).has("event:categories:manage"),this.tableCanManage=new Set(e??[]).has("event:tables:manage"),!this.categoryCanManage&&this.mode==="categories"||!this.tableCanManage&&this.mode==="tables"?this.setMode("view"):this.paintModeTabs(),this.ready&&this.resolveChannelCapabilities()}setTokenRefresh(e){this.opts.onTokenRefresh=e,this.scheduleTokenRefresh()}setTrendWindow(e){let t=Number.isFinite(e)?Math.floor(e):15;return this.trendWindowMinutes=Math.max(5,Math.min(60,t)),this.paintTrendWindow(),this.refreshControlRoom()}async enterFullscreen(){!this.root?.requestFullscreen||this.isFullscreen()||(await this.root.requestFullscreen(),this.root.focus({preventScroll:!0}))}async exitFullscreen(){typeof document>"u"||!this.isFullscreen()||await document.exitFullscreen()}isFullscreen(){return typeof document<"u"&&document.fullscreenElement===this.root}toggleFullscreen(){(this.isFullscreen()?this.exitFullscreen():this.enterFullscreen()).catch(t=>this.opts.onError?.(t))}setToken(e,t){F(e),this.api.setToken(e),this.opts.token=e,this.opts.tokenExpiresAt=t,this.tokenExpiresAt=t??null,this.scheduleTokenRefresh(),this.ready&&this.resolveChannelCapabilities()}scheduleTokenRefresh(){this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.tokenRefreshTimer=null;let e=this.opts.onTokenRefresh,t=this.tokenExpiresAt;if(this.closed||!e||!t||!Number.isFinite(t))return;let s=t-Date.now(),i=Math.min(12e4,Math.max(3e4,s*.2)),o=Math.max(0,s-i);this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},o)}async rotateToken(){if(!(this.closed||this.sessionEnded||this.tokenRefreshInFlight||!this.opts.onTokenRefresh)){this.tokenRefreshInFlight=!0;try{let e=await this.opts.onTokenRefresh();if(!e?.token||!Number.isFinite(e.expiresAt))throw new Error("invalid_token_refresh_result");this.tokenRefreshFailures=0,this.setToken(e.token,e.expiresAt)}catch(e){this.opts.onError?.(e),this.tokenRefreshFailures+=1,!this.closed&&(this.tokenRefreshFailures>=Mt||Tt(e))?this.endSession():this.closed||(this.tokenRefreshTimer=setTimeout(()=>{this.tokenRefreshTimer=null,this.rotateToken()},3e4))}finally{this.tokenRefreshInFlight=!1}}}endSession(){if(this.sessionEnded)return;this.sessionEnded=!0,this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.tokenRefreshTimer=null,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.reconnectTimer=null,this.monitorRefreshTimer&&clearTimeout(this.monitorRefreshTimer),this.monitorRefreshTimer=null;let e=this.ws;if(this.ws=null,e){e.onclose=null;try{e.close()}catch{}}this.setLive(!1),this.paintSessionEnded()}async retrySession(){if(this.closed||!this.sessionEnded)return!this.sessionEnded;if(!this.opts.onTokenRefresh)return!1;this.sessionEnded=!1,this.tokenRefreshFailures=0;let e=this.root?.querySelector('[data-ref="ended"]');return e?.setAttribute("data-busy","true"),await this.rotateToken(),this.sessionEnded?(e?.removeAttribute("data-busy"),!1):(e?.remove(),this.attempt=0,this.connect(),!0)}paintSessionEnded(){let e=this.els.lane;if(!e||e.querySelector('[data-ref="ended"]'))return;let t=document.createElement("div");t.className="slm-ended",t.setAttribute("data-ref","ended"),t.setAttribute("role","alertdialog"),t.setAttribute("aria-labelledby","slm-ended-title"),t.innerHTML=`
|
|
716
727
|
<strong id="slm-ended-title">This session ended</strong>
|
|
717
728
|
<span>The map is as it was when the connection stopped. Sign in again, then try again to pick the live stream back up.</span>
|
|
718
|
-
<button type="button" class="slm-btn" data-ref="ended-retry">Try again</button>`,t.querySelector('[data-ref="ended-retry"]').addEventListener("click",()=>{this.retrySession()}),e.appendChild(t)}async block(e,t={}){let s=(e??this.selectionLabels()).filter(o=>this.status.get(o)==="free");if(!s.length)return;let i=t.releaseAt??this.releaseAt??void 0;this.setSeatsLocal(s,"blocked");try{await this.api.block(this.key,s,{...t,releaseAt:i}),this.clearSelection(),this.done("block",s,i?`Blocked ${s.length} \u2014 auto-release ${new Date(i).toLocaleString()}.`:`Blocked ${s.length} seat${s.length===1?"":"s"}.`)}catch(o){this.setSeatsLocal(s,"free"),this.toastErr(o instanceof k&&o.status===409?"Some seats were just taken. Try again.":"Couldn't block those seats."),this.opts.onError?.(o)}}async unblock(e){let t=(e??this.selectionLabels()).filter(s=>this.status.get(s)==="blocked");if(t.length){this.setSeatsLocal(t,"free");try{await this.api.unblock(this.key,t),this.clearSelection(),this.done("unblock",t,`Unblocked ${t.length} seat${t.length===1?"":"s"}.`)}catch(s){this.setSeatsLocal(t,"blocked"),this.toastErr("Couldn't unblock those seats."),this.opts.onError?.(s)}}}async unblockAll(){let e=[...this.status.entries()].filter(([,t])=>t==="blocked").map(([t])=>t);if(e.length){this.setSeatsLocal(e,"free");try{let t=await this.api.unblockAll(this.key);this.clearSelection(),this.done("unblockAll",e,`Unblocked ${t.freed} seat${t.freed===1?"":"s"}.`)}catch(t){await this.resnapshot(),this.toastErr("Couldn't mark everything for sale."),this.opts.onError?.(t)}}}async cancelBooking(e,t){let s=e.filter(i=>this.status.get(i)==="booked");if(!(!s.length||!t)){this.setSeatsLocal(s,"free");try{await this.api.unbook(this.key,s,t),this.clearSelection(),this.done("cancelBooking",s,`Released ${s.length} booked unit${s.length===1?"":"s"}.`)}catch(i){this.setSeatsLocal(s,"booked"),this.toastErr("Couldn't release that booked inventory. Check the booking reference."),this.opts.onError?.(i)}}}async setCategory(e,t){let s=this.doc?.categories.find(o=>o.key===e),i=[...new Set(t??this.selectionLabels())].filter(o=>this.labelToSeat.has(o));if(!(!s||!i.length))try{let o=await this.withAuthRetry(()=>this.api.setCategory(this.key,i,e)),a={};for(let l of o.labels){let r=this.labelToSeat.get(l),c=this.labelToId.get(l);r&&(r.categoryKey=e),c&&(a[c]=e)}this.renderer?.setSeatCategories?.(a),this.clearSelection(),this.mode==="categories"&&this.loadCategoryDifferences(),this.done("setCategory",o.labels,`Assigned ${o.labels.length.toLocaleString()} object${o.labels.length===1?"":"s"} to ${s.label??s.key}.`)}catch(o){this.toastErr("Couldn't update those event categories."),this.opts.onError?.(o)}}async setTableBooking(e,t,s={}){let i=[...new Set(e)].filter(Boolean);if(!(!i.length||this.tableBookingSaving)){if(this.inventoryModelVersion!==2){this.toastErr("Table booking controls require inventory model 2 for this event.");return}this.tableBookingSaving=!0,this.mode==="tables"&&this.renderTablesRail();try{let o=await this.withAuthRetry(()=>this.api.setTableBooking(this.key,i,t,s));await this.reloadEventChart(),this.done("setTableBooking",o.tableIds,`Updated ${o.tableIds.length.toLocaleString()} table${o.tableIds.length===1?"":"s"} to ${t==="individual"?"per-chair":t==="whole"?"whole-table":"flexible-group"} booking.`)}catch(o){let a=o instanceof k&&o.code==="table_inventory_in_use";this.toastErr(a?"Release held, booked, or blocked table inventory before changing its booking mode.":"Couldn't update table booking. No table mode was changed."),this.opts.onError?.(o)}finally{this.tableBookingSaving=!1,this.mode==="tables"&&this.renderTablesRail()}}}async reloadEventChart(){let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1;let t=await this.organizerAssetUrls.prepareRendererChart(e.doc);this.renderer?.destroy(),this.renderer=null,this.doc=t,this.labelToId.clear(),this.labelToSeat.clear(),this.allIds=[],this.gaUnitLabelSet.clear(),this.tableChairIds.clear(),this.status.clear(),this.counts={held:0,booked:0,blocked:0},this.serverBaseline=null,this.lastSelectionLabels.clear(),this.buildUnitUniverse(t),this.buildRenderer(),this.buildSectionOptions(),this.settleMode(),await Promise.all([this.resnapshot(),this.refreshAvailability()]),this.paintRail()}selectAll(){if(this.mode==="select")return this.selectByLabels([...this.labelToSeat.values()].filter(t=>this.canSelectObject(t)).map(t=>t.label));let e=this.renderer?.selectAllSelectable()??[];return this.syncSelection(),e}selectSection(e){if(!this.renderer)return[];let t=this.renderer.getSelectableInSection(e);return this.renderer.selectByLabels(t.map(s=>s.label)),this.syncSelection(),this.renderer.getSelection()}setFilteredSection(e){let t=e.trim(),s=this.filterableSections().filter(a=>a.label===t);if(!s.length)throw new Error(`Unknown event section: ${e}`);let i=t!==this.filteredSectionLabel;this.filteredSectionLabel=t,this.mode==="filterSections"&&(this.applyFilteredSectionCanvas(s),this.renderFilterSectionsRail());let o=s.map(({id:a,label:l,seatCount:r,zone:c})=>({id:a,label:l,seatCount:r,...c?{zone:c}:{}}));return i&&this.opts.onFilteredSectionChange?.(o),o}focusSection(e){let t=e.trim(),s=this.filterableSections().filter(i=>i.label===t);return!this.renderer||!s.length?[]:(this.frameSections(s),s.map(({id:i,label:o,seatCount:a,zone:l})=>({id:i,label:o,seatCount:a,...l?{zone:l}:{}})))}clearFilteredSection(){let e=this.filteredSectionLabel!==null;this.filteredSectionLabel=null,this.renderer?.setDimmedSections(null),this.renderer?.clearSectionFocus(),this.renderer?.zoomToFit(),this.mode==="filterSections"&&this.renderFilterSectionsRail(),e&&this.opts.onFilteredSectionChange?.([])}getFilteredSections(){return this.filteredSectionLabel?this.filterableSections().filter(e=>e.label===this.filteredSectionLabel).map(({id:e,label:t,seatCount:s,zone:i})=>({id:e,label:t,seatCount:s,...i?{zone:i}:{}})):[]}selectByLabels(e){let t=e;if(this.mode==="select"){let s=new Set(this.selectionLabels()),i=this.selectionCap(),o=[...new Set(e)].filter(l=>!s.has(l)).map(l=>this.labelToSeat.get(l)).filter(l=>!!l&&this.canSelectObject(l)),a=Math.max(0,i-s.size);o.length>a&&this.opts.onSelectionLimit?.(i),t=o.slice(0,a).map(l=>l.label)}return this.renderer?.selectByLabels(t),this.syncSelection(),this.getSelection()}selectObjects(e){return this.selectByLabels(e)}deselectObjects(e){let t=e.map(s=>this.labelToId.get(s)).filter(s=>!!s);return this.renderer?.deselect(t),this.syncSelection(),this.getSelection()}selectCategories(e){let t=new Set(e);return this.selectByLabels([...this.labelToSeat.values()].filter(s=>t.has(s.categoryKey)).map(s=>s.label))}deselectCategories(e){let t=new Set(e);return this.deselectObjects(this.getSelection().filter(s=>t.has(s.categoryKey)).map(s=>s.label))}setSelectableObjects(e){this.opts.selectableObjects=[...e],this.selectableObjectLabels=new Set(e),this.reconcileSelectPolicy()}setUnavailableObjectsSelectable(e){this.opts.unavailableObjectsSelectable=e,this.reconcileSelectPolicy()}setObjectSelectable(e){this.opts.isObjectSelectable=e,this.reconcileSelectPolicy()}setMaxSelectedObjects(e){this.assertSelectionOptions(e,this.opts.numberOfPlacesToSelect),this.opts.maxSelectedObjects=e,this.trimSelectionToCap(),this.updateRendererInteraction(),this.syncSelection()}setNumberOfPlacesToSelect(e){this.assertSelectionOptions(this.opts.maxSelectedObjects,e),this.opts.numberOfPlacesToSelect=e,this.selectionWasValid=null,this.trimSelectionToCap(),this.updateRendererInteraction(),this.syncSelection()}getSelectionValidity(){let e=this.opts.numberOfPlacesToSelect;if(e===void 0)return null;let t=this.getSelection(),s=t.length;return{isValid:s===e,count:s,required:e,remaining:Math.max(0,e-s),objects:t}}clearSelection(){this.renderer?.clearSelection(),this.syncSelection()}getSelection(){return this.renderer?.getSelection()??[]}getReport(){return this.api.report(this.key).then(e=>(this.applyReportRevenue(e),e))}getControlRoomSnapshot(e=this.trendWindowMinutes){return this.setTrendWindow(e)}getConnection(){return{status:this.connectionStatus,lastMessageAt:this.lastMessageAt}}getLog(e={}){return this.api.log(this.key,e)}async setHoldTtl(e){try{await this.api.setHoldTtl(this.key,e),this.done("setHoldTtl",[],e?`Hold window set to ${Math.round(e/6e4)} min.`:"Hold window reset.")}catch(t){this.toastErr("Couldn't update the hold window."),this.opts.onError?.(t)}}zoomToFit(){if(this.mode==="filterSections"&&this.filteredSectionLabel){this.clearFilteredSection();return}this.renderer?.clearSectionFocus(),this.renderer?.zoomToFit()}zoomOutStep(){let e=this.renderer;if(!e)return;if(!e.zoomOutLevel)return void e.zoomOut();let t=!!e.getFocusedSection?.();e.zoomOutLevel()==="venue"&&t&&e.clearSectionFocus()}paintMapChrome(){let e=this.renderer;if(!e||!this.els.crumb)return;let t=e.getFocusedSection?.()??null,s=t?e.getMinimapSnapshot?.().sections.find(l=>l.id===t)??null:null,i=e.getFloors?.()??[],o=i.length>1?e.isFloorOverview?.()?"All floors":i.find(l=>l.id===e.getActiveFloorId?.())?.name??null:null,a=this.els.blocklegend;a&&fe(a,{colourBy:this.getColourBy(),seats:e.getRung?.()==="seats",types:this.legendTypes()}),ue(this.els,me({focused:s?{label:s.label,free:s.free,total:s.total}:null,floor:o,seatsRevealed:e.seatsRevealed?.()??!0,atVenueFit:e.atVenueFit?.(),atCeiling:e.canZoomIn?.()===!1||e.seatsPickable?.()===!0}))}sectionTypeKeys(){if(this.typeKeyBySection&&this.typeKeyBase===this.sectionsBase)return this.typeKeyBySection;let e=new Map;for(let t of this.filterableSections()){let s=new Map;for(let o of t.seatLabels){let a=this.labelToSeat.get(o)?.categoryKey;a&&s.set(a,(s.get(a)??0)+1)}let i=null;for(let[o,a]of s)(!i||a>s.get(i))&&(i=o);i&&e.set(t.id,i)}return this.typeKeyBySection=e,this.typeKeyBase=this.sectionsBase,e}sectionTypeTint(e){let t=this.sectionTypeKeys().get(e);return t?this.renderer?.categoryDisplayColor?.(t)??null:null}legendTypes(){let e=new Set;for(let t of this.labelToSeat.values())e.add(t.categoryKey);return(this.doc?.categories??[]).filter(t=>e.has(t.key)).map(t=>({label:t.label,color:this.renderer?.categoryDisplayColor?.(t.key)??t.color}))}refreshBlockPaint(){this.renderer?.refreshBlockPaint?.(),this.minimap?.refreshMinimap()}mapCamera(){return{getViewport:()=>{let e=this.renderer;return!e?.getVisibleWorldRect||!e.getWorldBounds?null:{visible:e.getVisibleWorldRect(),bounds:e.getWorldBounds()}},getMinimapSnapshot:()=>this.renderer?.getMinimapSnapshot?.()??{sections:[],seats:[]},panToWorld:e=>{this.setFollowLive(!1),this.renderer?.panToWorld?.(e)},clearSectionFocus:()=>this.renderer?.clearSectionFocus?.(),focusSection:e=>{this.setFollowLive(!1),this.renderer?.focusSection(e),this.channels?.handleSectionFocus(e)},overview:()=>{this.setFollowLive(!1),this.zoomToFit()},getFloors:()=>this.renderer?.getFloors?.()??[],getActiveFloorId:()=>this.renderer?.getActiveFloorId?.()??"",isFloorOverview:()=>this.renderer?.isFloorOverview?.()??!1,getRenderer:()=>this.renderer}}syncMinimap(){let e=this.els.minimapMount,t=!!this.root?.classList.contains("compact");if(!e||!this.renderer||t){this.minimap?.dispose(),this.minimap=null;return}if(this.minimap){this.minimap.refreshMinimap();return}this.minimap=K({controller:this.mapCamera(),root:()=>this.root,cssVar:s=>this.cssVar(s.replace(/^--sl-/,"--slm-")),focusedSectionLabel:()=>{},tint:s=>this.renderer?.categoryDisplayColor?.(s)||void 0},e),this.minimap.refreshMinimap()}cssVar(e){return this.root?getComputedStyle(this.root).getPropertyValue(e).trim():""}destroy(){if(this.selectObserver?.disconnect(),this.closed=!0,this.minimap?.dispose(),this.minimap=null,this.monitorRefreshTimer&&clearTimeout(this.monitorRefreshTimer),this.monitorRefreshTimer=null,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.feedTimer&&clearInterval(this.feedTimer),this.toastTimer&&clearTimeout(this.toastTimer),this.liveEventTimer&&clearTimeout(this.liveEventTimer),this.kpiCleanupTimer&&clearTimeout(this.kpiCleanupTimer),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.paintHandle!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.paintHandle),this.paintHandle=null,this.channels?.destroy(),this.channels=null,this.channelsLoading=null,this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.layoutObserver?.disconnect(),this.layoutObserver=null,this.colorSchemeStop?.(),this.colorSchemeStop=null,this.root?.removeEventListener("keydown",this.onKeyDown),this.els.rail?.removeEventListener("click",this.onRailClick),typeof document<"u"&&document.removeEventListener("fullscreenchange",this.onFullscreenChange),this.ws){try{this.ws.close()}catch{}this.ws=null}this.seatHistoryPanel?.destroy(),this.seatHistoryPanel=null,this.activityPanel?.destroy(),this.activityPanel=null,this.navigation?.destroy(),this.navigation=null,this.renderer?.destroy(),this.renderer=null,this.organizerAssetUrls.dispose(),this.root&&this.root.parentNode===this.host&&this.host.removeChild(this.root)}buildRenderer(){if(!this.doc)return;let e=this.isBulkSelectMode();this.renderer=new gt(this.mapHost,{manageMode:!0,organizerGlyph:{apply:ft,clear:vt,isPainted:yt},marqueeSelect:e&&!this.movingMap,marqueeShape:this.marqueeShape,rowLabelSelect:this.rowLabelSelectable(),maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses(),currency:this.currency,onSelect:t=>this.handleSeatSelect(t),onDeselect:()=>this.syncSelection(),onSelectionLimit:t=>this.opts.onSelectionLimit?.(t),onMarquee:()=>this.syncSelection(),onGAClick:t=>{if(this.mode!=="select"||!this.opts.onAreaClick||!this.doc)return;let s=Re(this.doc).find(i=>i.id===t);s&&this.opts.onAreaClick({id:s.id,label:s.label,name:s.displayLabel?.trim()||s.label})},onSectionTap:t=>{if(this.mode==="filterSections"){let s=this.filterableSections().find(i=>i.id===t);s&&this.setFilteredSection(s.label);return}this.renderer?.focusSection(t),this.channels?.handleSectionFocus(t)},onViewChange:()=>{this.updateZoomHint(),this.paintMapChrome(),this.minimap?.drawMinimapRect(),this.channels?.handleViewChange()},onFocusedSectionChange:()=>{this.paintMapChrome(),this.minimap?.refreshMinimap()},hoverFacts:t=>this.hoverFactsFor(t),blockPaint:t=>be(t,{rule:this.availabilityRules[t.id],hiddenNow:this.effectiveHidden.has(t.id),closedNow:this.effectiveClosed.has(t.id),colourBy:this.getColourBy(),typeTint:this.sectionTypeTint(t.id)}),openAtSectionsWhenDense:!0}),this.renderer.setChart(this.themedDoc()),this.chromeClearance=-1,this.applyChromeClearance(),this.repaintAll(),this.applyHeatOverlay(),this.applyMapView(),this.updateZoomHint(),this.minimap?.dispose(),this.minimap=null,this.syncMinimap(),this.paintMapChrome()}hoverFactsFor(e){let t=[...this.labelToSeat.values()].find(d=>d.id===e);if(!t)return null;let s=this.status.get(t.label)??"free",o=[{caption:"Status",value:{free:"Free",held:"Held",booked:"Booked",blocked:"Blocked"}[s]}],a=this.channels?.channelNameForLabel(t.label)??null;a&&o.push({caption:"Channel",value:a});let l=this.sectionByObject.get(t.rowId)??v,r=this.doc?.categories.find(d=>d.key===t.categoryKey),c=s==="free"&&!this.effectiveHidden.has(l)&&!this.effectiveClosed.has(l)&&r?.notForSale!==!0;return o.push({caption:"For sale",value:c?"Yes":s==="free"?"No":"\u2014"}),o}rowLabelSelectable(){return this.isBulkSelectMode()||this.mode==="select"}marqueeShapeChipsHtml(){let e=(t,s)=>`<button type="button" class="slm-btn${this.marqueeShape===t?"":" ghost"}" data-ref="shape-${t}"
|
|
719
|
-
aria-pressed="${this.marqueeShape===t}" title="${t==="box"?"Drag a rectangle over seats":"Draw a loop around seats"}">${s}</button>`;return`${e("box","Drag box")}${e("lasso","Lasso")}`}wireMarqueeShapeChips(){this.els.rail.querySelectorAll('[data-ref^="shape-"]').forEach(e=>{e.addEventListener("click",()=>{let t=e.dataset.ref==="shape-lasso"?"lasso":"box";t!==this.marqueeShape&&(this.marqueeShape=t,this.updateRendererInteraction(),this.els.rail.querySelectorAll('[data-ref^="shape-"]').forEach(s=>{let i=s.dataset.ref===`shape-${t}`;s.classList.toggle("ghost",!i),s.setAttribute("aria-pressed",String(i))}))})})}isBulkSelectMode(){return this.mode==="block"||this.mode==="categories"||this.mode==="channels"&&this.channels?.usesMarqueeSelection()===!0}selectableStatuses(){return this.mode==="block"?["free","not_for_sale"]:this.mode==="select"||this.mode==="categories"||this.mode==="inspect"||this.isBulkSelectMode()||this.mode==="channels"&&this.channels?.canSelect()===!0?["free","held","booked","not_for_sale"]:[]}updateRendererInteraction(){let e=this.isBulkSelectMode();this.renderer?.setManageInteraction({manageMode:!0,organizerStatus:this.mode!=="channels",marqueeSelect:e&&!this.movingMap,marqueeShape:this.marqueeShape,rowLabelSelect:this.rowLabelSelectable(),maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses()}),this.navigation?.update(e,this.mode==="view"),this.updateZoomHint()}handleSeatSelect(e){if(this.mode==="select"&&!this.canSelectObject(e)){this.renderer?.deselect([e.id]),this.syncSelection();return}if(this.mode==="inspect"){let t=this.getSelection().filter(s=>s.id!==e.id).map(s=>s.id);t.length&&this.renderer?.deselect(t)}this.syncSelection()}buildUnitUniverse(e){let t=new Map;for(let i of wt(e))i.type==="table"&&t.set(i.id,i.label);let s=new Map;for(let i of xt(e))if(this.labelToId.set(i.label,i.id),this.labelToSeat.set(i.label,i),this.allIds.push(i.id),t.has(i.rowId)){let o=s.get(i.rowId)??[];o.push(i.id),s.set(i.rowId,o)}for(let[i,o]of s){let a=t.get(i);this.labelToId.has(a)||this.tableChairIds.set(a,o)}for(let i of Re(e))for(let o of St(i))this.labelToId.has(o)||this.gaUnitLabelSet.add(o)}unitTotal(){return this.allIds.length+this.gaUnitLabelSet.size}paintIds(e){let t=this.labelToId.get(e);return t?[t]:this.tableChairIds.get(e)??[]}knownLabels(){return[...this.labelToId.keys(),...this.gaUnitLabelSet]}repaintAll(){let e=this.renderer;if(!e)return;this.allIds.length&&e.setStatus(this.allIds,"free");let t={free:[],held:[],booked:[],not_for_sale:[]};for(let[s,i]of this.status.entries())t[M(i)].push(...this.paintIds(s));["held","booked","not_for_sale"].forEach(s=>{t[s].length&&e.setStatus(t[s],s)})}async connect(){if(this.closed||this.sessionEnded)return;let e;try{if(e=(await this.withAuthRetry(()=>this.api.subscribeTicket(this.key))).protocols,!e.length)throw new Error("manage_subscribe_ticket_missing")}catch(s){this.setLive(!1),this.opts.onError?.(s),this.scheduleReconnect();return}if(this.closed)return;let t;try{t=new WebSocket(this.api.socketUrl(this.key),e)}catch(s){this.opts.onError?.(s),this.scheduleReconnect();return}this.ws=t,this.socketSnapshotSeen=!1,t.onopen=()=>{this.attempt=0,this.setLive(!0),this.resnapshot().then(()=>this.refreshControlRoom()).catch(s=>this.opts.onError?.(s)),this.refreshAvailability()},t.onmessage=s=>this.onMessage(s),t.onclose=()=>{this.ws===t&&(this.ws=null),this.setLive(!1),this.scheduleReconnect()},t.onerror=()=>{try{t.close()}catch{}}}scheduleReconnect(){if(this.closed||this.sessionEnded||this.reconnectTimer)return;let e=Math.min(1e3*2**Math.min(this.attempt++,5),15e3);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}onMessage(e){let t;try{t=JSON.parse(typeof e.data=="string"?e.data:"")}catch{return}if(!t||typeof t!="object")return;this.lastMessageAt=Date.now();let s=t;if((Array.isArray(s.hidden)||Array.isArray(s.closed))&&this.updateEffectiveAvailability(s.hidden,s.closed),s.type==="presence"){typeof s.shoppingSessions=="number"&&typeof s.activeHolds=="number"&&(this.livePresence={at:Date.now(),value:{shoppingSessions:s.shoppingSessions,activeHolds:s.activeHolds}},this.controlRoomSnapshot&&(this.controlRoomSnapshot={...this.controlRoomSnapshot,presence:this.livePresence.value},this.opts.onControlRoom?.(this.controlRoomSnapshot)),this.lastSyncedAt=Date.now(),this.recomputeTallies(),this.paintMonitorInsights());return}if(s.type!=="hidden"){if(s.seats&&typeof s.seats=="object")this.applySocketSnapshot(s.seats,typeof s.default=="string"?s.default:void 0);else if(Array.isArray(s.changes)){let i=[],o=new Map;for(let l of s.changes){let r=["free","held","booked","blocked"].includes(l.status)?l.status:"free",c=this.status.get(l.label)??"free";if(c===r)continue;this.setStatusLabel(l.label,r,c);let d=this.paintIds(l.label);d.length&&(this.renderer?.setStatus(d,M(r)),i.push(...d));let h=this.verbFor(c,r),p=`${h}:${r}`,u=o.get(p)??{labels:[],verb:h,status:r};u.labels.push(l.label),o.set(p,u)}for(let l of o.values()){let r=this.pushActivity(l.labels,l.verb,l.status);r&&this.paintSpatialActivity(r)}o.size&&this.scheduleMonitorRefresh(),i.length&&(this.lastSyncedAt=Date.now(),this.afterPaint());let a=typeof s.bookedValue?.gross=="number"?s.bookedValue.gross:s.revenue?.gross;typeof a=="number"&&Number.isFinite(a)&&this.applyLiveGross(a),this.recomputeTallies()}}}applyLiveGross(e){if(this.liveGross={at:Date.now(),value:e},this.authoritativeGrossRevenue=e,this.revenueStatus="current",this.controlRoomSnapshot){let s={...this.controlRoomSnapshot.bookedValue??this.controlRoomSnapshot.revenue,gross:e};this.controlRoomSnapshot={...this.controlRoomSnapshot,bookedValue:s,revenue:s},this.opts.onControlRoom?.(this.controlRoomSnapshot)}}setStatusLabel(e,t,s=this.status.get(e)??"free"){this.status.set(e,t),s!==t&&(s!=="free"&&(this.counts[s]-=1),t!=="free"&&(this.counts[t]+=1))}applySocketSnapshot(e,t){let s=this.socketSnapshotSeen?this.status:null;if(this.applySnapshot(e,t),this.socketSnapshotSeen=!0,!s)return;let i=new Map;for(let o of new Set([...s.keys(),...this.status.keys()])){let a=s.get(o)??"free",l=this.status.get(o)??"free";if(a===l)continue;let r=this.verbFor(a,l),c=`${r}:${l}`,d=i.get(c)??{labels:[],verb:r,status:l};d.labels.push(o),i.set(c,d)}for(let o of i.values()){let a=this.pushActivity(o.labels,o.verb,o.status);a&&this.paintSpatialActivity(a)}i.size&&this.scheduleMonitorRefresh()}scheduleMonitorRefresh(){this.monitorRefreshTimer||(this.monitorRefreshTimer=setTimeout(()=>{this.monitorRefreshTimer=null,this.closed||this.refreshControlRoom().catch(e=>this.opts.onError?.(e))},150))}async resnapshot(){try{let e=await this.api.objects(this.key);this.applySnapshot(e.seats),this.updateEffectiveAvailability(e.hidden,e.closed),this.lastMessageAt=Date.now()}catch{}}applySnapshot(e,t){let s=o=>["free","held","booked","blocked"].includes(o)?o:"free",i=new Map;if(t!==void 0){let o=s(t);for(let a of this.knownLabels())i.set(a,o)}for(let[o,a]of Object.entries(e))i.set(o,s(a));this.status=i,this.modelVersion+=1,this.recountAll(),this.lastSyncedAt=Date.now(),this.repaintAll(),this.afterPaint(),this.recomputeTallies()}recountAll(){let e={held:0,booked:0,blocked:0};for(let t of this.status.values())t!=="free"&&(e[t]+=1);this.counts=e}setSeatsLocal(e,t){let s=[];for(let i of e)this.setStatusLabel(i,t),s.push(...this.paintIds(i));s.length&&this.renderer?.setStatus(s,M(t)),this.afterPaint(),this.recomputeTallies()}afterPaint(){this.keepLive&&typeof document<"u"&&document.hidden&&this.renderer?.forceDraw()}activityColor(e){return e==="held"?x.held:e==="booked"?x.booked:e==="blocked"?x.blocked:x.free}sectionsForLabels(e){let t=new Set;for(let i of e){let o=this.labelToSeat.get(i);if(!o)continue;let a=this.sectionByObject.get(o.rowId);a&&a!==v&&t.add(a)}let s=[...t];return{ids:s,labels:s.map(i=>this.sectionLabelById.get(i)??i)}}pulseSeatLabels(e,t){let s=this.activityColor(t);for(let i of e.slice(0,Ae)){let o=this.labelToId.get(i);o&&this.renderer?.flashSeat(o,s)}}paintSpatialActivity(e){let t=e.sectionIds??this.sectionsForLabels(e.labels).ids,s=this.renderer?.getFocusedSection()??null;if(this.followLive&&t.length===1&&(e.status==="held"||e.status==="booked")){let o=this.root?.querySelector('[data-ref="followstatus"]');o&&(o.textContent=`Following ${e.labels.length===1?e.labels[0]:`${e.labels.length} seats`} \xB7 ${e.status}`),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=setTimeout(()=>{this.followLiveTimer=null,this.focusActivitySeats(e.labels,t[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(e.labels,e.status)},520)},220);return}if(!s&&t.length){let o=this.activityColor(e.status);for(let a of t.slice(0,$e))this.renderer?.flashSection(a,o);return}(!t.length||s&&t.includes(s))&&this.pulseSeatLabels(e.labels,e.status)}locateSection(e){this.renderer?.focusSection(e)}focusActivitySeats(e,t){this.renderer?.focusSection(t);let s=e.slice(0,Ae).map(r=>this.labelToSeat.get(r)).filter(r=>!!r);if(!s.length)return;let i=s.map(r=>r.x),o=s.map(r=>r.y),a=Math.min(...i),l=Math.min(...o);this.renderer?.focusRegion({x:a-150,y:l-100,width:Math.max(...i)-a+300,height:Math.max(...o)-l+200})}locateActivity(e){let t=this.feed.find(i=>i.id===e);if(!t)return;let s=t.sectionIds??this.sectionsForLabels(t.labels).ids;if(this.followSeatTimer&&clearTimeout(this.followSeatTimer),s.length===1){this.focusActivitySeats(t.labels,s[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(t.labels,t.status)},520);return}this.zoomToFit(),this.followSeatTimer=setTimeout(()=>{if(this.followSeatTimer=null,s.length){let i=this.activityColor(t.status);for(let o of s.slice(0,$e))this.renderer?.flashSection(o,i)}else this.pulseSeatLabels(t.labels,t.status)},280)}showLiveEvent(e){let t=this.els.liveevent;if(!t)return;let s=e.sectionLabels??[],i=s.length===1?s[0]:s.length>1?`${s.length} sections`:e.label,o=e.count===1?"seat":"seats";t.innerHTML=`<span class="slm-liveeventdot" style="background:${this.activityColor(e.status)}"></span>
|
|
729
|
+
<button type="button" class="slm-btn" data-ref="ended-retry">Try again</button>`,t.querySelector('[data-ref="ended-retry"]').addEventListener("click",()=>{this.retrySession()}),e.appendChild(t)}async block(e,t={}){let s=(e??this.selectionLabels()).filter(o=>this.status.get(o)==="free");if(!s.length)return;let i=t.releaseAt??this.releaseAt??void 0;this.setSeatsLocal(s,"blocked");try{await this.api.block(this.key,s,{...t,releaseAt:i}),this.clearSelection(),this.done("block",s,i?`Blocked ${s.length} \u2014 auto-release ${new Date(i).toLocaleString()}.`:`Blocked ${s.length} seat${s.length===1?"":"s"}.`)}catch(o){this.setSeatsLocal(s,"free"),this.toastErr(o instanceof k&&o.status===409?"Some seats were just taken. Try again.":"Couldn't block those seats."),this.opts.onError?.(o)}}async unblock(e){let t=(e??this.selectionLabels()).filter(s=>this.status.get(s)==="blocked");if(t.length){this.setSeatsLocal(t,"free");try{await this.api.unblock(this.key,t),this.clearSelection(),this.done("unblock",t,`Unblocked ${t.length} seat${t.length===1?"":"s"}.`)}catch(s){this.setSeatsLocal(t,"blocked"),this.toastErr("Couldn't unblock those seats."),this.opts.onError?.(s)}}}async unblockAll(){let e=[...this.status.entries()].filter(([,t])=>t==="blocked").map(([t])=>t);if(e.length){this.setSeatsLocal(e,"free");try{let t=await this.api.unblockAll(this.key);this.clearSelection(),this.done("unblockAll",e,`Unblocked ${t.freed} seat${t.freed===1?"":"s"}.`)}catch(t){await this.resnapshot(),this.toastErr("Couldn't mark everything for sale."),this.opts.onError?.(t)}}}async cancelBooking(e,t){let s=e.filter(i=>this.status.get(i)==="booked");if(!(!s.length||!t)){this.setSeatsLocal(s,"free");try{await this.api.unbook(this.key,s,t),this.clearSelection(),this.done("cancelBooking",s,`Released ${s.length} booked unit${s.length===1?"":"s"}.`)}catch(i){this.setSeatsLocal(s,"booked"),this.toastErr("Couldn't release that booked inventory. Check the booking reference."),this.opts.onError?.(i)}}}async setCategory(e,t){let s=this.doc?.categories.find(o=>o.key===e),i=[...new Set(t??this.selectionLabels())].filter(o=>this.labelToSeat.has(o));if(!(!s||!i.length))try{let o=await this.withAuthRetry(()=>this.api.setCategory(this.key,i,e)),a={};for(let l of o.labels){let r=this.labelToSeat.get(l),c=this.labelToId.get(l);r&&(r.categoryKey=e),c&&(a[c]=e)}this.renderer?.setSeatCategories?.(a),this.clearSelection(),this.mode==="categories"&&this.loadCategoryDifferences(),this.done("setCategory",o.labels,`Assigned ${o.labels.length.toLocaleString()} object${o.labels.length===1?"":"s"} to ${s.label??s.key}.`)}catch(o){this.toastErr("Couldn't update those event categories."),this.opts.onError?.(o)}}async setTableBooking(e,t,s={}){let i=[...new Set(e)].filter(Boolean);if(!(!i.length||this.tableBookingSaving)){if(this.inventoryModelVersion!==2){this.toastErr("Table booking controls require inventory model 2 for this event.");return}this.tableBookingSaving=!0,this.mode==="tables"&&this.renderTablesRail();try{let o=await this.withAuthRetry(()=>this.api.setTableBooking(this.key,i,t,s));await this.reloadEventChart(),this.done("setTableBooking",o.tableIds,`Updated ${o.tableIds.length.toLocaleString()} table${o.tableIds.length===1?"":"s"} to ${t==="individual"?"per-chair":t==="whole"?"whole-table":"flexible-group"} booking.`)}catch(o){let a=o instanceof k&&o.code==="table_inventory_in_use";this.toastErr(a?"Release held, booked, or blocked table inventory before changing its booking mode.":"Couldn't update table booking. No table mode was changed."),this.opts.onError?.(o)}finally{this.tableBookingSaving=!1,this.mode==="tables"&&this.renderTablesRail()}}}async reloadEventChart(){let e=await this.withAuthRetry(()=>this.api.chart(this.key));this.inventoryModelVersion=e.event.inventoryModelVersion===2?2:1;let t=await this.organizerAssetUrls.prepareRendererChart(e.doc);this.renderer?.destroy(),this.renderer=null,this.doc=t,this.labelToId.clear(),this.labelToSeat.clear(),this.allIds=[],this.gaUnitLabelSet.clear(),this.tableChairIds.clear(),this.status.clear(),this.counts={held:0,booked:0,blocked:0},this.serverBaseline=null,this.lastSelectionLabels.clear(),this.buildUnitUniverse(t),this.buildRenderer(),this.buildSectionOptions(),this.settleMode(),await Promise.all([this.resnapshot(),this.refreshAvailability()]),this.paintRail()}selectAll(){if(this.mode==="select")return this.selectByLabels([...this.labelToSeat.values()].filter(t=>this.canSelectObject(t)).map(t=>t.label));let e=this.renderer?.selectAllSelectable()??[];return this.syncSelection(),e}selectSection(e){if(!this.renderer)return[];let t=this.renderer.getSelectableInSection(e);return this.renderer.selectByLabels(t.map(s=>s.label)),this.syncSelection(),this.renderer.getSelection()}setFilteredSection(e){let t=e.trim(),s=this.filterableSections().filter(a=>a.label===t);if(!s.length)throw new Error(`Unknown event section: ${e}`);let i=t!==this.filteredSectionLabel;this.filteredSectionLabel=t,this.mode==="filterSections"&&(this.applyFilteredSectionCanvas(s),this.renderFilterSectionsRail());let o=s.map(({id:a,label:l,seatCount:r,zone:c})=>({id:a,label:l,seatCount:r,...c?{zone:c}:{}}));return i&&this.opts.onFilteredSectionChange?.(o),o}focusSection(e){let t=e.trim(),s=this.filterableSections().filter(i=>i.label===t);return!this.renderer||!s.length?[]:(this.frameSections(s),s.map(({id:i,label:o,seatCount:a,zone:l})=>({id:i,label:o,seatCount:a,...l?{zone:l}:{}})))}clearFilteredSection(){let e=this.filteredSectionLabel!==null;this.filteredSectionLabel=null,this.renderer?.setDimmedSections(null),this.renderer?.clearSectionFocus(),this.renderer?.zoomToFit(),this.mode==="filterSections"&&this.renderFilterSectionsRail(),e&&this.opts.onFilteredSectionChange?.([])}getFilteredSections(){return this.filteredSectionLabel?this.filterableSections().filter(e=>e.label===this.filteredSectionLabel).map(({id:e,label:t,seatCount:s,zone:i})=>({id:e,label:t,seatCount:s,...i?{zone:i}:{}})):[]}selectByLabels(e){let t=e;if(this.mode==="select"){let s=new Set(this.selectionLabels()),i=this.selectionCap(),o=[...new Set(e)].filter(l=>!s.has(l)).map(l=>this.labelToSeat.get(l)).filter(l=>!!l&&this.canSelectObject(l)),a=Math.max(0,i-s.size);o.length>a&&this.opts.onSelectionLimit?.(i),t=o.slice(0,a).map(l=>l.label)}return this.renderer?.selectByLabels(t),this.syncSelection(),this.getSelection()}selectObjects(e){return this.selectByLabels(e)}deselectObjects(e){let t=e.map(s=>this.labelToId.get(s)).filter(s=>!!s);return this.renderer?.deselect(t),this.syncSelection(),this.getSelection()}selectCategories(e){let t=new Set(e);return this.selectByLabels([...this.labelToSeat.values()].filter(s=>t.has(s.categoryKey)).map(s=>s.label))}deselectCategories(e){let t=new Set(e);return this.deselectObjects(this.getSelection().filter(s=>t.has(s.categoryKey)).map(s=>s.label))}setSelectableObjects(e){this.opts.selectableObjects=[...e],this.selectableObjectLabels=new Set(e),this.reconcileSelectPolicy()}setUnavailableObjects(e,t){this.opts.unavailableObjectsReason=t;let s=new Set(e),i=[...s].filter(a=>!this.unavailableLabels.has(a)).concat([...this.unavailableLabels].filter(a=>!s.has(a)));if(!i.length)return;if(this.opts.unavailableObjects=[...s],this.unavailableLabels=s,this.renderer){let a=new Map;for(let l of i){let r=this.paintIds(l);if(!r.length)continue;let c=this.renderStatusOf(l,this.status.get(l)??"free");a.set(c,[...a.get(c)??[],...r])}for(let[l,r]of a)this.renderer.setStatus(r,l);this.afterPaint()}let o=this.getSelection().filter(a=>this.isHostUnavailable(a.label));o.length&&(this.renderer?.deselect(o.map(a=>a.id)),this.syncSelection())}setCategoryPrices(e){this.opts.categoryPrices=e,this.renderer?.setCategoryPriceRanges(this.hoverPriceRanges())}hoverPriceRanges(){let e=this.opts.categoryPrices;return e==null?e:Object.fromEntries(Object.entries(e).map(([t,s])=>[t,typeof s=="number"?{min:s,max:s}:{min:s.min,max:s.max}]))}setUnavailableObjectsSelectable(e){this.opts.unavailableObjectsSelectable=e,this.reconcileSelectPolicy()}setObjectSelectable(e){this.opts.isObjectSelectable=e,this.reconcileSelectPolicy()}setMaxSelectedObjects(e){this.assertSelectionOptions(e,this.opts.numberOfPlacesToSelect),this.opts.maxSelectedObjects=e,this.trimSelectionToCap(),this.updateRendererInteraction(),this.syncSelection()}setNumberOfPlacesToSelect(e){this.assertSelectionOptions(this.opts.maxSelectedObjects,e),this.opts.numberOfPlacesToSelect=e,this.selectionWasValid=null,this.trimSelectionToCap(),this.updateRendererInteraction(),this.syncSelection()}getSelectionValidity(){let e=this.opts.numberOfPlacesToSelect;if(e===void 0)return null;let t=this.getSelection(),s=t.length;return{isValid:s===e,count:s,required:e,remaining:Math.max(0,e-s),objects:t}}clearSelection(){this.renderer?.clearSelection(),this.syncSelection()}getSelection(){return this.renderer?.getSelection()??[]}getReport(){return this.api.report(this.key).then(e=>(this.applyReportRevenue(e),e))}getControlRoomSnapshot(e=this.trendWindowMinutes){return this.setTrendWindow(e)}getConnection(){return{status:this.connectionStatus,lastMessageAt:this.lastMessageAt}}getLog(e={}){return this.api.log(this.key,e)}async setHoldTtl(e){try{await this.api.setHoldTtl(this.key,e),this.done("setHoldTtl",[],e?`Hold window set to ${Math.round(e/6e4)} min.`:"Hold window reset.")}catch(t){this.toastErr("Couldn't update the hold window."),this.opts.onError?.(t)}}zoomToFit(){if(this.mode==="filterSections"&&this.filteredSectionLabel){this.clearFilteredSection();return}this.renderer?.clearSectionFocus(),this.renderer?.zoomToFit()}zoomOutStep(){let e=this.renderer;if(!e)return;if(!e.zoomOutLevel)return void e.zoomOut();let t=!!e.getFocusedSection?.();e.zoomOutLevel()==="venue"&&t&&e.clearSectionFocus()}paintMapChrome(){let e=this.renderer;if(!e||!this.els.crumb)return;let t=e.getFocusedSection?.()??null,s=t?e.getMinimapSnapshot?.().sections.find(l=>l.id===t)??null:null,i=e.getFloors?.()??[],o=i.length>1?e.isFloorOverview?.()?"All floors":i.find(l=>l.id===e.getActiveFloorId?.())?.name??null:null,a=this.els.blocklegend;a&&fe(a,{colourBy:this.getColourBy(),seats:e.getRung?.()==="seats",types:this.legendTypes()}),ue(this.els,me({focused:s?{label:s.label,free:s.free,total:s.total}:null,floor:o,seatsRevealed:e.seatsRevealed?.()??!0,atVenueFit:e.atVenueFit?.(),atCeiling:e.canZoomIn?.()===!1||e.seatsPickable?.()===!0}))}sectionTypeKeys(){if(this.typeKeyBySection&&this.typeKeyBase===this.sectionsBase)return this.typeKeyBySection;let e=new Map;for(let t of this.filterableSections()){let s=new Map;for(let o of t.seatLabels){let a=this.labelToSeat.get(o)?.categoryKey;a&&s.set(a,(s.get(a)??0)+1)}let i=null;for(let[o,a]of s)(!i||a>s.get(i))&&(i=o);i&&e.set(t.id,i)}return this.typeKeyBySection=e,this.typeKeyBase=this.sectionsBase,e}sectionTypeTint(e){let t=this.sectionTypeKeys().get(e);return t?this.renderer?.categoryDisplayColor?.(t)??null:null}legendTypes(){let e=new Set;for(let t of this.labelToSeat.values())e.add(t.categoryKey);return(this.doc?.categories??[]).filter(t=>e.has(t.key)).map(t=>({label:t.label,color:this.renderer?.categoryDisplayColor?.(t.key)??t.color}))}refreshBlockPaint(){this.renderer?.refreshBlockPaint?.(),this.minimap?.refreshMinimap()}mapCamera(){return{getViewport:()=>{let e=this.renderer;return!e?.getVisibleWorldRect||!e.getWorldBounds?null:{visible:e.getVisibleWorldRect(),bounds:e.getWorldBounds()}},getMinimapSnapshot:()=>this.renderer?.getMinimapSnapshot?.()??{sections:[],seats:[]},panToWorld:e=>{this.setFollowLive(!1),this.renderer?.panToWorld?.(e)},clearSectionFocus:()=>this.renderer?.clearSectionFocus?.(),focusSection:e=>{this.setFollowLive(!1),this.renderer?.focusSection(e),this.channels?.handleSectionFocus(e)},overview:()=>{this.setFollowLive(!1),this.zoomToFit()},getFloors:()=>this.renderer?.getFloors?.()??[],getActiveFloorId:()=>this.renderer?.getActiveFloorId?.()??"",isFloorOverview:()=>this.renderer?.isFloorOverview?.()??!1,getRenderer:()=>this.renderer}}syncMinimap(){let e=this.els.minimapMount,t=!!this.root?.classList.contains("compact");if(!e||!this.renderer||t){this.minimap?.dispose(),this.minimap=null;return}if(this.minimap){this.minimap.refreshMinimap();return}this.minimap=K({controller:this.mapCamera(),root:()=>this.root,cssVar:s=>this.cssVar(s.replace(/^--sl-/,"--slm-")),focusedSectionLabel:()=>{},tint:s=>this.renderer?.categoryDisplayColor?.(s)||void 0},e),this.minimap.refreshMinimap()}cssVar(e){return this.root?getComputedStyle(this.root).getPropertyValue(e).trim():""}destroy(){if(this.selectObserver?.disconnect(),this.closed=!0,this.minimap?.dispose(),this.minimap=null,this.monitorRefreshTimer&&clearTimeout(this.monitorRefreshTimer),this.monitorRefreshTimer=null,this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.feedTimer&&clearInterval(this.feedTimer),this.toastTimer&&clearTimeout(this.toastTimer),this.liveEventTimer&&clearTimeout(this.liveEventTimer),this.kpiCleanupTimer&&clearTimeout(this.kpiCleanupTimer),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.paintHandle!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.paintHandle),this.paintHandle=null,this.channels?.destroy(),this.channels=null,this.channelsLoading=null,this.tokenRefreshTimer&&clearTimeout(this.tokenRefreshTimer),this.layoutObserver?.disconnect(),this.layoutObserver=null,this.colorSchemeStop?.(),this.colorSchemeStop=null,this.root?.removeEventListener("keydown",this.onKeyDown),this.els.rail?.removeEventListener("click",this.onRailClick),typeof document<"u"&&document.removeEventListener("fullscreenchange",this.onFullscreenChange),this.ws){try{this.ws.close()}catch{}this.ws=null}this.seatHistoryPanel?.destroy(),this.seatHistoryPanel=null,this.activityPanel?.destroy(),this.activityPanel=null,this.navigation?.destroy(),this.navigation=null,this.renderer?.destroy(),this.renderer=null,this.organizerAssetUrls.dispose(),this.root&&this.root.parentNode===this.host&&this.host.removeChild(this.root)}buildRenderer(){if(!this.doc)return;let e=this.isBulkSelectMode();this.renderer=new gt(this.mapHost,{manageMode:!0,organizerGlyph:{apply:ft,clear:vt,isPainted:yt},marqueeSelect:e&&!this.movingMap,marqueeShape:this.marqueeShape,rowLabelSelect:this.rowLabelSelectable(),maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses(),currency:this.currency,onSelect:t=>this.handleSeatSelect(t),onDeselect:()=>this.syncSelection(),onSelectionLimit:t=>this.opts.onSelectionLimit?.(t),onMarquee:()=>this.mode==="select"?this.reconcileSelectPolicy():this.syncSelection(),onGAClick:t=>{if(this.mode!=="select"||!this.opts.onAreaClick||!this.doc)return;let s=Re(this.doc).find(i=>i.id===t);s&&this.opts.onAreaClick({id:s.id,label:s.label,name:s.displayLabel?.trim()||s.label})},onSectionTap:t=>{if(this.mode==="filterSections"){let s=this.filterableSections().find(i=>i.id===t);s&&this.setFilteredSection(s.label);return}this.renderer?.focusSection(t),this.channels?.handleSectionFocus(t)},onViewChange:()=>{this.updateZoomHint(),this.paintMapChrome(),this.minimap?.drawMinimapRect(),this.channels?.handleViewChange()},onFocusedSectionChange:()=>{this.paintMapChrome(),this.minimap?.refreshMinimap()},hoverFacts:t=>this.hoverFactsFor(t),blockPaint:t=>be(t,{rule:this.availabilityRules[t.id],hiddenNow:this.effectiveHidden.has(t.id),closedNow:this.effectiveClosed.has(t.id),colourBy:this.getColourBy(),typeTint:this.sectionTypeTint(t.id)}),openAtSectionsWhenDense:!0}),this.renderer.setCategoryPriceRanges(this.hoverPriceRanges()),this.renderer.setChart(this.themedDoc()),this.chromeClearance=-1,this.applyChromeClearance(),this.repaintAll(),this.applyHeatOverlay(),this.applyMapView(),this.updateZoomHint(),this.minimap?.dispose(),this.minimap=null,this.syncMinimap(),this.paintMapChrome()}hoverFactsFor(e){let t=[...this.labelToSeat.values()].find(p=>p.id===e);if(!t)return null;let s=this.status.get(t.label)??"free",i={free:"Free",held:"Held",booked:"Booked",blocked:"Blocked"},o=s==="free"&&this.isHostUnavailable(t.label),l=[{caption:"Status",value:o?this.opts.unavailableObjectsReason?.trim()||"Unavailable":i[s]}],r=this.channels?.channelNameForLabel(t.label)??null;r&&l.push({caption:"Channel",value:r});let c=this.sectionByObject.get(t.rowId)??v,d=this.doc?.categories.find(p=>p.key===t.categoryKey),h=s==="free"&&!o&&!this.effectiveHidden.has(c)&&!this.effectiveClosed.has(c)&&d?.notForSale!==!0;return l.push({caption:"For sale",value:h?"Yes":s==="free"&&!o?"No":"\u2014"}),l}rowLabelSelectable(){return this.isBulkSelectMode()||this.mode==="select"}marqueeShapeChipsHtml(){let e=(t,s)=>`<button type="button" class="slm-btn${this.marqueeShape===t?"":" ghost"}" data-ref="shape-${t}"
|
|
730
|
+
aria-pressed="${this.marqueeShape===t}" title="${t==="box"?"Drag a rectangle over seats":"Draw a loop around seats"}">${s}</button>`;return`${e("box","Drag box")}${e("lasso","Lasso")}`}wireMarqueeShapeChips(){this.els.rail.querySelectorAll('[data-ref^="shape-"]').forEach(e=>{e.addEventListener("click",()=>{let t=e.dataset.ref==="shape-lasso"?"lasso":"box";t!==this.marqueeShape&&(this.marqueeShape=t,this.updateRendererInteraction(),this.els.rail.querySelectorAll('[data-ref^="shape-"]').forEach(s=>{let i=s.dataset.ref===`shape-${t}`;s.classList.toggle("ghost",!i),s.setAttribute("aria-pressed",String(i))}))})})}isBulkSelectMode(){return this.mode==="block"||this.mode==="categories"||this.mode==="channels"&&this.channels?.usesMarqueeSelection()===!0}selectableStatuses(){return this.mode==="block"?["free","not_for_sale"]:this.mode==="select"||this.mode==="categories"||this.mode==="inspect"||this.isBulkSelectMode()||this.mode==="channels"&&this.channels?.canSelect()===!0?["free","held","booked","not_for_sale"]:[]}updateRendererInteraction(){let e=this.isBulkSelectMode();this.renderer?.setManageInteraction({manageMode:!0,organizerStatus:this.mode!=="channels",marqueeSelect:e&&!this.movingMap,marqueeShape:this.marqueeShape,rowLabelSelect:this.rowLabelSelectable(),maxSelection:this.selectionCap(),selectableStatuses:this.selectableStatuses()}),this.navigation?.update(e,this.mode==="view"),this.updateZoomHint()}handleSeatSelect(e){if(this.mode==="select"&&!this.canSelectObject(e)){this.renderer?.deselect([e.id]),this.syncSelection();return}if(this.mode==="inspect"){let t=this.getSelection().filter(s=>s.id!==e.id).map(s=>s.id);t.length&&this.renderer?.deselect(t)}this.syncSelection()}buildUnitUniverse(e){let t=new Map;for(let i of wt(e))i.type==="table"&&t.set(i.id,i.label);let s=new Map;for(let i of xt(e))if(this.labelToId.set(i.label,i.id),this.labelToSeat.set(i.label,i),this.allIds.push(i.id),t.has(i.rowId)){let o=s.get(i.rowId)??[];o.push(i.id),s.set(i.rowId,o)}for(let[i,o]of s){let a=t.get(i);this.labelToId.has(a)||this.tableChairIds.set(a,o)}for(let i of Re(e))for(let o of St(i))this.labelToId.has(o)||this.gaUnitLabelSet.add(o)}unitTotal(){return this.allIds.length+this.gaUnitLabelSet.size}paintIds(e){let t=this.labelToId.get(e);return t?[t]:this.tableChairIds.get(e)??[]}knownLabels(){return[...this.labelToId.keys(),...this.gaUnitLabelSet]}repaintAll(){let e=this.renderer;if(!e)return;this.allIds.length&&e.setStatus(this.allIds,"free");let t={free:[],held:[],booked:[],not_for_sale:[]};for(let[s,i]of this.status.entries())t[this.renderStatusOf(s,i)].push(...this.paintIds(s));for(let s of this.unavailableLabels)this.status.has(s)||t.held.push(...this.paintIds(s));["held","booked","not_for_sale"].forEach(s=>{t[s].length&&e.setStatus(t[s],s)})}async connect(){if(this.closed||this.sessionEnded)return;let e;try{if(e=(await this.withAuthRetry(()=>this.api.subscribeTicket(this.key))).protocols,!e.length)throw new Error("manage_subscribe_ticket_missing")}catch(s){this.setLive(!1),this.opts.onError?.(s),this.scheduleReconnect();return}if(this.closed)return;let t;try{t=new WebSocket(this.api.socketUrl(this.key),e)}catch(s){this.opts.onError?.(s),this.scheduleReconnect();return}this.ws=t,this.socketSnapshotSeen=!1,t.onopen=()=>{this.attempt=0,this.setLive(!0),this.resnapshot().then(()=>this.refreshControlRoom()).catch(s=>this.opts.onError?.(s)),this.refreshAvailability()},t.onmessage=s=>this.onMessage(s),t.onclose=()=>{this.ws===t&&(this.ws=null),this.setLive(!1),this.scheduleReconnect()},t.onerror=()=>{try{t.close()}catch{}}}scheduleReconnect(){if(this.closed||this.sessionEnded||this.reconnectTimer)return;let e=Math.min(1e3*2**Math.min(this.attempt++,5),15e3);this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},e)}onMessage(e){let t;try{t=JSON.parse(typeof e.data=="string"?e.data:"")}catch{return}if(!t||typeof t!="object")return;this.lastMessageAt=Date.now();let s=t;if((Array.isArray(s.hidden)||Array.isArray(s.closed))&&this.updateEffectiveAvailability(s.hidden,s.closed),s.type==="presence"){typeof s.shoppingSessions=="number"&&typeof s.activeHolds=="number"&&(this.livePresence={at:Date.now(),value:{shoppingSessions:s.shoppingSessions,activeHolds:s.activeHolds}},this.controlRoomSnapshot&&(this.controlRoomSnapshot={...this.controlRoomSnapshot,presence:this.livePresence.value},this.opts.onControlRoom?.(this.controlRoomSnapshot)),this.lastSyncedAt=Date.now(),this.recomputeTallies(),this.paintMonitorInsights());return}if(s.type!=="hidden"){if(s.seats&&typeof s.seats=="object")this.applySocketSnapshot(s.seats,typeof s.default=="string"?s.default:void 0);else if(Array.isArray(s.changes)){let i=[],o=new Map;for(let l of s.changes){let r=["free","held","booked","blocked"].includes(l.status)?l.status:"free",c=this.status.get(l.label)??"free";if(c===r)continue;this.setStatusLabel(l.label,r,c);let d=this.paintIds(l.label);d.length&&(this.renderer?.setStatus(d,this.renderStatusOf(l.label,r)),i.push(...d));let h=this.verbFor(c,r),p=`${h}:${r}`,u=o.get(p)??{labels:[],verb:h,status:r};u.labels.push(l.label),o.set(p,u)}for(let l of o.values()){let r=this.pushActivity(l.labels,l.verb,l.status);r&&this.paintSpatialActivity(r)}o.size&&this.scheduleMonitorRefresh(),i.length&&(this.lastSyncedAt=Date.now(),this.afterPaint());let a=typeof s.bookedValue?.gross=="number"?s.bookedValue.gross:s.revenue?.gross;typeof a=="number"&&Number.isFinite(a)&&this.applyLiveGross(a),this.recomputeTallies()}}}applyLiveGross(e){if(this.liveGross={at:Date.now(),value:e},this.authoritativeGrossRevenue=e,this.revenueStatus="current",this.controlRoomSnapshot){let s={...this.controlRoomSnapshot.bookedValue??this.controlRoomSnapshot.revenue,gross:e};this.controlRoomSnapshot={...this.controlRoomSnapshot,bookedValue:s,revenue:s},this.opts.onControlRoom?.(this.controlRoomSnapshot)}}setStatusLabel(e,t,s=this.status.get(e)??"free"){this.status.set(e,t),s!==t&&(s!=="free"&&(this.counts[s]-=1),t!=="free"&&(this.counts[t]+=1))}applySocketSnapshot(e,t){let s=this.socketSnapshotSeen?this.status:null;if(this.applySnapshot(e,t),this.socketSnapshotSeen=!0,!s)return;let i=new Map;for(let o of new Set([...s.keys(),...this.status.keys()])){let a=s.get(o)??"free",l=this.status.get(o)??"free";if(a===l)continue;let r=this.verbFor(a,l),c=`${r}:${l}`,d=i.get(c)??{labels:[],verb:r,status:l};d.labels.push(o),i.set(c,d)}for(let o of i.values()){let a=this.pushActivity(o.labels,o.verb,o.status);a&&this.paintSpatialActivity(a)}i.size&&this.scheduleMonitorRefresh()}scheduleMonitorRefresh(){this.monitorRefreshTimer||(this.monitorRefreshTimer=setTimeout(()=>{this.monitorRefreshTimer=null,this.closed||this.refreshControlRoom().catch(e=>this.opts.onError?.(e))},150))}async resnapshot(){try{let e=await this.api.objects(this.key);this.applySnapshot(e.seats),this.updateEffectiveAvailability(e.hidden,e.closed),this.lastMessageAt=Date.now()}catch{}}applySnapshot(e,t){let s=o=>["free","held","booked","blocked"].includes(o)?o:"free",i=new Map;if(t!==void 0){let o=s(t);for(let a of this.knownLabels())i.set(a,o)}for(let[o,a]of Object.entries(e))i.set(o,s(a));this.status=i,this.modelVersion+=1,this.recountAll(),this.lastSyncedAt=Date.now(),this.repaintAll(),this.afterPaint(),this.recomputeTallies()}recountAll(){let e={held:0,booked:0,blocked:0};for(let t of this.status.values())t!=="free"&&(e[t]+=1);this.counts=e}setSeatsLocal(e,t){let s=[],i=[];for(let o of e)this.setStatusLabel(o,t),(this.renderStatusOf(o,t)===M(t)?s:i).push(...this.paintIds(o));s.length&&this.renderer?.setStatus(s,M(t)),i.length&&this.renderer?.setStatus(i,"held"),this.afterPaint(),this.recomputeTallies()}afterPaint(){this.keepLive&&typeof document<"u"&&document.hidden&&this.renderer?.forceDraw()}activityColor(e){return e==="held"?x.held:e==="booked"?x.booked:e==="blocked"?x.blocked:x.free}sectionsForLabels(e){let t=new Set;for(let i of e){let o=this.labelToSeat.get(i);if(!o)continue;let a=this.sectionByObject.get(o.rowId);a&&a!==v&&t.add(a)}let s=[...t];return{ids:s,labels:s.map(i=>this.sectionLabelById.get(i)??i)}}pulseSeatLabels(e,t){let s=this.activityColor(t);for(let i of e.slice(0,Ae)){let o=this.labelToId.get(i);o&&this.renderer?.flashSeat(o,s)}}paintSpatialActivity(e){let t=e.sectionIds??this.sectionsForLabels(e.labels).ids,s=this.renderer?.getFocusedSection()??null;if(this.followLive&&t.length===1&&(e.status==="held"||e.status==="booked")){let o=this.root?.querySelector('[data-ref="followstatus"]');o&&(o.textContent=`Following ${e.labels.length===1?e.labels[0]:`${e.labels.length} seats`} \xB7 ${e.status}`),this.followLiveTimer&&clearTimeout(this.followLiveTimer),this.followSeatTimer&&clearTimeout(this.followSeatTimer),this.followLiveTimer=setTimeout(()=>{this.followLiveTimer=null,this.focusActivitySeats(e.labels,t[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(e.labels,e.status)},520)},220);return}if(!s&&t.length){let o=this.activityColor(e.status);for(let a of t.slice(0,$e))this.renderer?.flashSection(a,o);return}(!t.length||s&&t.includes(s))&&this.pulseSeatLabels(e.labels,e.status)}locateSection(e){this.renderer?.focusSection(e)}focusActivitySeats(e,t){this.renderer?.focusSection(t);let s=e.slice(0,Ae).map(r=>this.labelToSeat.get(r)).filter(r=>!!r);if(!s.length)return;let i=s.map(r=>r.x),o=s.map(r=>r.y),a=Math.min(...i),l=Math.min(...o);this.renderer?.focusRegion({x:a-150,y:l-100,width:Math.max(...i)-a+300,height:Math.max(...o)-l+200})}locateActivity(e){let t=this.feed.find(i=>i.id===e);if(!t)return;let s=t.sectionIds??this.sectionsForLabels(t.labels).ids;if(this.followSeatTimer&&clearTimeout(this.followSeatTimer),s.length===1){this.focusActivitySeats(t.labels,s[0]),this.followSeatTimer=setTimeout(()=>{this.followSeatTimer=null,this.pulseSeatLabels(t.labels,t.status)},520);return}this.zoomToFit(),this.followSeatTimer=setTimeout(()=>{if(this.followSeatTimer=null,s.length){let i=this.activityColor(t.status);for(let o of s.slice(0,$e))this.renderer?.flashSection(o,i)}else this.pulseSeatLabels(t.labels,t.status)},280)}showLiveEvent(e){let t=this.els.liveevent;if(!t)return;let s=e.sectionLabels??[],i=s.length===1?s[0]:s.length>1?`${s.length} sections`:e.label,o=e.count===1?"seat":"seats";t.innerHTML=`<span class="slm-liveeventdot" style="background:${this.activityColor(e.status)}"></span>
|
|
720
731
|
<span class="slm-liveeventcopy">${m(i)} \xB7 ${e.count.toLocaleString()} ${o} ${m(e.verb)}</span>
|
|
721
|
-
<span class="slm-liveeventhint">Live</span>`,t.classList.add("on"),this.liveEventTimer&&clearTimeout(this.liveEventTimer),this.liveEventTimer=setTimeout(()=>{this.liveEventTimer=null,t.classList.remove("on"),t.innerHTML=""},2800)}applyReportRevenue(e){this.authoritativeGrossRevenue=e.report.byCategory.reduce((t,s)=>{let i=Number.isFinite(s.bookedValue)?s.bookedValue:s.bookedRevenue;return t+(Number.isFinite(i)?i:0)},0),this.revenueStatus="current",this.recomputeTallies()}async refreshControlRoom(){let e=++this.revenueRequest,t=Date.now();try{let s=await this.api.controlRoom(this.key,this.trendWindowMinutes),i=s.bookedValue??s.revenue??{gross:0,bySection:[]},o=(i.bySection??[]).map(r=>{let c=Number.isFinite(r.bookedValue)?r.bookedValue:r.bookedRevenue;return{...r,bookedValue:c??0,bookedRevenue:c??0}}),a={...i,bySection:o},l={...s,bookedValue:a,revenue:a};if(e===this.revenueRequest){if(this.livePresence&&this.livePresence.at>=t?l={...l,presence:this.livePresence.value}:this.livePresence=null,this.liveGross&&this.liveGross.at>=t){let d={...l.bookedValue,gross:this.liveGross.value};l={...l,bookedValue:d,revenue:d}}else this.liveGross=null;this.controlRoomSnapshot=l,l.activity&&this.seedFeed(l.activity),this.rebaseServerTotals(l),this.lastSyncedAt=Date.now(),this.authoritativeGrossRevenue=l.bookedValue.gross,this.authoritativeCurrency=l.currency,this.currency=l.currency,this.revenueStatus="current",this.recomputeTallies(),this.applyHeatOverlay(),this.paintMonitorInsights(),this.seatHistoryPanel?.refresh();let r=this.getSelection().slice(-1)[0],c=this.els.rail?.querySelector("[data-seat-status]");r&&c&&(c.textContent=this.status.get(r.label)??"free"),this.opts.onControlRoom?.(l)}return l}catch(s){throw e===this.revenueRequest&&(this.revenueStatus="stale",this.recomputeTallies()),s}}rebaseServerTotals(e){let t=e.totals;if(!t||["free","held","booked","blocked"].some(s=>!Number.isFinite(t[s]))){this.serverBaseline=null;return}this.serverBaseline={model:this.modelVersion,server:{free:t.free,held:t.held,booked:t.booked,blocked:t.blocked},client:this.clientTallies()}}clientTallies(){let{held:e,booked:t,blocked:s}=this.counts;return{held:e,booked:t,blocked:s,free:Math.max(0,this.unitTotal()-e-t-s)}}buildTallies(){let e=this.clientTallies(),t=this.serverBaseline?.model===this.modelVersion?this.serverBaseline:null,s=l=>t?Math.max(0,t.server[l]+(e[l]-t.client[l])):e[l],i=this.controlRoomSnapshot?.event?.seatTotal,o={free:s("free"),held:s("held"),booked:s("booked"),blocked:s("blocked"),total:Number.isFinite(i)?i:this.unitTotal(),capacityPct:0,sellThroughPct:0,bookedValue:this.authoritativeGrossRevenue,grossRevenue:this.authoritativeGrossRevenue,bookedValueStatus:this.revenueStatus,revenueStatus:this.revenueStatus,currency:this.currency};o.capacityPct=o.total?Math.round(o.booked/o.total*100):0;let a=o.total-o.blocked;return o.sellThroughPct=a>0?Math.round(o.booked/a*100):0,o}recomputeTallies(){if(!this.closed){if(typeof requestAnimationFrame!="function"){this.flushTallies();return}this.paintHandle===null&&(this.paintHandle=requestAnimationFrame(()=>{this.paintHandle=null,this.flushTallies()}))}}flushTallies(){if(this.closed)return;let e=this.buildTallies();this.paintKpis(e),this.minimap?.refreshMinimap(),this.mode==="view"?(this.paintLegend(e),this.paintMonitorInsights()):this.mode==="inspect"?this.renderInspectRail(this.getSelection()):this.mode==="block"?this.paintSelBar(this.getSelection()):this.mode==="channels"&&this.channels?.handleSelectionChange(),this.opts.onTallies?.(e)}verbFor(e,t){return t==="held"?"held":t==="booked"?"booked":t==="blocked"?"blocked":t==="free"?e==="blocked"?"unblocked":e==="booked"?"cancelled":"available":t}pushActivity(e,t,s,i=Date.now()){let o=e[0];if(!o)return null;let a=this.sectionsForLabels(e),l={id:`${o}:${i}:${Math.random().toString(36).slice(2,6)}`,at:i,label:o,labels:[...e],count:e.length,verb:t,status:s,sectionIds:a.ids,sectionLabels:a.labels};return this.controlRoomSnapshot?.activity||this.feed.unshift(l),this.feed.length>
|
|
732
|
+
<span class="slm-liveeventhint">Live</span>`,t.classList.add("on"),this.liveEventTimer&&clearTimeout(this.liveEventTimer),this.liveEventTimer=setTimeout(()=>{this.liveEventTimer=null,t.classList.remove("on"),t.innerHTML=""},2800)}applyReportRevenue(e){this.authoritativeGrossRevenue=e.report.byCategory.reduce((t,s)=>{let i=Number.isFinite(s.bookedValue)?s.bookedValue:s.bookedRevenue;return t+(Number.isFinite(i)?i:0)},0),this.revenueStatus="current",this.recomputeTallies()}async refreshControlRoom(){let e=++this.revenueRequest,t=Date.now();try{let s=await this.api.controlRoom(this.key,this.trendWindowMinutes),i=s.bookedValue??s.revenue??{gross:0,bySection:[]},o=(i.bySection??[]).map(r=>{let c=Number.isFinite(r.bookedValue)?r.bookedValue:r.bookedRevenue;return{...r,bookedValue:c??0,bookedRevenue:c??0}}),a={...i,bySection:o},l={...s,bookedValue:a,revenue:a};if(e===this.revenueRequest){if(this.livePresence&&this.livePresence.at>=t?l={...l,presence:this.livePresence.value}:this.livePresence=null,this.liveGross&&this.liveGross.at>=t){let d={...l.bookedValue,gross:this.liveGross.value};l={...l,bookedValue:d,revenue:d}}else this.liveGross=null;this.controlRoomSnapshot=l,l.activity&&this.seedFeed(l.activity),this.rebaseServerTotals(l),this.lastSyncedAt=Date.now(),this.authoritativeGrossRevenue=l.bookedValue.gross,this.authoritativeCurrency=l.currency,this.currency=l.currency,this.revenueStatus="current",this.recomputeTallies(),this.applyHeatOverlay(),this.paintMonitorInsights(),this.seatHistoryPanel?.refresh();let r=this.getSelection().slice(-1)[0],c=this.els.rail?.querySelector("[data-seat-status]");r&&c&&(c.textContent=this.status.get(r.label)??"free"),this.opts.onControlRoom?.(l)}return l}catch(s){throw e===this.revenueRequest&&(this.revenueStatus="stale",this.recomputeTallies()),s}}rebaseServerTotals(e){let t=e.totals;if(!t||["free","held","booked","blocked"].some(s=>!Number.isFinite(t[s]))){this.serverBaseline=null;return}this.serverBaseline={model:this.modelVersion,server:{free:t.free,held:t.held,booked:t.booked,blocked:t.blocked},client:this.clientTallies()}}clientTallies(){let{held:e,booked:t,blocked:s}=this.counts;return{held:e,booked:t,blocked:s,free:Math.max(0,this.unitTotal()-e-t-s)}}buildTallies(){let e=this.clientTallies(),t=this.serverBaseline?.model===this.modelVersion?this.serverBaseline:null,s=l=>t?Math.max(0,t.server[l]+(e[l]-t.client[l])):e[l],i=this.controlRoomSnapshot?.event?.seatTotal,o={free:s("free"),held:s("held"),booked:s("booked"),blocked:s("blocked"),total:Number.isFinite(i)?i:this.unitTotal(),capacityPct:0,sellThroughPct:0,bookedValue:this.authoritativeGrossRevenue,grossRevenue:this.authoritativeGrossRevenue,bookedValueStatus:this.revenueStatus,revenueStatus:this.revenueStatus,currency:this.currency};o.capacityPct=o.total?Math.round(o.booked/o.total*100):0;let a=o.total-o.blocked;return o.sellThroughPct=a>0?Math.round(o.booked/a*100):0,o}recomputeTallies(){if(!this.closed){if(typeof requestAnimationFrame!="function"){this.flushTallies();return}this.paintHandle===null&&(this.paintHandle=requestAnimationFrame(()=>{this.paintHandle=null,this.flushTallies()}))}}flushTallies(){if(this.closed)return;let e=this.buildTallies();this.paintKpis(e),this.minimap?.refreshMinimap(),this.mode==="view"?(this.paintLegend(e),this.paintMonitorInsights()):this.mode==="inspect"?this.renderInspectRail(this.getSelection()):this.mode==="block"?this.paintSelBar(this.getSelection()):this.mode==="channels"&&this.channels?.handleSelectionChange(),this.opts.onTallies?.(e)}verbFor(e,t){return t==="held"?"held":t==="booked"?"booked":t==="blocked"?"blocked":t==="free"?e==="blocked"?"unblocked":e==="booked"?"cancelled":"available":t}pushActivity(e,t,s,i=Date.now()){let o=e[0];if(!o)return null;let a=this.sectionsForLabels(e),l={id:`${o}:${i}:${Math.random().toString(36).slice(2,6)}`,at:i,label:o,labels:[...e],count:e.length,verb:t,status:s,sectionIds:a.ids,sectionLabels:a.labels};return this.controlRoomSnapshot?.activity||this.feed.unshift(l),this.feed.length>B&&(this.feed.length=B),this.mode==="view"&&this.paintFeed(),this.showLiveEvent(l),this.opts.onActivity?.(l),l}seedFeed(e){this.controlRoomSnapshot?.activity&&(this.feed=this.feed.filter(i=>i.id.startsWith("log:")));let t={hold:"held",book:"booked",release:"released",expire:"expired",block:"blocked",unblock:"unblocked",unbook:"cancelled"},s={hold:"held",book:"booked",release:"free",expire:"free",block:"blocked",unblock:"free",unbook:"free"};for(let i of e){if(this.feed.some(r=>r.id===`log:${i.id}`))continue;let o=i.labels[0];if(!o)continue;let a=this.sectionsForLabels(i.labels),l={id:`log:${i.id}`,at:i.at,label:o,labels:[...i.labels],count:i.labels.length,verb:t[i.action]??i.action,status:s[i.action]??"free",sectionIds:a.ids,sectionLabels:a.labels};this.feed.push(l),this.opts.onActivity?.(l)}this.feed.sort((i,o)=>o.at-i.at),this.feed.length>B&&(this.feed.length=B),this.mode==="view"&&this.paintFeed()}startFeedClock(){this.feedTimer=setInterval(()=>{this.mode==="view"&&(this.paintFeed(),this.paintMonitorInsights())},1e4)}selectionCap(){return this.mode!=="select"?1e6:this.opts.numberOfPlacesToSelect??this.opts.maxSelectedObjects??1e6}isHostUnavailable(e){return this.unavailableLabels.has(e)}renderStatusOf(e,t){return t==="free"&&this.unavailableLabels.has(e)?"held":M(t)}canSelectObject(e){if(this.isHostUnavailable(e.label))return!1;let t=this.status.get(e.label)??"free",s=this.opts.unavailableObjectsSelectable??!0,i=t==="free"||s||this.selectableObjectLabels.has(e.label);if(!this.opts.isObjectSelectable)return i;try{return this.opts.isObjectSelectable(e,i)===!0}catch(o){return this.opts.onError?.(o),!1}}applyInitialSelection(){this.initialSelectionApplied||this.mode!=="select"||!this.renderer||(this.initialSelectionApplied=!0,this.selectByLabels(this.opts.selectedObjects??[]))}trimSelectionToCap(){if(this.mode!=="select")return;let e=this.getSelection(),t=this.selectionCap();e.length<=t||this.renderer?.deselect(e.slice(t).map(s=>s.id))}reconcileSelectPolicy(){if(this.mode!=="select")return;let e=this.getSelection().filter(t=>!this.canSelectObject(t));e.length&&this.renderer?.deselect(e.map(t=>t.id)),this.trimSelectionToCap(),this.syncSelection()}selectionLabels(){return this.getSelection().map(e=>e.label)}syncSelection(){let e=this.getSelection();this.mode==="block"?this.paintSelBar(e):this.mode==="inspect"?this.renderInspectRail(e):this.mode==="select"?this.paintSelectSelection(e):this.mode==="categories"?this.paintCategorySelection(e):this.mode==="channels"&&this.channels?.handleSelectionChange();let t=new Map(e.map(s=>[s.label,s]));if(this.mode==="select"){for(let[i,o]of t)this.lastSelectionLabels.has(i)||this.opts.onObjectSelected?.(o);for(let i of this.lastSelectionLabels)if(!t.has(i)){let o=this.labelToSeat.get(i);o&&this.opts.onObjectDeselected?.(o)}let s=this.getSelectionValidity();s&&(this.opts.onSelectionValidityChange?.(s),this.selectionWasValid!==s.isValid&&(s.isValid?this.opts.onSelectionValid?.(s):this.opts.onSelectionInvalid?.(s)),this.selectionWasValid=s.isValid)}this.lastSelectionLabels=new Set(t.keys()),this.navigation?.selectionChanged(e.length),this.opts.onSelectionChange?.(e)}buildChrome(){let e=document.createElement("div"),t=this.opts.chrome==="minimal";e.className=t?"slm slm-minimal":"slm",e.tabIndex=0,e.setAttribute("role","region"),e.setAttribute("aria-label",t?"Seat map":"SeatLayer live control room"),e.innerHTML=`
|
|
722
733
|
<div class="slm-bar">
|
|
723
734
|
<div class="slm-modes" data-ref="modes" role="tablist" aria-label="Control room tools">
|
|
724
|
-
${
|
|
735
|
+
${Be.map(o=>`<div class="slm-modegroup" data-group="${o.key}" role="presentation" hidden>
|
|
725
736
|
<span class="slm-modegroup-label" aria-hidden="true">${m(o.label)}</span>
|
|
726
737
|
${o.tools.map(a=>`<button class="slm-mode" role="tab" data-mode="${a.mode}"
|
|
727
738
|
title="${m(a.title)} (${a.shortcut})" aria-keyshortcuts="${a.shortcut}" hidden>${m(a.label)}</button>`).join("")}
|
|
@@ -732,7 +743,7 @@ import{s as _,t as K}from"./chunk-URLBBOTJ.js";import{A as Ve,B as Pe,C as je,D
|
|
|
732
743
|
<div class="slm-bar-actions">
|
|
733
744
|
<button class="slm-barbtn follow" data-ref="follow" aria-label="Follow live" aria-pressed="false"
|
|
734
745
|
title="Stay on the current map view unless enabled">Auto-follow</button>
|
|
735
|
-
<div data-ref="findbar" class="slm-findbar">${
|
|
746
|
+
<div data-ref="findbar" class="slm-findbar">${P({compact:!0})}</div>
|
|
736
747
|
${Me()}
|
|
737
748
|
<button type="button" class="slm-barbtn slm-fullscreen" data-ref="fullscreen" title="Full screen (F)" aria-label="Full screen"
|
|
738
749
|
aria-keyshortcuts="F"><span class="slm-fullscreen-icon" aria-hidden="true">${j.enter}</span><span class="slm-fullscreen-label">Full screen</span></button>
|
|
@@ -836,7 +847,7 @@ import{s as _,t as K}from"./chunk-URLBBOTJ.js";import{A as Ve,B as Pe,C as je,D
|
|
|
836
847
|
<div class="slm-empty">Select a seat on the map.</div>`;return}let s=this.status.get(t.label)??"free",i={free:"Free",held:"Held",booked:"Booked",blocked:"Blocked"},o=this.sectionByObject.get(t.rowId)??v,a=this.sectionLabelById.get(o)??"Other seats",l=this.doc?.categories.find(c=>c.key===t.categoryKey);this.els.rail.innerHTML=`
|
|
837
848
|
<div class="slm-seat-heading"><h2>${m(t.label)}</h2><span data-seat-status>${i[s]}</span></div>
|
|
838
849
|
<p class="slm-note">${m(a)} \xB7 ${m(l?.label??t.categoryKey)}</p>
|
|
839
|
-
<div data-ref="seat-history"></div>`;let r=this.els.rail.querySelector('[data-ref="seat-history"]');this.seatHistoryPanel=new C(r,(c,d)=>this.withAuthRetry(()=>this.api.seatHistory(this.key,t.label,c,d)))}async refreshAvailability(){try{let e=await this.withAuthRetry(()=>this.api.availability(this.key));this.availabilityRules=e.rules??{},this.effectiveClosed=new Set(
|
|
850
|
+
<div data-ref="seat-history"></div>`;let r=this.els.rail.querySelector('[data-ref="seat-history"]');this.seatHistoryPanel=new C(r,(c,d)=>this.withAuthRetry(()=>this.api.seatHistory(this.key,t.label,c,d)))}async refreshAvailability(){try{let e=await this.withAuthRetry(()=>this.api.availability(this.key));this.availabilityRules=e.rules??{},this.effectiveClosed=new Set(V(this.availabilityRules)),this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment()}catch(e){this.opts.onError?.(e)}}async withAuthRetry(e){try{return await e()}catch(t){if(t instanceof k&&t.status===401&&this.opts.onTokenRefresh&&!this.tokenRefreshInFlight){if(await this.rotateToken(),this.sessionEnded)throw t;return e()}throw t instanceof k&&t.status===401&&!this.opts.onTokenRefresh&&this.endSession(),t}}updateEffectiveAvailability(e,t){let s=!1;Array.isArray(e)&&(this.effectiveHidden=new Set(e.filter(i=>typeof i=="string")),s=!0),Array.isArray(t)&&(this.effectiveClosed=new Set(t.filter(i=>typeof i=="string")),s=!0),s&&(this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment())}applySectionCanvasTreatment(){this.renderer&&(this.refreshBlockPaint(),this.mode==="sections"?(this.renderer.setDimmedSections([...this.effectiveHidden]),this.renderer.setClosedSections([...this.effectiveClosed])):this.mode==="filterSections"&&this.filteredSectionLabel?this.applyFilteredSectionCanvas():(this.renderer.setDimmedSections(null),this.renderer.setClosedSections(null)))}sectionRowsInput(){return{sectionsBase:this.sectionsBase,doc:this.doc,availabilityRules:this.availabilityRules,effectiveHidden:this.effectiveHidden,effectiveClosed:this.effectiveClosed}}renderSectionsRail(){let{rows:e,hiddenSections:t,closedSections:s}=H(this.sectionRowsInput());if(!e.length){this.els.rail.innerHTML=`
|
|
840
851
|
${this.railHeader("Sections","event","Draw sections or zones in the designer to schedule availability per area. This chart has none yet.")}
|
|
841
852
|
<div class="slm-empty">No sections on this chart.</div>`;return}let i=[];t&&i.push(`${t} hidden`),s&&i.push(`${s} closed`);let o=i.length?i.join(" \xB7 "):"All sections open and on sale",a=t>0||s>0;this.els.rail.innerHTML=`
|
|
842
853
|
${this.railHeader("Sections","event","Decide when each zone or section goes on sale for this event. Keep it hidden, reveal it at a set time, or <b>auto-reveal once the rest sells past a threshold</b>. Hidden seats vanish for buyers; closed seats stay on the map (flat grey) but can't be bought.")}
|
|
@@ -848,7 +859,7 @@ import{s as _,t as K}from"./chunk-URLBBOTJ.js";import{A as Ve,B as Pe,C as je,D
|
|
|
848
859
|
<div class="slm-availcallout">
|
|
849
860
|
<span class="slm-availstar" aria-hidden="true">\u2726</span>
|
|
850
861
|
<p><b>Auto-reveal at % sold</b> is demand-triggered release: the balcony opens itself the moment the stalls cross the threshold \u2014 no one has to be watching.</p>
|
|
851
|
-
</div>`,this.wireSectionRail(),this.applySectionCanvasTreatment()}wireSectionRail(){let e=this.els.rail;e&&(e.querySelectorAll("[data-avail-id]").forEach(t=>{t.addEventListener("click",()=>this.setSectionMode(t.dataset.availId,t.dataset.availValue))}),e.querySelectorAll("[data-avail-picker]").forEach(t=>{t.querySelector("summary").addEventListener("click",s=>{this.availabilitySaving&&s.preventDefault(),e.querySelectorAll("[data-avail-picker]").forEach(i=>{i!==t&&(i.open=!1)})}),t.addEventListener("focusout",s=>{t.contains(s.relatedTarget)||(t.open=!1)}),t.addEventListener("keydown",s=>{if(s.key==="Escape"&&(t.open=!1,t.querySelector("summary").focus(),s.preventDefault()),s.key==="ArrowDown"||s.key==="ArrowUp"){if(this.availabilitySaving)return;s.preventDefault(),t.open=!0;let i=[...t.querySelectorAll("button")],o=i.indexOf(document.activeElement);i[(o+(s.key==="ArrowDown"?1:i.length-1)+i.length)%i.length]?.focus()}})}),e.querySelectorAll("[data-avail-reveal]").forEach(t=>{t.addEventListener("change",()=>{let s=new Date(t.value).getTime();Number.isFinite(s)&&this.setSectionRulePatch(t.dataset.availReveal,{revealAt:s})})}),e.querySelectorAll("[data-avail-pct]").forEach(t=>{t.addEventListener("change",()=>{let s=Math.max(1,Math.min(100,Number(t.value)||0));this.setSectionRulePatch(t.dataset.availPct,{thresholdPct:s})})}))}setSectionMode(e,t){let s=
|
|
862
|
+
</div>`,this.wireSectionRail(),this.applySectionCanvasTreatment()}wireSectionRail(){let e=this.els.rail;e&&(e.querySelectorAll("[data-avail-id]").forEach(t=>{t.addEventListener("click",()=>this.setSectionMode(t.dataset.availId,t.dataset.availValue))}),e.querySelectorAll("[data-avail-picker]").forEach(t=>{t.querySelector("summary").addEventListener("click",s=>{this.availabilitySaving&&s.preventDefault(),e.querySelectorAll("[data-avail-picker]").forEach(i=>{i!==t&&(i.open=!1)})}),t.addEventListener("focusout",s=>{t.contains(s.relatedTarget)||(t.open=!1)}),t.addEventListener("keydown",s=>{if(s.key==="Escape"&&(t.open=!1,t.querySelector("summary").focus(),s.preventDefault()),s.key==="ArrowDown"||s.key==="ArrowUp"){if(this.availabilitySaving)return;s.preventDefault(),t.open=!0;let i=[...t.querySelectorAll("button")],o=i.indexOf(document.activeElement);i[(o+(s.key==="ArrowDown"?1:i.length-1)+i.length)%i.length]?.focus()}})}),e.querySelectorAll("[data-avail-reveal]").forEach(t=>{t.addEventListener("change",()=>{let s=new Date(t.value).getTime();Number.isFinite(s)&&this.setSectionRulePatch(t.dataset.availReveal,{revealAt:s})})}),e.querySelectorAll("[data-avail-pct]").forEach(t=>{t.addEventListener("change",()=>{let s=Math.max(1,Math.min(100,Number(t.value)||0));this.setSectionRulePatch(t.dataset.availPct,{thresholdPct:s})})}))}setSectionMode(e,t){let s=H(this.sectionRowsInput()).rows.find(l=>l.id===e),i=s?.seatLabels??this.availabilityRules[e]?.labels??[],o={...this.availabilityRules},a=G(t,i,this.availabilityRules[e]);if(a?o[e]=a:delete o[e],s?.kind==="zone"&&this.sectionsBase)for(let l of this.sectionsBase.sections)l.zone===e&&delete o[l.id];this.persistAvailability(o)}setSectionRulePatch(e,t){let s=this.availabilityRules[e];if(!s)return;let o=H(this.sectionRowsInput()).rows.find(a=>a.id===e)?.seatLabels??s.labels??[];this.persistAvailability({...this.availabilityRules,[e]:{...s,...t,labels:o}})}async persistAvailability(e){let t=this.availabilityRules;this.availabilityRules=e,this.availabilitySaving=!0,this.mode==="sections"&&this.renderSectionsRail();try{let s=await this.withAuthRetry(()=>this.api.setAvailability(this.key,e));this.availabilityRules=s.rules,this.effectiveHidden=new Set(s.hidden),this.effectiveClosed=new Set(V(s.rules)),this.availabilitySaving=!1,this.mode==="sections"&&this.renderSectionsRail(),this.applySectionCanvasTreatment()}catch(s){this.availabilityRules=t,this.availabilitySaving=!1,this.mode==="sections"&&this.renderSectionsRail(),this.toastErr("Couldn't update availability. Try again."),this.opts.onError?.(s)}}paintLegend(e){this.els.legend&&(this.els.legend.innerHTML=Q.map(t=>`<div class="slm-legrow"><span class="slm-legdot" style="background:${t.color}"></span>
|
|
852
863
|
<span class="slm-leglabel">${t.label}</span><span class="slm-legcount">${e[t.key].toLocaleString()}</span></div>`).join(""))}paintFeed(){this.activityPanel?.update(this.feed)}renderBlockRail(){let e=this.toolChooser(),t=this.sectionOptions.map(l=>`<option value="${m(l.id)}">${m(l.label)}</option>`).join("");this.els.rail.innerHTML=`
|
|
853
864
|
<div class="slm-monitor-tabs" role="tablist" aria-label="Blocking tools"><button role="tab" data-block-tab="edit" aria-selected="${!this.blockBrowse}">Block seats</button><button role="tab" data-block-tab="browse" aria-selected="${this.blockBrowse}">Find blocked</button></div>
|
|
854
865
|
<p class="slm-note">${X}</p>
|
|
@@ -892,5 +903,5 @@ import{s as _,t as K}from"./chunk-URLBBOTJ.js";import{A as Ve,B as Pe,C as je,D
|
|
|
892
903
|
<button class="slm-btn ghost" data-ref="markall" style="width:100%" disabled>Put all blocked seats on sale</button>
|
|
893
904
|
<p class="slm-note slm-allnote" data-ref="markallnote">For a full reset only. You will be asked to confirm.</p>
|
|
894
905
|
</div></details>
|
|
895
|
-
`,this.els.rail.querySelectorAll("[data-block-tab]").forEach(l=>l.addEventListener("click",()=>{this.blockBrowse=l.dataset.blockTab==="browse",this.renderBlockRail()}));let s=l=>this.els.rail.querySelector(`[data-ref="${l}"]`);this.els.selnum=s("selnum"),this.els.doblock=s("doblock"),this.els.dounblock=s("dounblock"),this.els.selmeta=s("selmeta"),this.els.blockedcount=s("blockedcount"),this.els.blockedshowing=s("blockedshowing"),this.els.blockedlist=s("blockedlist"),this.els.selblocked=s("selblocked"),this.els.markall=s("markall"),this.els.markallnote=s("markallnote"),s("doblock").addEventListener("click",()=>{this.block()}),s("dounblock").addEventListener("click",()=>{this.unblock()}),s("selall").addEventListener("click",()=>this.selectAll()),s("clearsel").addEventListener("click",()=>this.clearSelection()),s("markall").addEventListener("click",()=>this.confirmUnblockAll()),e.wire(this.els.rail),this.wireMarqueeShapeChips();let i=s("blockedsearch"),o=s("blockedsection");i.value=this.blockedQuery,o.value=this.blockedSection,i.addEventListener("input",()=>{this.blockedQuery=i.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),o.addEventListener("change",()=>{this.blockedSection=o.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),s("selblocked").addEventListener("click",()=>{this.toggleLabels(this.filteredBlockedSeats().map(l=>l.label))}),s("blockedlist").addEventListener("click",l=>{let r=l.target,c=r.closest("[data-block-seat-find]");if(c?.dataset.blockSeatFind){let u=this.labelToSeat.get(c.dataset.blockSeatFind);u&&(this.setFollowLive(!1),this.focusActivitySeats([u.label],this.sectionByObject.get(u.rowId)??v));return}let d=r.closest("[data-block-locate]"),h=r.closest("[data-block-group]");if(d||h){let u=d?.dataset.blockLocate??h?.dataset.blockGroup,g=this.filteredBlockedSeats().filter(f=>f.rowId===u);d&&g.length&&(this.setFollowLive(!1),this.focusActivitySeats(g.map(f=>f.label),this.sectionByObject.get(g[0].rowId)??v)),h&&this.toggleLabels(g.map(f=>f.label));return}let p=r.closest("[data-blocked-label]");p?.dataset.blockedLabel?this.toggleLabels([p.dataset.blockedLabel]):r.closest("[data-blocked-more]")&&(this.blockedResultLimit+=100,this.paintBlockedInventory())});let a=s("release");a.addEventListener("change",()=>{let l=a.value?new Date(a.value).getTime():NaN;this.releaseAt=Number.isFinite(l)&&l>Date.now()?l:null;let r=s("releasenote");r.textContent=this.releaseAt?`New blocks auto-release ${new Date(this.releaseAt).toLocaleString()}.`:a.value?"Pick a time in the future.":"Leave empty to block permanently."}),this.paintSelBar(this.getSelection())}toggleLabels(e){if(!this.renderer)return;let t=e.filter(o=>this.labelToSeat.has(o)&&this.isBlockSelectable(o));if(!t.length)return;let s=new Set(this.selectionLabels());if(t.every(o=>s.has(o))){let o=t.map(a=>this.labelToId.get(a)).filter(a=>!!a);this.renderer.deselect(o)}else this.renderer.selectByLabels(t);this.syncSelection()}isBlockSelectable(e){let t=this.status.get(e)??"free";return t==="free"||t==="blocked"}paintSelBar(e){if(!this.els.selnum)return;this.els.selnum.textContent=e.length.toLocaleString();let t=e.filter(a=>(this.status.get(a.label)??"free")==="free").length,s=e.filter(a=>this.status.get(a.label)==="blocked").length;this.els.selmeta.textContent=e.length?`${t.toLocaleString()} available \xB7 ${s.toLocaleString()} blocked`:"selected";let i=this.els.doblock,o=this.els.dounblock;i.disabled=t===0,o.disabled=s===0,i.textContent=t?`Block ${t.toLocaleString()}`:"Block selected",o.textContent=s?`Put ${s.toLocaleString()} on sale`:"Put back on sale",this.paintBlockedInventory()}filteredBlockedSeats(){let e=this.blockedQuery.trim().toLocaleLowerCase(),t=[];for(let[s,i]of this.labelToSeat.entries()){if(this.status.get(s)!=="blocked")continue;let o=this.sectionByObject.get(i.rowId)??v;if(!(this.blockedSection&&o!==this.blockedSection)){if(e){let a=this.doc?.categories.find(h=>h.key===i.categoryKey)?.label??i.categoryKey,l=this.sectionLabelById.get(o)??"Other seats",r=this.doc?.objects.find(h=>h.id===i.rowId),c=r?.type==="row"||r?.type==="table"?r.label:"";if(!`${s} ${a} ${l} ${c}`.toLocaleLowerCase().includes(e))continue}t.push(i)}}return t.sort((s,i)=>s.label.localeCompare(i.label,void 0,{numeric:!0,sensitivity:"base"}))}paintBlockedInventory(){if(!this.els.blockedlist)return;let e=[...this.status.entries()].filter(([,h])=>h==="blocked").length,t=this.filteredBlockedSeats(),s=t.slice(0,this.blockedResultLimit),i=new Set(this.selectionLabels()),o=t.filter(h=>i.has(h.label)).length,a=t.length>0&&o===t.length;this.els.blockedcount.textContent=e.toLocaleString(),this.els.blockedshowing.textContent=t.length?`Showing ${s.length.toLocaleString()} of ${t.length.toLocaleString()}`:e?"No matches":"No blocked seats";let l=this.els.selblocked;l.disabled=t.length===0,l.textContent=a?`Remove ${t.length.toLocaleString()} results`:`Select ${t.length.toLocaleString()} results`;let r=new Map;for(let h of t){let p=r.get(h.rowId)??[];p.push(h),r.set(h.rowId,p)}this.els.blockedshowing.textContent=`${t.length.toLocaleString()} seats \xB7 ${r.size} rows`,this.els.blockedlist.innerHTML=[...r.entries()].slice(0,this.blockedResultLimit).map(([h,p])=>{let u=this.sectionByObject.get(h)??v,g=this.sectionLabelById.get(u)??"Other seats",f=this.doc?.objects.find(y=>y.id===h),b=f&&"label"in f?f.label:p[0].label;return`<div class="slm-block-group"><div class="slm-block-grouphead"><button type="button" data-block-locate="${m(h)}" title="Show this row and nearby seats on the map"><b>${m(b)}</b><small>${m(g)} \xB7 ${p.length} blocked</small></button><button type="button" data-block-group="${m(h)}">Select row</button></div>
|
|
896
|
-
<details><summary>Choose seats</summary>${p.map(y=>`<div class="slm-block-seatline"><button type="button" class="slm-blockeditem${i.has(y.label)?" on":""}" data-blocked-label="${m(y.label)}" aria-pressed="${i.has(y.label)}"><span class="slm-blockedcheck" aria-hidden="true">\u2713</span><span>${m(y.label)}</span></button><button type="button" data-block-seat-find="${m(y.label)}" aria-label="Show ${m(y.label)} and nearby seats">Show</button></div>`).join("")}</details></div>`}).join("")||'<div class="slm-blockedempty">No blocked seats match.</div>',r.size>this.blockedResultLimit&&(this.els.blockedlist.innerHTML+="<button data-blocked-more>Show more rows</button>");let c=this.els.markall,d=c.dataset.confirm==="true";c.disabled=e===0,c.textContent=d?`Confirm: put all ${e.toLocaleString()} on sale`:`Put all ${e.toLocaleString()} blocked seats on sale`}confirmUnblockAll(){let e=this.els.markall;if(!(!e||e.disabled)){if(e.dataset.confirm==="true"){this.resetUnblockAllConfirm(),this.unblockAll();return}e.dataset.confirm="true",e.classList.add("danger"),this.els.markallnote.textContent="This changes every blocked seat. Click the red button again to confirm.",this.paintBlockedInventory(),this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.unblockAllConfirmTimer=setTimeout(()=>this.resetUnblockAllConfirm(),6e3)}}resetUnblockAllConfirm(){this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.unblockAllConfirmTimer=null;let e=this.els.markall;e&&(delete e.dataset.confirm,e.classList.remove("danger"),this.els.markallnote&&(this.els.markallnote.textContent="For a full reset only. You will be asked to confirm."),this.paintBlockedInventory())}done(e,t,s){if(this.toastOk(s),t.length){let i=e==="block"?this.pushActivity(t,"blocked","blocked"):e==="unblock"||e==="unblockAll"?this.pushActivity(t,"unblocked","free"):e==="cancelBooking"?this.pushActivity(t,"cancelled","free"):null;i&&this.paintSpatialActivity(i)}e!=="setHoldTtl"&&this.refreshControlRoom().catch(i=>this.opts.onError?.(i)),this.opts.onActionComplete?.({action:e,labels:t,count:t.length})}toastOk(e){this.toast(e,"ok")}toastErr(e){this.toast(e,"err")}toast(e,t){let s=this.els.toast;s&&(s.textContent=e,s.className=`slm-toast on ${t}`,this.toastTimer&&clearTimeout(this.toastTimer),this.toastTimer=setTimeout(()=>{s.className="slm-toast"},3200))}fail(e){this.opts.onError?.(e),this.els.rail&&(this.els.rail.innerHTML=`<div class="slm-empty">Couldn't load this event. Check the event key and token.</div>`)}};export{Xe as ACCESS_LINK_DEFAULTS,at as ChannelsMode,
|
|
906
|
+
`,this.els.rail.querySelectorAll("[data-block-tab]").forEach(l=>l.addEventListener("click",()=>{this.blockBrowse=l.dataset.blockTab==="browse",this.renderBlockRail()}));let s=l=>this.els.rail.querySelector(`[data-ref="${l}"]`);this.els.selnum=s("selnum"),this.els.doblock=s("doblock"),this.els.dounblock=s("dounblock"),this.els.selmeta=s("selmeta"),this.els.blockedcount=s("blockedcount"),this.els.blockedshowing=s("blockedshowing"),this.els.blockedlist=s("blockedlist"),this.els.selblocked=s("selblocked"),this.els.markall=s("markall"),this.els.markallnote=s("markallnote"),s("doblock").addEventListener("click",()=>{this.block()}),s("dounblock").addEventListener("click",()=>{this.unblock()}),s("selall").addEventListener("click",()=>this.selectAll()),s("clearsel").addEventListener("click",()=>this.clearSelection()),s("markall").addEventListener("click",()=>this.confirmUnblockAll()),e.wire(this.els.rail),this.wireMarqueeShapeChips();let i=s("blockedsearch"),o=s("blockedsection");i.value=this.blockedQuery,o.value=this.blockedSection,i.addEventListener("input",()=>{this.blockedQuery=i.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),o.addEventListener("change",()=>{this.blockedSection=o.value,this.blockedResultLimit=100,this.paintBlockedInventory()}),s("selblocked").addEventListener("click",()=>{this.toggleLabels(this.filteredBlockedSeats().map(l=>l.label))}),s("blockedlist").addEventListener("click",l=>{let r=l.target,c=r.closest("[data-block-seat-find]");if(c?.dataset.blockSeatFind){let u=this.labelToSeat.get(c.dataset.blockSeatFind);u&&(this.setFollowLive(!1),this.focusActivitySeats([u.label],this.sectionByObject.get(u.rowId)??v));return}let d=r.closest("[data-block-locate]"),h=r.closest("[data-block-group]");if(d||h){let u=d?.dataset.blockLocate??h?.dataset.blockGroup,g=this.filteredBlockedSeats().filter(f=>f.rowId===u);d&&g.length&&(this.setFollowLive(!1),this.focusActivitySeats(g.map(f=>f.label),this.sectionByObject.get(g[0].rowId)??v)),h&&this.toggleLabels(g.map(f=>f.label));return}let p=r.closest("[data-blocked-label]");p?.dataset.blockedLabel?this.toggleLabels([p.dataset.blockedLabel]):r.closest("[data-blocked-more]")&&(this.blockedResultLimit+=100,this.paintBlockedInventory())});let a=s("release");a.addEventListener("change",()=>{let l=a.value?new Date(a.value).getTime():NaN;this.releaseAt=Number.isFinite(l)&&l>Date.now()?l:null;let r=s("releasenote");r.textContent=this.releaseAt?`New blocks auto-release ${new Date(this.releaseAt).toLocaleString()}.`:a.value?"Pick a time in the future.":"Leave empty to block permanently."}),this.paintSelBar(this.getSelection())}toggleLabels(e){if(!this.renderer)return;let t=e.filter(o=>this.labelToSeat.has(o)&&this.isBlockSelectable(o));if(!t.length)return;let s=new Set(this.selectionLabels());if(t.every(o=>s.has(o))){let o=t.map(a=>this.labelToId.get(a)).filter(a=>!!a);this.renderer.deselect(o)}else this.renderer.selectByLabels(t);this.syncSelection()}isBlockSelectable(e){if(this.isHostUnavailable(e))return!1;let t=this.status.get(e)??"free";return t==="free"||t==="blocked"}paintSelBar(e){if(!this.els.selnum)return;this.els.selnum.textContent=e.length.toLocaleString();let t=e.filter(a=>(this.status.get(a.label)??"free")==="free").length,s=e.filter(a=>this.status.get(a.label)==="blocked").length;this.els.selmeta.textContent=e.length?`${t.toLocaleString()} available \xB7 ${s.toLocaleString()} blocked`:"selected";let i=this.els.doblock,o=this.els.dounblock;i.disabled=t===0,o.disabled=s===0,i.textContent=t?`Block ${t.toLocaleString()}`:"Block selected",o.textContent=s?`Put ${s.toLocaleString()} on sale`:"Put back on sale",this.paintBlockedInventory()}filteredBlockedSeats(){let e=this.blockedQuery.trim().toLocaleLowerCase(),t=[];for(let[s,i]of this.labelToSeat.entries()){if(this.status.get(s)!=="blocked")continue;let o=this.sectionByObject.get(i.rowId)??v;if(!(this.blockedSection&&o!==this.blockedSection)){if(e){let a=this.doc?.categories.find(h=>h.key===i.categoryKey)?.label??i.categoryKey,l=this.sectionLabelById.get(o)??"Other seats",r=this.doc?.objects.find(h=>h.id===i.rowId),c=r?.type==="row"||r?.type==="table"?r.label:"";if(!`${s} ${a} ${l} ${c}`.toLocaleLowerCase().includes(e))continue}t.push(i)}}return t.sort((s,i)=>s.label.localeCompare(i.label,void 0,{numeric:!0,sensitivity:"base"}))}paintBlockedInventory(){if(!this.els.blockedlist)return;let e=[...this.status.entries()].filter(([,h])=>h==="blocked").length,t=this.filteredBlockedSeats(),s=t.slice(0,this.blockedResultLimit),i=new Set(this.selectionLabels()),o=t.filter(h=>i.has(h.label)).length,a=t.length>0&&o===t.length;this.els.blockedcount.textContent=e.toLocaleString(),this.els.blockedshowing.textContent=t.length?`Showing ${s.length.toLocaleString()} of ${t.length.toLocaleString()}`:e?"No matches":"No blocked seats";let l=this.els.selblocked;l.disabled=t.length===0,l.textContent=a?`Remove ${t.length.toLocaleString()} results`:`Select ${t.length.toLocaleString()} results`;let r=new Map;for(let h of t){let p=r.get(h.rowId)??[];p.push(h),r.set(h.rowId,p)}this.els.blockedshowing.textContent=`${t.length.toLocaleString()} seats \xB7 ${r.size} rows`,this.els.blockedlist.innerHTML=[...r.entries()].slice(0,this.blockedResultLimit).map(([h,p])=>{let u=this.sectionByObject.get(h)??v,g=this.sectionLabelById.get(u)??"Other seats",f=this.doc?.objects.find(y=>y.id===h),b=f&&"label"in f?f.label:p[0].label;return`<div class="slm-block-group"><div class="slm-block-grouphead"><button type="button" data-block-locate="${m(h)}" title="Show this row and nearby seats on the map"><b>${m(b)}</b><small>${m(g)} \xB7 ${p.length} blocked</small></button><button type="button" data-block-group="${m(h)}">Select row</button></div>
|
|
907
|
+
<details><summary>Choose seats</summary>${p.map(y=>`<div class="slm-block-seatline"><button type="button" class="slm-blockeditem${i.has(y.label)?" on":""}" data-blocked-label="${m(y.label)}" aria-pressed="${i.has(y.label)}"><span class="slm-blockedcheck" aria-hidden="true">\u2713</span><span>${m(y.label)}</span></button><button type="button" data-block-seat-find="${m(y.label)}" aria-label="Show ${m(y.label)} and nearby seats">Show</button></div>`).join("")}</details></div>`}).join("")||'<div class="slm-blockedempty">No blocked seats match.</div>',r.size>this.blockedResultLimit&&(this.els.blockedlist.innerHTML+="<button data-blocked-more>Show more rows</button>");let c=this.els.markall,d=c.dataset.confirm==="true";c.disabled=e===0,c.textContent=d?`Confirm: put all ${e.toLocaleString()} on sale`:`Put all ${e.toLocaleString()} blocked seats on sale`}confirmUnblockAll(){let e=this.els.markall;if(!(!e||e.disabled)){if(e.dataset.confirm==="true"){this.resetUnblockAllConfirm(),this.unblockAll();return}e.dataset.confirm="true",e.classList.add("danger"),this.els.markallnote.textContent="This changes every blocked seat. Click the red button again to confirm.",this.paintBlockedInventory(),this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.unblockAllConfirmTimer=setTimeout(()=>this.resetUnblockAllConfirm(),6e3)}}resetUnblockAllConfirm(){this.unblockAllConfirmTimer&&clearTimeout(this.unblockAllConfirmTimer),this.unblockAllConfirmTimer=null;let e=this.els.markall;e&&(delete e.dataset.confirm,e.classList.remove("danger"),this.els.markallnote&&(this.els.markallnote.textContent="For a full reset only. You will be asked to confirm."),this.paintBlockedInventory())}done(e,t,s){if(this.toastOk(s),t.length){let i=e==="block"?this.pushActivity(t,"blocked","blocked"):e==="unblock"||e==="unblockAll"?this.pushActivity(t,"unblocked","free"):e==="cancelBooking"?this.pushActivity(t,"cancelled","free"):null;i&&this.paintSpatialActivity(i)}e!=="setHoldTtl"&&this.refreshControlRoom().catch(i=>this.opts.onError?.(i)),this.opts.onActionComplete?.({action:e,labels:t,count:t.length})}toastOk(e){this.toast(e,"ok")}toastErr(e){this.toast(e,"err")}toast(e,t){let s=this.els.toast;s&&(s.textContent=e,s.className=`slm-toast on ${t}`,this.toastTimer&&clearTimeout(this.toastTimer),this.toastTimer=setTimeout(()=>{s.className="slm-toast"},3200))}fail(e){this.opts.onError?.(e),this.els.rail&&(this.els.rail.innerHTML=`<div class="slm-empty">Couldn't load this event. Check the event key and token.</div>`)}};export{Xe as ACCESS_LINK_DEFAULTS,at as ChannelsMode,O as ManageApi,k as ManageApiError,ze as PUBLIC_CHANNEL_ID,Ie as PUBLIC_CHANNEL_NAME,q as SeatManager,Ge as accessIntentDescription,We as accessIntentLabel,Ue as accessLine,Qe as accessLinkBadge,tt as accessLinkErrorCopy,Je as accessLinkIsLive,et as accessLinkPolicyLines,_e as bucketRows,ot as bucketRowsHtml,st as dropReviewRows,Ze as intentForbidsCopy,Ye as intentSwitchBlockedCopy,Oe as isPublicChannelId,Fe as markerLetter,De as markerOf,qe as mutationCount,Ne as needsMoveConfirmation,je as planAssignment,Ke as retryAfterCopy,Ve as selectionSources,it as stateBadge,Pe as suggestMarker};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seatlayer/js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.99.0",
|
|
4
4
|
"description": "SeatLayer's official JavaScript seating chart and seat map SDK — live availability, seat selection, temporary holds, and a typed API for any web ticketing app.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": {
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"typescript"
|
|
69
69
|
],
|
|
70
70
|
"dependencies": {
|
|
71
|
-
"@seatlayer/core": "0.
|
|
71
|
+
"@seatlayer/core": "0.99.0"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"tsup": "^8.5.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{T as a,U as b,V as c}from"./chunk-DR5JXWLO.js";import"./chunk-RZ2VKZ44.js";import"./chunk-OSZ7DOEH.js";export{b as CHANNELS_CSS,c as ChannelsMode,a as bucketRowsHtml};
|
package/dist/chunk-RZ2VKZ44.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{relativeLuminance255 as v,rgb255ToHex as y}from"@seatlayer/core/core/color";function a(e){if(!e)return null;let n=e.trim().toLowerCase();if(n==="white")return{r:255,g:255,b:255};if(n==="black")return{r:0,g:0,b:0};let t=/^#([0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(n)?.[1];if(t){let s=t.length<=4?[...t].map(o=>`${o}${o}`).join(""):t;return{r:Number.parseInt(s.slice(0,2),16),g:Number.parseInt(s.slice(2,4),16),b:Number.parseInt(s.slice(4,6),16)}}let r=/^rgba?\(\s*([\d.]+)[,\s]+([\d.]+)[,\s]+([\d.]+)(?:\s*[,/]\s*[\d.]+%?)?\s*\)$/i.exec(n);return r?{r:Math.max(0,Math.min(255,Number(r[1]))),g:Math.max(0,Math.min(255,Number(r[2]))),b:Math.max(0,Math.min(255,Number(r[3])))}:null}function d(e){return v([e.r,e.g,e.b])}function i(e,n){let t=a(e),r=a(n);if(!t||!r)return null;let s=Math.max(d(t),d(r)),o=Math.min(d(t),d(r));return(s+.05)/(o+.05)}function l(e,n="#172033",t="#eef1f8"){return(i(n,e)??0)>=(i(t,e)??0)?n:t}function C(e){return y(e.r,e.g,e.b)}function p(e,n,t){let r=a(e),s=a(n);if(!r||!s)return null;let o=Math.max(0,Math.min(1,t));return C({r:r.r*o+s.r*(1-o),g:r.g*o+s.g*(1-o),b:r.b*o+s.b*(1-o)})}var m="#d8a425",E=.18;function h(e,n){let t=p(m,n,E)??n;if((i(m,t)??0)>=4.5)return m;for(let r=.15;r<=1;r+=.05){let s=p(m,e,1-r);if(s&&(i(s,t)??0)>=4.5)return s}return l(t)}function x(e,n,t,r){if((i(e,t)??4.5)>=4.5&&(i(e,r)??4.5)>=4.5)return e;if(!a(e)||!a(n))return n;for(let s=.15;s<=1;s+=.05){let o=p(e,n,1-s);if(o&&(i(o,t)??0)>=4.5&&(i(o,r)??0)>=4.5)return o}return n}function M(e){return{"--sl-chrome":e?"#d6dce6":"#556278","--sl-chrome-line":e?"rgba(23,32,51,.55)":"rgba(233,238,247,.55)"}}var w=["--sl-bg","--sl-surface","--sl-text","--sl-muted","--sl-line","--sl-accent-text","--sl-warn-text","--sl-chrome","--sl-chrome-line"];function N(e,n){let t=n??e["--sl-bg"],r=a(t)?l(t)==="#172033":!1,s=a(e["--sl-bg"])?l(e["--sl-bg"])==="#172033":!1;if(r===s)return null;let o=r?"#ffffff":"#1a2234",c=l(t),u=e["--sl-accent"];return{"--sl-bg":t,"--sl-surface":o,"--sl-text":c,"--sl-muted":r?"#667085":"#a5aec2","--sl-line":r?"rgba(23,32,51,.16)":"rgba(165,174,194,.24)","--sl-accent-text":x(u,c,t,o),...M(r),"--sl-warn-text":h(c,o)}}var k={light:{background:"#ffffff",surface:"#f6f7fb",text:"#172033",muted:"#667085",line:"rgba(23,32,51,.16)",map:"#e9edf4"},dark:{background:"#0f1522",surface:"#1a2234",text:"#eef1f8",muted:"#a5aec2",line:"rgba(165,174,194,.24)",map:"#0f1522"}};function I(){try{return window.matchMedia?.("(prefers-color-scheme: dark)").matches===!0}catch{return!1}}function L(e){if(e)return e==="auto"?I()?"dark":"light":e}function P(e,n=e?.mode){if(e?.map)return e.map;let t=L(n);return t?{background:k[t].map}:null}function S(e){let n;try{n=window.matchMedia?.("(prefers-color-scheme: dark)")}catch{return()=>{}}if(!n)return()=>{};let t=r=>e(r.matches);return typeof n.addEventListener=="function"?n.addEventListener("change",t):n.addListener?.(t),()=>{typeof n.removeEventListener=="function"?n.removeEventListener("change",t):n.removeListener?.(t)}}function _(e,n,t){let r=t?k[t]:null,s=n?.background??r?.background??e?.background??"#0f1522",o=a(s)?l(s)==="#172033":!1,c=n?.surface??r?.surface??(o?"#ffffff":"#1a2234"),u=n?.accent??e?.accent??"#f4b740",g=e?.accentInk,T=n?.accentInk??(g&&(i(g,u)??4.5)>=4.5?g:l(u,"#1a1200","#ffffff")),f=r?void 0:e?.textColor,b=n?.text??r?.text??(f&&(i(f,s)??4.5)>=4.5&&(i(f,c)??4.5)>=4.5?f:l(s));return{"--sl-accent":u,"--sl-accent-ink":T,"--sl-accent-text":x(u,b,s,c),"--sl-warn-text":h(b,c),"--sl-bg":s,"--sl-surface":c,"--sl-text":b,"--sl-muted":n?.muted??r?.muted??(o?"#667085":"#a5aec2"),"--sl-line":n?.line??r?.line??(o?"rgba(23,32,51,.16)":"rgba(165,174,194,.24)"),...M(o),"--sl-scrim-ink":o?"rgba(16,22,36,1)":"rgba(4,7,13,1)","--sl-font":n?.fontFamily??e?.fontFamily??"-apple-system,BlinkMacSystemFont,'Segoe UI',Inter,sans-serif","--sl-radius":`${n?.radius??14}px`}}export{w as a,N as b,k as c,L as d,P as e,S as f,_ as g};
|