@seatlayer/js 0.90.0 → 0.92.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-CP2yegbE.d.cts → channelsMode-B41tbE29.d.cts} +12 -2
- package/dist/{channelsMode-CP2yegbE.d.ts → channelsMode-B41tbE29.d.ts} +12 -2
- package/dist/{channelsMode-JQPW2SVE.js → channelsMode-KZU235GN.js} +1 -1
- package/dist/{chunk-H7F4LMNV.js → chunk-5VGXB6GJ.js} +141 -92
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/manager.cjs +207 -135
- package/dist/manager.d.cts +2 -2
- package/dist/manager.d.ts +2 -2
- package/dist/manager.js +51 -28
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dataset.themed="true";let t=document.createElement("details");t.className="slm-themed-picker";let n=document.createElement("summary"),s=document.createElement("div");s.className="slm-themed-options";let r=e.getAttribute("aria-label")||Array.from(e.labels??[]).map(a=>a.textContent).join(" ")||"Choose option";n.setAttribute("aria-label",r.trim()),t.append(n,s),e.after(t),e.hidden=!0;let o=()=>{n.textContent=e.selectedOptions[0]?.textContent??"Choose\u2026",n.setAttribute("aria-disabled",String(e.disabled)),s.replaceChildren(...Array.from(e.options).map(a=>{let l=document.createElement("button");return l.type="button",l.textContent=a.textContent,l.setAttribute("aria-label",a.textContent??""),l.disabled=e.disabled||a.disabled,l.setAttribute("aria-pressed",String(a.selected)),l.onclick=()=>{e.value=a.value,t.open=!1,o(),n.focus(),e.dispatchEvent(new Event("change",{bubbles:!0})),o()},l}))};o(),e.addEventListener("change",o),n.onclick=a=>{if(e.disabled){a.preventDefault();return}o(),i.querySelectorAll(".slm-themed-picker").forEach(l=>{l!==t&&(l.open=!1)})},t.addEventListener("focusout",a=>{t.contains(a.relatedTarget)||(t.open=!1)}),t.addEventListener("keydown",a=>{if(a.key==="Escape"&&(a.preventDefault(),a.stopPropagation(),t.open=!1,n.focus()),a.key==="ArrowDown"||a.key==="ArrowUp"){if(e.disabled)return;a.preventDefault(),t.open=!0;let l=Array.from(s.querySelectorAll("button:not(:disabled)")),d=l.indexOf(document.activeElement);l[(d+(a.key==="ArrowDown"?1:l.length-1)+l.length)%l.length]?.focus()}})})}var $="public",E="Public sale";function M(i){return i==null||i===""||i===$}var K=["#a78bfa","#2dd4bf","#fb923c","#60a5fa","#f472b6","#a3e635","#f87171","#38bdf8","#c084fc","#facc15"],Be="#f4b740",de="ABCDEFGHJKLMNPQRSTUVWXYZ";function q(i,e){let t=(i??"").trim();return((/\p{L}/u.exec(t)?.[0]??t[0]??"")||e).toUpperCase().slice(0,1)}function ee(i,e){let t=new Set([...e].map(r=>q(r,"")).filter(Boolean)),n=q(i,"");return{letter:de.includes(n)&&!t.has(n)?n:[...de].find(r=>!t.has(r))??(n||"X"),color:K[t.size%K.length]}}function ue(i,e=0){return M(i.id)?{letter:q(i.marker,"P"),color:i.color||Be}:{letter:q(i.marker||i.name,"?"),color:i.color||K[e%K.length]}}function pe(i,e,t){let n=new Map;for(let o of i){let a=J(e.get(o));n.set(a,(n.get(a)??0)+1)}let s=[{id:$,name:t?.publicSale?.name??E},...(t?.channels??[]).map(o=>({id:o.id,name:o.name}))],r=[];for(let o of s){let a=n.get(o.id);a&&r.push({channelId:o.id,name:o.name,count:a}),n.delete(o.id)}for(let[o,a]of n)r.push({channelId:o,name:M(o)?E:"Another channel",count:a});return r}function J(i){return M(i)?$:i}var he=12;function Q(i){return{count:i.length,labels:i.slice(0,he),truncated:i.length>he}}function me(i){let{labels:e,allocation:t,statusOf:n,nameOf:s}=i,r=J(i.targetChannelId),o=new Set,a=0,l=0,d=new Map,h=[],u=[],w=[];for(let v of e){if(o.has(v))continue;o.add(v);let p=n(v);if(!p){w.push(v);continue}let m=J(t.get(v));if(m===r){l+=1;continue}if(p==="held"){h.push(v);continue}if(p==="booked"){u.push(v);continue}m===$?a+=1:d.set(m,(d.get(m)??0)+1)}let x=[...d.entries()].map(([v,p])=>({channelId:v,name:s(v),count:p}));return{changedFromPublic:{count:a},movedFromOtherChannel:{count:x.reduce((v,p)=>v+p.count,0),channels:x},alreadyInTarget:{count:l},skippedHeld:Q(h),skippedBooked:Q(u),notFound:Q(w)}}function X(i){return i.changedFromPublic.count+i.movedFromOtherChannel.count}function ge(i){return i.movedFromOtherChannel.count>0}function be(i,e){let t=[];i.changedFromPublic.count&&t.push({kind:"add",icon:"+",count:i.changedFromPublic.count,text:`${i.changedFromPublic.count.toLocaleString()} from ${E}`});for(let n of i.movedFromOtherChannel.channels)t.push({kind:"move",icon:"\u21C4",count:n.count,text:`${n.count.toLocaleString()} moved out of ${n.name??"another channel"}`,why:"needs this confirmation"});return i.alreadyInTarget.count&&t.push({kind:"same",icon:"=",count:i.alreadyInTarget.count,text:`${i.alreadyInTarget.count.toLocaleString()} already in ${e}`,why:"unchanged"}),i.skippedHeld.count&&t.push({kind:"skip",icon:"\u23F8",count:i.skippedHeld.count,text:`${i.skippedHeld.count.toLocaleString()} in a buyer's checkout`,why:"can't move while held",peek:Y(i.skippedHeld)}),i.skippedBooked.count&&t.push({kind:"skip",icon:"\u{1F512}",count:i.skippedBooked.count,text:`${i.skippedBooked.count.toLocaleString()} already sold`,why:"sales are never rewritten",peek:Y(i.skippedBooked)}),i.notFound.count&&t.push({kind:"skip",icon:"?",count:i.notFound.count,text:`${i.notFound.count.toLocaleString()} not on this map`,why:"these seats are no longer part of the event",peek:Y(i.notFound)}),t}function Y(i){if(!i.labels.length)return;let e=i.labels.slice(0,4).join(", ");return i.truncated||i.labels.length>4?`${e}\u2026`:e}function ve(i){let e=i?.retryAfterMs??(i?.latestHoldExpiresAt?Math.max(0,i.latestHoldExpiresAt-Date.now()):0);if(!e)return"in a moment";let t=Math.ceil(e/6e4);return t<=1?"in about a minute":`in about ${t} minutes`}function fe(i){if(!i||!i.intent)return"\u2014";let e=i.intent==="server"?"Website integration":i.intent==="hosted_link"?"Buyer link":i.intent==="internal"?"Your staff sell these":"Protected reserve",t=i.hasActiveGrants?"in use now":i.lastMintAt?`last used ${new Date(i.lastMintAt).toLocaleDateString()}`:null,n=i.detail??t;return n?`${e} \xB7 ${n}`:e}function _(i){return i==="internal"?"Sell through your own staff":i==="server"?"Integrate a website or app":i==="hosted_link"?"Sell with a buyer link":"Keep as protected reserve"}function ye(i){switch(i){case"internal":return"Only your own box office can sell these seats, through your secret key. Buyer links and website integrations are refused.";case"server":return"Your website's backend mints each buyer a short-lived session for these seats. Buyer links are refused; the code lives on the Embed page.";case"hosted_link":return"SeatLayer makes a link you send to a named group. They open it and buy only these seats. No other route can sell them.";default:return"Nobody can buy these seats. Every way of letting a buyer in \u2014 a buyer link, your website, even your own staff \u2014 is refused while this is the route. The seats stay out of public sale."}}function qe(i){return i==="hosted_link"?"hosted_link":i==="server"?"server":i==="staff"?"internal":null}function G(i){let e=Z(i?.accessIntent),t=qe(i?.route),n=`This channel is set to "${_(e)}"`;return t?`${n}, so it cannot do that. Switch it to "${_(t)}" first.`:`${n}, so it cannot do that. Choose a different route for this channel first.`}function Z(i){return i==="internal"||i==="server"||i==="hosted_link"||i==="none"?i:"none"}function F(i,e,t){return`${i.toLocaleString()} ${i===1?e:t}`}function ke(i){let e=Math.max(0,i?.liveAccessLinks??0),t=Math.max(0,i?.activeSessions??0),n=Z(i?.from),s=Z(i?.to),o=`${[e?F(e,"buyer link is live","buyer links are live"):null,t?F(t,"buyer is in a checkout","buyers are in a checkout"):null].filter(Boolean).join(", and ")||"Buyers are inside this channel"} on "${_(n)}". Moving it to "${_(s)}" changes what happens to them.`,a=[];return e&&a.push(`${F(e,"buyer link closes","buyer links close")} immediately. Anyone who has not opened it yet never will \u2014 send a new link if you still need one.`),t&&a.push(`${F(t,"buyer who is already in a checkout keeps","buyers who are already in a checkout keep")} their seats and can finish paying. Nobody is thrown out. No new buyers come in this way, so the old route empties on its own within 12 hours.`),{headline:o,consequences:a}}var te={maxRedemptions:100,maxQuantity:4};function we(i){switch(i.status??i.state){case"active":return{text:"Active",kind:"active"};case"expired":return{text:"Expired",kind:"archived"};case"exhausted":return{text:"All used",kind:"paused"};case"rotated":return{text:"Replaced",kind:"archived"};default:return{text:"Revoked",kind:"archived"}}}function ne(i){return i.state==="active"&&i.status==="active"}function _e(i){return Number.isFinite(i)?new Date(i).toLocaleString(void 0,{day:"numeric",month:"short",year:"numeric",hour:"numeric",minute:"2-digit"}):"\u2014"}function se(i){return[{k:"Expires",v:_e(i.expiresAt)},{k:"Redemptions",v:`${i.redemptions.toLocaleString()} of ${i.maxRedemptions.toLocaleString()} used`},{k:"Seats per buyer",v:`${i.maxQuantity.toLocaleString()} seat${i.maxQuantity===1?"":"s"} maximum`},{k:"Covers",v:i.includePublic?"This channel's allocation and Public sale seats":"This channel's allocation only"}]}function j(i){let e=i?.serverMessage?.trim();switch(i?.code){case"invalid_expiry":case"invalid_max_redemptions":case"invalid_max_quantity":case"invalid_session_ttl":case"invalid_label":return e||"That setting is outside what a hosted link allows. Adjust it and try again.";case"too_many_access_links":return e||"This channel already has as many live links as it can hold. Revoke one before creating another.";case"access_link_not_active":return"That link is no longer active, so it cannot be rotated or revoked.";case"channel_unavailable":return"This channel is paused or archived, so it cannot let new buyers in. Resume it first.";case"channel_access_intent_forbids":return G(i?.details);case"end_active_sessions_required":return"Choose what happens to the buyers who already came in through this link.";case"not_found":return"That link is no longer here. Refresh and try again.";default:return i?.status===403?"Hosted access links need channel-management permission.":e||"That did not go through. Try again."}}function tt(i){return(i?.channels??[]).map(e=>({kind:"skip",icon:"\u26A0",count:e.count,text:`${e.count.toLocaleString()} would leave ${e.name??"a channel"}`,why:"the new chart no longer has these seats",peek:e.labels?.length?Y({count:e.count,labels:e.labels,truncated:e.truncated??!1}):void 0}))}function xe(i){return i==="builtin"?"Built-in":i==="active"?"Active":i==="paused"?"Paused":"Archived"}var b=class extends Error{constructor(e,t,n,s,r,o){super(t),this.name="ManageApiError",this.status=e,this.code=n,this.conflicts=s,this.details=r,this.serverMessage=o}};async function Se(i){let t=(i.headers.get("content-type")??"").includes("application/json")?await i.json().catch(()=>null):null;if(!i.ok){let n=t;throw new b(i.status,n?.error??`request_failed_${i.status}`,n?.code,n?.conflicts,n?.details,typeof n?.message=="string"?n.message:void 0)}return t}function C(i){return i&&typeof i=="object"?i:{}}function W(i,e,t=0){return typeof i=="number"&&Number.isFinite(i)?i:typeof e=="number"&&Number.isFinite(e)?e:t}function Ce(i,e){return i===null?null:typeof i=="number"&&Number.isFinite(i)?i:i!==void 0?null:typeof e=="number"&&Number.isFinite(e)?e:null}function Le(i){let e=C(i),t=W(e.bookedValue,e.bookedRevenue);return{...e,bookedValue:t,bookedRevenue:t}}function Oe(i){let e=C(i),t=C(e.report),n=Array.isArray(t.byCategory)?t.byCategory.map(r=>{let o=C(r),a=W(o.bookedValue,o.bookedRevenue);return{...o,bookedValue:a,bookedRevenue:a}}):[],s=Array.isArray(t.bySection)?t.bySection.map(Le):void 0;return{...e,report:{...t,byCategory:n,...s?{bySection:s}:{}}}}function ze(i){let e=C(i),t=C(e.bookedValue),n=C(e.revenue),s=Object.keys(t).length?t:n,r=Array.isArray(t.bySection)?t.bySection:Array.isArray(n.bySection)?n.bySection:[],o={...s,gross:W(t.gross,n.gross),bySection:r.map(Le)},a=C(e.velocity),l=Array.isArray(a.bySection)?a.bySection.map(d=>{let h=C(d),u=W(h.bookedValue,h.grossRevenue);return{...h,bookedValue:u,grossRevenue:u}}):[];return{...e,bookedValue:o,revenue:o,velocity:{...a,bySection:l}}}function Ue(i){let e=C(i),t=C(e.report),n=typeof t.includesBookedValue=="boolean"?t.includesBookedValue:t.includesRevenue===!0,s=Array.isArray(t.rows)?t.rows.map(a=>{let l=C(a),d=C(l.attribution),h=Ce(d.bookedValue,d.revenue);return{...l,attribution:{...d,bookedValue:h,revenue:h}}}):[],r=C(t.totals),o=Ce(r.bookedValue,r.revenue);return{...e,report:{...t,includesBookedValue:n,includesRevenue:n,rows:s,totals:{...r,bookedValue:o,revenue:o}}}}function ie(i){let e=C(i),t=typeof e.includesBookedValue=="boolean"?e.includesBookedValue:e.includesRevenue===!0;return{...e,includesBookedValue:t,includesRevenue:t}}var $e=class{constructor(e,t){this.base=e.replace(/\/+$/,""),this.token=t}setToken(e){this.token=e}auth(e,t={}){let n=t.method??"GET",s={Authorization:`Bearer ${this.token}`},r;return t.body!==void 0&&(s["Content-Type"]="application/json",r=JSON.stringify(t.body)),fetch(`${this.base}${e}`,{method:n,headers:s,body:r,credentials:"omit"}).then(o=>Se(o))}async authBlob(e){let t=await fetch(`${this.base}${e}`,{method:"GET",headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});return t.ok||await Se(t),t.blob()}chart(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/chart`)}asset(e,t){return/^[a-zA-Z0-9._-]+$/.test(t)?this.authBlob(`/v1/events/${encodeURIComponent(e)}/assets/${encodeURIComponent(t)}`):Promise.reject(new b(404,"not_found","not_found"))}objects(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/objects`)}subscribeTicket(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/subscribe-tickets`,{method:"POST"})}socketUrl(e){return`${this.base.replace(/^http/,"ws")}/pub/events/${encodeURIComponent(e)}/subscribe?surface=manager`}block(e,t,n={}){let s={labels:t};return typeof n.releaseAt=="number"&&(s.releaseAt=n.releaseAt),n.reason&&(s.reason=n.reason),this.auth(`/v1/events/${encodeURIComponent(e)}/block`,{method:"POST",body:s})}unblock(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/unblock`,{method:"POST",body:{labels:t}})}unblockAll(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/unblock-all`,{method:"POST"})}unbook(e,t,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/unbook`,{method:"POST",body:{labels:t,bookingRef:n}})}setHoldTtl(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/hold-ttl`,{method:"POST",body:{holdTtlMs:t}})}setCategory(e,t,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/category-assignments`,{method:"POST",body:{labels:t,categoryKey:n}})}setTableBooking(e,t,n,s={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/table-booking`,{method:"POST",body:{tableIds:t,mode:n,...s}})}bookings(e,t={}){let n=new URLSearchParams;t.q&&n.set("q",t.q),t.state&&n.set("state",t.state),t.cursor&&n.set("cursor",t.cursor),t.limit!=null&&n.set("limit",String(t.limit));let s=n.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/bookings${s?`?${s}`:""}`)}booking(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/bookings/${encodeURIComponent(t)}`)}listBookings(e,t={}){return this.bookings(e,t)}retrieveBooking(e,t){return this.booking(e,t)}availability(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/availability`)}setAvailability(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/availability`,{method:"POST",body:{rules:t}})}channels(e,t={}){let n=t.includeArchived?"?includeArchived=1":"";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels${n}`)}channelAllocation(e,t={}){let n=new URLSearchParams;t.afterLabel&&n.set("afterLabel",t.afterLabel),t.limit!=null&&n.set("limit",String(t.limit));let s=n.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/allocation${s?`?${s}`:""}`)}channelAudit(e,t={}){let n=new URLSearchParams;t.limit!=null&&n.set("limit",String(t.limit)),t.before!=null&&n.set("before",String(t.before));let s=n.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/audit${s?`?${s}`:""}`)}createChannel(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels`,{method:"POST",body:t})}renameChannel(e,t,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{name:n}})}updateChannelPricing(e,t,n,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{priceOverrides:n,expectedPricingVersion:s}})}setChannelPaused(e,t,n){let s=n?"pause":"unpause";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/${s}`,{method:"POST",body:{}})}archiveChannel(e,t,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/archive`,{method:"POST",body:{destination:n}})}applyChannelAssignment(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/assignments`,{method:"POST",body:{targetChannelId:t.targetChannelId||null,labels:t.labels,assignmentVersion:t.assignmentVersion}})}channelPreview(e,t,n={}){let s=new URLSearchParams;t.length&&s.set("channelIds",t.join(",")),n.includePublic!=null&&s.set("includePublic",n.includePublic?"1":"0");let r=s.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/preview${r?`?${r}`:""}`)}setChannelAccessIntent(e,t,n,s={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{accessIntent:n,...s.acknowledgeLiveAccess?{acknowledgeLiveAccess:!0}:{},...s.reason?{reason:s.reason}:{}}})}createAccessLink(e,t,n={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links`,{method:"POST",body:n})}accessLinks(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links`)}rotateAccessLink(e,t,n,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links/${encodeURIComponent(n)}/rotate`,{method:"POST",body:{endActiveSessions:s}})}revokeAccessLink(e,t,n,s=!1){let r=s?"?endActiveSessions=1":"";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links/${encodeURIComponent(n)}${r}`,{method:"DELETE"})}report(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/report`).then(Oe)}seatHistory(e,t,n,s){let r=new URLSearchParams({label:t});return n&&r.set("before",String(n)),s&&r.set("action",s),this.auth(`/v1/events/${encodeURIComponent(e)}/seat-history?${r}`)}controlRoom(e,t=15){return this.auth(`/v1/events/${encodeURIComponent(e)}/control-room?window=${t}`).then(ze)}channelReport(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/report`).then(Ue)}createChannelReportLink(e,t,n={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`,{method:"POST",body:n}).then(s=>{let r=C(s);return{...r,link:ie(r.link)}})}channelReportLinks(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`).then(n=>{let s=C(n);return{links:Array.isArray(s.links)?s.links.map(ie):[]}})}revokeChannelReportLink(e,t,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links/${encodeURIComponent(n)}`,{method:"DELETE"}).then(s=>{let r=C(s);return{...r,link:ie(r.link)}})}log(e,t={}){let n=new URLSearchParams;t.limit!=null&&n.set("limit",String(t.limit)),t.before!=null&&n.set("before",String(t.before));let s=n.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/log${s?`?${s}`:""}`)}async reportCsv(e){let t=await fetch(`${this.base}/v1/events/${encodeURIComponent(e)}/report.csv`,{headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});if(!t.ok)throw new b(t.status,`request_failed_${t.status}`);return t.blob()}};function ae(i){return i.map((e,t)=>`
|
|
1
|
+
function le(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dataset.themed="true";let t=document.createElement("details");t.className="slm-themed-picker";let n=document.createElement("summary"),s=document.createElement("div");s.className="slm-themed-options";let r=e.getAttribute("aria-label")||Array.from(e.labels??[]).map(a=>a.textContent).join(" ")||"Choose option";n.setAttribute("aria-label",r.trim()),t.append(n,s),e.after(t),e.hidden=!0;let o=()=>{n.textContent=e.selectedOptions[0]?.textContent??"Choose\u2026",n.setAttribute("aria-disabled",String(e.disabled)),s.replaceChildren(...Array.from(e.options).map(a=>{let l=document.createElement("button");return l.type="button",l.textContent=a.textContent,l.setAttribute("aria-label",a.textContent??""),l.disabled=e.disabled||a.disabled,l.setAttribute("aria-pressed",String(a.selected)),l.onclick=()=>{e.value=a.value,t.open=!1,o(),n.focus(),e.dispatchEvent(new Event("change",{bubbles:!0})),o()},l}))};o(),e.addEventListener("change",o),n.onclick=a=>{if(e.disabled){a.preventDefault();return}o(),i.querySelectorAll(".slm-themed-picker").forEach(l=>{l!==t&&(l.open=!1)})},t.addEventListener("focusout",a=>{t.contains(a.relatedTarget)||(t.open=!1)}),t.addEventListener("keydown",a=>{if(a.key==="Escape"&&(a.preventDefault(),a.stopPropagation(),t.open=!1,n.focus()),a.key==="ArrowDown"||a.key==="ArrowUp"){if(e.disabled)return;a.preventDefault(),t.open=!0;let l=Array.from(s.querySelectorAll("button:not(:disabled)")),h=l.indexOf(document.activeElement);l[(h+(a.key==="ArrowDown"?1:l.length-1)+l.length)%l.length]?.focus()}})})}var $="public",P="Public sale";function D(i){return i==null||i===""||i===$}var Y=["#a78bfa","#2dd4bf","#fb923c","#60a5fa","#f472b6","#a3e635","#f87171","#38bdf8","#c084fc","#facc15"],_e="#f4b740",ce="ABCDEFGHJKLMNPQRSTUVWXYZ";function B(i,e){let t=(i??"").trim();return((/\p{L}/u.exec(t)?.[0]??t[0]??"")||e).toUpperCase().slice(0,1)}function ee(i,e){let t=new Set([...e].map(r=>B(r,"")).filter(Boolean)),n=B(i,"");return{letter:ce.includes(n)&&!t.has(n)?n:[...ce].find(r=>!t.has(r))??(n||"X"),color:Y[t.size%Y.length]}}function de(i,e=0){return D(i.id)?{letter:B(i.marker,"P"),color:i.color||_e}:{letter:B(i.marker||i.name,"?"),color:i.color||Y[e%Y.length]}}function ue(i,e,t){let n=new Map;for(let o of i){let a=J(e.get(o));n.set(a,(n.get(a)??0)+1)}let s=[{id:$,name:t?.publicSale?.name??P},...(t?.channels??[]).map(o=>({id:o.id,name:o.name}))],r=[];for(let o of s){let a=n.get(o.id);a&&r.push({channelId:o.id,name:o.name,count:a}),n.delete(o.id)}for(let[o,a]of n)r.push({channelId:o,name:D(o)?P:"Another channel",count:a});return r}function J(i){return D(i)?$:i}var he=12;function Q(i){return{count:i.length,labels:i.slice(0,he),truncated:i.length>he}}function pe(i){let{labels:e,allocation:t,statusOf:n,nameOf:s}=i,r=J(i.targetChannelId),o=new Set,a=0,l=0,h=new Map,d=[],u=[],k=[];for(let v of e){if(o.has(v))continue;o.add(v);let m=n(v);if(!m){k.push(v);continue}let b=J(t.get(v));if(b===r){l+=1;continue}if(m==="held"){d.push(v);continue}if(m==="booked"){u.push(v);continue}b===$?a+=1:h.set(b,(h.get(b)??0)+1)}let L=[...h.entries()].map(([v,m])=>({channelId:v,name:s(v),count:m}));return{changedFromPublic:{count:a},movedFromOtherChannel:{count:L.reduce((v,m)=>v+m.count,0),channels:L},alreadyInTarget:{count:l},skippedHeld:Q(d),skippedBooked:Q(u),notFound:Q(k)}}function K(i){return i.changedFromPublic.count+i.movedFromOtherChannel.count}function me(i){return i.movedFromOtherChannel.count>0}function ge(i,e){let t=[];i.changedFromPublic.count&&t.push({kind:"add",icon:"+",count:i.changedFromPublic.count,text:`${i.changedFromPublic.count.toLocaleString()} from ${P}`});for(let n of i.movedFromOtherChannel.channels)t.push({kind:"move",icon:"\u21C4",count:n.count,text:`${n.count.toLocaleString()} moved out of ${n.name??"another channel"}`,why:"needs this confirmation"});return i.alreadyInTarget.count&&t.push({kind:"same",icon:"=",count:i.alreadyInTarget.count,text:`${i.alreadyInTarget.count.toLocaleString()} already in ${e}`,why:"unchanged"}),i.skippedHeld.count&&t.push({kind:"skip",icon:"\u23F8",count:i.skippedHeld.count,text:`${i.skippedHeld.count.toLocaleString()} in a buyer's checkout`,why:"can't move while held",peek:F(i.skippedHeld)}),i.skippedBooked.count&&t.push({kind:"skip",icon:"\u{1F512}",count:i.skippedBooked.count,text:`${i.skippedBooked.count.toLocaleString()} already sold`,why:"sales are never rewritten",peek:F(i.skippedBooked)}),i.notFound.count&&t.push({kind:"skip",icon:"?",count:i.notFound.count,text:`${i.notFound.count.toLocaleString()} not on this map`,why:"these seats are no longer part of the event",peek:F(i.notFound)}),t}function F(i){if(!i.labels.length)return;let e=i.labels.slice(0,4).join(", ");return i.truncated||i.labels.length>4?`${e}\u2026`:e}function be(i){let e=i?.retryAfterMs??(i?.latestHoldExpiresAt?Math.max(0,i.latestHoldExpiresAt-Date.now()):0);if(!e)return"in a moment";let t=Math.ceil(e/6e4);return t<=1?"in about a minute":`in about ${t} minutes`}function ve(i){if(!i||!i.intent)return"\u2014";let e=i.intent==="server"?"Website integration":i.intent==="hosted_link"?"Buyer link":i.intent==="internal"?"Your staff sell these":"Protected reserve",t=i.hasActiveGrants?"in use now":i.lastMintAt?`last used ${new Date(i.lastMintAt).toLocaleDateString()}`:null,n=i.detail??t;return n?`${e} \xB7 ${n}`:e}function q(i){return i==="internal"?"Sell through your own staff":i==="server"?"Integrate a website or app":i==="hosted_link"?"Sell with a buyer link":"Keep as protected reserve"}function fe(i){switch(i){case"internal":return"Only your own box office can sell these seats, through your secret key. Buyer links and website integrations are refused.";case"server":return"Your website's backend mints each buyer a short-lived session for these seats. Buyer links are refused; the code lives on the Embed page.";case"hosted_link":return"SeatLayer makes a link you send to a named group. They open it and buy only these seats. No other route can sell them.";default:return"Nobody can buy these seats. Every way of letting a buyer in \u2014 a buyer link, your website, even your own staff \u2014 is refused while this is the route. The seats stay out of public sale."}}function ze(i){return i==="hosted_link"?"hosted_link":i==="server"?"server":i==="staff"?"internal":null}function X(i){let e=Z(i?.accessIntent),t=ze(i?.route),n=`This channel is set to "${q(e)}"`;return t?`${n}, so it cannot do that. Switch it to "${q(t)}" first.`:`${n}, so it cannot do that. Choose a different route for this channel first.`}function Z(i){return i==="internal"||i==="server"||i==="hosted_link"||i==="none"?i:"none"}function j(i,e,t){return`${i.toLocaleString()} ${i===1?e:t}`}function ye(i){let e=Math.max(0,i?.liveAccessLinks??0),t=Math.max(0,i?.activeSessions??0),n=Z(i?.from),s=Z(i?.to),o=`${[e?j(e,"buyer link is live","buyer links are live"):null,t?j(t,"buyer is in a checkout","buyers are in a checkout"):null].filter(Boolean).join(", and ")||"Buyers are inside this channel"} on "${q(n)}". Moving it to "${q(s)}" changes what happens to them.`,a=[];return e&&a.push(`${j(e,"buyer link closes","buyer links close")} immediately. Anyone who has not opened it yet never will \u2014 send a new link if you still need one.`),t&&a.push(`${j(t,"buyer who is already in a checkout keeps","buyers who are already in a checkout keep")} their seats and can finish paying. Nobody is thrown out. No new buyers come in this way, so the old route empties on its own within 12 hours.`),{headline:o,consequences:a}}var te={maxRedemptions:100,maxQuantity:4};function ke(i){switch(i.status??i.state){case"active":return{text:"Active",kind:"active"};case"expired":return{text:"Expired",kind:"archived"};case"exhausted":return{text:"All used",kind:"paused"};case"rotated":return{text:"Replaced",kind:"archived"};default:return{text:"Revoked",kind:"archived"}}}function ne(i){return i.state==="active"&&i.status==="active"}function Ue(i){return Number.isFinite(i)?new Date(i).toLocaleString(void 0,{day:"numeric",month:"short",year:"numeric",hour:"numeric",minute:"2-digit"}):"\u2014"}function se(i){return[{k:"Expires",v:Ue(i.expiresAt)},{k:"Redemptions",v:`${i.redemptions.toLocaleString()} of ${i.maxRedemptions.toLocaleString()} used`},{k:"Seats per buyer",v:`${i.maxQuantity.toLocaleString()} seat${i.maxQuantity===1?"":"s"} maximum`},{k:"Covers",v:i.includePublic?"This channel's allocation and Public sale seats":"This channel's allocation only"}]}function V(i){let e=i?.serverMessage?.trim();switch(i?.code){case"invalid_expiry":case"invalid_max_redemptions":case"invalid_max_quantity":case"invalid_session_ttl":case"invalid_label":return e||"That setting is outside what a hosted link allows. Adjust it and try again.";case"too_many_access_links":return e||"This channel already has as many live links as it can hold. Revoke one before creating another.";case"access_link_not_active":return"That link is no longer active, so it cannot be rotated or revoked.";case"channel_unavailable":return"This channel is paused or archived, so it cannot let new buyers in. Resume it first.";case"channel_access_intent_forbids":return X(i?.details);case"end_active_sessions_required":return"Choose what happens to the buyers who already came in through this link.";case"not_found":return"That link is no longer here. Refresh and try again.";default:return i?.status===403?"Hosted access links need channel-management permission.":e||"That did not go through. Try again."}}function rt(i){return(i?.channels??[]).map(e=>({kind:"skip",icon:"\u26A0",count:e.count,text:`${e.count.toLocaleString()} would leave ${e.name??"a channel"}`,why:"the new chart no longer has these seats",peek:e.labels?.length?F({count:e.count,labels:e.labels,truncated:e.truncated??!1}):void 0}))}function we(i){return i==="builtin"?"Built-in":i==="active"?"Active":i==="paused"?"Paused":"Archived"}var g=class extends Error{constructor(e,t,n,s,r,o){super(t),this.name="ManageApiError",this.status=e,this.code=n,this.conflicts=s,this.details=r,this.serverMessage=o}};async function xe(i){let t=(i.headers.get("content-type")??"").includes("application/json")?await i.json().catch(()=>null):null;if(!i.ok){let n=t;throw new g(i.status,n?.error??`request_failed_${i.status}`,n?.code,n?.conflicts,n?.details,typeof n?.message=="string"?n.message:void 0)}return t}function C(i){return i&&typeof i=="object"?i:{}}function G(i,e,t=0){return typeof i=="number"&&Number.isFinite(i)?i:typeof e=="number"&&Number.isFinite(e)?e:t}function Se(i,e){return i===null?null:typeof i=="number"&&Number.isFinite(i)?i:i!==void 0?null:typeof e=="number"&&Number.isFinite(e)?e:null}function Le(i){let e=C(i),t=G(e.bookedValue,e.bookedRevenue);return{...e,bookedValue:t,bookedRevenue:t}}function Ne(i){let e=C(i),t=C(e.report),n=Array.isArray(t.byCategory)?t.byCategory.map(r=>{let o=C(r),a=G(o.bookedValue,o.bookedRevenue);return{...o,bookedValue:a,bookedRevenue:a}}):[],s=Array.isArray(t.bySection)?t.bySection.map(Le):void 0;return{...e,report:{...t,byCategory:n,...s?{bySection:s}:{}}}}function Ve(i){let e=C(i),t=C(e.bookedValue),n=C(e.revenue),s=Object.keys(t).length?t:n,r=Array.isArray(t.bySection)?t.bySection:Array.isArray(n.bySection)?n.bySection:[],o={...s,gross:G(t.gross,n.gross),bySection:r.map(Le)},a=C(e.velocity),l=Array.isArray(a.bySection)?a.bySection.map(h=>{let d=C(h),u=G(d.bookedValue,d.grossRevenue);return{...d,bookedValue:u,grossRevenue:u}}):[];return{...e,bookedValue:o,revenue:o,velocity:{...a,bySection:l}}}function je(i){let e=C(i),t=C(e.report),n=typeof t.includesBookedValue=="boolean"?t.includesBookedValue:t.includesRevenue===!0,s=Array.isArray(t.rows)?t.rows.map(a=>{let l=C(a),h=C(l.attribution),d=Se(h.bookedValue,h.revenue);return{...l,attribution:{...h,bookedValue:d,revenue:d}}}):[],r=C(t.totals),o=Se(r.bookedValue,r.revenue);return{...e,report:{...t,includesBookedValue:n,includesRevenue:n,rows:s,totals:{...r,bookedValue:o,revenue:o}}}}function ie(i){let e=C(i),t=typeof e.includesBookedValue=="boolean"?e.includesBookedValue:e.includesRevenue===!0;return{...e,includesBookedValue:t,includesRevenue:t}}var Ce=class{constructor(e,t){this.base=e.replace(/\/+$/,""),this.token=t}setToken(e){this.token=e}auth(e,t={}){let n=t.method??"GET",s={Authorization:`Bearer ${this.token}`},r;return t.body!==void 0&&(s["Content-Type"]="application/json",r=JSON.stringify(t.body)),fetch(`${this.base}${e}`,{method:n,headers:s,body:r,credentials:"omit"}).then(o=>xe(o))}async authBlob(e){let t=await fetch(`${this.base}${e}`,{method:"GET",headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});return t.ok||await xe(t),t.blob()}chart(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/chart`)}asset(e,t){return/^[a-zA-Z0-9._-]+$/.test(t)?this.authBlob(`/v1/events/${encodeURIComponent(e)}/assets/${encodeURIComponent(t)}`):Promise.reject(new g(404,"not_found","not_found"))}objects(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/objects`)}subscribeTicket(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/subscribe-tickets`,{method:"POST"})}socketUrl(e){return`${this.base.replace(/^http/,"ws")}/pub/events/${encodeURIComponent(e)}/subscribe?surface=manager`}block(e,t,n={}){let s={labels:t};return typeof n.releaseAt=="number"&&(s.releaseAt=n.releaseAt),n.reason&&(s.reason=n.reason),this.auth(`/v1/events/${encodeURIComponent(e)}/block`,{method:"POST",body:s})}unblock(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/unblock`,{method:"POST",body:{labels:t}})}unblockAll(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/unblock-all`,{method:"POST"})}unbook(e,t,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/unbook`,{method:"POST",body:{labels:t,bookingRef:n}})}setHoldTtl(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/hold-ttl`,{method:"POST",body:{holdTtlMs:t}})}setCategory(e,t,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/category-assignments`,{method:"POST",body:{labels:t,categoryKey:n}})}setTableBooking(e,t,n,s={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/table-booking`,{method:"POST",body:{tableIds:t,mode:n,...s}})}bookings(e,t={}){let n=new URLSearchParams;t.q&&n.set("q",t.q),t.state&&n.set("state",t.state),t.cursor&&n.set("cursor",t.cursor),t.limit!=null&&n.set("limit",String(t.limit));let s=n.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/bookings${s?`?${s}`:""}`)}booking(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/bookings/${encodeURIComponent(t)}`)}listBookings(e,t={}){return this.bookings(e,t)}retrieveBooking(e,t){return this.booking(e,t)}availability(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/availability`)}setAvailability(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/availability`,{method:"POST",body:{rules:t}})}channels(e,t={}){let n=t.includeArchived?"?includeArchived=1":"";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels${n}`)}channelAllocation(e,t={}){let n=new URLSearchParams;t.afterLabel&&n.set("afterLabel",t.afterLabel),t.limit!=null&&n.set("limit",String(t.limit));let s=n.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/allocation${s?`?${s}`:""}`)}channelAudit(e,t={}){let n=new URLSearchParams;t.limit!=null&&n.set("limit",String(t.limit)),t.before!=null&&n.set("before",String(t.before));let s=n.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/audit${s?`?${s}`:""}`)}createChannel(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels`,{method:"POST",body:t})}renameChannel(e,t,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{name:n}})}updateChannelPricing(e,t,n,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{priceOverrides:n,expectedPricingVersion:s}})}setChannelPaused(e,t,n){let s=n?"pause":"unpause";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/${s}`,{method:"POST",body:{}})}archiveChannel(e,t,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/archive`,{method:"POST",body:{destination:n}})}applyChannelAssignment(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/assignments`,{method:"POST",body:{targetChannelId:t.targetChannelId||null,labels:t.labels,assignmentVersion:t.assignmentVersion}})}channelPreview(e,t,n={}){let s=new URLSearchParams;t.length&&s.set("channelIds",t.join(",")),n.includePublic!=null&&s.set("includePublic",n.includePublic?"1":"0");let r=s.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/preview${r?`?${r}`:""}`)}setChannelAccessIntent(e,t,n,s={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}`,{method:"PATCH",body:{accessIntent:n,...s.acknowledgeLiveAccess?{acknowledgeLiveAccess:!0}:{},...s.reason?{reason:s.reason}:{}}})}createAccessLink(e,t,n={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links`,{method:"POST",body:n})}accessLinks(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links`)}rotateAccessLink(e,t,n,s){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links/${encodeURIComponent(n)}/rotate`,{method:"POST",body:{endActiveSessions:s}})}revokeAccessLink(e,t,n,s=!1){let r=s?"?endActiveSessions=1":"";return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/access-links/${encodeURIComponent(n)}${r}`,{method:"DELETE"})}report(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/report`).then(Ne)}seatHistory(e,t,n,s){let r=new URLSearchParams({label:t});return n&&r.set("before",String(n)),s&&r.set("action",s),this.auth(`/v1/events/${encodeURIComponent(e)}/seat-history?${r}`)}controlRoom(e,t=15){return this.auth(`/v1/events/${encodeURIComponent(e)}/control-room?window=${t}`).then(Ve)}channelReport(e){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/report`).then(je)}createChannelReportLink(e,t,n={}){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`,{method:"POST",body:n}).then(s=>{let r=C(s);return{...r,link:ie(r.link)}})}channelReportLinks(e,t){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links`).then(n=>{let s=C(n);return{links:Array.isArray(s.links)?s.links.map(ie):[]}})}revokeChannelReportLink(e,t,n){return this.auth(`/v1/events/${encodeURIComponent(e)}/channels/${encodeURIComponent(t)}/report-links/${encodeURIComponent(n)}`,{method:"DELETE"}).then(s=>{let r=C(s);return{...r,link:ie(r.link)}})}log(e,t={}){let n=new URLSearchParams;t.limit!=null&&n.set("limit",String(t.limit)),t.before!=null&&n.set("before",String(t.before));let s=n.toString();return this.auth(`/v1/events/${encodeURIComponent(e)}/log${s?`?${s}`:""}`)}async reportCsv(e){let t=await fetch(`${this.base}/v1/events/${encodeURIComponent(e)}/report.csv`,{headers:{Authorization:`Bearer ${this.token}`},credentials:"omit"});if(!t.ok)throw new g(t.status,`request_failed_${t.status}`);return t.blob()}};function ae(i){return i.map((e,t)=>`
|
|
2
2
|
<div class="slm-ch-bucket" style="animation-delay:${Math.min(t,4)*30}ms">
|
|
3
3
|
<span class="ico ${e.kind}" aria-hidden="true">${c(e.icon)}</span>
|
|
4
4
|
<span><b>${e.count.toLocaleString()}</b> ${c(e.text.replace(/^[\d,.\s]+/,""))}
|
|
@@ -10,40 +10,54 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
10
10
|
access session for this channel with the SeatLayer server SDK and hands it to the widget. A channel name
|
|
11
11
|
on its own never grants access.</p>
|
|
12
12
|
<p class="slm-note"><a class="slm-linkbtn" href="https://docs.seatlayer.io/server-api/channels"
|
|
13
|
-
target="_blank" rel="noreferrer noopener">Read the website integration guide \u2192</a></p>`;function c(i){return String(i??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Ae(i){return new Date(i-new Date(i).getTimezoneOffset()*6e4).toISOString().slice(0,16)}function oe(i,e){let t=i.querySelector(e)?.value.trim()??"",n=Number(t);return t!==""&&Number.isInteger(n)?n:null}function
|
|
14
|
-
.slm{--slm-
|
|
13
|
+
target="_blank" rel="noreferrer noopener">Read the website integration guide \u2192</a></p>`;function c(i){return String(i??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function Ae(i){return new Date(i-new Date(i).getTimezoneOffset()*6e4).toISOString().slice(0,16)}function oe(i,e){let t=i.querySelector(e)?.value.trim()??"",n=Number(t);return t!==""&&Number.isInteger(n)?n:null}function Ie(i,e){let t=typeof navigator>"u"?null:navigator.clipboard;return t?.writeText?t.writeText(e).then(()=>!0,()=>$e(i,e)):Promise.resolve($e(i,e))}function $e(i,e){let t=i.querySelector("[data-ch-lk-sink]");if(t&&typeof document.execCommand=="function")try{t.value=e,t.select(),t.setSelectionRange(0,e.length);let n=document.execCommand("copy");if(t.value="",n)return!0}catch{t.value=""}return Fe(i),!1}function Fe(i){let e=i.querySelector("[data-ch-lk-url]");if(e)try{let t=document.createRange();t.selectNodeContents(e);let n=window.getSelection();n?.removeAllRanges(),n?.addRange(t)}catch{}}var Ye=8,Ke="#6e7bff",Xe="#b9c0ff",Ge={unavailableFill:"#303846",unavailableStroke:"#4b5669",allocationStroke:"#101723",sectionPlate:"rgba(11,16,28,.88)",sectionPlateInk:"#f8fafc"},We={unavailableFill:"rgba(156,163,175,.55)",unavailableStroke:"rgba(107,114,128,.65)",allocationStroke:"#ffffff",sectionPlate:"rgba(255,255,255,.9)",sectionPlateInk:"#172033"};function Qe(i){return i?.dataset?.theme==="light"?We:Ge}function Te(i){let e=i.canvas,t=i.layer;if(!e||!t)return;let n=i.host.mapLayer.getBoundingClientRect(),s=Math.max(1,Math.round(n.width)),r=Math.max(1,Math.round(n.height)),o=typeof devicePixelRatio=="number"?Math.min(3,Math.max(1,devicePixelRatio)):1;(e.width!==s*o||e.height!==r*o)&&(e.width=s*o,e.height=r*o);let a=i.resolveCtx();if(!a)return;a.setTransform(o,0,0,o,0,0),a.clearRect(0,0,s,r);let l=Qe(i.host.root),h=i.host.isSeatDetail(),d=Math.max(3,i.host.seatPixelSize()),u=d/2,k=i.view==="preview"?i.previewProjection:null,L=k?new Set(k.available===!1?[]:k.eligible??[]):null,v=new Map,m=!h&&i.host.sections().length>1?new Map:null,b=i.view==="preview"&&h&&d<=15?new Map:null;for(let w of i.host.seats()){let W=i.host.statusOf(w.label)??"free",M=i.allocation.get(w.label)??$;if(M!==$){let y=v.get(M)??{x:0,y:0,n:0};y.x+=w.x,y.y+=w.y,y.n+=1,v.set(M,y)}if(!h){let y=i.host.sectionOfLabel(w.label),p=y?i.host.worldToScreen({x:w.x,y:w.y}):null;if(m&&y&&p){let x=m.get(y.id)??{label:y.label,minX:p.x,minY:p.y,maxX:p.x,maxY:p.y};x.minX=Math.min(x.minX,p.x),x.minY=Math.min(x.minY,p.y),x.maxX=Math.max(x.maxX,p.x),x.maxY=Math.max(x.maxY,p.y),m.set(y.id,x)}continue}if(W!=="free")continue;let R=null,H=null;if(i.view==="preview"?L?.has(w.label)?(R=Ke,H=Xe):(R=l.unavailableFill,H=l.unavailableStroke):M!==$&&(R=i.markerFor(M).color,H=l.allocationStroke),!R)continue;let f=i.host.worldToScreen({x:w.x,y:w.y});if(f&&!(f.x<-d||f.y<-d||f.x>s+d||f.y>r+d)){if(b){let y=i.host.sectionOfLabel(w.label);if(y){let p=b.get(y.id)??{label:y.label,minX:f.x,minY:f.y,maxX:f.x,maxY:f.y};p.minX=Math.min(p.minX,f.x),p.minY=Math.min(p.minY,f.y),p.maxX=Math.max(p.maxX,f.x),p.maxY=Math.max(p.maxY,f.y),b.set(y.id,p)}}if(a.fillStyle=R,i.view==="preview"||M!==$){let y=Math.max(2,u+Math.min(1.5,u*.06));a.globalAlpha=1,a.beginPath(),a.arc(f.x,f.y,y,0,Math.PI*2),a.fill(),a.strokeStyle=H??R,a.lineWidth=i.view==="preview"?Math.max(1,Math.min(1.75,d*.13)):Math.max(1,Math.min(1.5,d*.1)),a.stroke(),i.view==="preview"&&L?.has(w.label)&&d>=22&&Je(a,w.label,f.x,f.y,y)}else a.globalAlpha=.85,a.fillRect(f.x-u,f.y-u,d,d)}}a.globalAlpha=1,b&&nt(a,b,l),Ze(m,i),st(v,i,a)}function Je(i,e,t,n,s){let r=s*1.55,o=Math.min(13,Math.max(7,s*.55)),a=6;for(;o>=a&&(i.font=`800 ${o}px var(--slm-font, system-ui, sans-serif)`,!(i.measureText(e).width<=r));)o-=.5;o<a||(i.fillStyle="#ffffff",i.textAlign="center",i.textBaseline="middle",i.fillText(e,t,n))}function Ze(i,e){let t=e.layer;if(t&&(t.querySelectorAll(".slm-ch-section-target").forEach(n=>n.remove()),!!i))for(let[n,s]of i){let r=s.maxX-s.minX,o=s.maxY-s.minY;if(r<20||o<20)continue;let a=document.createElement("button");a.type="button",a.className="slm-ch-section-target",a.style.left=`${s.minX-8}px`,a.style.top=`${s.minY-8}px`,a.style.width=`${r+16}px`,a.style.height=`${o+16}px`,a.setAttribute("aria-label",`Open ${s.label} seats`),tt(a,e,()=>e.onSectionTargetClick(n)),t.appendChild(a)}}var Ee=4;function et(i,e){let t={button:0,buttons:1,clientX:e.x,clientY:e.y,bubbles:!0,cancelable:!0,composed:!0};return typeof PointerEvent=="function"?new PointerEvent("pointerdown",{...t,pointerId:i.pointerId,pointerType:i.pointerType,isPrimary:!0}):new MouseEvent("pointerdown",t)}function Pe(i){return i.host.mapLayer.querySelector(".slm-map-host")??i.host.mapLayer}function tt(i,e,t){i.addEventListener("wheel",l=>{let h=Pe(e);h!==i&&(l.preventDefault(),h.dispatchEvent(new WheelEvent("wheel",{deltaX:l.deltaX,deltaY:l.deltaY,deltaZ:l.deltaZ,deltaMode:l.deltaMode,clientX:l.clientX,clientY:l.clientY,ctrlKey:l.ctrlKey,shiftKey:l.shiftKey,altKey:l.altKey,metaKey:l.metaKey,bubbles:!0,cancelable:!0,composed:!0})))},{passive:!1});let n=null,s=!1,r=()=>{n=null,e.layer?.classList.remove("panning"),window.removeEventListener("pointermove",o,!0),window.removeEventListener("pointerup",a,!0),window.removeEventListener("pointercancel",a,!0)};function o(l){if(!n||s||Math.abs(l.clientX-n.x)<Ee&&Math.abs(l.clientY-n.y)<Ee)return;s=!0;let h=n;e.layer?.classList.add("panning");let d=document.elementFromPoint?.(h.x,h.y)??null;(d&&d!==i?d:Pe(e)).dispatchEvent(et(l,h))}function a(){r()}i.addEventListener("pointerdown",l=>{s=!1,n={x:l.clientX,y:l.clientY},window.addEventListener("pointermove",o,!0),window.addEventListener("pointerup",a,!0),window.addEventListener("pointercancel",a,!0)}),i.addEventListener("click",l=>{if(s){s=!1,l.preventDefault(),l.stopPropagation();return}t()})}function nt(i,e,t){for(let n of e.values()){let s=n.maxX-n.minX,r=n.maxY-n.minY;if(s<52||r<26)continue;let o=(n.minX+n.maxX)/2,a=(n.minY+n.maxY)/2,l=Math.max(11,Math.min(15,r*.16));i.font=`800 ${l}px var(--slm-font, system-ui, sans-serif)`;let h=Math.min(s-8,i.measureText(n.label).width+18),d=l+10;i.fillStyle=t.sectionPlate,i.fillRect(o-h/2,a-d/2,h,d),i.fillStyle=t.sectionPlateInk,i.textAlign="center",i.textBaseline="middle",i.fillText(n.label,o,a)}}function st(i,e,t){let n=e.layer;if(!n||(n.querySelectorAll(".slm-ch-flag").forEach(r=>r.remove()),e.view==="preview"))return;let s=[...i.entries()].sort((r,o)=>o[1].n-r[1].n).slice(0,Ye);for(let[r,o]of s){let a=e.list?.channels.find(u=>u.id===r);if(!a)continue;let l=e.host.worldToScreen({x:o.x/o.n,y:o.y/o.n});if(!l)continue;let h=e.markerFor(r),d=document.createElement("span");d.className="slm-ch-flag",d.style.left=`${l.x}px`,d.style.top=`${l.y}px`,d.innerHTML=`<span class="mk" style="background:${c(h.color)}">${c(h.letter)}</span>${c(a.name)}${a.state==="paused"?" \xB7 Paused":""}`,n.appendChild(d)}}var it=`
|
|
14
|
+
.slm{--slm-ch-marker-ink:#0e1017;--slm-ch-scrim:rgba(0,0,0,.58);
|
|
15
|
+
--slm-mo-instant:80ms;--slm-mo-quick:140ms;--slm-mo-base:200ms;--slm-mo-slow:320ms;--slm-mo-ambient:2000ms;
|
|
15
16
|
--slm-mo-out:cubic-bezier(.2,.8,.2,1);--slm-mo-in-out:cubic-bezier(.4,0,.2,1);--slm-mo-exit:cubic-bezier(.4,0,1,1);
|
|
16
17
|
--slm-mo-spring:cubic-bezier(.34,1.3,.64,1)}
|
|
18
|
+
/* A channel's marker chip is painted in the CHANNEL's own colour, which is the
|
|
19
|
+
same in both themes, so its ink is a constant rather than a ground token \u2014
|
|
20
|
+
declared once here so a host can still override it. The scrim always DARKENS
|
|
21
|
+
(a light-ground modal dims with a dark veil too); only its strength changes. */
|
|
22
|
+
.slm[data-theme=light]{--slm-ch-scrim:rgba(23,32,51,.42)}
|
|
17
23
|
|
|
18
24
|
/* map overlay: ONE layer, faded in as a whole (never per seat) */
|
|
19
25
|
.slm-ch-layer{position:absolute;inset:0;overflow:hidden;pointer-events:none;opacity:0;transition:opacity var(--slm-mo-base) var(--slm-mo-out)}
|
|
20
26
|
.slm-ch-layer.on{opacity:1}
|
|
21
27
|
.slm-ch-canvas{position:absolute;inset:0;width:100%;height:100%}
|
|
22
28
|
.slm-ch-flag{position:absolute;display:flex;align-items:center;gap:5px;padding:3px 8px;border-radius:999px;
|
|
23
|
-
background:
|
|
29
|
+
background:color-mix(in srgb,var(--slm-surface) 92%,transparent);color:var(--slm-text);
|
|
30
|
+
border:1px solid var(--slm-line);font-size:10px;font-weight:800;letter-spacing:.04em;
|
|
24
31
|
transform:translate(-50%,-50%);white-space:nowrap}
|
|
25
|
-
.slm-ch-flag .mk{width:14px;height:14px;border-radius:4px;display:grid;place-items:center;font-size:8.5px;font-weight:800;color
|
|
32
|
+
.slm-ch-flag .mk{width:14px;height:14px;border-radius:4px;display:grid;place-items:center;font-size:8.5px;font-weight:800;color:var(--slm-ch-marker-ink)}
|
|
26
33
|
.slm-ch-section-target{position:absolute;pointer-events:auto;padding:0;border:0;border-radius:8px;background:transparent;cursor:zoom-in}
|
|
34
|
+
/* Set while a pointer gesture that started on a section target has turned into
|
|
35
|
+
a map pan: every target goes inert so the drag reaches the renderer host. */
|
|
36
|
+
.slm-ch-layer.panning .slm-ch-section-target{pointer-events:none}
|
|
27
37
|
.slm-ch-section-target:focus-visible{outline:2px solid var(--slm-accent);outline-offset:-3px;background:color-mix(in srgb,var(--slm-accent) 12%,transparent)}
|
|
28
38
|
|
|
29
39
|
/* preview banner \u2014 raised with the organizer chrome dim, as one transition */
|
|
30
|
-
.slm-ch-banner{
|
|
31
|
-
border-radius:999px;background:
|
|
32
|
-
|
|
40
|
+
.slm-ch-banner{display:flex;align-items:center;gap:9px;padding:8px 14px;max-width:100%;
|
|
41
|
+
border-radius:999px;background:color-mix(in srgb,var(--slm-surface) 94%,transparent);color:var(--slm-text);
|
|
42
|
+
border:1px solid var(--slm-line);font-size:12px;font-weight:700;
|
|
43
|
+
transform:translateY(-8px);opacity:0;pointer-events:none;
|
|
33
44
|
transition:opacity var(--slm-mo-base) var(--slm-mo-out),transform var(--slm-mo-base) var(--slm-mo-out)}
|
|
34
|
-
.slm-ch-banner.on{opacity:1;transform:
|
|
45
|
+
.slm-ch-banner.on{opacity:1;transform:none;pointer-events:auto}
|
|
35
46
|
.slm-ch-banner .dot{width:8px;height:8px;border-radius:50%}
|
|
36
47
|
.slm-ch-banner button{color:var(--slm-accent);font-weight:800;font-size:11.5px;min-height:32px}
|
|
37
48
|
.slm.ch-preview .slm-ch-flag{opacity:0;transition:opacity var(--slm-mo-base) var(--slm-mo-out)}
|
|
38
49
|
|
|
39
50
|
/* sticky staged bar */
|
|
40
51
|
.slm-ch-staged{position:absolute;left:12px;right:12px;bottom:12px;z-index:6;display:flex;align-items:center;gap:12px;
|
|
41
|
-
padding:10px 14px;min-height:44px;border-radius:12px;
|
|
52
|
+
padding:10px 14px;min-height:44px;border-radius:12px;color:var(--slm-text);
|
|
53
|
+
background:color-mix(in srgb,var(--slm-surface) 96%,transparent);border:1px solid var(--slm-line);
|
|
42
54
|
box-shadow:0 12px 34px rgba(0,0,0,.45);font-size:12.5px;pointer-events:auto;
|
|
43
55
|
transform:translateY(calc(100% + 18px));opacity:0;
|
|
44
56
|
transition:transform var(--slm-mo-slow) var(--slm-mo-out),opacity var(--slm-mo-base) var(--slm-mo-out)}
|
|
45
57
|
.slm-ch-staged.on{transform:none;opacity:1}
|
|
46
|
-
|
|
58
|
+
/* Success keeps its own green \u2014 a semantic state, not a ground \u2014 so it states
|
|
59
|
+
its ink rather than inheriting a token that flips with the theme. */
|
|
60
|
+
.slm-ch-staged.done{background:rgba(31,122,77,.96);border-color:#1f7a4d;color:#fff}
|
|
47
61
|
.slm-ch-staged.shake{animation:slm-ch-shake var(--slm-mo-slow) var(--slm-mo-in-out) 2}
|
|
48
62
|
.slm-ch-staged b{font-variant-numeric:tabular-nums}
|
|
49
63
|
.slm-ch-staged .grow{flex:1}
|
|
@@ -68,9 +82,19 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
68
82
|
.slm-ch-mapnav .slm-ch-viewseg{margin:8px 0 5px}
|
|
69
83
|
.slm-ch-mapnav p{margin:0;font-size:11px;line-height:1.45;color:var(--slm-muted)}
|
|
70
84
|
.slm-ch-list{display:flex;flex-direction:column;gap:8px;margin-bottom:12px}
|
|
71
|
-
|
|
85
|
+
/* The list header is PINNED: it carries the only route to a new channel, and a
|
|
86
|
+
long channel list used to push that button past the fold. Sticky offsets are
|
|
87
|
+
measured from the scrollport's PADDING box, so the top offset is the negative
|
|
88
|
+
of the rail's own padding, and the header's matching padding covers that
|
|
89
|
+
strip \u2014 the list scrolls under an opaque header rather than through a gap
|
|
90
|
+
above it. The side bleed makes the rule reach both edges. */
|
|
91
|
+
.slm-ch-listhead{position:sticky;top:-16px;z-index:4;display:flex;align-items:center;justify-content:space-between;
|
|
92
|
+
gap:8px;margin:0 -16px 10px;padding:16px 16px 10px;background:var(--slm-surface);
|
|
93
|
+
border-bottom:1px solid var(--slm-line)}
|
|
72
94
|
.slm-ch-listhead h2{margin:0;font-size:14px}
|
|
73
95
|
.slm .slm-ch-listhead .slm-linkbtn{font-size:11px;color:var(--slm-text)}
|
|
96
|
+
/* Compact primary: the rail's own button, sized to sit on one header line. */
|
|
97
|
+
.slm .slm-ch-new{flex:none;min-width:0;padding:7px 11px;min-height:32px;font-size:11.5px}
|
|
74
98
|
.slm[data-theme=light] .slm-ch-badge.active,.slm[data-theme=light] .slm-ch-counts .free b{color:#137047}
|
|
75
99
|
.slm[data-theme=light] .slm-ch-badge.paused,.slm[data-theme=light] .slm-ch-badge.builtin{color:#815705}
|
|
76
100
|
.slm[data-theme=light] .slm-ch-badge.archived{color:var(--slm-muted)}
|
|
@@ -82,7 +106,7 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
82
106
|
.slm-ch-row.archived{opacity:.68}
|
|
83
107
|
.slm-ch-head{display:flex;align-items:center;gap:8px}
|
|
84
108
|
.slm-ch-mk{width:20px;height:20px;border-radius:6px;display:grid;place-items:center;font-size:10px;font-weight:800;
|
|
85
|
-
color
|
|
109
|
+
color:var(--slm-ch-marker-ink);flex:none}
|
|
86
110
|
.slm-ch-mk.dim{opacity:.55}
|
|
87
111
|
.slm-ch-name{flex:1;min-width:0;font-size:13px;font-weight:800;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
88
112
|
.slm-ch-badge{flex:none;font-size:9px;font-weight:800;letter-spacing:.05em;text-transform:uppercase;padding:2px 7px;border-radius:999px}
|
|
@@ -116,7 +140,7 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
116
140
|
.slm-ch-selsrc{display:flex;flex-direction:column;gap:5px;margin:8px 0 12px}
|
|
117
141
|
.slm-ch-selsrc-row{display:flex;align-items:center;gap:8px;font-size:12px;font-variant-numeric:tabular-nums}
|
|
118
142
|
.slm-ch-selsrc-row .mk{width:15px;height:15px;border-radius:4px;display:grid;place-items:center;font-size:8px;
|
|
119
|
-
font-weight:800;color
|
|
143
|
+
font-weight:800;color:var(--slm-ch-marker-ink)}
|
|
120
144
|
.slm-ch-selsrc-row b{min-width:30px;text-align:right;font-weight:800}
|
|
121
145
|
.slm-ch-selsrc-row span{color:var(--slm-muted)}
|
|
122
146
|
.slm-ch-selnum.bump{animation:slm-ch-bump var(--slm-mo-base) var(--slm-mo-spring)}
|
|
@@ -149,9 +173,9 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
149
173
|
.slm-ch-live{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
|
|
150
174
|
|
|
151
175
|
/* dialogs */
|
|
152
|
-
.slm-ch-scrim{position:absolute;inset:0;z-index:12;background:
|
|
176
|
+
.slm-ch-scrim{position:absolute;inset:0;z-index:12;background:var(--slm-ch-scrim);display:grid;place-items:center;
|
|
153
177
|
padding:18px;animation:slm-ch-fade var(--slm-mo-quick) var(--slm-mo-out)}
|
|
154
|
-
.slm-ch-dialog{width:min(460px,100%);max-height:100%;overflow:auto;overscroll-behavior:contain;background
|
|
178
|
+
.slm-ch-dialog{width:min(460px,100%);max-height:100%;overflow:auto;overscroll-behavior:contain;background:var(--slm-surface);color:var(--slm-text);border:1px solid var(--slm-line);
|
|
155
179
|
border-radius:14px;padding:20px;box-shadow:0 24px 70px rgba(0,0,0,.6);
|
|
156
180
|
animation:slm-ch-rise var(--slm-mo-base) var(--slm-mo-out)}
|
|
157
181
|
.slm-ch-dialog h3{margin:0 0 4px;font-size:16px;font-weight:800;letter-spacing:-.01em}
|
|
@@ -167,14 +191,21 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
167
191
|
.slm-ch-bucket .ico{width:20px;height:20px;border-radius:6px;display:grid;place-items:center;font-size:10px;font-weight:800}
|
|
168
192
|
.slm-ch-bucket .ico.add{background:rgba(34,160,107,.18);color:#5bd39b}
|
|
169
193
|
.slm-ch-bucket .ico.move{background:rgba(167,139,250,.18);color:#c4b5fd}
|
|
170
|
-
.slm-ch-bucket .ico.same{background:
|
|
194
|
+
.slm-ch-bucket .ico.same{background:var(--slm-tint-strong);color:var(--slm-muted)}
|
|
171
195
|
.slm-ch-bucket .ico.skip{background:rgba(244,183,64,.16);color:#f7ca6b}
|
|
196
|
+
/* The three remaining icon inks are semantic (added / moved / skipped) and are
|
|
197
|
+
tuned for a dark ground; a light ground needs the darker end of the same hue
|
|
198
|
+
to stay readable, exactly as the status badges above already do. */
|
|
199
|
+
.slm[data-theme=light] .slm-ch-bucket .ico.add{color:#137047}
|
|
200
|
+
.slm[data-theme=light] .slm-ch-bucket .ico.move{color:#6d28d9}
|
|
201
|
+
.slm[data-theme=light] .slm-ch-bucket .ico.skip{color:#815705}
|
|
172
202
|
.slm-ch-bucket b{font-variant-numeric:tabular-nums;font-weight:800}
|
|
173
203
|
.slm-ch-bucket .why{color:var(--slm-muted);font-size:11px}
|
|
174
204
|
.slm-ch-bucket .peek{color:var(--slm-muted);font-size:11px;font-variant-numeric:tabular-nums}
|
|
175
205
|
@keyframes slm-ch-bucket{from{opacity:0;transform:translateY(4px)}to{opacity:1;transform:none}}
|
|
176
206
|
.slm-ch-secret{display:flex;align-items:center;gap:8px;padding:10px 12px;border:1px dashed rgba(244,183,64,.55);
|
|
177
|
-
border-radius:10px;background:rgba(244,183,64,.06);
|
|
207
|
+
border-radius:10px;background:rgba(244,183,64,.06);color:var(--slm-text);
|
|
208
|
+
font-family:ui-monospace,Menlo,monospace;font-size:11px;
|
|
178
209
|
overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
|
|
179
210
|
.slm-ch-err{color:var(--slm-text);font-size:11.5px;margin-top:6px}
|
|
180
211
|
.slm-ch-price-list{display:flex;flex-direction:column;gap:7px}
|
|
@@ -186,12 +217,25 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
186
217
|
.slm-ch-price-row small{font-size:10.5px;color:var(--slm-muted);font-weight:500}
|
|
187
218
|
.slm-ch-price-row .slm-input{margin:0;text-align:right;font-variant-numeric:tabular-nums}
|
|
188
219
|
|
|
189
|
-
/* buyer links \u2014 STATUS only
|
|
220
|
+
/* buyer links \u2014 STATUS only on the listing card: the URL is revealed once, at
|
|
221
|
+
creation, and the server keeps only a fingerprint, so there is nothing for a
|
|
222
|
+
listing-card Copy to write. Copy lives on the reveal sheet, where the string
|
|
223
|
+
actually exists. */
|
|
190
224
|
.slm-ch-link{padding:10px 11px;border:1px solid var(--slm-line);border-radius:10px;background:var(--slm-surface);
|
|
191
225
|
margin-bottom:8px}
|
|
192
226
|
.slm-ch-link .lk-head{display:flex;align-items:center;gap:8px}
|
|
193
227
|
.slm-ch-link .lk-name{flex:1;min-width:0;font-size:12.5px;font-weight:800;overflow:hidden;text-overflow:ellipsis;
|
|
194
228
|
white-space:nowrap}
|
|
229
|
+
/* The revealed URL: one mono line that truncates rather than wrapping the sheet
|
|
230
|
+
out of shape. The full string stays in the title attribute and in the copy. */
|
|
231
|
+
.slm-ch-copyrow{display:flex;align-items:center;gap:8px;margin-top:8px}
|
|
232
|
+
.slm-ch-copyrow .slm-ch-secret{flex:1;min-width:0;margin:0}
|
|
233
|
+
.slm-ch-copyrow .slm-btn{flex:none;min-width:0;padding:8px 12px;min-height:40px;font-size:12px;
|
|
234
|
+
transition:opacity var(--slm-mo-quick) var(--slm-mo-out)}
|
|
235
|
+
/* "Copied" is a moment on the same control, never a second control: the label
|
|
236
|
+
changes and the button dims for the length of the confirmation. */
|
|
237
|
+
.slm-ch-copyrow .slm-btn.copied{opacity:.72}
|
|
238
|
+
.slm-ch-copysink{position:absolute;left:-9999px;top:0;width:1px;height:1px;opacity:0}
|
|
195
239
|
.slm-ch-lkrow{display:flex;gap:8px;margin-top:5px;font-size:11px;color:var(--slm-muted)}
|
|
196
240
|
.slm-ch-lkrow .k{flex:none;min-width:104px}
|
|
197
241
|
.slm-ch-lkrow .v{color:var(--slm-text);font-variant-numeric:tabular-nums}
|
|
@@ -239,12 +283,16 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
239
283
|
|
|
240
284
|
/* compact: bottom sheet with three detents (\xA713) */
|
|
241
285
|
.slm.compact.ch-sheet .slm-rail{position:absolute;left:0;right:0;bottom:0;z-index:8;border-top:1px solid var(--slm-line);
|
|
242
|
-
border-radius:18px 18px 0 0;background
|
|
286
|
+
border-radius:18px 18px 0 0;background:var(--slm-surface);color:var(--slm-text);
|
|
243
287
|
transition:height var(--slm-mo-slow) var(--slm-mo-in-out)}
|
|
244
288
|
.slm.compact.ch-sheet.detent-collapsed .slm-rail{height:132px}
|
|
245
289
|
.slm.compact.ch-sheet.detent-medium .slm-rail{height:46%}
|
|
246
290
|
.slm.compact.ch-sheet.detent-full .slm-rail{height:92%}
|
|
247
291
|
.slm.compact.ch-sheet .slm-railscroll{padding:8px 14px calc(12px + env(safe-area-inset-bottom,0px))}
|
|
292
|
+
/* Same pinned header in the sheet, bled against the sheet's own padding so the
|
|
293
|
+
create action is in reach at every detent. */
|
|
294
|
+
.slm.compact.ch-sheet .slm-ch-listhead{top:-8px;margin:0 -14px 10px;padding:8px 14px 8px}
|
|
295
|
+
.slm.compact .slm-ch-new{min-height:40px}
|
|
248
296
|
.slm-ch-grab{display:none}
|
|
249
297
|
.slm.compact.ch-sheet .slm-ch-grab{display:flex;align-items:center;gap:10px;width:100%;padding:6px 0 10px}
|
|
250
298
|
.slm-ch-grabbar{width:42px;height:4px;border-radius:2px;background:var(--slm-muted);margin:0 auto}
|
|
@@ -252,26 +300,26 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
252
300
|
.slm.compact .slm-btn,.slm.compact .slm-ch-row,.slm.compact .slm-ch-viewseg button{min-height:44px}
|
|
253
301
|
@media (prefers-reduced-motion:reduce){
|
|
254
302
|
.slm-ch-layer,.slm-ch-banner,.slm-ch-staged,.slm-ch-row,.slm.compact.ch-sheet .slm-rail,
|
|
255
|
-
.slm-ch-meter i,.slm-ch-radio{transition:none!important}
|
|
303
|
+
.slm-ch-meter i,.slm-ch-radio,.slm-ch-copyrow .slm-btn{transition:none!important}
|
|
256
304
|
.slm-ch-staged.shake,.slm-ch-tick,.slm-ch-bucket,.slm-ch-scrim,.slm-ch-dialog,
|
|
257
305
|
.slm-ch-counts b.bump,.slm-ch-selnum.bump{animation:none!important}
|
|
258
306
|
.slm-ch-busy::before{animation:none!important;opacity:1}
|
|
259
307
|
.slm-ch-staged.shake{outline:2px solid #e5484d;outline-offset:2px}
|
|
260
308
|
.slm-ch-staged.done{outline:2px solid #5bd39b;outline-offset:2px}
|
|
261
309
|
}
|
|
262
|
-
`;var
|
|
310
|
+
`;var at=3e4,De=300,A=5e3,Me=class{constructor(e,t){this.active=!1;this.list=null;this.allocation=new Map;this.assignmentVersion=0;this.loadError=null;this.loading=!0;this.view="inspect";this.mapIntent="pan";this.focusedSectionId=null;this.showArchived=!1;this.detailChannelId=null;this.assignOpen=!1;this.targetChannelId="";this.conflict=!1;this.dialog=null;this.detent="medium";this.seatListLimit=De;this.links=[];this.linksChannelId=null;this.linksState="idle";this.listSeq=0;this.linksSeq=0;this.previewAudience=[];this.previewIncludePublic=!1;this.previewProjection=null;this.previewState="idle";this.pollTimer=null;this.layer=null;this.canvas=null;this.ctx=void 0;this.bannerEl=null;this.stagedEl=null;this.liveEl=null;this.scrimEl=null;this.lastFocus=null;this.stagedDoneTimer=null;this.lastSelectionCount=0;this.lastCounts=new Map;this.assignmentRowsCache=null;this.railHtml=null;this.allocationVersion=null;this.onVisibility=null;this.host=e,this.caps=t}enter(){this.active||(this.active=!0,this.mapIntent="pan",this.assignOpen=!1,this.focusedSectionId=null,this.assignmentRowsCache=null,this.railHtml=null,this.ensureLayer(),this.host.root.classList.add("ch-mode"),this.applySheetClasses(),this.host.sections().length>1&&this.host.showSectionOverview(),this.paintRail(),this.onInteractionChange?.(),this.refresh(),this.pollTimer=setInterval(()=>{typeof document<"u"&&document.hidden||this.refresh({quiet:!0})},at),typeof document<"u"&&typeof document.addEventListener=="function"&&(this.onVisibility=()=>{this.active&&!document.hidden&&this.refresh({quiet:!0})},document.addEventListener("visibilitychange",this.onVisibility)))}leave(){this.active&&(this.active=!1,this.pollTimer&&clearInterval(this.pollTimer),this.pollTimer=null,this.onVisibility&&typeof document<"u"&&document.removeEventListener("visibilitychange",this.onVisibility),this.onVisibility=null,this.railHtml=null,this.closeDialog({restoreFocus:!1}),this.links=[],this.linksChannelId=null,this.linksState="idle",this.layer?.classList.remove("on"),this.host.root.classList.remove("ch-mode","ch-preview","ch-sheet","detent-collapsed","detent-medium","detent-full"),this.setBanner(!1),this.setStaged(null))}destroy(){this.leave(),this.stagedDoneTimer&&clearTimeout(this.stagedDoneTimer),this.layer?.remove(),this.layer=null,this.bannerEl?.remove(),this.bannerEl=null}setCapabilities(e){this.caps=e,this.active&&this.paintRail()}isActive(){return this.active}canSelect(){return this.caps.manage&&this.view==="inspect"}usesMarqueeSelection(){return this.canSelect()&&this.mapIntent==="assign"}handleSectionFocus(e){this.active&&(this.focusedSectionId=e,this.paintRail())}applyRealtimeHint(){this.active&&this.refresh({quiet:!0})}handleSelectionChange(){this.active&&(this.paintSelection(),this.paintStagedBar())}handleViewChange(){this.active&&this.paintOverlay()}handleLayoutChange(){this.active&&(this.applySheetClasses(),this.paintOverlay())}async refresh(e={}){if(!this.caps.view)return;let t=++this.listSeq,n=()=>t!==this.listSeq;try{let s=await this.host.api.channels(this.host.eventKey,{includeArchived:this.showArchived});if(n())return;if(this.list=s,this.assignmentVersion=s.assignmentVersion,this.loadError=null,this.targetChannelId||(this.targetChannelId=s.channels.find(r=>r.state==="active")?.id??$),this.allocationVersion!==s.assignmentVersion){if(await this.loadAllocation(t),n())return;this.allocationVersion=s.assignmentVersion}if(this.detailChannelId&&await this.loadLinks(this.detailChannelId),n())return;this.loading=!1,this.active&&(this.paintRail(),this.paintOverlay())}catch(s){if(n())return;this.loading=!1,s instanceof g&&s.status===403&&(this.caps={view:!1,manage:!1}),this.loadError=s,e.quiet||this.host.onError(s),this.active&&this.paintRail()}}async loadAllocation(e){let t=new Map,n;for(let s=0;s<200;s+=1){if(e!==void 0&&e!==this.listSeq)return;let r=await this.host.api.channelAllocation(this.host.eventKey,{afterLabel:n,limit:1e3});for(let o of r.allocations)D(o.channelId)||t.set(o.label,o.channelId);if(this.assignmentVersion=r.assignmentVersion,!r.nextAfterLabel)break;n=r.nextAfterLabel}e!==void 0&&e!==this.listSeq||(this.allocation=t)}channelById(e){if(D(e))return{id:$,name:this.list?.publicSale?.name??P,marker:"P",color:null};let t=this.list?.channels.find(n=>n.id===e);return t?{id:e,name:t.name,marker:t.marker,color:t.color}:null}nameOf(e){return this.channelById(e)?.name??null}markerFor(e){let t=Math.max(0,this.list?.channels.findIndex(s=>s.id===e)??0),n=this.channelById(e);return de(n??{id:e,name:"?",marker:null,color:null},t)}assignableChannels(){return[{id:$,name:this.list?.publicSale.name??P},...(this.list?.channels??[]).filter(e=>e.state!=="archived").map(e=>({id:e.id,name:e.name}))]}currentPlan(){let e=this.host.selectionLabels(),t=pe({labels:e,targetChannelId:this.targetChannelId,allocation:this.allocation,statusOf:n=>this.host.statusOf(n),nameOf:n=>this.nameOf(n)});return{labels:e,buckets:t,target:this.targetChannelId}}ensureLayer(){if(this.layer)return;let e=document.createElement("div");e.className="slm-ch-layer",e.innerHTML=`
|
|
263
311
|
<canvas class="slm-ch-canvas" data-ch="canvas" aria-hidden="true"></canvas>
|
|
264
312
|
<div class="slm-ch-banner" data-ch="banner" role="status"></div>
|
|
265
313
|
<div class="slm-ch-staged" data-ch="staged" role="group" aria-label="Staged channel changes"></div>
|
|
266
|
-
<div class="slm-ch-live" data-ch="live" role="status" aria-live="polite"></div>`,this.host.mapLayer.appendChild(e),this.layer=e,this.canvas=e.querySelector('[data-ch="canvas"]'),this.bannerEl=e.querySelector('[data-ch="banner"]'),this.stagedEl=e.querySelector('[data-ch="staged"]'),this.liveEl=e.querySelector('[data-ch="live"]'),requestAnimationFrame(()=>e.classList.add("on"))}announce(e){this.liveEl&&(this.liveEl.textContent=e)}paintOverlay(){let e=this.canvas,t=this.layer;!e||!t||
|
|
314
|
+
<div class="slm-ch-live" data-ch="live" role="status" aria-live="polite"></div>`,this.host.mapLayer.appendChild(e),this.layer=e,this.canvas=e.querySelector('[data-ch="canvas"]'),this.bannerEl=e.querySelector('[data-ch="banner"]'),this.bannerEl&&this.host.pillLane&&this.host.pillLane.appendChild(this.bannerEl),this.stagedEl=e.querySelector('[data-ch="staged"]'),this.liveEl=e.querySelector('[data-ch="live"]'),requestAnimationFrame(()=>e.classList.add("on"))}announce(e){this.liveEl&&(this.liveEl.textContent=e)}paintOverlay(){let e=this.canvas,t=this.layer;!e||!t||Te({layer:t,canvas:e,resolveCtx:()=>{if(this.ctx===void 0)try{this.ctx=e.getContext("2d")}catch{this.ctx=null}return this.ctx},host:this.host,view:this.view,previewProjection:this.previewProjection,allocation:this.allocation,focusedSectionId:this.focusedSectionId,list:this.list,markerFor:n=>this.markerFor(n),onSectionTargetClick:n=>{this.focusedSectionId=n,this.host.focusSection(n),this.paintRail()}})}setStaged(e,t=""){let n=this.stagedEl;if(n){if(!e){n.classList.remove("on","done","shake"),n.innerHTML="";return}n.innerHTML=e,n.className=`slm-ch-staged on${t?` ${t}`:""}`}}paintStagedBar(){if(!this.active||this.view==="preview"||!this.caps.manage){this.setStaged(null);return}let{labels:e,buckets:t}=this.currentPlan();if(this.host.onStagedChange?.(K(t)),!e.length){this.setStaged(null);return}let n=this.nameOf(this.targetChannelId)??P,s=K(t),r=e.length>A,o=t.skippedHeld.count+t.skippedBooked.count,a=[`<b>${e.length.toLocaleString()}</b> selected`,`<b>+${s.toLocaleString()}</b> to ${c(n)}`];t.alreadyInTarget.count&&a.push(`<b>${t.alreadyInTarget.count.toLocaleString()}</b> already in`),o&&a.push(`<b>${o.toLocaleString()}</b> can't move now`),this.setStaged(`
|
|
267
315
|
<span>${a.join(" \xB7 ")}</span>
|
|
268
316
|
<span class="grow"></span>
|
|
269
317
|
<button type="button" class="drop" data-ch-act="discard">Discard</button>
|
|
270
318
|
<button type="button" class="go" data-ch-act="review"${r?" disabled":""}>
|
|
271
|
-
${r?`Maximum ${
|
|
319
|
+
${r?`Maximum ${A.toLocaleString()} seats`:"Review changes"}
|
|
272
320
|
</button>`),this.stagedEl?.querySelectorAll("[data-ch-act]").forEach(l=>{l.addEventListener("click",()=>{l.dataset.chAct==="discard"?this.host.clearSelection():this.openDialog({kind:"review"})})})}setBanner(e,t="",n){let s=this.bannerEl;if(!s)return;if(this.host.root.classList.toggle("ch-preview",e),!e){s.classList.remove("on"),s.innerHTML="";return}let r=this.previewAudience.length===1?this.markerFor(this.previewAudience[0]):{color:"var(--slm-accent)",letter:""},o=n==null?"":` \xB7 ${n.toLocaleString()} ${n===1?"seat":"seats"} available now`;s.innerHTML=`<span class="dot" style="background:${c(r.color)}"></span>
|
|
273
321
|
Previewing buyer access \xB7 ${c(t)}${o} \xB7 read-only
|
|
274
|
-
<button type="button" data-ch-act="exit-preview">Exit preview</button>`,s.classList.add("on"),s.querySelector('[data-ch-act="exit-preview"]')?.addEventListener("click",()=>this.setView("inspect"))}setView(e){if(this.view=e,e==="inspect")this.previewProjection=null,this.previewState="idle",this.setBanner(!1);else{if(!this.previewAudience.length){let t=this.list?.channels.find(n=>n.state==="active");this.previewAudience=[t?t.id:$]}this.loadPreview()}this.paintRail(),this.paintOverlay(),this.paintStagedBar(),this.onInteractionChange?.()}async loadPreview(){let e=[...this.previewAudience],t=e.map(n=>this.nameOf(n)??
|
|
322
|
+
<button type="button" data-ch-act="exit-preview">Exit preview</button>`,s.classList.add("on"),s.querySelector('[data-ch-act="exit-preview"]')?.addEventListener("click",()=>this.setView("inspect"))}setView(e){if(this.view=e,e==="inspect")this.previewProjection=null,this.previewState="idle",this.setBanner(!1);else{if(!this.previewAudience.length){let t=this.list?.channels.find(n=>n.state==="active");this.previewAudience=[t?t.id:$]}this.loadPreview()}this.paintRail(),this.paintOverlay(),this.paintStagedBar(),this.onInteractionChange?.()}async loadPreview(){let e=[...this.previewAudience],t=e.map(n=>this.nameOf(n)??P).join(" + ");this.setBanner(!0,t),this.previewProjection=null,this.previewState="loading",this.active&&this.paintRail();try{this.previewProjection=await this.host.api.channelPreview(this.host.eventKey,e,{includePublic:this.previewIncludePublic||e.some(D)}),this.previewState="ready";let n=this.previewProjection.available===!1?void 0:this.previewProjection.counts?.eligible??this.previewProjection.eligible?.length;this.setBanner(!0,t,n)}catch(n){let s=n instanceof g?n.status:0;this.previewState=s===404||s===405||s===501?"unsupported":"error",this.previewProjection=null,this.previewState==="error"&&this.host.onError(n)}this.active&&(this.paintRail(),this.paintOverlay())}setRailHtml(e){if(e===this.railHtml)return!1;let t=this.host.rail,n=t.scrollTop;return t.innerHTML=e,this.railHtml=e,n&&(t.scrollTop=n),!0}paintRail(){if(!this.active)return;let e=this.host.rail;if(!this.caps.view){this.setRailHtml(`<p class="slm-eyebrow">Sales channels</p>
|
|
275
323
|
<p class="slm-hint">You need channel-management permission on this event to see allocations.</p>`);return}if(this.loading&&!this.list){this.setRailHtml(`<p class="slm-eyebrow">Sales channels</p>
|
|
276
324
|
<div class="slm-ch-busy" role="status" data-ch-state="list-loading">Loading channels and allocations\u2026</div>`);return}if(!this.list&&this.loadError){this.setRailHtml(`<p class="slm-eyebrow">Sales channels</p>
|
|
277
325
|
<div class="slm-ch-alert err" role="alert" data-ch-state="list-error"><span>\u26A0</span>
|
|
@@ -283,23 +331,23 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
283
331
|
<button type="button" class="${t.trim()}" data-ch-view="preview"
|
|
284
332
|
aria-pressed="${this.view==="preview"}">Buyer preview</button>
|
|
285
333
|
</div>${this.mapNavigationHtml()}`}mapNavigationHtml(){if(this.host.sections().length<2)return"";let e=this.focusedSectionId?this.host.sections().find(t=>t.id===this.focusedSectionId)?.label??"section":null;return e?`<div class="slm-ch-mapnav-head"><span>${c(e)}</span>
|
|
286
|
-
<button type="button" data-ch-act="sections">All sections</button></div>`:""}countsHtml(e,t){let n=(s,r,o,a="")=>{let l=this.lastCounts.get(`${t}:${s}`),
|
|
334
|
+
<button type="button" data-ch-act="sections">All sections</button></div>`:""}countsHtml(e,t){let n=(s,r,o,a="")=>{let l=this.lastCounts.get(`${t}:${s}`),h=l!=null&&l!==r?" bump":"";return this.lastCounts.set(`${t}:${s}`,r),`<span class="${a}"><b class="${h.trim()}">${r.toLocaleString()}</b> ${o}</span>`};return`<span class="slm-ch-counts">
|
|
287
335
|
${n("allocated",e.allocated,"allocated")}
|
|
288
336
|
${n("free",e.free,"free","free")}
|
|
289
337
|
${n("booked",e.booked,"sold")}
|
|
290
338
|
${e.held?n("held",e.held,"held"):""}
|
|
291
339
|
</span>`}channelRowHtml(e,t={}){let n=this.markerFor(e.id),s=t.builtin?"builtin":e.state,r=e.state==="paused"||e.state==="archived"?" dim":"",o=!t.builtin&&this.caps.manage&&this.detailChannelId!==e.id,a=`slm-ch-row${t.builtin?" public":""}${e.state==="archived"?" archived":""}${this.detailChannelId===e.id?" on":""}${o?" open":""}`,l=!t.builtin&&this.caps.manage?`<button type="button" class="slm-ch-more" data-ch-menu="${c(e.id)}"
|
|
292
|
-
aria-label="More actions for ${c(e.name)}" aria-haspopup="dialog">\u22EF</button>`:"",
|
|
293
|
-
aria-label="Open ${c(e.name)}"`:"";return`<div class="${a}"${
|
|
340
|
+
aria-label="More actions for ${c(e.name)}" aria-haspopup="dialog">\u22EF</button>`:"",h=o?` role="button" tabindex="0" data-ch-open="${c(e.id)}"
|
|
341
|
+
aria-label="Open ${c(e.name)}"`:"";return`<div class="${a}"${h}>
|
|
294
342
|
<span class="slm-ch-head">
|
|
295
343
|
<span class="slm-ch-mk${r}" style="background:${c(n.color)}" aria-hidden="true">${c(n.letter)}</span>
|
|
296
344
|
<span class="slm-ch-name">${c(e.name)}</span>
|
|
297
|
-
<span class="slm-ch-badge ${s}">${c(
|
|
345
|
+
<span class="slm-ch-badge ${s}">${c(we(t.builtin?"builtin":e.state))}</span>
|
|
298
346
|
${l}
|
|
299
347
|
</span>
|
|
300
348
|
${this.countsHtml(e.counts,e.id||"public")}
|
|
301
|
-
${t.builtin?"":`<span class="slm-ch-access">${c(
|
|
302
|
-
</div>`}listRailHtml(){let e=this.list,t=e.channels.filter(l=>l.state==="archived").length,n=e.channels.filter(l=>this.showArchived||l.state!=="archived"),s=[this.channelRowHtml(e.publicSale,{builtin:!0}),...n.map((l,
|
|
349
|
+
${t.builtin?"":`<span class="slm-ch-access">${c(ve(e.access))}</span>`}
|
|
350
|
+
</div>`}listRailHtml(){let e=this.list,t=e.channels.filter(l=>l.state==="archived").length,n=e.channels.filter(l=>this.showArchived||l.state!=="archived"),s=[this.channelRowHtml(e.publicSale,{builtin:!0}),...n.map((l,h)=>this.channelRowHtml(l,{index:h}))].join(""),r=n.length?"":`<p class="slm-note" data-ch-state="list-empty">${t&&!this.showArchived?`No open channels \u2014 every seat is on public sale. ${t.toLocaleString()} archived channel${t===1?" is":"s are"} hidden below.`:"No private channels yet \u2014 every seat is on public sale."}</p>`,o=this.caps.manage?'<button type="button" class="slm-btn slm-ch-new" data-ch-act="create">+ New channel</button>':"",a=this.caps.manage?"":'<p class="slm-note">You can see how inventory is allocated. Changing it needs channel-management permission.</p>';return`
|
|
303
351
|
<div class="slm-ch-listhead"><h2>Sales channels</h2>${o}</div>
|
|
304
352
|
<div class="slm-ch-list">${s}</div>
|
|
305
353
|
${r}
|
|
@@ -327,10 +375,10 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
327
375
|
<button type="button" class="slm-btn ghost" data-ch-act="seatlist">Seat list \u2328</button>
|
|
328
376
|
</div>
|
|
329
377
|
<p class="slm-note" style="margin-bottom:18px">Choose a destination, then add whole sections,
|
|
330
|
-
multiple rows, a dragged area, or individual seats.</p>`}selectionRailHtml(e){let t=
|
|
378
|
+
multiple rows, a dragged area, or individual seats.</p>`}selectionRailHtml(e){let t=ue(e,this.allocation,this.list),n=this.conflict?`<div class="slm-ch-alert err" role="alert"><span>\u26A0</span>
|
|
331
379
|
<span><b>Assignments changed while you were editing.</b> Nothing was applied.
|
|
332
380
|
Your ${e.length.toLocaleString()}-seat selection is kept.
|
|
333
|
-
<button type="button" data-ch-act="refresh-review">Refresh and review \u2192</button></span></div>`:"",s=e.length!==this.lastSelectionCount?" bump":"";this.lastSelectionCount=e.length;let r=e.length>
|
|
381
|
+
<button type="button" data-ch-act="refresh-review">Refresh and review \u2192</button></span></div>`:"",s=e.length!==this.lastSelectionCount?" bump":"";this.lastSelectionCount=e.length;let r=e.length>A,o=t.map(a=>{let l=this.markerFor(a.channelId);return`<div class="slm-ch-selsrc-row">
|
|
334
382
|
<span class="mk" style="background:${c(l.color)}" aria-hidden="true">${c(l.letter)}</span>
|
|
335
383
|
<b>${a.count.toLocaleString()}</b><span>${c(a.name)}</span></div>`}).join("");return`
|
|
336
384
|
${n}
|
|
@@ -339,7 +387,7 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
339
387
|
<span class="slm-sellabel">selected</span></div>
|
|
340
388
|
<div class="slm-ch-selsrc" aria-live="polite" aria-label="Selection sources">${o}</div>
|
|
341
389
|
${r?`<div class="slm-ch-alert warn" role="alert"><span>\u2139</span><span>
|
|
342
|
-
<b>This selection is too large to apply at once.</b> Choose at most ${
|
|
390
|
+
<b>This selection is too large to apply at once.</b> Choose at most ${A.toLocaleString()}
|
|
343
391
|
seats, for example by splitting the venue into row groups.</span></div>`:""}
|
|
344
392
|
<p class="slm-note">Changes are staged \u2014 nothing moves until you review and apply.
|
|
345
393
|
Seats in checkout or already sold are never moved.</p>
|
|
@@ -371,11 +419,11 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
371
419
|
<div class="slm-ch-list">${this.channelRowHtml(n)}</div>
|
|
372
420
|
${a}
|
|
373
421
|
${r}
|
|
374
|
-
${s}`}distributeHtml(e){let t=e.access?.intent??"none",n=e.access?.hasActiveGrants===!0,s=this.linksState!=="unsupported",r=this.links.some(ne),o=t==="none"?"Protected reserve \u2014 no route can sell these seats. Every buyer path is refused.":t==="internal"?"Your staff sell these seats. No buyer-facing route is open.":n?t==="server"?"Your website is letting buyers in. Only they can buy these seats.":"A buyer link is live. Only people with that link can buy these seats.":t==="server"?"Set up for your website \u2014 no buyer has come through yet. Seats stay reserved.":"Set up for buyer links \u2014 no buyer has come through yet. Seats stay reserved.",a=(l,d,
|
|
375
|
-
<b>${c(
|
|
376
|
-
<span class="why">${c(
|
|
377
|
-
${
|
|
378
|
-
data-ch-act="${c(
|
|
422
|
+
${s}`}distributeHtml(e){let t=e.access?.intent??"none",n=e.access?.hasActiveGrants===!0,s=this.linksState!=="unsupported",r=this.links.some(ne),o=t==="none"?"Protected reserve \u2014 no route can sell these seats. Every buyer path is refused.":t==="internal"?"Your staff sell these seats. No buyer-facing route is open.":n?t==="server"?"Your website is letting buyers in. Only they can buy these seats.":"A buyer link is live. Only people with that link can buy these seats.":t==="server"?"Set up for your website \u2014 no buyer has come through yet. Seats stay reserved.":"Set up for buyer links \u2014 no buyer has come through yet. Seats stay reserved.",a=(l,h,d,u)=>{let k=l===t;return`<div class="slm-ch-dist${k?" on":""}" data-ch-route="${c(l)}">
|
|
423
|
+
<b>${c(q(l))}${k?'<span class="cur">Current route</span>':""}</b>
|
|
424
|
+
<span class="why">${c(fe(l))}</span>
|
|
425
|
+
${k&&!d?"":`<button type="button" class="slm-btn${u&&!k?"":" ghost"}"
|
|
426
|
+
data-ch-act="${c(h)}">${c(d)}</button>`}
|
|
379
427
|
</div>`};return`
|
|
380
428
|
<p class="slm-eyebrow" style="margin-top:14px">Distribute</p>
|
|
381
429
|
<p class="slm-hint">${c(o)}</p>
|
|
@@ -384,14 +432,14 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
384
432
|
${a("internal","route-internal",t==="internal"?"":"Hand to your staff",!1)}
|
|
385
433
|
${a("none","route-none",t==="none"?"":"Keep as reserve",!1)}
|
|
386
434
|
${this.hostedLinksHtml()}
|
|
387
|
-
${t==="server"?Re:""}`}async loadLinks(e){if(!this.caps.view)return;let t=++this.linksSeq,n=()=>t!==this.linksSeq||this.linksChannelId!==e;this.linksChannelId!==e&&(this.links=[],this.linksChannelId=e,this.linksState="loading");try{let s=await this.host.api.accessLinks(this.host.eventKey,e);if(n())return;this.links=s.links??[],this.linksState="ready"}catch(s){if(n())return;let r=s instanceof
|
|
435
|
+
${t==="server"?Re:""}`}async loadLinks(e){if(!this.caps.view)return;let t=++this.linksSeq,n=()=>t!==this.linksSeq||this.linksChannelId!==e;this.linksChannelId!==e&&(this.links=[],this.linksChannelId=e,this.linksState="loading");try{let s=await this.host.api.accessLinks(this.host.eventKey,e);if(n())return;this.links=s.links??[],this.linksState="ready"}catch(s){if(n())return;let r=s instanceof g?s.status:0;this.links=[],this.linksState=r===404||r===405||r===501?"unsupported":"error",this.linksState==="error"&&this.host.onError(s)}}hostedLinksHtml(){let e='<p class="slm-eyebrow" style="margin-top:18px">Buyer links</p>';return this.linksState==="unsupported"?`${e}<div class="slm-ch-alert warn" data-ch-state="links-unsupported"><span>\u2139</span>
|
|
388
436
|
<span><b>Buyer links need a newer server.</b> Everything else on this channel works normally.</span></div>`:this.linksState==="error"?`${e}<div class="slm-ch-alert err" role="alert" data-ch-state="links-error"><span>\u26A0</span>
|
|
389
437
|
<span><b>Couldn't load this channel's links.</b> This is a failed read, not an empty list \u2014
|
|
390
438
|
any live link is still working.
|
|
391
439
|
<button type="button" data-ch-act="link-reload">Try again</button></span></div>`:this.linksState==="idle"||this.linksState==="loading"&&!this.links.length?`${e}<div class="slm-ch-busy" role="status" data-ch-state="links-loading">Loading buyer links\u2026</div>`:this.links.length?`${e}
|
|
392
440
|
${this.links.map(t=>this.linkCardHtml(t)).join("")}
|
|
393
441
|
<p class="slm-note">A link is shown once, when you create it. SeatLayer keeps only a fingerprint of it, so it
|
|
394
|
-
can never be shown again \u2014 if a link is lost, rotate it and send the fresh one.</p>`:""}linkCardHtml(e){let t=
|
|
442
|
+
can never be shown again \u2014 if a link is lost, rotate it and send the fresh one.</p>`:""}linkCardHtml(e){let t=ke(e),n=e.maxRedemptions>0?Math.min(100,Math.round(e.redemptions/e.maxRedemptions*100)):0,s=se(e).map(l=>`<div class="slm-ch-lkrow"><span class="k">${c(l.k)}</span>
|
|
395
443
|
<span class="v">${c(l.v)}</span></div>`).join(""),r=e.activeSessions?`<div class="slm-ch-lkrow"><span class="k">Buyers inside now</span>
|
|
396
444
|
<span class="v">${e.activeSessions.toLocaleString()}</span></div>`:"",o=e.lastRedeemedAt?`<div class="slm-ch-lkrow"><span class="k">Last opened</span>
|
|
397
445
|
<span class="v">${c(new Date(e.lastRedeemedAt).toLocaleString())}</span></div>`:"",a=this.caps.manage&&ne(e)?`<div class="slm-ch-row2">
|
|
@@ -409,15 +457,15 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
409
457
|
<div class="slm-ch-lkrow"><span class="k">The URL</span>
|
|
410
458
|
<span class="v">Revealed once at creation \u2014 not recoverable</span></div>
|
|
411
459
|
${a}
|
|
412
|
-
</div>`}previewRailHtml(){let e=[{id:$,name:this.list?.publicSale.name??
|
|
460
|
+
</div>`}previewRailHtml(){let e=[{id:$,name:this.list?.publicSale.name??P},...(this.list?.channels??[]).filter(u=>u.state!=="archived").map(u=>({id:u.id,name:u.name}))],t=this.previewAudience[0]??$,n=e.map(u=>`<option value="${c(u.id)}"${u.id===t?" selected":""}>${c(u.name)}</option>`).join(""),s=this.previewState==="unsupported"?`<div class="slm-ch-alert warn" data-ch-state="preview-unsupported"><span>\u2139</span>
|
|
413
461
|
<span><b>Preview needs a newer server.</b> Allocation management works normally;
|
|
414
462
|
the buyer-view simulation will appear once this event's API is updated.</span></div>`:"",r=this.previewState==="loading"?'<div class="slm-ch-busy" role="status" data-ch-state="preview-loading">Asking the server what this audience sees\u2026</div>':"",o=this.previewState==="error"?`<div class="slm-ch-alert err" role="alert" data-ch-state="preview-error"><span>\u26A0</span>
|
|
415
463
|
<span><b>Couldn't load the buyer preview.</b> Nothing is wrong with this audience's seats \u2014
|
|
416
464
|
the simulation itself failed to load.
|
|
417
465
|
<button type="button" data-ch-act="preview-retry">Try again</button></span></div>`:"",a=this.previewProjection?.available===!1?`<div class="slm-ch-alert warn" role="status"><span>\u23F8</span>
|
|
418
466
|
<span><b>This private sale is not available.</b> ${c((this.previewProjection.unavailable??[]).map(u=>`${this.nameOf(u.channelId)??"This channel"} is ${u.state}`).join("; ")||"The audience cannot buy right now")}.
|
|
419
|
-
A buyer arriving with this access sees this message, not these seats.</span></div>`:"",l=this.previewProjection?.counts?.eligible??this.previewProjection?.eligible?.length,
|
|
420
|
-
This is the exact buyer-visible allocation.${this.previewProjection?.includePublic===!1?" Public sale seats are <b>not</b> included in this access.":""}</span></div>`:"",
|
|
467
|
+
A buyer arriving with this access sees this message, not these seats.</span></div>`:"",l=this.previewProjection?.counts?.eligible??this.previewProjection?.eligible?.length,h=l!=null&&this.previewProjection?.available!==!1?`<div class="slm-ch-alert info"><span>\u2713</span><span><b>${l.toLocaleString()} ${l===1?"seat is":"seats are"} available now.</b>
|
|
468
|
+
This is the exact buyer-visible allocation.${this.previewProjection?.includePublic===!1?" Public sale seats are <b>not</b> included in this access.":""}</span></div>`:"",d=D(t)?"":`
|
|
421
469
|
<label class="slm-note" style="display:flex;gap:8px;align-items:center;margin:10px 0">
|
|
422
470
|
<input type="checkbox" data-ch-includepublic ${this.previewIncludePublic?"checked":""} />
|
|
423
471
|
Also include Public sale seats in this grant
|
|
@@ -427,7 +475,7 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
427
475
|
<label for="slm-ch-audience">Audience</label>
|
|
428
476
|
<select class="slm-select" id="slm-ch-audience" data-ch-audience>${n}</select>
|
|
429
477
|
</div>
|
|
430
|
-
${
|
|
478
|
+
${d}
|
|
431
479
|
<p class="slm-hint">This is the same projection the buyer SDK receives for this audience \u2014 not a local
|
|
432
480
|
approximation. It is read-only: clicks open seat details, and no holds are created.</p>
|
|
433
481
|
${r}${o}${s}${a}
|
|
@@ -436,7 +484,7 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
436
484
|
<div class="r"><span class="sw" style="background:#3a4051"></span> Unavailable to this audience (one neutral state)</div>
|
|
437
485
|
<div class="r"><span class="sw" style="background:#22a06b"></span> Sold \u2014 same as any buyer sees</div>
|
|
438
486
|
</div>
|
|
439
|
-
${
|
|
487
|
+
${h}`}paintSelection(){this.caps.manage&&this.host.selectionLabels().length&&(this.assignOpen=!0),this.view==="inspect"&&!this.detailChannelId&&this.paintRail()}wireRail(){let e=this.host.rail;e.querySelectorAll("[data-ch-view]").forEach(o=>{o.addEventListener("click",()=>this.setView(o.dataset.chView))}),e.querySelectorAll("[data-ch-map]").forEach(o=>{o.addEventListener("click",()=>{this.mapIntent=o.dataset.chMap==="assign"?"assign":"pan",this.mapIntent==="assign"&&(this.assignOpen=!0),this.paintRail(),this.onInteractionChange?.()})}),e.querySelectorAll("[data-ch-open]").forEach(o=>{let a=()=>this.openChannel(o.dataset.chOpen);o.addEventListener("click",a),o.addEventListener("keydown",l=>{l.key!=="Enter"&&l.key!==" "&&l.key!=="Spacebar"||(l.preventDefault(),a())})}),e.querySelectorAll("[data-ch-menu]").forEach(o=>{o.addEventListener("click",a=>{a.stopPropagation(),this.openDialog({kind:"menu",channelId:o.dataset.chMenu})}),o.addEventListener("keydown",a=>{a.stopPropagation()})}),e.querySelectorAll("[data-ch-rotate]").forEach(o=>{o.addEventListener("click",()=>this.openDialog({kind:"linkRotate",channelId:this.detailChannelId,linkId:o.dataset.chRotate}))}),e.querySelectorAll("[data-ch-revoke]").forEach(o=>{o.addEventListener("click",()=>this.openDialog({kind:"linkRevoke",channelId:this.detailChannelId,linkId:o.dataset.chRevoke}))});let t=e.querySelector("[data-ch-target]");t?.addEventListener("change",()=>{this.targetChannelId=t.value,this.conflict=!1,this.paintRail()});let n=e.querySelector("[data-ch-audience]");n?.addEventListener("change",()=>{this.previewAudience=[n.value],this.loadPreview()});let s=e.querySelector("[data-ch-includepublic]");s?.addEventListener("change",()=>{this.previewIncludePublic=s.checked,this.loadPreview()}),e.querySelector(".slm-ch-grab")?.addEventListener("click",()=>this.cycleDetent()),e.querySelectorAll("[data-ch-act]").forEach(o=>{o.addEventListener("click",()=>this.railAction(o.dataset.chAct))})}openChannel(e){this.detailChannelId=e,this.paintRail(),this.loadLinks(e).then(()=>this.paintRail())}railAction(e){switch(e){case"sections":this.focusedSectionId=null,this.host.showSectionOverview(),this.paintRail();break;case"create":this.openDialog({kind:"create"});break;case"review":this.openDialog({kind:"review"});break;case"rename":this.openDialog({kind:"rename",channelId:this.detailChannelId});break;case"pricing":this.openDialog({kind:"pricing",channelId:this.detailChannelId});break;case"archive":this.openDialog({kind:"archive",channelId:this.detailChannelId});break;case"seatlist":this.openDialog({kind:"seatlist"});break;case"pause":this.togglePause();break;case"discard":this.host.clearSelection();break;case"back":this.detailChannelId=null,this.linksChannelId=null,this.links=[],this.linksState="idle",this.paintRail();break;case"link-create":this.openDialog({kind:"linkCreate",channelId:this.detailChannelId});break;case"embed-code":this.chooseWebsiteIntegration();break;case"route-internal":this.setAccessIntent("internal");break;case"route-none":this.setAccessIntent("none");break;case"link-reload":this.detailChannelId&&this.reloadLinks();break;case"retry":this.refresh();break;case"toggle-archived":this.showArchived=!this.showArchived,this.refresh();break;case"refresh-review":this.conflict=!1,this.refresh().then(()=>this.openDialog({kind:"review"}));break;case"pick-sections":this.openDialog({kind:"scope",scope:"sections"});break;case"pick-rows":this.openDialog({kind:"scope",scope:"rows"});break;case"drag-select":this.mapIntent="assign",this.paintRail(),this.onInteractionChange?.();break;case"pick-category":this.pickCategory();break;case"assign-open":this.assignOpen=!0,this.mapIntent="assign",this.paintRail(),this.onInteractionChange?.();break;case"assign-close":this.assignOpen=!1,this.mapIntent="pan",this.paintRail(),this.onInteractionChange?.();break;case"preview-retry":this.loadPreview();break;default:break}}assignmentRows(){return this.assignmentRowsCache||(this.assignmentRowsCache=this.host.rows()),this.assignmentRowsCache}pickCategory(){let e=this.host.categories();e.length&&this.promptChoice("Select a whole category",e.map(t=>({value:t.key,label:t.label})),t=>{this.host.selectByLabels(this.host.labelsInCategory(t))})}promptChoice(e,t,n){this.renderScrim(`
|
|
440
488
|
<h3 id="slm-ch-dlg-title">${c(e)}</h3>
|
|
441
489
|
<div class="slm-field">
|
|
442
490
|
<label for="slm-ch-choice">Choose one</label>
|
|
@@ -460,26 +508,26 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
460
508
|
<div class="foot">
|
|
461
509
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
462
510
|
<button type="button" class="slm-btn" data-ch-add-scope disabled>Add seats</button>
|
|
463
|
-
</div>`,l=>{let
|
|
464
|
-
<button type="button" class="slm-ch-groupcheck" role="checkbox" aria-checked="${
|
|
465
|
-
aria-label="Select all ${S.length.toLocaleString()} rows in ${c(
|
|
466
|
-
<span class="box" aria-hidden="true">\u2713</span><span>${c(
|
|
467
|
-
<span class="meta">${S.length.toLocaleString()} rows \xB7 ${
|
|
511
|
+
</div>`,l=>{let h=new Map(s.map(p=>[p.id,p])),d=new Set,u=new Set,k=new Set(this.host.selectionLabels()),L=l.querySelector("[data-ch-add-scope]"),v=l.querySelector("[data-ch-error]"),m=l.querySelector("[data-ch-scope-list]"),b=l.querySelector("[data-ch-scope-search]"),w=l.querySelector("[data-ch-scope-summary]"),W=l.querySelector("[data-ch-scope-filter]"),M=200,R="",H=()=>{let p=new Set(k);for(let x of d)for(let T of h.get(x)?.labels??[])p.add(T);return p},f=()=>{let p=H(),x=p.size-k.size,T=p.size>A;L.disabled=x===0||T,L.textContent=T?`Maximum ${A.toLocaleString()} seats`:`Add ${x.toLocaleString()} seat${x===1?"":"s"}`,v.hidden=!T,v.textContent=T?`That would make ${p.size.toLocaleString()} selected seats. Choose fewer rows or sections.`:"",w.textContent=`${d.size.toLocaleString()} row${d.size===1?"":"s"} \xB7 ${x.toLocaleString()} seat${x===1?"":"s"} added`},y=()=>{let p=[],x=0,T=0;a.forEach(([I,S],z)=>{let O=I.toLocaleLowerCase(),_=R?S.filter(E=>`${O} ${E.label.toLocaleLowerCase()}`.includes(R)):S;if(R&&!_.length)return;x+=_.length;let re=S.every(E=>d.has(E.id)),He=!re&&S.some(E=>d.has(E.id)),U=!!R||u.has(z),Be=Math.max(0,M-T),N=U?_.slice(0,Be):[];T+=N.length;let qe=S.reduce((E,Oe)=>E+Oe.labels.length,0);p.push(`<div class="slm-ch-scopegroup">
|
|
512
|
+
<button type="button" class="slm-ch-groupcheck" role="checkbox" aria-checked="${re?"true":He?"mixed":"false"}"
|
|
513
|
+
aria-label="Select all ${S.length.toLocaleString()} rows in ${c(I)}" data-ch-scope-group="${z}">
|
|
514
|
+
<span class="box" aria-hidden="true">\u2713</span><span>${c(I)}</span>
|
|
515
|
+
<span class="meta">${S.length.toLocaleString()} rows \xB7 ${qe.toLocaleString()} seats</span>
|
|
468
516
|
</button>
|
|
469
|
-
<button type="button" class="slm-ch-grouptoggle" aria-expanded="${
|
|
470
|
-
data-ch-scope-toggle="${
|
|
471
|
-
</div>`),
|
|
472
|
-
aria-checked="${
|
|
473
|
-
<span class="box" aria-hidden="true">\u2713</span><span>${c(
|
|
474
|
-
<span class="meta">${
|
|
475
|
-
</button>`)),
|
|
476
|
-
Use Drag box or the seat list instead.</div>`),
|
|
517
|
+
<button type="button" class="slm-ch-grouptoggle" aria-expanded="${U}" aria-label="${U?"Hide":"Show"} rows in ${c(I)}"
|
|
518
|
+
data-ch-scope-toggle="${z}">${U?"Hide":"Show"}</button>
|
|
519
|
+
</div>`),p.push(...N.map(E=>`<button type="button" class="slm-ch-seatitem" role="checkbox"
|
|
520
|
+
aria-checked="${d.has(E.id)}" data-ch-scope-id="${c(E.id)}">
|
|
521
|
+
<span class="box" aria-hidden="true">\u2713</span><span>${c(E.label)}</span>
|
|
522
|
+
<span class="meta">${E.labels.length.toLocaleString()} seat${E.labels.length===1?"":"s"}</span>
|
|
523
|
+
</button>`)),U&&_.length>N.length&&p.push(`<p class="slm-ch-scopehint">${(_.length-N.length).toLocaleString()} more row${_.length-N.length===1?"":"s"}. Search to narrow the list.</p>`)}),m.innerHTML=p.join("")||(R?`<div class="slm-ch-scope-empty" data-ch-state="scope-nomatch">No sections or rows match \u201C${c(R)}\u201D.</div>`:`<div class="slm-ch-scope-empty" data-ch-state="scope-empty">This chart has no rows with selectable seats.
|
|
524
|
+
Use Drag box or the seat list instead.</div>`),W.textContent=R?`Showing ${T.toLocaleString()} of ${x.toLocaleString()} matching rows. Section checkboxes still select every row in that section.`:"Showing section groups. Expand one or search to see rows.",m.querySelectorAll("[data-ch-scope-group]").forEach(I=>I.addEventListener("click",()=>{let S=a[Number(I.dataset.chScopeGroup)]?.[1]??[],z=S.every(O=>d.has(O.id));for(let O of S)z?d.delete(O.id):d.add(O.id);y(),f()})),m.querySelectorAll("[data-ch-scope-toggle]").forEach(I=>I.addEventListener("click",()=>{let S=Number(I.dataset.chScopeToggle);u.has(S)?u.delete(S):u.add(S),y()})),m.querySelectorAll("[data-ch-scope-id]").forEach(I=>I.addEventListener("click",()=>{let S=I.dataset.chScopeId;d.has(S)?d.delete(S):d.add(S),y(),f()}))};b.addEventListener("input",()=>{R=b.value.trim().toLocaleLowerCase(),y(),f()}),L.addEventListener("click",()=>{let p=[...H()];!d.size||p.length>A||(this.closeDialog(),this.host.selectByLabels(p))}),y(),f()});return}let o=[...r.entries()].map(([a,l])=>`
|
|
477
525
|
<div class="slm-ch-seatgroup"><span>${c(a)}</span></div>
|
|
478
|
-
${l.map(
|
|
479
|
-
aria-checked="false" data-ch-scope-id="${c(
|
|
526
|
+
${l.map(h=>`<button type="button" class="slm-ch-seatitem" role="checkbox"
|
|
527
|
+
aria-checked="false" data-ch-scope-id="${c(h.id)}">
|
|
480
528
|
<span class="box" aria-hidden="true">\u2713</span>
|
|
481
|
-
<span>${c(
|
|
482
|
-
<span class="meta">${
|
|
529
|
+
<span>${c(h.label)}</span>
|
|
530
|
+
<span class="meta">${h.labels.length.toLocaleString()} seat${h.labels.length===1?"":"s"}</span>
|
|
483
531
|
</button>`).join("")}`).join("");this.renderScrim(`
|
|
484
532
|
<h3 id="slm-ch-dlg-title">Add whole sections</h3>
|
|
485
533
|
<p class="sub">Choose one or more. They are added to the seats already selected on the map.</p>
|
|
@@ -489,7 +537,7 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
489
537
|
<div class="foot">
|
|
490
538
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
491
539
|
<button type="button" class="slm-btn" data-ch-add-scope disabled>Add seats</button>
|
|
492
|
-
</div>`,a=>{let l=new Map(s.map(
|
|
540
|
+
</div>`,a=>{let l=new Map(s.map(m=>[m.id,m])),h=new Set,d=new Set(this.host.selectionLabels()),u=a.querySelector("[data-ch-add-scope]"),k=a.querySelector("[data-ch-error]"),L=()=>{let m=new Set(d);for(let b of h)for(let w of l.get(b)?.labels??[])m.add(w);return m},v=()=>{let m=L(),b=m.size-d.size,w=m.size>A;u.disabled=b===0||w,u.textContent=w?`Maximum ${A.toLocaleString()} seats`:`Add ${b.toLocaleString()} seat${b===1?"":"s"}`,k.hidden=!w,k.textContent=w?`That would make ${m.size.toLocaleString()} selected seats. Choose fewer rows or sections.`:""};a.querySelectorAll("[data-ch-scope-id]").forEach(m=>{m.addEventListener("click",()=>{let b=m.dataset.chScopeId;h.has(b)?h.delete(b):h.add(b),m.setAttribute("aria-checked",String(h.has(b))),v()})}),u.addEventListener("click",()=>{let m=[...L()];!h.size||m.length>A||(this.closeDialog(),this.host.selectByLabels(m))}),v()})}openDialog(e){this.dialog=e,this.renderDialog()}renderDialog(){let e=this.dialog;e&&(e.kind==="create"?this.renderCreateDialog(e):e.kind==="review"?this.renderReviewDialog(e):e.kind==="scope"?this.renderScopeDialog(e):e.kind==="archive"?this.renderArchiveDialog(e):e.kind==="rename"?this.renderRenameDialog(e):e.kind==="pricing"?this.renderPricingDialog(e):e.kind==="seatlist"?this.renderSeatListDialog():e.kind==="menu"?this.renderMenuDialog(e):e.kind==="linkCreate"?this.renderLinkCreateDialog(e):e.kind==="linkRotate"?this.renderLinkRotateDialog(e):e.kind==="linkRevoke"?this.renderLinkRevokeDialog(e):e.kind==="intentSwitch"&&this.renderIntentSwitchDialog(e))}renderIntentSwitchDialog(e){let t=this.list?.channels.find(o=>o.id===e.channelId),n=e.intentTo;if(!t||!n||!this.caps.manage){this.closeDialog();return}let{headline:s,consequences:r}=ye(e.switchBlocked);this.renderScrim(`
|
|
493
541
|
<h3 id="slm-ch-dlg-title">Change how ${c(t.name)} reaches buyers?</h3>
|
|
494
542
|
<p class="sub">${c(s)}</p>
|
|
495
543
|
<div class="slm-ch-alert warn" role="alert"><span>\u26A0</span><span>
|
|
@@ -501,9 +549,9 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
501
549
|
<div class="foot">
|
|
502
550
|
<button type="button" class="quiet" data-ch-close>Leave it as it is</button>
|
|
503
551
|
<button type="button" class="slm-btn" data-ch-intent-ack${e.busy?" disabled":""}>
|
|
504
|
-
${e.busy?"Changing\u2026":`Change to "${c(
|
|
552
|
+
${e.busy?"Changing\u2026":`Change to "${c(q(n))}"`}</button>
|
|
505
553
|
</div>`,o=>{o.querySelector("[data-ch-intent-ack]")?.addEventListener("click",()=>{this.acknowledgeIntentSwitch(n,e.pendingLink??null)})})}async acknowledgeIntentSwitch(e,t){let n=this.detailChannelId;if(!n){this.closeDialog();return}if(this.dialog&&(this.dialog.busy=!0,this.renderDialog()),!await this.setAccessIntent(e,{acknowledgeLiveAccess:!0})){this.dialog?.kind==="intentSwitch"&&(this.dialog.busy=!1,this.renderDialog());return}if(!t){this.closeDialog();return}this.dialog?.kind==="intentSwitch"&&(this.dialog.busy=!1,this.renderDialog()),await this.mintLink(n,t)}renderScrim(e,t){let n=this.scrimEl;n||(this.lastFocus=document.activeElement??null),n?.remove();let s=document.createElement("div");s.className="slm-ch-scrim",s.innerHTML=`<div class="slm-ch-dialog" role="dialog" aria-modal="true"
|
|
506
|
-
aria-labelledby="slm-ch-dlg-title" tabindex="-1">${e}</div>`,this.host.root.appendChild(s),this.scrimEl=s;let r=s.firstElementChild;r.querySelectorAll("[data-ch-close]").forEach(a=>{a.addEventListener("click",()=>this.closeDialog())}),s.addEventListener("keydown",a=>{if(a.key==="Escape"){a.stopPropagation(),this.closeDialog();return}if(a.key!=="Tab")return;let l=[...r.querySelectorAll('summary,button:not([disabled]),select:not([hidden]),input,textarea,a[href],[tabindex]:not([tabindex="-1"])')];if(!l.length)return;let
|
|
554
|
+
aria-labelledby="slm-ch-dlg-title" tabindex="-1">${e}</div>`,this.host.root.appendChild(s),this.scrimEl=s;let r=s.firstElementChild;r.querySelectorAll("[data-ch-close]").forEach(a=>{a.addEventListener("click",()=>this.closeDialog())}),s.addEventListener("keydown",a=>{if(a.key==="Escape"){a.stopPropagation(),this.closeDialog();return}if(a.key!=="Tab")return;let l=[...r.querySelectorAll('summary,button:not([disabled]),select:not([hidden]),input,textarea,a[href],[tabindex]:not([tabindex="-1"])')];if(!l.length)return;let h=l[0],d=l[l.length-1];a.shiftKey&&document.activeElement===h?(a.preventDefault(),d.focus()):!a.shiftKey&&document.activeElement===d&&(a.preventDefault(),h.focus())}),t(r),le(r),(r.querySelector("input,summary,button")??r).focus()}closeDialog(e={}){this.dialog=null,this.scrimEl?.remove(),this.scrimEl=null,e.restoreFocus!==!1&&this.lastFocus?.focus?.(),this.lastFocus=null}renderCreateDialog(e){let t=(this.list?.channels??[]).map(s=>B(s.marker||s.name,"")),n=ee("",t);this.renderScrim(`
|
|
507
555
|
<h3 id="slm-ch-dlg-title">Create channel</h3>
|
|
508
556
|
<p class="sub">A named allocation only the right audience can buy from. You'll pick the seats next.</p>
|
|
509
557
|
<div class="slm-field">
|
|
@@ -528,22 +576,22 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
528
576
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
529
577
|
<button type="button" class="slm-btn ghost" data-ch-create="plain">Create without allocating</button>
|
|
530
578
|
<button type="button" class="slm-btn" data-ch-create="allocate">Create and allocate seats</button>
|
|
531
|
-
</div>`,s=>{let r=s.querySelector("#slm-ch-name"),o=s.querySelector("[data-ch-marker]");r.addEventListener("input",()=>{let a=ee(r.value,t);o.textContent=a.letter,o.style.background=a.color}),s.querySelectorAll("[data-ch-create]").forEach(a=>{a.addEventListener("click",()=>{let l=a.dataset.chCreate==="allocate";this.createChannel(r.value,o.textContent??"",o.style.background,s.querySelector("#slm-ch-ref")?.value??"",l)})})})}async createChannel(e,t,n,s,r){let o=e.trim();if(!o){this.showDialogError("Give the channel a name your team will recognise.");return}try{let a=await this.host.api.createChannel(this.host.eventKey,{name:o,marker:
|
|
579
|
+
</div>`,s=>{let r=s.querySelector("#slm-ch-name"),o=s.querySelector("[data-ch-marker]");r.addEventListener("input",()=>{let a=ee(r.value,t);o.textContent=a.letter,o.style.background=a.color}),s.querySelectorAll("[data-ch-create]").forEach(a=>{a.addEventListener("click",()=>{let l=a.dataset.chCreate==="allocate";this.createChannel(r.value,o.textContent??"",o.style.background,s.querySelector("#slm-ch-ref")?.value??"",l)})})})}async createChannel(e,t,n,s,r){let o=e.trim();if(!o){this.showDialogError("Give the channel a name your team will recognise.");return}try{let a=await this.host.api.createChannel(this.host.eventKey,{name:o,marker:B(t,"")||null,color:n||null,externalRef:s.trim()||null});this.closeDialog(),await this.refresh(),this.targetChannelId=a.channel.id,this.detailChannelId=r?null:a.channel.id,this.announce(`Channel ${o} created with 0 seats allocated.`),this.host.toast(r?`${o} created. Select seats on the map to allocate them.`:`${o} created.`,"ok"),this.paintRail()}catch(a){let l=a instanceof g?a.code:void 0;this.showDialogError(l==="channel_name_taken"?"That name is already used on this event. Pick another.":"Couldn't create the channel. Try again."),this.host.onError(a)}}showDialogError(e){let t=this.scrimEl?.querySelector("[data-ch-error]");t&&(t.textContent=e,t.hidden=!1)}renderReviewDialog(e){let{labels:t,buckets:n}=this.currentPlan(),s=e.applied,r=s?s.buckets:n,o=this.nameOf(s?.targetChannelId??this.targetChannelId)??P,a=ge(r,o),l=s?s.applied:K(n),h=!s&&t.length>0&&l===0,d=!s&&t.length>A,u=ae(a),k=s?'<div class="foot"><button type="button" class="slm-btn" data-ch-close>Done</button></div>':`<div class="foot">
|
|
532
580
|
<button type="button" class="quiet" data-ch-close>Back</button>
|
|
533
|
-
<button type="button" class="slm-btn" data-ch-apply ${d||
|
|
581
|
+
<button type="button" class="slm-btn" data-ch-apply ${h||d||e.busy?"disabled":""}>
|
|
534
582
|
${e.busy?"Applying\u2026":`Apply ${l.toLocaleString()} change${l===1?"":"s"}`}
|
|
535
583
|
</button>
|
|
536
|
-
</div>`,
|
|
537
|
-
every seat is in a buyer's checkout, already sold, or already in ${c(o)}.</span></div>`:"",
|
|
538
|
-
One Apply can cover at most ${
|
|
584
|
+
</div>`,L=!s&&me(n)?'<p class="slm-note">Applying moves inventory out of another private channel. That is the line marked above.</p>':"",v=h?`<div class="slm-ch-alert warn"><span>\u2139</span><span>Nothing in this selection can move right now \u2014
|
|
585
|
+
every seat is in a buyer's checkout, already sold, or already in ${c(o)}.</span></div>`:"",m=d?`<div class="slm-ch-alert warn" role="alert"><span>\u2139</span><span><b>Choose fewer seats.</b>
|
|
586
|
+
One Apply can cover at most ${A.toLocaleString()} seats.</span></div>`:"";this.renderScrim(`
|
|
539
587
|
<h3 id="slm-ch-dlg-title">${s?`Moved ${s.applied.toLocaleString()} seat${s.applied===1?"":"s"} to ${c(o)}`:`Move ${t.length.toLocaleString()} selected seat${t.length===1?"":"s"} to ${c(o)}`}</h3>
|
|
540
588
|
<p class="sub">${s?"These are the exact counts the server applied.":"Every selected seat is in exactly one line below."}</p>
|
|
541
589
|
${v}
|
|
542
|
-
${
|
|
590
|
+
${m}
|
|
543
591
|
${u||'<div class="slm-empty">Nothing selected.</div>'}
|
|
544
|
-
${
|
|
592
|
+
${L}
|
|
545
593
|
<p class="slm-ch-err" data-ch-error ${e.error?"":"hidden"}>${c(e.error??"")}</p>
|
|
546
|
-
${
|
|
594
|
+
${k}`,b=>{b.querySelector("[data-ch-apply]")?.addEventListener("click",()=>{this.apply()})}),s&&this.announce(`Applied ${s.applied} change${s.applied===1?"":"s"} to ${o}.`)}async apply(){if(!this.dialog||!this.caps.manage)return;let{labels:e}=this.currentPlan();if(e.length){if(e.length>A){this.showDialogError(`Choose at most ${A.toLocaleString()} seats for one Apply.`);return}this.dialog={...this.dialog,busy:!0,error:null},this.renderDialog();try{let t=await this.host.api.applyChannelAssignment(this.host.eventKey,{targetChannelId:D(this.targetChannelId)?null:this.targetChannelId,labels:e,assignmentVersion:this.assignmentVersion});this.assignmentVersion=t.assignmentVersion,this.conflict=!1,await this.refresh({quiet:!0}),this.closeDialog({restoreFocus:!1}),this.host.clearSelection(),this.showApplied(t)}catch(t){if(t instanceof g&&t.status===409&&t.code==="channel_assignment_conflict"){this.conflict=!0,this.closeDialog(),this.shakeStaged(),this.paintRail(),this.announce("Assignments changed while you were editing. Nothing was applied and your selection is kept.");return}if(t instanceof g&&t.status===403){this.caps={view:this.caps.view,manage:!1},this.closeDialog(),this.paintRail(),this.host.toast("Changing channels needs channel-management permission.","err");return}this.dialog={kind:"review",busy:!1,error:"Couldn't apply those changes. Try again."},this.renderDialog(),this.host.onError(t)}}}showApplied(e){let t=this.nameOf(e.targetChannelId)??P,n=e.buckets.skippedHeld.count+e.buckets.skippedBooked.count+e.buckets.notFound.count;this.setStaged(`<span class="slm-ch-tick" aria-hidden="true">\u2713</span>
|
|
547
595
|
<span>Assigned <b>${e.applied.toLocaleString()}</b> seat${e.applied===1?"":"s"} to ${c(t)}
|
|
548
596
|
${n?` \xB7 ${n.toLocaleString()} skipped`:""}</span>
|
|
549
597
|
<span class="grow"></span>
|
|
@@ -571,12 +619,12 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
571
619
|
<div class="foot">
|
|
572
620
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
573
621
|
<button type="button" class="slm-btn" data-ch-rename>Save name</button>
|
|
574
|
-
</div>`,n=>{n.querySelector("[data-ch-rename]")?.addEventListener("click",()=>{let s=n.querySelector("#slm-ch-newname")?.value??"";if(!s.trim()){this.showDialogError("A channel needs a name.");return}this.host.api.renameChannel(this.host.eventKey,t.id,s.trim()).then(()=>(this.closeDialog(),this.refresh())).catch(r=>{this.showDialogError(r instanceof
|
|
575
|
-
<span><b>${c(
|
|
622
|
+
</div>`,n=>{n.querySelector("[data-ch-rename]")?.addEventListener("click",()=>{let s=n.querySelector("#slm-ch-newname")?.value??"";if(!s.trim()){this.showDialogError("A channel needs a name.");return}this.host.api.renameChannel(this.host.eventKey,t.id,s.trim()).then(()=>(this.closeDialog(),this.refresh())).catch(r=>{this.showDialogError(r instanceof g&&r.code==="channel_name_taken"?"That name is already used on this event.":"Couldn't rename the channel."),this.host.onError(r)})})})}renderPricingDialog(e){let t=this.list?.channels.find(o=>o.id===e.channelId),n=this.host.api.updateChannelPricing;if(!t||!n||!this.caps.manage){this.closeDialog();return}let s=new Map((t.priceOverrides??[]).map(o=>[`${o.categoryKey}\0${o.tierId??""}`,o.price])),r=this.host.categories().flatMap(o=>(o.tiers?.length?o.tiers:[null]).map(l=>{let h=l?.id??null,d=`${o.key}\0${h??""}`,u=l?.price??o.price??0,k=s.get(d),L=l?`${o.label} \xB7 ${l.name}`:o.label;return`<label class="slm-ch-price-row">
|
|
623
|
+
<span><b>${c(L)}</b><small>Event price ${c(String(u))}</small></span>
|
|
576
624
|
<input class="slm-input" type="number" min="0" max="1000000" step="0.01"
|
|
577
|
-
inputmode="decimal" aria-label="Custom price for ${c(
|
|
578
|
-
data-ch-price-category="${c(o.key)}" data-ch-price-tier="${c(
|
|
579
|
-
placeholder="${c(String(u))}" value="${
|
|
625
|
+
inputmode="decimal" aria-label="Custom price for ${c(L)}"
|
|
626
|
+
data-ch-price-category="${c(o.key)}" data-ch-price-tier="${c(h??"")}"
|
|
627
|
+
placeholder="${c(String(u))}" value="${k===void 0?"":c(String(k))}"
|
|
580
628
|
${e.busy?"disabled":""} />
|
|
581
629
|
</label>`})).join("");this.renderScrim(`
|
|
582
630
|
<h3 id="slm-ch-dlg-title">Prices for ${c(t.name)}</h3>
|
|
@@ -588,9 +636,9 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
588
636
|
<button type="button" class="slm-btn" data-ch-price-save ${e.busy||!r?"disabled":""}>
|
|
589
637
|
${e.busy?"Saving\u2026":"Save prices"}
|
|
590
638
|
</button>
|
|
591
|
-
</div>`,o=>{o.querySelector("[data-ch-price-save]")?.addEventListener("click",()=>{let a=[];for(let l of o.querySelectorAll("[data-ch-price-category]")){let
|
|
639
|
+
</div>`,o=>{o.querySelector("[data-ch-price-save]")?.addEventListener("click",()=>{let a=[];for(let l of o.querySelectorAll("[data-ch-price-category]")){let h=l.value.trim();if(!h)continue;let d=Number(h);if(!Number.isFinite(d)||d<0||d>1e6){l.focus(),this.showDialogError("Enter a price from 0 to 1,000,000, or leave the field blank.");return}a.push({categoryKey:l.dataset.chPriceCategory,tierId:l.dataset.chPriceTier||null,price:d})}this.saveChannelPricing(t,a)})})}async saveChannelPricing(e,t){let n=this.host.api.updateChannelPricing;if(!(!n||!this.dialog||this.dialog.kind!=="pricing")){this.dialog={...this.dialog,busy:!0,error:null},this.renderDialog();try{await n.call(this.host.api,this.host.eventKey,e.id,t,e.pricingVersion??0),this.closeDialog(),await this.refresh(),this.host.toast(t.length?`Custom prices saved for ${e.name}.`:`${e.name} now uses event prices.`,"ok")}catch(s){if(s instanceof g&&s.code==="channel_pricing_conflict"){await this.refresh({quiet:!0}),this.dialog={kind:"pricing",channelId:e.id,error:"Prices changed in another window. Latest values are shown \u2014 review and save again."},this.renderDialog();return}this.dialog={kind:"pricing",channelId:e.id,error:s instanceof g&&s.serverMessage?s.serverMessage:"Couldn't save these prices. Try again."},this.renderDialog(),this.host.onError(s)}}}async chooseWebsiteIntegration(){this.detailChannelId&&await this.setAccessIntent("server")}async setAccessIntent(e,t={}){let n=this.detailChannelId;if(!n||!this.caps.manage)return!1;try{let s=await this.host.api.setChannelAccessIntent(this.host.eventKey,n,e,t);return await this.refresh(),this.host.toast(this.intentSavedCopy(e,s?.intentSwitch),"ok"),!0}catch(s){return s instanceof g&&s.code==="channel_intent_switch_blocked"?(this.openDialog({kind:"intentSwitch",channelId:n,intentTo:e,switchBlocked:s.details}),!1):s instanceof g&&s.code==="channel_access_intent_forbids"?(this.host.toast(X(s.details),"err"),!1):(this.host.toast("Couldn't change how this channel reaches buyers.","err"),this.host.onError(s),!1)}}intentSavedCopy(e,t){let n=e==="server"?"Set to your website or app. The embed code is on the Embed page.":e==="internal"?"Only your own staff can sell this channel now.":e==="hosted_link"?"Set to buyer links. Create one to let buyers in.":"Kept as a protected reserve. No route can sell these seats.";if(!t)return n;let s=t.closedLinks?` ${t.closedLinks.toLocaleString()} buyer link${t.closedLinks===1?"":"s"} closed.`:"",r=t.keptSessions?` ${t.keptSessions.toLocaleString()} buyer${t.keptSessions===1?"":"s"} already in a checkout can still finish.`:"";return`${n}${s}${r}`}async togglePause(e=this.detailChannelId){let t=this.list?.channels.find(s=>s.id===e);if(!t||!this.caps.manage)return;let n=t.state!=="paused";try{await this.host.api.setChannelPaused(this.host.eventKey,t.id,n),await this.refresh(),this.host.toast(n?`${t.name} paused. Existing checkouts can finish; no new buyer access is issued.`:`${t.name} resumed.`,"ok")}catch(s){this.host.toast("Couldn't change that channel.","err"),this.host.onError(s)}}renderArchiveDialog(e){let t=this.list?.channels.find(a=>a.id===e.channelId);if(!t){this.closeDialog();return}let n=e.archiveBlocked??null,s=!n&&t.counts.held>0,r=this.assignableChannels().filter(a=>a.id!==t.id),o=n?`<div class="slm-ch-alert warn" role="alert"><span>\u23F3</span>
|
|
592
640
|
<span><b>${(n.heldUnits??n.activeHolds??0).toLocaleString()} seats are in a buyer's checkout right now.</b>
|
|
593
|
-
Archive is unavailable while seats are held \u2014 try again ${c(
|
|
641
|
+
Archive is unavailable while seats are held \u2014 try again ${c(be(n))}.</span></div>`:s?`<div class="slm-ch-alert warn"><span>\u23F3</span>
|
|
594
642
|
<span>${t.counts.held.toLocaleString()} seats are in a buyer's checkout right now.
|
|
595
643
|
Archive is refused while any seat is held \u2014 you can try, and we'll tell you when to come back.</span></div>`:"";this.renderScrim(`
|
|
596
644
|
<h3 id="slm-ch-dlg-title">Archive ${c(t.name)}</h3>
|
|
@@ -610,22 +658,22 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
610
658
|
<div class="foot">
|
|
611
659
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
612
660
|
<button type="button" class="slm-btn danger" data-ch-archive ${n?"disabled":""}>Archive channel</button>
|
|
613
|
-
</div>`,a=>{a.querySelector("[data-ch-archive]")?.addEventListener("click",()=>{let l=a.querySelector("#slm-ch-dest")?.value??"";this.archive(t.id,l||null)})})}async archive(e,t){try{await this.host.api.archiveChannel(this.host.eventKey,e,t),this.closeDialog(),this.detailChannelId=null,await this.refresh(),this.host.toast("Channel archived. Its remaining seats moved to the destination you chose.","ok")}catch(n){if(n instanceof
|
|
661
|
+
</div>`,a=>{a.querySelector("[data-ch-archive]")?.addEventListener("click",()=>{let l=a.querySelector("#slm-ch-dest")?.value??"";this.archive(t.id,l||null)})})}async archive(e,t){try{await this.host.api.archiveChannel(this.host.eventKey,e,t),this.closeDialog(),this.detailChannelId=null,await this.refresh(),this.host.toast("Channel archived. Its remaining seats moved to the destination you chose.","ok")}catch(n){if(n instanceof g&&n.status===409&&n.code==="channel_archive_blocked_by_holds"){this.dialog={kind:"archive",channelId:e,archiveBlocked:n.details??{}},this.renderDialog();return}this.showDialogError("Couldn't archive that channel. Try again."),this.host.onError(n)}}renderSeatListDialog(){let e=new Set(this.host.selectionLabels()),t=new Map,n=0;for(let r of this.host.seats()){if(n+=1,n>this.seatListLimit)break;let o=this.host.sectionOfLabel(r.label),a=o?.id??"",l=t.get(a)??{label:o?.label??"Other seats",seats:[]};l.seats.push({label:r.label,status:this.host.statusOf(r.label)??"free"}),t.set(a,l)}let s=[...t.entries()].map(([r,o])=>`
|
|
614
662
|
<div class="slm-ch-seatgroup">
|
|
615
663
|
<span>${c(o.label)}</span>
|
|
616
664
|
${r?`<button type="button" data-ch-section="${c(r)}">Select section</button>`:""}
|
|
617
665
|
</div>
|
|
618
|
-
${o.seats.map(a=>{let l=this.allocation.get(a.label)??$,
|
|
666
|
+
${o.seats.map(a=>{let l=this.allocation.get(a.label)??$,h=this.nameOf(l)??P;return`<button type="button" class="slm-ch-seatitem" role="checkbox"
|
|
619
667
|
aria-checked="${e.has(a.label)}" data-ch-seat="${c(a.label)}">
|
|
620
668
|
<span class="box" aria-hidden="true">\u2713</span>
|
|
621
669
|
<span>${c(a.label)}</span>
|
|
622
|
-
<span class="meta">${c(
|
|
670
|
+
<span class="meta">${c(h)} \xB7 ${c(a.status)}</span>
|
|
623
671
|
</button>`}).join("")}`).join("");this.renderScrim(`
|
|
624
672
|
<h3 id="slm-ch-dlg-title">Seat list</h3>
|
|
625
673
|
<p class="sub">The same selection as the map, with checkboxes. Space or Enter toggles a seat.</p>
|
|
626
674
|
<div class="slm-ch-seatlist">${s||'<div class="slm-empty">No seats on this chart.</div>'}</div>
|
|
627
675
|
${n>this.seatListLimit?'<div class="foot"><button type="button" class="slm-btn ghost" data-ch-more>Show more seats</button></div>':""}
|
|
628
|
-
<div class="foot"><button type="button" class="slm-btn" data-ch-close>Done</button></div>`,r=>{r.querySelectorAll("[data-ch-seat]").forEach(o=>{o.addEventListener("click",()=>{let a=o.dataset.chSeat,l=new Set(this.host.selectionLabels());l.has(a)?l.delete(a):l.add(a),this.host.clearSelection(),l.size&&this.host.selectByLabels([...l]),this.renderSeatListDialog()})}),r.querySelectorAll("[data-ch-section]").forEach(o=>{o.addEventListener("click",()=>{this.host.selectSection(o.dataset.chSection),this.renderSeatListDialog()})}),r.querySelector("[data-ch-more]")?.addEventListener("click",()=>{this.seatListLimit+=
|
|
676
|
+
<div class="foot"><button type="button" class="slm-btn" data-ch-close>Done</button></div>`,r=>{r.querySelectorAll("[data-ch-seat]").forEach(o=>{o.addEventListener("click",()=>{let a=o.dataset.chSeat,l=new Set(this.host.selectionLabels());l.has(a)?l.delete(a):l.add(a),this.host.clearSelection(),l.size&&this.host.selectByLabels([...l]),this.renderSeatListDialog()})}),r.querySelectorAll("[data-ch-section]").forEach(o=>{o.addEventListener("click",()=>{this.host.selectSection(o.dataset.chSection),this.renderSeatListDialog()})}),r.querySelector("[data-ch-more]")?.addEventListener("click",()=>{this.seatListLimit+=De,this.renderSeatListDialog()})})}async reloadLinks(){let e=this.detailChannelId;e&&(this.linksState=this.links.length?this.linksState:"loading",await this.loadLinks(e),this.paintRail())}async reloadAfterLinkChange(e){if(this.detailChannelId===e){await this.refresh({quiet:!0});return}await this.loadLinks(e),this.active&&this.paintRail()}linkById(e){return this.links.find(t=>t.id===e)??null}renderLinkCreateDialog(e){let t=this.list?.channels.find(n=>n.id===e.channelId);if(!t||!this.caps.manage){this.closeDialog();return}this.renderScrim(`
|
|
629
677
|
<h3 id="slm-ch-dlg-title">Create a buyer link for ${c(t.name)}</h3>
|
|
630
678
|
<p class="sub">Anyone who opens the link can buy from this channel's allocation \u2014 and only from it.
|
|
631
679
|
You'll see the link once, right after you create it.</p>
|
|
@@ -664,17 +712,18 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
664
712
|
<div class="foot">
|
|
665
713
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
666
714
|
<button type="button" class="slm-btn" data-ch-lk-create>Create link</button>
|
|
667
|
-
</div>`,n=>{let s=n.querySelector("[data-ch-lk-expiry]"),r=n.querySelector("[data-ch-lk-when-field]"),o=n.querySelector("#slm-ch-lk-when");s.addEventListener("change",()=>{let a=s.value==="custom";r.hidden=!a,a&&!o.value&&(o.value=Ae(Date.now()+7*864e5))}),n.querySelector("[data-ch-lk-create]")?.addEventListener("click",()=>{let a=oe(n,"#slm-ch-lk-redemptions"),l=oe(n,"#slm-ch-lk-quantity");if(a==null||l==null){this.showDialogError("Those two settings need to be whole numbers.");return}let
|
|
715
|
+
</div>`,n=>{let s=n.querySelector("[data-ch-lk-expiry]"),r=n.querySelector("[data-ch-lk-when-field]"),o=n.querySelector("#slm-ch-lk-when");s.addEventListener("change",()=>{let a=s.value==="custom";r.hidden=!a,a&&!o.value&&(o.value=Ae(Date.now()+7*864e5))}),n.querySelector("[data-ch-lk-create]")?.addEventListener("click",()=>{let a=oe(n,"#slm-ch-lk-redemptions"),l=oe(n,"#slm-ch-lk-quantity");if(a==null||l==null){this.showDialogError("Those two settings need to be whole numbers.");return}let h;if(s.value==="custom"&&(h=Date.parse(o.value),!Number.isFinite(h))){this.showDialogError("Pick the date and time the link should stop working.");return}this.createLink(t.id,{label:n.querySelector("#slm-ch-lk-label")?.value.trim()||null,includePublic:n.querySelector("#slm-ch-lk-public")?.checked??!1,...h===void 0?{}:{expiresAt:h},maxRedemptions:a,maxQuantity:l})})})}async createLink(e,t){await this.ensureHostedLinkRoute(e,t)&&await this.mintLink(e,t)}async mintLink(e,t){try{let n=await this.host.api.createAccessLink(this.host.eventKey,e,t);this.revealLink(n,{channelId:e}),await this.reloadAfterLinkChange(e)}catch(n){this.showDialogError(V(n instanceof g?n:void 0)),n instanceof g||this.host.onError(n)}}async ensureHostedLinkRoute(e,t){if((this.list?.channels.find(s=>s.id===e)?.access?.intent??"none")==="hosted_link")return!0;try{return await this.host.api.setChannelAccessIntent(this.host.eventKey,e,"hosted_link"),await this.refresh(),!0}catch(s){return s instanceof g&&s.code==="channel_intent_switch_blocked"?(this.openDialog({kind:"intentSwitch",channelId:e,intentTo:"hosted_link",switchBlocked:s.details,pendingLink:t}),!1):(this.showDialogError(s instanceof g&&s.code==="channel_access_intent_forbids"?X(s.details):"Couldn't set this channel up for buyer links. Try again."),s instanceof g||this.host.onError(s),!1)}}revealLink(e,t){let n=e.url;this.dialog=null;let s=t.rotated?`<div class="slm-ch-alert warn" role="status"><span>\u26A0</span><span>
|
|
668
716
|
<b>The old link has stopped working.</b> ${e.endedSessions?`${e.endedSessions.toLocaleString()} buyer${e.endedSessions===1?"":"s"} lost access immediately.`:"Buyers who already came in can finish; every new visit needs this link."}</span></div>`:"",r=se(e.link).map(o=>`<div class="slm-ch-lkrow"><span class="k">${c(o.k)}</span>
|
|
669
717
|
<span class="v">${c(o.v)}</span></div>`).join("");this.renderScrim(`
|
|
670
718
|
<h3 id="slm-ch-dlg-title">Copy this link now</h3>
|
|
671
719
|
<p class="sub">This is the only time SeatLayer can show it. We keep just a fingerprint, so it cannot be
|
|
672
720
|
shown again \u2014 if it is lost, rotate the link for a fresh one.</p>
|
|
673
721
|
${s}
|
|
674
|
-
<div class="slm-ch-
|
|
675
|
-
|
|
676
|
-
<button type="button" class="slm-btn" data-ch-lk-copy>Copy
|
|
722
|
+
<div class="slm-ch-copyrow">
|
|
723
|
+
<div class="slm-ch-secret" data-ch-lk-url title="${c(n)}">${c(n)}</div>
|
|
724
|
+
<button type="button" class="slm-btn" data-ch-lk-copy aria-live="polite">Copy</button>
|
|
677
725
|
</div>
|
|
726
|
+
<input class="slm-ch-copysink" data-ch-lk-sink tabindex="-1" aria-hidden="true" readonly />
|
|
678
727
|
<div class="slm-ch-alert warn" style="margin-top:12px"><span>\u26A0</span>
|
|
679
728
|
<span>Anyone who opens this link can buy from this allocation. Send it only to the people it is meant
|
|
680
729
|
for \u2014 forwarding it hands on the same access, and SeatLayer cannot tell the difference.</span></div>
|
|
@@ -682,7 +731,7 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
682
731
|
${r}
|
|
683
732
|
<div class="foot">
|
|
684
733
|
<button type="button" class="slm-btn" data-ch-close data-ch-lk-done>I've copied it</button>
|
|
685
|
-
</div>`,o=>{let a=o.querySelector("[data-ch-lk-copy]");a?.addEventListener("click",()=>{
|
|
734
|
+
</div>`,o=>{let a=o.querySelector("[data-ch-lk-copy]"),l=null;a?.addEventListener("click",()=>{Ie(o,n).then(h=>{if(!h){a.textContent="Copy",a.classList.remove("copied"),this.announce("Copying was blocked. The link is selected \u2014 copy it by hand.");return}a.textContent="Copied",a.classList.add("copied"),this.announce("Buyer link copied."),l&&clearTimeout(l),l=setTimeout(()=>{a.textContent="Copy",a.classList.remove("copied")},1500)})})}),this.announce("Your buyer link is ready and is shown once.")}renderLinkRotateDialog(e){let t=this.linkById(e.linkId);if(!t||!this.caps.manage){this.closeDialog();return}let n=t.activeSessions??0,s=n?`<div class="slm-ch-alert warn"><span>\u26A0</span>
|
|
686
735
|
<span><b>${n.toLocaleString()} buyer${n===1?"":"s"}</b> got in with the current link
|
|
687
736
|
and still ${n===1?"has":"have"} active access.</span></div>`:"";this.renderScrim(`
|
|
688
737
|
<h3 id="slm-ch-dlg-title">Rotate the ${c(t.label||"buyer")} link?</h3>
|
|
@@ -704,7 +753,7 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
704
753
|
<div class="foot">
|
|
705
754
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
706
755
|
<button type="button" class="slm-btn" data-ch-lk-rotate disabled>Rotate and copy new link</button>
|
|
707
|
-
</div>`,r=>{let o=r.querySelector("[data-ch-lk-rotate]");r.querySelectorAll("[data-ch-rot]").forEach(a=>{a.addEventListener("change",()=>{o.disabled=!1})}),o.addEventListener("click",()=>{let a=[...r.querySelectorAll("[data-ch-rot]")].find(l=>l.checked);if(!a){this.showDialogError(
|
|
756
|
+
</div>`,r=>{let o=r.querySelector("[data-ch-lk-rotate]");r.querySelectorAll("[data-ch-rot]").forEach(a=>{a.addEventListener("change",()=>{o.disabled=!1})}),o.addEventListener("click",()=>{let a=[...r.querySelectorAll("[data-ch-rot]")].find(l=>l.checked);if(!a){this.showDialogError(V({code:"end_active_sessions_required"}));return}this.rotateLink(e.channelId,t.id,a.value==="end")})})}async rotateLink(e,t,n){try{let s=await this.host.api.rotateAccessLink(this.host.eventKey,e,t,n);this.revealLink(s,{channelId:e,rotated:!0}),await this.reloadAfterLinkChange(e)}catch(s){this.showDialogError(V(s instanceof g?s:void 0)),s instanceof g||this.host.onError(s)}}renderLinkRevokeDialog(e){let t=this.linkById(e.linkId);if(!t||!this.caps.manage){this.closeDialog();return}let n=t.activeSessions??0;this.renderScrim(`
|
|
708
757
|
<h3 id="slm-ch-dlg-title">Revoke the ${c(t.label||"buyer")} link?</h3>
|
|
709
758
|
<p class="sub">It stops opening immediately and cannot be restored \u2014 there is no undo, and no way to
|
|
710
759
|
bring the same URL back. Seats already bought through it keep their sale.</p>
|
|
@@ -718,4 +767,4 @@ function ce(i){i.querySelectorAll("select:not([data-themed])").forEach(e=>{e.dat
|
|
|
718
767
|
<div class="foot">
|
|
719
768
|
<button type="button" class="quiet" data-ch-close>Cancel</button>
|
|
720
769
|
<button type="button" class="slm-btn danger" data-ch-lk-revoke>Revoke link</button>
|
|
721
|
-
</div>`,s=>{s.querySelector("[data-ch-lk-revoke]")?.addEventListener("click",()=>{let r=s.querySelector("[data-ch-lk-endsessions]")?.checked??!1;this.revokeLink(e.channelId,t.id,r)})})}async revokeLink(e,t,n){try{let s=await this.host.api.revokeAccessLink(this.host.eventKey,e,t,n);this.closeDialog(),await this.reloadAfterLinkChange(e),this.host.toast(s.endedSessions?`Link revoked. ${s.endedSessions.toLocaleString()} buyer${s.endedSessions===1?"":"s"} lost access.`:"Link revoked. It no longer opens for anyone.","ok")}catch(s){this.showDialogError(
|
|
770
|
+
</div>`,s=>{s.querySelector("[data-ch-lk-revoke]")?.addEventListener("click",()=>{let r=s.querySelector("[data-ch-lk-endsessions]")?.checked??!1;this.revokeLink(e.channelId,t.id,r)})})}async revokeLink(e,t,n){try{let s=await this.host.api.revokeAccessLink(this.host.eventKey,e,t,n);this.closeDialog(),await this.reloadAfterLinkChange(e),this.host.toast(s.endedSessions?`Link revoked. ${s.endedSessions.toLocaleString()} buyer${s.endedSessions===1?"":"s"} lost access.`:"Link revoked. It no longer opens for anyone.","ok")}catch(s){this.showDialogError(V(s instanceof g?s:void 0)),s instanceof g||this.host.onError(s)}}applySheetClasses(){let e=this.host.root,t=this.host.isCompact();e.classList.toggle("ch-sheet",t&&this.active);for(let n of["collapsed","medium","full"])e.classList.toggle(`detent-${n}`,t&&this.active&&this.detent===n);this.host.setMapInert(t&&this.active&&this.detent==="full")}cycleDetent(){let e=["collapsed","medium","full"];this.detent=e[(e.indexOf(this.detent)+1)%e.length],this.applySheetClasses()}handleBack(){return this.scrimEl?(this.closeDialog(),!0):this.host.isCompact()&&this.detent==="full"?(this.detent="medium",this.applySheetClasses(),!0):!1}};export{le as a,g as b,Ce as c,$ as d,P as e,D as f,B as g,ee as h,de as i,ue as j,pe as k,K as l,me as m,ge as n,be as o,ve as p,q,fe as r,X as s,ye as t,te as u,ke as v,ne as w,se as x,V as y,rt as z,we as A,ae as B,it as C,Me as D};
|