PageSourceSearch

https://www.downstairscomedy.shop/assets/waterline/controllers/sea…f4b7a96178691cee5d7a2e5a1f76f0b2f48b7b61.js

js downstairscomedy.shop collected 2026-10-06 14:03:21 UTC 14,512 bytes, 1 lines download raw bytes

1import{Controller}from"@hotwired/stimulus";import{get}from"@rails/request.js";import{CanvasRenderer}from"waterline/seating-plan/canvas_renderer";import{SeatingPlanMinimap}from"waterline/seating-plan/seating_plan_minimap";import{SeatingPlanTooltip}from"waterline/seating-plan/seating_plan_tooltip";import{SeatingPlanAPI}from"waterline/seating-plan/seating_plan_api";import{SeatingPlanStatus}from"waterline/seating-plan/seating_plan_status";import{SeatPopover}from"waterline/seating-plan/seat_popover";import{SeatHoverChip}from"waterline/seating-plan/seat_hover_chip";import{HandicapBridge}from"waterline/seating-plan/handicap_bridge";import{StatusPoller}from"waterline/seating-plan/status_poller";import{CanvasKeyboardNavigator}from"waterline/seating-plan/canvas_keyboard_navigator";import{readThemeColors}from"waterline/seating-plan/theme_colors";import{SrAnnouncer}from"waterline/seating-plan/sr_announcer";import{SeatToggleFlow}from"waterline/seating-plan/seat_toggle_flow";import{CatalogStore}from"waterline/seating-plan/catalog_store";import{PointerCoordinator}from"waterline/seating-plan/pointer_coordinator";import{readLegendIcon}from"waterline/seating-plan/legend_icon";import{buildSegmentIndex,findIsolatedSeats}from"waterline/seating-plan/seat_gap_analyzer";const POLL_INTERVAL_MS=18e4,CATALOG_DEBOUNCE_MS=300,REQUIRED_TARGETS=["canvas","loadingOverlay","sidebar","minimapCanvas","tooltip","tooltipSeatName","tooltipVersionList","tooltipVersionRowTemplate","hoverChip","hoverChipSeatName","hoverChipPrice","errorTemplate","canvasKeyboardStatus"];export default class extends Controller{static targets=["canvas","loadingOverlay","sidebar","sidebarToggle","minimapCanvas","tooltip","tooltipArrow","tooltipBlockName","tooltipSeatName","tooltipVersionList","tooltipVersionRowTemplate","tooltipClose","hoverChip","hoverChipBlockName","hoverChipSeatName","hoverChipPrice","hoverChipHint","errorTemplate","canvasKeyboardStatus","keyboardShortcutsDetails","legendHandicap","legendPoorVisibility","legendVoucherSwap"];static values={structurePath:String,catalogPath:String,statusPublicPath:String,statusMinePath:String,togglePath:String,handicapConfirmModalPath:String,standingBlockModalPath:String,seatAriaLabelTemplate:String,tooltipSeatLabelTemplate:String,loadFailedMessage:String,seatAvailableLabel:String,seatSelectedLabel:String,seatAddedLabel:String,seatRemovedLabel:String,seatLimitedViewLabel:String,seatAccessibleLabel:String,seatResaleLabel:String,noAccessibleSeatsLabel:String,voucherSwapModalPath:String,priceFromLabel:String,chipChooseHintLabel:String,chipAddHintLabel:String,chipRemoveHintLabel:String};async connect(){this._requireTargets(),this.abort=new AbortController;const e=this.abort.signal;let t,a;this.colors=readThemeColors(this.element),this.isHoverDevice=window.matchMedia("(any-hover: hover)").matches,this.api=new SeatingPlanAPI({structurePath:this.structurePathValue,catalogPath:this.catalogPathValue,statusPublicPath:this.statusPublicPathValue,statusMinePath:this.statusMinePathValue,togglePath:this.togglePathValue}),this.catalogStore=new CatalogStore({api:this.api});try{[t,,a]=await Promise.all([this.api.getStructure(),this.catalogStore.load(),this.api.getStatus()])}catch(e){return console.error("Failed to load seating plan:",e),void this._showError()}this.structure=t,this.planStatus=new SeatingPlanStatus({seatById:new Map,catalogStore:this.catalogStore,colors:this.colors}),this.planStatus.applyStatus(a),this.renderer=new CanvasRenderer({canvas:this.canvasTarget,host:this.element,structure:t,planStatus:this.planStatus,colors:this.colors,accessibilityIcons:{handicap:this.hasLegendHandicapTarget?readLegendIcon(this.legendHandicapTarget):null,poorvis:this.hasLegendPoorVisibilityTarget?readLegendIcon(this.legendPoorVisibilityTarget):null,resale:this.hasLegendVoucherSwapTarget?readLegendIcon(this.legendVoucherSwapTarget):null},seatLabelTemplate:this.hasTooltipSeatLabelTemplateValue?this.tooltipSeatLabelTemplateValue:void 0}),await this.renderer.init({signal:e}),this.planStatus.seatById=this.renderer.enriched,this.tooltip=new SeatingPlanTooltip({root:this.tooltipTarget,host:this.element,blockName:this.tooltipBlockNameTarget,seatName:this.tooltipSeatNameTarget,versionList:this.tooltipVersionListTarget,versionRowTemplate:this.tooltipVersionRowTemplateTarget,formatPrice:e=>this._formatPrice(e),seatLabelTemplate:this.hasTooltipSeatLabelTemplateValue?this.tooltipSeatLabelTemplateValue:"Row %{row}, seat %{no}",arrow:this.hasTooltipArrowTarget?this.tooltipArrowTarget:null}),this.popover=new SeatPopover({tooltip:this.tooltip,root:this.tooltipTarget,canvasTarget:this.canvasTarget,onClose:()=>this.pointerCoordinator?.onPopoverClosed(),signal:e}),this.hoverChip=new SeatHoverChip({root:this.hoverChipTarget,host:this.element,blockName:this.hasHoverChipBlockNameTarget?this.hoverChipBlockNameTarget:null,seatName:this.hoverChipSeatNameTarget,price:this.hoverChipPriceTarget,hint:this.hasHoverChipHintTarget?this.hoverChipHintTarget:null,formatPrice:e=>this._formatPrice(e),seatLabelTemplate:this.hasTooltipSeatLabelTemplateValue?this.tooltipSeatLabelTemplateValue:"Row %{row}, seat %{no}",labels:{from:this.priceFromLabelValue,choose:this.chipChooseHintLabelValue,add:this.chipAddHintLabelValue,remove:this.chipRemoveHintLabelValue}}),await this._buildMinimap(e),this.segmentIndex=buildSegmentIndex(t,t.seatwidth),this._isolatedSet=new Set,this._refreshIsolatedSeats(),this.handicap=new Handicap
1Bridge({modalPath:this.handicapConfirmModalPathValue,signal:e}),this.seatToggleFlow=new SeatToggleFlow({planStatus:this.planStatus,renderer:this.renderer,handicapBridge:this.handicap,voucherSwapModalPath:this.voucherSwapModalPathValue,api:this.api,onRejected:()=>this._pollStatus(),onError:e=>{console.error("Toggle failed:",e),this._pollStatus()}}),this.srAnnouncer=new SrAnnouncer({target:this.hasCanvasKeyboardStatusTarget?this.canvasKeyboardStatusTarget:null,signal:e}),this.canvasKeyboard=new CanvasKeyboardNavigator({renderer:this.renderer,planStatus:this.planStatus,catalogStore:this.catalogStore,labels:{seatAria:this.seatAriaLabelTemplateValue,availableState:this.seatAvailableLabelValue||"Available",selectedState:this.seatSelectedLabelValue||"Selected",accessibleState:this.seatAccessibleLabelValue||"Accessible seat",limitedViewState:this.seatLimitedViewLabelValue||"Limited view",resaleState:this.seatResaleLabelValue||"Resale offer",noAccessibleSeats:this.noAccessibleSeatsLabelValue||"No accessible seats available"},onActivateSeat:e=>this.pointerCoordinator.activateFromKeyboard(e),announce:e=>this.srAnnouncer.announce(e),signal:e}),this.pointerCoordinator=new PointerCoordinator({renderer:this.renderer,canvasTarget:this.canvasTarget,hoverChip:this.hoverChip,popover:this.popover,sidebarTarget:this.hasSidebarTarget?this.sidebarTarget:null,sidebarToggleTarget:this.hasSidebarToggleTarget?this.sidebarToggleTarget:null,planStatus:this.planStatus,catalogStore:this.catalogStore,canvasKeyboard:this.canvasKeyboard,seatToggleFlow:this.seatToggleFlow,isHoverDevice:this.isHoverDevice}),this._refreshAllSeats(),this._updateLegend(),this.loadingOverlayTarget.hidden=!0,this.poller=new StatusPoller({intervalMs:POLL_INTERVAL_MS,onTick:()=>this._pollStatus(),signal:e}),this.poller.start(),this.pointerCoordinator.wire(e),this._wireStatusStream(e),this._wireCartChanged(e),this.element.addEventListener("standing-block-clicked",this._handleStandingBlockClick.bind(this),{signal:e})}disconnect(){this.abort?.abort(),this._catalogRefetchTimer&&clearTimeout(this._catalogRefetchTimer)}zoomIn(){this.renderer.zoomIn()}zoomOut(){this.renderer.zoomOut()}resetZoom(){this.renderer.resetZoom()}reload(){window.location.reload()}selectVersion(e){const t=e.currentTarget,a=Number(t.dataset.seatId),i=Number(t.dataset.variantId),s=this.renderer.enriched.get(a);s&&(this.pointerCoordinator.notifyVersionSelected(a,i),this.pointerCoordinator.closePopover(),this.seatToggleFlow.toggle(s,i,{dismissTooltip:()=>this.pointerCoordinator.closePopover()}))}closePopover(){this.pointerCoordinator.closePopover()}popoverKeydown(e){if("Escape"===e.key||"Tab"===e.key)return e.preventDefault(),void this.pointerCoordinator.closePopover();if(!["ArrowDown","ArrowUp","Home","End"].includes(e.key))return;const t=Array.from(this.tooltipVersionListTarget.querySelectorAll('button[role="menuitem"]'));if(0===t.length)return;e.preventDefault();const a=document.activeElement;let i,s=t.indexOf(a);switch(-1===s&&(s=0),e.key){case"ArrowDown":i=(s+1)%t.length;break;case"ArrowUp":i=(s-1+t.length)%t.length;break;case"Home":i=0;break;case"End":i=t.length-1}t[i].focus()}canvasFocus(){this.canvasTarget.matches(":focus-visible")&&(this.canvasKeyboard?.focusedSeatId||this.canvasKeyboard?.focusSeat(this.canvasKeyboard.firstSeat()),this.canvasKeyboard&&(this.canvasKeyboard.hasNavigated=!1))}canvasKeydown(e){return"Escape"===e.key?(e.preventDefault(),this.popover?.isOpen()?void this.pointerCoordinator.closePopover():(this.canvasKeyboard?.clearFocus(),void this.canvasTarget.blur())):"h"===e.key.toLowerCase()?(e.preventDefault(),void this._toggleSidebarFromKeyboard()):"a"===e.key.toLowerCase()?(e.preventDefault(),void this.canvasKeyboard?.focusNextAccessibleSeat()):["+","=","Add"].includes(e.key)?(e.preventDefault(),void this.zoomIn()):["-","_","Subtract"].includes(e.key)?(e.preventDefault(),void this.zoomOut()):"0"===e.key?(e.preventDefault(),void this.resetZoom()):void this.canvasKeyboard?.handleKeydown(e)}toggleSidebar(){this.hasSidebarTarget&&this._setSidebarCollapsed(!this.sidebarTarget.classList.contains("collapsed"))}highlightAccessibleSeats(e){const t=e.params.set,a="poorvisibility"===t?this.planStatus.poorVisibilitySet:"voucher_swap"===t?this.planStatus.voucherSwapMap:this.planStatus.handicapSet,i=[],s=e=>{this.renderer.enriched.has(e)&&("poorvisibility"===t&&this.planStatus.handicapSet.has(e)||i.push(e))};a instanceof Map?a.forEach(((e,t)=>
1s(t))):a.forEach((e=>s(e))),i.length&&this.renderer.popSeats(i)}_requireTargets(){const e=REQUIRED_TARGETS.filter((e=>!this[`has${e[0].toUpperCase()}${e.slice(1)}Target`]));if(e.length)throw new Error(`seating-plan: missing required target(s): ${e.join(", ")}. Theme must include all template targets in _seating_plan.liquid.`)}_refreshIsolatedSeats(){if(!this.segmentIndex||!this.planStatus||!this.renderer)return;const{freeSet:e,handicapSet:t,mineSet:a}=this.planStatus;this._isolatedSet.clear();const i=new Set;for(const s of a){const r=this.segmentIndex.get(s);if(r&&!i.has(r.segment)){i.add(r.segment);for(const i of findIsolatedSeats(r.segment,e,a,t))this._isolatedSet.add(i)}}this.renderer.setIsolatedSeats([...this._isolatedSet])}async _buildMinimap(e){this.hasSidebarToggleTarget&&(this.sidebarToggleTarget.hidden=!1),this.hasSidebarTarget&&(this.sidebarTarget.hidden=!1);const t=Math.floor(this.minimapCanvasTarget.getBoundingClientRect().width)||120;this.minimap=new SeatingPlanMinimap({canvas:this.minimapCanvasTarget,plan:this.structure,planStatus:this.planStatus,renderer:this.renderer,viewportColor:this.colors.minimapViewport,width:t,signal:e}),await this.minimap.init(),this.resetZoom(),window.matchMedia("(max-width: 768px)").matches&&this._setSidebarCollapsed(!0)}_setSidebarCollapsed(e){this.sidebarTarget.classList.toggle("collapsed",e),this.hasSidebarToggleTarget&&this.sidebarToggleTarget.setAttribute("aria-expanded",e?"false":"true"),this.minimap?.setVisible(!e)}_wireStatusStream(e){this.element.addEventListener("seating-plan:status",(e=>{const t=Number(e.detail.seat_id);this.planStatus.unmarkPending(t),this.planStatus.applySeatToggle(e.detail),e.detail.added||this.pointerCoordinator?.clearTrackVersion(t),this._refreshSeat(t),this.minimap?.refreshSeat(t),this.pointerCoordinator?.refreshHoverState(t),this.canvasKeyboard?.onStatusChanged(),this._announceSeatMutation(t,e.detail.added),this._refreshIsolatedSeats()}),{signal:e})}_wireCartChanged(e){window.addEventListener("cart:changed",(()=>{this._catalogRefetchTimer&&clearTimeout(this._catalogRefetchTimer),this._statusRefetchTimer&&clearTimeout(this._statusRefetchTimer),this._catalogRefetchTimer=setTimeout((()=>{this.catalogStore.refresh()}),CATALOG_DEBOUNCE_MS),this._statusRefetchTimer=setTimeout((()=>this._pollStatus()),CATALOG_DEBOUNCE_MS+200)}),{signal:e})}_toggleSidebarFromKeyboard(){if(!this.hasSidebarTarget)return;const e=this.sidebarTarget.classList.contains("collapsed");this._setSidebarCollapsed(!e),e&&this.hasKeyboardShortcutsDetailsTarget&&(this.keyboardShortcutsDetailsTarget.open=!0)}async _pollStatus(){if(this.planStatus)try{this.planStatus.applyStatus(await this.api.getStatus()),this._refreshAllSeats(),this.minimap?.refreshSeats(),this.pointerCoordinator?.refreshHoverState(),this.canvasKeyboard?.onStatusChanged(),this._updateLegend(),this._refreshIsolatedSeats()}catch(e){console.error("Status poll failed:",e)}}_refreshSeat(e){this.renderer.refreshSeat(e,this.planStatus.renderHints(e))}_refreshAllSeats(){this.renderer.seatParticles.forEach(((e,t)=>this._refreshSeat(t)))}_updateLegend(){this.hasLegendHandicapTarget&&(this.legendHandicapTarget.hidden=0===this.planStatus.handicapSet.size),this.hasLegendPoorVisibilityTarget&&(this.legendPoorVisibilityTarget.hidden=0===this.planStatus.poorVisibilitySet.size),this.hasLegendVoucherSwapTarget&&(this.legendVoucherSwapTarget.hidden=0===this.planStatus.voucherSwapMap.size)}async _handleStandingBlockClick(e){const t=e.detail.blockIdx,a=this.renderer.standingBlockGraphics.get(t);if(a?.variantId&&this.hasStandingBlockModalPathValue){const e=new URL(this.standingBlockModalPathValue,window.location.origin);e.searchParams.set("variant_id",a.variantId),get(e.toString(),{responseKind:"turbo-stream"})}}_showError(){if(!this.hasErrorTemplateTarget)return;const e=this.errorTemplateTarget.content.cloneNode(!0),t=e.querySelector("[data-error-message]");t&&(t.textContent=this.hasLoadFailedMessageValue?this.loadFailedMessageValue:"Saalplan konnte nicht geladen werden."),this.element.replaceChildren(e)}_formatPrice(e){return Number(e||0).toFixed(2).replace(".",",")+" \u20ac"}_announceSeatMutation(e,t){const a=this.renderer?.enriched?.get(e);if(!a)return;const i=t?this.seatAddedLabelValue:this.seatRemovedLabelValue;this.srAnnouncer.announce(`${this._seatSummary(a)} ${i}.`)}_seatSummary(e){return(this.seatAriaLabelTemplateValue||"Block %{block}, row %{row}, seat %{no}, %{variant}").replace("%{block}",e.block_name||"").replace("%{row}",e.row_name||"").replace("%{no}",String(e.no??"")).replace(/[,\s]*%\{variant\}/,"").replace(/\s+,/g,",").replace(/,\s*$/,"")}}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.