@nex125/seatmap-core 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -132,6 +132,16 @@ function normalizeVenue(venue) {
132
132
  const seatStatuses = venue.seatStatuses && venue.seatStatuses.length > 0 ? venue.seatStatuses : DEFAULT_SEAT_STATUSES;
133
133
  const clonedStatuses = seatStatuses.map((status) => ({ ...status }));
134
134
  const allowedStatuses = new Set(clonedStatuses.map((status) => status.id));
135
+ const categories = venue.categories.map((category) => {
136
+ const hasBackendPrice = Number.isFinite(category.backendPrice);
137
+ const hasOverriddenPrice = Number.isFinite(category.overriddenPrice);
138
+ return {
139
+ ...category,
140
+ backendPrice: hasBackendPrice ? category.backendPrice : void 0,
141
+ overriddenPrice: hasOverriddenPrice ? category.overriddenPrice : void 0,
142
+ isPriceOverridden: Boolean(category.isPriceOverridden) && hasOverriddenPrice
143
+ };
144
+ });
135
145
  const sections = venue.sections.map((section) => ({
136
146
  ...section,
137
147
  rows: section.rows.map((row) => ({
@@ -151,6 +161,7 @@ function normalizeVenue(venue) {
151
161
  }));
152
162
  return {
153
163
  ...venue,
164
+ categories,
154
165
  seatStatuses: clonedStatuses,
155
166
  sections,
156
167
  tables
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/models/helpers.ts","../src/spatial/SpatialIndex.ts","../src/rendering/Viewport.ts","../src/rendering/LODLevel.ts","../src/rendering/SpriteAtlas.ts","../src/rendering/CategoryTextureCache.ts","../src/commands/CommandHistory.ts","../src/serialization/index.ts"],"names":["uuidv7","RBush","LODLevel","Graphics"],"mappings":"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","file":"index.cjs","sourcesContent":["import { v7 as uuidv7 } from \"uuid\";\nimport type { AABB, Section, Seat, SeatStatusDefinition, Vec2, Venue } from \"./types\";\n\nexport const AVAILABLE_STATUS_ID = \"available\";\n\nexport const DEFAULT_SEAT_STATUSES: SeatStatusDefinition[] = [\n { id: AVAILABLE_STATUS_ID, name: \"Available\", color: \"#4caf50\" },\n { id: \"locked\", name: \"Locked\", color: \"#f44336\" },\n { id: \"booked\", name: \"Booked\", color: \"#9e9e9e\" },\n];\n\nconst LEGACY_STATUS_MAP: Record<string, string> = {\n held: \"locked\",\n blocked: \"locked\",\n sold: \"booked\",\n};\n\nfunction normalizeStatusId(rawStatus: string, allowedStatuses: Set<string>): string {\n const mapped = LEGACY_STATUS_MAP[rawStatus] ?? rawStatus;\n if (allowedStatuses.has(mapped)) return mapped;\n return AVAILABLE_STATUS_ID;\n}\n\nexport function seatWorldPosition(section: Section, seat: Seat): Vec2 {\n const cos = Math.cos(section.rotation);\n const sin = Math.sin(section.rotation);\n return {\n x: section.position.x + seat.position.x * cos - seat.position.y * sin,\n y: section.position.y + seat.position.x * sin + seat.position.y * cos,\n };\n}\n\nexport function sectionAABB(section: Section): AABB {\n const allPoints: Vec2[] = [];\n\n if (section.outline.length > 0) {\n const cos = Math.cos(section.rotation);\n const sin = Math.sin(section.rotation);\n for (const p of section.outline) {\n allPoints.push({\n x: section.position.x + p.x * cos - p.y * sin,\n y: section.position.y + p.x * sin + p.y * cos,\n });\n }\n }\n\n const allSeats = section.rows.flatMap((r) => r.seats);\n for (const seat of allSeats) {\n allPoints.push(seatWorldPosition(section, seat));\n }\n\n if (allPoints.length === 0) {\n return {\n minX: section.position.x,\n minY: section.position.y,\n maxX: section.position.x,\n maxY: section.position.y,\n };\n }\n\n const pad = 10;\n return {\n minX: Math.min(...allPoints.map((p) => p.x)) - pad,\n minY: Math.min(...allPoints.map((p) => p.y)) - pad,\n maxX: Math.max(...allPoints.map((p) => p.x)) + pad,\n maxY: Math.max(...allPoints.map((p) => p.y)) + pad,\n };\n}\n\nexport function venueAABB(venue: Venue): AABB {\n if (venue.sections.length === 0) {\n return { minX: 0, minY: 0, maxX: venue.bounds.width, maxY: venue.bounds.height };\n }\n const boxes = venue.sections.map(sectionAABB);\n return {\n minX: Math.min(...boxes.map((b) => b.minX)),\n minY: Math.min(...boxes.map((b) => b.minY)),\n maxX: Math.max(...boxes.map((b) => b.maxX)),\n maxY: Math.max(...boxes.map((b) => b.maxY)),\n };\n}\n\n/** Ray-casting point-in-polygon test. Works with any simple polygon. */\nexport function pointInPolygon(point: Vec2, polygon: Vec2[]): boolean {\n if (polygon.length < 3) return false;\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i].x, yi = polygon[i].y;\n const xj = polygon[j].x, yj = polygon[j].y;\n if ((yi > point.y) !== (yj > point.y) &&\n point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi) {\n inside = !inside;\n }\n }\n return inside;\n}\n\n/** Clamp a point to the nearest position inside a polygon (with margin). */\nexport function clampToPolygon(point: Vec2, polygon: Vec2[], margin = 5): Vec2 {\n if (polygon.length < 3 || pointInPolygon(point, polygon)) return point;\n\n // Find the closest point on any polygon edge\n let bestX = point.x, bestY = point.y, bestDist = Infinity;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const ax = polygon[j].x, ay = polygon[j].y;\n const bx = polygon[i].x, by = polygon[i].y;\n const dx = bx - ax, dy = by - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) continue;\n const t = Math.max(0, Math.min(1, ((point.x - ax) * dx + (point.y - ay) * dy) / len2));\n const cx = ax + t * dx - margin * dy / Math.sqrt(len2);\n const cy = ay + t * dy + margin * dx / Math.sqrt(len2);\n const d = Math.hypot(point.x - cx, point.y - cy);\n if (d < bestDist) { bestDist = d; bestX = cx; bestY = cy; }\n }\n\n // Verify the clamped point is inside; if not just project onto edge without margin\n if (!pointInPolygon({ x: bestX, y: bestY }, polygon)) {\n bestDist = Infinity;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const ax = polygon[j].x, ay = polygon[j].y;\n const bx = polygon[i].x, by = polygon[i].y;\n const dx = bx - ax, dy = by - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) continue;\n const t = Math.max(0, Math.min(1, ((point.x - ax) * dx + (point.y - ay) * dy) / len2));\n const cx = ax + t * dx, cy = ay + t * dy;\n const d = Math.hypot(point.x - cx, point.y - cy);\n if (d < bestDist) { bestDist = d; bestX = cx; bestY = cy; }\n }\n }\n\n return { x: bestX, y: bestY };\n}\n\nexport function normalizeVenue(venue: Venue): Venue {\n const seatStatuses =\n venue.seatStatuses && venue.seatStatuses.length > 0\n ? venue.seatStatuses\n : DEFAULT_SEAT_STATUSES;\n const clonedStatuses = seatStatuses.map((status) => ({ ...status }));\n const allowedStatuses = new Set(clonedStatuses.map((status) => status.id));\n\n const sections = venue.sections.map((section) => ({\n ...section,\n rows: section.rows.map((row) => ({\n ...row,\n seats: row.seats.map((seat) => ({\n ...seat,\n status: normalizeStatusId(seat.status, allowedStatuses),\n })),\n })),\n }));\n\n const tables = venue.tables.map((table) => ({\n ...table,\n seats: table.seats.map((seat) => ({\n ...seat,\n status: normalizeStatusId(seat.status, allowedStatuses),\n })),\n }));\n\n return {\n ...venue,\n seatStatuses: clonedStatuses,\n sections,\n tables,\n };\n}\n\nexport function generateId(prefix = \"\"): string {\n const id = uuidv7();\n return prefix ? `${prefix}-${id}` : id;\n}\n","import RBush from \"rbush\";\nimport type { AABB, Section, Vec2 } from \"../models/types\";\nimport { seatWorldPosition, sectionAABB } from \"../models/helpers\";\n\nexport interface SpatialItem extends AABB {\n type: \"section\" | \"seat\";\n sectionId: string;\n seatId?: string;\n}\n\nexport class SpatialIndex {\n private tree = new RBush<SpatialItem>();\n private items: SpatialItem[] = [];\n\n buildFromSections(sections: Section[]): void {\n this.items = [];\n\n for (const section of sections) {\n const box = sectionAABB(section);\n this.items.push({\n ...box,\n type: \"section\",\n sectionId: section.id,\n });\n\n for (const row of section.rows) {\n for (const seat of row.seats) {\n const wp = seatWorldPosition(section, seat);\n const r = 8;\n this.items.push({\n minX: wp.x - r,\n minY: wp.y - r,\n maxX: wp.x + r,\n maxY: wp.y + r,\n type: \"seat\",\n sectionId: section.id,\n seatId: seat.id,\n });\n }\n }\n }\n\n this.tree.clear();\n this.tree.load(this.items);\n }\n\n queryViewport(viewport: AABB): SpatialItem[] {\n return this.tree.search(viewport);\n }\n\n queryPoint(point: Vec2, radius = 8): SpatialItem[] {\n return this.tree.search({\n minX: point.x - radius,\n minY: point.y - radius,\n maxX: point.x + radius,\n maxY: point.y + radius,\n });\n }\n\n queryRect(rect: AABB): SpatialItem[] {\n return this.tree.search(rect);\n }\n}\n","import type { AABB, Vec2 } from \"../models/types\";\n\nexport interface ViewportState {\n x: number;\n y: number;\n zoom: number;\n}\n\nconst MIN_ZOOM = 0.05;\nconst MAX_ZOOM = 4;\n\nexport class Viewport {\n x = 0;\n y = 0;\n zoom = 1;\n screenWidth = 0;\n screenHeight = 0;\n\n private listeners = new Set<() => void>();\n\n setScreenSize(width: number, height: number): void {\n this.screenWidth = width;\n this.screenHeight = height;\n this.notify();\n }\n\n pan(dx: number, dy: number): void {\n this.x += dx / this.zoom;\n this.y += dy / this.zoom;\n this.notify();\n }\n\n zoomAt(screenPoint: Vec2, factor: number): void {\n const newZoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, this.zoom * factor));\n\n // 1) World coordinate currently under the cursor\n const wx = screenPoint.x / this.zoom - this.x;\n const wy = screenPoint.y / this.zoom - this.y;\n\n // 2) Solve for the offset that keeps that world point at the same screen position\n // screenPoint = (world + offset) * newZoom → offset = screenPoint / newZoom - world\n this.x = screenPoint.x / newZoom - wx;\n this.y = screenPoint.y / newZoom - wy;\n this.zoom = newZoom;\n this.notify();\n }\n\n setZoom(zoom: number): void {\n this.zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, zoom));\n this.notify();\n }\n\n fitBounds(aabb: AABB, padding = 40): void {\n const contentW = aabb.maxX - aabb.minX;\n const contentH = aabb.maxY - aabb.minY;\n if (contentW <= 0 || contentH <= 0) return;\n\n const scaleX = (this.screenWidth - padding * 2) / contentW;\n const scaleY = (this.screenHeight - padding * 2) / contentH;\n this.zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, Math.min(scaleX, scaleY)));\n\n this.x = -(aabb.minX + contentW / 2) + this.screenWidth / (2 * this.zoom);\n this.y = -(aabb.minY + contentH / 2) + this.screenHeight / (2 * this.zoom);\n this.notify();\n }\n\n screenToWorld(screenX: number, screenY: number): Vec2 {\n return {\n x: screenX / this.zoom - this.x,\n y: screenY / this.zoom - this.y,\n };\n }\n\n worldToScreen(worldX: number, worldY: number): Vec2 {\n return {\n x: (worldX + this.x) * this.zoom,\n y: (worldY + this.y) * this.zoom,\n };\n }\n\n getVisibleAABB(): AABB {\n const topLeft = this.screenToWorld(0, 0);\n const bottomRight = this.screenToWorld(this.screenWidth, this.screenHeight);\n return {\n minX: topLeft.x,\n minY: topLeft.y,\n maxX: bottomRight.x,\n maxY: bottomRight.y,\n };\n }\n\n getState(): ViewportState {\n return { x: this.x, y: this.y, zoom: this.zoom };\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n","export enum LODLevel {\n Overview = \"overview\",\n Section = \"section\",\n Detail = \"detail\",\n}\n\nconst SECTION_THRESHOLD = 0.3;\nconst DETAIL_THRESHOLD = 0.7;\n\nexport function getLODLevel(zoom: number): LODLevel {\n if (zoom < SECTION_THRESHOLD) return LODLevel.Overview;\n if (zoom < DETAIL_THRESHOLD) return LODLevel.Section;\n return LODLevel.Detail;\n}\n","import { Graphics, type Texture, type Renderer } from \"pixi.js\";\nimport type { SeatStatusDefinition } from \"../models\";\n\nexport interface SeatTextureSet {\n [statusId: string]: Texture;\n selected: Texture;\n hovered: Texture;\n}\n\nconst UI_TEXTURE_COLORS: Record<string, number> = {\n selected: 0x2196f3,\n hovered: 0x64b5f6,\n};\n\nfunction parseHexColor(color: string): number {\n return parseInt(color.replace(\"#\", \"\"), 16);\n}\n\nexport function createSeatTextures(\n renderer: Renderer,\n seatStatuses: SeatStatusDefinition[],\n radius = 7,\n categoryColor?: number,\n textureResolution?: number,\n): SeatTextureSet {\n const result: Partial<SeatTextureSet> = {};\n const resolution = textureResolution ?? (4 * (typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1));\n\n for (const status of seatStatuses) {\n const g = new Graphics();\n const fillColor = status.id === \"available\" && categoryColor != null\n ? categoryColor\n : parseHexColor(status.color);\n g.circle(radius + 4, radius + 4, radius);\n g.fill({ color: fillColor });\n\n const texture = renderer.textureGenerator.generateTexture({\n target: g,\n resolution,\n antialias: true,\n });\n g.destroy();\n\n result[status.id] = texture;\n }\n\n for (const [statusId, color] of Object.entries(UI_TEXTURE_COLORS)) {\n const g = new Graphics();\n g.circle(radius + 4, radius + 4, radius);\n g.fill({ color });\n\n if (statusId === \"selected\") {\n g.circle(radius + 4, radius + 4, radius + 2);\n g.stroke({ color: 0xffffff, width: 2 });\n }\n\n const texture = renderer.textureGenerator.generateTexture({\n target: g,\n resolution,\n antialias: true,\n });\n g.destroy();\n\n result[statusId] = texture;\n }\n\n return result as SeatTextureSet;\n}\n\nexport function destroySeatTextures(textures: SeatTextureSet): void {\n for (const tex of Object.values(textures)) {\n tex.destroy(true);\n }\n}\n","import type { Renderer } from \"pixi.js\";\nimport type { SeatStatusDefinition } from \"../models\";\nimport {\n createSeatTextures,\n destroySeatTextures,\n type SeatTextureSet,\n} from \"./SpriteAtlas\";\n\nexport class CategoryTextureCache {\n private cache = new Map<string, SeatTextureSet>();\n private defaultTextures: SeatTextureSet | null = null;\n\n create(\n renderer: Renderer,\n categories: { id: string; color: string }[],\n seatStatuses: SeatStatusDefinition[],\n seatRadius = 7,\n ): void {\n this.destroy();\n this.defaultTextures = createSeatTextures(renderer, seatStatuses, seatRadius);\n\n for (const cat of categories) {\n const color = parseInt(cat.color.replace(\"#\", \"\"), 16);\n this.cache.set(cat.id, createSeatTextures(renderer, seatStatuses, seatRadius, color));\n }\n }\n\n get(categoryId: string): SeatTextureSet {\n return this.cache.get(categoryId) ?? this.defaultTextures!;\n }\n\n destroy(): void {\n for (const textures of this.cache.values()) {\n destroySeatTextures(textures);\n }\n if (this.defaultTextures) {\n destroySeatTextures(this.defaultTextures);\n }\n this.cache.clear();\n this.defaultTextures = null;\n }\n}\n","export interface Command {\n execute(): void;\n undo(): void;\n description: string;\n}\n\nexport class CommandHistory {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private listeners = new Set<() => void>();\n\n execute(command: Command): void {\n command.execute();\n this.undoStack.push(command);\n this.redoStack = [];\n this.notify();\n }\n\n undo(): void {\n const command = this.undoStack.pop();\n if (!command) return;\n command.undo();\n this.redoStack.push(command);\n this.notify();\n }\n\n redo(): void {\n const command = this.redoStack.pop();\n if (!command) return;\n command.execute();\n this.undoStack.push(command);\n this.notify();\n }\n\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notify();\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n","import type { Venue } from \"../models/types\";\nimport { normalizeVenue } from \"../models/helpers\";\n\nexport function serializeVenue(venue: Venue): string {\n return JSON.stringify(venue, null, 2);\n}\n\nexport function deserializeVenue(json: string): Venue {\n return normalizeVenue(JSON.parse(json) as Venue);\n}\n"]}
1
+ {"version":3,"sources":["../src/models/helpers.ts","../src/spatial/SpatialIndex.ts","../src/rendering/Viewport.ts","../src/rendering/LODLevel.ts","../src/rendering/SpriteAtlas.ts","../src/rendering/CategoryTextureCache.ts","../src/commands/CommandHistory.ts","../src/serialization/index.ts"],"names":["uuidv7","RBush","LODLevel","Graphics"],"mappings":"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","file":"index.cjs","sourcesContent":["import { v7 as uuidv7 } from \"uuid\";\nimport type { AABB, Section, Seat, SeatStatusDefinition, Vec2, Venue } from \"./types\";\n\nexport const AVAILABLE_STATUS_ID = \"available\";\n\nexport const DEFAULT_SEAT_STATUSES: SeatStatusDefinition[] = [\n { id: AVAILABLE_STATUS_ID, name: \"Available\", color: \"#4caf50\" },\n { id: \"locked\", name: \"Locked\", color: \"#f44336\" },\n { id: \"booked\", name: \"Booked\", color: \"#9e9e9e\" },\n];\n\nconst LEGACY_STATUS_MAP: Record<string, string> = {\n held: \"locked\",\n blocked: \"locked\",\n sold: \"booked\",\n};\n\nfunction normalizeStatusId(rawStatus: string, allowedStatuses: Set<string>): string {\n const mapped = LEGACY_STATUS_MAP[rawStatus] ?? rawStatus;\n if (allowedStatuses.has(mapped)) return mapped;\n return AVAILABLE_STATUS_ID;\n}\n\nexport function seatWorldPosition(section: Section, seat: Seat): Vec2 {\n const cos = Math.cos(section.rotation);\n const sin = Math.sin(section.rotation);\n return {\n x: section.position.x + seat.position.x * cos - seat.position.y * sin,\n y: section.position.y + seat.position.x * sin + seat.position.y * cos,\n };\n}\n\nexport function sectionAABB(section: Section): AABB {\n const allPoints: Vec2[] = [];\n\n if (section.outline.length > 0) {\n const cos = Math.cos(section.rotation);\n const sin = Math.sin(section.rotation);\n for (const p of section.outline) {\n allPoints.push({\n x: section.position.x + p.x * cos - p.y * sin,\n y: section.position.y + p.x * sin + p.y * cos,\n });\n }\n }\n\n const allSeats = section.rows.flatMap((r) => r.seats);\n for (const seat of allSeats) {\n allPoints.push(seatWorldPosition(section, seat));\n }\n\n if (allPoints.length === 0) {\n return {\n minX: section.position.x,\n minY: section.position.y,\n maxX: section.position.x,\n maxY: section.position.y,\n };\n }\n\n const pad = 10;\n return {\n minX: Math.min(...allPoints.map((p) => p.x)) - pad,\n minY: Math.min(...allPoints.map((p) => p.y)) - pad,\n maxX: Math.max(...allPoints.map((p) => p.x)) + pad,\n maxY: Math.max(...allPoints.map((p) => p.y)) + pad,\n };\n}\n\nexport function venueAABB(venue: Venue): AABB {\n if (venue.sections.length === 0) {\n return { minX: 0, minY: 0, maxX: venue.bounds.width, maxY: venue.bounds.height };\n }\n const boxes = venue.sections.map(sectionAABB);\n return {\n minX: Math.min(...boxes.map((b) => b.minX)),\n minY: Math.min(...boxes.map((b) => b.minY)),\n maxX: Math.max(...boxes.map((b) => b.maxX)),\n maxY: Math.max(...boxes.map((b) => b.maxY)),\n };\n}\n\n/** Ray-casting point-in-polygon test. Works with any simple polygon. */\nexport function pointInPolygon(point: Vec2, polygon: Vec2[]): boolean {\n if (polygon.length < 3) return false;\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i].x, yi = polygon[i].y;\n const xj = polygon[j].x, yj = polygon[j].y;\n if ((yi > point.y) !== (yj > point.y) &&\n point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi) {\n inside = !inside;\n }\n }\n return inside;\n}\n\n/** Clamp a point to the nearest position inside a polygon (with margin). */\nexport function clampToPolygon(point: Vec2, polygon: Vec2[], margin = 5): Vec2 {\n if (polygon.length < 3 || pointInPolygon(point, polygon)) return point;\n\n // Find the closest point on any polygon edge\n let bestX = point.x, bestY = point.y, bestDist = Infinity;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const ax = polygon[j].x, ay = polygon[j].y;\n const bx = polygon[i].x, by = polygon[i].y;\n const dx = bx - ax, dy = by - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) continue;\n const t = Math.max(0, Math.min(1, ((point.x - ax) * dx + (point.y - ay) * dy) / len2));\n const cx = ax + t * dx - margin * dy / Math.sqrt(len2);\n const cy = ay + t * dy + margin * dx / Math.sqrt(len2);\n const d = Math.hypot(point.x - cx, point.y - cy);\n if (d < bestDist) { bestDist = d; bestX = cx; bestY = cy; }\n }\n\n // Verify the clamped point is inside; if not just project onto edge without margin\n if (!pointInPolygon({ x: bestX, y: bestY }, polygon)) {\n bestDist = Infinity;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const ax = polygon[j].x, ay = polygon[j].y;\n const bx = polygon[i].x, by = polygon[i].y;\n const dx = bx - ax, dy = by - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) continue;\n const t = Math.max(0, Math.min(1, ((point.x - ax) * dx + (point.y - ay) * dy) / len2));\n const cx = ax + t * dx, cy = ay + t * dy;\n const d = Math.hypot(point.x - cx, point.y - cy);\n if (d < bestDist) { bestDist = d; bestX = cx; bestY = cy; }\n }\n }\n\n return { x: bestX, y: bestY };\n}\n\nexport function normalizeVenue(venue: Venue): Venue {\n const seatStatuses =\n venue.seatStatuses && venue.seatStatuses.length > 0\n ? venue.seatStatuses\n : DEFAULT_SEAT_STATUSES;\n const clonedStatuses = seatStatuses.map((status) => ({ ...status }));\n const allowedStatuses = new Set(clonedStatuses.map((status) => status.id));\n const categories = venue.categories.map((category) => {\n const hasBackendPrice = Number.isFinite(category.backendPrice);\n const hasOverriddenPrice = Number.isFinite(category.overriddenPrice);\n return {\n ...category,\n backendPrice: hasBackendPrice ? category.backendPrice : undefined,\n overriddenPrice: hasOverriddenPrice ? category.overriddenPrice : undefined,\n isPriceOverridden:\n Boolean(category.isPriceOverridden) && hasOverriddenPrice,\n };\n });\n\n const sections = venue.sections.map((section) => ({\n ...section,\n rows: section.rows.map((row) => ({\n ...row,\n seats: row.seats.map((seat) => ({\n ...seat,\n status: normalizeStatusId(seat.status, allowedStatuses),\n })),\n })),\n }));\n\n const tables = venue.tables.map((table) => ({\n ...table,\n seats: table.seats.map((seat) => ({\n ...seat,\n status: normalizeStatusId(seat.status, allowedStatuses),\n })),\n }));\n\n return {\n ...venue,\n categories,\n seatStatuses: clonedStatuses,\n sections,\n tables,\n };\n}\n\nexport function generateId(prefix = \"\"): string {\n const id = uuidv7();\n return prefix ? `${prefix}-${id}` : id;\n}\n","import RBush from \"rbush\";\nimport type { AABB, Section, Vec2 } from \"../models/types\";\nimport { seatWorldPosition, sectionAABB } from \"../models/helpers\";\n\nexport interface SpatialItem extends AABB {\n type: \"section\" | \"seat\";\n sectionId: string;\n seatId?: string;\n}\n\nexport class SpatialIndex {\n private tree = new RBush<SpatialItem>();\n private items: SpatialItem[] = [];\n\n buildFromSections(sections: Section[]): void {\n this.items = [];\n\n for (const section of sections) {\n const box = sectionAABB(section);\n this.items.push({\n ...box,\n type: \"section\",\n sectionId: section.id,\n });\n\n for (const row of section.rows) {\n for (const seat of row.seats) {\n const wp = seatWorldPosition(section, seat);\n const r = 8;\n this.items.push({\n minX: wp.x - r,\n minY: wp.y - r,\n maxX: wp.x + r,\n maxY: wp.y + r,\n type: \"seat\",\n sectionId: section.id,\n seatId: seat.id,\n });\n }\n }\n }\n\n this.tree.clear();\n this.tree.load(this.items);\n }\n\n queryViewport(viewport: AABB): SpatialItem[] {\n return this.tree.search(viewport);\n }\n\n queryPoint(point: Vec2, radius = 8): SpatialItem[] {\n return this.tree.search({\n minX: point.x - radius,\n minY: point.y - radius,\n maxX: point.x + radius,\n maxY: point.y + radius,\n });\n }\n\n queryRect(rect: AABB): SpatialItem[] {\n return this.tree.search(rect);\n }\n}\n","import type { AABB, Vec2 } from \"../models/types\";\n\nexport interface ViewportState {\n x: number;\n y: number;\n zoom: number;\n}\n\nconst MIN_ZOOM = 0.05;\nconst MAX_ZOOM = 4;\n\nexport class Viewport {\n x = 0;\n y = 0;\n zoom = 1;\n screenWidth = 0;\n screenHeight = 0;\n\n private listeners = new Set<() => void>();\n\n setScreenSize(width: number, height: number): void {\n this.screenWidth = width;\n this.screenHeight = height;\n this.notify();\n }\n\n pan(dx: number, dy: number): void {\n this.x += dx / this.zoom;\n this.y += dy / this.zoom;\n this.notify();\n }\n\n zoomAt(screenPoint: Vec2, factor: number): void {\n const newZoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, this.zoom * factor));\n\n // 1) World coordinate currently under the cursor\n const wx = screenPoint.x / this.zoom - this.x;\n const wy = screenPoint.y / this.zoom - this.y;\n\n // 2) Solve for the offset that keeps that world point at the same screen position\n // screenPoint = (world + offset) * newZoom → offset = screenPoint / newZoom - world\n this.x = screenPoint.x / newZoom - wx;\n this.y = screenPoint.y / newZoom - wy;\n this.zoom = newZoom;\n this.notify();\n }\n\n setZoom(zoom: number): void {\n this.zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, zoom));\n this.notify();\n }\n\n fitBounds(aabb: AABB, padding = 40): void {\n const contentW = aabb.maxX - aabb.minX;\n const contentH = aabb.maxY - aabb.minY;\n if (contentW <= 0 || contentH <= 0) return;\n\n const scaleX = (this.screenWidth - padding * 2) / contentW;\n const scaleY = (this.screenHeight - padding * 2) / contentH;\n this.zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, Math.min(scaleX, scaleY)));\n\n this.x = -(aabb.minX + contentW / 2) + this.screenWidth / (2 * this.zoom);\n this.y = -(aabb.minY + contentH / 2) + this.screenHeight / (2 * this.zoom);\n this.notify();\n }\n\n screenToWorld(screenX: number, screenY: number): Vec2 {\n return {\n x: screenX / this.zoom - this.x,\n y: screenY / this.zoom - this.y,\n };\n }\n\n worldToScreen(worldX: number, worldY: number): Vec2 {\n return {\n x: (worldX + this.x) * this.zoom,\n y: (worldY + this.y) * this.zoom,\n };\n }\n\n getVisibleAABB(): AABB {\n const topLeft = this.screenToWorld(0, 0);\n const bottomRight = this.screenToWorld(this.screenWidth, this.screenHeight);\n return {\n minX: topLeft.x,\n minY: topLeft.y,\n maxX: bottomRight.x,\n maxY: bottomRight.y,\n };\n }\n\n getState(): ViewportState {\n return { x: this.x, y: this.y, zoom: this.zoom };\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n","export enum LODLevel {\n Overview = \"overview\",\n Section = \"section\",\n Detail = \"detail\",\n}\n\nconst SECTION_THRESHOLD = 0.3;\nconst DETAIL_THRESHOLD = 0.7;\n\nexport function getLODLevel(zoom: number): LODLevel {\n if (zoom < SECTION_THRESHOLD) return LODLevel.Overview;\n if (zoom < DETAIL_THRESHOLD) return LODLevel.Section;\n return LODLevel.Detail;\n}\n","import { Graphics, type Texture, type Renderer } from \"pixi.js\";\nimport type { SeatStatusDefinition } from \"../models\";\n\nexport interface SeatTextureSet {\n [statusId: string]: Texture;\n selected: Texture;\n hovered: Texture;\n}\n\nconst UI_TEXTURE_COLORS: Record<string, number> = {\n selected: 0x2196f3,\n hovered: 0x64b5f6,\n};\n\nfunction parseHexColor(color: string): number {\n return parseInt(color.replace(\"#\", \"\"), 16);\n}\n\nexport function createSeatTextures(\n renderer: Renderer,\n seatStatuses: SeatStatusDefinition[],\n radius = 7,\n categoryColor?: number,\n textureResolution?: number,\n): SeatTextureSet {\n const result: Partial<SeatTextureSet> = {};\n const resolution = textureResolution ?? (4 * (typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1));\n\n for (const status of seatStatuses) {\n const g = new Graphics();\n const fillColor = status.id === \"available\" && categoryColor != null\n ? categoryColor\n : parseHexColor(status.color);\n g.circle(radius + 4, radius + 4, radius);\n g.fill({ color: fillColor });\n\n const texture = renderer.textureGenerator.generateTexture({\n target: g,\n resolution,\n antialias: true,\n });\n g.destroy();\n\n result[status.id] = texture;\n }\n\n for (const [statusId, color] of Object.entries(UI_TEXTURE_COLORS)) {\n const g = new Graphics();\n g.circle(radius + 4, radius + 4, radius);\n g.fill({ color });\n\n if (statusId === \"selected\") {\n g.circle(radius + 4, radius + 4, radius + 2);\n g.stroke({ color: 0xffffff, width: 2 });\n }\n\n const texture = renderer.textureGenerator.generateTexture({\n target: g,\n resolution,\n antialias: true,\n });\n g.destroy();\n\n result[statusId] = texture;\n }\n\n return result as SeatTextureSet;\n}\n\nexport function destroySeatTextures(textures: SeatTextureSet): void {\n for (const tex of Object.values(textures)) {\n tex.destroy(true);\n }\n}\n","import type { Renderer } from \"pixi.js\";\nimport type { SeatStatusDefinition } from \"../models\";\nimport {\n createSeatTextures,\n destroySeatTextures,\n type SeatTextureSet,\n} from \"./SpriteAtlas\";\n\nexport class CategoryTextureCache {\n private cache = new Map<string, SeatTextureSet>();\n private defaultTextures: SeatTextureSet | null = null;\n\n create(\n renderer: Renderer,\n categories: { id: string; color: string }[],\n seatStatuses: SeatStatusDefinition[],\n seatRadius = 7,\n ): void {\n this.destroy();\n this.defaultTextures = createSeatTextures(renderer, seatStatuses, seatRadius);\n\n for (const cat of categories) {\n const color = parseInt(cat.color.replace(\"#\", \"\"), 16);\n this.cache.set(cat.id, createSeatTextures(renderer, seatStatuses, seatRadius, color));\n }\n }\n\n get(categoryId: string): SeatTextureSet {\n return this.cache.get(categoryId) ?? this.defaultTextures!;\n }\n\n destroy(): void {\n for (const textures of this.cache.values()) {\n destroySeatTextures(textures);\n }\n if (this.defaultTextures) {\n destroySeatTextures(this.defaultTextures);\n }\n this.cache.clear();\n this.defaultTextures = null;\n }\n}\n","export interface Command {\n execute(): void;\n undo(): void;\n description: string;\n}\n\nexport class CommandHistory {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private listeners = new Set<() => void>();\n\n execute(command: Command): void {\n command.execute();\n this.undoStack.push(command);\n this.redoStack = [];\n this.notify();\n }\n\n undo(): void {\n const command = this.undoStack.pop();\n if (!command) return;\n command.undo();\n this.redoStack.push(command);\n this.notify();\n }\n\n redo(): void {\n const command = this.redoStack.pop();\n if (!command) return;\n command.execute();\n this.undoStack.push(command);\n this.notify();\n }\n\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notify();\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n","import type { Venue } from \"../models/types\";\nimport { normalizeVenue } from \"../models/helpers\";\n\nexport function serializeVenue(venue: Venue): string {\n return JSON.stringify(venue, null, 2);\n}\n\nexport function deserializeVenue(json: string): Venue {\n return normalizeVenue(JSON.parse(json) as Venue);\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -24,6 +24,9 @@ interface PricingCategory {
24
24
  id: string;
25
25
  name: string;
26
26
  color: string;
27
+ backendPrice?: number;
28
+ isPriceOverridden?: boolean;
29
+ overriddenPrice?: number;
27
30
  }
28
31
  interface Seat {
29
32
  id: string;
package/dist/index.d.ts CHANGED
@@ -24,6 +24,9 @@ interface PricingCategory {
24
24
  id: string;
25
25
  name: string;
26
26
  color: string;
27
+ backendPrice?: number;
28
+ isPriceOverridden?: boolean;
29
+ overriddenPrice?: number;
27
30
  }
28
31
  interface Seat {
29
32
  id: string;
package/dist/index.js CHANGED
@@ -126,6 +126,16 @@ function normalizeVenue(venue) {
126
126
  const seatStatuses = venue.seatStatuses && venue.seatStatuses.length > 0 ? venue.seatStatuses : DEFAULT_SEAT_STATUSES;
127
127
  const clonedStatuses = seatStatuses.map((status) => ({ ...status }));
128
128
  const allowedStatuses = new Set(clonedStatuses.map((status) => status.id));
129
+ const categories = venue.categories.map((category) => {
130
+ const hasBackendPrice = Number.isFinite(category.backendPrice);
131
+ const hasOverriddenPrice = Number.isFinite(category.overriddenPrice);
132
+ return {
133
+ ...category,
134
+ backendPrice: hasBackendPrice ? category.backendPrice : void 0,
135
+ overriddenPrice: hasOverriddenPrice ? category.overriddenPrice : void 0,
136
+ isPriceOverridden: Boolean(category.isPriceOverridden) && hasOverriddenPrice
137
+ };
138
+ });
129
139
  const sections = venue.sections.map((section) => ({
130
140
  ...section,
131
141
  rows: section.rows.map((row) => ({
@@ -145,6 +155,7 @@ function normalizeVenue(venue) {
145
155
  }));
146
156
  return {
147
157
  ...venue,
158
+ categories,
148
159
  seatStatuses: clonedStatuses,
149
160
  sections,
150
161
  tables
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/models/helpers.ts","../src/spatial/SpatialIndex.ts","../src/rendering/Viewport.ts","../src/rendering/LODLevel.ts","../src/rendering/SpriteAtlas.ts","../src/rendering/CategoryTextureCache.ts","../src/commands/CommandHistory.ts","../src/serialization/index.ts"],"names":["uuidv7","LODLevel"],"mappings":";;;;;AAGO,IAAM,mBAAA,GAAsB;AAE5B,IAAM,qBAAA,GAAgD;AAAA,EAC3D,EAAE,EAAA,EAAI,mBAAA,EAAqB,IAAA,EAAM,WAAA,EAAa,OAAO,SAAA,EAAU;AAAA,EAC/D,EAAE,EAAA,EAAI,QAAA,EAAU,IAAA,EAAM,QAAA,EAAU,OAAO,SAAA,EAAU;AAAA,EACjD,EAAE,EAAA,EAAI,QAAA,EAAU,IAAA,EAAM,QAAA,EAAU,OAAO,SAAA;AACzC;AAEA,IAAM,iBAAA,GAA4C;AAAA,EAChD,IAAA,EAAM,QAAA;AAAA,EACN,OAAA,EAAS,QAAA;AAAA,EACT,IAAA,EAAM;AACR,CAAA;AAEA,SAAS,iBAAA,CAAkB,WAAmB,eAAA,EAAsC;AAClF,EAAA,MAAM,MAAA,GAAS,iBAAA,CAAkB,SAAS,CAAA,IAAK,SAAA;AAC/C,EAAA,IAAI,eAAA,CAAgB,GAAA,CAAI,MAAM,CAAA,EAAG,OAAO,MAAA;AACxC,EAAA,OAAO,mBAAA;AACT;AAEO,SAAS,iBAAA,CAAkB,SAAkB,IAAA,EAAkB;AACpE,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,QAAQ,CAAA;AACrC,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,QAAQ,CAAA;AACrC,EAAA,OAAO;AAAA,IACL,CAAA,EAAG,OAAA,CAAQ,QAAA,CAAS,CAAA,GAAI,IAAA,CAAK,SAAS,CAAA,GAAI,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI,GAAA;AAAA,IAClE,CAAA,EAAG,OAAA,CAAQ,QAAA,CAAS,CAAA,GAAI,IAAA,CAAK,SAAS,CAAA,GAAI,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,CAAA,GAAI;AAAA,GACpE;AACF;AAEO,SAAS,YAAY,OAAA,EAAwB;AAClD,EAAA,MAAM,YAAoB,EAAC;AAE3B,EAAA,IAAI,OAAA,CAAQ,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG;AAC9B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,QAAQ,CAAA;AACrC,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,GAAA,CAAI,OAAA,CAAQ,QAAQ,CAAA;AACrC,IAAA,KAAA,MAAW,CAAA,IAAK,QAAQ,OAAA,EAAS;AAC/B,MAAA,SAAA,CAAU,IAAA,CAAK;AAAA,QACb,CAAA,EAAG,QAAQ,QAAA,CAAS,CAAA,GAAI,EAAE,CAAA,GAAI,GAAA,GAAM,EAAE,CAAA,GAAI,GAAA;AAAA,QAC1C,CAAA,EAAG,QAAQ,QAAA,CAAS,CAAA,GAAI,EAAE,CAAA,GAAI,GAAA,GAAM,EAAE,CAAA,GAAI;AAAA,OAC3C,CAAA;AAAA,IACH;AAAA,EACF;AAEA,EAAA,MAAM,WAAW,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAC,CAAA,KAAM,EAAE,KAAK,CAAA;AACpD,EAAA,KAAA,MAAW,QAAQ,QAAA,EAAU;AAC3B,IAAA,SAAA,CAAU,IAAA,CAAK,iBAAA,CAAkB,OAAA,EAAS,IAAI,CAAC,CAAA;AAAA,EACjD;AAEA,EAAA,IAAI,SAAA,CAAU,WAAW,CAAA,EAAG;AAC1B,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,QAAQ,QAAA,CAAS,CAAA;AAAA,MACvB,IAAA,EAAM,QAAQ,QAAA,CAAS,CAAA;AAAA,MACvB,IAAA,EAAM,QAAQ,QAAA,CAAS,CAAA;AAAA,MACvB,IAAA,EAAM,QAAQ,QAAA,CAAS;AAAA,KACzB;AAAA,EACF;AAEA,EAAA,MAAM,GAAA,GAAM,EAAA;AACZ,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,GAAA;AAAA,IAC/C,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,GAAA;AAAA,IAC/C,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI,GAAA;AAAA,IAC/C,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,CAAC,CAAC,CAAA,GAAI;AAAA,GACjD;AACF;AAEO,SAAS,UAAU,KAAA,EAAoB;AAC5C,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG;AAC/B,IAAA,OAAO,EAAE,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,CAAA,EAAG,IAAA,EAAM,KAAA,CAAM,MAAA,CAAO,KAAA,EAAO,IAAA,EAAM,KAAA,CAAM,MAAA,CAAO,MAAA,EAAO;AAAA,EACjF;AACA,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,WAAW,CAAA;AAC5C,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,IAC1C,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,IAC1C,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC,CAAA;AAAA,IAC1C,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,GAAG,KAAA,CAAM,IAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAI,CAAC;AAAA,GAC5C;AACF;AAGO,SAAS,cAAA,CAAe,OAAa,OAAA,EAA0B;AACpE,EAAA,IAAI,OAAA,CAAQ,MAAA,GAAS,CAAA,EAAG,OAAO,KAAA;AAC/B,EAAA,IAAI,MAAA,GAAS,KAAA;AACb,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,MAAA,GAAS,GAAG,CAAA,GAAI,OAAA,CAAQ,MAAA,EAAQ,CAAA,GAAI,CAAA,EAAA,EAAK;AACnE,IAAA,MAAM,EAAA,GAAK,QAAQ,CAAC,CAAA,CAAE,GAAG,EAAA,GAAK,OAAA,CAAQ,CAAC,CAAA,CAAE,CAAA;AACzC,IAAA,MAAM,EAAA,GAAK,QAAQ,CAAC,CAAA,CAAE,GAAG,EAAA,GAAK,OAAA,CAAQ,CAAC,CAAA,CAAE,CAAA;AACzC,IAAA,IAAK,EAAA,GAAK,KAAA,CAAM,CAAA,KAAQ,EAAA,GAAK,MAAM,CAAA,IAC/B,KAAA,CAAM,CAAA,GAAA,CAAK,EAAA,GAAK,OAAO,KAAA,CAAM,CAAA,GAAI,EAAA,CAAA,IAAO,EAAA,GAAK,MAAM,EAAA,EAAI;AACzD,MAAA,MAAA,GAAS,CAAC,MAAA;AAAA,IACZ;AAAA,EACF;AACA,EAAA,OAAO,MAAA;AACT;AAGO,SAAS,cAAA,CAAe,KAAA,EAAa,OAAA,EAAiB,MAAA,GAAS,CAAA,EAAS;AAC7E,EAAA,IAAI,QAAQ,MAAA,GAAS,CAAA,IAAK,eAAe,KAAA,EAAO,OAAO,GAAG,OAAO,KAAA;AAGjE,EAAA,IAAI,QAAQ,KAAA,CAAM,CAAA,EAAG,KAAA,GAAQ,KAAA,CAAM,GAAG,QAAA,GAAW,QAAA;AACjD,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,MAAA,GAAS,GAAG,CAAA,GAAI,OAAA,CAAQ,MAAA,EAAQ,CAAA,GAAI,CAAA,EAAA,EAAK;AACnE,IAAA,MAAM,EAAA,GAAK,QAAQ,CAAC,CAAA,CAAE,GAAG,EAAA,GAAK,OAAA,CAAQ,CAAC,CAAA,CAAE,CAAA;AACzC,IAAA,MAAM,EAAA,GAAK,QAAQ,CAAC,CAAA,CAAE,GAAG,EAAA,GAAK,OAAA,CAAQ,CAAC,CAAA,CAAE,CAAA;AACzC,IAAA,MAAM,EAAA,GAAK,EAAA,GAAK,EAAA,EAAI,EAAA,GAAK,EAAA,GAAK,EAAA;AAC9B,IAAA,MAAM,IAAA,GAAO,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA;AAC5B,IAAA,IAAI,SAAS,CAAA,EAAG;AAChB,IAAA,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,CAAA,CAAK,KAAA,CAAM,CAAA,GAAI,EAAA,IAAM,MAAM,KAAA,CAAM,CAAA,GAAI,EAAA,IAAM,EAAA,IAAM,IAAI,CAAC,CAAA;AACrF,IAAA,MAAM,EAAA,GAAK,KAAK,CAAA,GAAI,EAAA,GAAK,SAAS,EAAA,GAAK,IAAA,CAAK,KAAK,IAAI,CAAA;AACrD,IAAA,MAAM,EAAA,GAAK,KAAK,CAAA,GAAI,EAAA,GAAK,SAAS,EAAA,GAAK,IAAA,CAAK,KAAK,IAAI,CAAA;AACrD,IAAA,MAAM,CAAA,GAAI,KAAK,KAAA,CAAM,KAAA,CAAM,IAAI,EAAA,EAAI,KAAA,CAAM,IAAI,EAAE,CAAA;AAC/C,IAAA,IAAI,IAAI,QAAA,EAAU;AAAE,MAAA,QAAA,GAAW,CAAA;AAAG,MAAA,KAAA,GAAQ,EAAA;AAAI,MAAA,KAAA,GAAQ,EAAA;AAAA,IAAI;AAAA,EAC5D;AAGA,EAAA,IAAI,CAAC,eAAe,EAAE,CAAA,EAAG,OAAO,CAAA,EAAG,KAAA,EAAM,EAAG,OAAO,CAAA,EAAG;AACpD,IAAA,QAAA,GAAW,QAAA;AACX,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,OAAA,CAAQ,MAAA,GAAS,GAAG,CAAA,GAAI,OAAA,CAAQ,MAAA,EAAQ,CAAA,GAAI,CAAA,EAAA,EAAK;AACnE,MAAA,MAAM,EAAA,GAAK,QAAQ,CAAC,CAAA,CAAE,GAAG,EAAA,GAAK,OAAA,CAAQ,CAAC,CAAA,CAAE,CAAA;AACzC,MAAA,MAAM,EAAA,GAAK,QAAQ,CAAC,CAAA,CAAE,GAAG,EAAA,GAAK,OAAA,CAAQ,CAAC,CAAA,CAAE,CAAA;AACzC,MAAA,MAAM,EAAA,GAAK,EAAA,GAAK,EAAA,EAAI,EAAA,GAAK,EAAA,GAAK,EAAA;AAC9B,MAAA,MAAM,IAAA,GAAO,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,EAAA;AAC5B,MAAA,IAAI,SAAS,CAAA,EAAG;AAChB,MAAA,MAAM,IAAI,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,EAAA,CAAA,CAAK,KAAA,CAAM,CAAA,GAAI,EAAA,IAAM,MAAM,KAAA,CAAM,CAAA,GAAI,EAAA,IAAM,EAAA,IAAM,IAAI,CAAC,CAAA;AACrF,MAAA,MAAM,KAAK,EAAA,GAAK,CAAA,GAAI,EAAA,EAAI,EAAA,GAAK,KAAK,CAAA,GAAI,EAAA;AACtC,MAAA,MAAM,CAAA,GAAI,KAAK,KAAA,CAAM,KAAA,CAAM,IAAI,EAAA,EAAI,KAAA,CAAM,IAAI,EAAE,CAAA;AAC/C,MAAA,IAAI,IAAI,QAAA,EAAU;AAAE,QAAA,QAAA,GAAW,CAAA;AAAG,QAAA,KAAA,GAAQ,EAAA;AAAI,QAAA,KAAA,GAAQ,EAAA;AAAA,MAAI;AAAA,IAC5D;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,CAAA,EAAG,KAAA,EAAO,CAAA,EAAG,KAAA,EAAM;AAC9B;AAEO,SAAS,eAAe,KAAA,EAAqB;AAClD,EAAA,MAAM,YAAA,GACJ,MAAM,YAAA,IAAgB,KAAA,CAAM,aAAa,MAAA,GAAS,CAAA,GAC9C,MAAM,YAAA,GACN,qBAAA;AACN,EAAA,MAAM,cAAA,GAAiB,aAAa,GAAA,CAAI,CAAC,YAAY,EAAE,GAAG,QAAO,CAAE,CAAA;AACnE,EAAA,MAAM,eAAA,GAAkB,IAAI,GAAA,CAAI,cAAA,CAAe,IAAI,CAAC,MAAA,KAAW,MAAA,CAAO,EAAE,CAAC,CAAA;AAEzE,EAAA,MAAM,QAAA,GAAW,KAAA,CAAM,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,MAAa;AAAA,IAChD,GAAG,OAAA;AAAA,IACH,IAAA,EAAM,OAAA,CAAQ,IAAA,CAAK,GAAA,CAAI,CAAC,GAAA,MAAS;AAAA,MAC/B,GAAG,GAAA;AAAA,MACH,KAAA,EAAO,GAAA,CAAI,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,MAAU;AAAA,QAC9B,GAAG,IAAA;AAAA,QACH,MAAA,EAAQ,iBAAA,CAAkB,IAAA,CAAK,MAAA,EAAQ,eAAe;AAAA,OACxD,CAAE;AAAA,KACJ,CAAE;AAAA,GACJ,CAAE,CAAA;AAEF,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,MAAW;AAAA,IAC1C,GAAG,KAAA;AAAA,IACH,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,GAAA,CAAI,CAAC,IAAA,MAAU;AAAA,MAChC,GAAG,IAAA;AAAA,MACH,MAAA,EAAQ,iBAAA,CAAkB,IAAA,CAAK,MAAA,EAAQ,eAAe;AAAA,KACxD,CAAE;AAAA,GACJ,CAAE,CAAA;AAEF,EAAA,OAAO;AAAA,IACL,GAAG,KAAA;AAAA,IACH,YAAA,EAAc,cAAA;AAAA,IACd,QAAA;AAAA,IACA;AAAA,GACF;AACF;AAEO,SAAS,UAAA,CAAW,SAAS,EAAA,EAAY;AAC9C,EAAA,MAAM,KAAKA,EAAA,EAAO;AAClB,EAAA,OAAO,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,GAAK,EAAA;AACtC;ACnKO,IAAM,eAAN,MAAmB;AAAA,EAChB,IAAA,GAAO,IAAI,KAAA,EAAmB;AAAA,EAC9B,QAAuB,EAAC;AAAA,EAEhC,kBAAkB,QAAA,EAA2B;AAC3C,IAAA,IAAA,CAAK,QAAQ,EAAC;AAEd,IAAA,KAAA,MAAW,WAAW,QAAA,EAAU;AAC9B,MAAA,MAAM,GAAA,GAAM,YAAY,OAAO,CAAA;AAC/B,MAAA,IAAA,CAAK,MAAM,IAAA,CAAK;AAAA,QACd,GAAG,GAAA;AAAA,QACH,IAAA,EAAM,SAAA;AAAA,QACN,WAAW,OAAA,CAAQ;AAAA,OACpB,CAAA;AAED,MAAA,KAAA,MAAW,GAAA,IAAO,QAAQ,IAAA,EAAM;AAC9B,QAAA,KAAA,MAAW,IAAA,IAAQ,IAAI,KAAA,EAAO;AAC5B,UAAA,MAAM,EAAA,GAAK,iBAAA,CAAkB,OAAA,EAAS,IAAI,CAAA;AAC1C,UAAA,MAAM,CAAA,GAAI,CAAA;AACV,UAAA,IAAA,CAAK,MAAM,IAAA,CAAK;AAAA,YACd,IAAA,EAAM,GAAG,CAAA,GAAI,CAAA;AAAA,YACb,IAAA,EAAM,GAAG,CAAA,GAAI,CAAA;AAAA,YACb,IAAA,EAAM,GAAG,CAAA,GAAI,CAAA;AAAA,YACb,IAAA,EAAM,GAAG,CAAA,GAAI,CAAA;AAAA,YACb,IAAA,EAAM,MAAA;AAAA,YACN,WAAW,OAAA,CAAQ,EAAA;AAAA,YACnB,QAAQ,IAAA,CAAK;AAAA,WACd,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,KAAK,KAAA,EAAM;AAChB,IAAA,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,KAAK,CAAA;AAAA,EAC3B;AAAA,EAEA,cAAc,QAAA,EAA+B;AAC3C,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,QAAQ,CAAA;AAAA,EAClC;AAAA,EAEA,UAAA,CAAW,KAAA,EAAa,MAAA,GAAS,CAAA,EAAkB;AACjD,IAAA,OAAO,IAAA,CAAK,KAAK,MAAA,CAAO;AAAA,MACtB,IAAA,EAAM,MAAM,CAAA,GAAI,MAAA;AAAA,MAChB,IAAA,EAAM,MAAM,CAAA,GAAI,MAAA;AAAA,MAChB,IAAA,EAAM,MAAM,CAAA,GAAI,MAAA;AAAA,MAChB,IAAA,EAAM,MAAM,CAAA,GAAI;AAAA,KACjB,CAAA;AAAA,EACH;AAAA,EAEA,UAAU,IAAA,EAA2B;AACnC,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA;AAAA,EAC9B;AACF;;;ACtDA,IAAM,QAAA,GAAW,IAAA;AACjB,IAAM,QAAA,GAAW,CAAA;AAEV,IAAM,WAAN,MAAe;AAAA,EACpB,CAAA,GAAI,CAAA;AAAA,EACJ,CAAA,GAAI,CAAA;AAAA,EACJ,IAAA,GAAO,CAAA;AAAA,EACP,WAAA,GAAc,CAAA;AAAA,EACd,YAAA,GAAe,CAAA;AAAA,EAEP,SAAA,uBAAgB,GAAA,EAAgB;AAAA,EAExC,aAAA,CAAc,OAAe,MAAA,EAAsB;AACjD,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,IAAA,IAAA,CAAK,YAAA,GAAe,MAAA;AACpB,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA,EAEA,GAAA,CAAI,IAAY,EAAA,EAAkB;AAChC,IAAA,IAAA,CAAK,CAAA,IAAK,KAAK,IAAA,CAAK,IAAA;AACpB,IAAA,IAAA,CAAK,CAAA,IAAK,KAAK,IAAA,CAAK,IAAA;AACpB,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA,EAEA,MAAA,CAAO,aAAmB,MAAA,EAAsB;AAC9C,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,IAAA,CAAK,IAAI,QAAA,EAAU,IAAA,CAAK,IAAA,GAAO,MAAM,CAAC,CAAA;AAGzE,IAAA,MAAM,EAAA,GAAK,WAAA,CAAY,CAAA,GAAI,IAAA,CAAK,OAAO,IAAA,CAAK,CAAA;AAC5C,IAAA,MAAM,EAAA,GAAK,WAAA,CAAY,CAAA,GAAI,IAAA,CAAK,OAAO,IAAA,CAAK,CAAA;AAI5C,IAAA,IAAA,CAAK,CAAA,GAAI,WAAA,CAAY,CAAA,GAAI,OAAA,GAAU,EAAA;AACnC,IAAA,IAAA,CAAK,CAAA,GAAI,WAAA,CAAY,CAAA,GAAI,OAAA,GAAU,EAAA;AACnC,IAAA,IAAA,CAAK,IAAA,GAAO,OAAA;AACZ,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA,EAEA,QAAQ,IAAA,EAAoB;AAC1B,IAAA,IAAA,CAAK,IAAA,GAAO,KAAK,GAAA,CAAI,QAAA,EAAU,KAAK,GAAA,CAAI,QAAA,EAAU,IAAI,CAAC,CAAA;AACvD,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA,EAEA,SAAA,CAAU,IAAA,EAAY,OAAA,GAAU,EAAA,EAAU;AACxC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA;AAClC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA;AAClC,IAAA,IAAI,QAAA,IAAY,CAAA,IAAK,QAAA,IAAY,CAAA,EAAG;AAEpC,IAAA,MAAM,MAAA,GAAA,CAAU,IAAA,CAAK,WAAA,GAAc,OAAA,GAAU,CAAA,IAAK,QAAA;AAClD,IAAA,MAAM,MAAA,GAAA,CAAU,IAAA,CAAK,YAAA,GAAe,OAAA,GAAU,CAAA,IAAK,QAAA;AACnD,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,MAAM,CAAC,CAAC,CAAA;AAE3E,IAAA,IAAA,CAAK,CAAA,GAAI,EAAE,IAAA,CAAK,IAAA,GAAO,WAAW,CAAA,CAAA,GAAK,IAAA,CAAK,WAAA,IAAe,CAAA,GAAI,IAAA,CAAK,IAAA,CAAA;AACpE,IAAA,IAAA,CAAK,CAAA,GAAI,EAAE,IAAA,CAAK,IAAA,GAAO,WAAW,CAAA,CAAA,GAAK,IAAA,CAAK,YAAA,IAAgB,CAAA,GAAI,IAAA,CAAK,IAAA,CAAA;AACrE,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA,EAEA,aAAA,CAAc,SAAiB,OAAA,EAAuB;AACpD,IAAA,OAAO;AAAA,MACL,CAAA,EAAG,OAAA,GAAU,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,CAAA;AAAA,MAC9B,CAAA,EAAG,OAAA,GAAU,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK;AAAA,KAChC;AAAA,EACF;AAAA,EAEA,aAAA,CAAc,QAAgB,MAAA,EAAsB;AAClD,IAAA,OAAO;AAAA,MACL,CAAA,EAAA,CAAI,MAAA,GAAS,IAAA,CAAK,CAAA,IAAK,IAAA,CAAK,IAAA;AAAA,MAC5B,CAAA,EAAA,CAAI,MAAA,GAAS,IAAA,CAAK,CAAA,IAAK,IAAA,CAAK;AAAA,KAC9B;AAAA,EACF;AAAA,EAEA,cAAA,GAAuB;AACrB,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,aAAA,CAAc,CAAA,EAAG,CAAC,CAAA;AACvC,IAAA,MAAM,cAAc,IAAA,CAAK,aAAA,CAAc,IAAA,CAAK,WAAA,EAAa,KAAK,YAAY,CAAA;AAC1E,IAAA,OAAO;AAAA,MACL,MAAM,OAAA,CAAQ,CAAA;AAAA,MACd,MAAM,OAAA,CAAQ,CAAA;AAAA,MACd,MAAM,WAAA,CAAY,CAAA;AAAA,MAClB,MAAM,WAAA,CAAY;AAAA,KACpB;AAAA,EACF;AAAA,EAEA,QAAA,GAA0B;AACxB,IAAA,OAAO,EAAE,GAAG,IAAA,CAAK,CAAA,EAAG,GAAG,IAAA,CAAK,CAAA,EAAG,IAAA,EAAM,IAAA,CAAK,IAAA,EAAK;AAAA,EACjD;AAAA,EAEA,UAAU,QAAA,EAAkC;AAC1C,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC3B,IAAA,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,EAC7C;AAAA,EAEQ,MAAA,GAAe;AACrB,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,SAAA,EAAW;AACrC,MAAA,QAAA,EAAS;AAAA,IACX;AAAA,EACF;AACF;;;ACzGO,IAAK,QAAA,qBAAAC,SAAAA,KAAL;AACL,EAAAA,UAAA,UAAA,CAAA,GAAW,UAAA;AACX,EAAAA,UAAA,SAAA,CAAA,GAAU,SAAA;AACV,EAAAA,UAAA,QAAA,CAAA,GAAS,QAAA;AAHC,EAAA,OAAAA,SAAAA;AAAA,CAAA,EAAA,QAAA,IAAA,EAAA;AAMZ,IAAM,iBAAA,GAAoB,GAAA;AAC1B,IAAM,gBAAA,GAAmB,GAAA;AAElB,SAAS,YAAY,IAAA,EAAwB;AAClD,EAAA,IAAI,IAAA,GAAO,mBAAmB,OAAO,UAAA;AACrC,EAAA,IAAI,IAAA,GAAO,kBAAkB,OAAO,SAAA;AACpC,EAAA,OAAO,QAAA;AACT;ACJA,IAAM,iBAAA,GAA4C;AAAA,EAChD,QAAA,EAAU,OAAA;AAAA,EACV,OAAA,EAAS;AACX,CAAA;AAEA,SAAS,cAAc,KAAA,EAAuB;AAC5C,EAAA,OAAO,SAAS,KAAA,CAAM,OAAA,CAAQ,GAAA,EAAK,EAAE,GAAG,EAAE,CAAA;AAC5C;AAEO,SAAS,mBACd,QAAA,EACA,YAAA,EACA,MAAA,GAAS,CAAA,EACT,eACA,iBAAA,EACgB;AAChB,EAAA,MAAM,SAAkC,EAAC;AACzC,EAAA,MAAM,UAAA,GAAa,qBAAsB,CAAA,IAAK,OAAO,WAAW,WAAA,GAAc,MAAA,CAAO,oBAAoB,CAAA,GAAI,CAAA,CAAA;AAE7G,EAAA,KAAA,MAAW,UAAU,YAAA,EAAc;AACjC,IAAA,MAAM,CAAA,GAAI,IAAI,QAAA,EAAS;AACvB,IAAA,MAAM,SAAA,GAAY,OAAO,EAAA,KAAO,WAAA,IAAe,iBAAiB,IAAA,GAC5D,aAAA,GACA,aAAA,CAAc,MAAA,CAAO,KAAK,CAAA;AAC9B,IAAA,CAAA,CAAE,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,MAAA,GAAS,GAAG,MAAM,CAAA;AACvC,IAAA,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,SAAA,EAAW,CAAA;AAE3B,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,gBAAA,CAAiB,eAAA,CAAgB;AAAA,MACxD,MAAA,EAAQ,CAAA;AAAA,MACR,UAAA;AAAA,MACA,SAAA,EAAW;AAAA,KACZ,CAAA;AACD,IAAA,CAAA,CAAE,OAAA,EAAQ;AAEV,IAAA,MAAA,CAAO,MAAA,CAAO,EAAE,CAAA,GAAI,OAAA;AAAA,EACtB;AAEA,EAAA,KAAA,MAAW,CAAC,QAAA,EAAU,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,iBAAiB,CAAA,EAAG;AACjE,IAAA,MAAM,CAAA,GAAI,IAAI,QAAA,EAAS;AACvB,IAAA,CAAA,CAAE,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,MAAA,GAAS,GAAG,MAAM,CAAA;AACvC,IAAA,CAAA,CAAE,IAAA,CAAK,EAAE,KAAA,EAAO,CAAA;AAEhB,IAAA,IAAI,aAAa,UAAA,EAAY;AAC3B,MAAA,CAAA,CAAE,OAAO,MAAA,GAAS,CAAA,EAAG,MAAA,GAAS,CAAA,EAAG,SAAS,CAAC,CAAA;AAC3C,MAAA,CAAA,CAAE,OAAO,EAAE,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,GAAG,CAAA;AAAA,IACxC;AAEA,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,gBAAA,CAAiB,eAAA,CAAgB;AAAA,MACxD,MAAA,EAAQ,CAAA;AAAA,MACR,UAAA;AAAA,MACA,SAAA,EAAW;AAAA,KACZ,CAAA;AACD,IAAA,CAAA,CAAE,OAAA,EAAQ;AAEV,IAAA,MAAA,CAAO,QAAQ,CAAA,GAAI,OAAA;AAAA,EACrB;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,SAAS,oBAAoB,QAAA,EAAgC;AAClE,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,MAAA,CAAO,QAAQ,CAAA,EAAG;AACzC,IAAA,GAAA,CAAI,QAAQ,IAAI,CAAA;AAAA,EAClB;AACF;;;ACjEO,IAAM,uBAAN,MAA2B;AAAA,EACxB,KAAA,uBAAY,GAAA,EAA4B;AAAA,EACxC,eAAA,GAAyC,IAAA;AAAA,EAEjD,MAAA,CACE,QAAA,EACA,UAAA,EACA,YAAA,EACA,aAAa,CAAA,EACP;AACN,IAAA,IAAA,CAAK,OAAA,EAAQ;AACb,IAAA,IAAA,CAAK,eAAA,GAAkB,kBAAA,CAAmB,QAAA,EAAU,YAAA,EAAc,UAAU,CAAA;AAE5E,IAAA,KAAA,MAAW,OAAO,UAAA,EAAY;AAC5B,MAAA,MAAM,KAAA,GAAQ,SAAS,GAAA,CAAI,KAAA,CAAM,QAAQ,GAAA,EAAK,EAAE,GAAG,EAAE,CAAA;AACrD,MAAA,IAAA,CAAK,KAAA,CAAM,IAAI,GAAA,CAAI,EAAA,EAAI,mBAAmB,QAAA,EAAU,YAAA,EAAc,UAAA,EAAY,KAAK,CAAC,CAAA;AAAA,IACtF;AAAA,EACF;AAAA,EAEA,IAAI,UAAA,EAAoC;AACtC,IAAA,OAAO,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,UAAU,KAAK,IAAA,CAAK,eAAA;AAAA,EAC5C;AAAA,EAEA,OAAA,GAAgB;AACd,IAAA,KAAA,MAAW,QAAA,IAAY,IAAA,CAAK,KAAA,CAAM,MAAA,EAAO,EAAG;AAC1C,MAAA,mBAAA,CAAoB,QAAQ,CAAA;AAAA,IAC9B;AACA,IAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,MAAA,mBAAA,CAAoB,KAAK,eAAe,CAAA;AAAA,IAC1C;AACA,IAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AACjB,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AAAA,EACzB;AACF;;;ACnCO,IAAM,iBAAN,MAAqB;AAAA,EAClB,YAAuB,EAAC;AAAA,EACxB,YAAuB,EAAC;AAAA,EACxB,SAAA,uBAAgB,GAAA,EAAgB;AAAA,EAExC,QAAQ,OAAA,EAAwB;AAC9B,IAAA,OAAA,CAAQ,OAAA,EAAQ;AAChB,IAAA,IAAA,CAAK,SAAA,CAAU,KAAK,OAAO,CAAA;AAC3B,IAAA,IAAA,CAAK,YAAY,EAAC;AAClB,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,EAAI;AACnC,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,OAAA,CAAQ,IAAA,EAAK;AACb,IAAA,IAAA,CAAK,SAAA,CAAU,KAAK,OAAO,CAAA;AAC3B,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,GAAA,EAAI;AACnC,IAAA,IAAI,CAAC,OAAA,EAAS;AACd,IAAA,OAAA,CAAQ,OAAA,EAAQ;AAChB,IAAA,IAAA,CAAK,SAAA,CAAU,KAAK,OAAO,CAAA;AAC3B,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA,EAEA,IAAI,OAAA,GAAmB;AACrB,IAAA,OAAO,IAAA,CAAK,UAAU,MAAA,GAAS,CAAA;AAAA,EACjC;AAAA,EAEA,IAAI,OAAA,GAAmB;AACrB,IAAA,OAAO,IAAA,CAAK,UAAU,MAAA,GAAS,CAAA;AAAA,EACjC;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,YAAY,EAAC;AAClB,IAAA,IAAA,CAAK,YAAY,EAAC;AAClB,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA,EAEA,UAAU,QAAA,EAAkC;AAC1C,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC3B,IAAA,OAAO,MAAM,IAAA,CAAK,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AAAA,EAC7C;AAAA,EAEQ,MAAA,GAAe;AACrB,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,SAAA,EAAW;AACrC,MAAA,QAAA,EAAS;AAAA,IACX;AAAA,EACF;AACF;;;ACvDO,SAAS,eAAe,KAAA,EAAsB;AACnD,EAAA,OAAO,IAAA,CAAK,SAAA,CAAU,KAAA,EAAO,IAAA,EAAM,CAAC,CAAA;AACtC;AAEO,SAAS,iBAAiB,IAAA,EAAqB;AACpD,EAAA,OAAO,cAAA,CAAe,IAAA,CAAK,KAAA,CAAM,IAAI,CAAU,CAAA;AACjD","file":"index.js","sourcesContent":["import { v7 as uuidv7 } from \"uuid\";\nimport type { AABB, Section, Seat, SeatStatusDefinition, Vec2, Venue } from \"./types\";\n\nexport const AVAILABLE_STATUS_ID = \"available\";\n\nexport const DEFAULT_SEAT_STATUSES: SeatStatusDefinition[] = [\n { id: AVAILABLE_STATUS_ID, name: \"Available\", color: \"#4caf50\" },\n { id: \"locked\", name: \"Locked\", color: \"#f44336\" },\n { id: \"booked\", name: \"Booked\", color: \"#9e9e9e\" },\n];\n\nconst LEGACY_STATUS_MAP: Record<string, string> = {\n held: \"locked\",\n blocked: \"locked\",\n sold: \"booked\",\n};\n\nfunction normalizeStatusId(rawStatus: string, allowedStatuses: Set<string>): string {\n const mapped = LEGACY_STATUS_MAP[rawStatus] ?? rawStatus;\n if (allowedStatuses.has(mapped)) return mapped;\n return AVAILABLE_STATUS_ID;\n}\n\nexport function seatWorldPosition(section: Section, seat: Seat): Vec2 {\n const cos = Math.cos(section.rotation);\n const sin = Math.sin(section.rotation);\n return {\n x: section.position.x + seat.position.x * cos - seat.position.y * sin,\n y: section.position.y + seat.position.x * sin + seat.position.y * cos,\n };\n}\n\nexport function sectionAABB(section: Section): AABB {\n const allPoints: Vec2[] = [];\n\n if (section.outline.length > 0) {\n const cos = Math.cos(section.rotation);\n const sin = Math.sin(section.rotation);\n for (const p of section.outline) {\n allPoints.push({\n x: section.position.x + p.x * cos - p.y * sin,\n y: section.position.y + p.x * sin + p.y * cos,\n });\n }\n }\n\n const allSeats = section.rows.flatMap((r) => r.seats);\n for (const seat of allSeats) {\n allPoints.push(seatWorldPosition(section, seat));\n }\n\n if (allPoints.length === 0) {\n return {\n minX: section.position.x,\n minY: section.position.y,\n maxX: section.position.x,\n maxY: section.position.y,\n };\n }\n\n const pad = 10;\n return {\n minX: Math.min(...allPoints.map((p) => p.x)) - pad,\n minY: Math.min(...allPoints.map((p) => p.y)) - pad,\n maxX: Math.max(...allPoints.map((p) => p.x)) + pad,\n maxY: Math.max(...allPoints.map((p) => p.y)) + pad,\n };\n}\n\nexport function venueAABB(venue: Venue): AABB {\n if (venue.sections.length === 0) {\n return { minX: 0, minY: 0, maxX: venue.bounds.width, maxY: venue.bounds.height };\n }\n const boxes = venue.sections.map(sectionAABB);\n return {\n minX: Math.min(...boxes.map((b) => b.minX)),\n minY: Math.min(...boxes.map((b) => b.minY)),\n maxX: Math.max(...boxes.map((b) => b.maxX)),\n maxY: Math.max(...boxes.map((b) => b.maxY)),\n };\n}\n\n/** Ray-casting point-in-polygon test. Works with any simple polygon. */\nexport function pointInPolygon(point: Vec2, polygon: Vec2[]): boolean {\n if (polygon.length < 3) return false;\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i].x, yi = polygon[i].y;\n const xj = polygon[j].x, yj = polygon[j].y;\n if ((yi > point.y) !== (yj > point.y) &&\n point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi) {\n inside = !inside;\n }\n }\n return inside;\n}\n\n/** Clamp a point to the nearest position inside a polygon (with margin). */\nexport function clampToPolygon(point: Vec2, polygon: Vec2[], margin = 5): Vec2 {\n if (polygon.length < 3 || pointInPolygon(point, polygon)) return point;\n\n // Find the closest point on any polygon edge\n let bestX = point.x, bestY = point.y, bestDist = Infinity;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const ax = polygon[j].x, ay = polygon[j].y;\n const bx = polygon[i].x, by = polygon[i].y;\n const dx = bx - ax, dy = by - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) continue;\n const t = Math.max(0, Math.min(1, ((point.x - ax) * dx + (point.y - ay) * dy) / len2));\n const cx = ax + t * dx - margin * dy / Math.sqrt(len2);\n const cy = ay + t * dy + margin * dx / Math.sqrt(len2);\n const d = Math.hypot(point.x - cx, point.y - cy);\n if (d < bestDist) { bestDist = d; bestX = cx; bestY = cy; }\n }\n\n // Verify the clamped point is inside; if not just project onto edge without margin\n if (!pointInPolygon({ x: bestX, y: bestY }, polygon)) {\n bestDist = Infinity;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const ax = polygon[j].x, ay = polygon[j].y;\n const bx = polygon[i].x, by = polygon[i].y;\n const dx = bx - ax, dy = by - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) continue;\n const t = Math.max(0, Math.min(1, ((point.x - ax) * dx + (point.y - ay) * dy) / len2));\n const cx = ax + t * dx, cy = ay + t * dy;\n const d = Math.hypot(point.x - cx, point.y - cy);\n if (d < bestDist) { bestDist = d; bestX = cx; bestY = cy; }\n }\n }\n\n return { x: bestX, y: bestY };\n}\n\nexport function normalizeVenue(venue: Venue): Venue {\n const seatStatuses =\n venue.seatStatuses && venue.seatStatuses.length > 0\n ? venue.seatStatuses\n : DEFAULT_SEAT_STATUSES;\n const clonedStatuses = seatStatuses.map((status) => ({ ...status }));\n const allowedStatuses = new Set(clonedStatuses.map((status) => status.id));\n\n const sections = venue.sections.map((section) => ({\n ...section,\n rows: section.rows.map((row) => ({\n ...row,\n seats: row.seats.map((seat) => ({\n ...seat,\n status: normalizeStatusId(seat.status, allowedStatuses),\n })),\n })),\n }));\n\n const tables = venue.tables.map((table) => ({\n ...table,\n seats: table.seats.map((seat) => ({\n ...seat,\n status: normalizeStatusId(seat.status, allowedStatuses),\n })),\n }));\n\n return {\n ...venue,\n seatStatuses: clonedStatuses,\n sections,\n tables,\n };\n}\n\nexport function generateId(prefix = \"\"): string {\n const id = uuidv7();\n return prefix ? `${prefix}-${id}` : id;\n}\n","import RBush from \"rbush\";\nimport type { AABB, Section, Vec2 } from \"../models/types\";\nimport { seatWorldPosition, sectionAABB } from \"../models/helpers\";\n\nexport interface SpatialItem extends AABB {\n type: \"section\" | \"seat\";\n sectionId: string;\n seatId?: string;\n}\n\nexport class SpatialIndex {\n private tree = new RBush<SpatialItem>();\n private items: SpatialItem[] = [];\n\n buildFromSections(sections: Section[]): void {\n this.items = [];\n\n for (const section of sections) {\n const box = sectionAABB(section);\n this.items.push({\n ...box,\n type: \"section\",\n sectionId: section.id,\n });\n\n for (const row of section.rows) {\n for (const seat of row.seats) {\n const wp = seatWorldPosition(section, seat);\n const r = 8;\n this.items.push({\n minX: wp.x - r,\n minY: wp.y - r,\n maxX: wp.x + r,\n maxY: wp.y + r,\n type: \"seat\",\n sectionId: section.id,\n seatId: seat.id,\n });\n }\n }\n }\n\n this.tree.clear();\n this.tree.load(this.items);\n }\n\n queryViewport(viewport: AABB): SpatialItem[] {\n return this.tree.search(viewport);\n }\n\n queryPoint(point: Vec2, radius = 8): SpatialItem[] {\n return this.tree.search({\n minX: point.x - radius,\n minY: point.y - radius,\n maxX: point.x + radius,\n maxY: point.y + radius,\n });\n }\n\n queryRect(rect: AABB): SpatialItem[] {\n return this.tree.search(rect);\n }\n}\n","import type { AABB, Vec2 } from \"../models/types\";\n\nexport interface ViewportState {\n x: number;\n y: number;\n zoom: number;\n}\n\nconst MIN_ZOOM = 0.05;\nconst MAX_ZOOM = 4;\n\nexport class Viewport {\n x = 0;\n y = 0;\n zoom = 1;\n screenWidth = 0;\n screenHeight = 0;\n\n private listeners = new Set<() => void>();\n\n setScreenSize(width: number, height: number): void {\n this.screenWidth = width;\n this.screenHeight = height;\n this.notify();\n }\n\n pan(dx: number, dy: number): void {\n this.x += dx / this.zoom;\n this.y += dy / this.zoom;\n this.notify();\n }\n\n zoomAt(screenPoint: Vec2, factor: number): void {\n const newZoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, this.zoom * factor));\n\n // 1) World coordinate currently under the cursor\n const wx = screenPoint.x / this.zoom - this.x;\n const wy = screenPoint.y / this.zoom - this.y;\n\n // 2) Solve for the offset that keeps that world point at the same screen position\n // screenPoint = (world + offset) * newZoom → offset = screenPoint / newZoom - world\n this.x = screenPoint.x / newZoom - wx;\n this.y = screenPoint.y / newZoom - wy;\n this.zoom = newZoom;\n this.notify();\n }\n\n setZoom(zoom: number): void {\n this.zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, zoom));\n this.notify();\n }\n\n fitBounds(aabb: AABB, padding = 40): void {\n const contentW = aabb.maxX - aabb.minX;\n const contentH = aabb.maxY - aabb.minY;\n if (contentW <= 0 || contentH <= 0) return;\n\n const scaleX = (this.screenWidth - padding * 2) / contentW;\n const scaleY = (this.screenHeight - padding * 2) / contentH;\n this.zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, Math.min(scaleX, scaleY)));\n\n this.x = -(aabb.minX + contentW / 2) + this.screenWidth / (2 * this.zoom);\n this.y = -(aabb.minY + contentH / 2) + this.screenHeight / (2 * this.zoom);\n this.notify();\n }\n\n screenToWorld(screenX: number, screenY: number): Vec2 {\n return {\n x: screenX / this.zoom - this.x,\n y: screenY / this.zoom - this.y,\n };\n }\n\n worldToScreen(worldX: number, worldY: number): Vec2 {\n return {\n x: (worldX + this.x) * this.zoom,\n y: (worldY + this.y) * this.zoom,\n };\n }\n\n getVisibleAABB(): AABB {\n const topLeft = this.screenToWorld(0, 0);\n const bottomRight = this.screenToWorld(this.screenWidth, this.screenHeight);\n return {\n minX: topLeft.x,\n minY: topLeft.y,\n maxX: bottomRight.x,\n maxY: bottomRight.y,\n };\n }\n\n getState(): ViewportState {\n return { x: this.x, y: this.y, zoom: this.zoom };\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n","export enum LODLevel {\n Overview = \"overview\",\n Section = \"section\",\n Detail = \"detail\",\n}\n\nconst SECTION_THRESHOLD = 0.3;\nconst DETAIL_THRESHOLD = 0.7;\n\nexport function getLODLevel(zoom: number): LODLevel {\n if (zoom < SECTION_THRESHOLD) return LODLevel.Overview;\n if (zoom < DETAIL_THRESHOLD) return LODLevel.Section;\n return LODLevel.Detail;\n}\n","import { Graphics, type Texture, type Renderer } from \"pixi.js\";\nimport type { SeatStatusDefinition } from \"../models\";\n\nexport interface SeatTextureSet {\n [statusId: string]: Texture;\n selected: Texture;\n hovered: Texture;\n}\n\nconst UI_TEXTURE_COLORS: Record<string, number> = {\n selected: 0x2196f3,\n hovered: 0x64b5f6,\n};\n\nfunction parseHexColor(color: string): number {\n return parseInt(color.replace(\"#\", \"\"), 16);\n}\n\nexport function createSeatTextures(\n renderer: Renderer,\n seatStatuses: SeatStatusDefinition[],\n radius = 7,\n categoryColor?: number,\n textureResolution?: number,\n): SeatTextureSet {\n const result: Partial<SeatTextureSet> = {};\n const resolution = textureResolution ?? (4 * (typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1));\n\n for (const status of seatStatuses) {\n const g = new Graphics();\n const fillColor = status.id === \"available\" && categoryColor != null\n ? categoryColor\n : parseHexColor(status.color);\n g.circle(radius + 4, radius + 4, radius);\n g.fill({ color: fillColor });\n\n const texture = renderer.textureGenerator.generateTexture({\n target: g,\n resolution,\n antialias: true,\n });\n g.destroy();\n\n result[status.id] = texture;\n }\n\n for (const [statusId, color] of Object.entries(UI_TEXTURE_COLORS)) {\n const g = new Graphics();\n g.circle(radius + 4, radius + 4, radius);\n g.fill({ color });\n\n if (statusId === \"selected\") {\n g.circle(radius + 4, radius + 4, radius + 2);\n g.stroke({ color: 0xffffff, width: 2 });\n }\n\n const texture = renderer.textureGenerator.generateTexture({\n target: g,\n resolution,\n antialias: true,\n });\n g.destroy();\n\n result[statusId] = texture;\n }\n\n return result as SeatTextureSet;\n}\n\nexport function destroySeatTextures(textures: SeatTextureSet): void {\n for (const tex of Object.values(textures)) {\n tex.destroy(true);\n }\n}\n","import type { Renderer } from \"pixi.js\";\nimport type { SeatStatusDefinition } from \"../models\";\nimport {\n createSeatTextures,\n destroySeatTextures,\n type SeatTextureSet,\n} from \"./SpriteAtlas\";\n\nexport class CategoryTextureCache {\n private cache = new Map<string, SeatTextureSet>();\n private defaultTextures: SeatTextureSet | null = null;\n\n create(\n renderer: Renderer,\n categories: { id: string; color: string }[],\n seatStatuses: SeatStatusDefinition[],\n seatRadius = 7,\n ): void {\n this.destroy();\n this.defaultTextures = createSeatTextures(renderer, seatStatuses, seatRadius);\n\n for (const cat of categories) {\n const color = parseInt(cat.color.replace(\"#\", \"\"), 16);\n this.cache.set(cat.id, createSeatTextures(renderer, seatStatuses, seatRadius, color));\n }\n }\n\n get(categoryId: string): SeatTextureSet {\n return this.cache.get(categoryId) ?? this.defaultTextures!;\n }\n\n destroy(): void {\n for (const textures of this.cache.values()) {\n destroySeatTextures(textures);\n }\n if (this.defaultTextures) {\n destroySeatTextures(this.defaultTextures);\n }\n this.cache.clear();\n this.defaultTextures = null;\n }\n}\n","export interface Command {\n execute(): void;\n undo(): void;\n description: string;\n}\n\nexport class CommandHistory {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private listeners = new Set<() => void>();\n\n execute(command: Command): void {\n command.execute();\n this.undoStack.push(command);\n this.redoStack = [];\n this.notify();\n }\n\n undo(): void {\n const command = this.undoStack.pop();\n if (!command) return;\n command.undo();\n this.redoStack.push(command);\n this.notify();\n }\n\n redo(): void {\n const command = this.redoStack.pop();\n if (!command) return;\n command.execute();\n this.undoStack.push(command);\n this.notify();\n }\n\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notify();\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n","import type { Venue } from \"../models/types\";\nimport { normalizeVenue } from \"../models/helpers\";\n\nexport function serializeVenue(venue: Venue): string {\n return JSON.stringify(venue, null, 2);\n}\n\nexport function deserializeVenue(json: string): Venue {\n return normalizeVenue(JSON.parse(json) as Venue);\n}\n"]}
1
+ {"version":3,"sources":["../src/models/helpers.ts","../src/spatial/SpatialIndex.ts","../src/rendering/Viewport.ts","../src/rendering/LODLevel.ts","../src/rendering/SpriteAtlas.ts","../src/rendering/CategoryTextureCache.ts","../src/commands/CommandHistory.ts","../src/serialization/index.ts"],"names":["uuidv7","LODLevel"],"mappings":"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","file":"index.js","sourcesContent":["import { v7 as uuidv7 } from \"uuid\";\nimport type { AABB, Section, Seat, SeatStatusDefinition, Vec2, Venue } from \"./types\";\n\nexport const AVAILABLE_STATUS_ID = \"available\";\n\nexport const DEFAULT_SEAT_STATUSES: SeatStatusDefinition[] = [\n { id: AVAILABLE_STATUS_ID, name: \"Available\", color: \"#4caf50\" },\n { id: \"locked\", name: \"Locked\", color: \"#f44336\" },\n { id: \"booked\", name: \"Booked\", color: \"#9e9e9e\" },\n];\n\nconst LEGACY_STATUS_MAP: Record<string, string> = {\n held: \"locked\",\n blocked: \"locked\",\n sold: \"booked\",\n};\n\nfunction normalizeStatusId(rawStatus: string, allowedStatuses: Set<string>): string {\n const mapped = LEGACY_STATUS_MAP[rawStatus] ?? rawStatus;\n if (allowedStatuses.has(mapped)) return mapped;\n return AVAILABLE_STATUS_ID;\n}\n\nexport function seatWorldPosition(section: Section, seat: Seat): Vec2 {\n const cos = Math.cos(section.rotation);\n const sin = Math.sin(section.rotation);\n return {\n x: section.position.x + seat.position.x * cos - seat.position.y * sin,\n y: section.position.y + seat.position.x * sin + seat.position.y * cos,\n };\n}\n\nexport function sectionAABB(section: Section): AABB {\n const allPoints: Vec2[] = [];\n\n if (section.outline.length > 0) {\n const cos = Math.cos(section.rotation);\n const sin = Math.sin(section.rotation);\n for (const p of section.outline) {\n allPoints.push({\n x: section.position.x + p.x * cos - p.y * sin,\n y: section.position.y + p.x * sin + p.y * cos,\n });\n }\n }\n\n const allSeats = section.rows.flatMap((r) => r.seats);\n for (const seat of allSeats) {\n allPoints.push(seatWorldPosition(section, seat));\n }\n\n if (allPoints.length === 0) {\n return {\n minX: section.position.x,\n minY: section.position.y,\n maxX: section.position.x,\n maxY: section.position.y,\n };\n }\n\n const pad = 10;\n return {\n minX: Math.min(...allPoints.map((p) => p.x)) - pad,\n minY: Math.min(...allPoints.map((p) => p.y)) - pad,\n maxX: Math.max(...allPoints.map((p) => p.x)) + pad,\n maxY: Math.max(...allPoints.map((p) => p.y)) + pad,\n };\n}\n\nexport function venueAABB(venue: Venue): AABB {\n if (venue.sections.length === 0) {\n return { minX: 0, minY: 0, maxX: venue.bounds.width, maxY: venue.bounds.height };\n }\n const boxes = venue.sections.map(sectionAABB);\n return {\n minX: Math.min(...boxes.map((b) => b.minX)),\n minY: Math.min(...boxes.map((b) => b.minY)),\n maxX: Math.max(...boxes.map((b) => b.maxX)),\n maxY: Math.max(...boxes.map((b) => b.maxY)),\n };\n}\n\n/** Ray-casting point-in-polygon test. Works with any simple polygon. */\nexport function pointInPolygon(point: Vec2, polygon: Vec2[]): boolean {\n if (polygon.length < 3) return false;\n let inside = false;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const xi = polygon[i].x, yi = polygon[i].y;\n const xj = polygon[j].x, yj = polygon[j].y;\n if ((yi > point.y) !== (yj > point.y) &&\n point.x < (xj - xi) * (point.y - yi) / (yj - yi) + xi) {\n inside = !inside;\n }\n }\n return inside;\n}\n\n/** Clamp a point to the nearest position inside a polygon (with margin). */\nexport function clampToPolygon(point: Vec2, polygon: Vec2[], margin = 5): Vec2 {\n if (polygon.length < 3 || pointInPolygon(point, polygon)) return point;\n\n // Find the closest point on any polygon edge\n let bestX = point.x, bestY = point.y, bestDist = Infinity;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const ax = polygon[j].x, ay = polygon[j].y;\n const bx = polygon[i].x, by = polygon[i].y;\n const dx = bx - ax, dy = by - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) continue;\n const t = Math.max(0, Math.min(1, ((point.x - ax) * dx + (point.y - ay) * dy) / len2));\n const cx = ax + t * dx - margin * dy / Math.sqrt(len2);\n const cy = ay + t * dy + margin * dx / Math.sqrt(len2);\n const d = Math.hypot(point.x - cx, point.y - cy);\n if (d < bestDist) { bestDist = d; bestX = cx; bestY = cy; }\n }\n\n // Verify the clamped point is inside; if not just project onto edge without margin\n if (!pointInPolygon({ x: bestX, y: bestY }, polygon)) {\n bestDist = Infinity;\n for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {\n const ax = polygon[j].x, ay = polygon[j].y;\n const bx = polygon[i].x, by = polygon[i].y;\n const dx = bx - ax, dy = by - ay;\n const len2 = dx * dx + dy * dy;\n if (len2 === 0) continue;\n const t = Math.max(0, Math.min(1, ((point.x - ax) * dx + (point.y - ay) * dy) / len2));\n const cx = ax + t * dx, cy = ay + t * dy;\n const d = Math.hypot(point.x - cx, point.y - cy);\n if (d < bestDist) { bestDist = d; bestX = cx; bestY = cy; }\n }\n }\n\n return { x: bestX, y: bestY };\n}\n\nexport function normalizeVenue(venue: Venue): Venue {\n const seatStatuses =\n venue.seatStatuses && venue.seatStatuses.length > 0\n ? venue.seatStatuses\n : DEFAULT_SEAT_STATUSES;\n const clonedStatuses = seatStatuses.map((status) => ({ ...status }));\n const allowedStatuses = new Set(clonedStatuses.map((status) => status.id));\n const categories = venue.categories.map((category) => {\n const hasBackendPrice = Number.isFinite(category.backendPrice);\n const hasOverriddenPrice = Number.isFinite(category.overriddenPrice);\n return {\n ...category,\n backendPrice: hasBackendPrice ? category.backendPrice : undefined,\n overriddenPrice: hasOverriddenPrice ? category.overriddenPrice : undefined,\n isPriceOverridden:\n Boolean(category.isPriceOverridden) && hasOverriddenPrice,\n };\n });\n\n const sections = venue.sections.map((section) => ({\n ...section,\n rows: section.rows.map((row) => ({\n ...row,\n seats: row.seats.map((seat) => ({\n ...seat,\n status: normalizeStatusId(seat.status, allowedStatuses),\n })),\n })),\n }));\n\n const tables = venue.tables.map((table) => ({\n ...table,\n seats: table.seats.map((seat) => ({\n ...seat,\n status: normalizeStatusId(seat.status, allowedStatuses),\n })),\n }));\n\n return {\n ...venue,\n categories,\n seatStatuses: clonedStatuses,\n sections,\n tables,\n };\n}\n\nexport function generateId(prefix = \"\"): string {\n const id = uuidv7();\n return prefix ? `${prefix}-${id}` : id;\n}\n","import RBush from \"rbush\";\nimport type { AABB, Section, Vec2 } from \"../models/types\";\nimport { seatWorldPosition, sectionAABB } from \"../models/helpers\";\n\nexport interface SpatialItem extends AABB {\n type: \"section\" | \"seat\";\n sectionId: string;\n seatId?: string;\n}\n\nexport class SpatialIndex {\n private tree = new RBush<SpatialItem>();\n private items: SpatialItem[] = [];\n\n buildFromSections(sections: Section[]): void {\n this.items = [];\n\n for (const section of sections) {\n const box = sectionAABB(section);\n this.items.push({\n ...box,\n type: \"section\",\n sectionId: section.id,\n });\n\n for (const row of section.rows) {\n for (const seat of row.seats) {\n const wp = seatWorldPosition(section, seat);\n const r = 8;\n this.items.push({\n minX: wp.x - r,\n minY: wp.y - r,\n maxX: wp.x + r,\n maxY: wp.y + r,\n type: \"seat\",\n sectionId: section.id,\n seatId: seat.id,\n });\n }\n }\n }\n\n this.tree.clear();\n this.tree.load(this.items);\n }\n\n queryViewport(viewport: AABB): SpatialItem[] {\n return this.tree.search(viewport);\n }\n\n queryPoint(point: Vec2, radius = 8): SpatialItem[] {\n return this.tree.search({\n minX: point.x - radius,\n minY: point.y - radius,\n maxX: point.x + radius,\n maxY: point.y + radius,\n });\n }\n\n queryRect(rect: AABB): SpatialItem[] {\n return this.tree.search(rect);\n }\n}\n","import type { AABB, Vec2 } from \"../models/types\";\n\nexport interface ViewportState {\n x: number;\n y: number;\n zoom: number;\n}\n\nconst MIN_ZOOM = 0.05;\nconst MAX_ZOOM = 4;\n\nexport class Viewport {\n x = 0;\n y = 0;\n zoom = 1;\n screenWidth = 0;\n screenHeight = 0;\n\n private listeners = new Set<() => void>();\n\n setScreenSize(width: number, height: number): void {\n this.screenWidth = width;\n this.screenHeight = height;\n this.notify();\n }\n\n pan(dx: number, dy: number): void {\n this.x += dx / this.zoom;\n this.y += dy / this.zoom;\n this.notify();\n }\n\n zoomAt(screenPoint: Vec2, factor: number): void {\n const newZoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, this.zoom * factor));\n\n // 1) World coordinate currently under the cursor\n const wx = screenPoint.x / this.zoom - this.x;\n const wy = screenPoint.y / this.zoom - this.y;\n\n // 2) Solve for the offset that keeps that world point at the same screen position\n // screenPoint = (world + offset) * newZoom → offset = screenPoint / newZoom - world\n this.x = screenPoint.x / newZoom - wx;\n this.y = screenPoint.y / newZoom - wy;\n this.zoom = newZoom;\n this.notify();\n }\n\n setZoom(zoom: number): void {\n this.zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, zoom));\n this.notify();\n }\n\n fitBounds(aabb: AABB, padding = 40): void {\n const contentW = aabb.maxX - aabb.minX;\n const contentH = aabb.maxY - aabb.minY;\n if (contentW <= 0 || contentH <= 0) return;\n\n const scaleX = (this.screenWidth - padding * 2) / contentW;\n const scaleY = (this.screenHeight - padding * 2) / contentH;\n this.zoom = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, Math.min(scaleX, scaleY)));\n\n this.x = -(aabb.minX + contentW / 2) + this.screenWidth / (2 * this.zoom);\n this.y = -(aabb.minY + contentH / 2) + this.screenHeight / (2 * this.zoom);\n this.notify();\n }\n\n screenToWorld(screenX: number, screenY: number): Vec2 {\n return {\n x: screenX / this.zoom - this.x,\n y: screenY / this.zoom - this.y,\n };\n }\n\n worldToScreen(worldX: number, worldY: number): Vec2 {\n return {\n x: (worldX + this.x) * this.zoom,\n y: (worldY + this.y) * this.zoom,\n };\n }\n\n getVisibleAABB(): AABB {\n const topLeft = this.screenToWorld(0, 0);\n const bottomRight = this.screenToWorld(this.screenWidth, this.screenHeight);\n return {\n minX: topLeft.x,\n minY: topLeft.y,\n maxX: bottomRight.x,\n maxY: bottomRight.y,\n };\n }\n\n getState(): ViewportState {\n return { x: this.x, y: this.y, zoom: this.zoom };\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n","export enum LODLevel {\n Overview = \"overview\",\n Section = \"section\",\n Detail = \"detail\",\n}\n\nconst SECTION_THRESHOLD = 0.3;\nconst DETAIL_THRESHOLD = 0.7;\n\nexport function getLODLevel(zoom: number): LODLevel {\n if (zoom < SECTION_THRESHOLD) return LODLevel.Overview;\n if (zoom < DETAIL_THRESHOLD) return LODLevel.Section;\n return LODLevel.Detail;\n}\n","import { Graphics, type Texture, type Renderer } from \"pixi.js\";\nimport type { SeatStatusDefinition } from \"../models\";\n\nexport interface SeatTextureSet {\n [statusId: string]: Texture;\n selected: Texture;\n hovered: Texture;\n}\n\nconst UI_TEXTURE_COLORS: Record<string, number> = {\n selected: 0x2196f3,\n hovered: 0x64b5f6,\n};\n\nfunction parseHexColor(color: string): number {\n return parseInt(color.replace(\"#\", \"\"), 16);\n}\n\nexport function createSeatTextures(\n renderer: Renderer,\n seatStatuses: SeatStatusDefinition[],\n radius = 7,\n categoryColor?: number,\n textureResolution?: number,\n): SeatTextureSet {\n const result: Partial<SeatTextureSet> = {};\n const resolution = textureResolution ?? (4 * (typeof window !== \"undefined\" ? window.devicePixelRatio || 1 : 1));\n\n for (const status of seatStatuses) {\n const g = new Graphics();\n const fillColor = status.id === \"available\" && categoryColor != null\n ? categoryColor\n : parseHexColor(status.color);\n g.circle(radius + 4, radius + 4, radius);\n g.fill({ color: fillColor });\n\n const texture = renderer.textureGenerator.generateTexture({\n target: g,\n resolution,\n antialias: true,\n });\n g.destroy();\n\n result[status.id] = texture;\n }\n\n for (const [statusId, color] of Object.entries(UI_TEXTURE_COLORS)) {\n const g = new Graphics();\n g.circle(radius + 4, radius + 4, radius);\n g.fill({ color });\n\n if (statusId === \"selected\") {\n g.circle(radius + 4, radius + 4, radius + 2);\n g.stroke({ color: 0xffffff, width: 2 });\n }\n\n const texture = renderer.textureGenerator.generateTexture({\n target: g,\n resolution,\n antialias: true,\n });\n g.destroy();\n\n result[statusId] = texture;\n }\n\n return result as SeatTextureSet;\n}\n\nexport function destroySeatTextures(textures: SeatTextureSet): void {\n for (const tex of Object.values(textures)) {\n tex.destroy(true);\n }\n}\n","import type { Renderer } from \"pixi.js\";\nimport type { SeatStatusDefinition } from \"../models\";\nimport {\n createSeatTextures,\n destroySeatTextures,\n type SeatTextureSet,\n} from \"./SpriteAtlas\";\n\nexport class CategoryTextureCache {\n private cache = new Map<string, SeatTextureSet>();\n private defaultTextures: SeatTextureSet | null = null;\n\n create(\n renderer: Renderer,\n categories: { id: string; color: string }[],\n seatStatuses: SeatStatusDefinition[],\n seatRadius = 7,\n ): void {\n this.destroy();\n this.defaultTextures = createSeatTextures(renderer, seatStatuses, seatRadius);\n\n for (const cat of categories) {\n const color = parseInt(cat.color.replace(\"#\", \"\"), 16);\n this.cache.set(cat.id, createSeatTextures(renderer, seatStatuses, seatRadius, color));\n }\n }\n\n get(categoryId: string): SeatTextureSet {\n return this.cache.get(categoryId) ?? this.defaultTextures!;\n }\n\n destroy(): void {\n for (const textures of this.cache.values()) {\n destroySeatTextures(textures);\n }\n if (this.defaultTextures) {\n destroySeatTextures(this.defaultTextures);\n }\n this.cache.clear();\n this.defaultTextures = null;\n }\n}\n","export interface Command {\n execute(): void;\n undo(): void;\n description: string;\n}\n\nexport class CommandHistory {\n private undoStack: Command[] = [];\n private redoStack: Command[] = [];\n private listeners = new Set<() => void>();\n\n execute(command: Command): void {\n command.execute();\n this.undoStack.push(command);\n this.redoStack = [];\n this.notify();\n }\n\n undo(): void {\n const command = this.undoStack.pop();\n if (!command) return;\n command.undo();\n this.redoStack.push(command);\n this.notify();\n }\n\n redo(): void {\n const command = this.redoStack.pop();\n if (!command) return;\n command.execute();\n this.undoStack.push(command);\n this.notify();\n }\n\n get canUndo(): boolean {\n return this.undoStack.length > 0;\n }\n\n get canRedo(): boolean {\n return this.redoStack.length > 0;\n }\n\n clear(): void {\n this.undoStack = [];\n this.redoStack = [];\n this.notify();\n }\n\n subscribe(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n private notify(): void {\n for (const listener of this.listeners) {\n listener();\n }\n }\n}\n","import type { Venue } from \"../models/types\";\nimport { normalizeVenue } from \"../models/helpers\";\n\nexport function serializeVenue(venue: Venue): string {\n return JSON.stringify(venue, null, 2);\n}\n\nexport function deserializeVenue(json: string): Venue {\n return normalizeVenue(JSON.parse(json) as Venue);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nex125/seatmap-core",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",