venuekit 0.0.0-stage → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,180 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+
19
+
20
+
21
+
22
+
23
+
24
+
25
+
26
+
27
+
28
+
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
+
59
+
60
+
61
+
62
+
63
+
64
+
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+ var _chunk47ILVPKZcjs = require('./chunk-47ILVPKZ.cjs');
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+
151
+
152
+
153
+
154
+
155
+
156
+
157
+
158
+
159
+
160
+
161
+
162
+
163
+
164
+
165
+
166
+
167
+
168
+
169
+
170
+
171
+
172
+
173
+
174
+
175
+
176
+
177
+
178
+
179
+
180
+ exports.CURRENT_VERSION = _chunk47ILVPKZcjs.CURRENT_VERSION; exports.CommandError = _chunk47ILVPKZcjs.CommandError; exports.DEFAULT_BLOCK = _chunk47ILVPKZcjs.DEFAULT_BLOCK; exports.DEFAULT_MAX_SELECTION = _chunk47ILVPKZcjs.DEFAULT_MAX_SELECTION; exports.DEFAULT_TABLE_PLACES = _chunk47ILVPKZcjs.DEFAULT_TABLE_PLACES; exports.DEFAULT_ZONE = _chunk47ILVPKZcjs.DEFAULT_ZONE; exports.HISTORY_LIMIT = _chunk47ILVPKZcjs.HISTORY_LIMIT; exports.History = _chunk47ILVPKZcjs.History; exports.ID_SEP = _chunk47ILVPKZcjs.ID_SEP; exports.LATIN_ALPHABET = _chunk47ILVPKZcjs.LATIN_ALPHABET; exports.LayoutError = _chunk47ILVPKZcjs.LayoutError; exports.MAX_ELEMENTS = _chunk47ILVPKZcjs.MAX_ELEMENTS; exports.MAX_ID_LENGTH = _chunk47ILVPKZcjs.MAX_ID_LENGTH; exports.MAX_LETTERS_START = _chunk47ILVPKZcjs.MAX_LETTERS_START; exports.MAX_NAME_LENGTH = _chunk47ILVPKZcjs.MAX_NAME_LENGTH; exports.MAX_REF_LENGTH = _chunk47ILVPKZcjs.MAX_REF_LENGTH; exports.MAX_SCALE = _chunk47ILVPKZcjs.MAX_SCALE; exports.MAX_SKIP = _chunk47ILVPKZcjs.MAX_SKIP; exports.MAX_SRC_LENGTH = _chunk47ILVPKZcjs.MAX_SRC_LENGTH; exports.MAX_TABLE_LABEL_LENGTH = _chunk47ILVPKZcjs.MAX_TABLE_LABEL_LENGTH; exports.MAX_UNITS = _chunk47ILVPKZcjs.MAX_UNITS; exports.MIN_SCALE = _chunk47ILVPKZcjs.MIN_SCALE; exports.PLACE_OFFSET = _chunk47ILVPKZcjs.PLACE_OFFSET; exports.SPANISH_ALPHABET = _chunk47ILVPKZcjs.SPANISH_ALPHABET; exports.SpatialIndex = _chunk47ILVPKZcjs.SpatialIndex; exports.TABLE_HEIGHT = _chunk47ILVPKZcjs.TABLE_HEIGHT; exports.TABLE_RADIUS = _chunk47ILVPKZcjs.TABLE_RADIUS; exports.TABLE_WIDTH = _chunk47ILVPKZcjs.TABLE_WIDTH; exports.VERSION = _chunk47ILVPKZcjs.VERSION; exports.applyCommand = _chunk47ILVPKZcjs.applyCommand; exports.applyTransform = _chunk47ILVPKZcjs.applyTransform; exports.assignPlaceType = _chunk47ILVPKZcjs.assignPlaceType; exports.backgroundSchema = _chunk47ILVPKZcjs.backgroundSchema; exports.bbox = _chunk47ILVPKZcjs.bbox; exports.blockShape = _chunk47ILVPKZcjs.blockShape; exports.canAssign = _chunk47ILVPKZcjs.canAssign; exports.capacityViolations = _chunk47ILVPKZcjs.capacityViolations; exports.createPiece = _chunk47ILVPKZcjs.createPiece; exports.distance = _chunk47ILVPKZcjs.distance; exports.duplicatePiece = _chunk47ILVPKZcjs.duplicatePiece; exports.elementSchema = _chunk47ILVPKZcjs.elementSchema; exports.expand = _chunk47ILVPKZcjs.expand; exports.expandLabels = _chunk47ILVPKZcjs.expandLabels; exports.expandSeatBlock = _chunk47ILVPKZcjs.expandSeatBlock; exports.expandTable = _chunk47ILVPKZcjs.expandTable; exports.findLockViolations = _chunk47ILVPKZcjs.findLockViolations; exports.idSchema = _chunk47ILVPKZcjs.idSchema; exports.labelRuleSchema = _chunk47ILVPKZcjs.labelRuleSchema; exports.labelSequence = _chunk47ILVPKZcjs.labelSequence; exports.landmarkById = _chunk47ILVPKZcjs.landmarkById; exports.landmarkSchema = _chunk47ILVPKZcjs.landmarkSchema; exports.landmarks = _chunk47ILVPKZcjs.landmarks; exports.layoutSchema = _chunk47ILVPKZcjs.layoutSchema; exports.letterIndex = _chunk47ILVPKZcjs.letterIndex; exports.letterLabel = _chunk47ILVPKZcjs.letterLabel; exports.metaSchema = _chunk47ILVPKZcjs.metaSchema; exports.migrate = _chunk47ILVPKZcjs.migrate; exports.newElementId = _chunk47ILVPKZcjs.newElementId; exports.nextBlockUnits = _chunk47ILVPKZcjs.nextBlockUnits; exports.parseUnitId = _chunk47ILVPKZcjs.parseUnitId; exports.placeTypeBounds = _chunk47ILVPKZcjs.placeTypeBounds; exports.placeTypeCapacity = _chunk47ILVPKZcjs.placeTypeCapacity; exports.placeTypeLinkSchema = _chunk47ILVPKZcjs.placeTypeLinkSchema; exports.placeUnitId = _chunk47ILVPKZcjs.placeUnitId; exports.pointInPolygon = _chunk47ILVPKZcjs.pointInPolygon; exports.pointInZone = _chunk47ILVPKZcjs.pointInZone; exports.rebindPlaceTypes = _chunk47ILVPKZcjs.rebindPlaceTypes; exports.rotatePiece = _chunk47ILVPKZcjs.rotatePiece; exports.rotationSchema = _chunk47ILVPKZcjs.rotationSchema; exports.scalePiece = _chunk47ILVPKZcjs.scalePiece; exports.seatBlockSchema = _chunk47ILVPKZcjs.seatBlockSchema; exports.seatUnitId = _chunk47ILVPKZcjs.seatUnitId; exports.snapScale = _chunk47ILVPKZcjs.snapScale; exports.spanishParseOptions = _chunk47ILVPKZcjs.spanishParseOptions; exports.summarize = _chunk47ILVPKZcjs.summarize; exports.tableSchema = _chunk47ILVPKZcjs.tableSchema; exports.tableSize = _chunk47ILVPKZcjs.tableSize; exports.toggleRemovedSeat = _chunk47ILVPKZcjs.toggleRemovedSeat; exports.toggleUnit = _chunk47ILVPKZcjs.toggleUnit; exports.transformSchema = _chunk47ILVPKZcjs.transformSchema; exports.unitStates = _chunk47ILVPKZcjs.unitStates; exports.zoneArc = _chunk47ILVPKZcjs.zoneArc; exports.zoneBounds = _chunk47ILVPKZcjs.zoneBounds; exports.zoneLabelSize = _chunk47ILVPKZcjs.zoneLabelSize; exports.zoneLocalSize = _chunk47ILVPKZcjs.zoneLocalSize; exports.zoneOutline = _chunk47ILVPKZcjs.zoneOutline; exports.zoneSchema = _chunk47ILVPKZcjs.zoneSchema; exports.zoneWithLocalSize = _chunk47ILVPKZcjs.zoneWithLocalSize;
@@ -0,0 +1,256 @@
1
+ import { L as LabelRule, a as Layout, S as SellableUnit, B as Box, Z as Zone, P as Point, E as Element, b as Background } from './place-types-CeTjPHTF.cjs';
2
+ export { C as CapacityViolation, D as DEFAULT_BLOCK, c as DEFAULT_TABLE_PLACES, d as DEFAULT_ZONE, e as Landmark, f as LockViolation, M as MAX_ELEMENTS, g as MAX_ID_LENGTH, h as MAX_LETTERS_START, i as MAX_NAME_LENGTH, j as MAX_REF_LENGTH, k as MAX_SCALE, l as MAX_SKIP, m as MAX_SRC_LENGTH, n as MAX_TABLE_LABEL_LENGTH, o as MAX_UNITS, p as MIN_SCALE, q as PLACE_OFFSET, r as PieceKind, s as PieceOptions, t as PlaceTypeAccepts, u as PlaceTypeLink, v as PlaceTypeOption, w as PlanSummary, R as Rotation, x as SeatBlock, T as TABLE_HEIGHT, y as TABLE_RADIUS, z as TABLE_WIDTH, A as Table, F as Transform, G as applyTransform, H as assignPlaceType, I as backgroundSchema, J as bbox, K as blockShape, N as canAssign, O as capacityViolations, Q as createPiece, U as distance, V as duplicatePiece, W as elementSchema, X as expand, Y as expandSeatBlock, _ as expandTable, $ as findLockViolations, a0 as idSchema, a1 as labelRuleSchema, a2 as landmarkSchema, a3 as layoutSchema, a4 as metaSchema, a5 as newElementId, a6 as nextBlockUnits, a7 as placeTypeCapacity, a8 as placeTypeLinkSchema, a9 as pointInPolygon, aa as rebindPlaceTypes, ab as rotatePiece, ac as rotationSchema, ad as scalePiece, ae as seatBlockSchema, af as snapScale, ag as spanishParseOptions, ah as summarize, ai as tableSchema, aj as tableSize, ak as toggleRemovedSeat, al as transformSchema, am as zoneSchema } from './place-types-CeTjPHTF.cjs';
3
+ import 'zod';
4
+
5
+ declare const LATIN_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
6
+ /** El alfabeto argentino: la Ñ va después de la N. */
7
+ declare const SPANISH_ALPHABET = "ABCDEFGHIJKLMN\u00D1OPQRSTUVWXYZ";
8
+ type LabelAlphabet = "latin" | "es";
9
+ type LabelPattern = "sequential" | "odd" | "even" | "center";
10
+ /** 0 → "A", 25 → "Z", 26 → "AA" (numeración bijectiva en base 26; 27 con la Ñ). */
11
+ declare function letterLabel(index: number, alphabet?: LabelAlphabet): string;
12
+ /** Inversa de letterLabel. "A" → 0, "AA" → 26. */
13
+ declare function letterIndex(label: string, alphabet?: LabelAlphabet): number;
14
+ /**
15
+ * Las `count` etiquetas en el orden en que se numeran (todavía sin acomodarlas en
16
+ * la fila): desde `start`, sin las de `skip`. Con `odd`/`even`, sólo impares o
17
+ * pares, desde el primero de esa clase que no sea menor que `start`.
18
+ */
19
+ declare function labelSequence(rule: LabelRule, count: number): string[];
20
+ /**
21
+ * Genera `count` etiquetas en el orden de la fila/columna (de izquierda a derecha).
22
+ * `skip` saca etiquetas de la secuencia (después de H viene J si skip incluye I).
23
+ * `pattern` (sólo números; ausente = `sequential`, como siempre): seguidas, sólo
24
+ * impares, sólo pares o desde el centro. `rtl` invierte el orden en que se asignan.
25
+ */
26
+ declare function expandLabels(rule: LabelRule, count: number): string[];
27
+
28
+ declare const ID_SEP = ":";
29
+ declare function seatUnitId(blockId: string, rowLabel: string, seatLabel: string): string;
30
+ declare function placeUnitId(tableId: string, n: number): string;
31
+ declare function parseUnitId(id: string): string[];
32
+
33
+ /**
34
+ * Caja que encierra las posiciones de las unidades de un tipo de lugar. Es lo
35
+ * que el selector usa para encuadrar la cámara sobre ese tipo.
36
+ *
37
+ * Devuelve `null` si no tiene ninguna — `bbox([])` devuelve una caja de
38
+ * ±Infinity, que como cámara es una pantalla en blanco sin explicación.
39
+ */
40
+ declare function placeTypeBounds(_layout: Layout, units: SellableUnit[], ref: string): Box | null;
41
+
42
+ /**
43
+ * Una zona curva es una banda de arco con la misma convención que un bloque curvo
44
+ * (`expand.ts`): el arco abre `curve` grados, el centro queda arriba y los extremos
45
+ * suben (la "sonrisa"). `width` se mide sobre el arco central y `height` es el grosor.
46
+ * El punto de la pieza (`transform`) es el medio del arco central.
47
+ */
48
+ type ZoneArc = {
49
+ /** Mitad del ángulo, en radianes. */
50
+ half: number;
51
+ /** Radio del arco central. */
52
+ mid: number;
53
+ inner: number;
54
+ outer: number;
55
+ };
56
+ /** `null` si la zona es recta. */
57
+ declare function zoneArc(zone: Zone): ZoneArc | null;
58
+ /** Ancho y alto de la caja de la pieza sin girar. */
59
+ declare function zoneLocalSize(zone: Zone): {
60
+ width: number;
61
+ height: number;
62
+ };
63
+ /** La caja que contiene la zona, en el mundo. */
64
+ declare function zoneBounds(zone: Zone): Box;
65
+ /** Si un punto del mundo cae adentro de la zona (de la banda, si es curva). */
66
+ declare function pointInZone(zone: Zone, p: Point): boolean;
67
+ /**
68
+ * El contorno de una zona curva en el mundo, con las cuatro esquinas suaves
69
+ * (`corner`, en unidades del plano). Vacío si la zona es recta: esa se dibuja como rect.
70
+ */
71
+ declare function zoneOutline(zone: Zone, corner?: number): Point[];
72
+ /**
73
+ * Cuánto lugar recto hay para un texto horizontal en el medio de la banda (sin girar).
74
+ * Recta, toda la zona; curva, lo que entra sobre la línea que pasa por su punto.
75
+ */
76
+ declare function zoneLabelSize(zone: Zone): {
77
+ width: number;
78
+ height: number;
79
+ };
80
+ /**
81
+ * La zona con la caja (sin girar) de `width` × `height`, manteniendo su curva.
82
+ * Es la inversa de `zoneLocalSize`: con ella las manijas y «mismo ancho» trabajan
83
+ * sobre la caja que se ve, no sobre el arco. Lo que no se puede (más alto que
84
+ * una porción de torta) se acota.
85
+ */
86
+ declare function zoneWithLocalSize(zone: Zone, width: number, height: number): Zone;
87
+
88
+ type Item = {
89
+ id: string;
90
+ x: number;
91
+ y: number;
92
+ };
93
+ /** Quadtree de puntos con id. Inmutable después de construido. */
94
+ declare class SpatialIndex {
95
+ private readonly root;
96
+ readonly size: number;
97
+ constructor(items: Item[], capacity?: number);
98
+ queryRect(box: Box): string[];
99
+ nearest(p: Point, maxDistance: number): string | null;
100
+ }
101
+
102
+ type Command = {
103
+ type: "addElement";
104
+ element: Element;
105
+ } | {
106
+ type: "removeElement";
107
+ id: string;
108
+ } | {
109
+ type: "updateElement";
110
+ id: string;
111
+ patch: Record<string, unknown>;
112
+ } | {
113
+ type: "moveElement";
114
+ id: string;
115
+ dx: number;
116
+ dy: number;
117
+ } | {
118
+ type: "replaceElement";
119
+ element: Element;
120
+ } | {
121
+ type: "setBackground";
122
+ background: Background | null;
123
+ }
124
+ /** Varios comandos como un solo cambio: alinear o mover varias piezas es un paso de deshacer. */
125
+ | {
126
+ type: "batch";
127
+ commands: Command[];
128
+ };
129
+ declare class CommandError extends Error {
130
+ constructor(message: string);
131
+ }
132
+ /** Aplica un comando y valida el resultado. Pura: nunca muta `layout`. */
133
+ declare function applyCommand(layout: Layout, cmd: Command): Layout;
134
+ declare const HISTORY_LIMIT = 100;
135
+ /** Historial por snapshots: el documento pesa KB (guarda bloques, no asientos). */
136
+ declare class History {
137
+ private past;
138
+ private future;
139
+ /** La clave de agrupación del último `apply`. Ver `apply`. */
140
+ private lastKey;
141
+ present: Layout;
142
+ constructor(initial: Layout);
143
+ get canUndo(): boolean;
144
+ get canRedo(): boolean;
145
+ /**
146
+ * Aplica un comando y lo anota en la historia.
147
+ *
148
+ * `key` agrupa: escribir un nombre en un campo son quince comandos seguidos,
149
+ * no quince pasos. Con la misma clave que el anterior, el comando pisa al
150
+ * presente sin apilar otro paso — Deshacer vuelve al nombre de antes, no
151
+ * borra una letra. Sin clave, cada comando es su propio paso, que es lo que
152
+ * corresponde a dibujar, borrar o mover.
153
+ */
154
+ apply(cmd: Command, key?: string): Layout;
155
+ /**
156
+ * Reemplaza el documento entero, y se puede deshacer.
157
+ *
158
+ * Es cargar un plano: elegir de qué forma partir, o abrir uno guardado. No es
159
+ * un comando porque no describe una edición — no hay un "cambio" que aplicar
160
+ * sobre lo anterior, hay un documento nuevo.
161
+ *
162
+ * Va a la historia igual, y ahí está la gracia: alguien que dibujó media hora
163
+ * y elige otra forma por error tiene que poder volver con Deshacer.
164
+ */
165
+ load(next: Layout): Layout;
166
+ /** El documento al que llevaría `undo`, sin moverse. Para chequearlo antes (el candado). */
167
+ peekUndo(): Layout | null;
168
+ peekRedo(): Layout | null;
169
+ undo(): Layout;
170
+ redo(): Layout;
171
+ /**
172
+ * Pasa todos los documentos (pasado, presente y futuro) por `fn`, sin agregar
173
+ * un paso. Es para lo que cambia por fuera del plano, como una entrada que el
174
+ * host borró: deshacer no puede devolver una pieza a un tipo que ya no existe.
175
+ */
176
+ rewrite(fn: (layout: Layout) => Layout): Layout;
177
+ }
178
+
179
+ /**
180
+ * Estado de una unidad para el comprador (spec §7.2). `held` es el `locked`
181
+ * del spec: retenida por mí, con la cuenta regresiva a cargo del host. Se
182
+ * llama distinto porque `locked` ya significa "vendida, el editor no la
183
+ * puede tocar" en §6.4.
184
+ */
185
+ type UnitState = "free" | "taken" | "selected" | "held";
186
+ /** Cuántas unidades entran en una compra si el host no dice otra cosa. */
187
+ declare const DEFAULT_MAX_SELECTION = 10;
188
+ /**
189
+ * Estado de cada unidad. Lo mío gana sobre lo ocupado: si `taken`
190
+ * todavía lista como tomada una butaca que acabo de retener, para mí sigue
191
+ * siendo mía (el polling de §8.5 llega tarde, no manda).
192
+ */
193
+ declare function unitStates(units: SellableUnit[], taken: ReadonlySet<string>, selection: readonly string[], held: ReadonlySet<string>): Map<string, UnitState>;
194
+ type ToggleResult = {
195
+ selection: string[];
196
+ rejected?: "taken" | "max";
197
+ };
198
+ /**
199
+ * Toca una unidad. Sacar siempre se puede; agregar sólo si está libre y hay
200
+ * lugar. Nunca lanza: devuelve `rejected` para que la UI diga por qué.
201
+ */
202
+ declare function toggleUnit(selection: readonly string[], unitId: string, states: ReadonlyMap<string, UnitState>, maxSelection: number): ToggleResult;
203
+
204
+ declare const CURRENT_VERSION = 2;
205
+ declare class LayoutError extends Error {
206
+ readonly issues: {
207
+ path: string;
208
+ message: string;
209
+ }[];
210
+ constructor(message: string, issues?: {
211
+ path: string;
212
+ message: string;
213
+ }[]);
214
+ }
215
+ /** Única puerta de entrada de documentos externos: migra a la versión actual y valida. */
216
+ declare function migrate(input: unknown): Layout;
217
+
218
+ /**
219
+ * Las cosas del lugar que NO se venden.
220
+ *
221
+ * Un baño, la barra, el escenario: están en el plano porque el que compra
222
+ * necesita ubicarse —"quiero estar cerca de la barra"— pero no tienen precio
223
+ * ni stock, y nadie compra un baño.
224
+ *
225
+ * Por eso **no están atados a un tipo de lugar**. Lo vendible (bloques y
226
+ * mesas) se enlaza a un tipo de lugar del host y sale en el listado de venta.
227
+ * Meter un baño ahí lo dejaría pidiendo un tipo que no existe y apareciendo
228
+ * entre las opciones de compra. Un landmark es un elemento aparte del plano
229
+ * (`type: "landmark"`) que sólo lleva `kind` (este catálogo), nombre y medidas.
230
+ *
231
+ * El catálogo vive en `core` —sin DOM, sin React— porque es dato, no interfaz:
232
+ * el editor lo muestra en una lista, pero un host que arme planos por API usa
233
+ * los mismos nombres y las mismas medidas.
234
+ */
235
+ type LandmarkGroup = "access" | "bar" | "service" | "stage" | "space";
236
+ interface LandmarkDef {
237
+ id: string;
238
+ /** Lo que se dibuja en el plano y se lee en la lista. */
239
+ name: string;
240
+ group: LandmarkGroup;
241
+ /** Medida sugerida, en unidades del plano. Un click suelto lo crea así. */
242
+ width: number;
243
+ height: number;
244
+ }
245
+ /**
246
+ * Medidas: el plano de las plantillas mide 1200×800 y una butaca ocupa 26.
247
+ * Un baño de 120×80 son ~4 butacas de ancho, que es como se ve en un plano de
248
+ * boliche de verdad. El escenario es la excepción a propósito — es lo primero
249
+ * que el ojo tiene que encontrar.
250
+ */
251
+ declare const landmarks: readonly LandmarkDef[];
252
+ declare function landmarkById(id: string): LandmarkDef | null;
253
+
254
+ declare const VERSION = "0.10.0";
255
+
256
+ export { Background, Box, CURRENT_VERSION, type Command, CommandError, DEFAULT_MAX_SELECTION, Element, HISTORY_LIMIT, History, ID_SEP, LATIN_ALPHABET, type LabelAlphabet, type LabelPattern, LabelRule, type LandmarkDef, type LandmarkGroup, Layout, LayoutError, Point, SPANISH_ALPHABET, SellableUnit, SpatialIndex, type ToggleResult, type UnitState, VERSION, Zone, type ZoneArc, applyCommand, expandLabels, labelSequence, landmarkById, landmarks, letterIndex, letterLabel, migrate, parseUnitId, placeTypeBounds, placeUnitId, pointInZone, seatUnitId, toggleUnit, unitStates, zoneArc, zoneBounds, zoneLabelSize, zoneLocalSize, zoneOutline, zoneWithLocalSize };
@@ -0,0 +1,256 @@
1
+ import { L as LabelRule, a as Layout, S as SellableUnit, B as Box, Z as Zone, P as Point, E as Element, b as Background } from './place-types-CeTjPHTF.js';
2
+ export { C as CapacityViolation, D as DEFAULT_BLOCK, c as DEFAULT_TABLE_PLACES, d as DEFAULT_ZONE, e as Landmark, f as LockViolation, M as MAX_ELEMENTS, g as MAX_ID_LENGTH, h as MAX_LETTERS_START, i as MAX_NAME_LENGTH, j as MAX_REF_LENGTH, k as MAX_SCALE, l as MAX_SKIP, m as MAX_SRC_LENGTH, n as MAX_TABLE_LABEL_LENGTH, o as MAX_UNITS, p as MIN_SCALE, q as PLACE_OFFSET, r as PieceKind, s as PieceOptions, t as PlaceTypeAccepts, u as PlaceTypeLink, v as PlaceTypeOption, w as PlanSummary, R as Rotation, x as SeatBlock, T as TABLE_HEIGHT, y as TABLE_RADIUS, z as TABLE_WIDTH, A as Table, F as Transform, G as applyTransform, H as assignPlaceType, I as backgroundSchema, J as bbox, K as blockShape, N as canAssign, O as capacityViolations, Q as createPiece, U as distance, V as duplicatePiece, W as elementSchema, X as expand, Y as expandSeatBlock, _ as expandTable, $ as findLockViolations, a0 as idSchema, a1 as labelRuleSchema, a2 as landmarkSchema, a3 as layoutSchema, a4 as metaSchema, a5 as newElementId, a6 as nextBlockUnits, a7 as placeTypeCapacity, a8 as placeTypeLinkSchema, a9 as pointInPolygon, aa as rebindPlaceTypes, ab as rotatePiece, ac as rotationSchema, ad as scalePiece, ae as seatBlockSchema, af as snapScale, ag as spanishParseOptions, ah as summarize, ai as tableSchema, aj as tableSize, ak as toggleRemovedSeat, al as transformSchema, am as zoneSchema } from './place-types-CeTjPHTF.js';
3
+ import 'zod';
4
+
5
+ declare const LATIN_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
6
+ /** El alfabeto argentino: la Ñ va después de la N. */
7
+ declare const SPANISH_ALPHABET = "ABCDEFGHIJKLMN\u00D1OPQRSTUVWXYZ";
8
+ type LabelAlphabet = "latin" | "es";
9
+ type LabelPattern = "sequential" | "odd" | "even" | "center";
10
+ /** 0 → "A", 25 → "Z", 26 → "AA" (numeración bijectiva en base 26; 27 con la Ñ). */
11
+ declare function letterLabel(index: number, alphabet?: LabelAlphabet): string;
12
+ /** Inversa de letterLabel. "A" → 0, "AA" → 26. */
13
+ declare function letterIndex(label: string, alphabet?: LabelAlphabet): number;
14
+ /**
15
+ * Las `count` etiquetas en el orden en que se numeran (todavía sin acomodarlas en
16
+ * la fila): desde `start`, sin las de `skip`. Con `odd`/`even`, sólo impares o
17
+ * pares, desde el primero de esa clase que no sea menor que `start`.
18
+ */
19
+ declare function labelSequence(rule: LabelRule, count: number): string[];
20
+ /**
21
+ * Genera `count` etiquetas en el orden de la fila/columna (de izquierda a derecha).
22
+ * `skip` saca etiquetas de la secuencia (después de H viene J si skip incluye I).
23
+ * `pattern` (sólo números; ausente = `sequential`, como siempre): seguidas, sólo
24
+ * impares, sólo pares o desde el centro. `rtl` invierte el orden en que se asignan.
25
+ */
26
+ declare function expandLabels(rule: LabelRule, count: number): string[];
27
+
28
+ declare const ID_SEP = ":";
29
+ declare function seatUnitId(blockId: string, rowLabel: string, seatLabel: string): string;
30
+ declare function placeUnitId(tableId: string, n: number): string;
31
+ declare function parseUnitId(id: string): string[];
32
+
33
+ /**
34
+ * Caja que encierra las posiciones de las unidades de un tipo de lugar. Es lo
35
+ * que el selector usa para encuadrar la cámara sobre ese tipo.
36
+ *
37
+ * Devuelve `null` si no tiene ninguna — `bbox([])` devuelve una caja de
38
+ * ±Infinity, que como cámara es una pantalla en blanco sin explicación.
39
+ */
40
+ declare function placeTypeBounds(_layout: Layout, units: SellableUnit[], ref: string): Box | null;
41
+
42
+ /**
43
+ * Una zona curva es una banda de arco con la misma convención que un bloque curvo
44
+ * (`expand.ts`): el arco abre `curve` grados, el centro queda arriba y los extremos
45
+ * suben (la "sonrisa"). `width` se mide sobre el arco central y `height` es el grosor.
46
+ * El punto de la pieza (`transform`) es el medio del arco central.
47
+ */
48
+ type ZoneArc = {
49
+ /** Mitad del ángulo, en radianes. */
50
+ half: number;
51
+ /** Radio del arco central. */
52
+ mid: number;
53
+ inner: number;
54
+ outer: number;
55
+ };
56
+ /** `null` si la zona es recta. */
57
+ declare function zoneArc(zone: Zone): ZoneArc | null;
58
+ /** Ancho y alto de la caja de la pieza sin girar. */
59
+ declare function zoneLocalSize(zone: Zone): {
60
+ width: number;
61
+ height: number;
62
+ };
63
+ /** La caja que contiene la zona, en el mundo. */
64
+ declare function zoneBounds(zone: Zone): Box;
65
+ /** Si un punto del mundo cae adentro de la zona (de la banda, si es curva). */
66
+ declare function pointInZone(zone: Zone, p: Point): boolean;
67
+ /**
68
+ * El contorno de una zona curva en el mundo, con las cuatro esquinas suaves
69
+ * (`corner`, en unidades del plano). Vacío si la zona es recta: esa se dibuja como rect.
70
+ */
71
+ declare function zoneOutline(zone: Zone, corner?: number): Point[];
72
+ /**
73
+ * Cuánto lugar recto hay para un texto horizontal en el medio de la banda (sin girar).
74
+ * Recta, toda la zona; curva, lo que entra sobre la línea que pasa por su punto.
75
+ */
76
+ declare function zoneLabelSize(zone: Zone): {
77
+ width: number;
78
+ height: number;
79
+ };
80
+ /**
81
+ * La zona con la caja (sin girar) de `width` × `height`, manteniendo su curva.
82
+ * Es la inversa de `zoneLocalSize`: con ella las manijas y «mismo ancho» trabajan
83
+ * sobre la caja que se ve, no sobre el arco. Lo que no se puede (más alto que
84
+ * una porción de torta) se acota.
85
+ */
86
+ declare function zoneWithLocalSize(zone: Zone, width: number, height: number): Zone;
87
+
88
+ type Item = {
89
+ id: string;
90
+ x: number;
91
+ y: number;
92
+ };
93
+ /** Quadtree de puntos con id. Inmutable después de construido. */
94
+ declare class SpatialIndex {
95
+ private readonly root;
96
+ readonly size: number;
97
+ constructor(items: Item[], capacity?: number);
98
+ queryRect(box: Box): string[];
99
+ nearest(p: Point, maxDistance: number): string | null;
100
+ }
101
+
102
+ type Command = {
103
+ type: "addElement";
104
+ element: Element;
105
+ } | {
106
+ type: "removeElement";
107
+ id: string;
108
+ } | {
109
+ type: "updateElement";
110
+ id: string;
111
+ patch: Record<string, unknown>;
112
+ } | {
113
+ type: "moveElement";
114
+ id: string;
115
+ dx: number;
116
+ dy: number;
117
+ } | {
118
+ type: "replaceElement";
119
+ element: Element;
120
+ } | {
121
+ type: "setBackground";
122
+ background: Background | null;
123
+ }
124
+ /** Varios comandos como un solo cambio: alinear o mover varias piezas es un paso de deshacer. */
125
+ | {
126
+ type: "batch";
127
+ commands: Command[];
128
+ };
129
+ declare class CommandError extends Error {
130
+ constructor(message: string);
131
+ }
132
+ /** Aplica un comando y valida el resultado. Pura: nunca muta `layout`. */
133
+ declare function applyCommand(layout: Layout, cmd: Command): Layout;
134
+ declare const HISTORY_LIMIT = 100;
135
+ /** Historial por snapshots: el documento pesa KB (guarda bloques, no asientos). */
136
+ declare class History {
137
+ private past;
138
+ private future;
139
+ /** La clave de agrupación del último `apply`. Ver `apply`. */
140
+ private lastKey;
141
+ present: Layout;
142
+ constructor(initial: Layout);
143
+ get canUndo(): boolean;
144
+ get canRedo(): boolean;
145
+ /**
146
+ * Aplica un comando y lo anota en la historia.
147
+ *
148
+ * `key` agrupa: escribir un nombre en un campo son quince comandos seguidos,
149
+ * no quince pasos. Con la misma clave que el anterior, el comando pisa al
150
+ * presente sin apilar otro paso — Deshacer vuelve al nombre de antes, no
151
+ * borra una letra. Sin clave, cada comando es su propio paso, que es lo que
152
+ * corresponde a dibujar, borrar o mover.
153
+ */
154
+ apply(cmd: Command, key?: string): Layout;
155
+ /**
156
+ * Reemplaza el documento entero, y se puede deshacer.
157
+ *
158
+ * Es cargar un plano: elegir de qué forma partir, o abrir uno guardado. No es
159
+ * un comando porque no describe una edición — no hay un "cambio" que aplicar
160
+ * sobre lo anterior, hay un documento nuevo.
161
+ *
162
+ * Va a la historia igual, y ahí está la gracia: alguien que dibujó media hora
163
+ * y elige otra forma por error tiene que poder volver con Deshacer.
164
+ */
165
+ load(next: Layout): Layout;
166
+ /** El documento al que llevaría `undo`, sin moverse. Para chequearlo antes (el candado). */
167
+ peekUndo(): Layout | null;
168
+ peekRedo(): Layout | null;
169
+ undo(): Layout;
170
+ redo(): Layout;
171
+ /**
172
+ * Pasa todos los documentos (pasado, presente y futuro) por `fn`, sin agregar
173
+ * un paso. Es para lo que cambia por fuera del plano, como una entrada que el
174
+ * host borró: deshacer no puede devolver una pieza a un tipo que ya no existe.
175
+ */
176
+ rewrite(fn: (layout: Layout) => Layout): Layout;
177
+ }
178
+
179
+ /**
180
+ * Estado de una unidad para el comprador (spec §7.2). `held` es el `locked`
181
+ * del spec: retenida por mí, con la cuenta regresiva a cargo del host. Se
182
+ * llama distinto porque `locked` ya significa "vendida, el editor no la
183
+ * puede tocar" en §6.4.
184
+ */
185
+ type UnitState = "free" | "taken" | "selected" | "held";
186
+ /** Cuántas unidades entran en una compra si el host no dice otra cosa. */
187
+ declare const DEFAULT_MAX_SELECTION = 10;
188
+ /**
189
+ * Estado de cada unidad. Lo mío gana sobre lo ocupado: si `taken`
190
+ * todavía lista como tomada una butaca que acabo de retener, para mí sigue
191
+ * siendo mía (el polling de §8.5 llega tarde, no manda).
192
+ */
193
+ declare function unitStates(units: SellableUnit[], taken: ReadonlySet<string>, selection: readonly string[], held: ReadonlySet<string>): Map<string, UnitState>;
194
+ type ToggleResult = {
195
+ selection: string[];
196
+ rejected?: "taken" | "max";
197
+ };
198
+ /**
199
+ * Toca una unidad. Sacar siempre se puede; agregar sólo si está libre y hay
200
+ * lugar. Nunca lanza: devuelve `rejected` para que la UI diga por qué.
201
+ */
202
+ declare function toggleUnit(selection: readonly string[], unitId: string, states: ReadonlyMap<string, UnitState>, maxSelection: number): ToggleResult;
203
+
204
+ declare const CURRENT_VERSION = 2;
205
+ declare class LayoutError extends Error {
206
+ readonly issues: {
207
+ path: string;
208
+ message: string;
209
+ }[];
210
+ constructor(message: string, issues?: {
211
+ path: string;
212
+ message: string;
213
+ }[]);
214
+ }
215
+ /** Única puerta de entrada de documentos externos: migra a la versión actual y valida. */
216
+ declare function migrate(input: unknown): Layout;
217
+
218
+ /**
219
+ * Las cosas del lugar que NO se venden.
220
+ *
221
+ * Un baño, la barra, el escenario: están en el plano porque el que compra
222
+ * necesita ubicarse —"quiero estar cerca de la barra"— pero no tienen precio
223
+ * ni stock, y nadie compra un baño.
224
+ *
225
+ * Por eso **no están atados a un tipo de lugar**. Lo vendible (bloques y
226
+ * mesas) se enlaza a un tipo de lugar del host y sale en el listado de venta.
227
+ * Meter un baño ahí lo dejaría pidiendo un tipo que no existe y apareciendo
228
+ * entre las opciones de compra. Un landmark es un elemento aparte del plano
229
+ * (`type: "landmark"`) que sólo lleva `kind` (este catálogo), nombre y medidas.
230
+ *
231
+ * El catálogo vive en `core` —sin DOM, sin React— porque es dato, no interfaz:
232
+ * el editor lo muestra en una lista, pero un host que arme planos por API usa
233
+ * los mismos nombres y las mismas medidas.
234
+ */
235
+ type LandmarkGroup = "access" | "bar" | "service" | "stage" | "space";
236
+ interface LandmarkDef {
237
+ id: string;
238
+ /** Lo que se dibuja en el plano y se lee en la lista. */
239
+ name: string;
240
+ group: LandmarkGroup;
241
+ /** Medida sugerida, en unidades del plano. Un click suelto lo crea así. */
242
+ width: number;
243
+ height: number;
244
+ }
245
+ /**
246
+ * Medidas: el plano de las plantillas mide 1200×800 y una butaca ocupa 26.
247
+ * Un baño de 120×80 son ~4 butacas de ancho, que es como se ve en un plano de
248
+ * boliche de verdad. El escenario es la excepción a propósito — es lo primero
249
+ * que el ojo tiene que encontrar.
250
+ */
251
+ declare const landmarks: readonly LandmarkDef[];
252
+ declare function landmarkById(id: string): LandmarkDef | null;
253
+
254
+ declare const VERSION = "0.10.0";
255
+
256
+ export { Background, Box, CURRENT_VERSION, type Command, CommandError, DEFAULT_MAX_SELECTION, Element, HISTORY_LIMIT, History, ID_SEP, LATIN_ALPHABET, type LabelAlphabet, type LabelPattern, LabelRule, type LandmarkDef, type LandmarkGroup, Layout, LayoutError, Point, SPANISH_ALPHABET, SellableUnit, SpatialIndex, type ToggleResult, type UnitState, VERSION, Zone, type ZoneArc, applyCommand, expandLabels, labelSequence, landmarkById, landmarks, letterIndex, letterLabel, migrate, parseUnitId, placeTypeBounds, placeUnitId, pointInZone, seatUnitId, toggleUnit, unitStates, zoneArc, zoneBounds, zoneLabelSize, zoneLocalSize, zoneOutline, zoneWithLocalSize };